From 31f1ff91028dd7f90925d5b3737e4d88b5fb07aa Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 16 Oct 2009 16:18:36 +0200 Subject: Send posted events in response to WM_QT_SENDPOSTEDEVENTS (which is just WM_USER+1) Delay the next WM_QT_SENDPOSTEDEVENTS iff there is a WM_TIMER or input event pending We also need to break out of processEvents() after seeing this message, to prevent livelocking in the prescence of fast timers. I also took the liberty of defining WM_QT_SOCKETNOTIFIER (WM_USER) at the same time (to give clear meaning to what WM_USER and WM_USER+1 are used for). Reviewed-by: Prasanth Ullattil --- src/corelib/kernel/qeventdispatcher_win.cpp | 178 +++++++++++++++------------- 1 file changed, 94 insertions(+), 84 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 1e6402f..f7de29d 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -64,6 +64,11 @@ extern uint qGlobalPostedEventsCount(); # define TIME_KILL_SYNCHRONOUS 0x0100 #endif +enum { + WM_QT_SOCKETNOTIFIER = WM_USER, + WM_QT_SENDPOSTEDEVENTS = WM_USER + 1 +}; + #if defined(Q_OS_WINCE) QT_BEGIN_INCLUDE_NAMESPACE #include @@ -327,6 +332,11 @@ public: // internal window handle used for socketnotifiers/timers/etc HWND internalHwnd; + // for controlling when to send posted events + QAtomicInt serialNumber; + int lastSerialNumber; + QAtomicInt wakeUps; + // timers WinTimerVec timerVec; WinTimerDict timerDict; @@ -340,9 +350,6 @@ public: QSNDict sn_except; void doWsaAsyncSelect(int socket); - // event notifier - QWinEventNotifier wakeUpNotifier; - QList winEventNotifierList; void activateEventNotifier(QWinEventNotifier * wen); @@ -351,19 +358,13 @@ public: }; QEventDispatcherWin32Private::QEventDispatcherWin32Private() - : threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0) + : threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0), serialNumber(0), lastSerialNumber(0), wakeUps(0) { resolveTimerAPI(); - - wakeUpNotifier.setHandle(CreateEvent(0, FALSE, FALSE, 0)); - if (!wakeUpNotifier.handle()) - qWarning("QEventDispatcher: Creating QEventDispatcherWin32Private wakeup event failed"); } QEventDispatcherWin32Private::~QEventDispatcherWin32Private() { - wakeUpNotifier.setEnabled(false); - CloseHandle(wakeUpNotifier.handle()); if (internalHwnd) DestroyWindow(internalHwnd); QString className = QLatin1String("QEventDispatcherWin32_Internal_Widget") + QString::number(quintptr(qt_internal_proc)); @@ -408,22 +409,35 @@ void WINAPI CALLBACK qt_fast_timer_proc(uint timerId, uint /*reserved*/, DWORD_P LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp) { - if (message == WM_NCCREATE) { - return true; - } else if (message == WM_USER) { + if (message == WM_NCCREATE) + return true; - // socket notifier message - MSG msg; - msg.hwnd = hwnd; - msg.message = message; - msg.wParam = wp; - msg.lParam = lp; + MSG msg; + msg.hwnd = hwnd; + msg.message = message; + msg.wParam = wp; + msg.lParam = lp; + QCoreApplication *app = QCoreApplication::instance(); + long result; + if (!app) { + if (message == WM_TIMER) + KillTimer(hwnd, wp); + return 0; + } else if (app->filterEvent(&msg, &result)) { + return result; + } - QCoreApplication *app = QCoreApplication::instance(); - long result; - if (app && app->filterEvent(&msg, &result)) - return result; +#ifdef GWLP_USERDATA + QEventDispatcherWin32 *q = (QEventDispatcherWin32 *) GetWindowLongPtr(hwnd, GWLP_USERDATA); +#else + QEventDispatcherWin32 *q = (QEventDispatcherWin32 *) GetWindowLong(hwnd, GWL_USERDATA); +#endif + QEventDispatcherWin32Private *d = 0; + if (q != 0) + d = q->d_func(); + if (message == WM_QT_SOCKETNOTIFIER) { + // socket notifier message int type = -1; switch (WSAGETSELECTEVENT(lp)) { case FD_READ: @@ -440,56 +454,52 @@ LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp) break; } if (type >= 0) { - - #ifdef GWLP_USERDATA - QEventDispatcherWin32 *eventDispatcher = - (QEventDispatcherWin32 *) GetWindowLongPtr(hwnd, GWLP_USERDATA); - #else - QEventDispatcherWin32 *eventDispatcher = - (QEventDispatcherWin32 *) GetWindowLong(hwnd, GWL_USERDATA); - #endif - if (eventDispatcher) { - QEventDispatcherWin32Private *d = eventDispatcher->d_func(); - QSNDict *sn_vec[3] = { &d->sn_read, &d->sn_write, &d->sn_except }; - QSNDict *dict = sn_vec[type]; - - QSockNot *sn = dict ? dict->value(wp) : 0; - if (sn) { - QEvent event(QEvent::SockAct); - QCoreApplication::sendEvent(sn->obj, &event); - } + Q_ASSERT(d != 0); + QSNDict *sn_vec[3] = { &d->sn_read, &d->sn_write, &d->sn_except }; + QSNDict *dict = sn_vec[type]; + + QSockNot *sn = dict ? dict->value(wp) : 0; + if (sn) { + QEvent event(QEvent::SockAct); + QCoreApplication::sendEvent(sn->obj, &event); } } return 0; - - } else if (message == WM_TIMER) { - - MSG msg; - msg.hwnd = hwnd; - msg.message = message; - msg.wParam = wp; - msg.lParam = lp; - - QCoreApplication *app = QCoreApplication::instance(); - Q_ASSERT_X(app, "qt_interal_proc", "Timer fired, but no QCoreApplication"); - if (!app) { - KillTimer(hwnd, wp); - return 0; + } else if (message == WM_TIMER) { + if (wp == ~0u) { + KillTimer(d->internalHwnd, wp); + int localSerialNumber = d->serialNumber; + (void) d->wakeUps.fetchAndStoreRelease(0); + if (localSerialNumber != d->lastSerialNumber) { + PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0); + } + } else { + Q_ASSERT(d != 0); + d->sendTimerEvent(wp); + } + return 0; + } else if (message == WM_QT_SENDPOSTEDEVENTS) { + int localSerialNumber = d->serialNumber; + + MSG peeked; + if (PeekMessage(&peeked, d->internalHwnd, WM_TIMER, WM_TIMER, PM_NOREMOVE) + || PeekMessage(&peeked, NULL, 0, 0, PM_NOREMOVE | PM_QS_INPUT)) { + // delay the next pass of sendPostedEvents() until we get the special + // WM_TIMER, which allows all pending Windows messages to be processed + SetTimer(d->internalHwnd, ~0u, 0, 0); + } else { + // nothing pending in the queue, let sendPostedEvents go through + d->wakeUps.fetchAndStoreRelease(0); } - long result; - if (app->filterEvent(&msg, &result)) - return result; - - QEventDispatcherWin32 *eventDispatcher = - qobject_cast(QAbstractEventDispatcher::instance()); - Q_ASSERT(eventDispatcher != 0); - QEventDispatcherWin32Private *d = eventDispatcher->d_func(); - d->sendTimerEvent(wp); + if (localSerialNumber != d->lastSerialNumber) { + d->lastSerialNumber = localSerialNumber; + QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData); + } return 0; } - return DefWindowProc(hwnd, message, wp, lp); + return DefWindowProc(hwnd, message, wp, lp); } static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatcher) @@ -538,11 +548,6 @@ void QEventDispatcherWin32Private::registerTimer(WinTimerInfo *t) Q_Q(QEventDispatcherWin32); int ok = 0; - - //in the animation api, we delay the start of the animation - //for the dock widgets, we need to use a system timer because dragging a native window - //makes Windows start its own event loop. - //So if this threshold changes, please change STARTSTOP_TIMER_DELAY in qabstractanimation.cpp accordingly. if (t->interval > 15 || !t->interval || !qtimeSetEvent) { ok = 1; if (!t->interval) // optimization for single-shot-zero-timer @@ -608,7 +613,7 @@ void QEventDispatcherWin32Private::doWsaAsyncSelect(int socket) sn_event |= FD_OOB; // BoundsChecker may emit a warning for WSAAsyncSelect when sn_event == 0 // This is a BoundsChecker bug and not a Qt bug - WSAAsyncSelect(socket, internalHwnd, sn_event ? WM_USER : 0, sn_event); + WSAAsyncSelect(socket, internalHwnd, sn_event ? WM_QT_SOCKETNOTIFIER : 0, sn_event); } void QEventDispatcherWin32::createInternalHwnd() @@ -630,6 +635,9 @@ void QEventDispatcherWin32::createInternalHwnd() // start all normal timers for (int i = 0; i < d->timerVec.count(); ++i) d->registerTimer(d->timerVec.at(i)); + + // trigger a call to sendPostedEvents() + wakeUp(); } QEventDispatcherWin32::QEventDispatcherWin32(QObject *parent) @@ -654,11 +662,10 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) bool canWait; bool retVal = false; do { - QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData); - DWORD waitRet = 0; HANDLE pHandles[MAXIMUM_WAIT_OBJECTS - 1]; QVarLengthArray processedTimers; + bool seenWM_QT_SENDPOSTEDEVENTS = false; while (!d->interrupt) { DWORD nCount = d->winEventNotifierList.count(); Q_ASSERT(nCount < MAXIMUM_WAIT_OBJECTS - 1); @@ -689,7 +696,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) d->queuedUserInputEvents.append(msg); } if (haveMessage && (flags & QEventLoop::ExcludeSocketNotifiers) - && (msg.message == WM_USER && msg.hwnd == d->internalHwnd)) { + && (msg.message == WM_QT_SOCKETNOTIFIER && msg.hwnd == d->internalHwnd)) { // queue socket events for later processing haveMessage = false; d->queuedSocketEvents.append(msg); @@ -706,7 +713,13 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) } } if (haveMessage) { - if (msg.message == WM_TIMER) { + if (msg.message == WM_QT_SENDPOSTEDEVENTS && !(flags & QEventLoop::EventLoopExec)) { + if (seenWM_QT_SENDPOSTEDEVENTS) { + PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0); + break; + } + seenWM_QT_SENDPOSTEDEVENTS = true; + } else if (msg.message == WM_TIMER) { // avoid live-lock by keeping track of the timers we've already sent bool found = false; for (int i = 0; !found && i < processedTimers.count(); ++i) { @@ -736,9 +749,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) } // still nothing - wait for message or signalled objects - QThreadData *data = d->threadData; canWait = (!retVal - && data->canWait && !d->interrupt && (flags & QEventLoop::WaitForMoreEvents)); if (canWait) { @@ -990,7 +1001,11 @@ void QEventDispatcherWin32::activateEventNotifiers() void QEventDispatcherWin32::wakeUp() { Q_D(QEventDispatcherWin32); - SetEvent(d->wakeUpNotifier.handle()); + d->serialNumber.ref(); + if (d->internalHwnd && d->wakeUps.testAndSetAcquire(0, 1)) { + // post a WM_QT_SENDPOSTEDEVENTS to this thread if there isn't one already pending + PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0); + } } void QEventDispatcherWin32::interrupt() @@ -1003,13 +1018,8 @@ void QEventDispatcherWin32::interrupt() void QEventDispatcherWin32::flush() { } - void QEventDispatcherWin32::startingUp() -{ - Q_D(QEventDispatcherWin32); - - if (d->wakeUpNotifier.handle()) d->wakeUpNotifier.setEnabled(true); -} +{ } void QEventDispatcherWin32::closingDown() { -- cgit v0.12 From 4e22238ac86eb7ddb88b7dec73d419767da72323 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Mon, 19 Oct 2009 16:14:13 +0200 Subject: Remove workarounds for Win32 event dispatcher bugs This includes the startstop timer delay in QAbstractAnimation, and the inSizeMove workaround for paint events. Reviewed-by: Prasanth Ullattil --- src/corelib/animation/qabstractanimation.cpp | 12 ------------ src/gui/kernel/qapplication.cpp | 3 --- src/gui/kernel/qapplication_p.h | 3 --- src/gui/kernel/qapplication_win.cpp | 2 -- src/gui/painting/qbackingstore.cpp | 12 ------------ 5 files changed, 32 deletions(-) diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index c775a00..df8b548 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -157,19 +157,7 @@ #ifndef QT_NO_ANIMATION #define DEFAULT_TIMER_INTERVAL 16 - -#ifdef Q_WS_WIN - /// Fix for Qt 4.7 - //on windows if you're currently dragging a widget an inner eventloop was started by the system - //to make sure that this timer is getting fired, we need to make sure to use the system timers - //that will send a WM_TIMER event. We do that by settings the timer interval to 11 - //It is 16 because QEventDispatcherWin32Private::registerTimer specifically checks if the interval - //is greater than 11 to determine if it should use a system timer (or the multimedia timer). -#define STARTSTOP_TIMER_DELAY 16 -#else #define STARTSTOP_TIMER_DELAY 0 -#endif - QT_BEGIN_NAMESPACE diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index f48c551..9658f5e 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -474,9 +474,6 @@ bool QApplicationPrivate::fade_tooltip = false; bool QApplicationPrivate::animate_toolbox = false; bool QApplicationPrivate::widgetCount = false; bool QApplicationPrivate::load_testability = false; -#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE) -bool QApplicationPrivate::inSizeMove = false; -#endif #ifdef QT_KEYPAD_NAVIGATION # ifdef Q_OS_SYMBIAN Qt::NavigationMode QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional; diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 2d3d18c..92b07c7 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -441,9 +441,6 @@ public: #ifdef Q_WS_MAC static bool native_modal_dialog_active; #endif -#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE) - static bool inSizeMove; -#endif static void setSystemPalette(const QPalette &pal); static void setPalette_helper(const QPalette &palette, const char* className, bool clearWidgetPaletteHash); diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 5bb25fa..522f1ac 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -1916,11 +1916,9 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam #ifndef Q_WS_WINCE case WM_ENTERSIZEMOVE: autoCaptureWnd = hwnd; - QApplicationPrivate::inSizeMove = true; break; case WM_EXITSIZEMOVE: autoCaptureWnd = 0; - QApplicationPrivate::inSizeMove = false; break; #endif case WM_MOVE: // move window diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 7c07df8..7facd91 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -497,18 +497,6 @@ static inline void sendUpdateRequest(QWidget *widget, bool updateImmediately) if (!widget) return; -#if defined(Q_WS_WIN) && !defined(Q_OS_WINCE) - if (QApplicationPrivate::inSizeMove && widget->internalWinId() && !updateImmediately - && !widget->testAttribute(Qt::WA_DontShowOnScreen)) { - // Tell Windows to send us a paint event if we're in WM_SIZE/WM_MOVE; posted events - // are blocked until the mouse button is released. See task 146849. - const QRegion rgn(qt_dirtyRegion(widget)); - InvalidateRgn(widget->internalWinId(), rgn.handle(), false); - qt_widget_private(widget)->dirty = QRegion(); - return; - } -#endif - if (updateImmediately) { QEvent event(QEvent::UpdateRequest); QApplication::sendEvent(widget, &event); -- cgit v0.12 From e28e6772e79df9b2adf70e21969af8cac28dc9cf Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 21 Oct 2009 12:33:35 +0200 Subject: Use GetStatusQueue() to look for timer and input messages This function works more reliably than PeekMessage() with different flags. --- src/corelib/kernel/qeventdispatcher_win.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index f7de29d..eca94fc 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -482,8 +482,7 @@ LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp) int localSerialNumber = d->serialNumber; MSG peeked; - if (PeekMessage(&peeked, d->internalHwnd, WM_TIMER, WM_TIMER, PM_NOREMOVE) - || PeekMessage(&peeked, NULL, 0, 0, PM_NOREMOVE | PM_QS_INPUT)) { + if (GetQueueStatus(QS_INPUT | QS_RAWINPUT | QS_TIMER) != 0) { // delay the next pass of sendPostedEvents() until we get the special // WM_TIMER, which allows all pending Windows messages to be processed SetTimer(d->internalHwnd, ~0u, 0, 0); -- cgit v0.12 From 4279889ebebb9fdd026fc107f60f825fb2ad565e Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 21 Oct 2009 14:02:32 +0200 Subject: Compile on Windows when QS_RAWINPUT is not defined. --- src/corelib/kernel/qeventdispatcher_win.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index eca94fc..df4c02d 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -64,6 +64,10 @@ extern uint qGlobalPostedEventsCount(); # define TIME_KILL_SYNCHRONOUS 0x0100 #endif +#ifndef QS_RAWINPUT +# define QS_RAWINPUT 0x0400 +#endif + enum { WM_QT_SOCKETNOTIFIER = WM_USER, WM_QT_SENDPOSTEDEVENTS = WM_USER + 1 @@ -481,7 +485,6 @@ LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp) } else if (message == WM_QT_SENDPOSTEDEVENTS) { int localSerialNumber = d->serialNumber; - MSG peeked; if (GetQueueStatus(QS_INPUT | QS_RAWINPUT | QS_TIMER) != 0) { // delay the next pass of sendPostedEvents() until we get the special // WM_TIMER, which allows all pending Windows messages to be processed -- cgit v0.12 From 3481db791c3b48e28f1a9531b247adf6562edb71 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Thu, 22 Oct 2009 16:39:14 +0200 Subject: Remove internal widgets from QApplication::topLevelWidgets() We have some internal hidden widgets which should not come up in the QApplication::topLevelWidgets() list. So the known ones are being removed from the QWidgetPrivate::allWidgets set. Task-number: QTBUG-739 Reviewed-by: Denis Dzyubenko Reviewed-by: Bradley T. Hughes --- src/gui/kernel/qclipboard_win.cpp | 4 ++++ src/gui/kernel/qclipboard_x11.cpp | 9 +++++++++ src/gui/kernel/qwidget_win.cpp | 3 +++ src/gui/styles/qwindowsxpstyle.cpp | 5 +++++ src/opengl/qwindowsurface_gl.cpp | 5 ++++- tests/auto/qapplication/tst_qapplication.cpp | 22 ++++++++++++++++++++++ 6 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qclipboard_win.cpp b/src/gui/kernel/qclipboard_win.cpp index 7f7ef0c..0157052 100644 --- a/src/gui/kernel/qclipboard_win.cpp +++ b/src/gui/kernel/qclipboard_win.cpp @@ -51,6 +51,7 @@ #include "qmime.h" #include "qt_windows.h" #include "qdnd_p.h" +#include QT_BEGIN_NAMESPACE @@ -140,6 +141,9 @@ public: clipBoardViewer = new QWidget(); clipBoardViewer->createWinId(); clipBoardViewer->setObjectName(QLatin1String("internal clipboard owner")); + // We dont need this internal widget to appear in QApplication::topLevelWidgets() + if (QWidgetPrivate::allWidgets) + QWidgetPrivate::allWidgets->remove(clipBoardViewer); } ~QClipboardData() diff --git a/src/gui/kernel/qclipboard_x11.cpp b/src/gui/kernel/qclipboard_x11.cpp index 9621944..22d7c9e 100644 --- a/src/gui/kernel/qclipboard_x11.cpp +++ b/src/gui/kernel/qclipboard_x11.cpp @@ -78,6 +78,7 @@ #include "qimagewriter.h" #include "qvariant.h" #include "qdnd_p.h" +#include #ifndef QT_NO_XFIXES #include @@ -131,6 +132,11 @@ void setupOwner() requestor = new QWidget(0); requestor->createWinId(); requestor->setObjectName(QLatin1String("internal clipboard requestor")); + // We dont need this internal widgets to appear in QApplication::topLevelWidgets() + if (QWidgetPrivate::allWidgets) { + QWidgetPrivate::allWidgets->remove(owner); + QWidgetPrivate::allWidgets->remove(requestor); + } qAddPostRoutine(cleanup); } @@ -769,6 +775,9 @@ QByteArray QX11Data::clipboardReadIncrementalProperty(Window win, Atom property, delete requestor; requestor = new QWidget(0); requestor->setObjectName(QLatin1String("internal clipboard requestor")); + // We dont need this internal widget to appear in QApplication::topLevelWidgets() + if (QWidgetPrivate::allWidgets) + QWidgetPrivate::allWidgets->remove(requestor); return QByteArray(); } diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp index 2b11bec..0672fee 100644 --- a/src/gui/kernel/qwidget_win.cpp +++ b/src/gui/kernel/qwidget_win.cpp @@ -161,6 +161,9 @@ static void qt_tablet_init() qt_tablet_widget = new QWidget(0); qt_tablet_widget->createWinId(); qt_tablet_widget->setObjectName(QLatin1String("Qt internal tablet widget")); + // We dont need this internal widget to appear in QApplication::topLevelWidgets() + if (QWidgetPrivate::allWidgets) + QWidgetPrivate::allWidgets->remove(qt_tablet_widget); LOGCONTEXT lcMine; qAddPostRoutine(qt_tablet_cleanup); struct tagAXIS tpOri[3]; diff --git a/src/gui/styles/qwindowsxpstyle.cpp b/src/gui/styles/qwindowsxpstyle.cpp index 9ef30e5..2f00f07 100644 --- a/src/gui/styles/qwindowsxpstyle.cpp +++ b/src/gui/styles/qwindowsxpstyle.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -299,7 +300,11 @@ HWND QWindowsXPStylePrivate::winId(const QWidget *widget) if (!limboWidget) { limboWidget = new QWidget(0); + limboWidget->createWinId(); limboWidget->setObjectName(QLatin1String("xp_limbo_widget")); + // We dont need this internal widget to appear in QApplication::topLevelWidgets() + if (QWidgetPrivate::allWidgets) + QWidgetPrivate::allWidgets->remove(limboWidget); } return limboWidget->winId(); diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index 4547416..dcbf021 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -49,12 +49,12 @@ #include #include #include +#include #include "qdebug.h" #ifdef Q_WS_X11 #include #include -#include #ifndef QT_OPENGL_ES #include @@ -195,6 +195,9 @@ public: if (!initializing && !widget && !cleanedUp) { initializing = true; widget = new QGLWidget; + // We dont need this internal widget to appear in QApplication::topLevelWidgets() + if (QWidgetPrivate::allWidgets) + QWidgetPrivate::allWidgets->remove(widget); initializing = false; } return widget; diff --git a/tests/auto/qapplication/tst_qapplication.cpp b/tests/auto/qapplication/tst_qapplication.cpp index 97aa092..e8e1ef0 100644 --- a/tests/auto/qapplication/tst_qapplication.cpp +++ b/tests/auto/qapplication/tst_qapplication.cpp @@ -129,6 +129,7 @@ private slots: void style(); void allWidgets(); + void topLevelWidgets(); void setAttribute(); @@ -1792,6 +1793,27 @@ void tst_QApplication::allWidgets() QVERIFY(!app.allWidgets().contains(w)); // removal test } +void tst_QApplication::topLevelWidgets() +{ + int argc = 1; + QApplication app(argc, &argv0, QApplication::GuiServer); + QWidget *w = new QWidget; + w->show(); +#ifndef QT_NO_CLIPBOARD + QClipboard *clipboard = QApplication::clipboard(); + QString originalText = clipboard->text(); + clipboard->setText(QString("newText")); +#endif + app.processEvents(); + QVERIFY(QApplication::topLevelWidgets().contains(w)); + QCOMPARE(QApplication::topLevelWidgets().count(), 1); + delete w; + w = 0; + app.processEvents(); + QCOMPARE(QApplication::topLevelWidgets().count(), 0); +} + + void tst_QApplication::setAttribute() { -- cgit v0.12 From 706c3f846b97c74c5e15395b6e2d306c522ba769 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Thu, 22 Oct 2009 22:09:03 +0200 Subject: Optimisation for filtering events for gestures in graphics view. We shouldn't add several graphicsobject contexts for the same gesture type when looking for the gesture-enabled QGraphicsObject under a hotspot. Reviewed-by: Thomas Zander --- src/gui/kernel/qgesturemanager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index ed8e744..0601457 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -352,8 +352,10 @@ bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event) for (ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(), e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) { if (it.value() == Qt::ItemWithChildrenGesture) { - if (!types.contains(it.key())) + if (!types.contains(it.key())) { + types.insert(it.key()); contexts.insertMulti(item, it.key()); + } } } item = item->parentObject(); -- cgit v0.12 From dc54674e9f8998b4aee3a58d06f6b5533ccd3cfe Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Thu, 22 Oct 2009 22:41:43 +0200 Subject: Implemented QGestureEvent::activeGestures and canceledGestures. Reviewed-by: Thomas Zander --- src/gui/kernel/qevent.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 065bd09..74dfa53 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -4262,7 +4262,12 @@ QGesture *QGestureEvent::gesture(Qt::GestureType type) const */ QList QGestureEvent::activeGestures() const { - return d_func()->gestures; + QList gestures; + foreach (QGesture *gesture, d_func()->gestures) { + if (gesture->state() != Qt::GestureCanceled) + gestures.append(gesture); + } + return gestures; } /*! @@ -4270,7 +4275,12 @@ QList QGestureEvent::activeGestures() const */ QList QGestureEvent::canceledGestures() const { - return d_func()->gestures; + QList gestures; + foreach (QGesture *gesture, d_func()->gestures) { + if (gesture->state() == Qt::GestureCanceled) + gestures.append(gesture); + } + return gestures; } /*! -- cgit v0.12 From f3cbbd7b8388b4c7445a5fa56d59abdae6c532cb Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Thu, 22 Oct 2009 22:39:24 +0200 Subject: Added convenience functions QGestureEvent::setAccepted with a gesture type argument. Reviewed-by: Thomas Zander --- src/gui/kernel/qevent.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++---- src/gui/kernel/qevent.h | 5 ++++ 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 74dfa53..ea05869 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -4298,9 +4298,8 @@ QList QGestureEvent::canceledGestures() const */ void QGestureEvent::setAccepted(QGesture *gesture, bool value) { - setAccepted(false); if (gesture) - d_func()->accepted[gesture->gestureType()] = value; + setAccepted(gesture->gestureType(), value); } /*! @@ -4314,7 +4313,8 @@ void QGestureEvent::setAccepted(QGesture *gesture, bool value) */ void QGestureEvent::accept(QGesture *gesture) { - setAccepted(gesture, true); + if (gesture) + setAccepted(gesture->gestureType(), true); } /*! @@ -4328,7 +4328,8 @@ void QGestureEvent::accept(QGesture *gesture) */ void QGestureEvent::ignore(QGesture *gesture) { - setAccepted(gesture, false); + if (gesture) + setAccepted(gesture->gestureType(), false); } /*! @@ -4336,7 +4337,64 @@ void QGestureEvent::ignore(QGesture *gesture) */ bool QGestureEvent::isAccepted(QGesture *gesture) const { - return gesture ? d_func()->accepted.value(gesture->gestureType(), true) : false; + return gesture ? isAccepted(gesture->gestureType()) : false; +} + +/*! + Sets the accept flag of the given \a gestureType object to the specified + \a value. + + Setting the accept flag indicates that the event receiver wants the \a gesture. + Unwanted gestures may be propagated to the parent widget. + + By default, gestures in events of type QEvent::Gesture are accepted, and + gestures in QEvent::GestureOverride events are ignored. + + For convenience, the accept flag can also be set with + \l{QGestureEvent::accept()}{accept(gestureType)}, and cleared with + \l{QGestureEvent::ignore()}{ignore(gestureType)}. +*/ +void QGestureEvent::setAccepted(Qt::GestureType gestureType, bool value) +{ + setAccepted(false); + d_func()->accepted[gestureType] = value; +} + +/*! + Sets the accept flag of the given \a gestureType, the equivalent of calling + \l{QGestureEvent::setAccepted()}{setAccepted(gestureType, true)}. + + Setting the accept flag indicates that the event receiver wants the + gesture. Unwanted gestures may be propagated to the parent widget. + + \sa QGestureEvent::ignore() +*/ +void QGestureEvent::accept(Qt::GestureType gestureType) +{ + setAccepted(gestureType, true); +} + +/*! + Clears the accept flag parameter of the given \a gestureType, the equivalent + of calling \l{QGestureEvent::setAccepted()}{setAccepted(gesture, false)}. + + Clearing the accept flag indicates that the event receiver does not + want the gesture. Unwanted gestures may be propgated to the parent widget. + + \sa QGestureEvent::accept() +*/ +void QGestureEvent::ignore(Qt::GestureType gestureType) +{ + setAccepted(gestureType, false); +} + +/*! + Returns true if the gesture of type \a gestureType is accepted; otherwise + returns false. +*/ +bool QGestureEvent::isAccepted(Qt::GestureType gestureType) const +{ + return d_func()->accepted.value(gestureType, true); } /*! diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index b7370fd..fb245c0 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -851,6 +851,11 @@ public: void ignore(QGesture *); bool isAccepted(QGesture *) const; + void setAccepted(Qt::GestureType, bool); + void accept(Qt::GestureType); + void ignore(Qt::GestureType); + bool isAccepted(Qt::GestureType) const; + void setWidget(QWidget *widget); QWidget *widget() const; -- cgit v0.12 From 20cddedfe5f422eb0607a5ac85870267b2788117 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Fri, 23 Oct 2009 13:04:19 +0200 Subject: Unregister the temporary gesture recognizer in the gestures autotest. Reviewed-by: trustme --- tests/auto/gestures/tst_gestures.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index 92f979f..800af1b 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -341,6 +341,7 @@ void tst_Gestures::initTestCase() void tst_Gestures::cleanupTestCase() { + qApp->unregisterGestureRecognizer(CustomGesture::GestureType); } void tst_Gestures::init() @@ -547,6 +548,8 @@ void tst_Gestures::conflictingGestures() QCOMPARE(child->events.all.count(), TotalGestureEventsCount + ContinuousGestureEventsCount); QCOMPARE(parent.gestureOverrideEventsReceived, 0); QCOMPARE(parent.gestureEventsReceived, 0); + + qApp->unregisterGestureRecognizer(ContinuousGesture); } void tst_Gestures::finishedWithoutStarted() @@ -978,6 +981,8 @@ void tst_Gestures::twoGesturesOnDifferentLevel() QCOMPARE(parent.events.all.size(), TotalGestureEventsCount); for(int i = 0; i < child->events.all.size(); ++i) QCOMPARE(parent.events.all.at(i), CustomGesture::GestureType); + + qApp->unregisterGestureRecognizer(SecondGesture); } void tst_Gestures::multipleGesturesInTree() @@ -1046,6 +1051,9 @@ void tst_Gestures::multipleGesturesInTree() QCOMPARE(A->events.all.count(FirstGesture), TotalGestureEventsCount); QCOMPARE(A->events.all.count(SecondGesture), 0); QCOMPARE(A->events.all.count(ThirdGesture), TotalGestureEventsCount); + + qApp->unregisterGestureRecognizer(SecondGesture); + qApp->unregisterGestureRecognizer(ThirdGesture); } void tst_Gestures::multipleGesturesInComplexTree() @@ -1139,6 +1147,13 @@ void tst_Gestures::multipleGesturesInComplexTree() QCOMPARE(A->events.all.count(FifthGesture), 0); QCOMPARE(A->events.all.count(SixthGesture), 0); QCOMPARE(A->events.all.count(SeventhGesture), 0); + + qApp->unregisterGestureRecognizer(SecondGesture); + qApp->unregisterGestureRecognizer(ThirdGesture); + qApp->unregisterGestureRecognizer(FourthGesture); + qApp->unregisterGestureRecognizer(FifthGesture); + qApp->unregisterGestureRecognizer(SixthGesture); + qApp->unregisterGestureRecognizer(SeventhGesture); } void tst_Gestures::testMapToScene() -- cgit v0.12 From 92d8b0e1d6ecce8214b24a08b8a199af4321bd88 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 21 Oct 2009 12:40:59 +0200 Subject: Implement QApplication::unregisterGestureRecognizer Reviewed-by: Denis Dzyubenko --- src/gui/kernel/qapplication.cpp | 4 +++- src/gui/kernel/qgesturemanager.cpp | 42 +++++++++++++++++++++++++++++++++++--- src/gui/kernel/qgesturemanager_p.h | 9 ++++++-- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 202d450..e64dfd2 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -5642,7 +5642,9 @@ Qt::GestureType QApplication::registerGestureRecognizer(QGestureRecognizer *reco */ void QApplication::unregisterGestureRecognizer(Qt::GestureType type) { - QGestureManager::instance()->unregisterGestureRecognizer(type); + QApplicationPrivate *d = qApp->d_func(); + if (d->gestureManager) + d->gestureManager->unregisterGestureRecognizer(type); } QT_END_NAMESPACE diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index 0601457..dc76c3f 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -104,9 +104,29 @@ Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *r return type; } -void QGestureManager::unregisterGestureRecognizer(Qt::GestureType) +void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type) { + QList list = recognizers.values(type); + recognizers.remove(type); + foreach (QGesture* g, gestureToRecognizer.keys()) { + QGestureRecognizer *recognizer = gestureToRecognizer.value(g); + if (list.contains(recognizer)) { + m_deletedRecognizers.insert(g, recognizer); + gestureToRecognizer.remove(g); + } + } + foreach (QGestureRecognizer *recognizer, list) { + QList obsoleteGestures; + QMap::Iterator iter = objectGestures.begin(); + while (iter != objectGestures.end()) { + ObjectGesture objectGesture = iter.key(); + if (objectGesture.gesture == type) + obsoleteGestures << iter.value(); + ++iter; + } + m_obsoleteGestures.insert(recognizer, obsoleteGestures); + } } QGesture *QGestureManager::getState(QObject *object, Qt::GestureType type) @@ -290,14 +310,28 @@ bool QGestureManager::filterEventThroughContexts(const QMap endedGestures = finishedGestures + canceledGestures + undeliveredGestures; foreach (QGesture *gesture, endedGestures) { - if (QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0)) { + if (QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0)) recognizer->reset(gesture); - } + else + cleanupGesturesForRemovedRecognizer(gesture); gestureTargets.remove(gesture); } return false; } +void QGestureManager::cleanupGesturesForRemovedRecognizer(QGesture *gesture) +{ + QGestureRecognizer *recognizer = m_deletedRecognizers.value(gesture); + Q_ASSERT(recognizer); + m_deletedRecognizers.remove(gesture); + if (m_deletedRecognizers.keys(recognizer).isEmpty()) { + // no more active gestures, cleanup! + qDeleteAll(m_obsoleteGestures.value(recognizer)); + m_obsoleteGestures.remove(recognizer); + delete recognizer; + } +} + bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) { QSet types; @@ -534,6 +568,8 @@ void QGestureManager::timerEvent(QTimerEvent *event) QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0); if (recognizer) recognizer->reset(gesture); + else + cleanupGesturesForRemovedRecognizer(gesture); } else { ++it; } diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h index f0e7225..eef45d2 100644 --- a/src/gui/kernel/qgesturemanager_p.h +++ b/src/gui/kernel/qgesturemanager_p.h @@ -104,7 +104,7 @@ private: Qt::GestureType gesture; ObjectGesture(QObject *o, const Qt::GestureType &g) : object(o), gesture(g) { } - inline bool operator<(const ObjectGesture& rhs) const + inline bool operator<(const ObjectGesture &rhs) const { if (object.data() < rhs.object.data()) return true; @@ -114,7 +114,8 @@ private: } }; - QMap objectGestures; + // TODO rename all member vars to be m_ + QMap objectGestures; // TODO rename widgetGestures QMap gestureToRecognizer; QHash gestureOwners; @@ -122,6 +123,10 @@ private: int lastCustomGestureId; + QHash > m_obsoleteGestures; + QMap m_deletedRecognizers; + void cleanupGesturesForRemovedRecognizer(QGesture *gesture); + QGesture *getState(QObject *widget, Qt::GestureType gesture); void deliverEvents(const QSet &gestures, QSet *undeliveredGestures); -- cgit v0.12 From 25bc5c29db866d5abc3f9fbae7b5211e2e6b1f25 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 21 Oct 2009 13:58:24 +0200 Subject: Add QWidget::ungrabGesture Reviewed-by: Denis Dzyubenko --- src/gui/kernel/qgesturemanager.cpp | 16 ++++++++ src/gui/kernel/qgesturemanager_p.h | 2 + src/gui/kernel/qwidget.cpp | 16 ++++++++ src/gui/kernel/qwidget.h | 1 + tests/auto/gestures/tst_gestures.cpp | 71 ++++++++++++++++++++++++++++++++++++ 5 files changed, 106 insertions(+) diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index dc76c3f..df88f9e 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -129,6 +129,21 @@ void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type) } } +void QGestureManager::cleanupCachedGestures(QObject *target, Qt::GestureType type) +{ + QMap::Iterator iter = objectGestures.begin(); + while (iter != objectGestures.end()) { + ObjectGesture objectGesture = iter.key(); + if (objectGesture.gesture == type && target == objectGesture.object.data()) { + delete iter.value(); + iter = objectGestures.erase(iter); + } else { + ++iter; + } + } +} + +// get or create a QGesture object that will represent the state for a given object, used by the recognizer QGesture *QGestureManager::getState(QObject *object, Qt::GestureType type) { // if the widget is being deleted we should be carefull and not to @@ -332,6 +347,7 @@ void QGestureManager::cleanupGesturesForRemovedRecognizer(QGesture *gesture) } } +// return true if accepted (consumed) bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) { QSet types; diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h index eef45d2..96c2fb7 100644 --- a/src/gui/kernel/qgesturemanager_p.h +++ b/src/gui/kernel/qgesturemanager_p.h @@ -79,6 +79,8 @@ public: // declared in qapplication.cpp static QGestureManager* instance(); + void cleanupCachedGestures(QObject *target, Qt::GestureType type); + protected: void timerEvent(QTimerEvent *event); bool filterEventThroughContexts(const QMap &contexts, diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 5fa9a92..c10db90 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -11708,6 +11708,22 @@ void QWidget::grabGesture(Qt::GestureType gesture, Qt::GestureContext context) (void)QGestureManager::instance(); // create a gesture manager } +/*! + Unsubscribes the widget to a given \a gesture type + + \sa QGestureEvent + \since 4.6 +*/ +void QWidget::ungrabGesture(Qt::GestureType gesture) +{ + Q_D(QWidget); + if (d->gestureContext.remove(gesture)) { + QGestureManager *manager = QGestureManager::instance(); + manager->cleanupCachedGestures(this, gesture); + } +} + + QT_END_NAMESPACE #include "moc_qwidget.cpp" diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h index e603a1a..fce3f09 100644 --- a/src/gui/kernel/qwidget.h +++ b/src/gui/kernel/qwidget.h @@ -355,6 +355,7 @@ public: void setGraphicsEffect(QGraphicsEffect *effect); void grabGesture(Qt::GestureType type, Qt::GestureContext context = Qt::WidgetWithChildrenGesture); + void ungrabGesture(Qt::GestureType type); public Q_SLOTS: void setWindowTitle(const QString &); diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index 800af1b..6e52de3 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -280,6 +280,7 @@ protected: } }; +// TODO rename to sendGestureSequence static void sendCustomGesture(CustomEvent *event, QObject *object, QGraphicsScene *scene = 0) { for (int i = CustomGesture::SerialMaybeThreshold; @@ -322,6 +323,7 @@ private slots: void multipleGesturesInTree(); void multipleGesturesInComplexTree(); void testMapToScene(); + void ungrabGesture(); }; tst_Gestures::tst_Gestures() @@ -1181,5 +1183,74 @@ void tst_Gestures::testMapToScene() QCOMPARE(event.mapToScene(origin + QPoint(100, 200)), view.mapToScene(QPoint(100, 200))); } +void tst_Gestures::ungrabGesture() // a method on QWidget +{ + class MockGestureWidget : public GestureWidget { + public: + MockGestureWidget(const char *name = 0, QWidget *parent = 0) + : GestureWidget(name, parent) { } + + + QSet gestures; + protected: + bool event(QEvent *event) + { + if (event->type() == QEvent::Gesture) { + QGestureEvent *gestureEvent = static_cast(event); + if (gestureEvent) + foreach (QGesture *g, gestureEvent->allGestures()) + gestures.insert(g); + } + return GestureWidget::event(event); + } + }; + + MockGestureWidget parent("A"); + MockGestureWidget *a = &parent; + MockGestureWidget *b = new MockGestureWidget("B", a); + + a->grabGesture(CustomGesture::GestureType, Qt::WidgetGesture); + b->grabGesture(CustomGesture::GestureType, Qt::WidgetWithChildrenGesture); + b->ignoredGestures << CustomGesture::GestureType; + + CustomEvent event; + // sending an event will cause the QGesture objects to be instantiated for the widgets + sendCustomGesture(&event, b); + + QCOMPARE(a->gestures.count(), 1); + QPointer customGestureA; + customGestureA = *(a->gestures.begin()); + QVERIFY(!customGestureA.isNull()); + QCOMPARE(customGestureA->gestureType(), CustomGesture::GestureType); + + QCOMPARE(b->gestures.count(), 1); + QPointer customGestureB; + customGestureB = *(b->gestures.begin()); + QVERIFY(!customGestureB.isNull()); + QVERIFY(customGestureA.data() == customGestureB.data()); + QCOMPARE(customGestureB->gestureType(), CustomGesture::GestureType); + + a->gestures.clear(); + // sending an event will cause the QGesture objects to be instantiated for the widget + sendCustomGesture(&event, a); + + QCOMPARE(a->gestures.count(), 1); + customGestureA = *(a->gestures.begin()); + QVERIFY(!customGestureA.isNull()); + QCOMPARE(customGestureA->gestureType(), CustomGesture::GestureType); + QVERIFY(customGestureA.data() != customGestureB.data()); + + a->ungrabGesture(CustomGesture::GestureType); + QVERIFY(customGestureA.isNull()); + QVERIFY(!customGestureB.isNull()); + + a->gestures.clear(); + a->reset(); + // send again to 'b' and make sure a never gets it. + sendCustomGesture(&event, b); + QCOMPARE(a->gestureEventsReceived, 0); + QCOMPARE(a->gestureOverrideEventsReceived, 0); +} + QTEST_MAIN(tst_Gestures) #include "tst_gestures.moc" -- cgit v0.12 From 487570340062a1165e0473e2557f844b097db526 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Fri, 23 Oct 2009 15:43:50 +0200 Subject: Fix memory leaks in the gesture manager Reviewed-by: Denis Dzyubenko --- src/gui/kernel/qgesturemanager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index df88f9e..0139533 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -82,7 +82,7 @@ QGestureManager::QGestureManager(QObject *parent) QGestureManager::~QGestureManager() { - + qDeleteAll(recognizers.values()); } Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *recognizer) @@ -166,6 +166,7 @@ QGesture *QGestureManager::getState(QObject *object, Qt::GestureType type) state = recognizer->createGesture(object); if (!state) return 0; + state->setParent(this); if (state->gestureType() == Qt::CustomGesture) { // if the recognizer didn't fill in the gesture type, then this // is a custom gesture with autogenerated it and we fill it. -- cgit v0.12 From 293ee52fce78b74fcfa2effbccf6df6f12e9daa5 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Fri, 23 Oct 2009 15:44:37 +0200 Subject: Fix the debug output to be correct again after refactoring Reviewed-by: Denis Dzyubenko --- src/gui/kernel/qgesturemanager.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index 0139533..9890a12 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -212,21 +212,21 @@ bool QGestureManager::filterEventThroughContexts(const QMapfilterEvent(state, target, event); QGestureRecognizer::Result type = result & QGestureRecognizer::ResultState_Mask; if (type == QGestureRecognizer::GestureTriggered) { - DEBUG() << "QGestureManager: gesture triggered: " << state; + DEBUG() << "QGestureManager:Recognizer: gesture triggered: " << state; triggeredGestures << state; } else if (type == QGestureRecognizer::GestureFinished) { - DEBUG() << "QGestureManager: gesture finished: " << state; + DEBUG() << "QGestureManager:Recognizer: gesture finished: " << state; finishedGestures << state; } else if (type == QGestureRecognizer::MaybeGesture) { - DEBUG() << "QGestureManager: maybe gesture: " << state; + DEBUG() << "QGestureManager:Recognizer: maybe gesture: " << state; newMaybeGestures << state; } else if (type == QGestureRecognizer::NotGesture) { - DEBUG() << "QGestureManager: not gesture: " << state; + DEBUG() << "QGestureManager:Recognizer: not gesture: " << state; notGestures << state; } else if (type == QGestureRecognizer::Ignore) { - DEBUG() << "QGestureManager: gesture ignored the event: " << state; + DEBUG() << "QGestureManager:Recognizer: ignored the event: " << state; } else { - DEBUG() << "QGestureManager: hm, lets assume the recognizer" + DEBUG() << "QGestureManager:Recognizer: hm, lets assume the recognizer" << "ignored the event: " << state; } if (result & QGestureRecognizer::ConsumeEventHint) { @@ -307,7 +307,7 @@ bool QGestureManager::filterEventThroughContexts(const QMap Date: Mon, 26 Oct 2009 13:36:30 +0100 Subject: Removed the obsolete documentation reference from the QGesture. Reviewed-by: trustme --- src/gui/kernel/qgesture.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index ecdd661..a161876 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -142,12 +142,6 @@ QGesture::~QGesture() \brief whether the gesture has a hot-spot */ -/*! - \property QGesture::targetObject - \brief the target object which will receive the gesture event if the hotSpot is - not set -*/ - Qt::GestureType QGesture::gestureType() const { return d_func()->gestureType; -- cgit v0.12 From 3bc088fad760bd50eec05b323a056641247a9a59 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Tue, 27 Oct 2009 10:56:39 +0100 Subject: QTabbar is not behaving (painting) like native ones on Mac. When a tab is clicked and mouse is moved outside that tab, it should be drawn as normal (not in sunken state). Reviewed-by: MortenS --- src/gui/widgets/qtabbar.cpp | 18 +++++++++++++++++- src/gui/widgets/qtabbar_p.h | 10 ++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp index 6c9761c..4dffbdc 100644 --- a/src/gui/widgets/qtabbar.cpp +++ b/src/gui/widgets/qtabbar.cpp @@ -1694,6 +1694,9 @@ void QTabBar::mousePressEvent(QMouseEvent *event) d->moveTabFinished(d->pressedIndex); d->pressedIndex = d->indexAtPos(event->pos()); +#ifdef Q_WS_MAC + d->previousPressedIndex = d->pressedIndex; +#endif if (d->validIndex(d->pressedIndex)) { QStyleOptionTabBarBaseV2 optTabBase; optTabBase.init(this); @@ -1774,6 +1777,17 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event) update(); } +#ifdef Q_WS_MAC + } else if (!d->documentMode && event->buttons() == Qt::LeftButton && d->previousPressedIndex != -1) { + int newPressedIndex = d->indexAtPos(event->pos()); + if (d->pressedIndex == -1 && d->previousPressedIndex == newPressedIndex) { + d->pressedIndex = d->previousPressedIndex; + update(tabRect(d->pressedIndex)); + } else if(d->pressedIndex != newPressedIndex) { + d->pressedIndex = -1; + update(tabRect(d->previousPressedIndex)); + } +#endif } if (event->buttons() != Qt::LeftButton) { @@ -1865,7 +1879,9 @@ void QTabBar::mouseReleaseEvent(QMouseEvent *event) event->ignore(); return; } - +#ifdef Q_WS_MAC + d->previousPressedIndex = -1; +#endif if (d->movable && d->dragInProgress && d->validIndex(d->pressedIndex)) { int length = d->tabList[d->pressedIndex].dragOffset; int width = verticalTabs(d->shape) diff --git a/src/gui/widgets/qtabbar_p.h b/src/gui/widgets/qtabbar_p.h index 494a340..9f3285b 100644 --- a/src/gui/widgets/qtabbar_p.h +++ b/src/gui/widgets/qtabbar_p.h @@ -77,7 +77,11 @@ public: :currentIndex(-1), pressedIndex(-1), shape(QTabBar::RoundedNorth), layoutDirty(false), drawBase(true), scrollOffset(0), expanding(true), closeButtonOnTabs(false), selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false), - dragInProgress(false), documentMode(false), movingTab(0) {} + dragInProgress(false), documentMode(false), movingTab(0) +#ifdef Q_WS_MAC + , previousPressedIndex(-1) +#endif + {} int currentIndex; int pressedIndex; @@ -195,7 +199,9 @@ public: bool documentMode; QWidget *movingTab; - +#ifdef Q_WS_MAC + int previousPressedIndex; +#endif // shared by tabwidget and qtabbar static void initStyleBaseOption(QStyleOptionTabBarBaseV2 *optTabBase, QTabBar *tabbar, QSize size) { -- cgit v0.12 From 124df35db0be3ae7578635735b4e64c589d07cba Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Tue, 27 Oct 2009 14:01:58 +0100 Subject: Selected tab is drawn incorrectly on Snow Leopard. The default height of tab bar is 22 pixels in Snow Leopard. We used to draw tabs taller than 21 pixels to a pixmap and stretch to the required size. The limit is now changed to 22 pixels (which is the most common use case). The stretched drawing is not perfect in Snow Leopard due to some changes in how HITheme draws tabs. Reviewed-by: Jens Bache-Wiig --- src/gui/styles/qmacstyle_mac.mm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm index 63ba641..4dcb469 100644 --- a/src/gui/styles/qmacstyle_mac.mm +++ b/src/gui/styles/qmacstyle_mac.mm @@ -3637,17 +3637,19 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter break; } } + bool stretchTabs = (!verticalTabs && tabRect.height() > 22 || verticalTabs && tabRect.width() > 22); + switch (tp) { case QStyleOptionTab::Beginning: tdi.position = kHIThemeTabPositionFirst; - if (sp != QStyleOptionTab::NextIsSelected) + if (sp != QStyleOptionTab::NextIsSelected || stretchTabs) tdi.adornment |= kHIThemeTabAdornmentTrailingSeparator; break; case QStyleOptionTab::Middle: tdi.position = kHIThemeTabPositionMiddle; if (selected) tdi.adornment |= kHIThemeTabAdornmentLeadingSeparator; - if (sp != QStyleOptionTab::NextIsSelected) // Also when we're selected. + if (sp != QStyleOptionTab::NextIsSelected || stretchTabs) // Also when we're selected. tdi.adornment |= kHIThemeTabAdornmentTrailingSeparator; break; case QStyleOptionTab::End: @@ -3659,9 +3661,8 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter tdi.position = kHIThemeTabPositionOnly; break; } - // HITheme doesn't stretch its tabs. Therefore we have to cheat and do the job ourselves. - if ((!verticalTabs && tabRect.height() > 21 || verticalTabs && tabRect.width() > 21)) { + if (stretchTabs) { HIRect hirect = CGRectMake(0, 0, 23, 23); QPixmap pm(23, 23); pm.fill(Qt::transparent); -- cgit v0.12 From e5c87d92fa6380c13ff47ce1fe6d85a02dc92794 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 27 Oct 2009 15:05:22 +0100 Subject: Improved gesture autotest reliability on X11. Reviewed-by: trustme --- tests/auto/gestures/tst_gestures.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index 6e52de3..edfbf32 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -715,6 +715,7 @@ void tst_Gestures::graphicsItemGesture() { QGraphicsScene scene; QGraphicsView view(&scene); + view.setWindowFlags(Qt::X11BypassWindowManagerHint); GestureItem *item = new GestureItem("item"); scene.addItem(item); @@ -777,6 +778,7 @@ void tst_Gestures::graphicsItemTreeGesture() { QGraphicsScene scene; QGraphicsView view(&scene); + view.setWindowFlags(Qt::X11BypassWindowManagerHint); GestureItem *item1 = new GestureItem("item1"); item1->setPos(100, 100); @@ -834,6 +836,7 @@ void tst_Gestures::explicitGraphicsObjectTarget() { QGraphicsScene scene; QGraphicsView view(&scene); + view.setWindowFlags(Qt::X11BypassWindowManagerHint); GestureItem *item1 = new GestureItem("item1"); scene.addItem(item1); @@ -887,6 +890,7 @@ void tst_Gestures::gestureOverChildGraphicsItem() { QGraphicsScene scene; QGraphicsView view(&scene); + view.setWindowFlags(Qt::X11BypassWindowManagerHint); GestureItem *item0 = new GestureItem("item0"); scene.addItem(item0); @@ -1168,6 +1172,7 @@ void tst_Gestures::testMapToScene() QGraphicsScene scene; QGraphicsView view(&scene); + view.setWindowFlags(Qt::X11BypassWindowManagerHint); GestureItem *item0 = new GestureItem; scene.addItem(item0); -- cgit v0.12 From fcd8edaf6e17463603d81525f2b57fc11f20216b Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 27 Oct 2009 10:41:32 +0100 Subject: Implemented QGestureRecognizer::ConsumeEventHint Reviewed-By: trustme --- src/gui/kernel/qgesturemanager.cpp | 6 ++++-- tests/auto/gestures/tst_gestures.cpp | 21 ++++++++++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index 9890a12..52f8eef 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -196,6 +196,8 @@ bool QGestureManager::filterEventThroughContexts(const QMap::const_iterator ContextIterator; for (ContextIterator cit = contexts.begin(), ce = contexts.end(); cit != ce; ++cit) { @@ -232,7 +234,7 @@ bool QGestureManager::filterEventThroughContexts(const QMaptype() == CustomEvent::EventType) { - QGestureRecognizer::Result result = QGestureRecognizer::ConsumeEventHint; + QGestureRecognizer::Result result = 0; + if (CustomGestureRecognizer::ConsumeEvents) + result |= QGestureRecognizer::ConsumeEventHint; CustomGesture *g = static_cast(state); CustomEvent *e = static_cast(event); g->serial = e->serial; @@ -143,6 +147,7 @@ public: QGestureRecognizer::reset(state); } }; +bool CustomGestureRecognizer::ConsumeEvents = false; // same as CustomGestureRecognizer but triggers early without the maybe state class CustomContinuousGestureRecognizer : public QGestureRecognizer @@ -324,6 +329,7 @@ private slots: void multipleGesturesInComplexTree(); void testMapToScene(); void ungrabGesture(); + void consumeEventHint(); }; tst_Gestures::tst_Gestures() @@ -375,6 +381,19 @@ void tst_Gestures::customGesture() QCOMPARE(widget.events.canceled.size(), 0); } +void tst_Gestures::consumeEventHint() +{ + GestureWidget widget; + widget.grabGesture(CustomGesture::GestureType, Qt::WidgetGesture); + + CustomGestureRecognizer::ConsumeEvents = true; + CustomEvent event; + sendCustomGesture(&event, &widget); + CustomGestureRecognizer::ConsumeEvents = false; + + QCOMPARE(widget.customEventsReceived, 0); +} + void tst_Gestures::autoCancelingGestures() { GestureWidget widget; -- cgit v0.12 From 6efa1085b6a61cf2883b460e5b76bde9576dc4a7 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 27 Oct 2009 15:18:07 +0100 Subject: Renamed QGestureRecognizer::ResultFlags to ResultFlag Decided after review by David Boddie. Reviewed-by: trustme --- src/gui/kernel/qgesturerecognizer.cpp | 2 +- src/gui/kernel/qgesturerecognizer.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/gui/kernel/qgesturerecognizer.cpp index ba3a750..c2b26f0 100644 --- a/src/gui/kernel/qgesturerecognizer.cpp +++ b/src/gui/kernel/qgesturerecognizer.cpp @@ -100,7 +100,7 @@ QT_BEGIN_NAMESPACE */ /*! - \enum QGestureRecognizer::ResultFlags + \enum QGestureRecognizer::ResultFlag This enum describes the result of the current event filtering step in a gesture recognizer state machine. diff --git a/src/gui/kernel/qgesturerecognizer.h b/src/gui/kernel/qgesturerecognizer.h index efd8565..a3c990d 100644 --- a/src/gui/kernel/qgesturerecognizer.h +++ b/src/gui/kernel/qgesturerecognizer.h @@ -56,7 +56,7 @@ class QGesture; class Q_GUI_EXPORT QGestureRecognizer { public: - enum ResultFlags + enum ResultFlag { Ignore = 0x0001, NotGesture = 0x0002, @@ -73,7 +73,7 @@ public: ResultHint_Mask = 0xff00 }; - Q_DECLARE_FLAGS(Result, ResultFlags) + Q_DECLARE_FLAGS(Result, ResultFlag) QGestureRecognizer(); virtual ~QGestureRecognizer(); -- cgit v0.12 From 6c8c1c5322a26d789165783d7df3e29c672690cb Mon Sep 17 00:00:00 2001 From: Helio Chissini de Castro Date: Tue, 27 Oct 2009 18:07:56 +0100 Subject: Fill gap of X.org/XFree multimedia/special/launcher keys Qt up to 4.5.x is missing whole setup of multimedia keys already defined by X Merge-request: 1742 Reviewed-by: Denis Dzyubenko --- src/corelib/global/qnamespace.h | 97 ++++++++++++- src/corelib/global/qnamespace.qdoc | 92 ++++++++++++ src/gui/kernel/qkeymapper_x11.cpp | 286 ++++++++++++++++++++++++++++++------- src/gui/kernel/qkeysequence.cpp | 174 ++++++++++++++++------ 4 files changed, 553 insertions(+), 96 deletions(-) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 2b62c6b..aeaca54 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -909,12 +909,10 @@ public: Key_Dead_Horn = 0x01001262, // multimedia/internet keys - ignored by default - see QKeyEvent c'tor - Key_Back = 0x01000061, Key_Forward = 0x01000062, Key_Stop = 0x01000063, Key_Refresh = 0x01000064, - Key_VolumeDown = 0x01000070, Key_VolumeMute = 0x01000071, Key_VolumeUp = 0x01000072, @@ -923,7 +921,6 @@ public: Key_BassDown = 0x01000075, Key_TrebleUp = 0x01000076, Key_TrebleDown = 0x01000077, - Key_MediaPlay = 0x01000080, Key_MediaStop = 0x01000081, Key_MediaPrevious = 0x01000082, @@ -932,13 +929,11 @@ public: #endif Key_MediaNext = 0x01000083, Key_MediaRecord = 0x01000084, - Key_HomePage = 0x01000090, Key_Favorites = 0x01000091, Key_Search = 0x01000092, Key_Standby = 0x01000093, Key_OpenUrl = 0x01000094, - Key_LaunchMail = 0x010000a0, Key_LaunchMedia = 0x010000a1, Key_Launch0 = 0x010000a2, @@ -957,6 +952,98 @@ public: Key_LaunchD = 0x010000af, Key_LaunchE = 0x010000b0, Key_LaunchF = 0x010000b1, + Key_MonBrightnessUp = 0x010000b2, + Key_MonBrightnessDown = 0x010000b3, + Key_KeyboardLightOnOff = 0x010000b4, + Key_KeyboardBrightnessUp = 0x010000b5, + Key_KeyboardBrightnessDown = 0x010000b6, + Key_PowerOff = 0x010000b7, + Key_WakeUp = 0x010000b8, + Key_Eject = 0x010000b9, + Key_ScreenSaver = 0x010000ba, + Key_WWW = 0x010000bb, + Key_Memo = 0x010000bc, + Key_LightBulb = 0x010000bd, + Key_Shop = 0x010000be, + Key_History = 0x010000bf, + Key_AddFavorite = 0x010000c0, + Key_HotLinks = 0x010000c1, + Key_BrightnessAdjust = 0x010000c2, + Key_Finance = 0x010000c3, + Key_Community = 0x010000c4, + Key_AudioRewind = 0x010000c5, + Key_BackForward = 0x010000c6, + Key_ApplicationLeft = 0x010000c7, + Key_ApplicationRight = 0x010000c8, + Key_Book = 0x010000c9, + Key_CD = 0x010000ca, + Key_Calculator = 0x010000cb, + Key_ToDoList = 0x010000cc, + Key_ClearGrab = 0x010000cd, + Key_Close = 0x010000ce, + Key_Copy = 0x010000cf, + Key_Cut = 0x010000d0, + Key_Display = 0x010000d1, + Key_DOS = 0x010000d2, + Key_Documents = 0x010000d3, + Key_Excel = 0x010000d4, + Key_Explorer = 0x010000d5, + Key_Game = 0x010000d6, + Key_Go = 0x010000d7, + Key_iTouch = 0x010000d8, + Key_LogOff = 0x010000d9, + Key_Market = 0x010000da, + Key_Meeting = 0x010000db, + Key_MenuKB = 0x010000dc, + Key_MenuPB = 0x010000dd, + Key_MySites = 0x010000de, + Key_News = 0x010000df, + Key_OfficeHome = 0x010000e0, + Key_Option = 0x010000e1, + Key_Paste = 0x010000e2, + Key_Phone = 0x010000e3, + Key_Calendar = 0x010000e4, + Key_Reply = 0x010000e5, + Key_Reload = 0x010000e6, + Key_RotateWindows = 0x010000e7, + Key_RotationPB = 0x010000e8, + Key_RotationKB = 0x010000e9, + Key_Save = 0x010000ea, + Key_Send = 0x010000eb, + Key_Spell = 0x010000ec, + Key_SplitScreen = 0x010000ed, + Key_Support = 0x010000ee, + Key_TaskPane = 0x010000ef, + Key_Terminal = 0x010000f0, + Key_Tools = 0x010000f1, + Key_Travel = 0x010000f2, + Key_Video = 0x010000f3, + Key_Word = 0x010000f4, + Key_Xfer = 0x010000f5, + Key_ZoomIn = 0x010000f6, + Key_ZoomOut = 0x010000f7, + Key_Away = 0x010000f8, + Key_Messenger = 0x010000f9, + Key_WebCam = 0x010000fa, + Key_MailForward = 0x010000fb, + Key_Pictures = 0x010000fc, + Key_Music = 0x010000fd, + Key_Battery = 0x010000fe, + Key_Bluetooth = 0x010000ff, + Key_WLAN = 0x01000100, + Key_UWB = 0x01000101, + Key_AudioForward = 0x01000102, + Key_AudioRepeat = 0x01000103, + Key_AudioRandomPlay = 0x01000104, + Key_Subtitle = 0x01000105, + Key_AudioCycleTrack = 0x01000106, + Key_Time = 0x01000107, + Key_Hibernate = 0x01000108, + Key_View = 0x01000109, + Key_TopMenu = 0x0100010a, + Key_PowerDown = 0x0100010b, + Key_Suspend = 0x0100010c, + Key_ContrastAdjust = 0x0100010d, Key_MediaLast = 0x0100ffff, diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index e8d6df0..4a48a8f 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -1609,6 +1609,98 @@ \value Key_LaunchD \value Key_LaunchE \value Key_LaunchF + \value Key_MonBrightnessUp + \value Key_MonBrightnessDown + \value Key_KeyboardLightOnOff + \value Key_KeyboardBrightnessUp + \value Key_KeyboardBrightnessDown + \value Key_PowerOff + \value Key_WakeUp + \value Key_Eject + \value Key_ScreenSaver + \value Key_WWW + \value Key_Memo + \value Key_LightBulb + \value Key_Shop + \value Key_History + \value Key_AddFavorite + \value Key_HotLinks + \value Key_BrightnessAdjust + \value Key_Finance + \value Key_Community + \value Key_AudioRewind + \value Key_BackForward + \value Key_ApplicationLeft + \value Key_ApplicationRight + \value Key_Book + \value Key_CD + \value Key_Calculator + \value Key_ToDoList + \value Key_ClearGrab + \value Key_Close + \value Key_Copy + \value Key_Cut + \value Key_Display + \value Key_DOS + \value Key_Documents + \value Key_Excel + \value Key_Explorer + \value Key_Game + \value Key_Go + \value Key_iTouch + \value Key_LogOff + \value Key_Market + \value Key_Meeting + \value Key_MenuKB + \value Key_MenuPB + \value Key_MySites + \value Key_News + \value Key_OfficeHome + \value Key_Option + \value Key_Paste + \value Key_Phone + \value Key_Calendar + \value Key_Reply + \value Key_Reload + \value Key_RotateWindows + \value Key_RotationPB + \value Key_RotationKB + \value Key_Save + \value Key_Send + \value Key_Spell + \value Key_SplitScreen + \value Key_Support + \value Key_TaskPane + \value Key_Terminal + \value Key_Tools + \value Key_Travel + \value Key_Video + \value Key_Word + \value Key_Xfer + \value Key_ZoomIn + \value Key_ZoomOut + \value Key_Away + \value Key_Messenger + \value Key_WebCam + \value Key_MailForward + \value Key_Pictures + \value Key_Music + \value Key_Battery + \value Key_Bluetooth + \value Key_WLAN + \value Key_UWB + \value Key_AudioForward + \value Key_AudioRepeat + \value Key_AudioRandomPlay + \value Key_Subtitle + \value Key_AudioCycleTrack + \value Key_Time + \value Key_Hibernate + \value Key_View + \value Key_TopMenu + \value Key_PowerDown + \value Key_Suspend + \value Key_ContrastAdjust \value Key_MediaLast \value Key_unknown diff --git a/src/gui/kernel/qkeymapper_x11.cpp b/src/gui/kernel/qkeymapper_x11.cpp index 0ce77fe..8164589 100644 --- a/src/gui/kernel/qkeymapper_x11.cpp +++ b/src/gui/kernel/qkeymapper_x11.cpp @@ -714,47 +714,144 @@ extern bool qt_sm_blockUserInput; #define XK_KP_Delete 0xFF9F #endif -// the next lines are taken from XFree > 4.0 (X11/XF86keysyms.h), defining some special +// the next lines are taken on 10/2009 from X.org (X11/XF86keysym.h), defining some special // multimedia keys. They are included here as not every system has them. -#define XF86XK_Standby 0x1008FF10 -#define XF86XK_AudioLowerVolume 0x1008FF11 -#define XF86XK_AudioMute 0x1008FF12 -#define XF86XK_AudioRaiseVolume 0x1008FF13 -#define XF86XK_AudioPlay 0x1008FF14 -#define XF86XK_AudioStop 0x1008FF15 -#define XF86XK_AudioPrev 0x1008FF16 -#define XF86XK_AudioNext 0x1008FF17 -#define XF86XK_HomePage 0x1008FF18 -#define XF86XK_Calculator 0x1008FF1D -#define XF86XK_Mail 0x1008FF19 -#define XF86XK_Start 0x1008FF1A -#define XF86XK_Search 0x1008FF1B -#define XF86XK_AudioRecord 0x1008FF1C -#define XF86XK_Back 0x1008FF26 -#define XF86XK_Forward 0x1008FF27 -#define XF86XK_Stop 0x1008FF28 -#define XF86XK_Refresh 0x1008FF29 -#define XF86XK_Favorites 0x1008FF30 -#define XF86XK_AudioPause 0x1008FF31 -#define XF86XK_AudioMedia 0x1008FF32 -#define XF86XK_MyComputer 0x1008FF33 -#define XF86XK_OpenURL 0x1008FF38 -#define XF86XK_Launch0 0x1008FF40 -#define XF86XK_Launch1 0x1008FF41 -#define XF86XK_Launch2 0x1008FF42 -#define XF86XK_Launch3 0x1008FF43 -#define XF86XK_Launch4 0x1008FF44 -#define XF86XK_Launch5 0x1008FF45 -#define XF86XK_Launch6 0x1008FF46 -#define XF86XK_Launch7 0x1008FF47 -#define XF86XK_Launch8 0x1008FF48 -#define XF86XK_Launch9 0x1008FF49 -#define XF86XK_LaunchA 0x1008FF4A -#define XF86XK_LaunchB 0x1008FF4B -#define XF86XK_LaunchC 0x1008FF4C -#define XF86XK_LaunchD 0x1008FF4D -#define XF86XK_LaunchE 0x1008FF4E -#define XF86XK_LaunchF 0x1008FF4F +#define XF86XK_MonBrightnessUp 0x1008FF02 +#define XF86XK_MonBrightnessDown 0x1008FF03 +#define XF86XK_KbdLightOnOff 0x1008FF04 +#define XF86XK_KbdBrightnessUp 0x1008FF05 +#define XF86XK_KbdBrightnessDown 0x1008FF06 +#define XF86XK_Standby 0x1008FF10 +#define XF86XK_AudioLowerVolume 0x1008FF11 +#define XF86XK_AudioMute 0x1008FF12 +#define XF86XK_AudioRaiseVolume 0x1008FF13 +#define XF86XK_AudioPlay 0x1008FF14 +#define XF86XK_AudioStop 0x1008FF15 +#define XF86XK_AudioPrev 0x1008FF16 +#define XF86XK_AudioNext 0x1008FF17 +#define XF86XK_HomePage 0x1008FF18 +#define XF86XK_Mail 0x1008FF19 +#define XF86XK_Start 0x1008FF1A +#define XF86XK_Search 0x1008FF1B +#define XF86XK_AudioRecord 0x1008FF1C +#define XF86XK_Calculator 0x1008FF1D +#define XF86XK_Memo 0x1008FF1E +#define XF86XK_ToDoList 0x1008FF1F +#define XF86XK_Calendar 0x1008FF20 +#define XF86XK_PowerDown 0x1008FF21 +#define XF86XK_ContrastAdjust 0x1008FF22 +#define XF86XK_Back 0x1008FF26 +#define XF86XK_Forward 0x1008FF27 +#define XF86XK_Stop 0x1008FF28 +#define XF86XK_Refresh 0x1008FF29 +#define XF86XK_PowerOff 0x1008FF2A +#define XF86XK_WakeUp 0x1008FF2B +#define XF86XK_Eject 0x1008FF2C +#define XF86XK_ScreenSaver 0x1008FF2D +#define XF86XK_WWW 0x1008FF2E +#define XF86XK_Sleep 0x1008FF2F +#define XF86XK_Favorites 0x1008FF30 +#define XF86XK_AudioPause 0x1008FF31 +#define XF86XK_AudioMedia 0x1008FF32 +#define XF86XK_MyComputer 0x1008FF33 +#define XF86XK_LightBulb 0x1008FF35 +#define XF86XK_Shop 0x1008FF36 +#define XF86XK_History 0x1008FF37 +#define XF86XK_OpenURL 0x1008FF38 +#define XF86XK_AddFavorite 0x1008FF39 +#define XF86XK_HotLinks 0x1008FF3A +#define XF86XK_BrightnessAdjust 0x1008FF3B +#define XF86XK_Finance 0x1008FF3C +#define XF86XK_Community 0x1008FF3D +#define XF86XK_AudioRewind 0x1008FF3E +#define XF86XK_BackForward 0x1008FF3F +#define XF86XK_Launch0 0x1008FF40 +#define XF86XK_Launch1 0x1008FF41 +#define XF86XK_Launch2 0x1008FF42 +#define XF86XK_Launch3 0x1008FF43 +#define XF86XK_Launch4 0x1008FF44 +#define XF86XK_Launch5 0x1008FF45 +#define XF86XK_Launch6 0x1008FF46 +#define XF86XK_Launch7 0x1008FF47 +#define XF86XK_Launch8 0x1008FF48 +#define XF86XK_Launch9 0x1008FF49 +#define XF86XK_LaunchA 0x1008FF4A +#define XF86XK_LaunchB 0x1008FF4B +#define XF86XK_LaunchC 0x1008FF4C +#define XF86XK_LaunchD 0x1008FF4D +#define XF86XK_LaunchE 0x1008FF4E +#define XF86XK_LaunchF 0x1008FF4F +#define XF86XK_ApplicationLeft 0x1008FF50 +#define XF86XK_ApplicationRight 0x1008FF51 +#define XF86XK_Book 0x1008FF52 +#define XF86XK_CD 0x1008FF53 +#define XF86XK_Calculater 0x1008FF54 +#define XF86XK_Clear 0x1008FF55 +#define XF86XK_ClearGrab 0x1008FE21 +#define XF86XK_Close 0x1008FF56 +#define XF86XK_Copy 0x1008FF57 +#define XF86XK_Cut 0x1008FF58 +#define XF86XK_Display 0x1008FF59 +#define XF86XK_DOS 0x1008FF5A +#define XF86XK_Documents 0x1008FF5B +#define XF86XK_Excel 0x1008FF5C +#define XF86XK_Explorer 0x1008FF5D +#define XF86XK_Game 0x1008FF5E +#define XF86XK_Go 0x1008FF5F +#define XF86XK_iTouch 0x1008FF60 +#define XF86XK_LogOff 0x1008FF61 +#define XF86XK_Market 0x1008FF62 +#define XF86XK_Meeting 0x1008FF63 +#define XF86XK_MenuKB 0x1008FF65 +#define XF86XK_MenuPB 0x1008FF66 +#define XF86XK_MySites 0x1008FF67 +#define XF86XK_News 0x1008FF69 +#define XF86XK_OfficeHome 0x1008FF6A +#define XF86XK_Option 0x1008FF6C +#define XF86XK_Paste 0x1008FF6D +#define XF86XK_Phone 0x1008FF6E +#define XF86XK_Reply 0x1008FF72 +#define XF86XK_Reload 0x1008FF73 +#define XF86XK_RotateWindows 0x1008FF74 +#define XF86XK_RotationPB 0x1008FF75 +#define XF86XK_RotationKB 0x1008FF76 +#define XF86XK_Save 0x1008FF77 +#define XF86XK_Send 0x1008FF7B +#define XF86XK_Spell 0x1008FF7C +#define XF86XK_SplitScreen 0x1008FF7D +#define XF86XK_Support 0x1008FF7E +#define XF86XK_TaskPane 0x1008FF7F +#define XF86XK_Terminal 0x1008FF80 +#define XF86XK_Tools 0x1008FF81 +#define XF86XK_Travel 0x1008FF82 +#define XF86XK_Video 0x1008FF87 +#define XF86XK_Word 0x1008FF89 +#define XF86XK_Xfer 0x1008FF8A +#define XF86XK_ZoomIn 0x1008FF8B +#define XF86XK_ZoomOut 0x1008FF8C +#define XF86XK_Away 0x1008FF8D +#define XF86XK_Messenger 0x1008FF8E +#define XF86XK_WebCam 0x1008FF8F +#define XF86XK_MailForward 0x1008FF90 +#define XF86XK_Pictures 0x1008FF91 +#define XF86XK_Music 0x1008FF92 +#define XF86XK_Battery 0x1008FF93 +#define XF86XK_Bluetooth 0x1008FF94 +#define XF86XK_WLAN 0x1008FF95 +#define XF86XK_UWB 0x1008FF96 +#define XF86XK_AudioForward 0x1008FF97 +#define XF86XK_AudioRepeat 0x1008FF98 +#define XF86XK_AudioRandomPlay 0x1008FF99 +#define XF86XK_Subtitle 0x1008FF9A +#define XF86XK_AudioCycleTrack 0x1008FF9B +#define XF86XK_Time 0x1008FF9F +#define XF86XK_Select 0x1008FFA0 +#define XF86XK_View 0x1008FFA1 +#define XF86XK_TopMenu 0x1008FFA2 +#define XF86XK_Suspend 0x1008FFA7 +#define XF86XK_Hibernate 0x1008FFA8 + + // end of XF86keysyms.h // Special keys used by Qtopia, mapped into the X11 private keypad range. @@ -942,10 +1039,8 @@ static const unsigned int KeyTbl[] = { XK_dead_hook, Qt::Key_Dead_Hook, XK_dead_horn, Qt::Key_Dead_Horn, - // Special multimedia keys - // currently only tested with MS internet keyboard - - // browsing keys + // Special keys from X.org - This include multimedia keys, + // wireless/bluetooth/uwb keys, special launcher keys, etc. XF86XK_Back, Qt::Key_Back, XF86XK_Forward, Qt::Key_Forward, XF86XK_Stop, Qt::Key_Stop, @@ -955,8 +1050,6 @@ static const unsigned int KeyTbl[] = { XF86XK_OpenURL, Qt::Key_OpenUrl, XF86XK_HomePage, Qt::Key_HomePage, XF86XK_Search, Qt::Key_Search, - - // media keys XF86XK_AudioLowerVolume, Qt::Key_VolumeDown, XF86XK_AudioMute, Qt::Key_VolumeMute, XF86XK_AudioRaiseVolume, Qt::Key_VolumeUp, @@ -965,13 +1058,106 @@ static const unsigned int KeyTbl[] = { XF86XK_AudioPrev, Qt::Key_MediaPrevious, XF86XK_AudioNext, Qt::Key_MediaNext, XF86XK_AudioRecord, Qt::Key_MediaRecord, - - // launch keys XF86XK_Mail, Qt::Key_LaunchMail, XF86XK_MyComputer, Qt::Key_Launch0, - XF86XK_Calculator, Qt::Key_Launch1, + XF86XK_Calculator, Qt::Key_Calculator, + XF86XK_Memo, Qt::Key_Memo, + XF86XK_ToDoList, Qt::Key_ToDoList, + XF86XK_Calendar, Qt::Key_Calendar, + XF86XK_PowerDown, Qt::Key_PowerDown, + XF86XK_ContrastAdjust, Qt::Key_ContrastAdjust, XF86XK_Standby, Qt::Key_Standby, - + XF86XK_MonBrightnessUp, Qt::Key_MonBrightnessUp, + XF86XK_MonBrightnessDown, Qt::Key_MonBrightnessDown, + XF86XK_KbdLightOnOff, Qt::Key_KeyboardLightOnOff, + XF86XK_KbdBrightnessUp, Qt::Key_KeyboardBrightnessUp, + XF86XK_KbdBrightnessDown, Qt::Key_KeyboardBrightnessDown, + XF86XK_PowerOff, Qt::Key_PowerOff, + XF86XK_WakeUp, Qt::Key_WakeUp, + XF86XK_Eject, Qt::Key_Eject, + XF86XK_ScreenSaver, Qt::Key_ScreenSaver, + XF86XK_WWW, Qt::Key_WWW, + XF86XK_Sleep, Qt::Key_Sleep, + XF86XK_LightBulb, Qt::Key_LightBulb, + XF86XK_Shop, Qt::Key_Shop, + XF86XK_History, Qt::Key_History, + XF86XK_AddFavorite, Qt::Key_AddFavorite, + XF86XK_HotLinks, Qt::Key_HotLinks, + XF86XK_BrightnessAdjust, Qt::Key_BrightnessAdjust, + XF86XK_Finance, Qt::Key_Finance, + XF86XK_Community, Qt::Key_Community, + XF86XK_AudioRewind, Qt::Key_AudioRewind, + XF86XK_BackForward, Qt::Key_BackForward, + XF86XK_ApplicationLeft, Qt::Key_ApplicationLeft, + XF86XK_ApplicationRight, Qt::Key_ApplicationRight, + XF86XK_Book, Qt::Key_Book, + XF86XK_CD, Qt::Key_CD, + XF86XK_Calculater, Qt::Key_Calculator, + XF86XK_Clear, Qt::Key_Clear, + XF86XK_ClearGrab, Qt::Key_ClearGrab, + XF86XK_Close, Qt::Key_Close, + XF86XK_Copy, Qt::Key_Copy, + XF86XK_Cut, Qt::Key_Cut, + XF86XK_Display, Qt::Key_Display, + XF86XK_DOS, Qt::Key_DOS, + XF86XK_Documents, Qt::Key_Documents, + XF86XK_Excel, Qt::Key_Excel, + XF86XK_Explorer, Qt::Key_Explorer, + XF86XK_Game, Qt::Key_Game, + XF86XK_Go, Qt::Key_Go, + XF86XK_iTouch, Qt::Key_iTouch, + XF86XK_LogOff, Qt::Key_LogOff, + XF86XK_Market, Qt::Key_Market, + XF86XK_Meeting, Qt::Key_Meeting, + XF86XK_MenuKB, Qt::Key_MenuKB, + XF86XK_MenuPB, Qt::Key_MenuPB, + XF86XK_MySites, Qt::Key_MySites, + XF86XK_News, Qt::Key_News, + XF86XK_OfficeHome, Qt::Key_OfficeHome, + XF86XK_Option, Qt::Key_Option, + XF86XK_Paste, Qt::Key_Paste, + XF86XK_Phone, Qt::Key_Phone, + XF86XK_Reply, Qt::Key_Reply, + XF86XK_Reload, Qt::Key_Reload, + XF86XK_RotateWindows, Qt::Key_RotateWindows, + XF86XK_RotationPB, Qt::Key_RotationPB, + XF86XK_RotationKB, Qt::Key_RotationKB, + XF86XK_Save, Qt::Key_Save, + XF86XK_Send, Qt::Key_Send, + XF86XK_Spell, Qt::Key_Spell, + XF86XK_SplitScreen, Qt::Key_SplitScreen, + XF86XK_Support, Qt::Key_Support, + XF86XK_TaskPane, Qt::Key_TaskPane, + XF86XK_Terminal, Qt::Key_Terminal, + XF86XK_Tools, Qt::Key_Tools, + XF86XK_Travel, Qt::Key_Travel, + XF86XK_Video, Qt::Key_Video, + XF86XK_Word, Qt::Key_Word, + XF86XK_Xfer, Qt::Key_Xfer, + XF86XK_ZoomIn, Qt::Key_ZoomIn, + XF86XK_ZoomOut, Qt::Key_ZoomOut, + XF86XK_Away, Qt::Key_Away, + XF86XK_Messenger, Qt::Key_Messenger, + XF86XK_WebCam, Qt::Key_WebCam, + XF86XK_MailForward, Qt::Key_MailForward, + XF86XK_Pictures, Qt::Key_Pictures, + XF86XK_Music, Qt::Key_Music, + XF86XK_Battery, Qt::Key_Battery, + XF86XK_Bluetooth, Qt::Key_Bluetooth, + XF86XK_WLAN, Qt::Key_WLAN, + XF86XK_UWB, Qt::Key_UWB, + XF86XK_AudioForward, Qt::Key_AudioForward, + XF86XK_AudioRepeat, Qt::Key_AudioRepeat, + XF86XK_AudioRandomPlay, Qt::Key_AudioRandomPlay, + XF86XK_Subtitle, Qt::Key_Subtitle, + XF86XK_AudioCycleTrack, Qt::Key_AudioCycleTrack, + XF86XK_Time, Qt::Key_Time, + XF86XK_Select, Qt::Key_Select, + XF86XK_View, Qt::Key_View, + XF86XK_TopMenu, Qt::Key_TopMenu, + XF86XK_Bluetooth, Qt::Key_Bluetooth, + XF86XK_Suspend, Qt::Key_Suspend, + XF86XK_Hibernate, Qt::Key_Hibernate, XF86XK_Launch0, Qt::Key_Launch2, XF86XK_Launch1, Qt::Key_Launch3, XF86XK_Launch2, Qt::Key_Launch4, diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index b44ef7f..1a76083 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -416,47 +416,139 @@ static const struct { { Qt::Key_Menu, QT_TRANSLATE_NOOP("QShortcut", "Menu") }, { Qt::Key_Help, QT_TRANSLATE_NOOP("QShortcut", "Help") }, - // Multimedia keys - { Qt::Key_Back, QT_TRANSLATE_NOOP("QShortcut", "Back") }, - { Qt::Key_Forward, QT_TRANSLATE_NOOP("QShortcut", "Forward") }, - { Qt::Key_Stop, QT_TRANSLATE_NOOP("QShortcut", "Stop") }, - { Qt::Key_Refresh, QT_TRANSLATE_NOOP("QShortcut", "Refresh") }, - { Qt::Key_VolumeDown, QT_TRANSLATE_NOOP("QShortcut", "Volume Down") }, - { Qt::Key_VolumeMute, QT_TRANSLATE_NOOP("QShortcut", "Volume Mute") }, - { Qt::Key_VolumeUp, QT_TRANSLATE_NOOP("QShortcut", "Volume Up") }, - { Qt::Key_BassBoost, QT_TRANSLATE_NOOP("QShortcut", "Bass Boost") }, - { Qt::Key_BassUp, QT_TRANSLATE_NOOP("QShortcut", "Bass Up") }, - { Qt::Key_BassDown, QT_TRANSLATE_NOOP("QShortcut", "Bass Down") }, - { Qt::Key_TrebleUp, QT_TRANSLATE_NOOP("QShortcut", "Treble Up") }, - { Qt::Key_TrebleDown, QT_TRANSLATE_NOOP("QShortcut", "Treble Down") }, - { Qt::Key_MediaPlay, QT_TRANSLATE_NOOP("QShortcut", "Media Play") }, - { Qt::Key_MediaStop, QT_TRANSLATE_NOOP("QShortcut", "Media Stop") }, - { Qt::Key_MediaPrevious,QT_TRANSLATE_NOOP("QShortcut", "Media Previous") }, - { Qt::Key_MediaNext, QT_TRANSLATE_NOOP("QShortcut", "Media Next") }, - { Qt::Key_MediaRecord, QT_TRANSLATE_NOOP("QShortcut", "Media Record") }, - { Qt::Key_HomePage, QT_TRANSLATE_NOOP("QShortcut", "Home Page") }, - { Qt::Key_Favorites, QT_TRANSLATE_NOOP("QShortcut", "Favorites") }, - { Qt::Key_Search, QT_TRANSLATE_NOOP("QShortcut", "Search") }, - { Qt::Key_Standby, QT_TRANSLATE_NOOP("QShortcut", "Standby") }, - { Qt::Key_OpenUrl, QT_TRANSLATE_NOOP("QShortcut", "Open URL") }, - { Qt::Key_LaunchMail, QT_TRANSLATE_NOOP("QShortcut", "Launch Mail") }, - { Qt::Key_LaunchMedia, QT_TRANSLATE_NOOP("QShortcut", "Launch Media") }, - { Qt::Key_Launch0, QT_TRANSLATE_NOOP("QShortcut", "Launch (0)") }, - { Qt::Key_Launch1, QT_TRANSLATE_NOOP("QShortcut", "Launch (1)") }, - { Qt::Key_Launch2, QT_TRANSLATE_NOOP("QShortcut", "Launch (2)") }, - { Qt::Key_Launch3, QT_TRANSLATE_NOOP("QShortcut", "Launch (3)") }, - { Qt::Key_Launch4, QT_TRANSLATE_NOOP("QShortcut", "Launch (4)") }, - { Qt::Key_Launch5, QT_TRANSLATE_NOOP("QShortcut", "Launch (5)") }, - { Qt::Key_Launch6, QT_TRANSLATE_NOOP("QShortcut", "Launch (6)") }, - { Qt::Key_Launch7, QT_TRANSLATE_NOOP("QShortcut", "Launch (7)") }, - { Qt::Key_Launch8, QT_TRANSLATE_NOOP("QShortcut", "Launch (8)") }, - { Qt::Key_Launch9, QT_TRANSLATE_NOOP("QShortcut", "Launch (9)") }, - { Qt::Key_LaunchA, QT_TRANSLATE_NOOP("QShortcut", "Launch (A)") }, - { Qt::Key_LaunchB, QT_TRANSLATE_NOOP("QShortcut", "Launch (B)") }, - { Qt::Key_LaunchC, QT_TRANSLATE_NOOP("QShortcut", "Launch (C)") }, - { Qt::Key_LaunchD, QT_TRANSLATE_NOOP("QShortcut", "Launch (D)") }, - { Qt::Key_LaunchE, QT_TRANSLATE_NOOP("QShortcut", "Launch (E)") }, - { Qt::Key_LaunchF, QT_TRANSLATE_NOOP("QShortcut", "Launch (F)") }, + // Special keys + // Includes multimedia, launcher, lan keys ( bluetooth, wireless ) + // window navigation + { Qt::Key_Back, QT_TRANSLATE_NOOP("QShortcut", "Back") }, + { Qt::Key_Forward, QT_TRANSLATE_NOOP("QShortcut", "Forward") }, + { Qt::Key_Stop, QT_TRANSLATE_NOOP("QShortcut", "Stop") }, + { Qt::Key_Refresh, QT_TRANSLATE_NOOP("QShortcut", "Refresh") }, + { Qt::Key_VolumeDown, QT_TRANSLATE_NOOP("QShortcut", "Volume Down") }, + { Qt::Key_VolumeMute, QT_TRANSLATE_NOOP("QShortcut", "Volume Mute") }, + { Qt::Key_VolumeUp, QT_TRANSLATE_NOOP("QShortcut", "Volume Up") }, + { Qt::Key_BassBoost, QT_TRANSLATE_NOOP("QShortcut", "Bass Boost") }, + { Qt::Key_BassUp, QT_TRANSLATE_NOOP("QShortcut", "Bass Up") }, + { Qt::Key_BassDown, QT_TRANSLATE_NOOP("QShortcut", "Bass Down") }, + { Qt::Key_TrebleUp, QT_TRANSLATE_NOOP("QShortcut", "Treble Up") }, + { Qt::Key_TrebleDown, QT_TRANSLATE_NOOP("QShortcut", "Treble Down") }, + { Qt::Key_MediaPlay, QT_TRANSLATE_NOOP("QShortcut", "Media Play") }, + { Qt::Key_MediaStop, QT_TRANSLATE_NOOP("QShortcut", "Media Stop") }, + { Qt::Key_MediaPrevious, QT_TRANSLATE_NOOP("QShortcut", "Media Previous") }, + { Qt::Key_MediaNext, QT_TRANSLATE_NOOP("QShortcut", "Media Next") }, + { Qt::Key_MediaRecord, QT_TRANSLATE_NOOP("QShortcut", "Media Record") }, + { Qt::Key_HomePage, QT_TRANSLATE_NOOP("QShortcut", "Home Page") }, + { Qt::Key_Favorites, QT_TRANSLATE_NOOP("QShortcut", "Favorites") }, + { Qt::Key_Search, QT_TRANSLATE_NOOP("QShortcut", "Search") }, + { Qt::Key_Standby, QT_TRANSLATE_NOOP("QShortcut", "Standby") }, + { Qt::Key_OpenUrl, QT_TRANSLATE_NOOP("QShortcut", "Open URL") }, + { Qt::Key_LaunchMail, QT_TRANSLATE_NOOP("QShortcut", "Launch Mail") }, + { Qt::Key_LaunchMedia, QT_TRANSLATE_NOOP("QShortcut", "Launch Media") }, + { Qt::Key_Launch0, QT_TRANSLATE_NOOP("QShortcut", "Launch (0)") }, + { Qt::Key_Launch1, QT_TRANSLATE_NOOP("QShortcut", "Launch (1)") }, + { Qt::Key_Launch2, QT_TRANSLATE_NOOP("QShortcut", "Launch (2)") }, + { Qt::Key_Launch3, QT_TRANSLATE_NOOP("QShortcut", "Launch (3)") }, + { Qt::Key_Launch4, QT_TRANSLATE_NOOP("QShortcut", "Launch (4)") }, + { Qt::Key_Launch5, QT_TRANSLATE_NOOP("QShortcut", "Launch (5)") }, + { Qt::Key_Launch6, QT_TRANSLATE_NOOP("QShortcut", "Launch (6)") }, + { Qt::Key_Launch7, QT_TRANSLATE_NOOP("QShortcut", "Launch (7)") }, + { Qt::Key_Launch8, QT_TRANSLATE_NOOP("QShortcut", "Launch (8)") }, + { Qt::Key_Launch9, QT_TRANSLATE_NOOP("QShortcut", "Launch (9)") }, + { Qt::Key_LaunchA, QT_TRANSLATE_NOOP("QShortcut", "Launch (A)") }, + { Qt::Key_LaunchB, QT_TRANSLATE_NOOP("QShortcut", "Launch (B)") }, + { Qt::Key_LaunchC, QT_TRANSLATE_NOOP("QShortcut", "Launch (C)") }, + { Qt::Key_LaunchD, QT_TRANSLATE_NOOP("QShortcut", "Launch (D)") }, + { Qt::Key_LaunchE, QT_TRANSLATE_NOOP("QShortcut", "Launch (E)") }, + { Qt::Key_LaunchF, QT_TRANSLATE_NOOP("QShortcut", "Launch (F)") }, + { Qt::Key_MonBrightnessUp, QT_TRANSLATE_NOOP("QShortcut", "Monitor Brightness Up") }, + { Qt::Key_MonBrightnessDown, QT_TRANSLATE_NOOP("QShortcut", "Monitor Brightness Down") }, + { Qt::Key_KeyboardLightOnOff, QT_TRANSLATE_NOOP("QShortcut", "Keyboard Light On/Off") }, + { Qt::Key_KeyboardBrightnessUp, QT_TRANSLATE_NOOP("QShortcut", "Keyboard Brightness Up") }, + { Qt::Key_KeyboardBrightnessDown, QT_TRANSLATE_NOOP("QShortcut", "Keyboard Brightness Down") }, + { Qt::Key_PowerOff, QT_TRANSLATE_NOOP("QShortcut", "Power Off") }, + { Qt::Key_WakeUp, QT_TRANSLATE_NOOP("QShortcut", "Wake Up") }, + { Qt::Key_Eject, QT_TRANSLATE_NOOP("QShortcut", "Eject") }, + { Qt::Key_ScreenSaver, QT_TRANSLATE_NOOP("QShortcut", "Screensaver") }, + { Qt::Key_WWW, QT_TRANSLATE_NOOP("QShortcut", "WWW") }, + { Qt::Key_Sleep, QT_TRANSLATE_NOOP("QShortcut", "Sleep") }, + { Qt::Key_LightBulb, QT_TRANSLATE_NOOP("QShortcut", "LightBulb") }, + { Qt::Key_Shop, QT_TRANSLATE_NOOP("QShortcut", "Shop") }, + { Qt::Key_History, QT_TRANSLATE_NOOP("QShortcut", "History") }, + { Qt::Key_AddFavorite, QT_TRANSLATE_NOOP("QShortcut", "Add Favorite") }, + { Qt::Key_HotLinks, QT_TRANSLATE_NOOP("QShortcut", "Hot Links") }, + { Qt::Key_BrightnessAdjust, QT_TRANSLATE_NOOP("QShortcut", "Adjust Brightness") }, + { Qt::Key_Finance, QT_TRANSLATE_NOOP("QShortcut", "Finance") }, + { Qt::Key_Community, QT_TRANSLATE_NOOP("QShortcut", "Community") }, + { Qt::Key_AudioRewind, QT_TRANSLATE_NOOP("QShortcut", "Audio Rewind") }, + { Qt::Key_BackForward, QT_TRANSLATE_NOOP("QShortcut", "Back Forward") }, + { Qt::Key_ApplicationLeft, QT_TRANSLATE_NOOP("QShortcut", "Application Left") }, + { Qt::Key_ApplicationRight, QT_TRANSLATE_NOOP("QShortcut", "Application Right") }, + { Qt::Key_Book, QT_TRANSLATE_NOOP("QShortcut", "Book") }, + { Qt::Key_CD, QT_TRANSLATE_NOOP("QShortcut", "CD") }, + { Qt::Key_Calculator, QT_TRANSLATE_NOOP("QShortcut", "Calculator") }, + { Qt::Key_Clear, QT_TRANSLATE_NOOP("QShortcut", "Clear") }, + { Qt::Key_ClearGrab, QT_TRANSLATE_NOOP("QShortcut", "Clear Grab") }, + { Qt::Key_Close, QT_TRANSLATE_NOOP("QShortcut", "Close") }, + { Qt::Key_Copy, QT_TRANSLATE_NOOP("QShortcut", "Copy") }, + { Qt::Key_Cut, QT_TRANSLATE_NOOP("QShortcut", "Cut") }, + { Qt::Key_Display, QT_TRANSLATE_NOOP("QShortcut", "Display") }, + { Qt::Key_DOS, QT_TRANSLATE_NOOP("QShortcut", "DOS") }, + { Qt::Key_Documents, QT_TRANSLATE_NOOP("QShortcut", "Documents") }, + { Qt::Key_Excel, QT_TRANSLATE_NOOP("QShortcut", "Spreadsheet") }, + { Qt::Key_Explorer, QT_TRANSLATE_NOOP("QShortcut", "Browser") }, + { Qt::Key_Game, QT_TRANSLATE_NOOP("QShortcut", "Game") }, + { Qt::Key_Go, QT_TRANSLATE_NOOP("QShortcut", "Go") }, + { Qt::Key_iTouch, QT_TRANSLATE_NOOP("QShortcut", "iTouch") }, + { Qt::Key_LogOff, QT_TRANSLATE_NOOP("QShortcut", "Logoff") }, + { Qt::Key_Market, QT_TRANSLATE_NOOP("QShortcut", "Market") }, + { Qt::Key_Meeting, QT_TRANSLATE_NOOP("QShortcut", "Meeting") }, + { Qt::Key_MenuKB, QT_TRANSLATE_NOOP("QShortcut", "Keyboard Menu") }, + { Qt::Key_MenuPB, QT_TRANSLATE_NOOP("QShortcut", "Menu PB") }, + { Qt::Key_MySites, QT_TRANSLATE_NOOP("QShortcut", "My Sites") }, + { Qt::Key_News, QT_TRANSLATE_NOOP("QShortcut", "News") }, + { Qt::Key_OfficeHome, QT_TRANSLATE_NOOP("QShortcut", "Home Office") }, + { Qt::Key_Option, QT_TRANSLATE_NOOP("QShortcut", "Option") }, + { Qt::Key_Paste, QT_TRANSLATE_NOOP("QShortcut", "Paste") }, + { Qt::Key_Phone, QT_TRANSLATE_NOOP("QShortcut", "Phone") }, + { Qt::Key_Reply, QT_TRANSLATE_NOOP("QShortcut", "Reply") }, + { Qt::Key_Reload, QT_TRANSLATE_NOOP("QShortcut", "Reload") }, + { Qt::Key_RotateWindows, QT_TRANSLATE_NOOP("QShortcut", "Rotate Windows") }, + { Qt::Key_RotationPB, QT_TRANSLATE_NOOP("QShortcut", "Rotation PB") }, + { Qt::Key_RotationKB, QT_TRANSLATE_NOOP("QShortcut", "Rotation KB") }, + { Qt::Key_Save, QT_TRANSLATE_NOOP("QShortcut", "Save") }, + { Qt::Key_Send, QT_TRANSLATE_NOOP("QShortcut", "Send") }, + { Qt::Key_Spell, QT_TRANSLATE_NOOP("QShortcut", "Spellchecker") }, + { Qt::Key_SplitScreen, QT_TRANSLATE_NOOP("QShortcut", "Split Screen") }, + { Qt::Key_Support, QT_TRANSLATE_NOOP("QShortcut", "Support") }, + { Qt::Key_TaskPane, QT_TRANSLATE_NOOP("QShortcut", "Task Panel") }, + { Qt::Key_Terminal, QT_TRANSLATE_NOOP("QShortcut", "Terminal") }, + { Qt::Key_Tools, QT_TRANSLATE_NOOP("QShortcut", "Tools") }, + { Qt::Key_Travel, QT_TRANSLATE_NOOP("QShortcut", "Travel") }, + { Qt::Key_Video, QT_TRANSLATE_NOOP("QShortcut", "Video") }, + { Qt::Key_Word, QT_TRANSLATE_NOOP("QShortcut", "Word Processor") }, + { Qt::Key_Xfer, QT_TRANSLATE_NOOP("QShortcut", "XFer") }, + { Qt::Key_ZoomIn, QT_TRANSLATE_NOOP("QShortcut", "Zoom In") }, + { Qt::Key_ZoomOut, QT_TRANSLATE_NOOP("QShortcut", "Zoom Out") }, + { Qt::Key_Away, QT_TRANSLATE_NOOP("QShortcut", "Away") }, + { Qt::Key_Messenger, QT_TRANSLATE_NOOP("QShortcut", "Messenger") }, + { Qt::Key_WebCam, QT_TRANSLATE_NOOP("QShortcut", "WebCam") }, + { Qt::Key_MailForward, QT_TRANSLATE_NOOP("QShortcut", "Mail Forward") }, + { Qt::Key_Pictures, QT_TRANSLATE_NOOP("QShortcut", "Pictures") }, + { Qt::Key_Music, QT_TRANSLATE_NOOP("QShortcut", "Music") }, + { Qt::Key_Battery, QT_TRANSLATE_NOOP("QShortcut", "Battery") }, + { Qt::Key_Bluetooth, QT_TRANSLATE_NOOP("QShortcut", "Bluetooth") }, + { Qt::Key_WLAN, QT_TRANSLATE_NOOP("QShortcut", "Wireless") }, + { Qt::Key_UWB, QT_TRANSLATE_NOOP("QShortcut", "Ultra Wide Band") }, + { Qt::Key_AudioForward, QT_TRANSLATE_NOOP("QShortcut", "Audio Forward") }, + { Qt::Key_AudioRepeat, QT_TRANSLATE_NOOP("QShortcut", "Audio Repeat") }, + { Qt::Key_AudioRandomPlay, QT_TRANSLATE_NOOP("QShortcut", "Audio Random Play") }, + { Qt::Key_Subtitle, QT_TRANSLATE_NOOP("QShortcut", "Subtitle") }, + { Qt::Key_AudioCycleTrack, QT_TRANSLATE_NOOP("QShortcut", "Audio Cycle Track") }, + { Qt::Key_Time, QT_TRANSLATE_NOOP("QShortcut", "Time") }, + { Qt::Key_Select, QT_TRANSLATE_NOOP("QShortcut", "Select") }, + { Qt::Key_View, QT_TRANSLATE_NOOP("QShortcut", "View") }, + { Qt::Key_TopMenu, QT_TRANSLATE_NOOP("QShortcut", "Top Menu") }, + { Qt::Key_Suspend, QT_TRANSLATE_NOOP("QShortcut", "Suspend") }, + { Qt::Key_Hibernate, QT_TRANSLATE_NOOP("QShortcut", "Hibernate") }, // -------------------------------------------------------------- // More consistent namings -- cgit v0.12 From 0313ccbfaff690c5a8fc18a3a2c7d976a4a55aaf Mon Sep 17 00:00:00 2001 From: Gustavo Pichorim Boiko Date: Tue, 27 Oct 2009 18:16:11 +0100 Subject: Emit workAreaResized() in X11 when it changes Emit the QDesktopWidget::workAreaResized() signal when the _NET_WORKAREA property of the root window changes. Merge-request: 1111 Reviewed-by: Denis Dzyubenko --- src/gui/kernel/qapplication_x11.cpp | 6 ++++++ src/gui/kernel/qdesktopwidget_x11.cpp | 9 --------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index bf95684..c6d188b 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -3750,6 +3750,12 @@ int QApplication::x11ProcessEvent(XEvent* event) qt_get_net_virtual_roots(); } else if (event->xproperty.atom == ATOM(_NET_WORKAREA)) { qt_desktopwidget_update_workarea(); + + // emit the workAreaResized() signal + QDesktopWidget *desktop = QApplication::desktop(); + int numScreens = desktop->numScreens(); + for (int i = 0; i < numScreens; ++i) + emit desktop->workAreaResized(i); } } else if (widget) { widget->translatePropertyEvent(event); diff --git a/src/gui/kernel/qdesktopwidget_x11.cpp b/src/gui/kernel/qdesktopwidget_x11.cpp index 02a2c82..14eb976 100644 --- a/src/gui/kernel/qdesktopwidget_x11.cpp +++ b/src/gui/kernel/qdesktopwidget_x11.cpp @@ -384,10 +384,8 @@ void QDesktopWidget::resizeEvent(QResizeEvent *event) Q_D(QDesktopWidget); int oldScreenCount = d->screenCount; QVector oldRects(oldScreenCount); - QVector oldWorks(oldScreenCount); for (int i = 0; i < oldScreenCount; ++i) { oldRects[i] = d->rects[i]; - oldWorks[i] = d->workareas[i]; } d->init(); @@ -397,13 +395,6 @@ void QDesktopWidget::resizeEvent(QResizeEvent *event) emit resized(i); } - // ### workareas are just reset by init, not filled with new values - // ### so this will not work correctly - for (int j = 0; j < qMin(oldScreenCount, d->screenCount); ++j) { - if (oldWorks.at(j) != d->workareas[j]) - emit workAreaResized(j); - } - if (oldScreenCount != d->screenCount) { emit screenCountChanged(d->screenCount); } -- cgit v0.12 From 0444453661df0f56fd034778028c7abdc0b621cc Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 28 Oct 2009 09:42:09 +0100 Subject: Don't stop event processing at the second WM_QT_SENDPOSTEDEVENTS We should continue processing as much as we can, and report the WM_QT_SENDPOSTEDEVENTS at the end of processEvents(). --- src/corelib/kernel/qeventdispatcher_win.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index df4c02d..d13e1d1 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -663,11 +663,12 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) bool canWait; bool retVal = false; + bool seenWM_QT_SENDPOSTEDEVENTS = false; + bool needWM_QT_SENDPOSTEDEVENTS = false; do { DWORD waitRet = 0; HANDLE pHandles[MAXIMUM_WAIT_OBJECTS - 1]; QVarLengthArray processedTimers; - bool seenWM_QT_SENDPOSTEDEVENTS = false; while (!d->interrupt) { DWORD nCount = d->winEventNotifierList.count(); Q_ASSERT(nCount < MAXIMUM_WAIT_OBJECTS - 1); @@ -717,8 +718,8 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) if (haveMessage) { if (msg.message == WM_QT_SENDPOSTEDEVENTS && !(flags & QEventLoop::EventLoopExec)) { if (seenWM_QT_SENDPOSTEDEVENTS) { - PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0); - break; + needWM_QT_SENDPOSTEDEVENTS = true; + continue; } seenWM_QT_SENDPOSTEDEVENTS = true; } else if (msg.message == WM_TIMER) { @@ -770,6 +771,9 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) } } while (canWait); + if (needWM_QT_SENDPOSTEDEVENTS) + PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0); + return retVal; } -- cgit v0.12 From 9a9cd7765bfe879b53488fe18bba75425e4c5c61 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Mon, 26 Oct 2009 14:20:49 +0100 Subject: add empty test method, should implement it fully when more important things are done --- tests/auto/gestures/tst_gestures.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index eba2616..6acfe70 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -330,6 +330,7 @@ private slots: void testMapToScene(); void ungrabGesture(); void consumeEventHint(); + void unregisterRecognizer(); }; tst_Gestures::tst_Gestures() @@ -1276,5 +1277,20 @@ void tst_Gestures::ungrabGesture() // a method on QWidget QCOMPARE(a->gestureOverrideEventsReceived, 0); } +void tst_Gestures::unregisterRecognizer() // a method on QApplication +{ + /* + The hardest usecase to get right is when we remove a recognizer while several + of the gestures it created are in active state and we immediately add a new recognizer + for the same type (thus replacing the old one). + The expected result is that all old gestures continue till they are finished/cancelled + and the new recognizer starts creating gestures immediately at registration. + + This implies that deleting of the recognizer happens only when there are no more gestures + that it created. (since gestures might have a pointer to the recognizer) + */ + +} + QTEST_MAIN(tst_Gestures) #include "tst_gestures.moc" -- cgit v0.12 From 4470801f73b86d3ee06a866fbbdafcaeb9f294a6 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Tue, 27 Oct 2009 15:31:16 +0100 Subject: Introduce QGesture::GestureCancelPolicy, a way to auto-cancel gestures On accepting one gesture Qt can automatically cancel other gestures that belong to other targets. The policy is normally set to not cancel any other gestures and can be set to cancel all active gestures in the context. For example for all child widgets. Reviewed-By: Denis Dzyubenko --- src/gui/kernel/qgesture.cpp | 33 ++++++++++++++ src/gui/kernel/qgesture.h | 10 +++++ src/gui/kernel/qgesture_p.h | 10 +++-- src/gui/kernel/qgesturemanager.cpp | 85 ++++++++++++++++++++++++++++++++++-- src/gui/kernel/qgesturemanager_p.h | 2 + tests/auto/gestures/tst_gestures.cpp | 62 ++++++++++++++++++++++++++ 6 files changed, 195 insertions(+), 7 deletions(-) diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index a161876..c302c51 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -175,6 +175,29 @@ void QGesture::unsetHotSpot() } /*! + \enum QGesture::GestureCancelPolicy + + This enum describes how accepting a gesture can cancel other gestures + automatically. + + \value CancelNone On accepting this gesture no other gestures will be affected. + \value CancelAllInContext On accepting this gesture all gestures that are active + in the context (Qt::GestureContext) will be cancelled. +*/ + +void QGesture::setGestureCancelPolicy(GestureCancelPolicy policy) +{ + Q_D(QGesture); + d->gestureCancelPolicy = static_cast(policy); +} + +QGesture::GestureCancelPolicy QGesture::gestureCancelPolicy() const +{ + Q_D(const QGesture); + return static_cast(d->gestureCancelPolicy); +} + +/*! \class QPanGesture \since 4.6 \brief The QPanGesture class describes a panning gesture made by the user. @@ -195,6 +218,16 @@ void QGesture::unsetHotSpot() */ /*! + \property QGesture::GestureCancelPolicy + \brief the policy for deciding what happens on accepting a gesture + + On accepting one gesture Qt can automatically cancel other gestures + that belong to other targets. The policy is normally set to not cancel + any other gestures and can be set to cancel all active gestures in the + context. For example for all child widgets. +*/ + +/*! \property QPanGesture::lastOffset \brief the last offset recorded for this gesture diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h index 6469959..524d26e 100644 --- a/src/gui/kernel/qgesture.h +++ b/src/gui/kernel/qgesture.h @@ -65,6 +65,7 @@ class Q_GUI_EXPORT QGesture : public QObject Q_PROPERTY(Qt::GestureState state READ state) Q_PROPERTY(Qt::GestureType gestureType READ gestureType) + Q_PROPERTY(QGesture::GestureCancelPolicy gestureCancelPolicy READ gestureCancelPolicy WRITE setGestureCancelPolicy) Q_PROPERTY(QPointF hotSpot READ hotSpot WRITE setHotSpot RESET unsetHotSpot) Q_PROPERTY(bool hasHotSpot READ hasHotSpot) @@ -81,6 +82,14 @@ public: bool hasHotSpot() const; void unsetHotSpot(); + enum GestureCancelPolicy { + CancelNone = 0, + CancelAllInContext + }; + + void setGestureCancelPolicy(GestureCancelPolicy policy); + GestureCancelPolicy gestureCancelPolicy() const; + protected: QGesture(QGesturePrivate &dd, QObject *parent); @@ -208,6 +217,7 @@ public: QT_END_NAMESPACE +Q_DECLARE_METATYPE(QGesture::GestureCancelPolicy) QT_END_HEADER #endif // QGESTURE_H diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h index 975c0c9..d2ef8a7 100644 --- a/src/gui/kernel/qgesture_p.h +++ b/src/gui/kernel/qgesture_p.h @@ -67,16 +67,20 @@ class QGesturePrivate : public QObjectPrivate public: QGesturePrivate() - : gestureType(Qt::CustomGesture), state(Qt::NoGesture), isHotSpotSet(false), - targetObject(0) + : gestureType(Qt::CustomGesture), state(Qt::NoGesture), + targetObject(0), + isHotSpotSet(false), + gestureCancelPolicy(0) + { } Qt::GestureType gestureType; Qt::GestureState state; QPointF hotSpot; - bool isHotSpotSet; QObject *targetObject; + uint isHotSpotSet : 1; + uint gestureCancelPolicy : 2; }; class QPanGesturePrivate : public QGesturePrivate diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index 52f8eef..fc7c8b2 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -322,21 +322,96 @@ bool QGestureManager::filterEventThroughContexts(const QMapgestureCancelPolicy() == QGesture::CancelAllInContext) { + DEBUG() << "lets try to cancel some"; + // find gestures in context in Qt::GestureStarted or Qt::GestureUpdated state and cancel them + cancelGesturesForChildren(g); + } + } + activeGestures -= undeliveredGestures; // reset gestures that ended QSet endedGestures = finishedGestures + canceledGestures + undeliveredGestures; foreach (QGesture *gesture, endedGestures) { - if (QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0)) + if (QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0)) { + gesture->setGestureCancelPolicy(QGesture::CancelNone); recognizer->reset(gesture); - else + } else { cleanupGesturesForRemovedRecognizer(gesture); + } gestureTargets.remove(gesture); } return ret; } +// Cancel all gestures of children of the widget that original is associated with +void QGestureManager::cancelGesturesForChildren(QGesture *original) +{ + Q_ASSERT(original); + QWidget *originatingWidget = gestureTargets.value(original); + Q_ASSERT(originatingWidget); + + // iterate over all active gestures and all maybe gestures + // for each find the owner + // if the owner is part of our sub-hierarchy, cancel it. + + QSet cancelledGestures; + QSet::Iterator iter = activeGestures.begin(); + while (iter != activeGestures.end()) { + QWidget *widget = gestureTargets.value(*iter); + // note that we don't touch the gestures for our originatingWidget + if (widget != originatingWidget && originatingWidget->isAncestorOf(widget)) { + DEBUG() << " found a gesture to cancel" << (*iter); + (*iter)->d_func()->state = Qt::GestureCanceled; + cancelledGestures << *iter; + iter = activeGestures.erase(iter); + } else { + ++iter; + } + } + + // TODO handle 'maybe' gestures too + + // sort them per target widget by cherry picking from almostCanceledGestures and delivering + QSet almostCanceledGestures = cancelledGestures; + while (!almostCanceledGestures.isEmpty()) { + QWidget *target = 0; + QSet gestures; + iter = almostCanceledGestures.begin(); + // sort per target widget + while (iter != almostCanceledGestures.end()) { + QWidget *widget = gestureTargets.value(*iter); + if (target == 0) + target = widget; + if (target == widget) { + gestures << *iter; + iter = almostCanceledGestures.erase(iter); + } else { + ++iter; + } + } + Q_ASSERT(target); + + QSet undeliveredGestures; + deliverEvents(gestures, &undeliveredGestures); + } + + for (iter = cancelledGestures.begin(); iter != cancelledGestures.end(); ++iter) { + QGestureRecognizer *recognizer = gestureToRecognizer.value(*iter, 0); + if (recognizer) { + (*iter)->setGestureCancelPolicy(QGesture::CancelNone); + recognizer->reset(*iter); + } else { + cleanupGesturesForRemovedRecognizer(*iter); + } + } +} + void QGestureManager::cleanupGesturesForRemovedRecognizer(QGesture *gesture) { QGestureRecognizer *recognizer = m_deletedRecognizers.value(gesture); @@ -585,10 +660,12 @@ void QGestureManager::timerEvent(QTimerEvent *event) DEBUG() << "QGestureManager::timerEvent: gesture stopped due to timeout:" << gesture; QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0); - if (recognizer) + if (recognizer) { + gesture->setGestureCancelPolicy(QGesture::CancelNone); recognizer->reset(gesture); - else + } else { cleanupGesturesForRemovedRecognizer(gesture); + } } else { ++it; } diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h index 96c2fb7..e6a1d50 100644 --- a/src/gui/kernel/qgesturemanager_p.h +++ b/src/gui/kernel/qgesturemanager_p.h @@ -135,6 +135,8 @@ private: void getGestureTargets(const QSet &gestures, QMap > *conflicts, QMap > *normal); + + void cancelGesturesForChildren(QGesture *originatingGesture); }; QT_END_NAMESPACE diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index 6acfe70..39cdf63 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -331,6 +331,7 @@ private slots: void ungrabGesture(); void consumeEventHint(); void unregisterRecognizer(); + void autoCancelGestures(); }; tst_Gestures::tst_Gestures() @@ -1292,5 +1293,66 @@ void tst_Gestures::unregisterRecognizer() // a method on QApplication } +void tst_Gestures::autoCancelGestures() +{ + class MockRecognizer : public QGestureRecognizer { + public: + QGestureRecognizer::Result filterEvent(QGesture *gesture, QObject *watched, QEvent *event) + { + Q_UNUSED(gesture); + Q_UNUSED(watched); + if (event->type() == QEvent::MouseButtonPress) + return QGestureRecognizer::GestureTriggered; + if (event->type() == QEvent::MouseButtonRelease) + return QGestureRecognizer::GestureFinished; + return QGestureRecognizer::Ignore; + } + }; + + class MockWidget : public GestureWidget { + public: + MockWidget(const char *name) : GestureWidget(name) { } + + bool event(QEvent *event) + { + if (event->type() == QEvent::Gesture) { + QGestureEvent *ge = static_cast(event); + Q_ASSERT(ge->allGestures().count() == 1); // can't use QCOMPARE here... + ge->allGestures().first()->setGestureCancelPolicy(QGesture::CancelAllInContext); + } + return GestureWidget::event(event); + } + }; + + MockWidget parent("parent"); // this one sets the cancel policy to CancelAllInContext + parent.resize(300, 100); + GestureWidget *child = new GestureWidget("child", &parent); + child->setGeometry(10, 10, 100, 80); + + Qt::GestureType type = qApp->registerGestureRecognizer(new MockRecognizer()); + parent.grabGesture(type, Qt::WidgetWithChildrenGesture); + child->grabGesture(type, Qt::WidgetWithChildrenGesture); + + /* + An event is send to both the child and the parent, when the child gets it a gesture is triggered + and send to the child. + When the parent gets the event a new gesture is triggered and delivered to the parent. When the + parent gets it he accepts it and that causes the cancel policy to activate. + The cause of that is the gesture for the child is cancelled and send to the child as such. + */ + QMouseEvent event(QEvent::MouseButtonPress, QPoint(20,20), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + QApplication::sendEvent(child, &event); + QCOMPARE(child->events.started.count(), 1); + QCOMPARE(child->events.all.count(), 1); + QCOMPARE(parent.events.all.count(), 0); + child->reset(); + QApplication::sendEvent(&parent, &event); + QCOMPARE(parent.events.all.count(), 1); + QCOMPARE(parent.events.started.count(), 1); + QCOMPARE(child->events.started.count(), 0); + QCOMPARE(child->events.all.count(), 1); + QCOMPARE(child->events.canceled.count(), 1); +} + QTEST_MAIN(tst_Gestures) #include "tst_gestures.moc" -- cgit v0.12 From 3c2c1c21b41f600eeaa056b66fe44d5017f9b500 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 28 Oct 2009 10:55:19 +0100 Subject: Drag and drop of plain text doesnot work on Mac. While querying for the text in the pasteboard, it was looking in the wrong place. The helper function qt_mac_get_pasteboardString() always searched in generalPasteboard instead of the pasteboard referred by the QMacPasteboard. Reviewed-by: MortenS --- src/gui/kernel/qclipboard_mac.cpp | 2 +- src/gui/kernel/qt_cocoa_helpers_mac.mm | 19 +++++++++++++------ src/gui/kernel/qt_cocoa_helpers_mac_p.h | 2 +- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/gui/kernel/qclipboard_mac.cpp b/src/gui/kernel/qclipboard_mac.cpp index 3db647b..8892269 100644 --- a/src/gui/kernel/qclipboard_mac.cpp +++ b/src/gui/kernel/qclipboard_mac.cpp @@ -532,7 +532,7 @@ QMacPasteboard::retrieveData(const QString &format, QVariant::Type) const // Try to get the NSStringPboardType from NSPasteboard, newlines are mapped // correctly (as '\n') in this data. The 'public.utf16-plain-text' type // usually maps newlines to '\r' instead. - QString str = qt_mac_get_pasteboardString(); + QString str = qt_mac_get_pasteboardString(paste); if (!str.isEmpty()) return str; } diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index 2b2259c..c0fb8aa 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -1152,16 +1152,23 @@ CGFloat qt_mac_get_scalefactor() #endif } -QString qt_mac_get_pasteboardString() +QString qt_mac_get_pasteboardString(OSPasteboardRef paste) { QMacCocoaAutoReleasePool pool; - NSPasteboard *pb = [NSPasteboard generalPasteboard]; - NSString *text = [pb stringForType:NSStringPboardType]; - if (text) { - return qt_mac_NSStringToQString(text); + NSPasteboard *pb = nil; + CFStringRef pbname; + if (PasteboardCopyName (paste, &pbname)) { + pb = [NSPasteboard generalPasteboard]; } else { - return QString(); + pb = [NSPasteboard pasteboardWithName:reinterpret_cast(pbname)]; + CFRelease (pbname); } + if (pb) { + NSString *text = [pb stringForType:NSStringPboardType]; + if (text) + return qt_mac_NSStringToQString(text); + } + return QString(); } QPixmap qt_mac_convert_iconref(const IconRef icon, int width, int height) diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h index 62db064..ea35fb6 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h +++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h @@ -170,7 +170,7 @@ void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list); void qt_syncCocoaTitleBarButtons(OSWindowRef window, QWidget *widgetForWindow); CGFloat qt_mac_get_scalefactor(); -QString qt_mac_get_pasteboardString(); +QString qt_mac_get_pasteboardString(OSPasteboardRef paste); #ifdef __OBJC__ inline NSMutableArray *qt_mac_QStringListToNSMutableArray(const QStringList &qstrlist) -- cgit v0.12 From 7f2d0fdf064f1e5625b784a5712d21545cf79ba1 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 28 Oct 2009 12:49:38 +0100 Subject: Rename private member variables to begin with m_ Reviewed-By: TrustMe --- src/gui/kernel/qgesturemanager.cpp | 116 ++++++++++++++++++------------------- src/gui/kernel/qgesturemanager_p.h | 17 +++--- 2 files changed, 66 insertions(+), 67 deletions(-) diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index fc7c8b2..a90c299 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -65,7 +65,7 @@ QT_BEGIN_NAMESPACE QGestureManager::QGestureManager(QObject *parent) - : QObject(parent), state(NotGesture), lastCustomGestureId(0) + : QObject(parent), state(NotGesture), m_lastCustomGestureId(0) { qRegisterMetaType(); @@ -82,7 +82,7 @@ QGestureManager::QGestureManager(QObject *parent) QGestureManager::~QGestureManager() { - qDeleteAll(recognizers.values()); + qDeleteAll(m_recognizers.values()); } Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *recognizer) @@ -96,30 +96,30 @@ Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *r Qt::GestureType type = dummy->gestureType(); if (type == Qt::CustomGesture) { // generate a new custom gesture id - ++lastCustomGestureId; - type = Qt::GestureType(Qt::CustomGesture + lastCustomGestureId); + ++m_lastCustomGestureId; + type = Qt::GestureType(Qt::CustomGesture + m_lastCustomGestureId); } - recognizers.insertMulti(type, recognizer); + m_recognizers.insertMulti(type, recognizer); delete dummy; return type; } void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type) { - QList list = recognizers.values(type); - recognizers.remove(type); - foreach (QGesture* g, gestureToRecognizer.keys()) { - QGestureRecognizer *recognizer = gestureToRecognizer.value(g); + QList list = m_recognizers.values(type); + m_recognizers.remove(type); + foreach (QGesture* g, m_gestureToRecognizer.keys()) { + QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g); if (list.contains(recognizer)) { m_deletedRecognizers.insert(g, recognizer); - gestureToRecognizer.remove(g); + m_gestureToRecognizer.remove(g); } } foreach (QGestureRecognizer *recognizer, list) { QList obsoleteGestures; - QMap::Iterator iter = objectGestures.begin(); - while (iter != objectGestures.end()) { + QMap::Iterator iter = m_objectGestures.begin(); + while (iter != m_objectGestures.end()) { ObjectGesture objectGesture = iter.key(); if (objectGesture.gesture == type) obsoleteGestures << iter.value(); @@ -131,12 +131,12 @@ void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type) void QGestureManager::cleanupCachedGestures(QObject *target, Qt::GestureType type) { - QMap::Iterator iter = objectGestures.begin(); - while (iter != objectGestures.end()) { + QMap::Iterator iter = m_objectGestures.begin(); + while (iter != m_objectGestures.end()) { ObjectGesture objectGesture = iter.key(); if (objectGesture.gesture == type && target == objectGesture.object.data()) { delete iter.value(); - iter = objectGestures.erase(iter); + iter = m_objectGestures.erase(iter); } else { ++iter; } @@ -159,9 +159,9 @@ QGesture *QGestureManager::getState(QObject *object, Qt::GestureType type) } QGesture *state = - objectGestures.value(QGestureManager::ObjectGesture(object, type)); + m_objectGestures.value(QGestureManager::ObjectGesture(object, type)); if (!state) { - QGestureRecognizer *recognizer = recognizers.value(type); + QGestureRecognizer *recognizer = m_recognizers.value(type); if (recognizer) { state = recognizer->createGesture(object); if (!state) @@ -175,9 +175,9 @@ QGesture *QGestureManager::getState(QObject *object, Qt::GestureType type) state->setObjectName(QString::number((int)type)); #endif } - objectGestures.insert(QGestureManager::ObjectGesture(object, type), state); - gestureToRecognizer[state] = recognizer; - gestureOwners[state] = object; + m_objectGestures.insert(QGestureManager::ObjectGesture(object, type), state); + m_gestureToRecognizer[state] = recognizer; + m_gestureOwners[state] = object; } } return state; @@ -203,8 +203,8 @@ bool QGestureManager::filterEventThroughContexts(const QMap::const_iterator - rit = recognizers.lowerBound(gestureType), - re = recognizers.upperBound(gestureType); + rit = m_recognizers.lowerBound(gestureType), + re = m_recognizers.upperBound(gestureType); for (; rit != re; ++rit) { QGestureRecognizer *recognizer = rit.value(); QObject *target = cit.key(); @@ -239,20 +239,20 @@ bool QGestureManager::filterEventThroughContexts(const QMap startedGestures = triggeredGestures - activeGestures; - triggeredGestures &= activeGestures; + QSet startedGestures = triggeredGestures - m_activeGestures; + triggeredGestures &= m_activeGestures; // check if a running gesture switched back to maybe state - QSet activeToMaybeGestures = activeGestures & newMaybeGestures; + QSet activeToMaybeGestures = m_activeGestures & newMaybeGestures; // check if a running gesture switched back to not gesture state, // i.e. were canceled - QSet activeToCancelGestures = activeGestures & notGestures; + QSet activeToCancelGestures = m_activeGestures & notGestures; canceledGestures += activeToCancelGestures; // start timers for new gestures in maybe state foreach (QGesture *state, newMaybeGestures) { - QBasicTimer &timer = maybeGestures[state]; + QBasicTimer &timer = m_maybeGestures[state]; if (!timer.isActive()) timer.start(3000, this); } @@ -262,10 +262,10 @@ bool QGestureManager::filterEventThroughContexts(const QMap::iterator it = - maybeGestures.find(gesture); - if (it != maybeGestures.end()) { + m_maybeGestures.find(gesture); + if (it != m_maybeGestures.end()) { it.value().stop(); - maybeGestures.erase(it); + m_maybeGestures.erase(it); } } @@ -276,7 +276,7 @@ bool QGestureManager::filterEventThroughContexts(const QMap notStarted = finishedGestures - activeGestures; + QSet notStarted = finishedGestures - m_activeGestures; if (!notStarted.isEmpty()) { // there are some gestures that claim to be finished, but never started. // probably those are "singleshot" gestures so we'll fake the started state. @@ -287,12 +287,12 @@ bool QGestureManager::filterEventThroughContexts(const QMapd_func()->state = Qt::GestureFinished; - if (!activeGestures.isEmpty() || !maybeGestures.isEmpty() || + if (!m_activeGestures.isEmpty() || !m_maybeGestures.isEmpty() || !startedGestures.isEmpty() || !triggeredGestures.isEmpty() || !finishedGestures.isEmpty() || !canceledGestures.isEmpty()) { DEBUG() << "QGestureManager::filterEventThroughContexts:" - << "\n\tactiveGestures:" << activeGestures - << "\n\tmaybeGestures:" << maybeGestures.keys() + << "\n\tactiveGestures:" << m_activeGestures + << "\n\tmaybeGestures:" << m_maybeGestures.keys() << "\n\tstarted:" << startedGestures << "\n\ttriggered:" << triggeredGestures << "\n\tfinished:" << finishedGestures @@ -332,19 +332,19 @@ bool QGestureManager::filterEventThroughContexts(const QMap endedGestures = finishedGestures + canceledGestures + undeliveredGestures; foreach (QGesture *gesture, endedGestures) { - if (QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0)) { + if (QGestureRecognizer *recognizer = m_gestureToRecognizer.value(gesture, 0)) { gesture->setGestureCancelPolicy(QGesture::CancelNone); recognizer->reset(gesture); } else { cleanupGesturesForRemovedRecognizer(gesture); } - gestureTargets.remove(gesture); + m_gestureTargets.remove(gesture); } return ret; } @@ -353,7 +353,7 @@ bool QGestureManager::filterEventThroughContexts(const QMap cancelledGestures; - QSet::Iterator iter = activeGestures.begin(); - while (iter != activeGestures.end()) { - QWidget *widget = gestureTargets.value(*iter); + QSet::Iterator iter = m_activeGestures.begin(); + while (iter != m_activeGestures.end()) { + QWidget *widget = m_gestureTargets.value(*iter); // note that we don't touch the gestures for our originatingWidget if (widget != originatingWidget && originatingWidget->isAncestorOf(widget)) { DEBUG() << " found a gesture to cancel" << (*iter); (*iter)->d_func()->state = Qt::GestureCanceled; cancelledGestures << *iter; - iter = activeGestures.erase(iter); + iter = m_activeGestures.erase(iter); } else { ++iter; } @@ -385,7 +385,7 @@ void QGestureManager::cancelGesturesForChildren(QGesture *original) iter = almostCanceledGestures.begin(); // sort per target widget while (iter != almostCanceledGestures.end()) { - QWidget *widget = gestureTargets.value(*iter); + QWidget *widget = m_gestureTargets.value(*iter); if (target == 0) target = widget; if (target == widget) { @@ -402,7 +402,7 @@ void QGestureManager::cancelGesturesForChildren(QGesture *original) } for (iter = cancelledGestures.begin(); iter != cancelledGestures.end(); ++iter) { - QGestureRecognizer *recognizer = gestureToRecognizer.value(*iter, 0); + QGestureRecognizer *recognizer = m_gestureToRecognizer.value(*iter, 0); if (recognizer) { (*iter)->setGestureCancelPolicy(QGesture::CancelNone); recognizer->reset(*iter); @@ -507,7 +507,7 @@ void QGestureManager::getGestureTargets(const QSet &gestures, // sort gestures by types foreach (QGesture *gesture, gestures) { - QWidget *receiver = gestureTargets.value(gesture, 0); + QWidget *receiver = m_gestureTargets.value(gesture, 0); Q_ASSERT(receiver); gestureByTypes[gesture->gestureType()].insert(receiver, gesture); } @@ -556,7 +556,7 @@ void QGestureManager::deliverEvents(const QSet &gestures, for (QSet::const_iterator it = gestures.begin(), e = gestures.end(); it != e; ++it) { QGesture *gesture = *it; - QWidget *target = gestureTargets.value(gesture, 0); + QWidget *target = m_gestureTargets.value(gesture, 0); if (!target) { // the gesture has just started and doesn't have a target yet. Q_ASSERT(gesture->state() == Qt::GestureStarted); @@ -568,12 +568,12 @@ void QGestureManager::deliverEvents(const QSet &gestures, } } else { // or use the context of the gesture - QObject *context = gestureOwners.value(gesture, 0); + QObject *context = m_gestureOwners.value(gesture, 0); if (context->isWidgetType()) target = static_cast(context); } if (target) - gestureTargets.insert(gesture, target); + m_gestureTargets.insert(gesture, target); } Qt::GestureType gestureType = gesture->gestureType(); @@ -625,7 +625,7 @@ void QGestureManager::deliverEvents(const QSet &gestures, QList &gestures = normalStartedGestures[w]; gestures.append(gesture); // override the target - gestureTargets[gesture] = w; + m_gestureTargets[gesture] = w; } else { DEBUG() << "override event: gesture wasn't accepted. putting back:" << gesture; QList &gestures = normalStartedGestures[receiver]; @@ -648,18 +648,18 @@ void QGestureManager::deliverEvents(const QSet &gestures, void QGestureManager::timerEvent(QTimerEvent *event) { - QMap::iterator it = maybeGestures.begin(), - e = maybeGestures.end(); + QMap::iterator it = m_maybeGestures.begin(), + e = m_maybeGestures.end(); for (; it != e; ) { QBasicTimer &timer = it.value(); Q_ASSERT(timer.isActive()); if (timer.timerId() == event->timerId()) { timer.stop(); QGesture *gesture = it.key(); - it = maybeGestures.erase(it); + it = m_maybeGestures.erase(it); DEBUG() << "QGestureManager::timerEvent: gesture stopped due to timeout:" << gesture; - QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0); + QGestureRecognizer *recognizer = m_gestureToRecognizer.value(gesture, 0); if (recognizer) { gesture->setGestureCancelPolicy(QGesture::CancelNone); recognizer->reset(gesture); diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h index e6a1d50..5a2816c 100644 --- a/src/gui/kernel/qgesturemanager_p.h +++ b/src/gui/kernel/qgesturemanager_p.h @@ -87,10 +87,10 @@ protected: QEvent *event); private: - QMultiMap recognizers; + QMultiMap m_recognizers; - QSet activeGestures; - QMap maybeGestures; + QSet m_activeGestures; + QMap m_maybeGestures; enum State { Gesture, @@ -116,14 +116,13 @@ private: } }; - // TODO rename all member vars to be m_ - QMap objectGestures; // TODO rename widgetGestures - QMap gestureToRecognizer; - QHash gestureOwners; + QMap m_objectGestures; + QMap m_gestureToRecognizer; + QHash m_gestureOwners; - QHash gestureTargets; + QHash m_gestureTargets; - int lastCustomGestureId; + int m_lastCustomGestureId; QHash > m_obsoleteGestures; QMap m_deletedRecognizers; -- cgit v0.12 From 0dc77406ae05c6ad27406e91b230b177b97fbc7c Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 28 Oct 2009 12:56:59 +0100 Subject: Make the un/registerGestureRecognizer methods static As QApplication is a singleton this makes usage of these easier and also in line with many other methods on the class. --- src/gui/kernel/qapplication.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h index 5a8e325..5877ba4 100644 --- a/src/gui/kernel/qapplication.h +++ b/src/gui/kernel/qapplication.h @@ -288,8 +288,8 @@ public: static Qt::NavigationMode navigationMode(); #endif - Qt::GestureType registerGestureRecognizer(QGestureRecognizer *recognizer); - void unregisterGestureRecognizer(Qt::GestureType type); + static Qt::GestureType registerGestureRecognizer(QGestureRecognizer *recognizer); + static void unregisterGestureRecognizer(Qt::GestureType type); Q_SIGNALS: void lastWindowClosed(); -- cgit v0.12 From 603d3fb41601e9c69e0f2f3afe4b3717b33f75e4 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 28 Oct 2009 12:59:51 +0100 Subject: Mark the QGestureEvent::setWidget as internal The widget() getter is still publicly documented, follow the lead of other events to make the setter internal. --- src/gui/kernel/qevent.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index ea05869..ab43e79 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -4398,6 +4398,8 @@ bool QGestureEvent::isAccepted(Qt::GestureType gestureType) const } /*! + \internal + Sets the widget for this event. */ void QGestureEvent::setWidget(QWidget *widget) -- cgit v0.12 From 244d8993c4aac6746306e58b1b766f804e2566f4 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 28 Oct 2009 13:36:43 +0100 Subject: Follow refactor; use QApplication:: instead of qApp-> Our tests now call the recently converted registerRecognizer using a proper static method. --- tests/auto/gestures/tst_gestures.cpp | 46 ++++++++++++++--------------- tests/manual/gestures/graphicsview/main.cpp | 4 +-- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index 39cdf63..02c8232 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -344,14 +344,14 @@ tst_Gestures::~tst_Gestures() void tst_Gestures::initTestCase() { - CustomGesture::GestureType = qApp->registerGestureRecognizer(new CustomGestureRecognizer); + CustomGesture::GestureType = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); QVERIFY(CustomGesture::GestureType != Qt::GestureType(0)); QVERIFY(CustomGesture::GestureType != Qt::CustomGesture); } void tst_Gestures::cleanupTestCase() { - qApp->unregisterGestureRecognizer(CustomGesture::GestureType); + QApplication::unregisterGestureRecognizer(CustomGesture::GestureType); } void tst_Gestures::init() @@ -558,7 +558,7 @@ void tst_Gestures::conflictingGestures() parent.reset(); child->reset(); - Qt::GestureType ContinuousGesture = qApp->registerGestureRecognizer(new CustomContinuousGestureRecognizer); + Qt::GestureType ContinuousGesture = QApplication::registerGestureRecognizer(new CustomContinuousGestureRecognizer); static const int ContinuousGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialMaybeThreshold + 1; child->grabGesture(ContinuousGesture); // child accepts override. And it also receives another custom gesture. @@ -572,7 +572,7 @@ void tst_Gestures::conflictingGestures() QCOMPARE(parent.gestureOverrideEventsReceived, 0); QCOMPARE(parent.gestureEventsReceived, 0); - qApp->unregisterGestureRecognizer(ContinuousGesture); + QApplication::unregisterGestureRecognizer(ContinuousGesture); } void tst_Gestures::finishedWithoutStarted() @@ -981,7 +981,7 @@ void tst_Gestures::twoGesturesOnDifferentLevel() GestureWidget *child = new GestureWidget("child"); l->addWidget(child); - Qt::GestureType SecondGesture = qApp->registerGestureRecognizer(new CustomGestureRecognizer); + Qt::GestureType SecondGesture = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); parent.grabGesture(CustomGesture::GestureType, Qt::WidgetWithChildrenGesture); child->grabGesture(SecondGesture, Qt::WidgetWithChildrenGesture); @@ -1009,7 +1009,7 @@ void tst_Gestures::twoGesturesOnDifferentLevel() for(int i = 0; i < child->events.all.size(); ++i) QCOMPARE(parent.events.all.at(i), CustomGesture::GestureType); - qApp->unregisterGestureRecognizer(SecondGesture); + QApplication::unregisterGestureRecognizer(SecondGesture); } void tst_Gestures::multipleGesturesInTree() @@ -1021,8 +1021,8 @@ void tst_Gestures::multipleGesturesInTree() GestureWidget *D = new GestureWidget("D", C); Qt::GestureType FirstGesture = CustomGesture::GestureType; - Qt::GestureType SecondGesture = qApp->registerGestureRecognizer(new CustomGestureRecognizer); - Qt::GestureType ThirdGesture = qApp->registerGestureRecognizer(new CustomGestureRecognizer); + Qt::GestureType SecondGesture = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); + Qt::GestureType ThirdGesture = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); A->grabGesture(FirstGesture, Qt::WidgetWithChildrenGesture); // A [1 3] A->grabGesture(ThirdGesture, Qt::WidgetWithChildrenGesture); // | @@ -1079,8 +1079,8 @@ void tst_Gestures::multipleGesturesInTree() QCOMPARE(A->events.all.count(SecondGesture), 0); QCOMPARE(A->events.all.count(ThirdGesture), TotalGestureEventsCount); - qApp->unregisterGestureRecognizer(SecondGesture); - qApp->unregisterGestureRecognizer(ThirdGesture); + QApplication::unregisterGestureRecognizer(SecondGesture); + QApplication::unregisterGestureRecognizer(ThirdGesture); } void tst_Gestures::multipleGesturesInComplexTree() @@ -1092,12 +1092,12 @@ void tst_Gestures::multipleGesturesInComplexTree() GestureWidget *D = new GestureWidget("D", C); Qt::GestureType FirstGesture = CustomGesture::GestureType; - Qt::GestureType SecondGesture = qApp->registerGestureRecognizer(new CustomGestureRecognizer); - Qt::GestureType ThirdGesture = qApp->registerGestureRecognizer(new CustomGestureRecognizer); - Qt::GestureType FourthGesture = qApp->registerGestureRecognizer(new CustomGestureRecognizer); - Qt::GestureType FifthGesture = qApp->registerGestureRecognizer(new CustomGestureRecognizer); - Qt::GestureType SixthGesture = qApp->registerGestureRecognizer(new CustomGestureRecognizer); - Qt::GestureType SeventhGesture = qApp->registerGestureRecognizer(new CustomGestureRecognizer); + Qt::GestureType SecondGesture = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); + Qt::GestureType ThirdGesture = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); + Qt::GestureType FourthGesture = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); + Qt::GestureType FifthGesture = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); + Qt::GestureType SixthGesture = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); + Qt::GestureType SeventhGesture = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); A->grabGesture(FirstGesture, Qt::WidgetWithChildrenGesture); // A [1,3,4] A->grabGesture(ThirdGesture, Qt::WidgetWithChildrenGesture); // | @@ -1175,12 +1175,12 @@ void tst_Gestures::multipleGesturesInComplexTree() QCOMPARE(A->events.all.count(SixthGesture), 0); QCOMPARE(A->events.all.count(SeventhGesture), 0); - qApp->unregisterGestureRecognizer(SecondGesture); - qApp->unregisterGestureRecognizer(ThirdGesture); - qApp->unregisterGestureRecognizer(FourthGesture); - qApp->unregisterGestureRecognizer(FifthGesture); - qApp->unregisterGestureRecognizer(SixthGesture); - qApp->unregisterGestureRecognizer(SeventhGesture); + QApplication::unregisterGestureRecognizer(SecondGesture); + QApplication::unregisterGestureRecognizer(ThirdGesture); + QApplication::unregisterGestureRecognizer(FourthGesture); + QApplication::unregisterGestureRecognizer(FifthGesture); + QApplication::unregisterGestureRecognizer(SixthGesture); + QApplication::unregisterGestureRecognizer(SeventhGesture); } void tst_Gestures::testMapToScene() @@ -1329,7 +1329,7 @@ void tst_Gestures::autoCancelGestures() GestureWidget *child = new GestureWidget("child", &parent); child->setGeometry(10, 10, 100, 80); - Qt::GestureType type = qApp->registerGestureRecognizer(new MockRecognizer()); + Qt::GestureType type = QApplication::registerGestureRecognizer(new MockRecognizer()); parent.grabGesture(type, Qt::WidgetWithChildrenGesture); child->grabGesture(type, Qt::WidgetWithChildrenGesture); diff --git a/tests/manual/gestures/graphicsview/main.cpp b/tests/manual/gestures/graphicsview/main.cpp index e9065eb..de92afe 100644 --- a/tests/manual/gestures/graphicsview/main.cpp +++ b/tests/manual/gestures/graphicsview/main.cpp @@ -152,8 +152,8 @@ private: MainWindow::MainWindow() { - (void)qApp->registerGestureRecognizer(new MousePanGestureRecognizer); - ThreeFingerSlideGesture::Type = qApp->registerGestureRecognizer(new ThreeFingerSlideGestureRecognizer); + (void)QApplication::registerGestureRecognizer(new MousePanGestureRecognizer); + ThreeFingerSlideGesture::Type = QApplication::registerGestureRecognizer(new ThreeFingerSlideGestureRecognizer); tabWidget = new QTabWidget; -- cgit v0.12 From 4f4c4fda9925f585128175796d04926863943dad Mon Sep 17 00:00:00 2001 From: dka Date: Mon, 19 Oct 2009 12:21:02 +0300 Subject: QLocale: AM/PM symbol support for symbian platform Reviewed-by: Denis Dzyubenko --- src/corelib/tools/qlocale_symbian.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qlocale_symbian.cpp b/src/corelib/tools/qlocale_symbian.cpp index 1660e95..1273d06 100644 --- a/src/corelib/tools/qlocale_symbian.cpp +++ b/src/corelib/tools/qlocale_symbian.cpp @@ -873,9 +873,11 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const } case NegativeSign: case PositiveSign: + break; case AMText: + return qt_TDes2QString(TAmPmName(TAmPm(EAm))); case PMText: - break; + return qt_TDes2QString(TAmPmName(TAmPm(EPm))); default: break; } -- cgit v0.12 From 7a215265994bca72bbc7fcc198048c2f6bb7527a Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 28 Oct 2009 12:05:26 +0100 Subject: Removed obsolete private field from the QGesture and fixed the doc. Reviewed-by: Thomas Zander --- src/gui/kernel/qgesture.cpp | 11 +++++------ src/gui/kernel/qgesture_p.h | 5 +---- src/gui/kernel/qgesturerecognizer.cpp | 2 +- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index c302c51..b72fae0 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -69,10 +69,9 @@ QT_BEGIN_NAMESPACE \section1 Lifecycle of a Gesture Object - A QGesture instance is created when the application calls QWidget::grabGesture() - or QGraphicsObject::grabGesture() to configure a widget or graphics object (the - target object) for gesture input. One gesture object is created for each target - object. + A QGesture instance is implicitely created when needed and is owned by Qt, + so application developer should never destroy them or store a pointer to a + QGesture object. The registered gesture recognizer monitors the input events for the target object via its \l{QGestureRecognizer::}{filterEvent()} function, updating the @@ -133,8 +132,8 @@ QGesture::~QGesture() QWidget::mapFromGlobal() or QGestureEvent::mapToScene() to get a local hot-spot. - If the hot-spot is not set, the targetObject is used as the receiver of the - gesture event. + The hot-spot should be set by the gesture recognizer to allow gesture event + delivery to a QGraphicsObject. */ /*! diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h index d2ef8a7..34fbb26 100644 --- a/src/gui/kernel/qgesture_p.h +++ b/src/gui/kernel/qgesture_p.h @@ -68,9 +68,7 @@ class QGesturePrivate : public QObjectPrivate public: QGesturePrivate() : gestureType(Qt::CustomGesture), state(Qt::NoGesture), - targetObject(0), - isHotSpotSet(false), - gestureCancelPolicy(0) + isHotSpotSet(false), gestureCancelPolicy(0) { } @@ -78,7 +76,6 @@ public: Qt::GestureType gestureType; Qt::GestureState state; QPointF hotSpot; - QObject *targetObject; uint isHotSpotSet : 1; uint gestureCancelPolicy : 2; }; diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/gui/kernel/qgesturerecognizer.cpp index c2b26f0..2673be3 100644 --- a/src/gui/kernel/qgesturerecognizer.cpp +++ b/src/gui/kernel/qgesturerecognizer.cpp @@ -178,7 +178,7 @@ void QGestureRecognizer::reset(QGesture *gesture) QGesturePrivate *d = gesture->d_func(); d->state = Qt::NoGesture; d->hotSpot = QPointF(); - d->targetObject = 0; + d->isHotSpotSet = false; } } -- cgit v0.12 From a2b12363c96d4307444552eefc21eebf430dba5d Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 28 Oct 2009 13:05:20 +0100 Subject: Fixed the scrollarea gesture manual test. Reviewed-by: trustme --- tests/manual/gestures/scrollarea/mousepangesturerecognizer.cpp | 2 +- tests/manual/gestures/scrollarea/mousepangesturerecognizer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/manual/gestures/scrollarea/mousepangesturerecognizer.cpp b/tests/manual/gestures/scrollarea/mousepangesturerecognizer.cpp index 5f94dbc..63d3e76 100644 --- a/tests/manual/gestures/scrollarea/mousepangesturerecognizer.cpp +++ b/tests/manual/gestures/scrollarea/mousepangesturerecognizer.cpp @@ -49,7 +49,7 @@ MousePanGestureRecognizer::MousePanGestureRecognizer() { } -QGesture* MousePanGestureRecognizer::createGesture(QObject *) const +QGesture* MousePanGestureRecognizer::createGesture(QObject *) { return new QPanGesture; } diff --git a/tests/manual/gestures/scrollarea/mousepangesturerecognizer.h b/tests/manual/gestures/scrollarea/mousepangesturerecognizer.h index c92d477..b062fd0 100644 --- a/tests/manual/gestures/scrollarea/mousepangesturerecognizer.h +++ b/tests/manual/gestures/scrollarea/mousepangesturerecognizer.h @@ -49,7 +49,7 @@ class MousePanGestureRecognizer : public QGestureRecognizer public: MousePanGestureRecognizer(); - QGesture* createGesture(QObject *target) const; + QGesture* createGesture(QObject *target); QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event); void reset(QGesture *state); }; -- cgit v0.12 From 3ce8fb5e754014ed29cabf9e33b71dabecb02e46 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 28 Oct 2009 13:06:03 +0100 Subject: Fixed the gesture event filtering through multiple gesture recognizers. When there are several gesture recognizers registered for the same gesture type, we need to know which recognizer we need to get a state object for since those QGesture objects are tied to the recognizer that created them. Reviewed-by: Thomas Zander --- src/gui/kernel/qgesturemanager.cpp | 49 ++++++++++++++++++++------------------ src/gui/kernel/qgesturemanager_p.h | 5 ++-- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index a90c299..04dcfe3 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -118,7 +118,7 @@ void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type) foreach (QGestureRecognizer *recognizer, list) { QList obsoleteGestures; - QMap::Iterator iter = m_objectGestures.begin(); + QMap >::Iterator iter = m_objectGestures.begin(); while (iter != m_objectGestures.end()) { ObjectGesture objectGesture = iter.key(); if (objectGesture.gesture == type) @@ -131,11 +131,11 @@ void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type) void QGestureManager::cleanupCachedGestures(QObject *target, Qt::GestureType type) { - QMap::Iterator iter = m_objectGestures.begin(); + QMap >::Iterator iter = m_objectGestures.begin(); while (iter != m_objectGestures.end()) { ObjectGesture objectGesture = iter.key(); if (objectGesture.gesture == type && target == objectGesture.object.data()) { - delete iter.value(); + qDeleteAll(iter.value()); iter = m_objectGestures.erase(iter); } else { ++iter; @@ -144,7 +144,7 @@ void QGestureManager::cleanupCachedGestures(QObject *target, Qt::GestureType typ } // get or create a QGesture object that will represent the state for a given object, used by the recognizer -QGesture *QGestureManager::getState(QObject *object, Qt::GestureType type) +QGesture *QGestureManager::getState(QObject *object, QGestureRecognizer *recognizer, Qt::GestureType type) { // if the widget is being deleted we should be carefull and not to // create a new state, as it will create QWeakPointer which doesnt work @@ -158,28 +158,31 @@ QGesture *QGestureManager::getState(QObject *object, Qt::GestureType type) Q_ASSERT(qobject_cast(object)); } - QGesture *state = + QList states = m_objectGestures.value(QGestureManager::ObjectGesture(object, type)); - if (!state) { - QGestureRecognizer *recognizer = m_recognizers.value(type); - if (recognizer) { - state = recognizer->createGesture(object); - if (!state) - return 0; - state->setParent(this); - if (state->gestureType() == Qt::CustomGesture) { - // if the recognizer didn't fill in the gesture type, then this - // is a custom gesture with autogenerated it and we fill it. - state->d_func()->gestureType = type; + // check if the QGesture for this recognizer has already been created + foreach (QGesture *state, states) { + if (m_gestureToRecognizer.value(state) == recognizer) + return state; + } + + Q_ASSERT(recognizer); + QGesture *state = recognizer->createGesture(object); + if (!state) + return 0; + state->setParent(this); + if (state->gestureType() == Qt::CustomGesture) { + // if the recognizer didn't fill in the gesture type, then this + // is a custom gesture with autogenerated id and we fill it. + state->d_func()->gestureType = type; #if defined(GESTURE_DEBUG) - state->setObjectName(QString::number((int)type)); + state->setObjectName(QString::number((int)type)); #endif - } - m_objectGestures.insert(QGestureManager::ObjectGesture(object, type), state); - m_gestureToRecognizer[state] = recognizer; - m_gestureOwners[state] = object; - } } + m_objectGestures[QGestureManager::ObjectGesture(object, type)].append(state); + m_gestureToRecognizer[state] = recognizer; + m_gestureOwners[state] = object; + return state; } @@ -208,7 +211,7 @@ bool QGestureManager::filterEventThroughContexts(const QMapfilterEvent(state, target, event); diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h index 5a2816c..f128273 100644 --- a/src/gui/kernel/qgesturemanager_p.h +++ b/src/gui/kernel/qgesturemanager_p.h @@ -116,7 +116,7 @@ private: } }; - QMap m_objectGestures; + QMap > m_objectGestures; QMap m_gestureToRecognizer; QHash m_gestureOwners; @@ -128,7 +128,8 @@ private: QMap m_deletedRecognizers; void cleanupGesturesForRemovedRecognizer(QGesture *gesture); - QGesture *getState(QObject *widget, Qt::GestureType gesture); + QGesture *getState(QObject *widget, QGestureRecognizer *recognizer, + Qt::GestureType gesture); void deliverEvents(const QSet &gestures, QSet *undeliveredGestures); void getGestureTargets(const QSet &gestures, -- cgit v0.12 From 96b8e9f824daaf88cb8c153caa774a92b0261580 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 28 Oct 2009 13:11:49 +0100 Subject: Delete all gesture objects and recognizers when gesture manager is deleted. When application closes and we haven't deleted the unregistered gestures and gesture recognizer, we should delete them. Reviewed-by: Thomas Zander --- src/gui/kernel/qgesturemanager.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index 04dcfe3..3eb15cf 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -83,6 +83,11 @@ QGestureManager::QGestureManager(QObject *parent) QGestureManager::~QGestureManager() { qDeleteAll(m_recognizers.values()); + foreach (QGestureRecognizer *recognizer, m_obsoleteGestures.keys()) { + qDeleteAll(m_obsoleteGestures.value(recognizer)); + delete recognizer; + } + m_obsoleteGestures.clear(); } Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *recognizer) -- cgit v0.12 From 6efb1b7df725c74f265d0f315993542b0bd19b97 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 28 Oct 2009 14:07:53 +0100 Subject: Tiny doc change by David Boddie. Reviewed-by: David Boddie --- src/gui/kernel/qgesture.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index b72fae0..850f22c 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -69,9 +69,9 @@ QT_BEGIN_NAMESPACE \section1 Lifecycle of a Gesture Object - A QGesture instance is implicitely created when needed and is owned by Qt, - so application developer should never destroy them or store a pointer to a - QGesture object. + A QGesture instance is implicitly created when needed and is owned by Qt. + Developers should never destroy them or store them for later use as Qt may + destroy particular instances of them and create new ones to replace them. The registered gesture recognizer monitors the input events for the target object via its \l{QGestureRecognizer::}{filterEvent()} function, updating the -- cgit v0.12 From 4b3ef85b499d9ec508acdf83d250e022161defbb Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 28 Oct 2009 14:30:11 +0100 Subject: Replaced QMap with QHash where possible in the gesture manager implementation. There is no reason to use QMap when the key is a pointer. Reviewed-by: Thomas Zander --- src/gui/kernel/qgesturemanager.cpp | 18 +++++++++--------- src/gui/kernel/qgesturemanager_p.h | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index 3eb15cf..f1abc89 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -113,7 +113,7 @@ void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type) { QList list = m_recognizers.values(type); m_recognizers.remove(type); - foreach (QGesture* g, m_gestureToRecognizer.keys()) { + foreach (QGesture *g, m_gestureToRecognizer.keys()) { QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g); if (list.contains(recognizer)) { m_deletedRecognizers.insert(g, recognizer); @@ -191,7 +191,7 @@ QGesture *QGestureManager::getState(QObject *object, QGestureRecognizer *recogni return state; } -bool QGestureManager::filterEventThroughContexts(const QMap &contexts, QEvent *event) { @@ -207,7 +207,7 @@ bool QGestureManager::filterEventThroughContexts(const QMap::const_iterator ContextIterator; + typedef QHash::const_iterator ContextIterator; for (ContextIterator cit = contexts.begin(), ce = contexts.end(); cit != ce; ++cit) { Qt::GestureType gestureType = cit.value(); QMap::const_iterator @@ -269,7 +269,7 @@ bool QGestureManager::filterEventThroughContexts(const QMap::iterator it = + QHash::iterator it = m_maybeGestures.find(gesture); if (it != m_maybeGestures.end()) { it.value().stop(); @@ -437,7 +437,7 @@ void QGestureManager::cleanupGesturesForRemovedRecognizer(QGesture *gesture) bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) { QSet types; - QMap contexts; + QMultiHash contexts; QWidget *w = receiver; typedef QMap::const_iterator ContextIterator; if (!w->d_func()->gestureContext.isEmpty()) { @@ -470,7 +470,7 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event) { QSet types; - QMap contexts; + QMultiHash contexts; QGraphicsObject *item = receiver; if (!item->QGraphicsItem::d_func()->gestureContext.isEmpty()) { typedef QMap::const_iterator ContextIterator; @@ -501,7 +501,7 @@ bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event) bool QGestureManager::filterEvent(QGesture *state, QEvent *event) { - QMap contexts; + QMultiHash contexts; contexts.insert(state, state->gestureType()); return filterEventThroughContexts(contexts, event); } @@ -656,8 +656,8 @@ void QGestureManager::deliverEvents(const QSet &gestures, void QGestureManager::timerEvent(QTimerEvent *event) { - QMap::iterator it = m_maybeGestures.begin(), - e = m_maybeGestures.end(); + QHash::iterator it = m_maybeGestures.begin(), + e = m_maybeGestures.end(); for (; it != e; ) { QBasicTimer &timer = it.value(); Q_ASSERT(timer.isActive()); diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h index f128273..4958cdb 100644 --- a/src/gui/kernel/qgesturemanager_p.h +++ b/src/gui/kernel/qgesturemanager_p.h @@ -83,14 +83,14 @@ public: protected: void timerEvent(QTimerEvent *event); - bool filterEventThroughContexts(const QMap &contexts, + bool filterEventThroughContexts(const QMultiHash &contexts, QEvent *event); private: QMultiMap m_recognizers; QSet m_activeGestures; - QMap m_maybeGestures; + QHash m_maybeGestures; enum State { Gesture, @@ -117,7 +117,7 @@ private: }; QMap > m_objectGestures; - QMap m_gestureToRecognizer; + QHash m_gestureToRecognizer; QHash m_gestureOwners; QHash m_gestureTargets; @@ -125,7 +125,7 @@ private: int m_lastCustomGestureId; QHash > m_obsoleteGestures; - QMap m_deletedRecognizers; + QHash m_deletedRecognizers; void cleanupGesturesForRemovedRecognizer(QGesture *gesture); QGesture *getState(QObject *widget, QGestureRecognizer *recognizer, -- cgit v0.12 From e4606e2d6491bd7020e8bfb12665c3addc24b7e3 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 28 Oct 2009 14:47:28 +0100 Subject: Wrong font used when moving a tab in document mode. Dragging is handled by a seperate window in document mode. The currently selected tabbar item is drawn to a pixmap for this purpose. That paintdevice was not initialized correctly. (e.g. font) Reviewed-by: Trond --- src/gui/widgets/qtabbar.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp index 4dffbdc..3935c55 100644 --- a/src/gui/widgets/qtabbar.cpp +++ b/src/gui/widgets/qtabbar.cpp @@ -1812,6 +1812,7 @@ void QTabBarPrivate::setupMovableTab() QPixmap grabImage(grabRect.size()); grabImage.fill(Qt::transparent); QStylePainter p(&grabImage, q); + p.initFrom(q); QStyleOptionTabV3 tab; q->initStyleOption(&tab, pressedIndex); -- cgit v0.12 From dbaa856d4d20840394baf8f4c9abf78051a6693a Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Wed, 7 Oct 2009 16:15:43 +0200 Subject: Fix split tool button drawing on Vista when not in a tool bar When a tool button is not in a tool bar on XP and Vista it will get a slightly different appearance from normal tool buttons. I resolved this by drawing a normal tool button with a divider line on top if the autoraise property is not set on the button. (which is by default enabled only for buttons in a tool bar). Task-number: QTBUG-5061 Reviewed-by: prasanth --- src/gui/styles/qwindowsxpstyle.cpp | 46 +++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/src/gui/styles/qwindowsxpstyle.cpp b/src/gui/styles/qwindowsxpstyle.cpp index 2f00f07..b5dc647 100644 --- a/src/gui/styles/qwindowsxpstyle.cpp +++ b/src/gui/styles/qwindowsxpstyle.cpp @@ -2841,8 +2841,8 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo State bflags = toolbutton->state & ~State_Sunken; State mflags = bflags; - - if (bflags & State_AutoRaise) { + bool autoRaise = flags & State_AutoRaise; + if (autoRaise) { if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) { bflags &= ~State_Raised; } @@ -2861,8 +2861,8 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo QStyleOption tool(0); tool.palette = toolbutton->palette; if (toolbutton->subControls & SC_ToolButton) { - if (flags & (State_Sunken | State_On | State_Raised) || !(flags & State_AutoRaise)) { - if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup) { + if (flags & (State_Sunken | State_On | State_Raised) || !autoRaise) { + if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup && autoRaise) { XPThemeData theme(widget, p, QLatin1String("TOOLBAR")); theme.partId = TP_SPLITBUTTON; theme.rect = button; @@ -2881,13 +2881,12 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo theme.stateId = stateId; d->drawBackground(theme); } else { - tool.rect = button; + tool.rect = option->rect; tool.state = bflags; - if (widget && !qobject_cast(widget->parentWidget()) - && !(bflags & State_AutoRaise)) - proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, widget); - else + if (autoRaise) // for tool bars proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget); + else + proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, widget); } } } @@ -2904,13 +2903,40 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo QStyleOptionToolButton label = *toolbutton; label.state = bflags; int fw = 2; + if (!autoRaise) + label.state &= ~State_Sunken; label.rect = button.adjusted(fw, fw, -fw, -fw); proxy()->drawControl(CE_ToolButtonLabel, &label, p, widget); if (toolbutton->subControls & SC_ToolButtonMenu) { tool.rect = menuarea; tool.state = mflags; - proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, p, widget); + if (autoRaise) { + proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, p, widget); + } else { + tool.state = mflags; + menuarea.adjust(-2, 0, 0, 0); + // Draw menu button + if ((bflags & State_Sunken) != (mflags & State_Sunken)){ + p->save(); + p->setClipRect(menuarea); + tool.rect = option->rect; + proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, 0); + p->restore(); + } + // Draw arrow + p->save(); + p->setPen(option->palette.dark()); + p->drawLine(menuarea.left(), menuarea.top() + 3, + menuarea.left(), menuarea.bottom() - 3); + p->setPen(option->palette.light()); + p->drawLine(menuarea.left() - 1, menuarea.top() + 3, + menuarea.left() - 1, menuarea.bottom() - 3); + + tool.rect = menuarea.adjusted(2, 3, -2, -1); + proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, p, widget); + p->restore(); + } } else if (toolbutton->features & QStyleOptionToolButton::HasMenu) { int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton, widget); QRect ir = toolbutton->rect; -- cgit v0.12 From 5eb2f63acda335aaf06e302ee4564259bc60222a Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Wed, 7 Oct 2009 18:29:46 +0200 Subject: Fix a combobox autotest on Vista The subcontrol rect offset was correctly reporting not to work on Vista style. The problem was that we were getting the size of the arrow by subtracting the xoffset. But this would mean that the Reviewed-by: ogoffart --- src/gui/styles/qwindowsvistastyle.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/styles/qwindowsvistastyle.cpp b/src/gui/styles/qwindowsvistastyle.cpp index 6cb8b40..974bce1 100644 --- a/src/gui/styles/qwindowsvistastyle.cpp +++ b/src/gui/styles/qwindowsvistastyle.cpp @@ -2217,14 +2217,15 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt int xpos = x; int margin = cb->frame ? 3 : 0; int bmarg = cb->frame ? 2 : 0; - xpos += wi - bmarg - 16; + int arrowButtonWidth = bmarg + 16; + xpos += wi - arrowButtonWidth; switch (subControl) { case SC_ComboBoxFrame: rect = cb->rect; break; case SC_ComboBoxArrow: - rect.setRect(xpos, y , wi - xpos, he); + rect.setRect(xpos, y , arrowButtonWidth, he); break; case SC_ComboBoxEditField: rect.setRect(x + margin, y + margin, wi - 2 * margin - 16, he - 2 * margin); -- cgit v0.12 From b1f9882fa52745c922eb0109daa011908214dcf7 Mon Sep 17 00:00:00 2001 From: Dean Dettman Date: Thu, 29 Oct 2009 11:29:08 +0100 Subject: Ensure that button returns 0 for mouse move events This was a platform regression for the cocoa platform Reviewed-by: Prasanth --- src/gui/kernel/qcocoaview_mac.mm | 7 ++- tests/auto/qmouseevent/tst_qmouseevent.cpp | 75 ++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 4 deletions(-) diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index ecc6bc9..a16d1f8 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -745,7 +745,7 @@ extern "C" { { qMacDnDParams()->view = self; qMacDnDParams()->theEvent = theEvent; - bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::LeftButton); + bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton); if (!mouseOK) [super mouseDragged:theEvent]; @@ -755,7 +755,7 @@ extern "C" { { qMacDnDParams()->view = self; qMacDnDParams()->theEvent = theEvent; - bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::RightButton); + bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton); if (!mouseOK) [super rightMouseDragged:theEvent]; @@ -765,8 +765,7 @@ extern "C" { { qMacDnDParams()->view = self; qMacDnDParams()->theEvent = theEvent; - Qt::MouseButton mouseButton = cocoaButton2QtButton([theEvent buttonNumber]); - bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, mouseButton); + bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton); if (!mouseOK) [super otherMouseDragged:theEvent]; diff --git a/tests/auto/qmouseevent/tst_qmouseevent.cpp b/tests/auto/qmouseevent/tst_qmouseevent.cpp index b961851..d700181 100644 --- a/tests/auto/qmouseevent/tst_qmouseevent.cpp +++ b/tests/auto/qmouseevent/tst_qmouseevent.cpp @@ -62,6 +62,7 @@ public: } bool mousePressEventRecieved; bool mouseReleaseEventRecieved; + bool mouseMoveEventRecieved; #ifdef QT3_SUPPORT int mousePressStateBefore; int mousePressStateAfter; @@ -76,6 +77,13 @@ public: int mouseReleaseButton; int mouseReleaseButtons; int mouseReleaseModifiers; +#ifdef QT3_SUPPORT + int mouseMoveStateBefore; + int mouseMoveStateAfter; +#endif + int mouseMoveButton; + int mouseMoveButtons; + int mouseMoveModifiers; protected: void mousePressEvent(QMouseEvent *e) { @@ -103,6 +111,19 @@ protected: mouseReleaseEventRecieved = TRUE; e->accept(); } + void mouseMoveEvent(QMouseEvent *e) + { + QWidget::mouseMoveEvent(e); +#ifdef QT3_SUPPORT + mouseMoveStateBefore = e->state(); + mouseMoveStateAfter = e->stateAfter(); +#endif + mouseMoveButton = e->button(); + mouseMoveButtons = e->buttons(); + mouseMoveModifiers = e->modifiers(); + mouseMoveEventRecieved = TRUE; + e->accept(); + } }; class tst_QMouseEvent : public QObject @@ -124,6 +145,8 @@ private slots: void checkMousePressEvent(); void checkMouseReleaseEvent_data(); void checkMouseReleaseEvent(); + void checkMouseMoveEvent_data(); + void checkMouseMoveEvent(); void qt3supportConstructors(); @@ -157,11 +180,14 @@ void tst_QMouseEvent::init() { testMouseWidget->mousePressEventRecieved = FALSE; testMouseWidget->mouseReleaseEventRecieved = FALSE; + testMouseWidget->mouseMoveEventRecieved = FALSE; #ifdef QT3_SUPPORT testMouseWidget->mousePressStateBefore = 0; testMouseWidget->mousePressStateAfter = 0; testMouseWidget->mouseReleaseStateBefore = 0; testMouseWidget->mouseReleaseStateAfter = 0; + testMouseWidget->mouseMoveStateBefore = 0; + testMouseWidget->mouseMoveStateAfter = 0; #endif testMouseWidget->mousePressButton = 0; testMouseWidget->mousePressButtons = 0; @@ -169,6 +195,9 @@ void tst_QMouseEvent::init() testMouseWidget->mouseReleaseButton = 0; testMouseWidget->mouseReleaseButtons = 0; testMouseWidget->mouseReleaseModifiers = 0; + testMouseWidget->mouseMoveButton = 0; + testMouseWidget->mouseMoveButtons = 0; + testMouseWidget->mouseMoveModifiers = 0; } void tst_QMouseEvent::cleanup() @@ -265,6 +294,52 @@ void tst_QMouseEvent::checkMouseReleaseEvent() #endif } +void tst_QMouseEvent::checkMouseMoveEvent_data() +{ + QTest::addColumn("buttonMoved"); + QTest::addColumn("keyPressed"); + + QTest::newRow("leftButton-nokey") << int(Qt::LeftButton) << int(Qt::NoButton); + QTest::newRow("leftButton-shiftkey") << int(Qt::LeftButton) << int(Qt::ShiftModifier); + QTest::newRow("leftButton-controlkey") << int(Qt::LeftButton) << int(Qt::ControlModifier); + QTest::newRow("leftButton-altkey") << int(Qt::LeftButton) << int(Qt::AltModifier); + QTest::newRow("leftButton-metakey") << int(Qt::LeftButton) << int(Qt::MetaModifier); + QTest::newRow("rightButton-nokey") << int(Qt::RightButton) << int(Qt::NoButton); + QTest::newRow("rightButton-shiftkey") << int(Qt::RightButton) << int(Qt::ShiftModifier); + QTest::newRow("rightButton-controlkey") << int(Qt::RightButton) << int(Qt::ControlModifier); + QTest::newRow("rightButton-altkey") << int(Qt::RightButton) << int(Qt::AltModifier); + QTest::newRow("rightButton-metakey") << int(Qt::RightButton) << int(Qt::MetaModifier); + QTest::newRow("midButton-nokey") << int(Qt::MidButton) << int(Qt::NoButton); + QTest::newRow("midButton-shiftkey") << int(Qt::MidButton) << int(Qt::ShiftModifier); + QTest::newRow("midButton-controlkey") << int(Qt::MidButton) << int(Qt::ControlModifier); + QTest::newRow("midButton-altkey") << int(Qt::MidButton) << int(Qt::AltModifier); + QTest::newRow("midButton-metakey") << int(Qt::MidButton) << int(Qt::MetaModifier); +} + +void tst_QMouseEvent::checkMouseMoveEvent() +{ + QFETCH(int,buttonMoved); + QFETCH(int,keyPressed); + int button = (int)Qt::NoButton; + int buttons = buttonMoved; + int modifiers = keyPressed; + + QTest::mousePress(testMouseWidget, Qt::MouseButton(buttonMoved), Qt::KeyboardModifiers(keyPressed)); + QTest::mouseMove(testMouseWidget, QPoint(10,10)); + QVERIFY(testMouseWidget->mouseMoveEventRecieved); + QCOMPARE(testMouseWidget->mouseMoveButton, button); + QCOMPARE(testMouseWidget->mouseMoveButtons, buttons); + QCOMPARE(testMouseWidget->mouseMoveModifiers, modifiers); +#ifdef QT3_SUPPORT + int stateAfter = buttons|modifiers; + int stateBefore = stateAfter|button; + + QCOMPARE(testMouseWidget->mouseMoveStateBefore, stateBefore); + QCOMPARE(testMouseWidget->mouseMoveStateAfter, stateAfter); +#endif + QTest::mouseRelease(testMouseWidget, Qt::MouseButton(buttonMoved), Qt::KeyboardModifiers(keyPressed)); +} + void tst_QMouseEvent::qt3supportConstructors() { #if !defined(QT3_SUPPORT) -- cgit v0.12 From 9551b8c349ce4e15a57c24a2408ee1b73c2b7510 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Thu, 29 Oct 2009 13:46:45 +0100 Subject: Tabs with corner widgets are drawn incorrectly in document mode on Mac. While drawing the tabbar frame, mac style needs the QTabBar pointer to calculate the correct size. Since the QTabWidget also uses the PE_FrameTabBarBase to draw background of the corner widgets, the mac style has to use position passed with the style option. This only works with horizontal tabs. Reviewed-by: Jens Bache-Wiig --- src/gui/styles/qmacstyle_mac.mm | 10 +++++----- src/gui/widgets/qtabwidget.cpp | 4 ++-- tools/assistant/tools/assistant/centralwidget.cpp | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm index 4dcb469..38c3feb 100644 --- a/src/gui/styles/qmacstyle_mac.mm +++ b/src/gui/styles/qmacstyle_mac.mm @@ -342,12 +342,12 @@ void drawTabBase(QPainter *p, const QStyleOptionTabBarBaseV2 *tbb, const QWidget borderHighlightTop = QColor(207, 207, 207); } p->setPen(borderHighlightTop); - p->drawLine(0, 0, width, 0); + p->drawLine(tabRect.x(), 0, width, 0); p->setPen(borderTop); - p->drawLine(0, 1, width, 1); + p->drawLine(tabRect.x(), 1, width, 1); // center block - QRect centralRect(0, 2, width, height - 2); + QRect centralRect(tabRect.x(), 2, width, height - 2); if (active) { QColor mainColor = QColor(120, 120, 120); p->fillRect(centralRect, mainColor); @@ -370,9 +370,9 @@ void drawTabBase(QPainter *p, const QStyleOptionTabBarBaseV2 *tbb, const QWidget borderBottom = QColor(127, 127, 127); } p->setPen(borderHighlightBottom); - p->drawLine(0, height - 2, width, height - 2); + p->drawLine(tabRect.x(), height - 2, width, height - 2); p->setPen(borderBottom); - p->drawLine(0, height - 1, width, height - 1); + p->drawLine(tabRect.x(), height - 1, width, height - 1); } /* diff --git a/src/gui/widgets/qtabwidget.cpp b/src/gui/widgets/qtabwidget.cpp index 9aeb033..0c89a72 100644 --- a/src/gui/widgets/qtabwidget.cpp +++ b/src/gui/widgets/qtabwidget.cpp @@ -1167,8 +1167,8 @@ void QTabWidget::tabRemoved(int index) void QTabWidget::paintEvent(QPaintEvent *) { Q_D(QTabWidget); - QStylePainter p(this); if (documentMode()) { + QStylePainter p(this, tabBar()); if (QWidget *w = cornerWidget(Qt::TopLeftCorner)) { QStyleOptionTabBarBaseV2 opt; QTabBarPrivate::initStyleBaseOption(&opt, tabBar(), w->size()); @@ -1185,7 +1185,7 @@ void QTabWidget::paintEvent(QPaintEvent *) } return; } - + QStylePainter p(this); QStyleOptionTabWidgetFrame opt; initStyleOption(&opt); opt.rect = d->panelRect; diff --git a/tools/assistant/tools/assistant/centralwidget.cpp b/tools/assistant/tools/assistant/centralwidget.cpp index 04739d4..2722b2f 100644 --- a/tools/assistant/tools/assistant/centralwidget.cpp +++ b/tools/assistant/tools/assistant/centralwidget.cpp @@ -230,6 +230,7 @@ CentralWidget::CentralWidget(QHelpEngine *engine, MainWindow *parent) #endif tabWidget = new QTabWidget(this); + tabWidget->setDocumentMode(true); connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(currentPageChanged(int))); -- cgit v0.12 From 8c4edbd04f350294462fd689748de2dd7cc84d47 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Thu, 8 Oct 2009 21:10:01 +0200 Subject: Fix tab widget painting in QGtkStyle with reverse This also adds QStyleOptionTabWidgetFrameV2 so that we do not have to do ugly hacks in the style to obtain it. Task-number: QTBUG-5187 Reviewed-by: ogoffart --- src/gui/styles/qgtkstyle.cpp | 43 ++++++-------- src/gui/styles/qstyleoption.cpp | 113 ++++++++++++++++++++++++++++++++++++ src/gui/styles/qstyleoption.h | 20 +++++++ src/gui/styles/qstylesheetstyle.cpp | 2 +- src/gui/styles/qwindowsxpstyle.cpp | 2 +- src/gui/widgets/qtabwidget.cpp | 14 ++++- 6 files changed, 166 insertions(+), 28 deletions(-) diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index d315c98..a7c291b 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -1004,32 +1004,27 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, gtkPainter.setAlphaSupport(false); GtkShadowType shadow = GTK_SHADOW_OUT; GtkStateType state = GTK_STATE_NORMAL; // Only state supported by gtknotebook - if (const QTabWidget *tabwidget = qobject_cast(widget)) { - // We should introduce QStyleOptionTabWidgetFrameV2 to obtain this information - // No gap if we do not show the actual tabs - QTabBar *tabBar = tabwidget->findChild(); - if (tabwidget->count() > 0 && tabBar->isVisible()) { - QRect tabRect = tabBar->tabRect(tabBar->currentIndex()); - int begin = 0, size = 0; - GtkPositionType frameType = GTK_POS_TOP; - QTabBar::Shape shape = frame->shape; - if (shape == QTabBar::RoundedNorth || shape == QTabBar::RoundedSouth) { - begin = option->direction == Qt::LeftToRight ? - frame->leftCornerWidgetSize.width() + tabRect.left() : - frame->rect.width() - frame->tabBarSize.width() + tabRect.left() - - frame->rightCornerWidgetSize.width(); - size = tabRect.width(); - frameType = (shape == QTabBar::RoundedNorth) ? GTK_POS_TOP : GTK_POS_BOTTOM; - } else { - begin = frame->leftCornerWidgetSize.height() + tabRect.top(); - size = tabRect.height(); - frameType = (shape == QTabBar::RoundedWest) ? GTK_POS_LEFT : GTK_POS_RIGHT; - } - gtkPainter.paintBoxGap(gtkNotebook, "notebook", option->rect, state, shadow, frameType, - begin, size, style); - break; // done + bool reverse = (option->direction == Qt::RightToLeft); + QGtk::gtk_widget_set_direction(gtkNotebook, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR); + if (const QStyleOptionTabWidgetFrameV2 *tabframe = qstyleoption_cast(option)) { + GtkPositionType frameType = GTK_POS_TOP; + QTabBar::Shape shape = frame->shape; + int gapStart = 0; + int gapSize = 0; + if (shape == QTabBar::RoundedNorth || shape == QTabBar::RoundedSouth) { + frameType = (shape == QTabBar::RoundedNorth) ? GTK_POS_TOP : GTK_POS_BOTTOM; + gapStart = tabframe->selectedTabRect.left(); + gapSize = tabframe->selectedTabRect.width(); + } else { + frameType = (shape == QTabBar::RoundedWest) ? GTK_POS_LEFT : GTK_POS_RIGHT; + gapStart = tabframe->selectedTabRect.y(); + gapSize = tabframe->selectedTabRect.height(); } + gtkPainter.paintBoxGap(gtkNotebook, "notebook", option->rect, state, shadow, frameType, + gapStart, gapSize, style); + break; // done } + // Note this is only the fallback option gtkPainter.paintBox(gtkNotebook, "notebook", option->rect, state, shadow, style); } diff --git a/src/gui/styles/qstyleoption.cpp b/src/gui/styles/qstyleoption.cpp index 061afcc..f5a2b94 100644 --- a/src/gui/styles/qstyleoption.cpp +++ b/src/gui/styles/qstyleoption.cpp @@ -4654,6 +4654,119 @@ QStyleOptionTabWidgetFrame::QStyleOptionTabWidgetFrame(int version) The default value is QSize(-1, -1), i.e. an invalid size. */ + + +/*! + + \class QStyleOptionTabWidgetFrameV2 + \brief The QStyleOptionTabWidgetFrameV2 class is used to describe the + parameters for drawing the frame around a tab widget. + + QStyleOptionTabWidgetFrameV2 contains all the information that + QStyle functions need to draw the frame around QTabWidget. + + For performance reasons, the access to the member variables is + direct (i.e., using the \c . or \c -> operator). This low-level feel + makes the structures straightforward to use and emphasizes that + these are simply parameters used by the style functions. + + For an example demonstrating how style options can be used, see + the \l {widgets/styles}{Styles} example. + + \sa QStyleOption, QTabWidget +*/ + + +/*! + \variable QStyleOptionTabWidgetFrameV2::tabBarRect + \brief the rectangle containing all the tabs + + The default value is a null rectangle, i.e. a rectangle with both + the width and the height set to 0. +*/ + +/*! + \variable QStyleOptionTabWidgetFrameV2::selectedTabRect + \brief the rectangle containing the selected tab + + This rectangle is contained within the tabBarRect. The default + value is a null rectangle, i.e. a rectangle with both the width + and the height set to 0. +*/ + + +/*! + Constructs a QStyleOptionTabWidgetFrameV2, initializing the members + variables to their default values. +*/ + +QStyleOptionTabWidgetFrameV2::QStyleOptionTabWidgetFrameV2() + : QStyleOptionTabWidgetFrame(Version) +{ +} + + +/*! \internal */ +QStyleOptionTabWidgetFrameV2::QStyleOptionTabWidgetFrameV2(int version) + : QStyleOptionTabWidgetFrame(version) +{ +} + + +/*! + Constructs a QStyleOptionTabWidgetFrameV2 copy of the \a other style option + which can be either of the QStyleOptionTabWidgetFrameV2 or + QStyleOptionTabWidgetFrame types. + + If the \a other style option's version is 1, the new style option's \l + selectedTabRect and tabBarRect will contain null rects + + \sa version +*/ +QStyleOptionTabWidgetFrameV2::QStyleOptionTabWidgetFrameV2(const QStyleOptionTabWidgetFrame &other) +{ + QStyleOptionTabWidgetFrameV2::operator=(other); + +} + + +/*! + Assigns the \a other style option to this style option. The \a + other style option can be either of the QStyleOptionFrameV2 or + QStyleOptionFrame types. + + If the \a{other} style option's version is 1, this style option's + \l FrameFeature value is set to \l QStyleOptionFrameV2::None. If + its version is 2, its \l FrameFeature value is simply copied to + this style option. +*/ +QStyleOptionTabWidgetFrameV2 &QStyleOptionTabWidgetFrameV2::operator=(const QStyleOptionTabWidgetFrame &other) +{ + QStyleOptionTabWidgetFrame::operator=(other); + if (const QStyleOptionTabWidgetFrameV2 *f2 = qstyleoption_cast(&other)) { + selectedTabRect = f2->selectedTabRect; + tabBarRect = f2->tabBarRect; + } + return *this; +} + + +/*! + \enum QStyleOptionTabWidgetFrameV2::StyleOptionVersion + + This enum is used to hold information about the version of the style option, and + is defined for each QStyleOption subclass. + + \value Version 2 + + The version is used by QStyleOption subclasses to implement + extensions without breaking compatibility. If you use + qstyleoption_cast(), you normally do not need to check it. + + \sa StyleOptionType +*/ + + #endif // QT_NO_TABWIDGET #ifndef QT_NO_TABBAR diff --git a/src/gui/styles/qstyleoption.h b/src/gui/styles/qstyleoption.h index bf8b479..abd52bf 100644 --- a/src/gui/styles/qstyleoption.h +++ b/src/gui/styles/qstyleoption.h @@ -192,8 +192,28 @@ public: protected: QStyleOptionTabWidgetFrame(int version); }; + +class Q_GUI_EXPORT QStyleOptionTabWidgetFrameV2 : public QStyleOptionTabWidgetFrame +{ +public: + enum StyleOptionVersion { Version = 2 }; + + QRect tabBarRect; + QRect selectedTabRect; + + QStyleOptionTabWidgetFrameV2(); + QStyleOptionTabWidgetFrameV2(const QStyleOptionTabWidgetFrameV2 &other) : + QStyleOptionTabWidgetFrame(Version) { *this = other; } + QStyleOptionTabWidgetFrameV2(const QStyleOptionTabWidgetFrame &other); + QStyleOptionTabWidgetFrameV2 &operator=(const QStyleOptionTabWidgetFrame &other); + +protected: + QStyleOptionTabWidgetFrameV2(int version); +}; + #endif + #ifndef QT_NO_TABBAR class Q_GUI_EXPORT QStyleOptionTabBarBase : public QStyleOption { diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index 2d90aa1..ae1d33a 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -4325,7 +4325,7 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op QRenderRule subRule = renderRule(w, opt, PseudoElement_TabWidgetPane); if (subRule.hasNativeBorder()) { subRule.drawBackground(p, opt->rect); - QStyleOptionTabWidgetFrame frmCopy(*frm); + QStyleOptionTabWidgetFrameV2 frmCopy(*frm); subRule.configurePalette(&frmCopy.palette, QPalette::WindowText, QPalette::Window); baseStyle()->drawPrimitive(pe, &frmCopy, p, w); } else { diff --git a/src/gui/styles/qwindowsxpstyle.cpp b/src/gui/styles/qwindowsxpstyle.cpp index b5dc647..9fd9ce9 100644 --- a/src/gui/styles/qwindowsxpstyle.cpp +++ b/src/gui/styles/qwindowsxpstyle.cpp @@ -1582,7 +1582,7 @@ case PE_Frame: // This should work, but currently there's an error in the ::drawBackgroundDirectly() // code, when using the HDC directly.. if (useGradient) { - QStyleOptionTabWidgetFrame frameOpt = *tab; + QStyleOptionTabWidgetFrameV2 frameOpt = *tab; frameOpt.rect = widget->rect(); QRect contentsRect = subElementRect(SE_TabWidgetTabContents, &frameOpt, widget); QRegion reg = option->rect; diff --git a/src/gui/widgets/qtabwidget.cpp b/src/gui/widgets/qtabwidget.cpp index 0c89a72..d22bd54 100644 --- a/src/gui/widgets/qtabwidget.cpp +++ b/src/gui/widgets/qtabwidget.cpp @@ -313,7 +313,16 @@ void QTabWidget::initStyleOption(QStyleOptionTabWidgetFrame *option) const : QTabBar::TriangularEast; break; } + option->tabBarSize = t; + + if (QStyleOptionTabWidgetFrameV2 *tabframe = qstyleoption_cast(option)) { + QRect tbRect = tabBar()->geometry(); + QRect selectedTabRect = tabBar()->tabRect(tabBar()->currentIndex()); + tabframe->tabBarRect = tbRect; + selectedTabRect.moveTopLeft(selectedTabRect.topLeft() + tbRect.topLeft()); + tabframe->selectedTabRect = selectedTabRect; + } } /*! @@ -756,7 +765,7 @@ void QTabWidget::setUpLayout(bool onlyCheck) if (onlyCheck && !d->dirty) return; // nothing to do - QStyleOptionTabWidgetFrame option; + QStyleOptionTabWidgetFrameV2 option; initStyleOption(&option); // this must be done immediately, because QWidgetItem relies on it (even if !isVisible()) @@ -1186,7 +1195,8 @@ void QTabWidget::paintEvent(QPaintEvent *) return; } QStylePainter p(this); - QStyleOptionTabWidgetFrame opt; + + QStyleOptionTabWidgetFrameV2 opt; initStyleOption(&opt); opt.rect = d->panelRect; p.drawPrimitive(QStyle::PE_FrameTabWidget, opt); -- cgit v0.12 From e1f691d84dad17c5ee47c97c31ae743093ad8bc9 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 8 Oct 2009 09:15:20 +0200 Subject: Ensure that qmake doesn't lose the error code when processing subdirs When processing a project in a subdirs template failed for whatever reason then qmake would lose the result of that and would return an error code of 0 if the subdirs project file itself was processed fine. So now it ensures that any errors arising from processing a project referenced in a subdirs project file are not lost so that the error code returned from qmake will indicate an error actually occured. Task-number: QTBUG-4065 Reviewed-by: mariusSO Original-commit: c15b370c9db16fdbfd9e7bec89ee9bf8c1110827 --- qmake/generators/metamakefile.cpp | 17 ++++++++++++----- qmake/generators/metamakefile.h | 2 +- qmake/main.cpp | 6 +++++- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp index 5915fcf..819cdaf 100644 --- a/qmake/generators/metamakefile.cpp +++ b/qmake/generators/metamakefile.cpp @@ -291,6 +291,7 @@ SubdirsMetaMakefileGenerator::init() if(init_flag) return false; init_flag = true; + bool hasError = false; if(Option::recursive) { QString old_output_dir = Option::output_dir; @@ -336,14 +337,18 @@ SubdirsMetaMakefileGenerator::init() } qmake_setpwd(sub->input_dir); Option::output_dir = sub->output_dir; - sub_proj->read(subdir.fileName()); + bool tmpError = !sub_proj->read(subdir.fileName()); if(!sub_proj->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { fprintf(stderr, "Project file(%s) not recursed because all requirements not met:\n\t%s\n", subdir.fileName().toLatin1().constData(), sub_proj->values("QMAKE_FAILED_REQUIREMENTS").join(" ").toLatin1().constData()); delete sub; delete sub_proj; + Option::output_dir = old_output_dir; + qmake_setpwd(oldpwd); continue; + } else { + hasError |= tmpError; } sub->makefile = MetaMakefileGenerator::createMetaGenerator(sub_proj, sub_name); if(0 && sub->makefile->type() == SUBDIRSMETATYPE) { @@ -351,7 +356,7 @@ SubdirsMetaMakefileGenerator::init() } else { const QString output_name = Option::output.fileName(); Option::output.setFileName(sub->output_file); - sub->makefile->write(sub->output_dir); + hasError |= !sub->makefile->write(sub->output_dir); delete sub; qmakeClearCaches(); sub = 0; @@ -376,7 +381,7 @@ SubdirsMetaMakefileGenerator::init() self->makefile->init(); subs.append(self); - return true; + return !hasError; } bool @@ -482,7 +487,7 @@ MetaMakefileGenerator::createMakefileGenerator(QMakeProject *proj, bool noIO) } MetaMakefileGenerator * -MetaMakefileGenerator::createMetaGenerator(QMakeProject *proj, const QString &name, bool op) +MetaMakefileGenerator::createMetaGenerator(QMakeProject *proj, const QString &name, bool op, bool *success) { MetaMakefileGenerator *ret = 0; if ((Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || @@ -492,7 +497,9 @@ MetaMakefileGenerator::createMetaGenerator(QMakeProject *proj, const QString &na } if (!ret) ret = new BuildsMetaMakefileGenerator(proj, name, op); - ret->init(); + bool res = ret->init(); + if (success) + *success = res; return ret; } diff --git a/qmake/generators/metamakefile.h b/qmake/generators/metamakefile.h index e69304a..f74f4a2 100644 --- a/qmake/generators/metamakefile.h +++ b/qmake/generators/metamakefile.h @@ -62,7 +62,7 @@ public: virtual ~MetaMakefileGenerator(); - static MetaMakefileGenerator *createMetaGenerator(QMakeProject *proj, const QString &name, bool op=true); + static MetaMakefileGenerator *createMetaGenerator(QMakeProject *proj, const QString &name, bool op=true, bool *success = 0); static MakefileGenerator *createMakefileGenerator(QMakeProject *proj, bool noIO = false); inline QMakeProject *projectFile() const { return project; } diff --git a/qmake/main.cpp b/qmake/main.cpp index 73fdda9..a0346c5 100644 --- a/qmake/main.cpp +++ b/qmake/main.cpp @@ -168,7 +168,11 @@ int runQMake(int argc, char **argv) continue; } - MetaMakefileGenerator *mkfile = MetaMakefileGenerator::createMetaGenerator(&project, QString(), false); + bool success = true; + MetaMakefileGenerator *mkfile = MetaMakefileGenerator::createMetaGenerator(&project, QString(), false, &success); + if (!success) + exit_val = 3; + if(mkfile && !mkfile->write(oldpwd)) { if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) fprintf(stderr, "Unable to generate project file.\n"); -- cgit v0.12 From e4954731369d9b339a79ec9fe737d70ef6dc4755 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 22 Oct 2009 15:38:25 +0200 Subject: In Vista style, renaming Animation, Transition and Pulse There is a name clash, so we prefixed them with QWindowsVista Reviewed-by: Benjamin Poulain --- src/gui/styles/qwindowsvistastyle.cpp | 50 +++++++++++++++++------------------ src/gui/styles/qwindowsvistastyle_p.h | 24 ++++++++--------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/gui/styles/qwindowsvistastyle.cpp b/src/gui/styles/qwindowsvistastyle.cpp index 6cb8b40..aafd087 100644 --- a/src/gui/styles/qwindowsvistastyle.cpp +++ b/src/gui/styles/qwindowsvistastyle.cpp @@ -159,7 +159,7 @@ QWindowsVistaStyle::QWindowsVistaStyle() } //convert Qt state flags to uxtheme button states -int buttonStateId(int flags, int partId) +static int buttonStateId(int flags, int partId) { int stateId = 0; if (partId == BP_RADIOBUTTON || partId == BP_CHECKBOX) { @@ -190,7 +190,7 @@ int buttonStateId(int flags, int partId) return stateId; } -void Animation::paint(QPainter *painter, const QStyleOption *option) +void QWindowsVistaAnimation::paint(QPainter *painter, const QStyleOption *option) { Q_UNUSED(option); Q_UNUSED(painter); @@ -205,7 +205,7 @@ void Animation::paint(QPainter *painter, const QStyleOption *option) + ((1-alpha)*_secondaryImage) */ -void Animation::drawBlendedImage(QPainter *painter, QRect rect, float alpha) { +void QWindowsVistaAnimation::drawBlendedImage(QPainter *painter, QRect rect, float alpha) { if (_secondaryImage.isNull() || _primaryImage.isNull()) return; @@ -251,7 +251,7 @@ void Animation::drawBlendedImage(QPainter *painter, QRect rect, float alpha) { initial and final state of the transition, depending on the time difference between _startTime and current time. */ -void Transition::paint(QPainter *painter, const QStyleOption *option) +void QWindowsVistaTransition::paint(QPainter *painter, const QStyleOption *option) { float alpha = 1.0; if (_duration > 0) { @@ -278,7 +278,7 @@ void Transition::paint(QPainter *painter, const QStyleOption *option) secondary pulse images depending on the time difference between _startTime and current time. */ -void Pulse::paint(QPainter *painter, const QStyleOption *option) +void QWindowsVistaPulse::paint(QPainter *painter, const QStyleOption *option) { float alpha = 1.0; if (_duration > 0) { @@ -393,8 +393,8 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt startImage.fill(0); QPainter startPainter(&startImage); - Animation *anim = d->widgetAnimation(widget); - Transition *t = new Transition; + QWindowsVistaAnimation *anim = d->widgetAnimation(widget); + QWindowsVistaTransition *t = new QWindowsVistaTransition; t->setWidget(w); // If we have a running animation on the widget already, we will use that to paint the initial @@ -531,7 +531,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt case PE_IndicatorCheckBox: case PE_IndicatorRadioButton: { - if (Animation *a = d->widgetAnimation(widget)) { + if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) { a->paint(painter, option); } else { QWindowsXPStyle::drawPrimitive(element, option, painter, widget); @@ -644,7 +644,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt break; case PE_FrameLineEdit: - if (Animation *anim = d->widgetAnimation(widget)) { + if (QWindowsVistaAnimation *anim = d->widgetAnimation(widget)) { anim->paint(painter, option); } else { QPainter *p = painter; @@ -929,13 +929,13 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption if (doTransition) { QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); - Animation *anim = d->widgetAnimation(widget); + QWindowsVistaAnimation *anim = d->widgetAnimation(widget); QStyleOptionButton opt = *button; opt.state = (QStyle::State)oldState; startImage.fill(0); - Transition *t = new Transition; + QWindowsVistaTransition *t = new QWindowsVistaTransition; t->setWidget(w); QPainter startPainter(&startImage); @@ -972,7 +972,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption if (const QStyleOptionButton *btn = qstyleoption_cast(option)) { - if (Animation *anim = d->widgetAnimation(widget)) { + if (QWindowsVistaAnimation *anim = d->widgetAnimation(widget)) { anim->paint(painter, option); } else { name = QLatin1String("BUTTON"); @@ -999,14 +999,14 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption !(state & (State_Sunken | State_On)) && !(state & State_MouseOver) && (state & State_Enabled) && (state & State_Active)) { - Animation *anim = d->widgetAnimation(widget); + QWindowsVistaAnimation *anim = d->widgetAnimation(widget); if (!anim && widget) { QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); startImage.fill(0); QImage alternateImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); alternateImage.fill(0); - Pulse *pulse = new Pulse; + QWindowsVistaPulse *pulse = new QWindowsVistaPulse; pulse->setWidget(const_cast(widget)); QPainter startPainter(&startImage); @@ -1079,7 +1079,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption if (const QProgressBar *progressbar = qobject_cast(widget)) { if (((progressbar->value() > 0 && d->transitionsEnabled()) || isIndeterminate)) { if (!d->widgetAnimation(progressbar) && progressbar->value() < progressbar->maximum()) { - Animation *a = new Animation; + QWindowsVistaAnimation *a = new QWindowsVistaAnimation; a->setWidget(const_cast(widget)); a->setStartTime(QTime::currentTime()); d->startAnimation(a); @@ -1095,7 +1095,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption QTime current = QTime::currentTime(); if (isIndeterminate) { - if (Animation *a = d->widgetAnimation(widget)) { + if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) { int glowSize = 120; int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width()); int animOffset = a->startTime().msecsTo(current) / 4; @@ -1165,7 +1165,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption } d->drawBackground(theme); - if (Animation *a = d->widgetAnimation(widget)) { + if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) { int glowSize = 140; int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width()); int animOffset = a->startTime().msecsTo(current) / 4; @@ -1603,8 +1603,8 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle if (doTransition) { QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); - Animation *anim = d->widgetAnimation(widget); - Transition *t = new Transition; + QWindowsVistaAnimation *anim = d->widgetAnimation(widget); + QWindowsVistaTransition *t = new QWindowsVistaTransition; t->setWidget(w); if (!anim) { if (const QStyleOptionComboBox *combo = qstyleoption_cast(option)) { @@ -1651,7 +1651,7 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle t->setDuration(500); } - if (Animation *anim = d->widgetAnimation(widget)) { + if (QWindowsVistaAnimation *anim = d->widgetAnimation(widget)) { anim->paint(painter, option); return; } @@ -2533,7 +2533,7 @@ void QWindowsVistaStylePrivate::timerEvent() !animations[i]->running() || !QWindowsVistaStylePrivate::useVista()) { - Animation *a = animations.takeAt(i); + QWindowsVistaAnimation *a = animations.takeAt(i); delete a; } } @@ -2546,14 +2546,14 @@ void QWindowsVistaStylePrivate::stopAnimation(const QWidget *w) { for (int i = animations.size() - 1 ; i >= 0 ; --i) { if (animations[i]->widget() == w) { - Animation *a = animations.takeAt(i); + QWindowsVistaAnimation *a = animations.takeAt(i); delete a; break; } } } -void QWindowsVistaStylePrivate::startAnimation(Animation *t) +void QWindowsVistaStylePrivate::startAnimation(QWindowsVistaAnimation *t) { Q_Q(QWindowsVistaStyle); stopAnimation(t->widget()); @@ -2575,11 +2575,11 @@ bool QWindowsVistaStylePrivate::transitionsEnabled() const } -Animation * QWindowsVistaStylePrivate::widgetAnimation(const QWidget *widget) const +QWindowsVistaAnimation * QWindowsVistaStylePrivate::widgetAnimation(const QWidget *widget) const { if (!widget) return 0; - foreach (Animation *a, animations) { + foreach (QWindowsVistaAnimation *a, animations) { if (a->widget() == widget) return a; } diff --git a/src/gui/styles/qwindowsvistastyle_p.h b/src/gui/styles/qwindowsvistastyle_p.h index e9bbb77..04823c1 100644 --- a/src/gui/styles/qwindowsvistastyle_p.h +++ b/src/gui/styles/qwindowsvistastyle_p.h @@ -136,11 +136,11 @@ QT_BEGIN_NAMESPACE #define TDLG_SECONDARYPANEL 8 #endif -class Animation +class QWindowsVistaAnimation { public : - Animation() : _running(true) { } - virtual ~Animation() { } + QWindowsVistaAnimation() : _running(true) { } + virtual ~QWindowsVistaAnimation() { } QWidget * widget() const { return _widget; } bool running() const { return _running; } const QTime &startTime() const { return _startTime; } @@ -161,11 +161,11 @@ protected: // Handles state transition animations -class Transition : public Animation +class QWindowsVistaTransition : public QWindowsVistaAnimation { public : - Transition() : Animation() {} - virtual ~Transition() { } + QWindowsVistaTransition() : QWindowsVistaAnimation() {} + virtual ~QWindowsVistaTransition() { } void setDuration(int duration) { _duration = duration; } void setStartImage(const QImage &image) { _primaryImage = image; } void setEndImage(const QImage &image) { _secondaryImage = image; } @@ -176,11 +176,11 @@ public : // Handles pulse animations (default buttons) -class Pulse: public Animation +class QWindowsVistaPulse: public QWindowsVistaAnimation { public : - Pulse() : Animation() {} - virtual ~Pulse() { } + QWindowsVistaPulse() : QWindowsVistaAnimation() {} + virtual ~QWindowsVistaPulse() { } void setDuration(int duration) { _duration = duration; } void setPrimaryImage(const QImage &image) { _primaryImage = image; } void setAlternateImage(const QImage &image) { _secondaryImage = image; } @@ -199,15 +199,15 @@ public: ~QWindowsVistaStylePrivate(); static bool resolveSymbols(); static inline bool useVista(); - void startAnimation(Animation *); + void startAnimation(QWindowsVistaAnimation *); void stopAnimation(const QWidget *); - Animation* widgetAnimation(const QWidget *) const; + QWindowsVistaAnimation* widgetAnimation(const QWidget *) const; void timerEvent(); bool transitionsEnabled() const; QWidget *treeViewHelper(); private: - QList animations; + QList animations; QBasicTimer animationTimer; QWidget *m_treeViewHelper; }; -- cgit v0.12 From 63b8a706c57ed292d82fc16a446daa543cf12a38 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 22 Oct 2009 15:21:29 +0200 Subject: stabilize QListView test --- tests/auto/qlistview/tst_qlistview.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/auto/qlistview/tst_qlistview.cpp b/tests/auto/qlistview/tst_qlistview.cpp index 6e211ae..3968529 100644 --- a/tests/auto/qlistview/tst_qlistview.cpp +++ b/tests/auto/qlistview/tst_qlistview.cpp @@ -1132,6 +1132,7 @@ void tst_QListView::selection() #endif v.show(); + QTest::qWaitForWindowShown(&v); QApplication::processEvents(); v.setSelection(selectionRect, QItemSelectionModel::ClearAndSelect); @@ -1184,6 +1185,7 @@ void tst_QListView::scrollTo() lv.setModel(&model); lv.setFixedSize(100, 200); lv.show(); + QTest::qWaitForWindowShown(&lv); //by default, the list view scrolls per item and has no wrapping QModelIndex index = model.index(6,0); @@ -1782,12 +1784,13 @@ void tst_QListView::task262152_setModelColumnNavigate() view.setModelColumn(1); view.show(); - QTest::qWait(100); + QTest::qWaitForWindowShown(&view); + QTest::qWait(10); QTest::keyClick(&view, Qt::Key_Down); - QTest::qWait(100); + QTest::qWait(10); QCOMPARE(view.currentIndex(), model.index(1,1)); QTest::keyClick(&view, Qt::Key_Down); - QTest::qWait(100); + QTest::qWait(10); QCOMPARE(view.currentIndex(), model.index(2,1)); } -- cgit v0.12 From 44aa15a08dd8e7e1ea428fd8868a8e531f5ba4d9 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 22 Oct 2009 16:04:34 +0200 Subject: Autotest fix for parallel animation group On macos (as on symbian), we need to leave some time for the application to become responsive. --- .../tst_qparallelanimationgroup.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp b/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp index 8578d36..8d937e9 100644 --- a/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp +++ b/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp @@ -56,8 +56,7 @@ public: virtual ~tst_QParallelAnimationGroup(); public Q_SLOTS: - void init(); - void cleanup(); + void initTestCase(); private slots: void construction(); @@ -86,13 +85,13 @@ tst_QParallelAnimationGroup::~tst_QParallelAnimationGroup() { } -void tst_QParallelAnimationGroup::init() +void tst_QParallelAnimationGroup::initTestCase() { qRegisterMetaType("QAbstractAnimation::State"); -} - -void tst_QParallelAnimationGroup::cleanup() -{ +#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAC) || defined(Q_WS_WINCE) + // give the Symbian and mac app start event queue time to clear + QTest::qWait(1000); +#endif } void tst_QParallelAnimationGroup::construction() @@ -486,10 +485,6 @@ void tst_QParallelAnimationGroup::updateChildrenWithRunningGroup() void tst_QParallelAnimationGroup::deleteChildrenWithRunningGroup() { -#if defined(Q_OS_SYMBIAN) - // give the Symbian app start event queue time to clear - QTest::qWait(1000); -#endif // test if children can be activated when their group is stopped QParallelAnimationGroup group; -- cgit v0.12 From 82caa7b3f97c6cda0ebceb477856442653a83699 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Thu, 22 Oct 2009 18:11:19 +0200 Subject: Warning -- Reviewed-by:TrustMe --- src/gui/graphicsview/qgraphicsproxywidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp index 64c51ad..e9173a9 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget.cpp +++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp @@ -397,7 +397,7 @@ QWidget *QGraphicsProxyWidgetPrivate::findFocusChild(QWidget *child, bool next) do { if (child->isEnabled() && child->isVisibleTo(widget) - && (child->focusPolicy() & focus_flag == focus_flag) + && ((child->focusPolicy() & focus_flag) == focus_flag) && !(child->d_func()->extra && child->d_func()->extra->focus_proxy)) { return child; } -- cgit v0.12 From a5f7f88932c6911fb65552d65d62efdcf496beec Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Thu, 22 Oct 2009 18:11:34 +0200 Subject: Fix crash in QGraphicsView BSP discovered in Amarok. Basically some items were not properly remove in the BSP which means that if you delete one of items, the BSP tree may contain dangling pointers. The problem was in removeItemHelper in QGraphicsScene were the child were removed after reparenting to 0 the topmost parent. The sceneBoundingRect for children was invalid which means that we were removing them in the wrong position inside the BSP. Reparenting to 0 means that the sceneBoundingRect will be the boundingRect but wasn't the case before (for the topmost parent). Reviewed-by:bnilsen --- src/gui/graphicsview/qgraphicsscene.cpp | 14 +++--- .../tst_qgraphicssceneindex.cpp | 58 ++++++++++++++++++++++ 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index a624b10..03c8a97 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -518,6 +518,14 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) item->d_func()->scene = 0; + //We need to remove all children first because they might use their parent + //attributes (e.g. sceneTransform). + if (!item->d_ptr->inDestructor) { + // Remove all children recursively + for (int i = 0; i < item->d_ptr->children.size(); ++i) + q->removeItem(item->d_ptr->children.at(i)); + } + // Unregister focus proxy. item->d_ptr->resetFocusProxy(); @@ -564,12 +572,6 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) ++iterator; } - if (!item->d_ptr->inDestructor) { - // Remove all children recursively - for (int i = 0; i < item->d_ptr->children.size(); ++i) - q->removeItem(item->d_ptr->children.at(i)); - } - if (item->isPanel() && item->isVisible() && item->panelModality() != QGraphicsItem::NonModal) leaveModal(item); diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index 1109e5e..9dfd486 100644 --- a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -66,6 +66,7 @@ private slots: void movingItems(); void connectedToSceneRectChanged(); void items(); + void removeItems(); void clear(); private: @@ -268,6 +269,63 @@ void tst_QGraphicsSceneIndex::items() QCOMPARE(scene.items().size(), 3); } +class RectWidget : public QGraphicsWidget +{ + Q_OBJECT +public: + RectWidget(QGraphicsItem *parent = 0) : QGraphicsWidget(parent) + { + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + painter->setBrush(brush); + painter->drawRect(boundingRect()); + } +public: + QBrush brush; +}; + +void tst_QGraphicsSceneIndex::removeItems() +{ + QGraphicsScene scene; + + RectWidget *parent = new RectWidget; + parent->brush = QBrush(QColor(Qt::magenta)); + parent->setGeometry(250, 250, 400, 400); + + RectWidget *widget = new RectWidget(parent); + widget->brush = QBrush(QColor(Qt::blue)); + widget->setGeometry(10, 10, 200, 200); + + RectWidget *widgetChild1 = new RectWidget(widget); + widgetChild1->brush = QBrush(QColor(Qt::green)); + widgetChild1->setGeometry(20, 20, 100, 100); + + RectWidget *widgetChild2 = new RectWidget(widgetChild1); + widgetChild2->brush = QBrush(QColor(Qt::yellow)); + widgetChild2->setGeometry(25, 25, 50, 50); + + scene.addItem(parent); + + QGraphicsView view(&scene); + view.resize(600, 600); + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + + QApplication::processEvents(); + + scene.removeItem(widgetChild1); + + delete widgetChild1; + + //We move the parent + scene.items(295, 295, 50, 50); + + //This should not crash +} + void tst_QGraphicsSceneIndex::clear() { class MyItem : public QGraphicsItem -- cgit v0.12 From a95883e90fadeddd2f49da6765fb2d79f7ce77bd Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 23 Oct 2009 09:14:39 +0200 Subject: Added visual DnD indicator for left to right flow in QListView Extended the behaviour already present in QAbstractItemView into QListView. This means some code duplication which should maybe be refactored at some point. (Seems to be the price to pay when some delegate does almost the same thing as the base class). No auto-test, as it's a drag-and-drop related task. Reviewed-by: Thierry Task-number: QTBUG-3730 --- src/gui/itemviews/qabstractitemview.h | 1 + src/gui/itemviews/qabstractitemview_p.h | 3 +- src/gui/itemviews/qlistview.cpp | 109 +++++++++++++++++++++++++++++++- src/gui/itemviews/qlistview_p.h | 9 +++ 4 files changed, 119 insertions(+), 3 deletions(-) diff --git a/src/gui/itemviews/qabstractitemview.h b/src/gui/itemviews/qabstractitemview.h index b4f0957..f438148 100644 --- a/src/gui/itemviews/qabstractitemview.h +++ b/src/gui/itemviews/qabstractitemview.h @@ -361,6 +361,7 @@ private: friend class QTreeViewPrivate; // needed to compile with MSVC friend class QAccessibleItemRow; + friend class QListModeViewBase; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractItemView::EditTriggers) diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index fcf381a..66b7662 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -164,7 +164,8 @@ public: } #ifndef QT_NO_DRAGANDDROP - QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const; + virtual QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const; + inline bool canDecode(QDropEvent *e) const { QStringList modelTypes = model->mimeTypes(); const QMimeData *mime = e->mimeData(); diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index f58f458..109d760 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -853,8 +853,13 @@ void QListView::resizeEvent(QResizeEvent *e) */ void QListView::dragMoveEvent(QDragMoveEvent *e) { - if (!d_func()->commonListView->filterDragMoveEvent(e)) - QAbstractItemView::dragMoveEvent(e); + Q_D(QListView); + if (!d->commonListView->filterDragMoveEvent(e)) { + if (viewMode() == QListView::ListMode && flow() == QListView::LeftToRight) + static_cast(d->commonListView)->dragMoveEvent(e); + else + QAbstractItemView::dragMoveEvent(e); + } } @@ -1804,6 +1809,16 @@ QItemSelection QListViewPrivate::selection(const QRect &rect) const return selection; } +#ifndef QT_NO_DRAGANDDROP +QAbstractItemView::DropIndicatorPosition QListViewPrivate::position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const +{ + if (viewMode == QListView::ListMode && flow == QListView::LeftToRight) + return static_cast(commonListView)->position(pos, rect, idx); + else + return QAbstractItemViewPrivate::position(pos, rect, idx); +} +#endif + /* * Common ListView Implementation */ @@ -1893,6 +1908,96 @@ void QListModeViewBase::paintDragDrop(QPainter *painter) // in IconMode, it makes no sense to show it dd->paintDropIndicator(painter); } + +QAbstractItemView::DropIndicatorPosition QListModeViewBase::position(const QPoint &pos, const QRect &rect, const QModelIndex &index) const +{ + QAbstractItemView::DropIndicatorPosition r = QAbstractItemView::OnViewport; + if (!dd->overwrite) { + const int margin = 2; + if (pos.x() - rect.left() < margin) { + r = QAbstractItemView::AboveItem; // Visually, on the left + } else if (rect.right() - pos.x() < margin) { + r = QAbstractItemView::BelowItem; // Visually, on the right + } else if (rect.contains(pos, true)) { + r = QAbstractItemView::OnItem; + } + } else { + QRect touchingRect = rect; + touchingRect.adjust(-1, -1, 1, 1); + if (touchingRect.contains(pos, false)) { + r = QAbstractItemView::OnItem; + } + } + + if (r == QAbstractItemView::OnItem && (!(dd->model->flags(index) & Qt::ItemIsDropEnabled))) + r = pos.x() < rect.center().x() ? QAbstractItemView::AboveItem : QAbstractItemView::BelowItem; + + return r; +} + +void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event) +{ + if (qq->dragDropMode() == QAbstractItemView::InternalMove + && (event->source() != qq || !(event->possibleActions() & Qt::MoveAction))) + return; + + // ignore by default + event->ignore(); + + QModelIndex index = qq->indexAt(event->pos()); + dd->hover = index; + if (!dd->droppingOnItself(event, index) + && dd->canDecode(event)) { + + if (index.isValid() && dd->showDropIndicator) { + QRect rect = qq->visualRect(index); + dd->dropIndicatorPosition = position(event->pos(), rect, index); + switch (dd->dropIndicatorPosition) { + case QAbstractItemView::AboveItem: + if (dd->isIndexDropEnabled(index.parent())) { + dd->dropIndicatorRect = QRect(rect.left(), rect.top(), 0, rect.height()); + event->accept(); + } else { + dd->dropIndicatorRect = QRect(); + } + break; + case QAbstractItemView::BelowItem: + if (dd->isIndexDropEnabled(index.parent())) { + dd->dropIndicatorRect = QRect(rect.right(), rect.top(), 0, rect.height()); + event->accept(); + } else { + dd->dropIndicatorRect = QRect(); + } + break; + case QAbstractItemView::OnItem: + if (dd->isIndexDropEnabled(index)) { + dd->dropIndicatorRect = rect; + event->accept(); + } else { + dd->dropIndicatorRect = QRect(); + } + break; + case QAbstractItemView::OnViewport: + dd->dropIndicatorRect = QRect(); + if (dd->isIndexDropEnabled(qq->rootIndex())) { + event->accept(); // allow dropping in empty areas + } + break; + } + } else { + dd->dropIndicatorRect = QRect(); + dd->dropIndicatorPosition = QAbstractItemView::OnViewport; + if (dd->isIndexDropEnabled(qq->rootIndex())) { + event->accept(); // allow dropping in empty areas + } + } + dd->viewport->update(); + } // can decode + + if (dd->shouldAutoScroll(event->pos())) + qq->startAutoScroll(); +} + #endif //QT_NO_DRAGANDDROP void QListModeViewBase::updateVerticalScrollBar(const QSize &step) diff --git a/src/gui/itemviews/qlistview_p.h b/src/gui/itemviews/qlistview_p.h index de4c7f3..3f8f9db 100644 --- a/src/gui/itemviews/qlistview_p.h +++ b/src/gui/itemviews/qlistview_p.h @@ -231,6 +231,11 @@ public: #ifndef QT_NO_DRAGANDDROP void paintDragDrop(QPainter *painter); + + // The next two methods are to be used on LefToRight flow only. + // WARNING: Plenty of duplicated code from QAbstractItemView{,Private}. + QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const; + void dragMoveEvent(QDragMoveEvent *e); #endif private: @@ -356,6 +361,10 @@ public: QItemSelection selection(const QRect &rect) const; void selectAll(QItemSelectionModel::SelectionFlags command); +#ifndef QT_NO_DRAGANDDROP + virtual QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const; +#endif + inline void setGridSize(const QSize &size) { grid = size; } inline QSize gridSize() const { return grid; } inline void setWrapping(bool b) { wrap = b; } -- cgit v0.12 From cc4d3fbc317bc9044c3ce23569f0225b29af4fd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Thu, 22 Oct 2009 14:49:40 +0200 Subject: QGraphicsLineItem leave traces when moving around (reg. against 4.5) The problem was that QGraphicsLineItem's bounding rect is an empty rect (either width is 0 or height is 0), and when updating the item's old occupied area, we explicitly checked whether the rect was empty() or not. In case of being empty (rect.isEmpty()) we did nothing, which was the root of the problem. We can safely remove the rect.isEmpty() check without any significant loss of performance since the common case is that the rect is non-empty. And in the case of being empty, we'll bail out from QGraphicsViewPrivate::updateRect's highly optimized rect intersection. Auto test included. Task: QTBUG-4877 Reviewed-by: alexis --- src/gui/graphicsview/qgraphicsscene.cpp | 2 +- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 34 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 03c8a97..9736c3e 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4888,7 +4888,7 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool continue; } - if (item->d_ptr->paintedViewBoundingRectsNeedRepaint && !paintedViewBoundingRect.isEmpty()) { + if (item->d_ptr->paintedViewBoundingRectsNeedRepaint) { paintedViewBoundingRect.translate(viewPrivate->dirtyScrollOffset); if (!viewPrivate->updateRect(paintedViewBoundingRect)) paintedViewBoundingRect = QRect(-1, -1, -1, -1); // Outside viewport. diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index dcad8e1..4fae911 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -372,6 +372,7 @@ private slots: void itemUsesExtendedStyleOption(); void itemSendsGeometryChanges(); void moveItem(); + void moveLineItem(); void sorting_data(); void sorting(); void itemHasNoContents(); @@ -7438,6 +7439,39 @@ void tst_QGraphicsItem::moveItem() COMPARE_REGIONS(view.paintedRegion, expectedParentRegion); } +void tst_QGraphicsItem::moveLineItem() +{ + QGraphicsScene scene; + scene.setSceneRect(0, 0, 200, 200); + QGraphicsLineItem *item = new QGraphicsLineItem(0, 0, 100, 0); + item->setPos(50, 50); + scene.addItem(item); + + MyGraphicsView view(&scene); + view.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&view); +#endif + QTest::qWait(200); + view.reset(); + + const QRect itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform()) + .mapRect(item->boundingRect()).toRect(); + QRegion expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2); // antialiasing + + // Make sure the calculated region is correct. + item->update(); + QTest::qWait(10); + QCOMPARE(view.paintedRegion, expectedRegion); + view.reset(); + + // Old position: (50, 50) + item->setPos(50, 100); + expectedRegion += expectedRegion.translated(0, 50); + QTest::qWait(10); + QCOMPARE(view.paintedRegion, expectedRegion); +} + void tst_QGraphicsItem::sorting_data() { QTest::addColumn("index"); -- cgit v0.12 From e751b8e9b0fdc1e23084a102ca6d86fea7f530d4 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 23 Oct 2009 12:05:30 +0200 Subject: MAke sure we call setCurrentTime when an animation is started This could be prevented by a pause animation currently running. Reviewed-by: Leo --- src/corelib/animation/qabstractanimation.cpp | 19 ++++++++----------- src/corelib/animation/qabstractanimation_p.h | 2 +- tests/auto/qpauseanimation/tst_qpauseanimation.cpp | 9 +++++++++ 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index f83c2a1..b8b9214 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -194,15 +194,10 @@ QUnifiedTimer *QUnifiedTimer::instance() return inst; } -void QUnifiedTimer::ensureTimerUpdate(QAbstractAnimation *animation) +void QUnifiedTimer::ensureTimerUpdate() { - if (isPauseTimerActive) { + if (isPauseTimerActive) updateAnimationsTime(); - } else { - // this code is needed when ensureTimerUpdate is called from setState because we update - // the currentTime when an animation starts running (otherwise we could remove it) - animation->setCurrentTime(animation->currentTime()); - } } void QUnifiedTimer::updateAnimationsTime() @@ -381,7 +376,7 @@ void QAbstractAnimationPrivate::setState(QAbstractAnimation::State newState) case QAbstractAnimation::Paused: if (hasRegisteredTimer) // currentTime needs to be updated if pauseTimer is active - QUnifiedTimer::instance()->ensureTimerUpdate(q); + QUnifiedTimer::instance()->ensureTimerUpdate(); if (!guard) return; //here we're sure that we were in running state before and that the @@ -395,9 +390,11 @@ void QAbstractAnimationPrivate::setState(QAbstractAnimation::State newState) // this ensures that the value is updated now that the animation is running if (oldState == QAbstractAnimation::Stopped) { - if (isTopLevel) + if (isTopLevel) { // currentTime needs to be updated if pauseTimer is active - QUnifiedTimer::instance()->ensureTimerUpdate(q); + QUnifiedTimer::instance()->ensureTimerUpdate(); + q->setCurrentTime(totalCurrentTime); + } } } break; @@ -558,7 +555,7 @@ void QAbstractAnimation::setDirection(Direction direction) // the commands order below is important: first we need to setCurrentTime with the old direction, // then update the direction on this and all children and finally restart the pauseTimer if needed if (d->hasRegisteredTimer) - QUnifiedTimer::instance()->ensureTimerUpdate(this); + QUnifiedTimer::instance()->ensureTimerUpdate(); d->direction = direction; updateDirection(direction); diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index bef0499..f989bce 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -142,7 +142,7 @@ public: this is used for updating the currentTime of all animations in case the pause timer is active or, otherwise, only of the animation passed as parameter. */ - void ensureTimerUpdate(QAbstractAnimation *animation); + void ensureTimerUpdate(); /* this will evaluate the need of restarting the pause timer in case there is still diff --git a/tests/auto/qpauseanimation/tst_qpauseanimation.cpp b/tests/auto/qpauseanimation/tst_qpauseanimation.cpp index b11efa0..2546163 100644 --- a/tests/auto/qpauseanimation/tst_qpauseanimation.cpp +++ b/tests/auto/qpauseanimation/tst_qpauseanimation.cpp @@ -260,6 +260,9 @@ void tst_QPauseAnimation::sequentialPauseGroup() animation3.setDuration(200); group.start(); + QCOMPARE(animation1.m_updateCurrentTimeCount, 1); + QCOMPARE(animation2.m_updateCurrentTimeCount, 0); + QCOMPARE(animation3.m_updateCurrentTimeCount, 0); QVERIFY(group.state() == QAbstractAnimation::Running); QVERIFY(animation1.state() == QAbstractAnimation::Running); @@ -267,6 +270,9 @@ void tst_QPauseAnimation::sequentialPauseGroup() QVERIFY(animation3.state() == QAbstractAnimation::Stopped); group.setCurrentTime(250); + QCOMPARE(animation1.m_updateCurrentTimeCount, 2); + QCOMPARE(animation2.m_updateCurrentTimeCount, 1); + QCOMPARE(animation3.m_updateCurrentTimeCount, 0); QVERIFY(group.state() == QAbstractAnimation::Running); QVERIFY(animation1.state() == QAbstractAnimation::Stopped); @@ -275,6 +281,9 @@ void tst_QPauseAnimation::sequentialPauseGroup() QVERIFY(animation3.state() == QAbstractAnimation::Stopped); group.setCurrentTime(500); + QCOMPARE(animation1.m_updateCurrentTimeCount, 2); + QCOMPARE(animation2.m_updateCurrentTimeCount, 2); + QCOMPARE(animation3.m_updateCurrentTimeCount, 1); QVERIFY(group.state() == QAbstractAnimation::Running); QVERIFY(animation1.state() == QAbstractAnimation::Stopped); -- cgit v0.12 From a1301736c3fdc25bdf6f35bf67747804adb83ac3 Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Fri, 23 Oct 2009 12:08:54 +0200 Subject: Increase realiability of pauseanimation autotests on win Reviewed-by: thierry --- tests/auto/qpauseanimation/tst_qpauseanimation.cpp | 44 ++++++++++++---------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/tests/auto/qpauseanimation/tst_qpauseanimation.cpp b/tests/auto/qpauseanimation/tst_qpauseanimation.cpp index 2546163..4d0a7a7 100644 --- a/tests/auto/qpauseanimation/tst_qpauseanimation.cpp +++ b/tests/auto/qpauseanimation/tst_qpauseanimation.cpp @@ -93,8 +93,7 @@ public: virtual ~tst_QPauseAnimation(); public Q_SLOTS: - void init(); - void cleanup(); + void initTestCase(); private slots: void changeDirectionWhileRunning(); @@ -117,20 +116,15 @@ tst_QPauseAnimation::~tst_QPauseAnimation() { } -void tst_QPauseAnimation::init() +void tst_QPauseAnimation::initTestCase() { qRegisterMetaType("QAbstractAnimation::State"); qRegisterMetaType("QAbstractAnimation::DeletionPolicy"); } -void tst_QPauseAnimation::cleanup() -{ -} - void tst_QPauseAnimation::changeDirectionWhileRunning() { - QUnifiedTimer *timer = QUnifiedTimer::instance(); - timer->setConsistentTiming(true); + EnableConsistentTiming enabled; TestablePauseAnimation animation; animation.setDuration(400); @@ -140,8 +134,6 @@ void tst_QPauseAnimation::changeDirectionWhileRunning() animation.setDirection(QAbstractAnimation::Backward); QTest::qWait(animation.totalDuration() + 50); QVERIFY(animation.state() == QAbstractAnimation::Stopped); - - timer->setConsistentTiming(false); } void tst_QPauseAnimation::noTimerUpdates_data() @@ -157,8 +149,7 @@ void tst_QPauseAnimation::noTimerUpdates_data() void tst_QPauseAnimation::noTimerUpdates() { - QUnifiedTimer *timer = QUnifiedTimer::instance(); - timer->setConsistentTiming(true); + EnableConsistentTiming enabled; QFETCH(int, duration); QFETCH(int, loopCount); @@ -168,16 +159,19 @@ void tst_QPauseAnimation::noTimerUpdates() animation.setLoopCount(loopCount); animation.start(); QTest::qWait(animation.totalDuration() + 100); + +#ifdef Q_OS_WIN + if (animation.state() != QAbstractAnimation::Stopped) + QEXPECT_FAIL("", "On windows, consistent timing is not working properly due to bad timer resolution", Abort); +#endif + QVERIFY(animation.state() == QAbstractAnimation::Stopped); QCOMPARE(animation.m_updateCurrentTimeCount, 1 + loopCount); - - timer->setConsistentTiming(false); } void tst_QPauseAnimation::mulitplePauseAnimations() { - QUnifiedTimer *timer = QUnifiedTimer::instance(); - timer->setConsistentTiming(true); + EnableConsistentTiming enabled; TestablePauseAnimation animation; animation.setDuration(200); @@ -188,16 +182,26 @@ void tst_QPauseAnimation::mulitplePauseAnimations() animation.start(); animation2.start(); QTest::qWait(animation.totalDuration() + 100); + +#ifdef Q_OS_WIN + if (animation.state() != QAbstractAnimation::Stopped) + QEXPECT_FAIL("", "On windows, consistent timing is not working properly due to bad timer resolution", Abort); +#endif + QVERIFY(animation.state() == QAbstractAnimation::Stopped); QVERIFY(animation2.state() == QAbstractAnimation::Running); QCOMPARE(animation.m_updateCurrentTimeCount, 2); QCOMPARE(animation2.m_updateCurrentTimeCount, 2); QTest::qWait(550); + +#ifdef Q_OS_WIN + if (animation2.state() != QAbstractAnimation::Stopped) + QEXPECT_FAIL("", "On windows, consistent timing is not working properly due to bad timer resolution", Abort); +#endif + QVERIFY(animation2.state() == QAbstractAnimation::Stopped); QCOMPARE(animation2.m_updateCurrentTimeCount, 3); - - timer->setConsistentTiming(false); } void tst_QPauseAnimation::pauseAndPropertyAnimations() @@ -243,7 +247,7 @@ void tst_QPauseAnimation::pauseResume() animation.pause(); QVERIFY(animation.state() == QAbstractAnimation::Paused); animation.start(); - QTest::qWait(250); + QTest::qWait(300); QVERIFY(animation.state() == QAbstractAnimation::Stopped); QCOMPARE(animation.m_updateCurrentTimeCount, 3); } -- cgit v0.12 From 72fb0f2637db401efd178b9d4139fc2b6ef59112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Fri, 23 Oct 2009 13:17:06 +0200 Subject: Wrong worldTransform() on the painter in QGraphicsScene::drawForeground. The painter's worldTransform() is updated for each item we draw, and when the DontSavePainterState optimization flag is set, this change is not protected by save() and restore(). After all the items are drawn, it means the painter is left with the last drawn item's transform. We therefore have to make sure it is reset back to whatever it was before the items were drawn. Auto-test included. Task-number: QTBUG-4973 Reviewed-by: alexis Reviewed-by: andreas --- src/gui/graphicsview/qgraphicsview.cpp | 8 +++++ tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 49 ++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 32747cc..49348de 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -3306,6 +3306,14 @@ void QGraphicsView::paintEvent(QPaintEvent *event) if (!(d->optimizationFlags & IndirectPainting)) { d->scene->d_func()->drawItems(&painter, viewTransformed ? &viewTransform : 0, &d->exposedRegion, viewport()); + // Make sure the painter's world transform is restored correctly when + // drawing without painter state protection (DontSavePainterState). + // We only change the worldTransform() so there's no need to do a full-blown + // save() and restore(). Also note that we don't have to do this in case of + // IndirectPainting (the else branch), because in that case we always save() + // and restore() in QGraphicsScene::drawItems(). + if (!d->scene->d_func()->painterStateProtection) + painter.setWorldTransform(viewTransform); } else { // Find all exposed items bool allItems = false; diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index dc08d0e..092f81d 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -194,6 +194,8 @@ private slots: void acceptDrops(); void optimizationFlags(); void optimizationFlags_dontSavePainterState(); + void optimizationFlags_dontSavePainterState2_data(); + void optimizationFlags_dontSavePainterState2(); void levelOfDetail_data(); void levelOfDetail(); void scrollBarRanges_data(); @@ -2455,6 +2457,53 @@ void tst_QGraphicsView::optimizationFlags_dontSavePainterState() QTest::qWaitForWindowShown(&painter2); } +void tst_QGraphicsView::optimizationFlags_dontSavePainterState2_data() +{ + QTest::addColumn("savePainter"); + QTest::newRow("With painter state protection") << true; + QTest::newRow("Without painter state protection") << false; +} + +void tst_QGraphicsView::optimizationFlags_dontSavePainterState2() +{ + QFETCH(bool, savePainter); + + class MyScene : public QGraphicsScene + { + public: + void drawBackground(QPainter *p, const QRectF &) + { transformInDrawBackground = p->worldTransform(); } + + void drawForeground(QPainter *p, const QRectF &) + { transformInDrawForeground = p->worldTransform(); } + + QTransform transformInDrawBackground; + QTransform transformInDrawForeground; + }; + + MyScene scene; + // Add transformed dummy items to make sure the painter's worldTransform() is changed in drawItems. + scene.addRect(0, 0, 20, 20)->setTransform(QTransform::fromScale(2, 2)); + scene.addRect(50, 50, 20, 20)->setTransform(QTransform::fromTranslate(200, 200)); + + QGraphicsView view(&scene); + if (!savePainter) + view.setOptimizationFlag(QGraphicsView::DontSavePainterState); + view.rotate(45); + view.scale(1.5, 1.5); + view.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&view); +#endif + QTest::qWait(150); + + // Make sure the painter's world transform is preserved after drawItems. + const QTransform expectedTransform = view.viewportTransform(); + QVERIFY(!expectedTransform.isIdentity()); + QCOMPARE(scene.transformInDrawForeground, expectedTransform); + QCOMPARE(scene.transformInDrawBackground, expectedTransform); +} + class LodItem : public QGraphicsRectItem { public: -- cgit v0.12 From b2cc784cbba9c790c2cc083cf99d9a2a112a9c27 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 23 Oct 2009 15:36:30 +0200 Subject: Phonon: allows to stream wave files from QIODevice Reviewed-by: trust Me --- src/3rdparty/phonon/ds9/iodevicereader.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/3rdparty/phonon/ds9/iodevicereader.cpp b/src/3rdparty/phonon/ds9/iodevicereader.cpp index e0c505c..695af59 100644 --- a/src/3rdparty/phonon/ds9/iodevicereader.cpp +++ b/src/3rdparty/phonon/ds9/iodevicereader.cpp @@ -36,17 +36,20 @@ namespace Phonon //these mediatypes define a stream, its type will be autodetected by DirectShow static QVector getMediaTypes() { - AM_MEDIA_TYPE mt = { MEDIATYPE_Stream, MEDIASUBTYPE_NULL, TRUE, FALSE, 1, GUID_NULL, 0, 0, 0}; + //the order here is important because otherwise, + //directshow might not be able to detect the stream type correctly + + AM_MEDIA_TYPE mt = { MEDIATYPE_Stream, MEDIASUBTYPE_Avi, TRUE, FALSE, 1, GUID_NULL, 0, 0, 0}; QVector ret; - //normal auto-detect stream - ret << mt; //AVI stream - mt.subtype = MEDIASUBTYPE_Avi; ret << mt; //WAVE stream mt.subtype = MEDIASUBTYPE_WAVE; ret << mt; + //normal auto-detect stream (must be at the end!) + mt.subtype = MEDIASUBTYPE_NULL; + ret << mt; return ret; } -- cgit v0.12 From b14338cce8cb13003a4943d134502e085f36ab08 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Mon, 26 Oct 2009 09:07:39 +0100 Subject: Fix buglet in QGraphicsItem::stackBefore(). Reported by Alan. The stackBefore() implementation did not alter the insertion order if the two items' current Z values were different. The fix is to ensure it is updated, so that the stackBefore() operation takes effect should the Z values become equal in the future. Example: Current order: A-B-C-D A->setZValue(1); Current order: B-C-D-A (A moves to the end) D->stackBefore(A); Current order: B-C-D-A (unchanged, D is already before A) A->setZValue(0); Current order: D-A-B-C (now A moves back, and D moves in front) Reviewed-by: Aaron Kennedy --- src/gui/graphicsview/qgraphicsitem.cpp | 2 +- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 56 +++++++++++++------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 4b2ff52..ad672a3 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -4261,7 +4261,7 @@ void QGraphicsItem::stackBefore(const QGraphicsItem *sibling) // Only move items with the same Z value, and that need moving. int siblingIndex = sibling->d_ptr->siblingIndex; int myIndex = d_ptr->siblingIndex; - if (myIndex >= siblingIndex && d_ptr->z == sibling->d_ptr->z) { + if (myIndex >= siblingIndex) { siblings->move(myIndex, siblingIndex); // Fixup the insertion ordering. for (int i = 0; i < siblings->size(); ++i) { diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 4fae911..dabf64c 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -8569,24 +8569,24 @@ void tst_QGraphicsItem::stackBefore() QCOMPARE(parent.childItems(), (QList() << child1 << child3 << child4 << child2)); // Move child2 before child1 - child2->stackBefore(child1); + child2->stackBefore(child1); // 2134 QCOMPARE(parent.childItems(), (QList() << child2 << child1 << child3 << child4)); - child2->stackBefore(child2); + child2->stackBefore(child2); // 2134 QCOMPARE(parent.childItems(), (QList() << child2 << child1 << child3 << child4)); - child1->setZValue(1); + child1->setZValue(1); // 2341 QCOMPARE(parent.childItems(), (QList() << child2 << child3 << child4 << child1)); - child1->stackBefore(child2); // no effect + child1->stackBefore(child2); // 2341 QCOMPARE(parent.childItems(), (QList() << child2 << child3 << child4 << child1)); - child1->setZValue(0); - QCOMPARE(parent.childItems(), (QList() << child2 << child1 << child3 << child4)); - child4->stackBefore(child1); - QCOMPARE(parent.childItems(), (QList() << child2 << child4 << child1 << child3)); - child4->setZValue(1); - QCOMPARE(parent.childItems(), (QList() << child2 << child1 << child3 << child4)); - child3->stackBefore(child1); - QCOMPARE(parent.childItems(), (QList() << child2 << child3 << child1 << child4)); - child4->setZValue(0); - QCOMPARE(parent.childItems(), (QList() << child2 << child4 << child3 << child1)); + child1->setZValue(0); // 1234 + QCOMPARE(parent.childItems(), (QList() << child1 << child2 << child3 << child4)); + child4->stackBefore(child1); // 4123 + QCOMPARE(parent.childItems(), (QList() << child4 << child1 << child2 << child3)); + child4->setZValue(1); // 1234 (4123) + QCOMPARE(parent.childItems(), (QList() << child1 << child2 << child3 << child4)); + child3->stackBefore(child1); // 3124 (4312) + QCOMPARE(parent.childItems(), (QList() << child3 << child1 << child2 << child4)); + child4->setZValue(0); // 4312 + QCOMPARE(parent.childItems(), (QList() << child4 << child3 << child1 << child2)); // Make them all toplevels child1->setParentItem(0); @@ -8608,24 +8608,24 @@ void tst_QGraphicsItem::stackBefore() QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList() << child1 << child3 << child4 << child2)); // Move child2 before child1 - child2->stackBefore(child1); + child2->stackBefore(child1); // 2134 QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList() << child2 << child1 << child3 << child4)); - child2->stackBefore(child2); + child2->stackBefore(child2); // 2134 QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList() << child2 << child1 << child3 << child4)); - child1->setZValue(1); + child1->setZValue(1); // 2341 QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList() << child2 << child3 << child4 << child1)); - child1->stackBefore(child2); // no effect + child1->stackBefore(child2); // 2341 QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList() << child2 << child3 << child4 << child1)); - child1->setZValue(0); - QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList() << child2 << child1 << child3 << child4)); - child4->stackBefore(child1); - QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList() << child2 << child4 << child1 << child3)); - child4->setZValue(1); - QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList() << child2 << child1 << child3 << child4)); - child3->stackBefore(child1); - QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList() << child2 << child3 << child1 << child4)); - child4->setZValue(0); - QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList() << child2 << child4 << child3 << child1)); + child1->setZValue(0); // 1234 + QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList() << child1 << child2 << child3 << child4)); + child4->stackBefore(child1); // 4123 + QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList() << child4 << child1 << child2 << child3)); + child4->setZValue(1); // 1234 (4123) + QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList() << child1 << child2 << child3 << child4)); + child3->stackBefore(child1); // 3124 (4312) + QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList() << child3 << child1 << child2 << child4)); + child4->setZValue(0); // 4312 + QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList() << child4 << child3 << child1 << child2)); } void tst_QGraphicsItem::QTBUG_4233_updateCachedWithSceneRect() -- cgit v0.12 From 319482a6b33ce1bd365457054aca49a51d885e07 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 23 Oct 2009 09:14:39 +0200 Subject: Drag and drop in QListWidget would not preserve the selection Now, when dropping items, these will remain selected, and in the same visual order as when dragged. Auto-test included for the items moving part. For the rest, it's a drag-and-drop thing. Reviewed-by: Olivier --- src/gui/itemviews/qlistwidget.cpp | 31 ++++++++++------ src/gui/itemviews/qlistwidget_p.h | 3 +- tests/auto/qlistwidget/tst_qlistwidget.cpp | 59 ++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 13 deletions(-) diff --git a/src/gui/itemviews/qlistwidget.cpp b/src/gui/itemviews/qlistwidget.cpp index a978d0f..5dd1d76 100644 --- a/src/gui/itemviews/qlistwidget.cpp +++ b/src/gui/itemviews/qlistwidget.cpp @@ -169,6 +169,20 @@ QListWidgetItem *QListModel::take(int row) return item; } +void QListModel::move(int srcRow, int dstRow) +{ + if (srcRow == dstRow + || srcRow < 0 || srcRow >= items.count() + || dstRow < 0 || dstRow >= items.count()) + return; + + beginMoveRows(QModelIndex(), srcRow, srcRow, QModelIndex(), dstRow); + if (srcRow < dstRow) + --dstRow; + items.move(srcRow, dstRow); + endMoveRows(); +} + int QListModel::rowCount(const QModelIndex &parent) const { return parent.isValid() ? 0 : items.count(); @@ -1804,22 +1818,15 @@ void QListWidget::dropEvent(QDropEvent *event) { if (persIndexes.contains(topIndex)) return; + qSort(persIndexes); // The dropped items will remain in the same visual order. QPersistentModelIndex dropRow = model()->index(row, col, topIndex); - QList taken; - for (int i = 0; i < persIndexes.count(); ++i) - taken.append(takeItem(persIndexes.at(i).row())); - - // insert them back in at their new positions + int r = row == -1 ? count() : (dropRow.row() >= 0 ? dropRow.row() : row); for (int i = 0; i < persIndexes.count(); ++i) { - // Either at a specific point or appended - if (row == -1) { - insertItem(count(), taken.takeFirst()); - } else { - int r = dropRow.row() >= 0 ? dropRow.row() : row; - insertItem(qMin(r, count()), taken.takeFirst()); - } + const QPersistentModelIndex &pIndex = persIndexes.at(i); + d->listModel()->move(pIndex.row(), r); + r = pIndex.row() + 1; // Dropped items are inserted contiguously and in the right order. } event->accept(); diff --git a/src/gui/itemviews/qlistwidget_p.h b/src/gui/itemviews/qlistwidget_p.h index 69cfa26..b5f28e3 100644 --- a/src/gui/itemviews/qlistwidget_p.h +++ b/src/gui/itemviews/qlistwidget_p.h @@ -77,7 +77,7 @@ public: { return *i2 < *i1; } }; -class QListModel : public QAbstractListModel +class Q_AUTOTEST_EXPORT QListModel : public QAbstractListModel { Q_OBJECT public: @@ -90,6 +90,7 @@ public: void insert(int row, const QStringList &items); void remove(QListWidgetItem *item); QListWidgetItem *take(int row); + void move(int srcRow, int dstRow); int rowCount(const QModelIndex &parent = QModelIndex()) const; diff --git a/tests/auto/qlistwidget/tst_qlistwidget.cpp b/tests/auto/qlistwidget/tst_qlistwidget.cpp index e825c8f..5c6ed54 100644 --- a/tests/auto/qlistwidget/tst_qlistwidget.cpp +++ b/tests/auto/qlistwidget/tst_qlistwidget.cpp @@ -46,6 +46,7 @@ #include #include +#include //TESTED_CLASS= //TESTED_FILES= @@ -95,6 +96,8 @@ private slots: void insertItem(); void insertItems_data(); void insertItems(); + void moveItemsPriv_data(); + void moveItemsPriv(); void itemAssignment(); void item_data(); @@ -849,6 +852,62 @@ void tst_QListWidget::removeItems() } +void tst_QListWidget::moveItemsPriv_data() +{ + QTest::addColumn("rowCount"); + QTest::addColumn("srcRow"); + QTest::addColumn("dstRow"); + QTest::addColumn("shouldHaveSignaled"); + + QTest::newRow("Empty") << 0 << 0 << 0 << false; + QTest::newRow("Overflow src") << 5 << 5 << 2 << false; + QTest::newRow("Underflow src") << 5 << -1 << 2 << false; + QTest::newRow("Overflow dst") << 5 << 2 << 5 << false; + QTest::newRow("Underflow dst") << 5 << 2 << -1 << false; + QTest::newRow("Same place") << 5 << 2 << 2 << false; + QTest::newRow("Up") << 5 << 4 << 2 << true; + QTest::newRow("Down") << 5 << 2 << 4 << true; +} + +void tst_QListWidget::moveItemsPriv() +{ + QFETCH(int, rowCount); + QFETCH(int, srcRow); + QFETCH(int, dstRow); + QFETCH(bool, shouldHaveSignaled); + + for (int r = 0; r < rowCount; ++r) + new QListWidgetItem(QString::number(r), testWidget); + + QListModel *model = dynamic_cast(testWidget->model()); + QVERIFY(model); + QSignalSpy beginMoveSpy(model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy movedSpy(model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); + model->move(srcRow, dstRow); + + if (shouldHaveSignaled) { + if (srcRow < dstRow) + QCOMPARE(testWidget->item(dstRow - 1)->text(), QString::number(srcRow)); + else + QCOMPARE(testWidget->item(dstRow)->text(), QString::number(srcRow)); + + QCOMPARE(beginMoveSpy.count(), 1); + const QList &beginMoveArgs = beginMoveSpy.takeFirst(); + QCOMPARE(beginMoveArgs.at(1).toInt(), srcRow); + QCOMPARE(beginMoveArgs.at(2).toInt(), srcRow); + QCOMPARE(beginMoveArgs.at(4).toInt(), dstRow); + + QCOMPARE(movedSpy.count(), 1); + const QList &movedArgs = movedSpy.takeFirst(); + QCOMPARE(movedArgs.at(1).toInt(), srcRow); + QCOMPARE(movedArgs.at(2).toInt(), srcRow); + QCOMPARE(movedArgs.at(4).toInt(), dstRow); + } else { + QCOMPARE(beginMoveSpy.count(), 0); + QCOMPARE(movedSpy.count(), 0); + } +} + void tst_QListWidget::itemStreaming_data() { QTest::addColumn("text"); -- cgit v0.12 From c7e8c1844819bc9b078403f8cdbad9c104452a30 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 26 Oct 2009 12:52:30 +0100 Subject: Fixed typo Would not have introduced any bug as invald QModelIndex are currently initialised with -1 for row and column. Reviewed-by: trust me --- src/gui/itemviews/qitemselectionmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/itemviews/qitemselectionmodel.cpp b/src/gui/itemviews/qitemselectionmodel.cpp index dfebe03..f2ccb6e 100644 --- a/src/gui/itemviews/qitemselectionmodel.cpp +++ b/src/gui/itemviews/qitemselectionmodel.cpp @@ -599,7 +599,7 @@ void QItemSelectionModelPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &pare while (itParent.isValid() && itParent.parent() != parent) itParent = itParent.parent(); - if (parent.isValid() && start <= itParent.row() && itParent.row() <= end) { + if (itParent.isValid() && start <= itParent.row() && itParent.row() <= end) { deselected.append(*it); it = ranges.erase(it); } else { -- cgit v0.12 From 26713a8b3fa4b82ea18c314c01b4d7ccb54d1125 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Mon, 26 Oct 2009 11:02:52 +0100 Subject: QDom: make tests fail only on Windows Reviewed-by: Carlos Duclos --- tests/auto/qdom/tst_qdom.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/qdom/tst_qdom.cpp b/tests/auto/qdom/tst_qdom.cpp index 0d58554e..f3a7909 100644 --- a/tests/auto/qdom/tst_qdom.cpp +++ b/tests/auto/qdom/tst_qdom.cpp @@ -322,7 +322,9 @@ void tst_QDom::toString_01_data() */ void tst_QDom::toString_01() { +#ifdef Q_OS_WIN QFAIL("make test fail instead of timing out, will be fixed later (QT-2357)"); +#endif QFETCH(QString, fileName); QFile f(fileName); -- cgit v0.12 From 9c78eb972041a066e455bf04d63f3290afacb982 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 26 Oct 2009 15:15:59 +0100 Subject: stabilize test and fix warning --- src/gui/kernel/qguiplatformplugin.cpp | 2 ++ tests/auto/qlistview/tst_qlistview.cpp | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qguiplatformplugin.cpp b/src/gui/kernel/qguiplatformplugin.cpp index 6e074a1..b01d40f 100644 --- a/src/gui/kernel/qguiplatformplugin.cpp +++ b/src/gui/kernel/qguiplatformplugin.cpp @@ -288,6 +288,8 @@ int QGuiPlatformPlugin::platformHint(PlatformHint hint) #endif //by default keep ret = 0 so QCommonStyle will use the style default break; + default: + break; } return ret; } diff --git a/tests/auto/qlistview/tst_qlistview.cpp b/tests/auto/qlistview/tst_qlistview.cpp index 3968529..65ab12d 100644 --- a/tests/auto/qlistview/tst_qlistview.cpp +++ b/tests/auto/qlistview/tst_qlistview.cpp @@ -1785,12 +1785,12 @@ void tst_QListView::task262152_setModelColumnNavigate() view.show(); QTest::qWaitForWindowShown(&view); - QTest::qWait(10); + QTest::qWait(100); QTest::keyClick(&view, Qt::Key_Down); - QTest::qWait(10); + QTest::qWait(100); QCOMPARE(view.currentIndex(), model.index(1,1)); QTest::keyClick(&view, Qt::Key_Down); - QTest::qWait(10); + QTest::qWait(100); QCOMPARE(view.currentIndex(), model.index(2,1)); } -- cgit v0.12 From 2d750192e73244f5b4ad6b451f264728d42669be Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 26 Oct 2009 15:53:47 +0100 Subject: Fixed crash when setting header data in QSqlQueryModel. The crash (Q_ASSERT_X failure) happened when a proxy model was being attached to the QSqlQueryModel, and no query was set yet. The headerDataChanged() signal was being received by the proxy model who wouldn't check its "proxyfied" data bounds. The patch introduces a behaviour change. However, this change makes the usage of QSqlQueryModel::setHeaderData() to be more in accordance with the current documentation, and to behave in the same way as for QStandardItemModel, QTreeModel, and QTableModel. Task-number: QTBUG-4963 Reviewed-by: Olivier --- src/sql/models/qsqlquerymodel.cpp | 2 +- tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/sql/models/qsqlquerymodel.cpp b/src/sql/models/qsqlquerymodel.cpp index a72ad8c..1719239 100644 --- a/src/sql/models/qsqlquerymodel.cpp +++ b/src/sql/models/qsqlquerymodel.cpp @@ -417,7 +417,7 @@ bool QSqlQueryModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role) { Q_D(QSqlQueryModel); - if (orientation != Qt::Horizontal || section < 0) + if (orientation != Qt::Horizontal || section < 0 || columnCount() <= section) return false; if (d->headers.size() <= section) diff --git a/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp b/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp index 3131f35..02b48fa 100644 --- a/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp +++ b/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp @@ -96,6 +96,7 @@ private slots: void task_180617(); void task_180617_data() { generic_data(); } + void task_QTBUG_4963_setHeaderDataWithProxyModel(); private: void generic_data(const QString &engine=QString()); @@ -428,6 +429,8 @@ void tst_QSqlQueryModel::setHeaderData() QVERIFY(!model.setHeaderData(5, Qt::Vertical, "foo")); QVERIFY(model.headerData(5, Qt::Vertical).isValid()); + model.setQuery(QSqlQuery("select * from " + qTableName("test"), db)); + qRegisterMetaType("Qt::Orientation"); QSignalSpy spy(&model, SIGNAL(headerDataChanged(Qt::Orientation, int, int))); QVERIFY(model.setHeaderData(2, Qt::Horizontal, "bar")); @@ -437,10 +440,8 @@ void tst_QSqlQueryModel::setHeaderData() QCOMPARE(spy.value(0).value(1).toInt(), 2); QCOMPARE(spy.value(0).value(2).toInt(), 2); - QVERIFY(model.setHeaderData(7, Qt::Horizontal, "foo", Qt::ToolTipRole)); - QVERIFY(model.headerData(7, Qt::Horizontal, Qt::ToolTipRole).isValid()); - - model.setQuery(QSqlQuery("select * from " + qTableName("test"), db)); + QVERIFY(!model.setHeaderData(7, Qt::Horizontal, "foo", Qt::ToolTipRole)); + QVERIFY(!model.headerData(7, Qt::Horizontal, Qt::ToolTipRole).isValid()); bool isToUpper = db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2"); QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), isToUpper ? QString("ID") : QString("id")); @@ -603,5 +604,14 @@ void tst_QSqlQueryModel::task_180617() QCOMPARE(view.rowAt(0), -1); } +void tst_QSqlQueryModel::task_QTBUG_4963_setHeaderDataWithProxyModel() +{ + QSqlQueryModel plainModel; + QSortFilterProxyModel proxyModel; + proxyModel.setSourceModel(&plainModel); + QVERIFY(!plainModel.setHeaderData(0, Qt::Horizontal, QObject::tr("ID"))); + // And it should not crash. +} + QTEST_MAIN(tst_QSqlQueryModel) #include "tst_qsqlquerymodel.moc" -- cgit v0.12 From 96f59cb98c248185a3873f06d0e1a2e7652d8cec Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Mon, 19 Oct 2009 07:30:52 -0300 Subject: QGAL: complex anchors can indicate errors when refreshing sizehint Now the refreshSizeHints() returns a boolean, and the parallel anchor will return false in unfeasible cases, e.g. one anchor has maximum size smaller than other minimum size. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Eduardo M. Fleury --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 43 ++++++++++++++---------- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 10 +++--- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 8c8c303..a92a63e 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -141,7 +141,7 @@ static void internalSizeHints(QSizePolicy::Policy policy, *expSize = *prefSize; } -void AnchorData::refreshSizeHints(qreal effectiveSpacing) +bool AnchorData::refreshSizeHints(qreal effectiveSpacing) { const bool isInternalAnchor = from->m_item == to->m_item; @@ -164,7 +164,7 @@ void AnchorData::refreshSizeHints(qreal effectiveSpacing) maxSize = QWIDGETSIZE_MAX; if (hasCenter) maxSize /= 2; - return; + return true; } else { QGraphicsLayoutItem *item = from->m_item; @@ -214,6 +214,8 @@ void AnchorData::refreshSizeHints(qreal effectiveSpacing) sizeAtPreferred = prefSize; sizeAtExpanding = prefSize; sizeAtMaximum = prefSize; + + return true; } void ParallelAnchorData::updateChildrenSizes() @@ -227,26 +229,29 @@ void ParallelAnchorData::updateChildrenSizes() secondEdge->updateChildrenSizes(); } -void ParallelAnchorData::refreshSizeHints(qreal effectiveSpacing) +bool ParallelAnchorData::refreshSizeHints(qreal effectiveSpacing) { - refreshSizeHints_helper(effectiveSpacing); + return refreshSizeHints_helper(effectiveSpacing); } -void ParallelAnchorData::refreshSizeHints_helper(qreal effectiveSpacing, +bool ParallelAnchorData::refreshSizeHints_helper(qreal effectiveSpacing, bool refreshChildren) { - if (refreshChildren) { - firstEdge->refreshSizeHints(effectiveSpacing); - secondEdge->refreshSizeHints(effectiveSpacing); + if (refreshChildren && (!firstEdge->refreshSizeHints(effectiveSpacing) + || !secondEdge->refreshSizeHints(effectiveSpacing))) { + return false; } - // ### should we warn if the parallel connection is invalid? - // e.g. 1-2-3 with 10-20-30, the minimum of the latter is - // bigger than the maximum of the former. - minSize = qMax(firstEdge->minSize, secondEdge->minSize); maxSize = qMin(firstEdge->maxSize, secondEdge->maxSize); + // This condition means that the maximum size of one anchor being simplified is smaller than + // the minimum size of the other anchor. The consequence is that there won't be a valid size + // for this parallel setup. + if (minSize > maxSize) { + return false; + } + expSize = qMax(firstEdge->expSize, secondEdge->expSize); expSize = qMin(expSize, maxSize); @@ -258,6 +263,8 @@ void ParallelAnchorData::refreshSizeHints_helper(qreal effectiveSpacing, sizeAtPreferred = prefSize; sizeAtExpanding = prefSize; sizeAtMaximum = prefSize; + + return true; } /*! @@ -362,12 +369,12 @@ void SequentialAnchorData::updateChildrenSizes() } } -void SequentialAnchorData::refreshSizeHints(qreal effectiveSpacing) +bool SequentialAnchorData::refreshSizeHints(qreal effectiveSpacing) { - refreshSizeHints_helper(effectiveSpacing); + return refreshSizeHints_helper(effectiveSpacing); } -void SequentialAnchorData::refreshSizeHints_helper(qreal effectiveSpacing, +bool SequentialAnchorData::refreshSizeHints_helper(qreal effectiveSpacing, bool refreshChildren) { minSize = 0; @@ -379,8 +386,8 @@ void SequentialAnchorData::refreshSizeHints_helper(qreal effectiveSpacing, AnchorData *edge = m_edges.at(i); // If it's the case refresh children information first - if (refreshChildren) - edge->refreshSizeHints(effectiveSpacing); + if (refreshChildren && !edge->refreshSizeHints(effectiveSpacing)) + return false; minSize += edge->minSize; prefSize += edge->prefSize; @@ -393,6 +400,8 @@ void SequentialAnchorData::refreshSizeHints_helper(qreal effectiveSpacing, sizeAtPreferred = prefSize; sizeAtExpanding = prefSize; sizeAtMaximum = prefSize; + + return true; } #ifdef QT_DEBUG diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index d45c004..d4eb2d4 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -159,7 +159,7 @@ struct AnchorData : public QSimplexVariable { type(Normal), hasSize(true), isLayoutAnchor(false) {} virtual void updateChildrenSizes() {} - virtual void refreshSizeHints(qreal effectiveSpacing); + virtual bool refreshSizeHints(qreal effectiveSpacing); virtual ~AnchorData() {} @@ -226,9 +226,9 @@ struct SequentialAnchorData : public AnchorData } virtual void updateChildrenSizes(); - virtual void refreshSizeHints(qreal effectiveSpacing); + virtual bool refreshSizeHints(qreal effectiveSpacing); - void refreshSizeHints_helper(qreal effectiveSpacing, bool refreshChildren = true); + bool refreshSizeHints_helper(qreal effectiveSpacing, bool refreshChildren = true); void setVertices(const QVector &vertices) { @@ -261,9 +261,9 @@ struct ParallelAnchorData : public AnchorData } virtual void updateChildrenSizes(); - virtual void refreshSizeHints(qreal effectiveSpacing); + virtual bool refreshSizeHints(qreal effectiveSpacing); - void refreshSizeHints_helper(qreal effectiveSpacing, bool refreshChildren = true); + bool refreshSizeHints_helper(qreal effectiveSpacing, bool refreshChildren = true); AnchorData* firstEdge; AnchorData* secondEdge; -- cgit v0.12 From 3b025f72636041f7bfe1bf02b34e3b156a78844f Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Fri, 16 Oct 2009 17:40:02 -0300 Subject: QGAL: separate parallel anchor creation from sequence creation Extract the creation of parallel anchors from the creation of sequential anchor. This will be useful to keep track whether a parallel anchor is feasible or not. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Eduardo M. Fleury --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 90 ++++++++++++++++-------- 1 file changed, 61 insertions(+), 29 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index a92a63e..8b7ff08 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -519,18 +519,51 @@ inline static qreal checkAdd(qreal a, qreal b) } /*! - * \internal - * - * Takes the sequence of vertices described by (\a before, \a vertices, \a after) and replaces - * all anchors connected to the vertices in \a vertices with one simplified anchor between - * \a before and \a after. The simplified anchor will be a placeholder for all the previous - * anchors between \a before and \a after, and can be restored back to the anchors it is a - * placeholder for. - */ -static bool simplifySequentialChunk(Graph *graph, - AnchorVertex *before, - const QVector &vertices, - AnchorVertex *after) + \internal + + Adds \a newAnchor to the graph \a g. + + Returns the newAnchor itself if it could be added without further changes to the graph. If a + new parallel anchor had to be created, then returns the new parallel anchor. In case the + addition is unfeasible -- because a parallel setup is not possible, returns 0. +*/ +static AnchorData *addAnchorMaybeParallel(Graph *g, + AnchorData *newAnchor) +{ + bool feasible = true; + + // If already exists one anchor where newAnchor is supposed to be, we create a parallel + // anchor. + if (AnchorData *oldAnchor = g->takeEdge(newAnchor->from, newAnchor->to)) { + ParallelAnchorData *parallel = new ParallelAnchorData(oldAnchor, newAnchor); + parallel->isLayoutAnchor = (oldAnchor->isLayoutAnchor + || newAnchor->isLayoutAnchor); + + // At this point we can identify that the parallel anchor is not feasible, e.g. one + // anchor minimum size is bigger than the other anchor maximum size. + feasible = parallel->refreshSizeHints_helper(0, false); + newAnchor = parallel; + } + + g->createEdge(newAnchor->from, newAnchor->to, newAnchor); + return feasible ? newAnchor : 0; +} + + +/*! + \internal + + Takes the sequence of vertices described by (\a before, \a vertices, \a after) and removes + all anchors connected to the vertices in \a vertices, returning one simplified anchor between + \a before and \a after. + + Note that this function doesn't add the created anchor to the graph. This should be done by + the caller. +*/ +static AnchorData *createSequence(Graph *graph, + AnchorVertex *before, + const QVector &vertices, + AnchorVertex *after) { AnchorData *data = graph->edgeData(before, vertices.first()); Q_ASSERT(data); @@ -578,18 +611,7 @@ static bool simplifySequentialChunk(Graph *graph, sequence->isLayoutAnchor = (sequence->m_edges.first()->isLayoutAnchor || sequence->m_edges.last()->isLayoutAnchor); - AnchorData *newAnchor = sequence; - if (AnchorData *oldAnchor = graph->takeEdge(before, after)) { - ParallelAnchorData *parallel = new ParallelAnchorData(oldAnchor, sequence); - parallel->isLayoutAnchor = (oldAnchor->isLayoutAnchor - || sequence->isLayoutAnchor); - parallel->refreshSizeHints_helper(0, false); - newAnchor = parallel; - } - graph->createEdge(before, after, newAnchor); - - // True if we created a parallel anchor - return newAnchor != sequence; + return sequence; } /*! @@ -803,11 +825,21 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP continue; } - // This function will remove the candidates from the graph and create one edge between - // beforeSequence and afterSequence. This function returns true if the sequential - // simplification also caused a parallel simplification to be created. In this case we end - // the iteration and start again (since all the visited state we have may be outdated). - if (simplifySequentialChunk(&g, beforeSequence, candidates, afterSequence)) + // + // Add the sequence to the graph. + // + + AnchorData *sequence = createSequence(&g, beforeSequence, candidates, afterSequence); + + // If 'beforeSequence' and 'afterSequence' already had an anchor between them, we'll + // create a parallel anchor between the new sequence and the old anchor. + AnchorData *newAnchor = addAnchorMaybeParallel(&g, sequence); + + // When a new parallel anchor is create in the graph, we finish the iteration and return + // true to indicate a new iteration is needed. This happens because a parallel anchor + // changes the number of adjacents one vertex has, possibly opening up oportunities for + // building candidate lists (when adjacents == 2). + if (newAnchor != sequence) return true; // If there was no parallel simplification, we'll keep walking the graph. So we clear the -- cgit v0.12 From f9dfd711d104bb438da6ea281012600a897ab30c Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Mon, 19 Oct 2009 11:10:31 -0300 Subject: QGAL: identify unfeasible setups even when graph is simplified The calculate graphs now can return early due to unfeasible anchor setups found out during simplification. This allows finding out problems in parallel anchors, when one anchor has maximum size smaller than the minimum size of the other anchor. The order for simplification and refreshing size hints also has been swaped: - First, refresh size hints for all anchors in the graph. If the graph is simplified, the refreshSizeHints() call will reach the children anchors. - Then, if the simplificated graph is invalid, rebuild it. During this rebuild, refreshSizeHints_helper() will be called for all levels. So in both situations we can identify an unfeasible setup. Note that this test alone is not enough to classify the graph as feasible, depending on the graph, it will still need to go through the Simplex. A test case was added and the function that traverse the graph refreshing now is called refreshAllSizeHints(). The old name was not so clear since the function will not fill only the anchors that have items associated. Last but not least, the lastCalculationUsedSimplex variable is cleared when starting calculateGraphs(), since we now can leave the function earlier, without reaching calculateTrunk(), which is the function that sets it. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Eduardo M. Fleury --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 99 +++++++++++++++------- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 6 +- .../tst_qgraphicsanchorlayout.cpp | 51 +++++++++++ 3 files changed, 122 insertions(+), 34 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 8b7ff08..8d13b2b 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -648,15 +648,17 @@ static AnchorData *createSequence(Graph *graph, 2. Go to (1) 3. Done + When creating the parallel anchors, the algorithm might identify unfeasible situations. In this + case the simplification process stops and returns false. Otherwise returns true. */ -void QGraphicsAnchorLayoutPrivate::simplifyGraph(Orientation orientation) +bool QGraphicsAnchorLayoutPrivate::simplifyGraph(Orientation orientation) { static bool noSimplification = !qgetenv("QT_ANCHORLAYOUT_NO_SIMPLIFICATION").isEmpty(); if (noSimplification || items.isEmpty()) - return; + return true; if (graphSimplified[orientation]) - return; + return true; graphSimplified[orientation] = true; #if 0 @@ -665,12 +667,18 @@ void QGraphicsAnchorLayoutPrivate::simplifyGraph(Orientation orientation) #endif if (!graph[orientation].rootVertex()) - return; + return true; bool dirty; + bool feasible = true; do { - dirty = simplifyGraphIteration(orientation); - } while (dirty); + dirty = simplifyGraphIteration(orientation, &feasible); + } while (dirty && feasible); + + if (!feasible) + graphSimplified[orientation] = false; + + return feasible; } /*! @@ -687,7 +695,8 @@ void QGraphicsAnchorLayoutPrivate::simplifyGraph(Orientation orientation) Note that there are some catches to this that are not covered by the above explanation, see the function comments for more details. */ -bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutPrivate::Orientation orientation) +bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutPrivate::Orientation orientation, + bool *feasible) { Q_Q(QGraphicsAnchorLayout); Graph &g = graph[orientation]; @@ -835,6 +844,11 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP // create a parallel anchor between the new sequence and the old anchor. AnchorData *newAnchor = addAnchorMaybeParallel(&g, sequence); + if (!newAnchor) { + *feasible = false; + return false; + } + // When a new parallel anchor is create in the graph, we finish the iteration and return // true to indicate a new iteration is needed. This happens because a parallel anchor // changes the number of adjacents one vertex has, possibly opening up oportunities for @@ -1679,38 +1693,52 @@ QList getVariables(QList constraints) } /*! - \internal + \internal - Calculate graphs is the method that puts together all the helper routines - so that the AnchorLayout can calculate the sizes of each item. + Calculate graphs is the method that puts together all the helper routines + so that the AnchorLayout can calculate the sizes of each item. - In a nutshell it should do: + In a nutshell it should do: - 1) Update anchor nominal sizes, that is, the size that each anchor would - have if no other restrictions applied. This is done by quering the - layout style and the sizeHints of the items belonging to the layout. + 1) Refresh anchor nominal sizes, that is, the size that each anchor would + have if no other restrictions applied. This is done by quering the + layout style and the sizeHints of the items belonging to the layout. - 2) Simplify the graph by grouping together parallel and sequential anchors - into "group anchors". These have equivalent minimum, preferred and maximum - sizeHints as the anchors they replace. + 2) Simplify the graph by grouping together parallel and sequential anchors + into "group anchors". These have equivalent minimum, preferred and maximum + sizeHints as the anchors they replace. - 3) Check if we got to a trivial case. In some cases, the whole graph can be - simplified into a single anchor. If so, use this information. If not, - then call the Simplex solver to calculate the anchors sizes. + 3) Check if we got to a trivial case. In some cases, the whole graph can be + simplified into a single anchor. If so, use this information. If not, + then call the Simplex solver to calculate the anchors sizes. - 4) Once the root anchors had its sizes calculated, propagate that to the - anchors they represent. + 4) Once the root anchors had its sizes calculated, propagate that to the + anchors they represent. */ void QGraphicsAnchorLayoutPrivate::calculateGraphs( QGraphicsAnchorLayoutPrivate::Orientation orientation) { Q_Q(QGraphicsAnchorLayout); - // Simplify the graph - simplifyGraph(orientation); +#if defined(QT_DEBUG) || defined(Q_AUTOTEST_EXPORT) + lastCalculationUsedSimplex[orientation] = false; +#endif + + // Reset the nominal sizes of each anchor based on the current item sizes. This function + // works with both simplified and non-simplified graphs, so it'll work when the + // simplification is going to be reused. + if (!refreshAllSizeHints(orientation)) { + qWarning("QGraphicsAnchorLayout: anchor setup is not feasible."); + graphHasConflicts[orientation] = true; + return; + } - // Reset the nominal sizes of each anchor based on the current item sizes - setAnchorSizeHintsFromItems(orientation); + // Simplify the graph + if (!simplifyGraph(orientation)) { + qWarning("QGraphicsAnchorLayout: anchor setup is not feasible."); + graphHasConflicts[orientation] = true; + return; + } // Traverse all graph edges and store the possible paths to each vertex findPaths(orientation); @@ -1878,12 +1906,16 @@ bool QGraphicsAnchorLayoutPrivate::calculateNonTrunk(const QList &g = graph[orientation]; QList > vertices = g.connections(); @@ -1893,8 +1925,13 @@ void QGraphicsAnchorLayoutPrivate::setAnchorSizeHintsFromItems(Orientation orien for (int i = 0; i < vertices.count(); ++i) { AnchorData *data = g.edgeData(vertices.at(i).first, vertices.at(i).second);; Q_ASSERT(data->from && data->to); - data->refreshSizeHints(spacing); + + // During the traversal we check the feasibility of the complex anchors. + if (!data->refreshSizeHints(spacing)) + return false; } + + return true; } /*! diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index d4eb2d4..a3de6f6 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -428,8 +428,8 @@ public: qreal effectiveSpacing(Orientation orientation) const; // Activation methods - void simplifyGraph(Orientation orientation); - bool simplifyGraphIteration(Orientation orientation); + bool simplifyGraph(Orientation orientation); + bool simplifyGraphIteration(Orientation orientation, bool *feasible); void restoreSimplifiedGraph(Orientation orientation); void calculateGraphs(); @@ -441,7 +441,7 @@ public: bool calculateNonTrunk(const QList &constraints, const QList &variables); - void setAnchorSizeHintsFromItems(Orientation orientation); + bool refreshAllSizeHints(Orientation orientation); void findPaths(Orientation orientation); void constraintsFromPaths(Orientation orientation); void updateAnchorSizes(Orientation orientation); diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 7b87969..facc1ef 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -82,6 +82,7 @@ private slots: void expandingParallel(); void floatConflict(); void infiniteMaxSizes(); + void simplifiableUnfeasible(); }; class RectWidget : public QGraphicsWidget @@ -1755,5 +1756,55 @@ void tst_QGraphicsAnchorLayout::infiniteMaxSizes() QCOMPARE(d->geometry(), QRectF(QWIDGETSIZE_MAX - 50, 0, 50, 10)); } +void tst_QGraphicsAnchorLayout::simplifiableUnfeasible() +{ + QGraphicsWidget *a = createItem(QSizeF(70.0, 100.0), + QSizeF(100.0, 100.0), + QSizeF(100.0, 100.0), "A"); + + QGraphicsWidget *b = createItem(QSizeF(110.0, 100.0), + QSizeF(150.0, 100.0), + QSizeF(190.0, 100.0), "B"); + + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; + l->setContentsMargins(0, 0, 0, 0); + l->setSpacing(0); + + l->addAnchor(l, Qt::AnchorTop, a, Qt::AnchorTop); + l->addAnchor(a, Qt::AnchorBottom, b, Qt::AnchorTop); + l->addAnchor(b, Qt::AnchorBottom, l, Qt::AnchorBottom); + + l->addAnchors(l, a, Qt::Horizontal); + l->addAnchor(l, Qt::AnchorLeft, b, Qt::AnchorLeft); + l->addAnchor(b, Qt::AnchorRight, a, Qt::AnchorRight); + + QCOMPARE(l->count(), 2); + + QGraphicsWidget p; + p.setLayout(l); + + l->invalidate(); + QVERIFY(layoutHasConflict(l)); + if (hasSimplification) + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + + // Now we make it valid again + b->setMinimumWidth(100); + + l->invalidate(); + QVERIFY(!layoutHasConflict(l)); + if (hasSimplification) + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + + // And make it invalid again + a->setPreferredWidth(70); + a->setMaximumWidth(70); + + l->invalidate(); + QVERIFY(layoutHasConflict(l)); + if (hasSimplification) + QVERIFY(!usedSimplex(l, Qt::Horizontal)); +} + QTEST_MAIN(tst_QGraphicsAnchorLayout) #include "tst_qgraphicsanchorlayout.moc" -- cgit v0.12 From bee00ac4ca0865e621edaea54d079005c68f120e Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Fri, 16 Oct 2009 12:26:21 -0300 Subject: QGAL: store item and center-ness information in the anchor We used to look for this information in the anchor's from and to vertices, but to enable simplification of vertices, we have to store this information in the anchor. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Eduardo M. Fleury --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 24 ++++++++++++------------ src/gui/graphicsview/qgraphicsanchorlayout_p.h | 9 +++++++-- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 8d13b2b..aa510f1 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -143,31 +143,25 @@ static void internalSizeHints(QSizePolicy::Policy policy, bool AnchorData::refreshSizeHints(qreal effectiveSpacing) { - const bool isInternalAnchor = from->m_item == to->m_item; - QSizePolicy::Policy policy; qreal minSizeHint; qreal prefSizeHint; qreal maxSizeHint; - if (isInternalAnchor) { + // It is an internal anchor + if (item) { const QGraphicsAnchorLayoutPrivate::Orientation orient = QGraphicsAnchorLayoutPrivate::edgeOrientation(from->m_edge); - const Qt::AnchorPoint centerEdge = - QGraphicsAnchorLayoutPrivate::pickEdge(Qt::AnchorHorizontalCenter, orient); - bool hasCenter = (from->m_edge == centerEdge || to->m_edge == centerEdge); if (isLayoutAnchor) { minSize = 0; prefSize = 0; expSize = 0; maxSize = QWIDGETSIZE_MAX; - if (hasCenter) + if (isCenterAnchor) maxSize /= 2; return true; } else { - - QGraphicsLayoutItem *item = from->m_item; if (orient == QGraphicsAnchorLayoutPrivate::Horizontal) { policy = item->sizePolicy().horizontalPolicy(); minSizeHint = item->effectiveSizeHint(Qt::MinimumSize).width(); @@ -180,7 +174,7 @@ bool AnchorData::refreshSizeHints(qreal effectiveSpacing) maxSizeHint = item->effectiveSizeHint(Qt::MaximumSize).height(); } - if (hasCenter) { + if (isCenterAnchor) { minSizeHint /= 2; prefSizeHint /= 2; maxSizeHint /= 2; @@ -1063,11 +1057,13 @@ void QGraphicsAnchorLayoutPrivate::createCenterAnchors( AnchorData *data = new AnchorData; c->variables.insert(data, 1.0); addAnchor_helper(item, firstEdge, item, centerEdge, data); + data->isCenterAnchor = true; data->refreshSizeHints(0); data = new AnchorData; c->variables.insert(data, -1.0); addAnchor_helper(item, centerEdge, item, lastEdge, data); + data->isCenterAnchor = true; data->refreshSizeHints(0); itemCenterConstraints[orientation].append(c); @@ -1304,6 +1300,10 @@ void QGraphicsAnchorLayoutPrivate::addAnchor_helper(QGraphicsLayoutItem *firstIt removeAnchor_helper(v1, v2); } + // If its an internal anchor, set the associated item + if (firstItem == secondItem) + data->item = firstItem; + // Create a bi-directional edge in the sense it can be transversed both // from v1 or v2. "data" however is shared between the two references // so we still know that the anchor direction is from 1 to 2. @@ -2188,8 +2188,8 @@ void QGraphicsAnchorLayoutPrivate::identifyNonFloatItems_helper(const AnchorData switch(ad->type) { case AnchorData::Normal: - if (ad->from->m_item == ad->to->m_item && ad->to->m_item != q) - nonFloatingItemsIdentifiedSoFar->insert(ad->to->m_item); + if (ad->item && ad->item != q) + nonFloatingItemsIdentifiedSoFar->insert(ad->item); break; case AnchorData::Sequential: foreach (const AnchorData *d, static_cast(ad)->m_edges) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index a3de6f6..511e1ec 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -151,12 +151,13 @@ struct AnchorData : public QSimplexVariable { }; AnchorData() - : QSimplexVariable(), from(0), to(0), + : QSimplexVariable(), item(0), from(0), to(0), minSize(0), prefSize(0), expSize(0), maxSize(0), sizeAtMinimum(0), sizeAtPreferred(0), sizeAtExpanding(0), sizeAtMaximum(0), graphicsAnchor(0), skipInPreferred(0), - type(Normal), hasSize(true), isLayoutAnchor(false) {} + type(Normal), hasSize(true), isLayoutAnchor(false), + isCenterAnchor(false) {} virtual void updateChildrenSizes() {} virtual bool refreshSizeHints(qreal effectiveSpacing); @@ -180,6 +181,9 @@ struct AnchorData : public QSimplexVariable { hasSize = false; } + // Internal anchors have associated items + QGraphicsLayoutItem *item; + // Anchor is semantically directed AnchorVertex *from; AnchorVertex *to; @@ -206,6 +210,7 @@ struct AnchorData : public QSimplexVariable { uint type : 2; // either Normal, Sequential or Parallel uint hasSize : 1; // if false, get size from style. uint isLayoutAnchor : 1; // if this anchor is connected to a layout 'edge' + uint isCenterAnchor : 1; }; #ifdef QT_DEBUG -- cgit v0.12 From d4c1a4675bdff63912b31243e5292766ff5215a5 Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Fri, 16 Oct 2009 12:43:25 -0300 Subject: QGAL: simplification doesn't depend on vertex anchor point information Look for information inside the anchor instead of on the vertices. This will give us flexibility of simplifying vertices before the anchor simplification phase. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Eduardo M. Fleury --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index aa510f1..b0b1408 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -701,8 +701,6 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP QVector candidates; bool candidatesForward; - const Qt::AnchorPoint centerEdge = pickEdge(Qt::AnchorHorizontalCenter, orientation); - // Walk depth-first, in the stack we store start of the candidate sequence (beforeSequence) // and the vertex to be visited. while (!stack.isEmpty()) { @@ -811,7 +809,8 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP // One restriction we have is to not simplify half of an anchor and let the other half // unsimplified. So we remove center edges before and after the sequence. - if (beforeSequence->m_edge == centerEdge && beforeSequence->m_item == candidates.first()->m_item) { + const AnchorData *firstAnchor = g.edgeData(beforeSequence, candidates.first()); + if (firstAnchor->isCenterAnchor) { beforeSequence = candidates.first(); candidates.remove(0); @@ -820,7 +819,8 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP continue; } - if (afterSequence->m_edge == centerEdge && afterSequence->m_item == candidates.last()->m_item) { + const AnchorData *lastAnchor = g.edgeData(candidates.last(), afterSequence); + if (lastAnchor->isCenterAnchor) { afterSequence = candidates.last(); candidates.remove(candidates.count() - 1); -- cgit v0.12 From 73d89d68d5d710e86e6aa74b2924ee4aca11881e Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Fri, 16 Oct 2009 13:10:13 -0300 Subject: QGAL: add orientation bit to the anchor Use a free bit in the anchor struct to save the orientation information. That way we do not depend on looking for this information in the vertices (by looking the orientation of its edge). Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Eduardo M. Fleury --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 17 +++++++++-------- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 3 ++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index b0b1408..41e067c 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -150,9 +150,6 @@ bool AnchorData::refreshSizeHints(qreal effectiveSpacing) // It is an internal anchor if (item) { - const QGraphicsAnchorLayoutPrivate::Orientation orient = - QGraphicsAnchorLayoutPrivate::edgeOrientation(from->m_edge); - if (isLayoutAnchor) { minSize = 0; prefSize = 0; @@ -162,7 +159,7 @@ bool AnchorData::refreshSizeHints(qreal effectiveSpacing) maxSize /= 2; return true; } else { - if (orient == QGraphicsAnchorLayoutPrivate::Horizontal) { + if (orientation == QGraphicsAnchorLayoutPrivate::Horizontal) { policy = item->sizePolicy().horizontalPolicy(); minSizeHint = item->effectiveSizeHint(Qt::MinimumSize).width(); prefSizeHint = item->effectiveSizeHint(Qt::PreferredSize).width(); @@ -1285,9 +1282,11 @@ void QGraphicsAnchorLayoutPrivate::addAnchor_helper(QGraphicsLayoutItem *firstIt { Q_Q(QGraphicsAnchorLayout); + const Orientation orientation = edgeOrientation(firstEdge); + // Guarantee that the graph is no simplified when adding this anchor, // anchor manipulation always happen in the full graph - restoreSimplifiedGraph(edgeOrientation(firstEdge)); + restoreSimplifiedGraph(orientation); // Is the Vertex (firstItem, firstEdge) already represented in our // internal structure? @@ -1296,7 +1295,7 @@ void QGraphicsAnchorLayoutPrivate::addAnchor_helper(QGraphicsLayoutItem *firstIt // Remove previous anchor // ### Could we update the existing edgeData rather than creating a new one? - if (graph[edgeOrientation(firstEdge)].edgeData(v1, v2)) { + if (graph[orientation].edgeData(v1, v2)) { removeAnchor_helper(v1, v2); } @@ -1304,6 +1303,8 @@ void QGraphicsAnchorLayoutPrivate::addAnchor_helper(QGraphicsLayoutItem *firstIt if (firstItem == secondItem) data->item = firstItem; + data->orientation = orientation; + // Create a bi-directional edge in the sense it can be transversed both // from v1 or v2. "data" however is shared between the two references // so we still know that the anchor direction is from 1 to 2. @@ -1315,7 +1316,7 @@ void QGraphicsAnchorLayoutPrivate::addAnchor_helper(QGraphicsLayoutItem *firstIt // Keep track of anchors that are connected to the layout 'edges' data->isLayoutAnchor = (v1->m_item == q || v2->m_item == q); - graph[edgeOrientation(firstEdge)].createEdge(v1, v2, data); + graph[orientation].createEdge(v1, v2, data); } QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::getAnchor(QGraphicsLayoutItem *firstItem, @@ -1480,7 +1481,7 @@ void QGraphicsAnchorLayoutPrivate::anchorSize(const AnchorData *data, Q_ASSERT(minSize || prefSize || maxSize); Q_ASSERT(data); QGraphicsAnchorLayoutPrivate *that = const_cast(this); - that->restoreSimplifiedGraph(edgeOrientation(data->from->m_edge)); + that->restoreSimplifiedGraph(Orientation(data->orientation)); if (minSize) *minSize = data->minSize; diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 511e1ec..8525eb3 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -157,7 +157,7 @@ struct AnchorData : public QSimplexVariable { sizeAtExpanding(0), sizeAtMaximum(0), graphicsAnchor(0), skipInPreferred(0), type(Normal), hasSize(true), isLayoutAnchor(false), - isCenterAnchor(false) {} + isCenterAnchor(false), orientation(0) {} virtual void updateChildrenSizes() {} virtual bool refreshSizeHints(qreal effectiveSpacing); @@ -211,6 +211,7 @@ struct AnchorData : public QSimplexVariable { uint hasSize : 1; // if false, get size from style. uint isLayoutAnchor : 1; // if this anchor is connected to a layout 'edge' uint isCenterAnchor : 1; + uint orientation : 1; }; #ifdef QT_DEBUG -- cgit v0.12 From a79539b1364fa8c155c5fbd00a977ae40b24acbe Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Mon, 19 Oct 2009 16:17:35 -0300 Subject: QGAL: clarify the usage of isLayoutAnchor bit The 'isLayoutAnchor' is necessary only as a way to flag Layout internal anchors, i.e. anchors with the Layout as 'item' in the AnchorData structure. We don't need to propagate this bit when composing anchors. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Eduardo M. Fleury --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 13 +++---------- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 2 +- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 41e067c..7dbfba9 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -527,8 +527,6 @@ static AnchorData *addAnchorMaybeParallel(Graph *g, // anchor. if (AnchorData *oldAnchor = g->takeEdge(newAnchor->from, newAnchor->to)) { ParallelAnchorData *parallel = new ParallelAnchorData(oldAnchor, newAnchor); - parallel->isLayoutAnchor = (oldAnchor->isLayoutAnchor - || newAnchor->isLayoutAnchor); // At this point we can identify that the parallel anchor is not feasible, e.g. one // anchor minimum size is bigger than the other anchor maximum size. @@ -596,12 +594,6 @@ static AnchorData *createSequence(Graph *graph, sequence->refreshSizeHints_helper(0, false); - // Note that since layout 'edges' can't be simplified away from - // the graph, it's safe to assume that if there's a layout - // 'edge', it'll be in the boundaries of the sequence. - sequence->isLayoutAnchor = (sequence->m_edges.first()->isLayoutAnchor - || sequence->m_edges.last()->isLayoutAnchor); - return sequence; } @@ -1313,8 +1305,9 @@ void QGraphicsAnchorLayoutPrivate::addAnchor_helper(QGraphicsLayoutItem *firstIt #ifdef QT_DEBUG data->name = QString::fromAscii("%1 --to--> %2").arg(v1->toString()).arg(v2->toString()); #endif - // Keep track of anchors that are connected to the layout 'edges' - data->isLayoutAnchor = (v1->m_item == q || v2->m_item == q); + // ### bit to track internal anchors, since inside AnchorData methods + // we don't have access to the 'q' pointer. + data->isLayoutAnchor = (data->item == q); graph[orientation].createEdge(v1, v2, data); } diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 8525eb3..8eb65c5 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -209,7 +209,7 @@ struct AnchorData : public QSimplexVariable { uint skipInPreferred : 1; uint type : 2; // either Normal, Sequential or Parallel uint hasSize : 1; // if false, get size from style. - uint isLayoutAnchor : 1; // if this anchor is connected to a layout 'edge' + uint isLayoutAnchor : 1; // if this anchor is an internal layout anchor uint isCenterAnchor : 1; uint orientation : 1; }; -- cgit v0.12 From dc89e929d0f60e996c132e9484357e0b42f99436 Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Fri, 16 Oct 2009 16:09:28 -0300 Subject: QGAL: Use constraints of type "equal" for fixed items We usually create two restrictions for each item, one to tell its size should be more than its minimum size and other enforcing it to be at most its maximum size. Now, for items that have fixed size, ie. minSize == maxSize, we create a single constraint telling its size should be equal its min/maxSize. The immediate advantage is to have one less constraint for each of these items. The indirect advantage is that the simplex solver can take advantage of such information. Signed-off-by: Eduardo M. Fleury Reviewed-by: Caio Marcelo de Oliveira Filho --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 34 +++++++++++++++--------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 7dbfba9..a83e619 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -2032,17 +2032,27 @@ QList QGraphicsAnchorLayoutPrivate::constraintsFromSizeHin { QList anchorConstraints; for (int i = 0; i < anchors.size(); ++i) { - QSimplexConstraint *c = new QSimplexConstraint; - c->variables.insert(anchors[i], 1.0); - c->constant = anchors[i]->minSize; - c->ratio = QSimplexConstraint::MoreOrEqual; - anchorConstraints += c; - - c = new QSimplexConstraint; - c->variables.insert(anchors[i], 1.0); - c->constant = anchors[i]->maxSize; - c->ratio = QSimplexConstraint::LessOrEqual; - anchorConstraints += c; + AnchorData *ad = anchors[i]; + + if ((ad->minSize == ad->maxSize) || qFuzzyCompare(ad->minSize, ad->maxSize)) { + QSimplexConstraint *c = new QSimplexConstraint; + c->variables.insert(ad, 1.0); + c->constant = ad->minSize; + c->ratio = QSimplexConstraint::Equal; + anchorConstraints += c; + } else { + QSimplexConstraint *c = new QSimplexConstraint; + c->variables.insert(ad, 1.0); + c->constant = ad->minSize; + c->ratio = QSimplexConstraint::MoreOrEqual; + anchorConstraints += c; + + c = new QSimplexConstraint; + c->variables.insert(ad, 1.0); + c->constant = ad->maxSize; + c->ratio = QSimplexConstraint::LessOrEqual; + anchorConstraints += c; + } } return anchorConstraints; @@ -2608,7 +2618,7 @@ void QGraphicsAnchorLayoutPrivate::solveExpanding(const QListsizeAtMaximum) { + if (boundedExpSize == ad->sizeAtMaximum || qFuzzyCompare(boundedExpSize, ad->sizeAtMaximum)) { // The interval has only one possible value, we can use an "Equal" // constraint and don't need to add this variable to the objective. QSimplexConstraint *itemC = new QSimplexConstraint; -- cgit v0.12 From 3f29c77a26d0a898ca3a7c9c6715da90f1ecc50a Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Fri, 16 Oct 2009 16:10:29 -0300 Subject: QGAL: Add QSimplexConstraint::toString() method for debugging Signed-off-by: Eduardo M. Fleury Reviewed-by: Caio Marcelo de Oliveira Filho --- src/gui/graphicsview/qsimplex_p.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/gui/graphicsview/qsimplex_p.h b/src/gui/graphicsview/qsimplex_p.h index 51991a9..423f9bc 100644 --- a/src/gui/graphicsview/qsimplex_p.h +++ b/src/gui/graphicsview/qsimplex_p.h @@ -118,6 +118,29 @@ struct QSimplexConstraint return false; } } + + QString toString() { + QString result; + result += QString::fromAscii("-- QSimplexConstraint %1 --").arg(int(this), 0, 16); + + QHash::const_iterator iter; + for (iter = variables.constBegin(); iter != variables.constEnd(); ++iter) { + result += QString::fromAscii(" %1 x %2").arg(iter.value()).arg(int(iter.key()), 0, 16); + } + + switch (ratio) { + case LessOrEqual: + result += QString::fromAscii(" (less) <= %1").arg(constant); + break; + case MoreOrEqual: + result += QString::fromAscii(" (more) >= %1").arg(constant); + break; + default: + result += QString::fromAscii(" (eqal) == %1").arg(constant); + } + + return result; + } #endif }; -- cgit v0.12 From fa767bf7b104a4e44e4e283522f0dfd942094375 Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Tue, 20 Oct 2009 18:54:43 -0300 Subject: QGAL (QSimplex): Make deep copy of constraints inside QSimplex The idea is to allow QSimplex solver to modify the constraints without breaking other parts of the code that rely on the original ones. Signed-off-by: Eduardo M. Fleury Reviewed-by: Caio Marcelo de Oliveira Filho --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 2 +- src/gui/graphicsview/qsimplex_p.cpp | 15 +++++++++++---- src/gui/graphicsview/qsimplex_p.h | 8 +------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index a83e619..b4666c6 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -2459,7 +2459,7 @@ bool QGraphicsAnchorLayoutPrivate::solveMinMax(const QList *min = simplex.solveMin(); // Save sizeAtMinimum results - QList variables = simplex.constraintsVariables(); + QList variables = getVariables(constraints); for (int i = 0; i < variables.size(); ++i) { AnchorData *ad = static_cast(variables[i]); Q_ASSERT(ad->result >= ad->minSize || qFuzzyCompare(ad->result, ad->minSize)); diff --git a/src/gui/graphicsview/qsimplex_p.cpp b/src/gui/graphicsview/qsimplex_p.cpp index b8f8fb4..b3997fa 100644 --- a/src/gui/graphicsview/qsimplex_p.cpp +++ b/src/gui/graphicsview/qsimplex_p.cpp @@ -108,10 +108,8 @@ void QSimplex::clearDataStructures() // Constraints for (int i = 0; i < constraints.size(); ++i) { delete constraints[i]->helper.first; - constraints[i]->helper.first = 0; - constraints[i]->helper.second = 0.0; delete constraints[i]->artificial; - constraints[i]->artificial = 0; + delete constraints[i]; } constraints.clear(); @@ -137,7 +135,16 @@ bool QSimplex::setConstraints(const QList newConstraints) if (newConstraints.isEmpty()) return true; // we are ok with no constraints - constraints = newConstraints; + + // Make deep copy of constraints. We need this copy because we may change + // them in the simplification method. + for (int i = 0; i < newConstraints.size(); ++i) { + QSimplexConstraint *c = new QSimplexConstraint; + c->constant = newConstraints[i]->constant; + c->ratio = newConstraints[i]->ratio; + c->variables = newConstraints[i]->variables; + constraints << c; + } /////////////////////////////////////// // Prepare variables and constraints // diff --git a/src/gui/graphicsview/qsimplex_p.h b/src/gui/graphicsview/qsimplex_p.h index 423f9bc..5ec13c3 100644 --- a/src/gui/graphicsview/qsimplex_p.h +++ b/src/gui/graphicsview/qsimplex_p.h @@ -106,7 +106,7 @@ struct QSimplexConstraint Q_ASSERT(constant > 0 || qFuzzyCompare(1, 1 + constant)); - if (qFuzzyCompare(1000 + leftHandSide, 1000 + constant)) + if ((leftHandSide == constant) || qFuzzyCompare(1000 + leftHandSide, 1000 + constant)) return true; switch (ratio) { @@ -152,7 +152,6 @@ public: qreal solveMin(); qreal solveMax(); - QList constraintsVariables(); bool setConstraints(const QList constraints); void setObjective(QSimplexConstraint *objective); @@ -191,11 +190,6 @@ private: qreal *matrix; }; -inline QList QSimplex::constraintsVariables() -{ - return variables; -} - inline qreal QSimplex::valueAt(int rowIndex, int columnIndex) { return matrix[rowIndex * columns + columnIndex]; -- cgit v0.12 From b14a16ce149fe9bc0e4ab66d946eb90416bd4a88 Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Fri, 16 Oct 2009 16:10:52 -0300 Subject: QGAL (QSimplex): Add constraints simplification Now the simplex solver is able to remove fixed variables from its constraints as to improve its running time. The simplification consists of two actions that are done iteratively until no possible changes exist: 1st) Look for constraints of type Var == Constant Save constant as the trivial value of Var 2nd) Substitute known results in existing constraints Signed-off-by: Eduardo M. Fleury Reviewed-by: Caio Marcelo de Oliveira Filho --- src/gui/graphicsview/qsimplex_p.cpp | 96 ++++++++++++++++++++++++++++++++++++- src/gui/graphicsview/qsimplex_p.h | 7 ++- 2 files changed, 99 insertions(+), 4 deletions(-) diff --git a/src/gui/graphicsview/qsimplex_p.cpp b/src/gui/graphicsview/qsimplex_p.cpp index b3997fa..86b10b4 100644 --- a/src/gui/graphicsview/qsimplex_p.cpp +++ b/src/gui/graphicsview/qsimplex_p.cpp @@ -146,6 +146,13 @@ bool QSimplex::setConstraints(const QList newConstraints) constraints << c; } + // Remove constraints of type Var == K and replace them for their value. + if (!simplifyConstraints(&constraints)) { + qWarning() << "QSimplex: No feasible solution!"; + clearDataStructures(); + return false; + } + /////////////////////////////////////// // Prepare variables and constraints // /////////////////////////////////////// @@ -515,11 +522,21 @@ qreal QSimplex::solver(solverFactor factor) // Remove old objective clearRow(0); - // Set new objective + // Set new objective in the first row of the simplex matrix + qreal resultOffset = 0; QHash::const_iterator iter; for (iter = objective->variables.constBegin(); iter != objective->variables.constEnd(); ++iter) { + + // Check if the variable was removed in the simplification process. + // If so, we save its offset to the objective function and skip adding + // it to the matrix. + if (iter.key()->index == -1) { + resultOffset += iter.value() * iter.key()->result; + continue; + } + setValueAt(0, iter.key()->index, -1 * factor * iter.value()); } @@ -532,7 +549,9 @@ qreal QSimplex::solver(solverFactor factor) } #endif - return factor * valueAt(0, columns - 1); + // Return the value calculated by the simplex plus the value of the + // fixed variables. + return (factor * valueAt(0, columns - 1)) + resultOffset; } /*! @@ -578,4 +597,77 @@ void QSimplex::collectResults() } } +/*! + \internal + + Looks for single-valued variables and remove them from the constraints list. +*/ +bool QSimplex::simplifyConstraints(QList *constraints) +{ + QHash results; // List of single-valued variables + bool modified = true; // Any chance more optimization exists? + + while (modified) { + modified = false; + + // For all constraints + QList::iterator iter = constraints->begin(); + while (iter != constraints->end()) { + QSimplexConstraint *c = *iter; + if ((c->ratio == QSimplexConstraint::Equal) && (c->variables.count() == 1)) { + // Check whether this is a constraint of type Var == K + // If so, save its value to "results". + QSimplexVariable *variable = c->variables.constBegin().key(); + qreal result = c->constant / c->variables.value(variable); + + results.insert(variable, result); + variable->result = result; + variable->index = -1; + modified = true; + + } + + // Replace known values among their variables + QHash::const_iterator r; + for (r = results.constBegin(); r != results.constEnd(); ++r) { + if (c->variables.contains(r.key())) { + c->constant -= r.value() * c->variables.take(r.key()); + modified = true; + } + } + + // Keep it normalized + if (c->constant < 0) + c->invert(); + + if (c->variables.isEmpty()) { + // If constraint became empty due to substitution, delete it. + if (c->isSatisfied() == false) + // We must ensure that the constraint soon to be deleted would not + // make the problem unfeasible if left behind. If that's the case, + // we return false so the simplex solver can properly report that. + return false; + + delete c; + iter = constraints->erase(iter); + } else { + ++iter; + } + } + } + + return true; +} + +void QSimplexConstraint::invert() +{ + constant = -constant; + ratio = Ratio(2 - ratio); + + QHash::iterator iter; + for (iter = variables.begin(); iter != variables.end(); ++iter) { + iter.value() = -iter.value(); + } +} + QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qsimplex_p.h b/src/gui/graphicsview/qsimplex_p.h index 5ec13c3..66ea739 100644 --- a/src/gui/graphicsview/qsimplex_p.h +++ b/src/gui/graphicsview/qsimplex_p.h @@ -63,7 +63,7 @@ struct QSimplexVariable QSimplexVariable() : result(0), index(0) {} qreal result; - uint index; + int index; }; @@ -95,7 +95,8 @@ struct QSimplexConstraint QPair helper; QSimplexVariable * artificial; -#ifdef QT_DEBUG + void invert(); + bool isSatisfied() { qreal leftHandSide(0); @@ -119,6 +120,7 @@ struct QSimplexConstraint } } +#ifdef QT_DEBUG QString toString() { QString result; result += QString::fromAscii("-- QSimplexConstraint %1 --").arg(int(this), 0, 16); @@ -167,6 +169,7 @@ private: void combineRows(int toIndex, int fromIndex, qreal factor); // Simplex + bool simplifyConstraints(QList *constraints); int findPivotColumn(); int pivotRowForColumn(int column); void reducedRowEchelon(); -- cgit v0.12 From 1607216cc6292ef9a4af68ce6d29dc79fffea92c Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Mon, 26 Oct 2009 16:55:20 -0300 Subject: QGAL: Add test for David Boddie bug The current simplification code does not handle sequences with anchors pointed to different directions could not be simplified together into a sequential anchor. A (10 / 20 / 50 ) B (20 / 20 / 20) Ex: o-----------------> <----------------o The reason we don't support it yet is shown in the example above. The resulting anchor would be either: Result_1 (-10 / 0 / 30) o------------------------------------> (or) Result_2 (-30 / 0 / 10) <------------------------------------o But the current implementation assumes no anchors can have negative sizes. Hopefully, the next commits will add support for it and then enable such simplification. :-) Signed-off-by: Eduardo M. Fleury --- .../tst_qgraphicsanchorlayout.cpp | 46 ++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index facc1ef..5348e59 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -83,6 +83,7 @@ private slots: void floatConflict(); void infiniteMaxSizes(); void simplifiableUnfeasible(); + void simplificationVsOrder(); }; class RectWidget : public QGraphicsWidget @@ -1806,5 +1807,50 @@ void tst_QGraphicsAnchorLayout::simplifiableUnfeasible() QVERIFY(!usedSimplex(l, Qt::Horizontal)); } +/* + Test whether the anchor direction can prevent it from + being simplificated +*/ +void tst_QGraphicsAnchorLayout::simplificationVsOrder() +{ + QSizeF min(10, 10); + QSizeF pref(20, 10); + QSizeF max(50, 10); + + QGraphicsWidget *a = createItem(min, pref, max); + QGraphicsWidget *b = createItem(min, pref, max); + QGraphicsWidget *c = createItem(min, pref, max); + + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; + + // Bulk anchors + l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft); + l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft); + l->addAnchor(b, Qt::AnchorLeft, c, Qt::AnchorLeft); + l->addAnchor(c, Qt::AnchorRight, l, Qt::AnchorRight); + + // Problematic anchor, direction b->c + QGraphicsAnchor *anchor = l->addAnchor(b, Qt::AnchorRight, c, Qt::AnchorRight); + anchor->setSpacing(5); + + l->effectiveSizeHint(Qt::MinimumSize); + if (hasSimplification) { + QCOMPARE(usedSimplex(l, Qt::Horizontal), false); + QCOMPARE(usedSimplex(l, Qt::Vertical), false); + } + + // Problematic anchor, direction c->b + delete anchor; + anchor = l->addAnchor(c, Qt::AnchorRight, b, Qt::AnchorRight); + anchor->setSpacing(5); + + l->effectiveSizeHint(Qt::MinimumSize); + if (hasSimplification) { + QEXPECT_FAIL("", "Sequential anchors cannot handle children of opposite directions", Continue); + QCOMPARE(usedSimplex(l, Qt::Horizontal), false); + QCOMPARE(usedSimplex(l, Qt::Vertical), false); + } +} + QTEST_MAIN(tst_QGraphicsAnchorLayout) #include "tst_qgraphicsanchorlayout.moc" -- cgit v0.12 From 68ab3b34571cfdde4002de9982388f9eec4d9939 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 26 Oct 2009 15:54:18 +0100 Subject: Fixed a bug in QMenuBar in RTL that would display menu at the wrong place This could happen when adding actions in response to the aboutToShow signal. Task-number: QT-2596 Reviewed-by: ogoffart --- src/gui/widgets/qmenu.cpp | 4 ++++ src/gui/widgets/qmenubar.cpp | 29 ++++++++++++----------------- tests/auto/qmenubar/tst_qmenubar.cpp | 29 ++++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index ea25901..1b5d1cd 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -1878,6 +1878,10 @@ void QMenu::popup(const QPoint &p, QAction *atAction) if(snapToMouse) //position flowing left from the mouse pos.setX(mouse.x()-size.width()); + //if in a menubar, it should be right-aligned + if (qobject_cast(d->causedPopup.widget)) + pos.rx() -= size.width(); + if (pos.x() < screen.left()+desktopFrame) pos.setX(qMax(p.x(), screen.left()+desktopFrame)); if (pos.x()+size.width()-1 > screen.right()-desktopFrame) diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp index f2f0722..689d2e1 100644 --- a/src/gui/widgets/qmenubar.cpp +++ b/src/gui/widgets/qmenubar.cpp @@ -336,30 +336,25 @@ void QMenuBarPrivate::popupAction(QAction *action, bool activateFirst) const bool fitUp = (q->mapToGlobal(adjustedActionRect.topLeft()).y() >= popup_size.height()); const bool fitDown = (pos.y() + popup_size.height() <= screenRect.bottom()); + const bool rtl = q->isRightToLeft(); const int actionWidth = adjustedActionRect.width(); if (!fitUp && !fitDown) { //we should shift the menu - bool shouldShiftToRight = !q->isRightToLeft(); - if (q->isRightToLeft() && popup_size.width() > pos.x()) + bool shouldShiftToRight = !rtl; + if (rtl && popup_size.width() > pos.x()) shouldShiftToRight = true; else if (actionWidth + popup_size.width() + pos.x() > screenRect.right()) shouldShiftToRight = false; - if (shouldShiftToRight) - pos.rx() += actionWidth; - else - pos.rx() -= popup_size.width(); - } else if (q->isRightToLeft()) { - pos.setX(pos.x()-(popup_size.width() - actionWidth)); - } - - if(pos.x() < screenRect.x()) { - pos.setX(screenRect.x()); - } else { - const int off = pos.x()+popup_size.width() - screenRect.right(); - if(off > 0) - pos.setX(qMax(screenRect.x(), pos.x()-off)); - + if (shouldShiftToRight) { + pos.rx() += actionWidth + (rtl ? popup_size.width() : 0); + } else { + //shift to left + if (!rtl) + pos.rx() -= popup_size.width(); + } + } else if (rtl) { + pos.rx() += actionWidth; } if(!defaultPopDown || (fitUp && !fitDown)) diff --git a/tests/auto/qmenubar/tst_qmenubar.cpp b/tests/auto/qmenubar/tst_qmenubar.cpp index 07aa9f4..4291c3e 100644 --- a/tests/auto/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/qmenubar/tst_qmenubar.cpp @@ -86,6 +86,18 @@ private: uint sel_count; }; +class Menu : public QMenu +{ + Q_OBJECT + public slots: + void addActions() + { + //this will change the geometry of the menu + addAction("action1"); + addAction("action2"); + } +}; + class tst_QMenuBar : public QObject { Q_OBJECT @@ -1442,7 +1454,7 @@ void tst_QMenuBar::check_menuPosition() #ifdef Q_OS_WINCE_WM QSKIP("Qt/CE uses native menubar", SkipAll); #endif - QMenu menu; + Menu menu; #ifdef QT3_SUPPORT initComplexMenubar(); #else @@ -1496,6 +1508,21 @@ void tst_QMenuBar::check_menuPosition() menu.close(); } + //in RTL, the menu should be stuck at the right of the action geometry + { + Qt::LayoutDirection dir = qApp->layoutDirection(); + qApp->setLayoutDirection(Qt::RightToLeft); + menu.clear(); + QObject::connect(&menu, SIGNAL(aboutToShow()), &menu, SLOT(addActions())); + QRect mbItemRect = mw->menuBar()->actionGeometry(menu_action); + mbItemRect.moveTo(mw->menuBar()->mapToGlobal(mbItemRect.topLeft())); + QTest::keyClick(mw, Qt::Key_M, Qt::AltModifier ); + QVERIFY(menu.isActiveWindow()); + QCOMPARE(menu.geometry().right(), mbItemRect.right()); + menu.close(); + qApp->setLayoutDirection(dir); + } + } void tst_QMenuBar::task223138_triggered() -- cgit v0.12 From 0f6ab9612eba6c5418991443b65a10820d6b5a1f Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Tue, 27 Oct 2009 09:56:28 +0100 Subject: Stabilize sequential animation startDelay autotest on win Reviewed-by: thierry --- .../tst_qsequentialanimationgroup.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp b/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp index aa6801a..f6afc5b 100644 --- a/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp +++ b/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp @@ -929,16 +929,13 @@ void tst_QSequentialAnimationGroup::startDelay() group.addPause(125); QCOMPARE(group.totalDuration(), 375); - QEventLoop loop; - QObject::connect(&group, SIGNAL(finished()), &loop, SLOT(quit())); - - QTime time; - time.start(); group.start(); - loop.exec(); + QCOMPARE(group.state(), QAnimationGroup::Running); - QVERIFY(time.elapsed() >= 375); - QVERIFY(time.elapsed() < 1000); + QTest::qWait(500); + + QVERIFY(group.currentTime() == 375); + QCOMPARE(group.state(), QAnimationGroup::Stopped); } void tst_QSequentialAnimationGroup::clearGroup() -- cgit v0.12 From dd89851abe4b0d0a3c293b5cadace00eb3f75a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Tue, 27 Oct 2009 11:01:45 +0100 Subject: If a QGraphicsWidget gets a StyleChange event, invalidate its layout. The layout should be invalidated because all layouts are dependent on some style-specific defaults. (e.g. PM_LayoutHorizontalSpacing can differ.) Reviewed-by: alexis --- src/gui/graphicsview/qgraphicswidget.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 35a3c13..d70a281 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -1352,6 +1352,8 @@ void QGraphicsWidget::changeEvent(QEvent *event) case QEvent::StyleChange: // ### Don't unset if the margins are explicitly set. unsetWindowFrameMargins(); + if (d->layout) + d->layout->invalidate(); case QEvent::FontChange: update(); updateGeometry(); -- cgit v0.12 From 8a9ab43e572443eefbf19d59740fdc64d25d1005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Tue, 27 Oct 2009 11:54:47 +0100 Subject: Respect the per-item layoutSpacing() if the style uses that feature. We move the QLayoutStyleInfo class out of the gridlayout engine to a common header file so that anchor layout also can utilize it. Due to that we now can have a per-item spacing we have to change the 'effectiveSpacing' argument of refreshSizeHints to just take a QLayoutStyleInfo pointer that we will later query for the actual spacing used. --- src/gui/graphicsview/qgraphicsanchorlayout.cpp | 7 +- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 78 +++++----- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 17 ++- src/gui/graphicsview/qgraphicslayout_p.h | 51 +++++++ src/gui/graphicsview/qgridlayoutengine_p.h | 25 +--- .../tst_qgraphicsanchorlayout.cpp | 162 +++++++++++++++++++++ 6 files changed, 271 insertions(+), 69 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp index 081572f..00d3478 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp @@ -400,7 +400,7 @@ void QGraphicsAnchorLayout::setSpacing(qreal spacing) qreal QGraphicsAnchorLayout::horizontalSpacing() const { Q_D(const QGraphicsAnchorLayout); - return d->effectiveSpacing(QGraphicsAnchorLayoutPrivate::Horizontal); + return d->styleInfo().defaultSpacing(Qt::Horizontal); } /*! @@ -411,7 +411,7 @@ qreal QGraphicsAnchorLayout::horizontalSpacing() const qreal QGraphicsAnchorLayout::verticalSpacing() const { Q_D(const QGraphicsAnchorLayout); - return d->effectiveSpacing(QGraphicsAnchorLayoutPrivate::Vertical); + return d->styleInfo().defaultSpacing(Qt::Vertical); } /*! @@ -481,7 +481,8 @@ void QGraphicsAnchorLayout::invalidate() { Q_D(QGraphicsAnchorLayout); QGraphicsLayout::invalidate(); - d->calculateGraphCacheDirty = 1; + d->calculateGraphCacheDirty = true; + d->styleInfoDirty = true; } /*! diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 8c8c303..5bc6708 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -141,7 +141,7 @@ static void internalSizeHints(QSizePolicy::Policy policy, *expSize = *prefSize; } -void AnchorData::refreshSizeHints(qreal effectiveSpacing) +void AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo) { const bool isInternalAnchor = from->m_item == to->m_item; @@ -196,7 +196,20 @@ void AnchorData::refreshSizeHints(qreal effectiveSpacing) // their effective size hints might be narrowed down due to their size policies. prefSizeHint = prefSize; } else { - prefSizeHint = effectiveSpacing; + const Qt::Orientation orient = Qt::Orientation(QGraphicsAnchorLayoutPrivate::edgeOrientation(from->m_edge) + 1); + qreal s = styleInfo->defaultSpacing(orient); + if (s < 0) { + QSizePolicy::ControlType controlTypeFrom = from->m_item->sizePolicy().controlType(); + QSizePolicy::ControlType controlTypeTo = to->m_item->sizePolicy().controlType(); + s = styleInfo->perItemSpacing(controlTypeFrom, controlTypeTo, orient); + + // ### Currently we do not support negative anchors inside the graph. + // To avoid those being created by a negative style spacing, we must + // make this test. + if (s < 0) + s = 0; + } + prefSizeHint = s; } maxSizeHint = QWIDGETSIZE_MAX; } @@ -227,17 +240,17 @@ void ParallelAnchorData::updateChildrenSizes() secondEdge->updateChildrenSizes(); } -void ParallelAnchorData::refreshSizeHints(qreal effectiveSpacing) +void ParallelAnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo) { - refreshSizeHints_helper(effectiveSpacing); + refreshSizeHints_helper(styleInfo); } -void ParallelAnchorData::refreshSizeHints_helper(qreal effectiveSpacing, +void ParallelAnchorData::refreshSizeHints_helper(const QLayoutStyleInfo *styleInfo, bool refreshChildren) { if (refreshChildren) { - firstEdge->refreshSizeHints(effectiveSpacing); - secondEdge->refreshSizeHints(effectiveSpacing); + firstEdge->refreshSizeHints(styleInfo); + secondEdge->refreshSizeHints(styleInfo); } // ### should we warn if the parallel connection is invalid? @@ -362,12 +375,12 @@ void SequentialAnchorData::updateChildrenSizes() } } -void SequentialAnchorData::refreshSizeHints(qreal effectiveSpacing) +void SequentialAnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo) { - refreshSizeHints_helper(effectiveSpacing); + refreshSizeHints_helper(styleInfo); } -void SequentialAnchorData::refreshSizeHints_helper(qreal effectiveSpacing, +void SequentialAnchorData::refreshSizeHints_helper(const QLayoutStyleInfo *styleInfo, bool refreshChildren) { minSize = 0; @@ -380,7 +393,7 @@ void SequentialAnchorData::refreshSizeHints_helper(qreal effectiveSpacing, // If it's the case refresh children information first if (refreshChildren) - edge->refreshSizeHints(effectiveSpacing); + edge->refreshSizeHints(styleInfo); minSize += edge->minSize; prefSize += edge->prefSize; @@ -458,7 +471,7 @@ QString GraphPath::toString() const #endif QGraphicsAnchorLayoutPrivate::QGraphicsAnchorLayoutPrivate() - : calculateGraphCacheDirty(1) + : calculateGraphCacheDirty(true), styleInfoDirty(true) { for (int i = 0; i < NOrientations; ++i) { for (int j = 0; j < 3; ++j) { @@ -1565,34 +1578,32 @@ void QGraphicsAnchorLayoutPrivate::correctEdgeDirection(QGraphicsLayoutItem *&fi } } -qreal QGraphicsAnchorLayoutPrivate::effectiveSpacing(Orientation orientation) const +QLayoutStyleInfo &QGraphicsAnchorLayoutPrivate::styleInfo() const { - Q_Q(const QGraphicsAnchorLayout); - qreal s = spacings[orientation]; - if (s < 0) { - // ### make sure behaviour is the same as in QGraphicsGridLayout + if (styleInfoDirty) { + Q_Q(const QGraphicsAnchorLayout); + //### Fix this if QGV ever gets support for Metal style or different Aqua sizes. + QWidget *wid = 0; + QGraphicsLayoutItem *parent = q->parentLayoutItem(); while (parent && parent->isLayout()) { parent = parent->parentLayoutItem(); } + QGraphicsWidget *w = 0; if (parent) { QGraphicsItem *parentItem = parent->graphicsItem(); - if (parentItem && parentItem->isWidget()) { - QGraphicsWidget *w = static_cast(parentItem); - s = w->style()->pixelMetric(orientation == Horizontal - ? QStyle::PM_LayoutHorizontalSpacing - : QStyle::PM_LayoutVerticalSpacing); - } + if (parentItem && parentItem->isWidget()) + w = static_cast(parentItem); } - } - // ### Currently we do not support negative anchors inside the graph. - // To avoid those being created by a negative style spacing, we must - // make this test. - if (s < 0) - s = 0; + QStyle *style = w ? w->style() : QApplication::style(); + cachedStyleInfo = QLayoutStyleInfo(style, wid); + cachedStyleInfo.setDefaultSpacing(Qt::Horizontal, spacings[0]); + cachedStyleInfo.setDefaultSpacing(Qt::Vertical, spacings[1]); - return s; + styleInfoDirty = false; + } + return cachedStyleInfo; } /*! @@ -1620,7 +1631,7 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs() dumpGraph(QString::fromAscii("%1-after").arg(count)); #endif - calculateGraphCacheDirty = 0; + calculateGraphCacheDirty = false; } // ### Maybe getGraphParts could return the variables when traversing, at least @@ -1847,12 +1858,11 @@ void QGraphicsAnchorLayoutPrivate::setAnchorSizeHintsFromItems(Orientation orien Graph &g = graph[orientation]; QList > vertices = g.connections(); - qreal spacing = effectiveSpacing(orientation); - + QLayoutStyleInfo styleInf = styleInfo(); for (int i = 0; i < vertices.count(); ++i) { AnchorData *data = g.edgeData(vertices.at(i).first, vertices.at(i).second);; Q_ASSERT(data->from && data->to); - data->refreshSizeHints(spacing); + data->refreshSizeHints(&styleInf); } } diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index d45c004..9b7d41e 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -159,7 +159,7 @@ struct AnchorData : public QSimplexVariable { type(Normal), hasSize(true), isLayoutAnchor(false) {} virtual void updateChildrenSizes() {} - virtual void refreshSizeHints(qreal effectiveSpacing); + virtual void refreshSizeHints(const QLayoutStyleInfo *styleInfo); virtual ~AnchorData() {} @@ -226,9 +226,9 @@ struct SequentialAnchorData : public AnchorData } virtual void updateChildrenSizes(); - virtual void refreshSizeHints(qreal effectiveSpacing); + virtual void refreshSizeHints(const QLayoutStyleInfo *styleInfo); - void refreshSizeHints_helper(qreal effectiveSpacing, bool refreshChildren = true); + void refreshSizeHints_helper(const QLayoutStyleInfo *styleInfo, bool refreshChildren = true); void setVertices(const QVector &vertices) { @@ -261,9 +261,9 @@ struct ParallelAnchorData : public AnchorData } virtual void updateChildrenSizes(); - virtual void refreshSizeHints(qreal effectiveSpacing); + virtual void refreshSizeHints(const QLayoutStyleInfo *styleInfo); - void refreshSizeHints_helper(qreal effectiveSpacing, bool refreshChildren = true); + void refreshSizeHints_helper(const QLayoutStyleInfo *styleInfo, bool refreshChildren = true); AnchorData* firstEdge; AnchorData* secondEdge; @@ -423,9 +423,8 @@ public: Qt::AnchorPoint &firstEdge, QGraphicsLayoutItem *&secondItem, Qt::AnchorPoint &secondEdge); - // for getting the actual spacing (will query the style if the - // spacing is not explicitly set). - qreal effectiveSpacing(Orientation orientation) const; + + QLayoutStyleInfo &styleInfo() const; // Activation methods void simplifyGraph(Orientation orientation); @@ -524,6 +523,8 @@ public: #endif uint calculateGraphCacheDirty : 1; + mutable uint styleInfoDirty : 1; + mutable QLayoutStyleInfo cachedStyleInfo; friend class QGraphicsAnchorPrivate; }; diff --git a/src/gui/graphicsview/qgraphicslayout_p.h b/src/gui/graphicsview/qgraphicslayout_p.h index 59c6dba..4aeae39 100644 --- a/src/gui/graphicsview/qgraphicslayout_p.h +++ b/src/gui/graphicsview/qgraphicslayout_p.h @@ -60,6 +60,8 @@ #include "qgraphicslayout.h" #include "qgraphicslayoutitem_p.h" #include +#include +#include QT_BEGIN_NAMESPACE @@ -76,6 +78,55 @@ inline bool qt_graphicsLayoutDebug() } #endif + +class QLayoutStyleInfo +{ +public: + inline QLayoutStyleInfo() { invalidate(); } + inline QLayoutStyleInfo(QStyle *style, QWidget *widget) + : m_valid(true), m_style(style), m_widget(widget) + { + Q_ASSERT(style); + if (widget) //### + m_styleOption.initFrom(widget); + m_defaultSpacing[0] = style->pixelMetric(QStyle::PM_LayoutHorizontalSpacing); + m_defaultSpacing[1] = style->pixelMetric(QStyle::PM_LayoutVerticalSpacing); + } + + inline void invalidate() { m_valid = false; m_style = 0; m_widget = 0; } + + inline QStyle *style() const { return m_style; } + inline QWidget *widget() const { return m_widget; } + + inline bool operator==(const QLayoutStyleInfo &other) + { return m_style == other.m_style && m_widget == other.m_widget; } + inline bool operator!=(const QLayoutStyleInfo &other) + { return !(*this == other); } + + inline void setDefaultSpacing(Qt::Orientation o, qreal spacing){ + if (spacing >= 0) + m_defaultSpacing[o - 1] = spacing; + } + + inline qreal defaultSpacing(Qt::Orientation o) const { + return m_defaultSpacing[o - 1]; + } + + inline qreal perItemSpacing(QSizePolicy::ControlType control1, + QSizePolicy::ControlType control2, + Qt::Orientation orientation) const + { + Q_ASSERT(style()); + return style()->layoutSpacing(control1, control2, orientation, &m_styleOption, widget()); + } +private: + bool m_valid; + QStyle *m_style; + QWidget *m_widget; + QStyleOption m_styleOption; + qreal m_defaultSpacing[2]; +}; + class Q_AUTOTEST_EXPORT QGraphicsLayoutPrivate : public QGraphicsLayoutItemPrivate { Q_DECLARE_PUBLIC(QGraphicsLayout) diff --git a/src/gui/graphicsview/qgridlayoutengine_p.h b/src/gui/graphicsview/qgridlayoutengine_p.h index a42a537..ed335a8 100644 --- a/src/gui/graphicsview/qgridlayoutengine_p.h +++ b/src/gui/graphicsview/qgridlayoutengine_p.h @@ -59,7 +59,7 @@ #include "qmap.h" #include "qpair.h" #include "qvector.h" - +#include "qgraphicslayout_p.h" #include QT_BEGIN_NAMESPACE @@ -128,29 +128,6 @@ public: }; -class QLayoutStyleInfo -{ -public: - inline QLayoutStyleInfo() { invalidate(); } - inline QLayoutStyleInfo(QStyle *style, QWidget *widget) - : q_valid(true), q_style(style), q_widget(widget) {} - - inline void invalidate() { q_valid = false; q_style = 0; q_widget = 0; } - - inline QStyle *style() const { return q_style; } - inline QWidget *widget() const { return q_widget; } - - inline bool operator==(const QLayoutStyleInfo &other) - { return q_style == other.q_style && q_widget == other.q_widget; } - inline bool operator!=(const QLayoutStyleInfo &other) - { return !(*this == other); } - -private: - bool q_valid; - QStyle *q_style; - QWidget *q_widget; -}; - class QGridLayoutBox { public: diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 7b87969..f6f1868 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -45,6 +45,7 @@ #include #include #include +#include class tst_QGraphicsAnchorLayout : public QObject { Q_OBJECT; @@ -72,6 +73,7 @@ private slots: void proportionalPreferred(); void example(); void setSpacing(); + void styleDefaults(); void hardComplexS60(); void stability(); void delete_anchor(); @@ -1102,6 +1104,166 @@ void tst_QGraphicsAnchorLayout::setSpacing() delete view; } +class CustomLayoutStyle : public QWindowsStyle +{ + Q_OBJECT +public: + CustomLayoutStyle() : QWindowsStyle() + { + hspacing = 5; + vspacing = 10; + } + + virtual int pixelMetric(PixelMetric metric, const QStyleOption * option = 0, + const QWidget * widget = 0 ) const; + + int hspacing; + int vspacing; + +protected slots: + int layoutSpacingImplementation(QSizePolicy::ControlType control1, + QSizePolicy::ControlType control2, + Qt::Orientation orientation, + const QStyleOption *option = 0, + const QWidget *widget = 0) const; + +}; + +#define CT1(c) CT2(c, c) +#define CT2(c1, c2) ((uint)c1 << 16) | (uint)c2 + +int CustomLayoutStyle::layoutSpacingImplementation(QSizePolicy::ControlType control1, + QSizePolicy::ControlType control2, + Qt::Orientation orientation, + const QStyleOption * /*option = 0*/, + const QWidget * /*widget = 0*/) const +{ + if (orientation == Qt::Horizontal) { + switch (CT2(control1, control2)) { + case CT1(QSizePolicy::PushButton): + return 2; + break; + } + return 5; + } else { + switch (CT2(control1, control2)) { + case CT1(QSizePolicy::RadioButton): + return 2; + break; + + } + return 10; + } +} + +int CustomLayoutStyle::pixelMetric(PixelMetric metric, const QStyleOption * option /*= 0*/, + const QWidget * widget /*= 0*/ ) const +{ + switch (metric) { + case PM_LayoutLeftMargin: + return 0; + break; + case PM_LayoutTopMargin: + return 3; + break; + case PM_LayoutRightMargin: + return 6; + break; + case PM_LayoutBottomMargin: + return 9; + break; + case PM_LayoutHorizontalSpacing: + return hspacing; + case PM_LayoutVerticalSpacing: + return vspacing; + break; + default: + break; + } + return QWindowsStyle::pixelMetric(metric, option, widget); +} + +void tst_QGraphicsAnchorLayout::styleDefaults() +{ + QSizeF min (10, 10); + QSizeF pref(20, 20); + QSizeF max (50, 50); + + /* + create this layout, where a,b have controlType QSizePolicy::RadioButton + c,d have controlType QSizePolicy::PushButton: + +-------+ + |a | + | b | + | c | + | d| + +-------+ + */ + QGraphicsScene scene; + QGraphicsWidget *a = createItem(min, pref, max); + QSizePolicy spRadioButton = a->sizePolicy(); + spRadioButton.setControlType(QSizePolicy::RadioButton); + a->setSizePolicy(spRadioButton); + + QGraphicsWidget *b = createItem(min, pref, max); + b->setSizePolicy(spRadioButton); + + QGraphicsWidget *c = createItem(min, pref, max); + QSizePolicy spPushButton = c->sizePolicy(); + spPushButton.setControlType(QSizePolicy::PushButton); + c->setSizePolicy(spPushButton); + + QGraphicsWidget *d = createItem(min, pref, max); + d->setSizePolicy(spPushButton); + + QGraphicsWidget *window = new QGraphicsWidget(0, Qt::Window); + + // Test layoutSpacingImplementation + CustomLayoutStyle *style = new CustomLayoutStyle; + style->hspacing = -1; + style->vspacing = -1; + window->setStyle(style); + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; + + l->addCornerAnchors(l, Qt::TopLeftCorner, a, Qt::TopLeftCorner); + l->addCornerAnchors(a, Qt::BottomRightCorner, b, Qt::TopLeftCorner); + l->addCornerAnchors(b, Qt::BottomRightCorner, c, Qt::TopLeftCorner); + l->addCornerAnchors(c, Qt::BottomRightCorner, d, Qt::TopLeftCorner); + l->addCornerAnchors(d, Qt::BottomRightCorner, l, Qt::BottomRightCorner); + + window->setLayout(l); + + scene.addItem(window); + + window->show(); + QGraphicsView *view = new QGraphicsView(&scene); + view->resize(200, 200); + view->show(); + + window->adjustSize(); + QCOMPARE(a->geometry(), QRectF(0, 3, 20, 20)); //radio + QCOMPARE(b->geometry(), QRectF(25, 25, 20, 20)); //radio + QCOMPARE(c->geometry(), QRectF(50, 55, 20, 20)); //push + QCOMPARE(d->geometry(), QRectF(72, 85, 20, 20)); //push + QCOMPARE(l->geometry(), QRectF(0, 0, 98, 114)); + + + // Test pixelMetric(PM_Layout{Horizontal|Vertical}Spacing + window->setStyle(0); + + style->hspacing = 1; + style->vspacing = 2; + + window->setStyle(style); + window->adjustSize(); + QCOMPARE(a->geometry(), QRectF(0, 3, 20, 20)); + QCOMPARE(b->geometry(), QRectF(21, 25, 20, 20)); + QCOMPARE(c->geometry(), QRectF(42, 47, 20, 20)); + QCOMPARE(d->geometry(), QRectF(63, 69, 20, 20)); + QCOMPARE(l->geometry(), QRectF(0, 0, 89, 98)); +} + + /*! Taken from "hard" complex case, found at https://cwiki.nokia.com/S60QTUI/AnchorLayoutComplexCases -- cgit v0.12 From bc49cbaab3356770eb4b27dcbc2e585bf21e9200 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 27 Oct 2009 12:15:49 +0100 Subject: QTableView would not correctly resize to contents The problem was that we didn't call ensurePolished when getting the size of the sections. Task-number: QTBUG-1002 Reviewed-by: ogoffart --- src/gui/itemviews/qheaderview.cpp | 2 ++ src/gui/itemviews/qtableview.cpp | 4 ++++ tests/auto/qtableview/tst_qtableview.cpp | 11 ++++++----- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index fc9820f..4b5ec71 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -2516,6 +2516,8 @@ QSize QHeaderView::sectionSizeFromContents(int logicalIndex) const Q_D(const QHeaderView); Q_ASSERT(logicalIndex >= 0); + ensurePolished(); + // use SizeHintRole QVariant variant = d->model->headerData(logicalIndex, d->orientation, Qt::SizeHintRole); if (variant.isValid()) diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp index 2a937f1..c80faa2 100644 --- a/src/gui/itemviews/qtableview.cpp +++ b/src/gui/itemviews/qtableview.cpp @@ -2065,6 +2065,8 @@ int QTableView::sizeHintForRow(int row) const if (!model()) return -1; + ensurePolished(); + int left = qMax(0, columnAt(0)); int right = columnAt(d->viewport->width()); if (right == -1) // the table don't have enough columns to fill the viewport @@ -2122,6 +2124,8 @@ int QTableView::sizeHintForColumn(int column) const if (!model()) return -1; + ensurePolished(); + int top = qMax(0, rowAt(0)); int bottom = rowAt(d->viewport->height()); if (!isVisible() || bottom == -1) // the table don't have enough rows to fill the viewport diff --git a/tests/auto/qtableview/tst_qtableview.cpp b/tests/auto/qtableview/tst_qtableview.cpp index d8110e1..8f8781d 100644 --- a/tests/auto/qtableview/tst_qtableview.cpp +++ b/tests/auto/qtableview/tst_qtableview.cpp @@ -2017,8 +2017,9 @@ void tst_QTableView::resizeRowsToContents() view.resizeRowsToContents(); QCOMPARE(resizedSpy.count(), model.rowCount()); - for (int r = 0; r < model.rowCount(); ++r) + for (int r = 0; r < model.rowCount(); ++r) { QCOMPARE(view.rowHeight(r), rowHeight); + } } void tst_QTableView::resizeColumnsToContents_data() @@ -3267,12 +3268,12 @@ void tst_QTableView::resizeToContents() //now let's check the row/col sizes for(int i = 0;i Date: Tue, 27 Oct 2009 12:49:06 +0100 Subject: Designer: Fix potential crash when moving pages of a QTabWidget ... which has movable=true, conflicting with its internal drag and drop. Introduce 'movable' as fake property. Reviewed-by: Jarek Kobus Task-number: QT-1788 --- tools/designer/src/lib/shared/qdesigner_tabwidget.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/designer/src/lib/shared/qdesigner_tabwidget.cpp b/tools/designer/src/lib/shared/qdesigner_tabwidget.cpp index 2789bd3..f4f3d24 100644 --- a/tools/designer/src/lib/shared/qdesigner_tabwidget.cpp +++ b/tools/designer/src/lib/shared/qdesigner_tabwidget.cpp @@ -399,6 +399,7 @@ static const char *currentTabNameKey = "currentTabName"; static const char *currentTabIconKey = "currentTabIcon"; static const char *currentTabToolTipKey = "currentTabToolTip"; static const char *currentTabWhatsThisKey = "currentTabWhatsThis"; +static const char *tabMovableKey = "movable"; QTabWidgetPropertySheet::QTabWidgetPropertySheet(QTabWidget *object, QObject *parent) : QDesignerPropertySheet(object, parent), @@ -411,6 +412,8 @@ QTabWidgetPropertySheet::QTabWidgetPropertySheet(QTabWidget *object, QObject *pa formWindowBase()->addReloadableProperty(this, indexOf(QLatin1String(currentTabIconKey))); createFakeProperty(QLatin1String(currentTabToolTipKey), qVariantFromValue(qdesigner_internal::PropertySheetStringValue())); createFakeProperty(QLatin1String(currentTabWhatsThisKey), qVariantFromValue(qdesigner_internal::PropertySheetStringValue())); + // Prevent the tab widget's drag and drop handling from interfering with Designer's + createFakeProperty(QLatin1String(tabMovableKey), QVariant(false)); } QTabWidgetPropertySheet::TabWidgetProperty QTabWidgetPropertySheet::tabWidgetPropertyFromName(const QString &name) -- cgit v0.12 From 11b1ced7cdc2af028164381d43c146ec79919f19 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 26 Oct 2009 15:55:16 +0100 Subject: Do not hardecode the ToolBar Icon Size So we correctly get the size from the platform plugin Reviewed-by: jbache --- src/gui/styles/qcommonstyle.cpp | 2 +- src/gui/styles/qplastiquestyle.cpp | 3 --- src/gui/styles/qwindowsstyle.cpp | 3 --- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index 5886512..b871842 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -4661,7 +4661,7 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid case PM_ToolBarIconSize: ret = qt_guiPlatformPlugin()->platformHint(QGuiPlatformPlugin::PH_ToolBarIconSize); if (!ret) - ret = proxy()->pixelMetric(PM_SmallIconSize, opt, widget); + ret = int(QStyleHelper::dpiScaled(24.)); break; case PM_TabBarIconSize: diff --git a/src/gui/styles/qplastiquestyle.cpp b/src/gui/styles/qplastiquestyle.cpp index ce2109a..1f77d90 100644 --- a/src/gui/styles/qplastiquestyle.cpp +++ b/src/gui/styles/qplastiquestyle.cpp @@ -5514,9 +5514,6 @@ int QPlastiqueStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, case PM_MenuHMargin: ret = 0; break; - case PM_ToolBarIconSize: - ret = 24; - break; case PM_ButtonShiftHorizontal: case PM_ButtonShiftVertical: ret = 1; diff --git a/src/gui/styles/qwindowsstyle.cpp b/src/gui/styles/qwindowsstyle.cpp index 0f72440..5cf738e 100644 --- a/src/gui/styles/qwindowsstyle.cpp +++ b/src/gui/styles/qwindowsstyle.cpp @@ -454,9 +454,6 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW ret = proxy()->pixelMetric(PM_LargeIconSize, opt, widget); break; - case PM_ToolBarIconSize: - ret = int(QStyleHelper::dpiScaled(24.)); - break; case PM_DockWidgetTitleMargin: ret = int(QStyleHelper::dpiScaled(2.)); break; -- cgit v0.12 From 5ff7b773a0f59e174001da1f0550a7f0c2b6f485 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 27 Oct 2009 11:39:51 +0100 Subject: Fixes QTreeView: stylesheet :has-children pseudo selector doesn't works for the ::item pseudo-class The State_Children was not set on the QStyleOption. Refactorized a little bit the way it was computed. Reviewed-by: Thierry Task-number: 234930 Task-number: QTBUG-3129 --- src/gui/itemviews/qtreeview.cpp | 28 +++++++++++++++------------ src/gui/itemviews/qtreeview_p.h | 3 ++- tests/auto/qtreeview/tst_qtreeview.cpp | 35 +++++++++++++++++++++++++++++++--- 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index f37d8c7..49c8e34 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -1422,8 +1422,8 @@ void QTreeView::drawTree(QPainter *painter, const QRegion ®ion) const for (; i < viewItems.count() && y <= area.bottom(); ++i) { const int itemHeight = d->itemHeight(i); option.rect.setRect(0, y, viewportWidth, itemHeight); - option.state = state | (viewItems.at(i).expanded - ? QStyle::State_Open : QStyle::State_None); + option.state = state | (viewItems.at(i).expanded ? QStyle::State_Open : QStyle::State_None) + | (viewItems.at(i).hasChildren ? QStyle::State_Children : QStyle::State_None ); d->current = i; d->spanning = viewItems.at(i).spanning; if (!multipleRects || !drawn.contains(i)) { @@ -1748,8 +1748,7 @@ void QTreeView::drawBranches(QPainter *painter, const QRect &rect, opt.rect = primitive; const bool expanded = viewItem.expanded; - const bool children = (((expanded && viewItem.total > 0)) // already laid out and has children - || d->hasVisibleChildren(index)); // not laid out yet, so we don't know + const bool children = viewItem.hasChildren; bool moreSiblings = false; if (d->hiddenIndexes.isEmpty()) moreSiblings = (d->model->rowCount(parent) - 1 > index.row()); @@ -3135,17 +3134,22 @@ void QTreeViewPrivate::layout(int i) last = j - hidden + children; } else { last = j - hidden + children; - viewItems[last].index = current; - viewItems[last].level = level; - viewItems[last].height = 0; - viewItems[last].spanning = q->isFirstColumnSpanned(current.row(), parent); - viewItems[last].expanded = false; - viewItems[last].total = 0; + QTreeViewItem *item = &viewItems[last]; + item->index = current; + item->level = level; + item->height = 0; + item->spanning = q->isFirstColumnSpanned(current.row(), parent); + item->expanded = false; + item->total = 0; if (isIndexExpanded(current)) { - viewItems[last].expanded = true; + item->expanded = true; layout(last); - children += viewItems[last].total; + item = &viewItems[last]; + children += item->total; + item->hasChildren = item->total > 0; last = j - hidden + children; + } else { + item->hasChildren = hasVisibleChildren(current); } } } diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h index def8253..f89c328 100644 --- a/src/gui/itemviews/qtreeview_p.h +++ b/src/gui/itemviews/qtreeview_p.h @@ -66,7 +66,8 @@ struct QTreeViewItem QModelIndex index; // we remove items whenever the indexes are invalidated uint expanded : 1; uint spanning : 1; - uint total : 30; // total number of children visible + uint hasChildren : 1; // if the item has visible children (even if collapsed) + uint total : 29; // total number of children visible uint level : 16; // indentation int height : 16; // row height }; diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp index da58725..8d824cb 100644 --- a/tests/auto/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/qtreeview/tst_qtreeview.cpp @@ -2891,7 +2891,8 @@ void tst_QTreeView::styleOptionViewItem() QVERIFY(!opt.text.isEmpty()); QCOMPARE(opt.index, index); - QCOMPARE(!(opt.features & QStyleOptionViewItemV2::Alternate), !(index.row() % 2)); + if (allCollapsed) + QCOMPARE(!(opt.features & QStyleOptionViewItemV2::Alternate), !(index.row() % 2)); QCOMPARE(!(opt.features & QStyleOptionViewItemV2::HasCheckIndicator), !opt.text.contains("Checkable")); if (opt.text.contains("Beginning")) @@ -2911,12 +2912,15 @@ void tst_QTreeView::styleOptionViewItem() else QCOMPARE(opt.checkState, Qt::Unchecked); + QCOMPARE(!(opt.state & QStyle::State_Children) , !opt.text.contains("HasChildren")); + QVERIFY(!opt.text.contains("Assert")); QStyledItemDelegate::paint(painter, option, index); count++; } mutable int count; + bool allCollapsed; }; QTreeView view; @@ -2926,8 +2930,9 @@ void tst_QTreeView::styleOptionViewItem() view.setItemDelegate(&delegate); model.appendRow(QList() << new QStandardItem("Beginning") << new QStandardItem("Middle") << new QStandardItem("Middle") << new QStandardItem("End") ); + QStandardItem *par1 = new QStandardItem("Beginning HasChildren"); model.appendRow(QList() - << new QStandardItem("Beginning") << new QStandardItem("Middle") << new QStandardItem("Middle") << new QStandardItem("End") ); + << par1 << new QStandardItem("Middle HasChildren") << new QStandardItem("Middle HasChildren") << new QStandardItem("End HasChildren") ); model.appendRow(QList() << new QStandardItem("OnlyOne") << new QStandardItem("Assert") << new QStandardItem("Assert") << new QStandardItem("Assert") ); QStandardItem *checkable = new QStandardItem("Checkable"); @@ -2938,12 +2943,37 @@ void tst_QTreeView::styleOptionViewItem() model.appendRow(QList() << new QStandardItem("Beginning") << checkable << checked << new QStandardItem("End") ); + par1->appendRow(QList() + << new QStandardItem("Beginning") << new QStandardItem("Middle") << new QStandardItem("Middle") << new QStandardItem("End") ); + QStandardItem *par2 = new QStandardItem("Beginning HasChildren"); + par1->appendRow(QList() + << par2 << new QStandardItem("Middle HasChildren") << new QStandardItem("Middle HasChildren") << new QStandardItem("End HasChildren") ); + par2->appendRow(QList() + << new QStandardItem("Beginning") << new QStandardItem("Middle") << new QStandardItem("Middle") << new QStandardItem("End") ); + + QStandardItem *par3 = new QStandardItem("Beginning"); + par1->appendRow(QList() + << par3 << new QStandardItem("Middle") << new QStandardItem("Middle") << new QStandardItem("End") ); + par3->appendRow(QList() + << new QStandardItem("Beginning") << new QStandardItem("Middle") << new QStandardItem("Middle") << new QStandardItem("End") ); + view.setRowHidden(0, par3->index(), true); + view.setFirstColumnSpanned(2, QModelIndex(), true); view.setAlternatingRowColors(true); delegate.count = 0; + delegate.allCollapsed = true; view.showMaximized(); + QApplication::processEvents(); QTRY_VERIFY(delegate.count >= 13); + delegate.count = 0; + delegate.allCollapsed = false; + view.expandAll(); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 13); + view.collapse(par2->index()); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 4); } class task174627_TreeView : public QTreeView @@ -3508,6 +3538,5 @@ void tst_QTreeView::task245654_changeModelAndExpandAll() } - QTEST_MAIN(tst_QTreeView) #include "tst_qtreeview.moc" -- cgit v0.12 From 0897713a560700f574386499a872f59e3fc4ce7d Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 27 Oct 2009 12:45:21 +0100 Subject: QTreeView: Make sure the state QStyle::State_Sibling is correctly set That state used not to be set for drawing the content of the items. Also, it could be wrong for branches if there was hidden items. Reviewed-by: Thierry Task-number: related to 234930 --- src/gui/itemviews/qtreeview.cpp | 17 ++++++++--------- src/gui/itemviews/qtreeview_p.h | 3 ++- tests/auto/qtreeview/tst_qtreeview.cpp | 15 +++++++++++---- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index 49c8e34..e74ecfc 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -1423,7 +1423,8 @@ void QTreeView::drawTree(QPainter *painter, const QRegion ®ion) const const int itemHeight = d->itemHeight(i); option.rect.setRect(0, y, viewportWidth, itemHeight); option.state = state | (viewItems.at(i).expanded ? QStyle::State_Open : QStyle::State_None) - | (viewItems.at(i).hasChildren ? QStyle::State_Children : QStyle::State_None ); + | (viewItems.at(i).hasChildren ? QStyle::State_Children : QStyle::State_None) + | (viewItems.at(i).hasMoreSiblings ? QStyle::State_Sibling : QStyle::State_None); d->current = i; d->spanning = viewItems.at(i).spanning; if (!multipleRects || !drawn.contains(i)) { @@ -1749,12 +1750,7 @@ void QTreeView::drawBranches(QPainter *painter, const QRect &rect, const bool expanded = viewItem.expanded; const bool children = viewItem.hasChildren; - bool moreSiblings = false; - if (d->hiddenIndexes.isEmpty()) - moreSiblings = (d->model->rowCount(parent) - 1 > index.row()); - else - moreSiblings = ((d->viewItems.size() > item +1) - && (d->viewItems.at(item + 1).index.parent() == parent)); + bool moreSiblings = viewItem.hasMoreSiblings; opt.state = QStyle::State_Item | extraFlags | (moreSiblings ? QStyle::State_Sibling : QStyle::State_None) @@ -3126,7 +3122,7 @@ void QTreeViewPrivate::layout(int i) int hidden = 0; int last = 0; int children = 0; - + QTreeViewItem *item = 0; for (int j = first; j < first + count; ++j) { current = model->index(j - first, 0, parent); if (isRowHidden(current)) { @@ -3134,13 +3130,16 @@ void QTreeViewPrivate::layout(int i) last = j - hidden + children; } else { last = j - hidden + children; - QTreeViewItem *item = &viewItems[last]; + if (item) + item->hasMoreSiblings = true; + item = &viewItems[last]; item->index = current; item->level = level; item->height = 0; item->spanning = q->isFirstColumnSpanned(current.row(), parent); item->expanded = false; item->total = 0; + item->hasMoreSiblings = false; if (isIndexExpanded(current)) { item->expanded = true; layout(last); diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h index f89c328..62676d8 100644 --- a/src/gui/itemviews/qtreeview_p.h +++ b/src/gui/itemviews/qtreeview_p.h @@ -67,7 +67,8 @@ struct QTreeViewItem uint expanded : 1; uint spanning : 1; uint hasChildren : 1; // if the item has visible children (even if collapsed) - uint total : 29; // total number of children visible + uint hasMoreSiblings : 1; + uint total : 28; // total number of children visible uint level : 16; // indentation int height : 16; // row height }; diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp index 8d824cb..cbc999f 100644 --- a/tests/auto/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/qtreeview/tst_qtreeview.cpp @@ -2913,6 +2913,7 @@ void tst_QTreeView::styleOptionViewItem() QCOMPARE(opt.checkState, Qt::Unchecked); QCOMPARE(!(opt.state & QStyle::State_Children) , !opt.text.contains("HasChildren")); + QCOMPARE(!!(opt.state & QStyle::State_Sibling) , !opt.text.contains("Last")); QVERIFY(!opt.text.contains("Assert")); @@ -2942,6 +2943,8 @@ void tst_QTreeView::styleOptionViewItem() checked->setCheckState(Qt::Checked); model.appendRow(QList() << new QStandardItem("Beginning") << checkable << checked << new QStandardItem("End") ); + model.appendRow(QList() + << new QStandardItem("Beginning Last") << new QStandardItem("Middle Last") << new QStandardItem("Middle Last") << new QStandardItem("End Last") ); par1->appendRow(QList() << new QStandardItem("Beginning") << new QStandardItem("Middle") << new QStandardItem("Middle") << new QStandardItem("End") ); @@ -2949,14 +2952,18 @@ void tst_QTreeView::styleOptionViewItem() par1->appendRow(QList() << par2 << new QStandardItem("Middle HasChildren") << new QStandardItem("Middle HasChildren") << new QStandardItem("End HasChildren") ); par2->appendRow(QList() - << new QStandardItem("Beginning") << new QStandardItem("Middle") << new QStandardItem("Middle") << new QStandardItem("End") ); + << new QStandardItem("Beginning Last") << new QStandardItem("Middle Last") << new QStandardItem("Middle Last") << new QStandardItem("End Last") ); - QStandardItem *par3 = new QStandardItem("Beginning"); + QStandardItem *par3 = new QStandardItem("Beginning Last"); par1->appendRow(QList() - << par3 << new QStandardItem("Middle") << new QStandardItem("Middle") << new QStandardItem("End") ); + << par3 << new QStandardItem("Middle Last") << new QStandardItem("Middle Last") << new QStandardItem("End Last") ); par3->appendRow(QList() - << new QStandardItem("Beginning") << new QStandardItem("Middle") << new QStandardItem("Middle") << new QStandardItem("End") ); + << new QStandardItem("Assert") << new QStandardItem("Assert") << new QStandardItem("Assert") << new QStandardItem("Asser") ); view.setRowHidden(0, par3->index(), true); + par1->appendRow(QList() + << new QStandardItem("Assert") << new QStandardItem("Assert") << new QStandardItem("Assert") << new QStandardItem("Asser") ); + view.setRowHidden(3, par1->index(), true); + view.setFirstColumnSpanned(2, QModelIndex(), true); view.setAlternatingRowColors(true); -- cgit v0.12 From d683fd25512dedacdac141222db36209ef65e42d Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 27 Oct 2009 13:43:42 +0100 Subject: Fixed QTreeView not emitting doubleCliked when 1st col is spanned Task-number: QTBUG-976 Reviewed-by: ogoffart --- src/gui/itemviews/qtreeview.cpp | 4 +--- tests/auto/qtreeview/tst_qtreeview.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index e74ecfc..16b454d 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -1840,9 +1840,7 @@ void QTreeView::mouseDoubleClickEvent(QMouseEvent *event) return; // user clicked outside the items const QPersistentModelIndex firstColumnIndex = d->viewItems.at(i).index; - - int column = d->header->logicalIndexAt(event->x()); - QPersistentModelIndex persistent = firstColumnIndex.sibling(firstColumnIndex.row(), column); + const QPersistentModelIndex persistent = indexAt(event->pos()); if (d->pressedIndex != persistent) { mousePressEvent(event); diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp index cbc999f..1429771 100644 --- a/tests/auto/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/qtreeview/tst_qtreeview.cpp @@ -235,6 +235,7 @@ private slots: void task254234_proxySort(); void task248022_changeSelection(); void task245654_changeModelAndExpandAll(); + void doubleClickedWithSpans(); }; class QtTestModel: public QAbstractItemModel @@ -3544,6 +3545,34 @@ void tst_QTreeView::task245654_changeModelAndExpandAll() } +void tst_QTreeView::doubleClickedWithSpans() +{ + QTreeView view; + QStandardItemModel model(1, 2); + view.setModel(&model); + view.setFirstColumnSpanned(0, QModelIndex(), true); + view.show(); + + QPoint p(10, 10); + QCOMPARE(view.indexAt(p), model.index(0, 0)); + QSignalSpy spy(&view, SIGNAL(doubleClicked(QModelIndex))); + QTest::mousePress(view.viewport(), Qt::LeftButton, 0, p); + QTest::mouseDClick(view.viewport(), Qt::LeftButton, 0, p); + QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, p); + QCOMPARE(spy.count(), 1); + + //let's click on the 2nd column + p.setX(p.x() + view.header()->sectionSize(0)); + QCOMPARE(view.indexAt(p), model.index(0, 0)); + + //end the previous edition + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, p); + QTest::qWait(100); + QTest::mousePress(view.viewport(), Qt::LeftButton, 0, p); + QTest::mouseDClick(view.viewport(), Qt::LeftButton, 0, p); + QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, p); + QCOMPARE(spy.count(), 2); +} QTEST_MAIN(tst_QTreeView) #include "tst_qtreeview.moc" -- cgit v0.12 From 8f040ea4da93f1b9cae1db560e5e9f9b3140b3ff Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 27 Oct 2009 13:48:39 +0100 Subject: QVariant::isNull does not return the right result with QVariant::setValue Inspired by merge request 1911 Reveiwed-by: Thierry --- src/corelib/kernel/qvariant.h | 1 + tests/auto/qvariant/tst_qvariant.cpp | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index eb4fb56..4cce529 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -460,6 +460,7 @@ inline void qVariantSetValue(QVariant &v, const T &t) QVariant::Private &d = v.data_ptr(); if (v.isDetached() && (type <= int(QVariant::Char) || type == d.type)) { d.type = type; + d.is_null = false; T *old = reinterpret_cast(d.is_shared ? d.data.shared->ptr : &d.data.ptr); if (QTypeInfo::isComplex) old->~T(); diff --git a/tests/auto/qvariant/tst_qvariant.cpp b/tests/auto/qvariant/tst_qvariant.cpp index 9295897..de4d7b4 100644 --- a/tests/auto/qvariant/tst_qvariant.cpp +++ b/tests/auto/qvariant/tst_qvariant.cpp @@ -318,6 +318,14 @@ void tst_QVariant::constructor() QVariant var6(qlonglong(0)); QCOMPARE(var6.type(), QVariant::LongLong); QCOMPARE(var6.typeName(), "qlonglong"); + + QVariant var7 = 5; + QVERIFY(var7.isValid()); + QVERIFY(!var7.isNull()); + QVariant var8; + var8.setValue(5); + QVERIFY(var8.isValid()); + QVERIFY(!var8.isNull()); } void tst_QVariant::copy_constructor() -- cgit v0.12 From d0b0e0ed8ac857d78e497b74bb1c3596273c53ba Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Tue, 27 Oct 2009 15:10:46 +0100 Subject: QLibrary on Windows: Do not show error boxes when library load fails When loading a library fails, the error message "The application or DLL ... is not a valid Windows image. Please check this against your installation diskette." is shown, which is not very helpful. Task-number: QT-2357 Reviewed-by: Marius Storm-Olsen --- src/corelib/plugin/qlibrary.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 2b463a1..6496876 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -659,7 +659,10 @@ bool QLibraryPrivate::isPlugin(QSettings *settings) #endif if (!pHnd) { #ifdef Q_OS_WIN + //avoid 'Bad Image' message box + UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); hTempModule = ::LoadLibraryEx((wchar_t*)QDir::toNativeSeparators(fileName).utf16(), 0, DONT_RESOLVE_DLL_REFERENCES); + SetErrorMode(oldmode); #else # if defined(Q_OS_SYMBIAN) //Guard against accidentally trying to load non-plugin libraries by making sure the stub exists -- cgit v0.12 From c79d83b6d661ea49d893b4590480a434d75b19bd Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 27 Oct 2009 15:18:59 +0100 Subject: QComboBox did not emit currentItemChanged when the model was reset Task-number: QTBUG-569 Reviewed-by: ogoffart --- src/gui/widgets/qcombobox.cpp | 27 +++++++++++---------------- src/gui/widgets/qcombobox.h | 3 +-- src/gui/widgets/qcombobox_p.h | 3 +-- tests/auto/qcombobox/tst_qcombobox.cpp | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 20 deletions(-) diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index 0e888d6..7cf35c7 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -192,6 +192,8 @@ void QComboBoxPrivate::_q_modelReset() lineEdit->setText(QString()); updateLineEditGeometry(); } + if (currentIndex.row() != indexBeforeChange) + _q_emitCurrentIndexChanged(currentIndex); q->update(); } @@ -992,14 +994,6 @@ void QComboBoxPrivate::_q_dataChanged(const QModelIndex &topLeft, const QModelIn } } -void QComboBoxPrivate::_q_rowsAboutToBeInserted(const QModelIndex & parent, - int /*start*/, int /*end*/) -{ - if (parent != root) - return; - indexBeforeChange = currentIndex.row(); -} - void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int end) { Q_Q(QComboBox); @@ -1022,11 +1016,8 @@ void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int } } -void QComboBoxPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &parent, int /*start*/, int /*end*/) +void QComboBoxPrivate::_q_updateIndexBeforeChange() { - if (parent != root) - return; - indexBeforeChange = currentIndex.row(); } @@ -1868,15 +1859,17 @@ void QComboBox::setModel(QAbstractItemModel *model) disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(_q_dataChanged(QModelIndex,QModelIndex))); disconnect(d->model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), - this, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int))); + this, SLOT(_q_updateIndexBeforeChange())); disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(_q_rowsInserted(QModelIndex,int,int))); disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int))); + this, SLOT(_q_updateIndexBeforeChange())); disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(_q_rowsRemoved(QModelIndex,int,int))); disconnect(d->model, SIGNAL(destroyed()), this, SLOT(_q_modelDestroyed())); + disconnect(d->model, SIGNAL(modelAboutToBeReset()), + this, SLOT(_q_updateIndexBeforeChange())); disconnect(d->model, SIGNAL(modelReset()), this, SLOT(_q_modelReset())); if (d->model->QObject::parent() == this) @@ -1888,15 +1881,17 @@ void QComboBox::setModel(QAbstractItemModel *model) connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(_q_dataChanged(QModelIndex,QModelIndex))); connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), - this, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int))); + this, SLOT(_q_updateIndexBeforeChange())); connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(_q_rowsInserted(QModelIndex,int,int))); connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int))); + this, SLOT(_q_updateIndexBeforeChange())); connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(_q_rowsRemoved(QModelIndex,int,int))); connect(model, SIGNAL(destroyed()), this, SLOT(_q_modelDestroyed())); + connect(model, SIGNAL(modelAboutToBeReset()), + this, SLOT(_q_updateIndexBeforeChange())); connect(model, SIGNAL(modelReset()), this, SLOT(_q_modelReset())); diff --git a/src/gui/widgets/qcombobox.h b/src/gui/widgets/qcombobox.h index 6a85096..4089a09 100644 --- a/src/gui/widgets/qcombobox.h +++ b/src/gui/widgets/qcombobox.h @@ -308,9 +308,8 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_returnPressed()) Q_PRIVATE_SLOT(d_func(), void _q_resetButton()) Q_PRIVATE_SLOT(d_func(), void _q_dataChanged(const QModelIndex &, const QModelIndex &)) - Q_PRIVATE_SLOT(d_func(), void _q_rowsAboutToBeInserted(const QModelIndex & parent, int start, int end)) + Q_PRIVATE_SLOT(d_func(), void _q_updateIndexBeforeChange()) Q_PRIVATE_SLOT(d_func(), void _q_rowsInserted(const QModelIndex & parent, int start, int end)) - Q_PRIVATE_SLOT(d_func(), void _q_rowsAboutToBeRemoved(const QModelIndex & parent, int start, int end)) Q_PRIVATE_SLOT(d_func(), void _q_rowsRemoved(const QModelIndex & parent, int start, int end)) Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed()) Q_PRIVATE_SLOT(d_func(), void _q_modelReset()) diff --git a/src/gui/widgets/qcombobox_p.h b/src/gui/widgets/qcombobox_p.h index f7458c4..06e51e4 100644 --- a/src/gui/widgets/qcombobox_p.h +++ b/src/gui/widgets/qcombobox_p.h @@ -357,9 +357,8 @@ public: #endif void _q_resetButton(); void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); - void _q_rowsAboutToBeInserted(const QModelIndex & parent, int start, int end); + void _q_updateIndexBeforeChange(); void _q_rowsInserted(const QModelIndex & parent, int start, int end); - void _q_rowsAboutToBeRemoved(const QModelIndex & parent, int start, int end); void _q_rowsRemoved(const QModelIndex & parent, int start, int end); void updateArrow(QStyle::StateFlag state); bool updateHoverControl(const QPoint &pos); diff --git a/tests/auto/qcombobox/tst_qcombobox.cpp b/tests/auto/qcombobox/tst_qcombobox.cpp index 0d3469d..8acae7a 100644 --- a/tests/auto/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/qcombobox/tst_qcombobox.cpp @@ -152,6 +152,7 @@ private slots: void subControlRectsWithOffset(); void task260974_menuItemRectangleForComboBoxPopup(); void removeItem(); + void resetModel(); protected slots: void onEditTextChanged( const QString &newString ); @@ -2416,5 +2417,37 @@ void tst_QComboBox::removeItem() QCOMPARE(cb.count(), 0); } +void tst_QComboBox::resetModel() +{ + class StringListModel : public QStringListModel + { + public: + StringListModel(const QStringList &list) : QStringListModel(list) + { + } + + void reset() + { + QStringListModel::reset(); + } + }; + QComboBox cb; + StringListModel model( QStringList() << "1" << "2"); + QSignalSpy spy(&cb, SIGNAL(currentIndexChanged(int))); + QCOMPARE(spy.count(), 0); + QCOMPARE(cb.currentIndex(), -1); //no selection + + cb.setModel(&model); + + QCOMPARE(spy.count(), 1); + QCOMPARE(cb.currentIndex(), 0); //first item selected + + model.reset(); + QCOMPARE(spy.count(), 2); + QCOMPARE(cb.currentIndex(), -1); //no selection + +} + + QTEST_MAIN(tst_QComboBox) #include "tst_qcombobox.moc" -- cgit v0.12 From df26c6e14287f1a02c636c4624c5085fd8271d11 Mon Sep 17 00:00:00 2001 From: David Faure Date: Tue, 27 Oct 2009 15:26:11 +0100 Subject: Fix incomplete documentation for Qt::DecorationRole As noticed by Laurent Montel. Merge-request: 1812 Reviewed-by: Olivier Goffart --- src/corelib/global/qnamespace.qdoc | 2 +- src/gui/itemviews/qitemdelegate.cpp | 2 +- src/gui/itemviews/qstyleditemdelegate.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index e8d6df0..438678a 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -2509,7 +2509,7 @@ \value DisplayRole The key data to be rendered in the form of text. (QString) \value DecorationRole The data to be rendered as a decoration in the form - of an icon. (QColor) + of an icon. (QColor, QIcon or QPixmap) \value EditRole The data in a form suitable for editing in an editor. (QString) \value ToolTipRole The data displayed in the item's tooltip. (QString) diff --git a/src/gui/itemviews/qitemdelegate.cpp b/src/gui/itemviews/qitemdelegate.cpp index 871a4b1..3b3036d 100644 --- a/src/gui/itemviews/qitemdelegate.cpp +++ b/src/gui/itemviews/qitemdelegate.cpp @@ -255,7 +255,7 @@ QSizeF QItemDelegatePrivate::doTextLayout(int lineWidth) const \row \o \l Qt::BackgroundRole \o QBrush \row \o \l Qt::BackgroundColorRole \o QColor (obsolete; use Qt::BackgroundRole instead) \row \o \l Qt::CheckStateRole \o Qt::CheckState - \row \o \l Qt::DecorationRole \o QIcon and QColor + \row \o \l Qt::DecorationRole \o QIcon, QPixmap and QColor \row \o \l Qt::DisplayRole \o QString and types with a string representation \row \o \l Qt::EditRole \o See QItemEditorFactory for details \row \o \l Qt::FontRole \o QFont diff --git a/src/gui/itemviews/qstyleditemdelegate.cpp b/src/gui/itemviews/qstyleditemdelegate.cpp index 1c36787..1ca0391 100644 --- a/src/gui/itemviews/qstyleditemdelegate.cpp +++ b/src/gui/itemviews/qstyleditemdelegate.cpp @@ -148,7 +148,7 @@ public: \row \o \l Qt::BackgroundRole \o QBrush \row \o \l Qt::BackgroundColorRole \o QColor (obsolete; use Qt::BackgroundRole instead) \row \o \l Qt::CheckStateRole \o Qt::CheckState - \row \o \l Qt::DecorationRole \o QIcon and QColor + \row \o \l Qt::DecorationRole \o QIcon, QPixmap, QImage and QColor \row \o \l Qt::DisplayRole \o QString and types with a string representation \row \o \l Qt::EditRole \o See QItemEditorFactory for details \row \o \l Qt::FontRole \o QFont -- cgit v0.12 From 2d0b29c312ddf422595ce9debb3678bb5c4d51b6 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Tue, 27 Oct 2009 16:04:29 +0100 Subject: QAbstractSocket: wait with closing until all bytes have been written only disconnect from host when all bytes have been written; i.e. not only check whether the write buffer is empty, but also check whether the socket engine has still bytes to write. This is necessary for HTTP and SOCKS5 socket engine, because they both contain an inner TCP socket which also does buffering. For the native socket engine, there is no difference with this patch. Reviewed-by: Markus Goetz Reviewed-by: Thiago Macieira --- src/network/socket/qabstractsocket.cpp | 22 +++++++++++++++------- src/network/socket/qabstractsocketengine_p.h | 2 ++ src/network/socket/qhttpsocketengine.cpp | 10 ++++++++++ src/network/socket/qhttpsocketengine_p.h | 2 ++ src/network/socket/qnativesocketengine.cpp | 6 ++++++ src/network/socket/qnativesocketengine_p.h | 2 ++ src/network/socket/qsocks5socketengine.cpp | 14 ++++++++++++++ src/network/socket/qsocks5socketengine_p.h | 2 ++ src/network/ssl/qsslsocket.cpp | 2 ++ tests/auto/qsslsocket/tst_qsslsocket.cpp | 4 +--- 10 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 9fb0b47..955fee0 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -669,11 +669,11 @@ bool QAbstractSocketPrivate::canWriteNotification() if (socketEngine) { #if defined (Q_OS_WIN) - if (!writeBuffer.isEmpty()) - socketEngine->setWriteNotificationEnabled(true); + if (!writeBuffer.isEmpty()) + socketEngine->setWriteNotificationEnabled(true); #else - if (writeBuffer.isEmpty()) - socketEngine->setWriteNotificationEnabled(false); + if (writeBuffer.isEmpty() && socketEngine->bytesToWrite() == 0) + socketEngine->setWriteNotificationEnabled(false); #endif } @@ -710,11 +710,17 @@ void QAbstractSocketPrivate::connectionNotification() bool QAbstractSocketPrivate::flush() { Q_Q(QAbstractSocket); - if (!socketEngine || !socketEngine->isValid() || writeBuffer.isEmpty()) { + if (!socketEngine || !socketEngine->isValid() || (writeBuffer.isEmpty() + && socketEngine->bytesToWrite() == 0)) { #if defined (QABSTRACTSOCKET_DEBUG) qDebug("QAbstractSocketPrivate::flush() nothing to do: valid ? %s, writeBuffer.isEmpty() ? %s", socketEngine->isValid() ? "yes" : "no", writeBuffer.isEmpty() ? "yes" : "no"); #endif + + // this covers the case when the buffer was empty, but we had to wait for the socket engine to finish + if (state == QAbstractSocket::ClosingState) + q->disconnectFromHost(); + return false; } @@ -751,7 +757,8 @@ bool QAbstractSocketPrivate::flush() } } - if (writeBuffer.isEmpty() && socketEngine && socketEngine->isWriteNotificationEnabled()) + if (writeBuffer.isEmpty() && socketEngine && socketEngine->isWriteNotificationEnabled() + && !socketEngine->bytesToWrite()) socketEngine->setWriteNotificationEnabled(false); if (state == QAbstractSocket::ClosingState) q->disconnectFromHost(); @@ -2347,7 +2354,8 @@ void QAbstractSocket::disconnectFromHostImplementation() } // Wait for pending data to be written. - if (d->socketEngine && d->socketEngine->isValid() && d->writeBuffer.size() > 0) { + if (d->socketEngine && d->socketEngine->isValid() && (d->writeBuffer.size() > 0 + || d->socketEngine->bytesToWrite() > 0)) { d->socketEngine->setWriteNotificationEnabled(true); #if defined(QABSTRACTSOCKET_DEBUG) diff --git a/src/network/socket/qabstractsocketengine_p.h b/src/network/socket/qabstractsocketengine_p.h index c639092..14b3c81 100644 --- a/src/network/socket/qabstractsocketengine_p.h +++ b/src/network/socket/qabstractsocketengine_p.h @@ -126,6 +126,8 @@ public: virtual qint64 pendingDatagramSize() const = 0; #endif + virtual qint64 bytesToWrite() const = 0; + virtual int option(SocketOption option) const = 0; virtual bool setOption(SocketOption option, int value) = 0; diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp index fb61dbf..5c28318 100644 --- a/src/network/socket/qhttpsocketengine.cpp +++ b/src/network/socket/qhttpsocketengine.cpp @@ -276,6 +276,16 @@ qint64 QHttpSocketEngine::pendingDatagramSize() const } #endif // QT_NO_UDPSOCKET +qint64 QHttpSocketEngine::bytesToWrite() const +{ + Q_D(const QHttpSocketEngine); + if (d->socket) { + return d->socket->bytesToWrite(); + } else { + return 0; + } +} + int QHttpSocketEngine::option(SocketOption option) const { Q_D(const QHttpSocketEngine); diff --git a/src/network/socket/qhttpsocketengine_p.h b/src/network/socket/qhttpsocketengine_p.h index a423116..76430db 100644 --- a/src/network/socket/qhttpsocketengine_p.h +++ b/src/network/socket/qhttpsocketengine_p.h @@ -110,6 +110,8 @@ public: qint64 pendingDatagramSize() const; #endif // QT_NO_UDPSOCKET + qint64 bytesToWrite() const; + int option(SocketOption option) const; bool setOption(SocketOption option, int value); diff --git a/src/network/socket/qnativesocketengine.cpp b/src/network/socket/qnativesocketengine.cpp index e7f8401..a150b26 100644 --- a/src/network/socket/qnativesocketengine.cpp +++ b/src/network/socket/qnativesocketengine.cpp @@ -754,6 +754,12 @@ qint64 QNativeSocketEngine::write(const char *data, qint64 size) return d->nativeWrite(data, size); } + +qint64 QNativeSocketEngine::bytesToWrite() const +{ + return 0; +} + /*! Reads up to \a maxSize bytes into \a data from the socket. Returns the number of bytes read, or -1 if an error occurred. diff --git a/src/network/socket/qnativesocketengine_p.h b/src/network/socket/qnativesocketengine_p.h index 1f6a243..a03d8f1 100644 --- a/src/network/socket/qnativesocketengine_p.h +++ b/src/network/socket/qnativesocketengine_p.h @@ -135,6 +135,8 @@ public: bool hasPendingDatagrams() const; qint64 pendingDatagramSize() const; + qint64 bytesToWrite() const; + qint64 receiveBufferSize() const; void setReceiveBufferSize(qint64 bufferSize); diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp index 30074cf..bd60ad1 100644 --- a/src/network/socket/qsocks5socketengine.cpp +++ b/src/network/socket/qsocks5socketengine.cpp @@ -1235,6 +1235,9 @@ void QSocks5SocketEnginePrivate::_q_controlSocketError(QAbstractSocket::SocketEr if (!readNotificationPending) connectData->readBuffer.clear(); emitReadNotification(); + data->controlSocket->close(); + // cause a disconnect in the outer socket + emitWriteNotification(); } else if (socks5State == Uninitialized || socks5State == AuthenticationMethodsSent || socks5State == Authenticating @@ -1245,6 +1248,7 @@ void QSocks5SocketEnginePrivate::_q_controlSocketError(QAbstractSocket::SocketEr } else { q_func()->setError(data->controlSocket->error(), data->controlSocket->errorString()); emitReadNotification(); + emitWriteNotification(); } } @@ -1623,6 +1627,16 @@ qint64 QSocks5SocketEngine::pendingDatagramSize() const } #endif // QT_NO_UDPSOCKET +qint64 QSocks5SocketEngine::bytesToWrite() const +{ + Q_D(const QSocks5SocketEngine); + if (d->data && d->data->controlSocket) { + return d->data->controlSocket->bytesToWrite(); + } else { + return 0; + } +} + int QSocks5SocketEngine::option(SocketOption option) const { Q_D(const QSocks5SocketEngine); diff --git a/src/network/socket/qsocks5socketengine_p.h b/src/network/socket/qsocks5socketengine_p.h index 7cb0920..2402517 100644 --- a/src/network/socket/qsocks5socketengine_p.h +++ b/src/network/socket/qsocks5socketengine_p.h @@ -100,6 +100,8 @@ public: qint64 pendingDatagramSize() const; #endif // QT_NO_UDPSOCKET + qint64 bytesToWrite() const; + int option(SocketOption option) const; bool setOption(SocketOption option, int value); diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 2c88130..608d772 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -707,6 +707,8 @@ void QSslSocket::close() qDebug() << "QSslSocket::close()"; #endif Q_D(QSslSocket); + if (d->plainSocket) + d->plainSocket->close(); QTcpSocket::close(); // must be cleared, reading/writing not possible on closed socket: diff --git a/tests/auto/qsslsocket/tst_qsslsocket.cpp b/tests/auto/qsslsocket/tst_qsslsocket.cpp index 2bd1684..db46b66 100644 --- a/tests/auto/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/qsslsocket/tst_qsslsocket.cpp @@ -1755,9 +1755,7 @@ void tst_QSslSocket::readFromClosedSocket() socket->close(); QVERIFY(!socket->bytesAvailable()); QVERIFY(!socket->bytesToWrite()); - socket->waitForDisconnected(); - QVERIFY(!socket->bytesAvailable()); - QVERIFY(!socket->bytesToWrite()); + QVERIFY(socket->state() == QAbstractSocket::UnconnectedState); } void tst_QSslSocket::writeBigChunk() -- cgit v0.12 From 576aced5cb8270b1827a505aa0ae815781b1cfa5 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 27 Oct 2009 16:42:55 +0100 Subject: QToolBar has now a topLevelChanged signal like in QDockWidget Task-number: QTBUG-4169 Reviewed-by: ogoffart --- src/gui/widgets/qtoolbar.cpp | 16 ++++++++++++++++ src/gui/widgets/qtoolbar.h | 1 + 2 files changed, 17 insertions(+) diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp index 40c0b02..5596ca4 100644 --- a/src/gui/widgets/qtoolbar.cpp +++ b/src/gui/widgets/qtoolbar.cpp @@ -183,6 +183,9 @@ void QToolBarPrivate::setWindowState(bool floating, bool unplug, const QRect &re if (visible) q->show(); + + if (floating != wasFloating) + emit q->topLevelChanged(floating); } void QToolBarPrivate::initDrag(const QPoint &pos) @@ -518,6 +521,19 @@ void QToolBarPrivate::plug(const QRect &r) */ /*! + \since 4.6 + + \fn void QToolBar::topLevelChanged(bool topLevel) + + This signal is emitted when the \l floating property changes. + The \a topLevel parameter is true if the toolbar is now floating; + otherwise it is false. + + \sa isWindow() +*/ + + +/*! Constructs a QToolBar with the given \a parent. */ QToolBar::QToolBar(QWidget *parent) diff --git a/src/gui/widgets/qtoolbar.h b/src/gui/widgets/qtoolbar.h index a084673..a1a24f0 100644 --- a/src/gui/widgets/qtoolbar.h +++ b/src/gui/widgets/qtoolbar.h @@ -142,6 +142,7 @@ Q_SIGNALS: void orientationChanged(Qt::Orientation orientation); void iconSizeChanged(const QSize &iconSize); void toolButtonStyleChanged(Qt::ToolButtonStyle toolButtonStyle); + void topLevelChanged(bool topLevel); protected: void actionEvent(QActionEvent *event); -- cgit v0.12 From 2c672ea518265496a0fc7c5de63ca7dda880dd85 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Tue, 27 Oct 2009 16:06:36 +0100 Subject: QAbstractSocket: insert timer to prevent timeout This fixes a timeout that occurred on Mac with the gui event dispatcher: we were waiting for a write notification, but timed out when we were in closing state and still waiting for the socket engine to complete writing. Now we close the socket anyway after 2 seconds. Reviewed-by: Thiago Macieira --- src/network/socket/qabstractsocket.cpp | 29 +++++++++++++++++++++++++++-- src/network/socket/qabstractsocket.h | 1 + src/network/socket/qabstractsocket_p.h | 2 ++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 955fee0..89a6e91 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -462,6 +462,7 @@ QAbstractSocketPrivate::QAbstractSocketPrivate() isBuffered(false), blockingTimeout(30000), connectTimer(0), + disconnectTimer(0), connectTimeElapsed(0), hostLookupId(-1), socketType(QAbstractSocket::UnknownSocketType), @@ -497,9 +498,10 @@ void QAbstractSocketPrivate::resetSocketLayer() socketEngine = 0; cachedSocketDescriptor = -1; } - if (connectTimer) { + if (connectTimer) connectTimer->stop(); - } + if (disconnectTimer) + disconnectTimer->stop(); } /*! \internal @@ -1094,6 +1096,15 @@ void QAbstractSocketPrivate::_q_abortConnectionAttempt() } } +void QAbstractSocketPrivate::_q_forceDisconnect() +{ + Q_Q(QAbstractSocket); + if (socketEngine && socketEngine->isValid() && state == QAbstractSocket::ClosingState) { + socketEngine->close(); + q->disconnectFromHost(); + } +} + /*! \internal Reads data from the socket layer into the read buffer. Returns @@ -2356,6 +2367,20 @@ void QAbstractSocket::disconnectFromHostImplementation() // Wait for pending data to be written. if (d->socketEngine && d->socketEngine->isValid() && (d->writeBuffer.size() > 0 || d->socketEngine->bytesToWrite() > 0)) { + // hack: when we are waiting for the socket engine to write bytes (only + // possible when using Socks5 or HTTP socket engine), then close + // anyway after 2 seconds. This is to prevent a timeout on Mac, where we + // sometimes just did not get the write notifier from the underlying + // CFSocket and no progress was made. + if (d->writeBuffer.size() == 0 && d->socketEngine->bytesToWrite() > 0) { + if (!d->disconnectTimer) { + d->disconnectTimer = new QTimer(this); + connect(d->disconnectTimer, SIGNAL(timeout()), this, + SLOT(_q_forceDisconnect()), Qt::DirectConnection); + } + if (!d->disconnectTimer->isActive()) + d->disconnectTimer->start(2000); + } d->socketEngine->setWriteNotificationEnabled(true); #if defined(QABSTRACTSOCKET_DEBUG) diff --git a/src/network/socket/qabstractsocket.h b/src/network/socket/qabstractsocket.h index 5d94a01..5cfae17 100644 --- a/src/network/socket/qabstractsocket.h +++ b/src/network/socket/qabstractsocket.h @@ -216,6 +216,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_startConnecting(const QHostInfo &)) Q_PRIVATE_SLOT(d_func(), void _q_abortConnectionAttempt()) Q_PRIVATE_SLOT(d_func(), void _q_testConnection()) + Q_PRIVATE_SLOT(d_func(), void _q_forceDisconnect()) #ifdef QT3_SUPPORT public: diff --git a/src/network/socket/qabstractsocket_p.h b/src/network/socket/qabstractsocket_p.h index 8ccddd3..acf82bf 100644 --- a/src/network/socket/qabstractsocket_p.h +++ b/src/network/socket/qabstractsocket_p.h @@ -93,6 +93,7 @@ public: void _q_startConnecting(const QHostInfo &hostInfo); void _q_testConnection(); void _q_abortConnectionAttempt(); + void _q_forceDisconnect(); bool readSocketNotifierCalled; bool readSocketNotifierState; @@ -148,6 +149,7 @@ public: int blockingTimeout; QTimer *connectTimer; + QTimer *disconnectTimer; int connectTimeElapsed; int hostLookupId; -- cgit v0.12 From f0fa85911b1b5aeedf61a1c41ee81674b1575cc7 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 27 Oct 2009 17:01:32 +0100 Subject: In Qt3Support, the "line up" action for toolbars was not working Task-number: QTBUG-1063 Reviewed-by: ogoffart --- src/qt3support/widgets/q3dockarea.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt3support/widgets/q3dockarea.cpp b/src/qt3support/widgets/q3dockarea.cpp index afeefff..bb34622 100644 --- a/src/qt3support/widgets/q3dockarea.cpp +++ b/src/qt3support/widgets/q3dockarea.cpp @@ -1019,6 +1019,7 @@ void Q3DockArea::lineUp(bool keepNewLines) if (!keepNewLines) dw->setNewLine(false); } + layout->invalidate(); layout->activate(); } -- cgit v0.12 From ad342b62f1b4c6b9ca0997ddb937f3871f6d875b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 27 Oct 2009 18:19:53 +0100 Subject: Make QProcess report errors from a failed subprocess start. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: João Abecasis --- src/corelib/io/qprocess_unix.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 99296c7..f040d16 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -108,6 +108,10 @@ QT_END_NAMESPACE QT_BEGIN_NAMESPACE +// POSIX requires PIPE_BUF to be 512 or larger +// so we will use 512 +static const int errorBufferMax = 512; + #ifdef Q_OS_INTEGRITY static inline char *strdup(const char *data) { @@ -752,18 +756,19 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv } // notify failure + QString error = qt_error_string(errno); #if defined (QPROCESS_DEBUG) - fprintf(stderr, "QProcessPrivate::execChild() failed, notifying parent process\n"); + fprintf(stderr, "QProcessPrivate::execChild() failed (%s), notifying parent process\n", qPrintable(error)); #endif - qt_safe_write(childStartedPipe[1], "", 1); + qt_safe_write(childStartedPipe[1], error.data(), error.length() * sizeof(QChar)); qt_safe_close(childStartedPipe[1]); childStartedPipe[1] = -1; } bool QProcessPrivate::processStarted() { - char c; - int i = qt_safe_read(childStartedPipe[0], &c, 1); + ushort buf[errorBufferMax]; + int i = qt_safe_read(childStartedPipe[0], &buf, sizeof buf); if (startupSocketNotifier) { startupSocketNotifier->setEnabled(false); startupSocketNotifier->deleteLater(); @@ -775,6 +780,11 @@ bool QProcessPrivate::processStarted() #if defined (QPROCESS_DEBUG) qDebug("QProcessPrivate::processStarted() == %s", i <= 0 ? "true" : "false"); #endif + + // did we read an error message? + if (i > 0) + q_func()->setErrorString(QString::fromUtf16(buf, i / sizeof(QChar))); + return i <= 0; } -- cgit v0.12 From b3435aa7ae1eb4a0766b82560980e49039aea1d8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 27 Oct 2009 17:54:03 +0100 Subject: Autotest: Add some debugging info as to why the subprocess fails to start --- tests/auto/qudpsocket/tst_qudpsocket.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/auto/qudpsocket/tst_qudpsocket.cpp b/tests/auto/qudpsocket/tst_qudpsocket.cpp index 7ea2163..9418be0 100644 --- a/tests/auto/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/qudpsocket/tst_qudpsocket.cpp @@ -719,6 +719,8 @@ void tst_QUdpSocket::outOfProcessConnectedClientServerTest() QProcess serverProcess; serverProcess.start(QLatin1String("clientserver/clientserver server 1 1"), QIODevice::ReadWrite | QIODevice::Text); + QVERIFY2(serverProcess.waitForStarted(3000), + qPrintable("Failed to start subprocess: " + serverProcess.errorString())); // Wait until the server has started and reports success. while (!serverProcess.canReadLine()) @@ -732,6 +734,9 @@ void tst_QUdpSocket::outOfProcessConnectedClientServerTest() clientProcess.start(QString::fromLatin1("clientserver/clientserver connectedclient %1 %2") .arg(QLatin1String("127.0.0.1")).arg(serverPort), QIODevice::ReadWrite | QIODevice::Text); + QVERIFY2(clientProcess.waitForStarted(3000), + qPrintable("Failed to start subprocess: " + clientProcess.errorString())); + // Wait until the server has started and reports success. while (!clientProcess.canReadLine()) QVERIFY(clientProcess.waitForReadyRead(3000)); @@ -779,6 +784,8 @@ void tst_QUdpSocket::outOfProcessUnconnectedClientServerTest() QProcess serverProcess; serverProcess.start(QLatin1String("clientserver/clientserver server 1 1"), QIODevice::ReadWrite | QIODevice::Text); + QVERIFY2(serverProcess.waitForStarted(3000), + qPrintable("Failed to start subprocess: " + serverProcess.errorString())); // Wait until the server has started and reports success. while (!serverProcess.canReadLine()) @@ -792,6 +799,9 @@ void tst_QUdpSocket::outOfProcessUnconnectedClientServerTest() clientProcess.start(QString::fromLatin1("clientserver/clientserver unconnectedclient %1 %2") .arg(QLatin1String("127.0.0.1")).arg(serverPort), QIODevice::ReadWrite | QIODevice::Text); + QVERIFY2(clientProcess.waitForStarted(3000), + qPrintable("Failed to start subprocess: " + clientProcess.errorString())); + // Wait until the server has started and reports success. while (!clientProcess.canReadLine()) QVERIFY(clientProcess.waitForReadyRead(3000)); -- cgit v0.12 From 588b1c40115b975ad4998251646f00db23144cd4 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 27 Oct 2009 20:07:38 +0100 Subject: Compile --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 5bc6708..5f7d5b9 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include +#include #include #include -- cgit v0.12 From b209ab1e2139cb50e26bbeeb094da9a6a4a8a067 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 27 Oct 2009 19:58:10 +0100 Subject: Always use QExplicitlySharedDataPointer Fixes a refcount bug that occurs when QFont is constructed from a QFontPrivate* that was created without an initial ref(). Merge-request: 1831 Reviewed-by: Olivier Goffart --- src/gui/text/qfont.cpp | 12 +++++------ src/gui/text/qfontinfo.h | 3 ++- src/gui/text/qfontmetrics.cpp | 49 +++++++++++++++++++------------------------ src/gui/text/qfontmetrics.h | 5 +++-- 4 files changed, 32 insertions(+), 37 deletions(-) diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 1285935..8722f5b 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -2324,22 +2324,22 @@ QDataStream &operator>>(QDataStream &s, QFont &font) */ QFontInfo::QFontInfo(const QFont &font) : d(font.d.data()) -{ d->ref.ref(); } +{ +} /*! Constructs a copy of \a fi. */ QFontInfo::QFontInfo(const QFontInfo &fi) - : d(fi.d) -{ d->ref.ref(); } + : d(fi.d.data()) +{ +} /*! Destroys the font info object. */ QFontInfo::~QFontInfo() { - if (!d->ref.deref()) - delete d; } /*! @@ -2347,7 +2347,7 @@ QFontInfo::~QFontInfo() */ QFontInfo &QFontInfo::operator=(const QFontInfo &fi) { - qAtomicAssign(d, fi.d); + d = fi.d.data(); return *this; } diff --git a/src/gui/text/qfontinfo.h b/src/gui/text/qfontinfo.h index 335d761..0998949 100644 --- a/src/gui/text/qfontinfo.h +++ b/src/gui/text/qfontinfo.h @@ -43,6 +43,7 @@ #define QFONTINFO_H #include +#include QT_BEGIN_HEADER @@ -77,7 +78,7 @@ public: bool exactMatch() const; private: - QFontPrivate *d; + QExplicitlySharedDataPointer d; }; QT_END_NAMESPACE diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index ce122aa..b8c1b33 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -165,7 +165,6 @@ extern int qt_defaultDpi(); QFontMetrics::QFontMetrics(const QFont &font) : d(font.d.data()) { - d->ref.ref(); } /*! @@ -196,7 +195,6 @@ QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice) d->screen = screen; } else { d = font.d.data(); - d->ref.ref(); } } @@ -205,8 +203,9 @@ QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice) Constructs a copy of \a fm. */ QFontMetrics::QFontMetrics(const QFontMetrics &fm) - : d(fm.d) -{ d->ref.ref(); } + : d(fm.d.data()) +{ +} /*! Destroys the font metrics object and frees all allocated @@ -214,8 +213,6 @@ QFontMetrics::QFontMetrics(const QFontMetrics &fm) */ QFontMetrics::~QFontMetrics() { - if (!d->ref.deref()) - delete d; } /*! @@ -223,7 +220,7 @@ QFontMetrics::~QFontMetrics() */ QFontMetrics &QFontMetrics::operator=(const QFontMetrics &fm) { - qAtomicAssign(d, fm.d); + d = fm.d.data(); return *this; } @@ -536,7 +533,7 @@ int QFontMetrics::width(const QString &text, int len) const if (len == 0) return 0; - QTextEngine layout(text, d); + QTextEngine layout(text, d.data()); layout.ignoreBidi = true; return qRound(layout.width(0, len)); } @@ -612,7 +609,7 @@ int QFontMetrics::charWidth(const QString &text, int pos) const int from = qMax(0, pos - 8); int to = qMin(text.length(), pos + 8); QString cstr = QString::fromRawData(text.unicode() + from, to - from); - QTextEngine layout(cstr, d); + QTextEngine layout(cstr, d.data()); layout.ignoreBidi = true; layout.itemize(); width = qRound(layout.width(pos-from, 1)); @@ -661,7 +658,7 @@ QRect QFontMetrics::boundingRect(const QString &text) const if (text.length() == 0) return QRect(); - QTextEngine layout(text, d); + QTextEngine layout(text, d.data()); layout.ignoreBidi = true; layout.itemize(); glyph_metrics_t gm = layout.boundingBox(0, text.length()); @@ -770,7 +767,7 @@ QRect QFontMetrics::boundingRect(const QRect &rect, int flags, const QString &te QRectF rb; QRectF rr(rect); - qt_format_text(QFont(d), rr, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray, + qt_format_text(QFont(d.data()), rr, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray, tabArrayLen, 0); return rb.toAlignedRect(); @@ -831,7 +828,7 @@ QRect QFontMetrics::tightBoundingRect(const QString &text) const if (text.length() == 0) return QRect(); - QTextEngine layout(text, d); + QTextEngine layout(text, d.data()); layout.ignoreBidi = true; layout.itemize(); glyph_metrics_t gm = layout.tightBoundingBox(0, text.length()); @@ -876,7 +873,7 @@ QString QFontMetrics::elidedText(const QString &text, Qt::TextElideMode mode, in } _text = _text.mid(posA); } - QStackTextEngine engine(_text, QFont(d)); + QStackTextEngine engine(_text, QFont(d.data())); return engine.elidedText(mode, width, flags); } @@ -989,9 +986,8 @@ int QFontMetrics::lineWidth() const from the given \a fontMetrics object. */ QFontMetricsF::QFontMetricsF(const QFontMetrics &fontMetrics) - : d(fontMetrics.d) + : d(fontMetrics.d.data()) { - d->ref.ref(); } /*! @@ -1001,7 +997,7 @@ QFontMetricsF::QFontMetricsF(const QFontMetrics &fontMetrics) */ QFontMetricsF &QFontMetricsF::operator=(const QFontMetrics &other) { - qAtomicAssign(d, other.d); + d = other.d.data(); return *this; } @@ -1021,7 +1017,6 @@ QFontMetricsF &QFontMetricsF::operator=(const QFontMetrics &other) QFontMetricsF::QFontMetricsF(const QFont &font) : d(font.d.data()) { - d->ref.ref(); } /*! @@ -1052,7 +1047,6 @@ QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice) d->screen = screen; } else { d = font.d.data(); - d->ref.ref(); } } @@ -1061,8 +1055,9 @@ QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice) Constructs a copy of \a fm. */ QFontMetricsF::QFontMetricsF(const QFontMetricsF &fm) - : d(fm.d) -{ d->ref.ref(); } + : d(fm.d.data()) +{ +} /*! Destroys the font metrics object and frees all allocated @@ -1070,8 +1065,6 @@ QFontMetricsF::QFontMetricsF(const QFontMetricsF &fm) */ QFontMetricsF::~QFontMetricsF() { - if (!d->ref.deref()) - delete d; } /*! @@ -1079,7 +1072,7 @@ QFontMetricsF::~QFontMetricsF() */ QFontMetricsF &QFontMetricsF::operator=(const QFontMetricsF &fm) { - qAtomicAssign(d, fm.d); + d = fm.d.data(); return *this; } @@ -1374,7 +1367,7 @@ qreal QFontMetricsF::rightBearing(QChar ch) const */ qreal QFontMetricsF::width(const QString &text) const { - QTextEngine layout(text, d); + QTextEngine layout(text, d.data()); layout.ignoreBidi = true; layout.itemize(); return layout.width(0, text.length()).toReal(); @@ -1451,7 +1444,7 @@ QRectF QFontMetricsF::boundingRect(const QString &text) const if (len == 0) return QRectF(); - QTextEngine layout(text, d); + QTextEngine layout(text, d.data()); layout.ignoreBidi = true; layout.itemize(); glyph_metrics_t gm = layout.boundingBox(0, len); @@ -1559,7 +1552,7 @@ QRectF QFontMetricsF::boundingRect(const QRectF &rect, int flags, const QString& tabArrayLen++; QRectF rb; - qt_format_text(QFont(d), rect, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray, + qt_format_text(QFont(d.data()), rect, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray, tabArrayLen, 0); return rb; } @@ -1624,7 +1617,7 @@ QRectF QFontMetricsF::tightBoundingRect(const QString &text) const if (text.length() == 0) return QRect(); - QTextEngine layout(text, d); + QTextEngine layout(text, d.data()); layout.ignoreBidi = true; layout.itemize(); glyph_metrics_t gm = layout.tightBoundingBox(0, text.length()); @@ -1649,7 +1642,7 @@ QRectF QFontMetricsF::tightBoundingRect(const QString &text) const */ QString QFontMetricsF::elidedText(const QString &text, Qt::TextElideMode mode, qreal width, int flags) const { - QStackTextEngine engine(text, QFont(d)); + QStackTextEngine engine(text, QFont(d.data())); return engine.elidedText(mode, QFixed::fromReal(width), flags); } diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h index 1147e3a..23200c5 100644 --- a/src/gui/text/qfontmetrics.h +++ b/src/gui/text/qfontmetrics.h @@ -43,6 +43,7 @@ #define QFONTMETRICS_H #include +#include #ifndef QT_INCLUDE_COMPAT #include #endif @@ -131,7 +132,7 @@ private: friend class QFontMetricsF; friend class QStackTextEngine; - QFontPrivate *d; + QExplicitlySharedDataPointer d; }; @@ -187,7 +188,7 @@ public: inline bool operator !=(const QFontMetricsF &other) const { return !operator==(other); } private: - QFontPrivate *d; + QExplicitlySharedDataPointer d; }; QT_END_NAMESPACE -- cgit v0.12 From df0001a3d62938c713b351c7e59228b803ec5670 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 27 Oct 2009 19:49:33 +0100 Subject: QFontMetrics test For commit b209ab1e2139cb5 --- tests/auto/qfontmetrics/tst_qfontmetrics.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp index 6b2f0fe..e80f8e0 100644 --- a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp +++ b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp @@ -100,6 +100,20 @@ void tst_QFontMetrics::same() QFontMetrics fm(font); const QString text = QLatin1String("Some stupid STRING"); QCOMPARE(fm.size(0, text), fm.size(0, text)) ; + + { + QImage image; + QFontMetrics fm2(font, &image); + QString text2 = QLatin1String("Foo Foo"); + QCOMPARE(fm2.size(0, text2), fm2.size(0, text2)); //used to crash + } + + { + QImage image; + QFontMetricsF fm3(font, &image); + QString text2 = QLatin1String("Foo Foo"); + QCOMPARE(fm3.size(0, text2), fm3.size(0, text2)); //used to crash + } } -- cgit v0.12 From 08e5bae295204ac0cadc1dda6c7a01599f66a2bb Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 28 Oct 2009 09:42:14 +0100 Subject: Let QGraphicsItem set QObjectPrivate::wasDeleted when appropriate. This change allows children of QGraphicsObject-derived classes to check if the parent is being deleted by checking the private flag wasDeleted. Reverts 37b16d5cbb4e7bc534f690ebf50434d228b5ecfc, p4 change 9681, to allow QGraphicsItem to set QObjectPrivate's wasDeleted member before entering QObjectPrivate's destructor. The original code was in there to let the user know, via the console output, that QObject was double-deleted (e.g., when placing QObject on the stack, and also giving it a parent, so that if the parent is deleted first, bang). Reviewed-by: Aaron Kennedy Reviewed-by: Bradley T. Hughes --- src/corelib/kernel/qobject.cpp | 7 ---- src/gui/graphicsview/qgraphicsitem.cpp | 2 ++ tests/auto/qgraphicsobject/tst_qgraphicsobject.cpp | 42 ++++++++++++++++++++++ 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 7be19b3..5303975 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -835,14 +835,7 @@ QObject::QObject(QObjectPrivate &dd, QObject *parent) QObject::~QObject() { Q_D(QObject); - if (d->wasDeleted) { -#if defined(QT_DEBUG) - qWarning("QObject: Double deletion detected"); -#endif - return; - } d->wasDeleted = true; - d->blockSig = 0; // unblock signals so we always emit destroyed() if (!d->isWidget) { diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index ad672a3..2e68d3e 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1286,6 +1286,8 @@ QGraphicsItem::QGraphicsItem(QGraphicsItemPrivate &dd, QGraphicsItem *parent, */ QGraphicsItem::~QGraphicsItem() { + if (d_ptr->isObject) + QObjectPrivate::get(static_cast(this))->wasDeleted = true; d_ptr->inDestructor = 1; d_ptr->removeExtraItemCache(); diff --git a/tests/auto/qgraphicsobject/tst_qgraphicsobject.cpp b/tests/auto/qgraphicsobject/tst_qgraphicsobject.cpp index a9fd55a..194665d 100644 --- a/tests/auto/qgraphicsobject/tst_qgraphicsobject.cpp +++ b/tests/auto/qgraphicsobject/tst_qgraphicsobject.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include "../../shared/util.h" class tst_QGraphicsObject : public QObject { @@ -65,6 +66,7 @@ private slots: void opacity(); void enabled(); void visible(); + void deleted(); }; @@ -249,6 +251,46 @@ void tst_QGraphicsObject::visible() QVERIFY(object.property("visible") == true); } +class DeleteTester : public QGraphicsObject +{ +public: + DeleteTester(bool *w, bool *pw, QGraphicsItem *parent = 0) + : QGraphicsObject(parent), wasDeleted(w), parentWasDeleted(pw) + { } + + ~DeleteTester() + { + *wasDeleted = QObjectPrivate::get(this)->wasDeleted; + if (QGraphicsItem *p = parentItem()) { + if (QGraphicsObject *o = p->toGraphicsObject()) + *parentWasDeleted = QObjectPrivate::get(o)->wasDeleted; + } + } + + void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0) + { } + QRectF boundingRect() const + { return QRectF(); } + + bool *wasDeleted; + bool *parentWasDeleted; +}; + +void tst_QGraphicsObject::deleted() +{ + bool item1_parentWasDeleted = false; + bool item1_wasDeleted = false; + bool item2_parentWasDeleted = false; + bool item2_wasDeleted = false; + DeleteTester *item1 = new DeleteTester(&item1_wasDeleted, &item1_parentWasDeleted); + DeleteTester *item2 = new DeleteTester(&item2_wasDeleted, &item2_parentWasDeleted, item1); + delete item1; + + QVERIFY(!item1_wasDeleted); // destructor not called yet + QVERIFY(!item1_parentWasDeleted); // no parent + QVERIFY(!item2_wasDeleted); // destructor not called yet + QVERIFY(item2_parentWasDeleted); +} QTEST_MAIN(tst_QGraphicsObject) #include "tst_qgraphicsobject.moc" -- cgit v0.12 From a8b5aefc48d619c1fc0ff1e97c8e3a42baccb7c0 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Tue, 27 Oct 2009 19:07:03 +0100 Subject: QDom autotests: test is not failing anymore removing the temporary QFAIL Reviewed-by: Carlos Duclos --- tests/auto/qdom/tst_qdom.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/auto/qdom/tst_qdom.cpp b/tests/auto/qdom/tst_qdom.cpp index f3a7909..6637202 100644 --- a/tests/auto/qdom/tst_qdom.cpp +++ b/tests/auto/qdom/tst_qdom.cpp @@ -322,9 +322,6 @@ void tst_QDom::toString_01_data() */ void tst_QDom::toString_01() { -#ifdef Q_OS_WIN - QFAIL("make test fail instead of timing out, will be fixed later (QT-2357)"); -#endif QFETCH(QString, fileName); QFile f(fileName); -- cgit v0.12 From 5c7345809d7f620981f92cc2e93beb14b10504a9 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 23 Oct 2009 10:54:09 +0200 Subject: Add the ability for the match-rule builder to add argument matching. I'll use this feature to match the NameOwnerChanged signal from the bus. --- src/dbus/qdbusconnection.cpp | 4 ++-- src/dbus/qdbusconnection_p.h | 1 + src/dbus/qdbusintegrator.cpp | 17 +++++++++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index bb0d06f..bead369 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -609,7 +609,7 @@ bool QDBusConnection::connect(const QString &service, const QString &path, const QString owner = d->getNameOwner(service); // we don't care if the owner is empty hook.signature = signature; // it might get started later - if (!d->prepareHook(hook, key, service, owner, path, interface, name, receiver, slot, 0, false)) + if (!d->prepareHook(hook, key, service, owner, path, interface, name, QStringList(), receiver, slot, 0, false)) return false; // don't connect // avoid duplicating: @@ -663,7 +663,7 @@ bool QDBusConnection::disconnect(const QString &service, const QString &path, co QString owner = d->getNameOwner(service); // we don't care of owner is empty hook.signature = signature; - if (!d->prepareHook(hook, key, service, owner, path, interface, name, receiver, slot, 0, false)) + if (!d->prepareHook(hook, key, service, owner, path, interface, name, QStringList(), receiver, slot, 0, false)) return false; // don't disconnect // avoid duplicating: diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index ab96457..df51c27 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -278,6 +278,7 @@ public: static bool prepareHook(QDBusConnectionPrivate::SignalHook &hook, QString &key, const QString &service, const QString &owner, const QString &path, const QString &interface, const QString &name, + const QStringList &argMatch, QObject *receiver, const char *signal, int minMIdx, bool buildSignature); static DBusHandlerResult messageFilter(DBusConnection *, DBusMessage *, void *); diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index fb2dd77..9e41708 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -392,7 +392,7 @@ static void qDBusNewConnection(DBusServer *server, DBusConnection *connection, v static QByteArray buildMatchRule(const QString &service, const QString & /*owner*/, const QString &objectPath, const QString &interface, - const QString &member, const QString & /*signature*/) + const QString &member, const QStringList &argMatch, const QString & /*signature*/) { QString result = QLatin1String("type='signal',"); QString keyValue = QLatin1String("%1='%2',"); @@ -406,6 +406,14 @@ static QByteArray buildMatchRule(const QString &service, const QString & /*owner if (!member.isEmpty()) result += keyValue.arg(QLatin1String("member"), member); + // add the argument string-matching now + if (!argMatch.isEmpty()) { + keyValue = QLatin1String("arg%1='%2',"); + for (int i = 0; i < argMatch.count(); ++i) + if (!argMatch.at(i).isNull()) + result += keyValue.arg(i).arg(argMatch.at(i)); + } + result.chop(1); // remove ending comma return result.toLatin1(); } @@ -1195,6 +1203,7 @@ int QDBusConnectionPrivate::findSlot(QObject* obj, const QByteArray &normalizedN bool QDBusConnectionPrivate::prepareHook(QDBusConnectionPrivate::SignalHook &hook, QString &key, const QString &service, const QString &owner, const QString &path, const QString &interface, const QString &name, + const QStringList &argMatch, QObject *receiver, const char *signal, int minMIdx, bool buildSignature) { @@ -1235,7 +1244,7 @@ bool QDBusConnectionPrivate::prepareHook(QDBusConnectionPrivate::SignalHook &hoo hook.signature += QLatin1String( QDBusMetaType::typeToSignature( hook.params.at(i) ) ); } - hook.matchRule = buildMatchRule(service, owner, path, interface, mname, hook.signature); + hook.matchRule = buildMatchRule(service, owner, path, interface, mname, argMatch, hook.signature); return true; // connect to this signal } @@ -2027,7 +2036,7 @@ void QDBusConnectionPrivate::connectRelay(const QString &service, const QString SignalHook hook; QString key; - if (!prepareHook(hook, key, service, owner, path, interface, QString(), receiver, signal, + if (!prepareHook(hook, key, service, owner, path, interface, QString(), QStringList(), receiver, signal, QDBusAbstractInterface::staticMetaObject.methodCount(), true)) return; // don't connect @@ -2059,7 +2068,7 @@ void QDBusConnectionPrivate::disconnectRelay(const QString &service, const QStri SignalHook hook; QString key; - if (!prepareHook(hook, key, service, owner, path, interface, QString(), receiver, signal, + if (!prepareHook(hook, key, service, owner, path, interface, QString(), QStringList(), receiver, signal, QDBusAbstractInterface::staticMetaObject.methodCount(), true)) return; // don't connect -- cgit v0.12 From 735525dc51952c90846c8129b755422b288b204b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 23 Oct 2009 11:13:10 +0200 Subject: Add new public API to QDBusConnection for connecting with string matching. The bus allows us to match string arguments when receiving messages. This is very useful for the NameOwnerChanged signal, whose first argument is usually what we're interested in. By using these new functions, you can restrict receiving of signals to those that you truly want, instead of receiving NameOwnerChanged for all services registered/unregistered on the bus. --- src/dbus/qdbusconnection.cpp | 88 ++++++++++++++++++++++++++++++++++---------- src/dbus/qdbusconnection.h | 12 ++++-- 2 files changed, 78 insertions(+), 22 deletions(-) diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index bead369..3aaba68 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -557,42 +557,61 @@ QDBusPendingCall QDBusConnection::asyncCall(const QDBusMessage &message, int tim bool QDBusConnection::connect(const QString &service, const QString &path, const QString& interface, const QString &name, QObject *receiver, const char *slot) { - return connect(service, path, interface, name, QString(), receiver, slot); + return connect(service, path, interface, name, QStringList(), QString(), receiver, slot); } /*! - Disconnects the signal specified by the \a service, \a path, \a interface and \a name parameters from - the slot \a slot in object \a receiver. The arguments \a service and \a path can be empty, - denoting a disconnection from all signals of the (\a interface, \a name) pair, from all remote - applications. + \overload - Returns true if the disconnection was successful. + Connects the signal to the slot \a slot in object \a + receiver. Unlike the previous connect() overload, this function + allows one to specify the parameter signature to be connected + using the \a signature variable. The function will then verify + that this signature can be delivered to the slot specified by \a + slot and return false otherwise. + + Returns true if the connection was successful. + + \note This function verifies that the signal signature matches the + slot's parameters, but it does not verify that the actual + signal exists with the given signature in the remote + service. */ -bool QDBusConnection::disconnect(const QString &service, const QString &path, const QString &interface, - const QString &name, QObject *receiver, const char *slot) +bool QDBusConnection::connect(const QString &service, const QString &path, const QString& interface, + const QString &name, const QString &signature, + QObject *receiver, const char *slot) { - return disconnect(service, path, interface, name, QString(), receiver, slot); + return connect(service, path, interface, name, QStringList(), signature, receiver, slot); } /*! \overload + \since 4.6 Connects the signal to the slot \a slot in object \a - receiver. Unlike the other connect() overload, this function + receiver. Unlike the previous connect() overload, this function allows one to specify the parameter signature to be connected using the \a signature variable. The function will then verify that this signature can be delivered to the slot specified by \a slot and return false otherwise. + The \a argumentMatch parameter lists the string parameters to be matched, + in sequential order. Note that, to match an empty string, you need to + pass a QString that is empty but not null (i.e., QString("")). A null + QString skips matching at that position. + + Returns true if the connection was successful. + \note This function verifies that the signal signature matches the slot's parameters, but it does not verify that the actual signal exists with the given signature in the remote service. */ bool QDBusConnection::connect(const QString &service, const QString &path, const QString& interface, - const QString &name, const QString &signature, + const QString &name, const QStringList &argumentMatch, const QString &signature, QObject *receiver, const char *slot) { + if (!receiver || !slot || !d || !d->connection) return false; if (!interface.isEmpty() && !QDBusUtil::isValidInterfaceName(interface)) @@ -609,7 +628,7 @@ bool QDBusConnection::connect(const QString &service, const QString &path, const QString owner = d->getNameOwner(service); // we don't care if the owner is empty hook.signature = signature; // it might get started later - if (!d->prepareHook(hook, key, service, owner, path, interface, name, QStringList(), receiver, slot, 0, false)) + if (!d->prepareHook(hook, key, service, owner, path, interface, name, argumentMatch, receiver, slot, 0, false)) return false; // don't connect // avoid duplicating: @@ -634,19 +653,50 @@ bool QDBusConnection::connect(const QString &service, const QString &path, const } /*! + Disconnects the signal specified by the \a service, \a path, \a interface + and \a name parameters from the slot \a slot in object \a receiver. The + arguments must be the same as passed to the connect() function. + + Returns true if the disconnection was successful. +*/ +bool QDBusConnection::disconnect(const QString &service, const QString &path, const QString &interface, + const QString &name, QObject *receiver, const char *slot) +{ + return disconnect(service, path, interface, name, QStringList(), QString(), receiver, slot); +} + +/*! \overload - Disconnects the signal from the slot \a slot in object \a - receiver. Unlike the other disconnect() overload, this function - allows one to specify the parameter signature to be disconnected - using the \a signature variable. The function will then verify - that this signature is connected to the slot specified by \a slot - and return false otherwise. + Disconnects the signal specified by the \a service, \a path, \a + interface, \a name, and \a signature parameters from the slot \a slot in + object \a receiver. The arguments must be the same as passed to the + connect() function. + + Returns true if the disconnection was successful. */ bool QDBusConnection::disconnect(const QString &service, const QString &path, const QString& interface, const QString &name, const QString &signature, QObject *receiver, const char *slot) { + return disconnect(service, path, interface, name, QStringList(), signature, receiver, slot); +} + +/*! + \overload + \since 4.6 + + Disconnects the signal specified by the \a service, \a path, \a + interface, \a name, \a argumentMatch, and \a signature parameters from + the slot \a slot in object \a receiver. The arguments must be the same as + passed to the connect() function. + + Returns true if the disconnection was successful. +*/ +bool QDBusConnection::disconnect(const QString &service, const QString &path, const QString& interface, + const QString &name, const QStringList &argumentMatch, const QString &signature, + QObject *receiver, const char *slot) +{ if (!receiver || !slot || !d || !d->connection) return false; if (!interface.isEmpty() && !QDBusUtil::isValidInterfaceName(interface)) @@ -663,7 +713,7 @@ bool QDBusConnection::disconnect(const QString &service, const QString &path, co QString owner = d->getNameOwner(service); // we don't care of owner is empty hook.signature = signature; - if (!d->prepareHook(hook, key, service, owner, path, interface, name, QStringList(), receiver, slot, 0, false)) + if (!d->prepareHook(hook, key, service, owner, path, interface, name, argumentMatch, receiver, slot, 0, false)) return false; // don't disconnect // avoid duplicating: diff --git a/src/dbus/qdbusconnection.h b/src/dbus/qdbusconnection.h index 85fc7c2..82ae726 100644 --- a/src/dbus/qdbusconnection.h +++ b/src/dbus/qdbusconnection.h @@ -132,15 +132,21 @@ public: bool connect(const QString &service, const QString &path, const QString &interface, const QString &name, QObject *receiver, const char *slot); - bool disconnect(const QString &service, const QString &path, const QString &interface, - const QString &name, QObject *receiver, const char *slot); - bool connect(const QString &service, const QString &path, const QString &interface, const QString &name, const QString& signature, QObject *receiver, const char *slot); + bool connect(const QString &service, const QString &path, const QString &interface, + const QString &name, const QStringList &argumentMatch, const QString& signature, + QObject *receiver, const char *slot); + + bool disconnect(const QString &service, const QString &path, const QString &interface, + const QString &name, QObject *receiver, const char *slot); bool disconnect(const QString &service, const QString &path, const QString &interface, const QString &name, const QString& signature, QObject *receiver, const char *slot); + bool disconnect(const QString &service, const QString &path, const QString &interface, + const QString &name, const QStringList &argumentMatch, const QString& signature, + QObject *receiver, const char *slot); bool registerObject(const QString &path, QObject *object, RegisterOptions options = ExportAdaptors); -- cgit v0.12 From c180071b66d4e5c22248c488df57c6acd6aa36ed Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 23 Oct 2009 19:23:51 +0200 Subject: Autotest: fix improper use of the serviceOwnerChanged signal This test was doubly wrong: it first registered a service name, then it connected to signal to watch it. You can't receive a signal if you connect to it after it's emitted... Second, it waited for any serviceOwnerChanged() signal to exit the event loop, not necessarily the one we wanted to receive. This used to work because we'd always connect to the D-Bus signal, but now we don't anymore. --- tests/auto/qdbusinterface/tst_qdbusinterface.cpp | 34 ++++++++---------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp index e31a3a0..62d6342 100644 --- a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp +++ b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp @@ -171,6 +171,13 @@ class tst_QDBusInterface: public QObject { Q_OBJECT MyObject obj; +public slots: + void testServiceOwnerChanged(const QString &service) + { + if (service == "com.example.Test") + QTestEventLoop::instance().exitLoop(); + } + private slots: void initTestCase(); @@ -235,32 +242,13 @@ void tst_QDBusInterface::invalidAfterServiceOwnerChanged() QDBusInterface invalidInterface("com.example.Test", "/"); QVERIFY(!invalidInterface.isValid()); + QTestEventLoop::instance().connect(connIface, SIGNAL(serviceOwnerChanged(QString, QString, QString)), + SLOT(exitLoop())); QVERIFY(connIface->registerService("com.example.Test") == QDBusConnectionInterface::ServiceRegistered); - QSignalSpy serviceOwnerChangedSpy(connIface, SIGNAL(serviceOwnerChanged(QString, QString, QString))); - - QEventLoop loop; - QObject::connect(connIface, SIGNAL(serviceOwnerChanged(QString, QString, QString)), - &loop, SLOT(quit())); - loop.exec(); - - // at least once, but other services might have changed while running the test, too. - QVERIFY(serviceOwnerChangedSpy.count() >= 1); - bool foundOurService = false; - for (int i = 0; i < serviceOwnerChangedSpy.count(); ++i) { - QList args = serviceOwnerChangedSpy.at(i); - QString name = args[0].toString(); - QString oldOwner = args[1].toString(); - QString newOwner = args[2].toString(); - if (name == QLatin1String("com.example.Test")) { - if (newOwner == conn.baseService()) { - foundOurService = true; - break; - } - } - } - QVERIFY(foundOurService); + QTestEventLoop::instance().enterLoop(5); + QVERIFY(!QTestEventLoop::instance().timeout()); QVERIFY(!invalidInterface.isValid()); } -- cgit v0.12 From feca69fb15a4176689e4f58252361750f3444275 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 23 Oct 2009 19:25:56 +0200 Subject: Autotest: add a test that tries to follow a service changing owners. I'm not sure if this used to work before... --- .../tst_qdbusabstractinterface.cpp | 56 ++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp index baf769f..d84350b 100644 --- a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp +++ b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp @@ -103,6 +103,8 @@ private slots: void getComplexSignal_data(); void getComplexSignal(); + void followSignal(); + void createErrors_data(); void createErrors(); @@ -432,6 +434,60 @@ void tst_QDBusAbstractInterface::getComplexSignal() QCOMPARE(s[0][0].value(), expectedValue); } +void tst_QDBusAbstractInterface::followSignal() +{ + const QString serviceToFollow = "com.trolltech.tst_qdbusabstractinterface.FollowMe"; + Pinger p = getPinger(serviceToFollow); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusConnection con = p->connection(); + QVERIFY(!con.interface()->isServiceRegistered(serviceToFollow)); + Pinger control = getPinger(""); + + // we need to connect the signal somewhere in order for D-Bus to enable the rules + QTestEventLoop::instance().connect(p.data(), SIGNAL(voidSignal()), SLOT(exitLoop())); + QTestEventLoop::instance().connect(control.data(), SIGNAL(voidSignal()), SLOT(exitLoop())); + QSignalSpy s(p.data(), SIGNAL(voidSignal())); + + emit targetObj.voidSignal(); + QTestEventLoop::instance().enterLoop(200); + QVERIFY(!QTestEventLoop::instance().timeout()); + + // signal must not have been received because the service isn't registered + QVERIFY(s.isEmpty()); + + // now register the service + QDBusReply r = + con.interface()->registerService(serviceToFollow, QDBusConnectionInterface::DontQueueService, + QDBusConnectionInterface::DontAllowReplacement); + QVERIFY(r.isValid() && r.value() == QDBusConnectionInterface::ServiceRegistered); + QVERIFY(con.interface()->isServiceRegistered(serviceToFollow)); + + // emit the signal again: + emit targetObj.voidSignal(); + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!QTestEventLoop::instance().timeout()); + + // now the signal must have been received: + QVERIFY(s.size() == 1); + QVERIFY(s.at(0).size() == 0); + s.clear(); + + // disconnect the signal + disconnect(p.data(), SIGNAL(voidSignal()), &QTestEventLoop::instance(), 0); + + // emit the signal again: + emit targetObj.voidSignal(); + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!QTestEventLoop::instance().timeout()); + + // and now it mustn't have been received + QVERIFY(s.isEmpty()); + + // cleanup: + con.interface()->unregisterService(serviceToFollow); +} + void tst_QDBusAbstractInterface::createErrors_data() { QTest::addColumn("service"); -- cgit v0.12 From 95d68417bfced3458e72ab3fdbc8f97ab15dd1db Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 23 Oct 2009 12:02:40 +0200 Subject: Use the new argument-based rule-matching in QDBusAbstractInterface. This allows us to listen only to the activations we're really interested in. --- src/dbus/qdbusabstractinterface.cpp | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp index 61a9d95..bea365a 100644 --- a/src/dbus/qdbusabstractinterface.cpp +++ b/src/dbus/qdbusabstractinterface.cpp @@ -279,9 +279,17 @@ QDBusAbstractInterface::QDBusAbstractInterface(QDBusAbstractInterfacePrivate &d, : QDBusAbstractInterfaceBase(d, parent) { // keep track of the service owner - if (!d_func()->currentOwner.isEmpty()) - QObject::connect(d_func()->connectionPrivate(), SIGNAL(serviceOwnerChanged(QString,QString,QString)), - this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); + if (d.isValid && + d.connection.isConnected() + && !d.service.isEmpty() + && !d.service.startsWith(QLatin1Char(':'))) + d_func()->connection.connect(QLatin1String(DBUS_SERVICE_DBUS), // service + QString(), // path + QLatin1String(DBUS_INTERFACE_DBUS), // interface + QLatin1String("NameOwnerChanged"), + QStringList() << d.service, + QString(), // signature + this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); } /*! @@ -296,9 +304,17 @@ QDBusAbstractInterface::QDBusAbstractInterface(const QString &service, const QSt con, false), parent) { // keep track of the service owner - if (d_func()->connection.isConnected()) - QObject::connect(d_func()->connectionPrivate(), SIGNAL(serviceOwnerChanged(QString,QString,QString)), - this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); + if (d_func()->isValid && + d_func()->connection.isConnected() + && !service.isEmpty() + && !service.startsWith(QLatin1Char(':'))) + d_func()->connection.connect(QLatin1String(DBUS_SERVICE_DBUS), // service + QString(), // path + QLatin1String(DBUS_INTERFACE_DBUS), // interface + QLatin1String("NameOwnerChanged"), + QStringList() << service, + QString(), //signature + this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); } /*! -- cgit v0.12 From 26c5680cf5adbf0c87357d84f2e2a6256724d4b7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 23 Oct 2009 19:28:35 +0200 Subject: Fix the use of the owner when connecting the service "watcher". Use null services to indicate we're not interested in the owner, but empty-but-not-null to indicate we don't know what the owner is. Since empty service names are not valid, this will mean that this rule won't match. --- src/dbus/qdbusabstractinterface.cpp | 11 +++++++++-- src/dbus/qdbusintegrator.cpp | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp index bea365a..994da10 100644 --- a/src/dbus/qdbusabstractinterface.cpp +++ b/src/dbus/qdbusabstractinterface.cpp @@ -560,9 +560,16 @@ void QDBusAbstractInterface::connectNotify(const char *signal) return; QDBusConnectionPrivate *conn = d->connectionPrivate(); - if (conn) - conn->connectRelay(d->service, d->currentOwner, d->path, d->interface, + if (conn) { + // do we know what our owner is? + QString owner; + if (!d->service.isEmpty() && d->currentOwner.isNull()) + owner = QLatin1String(""); + else + owner = d->currentOwner; + conn->connectRelay(d->service, owner, d->path, d->interface, this, signal); + } } /*! diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 9e41708..8fff8b3 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1487,7 +1487,7 @@ void QDBusConnectionPrivate::handleSignal(const QString &key, const QDBusMessage //qDBusDebug() << signalHooks.keys(); for ( ; it != end && it.key() == key; ++it) { const SignalHook &hook = it.value(); - if (!hook.owner.isEmpty() && hook.owner != msg.service()) + if (!hook.owner.isNull() && hook.owner != msg.service()) continue; if (!hook.path.isEmpty() && hook.path != msg.path()) continue; -- cgit v0.12 From ed75146e45d41ca52b64193acbf433e6d2ceaaf5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 23 Oct 2009 19:33:38 +0200 Subject: Move the bulk of the signal connecting/disconnecting code to QDBusConnectionPrivate I'll need to recurse into the signal connection mechanism in the next commit. --- src/dbus/qdbusconnection.cpp | 63 ++------------------------------------ src/dbus/qdbusconnection_p.h | 6 ++++ src/dbus/qdbusintegrator.cpp | 73 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 60 deletions(-) diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index 3aaba68..71e433e 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -619,37 +619,10 @@ bool QDBusConnection::connect(const QString &service, const QString &path, const if (interface.isEmpty() && name.isEmpty()) return false; - // check the slot - QDBusConnectionPrivate::SignalHook hook; - QString key; - QString name2 = name; - if (name2.isNull()) - name2.detach(); - QString owner = d->getNameOwner(service); // we don't care if the owner is empty - hook.signature = signature; // it might get started later - if (!d->prepareHook(hook, key, service, owner, path, interface, name, argumentMatch, receiver, slot, 0, false)) - return false; // don't connect - - // avoid duplicating: + // it might get started later QDBusWriteLocker locker(ConnectAction, d); - QDBusConnectionPrivate::SignalHookHash::ConstIterator it = d->signalHooks.find(key); - QDBusConnectionPrivate::SignalHookHash::ConstIterator end = d->signalHooks.constEnd(); - for ( ; it != end && it.key() == key; ++it) { - const QDBusConnectionPrivate::SignalHook &entry = it.value(); - if (entry.service == hook.service && - entry.owner == hook.owner && - entry.path == hook.path && - entry.signature == hook.signature && - entry.obj == hook.obj && - entry.midx == hook.midx) { - // no need to compare the parameters if it's the same slot - return true; // already there - } - } - - d->connectSignal(key, hook); - return true; + return d->connectSignal(service, owner, path, interface, name, argumentMatch, signature, receiver, slot); } /*! @@ -704,38 +677,8 @@ bool QDBusConnection::disconnect(const QString &service, const QString &path, co if (interface.isEmpty() && name.isEmpty()) return false; - // check the slot - QDBusConnectionPrivate::SignalHook hook; - QString key; - QString name2 = name; - if (name2.isNull()) - name2.detach(); - - QString owner = d->getNameOwner(service); // we don't care of owner is empty - hook.signature = signature; - if (!d->prepareHook(hook, key, service, owner, path, interface, name, argumentMatch, receiver, slot, 0, false)) - return false; // don't disconnect - - // avoid duplicating: QDBusWriteLocker locker(DisconnectAction, d); - QDBusConnectionPrivate::SignalHookHash::Iterator it = d->signalHooks.find(key); - QDBusConnectionPrivate::SignalHookHash::Iterator end = d->signalHooks.end(); - for ( ; it != end && it.key() == key; ++it) { - const QDBusConnectionPrivate::SignalHook &entry = it.value(); - if (entry.service == hook.service && - entry.owner == hook.owner && - entry.path == hook.path && - entry.signature == hook.signature && - entry.obj == hook.obj && - entry.midx == hook.midx) { - // no need to compare the parameters if it's the same slot - d->disconnectSignal(it); - return true; // it was there - } - } - - // the slot was not found - return false; + return d->disconnectSignal(service, path, interface, name, argumentMatch, signature, receiver, slot); } /*! diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index df51c27..2402719 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -175,8 +175,14 @@ public: QDBusPendingCallPrivate *sendWithReplyAsync(const QDBusMessage &message, int timeout = -1); int sendWithReplyAsync(const QDBusMessage &message, QObject *receiver, const char *returnMethod, const char *errorMethod, int timeout = -1); + bool connectSignal(const QString &service, const QString &owner, const QString &path, const QString& interface, + const QString &name, const QStringList &argumentMatch, const QString &signature, + QObject *receiver, const char *slot); void connectSignal(const QString &key, const SignalHook &hook); SignalHookHash::Iterator disconnectSignal(SignalHookHash::Iterator &it); + bool disconnectSignal(const QString &service, const QString &path, const QString& interface, + const QString &name, const QStringList &argumentMatch, const QString &signature, + QObject *receiver, const char *slot); void registerObject(const ObjectTreeNode *node); void connectRelay(const QString &service, const QString ¤tOwner, const QString &path, const QString &interface, diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 8fff8b3..89a7449 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1942,6 +1942,42 @@ int QDBusConnectionPrivate::sendWithReplyAsync(const QDBusMessage &message, QObj return 1; } +bool QDBusConnectionPrivate::connectSignal(const QString &service, const QString &owner, + const QString &path, const QString &interface, const QString &name, + const QStringList &argumentMatch, const QString &signature, + QObject *receiver, const char *slot) +{ + // check the slot + QDBusConnectionPrivate::SignalHook hook; + QString key; + QString name2 = name; + if (name2.isNull()) + name2.detach(); + + hook.signature = signature; + if (!prepareHook(hook, key, service, owner, path, interface, name, argumentMatch, receiver, slot, 0, false)) + return false; // don't connect + + // avoid duplicating: + QDBusConnectionPrivate::SignalHookHash::ConstIterator it = signalHooks.find(key); + QDBusConnectionPrivate::SignalHookHash::ConstIterator end = signalHooks.constEnd(); + for ( ; it != end && it.key() == key; ++it) { + const QDBusConnectionPrivate::SignalHook &entry = it.value(); + if (entry.service == hook.service && + entry.owner == hook.owner && + entry.path == hook.path && + entry.signature == hook.signature && + entry.obj == hook.obj && + entry.midx == hook.midx) { + // no need to compare the parameters if it's the same slot + return true; // already there + } + } + + connectSignal(key, hook); + return true; +} + void QDBusConnectionPrivate::connectSignal(const QString &key, const SignalHook &hook) { signalHooks.insertMulti(key, hook); @@ -1973,6 +2009,43 @@ void QDBusConnectionPrivate::connectSignal(const QString &key, const SignalHook } } +bool QDBusConnectionPrivate::disconnectSignal(const QString &service, + const QString &path, const QString &interface, const QString &name, + const QStringList &argumentMatch, const QString &signature, + QObject *receiver, const char *slot) +{ + // check the slot + QDBusConnectionPrivate::SignalHook hook; + QString key; + QString name2 = name; + if (name2.isNull()) + name2.detach(); + + hook.signature = signature; + if (!prepareHook(hook, key, service, QString(), path, interface, name, argumentMatch, receiver, slot, 0, false)) + return false; // don't disconnect + + // avoid duplicating: + QDBusConnectionPrivate::SignalHookHash::Iterator it = signalHooks.find(key); + QDBusConnectionPrivate::SignalHookHash::Iterator end = signalHooks.end(); + for ( ; it != end && it.key() == key; ++it) { + const QDBusConnectionPrivate::SignalHook &entry = it.value(); + if (entry.service == hook.service && + //entry.owner == hook.owner && + entry.path == hook.path && + entry.signature == hook.signature && + entry.obj == hook.obj && + entry.midx == hook.midx) { + // no need to compare the parameters if it's the same slot + disconnectSignal(it); + return true; // it was there + } + } + + // the slot was not found + return false; +} + QDBusConnectionPrivate::SignalHookHash::Iterator QDBusConnectionPrivate::disconnectSignal(SignalHookHash::Iterator &it) { -- cgit v0.12 From 1176ecf0b533279e5a1c97f183e5c5f1c57fb188 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 23 Oct 2009 19:35:19 +0200 Subject: Stop using the NameOwnerChanged signal without arg0 in QtDBus itself We were using this signal to update the signal hooks when the remote service changed. That meant each Qt app received every single service creation, change or destruction. Now we only watch the services we're really interested in. --- src/dbus/qdbusconnection.cpp | 4 ---- src/dbus/qdbusconnection_p.h | 2 ++ src/dbus/qdbusintegrator.cpp | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index 71e433e..d7088ff 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -1005,14 +1005,10 @@ void QDBusConnectionPrivate::setBusService(const QDBusConnection &connection) busService = new QDBusConnectionInterface(connection, this); ref.deref(); // busService has increased the refcounting to us // avoid cyclic refcounting -// if (mode != PeerMode) - QObject::connect(busService, SIGNAL(serviceOwnerChanged(QString,QString,QString)), - this, SIGNAL(serviceOwnerChanged(QString,QString,QString))); QObject::connect(this, SIGNAL(callWithCallbackFailed(QDBusError,QDBusMessage)), busService, SIGNAL(callWithCallbackFailed(QDBusError,QDBusMessage)), Qt::QueuedConnection); - } /*! diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index 2402719..ed29e4e 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -154,6 +154,7 @@ public: typedef QMultiHash SignalHookHash; typedef QHash MetaObjectHash; typedef QHash MatchRefCountHash; + typedef QHash WatchedServicesHash; public: // public methods are entry points from other objects @@ -270,6 +271,7 @@ public: QDBusError lastError; QStringList serviceNames; + WatchedServicesHash watchedServiceNames; SignalHookHash signalHooks; MatchRefCountHash matchRefCounts; ObjectTreeNode rootNode; diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 89a7449..c7538c3 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -501,6 +501,11 @@ static QObject *findChildObject(const QDBusConnectionPrivate::ObjectTreeNode *ro return 0; } +static bool shouldWatchService(const QString &service) +{ + return !service.isEmpty() && !service.startsWith(QLatin1Char(':')); +} + extern QDBUS_EXPORT void qDBusAddSpyHook(QDBusSpyHook); void qDBusAddSpyHook(QDBusSpyHook hook) { @@ -941,6 +946,7 @@ QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p) QDBusMetaTypeId::init(); rootNode.flags = 0; + watchedServiceNames[QLatin1String(DBUS_SERVICE_DBUS)] = 1; connect(this, SIGNAL(serviceOwnerChanged(QString,QString,QString)), this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); @@ -2005,6 +2011,22 @@ void QDBusConnectionPrivate::connectSignal(const QString &key, const SignalHook hook.obj->metaObject()->method(hook.midx).signature(), qPrintable(qerror.name()), qPrintable(qerror.message())); Q_ASSERT(false); + } else { + // Successfully connected the signal + // Do we need to watch for this name? + if (shouldWatchService(hook.service)) { + WatchedServicesHash::Iterator it = watchedServiceNames.find(hook.service); + if (it != watchedServiceNames.end()) { + // already watching + ++it.value(); + } else { + // we need to watch for this service changing + QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS); + connectSignal(dbusServerService, dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS), + QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(), + this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); + } + } } } } @@ -2051,6 +2073,19 @@ QDBusConnectionPrivate::disconnectSignal(SignalHookHash::Iterator &it) { const SignalHook &hook = it.value(); + WatchedServicesHash::Iterator sit = watchedServiceNames.find(hook.service); + if (sit != watchedServiceNames.end()) { + if (sit.value() == 1) { + watchedServiceNames.erase(sit); + QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS); + disconnectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS), + QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(), + this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); + } else { + --sit.value(); + } + } + bool erase = false; MatchRefCountHash::iterator i = matchRefCounts.find(hook.matchRule); if (i == matchRefCounts.end()) { -- cgit v0.12 From da9a3a919326e35730b13d0660bb4a7b64e2c81c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 23 Oct 2009 19:37:16 +0200 Subject: Add a warning to user's connecting to serviceOwnerChanged directly We want people to not use this signal directly. --- src/dbus/qdbusconnectioninterface.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/dbus/qdbusconnectioninterface.cpp b/src/dbus/qdbusconnectioninterface.cpp index 8670ed5..414d318 100644 --- a/src/dbus/qdbusconnectioninterface.cpp +++ b/src/dbus/qdbusconnectioninterface.cpp @@ -336,8 +336,14 @@ void QDBusConnectionInterface::connectNotify(const char *signalName) else if (qstrcmp(signalName, SIGNAL(serviceUnregistered(QString))) == 0) QDBusAbstractInterface::connectNotify(SIGNAL(NameLost(QString))); - else if (qstrcmp(signalName, SIGNAL(serviceOwnerChanged(QString,QString,QString))) == 0) + else if (qstrcmp(signalName, SIGNAL(serviceOwnerChanged(QString,QString,QString))) == 0) { + static bool warningPrinted = false; + if (!warningPrinted) { + qWarning("Connecting to deprecated signal QDBusConnectionInterface::serviceOwnerChanged(QString,QString,QString)"); + warningPrinted = true; + } QDBusAbstractInterface::connectNotify(SIGNAL(NameOwnerChanged(QString,QString,QString))); + } } /*! -- cgit v0.12 From fb941d5c297e3205d421126c38a9f3a262584b88 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 26 Oct 2009 12:21:29 +0100 Subject: Add QDBusServiceWatcher class. --- src/dbus/dbus.pro | 148 ++++++++++++++------------- src/dbus/qdbusservicewatcher.cpp | 211 +++++++++++++++++++++++++++++++++++++++ src/dbus/qdbusservicewatcher.h | 103 +++++++++++++++++++ 3 files changed, 393 insertions(+), 69 deletions(-) create mode 100644 src/dbus/qdbusservicewatcher.cpp create mode 100644 src/dbus/qdbusservicewatcher.h diff --git a/src/dbus/dbus.pro b/src/dbus/dbus.pro index 57c6a58..9ab3920 100644 --- a/src/dbus/dbus.pro +++ b/src/dbus/dbus.pro @@ -1,77 +1,87 @@ -TARGET = QtDBus -QPRO_PWD = $$PWD -QT = core xml -CONFIG += link_pkgconfig -DEFINES += QDBUS_MAKEDLL DBUS_API_SUBJECT_TO_CHANGE +TARGET = QtDBus +QPRO_PWD = $$PWD +QT = core \ + xml +CONFIG += link_pkgconfig +DEFINES += QDBUS_MAKEDLL \ + DBUS_API_SUBJECT_TO_CHANGE QMAKE_CXXFLAGS += $$QT_CFLAGS_DBUS - -contains(QT_CONFIG, dbus-linked) { +contains(QT_CONFIG, dbus-linked) { LIBS_PRIVATE += $$QT_LIBS_DBUS - DEFINES += QT_LINKED_LIBDBUS + DEFINES += QT_LINKED_LIBDBUS } -#INCLUDEPATH += . - -unix { - QMAKE_PKGCONFIG_DESCRIPTION = Qt DBus module - QMAKE_PKGCONFIG_REQUIRES = QtCore QtXml +# INCLUDEPATH += . +unix { + QMAKE_PKGCONFIG_DESCRIPTION = Qt \ + DBus \ + module + QMAKE_PKGCONFIG_REQUIRES = QtCore \ + QtXml } - -win32 { - LIBS_PRIVATE += -lws2_32 -ladvapi32 -lnetapi32 -luser32 - CONFIG(debug, debug|release):LIBS_PRIVATE += -ldbus-1d - else:LIBS_PRIVATE += -ldbus-1 +win32 { + LIBS_PRIVATE += -lws2_32 \ + -ladvapi32 \ + -lnetapi32 \ + -luser32 + CONFIG(debug, debug|release):LIBS_PRIVATE += -ldbus-1d + else:LIBS_PRIVATE += -ldbus-1 } - include(../qbase.pri) - -PUB_HEADERS = qdbusargument.h \ - qdbusconnectioninterface.h \ - qdbusmacros.h \ - qdbuserror.h \ - qdbusextratypes.h \ - qdbusmessage.h \ - qdbusserver.h \ - qdbusconnection.h \ - qdbusabstractinterface.h \ - qdbusinterface.h \ - qdbusabstractadaptor.h \ - qdbusreply.h \ - qdbusmetatype.h \ - qdbuspendingcall.h \ - qdbuspendingreply.h \ - qdbuscontext.h - +PUB_HEADERS = qdbusargument.h \ + qdbusconnectioninterface.h \ + qdbusmacros.h \ + qdbuserror.h \ + qdbusextratypes.h \ + qdbusmessage.h \ + qdbusserver.h \ + qdbusconnection.h \ + qdbusabstractinterface.h \ + qdbusinterface.h \ + qdbusabstractadaptor.h \ + qdbusreply.h \ + qdbusmetatype.h \ + qdbuspendingcall.h \ + qdbuspendingreply.h \ + qdbuscontext.h HEADERS += $$PUB_HEADERS \ - qdbusconnection_p.h qdbusmessage_p.h \ - qdbusinterface_p.h qdbusxmlparser_p.h qdbusabstractadaptor_p.h \ - qdbusargument_p.h qdbusutil_p.h qdbusabstractinterface_p.h \ - qdbuscontext_p.h qdbusthreaddebug_p.h qdbusintegrator_p.h \ - qdbuspendingcall_p.h qdbus_symbols_p.h - -SOURCES += qdbusconnection.cpp \ - qdbusconnectioninterface.cpp \ - qdbuserror.cpp \ - qdbusintegrator.cpp \ - qdbusmessage.cpp \ - qdbusserver.cpp \ - qdbusabstractinterface.cpp \ - qdbusinterface.cpp \ - qdbusxmlparser.cpp \ - qdbusutil.cpp \ - qdbusintrospection.cpp \ - qdbusabstractadaptor.cpp \ - qdbusinternalfilters.cpp \ - qdbusmetaobject.cpp \ - qdbusxmlgenerator.cpp \ - qdbusmisc.cpp \ - qdbusargument.cpp \ - qdbusreply.cpp \ - qdbusmetatype.cpp \ - qdbusextratypes.cpp \ - qdbusmarshaller.cpp \ - qdbuscontext.cpp \ - qdbuspendingcall.cpp \ - qdbuspendingreply.cpp \ - qdbus_symbols.cpp - + qdbusconnection_p.h \ + qdbusmessage_p.h \ + qdbusinterface_p.h \ + qdbusxmlparser_p.h \ + qdbusabstractadaptor_p.h \ + qdbusargument_p.h \ + qdbusutil_p.h \ + qdbusabstractinterface_p.h \ + qdbuscontext_p.h \ + qdbusthreaddebug_p.h \ + qdbusintegrator_p.h \ + qdbuspendingcall_p.h \ + qdbus_symbols_p.h \ + qdbusservicewatcher.h +SOURCES += qdbusconnection.cpp \ + qdbusconnectioninterface.cpp \ + qdbuserror.cpp \ + qdbusintegrator.cpp \ + qdbusmessage.cpp \ + qdbusserver.cpp \ + qdbusabstractinterface.cpp \ + qdbusinterface.cpp \ + qdbusxmlparser.cpp \ + qdbusutil.cpp \ + qdbusintrospection.cpp \ + qdbusabstractadaptor.cpp \ + qdbusinternalfilters.cpp \ + qdbusmetaobject.cpp \ + qdbusxmlgenerator.cpp \ + qdbusmisc.cpp \ + qdbusargument.cpp \ + qdbusreply.cpp \ + qdbusmetatype.cpp \ + qdbusextratypes.cpp \ + qdbusmarshaller.cpp \ + qdbuscontext.cpp \ + qdbuspendingcall.cpp \ + qdbuspendingreply.cpp \ + qdbus_symbols.cpp \ + qdbusservicewatcher.cpp diff --git a/src/dbus/qdbusservicewatcher.cpp b/src/dbus/qdbusservicewatcher.cpp new file mode 100644 index 0000000..d8a33c3 --- /dev/null +++ b/src/dbus/qdbusservicewatcher.cpp @@ -0,0 +1,211 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDBus module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdbusservicewatcher.h" +#include "qdbusconnection.h" +#include "qdbus_symbols_p.h" + +#include + +#include + +Q_GLOBAL_STATIC_WITH_ARGS(QString, busService, (QLatin1String(DBUS_SERVICE_DBUS))) +Q_GLOBAL_STATIC_WITH_ARGS(QString, busPath, (QLatin1String(DBUS_PATH_DBUS))) +Q_GLOBAL_STATIC_WITH_ARGS(QString, busInterface, (QLatin1String(DBUS_INTERFACE_DBUS))) +Q_GLOBAL_STATIC_WITH_ARGS(QString, signalName, (QLatin1String("NameOwnerChanged"))) + +class QDBusServiceWatcherPrivate: public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QDBusServiceWatcher) +public: + QDBusServiceWatcherPrivate(const QDBusConnection &c, QDBusServiceWatcher::WatchMode wm) + : connection(c), watchMode(wm) + { + } + + QStringList servicesWatched; + QDBusConnection connection; + QDBusServiceWatcher::WatchMode watchMode; + + void _q_serviceOwnerChanged(const QString &, const QString &, const QString &); + void setConnection(const QStringList &services, const QDBusConnection &c, QDBusServiceWatcher::WatchMode watchMode); + + QStringList matchArgsForService(const QString &service); + void addService(const QString &service); + void removeService(const QString &service); +}; + +void QDBusServiceWatcherPrivate::_q_serviceOwnerChanged(const QString &service, const QString &oldOwner, const QString &newOwner) +{ + Q_Q(QDBusServiceWatcher); + emit q->serviceOwnerChanged(service, oldOwner, newOwner); + if (oldOwner.isEmpty()) + emit q->serviceRegistered(service); + else if (newOwner.isEmpty()) + emit q->serviceUnregistered(service); +} + +void QDBusServiceWatcherPrivate::setConnection(const QStringList &s, const QDBusConnection &c, QDBusServiceWatcher::WatchMode wm) +{ + if (connection.isConnected()) { + // remove older rules + foreach (const QString &s, servicesWatched) + removeService(s); + } + + connection = c; + watchMode = wm; + servicesWatched = s; + + if (connection.isConnected()) { + // add new rules + foreach (const QString &s, servicesWatched) + addService(s); + } +} + +QStringList QDBusServiceWatcherPrivate::matchArgsForService(const QString &service) +{ + QStringList matchArgs; + matchArgs << service; + + switch (watchMode) { + case QDBusServiceWatcher::WatchForOwnerChange: + break; + + case QDBusServiceWatcher::WatchForRegistration: + matchArgs << QString::fromLatin1("", 0); + break; + + case QDBusServiceWatcher::WatchForUnregistration: + matchArgs << QString() << QString::fromLatin1("", 0); + break; + } + return matchArgs; +} + +void QDBusServiceWatcherPrivate::addService(const QString &service) +{ + QStringList matchArgs = matchArgsForService(service); + connection.connect(*busService(), *busPath(), *busInterface(), *signalName(), + matchArgs, QString(), q_func(), + SLOT(_q_serviceOwnerChanged(QString,QString,QString))); +} + +void QDBusServiceWatcherPrivate::removeService(const QString &service) +{ + QStringList matchArgs = matchArgsForService(service); + connection.disconnect(*busService(), *busPath(), *busInterface(), *signalName(), + matchArgs, QString(), q_func(), + SLOT(_q_serviceOwnerChanged(QString,QString,QString))); +} + +QDBusServiceWatcher::QDBusServiceWatcher(QObject *parent) + : QObject(*new QDBusServiceWatcherPrivate(QDBusConnection(QString()), WatchForOwnerChange), parent) +{ +} + +QDBusServiceWatcher::QDBusServiceWatcher(const QString &service, const QDBusConnection &connection, WatchMode watchMode, QObject *parent) + : QObject(*new QDBusServiceWatcherPrivate(connection, watchMode), parent) +{ + d_func()->setConnection(QStringList() << service, connection, watchMode); +} + +QDBusServiceWatcher::~QDBusServiceWatcher() +{ +} + +QStringList QDBusServiceWatcher::watchedServices() const +{ + return d_func()->servicesWatched; +} + +void QDBusServiceWatcher::setWatchedServices(const QStringList &services) +{ + Q_D(QDBusServiceWatcher); + if (services == d->servicesWatched) + return; + d->setConnection(services, d->connection, d->watchMode); +} + +void QDBusServiceWatcher::addWatchedService(const QString &newService) +{ + Q_D(QDBusServiceWatcher); + if (d->servicesWatched.contains(newService)) + return; + d->addService(newService); + d->servicesWatched << newService; +} + +bool QDBusServiceWatcher::removeWatchedService(const QString &service) +{ + Q_D(QDBusServiceWatcher); + d->removeService(service); + return d->servicesWatched.removeOne(service); +} + +QDBusServiceWatcher::WatchMode QDBusServiceWatcher::watchMode() const +{ + return d_func()->watchMode; +} + +void QDBusServiceWatcher::setWatchMode(WatchMode mode) +{ + Q_D(QDBusServiceWatcher); + if (mode == d->watchMode) + return; + d->setConnection(d->servicesWatched, d->connection, mode); +} + +QDBusConnection QDBusServiceWatcher::connection() const +{ + return d_func()->connection; +} + +void QDBusServiceWatcher::setConnection(const QDBusConnection &connection) +{ + Q_D(QDBusServiceWatcher); + if (connection.name() == d->connection.name()) + return; + d->setConnection(d->servicesWatched, connection, d->watchMode); +} + +#include "moc_qdbusservicewatcher.cpp" diff --git a/src/dbus/qdbusservicewatcher.h b/src/dbus/qdbusservicewatcher.h new file mode 100644 index 0000000..a968a9c --- /dev/null +++ b/src/dbus/qdbusservicewatcher.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDBus module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDBUSSERVICEWATCHER_H +#define QDBUSSERVICEWATCHER_H + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(DBus) + +class QDBusConnection; + +class QDBusServiceWatcherPrivate; +class QDBUS_EXPORT QDBusServiceWatcher: public QObject +{ + Q_OBJECT + Q_PROPERTY(QStringList watchedServices READ watchedServices WRITE setWatchedServices) + Q_PROPERTY(WatchMode watchMode READ watchMode WRITE setWatchMode) +public: + enum WatchModeFlag { + WatchForRegistration = 0x01, + WatchForUnregistration = 0x02, + WatchForOwnerChange = 0x03 + }; + Q_DECLARE_FLAGS(WatchMode, WatchModeFlag) + + explicit QDBusServiceWatcher(QObject *parent = 0); + QDBusServiceWatcher(const QString &service, const QDBusConnection &connection, + WatchMode watchMode = WatchForOwnerChange, QObject *parent = 0); + ~QDBusServiceWatcher(); + + QStringList watchedServices() const; + void setWatchedServices(const QStringList &services); + void addWatchedService(const QString &newService); + bool removeWatchedService(const QString &service); + + WatchMode watchMode() const; + void setWatchMode(WatchMode mode); + + QDBusConnection connection() const; + void setConnection(const QDBusConnection &connection); + +Q_SIGNALS: + void serviceRegistered(const QString &service); + void serviceUnregistered(const QString &service); + void serviceOwnerChanged(const QString &service, const QString &oldOwner, const QString &newOwner); + +private: + Q_PRIVATE_SLOT(d_func(), void _q_serviceOwnerChanged(QString,QString,QString)) + Q_DISABLE_COPY(QDBusServiceWatcher) + Q_DECLARE_PRIVATE(QDBusServiceWatcher) +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QDBusServiceWatcher::WatchMode) + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QDBUSSERVICEWATCHER_H -- cgit v0.12 From f9b55c5263ba25e707c8cc35988935a804af2f50 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 26 Oct 2009 14:08:01 +0100 Subject: Autotest: add unit test for QDBusServiceWatcher --- .../qdbusservicewatcher/qdbusservicewatcher.pro | 8 + .../tst_qdbusservicewatcher.cpp | 273 +++++++++++++++++++++ 2 files changed, 281 insertions(+) create mode 100644 tests/auto/qdbusservicewatcher/qdbusservicewatcher.pro create mode 100644 tests/auto/qdbusservicewatcher/tst_qdbusservicewatcher.cpp diff --git a/tests/auto/qdbusservicewatcher/qdbusservicewatcher.pro b/tests/auto/qdbusservicewatcher/qdbusservicewatcher.pro new file mode 100644 index 0000000..4970f16 --- /dev/null +++ b/tests/auto/qdbusservicewatcher/qdbusservicewatcher.pro @@ -0,0 +1,8 @@ +load(qttest_p4) +QT = core +contains(QT_CONFIG,dbus): { + SOURCES += tst_qdbusservicewatcher.cpp + QT += dbus +} else { + SOURCES += ../qdbusmarshall/dummy.cpp +} diff --git a/tests/auto/qdbusservicewatcher/tst_qdbusservicewatcher.cpp b/tests/auto/qdbusservicewatcher/tst_qdbusservicewatcher.cpp new file mode 100644 index 0000000..10b43b1 --- /dev/null +++ b/tests/auto/qdbusservicewatcher/tst_qdbusservicewatcher.cpp @@ -0,0 +1,273 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +class tst_QDBusServiceWatcher: public QObject +{ + Q_OBJECT + QString serviceName; +public: + tst_QDBusServiceWatcher(); + +private slots: + void initTestCase(); + void cleanup(); + + void watchForCreation(); + void watchForDisappearance(); + void watchForOwnerChange(); + void modeChange(); +}; + +tst_QDBusServiceWatcher::tst_QDBusServiceWatcher() + : serviceName("com.example.TestName") +{ +} + +void tst_QDBusServiceWatcher::initTestCase() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); +} + +void tst_QDBusServiceWatcher::cleanup() +{ + // ensure that the name isn't registered + QDBusConnection::sessionBus().unregisterService(serviceName); +} + +void tst_QDBusServiceWatcher::watchForCreation() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + + QDBusServiceWatcher watcher(serviceName, con, QDBusServiceWatcher::WatchForRegistration); + + QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString))); + QSignalSpy spyU(&watcher, SIGNAL(serviceUnregistered(QString))); + QSignalSpy spyO(&watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString))); + QTestEventLoop::instance().connect(&watcher, SIGNAL(serviceRegistered(QString)), SLOT(exitLoop())); + + // register a name + QVERIFY(con.registerService(serviceName)); + + QTestEventLoop::instance().enterLoop(1); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(spyR.count(), 1); + QCOMPARE(spyR.at(0).at(0).toString(), serviceName); + + QCOMPARE(spyU.count(), 0); + + QCOMPARE(spyO.count(), 1); + QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QVERIFY(spyO.at(0).at(1).toString().isEmpty()); + QCOMPARE(spyO.at(0).at(2).toString(), con.baseService()); + + spyR.clear(); + spyU.clear(); + spyO.clear(); + + // unregister it: + con.unregisterService(serviceName); + + // and register again + QVERIFY(con.registerService(serviceName)); + + QTestEventLoop::instance().enterLoop(1); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(spyR.count(), 1); + QCOMPARE(spyR.at(0).at(0).toString(), serviceName); + + QCOMPARE(spyU.count(), 0); + + QCOMPARE(spyO.count(), 1); + QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QVERIFY(spyO.at(0).at(1).toString().isEmpty()); + QCOMPARE(spyO.at(0).at(2).toString(), con.baseService()); +} + +void tst_QDBusServiceWatcher::watchForDisappearance() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + + QDBusServiceWatcher watcher(serviceName, con, QDBusServiceWatcher::WatchForUnregistration); + + QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString))); + QSignalSpy spyU(&watcher, SIGNAL(serviceUnregistered(QString))); + QSignalSpy spyO(&watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString))); + QTestEventLoop::instance().connect(&watcher, SIGNAL(serviceUnregistered(QString)), SLOT(exitLoop())); + + // register a name + QVERIFY(con.registerService(serviceName)); + + // unregister it: + con.unregisterService(serviceName); + + QTestEventLoop::instance().enterLoop(1); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(spyR.count(), 0); + + QCOMPARE(spyU.count(), 1); + QCOMPARE(spyU.at(0).at(0).toString(), serviceName); + + QCOMPARE(spyO.count(), 1); + QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QCOMPARE(spyO.at(0).at(1).toString(), con.baseService()); + QVERIFY(spyO.at(0).at(2).toString().isEmpty()); +} + +void tst_QDBusServiceWatcher::watchForOwnerChange() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + + QDBusServiceWatcher watcher(serviceName, con, QDBusServiceWatcher::WatchForOwnerChange); + + QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString))); + QSignalSpy spyU(&watcher, SIGNAL(serviceUnregistered(QString))); + QSignalSpy spyO(&watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString))); + QTestEventLoop::instance().connect(&watcher, SIGNAL(serviceRegistered(QString)), SLOT(exitLoop())); + + // register a name + QVERIFY(con.registerService(serviceName)); + + QTestEventLoop::instance().enterLoop(1); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(spyR.count(), 1); + QCOMPARE(spyR.at(0).at(0).toString(), serviceName); + + QCOMPARE(spyU.count(), 0); + + QCOMPARE(spyO.count(), 1); + QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QVERIFY(spyO.at(0).at(1).toString().isEmpty()); + QCOMPARE(spyO.at(0).at(2).toString(), con.baseService()); + + spyR.clear(); + spyU.clear(); + spyO.clear(); + + // unregister it: + con.unregisterService(serviceName); + + // and register again + QVERIFY(con.registerService(serviceName)); + + QTestEventLoop::instance().enterLoop(1); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(spyR.count(), 1); + QCOMPARE(spyR.at(0).at(0).toString(), serviceName); + + QCOMPARE(spyU.count(), 1); + QCOMPARE(spyU.at(0).at(0).toString(), serviceName); + + QCOMPARE(spyO.count(), 2); + QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QCOMPARE(spyO.at(0).at(1).toString(), con.baseService()); + QVERIFY(spyO.at(0).at(2).toString().isEmpty()); + QCOMPARE(spyO.at(1).at(0).toString(), serviceName); + QVERIFY(spyO.at(1).at(1).toString().isEmpty()); + QCOMPARE(spyO.at(1).at(2).toString(), con.baseService()); +} + +void tst_QDBusServiceWatcher::modeChange() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + + QDBusServiceWatcher watcher(serviceName, con, QDBusServiceWatcher::WatchForRegistration); + + QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString))); + QSignalSpy spyU(&watcher, SIGNAL(serviceUnregistered(QString))); + QSignalSpy spyO(&watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString))); + QTestEventLoop::instance().connect(&watcher, SIGNAL(serviceRegistered(QString)), SLOT(exitLoop())); + + // register a name + QVERIFY(con.registerService(serviceName)); + + QTestEventLoop::instance().enterLoop(1); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(spyR.count(), 1); + QCOMPARE(spyR.at(0).at(0).toString(), serviceName); + + QCOMPARE(spyU.count(), 0); + + QCOMPARE(spyO.count(), 1); + QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QVERIFY(spyO.at(0).at(1).toString().isEmpty()); + QCOMPARE(spyO.at(0).at(2).toString(), con.baseService()); + + spyR.clear(); + spyU.clear(); + spyO.clear(); + + watcher.setWatchMode(QDBusServiceWatcher::WatchForUnregistration); + + // unregister it: + con.unregisterService(serviceName); + + QTestEventLoop::instance().connect(&watcher, SIGNAL(serviceUnregistered(QString)), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(1); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(spyR.count(), 0); + + QCOMPARE(spyU.count(), 1); + QCOMPARE(spyU.at(0).at(0).toString(), serviceName); + + QCOMPARE(spyO.count(), 1); + QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QCOMPARE(spyO.at(0).at(1).toString(), con.baseService()); + QVERIFY(spyO.at(0).at(2).toString().isEmpty()); +} + +QTEST_MAIN(tst_QDBusServiceWatcher) +#include "tst_qdbusservicewatcher.moc" -- cgit v0.12 From bd9a8091eb8c731569e4972a04f23c9a2f48391c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 26 Oct 2009 15:16:47 +0100 Subject: Doc: add documentation for QDBusServiceWatcher class. --- src/dbus/qdbusservicewatcher.cpp | 163 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) diff --git a/src/dbus/qdbusservicewatcher.cpp b/src/dbus/qdbusservicewatcher.cpp index d8a33c3..4872732 100644 --- a/src/dbus/qdbusservicewatcher.cpp +++ b/src/dbus/qdbusservicewatcher.cpp @@ -138,26 +138,159 @@ void QDBusServiceWatcherPrivate::removeService(const QString &service) SLOT(_q_serviceOwnerChanged(QString,QString,QString))); } +/*! + \class QDBusServiceWatcher + \since 4.6 + \inmodule QtDBus + + \brief The QDBusServiceWatcher class allows the user to watch for a bus service change. + + A QDBusServiceWatcher object can be used to notify the application about + an ownership change of a service name on the bus. It has three watch + modes: + + \list + \o watching for service registration only + \o watching for service unregistration only + \o watching for any kind of service ownership change (the default mode) + \endlist + + Besides being created or deleted, services may change owners without a + unregister/register operation happening. So the \ref serviceRegistered() + and \ref serviceUnregistered() signals may not be emitted if that + happens. + + This class is more efficient than using the + QDBusConnectionInterface::serviceOwnerChanged() signal because it allows + one to receive only the signals for which the class is interested in. + + \sa QDBusConnection +*/ + +/*! + \enum QDBusServiceWatcher::WatchModeFlag + + QDBusServiceWatcher supports three different watch modes, which are configured by this flag: + + \value WatchForRegistration watch for service registration only, ignoring + any signals related to other service ownership change. + + \value WatchForUnregistration watch for service unregistration only, + ignoring any signals related to other service ownership change. + + \value WatchForOwnerChange watch for any kind of service ownership + change. +*/ + +/*! + \property QDBusServiceWatcher::watchMode + + The \c watchMode property holds the current watch mode for this + QDBusServiceWatcher object. The default value for this property is + QDBusServiceWatcher::WatchForOwnershipChange. +*/ + +/*! + \property QDBusServiceWatcher::watchedServices + + The \c servicesWatched property holds the list of services watched. + + Note that modifying this list with setServicesWatched() is an expensive + operation. If you can, prefer to change it by way of addWatchedService() + and removeWatchedService(). +*/ + +/*! + \fn void QDBusServiceWatcher::serviceRegistered(const QString &serviceName) + + This signal is emitted whenever this object detects that the service \a + serviceName became available on the bus. + + \sa serviceUnregistered(), serviceOwnerChanged() +*/ + +/*! + \fn void QDBusServiceWatcher::serviceUnregistered(const QString &serviceName) + + This signal is emitted whenever this object detects that the service \a + serviceName was unregistered from the bus and is no longer available. + + \sa serviceRegistered(), serviceOwnerChanged() +*/ + +/*! + \fn void QDBusServiceWatcher::serviceOwnerChanged(const QString &serviceName, const QString &oldOwner, const QString &newOwner) + + This signal is emitted whenever this object detects that there was a + service ownership change relating to the \a serviceName service. The \a + oldOwner parameter contains the old owner name and \a newOwner is the new + owner. Both \a oldOwner and \a newOwner are unique connection names. + + Note that this signal is also emitted whenever the \a serviceName service + was registered or unregistered. If it was registered, \a oldOwner will + contain an empty string, whereas if it was unregistered, \a newOwner will + contain an empty string. + + If you need only to find out if the service is registered or unregistered + only, without being notified that the ownership changed, consider using + the specific modes for those operations. This class is more efficient if + you use the more specific modes. + + \sa serviceRegistered(), serviceUnregistered() +*/ + +/*! + Creates a QDBusServiceWatcher object. Note that until you set a + connection with setConnection(), this object will not emit any signals. + + The \a parent parameter is passed to QObject to set the parent of this + object. +*/ QDBusServiceWatcher::QDBusServiceWatcher(QObject *parent) : QObject(*new QDBusServiceWatcherPrivate(QDBusConnection(QString()), WatchForOwnerChange), parent) { } +/*! + Creates a QDBusServiceWatcher object and attaches it to the \a connection + connection. Also, this function immediately starts watching for \a + watchMode changes to service \a service. + + The \a parent parameter is passed to QObject to set the parent of this + object. +*/ QDBusServiceWatcher::QDBusServiceWatcher(const QString &service, const QDBusConnection &connection, WatchMode watchMode, QObject *parent) : QObject(*new QDBusServiceWatcherPrivate(connection, watchMode), parent) { d_func()->setConnection(QStringList() << service, connection, watchMode); } +/*! + Destroys the QDBusServiceWatcher object and releases any resources + associated with it. +*/ QDBusServiceWatcher::~QDBusServiceWatcher() { } +/*! + Returns the list of D-Bus services that are being watched. + + \sa setWatchedServices() +*/ QStringList QDBusServiceWatcher::watchedServices() const { return d_func()->servicesWatched; } +/*! + Sets the list of D-Bus services being watched to be \a services. + + Note that setting the entire list means removing all previous rules for + watching services and adding new ones. This is an expensive operation and + should be avoided, if possible. Instead, use addWatchedService() and + removeWatchedService() if you can to manipulate entries in the list. +*/ void QDBusServiceWatcher::setWatchedServices(const QStringList &services) { Q_D(QDBusServiceWatcher); @@ -166,6 +299,11 @@ void QDBusServiceWatcher::setWatchedServices(const QStringList &services) d->setConnection(services, d->connection, d->watchMode); } +/*! + Adds \a newService to the list of services to be watched by this object. + This function is more efficient than setWatchedServices() and should be + used whenever possible to add services. +*/ void QDBusServiceWatcher::addWatchedService(const QString &newService) { Q_D(QDBusServiceWatcher); @@ -175,6 +313,14 @@ void QDBusServiceWatcher::addWatchedService(const QString &newService) d->servicesWatched << newService; } +/*! + Removes the \a service from the list of services being watched by this + object. Note that D-Bus notifications are asynchronous, so there may + still be signals pending delivery about \a service. Those signals will + still be emitted whenever the D-Bus messages are processed. + + This function returns true if any services were removed. +*/ bool QDBusServiceWatcher::removeWatchedService(const QString &service) { Q_D(QDBusServiceWatcher); @@ -195,11 +341,28 @@ void QDBusServiceWatcher::setWatchMode(WatchMode mode) d->setConnection(d->servicesWatched, d->connection, mode); } +/*! + Returns the QDBusConnection that this object is attached to. + + \sa setConnection() +*/ QDBusConnection QDBusServiceWatcher::connection() const { return d_func()->connection; } +/*! + Sets the D-Bus connection that this object is attached to be \a + connection. All services watched will be transferred to this connection. + + Note that QDBusConnection objects are reference counted: + QDBusServiceWatcher will keep a reference for this connection while it + exists. The connection is not closed until the reference count drops to + zero, so this will ensure that any notifications are received while this + QDBusServiceWatcher object exists. + + \sa connection() +*/ void QDBusServiceWatcher::setConnection(const QDBusConnection &connection) { Q_D(QDBusServiceWatcher); -- cgit v0.12 From de7de35082ec21d506a90e68cb30888540ec64cc Mon Sep 17 00:00:00 2001 From: Thorvald Natvig Date: Tue, 20 Oct 2009 13:31:02 +0200 Subject: Fix XML entities in QTextDocument::toHtml() If a QTextDocument contains an anchor with a & in it, this & is not escaped in the toHtml() function, meaning the resulting document can't be parsed as XML as it will contain invalid entities. Reviewed-by: Olivier Goffart Merge-request: 1753 --- src/gui/text/qtextdocument.cpp | 33 ++++++++++++++++++++------ tests/auto/qtextdocument/qtextdocument.pro | 1 + tests/auto/qtextdocument/tst_qtextdocument.cpp | 32 +++++++++++++++++++++++-- 3 files changed, 57 insertions(+), 9 deletions(-) diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index a8956b8..17981e3 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -168,6 +168,25 @@ QString Qt::escape(const QString& plain) return rich; } +static QString escapeXml(const QString &plain) +{ + QString rich; + rich.reserve(int(plain.length() * 1.1)); + for (int i = 0; i < plain.length(); ++i) { + if (plain.at(i) == QLatin1Char('<')) + rich += QLatin1String("<"); + else if (plain.at(i) == QLatin1Char('>')) + rich += QLatin1String(">"); + else if (plain.at(i) == QLatin1Char('&')) + rich += QLatin1String("&"); + else if (plain.at(i) == QLatin1Char('"')) + rich += QLatin1String("""); + else + rich += plain.at(i); + } + return rich; +} + /*! \fn QString Qt::convertFromPlainText(const QString &plain, WhiteSpaceMode mode) @@ -2038,7 +2057,7 @@ void QTextHtmlExporter::emitAttribute(const char *attribute, const QString &valu html += QLatin1Char(' '); html += QLatin1String(attribute); html += QLatin1String("=\""); - html += value; + html += escapeXml(value); html += QLatin1Char('"'); } @@ -2302,12 +2321,12 @@ void QTextHtmlExporter::emitFontFamily(const QString &family) { html += QLatin1String(" font-family:"); - QLatin1Char quote('\''); - if (family.contains(quote)) - quote = QLatin1Char('\"'); + QLatin1String quote("\'"); + if (family.contains(QLatin1Char('\''))) + quote = QLatin1String("""); html += quote; - html += family; + html += escapeXml(family); html += quote; html += QLatin1Char(';'); } @@ -2341,13 +2360,13 @@ void QTextHtmlExporter::emitFragment(const QTextFragment &fragment) const QString name = format.anchorName(); if (!name.isEmpty()) { html += QLatin1String(""); } const QString href = format.anchorHref(); if (!href.isEmpty()) { html += QLatin1String(""); closeAnchor = true; } diff --git a/tests/auto/qtextdocument/qtextdocument.pro b/tests/auto/qtextdocument/qtextdocument.pro index d3ec45d..1e44a9c 100644 --- a/tests/auto/qtextdocument/qtextdocument.pro +++ b/tests/auto/qtextdocument/qtextdocument.pro @@ -1,4 +1,5 @@ load(qttest_p4) +QT += xml HEADERS += common.h SOURCES += tst_qtextdocument.cpp diff --git a/tests/auto/qtextdocument/tst_qtextdocument.cpp b/tests/auto/qtextdocument/tst_qtextdocument.cpp index f393393..452b683 100644 --- a/tests/auto/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/qtextdocument/tst_qtextdocument.cpp @@ -59,6 +59,7 @@ #include #include #include +#include #include "common.h" @@ -732,7 +733,7 @@ void tst_QTextDocument::toHtml_data() cursor.insertText("Blah", fmt); QTest::newRow("font-family-with-quotes1") << QTextDocumentFragment(&doc) - << QString("

Blah

"); + << QString("

Blah

"); } { @@ -743,7 +744,7 @@ void tst_QTextDocument::toHtml_data() cursor.insertText("Blah", fmt); QTest::newRow("font-family-with-quotes2") << QTextDocumentFragment(&doc) - << QString("

Blah

"); + << QString("

Blah

"); } { @@ -974,6 +975,30 @@ void tst_QTextDocument::toHtml_data() { CREATE_DOC_AND_CURSOR(); + QTextCharFormat fmt; + fmt.setAnchor(true); + fmt.setAnchorHref("http://www.kde.org/?a=1&b=2"); + cursor.insertText("Blah", fmt); + + QTest::newRow("href anchor with &") << QTextDocumentFragment(&doc) + << QString("

Blah

"); + } + + { + CREATE_DOC_AND_CURSOR(); + + QTextCharFormat fmt; + fmt.setAnchor(true); + fmt.setAnchorHref("http://www.kde.org/?a='&b=\""); + cursor.insertText("Blah", fmt); + + QTest::newRow("href anchor with ' and \"") << QTextDocumentFragment(&doc) + << QString("

Blah

"); + } + + { + CREATE_DOC_AND_CURSOR(); + cursor.insertTable(2, 2); QTest::newRow("simpletable") << QTextDocumentFragment(&doc) @@ -1541,6 +1566,9 @@ void tst_QTextDocument::toHtml() QString output = doc->toHtml(); QCOMPARE(output, expectedOutput); + + QDomDocument document; + QVERIFY2(document.setContent(output), "Output was not valid XML"); } void tst_QTextDocument::toHtml2() -- cgit v0.12 From 1f3218e086778a0e324542a00937cd44e8e10c79 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 27 Oct 2009 20:37:27 +0100 Subject: Qt::escape(): also escape the quote (") This amend previous commit by removing the duplicate function. The quote need to be escaped in attributes. Reviewed-by: Thomas Zander --- dist/changes-4.6.0 | 3 +++ src/gui/text/qtextdocument.cpp | 27 +++++--------------------- tests/auto/qtextdocument/tst_qtextdocument.cpp | 26 +++++++++++++++++++++++-- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/dist/changes-4.6.0 b/dist/changes-4.6.0 index 7f723da..ba2b051 100644 --- a/dist/changes-4.6.0 +++ b/dist/changes-4.6.0 @@ -35,6 +35,9 @@ information about a particular change. * Added QVariant::toFloat() and QVariant::toReal() * Added QVariant(float) constructor + - Qt::escape + * now escape the double quote (") + **************************************************************************** * Platform Specific Changes * **************************************************************************** diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 17981e3..6978b6c 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -140,7 +140,7 @@ bool Qt::mightBeRichText(const QString& text) /*! Converts the plain text string \a plain to a HTML string with - HTML metacharacters \c{<}, \c{>}, and \c{&} replaced by HTML + HTML metacharacters \c{<}, \c{>}, \c{&}, and \c{"} replaced by HTML entities. Example: @@ -162,23 +162,6 @@ QString Qt::escape(const QString& plain) rich += QLatin1String(">"); else if (plain.at(i) == QLatin1Char('&')) rich += QLatin1String("&"); - else - rich += plain.at(i); - } - return rich; -} - -static QString escapeXml(const QString &plain) -{ - QString rich; - rich.reserve(int(plain.length() * 1.1)); - for (int i = 0; i < plain.length(); ++i) { - if (plain.at(i) == QLatin1Char('<')) - rich += QLatin1String("<"); - else if (plain.at(i) == QLatin1Char('>')) - rich += QLatin1String(">"); - else if (plain.at(i) == QLatin1Char('&')) - rich += QLatin1String("&"); else if (plain.at(i) == QLatin1Char('"')) rich += QLatin1String("""); else @@ -2057,7 +2040,7 @@ void QTextHtmlExporter::emitAttribute(const char *attribute, const QString &valu html += QLatin1Char(' '); html += QLatin1String(attribute); html += QLatin1String("=\""); - html += escapeXml(value); + html += Qt::escape(value); html += QLatin1Char('"'); } @@ -2326,7 +2309,7 @@ void QTextHtmlExporter::emitFontFamily(const QString &family) quote = QLatin1String("""); html += quote; - html += escapeXml(family); + html += Qt::escape(family); html += quote; html += QLatin1Char(';'); } @@ -2360,13 +2343,13 @@ void QTextHtmlExporter::emitFragment(const QTextFragment &fragment) const QString name = format.anchorName(); if (!name.isEmpty()) { html += QLatin1String(""); } const QString href = format.anchorHref(); if (!href.isEmpty()) { html += QLatin1String(""); closeAnchor = true; } diff --git a/tests/auto/qtextdocument/tst_qtextdocument.cpp b/tests/auto/qtextdocument/tst_qtextdocument.cpp index 452b683..5237438 100644 --- a/tests/auto/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/qtextdocument/tst_qtextdocument.cpp @@ -176,6 +176,8 @@ private slots: void testUndoBlocks(); void receiveCursorPositionChangedAfterContentsChange(); + void escape_data(); + void escape(); private: void backgroundImage_checkExpectedHtml(const QTextDocument &doc); @@ -577,7 +579,7 @@ void tst_QTextDocument::task240325() } void tst_QTextDocument::stylesheetFont_data() -{ +{ QTest::addColumn("stylesheet"); QTest::addColumn("font"); @@ -1566,7 +1568,7 @@ void tst_QTextDocument::toHtml() QString output = doc->toHtml(); QCOMPARE(output, expectedOutput); - + QDomDocument document; QVERIFY2(document.setContent(output), "Output was not valid XML"); } @@ -2680,5 +2682,25 @@ void tst_QTextDocument::receiveCursorPositionChangedAfterContentsChange() QCOMPARE(rec.first, QString("contentsChanged")); } +void tst_QTextDocument::escape_data() +{ + QTest::addColumn("original"); + QTest::addColumn("expected"); + + QTest::newRow("1") << "Hello World\n" << "Hello World\n"; + QTest::newRow("2") << "#include " << "#include <QtCore>"; + QTest::newRow("3") << "

plop -->

" + << "<p class="cool"><a href="http://example.com/?foo=bar&amp;bar=foo">plop --&gt; </a></p>"; + QTest::newRow("4") << QString::fromUtf8("<\320\222\321\201>") << QString::fromUtf8("<\320\222\321\201>"); +} + +void tst_QTextDocument::escape() +{ + QFETCH(QString, original); + QFETCH(QString, expected); + + QCOMPARE(Qt::escape(original), expected); +} + QTEST_MAIN(tst_QTextDocument) #include "tst_qtextdocument.moc" -- cgit v0.12 From a925ba1ab6316a155f2ac61f898c52f07a1340b4 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 28 Oct 2009 09:58:18 +0100 Subject: QSplitter would not show previously collapsed widgets. After deleting or hiding the last non collapsed item in a QSplitter, none would be visible. We now check wether there is any non-hidden, collapsed widget, and set it to non-collapsed. Auto-test included. Task-number: QTBUG-4101 Reviewed-by: Olivier --- src/gui/widgets/qsplitter.cpp | 17 +++++++++++++++-- tests/auto/qsplitter/tst_qsplitter.cpp | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/qsplitter.cpp b/src/gui/widgets/qsplitter.cpp index e3121ae..520a802 100644 --- a/src/gui/widgets/qsplitter.cpp +++ b/src/gui/widgets/qsplitter.cpp @@ -360,13 +360,26 @@ void QSplitterPrivate::recalc(bool update) before a hidden widget must be hidden. */ bool first = true; + bool allInvisible = n != 0; for (int i = 0; i < n ; ++i) { QSplitterLayoutStruct *s = list.at(i); - s->handle->setHidden(first || s->widget->isHidden()); - if (!s->widget->isHidden()) + bool widgetHidden = s->widget->isHidden(); + if (allInvisible && !widgetHidden && !s->collapsed) + allInvisible = false; + s->handle->setHidden(first || widgetHidden); + if (!widgetHidden) first = false; } + if (allInvisible) + for (int i = 0; i < n ; ++i) { + QSplitterLayoutStruct *s = list.at(i); + if (!s->widget->isHidden()) { + s->collapsed = false; + break; + } + } + int fi = 2 * q->frameWidth(); int maxl = fi; int minl = fi; diff --git a/tests/auto/qsplitter/tst_qsplitter.cpp b/tests/auto/qsplitter/tst_qsplitter.cpp index cf16421..b832f3a 100644 --- a/tests/auto/qsplitter/tst_qsplitter.cpp +++ b/tests/auto/qsplitter/tst_qsplitter.cpp @@ -102,6 +102,8 @@ private slots: void task187373_addAbstractScrollAreas(); void task187373_addAbstractScrollAreas_data(); void task169702_sizes(); + void taskQTBUG_4101_ensureOneNonCollapsedWidget_data(); + void taskQTBUG_4101_ensureOneNonCollapsedWidget(); private: void removeThirdWidget(); @@ -1281,6 +1283,8 @@ class MyFriendlySplitter : public QSplitter public: MyFriendlySplitter(QWidget *parent = 0) : QSplitter(parent) {} void setRubberBand(int pos) { QSplitter::setRubberBand(pos); } + + friend class tst_QSplitter; }; void tst_QSplitter::rubberBandNotInSplitter() @@ -1403,5 +1407,35 @@ void tst_QSplitter::task169702_sizes() QCOMPARE(testW->size().height(), testW->minimumSizeHint().height()); } +void tst_QSplitter::taskQTBUG_4101_ensureOneNonCollapsedWidget_data() +{ + QTest::addColumn("testingHide"); + + QTest::newRow("last non collapsed hidden") << true; + QTest::newRow("last non collapsed deleted") << false; +} + +void tst_QSplitter::taskQTBUG_4101_ensureOneNonCollapsedWidget() +{ + QFETCH(bool, testingHide); + + MyFriendlySplitter s; + QLabel *l; + for (int i = 0; i < 5; ++i) { + l = new QLabel(QString("Label ") + QChar('A' + i)); + l->setAlignment(Qt::AlignCenter); + s.addWidget(l); + s.moveSplitter(0, i); // Collapse all the labels except the last one. + } + + s.show(); + if (testingHide) + l->hide(); + else + delete l; + QTest::qWait(100); + QVERIFY(s.sizes().at(0) > 0); +} + QTEST_MAIN(tst_QSplitter) #include "tst_qsplitter.moc" -- cgit v0.12 From 44f8fac4e2fc4a4258b921ac595c2826ca96e99c Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 28 Oct 2009 11:31:33 +0100 Subject: Double-clicking a dock widget titlebar could make it disappear If it wasn't already docked on a mainwindow, its state would become unexpected. Task-number: QTBUG-945 Reviewed-by: gabi --- src/gui/widgets/qdockwidget.cpp | 10 ++++++---- tests/auto/qdockwidget/tst_qdockwidget.cpp | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/gui/widgets/qdockwidget.cpp b/src/gui/widgets/qdockwidget.cpp index 6710275..a8e2a37 100644 --- a/src/gui/widgets/qdockwidget.cpp +++ b/src/gui/widgets/qdockwidget.cpp @@ -685,8 +685,6 @@ void QDockWidgetPrivate::_q_toggleTopLevel() void QDockWidgetPrivate::initDrag(const QPoint &pos, bool nca) { - Q_Q(QDockWidget); - if (state != 0) return; @@ -694,8 +692,6 @@ void QDockWidgetPrivate::initDrag(const QPoint &pos, bool nca) Q_ASSERT(win != 0); QMainWindowLayout *layout = qobject_cast(win->layout()); Q_ASSERT(layout != 0); - if (layout->layoutState.indexOf(q).isEmpty()) //The dock widget has not been added into the main window - return; if (layout->pluggingWidget != 0) // the main window is animating a docking operation return; @@ -1012,6 +1008,12 @@ void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect { Q_Q(QDockWidget); + if (!floating && parent) { + QMainWindowLayout *mwlayout = qobject_cast(q->parentWidget()->layout()); + if (!mwlayout || mwlayout->dockWidgetArea(q) == Qt::NoDockWidgetArea) + return; // this dockwidget can't be redocked + } + bool wasFloating = q->isFloating(); bool hidden = q->isHidden(); diff --git a/tests/auto/qdockwidget/tst_qdockwidget.cpp b/tests/auto/qdockwidget/tst_qdockwidget.cpp index dc67f36..e62ba8c 100644 --- a/tests/auto/qdockwidget/tst_qdockwidget.cpp +++ b/tests/auto/qdockwidget/tst_qdockwidget.cpp @@ -86,6 +86,7 @@ private slots: void visibilityChanged(); void dockLocationChanged(); void setTitleBarWidget(); + void titleBarDoubleClick(); // task specific tests: void task165177_deleteFocusWidget(); void task169808_setFloating(); @@ -694,6 +695,24 @@ void tst_QDockWidget::setTitleBarWidget() QCOMPARE(w2.isVisible(), false); } +void tst_QDockWidget::titleBarDoubleClick() +{ + QMainWindow win; + QDockWidget dock(&win); + win.show(); + dock.setFloating(true); + + QEvent e(QEvent::NonClientAreaMouseButtonDblClick); + QApplication::sendEvent(&dock, &e); + QVERIFY(dock.isFloating()); + QCOMPARE(win.dockWidgetArea(&dock), Qt::NoDockWidgetArea); + + win.addDockWidget(Qt::TopDockWidgetArea, &dock); + dock.setFloating(true); + QApplication::sendEvent(&dock, &e); + QVERIFY(!dock.isFloating()); + QCOMPARE(win.dockWidgetArea(&dock), Qt::TopDockWidgetArea); +} void tst_QDockWidget::task165177_deleteFocusWidget() { -- cgit v0.12 From cc34b794439b59e3e226e2a8dc896fec5e27689d Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 28 Oct 2009 11:25:31 +0100 Subject: Fix initial focus bug in ItemIsFocusScope. The task provides an example that doesn't gain input focus when started. The fix contains two parts: one is to allow items with focus scope ancestors to become focus items even if the scope is inactive. The other is to fix up the focusItem pointers on reparent. Before, the focus scopes' focusItem pointers always pointed to itself, or the next scope. Now these items are treated no differently than other items in that respect. The change has a performance impact when reparenting a large subtree that has a sub focus item onto another item (one more dig). Task-number: QT-2331 Reviewed-by: Alexis Menard --- src/gui/graphicsview/qgraphicsitem.cpp | 39 +++++++++--- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 87 +++++++++++++++++++++++--- 2 files changed, 112 insertions(+), 14 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 0107fba..ef43d5c 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1039,13 +1039,31 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) } // Update focus scope item ptr in new scope. - if (newParent) { + QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem; + if (newFocusScopeItem && newParent) { + if (subFocusItem) { + // Find the subFocusItem's topmost focus scope. + QGraphicsItem *ancestorScope = 0; + QGraphicsItem *p = subFocusItem->d_ptr->parent; + while (p) { + if (p->flags() & QGraphicsItem::ItemIsFocusScope) + ancestorScope = p; + if (p->isPanel()) + break; + p = p->parentItem(); + } + if (ancestorScope) + newFocusScopeItem = ancestorScope; + } + QGraphicsItem *p = newParent; while (p) { if (p->flags() & QGraphicsItem::ItemIsFocusScope) { - p->d_ptr->focusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem; - // ### The below line might not make sense... - if (subFocusItem) + p->d_ptr->focusScopeItem = newFocusScopeItem; + // Ensure the new item is no longer the subFocusItem. The + // only way to set focus on a child of a focus scope is + // by setting focus on the scope itself. + if (subFocusItem && !p->focusItem()) subFocusItem->d_ptr->clearSubFocus(); break; } @@ -2983,8 +3001,11 @@ void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool clim while (p) { if (p->flags() & QGraphicsItem::ItemIsFocusScope) { p->d_ptr->focusScopeItem = q_ptr; - if (!q_ptr->isActive() || !p->focusItem()) + if (!p->focusItem()) { + // If you call setFocus on a child of a focus scope that + // doesn't currently have a focus item, then stop. return; + } break; } p = p->d_ptr->parent; @@ -10751,8 +10772,12 @@ QDebug operator<<(QDebug debug, QGraphicsItem *item) return debug; } - debug << "QGraphicsItem(this =" << ((void*)item) - << ", parent =" << ((void*)item->parentItem()) + if (QGraphicsObject *o = item->toGraphicsObject()) + debug << o->metaObject()->className(); + else + debug << "QGraphicsItem"; + debug << "(this =" << (void*)item + << ", parent =" << (void*)item->parentItem() << ", pos =" << item->pos() << ", z =" << item->zValue() << ", flags = " << item->flags() << ")"; diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index dabf64c..2c948cc 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -391,6 +391,7 @@ private slots: void moveWhileDeleting(); void ensureDirtySceneTransform(); void focusScope(); + void focusScope2(); void stackBefore(); void sceneModality(); void panelModality(); @@ -8465,7 +8466,7 @@ void tst_QGraphicsItem::focusScope() QVERIFY(!scope2->focusScopeItem()); scope3->setParentItem(scope2); QCOMPARE(scope2->focusScopeItem(), (QGraphicsItem *)scope3); - QCOMPARE(scope2->focusItem(), (QGraphicsItem *)scope2); + QCOMPARE(scope2->focusItem(), (QGraphicsItem *)scope3); QGraphicsRectItem *scope1 = new QGraphicsRectItem; scope1->setData(0, "scope1"); @@ -8474,9 +8475,9 @@ void tst_QGraphicsItem::focusScope() QVERIFY(!scope1->focusScopeItem()); scope2->setParentItem(scope1); - QCOMPARE(scope1->focusItem(), (QGraphicsItem *)scope1); - QCOMPARE(scope2->focusItem(), (QGraphicsItem *)0); - QCOMPARE(scope3->focusItem(), (QGraphicsItem *)0); + QCOMPARE(scope1->focusItem(), (QGraphicsItem *)scope3); + QCOMPARE(scope2->focusItem(), (QGraphicsItem *)scope3); + QCOMPARE(scope3->focusItem(), (QGraphicsItem *)scope3); QCOMPARE(scope1->focusScopeItem(), (QGraphicsItem *)scope2); QCOMPARE(scope2->focusScopeItem(), (QGraphicsItem *)scope3); QCOMPARE(scope3->focusScopeItem(), (QGraphicsItem *)0); @@ -8527,11 +8528,13 @@ void tst_QGraphicsItem::focusScope() rect5->setFocus(); rect5->setParentItem(rect4); QCOMPARE(scope3->focusScopeItem(), (QGraphicsItem *)rect5); - QVERIFY(!rect5->hasFocus()); + QVERIFY(rect5->hasFocus()); rect4->setParentItem(0); + QVERIFY(rect5->hasFocus()); QCOMPARE(scope3->focusScopeItem(), (QGraphicsItem *)0); - QVERIFY(scope3->hasFocus()); + QCOMPARE(scope3->focusItem(), (QGraphicsItem *)0); + QVERIFY(!scope3->hasFocus()); QGraphicsRectItem *rectA = new QGraphicsRectItem; QGraphicsRectItem *scopeA = new QGraphicsRectItem(rectA); @@ -8542,7 +8545,7 @@ void tst_QGraphicsItem::focusScope() scopeB->setFocus(); scene.addItem(rectA); - QVERIFY(!rect5->hasFocus()); + QVERIFY(rect5->hasFocus()); QVERIFY(!scopeB->hasFocus()); scopeA->setFocus(); @@ -8550,6 +8553,76 @@ void tst_QGraphicsItem::focusScope() QCOMPARE(scopeB->focusItem(), (QGraphicsItem *)scopeB); } +void tst_QGraphicsItem::focusScope2() +{ + QGraphicsRectItem *child1 = new QGraphicsRectItem; + child1->setFlags(QGraphicsItem::ItemIsFocusable); + child1->setFocus(); + QCOMPARE(child1->focusItem(), (QGraphicsItem *)child1); + + QGraphicsRectItem *child2 = new QGraphicsRectItem; + child2->setFlags(QGraphicsItem::ItemIsFocusable); + + QGraphicsRectItem *rootFocusScope = new QGraphicsRectItem; + rootFocusScope->setFlags(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsFocusScope); + rootFocusScope->setFocus(); + QCOMPARE(rootFocusScope->focusItem(), (QGraphicsItem *)rootFocusScope); + + child1->setParentItem(rootFocusScope); + child2->setParentItem(rootFocusScope); + + QCOMPARE(rootFocusScope->focusScopeItem(), (QGraphicsItem *)child1); + QCOMPARE(rootFocusScope->focusItem(), (QGraphicsItem *)child1); + + QGraphicsRectItem *siblingChild1 = new QGraphicsRectItem; + siblingChild1->setFlags(QGraphicsItem::ItemIsFocusable); + siblingChild1->setFocus(); + + QGraphicsRectItem *siblingChild2 = new QGraphicsRectItem; + siblingChild2->setFlags(QGraphicsItem::ItemIsFocusable); + + QGraphicsRectItem *siblingFocusScope = new QGraphicsRectItem; + siblingFocusScope->setFlags(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsFocusScope); + + siblingChild1->setParentItem(siblingFocusScope); + siblingChild2->setParentItem(siblingFocusScope); + + QCOMPARE(siblingFocusScope->focusScopeItem(), (QGraphicsItem *)siblingChild1); + QCOMPARE(siblingFocusScope->focusItem(), (QGraphicsItem *)0); + + QGraphicsItem *root = new QGraphicsRectItem; + rootFocusScope->setParentItem(root); + siblingFocusScope->setParentItem(root); + + QCOMPARE(root->focusItem(), (QGraphicsItem *)child1); + + QGraphicsScene scene; + scene.addItem(root); + + QEvent activate(QEvent::WindowActivate); + qApp->sendEvent(&scene, &activate); + scene.setFocus(); + + QCOMPARE(scene.focusItem(), (QGraphicsItem *)child1); + + // You cannot set focus on a descendant of a focus scope directly; + // this will only change the scope's focus scope item pointer. If + // you want to give true input focus, you must set it directly on + // the scope itself + siblingChild2->setFocus(); + QVERIFY(!siblingChild2->hasFocus()); + QVERIFY(!siblingChild2->focusItem()); + QCOMPARE(siblingFocusScope->focusScopeItem(), (QGraphicsItem *)siblingChild2); + QCOMPARE(siblingFocusScope->focusItem(), (QGraphicsItem *)0); + + // Set focus on the scope; focus is forwarded to the focus scope item. + siblingFocusScope->setFocus(); + QVERIFY(siblingChild2->hasFocus()); + QVERIFY(siblingChild2->focusItem()); + QCOMPARE(siblingFocusScope->focusScopeItem(), (QGraphicsItem *)siblingChild2); + QCOMPARE(siblingFocusScope->focusItem(), (QGraphicsItem *)siblingChild2); +} + void tst_QGraphicsItem::stackBefore() { QGraphicsRectItem parent; -- cgit v0.12 From 51a644360cdf9ef4d936700f02da6cc380ae1f9d Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 28 Oct 2009 11:43:40 +0100 Subject: Make the QPropertyAnimation pass on windows by waiting slightly longer Timers on windows are not accurate enough to "only" wait for the animation duration + 50. --- tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp index 7dd17e5..92bed7d 100644 --- a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp +++ b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp @@ -495,7 +495,7 @@ void tst_QPropertyAnimation::startWhenAnotherIsRunning() anim->setEndValue(100); QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); anim->start(QVariantAnimation::DeleteWhenStopped); - QTest::qWait(anim->duration() + 50); + QTest::qWait(anim->duration() + 100); QCOMPARE(runningSpy.count(), 2); //started and then stopped QVERIFY(!anim); } @@ -659,7 +659,7 @@ void tst_QPropertyAnimation::playForwardBackward() anim.setStartValue(0); anim.setEndValue(100); anim.start(); - QTest::qWait(anim.duration() + 50); + QTest::qWait(anim.duration() + 100); QCOMPARE(anim.state(), QAbstractAnimation::Stopped); QCOMPARE(anim.currentTime(), anim.duration()); @@ -667,7 +667,7 @@ void tst_QPropertyAnimation::playForwardBackward() anim.setDirection(QVariantAnimation::Backward); anim.start(); QCOMPARE(anim.state(), QAbstractAnimation::Running); - QTest::qWait(anim.duration() + 50); + QTest::qWait(anim.duration() + 100); QCOMPARE(anim.state(), QAbstractAnimation::Stopped); QCOMPARE(anim.currentTime(), 0); @@ -676,7 +676,7 @@ void tst_QPropertyAnimation::playForwardBackward() anim.start(); QCOMPARE(anim.state(), QAbstractAnimation::Running); QCOMPARE(anim.currentTime(), anim.duration()); - QTest::qWait(anim.duration() + 50); + QTest::qWait(anim.duration() + 100); QCOMPARE(anim.state(), QAbstractAnimation::Stopped); QCOMPARE(anim.currentTime(), 0); } -- cgit v0.12 From 8cf53009aa8012c1d911eb3ccac5c5345da712e7 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 28 Oct 2009 11:46:35 +0100 Subject: Changing the time we wait for the end of the animation We now wait for the animation duration + 100 (instead of 50). It makes tests more reliable on windows (and probably embedded) --- tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp index 92bed7d..56c1ced 100644 --- a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp +++ b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp @@ -1093,7 +1093,7 @@ void tst_QPropertyAnimation::valueChanged() QSignalSpy spy(&anim, SIGNAL(valueChanged(QVariant))); anim.start(); - QTest::qWait(anim.duration() + 50); + QTest::qWait(anim.duration() + 100); QCOMPARE(anim.state(), QAbstractAnimation::Stopped); QCOMPARE(anim.currentTime(), anim.duration()); @@ -1144,7 +1144,7 @@ void tst_QPropertyAnimation::twoAnimations() o1.anim.start(); o2.anim.start(); - QTest::qWait(o1.anim.duration() + 50); + QTest::qWait(o1.anim.duration() + 100); QCOMPARE(o1.anim.state(), QAbstractAnimation::Stopped); QCOMPARE(o2.anim.state(), QAbstractAnimation::Stopped); @@ -1194,7 +1194,7 @@ void tst_QPropertyAnimation::deletedInUpdateCurrentTime() MyComposedAnimation composedAnimation(&o, "value", "realValue"); composedAnimation.start(); QCOMPARE(composedAnimation.state(), QAbstractAnimation::Running); - QTest::qWait(composedAnimation.duration() + 50); + QTest::qWait(composedAnimation.duration() + 100); QCOMPARE(composedAnimation.state(), QAbstractAnimation::Stopped); QCOMPARE(o.value(), 1000); -- cgit v0.12 From 0b637c89e785cf4151fbda91eda905032d4baf1e Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 28 Oct 2009 13:17:17 +0100 Subject: Allow to put the central widget in a QMainWindow after it was shown Task-number: QTBUG-1171 --- src/gui/widgets/qdockarealayout.cpp | 14 ++++++++------ src/gui/widgets/qdockarealayout_p.h | 1 + 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index 5a0a9d4..df131ee 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -2259,7 +2259,7 @@ QRect QDockAreaLayoutInfo::tabContentRect() const ** QDockAreaLayout */ -QDockAreaLayout::QDockAreaLayout(QMainWindow *win) +QDockAreaLayout::QDockAreaLayout(QMainWindow *win) : have_central(false) { mainWindow = win; sep = win->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent, 0, win); @@ -2582,7 +2582,9 @@ void QDockAreaLayout::getGrid(QVector *_ver_struct_list, { QSize center_hint(0, 0); QSize center_min(0, 0); - bool have_central = centralWidgetItem != 0 && !centralWidgetItem->isEmpty(); + const bool old_have_central = have_central; + have_central = centralWidgetItem != 0 && !centralWidgetItem->isEmpty(); + const bool fallbackToSizeHints = !old_have_central && have_central; if (have_central) { center_hint = centralWidgetRect.size(); if (!center_hint.isValid()) @@ -2601,28 +2603,28 @@ void QDockAreaLayout::getGrid(QVector *_ver_struct_list, center_rect.setBottom(rect.bottom() - docks[QInternal::BottomDock].rect.height() - sep); QSize left_hint = docks[QInternal::LeftDock].size(); - if (left_hint.isNull()) + if (left_hint.isNull() || fallbackToSizeHints) left_hint = docks[QInternal::LeftDock].sizeHint(); QSize left_min = docks[QInternal::LeftDock].minimumSize(); QSize left_max = docks[QInternal::LeftDock].maximumSize(); left_hint = left_hint.boundedTo(left_max).expandedTo(left_min); QSize right_hint = docks[QInternal::RightDock].size(); - if (right_hint.isNull()) + if (right_hint.isNull() || fallbackToSizeHints) right_hint = docks[QInternal::RightDock].sizeHint(); QSize right_min = docks[QInternal::RightDock].minimumSize(); QSize right_max = docks[QInternal::RightDock].maximumSize(); right_hint = right_hint.boundedTo(right_max).expandedTo(right_min); QSize top_hint = docks[QInternal::TopDock].size(); - if (top_hint.isNull()) + if (top_hint.isNull() || fallbackToSizeHints) top_hint = docks[QInternal::TopDock].sizeHint(); QSize top_min = docks[QInternal::TopDock].minimumSize(); QSize top_max = docks[QInternal::TopDock].maximumSize(); top_hint = top_hint.boundedTo(top_max).expandedTo(top_min); QSize bottom_hint = docks[QInternal::BottomDock].size(); - if (bottom_hint.isNull()) + if (bottom_hint.isNull() || fallbackToSizeHints) bottom_hint = docks[QInternal::BottomDock].sizeHint(); QSize bottom_min = docks[QInternal::BottomDock].minimumSize(); QSize bottom_max = docks[QInternal::BottomDock].maximumSize(); diff --git a/src/gui/widgets/qdockarealayout_p.h b/src/gui/widgets/qdockarealayout_p.h index 99a9dbb..1ed14ce 100644 --- a/src/gui/widgets/qdockarealayout_p.h +++ b/src/gui/widgets/qdockarealayout_p.h @@ -233,6 +233,7 @@ public: QDockAreaLayout(QMainWindow *win); QDockAreaLayoutInfo docks[4]; int sep; // separator extent + bool have_central; mutable QVector separatorWidgets; bool isValid() const; -- cgit v0.12 From 9862d354c0e2135df848dd02417f958b1d7e16f5 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 28 Oct 2009 13:33:16 +0100 Subject: Compile on 64bit Reviewed-by: Jan-Arve --- src/gui/graphicsview/qsimplex_p.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qsimplex_p.h b/src/gui/graphicsview/qsimplex_p.h index 66ea739..084ad7f 100644 --- a/src/gui/graphicsview/qsimplex_p.h +++ b/src/gui/graphicsview/qsimplex_p.h @@ -123,11 +123,11 @@ struct QSimplexConstraint #ifdef QT_DEBUG QString toString() { QString result; - result += QString::fromAscii("-- QSimplexConstraint %1 --").arg(int(this), 0, 16); + result += QString::fromAscii("-- QSimplexConstraint %1 --").arg(quintptr(this), 0, 16); QHash::const_iterator iter; for (iter = variables.constBegin(); iter != variables.constEnd(); ++iter) { - result += QString::fromAscii(" %1 x %2").arg(iter.value()).arg(int(iter.key()), 0, 16); + result += QString::fromAscii(" %1 x %2").arg(iter.value()).arg(quintptr(iter.key()), 0, 16); } switch (ratio) { -- cgit v0.12 From f62e0f8323304b2afbf2e3b918d611ea1d0f6856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Wed, 28 Oct 2009 13:30:28 +0100 Subject: Stabilize tst_QGraphicsView::optimizationFlags_dontSavePainterState2 Make sure the view is painted, otherwise the transforms are identity and comparisons don't make sense. --- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 092f81d..89628d8 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -2486,7 +2486,7 @@ void tst_QGraphicsView::optimizationFlags_dontSavePainterState2() scene.addRect(0, 0, 20, 20)->setTransform(QTransform::fromScale(2, 2)); scene.addRect(50, 50, 20, 20)->setTransform(QTransform::fromTranslate(200, 200)); - QGraphicsView view(&scene); + CustomView view(&scene); if (!savePainter) view.setOptimizationFlag(QGraphicsView::DontSavePainterState); view.rotate(45); @@ -2495,7 +2495,11 @@ void tst_QGraphicsView::optimizationFlags_dontSavePainterState2() #ifdef Q_WS_X11 qt_x11_wait_for_window_manager(&view); #endif - QTest::qWait(150); + + // Make sure the view is repainted; otherwise the tests below will fail. + view.viewport()->repaint(); + QTest::qWait(200); + QVERIFY(view.painted); // Make sure the painter's world transform is preserved after drawItems. const QTransform expectedTransform = view.viewportTransform(); -- cgit v0.12 From 992f5cef19ce9e313dd06279c47d7535c6dbc857 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Wed, 28 Oct 2009 12:39:33 +0100 Subject: Wrong caching of opaque children in QWidget. The opaque children cache was clipped to all the ancestors up to the top-level, which means whenever a widget changes geometry all the children must be invalidated. However, the bug was that we didn't invalidate the children, and that is of course slow so we don't want to do it either. A better solution is to only clip the children cache to the widget itself (widget->rect() instead of widget->clipRect()), and we can perfectly do this because the region we subtract the opaque children from is already inside the clipRect(). Auto-test included. Task-number: QTBUG-4245 (related to) --- src/gui/kernel/qwidget.cpp | 22 ++++++++------------ src/gui/kernel/qwidget_p.h | 1 - tests/auto/qwidget/tst_qwidget.cpp | 42 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 5fa9a92..1951ab2 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1825,18 +1825,6 @@ void QWidgetPrivate::setDirtyOpaqueRegion() pd->setDirtyOpaqueRegion(); } -QRegion QWidgetPrivate::getOpaqueRegion() const -{ - Q_Q(const QWidget); - - QRegion r = isOpaque ? q->rect() : getOpaqueChildren(); - if (extra && extra->hasMask) - r &= extra->mask; - if (r.isEmpty()) - return r; - return r & clipRect(); -} - const QRegion &QWidgetPrivate::getOpaqueChildren() const { if (!dirtyOpaqueChildren) @@ -1851,9 +1839,17 @@ const QRegion &QWidgetPrivate::getOpaqueChildren() const continue; const QPoint offset = child->geometry().topLeft(); - that->opaqueChildren += child->d_func()->getOpaqueRegion().translated(offset); + QWidgetPrivate *childd = child->d_func(); + QRegion r = childd->isOpaque ? child->rect() : childd->getOpaqueChildren(); + if (childd->extra && childd->extra->hasMask) + r &= childd->extra->mask; + if (r.isEmpty()) + continue; + r.translate(offset); + that->opaqueChildren += r; } + that->opaqueChildren &= q_func()->rect(); that->dirtyOpaqueChildren = false; return that->opaqueChildren; diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 159a3f2..5cea641 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -386,7 +386,6 @@ public: bool paintOnScreen() const; void invalidateGraphicsEffectsRecursively(); - QRegion getOpaqueRegion() const; const QRegion &getOpaqueChildren() const; void setDirtyOpaqueRegion(); diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 050d1c5..9c421d1 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -332,6 +332,7 @@ private slots: void doubleRepaint(); #ifndef Q_WS_MAC void resizeInPaintEvent(); + void opaqueChildren(); #endif void setMaskInResizeEvent(); @@ -8272,6 +8273,47 @@ void tst_QWidget::resizeInPaintEvent() // Make sure the resize triggers another update. QTRY_COMPARE(widget.numPaintEvents, 1); } + +void tst_QWidget::opaqueChildren() +{ + QWidget widget; + widget.resize(200, 200); + + QWidget child(&widget); + child.setGeometry(-700, -700, 200, 200); + + QWidget grandChild(&child); + grandChild.resize(200, 200); + + QWidget greatGrandChild(&grandChild); + greatGrandChild.setGeometry(50, 50, 200, 200); + greatGrandChild.setPalette(Qt::red); + greatGrandChild.setAutoFillBackground(true); // Opaque child widget. + + widget.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&widget); +#endif + QTest::qWait(100); + + // Child, grandChild and greatGrandChild are outside the ancestor clip. + QRegion expectedOpaqueRegion(50, 50, 150, 150); + QCOMPARE(qt_widget_private(&grandChild)->getOpaqueChildren(), expectedOpaqueRegion); + + // Now they are all inside the ancestor clip. + child.setGeometry(50, 50, 150, 150); + QCOMPARE(qt_widget_private(&grandChild)->getOpaqueChildren(), expectedOpaqueRegion); + + // Set mask on greatGrandChild. + const QRegion mask(10, 10, 50, 50); + greatGrandChild.setMask(mask); + expectedOpaqueRegion &= mask.translated(50, 50); + QCOMPARE(qt_widget_private(&grandChild)->getOpaqueChildren(), expectedOpaqueRegion); + + // Make greatGrandChild "transparent". + greatGrandChild.setAutoFillBackground(false); + QCOMPARE(qt_widget_private(&grandChild)->getOpaqueChildren(), QRegion()); +} #endif -- cgit v0.12 From e2584b9e910da18e7e472b5681eb7d0d1630647a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20L=C3=A9tourneau?= Date: Mon, 14 Sep 2009 16:54:13 -0400 Subject: Use qLowerBound in qBinaryFind The current implementation of qBinaryFind use 64bit arithmetics even on a 32bit system, which make it slow The docs mention qBinaryFind will find any occurence of the search value not necessarily the first one, but this is not case with current implementation So nothing prevents the use of qLowerBound Reviewed-by: Olivier Goffart Merge-request: 1513 --- src/corelib/tools/qalgorithms.h | 42 ++++++++++------------------------------- 1 file changed, 10 insertions(+), 32 deletions(-) diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h index a68ce27..f70821a 100644 --- a/src/corelib/tools/qalgorithms.h +++ b/src/corelib/tools/qalgorithms.h @@ -295,23 +295,12 @@ template Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value) { // Implementation is duplicated from QAlgorithmsPrivate. - qint64 l = 0; - qint64 r = end - begin - 1; - if (r < 0) - return end; - qint64 i = (l + r + 1) / 2; - - while (r != l) { - if (value < begin[i]) - r = i - 1; - else - l = i; - i = (l + r + 1) / 2; - } - if (begin[i] < value || value < begin[i]) + RandomAccessIterator it = qLowerBound(begin, end, value); + + if (it == end || value < *it) return end; - else - return begin + i; + + return it; } template @@ -520,23 +509,12 @@ Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator template Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan) { - qint64 l = 0; - qint64 r = end - begin - 1; - if (r < 0) - return end; - qint64 i = (l + r + 1) / 2; - - while (r != l) { - if (lessThan(value, begin[i])) - r = i - 1; - else - l = i; - i = (l + r + 1) / 2; - } - if (lessThan(begin[i], value) || lessThan(value, begin[i])) + RandomAccessIterator it = qLowerBoundHelper(begin, end, value, lessThan); + + if (it == end || lessThan(value, *it)) return end; - else - return begin + i; + + return it; } } //namespace QAlgorithmsPrivate -- cgit v0.12 From b41086b8f68f280f1f683d0f107b26d1c6221883 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 28 Oct 2009 14:20:29 +0100 Subject: Extand test of qBinaryFind --- tests/auto/qalgorithms/tst_qalgorithms.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/auto/qalgorithms/tst_qalgorithms.cpp b/tests/auto/qalgorithms/tst_qalgorithms.cpp index 1f1de82..176a451 100644 --- a/tests/auto/qalgorithms/tst_qalgorithms.cpp +++ b/tests/auto/qalgorithms/tst_qalgorithms.cpp @@ -602,9 +602,15 @@ void tst_QAlgorithms::test_qUpperBound() void tst_QAlgorithms::test_qBinaryFind_data() { QTest::addColumn >("data"); - QTest::addColumn("resultValue"); + QTest::addColumn("resultValue"); // -42 means not found QTest::newRow("sorted-duplicate") << (QList() << 1 << 2 << 2 << 3) << 2; + QTest::newRow("sorted-end") << (QList() << -5 << -2 << 0 << 8) << 8; + QTest::newRow("sorted-beginning") << (QList() << -5 << -2 << 0 << 8) << -5; + QTest::newRow("sorted-duplicate-beginning") << (QList() << -5 << -5 << -2 << 0 << 8) << -5; + QTest::newRow("empty") << (QList()) << -42; + QTest::newRow("not found 1 ") << (QList() << 1 << 5 << 8 << 65) << -42; + QTest::newRow("not found 2 ") << (QList() << -456 << -5 << 8 << 65) << -42; } void tst_QAlgorithms::test_qBinaryFind() @@ -612,6 +618,15 @@ void tst_QAlgorithms::test_qBinaryFind() QFETCH(QList, data); QFETCH(int, resultValue); + //-42 means not found + if (resultValue == -42) { + QVERIFY(qBinaryFind(data.constBegin(), data.constEnd(), resultValue) == data.end()); + QVERIFY(qBinaryFind(data, resultValue) == data.end()); + QVERIFY(qBinaryFind(data.begin(), data.end(), resultValue) == data.end()); + QVERIFY(qBinaryFind(data.begin(), data.end(), resultValue, qLess()) == data.end()); + return; + } + QCOMPARE(*qBinaryFind(data.constBegin(), data.constEnd(), resultValue), resultValue); QCOMPARE(*qBinaryFind(data.begin(), data.end(), resultValue), resultValue); QCOMPARE(*qBinaryFind(data, resultValue), resultValue); -- cgit v0.12 From e77732c9b0c8b8313138306d723f5227cfbc124d Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Wed, 28 Oct 2009 11:17:18 -0300 Subject: QGAL: set the orientation bit for complex anchors Sets the orientation bit for complex anchors. This is being done in the constructor, and I did a minor refactor to make the constructor of SequentialAnchor take the list of vertices and anchors that it is simplifying. Before that we set one of those directly in the structure and the other via a setter function. The tests were passing because right now, complex anchors do not use the orientation bit, while some Normal anchors use in the refreshSizeHints() function (to get either the width() or height() of an item). Signed-off-by: Caio Marcelo de Oliveira Filho --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 6 +++--- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 15 +++++---------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index b4666c6..ac81ddc 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -577,18 +577,18 @@ static AnchorData *createSequence(Graph *graph, qDebug("simplifying [%s] to [%s - %s]", qPrintable(strPath), qPrintable(before->toString()), qPrintable(after->toString())); #endif - SequentialAnchorData *sequence = new SequentialAnchorData; AnchorVertex *prev = before; + QVector edges; for (int i = 0; i <= orderedVertices.count(); ++i) { AnchorVertex *next = (i < orderedVertices.count()) ? orderedVertices.at(i) : after; AnchorData *ad = graph->takeEdge(prev, next); Q_ASSERT(ad); - sequence->m_edges.append(ad); + edges.append(ad); prev = next; } - sequence->setVertices(orderedVertices); + SequentialAnchorData *sequence = new SequentialAnchorData(orderedVertices, edges); sequence->from = before; sequence->to = after; diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 8eb65c5..600b06c 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -223,11 +223,13 @@ inline QString AnchorData::toString() const struct SequentialAnchorData : public AnchorData { - SequentialAnchorData() : AnchorData() + SequentialAnchorData(const QVector &vertices, const QVector &edges) + : AnchorData(), m_children(vertices), m_edges(edges) { type = AnchorData::Sequential; + orientation = m_edges.at(0)->orientation; #ifdef QT_DEBUG - name = QLatin1String("SequentialAnchorData"); + name = QString::fromAscii("%1 -- %2").arg(vertices.first()->toString(), vertices.last()->toString()); #endif } @@ -236,14 +238,6 @@ struct SequentialAnchorData : public AnchorData bool refreshSizeHints_helper(qreal effectiveSpacing, bool refreshChildren = true); - void setVertices(const QVector &vertices) - { - m_children = vertices; -#ifdef QT_DEBUG - name = QString::fromAscii("%1 -- %2").arg(vertices.first()->toString(), vertices.last()->toString()); -#endif - } - QVector m_children; // list of vertices in the sequence QVector m_edges; // keep the list of edges too. }; @@ -254,6 +248,7 @@ struct ParallelAnchorData : public AnchorData : AnchorData(), firstEdge(first), secondEdge(second) { type = AnchorData::Parallel; + orientation = first->orientation; // ### Those asserts force that both child anchors have the same direction, // but can't we simplify a pair of anchors in opposite directions? -- cgit v0.12 From 0283ca4cf2ad1c9e642b24f8376aa7179fa54599 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 22 Oct 2009 20:59:07 +0200 Subject: Add some STL compatibility for QContiguousCache and private inheritance The private inheritance ensures that we don't try to access the types under the wrong pointer. If we did that, we'd cause strict aliasing violations. Reviewed-by: Olivier Goffart --- src/corelib/tools/qcontiguouscache.h | 125 ++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 60 deletions(-) diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h index ad78d1f..862df61 100644 --- a/src/corelib/tools/qcontiguouscache.h +++ b/src/corelib/tools/qcontiguouscache.h @@ -62,6 +62,12 @@ struct Q_CORE_EXPORT QContiguousCacheData int start; int offset; uint sharable : 1; + // uint unused : 31; + + // total is 24 bytes (HP-UX aCC: 40 bytes) + // the next entry is already aligned to 8 bytes + // there will be an 8 byte gap here if T requires 16-byte alignment + // (such as long double on 64-bit platforms, __int128, __float128) #ifdef QT_QCONTIGUOUSCACHE_DEBUG void dump() const; @@ -69,33 +75,32 @@ struct Q_CORE_EXPORT QContiguousCacheData }; template -struct QContiguousCacheTypedData +struct QContiguousCacheTypedData: private QContiguousCacheData { - QBasicAtomicInt ref; - int alloc; - int count; - int start; - int offset; - uint sharable : 1; - // uint unused : 31; - - // total is 24 bytes (HP-UX aCC: 40 bytes) - // the next entry is already aligned to 8 bytes - // there will be an 8 byte gap here if T requires 16-byte alignment - // (such as long double on 64-bit platforms, __int128, __float128) - + // private inheritance to avoid aliasing warningss T array[1]; + + static inline void free(QContiguousCacheTypedData *data) { QContiguousCacheData::free(data); } }; template class QContiguousCache { typedef QContiguousCacheTypedData Data; - union { QContiguousCacheData *p; QContiguousCacheTypedData *d; }; + union { QContiguousCacheData *d; QContiguousCacheTypedData *p; }; public: + // STL compatibility + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef ptrdiff_t difference_type; + typedef int size_type; + explicit QContiguousCache(int capacity = 0); QContiguousCache(const QContiguousCache &v) : d(v.d) { d->ref.ref(); if (!d->sharable) detach_helper(); } - inline ~QContiguousCache() { if (!d) return; if (!d->ref.deref()) free(d); } + inline ~QContiguousCache() { if (!d) return; if (!d->ref.deref()) free(p); } inline void detach() { if (d->ref != 1) detach_helper(); } inline bool isDetached() const { return d->ref == 1; } @@ -128,10 +133,10 @@ public: inline int firstIndex() const { return d->offset; } inline int lastIndex() const { return d->offset + d->count - 1; } - inline const T &first() const { Q_ASSERT(!isEmpty()); return d->array[d->start]; } - inline const T &last() const { Q_ASSERT(!isEmpty()); return d->array[(d->start + d->count -1) % d->alloc]; } - inline T &first() { Q_ASSERT(!isEmpty()); detach(); return d->array[d->start]; } - inline T &last() { Q_ASSERT(!isEmpty()); detach(); return d->array[(d->start + d->count -1) % d->alloc]; } + inline const T &first() const { Q_ASSERT(!isEmpty()); return p->array[d->start]; } + inline const T &last() const { Q_ASSERT(!isEmpty()); return p->array[(d->start + d->count -1) % d->alloc]; } + inline T &first() { Q_ASSERT(!isEmpty()); detach(); return p->array[d->start]; } + inline T &last() { Q_ASSERT(!isEmpty()); detach(); return p->array[(d->start + d->count -1) % d->alloc]; } void removeFirst(); T takeFirst(); @@ -161,9 +166,9 @@ private: template void QContiguousCache::detach_helper() { - union { QContiguousCacheData *p; QContiguousCacheTypedData *d; } x; + union { QContiguousCacheData *d; QContiguousCacheTypedData *p; } x; - x.p = malloc(d->alloc); + x.d = malloc(d->alloc); x.d->ref = 1; x.d->count = d->count; x.d->start = d->start; @@ -171,8 +176,8 @@ void QContiguousCache::detach_helper() x.d->alloc = d->alloc; x.d->sharable = true; - T *dest = x.d->array + x.d->start; - T *src = d->array + d->start; + T *dest = x.p->array + x.d->start; + T *src = p->array + d->start; int oldcount = x.d->count; while (oldcount--) { if (QTypeInfo::isComplex) { @@ -181,15 +186,15 @@ void QContiguousCache::detach_helper() *dest = *src; } dest++; - if (dest == x.d->array + x.d->alloc) - dest = x.d->array; + if (dest == x.p->array + x.d->alloc) + dest = x.p->array; src++; - if (src == d->array + d->alloc) - src = d->array; + if (src == p->array + d->alloc) + src = p->array; } if (!d->ref.deref()) - free(d); + free(p); d = x.d; } @@ -205,8 +210,8 @@ void QContiguousCache::setCapacity(int asize) x.d->count = qMin(d->count, asize); x.d->offset = d->offset + d->count - x.d->count; x.d->start = x.d->offset % x.d->alloc; - T *dest = x.d->array + (x.d->start + x.d->count-1) % x.d->alloc; - T *src = d->array + (d->start + d->count-1) % d->alloc; + T *dest = x.p->array + (x.d->start + x.d->count-1) % x.d->alloc; + T *src = p->array + (d->start + d->count-1) % d->alloc; int oldcount = x.d->count; while (oldcount--) { if (QTypeInfo::isComplex) { @@ -214,11 +219,11 @@ void QContiguousCache::setCapacity(int asize) } else { *dest = *src; } - if (dest == x.d->array) - dest = x.d->array + x.d->alloc; + if (dest == x.p->array) + dest = x.p->array + x.d->alloc; dest--; - if (src == d->array) - src = d->array + d->alloc; + if (src == p->array) + src = p->array + d->alloc; src--; } /* free old */ @@ -232,24 +237,24 @@ void QContiguousCache::clear() if (d->ref == 1) { if (QTypeInfo::isComplex) { int oldcount = d->count; - T * i = d->array + d->start; - T * e = d->array + d->alloc; + T * i = p->array + d->start; + T * e = p->array + d->alloc; while (oldcount--) { i->~T(); i++; if (i == e) - i = d->array; + i = p->array; } } d->count = d->start = d->offset = 0; } else { - union { QContiguousCacheData *p; QContiguousCacheTypedData *d; } x; - x.p = malloc(d->alloc); + union { QContiguousCacheData *d; QContiguousCacheTypedData *p; } x; + x.d = malloc(d->alloc); x.d->ref = 1; x.d->alloc = d->alloc; x.d->count = x.d->start = x.d->offset = 0; x.d->sharable = true; - if (!d->ref.deref()) free(d); + if (!d->ref.deref()) free(p); d = x.d; } } @@ -263,7 +268,7 @@ inline QContiguousCacheData *QContiguousCache::malloc(int aalloc) template QContiguousCache::QContiguousCache(int cap) { - p = malloc(cap); + d = malloc(cap); d->ref = 1; d->alloc = cap; d->count = d->start = d->offset = 0; @@ -303,13 +308,13 @@ void QContiguousCache::free(Data *x) { if (QTypeInfo::isComplex) { int oldcount = d->count; - T * i = d->array + d->start; - T * e = d->array + d->alloc; + T * i = p->array + d->start; + T * e = p->array + d->alloc; while (oldcount--) { i->~T(); i++; if (i == e) - i = d->array; + i = p->array; } } qFree(x); @@ -320,10 +325,10 @@ void QContiguousCache::append(const T &value) detach(); if (QTypeInfo::isComplex) { if (d->count == d->alloc) - (d->array + (d->start+d->count) % d->alloc)->~T(); - new (d->array + (d->start+d->count) % d->alloc) T(value); + (p->array + (d->start+d->count) % d->alloc)->~T(); + new (p->array + (d->start+d->count) % d->alloc) T(value); } else { - d->array[(d->start+d->count) % d->alloc] = value; + p->array[(d->start+d->count) % d->alloc] = value; } if (d->count == d->alloc) { @@ -349,12 +354,12 @@ void QContiguousCache::prepend(const T &value) d->count++; else if (d->count == d->alloc) - (d->array + d->start)->~T(); + (p->array + d->start)->~T(); if (QTypeInfo::isComplex) - new (d->array + d->start) T(value); + new (p->array + d->start) T(value); else - d->array[d->start] = value; + p->array[d->start] = value; } template @@ -364,9 +369,9 @@ void QContiguousCache::insert(int pos, const T &value) detach(); if (containsIndex(pos)) { if(QTypeInfo::isComplex) - new (d->array + pos % d->alloc) T(value); + new (p->array + pos % d->alloc) T(value); else - d->array[pos % d->alloc] = value; + p->array[pos % d->alloc] = value; } else if (pos == d->offset-1) prepend(value); else if (pos == d->offset+d->count) @@ -378,18 +383,18 @@ void QContiguousCache::insert(int pos, const T &value) d->start = pos % d->alloc; d->count = 1; if (QTypeInfo::isComplex) - new (d->array + d->start) T(value); + new (p->array + d->start) T(value); else - d->array[d->start] = value; + p->array[d->start] = value; } } template inline const T &QContiguousCache::at(int pos) const -{ Q_ASSERT_X(pos >= d->offset && pos - d->offset < d->count, "QContiguousCache::at", "index out of range"); return d->array[pos % d->alloc]; } +{ Q_ASSERT_X(pos >= d->offset && pos - d->offset < d->count, "QContiguousCache::at", "index out of range"); return p->array[pos % d->alloc]; } template inline const T &QContiguousCache::operator[](int pos) const -{ Q_ASSERT_X(pos >= d->offset && pos - d->offset < d->count, "QContiguousCache::at", "index out of range"); return d->array[pos % d->alloc]; } +{ Q_ASSERT_X(pos >= d->offset && pos - d->offset < d->count, "QContiguousCache::at", "index out of range"); return p->array[pos % d->alloc]; } template inline T &QContiguousCache::operator[](int pos) @@ -397,7 +402,7 @@ inline T &QContiguousCache::operator[](int pos) detach(); if (!containsIndex(pos)) insert(pos, T()); - return d->array[pos % d->alloc]; + return p->array[pos % d->alloc]; } template @@ -407,7 +412,7 @@ inline void QContiguousCache::removeFirst() detach(); d->count--; if (QTypeInfo::isComplex) - (d->array + d->start)->~T(); + (p->array + d->start)->~T(); d->start = (d->start + 1) % d->alloc; d->offset++; } @@ -419,7 +424,7 @@ inline void QContiguousCache::removeLast() detach(); d->count--; if (QTypeInfo::isComplex) - (d->array + (d->start + d->count) % d->alloc)->~T(); + (p->array + (d->start + d->count) % d->alloc)->~T(); } template -- cgit v0.12 From 3f0b969772cf3056ed54349bfe6837d9de2995ea Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 22 Oct 2009 18:57:53 +0200 Subject: Add the aligned versions of qMalloc/qRealloc/qFree --- src/corelib/global/qglobal.h | 3 ++ src/corelib/global/qmalloc.cpp | 100 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 5ee1815..cbb8fda 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -2065,6 +2065,9 @@ Q_DECLARE_TYPEINFO(long double, Q_PRIMITIVE_TYPE); Q_CORE_EXPORT void *qMalloc(size_t size); Q_CORE_EXPORT void qFree(void *ptr); Q_CORE_EXPORT void *qRealloc(void *ptr, size_t size); +Q_CORE_EXPORT void *qMallocAligned(size_t size, size_t alignment); +Q_CORE_EXPORT void *qReallocAligned(void *ptr, size_t size, size_t oldsize, size_t alignment); +Q_CORE_EXPORT void qFreeAligned(void *ptr); Q_CORE_EXPORT void *qMemCopy(void *dest, const void *src, size_t n); Q_CORE_EXPORT void *qMemSet(void *dest, int c, size_t n); diff --git a/src/corelib/global/qmalloc.cpp b/src/corelib/global/qmalloc.cpp index a9f103c..db5e519 100644 --- a/src/corelib/global/qmalloc.cpp +++ b/src/corelib/global/qmalloc.cpp @@ -42,6 +42,7 @@ #include "qplatformdefs.h" #include +#include /* Define the container allocation functions in a separate file, so that our @@ -65,4 +66,103 @@ void *qRealloc(void *ptr, size_t size) return ::realloc(ptr, size); } +#if ((defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600)) +# define HAVE_POSIX_MEMALIGN +#endif + +void *qMallocAligned(size_t size, size_t alignment) +{ +#if defined(Q_OS_WIN) + return _aligned_malloc(size, alignment); +#elif defined(HAVE_POSIX_MEMALIGN) + if (alignment <= sizeof(void*)) + return qMalloc(size); + + // we have posix_memalign + void *ptr = 0; + if (posix_memalign(&ptr, alignment, size) == 0) + return ptr; + return 0; +#else + return qReallocAligned(0, size, 0, alignment); +#endif +} + +void *qReallocAligned(void *oldptr, size_t newsize, size_t oldsize, size_t alignment) +{ +#if defined(Q_OS_WIN) + Q_UNUSED(oldsize); + return _aligned_realloc(oldptr, newsize, alignment); +#elif defined(HAVE_POSIX_MEMALIGN) + if (alignment <= sizeof(void*)) + return qRealloc(oldptr, newsize); + + void *newptr = qMallocAligned(newsize, alignment); + if (!newptr) + return 0; + qMemCopy(newptr, oldptr, qMin(oldsize, newsize)); + qFree(oldptr); + return newptr; +#else + // fake an aligned allocation + Q_UNUSED(oldsize); + + void *actualptr = oldptr ? static_cast(oldptr)[-1] : 0; + if (alignment <= sizeof(void*)) { + // special, fast case + void **newptr = static_cast(qRealloc(actualptr, newsize + sizeof(void*))); + if (!newptr) + return 0; + if (newptr == actualptr) { + // realloc succeeded without reallocating + return oldptr; + } + + *newptr = newptr; + return newptr + 1; + } + + union { void *ptr; void **pptr; quintptr n; } real, faked; + + // qMalloc returns pointers aligned at least at sizeof(size_t) boundaries + // but usually more (8- or 16-byte boundaries). + // So we overallocate by alignment-sizeof(size_t) bytes, so we're guaranteed to find a + // somewhere within the first alignment-sizeof(size_t) that is properly aligned. + + // However, we need to store the actual pointer, so we need to allocate actually size + + // alignment anyway. + + real.ptr = qRealloc(actualptr, newsize + alignment); + if (!real.ptr) + return 0; + + faked.n = real.n + alignment; + faked.n &= ~(alignment - 1); + + // now save the value of the real pointer at faked-sizeof(void*) + // by construction, alignment > sizeof(void*) and is a power of 2, so + // faked-sizeof(void*) is properly aligned for a pointer + faked.pptr[-1] = real.ptr; + + // and save the actual size just before the pointer + //reinterpret_cast(faked.pptr - 1)[-1] = size; + + return faked.ptr; +#endif +} + +void qFreeAligned(void *ptr) +{ +#if defined(Q_OS_WIN) + _aligned_free(ptr); +#elif defined(HAVE_POSIX_MEMALIGN) + ::free(ptr); +#else + if (!ptr) + return; + void **ptr2 = static_cast(ptr); + free(ptr2[-1]); +#endif +} + QT_END_NAMESPACE -- cgit v0.12 From e83bb2fdfc2dc899526c8157fd8b77a68cdde9da Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 22 Oct 2009 21:09:24 +0200 Subject: Fix Qt containers to properly support types with strict alignments. QContiguousCache is a new type, so there are no binary compatibility issues. QHash and QMap didn't have any public qMalloc / qFree, so the entire logic is contained in .cpp code. However, since old code will not inform us of the alignment requirements, we need to add a bit to the structure to indicate whether strict alignment is in use or not. QList doesn't require any changes. For small, movable types, they're all stored in the pointer array itself, so they're aligned. For larger types, we use new(), so types with stricter requirements should define their own operator new(). QLinkedList cannot be fixed. It uses new() on the QLinkedListNode, which contains a T type. Sorry. QVector did have public qMalloc / qFree. I've moved the calls to the inner function and made it keep the old calls if the alignment requirement is below a certain threshold. The idea is that, if it's above, no one was using QVector anyway. Reviewed-by: Bradley T. Hughes --- src/corelib/global/qmalloc.cpp | 3 - src/corelib/tools/qcontiguouscache.cpp | 10 +++ src/corelib/tools/qcontiguouscache.h | 15 +++- src/corelib/tools/qhash.cpp | 27 ++++--- src/corelib/tools/qhash.h | 36 ++++++---- src/corelib/tools/qmap.cpp | 31 ++++++-- src/corelib/tools/qmap.h | 20 ++++-- src/corelib/tools/qvector.cpp | 27 +++++++ src/corelib/tools/qvector.h | 20 +++++- tests/auto/collections/tst_collections.cpp | 109 +++++++++++++++++++++++++++++ 10 files changed, 259 insertions(+), 39 deletions(-) diff --git a/src/corelib/global/qmalloc.cpp b/src/corelib/global/qmalloc.cpp index db5e519..e33f77c 100644 --- a/src/corelib/global/qmalloc.cpp +++ b/src/corelib/global/qmalloc.cpp @@ -144,9 +144,6 @@ void *qReallocAligned(void *oldptr, size_t newsize, size_t oldsize, size_t align // faked-sizeof(void*) is properly aligned for a pointer faked.pptr[-1] = real.ptr; - // and save the actual size just before the pointer - //reinterpret_cast(faked.pptr - 1)[-1] = size; - return faked.ptr; #endif } diff --git a/src/corelib/tools/qcontiguouscache.cpp b/src/corelib/tools/qcontiguouscache.cpp index b0ed701..dd7cab6 100644 --- a/src/corelib/tools/qcontiguouscache.cpp +++ b/src/corelib/tools/qcontiguouscache.cpp @@ -56,6 +56,16 @@ void QContiguousCacheData::dump() const } #endif +QContiguousCacheData *QContiguousCacheData::allocate(int size, int alignment) +{ + return static_cast(qMallocAligned(size, alignment)); +} + +void QContiguousCacheData::free(QContiguousCacheData *data) +{ + qFreeAligned(data); +} + /*! \class QContiguousCache \brief The QContiguousCache class is a template class that provides a contiguous cache. \ingroup tools diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h index 862df61..b9d04b8 100644 --- a/src/corelib/tools/qcontiguouscache.h +++ b/src/corelib/tools/qcontiguouscache.h @@ -69,6 +69,9 @@ struct Q_CORE_EXPORT QContiguousCacheData // there will be an 8 byte gap here if T requires 16-byte alignment // (such as long double on 64-bit platforms, __int128, __float128) + static QContiguousCacheData *allocate(int size, int alignment); + static void free(QContiguousCacheData *data); + #ifdef QT_QCONTIGUOUSCACHE_DEBUG void dump() const; #endif @@ -161,6 +164,14 @@ private: // count the padding at the end return reinterpret_cast(&(reinterpret_cast(this))->array[1]) - reinterpret_cast(this); } + int alignOfTypedData() const + { +#ifdef Q_ALIGNOF + return qMax(sizeof(void*), Q_ALIGNOF(Data)); +#else + return 0; +#endif + } }; template @@ -262,7 +273,7 @@ void QContiguousCache::clear() template inline QContiguousCacheData *QContiguousCache::malloc(int aalloc) { - return static_cast(qMalloc(sizeOfTypedData() + (aalloc - 1) * sizeof(T))); + return QContiguousCacheData::allocate(sizeOfTypedData() + (aalloc - 1) * sizeof(T), alignOfTypedData()); } template @@ -317,7 +328,7 @@ void QContiguousCache::free(Data *x) i = p->array; } } - qFree(x); + x->free(x); } template void QContiguousCache::append(const T &value) diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index f33aba9..23fff1c 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -166,29 +166,38 @@ static int countBits(int hint) const int MinNumBits = 4; QHashData QHashData::shared_null = { - 0, 0, Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, MinNumBits, 0, 0, true + 0, 0, Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, MinNumBits, 0, 0, true, false }; void *QHashData::allocateNode() { - void *ptr = qMalloc(nodeSize); + return allocateNode(0); +} + +void *QHashData::allocateNode(int nodeAlign) +{ + void *ptr = strictAlignment ? qMallocAligned(nodeSize, nodeAlign) : qMalloc(nodeSize); Q_CHECK_PTR(ptr); return ptr; } void QHashData::freeNode(void *node) { - qFree(node); + if (strictAlignment) + qFreeAligned(node); + else + qFree(node); } QHashData *QHashData::detach_helper(void (*node_duplicate)(Node *, void *), int nodeSize) { - return detach_helper( node_duplicate, 0, nodeSize ); + return detach_helper2( node_duplicate, 0, nodeSize, 0 ); } -QHashData *QHashData::detach_helper(void (*node_duplicate)(Node *, void *), - void (*node_delete)(Node *), - int nodeSize) +QHashData *QHashData::detach_helper2(void (*node_duplicate)(Node *, void *), + void (*node_delete)(Node *), + int nodeSize, + int nodeAlign) { union { QHashData *d; @@ -204,6 +213,7 @@ QHashData *QHashData::detach_helper(void (*node_duplicate)(Node *, void *), d->numBits = numBits; d->numBuckets = numBuckets; d->sharable = true; + d->strictAlignment = nodeAlign > 8; if (numBuckets) { QT_TRY { @@ -222,7 +232,7 @@ QHashData *QHashData::detach_helper(void (*node_duplicate)(Node *, void *), Node *oldNode = buckets[i]; while (oldNode != this_e) { QT_TRY { - Node *dup = static_cast(allocateNode()); + Node *dup = static_cast(allocateNode(nodeAlign)); QT_TRY { node_duplicate(oldNode, dup); @@ -262,6 +272,7 @@ void QHashData::free_helper(void (*node_delete)(Node *)) while (cur != this_e) { Node *next = cur->next; node_delete(cur); + freeNode(cur); cur = next; } } diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index b65f1d3..67b394b 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -125,12 +125,14 @@ struct Q_CORE_EXPORT QHashData short numBits; int numBuckets; uint sharable : 1; + uint strictAlignment : 1; - void *allocateNode(); + void *allocateNode(); // ### Qt5 remove me + void *allocateNode(int nodeAlign); void freeNode(void *node); QHashData *detach_helper(void (*node_duplicate)(Node *, void *), int nodeSize); // ### Qt5 remove me - QHashData *detach_helper(void (*node_duplicate)(Node *, void *), void (*node_delete)(Node *), - int nodeSize); + QHashData *detach_helper2(void (*node_duplicate)(Node *, void *), void (*node_delete)(Node *), + int nodeSize, int nodeAlign); void mightGrow(); bool willGrow(); void hasShrunk(); @@ -267,6 +269,14 @@ class QHash return reinterpret_cast(node); } +#ifdef Q_ALIGNOF + static inline int alignOfNode() { return qMax(sizeof(void*), Q_ALIGNOF(Node)); } + static inline int alignOfDummyNode() { return qMax(sizeof(void*), Q_ALIGNOF(DummyNode)); } +#else + static inline int alignOfNode() { return 0; } + static inline int alignOfDummyNode() { return 0; } +#endif + public: inline QHash() : d(&QHashData::shared_null) { d->ref.ref(); } inline QHash(const QHash &other) : d(other.d) { d->ref.ref(); if (!d->sharable) detach(); } @@ -483,7 +493,7 @@ private: Node **findNode(const Key &key, uint *hp = 0) const; Node *createNode(uint h, const Key &key, const T &value, Node **nextNode); void deleteNode(Node *node); - static void deleteNode(QHashData::Node *node); + static void deleteNode2(QHashData::Node *node); static void duplicateNode(QHashData::Node *originalNode, void *newNode); }; @@ -492,12 +502,12 @@ private: template Q_INLINE_TEMPLATE void QHash::deleteNode(Node *node) { - deleteNode(reinterpret_cast(node)); + deleteNode2(reinterpret_cast(node)); + d->freeNode(node); } - template -Q_INLINE_TEMPLATE void QHash::deleteNode(QHashData::Node *node) +Q_INLINE_TEMPLATE void QHash::deleteNode2(QHashData::Node *node) { #ifdef Q_CC_BOR concrete(node)->~QHashNode(); @@ -506,7 +516,6 @@ Q_INLINE_TEMPLATE void QHash::deleteNode(QHashData::Node *node) #else concrete(node)->~Node(); #endif - qFree(node); } template @@ -527,9 +536,9 @@ QHash::createNode(uint ah, const Key &akey, const T &avalue, Node **anex Node *node; if (QTypeInfo::isDummy) { - node = reinterpret_cast(new (d->allocateNode()) DummyNode(akey)); + node = reinterpret_cast(new (d->allocateNode(alignOfDummyNode())) DummyNode(akey)); } else { - node = new (d->allocateNode()) Node(akey, avalue); + node = new (d->allocateNode(alignOfNode())) Node(akey, avalue); } node->h = ah; @@ -554,7 +563,7 @@ Q_INLINE_TEMPLATE QHash &QHash::unite(const QHash &other template Q_OUTOFLINE_TEMPLATE void QHash::freeData(QHashData *x) { - x->free_helper(deleteNode); + x->free_helper(deleteNode2); } template @@ -566,8 +575,9 @@ Q_INLINE_TEMPLATE void QHash::clear() template Q_OUTOFLINE_TEMPLATE void QHash::detach_helper() { - QHashData *x = d->detach_helper(duplicateNode, deleteNode, - QTypeInfo::isDummy ? sizeof(DummyNode) : sizeof(Node)); + QHashData *x = d->detach_helper2(duplicateNode, deleteNode2, + QTypeInfo::isDummy ? sizeof(DummyNode) : sizeof(Node), + QTypeInfo::isDummy ? alignOfDummyNode() : alignOfNode()); if (!d->ref.deref()) freeData(d); d = x; diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp index 1385810..cfb18b4 100644 --- a/src/corelib/tools/qmap.cpp +++ b/src/corelib/tools/qmap.cpp @@ -53,11 +53,16 @@ QT_BEGIN_NAMESPACE QMapData QMapData::shared_null = { &shared_null, { &shared_null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, 0, false, true + Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, 0, false, true, false }; QMapData *QMapData::createData() { + return createData(0); +} + +QMapData *QMapData::createData(int alignment) +{ QMapData *d = new QMapData; Q_CHECK_PTR(d); Node *e = reinterpret_cast(d); @@ -69,6 +74,7 @@ QMapData *QMapData::createData() d->randomBits = 0; d->insertInOrder = false; d->sharable = true; + d->strictAlignment = alignment > 8; return d; } @@ -80,11 +86,19 @@ void QMapData::continueFreeData(int offset) while (cur != e) { prev = cur; cur = cur->forward[0]; - qFree(reinterpret_cast(prev) - offset); + if (strictAlignment) + qFreeAligned(reinterpret_cast(prev) - offset); + else + qFree(reinterpret_cast(prev) - offset); } delete this; } +QMapData::Node *QMapData::node_create(Node *update[], int offset) +{ + return node_create(update, offset, 0); +} + /*! Creates a new node inside the data structure. @@ -94,10 +108,12 @@ void QMapData::continueFreeData(int offset) \a offset is an amount of bytes that needs to reserved just before the QMapData::Node structure. + \a alignment dictates the alignment for the data. + \internal \since 4.6 */ -QMapData::Node *QMapData::node_create(Node *update[], int offset) +QMapData::Node *QMapData::node_create(Node *update[], int offset, int alignment) { int level = 0; uint mask = (1 << Sparseness) - 1; @@ -118,7 +134,9 @@ QMapData::Node *QMapData::node_create(Node *update[], int offset) if (level == 3 && !insertInOrder) randomBits = qrand(); - void *concreteNode = qMalloc(offset + sizeof(Node) + level * sizeof(Node *)); + void *concreteNode = strictAlignment ? + qMallocAligned(offset + sizeof(Node) + level * sizeof(Node *), alignment) : + qMalloc(offset + sizeof(Node) + level * sizeof(Node *)); Q_CHECK_PTR(concreteNode); Node *abstractNode = reinterpret_cast(reinterpret_cast(concreteNode) + offset); @@ -145,7 +163,10 @@ void QMapData::node_delete(Node *update[], int offset, Node *node) update[i]->forward[i] = node->forward[i]; } --size; - qFree(reinterpret_cast(node) - offset); + if (strictAlignment) + qFreeAligned(reinterpret_cast(node) - offset); + else + qFree(reinterpret_cast(node) - offset); } #ifdef QT_QMAP_DEBUG diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 688aca6..20980e7 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -74,10 +74,13 @@ struct Q_CORE_EXPORT QMapData uint randomBits; uint insertInOrder : 1; uint sharable : 1; + uint strictAlignment : 1; - static QMapData *createData(); + static QMapData *createData(); // ### Qt5 remove me + static QMapData *createData(int alignment); void continueFreeData(int offset); - Node *node_create(Node *update[], int offset); + Node *node_create(Node *update[], int offset); // ### Qt5 remove me + Node *node_create(Node *update[], int offset, int alignment); void node_delete(Node *update[], int offset, Node *node); #ifdef QT_QMAP_DEBUG uint adjust_ptr(Node *node); @@ -145,6 +148,13 @@ class QMap }; static inline int payload() { return sizeof(PayloadNode) - sizeof(QMapData::Node *); } + static inline int alignment() { +#ifdef Q_ALIGNOF + return qMax(sizeof(void*), Q_ALIGNOF(Node)); +#else + return 0; +#endif + } static inline Node *concrete(QMapData::Node *node) { return reinterpret_cast(reinterpret_cast(node) - payload()); } @@ -414,7 +424,7 @@ template Q_INLINE_TEMPLATE typename QMapData::Node * QMap::node_create(QMapData *adt, QMapData::Node *aupdate[], const Key &akey, const T &avalue) { - QMapData::Node *abstractNode = adt->node_create(aupdate, payload()); + QMapData::Node *abstractNode = adt->node_create(aupdate, payload(), alignment()); QT_TRY { Node *concreteNode = concrete(abstractNode); new (&concreteNode->key) Key(akey); @@ -715,7 +725,7 @@ template Q_OUTOFLINE_TEMPLATE void QMap::detach_helper() { union { QMapData *d; QMapData::Node *e; } x; - x.d = QMapData::createData(); + x.d = QMapData::createData(alignment()); if (d->size) { x.d->insertInOrder = true; QMapData::Node *update[QMapData::LastLevel + 1]; @@ -905,7 +915,7 @@ Q_OUTOFLINE_TEMPLATE bool QMap::operator==(const QMap &other) co template Q_OUTOFLINE_TEMPLATE QMap::QMap(const std::map &other) { - d = QMapData::createData(); + d = QMapData::createData(alignment()); d->insertInOrder = true; typename std::map::const_iterator it = other.end(); while (it != other.begin()) { diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp index 20f3a80..6522791 100644 --- a/src/corelib/tools/qvector.cpp +++ b/src/corelib/tools/qvector.cpp @@ -45,6 +45,13 @@ QT_BEGIN_NAMESPACE +static inline int alignmentThreshold() +{ + // malloc on 32-bit platforms should return pointers that are 8-byte aligned or more + // while on 64-bit platforms they should be 16-byte aligned or more + return 2 * sizeof(void*); +} + QVectorData QVectorData::shared_null = { Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, true, false }; QVectorData *QVectorData::malloc(int sizeofTypedData, int size, int sizeofT, QVectorData *init) @@ -55,6 +62,26 @@ QVectorData *QVectorData::malloc(int sizeofTypedData, int size, int sizeofT, QVe return p; } +QVectorData *QVectorData::allocate(int size, int alignment) +{ + return static_cast(alignment > alignmentThreshold() ? qMallocAligned(size, alignment) : qMalloc(size)); +} + +QVectorData *QVectorData::reallocate(QVectorData *x, int newsize, int oldsize, int alignment) +{ + if (alignment > alignmentThreshold()) + return static_cast(qReallocAligned(x, newsize, oldsize, alignment)); + return static_cast(qRealloc(x, newsize)); +} + +void QVectorData::free(QVectorData *x, int alignment) +{ + if (alignment > alignmentThreshold()) + qFreeAligned(x); + else + qFree(x); +} + int QVectorData::grow(int sizeofTypedData, int size, int sizeofT, bool excessive) { if (excessive) diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index b77b53a..cf7df12 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -79,6 +79,9 @@ struct Q_CORE_EXPORT QVectorData // some debugges when the QVector is member of a class within an unnamed namespace. // ### Qt 5: can be removed completely. (Ralf) static QVectorData *malloc(int sizeofTypedData, int size, int sizeofT, QVectorData *init); + static QVectorData *allocate(int size, int alignment); + static QVectorData *reallocate(QVectorData *old, int newsize, int oldsize, int alignment); + static void free(QVectorData *data, int alignment); static int grow(int sizeofTypedData, int size, int sizeofT, bool excessive); }; @@ -87,6 +90,8 @@ struct QVectorTypedData : private QVectorData { // private inheritance as we must not access QVectorData member thought QVectorTypedData // as this would break strict aliasing rules. (in the case of shared_null) T array[1]; + + static inline void free(QVectorTypedData *x, int alignment) { QVectorData::free(x, alignment); } }; class QRegion; @@ -302,6 +307,14 @@ private: // count the padding at the end return reinterpret_cast(&(reinterpret_cast(this))->array[1]) - reinterpret_cast(this); } + inline int alignOfTypedData() const + { +#ifdef Q_ALIGNOF + return qMax(sizeof(void*), Q_ALIGNOF(Data)); +#else + return 0; +#endif + } }; template @@ -373,7 +386,7 @@ QVector &QVector::operator=(const QVector &v) template inline QVectorData *QVector::malloc(int aalloc) { - QVectorData *vectordata = static_cast(qMalloc(sizeOfTypedData() + (aalloc - 1) * sizeof(T))); + QVectorData *vectordata = QVectorData::allocate(sizeOfTypedData() + (aalloc - 1) * sizeof(T), alignOfTypedData()); Q_CHECK_PTR(vectordata); return vectordata; } @@ -420,7 +433,7 @@ void QVector::free(Data *x) while (i-- != b) i->~T(); } - qFree(x); + x->free(x, alignOfTypedData()); } template @@ -459,7 +472,8 @@ void QVector::realloc(int asize, int aalloc) } } else { QT_TRY { - QVectorData *mem = static_cast(qRealloc(p, sizeOfTypedData() + (aalloc - 1) * sizeof(T))); + QVectorData *mem = QVectorData::reallocate(d, sizeOfTypedData() + (aalloc - 1) * sizeof(T), + sizeOfTypedData() + (d->alloc - 1) * sizeof(T), alignOfTypedData()); Q_CHECK_PTR(mem); x.d = d = mem; x.d->size = d->size; diff --git a/tests/auto/collections/tst_collections.cpp b/tests/auto/collections/tst_collections.cpp index 670cff0..f97805e 100644 --- a/tests/auto/collections/tst_collections.cpp +++ b/tests/auto/collections/tst_collections.cpp @@ -164,6 +164,7 @@ private slots: void qtimerList(); void containerTypedefs(); void forwardDeclared(); + void alignment(); }; struct LargeStatic { @@ -3481,5 +3482,113 @@ void tst_Collections::forwardDeclared() { typedef QSet C; C *x = 0; /* C::iterator i; */ C::const_iterator j; Q_UNUSED(x) } } +#if defined(Q_ALIGNOF) && defined(Q_DECL_ALIGN) + +class Q_DECL_ALIGN(4) Aligned4 +{ + char i; +public: + Aligned4(int i = 0) : i(i) {} + bool checkAligned() const + { + return (quintptr(this) & 3) == 0; + } + + inline bool operator==(const Aligned4 &other) const { return i == other.i; } + inline bool operator<(const Aligned4 &other) const { return i < other.i; } + friend inline int qHash(const Aligned4 &a) { return qHash(a.i); } +}; + +class Q_DECL_ALIGN(128) Aligned128 +{ + char i; +public: + Aligned128(int i = 0) : i(i) {} + bool checkAligned() const + { + return (quintptr(this) & 127) == 0; + } + + inline bool operator==(const Aligned128 &other) const { return i == other.i; } + inline bool operator<(const Aligned128 &other) const { return i < other.i; } + friend inline int qHash(const Aligned128 &a) { return qHash(a.i); } +}; + +template +void testVectorAlignment() +{ + typedef typename C::value_type Aligned; + C container; + container.append(Aligned()); + QVERIFY(container[0].checkAligned()); + + for (int i = 0; i < 200; ++i) + container.append(Aligned()); + + for (int i = 0; i < container.size(); ++i) + QVERIFY(container.at(i).checkAligned()); +} + +template +void testContiguousCacheAlignment() +{ + typedef typename C::value_type Aligned; + C container(150); + container.append(Aligned()); + QVERIFY(container[container.firstIndex()].checkAligned()); + + for (int i = 0; i < 200; ++i) + container.append(Aligned()); + + for (int i = container.firstIndex(); i < container.lastIndex(); ++i) + QVERIFY(container.at(i).checkAligned()); +} + +template +void testAssociativeContainerAlignment() +{ + typedef typename C::key_type Key; + typedef typename C::mapped_type Value; + C container; + container.insert(Key(), Value()); + + typename C::const_iterator it = container.constBegin(); + QVERIFY(it.key().checkAligned()); + QVERIFY(it.value().checkAligned()); + + // add some more elements + for (int i = 0; i < 200; ++i) + container.insert(Key(i), Value(i)); + + it = container.constBegin(); + for ( ; it != container.constEnd(); ++it) { + QVERIFY(it.key().checkAligned()); + QVERIFY(it.value().checkAligned()); + } +} + +void tst_Collections::alignment() +{ + testVectorAlignment >(); + testVectorAlignment >(); + testContiguousCacheAlignment >(); + testContiguousCacheAlignment >(); + testAssociativeContainerAlignment >(); + testAssociativeContainerAlignment >(); + testAssociativeContainerAlignment >(); + testAssociativeContainerAlignment >(); + testAssociativeContainerAlignment >(); + testAssociativeContainerAlignment >(); + testAssociativeContainerAlignment >(); + testAssociativeContainerAlignment >(); +} + +#else +void tst_Collections::alignment() +{ + QSKIP("Compiler doesn't support necessary extension keywords", SkipAll) +} +#endif + QTEST_APPLESS_MAIN(tst_Collections) #include "tst_collections.moc" -- cgit v0.12 From 5b4b6b2be7b901ef9a29c37431998034730fa3d3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 28 Oct 2009 12:47:35 +0100 Subject: Initialise the reserved bits to 0. This is future compatibility: we must rely on them being 0 in older versions of Qt. Reviewed-by: Bradley T. Hughes --- src/corelib/tools/qcontiguouscache.h | 3 ++- src/corelib/tools/qhash.cpp | 3 ++- src/corelib/tools/qhash.h | 1 + src/corelib/tools/qmap.cpp | 3 ++- src/corelib/tools/qmap.h | 1 + src/corelib/tools/qvector.cpp | 2 +- src/corelib/tools/qvector.h | 2 ++ 7 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h index b9d04b8..ef5b238 100644 --- a/src/corelib/tools/qcontiguouscache.h +++ b/src/corelib/tools/qcontiguouscache.h @@ -62,7 +62,7 @@ struct Q_CORE_EXPORT QContiguousCacheData int start; int offset; uint sharable : 1; - // uint unused : 31; + uint reserved : 31; // total is 24 bytes (HP-UX aCC: 40 bytes) // the next entry is already aligned to 8 bytes @@ -186,6 +186,7 @@ void QContiguousCache::detach_helper() x.d->offset = d->offset; x.d->alloc = d->alloc; x.d->sharable = true; + x.d->reserved = 0; T *dest = x.p->array + x.d->start; T *src = p->array + d->start; diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index 23fff1c..c82c389 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -166,7 +166,7 @@ static int countBits(int hint) const int MinNumBits = 4; QHashData QHashData::shared_null = { - 0, 0, Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, MinNumBits, 0, 0, true, false + 0, 0, Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, MinNumBits, 0, 0, true, false, 0 }; void *QHashData::allocateNode() @@ -214,6 +214,7 @@ QHashData *QHashData::detach_helper2(void (*node_duplicate)(Node *, void *), d->numBuckets = numBuckets; d->sharable = true; d->strictAlignment = nodeAlign > 8; + d->reserved = 0; if (numBuckets) { QT_TRY { diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 67b394b..1918229 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -126,6 +126,7 @@ struct Q_CORE_EXPORT QHashData int numBuckets; uint sharable : 1; uint strictAlignment : 1; + uint reserved : 30; void *allocateNode(); // ### Qt5 remove me void *allocateNode(int nodeAlign); diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp index cfb18b4..3b48c3f 100644 --- a/src/corelib/tools/qmap.cpp +++ b/src/corelib/tools/qmap.cpp @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE QMapData QMapData::shared_null = { &shared_null, { &shared_null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, 0, false, true, false + Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, 0, false, true, false, 0 }; QMapData *QMapData::createData() @@ -75,6 +75,7 @@ QMapData *QMapData::createData(int alignment) d->insertInOrder = false; d->sharable = true; d->strictAlignment = alignment > 8; + d->reserved = 0; return d; } diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 20980e7..65c3d2a 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -75,6 +75,7 @@ struct Q_CORE_EXPORT QMapData uint insertInOrder : 1; uint sharable : 1; uint strictAlignment : 1; + uint reserved : 29; static QMapData *createData(); // ### Qt5 remove me static QMapData *createData(int alignment); diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp index 6522791..8bb1074 100644 --- a/src/corelib/tools/qvector.cpp +++ b/src/corelib/tools/qvector.cpp @@ -52,7 +52,7 @@ static inline int alignmentThreshold() return 2 * sizeof(void*); } -QVectorData QVectorData::shared_null = { Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, true, false }; +QVectorData QVectorData::shared_null = { Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, true, false, 0 }; QVectorData *QVectorData::malloc(int sizeofTypedData, int size, int sizeofT, QVectorData *init) { diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index cf7df12..7402d77 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -72,6 +72,7 @@ struct Q_CORE_EXPORT QVectorData #else uint sharable : 1; uint capacity : 1; + uint reserved : 30; #endif static QVectorData shared_null; @@ -486,6 +487,7 @@ void QVector::realloc(int asize, int aalloc) x.d->alloc = aalloc; x.d->sharable = true; x.d->capacity = d->capacity; + x.d->reserved = 0; } if (QTypeInfo::isComplex) { -- cgit v0.12 From 138e8c17767959c183b3e00e3fb364ab5b6fbdfd Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Wed, 28 Oct 2009 14:14:25 +0100 Subject: QLocalServer: block indefinitely when timeout value is -1 ... as described in the documentation. Furthermore: * use qt_safe_select to timeout correctly * return immediately when timeout value is 0 Reviewed-by: Oswald Buddenhagen --- src/network/socket/qlocalserver_unix.cpp | 22 ++++++---------------- tests/auto/qlocalsocket/tst_qlocalsocket.cpp | 2 +- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/network/socket/qlocalserver_unix.cpp b/src/network/socket/qlocalserver_unix.cpp index 5ffe0c0..e09e547 100644 --- a/src/network/socket/qlocalserver_unix.cpp +++ b/src/network/socket/qlocalserver_unix.cpp @@ -216,24 +216,14 @@ void QLocalServerPrivate::waitForNewConnection(int msec, bool *timedOut) timeout.tv_sec = msec / 1000; timeout.tv_usec = (msec % 1000) * 1000; - // timeout can not be 0 or else select will return an error. - if (0 == msec) - timeout.tv_usec = 1000; - int result = -1; - // on Linux timeout will be updated by select, but _not_ on other systems. - QTime timer; - timer.start(); - while (pendingConnections.isEmpty() && (-1 == msec || timer.elapsed() < msec)) { - result = ::select(listenSocket + 1, &readfds, 0, 0, &timeout); - if (-1 == result && errno != EINTR) { - setError(QLatin1String("QLocalServer::waitForNewConnection")); - closeServer(); - break; - } - if (result > 0) - _q_onNewConnection(); + result = qt_safe_select(listenSocket + 1, &readfds, 0, 0, (msec == -1) ? 0 : &timeout); + if (-1 == result) { + setError(QLatin1String("QLocalServer::waitForNewConnection")); + closeServer(); } + if (result > 0) + _q_onNewConnection(); if (timedOut) *timedOut = (result == 0); } diff --git a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp index be39d00..ab7b0ac 100644 --- a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp @@ -976,7 +976,7 @@ void tst_QLocalSocket::writeOnlySocket() #if defined(Q_OS_SYMBIAN) QTest::qWait(250); #endif - QVERIFY(server.waitForNewConnection()); + QVERIFY(server.waitForNewConnection(200)); QLocalSocket* serverSocket = server.nextPendingConnection(); QVERIFY(serverSocket); -- cgit v0.12 From 6e228d57da9d5dd9b7365d5539f6ed88cafb5d97 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 28 Oct 2009 16:00:49 +0100 Subject: Fixed missing repaints on QTreeView when moving the mouse ..from the decoration to the item itself. QAbstractItemView can't handle that because it doesn't know anything about decoration. Reviewed-by: gabi --- src/gui/itemviews/qtreeview.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index 16b454d..bad9dfe 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -1226,8 +1226,12 @@ bool QTreeView::viewportEvent(QEvent *event) if (oldIndex != newIndex) { QRect oldRect = visualRect(oldIndex); QRect newRect = visualRect(newIndex); - viewport()->update(oldRect.left() - d->indent, oldRect.top(), d->indent, oldRect.height()); - viewport()->update(newRect.left() - d->indent, newRect.top(), d->indent, newRect.height()); + oldRect.rLeft() -= d->indent; + newRect.rLeft() -= d->indent; + //we need to paint the whole items (including the decoration) so that when the user + //moves the mouse over those elements they are updated + viewport()->update(oldRect); + viewport()->update(newRect); } } if (selectionBehavior() == QAbstractItemView::SelectRows) { -- cgit v0.12 From d560894ad085ac8c6266fd1af66139db950f473f Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 28 Oct 2009 15:10:36 +0100 Subject: Fixed bug in QTableView spans. In some cases, the spans internal structure was left in an inconsistent state. Auto-test included. Bonus: spans consistency checking method. Task-number: QTBUG-5062 Reviewed-by: Olivier --- src/gui/itemviews/qtableview.cpp | 43 +++++++++++++++++++++++++++++++- src/gui/itemviews/qtableview_p.h | 6 ++++- tests/auto/qtableview/tst_qtableview.cpp | 38 ++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 2 deletions(-) diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp index c80faa2..02e5fff 100644 --- a/src/gui/itemviews/qtableview.cpp +++ b/src/gui/itemviews/qtableview.cpp @@ -117,7 +117,7 @@ void QSpanCollection::updateSpan(QSpanCollection::Span *span, int old_height) Index::iterator it_y = index.lowerBound(-span->bottom()); Q_ASSERT(it_y != index.end()); //it_y must exist since the span is in the list while (-it_y.key() <= span->top() + old_height -1) { - if(-it_y.key() != span->bottom()) { + if (-it_y.key() > span->bottom()) { (*it_y).remove(-span->left()); if (it_y->isEmpty()) { it_y = index.erase(it_y) - 1; @@ -544,6 +544,47 @@ void QSpanCollection::updateRemovedColumns(int start, int end) qDeleteAll(toBeDeleted); } +#ifdef QT_BUILD_INTERNAL +/*! + \internal + Checks whether the span index structure is self-consistent, and consistent with the spans list. +*/ +bool QSpanCollection::checkConsistency() const +{ + for (Index::const_iterator it_y = index.begin(); it_y != index.end(); ++it_y) { + int y = -it_y.key(); + const SubIndex &subIndex = it_y.value(); + for (SubIndex::const_iterator it = subIndex.begin(); it != subIndex.end(); ++it) { + int x = -it.key(); + Span *span = it.value(); + if (!spans.contains(span) || span->left() != x + || y < span->top() || y > span->bottom()) + return false; + } + } + + foreach (const Span *span, spans) { + if (span->width() < 1 || span->height() < 1 + || (span->width() == 1 && span->height() == 1)) + return false; + for (int y = span->top(); y <= span->bottom(); ++y) { + Index::const_iterator it_y = index.find(-y); + if (it_y == index.end()) { + if (y == span->top()) + return false; + else + continue; + } + const SubIndex &subIndex = it_y.value(); + SubIndex::const_iterator it = subIndex.find(-span->left()); + if (it == subIndex.end() || it.value() != span) + return false; + } + } + return true; +} +#endif + class QTableCornerButton : public QAbstractButton { Q_OBJECT diff --git a/src/gui/itemviews/qtableview_p.h b/src/gui/itemviews/qtableview_p.h index 9fa14c2..6b19ded 100644 --- a/src/gui/itemviews/qtableview_p.h +++ b/src/gui/itemviews/qtableview_p.h @@ -74,7 +74,7 @@ QT_BEGIN_NAMESPACE * The key of the first map is the row where the subspan starts, the value of the first map is * a list (map) of all subspans that starts at the same row. It is indexed with its row */ -class QSpanCollection +class Q_AUTOTEST_EXPORT QSpanCollection { public: struct Span @@ -112,6 +112,10 @@ public: void updateRemovedRows(int start, int end); void updateRemovedColumns(int start, int end); +#ifdef QT_BUILD_INTERNAL + bool checkConsistency() const; +#endif + typedef QLinkedList SpanList; SpanList spans; //lists of all spans private: diff --git a/tests/auto/qtableview/tst_qtableview.cpp b/tests/auto/qtableview/tst_qtableview.cpp index 8f8781d..fe2794f 100644 --- a/tests/auto/qtableview/tst_qtableview.cpp +++ b/tests/auto/qtableview/tst_qtableview.cpp @@ -41,6 +41,7 @@ #include +#include #include #include "../../shared/util.h" #include "private/qapplication_p.h" @@ -58,6 +59,13 @@ } \ } while(0) +#ifdef QT_BUILD_INTERNAL +#define VERIFY_SPANS_CONSISTENCY(TEST_VIEW_) \ + QVERIFY(static_cast(QObjectPrivate::get(TEST_VIEW_))->spans.checkConsistency()) +#else +#define VERIFY_SPANS_CONSISTENCY(TEST_VIEW_) (void)false +#endif + typedef QList IntList; Q_DECLARE_METATYPE(IntList) @@ -188,6 +196,7 @@ private slots: void task248688_autoScrollNavigation(); void task259308_scrollVerticalHeaderSwappedSections(); void task191545_dragSelectRows(); + void taskQTBUG_5062_spansInconsistency(); void mouseWheel_data(); void mouseWheel(); @@ -2899,6 +2908,8 @@ void tst_QTableView::span() view.clearSpans(); QCOMPARE(view.rowSpan(row, column), 1); QCOMPARE(view.columnSpan(row, column), 1); + + VERIFY_SPANS_CONSISTENCY(&view); } typedef QVector SpanList; @@ -3034,6 +3045,8 @@ void tst_QTableView::spans() QCOMPARE(view.columnSpan(pos.x(), pos.y()), expectedColumnSpan); QCOMPARE(view.rowSpan(pos.x(), pos.y()), expectedRowSpan); + + VERIFY_SPANS_CONSISTENCY(&view); } void tst_QTableView::spansAfterRowInsertion() @@ -3068,6 +3081,8 @@ void tst_QTableView::spansAfterRowInsertion() view.model()->insertRows(12, 2); QCOMPARE(view.rowSpan(7, 3), 5); QCOMPARE(view.columnSpan(7, 3), 3); + + VERIFY_SPANS_CONSISTENCY(&view); } void tst_QTableView::spansAfterColumnInsertion() @@ -3102,6 +3117,8 @@ void tst_QTableView::spansAfterColumnInsertion() view.model()->insertColumns(12, 2); QCOMPARE(view.rowSpan(3, 7), 3); QCOMPARE(view.columnSpan(3, 7), 5); + + VERIFY_SPANS_CONSISTENCY(&view); } void tst_QTableView::spansAfterRowRemoval() @@ -3139,6 +3156,8 @@ void tst_QTableView::spansAfterRowRemoval() QCOMPARE(view.columnSpan(span.top(), span.left()), span.width()); QCOMPARE(view.rowSpan(span.top(), span.left()), span.height()); } + + VERIFY_SPANS_CONSISTENCY(&view); } void tst_QTableView::spansAfterColumnRemoval() @@ -3177,6 +3196,8 @@ void tst_QTableView::spansAfterColumnRemoval() QCOMPARE(view.columnSpan(span.left(), span.top()), span.height()); QCOMPARE(view.rowSpan(span.left(), span.top()), span.width()); } + + VERIFY_SPANS_CONSISTENCY(&view); } class Model : public QAbstractTableModel { @@ -3845,5 +3866,22 @@ void tst_QTableView::task234926_setHeaderSorting() QCOMPARE(model.stringList() , sortedDataD); } +void tst_QTableView::taskQTBUG_5062_spansInconsistency() +{ + const int nRows = 5; + const int nColumns = 5; + + QtTestTableModel model(nRows, nColumns); + QtTestTableView view; + view.setModel(&model); + + for (int i = 0; i < nRows; ++i) + view.setSpan(i, 0, 1, nColumns); + view.setSpan(2, 0, 1, 1); + view.setSpan(3, 0, 1, 1); + + VERIFY_SPANS_CONSISTENCY(&view); +} + QTEST_MAIN(tst_QTableView) #include "tst_qtableview.moc" -- cgit v0.12 From 51f1d68addd23516d7e6e252e476feac0a95d0c0 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 28 Oct 2009 15:55:47 +0100 Subject: Fix warning in qvariant.h header + make sure QVariant in QVariant works as expected Also add more test Reviewed-by: Thierry --- src/corelib/kernel/qvariant.h | 39 ++---- tests/auto/qvariant/tst_qvariant.cpp | 245 +++++++++++++++++++++++++++++++++++ 2 files changed, 257 insertions(+), 27 deletions(-) diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index 4cce529..a1ab4e9 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -456,9 +456,9 @@ template inline void qVariantSetValue(QVariant &v, const T &t) { //if possible we reuse the current QVariant private - const int type = qMetaTypeId(reinterpret_cast(0)); + const uint type = qMetaTypeId(reinterpret_cast(0)); QVariant::Private &d = v.data_ptr(); - if (v.isDetached() && (type <= int(QVariant::Char) || type == d.type)) { + if (v.isDetached() && (type <= uint(QVariant::Char) || type == d.type)) { d.type = type; d.is_null = false; T *old = reinterpret_cast(d.is_shared ? d.data.shared->ptr : &d.data.ptr); @@ -470,6 +470,13 @@ inline void qVariantSetValue(QVariant &v, const T &t) } } +template <> +inline void qVariantSetValue(QVariant &v, const QVariant &t) +{ + v = t; +} + + inline QVariant::QVariant() {} inline bool QVariant::isValid() const { return d.type != Invalid; } @@ -559,9 +566,7 @@ inline bool operator!=(const QVariant &v1, const QVariantComparisonHelper &v2) #endif #ifndef QT_MOC -#if !defined qdoc && defined Q_CC_MSVC && _MSC_VER < 1300 - -template T qvariant_cast(const QVariant &v, T * = 0) +template inline T qvariant_cast(const QVariant &v) { const int vid = qMetaTypeId(static_cast(0)); if (vid == v.userType()) @@ -574,28 +579,9 @@ template T qvariant_cast(const QVariant &v, T * = 0) return T(); } -template -inline T qVariantValue(const QVariant &variant, T *t = 0) -{ return qvariant_cast(variant, t); } - -template -inline bool qVariantCanConvert(const QVariant &variant, T *t = 0) +template<> inline QVariant qvariant_cast(const QVariant &v) { - return variant.canConvert(static_cast(qMetaTypeId(t))); -} -#else - -template T qvariant_cast(const QVariant &v) -{ - const int vid = qMetaTypeId(static_cast(0)); - if (vid == v.userType()) - return *reinterpret_cast(v.constData()); - if (vid < int(QMetaType::User)) { - T t; - if (qvariant_cast_helper(v, QVariant::Type(vid), &t)) - return t; - } - return T(); + return v; } template @@ -609,7 +595,6 @@ inline bool qVariantCanConvert(const QVariant &variant) qMetaTypeId(static_cast(0)))); } #endif -#endif Q_DECLARE_SHARED(QVariant) Q_DECLARE_TYPEINFO(QVariant, Q_MOVABLE_TYPE); diff --git a/tests/auto/qvariant/tst_qvariant.cpp b/tests/auto/qvariant/tst_qvariant.cpp index de4d7b4..61e9a4f 100644 --- a/tests/auto/qvariant/tst_qvariant.cpp +++ b/tests/auto/qvariant/tst_qvariant.cpp @@ -270,6 +270,8 @@ private slots: void task256984_setValue(); void numericalConvert(); + void moreCustomTypes(); + void variantInVariant(); }; Q_DECLARE_METATYPE(QDate) @@ -3135,7 +3137,250 @@ void tst_QVariant::numericalConvert() } +template void playWithVariant(const T &orig, bool isNull, const QString &toString, double toDouble, bool toBool) +{ + QVariant v = QVariant::fromValue(orig); + QVERIFY(v.isValid()); + QCOMPARE(v.isNull(), isNull); + QCOMPARE(v.toString(), toString); + QCOMPARE(v.toDouble(), toDouble); + QCOMPARE(v.toBool(), toBool); + QCOMPARE(qvariant_cast(v), orig); + + { + QVariant v2 = v; + QCOMPARE(v2, v); + QVERIFY(v2.isValid()); + QCOMPARE(v2.isNull(), isNull); + QCOMPARE(v2.toString(), toString); + QCOMPARE(v2.toDouble(), toDouble); + QCOMPARE(v2.toBool(), toBool); + QCOMPARE(qvariant_cast(v2), orig); + + QVariant v3; + v = QVariant(); + QCOMPARE(v3, v); + v = v2; + QCOMPARE(v, v2); + QCOMPARE(qvariant_cast(v2), qvariant_cast(v)); + QCOMPARE(v2.toString(), toString); + v3 = qVariantFromValue(orig); + + QVERIFY(v3.isValid()); + QCOMPARE(v3.isNull(), isNull); + QCOMPARE(v3.toString(), toString); + QCOMPARE(v3.toDouble(), toDouble); + QCOMPARE(v3.toBool(), toBool); + QCOMPARE(qvariant_cast(v3), qvariant_cast(v)); + } + + QVERIFY(v.isValid()); + QCOMPARE(v.isNull(), isNull); + QCOMPARE(v.toString(), toString); + QCOMPARE(v.toDouble(), toDouble); + QCOMPARE(v.toBool(), toBool); + QCOMPARE(qvariant_cast(v), orig); + + if (qMetaTypeId() != qMetaTypeId()) { + QCOMPARE(v.userType(), qMetaTypeId()); + QCOMPARE(QVariant::typeToName(QVariant::Type(v.userType())), QMetaType::typeName(qMetaTypeId())); + } +} + + +struct MyPrimitive +{ + char x, y; + bool operator==(const MyPrimitive &o) const + { + return x == o.x && y == o.y; + } +}; +Q_DECLARE_TYPEINFO(MyPrimitive, Q_PRIMITIVE_TYPE); + +struct MyData +{ + void *ptr; + MyData() : ptr(this) {} + ~MyData() { Q_ASSERT(ptr == this); } + MyData(const MyData& o) : ptr(this) { Q_ASSERT(o.ptr == &o); } + MyData &operator=(const MyData &o) + { + Q_ASSERT(ptr == this); + Q_ASSERT(o.ptr == &o); + return *this; + } + bool operator==(const MyData &o) const + { + Q_ASSERT(ptr == this); + Q_ASSERT(o.ptr == &o); + return true; + } +}; + +struct MyMovable +{ + static int count; + int v; + MyMovable() { v = count++; } + ~MyMovable() { count--; } + MyMovable(const MyMovable &o) : v(o.v) { count++; } + + bool operator==(const MyMovable &o) const + { + return v == o.v; + } +}; + +int MyMovable::count = 0; + + +Q_DECLARE_TYPEINFO(MyMovable, Q_MOVABLE_TYPE); + +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(MyPrimitive) +Q_DECLARE_METATYPE(MyData) +Q_DECLARE_METATYPE(MyMovable) +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(MyPrimitive *) +Q_DECLARE_METATYPE(MyData *) +Q_DECLARE_METATYPE(MyMovable *) + +void tst_QVariant::moreCustomTypes() +{ + { + QList listSize; + playWithVariant(listSize, false, QString(), 0, false); + listSize << QSize(4,5) << QSize(89,23) << QSize(5,6); + playWithVariant(listSize, false, QString(), 0, false); + } + + { + QString str; + playWithVariant(str, true, QString(), 0, false); + str = QString::fromLatin1("123456789.123"); + playWithVariant(str, false, str, 123456789.123, true); + } + + { + QSize size; + playWithVariant(size, false, QString(), 0, false); + playWithVariant(QSize(45,78), false, QString(), 0, false); + } + + { + MyData d; + playWithVariant(d, false, QString(), 0, false); + playWithVariant(&d, false, QString(), 0, false); + QList l; + playWithVariant(l, false, QString(), 0, false); + l << MyData() << MyData(); + playWithVariant(l, false, QString(), 0, false); + } + + { + MyPrimitive d = { 4, 5 }; + playWithVariant(d, false, QString(), 0, false); + playWithVariant(&d, false, QString(), 0, false); + QList l; + playWithVariant(l, false, QString(), 0, false); + l << d; + playWithVariant(l, false, QString(), 0, false); + } + + { + MyMovable d; + playWithVariant(d, false, QString(), 0, false); + playWithVariant(&d, false, QString(), 0, false); + QList l; + playWithVariant(l, false, QString(), 0, false); + l << MyMovable() << d; + playWithVariant(l, false, QString(), 0, false); + } + QCOMPARE(MyMovable::count, 0); + + { + playWithVariant(12.12, false, "12.12", 12.12, true); + playWithVariant(12.12f, false, "12.12", 12.12f, true); + playWithVariant('a', false, "a", 'a', true); + playWithVariant((unsigned char)('a'), false, "a", 'a', true); + playWithVariant( quint8(12), false, "\xc", 12, true); + playWithVariant( qint8(13), false, "\xd", 13, true); + playWithVariant(quint16(14), false, "14", 14, true); + playWithVariant( qint16(15), false, "15", 15, true); + playWithVariant(quint32(16), false, "16", 16, true); + playWithVariant( qint32(17), false, "17", 17, true); + playWithVariant(quint64(18), false, "18", 18, true); + playWithVariant( qint64(19), false, "19", 19, true); + playWithVariant( qint8(-12), false, "\xf4", -12, true); + playWithVariant( qint16(-13), false, "-13", -13, true); + playWithVariant( qint32(-14), false, "-14", -14, true); + playWithVariant( qint64(-15), false, "-15", -15, true); + playWithVariant(quint64(0), false, "0", 0, false); + playWithVariant( true, false, "true", 1, true); + playWithVariant( false, false, "false", 0, false); + + playWithVariant(QString("hello\n"), false, "hello\n", 0, true); + } + + { + int i = 5; + playWithVariant((void *)(&i), false, QString(), 0, false); + playWithVariant((void *)(0), false, QString(), 0, false); + } + + { + QVariant v1 = QVariant::fromValue(5); + QVariant v2 = QVariant::fromValue(5.0); + QVariant v3 = QVariant::fromValue(quint16(5)); + QVariant v4 = 5; + QVariant v5 = QVariant::fromValue(MyPrimitive()); + QVariant v6 = QVariant::fromValue(MyMovable()); + QVariant v7 = QVariant::fromValue(MyData()); + playWithVariant(v1, false, "5", 5, true); + playWithVariant(v2, false, "5", 5, true); + playWithVariant(v3, false, "5", 5, true); + playWithVariant(v4, false, "5", 5, true); + + playWithVariant(v5, false, QString(), 0, false); + } +} + + +void tst_QVariant::variantInVariant() +{ + QVariant var1 = 5; + QCOMPARE(var1.type(), QVariant::Int); + QVariant var2 = var1; + QCOMPARE(var2, var1); + QCOMPARE(var2.type(), QVariant::Int); + QVariant var3 = QVariant::fromValue(var1); + QCOMPARE(var3, var1); + QCOMPARE(var3.type(), QVariant::Int); + QVariant var4 = qvariant_cast(var1); + QCOMPARE(var4, var1); + QCOMPARE(var4.type(), QVariant::Int); + QVariant var5; + var5 = var1; + QCOMPARE(var5, var1); + QCOMPARE(var5.type(), QVariant::Int); + QVariant var6; + var6.setValue(var1); + QCOMPARE(var6, var1); + QCOMPARE(var6.type(), QVariant::Int); + + QCOMPARE(QVariant::fromValue(var1), QVariant::fromValue(var2)); + QCOMPARE(qvariant_cast(var3), QVariant::fromValue(var4)); + QCOMPARE(qvariant_cast(var5), qvariant_cast(var6)); + + QString str("hello"); + QVariant var8 = qvariant_cast(QVariant::fromValue(QVariant::fromValue(str))); + QCOMPARE((int)var8.type(), (int)QVariant::String); + QCOMPARE(qvariant_cast(QVariant(qvariant_cast(var8))), str); +} QTEST_MAIN(tst_QVariant) #include "tst_qvariant.moc" -- cgit v0.12 From f32abd2b9febdeadeb5536d0318f77be4180f142 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 29 Oct 2009 17:01:36 +1000 Subject: Compile with -no-qt3support Reviewed-by: andreas --- src/gui/itemviews/qtreeview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index bad9dfe..be64c46 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -1226,8 +1226,8 @@ bool QTreeView::viewportEvent(QEvent *event) if (oldIndex != newIndex) { QRect oldRect = visualRect(oldIndex); QRect newRect = visualRect(newIndex); - oldRect.rLeft() -= d->indent; - newRect.rLeft() -= d->indent; + oldRect.setLeft(oldRect.left() - d->indent); + newRect.setLeft(newRect.left() - d->indent); //we need to paint the whole items (including the decoration) so that when the user //moves the mouse over those elements they are updated viewport()->update(oldRect); -- cgit v0.12 From 25502811723a026a38c0a861a6a304d24b8e6a95 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 29 Oct 2009 09:37:26 +0100 Subject: Stabilize tests --- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 2 +- tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp | 4 +++- tests/auto/qtreeview/tst_qtreeview.cpp | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 2c948cc..28f249f 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -7463,7 +7463,7 @@ void tst_QGraphicsItem::moveLineItem() // Make sure the calculated region is correct. item->update(); QTest::qWait(10); - QCOMPARE(view.paintedRegion, expectedRegion); + QTRY_COMPARE(view.paintedRegion, expectedRegion); view.reset(); // Old position: (50, 50) diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index 9dfd486..7d98748 100644 --- a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -45,6 +45,8 @@ #include #include #include +#include "../../shared/util.h" + //TESTED_CLASS= //TESTED_FILES= @@ -356,7 +358,7 @@ void tst_QGraphicsSceneIndex::clear() MyItem *item = new MyItem; scene.addItem(item); qApp->processEvents(); - QCOMPARE(item->numPaints, 1); + QTRY_COMPARE(item->numPaints, 1); } QTEST_MAIN(tst_QGraphicsSceneIndex) diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp index 1429771..75c02e9 100644 --- a/tests/auto/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/qtreeview/tst_qtreeview.cpp @@ -3552,6 +3552,7 @@ void tst_QTreeView::doubleClickedWithSpans() view.setModel(&model); view.setFirstColumnSpanned(0, QModelIndex(), true); view.show(); + QTest::qWaitForWindowShown(&view); QPoint p(10, 10); QCOMPARE(view.indexAt(p), model.index(0, 0)); -- cgit v0.12 From d5a228fbd44f7dd92a10981a5c835db66e3ea6f8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 29 Oct 2009 09:59:40 +0100 Subject: Fix compilation in QContiguousCache. Reviewed-by: TrustMe --- src/corelib/tools/qcontiguouscache.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h index ef5b238..3785938 100644 --- a/src/corelib/tools/qcontiguouscache.h +++ b/src/corelib/tools/qcontiguouscache.h @@ -216,8 +216,8 @@ void QContiguousCache::setCapacity(int asize) if (asize == d->alloc) return; detach(); - union { QContiguousCacheData *p; QContiguousCacheTypedData *d; } x; - x.p = malloc(asize); + union { QContiguousCacheData *d; QContiguousCacheTypedData *p; } x; + x.d = malloc(asize); x.d->alloc = asize; x.d->count = qMin(d->count, asize); x.d->offset = d->offset + d->count - x.d->count; @@ -239,7 +239,7 @@ void QContiguousCache::setCapacity(int asize) src--; } /* free old */ - free(d); + free(p); d = x.d; } -- cgit v0.12 From 8307d3511b35adbb945948eda2cf54bbd3c0a20e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 29 Oct 2009 10:28:28 +0100 Subject: Update confusing qWarning message. Reviewed-by: Olivier Goffart --- src/corelib/kernel/qmetaobject.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index f98c449..71afc5b 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -574,8 +574,8 @@ int QMetaObjectPrivate::indexOfSignalRelative(const QMetaObject **baseObject, co if (i >= 0 && m && m->d.superdata) { int conflict = m->d.superdata->indexOfMethod(signal); if (conflict >= 0) - qWarning("QMetaObject::indexOfSignal:%s: Conflict with %s::%s", - m->d.stringdata, m->d.superdata->d.stringdata, signal); + qWarning("QMetaObject::indexOfSignal: signal %s from %s redefined in %s", + signal, m->d.superdata->d.stringdata, m->d.stringdata); } #endif return i; -- cgit v0.12 From ffe49ed60c9ee778b9999ee4145b44851b053f9f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 29 Oct 2009 10:31:48 +0100 Subject: Fix compilation on Mac: there's no malloc.h there Reviewed-by: Trust Me --- src/corelib/global/qmalloc.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/corelib/global/qmalloc.cpp b/src/corelib/global/qmalloc.cpp index e33f77c..3584c50 100644 --- a/src/corelib/global/qmalloc.cpp +++ b/src/corelib/global/qmalloc.cpp @@ -42,7 +42,10 @@ #include "qplatformdefs.h" #include -#include + +#ifdef Q_OS_WIN +# include +#endif /* Define the container allocation functions in a separate file, so that our @@ -66,10 +69,6 @@ void *qRealloc(void *ptr, size_t size) return ::realloc(ptr, size); } -#if ((defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600)) -# define HAVE_POSIX_MEMALIGN -#endif - void *qMallocAligned(size_t size, size_t alignment) { #if defined(Q_OS_WIN) -- cgit v0.12 From 00908877d47c72e178cb0cee643229e3f3e1c64e Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 29 Oct 2009 10:39:16 +0100 Subject: Fix autotest for QMainWindow --- src/gui/widgets/qdockarealayout.cpp | 11 +++++++---- src/gui/widgets/qdockarealayout_p.h | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index df131ee..6895e09 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -2259,7 +2259,7 @@ QRect QDockAreaLayoutInfo::tabContentRect() const ** QDockAreaLayout */ -QDockAreaLayout::QDockAreaLayout(QMainWindow *win) : have_central(false) +QDockAreaLayout::QDockAreaLayout(QMainWindow *win) : fallbackToSizeHints(true) { mainWindow = win; sep = win->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent, 0, win); @@ -2346,6 +2346,9 @@ bool QDockAreaLayout::restoreState(QDataStream &stream, const QList(cornerData[i]); } + + if (!testing) + fallbackToSizeHints = false; } return ok; @@ -2582,9 +2585,7 @@ void QDockAreaLayout::getGrid(QVector *_ver_struct_list, { QSize center_hint(0, 0); QSize center_min(0, 0); - const bool old_have_central = have_central; - have_central = centralWidgetItem != 0 && !centralWidgetItem->isEmpty(); - const bool fallbackToSizeHints = !old_have_central && have_central; + const bool have_central = centralWidgetItem != 0 && !centralWidgetItem->isEmpty(); if (have_central) { center_hint = centralWidgetRect.size(); if (!center_hint.isValid()) @@ -2630,6 +2631,8 @@ void QDockAreaLayout::getGrid(QVector *_ver_struct_list, QSize bottom_max = docks[QInternal::BottomDock].maximumSize(); bottom_hint = bottom_hint.boundedTo(bottom_max).expandedTo(bottom_min); + fallbackToSizeHints = !have_central; + if (_ver_struct_list != 0) { QVector &ver_struct_list = *_ver_struct_list; ver_struct_list.resize(3); diff --git a/src/gui/widgets/qdockarealayout_p.h b/src/gui/widgets/qdockarealayout_p.h index 1ed14ce..065890d 100644 --- a/src/gui/widgets/qdockarealayout_p.h +++ b/src/gui/widgets/qdockarealayout_p.h @@ -233,7 +233,7 @@ public: QDockAreaLayout(QMainWindow *win); QDockAreaLayoutInfo docks[4]; int sep; // separator extent - bool have_central; + bool fallbackToSizeHints; //determines if we should use the sizehint for the dock areas (true until the layout is restored or the central widget is set) mutable QVector separatorWidgets; bool isValid() const; -- cgit v0.12 From ce0c22d4da46664636e651285f6e3ba38e77aea7 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 29 Oct 2009 10:40:14 +0100 Subject: Fix qvariant_cast when a QVariant is really inside a QVariant This fix the QPropertyAnimation test. Reviewed-by: Gabriel Reviewed-by: Thierry --- src/corelib/kernel/qvariant.h | 3 +++ tests/auto/qvariant/tst_qvariant.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index a1ab4e9..3c10788 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -581,6 +581,9 @@ template inline T qvariant_cast(const QVariant &v) template<> inline QVariant qvariant_cast(const QVariant &v) { + static const int vid = qRegisterMetaType("QVariant"); + if (vid == v.userType()) + return *reinterpret_cast(v.constData()); return v; } diff --git a/tests/auto/qvariant/tst_qvariant.cpp b/tests/auto/qvariant/tst_qvariant.cpp index 61e9a4f..e2a606f 100644 --- a/tests/auto/qvariant/tst_qvariant.cpp +++ b/tests/auto/qvariant/tst_qvariant.cpp @@ -3380,6 +3380,10 @@ void tst_QVariant::variantInVariant() QVariant var8 = qvariant_cast(QVariant::fromValue(QVariant::fromValue(str))); QCOMPARE((int)var8.type(), (int)QVariant::String); QCOMPARE(qvariant_cast(QVariant(qvariant_cast(var8))), str); + + QVariant var9(qMetaTypeId(), &var1); + QCOMPARE(var9.userType(), qMetaTypeId()); + QCOMPARE(qvariant_cast(var9), var1); } QTEST_MAIN(tst_QVariant) -- cgit v0.12 From 0f1aeb863474d2894a896fb28ea8eae8d736a363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Thu, 29 Oct 2009 11:47:44 +0100 Subject: Fix tst_QWidget::compatibilityChildInsertedEvents test This broke after commit: a8e2a457bb7d2fc377c1c65b6a4172974919e055 (Add a new event type, WinIdChange). The first thing that happens in show() is that the top-level is created, and hence we send WinIdChange. We therefore have to add this event to list of expected events. Reviewed-by: TrustMe --- tests/auto/qwidget/tst_qwidget.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 9c421d1..c27de1d 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -6320,6 +6320,7 @@ void tst_QWidget::compatibilityChildInsertedEvents() widget.show(); expected = EventRecorder::EventList() + << qMakePair(&widget, QEvent::WinIdChange) << qMakePair(&widget, QEvent::Polish) << qMakePair(&widget, QEvent::Move) << qMakePair(&widget, QEvent::Resize) @@ -6405,6 +6406,7 @@ void tst_QWidget::compatibilityChildInsertedEvents() widget.show(); expected = EventRecorder::EventList() + << qMakePair(&widget, QEvent::WinIdChange) << qMakePair(&widget, QEvent::Polish) #ifdef QT_HAS_QT3SUPPORT << qMakePair(&widget, QEvent::ChildInserted) @@ -6502,6 +6504,7 @@ void tst_QWidget::compatibilityChildInsertedEvents() widget.show(); expected = EventRecorder::EventList() + << qMakePair(&widget, QEvent::WinIdChange) << qMakePair(&widget, QEvent::Polish) #ifdef QT_HAS_QT3SUPPORT << qMakePair(&widget, QEvent::ChildInserted) -- cgit v0.12 From 316bf04887aed61804e16d64857754b78cf2f713 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 29 Oct 2009 12:03:34 +0100 Subject: ItemViews: make the geometries update when header data changes autotest included Task-number: QT-711 Reviewed-by: ogoffart --- src/gui/itemviews/qabstractitemview.cpp | 4 ++++ src/gui/itemviews/qabstractitemview.h | 1 + src/gui/itemviews/qabstractitemview_p.h | 1 + tests/auto/qtableview/tst_qtableview.cpp | 21 +++++++++++++++++++++ 4 files changed, 27 insertions(+) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index d91cedd..9247411 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -605,6 +605,8 @@ void QAbstractItemView::setModel(QAbstractItemModel *model) this, SLOT(_q_modelDestroyed())); disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(dataChanged(QModelIndex,QModelIndex))); + disconnect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), + this, SLOT(_q_headerDataChanged())); disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(rowsInserted(QModelIndex,int,int))); disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), @@ -637,6 +639,8 @@ void QAbstractItemView::setModel(QAbstractItemModel *model) this, SLOT(_q_modelDestroyed())); connect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(dataChanged(QModelIndex,QModelIndex))); + connect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), + this, SLOT(_q_headerDataChanged())); connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(rowsInserted(QModelIndex,int,int))); connect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), diff --git a/src/gui/itemviews/qabstractitemview.h b/src/gui/itemviews/qabstractitemview.h index f438148..7a0509b 100644 --- a/src/gui/itemviews/qabstractitemview.h +++ b/src/gui/itemviews/qabstractitemview.h @@ -358,6 +358,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_rowsRemoved(const QModelIndex&, int, int)) Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed()) Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged()) + Q_PRIVATE_SLOT(d_func(), void _q_headerDataChanged()) friend class QTreeViewPrivate; // needed to compile with MSVC friend class QAccessibleItemRow; diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index 66b7662..c691f61 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -117,6 +117,7 @@ public: virtual void _q_columnsInserted(const QModelIndex &parent, int start, int end); virtual void _q_modelDestroyed(); virtual void _q_layoutChanged(); + void _q_headerDataChanged() { doDelayedItemsLayout(); } void fetchMore(); diff --git a/tests/auto/qtableview/tst_qtableview.cpp b/tests/auto/qtableview/tst_qtableview.cpp index fe2794f..227ca6f 100644 --- a/tests/auto/qtableview/tst_qtableview.cpp +++ b/tests/auto/qtableview/tst_qtableview.cpp @@ -203,6 +203,8 @@ private slots: void addColumnWhileEditing(); void task234926_setHeaderSorting(); + + void changeHeaderData(); }; // Testing get/set functions @@ -3883,5 +3885,24 @@ void tst_QTableView::taskQTBUG_5062_spansInconsistency() VERIFY_SPANS_CONSISTENCY(&view); } +void tst_QTableView::changeHeaderData() +{ + QTableView view; + QStandardItemModel model(5,5); + view.setModel(&model); + view.show(); + QTest::qWaitForWindowShown(&view); + + QString text = "long long long text"; + const int textWidth = view.fontMetrics().width(text); + QVERIFY(view.verticalHeader()->width() < textWidth); + + model.setHeaderData(2, Qt::Vertical, text); + QTest::qWait(100); //leave time for layout + + QVERIFY(view.verticalHeader()->width() > textWidth); +} + + QTEST_MAIN(tst_QTableView) #include "tst_qtableview.moc" -- cgit v0.12 From 02d815b4bd497a5c7f07330576a5e3c3da3f46ab Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 29 Oct 2009 15:44:08 +0100 Subject: QListView: make sure we relayout items when data changes in the model Task-number: QTBUG-633 Reviewed-by: ogoffart --- src/gui/itemviews/qlistview.cpp | 6 ++++++ src/gui/itemviews/qlistview_p.h | 3 ++- tests/auto/qlistview/tst_qlistview.cpp | 21 +++++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index 109d760..d680af8 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -2403,6 +2403,12 @@ QVector QListModeViewBase::intersectingSet(const QRect &area) const return ret; } +void QListModeViewBase::dataChanged(const QModelIndex &, const QModelIndex &) +{ + dd->doDelayedItemsLayout(); +} + + QRect QListModeViewBase::mapToViewport(const QRect &rect) const { if (isWrapping()) diff --git a/src/gui/itemviews/qlistview_p.h b/src/gui/itemviews/qlistview_p.h index 3f8f9db..31459b0 100644 --- a/src/gui/itemviews/qlistview_p.h +++ b/src/gui/itemviews/qlistview_p.h @@ -130,6 +130,7 @@ public: virtual void clear() = 0; virtual void setRowCount(int) = 0; virtual QVector intersectingSet(const QRect &area) const = 0; + virtual void dataChanged(const QModelIndex &, const QModelIndex &) = 0; virtual int horizontalScrollToValue(int index, QListView::ScrollHint hint, bool leftOf, bool rightOf, const QRect &area, const QRect &rect) const; @@ -141,7 +142,6 @@ public: virtual int verticalOffset() const { return verticalScrollBar()->value(); } virtual void updateHorizontalScrollBar(const QSize &step); virtual void updateVerticalScrollBar(const QSize &step); - virtual void dataChanged(const QModelIndex &, const QModelIndex &) { } virtual void appendHiddenRow(int row); virtual void removeHiddenRow(int row); virtual void setPositionForIndex(const QPoint &, const QModelIndex &) { } @@ -217,6 +217,7 @@ public: void clear(); void setRowCount(int rowCount) { flowPositions.resize(rowCount); } QVector intersectingSet(const QRect &area) const; + void dataChanged(const QModelIndex &, const QModelIndex &); int horizontalScrollToValue(int index, QListView::ScrollHint hint, bool leftOf, bool rightOf,const QRect &area, const QRect &rect) const; diff --git a/tests/auto/qlistview/tst_qlistview.cpp b/tests/auto/qlistview/tst_qlistview.cpp index 65ab12d..727e6d3 100644 --- a/tests/auto/qlistview/tst_qlistview.cpp +++ b/tests/auto/qlistview/tst_qlistview.cpp @@ -119,6 +119,7 @@ private slots: void task262152_setModelColumnNavigate(); void taskQTBUG_2233_scrollHiddenItems_data(); void taskQTBUG_2233_scrollHiddenItems(); + void taskQTBUG_633_changeModelData(); }; // Testing get/set functions @@ -1832,5 +1833,25 @@ void tst_QListView::taskQTBUG_2233_scrollHiddenItems() } } +void tst_QListView::taskQTBUG_633_changeModelData() +{ + QListView view; + view.setFlow(QListView::LeftToRight); + QStandardItemModel model(5,1); + for (int i = 0; i < model.rowCount(); ++i) { + model.setData( model.index(i, 0), QString::number(i)); + } + + view.setModel(&model); + view.show(); + QTest::qWaitForWindowShown(&view); + model.setData( model.index(1, 0), QLatin1String("long long text")); + QTest::qWait(100); //leave time for relayouting the items + QRect rectLongText = view.visualRect(model.index(1,0)); + QRect rect2 = view.visualRect(model.index(2,0)); + QVERIFY( ! rectLongText.intersects(rect2) ); +} + + QTEST_MAIN(tst_QListView) #include "tst_qlistview.moc" -- cgit v0.12 From 7a6296197cdab656053fbf1fc2584707e78cbe54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 8 Oct 2009 12:57:20 +0200 Subject: Make QT_NO_PHONON_PLATFORMPLUGIN work Reviewed-by:tom --- src/3rdparty/phonon/phonon/factory.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/3rdparty/phonon/phonon/factory.cpp b/src/3rdparty/phonon/phonon/factory.cpp index 5c3752a..e5adb490 100644 --- a/src/3rdparty/phonon/phonon/factory.cpp +++ b/src/3rdparty/phonon/phonon/factory.cpp @@ -189,11 +189,12 @@ bool FactoryPrivate::createBackend() } FactoryPrivate::FactoryPrivate() + : #ifndef QT_NO_PHONON_PLATFORMPLUGIN - : m_platformPlugin(0), - m_noPlatformPlugin(false) + m_platformPlugin(0), + m_noPlatformPlugin(false), #endif //QT_NO_PHONON_PLATFORMPLUGIN - , m_backendObject(0) + m_backendObject(0) { // Add the post routine to make sure that all other global statics (especially the ones from Qt) // are still available. If the FactoryPrivate dtor is called too late many bad things can happen -- cgit v0.12 From 5c4ed2858f31d6b3adcf5200c3a64fbf188a3f4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 9 Oct 2009 11:20:32 +0200 Subject: Fix QFeature QT_NO_PHONON_VOLUMEFADEREFFECT Reviewed-by: Jens Bache-Wiig --- src/3rdparty/phonon/gstreamer/backend.cpp | 4 ++++ src/3rdparty/phonon/gstreamer/volumefadereffect.cpp | 4 ++-- src/3rdparty/phonon/gstreamer/volumefadereffect.h | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/3rdparty/phonon/gstreamer/backend.cpp b/src/3rdparty/phonon/gstreamer/backend.cpp index cd49454..ceaf94a 100644 --- a/src/3rdparty/phonon/gstreamer/backend.cpp +++ b/src/3rdparty/phonon/gstreamer/backend.cpp @@ -134,7 +134,11 @@ QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const } case VolumeFaderEffectClass: +#ifndef QT_NO_PHONON_VOLUMEFADEREFFECT return new VolumeFaderEffect(this, parent); +#else + return 0; +#endif //QT_NO_PHONON_VOLUMEFADEREFFECT case VisualizationClass: //Fall through default: diff --git a/src/3rdparty/phonon/gstreamer/volumefadereffect.cpp b/src/3rdparty/phonon/gstreamer/volumefadereffect.cpp index d7ee11b..bf0d646 100644 --- a/src/3rdparty/phonon/gstreamer/volumefadereffect.cpp +++ b/src/3rdparty/phonon/gstreamer/volumefadereffect.cpp @@ -21,11 +21,11 @@ QT_BEGIN_NAMESPACE +#ifndef QT_NO_PHONON_VOLUMEFADEREFFECT namespace Phonon { namespace Gstreamer { - VolumeFaderEffect::VolumeFaderEffect(Backend *backend, QObject *parent) : Effect(backend, parent, AudioSource | AudioSink) , m_fadeCurve(Phonon::VolumeFaderEffect::Fade3Decibel) @@ -156,7 +156,7 @@ bool VolumeFaderEffect::event(QEvent *event) } }} //namespace Phonon::Gstreamer - +#endif //QT_NO_PHONON_VOLUMEFADEREFFECT QT_END_NAMESPACE #include "moc_volumefadereffect.cpp" diff --git a/src/3rdparty/phonon/gstreamer/volumefadereffect.h b/src/3rdparty/phonon/gstreamer/volumefadereffect.h index d74014c..748d2d6 100644 --- a/src/3rdparty/phonon/gstreamer/volumefadereffect.h +++ b/src/3rdparty/phonon/gstreamer/volumefadereffect.h @@ -30,7 +30,7 @@ #include QT_BEGIN_NAMESPACE - +#ifndef QT_NO_PHONON_VOLUMEFADEREFFECT namespace Phonon { namespace Gstreamer @@ -64,7 +64,7 @@ namespace Gstreamer QTime m_fadeStartTime; }; }} //namespace Phonon::Gstreamer - +#endif //QT_NO_PHONON_VOLUMEFADEREFFECT QT_END_NAMESPACE #endif // Phonon_GSTREAMER_VOLUMEFADEREFFECT_H -- cgit v0.12 From a7a70ad81a9a1f3cba5fca66c232e7d8560a2850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 9 Oct 2009 11:21:51 +0200 Subject: Fix QT_NO_IMAGEFORMAT_PNG Reviewed-by: tom --- src/gui/styles/qcommonstyle.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index 70d130a..b08dc4b 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -5169,13 +5169,12 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget QPixmap QCommonStyle::standardPixmap(StandardPixmap sp, const QStyleOption *option, const QWidget *widget) const { + const bool rtl = (option && option->direction == Qt::RightToLeft) || (!option && QApplication::isRightToLeft()); #ifdef QT_NO_IMAGEFORMAT_PNG - Q_UNUSED(option); Q_UNUSED(widget); Q_UNUSED(sp); #else QPixmap pixmap; - const bool rtl = (option && option->direction == Qt::RightToLeft) || (!option && QApplication::isRightToLeft()); if (QApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty()) { switch (sp) { -- cgit v0.12 From 86e3be13d870e8dce1e06f7cd0adeb8996fade7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 9 Oct 2009 11:22:24 +0200 Subject: Fix dependencies to QT_NO_PRINTPREVIEWWIDGET Reviewed-by: Trust Me --- src/corelib/global/qfeatures.h | 2 +- src/corelib/global/qfeatures.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qfeatures.h b/src/corelib/global/qfeatures.h index 36c2cf9..ab81290 100644 --- a/src/corelib/global/qfeatures.h +++ b/src/corelib/global/qfeatures.h @@ -767,7 +767,7 @@ #endif // QPrintPreviewWidget -#if !defined(QT_NO_PRINTPREVIEWWIDGET) && (defined(QT_NO_GRAPHICSVIEW) || defined(QT_NO_PRINTER)) +#if !defined(QT_NO_PRINTPREVIEWWIDGET) && (defined(QT_NO_GRAPHICSVIEW) || defined(QT_NO_PRINTER) || defined(QT_NO_TOOLBAR) || defined(QT_NO_MAINWINDOW)) #define QT_NO_PRINTPREVIEWWIDGET #endif diff --git a/src/corelib/global/qfeatures.txt b/src/corelib/global/qfeatures.txt index ec47883..a0928fc 100644 --- a/src/corelib/global/qfeatures.txt +++ b/src/corelib/global/qfeatures.txt @@ -567,7 +567,7 @@ Feature: PRINTPREVIEWWIDGET Description: Provides a widget for previewing page layouts for printer output. a date. Section: Widgets -Requires: GRAPHICSVIEW PRINTER +Requires: GRAPHICSVIEW PRINTER TOOLBAR MAINWINDOW Name: QPrintPreviewWidget SeeAlso: ??? -- cgit v0.12 From 854df9c08635fd175f6658e66320d8fa2360389a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 9 Oct 2009 15:51:57 +0200 Subject: The PRINTER feature now depends on TEMPORARYFILE Reviewed-by: Trust Me --- src/corelib/global/qfeatures.h | 2 +- src/corelib/global/qfeatures.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qfeatures.h b/src/corelib/global/qfeatures.h index ab81290..b18196e 100644 --- a/src/corelib/global/qfeatures.h +++ b/src/corelib/global/qfeatures.h @@ -522,7 +522,7 @@ #endif // QPrinter -#if !defined(QT_NO_PRINTER) && (defined(QT_NO_TEXTSTREAM) || defined(QT_NO_PICTURE)) +#if !defined(QT_NO_PRINTER) && (defined(QT_NO_TEXTSTREAM) || defined(QT_NO_PICTURE) || defined(QT_NO_TEMPORARYFILE)) #define QT_NO_PRINTER #endif diff --git a/src/corelib/global/qfeatures.txt b/src/corelib/global/qfeatures.txt index a0928fc..c18df62 100644 --- a/src/corelib/global/qfeatures.txt +++ b/src/corelib/global/qfeatures.txt @@ -910,7 +910,7 @@ SeeAlso: ??? Feature: PRINTER Description: Supports printing Section: Painting -Requires: TEXTSTREAM PICTURE +Requires: TEXTSTREAM PICTURE TEMPORARYFILE Name: QPrinter SeeAlso: ??? -- cgit v0.12 From 8c29407a7bf5af9dbcaff1ea7f24951297aa9e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 16 Oct 2009 10:42:56 +0200 Subject: Fix QT_NO_PHONON_ABSTRACTMEDIASTREAM in phonon Seemed to be missing from gstreamer backend Reviewed-by: Jens Bache-Wiig --- src/3rdparty/phonon/gstreamer/mediaobject.cpp | 5 +++++ src/3rdparty/phonon/gstreamer/phononsrc.cpp | 28 ++++++++++++++++++++++++++ src/3rdparty/phonon/gstreamer/phononsrc.h | 2 ++ src/3rdparty/phonon/gstreamer/streamreader.cpp | 3 ++- src/3rdparty/phonon/gstreamer/streamreader.h | 4 ++++ 5 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/3rdparty/phonon/gstreamer/mediaobject.cpp b/src/3rdparty/phonon/gstreamer/mediaobject.cpp index 5dcbd42..0b800af 100644 --- a/src/3rdparty/phonon/gstreamer/mediaobject.cpp +++ b/src/3rdparty/phonon/gstreamer/mediaobject.cpp @@ -392,6 +392,7 @@ bool MediaObject::createPipefromURL(const QUrl &url) */ bool MediaObject::createPipefromStream(const MediaSource &source) { +#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM // Remove any existing data source if (m_datasource) { gst_bin_remove(GST_BIN(m_pipeline), m_datasource); @@ -413,6 +414,10 @@ bool MediaObject::createPipefromStream(const MediaSource &source) return false; } return true; +#else //QT_NO_PHONON_ABSTRACTMEDIASTREAM + Q_UNUSED(source); + return false; +#endif } void MediaObject::createPipeline() diff --git a/src/3rdparty/phonon/gstreamer/phononsrc.cpp b/src/3rdparty/phonon/gstreamer/phononsrc.cpp index f893fb5..97d7220 100644 --- a/src/3rdparty/phonon/gstreamer/phononsrc.cpp +++ b/src/3rdparty/phonon/gstreamer/phononsrc.cpp @@ -109,18 +109,25 @@ static void phonon_src_class_init (PhononSrcClass * klass) static void phonon_src_init (PhononSrc * src, PhononSrcClass * g_class) { Q_UNUSED(g_class); +#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM src->device = 0; +#else + Q_UNUSED(src); +#endif } static void phonon_src_finalize (GObject * object) { +#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM PhononSrc *src; src = GST_PHONON_SRC (object); delete src->device; src->device = 0; +#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM G_OBJECT_CLASS (parent_class)->finalize (object); } +#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM static gboolean phonon_src_set_device(PhononSrc * src, StreamReader* device) { GstState state; @@ -145,6 +152,7 @@ wrong_state: return FALSE; } } +#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM static void phonon_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { @@ -153,6 +161,7 @@ static void phonon_src_set_property (GObject * object, guint prop_id, const GVal src = GST_PHONON_SRC (object); switch (prop_id) { +#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM case ARG_PHONONSRC: { StreamReader *dev = (StreamReader*)(g_value_get_pointer(value)); @@ -160,6 +169,9 @@ static void phonon_src_set_property (GObject * object, guint prop_id, const GVal phonon_src_set_device(src, dev); break; } +#else + Q_UNUSED(value); +#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -174,9 +186,13 @@ static void phonon_src_get_property (GObject * object, guint prop_id, GValue * v src = GST_PHONON_SRC (object); switch (prop_id) { +#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM case ARG_PHONONSRC: g_value_set_pointer(value, src->device); break; +#else //QT_NO_PHONON_ABSTRACTMEDIASTREAM + Q_UNUSED(value); +#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -185,6 +201,7 @@ static void phonon_src_get_property (GObject * object, guint prop_id, GValue * v static GstFlowReturn phonon_src_create_read (PhononSrc * src, guint64 offset, guint length, GstBuffer ** buffer) { +#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM Q_ASSERT(src->device); if (!src->device) return GST_FLOW_ERROR; @@ -204,6 +221,13 @@ static GstFlowReturn phonon_src_create_read (PhononSrc * src, guint64 offset, gu gst_mini_object_unref(GST_MINI_OBJECT(buf)); return GST_FLOW_ERROR; +#else //QT_NO_PHONON_ABSTRACTMEDIASTREAM + Q_UNUSED(src); + Q_UNUSED(offset); + Q_UNUSED(length); + Q_UNUSED(buffer); + return GST_FLOW_ERROR; +#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM } static GstFlowReturn phonon_src_create (GstBaseSrc * basesrc, guint64 offset, guint length, GstBuffer ** buffer) @@ -218,19 +242,23 @@ static GstFlowReturn phonon_src_create (GstBaseSrc * basesrc, guint64 offset, gu static gboolean phonon_src_is_seekable (GstBaseSrc * basesrc) { PhononSrc *src = GST_PHONON_SRC (basesrc); +#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM if (src->device) return src->device->streamSeekable(); +#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM return false; } static gboolean phonon_src_get_size (GstBaseSrc * basesrc, guint64 * size) { +#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM PhononSrc *src; src = GST_PHONON_SRC (basesrc); if (src->device && src->device->streamSeekable()) { *size = src->device->streamSize(); return TRUE; } +#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM *size = 0; return FALSE; } diff --git a/src/3rdparty/phonon/gstreamer/phononsrc.h b/src/3rdparty/phonon/gstreamer/phononsrc.h index a2cd8b3..a50f8a2 100644 --- a/src/3rdparty/phonon/gstreamer/phononsrc.h +++ b/src/3rdparty/phonon/gstreamer/phononsrc.h @@ -49,7 +49,9 @@ typedef struct _PhononSrcClass PhononSrcClass; // PhononSrc: struct _PhononSrc { GstBaseSrc element; +#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM StreamReader *device; +#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM }; struct _PhononSrcClass { diff --git a/src/3rdparty/phonon/gstreamer/streamreader.cpp b/src/3rdparty/phonon/gstreamer/streamreader.cpp index 04fa6cc..f8219e6 100644 --- a/src/3rdparty/phonon/gstreamer/streamreader.cpp +++ b/src/3rdparty/phonon/gstreamer/streamreader.cpp @@ -20,7 +20,7 @@ along with this library. If not, see . #include QT_BEGIN_NAMESPACE - +#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM namespace Phonon { namespace Gstreamer @@ -49,5 +49,6 @@ bool StreamReader::read(quint64 pos, int length, char * buffer) } } +#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/gstreamer/streamreader.h b/src/3rdparty/phonon/gstreamer/streamreader.h index c2e61c8..387370c 100644 --- a/src/3rdparty/phonon/gstreamer/streamreader.h +++ b/src/3rdparty/phonon/gstreamer/streamreader.h @@ -23,6 +23,8 @@ along with this library. If not, see . QT_BEGIN_NAMESPACE +#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM + namespace Phonon { class MediaSource; @@ -91,6 +93,8 @@ private: } } +#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM + QT_END_NAMESPACE #endif -- cgit v0.12 From 1a8a4b2ce746f357a58b04a02321824f8040b3e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 16 Oct 2009 10:44:52 +0200 Subject: Updated qfeatures.h Reviewed-by: Trust Me --- src/corelib/global/qfeatures.h | 27 ++++++++++++++------------- util/scripts/make_qfeatures_dot_h | 1 + 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/corelib/global/qfeatures.h b/src/corelib/global/qfeatures.h index b18196e..d87cf64 100644 --- a/src/corelib/global/qfeatures.h +++ b/src/corelib/global/qfeatures.h @@ -43,6 +43,7 @@ * All features and their dependencies. * * This list is generated from $QTDIR/src/corelib/global/qfeatures.txt + * by $QTSRCDIR/util/scripts/make_qfeatures_dot_h */ // QAction @@ -521,11 +522,6 @@ #define QT_NO_LIBRARY #endif -// QPrinter -#if !defined(QT_NO_PRINTER) && (defined(QT_NO_TEXTSTREAM) || defined(QT_NO_PICTURE) || defined(QT_NO_TEMPORARYFILE)) -#define QT_NO_PRINTER -#endif - // QScrollArea #if !defined(QT_NO_SCROLLAREA) && (defined(QT_NO_SCROLLBAR)) #define QT_NO_SCROLLAREA @@ -561,6 +557,11 @@ #define QT_NO_MDIAREA #endif +// QPrinter +#if !defined(QT_NO_PRINTER) && (defined(QT_NO_TEXTSTREAM) || defined(QT_NO_PICTURE) || defined(QT_NO_TEMPORARYFILE)) +#define QT_NO_PRINTER +#endif + // QSpinBox #if !defined(QT_NO_SPINBOX) && (defined(QT_NO_SPINWIDGET) || defined(QT_NO_LINEEDIT) || defined(QT_NO_VALIDATOR)) #define QT_NO_SPINBOX @@ -731,11 +732,6 @@ #define QT_NO_COMPLETER #endif -// Common UNIX Printing System -#if !defined(QT_NO_CUPS) && (defined(QT_NO_PRINTER) || defined(QT_NO_LIBRARY)) -#define QT_NO_CUPS -#endif - // QDataWidgetMapper #if !defined(QT_NO_DATAWIDGETMAPPER) && (defined(QT_NO_ITEMVIEWS) || defined(QT_NO_PROPERTIES)) #define QT_NO_DATAWIDGETMAPPER @@ -766,9 +762,9 @@ #define QT_NO_TREEWIDGET #endif -// QPrintPreviewWidget -#if !defined(QT_NO_PRINTPREVIEWWIDGET) && (defined(QT_NO_GRAPHICSVIEW) || defined(QT_NO_PRINTER) || defined(QT_NO_TOOLBAR) || defined(QT_NO_MAINWINDOW)) -#define QT_NO_PRINTPREVIEWWIDGET +// Common UNIX Printing System +#if !defined(QT_NO_CUPS) && (defined(QT_NO_PRINTER) || defined(QT_NO_LIBRARY)) +#define QT_NO_CUPS #endif // QToolBar @@ -831,6 +827,11 @@ #define QT_NO_FONTDIALOG #endif +// QPrintPreviewWidget +#if !defined(QT_NO_PRINTPREVIEWWIDGET) && (defined(QT_NO_GRAPHICSVIEW) || defined(QT_NO_PRINTER) || defined(QT_NO_TOOLBAR) || defined(QT_NO_MAINWINDOW)) +#define QT_NO_PRINTPREVIEWWIDGET +#endif + // QWorkSpace #if !defined(QT_NO_WORKSPACE) && (defined(QT_NO_SCROLLBAR) || defined(QT_NO_RESIZEHANDLER) || defined(QT_NO_MENU) || defined(QT_NO_TOOLBUTTON) || defined(QT_NO_MAINWINDOW) || defined(QT_NO_TOOLBAR) || defined(QT_NO_MENUBAR)) #define QT_NO_WORKSPACE diff --git a/util/scripts/make_qfeatures_dot_h b/util/scripts/make_qfeatures_dot_h index bdd68a3..23d88a3 100755 --- a/util/scripts/make_qfeatures_dot_h +++ b/util/scripts/make_qfeatures_dot_h @@ -175,6 +175,7 @@ print OUT * All features and their dependencies. * * This list is generated from $QTDIR/src/corelib/global/qfeatures.txt + * by $QTSRCDIR/util/scripts/make_qfeatures_dot_h */ '; -- cgit v0.12 From 5c4130a509248e897d52e4980cc8d58f0940d76c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 16 Oct 2009 11:42:00 +0200 Subject: Added QT_NO_PHONON_EFFECT to gstreamer backend Reviewed-by: Jens Bache-Wiig --- src/3rdparty/phonon/gstreamer/audioeffect.cpp | 3 ++- src/3rdparty/phonon/gstreamer/audioeffect.h | 4 ++-- src/3rdparty/phonon/gstreamer/backend.cpp | 3 ++- src/3rdparty/phonon/gstreamer/effect.cpp | 4 ++-- src/3rdparty/phonon/gstreamer/effect.h | 4 ++-- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/3rdparty/phonon/gstreamer/audioeffect.cpp b/src/3rdparty/phonon/gstreamer/audioeffect.cpp index db72c8b..d3d7a35 100644 --- a/src/3rdparty/phonon/gstreamer/audioeffect.cpp +++ b/src/3rdparty/phonon/gstreamer/audioeffect.cpp @@ -23,7 +23,7 @@ #include "gsthelper.h" #include - +#ifndef QT_NO_PHONON_EFFECT QT_BEGIN_NAMESPACE namespace Phonon @@ -75,4 +75,5 @@ GstElement* AudioEffect::createEffectBin() } //namespace Phonon::Gstreamer QT_END_NAMESPACE +#endif //QT_NO_PHONON_EFFECT #include "moc_audioeffect.cpp" diff --git a/src/3rdparty/phonon/gstreamer/audioeffect.h b/src/3rdparty/phonon/gstreamer/audioeffect.h index 3a985e5..f49f8d2 100644 --- a/src/3rdparty/phonon/gstreamer/audioeffect.h +++ b/src/3rdparty/phonon/gstreamer/audioeffect.h @@ -29,8 +29,8 @@ #include +#ifndef QT_NO_PHONON_EFFECT QT_BEGIN_NAMESPACE - namespace Phonon { namespace Gstreamer @@ -49,7 +49,7 @@ namespace Gstreamer QString m_effectName; }; }} //namespace Phonon::Gstreamer - QT_END_NAMESPACE +#endif //QT_NO_PHONON_EFFECT #endif // Phonon_GSTREAMER_AUDIOEFFECT_H diff --git a/src/3rdparty/phonon/gstreamer/backend.cpp b/src/3rdparty/phonon/gstreamer/backend.cpp index ceaf94a..b285fd9 100644 --- a/src/3rdparty/phonon/gstreamer/backend.cpp +++ b/src/3rdparty/phonon/gstreamer/backend.cpp @@ -117,9 +117,10 @@ QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const m_audioOutputs.append(ao); return ao; } +#ifndef QT_NO_PHONON_EFFECT case EffectClass: return new AudioEffect(this, args[0].toInt(), parent); - +#endif //QT_NO_PHONON_EFFECT case AudioDataOutputClass: logMessage("createObject() : AudioDataOutput not implemented"); break; diff --git a/src/3rdparty/phonon/gstreamer/effect.cpp b/src/3rdparty/phonon/gstreamer/effect.cpp index f653535..4937246 100644 --- a/src/3rdparty/phonon/gstreamer/effect.cpp +++ b/src/3rdparty/phonon/gstreamer/effect.cpp @@ -25,8 +25,8 @@ #include +#ifndef QT_NO_PHONON_EFFECT QT_BEGIN_NAMESPACE - namespace Phonon { namespace Gstreamer @@ -241,6 +241,6 @@ void Effect::setParameterValue(const EffectParameter &p, const QVariant &v) } } //namespace Phonon::Gstreamer - QT_END_NAMESPACE +#endif //QT_NO_PHONON_EFFECT #include "moc_effect.cpp" diff --git a/src/3rdparty/phonon/gstreamer/effect.h b/src/3rdparty/phonon/gstreamer/effect.h index dbbb457..51cbe9c 100644 --- a/src/3rdparty/phonon/gstreamer/effect.h +++ b/src/3rdparty/phonon/gstreamer/effect.h @@ -28,8 +28,8 @@ #include +#ifndef QT_NO_PHONON_EFFECT QT_BEGIN_NAMESPACE - namespace Phonon { namespace Gstreamer @@ -58,7 +58,7 @@ namespace Gstreamer QList m_parameterList; }; }} //namespace Phonon::Gstreamer - QT_END_NAMESPACE +#endif //QT_NO_PHONON_EFFECT #endif // Phonon_GSTREAMER_EFFECT_H -- cgit v0.12 From 7c1122b79df61668525b63670c03c5da7e44ac9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Mon, 19 Oct 2009 09:41:57 +0200 Subject: Fix QT_NO_XMLSTREAMREADER Reviewed-by: tom --- src/corelib/xml/qxmlstream.g | 4 +++- src/corelib/xml/qxmlstream_p.h | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/corelib/xml/qxmlstream.g b/src/corelib/xml/qxmlstream.g index 3bf0e7d..6c0c0cf 100644 --- a/src/corelib/xml/qxmlstream.g +++ b/src/corelib/xml/qxmlstream.g @@ -243,7 +243,7 @@ public: class QXmlStreamEntityResolver; - +#ifndef QT_NO_XMLSTREAMREADER class QXmlStreamReaderPrivate : public QXmlStreamReader_Table, public QXmlStreamPrivateTagStack{ QXmlStreamReader *q_ptr; Q_DECLARE_PUBLIC(QXmlStreamReader) @@ -1840,4 +1840,6 @@ nmtoken ::= COLON; } return false; } +#endif //QT_NO_XMLSTREAMREADER.xml + ./ diff --git a/src/corelib/xml/qxmlstream_p.h b/src/corelib/xml/qxmlstream_p.h index ed65409..eee3a13 100644 --- a/src/corelib/xml/qxmlstream_p.h +++ b/src/corelib/xml/qxmlstream_p.h @@ -736,9 +736,9 @@ public: } }; - class QXmlStreamEntityResolver; +#ifndef QT_NO_XMLSTREAMREADER class QXmlStreamReaderPrivate : public QXmlStreamReader_Table, public QXmlStreamPrivateTagStack{ QXmlStreamReader *q_ptr; Q_DECLARE_PUBLIC(QXmlStreamReader) @@ -1959,5 +1959,6 @@ bool QXmlStreamReaderPrivate::parse() return false; } +#endif //QT_NO_XMLSTREAMREADER #endif // QXMLSTREAM_P_H -- cgit v0.12 From 7246b5a5942049b485bfdefbe133d7bb12165301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Mon, 19 Oct 2009 09:43:36 +0200 Subject: Fix QT_NO_ACTION dependencies Reviewed-by: tom --- src/corelib/global/qfeatures.h | 25 +++++++++++++++---------- src/corelib/global/qfeatures.txt | 11 +++++++++-- src/gui/kernel/qsoftkeymanager.cpp | 3 ++- src/gui/kernel/qsoftkeymanager_p.h | 2 ++ 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/corelib/global/qfeatures.h b/src/corelib/global/qfeatures.h index d87cf64..1266be1 100644 --- a/src/corelib/global/qfeatures.h +++ b/src/corelib/global/qfeatures.h @@ -307,11 +307,6 @@ // //#define QT_NO_XMLSTREAM -// Accessibility -#if !defined(QT_NO_ACCESSIBILITY) && (defined(QT_NO_PROPERTIES)) -#define QT_NO_ACCESSIBILITY -#endif - // Animation #if !defined(QT_NO_ANIMATION) && (defined(QT_NO_PROPERTIES)) #define QT_NO_ANIMATION @@ -387,11 +382,6 @@ #define QT_NO_PHONON_VOLUMEFADEREFFECT #endif -// Phonon::VolumeSlider -#if !defined(QT_NO_PHONON_VOLUMESLIDER) && (defined(QT_NO_SLIDER)) -#define QT_NO_PHONON_VOLUMESLIDER -#endif - // QProcess #if !defined(QT_NO_PROCESS) && (defined(QT_NO_THREAD)) #define QT_NO_PROCESS @@ -442,6 +432,11 @@ #define QT_NO_SOCKS5 #endif +// QSoftKeyManager +#if !defined(QT_NO_SOFTKEYMANAGER) && (defined(QT_NO_ACTION)) +#define QT_NO_SOFTKEYMANAGER +#endif + // QSplitter #if !defined(QT_NO_SPLITTER) && (defined(QT_NO_RUBBERBAND)) #define QT_NO_SPLITTER @@ -497,6 +492,11 @@ #define QT_NO_XMLSTREAMWRITER #endif +// Accessibility +#if !defined(QT_NO_ACCESSIBILITY) && (defined(QT_NO_PROPERTIES) || defined(QT_NO_ACTION)) +#define QT_NO_ACCESSIBILITY +#endif + // Context menu #if !defined(QT_NO_CONTEXTMENU) && (defined(QT_NO_MENU)) #define QT_NO_CONTEXTMENU @@ -522,6 +522,11 @@ #define QT_NO_LIBRARY #endif +// Phonon::VolumeSlider +#if !defined(QT_NO_PHONON_VOLUMESLIDER) && (defined(QT_NO_SLIDER) || defined(QT_NO_ACTION)) +#define QT_NO_PHONON_VOLUMESLIDER +#endif + // QScrollArea #if !defined(QT_NO_SCROLLAREA) && (defined(QT_NO_SCROLLBAR)) #define QT_NO_SCROLLAREA diff --git a/src/corelib/global/qfeatures.txt b/src/corelib/global/qfeatures.txt index c18df62..9d4eb5e 100644 --- a/src/corelib/global/qfeatures.txt +++ b/src/corelib/global/qfeatures.txt @@ -70,6 +70,13 @@ Requires: Name: QAction SeeAlso: ??? +Feature: SOFTKEYMANAGER +Description: Supports softkeys. +Section: Gui +Requires: ACTION +Name: QSoftKeyManager +SeeAlso: ??? + Feature: CURSOR Description: Supports mouse cursors. Section: Kernel @@ -1146,7 +1153,7 @@ SeeAlso: ??? Feature: ACCESSIBILITY Description: Provides accessibility support. Section: Utilities -Requires: PROPERTIES +Requires: PROPERTIES ACTION Name: Accessibility SeeAlso: ??? @@ -1403,7 +1410,7 @@ SeeAlso: ??? Feature: PHONON_VOLUMESLIDER Description: Support for the Volume Slider class Section: Phonon -Requires: SLIDER +Requires: SLIDER ACTION Name: Phonon::VolumeSlider SeeAlso: ??? diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp index 75c321e..5249dab 100644 --- a/src/gui/kernel/qsoftkeymanager.cpp +++ b/src/gui/kernel/qsoftkeymanager.cpp @@ -48,6 +48,7 @@ #include "private/qsoftkeymanager_p.h" #include "private/qobject_p.h" +#ifndef QT_NO_SOFTKEYMANAGER QT_BEGIN_NAMESPACE #ifdef Q_WS_S60 @@ -277,4 +278,4 @@ void QSoftKeyManagerPrivate::updateSoftKeys_sys(const QList &) #endif QT_END_NAMESPACE - +#endif //QT_NO_SOFTKEYMANAGER diff --git a/src/gui/kernel/qsoftkeymanager_p.h b/src/gui/kernel/qsoftkeymanager_p.h index b455445..62d872f 100644 --- a/src/gui/kernel/qsoftkeymanager_p.h +++ b/src/gui/kernel/qsoftkeymanager_p.h @@ -58,6 +58,7 @@ QT_BEGIN_HEADER +#ifndef QT_NO_SOFTKEYMANAGER QT_BEGIN_NAMESPACE class QSoftKeyManagerPrivate; @@ -100,6 +101,7 @@ private Q_SLOTS: }; QT_END_NAMESPACE +#endif //QT_NO_SOFTKEYMANAGER QT_END_HEADER -- cgit v0.12 From e55810dc838e95c60a275f1ea3be3bb6bb93fb83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Mon, 19 Oct 2009 10:59:39 +0200 Subject: Fix QT_NO_PROPERTIES However, there are some stuff added to qscript that I'm really not sure about. Reviewed-by: tom --- src/3rdparty/phonon/gstreamer/backend.cpp | 3 ++- src/3rdparty/phonon/phonon/factory.cpp | 3 ++- src/script/bridge/qscriptqobject.cpp | 16 ++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/phonon/gstreamer/backend.cpp b/src/3rdparty/phonon/gstreamer/backend.cpp index b285fd9..647bb6f 100644 --- a/src/3rdparty/phonon/gstreamer/backend.cpp +++ b/src/3rdparty/phonon/gstreamer/backend.cpp @@ -55,12 +55,13 @@ Backend::Backend(QObject *parent, const QVariantList &) g_error_free(err); qRegisterMetaType("Message"); - +#ifndef QT_NO_PROPERTIES setProperty("identifier", QLatin1String("phonon_gstreamer")); setProperty("backendName", QLatin1String("Gstreamer")); setProperty("backendComment", QLatin1String("Gstreamer plugin for Phonon")); setProperty("backendVersion", QLatin1String("0.2")); setProperty("backendWebsite", QLatin1String("http://qt.nokia.com/")); +#endif //QT_NO_PROPERTIES //check if we should enable debug output QString debugLevelString = qgetenv("PHONON_GST_DEBUG"); diff --git a/src/3rdparty/phonon/phonon/factory.cpp b/src/3rdparty/phonon/phonon/factory.cpp index e5adb490..881aca3 100644 --- a/src/3rdparty/phonon/phonon/factory.cpp +++ b/src/3rdparty/phonon/phonon/factory.cpp @@ -443,6 +443,7 @@ QObject *Factory::backend(bool createWhenNull) return globalFactory->m_backendObject; } +#ifndef QT_NO_PROPERTIES #define GET_STRING_PROPERTY(name) \ QString Factory::name() \ { \ @@ -458,7 +459,7 @@ GET_STRING_PROPERTY(backendComment) GET_STRING_PROPERTY(backendVersion) GET_STRING_PROPERTY(backendIcon) GET_STRING_PROPERTY(backendWebsite) - +#endif //QT_NO_PROPERTIES QObject *Factory::registerQObject(QObject *o) { if (o) { diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp index 345489f..caf1018 100644 --- a/src/script/bridge/qscriptqobject.cpp +++ b/src/script/bridge/qscriptqobject.cpp @@ -1190,6 +1190,7 @@ bool QObjectDelegate::getOwnPropertySlot(QScriptObject *object, JSC::ExecState * const JSC::Identifier &propertyName, JSC::PropertySlot &slot) { +#ifndef QT_NO_PROPERTIES QByteArray name = QString(propertyName.ustring()).toLatin1(); QObject *qobject = data->value; if (!qobject) { @@ -1296,12 +1297,16 @@ bool QObjectDelegate::getOwnPropertySlot(QScriptObject *object, JSC::ExecState * } return QScriptObjectDelegate::getOwnPropertySlot(object, exec, propertyName, slot); +#else //QT_NO_PROPERTIES + return false; +#endif //QT_NO_PROPERTIES } void QObjectDelegate::put(QScriptObject *object, JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSValue value, JSC::PutPropertySlot &slot) { +#ifndef QT_NO_PROPERTIES QByteArray name = ((QString)propertyName.ustring()).toLatin1(); QObject *qobject = data->value; if (!qobject) { @@ -1392,12 +1397,14 @@ void QObjectDelegate::put(QScriptObject *object, JSC::ExecState* exec, } QScriptObjectDelegate::put(object, exec, propertyName, value, slot); +#endif //QT_NO_PROPERTIES } bool QObjectDelegate::deleteProperty(QScriptObject *object, JSC::ExecState *exec, const JSC::Identifier& propertyName, bool checkDontDelete) { +#ifndef QT_NO_PROPERTIES QByteArray name = ((QString)propertyName.ustring()).toLatin1(); QObject *qobject = data->value; if (!qobject) { @@ -1436,6 +1443,9 @@ bool QObjectDelegate::deleteProperty(QScriptObject *object, JSC::ExecState *exec } return QScriptObjectDelegate::deleteProperty(object, exec, propertyName, checkDontDelete); +#else //QT_NO_PROPERTIES + return false; +#endif //QT_NO_PROPERTIES } bool QObjectDelegate::getPropertyAttributes(const QScriptObject *object, @@ -1443,6 +1453,7 @@ bool QObjectDelegate::getPropertyAttributes(const QScriptObject *object, const JSC::Identifier &propertyName, unsigned &attributes) const { +#ifndef QT_NO_PROPERTIES // ### try to avoid duplicating logic from getOwnPropertySlot() QByteArray name = ((QString)propertyName.ustring()).toLatin1(); QObject *qobject = data->value; @@ -1511,12 +1522,16 @@ bool QObjectDelegate::getPropertyAttributes(const QScriptObject *object, } return QScriptObjectDelegate::getPropertyAttributes(object, exec, propertyName, attributes); +#else //QT_NO_PROPERTIES + return false; +#endif //QT_NO_PROPERTIES } void QObjectDelegate::getOwnPropertyNames(QScriptObject *object, JSC::ExecState *exec, JSC::PropertyNameArray &propertyNames, bool includeNonEnumerable) { +#ifndef QT_NO_PROPERTIES QObject *qobject = data->value; if (!qobject) { QString message = QString::fromLatin1("cannot get property names of deleted QObject"); @@ -1560,6 +1575,7 @@ void QObjectDelegate::getOwnPropertyNames(QScriptObject *object, JSC::ExecState } QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, includeNonEnumerable); +#endif //QT_NO_PROPERTIES } void QObjectDelegate::markChildren(QScriptObject *object, JSC::MarkStack& markStack) -- cgit v0.12 From 6eb1faad9511dde6ab31b9a4f75fce0bdfbdc12c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Mon, 19 Oct 2009 13:55:38 +0200 Subject: Fixed MENU and QWS_PROXYSCREEN Reviewed-by: tom --- src/corelib/global/qfeatures.h | 20 +++++++++++++++----- src/corelib/global/qfeatures.txt | 16 +++++++++++++++- src/plugins/gfxdrivers/transformed/main.cpp | 5 ++++- src/plugins/gfxdrivers/vnc/main.cpp | 5 ++++- 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/corelib/global/qfeatures.h b/src/corelib/global/qfeatures.h index 1266be1..c9dfabb 100644 --- a/src/corelib/global/qfeatures.h +++ b/src/corelib/global/qfeatures.h @@ -417,6 +417,16 @@ #define QT_NO_QWS_MANAGER #endif +// QVncTransformed +#if !defined(QT_NO_QWS_TRANSFORMED) && (defined(QT_NO_QWS_PROXYSCREEN)) +#define QT_NO_QWS_TRANSFORMED +#endif + +// QVncScreen +#if !defined(QT_NO_QWS_VNC) && (defined(QT_NO_QWS_PROXYSCREEN)) +#define QT_NO_QWS_VNC +#endif + // QScrollBar #if !defined(QT_NO_SCROLLBAR) && (defined(QT_NO_SLIDER)) #define QT_NO_SCROLLBAR @@ -492,11 +502,6 @@ #define QT_NO_XMLSTREAMWRITER #endif -// Accessibility -#if !defined(QT_NO_ACCESSIBILITY) && (defined(QT_NO_PROPERTIES) || defined(QT_NO_ACTION)) -#define QT_NO_ACCESSIBILITY -#endif - // Context menu #if !defined(QT_NO_CONTEXTMENU) && (defined(QT_NO_MENU)) #define QT_NO_CONTEXTMENU @@ -617,6 +622,11 @@ #define QT_NO_UNDOGROUP #endif +// Accessibility +#if !defined(QT_NO_ACCESSIBILITY) && (defined(QT_NO_PROPERTIES) || defined(QT_NO_ACTION) || defined(QT_NO_MENU)) +#define QT_NO_ACCESSIBILITY +#endif + // The Model/View Framework #if !defined(QT_NO_ITEMVIEWS) && (defined(QT_NO_RUBBERBAND) || defined(QT_NO_SCROLLAREA)) #define QT_NO_ITEMVIEWS diff --git a/src/corelib/global/qfeatures.txt b/src/corelib/global/qfeatures.txt index 9d4eb5e..fb9181b 100644 --- a/src/corelib/global/qfeatures.txt +++ b/src/corelib/global/qfeatures.txt @@ -1153,7 +1153,7 @@ SeeAlso: ??? Feature: ACCESSIBILITY Description: Provides accessibility support. Section: Utilities -Requires: PROPERTIES ACTION +Requires: PROPERTIES ACTION MENU Name: Accessibility SeeAlso: ??? @@ -1324,6 +1324,20 @@ Requires: Name: QProxyScreen SeeAlso: ??? +Feature: QWS_VNC +Description: Provides VNC screen driver +Section: Qt for Embedded Linux +Requires: QWS_PROXYSCREEN +Name: QVncScreen +SeeAlso: ??? + +Feature: QWS_TRANSFORMED +Description: Provides Transformed screen driver +Section: Qt for Embedded Linux +Requires: QWS_PROXYSCREEN +Name: QVncTransformed +SeeAlso: ??? + Feature: QWS_DYNAMICSCREENTRANSFORMATION Description: Enables dynamic setting of screen transformation/rotation. Section: Qt for Embedded Linux diff --git a/src/plugins/gfxdrivers/transformed/main.cpp b/src/plugins/gfxdrivers/transformed/main.cpp index 982882e..859fd49 100644 --- a/src/plugins/gfxdrivers/transformed/main.cpp +++ b/src/plugins/gfxdrivers/transformed/main.cpp @@ -68,9 +68,12 @@ QStringList GfxTransformedDriver::keys() const QScreen* GfxTransformedDriver::create(const QString& driver, int displayId) { +#ifndef QT_NO_QWS_TRANSFORMED if (driver.toLower() == "transformed") return new QTransformedScreen(displayId); - +#else //QT_NO_QWS_TRANSFORMED + printf("QT buildt with QT_NO_QWS_TRANSFORMED. No screen driver returned\n"); +#endif //QT_NO_QWS_TRANSFORMED return 0; } diff --git a/src/plugins/gfxdrivers/vnc/main.cpp b/src/plugins/gfxdrivers/vnc/main.cpp index aa20d11..7d91ff5 100644 --- a/src/plugins/gfxdrivers/vnc/main.cpp +++ b/src/plugins/gfxdrivers/vnc/main.cpp @@ -68,9 +68,12 @@ QStringList GfxVncDriver::keys() const QScreen* GfxVncDriver::create(const QString& driver, int displayId) { +#ifndef QT_NO_QWS_VNC if (driver.toLower() == "vnc") return new QVNCScreen(displayId); - +#else //QT_NO_QWS_VNC + printf("QT buildt with QT_NO_QWS_VNC. No screen driver returned\n"); +#endif //QT_NO_QWS_VNC return 0; } -- cgit v0.12 From cbef10e1781cdef5ec6dcf0bdeea6506258ee431 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Mon, 19 Oct 2009 16:25:44 +0200 Subject: Fix Validator Reviewed-by: tom --- src/gui/widgets/qlinecontrol_p.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h index 68898b6..f8e1a5d 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -174,8 +174,10 @@ public: void setMaxLength(int maxLength); int maxLength() const; +#ifndef QT_NO_VALIDATOR const QValidator *validator() const; void setValidator(const QValidator *); +#endif #ifndef QT_NO_COMPLETER QCompleter *completer() const; @@ -282,7 +284,9 @@ private: bool finishChange(int validateFromState = -1, bool update = false, bool edited = true); +#ifndef QT_NO_VALIDATOR QPointer m_validator; +#endif QPointer m_completer; #ifndef QT_NO_COMPLETER bool advanceToEnabledItem(int dir); @@ -623,6 +627,7 @@ inline int QLineControl::maxLength() const return m_maxLength; } +#ifndef QT_NO_VALIDATOR inline const QValidator *QLineControl::validator() const { return m_validator; @@ -632,6 +637,7 @@ inline void QLineControl::setValidator(const QValidator *v) { m_validator = const_cast(v); } +#endif #ifndef QT_NO_COMPLETER inline QCompleter *QLineControl::completer() const -- cgit v0.12 From f56f27e2cfd5880dfa8435f7648b080e02c8ee99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Tue, 20 Oct 2009 09:18:44 +0200 Subject: Fix QT_NO_GROUPBOX Reviewed-by: tom --- src/gui/widgets/qplaintextedit.cpp | 2 +- src/gui/widgets/qtextedit.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index fc61889..bb93546 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -1599,7 +1599,6 @@ void QPlainTextEdit::keyPressEvent(QKeyEvent *e) return; } } -#endif // QT_NO_SHORTCUT if (!(tif & Qt::TextEditable)) { switch (e->key()) { @@ -1627,6 +1626,7 @@ void QPlainTextEdit::keyPressEvent(QKeyEvent *e) } return; } +#endif // QT_NO_SHORTCUT d->sendControlEvent(e); #ifdef QT_KEYPAD_NAVIGATION diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp index f477fee..d995e0f 100644 --- a/src/gui/widgets/qtextedit.cpp +++ b/src/gui/widgets/qtextedit.cpp @@ -1246,7 +1246,6 @@ void QTextEdit::keyPressEvent(QKeyEvent *e) return; } } -#endif // QT_NO_SHORTCUT if (!(tif & Qt::TextEditable)) { switch (e->key()) { @@ -1274,6 +1273,7 @@ void QTextEdit::keyPressEvent(QKeyEvent *e) } return; } +#endif // QT_NO_SHORTCUT { QTextCursor cursor = d->control->textCursor(); -- cgit v0.12 From 488a89e2671fb93981db6c71f3557500b9f52588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Tue, 20 Oct 2009 09:19:40 +0200 Subject: Fix QT_NO_GROUPBOX Reviewed-by: tom --- src/gui/styles/qcleanlooksstyle.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp index fc12cfe..973e682 100644 --- a/src/gui/styles/qcleanlooksstyle.cpp +++ b/src/gui/styles/qcleanlooksstyle.cpp @@ -3825,6 +3825,7 @@ QSize QCleanlooksStyle::sizeFromContents(ContentsType type, const QStyleOption * } } break; +#ifndef QT_NO_GROUPBOX case CT_GroupBox: // Since we use a bold font we have to recalculate base width if (const QGroupBox *gb = qobject_cast(widget)) { @@ -3840,6 +3841,7 @@ QSize QCleanlooksStyle::sizeFromContents(ContentsType type, const QStyleOption * } newSize += QSize(0, 1); break; +#endif //QT_NO_GROUPBOX case CT_RadioButton: case CT_CheckBox: newSize += QSize(0, 1); -- cgit v0.12 From d24fd9b951352fe184ff9bccb0f53e18368e8735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 21 Oct 2009 15:23:30 +0200 Subject: Fix LIBRARY and SETTINGS in phonon Reviewed-by: Jens Bache-Wiig Squash me with Fix LIBRARY and SETTINGS in phonon 7d2282 --- src/3rdparty/phonon/gstreamer/artssink.cpp | 3 ++- src/3rdparty/phonon/gstreamer/devicemanager.cpp | 7 +++++-- src/3rdparty/phonon/gstreamer/mediaobject.cpp | 6 +++++- src/3rdparty/phonon/phonon/factory.cpp | 6 ++++++ src/3rdparty/phonon/phonon/globalconfig.cpp | 14 ++++++++++++-- src/3rdparty/phonon/phonon/globalconfig_p.h | 4 ++++ src/3rdparty/phonon/phonon/qsettingsgroup_p.h | 3 +++ 7 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/3rdparty/phonon/gstreamer/artssink.cpp b/src/3rdparty/phonon/gstreamer/artssink.cpp index ff56da9..441607d 100644 --- a/src/3rdparty/phonon/gstreamer/artssink.cpp +++ b/src/3rdparty/phonon/gstreamer/artssink.cpp @@ -233,7 +233,7 @@ static void arts_sink_init (ArtsSink * src, ArtsSinkClass * g_class) Q_UNUSED(g_class); GST_DEBUG_OBJECT (src, "initializing artssink"); src->stream = 0; - +#ifndef QT_NO_LIBRARY p_arts_init = (Ptr_arts_init)QLibrary::resolve(QLatin1String("artsc"), 0, "arts_init"); p_arts_play_stream = (Ptr_arts_play_stream)QLibrary::resolve(QLatin1String("artsc"), 0, "arts_play_stream"); p_arts_close_stream = (Ptr_arts_close_stream)QLibrary::resolve(QLatin1String("artsc"), 0, "arts_close_stream"); @@ -250,6 +250,7 @@ static void arts_sink_init (ArtsSink * src, ArtsSinkClass * g_class) } } sinkCount ++; +#endif //QT_NO_LIBRARY } static void arts_sink_dispose (GObject * object) diff --git a/src/3rdparty/phonon/gstreamer/devicemanager.cpp b/src/3rdparty/phonon/gstreamer/devicemanager.cpp index 2240396..86463c1 100644 --- a/src/3rdparty/phonon/gstreamer/devicemanager.cpp +++ b/src/3rdparty/phonon/gstreamer/devicemanager.cpp @@ -72,18 +72,21 @@ DeviceManager::DeviceManager(Backend *backend) : QObject(backend) , m_backend(backend) { + m_audioSink = qgetenv("PHONON_GST_AUDIOSINK"); + m_videoSinkWidget = qgetenv("PHONON_GST_VIDEOMODE"); + +#ifndef QT_NO_SETTINGS QSettings settings(QLatin1String("Trolltech")); settings.beginGroup(QLatin1String("Qt")); - m_audioSink = qgetenv("PHONON_GST_AUDIOSINK"); if (m_audioSink.isEmpty()) { m_audioSink = settings.value(QLatin1String("audiosink"), "Auto").toByteArray().toLower(); } - m_videoSinkWidget = qgetenv("PHONON_GST_VIDEOMODE"); if (m_videoSinkWidget.isEmpty()) { m_videoSinkWidget = settings.value(QLatin1String("videomode"), "Auto").toByteArray().toLower(); } +#endif //QT_NO_SETTINGS if (m_backend->isValid()) updateDeviceList(); diff --git a/src/3rdparty/phonon/gstreamer/mediaobject.cpp b/src/3rdparty/phonon/gstreamer/mediaobject.cpp index 0b800af..1c32c3c 100644 --- a/src/3rdparty/phonon/gstreamer/mediaobject.cpp +++ b/src/3rdparty/phonon/gstreamer/mediaobject.cpp @@ -226,6 +226,7 @@ void MediaObject::cb_unknown_type (GstElement *decodebin, GstPad *pad, GstCaps * QString value = "unknown codec"; // These functions require GStreamer > 0.10.12 +#ifndef QT_NO_LIBRARY static Ptr_gst_pb_utils_init p_gst_pb_utils_init = 0; static Ptr_gst_pb_utils_get_codec_description p_gst_pb_utils_get_codec_description = 0; if (!p_gst_pb_utils_init) { @@ -239,10 +240,13 @@ void MediaObject::cb_unknown_type (GstElement *decodebin, GstPad *pad, GstCaps * codecName = p_gst_pb_utils_get_codec_description (caps); value = QString::fromUtf8(codecName); g_free (codecName); - } else { + } else +#endif //QT_NO_LIBRARY + { // For GStreamer versions < 0.10.12 GstStructure *str = gst_caps_get_structure (caps, 0); value = QString::fromUtf8(gst_structure_get_name (str)); + } media->addMissingCodecName(value); } diff --git a/src/3rdparty/phonon/phonon/factory.cpp b/src/3rdparty/phonon/phonon/factory.cpp index 881aca3..d5010e7 100644 --- a/src/3rdparty/phonon/phonon/factory.cpp +++ b/src/3rdparty/phonon/phonon/factory.cpp @@ -111,6 +111,7 @@ void Factory::setBackend(QObject *b) bool FactoryPrivate::createBackend() { +#ifndef QT_NO_LIBRARY Q_ASSERT(m_backendObject == 0); #ifndef QT_NO_PHONON_PLATFORMPLUGIN PlatformPlugin *f = globalFactory->platformPlugin(); @@ -186,6 +187,11 @@ bool FactoryPrivate::createBackend() SLOT(objectDescriptionChanged(ObjectDescriptionType))); return true; +#else //QT_NO_LIBRARY + pWarning() << Q_FUNC_INFO << "Trying to use Phonon with QT_NO_LIBRARY defined. " + "That is currently not supported"; + return false; +#endif } FactoryPrivate::FactoryPrivate() diff --git a/src/3rdparty/phonon/phonon/globalconfig.cpp b/src/3rdparty/phonon/phonon/globalconfig.cpp index d13e491..3718c6a 100644 --- a/src/3rdparty/phonon/phonon/globalconfig.cpp +++ b/src/3rdparty/phonon/phonon/globalconfig.cpp @@ -38,7 +38,10 @@ QT_BEGIN_NAMESPACE namespace Phonon { -GlobalConfig::GlobalConfig() : m_config(QLatin1String("kde.org"), QLatin1String("libphonon")) +GlobalConfig::GlobalConfig() +#ifndef QT_NO_SETTINGS + : m_config(QLatin1String("kde.org"), QLatin1String("libphonon")) +#endif //QT_NO_SETTINGS { } @@ -82,6 +85,7 @@ static void filter(ObjectDescriptionType type, BackendInterface *backendIface, Q } } +#ifndef QT_NO_PHONON_SETTINGSGROUP static QList listSortedByConfig(const QSettingsGroup &backendConfig, Phonon::Category category, QList &defaultList) { if (defaultList.size() <= 1) { @@ -126,7 +130,9 @@ static QList listSortedByConfig(const QSettingsGroup &backendConfig, Phonon return deviceList; } +#endif //QT_NO_PHONON_SETTINGSGROUP +#ifndef QT_NO_PHONON_SETTINGSGROUP QList GlobalConfig::audioOutputDeviceListFor(Phonon::Category category, int override) const { //The devices need to be stored independently for every backend @@ -172,7 +178,7 @@ QList GlobalConfig::audioOutputDeviceListFor(Phonon::Category category, int return listSortedByConfig(backendConfig, category, defaultList); } - +#endif //QT_NO_SETTINGSGROUPS int GlobalConfig::audioOutputDeviceFor(Phonon::Category category, int override) const { QList ret = audioOutputDeviceListFor(category, override); @@ -184,6 +190,7 @@ int GlobalConfig::audioOutputDeviceFor(Phonon::Category category, int override) #ifndef QT_NO_PHONON_AUDIOCAPTURE QList GlobalConfig::audioCaptureDeviceListFor(Phonon::Category category, int override) const { +#ifndef QT_NO_PHONON_SETTINGSGROUP //The devices need to be stored independently for every backend const QSettingsGroup backendConfig(&m_config, QLatin1String("AudioCaptureDevice")); // + Factory::identifier()); const QSettingsGroup generalGroup(&m_config, QLatin1String("General")); @@ -226,6 +233,9 @@ QList GlobalConfig::audioCaptureDeviceListFor(Phonon::Category category, in } return listSortedByConfig(backendConfig, category, defaultList); +#else //QT_NO_SETTINGSGROUP + return QList(); +#endif //QT_NO_SETTINGSGROUP } int GlobalConfig::audioCaptureDeviceFor(Phonon::Category category, int override) const diff --git a/src/3rdparty/phonon/phonon/globalconfig_p.h b/src/3rdparty/phonon/phonon/globalconfig_p.h index 023858f..034bce3 100644 --- a/src/3rdparty/phonon/phonon/globalconfig_p.h +++ b/src/3rdparty/phonon/phonon/globalconfig_p.h @@ -46,7 +46,9 @@ namespace Phonon AdvancedDevicesFromSettings = 2, HideUnavailableDevices = 4 }; +#ifndef QT_NO_PHONON_SETTINGSGROUP QList audioOutputDeviceListFor(Phonon::Category category, int override = AdvancedDevicesFromSettings) const; +#endif //QT_NO_PHONON_SETTINGSGROUP int audioOutputDeviceFor(Phonon::Category category, int override = AdvancedDevicesFromSettings) const; #ifndef QT_NO_PHONON_AUDIOCAPTURE @@ -55,7 +57,9 @@ namespace Phonon #endif //QT_NO_PHONON_AUDIOCAPTURE protected: +#ifndef QT_NO_SETTINGS QSettings m_config; +#endif //QT_NO_SETTINGS }; } // namespace Phonon diff --git a/src/3rdparty/phonon/phonon/qsettingsgroup_p.h b/src/3rdparty/phonon/phonon/qsettingsgroup_p.h index 95f6c9b..501fe37 100644 --- a/src/3rdparty/phonon/phonon/qsettingsgroup_p.h +++ b/src/3rdparty/phonon/phonon/qsettingsgroup_p.h @@ -27,6 +27,8 @@ #include #include +#ifndef QT_NO_PHONON_SETTINGSGROUP + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -87,5 +89,6 @@ class QSettingsGroup QT_END_NAMESPACE QT_END_HEADER +#endif //QT_NO_PHONON_SETTINGSGROUP #endif // PHONON_QSETTINGSGROUP_P_H -- cgit v0.12 From f73e3063649220f80b2d0ada3a7f087c32c0bfc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 21 Oct 2009 15:25:28 +0200 Subject: Fix dependencies in qfeatures Reviewed-by: Trust Me --- src/corelib/global/qfeatures.h | 110 ++++++++++++++++++++++----------------- src/corelib/global/qfeatures.txt | 41 ++++++++++----- 2 files changed, 89 insertions(+), 62 deletions(-) diff --git a/src/corelib/global/qfeatures.h b/src/corelib/global/qfeatures.h index c9dfabb..adc2743 100644 --- a/src/corelib/global/qfeatures.h +++ b/src/corelib/global/qfeatures.h @@ -148,9 +148,6 @@ // Phonon::ObjectDescriptionModel //#define QT_NO_PHONON_OBJECTDESCRIPTIONMODEL -// Phonon::PlatformPlugin -//#define QT_NO_PHONON_PLATFORMPLUGIN - // Phonon::VideoWidget //#define QT_NO_PHONON_VIDEO @@ -175,9 +172,6 @@ // Decoration //#define QT_NO_QWS_DECORATION_DEFAULT -// QWSInputMethod -//#define QT_NO_QWS_INPUTMETHODS - // Keyboard //#define QT_NO_QWS_KEYBOARD @@ -527,9 +521,9 @@ #define QT_NO_LIBRARY #endif -// Phonon::VolumeSlider -#if !defined(QT_NO_PHONON_VOLUMESLIDER) && (defined(QT_NO_SLIDER) || defined(QT_NO_ACTION)) -#define QT_NO_PHONON_VOLUMESLIDER +// Phonon::AbstractMediaStream +#if !defined(QT_NO_PHONON_SETTINGSGROUP) && (defined(QT_NO_SETTINGS)) +#define QT_NO_PHONON_SETTINGSGROUP #endif // QScrollArea @@ -537,6 +531,11 @@ #define QT_NO_SCROLLAREA #endif +// QWindowsVistaStyle +#if !defined(QT_NO_STYLE_WINDOWSVISTA) && (defined(QT_NO_STYLE_WINDOWSXP)) +#define QT_NO_STYLE_WINDOWSVISTA +#endif + // OdfWriter #if !defined(QT_NO_TEXTODFWRITER) && (defined(QT_NO_XMLSTREAMWRITER)) #define QT_NO_TEXTODFWRITER @@ -552,6 +551,11 @@ #define QT_NO_TRANSLATION_UTF8 #endif +// QUndoGroup +#if !defined(QT_NO_UNDOGROUP) && (defined(QT_NO_UNDOSTACK)) +#define QT_NO_UNDOGROUP +#endif + // Drag and drop #if !defined(QT_NO_DRAGANDDROP) && (defined(QT_NO_QWS_PROPERTIES) || defined(QT_NO_IMAGEFORMAT_XPM)) #define QT_NO_DRAGANDDROP @@ -562,11 +566,21 @@ #define QT_NO_GRAPHICSVIEW #endif +// QInputContext +#if !defined(QT_NO_IM) && (defined(QT_NO_LIBRARY)) +#define QT_NO_IM +#endif + // QMdiArea #if !defined(QT_NO_MDIAREA) && (defined(QT_NO_SCROLLAREA)) #define QT_NO_MDIAREA #endif +// Phonon::PlatformPlugin +#if !defined(QT_NO_PHONON_PLATFORMPLUGIN) && (defined(QT_NO_LIBRARY)) +#define QT_NO_PHONON_PLATFORMPLUGIN +#endif + // QPrinter #if !defined(QT_NO_PRINTER) && (defined(QT_NO_TEXTSTREAM) || defined(QT_NO_PICTURE) || defined(QT_NO_TEMPORARYFILE)) #define QT_NO_PRINTER @@ -602,11 +616,6 @@ #define QT_NO_STYLE_WINDOWSMOBILE #endif -// QWindowsVistaStyle -#if !defined(QT_NO_STYLE_WINDOWSVISTA) && (defined(QT_NO_STYLE_WINDOWS) || defined(QT_NO_STYLE_WINDOWSXP)) -#define QT_NO_STYLE_WINDOWSVISTA -#endif - // QtSvg module #if !defined(QT_NO_SVG) && (defined(QT_NO_XMLSTREAMREADER) || defined(QT_NO_CSSPARSER)) #define QT_NO_SVG @@ -617,14 +626,14 @@ #define QT_NO_TABBAR #endif -// QUndoGroup -#if !defined(QT_NO_UNDOGROUP) && (defined(QT_NO_UNDOCOMMAND) || defined(QT_NO_UNDOSTACK)) -#define QT_NO_UNDOGROUP +// QWhatsThis +#if !defined(QT_NO_WHATSTHIS) && (defined(QT_NO_TOOLBUTTON)) +#define QT_NO_WHATSTHIS #endif -// Accessibility -#if !defined(QT_NO_ACCESSIBILITY) && (defined(QT_NO_PROPERTIES) || defined(QT_NO_ACTION) || defined(QT_NO_MENU)) -#define QT_NO_ACCESSIBILITY +// QColorDialog +#if !defined(QT_NO_COLORDIALOG) && (defined(QT_NO_SPINBOX)) +#define QT_NO_COLORDIALOG #endif // The Model/View Framework @@ -632,6 +641,16 @@ #define QT_NO_ITEMVIEWS #endif +// Phonon::VolumeSlider +#if !defined(QT_NO_PHONON_VOLUMESLIDER) && (defined(QT_NO_SLIDER) || defined(QT_NO_TOOLBUTTON)) +#define QT_NO_PHONON_VOLUMESLIDER +#endif + +// QWSInputMethod +#if !defined(QT_NO_QWS_INPUTMETHODS) && (defined(QT_NO_IM)) +#define QT_NO_QWS_INPUTMETHODS +#endif + // Sound Server #if !defined(QT_NO_QWS_SOUNDSERVER) && (defined(QT_NO_SOUND) || defined(QT_NO_HOSTINFO) || defined(QT_NO_QWS_MULTIPROCESS)) #define QT_NO_QWS_SOUNDSERVER @@ -662,11 +681,6 @@ #define QT_NO_TEXTEDIT #endif -// QWhatsThis -#if !defined(QT_NO_WHATSTHIS) && (defined(QT_NO_TOOLBUTTON) || defined(QT_NO_ACTION)) -#define QT_NO_WHATSTHIS -#endif - // QDirModel #if !defined(QT_NO_DIRMODEL) && (defined(QT_NO_ITEMVIEWS)) #define QT_NO_DIRMODEL @@ -732,11 +746,6 @@ #define QT_NO_TREEVIEW #endif -// QColorDialog -#if !defined(QT_NO_COLORDIALOG) && (defined(QT_NO_LINEEDIT) || defined(QT_NO_VALIDATOR) || defined(QT_NO_SPINBOX)) -#define QT_NO_COLORDIALOG -#endif - // QColumnView #if !defined(QT_NO_COLUMNVIEW) && (defined(QT_NO_LISTVIEW)) #define QT_NO_COLUMNVIEW @@ -772,11 +781,21 @@ #define QT_NO_TABLEWIDGET #endif +// QToolBox +#if !defined(QT_NO_TOOLBOX) && (defined(QT_NO_TOOLBUTTON) || defined(QT_NO_SCROLLAREA)) +#define QT_NO_TOOLBOX +#endif + // QTreeWidget #if !defined(QT_NO_TREEWIDGET) && (defined(QT_NO_TREEVIEW)) #define QT_NO_TREEWIDGET #endif +// Accessibility +#if !defined(QT_NO_ACCESSIBILITY) && (defined(QT_NO_PROPERTIES) || defined(QT_NO_MENUBAR)) +#define QT_NO_ACCESSIBILITY +#endif + // Common UNIX Printing System #if !defined(QT_NO_CUPS) && (defined(QT_NO_PRINTER) || defined(QT_NO_LIBRARY)) #define QT_NO_CUPS @@ -787,11 +806,6 @@ #define QT_NO_TOOLBAR #endif -// QToolBox -#if !defined(QT_NO_TOOLBOX) && (defined(QT_NO_ICON) || defined(QT_NO_TOOLBUTTON) || defined(QT_NO_SCROLLAREA)) -#define QT_NO_TOOLBOX -#endif - // QDockwidget #if !defined(QT_NO_DOCKWIDGET) && (defined(QT_NO_RUBBERBAND) || defined(QT_NO_MAINWINDOW)) #define QT_NO_DOCKWIDGET @@ -808,10 +822,20 @@ #endif // QComboBox -#if !defined(QT_NO_COMBOBOX) && (defined(QT_NO_LINEEDIT) || defined(QT_NO_STANDARDITEMMODEL) || defined(QT_NO_LISTVIEW)) +#if !defined(QT_NO_COMBOBOX) && (defined(QT_NO_LINEEDIT) || defined(QT_NO_STANDARDITEMMODEL) || defined(QT_NO_LISTVIEW) || defined(QT_NO_ICON)) #define QT_NO_COMBOBOX #endif +// QPrintPreviewWidget +#if !defined(QT_NO_PRINTPREVIEWWIDGET) && (defined(QT_NO_GRAPHICSVIEW) || defined(QT_NO_PRINTER) || defined(QT_NO_MAINWINDOW)) +#define QT_NO_PRINTPREVIEWWIDGET +#endif + +// QWorkSpace +#if !defined(QT_NO_WORKSPACE) && (defined(QT_NO_SCROLLBAR) || defined(QT_NO_MAINWINDOW) || defined(QT_NO_MENUBAR)) +#define QT_NO_WORKSPACE +#endif + // QCalendarWidget #if !defined(QT_NO_CALENDARWIDGET) && (defined(QT_NO_TABLEVIEW) || defined(QT_NO_MENU) || defined(QT_NO_TEXTDATE) || defined(QT_NO_SPINBOX) || defined(QT_NO_TOOLBUTTON)) #define QT_NO_CALENDARWIDGET @@ -842,18 +866,8 @@ #define QT_NO_FONTDIALOG #endif -// QPrintPreviewWidget -#if !defined(QT_NO_PRINTPREVIEWWIDGET) && (defined(QT_NO_GRAPHICSVIEW) || defined(QT_NO_PRINTER) || defined(QT_NO_TOOLBAR) || defined(QT_NO_MAINWINDOW)) -#define QT_NO_PRINTPREVIEWWIDGET -#endif - -// QWorkSpace -#if !defined(QT_NO_WORKSPACE) && (defined(QT_NO_SCROLLBAR) || defined(QT_NO_RESIZEHANDLER) || defined(QT_NO_MENU) || defined(QT_NO_TOOLBUTTON) || defined(QT_NO_MAINWINDOW) || defined(QT_NO_TOOLBAR) || defined(QT_NO_MENUBAR)) -#define QT_NO_WORKSPACE -#endif - // QPrintDialog -#if !defined(QT_NO_PRINTDIALOG) && (defined(QT_NO_PRINTER) || defined(QT_NO_COMBOBOX) || defined(QT_NO_BUTTONGROUP) || defined(QT_NO_SPINBOX) || defined(QT_NO_TREEVIEW) || defined(QT_NO_STACKEDWIDGET) || defined(QT_NO_TABWIDGET)) +#if !defined(QT_NO_PRINTDIALOG) && (defined(QT_NO_PRINTER) || defined(QT_NO_COMBOBOX) || defined(QT_NO_BUTTONGROUP) || defined(QT_NO_SPINBOX) || defined(QT_NO_TREEVIEW) || defined(QT_NO_TABWIDGET)) #define QT_NO_PRINTDIALOG #endif @@ -863,7 +877,7 @@ #endif // QPrintPreviewDialog -#if !defined(QT_NO_PRINTPREVIEWDIALOG) && (defined(QT_NO_PRINTPREVIEWWIDGET) || defined(QT_NO_PRINTDIALOG) || defined(QT_NO_MAINWINDOW)) +#if !defined(QT_NO_PRINTPREVIEWDIALOG) && (defined(QT_NO_PRINTPREVIEWWIDGET) || defined(QT_NO_PRINTDIALOG)) #define QT_NO_PRINTPREVIEWDIALOG #endif diff --git a/src/corelib/global/qfeatures.txt b/src/corelib/global/qfeatures.txt index fb9181b..4b012d9 100644 --- a/src/corelib/global/qfeatures.txt +++ b/src/corelib/global/qfeatures.txt @@ -154,6 +154,12 @@ Requires: XMLSTREAM Name: QXmlStreamWriter SeeAlso: ??? +Feature: IM +Description: Inputmethods with QInputContext +Section: Kernel +Requires: LIBRARY +Name: QInputContext +SeeAlso: ??? # Data structures Feature: STL @@ -346,7 +352,7 @@ SeeAlso: ??? Feature: COMBOBOX Description: Supports comboboxes presenting a list of options to the user. Section: Widgets -Requires: LINEEDIT STANDARDITEMMODEL LISTVIEW +Requires: LINEEDIT STANDARDITEMMODEL LISTVIEW ICON Name: QComboBox SeeAlso: ??? @@ -374,7 +380,7 @@ SeeAlso: ??? Feature: TOOLBOX Description: Supports columns of tabbed widget items. Section: Widgets -Requires: ICON TOOLBUTTON SCROLLAREA +Requires: TOOLBUTTON SCROLLAREA Name: QToolBox SeeAlso: ??? @@ -410,7 +416,7 @@ SeeAlso: ??? Feature: WORKSPACE Description: Supports workspace windows, e.g. used in an MDI application. Section: Widgets -Requires: SCROLLBAR RESIZEHANDLER MENU TOOLBUTTON MAINWINDOW TOOLBAR MENUBAR +Requires: SCROLLBAR MAINWINDOW MENUBAR Name: QWorkSpace SeeAlso: ??? @@ -544,7 +550,7 @@ SeeAlso: ??? Feature: WHATSTHIS Description: Supports displaying "What's this" help. Section: Widgets -Requires: TOOLBUTTON ACTION +Requires: TOOLBUTTON Name: QWhatsThis SeeAlso: ??? @@ -574,7 +580,7 @@ Feature: PRINTPREVIEWWIDGET Description: Provides a widget for previewing page layouts for printer output. a date. Section: Widgets -Requires: GRAPHICSVIEW PRINTER TOOLBAR MAINWINDOW +Requires: GRAPHICSVIEW PRINTER MAINWINDOW Name: QPrintPreviewWidget SeeAlso: ??? @@ -591,7 +597,7 @@ SeeAlso: ??? Feature: COLORDIALOG Description: Supports a dialog widget for specifying colors. Section: Dialogs -Requires: LINEEDIT VALIDATOR SPINBOX +Requires: SPINBOX Name: QColorDialog SeeAlso: ??? @@ -612,14 +618,14 @@ SeeAlso: ??? Feature: PRINTDIALOG Description: Supports a dialog widget for specifying printer configuration. Section: Dialogs -Requires: PRINTER COMBOBOX BUTTONGROUP SPINBOX TREEVIEW STACKEDWIDGET TABWIDGET +Requires: PRINTER COMBOBOX BUTTONGROUP SPINBOX TREEVIEW TABWIDGET Name: QPrintDialog SeeAlso: ??? Feature: PRINTPREVIEWDIALOG Description: Provides a dialog for previewing and configuring page layouts for printer output. Section: Dialogs -Requires: PRINTPREVIEWWIDGET PRINTDIALOG MAINWINDOW +Requires: PRINTPREVIEWWIDGET PRINTDIALOG Name: QPrintPreviewDialog SeeAlso: ??? @@ -779,7 +785,7 @@ SeeAlso: ??? Feature: STYLE_WINDOWSVISTA Description: Supports a Microsoft WindowsVista-like look and feel. Section: Styles -Requires: STYLE_WINDOWS STYLE_WINDOWSXP +Requires: STYLE_WINDOWSXP Name: QWindowsVistaStyle SeeAlso: ??? @@ -1021,7 +1027,7 @@ SeeAlso: ??? Feature: QWS_INPUTMETHODS Description: Supports international input methods. Section: Internationalization -Requires: +Requires: IM Name: QWSInputMethod SeeAlso: ??? @@ -1139,7 +1145,7 @@ SeeAlso: ??? Feature: UNDOGROUP Description: Section: Utilities -Requires: UNDOCOMMAND UNDOSTACK +Requires: UNDOSTACK Name: QUndoGroup SeeAlso: ??? @@ -1153,7 +1159,7 @@ SeeAlso: ??? Feature: ACCESSIBILITY Description: Provides accessibility support. Section: Utilities -Requires: PROPERTIES ACTION MENU +Requires: PROPERTIES MENUBAR Name: Accessibility SeeAlso: ??? @@ -1359,7 +1365,7 @@ SeeAlso: ??? Feature: PHONON_PLATFORMPLUGIN Description: Support for platform plugin Section: Phonon -Requires: +Requires: LIBRARY Name: Phonon::PlatformPlugin SeeAlso: ??? @@ -1424,7 +1430,7 @@ SeeAlso: ??? Feature: PHONON_VOLUMESLIDER Description: Support for the Volume Slider class Section: Phonon -Requires: SLIDER ACTION +Requires: SLIDER TOOLBUTTON Name: Phonon::VolumeSlider SeeAlso: ??? @@ -1441,3 +1447,10 @@ Section: Phonon Requires: Name: Phonon::AbstractMediaStream SeeAlso: ??? + +Feature: PHONON_SETTINGSGROUP +Description: Phonon settingsgroup +Section: Phonon +Requires: SETTINGS +Name: Phonon::AbstractMediaStream +SeeAlso: ??? -- cgit v0.12 From fccbc9b94d843f4c55834ee75127cd6219b4839a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 21 Oct 2009 15:26:06 +0200 Subject: Fix LIBRARY and ICON However, compiling with QT_NO_ICON will still not work :( Reviewed-by: tom --- src/gui/graphicsview/qgraphicsitem.cpp | 2 ++ src/gui/graphicsview/qgraphicsscene.cpp | 2 ++ src/gui/image/qicon.cpp | 2 ++ src/gui/image/qicon_p.h | 3 ++- src/gui/image/qiconloader.cpp | 9 +++++++-- src/gui/image/qiconloader_p.h | 3 +++ src/gui/kernel/qapplication.cpp | 5 ++++- src/gui/kernel/qwidget.cpp | 12 ++++++++++++ src/gui/kernel/qwidget_qws.cpp | 3 ++- src/gui/painting/qprinterinfo_unix.cpp | 2 ++ src/gui/text/qtextcontrol.cpp | 2 ++ src/gui/widgets/qcombobox.h | 1 - src/gui/widgets/qlinecontrol.cpp | 3 ++- src/network/access/qnetworkaccessdebugpipebackend.cpp | 4 ++-- src/plugins/gfxdrivers/qvfb/main.cpp | 2 ++ src/plugins/gfxdrivers/transformed/main.cpp | 3 ++- src/plugins/gfxdrivers/vnc/main.cpp | 3 +++ 17 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 2685b86..f7cea17 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -9670,12 +9670,14 @@ bool QGraphicsTextItem::sceneEvent(QEvent *event) // Reset the focus widget's input context, regardless // of how this item gained or lost focus. if (QWidget *fw = qApp->focusWidget()) { +#ifndef QT_NO_IM if (QInputContext *qic = fw->inputContext()) { if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut) qic->reset(); else qic->update(); } +#endif //QT_NO_IM } break; default: diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index c459d21..1e4fe6f 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -691,6 +691,7 @@ void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item, focusItem = 0; sendEvent(lastFocusItem, &event); +#ifndef QT_NO_IM if (lastFocusItem && (lastFocusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) { // Reset any visible preedit text @@ -706,6 +707,7 @@ void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item, views.at(i)->inputContext()->reset(); } } +#endif //QT_NO_IM } if (item) { diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index e0779a0..cff9cd2 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -66,6 +66,7 @@ #include "private/qkde_p.h" #endif +#ifndef QT_NO_ICON QT_BEGIN_NAMESPACE /*! @@ -1217,3 +1218,4 @@ QSize QIcon::pixmapSize(Size which) */ QT_END_NAMESPACE +#endif //QT_NO_ICON diff --git a/src/gui/image/qicon_p.h b/src/gui/image/qicon_p.h index fc96a65..43a59a6 100644 --- a/src/gui/image/qicon_p.h +++ b/src/gui/image/qicon_p.h @@ -60,6 +60,7 @@ #include #include +#ifndef QT_NO_ICON QT_BEGIN_NAMESPACE class QIconPrivate @@ -134,5 +135,5 @@ private: }; QT_END_NAMESPACE - +#endif //QT_NO_ICON #endif // QICON_P_H diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp index 46c5431..234f271 100644 --- a/src/gui/image/qiconloader.cpp +++ b/src/gui/image/qiconloader.cpp @@ -38,7 +38,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ - +#ifndef QT_NO_ICON #include #include @@ -92,11 +92,13 @@ QIconLoader::QIconLoader() : if (m_systemTheme.isEmpty()) m_systemTheme = fallbackTheme(); +#ifndef QT_NO_LIBRARY QFactoryLoader iconFactoryLoader(QIconEngineFactoryInterfaceV2_iid, QLatin1String("/iconengines"), Qt::CaseInsensitive); if (iconFactoryLoader.keys().contains(QLatin1String("svg"))) m_supportsSvg = true; +#endif //QT_NO_LIBRARY } QIconLoader *QIconLoader::instance() @@ -160,7 +162,7 @@ QIconTheme::QIconTheme(const QString &themeName) break; } } - +#ifndef QT_NO_SETTINGS if (themeIndex.exists()) { const QSettings indexReader(themeIndex.fileName(), QSettings::IniFormat); QStringListIterator keyIterator(indexReader.allKeys()); @@ -213,6 +215,7 @@ QIconTheme::QIconTheme(const QString &themeName) if (!m_parents.contains(QLatin1String("hicolor"))) m_parents.append(QLatin1String("hicolor")); } +#endif //QT_NO_SETTINGS } QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName, @@ -546,3 +549,5 @@ void QIconLoaderEngine::virtual_hook(int id, void *data) } QT_END_NAMESPACE + +#endif //QT_NO_ICON diff --git a/src/gui/image/qiconloader_p.h b/src/gui/image/qiconloader_p.h index b152d46..2a330d3 100644 --- a/src/gui/image/qiconloader_p.h +++ b/src/gui/image/qiconloader_p.h @@ -42,6 +42,7 @@ #ifndef QDESKTOPICON_P_H #define QDESKTOPICON_P_H +#ifndef QT_NO_ICON // // W A R N I N G // ------------- @@ -185,3 +186,5 @@ private: QT_END_NAMESPACE #endif // QDESKTOPICON_P_H + +#endif //QT_NO_ICON diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 85b055e..30d3c7f 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -2081,7 +2081,7 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason) } QWidget *prev = focus_widget; focus_widget = focus; - +#ifndef QT_NO_IM if (prev && ((reason != Qt::PopupFocusReason && reason != Qt::MenuBarFocusReason && prev->testAttribute(Qt::WA_InputMethodEnabled)) // Do reset the input context, in case the new focus widget won't accept keyboard input @@ -2094,6 +2094,7 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason) qic->setFocusWidget(0); } } +#endif //QT_NO_IM if(focus_widget) focus_widget->d_func()->setFocus_sys(); @@ -2125,12 +2126,14 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason) QApplication::sendEvent(that->style(), &out); } if(focus && QApplicationPrivate::focus_widget == focus) { +#ifndef QT_NO_IM if (focus->testAttribute(Qt::WA_InputMethodEnabled)) { QInputContext *qic = focus->inputContext(); if (qic && focus->testAttribute(Qt::WA_WState_Created) && focus->isEnabled()) qic->setFocusWidget(focus); } +#endif //QT_NO_IM QFocusEvent in(QEvent::FocusIn, reason); QPointer that = focus; QApplication::sendEvent(focus, &in); diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 5fa9a92..916ae8b 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -3072,6 +3072,7 @@ void QWidgetPrivate::setEnabled_helper(bool enable) #if defined(Q_WS_MAC) setEnabled_helper_sys(enable); #endif +#ifndef QT_NO_IM if (q->testAttribute(Qt::WA_InputMethodEnabled) && q->hasFocus()) { QInputContext *qic = inputContext(); if (enable) { @@ -3081,6 +3082,7 @@ void QWidgetPrivate::setEnabled_helper(bool enable) qic->setFocusWidget(0); } } +#endif //QT_NO_IM QEvent e(QEvent::EnabledChange); QApplication::sendEvent(q, &e); #ifdef QT3_SUPPORT @@ -8950,11 +8952,16 @@ QVariant QWidget::inputMethodQuery(Qt::InputMethodQuery query) const Qt::InputMethodHints QWidget::inputMethodHints() const { Q_D(const QWidget); +#ifndef QT_NO_IM return d->imHints; +#else //QT_NO_IM + return 0; +#endif //QT_NO_IM } void QWidget::setInputMethodHints(Qt::InputMethodHints hints) { +#ifndef QT_NO_IM Q_D(QWidget); d->imHints = hints; // Optimisation to update input context only it has already been created. @@ -8963,6 +8970,7 @@ void QWidget::setInputMethodHints(Qt::InputMethodHints hints) if (ic) ic->update(); } +#endif //QT_NO_IM } @@ -10294,6 +10302,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) QApplication::sendEvent(this, &e); break; } case Qt::WA_NativeWindow: { +#ifndef QT_NO_IM QInputContext *ic = 0; if (on && !internalWinId() && testAttribute(Qt::WA_InputMethodEnabled) && hasFocus()) { ic = d->inputContext(); @@ -10306,6 +10315,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) d->createWinId(); if (ic && isEnabled()) ic->setFocusWidget(this); +#endif //QT_NO_IM break; } case Qt::WA_PaintOnScreen: @@ -10335,6 +10345,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) #endif break; case Qt::WA_InputMethodEnabled: { +#ifndef QT_NO_IM QInputContext *ic = d->ic; if (!ic && (!on || hasFocus())) ic = d->inputContext(); @@ -10346,6 +10357,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) ic->setFocusWidget(0); } } +#endif //QT_NO_IM break; } case Qt::WA_WindowPropagation: diff --git a/src/gui/kernel/qwidget_qws.cpp b/src/gui/kernel/qwidget_qws.cpp index 0f46016..e299c6e 100644 --- a/src/gui/kernel/qwidget_qws.cpp +++ b/src/gui/kernel/qwidget_qws.cpp @@ -280,7 +280,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows) QApplicationPrivate::leaveModal(this); else if ((windowType() == Qt::Popup)) qApp->d_func()->closePopup(this); - +#ifndef QT_NO_IM if (d->ic) { delete d->ic; d->ic =0; @@ -291,6 +291,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows) if (qic) qic->widgetDestroyed(this); } +#endif //QT_NO_IM if ((windowType() == Qt::Desktop)) { } else { diff --git a/src/gui/painting/qprinterinfo_unix.cpp b/src/gui/painting/qprinterinfo_unix.cpp index 7e2946a..6684ff7 100644 --- a/src/gui/painting/qprinterinfo_unix.cpp +++ b/src/gui/painting/qprinterinfo_unix.cpp @@ -421,6 +421,7 @@ int qt_pd_foreach(int /*status */, char * /*key */, int /*keyLen */, int qt_retrieveNisPrinters(QList *printers) { +#ifndef QT_NO_LIBRARY typedef int (*WildCast)(int, char *, int, char *, int, char *); char printersConfByname[] = "printers.conf.byname"; char *domain; @@ -444,6 +445,7 @@ int qt_retrieveNisPrinters(QList *printers) if (!err) return Success; } +#endif //QT_NO_LIBRARY return Unavail; } diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index ee8b751..3f6545c 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -1619,9 +1619,11 @@ void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF if (cursor.position() != oldCursorPos) emit q->cursorPositionChanged(); _q_updateCurrentCharFormatAndSelection(); +#ifndef QT_NO_IM if (QInputContext *ic = inputContext()) { ic->update(); } +#endif //QT_NO_IM } else { //emit q->visibilityRequest(QRectF(mousePos, QSizeF(1, 1))); if (cursor.position() != oldCursorPos) diff --git a/src/gui/widgets/qcombobox.h b/src/gui/widgets/qcombobox.h index 6a85096..462636c 100644 --- a/src/gui/widgets/qcombobox.h +++ b/src/gui/widgets/qcombobox.h @@ -52,7 +52,6 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE QT_MODULE(Gui) - #ifndef QT_NO_COMBOBOX class QAbstractItemView; diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index 7f9ff82..8f17e98 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -447,8 +447,9 @@ void QLineControl::processInputMethodEvent(QInputMethodEvent *event) cursorPositionChanged = true; } } - +#ifndef QT_NO_IM setPreeditArea(m_cursor, event->preeditString()); +#endif //QT_NO_IM m_preeditCursor = event->preeditString().length(); m_hideCursor = false; QList formats; diff --git a/src/network/access/qnetworkaccessdebugpipebackend.cpp b/src/network/access/qnetworkaccessdebugpipebackend.cpp index b4af5b6..4f7f15c 100644 --- a/src/network/access/qnetworkaccessdebugpipebackend.cpp +++ b/src/network/access/qnetworkaccessdebugpipebackend.cpp @@ -229,7 +229,7 @@ void QNetworkAccessDebugPipeBackend::possiblyFinish() void QNetworkAccessDebugPipeBackend::closeDownstreamChannel() { - qWarning() << "QNetworkAccessDebugPipeBackend::closeDownstreamChannel()" << operation(); + qWarning("QNetworkAccessDebugPipeBackend::closeDownstreamChannel()",operation());; //if (operation() == QNetworkAccessManager::GetOperation) // socket.disconnectFromHost(); } @@ -237,7 +237,7 @@ void QNetworkAccessDebugPipeBackend::closeDownstreamChannel() void QNetworkAccessDebugPipeBackend::socketError() { - qWarning() << "QNetworkAccessDebugPipeBackend::socketError()" << socket.error(); + qWarning("QNetworkAccessDebugPipeBackend::socketError()", socket.error()); QNetworkReply::NetworkError code; switch (socket.error()) { case QAbstractSocket::RemoteHostClosedError: diff --git a/src/plugins/gfxdrivers/qvfb/main.cpp b/src/plugins/gfxdrivers/qvfb/main.cpp index bcaecab..beca37e 100644 --- a/src/plugins/gfxdrivers/qvfb/main.cpp +++ b/src/plugins/gfxdrivers/qvfb/main.cpp @@ -43,6 +43,7 @@ #include #include +#ifndef QT_NO_LIBRARY QT_BEGIN_NAMESPACE class ScreenVfbDriver : public QScreenDriverPlugin @@ -78,3 +79,4 @@ Q_EXPORT_STATIC_PLUGIN(ScreenVfbDriver) Q_EXPORT_PLUGIN2(qscreenvfb, ScreenVfbDriver) QT_END_NAMESPACE +#endif //QT_NO_LIBRARY diff --git a/src/plugins/gfxdrivers/transformed/main.cpp b/src/plugins/gfxdrivers/transformed/main.cpp index 859fd49..a9ff97d 100644 --- a/src/plugins/gfxdrivers/transformed/main.cpp +++ b/src/plugins/gfxdrivers/transformed/main.cpp @@ -42,7 +42,7 @@ #include #include #include - +#ifndef QT_NO_LIBRARY QT_BEGIN_NAMESPACE class GfxTransformedDriver : public QScreenDriverPlugin @@ -81,3 +81,4 @@ Q_EXPORT_STATIC_PLUGIN(GfxTransformedDriver) Q_EXPORT_PLUGIN2(qgfxtransformed, GfxTransformedDriver) QT_END_NAMESPACE +#endif //QT_NO_LIBRARY diff --git a/src/plugins/gfxdrivers/vnc/main.cpp b/src/plugins/gfxdrivers/vnc/main.cpp index 7d91ff5..58c8c25 100644 --- a/src/plugins/gfxdrivers/vnc/main.cpp +++ b/src/plugins/gfxdrivers/vnc/main.cpp @@ -43,6 +43,7 @@ #include #include +#ifndef QT_NO_LIBRARY QT_BEGIN_NAMESPACE class GfxVncDriver : public QScreenDriverPlugin @@ -81,3 +82,5 @@ Q_EXPORT_STATIC_PLUGIN(GfxVncDriver) Q_EXPORT_PLUGIN2(qgfxvnc, GfxVncDriver) QT_END_NAMESPACE + +#endif //QT_NO_LIBRARY -- cgit v0.12 From a45a8e33b72a4a86ae269acabc5e95ed8452cda9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 22 Oct 2009 11:32:20 +0200 Subject: Fix QT_NO_PHONON_VIDEO Reviewed-by: Jens Bache-Wiig --- src/3rdparty/phonon/gstreamer/abstractrenderer.cpp | 3 ++- src/3rdparty/phonon/gstreamer/abstractrenderer.h | 3 ++- src/3rdparty/phonon/gstreamer/backend.cpp | 7 +++---- src/3rdparty/phonon/gstreamer/devicemanager.cpp | 2 ++ src/3rdparty/phonon/gstreamer/videowidget.cpp | 2 ++ src/3rdparty/phonon/gstreamer/videowidget.h | 3 ++- src/3rdparty/phonon/gstreamer/widgetrenderer.cpp | 2 ++ src/3rdparty/phonon/gstreamer/widgetrenderer.h | 3 ++- 8 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/3rdparty/phonon/gstreamer/abstractrenderer.cpp b/src/3rdparty/phonon/gstreamer/abstractrenderer.cpp index 924b611..5d88d10 100644 --- a/src/3rdparty/phonon/gstreamer/abstractrenderer.cpp +++ b/src/3rdparty/phonon/gstreamer/abstractrenderer.cpp @@ -17,6 +17,7 @@ #include "abstractrenderer.h" +#ifndef QT_NO_PHONON_VIDEO QT_BEGIN_NAMESPACE namespace Phonon @@ -52,5 +53,5 @@ void AbstractRenderer::movieSizeChanged(const QSize &size) } //namespace Phonon::Gstreamer QT_END_NAMESPACE - +#endif //QT_NO_PHONON_VIDEO diff --git a/src/3rdparty/phonon/gstreamer/abstractrenderer.h b/src/3rdparty/phonon/gstreamer/abstractrenderer.h index 140413d..10a2822 100644 --- a/src/3rdparty/phonon/gstreamer/abstractrenderer.h +++ b/src/3rdparty/phonon/gstreamer/abstractrenderer.h @@ -23,6 +23,7 @@ #include "medianode.h" #include +#ifndef QT_NO_PHONON_VIDEO QT_BEGIN_NAMESPACE class QString; @@ -58,5 +59,5 @@ protected: } //namespace Phonon::Gstreamer QT_END_NAMESPACE - +#endif //QT_NO_PHONON_VIDEO #endif // Phonon_GSTREAMER_ABSTRACTRENDERER_H diff --git a/src/3rdparty/phonon/gstreamer/backend.cpp b/src/3rdparty/phonon/gstreamer/backend.cpp index 647bb6f..e1ffd1f 100644 --- a/src/3rdparty/phonon/gstreamer/backend.cpp +++ b/src/3rdparty/phonon/gstreamer/backend.cpp @@ -126,6 +126,7 @@ QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const logMessage("createObject() : AudioDataOutput not implemented"); break; +#ifndef QT_NO_PHONON_VIDEO case VideoDataOutputClass: logMessage("createObject() : VideoDataOutput not implemented"); break; @@ -134,12 +135,10 @@ QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const QWidget *widget = qobject_cast(parent); return new VideoWidget(this, widget); } - - case VolumeFaderEffectClass: +#endif //QT_NO_PHONON_VIDEO #ifndef QT_NO_PHONON_VOLUMEFADEREFFECT + case VolumeFaderEffectClass: return new VolumeFaderEffect(this, parent); -#else - return 0; #endif //QT_NO_PHONON_VOLUMEFADEREFFECT case VisualizationClass: //Fall through diff --git a/src/3rdparty/phonon/gstreamer/devicemanager.cpp b/src/3rdparty/phonon/gstreamer/devicemanager.cpp index 86463c1..60e860f 100644 --- a/src/3rdparty/phonon/gstreamer/devicemanager.cpp +++ b/src/3rdparty/phonon/gstreamer/devicemanager.cpp @@ -246,6 +246,7 @@ GstElement *DeviceManager::createAudioSink(Category category) return sink; } +#ifndef QT_NO_PHONON_VIDEO AbstractRenderer *DeviceManager::createVideoRenderer(VideoWidget *parent) { #if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES) @@ -268,6 +269,7 @@ AbstractRenderer *DeviceManager::createVideoRenderer(VideoWidget *parent) #endif return new WidgetRenderer(parent); } +#endif //QT_NO_PHONON_VIDEO /* * Returns a positive device id or -1 if device diff --git a/src/3rdparty/phonon/gstreamer/videowidget.cpp b/src/3rdparty/phonon/gstreamer/videowidget.cpp index efc750a..e1f0ec9 100644 --- a/src/3rdparty/phonon/gstreamer/videowidget.cpp +++ b/src/3rdparty/phonon/gstreamer/videowidget.cpp @@ -33,6 +33,7 @@ #include "widgetrenderer.h" #include "x11renderer.h" +#ifndef QT_NO_PHONON_VIDEO QT_BEGIN_NAMESPACE namespace Phonon @@ -383,5 +384,6 @@ void VideoWidget::mediaNodeEvent(const MediaNodeEvent *event) } //namespace Phonon::Gstreamer QT_END_NAMESPACE +#endif //QT_NO_PHONON_VIDEO #include "moc_videowidget.cpp" diff --git a/src/3rdparty/phonon/gstreamer/videowidget.h b/src/3rdparty/phonon/gstreamer/videowidget.h index a0ebe5f..dc0754d 100644 --- a/src/3rdparty/phonon/gstreamer/videowidget.h +++ b/src/3rdparty/phonon/gstreamer/videowidget.h @@ -28,6 +28,7 @@ #include +#ifndef QT_NO_PHONON_VIDEO QT_BEGIN_NAMESPACE class QString; @@ -102,5 +103,5 @@ private: } //namespace Phonon::Gstreamer QT_END_NAMESPACE - +#endif //QT_NO_PHONON_VIDEO #endif // Phonon_GSTREAMER_VIDEOWIDGET_H diff --git a/src/3rdparty/phonon/gstreamer/widgetrenderer.cpp b/src/3rdparty/phonon/gstreamer/widgetrenderer.cpp index d4a411f..423af9d 100644 --- a/src/3rdparty/phonon/gstreamer/widgetrenderer.cpp +++ b/src/3rdparty/phonon/gstreamer/widgetrenderer.cpp @@ -32,6 +32,7 @@ # define GL_TEXTURE2 0x84C2 #endif +#ifndef QT_NO_PHONON_VIDEO QT_BEGIN_NAMESPACE static void frameRendered() @@ -148,3 +149,4 @@ bool WidgetRenderer::eventFilter(QEvent * event) } //namespace Phonon::Gstreamer QT_END_NAMESPACE +#endif //QT_NO_PHONON_VIDEO diff --git a/src/3rdparty/phonon/gstreamer/widgetrenderer.h b/src/3rdparty/phonon/gstreamer/widgetrenderer.h index ff64fa7..03ee9c0 100644 --- a/src/3rdparty/phonon/gstreamer/widgetrenderer.h +++ b/src/3rdparty/phonon/gstreamer/widgetrenderer.h @@ -26,6 +26,7 @@ #include #endif +#ifndef QT_NO_PHONON_VIDEO QT_BEGIN_NAMESPACE class QString; @@ -59,5 +60,5 @@ private: } //namespace Phonon::Gstreamer QT_END_NAMESPACE - +#endif //QT_NO_PHONON_VIDEO #endif // Phonon_GSTREAMER_WIDGETRENDERER_H -- cgit v0.12 From 433d3d130ac1b542f12574566c176f065bab29d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 22 Oct 2009 13:46:32 +0200 Subject: Remove ICON from QFeature Reviewed-by: Trust Me --- src/corelib/global/qconfig-local.h | 3 + src/corelib/global/qfeatures.h | 109 ++++++++++++++++++------------------- src/corelib/global/qfeatures.txt | 13 +---- 3 files changed, 58 insertions(+), 67 deletions(-) create mode 100644 src/corelib/global/qconfig-local.h diff --git a/src/corelib/global/qconfig-local.h b/src/corelib/global/qconfig-local.h new file mode 100644 index 0000000..90db873 --- /dev/null +++ b/src/corelib/global/qconfig-local.h @@ -0,0 +1,3 @@ +#ifndef QT_NO_SCROLLAREA +# define QT_NO_SCROLLAREA +#endif diff --git a/src/corelib/global/qfeatures.h b/src/corelib/global/qfeatures.h index adc2743..e4fd67a 100644 --- a/src/corelib/global/qfeatures.h +++ b/src/corelib/global/qfeatures.h @@ -82,9 +82,6 @@ // QGroupBox //#define QT_NO_GROUPBOX -// QIcon -//#define QT_NO_ICON - // QImageIOPlugin //#define QT_NO_IMAGEFORMATPLUGIN @@ -256,6 +253,9 @@ // QSystemSemaphore //#define QT_NO_SYSTEMSEMAPHORE +// QSystemTrayIcon +//#define QT_NO_SYSTEMTRAYICON + // QTabletEvent //#define QT_NO_TABLETEVENT @@ -466,9 +466,9 @@ #define QT_NO_SXE #endif -// QSystemTrayIcon -#if !defined(QT_NO_SYSTEMTRAYICON) && (defined(QT_NO_ICON)) -#define QT_NO_SYSTEMTRAYICON +// QToolButton +#if !defined(QT_NO_TOOLBUTTON) && (defined(QT_NO_ACTION)) +#define QT_NO_TOOLBUTTON #endif // QUndoStack @@ -536,16 +536,16 @@ #define QT_NO_STYLE_WINDOWSVISTA #endif +// QTabBar +#if !defined(QT_NO_TABBAR) && (defined(QT_NO_TOOLBUTTON)) +#define QT_NO_TABBAR +#endif + // OdfWriter #if !defined(QT_NO_TEXTODFWRITER) && (defined(QT_NO_XMLSTREAMWRITER)) #define QT_NO_TEXTODFWRITER #endif -// QToolButton -#if !defined(QT_NO_TOOLBUTTON) && (defined(QT_NO_ICON) || defined(QT_NO_ACTION)) -#define QT_NO_TOOLBUTTON -#endif - // Translation (UTF-8 representation) #if !defined(QT_NO_TRANSLATION_UTF8) && (defined(QT_NO_TRANSLATION) || defined(QT_NO_TEXTCODEC)) #define QT_NO_TRANSLATION_UTF8 @@ -556,6 +556,11 @@ #define QT_NO_UNDOGROUP #endif +// QWhatsThis +#if !defined(QT_NO_WHATSTHIS) && (defined(QT_NO_TOOLBUTTON)) +#define QT_NO_WHATSTHIS +#endif + // Drag and drop #if !defined(QT_NO_DRAGANDDROP) && (defined(QT_NO_QWS_PROPERTIES) || defined(QT_NO_IMAGEFORMAT_XPM)) #define QT_NO_DRAGANDDROP @@ -581,6 +586,11 @@ #define QT_NO_PHONON_PLATFORMPLUGIN #endif +// Phonon::VolumeSlider +#if !defined(QT_NO_PHONON_VOLUMESLIDER) && (defined(QT_NO_SLIDER) || defined(QT_NO_TOOLBUTTON)) +#define QT_NO_PHONON_VOLUMESLIDER +#endif + // QPrinter #if !defined(QT_NO_PRINTER) && (defined(QT_NO_TEXTSTREAM) || defined(QT_NO_PICTURE) || defined(QT_NO_TEMPORARYFILE)) #define QT_NO_PRINTER @@ -621,14 +631,9 @@ #define QT_NO_SVG #endif -// QTabBar -#if !defined(QT_NO_TABBAR) && (defined(QT_NO_TOOLBUTTON)) -#define QT_NO_TABBAR -#endif - -// QWhatsThis -#if !defined(QT_NO_WHATSTHIS) && (defined(QT_NO_TOOLBUTTON)) -#define QT_NO_WHATSTHIS +// Q3TabDialog +#if !defined(QT_NO_TABDIALOG) && (defined(QT_NO_TABBAR)) +#define QT_NO_TABDIALOG #endif // QColorDialog @@ -641,9 +646,9 @@ #define QT_NO_ITEMVIEWS #endif -// Phonon::VolumeSlider -#if !defined(QT_NO_PHONON_VOLUMESLIDER) && (defined(QT_NO_SLIDER) || defined(QT_NO_TOOLBUTTON)) -#define QT_NO_PHONON_VOLUMESLIDER +// QMenuBar +#if !defined(QT_NO_MENUBAR) && (defined(QT_NO_MENU) || defined(QT_NO_TOOLBUTTON)) +#define QT_NO_MENUBAR #endif // QWSInputMethod @@ -666,9 +671,9 @@ #define QT_NO_SVGRENDERER #endif -// Q3TabDialog -#if !defined(QT_NO_TABDIALOG) && (defined(QT_NO_TABBAR)) -#define QT_NO_TABDIALOG +// QTabWidget +#if !defined(QT_NO_TABWIDGET) && (defined(QT_NO_TABBAR) || defined(QT_NO_STACKEDWIDGET)) +#define QT_NO_TABWIDGET #endif // QTextCodecPlugin @@ -696,9 +701,9 @@ #define QT_NO_LISTVIEW #endif -// QMenuBar -#if !defined(QT_NO_MENUBAR) && (defined(QT_NO_MENU) || defined(QT_NO_TOOLBUTTON)) -#define QT_NO_MENUBAR +// QMainWindow +#if !defined(QT_NO_MAINWINDOW) && (defined(QT_NO_MENU) || defined(QT_NO_RESIZEHANDLER) || defined(QT_NO_TOOLBUTTON)) +#define QT_NO_MAINWINDOW #endif // QAbstractProxyModel @@ -731,21 +736,26 @@ #define QT_NO_TABLEVIEW #endif -// QTabWidget -#if !defined(QT_NO_TABWIDGET) && (defined(QT_NO_TABBAR) || defined(QT_NO_STACKEDWIDGET)) -#define QT_NO_TABWIDGET -#endif - // QTextBrowser #if !defined(QT_NO_TEXTBROWSER) && (defined(QT_NO_TEXTEDIT)) #define QT_NO_TEXTBROWSER #endif +// QToolBox +#if !defined(QT_NO_TOOLBOX) && (defined(QT_NO_TOOLBUTTON) || defined(QT_NO_SCROLLAREA)) +#define QT_NO_TOOLBOX +#endif + // QTreeView #if !defined(QT_NO_TREEVIEW) && (defined(QT_NO_ITEMVIEWS)) #define QT_NO_TREEVIEW #endif +// Accessibility +#if !defined(QT_NO_ACCESSIBILITY) && (defined(QT_NO_PROPERTIES) || defined(QT_NO_MENUBAR)) +#define QT_NO_ACCESSIBILITY +#endif + // QColumnView #if !defined(QT_NO_COLUMNVIEW) && (defined(QT_NO_LISTVIEW)) #define QT_NO_COLUMNVIEW @@ -766,11 +776,6 @@ #define QT_NO_LISTWIDGET #endif -// QMainWindow -#if !defined(QT_NO_MAINWINDOW) && (defined(QT_NO_MENU) || defined(QT_NO_RESIZEHANDLER) || defined(QT_NO_TOOLBUTTON)) -#define QT_NO_MAINWINDOW -#endif - // QSortFilterProxyModel #if !defined(QT_NO_SORTFILTERPROXYMODEL) && (defined(QT_NO_PROXYMODEL)) #define QT_NO_SORTFILTERPROXYMODEL @@ -781,9 +786,9 @@ #define QT_NO_TABLEWIDGET #endif -// QToolBox -#if !defined(QT_NO_TOOLBOX) && (defined(QT_NO_TOOLBUTTON) || defined(QT_NO_SCROLLAREA)) -#define QT_NO_TOOLBOX +// QToolBar +#if !defined(QT_NO_TOOLBAR) && (defined(QT_NO_MAINWINDOW)) +#define QT_NO_TOOLBAR #endif // QTreeWidget @@ -791,21 +796,11 @@ #define QT_NO_TREEWIDGET #endif -// Accessibility -#if !defined(QT_NO_ACCESSIBILITY) && (defined(QT_NO_PROPERTIES) || defined(QT_NO_MENUBAR)) -#define QT_NO_ACCESSIBILITY -#endif - // Common UNIX Printing System #if !defined(QT_NO_CUPS) && (defined(QT_NO_PRINTER) || defined(QT_NO_LIBRARY)) #define QT_NO_CUPS #endif -// QToolBar -#if !defined(QT_NO_TOOLBAR) && (defined(QT_NO_MAINWINDOW)) -#define QT_NO_TOOLBAR -#endif - // QDockwidget #if !defined(QT_NO_DOCKWIDGET) && (defined(QT_NO_RUBBERBAND) || defined(QT_NO_MAINWINDOW)) #define QT_NO_DOCKWIDGET @@ -822,20 +817,20 @@ #endif // QComboBox -#if !defined(QT_NO_COMBOBOX) && (defined(QT_NO_LINEEDIT) || defined(QT_NO_STANDARDITEMMODEL) || defined(QT_NO_LISTVIEW) || defined(QT_NO_ICON)) +#if !defined(QT_NO_COMBOBOX) && (defined(QT_NO_LINEEDIT) || defined(QT_NO_STANDARDITEMMODEL) || defined(QT_NO_LISTVIEW)) #define QT_NO_COMBOBOX #endif -// QPrintPreviewWidget -#if !defined(QT_NO_PRINTPREVIEWWIDGET) && (defined(QT_NO_GRAPHICSVIEW) || defined(QT_NO_PRINTER) || defined(QT_NO_MAINWINDOW)) -#define QT_NO_PRINTPREVIEWWIDGET -#endif - // QWorkSpace #if !defined(QT_NO_WORKSPACE) && (defined(QT_NO_SCROLLBAR) || defined(QT_NO_MAINWINDOW) || defined(QT_NO_MENUBAR)) #define QT_NO_WORKSPACE #endif +// QPrintPreviewWidget +#if !defined(QT_NO_PRINTPREVIEWWIDGET) && (defined(QT_NO_GRAPHICSVIEW) || defined(QT_NO_PRINTER) || defined(QT_NO_MAINWINDOW)) +#define QT_NO_PRINTPREVIEWWIDGET +#endif + // QCalendarWidget #if !defined(QT_NO_CALENDARWIDGET) && (defined(QT_NO_TABLEVIEW) || defined(QT_NO_MENU) || defined(QT_NO_TEXTDATE) || defined(QT_NO_SPINBOX) || defined(QT_NO_TOOLBUTTON)) #define QT_NO_CALENDARWIDGET diff --git a/src/corelib/global/qfeatures.txt b/src/corelib/global/qfeatures.txt index 4b012d9..0bee94a 100644 --- a/src/corelib/global/qfeatures.txt +++ b/src/corelib/global/qfeatures.txt @@ -352,7 +352,7 @@ SeeAlso: ??? Feature: COMBOBOX Description: Supports comboboxes presenting a list of options to the user. Section: Widgets -Requires: LINEEDIT STANDARDITEMMODEL LISTVIEW ICON +Requires: LINEEDIT STANDARDITEMMODEL LISTVIEW Name: QComboBox SeeAlso: ??? @@ -366,7 +366,7 @@ SeeAlso: ??? Feature: TOOLBUTTON Description: Supports quick-access buttons to commands and options. Section: Widgets -Requires: ICON ACTION +Requires: ACTION Name: QToolButton SeeAlso: ??? @@ -826,13 +826,6 @@ Requires: Name: QImageIOPlugin SeeAlso: ??? -Feature: ICON -Description: Supports scalable icons in different modes and states. -Section: Images -Requires: -Name: QIcon -SeeAlso: ??? - Feature: MOVIE Description: Supports animated images. Section: Images @@ -1124,7 +1117,7 @@ SeeAlso: ??? Feature: SYSTEMTRAYICON Description: Provides an icon for an application in the system tray. Section: Utilities -Requires: ICON +Requires: Name: QSystemTrayIcon SeeAlso: ??? -- cgit v0.12 From 38908792600e7cd471fece1de71e2ad13cbb0866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 22 Oct 2009 13:48:23 +0200 Subject: Fix SCROLLAREA by fixing missing QT_NO_GRAPHICSVIEW dependencies Reviewed-by: tom --- src/gui/graphicsview/qgraphicsanchorlayout.cpp | 3 ++- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 3 ++- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 3 ++- src/gui/graphicsview/qgraphicstransform.cpp | 3 ++- src/gui/graphicsview/qgraphicstransform.h | 2 ++ src/gui/graphicsview/qgraphicstransform_p.h | 3 ++- 6 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp index e21cd99..2bed776 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp @@ -123,7 +123,7 @@ */ #include "qgraphicsanchorlayout_p.h" - +#ifndef QT_NO_GRAPHICSVIEW QT_BEGIN_NAMESPACE QGraphicsAnchor::QGraphicsAnchor(QGraphicsAnchorLayout *parentLayout) @@ -535,3 +535,4 @@ QSizeF QGraphicsAnchorLayout::sizeHint(Qt::SizeHint which, const QSizeF &constra } QT_END_NAMESPACE +#endif //QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 8c8c303..c424be5 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -48,7 +48,7 @@ #endif #include "qgraphicsanchorlayout_p.h" - +#ifndef QT_NO_GRAPHICSVIEW QT_BEGIN_NAMESPACE @@ -2635,3 +2635,4 @@ void QGraphicsAnchorLayoutPrivate::dumpGraph(const QString &name) #endif QT_END_NAMESPACE +#endif //QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index d45c004..9513ddf 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -60,7 +60,7 @@ #include "qgraphicsanchorlayout.h" #include "qgraph_p.h" #include "qsimplex_p.h" - +#ifndef QT_NO_GRAPHICSVIEW QT_BEGIN_NAMESPACE /* @@ -529,5 +529,6 @@ public: }; QT_END_NAMESPACE +#endif //QT_NO_GRAPHICSVIEW #endif diff --git a/src/gui/graphicsview/qgraphicstransform.cpp b/src/gui/graphicsview/qgraphicstransform.cpp index e2a3f08..83bc9e1 100644 --- a/src/gui/graphicsview/qgraphicstransform.cpp +++ b/src/gui/graphicsview/qgraphicstransform.cpp @@ -93,8 +93,8 @@ #include #include +#ifndef QT_NO_GRAPHICSVIEW QT_BEGIN_NAMESPACE - void QGraphicsTransformPrivate::setItem(QGraphicsItem *i) { if (item == i) @@ -565,3 +565,4 @@ void QGraphicsRotation::applyTo(QMatrix4x4 *matrix) const #include "moc_qgraphicstransform.cpp" QT_END_NAMESPACE +#endif //QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicstransform.h b/src/gui/graphicsview/qgraphicstransform.h index 58075aa..58e3077 100644 --- a/src/gui/graphicsview/qgraphicstransform.h +++ b/src/gui/graphicsview/qgraphicstransform.h @@ -47,6 +47,7 @@ #include #include +#ifndef QT_NO_GRAPHICSVIEW QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -150,5 +151,6 @@ private: QT_END_NAMESPACE QT_END_HEADER +#endif //QT_NO_GRAPHICSVIEW #endif // QFXTRANSFORM_H diff --git a/src/gui/graphicsview/qgraphicstransform_p.h b/src/gui/graphicsview/qgraphicstransform_p.h index 9e708b2..ddf99bb 100644 --- a/src/gui/graphicsview/qgraphicstransform_p.h +++ b/src/gui/graphicsview/qgraphicstransform_p.h @@ -54,7 +54,7 @@ // #include "private/qobject_p.h" - +#ifndef QT_NO_GRAPHICSVIEW QT_BEGIN_NAMESPACE class QGraphicsItem; @@ -73,5 +73,6 @@ public: }; QT_END_NAMESPACE +#endif //QT_NO_GRAPHCISVIEW #endif // QGRAPHICSTRANSFORM_P_H -- cgit v0.12 From 9d4d1814eb7e130cd3ef75393a7957216dc14d2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Mon, 26 Oct 2009 12:27:20 +0100 Subject: Fix THREAD and TOOLBAR Reviewed-by: tom Squash me with Fix THREAD and TOOLBAR a6e785b4ff9ec9cd48 --- src/corelib/global/qconfig-local.h | 4 +-- src/corelib/global/qfeatures.h | 29 ++++++++++-------- src/corelib/global/qfeatures.txt | 15 ++++++--- src/corelib/thread/qmutexpool.cpp | 20 ++++++------ src/corelib/thread/qmutexpool_p.h | 17 +++++++++-- src/corelib/thread/qthread.cpp | 24 +++++++++------ src/corelib/thread/qthread_p.h | 62 ++++++++++++++++++-------------------- src/gui/dialogs/qfscompleter_p.h | 4 +-- 8 files changed, 101 insertions(+), 74 deletions(-) diff --git a/src/corelib/global/qconfig-local.h b/src/corelib/global/qconfig-local.h index 90db873..b9a5090 100644 --- a/src/corelib/global/qconfig-local.h +++ b/src/corelib/global/qconfig-local.h @@ -1,3 +1,3 @@ -#ifndef QT_NO_SCROLLAREA -# define QT_NO_SCROLLAREA +#ifndef QT_NO_TOOLBAR +# define QT_NO_TOOLBAR #endif diff --git a/src/corelib/global/qfeatures.h b/src/corelib/global/qfeatures.h index e4fd67a..455fead 100644 --- a/src/corelib/global/qfeatures.h +++ b/src/corelib/global/qfeatures.h @@ -301,11 +301,6 @@ // //#define QT_NO_XMLSTREAM -// Animation -#if !defined(QT_NO_ANIMATION) && (defined(QT_NO_PROPERTIES)) -#define QT_NO_ANIMATION -#endif - // QButtonGroup #if !defined(QT_NO_BUTTONGROUP) && (defined(QT_NO_GROUPBOX)) #define QT_NO_BUTTONGROUP @@ -496,6 +491,11 @@ #define QT_NO_XMLSTREAMWRITER #endif +// Animation +#if !defined(QT_NO_ANIMATION) && (defined(QT_NO_PROPERTIES) || defined(QT_NO_THREAD)) +#define QT_NO_ANIMATION +#endif + // Context menu #if !defined(QT_NO_CONTEXTMENU) && (defined(QT_NO_MENU)) #define QT_NO_CONTEXTMENU @@ -686,11 +686,6 @@ #define QT_NO_TEXTEDIT #endif -// QDirModel -#if !defined(QT_NO_DIRMODEL) && (defined(QT_NO_ITEMVIEWS)) -#define QT_NO_DIRMODEL -#endif - // QErrorMessage #if !defined(QT_NO_ERRORMESSAGE) && (defined(QT_NO_TEXTEDIT)) #define QT_NO_ERRORMESSAGE @@ -806,6 +801,11 @@ #define QT_NO_DOCKWIDGET #endif +// QDirModel +#if !defined(QT_NO_DIRMODEL) && (defined(QT_NO_ITEMVIEWS) || defined(QT_NO_FILESYSTEMMODEL)) +#define QT_NO_DIRMODEL +#endif + // QUndoView #if !defined(QT_NO_UNDOVIEW) && (defined(QT_NO_UNDOSTACK) || defined(QT_NO_LISTVIEW)) #define QT_NO_UNDOVIEW @@ -816,6 +816,11 @@ #define QT_NO_GRAPHICSSVGITEM #endif +// QCompleter +#if !defined(QT_NO_FSCOMPLETER) && (defined(QT_NO_FILESYSTEMMODEL) || defined(QT_NO_COMPLETER)) +#define QT_NO_FSCOMPLETER +#endif + // QComboBox #if !defined(QT_NO_COMBOBOX) && (defined(QT_NO_LINEEDIT) || defined(QT_NO_STANDARDITEMMODEL) || defined(QT_NO_LISTVIEW)) #define QT_NO_COMBOBOX @@ -867,12 +872,12 @@ #endif // QFileDialog -#if !defined(QT_NO_FILEDIALOG) && (defined(QT_NO_DIRMODEL) || defined(QT_NO_TREEVIEW) || defined(QT_NO_COMBOBOX) || defined(QT_NO_TOOLBUTTON) || defined(QT_NO_BUTTONGROUP) || defined(QT_NO_TOOLTIP) || defined(QT_NO_SPLITTER) || defined(QT_NO_STACKEDWIDGET) || defined(QT_NO_FILESYSTEMMODEL)) +#if !defined(QT_NO_FILEDIALOG) && (defined(QT_NO_DIRMODEL) || defined(QT_NO_TREEVIEW) || defined(QT_NO_COMBOBOX) || defined(QT_NO_TOOLBUTTON) || defined(QT_NO_BUTTONGROUP) || defined(QT_NO_TOOLTIP) || defined(QT_NO_SPLITTER) || defined(QT_NO_STACKEDWIDGET)) #define QT_NO_FILEDIALOG #endif // QPrintPreviewDialog -#if !defined(QT_NO_PRINTPREVIEWDIALOG) && (defined(QT_NO_PRINTPREVIEWWIDGET) || defined(QT_NO_PRINTDIALOG)) +#if !defined(QT_NO_PRINTPREVIEWDIALOG) && (defined(QT_NO_PRINTPREVIEWWIDGET) || defined(QT_NO_PRINTDIALOG) || defined(QT_NO_TOOLBAR)) #define QT_NO_PRINTPREVIEWDIALOG #endif diff --git a/src/corelib/global/qfeatures.txt b/src/corelib/global/qfeatures.txt index 0bee94a..f2b5c20 100644 --- a/src/corelib/global/qfeatures.txt +++ b/src/corelib/global/qfeatures.txt @@ -604,7 +604,7 @@ SeeAlso: ??? Feature: FILEDIALOG Description: Supports a dialog widget for selecting files or directories. Section: Dialogs -Requires: DIRMODEL TREEVIEW COMBOBOX TOOLBUTTON BUTTONGROUP TOOLTIP SPLITTER STACKEDWIDGET FILESYSTEMMODEL +Requires: DIRMODEL TREEVIEW COMBOBOX TOOLBUTTON BUTTONGROUP TOOLTIP SPLITTER STACKEDWIDGET Name: QFileDialog SeeAlso: ??? @@ -625,7 +625,7 @@ SeeAlso: ??? Feature: PRINTPREVIEWDIALOG Description: Provides a dialog for previewing and configuring page layouts for printer output. Section: Dialogs -Requires: PRINTPREVIEWWIDGET PRINTDIALOG +Requires: PRINTPREVIEWWIDGET PRINTDIALOG TOOLBAR Name: QPrintPreviewDialog SeeAlso: ??? @@ -677,7 +677,7 @@ SeeAlso: ??? Feature: DIRMODEL Description: Supports a data model for the local filesystem. Section: ItemViews -Requires: ITEMVIEWS +Requires: ITEMVIEWS FILESYSTEMMODEL Name: QDirModel SeeAlso: ??? @@ -1107,6 +1107,13 @@ Requires: PROXYMODEL Name: QCompleter SeeAlso: ??? +Feature: FSCOMPLETER +Description: Provides completions based on an item model. +Section: Utilities +Requires: FILESYSTEMMODEL COMPLETER +Name: QCompleter +SeeAlso: ??? + Feature: DESKTOPSERVICES Description: Provides methods for accessing common desktop services. Section: Utilities @@ -1159,7 +1166,7 @@ SeeAlso: ??? Feature: ANIMATION Description: Provides a framework for animations. Section: Utilities -Requires: PROPERTIES +Requires: PROPERTIES THREAD Name: Animation SeeAlso: ??? diff --git a/src/corelib/thread/qmutexpool.cpp b/src/corelib/thread/qmutexpool.cpp index c5c1882..9f37239 100644 --- a/src/corelib/thread/qmutexpool.cpp +++ b/src/corelib/thread/qmutexpool.cpp @@ -42,7 +42,6 @@ #include "qatomic.h" #include "qmutexpool_p.h" -#ifndef QT_NO_THREAD QT_BEGIN_NAMESPACE @@ -50,6 +49,7 @@ QT_BEGIN_NAMESPACE // use QMutexpool::instance() in new clode. Q_CORE_EXPORT QMutexPool *qt_global_mutexpool = 0; Q_GLOBAL_STATIC_WITH_ARGS(QMutexPool, globalMutexPool, (QMutex::Recursive)) +#ifndef QT_NO_THREAD /*! \class QMutexPool @@ -114,15 +114,6 @@ QMutexPool::~QMutexPool() mutexes[index] = 0; } } - -/*! - Returns the global QMutexPool instance. -*/ -QMutexPool *QMutexPool::instance() -{ - return globalMutexPool(); -} - /*! Returns a QMutex from the pool. QMutexPool uses the value \a address to determine which mutex is returned from the pool. @@ -152,7 +143,14 @@ QMutex *QMutexPool::globalInstanceGet(const void *address) return 0; return globalInstance->get(address); } +#endif // QT_NO_THREAD +/*! + Returns the global QMutexPool instance. +*/ +QMutexPool *QMutexPool::instance() +{ + return globalMutexPool(); +} QT_END_NAMESPACE -#endif // QT_NO_THREAD diff --git a/src/corelib/thread/qmutexpool_p.h b/src/corelib/thread/qmutexpool_p.h index 3e1bad0..c26711b 100644 --- a/src/corelib/thread/qmutexpool_p.h +++ b/src/corelib/thread/qmutexpool_p.h @@ -57,9 +57,9 @@ #include "QtCore/qmutex.h" #include "QtCore/qvarlengtharray.h" -#ifndef QT_NO_THREAD QT_BEGIN_NAMESPACE +#ifndef QT_NO_THREAD class Q_CORE_EXPORT QMutexPool { @@ -75,11 +75,24 @@ private: QVarLengthArray, 131> mutexes; QMutex::RecursionMode recursionMode; }; +#else //QT_NO_THREAD +Q_GLOBAL_STATIC(QMutex, globalMutex) +class Q_CORE_EXPORT QMutexPool +{ +public: + explicit QMutexPool(QMutex::RecursionMode recursionMode = QMutex::NonRecursive, int size = 131){} + ~QMutexPool(){} + + QMutex *get(const void *address){return globalMutex();} + static QMutexPool *instance(); + static QMutex *globalInstanceGet(const void *address){return globalMutex();} +}; + +#endif // QT_NO_THREAD extern Q_CORE_EXPORT QMutexPool *qt_global_mutexpool; QT_END_NAMESPACE -#endif // QT_NO_THREAD #endif // QMUTEXPOOL_P_H diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index ac191fe..cf57d33 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -727,6 +727,16 @@ QThread *QThread::currentThread() return QThreadData::current()->thread; } +/*! \internal + */ +QThread::QThread(QThreadPrivate &dd, QObject *parent) + : QObject(dd, parent) +{ + Q_D(QThread); + // fprintf(stderr, "QThreadData %p taken from private data for thread %p\n", d->data, this); + d->data->thread = this; +} + QThreadData* QThreadData::current() { static QThreadData *data = 0; // reinterpret_cast(pthread_getspecific(current_thread_data_key)); @@ -738,17 +748,13 @@ QThreadData* QThreadData::current() } return data; } - -/*! \internal - */ -QThread::QThread(QThreadPrivate &dd, QObject *parent) - : QObject(dd, parent) +#endif // QT_NO_THREAD +QThreadData* QThreadData::get2(QThread *thread) { - Q_D(QThread); - // fprintf(stderr, "QThreadData %p taken from private data for thread %p\n", d->data, this); - d->data->thread = this; + Q_ASSERT_X(thread != 0, "QThread", "internal error"); + return thread->d_func()->data; } -#endif // QT_NO_THREAD + QT_END_NAMESPACE diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index af68434..8c3acdb 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -111,6 +111,36 @@ public: { } }; +class QThreadData +{ + QAtomicInt _ref; + +public: + QThreadData(int initialRefCount = 1); + ~QThreadData(); + + static QThreadData *current(); + static QThreadData *get2(QThread *thread); + + void ref(); + void deref(); + + QThread *thread; + bool quitNow; + int loopLevel; + QAbstractEventDispatcher *eventDispatcher; + QStack eventLoops; + QPostEventList postEventList; + bool canWait; + QMap tls; + + QMutex mutex; + +# ifdef Q_OS_SYMBIAN + RThread symbian_thread_handle; +# endif +}; + #ifndef QT_NO_THREAD class QThreadPrivate : public QObjectPrivate { @@ -179,38 +209,6 @@ public: #endif // QT_NO_THREAD -class QThreadData -{ - QAtomicInt _ref; - -public: - QThreadData(int initialRefCount = 1); - ~QThreadData(); - - static QThreadData *current(); - static QThreadData *get2(QThread *thread) - { Q_ASSERT_X(thread != 0, "QThread", "internal error"); return thread->d_func()->data; } - - - void ref(); - void deref(); - - QThread *thread; - bool quitNow; - int loopLevel; - QAbstractEventDispatcher *eventDispatcher; - QStack eventLoops; - QPostEventList postEventList; - bool canWait; - QMap tls; - - QMutex mutex; - -# ifdef Q_OS_SYMBIAN - RThread symbian_thread_handle; -# endif -}; - // thread wrapper for the main() thread class QAdoptedThread : public QThread { diff --git a/src/gui/dialogs/qfscompleter_p.h b/src/gui/dialogs/qfscompleter_p.h index cb1b427..1edab2d 100644 --- a/src/gui/dialogs/qfscompleter_p.h +++ b/src/gui/dialogs/qfscompleter_p.h @@ -56,7 +56,7 @@ #include "qcompleter.h" #include QT_BEGIN_NAMESPACE -#ifndef QT_NO_COMPLETER +#ifndef QT_NO_FSCOMPLETER /*! QCompleter that can deal with QFileSystemModel @@ -76,7 +76,7 @@ public: QAbstractProxyModel *proxyModel; QFileSystemModel *sourceModel; }; -#endif // QT_NO_COMPLETER +#endif // QT_NO_FSCOMPLETER QT_END_NAMESPACE #endif // QFSCOMPLETOR_P_H -- cgit v0.12 From a733f087467c5f8361a7765a38e45037549c019f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Tue, 27 Oct 2009 08:34:39 +0100 Subject: Fix FSCOMPLETER Reviewed-by: tom --- src/gui/dialogs/qfiledialog.cpp | 12 ++++++------ src/gui/dialogs/qfiledialog_p.h | 4 ++-- src/gui/dialogs/qprintdialog_unix.cpp | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index eab842f..c6b4a77 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -777,7 +777,7 @@ void QFileDialog::setDirectory(const QString &directory) QModelIndex root = d->model->setRootPath(newDirectory); d->qFileDialogUi->newFolderButton->setEnabled(d->model->flags(root) & Qt::ItemIsDropEnabled); if (root != d->rootIndex()) { -#ifndef QT_NO_COMPLETER +#ifndef QT_NO_FSCOMPLETER if (directory.endsWith(QLatin1Char('/'))) d->completer->setCompletionPrefix(newDirectory); else @@ -2177,12 +2177,12 @@ void QFileDialogPrivate::createWidgets() #ifndef QT_NO_SHORTCUT qFileDialogUi->fileNameLabel->setBuddy(qFileDialogUi->fileNameEdit); #endif -#ifndef QT_NO_COMPLETER +#ifndef QT_NO_FSCOMPLETER completer = new QFSCompleter(model, q); qFileDialogUi->fileNameEdit->setCompleter(completer); QObject::connect(qFileDialogUi->fileNameEdit, SIGNAL(textChanged(QString)), q, SLOT(_q_autoCompleteFileName(QString))); -#endif // QT_NO_COMPLETER +#endif // QT_NO_FSCOMPLETER QObject::connect(qFileDialogUi->fileNameEdit, SIGNAL(textChanged(QString)), q, SLOT(_q_updateOkButton())); @@ -2302,7 +2302,7 @@ void QFileDialog::setProxyModel(QAbstractProxyModel *proxyModel) proxyModel->setSourceModel(d->model); d->qFileDialogUi->listView->setModel(d->proxyModel); d->qFileDialogUi->treeView->setModel(d->proxyModel); -#ifndef QT_NO_COMPLETER +#ifndef QT_NO_FSCOMPLETER d->completer->setModel(d->proxyModel); d->completer->proxyModel = d->proxyModel; #endif @@ -2312,7 +2312,7 @@ void QFileDialog::setProxyModel(QAbstractProxyModel *proxyModel) d->proxyModel = 0; d->qFileDialogUi->listView->setModel(d->model); d->qFileDialogUi->treeView->setModel(d->model); -#ifndef QT_NO_COMPLETER +#ifndef QT_NO_FSCOMPLETER d->completer->setModel(d->model); d->completer->sourceModel = d->model; d->completer->proxyModel = 0; @@ -3218,7 +3218,7 @@ void QFileDialogLineEdit::keyPressEvent(QKeyEvent *e) } } -#ifndef QT_NO_COMPLETER +#ifndef QT_NO_FSCOMPLETER QString QFSCompleter::pathFromIndex(const QModelIndex &index) const { diff --git a/src/gui/dialogs/qfiledialog_p.h b/src/gui/dialogs/qfiledialog_p.h index 32cd397..0e447a3 100644 --- a/src/gui/dialogs/qfiledialog_p.h +++ b/src/gui/dialogs/qfiledialog_p.h @@ -234,9 +234,9 @@ public: QStringList watching; QFileSystemModel *model; -#ifndef QT_NO_COMPLETER +#ifndef QT_NO_FSCOMPLETER QFSCompleter *completer; -#endif //QT_NO_COMPLETER +#endif //QT_NO_FSCOMPLETER QFileDialog::FileMode fileMode; QFileDialog::AcceptMode acceptMode; diff --git a/src/gui/dialogs/qprintdialog_unix.cpp b/src/gui/dialogs/qprintdialog_unix.cpp index 7daa273..6fc270d 100644 --- a/src/gui/dialogs/qprintdialog_unix.cpp +++ b/src/gui/dialogs/qprintdialog_unix.cpp @@ -696,7 +696,7 @@ QUnixPrintWidgetPrivate::QUnixPrintWidgetPrivate(QUnixPrintWidget *p) #ifndef QT_NO_FILESYSTEMMODEL QFileSystemModel *fsm = new QFileSystemModel(widget.filename); fsm->setRootPath(QDir::homePath()); -#if !defined(QT_NO_COMPLETER) && !defined(QT_NO_FILEDIALOG) +#if !defined(QT_NO_FSCOMPLETER) && !defined(QT_NO_FILEDIALOG) widget.filename->setCompleter(new QFSCompleter(fsm, widget.filename)); #endif #endif -- cgit v0.12 From c0c9940b371215eea294ae83ed6586a6414957ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Tue, 27 Oct 2009 10:53:17 +0100 Subject: Fix TEXTCODEC Reviewed-by: tom --- src/gui/kernel/qclipboard.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/kernel/qclipboard.cpp b/src/gui/kernel/qclipboard.cpp index 5ed4dc9..e43f8b5 100644 --- a/src/gui/kernel/qclipboard.cpp +++ b/src/gui/kernel/qclipboard.cpp @@ -296,12 +296,16 @@ QString QClipboard::text(QString &subtype, Mode mode) const const QByteArray rawData = data->data(QLatin1String("text/") + subtype); +#ifndef QT_NO_TEXTCODEC QTextCodec* codec = QTextCodec::codecForMib(106); // utf-8 is default if (subtype == QLatin1String("html")) codec = QTextCodec::codecForHtml(rawData, codec); else codec = QTextCodec::codecForUtfText(rawData, codec); return codec->toUnicode(rawData); +#else //QT_NO_TEXTCODEC + return rawData; +#endif //QT_NO_TEXTCODEC } /*! -- cgit v0.12 From d0aa2b8422eea07823caef639a0970b8f2a1fde0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Tue, 27 Oct 2009 10:55:28 +0100 Subject: Fix PROXYMODEL Reviewed-by: Trust Me --- src/corelib/global/qconfig-local.h | 3 --- src/corelib/global/qfeatures.h | 2 +- src/corelib/global/qfeatures.txt | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) delete mode 100644 src/corelib/global/qconfig-local.h diff --git a/src/corelib/global/qconfig-local.h b/src/corelib/global/qconfig-local.h deleted file mode 100644 index b9a5090..0000000 --- a/src/corelib/global/qconfig-local.h +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef QT_NO_TOOLBAR -# define QT_NO_TOOLBAR -#endif diff --git a/src/corelib/global/qfeatures.h b/src/corelib/global/qfeatures.h index 455fead..3996180 100644 --- a/src/corelib/global/qfeatures.h +++ b/src/corelib/global/qfeatures.h @@ -872,7 +872,7 @@ #endif // QFileDialog -#if !defined(QT_NO_FILEDIALOG) && (defined(QT_NO_DIRMODEL) || defined(QT_NO_TREEVIEW) || defined(QT_NO_COMBOBOX) || defined(QT_NO_TOOLBUTTON) || defined(QT_NO_BUTTONGROUP) || defined(QT_NO_TOOLTIP) || defined(QT_NO_SPLITTER) || defined(QT_NO_STACKEDWIDGET)) +#if !defined(QT_NO_FILEDIALOG) && (defined(QT_NO_DIRMODEL) || defined(QT_NO_TREEVIEW) || defined(QT_NO_COMBOBOX) || defined(QT_NO_TOOLBUTTON) || defined(QT_NO_BUTTONGROUP) || defined(QT_NO_TOOLTIP) || defined(QT_NO_SPLITTER) || defined(QT_NO_STACKEDWIDGET) || defined(QT_NO_PROXYMODEL)) #define QT_NO_FILEDIALOG #endif diff --git a/src/corelib/global/qfeatures.txt b/src/corelib/global/qfeatures.txt index f2b5c20..543056f 100644 --- a/src/corelib/global/qfeatures.txt +++ b/src/corelib/global/qfeatures.txt @@ -604,7 +604,7 @@ SeeAlso: ??? Feature: FILEDIALOG Description: Supports a dialog widget for selecting files or directories. Section: Dialogs -Requires: DIRMODEL TREEVIEW COMBOBOX TOOLBUTTON BUTTONGROUP TOOLTIP SPLITTER STACKEDWIDGET +Requires: DIRMODEL TREEVIEW COMBOBOX TOOLBUTTON BUTTONGROUP TOOLTIP SPLITTER STACKEDWIDGET PROXYMODEL Name: QFileDialog SeeAlso: ??? -- cgit v0.12 From 3117574558b2aeb6e3e3e90ff8e44f4a2e74cf6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Tue, 27 Oct 2009 14:30:25 +0100 Subject: Fix SHAREDMEMORY Reviewed-by: tom --- src/corelib/kernel/qsharedmemory_unix.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/corelib/kernel/qsharedmemory_unix.cpp b/src/corelib/kernel/qsharedmemory_unix.cpp index 1165fb1..40b9f04 100644 --- a/src/corelib/kernel/qsharedmemory_unix.cpp +++ b/src/corelib/kernel/qsharedmemory_unix.cpp @@ -49,8 +49,6 @@ #include -#ifndef QT_NO_SHAREDMEMORY - #include #include #include @@ -61,6 +59,7 @@ #include "private/qcore_unix_p.h" +#ifndef QT_NO_SHAREDMEMORY QT_BEGIN_NAMESPACE QSharedMemoryPrivate::QSharedMemoryPrivate() -- cgit v0.12 From eec8980202f05737b0ef0b8db410675e0df5bafe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Tue, 27 Oct 2009 14:30:56 +0100 Subject: FIX TABBAR Reviewed-by: tom --- src/gui/widgets/qdockarealayout.cpp | 14 ++++++++++---- src/gui/widgets/qdockarealayout_p.h | 8 ++++++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index 5a0a9d4..ec35c4f 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -1556,9 +1556,10 @@ void QDockAreaLayoutInfo::apply(bool animate) } } } - +#ifndef QT_NO_TABBAR if (sep == 1) updateSeparatorWidgets(); +#endif //QT_NO_TABBAR } static void paintSep(QPainter *p, QWidget *w, const QRect &r, Qt::Orientation o, bool mouse_over) @@ -2008,13 +2009,14 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList updateTabBar(); setCurrentTabId(tabId(item_list.at(index))); } -#endif if (!testing && sep == 1) updateSeparatorWidgets(); +#endif return true; } +#ifndef QT_NO_TABBAR void QDockAreaLayoutInfo::updateSeparatorWidgets() const { if (tabbed) { @@ -2065,6 +2067,7 @@ void QDockAreaLayoutInfo::updateSeparatorWidgets() const separatorWidgets.resize(j); Q_ASSERT(separatorWidgets.size() == j); } +#endif //QT_NO_TABBAR #ifndef QT_NO_TABBAR void QDockAreaLayoutInfo::updateTabBar() const @@ -3073,9 +3076,10 @@ void QDockAreaLayout::apply(bool animate) widgetAnimator.animate(centralWidgetItem->widget(), centralWidgetRect, animate); } - +#ifndef QT_NO_TABBAR if (sep == 1) updateSeparatorWidgets(); +#endif //QT_NO_TABBAR } void QDockAreaLayout::paintSeparators(QPainter *p, QWidget *widget, @@ -3153,6 +3157,7 @@ int QDockAreaLayout::separatorMove(const QList &separator, const QPoint &or return delta; } +#ifndef QT_NO_TABBAR // Sets the correct positions for the seperator widgets // Allocates new sepearator widgets with getSeparatorWidget void QDockAreaLayout::updateSeparatorWidgets() const @@ -3186,6 +3191,7 @@ void QDockAreaLayout::updateSeparatorWidgets() const separatorWidgets.resize(j); } +#endif //QT_NO_TABBAR QLayoutItem *QDockAreaLayout::itemAt(int *x, int index) const { @@ -3238,7 +3244,6 @@ QSet QDockAreaLayout::usedTabBars() const } return result; } -#endif // Returns the set of all used separator widgets QSet QDockAreaLayout::usedSeparatorWidgets() const @@ -3253,6 +3258,7 @@ QSet QDockAreaLayout::usedSeparatorWidgets() const } return result; } +#endif QRect QDockAreaLayout::gapRect(const QList &path) const { diff --git a/src/gui/widgets/qdockarealayout_p.h b/src/gui/widgets/qdockarealayout_p.h index 99a9dbb..5692850 100644 --- a/src/gui/widgets/qdockarealayout_p.h +++ b/src/gui/widgets/qdockarealayout_p.h @@ -196,9 +196,10 @@ public: QRect rect; QMainWindow *mainWindow; QList item_list; - +#ifndef QT_NO_TABBAR void updateSeparatorWidgets() const; QSet usedSeparatorWidgets() const; +#endif //QT_NO_TABBAR #ifndef QT_NO_TABBAR quintptr currentTabId() const; @@ -278,7 +279,9 @@ public: const QPoint &mouse) const; QRegion separatorRegion() const; int separatorMove(const QList &separator, const QPoint &origin, const QPoint &dest); +#ifndef QT_NO_TABBAR void updateSeparatorWidgets() const; +#endif //QT_NO_TABBAR QLayoutItem *itemAt(int *x, int index) const; QLayoutItem *takeAt(int *x, int index); @@ -292,9 +295,10 @@ public: QRect gapRect(const QList &path) const; void keepSize(QDockWidget *w); - +#ifndef QT_NO_TABBAR QSet usedTabBars() const; QSet usedSeparatorWidgets() const; +#endif //QT_NO_TABBAR }; QT_END_NAMESPACE -- cgit v0.12 From 578b113f3dcceec0a88599494ad686fbc8cbfbb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 28 Oct 2009 08:42:10 +0100 Subject: Fix QT_NO_MAINWINDOW Reviewed-by: tom --- src/gui/widgets/qwidgetanimator.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/widgets/qwidgetanimator.cpp b/src/gui/widgets/qwidgetanimator.cpp index f440961..bdd3c75 100644 --- a/src/gui/widgets/qwidgetanimator.cpp +++ b/src/gui/widgets/qwidgetanimator.cpp @@ -105,7 +105,9 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo #else //we do it in one shot widget->setGeometry(final_geometry); +#ifndef QT_NO_MAINWINDOW m_mainWindowLayout->animationFinished(widget); +#endif //QT_NO_MAINWINDOW #endif //QT_NO_ANIMATION } -- cgit v0.12 From 23b6599324bc62666d4303ca108ed372e8d7c490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 28 Oct 2009 09:23:45 +0100 Subject: Remove QT_NO_ICON from mimimal Reviewed-by: Trust Me --- src/corelib/global/qconfig-minimal.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/corelib/global/qconfig-minimal.h b/src/corelib/global/qconfig-minimal.h index 3d9539e..9cc3057 100644 --- a/src/corelib/global/qconfig-minimal.h +++ b/src/corelib/global/qconfig-minimal.h @@ -123,9 +123,6 @@ #endif /* Images */ -#ifndef QT_NO_ICON -# define QT_NO_ICON -#endif #ifndef QT_NO_IMAGEFORMATPLUGIN # define QT_NO_IMAGEFORMATPLUGIN #endif -- cgit v0.12 From 9c681ddc3a70b220de5d38de498ab1804ec12d4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 28 Oct 2009 15:50:04 +0100 Subject: Fix GRAPHICSVIEW Reviewed-by: tom --- src/gui/kernel/qevent.cpp | 2 ++ src/gui/kernel/qevent.h | 2 ++ src/gui/kernel/qgesturemanager.cpp | 2 ++ src/gui/kernel/qgesturemanager_p.h | 2 ++ src/gui/kernel/qwidget.cpp | 40 ++++++++++++++++++++++++--------- src/gui/painting/qbackingstore.cpp | 4 ++-- src/gui/painting/qwindowsurface_qws.cpp | 2 ++ 7 files changed, 41 insertions(+), 13 deletions(-) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 065bd09..bf9479f 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -4345,6 +4345,7 @@ QWidget *QGestureEvent::widget() const return d_func()->widget; } +#ifndef QT_NO_GRAPHICSVIEW /*! Returns the scene-local coordinates if the \a gesturePoint is inside a graphics view. @@ -4361,6 +4362,7 @@ QPointF QGestureEvent::mapToScene(const QPointF &gesturePoint) const } return QPointF(); } +#endif //QT_NO_GRAPHICSVIEW /*! \internal diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index b7370fd..d6b1dc1 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -854,7 +854,9 @@ public: void setWidget(QWidget *widget); QWidget *widget() const; +#ifndef QT_NO_GRAPHICSVIEW QPointF mapToScene(const QPointF &gesturePoint) const; +#endif private: QGestureEventPrivate *d_func(); diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index ed8e744..5ad607b 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -331,6 +331,7 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) return filterEventThroughContexts(contexts, event); } +#ifndef QT_NO_GRAPHICSVIEW bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event) { QSet types; @@ -360,6 +361,7 @@ bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event) } return filterEventThroughContexts(contexts, event); } +#endif bool QGestureManager::filterEvent(QGesture *state, QEvent *event) { diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h index f0e7225..8199e02 100644 --- a/src/gui/kernel/qgesturemanager_p.h +++ b/src/gui/kernel/qgesturemanager_p.h @@ -74,7 +74,9 @@ public: bool filterEvent(QWidget *receiver, QEvent *event); bool filterEvent(QGesture *receiver, QEvent *event); +#ifndef QT_NO_GRAPHICSVIEW bool filterEvent(QGraphicsObject *receiver, QEvent *event); +#endif //QT_NO_GRAPHICSVIEW // declared in qapplication.cpp static QGestureManager* instance(); diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 916ae8b..62cfd12 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1549,7 +1549,9 @@ void QWidgetPrivate::createExtra() extra = new QWExtra; extra->glContext = 0; extra->topextra = 0; +#ifndef QT_NO_GRAPHICSVIEW extra->proxyWidget = 0; +#endif #ifndef QT_NO_CURSOR extra->curs = 0; #endif @@ -1699,12 +1701,13 @@ void QWidgetPrivate::propagatePaletteChange() { Q_Q(QWidget); // Propagate a new inherited mask to all children. - if (!q->parentWidget() && extra && extra->proxyWidget) { #ifndef QT_NO_GRAPHICSVIEW + if (!q->parentWidget() && extra && extra->proxyWidget) { QGraphicsProxyWidget *p = extra->proxyWidget; inheritedPaletteResolveMask = p->d_func()->inheritedPaletteResolveMask | p->palette().resolve(); + } else #endif //QT_NO_GRAPHICSVIEW - } else if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) { + if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) { inheritedPaletteResolveMask = 0; } int mask = data.pal.resolve() | inheritedPaletteResolveMask; @@ -4381,7 +4384,11 @@ QPalette QWidgetPrivate::naturalWidgetPalette(uint inheritedMask) const Q_Q(const QWidget); QPalette naturalPalette = QApplication::palette(q); if (!q->testAttribute(Qt::WA_StyleSheet) - && (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation) || (extra && extra->proxyWidget))) { + && (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation) +#ifndef QT_NO_GRAPHICSVIEW + || (extra && extra->proxyWidget) +#endif //QT_NO_GRAPHICSVIEW + )) { if (QWidget *p = q->parentWidget()) { if (!p->testAttribute(Qt::WA_StyleSheet)) { if (!naturalPalette.isCopyOf(QApplication::palette())) { @@ -4392,13 +4399,14 @@ QPalette QWidgetPrivate::naturalWidgetPalette(uint inheritedMask) const naturalPalette = p->palette(); } } - } else if (extra && extra->proxyWidget) { + } #ifndef QT_NO_GRAPHICSVIEW + else if (extra && extra->proxyWidget) { QPalette inheritedPalette = extra->proxyWidget->palette(); inheritedPalette.resolve(inheritedMask); naturalPalette = inheritedPalette.resolve(naturalPalette); -#endif //QT_NO_GRAPHICSVIEW } +#endif //QT_NO_GRAPHICSVIEW } naturalPalette.resolve(0); return naturalPalette; @@ -4516,7 +4524,11 @@ QFont QWidgetPrivate::naturalWidgetFont(uint inheritedMask) const Q_Q(const QWidget); QFont naturalFont = QApplication::font(q); if (!q->testAttribute(Qt::WA_StyleSheet) - && (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation) || (extra && extra->proxyWidget))) { + && (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation) +#ifndef QT_NO_GRAPHICSVIEW + || (extra && extra->proxyWidget) +#endif //QT_NO_GRAPHICSVIEW + )) { if (QWidget *p = q->parentWidget()) { if (!p->testAttribute(Qt::WA_StyleSheet)) { if (!naturalFont.isCopyOf(QApplication::font())) { @@ -4527,13 +4539,14 @@ QFont QWidgetPrivate::naturalWidgetFont(uint inheritedMask) const naturalFont = p->font(); } } - } else if (extra && extra->proxyWidget) { + } #ifndef QT_NO_GRAPHICSVIEW + else if (extra && extra->proxyWidget) { QFont inheritedFont = extra->proxyWidget->font(); inheritedFont.resolve(inheritedMask); naturalFont = inheritedFont.resolve(naturalFont); -#endif //QT_NO_GRAPHICSVIEW } +#endif //QT_NO_GRAPHICSVIEW } naturalFont.resolve(0); return naturalFont; @@ -4580,12 +4593,13 @@ void QWidgetPrivate::updateFont(const QFont &font) data.fnt.x11SetScreen(xinfo.screen()); #endif // Combine new mask with natural mask and propagate to children. - if (!q->parentWidget() && extra && extra->proxyWidget) { #ifndef QT_NO_GRAPHICSVIEW + if (!q->parentWidget() && extra && extra->proxyWidget) { QGraphicsProxyWidget *p = extra->proxyWidget; inheritedFontResolveMask = p->d_func()->inheritedFontResolveMask | p->font().resolve(); + } else #endif //QT_NO_GRAPHICSVIEW - } else if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) { + if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) { inheritedFontResolveMask = 0; } uint newMask = data.fnt.resolve() | inheritedFontResolveMask; @@ -5396,7 +5410,11 @@ void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectLis , sharedPainter, backingStore); } - if (w->updatesEnabled() && (!w->d_func()->extra || !w->d_func()->extra->proxyWidget)) { + if (w->updatesEnabled() +#ifndef QT_NO_GRAPHICSVIEW + && (!w->d_func()->extra || !w->d_func()->extra->proxyWidget) +#endif //QT_NO_GRAPHICSVIEW + ) { QRegion wRegion(rgn); wRegion &= wd->effectiveRectFor(w->data->crect); wRegion.translate(-widgetPos); diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 3cd1402..de97302 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -891,7 +891,7 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy) const QRect parentRect(rect & clipR); bool accelerateMove = accelEnv && isOpaque -#ifndef QT_NO_GRAPHICSCVIEW +#ifndef QT_NO_GRAPHICSVIEW // No accelerate move for proxy widgets. && !tlw->d_func()->extra->proxyWidget #endif @@ -1189,7 +1189,7 @@ void QWidgetBackingStore::sync() : wd->dirty); toClean += widgetDirty; -#ifndef QT_NO_GRAPHICSCVIEW +#ifndef QT_NO_GRAPHICSVIEW if (tlw->d_func()->extra->proxyWidget) { resetWidget(w); continue; diff --git a/src/gui/painting/qwindowsurface_qws.cpp b/src/gui/painting/qwindowsurface_qws.cpp index 4f489c4..fa0c80e 100644 --- a/src/gui/painting/qwindowsurface_qws.cpp +++ b/src/gui/painting/qwindowsurface_qws.cpp @@ -668,9 +668,11 @@ void QWSWindowSurface::flush(QWidget *widget, const QRegion ®ion, if (!win) return; +#ifndef QT_NO_GRAPHICSVIEW QWExtra *extra = win->d_func()->extra; if (extra && extra->proxyWidget) return; +#endif //QT_NO_GRAPHICSVIEW Q_UNUSED(offset); -- cgit v0.12 From 9e01ced1d14467c06d7e1db57982556c9e861372 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 29 Oct 2009 18:07:06 +0100 Subject: Remove the posix_memalign and Win32 _aligned_malloc MinGW doesn't have _aligned_malloc and posix_memalign doesn't have a realloc function. So use our own implementation in all platforms. Removing posix_memalign was reviewed by Brad, but I apparently lost the commit. Reviewed-by: Trust Me --- src/corelib/global/qmalloc.cpp | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/src/corelib/global/qmalloc.cpp b/src/corelib/global/qmalloc.cpp index 3584c50..4aab1bd 100644 --- a/src/corelib/global/qmalloc.cpp +++ b/src/corelib/global/qmalloc.cpp @@ -43,10 +43,6 @@ #include -#ifdef Q_OS_WIN -# include -#endif - /* Define the container allocation functions in a separate file, so that our users can easily override them. @@ -71,38 +67,11 @@ void *qRealloc(void *ptr, size_t size) void *qMallocAligned(size_t size, size_t alignment) { -#if defined(Q_OS_WIN) - return _aligned_malloc(size, alignment); -#elif defined(HAVE_POSIX_MEMALIGN) - if (alignment <= sizeof(void*)) - return qMalloc(size); - - // we have posix_memalign - void *ptr = 0; - if (posix_memalign(&ptr, alignment, size) == 0) - return ptr; - return 0; -#else return qReallocAligned(0, size, 0, alignment); -#endif } void *qReallocAligned(void *oldptr, size_t newsize, size_t oldsize, size_t alignment) { -#if defined(Q_OS_WIN) - Q_UNUSED(oldsize); - return _aligned_realloc(oldptr, newsize, alignment); -#elif defined(HAVE_POSIX_MEMALIGN) - if (alignment <= sizeof(void*)) - return qRealloc(oldptr, newsize); - - void *newptr = qMallocAligned(newsize, alignment); - if (!newptr) - return 0; - qMemCopy(newptr, oldptr, qMin(oldsize, newsize)); - qFree(oldptr); - return newptr; -#else // fake an aligned allocation Q_UNUSED(oldsize); @@ -144,21 +113,14 @@ void *qReallocAligned(void *oldptr, size_t newsize, size_t oldsize, size_t align faked.pptr[-1] = real.ptr; return faked.ptr; -#endif } void qFreeAligned(void *ptr) { -#if defined(Q_OS_WIN) - _aligned_free(ptr); -#elif defined(HAVE_POSIX_MEMALIGN) - ::free(ptr); -#else if (!ptr) return; void **ptr2 = static_cast(ptr); free(ptr2[-1]); -#endif } QT_END_NAMESPACE -- cgit v0.12 From 6f602c01b9dc2b037cb42cacfe1c2df6e092a6b4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 29 Oct 2009 18:13:21 +0100 Subject: Autotest: this test is failing, enable debugging to find out why. It doesn't happen on my machine, so I need to figure out what's different. Reviewed-by: Trust Me --- tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp index d84350b..91050f5 100644 --- a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp +++ b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp @@ -132,6 +132,9 @@ tst_QDBusAbstractInterface::tst_QDBusAbstractInterface() void tst_QDBusAbstractInterface::initTestCase() { + // enable debugging temporarily: + putenv("QDBUS_DEBUG=1"); + // register the object QDBusConnection con = QDBusConnection::sessionBus(); QVERIFY(con.isConnected()); @@ -469,7 +472,7 @@ void tst_QDBusAbstractInterface::followSignal() QVERIFY(!QTestEventLoop::instance().timeout()); // now the signal must have been received: - QVERIFY(s.size() == 1); + QCOMPARE(s.size(), 1); QVERIFY(s.at(0).size() == 0); s.clear(); -- cgit v0.12 From 27c99302d0b44c6e9cd0eda6ba888b6a6f5bea38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Thu, 29 Oct 2009 18:50:55 +0100 Subject: Get rid of QPainter warnings generated from QGraphicsOpacityEffect. Problem was that we painted on null pixmap. We also want to use the pixmap cache (QGraphicsEffectSource::pixmap()) to improve performance. Reported by Andrew Baldwin's performance team. --- src/gui/effects/qgraphicseffect.cpp | 69 +++++++++++-------------------------- 1 file changed, 20 insertions(+), 49 deletions(-) diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp index 96d35b0..969b6b5 100644 --- a/src/gui/effects/qgraphicseffect.cpp +++ b/src/gui/effects/qgraphicseffect.cpp @@ -1235,64 +1235,35 @@ void QGraphicsOpacityEffect::draw(QPainter *painter, QGraphicsEffectSource *sour return; } - painter->save(); - painter->setOpacity(d->opacity); QPoint offset; - if (source->isPixmap()) { - // No point in drawing in device coordinates (pixmap will be scaled anyways). - if (!d->hasOpacityMask) { - const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset); - painter->drawPixmap(offset, pixmap); - } else { - QRect srcBrect = source->boundingRect().toAlignedRect(); - offset = srcBrect.topLeft(); - QPixmap pixmap(srcBrect.size()); - pixmap.fill(Qt::transparent); + Qt::CoordinateSystem system = source->isPixmap() ? Qt::LogicalCoordinates : Qt::DeviceCoordinates; + QPixmap pixmap = source->pixmap(system, &offset); + if (pixmap.isNull()) + return; - QPainter pixmapPainter(&pixmap); - pixmapPainter.setRenderHints(painter->renderHints()); - pixmapPainter.translate(-offset); - source->draw(&pixmapPainter); - pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn); - pixmapPainter.fillRect(srcBrect, d->opacityMask); - pixmapPainter.end(); + painter->save(); + painter->setOpacity(d->opacity); - painter->drawPixmap(offset, pixmap); - } - } else { - // Draw pixmap in device coordinates to avoid pixmap scaling; - if (!d->hasOpacityMask) { - const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset); - painter->setWorldTransform(QTransform()); - painter->drawPixmap(offset, pixmap); - } else { + if (d->hasOpacityMask) { + QPainter pixmapPainter(&pixmap); + pixmapPainter.setRenderHints(painter->renderHints()); + pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn); + if (system == Qt::DeviceCoordinates) { QTransform worldTransform = painter->worldTransform(); - - // Calculate source bounding rect in logical and device coordinates. - QRectF srcBrect = source->boundingRect(); - QRect srcDeviceBrect = worldTransform.mapRect(srcBrect).toAlignedRect(); - srcDeviceBrect &= source->deviceRect(); - - offset = srcDeviceBrect.topLeft(); - worldTransform *= QTransform::fromTranslate(-srcDeviceBrect.x(), -srcDeviceBrect.y()); - - QPixmap pixmap(srcDeviceBrect.size()); - pixmap.fill(Qt::transparent); - - QPainter pixmapPainter(&pixmap); - pixmapPainter.setRenderHints(painter->renderHints()); + worldTransform *= QTransform::fromTranslate(-offset.x(), -offset.y()); pixmapPainter.setWorldTransform(worldTransform); - source->draw(&pixmapPainter); - pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn); - pixmapPainter.fillRect(srcBrect, d->opacityMask); - pixmapPainter.end(); - - painter->setWorldTransform(QTransform()); - painter->drawPixmap(offset, pixmap); + pixmapPainter.fillRect(source->boundingRect(), d->opacityMask); + } else { + pixmapPainter.translate(-offset); + pixmapPainter.fillRect(pixmap.rect(), d->opacityMask); } } + if (system == Qt::DeviceCoordinates) + painter->setWorldTransform(QTransform()); + + painter->drawPixmap(offset, pixmap); painter->restore(); } -- cgit v0.12 From a5c3cd6d540f282f59c7c5891598ed8f2c6e033f Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 30 Oct 2009 10:44:37 +0100 Subject: Updated QTextEdit auto-test after changes in commit 04d18b38c. --- .../fullWidthSelection/centered-fully-selected.png | Bin 1232 -> 1232 bytes .../fullWidthSelection/centered-partly-selected.png | Bin 1231 -> 1231 bytes .../fullWidthSelection/last-char-on-line.png | Bin 1220 -> 1226 bytes .../fullWidthSelection/last-char-on-parag.png | Bin 1222 -> 1223 bytes .../fullWidthSelection/multiple-full-width-lines.png | Bin 1236 -> 1236 bytes .../auto/qtextedit/fullWidthSelection/nowrap_long.png | Bin 1199 -> 1199 bytes .../fullWidthSelection/single-full-width-line.png | Bin 1235 -> 1225 bytes tests/auto/qtextedit/tst_qtextedit.cpp | 4 ++-- 8 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qtextedit/fullWidthSelection/centered-fully-selected.png b/tests/auto/qtextedit/fullWidthSelection/centered-fully-selected.png index 7467478..ced6eb6 100644 Binary files a/tests/auto/qtextedit/fullWidthSelection/centered-fully-selected.png and b/tests/auto/qtextedit/fullWidthSelection/centered-fully-selected.png differ diff --git a/tests/auto/qtextedit/fullWidthSelection/centered-partly-selected.png b/tests/auto/qtextedit/fullWidthSelection/centered-partly-selected.png index 7a10e63..481b99c 100644 Binary files a/tests/auto/qtextedit/fullWidthSelection/centered-partly-selected.png and b/tests/auto/qtextedit/fullWidthSelection/centered-partly-selected.png differ diff --git a/tests/auto/qtextedit/fullWidthSelection/last-char-on-line.png b/tests/auto/qtextedit/fullWidthSelection/last-char-on-line.png index df5b92e..292d3f9 100644 Binary files a/tests/auto/qtextedit/fullWidthSelection/last-char-on-line.png and b/tests/auto/qtextedit/fullWidthSelection/last-char-on-line.png differ diff --git a/tests/auto/qtextedit/fullWidthSelection/last-char-on-parag.png b/tests/auto/qtextedit/fullWidthSelection/last-char-on-parag.png index d58d4cc..69b72ed 100644 Binary files a/tests/auto/qtextedit/fullWidthSelection/last-char-on-parag.png and b/tests/auto/qtextedit/fullWidthSelection/last-char-on-parag.png differ diff --git a/tests/auto/qtextedit/fullWidthSelection/multiple-full-width-lines.png b/tests/auto/qtextedit/fullWidthSelection/multiple-full-width-lines.png index c5c3c22..467b91e 100644 Binary files a/tests/auto/qtextedit/fullWidthSelection/multiple-full-width-lines.png and b/tests/auto/qtextedit/fullWidthSelection/multiple-full-width-lines.png differ diff --git a/tests/auto/qtextedit/fullWidthSelection/nowrap_long.png b/tests/auto/qtextedit/fullWidthSelection/nowrap_long.png index 7ded254..cce921b 100644 Binary files a/tests/auto/qtextedit/fullWidthSelection/nowrap_long.png and b/tests/auto/qtextedit/fullWidthSelection/nowrap_long.png differ diff --git a/tests/auto/qtextedit/fullWidthSelection/single-full-width-line.png b/tests/auto/qtextedit/fullWidthSelection/single-full-width-line.png index d2fd629..937494a 100644 Binary files a/tests/auto/qtextedit/fullWidthSelection/single-full-width-line.png and b/tests/auto/qtextedit/fullWidthSelection/single-full-width-line.png differ diff --git a/tests/auto/qtextedit/tst_qtextedit.cpp b/tests/auto/qtextedit/tst_qtextedit.cpp index 59abbd5..fee030c 100644 --- a/tests/auto/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/qtextedit/tst_qtextedit.cpp @@ -1967,7 +1967,7 @@ void tst_QTextEdit::fullWidthSelection() qt_setQtEnableTestFont(true); QFont testFont; testFont.setFamily("__Qt__Box__Engine__"); - testFont.setPixelSize(12); + testFont.setPixelSize(11); testFont.setWeight(QFont::Normal); QTextCharFormat cf; cf.setFont(testFont); @@ -2015,7 +2015,7 @@ void tst_QTextEdit::fullWidthSelection2() qt_setQtEnableTestFont(true); QFont testFont; testFont.setFamily("__Qt__Box__Engine__"); - testFont.setPixelSize(12); + testFont.setPixelSize(11); testFont.setWeight(QFont::Normal); QTextCharFormat cf; cf.setFont(testFont); -- cgit v0.12 From d670ef51fe76adccd6f4d017f6a23940ab5284ee Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 30 Oct 2009 10:55:29 +0100 Subject: rename qstringbuilder test classes --- tests/auto/qstringbuilder1/qstringbuilder1.pro | 3 -- tests/auto/qstringbuilder1/stringbuilder.cpp | 56 +--------------------- tests/auto/qstringbuilder1/stringbuilder.h | 55 --------------------- tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp | 33 ++++++++++++- tests/auto/qstringbuilder2/qstringbuilder2.pro | 3 -- tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp | 32 +++++++++++++ tests/auto/qstringbuilder3/qstringbuilder3.pro | 3 -- tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp | 31 ++++++++++++ tests/auto/qstringbuilder4/qstringbuilder4.pro | 3 -- tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp | 34 ++++++++++++- 10 files changed, 129 insertions(+), 124 deletions(-) delete mode 100644 tests/auto/qstringbuilder1/stringbuilder.h diff --git a/tests/auto/qstringbuilder1/qstringbuilder1.pro b/tests/auto/qstringbuilder1/qstringbuilder1.pro index 1ca9d45..5bb14d4 100644 --- a/tests/auto/qstringbuilder1/qstringbuilder1.pro +++ b/tests/auto/qstringbuilder1/qstringbuilder1.pro @@ -3,7 +3,4 @@ load(qttest_p4) QT = core SOURCES += tst_qstringbuilder1.cpp -HEADERS += ../qstringbuilder1/stringbuilder.h - -DEFINES += SCENARIO=1 diff --git a/tests/auto/qstringbuilder1/stringbuilder.cpp b/tests/auto/qstringbuilder1/stringbuilder.cpp index 9fea137..f35d4d2 100644 --- a/tests/auto/qstringbuilder1/stringbuilder.cpp +++ b/tests/auto/qstringbuilder1/stringbuilder.cpp @@ -39,61 +39,9 @@ ** ****************************************************************************/ -// This is included in various .cpp files as a compile test for various scenarios -// depending on NO_CAST_* and QT_USE_FAST_OPERATOR_PLUS and QT_USE_FAST_CONCATENATION - -#if SCENARIO == 1 -// this is the "no harm done" version. Only operator% is active, -// with NO_CAST * defined -#define P % -#undef QT_USE_FAST_OPERATOR_PLUS -#undef QT_USE_FAST_CONCATENATION -#define QT_NO_CAST_FROM_ASCII -#define QT_NO_CAST_TO_ASCII -#endif - - -#if SCENARIO == 2 -// this is the "full" version. Operator+ is replaced by a QStringBuilder -// based version -// with NO_CAST * defined -#define P + -#define QT_USE_FAST_OPERATOR_PLUS -#define QT_USE_FAST_CONCATENATION -#define QT_NO_CAST_FROM_ASCII -#define QT_NO_CAST_TO_ASCII -#endif - -#if SCENARIO == 3 -// this is the "no harm done" version. Only operator% is active, -// with NO_CAST * _not_ defined -#define P % -#undef QT_USE_FAST_OPERATOR_PLUS -#undef QT_USE_FAST_CONCATENATION -#undef QT_NO_CAST_FROM_ASCII -#undef QT_NO_CAST_TO_ASCII -#endif - -#if SCENARIO == 4 -// this is the "full" version. Operator+ is replaced by a QStringBuilder -// based version -// with NO_CAST * _not_ defined -#define P + -#define QT_USE_FAST_OPERATOR_PLUS -#define QT_USE_FAST_CONCATENATION -#undef QT_NO_CAST_FROM_ASCII -#undef QT_NO_CAST_TO_ASCII -#endif - -#include -#include "stringbuilder.h" - -//TESTED_CLASS=QStringBuilder -//TESTED_FILES=qstringbuilder.cpp - #define LITERAL "some literal" -void tst_QStringBuilder::scenario() +void runScenario() { QLatin1Literal l1literal(LITERAL); QLatin1String l1string(LITERAL); @@ -129,5 +77,3 @@ void tst_QStringBuilder::scenario() QCOMPARE(r, r2); #endif } - -QTEST_APPLESS_MAIN(tst_QStringBuilder) diff --git a/tests/auto/qstringbuilder1/stringbuilder.h b/tests/auto/qstringbuilder1/stringbuilder.h deleted file mode 100644 index 5ac9dbe..0000000 --- a/tests/auto/qstringbuilder1/stringbuilder.h +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TST_QSTRINGBUILDER_H -#define TST_QSTRINGBUILDER_H - -#include - -class tst_QStringBuilder : public QObject -{ - Q_OBJECT - -private slots: - void scenario(); -}; - -#endif diff --git a/tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp b/tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp index bd2e4b0..d0a613c 100644 --- a/tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp +++ b/tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp @@ -39,4 +39,35 @@ ** ****************************************************************************/ -#include "../qstringbuilder1/stringbuilder.cpp" + +// SCENARIO 1 +// this is the "no harm done" version. Only operator% is active, +// with NO_CAST * defined +#define P % +#undef QT_USE_FAST_OPERATOR_PLUS +#undef QT_USE_FAST_CONCATENATION +#define QT_NO_CAST_FROM_ASCII +#define QT_NO_CAST_TO_ASCII + + +#include + +//TESTED_CLASS=QStringBuilder +//TESTED_FILES=qstringbuilder.cpp + +#define LITERAL "some literal" + +void runScenario(); // Defined in stringbuilder.cpp #included below. + +class tst_QStringBuilder1 : public QObject +{ + Q_OBJECT + +private slots: + void scenario() { runScenario(); } +}; + +#include "stringbuilder.cpp" +#include "tst_qstringbuilder1.moc" + +QTEST_APPLESS_MAIN(tst_QStringBuilder1) diff --git a/tests/auto/qstringbuilder2/qstringbuilder2.pro b/tests/auto/qstringbuilder2/qstringbuilder2.pro index c0b3ebc..4152dc3 100644 --- a/tests/auto/qstringbuilder2/qstringbuilder2.pro +++ b/tests/auto/qstringbuilder2/qstringbuilder2.pro @@ -3,6 +3,3 @@ load(qttest_p4) QT = core SOURCES += tst_qstringbuilder2.cpp -HEADERS += ../qstringbuilder1/stringbuilder.h - -DEFINES += SCENARIO=2 diff --git a/tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp b/tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp index bd2e4b0..4470928 100644 --- a/tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp +++ b/tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp @@ -39,4 +39,36 @@ ** ****************************************************************************/ + +// SCENARIO 2 +// this is the "full" version. Operator+ is replaced by a QStringBuilder +// based version +// with NO_CAST * defined +#define P + +#define QT_USE_FAST_OPERATOR_PLUS +#define QT_USE_FAST_CONCATENATION +#define QT_NO_CAST_FROM_ASCII +#define QT_NO_CAST_TO_ASCII + + +#include + +//TESTED_CLASS=QStringBuilder +//TESTED_FILES=qstringbuilder.cpp + +#define LITERAL "some literal" + +void runScenario(); // Defined in stringbuilder.cpp #included below. + +class tst_QStringBuilder2 : public QObject +{ + Q_OBJECT + +private slots: + void scenario() { runScenario(); } +}; + #include "../qstringbuilder1/stringbuilder.cpp" +#include "tst_qstringbuilder2.moc" + +QTEST_APPLESS_MAIN(tst_QStringBuilder2) diff --git a/tests/auto/qstringbuilder3/qstringbuilder3.pro b/tests/auto/qstringbuilder3/qstringbuilder3.pro index 93d1a39..b4d2225 100644 --- a/tests/auto/qstringbuilder3/qstringbuilder3.pro +++ b/tests/auto/qstringbuilder3/qstringbuilder3.pro @@ -3,6 +3,3 @@ load(qttest_p4) QT = core SOURCES += tst_qstringbuilder3.cpp -HEADERS += ../qstringbuilder1/stringbuilder.h - -DEFINES += SCENARIO=3 diff --git a/tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp b/tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp index bd2e4b0..30f0181 100644 --- a/tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp +++ b/tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp @@ -39,4 +39,35 @@ ** ****************************************************************************/ + +// SCENARIO 3 +// this is the "no harm done" version. Only operator% is active, +// with NO_CAST * _not_ defined +#define P % +#undef QT_USE_FAST_OPERATOR_PLUS +#undef QT_USE_FAST_CONCATENATION +#undef QT_NO_CAST_FROM_ASCII +#undef QT_NO_CAST_TO_ASCII + + +#include + +//TESTED_CLASS=QStringBuilder +//TESTED_FILES=qstringbuilder.cpp + +#define LITERAL "some literal" + +void runScenario(); // Defined in stringbuilder.cpp #included below. + +class tst_QStringBuilder3 : public QObject +{ + Q_OBJECT + +private slots: + void scenario() { runScenario(); } +}; + #include "../qstringbuilder1/stringbuilder.cpp" +#include "tst_qstringbuilder3.moc" + +QTEST_APPLESS_MAIN(tst_QStringBuilder3) diff --git a/tests/auto/qstringbuilder4/qstringbuilder4.pro b/tests/auto/qstringbuilder4/qstringbuilder4.pro index eeec447..6ec5228 100644 --- a/tests/auto/qstringbuilder4/qstringbuilder4.pro +++ b/tests/auto/qstringbuilder4/qstringbuilder4.pro @@ -3,6 +3,3 @@ load(qttest_p4) QT = core SOURCES += tst_qstringbuilder4.cpp -HEADERS += ../qstringbuilder1/stringbuilder.h - -DEFINES += SCENARIO=4 diff --git a/tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp b/tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp index 2159283..95b4ec3 100644 --- a/tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp +++ b/tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** This file is part of the test suite module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage @@ -39,4 +39,36 @@ ** ****************************************************************************/ + +// SCENARIO 4 +// this is the "full" version. Operator+ is replaced by a QStringBuilder +// based version +// with NO_CAST * _not_ defined +#define P + +#define QT_USE_FAST_OPERATOR_PLUS +#define QT_USE_FAST_CONCATENATION +#undef QT_NO_CAST_FROM_ASCII +#undef QT_NO_CAST_TO_ASCII + + +#include + +//TESTED_CLASS=QStringBuilder +//TESTED_FILES=qstringbuilder.cpp + +#define LITERAL "some literal" + +void runScenario(); // Defined in stringbuilder.cpp #included below. + +class tst_QStringBuilder4 : public QObject +{ + Q_OBJECT + +private slots: + void scenario() { runScenario(); } +}; + #include "../qstringbuilder1/stringbuilder.cpp" +#include "tst_qstringbuilder4.moc" + +QTEST_APPLESS_MAIN(tst_QStringBuilder4) -- cgit v0.12 From 2cdea6a10da75b7b8870f27c432a5e02f7500340 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 30 Oct 2009 11:11:26 +0100 Subject: QActionGroup: reset the checkedAction when it is unchecked Task-number: QTBUG-1019 Reviewed-by: Gabriel --- src/gui/kernel/qactiongroup.cpp | 14 ++++++++++---- tests/auto/qactiongroup/tst_qactiongroup.cpp | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/gui/kernel/qactiongroup.cpp b/src/gui/kernel/qactiongroup.cpp index 40d18a2..8db76e4 100644 --- a/src/gui/kernel/qactiongroup.cpp +++ b/src/gui/kernel/qactiongroup.cpp @@ -72,10 +72,16 @@ void QActionGroupPrivate::_q_actionChanged() Q_Q(QActionGroup); QAction *action = qobject_cast(q->sender()); Q_ASSERT_X(action != 0, "QWidgetGroup::_q_actionChanged", "internal error"); - if(exclusive && action->isChecked() && action != current) { - if(current) - current->setChecked(false); - current = action; + if(exclusive) { + if (action->isChecked()) { + if (action != current) { + if(current) + current->setChecked(false); + current = action; + } + } else if (action == current) { + current = 0; + } } } diff --git a/tests/auto/qactiongroup/tst_qactiongroup.cpp b/tests/auto/qactiongroup/tst_qactiongroup.cpp index 2d215a0..7259479 100644 --- a/tests/auto/qactiongroup/tst_qactiongroup.cpp +++ b/tests/auto/qactiongroup/tst_qactiongroup.cpp @@ -70,6 +70,7 @@ private slots: void separators(); void testActionInTwoQActionGroup(); + void unCheckCurrentAction(); }; tst_QActionGroup::tst_QActionGroup() @@ -278,5 +279,25 @@ void tst_QActionGroup::testActionInTwoQActionGroup() QCOMPARE(group1.actions().isEmpty(), true); } +void tst_QActionGroup::unCheckCurrentAction() +{ + QActionGroup group(0); + QAction action1(&group) ,action2(&group); + action1.setCheckable(true); + action2.setCheckable(true); + QVERIFY(!action1.isChecked()); + QVERIFY(!action2.isChecked()); + action1.setChecked(true); + QVERIFY(action1.isChecked()); + QVERIFY(!action2.isChecked()); + QAction *current = group.checkedAction(); + QCOMPARE(current, &action1); + current->setChecked(false); + QVERIFY(!action1.isChecked()); + QVERIFY(!action2.isChecked()); + QVERIFY(group.checkedAction() == 0); +} + + QTEST_MAIN(tst_QActionGroup) #include "tst_qactiongroup.moc" -- cgit v0.12 From 1bed105d048531e3e260eff0ef2533d7cc8ba7fb Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 26 Oct 2009 12:40:33 +0100 Subject: introduce int QTextDocument::available{Undo,Redo}Steps() const; Formerly, QTextDocument::revision() could be used to guesstimate the number of available undo steps that was used in Qt Creator to store cursor positions in parallel to the actual text contents. Now that revision() is strictly increasing, another means is needed, therefore the new functions providing the needed data. Reviewed-by: mae --- src/gui/text/qtextdocument.cpp | 27 +++++++++++++++++++++++++++ src/gui/text/qtextdocument.h | 3 +++ src/gui/text/qtextdocument_p.h | 3 +++ 3 files changed, 33 insertions(+) diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index a8956b8..5398111 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -956,6 +956,8 @@ QString QTextDocument::defaultStyleSheet() const /*! Returns true if undo is available; otherwise returns false. + + \sa isRedoAvailable(), availableUndoSteps() */ bool QTextDocument::isUndoAvailable() const { @@ -965,6 +967,8 @@ bool QTextDocument::isUndoAvailable() const /*! Returns true if redo is available; otherwise returns false. + + \sa isUndoAvailable(), availableRedoSteps() */ bool QTextDocument::isRedoAvailable() const { @@ -972,6 +976,29 @@ bool QTextDocument::isRedoAvailable() const return d->isRedoAvailable(); } +/*! \since 4.6 + + Returns the number of available undo steps. + + \sa isUndoAvailable() +*/ +int QTextDocument::availableUndoSteps() const +{ + Q_D(const QTextDocument); + return d->availableUndoSteps(); +} + +/*! \since 4.6 + + Returns the number of available redo steps. + + \sa isRedoAvailable() +*/ +int QTextDocument::availableRedoSteps() const +{ + Q_D(const QTextDocument); + return d->availableRedoSteps(); +} /*! \since 4.4 diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h index e52716a..d217a4d 100644 --- a/src/gui/text/qtextdocument.h +++ b/src/gui/text/qtextdocument.h @@ -142,6 +142,9 @@ public: bool isUndoAvailable() const; bool isRedoAvailable() const; + int availableUndoSteps() const; + int availableRedoSteps() const; + int revision() const; void setDocumentLayout(QAbstractTextDocumentLayout *layout); diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h index ce25c57..c10855b 100644 --- a/src/gui/text/qtextdocument_p.h +++ b/src/gui/text/qtextdocument_p.h @@ -212,6 +212,9 @@ public: inline bool isUndoAvailable() const { return undoEnabled && undoState > 0; } inline bool isRedoAvailable() const { return undoEnabled && undoState < undoStack.size(); } + inline int availableUndoSteps() const { return undoEnabled ? undoState : 0; } + inline int availableRedoSteps() const { return undoEnabled ? qMax(undoStack.size() - undoState - 1, 0) : 0; } + inline QString buffer() const { return text; } QString plainText() const; inline int length() const { return fragments.length(); } -- cgit v0.12 From c726e83aebf2252b5a94444d5d61e03ef2033437 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 30 Oct 2009 11:36:30 +0100 Subject: In ItemViews, right click on the viewport clear the ext selection Task-number: QTBUG-435 Reviewed-by: Gabriel --- src/gui/itemviews/qabstractitemview.cpp | 2 +- tests/auto/qlistview/tst_qlistview.cpp | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index 9247411..23bef12 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -3641,7 +3641,7 @@ QItemSelectionModel::SelectionFlags QAbstractItemViewPrivate::extendedSelectionC const bool controlKeyPressed = modifiers & Qt::ControlModifier; if (((index == pressedIndex && selectionModel->isSelected(index)) || !index.isValid()) && state != QAbstractItemView::DragSelectingState - && !shiftKeyPressed && !controlKeyPressed && !rightButtonPressed) + && !shiftKeyPressed && !controlKeyPressed && (!rightButtonPressed || !index.isValid())) return QItemSelectionModel::ClearAndSelect|selectionBehaviorFlags(); return QItemSelectionModel::NoUpdate; } diff --git a/tests/auto/qlistview/tst_qlistview.cpp b/tests/auto/qlistview/tst_qlistview.cpp index 727e6d3..a5ff153 100644 --- a/tests/auto/qlistview/tst_qlistview.cpp +++ b/tests/auto/qlistview/tst_qlistview.cpp @@ -120,6 +120,7 @@ private slots: void taskQTBUG_2233_scrollHiddenItems_data(); void taskQTBUG_2233_scrollHiddenItems(); void taskQTBUG_633_changeModelData(); + void taskQTBUG_435_deselectOnViewportClick(); }; // Testing get/set functions @@ -1852,6 +1853,28 @@ void tst_QListView::taskQTBUG_633_changeModelData() QVERIFY( ! rectLongText.intersects(rect2) ); } +void tst_QListView::taskQTBUG_435_deselectOnViewportClick() +{ + QListView view; + QStringListModel model( QStringList() << "1" << "2" << "3" << "4"); + view.setModel(&model); + view.setSelectionMode(QAbstractItemView::ExtendedSelection); + view.selectAll(); + QCOMPARE(view.selectionModel()->selectedIndexes().count(), model.rowCount()); + + + QPoint p = view.visualRect(model.index(model.rowCount() - 1)).center() + QPoint(0, 20); + //first the left button + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, p); + QVERIFY(!view.selectionModel()->hasSelection()); + + view.selectAll(); + QCOMPARE(view.selectionModel()->selectedIndexes().count(), model.rowCount()); + + //and now the right button + QTest::mouseClick(view.viewport(), Qt::RightButton, 0, p); + QVERIFY(!view.selectionModel()->hasSelection()); +} QTEST_MAIN(tst_QListView) #include "tst_qlistview.moc" -- cgit v0.12 From b68cd1df21935fc032a93c7d7bc33fcb77c7b8cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 30 Oct 2009 12:20:09 +0100 Subject: Reverts bf1a6bb6b3b8c98f6ab402512eb2f1996c2435c7 and removes THREAD from qfeature Reviewed-by: Trust Me --- src/corelib/global/qconfig-minimal.h | 3 -- src/corelib/global/qfeatures.h | 63 ++++++++++++++++-------------------- src/corelib/global/qfeatures.txt | 15 +++------ src/corelib/thread/qmutexpool.cpp | 20 ++++++------ src/corelib/thread/qmutexpool_p.h | 17 ++-------- src/corelib/thread/qthread.cpp | 24 ++++++-------- src/corelib/thread/qthread_p.h | 62 ++++++++++++++++++----------------- 7 files changed, 85 insertions(+), 119 deletions(-) diff --git a/src/corelib/global/qconfig-minimal.h b/src/corelib/global/qconfig-minimal.h index 9cc3057..58565d6 100644 --- a/src/corelib/global/qconfig-minimal.h +++ b/src/corelib/global/qconfig-minimal.h @@ -255,9 +255,6 @@ #ifndef QT_NO_TEXTHTMLPARSER # define QT_NO_TEXTHTMLPARSER #endif -#ifndef QT_NO_THREAD -# define QT_NO_THREAD -#endif #ifndef QT_NO_CONCURRENT # define QT_NO_CONCURRENT #endif diff --git a/src/corelib/global/qfeatures.h b/src/corelib/global/qfeatures.h index 3996180..9b3e817 100644 --- a/src/corelib/global/qfeatures.h +++ b/src/corelib/global/qfeatures.h @@ -55,6 +55,9 @@ // Color Names //#define QT_NO_COLORNAMES +// QtConcurrent +//#define QT_NO_CONCURRENT + // QCopChannel //#define QT_NO_COP @@ -76,6 +79,9 @@ // Effects //#define QT_NO_EFFECTS +// QFileSystemWatcher +//#define QT_NO_FILESYSTEMWATCHER + // Freetype Font Engine //#define QT_NO_FREETYPE @@ -151,6 +157,9 @@ // QPicture //#define QT_NO_PICTURE +// QProcess +//#define QT_NO_PROCESS + // QProgressBar //#define QT_NO_PROGRESSBAR @@ -274,9 +283,6 @@ // QTextStream //#define QT_NO_TEXTSTREAM -// QThread -//#define QT_NO_THREAD - // QToolTip //#define QT_NO_TOOLTIP @@ -301,6 +307,11 @@ // //#define QT_NO_XMLSTREAM +// Animation +#if !defined(QT_NO_ANIMATION) && (defined(QT_NO_PROPERTIES)) +#define QT_NO_ANIMATION +#endif + // QButtonGroup #if !defined(QT_NO_BUTTONGROUP) && (defined(QT_NO_GROUPBOX)) #define QT_NO_BUTTONGROUP @@ -316,11 +327,6 @@ #define QT_NO_CODECS #endif -// QtConcurrent -#if !defined(QT_NO_CONCURRENT) && (defined(QT_NO_THREAD)) -#define QT_NO_CONCURRENT -#endif - // QDate/QTime/QDateTime #if !defined(QT_NO_DATESTRING) && (defined(QT_NO_TEXTDATE)) #define QT_NO_DATESTRING @@ -331,9 +337,9 @@ #define QT_NO_DIAL #endif -// QFileSystemWatcher -#if !defined(QT_NO_FILESYSTEMWATCHER) && (defined(QT_NO_THREAD)) -#define QT_NO_FILESYSTEMWATCHER +// QFileSystemModel +#if !defined(QT_NO_FILESYSTEMMODEL) && (defined(QT_NO_FILESYSTEMWATCHER)) +#define QT_NO_FILESYSTEMMODEL #endif // QHostInfo @@ -371,11 +377,6 @@ #define QT_NO_PHONON_VOLUMEFADEREFFECT #endif -// QProcess -#if !defined(QT_NO_PROCESS) && (defined(QT_NO_THREAD)) -#define QT_NO_PROCESS -#endif - // QProgressDialog #if !defined(QT_NO_PROGRESSDIALOG) && (defined(QT_NO_PROGRESSBAR)) #define QT_NO_PROGRESSDIALOG @@ -491,21 +492,11 @@ #define QT_NO_XMLSTREAMWRITER #endif -// Animation -#if !defined(QT_NO_ANIMATION) && (defined(QT_NO_PROPERTIES) || defined(QT_NO_THREAD)) -#define QT_NO_ANIMATION -#endif - // Context menu #if !defined(QT_NO_CONTEXTMENU) && (defined(QT_NO_MENU)) #define QT_NO_CONTEXTMENU #endif -// QFileSystemModel -#if !defined(QT_NO_FILESYSTEMMODEL) && (defined(QT_NO_FILESYSTEMWATCHER)) -#define QT_NO_FILESYSTEMMODEL -#endif - // File Transfer Protocol #if !defined(QT_NO_FTP) && (defined(QT_NO_URLINFO) || defined(QT_NO_TEXTDATE)) #define QT_NO_FTP @@ -796,31 +787,31 @@ #define QT_NO_CUPS #endif -// QDockwidget -#if !defined(QT_NO_DOCKWIDGET) && (defined(QT_NO_RUBBERBAND) || defined(QT_NO_MAINWINDOW)) -#define QT_NO_DOCKWIDGET -#endif - // QDirModel #if !defined(QT_NO_DIRMODEL) && (defined(QT_NO_ITEMVIEWS) || defined(QT_NO_FILESYSTEMMODEL)) #define QT_NO_DIRMODEL #endif +// QDockwidget +#if !defined(QT_NO_DOCKWIDGET) && (defined(QT_NO_RUBBERBAND) || defined(QT_NO_MAINWINDOW)) +#define QT_NO_DOCKWIDGET +#endif + // QUndoView #if !defined(QT_NO_UNDOVIEW) && (defined(QT_NO_UNDOSTACK) || defined(QT_NO_LISTVIEW)) #define QT_NO_UNDOVIEW #endif -// QGraphicsSvgItem -#if !defined(QT_NO_GRAPHICSSVGITEM) && (defined(QT_NO_SVGRENDERER) || defined(QT_NO_GRAPHICSVIEW)) -#define QT_NO_GRAPHICSSVGITEM -#endif - // QCompleter #if !defined(QT_NO_FSCOMPLETER) && (defined(QT_NO_FILESYSTEMMODEL) || defined(QT_NO_COMPLETER)) #define QT_NO_FSCOMPLETER #endif +// QGraphicsSvgItem +#if !defined(QT_NO_GRAPHICSSVGITEM) && (defined(QT_NO_SVGRENDERER) || defined(QT_NO_GRAPHICSVIEW)) +#define QT_NO_GRAPHICSSVGITEM +#endif + // QComboBox #if !defined(QT_NO_COMBOBOX) && (defined(QT_NO_LINEEDIT) || defined(QT_NO_STANDARDITEMMODEL) || defined(QT_NO_LISTVIEW)) #define QT_NO_COMBOBOX diff --git a/src/corelib/global/qfeatures.txt b/src/corelib/global/qfeatures.txt index 543056f..ff34006 100644 --- a/src/corelib/global/qfeatures.txt +++ b/src/corelib/global/qfeatures.txt @@ -28,17 +28,10 @@ Requires: Name: CssParser SeeAlso: ??? -Feature: THREAD -Description: Supports multithreaded programming. -Section: Kernel -Requires: -Name: QThread -SeeAlso: ??? - Feature: CONCURRENT Description: Provides a high-level multi-threaded APIs Section: Kernel -Requires: THREAD +Requires: Name: QtConcurrent SeeAlso: ??? @@ -195,7 +188,7 @@ SeeAlso: ??? Feature: PROCESS Description: Supports external process invocation. Section: File I/O -Requires: THREAD +Requires: Name: QProcess SeeAlso: ??? @@ -245,7 +238,7 @@ Feature: FILESYSTEMWATCHER Description: Provides an interface for monitoring files and directories for modications. Section: File I/O -Requires: THREAD +Requires: Name: QFileSystemWatcher SeeAlso: ??? @@ -1166,7 +1159,7 @@ SeeAlso: ??? Feature: ANIMATION Description: Provides a framework for animations. Section: Utilities -Requires: PROPERTIES THREAD +Requires: PROPERTIES Name: Animation SeeAlso: ??? diff --git a/src/corelib/thread/qmutexpool.cpp b/src/corelib/thread/qmutexpool.cpp index 9f37239..c5c1882 100644 --- a/src/corelib/thread/qmutexpool.cpp +++ b/src/corelib/thread/qmutexpool.cpp @@ -42,6 +42,7 @@ #include "qatomic.h" #include "qmutexpool_p.h" +#ifndef QT_NO_THREAD QT_BEGIN_NAMESPACE @@ -49,7 +50,6 @@ QT_BEGIN_NAMESPACE // use QMutexpool::instance() in new clode. Q_CORE_EXPORT QMutexPool *qt_global_mutexpool = 0; Q_GLOBAL_STATIC_WITH_ARGS(QMutexPool, globalMutexPool, (QMutex::Recursive)) -#ifndef QT_NO_THREAD /*! \class QMutexPool @@ -114,6 +114,15 @@ QMutexPool::~QMutexPool() mutexes[index] = 0; } } + +/*! + Returns the global QMutexPool instance. +*/ +QMutexPool *QMutexPool::instance() +{ + return globalMutexPool(); +} + /*! Returns a QMutex from the pool. QMutexPool uses the value \a address to determine which mutex is returned from the pool. @@ -143,14 +152,7 @@ QMutex *QMutexPool::globalInstanceGet(const void *address) return 0; return globalInstance->get(address); } -#endif // QT_NO_THREAD -/*! - Returns the global QMutexPool instance. -*/ -QMutexPool *QMutexPool::instance() -{ - return globalMutexPool(); -} QT_END_NAMESPACE +#endif // QT_NO_THREAD diff --git a/src/corelib/thread/qmutexpool_p.h b/src/corelib/thread/qmutexpool_p.h index c26711b..3e1bad0 100644 --- a/src/corelib/thread/qmutexpool_p.h +++ b/src/corelib/thread/qmutexpool_p.h @@ -57,9 +57,9 @@ #include "QtCore/qmutex.h" #include "QtCore/qvarlengtharray.h" +#ifndef QT_NO_THREAD QT_BEGIN_NAMESPACE -#ifndef QT_NO_THREAD class Q_CORE_EXPORT QMutexPool { @@ -75,24 +75,11 @@ private: QVarLengthArray, 131> mutexes; QMutex::RecursionMode recursionMode; }; -#else //QT_NO_THREAD -Q_GLOBAL_STATIC(QMutex, globalMutex) -class Q_CORE_EXPORT QMutexPool -{ -public: - explicit QMutexPool(QMutex::RecursionMode recursionMode = QMutex::NonRecursive, int size = 131){} - ~QMutexPool(){} - - QMutex *get(const void *address){return globalMutex();} - static QMutexPool *instance(); - static QMutex *globalInstanceGet(const void *address){return globalMutex();} -}; - -#endif // QT_NO_THREAD extern Q_CORE_EXPORT QMutexPool *qt_global_mutexpool; QT_END_NAMESPACE +#endif // QT_NO_THREAD #endif // QMUTEXPOOL_P_H diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index cf57d33..ac191fe 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -727,16 +727,6 @@ QThread *QThread::currentThread() return QThreadData::current()->thread; } -/*! \internal - */ -QThread::QThread(QThreadPrivate &dd, QObject *parent) - : QObject(dd, parent) -{ - Q_D(QThread); - // fprintf(stderr, "QThreadData %p taken from private data for thread %p\n", d->data, this); - d->data->thread = this; -} - QThreadData* QThreadData::current() { static QThreadData *data = 0; // reinterpret_cast(pthread_getspecific(current_thread_data_key)); @@ -748,13 +738,17 @@ QThreadData* QThreadData::current() } return data; } -#endif // QT_NO_THREAD -QThreadData* QThreadData::get2(QThread *thread) + +/*! \internal + */ +QThread::QThread(QThreadPrivate &dd, QObject *parent) + : QObject(dd, parent) { - Q_ASSERT_X(thread != 0, "QThread", "internal error"); - return thread->d_func()->data; + Q_D(QThread); + // fprintf(stderr, "QThreadData %p taken from private data for thread %p\n", d->data, this); + d->data->thread = this; } - +#endif // QT_NO_THREAD QT_END_NAMESPACE diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index 8c3acdb..af68434 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -111,36 +111,6 @@ public: { } }; -class QThreadData -{ - QAtomicInt _ref; - -public: - QThreadData(int initialRefCount = 1); - ~QThreadData(); - - static QThreadData *current(); - static QThreadData *get2(QThread *thread); - - void ref(); - void deref(); - - QThread *thread; - bool quitNow; - int loopLevel; - QAbstractEventDispatcher *eventDispatcher; - QStack eventLoops; - QPostEventList postEventList; - bool canWait; - QMap tls; - - QMutex mutex; - -# ifdef Q_OS_SYMBIAN - RThread symbian_thread_handle; -# endif -}; - #ifndef QT_NO_THREAD class QThreadPrivate : public QObjectPrivate { @@ -209,6 +179,38 @@ public: #endif // QT_NO_THREAD +class QThreadData +{ + QAtomicInt _ref; + +public: + QThreadData(int initialRefCount = 1); + ~QThreadData(); + + static QThreadData *current(); + static QThreadData *get2(QThread *thread) + { Q_ASSERT_X(thread != 0, "QThread", "internal error"); return thread->d_func()->data; } + + + void ref(); + void deref(); + + QThread *thread; + bool quitNow; + int loopLevel; + QAbstractEventDispatcher *eventDispatcher; + QStack eventLoops; + QPostEventList postEventList; + bool canWait; + QMap tls; + + QMutex mutex; + +# ifdef Q_OS_SYMBIAN + RThread symbian_thread_handle; +# endif +}; + // thread wrapper for the main() thread class QAdoptedThread : public QThread { -- cgit v0.12 From 30b0902cf05b0c1dc649e9c2e7ae0415e0c1d042 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 30 Oct 2009 12:35:49 +0100 Subject: Remove the unnecessary (and broken) tst_QMouseEvent::checkMouseMoveEvent() test According to people responsible for the test, it is not necessary. This partially reverts commit b1f9882fa52745c922eb0109daa011908214dcf7. --- tests/auto/qmouseevent/tst_qmouseevent.cpp | 75 ------------------------------ 1 file changed, 75 deletions(-) diff --git a/tests/auto/qmouseevent/tst_qmouseevent.cpp b/tests/auto/qmouseevent/tst_qmouseevent.cpp index d700181..b961851 100644 --- a/tests/auto/qmouseevent/tst_qmouseevent.cpp +++ b/tests/auto/qmouseevent/tst_qmouseevent.cpp @@ -62,7 +62,6 @@ public: } bool mousePressEventRecieved; bool mouseReleaseEventRecieved; - bool mouseMoveEventRecieved; #ifdef QT3_SUPPORT int mousePressStateBefore; int mousePressStateAfter; @@ -77,13 +76,6 @@ public: int mouseReleaseButton; int mouseReleaseButtons; int mouseReleaseModifiers; -#ifdef QT3_SUPPORT - int mouseMoveStateBefore; - int mouseMoveStateAfter; -#endif - int mouseMoveButton; - int mouseMoveButtons; - int mouseMoveModifiers; protected: void mousePressEvent(QMouseEvent *e) { @@ -111,19 +103,6 @@ protected: mouseReleaseEventRecieved = TRUE; e->accept(); } - void mouseMoveEvent(QMouseEvent *e) - { - QWidget::mouseMoveEvent(e); -#ifdef QT3_SUPPORT - mouseMoveStateBefore = e->state(); - mouseMoveStateAfter = e->stateAfter(); -#endif - mouseMoveButton = e->button(); - mouseMoveButtons = e->buttons(); - mouseMoveModifiers = e->modifiers(); - mouseMoveEventRecieved = TRUE; - e->accept(); - } }; class tst_QMouseEvent : public QObject @@ -145,8 +124,6 @@ private slots: void checkMousePressEvent(); void checkMouseReleaseEvent_data(); void checkMouseReleaseEvent(); - void checkMouseMoveEvent_data(); - void checkMouseMoveEvent(); void qt3supportConstructors(); @@ -180,14 +157,11 @@ void tst_QMouseEvent::init() { testMouseWidget->mousePressEventRecieved = FALSE; testMouseWidget->mouseReleaseEventRecieved = FALSE; - testMouseWidget->mouseMoveEventRecieved = FALSE; #ifdef QT3_SUPPORT testMouseWidget->mousePressStateBefore = 0; testMouseWidget->mousePressStateAfter = 0; testMouseWidget->mouseReleaseStateBefore = 0; testMouseWidget->mouseReleaseStateAfter = 0; - testMouseWidget->mouseMoveStateBefore = 0; - testMouseWidget->mouseMoveStateAfter = 0; #endif testMouseWidget->mousePressButton = 0; testMouseWidget->mousePressButtons = 0; @@ -195,9 +169,6 @@ void tst_QMouseEvent::init() testMouseWidget->mouseReleaseButton = 0; testMouseWidget->mouseReleaseButtons = 0; testMouseWidget->mouseReleaseModifiers = 0; - testMouseWidget->mouseMoveButton = 0; - testMouseWidget->mouseMoveButtons = 0; - testMouseWidget->mouseMoveModifiers = 0; } void tst_QMouseEvent::cleanup() @@ -294,52 +265,6 @@ void tst_QMouseEvent::checkMouseReleaseEvent() #endif } -void tst_QMouseEvent::checkMouseMoveEvent_data() -{ - QTest::addColumn("buttonMoved"); - QTest::addColumn("keyPressed"); - - QTest::newRow("leftButton-nokey") << int(Qt::LeftButton) << int(Qt::NoButton); - QTest::newRow("leftButton-shiftkey") << int(Qt::LeftButton) << int(Qt::ShiftModifier); - QTest::newRow("leftButton-controlkey") << int(Qt::LeftButton) << int(Qt::ControlModifier); - QTest::newRow("leftButton-altkey") << int(Qt::LeftButton) << int(Qt::AltModifier); - QTest::newRow("leftButton-metakey") << int(Qt::LeftButton) << int(Qt::MetaModifier); - QTest::newRow("rightButton-nokey") << int(Qt::RightButton) << int(Qt::NoButton); - QTest::newRow("rightButton-shiftkey") << int(Qt::RightButton) << int(Qt::ShiftModifier); - QTest::newRow("rightButton-controlkey") << int(Qt::RightButton) << int(Qt::ControlModifier); - QTest::newRow("rightButton-altkey") << int(Qt::RightButton) << int(Qt::AltModifier); - QTest::newRow("rightButton-metakey") << int(Qt::RightButton) << int(Qt::MetaModifier); - QTest::newRow("midButton-nokey") << int(Qt::MidButton) << int(Qt::NoButton); - QTest::newRow("midButton-shiftkey") << int(Qt::MidButton) << int(Qt::ShiftModifier); - QTest::newRow("midButton-controlkey") << int(Qt::MidButton) << int(Qt::ControlModifier); - QTest::newRow("midButton-altkey") << int(Qt::MidButton) << int(Qt::AltModifier); - QTest::newRow("midButton-metakey") << int(Qt::MidButton) << int(Qt::MetaModifier); -} - -void tst_QMouseEvent::checkMouseMoveEvent() -{ - QFETCH(int,buttonMoved); - QFETCH(int,keyPressed); - int button = (int)Qt::NoButton; - int buttons = buttonMoved; - int modifiers = keyPressed; - - QTest::mousePress(testMouseWidget, Qt::MouseButton(buttonMoved), Qt::KeyboardModifiers(keyPressed)); - QTest::mouseMove(testMouseWidget, QPoint(10,10)); - QVERIFY(testMouseWidget->mouseMoveEventRecieved); - QCOMPARE(testMouseWidget->mouseMoveButton, button); - QCOMPARE(testMouseWidget->mouseMoveButtons, buttons); - QCOMPARE(testMouseWidget->mouseMoveModifiers, modifiers); -#ifdef QT3_SUPPORT - int stateAfter = buttons|modifiers; - int stateBefore = stateAfter|button; - - QCOMPARE(testMouseWidget->mouseMoveStateBefore, stateBefore); - QCOMPARE(testMouseWidget->mouseMoveStateAfter, stateAfter); -#endif - QTest::mouseRelease(testMouseWidget, Qt::MouseButton(buttonMoved), Qt::KeyboardModifiers(keyPressed)); -} - void tst_QMouseEvent::qt3supportConstructors() { #if !defined(QT3_SUPPORT) -- cgit v0.12 From 85b7896a47f9bb622b394107769cb7c1121a6995 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 30 Oct 2009 12:40:13 +0100 Subject: QItemSelectionModel could emit selectionChanged with no change Task-number: QTBUG-560 Reviewed-by: ogoffart --- src/gui/itemviews/qitemselectionmodel.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/itemviews/qitemselectionmodel.cpp b/src/gui/itemviews/qitemselectionmodel.cpp index f2ccb6e..c6e02a6 100644 --- a/src/gui/itemviews/qitemselectionmodel.cpp +++ b/src/gui/itemviews/qitemselectionmodel.cpp @@ -1587,7 +1587,8 @@ void QItemSelectionModel::emitSelectionChanged(const QItemSelection &newSelectio } } - emit selectionChanged(selected, deselected); + if (!selected.isEmpty() || !deselected.isEmpty()) + emit selectionChanged(selected, deselected); } #ifndef QT_NO_DEBUG_STREAM -- cgit v0.12 From d025ebb1a8163cd1f03151927486cf62c5e77957 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 30 Oct 2009 09:55:20 +0100 Subject: Fixes regression in QComboBox with keypad navigation while mouse is over the popup The problem is that is we move the selection with the keyboard in a way that causes the view to scroll, the current selection would jump. This happends since commit 9cb231d773db6deb that fixed the emission of the enter signal when the view is scrolled. We Therefor cannot use the enter signal. Catch manually the mouse move events to update the selection instead. Reviewed-by: Thierry --- src/gui/widgets/qcombobox.cpp | 24 ++++------------ src/gui/widgets/qcombobox_p.h | 1 - tests/auto/qcombobox/tst_qcombobox.cpp | 52 ++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 19 deletions(-) diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index 6dbf15a..1879db4 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -489,18 +489,6 @@ void QComboBoxPrivateContainer::viewDestroyed() } /* - Sets currentIndex on entered if the LeftButton is not pressed. This - means that if mouseTracking(...) is on, we setCurrentIndex and select - even when LeftButton is not pressed. -*/ -void QComboBoxPrivateContainer::setCurrentIndex(const QModelIndex &index) -{ - if (QComboBoxDelegate::isSeparator(index)) - return; - view->setCurrentIndex(index); -} - -/* Returns the item view used for the combobox popup. */ QAbstractItemView *QComboBoxPrivateContainer::itemView() const @@ -525,8 +513,6 @@ void QComboBoxPrivateContainer::setItemView(QAbstractItemView *itemView) disconnect(view->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), this, SLOT(updateScrollers())); #endif - disconnect(view, SIGNAL(entered(QModelIndex)), - this, SLOT(setCurrentIndex(QModelIndex))); disconnect(view, SIGNAL(destroyed()), this, SLOT(viewDestroyed())); @@ -563,8 +549,6 @@ void QComboBoxPrivateContainer::setItemView(QAbstractItemView *itemView) connect(view->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), this, SLOT(updateScrollers())); #endif - connect(view, SIGNAL(entered(QModelIndex)), - this, SLOT(setCurrentIndex(QModelIndex))); connect(view, SIGNAL(destroyed()), this, SLOT(viewDestroyed())); @@ -655,16 +639,20 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e) break; } break; - case QEvent::MouseMove: { + case QEvent::MouseMove: if (isVisible()) { QMouseEvent *m = static_cast(e); QWidget *widget = static_cast(o); QPoint vector = widget->mapToGlobal(m->pos()) - initialClickPosition; if (vector.manhattanLength() > 9 && blockMouseReleaseTimer.isActive()) blockMouseReleaseTimer.stop(); + QModelIndex indexUnderMouse = view->indexAt(m->pos()); + if (indexUnderMouse.isValid() && indexUnderMouse != view->currentIndex() + && !QComboBoxDelegate::isSeparator(indexUnderMouse)) { + view->setCurrentIndex(indexUnderMouse); + } } break; - } case QEvent::MouseButtonRelease: { QMouseEvent *m = static_cast(e); if (isVisible() && view->rect().contains(m->pos()) && view->currentIndex().isValid() diff --git a/src/gui/widgets/qcombobox_p.h b/src/gui/widgets/qcombobox_p.h index 06e51e4..fe42c47 100644 --- a/src/gui/widgets/qcombobox_p.h +++ b/src/gui/widgets/qcombobox_p.h @@ -231,7 +231,6 @@ public: public Q_SLOTS: void scrollItemView(int action); void updateScrollers(); - void setCurrentIndex(const QModelIndex &index); void viewDestroyed(); protected: diff --git a/tests/auto/qcombobox/tst_qcombobox.cpp b/tests/auto/qcombobox/tst_qcombobox.cpp index 8acae7a..51a7ff8 100644 --- a/tests/auto/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/qcombobox/tst_qcombobox.cpp @@ -153,6 +153,7 @@ private slots: void task260974_menuItemRectangleForComboBoxPopup(); void removeItem(); void resetModel(); + void keyBoardNavigationWithMouse(); protected slots: void onEditTextChanged( const QString &newString ); @@ -2448,6 +2449,57 @@ void tst_QComboBox::resetModel() } +void tst_QComboBox::keyBoardNavigationWithMouse() +{ + QComboBox combo; + combo.setEditable(false); + for (int i = 0; i < 80; i++) + combo.addItem( QString::number(i)); + combo.show(); + QApplication::setActiveWindow(&combo); + QTest::qWaitForWindowShown(&combo); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(&combo)); + + QCOMPARE(combo.currentText(), QLatin1String("0")); + + combo.setFocus(); + QTRY_VERIFY(combo.hasFocus()); + + QTest::keyClick(testWidget->lineEdit(), Qt::Key_Space); + QTest::qWait(30); + QTRY_VERIFY(combo.view()); + QTRY_VERIFY(combo.view()->isVisible()); + QTest::qWait(130); + + QCOMPARE(combo.currentText(), QLatin1String("0")); + + QCursor::setPos(combo.view()->mapToGlobal(combo.view()->rect().center())); + QTest::qWait(200); + +#define GET_SELECTION(SEL) \ + QCOMPARE(combo.view()->selectionModel()->selection().count(), 1); \ + QCOMPARE(combo.view()->selectionModel()->selection().indexes().count(), 1); \ + SEL = combo.view()->selectionModel()->selection().indexes().first().row() + + int selection; + GET_SELECTION(selection); + + //since we moved the mouse is in the middle it should even be around 5; + QVERIFY(selection > 3); + + static const int final = 40; + for (int i = selection + 1; i <= final; i++) + { + QTest::keyClick(combo.view(), Qt::Key_Down); + QTest::qWait(20); + GET_SELECTION(selection); + QCOMPARE(selection, i); + } + + QTest::keyClick(combo.view(), Qt::Key_Enter); + QTRY_COMPARE(combo.currentText(), QString::number(final)); +} + QTEST_MAIN(tst_QComboBox) #include "tst_qcombobox.moc" -- cgit v0.12 From 79a7c969983eafeef67cce28724c3981cf3af1ea Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 29 Oct 2009 16:25:56 +0100 Subject: QTreeView: fix drawing branches of model that adds or remove rows dynamically The lasts commits in the treeview did put the flags weither item has child or is the last in cache in the viewItem vector. But the cache was not updated while the model is modified. Reviewed-by: Thierry --- src/gui/itemviews/qtreeview.cpp | 38 ++++++++++++- src/gui/itemviews/qtreeview_p.h | 3 +- tests/auto/qtreeview/tst_qtreeview.cpp | 101 +++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+), 4 deletions(-) diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index be64c46..3856293 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -2434,7 +2434,9 @@ void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end) return; } - if (parent != d->root && !d->isIndexExpanded(parent) && d->model->rowCount(parent) > (end - start) + 1) { + const int parentRowCount = d->model->rowCount(parent); + const int delta = end - start + 1; + if (parent != d->root && !d->isIndexExpanded(parent) && parentRowCount > delta) { QAbstractItemView::rowsInserted(parent, start, end); return; } @@ -2449,11 +2451,29 @@ void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end) ? d->viewItems.count() : d->viewItems.at(parentItem).total) - 1; - const int delta = end - start + 1; + if (parentRowCount == end + 1 && start > 0) { + //need to Update hasMoreSiblings + int previousRow = start - 1; + QModelIndex previousSibilingModelIndex = d->model->index(previousRow, 0, parent); + bool isHidden = d->isRowHidden(previousSibilingModelIndex); + while (isHidden && previousRow > 0) { + previousRow--; + previousSibilingModelIndex = d->model->index(previousRow, 0, parent); + isHidden = d->isRowHidden(previousSibilingModelIndex); + } + if (!isHidden) { + const int previousSibilling = d->viewIndex(previousSibilingModelIndex); + if(previousSibilling != -1) + d->viewItems[previousSibilling].hasMoreSiblings = true; + } + } + QVector insertedItems(delta); for (int i = 0; i < delta; ++i) { insertedItems[i].index = d->model->index(i + start, 0, parent); insertedItems[i].level = childLevel; + insertedItems[i].hasChildren = d->hasVisibleChildren(insertedItems[i].index); + insertedItems[i].hasMoreSiblings = !((i == delta - 1) && (parentRowCount == end +1)); } if (d->viewItems.isEmpty()) d->defaultItemHeight = indexRowSizeHint(insertedItems[0].index); @@ -2495,13 +2515,17 @@ void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end) d->viewItems.begin() + insertPos + 1); } + if (parentItem != -1) + d->viewItems[parentItem].hasChildren = true; d->updateChildCount(parentItem, delta); + updateGeometries(); viewport()->update(); } else if ((parentItem != -1) && d->viewItems.at(parentItem).expanded) { d->doDelayedItemsLayout(); } else if (parentItem != -1 && (d->model->rowCount(parent) == end - start + 1)) { - // the parent just went from 0 children to having some update to re-paint the decoration + // the parent just went from 0 children to more. update to re-paint the decoration + d->viewItems[parentItem].hasChildren = true; viewport()->update(); } QAbstractItemView::rowsInserted(parent, start, end); @@ -3706,6 +3730,7 @@ void QTreeViewPrivate::rowsRemoved(const QModelIndex &parent, const int delta = end - start + 1; + int previousSibiling = -1; int removedCount = 0; for (int item = firstChildItem; item <= lastChildItem; ) { Q_ASSERT(viewItems.at(item).level == childLevel); @@ -3713,6 +3738,7 @@ void QTreeViewPrivate::rowsRemoved(const QModelIndex &parent, //Q_ASSERT(modelIndex.parent() == parent); const int count = viewItems.at(item).total + 1; if (modelIndex.row() < start) { + previousSibiling = item; // not affected by the removal item += count; } else if (modelIndex.row() <= end) { @@ -3730,7 +3756,13 @@ void QTreeViewPrivate::rowsRemoved(const QModelIndex &parent, } } + if (previousSibiling != -1 && after && model->rowCount(parent) == start) + viewItems[previousSibiling].hasMoreSiblings = false; + + updateChildCount(parentItem, -removedCount); + if (parentItem != -1 && viewItems.at(parentItem).total == 0) + viewItems[parentItem].hasChildren = false; //every children have been removed; if (after) { q->updateGeometries(); viewport->update(); diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h index 62676d8..aad5837 100644 --- a/src/gui/itemviews/qtreeview_p.h +++ b/src/gui/itemviews/qtreeview_p.h @@ -62,7 +62,8 @@ QT_BEGIN_NAMESPACE struct QTreeViewItem { - QTreeViewItem() : expanded(false), spanning(false), total(0), level(0), height(0) {} + QTreeViewItem() : expanded(false), spanning(false), hasChildren(false), + hasMoreSiblings(false), total(0), level(0), height(0) {} QModelIndex index; // we remove items whenever the indexes are invalidated uint expanded : 1; uint spanning : 1; diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp index 75c02e9..90e6c5c 100644 --- a/tests/auto/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/qtreeview/tst_qtreeview.cpp @@ -2892,6 +2892,8 @@ void tst_QTreeView::styleOptionViewItem() QVERIFY(!opt.text.isEmpty()); QCOMPARE(opt.index, index); + //qDebug() << index << opt.text; + if (allCollapsed) QCOMPARE(!(opt.features & QStyleOptionViewItemV2::Alternate), !(index.row() % 2)); QCOMPARE(!(opt.features & QStyleOptionViewItemV2::HasCheckIndicator), !opt.text.contains("Checkable")); @@ -2979,9 +2981,108 @@ void tst_QTreeView::styleOptionViewItem() view.expandAll(); QApplication::processEvents(); QTRY_VERIFY(delegate.count >= 13); + delegate.count = 0; view.collapse(par2->index()); QApplication::processEvents(); QTRY_VERIFY(delegate.count >= 4); + + + //test dynamic models + { + delegate.count = 0; + QStandardItemModel model2; + QStandardItem *item0 = new QStandardItem("OnlyOne Last"); + model2.appendRow(QList() << item0); + view.setModel(&model2); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 1); + QApplication::processEvents(); + + QStandardItem *item00 = new QStandardItem("OnlyOne Last"); + item0->appendRow(QList() << item00); + item0->setText("OnlyOne Last HasChildren"); + QApplication::processEvents(); + delegate.count = 0; + view.expandAll(); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 2); + QApplication::processEvents(); + + QStandardItem *item1 = new QStandardItem("OnlyOne Last"); + delegate.count = 0; + item0->setText("OnlyOne HasChildren"); + model2.appendRow(QList() << item1); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 3); + QApplication::processEvents(); + + QStandardItem *item01 = new QStandardItem("OnlyOne Last"); + delegate.count = 0; + item00->setText("OnlyOne"); + item0->appendRow(QList() << item01); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 4); + QApplication::processEvents(); + + QStandardItem *item000 = new QStandardItem("OnlyOne Last"); + delegate.count = 0; + item00->setText("OnlyOne HasChildren"); + item00->appendRow(QList() << item000); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 5); + QApplication::processEvents(); + + delegate.count = 0; + item0->removeRow(0); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 3); + QApplication::processEvents(); + + item00 = new QStandardItem("OnlyOne"); + item0->insertRow(0, QList() << item00); + QApplication::processEvents(); + delegate.count = 0; + view.expandAll(); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 4); + QApplication::processEvents(); + + delegate.count = 0; + item0->removeRow(1); + item00->setText("OnlyOne Last"); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 3); + QApplication::processEvents(); + + delegate.count = 0; + item0->removeRow(0); + item0->setText("OnlyOne"); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 2); + QApplication::processEvents(); + + //with hidden items + item0->setText("OnlyOne HasChildren"); + item00 = new QStandardItem("OnlyOne"); + item0->appendRow(QList() << item00); + item01 = new QStandardItem("Assert"); + item0->appendRow(QList() << item01); + view.setRowHidden(1, item0->index(), true); + view.expandAll(); + QStandardItem *item02 = new QStandardItem("OnlyOne Last"); + item0->appendRow(QList() << item02); + delegate.count = 0; + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 4); + QApplication::processEvents(); + + item0->removeRow(2); + item00->setText("OnlyOne Last"); + delegate.count = 0; + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 3); + QApplication::processEvents(); + } } class task174627_TreeView : public QTreeView -- cgit v0.12 From 96799bf4da265835b5e574593bc5106712352ffc Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 30 Oct 2009 14:02:22 +0100 Subject: Update Polish translation --- translations/designer_pl.ts | 4 +- translations/linguist_pl.ts | 2 +- translations/qt_help_pl.ts | 58 +++++++++++++++++-------- translations/qt_pl.ts | 102 ++++++++++++++++++++++++-------------------- 4 files changed, 99 insertions(+), 67 deletions(-) diff --git a/translations/designer_pl.ts b/translations/designer_pl.ts index 0c196d8..f9c6dd0 100644 --- a/translations/designer_pl.ts +++ b/translations/designer_pl.ts @@ -6103,7 +6103,7 @@ Klasa: %2 Change toolTip... - Zmień tekst chmurki... + Zmień podpowiedź... @@ -6909,7 +6909,7 @@ Klasa: %2 Expand all - Rozszerz wszystkie + Rozwiń wszystkie diff --git a/translations/linguist_pl.ts b/translations/linguist_pl.ts index b59ebc3..cdff54b 100644 --- a/translations/linguist_pl.ts +++ b/translations/linguist_pl.ts @@ -312,7 +312,7 @@ Przyjmie on uniwersalną formę liczby pojedynczej. LRelease - + Dropped %n message(s) which had no ID. Opuszczono %n wyrażenie które nie miało identyfikatora. diff --git a/translations/qt_help_pl.ts b/translations/qt_help_pl.ts index 0e6bbbf..220f70c 100644 --- a/translations/qt_help_pl.ts +++ b/translations/qt_help_pl.ts @@ -32,33 +32,61 @@ QHelpCollectionHandler - The collection file is not set up yet! - Plik z kolekcją nie jest jeszcze ustawiony! + Plik z kolekcją nie jest jeszcze ustawiony! - + + The collection file '%1' is not set up yet! + + + + Cannot load sqlite database driver! Nie można załadować sterownika bazy danych sqlite! - + Cannot open collection file: %1 Nie można otworzyć pliku z kolekcją: %1 - + Cannot create tables in file %1! Nie można utworzyć tabel w pliku %1! + The collection file '%1' already exists! + + + + + Unknown filter '%1'! + + + + + Invalid documentation file '%1'! + + + + + Cannot register namespace '%1'! + + + + + Cannot open database '%1' to optimize! + + + The specified collection file already exists! - Podany plik z kolekcją już istnieje! + Podany plik z kolekcją już istnieje! - + Cannot create directory: %1 Nie można utworzyć katalogu: %1 @@ -68,12 +96,11 @@ Nie można skopiować pliku z kolekcją: %1 - Unknown filter! - Nieznany filtr! + Nieznany filtr! - + Cannot register filter %1! Nie można zarejestrować pliku %1! @@ -83,12 +110,11 @@ Nie można otworzyć pliku z dokumentacją %1! - Invalid documentation file! - Niepoprawny plik z dokumentacją! + Niepoprawny plik z dokumentacją! - + The namespace %1 was not registered! Przestrzeń nazw %1 nie została zarejestrowana! @@ -98,14 +124,12 @@ Przestrzeń nazw %1 już istnieje! - Cannot register namespace! - Nie można zarejestrować przestrzeni nazw! + Nie można zarejestrować przestrzeni nazw! - Cannot open database to optimize! - Nie można otworzyć bazy danych do zoptymalizowania! + Nie można otworzyć bazy danych do zoptymalizowania! diff --git a/translations/qt_pl.ts b/translations/qt_pl.ts index 424fd31..f79ecb0 100644 --- a/translations/qt_pl.ts +++ b/translations/qt_pl.ts @@ -12,7 +12,7 @@ FakeReply - + Fake error ! @@ -932,7 +932,7 @@ na Operacja na gnieździe nieobsługiwana - + Socket is not connected Gniazdo nie jest podłączone @@ -966,6 +966,14 @@ na + QAccessibleButton + + + Press + Wciśnij + + + QApplication @@ -988,7 +996,7 @@ na Niekompatybilność biblioteki Qt - + QT_LAYOUT_DIRECTION Translate this string to the string 'LTR' in left-to-right languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout. LTR @@ -1020,7 +1028,7 @@ na QCheckBox - + Check Zaznacz @@ -1276,7 +1284,7 @@ na QDialogButtonBox - + Abort Przerwij @@ -1472,7 +1480,7 @@ na Błąd krytyczny: - + &OK &OK @@ -1482,7 +1490,7 @@ na &Pokaż ten komunikat ponownie - + Warning: Ostrzeżenie: @@ -1851,52 +1859,52 @@ Proszę o sprawdzenie podanej nazwy pliku. QFontDatabase - + Normal Normalny - + - + Bold Pogrubiony - - + + Demi Bold Na wpół pogrubiony - + - + Black it's about font weight Bardzo gruby - + Demi Na wpół - + Light it's about font weight Cienki - - + + Italic Kursywa - - + + Oblique Pochyły @@ -2340,7 +2348,7 @@ Proszę o sprawdzenie podanej nazwy pliku. Host %1 znaleziony - + Host %1 not found @@ -2360,7 +2368,7 @@ Proszę o sprawdzenie podanej nazwy pliku. Komenda HTTP zakończona błędem - + @@ -2374,7 +2382,7 @@ Proszę o sprawdzenie podanej nazwy pliku. Niepoprawny nagłówek odpowiedzi HTTP - + No server set to connect to Brak serwera do podłączenia @@ -2411,7 +2419,7 @@ Proszę o sprawdzenie podanej nazwy pliku. Błędna długość zawartości - + Unknown authentication method Nieznana metoda autoryzacji @@ -2456,7 +2464,7 @@ Proszę o sprawdzenie podanej nazwy pliku. Nawiązanie sesji SSL nie powiodło się - + Connection refused (or timed out) Połączenie odrzucone (przekroczony czas połączenia) @@ -3105,7 +3113,7 @@ Proszę o sprawdzenie podanej nazwy pliku. QMenuBar - + Actions Akcje @@ -4361,7 +4369,7 @@ Proszę wybrać inną nazwę pliku. Selection - Wybór + Wybrane strony @@ -4449,7 +4457,7 @@ Proszę wybrać inną nazwę pliku. Location: - Lokalizacja: + Położenie: @@ -4505,7 +4513,7 @@ Proszę wybrać inną nazwę pliku. Przekroczony czas operacji procesu - + @@ -4726,7 +4734,7 @@ Proszę wybrać inną nazwę pliku. Location - Miejsce + Położenie @@ -4967,7 +4975,7 @@ Proszę wybrać inną nazwę pliku. Location - Miejsce + Położenie @@ -5847,7 +5855,7 @@ Proszę wybrać inną nazwę pliku. Anuluj - + Exit Wyjście @@ -6071,7 +6079,7 @@ Proszę wybrać inną nazwę pliku. QTextControl - + &Copy S&kopiuj @@ -6114,7 +6122,7 @@ Proszę wybrać inną nazwę pliku. QToolButton - + Open Otwórz @@ -6229,7 +6237,7 @@ Proszę wybrać inną nazwę pliku. QWebFrame - + Request cancelled Prośba anulowana @@ -6262,7 +6270,7 @@ Proszę wybrać inną nazwę pliku. QWebPage - + Submit default label for Submit buttons in forms on web pages Wyślij @@ -6280,7 +6288,7 @@ Proszę wybrać inną nazwę pliku. Wyczyść - + Choose File title for file button used in HTML forms Wybierz plik @@ -6766,12 +6774,12 @@ Proszę wybrać inną nazwę pliku. Nieznany - + Web Inspector - %2 Wizytator sieciowy - %2 - + Bad HTTP request Niepoprawna komenda HTTP @@ -6875,7 +6883,7 @@ Proszę wybrać inną nazwę pliku. - + JavaScript Alert - %1 Ostrzeżenie JavaScript - %1 @@ -7121,7 +7129,7 @@ Proszę wybrać inną nazwę pliku. QWidget - + * * @@ -9596,32 +9604,32 @@ Proszę wybrać inną nazwę pliku. Duration content does not match the maxInclusive facet. - Wartość czasu trwania koliduje z aspektem "maxInclusive". + Wartość długości okresu czasu koliduje z aspektem "maxInclusive". Duration content does not match the maxExclusive facet. - Wartość czasu trwania koliduje z aspektem "maxExclusive". + Wartość długości okresu czasu koliduje z aspektem "maxExclusive". Duration content does not match the minInclusive facet. - Wartość czasu trwania koliduje z aspektem "minInclusive". + Wartość długości okresu czasu koliduje z aspektem "minInclusive". Duration content does not match the minExclusive facet. - Wartość czasu trwania koliduje z aspektem "minExclusive". + Wartość długości okresu czasu koliduje z aspektem "minExclusive". Duration content is not listed in the enumeration facet. - Wartość czasu trwania nie widnieje na liście aspektu "enumeration". + Wartość długości okresu czasu nie widnieje na liście aspektu "enumeration". Duration content does not match pattern facet. - Wartość czasu trwania koliduje z aspektem "pattern". + Wartość długości okresu czasu koliduje z aspektem "pattern". -- cgit v0.12 From 8097fa53b5e0e6228bd5737de6de8cd77c04dddf Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 30 Oct 2009 13:23:28 +0100 Subject: Add QScriptString::toArrayIndex() function Avoid hacking a custom toArrayIndex() in the example; instead provide an ECMA-compliant conversion that's as fast as possible (having to convert the QScriptString to a QString and then convert the result to a number is considerably slower than calling JSC's Identifier::toArrayIndex() function directly). Reviewed-by: Olivier Goffart --- examples/script/customclass/bytearrayclass.cpp | 17 +++--------- src/script/api/qscriptstring.cpp | 29 ++++++++++++++++++++ src/script/api/qscriptstring.h | 2 ++ tests/auto/qscriptstring/tst_qscriptstring.cpp | 37 ++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 14 deletions(-) diff --git a/examples/script/customclass/bytearrayclass.cpp b/examples/script/customclass/bytearrayclass.cpp index 7291b97..bce69e4 100644 --- a/examples/script/customclass/bytearrayclass.cpp +++ b/examples/script/customclass/bytearrayclass.cpp @@ -72,18 +72,6 @@ private: int m_last; }; -static qint32 toArrayIndex(const QString &str) -{ - QByteArray bytes = str.toUtf8(); - char *eptr; - quint32 pos = strtoul(bytes.constData(), &eptr, 10); - if ((eptr == bytes.constData() + bytes.size()) - && (QByteArray::number(pos) == bytes)) { - return pos; - } - return -1; -} - //! [0] ByteArrayClass::ByteArrayClass(QScriptEngine *engine) : QObject(engine), QScriptClass(engine) @@ -120,8 +108,9 @@ QScriptClass::QueryFlags ByteArrayClass::queryProperty(const QScriptValue &objec if (name == length) { return flags; } else { - qint32 pos = toArrayIndex(name); - if (pos == -1) + bool isArrayIndex; + qint32 pos = name.toArrayIndex(&isArrayIndex); + if (!isArrayIndex) return 0; *id = pos; if ((flags & HandlesReadAccess) && (pos >= ba->size())) diff --git a/src/script/api/qscriptstring.cpp b/src/script/api/qscriptstring.cpp index 1ede51c..10fccd0 100644 --- a/src/script/api/qscriptstring.cpp +++ b/src/script/api/qscriptstring.cpp @@ -68,6 +68,10 @@ QT_BEGIN_NAMESPACE Call the toString() function to obtain the string that a QScriptString represents. + + Call the toArrayIndex() function to convert a QScriptString to an + array index. This is useful when using QScriptClass to implement + array-like objects. */ /*! @@ -164,6 +168,31 @@ bool QScriptString::operator!=(const QScriptString &other) const } /*! + \since 4.6 + + Attempts to convert this QScriptString to a QtScript array index, + and returns the result. + + If a conversion error occurs, *\a{ok} is set to false; otherwise + *\a{ok} is set to true. +*/ +quint32 QScriptString::toArrayIndex(bool *ok) const +{ + Q_D(const QScriptString); + if (!d) { + if (ok) + *ok = false; + return -1; + } + bool tmp; + bool *okok = ok ? ok : &tmp; + quint32 result = d->identifier.toArrayIndex(okok); + if (!*okok) + result = -1; + return result; +} + +/*! Returns the string that this QScriptString represents, or a null string if this QScriptString is not valid. diff --git a/src/script/api/qscriptstring.h b/src/script/api/qscriptstring.h index 40d156c..bf5d1d5 100644 --- a/src/script/api/qscriptstring.h +++ b/src/script/api/qscriptstring.h @@ -67,6 +67,8 @@ public: bool operator==(const QScriptString &other) const; bool operator!=(const QScriptString &other) const; + quint32 toArrayIndex(bool *ok = 0) const; + QString toString() const; operator QString() const; diff --git a/tests/auto/qscriptstring/tst_qscriptstring.cpp b/tests/auto/qscriptstring/tst_qscriptstring.cpp index e1a4bc1..1229f4a 100644 --- a/tests/auto/qscriptstring/tst_qscriptstring.cpp +++ b/tests/auto/qscriptstring/tst_qscriptstring.cpp @@ -59,6 +59,8 @@ public: private slots: void test(); void hash(); + void toArrayIndex_data(); + void toArrayIndex(); }; tst_QScriptString::tst_QScriptString() @@ -155,5 +157,40 @@ void tst_QScriptString::hash() QCOMPARE(stringToInt.value(foo), 123); } +void tst_QScriptString::toArrayIndex_data() +{ + QTest::addColumn("input"); + QTest::addColumn("expectSuccess"); + QTest::addColumn("expectedIndex"); + QTest::newRow("foo") << QString::fromLatin1("foo") << false << quint32(0xffffffff); + QTest::newRow("empty") << QString::fromLatin1("") << false << quint32(0xffffffff); + QTest::newRow("0") << QString::fromLatin1("0") << true << quint32(0); + QTest::newRow("00") << QString::fromLatin1("00") << false << quint32(0xffffffff); + QTest::newRow("1") << QString::fromLatin1("1") << true << quint32(1); + QTest::newRow("123") << QString::fromLatin1("123") << true << quint32(123); + QTest::newRow("-1") << QString::fromLatin1("-1") << false << quint32(0xffffffff); + QTest::newRow("0a") << QString::fromLatin1("0a") << false << quint32(0xffffffff); + QTest::newRow("0x1") << QString::fromLatin1("0x1") << false << quint32(0xffffffff); + QTest::newRow("01") << QString::fromLatin1("01") << false << quint32(0xffffffff); + QTest::newRow("4294967294") << QString::fromLatin1("4294967294") << true << quint32(0xfffffffe); + QTest::newRow("4294967295") << QString::fromLatin1("4294967295") << false << quint32(0xffffffff); +} + +void tst_QScriptString::toArrayIndex() +{ + QFETCH(QString, input); + QFETCH(bool, expectSuccess); + QFETCH(quint32, expectedIndex); + QScriptEngine engine; + for (int x = 0; x < 2; ++x) { + bool isArrayIndex; + bool *ptr = (x == 0) ? &isArrayIndex : (bool*)0; + quint32 result = engine.toStringHandle(input).toArrayIndex(ptr); + if (x == 0) + QCOMPARE(isArrayIndex, expectSuccess); + QCOMPARE(result, expectedIndex); + } +} + QTEST_MAIN(tst_QScriptString) #include "tst_qscriptstring.moc" -- cgit v0.12 From e2b6e32fe128f094a47dad2be6b2ee797bfe3ff4 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 30 Oct 2009 17:16:49 +0100 Subject: Reduced file sizes. SVG graphics may contain much unneeded stuff. I used Inkscape's vacuum function and Ariya's svgmin. Much better now. Reviewed-By: trustme --- .../weatherinfo/icons/weather-few-clouds.svg | 791 +-- demos/embedded/weatherinfo/icons/weather-fog.svg | 1643 +----- demos/embedded/weatherinfo/icons/weather-haze.svg | 1231 +---- demos/embedded/weatherinfo/icons/weather-icy.svg | 278 +- .../weatherinfo/icons/weather-overcast.svg | 3131 +----------- .../embedded/weatherinfo/icons/weather-showers.svg | 4850 +----------------- demos/embedded/weatherinfo/icons/weather-sleet.svg | 5332 +------------------- demos/embedded/weatherinfo/icons/weather-snow.svg | 2076 +------- demos/embedded/weatherinfo/icons/weather-storm.svg | 4420 +--------------- .../icons/weather-sunny-very-few-clouds.svg | 626 +-- demos/embedded/weatherinfo/icons/weather-sunny.svg | 1328 +---- .../weatherinfo/icons/weather-thundershower.svg | 4725 +---------------- 12 files changed, 1446 insertions(+), 28985 deletions(-) diff --git a/demos/embedded/weatherinfo/icons/weather-few-clouds.svg b/demos/embedded/weatherinfo/icons/weather-few-clouds.svg index 57d45e9..a53e3d6 100644 --- a/demos/embedded/weatherinfo/icons/weather-few-clouds.svg +++ b/demos/embedded/weatherinfo/icons/weather-few-clouds.svg @@ -1,337 +1,70 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - - + + + + + - - - - - + + + + + - - - - + + + + - - - + + + - - + + - + image/svg+xml - + weather-clear January 2006 @@ -352,386 +85,88 @@ notification - + Garrett LeSage - - - - + + + + - - - - - - - + + + + + + + - - - - - + + + + + - - - + + + - - - + + + - - - - - + + + + + - - - - + + + + - - - - - + + + + + - - - - - - + + + + + + - - - - - + + + + + - - - + + + - - - + + + - - - - - + + + + + diff --git a/demos/embedded/weatherinfo/icons/weather-fog.svg b/demos/embedded/weatherinfo/icons/weather-fog.svg index a9a4ca8..56a2444 100644 --- a/demos/embedded/weatherinfo/icons/weather-fog.svg +++ b/demos/embedded/weatherinfo/icons/weather-fog.svg @@ -1,1585 +1,114 @@ - - - - - - + + + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - + + - + image/svg+xml - + - - - - - - - - + + + + + + + + - - - - - + + + + + - - - + + + - - - + + + - - - - - + + + + + - - - - - - - + + + + + + + - - - - - + + + + + - - - + + + - - - + + + - - - - - + + + + + - + diff --git a/demos/embedded/weatherinfo/icons/weather-haze.svg b/demos/embedded/weatherinfo/icons/weather-haze.svg index f2d6671..b31811f 100644 --- a/demos/embedded/weatherinfo/icons/weather-haze.svg +++ b/demos/embedded/weatherinfo/icons/weather-haze.svg @@ -1,1121 +1,162 @@ - - - - - - - + + + + + + - - - + + + - - - + + + - - - + + + + - - - + + + - - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + - + - + image/svg+xml - + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - + + + + - - + + diff --git a/demos/embedded/weatherinfo/icons/weather-icy.svg b/demos/embedded/weatherinfo/icons/weather-icy.svg index fe42860..2c45b33 100644 --- a/demos/embedded/weatherinfo/icons/weather-icy.svg +++ b/demos/embedded/weatherinfo/icons/weather-icy.svg @@ -1,255 +1,51 @@ - - - - - - + + + + + - - - + + + - - - + + + - - - + + + - - - - - - + + + + + - - + + - + image/svg+xml - + - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/demos/embedded/weatherinfo/icons/weather-overcast.svg b/demos/embedded/weatherinfo/icons/weather-overcast.svg index 35fb4a4..cf77214 100644 --- a/demos/embedded/weatherinfo/icons/weather-overcast.svg +++ b/demos/embedded/weatherinfo/icons/weather-overcast.svg @@ -1,2554 +1,81 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + image/svg+xml - + weather-overcast January 2006 @@ -2569,466 +96,94 @@ notify - + - - - - + + + + - - - - - - - - + + + + + + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - - - - + + + + + + - - - - - + + + + + - - - + + + - - - + + + - - - - - + + + + + - - - - - - + + + + + + - - - - - + + + + + - - - + + + - - - + + + - - - - - + + + + + diff --git a/demos/embedded/weatherinfo/icons/weather-showers.svg b/demos/embedded/weatherinfo/icons/weather-showers.svg index c814571..017665d 100644 --- a/demos/embedded/weatherinfo/icons/weather-showers.svg +++ b/demos/embedded/weatherinfo/icons/weather-showers.svg @@ -1,4297 +1,83 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + image/svg+xml - + weather-showers January 2006 @@ -4312,441 +98,81 @@ notify - + - - - - + + + + - - - - - - - + + + + + + + - - - - - - - - + + + + + + + + - - - + + + - - - + + + - - - + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/demos/embedded/weatherinfo/icons/weather-sleet.svg b/demos/embedded/weatherinfo/icons/weather-sleet.svg index f1cb9eb..bf2306f 100644 --- a/demos/embedded/weatherinfo/icons/weather-sleet.svg +++ b/demos/embedded/weatherinfo/icons/weather-sleet.svg @@ -1,4573 +1,96 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + image/svg+xml - + weather-showers January 2006 @@ -4588,608 +111,119 @@ notify - + - - - - - - - + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - + + + - - - + + + - - - + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - - - - - + + + + + + + + diff --git a/demos/embedded/weatherinfo/icons/weather-snow.svg b/demos/embedded/weatherinfo/icons/weather-snow.svg index 6c7b4ad..a91946f 100644 --- a/demos/embedded/weatherinfo/icons/weather-snow.svg +++ b/demos/embedded/weatherinfo/icons/weather-snow.svg @@ -1,1418 +1,81 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + image/svg+xml - + weather-snow January 2006 @@ -1433,542 +96,105 @@ notification - + - - - - + + + + - - - - - - - - + + + + + + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - - - - + + + + + + - - - - - + + + + + - - - + + + - - - + + + - - - - - + + + + + - - - - - - + + + + + + - - - - - + + + + + - - - + + + - - - + + + - - - - - + + + + + - - - - - - - - + + + + + + + + diff --git a/demos/embedded/weatherinfo/icons/weather-storm.svg b/demos/embedded/weatherinfo/icons/weather-storm.svg index 4d8bfec..1ad47ab 100644 --- a/demos/embedded/weatherinfo/icons/weather-storm.svg +++ b/demos/embedded/weatherinfo/icons/weather-storm.svg @@ -1,3851 +1,94 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + image/svg+xml - + weather-storm January 2006 @@ -3866,443 +109,82 @@ notify - + - - - - + + + + - - - - - - - - + + + + + + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - + diff --git a/demos/embedded/weatherinfo/icons/weather-sunny-very-few-clouds.svg b/demos/embedded/weatherinfo/icons/weather-sunny-very-few-clouds.svg index 93b0009..a27d30a 100644 --- a/demos/embedded/weatherinfo/icons/weather-sunny-very-few-clouds.svg +++ b/demos/embedded/weatherinfo/icons/weather-sunny-very-few-clouds.svg @@ -1,337 +1,63 @@ - - - - - - - - - - - - - - - + + + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - - + + + + + - - - - - + + + + + - - - - + + + + - - - + + + - - + + - + image/svg+xml - + weather-clear January 2006 @@ -352,241 +78,63 @@ notification - + Garrett LeSage - - - - - - - + + + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - - + + + + + + - - - - - + + + + + - - - + + + - - - + + + - - - - - + + + + + diff --git a/demos/embedded/weatherinfo/icons/weather-sunny.svg b/demos/embedded/weatherinfo/icons/weather-sunny.svg index 0360ac7..248199c 100644 --- a/demos/embedded/weatherinfo/icons/weather-sunny.svg +++ b/demos/embedded/weatherinfo/icons/weather-sunny.svg @@ -1,1225 +1,32 @@ - - - - - - - - + + + + + + - - - - - + + + + + - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - + + - + image/svg+xml - + weather-clear January 2006 @@ -1240,89 +47,34 @@ notification - + Garrett LeSage - - - - - - - + + + + + + + - - - - - + + + + + - - - - - + + + + + diff --git a/demos/embedded/weatherinfo/icons/weather-thundershower.svg b/demos/embedded/weatherinfo/icons/weather-thundershower.svg index 406abfa..e1c2286 100644 --- a/demos/embedded/weatherinfo/icons/weather-thundershower.svg +++ b/demos/embedded/weatherinfo/icons/weather-thundershower.svg @@ -1,4064 +1,108 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + image/svg+xml - + weather-storm January 2006 @@ -4079,508 +123,101 @@ notify - + - - - - - - - + + + + + + + - - - - - - - - - + + + + + + + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - + + + + - - - - + + + + -- cgit v0.12 From d5254dde567ef493d4df079a709b54c85e604a18 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 30 Oct 2009 17:18:02 +0100 Subject: Reducing file sizes. Using pngout to make the fluidlauncher a bit lighter. Reviewed-by: trustme --- .../fluidlauncher/screenshots/context2d_s60.png | Bin 39405 -> 39185 bytes .../screenshots/desktopservices_s60.png | Bin 31757 -> 31504 bytes .../fluidlauncher/screenshots/digiflip.png | Bin 3508 -> 2039 bytes .../fluidlauncher/screenshots/flickable.png | Bin 21107 -> 14141 bytes .../fluidlauncher/screenshots/flightinfo_s60.png | Bin 24473 -> 20482 bytes .../fluidlauncher/screenshots/lightmaps.png | Bin 114178 -> 79501 bytes .../fluidlauncher/screenshots/mediaplayer.png | Bin 98092 -> 80411 bytes .../fluidlauncher/screenshots/raycasting.png | Bin 43006 -> 11984 bytes .../fluidlauncher/screenshots/weatherinfo.png | Bin 38521 -> 34472 bytes demos/embedded/fluidlauncher/slides/demo_1.png | Bin 23539 -> 20560 bytes demos/embedded/fluidlauncher/slides/demo_2.png | Bin 11745 -> 5209 bytes demos/embedded/fluidlauncher/slides/demo_5.png | Bin 15890 -> 6130 bytes demos/embedded/fluidlauncher/slides/demo_6.png | Bin 14992 -> 5826 bytes 13 files changed, 0 insertions(+), 0 deletions(-) diff --git a/demos/embedded/fluidlauncher/screenshots/context2d_s60.png b/demos/embedded/fluidlauncher/screenshots/context2d_s60.png index c7225c7..9c288c9 100644 Binary files a/demos/embedded/fluidlauncher/screenshots/context2d_s60.png and b/demos/embedded/fluidlauncher/screenshots/context2d_s60.png differ diff --git a/demos/embedded/fluidlauncher/screenshots/desktopservices_s60.png b/demos/embedded/fluidlauncher/screenshots/desktopservices_s60.png index a429be3..64018f4 100644 Binary files a/demos/embedded/fluidlauncher/screenshots/desktopservices_s60.png and b/demos/embedded/fluidlauncher/screenshots/desktopservices_s60.png differ diff --git a/demos/embedded/fluidlauncher/screenshots/digiflip.png b/demos/embedded/fluidlauncher/screenshots/digiflip.png index 117b61b..c31a6f8 100644 Binary files a/demos/embedded/fluidlauncher/screenshots/digiflip.png and b/demos/embedded/fluidlauncher/screenshots/digiflip.png differ diff --git a/demos/embedded/fluidlauncher/screenshots/flickable.png b/demos/embedded/fluidlauncher/screenshots/flickable.png index 7080fc1..bad14bf 100644 Binary files a/demos/embedded/fluidlauncher/screenshots/flickable.png and b/demos/embedded/fluidlauncher/screenshots/flickable.png differ diff --git a/demos/embedded/fluidlauncher/screenshots/flightinfo_s60.png b/demos/embedded/fluidlauncher/screenshots/flightinfo_s60.png index 8a304eb..8e74d77 100644 Binary files a/demos/embedded/fluidlauncher/screenshots/flightinfo_s60.png and b/demos/embedded/fluidlauncher/screenshots/flightinfo_s60.png differ diff --git a/demos/embedded/fluidlauncher/screenshots/lightmaps.png b/demos/embedded/fluidlauncher/screenshots/lightmaps.png index 7cbe2e4..18aa74d 100644 Binary files a/demos/embedded/fluidlauncher/screenshots/lightmaps.png and b/demos/embedded/fluidlauncher/screenshots/lightmaps.png differ diff --git a/demos/embedded/fluidlauncher/screenshots/mediaplayer.png b/demos/embedded/fluidlauncher/screenshots/mediaplayer.png index 2d8a637..c9fd43c 100644 Binary files a/demos/embedded/fluidlauncher/screenshots/mediaplayer.png and b/demos/embedded/fluidlauncher/screenshots/mediaplayer.png differ diff --git a/demos/embedded/fluidlauncher/screenshots/raycasting.png b/demos/embedded/fluidlauncher/screenshots/raycasting.png index d3c86e9..b6b738a 100644 Binary files a/demos/embedded/fluidlauncher/screenshots/raycasting.png and b/demos/embedded/fluidlauncher/screenshots/raycasting.png differ diff --git a/demos/embedded/fluidlauncher/screenshots/weatherinfo.png b/demos/embedded/fluidlauncher/screenshots/weatherinfo.png index b18608d..7e23891 100644 Binary files a/demos/embedded/fluidlauncher/screenshots/weatherinfo.png and b/demos/embedded/fluidlauncher/screenshots/weatherinfo.png differ diff --git a/demos/embedded/fluidlauncher/slides/demo_1.png b/demos/embedded/fluidlauncher/slides/demo_1.png index d2952e5..d53d19d 100644 Binary files a/demos/embedded/fluidlauncher/slides/demo_1.png and b/demos/embedded/fluidlauncher/slides/demo_1.png differ diff --git a/demos/embedded/fluidlauncher/slides/demo_2.png b/demos/embedded/fluidlauncher/slides/demo_2.png index 1899825..f137de0 100644 Binary files a/demos/embedded/fluidlauncher/slides/demo_2.png and b/demos/embedded/fluidlauncher/slides/demo_2.png differ diff --git a/demos/embedded/fluidlauncher/slides/demo_5.png b/demos/embedded/fluidlauncher/slides/demo_5.png index 239f08a..0bb1781 100644 Binary files a/demos/embedded/fluidlauncher/slides/demo_5.png and b/demos/embedded/fluidlauncher/slides/demo_5.png differ diff --git a/demos/embedded/fluidlauncher/slides/demo_6.png b/demos/embedded/fluidlauncher/slides/demo_6.png index 0addf37..9daba67 100644 Binary files a/demos/embedded/fluidlauncher/slides/demo_6.png and b/demos/embedded/fluidlauncher/slides/demo_6.png differ -- cgit v0.12 From 9fd3e4746d9b65fa049664ce6d075f1027443fef Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 30 Oct 2009 17:19:34 +0100 Subject: Reducing file sizes. Using pngout to make the fluidlauncher a bit lighter. And to reduce Anomalies memory footprint. Reviewed-by: trustme --- demos/embedded/anomaly/src/images/edit-find.png | Bin 1636 -> 1495 bytes demos/embedded/anomaly/src/images/go-next.png | Bin 1219 -> 1150 bytes demos/embedded/anomaly/src/images/go-previous.png | Bin 1200 -> 1135 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/demos/embedded/anomaly/src/images/edit-find.png b/demos/embedded/anomaly/src/images/edit-find.png index 5594785..b84b1e2 100644 Binary files a/demos/embedded/anomaly/src/images/edit-find.png and b/demos/embedded/anomaly/src/images/edit-find.png differ diff --git a/demos/embedded/anomaly/src/images/go-next.png b/demos/embedded/anomaly/src/images/go-next.png index a68e2db..ed89a36 100644 Binary files a/demos/embedded/anomaly/src/images/go-next.png and b/demos/embedded/anomaly/src/images/go-next.png differ diff --git a/demos/embedded/anomaly/src/images/go-previous.png b/demos/embedded/anomaly/src/images/go-previous.png index c37bc04..44e803d 100644 Binary files a/demos/embedded/anomaly/src/images/go-previous.png and b/demos/embedded/anomaly/src/images/go-previous.png differ -- cgit v0.12 From 9b2d899499c60535a1c9af6dcc48dfa5184dd363 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 30 Oct 2009 17:19:57 +0100 Subject: Reducing file sizes. Using pngout to make the fluidlauncher a bit lighter. Reviewed-by: trustme --- demos/embedded/desktopservices/data/designer.png | Bin 4205 -> 2529 bytes demos/embedded/desktopservices/resources/browser.png | Bin 2739 -> 2525 bytes demos/embedded/desktopservices/resources/message.png | Bin 2234 -> 1989 bytes demos/embedded/desktopservices/resources/music.png | Bin 2322 -> 2123 bytes demos/embedded/desktopservices/resources/photo.png | Bin 2430 -> 2233 bytes 5 files changed, 0 insertions(+), 0 deletions(-) diff --git a/demos/embedded/desktopservices/data/designer.png b/demos/embedded/desktopservices/data/designer.png index 0988fce..1485efa 100644 Binary files a/demos/embedded/desktopservices/data/designer.png and b/demos/embedded/desktopservices/data/designer.png differ diff --git a/demos/embedded/desktopservices/resources/browser.png b/demos/embedded/desktopservices/resources/browser.png index 28561e1..9ecda6b 100644 Binary files a/demos/embedded/desktopservices/resources/browser.png and b/demos/embedded/desktopservices/resources/browser.png differ diff --git a/demos/embedded/desktopservices/resources/message.png b/demos/embedded/desktopservices/resources/message.png index e30052b..78917c7 100644 Binary files a/demos/embedded/desktopservices/resources/message.png and b/demos/embedded/desktopservices/resources/message.png differ diff --git a/demos/embedded/desktopservices/resources/music.png b/demos/embedded/desktopservices/resources/music.png index 11a57bb..cc569cb 100644 Binary files a/demos/embedded/desktopservices/resources/music.png and b/demos/embedded/desktopservices/resources/music.png differ diff --git a/demos/embedded/desktopservices/resources/photo.png b/demos/embedded/desktopservices/resources/photo.png index 5ba15c1..ac81cf3 100644 Binary files a/demos/embedded/desktopservices/resources/photo.png and b/demos/embedded/desktopservices/resources/photo.png differ -- cgit v0.12 From 9440e6a1b3ce4da0a832afeef23e69d9fc55bb47 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 30 Oct 2009 17:20:08 +0100 Subject: Reducing file sizes. Using pngout to make the fluidlauncher a bit lighter. Reviewed-by: trustme --- demos/embedded/flightinfo/aircraft.png | Bin 28713 -> 20200 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/demos/embedded/flightinfo/aircraft.png b/demos/embedded/flightinfo/aircraft.png index 0845cb4..2312bcc 100644 Binary files a/demos/embedded/flightinfo/aircraft.png and b/demos/embedded/flightinfo/aircraft.png differ -- cgit v0.12 From a647abd3d108eb6ce45642713b5786240659816f Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 30 Oct 2009 17:20:17 +0100 Subject: Reducing file sizes. Using pngout to make the fluidlauncher a bit lighter. Reviewed-by: trustme --- demos/embedded/raycasting/textures.png | Bin 42319 -> 17669 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/demos/embedded/raycasting/textures.png b/demos/embedded/raycasting/textures.png index 839488b..2eb1ba7 100644 Binary files a/demos/embedded/raycasting/textures.png and b/demos/embedded/raycasting/textures.png differ -- cgit v0.12 From fd0b91269e1cb46961414d689615ea3f17f6a524 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 30 Oct 2009 17:40:53 +0100 Subject: Reducing file size. Stripping 350k off by reencoding the mp3. 32 Kbps, mono, 22.05 KHz. Reviewed-by: trustme --- demos/embedded/desktopservices/data/sax.mp3 | Bin 417844 -> 104104 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/demos/embedded/desktopservices/data/sax.mp3 b/demos/embedded/desktopservices/data/sax.mp3 index 0a078b1..d77c817 100644 Binary files a/demos/embedded/desktopservices/data/sax.mp3 and b/demos/embedded/desktopservices/data/sax.mp3 differ -- cgit v0.12 From 243bd8c8f47f37b7a066a99bad180310dba2edcb Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 30 Oct 2009 18:36:37 +0100 Subject: Added manual text performance test. Small application that simulates different text rendering scenarios and displays the Fps. Reviewed-by: trustme --- .../manual/textrendering/textperformance/main.cpp | 231 +++++++++++++++++++++ .../textperformance/textperformance.pro | 1 + 2 files changed, 232 insertions(+) create mode 100644 tests/manual/textrendering/textperformance/main.cpp create mode 100644 tests/manual/textrendering/textperformance/textperformance.pro diff --git a/tests/manual/textrendering/textperformance/main.cpp b/tests/manual/textrendering/textperformance/main.cpp new file mode 100644 index 0000000..3019ebf --- /dev/null +++ b/tests/manual/textrendering/textperformance/main.cpp @@ -0,0 +1,231 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +static const int lastMeasurementsCount = 50; + +class FontBlaster: public QWidget +{ + Q_OBJECT + +public: + FontBlaster(QWidget *parent = 0) + : QWidget(parent) + , m_currentMode(0) + { + setFocusPolicy(Qt::StrongFocus); + } + + void paintEvent(QPaintEvent *event) + { + Q_UNUSED(event); + QPainter p(this); + + if (!m_timer.isNull()) + m_lastMeasurements.append(m_timer.elapsed()); + m_timer.start(); + + p.save(); + m_modes[m_currentMode].function(p, size()); + p.restore(); + + const QFontMetrics fm = p.fontMetrics(); + p.setOpacity(0.7); + p.fillRect(0, 0, width(), fm.height(), Qt::gray); + p.fillRect(0, height() - fm.height(), width(), height(), Qt::gray); + p.setOpacity(1); + p.setPen(palette().color(QPalette::Text)); + p.drawText(2, fm.ascent(), m_modes[m_currentMode].name); + + if (m_lastMeasurements.count() == lastMeasurementsCount) { + m_lastMeasurements.removeFirst(); + int lastMsecsSum = 0; + foreach(const int measurement, m_lastMeasurements) + lastMsecsSum += measurement; + + p.drawText(2, height() - fm.descent(), + QLatin1String("Fps: ") + + QString::number(1000 / (qreal)(lastMsecsSum / lastMeasurementsCount), 'f', 1) + ); + } + + QTimer::singleShot(0, this, SLOT(repaint())); + } + + /* + Creating all kinds of size/weight/italic combinations, stress testing + the glyph cache. + Also: painting with different opacities, stress testing blitting. + */ + static void paintDifferentFontStyles(QPainter &p, const QSize &size) + { + static const QString text = QLatin1String("Qt rocks!!!"); + static const int textsPerPaint = 30; + for (int i = 0; i < textsPerPaint; i++) { + const int fontSize = 4 + (qrand() % 5); + const int fontWeight = (qrand() % 2) == 1 ? QFont::Normal : QFont::Bold; + const bool fontItalic = (qrand() % 2) == 1; + const QFont font("Default", fontSize, fontWeight, fontItalic); + p.setFont(font); + p.setPen(QColor::fromHsv(qrand() % 359, 155 + qrand() % 100, + 155 + qrand() % 100, 100 + qrand() % 155)); + const QSize textSize(p.fontMetrics().boundingRect(text).size()); + const QPoint position( + -textSize.width() / 2 + (qrand() % size.width()), + textSize.height() / 2 + (qrand() % size.height())); + p.drawText(position, text); + } + } + + /* + Drawing a multiline latin text, stress testing the text layout system. + */ + static void paintLongLatinText(QPainter &p, const QSize &size) + { + static const char* const pieces[] = { + "lorem ipsum", + "dolor sit amet", + "consectetuer", + "sed diam nonumy", + "eos et accusam", + "sea takimata sanctus" + }; + static const int piecesCount = (int)(sizeof pieces / sizeof pieces[0]); + static const int piecesPerPaint = 30; + + QString text; + for (int i = 0; i < piecesPerPaint; ++i) { + QString piece = QLatin1String(pieces[qrand() % piecesCount]); + if (i == 0 || qrand() % 2) { + // Make this piece the beginning of a new sentence. + piece[0] = piece[0].toUpper(); + if (i > 0) + piece.prepend(QLatin1String(". ")); + } else { + piece.prepend(QLatin1String(", ")); + } + text.append(piece); + } + text.append(QLatin1Char('.')); + + p.drawText(QRectF(QPointF(0, 0), QSizeF(size)), + Qt::AlignTop | Qt::AlignAbsolute | Qt::TextWordWrap, text); + } + + /* + Drawing one text with several snippets of different writingSystems, stress + testing the font merging in the font database. + */ + static void paintInternationalText(QPainter &p, const QSize &size) + { + static QStringList samples; + if (samples.isEmpty()) { + foreach (const QFontDatabase::WritingSystem system, QFontDatabase().writingSystems()) + if (system != QFontDatabase::Ogham && system != QFontDatabase::Runic) + samples.append(QFontDatabase::writingSystemSample(system)); + } + static const int systemsPerPaint = 65; + QString text; + for (int i = 0; i < systemsPerPaint; i++) { + if (i > 0) + text.append(QLatin1Char(' ')); + text.append(samples.at(qrand() % samples.count())); + } + p.drawText(QRectF(QPointF(0, 0), QSizeF(size)), + Qt::AlignTop | Qt::AlignAbsolute | Qt::TextWordWrap, text); + } + +protected: + void nextMode() + { + m_currentMode = (m_currentMode + 1) % m_modesCount; + m_lastMeasurements.clear(); + } + + void keyPressEvent(QKeyEvent *event) + { + Q_UNUSED(event); + nextMode(); + } + + void mousePressEvent(QMouseEvent *event) + { + Q_UNUSED(event); + nextMode(); + } + +private: + static const struct mode { + QString name; + void (*function)(QPainter &, const QSize&); + } m_modes[]; + static const int m_modesCount; + + int m_currentMode; + QList m_lastMeasurements; + QTime m_timer; +}; + +const struct FontBlaster::mode FontBlaster::m_modes[] = { + { QLatin1String("Qt rocks!!!"), FontBlaster::paintDifferentFontStyles }, + { QLatin1String("Latin"), FontBlaster::paintLongLatinText }, + { QLatin1String("International"), FontBlaster::paintInternationalText } +}; + +const int FontBlaster::m_modesCount = + (int)(sizeof m_modes / sizeof m_modes[0]); + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + FontBlaster dlg; +#ifdef Q_OS_SYMBIAN + dlg.showFullScreen(); +#else + dlg.show(); +#endif + + return a.exec(); +} + +#include "main.moc" diff --git a/tests/manual/textrendering/textperformance/textperformance.pro b/tests/manual/textrendering/textperformance/textperformance.pro new file mode 100644 index 0000000..bba41b9 --- /dev/null +++ b/tests/manual/textrendering/textperformance/textperformance.pro @@ -0,0 +1 @@ +SOURCES = main.cpp -- cgit v0.12 From d6254cb596a8e320959a8bbc0310cf43f16657ba Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 30 Oct 2009 18:57:16 +0100 Subject: Fix a rounding error. Reviewed-by: trustme --- tests/manual/textrendering/textperformance/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/manual/textrendering/textperformance/main.cpp b/tests/manual/textrendering/textperformance/main.cpp index 3019ebf..47e0a88 100644 --- a/tests/manual/textrendering/textperformance/main.cpp +++ b/tests/manual/textrendering/textperformance/main.cpp @@ -84,7 +84,7 @@ public: p.drawText(2, height() - fm.descent(), QLatin1String("Fps: ") + - QString::number(1000 / (qreal)(lastMsecsSum / lastMeasurementsCount), 'f', 1) + QString::number(1000 / ((qreal)lastMsecsSum / lastMeasurementsCount), 'f', 1) ); } -- cgit v0.12 From 42342c76c86a368b78c55fefc28c4bca1c010d03 Mon Sep 17 00:00:00 2001 From: Daniel Molkentin Date: Thu, 29 Oct 2009 22:22:32 +0100 Subject: Make Linguist on Mac use the unified toolbar, like Assistant. Reviewed-By: Oswald Buddenhagen --- tools/linguist/linguist/mainwindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/linguist/linguist/mainwindow.cpp b/tools/linguist/linguist/mainwindow.cpp index 9bc6641..7f09a1c 100644 --- a/tools/linguist/linguist/mainwindow.cpp +++ b/tools/linguist/linguist/mainwindow.cpp @@ -269,6 +269,7 @@ MainWindow::MainWindow() m_editActiveModel(-1), m_statistics(0) { + setUnifiedTitleAndToolBarOnMac(true); m_ui.setupUi(this); #ifndef Q_WS_MAC -- cgit v0.12 From f914536c1c472cd7e0e21252c83447da7618c2cb Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Fri, 30 Oct 2009 19:41:48 +0100 Subject: Add a French translation to Assistant. Update the phrase book. Reviewed-by: Pierre Rossi --- tools/assistant/translations/translations.pro | 1 + tools/linguist/phrasebooks/french.qph | 20 + translations/assistant_fr.ts | 1080 +++++++++++++++++++++++++ 3 files changed, 1101 insertions(+) create mode 100644 translations/assistant_fr.ts diff --git a/tools/assistant/translations/translations.pro b/tools/assistant/translations/translations.pro index 6ff1fc9..95501ab 100644 --- a/tools/assistant/translations/translations.pro +++ b/tools/assistant/translations/translations.pro @@ -44,6 +44,7 @@ TR_DIR = $$PWD/../../../translations TRANSLATIONS = \ $$TR_DIR/assistant_da.ts \ $$TR_DIR/assistant_de.ts \ + $$TR_DIR/assistant_fr.ts \ $$TR_DIR/assistant_ja.ts \ $$TR_DIR/assistant_pl.ts \ $$TR_DIR/assistant_ru.ts \ diff --git a/tools/linguist/phrasebooks/french.qph b/tools/linguist/phrasebooks/french.qph index d38da5a..9440345 100644 --- a/tools/linguist/phrasebooks/french.qph +++ b/tools/linguist/phrasebooks/french.qph @@ -1326,4 +1326,24 @@ Close All Except %1 Fermer tout sauf %1 + + Remove + Suppression + + + About... + À propos… + + + Minimize + Minimiser + + + Remove + Supprimer + + + Select All + Sélectionner tout + diff --git a/translations/assistant_fr.ts b/translations/assistant_fr.ts new file mode 100644 index 0000000..91fcc1a --- /dev/null +++ b/translations/assistant_fr.ts @@ -0,0 +1,1080 @@ + + + + + AboutDialog + + + &Close + &Fermer + + + + AboutLabel + + + Warning + Avertissement + + + + Unable to launch external application. + + Impossible d'ouvrir l'application externe. + + + + + OK + OK + + + + BookmarkDialog + + + Add Bookmark + Ajouter un signet + + + + Bookmark: + Signet : + + + + Add in Folder: + Ajouter dans le dossier : + + + + + + + + + + + New Folder + Nouveau dossier + + + + + + + + Bookmarks + Signets + + + + Delete Folder + Supprimer le dossier + + + + Rename Folder + Renommer le dossier + + + + BookmarkManager + + + Bookmarks + Signets + + + + Remove + Suppression + + + + You are going to delete a Folder, this will also<br>remove it's content. Are you sure to continue? + Vous allez supprimer un dossier, ceci va aussi<br>supprimer son contenu. Voulez-vous continuer? + + + + + New Folder + Nouveau dossier + + + + BookmarkWidget + + + Delete Folder + Supprimer le dossier + + + + Rename Folder + Renommer le dossier + + + + Show Bookmark + Afficher le signet + + + + Show Bookmark in New Tab + Afficher le signet dans un nouvel onglet + + + + Delete Bookmark + Supprimer le signet + + + + Rename Bookmark + Renommer le signet + + + + Filter: + Filtre : + + + + Add + Ajouter + + + + Remove + Retirer + + + + CentralWidget + + + Add new page + Créer une nouvelle page + + + + Close current page + Fermer la page courante + + + + Print Document + Imprimer le document + + + + + unknown + inconnu + + + + Add New Page + Créer une nouvelle page + + + + Close This Page + Fermer cette page + + + + Close Other Pages + Fermer les autres pages + + + + Add Bookmark for this Page... + Ajouter un signet pour cette page... + + + + Search + Recherche + + + + ContentWindow + + + Open Link + Ouvrir le lien + + + + Open Link in New Tab + Ouvrir le lien dans un nouvel onglet + + + + FilterNameDialogClass + + + Add Filter Name + Ajouter un filtre + + + + Filter Name: + Nom du filtre : + + + + FindWidget + + + Previous + Précédent + + + + Next + Suivant + + + + Case Sensitive + Sensible à la casse + + + + Whole words + Mots complets + + + + <img src=":/trolltech/assistant/images/wrap.png">&nbsp;Search wrapped + <img src=":/trolltech/assistant/images/wrap.png">&nbsp;Recherche à partir du début + + + + FontPanel + + + Font + Police + + + + &Writing system + &Système d'écriture + + + + &Family + &Famille + + + + &Style + &Style + + + + &Point size + &Taille en points + + + + HelpViewer + + + Open Link in New Tab + Ouvrir le lien dans un nouvel onglet + + + + <title>Error 404...</title><div align="center"><br><br><h1>The page could not be found</h1><br><h3>'%1'</h3></div> + <title>Erreur 404...</title><div align="center"><br><br><h1>La page n'a pas pu être trouvée</h1><br><h3>'%1'</h3></div> + + + + Help + Aide + + + + Unable to launch external application. + + Impossible de lancer l'application externe. + + + + + OK + OK + + + + Copy &Link Location + Copier l'&adresse cible + + + + Open Link in New Tab Ctrl+LMB + LMB? ← ouais exactement pareil... + Ouvrir dans un nouvel onglet Ctrl+clic gauche + + + + IndexWindow + + + &Look for: + &Rechercher : + + + + Open Link + Ouvrir le lien + + + + Open Link in New Tab + Ouvrir le lien dans un nouvel onglet + + + + InstallDialog + + + + Install Documentation + Installer la documentation + + + + Available Documentation: + Documentation disponible : + + + + Install + Installer + + + + Cancel + Annuler + + + + Close + Fermer + + + + Installation Path: + Chemin d'installation : + + + + ... + + + + + Downloading documentation info... + Téléchargement des informations de la documentation… + + + + Download canceled. + Téléchargement annulé. + + + + + + Done. + Terminé. + + + + The file %1 already exists. Do you want to overwrite it? + Le fichier %1 existe déjà. Voulez-vous l'écraser? + + + + Unable to save the file %1: %2. + Impossible de sauver le fichier %1 : %2. + + + + Downloading %1... + Téléchargement de %1 en cours… + + + + + + Download failed: %1. + Échec du téléchargement : %1. + + + + Documentation info file is corrupt! + Le fichier d'information de documentation est corrompu! + + + + Download failed: Downloaded file is corrupted. + Échec du téléchargement : le fichier téléchargé est corrompu. + + + + Installing documentation %1... + Installation de la documentation %1… + + + + Error while installing documentation: +%1 + Erreur durant l'installation de la documentation : +%1 + + + + MainWindow + + + + Index + Index + + + + + Contents + Sommaire + + + + + Bookmarks + Signets + + + + + + Qt Assistant + Qt Assistant + + + + + Unfiltered + Non-filtré + + + + Looking for Qt Documentation... + Recherche la documentation de Qt… + + + + &File + &Fichier + + + + Page Set&up... + &Mise en page… + + + + Print Preview... + Aperçu avant impression… + + + + &Print... + &Imprimer… + + + + New &Tab + Nouvel ongle&t + + + + &Close Tab + &Fermer l'onglet + + + + &Quit + &Quitter + + + + &Edit + &Édition + + + + &Copy selected Text + &Copier le texte selectionné + + + + &Find in Text... + &Trouver dans le texte… + + + + Find &Next + Rechercher le suiva&nt + + + + Find &Previous + Rechercher le &précédent + + + + Preferences... + Préférences… + + + + &View + &Affichage + + + + Zoom &in + Zoom &avant + + + + Zoom &out + Zoom a&rrière + + + + Normal &Size + &Taille normale + + + + Ctrl+0 + Ctrl+0 + + + + ALT+C + ALT+C + + + + ALT+I + ALT+I + + + + ALT+O + ALT+O + + + + Search + Recherche + + + + ALT+S + ALT+S + + + + &Go + &Aller + + + + &Home + &Accueil + + + + ALT+Home + ALT+Home + + + + &Back + &Précédent + + + + &Forward + &Suivant + + + + Sync with Table of Contents + Synchroniser la table des matières + + + + Next Page + Page suivante + + + + Ctrl+Alt+Right + Ctrl+Alt+Right + + + + Previous Page + Page précédente + + + + Ctrl+Alt+Left + Ctrl+Alt+Left + + + + &Bookmarks + &Signets + + + + Add Bookmark... + Ajouter un signet… + + + + CTRL+D + CTRL+D + + + + &Help + &Aide + + + + About... + À propos… + + + + Navigation Toolbar + Barre d'outils de navigation + + + + &Window + &Fenêtre + + + + Zoom + Zoom + + + + Minimize + Minimiser + + + + Ctrl+M + Ctrl+M + + + + Toolbars + Barres d'outils + + + + Filter Toolbar + Barre d'outils de filtrage + + + + Filtered by: + Filtré par : + + + + Address Toolbar + Barre d'outils d'adresse + + + + Address: + Adresse : + + + + Could not find the associated content item. + what is item in this context? ← same question here + Impossible de trouver l'élément de contenu associé. + + + + About %1 + À propos de %1 + + + + Updating search index + Mise à jour de l'index de recherche + + + + PreferencesDialog + + + + Add Documentation + Ajouter de la documentation + + + + Qt Compressed Help Files (*.qch) + Fichiers d'aide Qt compressés (*.qch) + + + + The namespace %1 is already registered! + L'espace de nom %1 existe déjà! + + + + The specified file is not a valid Qt Help File! + Le fichier spécifié n'est pas un fichier d'aide Qt valide! + + + + Remove Documentation + Supprimer la documentation + + + + Some documents currently opened in Assistant reference the documentation you are attempting to remove. Removing the documentation will close those documents. + Certains documents ouverts dans Assistant ont des références vers la documentation que vous allez supprimer. Supprimer la documentation fermera ces documents. + + + + Cancel + Annuler + + + + OK + OK + + + + Use custom settings + Utiliser des paramètres personnalisés + + + + PreferencesDialogClass + + + Preferences + Préférences + + + + Fonts + Polices + + + + Font settings: + Configuration des polices : + + + + Browser + Navigateur + + + + Application + Application + + + + Filters + Filtres + + + + Filter: + Filtre : + + + + Attributes: + Attributs : + + + + 1 + 1 + + + + Add + Ajouter + + + + + Remove + Supprimer + + + + Documentation + Documentation + + + + Registered Documentation: + documentation enregistrée ? ← je préfère référencée pour les deux... + Documentation référencée : + + + + Add... + Ajouter… + + + + Options + Options + + + + On help start: + Au démarrage : + + + + Show my home page + Afficher ma page d'accueil + + + + Show a blank page + Afficher une page blanche + + + + Show my tabs from last session + Afficher mes onglets de la dernière session + + + + Homepage + Page d'accueil + + + + Current Page + Page courante + + + + Blank Page + Page blanche + + + + Restore to default + Restaurer les valeurs par défaut + + + + QObject + + + The specified collection file does not exist! + Le fichier de collection spécifié n'existe pas! + + + + Missing collection file! + Fichier de collection manquant! + + + + Invalid URL! + URL invalide! + + + + Missing URL! + URL manquante! + + + + + + Unknown widget: %1 + Widget inconnu : %1 + + + + + + Missing widget! + Widget manquant! + + + + + The specified Qt help file does not exist! + Le fichier d'aide Qt spécifié n'existe pas! + + + + + Missing help file! + Fichier d'aide manquant! + + + + Missing filter argument! + Argument de filtre manquant! + + + + Unknown option: %1 + Option inconnue : %1 + + + + + Qt Assistant + Qt Assistant + + + + Could not register documentation file +%1 + +Reason: +%2 + Impossible d'enregistrer le fichier de documentation +%1 + +Raison : +%2 + + + + Documentation successfully registered. + Documentation enregistrée avec succès. + + + + Documentation successfully unregistered. + Documentation retirée avec succès. + + + + Could not unregister documentation file +%1 + +Reason: +%2 + Impossible d'enregistrer le fichier de documentation +%1 + +Raison : +%2 + + + + Cannot load sqlite database driver! + Impossible de charger le driver de la base de données sqlite! + + + + The specified collection file could not be read! + Le fichier de collection spécifié ne peut pas être lu! + + + + RemoteControl + + + Debugging Remote Control + Débogage du contrôle à distance + + + + Received Command: %1 %2 + Commande reçue : %1 %2 + + + + SearchWidget + + + &Copy + &Copier + + + + Copy &Link Location + Copier &l'adresse du lien + + + + Open Link in New Tab + Ouvrir le lien dans un nouvel onglet + + + + Select All + Sélectionner tout + + + + TopicChooser + + + Choose Topic + Choisir le domaine + + + + &Topics + &Domaines + + + + &Display + &Afficher + + + + &Close + &Fermer + + + + Choose a topic for <b>%1</b>: + Choisir le domaine pour <b>%1</b> : + + + -- cgit v0.12 From 6991cf4fe678427aec370f1abb217591987d3a7e Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Mon, 2 Nov 2009 11:31:42 +1000 Subject: Add missing QENUM declarations (needed by declarative). --- src/corelib/animation/qabstractanimation.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/animation/qabstractanimation.h b/src/corelib/animation/qabstractanimation.h index 50b07d7..3d608b6 100644 --- a/src/corelib/animation/qabstractanimation.h +++ b/src/corelib/animation/qabstractanimation.h @@ -59,6 +59,8 @@ class QAbstractAnimationPrivate; class Q_CORE_EXPORT QAbstractAnimation : public QObject { Q_OBJECT + Q_ENUMS(State) + Q_ENUMS(Direction) Q_PROPERTY(State state READ state NOTIFY stateChanged) Q_PROPERTY(int loopCount READ loopCount WRITE setLoopCount) Q_PROPERTY(int currentTime READ currentTime WRITE setCurrentTime) -- cgit v0.12 From debc67d6183631339b910c52261a6bc7b7a7ae50 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Mon, 2 Nov 2009 11:33:09 +1000 Subject: Track declarative changes --- src/gui/graphicsview/qgraphicsitem_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 183e95b..ca56c18 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -607,7 +607,7 @@ public: return item->type() == QGraphicsPixmapItem::Type && !(item->flags() & QGraphicsItem::ItemIsSelectable) && item->d_ptr->children.size() == 0; - //|| (item->d_ptr->isObject && qobject_cast(q_func())); + //|| (item->d_ptr->isObject && qobject_cast(q_func())); } inline const QStyleOption *styleOption() const -- cgit v0.12 From ae576ea123d0625eceb9904e2039b2183cb82a0b Mon Sep 17 00:00:00 2001 From: Bill King Date: Mon, 2 Nov 2009 12:41:25 +1000 Subject: Fixes Floating point number truncation in qsqlpsql plugin under linux replaces strtod call with locale aware QString::toDouble() Task-number: QTBUG-5179 Reviewed-by: Justin McPherson --- src/sql/drivers/psql/qsql_psql.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index 4b7c2b5..1e41571 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -357,7 +357,7 @@ QVariant QPSQLResult::data(int i) } return QString::fromAscii(val); } - return strtod(val, 0); + return QString::fromAscii(val).toDouble(); case QVariant::Date: if (val[0] == '\0') { return QVariant(QDate()); -- cgit v0.12 From 55dcc5551e338ba16c0db8c7d6593554d3d019b8 Mon Sep 17 00:00:00 2001 From: Keith Isdale Date: Mon, 2 Nov 2009 14:29:05 +1000 Subject: Compilation error qegl_p.h not found for OpenGL ES enabled build of Qt for WindowsCE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Be more consistant in the usage of vs "foo_p.h" Task-number: QTBUG-5149 Reviewed-by: Trond Kjernåsen --- src/opengl/qgl_wince.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/opengl/qgl_wince.cpp b/src/opengl/qgl_wince.cpp index 53b9e27..fea2d3a 100644 --- a/src/opengl/qgl_wince.cpp +++ b/src/opengl/qgl_wince.cpp @@ -54,9 +54,9 @@ #include -#include "qegl_p.h" -#include "qgl_egl_p.h" -#include "qgl_cl_p.h" +#include +#include +#include QT_BEGIN_NAMESPACE -- cgit v0.12 From 504ac5668c7308dc67233ed8589eeadcd23e7cdd Mon Sep 17 00:00:00 2001 From: Keith Isdale Date: Mon, 2 Nov 2009 14:59:24 +1000 Subject: Compilation failure QtOpenGL when Opengl ES is used on Qt for Windows CE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable building egl/qegl_wince.cpp when a wince* mkspec is used Add "egl" to QT_CONFIG when any of the OpenGL ES variants is used Task-number: QTBUG-5073 Reviewed-by: Trond Kjernåsen --- src/gui/egl/egl.pri | 2 +- tools/configure/configureapp.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/egl/egl.pri b/src/gui/egl/egl.pri index ba991bd..627d511 100644 --- a/src/gui/egl/egl.pri +++ b/src/gui/egl/egl.pri @@ -6,7 +6,7 @@ SOURCES += \ egl/qegl.cpp \ egl/qeglproperties.cpp -contains(QT_CONFIG, wince*): SOURCES += egl/qegl_wince.cpp +wince*: SOURCES += egl/qegl_wince.cpp unix { embedded { diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 6d46c18..dd3823b 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -2438,14 +2438,17 @@ void Configure::generateOutputVars() if ( dictionary["OPENGL_ES_CM"] == "yes" ) { qtConfig += "opengles1"; + qtConfig += "egl"; } if ( dictionary["OPENGL_ES_2"] == "yes" ) { qtConfig += "opengles2"; + qtConfig += "egl"; } if ( dictionary["OPENGL_ES_CL"] == "yes" ) { qtConfig += "opengles1cl"; + qtConfig += "egl"; } if ( dictionary["OPENVG"] == "yes" ) { -- cgit v0.12 From d26bc43093cc6ed8d387abedcde0952ec24c0e0b Mon Sep 17 00:00:00 2001 From: Keith Isdale Date: Mon, 2 Nov 2009 15:17:12 +1000 Subject: Compilation failure for OpenGL and OpenVG graphic system plugins when Opengl ES is used on Qt for Windows CE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For WindowsCE plugins do not support version 1.x of OpenGL ES Task-number : QTBUG-5080 Reviewed-by : Trond Kjernåsen --- src/plugins/graphicssystems/graphicssystems.pro | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/plugins/graphicssystems/graphicssystems.pro b/src/plugins/graphicssystems/graphicssystems.pro index 14e3cfc..ca87b98 100644 --- a/src/plugins/graphicssystems/graphicssystems.pro +++ b/src/plugins/graphicssystems/graphicssystems.pro @@ -1,7 +1,13 @@ TEMPLATE = subdirs SUBDIRS += trace -contains(QT_CONFIG, opengl):SUBDIRS += opengl -contains(QT_CONFIG, openvg):contains(QT_CONFIG, egl):SUBDIRS += openvg +!wince*{ + contains(QT_CONFIG, opengl):SUBDIRS += opengl + contains(QT_CONFIG, openvg):contains(QT_CONFIG, egl):SUBDIRS += openvg +}else { + # For WindowsCE only 2.x of OpenGL ES is supported by these plugins at this time + contains(QT_CONFIG, opengl):!contains(QT_CONFIG, opengles1):!contains(QT_CONFIG, opengles1cl):SUBDIRS += opengl + contains(QT_CONFIG, openvg):!contains(QT_CONFIG, opengles1):!contains(QT_CONFIG, opengles1cl):contains(QT_CONFIG, egl):SUBDIRS += openvg +} contains(QT_CONFIG, shivavg) { # Only works under X11 at present -- cgit v0.12 From 2c99050cbf88325f0316159ac35bd34010035bf9 Mon Sep 17 00:00:00 2001 From: Yuecel Ahi Date: Mon, 2 Nov 2009 15:49:55 +1000 Subject: Fixed handling of database level precision policy for sqlite driver. Reviewed-by: Bill King --- src/sql/drivers/sqlite/qsql_sqlite.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp index 2766cca..8355de2 100644 --- a/src/sql/drivers/sqlite/qsql_sqlite.cpp +++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp @@ -228,13 +228,9 @@ bool QSQLiteResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int i values[i + idx] = sqlite3_column_int64(stmt, i); break; case QSql::LowPrecisionDouble: - values[i + idx] = sqlite3_column_double(stmt, i); - break; case QSql::HighPrecision: default: - values[i + idx] = QString::fromUtf16(static_cast( - sqlite3_column_text16(stmt, i)), - sqlite3_column_bytes16(stmt, i) / sizeof(ushort)); + values[i + idx] = sqlite3_column_double(stmt, i); break; }; break; -- cgit v0.12 From 2f97ddf87f817ce8ae42095d96644ff5fca131e6 Mon Sep 17 00:00:00 2001 From: Bill King Date: Mon, 2 Nov 2009 16:06:05 +1000 Subject: Fixes testing of sqlite against the real(floating pt) datatype --- tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index 82b6066..fe7c3ea 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -1234,6 +1234,7 @@ void tst_QSqlDatabase::recordSQLite() FieldDef("integer", QVariant::Int, QVariant(13)), FieldDef("int", QVariant::Int, QVariant(12)), + FieldDef("real", QVariant::String, QVariant(1.234567890123456)), FieldDef() }; -- cgit v0.12 From d47bc05931004c7384e77ff358d67feddb84d501 Mon Sep 17 00:00:00 2001 From: Keith Isdale Date: Mon, 2 Nov 2009 17:11:28 +1000 Subject: Compilation failure for OpenGL and OpenVG graphic system plugins when Opengl ES is used on Qt for Windows CE Simplify logic as OpenGL graphic system is not supported for WindowsCE Task-number: QTBUG-5080 Reviewed-by: Rhys Weatherley --- src/plugins/graphicssystems/graphicssystems.pro | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/plugins/graphicssystems/graphicssystems.pro b/src/plugins/graphicssystems/graphicssystems.pro index ca87b98..0788933 100644 --- a/src/plugins/graphicssystems/graphicssystems.pro +++ b/src/plugins/graphicssystems/graphicssystems.pro @@ -1,13 +1,7 @@ TEMPLATE = subdirs SUBDIRS += trace -!wince*{ - contains(QT_CONFIG, opengl):SUBDIRS += opengl - contains(QT_CONFIG, openvg):contains(QT_CONFIG, egl):SUBDIRS += openvg -}else { - # For WindowsCE only 2.x of OpenGL ES is supported by these plugins at this time - contains(QT_CONFIG, opengl):!contains(QT_CONFIG, opengles1):!contains(QT_CONFIG, opengles1cl):SUBDIRS += opengl - contains(QT_CONFIG, openvg):!contains(QT_CONFIG, opengles1):!contains(QT_CONFIG, opengles1cl):contains(QT_CONFIG, egl):SUBDIRS += openvg -} +!wince*:contains(QT_CONFIG, opengl):SUBDIRS += opengl +contains(QT_CONFIG, openvg):contains(QT_CONFIG, egl):SUBDIRS += openvg contains(QT_CONFIG, shivavg) { # Only works under X11 at present -- cgit v0.12 From 5d7e254583551659df42e59fab4756994d4211ed Mon Sep 17 00:00:00 2001 From: Keith Isdale Date: Mon, 2 Nov 2009 18:03:28 +1000 Subject: Compilation error due to undefined EGL_BIND_TO_TEXTURE_RGB for OpenGL ES enabled build of Qt for Windows CE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add #ifdef guards around EGL_BIND_TO_TEXTURE_RGB useage Task-number: QTBUG-5152 Reviewed-by: Trond Kjernåsen --- src/gui/egl/qeglproperties.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/egl/qeglproperties.cpp b/src/gui/egl/qeglproperties.cpp index c61e1d3..2d37edb 100644 --- a/src/gui/egl/qeglproperties.cpp +++ b/src/gui/egl/qeglproperties.cpp @@ -88,8 +88,12 @@ int QEglProperties::value(int name) const #if defined(EGL_ALPHA_MASK_SIZE) case EGL_ALPHA_MASK_SIZE: return 0; #endif +#if defined(EGL_BIND_TO_TEXTURE_RGB) case EGL_BIND_TO_TEXTURE_RGB: return EGL_DONT_CARE; +#endif +#if defined(EGL_BIND_TO_TEXTURE_RGBA) case EGL_BIND_TO_TEXTURE_RGBA: return EGL_DONT_CARE; +#endif #if defined(EGL_COLOR_BUFFER_TYPE) case EGL_COLOR_BUFFER_TYPE: return EGL_RGB_BUFFER; #endif -- cgit v0.12 From 016c06f8988c50f0f8309b1b5054ea99ecd1bc6c Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Mon, 2 Nov 2009 12:05:03 +0100 Subject: Manual glyph shaping test. It tests the glyph shaper in Qt by rendering a couple of glyph combinations that are known to be strongly shaped. For now, this test is manual and simply generates an html report for a visual test. It can, however also be implemented as auto test. The test data contains Vietnamese and Tamil data sets, more will follow. Reviewed-by: trustme --- .../textrendering/glyphshaping/glyphshaping.pro | 5 + .../glyphshaping/glyphshaping_data.xml | 251 +++++++++++++++++++ tests/manual/textrendering/glyphshaping/main.cpp | 269 +++++++++++++++++++++ 3 files changed, 525 insertions(+) create mode 100644 tests/manual/textrendering/glyphshaping/glyphshaping.pro create mode 100644 tests/manual/textrendering/glyphshaping/glyphshaping_data.xml create mode 100644 tests/manual/textrendering/glyphshaping/main.cpp diff --git a/tests/manual/textrendering/glyphshaping/glyphshaping.pro b/tests/manual/textrendering/glyphshaping/glyphshaping.pro new file mode 100644 index 0000000..caa9028 --- /dev/null +++ b/tests/manual/textrendering/glyphshaping/glyphshaping.pro @@ -0,0 +1,5 @@ +SOURCES = main.cpp +OTHER_FILES = glyphshaping_data.xml +glyphshaping_data.path = . +glyphshaping_data.sources = $$PWD/glyphshaping_data.xml +DEPLOYMENT += glyphshaping_data diff --git a/tests/manual/textrendering/glyphshaping/glyphshaping_data.xml b/tests/manual/textrendering/glyphshaping/glyphshaping_data.xml new file mode 100644 index 0000000..040804e --- /dev/null +++ b/tests/manual/textrendering/glyphshaping/glyphshaping_data.xml @@ -0,0 +1,251 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/manual/textrendering/glyphshaping/main.cpp b/tests/manual/textrendering/glyphshaping/main.cpp new file mode 100644 index 0000000..d2b53a0 --- /dev/null +++ b/tests/manual/textrendering/glyphshaping/main.cpp @@ -0,0 +1,269 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +static const int fontPixelSize = 25; +static const QLatin1String fontFamily("Series 60 Sans"); + +struct testDataSet +{ + QString language; + QString name; + QString input; + QString inputOriginal; + QString output; + QString outputOriginal; + QVector outputGlyphIDs; + QString outputGlyphIDsOriginal; +}; + +QString charHexCsv2String(const QString &csv) +{ + QString result; + foreach (const QString &charString, csv.split(QLatin1Char(','), QString::SkipEmptyParts)) { + bool isOk; + const uint charUInt = charString.toUInt(&isOk, 16); + Q_ASSERT(isOk); + const int size = charUInt >= SHRT_MAX ? 2:1; + result.append(QString::fromUtf16((const ushort*)&charUInt, size)); + } + return result; +} + +QList testDataSetList() +{ + QList result; + QFile file("glyphshaping_data.xml"); + const bool success = file.open(QIODevice::ReadOnly); + Q_ASSERT(success); + + const QLatin1String language("language"); + const QLatin1String test("test"); + const QLatin1String inputUtf16("inpututf16"); + const QLatin1String outputUtf16("outpututf16"); + const QLatin1String outputGlyphIDs("outputglyphids"); + const QLatin1String name("name"); + + QString languageName; + + QXmlStreamReader reader(&file); + while (!reader.atEnd()) { + const QXmlStreamReader::TokenType token = reader.readNext(); + switch (token) { + case QXmlStreamReader::StartElement: + if (reader.name() == language) { + Q_ASSERT(reader.attributes().hasAttribute(name)); + languageName = reader.attributes().value(name).toString(); + } else if (reader.name() == test) { + if (!reader.attributes().hasAttribute(outputUtf16) + && !reader.attributes().hasAttribute(outputGlyphIDs)) + continue; + Q_ASSERT(!languageName.isEmpty()); + Q_ASSERT(reader.attributes().hasAttribute(name)); + Q_ASSERT(reader.attributes().hasAttribute(inputUtf16)); + testDataSet set; + set.language = languageName; + set.name = reader.attributes().value(name).toString(); + set.inputOriginal = reader.attributes().value(inputUtf16).toString(); + set.input = charHexCsv2String(set.inputOriginal); + set.outputOriginal = reader.attributes().value(outputUtf16).toString(); + set.output = charHexCsv2String(set.outputOriginal); + set.outputGlyphIDsOriginal = reader.attributes().value(outputGlyphIDs).toString(); + result.append(set); + } + break; + default: + break; + } + } + return result; +} + +QImage renderedText(const QString &text, const QFont &font) +{ + const QFontMetrics metrics(font); + const QRect boundingRect = metrics.boundingRect(text); + QImage result(boundingRect.size(), QImage::Format_ARGB32); + result.fill(0); + + QPainter p(&result); + p.setFont(font); + p.drawText(boundingRect.translated(-boundingRect.topLeft()), text); + + return result; +} + +QString dumpImageHtml(const QString &text, const QString &pathName) +{ + if (text.isEmpty()) + return QLatin1String(""); + QFont font(fontFamily); + font.setPixelSize(fontPixelSize); + const QImage textImage = renderedText(text, font); + const QString imageFileName = + (pathName + QDir::separator() + QLatin1String("%1.png")) + .arg(textImage.cacheKey()); + const bool success = textImage.save(imageFileName); + Q_ASSERT(success); + return + QString::fromLatin1("\"%2\"") + .arg(QDir::cleanPath(imageFileName)).arg(text).arg(textImage.width()).arg(textImage.height()); +} + +QString dlItem(const QString &dt, const QString &dd) +{ + if (!dd.trimmed().isEmpty()) + return QString::fromLatin1("\t\t\t\t\t\t
%1
%2
\n").arg(dt).arg(dd); + return QString(); +} + +bool dumpHtml(const QString &pathName) +{ + QFile htmlPage(pathName + QDir::separator() + QLatin1String("index.html")); + if (!htmlPage.open(QFile::WriteOnly)) + return false; + + QString platformName = QString::fromLatin1( +#if defined(Q_OS_WIN) + "Win32" +#elif defined(Q_WS_X11) + "X11" +#elif defined(Q_OS_SYMBIAN) + "Symbian" +#else + "" +#endif + ); + + QString result = QString::fromLatin1( + "\n\n" + "\n" + "\t\n" + "\t\tQt on %1 glyph shaping (%2)\n" + "\t\t\n" + "\t\t\n" + "\t\n" + "\t\n" + "\t\t

Qt on %1 glyph shaping (%2)

\n" + "\t\t
\n" + "\t\t\t
I
Input Utf-16 to shaper
\n" + "\t\t\t
O-Utf
expected output Utf-16
\n" + "\t\t\t
O-ID
expected output Glyph IDs for \"Series 60 Sans\"
\n" + "\t\t
\n" + "\t\t\n" + ).arg(platformName).arg(fontFamily).arg(fontPixelSize); + + QString languageName; + foreach (const testDataSet &dataSet, testDataSetList()) { + if (languageName != dataSet.language) { + result.append(QString::fromLatin1( + "\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\n" + "\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\n" + ).arg(dataSet.language).arg(platformName)); + languageName = dataSet.language; + } + QString glyphsData; + if (!dataSet.inputOriginal.isEmpty()) + glyphsData.append(dlItem(QLatin1String("I"), dataSet.inputOriginal)); + if (!dataSet.outputOriginal.isEmpty()) + glyphsData.append(dlItem(QLatin1String("O-Utf"), dataSet.outputOriginal)); + if (!dataSet.outputGlyphIDsOriginal.isEmpty()) + glyphsData.append(dlItem(QLatin1String("O-ID"), dataSet.outputGlyphIDsOriginal)); + if (!glyphsData.isEmpty()) { + glyphsData.prepend(QLatin1String("\t\t\t\t\t
\n")); + glyphsData.append(QLatin1String("\t\t\t\t\t
\n")); + } + result.append(QString::fromLatin1( + "\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t%2\n" + "\t\t\t\t%3\n" + "\t\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\n" + ).arg(dataSet.name) + .arg(dumpImageHtml(dataSet.input, pathName)) + .arg(dumpImageHtml(dataSet.output, pathName)) + .arg(glyphsData) + .arg(dataSet.input) + .arg(dataSet.output) + ); + } + + result.append(QString::fromLatin1( + "\t\t

%1

Qt/%2GlyphsBrowser
InOutInOut
%1\n" + "%4" + "\t\t\t\t%5%6
\n" + "\t\n" + "") + ); + + htmlPage.write(result.toUtf8()); + + return true; +} + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + return dumpHtml(QLatin1String(".")) ? 0 : 1; +} -- cgit v0.12 From cf800465369fb1ef84e8bddbbbfa7128d95afd27 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Mon, 2 Nov 2009 15:34:27 +0100 Subject: Sanitize building Qt with OpenGL ES support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit introduce QMAKE_LIBS_OPENGL_ES1, QMAKE_LIBS_OPENGL_ES1CL and QMAKE_LIBS_OPENGL_ES2 so we do not have to force users to copy/paste around entire mkspecs just to change the OpenGL backend. This should make the "-opengl es2" (and friends) configure option work out of the box with any mkspec on Linux+WinCE. Also removes a WinCE specific hack that is not required anymore. Reviewed-by: Tom Cooksey Reviewed-by: Trond Kjernåsen Approved-by: Lars Knoll --- config.tests/unix/opengles1/opengles1.pro | 6 +++--- config.tests/unix/opengles1cl/opengles1cl.pro | 6 +++--- config.tests/unix/opengles2/opengles2.pro | 6 +++--- doc/src/development/qmake-manual.qdoc | 23 +++++++++++++++++++++++ mkspecs/common/linux.conf | 9 +++++++++ mkspecs/common/wince/qmake.conf | 4 ++++ mkspecs/features/unix/opengl.prf | 26 ++++++++++++++++++++++---- src/opengl/opengl.pro | 22 ++++++++++------------ 8 files changed, 77 insertions(+), 25 deletions(-) diff --git a/config.tests/unix/opengles1/opengles1.pro b/config.tests/unix/opengles1/opengles1.pro index ad8dd31..1469aa9 100644 --- a/config.tests/unix/opengles1/opengles1.pro +++ b/config.tests/unix/opengles1/opengles1.pro @@ -1,9 +1,9 @@ SOURCES = opengles1.cpp -INCLUDEPATH += $$QMAKE_INCDIR_OPENGL +INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES1 -for(p, QMAKE_LIBDIR_OPENGL) { +for(p, QMAKE_LIBDIR_OPENGL_ES1) { exists($$p):LIBS += -L$$p } CONFIG -= qt -LIBS += $$QMAKE_LIBS_OPENGL_QT +LIBS += $$QMAKE_LIBS_OPENGL_ES1 diff --git a/config.tests/unix/opengles1cl/opengles1cl.pro b/config.tests/unix/opengles1cl/opengles1cl.pro index 415cdbb..c4c069e 100644 --- a/config.tests/unix/opengles1cl/opengles1cl.pro +++ b/config.tests/unix/opengles1cl/opengles1cl.pro @@ -1,9 +1,9 @@ SOURCES = opengles1cl.cpp -INCLUDEPATH += $$QMAKE_INCDIR_OPENGL +INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES1CL -for(p, QMAKE_LIBDIR_OPENGL) { +for(p, QMAKE_LIBDIR_OPENGL_ES1CL) { exists($$p):LIBS += -L$$p } CONFIG -= qt -LIBS += $$QMAKE_LIBS_OPENGL_QT +LIBS += $$QMAKE_LIBS_OPENGL_ES1CL diff --git a/config.tests/unix/opengles2/opengles2.pro b/config.tests/unix/opengles2/opengles2.pro index 0dfae42..c383fd0 100644 --- a/config.tests/unix/opengles2/opengles2.pro +++ b/config.tests/unix/opengles2/opengles2.pro @@ -1,9 +1,9 @@ SOURCES = opengles2.cpp -INCLUDEPATH += $$QMAKE_INCDIR_OPENGL +INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES2 -for(p, QMAKE_LIBDIR_OPENGL) { +for(p, QMAKE_LIBDIR_OPENGL_ES2) { exists($$p):LIBS += -L$$p } CONFIG -= qt -LIBS += $$QMAKE_LIBS_OPENGL_QT +LIBS += $$QMAKE_LIBS_OPENGL_ES2 diff --git a/doc/src/development/qmake-manual.qdoc b/doc/src/development/qmake-manual.qdoc index 6c53242..09f1b9b 100644 --- a/doc/src/development/qmake-manual.qdoc +++ b/doc/src/development/qmake-manual.qdoc @@ -2252,6 +2252,18 @@ For example: If the OpenGL implementation uses EGL (most OpenGL/ES systems), then QMAKE_INCDIR_EGL may also need to be set. + \section1 QMAKE_INCDIR_OPENGL_ES1, QMAKE_INCDIR_OPENGL_ES1CL, QMAKE_INCDIR_OPENGL_ES2 + + These variables contain the location of OpenGL headers files to be added + to INCLUDEPATH when building an application with OpenGL ES 1, OpenGL ES 1 Common + Lite or OpenGL ES 2 support respectively. + + The value of this variable is typically handled by \c qmake or + \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified. + + If the OpenGL implementation uses EGL (most OpenGL/ES systems), + then QMAKE_INCDIR_EGL may also need to be set. + \target QMAKE_INCDIR_OPENVG \section1 QMAKE_INCDIR_OPENVG @@ -2496,6 +2508,17 @@ For example: variable is typically handled by \c qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified. + \section1 QMAKE_LIBS_OPENGL_ES1, QMAKE_LIBS_OPENGL_ES1CL, QMAKE_LIBS_OPENGL_ES2 + + These variables contain all the OpenGL libraries for OpenGL ES 1, + OpenGL ES 1 Common Lite profile and OpenGL ES 2. + + The value of these variables is typically handled by \c qmake or + \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified. + + If the OpenGL implementation uses EGL (most OpenGL/ES systems), + then QMAKE_LIBS_EGL may also need to be set. + \section1 QMAKE_LIBS_OPENVG This variable contains all OpenVG libraries. The value of this diff --git a/mkspecs/common/linux.conf b/mkspecs/common/linux.conf index cc5c38b..1ae5608 100644 --- a/mkspecs/common/linux.conf +++ b/mkspecs/common/linux.conf @@ -13,6 +13,12 @@ QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS] QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS] QMAKE_INCDIR_OPENGL = /usr/X11R6/include QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib +QMAKE_INCDIR_OPENGL_ES1 = $$QMAKE_INCDIR_OPENGL +QMAKE_LIBDIR_OPENGL_ES1 = $$QMAKE_LIBDIR_OPENGL +QMAKE_INCDIR_OPENGL_ES1CL = $$QMAKE_INCDIR_OPENGL +QMAKE_LIBDIR_OPENGL_ES1CL = $$QMAKE_LIBDIR_OPENGL +QMAKE_INCDIR_OPENGL_ES2 = $$QMAKE_INCDIR_OPENGL +QMAKE_LIBDIR_OPENGL_ES2 = $$QMAKE_LIBDIR_OPENGL QMAKE_INCDIR_EGL = QMAKE_LIBDIR_EGL = QMAKE_INCDIR_OPENVG = @@ -26,6 +32,9 @@ QMAKE_LIBS_NIS = -lnsl QMAKE_LIBS_EGL = -lEGL QMAKE_LIBS_OPENGL = -lGLU -lGL QMAKE_LIBS_OPENGL_QT = -lGL +QMAKE_LIBS_OPENGL_ES1 = -lGLES_CM +QMAKE_LIBS_OPENGL_ES1CL = -lGLES_CL +QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 QMAKE_LIBS_OPENVG = -lOpenVG QMAKE_LIBS_THREAD = -lpthread diff --git a/mkspecs/common/wince/qmake.conf b/mkspecs/common/wince/qmake.conf index d6e4ba7..d87be02 100644 --- a/mkspecs/common/wince/qmake.conf +++ b/mkspecs/common/wince/qmake.conf @@ -64,6 +64,10 @@ QMAKE_LIBS_NETWORK = ws2.lib QMAKE_LIBS_OPENGL = QMAKE_LIBS_COMPAT = +QMAKE_LIBS_OPENGL_ES1 = libGLES_CM.lib +QMAKE_LIBS_OPENGL_ES1CL = libGLES_CL.lib +QMAKE_LIBS_OPENGL_ES2 = libGLESv2.lib + QMAKE_LIBS_QT_ENTRY = -lqtmain QMAKE_MOC = $$[QT_INSTALL_BINS]\moc.exe diff --git a/mkspecs/features/unix/opengl.prf b/mkspecs/features/unix/opengl.prf index 2fdf324..f2db819 100644 --- a/mkspecs/features/unix/opengl.prf +++ b/mkspecs/features/unix/opengl.prf @@ -1,4 +1,22 @@ -INCLUDEPATH += $$QMAKE_INCDIR_OPENGL -!isEmpty(QMAKE_LIBDIR_OPENGL):QMAKE_LIBDIR += $$QMAKE_LIBDIR_OPENGL -target_qt:LIBS_PRIVATE += $$QMAKE_LIBS_OPENGL_QT -else:LIBS += $$QMAKE_LIBS_OPENGL +contains(QT_CONFIG, opengles1) { + INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES1 + !isEmpty(QMAKE_LIBDIR_OPENGL_ES1):QMAKE_LIBDIR += $$QMAKE_LIBDIR_OPENGL_ES1 + target_qt:LIBS_PRIVATE += $$QMAKE_LIBS_OPENGL_ES1 + else:LIBS += $$QMAKE_LIBS_OPENGL_ES1 +} else:contains(QT_CONFIG, opengles1cl) { + INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES1CL + !isEmpty(QMAKE_LIBDIR_OPENGL_ES1CL):QMAKE_LIBDIR += $$QMAKE_LIBDIR_OPENGL_ES1CL + target_qt:LIBS_PRIVATE += $$QMAKE_LIBS_OPENGL_ES1CL + else:LIBS += $$QMAKE_LIBS_OPENGL_ES1CL +} else:contains(QT_CONFIG, opengles2) { + INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES2 + !isEmpty(QMAKE_LIBDIR_OPENGL_ES2):QMAKE_LIBDIR += $$QMAKE_LIBDIR_OPENGL_ES2 + target_qt:LIBS_PRIVATE += $$QMAKE_LIBS_OPENGL_ES2 + else:LIBS += $$QMAKE_LIBS_OPENGL_ES2 +} else { + INCLUDEPATH += $$QMAKE_INCDIR_OPENGL + !isEmpty(QMAKE_LIBDIR_OPENGL):QMAKE_LIBDIR += $$QMAKE_LIBDIR_OPENGL + target_qt:LIBS_PRIVATE += $$QMAKE_LIBS_OPENGL_QT + else:LIBS += $$QMAKE_LIBS_OPENGL +} + diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index a212675..7d6052b 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -103,7 +103,7 @@ x11 { LIBS_PRIVATE += -lfreetype } else { ### Note: how does this compile with a non-system freetype? - # This probably doesn't compile + # This probably does not compile } } else { DEFINES *= QT_NO_FREETYPE @@ -150,17 +150,15 @@ embedded { INCLUDEPATH += ../3rdparty/harfbuzz/src -wince*: { - contains(QT_CONFIG,opengles1) { - QMAKE_LIBS += "libGLES_CM.lib" - } - contains(QT_CONFIG,opengles1cl) { - QMAKE_LIBS += "libGLES_CL.lib" - } - contains(QT_CONFIG,opengles2) { - QMAKE_LIBS += "libGLESv2.lib" - } - +contains(QT_CONFIG,opengles1) { + LIBS_PRIVATE += $$QMAKE_LIBS_OPENGL_ES1 + LIBS += $$QMAKE_LFLAGS_OPENGL_ES1 +} else:contains(QT_CONFIG,opengles1cl) { + LIBS_PRIVATE += $$QMAKE_LIBS_OPENGL_ES1CL + LIBS += $$QMAKE_LFLAGS_OPENGL_ES1CL +} else:contains(QT_CONFIG,opengles2) { + LIBS_PRIVATE += $$QMAKE_LIBS_OPENGL_ES2 + LIBS += $$QMAKE_LFLAGS_OPENGL_ES2 } else { LIBS_PRIVATE += $$QMAKE_LIBS_OPENGL LIBS += $$QMAKE_LFLAGS_OPENGL -- cgit v0.12 From 83e497fdae56e11c79d913cdc665e78615291e9c Mon Sep 17 00:00:00 2001 From: Jure Repinc Date: Mon, 2 Nov 2009 17:48:36 +0100 Subject: Updated Slovenian translation of Qt libraries Merge-request: 1977 Reviewed-by: Oswald Buddenhagen --- translations/qt_sl.ts | 1785 +++++++++++++++++++++++++++---------------------- 1 file changed, 986 insertions(+), 799 deletions(-) diff --git a/translations/qt_sl.ts b/translations/qt_sl.ts index 517ce71..c7684e3 100644 --- a/translations/qt_sl.ts +++ b/translations/qt_sl.ts @@ -12,7 +12,7 @@ FakeReply - + Fake error ! Lažna napaka. @@ -23,14 +23,6 @@
- InputPrivate - - - PUSH: read in bytes = %1 (frames=%2) - - - - Phonon:: @@ -117,10 +109,10 @@ da je nameščen paket libgstreamer-plugins-base. Manjka potreben kodek. Za predvajanje te vsebine morate namestiti sledeče kodeke: %0 - + - + @@ -129,12 +121,12 @@ da je nameščen paket libgstreamer-plugins-base. Ni moč odpreti večpredstavnostnega vira. - + Invalid source type. Neveljavna vrsta vira. - + Could not locate media source. Ni moč najti večpredstavnostnega vira. @@ -150,11 +142,63 @@ da je nameščen paket libgstreamer-plugins-base. + Phonon::MMF + + + Audio Output + Predvajanje zvoka + + + + The audio output device + Naprava za predvajanje zvoka + + + Phonon::MMF::AudioEqualizer - + Frequency band, %1 Hz - + Frekvenčni pas, %1 Hz + + + + Phonon::MMF::EffectFactory + + + audio equalizer + izenačevalnik zvoka + + + + Bass boost + Ojačanje basov + + + + Distance Attenuation + Utišanje zaradi razdalje + + + + + Environmental Reverb + Okoljsko odmevanje + + + + Loudness + Glasnost + + + + Source Orientation + Usmerjenost vira + + + + Stereo Widening + Razširitev sterea @@ -888,7 +932,7 @@ v Dejanje na vtičnici ni podprto - + Socket operation timed out Čas za dejanje na vtičnici je potekel @@ -922,6 +966,14 @@ v + QAccessibleButton + + + Press + Pritisni + + + QApplication @@ -939,7 +991,7 @@ v Napaka nezdružljivosti knjižnice Qt - + QT_LAYOUT_DIRECTION Translate this string to the string 'LTR' in left-to-right languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout. LTR @@ -951,117 +1003,6 @@ v - QAudioInputPrivate - - - QAudioInput: snd_pcm_hw_params_any: err = %1 - - - - - QAudioInput: snd_pcm_hw_params_set_rate_resample: err = %1 - - - - - QAudioInput: snd_pcm_hw_params_set_access: err = %1 - - - - - QAudioInput: snd_pcm_hw_params_set_format: err = %1 - - - - - QAudioInput: snd_pcm_hw_params_set_channels: err = %1 - - - - - QAudioInput: snd_pcm_hw_params_set_rate_near: err = %1 - - - - - QAudioInput: snd_pcm_hw_params_set_buffer_time_near: err = %1 - - - - - QAudioInput: snd_pcm_hw_params_set_period_time_near: err = %1 - - - - - QAudioInput: snd_pcm_hw_params_set_periods_near: err = %1 - - - - - QAudioInput: snd_pcm_hw_params: err = %1 - - - - - PULL: read in bytes = %1 (frames=%2) - - - - - QAudioOutputPrivate - - - QAudioOutput: snd_pcm_hw_params_any: err = %1 - - - - - QAudioOutput: snd_pcm_hw_params_set_rate_resample: err = %1 - - - - - QAudioOutput: snd_pcm_hw_params_set_access: err = %1 - - - - - QAudioOutput: snd_pcm_hw_params_set_format: err = %1 - - - - - QAudioOutput: snd_pcm_hw_params_set_channels: err = %1 - - - - - QAudioOutput: snd_pcm_hw_params_set_rate_near: err = %1 - - - - - QAudioOutput: snd_pcm_hw_params_set_buffer_time_near: err = %1 - - - - - QAudioOutput: snd_pcm_hw_params_set_period_time_near: err = %1 - - - - - QAudioOutput: snd_pcm_hw_params_set_periods_near: err = %1 - - - - - QAudioOutput: snd_pcm_hw_params: err = %1 - - - - QAxSelect @@ -1087,7 +1028,7 @@ v QCheckBox - + Uncheck Odznači @@ -1105,7 +1046,7 @@ v QColorDialog - + Hu&e: &Odtenek: @@ -1145,7 +1086,7 @@ v Izberite barvo - + &Basic colors &Osnovne barve @@ -1214,7 +1155,7 @@ v %1: does not exist QSystemSemaphore - %1: ne obstaja + %1: ne obstaja @@ -1345,7 +1286,7 @@ v - + OK V redu @@ -1544,7 +1485,7 @@ v Usodna napaka: - + &Show this message again &To sporočilo naslednjič spet prikaži @@ -1565,7 +1506,7 @@ v Will not rename sequential file using block copy - + Sekvenčna datoteka ne bo preimenovana z uporabo kopiranja blokov @@ -1596,7 +1537,7 @@ v QFileDialog - + All Files (*) Vse datoteke (*) @@ -1724,7 +1665,7 @@ Ali jo kljub temu želite izbrisati? Ni bilo moč izbrisati mape. - + Recent Places Nedavna mesta @@ -1734,12 +1675,12 @@ Ali jo kljub temu želite izbrisati? Vse datoteke (*.*) - + Save As Shrani kot - + Drive Pogon @@ -1918,50 +1859,50 @@ Ali jo kljub temu želite izbrisati? QFontDatabase - + Normal Normalno - + - + Bold Polkrepko - - + + Demi Bold - + - + Black Črni - + Demi - + Light Lahko - - + + Italic Ležeče - - + + Oblique Nagnjeno @@ -2063,32 +2004,32 @@ Ali jo kljub temu želite izbrisati? Thai - Tajski + Tajska Lao - Laoška + Laoška Tibetan - tibetansko + Tibetanska Myanmar - Mjanmar + Mjanmarska Georgian - gruzijsko + Gruzijska Khmer - Kmersko + Kmerska @@ -2118,7 +2059,7 @@ Ali jo kljub temu želite izbrisati? Symbol - Znak + Simbol @@ -2134,7 +2075,7 @@ Ali jo kljub temu želite izbrisati? QFontDialog - + &Font &Pisava @@ -2174,7 +2115,7 @@ Ali jo kljub temu želite izbrisati? S&istem pisanja - + Select Font Izberite pisavo @@ -2337,13 +2278,9 @@ Ali jo kljub temu želite izbrisati? QHostInfoAgent - - - + - - - + Host not found Ni moč najti gostitelja @@ -2364,20 +2301,20 @@ Ali jo kljub temu želite izbrisati? Neznana napaka - + No host name given - Podano ni bilo nobeno ime gostitelja + Podano ni bilo nobeno ime gostitelja Invalid hostname - Neveljavno ime gostitelja + Neveljavno ime gostitelja QHttp - + @@ -2409,7 +2346,7 @@ Ali jo kljub temu želite izbrisati? Strežnik je nepričakovano prekinil povezavo - + Unknown authentication method Neznan način overjanja @@ -2419,13 +2356,13 @@ Ali jo kljub temu želite izbrisati? Napaka pri pisanju odziva na napravo - + Connection refused Povezava je zavrnjena - + Host %1 not found @@ -2440,7 +2377,7 @@ Ali jo kljub temu želite izbrisati? Zahtevek HTTP ni uspel - + Invalid HTTP response header Neveljavna glava odgovora HTTP @@ -2495,7 +2432,7 @@ Ali jo kljub temu želite izbrisati? Potrebna je overitev - + Connection refused (or timed out) Povezava je bila zavrnjena (ali pa je potekel čas) @@ -2694,7 +2631,7 @@ Ali jo kljub temu želite izbrisati? QIODevice - + Permission denied Nimate dovoljenja @@ -3174,7 +3111,7 @@ Ali jo kljub temu želite izbrisati? QMenuBar - + Actions Dejanja @@ -3527,7 +3464,7 @@ Ali jo kljub temu želite izbrisati? Unable to alloc statement - + Ni moč dodeliti izjave @@ -3553,7 +3490,7 @@ Ali jo kljub temu želite izbrisati? QODBCDriver - + Unable to connect Ni moč vzpostaviti povezave @@ -3586,7 +3523,7 @@ Ali jo kljub temu želite izbrisati? QODBCResult - + QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration QODBCResult::reset: ni moč nastaviti 'SQL_CURSOR_STATIC' kot lastnosti izjave. Preverite nastavitve gonilnika ODBC @@ -3638,7 +3575,7 @@ Ali jo kljub temu želite izbrisati? QObject - + Invalid hostname Neveljavno ime gostitelja @@ -3668,42 +3605,6 @@ Ali jo kljub temu želite izbrisati? No host name given Podano ni bilo nobeno ime gostitelja - - - audio equalizer - - - - - Bass boost - - - - - Distance Attenuation - - - - - - Environmental Reverb - - - - - Loudness - - - - - Source Orientation - - - - - Stereo Widening - - QPPDOptionsModel @@ -4050,7 +3951,7 @@ Ali jo kljub temu želite izbrisati? US Common #10 Envelope (105 x 241 mm) - + OK V redu @@ -4610,7 +4511,7 @@ Izberite drugo ime datoteke. Čas za dejanje procesa je potekel - + @@ -4826,32 +4727,32 @@ Izberite drugo ime datoteke. ID - + ID Location - + Lokacija Condition - + Pogoj Ignore-count - + Število prezrtij Single-shot - + Enojen zadetek Hit-count - + Število zadetkov @@ -4859,12 +4760,12 @@ Izberite drugo ime datoteke. New - + Nova Delete - Izbriši + Izbriši @@ -4873,17 +4774,17 @@ Izberite drugo ime datoteke. Go to Line - + Pojdi v vrstico Line: - + Vrstica: Interrupt - + Prekini @@ -4893,7 +4794,7 @@ Izberite drugo ime datoteke. Continue - Nadaljuj + Nadaljuj @@ -4903,7 +4804,7 @@ Izberite drugo ime datoteke. Step Into - + Vstopi @@ -4913,7 +4814,7 @@ Izberite drugo ime datoteke. Step Over - + Prestopi @@ -4923,7 +4824,7 @@ Izberite drugo ime datoteke. Step Out - + Izstopi @@ -4933,7 +4834,7 @@ Izberite drugo ime datoteke. Run to Cursor - + Zaženi do kazalca @@ -4943,12 +4844,12 @@ Izberite drugo ime datoteke. Run to New Script - + Zaženi do novega skripta Toggle Breakpoint - + Preklopi prekinitveno točko @@ -4958,22 +4859,22 @@ Izberite drugo ime datoteke. Clear Debug Output - + Počisti razhroščevalni izhod Clear Error Log - + Počisti dnevnik napak Clear Console - + Počisti konzolo &Find in Script... - + Najdi v &skriptu ... @@ -4983,7 +4884,7 @@ Izberite drugo ime datoteke. Find &Next - + Najdi &naslednje @@ -4993,7 +4894,7 @@ Izberite drugo ime datoteke. Find &Previous - + Najdi &predhodno @@ -5008,7 +4909,7 @@ Izberite drugo ime datoteke. Debug - + Razhrošči @@ -5016,32 +4917,32 @@ Izberite drugo ime datoteke. Close - Zapri + Zapri Previous - + Predhodno Next - + Naslednje Case Sensitive - + Občutljivo na velikost črk Whole words - + Cele besede <img src=":/qt/scripttools/debugging/images/wrap.png">&nbsp;Search wrapped - + <img src=":/qt/scripttools/debugging/images/wrap.png">&nbsp;Iskanje se nadaljuje na drugem koncu @@ -5049,12 +4950,12 @@ Izberite drugo ime datoteke. Name - Ime + Ime Value - Vrednost + Vrednost @@ -5062,17 +4963,17 @@ Izberite drugo ime datoteke. Level - + Stopnja Name - Ime + Ime Location - + Lokacija @@ -5080,22 +4981,22 @@ Izberite drugo ime datoteke. Toggle Breakpoint - + Preklopi prekinitveno točko Disable Breakpoint - + Onemogoči prekinitveno točko Enable Breakpoint - + Omogoči prekinitveno točko Breakpoint Condition: - + Pogoj za prelomno točko: @@ -5103,52 +5004,52 @@ Izberite drugo ime datoteke. Loaded Scripts - + Naloženi skripti Breakpoints - + Prelomne točke Stack - + Sklad Locals - + Krajevno Console - + Konzola Debug Output - + Razhroščevalni izhod Error Log - + Dnevnik napak Search - Išči + Išči View - + Videz Qt Script Debugger - + Razhroščevalnik za Qt Script @@ -5156,7 +5057,7 @@ Izberite drugo ime datoteke. Close - Zapri + Zapri @@ -5521,7 +5422,7 @@ Izberite drugo ime datoteke. Bass Boost - + Ojačanje basov @@ -5536,12 +5437,12 @@ Izberite drugo ime datoteke. Treble Up - + Več visokih tonov Treble Down - + Manj visokih tonov @@ -5736,7 +5637,7 @@ Izberite drugo ime datoteke. Select - Izberi + Izberi @@ -5771,17 +5672,17 @@ Izberite drugo ime datoteke. Call - Pokliči + Pokliči Hangup - Odloži + Odloži Flip - Obrni + Obrni @@ -5954,7 +5855,7 @@ Izberite drugo ime datoteke. Exit - Končaj + Končaj @@ -6176,7 +6077,7 @@ Izberite drugo ime datoteke. QTextControl - + &Undo &Razveljavi @@ -6219,7 +6120,7 @@ Izberite drugo ime datoteke. QToolButton - + Press Pritisni @@ -6334,12 +6235,12 @@ Izberite drugo ime datoteke. QWebFrame - + Request cancelled Zahtevek je bil preklican - + Request blocked Zahtevek je bil blokiran @@ -6367,12 +6268,12 @@ Izberite drugo ime datoteke. QWebPage - + Bad HTTP request Napačen zahtevek HTTP - + Submit default label for Submit buttons in forms on web pages Pošlji @@ -6390,7 +6291,7 @@ Izberite drugo ime datoteke. Ponastavi - + This is a searchable index. Enter search keywords: text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index' To je stvarno kazalo z iskanjem. Vnesite iskane besede: @@ -6777,7 +6678,7 @@ Izberite drugo ime datoteke. Movie time scrubber Media controller element - + @@ -6805,7 +6706,7 @@ Izberite drugo ime datoteke. - Remaining move time + Remaining movie time Media controller element Preostali čas filma @@ -6900,7 +6801,7 @@ Izberite drugo ime datoteke. %1 (%2×%3 pik) - + Web Inspector - %2 Web Inspector - %2 @@ -6974,24 +6875,24 @@ Izberite drugo ime datoteke. %n file(s) number of chosen file - %n datotek - %n datotek - %n datotek + %n datoteka + %n datoteki + %n datoteke %n datotek - + JavaScript Alert - %1 Opozorilo JavaScript - %1 - + JavaScript Confirm - %1 Potrditev JavaScript - %1 - + JavaScript Prompt - %1 Poziv JavaScript - %1 @@ -7006,7 +6907,7 @@ Izberite drugo ime datoteke. Kot kaže ima skript na tej strani težavo. Ali želite ustaviti skript? - + Move the cursor to the next character Premakni kazalec na naslednji znak @@ -7215,6 +7116,12 @@ Izberite drugo ime datoteke. Align Right Poravnaj desno + + + Remaining move time + Media controller element + Preostali čas filma + QWhatsThisAction @@ -7227,7 +7134,7 @@ Izberite drugo ime datoteke. QWidget - + * * @@ -7902,20 +7809,20 @@ Izberite drugo ime datoteke. %1 takes at most %n argument(s). %2 is therefore invalid. + %1 potrebuje največ %n argument. %2 zato ni veljavno. + %1 potrebuje največ %n argumenta. %2 zato ni veljavno. + %1 potrebuje največ %n argumente. %2 zato ni veljavno. %1 potrebuje največ %n argumentov. %2 zato ni veljavno. - - - %1 requires at least %n argument(s). %2 is therefore invalid. + %1 potrebuje najmanj %n argument. %2 zato ni veljavno. + %1 potrebuje najmanj %n argumenta. %2 zato ni veljavno. + %1 potrebuje najmanj %n argumente. %2 zato ni veljavno. %1 potrebuje najmanj %n argumentov. %2 zato ni veljavno. - - - @@ -8613,277 +8520,207 @@ Izberite drugo ime datoteke. - - empty particle cannot be derived from non-empty particle - - - - - derived particle is missing element %1 - - - - - derived element %1 is missing value constraint as defined in base particle - - - - - derived element %1 has weaker value constraint than base particle - - - - - fixed value constraint of element %1 differs from value constraint in base particle - - - - - derived element %1 cannot be nillable as base element is not nillable - - - - - block constraints of derived element %1 must not be more weaker than in the base element - - - - - simple type of derived element %1 cannot be validly derived from base element - - - - - complex type of derived element %1 cannot be validly derived from base element - - - - - element %1 is missing in derived particle - - - - - element %1 does not match namespace constraint of wildcard in base particle - - - - - wildcard in derived particle is not a valid subset of wildcard in base particle - - - - - processContent of wildcard in derived particle is weaker than wildcard in base particle - - - - - derived particle allows content that is not allowed in the base particle - - - - %1 has inheritance loop in its base type %2 + %1 has inheritance loop in its base type %2. - circular inheritance of base type %1 + Circular inheritance of base type %1. - circular inheritance of union %1 + Circular inheritance of union %1. - %1 is not allowed to derive from %2 by restriction as the latter defines it as final + %1 is not allowed to derive from %2 by restriction as the latter defines it as final. - %1 is not allowed to derive from %2 by extension as the latter defines it as final + %1 is not allowed to derive from %2 by extension as the latter defines it as final. - base type of simple type %1 cannot be complex type %2 + Base type of simple type %1 cannot be complex type %2. - simple type %1 cannot have direct base type %2 + Simple type %1 cannot have direct base type %2. - simple type %1 is not allowed to have base type %2 + Simple type %1 is not allowed to have base type %2. - simple type %1 can only have simple atomic type as base type + Simple type %1 can only have simple atomic type as base type. - simple type %1 cannot derive from %2 as the latter defines restriction as final + Simple type %1 cannot derive from %2 as the latter defines restriction as final. - variety of item type of %1 must be either atomic or union + Variety of item type of %1 must be either atomic or union. - variety of member types of %1 must be atomic + Variety of member types of %1 must be atomic. - %1 is not allowed to derive from %2 by list as the latter defines it as final + %1 is not allowed to derive from %2 by list as the latter defines it as final. - simple type %1 is only allowed to have %2 facet + Simple type %1 is only allowed to have %2 facet. - base type of simple type %1 must have variety of type list + Base type of simple type %1 must have variety of type list. - base type of simple type %1 has defined derivation by restriction as final + Base type of simple type %1 has defined derivation by restriction as final. - item type of base type does not match item type of %1 + Item type of base type does not match item type of %1. - simple type %1 contains not allowed facet type %2 + Simple type %1 contains not allowed facet type %2. - %1 is not allowed to derive from %2 by union as the latter defines it as final + %1 is not allowed to derive from %2 by union as the latter defines it as final. - %1 is not allowed to have any facets + %1 is not allowed to have any facets. - base type %1 of simple type %2 must have variety of union + Base type %1 of simple type %2 must have variety of union. - base type %1 of simple type %2 is not allowed to have restriction in %3 attribute + Base type %1 of simple type %2 is not allowed to have restriction in %3 attribute. - member type %1 cannot be derived from member type %2 of %3's base type %4 + Member type %1 cannot be derived from member type %2 of %3's base type %4. - derivation method of %1 must be extension because the base type %2 is a simple type + Derivation method of %1 must be extension because the base type %2 is a simple type. - complex type %1 has duplicated element %2 in its content model + Complex type %1 has duplicated element %2 in its content model. - complex type %1 has non-deterministic content + Complex type %1 has non-deterministic content. - attributes of complex type %1 are not a valid extension of the attributes of base type %2: %3 + Attributes of complex type %1 are not a valid extension of the attributes of base type %2: %3. - content model of complex type %1 is not a valid extension of content model of %2 + Content model of complex type %1 is not a valid extension of content model of %2. - complex type %1 must have simple content + Complex type %1 must have simple content. - complex type %1 must have the same simple type as its base class %2 + Complex type %1 must have the same simple type as its base class %2. - complex type %1 cannot be derived from base type %2%3 + Complex type %1 cannot be derived from base type %2%3. - attributes of complex type %1 are not a valid restriction from the attributes of base type %2: %3 + Attributes of complex type %1 are not a valid restriction from the attributes of base type %2: %3. - complex type %1 with simple content cannot be derived from complex base type %2 + Complex type %1 with simple content cannot be derived from complex base type %2. - item type of simple type %1 cannot be a complex type + Item type of simple type %1 cannot be a complex type. - member type of simple type %1 cannot be a complex type + Member type of simple type %1 cannot be a complex type. - %1 is not allowed to have a member type with the same name as itself + %1 is not allowed to have a member type with the same name as itself. - %1 facet collides with %2 facet + %1 facet collides with %2 facet. - %1 facet must have the same value as %2 facet of base type + %1 facet must have the same value as %2 facet of base type. - %1 facet must be equal or greater than %2 facet of base type + %1 facet must be equal or greater than %2 facet of base type. @@ -8895,7 +8732,7 @@ Izberite drugo ime datoteke. - %1 facet must be less than or equal to %2 facet of base type + %1 facet must be less than or equal to %2 facet of base type. @@ -8905,225 +8742,225 @@ Izberite drugo ime datoteke. - unknown notation %1 used in %2 facet + Unknown notation %1 used in %2 facet. - %1 facet contains invalid value %2: %3 + %1 facet contains invalid value %2: %3. - %1 facet cannot be %2 or %3 if %4 facet of base type is %5 + %1 facet cannot be %2 or %3 if %4 facet of base type is %5. - %1 facet cannot be %2 if %3 facet of base type is %4 + %1 facet cannot be %2 if %3 facet of base type is %4. - %1 facet must be less than or equal to %2 facet + %1 facet must be less than or equal to %2 facet. - %1 facet must be less than %2 facet of base type + %1 facet must be less than %2 facet of base type. - %1 facet and %2 facet cannot appear together + %1 facet and %2 facet cannot appear together. - %1 facet must be greater than %2 facet of base type + %1 facet must be greater than %2 facet of base type. - %1 facet must be less than %2 facet + %1 facet must be less than %2 facet. - %1 facet must be greater than or equal to %2 facet of base type + %1 facet must be greater than or equal to %2 facet of base type. - simple type contains not allowed facet %1 + Simple type contains not allowed facet %1. - %1, %2, %3, %4, %5 and %6 facets are not allowed when derived by list + %1, %2, %3, %4, %5 and %6 facets are not allowed when derived by list. - only %1 and %2 facets are allowed when derived by union + Only %1 and %2 facets are allowed when derived by union. - %1 contains %2 facet with invalid data: %3 + %1 contains %2 facet with invalid data: %3. - attribute group %1 contains attribute %2 twice - skupina lastnosti %1 dvakrat vsebuje lastnost %2 + Attribute group %1 contains attribute %2 twice. + Skupina lastnosti %1 dvakrat vsebuje lastnost %2. - attribute group %1 contains two different attributes that both have types derived from %2 + Attribute group %1 contains two different attributes that both have types derived from %2. - attribute group %1 contains attribute %2 that has value constraint but type that inherits from %3 + Attribute group %1 contains attribute %2 that has value constraint but type that inherits from %3. - complex type %1 contains attribute %2 twice - kompleksna vrsta %1 dvakrat vsebuje lastnost %2 + Complex type %1 contains attribute %2 twice. + Kompleksna vrsta %1 dvakrat vsebuje lastnost %2. - complex type %1 contains two different attributes that both have types derived from %2 + Complex type %1 contains two different attributes that both have types derived from %2. - complex type %1 contains attribute %2 that has value constraint but type that inherits from %3 + Complex type %1 contains attribute %2 that has value constraint but type that inherits from %3. - element %1 is not allowed to have a value constraint if its base type is complex + Element %1 is not allowed to have a value constraint if its base type is complex. - element %1 is not allowed to have a value constraint if its type is derived from %2 + Element %1 is not allowed to have a value constraint if its type is derived from %2. - value constraint of element %1 is not of elements type: %2 + Value constraint of element %1 is not of elements type: %2. - element %1 is not allowed to have substitution group affiliation as it is no global element + Element %1 is not allowed to have substitution group affiliation as it is no global element. - type of element %1 cannot be derived from type of substitution group affiliation + Type of element %1 cannot be derived from type of substitution group affiliation. - value constraint of attribute %1 is not of attributes type: %2 + Value constraint of attribute %1 is not of attributes type: %2. - attribute %1 has value constraint but has type derived from %2 + Attribute %1 has value constraint but has type derived from %2. - %1 attribute in derived complex type must be %2 like in base type + %1 attribute in derived complex type must be %2 like in base type. - attribute %1 in derived complex type must have %2 value constraint like in base type + Attribute %1 in derived complex type must have %2 value constraint like in base type. - attribute %1 in derived complex type must have the same %2 value constraint like in base type + Attribute %1 in derived complex type must have the same %2 value constraint like in base type. - attribute %1 in derived complex type must have %2 value constraint + Attribute %1 in derived complex type must have %2 value constraint. - processContent of base wildcard must be weaker than derived wildcard + processContent of base wildcard must be weaker than derived wildcard. - element %1 exists twice with different types - element %1 obstaja dvakrat, z različnima vrstama + Element %1 exists twice with different types. + Element %1 obstaja dvakrat, z različnima vrstama. - particle contains non-deterministic wildcards + Particle contains non-deterministic wildcards. - base attribute %1 is required but derived attribute is not + Base attribute %1 is required but derived attribute is not. - type of derived attribute %1 cannot be validly derived from type of base attribute + Type of derived attribute %1 cannot be validly derived from type of base attribute. - value constraint of derived attribute %1 does not match value constraint of base attribute + Value constraint of derived attribute %1 does not match value constraint of base attribute. - derived attribute %1 does not exists in the base definition + Derived attribute %1 does not exists in the base definition. - derived attribute %1 does not match the wildcard in the base definition + Derived attribute %1 does not match the wildcard in the base definition. - base attribute %1 is required but missing in derived definition + Base attribute %1 is required but missing in derived definition. - derived definition contains an %1 element that does not exists in the base definition + Derived definition contains an %1 element that does not exists in the base definition - derived wildcard is not a subset of the base wildcard + Derived wildcard is not a subset of the base wildcard. @@ -9133,905 +8970,1255 @@ Izberite drugo ime datoteke. - attribute %1 from base type is missing in derived type + Attribute %1 from base type is missing in derived type. - type of derived attribute %1 differs from type of base attribute + Type of derived attribute %1 differs from type of base attribute. - base definition contains an %1 element that is missing in the derived definition + Base definition contains an %1 element that is missing in the derived definition - - can not process unknown element %1, expected elements are: %2 - ni moč obdelati neznanega elementa %1, pričakovani elementi so: %2 - - - - element %1 is not allowed in this scope, possible elements are: %2 - element %1 v tem obsegu ni dovoljen, možni elementi so: %2 + + %1 references unknown %2 or %3 element %4. + - - child element is missing in that scope, possible child elements are: %1 - v tem obsegu manjka podelement, možni podelementi so: %1 + + %1 references identity constraint %2 that is no %3 or %4 element. + - - document is not a XML schema - dokument ni shema XML + + %1 has a different number of fields from the identity constraint %2 that it references. + - - %1 attribute of %2 element contains invalid content: {%3} is not a value of type %4 - lastnost %1 elementa %2 vsebuje neveljavno vsebino: {%3} ni vrednost vrste %4 + + Base type %1 of %2 element cannot be resolved. + - - %1 attribute of %2 element contains invalid content: {%3} - lastnost %1 elementa %2 vsebuje neveljavno vsebino: {%3} + + Item type %1 of %2 element cannot be resolved. + - - target namespace %1 of included schema is different from the target namespace %2 as defined by the including schema + + Member type %1 of %2 element cannot be resolved. - - - target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema + + + + Type %1 of %2 element cannot be resolved. - - %1 element is not allowed to have the same %2 attribute value as the target namespace %3 + + Base type %1 of complex type cannot be resolved. - - %1 element without %2 attribute is not allowed inside schema without target namespace + + %1 cannot have complex base type that has a %2. - - - %1 element is not allowed inside %2 element if %3 attribute is present - element %1 znotraj elementa %2 ni dovoljen, če je prisotna lastnost %3 + + Content model of complex type %1 contains %2 element so it cannot be derived by extension from a non-empty type. + - - - - %1 element has neither %2 attribute nor %3 child element - element %1 nima niti lastnosti %2 niti podelementa %3 + + Complex type %1 cannot be derived by extension from %2 as the latter contains %3 element in its content model. + - - - - - - - - - - - - - - - %1 element with %2 child element must not have a %3 attribute - element %1 s podelementom %2 ne sme imeti lastnosti %3 + + Type of %1 element must be a simple type, %2 is not. + Vrsta elementa %1 mora biti preprosta, %2 to ni. - - %1 attribute of %2 element must be %3 or %4 - lastnost %1 elementa %2 mora biti %3 ali %4 + + Substitution group %1 of %2 element cannot be resolved. + - - %1 attribute of %2 element must have a value of %3 - lastnost %1 elementa %2 mora imeti vrednost %3 + + Substitution group %1 has circular definition. + + - - %1 attribute of %2 element must have a value of %3 or %4 - lastnost %1 elementa %2 mora imeti vrednost %3 ali %4 + Duplicated element names %1 in %2 element. + Podvojeni imeni elementov %1 v elementu %2. - - - - - - - - - - - - - - - %1 element must not have %2 and %3 attribute together - element %1 hkrati ne sme imeti lastnosti %2 in %3 + + + + + Reference %1 of %2 element cannot be resolved. + - - - content of %1 attribute of %2 element must not be from namespace %3 - vsebina lastnosti %1 elementa %2 ne sme biti iz imenskega prostora %3 + + Circular group reference for %1. + - - - %1 attribute of %2 element must not be %3 - lastnost %1 elementa %2 ne sme biti %3 + + %1 element is not allowed in this scope + Element %1 v tem obsegu ni dovoljen - - %1 attribute of %2 element must have the value %3 because the %4 attribute is set + + %1 element cannot have %2 attribute with value other than %3. - - specifying use='prohibited' inside an attribute group has no effect + + %1 element cannot have %2 attribute with value other than %3 or %4. - - %1 element must have either %2 or %3 attribute - element %1 mora imeti lastnost %2 ali %3 + + %1 or %2 attribute of reference %3 does not match with the attribute declaration %4. + - - %1 element must have either %2 attribute or %3 or %4 as child element + + Attribute group %1 has circular reference. - - %1 element requires either %2 or %3 attribute - element %1 potrebuje vsaj lastnost %2 ali %3 + + %1 attribute in %2 must have %3 use like in base type %4. + - - text or entity references not allowed inside %1 element + + Attribute wildcard of %1 is not a valid restriction of attribute wildcard of base type %2. - - - %1 attribute of %2 element must contain %3, %4 or a list of URIs + + %1 has attribute wildcard but its base type %2 has not. - - %1 element is not allowed in this context - element %1 v tem kontekstu ni dovoljen + + Union of attribute wildcard of type %1 and attribute wildcard of its base type %2 is not expressible. + - - %1 attribute of %2 element has larger value than %3 attribute + + Enumeration facet contains invalid content: {%1} is not a value of type %2. - - prefix of qualified name %1 is not defined + + Namespace prefix of qualified name %1 is not defined. - - - %1 attribute of %2 element must either contain %3 or the other values + + + %1 element %2 is not a valid restriction of the %3 element it redefines: %4. - - component with id %1 has been defined previously - komponenta z ID-jem %1 je že bila definirana + + Empty particle cannot be derived from non-empty particle. + - - element %1 already defined - element %1 je že definiran + + Derived particle is missing element %1. + - - attribute %1 already defined - lastnost %1 je že definirana + + Derived element %1 is missing value constraint as defined in base particle. + - - type %1 already defined - vrsta %1 je že definirana + + Derived element %1 has weaker value constraint than base particle. + - - attribute group %1 already defined - skupina lastnosti %1 je že definirana + + Fixed value constraint of element %1 differs from value constraint in base particle. + - - element group %1 already defined - skupina elementov %1 je že definirana + + Derived element %1 cannot be nillable as base element is not nillable. + - - notation %1 already defined - zapis %1 je že definiran + + Block constraints of derived element %1 must not be more weaker than in the base element. + - identity constraint %1 already defined + Simple type of derived element %1 cannot be validly derived from base element. - - duplicated facets in simple type %1 + + Complex type of derived element %1 cannot be validly derived from base element. - - %1 references unknown %2 or %3 element %4 + + Element %1 is missing in derived particle. - - %1 references identity constraint %2 that is no %3 or %4 element + + Element %1 does not match namespace constraint of wildcard in base particle. - - %1 has a different number of fields from the identity constraint %2 that it references + + Wildcard in derived particle is not a valid subset of wildcard in base particle. - - base type %1 of %2 element cannot be resolved + + processContent of wildcard in derived particle is weaker than wildcard in base particle. - - item type %1 of %2 element cannot be resolved + + Derived particle allows content that is not allowed in the base particle. - - member type %1 of %2 element cannot be resolved - + + Can not process unknown element %1, expected elements are: %2. + Ni moč obdelati neznanega elementa %1, pričakovani elementi so: %2. - - - - type %1 of %2 element cannot be resolved - + + Element %1 is not allowed in this scope, possible elements are: %2. + Element %1 v tem obsegu ni dovoljen, možni elementi so: %2. - - base type %1 of complex type cannot be resolved - + + Child element is missing in that scope, possible child elements are: %1. + V tem obsegu manjka podelement, možni podelementi so: %1. - - %1 cannot have complex base type that has a %2 - + + Document is not a XML schema. + Dokument ni shema XML. - - content model of complex type %1 contains %2 element so it cannot be derived by extension from a non-empty type - + + %1 attribute of %2 element contains invalid content: {%3} is not a value of type %4. + Lastnost %1 elementa %2 vsebuje neveljavno vsebino: {%3} ni vrednost vrste %4. - complex type %1 cannot be derived by extension from %2 as the latter contains %3 element in its content model - + %1 attribute of %2 element contains invalid content: {%3}. + Lastnost %1 elementa %2 vsebuje neveljavno vsebino: {%3}. - - type of %1 element must be a simple type, %2 is not - vrsta elementa %1 mora biti preprosta, %2 to ni + + Target namespace %1 of included schema is different from the target namespace %2 as defined by the including schema. + - - substitution group %1 of %2 element cannot be resolved + + + Target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema. - - substitution group %1 has circular definition + + %1 element is not allowed to have the same %2 attribute value as the target namespace %3. - + + %1 element without %2 attribute is not allowed inside schema without target namespace. + + + + + + %1 element is not allowed inside %2 element if %3 attribute is present. + Element %1 znotraj elementa %2 ni dovoljen, če je prisotna lastnost %3. + + + + + + %1 element has neither %2 attribute nor %3 child element. + Element %1 nima niti lastnosti %2 niti podelementa %3. + + + + + - duplicated element names %1 in %2 element - podvojeni imeni elementov %1 v elementu %2 + + + + + + + + + + + %1 element with %2 child element must not have a %3 attribute. + Element %1 s podelementom %2 ne sme imeti lastnosti %3. - - - - - reference %1 of %2 element cannot be resolved - + + %1 attribute of %2 element must be %3 or %4. + Lastnost %1 elementa %2 mora biti %3 ali %4. - - circular group reference for %1 - + + %1 attribute of %2 element must have a value of %3. + Lastnost %1 elementa %2 mora imeti vrednost %3. - - %1 element is not allowed in this scope - element %1 v tem obsegu ni dovoljen + + + %1 attribute of %2 element must have a value of %3 or %4. + Lastnost %1 elementa %2 mora imeti vrednost %3 ali %4. - - %1 element cannot have %2 attribute with value other than %3 - + + + + + + + + + + + + + + + %1 element must not have %2 and %3 attribute together. + Element %1 hkrati ne sme imeti lastnosti %2 in %3. - - %1 element cannot have %2 attribute with value other than %3 or %4 + + + Content of %1 attribute of %2 element must not be from namespace %3. + Vsebina lastnosti %1 elementa %2 ne sme biti iz imenskega prostora %3. + + + + + %1 attribute of %2 element must not be %3. + Lastnost %1 elementa %2 ne sme biti %3. + + + + %1 attribute of %2 element must have the value %3 because the %4 attribute is set. - - %1 or %2 attribute of reference %3 does not match with the attribute declaration %4 + + Specifying use='prohibited' inside an attribute group has no effect. - - attribute group %1 has circular reference + + %1 element must have either %2 or %3 attribute. + Element %1 mora imeti lastnost %2 ali %3. + + + + %1 element must have either %2 attribute or %3 or %4 as child element. - - %1 attribute in %2 must have %3 use like in base type %4 + + %1 element requires either %2 or %3 attribute. + Element %1 potrebuje vsaj lastnost %2 ali %3. + + + + Text or entity references not allowed inside %1 element - - attribute wildcard of %1 is not a valid restriction of attribute wildcard of base type %2 + + + %1 attribute of %2 element must contain %3, %4 or a list of URIs. - - %1 has attribute wildcard but its base type %2 has not + + %1 element is not allowed in this context. + Element %1 v tem kontekstu ni dovoljen. + + + + %1 attribute of %2 element has larger value than %3 attribute. - - union of attribute wildcard of type %1 and attribute wildcard of its base type %2 is not expressible + + Prefix of qualified name %1 is not defined. - - enumeration facet contains invalid content: {%1} is not a value of type %2 + + + %1 attribute of %2 element must either contain %3 or the other values. - - namespace prefix of qualified name %1 is not defined + + Component with id %1 has been defined previously. + Komponenta z ID-jem %1 je že bila definirana. + + + + Element %1 already defined. + Element %1 je že definiran. + + + + Attribute %1 already defined. + Lastnost %1 je že definirana. + + + + Type %1 already defined. + Vrsta %1 je že definirana. + + + + Attribute group %1 already defined. + Skupina lastnosti %1 je že definirana. + + + + Element group %1 already defined. + Skupina elementov %1 je že definirana. + + + + Notation %1 already defined. + Zapis %1 je že definiran. + + + + Identity constraint %1 already defined. - - - %1 element %2 is not a valid restriction of the %3 element it redefines: %4 + + Duplicated facets in simple type %1. - %1 is not valid according to %2 - %1 glede na %2 ni veljaven + %1 is not valid according to %2. + %1 glede na %2 ni veljaven. - string content does not match the length facet + String content does not match the length facet. - string content does not match the minLength facet + String content does not match the minLength facet. - string content does not match the maxLength facet + String content does not match the maxLength facet. - string content does not match pattern facet + String content does not match pattern facet. - string content is not listed in the enumeration facet + String content is not listed in the enumeration facet. - signed integer content does not match the maxInclusive facet + Signed integer content does not match the maxInclusive facet. - signed integer content does not match the maxExclusive facet + Signed integer content does not match the maxExclusive facet. - signed integer content does not match the minInclusive facet + Signed integer content does not match the minInclusive facet. - signed integer content does not match the minExclusive facet + Signed integer content does not match the minExclusive facet. - signed integer content is not listed in the enumeration facet + Signed integer content is not listed in the enumeration facet. - signed integer content does not match pattern facet + Signed integer content does not match pattern facet. - signed integer content does not match in the totalDigits facet + Signed integer content does not match in the totalDigits facet. - unsigned integer content does not match the maxInclusive facet + Unsigned integer content does not match the maxInclusive facet. - unsigned integer content does not match the maxExclusive facet + Unsigned integer content does not match the maxExclusive facet. - unsigned integer content does not match the minInclusive facet + Unsigned integer content does not match the minInclusive facet. - unsigned integer content does not match the minExclusive facet + Unsigned integer content does not match the minExclusive facet. - unsigned integer content is not listed in the enumeration facet + Unsigned integer content is not listed in the enumeration facet. - unsigned integer content does not match pattern facet + Unsigned integer content does not match pattern facet. - unsigned integer content does not match in the totalDigits facet + Unsigned integer content does not match in the totalDigits facet. - double content does not match the maxInclusive facet + Double content does not match the maxInclusive facet. - double content does not match the maxExclusive facet + Double content does not match the maxExclusive facet. - double content does not match the minInclusive facet + Double content does not match the minInclusive facet. - double content does not match the minExclusive facet + Double content does not match the minExclusive facet. - double content is not listed in the enumeration facet + Double content is not listed in the enumeration facet. - double content does not match pattern facet + Double content does not match pattern facet. - decimal content does not match in the fractionDigits facet + Decimal content does not match in the fractionDigits facet. - decimal content does not match in the totalDigits facet + Decimal content does not match in the totalDigits facet. - date time content does not match the maxInclusive facet + Date time content does not match the maxInclusive facet. - date time content does not match the maxExclusive facet + Date time content does not match the maxExclusive facet. - date time content does not match the minInclusive facet + Date time content does not match the minInclusive facet. - date time content does not match the minExclusive facet + Date time content does not match the minExclusive facet. - date time content is not listed in the enumeration facet + Date time content is not listed in the enumeration facet. - date time content does not match pattern facet + Date time content does not match pattern facet. - duration content does not match the maxInclusive facet + Duration content does not match the maxInclusive facet. - duration content does not match the maxExclusive facet + Duration content does not match the maxExclusive facet. - duration content does not match the minInclusive facet + Duration content does not match the minInclusive facet. - duration content does not match the minExclusive facet + Duration content does not match the minExclusive facet. - duration content is not listed in the enumeration facet + Duration content is not listed in the enumeration facet. - duration content does not match pattern facet + Duration content does not match pattern facet. - boolean content does not match pattern facet + Boolean content does not match pattern facet. - binary content does not match the length facet + Binary content does not match the length facet. - binary content does not match the minLength facet + Binary content does not match the minLength facet. - binary content does not match the maxLength facet + Binary content does not match the maxLength facet. - binary content is not listed in the enumeration facet + Binary content is not listed in the enumeration facet. - invalid QName content: %1 - neveljavna vsebina QName: %1 + Invalid QName content: %1. + Neveljavna vsebina QName: %1. - QName content is not listed in the enumeration facet + QName content is not listed in the enumeration facet. - QName content does not match pattern facet + QName content does not match pattern facet. - notation content is not listed in the enumeration facet + Notation content is not listed in the enumeration facet. - list content does not match length facet + List content does not match length facet. - list content does not match minLength facet + List content does not match minLength facet. - list content does not match maxLength facet + List content does not match maxLength facet. - list content is not listed in the enumeration facet + List content is not listed in the enumeration facet. - list content does not match pattern facet + List content does not match pattern facet. - union content is not listed in the enumeration facet + Union content is not listed in the enumeration facet. - union content does not match pattern facet + Union content does not match pattern facet. - data of type %1 are not allowed to be empty - podatki vrste %1 ne smejo biti prazni + Data of type %1 are not allowed to be empty. + Podatki vrste %1 ne smejo biti prazni. - element %1 is missing child element - elementu %1 manjka podelement + Element %1 is missing child element. + Elementu %1 manjka podelement. - there is one IDREF value with no corresponding ID: %1 + There is one IDREF value with no corresponding ID: %1. - loaded schema file is invalid + Loaded schema file is invalid. - %1 contains invalid data - %1 vsebuje neveljavne podatke + %1 contains invalid data. + %1 vsebuje neveljavne podatke. - xsi:schemaLocation namespace %1 has already appeared earlier in the instance document + xsi:schemaLocation namespace %1 has already appeared earlier in the instance document. - xsi:noNamespaceSchemaLocation cannot appear after the first no-namespace element or attribute + xsi:noNamespaceSchemaLocation cannot appear after the first no-namespace element or attribute. - no schema defined for validation + No schema defined for validation. - no definition for element %1 available - definicija za element %1 ni na voljo + No definition for element %1 available. + Definicija za element %1 ni na voljo. - specified type %1 is not known to the schema + Specified type %1 is not known to the schema. - element %1 is not defined in this scope - element %1 v tem obsegu ni definiran + Element %1 is not defined in this scope. + Element %1 v tem obsegu ni definiran. - declaration for element %1 does not exist - deklaracija elementa %1 ne obstaja + Declaration for element %1 does not exist. + Deklaracija elementa %1 ne obstaja. - element %1 contains invalid content - element %1 vsebuje neveljavno vsebino + Element %1 contains invalid content. + Element %1 vsebuje neveljavno vsebino. - element %1 is declared as abstract - element %1 je deklariran kot abstrakten + Element %1 is declared as abstract. + Element %1 je deklariran kot abstrakten. - element %1 is not nillable + Element %1 is not nillable. - attribute %1 contains invalid data: %2 - + Attribute %1 contains invalid data: %2 + Lastnost %1 vsebuje neveljavne podatke: %2 - element contains content although it is nillable + Element contains content although it is nillable. - fixed value constrained not allowed if element is nillable + Fixed value constrained not allowed if element is nillable. - specified type %1 is not validly substitutable with element type %2 + Specified type %1 is not validly substitutable with element type %2. - complex type %1 is not allowed to be abstract - kompleksna vrsta %1 ne sme biti abstraktna + Complex type %1 is not allowed to be abstract. + Kompleksna vrsta %1 ne sme biti abstraktna. - element %1 contains not allowed attributes - element %1 vsebuje nedovoljene lastnosti + Element %1 contains not allowed attributes. + Element %1 vsebuje nedovoljene lastnosti. - element %1 contains not allowed child element - element %1 vsebuje nedovoljen podelement + Element %1 contains not allowed child element. + Element %1 vsebuje nedovoljen podelement. - content of element %1 does not match its type definition: %2 - vsebina elementa %1 ne ustreza zanj določeni vrsti: %2 + Content of element %1 does not match its type definition: %2. + Vsebina elementa %1 ne ustreza zanj določeni vrsti: %2. - content of element %1 does not match defined value constraint + Content of element %1 does not match defined value constraint. - element %1 contains not allowed child content - element %1 vsebuje nedovoljeno vsebino v podelementih + Element %1 contains not allowed child content. + Element %1 vsebuje nedovoljeno vsebino v podelementih. - element %1 contains not allowed text content - element %1 vsebuje nedovoljeno besedilno vsebino + Element %1 contains not allowed text content. + Element %1 vsebuje nedovoljeno besedilno vsebino. - element %1 can not contain other elements, as it has a fixed content - element %1 ne more vsebovati drugih elementov, ker ima fiksno vsebino + Element %1 can not contain other elements, as it has a fixed content. + Element %1 ne more vsebovati drugih elementov, ker ima fiksno vsebino. - element %1 is missing required attribute %2 - elementu %1 manjka obvezna lastnost %2 + Element %1 is missing required attribute %2. + Elementu %1 manjka obvezna lastnost %2. - attribute %1 does not match the attribute wildcard + Attribute %1 does not match the attribute wildcard. - declaration for attribute %1 does not exist - deklaracija lastnosti %1 ne obstaja + Declaration for attribute %1 does not exist. + Deklaracija lastnosti %1 ne obstaja. - element %1 contains two attributes of type %2 - element %1 vsebuje dve lastnosti vrste %2 + Element %1 contains two attributes of type %2. + Element %1 vsebuje dve lastnosti vrste %2. - attribute %1 contains invalid content - lastnost %1 vsebuje neveljavno vsebino + Attribute %1 contains invalid content. + Lastnost %1 vsebuje neveljavno vsebino. - element %1 contains unknown attribute %2 - element %1 vsebuje neznano lastnost %2 + Element %1 contains unknown attribute %2. + Element %1 vsebuje neznano lastnost %2. - content of attribute %1 does not match its type definition: %2 + Content of attribute %1 does not match its type definition: %2. - content of attribute %1 does not match defined value constraint + Content of attribute %1 does not match defined value constraint. - non-unique value found for constraint %1 + Non-unique value found for constraint %1. - key constraint %1 contains absent fields + Key constraint %1 contains absent fields. - key constraint %1 contains references nillable element %2 + Key constraint %1 contains references nillable element %2. - no referenced value found for key reference %1 + No referenced value found for key reference %1. - more than one value found for field %1 - za polje %1 je bila najdena več kot ena vrednost + More than one value found for field %1. + Za polje %1 je bila najdena več kot ena vrednost. - field %1 has no simple type - polje %1 nima preproste vrste + Field %1 has no simple type. + Polje %1 nima preproste vrste. - ID value '%1' is not unique - Vrednost ID »%1« ni edinstvena + ID value '%1' is not unique. + Vrednost ID »%1« ni edinstvena. + '%1' attribute contains invalid QName content: %2. + Lastnost »%1« vsebuje neveljavno vsebino QName: %2. + + + + attribute group %1 contains attribute %2 twice + skupina lastnosti %1 dvakrat vsebuje lastnost %2 + + + + complex type %1 contains attribute %2 twice + kompleksna vrsta %1 dvakrat vsebuje lastnost %2 + + + + element %1 exists twice with different types + element %1 obstaja dvakrat, z različnima vrstama + + + + can not process unknown element %1, expected elements are: %2 + ni moč obdelati neznanega elementa %1, pričakovani elementi so: %2 + + + + element %1 is not allowed in this scope, possible elements are: %2 + element %1 v tem obsegu ni dovoljen, možni elementi so: %2 + + + + child element is missing in that scope, possible child elements are: %1 + v tem obsegu manjka podelement, možni podelementi so: %1 + + + + document is not a XML schema + dokument ni shema XML + + + + %1 attribute of %2 element contains invalid content: {%3} is not a value of type %4 + lastnost %1 elementa %2 vsebuje neveljavno vsebino: {%3} ni vrednost vrste %4 + + + + %1 attribute of %2 element contains invalid content: {%3} + lastnost %1 elementa %2 vsebuje neveljavno vsebino: {%3} + + + + %1 element is not allowed inside %2 element if %3 attribute is present + element %1 znotraj elementa %2 ni dovoljen, če je prisotna lastnost %3 + + + + %1 element has neither %2 attribute nor %3 child element + element %1 nima niti lastnosti %2 niti podelementa %3 + + + + %1 element with %2 child element must not have a %3 attribute + element %1 s podelementom %2 ne sme imeti lastnosti %3 + + + + %1 attribute of %2 element must be %3 or %4 + lastnost %1 elementa %2 mora biti %3 ali %4 + + + + %1 attribute of %2 element must have a value of %3 + lastnost %1 elementa %2 mora imeti vrednost %3 + + + + %1 attribute of %2 element must have a value of %3 or %4 + lastnost %1 elementa %2 mora imeti vrednost %3 ali %4 + + + + %1 element must not have %2 and %3 attribute together + element %1 hkrati ne sme imeti lastnosti %2 in %3 + + + + content of %1 attribute of %2 element must not be from namespace %3 + vsebina lastnosti %1 elementa %2 ne sme biti iz imenskega prostora %3 + + + + %1 attribute of %2 element must not be %3 + lastnost %1 elementa %2 ne sme biti %3 + + + + %1 element must have either %2 or %3 attribute + element %1 mora imeti lastnost %2 ali %3 + + + + %1 element requires either %2 or %3 attribute + element %1 potrebuje vsaj lastnost %2 ali %3 + + + + %1 element is not allowed in this context + element %1 v tem kontekstu ni dovoljen + + + + component with id %1 has been defined previously + komponenta z ID-jem %1 je že bila definirana + + + + element %1 already defined + element %1 je že definiran + + + + attribute %1 already defined + lastnost %1 je že definirana + + + + type %1 already defined + vrsta %1 je že definirana + + + + attribute group %1 already defined + skupina lastnosti %1 je že definirana + + + + element group %1 already defined + skupina elementov %1 je že definirana + + + + notation %1 already defined + zapis %1 je že definiran + + + + type of %1 element must be a simple type, %2 is not + vrsta elementa %1 mora biti preprosta, %2 to ni + + + + duplicated element names %1 in %2 element + podvojeni imeni elementov %1 v elementu %2 + + + + %1 is not valid according to %2 + %1 glede na %2 ni veljaven + + + + invalid QName content: %1 + neveljavna vsebina QName: %1 + + + + data of type %1 are not allowed to be empty + podatki vrste %1 ne smejo biti prazni + + + + element %1 is missing child element + elementu %1 manjka podelement + + + + %1 contains invalid data + %1 vsebuje neveljavne podatke + + + + no definition for element %1 available + definicija za element %1 ni na voljo + + + + element %1 is not defined in this scope + element %1 v tem obsegu ni definiran + + + + declaration for element %1 does not exist + deklaracija elementa %1 ne obstaja + + + + element %1 contains invalid content + element %1 vsebuje neveljavno vsebino + + + + element %1 is declared as abstract + element %1 je deklariran kot abstrakten + + + + complex type %1 is not allowed to be abstract + kompleksna vrsta %1 ne sme biti abstraktna + + + + element %1 contains not allowed attributes + element %1 vsebuje nedovoljene lastnosti + + + + element %1 contains not allowed child element + element %1 vsebuje nedovoljen podelement + + + + content of element %1 does not match its type definition: %2 + vsebina elementa %1 ne ustreza zanj določeni vrsti: %2 + + + + element %1 contains not allowed child content + element %1 vsebuje nedovoljeno vsebino v podelementih + + + + element %1 contains not allowed text content + element %1 vsebuje nedovoljeno besedilno vsebino + + + + element %1 can not contain other elements, as it has a fixed content + element %1 ne more vsebovati drugih elementov, ker ima fiksno vsebino + + + + element %1 is missing required attribute %2 + elementu %1 manjka obvezna lastnost %2 + + + + declaration for attribute %1 does not exist + deklaracija lastnosti %1 ne obstaja + + + + element %1 contains two attributes of type %2 + element %1 vsebuje dve lastnosti vrste %2 + + + + attribute %1 contains invalid content + lastnost %1 vsebuje neveljavno vsebino + + + + element %1 contains unknown attribute %2 + element %1 vsebuje neznano lastnost %2 + + + + more than one value found for field %1 + za polje %1 je bila najdena več kot ena vrednost + + + + field %1 has no simple type + polje %1 nima preproste vrste + + + + ID value '%1' is not unique + Vrednost ID »%1« ni edinstvena + + + '%1' attribute contains invalid QName content: %2 - Lastnost »%1« vsebuje neveljavno vsebino QName: %2 + Lastnost »%1« vsebuje neveljavno vsebino QName: %2 -- cgit v0.12 From f72c2d50b6ab7fc4a8ea3524e22de63ca8a366f7 Mon Sep 17 00:00:00 2001 From: Dmytro Poplavskiy Date: Tue, 3 Nov 2009 12:47:48 +1000 Subject: Fixed qrand global static related problem. qrand() uses global static seed storage, but if used from destructors of other global static objects (directly or via ~QSettings() or QMap::insert()) the global static seed storage can be already deleted. Fallback to plain rand() in this case. Task-number: QTBUG-5218 Reviewed-by: Justin McPherson --- src/corelib/global/qglobal.cpp | 59 ++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 7d47944..36e15b9 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2513,10 +2513,19 @@ Q_GLOBAL_STATIC(SeedStorage, randTLS) // Thread Local Storage for seed value void qsrand(uint seed) { #if defined(Q_OS_UNIX) && !defined(QT_NO_THREAD) && !defined(Q_OS_SYMBIAN) - SeedStorageType *pseed = randTLS()->localData(); - if (!pseed) - randTLS()->setLocalData(pseed = new SeedStorageType); - *pseed = seed; + SeedStorage *seedStorage = randTLS(); + if (seedStorage) { + SeedStorageType *pseed = seedStorage->localData(); + if (!pseed) + seedStorage->setLocalData(pseed = new SeedStorageType); + *pseed = seed; + } else { + //golbal static seed storage should always exist, + //except after being deleted by QGlobalStaticDeleter. + //But since it still can be called from destructor of another + //global static object, fallback to sqrand(seed) + srand(seed); + } #else // On Windows srand() and rand() already use Thread-Local-Storage // to store the seed between calls @@ -2536,17 +2545,20 @@ void qsrand(uint seed) void qsrand() { #if (defined(Q_OS_UNIX) || defined(Q_OS_WIN)) && !defined(QT_NO_THREAD) && !defined(Q_OS_SYMBIAN) - SeedStorageType *pseed = randTLS()->localData(); - if (pseed) { - // already seeded - return; + SeedStorage *seedStorage = randTLS(); + if (seedStorage) { + SeedStorageType *pseed = seedStorage->localData(); + if (pseed) { + // already seeded + return; + } + seedStorage->setLocalData(pseed = new SeedStorageType); + // start beyond 1 to avoid the sequence reset + static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(2); + *pseed = QDateTime::currentDateTime().toTime_t() + + quintptr(&pseed) + + serial.fetchAndAddRelaxed(1); } - randTLS()->setLocalData(pseed = new SeedStorageType); - // start beyond 1 to avoid the sequence reset - static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(2); - *pseed = QDateTime::currentDateTime().toTime_t() - + quintptr(&pseed) - + serial.fetchAndAddRelaxed(1); #if defined(Q_OS_WIN) // for Windows the srand function must still be called. srand(*pseed); @@ -2584,12 +2596,21 @@ void qsrand() int qrand() { #if defined(Q_OS_UNIX) && !defined(QT_NO_THREAD) && !defined(Q_OS_SYMBIAN) - SeedStorageType *pseed = randTLS()->localData(); - if (!pseed) { - randTLS()->setLocalData(pseed = new SeedStorageType); - *pseed = 1; + SeedStorage *seedStorage = randTLS(); + if (seedStorage) { + SeedStorageType *pseed = seedStorage->localData(); + if (!pseed) { + seedStorage->setLocalData(pseed = new SeedStorageType); + *pseed = 1; + } + return rand_r(pseed); + } else { + //golbal static seed storage should always exist, + //except after being deleted by QGlobalStaticDeleter. + //But since it still can be called from destructor of another + //global static object, fallback to qrand() + return rand(); } - return rand_r(pseed); #else // On Windows srand() and rand() already use Thread-Local-Storage // to store the seed between calls -- cgit v0.12 From 88f668430023acd3fbad3543a57198a4cf0255c2 Mon Sep 17 00:00:00 2001 From: Dmytro Poplavskiy Date: Tue, 3 Nov 2009 17:22:01 +1000 Subject: Fixed compilation on windows. Reviewed-by: trustme --- src/corelib/global/qglobal.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 36e15b9..33c6a34 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2558,11 +2558,11 @@ void qsrand() *pseed = QDateTime::currentDateTime().toTime_t() + quintptr(&pseed) + serial.fetchAndAddRelaxed(1); - } #if defined(Q_OS_WIN) - // for Windows the srand function must still be called. - srand(*pseed); + // for Windows the srand function must still be called. + srand(*pseed); #endif + } #elif defined(Q_OS_WIN) static unsigned int seed = 0; -- cgit v0.12 From 5dddf56e703bca59b874e46d3cabd2eba6fbb55e Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 13 Aug 2009 15:08:24 +0200 Subject: qdoc: Disabled reporting the NOTIFY signal until I know what it broke. Task-number: 259071 --- tools/qdoc3/cppcodeparser.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp index 84ec3f4..843bec8 100644 --- a/tools/qdoc3/cppcodeparser.cpp +++ b/tools/qdoc3/cppcodeparser.cpp @@ -1759,7 +1759,6 @@ bool CppCodeParser::matchProperty(InnerNode *parent) property->setDesignable(value.toLower() == "true"); else if (key == "RESET") tre->addPropertyFunction(property, value, PropertyNode::Resetter); - else if (key == "NOTIFY") { tre->addPropertyFunction(property, value, PropertyNode::Notifier); } -- cgit v0.12 From d54a1241a4470c73ccdac4b1a90264a9eaa28478 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 26 Oct 2009 12:22:13 +0100 Subject: disable link time code generation by default on Windows CE To be consistent with desktop Windows Qt, we also disable LTCG by default. To turn it on, use the -ltcg configure switch. Reviewed-by: mauricek --- tools/configure/configureapp.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index dd3823b..28645a0 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -1412,7 +1412,6 @@ void Configure::applySpecSpecifics() dictionary[ "WEBKIT" ] = "no"; dictionary[ "PHONON" ] = "yes"; dictionary[ "DIRECTSHOW" ] = "no"; - dictionary[ "LTCG" ] = "yes"; // We only apply MMX/IWMMXT for mkspecs we know they work if (dictionary[ "XQMAKESPEC" ].startsWith("wincewm")) { dictionary[ "MMX" ] = "yes"; -- cgit v0.12 From 0aade44ed9a2f223c603984a84ab012eadc5c388 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 26 Oct 2009 14:05:16 +0100 Subject: document the -no-ltcg default for Windows CE in changes-4.6.0 --- dist/changes-4.6.0 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dist/changes-4.6.0 b/dist/changes-4.6.0 index ba2b051..5a15cdb 100644 --- a/dist/changes-4.6.0 +++ b/dist/changes-4.6.0 @@ -58,6 +58,9 @@ information about a particular change. - The reading code of QLocalSocket on Windows has been rewritten to improve reading performance. + - On Windows CE the link time code geration has been disabled by default to + be consistent with win32-msvc200x. + **************************************************************************** * Important Behavior Changes * **************************************************************************** -- cgit v0.12 From fa1856bcb2eff41dadf0900202dd43f44ddb2343 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 27 Oct 2009 16:19:19 +0100 Subject: WebKit compile fix for Windows CE Not sure if this is right fix. We could also disable PLUGIN_PACKAGE_SIMPLE_HASH. But this is automatically enabled when NETSCAPE_PLUGIN_API is disabled. Reviewed-by: thartman --- src/3rdparty/webkit/WebCore/platform/FileSystem.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/3rdparty/webkit/WebCore/platform/FileSystem.h b/src/3rdparty/webkit/WebCore/platform/FileSystem.h index 958eb73..d144990 100644 --- a/src/3rdparty/webkit/WebCore/platform/FileSystem.h +++ b/src/3rdparty/webkit/WebCore/platform/FileSystem.h @@ -90,6 +90,17 @@ struct PlatformModuleVersion { { } + bool operator != (const PlatformModuleVersion& rhs) const + { + return mostSig != rhs.mostSig && leastSig != rhs.leastSig; + } + + + bool operator > (const PlatformModuleVersion& rhs) const + { + return mostSig > rhs.mostSig && leastSig > rhs.leastSig; + } + }; #else typedef QLibrary* PlatformModule; -- cgit v0.12 From 9fab0ede200960f0dbec1457757a6ba3214c3ce6 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 28 Oct 2009 10:03:12 +0100 Subject: fix font height calculation on QWS fontDef.pixelSize is a qreal now and we should round it after multiplication to avoid an accuracy loss. Reviewed-by: mae --- src/gui/text/qfontengine_qpf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qfontengine_qpf.cpp b/src/gui/text/qfontengine_qpf.cpp index 6ff0fbd..94974fc 100644 --- a/src/gui/text/qfontengine_qpf.cpp +++ b/src/gui/text/qfontengine_qpf.cpp @@ -819,7 +819,7 @@ FT_Face QFontEngineQPF::lockFace() const FT_Face face = freetype->face; // ### not perfect - const int ysize = int(fontDef.pixelSize) << 6; + const int ysize = qRound(fontDef.pixelSize * qreal(64)); const int xsize = ysize; if (freetype->xsize != xsize || freetype->ysize != ysize) { -- cgit v0.12