summaryrefslogtreecommitdiffstats
path: root/Python/bltinmodule.c
diff options
context:
space:
mode:
authorBarry Warsaw <barry@python.org>2003-03-12 03:43:09 (GMT)
committerBarry Warsaw <barry@python.org>2003-03-12 03:43:09 (GMT)
commit45c3941510e8ad29ed2ffa2cf8fa3c1c8f7c22e5 (patch)
treeb2383a6d141f7a6fbdec2bf9e1285be1ed6a30d9 /Python/bltinmodule.c
parentea8f6fa094449a977ae416ab7694e548062bf769 (diff)
downloadcpython-45c3941510e8ad29ed2ffa2cf8fa3c1c8f7c22e5.zip
cpython-45c3941510e8ad29ed2ffa2cf8fa3c1c8f7c22e5.tar.gz
cpython-45c3941510e8ad29ed2ffa2cf8fa3c1c8f7c22e5.tar.bz2
Update the package version number
Diffstat (limited to 'Python/bltinmodule.c')
0 files changed, 0 insertions, 0 deletions
ld_wclass == kFloatingWindowClass || old_wclass == kUtilityWindowClass){ - // Only change the class to kMovableModalWindowClass if the no explicit jewels - // are set (kMovableModalWindowClass can't contain them), and the current window class - // can be converted to modal (according to carbon doc). Mind the order of - // HIWindowChangeClass and ChangeWindowAttributes. - WindowGroupRef group = GetWindowGroup(windowRef); - HIWindowChangeClass(windowRef, kMovableModalWindowClass); - quint32 tmpWattr = kWindowCloseBoxAttribute | kWindowHorizontalZoomAttribute; - ChangeWindowAttributes(windowRef, tmpWattr, kWindowNoAttributes); - ChangeWindowAttributes(windowRef, kWindowNoAttributes, tmpWattr); - // If the window belongs to a qt-created group, set that group once more: - if (data.window_flags & Qt::WindowStaysOnTopHint - || q->windowType() == Qt::Popup - || q->windowType() == Qt::ToolTip) - SetWindowGroup(windowRef, group); + } else { + // Window should be application-modal (which implies NOT using a sheet). + if (old_wclass == kSheetWindowClass){ + // We cannot convert a sheet to a window. + // So we recreate the window: + recreateMacWindow(); + return; + } else if (!(q->data->window_flags & Qt::CustomizeWindowHint)) { + if (old_wclass == kDocumentWindowClass || old_wclass == kFloatingWindowClass || old_wclass == kUtilityWindowClass){ + // Only change the class to kMovableModalWindowClass if the no explicit jewels + // are set (kMovableModalWindowClass can't contain them), and the current window class + // can be converted to modal (according to carbon doc). Mind the order of + // HIWindowChangeClass and ChangeWindowAttributes. + WindowGroupRef group = GetWindowGroup(windowRef); + HIWindowChangeClass(windowRef, kMovableModalWindowClass); + quint32 tmpWattr = kWindowCloseBoxAttribute | kWindowHorizontalZoomAttribute; + ChangeWindowAttributes(windowRef, tmpWattr, kWindowNoAttributes); + ChangeWindowAttributes(windowRef, kWindowNoAttributes, tmpWattr); + // If the window belongs to a qt-created group, set that group once more: + if (data.window_flags & Qt::WindowStaysOnTopHint + || q->windowType() == Qt::Popup + || q->windowType() == Qt::ToolTip) + SetWindowGroup(windowRef, group); + } + // Popups are usually handled "special" and are never modal. + Qt::WindowType winType = q->windowType(); + if (winType != Qt::Popup && winType != Qt::ToolTip) + SetWindowModality(windowRef, kWindowModalityAppModal, 0); } - // Popups are usually handled "special" and are never modal. - Qt::WindowType winType = q->windowType(); - if (winType != Qt::Popup && winType != Qt::ToolTip) - SetWindowModality(windowRef, kWindowModalityAppModal, 0); } } else if (windowRef) { if (old_wclass == kSheetWindowClass){ -- cgit v0.12 From e4c3734d31dd4f76c96b0b8f7607347aeea328c3 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 24 Jul 2009 15:07:51 +0200 Subject: Musicplayer example crashes when trying to open unvalid file Reason: Example tries to get media from QList with an index out of bounds. Nothing to do with Phonon. Task-number: 253307 --- examples/phonon/musicplayer/mainwindow.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/phonon/musicplayer/mainwindow.cpp b/examples/phonon/musicplayer/mainwindow.cpp index a9bb379..ccea606 100644 --- a/examples/phonon/musicplayer/mainwindow.cpp +++ b/examples/phonon/musicplayer/mainwindow.cpp @@ -157,9 +157,12 @@ void MainWindow::tableClicked(int row, int /* column */) mediaObject->stop(); mediaObject->clearQueue(); + if (row >= sources.size()) + return; + mediaObject->setCurrentSource(sources[row]); - if (wasPlaying) + if (wasPlaying) mediaObject->play(); else mediaObject->stop(); -- cgit v0.12 From 295f0fd9b98a7e4846c7a8c8c92116fb05f7cbd7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 25 Jul 2009 12:05:28 +0200 Subject: Fix a running external tests: user program headers must come first. No wonder QT_SHAREDPOINTER_TRACK_POINTERS was having no effect: there was an #include before it. (cherry picked from commit 4c12010fac555bce0a6c8d69a267a56f4c15087f) --- tests/auto/qsharedpointer/externaltests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qsharedpointer/externaltests.cpp b/tests/auto/qsharedpointer/externaltests.cpp index 75ac5f1..d1618d1 100644 --- a/tests/auto/qsharedpointer/externaltests.cpp +++ b/tests/auto/qsharedpointer/externaltests.cpp @@ -323,6 +323,8 @@ namespace QTest { sourceCode.clear(); sourceCode.reserve(8192); + sourceCode += programHeader; + // Add Qt header includes if (qtModules & QExternalTest::QtCore) sourceCode += "#include \n"; @@ -356,8 +358,6 @@ namespace QTest { "#include \n" "#include \n"; - sourceCode += programHeader; - sourceCode += "\n" "void q_external_test_user_code()\n" -- cgit v0.12 From ba5b630fd58127a4bcfe2baf92603a7bc8899824 Mon Sep 17 00:00:00 2001 From: Kavindra Palaraja Date: Sun, 26 Jul 2009 20:18:02 +0200 Subject: Doc - Mention Google trademarks with the two examples using Google services. Reviewed-by: Simon Hausmann --- doc/src/examples/googlechat.qdoc | 1 + doc/src/examples/googlesuggest.qdoc | 1 + 2 files changed, 2 insertions(+) diff --git a/doc/src/examples/googlechat.qdoc b/doc/src/examples/googlechat.qdoc index 42a0198..7c9d7db 100644 --- a/doc/src/examples/googlechat.qdoc +++ b/doc/src/examples/googlechat.qdoc @@ -48,4 +48,5 @@ \image googlechat-example.png + \note The Google Talk instant messaging service is a registered trademark of Google Inc. */ diff --git a/doc/src/examples/googlesuggest.qdoc b/doc/src/examples/googlesuggest.qdoc index 1752420..e3d2b1f 100644 --- a/doc/src/examples/googlesuggest.qdoc +++ b/doc/src/examples/googlesuggest.qdoc @@ -48,4 +48,5 @@ \image googlesuggest-example.png + \note The Google Suggest suggestion service is a registered trademark of Google Inc. */ -- cgit v0.12 From 5a7d29039917d9f0faf373045e8dbb274837c11d Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Mon, 27 Jul 2009 14:50:10 +1000 Subject: Fixed failure of tst_qlocale if run when LC_ALL is set. This test tried to be unaffected by the locale environment variables set by the user by explicitly overwriting them and spawning a new process. However this was only done for LANG and not the other variables which can affect the locale. Do it for all the locale variables. Also, the previous approach (store the current value with qgetenv, then put it back with qputenv later) doesn't really work because that effectively takes variables which weren't set and sets them to an empty string, which is not the same thing. Use QProcess::setEnvironment instead. Reviewed-by: Andy Shaw --- tests/auto/qlocale/tst_qlocale.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/auto/qlocale/tst_qlocale.cpp b/tests/auto/qlocale/tst_qlocale.cpp index 8ac6ef0..82bd864 100644 --- a/tests/auto/qlocale/tst_qlocale.cpp +++ b/tests/auto/qlocale/tst_qlocale.cpp @@ -327,9 +327,8 @@ void tst_QLocale::emptyCtor() { \ /* Test constructor without arguments. Needs separate process */ \ /* because of caching of the system locale. */ \ - QString oldEnv = QString::fromLocal8Bit(qgetenv("LANG")); \ - qputenv("LANG", QString(req_lc).toLocal8Bit()); \ QProcess process; \ + process.setEnvironment(QStringList(env) << QString("LANG=%1").arg(req_lc)); \ process.start("syslocaleapp/syslocaleapp"); \ process.waitForReadyRead(); \ QString ret = QString(process.readAll()); \ @@ -337,18 +336,23 @@ void tst_QLocale::emptyCtor() QVERIFY2(!ret.isEmpty(), "Cannot launch external process"); \ QVERIFY2(QString(exp_str) == ret, QString("Expected: " + QString(exp_str) + ", got: " \ + ret + ". Requested: " + QString(req_lc)).toLatin1().constData()); \ - qputenv("LANG", oldEnv.toLocal8Bit()); \ + } + + // Get an environment free of any locale-related variables + QStringList env; + foreach (QString const& entry, QProcess::systemEnvironment()) { + if (entry.startsWith("LANG=") || entry.startsWith("LC_")) + continue; + env << entry; } // Get default locale. - QString old = QString::fromLocal8Bit(qgetenv("LANG")); - qputenv("LANG", ""); QProcess p; + p.setEnvironment(env); p.start("syslocaleapp/syslocaleapp"); p.waitForReadyRead(); QString defaultLoc = QString(p.readAll()); p.waitForFinished(); - qputenv("LANG", old.toLocal8Bit()); TEST_CTOR("C", "C") TEST_CTOR("bla", "C") -- cgit v0.12 From ebaae9e6a8694d6be4ec5c353a98d532e133245a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20S=C3=B8rvig?= Date: Mon, 27 Jul 2009 12:27:09 +0200 Subject: Fix crash when printing to PDF on Qt/Mac Priting to PDF would crash for applications built on Leopard when running on Tiger. Add the standard runtime version check to QFontEngineMac::faceId(). Task-number: 251791 Reviewed-by: Richard Moe Gustavsen --- src/gui/text/qfontengine_mac.mm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 327df45..72e5175 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -1560,6 +1560,7 @@ QFontEngine::FaceId QFontEngineMac::faceId() const { FaceId ret; #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) +if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { // CTFontGetPlatformFont FSRef ref; if (ATSFontGetFileReference(FMGetATSFontRefFromFont(fontID), &ref) != noErr) @@ -1567,7 +1568,9 @@ QFontEngine::FaceId QFontEngineMac::faceId() const ret.filename = QByteArray(128, 0); ret.index = fontID; FSRefMakePath(&ref, (UInt8 *)ret.filename.data(), ret.filename.size()); -#else +}else +#endif +{ FSSpec spec; if (ATSFontGetFileSpecification(FMGetATSFontRefFromFont(fontID), &spec) != noErr) return ret; @@ -1577,7 +1580,7 @@ QFontEngine::FaceId QFontEngineMac::faceId() const ret.filename = QByteArray(128, 0); ret.index = fontID; FSRefMakePath(&ref, (UInt8 *)ret.filename.data(), ret.filename.size()); -#endif +} return ret; } -- cgit v0.12 From 14c96b7079a0fb32d1c32d00f95a87e0e3ada8b6 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Mon, 27 Jul 2009 13:45:20 +0200 Subject: Add docs for Windows Server 2008 R2 to QSysInfo::WinVersion Windows Server 2008 R2 is based on kernel 6.1, the same as Windows 7. Reviewed-by: TrustMe --- src/corelib/global/qglobal.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 48116b8..d15c102 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1079,7 +1079,7 @@ bool qSharedBuild() \value WV_XP Windows XP (operating system version 5.1) \value WV_2003 Windows Server 2003, Windows Server 2003 R2, Windows Home Server, Windows XP Professional x64 Edition (operating system version 5.2) \value WV_VISTA Windows Vista, Windows Server 2008 (operating system version 6.0) - \value WV_WINDOWS7 Windows 7 (operating system version 6.1) + \value WV_WINDOWS7 Windows 7, Windows Server 2008 R2 (operating system version 6.1) Alternatively, you may use the following macros which correspond directly to the Windows operating system version number: @@ -1088,7 +1088,7 @@ bool qSharedBuild() \value WV_5_1 Operating system version 5.1, corresponds to Windows XP \value WV_5_2 Operating system version 5.2, corresponds to Windows Server 2003, Windows Server 2003 R2, Windows Home Server, and Windows XP Professional x64 Edition \value WV_6_0 Operating system version 6.0, corresponds to Windows Vista and Windows Server 2008 - \value WV_6_1 Operating system version 6.1, corresponds to Windows 7 + \value WV_6_1 Operating system version 6.1, corresponds to Windows 7 and Windows Server 2008 R2 CE-based versions: -- cgit v0.12 From fab51e1d9ce57be4d786ad7c9df8bc695252a0de Mon Sep 17 00:00:00 2001 From: kh Date: Mon, 27 Jul 2009 15:08:00 +0200 Subject: Fix missing title quoting. Reviewed-by: kh --- tools/assistant/tools/assistant/centralwidget.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/assistant/tools/assistant/centralwidget.cpp b/tools/assistant/tools/assistant/centralwidget.cpp index a384544..00a8893 100644 --- a/tools/assistant/tools/assistant/centralwidget.cpp +++ b/tools/assistant/tools/assistant/centralwidget.cpp @@ -739,8 +739,10 @@ void CentralWidget::setTabTitle(const QUrl &url) QTabBar *tabBar = qFindChild(tabWidget); for (int tab = 0; tab < tabBar->count(); ++tab) { HelpViewer *viewer = qobject_cast(tabWidget->widget(tab)); - if (viewer) - tabWidget->setTabText(tab, viewer->documentTitle().trimmed()); + if (viewer) { + tabWidget->setTabText(tab, + quoteTabTitle(viewer->documentTitle().trimmed())); + } } #else HelpViewer *viewer = currentHelpViewer(); -- cgit v0.12 From ef105812bd65d7536f2d403dd3b65a0b77ea843c Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Mon, 27 Jul 2009 16:00:47 +0200 Subject: Roll back the fancy updating of translucent windows. The problem with the fix, though it produces less flicker when resizing, is that it delays telling windows that the window has moved until after the window has been completely repainted. Problem with this is that functions that rely on windows to be up to date will fail until the backbuffer is flushed. This was the case for mapTo/FromGlobal, and potentially other functions too. Reviewed-By: Eskil --- src/gui/kernel/qwidget_win.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp index 3ab1ccb..f7ff2d0 100644 --- a/src/gui/kernel/qwidget_win.cpp +++ b/src/gui/kernel/qwidget_win.cpp @@ -1468,10 +1468,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) qt_wince_maximize(q); } else { #endif - if (!isTranslucentWindow) - MoveWindow(q->internalWinId(), fs.x(), fs.y(), fs.width(), fs.height(), true); - else if (isMove && !isResize) - SetWindowPos(q->internalWinId(), 0, fs.x(), fs.y(), 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER); + MoveWindow(q->internalWinId(), fs.x(), fs.y(), fs.width(), fs.height(), true); } if (!q->isVisible()) InvalidateRect(q->internalWinId(), 0, FALSE); -- cgit v0.12 From 96fbc28c9b4e8e97eec43b99fc18ad29c269bd25 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 27 Jul 2009 21:16:34 +0200 Subject: Disable the pointer tracking feature in Qt 4.5. The functionality is broken, since pointers can be released by a QSharedPointer tracking a pointer of different type, which would leave behind pointers in the hash. The fix requires Qt 4.6 because of a new symbol being added. --- src/corelib/tools/qsharedpointer.cpp | 28 +++++----------------------- src/corelib/tools/qsharedpointer_impl.h | 6 ------ 2 files changed, 5 insertions(+), 29 deletions(-) diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index ba62ce1..c9dccd3 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -833,42 +833,24 @@ namespace { }; } -Q_GLOBAL_STATIC(KnownPointers, knownPointers) +//Q_GLOBAL_STATIC(KnownPointers, knownPointers) QT_BEGIN_NAMESPACE /*! \internal */ -void QtSharedPointer::internalSafetyCheckAdd(const volatile void *ptr) +void QtSharedPointer::internalSafetyCheckAdd(const volatile void *) { - KnownPointers *const kp = knownPointers(); - if (!kp) - return; // end-game: the application is being destroyed already - - QMutexLocker lock(&kp->mutex); - void *actual = const_cast(ptr); - if (kp->values.contains(actual)) { - printBacktrace(knownPointers()->values.value(actual)); - qFatal("QSharedPointerData: internal self-check failed: pointer %p was already tracked " - "by another QSharedPointerData object", actual); - } - - kp->values.insert(actual, saveBacktrace()); + // functionality is broken + // fix requires Qt 4.6 } /*! \internal */ -void QtSharedPointer::internalSafetyCheckRemove(const volatile void *ptr) +void QtSharedPointer::internalSafetyCheckRemove(const volatile void *) { - KnownPointers *const kp = knownPointers(); - if (!kp) - return; // end-game: the application is being destroyed already - - QMutexLocker lock(&kp->mutex); - void *actual = const_cast(ptr); - kp->values.remove(actual); } QT_END_NAMESPACE diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 0471a1b..7aaed22 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -140,16 +140,10 @@ namespace QtSharedPointer { inline void internalConstruct(T *ptr) { -#ifdef QT_SHAREDPOINTER_TRACK_POINTERS - if (ptr) internalSafetyCheckAdd(ptr); -#endif value = ptr; } inline void internalDestroy() { -#ifdef QT_SHAREDPOINTER_TRACK_POINTERS - if (value) internalSafetyCheckRemove(value); -#endif } #if defined(Q_NO_TEMPLATE_FRIENDS) -- cgit v0.12 From 54cff1f39d04730ecbb6f2500711c27f3e99465c Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 27 Jul 2009 15:36:26 -0700 Subject: Make porterduff operations work in DirectFB This patch makes us not fall back to the raster engine for most of the composition mode operations when doing blits. Primitives are still handled by Qt when composition != SourceOver Reviewed-by: Noam Rosenthal --- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 130 +++++++++++++++------ 1 file changed, 97 insertions(+), 33 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index b264ac0..67aa516 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -59,10 +59,17 @@ class QDirectFBPaintEnginePrivate : public QRasterPaintEnginePrivate { public: enum TransformationTypeFlags { - NegativeScale = 0x100, - RectsUnsupported = (QTransform::TxRotate|QTransform::TxShear|QTransform::TxProject), - BlitUnsupported = (NegativeScale|RectsUnsupported) + Matrix_NegativeScale = 0x100, + Matrix_RectsUnsupported = (QTransform::TxRotate|QTransform::TxShear|QTransform::TxProject), + Matrix_BlitsUnsupported = (Matrix_NegativeScale|Matrix_RectsUnsupported) }; + + enum CompositionModeStatus { + PorterDuff_None = 0x0, + PorterDuff_SupportedBlits = 0x1, + PorterDuff_SupportedPrimitives = 0x2 + }; + QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p); ~QDirectFBPaintEnginePrivate(); @@ -100,7 +107,7 @@ private: bool antialiased; bool simplePen; - uint transformationType; // this is QTransform::type() + NegativeScale if qMin(transform.m11(), transform.m22()) < 0 + uint transformationType; // this is QTransform::type() + Matrix_NegativeScale if qMin(transform.m11(), transform.m22()) < 0 SurfaceCache *surfaceCache; @@ -112,7 +119,7 @@ private: bool dfbHandledClip; bool ignoreSystemClip; QDirectFBPaintDevice *dfbDevice; - bool unsupportedCompositionMode; + uint compositionModeStatus; QDirectFBPaintEngine *q; QRect currentClip; @@ -161,8 +168,12 @@ enum PaintOperation { #ifdef QT_DIRECTFB_WARN_ON_RASTERFALLBACKS template -static void rasterFallbackWarn(const char *msg, const char *, const device *, uint, bool, bool, bool, - const char *, const T1 &, const char *, const T2 &, const char *, const T3 &); +static void rasterFallbackWarn(const char *msg, const char *func, const device *dev, + uint transformationType, bool simplePen, + bool dfbHandledClip, uint compositionModeStatus, + const char *nameOne, const T1 &one, + const char *nameTwo, const T2 &two, + const char *nameThree, const T3 &three); #endif #if defined QT_DIRECTFB_WARN_ON_RASTERFALLBACKS && defined QT_DIRECTFB_DISABLE_RASTERFALLBACKS @@ -173,7 +184,7 @@ static void rasterFallbackWarn(const char *msg, const char *, const device *, ui d_func()->transformationType, \ d_func()->simplePen, \ d_func()->dfbCanHandleClip(), \ - d_func()->unsupportedCompositionMode, \ + d_func()->compositionModeStatus, \ #one, one, #two, two, #three, three); \ if (op & (QT_DIRECTFB_DISABLE_RASTERFALLBACKS)) \ return; @@ -189,7 +200,7 @@ static void rasterFallbackWarn(const char *msg, const char *, const device *, ui d_func()->transformationType, \ d_func()->simplePen, \ d_func()->dfbCanHandleClip(), \ - d_func()->unsupportedCompositionMode, \ + d_func()->compositionModeStatus, \ #one, one, #two, two, #three, three); #else #define RASTERFALLBACK(op, one, two, three) @@ -233,6 +244,7 @@ bool QDirectFBPaintEngine::begin(QPaintDevice *device) } d->prepare(d->dfbDevice); + d->setCompositionMode(state()->composition_mode); return QRasterPaintEngine::begin(device); } @@ -325,8 +337,8 @@ void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount) Q_D(QDirectFBPaintEngine); d->updateClip(); const QBrush &brush = state()->brush; - if (d->unsupportedCompositionMode - || (d->transformationType & QDirectFBPaintEnginePrivate::RectsUnsupported) + if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) + || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) || !d->simplePen || !d->dfbCanHandleClip() || !d->isSimpleBrush(brush)) { @@ -354,8 +366,8 @@ void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount) Q_D(QDirectFBPaintEngine); d->updateClip(); const QBrush &brush = state()->brush; - if (d->unsupportedCompositionMode - || (d->transformationType & QDirectFBPaintEnginePrivate::RectsUnsupported) + if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) + || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) || !d->simplePen || !d->dfbCanHandleClip() || !d->isSimpleBrush(brush)) { @@ -382,7 +394,9 @@ void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount) { Q_D(QDirectFBPaintEngine); d->updateClip(); - if (d->unsupportedCompositionMode || !d->simplePen || !d->dfbCanHandleClip()) { + if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) + || !d->simplePen + || !d->dfbCanHandleClip()) { RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG()); d->lock(); QRasterPaintEngine::drawLines(lines, lineCount); @@ -401,7 +415,9 @@ void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount) { Q_D(QDirectFBPaintEngine); d->updateClip(); - if (d->unsupportedCompositionMode || !d->simplePen || !d->dfbCanHandleClip()) { + if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) + || !d->simplePen + || !d->dfbCanHandleClip()) { RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG()); d->lock(); QRasterPaintEngine::drawLines(lines, lineCount); @@ -442,8 +458,8 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image, d->updateClip(); #if !defined QT_NO_DIRECTFB_PREALLOCATED || defined QT_DIRECTFB_IMAGECACHE - if (d->unsupportedCompositionMode - || (d->transformationType & QDirectFBPaintEnginePrivate::BlitUnsupported) + if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) + || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) || !d->dfbCanHandleClip(r) #ifndef QT_DIRECTFB_IMAGECACHE || QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN @@ -488,8 +504,8 @@ void QDirectFBPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap, RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr); d->lock(); QRasterPaintEngine::drawPixmap(r, pixmap, sr); - } else if (d->unsupportedCompositionMode - || (d->transformationType & QDirectFBPaintEnginePrivate::BlitUnsupported) + } else if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) + || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) || !d->dfbCanHandleClip(r)) { RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr); const QImage *img = static_cast(pixmap.pixmapData())->buffer(DSLF_READ); @@ -522,8 +538,8 @@ void QDirectFBPaintEngine::drawTiledPixmap(const QRectF &r, RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset); d->lock(); QRasterPaintEngine::drawTiledPixmap(r, pixmap, offset); - } else if (d->unsupportedCompositionMode - || (d->transformationType & QDirectFBPaintEnginePrivate::BlitUnsupported) + } else if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) + || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) || !d->dfbCanHandleClip(r)) { RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset); const QImage *img = static_cast(pixmap.pixmapData())->buffer(DSLF_READ); @@ -623,11 +639,13 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) if (brush.style() == Qt::NoBrush) return; d->updateClip(); - if (!d->unsupportedCompositionMode - && !(d->transformationType & (QDirectFBPaintEnginePrivate::RectsUnsupported)) - && d->dfbCanHandleClip(rect)) { + if (d->dfbCanHandleClip(rect)) { switch (brush.style()) { case Qt::SolidPattern: { + if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) + || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)) { + break; + } const QColor color = brush.color(); if (!color.isValid()) return; @@ -638,8 +656,10 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) r.width(), r.height()); return; } case Qt::TexturePattern: { - if (d->transformationType & QDirectFBPaintEnginePrivate::NegativeScale) + if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) + || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)) { break; + } const QPixmap texture = brush.texture(); if (texture.pixmapData()->classId() != QPixmapData::DirectFBClass) @@ -663,8 +683,8 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color) return; Q_D(QDirectFBPaintEngine); d->updateClip(); - if (d->unsupportedCompositionMode - || (d->transformationType & QDirectFBPaintEnginePrivate::RectsUnsupported) + if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) + || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) || !d->dfbCanHandleClip()) { RASTERFALLBACK(FILL_RECT, rect, color, VOID_ARG()); d->lock(); @@ -713,7 +733,7 @@ QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p : surface(0), antialiased(false), simplePen(false), transformationType(0), opacity(255), dirtyClip(true), dfbHandledClip(false), dfbDevice(0), - unsupportedCompositionMode(false), q(p) + compositionModeStatus(0), q(p) { fb = QDirectFBScreen::instance()->dfb(); ignoreSystemClip = QDirectFBScreen::instance()->directFBFlags() & QDirectFBScreen::IgnoreSystemClip; @@ -769,7 +789,7 @@ void QDirectFBPaintEnginePrivate::setTransform(const QTransform &transform) { transformationType = transform.type(); if (qMin(transform.m11(), transform.m22()) < 0) { - transformationType |= QDirectFBPaintEnginePrivate::NegativeScale; + transformationType |= QDirectFBPaintEnginePrivate::Matrix_NegativeScale; } setPen(q->state()->pen); } @@ -791,7 +811,51 @@ void QDirectFBPaintEnginePrivate::setPen(const QPen &pen) void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode mode) { - unsupportedCompositionMode = (mode != QPainter::CompositionMode_SourceOver); + if (!surface) + return; + compositionModeStatus = PorterDuff_SupportedBlits; + switch (mode) { + case QPainter::CompositionMode_Clear: + surface->SetPorterDuff(surface, DSPD_CLEAR); + break; + case QPainter::CompositionMode_Source: + surface->SetPorterDuff(surface, DSPD_SRC); + break; + case QPainter::CompositionMode_SourceOver: + compositionModeStatus |= PorterDuff_SupportedPrimitives; + surface->SetPorterDuff(surface, DSPD_SRC_OVER); + break; + case QPainter::CompositionMode_DestinationOver: + surface->SetPorterDuff(surface, DSPD_DST_OVER); + break; + case QPainter::CompositionMode_SourceIn: + surface->SetPorterDuff(surface, DSPD_SRC_IN); + break; + case QPainter::CompositionMode_DestinationIn: + surface->SetPorterDuff(surface, DSPD_DST_IN); + break; + case QPainter::CompositionMode_SourceOut: + surface->SetPorterDuff(surface, DSPD_SRC_OUT); + break; + case QPainter::CompositionMode_DestinationOut: + surface->SetPorterDuff(surface, DSPD_DST_OUT); + break; + case QPainter::CompositionMode_SourceAtop: + surface->SetPorterDuff(surface, DSPD_SRC_ATOP); + break; + case QPainter::CompositionMode_DestinationAtop: + surface->SetPorterDuff(surface, DSPD_DST_ATOP); + break; + case QPainter::CompositionMode_Plus: + surface->SetPorterDuff(surface, DSPD_ADD); + break; + case QPainter::CompositionMode_Xor: + surface->SetPorterDuff(surface, DSPD_XOR); + break; + default: + compositionModeStatus = 0; + break; + } } void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints) @@ -897,7 +961,7 @@ static inline qreal fixCoord(qreal rect_pos, qreal pixmapSize, qreal offset) void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap, const QPointF &off) { Q_ASSERT(!dirtyClip); - Q_ASSERT(!(transformationType & BlitUnsupported)); + Q_ASSERT(!(transformationType & Matrix_BlitsUnsupported)); const QTransform &transform = q->state()->matrix; const QRect destinationRect = transform.mapRect(dest).toRect().normalized(); QRect newClip = destinationRect; @@ -1108,7 +1172,7 @@ template <> inline const bool* ptr(const bool &) { return 0; } template static void rasterFallbackWarn(const char *msg, const char *func, const device *dev, uint transformationType, bool simplePen, - bool dfbHandledClip, bool unsupportedCompositionMode, + bool dfbHandledClip, uint compositionModeStatus, const char *nameOne, const T1 &one, const char *nameTwo, const T2 &two, const char *nameThree, const T3 &three) @@ -1125,7 +1189,7 @@ static void rasterFallbackWarn(const char *msg, const char *func, const device * dbg << QString("transformationType 0x%1").arg(transformationType, 3, 16, QLatin1Char('0')) << "simplePen" << simplePen << "dfbHandledClip" << dfbHandledClip - << "unsupportedCompositionMode" << unsupportedCompositionMode; + << "compositionModeStatus" << compositionModeStatus; const T1 *t1 = ptr(one); const T2 *t2 = ptr(two); -- cgit v0.12 From 3f6adc4a8071257c3a7211343b7591a1c32d73bd Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 27 Jul 2009 16:51:51 -0700 Subject: Major clipping patch in QDirectFBPaintEngine Handle region clips by iterating over the rectangles and updating clips accordingly. Reviewed-by: Noam Rosenthal --- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 166 +++++++++++---------- 1 file changed, 91 insertions(+), 75 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 67aa516..68d4b04 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -70,6 +70,14 @@ public: PorterDuff_SupportedPrimitives = 0x2 }; + enum ClipType { + ClipUnset, + NoClip, + RectClip, + RegionClip, + ComplexClip + }; + QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p); ~QDirectFBPaintEnginePrivate(); @@ -83,9 +91,6 @@ public: inline void lock(); inline void unlock(); - inline bool dfbCanHandleClip(const QRect &rect) const; - inline bool dfbCanHandleClip(const QRectF &rect) const; - inline bool dfbCanHandleClip() const; inline bool isSimpleBrush(const QBrush &brush) const; void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap, const QPointF &pos); @@ -110,14 +115,11 @@ private: uint transformationType; // this is QTransform::type() + Matrix_NegativeScale if qMin(transform.m11(), transform.m22()) < 0 SurfaceCache *surfaceCache; - IDirectFB *fb; - quint8 opacity; bool dirtyClip; - bool dfbHandledClip; - bool ignoreSystemClip; + ClipType clipType; QDirectFBPaintDevice *dfbDevice; uint compositionModeStatus; @@ -170,7 +172,7 @@ enum PaintOperation { template static void rasterFallbackWarn(const char *msg, const char *func, const device *dev, uint transformationType, bool simplePen, - bool dfbHandledClip, uint compositionModeStatus, + uint clipType, uint compositionModeStatus, const char *nameOne, const T1 &one, const char *nameTwo, const T2 &two, const char *nameThree, const T3 &three); @@ -183,7 +185,7 @@ static void rasterFallbackWarn(const char *msg, const char *func, const device * __FUNCTION__, state()->painter->device(), \ d_func()->transformationType, \ d_func()->simplePen, \ - d_func()->dfbCanHandleClip(), \ + d_func()->clipType, \ d_func()->compositionModeStatus, \ #one, one, #two, two, #three, three); \ if (op & (QT_DIRECTFB_DISABLE_RASTERFALLBACKS)) \ @@ -199,14 +201,13 @@ static void rasterFallbackWarn(const char *msg, const char *func, const device * __FUNCTION__, state()->painter->device(), \ d_func()->transformationType, \ d_func()->simplePen, \ - d_func()->dfbCanHandleClip(), \ + d_func()->clipType, \ d_func()->compositionModeStatus, \ #one, one, #two, two, #three, three); #else #define RASTERFALLBACK(op, one, two, three) #endif - template static inline void drawLines(const T *lines, int n, const QTransform &transform, IDirectFBSurface *surface); template @@ -214,6 +215,36 @@ static inline void fillRects(const T *rects, int n, const QTransform &transform, template static inline void drawRects(const T *rects, int n, const QTransform &transform, IDirectFBSurface *surface); +#define CLIPPED_PAINT(operation) { \ + DFBRegion clipRegion; \ + switch (d->clipType) { \ + case QDirectFBPaintEnginePrivate::NoClip: \ + case QDirectFBPaintEnginePrivate::RectClip: \ + operation; \ + break; \ + case QDirectFBPaintEnginePrivate::RegionClip: { \ + Q_ASSERT(d->clip()); \ + const QVector cr = d->clip()->clipRegion.rects(); \ + const int size = cr.size(); \ + for (int i=0; icurrentClip = cr.at(i); \ + clipRegion.x1 = d->currentClip.x(); \ + clipRegion.y1 = d->currentClip.y(); \ + clipRegion.x2 = d->currentClip.right(); \ + clipRegion.y2 = d->currentClip.bottom(); \ + d->surface->SetClip(d->surface, &clipRegion); \ + operation; \ + } \ + d->dirtyClip = true; \ + break; } \ + case QDirectFBPaintEnginePrivate::ComplexClip: \ + case QDirectFBPaintEnginePrivate::ClipUnset: \ + qFatal("CLIPPED_PAINT internal error %d", d->clipType); \ + break; \ + } \ + } + + QDirectFBPaintEngine::QDirectFBPaintEngine(QPaintDevice *device) : QRasterPaintEngine(*(new QDirectFBPaintEnginePrivate(this)), device) { @@ -245,7 +276,6 @@ bool QDirectFBPaintEngine::begin(QPaintDevice *device) d->prepare(d->dfbDevice); d->setCompositionMode(state()->composition_mode); - return QRasterPaintEngine::begin(device); } @@ -335,58 +365,60 @@ void QDirectFBPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount) { Q_D(QDirectFBPaintEngine); - d->updateClip(); + const QPen &pen = state()->pen; const QBrush &brush = state()->brush; + if (brush == Qt::NoBrush && pen == Qt::NoPen) + return; + + d->updateClip(); if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) || !d->simplePen - || !d->dfbCanHandleClip() + || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip || !d->isSimpleBrush(brush)) { RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG()); d->lock(); QRasterPaintEngine::drawRects(rects, rectCount); return; } - d->unlock(); - if (brush != Qt::NoBrush) { d->setDFBColor(brush.color()); - ::fillRects(rects, rectCount, state()->matrix, d->surface); + CLIPPED_PAINT(::fillRects(rects, rectCount, state()->matrix, d->surface)); } - const QPen &pen = state()->pen; if (pen != Qt::NoPen) { d->setDFBColor(pen.color()); - ::drawRects(rects, rectCount, state()->matrix, d->surface); + CLIPPED_PAINT(::drawRects(rects, rectCount, state()->matrix, d->surface)); } } void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount) { Q_D(QDirectFBPaintEngine); - d->updateClip(); + const QPen &pen = state()->pen; const QBrush &brush = state()->brush; + if (brush == Qt::NoBrush && pen == Qt::NoPen) + return; + + d->updateClip(); if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) || !d->simplePen - || !d->dfbCanHandleClip() + || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip || !d->isSimpleBrush(brush)) { RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG()); d->lock(); QRasterPaintEngine::drawRects(rects, rectCount); return; } - d->unlock(); - if (brush != Qt::NoBrush) { d->setDFBColor(brush.color()); - ::fillRects(rects, rectCount, state()->matrix, d->surface); + CLIPPED_PAINT(::fillRects(rects, rectCount, state()->matrix, d->surface)); } - const QPen &pen = state()->pen; if (pen != Qt::NoPen) { d->setDFBColor(pen.color()); - ::drawRects(rects, rectCount, state()->matrix, d->surface); + CLIPPED_PAINT(::drawRects(rects, rectCount, state()->matrix, d->surface)); } } @@ -394,9 +426,10 @@ void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount) { Q_D(QDirectFBPaintEngine); d->updateClip(); + if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) || !d->simplePen - || !d->dfbCanHandleClip()) { + || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) { RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG()); d->lock(); QRasterPaintEngine::drawLines(lines, lineCount); @@ -407,7 +440,7 @@ void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount) if (pen != Qt::NoPen) { d->unlock(); d->setDFBColor(pen.color()); - ::drawLines(lines, lineCount, state()->matrix, d->surface); + CLIPPED_PAINT(::drawLines(lines, lineCount, state()->matrix, d->surface)); } } @@ -415,9 +448,10 @@ void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount) { Q_D(QDirectFBPaintEngine); d->updateClip(); + if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) || !d->simplePen - || !d->dfbCanHandleClip()) { + || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) { RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG()); d->lock(); QRasterPaintEngine::drawLines(lines, lineCount); @@ -428,7 +462,7 @@ void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount) if (pen != Qt::NoPen) { d->unlock(); d->setDFBColor(pen.color()); - ::drawLines(lines, lineCount, state()->matrix, d->surface); + CLIPPED_PAINT(::drawLines(lines, lineCount, state()->matrix, d->surface)); } } @@ -460,7 +494,7 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image, #if !defined QT_NO_DIRECTFB_PREALLOCATED || defined QT_DIRECTFB_IMAGECACHE if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) - || !d->dfbCanHandleClip(r) + || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip #ifndef QT_DIRECTFB_IMAGECACHE || QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN #elif defined QT_NO_DIRECTFB_PREALLOCATED @@ -479,7 +513,7 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image, bool release; IDirectFBSurface *imgSurface = d->getSurface(image, &release); d->prepareForBlit(QDirectFBScreen::hasAlpha(imgSurface)); - d->blit(r, imgSurface, sr); + CLIPPED_PAINT(d->blit(r, imgSurface, sr)); if (release) { #if (Q_DIRECTFB_VERSION >= 0x010000) d->surface->ReleaseSource(d->surface); @@ -498,15 +532,15 @@ void QDirectFBPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap, const QRectF &sr) { Q_D(QDirectFBPaintEngine); - d->updateClip(); + d->updateClip(); if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) { RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr); d->lock(); QRasterPaintEngine::drawPixmap(r, pixmap, sr); } else if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) - || !d->dfbCanHandleClip(r)) { + || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) { RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr); const QImage *img = static_cast(pixmap.pixmapData())->buffer(DSLF_READ); d->lock(); @@ -519,7 +553,8 @@ void QDirectFBPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap, QDirectFBPixmapData *dfbData = static_cast(data); dfbData->unlockDirectFB(); IDirectFBSurface *s = dfbData->directFBSurface(); - d->blit(r, s, sr); + + CLIPPED_PAINT(d->blit(r, s, sr)); } } @@ -540,7 +575,7 @@ void QDirectFBPaintEngine::drawTiledPixmap(const QRectF &r, QRasterPaintEngine::drawTiledPixmap(r, pixmap, offset); } else if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) - || !d->dfbCanHandleClip(r)) { + || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) { RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset); const QImage *img = static_cast(pixmap.pixmapData())->buffer(DSLF_READ); d->lock(); @@ -639,7 +674,7 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) if (brush.style() == Qt::NoBrush) return; d->updateClip(); - if (d->dfbCanHandleClip(rect)) { + if (d->clipType != QDirectFBPaintEnginePrivate::ComplexClip) { switch (brush.style()) { case Qt::SolidPattern: { if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) @@ -652,9 +687,9 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) d->unlock(); d->setDFBColor(color); const QRect r = state()->matrix.mapRect(rect).toRect(); - d->surface->FillRectangle(d->surface, r.x(), r.y(), - r.width(), r.height()); + CLIPPED_PAINT(d->surface->FillRectangle(d->surface, r.x(), r.y(), r.width(), r.height())); return; } + case Qt::TexturePattern: { if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)) { @@ -666,7 +701,7 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) break; d->unlock(); - d->drawTiledPixmap(rect, texture, rect.topLeft() - state()->brushOrigin); + CLIPPED_PAINT(d->drawTiledPixmap(rect, texture, rect.topLeft() - state()->brushOrigin)); return; } default: break; @@ -685,7 +720,7 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color) d->updateClip(); if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) - || !d->dfbCanHandleClip()) { + || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) { RASTERFALLBACK(FILL_RECT, rect, color, VOID_ARG()); d->lock(); QRasterPaintEngine::fillRect(rect, color); @@ -732,11 +767,10 @@ void QDirectFBPaintEngine::initImageCache(int size) QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p) : surface(0), antialiased(false), simplePen(false), transformationType(0), opacity(255), dirtyClip(true), - dfbHandledClip(false), dfbDevice(0), + clipType(ClipUnset), dfbDevice(0), compositionModeStatus(0), q(p) { fb = QDirectFBScreen::instance()->dfb(); - ignoreSystemClip = QDirectFBScreen::instance()->directFBFlags() & QDirectFBScreen::IgnoreSystemClip; surfaceCache = new SurfaceCache; } @@ -745,23 +779,6 @@ QDirectFBPaintEnginePrivate::~QDirectFBPaintEnginePrivate() delete surfaceCache; } -bool QDirectFBPaintEnginePrivate::dfbCanHandleClip(const QRect &) const -{ - // TODO: Check to see if DirectFB can handle the clip for the given rect - return dfbHandledClip; -} - -bool QDirectFBPaintEnginePrivate::dfbCanHandleClip(const QRectF &) const -{ - // TODO: Check to see if DirectFB can handle the clip for the given rect - return dfbHandledClip; -} - -bool QDirectFBPaintEnginePrivate::dfbCanHandleClip() const -{ - return dfbHandledClip; -} - bool QDirectFBPaintEnginePrivate::isSimpleBrush(const QBrush &brush) const { return (brush.style() == Qt::NoBrush) || (brush.style() == Qt::SolidPattern && !antialiased); @@ -974,8 +991,8 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, const QPix const DFBRegion clip = { newClip.x(), newClip.y(), - newClip.x() + newClip.width() - 1, - newClip.y() + newClip.height() - 1 + newClip.right(), + newClip.bottom() }; surface->SetClip(surface, &clip); @@ -1044,8 +1061,8 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, const QPix const DFBRegion clip = { currentClip.x(), currentClip.y(), - currentClip.x() + currentClip.width(), - currentClip.y() + currentClip.height() + currentClip.right(), + currentClip.bottom() }; surface->SetClip(surface, &clip); } @@ -1060,22 +1077,22 @@ void QDirectFBPaintEnginePrivate::updateClip() const QClipData *clipData = clip(); if (!clipData || !clipData->enabled) { surface->SetClip(surface, NULL); - dfbHandledClip = true; + clipType = NoClip; } else if (clipData->hasRectClip) { const DFBRegion r = { clipData->clipRect.x(), clipData->clipRect.y(), - clipData->clipRect.x() + clipData->clipRect.width(), - clipData->clipRect.y() + clipData->clipRect.height() + clipData->clipRect.right(), + clipData->clipRect.bottom() }; surface->SetClip(surface, &r); currentClip = clipData->clipRect.normalized(); // ### is this guaranteed to always be normalized? - dfbHandledClip = true; - } else if (clipData->hasRegionClip && ignoreSystemClip && clipData->clipRegion == systemClip) { - dfbHandledClip = true; + clipType = RectClip; + } else if (clipData->hasRegionClip) { + clipType = RegionClip; } else { - dfbHandledClip = false; + clipType = ComplexClip; } dirtyClip = false; @@ -1172,7 +1189,7 @@ template <> inline const bool* ptr(const bool &) { return 0; } template static void rasterFallbackWarn(const char *msg, const char *func, const device *dev, uint transformationType, bool simplePen, - bool dfbHandledClip, uint compositionModeStatus, + uint clipType, uint compositionModeStatus, const char *nameOne, const T1 &one, const char *nameTwo, const T2 &two, const char *nameThree, const T3 &three) @@ -1188,7 +1205,7 @@ static void rasterFallbackWarn(const char *msg, const char *func, const device * dbg << QString("transformationType 0x%1").arg(transformationType, 3, 16, QLatin1Char('0')) << "simplePen" << simplePen - << "dfbHandledClip" << dfbHandledClip + << "clipType" << clipType << "compositionModeStatus" << compositionModeStatus; const T1 *t1 = ptr(one); @@ -1206,7 +1223,6 @@ static void rasterFallbackWarn(const char *msg, const char *func, const device * } qWarning("%s", qPrintable(out)); } -#endif - +#endif // QT_DIRECTFB_WARN_ON_RASTERFALLBACKS #endif // QT_NO_DIRECTFB -- cgit v0.12 From cb52327b12aa6c25696101a63d44bc688c165f47 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 27 Jul 2009 18:41:39 -0700 Subject: Fix off-by-one bug in QDirectFBScreen::flipSurface DFBRegions are exactly like QRects it turns out. x2/y2 == QRect::right()/QRect::bottom() This means I actually can reinterpret_cast QRect to DFBRegions but it's not really worth it. Reviewed-by: Noam Rosenthal --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 4b76ef6..642a386 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -1330,15 +1330,15 @@ void QDirectFBScreen::flipSurface(IDirectFBSurface *surface, DFBSurfaceFlipFlags for (int i=0; iFlip(surface, &dfbReg, i + 1 < rects.size() ? nonWaitFlags : flipFlags); } } else { const QRect r = region.boundingRect(); const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(), - r.x() + r.width() + offset.x(), - r.y() + r.height() + offset.y() }; + r.right() + offset.x(), + r.bottom() + offset.y() }; surface->Flip(surface, &dfbReg, flipFlags); } } -- cgit v0.12 From 444bbfe4f9e82a4d70c707a6c35da54065c6958e Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 27 Jul 2009 12:53:44 -0700 Subject: Remove ignore system clip stuff in dfbpaintengine Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 3 --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.h | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 642a386..04759a4 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -916,9 +916,6 @@ bool QDirectFBScreen::connect(const QString &displaySpec) QDirectFBPaintEngine::initImageCache(imageCacheSize); #endif - if (displayArgs.contains(QLatin1String("ignoresystemclip"), Qt::CaseInsensitive)) - d_ptr->directFBFlags |= IgnoreSystemClip; - #ifndef QT_NO_DIRECTFB_WM if (displayArgs.contains(QLatin1String("fullscreen"))) #endif diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h index c128932..92ea072 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h @@ -79,8 +79,7 @@ public: NoFlags = 0x00, VideoOnly = 0x01, SystemOnly = 0x02, - IgnoreSystemClip = 0x04, - BoundingRectFlip = 0x08 + BoundingRectFlip = 0x04 }; Q_DECLARE_FLAGS(DirectFBFlags, DirectFBFlag); -- cgit v0.12 From 8cfdb13015a58905539c25334e05492f9afe103b Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 28 Jul 2009 09:41:00 +0200 Subject: Don't use layered windows for non-translucent windows Reviewed-by: Samuel --- src/gui/painting/qwindowsurface_raster.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qwindowsurface_raster.cpp b/src/gui/painting/qwindowsurface_raster.cpp index 409d297..7fe5478 100644 --- a/src/gui/painting/qwindowsurface_raster.cpp +++ b/src/gui/painting/qwindowsurface_raster.cpp @@ -128,7 +128,7 @@ QPaintDevice *QRasterWindowSurface::paintDevice() void QRasterWindowSurface::beginPaint(const QRegion &rgn) { #if (defined(Q_WS_X11) && !defined(QT_NO_XRENDER)) || (defined(Q_WS_WIN) && !defined(Q_OS_WINCE)) - if (!qt_widget_private(window())->isOpaque) { + if (!qt_widget_private(window())->isOpaque && window()->testAttribute(Qt::WA_TranslucentBackground)) { #if defined(Q_WS_WIN) && !defined(Q_OS_WINCE) if (d_ptr->image->image.format() != QImage::Format_ARGB32_Premultiplied && d_ptr->canUseLayeredWindow) @@ -160,7 +160,7 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi QRect br = rgn.boundingRect(); #ifndef Q_OS_WINCE - if (!qt_widget_private(window())->isOpaque && d->canUseLayeredWindow) { + if (!qt_widget_private(window())->isOpaque && d->canUseLayeredWindow && window()->testAttribute(Qt::WA_TranslucentBackground)) { QRect r = window()->frameGeometry(); QPoint frameOffset = qt_widget_private(window())->frameStrut().topLeft(); QRect dirtyRect = br.translated(offset + frameOffset); -- cgit v0.12 From ac92e906114ed7216cfd99e0deecfb7be0fd91ec Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Tue, 28 Jul 2009 09:55:20 +0200 Subject: Fixed drawImage() so that it doesn't sample outside the source image. In qt_scale_image_16bit() and qt_scale_image_32bit(), when a sample point was located on the border between two pixels in the source image, the sample point was rounded up instead of down. If a sample point was exactly on the bottom or right edge of the source image, the function would therefore sample a pixel outside the image. Because of how the target rectangle is rounded, a sample point will never be exactly on the top or left edge of the source image, so we will not get a similar problem there. I extended the lance test pixmap_scaling.qps. Task-number: 258533 Reviewed-by: Samuel --- src/gui/painting/qblendfunctions.cpp | 8 +- tests/arthur/data/qps/pixmap_scaling.qps | 346 +++++++++++++++++++++++++++++-- 2 files changed, 331 insertions(+), 23 deletions(-) diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp index baea140..82abec3 100644 --- a/src/gui/painting/qblendfunctions.cpp +++ b/src/gui/painting/qblendfunctions.cpp @@ -192,8 +192,8 @@ void qt_scale_image_16bit(uchar *destPixels, int dbpl, int h = ty2 - ty1; int w = tx2 - tx1; - const int dstx = int((tx1 + 0.5 - qMin(targetRect.left(), targetRect.right())) * ix); - const int dsty = int((ty1 + 0.5 - qMin(targetRect.top(), targetRect.bottom())) * iy); + const int dstx = qCeil((tx1 + 0.5 - qMin(targetRect.left(), targetRect.right())) * ix) - 1; + const int dsty = qCeil((ty1 + 0.5 - qMin(targetRect.top(), targetRect.bottom())) * iy) - 1; quint32 basex = quint32((sx < 0 ? srcRect.right() : srcRect.left()) * 65536) + dstx; quint32 srcy = quint32((sy < 0 ? srcRect.bottom() : srcRect.top()) * 65536) + dsty; @@ -667,8 +667,8 @@ template void qt_scale_image_32bit(uchar *destPixels, int dbpl, int h = ty2 - ty1; int w = tx2 - tx1; - const int dstx = int((tx1 + 0.5 - qMin(targetRect.left(), targetRect.right())) * ix); - const int dsty = int((ty1 + 0.5 - qMin(targetRect.top(), targetRect.bottom())) * iy); + const int dstx = qCeil((tx1 + 0.5 - qMin(targetRect.left(), targetRect.right())) * ix) - 1; + const int dsty = qCeil((ty1 + 0.5 - qMin(targetRect.top(), targetRect.bottom())) * iy) - 1; quint32 basex = quint32((sx < 0 ? srcRect.right() : srcRect.left()) * 65536) + dstx; quint32 srcy = quint32((sy < 0 ? srcRect.bottom() : srcRect.top()) * 65536) + dsty; diff --git a/tests/arthur/data/qps/pixmap_scaling.qps b/tests/arthur/data/qps/pixmap_scaling.qps index 81b8fae..c5053ad 100644 --- a/tests/arthur/data/qps/pixmap_scaling.qps +++ b/tests/arthur/data/qps/pixmap_scaling.qps @@ -3,8 +3,8 @@ translate 5 25 setFont "arial" 8 -save - drawText 15 0 "opaque image" +save + drawText 15 0 "opaque image" translate 50 50 save translate 1 1 @@ -16,23 +16,23 @@ save scale -20 20 drawImage solid2x2.png 0 0 restore - save + save translate 1 -1 scale 20 -20 drawImage solid2x2.png 0 0 restore - save + save translate -1 -1 scale -20 -20 drawImage solid2x2.png 0 0 restore - -restore + +restore save translate 150 0 - drawText 15 0 "alpha image" + drawText 15 0 "alpha image" translate 50 50 save translate 1 1 @@ -44,12 +44,12 @@ save scale -20 20 drawImage alpha2x2.png 0 0 restore - save + save translate 1 -1 scale 20 -20 drawImage alpha2x2.png 0 0 restore - save + save translate -1 -1 scale -20 -20 drawImage alpha2x2.png 0 0 @@ -59,7 +59,7 @@ restore save translate 0 150 - drawText 15 0 "solid pixmap" + drawText 15 0 "solid pixmap" translate 50 50 save translate 1 1 @@ -71,12 +71,12 @@ save scale -20 20 drawPixmap solid2x2.png 0 0 restore - save + save translate 1 -1 scale 20 -20 drawPixmap solid2x2.png 0 0 restore - save + save translate -1 -1 scale -20 -20 drawPixmap solid2x2.png 0 0 @@ -85,9 +85,9 @@ restore save - translate 150 150 + translate 150 150 drawText 15 0 "alpha pixmap" - translate 50 50 + translate 50 50 save translate 1 1 scale 20 20 @@ -98,12 +98,12 @@ save scale -20 20 drawPixmap alpha2x2.png 0 0 restore - save + save translate 1 -1 scale 20 -20 drawPixmap alpha2x2.png 0 0 restore - save + save translate -1 -1 scale -20 -20 drawPixmap alpha2x2.png 0 0 @@ -111,7 +111,7 @@ save restore -save +save translate 300 10 save drawText 0 -10 "subrect solid image" @@ -138,7 +138,7 @@ save drawImage solid2x2.png 45 0 5 50 1.8 0 0.2 2 restore - save + save translate 150 0 drawText 0 -10 "subrect solid image" drawImage alpha2x2.png 0 0 50 5 0 0.0 2 0.2 @@ -151,7 +151,7 @@ save drawImage alpha2x2.png 0 35 50 5 0 1.4 2 0.2 drawImage alpha2x2.png 0 40 50 5 0 1.6 2 0.2 drawImage alpha2x2.png 0 45 50 5 0 1.8 2 0.2 - translate 60 0 + translate 60 0 drawImage alpha2x2.png 0 0 5 50 0.0 0 0.2 2 drawImage alpha2x2.png 5 0 5 50 0.2 0 0.2 2 drawImage alpha2x2.png 10 0 5 50 0.4 0 0.2 2 @@ -217,3 +217,311 @@ save restore restore + + + +image_load alpha2x2.png alpha2x2 +image_convertToFormat alpha2x2 alpha2x2_argb32 ARGB32 +image_convertToFormat alpha2x2 alpha2x2_argb32pre ARGB32_Premultiplied +image_convertToFormat alpha2x2 alpha2x2_rgb888 Format_RGB888 +image_convertToFormat alpha2x2 alpha2x2_rgb32 RGB32 +image_convertToFormat alpha2x2 alpha2x2_rgb16 Format_RGB16 + +save + translate 0 300 + drawText 15 0 "drawImage - argb32" + translate 50 50 + save + translate 0.5 0.5 + scale 20 20 + drawImage alpha2x2_argb32 0 0 + restore + save + translate -0.5 0.5 + scale -20 20 + drawImage alpha2x2_argb32 0 0 + restore + save + translate 0.5 -0.5 + scale 20 -20 + drawImage alpha2x2_argb32 0 0 + restore + save + translate -0.5 -0.5 + scale -20 -20 + drawImage alpha2x2_argb32 0 0 + restore +restore + +save + translate 150 300 + drawText 15 0 "drawImage - argb32premul" + translate 50 50 + save + translate 0.5 0.5 + scale 20 20 + drawImage alpha2x2_argb32pre 0 0 + restore + save + translate -0.5 0.5 + scale -20 20 + drawImage alpha2x2_argb32pre 0 0 + restore + save + translate 0.5 -0.5 + scale 20 -20 + drawImage alpha2x2_argb32pre 0 0 + restore + save + translate -0.5 -0.5 + scale -20 -20 + drawImage alpha2x2_argb32pre 0 0 + restore +restore + + + +save + translate 0 450 + drawText 15 0 "drawImage - rgb888" + translate 50 50 + save + translate 0.5 0.5 + scale 20 20 + drawImage alpha2x2_rgb888 0 0 + restore + save + translate -0.5 0.5 + scale -20 20 + drawImage alpha2x2_rgb888 0 0 + restore + save + translate 0.5 -0.5 + scale 20 -20 + drawImage alpha2x2_rgb888 0 0 + restore + save + translate -0.5 -0.5 + scale -20 -20 + drawImage alpha2x2_rgb888 0 0 + restore +restore + +save + translate 150 450 + drawText 15 0 "drawImage - rgb32" + translate 50 50 + save + translate 0.5 0.5 + scale 20 20 + drawImage alpha2x2_rgb32 0 0 + restore + save + translate -0.5 0.5 + scale -20 20 + drawImage alpha2x2_rgb32 0 0 + restore + save + translate 0.5 -0.5 + scale 20 -20 + drawImage alpha2x2_rgb32 0 0 + restore + save + translate -0.5 -0.5 + scale -20 -20 + drawImage alpha2x2_rgb32 0 0 + restore +restore + +save + translate 300 450 + drawText 15 0 "drawImage - rgb16" + translate 50 50 + save + translate 0.5 0.5 + scale 20 20 + drawImage alpha2x2_rgb16 0 0 + restore + save + translate -0.5 0.5 + scale -20 20 + drawImage alpha2x2_rgb16 0 0 + restore + save + translate 0.5 -0.5 + scale 20 -20 + drawImage alpha2x2_rgb16 0 0 + restore + save + translate -0.5 -0.5 + scale -20 -20 + drawImage alpha2x2_rgb16 0 0 + restore +restore + + + +save + translate 0 600 + drawText 15 0 "clipping - argb32" + translate 50 50 + setClipRect -30 -30 60 60 ReplaceClip + save + translate 0.5 0.5 + scale 20 20 + drawImage alpha2x2_argb32 0 0 + restore + save + translate -0.5 0.5 + scale -20 20 + drawImage alpha2x2_argb32 0 0 + restore + save + translate 0.5 -0.5 + scale 20 -20 + drawImage alpha2x2_argb32 0 0 + restore + save + translate -0.5 -0.5 + scale -20 -20 + drawImage alpha2x2_argb32 0 0 + restore +restore + +save + translate 150 600 + drawText 15 0 "clipping - argb32premul" + translate 50 50 + setClipRect -30 -30 60 60 ReplaceClip + save + translate 0.5 0.5 + scale 20 20 + drawImage alpha2x2_argb32pre 0 0 + restore + save + translate -0.5 0.5 + scale -20 20 + drawImage alpha2x2_argb32pre 0 0 + restore + save + translate 0.5 -0.5 + scale 20 -20 + drawImage alpha2x2_argb32pre 0 0 + restore + save + translate -0.5 -0.5 + scale -20 -20 + drawImage alpha2x2_argb32pre 0 0 + restore +restore + +save + translate 300 600 + drawText 15 0 "clipping - rgb16" + translate 50 50 + setClipRect -30 -30 60 60 ReplaceClip + save + translate 0.5 0.5 + scale 20 20 + drawImage alpha2x2_rgb16 0 0 + restore + save + translate -0.5 0.5 + scale -20 20 + drawImage alpha2x2_rgb16 0 0 + restore + save + translate 0.5 -0.5 + scale 20 -20 + drawImage alpha2x2_rgb16 0 0 + restore + save + translate -0.5 -0.5 + scale -20 -20 + drawImage alpha2x2_rgb16 0 0 + restore +restore + + +path_addEllipse ellipse -30 -30 60 60 + +save + translate 0 750 + drawText 15 0 "clipping - argb32" + translate 50 50 + setClipPath ellipse ReplaceClip + save + translate 0.5 0.5 + scale 20 20 + drawImage alpha2x2_argb32 0 0 + restore + save + translate -0.5 0.5 + scale -20 20 + drawImage alpha2x2_argb32 0 0 + restore + save + translate 0.5 -0.5 + scale 20 -20 + drawImage alpha2x2_argb32 0 0 + restore + save + translate -0.5 -0.5 + scale -20 -20 + drawImage alpha2x2_argb32 0 0 + restore +restore + +save + translate 150 750 + drawText 15 0 "clipping - argb32premul" + translate 50 50 + setClipPath ellipse ReplaceClip + save + translate 0.5 0.5 + scale 20 20 + drawImage alpha2x2_argb32pre 0 0 + restore + save + translate -0.5 0.5 + scale -20 20 + drawImage alpha2x2_argb32pre 0 0 + restore + save + translate 0.5 -0.5 + scale 20 -20 + drawImage alpha2x2_argb32pre 0 0 + restore + save + translate -0.5 -0.5 + scale -20 -20 + drawImage alpha2x2_argb32pre 0 0 + restore +restore + +save + translate 300 750 + drawText 15 0 "clipping - rgb16" + translate 50 50 + setClipPath ellipse ReplaceClip + save + translate 0.5 0.5 + scale 20 20 + drawImage alpha2x2_rgb16 0 0 + restore + save + translate -0.5 0.5 + scale -20 20 + drawImage alpha2x2_rgb16 0 0 + restore + save + translate 0.5 -0.5 + scale 20 -20 + drawImage alpha2x2_rgb16 0 0 + restore + save + translate -0.5 -0.5 + scale -20 -20 + drawImage alpha2x2_rgb16 0 0 + restore +restore -- cgit v0.12 From b0482e0b13ea3c20674515ffdafb66c14231cc56 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 28 Jul 2009 15:54:20 +0200 Subject: Regression: QColorDialog crash on Mac when accepting with keyboard Basically, the crash happends because we release the dialog when the ok button is clicked. But when the button is clicked with the keyboard (actually cocoa emulates a click when pressing enter), it also tries to do some focus handling on the button afterwards. But at that point, the button is already freed up. With a crash as the result. This patch goes through a lot of the code, and rewrites it so we doesnt free up the cocoa objects before the destructor of the QColorDialog is called. Task-number: 258445 Reviewed-by: msorvig --- src/gui/dialogs/qcolordialog.cpp | 22 ++-- src/gui/dialogs/qcolordialog_mac.mm | 218 +++++++++++++++++++----------------- src/gui/dialogs/qcolordialog_p.h | 13 +-- 3 files changed, 134 insertions(+), 119 deletions(-) diff --git a/src/gui/dialogs/qcolordialog.cpp b/src/gui/dialogs/qcolordialog.cpp index 510c0c4..e56faa2 100644 --- a/src/gui/dialogs/qcolordialog.cpp +++ b/src/gui/dialogs/qcolordialog.cpp @@ -1582,8 +1582,7 @@ void QColorDialog::setCurrentColor(const QColor &color) d->setCurrentAlpha(color.alpha()); #ifdef Q_WS_MAC - if (d->delegate) - QColorDialogPrivate::setColor(d->delegate, color); + d->setCocoaPanelColor(color); #endif } @@ -1724,19 +1723,16 @@ void QColorDialog::setVisible(bool visible) #if defined(Q_WS_MAC) if (visible) { - if (!d->delegate && QColorDialogPrivate::sharedColorPanelAvailable && - !(testAttribute(Qt::WA_DontShowOnScreen) || (d->opts & DontUseNativeDialog))){ - d->delegate = QColorDialogPrivate::openCocoaColorPanel( - currentColor(), parentWidget(), windowTitle(), options(), d); + if (d->delegate || (QColorDialogPrivate::sharedColorPanelAvailable && + !(testAttribute(Qt::WA_DontShowOnScreen) || (d->opts & DontUseNativeDialog)))){ + d->openCocoaColorPanel(currentColor(), parentWidget(), windowTitle(), options()); QColorDialogPrivate::sharedColorPanelAvailable = false; setAttribute(Qt::WA_DontShowOnScreen); } setWindowFlags(windowModality() == Qt::WindowModal ? Qt::Sheet : DefaultWindowFlags); } else { if (d->delegate) { - QColorDialogPrivate::closeCocoaColorPanel(d->delegate); - d->delegate = 0; - QColorDialogPrivate::sharedColorPanelAvailable = true; + d->closeCocoaColorPanel(); setAttribute(Qt::WA_DontShowOnScreen, false); } } @@ -1839,6 +1835,14 @@ QRgb QColorDialog::getRgba(QRgb initial, bool *ok, QWidget *parent) QColorDialog::~QColorDialog() { + Q_D(QColorDialog); +#if defined(Q_WS_MAC) + if (d->delegate) { + d->releaseCocoaColorPanelDelegate(); + QColorDialogPrivate::sharedColorPanelAvailable = true; + } +#endif + #ifndef QT_NO_SETTINGS if (!customSet) { QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); diff --git a/src/gui/dialogs/qcolordialog_mac.mm b/src/gui/dialogs/qcolordialog_mac.mm index 06120da..3770012 100644 --- a/src/gui/dialogs/qcolordialog_mac.mm +++ b/src/gui/dialogs/qcolordialog_mac.mm @@ -76,6 +76,8 @@ QT_USE_NAMESPACE CGFloat mMinWidth; // currently unused CGFloat mExtraHeight; // currently unused BOOL mHackedPanel; + NSInteger mResultCode; + BOOL mDialogIsExecuting; } - (id)initWithColorPanel:(NSColorPanel *)panel stolenContentView:(NSView *)stolenContentView @@ -90,7 +92,8 @@ QT_USE_NAMESPACE - (NSColorPanel *)colorPanel; - (QColor)qtColor; - (void)finishOffWithCode:(NSInteger)result; -- (void)cleanUpAfterMyself; +- (void)showColorPanel; +- (void)exec; @end @implementation QCocoaColorPanelDelegate @@ -110,6 +113,8 @@ QT_USE_NAMESPACE mMinWidth = 0.0; mExtraHeight = 0.0; mHackedPanel = (okButton != 0); + mResultCode = NSCancelButton; + mDialogIsExecuting = false; if (mHackedPanel) { [self relayout]; @@ -121,19 +126,31 @@ QT_USE_NAMESPACE [cancelButton setTarget:self]; } - if (mPriv) - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(colorChanged:) - name:NSColorPanelColorDidChangeNotification - object:mColorPanel]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(colorChanged:) + name:NSColorPanelColorDidChangeNotification + object:mColorPanel]; + mQtColor = new QColor(); return self; } - (void)dealloc { - if (mPriv) - [[NSNotificationCenter defaultCenter] removeObserver:self]; + QMacCocoaAutoReleasePool pool; + if (mHackedPanel) { + NSView *ourContentView = [mColorPanel contentView]; + + // return stolen stuff to its rightful owner + [mStolenContentView removeFromSuperview]; + [mColorPanel setContentView:mStolenContentView]; + + [mOkButton release]; + [mCancelButton release]; + [ourContentView release]; + } + [mColorPanel setDelegate:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; delete mQtColor; [super dealloc]; } @@ -160,8 +177,7 @@ QT_USE_NAMESPACE - (void)colorChanged:(NSNotification *)notification; { Q_UNUSED(notification); - if (mPriv) - [self updateQtColor]; + [self updateQtColor]; } - (void)relayout @@ -252,8 +268,7 @@ QT_USE_NAMESPACE mQtColor->setRgbF(red, green, blue, alpha); } - if (mPriv) - mPriv->setCurrentQColor(*mQtColor); + mPriv->setCurrentQColor(*mQtColor); } - (NSColorPanel *)colorPanel @@ -268,36 +283,39 @@ QT_USE_NAMESPACE - (void)finishOffWithCode:(NSInteger)code { - if (mPriv) { - // Finish the QColorDialog as well. But since a call to accept or reject will - // close down the QEventLoop found in QDialog, we need to make sure that the - // current thread has exited the native dialogs modal session/run loop first. - // We ensure this by posting the call: + // Finish the QColorDialog as well. But since a call to accept or reject will + // close down the QEventLoop found in QDialog, we need to make sure that the + // current thread has exited the native dialogs modal session/run loop first. + // We ensure this by posting the call: + mResultCode = code; + if (mDialogIsExecuting) { [NSApp stopModalWithCode:code]; - if (code == NSOKButton) - QMetaObject::invokeMethod(mPriv->colorDialog(), "accept", Qt::QueuedConnection); - else - QMetaObject::invokeMethod(mPriv->colorDialog(), "reject", Qt::QueuedConnection); } else { - [NSApp stopModalWithCode:code]; + if (mResultCode == NSCancelButton) + mPriv->colorDialog()->reject(); + else + mPriv->colorDialog()->accept(); } } -- (void)cleanUpAfterMyself +- (void)showColorPanel { - if (mHackedPanel) { - NSView *ourContentView = [mColorPanel contentView]; - - // return stolen stuff to its rightful owner - [mStolenContentView removeFromSuperview]; - [mColorPanel setContentView:mStolenContentView]; + mDialogIsExecuting = false; + [mColorPanel makeKeyAndOrderFront:mColorPanel]; +} - [mOkButton release]; - [mCancelButton release]; - [ourContentView release]; - } - [mColorPanel setDelegate:nil]; +- (void)exec +{ + QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active); + QMacCocoaAutoReleasePool pool; + mDialogIsExecuting = true; + [NSApp runModalForWindow:mColorPanel]; + if (mResultCode == NSCancelButton) + mPriv->colorDialog()->reject(); + else + mPriv->colorDialog()->accept(); } + @end QT_BEGIN_NAMESPACE @@ -306,91 +324,90 @@ extern void macStartInterceptNSPanelCtor(); extern void macStopInterceptNSPanelCtor(); extern NSButton *macCreateButton(const char *text, NSView *superview); -void *QColorDialogPrivate::openCocoaColorPanel(const QColor &initial, - QWidget *parent, const QString &title, QColorDialog::ColorDialogOptions options, - QColorDialogPrivate *priv) +void QColorDialogPrivate::openCocoaColorPanel(const QColor &initial, + QWidget *parent, const QString &title, QColorDialog::ColorDialogOptions options) { Q_UNUSED(parent); // we would use the parent if only NSColorPanel could be a sheet QMacCocoaAutoReleasePool pool; - /* - The standard Cocoa color panel has no OK or Cancel button and - is created as a utility window, whereas we want something like - the Carbon color panel. We need to take the following steps: + if (!delegate) { + /* + The standard Cocoa color panel has no OK or Cancel button and + is created as a utility window, whereas we want something like + the Carbon color panel. We need to take the following steps: + + 1. Intercept the color panel constructor to turn off the + NSUtilityWindowMask flag. This is done by temporarily + replacing initWithContentRect:styleMask:backing:defer: + in NSPanel by our own method. - 1. Intercept the color panel constructor to turn off the - NSUtilityWindowMask flag. This is done by temporarily - replacing initWithContentRect:styleMask:backing:defer: - in NSPanel by our own method. + 2. Modify the color panel so that its content view is part + of a new content view that contains it as well as two + buttons (OK and Cancel). - 2. Modify the color panel so that its content view is part - of a new content view that contains it as well as two - buttons (OK and Cancel). + 3. Lay out the original content view and the buttons when + the color panel is shown and whenever it is resized. - 3. Lay out the original content view and the buttons when - the color panel is shown and whenever it is resized. + 4. Clean up after ourselves. + */ - 4. Clean up after ourselves. - */ + bool hackColorPanel = !(options & QColorDialog::NoButtons); - bool hackColorPanel = !(options & QColorDialog::NoButtons); + if (hackColorPanel) + macStartInterceptNSPanelCtor(); + NSColorPanel *colorPanel = [NSColorPanel sharedColorPanel]; + if (hackColorPanel) + macStopInterceptNSPanelCtor(); - if (hackColorPanel) - macStartInterceptNSPanelCtor(); - NSColorPanel *colorPanel = [NSColorPanel sharedColorPanel]; - if (hackColorPanel) - macStopInterceptNSPanelCtor(); + [colorPanel setHidesOnDeactivate:false]; - [colorPanel setHidesOnDeactivate:false]; + // set up the Cocoa color panel + [colorPanel setShowsAlpha:options & QColorDialog::ShowAlphaChannel]; + [colorPanel setTitle:(NSString*)(CFStringRef)QCFString(title)]; - // set up the Cocoa color panel - [colorPanel setShowsAlpha:options & QColorDialog::ShowAlphaChannel]; - [colorPanel setTitle:(NSString*)(CFStringRef)QCFString(title)]; + NSView *stolenContentView = 0; + NSButton *okButton = 0; + NSButton *cancelButton = 0; - NSView *stolenContentView = 0; - NSButton *okButton = 0; - NSButton *cancelButton = 0; + if (hackColorPanel) { + // steal the color panel's contents view + stolenContentView = [colorPanel contentView]; + [stolenContentView retain]; + [colorPanel setContentView:0]; - if (hackColorPanel) { - // steal the color panel's contents view - stolenContentView = [colorPanel contentView]; - [stolenContentView retain]; - [colorPanel setContentView:0]; + // create a new content view and add the stolen one as a subview + NSRect frameRect = { { 0.0, 0.0 }, { 0.0, 0.0 } }; + NSView *ourContentView = [[NSView alloc] initWithFrame:frameRect]; + [ourContentView addSubview:stolenContentView]; - // create a new content view and add the stolen one as a subview - NSRect frameRect = { { 0.0, 0.0 }, { 0.0, 0.0 } }; - NSView *ourContentView = [[NSView alloc] initWithFrame:frameRect]; - [ourContentView addSubview:stolenContentView]; + // create OK and Cancel buttons and add these as subviews + okButton = macCreateButton("&OK", ourContentView); + cancelButton = macCreateButton("Cancel", ourContentView); - // create OK and Cancel buttons and add these as subviews - okButton = macCreateButton("&OK", ourContentView); - cancelButton = macCreateButton("Cancel", ourContentView); + [colorPanel setContentView:ourContentView]; + [colorPanel setDefaultButtonCell:[okButton cell]]; + } - [colorPanel setContentView:ourContentView]; - [colorPanel setDefaultButtonCell:[okButton cell]]; + delegate = [[QCocoaColorPanelDelegate alloc] initWithColorPanel:colorPanel + stolenContentView:stolenContentView + okButton:okButton + cancelButton:cancelButton + priv:this]; + [colorPanel setDelegate:static_cast(delegate)]; } - // create a delegate and set it - QCocoaColorPanelDelegate *delegate = - [[QCocoaColorPanelDelegate alloc] initWithColorPanel:colorPanel - stolenContentView:stolenContentView - okButton:okButton - cancelButton:cancelButton - priv:priv]; - [colorPanel setDelegate:delegate]; - setColor(delegate, initial); - [colorPanel makeKeyAndOrderFront:colorPanel]; - - return delegate; + setCocoaPanelColor(initial); + [static_cast(delegate) showColorPanel]; } -void QColorDialogPrivate::closeCocoaColorPanel(void *delegate) +void QColorDialogPrivate::closeCocoaColorPanel() { - QMacCocoaAutoReleasePool pool; - QCocoaColorPanelDelegate *theDelegate = static_cast(delegate); - [[theDelegate colorPanel] close]; - [theDelegate cleanUpAfterMyself]; - [theDelegate autorelease]; + [[static_cast(delegate) colorPanel] close]; +} + +void QColorDialogPrivate::releaseCocoaColorPanelDelegate() +{ + [static_cast(delegate) release]; } void QColorDialogPrivate::mac_nativeDialogModalHelp() @@ -410,13 +427,10 @@ void QColorDialogPrivate::mac_nativeDialogModalHelp() void QColorDialogPrivate::_q_macRunNativeAppModalPanel() { - QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active); - QMacCocoaAutoReleasePool pool; - QCocoaColorPanelDelegate *delegateCasted = static_cast(delegate); - [NSApp runModalForWindow:[delegateCasted colorPanel]]; + [static_cast(delegate) exec]; } -void QColorDialogPrivate::setColor(void *delegate, const QColor &color) +void QColorDialogPrivate::setCocoaPanelColor(const QColor &color) { QMacCocoaAutoReleasePool pool; QCocoaColorPanelDelegate *theDelegate = static_cast(delegate); diff --git a/src/gui/dialogs/qcolordialog_p.h b/src/gui/dialogs/qcolordialog_p.h index ea66d4a..00d40b6 100644 --- a/src/gui/dialogs/qcolordialog_p.h +++ b/src/gui/dialogs/qcolordialog_p.h @@ -116,14 +116,11 @@ public: QByteArray memberToDisconnectOnClose; #ifdef Q_WS_MAC - static void *openCocoaColorPanel(const QColor &initial, - QWidget *parent, const QString &title, - QColorDialog::ColorDialogOptions options, - QColorDialogPrivate *priv = 0); - static void closeCocoaColorPanel(void *delegate); - static QColor execCocoaColorPanel(const QColor &initial, QWidget *parent, - const QString &title, QColorDialog::ColorDialogOptions options); - static void setColor(void *delegate, const QColor &color); + void openCocoaColorPanel(const QColor &initial, + QWidget *parent, const QString &title, QColorDialog::ColorDialogOptions options); + void closeCocoaColorPanel(); + void releaseCocoaColorPanelDelegate(); + void setCocoaPanelColor(const QColor &color); inline void done(int result) { q_func()->done(result); } inline QColorDialog *colorDialog() { return q_func(); } -- cgit v0.12 From a1c4e70ddb04e364d89bfd39a409c4bcbe0019e4 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 28 Jul 2009 12:43:12 -0700 Subject: Compile with DirectFB < 1.0 These porter duff operations were added for 1.0. Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 68d4b04..8e06e6a 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -857,6 +857,7 @@ void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode m case QPainter::CompositionMode_DestinationOut: surface->SetPorterDuff(surface, DSPD_DST_OUT); break; +#if (Q_DIRECTFB_VERSION >= 0x010000) case QPainter::CompositionMode_SourceAtop: surface->SetPorterDuff(surface, DSPD_SRC_ATOP); break; @@ -866,6 +867,7 @@ void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode m case QPainter::CompositionMode_Plus: surface->SetPorterDuff(surface, DSPD_ADD); break; +#endif case QPainter::CompositionMode_Xor: surface->SetPorterDuff(surface, DSPD_XOR); break; -- cgit v0.12 From 4caf5c1568163aa8efbfabb69ef0d83c3c6efd0a Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 28 Jul 2009 13:13:26 -0700 Subject: Fix crash in when resizing directfb windows Since QRasterPaintEngine::baseClip was initialized when the QDirectFBPaintEngine was created and the paintengine persists for the window surface we run the risk that the baseClip is of the wrong size. This could lead to crashes and erroneous clipping. Reviewed-by: Donald --- .../gfxdrivers/directfb/qdirectfbwindowsurface.cpp | 15 ++++++++++----- src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp index a1009ac..15a46d7 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp @@ -56,6 +56,7 @@ QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirect , dfbWindow(0) #endif , engine(0) + , engineHeight(-1) , flipFlags(flip) , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip) { @@ -77,6 +78,7 @@ QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirect , dfbWindow(0) #endif , engine(0) + , engineHeight(-1) , flipFlags(flip) , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip) { @@ -295,11 +297,8 @@ bool QDirectFBWindowSurface::move(const QPoint &moveBy) QPaintEngine *QDirectFBWindowSurface::paintEngine() const { - if (!engine) { - QDirectFBWindowSurface *that = const_cast(this); - that->engine = new QDirectFBPaintEngine(that); - return that->engine; - } + Q_ASSERT(engine); + Q_ASSERT(height() <= engineHeight); return engine; } @@ -427,6 +426,12 @@ void QDirectFBWindowSurface::flush(QWidget *, const QRegion ®ion, void QDirectFBWindowSurface::beginPaint(const QRegion &) { + const int h = height(); + if (h > engineHeight) { + engineHeight = h; + delete engine; + engine = new QDirectFBPaintEngine(this); + } } void QDirectFBWindowSurface::endPaint(const QRegion &) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h index c46d93b..cd88aca 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h @@ -93,6 +93,7 @@ private: IDirectFBWindow *dfbWindow; #endif QDirectFBPaintEngine *engine; + int engineHeight; enum Mode { Primary, -- cgit v0.12 From c0f85469a76a25fff6951b634b67cfbcd0507b93 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 28 Jul 2009 13:49:03 -0700 Subject: Make autorepeat work for DirectFB When holding down a key DirectFB gives us only keypresses. Qt wants these kind of events: press not autorepeat release autorepeat press autorepeat release autorepeat press autorepeat release not autorepeat Reviewed-by: Donald --- .../gfxdrivers/directfb/qdirectfbkeyboard.cpp | 29 ++++++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp index b5376b1..13c4053 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp @@ -77,13 +77,15 @@ private: QSocketNotifier *keyboardNotifier; DFBEvent event; int bytesRead; - + int lastUnicode, lastKeycode; + Qt::KeyboardModifiers lastModifiers; private Q_SLOTS: void readKeyboardData(); }; QDirectFBKeyboardHandlerPrivate::QDirectFBKeyboardHandlerPrivate(QDirectFBKeyboardHandler *h) - : handler(h), eventBuffer(0) + : handler(h), eventBuffer(0), keyboardNotifier(0), bytesRead(0), + lastUnicode(0), lastKeycode(0), lastModifiers(0) { Q_ASSERT(qt_screen); @@ -114,8 +116,6 @@ QDirectFBKeyboardHandlerPrivate::QDirectFBKeyboardHandlerPrivate(QDirectFBKeyboa ::fcntl(fd, F_SETFL, flags | O_NONBLOCK); memset(&event, 0, sizeof(event)); - bytesRead = 0; - keyboardNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this); connect(keyboardNotifier, SIGNAL(activated(int)), @@ -213,8 +213,27 @@ void QDirectFBKeyboardHandlerPrivate::readKeyboardData() unicode = symbol; if (unicode != -1 || keycode != 0) { + bool autoRepeat = false; + if (press) { + if (unicode == lastUnicode && keycode == lastKeycode && modifiers == lastModifiers) { + autoRepeat = true; + } else { + lastUnicode = unicode; + lastKeycode = keycode; + lastModifiers = modifiers; + } + } else { + lastUnicode = lastKeycode = -1; + lastModifiers = 0; + } + if (autoRepeat) { + handler->processKeyEvent(unicode, keycode, + modifiers, false, autoRepeat); + + } + handler->processKeyEvent(unicode, keycode, - modifiers, press, false); + modifiers, press, autoRepeat); } } } -- cgit v0.12 From 77fc1ccec09e23de6fc6fedd368cef8111745711 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 28 Jul 2009 14:30:27 -0700 Subject: Refactor QDirectFBPaintDevice Make the engine a member in QDirectFBPaintDevice instead of one in QDirectFBPixmapData and one in QDirectFBWindowSurface. Don't use the default screen for the dfbpaintdevices. Pass one explicitly. Reviewed-by: Noam Rosenthal --- .../gfxdrivers/directfb/qdirectfbpaintdevice.cpp | 13 +++++++++++++ src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h | 17 ++++++++--------- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp | 13 +++++++------ src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h | 3 +-- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 10 ++++++---- .../gfxdrivers/directfb/qdirectfbwindowsurface.cpp | 9 --------- .../gfxdrivers/directfb/qdirectfbwindowsurface.h | 6 ++---- 7 files changed, 37 insertions(+), 34 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp index 8ad5264..7e61ed4 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp @@ -43,10 +43,17 @@ #include "qdirectfbscreen.h" #include "qdirectfbpaintdevice.h" +#include "qdirectfbpaintengine.h" + +QDirectFBPaintDevice::QDirectFBPaintDevice(QDirectFBScreen *scr) + : QCustomRasterPaintDevice(0), dfbSurface(0), lockedImage(0), screen(scr), + lock(DFBSurfaceLockFlags(0)), mem(0), engine(0) +{} QDirectFBPaintDevice::~QDirectFBPaintDevice() { delete lockedImage; + delete engine; } @@ -168,4 +175,10 @@ int QDirectFBPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const } } +QPaintEngine *QDirectFBPaintDevice::paintEngine() const +{ + return engine; +} + #endif + diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h index 248a15b..a6f9265 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h @@ -51,7 +51,8 @@ QT_BEGIN_HEADER QT_MODULE(Gui) // Inherited by both window surface and pixmap - class QDirectFBPaintDevice : public QCustomRasterPaintDevice +class QDirectFBPaintEngine; +class QDirectFBPaintDevice : public QCustomRasterPaintDevice { public: ~QDirectFBPaintDevice(); @@ -68,13 +69,10 @@ public: QSize size() const; int metric(QPaintDevice::PaintDeviceMetric metric) const; DFBSurfaceLockFlags lockFlags() const { return lock; } -protected: - // Shouldn't create QDirectFBPaintDevice by itself but only sub-class it: - QDirectFBPaintDevice(QDirectFBScreen *scr = QDirectFBScreen::instance()) - : QCustomRasterPaintDevice(0), dfbSurface(0), lockedImage(0), screen(scr), - lock(DFBSurfaceLockFlags(0)), mem(0) - {} + QPaintEngine *paintEngine() const; +protected: + QDirectFBPaintDevice(QDirectFBScreen *scr); inline int dotsPerMeterX() const { return (screen->deviceWidth() * 1000) / screen->physicalWidth(); @@ -90,9 +88,10 @@ protected: int bpl; DFBSurfaceLockFlags lock; uchar *mem; + QDirectFBPaintEngine *engine; private: - Q_DISABLE_COPY(QDirectFBPaintDevice) - }; + Q_DISABLE_COPY(QDirectFBPaintDevice); +}; QT_END_HEADER diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index dd7faf3..26a77a5 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -49,9 +49,9 @@ static int global_ser_no = 0; -QDirectFBPixmapData::QDirectFBPixmapData(PixelType pixelType) - : QPixmapData(pixelType, DirectFBClass), - engine(0), format(QImage::Format_Invalid), alpha(false) +QDirectFBPixmapData::QDirectFBPixmapData(QDirectFBScreen *screen, PixelType pixelType) + : QPixmapData(pixelType, DirectFBClass), QDirectFBPaintDevice(screen), + format(QImage::Format_Invalid), alpha(false) { setSerialNumber(0); } @@ -61,7 +61,6 @@ QDirectFBPixmapData::~QDirectFBPixmapData() unlockDirectFB(); if (dfbSurface && QDirectFBScreen::instance()) screen->releaseDFBSurface(dfbSurface); - delete engine; } void QDirectFBPixmapData::resize(int width, int height) @@ -289,7 +288,7 @@ QPixmap QDirectFBPixmapData::transformed(const QTransform &transform, Q_ASSERT(image); const QImage transformed = image->transformed(transform, mode); that->unlockDirectFB(); - QDirectFBPixmapData *data = new QDirectFBPixmapData(QPixmapData::PixmapType); + QDirectFBPixmapData *data = new QDirectFBPixmapData(screen, QPixmapData::PixmapType); data->fromImage(transformed, Qt::AutoColor); return QPixmap(data); } @@ -302,7 +301,7 @@ QPixmap QDirectFBPixmapData::transformed(const QTransform &transform, if (size.isEmpty()) return QPixmap(); - QDirectFBPixmapData *data = new QDirectFBPixmapData(QPixmapData::PixmapType); + QDirectFBPixmapData *data = new QDirectFBPixmapData(screen, QPixmapData::PixmapType); DFBSurfaceBlittingFlags flags = DSBLIT_NOFX; data->alpha = alpha; if (alpha) { @@ -357,6 +356,8 @@ QImage QDirectFBPixmapData::toImage() const return img->copy(); } +/* This is QPixmapData::paintEngine(), not QPaintDevice::paintEngine() */ + QPaintEngine *QDirectFBPixmapData::paintEngine() const { if (!engine) { diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h index 8f3ce41..5567102 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h @@ -56,7 +56,7 @@ class QDirectFBPaintEngine; class QDirectFBPixmapData : public QPixmapData, public QDirectFBPaintDevice { public: - QDirectFBPixmapData(PixelType pixelType); + QDirectFBPixmapData(QDirectFBScreen *screen, PixelType pixelType); ~QDirectFBPixmapData(); // Re-implemented from QPixmapData: @@ -78,7 +78,6 @@ public: static bool hasAlphaChannel(const QImage &img); private: void invalidate(); - QDirectFBPaintEngine *engine; QImage::Format format; bool alpha; }; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 04759a4..a28e940 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -57,7 +57,7 @@ class QDirectFBScreenPrivate : public QObject, public QWSGraphicsSystem { public: - QDirectFBScreenPrivate(QDirectFBScreen*); + QDirectFBScreenPrivate(QDirectFBScreen *qptr); ~QDirectFBScreenPrivate(); void setFlipFlags(const QStringList &args); @@ -82,10 +82,11 @@ public: QDirectFBScreen::DirectFBFlags directFBFlags; QImage::Format alphaPixmapFormat; QColor backgroundColor; + QDirectFBScreen *q; }; -QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen *screen) - : QWSGraphicsSystem(screen), dfb(0), dfbSurface(0), flipFlags(DSFLIP_NONE) +QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen *qptr) + : QWSGraphicsSystem(qptr), dfb(0), dfbSurface(0), flipFlags(DSFLIP_NONE) #ifndef QT_NO_DIRECTFB_LAYER , dfbLayer(0) #endif @@ -98,6 +99,7 @@ QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen *screen) #endif , directFBFlags(QDirectFBScreen::NoFlags) , alphaPixmapFormat(QImage::Format_Invalid) + , q(qptr) { #ifndef QT_NO_QWS_SIGNALHANDLER QWSSignalHandler::instance()->addObject(this); @@ -742,7 +744,7 @@ QPixmapData *QDirectFBScreenPrivate::createPixmapData(QPixmapData::PixelType typ if (type == QPixmapData::BitmapType) return QWSGraphicsSystem::createPixmapData(type); - return new QDirectFBPixmapData(type); + return new QDirectFBPixmapData(q, type); } #ifdef QT_NO_DEBUG diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp index 15a46d7..562e0c6 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp @@ -55,7 +55,6 @@ QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirect #ifndef QT_NO_DIRECTFB_WM , dfbWindow(0) #endif - , engine(0) , engineHeight(-1) , flipFlags(flip) , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip) @@ -77,7 +76,6 @@ QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirect #ifndef QT_NO_DIRECTFB_WM , dfbWindow(0) #endif - , engine(0) , engineHeight(-1) , flipFlags(flip) , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip) @@ -295,13 +293,6 @@ bool QDirectFBWindowSurface::move(const QPoint &moveBy) return true; } -QPaintEngine *QDirectFBWindowSurface::paintEngine() const -{ - Q_ASSERT(engine); - Q_ASSERT(height() <= engineHeight); - return engine; -} - // hw: XXX: copied from QWidgetPrivate::isOpaque() inline bool isWidgetOpaque(const QWidget *w) { diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h index cd88aca..fefe9f3 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h @@ -61,8 +61,8 @@ QT_MODULE(Gui) class QDirectFBWindowSurface : public QWSWindowSurface, public QDirectFBPaintDevice { public: - QDirectFBWindowSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr); - QDirectFBWindowSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr, QWidget *widget); + QDirectFBWindowSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen *scr); + QDirectFBWindowSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen *scr, QWidget *widget); ~QDirectFBWindowSurface(); bool isValid() const; @@ -79,7 +79,6 @@ public: QImage image() const { return QImage(); } QPaintDevice *paintDevice() { return this; } - QPaintEngine *paintEngine() const; void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); @@ -92,7 +91,6 @@ private: void createWindow(); IDirectFBWindow *dfbWindow; #endif - QDirectFBPaintEngine *engine; int engineHeight; enum Mode { -- cgit v0.12 From a57403b176c8fe5adcd4a444184832426807d0e9 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 28 Jul 2009 14:45:55 -0700 Subject: Qtify void* func => void *func Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h index a6f9265..c4aeb70 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h @@ -63,7 +63,7 @@ public: void unlockDirectFB(); // Reimplemented from QCustomRasterPaintDevice: - void* memory() const; + void *memory() const; QImage::Format format() const; int bytesPerLine() const; QSize size() const; @@ -81,7 +81,7 @@ protected: { return (screen->deviceHeight() * 1000) / screen->physicalHeight(); } - +protected: IDirectFBSurface *dfbSurface; QImage *lockedImage; QDirectFBScreen *screen; -- cgit v0.12 From 4c948161f80ddefb568c50f2a2a17612f25f646e Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 29 Jul 2009 09:35:03 +1000 Subject: Fixed failure of tst_q3socket. Make the test use network-settings.h correctly. --- tests/auto/q3socket/tst_qsocket.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/auto/q3socket/tst_qsocket.cpp b/tests/auto/q3socket/tst_qsocket.cpp index b07fa2f..854cc75 100644 --- a/tests/auto/q3socket/tst_qsocket.cpp +++ b/tests/auto/q3socket/tst_qsocket.cpp @@ -124,8 +124,10 @@ void tst_Q3Socket::peerAddress_data() QTest::addColumn("peerClosesConnection"); QTest::addColumn("peerAddr"); - QTest::newRow( "echo" ) << QString("qt-test-server.troll.no") << (uint)7 << false << QString("10.3.3.69"); - QTest::newRow( "daytime" ) << QString("qt-test-server.troll.no") << (uint)13 << true << QString("10.3.3.69"); + QTest::newRow( "echo" ) << QtNetworkSettings::serverLocalName() << (uint)7 << false + << QtNetworkSettings::serverIP().toString(); + QTest::newRow( "daytime" ) << QtNetworkSettings::serverLocalName() << (uint)13 << true + << QtNetworkSettings::serverIP().toString(); } void tst_Q3Socket::peerAddress() @@ -191,7 +193,7 @@ void tst_Q3Socket::emitConnectionRefused() { Q3Socket sock; connect( &sock, SIGNAL(error(int)), SLOT(emitConnectionRefused_error(int)) ); - sock.connectToHost( "ares.troll.no", 12331 ); + sock.connectToHost( QtNetworkSettings::serverLocalName(), 12331 ); emitConnectionRefused_errorReceived = false; QTestEventLoop::instance().enterLoop( 30 ); @@ -225,8 +227,8 @@ void tst_Q3Socket::connectionAttempts_data() QTest::addColumn("port"); QTest::addColumn("expectedResult"); - QTest::newRow("fluke port 80") << QString("qt-test-server.troll.no") << 80 << true; - QTest::newRow("fluke port 79") << QString("qt-test-server.troll.no") << 79 << false; + QTest::newRow("fluke port 80") << QtNetworkSettings::serverLocalName() << 80 << true; + QTest::newRow("fluke port 79") << QtNetworkSettings::serverLocalName() << 79 << false; } void tst_Q3Socket::connectionAttempts() @@ -266,7 +268,7 @@ void tst_Q3Socket::canReadLine() connect(&socket, SIGNAL(connected()), &loop, SLOT(quit())); // timeout error will fail in #238 connect(&socket, SIGNAL(error(int)), &loop, SLOT(quit())); - socket.connectToHost("qt-test-server.troll.no", 143); + socket.connectToHost(QtNetworkSettings::serverLocalName(), 143); loop.exec(); -- cgit v0.12 From 46a78065b4f971d58f91b7eddb7487529ce153c5 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 29 Jul 2009 09:44:27 +1000 Subject: Fixed failure of tst_q3urloperator. Make test use network-settings.h correctly. --- tests/auto/q3urloperator/tst_q3urloperator.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/auto/q3urloperator/tst_q3urloperator.cpp b/tests/auto/q3urloperator/tst_q3urloperator.cpp index f1e1059..a9e5096 100644 --- a/tests/auto/q3urloperator/tst_q3urloperator.cpp +++ b/tests/auto/q3urloperator/tst_q3urloperator.cpp @@ -55,6 +55,8 @@ #include #include +#include "../network-settings.h" + //TESTED_CLASS= //TESTED_FILES= @@ -150,7 +152,7 @@ void tst_Q3UrlOperator::initTestCase() // prepare: make sure that there is a unique directory for FTP upload // testing (to avoid parallel executed tests interfere with each other) - ftpQtestUpload = "ftp://qt-test-server.troll.no/"; + ftpQtestUpload = QString("ftp://%1/").arg(QtNetworkSettings::serverLocalName()); QString dir = QString( "qtest/upload/%1" ).arg( (ulong)this ); Q3UrlOperator opMkdir( ftpQtestUpload ); @@ -218,8 +220,8 @@ void tst_Q3UrlOperator::cleanup() void tst_Q3UrlOperator::copy_data() { - const QString ftpQtest( "ftp://qt-test-server.troll.no/qtest" ); - const QString httpQtest( "http://qt-test-server.troll.no/qtest" ); + const QString ftpQtest( QString("ftp://%1/qtest").arg(QtNetworkSettings::serverLocalName()) ); + const QString httpQtest( QString("http://%1/qtest").arg(QtNetworkSettings::serverLocalName()) ); // argument for the constructor QTest::addColumn("url"); @@ -339,8 +341,8 @@ void tst_Q3UrlOperator::slotFinished_copy( Q3NetworkOperation *op ) void tst_Q3UrlOperator::put_data() { - const QString httpQtest( "http://qt-test-server.troll.no/qtest/cgi-bin" ); - const QString httpQtestGet( "http://qt-test-server.troll.no/qtest/cgi-bin/retrieve_testfile.cgi" ); + const QString httpQtest( QString("http://%1/qtest/cgi-bin").arg(QtNetworkSettings::serverLocalName()) ); + const QString httpQtestGet( QString("http://%1/qtest/cgi-bin/retrieve_testfile.cgi").arg(QtNetworkSettings::serverLocalName()) ); QByteArray putData_1( 5 ); putData_1[0] = 'a'; -- cgit v0.12 From e0238a6d8a6a567dbdf598983dedbe4a58a9ef2d Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 29 Jul 2009 09:49:26 +1000 Subject: Fixed compile of tst_qitemeditorfactory. --- tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp b/tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp index d9a7d56..e235ff5 100644 --- a/tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp +++ b/tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp @@ -59,13 +59,13 @@ void tst_QItemEditorFactory::createEditor() QCOMPARE(w->metaObject()->className(), "QExpandingLineEdit"); } -void tst_QItemEditorFactory::createCustomEditor() +//we make it inherit from QObject so that we can use QPointer +class MyEditor : public QObject, public QStandardItemEditorCreator { - //we make it inherit from QObject so that we can use QPointer - class MyEditor : public QObject, public QStandardItemEditorCreator - { - }; +}; +void tst_QItemEditorFactory::createCustomEditor() +{ QPointer creator = new MyEditor; QPointer creator2 = new MyEditor; -- cgit v0.12 From af489fb5551265da1f5e34deaba627a36e5c560e Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 29 Jul 2009 11:23:37 +1000 Subject: Skip uic3 test when qt3support is disabled. --- tests/auto/uic3/uic3.pro | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/auto/uic3/uic3.pro b/tests/auto/uic3/uic3.pro index 520f95a..72a1304 100644 --- a/tests/auto/uic3/uic3.pro +++ b/tests/auto/uic3/uic3.pro @@ -6,3 +6,6 @@ TARGET = tst_uic3 # This test is not run on wince (I think) DEFINES += SRCDIR=\\\"$$PWD\\\" + +requires(contains(QT_CONFIG,qt3support)) + -- cgit v0.12 From 069be9309b721541b4087614b6ce7b029cf3dcb8 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 29 Jul 2009 12:00:53 +1000 Subject: Fixed failure of tst_moc. os9-newlines.h's lack of newline at end of file is significant. --- tests/auto/moc/os9-newlines.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/moc/os9-newlines.h b/tests/auto/moc/os9-newlines.h index fb9bbe4..85fa671 100644 --- a/tests/auto/moc/os9-newlines.h +++ b/tests/auto/moc/os9-newlines.h @@ -1 +1 @@ -/**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** 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 either Technology Preview License Agreement or the ** Beta Release License Agreement. ** ** 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.0, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ #include class Os9Newlines : public QObject { Q_OBJECT public Q_SLOTS: inline void testSlot() {} }; +/**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** 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 either Technology Preview License Agreement or the ** Beta Release License Agreement. ** ** 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.0, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ #include class Os9Newlines : public QObject { Q_OBJECT public Q_SLOTS: inline void testSlot() {} }; \ No newline at end of file -- cgit v0.12 From 5f0374c5754e872aaaabef44bd18f0c3bee8d586 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 29 Jul 2009 13:52:12 +1000 Subject: Fixed failure of tst_qmake::simple_app_shadowbuild. Test needs a placeholder file to make sure its build directory exists. --- tests/auto/qmake/testdata/simple_app_build/README | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/auto/qmake/testdata/simple_app_build/README diff --git a/tests/auto/qmake/testdata/simple_app_build/README b/tests/auto/qmake/testdata/simple_app_build/README new file mode 100644 index 0000000..81dc596 --- /dev/null +++ b/tests/auto/qmake/testdata/simple_app_build/README @@ -0,0 +1 @@ +Placeholder file to ensure this directory exists -- cgit v0.12 From 461518b2429bb1ab4b356f3326b63db98d19e11b Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 29 Jul 2009 13:59:41 +1000 Subject: Disable benchlibtickcounter test by default. This test depends on some low-level features of the CPU and the OS scheduler which seem impractical to automatically verify independently of the test. So turn it off to stop its intermittent failures in our test farm. --- tests/auto/selftests/tst_selftests.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/auto/selftests/tst_selftests.cpp b/tests/auto/selftests/tst_selftests.cpp index 30fe853..be8fcf6 100644 --- a/tests/auto/selftests/tst_selftests.cpp +++ b/tests/auto/selftests/tst_selftests.cpp @@ -180,9 +180,10 @@ void tst_Selftests::runSubTest_data() QTest::newRow("benchliboptions") << "benchliboptions" << QStringList("-eventcounter"); QTest::newRow("benchlibwalltime") << "benchlibwalltime" << QStringList(); - //### QWS tests are currently run on a virtual machine, where ticks are not - //### monotonously increasing -#if defined(HAVE_TICK_COUNTER) && !defined(Q_WS_QWS) + //### This test is affected by the speed of the CPU and whether the tick counter is + //### monotonically increasing. It won't work on some machines so leave it off by default. + //### Feel free to uncomment for your own testing. +#if 0 QTest::newRow("benchlibtickcounter") << "benchlibtickcounter" << QStringList("-tickcounter"); #endif -- cgit v0.12 From 7ac907ca7cfaac6698bc044e60ffd4d5d4a65d42 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 29 Jul 2009 08:18:35 +0200 Subject: Comment one of my changes from yesterday Task-number: 258445 --- src/gui/dialogs/qcolordialog_mac.mm | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/gui/dialogs/qcolordialog_mac.mm b/src/gui/dialogs/qcolordialog_mac.mm index 3770012..1ac225d 100644 --- a/src/gui/dialogs/qcolordialog_mac.mm +++ b/src/gui/dialogs/qcolordialog_mac.mm @@ -283,14 +283,17 @@ QT_USE_NAMESPACE - (void)finishOffWithCode:(NSInteger)code { - // Finish the QColorDialog as well. But since a call to accept or reject will - // close down the QEventLoop found in QDialog, we need to make sure that the - // current thread has exited the native dialogs modal session/run loop first. - // We ensure this by posting the call: mResultCode = code; if (mDialogIsExecuting) { + // We stop the current modal event loop. The control + // will then return inside -(void)exec below. + // It's important that the modal event loop is stopped before + // we accept/reject QColorDialog, since QColorDialog has its + // own event loop that needs to be stopped last. [NSApp stopModalWithCode:code]; } else { + // Since we are not in a modal event loop, we can safely close + // down QColorDialog if (mResultCode == NSCancelButton) mPriv->colorDialog()->reject(); else -- cgit v0.12 From d63f08018b0952eb917e090f214a1dbe24e2a767 Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Wed, 29 Jul 2009 17:17:12 +0200 Subject: Doc - Renamed the cursor's images to illustrate splitV and splitH properly Task: 258895 Reviewed-By: Jens Bache-Wiig --- doc/src/images/cursor-hsplit.png | Bin 161 -> 155 bytes doc/src/images/cursor-vsplit.png | Bin 155 -> 161 bytes src/gui/kernel/qcursor.cpp | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/images/cursor-hsplit.png b/doc/src/images/cursor-hsplit.png index 1beda25..a5667e3 100644 Binary files a/doc/src/images/cursor-hsplit.png and b/doc/src/images/cursor-hsplit.png differ diff --git a/doc/src/images/cursor-vsplit.png b/doc/src/images/cursor-vsplit.png index a5667e3..1beda25 100644 Binary files a/doc/src/images/cursor-vsplit.png and b/doc/src/images/cursor-vsplit.png differ diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp index 6fb5f5a..c48a781 100644 --- a/src/gui/kernel/qcursor.cpp +++ b/src/gui/kernel/qcursor.cpp @@ -127,11 +127,11 @@ QT_BEGIN_NAMESPACE \o Qt::SizeAllCursor \o \c size_all \row \o \inlineimage cursor-busy.png \o Qt::BusyCursor \o \c left_ptr_watch - \o \inlineimage cursor-hsplit.png + \o \inlineimage cursor-vsplit.png \o Qt::SplitVCursor \o \c split_v \row \o \inlineimage cursor-forbidden.png \o Qt::ForbiddenCursor \o \c forbidden - \o \inlineimage cursor-vsplit.png + \o \inlineimage cursor-hsplit.png \o Qt::SplitHCursor \o \c split_h \row \o \inlineimage cursor-hand.png \o Qt::PointingHandCursor \o \c pointing_hand -- cgit v0.12 From 15ccaa0995da2061009d269fa875e8601da1a3c8 Mon Sep 17 00:00:00 2001 From: Bill King Date: Thu, 30 Jul 2009 11:18:59 +1000 Subject: Fixes hack around show queries not allowed to be prepared. Mysql queries other than select can't be prepared, otherwise they fail to return the necessary meta-information to enable them to be seen as returning data under certain versions of mysql. This fixes the hack to work correctly until we stop preparing queries automagically. --- src/sql/drivers/mysql/qsql_mysql.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp index 8f377bd..3295a41 100644 --- a/src/sql/drivers/mysql/qsql_mysql.cpp +++ b/src/sql/drivers/mysql/qsql_mysql.cpp @@ -1336,8 +1336,8 @@ QSqlIndex QMYSQLDriver::primaryIndex(const QString& tablename) const if (!isOpen()) return idx; - prepQ = d->preparedQuerys; - d->preparedQuerys = false; + prepQ = d->preparedQuerysEnabled; + d->preparedQuerysEnabled = false; QSqlQuery i(createResult()); QString stmt(QLatin1String("show index from %1;")); @@ -1351,7 +1351,7 @@ QSqlIndex QMYSQLDriver::primaryIndex(const QString& tablename) const } } - d->preparedQuerys = prepQ; + d->preparedQuerysEnabled = prepQ; return idx; } -- cgit v0.12 From f752633b878840634ca374fb9c1e8755aa1fd886 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 29 Jul 2009 15:48:46 +0200 Subject: Unable to change focus between two line edits on mac This is because we try to decide whether the window cocoa tells us to be active should be active, and if we desagree, we do nothing. The result is that Qt and Cocoa ends up in different states. I decided to remove a lot of the logic that went on in this case, and the resons is: 1. By checking the callplaces to onApplicationWindowChangedActivation, we know that we always have a valid widget pointer, and we know that the widget always is a window (otherwise Cocoa would never tell us that the widget got active). 2. We can never end up doing nothing in this response. The best we can do is to follow what Cocoa tells us. If this turns out to break something, it would probably be better to check why we get an activation call in the first place for a window that should not be activated (e.g. is canBecomeKeyWindow set correctly?) Task: 253610 RevBy: msorvig --- src/gui/kernel/qapplication_mac.mm | 49 ++++++++++---------------------------- 1 file changed, 12 insertions(+), 37 deletions(-) diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index 0d86c8e..be23949 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -1481,6 +1481,7 @@ QWidget *QApplicationPrivate::tryModalHelper_sys(QWidget *top) return top; } +#ifndef QT_MAC_USE_COCOA static bool qt_try_modal(QWidget *widget, EventRef event) { QWidget * top = 0; @@ -1514,6 +1515,7 @@ static bool qt_try_modal(QWidget *widget, EventRef event) #endif return !block_event; } +#endif OSStatus QApplicationPrivate::tabletProximityCallback(EventHandlerCallRef, EventRef carbonEvent, void *) @@ -2894,52 +2896,25 @@ bool QApplicationPrivate::canQuit() #endif } -void onApplicationWindowChangedActivation( QWidget*widget, bool activated ) +void onApplicationWindowChangedActivation(QWidget *widget, bool activated) { #if QT_MAC_USE_COCOA - QApplication *app = qApp; + if (!widget) + return; - if ( activated ) - { - if (QApplicationPrivate::app_style) - { + if (activated) { + if (QApplicationPrivate::app_style) { QEvent ev(QEvent::Style); qt_sendSpontaneousEvent(QApplicationPrivate::app_style, &ev); } - - if (widget && app_do_modal && !qt_try_modal(widget, NULL)) - return; - - if (widget && widget->window()->isVisible()) - { - QWidget *tlw = widget->window(); - - if (tlw->isWindow() && !(tlw->windowType() == Qt::Popup) - && !qt_mac_is_macdrawer(tlw) - && (!tlw->parentWidget() || tlw->isModal() || !(tlw->windowType() == Qt::Tool))) { - bool just_send_event = false; -#if 0 - WindowActivationScope scope; - if ( GetWindowActivationScope((OSWindowRef)wid, &scope) == noErr && - scope == kWindowActivationScopeIndependent) - { - if ( GetFrontWindowOfClass(kAllWindowClasses, true) != wid ) - just_send_event = true; - } -#endif - if (just_send_event) { - QEvent e(QEvent::WindowActivate); - qt_sendSpontaneousEvent(widget, &e); - } else { - app->setActiveWindow(tlw); - } - } - } + qApp->setActiveWindow(widget); } else { // deactivated - if (widget && QApplicationPrivate::active_window == widget) - app->setActiveWindow(0); + if (QApplicationPrivate::active_window == widget) + qApp->setActiveWindow(0); } + QMenuBar::macUpdateMenuBar(); + #else Q_UNUSED(widget); Q_UNUSED(activated); -- cgit v0.12 From 1fa620be2794b46a9b5d867ae6b2d7fa844b610c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20S=C3=B8rvig?= Date: Thu, 30 Jul 2009 13:41:34 +0200 Subject: Mac: Fix crash in QCoreTextFontEngineMulti when disabling font kerning. CFDictionaryAddValue expects a CFNumberRef, not a pointer-to-CFNumberRef. Reviewed-by: TrustMe --- src/gui/text/qfontengine_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 72e5175..b16fd7e 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -156,7 +156,7 @@ QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, con if (!kerning) { float zero = 0.0; QCFType noKern = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &zero); - CFDictionaryAddValue(attributeDict, kCTKernAttributeName, &noKern); + CFDictionaryAddValue(attributeDict, kCTKernAttributeName, noKern); } QCoreTextFontEngine *fe = new QCoreTextFontEngine(ctfont, fontDef, this); -- cgit v0.12 From e1851f3246fe307830173573fbbcf013e8a1b1e8 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 30 Jul 2009 14:11:07 +0200 Subject: Remove mem leak / warning in the cocoaport Remove mem leak / warning in the cocoaport Reviewed-by: msorvig --- src/gui/kernel/qwidget_mac.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 0a31a28..8913c89 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -4674,6 +4674,7 @@ void QWidgetPrivate::setModal_sys() OSWindowRef windowRef = qt_mac_window_for(q); #ifdef QT_MAC_USE_COCOA + QMacCocoaAutoReleasePool pool; bool alreadySheet = [windowRef styleMask] & NSDocModalWindowMask; if (windowParent && q->windowModality() == Qt::WindowModal){ -- cgit v0.12 From efc7c605c5f561a75a718f8186e470bd24a18b4e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 30 Jul 2009 14:35:07 +0200 Subject: Autotest: add a newline after the user program headers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the user forgot to end their headers with a newline, the compilation would fail because the next line is #include . Reviewed-by: Jesper Thomschütz --- tests/auto/qsharedpointer/externaltests.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/qsharedpointer/externaltests.cpp b/tests/auto/qsharedpointer/externaltests.cpp index d1618d1..6542350 100644 --- a/tests/auto/qsharedpointer/externaltests.cpp +++ b/tests/auto/qsharedpointer/externaltests.cpp @@ -324,6 +324,7 @@ namespace QTest { sourceCode.reserve(8192); sourceCode += programHeader; + sourceCode += '\n'; // Add Qt header includes if (qtModules & QExternalTest::QtCore) -- cgit v0.12 From 9cbaefd4121ee082c402d5243f7ccb5e9d89456c Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 29 Jul 2009 15:34:31 +0200 Subject: Allow maximize button on the titlebar for a fixed size window On Windows we will add maximize button to the titlebar even if the window has a fixed size if the user explicitely asked for it by setting Qt::CustomizeWindowHint | Qt::WindowMaximizeButtonHint. Task-number: 250188 Reviewed-by: Leonardo Sobral Cunha --- src/gui/kernel/qwidget_win.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp index f7ff2d0..13658fb 100644 --- a/src/gui/kernel/qwidget_win.cpp +++ b/src/gui/kernel/qwidget_win.cpp @@ -1558,6 +1558,11 @@ bool QWidgetPrivate::shouldShowMaximizeButton() { if (data.window_flags & Qt::MSWindowsFixedSizeDialogHint) return false; + // if the user explicitely asked for the maximize button, we try to add + // it even if the window has fixed size. + if (data.window_flags & Qt::CustomizeWindowHint && + data.window_flags & Qt::WindowMaximizeButtonHint) + return true; if (extra) { if ((extra->maxw && extra->maxw != QWIDGETSIZE_MAX && extra->maxw != QLAYOUTSIZE_MAX) || (extra->maxh && extra->maxh != QWIDGETSIZE_MAX && extra->maxh != QLAYOUTSIZE_MAX)) -- cgit v0.12 From 1dbd205e304d0f0819f558591def249bdceac9fa Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Thu, 30 Jul 2009 17:37:30 +0200 Subject: Coverty warnings --. This switch was missing a break. Reviewed-by:TrustMe --- src/gui/dialogs/qfilesystemmodel.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/dialogs/qfilesystemmodel.cpp b/src/gui/dialogs/qfilesystemmodel.cpp index 4646012..73f2db5 100644 --- a/src/gui/dialogs/qfilesystemmodel.cpp +++ b/src/gui/dialogs/qfilesystemmodel.cpp @@ -880,6 +880,7 @@ QVariant QFileSystemModel::headerData(int section, Qt::Orientation orientation, pixmap.setAlphaChannel(pixmap.createAlphaMask()); return pixmap; } + break; case Qt::TextAlignmentRole: return Qt::AlignLeft; } -- cgit v0.12 From 4066cc8a2f2b824d1047913d863b4d3261dd2479 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 31 Jul 2009 09:09:47 +0200 Subject: Show open directory dialog for new gesture example RevBy: denis --- examples/gestures/imageviewer/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/gestures/imageviewer/main.cpp b/examples/gestures/imageviewer/main.cpp index 6bda418..cd1928b 100644 --- a/examples/gestures/imageviewer/main.cpp +++ b/examples/gestures/imageviewer/main.cpp @@ -81,6 +81,9 @@ int main(int argc, char *argv[]) if (QApplication::arguments().size() > 1) w.openDirectory(QApplication::arguments().at(1)); + else + w.openDirectory(QFileDialog::getExistingDirectory(0, "Select image folder")); + return app.exec(); } -- cgit v0.12 From 9c45d4daab2196b6418e7fb2be70f9e6d7a57799 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 31 Jul 2009 09:58:21 +0200 Subject: Cocoa with namespace breaks the build Added the needed macros around the classnames the way it should be done. Reviewed-by: Prasanth --- src/gui/kernel/qcocoaview_mac.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index e3ec30a..2b83df9 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -324,7 +324,7 @@ extern "C" { return NSDragOperationNone; } else { // save the mouse position, used by draggingExited handler. - DnDParams *dndParams = [QCocoaView currentMouseEvent]; + DnDParams *dndParams = [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]; dndParams->activeDragEnterPos = windowPoint; // send a drag move event immediately after a drag enter event (as per documentation). QDragMoveEvent qDMEvent(posDrag, qtAllowed, mimeData, QApplication::mouseButtons(), modifiers); @@ -403,7 +403,7 @@ extern "C" { dragEnterSequence = -1; if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) { // try sending the leave event to the last view which accepted drag enter. - DnDParams *dndParams = [QCocoaView currentMouseEvent]; + DnDParams *dndParams = [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]; NSView *candidateView = [[[self window] contentView] hitTest:dndParams->activeDragEnterPos]; if (candidateView && candidateView != self) return [candidateView draggingExited:sender]; -- cgit v0.12 From 65f6a08ba7d26405a9de683ea0806b400ba8b26d Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 31 Jul 2009 10:17:20 +0200 Subject: test that activation and this-object can be inherited from parent context --- tests/auto/qscriptcontext/tst_qscriptcontext.cpp | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp index d96006d..3c9ea4c9 100644 --- a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp +++ b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp @@ -72,6 +72,7 @@ private slots: void scopeChain(); void pushAndPopScope(); void getSetActivationObject(); + void inheritActivationAndThisObject(); void toString(); }; @@ -689,6 +690,35 @@ void tst_QScriptContext::getSetActivationObject() } } +static QScriptValue myEval(QScriptContext *ctx, QScriptEngine *eng) +{ + QString code = ctx->argument(0).toString(); + ctx->setActivationObject(ctx->parentContext()->activationObject()); + ctx->setThisObject(ctx->parentContext()->thisObject()); + return eng->evaluate(code); +} + +void tst_QScriptContext::inheritActivationAndThisObject() +{ + QScriptEngine eng; + eng.globalObject().setProperty("myEval", eng.newFunction(myEval)); + { + QScriptValue ret = eng.evaluate("var a = 123; myEval('a')"); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toInt32(), 123); + } + { + QScriptValue ret = eng.evaluate("(function() { return myEval('this'); }).call(Number)"); + QVERIFY(ret.isFunction()); + QVERIFY(ret.equals(eng.globalObject().property("Number"))); + } + { + QScriptValue ret = eng.evaluate("(function(a) { return myEval('a'); })(123)"); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toInt32(), 123); + } +} + static QScriptValue parentContextToString(QScriptContext *ctx, QScriptEngine *) { return ctx->parentContext()->toString(); -- cgit v0.12 From 919ac1291c6e7d163b58679eae691f866b40f71b Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Thu, 30 Jul 2009 14:09:22 +0200 Subject: Compile on HP-UXi There is no monotonic clock support on HP-UXi at all, and the _POSIX_MONOTONIC_CLOCK macro is not defined at all (not even to -1). We handle this in the event dispatcher, but not in qcore_unix.cpp. Since the monotonic clock time code has moved, the define of _POSIX_MONOTONIC_CLOCK to -1 should also move. Reviewed-by: thiago --- src/corelib/kernel/qcore_unix_p.h | 4 ++++ src/corelib/kernel/qeventdispatcher_unix_p.h | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index dceb73a..69ebb05 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -323,6 +323,10 @@ static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options) #endif // Q_OS_VXWORKS +#if !defined(_POSIX_MONOTONIC_CLOCK) +# define _POSIX_MONOTONIC_CLOCK -1 +#endif + bool qt_gettime_is_monotonic(); timeval qt_gettime(); Q_CORE_EXPORT int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h index 9c67c70..5e016d3 100644 --- a/src/corelib/kernel/qeventdispatcher_unix_p.h +++ b/src/corelib/kernel/qeventdispatcher_unix_p.h @@ -69,9 +69,6 @@ #endif QT_BEGIN_NAMESPACE -#if !defined(_POSIX_MONOTONIC_CLOCK) -# define _POSIX_MONOTONIC_CLOCK -1 -#endif // internal timer info struct QTimerInfo { -- cgit v0.12 From 18fbfdf0f774198e2e1277e064cc3a8eb9dbb29d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 31 Jul 2009 10:30:44 +0200 Subject: Fix compilation with xlC 7: operands to ?: must match. See 3ae2cab9c8bd1790a00da2755ac036143a3a35f4 for another similar fix. Reviewed-by: Trust Me --- tools/linguist/shared/po.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/linguist/shared/po.cpp b/tools/linguist/shared/po.cpp index 796d012..a6795cb 100644 --- a/tools/linguist/shared/po.cpp +++ b/tools/linguist/shared/po.cpp @@ -359,7 +359,7 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) const QChar quote = QLatin1Char('"'); const QChar newline = QLatin1Char('\n'); QTextStream in(&dev); - in.setCodec(cd.m_codecForSource.isEmpty() ? "UTF-8" : cd.m_codecForSource); + in.setCodec(cd.m_codecForSource.isEmpty() ? QByteArray("UTF-8") : cd.m_codecForSource); bool error = false; // format of a .po file entry: @@ -555,7 +555,7 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd) { bool ok = true; QTextStream out(&dev); - out.setCodec(cd.m_outputCodec.isEmpty() ? "UTF-8" : cd.m_outputCodec); + out.setCodec(cd.m_outputCodec.isEmpty() ? QByteArray("UTF-8") : cd.m_outputCodec); bool first = true; if (translator.messages().isEmpty() || !translator.messages().first().sourceText().isEmpty()) { -- cgit v0.12 From 1a7286691a74016a0577073275fc462aea2fe1bc Mon Sep 17 00:00:00 2001 From: Geir Vattekar Date: Fri, 31 Jul 2009 11:07:13 +0200 Subject: Doc: Fixed a snippet bug in QFileInfo Task-number: 258371 Reviewed-by: Trust Me --- doc/src/snippets/code/src_corelib_io_qfileinfo.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/src/snippets/code/src_corelib_io_qfileinfo.cpp b/doc/src/snippets/code/src_corelib_io_qfileinfo.cpp index 2ab15ee..89b4f33 100644 --- a/doc/src/snippets/code/src_corelib_io_qfileinfo.cpp +++ b/doc/src/snippets/code/src_corelib_io_qfileinfo.cpp @@ -13,9 +13,9 @@ info1.size(); // returns 56201 info1.symLinkTarget(); // returns "/opt/pretty++/bin/untabify" QFileInfo info2(info1.symLinkTarget()); -info1.isSymLink(); // returns false -info1.absoluteFilePath(); // returns "/opt/pretty++/bin/untabify" -info1.size(); // returns 56201 +info2.isSymLink(); // returns false +info2.absoluteFilePath(); // returns "/opt/pretty++/bin/untabify" +info2.size(); // returns 56201 #endif //! [0] -- cgit v0.12 From 8a0a59e6776e1384f884e0f6e7ec6fe10f3be054 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 31 Jul 2009 11:28:34 +0200 Subject: remove const from QSignalEvent::sender* QObject::sender() does not return const QObject*, so neither should this API; it just forces you to const_cast for no good reason. --- src/corelib/statemachine/qsignalevent.h | 6 +++--- src/corelib/statemachine/qstatemachine.cpp | 4 ++-- src/corelib/statemachine/qstatemachine_p.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/corelib/statemachine/qsignalevent.h b/src/corelib/statemachine/qsignalevent.h index c09c5a3..b7ca61f 100644 --- a/src/corelib/statemachine/qsignalevent.h +++ b/src/corelib/statemachine/qsignalevent.h @@ -58,16 +58,16 @@ QT_MODULE(Core) class Q_CORE_EXPORT QSignalEvent : public QEvent { public: - QSignalEvent(const QObject *sender, int signalIndex, + QSignalEvent(QObject *sender, int signalIndex, const QList &arguments); ~QSignalEvent(); - inline const QObject *sender() const { return m_sender; } + inline QObject *sender() const { return m_sender; } inline int signalIndex() const { return m_signalIndex; } inline QList arguments() const { return m_arguments; } private: - const QObject *m_sender; + QObject *m_sender; int m_signalIndex; QList m_arguments; }; diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index a02480b..d89ad98 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -1446,7 +1446,7 @@ void QStateMachinePrivate::unregisterEventTransition(QEventTransition *transitio } #endif -void QStateMachinePrivate::handleTransitionSignal(const QObject *sender, int signalIndex, +void QStateMachinePrivate::handleTransitionSignal(QObject *sender, int signalIndex, void **argv) { Q_ASSERT(connections[sender].at(signalIndex) != 0); @@ -2026,7 +2026,7 @@ QSignalEventGenerator::QSignalEventGenerator(QStateMachine *parent) Constructs a new QSignalEvent object with the given \a sender, \a signalIndex and \a arguments. */ -QSignalEvent::QSignalEvent(const QObject *sender, int signalIndex, +QSignalEvent::QSignalEvent(QObject *sender, int signalIndex, const QList &arguments) : QEvent(QEvent::Signal), m_sender(sender), m_signalIndex(signalIndex), m_arguments(arguments) diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index cae21aa..590cffe 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -147,7 +147,7 @@ public: #endif void unregisterTransition(QAbstractTransition *transition); void unregisterAllTransitions(); - void handleTransitionSignal(const QObject *sender, int signalIndex, + void handleTransitionSignal(QObject *sender, int signalIndex, void **args); void scheduleProcess(); -- cgit v0.12 From f12085f8a00957ed17c33e9d75e51dc74a3d2115 Mon Sep 17 00:00:00 2001 From: kh Date: Fri, 31 Jul 2009 12:02:46 +0200 Subject: Fix internal documentation after QUrl change. Reviewed-by: kh --- tools/assistant/tools/assistant/assistant.qch | Bin 368640 -> 368640 bytes tools/assistant/tools/assistant/doc/assistant.qhp | 2 +- tools/assistant/tools/assistant/helpviewer.cpp | 4 ++-- tools/assistant/tools/assistant/main.cpp | 2 +- tools/assistant/tools/assistant/mainwindow.cpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/assistant/tools/assistant/assistant.qch b/tools/assistant/tools/assistant/assistant.qch index 99687ed..3e66bd9 100644 Binary files a/tools/assistant/tools/assistant/assistant.qch and b/tools/assistant/tools/assistant/assistant.qch differ diff --git a/tools/assistant/tools/assistant/doc/assistant.qhp b/tools/assistant/tools/assistant/doc/assistant.qhp index 7a26101..7ea4cdd 100644 --- a/tools/assistant/tools/assistant/doc/assistant.qhp +++ b/tools/assistant/tools/assistant/doc/assistant.qhp @@ -1,7 +1,7 @@ assistant - com.trolltech.com.assistantinternal_1.0.0 + com.trolltech.com.assistantinternal-1.0.0 assistant.html diff --git a/tools/assistant/tools/assistant/helpviewer.cpp b/tools/assistant/tools/assistant/helpviewer.cpp index 6799db3..5422bf46 100644 --- a/tools/assistant/tools/assistant/helpviewer.cpp +++ b/tools/assistant/tools/assistant/helpviewer.cpp @@ -306,7 +306,7 @@ void HelpViewer::setSource(const QUrl &url) loadFinished = false; if (url.toString() == QLatin1String("help")) { load(QUrl(QLatin1String("qthelp://com.trolltech.com." - "assistantinternal_1.0.0/assistant/assistant.html"))); + "assistantinternal-1.0.0/assistant/assistant.html"))); } else { load(url); } @@ -425,7 +425,7 @@ void HelpViewer::setSource(const QUrl &url) if (help) { QTextBrowser::setSource(QUrl(QLatin1String("qthelp://com.trolltech.com." - "assistantinternal_1.0.0/assistant/assistant.html"))); + "assistantinternal-1.0.0/assistant/assistant.html"))); } else { QTextBrowser::setSource(url); setHtml(tr("Error 404...


" diff --git a/tools/assistant/tools/assistant/main.cpp b/tools/assistant/tools/assistant/main.cpp index 05355d9..a0a5a0d 100644 --- a/tools/assistant/tools/assistant/main.cpp +++ b/tools/assistant/tools/assistant/main.cpp @@ -306,7 +306,7 @@ int main(int argc, char *argv[]) } } - QLatin1String intern("com.trolltech.com.assistantinternal_"); + QLatin1String intern("com.trolltech.com.assistantinternal-"); foreach (const QString &doc, userDocs) { if (!callerDocs.contains(doc) && !doc.startsWith(intern)) user.unregisterDocumentation(doc); diff --git a/tools/assistant/tools/assistant/mainwindow.cpp b/tools/assistant/tools/assistant/mainwindow.cpp index 7926020..0c1723c 100644 --- a/tools/assistant/tools/assistant/mainwindow.cpp +++ b/tools/assistant/tools/assistant/mainwindow.cpp @@ -274,7 +274,7 @@ bool MainWindow::initHelpDB() return false; bool assistantInternalDocRegistered = false; - QString intern(QLatin1String("com.trolltech.com.assistantinternal_")); + QString intern(QLatin1String("com.trolltech.com.assistantinternal-")); foreach (const QString &ns, m_helpEngine->registeredDocumentations()) { if (ns.startsWith(intern)) { intern = ns; -- cgit v0.12 From fbbd7f9a27216dc66a77a064179a4775ce9fb91e Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 31 Jul 2009 13:42:08 +0200 Subject: add private goToState() function to state machine Needed for Declarative UI integration. --- src/corelib/statemachine/qstatemachine.cpp | 96 ++++++++++++++++++++++++-- src/corelib/statemachine/qstatemachine_p.h | 8 ++- tests/auto/qstatemachine/tst_qstatemachine.cpp | 41 +++++++++++ 3 files changed, 138 insertions(+), 7 deletions(-) diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index d89ad98..5aa5917 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -205,6 +205,7 @@ This is QStateMachinePrivate::QStateMachinePrivate() { state = NotRunning; + _startState = 0; processing = false; processingScheduled = false; stop = false; @@ -1146,6 +1147,20 @@ protected: } // namespace +QState *QStateMachinePrivate::startState() +{ + Q_Q(QStateMachine); + if (_startState == 0) + _startState = new StartState(q); + return _startState; +} + +void QStateMachinePrivate::removeStartState() +{ + delete _startState; + _startState = 0; +} + void QStateMachinePrivate::_q_start() { Q_Q(QStateMachine); @@ -1165,11 +1180,19 @@ void QStateMachinePrivate::_q_start() processingScheduled = true; // we call _q_process() below emit q->started(); - StartState *start = new StartState(rootState()); - QAbstractTransition *initialTransition = new InitialTransition(initial); - start->addTransition(initialTransition); - QList transitions; - transitions.append(initialTransition); + QState *start = startState(); + Q_ASSERT(start != 0); + + QList transitions = QStatePrivate::get(start)->transitions(); + + // If a transition has already been added, then we skip this step, as the + // initial transition in that case has been overridden. + if (transitions.isEmpty()) { + QAbstractTransition *initialTransition = new InitialTransition(initial); + start->addTransition(initialTransition); + transitions.append(initialTransition); + } + QEvent nullEvent(QEvent::None); executeTransitionContent(&nullEvent, transitions); QList enteredStates = enterStates(&nullEvent, transitions); @@ -1177,7 +1200,7 @@ void QStateMachinePrivate::_q_start() applyProperties(transitions, QList() << start, enteredStates); #endif - delete start; + removeStartState(); #ifdef QSTATEMACHINE_DEBUG qDebug() << q << ": initial configuration:" << configuration; @@ -1277,6 +1300,67 @@ void QStateMachinePrivate::scheduleProcess() QMetaObject::invokeMethod(q_func(), "_q_process", Qt::QueuedConnection); } +namespace { + +class GoToStateTransition : public QAbstractTransition +{ +public: + GoToStateTransition(QAbstractState *target) + : QAbstractTransition(QList() << target) {} +protected: + void onTransition(QEvent *) { deleteLater(); } + bool eventTest(QEvent *) { return true; } +}; + +} // namespace + +/*! + \internal + + Causes this state machine to unconditionally transition to the given + \a targetState. + + Provides a backdoor for using the state machine "imperatively"; i.e. rather + than defining explicit transitions, you drive the machine's execution by + calling this function. It breaks the whole integrity of the + transition-driven model, but is provided for pragmatic reasons. +*/ +void QStateMachinePrivate::goToState(QAbstractState *targetState) +{ + if (!targetState) { + qWarning("QStateMachine::goToState(): cannot go to null state"); + return; + } + + if (configuration.contains(targetState)) + return; + + QState *sourceState = 0; + if (state == Running) { + QSet::const_iterator it; + for (it = configuration.constBegin(); it != configuration.constEnd(); ++it) { + sourceState = qobject_cast(*it); + if (sourceState != 0) + break; + } + } else { + sourceState = startState(); + } + + Q_ASSERT(sourceState != 0); + // Reuse previous GoToStateTransition in case of several calls to + // goToState() in a row. + GoToStateTransition *trans = qFindChild(sourceState); + if (!trans) { + trans = new GoToStateTransition(targetState); + sourceState->addTransition(trans); + } else { + trans->setTargetState(targetState); + } + + scheduleProcess(); +} + void QStateMachinePrivate::registerTransitions(QAbstractState *state) { QState *group = qobject_cast(state); diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index 590cffe..714a40b 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -79,7 +79,7 @@ class QAbstractAnimation; #endif class QStateMachine; -class QStateMachinePrivate : public QStatePrivate +class Q_AUTOTEST_EXPORT QStateMachinePrivate : public QStatePrivate { Q_DECLARE_PUBLIC(QStateMachine) public: @@ -116,6 +116,9 @@ public: QState *rootState() const; + QState *startState(); + void removeStartState(); + void microstep(QEvent *event, const QList &transitionList); bool isPreempted(const QAbstractState *s, const QSet &transitions) const; QSet selectTransitions(QEvent *event) const; @@ -138,6 +141,8 @@ public: static bool isDescendantOf(const QAbstractState *s, const QAbstractState *other); static QList properAncestors(const QAbstractState *s, const QState *upperBound); + void goToState(QAbstractState *targetState); + void registerTransitions(QAbstractState *state); void registerSignalTransition(QSignalTransition *transition); void unregisterSignalTransition(QSignalTransition *transition); @@ -162,6 +167,7 @@ public: #endif State state; + QState *_startState; bool processing; bool processingScheduled; bool stop; diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index 7f4d9f5..32812e2 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -192,6 +192,7 @@ private slots: // void overrideDefaultTargetAnimationWithSource(); void nestedStateMachines(); + void goToState(); }; tst_QStateMachine::tst_QStateMachine() @@ -3900,5 +3901,45 @@ void tst_QStateMachine::nestedStateMachines() QTRY_COMPARE(finishedSpy.count(), 1); } +void tst_QStateMachine::goToState() +{ + QStateMachine machine; + QState *s1 = new QState(&machine); + QState *s2 = new QState(&machine); + machine.setInitialState(s1); + QSignalSpy startedSpy(&machine, SIGNAL(started())); + machine.start(); + QTRY_COMPARE(startedSpy.count(), 1); + + QStateMachinePrivate::get(&machine)->goToState(s2); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s2)); + + QStateMachinePrivate::get(&machine)->goToState(s2); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s2)); + + QStateMachinePrivate::get(&machine)->goToState(s1); + QStateMachinePrivate::get(&machine)->goToState(s2); + QStateMachinePrivate::get(&machine)->goToState(s1); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s2)); + + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + + // go to state in group + QState *s2_1 = new QState(s2); + s2->setInitialState(s2_1); + QStateMachinePrivate::get(&machine)->goToState(s2_1); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s2_1)); +} + QTEST_MAIN(tst_QStateMachine) #include "tst_qstatemachine.moc" -- cgit v0.12 From 18d9902a2c5650e48a33b09ef68596479e7cb9ff Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 31 Jul 2009 13:40:17 +0200 Subject: Fix compilation: add #include if placement new is used I'm not sure this is the proper fix, though. xlC 7 complains with: "/usr/vacpp/include/new", line 97.10: 1540-1298 (I) "void *operator new(size_t, void *) throw()" needs to be declared in the containing scope to be found by name lookup. Also add some calculations to the padding in the data structure. Reviewed-by: Trust Me --- src/corelib/tools/qcontiguouscache.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h index 0020d22..7221925 100644 --- a/src/corelib/tools/qcontiguouscache.h +++ b/src/corelib/tools/qcontiguouscache.h @@ -44,6 +44,7 @@ #include #include +#include QT_BEGIN_HEADER @@ -76,6 +77,12 @@ struct QContiguousCacheTypedData 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) T array[1]; }; -- cgit v0.12 From 991c2299078978d38692b3499580eb86d0ed7d9b Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 31 Jul 2009 13:56:37 +0200 Subject: Revert "Small simplification of code in ItemViews (delegate)" This reverts commit 95560abfdd3a1755b69f238eff2954d164dff6a5. Fix comboboxes used as editor. isAncestor() stops at windows. we want to go tought the whole widget chain, including parent windows Use case: examples/itemviews/coloreditorfactory/coloreditorfactory Task-number: 259034 --- src/gui/itemviews/qitemdelegate.cpp | 9 ++++++--- src/gui/itemviews/qstyleditemdelegate.cpp | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/gui/itemviews/qitemdelegate.cpp b/src/gui/itemviews/qitemdelegate.cpp index 336ca79..aff715c 100644 --- a/src/gui/itemviews/qitemdelegate.cpp +++ b/src/gui/itemviews/qitemdelegate.cpp @@ -1226,9 +1226,12 @@ bool QItemDelegate::eventFilter(QObject *object, QEvent *event) } else if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) { //the Hide event will take care of he editors that are in fact complete dialogs if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) { - if (editor->isAncestorOf(QApplication::focusWidget())) - return false; // don't worry about focus changes internally in the editor - + QWidget *w = QApplication::focusWidget(); + while (w) { // don't worry about focus changes internally in the editor + if (w == editor) + return false; + w = w->parentWidget(); + } #ifndef QT_NO_DRAGANDDROP // The window may lose focus during an drag operation. // i.e when dragging involves the taskbar on Windows. diff --git a/src/gui/itemviews/qstyleditemdelegate.cpp b/src/gui/itemviews/qstyleditemdelegate.cpp index bd8fdac..7ec2afe 100644 --- a/src/gui/itemviews/qstyleditemdelegate.cpp +++ b/src/gui/itemviews/qstyleditemdelegate.cpp @@ -674,9 +674,12 @@ bool QStyledItemDelegate::eventFilter(QObject *object, QEvent *event) } else if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) { //the Hide event will take care of he editors that are in fact complete dialogs if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) { - if (editor->isAncestorOf(QApplication::focusWidget())) - return false; // don't worry about focus changes internally in the editor - + QWidget *w = QApplication::focusWidget(); + while (w) { // don't worry about focus changes internally in the editor + if (w == editor) + return false; + w = w->parentWidget(); + } #ifndef QT_NO_DRAGANDDROP // The window may lose focus during an drag operation. // i.e when dragging involves the taskbar on Windows. -- cgit v0.12 From 193b109814a0bbf4fc8b5d7bd8911c920194838d Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 31 Jul 2009 14:25:58 +0200 Subject: compile Broke on WinCE since QStateMachinePrivate is now using Q_AUTOTEST_EXPORT. --- src/corelib/statemachine/qstatemachine_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index 714a40b..5d8c788 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -214,7 +214,7 @@ public: f_cloneEvent cloneEvent; }; - static Q_CORE_EXPORT const Handler *handler; + static const Handler *handler; }; QT_END_NAMESPACE -- cgit v0.12 From 7c4b1863495905c3486ea36e0d559f49c6f2ebb4 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 31 Jul 2009 14:33:30 +0200 Subject: Doc: fix warnings. --- src/corelib/kernel/qabstractitemmodel.cpp | 2 +- src/testlib/qtestcase.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp index 80da80e..bc95c60 100644 --- a/src/corelib/kernel/qabstractitemmodel.cpp +++ b/src/corelib/kernel/qabstractitemmodel.cpp @@ -1902,7 +1902,7 @@ void QAbstractItemModel::setRoleNames(const QHash &roleNames) /*! Returns the model's role names. - \sa setRoleNames + \sa setRoleNames() */ const QHash &QAbstractItemModel::roleNames() const { diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 1dae828..ac4ca83 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -818,6 +818,8 @@ void filter_unprintable(char *str) } } +/*! \internal + */ int qt_asprintf(char **str, const char *format, ...) { static const int MAXSIZE = 1024*1024*2; -- cgit v0.12 From c0f0e798e903c39d5f8b6dc6dd2abdfbcc8a7d93 Mon Sep 17 00:00:00 2001 From: ck Date: Fri, 31 Jul 2009 14:41:45 +0200 Subject: Assistant: Performance fixes for help generator's pattern matching. Reading a help project was unacceptably slow with pattern matching. Now we do it only for filenames that contain wildcard symbols. Also, we cache the results of QDir::entryList() calls. --- tools/assistant/lib/qhelpprojectdata.cpp | 43 ++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/tools/assistant/lib/qhelpprojectdata.cpp b/tools/assistant/lib/qhelpprojectdata.cpp index 55b4ea7..5df0426 100644 --- a/tools/assistant/lib/qhelpprojectdata.cpp +++ b/tools/assistant/lib/qhelpprojectdata.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -75,6 +76,8 @@ private: void readFiles(); void raiseUnknownTokenError(); void addMatchingFiles(const QString &pattern); + + QMap dirEntriesCache; }; void QHelpProjectDataPrivate::raiseUnknownTokenError() @@ -265,14 +268,40 @@ void QHelpProjectDataPrivate::readFiles() // meaningful warning later. void QHelpProjectDataPrivate::addMatchingFiles(const QString &pattern) { + // The pattern matching is expensive, so we skip it if no + // wildcard symbols occur in the string. + if (!pattern.contains('?') && !pattern.contains('*') + && !pattern.contains('[') && !pattern.contains(']')) { + filterSectionList.last().addFile(pattern); + return; + } + QFileInfo fileInfo(rootPath + '/' + pattern); - const QStringList &matches = - fileInfo.dir().entryList(QStringList(fileInfo.fileName())); - for (QStringList::ConstIterator it = matches.constBegin(); - it != matches.constEnd(); - ++it) - filterSectionList.last().addFile(QFileInfo(pattern).dir().path() + '/' + *it); - if (matches.empty()) + const QDir &dir = fileInfo.dir(); + const QString &path = dir.canonicalPath(); + + // QDir::entryList() is expensive, so we cache the results. + QMap::ConstIterator it = dirEntriesCache.find(path); + const QStringList &entries = it != dirEntriesCache.constEnd() ? + it.value() : dir.entryList(QDir::Files); + if (it == dirEntriesCache.constEnd()) + dirEntriesCache.insert(path, entries); + + bool matchFound = false; +#ifdef Q_OS_WIN + Qt::CaseSensitivity cs = Qt::CaseInSensitive; +#else + Qt::CaseSensitivity cs = Qt::CaseSensitive; +#endif + QRegExp regExp(fileInfo.fileName(), cs, QRegExp::Wildcard); + foreach (const QString &file, entries) { + if (regExp.exactMatch(file)) { + matchFound = true; + filterSectionList.last(). + addFile(QFileInfo(pattern).dir().path() + '/' + file); + } + } + if (!matchFound) filterSectionList.last().addFile(pattern); } -- cgit v0.12 From 9d511567ece87258ab0bdc77f8c0ab62c075f454 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 31 Jul 2009 14:52:29 +0200 Subject: Crash DirectFb plugin when resizing verticaly QRasterPaintEngine assumes device does not change size. Therefore create a new engine when resizing. Reviewed-by: Tom --- src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp index a1009ac..8cddc76 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp @@ -209,7 +209,6 @@ void QDirectFBWindowSurface::setGeometry(const QRect &rect) if (!dfbWindow) createWindow(); ::setGeometry(dfbWindow, oldRect, rect); - // ### do I need to release and get the surface again here? #endif break; case Offscreen: { @@ -227,7 +226,10 @@ void QDirectFBWindowSurface::setGeometry(const QRect &rect) if (result != DFB_OK) DirectFBErrorFatal("QDirectFBWindowSurface::setGeometry()", result); } - + if (engine) { + delete engine; + engine = 0; + } QWSWindowSurface::setGeometry(rect); } -- cgit v0.12 From 7c56a5b3825de2372712b9f0087df868ca1fd157 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Thu, 30 Jul 2009 13:12:56 +0200 Subject: QCheckBox on an out-of-process server wont allow key & Focus rect is not drawn correctly. Depending on the type of server, QAxClientSite::TranslateAccelerator() needs to process the message differently. For ActiveQt based in-process-servers, only normal Qt event handling is required. For ActiveQt based out-of-process-servers, the message has to be forwarded and Qt event handling needs to continue. For all other type of servers, forward the message and stop Qt event processing. Styles use the WA_KeyboardFocusChange attribute set on the window to decide on drawing the focus rect. ActiveQt handles the VK_TAB key in the QAxServerBase::TranslateAcceleratorW(), the attibute is now set when focus is changed. Task-number: 253763 Reviewed-by: Volker Hilsheimer --- src/activeqt/container/qaxwidget.cpp | 40 ++++++++++++++- src/activeqt/control/qaxserverbase.cpp | 90 ++++++++++++++++++---------------- src/activeqt/shared/qaxtypes.h | 3 ++ 3 files changed, 90 insertions(+), 43 deletions(-) diff --git a/src/activeqt/container/qaxwidget.cpp b/src/activeqt/container/qaxwidget.cpp index ae468ef..19f00db 100644 --- a/src/activeqt/container/qaxwidget.cpp +++ b/src/activeqt/container/qaxwidget.cpp @@ -118,6 +118,8 @@ public: QSize minimumSizeHint() const; int qt_metacall(QMetaObject::Call, int isignal, void **argv); + void* qt_metacast(const char *clname); + inline QAxClientSite *clientSite() const { return axhost; @@ -478,7 +480,9 @@ bool axc_FilterProc(void *m) QAxWidget *ax = 0; QAxHostWidget *host = 0; while (!host && hwnd) { - host = qobject_cast(QWidget::find(hwnd)); + QWidget *widget = QWidget::find(hwnd); + if (widget && widget->inherits("QAxHostWidget")) + host = qobject_cast(widget); hwnd = ::GetParent(hwnd); } if (host) @@ -976,10 +980,34 @@ HRESULT WINAPI QAxClientSite::TransformCoords(POINTL* /*pPtlHimetric*/, POINTF* HRESULT WINAPI QAxClientSite::TranslateAccelerator(LPMSG lpMsg, DWORD /*grfModifiers*/) { - eventTranslated = false; if (lpMsg->message == WM_KEYDOWN && !lpMsg->wParam) return S_OK; + + bool ActiveQtDetected = false; + bool fromInProcServer = false; + LONG_PTR serverType = GetWindowLongPtr(lpMsg->hwnd, GWLP_USERDATA); + if (serverType == QAX_INPROC_SERVER) { + ActiveQtDetected = true; + fromInProcServer = true; + } else if (serverType == QAX_OUTPROC_SERVER) { + ActiveQtDetected = true; + fromInProcServer = false; + } + + eventTranslated = false; + if (!ActiveQtDetected || !fromInProcServer) { + // if the request is coming from an out-of-proc server or a non ActiveQt server, + // we send the message to the host window. This will make sure this key event + // comes to Qt for processing. SendMessage(host->winId(), lpMsg->message, lpMsg->wParam, lpMsg->lParam); + if (ActiveQtDetected && !fromInProcServer) { + // ActiveQt based servers will need further processing of the event + // (eg. key for a checkbox), so we return false. + return S_FALSE; + } + } + // ActiveQt based in-processes-servers will handle the event properly, so + // we dont need to send this key event to the host. return S_OK; } @@ -1617,6 +1645,14 @@ int QAxHostWidget::qt_metacall(QMetaObject::Call call, int isignal, void **argv) return -1; } +void* QAxHostWidget::qt_metacast(const char *clname) +{ + if (!clname) return 0; + if (!qstrcmp(clname,"QAxHostWidget")) + return static_cast(const_cast< QAxHostWidget*>(this)); + return QWidget::qt_metacast(clname); +} + QSize QAxHostWidget::sizeHint() const { return axhost ? axhost->sizeHint() : QWidget::sizeHint(); diff --git a/src/activeqt/control/qaxserverbase.cpp b/src/activeqt/control/qaxserverbase.cpp index d7a8e07..e482c60 100644 --- a/src/activeqt/control/qaxserverbase.cpp +++ b/src/activeqt/control/qaxserverbase.cpp @@ -3502,24 +3502,24 @@ Q_GUI_EXPORT int qt_translateKeyCode(int); HRESULT WINAPI QAxServerBase::TranslateAcceleratorW(MSG *pMsg) { if (pMsg->message != WM_KEYDOWN || !isWidget) - return S_FALSE; + return S_FALSE; DWORD dwKeyMod = 0; if (::GetKeyState(VK_SHIFT) < 0) - dwKeyMod |= 1; // KEYMOD_SHIFT + dwKeyMod |= 1; // KEYMOD_SHIFT if (::GetKeyState(VK_CONTROL) < 0) - dwKeyMod |= 2; // KEYMOD_CONTROL + dwKeyMod |= 2; // KEYMOD_CONTROL if (::GetKeyState(VK_MENU) < 0) - dwKeyMod |= 4; // KEYMOD_ALT + dwKeyMod |= 4; // KEYMOD_ALT switch (LOWORD(pMsg->wParam)) { case VK_TAB: - if (isUIActive) { - bool shift = ::GetKeyState(VK_SHIFT) < 0; - bool giveUp = true; + if (isUIActive) { + bool shift = ::GetKeyState(VK_SHIFT) < 0; + bool giveUp = true; QWidget *curFocus = qt.widget->focusWidget(); if (curFocus) { - if (shift) { + if (shift) { if (!curFocus->isWindow()) { QWidget *nextFocus = curFocus->nextInFocusChain(); QWidget *prevFocus = 0; @@ -3537,9 +3537,10 @@ HRESULT WINAPI QAxServerBase::TranslateAcceleratorW(MSG *pMsg) if (!topLevel) { giveUp = false; ((HackWidget*)curFocus)->focusNextPrevChild(false); + curFocus->window()->setAttribute(Qt::WA_KeyboardFocusChange); } } - } else { + } else { QWidget *nextFocus = curFocus; while (1) { nextFocus = nextFocus->nextInFocusChain(); @@ -3548,63 +3549,70 @@ HRESULT WINAPI QAxServerBase::TranslateAcceleratorW(MSG *pMsg) if (nextFocus->focusPolicy() & Qt::TabFocus) { giveUp = false; ((HackWidget*)curFocus)->focusNextPrevChild(true); + curFocus->window()->setAttribute(Qt::WA_KeyboardFocusChange); break; } } - } + } + } + if (giveUp) { + HWND hwnd = ::GetParent(m_hWnd); + ::SetFocus(hwnd); + } else { + return S_OK; } - if (giveUp) { - HWND hwnd = ::GetParent(m_hWnd); - ::SetFocus(hwnd); - } else { - return S_OK; - } - } - break; + } + break; case VK_LEFT: case VK_RIGHT: case VK_UP: case VK_DOWN: - if (isUIActive) - return S_FALSE; - break; + if (isUIActive) + return S_FALSE; + break; default: - if (isUIActive && qt.widget->focusWidget()) { + if (isUIActive && qt.widget->focusWidget()) { int state = Qt::NoButton; - if (dwKeyMod & 1) - state |= Qt::ShiftModifier; - if (dwKeyMod & 2) - state |= Qt::ControlModifier; - if (dwKeyMod & 4) - state |= Qt::AltModifier; - - int key = pMsg->wParam; + if (dwKeyMod & 1) + state |= Qt::ShiftModifier; + if (dwKeyMod & 2) + state |= Qt::ControlModifier; + if (dwKeyMod & 4) + state |= Qt::AltModifier; + + int key = pMsg->wParam; if (!(key >= 'A' && key <= 'Z') && !(key >= '0' && key <= '9')) key = qt_translateKeyCode(pMsg->wParam); - QKeyEvent override(QEvent::ShortcutOverride, key, (Qt::KeyboardModifiers)state); - override.ignore(); - QApplication::sendEvent(qt.widget->focusWidget(), &override); - if (override.isAccepted()) - return S_FALSE; - } - break; + QKeyEvent override(QEvent::ShortcutOverride, key, (Qt::KeyboardModifiers)state); + override.ignore(); + QApplication::sendEvent(qt.widget->focusWidget(), &override); + if (override.isAccepted()) + return S_FALSE; + } + break; } if (!m_spClientSite) - return S_FALSE; + return S_FALSE; IOleControlSite *controlSite = 0; m_spClientSite->QueryInterface(IID_IOleControlSite, (void**)&controlSite); if (!controlSite) - return S_FALSE; - + return S_FALSE; + bool resetUserData = false; + // set server type in the user-data of the window. + LONG_PTR serverType = QAX_INPROC_SERVER; + if (qAxOutProcServer) + serverType = QAX_OUTPROC_SERVER; + LONG_PTR oldData = SetWindowLongPtr(pMsg->hwnd, GWLP_USERDATA, serverType); HRESULT hres = controlSite->TranslateAcceleratorW(pMsg, dwKeyMod); - controlSite->Release(); + // reset the user-data for the window. + SetWindowLongPtr(pMsg->hwnd, GWLP_USERDATA, oldData); return hres; } diff --git a/src/activeqt/shared/qaxtypes.h b/src/activeqt/shared/qaxtypes.h index 4f647a3..e3c7138 100644 --- a/src/activeqt/shared/qaxtypes.h +++ b/src/activeqt/shared/qaxtypes.h @@ -89,6 +89,9 @@ extern QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName extern bool QVariantToVoidStar(const QVariant &var, void *data, const QByteArray &typeName, uint type = 0); extern void clearVARIANT(VARIANT *var); +#define QAX_INPROC_SERVER (0x51540001) +#define QAX_OUTPROC_SERVER (0x51540002) + QT_END_NAMESPACE #endif // QT_NO_WIN_ACTIVEQT -- cgit v0.12 From ed6e0d67211938de7bcba844519d5bad8d2965b6 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 31 Jul 2009 15:30:12 +0200 Subject: Export symbol used in QtGui. Reviewed-by: Kent Hansen --- src/corelib/statemachine/qstatemachine_p.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index 5d8c788..387e42e 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -214,7 +214,11 @@ public: f_cloneEvent cloneEvent; }; - static const Handler *handler; + static +#ifndef QT_BUILD_INTERNAL // otherwise Q_AUTOTEST_EXPORT exports it all + Q_CORE_EXPORT +#endif + const Handler *handler; }; QT_END_NAMESPACE -- cgit v0.12 From 2cadc571339d4abee6d7cfb0da08e3119d934524 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 31 Jul 2009 15:52:55 +0200 Subject: Doc: Use new APIs in example and correct documentation regarding replacement. --- doc/src/examples/collidingmice-example.qdoc | 4 ++-- examples/graphicsview/collidingmice/mouse.cpp | 4 ++-- src/gui/graphicsview/qgraphicsitem.cpp | 31 +++++++++++++++++++++++---- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/doc/src/examples/collidingmice-example.qdoc b/doc/src/examples/collidingmice-example.qdoc index 5b124f9..f627fbf 100644 --- a/doc/src/examples/collidingmice-example.qdoc +++ b/doc/src/examples/collidingmice-example.qdoc @@ -95,11 +95,11 @@ the global qrand() function which is a thread-safe version of the standard C++ rand() function. - Then we call the \l {QGraphicsItem::rotate()}{rotate()} function + Then we call the \l {QGraphicsItem::setRotation()}{setRotation()} function inherited from QGraphicsItem. Items live in their own local coordinate system. Their coordinates are usually centered around (0, 0), and this is also the center for all transformations. By - calling the item's \l {QGraphicsItem::rotate()}{rotate()} function + calling the item's \l {QGraphicsItem::setRotation()}{setRotation()} function we alter the direction in which the mouse will start moving. When the QGraphicsScene decides to advance the scene a frame it will call diff --git a/examples/graphicsview/collidingmice/mouse.cpp b/examples/graphicsview/collidingmice/mouse.cpp index c6a67b1..4cc29dd 100644 --- a/examples/graphicsview/collidingmice/mouse.cpp +++ b/examples/graphicsview/collidingmice/mouse.cpp @@ -64,7 +64,7 @@ Mouse::Mouse() : angle(0), speed(0), mouseEyeDirection(0), color(qrand() % 256, qrand() % 256, qrand() % 256) { - rotate(qrand() % (360 * 16)); + setRotation(qrand() % (360 * 16)); } //! [0] @@ -195,7 +195,7 @@ void Mouse::advance(int step) qreal dx = ::sin(angle) * 10; mouseEyeDirection = (qAbs(dx / 5) < 1) ? 0 : dx / 5; - rotate(dx); + setRotation(rotation() + dx); setPos(mapToParent(0, -(3 + sin(speed) * 3))); } //! [11] diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index eaf9896..a4eca4d 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -3535,7 +3535,13 @@ void QGraphicsItem::resetTransform() /*! \obsolete - Use setRotation() instead + Use + + \code + setRotation(rotation() + angle); + \endcode + + instead. Rotates the current item transformation \a angle degrees clockwise around its origin. To translate around an arbitrary point (x, y), you need to @@ -3555,7 +3561,13 @@ void QGraphicsItem::rotate(qreal angle) /*! \obsolete - Use setScale() instead + Use + + \code + setTransform(QTransform::fromScale(sx, sy), true); + \encode + + instead. Scales the current item transformation by (\a sx, \a sy) around its origin. To scale from an arbitrary point (x, y), you need to combine @@ -3575,7 +3587,13 @@ void QGraphicsItem::scale(qreal sx, qreal sy) /*! \obsolete - Use setTransform() instead. + Use + + \code + setTransform(QTransform().shear(sh, sv), true); + \endcode + + instead. Shears the current item transformation by (\a sh, \a sv). @@ -3589,7 +3607,12 @@ void QGraphicsItem::shear(qreal sh, qreal sv) /*! \obsolete - Use setPos() or setTransformOriginPoint() instead. + Use setPos() or setTransformOriginPoint() instead. For identical + behavior, use + + \code + setTransform(QTransform::fromTranslate(dx, dy), true); + \endcode Translates the current item transformation by (\a dx, \a dy). -- cgit v0.12 From c6cdfcb02d74f726e79ead9f890f294587a7c63c Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 31 Jul 2009 15:55:41 +0200 Subject: Doc: Use new APIs in example and correct documentation regarding replacement. --- src/gui/graphicsview/qgraphicsitem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index a4eca4d..a047e6a 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -3565,7 +3565,7 @@ void QGraphicsItem::rotate(qreal angle) \code setTransform(QTransform::fromScale(sx, sy), true); - \encode + \endcode instead. -- cgit v0.12 From c57ed134a536c177d1774d9272ca187bdfb28e6b Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 31 Jul 2009 16:16:01 +0200 Subject: Revert "Fix QFormLayout which allowed fields to be smaller that their minimum size" This reverts commit 244f5ee9c2c34ddee200e4d5cdc1345762a5901b. Valgrind complains about the label fields that are not inisialized yet, and indeed. They are initialized right after, and need the maxLabelWidth to be computed. This is a chicken and egg problem difficult to solve, so I rather revert the change as the bug is not critical --- src/gui/kernel/qformlayout.cpp | 6 +----- tests/auto/qformlayout/tst_qformlayout.cpp | 30 ------------------------------ 2 files changed, 1 insertion(+), 35 deletions(-) diff --git a/src/gui/kernel/qformlayout.cpp b/src/gui/kernel/qformlayout.cpp index 0b7656f..de33f93 100644 --- a/src/gui/kernel/qformlayout.cpp +++ b/src/gui/kernel/qformlayout.cpp @@ -689,16 +689,12 @@ void QFormLayoutPrivate::setupVerticalLayoutData(int width) // are split. maxLabelWidth = 0; if (!wrapAllRows) { - int maxFieldMinWidth = 0; //the maximum minimum size of the field for (int i = 0; i < rr; ++i) { const QFormLayoutItem *label = m_matrix(i, 0); const QFormLayoutItem *field = m_matrix(i, 1); - if (label && field && label->sideBySide) + if (label && (label->sizeHint.width() + (field ? field->minSize.width() : 0) <= width)) maxLabelWidth = qMax(maxLabelWidth, label->sizeHint.width()); - if (field) - maxFieldMinWidth = qMax(maxFieldMinWidth, field->minSize.width() + field->sbsHSpace); } - maxLabelWidth = qMin(maxLabelWidth, width - maxFieldMinWidth); } else { maxLabelWidth = width; } diff --git a/tests/auto/qformlayout/tst_qformlayout.cpp b/tests/auto/qformlayout/tst_qformlayout.cpp index 74384a9..9806557 100644 --- a/tests/auto/qformlayout/tst_qformlayout.cpp +++ b/tests/auto/qformlayout/tst_qformlayout.cpp @@ -125,7 +125,6 @@ private slots: Qt::Orientations expandingDirections() const; */ - void fieldMinimumSize(); }; tst_QFormLayout::tst_QFormLayout() @@ -906,35 +905,6 @@ void tst_QFormLayout::layoutAlone() QTest::qWait(500); } - -void tst_QFormLayout::fieldMinimumSize() -{ - //check that the field with is bigger than its minimumSizeHint for any size of the widget - // even if the label with is not fixed - QWidget w; - QFormLayout layout; - layout.setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); - w.setLayout(&layout); - QLabel label1("Here is a strange test case"); - label1.setWordWrap(true); - QLabel label2("Here is another label"); - label2.setWordWrap(true); - QLabel shortLabel("short"); - QLabel longLabel("Quite long label"); - layout.addRow(&label1, &shortLabel); - layout.addRow(&label2, &longLabel); - w.show(); - int width = w.size().width() + 9; - - do { - w.resize(width, w.size().height()); - layout.activate(); - QVERIFY(shortLabel.size().width() >= shortLabel.minimumSizeHint().width()); - QVERIFY(longLabel.size().width() >= longLabel.minimumSizeHint().width()); - width -= 3; - } while(width >= w.minimumSizeHint().width()); -} - QTEST_MAIN(tst_QFormLayout) #include "tst_qformlayout.moc" -- cgit v0.12 From 5aed3db0a4084f470769ad4b965001f17b878c79 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Sat, 1 Aug 2009 12:04:25 +0200 Subject: Compilare necessus est --- tools/assistant/lib/qhelpprojectdata.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/assistant/lib/qhelpprojectdata.cpp b/tools/assistant/lib/qhelpprojectdata.cpp index 5df0426..9412f1c 100644 --- a/tools/assistant/lib/qhelpprojectdata.cpp +++ b/tools/assistant/lib/qhelpprojectdata.cpp @@ -289,7 +289,7 @@ void QHelpProjectDataPrivate::addMatchingFiles(const QString &pattern) bool matchFound = false; #ifdef Q_OS_WIN - Qt::CaseSensitivity cs = Qt::CaseInSensitive; + Qt::CaseSensitivity cs = Qt::CaseInsensitive; #else Qt::CaseSensitivity cs = Qt::CaseSensitive; #endif -- cgit v0.12 From 9ce6d885f4c141fabce1427ff776e02bdb6846ae Mon Sep 17 00:00:00 2001 From: Stian Sandvik Thomassen Date: Mon, 3 Aug 2009 09:47:56 +1000 Subject: Doc: Replaced QSet with QSet in QList::fromSet() example We don't implement qHash() for double, so let's not use QSet in the documentation. --- doc/src/snippets/code/src_corelib_tools_qlistdata.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/src/snippets/code/src_corelib_tools_qlistdata.cpp b/doc/src/snippets/code/src_corelib_tools_qlistdata.cpp index 7d75e1b..3b9a756 100644 --- a/doc/src/snippets/code/src_corelib_tools_qlistdata.cpp +++ b/doc/src/snippets/code/src_corelib_tools_qlistdata.cpp @@ -190,10 +190,10 @@ QVector vect = list.toVector(); //! [23] -QSet set; -set << 20.0 << 30.0 << 40.0 << ... << 70.0; +QSet set; +set << 20 << 30 << 40 << ... << 70; -QList list = QList::fromSet(set); +QList list = QList::fromSet(set); qSort(list); //! [23] -- cgit v0.12 From c386e433ff9e55bcf65abf9eee665ad4237fbd33 Mon Sep 17 00:00:00 2001 From: Bill King Date: Mon, 3 Aug 2009 14:11:07 +1000 Subject: Fixes casing fails for databases that have variable casing support. --- .../qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp index 1e23d3d..d836486 100644 --- a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp +++ b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp @@ -930,13 +930,15 @@ void tst_QSqlRelationalTableModel::casing() QSqlQuery q(db); QVERIFY_SQL( q, exec("create table " + qTableName("CASETEST1", db.driver()).toUpper() + " (id int not null primary key, name varchar(20), title_key int, another_title_key int)")); + + if( !q.exec("create table " + qTableName("casetest1", db.driver()) + + " (ident int not null primary key, name varchar(20), title_key int)")) + QSKIP("The casing test for this database is irrelevant since this database does not treat different cases as separate entities", SkipAll); + QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(1, 'harry', 1, 2)")); QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(2, 'trond', 2, 1)")); QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(3, 'vohi', 1, 2)")); QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(4, 'boris', 2, 2)")); - - QVERIFY_SQL( q, exec("create table " + qTableName("casetest1", db.driver()) + - " (ident int not null primary key, name varchar(20), title_key int)")); QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(1, 'jerry', 1)")); QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(2, 'george', 2)")); QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(4, 'kramer', 2)")); -- cgit v0.12 From f083e9c9aa59790695136811181f5f455d1c9dad Mon Sep 17 00:00:00 2001 From: Bill King Date: Mon, 3 Aug 2009 14:21:06 +1000 Subject: Fix more database autotests. --- tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp | 6 ++++-- tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp index 360c3b7..c449140 100644 --- a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp +++ b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp @@ -546,7 +546,7 @@ void tst_Q3SqlCursor::unicode() else QFAIL( QString( "Strings differ at position %1: orig: %2, db: %3" ).arg( i ).arg( utf8str[ i ].unicode(), 0, 16 ).arg( res[ i ].unicode(), 0, 16 ) ); } - if(db.driverName().startsWith("QMYSQL") || db.driverName().startsWith("QDB2")) + if((db.driverName().startsWith("QMYSQL") || db.driverName().startsWith("QDB2")) && res != utf8str) QEXPECT_FAIL("", "See above message", Continue); QVERIFY( res == utf8str ); } @@ -722,7 +722,9 @@ void tst_Q3SqlCursor::updateNoPK() // Sqlite returns 2, don't ask why. QVERIFY(cur.update() != 0); QString expect = "update " + qTableName("qtestPK") + - " set id = 1 , name = NULL , num = NULL where " + qTableName("qtestPK") + ".id" + " set "+db.driver()->escapeIdentifier("id", QSqlDriver::FieldName)+" = 1 , " + +db.driver()->escapeIdentifier("name", QSqlDriver::FieldName)+" = NULL , " + +db.driver()->escapeIdentifier("num", QSqlDriver::FieldName)+" = NULL where " + qTableName("qtestPK") + ".id" " IS NULL and " + qTableName("qtestPK") + ".name IS NULL and " + qTableName("qtestPK") + ".num IS NULL"; if (!db.driver()->hasFeature(QSqlDriver::PreparedQueries)) { diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index 025e895..ff62741 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -2009,8 +2009,8 @@ void tst_QSqlDatabase::mysql_multiselect() QVERIFY_SQL(q, exec("select version()")); QVERIFY_SQL(q, next()); QString version=tst_Databases::getMySqlVersion( db ); - int ver=version.section(QChar::fromLatin1('.'),0,1).toDouble(); - if (ver >= 4.1) + double ver=version.section(QChar::fromLatin1('.'),0,1).toDouble(); + if (ver < 4.1) QSKIP("Test requires MySQL >= 4.1", SkipSingle); QVERIFY_SQL(q, exec("SELECT * FROM " + qTableName("qtest") + "; SELECT * FROM " + qTableName("qtest"))); -- cgit v0.12 From 45005c68c6effa41108ef55cd10a84f5977f79a0 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 3 Aug 2009 09:19:31 +0200 Subject: Ensure that the dash offset is reset when using drawLines() When using drawLines() then the dash offset was remembering where it was on the previous line. This is not what the behaviour should be as it should be starting with the same offset for each line. Reviewed-by: Samuel --- src/gui/painting/qpaintengine_raster.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 69e490a..74456dd 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1736,6 +1736,8 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen) const QLineF *lines = reinterpret_cast(path.points()); for (int i = 0; i < lineCount; ++i) { + if (path.shape() == QVectorPath::LinesHint) + dashOffset = s->lastPen.dashOffset(); if (lines[i].p1() == lines[i].p2()) { if (s->lastPen.capStyle() != Qt::FlatCap) { QPointF p = lines[i].p1(); @@ -3454,8 +3456,8 @@ void QRasterPaintEngine::drawLines(const QLine *lines, int lineCount) int m22 = int(s->matrix.m22()); int dx = qFloor(s->matrix.dx() + aliasedCoordinateDelta); int dy = qFloor(s->matrix.dy() + aliasedCoordinateDelta); - int dashOffset = int(s->lastPen.dashOffset()); for (int i=0; ilastPen.dashOffset()); if (s->flags.int_xform) { const QLine &l = lines[i]; int x1 = l.x1() * m11 + dx; @@ -3554,8 +3556,8 @@ void QRasterPaintEngine::drawLines(const QLineF *lines, int lineCount) ? LineDrawNormal : LineDrawIncludeLastPixel; - int dashOffset = int(s->lastPen.dashOffset()); for (int i=0; ilastPen.dashOffset()); QLineF line = (lines[i] * s->matrix).translated(aliasedCoordinateDelta, aliasedCoordinateDelta); const QRectF brect(QPointF(line.x1(), line.y1()), QPointF(line.x2(), line.y2())); -- cgit v0.12 From acd156649b1083aeeb400fe8fdbbf4e55ada4bed Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Mon, 3 Aug 2009 10:35:37 +0200 Subject: remove constructors that are not useful The constructors that take a list of target states produce hard-to-read code, and they're rarely useful in practice since 99% of transitions take a single target state; so it's better to enforce that setTarget{State,States}() be used instead. --- examples/animation/stickman/lifecycle.cpp | 6 +++-- src/corelib/statemachine/qabstracttransition.cpp | 22 ----------------- src/corelib/statemachine/qabstracttransition.h | 3 --- src/corelib/statemachine/qeventtransition.cpp | 30 ------------------------ src/corelib/statemachine/qeventtransition.h | 5 ---- src/corelib/statemachine/qsignaltransition.cpp | 15 ------------ src/corelib/statemachine/qsignaltransition.h | 3 --- src/corelib/statemachine/qstate.cpp | 6 +++-- src/corelib/statemachine/qstatemachine.cpp | 6 +++-- src/gui/statemachine/qkeyeventtransition.cpp | 13 ---------- src/gui/statemachine/qkeyeventtransition.h | 3 --- src/gui/statemachine/qmouseeventtransition.cpp | 15 ------------ src/gui/statemachine/qmouseeventtransition.h | 4 ---- tests/auto/qstate/tst_qstate.cpp | 5 ++-- tests/auto/qstatemachine/tst_qstatemachine.cpp | 30 ++++++++++-------------- 15 files changed, 28 insertions(+), 138 deletions(-) diff --git a/examples/animation/stickman/lifecycle.cpp b/examples/animation/stickman/lifecycle.cpp index c761d87..700916d 100644 --- a/examples/animation/stickman/lifecycle.cpp +++ b/examples/animation/stickman/lifecycle.cpp @@ -56,8 +56,9 @@ public: { } KeyPressTransition(GraphicsView *receiver, Qt::Key key, QAbstractState *target) - : QSignalTransition(receiver, SIGNAL(keyPressed(int)), QList() << target), m_key(key) + : QSignalTransition(receiver, SIGNAL(keyPressed(int))), m_key(key) { + setTargetState(target); } virtual bool eventTest(QEvent *e) @@ -78,8 +79,9 @@ class LightningStrikesTransition: public QEventTransition { public: LightningStrikesTransition(QAbstractState *target) - : QEventTransition(this, QEvent::Timer, QList() << target) + : QEventTransition(this, QEvent::Timer) { + setTargetState(target); qsrand((uint)QDateTime::currentDateTime().toTime_t()); startTimer(1000); } diff --git a/src/corelib/statemachine/qabstracttransition.cpp b/src/corelib/statemachine/qabstracttransition.cpp index 0004d3e..3248dcf 100644 --- a/src/corelib/statemachine/qabstracttransition.cpp +++ b/src/corelib/statemachine/qabstracttransition.cpp @@ -153,34 +153,12 @@ QAbstractTransition::QAbstractTransition(QState *sourceState) } /*! - Constructs a new QAbstractTransition object with the given \a targets and \a - sourceState. -*/ -QAbstractTransition::QAbstractTransition(const QList &targets, - QState *sourceState) - : QObject(*new QAbstractTransitionPrivate, sourceState) -{ - setTargetStates(targets); -} - -/*! - \internal -*/ -QAbstractTransition::QAbstractTransition(QAbstractTransitionPrivate &dd, - QState *parent) - : QObject(dd, parent) -{ -} - -/*! \internal */ QAbstractTransition::QAbstractTransition(QAbstractTransitionPrivate &dd, - const QList &targets, QState *parent) : QObject(dd, parent) { - setTargetStates(targets); } /*! diff --git a/src/corelib/statemachine/qabstracttransition.h b/src/corelib/statemachine/qabstracttransition.h index 9ba1f11..8ff3a6e 100644 --- a/src/corelib/statemachine/qabstracttransition.h +++ b/src/corelib/statemachine/qabstracttransition.h @@ -72,7 +72,6 @@ class Q_CORE_EXPORT QAbstractTransition : public QObject Q_PROPERTY(QList targetStates READ targetStates WRITE setTargetStates) public: QAbstractTransition(QState *sourceState = 0); - QAbstractTransition(const QList &targets, QState *sourceState = 0); virtual ~QAbstractTransition(); QState *sourceState() const; @@ -104,8 +103,6 @@ protected: protected: QAbstractTransition(QAbstractTransitionPrivate &dd, QState *parent); - QAbstractTransition(QAbstractTransitionPrivate &dd, - const QList &targets, QState *parent); private: Q_DISABLE_COPY(QAbstractTransition) diff --git a/src/corelib/statemachine/qeventtransition.cpp b/src/corelib/statemachine/qeventtransition.cpp index 3933981..813c960 100644 --- a/src/corelib/statemachine/qeventtransition.cpp +++ b/src/corelib/statemachine/qeventtransition.cpp @@ -153,22 +153,6 @@ QEventTransition::QEventTransition(QObject *object, QEvent::Type type, } /*! - Constructs a new QEventTransition object associated with events of the given - \a type for the given \a object. The transition has the given \a targets and - \a sourceState. -*/ -QEventTransition::QEventTransition(QObject *object, QEvent::Type type, - const QList &targets, - QState *sourceState) - : QAbstractTransition(*new QEventTransitionPrivate, targets, sourceState) -{ - Q_D(QEventTransition); - d->registered = false; - d->object = object; - d->eventType = type; -} - -/*! \internal */ QEventTransition::QEventTransition(QEventTransitionPrivate &dd, QState *parent) @@ -190,20 +174,6 @@ QEventTransition::QEventTransition(QEventTransitionPrivate &dd, QObject *object, } /*! - \internal -*/ -QEventTransition::QEventTransition(QEventTransitionPrivate &dd, QObject *object, - QEvent::Type type, const QList &targets, - QState *parent) - : QAbstractTransition(dd, targets, parent) -{ - Q_D(QEventTransition); - d->registered = false; - d->object = object; - d->eventType = type; -} - -/*! Destroys this QObject event transition. */ QEventTransition::~QEventTransition() diff --git a/src/corelib/statemachine/qeventtransition.h b/src/corelib/statemachine/qeventtransition.h index b05ffef..0ebca19 100644 --- a/src/corelib/statemachine/qeventtransition.h +++ b/src/corelib/statemachine/qeventtransition.h @@ -62,8 +62,6 @@ class Q_CORE_EXPORT QEventTransition : public QAbstractTransition public: QEventTransition(QState *sourceState = 0); QEventTransition(QObject *object, QEvent::Type type, QState *sourceState = 0); - QEventTransition(QObject *object, QEvent::Type type, - const QList &targets, QState *sourceState = 0); ~QEventTransition(); QObject *eventObject() const; @@ -82,9 +80,6 @@ protected: QEventTransition(QEventTransitionPrivate &dd, QState *parent); QEventTransition(QEventTransitionPrivate &dd, QObject *object, QEvent::Type type, QState *parent); - QEventTransition(QEventTransitionPrivate &dd, QObject *object, - QEvent::Type type, const QList &targets, - QState *parent); private: Q_DISABLE_COPY(QEventTransition) diff --git a/src/corelib/statemachine/qsignaltransition.cpp b/src/corelib/statemachine/qsignaltransition.cpp index 389e513..7814699 100644 --- a/src/corelib/statemachine/qsignaltransition.cpp +++ b/src/corelib/statemachine/qsignaltransition.cpp @@ -159,21 +159,6 @@ QSignalTransition::QSignalTransition(QObject *sender, const char *signal, } /*! - Constructs a new signal transition associated with the given \a signal of - the given \a sender. The transition has the given \a targets and \a - sourceState. -*/ -QSignalTransition::QSignalTransition(QObject *sender, const char *signal, - const QList &targets, - QState *sourceState) - : QAbstractTransition(*new QSignalTransitionPrivate, targets, sourceState) -{ - Q_D(QSignalTransition); - d->sender = sender; - d->signal = signal; -} - -/*! Destroys this signal transition. */ QSignalTransition::~QSignalTransition() diff --git a/src/corelib/statemachine/qsignaltransition.h b/src/corelib/statemachine/qsignaltransition.h index 69060ae..415751e 100644 --- a/src/corelib/statemachine/qsignaltransition.h +++ b/src/corelib/statemachine/qsignaltransition.h @@ -62,9 +62,6 @@ public: QSignalTransition(QState *sourceState = 0); QSignalTransition(QObject *sender, const char *signal, QState *sourceState = 0); - QSignalTransition(QObject *sender, const char *signal, - const QList &targets, - QState *sourceState = 0); ~QSignalTransition(); QObject *senderObject() const; diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp index 2042288..09d0be0 100644 --- a/src/corelib/statemachine/qstate.cpp +++ b/src/corelib/statemachine/qstate.cpp @@ -339,7 +339,8 @@ QSignalTransition *QState::addTransition(QObject *sender, const char *signal, return 0; } } - QSignalTransition *trans = new QSignalTransition(sender, signal, QList() << target); + QSignalTransition *trans = new QSignalTransition(sender, signal); + trans->setTargetState(target); addTransition(trans); return trans; } @@ -351,7 +352,8 @@ class UnconditionalTransition : public QAbstractTransition { public: UnconditionalTransition(QAbstractState *target) - : QAbstractTransition(QList() << target) {} + : QAbstractTransition() + { setTargetState(target); } protected: void onTransition(QEvent *) {} bool eventTest(QEvent *) { return true; } diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 5aa5917..9cb1d4d 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -1139,7 +1139,8 @@ class InitialTransition : public QAbstractTransition { public: InitialTransition(QAbstractState *target) - : QAbstractTransition(QList() << target) {} + : QAbstractTransition() + { setTargetState(target); } protected: virtual bool eventTest(QEvent *) { return true; } virtual void onTransition(QEvent *) {} @@ -1306,7 +1307,8 @@ class GoToStateTransition : public QAbstractTransition { public: GoToStateTransition(QAbstractState *target) - : QAbstractTransition(QList() << target) {} + : QAbstractTransition() + { setTargetState(target); } protected: void onTransition(QEvent *) { deleteLater(); } bool eventTest(QEvent *) { return true; } diff --git a/src/gui/statemachine/qkeyeventtransition.cpp b/src/gui/statemachine/qkeyeventtransition.cpp index 51b3ccc..21a0736 100644 --- a/src/gui/statemachine/qkeyeventtransition.cpp +++ b/src/gui/statemachine/qkeyeventtransition.cpp @@ -106,19 +106,6 @@ QKeyEventTransition::QKeyEventTransition(QObject *object, QEvent::Type type, } /*! - Constructs a new key event transition for events of the given \a type for - the given \a object, with the given \a key, \a targets and \a sourceState. -*/ -QKeyEventTransition::QKeyEventTransition(QObject *object, QEvent::Type type, - int key, const QList &targets, - QState *sourceState) - : QEventTransition(*new QKeyEventTransitionPrivate, object, type, targets, sourceState) -{ - Q_D(QKeyEventTransition); - d->transition = new QBasicKeyEventTransition(type, key); -} - -/*! Destroys this key event transition. */ QKeyEventTransition::~QKeyEventTransition() diff --git a/src/gui/statemachine/qkeyeventtransition.h b/src/gui/statemachine/qkeyeventtransition.h index f5e8de3..45ae684 100644 --- a/src/gui/statemachine/qkeyeventtransition.h +++ b/src/gui/statemachine/qkeyeventtransition.h @@ -62,9 +62,6 @@ public: QKeyEventTransition(QState *sourceState = 0); QKeyEventTransition(QObject *object, QEvent::Type type, int key, QState *sourceState = 0); - QKeyEventTransition(QObject *object, QEvent::Type type, int key, - const QList &targets, - QState *sourceState = 0); ~QKeyEventTransition(); int key() const; diff --git a/src/gui/statemachine/qmouseeventtransition.cpp b/src/gui/statemachine/qmouseeventtransition.cpp index 0cd096a..dbe50b3 100644 --- a/src/gui/statemachine/qmouseeventtransition.cpp +++ b/src/gui/statemachine/qmouseeventtransition.cpp @@ -112,21 +112,6 @@ QMouseEventTransition::QMouseEventTransition(QObject *object, QEvent::Type type, } /*! - Constructs a new mouse event transition for events of the given \a type for - the given \a object, with the given \a button, \a targets and \a - sourceState. -*/ -QMouseEventTransition::QMouseEventTransition(QObject *object, QEvent::Type type, - Qt::MouseButton button, - const QList &targets, - QState *sourceState) - : QEventTransition(*new QMouseEventTransitionPrivate, object, type, targets, sourceState) -{ - Q_D(QMouseEventTransition); - d->transition = new QBasicMouseEventTransition(type, button); -} - -/*! Destroys this mouse event transition. */ QMouseEventTransition::~QMouseEventTransition() diff --git a/src/gui/statemachine/qmouseeventtransition.h b/src/gui/statemachine/qmouseeventtransition.h index 73ae6c9..a56a554 100644 --- a/src/gui/statemachine/qmouseeventtransition.h +++ b/src/gui/statemachine/qmouseeventtransition.h @@ -63,10 +63,6 @@ public: QMouseEventTransition(QState *sourceState = 0); QMouseEventTransition(QObject *object, QEvent::Type type, Qt::MouseButton button, QState *sourceState = 0); - QMouseEventTransition(QObject *object, QEvent::Type type, - Qt::MouseButton button, - const QList &targets, - QState *sourceState = 0); ~QMouseEventTransition(); Qt::MouseButton button() const; diff --git a/tests/auto/qstate/tst_qstate.cpp b/tests/auto/qstate/tst_qstate.cpp index 78b9853..43ea7fe 100644 --- a/tests/auto/qstate/tst_qstate.cpp +++ b/tests/auto/qstate/tst_qstate.cpp @@ -250,8 +250,9 @@ class EventTestTransition: public QAbstractTransition { public: EventTestTransition(QEvent::Type type, QState *targetState) - : QAbstractTransition(QList() << targetState), m_type(type) - { + : QAbstractTransition(), m_type(type) + { + setTargetState(targetState); } protected: diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index 32812e2..97115bb 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -226,7 +226,8 @@ class TestTransition : public QAbstractTransition { public: TestTransition(QAbstractState *target) - : QAbstractTransition(QList() << target) {} + : QAbstractTransition() + { setTargetState(target); } QList triggers; protected: virtual bool eventTest(QEvent *) { @@ -249,7 +250,8 @@ class EventTransition : public QAbstractTransition { public: EventTransition(QEvent::Type type, QAbstractState *target, QState *parent = 0) - : QAbstractTransition(QList() << target, parent), m_type(type) {} + : QAbstractTransition(parent), m_type(type) + { setTargetState(target); } protected: virtual bool eventTest(QEvent *e) { return (e->type() == m_type); @@ -1514,7 +1516,8 @@ class StringTransition : public QAbstractTransition { public: StringTransition(const QString &value, QAbstractState *target) - : QAbstractTransition(QList() << target), m_value(value) {} + : QAbstractTransition(), m_value(value) + { setTargetState(target); } protected: virtual bool eventTest(QEvent *e) @@ -1737,7 +1740,8 @@ public: : QSignalTransition(sourceState) {} TestSignalTransition(QObject *sender, const char *signal, QAbstractState *target) - : QSignalTransition(sender, signal, QList() << target) {} + : QSignalTransition(sender, signal) + { setTargetState(target); } QVariantList argumentsReceived() const { return m_args; } @@ -2022,20 +2026,15 @@ void tst_QStateMachine::signalTransitions() void tst_QStateMachine::eventTransitions() { QPushButton button; - for (int x = 0; x < 2; ++x) { + { QStateMachine machine; QState *s0 = new QState(&machine); QFinalState *s1 = new QFinalState(&machine); QMouseEventTransition *trans; - if (x == 0) { - trans = new QMouseEventTransition(&button, QEvent::MouseButtonPress, Qt::LeftButton); - QCOMPARE(trans->targetState(), (QAbstractState*)0); - trans->setTargetState(s1); - } else { - trans = new QMouseEventTransition(&button, QEvent::MouseButtonPress, - Qt::LeftButton, QList() << s1); - } + trans = new QMouseEventTransition(&button, QEvent::MouseButtonPress, Qt::LeftButton); + QCOMPARE(trans->targetState(), (QAbstractState*)0); + trans->setTargetState(s1); QCOMPARE(trans->eventType(), QEvent::MouseButtonPress); QCOMPARE(trans->button(), Qt::LeftButton); QCOMPARE(trans->targetState(), (QAbstractState*)s1); @@ -2071,7 +2070,7 @@ void tst_QStateMachine::eventTransitions() QTest::mousePress(&button2, Qt::LeftButton); QTRY_COMPARE(finishedSpy.count(), 4); } - for (int x = 0; x < 3; ++x) { + for (int x = 0; x < 2; ++x) { QStateMachine machine; QState *s0 = new QState(&machine); QFinalState *s1 = new QFinalState(&machine); @@ -2087,9 +2086,6 @@ void tst_QStateMachine::eventTransitions() } else if (x == 1) { trans = new QEventTransition(&button, QEvent::MouseButtonPress); trans->setTargetState(s1); - } else { - trans = new QEventTransition(&button, QEvent::MouseButtonPress, - QList() << s1); } QCOMPARE(trans->eventObject(), (QObject*)&button); QCOMPARE(trans->eventType(), QEvent::MouseButtonPress); -- cgit v0.12 From 34e272ae3b89237f5aa92a089fdd99b5682b238b Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Mon, 3 Aug 2009 10:44:15 +0200 Subject: export QStateMachinePrivate symbols 1) it's needed for the Declarative UI integration and 2) it hopefully fixes the build on Windows. --- src/corelib/statemachine/qstatemachine_p.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index 387e42e..f0f74d6 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -79,7 +79,7 @@ class QAbstractAnimation; #endif class QStateMachine; -class Q_AUTOTEST_EXPORT QStateMachinePrivate : public QStatePrivate +class Q_CORE_EXPORT QStateMachinePrivate : public QStatePrivate { Q_DECLARE_PUBLIC(QStateMachine) public: @@ -214,11 +214,7 @@ public: f_cloneEvent cloneEvent; }; - static -#ifndef QT_BUILD_INTERNAL // otherwise Q_AUTOTEST_EXPORT exports it all - Q_CORE_EXPORT -#endif - const Handler *handler; + static const Handler *handler; }; QT_END_NAMESPACE -- cgit v0.12 From 4e693c01a62701f9376316a21b3d133a05dcc1e6 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 15 Jul 2009 09:07:37 +0200 Subject: Fix compilation of webkit with mingw --- mkspecs/features/moc.prf | 3 --- 1 file changed, 3 deletions(-) diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf index 62d9092..c5af298 100644 --- a/mkspecs/features/moc.prf +++ b/mkspecs/features/moc.prf @@ -15,10 +15,7 @@ WIN_INCLUDETEMP= win32:count($$list($$INCPATH), 40, >) { INCLUDETEMP = $$MOC_DIR/mocinclude.tmp - # Remove any existing mocinclude.tmp when qmake runs WIN_INCLUDETEMP=$$INCLUDETEMP - WIN_INCLUDETEMP~=s,/,\,g - system($$QMAKE_DEL_FILE $$WIN_INCLUDETEMP > NUL 2>&1) EOC = $$escape_expand(\n\t) -- cgit v0.12 From 232346cb33bd99016ba4210a95eeca45d24bf1b7 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Thu, 30 Jul 2009 12:50:25 +0200 Subject: Add qglpixelbuffer_p.h to opengl.pro so Creator finds it Reviewed-By: Trustme --- src/opengl/opengl.pro | 1 + 1 file changed, 1 insertion(+) diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index c92b8cf..868484e 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -20,6 +20,7 @@ HEADERS += qgl.h \ qgl_p.h \ qglcolormap.h \ qglpixelbuffer.h \ + qglpixelbuffer_p.h \ qglframebufferobject.h \ qglextensions_p.h -- cgit v0.12 From fc34e1cbaeeaa54b15d28edfab16d5f302334f70 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Fri, 31 Jul 2009 17:30:11 +0200 Subject: Fix build on X11/EGL without XRender Reviewed-by: Trustme --- src/opengl/qgl_x11egl.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 5ab3647..ed9930f 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -299,6 +299,7 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, int matchingCount = 0; chosenVisualInfo = XGetVisualInfo(x11Info().display(), VisualIDMask, &vi, &matchingCount); if (chosenVisualInfo) { +#if !defined(QT_NO_XRENDER) if (useArgbVisual) { // Check to make sure the visual provided by EGL is ARGB XRenderPictFormat *format; @@ -312,8 +313,9 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, nativeVisualId, (int)qeglCtx->config()); vi.visualid = 0; } - } - else { + } else +#endif + { qDebug("Using opaque X Visual ID (%d) provided by EGL", (int)vi.visualid); vi = *chosenVisualInfo; } -- cgit v0.12 From f9f91a3ce45bb3ae0d1e47337791eaf373a0e734 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Fri, 31 Jul 2009 17:33:39 +0200 Subject: Make QEglProperties::setVisualFormat() read alpha for visual Reviewed-by: Trustme --- src/gui/egl/qegl_x11.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp index be89efe..daaa4ba 100644 --- a/src/gui/egl/qegl_x11.cpp +++ b/src/gui/egl/qegl_x11.cpp @@ -125,7 +125,17 @@ void QEglProperties::setVisualFormat(const QX11Info *xinfo) setValue(EGL_RED_SIZE, countBits(visual->red_mask)); setValue(EGL_GREEN_SIZE, countBits(visual->green_mask)); setValue(EGL_BLUE_SIZE, countBits(visual->blue_mask)); - setValue(EGL_ALPHA_SIZE, 0); // XXX + + EGLint alphaBits = 0; +#if !defined(QT_NO_XRENDER) + XRenderPictFormat *format; + format = XRenderFindVisualFormat(xinfo->display(), visual); + if (format && (format->type == PictTypeDirect) && format->direct.alphaMask) { + alphaBits = countBits(format->direct.alphaMask); + qDebug("QEglProperties::setVisualFormat() - visual's alphaMask is %d", alphaBits); + } +#endif + setValue(EGL_ALPHA_SIZE, alphaBits); } extern const QX11Info *qt_x11Info(const QPaintDevice *pd); -- cgit v0.12 From 23045677bc466b91619495809c97001f341a3d6c Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Mon, 3 Aug 2009 11:45:27 +0200 Subject: Add a constructor to QEglProperties which takes an EGLConfig The constructor then extracts all the attributes from the config. Useful for dumping all the attributes for a particular config to qDebug(). --- src/gui/egl/qeglproperties.cpp | 14 ++++++++++++++ src/gui/egl/qeglproperties_p.h | 1 + 2 files changed, 15 insertions(+) diff --git a/src/gui/egl/qeglproperties.cpp b/src/gui/egl/qeglproperties.cpp index e0ae8a6..fefd070 100644 --- a/src/gui/egl/qeglproperties.cpp +++ b/src/gui/egl/qeglproperties.cpp @@ -46,12 +46,26 @@ QT_BEGIN_NAMESPACE #include #include +#include "qegl_p.h" + + // Initialize a property block. QEglProperties::QEglProperties() { props.append(EGL_NONE); } +QEglProperties::QEglProperties(EGLConfig cfg) +{ + props.append(EGL_NONE); + for (int name = 0x3020; name <= 0x304F; ++name) { + EGLint value; + if (name != EGL_NONE && eglGetConfigAttrib(QEglContext::defaultDisplay(0), cfg, name, &value)) + setValue(name, value); + } + eglGetError(); // Clear the error state. +} + // Fetch the current value associated with a property. int QEglProperties::value(int name) const { diff --git a/src/gui/egl/qeglproperties_p.h b/src/gui/egl/qeglproperties_p.h index 81af4cd..bcdc657 100644 --- a/src/gui/egl/qeglproperties_p.h +++ b/src/gui/egl/qeglproperties_p.h @@ -107,6 +107,7 @@ class Q_GUI_EXPORT QEglProperties { public: QEglProperties(); + QEglProperties(EGLConfig); QEglProperties(const QEglProperties& other) : props(other.props) {} ~QEglProperties() {} -- cgit v0.12 From 1b469ac64cf81476436009aef66009c30335a01c Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Mon, 3 Aug 2009 11:54:33 +0200 Subject: Add EGL_BIND_TO_TEXTURE_RGBA to QEglProperties::reduceConfiguration() Now reduceConfiguration will add a new step of reduction which removes EGL_BIND_TO_TEXTURE_RGBA and replaces it with EGL_BIND_TO_TEXTURE_RGB. --- src/gui/egl/qeglproperties.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/gui/egl/qeglproperties.cpp b/src/gui/egl/qeglproperties.cpp index fefd070..358ebcc 100644 --- a/src/gui/egl/qeglproperties.cpp +++ b/src/gui/egl/qeglproperties.cpp @@ -229,12 +229,21 @@ bool QEglProperties::reduceConfiguration() removeValue(EGL_SAMPLES); return true; } - if (removeValue(EGL_ALPHA_SIZE)) + if (removeValue(EGL_ALPHA_SIZE)) { +#if defined(EGL_BIND_TO_TEXTURE_RGBA) && defined(EGL_BIND_TO_TEXTURE_RGB) + if (removeValue(EGL_BIND_TO_TEXTURE_RGBA)) + setValue(EGL_BIND_TO_TEXTURE_RGB, TRUE); +#endif return true; + } if (removeValue(EGL_STENCIL_SIZE)) return true; if (removeValue(EGL_DEPTH_SIZE)) return true; +#if defined(EGL_BIND_TO_TEXTURE_RGB) + if (removeValue(EGL_BIND_TO_TEXTURE_RGB)) + return true; +#endif return false; } -- cgit v0.12 From 128717b171f01c82e5f0fb83f5923d4f7b9cfc10 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 31 Jul 2009 17:35:34 +0200 Subject: Remove currentChildBeingDeleted from QObjectPrivate. When a child is being deleted by its parent, the child should not notify the parent (of that which it already knows anyway). We did that by keeping a pointer to the child being deleted. Much simpler to simply orphan the child. Reviewed-by: Bradley T. Hughes --- src/corelib/kernel/qobject.cpp | 29 ++++++++++++----------------- src/corelib/kernel/qobject_p.h | 5 +---- 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index ab91799..7bf209a 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -123,7 +123,7 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *) } QObjectPrivate::QObjectPrivate(int version) - : threadData(0), currentSender(0), currentChildBeingDeleted(0), connectionLists(0), senders(0) + : threadData(0), currentSender(0), declarativeData(0), connectionLists(0), senders(0) { if (version != QObjectPrivateVersion) qFatal("Cannot mix incompatible Qt libraries"); @@ -1859,12 +1859,13 @@ void QObjectPrivate::deleteChildren() // don't use qDeleteAll as the destructor of the child might // delete siblings for (int i = 0; i < children.count(); ++i) { - currentChildBeingDeleted = children.at(i); + QObject *child = children.at(i); children[i] = 0; - delete currentChildBeingDeleted; + if (child) + child->d_func()->parent = 0; + delete child; } children.clear(); - currentChildBeingDeleted = 0; wasDeleted = reallyWasDeleted; } @@ -1875,20 +1876,14 @@ void QObjectPrivate::setParent_helper(QObject *o) return; if (parent) { QObjectPrivate *parentD = parent->d_func(); - if (parentD->wasDeleted && wasDeleted - && parentD->currentChildBeingDeleted == q) { - // don't do anything since QObjectPrivate::deleteChildren() already - // cleared our entry in parentD->children. + const int index = parentD->children.indexOf(q); + if (parentD->wasDeleted) { + parentD->children[index] = 0; } else { - const int index = parentD->children.indexOf(q); - if (parentD->wasDeleted) { - parentD->children[index] = 0; - } else { - parentD->children.removeAt(index); - if (sendChildEvents && parentD->receiveChildEvents) { - QChildEvent e(QEvent::ChildRemoved, q); - QCoreApplication::sendEvent(parent, &e); - } + parentD->children.removeAt(index); + if (sendChildEvents && parentD->receiveChildEvents) { + QChildEvent e(QEvent::ChildRemoved, q); + QCoreApplication::sendEvent(parent, &e); } } } diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index e908753..0b41c9a 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -125,10 +125,7 @@ public: // object currently activating the object Sender *currentSender; - union { - QObject *currentChildBeingDeleted; - QDeclarativeData *declarativeData; - }; + QDeclarativeData *declarativeData; bool isSender(const QObject *receiver, const char *signal) const; QObjectList receiverList(const char *signal) const; -- cgit v0.12 From 463df7e4a6dc7c11716e27ca5de9ebeb61940990 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 3 Aug 2009 13:18:36 +0200 Subject: Autotest: disable the pointer-tracking tests in 4.5 The functionality these tests tested was broken in 4.5 and has been disabled. Therefore, these tests simply cannot pass. It's fixed in 4.6. --- tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index a11164f..697473e 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -952,6 +952,7 @@ void tst_QSharedPointer::invalidConstructs_data() "QSharedPointer b;\n" "if (a + b) return;"; +#if QT_VERSION >= 0x040600 // two objects with the same pointer QTest::newRow("same-pointer") << &QTest::QExternalTest::tryRunFail @@ -965,6 +966,7 @@ void tst_QSharedPointer::invalidConstructs_data() << "Data *aData = new Data;\n" "QSharedPointer ptr1 = QSharedPointer(aData);" "ptr1 = QSharedPointer(aData);"; +#endif // any type of cast for unrelated types: // (we have no reinterpret_cast) -- cgit v0.12 From 1f61ac3f28e8d2a765d12dea0f364cdd8082b7e1 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 3 Aug 2009 13:30:03 +0200 Subject: Fixed warnings on phonon/ds9 with mingw (gcc 4) Reviewed-by: Trustme --- src/3rdparty/phonon/ds9/abstractvideorenderer.cpp | 4 ++-- src/3rdparty/phonon/ds9/fakesource.cpp | 2 +- src/3rdparty/phonon/ds9/iodevicereader.cpp | 2 +- src/3rdparty/phonon/ds9/mediagraph.cpp | 8 +++++--- src/3rdparty/phonon/ds9/mediaobject.cpp | 7 ++++--- src/3rdparty/phonon/ds9/qbasefilter.cpp | 7 ++++--- src/3rdparty/phonon/ds9/qmeminputpin.cpp | 7 ++++--- src/3rdparty/phonon/ds9/qpin.cpp | 8 ++++---- src/3rdparty/phonon/ds9/videorenderer_soft.cpp | 6 +++--- 9 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/3rdparty/phonon/ds9/abstractvideorenderer.cpp b/src/3rdparty/phonon/ds9/abstractvideorenderer.cpp index e932e70..a9d0694 100644 --- a/src/3rdparty/phonon/ds9/abstractvideorenderer.cpp +++ b/src/3rdparty/phonon/ds9/abstractvideorenderer.cpp @@ -99,8 +99,8 @@ namespace Phonon m_dstX = m_dstY = 0; if (ratio > 0) { - if (realWidth / realHeight > ratio && scaleMode == Phonon::VideoWidget::FitInView - || realWidth / realHeight < ratio && scaleMode == Phonon::VideoWidget::ScaleAndCrop) { + if ((realWidth / realHeight > ratio && scaleMode == Phonon::VideoWidget::FitInView) + || (realWidth / realHeight < ratio && scaleMode == Phonon::VideoWidget::ScaleAndCrop)) { //the height is correct, let's change the width m_dstWidth = qRound(realHeight * ratio); m_dstX = qRound((realWidth - realHeight * ratio) / 2.); diff --git a/src/3rdparty/phonon/ds9/fakesource.cpp b/src/3rdparty/phonon/ds9/fakesource.cpp index a4d4640..4dce138 100644 --- a/src/3rdparty/phonon/ds9/fakesource.cpp +++ b/src/3rdparty/phonon/ds9/fakesource.cpp @@ -29,7 +29,7 @@ namespace Phonon namespace DS9 { static WAVEFORMATEX g_defaultWaveFormat = {WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0}; - static VIDEOINFOHEADER2 g_defaultVideoInfo = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0, 0, 0, 0, {sizeof(BITMAPINFOHEADER), 1, 1, 1, 0, 0, 0, 0, 0, 0, 0} }; + static VIDEOINFOHEADER2 g_defaultVideoInfo = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0, 0, {0}, 0, {sizeof(BITMAPINFOHEADER), 1, 1, 1, 0, 0, 0, 0, 0, 0, 0} }; static const AM_MEDIA_TYPE g_fakeAudioType = {MEDIATYPE_Audio, MEDIASUBTYPE_PCM, 0, 0, 2, FORMAT_WaveFormatEx, 0, sizeof(WAVEFORMATEX), reinterpret_cast(&g_defaultWaveFormat)}; static const AM_MEDIA_TYPE g_fakeVideoType = {MEDIATYPE_Video, MEDIASUBTYPE_RGB32, TRUE, FALSE, 0, FORMAT_VideoInfo2, 0, sizeof(VIDEOINFOHEADER2), reinterpret_cast(&g_defaultVideoInfo)}; diff --git a/src/3rdparty/phonon/ds9/iodevicereader.cpp b/src/3rdparty/phonon/ds9/iodevicereader.cpp index 38c983b..a885a69 100644 --- a/src/3rdparty/phonon/ds9/iodevicereader.cpp +++ b/src/3rdparty/phonon/ds9/iodevicereader.cpp @@ -167,7 +167,7 @@ namespace Phonon oldSize = currentBufferSize(); } - DWORD bytesRead = qMin(currentBufferSize(), int(length)); + int bytesRead = qMin(currentBufferSize(), int(length)); { QWriteLocker locker(&m_lock); qMemCopy(buffer, m_buffer.data(), bytesRead); diff --git a/src/3rdparty/phonon/ds9/mediagraph.cpp b/src/3rdparty/phonon/ds9/mediagraph.cpp index 31a0622..7b10176 100644 --- a/src/3rdparty/phonon/ds9/mediagraph.cpp +++ b/src/3rdparty/phonon/ds9/mediagraph.cpp @@ -68,6 +68,8 @@ namespace Phonon return ret; } + +/* static HRESULT saveToFile(Graph graph, const QString &filepath) { const WCHAR wszStreamName[] = L"ActiveMovieGraph"; @@ -103,7 +105,7 @@ namespace Phonon return hr; } - +*/ MediaGraph::MediaGraph(MediaObject *mo, short index) : m_graph(CLSID_FilterGraph, IID_IGraphBuilder), @@ -537,7 +539,7 @@ namespace Phonon const QList outputs = BackendNode::pins(filter, PINDIR_OUTPUT); for(int i = 0; i < outputs.count(); ++i) { const OutputPin &pin = outputs.at(i); - if (VFW_E_NOT_CONNECTED == pin->ConnectedTo(inPin.pparam())) { + if (HRESULT(VFW_E_NOT_CONNECTED) == pin->ConnectedTo(inPin.pparam())) { return SUCCEEDED(pin->Connect(newIn, 0)); } } @@ -809,7 +811,7 @@ namespace Phonon for (int i = 0; i < outputs.count(); ++i) { const OutputPin &out = outputs.at(i); InputPin pin; - if (out->ConnectedTo(pin.pparam()) == VFW_E_NOT_CONNECTED) { + if (out->ConnectedTo(pin.pparam()) == HRESULT(VFW_E_NOT_CONNECTED)) { m_decoderPins += out; //unconnected outputs can be decoded outputs } } diff --git a/src/3rdparty/phonon/ds9/mediaobject.cpp b/src/3rdparty/phonon/ds9/mediaobject.cpp index df42011..10782c2 100644 --- a/src/3rdparty/phonon/ds9/mediaobject.cpp +++ b/src/3rdparty/phonon/ds9/mediaobject.cpp @@ -786,15 +786,16 @@ namespace Phonon case Phonon::PausedState: pause(); break; - case Phonon::StoppedState: - stop(); - break; case Phonon::PlayingState: play(); break; case Phonon::ErrorState: setState(Phonon::ErrorState); break; + case Phonon::StoppedState: + default: + stop(); + break; } } } diff --git a/src/3rdparty/phonon/ds9/qbasefilter.cpp b/src/3rdparty/phonon/ds9/qbasefilter.cpp index 95cab92..c950c41 100644 --- a/src/3rdparty/phonon/ds9/qbasefilter.cpp +++ b/src/3rdparty/phonon/ds9/qbasefilter.cpp @@ -92,8 +92,8 @@ namespace Phonon return E_POINTER; } - int nbfetched = 0; - while (nbfetched < int(count) && m_index < m_pins.count()) { + uint nbfetched = 0; + while (nbfetched < count && m_index < m_pins.count()) { IPin *current = m_pins[m_index]; current->AddRef(); ret[nbfetched] = current; @@ -211,7 +211,8 @@ namespace Phonon } else if (iid == IID_IMediaPosition || iid == IID_IMediaSeeking) { if (inputPins().isEmpty()) { - if (*out = getUpStreamInterface(iid)) { + *out = getUpStreamInterface(iid); + if (*out) { return S_OK; //we return here to avoid adding a reference } else { hr = E_NOINTERFACE; diff --git a/src/3rdparty/phonon/ds9/qmeminputpin.cpp b/src/3rdparty/phonon/ds9/qmeminputpin.cpp index dca99db..865b8af 100644 --- a/src/3rdparty/phonon/ds9/qmeminputpin.cpp +++ b/src/3rdparty/phonon/ds9/qmeminputpin.cpp @@ -137,7 +137,8 @@ namespace Phonon return E_POINTER; } - if (*alloc = memoryAllocator(true)) { + *alloc = memoryAllocator(true); + if (*alloc) { return S_OK; } @@ -294,7 +295,7 @@ namespace Phonon LONG length = sample->GetActualDataLength(); HRESULT hr = alloc->Commit(); - if (hr == VFW_E_SIZENOTSET) { + if (hr == HRESULT(VFW_E_SIZENOTSET)) { ALLOCATOR_PROPERTIES prop = getDefaultAllocatorProperties(); prop.cbBuffer = qMax(prop.cbBuffer, length); ALLOCATOR_PROPERTIES actual; @@ -324,7 +325,7 @@ namespace Phonon { LONGLONG start, end; hr = sample->GetMediaTime(&start, &end); - if (hr != VFW_E_MEDIA_TIME_NOT_SET) { + if (hr != HRESULT(VFW_E_MEDIA_TIME_NOT_SET)) { hr = out->SetMediaTime(&start, &end); Q_ASSERT(SUCCEEDED(hr)); } diff --git a/src/3rdparty/phonon/ds9/qpin.cpp b/src/3rdparty/phonon/ds9/qpin.cpp index 68a4ec0..d14876b 100644 --- a/src/3rdparty/phonon/ds9/qpin.cpp +++ b/src/3rdparty/phonon/ds9/qpin.cpp @@ -91,8 +91,8 @@ namespace Phonon return E_INVALIDARG; } - int nbFetched = 0; - while (nbFetched < int(count) && m_index < m_pin->mediaTypes().count()) { + uint nbFetched = 0; + while (nbFetched < count && m_index < m_pin->mediaTypes().count()) { //the caller will deallocate the memory *out = static_cast(::CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE))); const AM_MEDIA_TYPE original = m_pin->mediaTypes().at(m_index); @@ -145,9 +145,9 @@ namespace Phonon QPin::QPin(QBaseFilter *parent, PIN_DIRECTION dir, const QVector &mt) : - m_memAlloc(0), m_parent(parent), m_refCount(1), m_connected(0), + m_parent(parent), m_flushing(false), m_refCount(1), m_connected(0), m_direction(dir), m_mediaTypes(mt), m_connectedType(defaultMediaType), - m_flushing(false) + m_memAlloc(0) { Q_ASSERT(m_parent); m_parent->addPin(this); diff --git a/src/3rdparty/phonon/ds9/videorenderer_soft.cpp b/src/3rdparty/phonon/ds9/videorenderer_soft.cpp index 2112267..cf5ce96 100644 --- a/src/3rdparty/phonon/ds9/videorenderer_soft.cpp +++ b/src/3rdparty/phonon/ds9/videorenderer_soft.cpp @@ -194,8 +194,8 @@ namespace Phonon m_sampleBuffer = ComPointer(); #ifndef QT_NO_OPENGL freeGLResources(); -#endif // QT_NO_OPENGL m_textureUploaded = false; +#endif // QT_NO_OPENGL } void endOfStream() @@ -314,7 +314,6 @@ namespace Phonon REFERENCE_TIME m_start; HANDLE m_renderEvent, m_receiveCanWait; // Signals sample to render QSize m_size; - bool m_textureUploaded; //mixer settings qreal m_brightness, @@ -356,6 +355,7 @@ namespace Phonon bool m_checkedPrograms; bool m_usingOpenGL; + bool m_textureUploaded; GLuint m_program[2]; GLuint m_texture[3]; #endif @@ -436,7 +436,7 @@ namespace Phonon QBaseFilter(CLSID_NULL), m_inputPin(new VideoRendererSoftPin(this)), m_renderer(renderer), m_start(0) #ifndef QT_NO_OPENGL - ,m_usingOpenGL(false), m_checkedPrograms(false), m_textureUploaded(false) + , m_checkedPrograms(false), m_usingOpenGL(false), m_textureUploaded(false) #endif { m_renderEvent = ::CreateEvent(0, 0, 0, 0); -- cgit v0.12 From dd9bedfd5e2098781faea8fdebc919d65858f13c Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Mon, 3 Aug 2009 13:32:29 +0200 Subject: Warning -- Reviewed-by: TrustMe --- src/svg/qsvgstyle.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/svg/qsvgstyle.cpp b/src/svg/qsvgstyle.cpp index 3682f47..6ed3dc2 100644 --- a/src/svg/qsvgstyle.cpp +++ b/src/svg/qsvgstyle.cpp @@ -206,8 +206,8 @@ QSvgFontStyle::QSvgFontStyle(QSvgFont *font, QSvgTinyDocument *doc) } QSvgFontStyle::QSvgFontStyle() - : m_doc(0) - , m_svgFont(0) + : m_svgFont(0) + , m_doc(0) , m_familySet(0) , m_sizeSet(0) , m_styleSet(0) -- cgit v0.12 From a7b422e7ea439f4ca4eb7159fa33f679311b4fe2 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Mon, 3 Aug 2009 13:40:56 +0200 Subject: Fix compilation and warning Reviewed-by: TrustMe --- demos/sub-attaq/custompropertyanimation.cpp | 2 +- demos/sub-attaq/states.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/demos/sub-attaq/custompropertyanimation.cpp b/demos/sub-attaq/custompropertyanimation.cpp index 9282f42..27a4eba 100644 --- a/demos/sub-attaq/custompropertyanimation.cpp +++ b/demos/sub-attaq/custompropertyanimation.cpp @@ -96,7 +96,7 @@ void CustomPropertyAnimation::updateState(QAbstractAnimation::State oldState, QA setKeyValues(values); } - if (animProp && !startValue().isValid() && currentTime() == 0 + if ((animProp && !startValue().isValid() && currentTime() == 0) || (currentTime() == duration() && currentLoop() == (loopCount() - 1))) { setStartValue(def); } diff --git a/demos/sub-attaq/states.cpp b/demos/sub-attaq/states.cpp index d63737f..d6c0b5a 100644 --- a/demos/sub-attaq/states.cpp +++ b/demos/sub-attaq/states.cpp @@ -269,9 +269,10 @@ void UpdateScoreState::onEntry(QEvent *e) /** Win transition */ UpdateScoreTransition::UpdateScoreTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target) - : QSignalTransition(scene,SIGNAL(subMarineDestroyed(int)), QList() << target), + : QSignalTransition(scene,SIGNAL(subMarineDestroyed(int))), game(game), scene(scene) { + setTargetState(target); } bool UpdateScoreTransition::eventTest(QEvent *event) @@ -288,9 +289,10 @@ bool UpdateScoreTransition::eventTest(QEvent *event) /** Win transition */ WinTransition::WinTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target) - : QSignalTransition(scene,SIGNAL(allSubMarineDestroyed(int)), QList() << target), + : QSignalTransition(scene,SIGNAL(allSubMarineDestroyed(int))), game(game), scene(scene) { + setTargetState(target); } bool WinTransition::eventTest(QEvent *event) -- cgit v0.12 From ac55107752934d6a036474e17530492ae3c0a632 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 31 Jul 2009 21:45:59 +0200 Subject: Autotest: add a way to ensure that there are no safety-check pointers leaking In the future, it would be nice to split the autotest in multiple functions at every check(). --- src/corelib/tools/qsharedpointer.cpp | 23 ++++++++++++- tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 42 ++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 59dfffe..2ca612e 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -897,6 +897,7 @@ QT_BEGIN_NAMESPACE namespace QtSharedPointer { Q_CORE_EXPORT void internalSafetyCheckAdd(const volatile void *); Q_CORE_EXPORT void internalSafetyCheckRemove(const volatile void *); + Q_AUTOTEST_EXPORT void internalSafetyCheckCleanCheck(); } /*! @@ -961,6 +962,7 @@ void QtSharedPointer::internalSafetyCheckAdd2(const void *d_ptr, const volatile kp->dPointers.insert(d_ptr, data); kp->dataPointers.insert(ptr, d_ptr); + Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size()); } /*! @@ -985,10 +987,29 @@ void QtSharedPointer::internalSafetyCheckRemove2(const void *d_ptr) Q_ASSERT(it2 != kp->dataPointers.end()); //qDebug("Removing d=%p value=%p", d_ptr, it->pointer); - + // remove entries kp->dataPointers.erase(it2); kp->dPointers.erase(it); + Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size()); +} + +/*! + \internal + Called by the QSharedPointer autotest +*/ +void QtSharedPointer::internalSafetyCheckCleanCheck() +{ +# ifdef QT_BUILD_INTERNAL + KnownPointers *const kp = knownPointers(); + Q_ASSERT_X(kp, "internalSafetyCheckSelfCheck()", "Called after global statics deletion!"); + + if (kp->dPointers.size() != kp->dataPointers.size()) + qFatal("Internal consistency error: the number of pointers is not equal!"); + + if (!kp->dPointers.isEmpty()) + qFatal("Pointer cleaning failed: %d entries remaining", kp->dPointers.size()); +# endif } QT_END_NAMESPACE diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index e001eab..74f4507 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -44,6 +44,10 @@ #include "externaltests.h" #include +namespace QtSharedPointer { + Q_CORE_EXPORT void internalSafetyCheckCleanCheck(); +} + class tst_QSharedPointer: public QObject { Q_OBJECT @@ -71,6 +75,12 @@ private slots: void validConstructs(); void invalidConstructs_data(); void invalidConstructs(); + +public slots: + void cleanup() { check(); } + +public: + inline void check() { QtSharedPointer::internalSafetyCheckCleanCheck(); } }; class Data @@ -496,6 +506,7 @@ void tst_QSharedPointer::objectCast() QVERIFY(ptr == data); #endif } + check(); { const OtherObject *data = new OtherObject; @@ -523,6 +534,7 @@ void tst_QSharedPointer::objectCast() QVERIFY(ptr == data); #endif } + check(); { OtherObject *data = new OtherObject; @@ -564,6 +576,7 @@ void tst_QSharedPointer::objectCast() QVERIFY(otherptr.isNull()); #endif } + check(); } void tst_QSharedPointer::differentPointers() @@ -583,6 +596,7 @@ void tst_QSharedPointer::differentPointers() QVERIFY(baseptr == aData); QVERIFY(baseptr == aBase); } + check(); { DiffPtrDerivedData *aData = new DiffPtrDerivedData; @@ -597,6 +611,7 @@ void tst_QSharedPointer::differentPointers() QVERIFY(ptr == aBase); QVERIFY(baseptr == aData); } + check(); { DiffPtrDerivedData *aData = new DiffPtrDerivedData; @@ -613,6 +628,7 @@ void tst_QSharedPointer::differentPointers() QVERIFY(baseptr == aData); QVERIFY(baseptr == aBase); } + check(); } void tst_QSharedPointer::virtualBaseDifferentPointers() @@ -632,6 +648,7 @@ void tst_QSharedPointer::virtualBaseDifferentPointers() QVERIFY(baseptr == aData); QVERIFY(baseptr == aBase); } + check(); { VirtualDerived *aData = new VirtualDerived; @@ -648,6 +665,7 @@ void tst_QSharedPointer::virtualBaseDifferentPointers() QVERIFY(baseptr == aData); QVERIFY(baseptr == aBase); } + check(); } #ifndef QTEST_NO_RTTI @@ -814,6 +832,7 @@ void tst_QSharedPointer::constCorrectness() ptr = cvptr.constCast(); #endif } + check(); { Data *aData = new Data; @@ -827,6 +846,7 @@ void tst_QSharedPointer::constCorrectness() QCOMPARE(cptr.data(), aData); QCOMPARE(cptr.operator->(), aData); } + check(); } static int customDeleterFnCallCount; @@ -855,11 +875,13 @@ void tst_QSharedPointer::customDeleter() QSharedPointer ptr2(new Data, &Data::alsoDelete); QSharedPointer ptr3(new Data, &Data::virtualDelete); } + check(); { QSharedPointer ptr(new DerivedData, &Data::doDelete); QSharedPointer ptr2(new DerivedData, &Data::alsoDelete); QSharedPointer ptr3(new DerivedData, &Data::virtualDelete); } + check(); customDeleterFnCallCount = 0; { @@ -868,6 +890,7 @@ void tst_QSharedPointer::customDeleter() QCOMPARE(customDeleterFnCallCount, 0); } QCOMPARE(customDeleterFnCallCount, 1); + check(); customDeleterFnCallCount = 0; { @@ -877,6 +900,7 @@ void tst_QSharedPointer::customDeleter() QCOMPARE(customDeleterFnCallCount, 1); } QCOMPARE(customDeleterFnCallCount, 1); + check(); customDeleterFnCallCount = 0; { @@ -886,6 +910,7 @@ void tst_QSharedPointer::customDeleter() QCOMPARE(customDeleterFnCallCount, 1); } QCOMPARE(customDeleterFnCallCount, 1); + check(); customDeleterFnCallCount = 0; { @@ -894,6 +919,7 @@ void tst_QSharedPointer::customDeleter() QCOMPARE(customDeleterFnCallCount, 0); } QCOMPARE(customDeleterFnCallCount, 1); + check(); customDeleterFnCallCount = 0; { @@ -902,6 +928,7 @@ void tst_QSharedPointer::customDeleter() QCOMPARE(customDeleterFnCallCount, 0); } QCOMPARE(customDeleterFnCallCount, 1); + check(); customDeleterFnCallCount = 0; { @@ -914,6 +941,7 @@ void tst_QSharedPointer::customDeleter() QCOMPARE(customDeleterFnCallCount, 0); } QCOMPARE(customDeleterFnCallCount, 1); + check(); customDeleterFnCallCount = 0; { @@ -926,6 +954,7 @@ void tst_QSharedPointer::customDeleter() QCOMPARE(customDeleterFnCallCount, 0); } QCOMPARE(customDeleterFnCallCount, 1); + check(); CustomDeleter dataDeleter; dataDeleter.callCount = 0; @@ -935,6 +964,7 @@ void tst_QSharedPointer::customDeleter() QCOMPARE(dataDeleter.callCount, 0); } QCOMPARE(dataDeleter.callCount, 1); + check(); dataDeleter.callCount = 0; { @@ -944,6 +974,7 @@ void tst_QSharedPointer::customDeleter() QCOMPARE(dataDeleter.callCount, 0); } QCOMPARE(dataDeleter.callCount, 1); + check(); dataDeleter.callCount = 0; { @@ -956,6 +987,7 @@ void tst_QSharedPointer::customDeleter() QCOMPARE(dataDeleter.callCount, 0); } QCOMPARE(dataDeleter.callCount, 1); + check(); dataDeleter.callCount = 0; { @@ -964,6 +996,7 @@ void tst_QSharedPointer::customDeleter() QCOMPARE(dataDeleter.callCount, 0); } QCOMPARE(dataDeleter.callCount, 1); + check(); CustomDeleter derivedDataDeleter; derivedDataDeleter.callCount = 0; @@ -976,6 +1009,7 @@ void tst_QSharedPointer::customDeleter() } QCOMPARE(dataDeleter.callCount, 0); QCOMPARE(derivedDataDeleter.callCount, 1); + check(); derivedDataDeleter.callCount = 0; dataDeleter.callCount = 0; @@ -992,6 +1026,7 @@ void tst_QSharedPointer::customDeleter() } QCOMPARE(dataDeleter.callCount, 1); QCOMPARE(derivedDataDeleter.callCount, 0); + check(); derivedDataDeleter.callCount = 0; dataDeleter.callCount = 0; @@ -1025,6 +1060,7 @@ void tst_QSharedPointer::creating() ptr.clear(); QCOMPARE(Data::destructorCounter, 1); } + check(); Data::generationCounter = Data::destructorCounter = 0; { @@ -1040,6 +1076,7 @@ void tst_QSharedPointer::creating() QVERIFY(d->weakref == 1); QVERIFY(d->strongref == 0); } + check(); Data::generationCounter = Data::destructorCounter = 0; DerivedData::derivedDestructorCounter = 0; @@ -1052,6 +1089,7 @@ void tst_QSharedPointer::creating() QCOMPARE(Data::destructorCounter, 1); QCOMPARE(DerivedData::derivedDestructorCounter, 1); } + check(); { QSharedPointer ptr = QSharedPointer::create(); @@ -1060,6 +1098,7 @@ void tst_QSharedPointer::creating() QCOMPARE(ptr.staticCast()->buffer[3]+0, 16-3); QCOMPARE(ptr.staticCast()->buffer[0]+0, 16); } + check(); { QSharedPointer ptr = QSharedPointer::create(); @@ -1069,6 +1108,7 @@ void tst_QSharedPointer::creating() QSharedPointer baseptr = ptr; QCOMPARE(baseptr->classLevel(), 4); } + check(); { QSharedPointer ptr = QSharedPointer::create(); @@ -1079,11 +1119,13 @@ void tst_QSharedPointer::creating() QVERIFY(qptr.isNull()); } + check(); { QSharedPointer ptr = QSharedPointer::create(); QCOMPARE(ptr->metaObject(), &OtherObject::staticMetaObject); } + check(); } void tst_QSharedPointer::validConstructs() -- cgit v0.12 From 9eb370bd519a8648905f8b3b869fac8e8be3ada5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 3 Aug 2009 14:10:00 +0200 Subject: Remove the need for internal API in QSharedPointer. That way, this code can be compiled with an earlier version of Qt and should still work in new ones. Reviewed-by: Trust Me --- src/corelib/tools/qsharedpointer_impl.h | 4 +- tests/auto/qsharedpointer/qsharedpointer.pro | 1 - tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 95 ++++++++++++++---------- 3 files changed, 56 insertions(+), 44 deletions(-) diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index b8f4139..089c479 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -350,9 +350,7 @@ namespace QtSharedPointer { this->value = d && d->strongref ? actual : 0; } -#if defined(QT_BUILD_INTERNAL) - public: -#endif + protected: Data *d; private: diff --git a/tests/auto/qsharedpointer/qsharedpointer.pro b/tests/auto/qsharedpointer/qsharedpointer.pro index 90fde06..30c81cb 100644 --- a/tests/auto/qsharedpointer/qsharedpointer.pro +++ b/tests/auto/qsharedpointer/qsharedpointer.pro @@ -4,6 +4,5 @@ SOURCES += tst_qsharedpointer.cpp \ forwarddeclared.cpp QT = core DEFINES += SRCDIR=\\\"$$PWD/\\\" -requires(contains(QT_CONFIG,private_tests)) include(externaltests.pri) HEADERS += forwarddeclared.h diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index 74f4507..1c2c60f 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -80,8 +80,23 @@ public slots: void cleanup() { check(); } public: - inline void check() { QtSharedPointer::internalSafetyCheckCleanCheck(); } + inline void check() + { +#ifdef QT_BUILD_INTERNAL + QtSharedPointer::internalSafetyCheckCleanCheck(); +#endif + } +}; + +template +class RefCountHack: public Base +{ +public: + using Base::d; }; +template static inline +QtSharedPointer::ExternalRefCountData *refCountData(const Base &b) +{ return static_cast *>(&b)->d; } class Data { @@ -166,8 +181,8 @@ void tst_QSharedPointer::basics() QVERIFY(! (ptr == otherData)); QVERIFY(! (otherData == ptr)); } - QVERIFY(!ptr.d || ptr.d->weakref == 1); - QVERIFY(!ptr.d || ptr.d->strongref == 1); + QVERIFY(!refCountData(ptr) || refCountData(ptr)->weakref == 1); + QVERIFY(!refCountData(ptr) || refCountData(ptr)->strongref == 1); { // create another object: @@ -179,8 +194,8 @@ void tst_QSharedPointer::basics() // otherData is deleted here } - QVERIFY(!ptr.d || ptr.d->weakref == 1); - QVERIFY(!ptr.d || ptr.d->strongref == 1); + QVERIFY(!refCountData(ptr) || refCountData(ptr)->weakref == 1); + QVERIFY(!refCountData(ptr) || refCountData(ptr)->strongref == 1); { // create a copy: @@ -196,8 +211,8 @@ void tst_QSharedPointer::basics() QCOMPARE(copy.data(), aData); QVERIFY(copy == aData); } - QVERIFY(!ptr.d || ptr.d->weakref == 1); - QVERIFY(!ptr.d || ptr.d->strongref == 1); + QVERIFY(!refCountData(ptr) || refCountData(ptr)->weakref == 1); + QVERIFY(!refCountData(ptr) || refCountData(ptr)->strongref == 1); { // create a weak reference: @@ -228,8 +243,8 @@ void tst_QSharedPointer::basics() QVERIFY(strong == ptr); QCOMPARE(strong.data(), aData); } - QVERIFY(!ptr.d || ptr.d->weakref == 1); - QVERIFY(!ptr.d || ptr.d->strongref == 1); + QVERIFY(!refCountData(ptr) || refCountData(ptr)->weakref == 1); + QVERIFY(!refCountData(ptr) || refCountData(ptr)->strongref == 1); // aData is deleted here } @@ -445,15 +460,15 @@ void tst_QSharedPointer::upCast() QVERIFY(baseptr == derivedptr); QCOMPARE(static_cast(derivedptr.data()), baseptr.data()); } - QCOMPARE(int(baseptr.d->weakref), 1); - QCOMPARE(int(baseptr.d->strongref), 1); + QCOMPARE(int(refCountData(baseptr)->weakref), 1); + QCOMPARE(int(refCountData(baseptr)->strongref), 1); { QWeakPointer derivedptr = qWeakPointerCast(baseptr); QVERIFY(baseptr == derivedptr); } - QCOMPARE(int(baseptr.d->weakref), 1); - QCOMPARE(int(baseptr.d->strongref), 1); + QCOMPARE(int(refCountData(baseptr)->weakref), 1); + QCOMPARE(int(refCountData(baseptr)->strongref), 1); { QWeakPointer weakptr = baseptr; @@ -461,16 +476,16 @@ void tst_QSharedPointer::upCast() QVERIFY(baseptr == derivedptr); QCOMPARE(static_cast(derivedptr.data()), baseptr.data()); } - QCOMPARE(int(baseptr.d->weakref), 1); - QCOMPARE(int(baseptr.d->strongref), 1); + QCOMPARE(int(refCountData(baseptr)->weakref), 1); + QCOMPARE(int(refCountData(baseptr)->strongref), 1); { QSharedPointer derivedptr = baseptr.staticCast(); QVERIFY(baseptr == derivedptr); QCOMPARE(static_cast(derivedptr.data()), baseptr.data()); } - QCOMPARE(int(baseptr.d->weakref), 1); - QCOMPARE(int(baseptr.d->strongref), 1); + QCOMPARE(int(refCountData(baseptr)->weakref), 1); + QCOMPARE(int(refCountData(baseptr)->strongref), 1); } class OtherObject: public QObject @@ -680,8 +695,8 @@ void tst_QSharedPointer::dynamicCast() QCOMPARE(derivedptr.data(), aData); QCOMPARE(static_cast(derivedptr.data()), baseptr.data()); } - QCOMPARE(int(baseptr.d->weakref), 1); - QCOMPARE(int(baseptr.d->strongref), 1); + QCOMPARE(int(refCountData(baseptr)->weakref), 1); + QCOMPARE(int(refCountData(baseptr)->strongref), 1); { QWeakPointer weakptr = baseptr; @@ -690,8 +705,8 @@ void tst_QSharedPointer::dynamicCast() QCOMPARE(derivedptr.data(), aData); QCOMPARE(static_cast(derivedptr.data()), baseptr.data()); } - QCOMPARE(int(baseptr.d->weakref), 1); - QCOMPARE(int(baseptr.d->strongref), 1); + QCOMPARE(int(refCountData(baseptr)->weakref), 1); + QCOMPARE(int(refCountData(baseptr)->strongref), 1); { QSharedPointer derivedptr = baseptr.dynamicCast(); @@ -699,8 +714,8 @@ void tst_QSharedPointer::dynamicCast() QCOMPARE(derivedptr.data(), aData); QCOMPARE(static_cast(derivedptr.data()), baseptr.data()); } - QCOMPARE(int(baseptr.d->weakref), 1); - QCOMPARE(int(baseptr.d->strongref), 1); + QCOMPARE(int(refCountData(baseptr)->weakref), 1); + QCOMPARE(int(refCountData(baseptr)->strongref), 1); } void tst_QSharedPointer::dynamicCastDifferentPointers() @@ -715,8 +730,8 @@ void tst_QSharedPointer::dynamicCastDifferentPointers() QCOMPARE(derivedptr.data(), aData); QCOMPARE(static_cast(derivedptr.data()), baseptr.data()); } - QCOMPARE(int(baseptr.d->weakref), 1); - QCOMPARE(int(baseptr.d->strongref), 1); + QCOMPARE(int(refCountData(baseptr)->weakref), 1); + QCOMPARE(int(refCountData(baseptr)->strongref), 1); { QWeakPointer weakptr = baseptr; @@ -725,8 +740,8 @@ void tst_QSharedPointer::dynamicCastDifferentPointers() QCOMPARE(derivedptr.data(), aData); QCOMPARE(static_cast(derivedptr.data()), baseptr.data()); } - QCOMPARE(int(baseptr.d->weakref), 1); - QCOMPARE(int(baseptr.d->strongref), 1); + QCOMPARE(int(refCountData(baseptr)->weakref), 1); + QCOMPARE(int(refCountData(baseptr)->strongref), 1); { QSharedPointer derivedptr = baseptr.dynamicCast(); @@ -734,8 +749,8 @@ void tst_QSharedPointer::dynamicCastDifferentPointers() QCOMPARE(derivedptr.data(), aData); QCOMPARE(static_cast(derivedptr.data()), baseptr.data()); } - QCOMPARE(int(baseptr.d->weakref), 1); - QCOMPARE(int(baseptr.d->strongref), 1); + QCOMPARE(int(refCountData(baseptr)->weakref), 1); + QCOMPARE(int(refCountData(baseptr)->strongref), 1); { Stuffing *nakedptr = dynamic_cast(baseptr.data()); @@ -760,8 +775,8 @@ void tst_QSharedPointer::dynamicCastVirtualBase() QCOMPARE(derivedptr.data(), aData); QCOMPARE(static_cast(derivedptr.data()), baseptr.data()); } - QCOMPARE(int(baseptr.d->weakref), 1); - QCOMPARE(int(baseptr.d->strongref), 1); + QCOMPARE(int(refCountData(baseptr)->weakref), 1); + QCOMPARE(int(refCountData(baseptr)->strongref), 1); { QWeakPointer weakptr = baseptr; @@ -770,8 +785,8 @@ void tst_QSharedPointer::dynamicCastVirtualBase() QCOMPARE(derivedptr.data(), aData); QCOMPARE(static_cast(derivedptr.data()), baseptr.data()); } - QCOMPARE(int(baseptr.d->weakref), 1); - QCOMPARE(int(baseptr.d->strongref), 1); + QCOMPARE(int(refCountData(baseptr)->weakref), 1); + QCOMPARE(int(refCountData(baseptr)->strongref), 1); { QSharedPointer derivedptr = baseptr.dynamicCast(); @@ -779,8 +794,8 @@ void tst_QSharedPointer::dynamicCastVirtualBase() QCOMPARE(derivedptr.data(), aData); QCOMPARE(static_cast(derivedptr.data()), baseptr.data()); } - QCOMPARE(int(baseptr.d->weakref), 1); - QCOMPARE(int(baseptr.d->strongref), 1); + QCOMPARE(int(refCountData(baseptr)->weakref), 1); + QCOMPARE(int(refCountData(baseptr)->strongref), 1); } void tst_QSharedPointer::dynamicCastFailure() @@ -792,15 +807,15 @@ void tst_QSharedPointer::dynamicCastFailure() QSharedPointer derivedptr = qSharedPointerDynamicCast(baseptr); QVERIFY(derivedptr.isNull()); } - QCOMPARE(int(baseptr.d->weakref), 1); - QCOMPARE(int(baseptr.d->strongref), 1); + QCOMPARE(int(refCountData(baseptr)->weakref), 1); + QCOMPARE(int(refCountData(baseptr)->strongref), 1); { QSharedPointer derivedptr = baseptr.dynamicCast(); QVERIFY(derivedptr.isNull()); } - QCOMPARE(int(baseptr.d->weakref), 1); - QCOMPARE(int(baseptr.d->strongref), 1); + QCOMPARE(int(refCountData(baseptr)->weakref), 1); + QCOMPARE(int(refCountData(baseptr)->strongref), 1); } #endif @@ -1066,7 +1081,7 @@ void tst_QSharedPointer::creating() { QSharedPointer ptr = QSharedPointer::create(); QWeakPointer weakptr = ptr; - QtSharedPointer::ExternalRefCountData *d = ptr.d; + QtSharedPointer::ExternalRefCountData *d = refCountData(ptr); ptr.clear(); QVERIFY(ptr.isNull()); -- cgit v0.12 From 788a33f7a061552e3f9e5d2fe6cf7faad516892e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 31 Jul 2009 21:49:24 +0200 Subject: Cleanup old code in QSharedPointer We don't support MSVC 6.0 or MSVC .NET 2002, so all compilers we support can deal with member templates and partial template specialisation. Remove the #ifdef protecting the code that needed it. Also add some comments indicating the sizes of the structures. There is no padding necessary in most cases. Reviewed-By: Trust Me --- src/corelib/tools/qsharedpointer_impl.h | 34 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 089c479..aa71168 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -100,20 +100,22 @@ namespace QtSharedPointer { // used in debug mode to verify the reuse of pointers Q_CORE_EXPORT void internalSafetyCheckAdd2(const void *, const volatile void *); Q_CORE_EXPORT void internalSafetyCheckRemove2(const void *); - + template inline void executeDeleter(T *t, RetVal (Klass:: *memberDeleter)()) { (t->*memberDeleter)(); } template inline void executeDeleter(T *t, Deleter d) { d(t); } + template inline void normalDeleter(T *t) { delete t; } + + // this uses partial template specialization + // the only compilers that didn't support this were MSVC 6.0 and 2002 + template struct RemovePointer; + template struct RemovePointer { typedef T Type; }; + template struct RemovePointer > { typedef T Type; }; + template struct RemovePointer > { typedef T Type; }; - // - // Depending on its template parameter, QSharedPointer derives from either - // QtSharedPointer::InternalRefCount or from QtSharedPointer::ExternalRefCount. - // Both of these classes derive from QtSharedPointer::Basic, which provides common - // operations, - // template class Basic { @@ -168,6 +170,7 @@ namespace QtSharedPointer { virtual inline bool destroy() { return false; } }; + // sizeof(ExternalRefCount) = 12 (32-bit) / 16 (64-bit) template struct CustomDeleter @@ -177,6 +180,9 @@ namespace QtSharedPointer { inline CustomDeleter(T *p, Deleter d) : deleter(d), ptr(p) {} }; + // sizeof(CustomDeleter) = sizeof(Deleter) + sizeof(void*) + // for Deleter = function pointer: 8 (32-bit) / 16 (64-bit) + // for Deleter = PMF: 12 (32-bit) / 24 (64-bit) (GCC) struct ExternalRefCountWithDestroyFn: public ExternalRefCountData { @@ -190,6 +196,7 @@ namespace QtSharedPointer { inline bool destroy() { destroyer(this); return true; } inline void operator delete(void *ptr) { ::operator delete(ptr); } }; + // sizeof(ExternalRefCountWithDestroyFn) = 16 (32-bit) / 24 (64-bit) template struct ExternalRefCountWithCustomDeleter: public ExternalRefCountWithDestroyFn @@ -258,9 +265,9 @@ namespace QtSharedPointer { template class ExternalRefCount: public Basic { - typedef ExternalRefCountData Data; - typedef void (*DeleterFunction)(T *); protected: + typedef ExternalRefCountData Data; + inline void ref() const { d->weakref.ref(); d->strongref.ref(); } inline bool deref() { @@ -667,14 +674,6 @@ Q_INLINE_TEMPLATE QSharedPointer qSharedPointerObjectCast(const QWeakPointer< return qSharedPointerObjectCast(src.toStrongRef()); } -# ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION -namespace QtSharedPointer { - template struct RemovePointer; - template struct RemovePointer { typedef T Type; }; - template struct RemovePointer > { typedef T Type; }; - template struct RemovePointer > { typedef T Type; }; -} - template inline QSharedPointer::Type> qobject_cast(const QSharedPointer &src) @@ -687,7 +686,6 @@ qobject_cast(const QWeakPointer &src) { return qSharedPointerObjectCast::Type, T>(src); } -# endif #endif -- cgit v0.12 From 7e0b201285c712a3c98c848033bbd8e5ab75a590 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 1 Aug 2009 01:07:54 +0200 Subject: Don't forget to delete the deleter object too in QSharedPointer. Destructors have to be run for the subobjects we initialise. Reviewed-By: Bradley T. Hughes --- src/corelib/tools/qsharedpointer_impl.h | 3 +++ tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index aa71168..55aeb10 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -210,6 +210,9 @@ namespace QtSharedPointer { { Self *realself = static_cast(self); executeDeleter(realself->extra.ptr, realself->extra.deleter); + + // delete the deleter too + realself->extra.~Next(); } static inline Self *create(T *ptr, Deleter userDeleter) diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index 1c2c60f..481377a 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -871,9 +871,14 @@ void customDeleterFn(Data *ptr) delete ptr; } +static int refcount; + template struct CustomDeleter { + CustomDeleter() { ++refcount; } + CustomDeleter(const CustomDeleter &) { ++refcount; } + ~CustomDeleter() { --refcount; } inline void operator()(T *ptr) { delete ptr; @@ -971,6 +976,7 @@ void tst_QSharedPointer::customDeleter() QCOMPARE(customDeleterFnCallCount, 1); check(); + refcount = 0; CustomDeleter dataDeleter; dataDeleter.callCount = 0; { @@ -979,6 +985,7 @@ void tst_QSharedPointer::customDeleter() QCOMPARE(dataDeleter.callCount, 0); } QCOMPARE(dataDeleter.callCount, 1); + QCOMPARE(refcount, 1); check(); dataDeleter.callCount = 0; @@ -989,6 +996,7 @@ void tst_QSharedPointer::customDeleter() QCOMPARE(dataDeleter.callCount, 0); } QCOMPARE(dataDeleter.callCount, 1); + QCOMPARE(refcount, 1); check(); dataDeleter.callCount = 0; @@ -1002,6 +1010,7 @@ void tst_QSharedPointer::customDeleter() QCOMPARE(dataDeleter.callCount, 0); } QCOMPARE(dataDeleter.callCount, 1); + QCOMPARE(refcount, 1); check(); dataDeleter.callCount = 0; @@ -1011,6 +1020,7 @@ void tst_QSharedPointer::customDeleter() QCOMPARE(dataDeleter.callCount, 0); } QCOMPARE(dataDeleter.callCount, 1); + QCOMPARE(refcount, 1); check(); CustomDeleter derivedDataDeleter; @@ -1024,6 +1034,7 @@ void tst_QSharedPointer::customDeleter() } QCOMPARE(dataDeleter.callCount, 0); QCOMPARE(derivedDataDeleter.callCount, 1); + QCOMPARE(refcount, 2); check(); derivedDataDeleter.callCount = 0; @@ -1041,6 +1052,7 @@ void tst_QSharedPointer::customDeleter() } QCOMPARE(dataDeleter.callCount, 1); QCOMPARE(derivedDataDeleter.callCount, 0); + QCOMPARE(refcount, 2); check(); derivedDataDeleter.callCount = 0; @@ -1058,6 +1070,7 @@ void tst_QSharedPointer::customDeleter() } QCOMPARE(dataDeleter.callCount, 0); QCOMPARE(derivedDataDeleter.callCount, 1); + QCOMPARE(refcount, 2); } void tst_QSharedPointer::creating() -- cgit v0.12 From 1c5cf2e3d6f091593aec237bbb527cb8cdb964c4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 31 Jul 2009 22:10:49 +0200 Subject: Change the pointer-tracking code to work everywhere. Currently, if you create a QSharedPointer in code with pointer-tracking, you must ensure it gets deleted in code with pointer-tracking, otherwise the internal safety tracker will be "leaking" objects. The pointers would never get removed. And if any new pointer happened to have the same pointer address (which happens quite often), the tracker code would promptly abort the application. With this change, the untracking of the pointer is scheduled by the same code that creates the tracking. This is done by "abusing" the custom deleter code: - for the QSharedPointer that used ExternalRefCountWithDestroyFn already, we intercept the call to the destroy function and call the untracking function - for a normal QSharedPointer, we use the "normalDeleter" function as custom deleter and chain up above Note: the autotest only *really* works in release mode. Otherwise functions don't get inlined and do get merged by the linker. Reviewed-By: Bradley T. Hughes --- src/corelib/tools/qsharedpointer_impl.h | 38 +++++++++++---- tests/auto/qsharedpointer/qsharedpointer.pro | 10 +++- tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 22 +++++++++ tests/auto/qsharedpointer/wrapper.cpp | 60 ++++++++++++++++++++++++ tests/auto/qsharedpointer/wrapper.h | 55 ++++++++++++++++++++++ 5 files changed, 173 insertions(+), 12 deletions(-) create mode 100644 tests/auto/qsharedpointer/wrapper.cpp create mode 100644 tests/auto/qsharedpointer/wrapper.h diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 55aeb10..b5daf5d 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -214,10 +214,19 @@ namespace QtSharedPointer { // delete the deleter too realself->extra.~Next(); } + static void safetyCheckDeleter(ExternalRefCountData *self) + { + internalSafetyCheckRemove2(self); + deleter(self); + } static inline Self *create(T *ptr, Deleter userDeleter) { +# ifdef QT_SHAREDPOINTER_TRACK_POINTERS + DestroyerFn destroy = &safetyCheckDeleter; +# else DestroyerFn destroy = &deleter; +# endif Self *d = static_cast(::operator new(sizeof(Self))); // initialize the two sub-objects @@ -244,10 +253,19 @@ namespace QtSharedPointer { static_cast(self); that->data.~T(); } + static void safetyCheckDeleter(ExternalRefCountData *self) + { + internalSafetyCheckRemove2(self); + deleter(self); + } static inline ExternalRefCountData *create(T **ptr) { +# ifdef QT_SHAREDPOINTER_TRACK_POINTERS + DestroyerFn destroy = &safetyCheckDeleter; +# else DestroyerFn destroy = &deleter; +# endif ExternalRefCountWithContiguousData *d = static_cast(::operator new(sizeof(ExternalRefCountWithContiguousData))); @@ -282,32 +300,34 @@ namespace QtSharedPointer { inline void internalConstruct(T *ptr) { - Basic::internalConstruct(ptr); +#ifdef QT_SHAREDPOINTER_TRACK_POINTERS + internalConstruct(ptr, normalDeleter); +#else Q_ASSERT(!d); if (ptr) d = new Data; -#ifdef QT_SHAREDPOINTER_TRACK_POINTERS - if (ptr) internalSafetyCheckAdd2(d, ptr); + internalFinishConstruction(ptr); #endif } template inline void internalConstruct(T *ptr, Deleter deleter) { - Basic::internalConstruct(ptr); Q_ASSERT(!d); if (ptr) d = ExternalRefCountWithCustomDeleter::create(ptr, deleter); -#ifdef QT_SHAREDPOINTER_TRACK_POINTERS - if (ptr) internalSafetyCheckAdd2(d, ptr); -#endif + internalFinishConstruction(ptr); } inline void internalCreate() { T *ptr; d = ExternalRefCountWithContiguousData::create(&ptr); + Basic::internalConstruct(ptr); + } + inline void internalFinishConstruction(T *ptr) + { Basic::internalConstruct(ptr); #ifdef QT_SHAREDPOINTER_TRACK_POINTERS if (ptr) internalSafetyCheckAdd2(d, ptr); @@ -327,9 +347,6 @@ namespace QtSharedPointer { inline void internalDestroy() { -#ifdef QT_SHAREDPOINTER_TRACK_POINTERS - internalSafetyCheckRemove2(d); -#endif if (!d->destroy()) delete this->value; } @@ -450,6 +467,7 @@ public: // now initialize the data new (result.data()) T(); + result.internalFinishConstruction(result.data()); return result; } }; diff --git a/tests/auto/qsharedpointer/qsharedpointer.pro b/tests/auto/qsharedpointer/qsharedpointer.pro index 30c81cb..1759323 100644 --- a/tests/auto/qsharedpointer/qsharedpointer.pro +++ b/tests/auto/qsharedpointer/qsharedpointer.pro @@ -1,8 +1,14 @@ load(qttest_p4) + SOURCES += tst_qsharedpointer.cpp \ forwarddeclaration.cpp \ - forwarddeclared.cpp + forwarddeclared.cpp \ + wrapper.cpp + +HEADERS += forwarddeclared.h \ + wrapper.h + QT = core DEFINES += SRCDIR=\\\"$$PWD/\\\" + include(externaltests.pri) -HEADERS += forwarddeclared.h diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index 481377a..e259e87 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -44,6 +44,8 @@ #include "externaltests.h" #include +#include "wrapper.h" + namespace QtSharedPointer { Q_CORE_EXPORT void internalSafetyCheckCleanCheck(); } @@ -72,6 +74,7 @@ private slots: void constCorrectness(); void customDeleter(); void creating(); + void mixTrackingPointerCode(); void validConstructs(); void invalidConstructs_data(); void invalidConstructs(); @@ -1156,6 +1159,25 @@ void tst_QSharedPointer::creating() check(); } +void tst_QSharedPointer::mixTrackingPointerCode() +{ + { + // pointer created with tracking + // deleted in code without tracking + QSharedPointer ptr = QSharedPointer(new int(42)); + Wrapper w(ptr); + ptr.clear(); + } + check(); + + { + // pointer created without tracking + // deleted in code with tracking + Wrapper w = Wrapper::create(); + w.ptr.clear(); + } +} + void tst_QSharedPointer::validConstructs() { { diff --git a/tests/auto/qsharedpointer/wrapper.cpp b/tests/auto/qsharedpointer/wrapper.cpp new file mode 100644 index 0000000..7640e68 --- /dev/null +++ b/tests/auto/qsharedpointer/wrapper.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifdef QT_SHAREDPOINTER_TRACK_POINTERS +# undef QT_SHAREDPOINTER_TRACK_POINTERS +#endif +#include +#include "wrapper.h" + +Wrapper::Wrapper(const QSharedPointer &value) + : ptr(value) +{ +} + +Wrapper::~Wrapper() +{ +} + +Wrapper Wrapper::create() +{ + return Wrapper(QSharedPointer(new int(-47))); +} diff --git a/tests/auto/qsharedpointer/wrapper.h b/tests/auto/qsharedpointer/wrapper.h new file mode 100644 index 0000000..a888063 --- /dev/null +++ b/tests/auto/qsharedpointer/wrapper.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef WRAPPER_H +#define WRAPPER_H + +template class QSharedPointer; +class Wrapper +{ +public: + QSharedPointer ptr; + Wrapper(const QSharedPointer &); + ~Wrapper(); + + static Wrapper create(); +}; + +#endif // WRAPPER_H -- cgit v0.12 From b969da8cf65bdcc00007415caff2dc69a09257c7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 1 Aug 2009 11:32:50 +0200 Subject: Ensure that we never increase the strong reference count up from zero. Also add some thread stress tests to try and detect doing it wrong. Reviewed-By: Bradley T. Hughes --- src/corelib/tools/qsharedpointer_impl.h | 18 +++- tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 125 ++++++++++++++++++++++- 2 files changed, 138 insertions(+), 5 deletions(-) diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index b5daf5d..9fa8df4 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -364,12 +364,22 @@ namespace QtSharedPointer { inline void internalSet(Data *o, T *actual) { if (d == o) return; - if (o && !o->strongref) - o = 0; if (o) { verifyReconstruction(actual); - o->weakref.ref(); - o->strongref.ref(); + + // increase the strongref, but never up from zero + register int tmp = o->strongref; + while (tmp > 0) { + // try to increment from "tmp" to "tmp + 1" + if (o->strongref.testAndSetRelaxed(tmp, tmp + 1)) + break; // succeeded + tmp = o->strongref; // failed, try again + } + + if (tmp) + o->weakref.ref(); + else + o = 0; } if (d && !deref()) delete d; diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index e259e87..210f3fa 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -41,11 +41,16 @@ #define QT_SHAREDPOINTER_TRACK_POINTERS #include "qsharedpointer.h" -#include "externaltests.h" #include +#include +#include +#include "externaltests.h" #include "wrapper.h" +#include +#include + namespace QtSharedPointer { Q_CORE_EXPORT void internalSafetyCheckCleanCheck(); } @@ -75,6 +80,8 @@ private slots: void customDeleter(); void creating(); void mixTrackingPointerCode(); + void threadStressTest_data(); + void threadStressTest(); void validConstructs(); void invalidConstructs_data(); void invalidConstructs(); @@ -1178,6 +1185,122 @@ void tst_QSharedPointer::mixTrackingPointerCode() } } +class ThreadData +{ + QAtomicInt * volatile ptr; +public: + ThreadData(QAtomicInt *p) : ptr(p) { } + ~ThreadData() { ++ptr; } + void ref() + { + // if we're called after the destructor, we'll crash + ptr->ref(); + } +}; + +class StrongThread: public QThread +{ +protected: + void run() + { + usleep(rand() % 2000); + ptr->ref(); + ptr.clear(); + } +public: + QSharedPointer ptr; +}; + +class WeakThread: public QThread +{ +protected: + void run() + { + usleep(rand() % 2000); + QSharedPointer ptr = weak; + if (ptr) + ptr->ref(); + ptr.clear(); + } +public: + QWeakPointer weak; +}; + +void tst_QSharedPointer::threadStressTest_data() +{ + QTest::addColumn("strongThreadCount"); + QTest::addColumn("weakThreadCount"); + + QTest::newRow("0+0") << 0 << 0; + QTest::newRow("1+0") << 1 << 0; + QTest::newRow("2+0") << 2 << 0; + QTest::newRow("10+0") << 10 << 0; + + QTest::newRow("0+1") << 0 << 1; + QTest::newRow("1+1") << 1 << 1; + + QTest::newRow("2+10") << 2 << 10; + QTest::newRow("5+10") << 5 << 10; + QTest::newRow("5+30") << 5 << 30; + + QTest::newRow("100+100") << 100 << 100; +} + +void tst_QSharedPointer::threadStressTest() +{ + QFETCH(int, strongThreadCount); + QFETCH(int, weakThreadCount); + + int guard1[128]; + QAtomicInt counter; + int guard2[128]; + + memset(guard1, 0, sizeof guard1); + memset(guard2, 0, sizeof guard2); + + for (int r = 0; r < 5; ++r) { + QVector allThreads(6 * qMax(strongThreadCount, weakThreadCount) + 3, 0); + QSharedPointer base = QSharedPointer(new ThreadData(&counter)); + counter = 0; + + // set the pointers + for (int i = 0; i < strongThreadCount; ++i) { + StrongThread *t = new StrongThread; + t->ptr = base; + allThreads[2 * i] = t; + } + for (int i = 0; i < weakThreadCount; ++i) { + WeakThread *t = new WeakThread; + t->weak = base; + allThreads[6 * i + 3] = t; + } + + base.clear(); + + srand(time(NULL)); + // start threads + for (int i = 0; i < allThreads.count(); ++i) + if (allThreads[i]) allThreads[i]->start(); + + // wait for them to finish + for (int i = 0; i < allThreads.count(); ++i) + if (allThreads[i]) allThreads[i]->wait(); + qDeleteAll(allThreads); + + // ensure the guards aren't touched + for (uint i = 0; i < sizeof guard1 / sizeof guard1[0]; ++i) + QVERIFY(!guard1[i]); + for (uint i = 0; i < sizeof guard2 / sizeof guard2[0]; ++i) + QVERIFY(!guard2[i]); + + // verify that the count is the right range + int minValue = strongThreadCount; + int maxValue = strongThreadCount + weakThreadCount; + QVERIFY(counter >= minValue); + QVERIFY(counter <= maxValue); + } +} + void tst_QSharedPointer::validConstructs() { { -- cgit v0.12 From bcbc297dfcf91a4113baa80378c4f4d67c2726d9 Mon Sep 17 00:00:00 2001 From: kh1 Date: Mon, 3 Aug 2009 14:25:53 +0200 Subject: Sync with QtCreator source, add's help startup options. Reviewed-by: kh --- tools/assistant/tools/assistant/centralwidget.cpp | 22 ++++ tools/assistant/tools/assistant/centralwidget.h | 3 +- tools/assistant/tools/assistant/mainwindow.cpp | 2 +- .../tools/assistant/preferencesdialog.cpp | 41 ++++--- .../assistant/tools/assistant/preferencesdialog.h | 12 ++- .../assistant/tools/assistant/preferencesdialog.ui | 118 +++++++++++++++++---- 6 files changed, 158 insertions(+), 40 deletions(-) diff --git a/tools/assistant/tools/assistant/centralwidget.cpp b/tools/assistant/tools/assistant/centralwidget.cpp index 00a8893..23562db 100644 --- a/tools/assistant/tools/assistant/centralwidget.cpp +++ b/tools/assistant/tools/assistant/centralwidget.cpp @@ -43,6 +43,7 @@ #include "helpviewer.h" #include "searchwidget.h" #include "mainwindow.h" +#include "preferencesdialog.h" #include #include @@ -423,6 +424,27 @@ void CentralWidget::setSource(const QUrl &url) tabWidget->setTabText(lastTabPage, quoteTabTitle(viewer->documentTitle())); } +void CentralWidget::setupWidget() +{ + int option = helpEngine->customValue(QLatin1String("StartOption"), + ShowLastPages).toInt(); + + if (option != ShowLastPages) { + QString homePage; + if (option == ShowHomePage) { + homePage = helpEngine->customValue(QLatin1String("defaultHomepage"), + QLatin1String("help")).toString(); + homePage = helpEngine->customValue(QLatin1String("homepage"), + homePage).toString(); + } + if (option == ShowBlankPage) + homePage = QLatin1String("about:blank"); + setSource(homePage); + } else { + setLastShownPages(); + } +} + void CentralWidget::setLastShownPages() { const QLatin1String key("LastShownPages"); diff --git a/tools/assistant/tools/assistant/centralwidget.h b/tools/assistant/tools/assistant/centralwidget.h index ca9caaf..f7ce1d5 100644 --- a/tools/assistant/tools/assistant/centralwidget.h +++ b/tools/assistant/tools/assistant/centralwidget.h @@ -111,7 +111,7 @@ public: CentralWidget(QHelpEngine *engine, MainWindow *parent); ~CentralWidget(); - void setLastShownPages(); + void setupWidget(); bool hasSelection() const; QUrl currentSource() const; QString currentTitle() const; @@ -188,6 +188,7 @@ private: void initPrinter(); QString quoteTabTitle(const QString &title) const; void highlightSearchTerms(); + void setLastShownPages(); private: int lastTabPage; diff --git a/tools/assistant/tools/assistant/mainwindow.cpp b/tools/assistant/tools/assistant/mainwindow.cpp index 0c1723c..bc73b80 100644 --- a/tools/assistant/tools/assistant/mainwindow.cpp +++ b/tools/assistant/tools/assistant/mainwindow.cpp @@ -407,7 +407,7 @@ void MainWindow::insertLastPages() if (m_cmdLine->url().isValid()) m_centralWidget->setSource(m_cmdLine->url()); else - m_centralWidget->setLastShownPages(); + m_centralWidget->setupWidget(); if (m_cmdLine->search() == CmdLineParser::Activate) showSearch(); diff --git a/tools/assistant/tools/assistant/preferencesdialog.cpp b/tools/assistant/tools/assistant/preferencesdialog.cpp index fa70196..2b58c64 100644 --- a/tools/assistant/tools/assistant/preferencesdialog.cpp +++ b/tools/assistant/tools/assistant/preferencesdialog.cpp @@ -146,10 +146,13 @@ PreferencesDialog::~PreferencesDialog() emit updateBrowserFont(); } - if (!m_ui.homePageLineEdit->text().isEmpty()) { - key = QLatin1String("homepage"); - m_helpEngine->setCustomValue(key, m_ui.homePageLineEdit->text()); - } + QString homePage = m_ui.homePageLineEdit->text(); + if (homePage.isEmpty()) + homePage = QLatin1String("help"); + m_helpEngine->setCustomValue(QLatin1String("homepage"), homePage); + + int option = m_ui.helpStartComboBox->currentIndex(); + m_helpEngine->setCustomValue(QLatin1String("StartOption"), option); } void PreferencesDialog::showDialog() @@ -379,6 +382,8 @@ void PreferencesDialog::applyChanges() CentralWidget* widget = CentralWidget::instance(); for (int i = m_TabsToClose.count(); --i >= 0;) widget->closeTabAt(m_TabsToClose.at(i)); + if (widget->availableHelpViewer()== 0) + widget->setSource(QUrl(QLatin1String("about:blank"))); if (m_unregDocs.count()) { foreach (const QString &doc, m_unregDocs) @@ -483,22 +488,23 @@ void PreferencesDialog::updateOptionsPage() homepage = m_helpEngine->customValue(QLatin1String("defaultHomepage"), QLatin1String("help")).toString(); } - m_ui.homePageLineEdit->setText(homepage); - connect(m_ui.currentPageButton, SIGNAL(pressed()), this, - SLOT(currentHomepageChanged())); - connect(m_ui.restoreDefaultHomePageButton, SIGNAL(pressed()), this, - SLOT(restoreDefaultHomepage())); + + int option = m_helpEngine->customValue(QLatin1String("StartOption"), + ShowLastPages).toInt(); + m_ui.helpStartComboBox->setCurrentIndex(option); + + connect(m_ui.blankPageButton, SIGNAL(clicked()), this, SLOT(setBlankPage())); + connect(m_ui.currentPageButton, SIGNAL(clicked()), this, SLOT(setCurrentPage())); + connect(m_ui.defaultPageButton, SIGNAL(clicked()), this, SLOT(setDefaultPage())); } -void PreferencesDialog::restoreDefaultHomepage() +void PreferencesDialog::setBlankPage() { - QString homepage = m_helpEngine->customValue(QLatin1String("defaultHomepage"), - QLatin1String("help")).toString(); - m_ui.homePageLineEdit->setText(homepage); + m_ui.homePageLineEdit->setText(QLatin1String("about:blank")); } -void PreferencesDialog::currentHomepageChanged() +void PreferencesDialog::setCurrentPage() { QString homepage = CentralWidget::instance()->currentSource().toString(); if (homepage.isEmpty()) @@ -507,4 +513,11 @@ void PreferencesDialog::currentHomepageChanged() m_ui.homePageLineEdit->setText(homepage); } +void PreferencesDialog::setDefaultPage() +{ + QString homepage = m_helpEngine->customValue(QLatin1String("defaultHomepage"), + QLatin1String("help")).toString(); + m_ui.homePageLineEdit->setText(homepage); +} + QT_END_NAMESPACE diff --git a/tools/assistant/tools/assistant/preferencesdialog.h b/tools/assistant/tools/assistant/preferencesdialog.h index 5b8ffe8..4471b5f 100644 --- a/tools/assistant/tools/assistant/preferencesdialog.h +++ b/tools/assistant/tools/assistant/preferencesdialog.h @@ -50,6 +50,12 @@ QT_BEGIN_NAMESPACE class FontPanel; class QHelpEngineCore; +enum { + ShowHomePage = 0, + ShowBlankPage = 1, + ShowLastPages = 2 +}; + class PreferencesDialog : public QDialog { Q_OBJECT @@ -72,8 +78,10 @@ private slots: void appFontSettingChanged(int index); void browserFontSettingToggled(bool on); void browserFontSettingChanged(int index); - void restoreDefaultHomepage(); - void currentHomepageChanged(); + + void setBlankPage(); + void setCurrentPage(); + void setDefaultPage(); signals: void updateBrowserFont(); diff --git a/tools/assistant/tools/assistant/preferencesdialog.ui b/tools/assistant/tools/assistant/preferencesdialog.ui index d848b49..279084d 100644 --- a/tools/assistant/tools/assistant/preferencesdialog.ui +++ b/tools/assistant/tools/assistant/preferencesdialog.ui @@ -6,7 +6,7 @@ 0 0 - 359 + 375 266 @@ -187,19 +187,90 @@ Options - + - + - Homepage + - + - + + + + 0 + 0 + + + + On help start: + + + + + + 0 + 0 + + + + + Show my home page + + + + + Show a blank page + + + + + Show my tabs from last session + + + + + + + + Qt::Horizontal + + + + 54 + 20 + + + + + + + + + + + + + + + + + Homepage + + + + + + + + + + + Qt::Horizontal @@ -213,22 +284,25 @@ - - - - - Current Page - - - - - - - Restore to default - - - - + + + Current Page + + + + + + + Blank Page + + + + + + + Restore to default + + -- cgit v0.12 From c1c52b5cd22655999a9abc6bce709e15b598d2c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 3 Aug 2009 14:31:10 +0200 Subject: Preserved fill rule for perspective mapped strokes in raster engine. Task-number: 254407 Reviewed-by: Gunnar --- src/gui/painting/qoutlinemapper.cpp | 2 ++ src/gui/painting/qtransform.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/src/gui/painting/qoutlinemapper.cpp b/src/gui/painting/qoutlinemapper.cpp index 401fad9..d294378 100644 --- a/src/gui/painting/qoutlinemapper.cpp +++ b/src/gui/painting/qoutlinemapper.cpp @@ -225,6 +225,8 @@ void QOutlineMapper::endOutline() } } path = QTransform(m_m11, m_m12, m_m13, m_m21, m_m22, m_m23, m_dx, m_dy, m_m33).map(path); + if (!(m_outline.flags & QT_FT_OUTLINE_EVEN_ODD_FILL)) + path.setFillRule(Qt::WindingFill); uint old_txop = m_txop; m_txop = QTransform::TxNone; if (path.isEmpty()) diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index dcb8947..6a33928 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -1459,6 +1459,7 @@ static QPainterPath mapProjective(const QTransform &transform, const QPainterPat if (path.elementCount() > 0 && lastMoveTo != last) lineTo_clipped(result, transform, last, lastMoveTo, needsMoveTo, false); + result.setFillRule(path.fillRule()); return result; } -- cgit v0.12 From 87432a42fba53ad910e8e21feb94e638f4ae17eb Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Mon, 3 Aug 2009 15:11:13 +0200 Subject: fixed broken integration of qwindowsurface_raster.cpp --- src/gui/painting/qwindowsurface_raster.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qwindowsurface_raster.cpp b/src/gui/painting/qwindowsurface_raster.cpp index 330a33f..eddbfd2 100644 --- a/src/gui/painting/qwindowsurface_raster.cpp +++ b/src/gui/painting/qwindowsurface_raster.cpp @@ -149,7 +149,7 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi QRect br = rgn.boundingRect(); #ifndef Q_WS_WINCE - if (!qt_widget_private(window())->isOpaque && d->canUseLayeredWindow && window()->testAttribute(Qt::WA_TranslucentBackground)) { + if (!qt_widget_private(window())->isOpaque && window()->testAttribute(Qt::WA_TranslucentBackground)) { QRect r = window()->frameGeometry(); QPoint frameOffset = qt_widget_private(window())->frameStrut().topLeft(); QRect dirtyRect = br.translated(offset + frameOffset); -- cgit v0.12 From 6130b2137da4c4aa6f12c2fb4e99ef19ac008781 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Mon, 3 Aug 2009 15:40:55 +0200 Subject: Fix deadlock in the fsevents file watcher. I was making an assumption that one could call CFRunLoopStop and expect that the runloop would stop very soon afterwards. This is a bit naive and can result in situations where we end up running past and entering run again before everything is finished. We now make sure that we don't leave stop() until the we really have stopped the other thread. Reviewed-by: mbm --- src/corelib/io/qfilesystemwatcher_fsevents.cpp | 7 ++++++- src/corelib/io/qfilesystemwatcher_fsevents_p.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.cpp b/src/corelib/io/qfilesystemwatcher_fsevents.cpp index 3e0aee8..cb276b7 100644 --- a/src/corelib/io/qfilesystemwatcher_fsevents.cpp +++ b/src/corelib/io/qfilesystemwatcher_fsevents.cpp @@ -422,9 +422,12 @@ void QFSEventsFileSystemWatcherEngine::fseventsCallback(ConstFSEventStreamRef , void QFSEventsFileSystemWatcherEngine::stop() { #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + QMutexLocker locker(&mutex); stopFSStream(fsStream); - if (threadsRunLoop) + if (threadsRunLoop) { CFRunLoopStop(threadsRunLoop); + waitForStop.wait(&mutex); + } #endif } @@ -461,6 +464,8 @@ void QFSEventsFileSystemWatcherEngine::run() // immediately. CFRunLoopRun(); threadsRunLoop = 0; + QMutexLocker locker(&mutex); + waitForStop.wakeAll(); #endif } diff --git a/src/corelib/io/qfilesystemwatcher_fsevents_p.h b/src/corelib/io/qfilesystemwatcher_fsevents_p.h index 4770867..ffc0c68 100644 --- a/src/corelib/io/qfilesystemwatcher_fsevents_p.h +++ b/src/corelib/io/qfilesystemwatcher_fsevents_p.h @@ -114,6 +114,7 @@ private: CFRunLoopRef threadsRunLoop; QMutex mutex; QWaitCondition waitCondition; + QWaitCondition waitForStop; #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 PathHash filePathInfoHash; PathHash dirPathInfoHash; -- cgit v0.12 From 28f94e1ef94f595bd8fa71005eaf3daf70731f72 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Mon, 3 Aug 2009 15:46:04 +0200 Subject: Wizard background images incorrect in Snow Leopard. We need to clear the QPixmap before the image is drawn using the CGContextDrawImage(). Reviewed-by: Norwegian Rock Cat --- src/gui/image/qpixmap_mac.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/image/qpixmap_mac.cpp b/src/gui/image/qpixmap_mac.cpp index 45392f1..5568898 100644 --- a/src/gui/image/qpixmap_mac.cpp +++ b/src/gui/image/qpixmap_mac.cpp @@ -1178,6 +1178,7 @@ QPixmap QPixmap::fromMacCGImageRef(CGImageRef image) const size_t w = CGImageGetWidth(image), h = CGImageGetHeight(image); QPixmap ret(w, h); + ret.fill(Qt::transparent); CGRect rect = CGRectMake(0, 0, w, h); CGContextRef ctx = qt_mac_cg_context(&ret); qt_mac_drawCGImage(ctx, &rect, image); -- cgit v0.12 From 895757ded9c9b0a07163e84b155ef4c8a623d1a0 Mon Sep 17 00:00:00 2001 From: Morten Sorvig Date: Mon, 3 Aug 2009 15:57:44 +0200 Subject: Fix spelling error. --- config.tests/mac/defaultarch.test | 14 +++++++------- configure | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/config.tests/mac/defaultarch.test b/config.tests/mac/defaultarch.test index 4502af7..80f244a 100755 --- a/config.tests/mac/defaultarch.test +++ b/config.tests/mac/defaultarch.test @@ -3,7 +3,7 @@ COMPILER=$1 VERBOSE=$2 WORKDIR=$3 -QT_MAC_DEFUALT_ARCH= +QT_MAC_DEFAULT_ARCH= touch defaultarch.c @@ -17,17 +17,17 @@ rm -f defaultarch.c defaultarch.o # detect our known archs. if echo "$FIlE_OUTPUT" | grep '\' > /dev/null 2>&1; then - QT_MAC_DEFUALT_ARCH=x86 # configure knows it as "x86" not "i386" + QT_MAC_DEFAULT_ARCH=x86 # configure knows it as "x86" not "i386" fi if echo "$FIlE_OUTPUT" | grep '\' > /dev/null 2>&1; then - QT_MAC_DEFUALT_ARCH=x86_64 + QT_MAC_DEFAULT_ARCH=x86_64 fi if echo "$FIlE_OUTPUT" | grep '\' > /dev/null 2>&1; then - QT_MAC_DEFUALT_ARCH=ppc + QT_MAC_DEFAULT_ARCH=ppc fi if echo "$FIlE_OUTPUT" | grep '\' > /dev/null 2>&1; then - QT_MAC_DEFUALT_ARCH=ppc64 + QT_MAC_DEFAULT_ARCH=ppc64 fi -[ "$VERBOSE" = "yes" ] && echo "setting QT_MAC_DEFUALT_ARCH to \"$QT_MAC_DEFUALT_ARCH\"" -export QT_MAC_DEFUALT_ARCH +[ "$VERBOSE" = "yes" ] && echo "setting QT_MAC_DEFAULT_ARCH to \"$QT_MAC_DEFAULT_ARCH\"" +export QT_MAC_DEFAULT_ARCH diff --git a/configure b/configure index 843d370..2f2e284 100755 --- a/configure +++ b/configure @@ -5712,12 +5712,12 @@ fi if [ "$PLATFORM_MAC" = "yes" ] && [ "$CFG_MAC_ARCHS" == "" ]; then source "$mactests/defaultarch.test" "$TEST_COMPILER" "$OPT_VERBOSE" "$mactests" - if [ "$QT_MAC_DEFUALT_ARCH" == "x86_64" ]; then + if [ "$QT_MAC_DEFAULT_ARCH" == "x86_64" ]; then CFG_MAC_ARCHS=" x86" - elif [ "$QT_MAC_DEFUALT_ARCH" == "ppc64" ]; then + elif [ "$QT_MAC_DEFAULT_ARCH" == "ppc64" ]; then CFG_MAC_ARCHS=" ppc" else - CFG_MAC_ARCHS=" $QT_MAC_DEFUALT_ARCH" + CFG_MAC_ARCHS=" $QT_MAC_DEFAULT_ARCH" fi [ "$OPT_VERBOSE" == "yes" ] && echo "Setting Mac architechture to$CFG_MAC_ARCHS." -- cgit v0.12 From fb622fa47ef81dfa95b9351d87b3415b9e03a368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 3 Aug 2009 15:19:22 +0200 Subject: Fixed some perspective transform rendering bugs. The bugs were caused by not clipping to the near plane (w = 0) when mapping primitives with perspective tranfsorms. Task-id: 258961 Reviewed-by: Gunnar --- src/gui/painting/qdatabuffer_p.h | 17 ------ src/gui/painting/qoutlinemapper.cpp | 67 ++++------------------- src/gui/painting/qpaintengineex.cpp | 106 +++++++++++++++--------------------- src/gui/painting/qtransform.cpp | 47 ++++++++-------- 4 files changed, 82 insertions(+), 155 deletions(-) diff --git a/src/gui/painting/qdatabuffer_p.h b/src/gui/painting/qdatabuffer_p.h index b568f43..275ec13 100644 --- a/src/gui/painting/qdatabuffer_p.h +++ b/src/gui/painting/qdatabuffer_p.h @@ -114,23 +114,6 @@ public: qSwap(buffer, other.buffer); } - inline void insertBlank(int pos, int count) { - Q_ASSERT(pos >= 0); - Q_ASSERT(pos < siz); - reserve(siz + count); - for (int i = siz - pos - 1; i >= 0; --i) - buffer[pos + count + i] = buffer[pos + i]; - siz += count; - } - - inline void removeAndShift(int pos, int count) { - Q_ASSERT(pos >= 0); - Q_ASSERT(pos < siz); - for (int i=pos; i 3) - m_element_types.insertBlank(t, segment.size() - 3); - else if (segment.size() < 3) - m_element_types.removeAndShift(t, 3 - segment.size()); - - for (QPolygonF::const_iterator it = segment.constBegin(); - it < segment.constEnd(); ++it, ++t) { - m_elements_dev << *it * matrix; - m_element_types.at(t) = QPainterPath::LineToElement; - } - i += 2; - } break; - default: - Q_ASSERT(false); - break; - } - } - element_count = m_elements_dev.size(); - } + const QVectorPath vp((qreal *)m_elements.data(), m_elements.size(), m_element_types.data()); + QPainterPath path = vp.convertToPainterPath(); + path = QTransform(m_m11, m_m12, m_m13, m_m21, m_m22, m_m23, m_dx, m_dy, m_m33).map(path); + uint old_txop = m_txop; + m_txop = QTransform::TxNone; + if (path.isEmpty()) + m_valid = false; + else + convertPath(path); + m_txop = old_txop; + return; } elements = m_elements_dev.data(); } if (m_round_coords) { // round coordinates to match outlines drawn with drawLine_midpoint_i - for (int i = 0; i < element_count; ++i) + for (int i = 0; i < m_elements.size(); ++i) elements[i] = QPointF(qFloor(elements[i].x() + aliasedCoordinateDelta), qFloor(elements[i].y() + aliasedCoordinateDelta)); } -#ifdef QT_DEBUG_CONVERT - for (int i=0; iactiveStroker->begin(d->strokeHandler); d->strokeHandler->types.reset(); d->strokeHandler->pts.reset(); @@ -430,13 +429,13 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) if (d->stroker.capStyle() == Qt::RoundCap || d->stroker.joinStyle() == Qt::RoundJoin) flags |= QVectorPath::CurvedShapeHint; - // ### Perspective Xforms are currently not supported... qreal txscale = 1; if (!(pen.isCosmetic() || (qt_scaleForTransform(state()->matrix, &txscale) && txscale != 1))) { // We include cosmetic pens in this case to avoid having to // change the current transform. Normal transformed, // non-cosmetic pens will be transformed as part of fill // later, so they are also covered here.. + d->activeStroker->begin(d->strokeHandler); if (types) { while (points < lastPoint) { switch (*types) { @@ -491,79 +490,64 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) const qreal strokeWidth = d->stroker.strokeWidth(); d->stroker.setStrokeWidth(strokeWidth * txscale); // For cosmetic pens we need a bit of trickery... We to process xform the input points - if (types) { - bool isProject = state()->matrix.type() >= QTransform::TxProject; - while (points < lastPoint) { - switch (*types) { - case QPainterPath::MoveToElement: { - QPointF pt = (*(QPointF *) points) * state()->matrix; - d->activeStroker->moveTo(pt.x(), pt.y()); - points += 2; - ++types; - break; - } - case QPainterPath::LineToElement: { - QPointF pt = (*(QPointF *) points) * state()->matrix; - d->activeStroker->lineTo(pt.x(), pt.y()); - points += 2; - ++types; - break; - } - case QPainterPath::CurveToElement: { - // Convert projective xformed curves to line - // segments so they can be transformed more - // accurately - if (isProject) { - // -1 access here is safe because there is - // always an element prior to the cubicTo, we - // just need the value.. - QPolygonF segment = - QBezier::fromPoints(*(((QPointF *) points) - 1), - *((QPointF *) points), - *(((QPointF *) points) + 1), - *(((QPointF *) points) + 2)).toPolygon(); - - for (QPolygonF::const_iterator it = segment.constBegin(); - it < segment.constEnd(); ++it) { - const QPointF pt = *it * state()->matrix; - d->activeStroker->lineTo(pt.x(), pt.y()); - } - } else { + if (state()->matrix.type() >= QTransform::TxProject) { + QPainterPath painterPath = state()->matrix.map(path.convertToPainterPath()); + d->activeStroker->strokePath(painterPath, d->strokeHandler, QTransform()); + } else { + d->activeStroker->begin(d->strokeHandler); + if (types) { + while (points < lastPoint) { + switch (*types) { + case QPainterPath::MoveToElement: { + QPointF pt = (*(QPointF *) points) * state()->matrix; + d->activeStroker->moveTo(pt.x(), pt.y()); + points += 2; + ++types; + break; + } + case QPainterPath::LineToElement: { + QPointF pt = (*(QPointF *) points) * state()->matrix; + d->activeStroker->lineTo(pt.x(), pt.y()); + points += 2; + ++types; + break; + } + case QPainterPath::CurveToElement: { QPointF c1 = ((QPointF *) points)[0] * state()->matrix; QPointF c2 = ((QPointF *) points)[1] * state()->matrix; QPointF e = ((QPointF *) points)[2] * state()->matrix; d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y()); + points += 6; + types += 3; + flags |= QVectorPath::CurvedShapeHint; + break; + } + default: + break; } - points += 6; - types += 3; - flags |= QVectorPath::CurvedShapeHint; - break; } - default: - break; + if (path.hasImplicitClose()) { + QPointF pt = * ((QPointF *) path.points()) * state()->matrix; + d->activeStroker->lineTo(pt.x(), pt.y()); } - } - if (path.hasImplicitClose()) { - QPointF pt = * ((QPointF *) path.points()) * state()->matrix; - d->activeStroker->lineTo(pt.x(), pt.y()); - } - } else { - QPointF p = ((QPointF *)points)[0] * state()->matrix; - d->activeStroker->moveTo(p.x(), p.y()); - points += 2; - ++types; - while (points < lastPoint) { + } else { QPointF p = ((QPointF *)points)[0] * state()->matrix; - d->activeStroker->lineTo(p.x(), p.y()); + d->activeStroker->moveTo(p.x(), p.y()); points += 2; ++types; + while (points < lastPoint) { + QPointF p = ((QPointF *)points)[0] * state()->matrix; + d->activeStroker->lineTo(p.x(), p.y()); + points += 2; + ++types; + } + if (path.hasImplicitClose()) + d->activeStroker->lineTo(p.x(), p.y()); } - if (path.hasImplicitClose()) - d->activeStroker->lineTo(p.x(), p.y()); + d->activeStroker->end(); } - d->activeStroker->end(); d->stroker.setStrokeWidth(strokeWidth); QVectorPath strokePath(d->strokeHandler->pts.data(), d->strokeHandler->types.size(), diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index a322fe4..0a64e4e 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -48,6 +48,8 @@ #include "qvariant.h" #include +#include + QT_BEGIN_NAMESPACE #define Q_NEAR_CLIP 0.000001 @@ -1492,27 +1494,12 @@ static inline bool lineTo_clipped(QPainterPath &path, const QTransform &transfor static inline bool cubicTo_clipped(QPainterPath &path, const QTransform &transform, const QPointF &a, const QPointF &b, const QPointF &c, const QPointF &d, bool needsMoveTo) { - const QHomogeneousCoordinate ha = mapHomogeneous(transform, a); - const QHomogeneousCoordinate hb = mapHomogeneous(transform, b); - const QHomogeneousCoordinate hc = mapHomogeneous(transform, c); - const QHomogeneousCoordinate hd = mapHomogeneous(transform, d); - - if (ha.w < Q_NEAR_CLIP && hb.w < Q_NEAR_CLIP && hc.w < Q_NEAR_CLIP && hd.w < Q_NEAR_CLIP) - return false; + // Convert projective xformed curves to line + // segments so they can be transformed more accurately + QPolygonF segment = QBezier::fromPoints(a, b, c, d).toPolygon(); - if (ha.w >= Q_NEAR_CLIP && hb.w >= Q_NEAR_CLIP && hc.w >= Q_NEAR_CLIP && hd.w >= Q_NEAR_CLIP) { - if (needsMoveTo) - path.moveTo(ha.toPoint()); - - path.cubicTo(hb.toPoint(), hc.toPoint(), hd.toPoint()); - return true; - } - - if (lineTo_clipped(path, transform, a, b, needsMoveTo)) - needsMoveTo = false; - if (lineTo_clipped(path, transform, b, c, needsMoveTo)) - needsMoveTo = false; - if (lineTo_clipped(path, transform, c, d, needsMoveTo)) + for (int i = 0; i < segment.size() - 1; ++i) + if (lineTo_clipped(path, transform, segment.at(i), segment.at(i+1), needsMoveTo)) needsMoveTo = false; return !needsMoveTo; @@ -1793,6 +1780,14 @@ void QTransform::setMatrix(qreal m11, qreal m12, qreal m13, m_dirty = TxProject; } +static inline bool needsPerspectiveClipping(const QRectF &rect, const QTransform &transform) +{ + const qreal wx = qMin(transform.m13() * rect.left(), transform.m13() * rect.right()); + const qreal wy = qMin(transform.m23() * rect.top(), transform.m23() * rect.bottom()); + + return wx + wy + transform.m33() < Q_NEAR_CLIP; +} + QRect QTransform::mapRect(const QRect &rect) const { TransformationType t = inline_type(); @@ -1813,7 +1808,7 @@ QRect QTransform::mapRect(const QRect &rect) const y -= h; } return QRect(x, y, w, h); - } else { + } else if (t < TxProject || !needsPerspectiveClipping(rect, *this)) { // see mapToPolygon for explanations of the algorithm. qreal x = 0, y = 0; MAP(rect.left(), rect.top(), x, y); @@ -1837,6 +1832,10 @@ QRect QTransform::mapRect(const QRect &rect) const xmax = qMax(xmax, x); ymax = qMax(ymax, y); return QRect(qRound(xmin), qRound(ymin), qRound(xmax)-qRound(xmin), qRound(ymax)-qRound(ymin)); + } else { + QPainterPath path; + path.addRect(rect); + return map(path).boundingRect().toRect(); } } @@ -1879,7 +1878,7 @@ QRectF QTransform::mapRect(const QRectF &rect) const y -= h; } return QRectF(x, y, w, h); - } else { + } else if (t < TxProject || !needsPerspectiveClipping(rect, *this)) { qreal x = 0, y = 0; MAP(rect.x(), rect.y(), x, y); qreal xmin = x; @@ -1902,6 +1901,10 @@ QRectF QTransform::mapRect(const QRectF &rect) const xmax = qMax(xmax, x); ymax = qMax(ymax, y); return QRectF(xmin, ymin, xmax-xmin, ymax - ymin); + } else { + QPainterPath path; + path.addRect(rect); + return map(path).boundingRect(); } } -- cgit v0.12 From 3d5ffba1a183bbe3d930158e87f65f858b78559c Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Mon, 3 Aug 2009 17:18:44 +0200 Subject: Fix compile error on WinCE. Reviewed-by: TrustMe --- src/activeqt/container/qaxwidget.cpp | 4 ++++ src/activeqt/control/qaxserverbase.cpp | 13 ++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/activeqt/container/qaxwidget.cpp b/src/activeqt/container/qaxwidget.cpp index 19f00db..ff6bcb8 100644 --- a/src/activeqt/container/qaxwidget.cpp +++ b/src/activeqt/container/qaxwidget.cpp @@ -985,7 +985,11 @@ HRESULT WINAPI QAxClientSite::TranslateAccelerator(LPMSG lpMsg, DWORD /*grfModif bool ActiveQtDetected = false; bool fromInProcServer = false; +#ifdef GWLP_USERDATA LONG_PTR serverType = GetWindowLongPtr(lpMsg->hwnd, GWLP_USERDATA); +#else + LONG serverType = GetWindowLong(lpMsg->hwnd, GWL_USERDATA); +#endif if (serverType == QAX_INPROC_SERVER) { ActiveQtDetected = true; fromInProcServer = true; diff --git a/src/activeqt/control/qaxserverbase.cpp b/src/activeqt/control/qaxserverbase.cpp index e482c60..e7ddb47 100644 --- a/src/activeqt/control/qaxserverbase.cpp +++ b/src/activeqt/control/qaxserverbase.cpp @@ -3605,15 +3605,26 @@ HRESULT WINAPI QAxServerBase::TranslateAcceleratorW(MSG *pMsg) return S_FALSE; bool resetUserData = false; // set server type in the user-data of the window. +#ifdef GWLP_USERDATA LONG_PTR serverType = QAX_INPROC_SERVER; +#else + LONG serverType = QAX_INPROC_SERVER; +#endif if (qAxOutProcServer) serverType = QAX_OUTPROC_SERVER; +#ifdef GWLP_USERDATA LONG_PTR oldData = SetWindowLongPtr(pMsg->hwnd, GWLP_USERDATA, serverType); +#else + LONG oldData = SetWindowLong(pMsg->hwnd, GWL_USERDATA, serverType); +#endif HRESULT hres = controlSite->TranslateAcceleratorW(pMsg, dwKeyMod); controlSite->Release(); // reset the user-data for the window. +#ifdef GWLP_USERDATA SetWindowLongPtr(pMsg->hwnd, GWLP_USERDATA, oldData); - +#else + SetWindowLong(pMsg->hwnd, GWL_USERDATA, oldData); +#endif return hres; } -- cgit v0.12 From 2076f150995e541308b1d8da936b3e12ab68b886 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 3 Aug 2009 17:20:16 +0200 Subject: Fixed "Hightlighted menu items not always selected" bug. Menu paintEvent was not called when the mouse cursor lied between the menu item area and the menu frame border. Task-number: 258920 Reviewed-by: olivier --- src/gui/widgets/qmenu.cpp | 2 +- tests/auto/qmenu/tst_qmenu.cpp | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 8eec0fc..0b85eec 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -2721,7 +2721,7 @@ void QMenu::mouseMoveEvent(QMouseEvent *e) QAction *action = d->actionAt(e->pos()); if (!action) { - if (d->hasHadMouse && !rect().contains(e->pos())) + if (d->hasHadMouse) d->setCurrentAction(0); return; } else if(e->buttons()) { diff --git a/tests/auto/qmenu/tst_qmenu.cpp b/tests/auto/qmenu/tst_qmenu.cpp index 1d19ffa..ec9c7b4 100644 --- a/tests/auto/qmenu/tst_qmenu.cpp +++ b/tests/auto/qmenu/tst_qmenu.cpp @@ -95,6 +95,7 @@ private slots: void task250673_activeMultiColumnSubMenuPosition(); void task256918_setFont(); void menuSizeHint(); + void task258920_mouseBorder(); protected slots: void onActivated(QAction*); void onHighlighted(QAction*); @@ -763,5 +764,40 @@ void tst_QMenu::menuSizeHint() QCOMPARE(resSize, menu.sizeHint()); } +class Menu258920 : public QMenu +{ + Q_OBJECT +public slots: + void paintEvent(QPaintEvent *e) + { + QMenu::paintEvent(e); + painted = true; + } + +public: + bool painted; +}; + +void tst_QMenu::task258920_mouseBorder() +{ + Menu258920 menu; + QAction *action = menu.addAction("test"); + + menu.popup(QPoint()); + QTest::qWait(100); + QRect actionRect = menu.actionGeometry(action); + QTest::mouseMove(&menu, actionRect.center()); + QTest::qWait(30); + QTest::mouseMove(&menu, actionRect.center() + QPoint(10, 0)); + QTest::qWait(30); + QCOMPARE(action, menu.activeAction()); + menu.painted = false; + QTest::mouseMove(&menu, QPoint(actionRect.center().x(), actionRect.bottom() + 1)); + QTest::qWait(30); + QCOMPARE(static_cast(0), menu.activeAction()); + QVERIFY(menu.painted); +} + + QTEST_MAIN(tst_QMenu) #include "tst_qmenu.moc" -- cgit v0.12 From acc9bc4d9dd3b7a1fef10fe88bfa753e515cdd3e Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Tue, 4 Aug 2009 10:59:02 +1000 Subject: Doc fixes Reviewed-by: TrustMe --- doc/src/properties.qdoc | 2 +- src/corelib/kernel/qabstractitemmodel.cpp | 4 ++++ src/corelib/kernel/qmetaobject.cpp | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/doc/src/properties.qdoc b/doc/src/properties.qdoc index 2d03e91..d0a9ccc 100644 --- a/doc/src/properties.qdoc +++ b/doc/src/properties.qdoc @@ -126,7 +126,7 @@ value is constant. For a given object instance, the READ method of a constant property must return the same value every time it is called. This constant value may be different for different instances of the object. A - constant property cannot have a WRTE method or a NOTIFY signal. + constant property cannot have a WRITE method or a NOTIFY signal. \o The presence of the \c FINAL attribute indicates that the property will not be overridden by a derived class. This can be used for performance diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp index bc95c60..5d5d4cc 100644 --- a/src/corelib/kernel/qabstractitemmodel.cpp +++ b/src/corelib/kernel/qabstractitemmodel.cpp @@ -1884,6 +1884,8 @@ QSize QAbstractItemModel::span(const QModelIndex &) const } /*! + \since 4.6 + Sets the model's role names to \a roleNames. This function is provided to allow mapping of role identifiers to @@ -1900,6 +1902,8 @@ void QAbstractItemModel::setRoleNames(const QHash &roleNames) } /*! + \since 4.6 + Returns the model's role names. \sa setRoleNames() diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 9ff0bc1..d43c5dd 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1352,6 +1352,8 @@ int QMetaMethod::attributes() const } /*! + \since 4.6 + Returns this method's index. */ int QMetaMethod::methodIndex() const @@ -2076,6 +2078,8 @@ int QMetaProperty::userType() const } /*! + \since 4.6 + Returns this property's index. */ int QMetaProperty::propertyIndex() const -- cgit v0.12 From c05a595cde1327edea3a72c6fa13d2351c02805d Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 4 Aug 2009 13:38:51 +1000 Subject: Fix obsolete license headers Reviewed-by: Trust Me --- doc/src/examples/frozencolumn.qdoc | 4 ++-- doc/src/qsqldatatype-table.qdoc | 4 ++-- examples/itemviews/frozencolumn/freezetablewidget.cpp | 4 ++-- examples/itemviews/frozencolumn/freezetablewidget.h | 5 ++--- examples/itemviews/frozencolumn/main.cpp | 5 ++--- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/doc/src/examples/frozencolumn.qdoc b/doc/src/examples/frozencolumn.qdoc index e5a3b59..9d89478 100644 --- a/doc/src/examples/frozencolumn.qdoc +++ b/doc/src/examples/frozencolumn.qdoc @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -34,7 +34,7 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/qsqldatatype-table.qdoc b/doc/src/qsqldatatype-table.qdoc index 5ab6413..60c9dcf 100644 --- a/doc/src/qsqldatatype-table.qdoc +++ b/doc/src/qsqldatatype-table.qdoc @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -34,7 +34,7 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/examples/itemviews/frozencolumn/freezetablewidget.cpp b/examples/itemviews/frozencolumn/freezetablewidget.cpp index 7a9a8df..4326763 100644 --- a/examples/itemviews/frozencolumn/freezetablewidget.cpp +++ b/examples/itemviews/frozencolumn/freezetablewidget.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the examples of the Qt Toolkit. ** @@ -34,7 +34,7 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/examples/itemviews/frozencolumn/freezetablewidget.h b/examples/itemviews/frozencolumn/freezetablewidget.h index 2abae47..f7b8e43 100644 --- a/examples/itemviews/frozencolumn/freezetablewidget.h +++ b/examples/itemviews/frozencolumn/freezetablewidget.h @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the examples of the Qt Toolkit. ** @@ -34,12 +34,11 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ - #ifndef FREEZETABLEWIDGET_H #define FREEZETABLEWIDGET_H diff --git a/examples/itemviews/frozencolumn/main.cpp b/examples/itemviews/frozencolumn/main.cpp index fdefd73..9f6a637 100644 --- a/examples/itemviews/frozencolumn/main.cpp +++ b/examples/itemviews/frozencolumn/main.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the examples of the Qt Toolkit. ** @@ -34,12 +34,11 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ - #include #include #include -- cgit v0.12 From 0b5511f621159a1a0a13650f94811a218e2c126a Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 4 Aug 2009 14:49:14 +1000 Subject: Fix obsolete license headers Reviewed-by: Trust Me --- mkspecs/unsupported/vxworks-ppc-dcc/qplatformdefs.h | 4 ++-- mkspecs/unsupported/vxworks-ppc-g++/qplatformdefs.h | 4 ++-- mkspecs/unsupported/vxworks-simpentium-dcc/qplatformdefs.h | 4 ++-- mkspecs/unsupported/vxworks-simpentium-g++/qplatformdefs.h | 4 ++-- src/corelib/arch/qatomic_vxworks.h | 2 +- src/corelib/kernel/qfunctions_vxworks.cpp | 4 ++-- src/corelib/kernel/qfunctions_vxworks.h | 2 +- src/gui/graphicsview/qgraphicstransform.cpp | 4 ++-- src/gui/widgets/qlinecontrol.cpp | 4 ++-- src/gui/widgets/qlineedit_p.cpp | 4 ++-- 10 files changed, 18 insertions(+), 18 deletions(-) diff --git a/mkspecs/unsupported/vxworks-ppc-dcc/qplatformdefs.h b/mkspecs/unsupported/vxworks-ppc-dcc/qplatformdefs.h index 4b0c24c..a1735d0 100644 --- a/mkspecs/unsupported/vxworks-ppc-dcc/qplatformdefs.h +++ b/mkspecs/unsupported/vxworks-ppc-dcc/qplatformdefs.h @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the qmake spec of the Qt Toolkit. ** @@ -34,7 +34,7 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/mkspecs/unsupported/vxworks-ppc-g++/qplatformdefs.h b/mkspecs/unsupported/vxworks-ppc-g++/qplatformdefs.h index 4b0c24c..a1735d0 100644 --- a/mkspecs/unsupported/vxworks-ppc-g++/qplatformdefs.h +++ b/mkspecs/unsupported/vxworks-ppc-g++/qplatformdefs.h @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the qmake spec of the Qt Toolkit. ** @@ -34,7 +34,7 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/mkspecs/unsupported/vxworks-simpentium-dcc/qplatformdefs.h b/mkspecs/unsupported/vxworks-simpentium-dcc/qplatformdefs.h index 4b0c24c..a1735d0 100644 --- a/mkspecs/unsupported/vxworks-simpentium-dcc/qplatformdefs.h +++ b/mkspecs/unsupported/vxworks-simpentium-dcc/qplatformdefs.h @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the qmake spec of the Qt Toolkit. ** @@ -34,7 +34,7 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/mkspecs/unsupported/vxworks-simpentium-g++/qplatformdefs.h b/mkspecs/unsupported/vxworks-simpentium-g++/qplatformdefs.h index 90eb955..b3eefea 100644 --- a/mkspecs/unsupported/vxworks-simpentium-g++/qplatformdefs.h +++ b/mkspecs/unsupported/vxworks-simpentium-g++/qplatformdefs.h @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the qmake spec of the Qt Toolkit. ** @@ -34,7 +34,7 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/arch/qatomic_vxworks.h b/src/corelib/arch/qatomic_vxworks.h index 573a44d..b441210 100644 --- a/src/corelib/arch/qatomic_vxworks.h +++ b/src/corelib/arch/qatomic_vxworks.h @@ -34,7 +34,7 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/kernel/qfunctions_vxworks.cpp b/src/corelib/kernel/qfunctions_vxworks.cpp index 6d5e7cc..def8f4c 100644 --- a/src/corelib/kernel/qfunctions_vxworks.cpp +++ b/src/corelib/kernel/qfunctions_vxworks.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -34,7 +34,7 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/kernel/qfunctions_vxworks.h b/src/corelib/kernel/qfunctions_vxworks.h index cc98948..e31d495 100644 --- a/src/corelib/kernel/qfunctions_vxworks.h +++ b/src/corelib/kernel/qfunctions_vxworks.h @@ -34,7 +34,7 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/gui/graphicsview/qgraphicstransform.cpp b/src/gui/graphicsview/qgraphicstransform.cpp index 890aff7..778cd94 100644 --- a/src/gui/graphicsview/qgraphicstransform.cpp +++ b/src/gui/graphicsview/qgraphicstransform.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtDeclarative module of the Qt Toolkit. ** @@ -34,7 +34,7 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index 106d8f2..f68d287 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. ** @@ -34,7 +34,7 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/gui/widgets/qlineedit_p.cpp b/src/gui/widgets/qlineedit_p.cpp index 0e39304..f0ec8ad 100644 --- a/src/gui/widgets/qlineedit_p.cpp +++ b/src/gui/widgets/qlineedit_p.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. ** @@ -34,7 +34,7 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ -- cgit v0.12 From 5fb4b30f96679d000086a49a2d25372421193a88 Mon Sep 17 00:00:00 2001 From: Bill King Date: Tue, 4 Aug 2009 14:57:36 +1000 Subject: Fixes failed queries when mysql auto-prepares Queries like "Show Index" etc, fail on mysql when automatically prepared due to a bug in several versions of mysql. Basically anything but a select query will fail. This fixes this by making the user explicitly prepare the query if they want to, and the blame then falls on them if they try and prepare a statement likely to fail. This fix also seems to result in a speedup for single-execution queries, possibly due to reduction in roundtrip communications. All autotests pass & behaviour conforms to documentation. Task-number: 252450, 246125 --- src/sql/drivers/mysql/qsql_mysql.cpp | 47 ++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp index bd6f7b9..39ef1ef 100644 --- a/src/sql/drivers/mysql/qsql_mysql.cpp +++ b/src/sql/drivers/mysql/qsql_mysql.cpp @@ -85,11 +85,10 @@ public: #else tc(0), #endif - preparedQuerys(false), preparedQuerysEnabled(false) {} + preparedQuerysEnabled(false) {} MYSQL *mysql; QTextCodec *tc; - bool preparedQuerys; bool preparedQuerysEnabled; }; @@ -172,6 +171,7 @@ public: #if MYSQL_VERSION_ID >= 40108 , stmt(0), meta(0), inBinds(0), outBinds(0) #endif + , preparedQuery(false) { connect(dp, SIGNAL(destroyed()), this, SLOT(driverDestroyed())); } @@ -209,6 +209,9 @@ public: MYSQL_BIND *inBinds; MYSQL_BIND *outBinds; #endif + + bool preparedQuery; + private Q_SLOTS: void driverDestroyed() { driver = NULL; } }; @@ -399,7 +402,7 @@ QMYSQLResult::~QMYSQLResult() QVariant QMYSQLResult::handle() const { #if MYSQL_VERSION_ID >= 40108 - if(d->driver && d->driver->d->preparedQuerys) + if(d->preparedQuery) return d->meta ? qVariantFromValue(d->meta) : qVariantFromValue(d->stmt); else #endif @@ -454,9 +457,6 @@ void QMYSQLResult::cleanup() d->row = NULL; setAt(-1); setActive(false); - - if(d->driver) - d->driver->d->preparedQuerys = d->driver->d->preparedQuerysEnabled; } bool QMYSQLResult::fetch(int i) @@ -474,7 +474,7 @@ bool QMYSQLResult::fetch(int i) } if (at() == i) return true; - if (d->driver->d->preparedQuerys) { + if (d->preparedQuery) { #if MYSQL_VERSION_ID >= 40108 mysql_stmt_data_seek(d->stmt, i); @@ -507,7 +507,7 @@ bool QMYSQLResult::fetchNext() { if(!d->driver) return false; - if (d->driver->d->preparedQuerys) { + if (d->preparedQuery) { #if MYSQL_VERSION_ID >= 40108 if (mysql_stmt_fetch(d->stmt)) return false; @@ -534,7 +534,7 @@ bool QMYSQLResult::fetchLast() } my_ulonglong numRows; - if (d->driver->d->preparedQuerys) { + if (d->preparedQuery) { #if MYSQL_VERSION_ID >= 40108 numRows = mysql_stmt_num_rows(d->stmt); #else @@ -574,7 +574,7 @@ QVariant QMYSQLResult::data(int field) int fieldLength = 0; const QMYSQLResultPrivate::QMyField &f = d->fields.at(field); QString val; - if (d->driver->d->preparedQuerys) { + if (d->preparedQuery) { if (f.nullIndicator) return QVariant(f.type); @@ -634,7 +634,7 @@ QVariant QMYSQLResult::data(int field) case QVariant::ByteArray: { QByteArray ba; - if (d->driver->d->preparedQuerys) { + if (d->preparedQuery) { ba = QByteArray(f.outField, f.bufLength); } else { ba = QByteArray(d->row[field], fieldLength); @@ -651,7 +651,7 @@ QVariant QMYSQLResult::data(int field) bool QMYSQLResult::isNull(int field) { - if (d->driver->d->preparedQuerys) + if (d->preparedQuery) return d->fields.at(field).nullIndicator; else return d->row[field] == NULL; @@ -662,11 +662,9 @@ bool QMYSQLResult::reset (const QString& query) if (!driver() || !driver()->isOpen() || driver()->isOpenError() || !d->driver) return false; - if(d->driver->d->preparedQuerysEnabled && prepare(query)) { - d->driver->d->preparedQuerys = true; - return exec(); - } - d->driver->d->preparedQuerys = false; + d->preparedQuery = false; + + cleanup(); const QByteArray encQuery(fromUnicode(d->driver->d->tc, query)); if (mysql_real_query(d->driver->d->mysql, encQuery.data(), encQuery.length())) { @@ -699,7 +697,7 @@ bool QMYSQLResult::reset (const QString& query) int QMYSQLResult::size() { if (d->driver && isSelect()) - if (d->driver->d->preparedQuerys) + if (d->preparedQuery) #if MYSQL_VERSION_ID >= 40108 return mysql_stmt_num_rows(d->stmt); #else @@ -721,7 +719,7 @@ QVariant QMYSQLResult::lastInsertId() const if (!isActive() || !d->driver) return QVariant(); - if (d->driver->d->preparedQuerys) { + if (d->preparedQuery) { #if MYSQL_VERSION_ID >= 40108 quint64 id = mysql_stmt_insert_id(d->stmt); if (id) @@ -743,7 +741,7 @@ QSqlRecord QMYSQLResult::record() const return info; #if MYSQL_VERSION_ID >= 40108 - res = d->driver->d->preparedQuerys ? d->meta : d->result; + res = d->preparedQuery ? d->meta : d->result; #else res = d->result; #endif @@ -856,7 +854,7 @@ bool QMYSQLResult::prepare(const QString& query) return false; #if MYSQL_VERSION_ID >= 40108 cleanup(); - if (!d->driver->d->preparedQuerys) + if (!d->driver->d->preparedQuerysEnabled) return QSqlResult::prepare(query); int r; @@ -886,6 +884,7 @@ bool QMYSQLResult::prepare(const QString& query) } setSelect(d->bindInValues()); + d->preparedQuery = true; return true; #else return false; @@ -896,7 +895,7 @@ bool QMYSQLResult::exec() { if (!d->driver) return false; - if (!d->driver->d->preparedQuerys) + if (!d->preparedQuery) return QSqlResult::exec(); if (!d->stmt) return false; @@ -1338,9 +1337,6 @@ QSqlIndex QMYSQLDriver::primaryIndex(const QString& tablename) const if (!isOpen()) return idx; - prepQ = d->preparedQuerysEnabled; - d->preparedQuerysEnabled = false; - QSqlQuery i(createResult()); QString stmt(QLatin1String("show index from %1;")); QSqlRecord fil = record(tablename); @@ -1353,7 +1349,6 @@ QSqlIndex QMYSQLDriver::primaryIndex(const QString& tablename) const } } - d->preparedQuerysEnabled = prepQ; return idx; } -- cgit v0.12 From 745ecf9cf48bc718690fa8b2149eb6dbbb64fcc6 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 4 Aug 2009 15:40:15 +1000 Subject: Fix incorrect license headers. Reviewed-by: Trust Me --- src/corelib/tools/qbytedata_p.h | 12 +++++++++++- src/gui/embedded/qkbdqnx_qws.cpp | 10 +++++----- src/gui/embedded/qkbdqnx_qws.h | 10 +++++----- src/gui/embedded/qmouseqnx_qws.cpp | 10 +++++----- src/gui/embedded/qmouseqnx_qws.h | 10 +++++----- src/gui/embedded/qscreenqnx_qws.cpp | 10 +++++----- src/gui/embedded/qscreenqnx_qws.h | 10 +++++----- 7 files changed, 41 insertions(+), 31 deletions(-) diff --git a/src/corelib/tools/qbytedata_p.h b/src/corelib/tools/qbytedata_p.h index cc10ea2..f3724f6 100644 --- a/src/corelib/tools/qbytedata_p.h +++ b/src/corelib/tools/qbytedata_p.h @@ -42,8 +42,18 @@ #ifndef QBYTEDATA_H #define QBYTEDATA_H -#include +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// +#include QT_BEGIN_NAMESPACE diff --git a/src/gui/embedded/qkbdqnx_qws.cpp b/src/gui/embedded/qkbdqnx_qws.cpp index 06163c7..089b868 100644 --- a/src/gui/embedded/qkbdqnx_qws.cpp +++ b/src/gui/embedded/qkbdqnx_qws.cpp @@ -6,11 +6,11 @@ ** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser diff --git a/src/gui/embedded/qkbdqnx_qws.h b/src/gui/embedded/qkbdqnx_qws.h index c046c8d..fa3ae56 100644 --- a/src/gui/embedded/qkbdqnx_qws.h +++ b/src/gui/embedded/qkbdqnx_qws.h @@ -6,11 +6,11 @@ ** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser diff --git a/src/gui/embedded/qmouseqnx_qws.cpp b/src/gui/embedded/qmouseqnx_qws.cpp index 98f8f06..59cd5be 100644 --- a/src/gui/embedded/qmouseqnx_qws.cpp +++ b/src/gui/embedded/qmouseqnx_qws.cpp @@ -6,11 +6,11 @@ ** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser diff --git a/src/gui/embedded/qmouseqnx_qws.h b/src/gui/embedded/qmouseqnx_qws.h index a61562e..f8cad4a 100644 --- a/src/gui/embedded/qmouseqnx_qws.h +++ b/src/gui/embedded/qmouseqnx_qws.h @@ -6,11 +6,11 @@ ** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser diff --git a/src/gui/embedded/qscreenqnx_qws.cpp b/src/gui/embedded/qscreenqnx_qws.cpp index 7101bc7..c79ee59 100644 --- a/src/gui/embedded/qscreenqnx_qws.cpp +++ b/src/gui/embedded/qscreenqnx_qws.cpp @@ -6,11 +6,11 @@ ** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser diff --git a/src/gui/embedded/qscreenqnx_qws.h b/src/gui/embedded/qscreenqnx_qws.h index 837c061..30312fe 100644 --- a/src/gui/embedded/qscreenqnx_qws.h +++ b/src/gui/embedded/qscreenqnx_qws.h @@ -6,11 +6,11 @@ ** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -- cgit v0.12 From e83f77cbc22be5e37de1e7a8ec2c55e66f7b51d9 Mon Sep 17 00:00:00 2001 From: Morten Sorvig Date: Tue, 4 Aug 2009 09:31:56 +0200 Subject: Build on snow leopard. Don't error out when building qmake, just let it build a 64-bit binary (even for carbon) RebBy: Richard Moe Gustavsen --- src/corelib/global/qglobal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index f650bd2..e05c05d 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -279,7 +279,7 @@ namespace QT_NAMESPACE {} # endif #endif -#if defined(Q_OS_MAC64) && !defined(QT_MAC_USE_COCOA) +#if defined(Q_OS_MAC64) && !defined(QT_MAC_USE_COCOA) && !defined(QT_BUILD_QMAKE) #error "You are building a 64-bit application, but using a 32-bit version of Qt. Check your build configuration." #endif -- cgit v0.12 From 4f7170d9d731234c65008b690a95a0e86d397db5 Mon Sep 17 00:00:00 2001 From: Morten Sorvig Date: Tue, 4 Aug 2009 08:15:21 +0200 Subject: Make Cocoa builds 64-bit by default on snow leopard. --- configure | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/configure b/configure index 2f2e284..095d040 100755 --- a/configure +++ b/configure @@ -5707,17 +5707,23 @@ if [ "$CFG_MAC_DWARF2" = "yes" ]; then QT_CONFIG="$QT_CONFIG dwarf2" fi -# Set the default arch. Select 32-bit/carbon if nothing else has -# been specified on the configure line. +# Set the default arch. +# Carbon builds: 32 bit x86/ppc. +# For "-cocoa" builds on snow leopard : compiler default (64-bit). +# For "-cocoa" builds on leopard : compiler default (32-bit). if [ "$PLATFORM_MAC" = "yes" ] && [ "$CFG_MAC_ARCHS" == "" ]; then source "$mactests/defaultarch.test" "$TEST_COMPILER" "$OPT_VERBOSE" "$mactests" - if [ "$QT_MAC_DEFAULT_ARCH" == "x86_64" ]; then - CFG_MAC_ARCHS=" x86" - elif [ "$QT_MAC_DEFAULT_ARCH" == "ppc64" ]; then - CFG_MAC_ARCHS=" ppc" - else - CFG_MAC_ARCHS=" $QT_MAC_DEFAULT_ARCH" + if [ "$CFG_MAC_COCOA" != "yes" ]; then + if [ "$QT_MAC_DEFAULT_ARCH" == "x86_64" ]; then + CFG_MAC_ARCHS=" x86" + elif [ "$QT_MAC_DEFAULT_ARCH" == "ppc64" ]; then + CFG_MAC_ARCHS=" ppc" + else + CFG_MAC_ARCHS=" $QT_MAC_DEFAULT_ARCH" + fi + else + CFG_MAC_ARCHS=" $QT_MAC_DEFAULT_ARCH" fi [ "$OPT_VERBOSE" == "yes" ] && echo "Setting Mac architechture to$CFG_MAC_ARCHS." -- cgit v0.12 From 83a82f900aa63a350b66d90ed55f63ee77f20250 Mon Sep 17 00:00:00 2001 From: Morten Sorvig Date: Tue, 4 Aug 2009 09:31:56 +0200 Subject: Build on snow leopard. Don't error out when building qmake, just let it build a 64-bit binary (even for carbon) RebBy: Richard Moe Gustavsen --- src/corelib/global/qglobal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 8263bae..c266ca0 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -279,7 +279,7 @@ namespace QT_NAMESPACE {} # endif #endif -#if defined(Q_OS_MAC64) && !defined(QT_MAC_USE_COCOA) +#if defined(Q_OS_MAC64) && !defined(QT_MAC_USE_COCOA) && !defined(QT_BUILD_QMAKE) #error "You are building a 64-bit application, but using a 32-bit version of Qt. Check your build configuration." #endif -- cgit v0.12 From 1f0ea657d33b6851c1f3cb4becd77c63d4b720d8 Mon Sep 17 00:00:00 2001 From: Morten Sorvig Date: Tue, 4 Aug 2009 09:47:05 +0200 Subject: Remove the "preliminary support" warning for 10.6 Also make the "usupported on > 10.6" error a warning. No need to stop the build, the warning will be printed enough times. --- src/corelib/global/qglobal.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index c266ca0..18d5a9f 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -311,11 +311,8 @@ namespace QT_NAMESPACE {} # if !defined(MAC_OS_X_VERSION_10_6) # define MAC_OS_X_VERSION_10_6 MAC_OS_X_VERSION_10_5 + 1 # endif -# if (MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_6) -# warning "Support for this version of Mac OS X is still preliminary" -# endif # if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_6) -# error "This version of Mac OS X is unsupported" +# warning "This version of Mac OS X is unsupported" # endif #endif -- cgit v0.12 From c96ed4426db7ae3287ee88b0ac7ffd2bd5070310 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 4 Aug 2009 09:43:14 +0200 Subject: Add support for pan gesture on mac (carbon and cocoa) --- src/gui/kernel/qstandardgestures.cpp | 64 ++++++++++++++++++++++++++++++++++++ src/gui/kernel/qstandardgestures_p.h | 6 ++++ 2 files changed, 70 insertions(+) diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index c8b11c5..1a88429 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -73,11 +73,17 @@ QPanGesture::QPanGesture(QWidget *parent) qAppPriv->widgetGestures[parent].pan = this; } #endif + +#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + d_func()->panFinishedTimer = 0; +#endif } /*! \internal */ bool QPanGesture::event(QEvent *event) { + Q_D(QPanGesture); + #ifdef Q_WS_WIN QApplicationPrivate* getQApplicationPrivateInternal(); switch (event->type()) { @@ -93,6 +99,21 @@ bool QPanGesture::event(QEvent *event) break; } #endif + +#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + if (event->type() == QEvent::Timer) { + const QTimerEvent *te = static_cast(event); + if (te->timerId() == d->panFinishedTimer) { + killTimer(d->panFinishedTimer); + d->panFinishedTimer = 0; + d->lastOffset = QSize(0, 0); + setState(Qt::GestureFinished); + emit triggered(); + setState(Qt::NoGesture); + } + } +#endif + return QObject::event(event); } @@ -133,6 +154,36 @@ bool QPanGesture::filterEvent(QEvent *event) emit triggered(); } } +#ifdef Q_OS_MAC + else if (event->type() == QEvent::Wheel) { + // On Mac, there is really no native panning gesture. Instead, a two + // finger pan is delivered as mouse wheel events. Otoh, on Windows, you + // either get mouse wheel events or pan events. We have decided to make this + // the Qt behaviour as well, meaning that on Mac, wheel + // events will be masked away when listening for pan events. +#ifndef QT_MAC_USE_COCOA + // In Carbon we receive neither touch-, nor pan gesture events. + // So we create pan gestures by converting wheel events. After all, this + // is how things are supposed to work on mac in the first place. + const QWheelEvent *wev = static_cast(event); + int offset = wev->delta() / -120; + d->lastOffset = wev->orientation() == Qt::Horizontal ? QSize(offset, 0) : QSize(0, offset); + + if (state() == Qt::NoGesture) { + setState(Qt::GestureStarted); + d->totalOffset = d->lastOffset; + } else { + setState(Qt::GestureUpdated); + d->totalOffset += d->lastOffset; + } + + killTimer(d->panFinishedTimer); + d->panFinishedTimer = startTimer(200); + emit triggered(); +#endif + return true; + } +#endif return false; } @@ -150,8 +201,13 @@ void QPanGesture::reset() */ QSize QPanGesture::totalOffset() const { +#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + Q_D(const QPanGesture); + return d->totalOffset; +#else QPoint pt = pos() - startPos(); return QSize(pt.x(), pt.y()); +#endif } /*! @@ -162,8 +218,13 @@ QSize QPanGesture::totalOffset() const */ QSize QPanGesture::lastOffset() const { +#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + Q_D(const QPanGesture); + return d->lastOffset; +#else QPoint pt = pos() - lastPos(); return QSize(pt.x(), pt.y()); +#endif } /*! @@ -252,3 +313,6 @@ void QTapAndHoldGesture::reset() } QT_END_NAMESPACE + +#include "moc_qstandardgestures.cpp" + diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h index bb11c9f..0fd42bd 100644 --- a/src/gui/kernel/qstandardgestures_p.h +++ b/src/gui/kernel/qstandardgestures_p.h @@ -70,6 +70,12 @@ public: QPanGesturePrivate() { } QList touchPoints; + QSize totalOffset; + QSize lastOffset; + +#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + int panFinishedTimer; +#endif }; class QTapAndHoldGesturePrivate : public QGesturePrivate -- cgit v0.12 From d2e03cc83b5dabc5fd1986a8b8119ff8f0d76179 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 4 Aug 2009 09:45:47 +0200 Subject: Modify imagewidget example so it works with new API --- examples/gestures/imageviewer/imagewidget.cpp | 46 +++++++++------------------ 1 file changed, 15 insertions(+), 31 deletions(-) diff --git a/examples/gestures/imageviewer/imagewidget.cpp b/examples/gestures/imageviewer/imagewidget.cpp index 717bb09..0b39997 100644 --- a/examples/gestures/imageviewer/imagewidget.cpp +++ b/examples/gestures/imageviewer/imagewidget.cpp @@ -100,7 +100,7 @@ void ImageWidget::paintEvent(QPaintEvent*) p.setPen(QPen(Qt::gray, 2)); p.drawEllipse(touchFeedback.position, 5, 5); if (touchFeedback.doubleTapped) { - p.setPen(QPen(Qt::gray, 2, Qt::DotLine)); + p.setPen(QPen(Qt::darkGray, 2, Qt::DotLine)); p.drawEllipse(touchFeedback.position, 15, 15); } else if (touchFeedback.tapAndHoldState != 0) { QPoint pts[8] = { @@ -159,51 +159,35 @@ void ImageWidget::gestureTriggered() touchFeedback.tapped = false; touchFeedback.doubleTapped = false; - QGesture *g = qobject_cast(sender()); if (sender() == panGesture) { + QPanGesture *pg = qobject_cast(sender()); if (zoomedIn) { - // usual panning #ifndef QT_NO_CURSOR - if (g->state() == Qt::GestureStarted) - setCursor(Qt::SizeAllCursor); - else - setCursor(Qt::ArrowCursor); + switch (pg->state()) { + case Qt::GestureStarted: + case Qt::GestureUpdated: + setCursor(Qt::SizeAllCursor); + break; + default: + setCursor(Qt::ArrowCursor); + } #endif - const int dx = g->pos().x() - g->lastPos().x(); - const int dy = g->pos().y() - g->lastPos().y(); - horizontalOffset += dx; - verticalOffset += dy; + horizontalOffset += pg->lastOffset().width(); + verticalOffset += pg->lastOffset().height(); update(); } else { // only slide gesture should be accepted - const QPanGesture *pg = static_cast(g); - if (g->state() == Qt::GestureFinished) { + if (pg->state() == Qt::GestureFinished) { touchFeedback.sliding = false; zoomed = rotated = false; - if (pg->totalOffset().width() > 0) { - qDebug() << "slide right"; + if (pg->totalOffset().width() > 0) goNextImage(); - } else { - qDebug() << "slide left"; + else goPrevImage(); - } updateImage(); } } feedbackFadeOutTimer.start(500, this); - } else if (sender() == tapAndHoldGesture) { - if (g->state() == Qt::GestureFinished) { - qDebug() << "tap and hold detected"; - touchFeedback.reset(); - update(); - - QMenu menu; - menu.addAction("Action 1"); - menu.addAction("Action 2"); - menu.addAction("Action 3"); - menu.exec(mapToGlobal(g->pos())); - } - feedbackFadeOutTimer.start(500, this); } } -- cgit v0.12 From 14f9cbbec204ba146205d12cb06577d41b5f974c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 4 Aug 2009 10:00:01 +0200 Subject: Mac: Remove debug work output --- src/gui/painting/qregion_mac.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/painting/qregion_mac.cpp b/src/gui/painting/qregion_mac.cpp index 9b0e99f..6fe7805 100644 --- a/src/gui/painting/qregion_mac.cpp +++ b/src/gui/painting/qregion_mac.cpp @@ -173,7 +173,6 @@ RgnHandle QRegion::toQDRgnForUpdate_sys() const // detect overflow. Tested for use with HIViewSetNeedsDisplayInRegion // in QWidgetPrivate::update_sys(). enum { HIViewSetNeedsDisplayInRegionOverflow = 10000 }; // empirically determined conservative value - qDebug() << qt_r->x() << qt_r->y() << qt_r->right() << qt_r->bottom(); if (qt_r->right() > HIViewSetNeedsDisplayInRegionOverflow || qt_r->bottom() > HIViewSetNeedsDisplayInRegionOverflow) { qt_mac_dispose_rgn(tmp_rgn); qt_mac_dispose_rgn(rgnHandle); -- cgit v0.12 From d3c96863ec17a69c616bdcb12e6a99a874eba66d Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 3 Aug 2009 16:49:46 +0200 Subject: fix warnings on mingw (gcc4.4) basically reordering members initialization in constructors or fixing singed/unsigned checks. Reviewed-by: Trustme --- src/activeqt/container/qaxbase.cpp | 14 +++++++++----- src/activeqt/container/qaxwidget.cpp | 2 +- src/activeqt/shared/qaxtypes.cpp | 2 +- src/gui/painting/qregion_win.cpp | 4 ++-- src/gui/util/qcompleter.cpp | 2 +- src/opengl/qgl.cpp | 5 +++-- 6 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/activeqt/container/qaxbase.cpp b/src/activeqt/container/qaxbase.cpp index 4fc9926..d602946 100644 --- a/src/activeqt/container/qaxbase.cpp +++ b/src/activeqt/container/qaxbase.cpp @@ -3204,12 +3204,12 @@ static const char qt_meta_stringdata_QAxBase[] = { }; static QMetaObject qaxobject_staticMetaObject = { - &QObject::staticMetaObject, qt_meta_stringdata_QAxBase, - qt_meta_data_QAxBase, 0 + { &QObject::staticMetaObject, qt_meta_stringdata_QAxBase, + qt_meta_data_QAxBase, 0 } }; static QMetaObject qaxwidget_staticMetaObject = { - &QWidget::staticMetaObject, qt_meta_stringdata_QAxBase, - qt_meta_data_QAxBase, 0 + { &QWidget::staticMetaObject, qt_meta_stringdata_QAxBase, + qt_meta_data_QAxBase, 0 } }; /*! @@ -3692,6 +3692,8 @@ int QAxBase::qt_metacall(QMetaObject::Call call, int id, void **v) case QMetaMethod::Slot: id = internalInvoke(call, id, v); break; + default: + break; } break; case QMetaObject::ReadProperty: @@ -3706,6 +3708,8 @@ int QAxBase::qt_metacall(QMetaObject::Call call, int id, void **v) case QMetaObject::QueryPropertyUser: id -= mo->propertyCount(); break; + default: + break; } Q_ASSERT(id < 0); return id; @@ -3905,7 +3909,7 @@ bool QAxBase::dynamicCallHelper(const char *name, void *inout, QList & else paramType = d->metaobj->paramType(normFunction, i, &out); - if (!parse && d->useMetaObject && var.type() == QVariant::String || var.type() == QVariant::ByteArray) { + if ((!parse && d->useMetaObject && var.type() == QVariant::String) || var.type() == QVariant::ByteArray) { int enumIndex =mo->indexOfEnumerator(paramType); if (enumIndex != -1) { QMetaEnum metaEnum =mo->enumerator(enumIndex); diff --git a/src/activeqt/container/qaxwidget.cpp b/src/activeqt/container/qaxwidget.cpp index ff6bcb8..e4c9d42 100644 --- a/src/activeqt/container/qaxwidget.cpp +++ b/src/activeqt/container/qaxwidget.cpp @@ -531,7 +531,7 @@ bool axc_FilterProc(void *m) } QAxClientSite::QAxClientSite(QAxWidget *c) -: ref(1), widget(c), host(0), eventTranslated(true) +: eventTranslated(true), ref(1), widget(c), host(0) { aggregatedObject = widget->createAggregate(); if (aggregatedObject) { diff --git a/src/activeqt/shared/qaxtypes.cpp b/src/activeqt/shared/qaxtypes.cpp index 49aa99c..63891c4 100644 --- a/src/activeqt/shared/qaxtypes.cpp +++ b/src/activeqt/shared/qaxtypes.cpp @@ -552,7 +552,7 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type int maxColumns = col.count(); if (maxColumns) { is2D = true; - SAFEARRAYBOUND rgsabound[2] = {0}; + SAFEARRAYBOUND rgsabound[2] = { {0} }; rgsabound[0].cElements = count; rgsabound[1].cElements = maxColumns; array = SafeArrayCreate(VT_VARIANT, 2, rgsabound); diff --git a/src/gui/painting/qregion_win.cpp b/src/gui/painting/qregion_win.cpp index 2d5e76b..8708461 100644 --- a/src/gui/painting/qregion_win.cpp +++ b/src/gui/painting/qregion_win.cpp @@ -57,7 +57,7 @@ HRGN qt_tryCreateRegion(QRegion::RegionType type, int left, int top, int right, { const int tries = 10; for (int i = 0; i < tries; ++i) { - HRGN region; + HRGN region = 0; switch (type) { case QRegion::Rectangle: region = CreateRectRgn(left, top, right, bottom); @@ -96,7 +96,7 @@ QRegion qt_region_from_HRGN(HRGN rgn) QRegion region; RECT *r = reinterpret_cast(rd->Buffer); - for (int i = 0; i < rd->rdh.nCount; ++i) { + for (uint i = 0; i < rd->rdh.nCount; ++i) { QRect rect; rect.setCoords(r->left, r->top, r->right - 1, r->bottom - 1); ++r; diff --git a/src/gui/util/qcompleter.cpp b/src/gui/util/qcompleter.cpp index a0a3756..f4dd87c 100644 --- a/src/gui/util/qcompleter.cpp +++ b/src/gui/util/qcompleter.cpp @@ -772,7 +772,7 @@ QMatchData QUnsortedModelEngine::filter(const QString& part, const QModelIndex& /////////////////////////////////////////////////////////////////////////////// QCompleterPrivate::QCompleterPrivate() : widget(0), proxy(0), popup(0), cs(Qt::CaseSensitive), role(Qt::EditRole), column(0), - sorting(QCompleter::UnsortedModel), wrap(true), maxVisibleItems(7), eatFocusOut(true) + maxVisibleItems(7), sorting(QCompleter::UnsortedModel), wrap(true), eatFocusOut(true) { } diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 48d09ce..0631df5 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -4604,7 +4604,7 @@ QGLFormat QGLDrawable::format() const GLuint QGLDrawable::bindTexture(const QImage &image, GLenum target, GLint format) { - QGLTexture *texture; + QGLTexture *texture = 0; if (widget) texture = widget->d_func()->glcx->d_func()->bindTexture(image, target, format, true); else if (buffer) @@ -4620,7 +4620,7 @@ GLuint QGLDrawable::bindTexture(const QImage &image, GLenum target, GLint format GLuint QGLDrawable::bindTexture(const QPixmap &pixmap, GLenum target, GLint format) { - QGLTexture *texture; + QGLTexture *texture = 0; if (widget) texture = widget->d_func()->glcx->d_func()->bindTexture(pixmap, target, format, true, true); else if (buffer) @@ -4718,6 +4718,7 @@ void QGLShareRegister::removeShare(const QGLContext *context) { int count = it.value().removeAll(context); Q_ASSERT(count == 1); + Q_UNUSED(count); Q_ASSERT(it.value().size() != 0); if (it.value().size() == 1) -- cgit v0.12 From 549736341a2268e33159949e076e0629abeb838a Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Tue, 28 Jul 2009 15:55:28 +0200 Subject: Fixes selectionModel::hasSelection return value after model::reset After resetting the model, the selectionModel::hasSelection() of the view should return false. Fixed the corresponding autotest, which was wrong. Task-number: 256502 Reviewed-by: thierry --- src/gui/itemviews/qabstractitemview.cpp | 1 + tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index 8b6b5cb..94569ec 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -960,6 +960,7 @@ void QAbstractItemView::reset() d->currentIndexSet = false; setState(NoState); setRootIndex(QModelIndex()); + d->selectionModel->reset(); } /*! diff --git a/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp b/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp index ae64e51..0541b46 100644 --- a/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp +++ b/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp @@ -1547,7 +1547,7 @@ void tst_QItemSelectionModel::resetModel() model.reset(); QVERIFY(view.selectionModel()->selection().isEmpty()); - QVERIFY(view.selectionModel()->hasSelection()); + QVERIFY(view.selectionModel()->hasSelection() == false); view.selectionModel()->select(QItemSelection(model.index(0, 0), model.index(5, 5)), QItemSelectionModel::Select); -- cgit v0.12 From baf3ec81ca5d5cd38b54dc853c12109956a98cb9 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 4 Aug 2009 11:16:01 +0200 Subject: QMenu now takes minimum width into account for the action rects The action now try to take advantage of the space given by a minimum width. Patch proposed initially by Aron Seigo and improved later on. Reviewed-by: Trustme --- src/gui/widgets/qmenu.cpp | 11 ++++++----- tests/auto/qmenu/tst_qmenu.cpp | 12 ++++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 0b85eec..67bb10a 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -228,6 +228,10 @@ void QMenuPrivate::updateActionRects() const const int hmargin = style->pixelMetric(QStyle::PM_MenuHMargin, 0, q), vmargin = style->pixelMetric(QStyle::PM_MenuVMargin, 0, q), icone = style->pixelMetric(QStyle::PM_SmallIconSize, 0, q); + const int fw = style->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q); + + const int sfcMargin = style->sizeFromContents(QStyle::CT_Menu, 0, QApplication::globalStrut(), q).width() - QApplication::globalStrut().width(); + const int min_column_width = q->minimumWidth() - (sfcMargin + leftmargin + rightmargin + 2 * (fw + hmargin)); //for compatability now - will have to refactor this away.. tabWidth = 0; @@ -300,7 +304,7 @@ void QMenuPrivate::updateActionRects() const if (!sz.isEmpty()) { - max_column_width = qMax(max_column_width, sz.width()); + max_column_width = qMax(min_column_width, qMax(max_column_width, sz.width())); //wrapping if (!scroll && y+sz.height()+vmargin > dh - (style->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q) * 2)) { @@ -316,7 +320,6 @@ void QMenuPrivate::updateActionRects() const max_column_width += tabWidth; //finally add in the tab width //calculate position - const int fw = style->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q); const int base_y = vmargin + fw + topmargin + (scroll ? scroll->scrollOffset : 0) + (tearoff ? style->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, q) : 0); @@ -1703,9 +1706,7 @@ QSize QMenu::sizeHint() const QSize s; QStyleOption opt(0); - opt.rect = rect(); - opt.palette = palette(); - opt.state = QStyle::State_None; + opt.init(this); for (int i = 0; i < d->actionRects.count(); ++i) { const QRect &rect = d->actionRects.at(i); if (rect.isNull()) diff --git a/tests/auto/qmenu/tst_qmenu.cpp b/tests/auto/qmenu/tst_qmenu.cpp index ec9c7b4..6ba6466 100644 --- a/tests/auto/qmenu/tst_qmenu.cpp +++ b/tests/auto/qmenu/tst_qmenu.cpp @@ -96,6 +96,7 @@ private slots: void task256918_setFont(); void menuSizeHint(); void task258920_mouseBorder(); + void setFixedWidth(); protected slots: void onActivated(QAction*); void onHighlighted(QAction*); @@ -798,6 +799,17 @@ void tst_QMenu::task258920_mouseBorder() QVERIFY(menu.painted); } +void tst_QMenu::setFixedWidth() +{ + QMenu menu; + menu.addAction("action"); + menu.setFixedWidth(300); + //the sizehint should reflect the minimumwidth because the action will try to + //get as much space as possible + QCOMPARE(menu.sizeHint().width(), menu.minimumWidth()); +} + + QTEST_MAIN(tst_QMenu) #include "tst_qmenu.moc" -- cgit v0.12 From 54d5c7eae26c025015f08bf06d0f9268175317e8 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 4 Aug 2009 11:47:45 +0200 Subject: fix warning on MSVC --- src/gui/kernel/qstandardgestures.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index 1a88429..c4820f0 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -82,8 +82,6 @@ QPanGesture::QPanGesture(QWidget *parent) /*! \internal */ bool QPanGesture::event(QEvent *event) { - Q_D(QPanGesture); - #ifdef Q_WS_WIN QApplicationPrivate* getQApplicationPrivateInternal(); switch (event->type()) { @@ -101,6 +99,7 @@ bool QPanGesture::event(QEvent *event) #endif #if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + Q_D(QPanGesture); if (event->type() == QEvent::Timer) { const QTimerEvent *te = static_cast(event); if (te->timerId() == d->panFinishedTimer) { -- cgit v0.12 From dc0088949822f846983c9a2d8f7dca59433ec555 Mon Sep 17 00:00:00 2001 From: ck Date: Tue, 4 Aug 2009 12:52:38 +0200 Subject: Assistant: Added search history. Task-number: 251278 Reviewed-by: kh --- tools/assistant/lib/qhelpsearchquerywidget.cpp | 295 ++++++++++++++++++++----- 1 file changed, 238 insertions(+), 57 deletions(-) diff --git a/tools/assistant/lib/qhelpsearchquerywidget.cpp b/tools/assistant/lib/qhelpsearchquerywidget.cpp index 00444b1..110df4f 100644 --- a/tools/assistant/lib/qhelpsearchquerywidget.cpp +++ b/tools/assistant/lib/qhelpsearchquerywidget.cpp @@ -43,9 +43,12 @@ #include +#include #include #include +#include +#include #include #include #include @@ -60,8 +63,46 @@ class QHelpSearchQueryWidgetPrivate : public QObject Q_OBJECT private: + struct QueryHistory { + explicit QueryHistory() : curQuery(-1) {} + QList > queries; + int curQuery; + }; + + class CompleterModel : public QAbstractListModel + { + public: + explicit CompleterModel(QObject *parent) + : QAbstractListModel(parent) {} + + int rowCount(const QModelIndex &parent = QModelIndex()) const + { + return parent.isValid() ? 0 : termList.size(); + } + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const + { + if (!index.isValid() || index.row() >= termList.count()|| + (role != Qt::EditRole && role != Qt::DisplayRole)) + return QVariant(); + return termList.at(index.row()); + } + + void addTerm(const QString &term) + { + if (!termList.contains(term)) { + termList.append(term); + reset(); + } + } + + private: + QStringList termList; + }; + QHelpSearchQueryWidgetPrivate() - : QObject() + : QObject(), simpleSearch(true), + searchCompleter(new CompleterModel(this), this) { searchButton = 0; advancedSearchWidget = 0; @@ -136,11 +177,102 @@ private: return wordList; } + void saveQuery(const QList &query, QueryHistory &queryHist) + { + // We only add the query to the list if it is different from the last one. + bool insert = false; + if (queryHist.queries.empty()) + insert = true; + else { + const QList &lastQuery = queryHist.queries.last(); + if (lastQuery.size() != query.size()) { + insert = true; + } else { + for (int i = 0; i < query.size(); ++i) { + if (query.at(i).fieldName != lastQuery.at(i).fieldName + || query.at(i).wordList != lastQuery.at(i).wordList) { + insert = true; + break; + } + } + } + } + if (insert) { + queryHist.queries.append(query); + foreach (const QHelpSearchQuery &queryPart, query) { + static_cast(searchCompleter.model())-> + addTerm(queryPart.wordList.join(" ")); + } + } + } + + void nextOrPrevQuery(int maxOrMinIndex, int addend, + QToolButton *thisButton, QToolButton *otherButton) + { + QueryHistory *queryHist; + QList lineEdits; + if (simpleSearch) { + queryHist = &simpleQueries; + lineEdits << defaultQuery; + } else { + queryHist = &complexQueries; + lineEdits << allQuery << atLeastQuery << similarQuery + << withoutQuery << exactQuery; + } + foreach (QLineEdit *lineEdit, lineEdits) + lineEdit->clear(); + + // Otherwise, the respective button would be disabled. + Q_ASSERT(queryHist->curQuery != maxOrMinIndex); + + queryHist->curQuery += addend; + const QList &query = + queryHist->queries.at(queryHist->curQuery); + foreach (const QHelpSearchQuery &queryPart, query) { + QLineEdit *lineEdit; + switch (queryPart.fieldName) { + case QHelpSearchQuery::DEFAULT: + lineEdit = defaultQuery; + break; + case QHelpSearchQuery::ALL: + lineEdit = allQuery; + break; + case QHelpSearchQuery::ATLEAST: + lineEdit = atLeastQuery; + break; + case QHelpSearchQuery::FUZZY: + lineEdit = similarQuery; + break; + case QHelpSearchQuery::WITHOUT: + lineEdit = withoutQuery; + break; + case QHelpSearchQuery::PHRASE: + lineEdit = exactQuery; + break; + default: + Q_ASSERT(0); + } + lineEdit->setText(queryPart.wordList.join(" ")); + } + + if (queryHist->curQuery == maxOrMinIndex) + thisButton->setEnabled(false); + otherButton->setEnabled(true); + } + + void enableOrDisableToolButtons() + { + const QueryHistory &queryHist = + simpleSearch ? simpleQueries : complexQueries; + prevQueryButton->setEnabled(queryHist.curQuery > 0); + nextQueryButton->setEnabled(queryHist.curQuery < + queryHist.queries.size() - 1); + } + private slots: void showHideAdvancedSearch() { - bool hidden = advancedSearchWidget->isHidden(); - if (hidden) { + if (simpleSearch) { advancedSearchWidget->show(); showHideAdvancedSearchButton->setText((QLatin1String("-"))); } else { @@ -148,12 +280,86 @@ private slots: showHideAdvancedSearchButton->setText((QLatin1String("+"))); } - defaultQuery->setEnabled(!hidden); + simpleSearch = !simpleSearch; + defaultQuery->setEnabled(simpleSearch); + enableOrDisableToolButtons(); + } + + void searchRequested() + { + QList queryList; +#if !defined(QT_CLUCENE_SUPPORT) + queryList.append(QHelSearchQuery(QHelpSearchQuery::DEFAULT, + QStringList(defaultQuery->text()))); + +#else + if (defaultQuery->isEnabled()) { + queryList.append(QHelpSearchQuery(QHelpSearchQuery::DEFAULT, + buildTermList(escapeString(defaultQuery->text())))); + } else { + const QRegExp exp(QLatin1String("\\s+")); + QStringList lst = similarQuery->text().split(exp, QString::SkipEmptyParts); + if (!lst.isEmpty()) { + QStringList fuzzy; + foreach (const QString term, lst) + fuzzy += buildTermList(escapeString(term)); + queryList.append(QHelpSearchQuery(QHelpSearchQuery::FUZZY, fuzzy)); + } + + lst = withoutQuery->text().split(exp, QString::SkipEmptyParts); + if (!lst.isEmpty()) { + QStringList without; + foreach (const QString term, lst) + without.append(escapeString(term)); + queryList.append(QHelpSearchQuery(QHelpSearchQuery::WITHOUT, without)); + } + + if (!exactQuery->text().isEmpty()) { + QString phrase = exactQuery->text().remove(QLatin1Char('\"')); + phrase = escapeString(phrase.simplified()); + queryList.append(QHelpSearchQuery(QHelpSearchQuery::PHRASE, QStringList(phrase))); + } + + lst = allQuery->text().split(exp, QString::SkipEmptyParts); + if (!lst.isEmpty()) { + QStringList all; + foreach (const QString term, lst) + all.append(escapeString(term)); + queryList.append(QHelpSearchQuery(QHelpSearchQuery::ALL, all)); + } + + lst = atLeastQuery->text().split(exp, QString::SkipEmptyParts); + if (!lst.isEmpty()) { + QStringList atLeast; + foreach (const QString term, lst) + atLeast += buildTermList(escapeString(term)); + queryList.append(QHelpSearchQuery(QHelpSearchQuery::ATLEAST, atLeast)); + } + } +#endif + QueryHistory &queryHist = simpleSearch ? simpleQueries : complexQueries; + saveQuery(queryList, queryHist); + queryHist.curQuery = queryHist.queries.size() - 1; + if (queryHist.curQuery > 0) + prevQueryButton->setEnabled(true); + nextQueryButton->setEnabled(false); + } + + void nextQuery() + { + nextOrPrevQuery((simpleSearch ? simpleQueries : complexQueries).queries.size() - 1, + 1, nextQueryButton, prevQueryButton); + } + + void prevQuery() + { + nextOrPrevQuery(0, -1, prevQueryButton, nextQueryButton); } private: friend class QHelpSearchQueryWidget; + bool simpleSearch; QPushButton *searchButton; QWidget* advancedSearchWidget; QToolButton *showHideAdvancedSearchButton; @@ -163,6 +369,11 @@ private: QLineEdit *withoutQuery; QLineEdit *allQuery; QLineEdit *atLeastQuery; + QToolButton *nextQueryButton; + QToolButton *prevQueryButton; + QueryHistory simpleQueries; + QueryHistory complexQueries; + QCompleter searchCompleter; }; #include "qhelpsearchquerywidget.moc" @@ -199,13 +410,26 @@ QHelpSearchQueryWidget::QHelpSearchQueryWidget(QWidget *parent) QHBoxLayout* hBoxLayout = new QHBoxLayout(); QLabel *label = new QLabel(tr("Search for:"), this); d->defaultQuery = new QLineEdit(this); + d->defaultQuery->setCompleter(&d->searchCompleter); + d->prevQueryButton = new QToolButton(this); + d->prevQueryButton->setArrowType(Qt::LeftArrow); + d->prevQueryButton->setToolTip(tr("Previous search")); + d->prevQueryButton->setEnabled(false); + d->nextQueryButton = new QToolButton(this); + d->nextQueryButton->setArrowType(Qt::RightArrow); + d->nextQueryButton->setToolTip(tr("Next search")); + d->nextQueryButton->setEnabled(false); d->searchButton = new QPushButton(tr("Search"), this); hBoxLayout->addWidget(label); hBoxLayout->addWidget(d->defaultQuery); + hBoxLayout->addWidget(d->prevQueryButton); + hBoxLayout->addWidget(d->nextQueryButton); hBoxLayout->addWidget(d->searchButton); vLayout->addLayout(hBoxLayout); + connect(d->prevQueryButton, SIGNAL(clicked()), d, SLOT(prevQuery())); + connect(d->nextQueryButton, SIGNAL(clicked()), d, SLOT(nextQuery())); connect(d->searchButton, SIGNAL(clicked()), this, SIGNAL(search())); connect(d->defaultQuery, SIGNAL(returnPressed()), this, SIGNAL(search())); @@ -236,26 +460,31 @@ QHelpSearchQueryWidget::QHelpSearchQueryWidget(QWidget *parent) label = new QLabel(tr("words similar to:"), this); gLayout->addWidget(label, 0, 0); d->similarQuery = new QLineEdit(this); + d->similarQuery->setCompleter(&d->searchCompleter); gLayout->addWidget(d->similarQuery, 0, 1); label = new QLabel(tr("without the words:"), this); gLayout->addWidget(label, 1, 0); d->withoutQuery = new QLineEdit(this); + d->withoutQuery->setCompleter(&d->searchCompleter); gLayout->addWidget(d->withoutQuery, 1, 1); label = new QLabel(tr("with exact phrase:"), this); gLayout->addWidget(label, 2, 0); d->exactQuery = new QLineEdit(this); + d->exactQuery->setCompleter(&d->searchCompleter); gLayout->addWidget(d->exactQuery, 2, 1); label = new QLabel(tr("with all of the words:"), this); gLayout->addWidget(label, 3, 0); d->allQuery = new QLineEdit(this); + d->allQuery->setCompleter(&d->searchCompleter); gLayout->addWidget(d->allQuery, 3, 1); label = new QLabel(tr("with at least one of the words:"), this); gLayout->addWidget(label, 4, 0); d->atLeastQuery = new QLineEdit(this); + d->atLeastQuery->setCompleter(&d->searchCompleter); gLayout->addWidget(d->atLeastQuery, 4, 1); vLayout->addWidget(d->advancedSearchWidget); @@ -269,6 +498,7 @@ QHelpSearchQueryWidget::QHelpSearchQueryWidget(QWidget *parent) connect(d->showHideAdvancedSearchButton, SIGNAL(clicked()), d, SLOT(showHideAdvancedSearch())); #endif + connect(this, SIGNAL(search()), d, SLOT(searchRequested())); } /*! @@ -285,59 +515,10 @@ QHelpSearchQueryWidget::~QHelpSearchQueryWidget() */ QList QHelpSearchQueryWidget::query() const { -#if !defined(QT_CLUCENE_SUPPORT) - QList queryList; - queryList.append(QHelpSearchQuery(QHelpSearchQuery::DEFAULT, - QStringList(d->defaultQuery->text()))); - - return queryList; -#else - QList queryList; - if (d->defaultQuery->isEnabled()) { - queryList.append(QHelpSearchQuery(QHelpSearchQuery::DEFAULT, - d->buildTermList(d->escapeString(d->defaultQuery->text())))); - } else { - const QRegExp exp(QLatin1String("\\s+")); - QStringList lst = d->similarQuery->text().split(exp, QString::SkipEmptyParts); - if (!lst.isEmpty()) { - QStringList fuzzy; - foreach (const QString term, lst) - fuzzy += d->buildTermList(d->escapeString(term)); - queryList.append(QHelpSearchQuery(QHelpSearchQuery::FUZZY, fuzzy)); - } - - lst = d->withoutQuery->text().split(exp, QString::SkipEmptyParts); - if (!lst.isEmpty()) { - QStringList without; - foreach (const QString term, lst) - without.append(d->escapeString(term)); - queryList.append(QHelpSearchQuery(QHelpSearchQuery::WITHOUT, without)); - } - - if (!d->exactQuery->text().isEmpty()) { - QString phrase = d->exactQuery->text().remove(QLatin1Char('\"')); - phrase = d->escapeString(phrase.simplified()); - queryList.append(QHelpSearchQuery(QHelpSearchQuery::PHRASE, QStringList(phrase))); - } - - lst = d->allQuery->text().split(exp, QString::SkipEmptyParts); - if (!lst.isEmpty()) { - QStringList all; - foreach (const QString term, lst) - all.append(d->escapeString(term)); - queryList.append(QHelpSearchQuery(QHelpSearchQuery::ALL, all)); - } - - lst = d->atLeastQuery->text().split(exp, QString::SkipEmptyParts); - if (!lst.isEmpty()) { - QStringList atLeast; - foreach (const QString term, lst) - atLeast += d->buildTermList(d->escapeString(term)); - queryList.append(QHelpSearchQuery(QHelpSearchQuery::ATLEAST, atLeast)); - } - } - return queryList; -#endif + const QHelpSearchQueryWidgetPrivate::QueryHistory &queryHist = + d->simpleSearch ? d->simpleQueries : d->complexQueries; + return queryHist.queries.isEmpty() ? + QList() : queryHist.queries.last(); } /*! \reimp -- cgit v0.12 From 232569c52844a4f661fe55001015ad5da5097ce7 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 4 Aug 2009 13:05:05 +0200 Subject: Fix ancestor flags that are not correctly update when reparenting. updateAncestorFlags was not reseting the flags if you change the parent that have for instance itemsClipChildrenToShape to a new one that doesn't have that flag. Task-number:258956 Reviewed-by:bnilsen --- src/gui/graphicsview/qgraphicsitem.cpp | 23 ++++++++++++----------- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index aa37981..7b650d2 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -638,18 +638,19 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch return; } - // Inherit the enabled-state from our parents. - if ((parent && ((parent->d_ptr->ancestorFlags & flag) - || (int(parent->d_ptr->flags & childFlag) == childFlag) - || (childFlag == -1 && parent->d_ptr->handlesChildEvents)))) { - enabled = true; - ancestorFlags |= flag; - } - - // Top-level root items don't have any ancestors, so there are no - // ancestor flags either. - if (!parent) + if (parent) { + // Inherit the enabled-state from our parents. + if ((parent->d_ptr->ancestorFlags & flag) || (int(parent->d_ptr->flags & childFlag) == childFlag) || (childFlag == -1 && parent->d_ptr->handlesChildEvents)) { + enabled = true; + ancestorFlags |= flag; + } else { + ancestorFlags &= ~flag; + } + } else { + // Top-level root items don't have any ancestors, so there are no + // ancestor flags either. ancestorFlags = 0; + } } else { // Don't set or propagate the ancestor flag if it's already correct. if (((ancestorFlags & flag) && enabled) || (!(ancestorFlags & flag) && !enabled)) diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 90c4636..ded8aca 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -665,6 +665,22 @@ void tst_QGraphicsItem::flags() QApplication::sendEvent(&scene, &event5); QCOMPARE(item->pos(), QPointF(10, 10)); } + { + QGraphicsItem* clippingParent = new QGraphicsRectItem; + clippingParent->setFlag(QGraphicsItem::ItemClipsChildrenToShape, true); + + QGraphicsItem* nonClippingParent = new QGraphicsRectItem; + nonClippingParent->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false); + + QGraphicsItem* child = new QGraphicsRectItem(nonClippingParent); + QVERIFY(!child->isClipped()); + + child->setParentItem(clippingParent); + QVERIFY(child->isClipped()); + + child->setParentItem(nonClippingParent); + QVERIFY(!child->isClipped()); + } } void tst_QGraphicsItem::toolTip() -- cgit v0.12 From 40d7153ad17d6eca96cb4718486e8e2654b72f00 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Tue, 4 Aug 2009 13:30:00 +0200 Subject: qdoc: Added \annotated list command to qdoc3. Now you can put "\annotatedlist xxx" anywhere in a qdoc comment, and it will generate the class list for the xxx group at that location. xxx must be a group name. --- tools/qdoc3/atom.cpp | 2 ++ tools/qdoc3/atom.h | 1 + tools/qdoc3/cppcodeparser.cpp | 3 +++ tools/qdoc3/doc.cpp | 32 ++++++++++++++++++-------------- tools/qdoc3/htmlgenerator.cpp | 14 ++++++++++++++ tools/qdoc3/tree.cpp | 2 ++ 6 files changed, 40 insertions(+), 14 deletions(-) diff --git a/tools/qdoc3/atom.cpp b/tools/qdoc3/atom.cpp index a82a783..da32735 100644 --- a/tools/qdoc3/atom.cpp +++ b/tools/qdoc3/atom.cpp @@ -93,6 +93,7 @@ QString Atom::UPPERROMAN_ ("upperroman"); \value AbstractLeft \value AbstractRight + \value AnnotatedList \value AutoLink \value BaseName \value BriefLeft @@ -163,6 +164,7 @@ static const struct { } atms[] = { { "AbstractLeft", Atom::AbstractLeft }, { "AbstractRight", Atom::AbstractRight }, + { "AnnotatedList", Atom::AnnotatedList }, { "AutoLink", Atom::AutoLink }, { "BaseName", Atom::BaseName }, { "BriefLeft", Atom::BriefLeft }, diff --git a/tools/qdoc3/atom.h b/tools/qdoc3/atom.h index 6d5af0a..941ac70 100644 --- a/tools/qdoc3/atom.h +++ b/tools/qdoc3/atom.h @@ -58,6 +58,7 @@ class Atom enum Type { AbstractLeft, AbstractRight, + AnnotatedList, AutoLink, BaseName, BriefLeft, diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp index 4563f65..562684b 100644 --- a/tools/qdoc3/cppcodeparser.cpp +++ b/tools/qdoc3/cppcodeparser.cpp @@ -1724,6 +1724,9 @@ bool CppCodeParser::matchProperty(InnerNode *parent) value = "?"; } + /* + Task 259071 requires work here. See gui/widgets/qdatetime.h, for example. + */ if (key == "READ") tre->addPropertyFunction(property, value, PropertyNode::Getter); else if (key == "WRITE") diff --git a/tools/qdoc3/doc.cpp b/tools/qdoc3/doc.cpp index d5aca0e..e2f3525 100644 --- a/tools/qdoc3/doc.cpp +++ b/tools/qdoc3/doc.cpp @@ -73,20 +73,20 @@ struct Macro }; enum { - CMD_A, CMD_ABSTRACT, CMD_BADCODE, CMD_BASENAME, CMD_BOLD, - CMD_BRIEF, CMD_C, CMD_CAPTION, CMD_CHAPTER, CMD_CODE, - CMD_CODELINE, CMD_DOTS, CMD_ELSE, CMD_ENDABSTRACT, - CMD_ENDCHAPTER, CMD_ENDCODE, CMD_ENDFOOTNOTE, CMD_ENDIF, - CMD_ENDLEGALESE, CMD_ENDLINK, CMD_ENDLIST, CMD_ENDOMIT, - CMD_ENDPART, CMD_ENDQUOTATION, CMD_ENDRAW, CMD_ENDSECTION1, - CMD_ENDSECTION2, CMD_ENDSECTION3, CMD_ENDSECTION4, - CMD_ENDSIDEBAR, CMD_ENDTABLE, CMD_EXPIRE, CMD_FOOTNOTE, - CMD_GENERATELIST, CMD_GRANULARITY, CMD_HEADER, CMD_I, - CMD_IF, CMD_IMAGE, CMD_INCLUDE, CMD_INLINEIMAGE, CMD_INDEX, - CMD_KEYWORD, CMD_L, CMD_LEGALESE, CMD_LINK, CMD_LIST, - CMD_META, CMD_NEWCODE, CMD_O, CMD_OLDCODE, CMD_OMIT, - CMD_OMITVALUE, CMD_OVERLOAD, - CMD_PART, CMD_PRINTLINE, CMD_PRINTTO, + CMD_A, CMD_ABSTRACT, CMD_ANNOTATEDLIST, CMD_BADCODE, + CMD_BASENAME, CMD_BOLD, CMD_BRIEF, CMD_C, CMD_CAPTION, + CMD_CHAPTER, CMD_CODE, CMD_CODELINE, CMD_DOTS, CMD_ELSE, + CMD_ENDABSTRACT, CMD_ENDCHAPTER, CMD_ENDCODE, + CMD_ENDFOOTNOTE, CMD_ENDIF, CMD_ENDLEGALESE, CMD_ENDLINK, + CMD_ENDLIST, CMD_ENDOMIT, CMD_ENDPART, CMD_ENDQUOTATION, + CMD_ENDRAW, CMD_ENDSECTION1, CMD_ENDSECTION2, + CMD_ENDSECTION3, CMD_ENDSECTION4, CMD_ENDSIDEBAR, + CMD_ENDTABLE, CMD_EXPIRE, CMD_FOOTNOTE, CMD_GENERATELIST, + CMD_GRANULARITY, CMD_HEADER, CMD_I, CMD_IF, CMD_IMAGE, + CMD_INCLUDE, CMD_INLINEIMAGE, CMD_INDEX, CMD_KEYWORD, + CMD_L, CMD_LEGALESE, CMD_LINK, CMD_LIST, CMD_META, + CMD_NEWCODE, CMD_O, CMD_OLDCODE, CMD_OMIT, CMD_OMITVALUE, + CMD_OVERLOAD, CMD_PART, CMD_PRINTLINE, CMD_PRINTTO, CMD_PRINTUNTIL, CMD_QUOTATION, CMD_QUOTEFILE, CMD_QUOTEFROMFILE, CMD_QUOTEFUNCTION, CMD_RAW, CMD_ROW, CMD_SA, CMD_SECTION1, CMD_SECTION2, CMD_SECTION3, @@ -108,6 +108,7 @@ static struct { } cmds[] = { { "a", CMD_A, 0 }, { "abstract", CMD_ABSTRACT, 0 }, + { "annotatedlist", CMD_ANNOTATEDLIST, 0 }, { "badcode", CMD_BADCODE, 0 }, { "basename", CMD_BASENAME, 0 }, // ### don't document for now { "bold", CMD_BOLD, 0 }, @@ -723,6 +724,9 @@ void DocParser::parse(const QString& source, paraState = OutsidePara; // ### } break; + case CMD_ANNOTATEDLIST: + append(Atom::AnnotatedList, getArgument()); + break; case CMD_GENERATELIST: append(Atom::GeneratedList, getArgument()); break; diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index 6590114..425c50b 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -537,6 +537,20 @@ int HtmlGenerator::generateAtom(const Atom *atom, out() << formattingRightMap()[atom->string()]; } break; + case Atom::AnnotatedList: + { + const FakeNode *fake = static_cast(relative); + if (fake && !fake->groupMembers().isEmpty()) { + QList values = tre->groups().values(atom->string()); + QMap nodeMap; + for (int i = 0; i < values.size(); ++i) { + const Node* n = values.at(i); + nodeMap.insert(n->name(),n); + } + generateAnnotatedList(fake, marker, nodeMap); + } + } + break; case Atom::GeneratedList: if (atom->string() == "annotatedclasses") { generateAnnotatedList(relative, marker, nonCompatClasses); diff --git a/tools/qdoc3/tree.cpp b/tools/qdoc3/tree.cpp index e6dd084..d75af70 100644 --- a/tools/qdoc3/tree.cpp +++ b/tools/qdoc3/tree.cpp @@ -419,6 +419,8 @@ void Tree::addPropertyFunction(PropertyNode *property, } /*! + This function adds the \a node to the \a group. The group + can be listed anywhere using the \e{annotated list} command. */ void Tree::addToGroup(Node *node, const QString &group) { -- cgit v0.12 From e888ff9902f193b8797d7993cd7d43e76045dcc1 Mon Sep 17 00:00:00 2001 From: ck Date: Tue, 4 Aug 2009 13:54:42 +0200 Subject: Assistant: Use non-GUI version of QApplication for command-line tasks. Task-number: 259136 Reviewed-by: kh --- tools/assistant/tools/assistant/main.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tools/assistant/tools/assistant/main.cpp b/tools/assistant/tools/assistant/main.cpp index a0a5a0d..4af2570 100644 --- a/tools/assistant/tools/assistant/main.cpp +++ b/tools/assistant/tools/assistant/main.cpp @@ -181,7 +181,21 @@ QString indexFilesFolder(const QString &collectionFile) int main(int argc, char *argv[]) { - QApplication a(argc, argv); + // First do a quick search for arguments that imply command-line mode. + const char * cmdModeArgs[] = { + "-help", "-register", "-unregister", "-remove-search-index" + }; + bool useGui = true; + for (int i = 1; i < argc; ++i) { + for (size_t j = 0; j < sizeof cmdModeArgs/sizeof *cmdModeArgs; ++j) { + if(strcmp(argv[i], cmdModeArgs[j]) == 0) { + useGui = false; + break; + } + } + } + + QApplication a(argc, argv, useGui); a.addLibraryPath(a.applicationDirPath() + QLatin1String("/plugins")); CmdLineParser cmd; -- cgit v0.12 From 2764dc0a0f4f8f6c87e716817ae99a7b57cdd23e Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 4 Aug 2009 14:13:57 +0200 Subject: Fix indentation. Reviewed-by:TrustMe --- src/gui/graphicsview/qgraphicsitem.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 7b650d2..40331fb 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -640,7 +640,9 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch if (parent) { // Inherit the enabled-state from our parents. - if ((parent->d_ptr->ancestorFlags & flag) || (int(parent->d_ptr->flags & childFlag) == childFlag) || (childFlag == -1 && parent->d_ptr->handlesChildEvents)) { + if ((parent->d_ptr->ancestorFlags & flag) + || (int(parent->d_ptr->flags & childFlag) == childFlag) + || (childFlag == -1 && parent->d_ptr->handlesChildEvents)) { enabled = true; ancestorFlags |= flag; } else { -- cgit v0.12 From 69c379451f496071c51542dab876d41916b62889 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 4 Aug 2009 14:19:12 +0200 Subject: have QPainter::begin() return false on null paint engine Reviewed-by: Samuel --- src/gui/painting/qpainter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 9c7a7fa..8192fb7 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -1672,7 +1672,7 @@ bool QPainter::begin(QPaintDevice *pd) if (!d->engine) { qWarning("QPainter::begin: Paint device returned engine == 0, type: %d", pd->devType()); - return true; + return false; } // Slip a painter state into the engine before we do any other operations -- cgit v0.12 From b6275b9dd1a852c86b22b354bfae3c98c8191fda Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 4 Aug 2009 14:26:39 +0200 Subject: Animations: better handling of the timer It could be that if you start lots of animations, they would not be started at the same time and even have their first tick to late. So we needed to only transfer the started animation when receiving the start/stop timer tick. In addition, if the animation timer is already active we don't restart it. This would cause no animation to receive ticks if lots of them are started. --- src/corelib/animation/qabstractanimation.cpp | 30 ++++++---------------------- src/corelib/animation/qabstractanimation_p.h | 3 --- 2 files changed, 6 insertions(+), 27 deletions(-) diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index ced86d2..1d274c9 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -177,17 +177,6 @@ QUnifiedTimer *QUnifiedTimer::instance() return inst; } -void QUnifiedTimer::updateRecentlyStartedAnimations() -{ - if (animationsToStart.isEmpty()) - return; - - animations += animationsToStart; - updateTimer(); //we make sure we start the timer there - - animationsToStart.clear(); -} - void QUnifiedTimer::timerEvent(QTimerEvent *event) { //this is simply the time we last received a tick @@ -195,15 +184,16 @@ void QUnifiedTimer::timerEvent(QTimerEvent *event) if (time.isValid()) lastTick = consistentTiming ? oldLastTick + timingInterval : time.elapsed(); - //we transfer the waiting animations into the "really running" state - updateRecentlyStartedAnimations(); if (event->timerId() == startStopAnimationTimer.timerId()) { startStopAnimationTimer.stop(); + //we transfer the waiting animations into the "really running" state + animations += animationsToStart; + animationsToStart.clear(); if (animations.isEmpty()) { animationTimer.stop(); time = QTime(); - } else { + } else if (!animationTimer.isActive()) { animationTimer.start(timingInterval, this); lastTick = 0; time.start(); @@ -219,27 +209,19 @@ void QUnifiedTimer::timerEvent(QTimerEvent *event) } } -void QUnifiedTimer::updateTimer() -{ - //we delay the call to start and stop for the animation timer so that if you - //stop and start animations in batch you don't stop/start the timer too often. - if (!startStopAnimationTimer.isActive()) - startStopAnimationTimer.start(0, this); // we delay the actual start of the animation -} - void QUnifiedTimer::registerAnimation(QAbstractAnimation *animation) { if (animations.contains(animation) ||animationsToStart.contains(animation)) return; animationsToStart << animation; - updateTimer(); + startStopAnimationTimer.start(0, this); // we delay the check if we should start/stop the global timer } void QUnifiedTimer::unregisterAnimation(QAbstractAnimation *animation) { animations.removeAll(animation); animationsToStart.removeAll(animation); - updateTimer(); + startStopAnimationTimer.start(0, this); // we delay the check if we should start/stop the global timer } diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index 0d8402e..b281aa2 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -135,11 +135,8 @@ public: protected: void timerEvent(QTimerEvent *); - void updateTimer(); private: - void updateRecentlyStartedAnimations(); - QBasicTimer animationTimer, startStopAnimationTimer; QTime time; int lastTick; -- cgit v0.12 From 30e3a39ca2e5e1204cc123dce2f2921d8fda620d Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 4 Aug 2009 15:03:15 +0200 Subject: QParallelAnimationGroup pause resume fixed If you resumed a parallel animation group, it would always restart (ie. stop and start) the animation which would reset its current time to 0 and trigger flickering. autotest included. Task-Number: 259102 --- src/corelib/animation/qparallelanimationgroup.cpp | 3 +- .../tst_qparallelanimationgroup.cpp | 33 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/corelib/animation/qparallelanimationgroup.cpp b/src/corelib/animation/qparallelanimationgroup.cpp index 5e4b0d2..8aa04a4 100644 --- a/src/corelib/animation/qparallelanimationgroup.cpp +++ b/src/corelib/animation/qparallelanimationgroup.cpp @@ -214,7 +214,8 @@ void QParallelAnimationGroup::updateState(QAbstractAnimation::State oldState, d->connectUncontrolledAnimations(); for (int i = 0; i < d->animations.size(); ++i) { QAbstractAnimation *animation = d->animations.at(i); - animation->stop(); + if (oldState == Stopped) + animation->stop(); animation->setDirection(d->direction); animation->start(); } diff --git a/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp b/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp index d7d6b88..16c58b0 100644 --- a/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp +++ b/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp @@ -74,6 +74,7 @@ private slots: void loopCount_data(); void loopCount(); void autoAdd(); + void pauseResume(); }; tst_QParallelAnimationGroup::tst_QParallelAnimationGroup() @@ -828,5 +829,37 @@ void tst_QParallelAnimationGroup::autoAdd() QCOMPARE(group.duration(), 0); } +void tst_QParallelAnimationGroup::pauseResume() +{ + QParallelAnimationGroup group; + TestAnimation2 *anim = new TestAnimation2(250, &group); // 0, duration = 250; + QSignalSpy spy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + QCOMPARE(group.duration(), 250); + group.start(); + QTest::qWait(100); + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(anim->state(), QAnimationGroup::Running); + QCOMPARE(spy.count(), 1); + spy.clear(); + const int currentTime = group.currentTime(); + QCOMPARE(anim->currentTime(), currentTime); + + group.pause(); + QCOMPARE(group.state(), QAnimationGroup::Paused); + QCOMPARE(group.currentTime(), currentTime); + QCOMPARE(anim->state(), QAnimationGroup::Paused); + QCOMPARE(anim->currentTime(), currentTime); + QCOMPARE(spy.count(), 1); + spy.clear(); + + group.resume(); + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(group.currentTime(), currentTime); + QCOMPARE(anim->state(), QAnimationGroup::Running); + QCOMPARE(anim->currentTime(), currentTime); + QCOMPARE(spy.count(), 1); +} + + QTEST_MAIN(tst_QParallelAnimationGroup) #include "tst_qparallelanimationgroup.moc" -- cgit v0.12 From b80a499764bf331880ff0c0d52670a419ec50feb Mon Sep 17 00:00:00 2001 From: jasplin Date: Tue, 4 Aug 2009 15:44:45 +0200 Subject: Added input hints to QGraphicsItem. This patch allows for input hints to be set on a QGraphicsItem. Input methods use such hints to define its appearance/behavior (e.g. to allow for numerical input only). Reviewed-by: ahanssen Task-number: 254493 --- doc/src/classes/qnamespace.qdoc | 24 ++++++++++++++++++ src/corelib/global/qnamespace.h | 16 ++++++++++++ src/gui/graphicsview/qgraphicsitem.cpp | 35 +++++++++++++++++++++++++- src/gui/graphicsview/qgraphicsitem.h | 3 +++ src/gui/graphicsview/qgraphicsitem_p.h | 4 ++- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 13 ++++++++++ 6 files changed, 93 insertions(+), 2 deletions(-) diff --git a/doc/src/classes/qnamespace.qdoc b/doc/src/classes/qnamespace.qdoc index 59e0a95..a49e079 100644 --- a/doc/src/classes/qnamespace.qdoc +++ b/doc/src/classes/qnamespace.qdoc @@ -2418,6 +2418,30 @@ */ /*! + \enum Qt::InputMethodHint + + \value ImhNone No hints. + \value ImhHiddenText Characters should be hidden, as is typically used when entering passwords. + This is automatically set when setting QLineEdit::echoMode to \c Password. + \value ImhNumbersOnly Only number input is allowed. + \value ImhUppercaseOnly Only upper case letter input is allowed. + \value ImhLowercaseOnly Only lower case letter input is allowed. + \value ImhNoAutoUppercase The input method should not try to automatically switch to upper case + when a sentence ends. + \value ImhPreferNumbers Numbers are preferred (but not required). + \value ImhPreferUppercase Upper case letters are preferred (but not required). + \value ImhPreferLowercase Lower case letters are preferred (but not required). + \value ImhNoPredictiveText Do not use predictive text (i.e. dictionary lookup) while typing. + \value ImhDialableCharactersOnly Only characters suitable for phone dialling are allowed. + + \note If several flags ending with \c Only are ORed together, the resulting character set will + consist of the union of the specified sets. For instance specifying \c ImhNumbersOnly and + \c ImhUppercaseOnly would yield a set consisting of numbers and uppercase letters. + + \sa QGraphicsItem::inputMethodHints() +*/ + +/*! \enum Qt::InputMethodQuery \value ImMicroFocus The rectangle covering the area of the input cursor in widget coordinates. diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 7770fd6..f172d77 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1406,6 +1406,21 @@ public: ImCurrentSelection }; + enum InputMethodHint { + ImhNone = 0x0, + ImhHiddenText = 0x1, + ImhNumbersOnly = 0x2, + ImhUppercaseOnly = 0x4, + ImhLowercaseOnly = 0x8, + ImhNoAutoUppercase = 0x10, + ImhPreferNumbers = 0x20, + ImhPreferUppercase = 0x40, + ImhPreferLowercase = 0x80, + ImhNoPredictiveText = 0x100, + ImhDialableCharactersOnly = 0x200 + }; + Q_DECLARE_FLAGS(InputMethodHints, InputMethodHint) + enum ToolButtonStyle { ToolButtonIconOnly, ToolButtonTextOnly, @@ -1591,6 +1606,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::ItemFlags) Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::MatchFlags) Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TextInteractionFlags) Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TouchPointStates) +Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::InputMethodHints) typedef bool (*qInternalCallback)(void **); diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index a047e6a..6a21e99 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -6384,7 +6384,7 @@ void QGraphicsItem::inputMethodEvent(QInputMethodEvent *event) surrounding text and reconversions. \a query specifies which property is queried. - \sa inputMethodEvent() + \sa inputMethodEvent(), QInputMethodEvent, QInputContext */ QVariant QGraphicsItem::inputMethodQuery(Qt::InputMethodQuery query) const { @@ -6400,6 +6400,39 @@ QVariant QGraphicsItem::inputMethodQuery(Qt::InputMethodQuery query) const } /*! + Returns the current input method hints of this item. + + Input method hints are only relevant for input items. + The hints are used by the input method to indicate how it should operate. + For example, if the Qt::ImhNumbersOnly flag is set, the input method may change + its visual components to reflect that only numbers can be entered. + + The effect may vary between input method implementations. + + \since 4.6 + + \sa setInputMethodHints(), inputMethodQuery(), QInputContext +*/ +Qt::InputMethodHints QGraphicsItem::inputMethodHints() const +{ + Q_D(const QGraphicsItem); + return d->imHints; +} + +/*! + Sets the current input method hints of this item to \a hints. + + \since 4.6 + + \sa inputMethodHints(), inputMethodQuery(), QInputContext +*/ +void QGraphicsItem::setInputMethodHints(Qt::InputMethodHints hints) +{ + Q_D(QGraphicsItem); + d->imHints = hints; +} + +/*! This virtual function is called by QGraphicsItem to notify custom items that some part of the item's state changes. By reimplementing this function, your can react to a change, and in some cases, (depending on \a diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index b94fb97..f142b0f 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -375,6 +375,9 @@ public: QVariant data(int key) const; void setData(int key, const QVariant &value); + Qt::InputMethodHints inputMethodHints() const; + void setInputMethodHints(Qt::InputMethodHints hints); + enum { Type = 1, UserType = 65536 diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 5c3622b..805b554 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -126,6 +126,7 @@ public: depth(0), focusProxy(0), subFocusItem(0), + imHints(Qt::ImhNone), acceptedMouseButtons(0x1f), visible(1), explicitlyHidden(0), @@ -419,8 +420,9 @@ public: int depth; QGraphicsItem *focusProxy; QGraphicsItem *subFocusItem; + Qt::InputMethodHints imHints; - // Packed 32 bytes + // Packed 32 bits quint32 acceptedMouseButtons : 5; quint32 visible : 1; quint32 explicitlyHidden : 1; diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 7f6f322..ef3f0f8 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -169,6 +169,7 @@ private slots: void setParentItem(); void children(); void flags(); + void inputMethodHints(); void toolTip(); void visible(); void explicitlyVisible(); @@ -762,6 +763,18 @@ void tst_QGraphicsItem::flags() } } +class ImhTester : public QGraphicsItem +{ + QRectF boundingRect() const { return QRectF(); } + void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) {} +}; + +void tst_QGraphicsItem::inputMethodHints() +{ + ImhTester item; + QCOMPARE(item.inputMethodHints(), Qt::ImhNone); +} + void tst_QGraphicsItem::toolTip() { QString toolTip = "Qt rocks!"; -- cgit v0.12 From 69f0ba079899970aa53351a7d6b864f0a2bb8343 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 4 Aug 2009 16:04:55 +0200 Subject: Fix build on Harmattan --- src/gui/egl/qegl_x11.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp index daaa4ba..6772592 100644 --- a/src/gui/egl/qegl_x11.cpp +++ b/src/gui/egl/qegl_x11.cpp @@ -39,15 +39,18 @@ ** ****************************************************************************/ +#include + +#include +#include +#include +#include + #include #include #include -#include #include "qegl_p.h" -#include -#include -#include QT_BEGIN_NAMESPACE -- cgit v0.12 From df373516909d4dc0dfe8149f4cbff17c9c9bfe54 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Tue, 4 Aug 2009 14:00:05 +0200 Subject: QHttpNetworkConnection: Moved channel slots to channel object Reviewed-by: Peter Hartmann --- src/network/access/qhttpnetworkconnection.cpp | 246 +-------------------- src/network/access/qhttpnetworkconnection_p.h | 30 +-- .../access/qhttpnetworkconnectionchannel.cpp | 214 ++++++++++++++++++ .../access/qhttpnetworkconnectionchannel_p.h | 25 +++ src/network/access/qhttpnetworkreply_p.h | 1 + 5 files changed, 249 insertions(+), 267 deletions(-) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 75ab837..d73cd67 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -87,58 +87,11 @@ QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate() delete []channels; } -void QHttpNetworkConnectionPrivate::connectSignals(QAbstractSocket *socket) -{ - Q_Q(QHttpNetworkConnection); - - QObject::connect(socket, SIGNAL(bytesWritten(qint64)), - q, SLOT(_q_bytesWritten(qint64)), - Qt::DirectConnection); - QObject::connect(socket, SIGNAL(connected()), - q, SLOT(_q_connected()), - Qt::DirectConnection); - QObject::connect(socket, SIGNAL(readyRead()), - q, SLOT(_q_readyRead()), - Qt::DirectConnection); - QObject::connect(socket, SIGNAL(disconnected()), - q, SLOT(_q_disconnected()), - Qt::DirectConnection); - QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), - q, SLOT(_q_error(QAbstractSocket::SocketError)), - Qt::DirectConnection); -#ifndef QT_NO_NETWORKPROXY - QObject::connect(socket, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)), - q, SLOT(_q_proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)), - Qt::DirectConnection); -#endif - -#ifndef QT_NO_OPENSSL - QSslSocket *sslSocket = qobject_cast(socket); - if (sslSocket) { - // won't be a sslSocket if encrypt is false - QObject::connect(sslSocket, SIGNAL(encrypted()), - q, SLOT(_q_encrypted()), - Qt::DirectConnection); - QObject::connect(sslSocket, SIGNAL(sslErrors(const QList&)), - q, SLOT(_q_sslErrors(const QList&)), - Qt::DirectConnection); - } -#endif -} - void QHttpNetworkConnectionPrivate::init() { - for (int i = 0; i < channelCount; ++i) { -#ifndef QT_NO_OPENSSL - if (encrypt) - channels[i].socket = new QSslSocket; - else - channels[i].socket = new QTcpSocket; -#else - channels[i].socket = new QTcpSocket; -#endif - - connectSignals(channels[i].socket); + for (int i = 0; i < channelCount; i++) { + channels[i].setConnection(this->q_func()); + channels[i].init(); } } @@ -406,7 +359,7 @@ bool QHttpNetworkConnectionPrivate::sendRequest(QAbstractSocket *socket) QNonContiguousByteDevice* uploadByteDevice = channels[i].request.uploadByteDevice(); if (uploadByteDevice) { // connect the signals so this function gets called again - QObject::connect(uploadByteDevice, SIGNAL(readyRead()), q, SLOT(_q_uploadDataReadyRead())); + QObject::connect(uploadByteDevice, SIGNAL(readyRead()), &channels[i], SLOT(_q_uploadDataReadyRead())); channels[i].bytesTotal = channels[i].request.contentLength(); } else { @@ -485,7 +438,7 @@ bool QHttpNetworkConnectionPrivate::sendRequest(QAbstractSocket *socket) { QNonContiguousByteDevice* uploadByteDevice = channels[i].request.uploadByteDevice(); if (uploadByteDevice) { - QObject::disconnect(uploadByteDevice, SIGNAL(readyRead()), q, SLOT(_q_uploadDataReadyRead())); + QObject::disconnect(uploadByteDevice, SIGNAL(readyRead()), &channels[i], SLOT(_q_uploadDataReadyRead())); } // ensure we try to receive a reply in all cases, even if _q_readyRead_ hat not been called // this is needed if the sends an reply before we have finished sending the request. In that @@ -1004,11 +957,7 @@ void QHttpNetworkConnectionPrivate::unqueueAndSendRequest(QAbstractSocket *socke void QHttpNetworkConnectionPrivate::closeChannel(int channel) { - QAbstractSocket *socket = channels[channel].socket; - socket->blockSignals(true); - socket->close(); - socket->blockSignals(false); - channels[channel].state = QHttpNetworkConnectionChannel::IdleState; + channels[channel].close(); } void QHttpNetworkConnectionPrivate::resendCurrentRequest(QAbstractSocket *socket) @@ -1102,53 +1051,6 @@ void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply) } -//private slots -void QHttpNetworkConnectionPrivate::_q_readyRead() -{ - Q_Q(QHttpNetworkConnection); - QAbstractSocket *socket = qobject_cast(q->sender()); - if (!socket) - return; // ### error - if (isSocketWaiting(socket) || isSocketReading(socket)) { - int i = indexOf(socket); - channels[i].state = QHttpNetworkConnectionChannel::ReadingState; - if (channels[i].reply) - receiveReply(socket, channels[i].reply); - } - // ### error -} - -void QHttpNetworkConnectionPrivate::_q_bytesWritten(qint64 bytes) -{ - Q_UNUSED(bytes); - Q_Q(QHttpNetworkConnection); - QAbstractSocket *socket = qobject_cast(q->sender()); - if (!socket) - return; // ### error - // bytes have been written to the socket. write even more of them :) - if (isSocketWriting(socket)) - sendRequest(socket); - // otherwise we do nothing -} - -void QHttpNetworkConnectionPrivate::_q_disconnected() -{ - Q_Q(QHttpNetworkConnection); - QAbstractSocket *socket = qobject_cast(q->sender()); - if (!socket) - return; // ### error - // read the available data before closing - int i = indexOf(socket); - if (isSocketWaiting(socket) || isSocketReading(socket)) { - channels[i].state = QHttpNetworkConnectionChannel::ReadingState; - if (channels[i].reply) - receiveReply(socket, channels[i].reply); - } else if (channels[i].state == QHttpNetworkConnectionChannel::IdleState && channels[i].resendCurrent) { - // re-sending request because the socket was in ClosingState - QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); - } - channels[i].state = QHttpNetworkConnectionChannel::IdleState; -} void QHttpNetworkConnectionPrivate::_q_startNextRequest() { @@ -1188,121 +1090,6 @@ void QHttpNetworkConnectionPrivate::_q_restartAuthPendingRequests() } } -void QHttpNetworkConnectionPrivate::_q_connected() -{ - Q_Q(QHttpNetworkConnection); - QAbstractSocket *socket = qobject_cast(q->sender()); - if (!socket) - return; // ### error - - // improve performance since we get the request sent by the kernel ASAP - socket->setSocketOption(QAbstractSocket::LowDelayOption, 1); - - int i = indexOf(socket); - // ### FIXME: if the server closes the connection unexpectedly, we shouldn't send the same broken request again! - //channels[i].reconnectAttempts = 2; - if (!channels[i].pendingEncrypt) { - channels[i].state = QHttpNetworkConnectionChannel::IdleState; - if (channels[i].reply) - sendRequest(socket); - else - closeChannel(i); - } -} - - -void QHttpNetworkConnectionPrivate::_q_error(QAbstractSocket::SocketError socketError) -{ - Q_Q(QHttpNetworkConnection); - QAbstractSocket *socket = qobject_cast(q->sender()); - if (!socket) - return; - bool send2Reply = false; - int i = indexOf(socket); - QNetworkReply::NetworkError errorCode = QNetworkReply::UnknownNetworkError; - - switch (socketError) { - case QAbstractSocket::HostNotFoundError: - errorCode = QNetworkReply::HostNotFoundError; - break; - case QAbstractSocket::ConnectionRefusedError: - errorCode = QNetworkReply::ConnectionRefusedError; - break; - case QAbstractSocket::RemoteHostClosedError: - // try to reconnect/resend before sending an error. - // while "Reading" the _q_disconnected() will handle this. - if (channels[i].state != QHttpNetworkConnectionChannel::IdleState && channels[i].state != QHttpNetworkConnectionChannel::ReadingState) { - if (channels[i].reconnectAttempts-- > 0) { - resendCurrentRequest(socket); - return; - } else { - send2Reply = true; - errorCode = QNetworkReply::RemoteHostClosedError; - } - } else { - return; - } - break; - case QAbstractSocket::SocketTimeoutError: - // try to reconnect/resend before sending an error. - if (channels[i].state == QHttpNetworkConnectionChannel::WritingState && (channels[i].reconnectAttempts-- > 0)) { - resendCurrentRequest(socket); - return; - } - send2Reply = true; - errorCode = QNetworkReply::TimeoutError; - break; - case QAbstractSocket::ProxyAuthenticationRequiredError: - errorCode = QNetworkReply::ProxyAuthenticationRequiredError; - break; - case QAbstractSocket::SslHandshakeFailedError: - errorCode = QNetworkReply::SslHandshakeFailedError; - break; - default: - // all other errors are treated as NetworkError - errorCode = QNetworkReply::UnknownNetworkError; - break; - } - QPointer that = q; - QString errorString = errorDetail(errorCode, socket); - if (send2Reply) { - if (channels[i].reply) { - channels[i].reply->d_func()->errorString = errorString; - // this error matters only to this reply - emit channels[i].reply->finishedWithError(errorCode, errorString); - } - // send the next request - QMetaObject::invokeMethod(that, "_q_startNextRequest", Qt::QueuedConnection); - } else { - // the failure affects all requests. - emit q->error(errorCode, errorString); - } - if (that) //signals make enter the event loop - closeChannel(i); -} - -#ifndef QT_NO_NETWORKPROXY -void QHttpNetworkConnectionPrivate::_q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator* auth) -{ - Q_Q(QHttpNetworkConnection); - emit q->proxyAuthenticationRequired(proxy, auth, q); -} -#endif - -void QHttpNetworkConnectionPrivate::_q_uploadDataReadyRead() -{ - Q_Q(QHttpNetworkConnection); - // upload data emitted readyRead() - // find out which channel it is for - QObject *sender = q->sender(); - - for (int i = 0; i < channelCount; ++i) { - if (sender == channels[i].request.uploadByteDevice()) { - sendRequest(channels[i].socket); - break; - } - } -} QHttpNetworkConnection::QHttpNetworkConnection(const QString &hostName, quint16 port, bool encrypt, QObject *parent) : QObject(*(new QHttpNetworkConnectionPrivate(hostName, port, encrypt)), parent) @@ -1397,27 +1184,6 @@ QNetworkProxy QHttpNetworkConnection::transparentProxy() const // SSL support below #ifndef QT_NO_OPENSSL -void QHttpNetworkConnectionPrivate::_q_encrypted() -{ - Q_Q(QHttpNetworkConnection); - QAbstractSocket *socket = qobject_cast(q->sender()); - if (!socket) - return; // ### error - int i = indexOf(socket); - channels[i].state = QHttpNetworkConnectionChannel::IdleState; - sendRequest(socket); -} - -void QHttpNetworkConnectionPrivate::_q_sslErrors(const QList &errors) -{ - Q_Q(QHttpNetworkConnection); - QAbstractSocket *socket = qobject_cast(q->sender()); - if (!socket) - return; - //QNetworkReply::NetworkError errorCode = QNetworkReply::ProtocolFailure; - emit q->sslErrors(errors); -} - QSslConfiguration QHttpNetworkConnectionPrivate::sslConfiguration(const QHttpNetworkReply &reply) const { if (!encrypt) diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index db6a140..48401d2 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -138,23 +138,10 @@ private: Q_DECLARE_PRIVATE(QHttpNetworkConnection) Q_DISABLE_COPY(QHttpNetworkConnection) friend class QHttpNetworkReply; + friend class QHttpNetworkConnectionChannel; - Q_PRIVATE_SLOT(d_func(), void _q_bytesWritten(qint64)) - Q_PRIVATE_SLOT(d_func(), void _q_readyRead()) - Q_PRIVATE_SLOT(d_func(), void _q_disconnected()) Q_PRIVATE_SLOT(d_func(), void _q_startNextRequest()) Q_PRIVATE_SLOT(d_func(), void _q_restartAuthPendingRequests()) - Q_PRIVATE_SLOT(d_func(), void _q_connected()) - Q_PRIVATE_SLOT(d_func(), void _q_error(QAbstractSocket::SocketError)) -#ifndef QT_NO_NETWORKPROXY - Q_PRIVATE_SLOT(d_func(), void _q_proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)) -#endif - Q_PRIVATE_SLOT(d_func(), void _q_uploadDataReadyRead()) - -#ifndef QT_NO_OPENSSL - Q_PRIVATE_SLOT(d_func(), void _q_encrypted()) - Q_PRIVATE_SLOT(d_func(), void _q_sslErrors(const QList&)) -#endif }; @@ -169,7 +156,6 @@ public: QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt); ~QHttpNetworkConnectionPrivate(); void init(); - void connectSignals(QAbstractSocket *socket); enum { ChunkSize = 4096 }; @@ -189,18 +175,8 @@ public: void copyCredentials(int fromChannel, QAuthenticator *auth, bool isProxy); // private slots - void _q_bytesWritten(qint64 bytes); // proceed sending - void _q_readyRead(); // pending data to read - void _q_disconnected(); // disconnected from host void _q_startNextRequest(); // send the next request from the queue void _q_restartAuthPendingRequests(); // send the currently blocked request - void _q_connected(); // start sending request - void _q_error(QAbstractSocket::SocketError); // error from socket -#ifndef QT_NO_NETWORKPROXY - void _q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth); // from transparent proxy -#endif - - void _q_uploadDataReadyRead(); void createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request); bool ensureConnection(QAbstractSocket *socket); @@ -237,8 +213,6 @@ public: inline bool expectContent(QHttpNetworkReply *reply); #ifndef QT_NO_OPENSSL - void _q_encrypted(); // start sending request (https) - void _q_sslErrors(const QList &errors); // ssl errors from the socket QSslConfiguration sslConfiguration(const QHttpNetworkReply &reply) const; #endif @@ -249,6 +223,8 @@ public: //The request queues QList highPriorityQueue; QList lowPriorityQueue; + + friend class QHttpNetworkConnectionChannel; }; diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index a04b530..6cd46fd 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -57,6 +57,220 @@ QT_BEGIN_NAMESPACE // TODO: Put channel specific stuff here so it does not polute qhttpnetworkconnection.cpp +void QHttpNetworkConnectionChannel::init() +{ +#ifndef QT_NO_OPENSSL + if (connection->d_func()->encrypt) + socket = new QSslSocket; + else + socket = new QTcpSocket; +#else + socket = new QTcpSocket; +#endif + + QObject::connect(socket, SIGNAL(bytesWritten(qint64)), + this, SLOT(_q_bytesWritten(qint64)), + Qt::DirectConnection); + QObject::connect(socket, SIGNAL(connected()), + this, SLOT(_q_connected()), + Qt::DirectConnection); + QObject::connect(socket, SIGNAL(readyRead()), + this, SLOT(_q_readyRead()), + Qt::DirectConnection); + QObject::connect(socket, SIGNAL(disconnected()), + this, SLOT(_q_disconnected()), + Qt::DirectConnection); + QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(_q_error(QAbstractSocket::SocketError)), + Qt::DirectConnection); +#ifndef QT_NO_NETWORKPROXY + QObject::connect(socket, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)), + this, SLOT(_q_proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)), + Qt::DirectConnection); +#endif + +#ifndef QT_NO_OPENSSL + QSslSocket *sslSocket = qobject_cast(socket); + if (sslSocket) { + // won't be a sslSocket if encrypt is false + QObject::connect(sslSocket, SIGNAL(encrypted()), + this, SLOT(_q_encrypted()), + Qt::DirectConnection); + QObject::connect(sslSocket, SIGNAL(sslErrors(const QList&)), + this, SLOT(_q_sslErrors(const QList&)), + Qt::DirectConnection); + } +#endif +} + + +void QHttpNetworkConnectionChannel::close() +{ + socket->blockSignals(true); + socket->close(); + socket->blockSignals(false); + state = QHttpNetworkConnectionChannel::IdleState; +} + + +//private slots +void QHttpNetworkConnectionChannel::_q_readyRead() +{ + if (!socket) + return; // ### error + if (connection->d_func()->isSocketWaiting(socket) || connection->d_func()->isSocketReading(socket)) { + state = QHttpNetworkConnectionChannel::ReadingState; + if (reply) + connection->d_func()->receiveReply(socket, reply); + } + // ### error +} + +void QHttpNetworkConnectionChannel::_q_bytesWritten(qint64 bytes) +{ + Q_UNUSED(bytes); + if (!socket) + return; // ### error + // bytes have been written to the socket. write even more of them :) + if (connection->d_func()->isSocketWriting(socket)) + connection->d_func()->sendRequest(socket); + // otherwise we do nothing +} + +void QHttpNetworkConnectionChannel::_q_disconnected() +{ + if (!socket) + return; // ### error + // read the available data before closing + if (connection->d_func()->isSocketWaiting(socket) || connection->d_func()->isSocketReading(socket)) { + state = QHttpNetworkConnectionChannel::ReadingState; + if (reply) + connection->d_func()->receiveReply(socket, reply); + } else if (state == QHttpNetworkConnectionChannel::IdleState && resendCurrent) { + // re-sending request because the socket was in ClosingState + QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); + } + state = QHttpNetworkConnectionChannel::IdleState; +} + + +void QHttpNetworkConnectionChannel::_q_connected() +{ + if (!socket) + return; // ### error + + // improve performance since we get the request sent by the kernel ASAP + socket->setSocketOption(QAbstractSocket::LowDelayOption, 1); + + // ### FIXME: if the server closes the connection unexpectedly, we shouldn't send the same broken request again! + //channels[i].reconnectAttempts = 2; + if (!pendingEncrypt) { + state = QHttpNetworkConnectionChannel::IdleState; + if (reply) + connection->d_func()->sendRequest(socket); + else + close(); + } +} + + +void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socketError) +{ + if (!socket) + return; + bool send2Reply = false; + QNetworkReply::NetworkError errorCode = QNetworkReply::UnknownNetworkError; + + switch (socketError) { + case QAbstractSocket::HostNotFoundError: + errorCode = QNetworkReply::HostNotFoundError; + break; + case QAbstractSocket::ConnectionRefusedError: + errorCode = QNetworkReply::ConnectionRefusedError; + break; + case QAbstractSocket::RemoteHostClosedError: + // try to reconnect/resend before sending an error. + // while "Reading" the _q_disconnected() will handle this. + if (state != QHttpNetworkConnectionChannel::IdleState && state != QHttpNetworkConnectionChannel::ReadingState) { + if (reconnectAttempts-- > 0) { + connection->d_func()->resendCurrentRequest(socket); + return; + } else { + send2Reply = true; + errorCode = QNetworkReply::RemoteHostClosedError; + } + } else { + return; + } + break; + case QAbstractSocket::SocketTimeoutError: + // try to reconnect/resend before sending an error. + if (state == QHttpNetworkConnectionChannel::WritingState && (reconnectAttempts-- > 0)) { + connection->d_func()->resendCurrentRequest(socket); + return; + } + send2Reply = true; + errorCode = QNetworkReply::TimeoutError; + break; + case QAbstractSocket::ProxyAuthenticationRequiredError: + errorCode = QNetworkReply::ProxyAuthenticationRequiredError; + break; + case QAbstractSocket::SslHandshakeFailedError: + errorCode = QNetworkReply::SslHandshakeFailedError; + break; + default: + // all other errors are treated as NetworkError + errorCode = QNetworkReply::UnknownNetworkError; + break; + } + QPointer that = connection; + QString errorString = connection->d_func()->errorDetail(errorCode, socket); + if (send2Reply) { + if (reply) { + reply->d_func()->errorString = errorString; + // this error matters only to this reply + emit reply->finishedWithError(errorCode, errorString); + } + // send the next request + QMetaObject::invokeMethod(that, "_q_startNextRequest", Qt::QueuedConnection); + } else { + // the failure affects all requests. + emit connection->error(errorCode, errorString); + } + if (that) //signal emission triggered event loop + close(); +} + +#ifndef QT_NO_NETWORKPROXY +void QHttpNetworkConnectionChannel::_q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator* auth) +{ + emit connection->proxyAuthenticationRequired(proxy, auth, connection); +} +#endif + +void QHttpNetworkConnectionChannel::_q_uploadDataReadyRead() +{ + connection->d_func()->sendRequest(socket); +} + +#ifndef QT_NO_OPENSSL +void QHttpNetworkConnectionChannel::_q_encrypted() +{ + if (!socket) + return; // ### error + state = QHttpNetworkConnectionChannel::IdleState; + connection->d_func()->sendRequest(socket); +} + +void QHttpNetworkConnectionChannel::_q_sslErrors(const QList &errors) +{ + if (!socket) + return; + //QNetworkReply::NetworkError errorCode = QNetworkReply::ProtocolFailure; + emit connection->sslErrors(errors); +} +#endif + QT_END_NAMESPACE #include "moc_qhttpnetworkconnectionchannel_p.cpp" diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index cbabc67..013e7a5 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -80,6 +80,7 @@ QT_BEGIN_NAMESPACE class QHttpNetworkRequest; class QHttpNetworkReply; class QByteArray; +class QHttpNetworkConnection; class QHttpNetworkConnectionChannel : public QObject { Q_OBJECT @@ -117,7 +118,31 @@ public: #ifndef QT_NO_OPENSSL , ignoreAllSslErrors(false) #endif + , connection(0) {} + + void setConnection(QHttpNetworkConnection *c) {connection = c;} + QHttpNetworkConnection *connection; + + void init(); + void close(); + + protected slots: + void _q_bytesWritten(qint64 bytes); // proceed sending + void _q_readyRead(); // pending data to read + void _q_disconnected(); // disconnected from host + void _q_connected(); // start sending request + void _q_error(QAbstractSocket::SocketError); // error from socket +#ifndef QT_NO_NETWORKPROXY + void _q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth); // from transparent proxy +#endif + + void _q_uploadDataReadyRead(); + +#ifndef QT_NO_OPENSSL + void _q_encrypted(); // start sending request (https) + void _q_sslErrors(const QList &errors); // ssl errors from the socket +#endif }; diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index 575e824..a386b10 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -149,6 +149,7 @@ private: Q_DECLARE_PRIVATE(QHttpNetworkReply) friend class QHttpNetworkConnection; friend class QHttpNetworkConnectionPrivate; + friend class QHttpNetworkConnectionChannel; }; -- cgit v0.12 From 627c5c865d77cca1f0d6508f8facfe6c0bf4d363 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Tue, 4 Aug 2009 16:16:32 +0200 Subject: QNAM HTTP Code: Moved append() functions to the reply object Reviewed-by: TrustMe --- src/network/access/qhttpnetworkconnection.cpp | 35 +++------------------------ src/network/access/qhttpnetworkconnection_p.h | 4 --- src/network/access/qhttpnetworkreply.cpp | 30 +++++++++++++++++++++++ src/network/access/qhttpnetworkreply_p.h | 4 +++ 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index d73cd67..4c52545 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -129,35 +129,6 @@ bool QHttpNetworkConnectionPrivate::isSocketReading(QAbstractSocket *socket) con return (i != -1 && (channels[i].state & QHttpNetworkConnectionChannel::ReadingState)); } -void QHttpNetworkConnectionPrivate::appendUncompressedData(QHttpNetworkReply &reply, QByteArray &qba) -{ - reply.d_func()->responseData.append(qba); - - // clear the original! helps with implicit sharing and - // avoiding memcpy when the user is reading the data - qba.clear(); -} - -void QHttpNetworkConnectionPrivate::appendUncompressedData(QHttpNetworkReply &reply, QByteDataBuffer &data) -{ - reply.d_func()->responseData.append(data); - - // clear the original! helps with implicit sharing and - // avoiding memcpy when the user is reading the data - data.clear(); -} - -void QHttpNetworkConnectionPrivate::appendCompressedData(QHttpNetworkReply &reply, QByteDataBuffer &data) -{ - // Work in progress: Later we will directly use a list of QByteArray or a QRingBuffer - // instead of one QByteArray. - for(int i = 0; i < data.bufferCount(); i++) { - QByteArray &byteData = data[i]; - reply.d_func()->compressedData.append(byteData.constData(), byteData.size()); - } - data.clear(); -} - qint64 QHttpNetworkConnectionPrivate::uncompressedBytesAvailable(const QHttpNetworkReply &reply) const { return reply.d_func()->responseData.byteAmount(); @@ -517,7 +488,7 @@ bool QHttpNetworkConnectionPrivate::expand(QAbstractSocket *socket, QHttpNetwork if (ret >= retCheck) { if (inflated.size()) { reply->d_func()->totalProgress += inflated.size(); - appendUncompressedData(*reply, inflated); + reply->d_func()->appendUncompressedReplyData(inflated); if (shouldEmitSignals(reply)) { // important: At the point of this readyRead(), inflated must be cleared, // else implicit sharing will trigger memcpy when the user is reading data! @@ -638,9 +609,9 @@ void QHttpNetworkConnectionPrivate::receiveReply(QAbstractSocket *socket, QHttpN bytes = reply->d_func()->readBody(socket, &byteDatas); if (bytes) { if (reply->d_func()->autoDecompress) - appendCompressedData(*reply, byteDatas); + reply->d_func()->appendCompressedReplyData(byteDatas); else - appendUncompressedData(*reply, byteDatas); + reply->d_func()->appendUncompressedReplyData(byteDatas); if (!reply->d_func()->autoDecompress) { reply->d_func()->totalProgress += bytes; diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index 48401d2..d6b0325 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -197,10 +197,6 @@ public: bool pendingAuthSignal; // there is an incomplete authentication signal bool pendingProxyAuthSignal; // there is an incomplete proxy authentication signal - void appendUncompressedData(QHttpNetworkReply &reply, QByteArray &qba); - void appendUncompressedData(QHttpNetworkReply &reply, QByteDataBuffer &data); - void appendCompressedData(QHttpNetworkReply &reply, QByteDataBuffer &data); - qint64 uncompressedBytesAvailable(const QHttpNetworkReply &reply) const; qint64 uncompressedBytesAvailableNextBlock(const QHttpNetworkReply &reply) const; qint64 compressedBytesAvailable(const QHttpNetworkReply &reply) const; diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index a623999..f40f7bf 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -687,6 +687,36 @@ qint64 QHttpNetworkReplyPrivate::getChunkSize(QIODevice *in, qint64 *chunkSize) return bytes; } +void QHttpNetworkReplyPrivate::appendUncompressedReplyData(QByteArray &qba) +{ + responseData.append(qba); + + // clear the original! helps with implicit sharing and + // avoiding memcpy when the user is reading the data + qba.clear(); +} + +void QHttpNetworkReplyPrivate::appendUncompressedReplyData(QByteDataBuffer &data) +{ + responseData.append(data); + + // clear the original! helps with implicit sharing and + // avoiding memcpy when the user is reading the data + data.clear(); +} + +void QHttpNetworkReplyPrivate::appendCompressedReplyData(QByteDataBuffer &data) +{ + // Work in progress: Later we will directly use a list of QByteArray or a QRingBuffer + // instead of one QByteArray. + for(int i = 0; i < data.bufferCount(); i++) { + QByteArray &byteData = data[i]; + compressedData.append(byteData.constData(), byteData.size()); + } + data.clear(); +} + + // SSL support below #ifndef QT_NO_OPENSSL diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index a386b10..fe49799 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -172,6 +172,10 @@ public: qint64 readReplyBodyChunked(QIODevice *in, QByteDataBuffer *out); qint64 getChunkSize(QIODevice *in, qint64 *chunkSize); + void appendUncompressedReplyData(QByteArray &qba); + void appendUncompressedReplyData(QByteDataBuffer &data); + void appendCompressedReplyData(QByteDataBuffer &data); + qint64 bytesAvailable() const; bool isChunked(); bool connectionCloseEnabled(); -- cgit v0.12 From fbee62af06ebe2c8cf6da1cc18a665c69c64eff7 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Mon, 3 Aug 2009 15:04:43 +0200 Subject: Renamed internal WinGesture event to NativeGesture. It will also be used on Mac, so it doesn't make sense to keep it windows specific. Reviewed-by: trustme --- src/corelib/kernel/qcoreevent.cpp | 2 +- src/corelib/kernel/qcoreevent.h | 2 +- src/gui/kernel/qapplication.cpp | 2 +- src/gui/kernel/qapplication_win.cpp | 10 +++++----- src/gui/kernel/qevent.cpp | 1 - src/gui/kernel/qevent_p.h | 13 +++++++++++-- src/gui/kernel/qwidget.cpp | 16 ++++++++-------- 7 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index a682fad9..ff00c1c 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -269,7 +269,7 @@ QT_BEGIN_NAMESPACE \omitvalue FutureCallOut \omitvalue CocoaRequestModal \omitvalue Signal - \omitvalue WinGesture + \omitvalue NativeGesture */ /*! diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index 1d86f47..d941286 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -276,7 +276,7 @@ public: TouchUpdate = 195, TouchEnd = 196, - WinGesture = 197, + NativeGesture = 197, // Internal for platform gesture support // 512 reserved for Qt Jambi's MetaCall event // 513 reserved for Qt Jambi's DeleteOnMainThread event diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index e210556..c24ff49 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -4052,7 +4052,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) touchEvent->setAccepted(eventAccepted); break; } - case QEvent::WinGesture: + case QEvent::NativeGesture: { // only propagate the first gesture event (after the GID_BEGIN) QWidget *w = static_cast(receiver); diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index d5c820c..3b5c0c3 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -3735,7 +3735,7 @@ bool QETWidget::translateGestureEvent(const MSG &msg) alienWidget = 0; QWidget *widget = alienWidget ? alienWidget : this; - QWinGestureEvent event; + QNativeGestureEvent event; event.sequenceId = gi.dwSequenceID; event.position = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); if (bResult) { @@ -3744,13 +3744,13 @@ bool QETWidget::translateGestureEvent(const MSG &msg) // we are not interested in this type of event. break; case GID_END: - event.gestureType = QWinGestureEvent::GestureEnd; + event.gestureType = QNativeGestureEvent::GestureEnd; break; case GID_ZOOM: - event.gestureType = QWinGestureEvent::Pinch; + event.gestureType = QNativeGestureEvent::Pinch; break; case GID_PAN: - event.gestureType = QWinGestureEvent::Pan; + event.gestureType = QNativeGestureEvent::Pan; break; case GID_ROTATE: case GID_TWOFINGERTAP: @@ -3758,7 +3758,7 @@ bool QETWidget::translateGestureEvent(const MSG &msg) default: break; } - if (event.gestureType != QWinGestureEvent::None) + if (event.gestureType != QNativeGestureEvent::None) qt_sendSpontaneousEvent(widget, &event); } else { DWORD dwErr = GetLastError(); diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index bc3633c..0fc36e7 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -49,7 +49,6 @@ #include "qmime.h" #include "qdnd_p.h" #include "qevent_p.h" -#include "qgesture.h" QT_BEGIN_NAMESPACE diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h index 67441ea..940e587 100644 --- a/src/gui/kernel/qevent_p.h +++ b/src/gui/kernel/qevent_p.h @@ -119,7 +119,7 @@ public: qreal pressure; }; -class QWinGestureEvent : public QEvent +class QNativeGestureEvent : public QEvent { public: enum Type { @@ -129,10 +129,19 @@ public: Pinch }; - QWinGestureEvent() : QEvent(QEvent::WinGesture), gestureType(None), sequenceId(0) { } + QNativeGestureEvent() + : QEvent(QEvent::NativeGesture), gestureType(None) +#ifdef Q_WS_WIN + , sequenceId(0) +#endif + { + } + Type gestureType; +#ifdef Q_WS_WIN QPoint position; ulong sequenceId; +#endif }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 43ac37d..5400146 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -7941,8 +7941,8 @@ bool QWidget::event(QEvent *event) break; } #ifdef Q_WS_WIN - case QEvent::WinGesture: { - QWinGestureEvent *ev = static_cast(event); + case QEvent::NativeGesture: { + QNativeGestureEvent *ev = static_cast(event); QApplicationPrivate *qAppPriv = qApp->d_func(); QApplicationPrivate::WidgetStandardGesturesMap::iterator it; it = qAppPriv->widgetGestures.find(this); @@ -7950,15 +7950,15 @@ bool QWidget::event(QEvent *event) Qt::GestureState state = Qt::GestureUpdated; if (qAppPriv->lastGestureId == 0) state = Qt::GestureStarted; - QWinGestureEvent::Type type = ev->gestureType; - if (ev->gestureType == QWinGestureEvent::GestureEnd) { - type = (QWinGestureEvent::Type)qAppPriv->lastGestureId; + QNativeGestureEvent::Type type = ev->gestureType; + if (ev->gestureType == QNativeGestureEvent::GestureEnd) { + type = (QNativeGestureEvent::Type)qAppPriv->lastGestureId; state = Qt::GestureFinished; } QGesture *gesture = 0; switch (type) { - case QWinGestureEvent::Pan: { + case QNativeGestureEvent::Pan: { QPanGesture *pan = it.value().pan; gesture = pan; if (state == Qt::GestureStarted) { @@ -7970,7 +7970,7 @@ bool QWidget::event(QEvent *event) gesture->setPos(ev->position); break; } - case QWinGestureEvent::Pinch: + case QNativeGestureEvent::Pinch: break; default: break; @@ -7984,7 +7984,7 @@ bool QWidget::event(QEvent *event) emit gesture->finished(); event->accept(); } - if (ev->gestureType == QWinGestureEvent::GestureEnd) { + if (ev->gestureType == QNativeGestureEvent::GestureEnd) { qAppPriv->lastGestureId = 0; } else { qAppPriv->lastGestureId = type; -- cgit v0.12 From 6e7a6478279a94a82af46e6814f113244aca46dd Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Mon, 3 Aug 2009 18:24:44 +0200 Subject: Moved the native window gesture handling code to the right place. --- src/gui/kernel/qapplication_win.cpp | 2 +- src/gui/kernel/qevent_p.h | 1 + src/gui/kernel/qstandardgestures.cpp | 124 +++++++++++++++++++++++++++++------ src/gui/kernel/qstandardgestures.h | 7 +- src/gui/kernel/qstandardgestures_p.h | 11 +++- src/gui/kernel/qwidget.cpp | 53 --------------- 6 files changed, 121 insertions(+), 77 deletions(-) diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 3b5c0c3..2bded5c 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -3741,7 +3741,7 @@ bool QETWidget::translateGestureEvent(const MSG &msg) if (bResult) { switch (gi.dwID) { case GID_BEGIN: - // we are not interested in this type of event. + event.gestureType = QNativeGestureEvent::GestureBegin; break; case GID_END: event.gestureType = QNativeGestureEvent::GestureEnd; diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h index 940e587..92c4fc1 100644 --- a/src/gui/kernel/qevent_p.h +++ b/src/gui/kernel/qevent_p.h @@ -124,6 +124,7 @@ class QNativeGestureEvent : public QEvent public: enum Type { None, + GestureBegin, GestureEnd, Pan, Pinch diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index c4820f0..1fbfe15 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -45,9 +45,14 @@ #include #include #include +#include QT_BEGIN_NAMESPACE +#ifdef Q_WS_WIN +QApplicationPrivate* getQApplicationPrivateInternal(); +#endif + /*! \class QPanGesture \since 4.6 @@ -68,15 +73,10 @@ QPanGesture::QPanGesture(QWidget *parent) { #ifdef Q_WS_WIN if (parent) { - QApplicationPrivate* getQApplicationPrivateInternal(); QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); qAppPriv->widgetGestures[parent].pan = this; } #endif - -#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) - d_func()->panFinishedTimer = 0; -#endif } /*! \internal */ @@ -116,6 +116,62 @@ bool QPanGesture::event(QEvent *event) return QObject::event(event); } +bool QPanGesture::eventFilter(QObject *receiver, QEvent *event) +{ +#ifdef Q_WS_WIN + if (receiver->isWidgetType() && event->type() == QEvent::NativeGesture) { + QNativeGestureEvent *ev = static_cast(event); + QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + QApplicationPrivate::WidgetStandardGesturesMap::iterator it; + it = qAppPriv->widgetGestures.find(static_cast(receiver)); + if (it == qAppPriv->widgetGestures.end()) + return false; + QPanGesture *gesture = it.value().pan; + if (!gesture) + return false; + Qt::GestureState nextState = state(); + switch(ev->gestureType) { + case QNativeGestureEvent::GestureBegin: + // next we might receive the first gesture update event, so we + // prepare for it. + setState(Qt::GestureStarted); + return false; + case QNativeGestureEvent::Pan: + nextState = Qt::GestureUpdated; + break; + case QNativeGestureEvent::GestureEnd: + if (state() != QNativeGestureEvent::Pan) + return false; // some other gesture has ended + setState(Qt::GestureFinished); + nextState = Qt::GestureFinished; + break; + default: + return false; + } + QPanGesturePrivate *d = gesture->d_func(); + if (state() == Qt::GestureStarted) { + d->lastPosition = ev->position; + d->lastOffset = d->totalOffset = QSize(); + } else { + d->lastOffset = QSize(ev->position.x() - d->lastPosition.x(), + ev->position.y() - d->lastPosition.y()); + d->totalOffset += d->lastOffset; + } + d->lastPosition = ev->position; + + if (state() == Qt::GestureStarted) + emit gesture->started(); + emit gesture->triggered(); + if (state() == Qt::GestureFinished) + emit gesture->finished(); + event->accept(); + gesture->setState(nextState); + return true; + } +#endif + return QGesture::eventFilter(receiver, event); +} + /*! \internal */ bool QPanGesture::filterEvent(QEvent *event) { @@ -124,28 +180,34 @@ bool QPanGesture::filterEvent(QEvent *event) return false; const QTouchEvent *ev = static_cast(event); if (event->type() == QEvent::TouchBegin) { - d->touchPoints = ev->touchPoints(); - const QPoint p = ev->touchPoints().at(0).pos().toPoint(); - setStartPos(p); - setLastPos(p); - setPos(p); - return false; + QTouchEvent::TouchPoint p = ev->touchPoints().at(0); + d->lastPosition = p.pos().toPoint(); + d->lastOffset = d->totalOffset = QSize(); } else if (event->type() == QEvent::TouchEnd) { if (state() != Qt::NoGesture) { setState(Qt::GestureFinished); - setLastPos(pos()); - setPos(ev->touchPoints().at(0).pos().toPoint()); + if (!ev->touchPoints().isEmpty()) { + QTouchEvent::TouchPoint p = ev->touchPoints().at(0); + const QPoint pos = p.pos().toPoint(); + const QPoint lastPos = p.lastPos().toPoint(); + const QPoint startPos = p.startPos().toPoint(); + d->lastOffset = QSize(pos.x() - lastPos.x(), pos.y() - lastPos.y()); + d->totalOffset = QSize(pos.x() - startPos.x(), pos.y() - startPos.y()); + } emit triggered(); emit finished(); } setState(Qt::NoGesture); reset(); } else if (event->type() == QEvent::TouchUpdate) { - d->touchPoints = ev->touchPoints(); - QPointF pt = d->touchPoints.at(0).pos() - d->touchPoints.at(0).startPos(); - setLastPos(pos()); - setPos(ev->touchPoints().at(0).pos().toPoint()); - if (pt.x() > 10 || pt.y() > 10 || pt.x() < -10 || pt.y() < -10) { + QTouchEvent::TouchPoint p = ev->touchPoints().at(0); + const QPoint pos = p.pos().toPoint(); + const QPoint lastPos = p.lastPos().toPoint(); + const QPoint startPos = p.startPos().toPoint(); + d->lastOffset = QSize(pos.x() - lastPos.x(), pos.y() - lastPos.y()); + d->totalOffset = QSize(pos.x() - startPos.x(), pos.y() - startPos.y()); + if (d->totalOffset.width() > 10 || d->totalOffset.height() > 10 || + d->totalOffset.width() < -10 || d->totalOffset.height() < -10) { if (state() == Qt::NoGesture) setState(Qt::GestureStarted); else @@ -190,7 +252,14 @@ bool QPanGesture::filterEvent(QEvent *event) void QPanGesture::reset() { Q_D(QPanGesture); - d->touchPoints.clear(); + d->lastOffset = d->totalOffset = QSize(); + d->lastPosition = QPoint(); +#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + if (d->panFinishedTimer) { + killTimer(d->panFinishedTimer); + d->panFinishedTimer = 0; + } +#endif } /*! @@ -226,6 +295,23 @@ QSize QPanGesture::lastOffset() const #endif } +QPoint QPanGesture::startPos() const +{ + Q_D(const QPanGesture); + return d->startPos; +} +QPoint QPanGesture::lastPos() const +{ + Q_D(const QPanGesture); + return d->lastPos; +} + +QPoint QPanGesture::pos() const +{ + Q_D(const QPanGesture); + return d->pos; +} + /*! \class QTapAndHoldGesture \since 4.6 diff --git a/src/gui/kernel/qstandardgestures.h b/src/gui/kernel/qstandardgestures.h index 2234702..030aac8 100644 --- a/src/gui/kernel/qstandardgestures.h +++ b/src/gui/kernel/qstandardgestures.h @@ -70,11 +70,14 @@ public: QSize totalOffset() const; QSize lastOffset() const; + QPoint startPos() const; + QPoint lastPos() const; + QPoint pos() const; -protected: +private: bool event(QEvent *event); + bool eventFilter(QObject *receiver, QEvent *event); -private: friend class QWidget; }; diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h index 0fd42bd..dd4fbc0 100644 --- a/src/gui/kernel/qstandardgestures_p.h +++ b/src/gui/kernel/qstandardgestures_p.h @@ -60,6 +60,8 @@ #include "qgesture.h" #include "qgesture_p.h" +#include "qstandardgestures.h" + QT_BEGIN_NAMESPACE class QPanGesturePrivate : public QGesturePrivate @@ -67,11 +69,16 @@ class QPanGesturePrivate : public QGesturePrivate Q_DECLARE_PUBLIC(QPanGesture) public: - QPanGesturePrivate() { } + QPanGesturePrivate() + { +#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + panFinishedTimer = 0; +#endif + } - QList touchPoints; QSize totalOffset; QSize lastOffset; + QPoint lastPosition; #if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) int panFinishedTimer; diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 5400146..765b26f 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -7940,59 +7940,6 @@ bool QWidget::event(QEvent *event) (void) QApplication::sendEvent(this, &mouseEvent); break; } -#ifdef Q_WS_WIN - case QEvent::NativeGesture: { - QNativeGestureEvent *ev = static_cast(event); - QApplicationPrivate *qAppPriv = qApp->d_func(); - QApplicationPrivate::WidgetStandardGesturesMap::iterator it; - it = qAppPriv->widgetGestures.find(this); - if (it != qAppPriv->widgetGestures.end()) { - Qt::GestureState state = Qt::GestureUpdated; - if (qAppPriv->lastGestureId == 0) - state = Qt::GestureStarted; - QNativeGestureEvent::Type type = ev->gestureType; - if (ev->gestureType == QNativeGestureEvent::GestureEnd) { - type = (QNativeGestureEvent::Type)qAppPriv->lastGestureId; - state = Qt::GestureFinished; - } - - QGesture *gesture = 0; - switch (type) { - case QNativeGestureEvent::Pan: { - QPanGesture *pan = it.value().pan; - gesture = pan; - if (state == Qt::GestureStarted) { - gesture->setStartPos(ev->position); - gesture->setLastPos(ev->position); - } else { - gesture->setLastPos(gesture->pos()); - } - gesture->setPos(ev->position); - break; - } - case QNativeGestureEvent::Pinch: - break; - default: - break; - } - if (gesture) { - gesture->setState(state); - if (state == Qt::GestureStarted) - emit gesture->started(); - emit gesture->triggered(); - if (state == Qt::GestureFinished) - emit gesture->finished(); - event->accept(); - } - if (ev->gestureType == QNativeGestureEvent::GestureEnd) { - qAppPriv->lastGestureId = 0; - } else { - qAppPriv->lastGestureId = type; - } - } - break; - } -#endif #ifndef QT_NO_PROPERTIES case QEvent::DynamicPropertyChange: { const QByteArray &propName = static_cast(event)->propertyName(); -- cgit v0.12 From 6b85ec8790aad8ac01c04f7e7bd4913d8cd8d104 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Mon, 3 Aug 2009 17:02:58 +0200 Subject: Removed the QTapAndHoldGesture Moved the gesture implementation to the imageviewer example as it cannot be fully implemented in a crossplatform way - for example on Windows tap and hold is a system gesture that is transparent to the application. Reviewed-by: trustme --- examples/gestures/imageviewer/imageviewer.pro | 11 +-- examples/gestures/imageviewer/imagewidget.cpp | 15 ++- examples/gestures/imageviewer/imagewidget.h | 4 +- .../gestures/imageviewer/tapandholdgesture.cpp | 97 ++++++++++++++++++++ examples/gestures/imageviewer/tapandholdgesture.h | 32 +++++++ src/gui/kernel/qstandardgestures.cpp | 101 ++++----------------- src/gui/kernel/qstandardgestures.h | 16 ---- src/gui/kernel/qstandardgestures_p.h | 14 --- 8 files changed, 167 insertions(+), 123 deletions(-) create mode 100644 examples/gestures/imageviewer/tapandholdgesture.cpp create mode 100644 examples/gestures/imageviewer/tapandholdgesture.h diff --git a/examples/gestures/imageviewer/imageviewer.pro b/examples/gestures/imageviewer/imageviewer.pro index 4c35dce..efbca00 100644 --- a/examples/gestures/imageviewer/imageviewer.pro +++ b/examples/gestures/imageviewer/imageviewer.pro @@ -1,12 +1,11 @@ -###################################################################### -# Automatically generated by qmake (2.01a) Thu Sep 11 17:18:17 2008 -###################################################################### - TEMPLATE = app TARGET = DEPENDPATH += . INCLUDEPATH += . # Input -HEADERS += imagewidget.h -SOURCES += imagewidget.cpp main.cpp +HEADERS += imagewidget.h \ + tapandholdgesture.h +SOURCES += imagewidget.cpp \ + tapandholdgesture.cpp \ + main.cpp diff --git a/examples/gestures/imageviewer/imagewidget.cpp b/examples/gestures/imageviewer/imagewidget.cpp index 0b39997..99889ed 100644 --- a/examples/gestures/imageviewer/imagewidget.cpp +++ b/examples/gestures/imageviewer/imagewidget.cpp @@ -65,7 +65,7 @@ ImageWidget::ImageWidget(QWidget *parent) panGesture = new QPanGesture(this); connect(panGesture, SIGNAL(triggered()), this, SLOT(gestureTriggered())); - tapAndHoldGesture = new QTapAndHoldGesture(this); + tapAndHoldGesture = new TapAndHoldGesture(this); connect(tapAndHoldGesture, SIGNAL(triggered()), this, SLOT(gestureTriggered())); } @@ -188,6 +188,19 @@ void ImageWidget::gestureTriggered() } } feedbackFadeOutTimer.start(500, this); + } else if (sender() == tapAndHoldGesture) { + if (tapAndHoldGesture->state() == Qt::GestureFinished) { + qDebug() << "tap and hold detected"; + touchFeedback.reset(); + update(); + + QMenu menu; + menu.addAction("Action 1"); + menu.addAction("Action 2"); + menu.addAction("Action 3"); + menu.exec(mapToGlobal(tapAndHoldGesture->pos())); + } + feedbackFadeOutTimer.start(500, this); } } diff --git a/examples/gestures/imageviewer/imagewidget.h b/examples/gestures/imageviewer/imagewidget.h index e12634d..d8d5f8d 100644 --- a/examples/gestures/imageviewer/imagewidget.h +++ b/examples/gestures/imageviewer/imagewidget.h @@ -48,6 +48,8 @@ #include +#include "tapandholdgesture.h" + class ImageWidget : public QWidget { Q_OBJECT @@ -79,7 +81,7 @@ private: void goToImage(int index); QPanGesture *panGesture; - QTapAndHoldGesture *tapAndHoldGesture; + TapAndHoldGesture *tapAndHoldGesture; QString path; QStringList files; diff --git a/examples/gestures/imageviewer/tapandholdgesture.cpp b/examples/gestures/imageviewer/tapandholdgesture.cpp new file mode 100644 index 0000000..c6f6779 --- /dev/null +++ b/examples/gestures/imageviewer/tapandholdgesture.cpp @@ -0,0 +1,97 @@ +#include "tapandholdgesture.h" + +#include + +/*! + \class TapAndHoldGesture + \since 4.6 + + \brief The TapAndHoldGesture class represents a Tap-and-Hold gesture, + providing additional information. +*/ + +const int TapAndHoldGesture::iterationCount = 40; +const int TapAndHoldGesture::iterationTimeout = 50; + +/*! + Creates a new Tap and Hold gesture handler object and marks it as a child + of \a parent. + + On some platforms like Windows there is a system-wide tap and hold gesture + that cannot be overriden, hence the gesture might never trigger and default + context menu will be shown instead. +*/ +TapAndHoldGesture::TapAndHoldGesture(QWidget *parent) + : QGesture(parent), iteration(0) +{ +} + +/*! \internal */ +bool TapAndHoldGesture::filterEvent(QEvent *event) +{ + if (!event->spontaneous()) + return false; + const QTouchEvent *ev = static_cast(event); + switch (event->type()) { + case QEvent::TouchBegin: { + if (timer.isActive()) + timer.stop(); + timer.start(TapAndHoldGesture::iterationTimeout, this); + const QPoint p = ev->touchPoints().at(0).pos().toPoint(); + position = p; + break; + } + case QEvent::TouchUpdate: + if (ev->touchPoints().size() == 1) { + const QPoint startPos = ev->touchPoints().at(0).startPos().toPoint(); + const QPoint pos = ev->touchPoints().at(0).pos().toPoint(); + if ((startPos - pos).manhattanLength() > 15) + reset(); + } else { + reset(); + } + break; + case QEvent::TouchEnd: + reset(); + break; + default: + break; + } + return false; +} + +/*! \internal */ +void TapAndHoldGesture::timerEvent(QTimerEvent *event) +{ + if (event->timerId() != timer.timerId()) + return; + if (iteration == TapAndHoldGesture::iterationCount) { + timer.stop(); + setState(Qt::GestureFinished); + emit triggered(); + } else { + setState(Qt::GestureStarted); + emit triggered(); + } + ++iteration; +} + +/*! \internal */ +void TapAndHoldGesture::reset() +{ + if (state() != Qt::NoGesture) + emit cancelled(); + setState(Qt::NoGesture); + timer.stop(); + iteration = 0; +} + +/*! + \property TapAndHoldGesture::pos + + \brief The position of the gesture. +*/ +QPoint TapAndHoldGesture::pos() const +{ + return position; +} diff --git a/examples/gestures/imageviewer/tapandholdgesture.h b/examples/gestures/imageviewer/tapandholdgesture.h new file mode 100644 index 0000000..711a1af --- /dev/null +++ b/examples/gestures/imageviewer/tapandholdgesture.h @@ -0,0 +1,32 @@ +#ifndef TAPANDHOLDGESTURE_H +#define TAPANDHOLDGESTURE_H + +#include +#include +#include + +class TapAndHoldGesture : public QGesture +{ + Q_OBJECT + Q_PROPERTY(QPoint pos READ pos) + +public: + TapAndHoldGesture(QWidget *parent); + + bool filterEvent(QEvent *event); + void reset(); + + QPoint pos() const; + +protected: + void timerEvent(QTimerEvent *event); + +private: + QBasicTimer timer; + int iteration; + QPoint position; + static const int iterationCount; + static const int iterationTimeout; +}; + +#endif // TAPANDHOLDGESTURE_H diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index 1fbfe15..e4b9abb 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -295,106 +295,37 @@ QSize QPanGesture::lastOffset() const #endif } +/*! + \property QPanGesture::startPos + + \brief The start position of the gesture. +*/ QPoint QPanGesture::startPos() const { Q_D(const QPanGesture); return d->startPos; } + +/*! + \property QPanGesture::lastPos + + \brief The last recorded position of the gesture. +*/ QPoint QPanGesture::lastPos() const { Q_D(const QPanGesture); return d->lastPos; } -QPoint QPanGesture::pos() const -{ - Q_D(const QPanGesture); - return d->pos; -} - /*! - \class QTapAndHoldGesture - \since 4.6 - - \brief The QTapAndHoldGesture class represents a Tap-and-Hold gesture, - providing additional information. -*/ - -const int QTapAndHoldGesturePrivate::iterationCount = 40; -const int QTapAndHoldGesturePrivate::iterationTimeout = 50; - -/*! - Creates a new Tap and Hold gesture handler object and marks it as a child - of \a parent. + \property QPanGesture::pos - On some platforms like Windows there is a system-wide tap and hold gesture - that cannot be overriden, hence the gesture might never trigger and default - context menu will be shown instead. + \brief The current position of the gesture. */ -QTapAndHoldGesture::QTapAndHoldGesture(QWidget *parent) - : QGesture(*new QTapAndHoldGesturePrivate, parent) -{ -} - -/*! \internal */ -bool QTapAndHoldGesture::filterEvent(QEvent *event) -{ - Q_D(QTapAndHoldGesture); - if (!event->spontaneous()) - return false; - const QTouchEvent *ev = static_cast(event); - switch (event->type()) { - case QEvent::TouchBegin: { - if (d->timer.isActive()) - d->timer.stop(); - d->timer.start(QTapAndHoldGesturePrivate::iterationTimeout, this); - const QPoint p = ev->touchPoints().at(0).pos().toPoint(); - setStartPos(p); - setLastPos(p); - setPos(p); - break; - } - case QEvent::TouchUpdate: - if (ev->touchPoints().size() != 1) - reset(); - else if ((startPos() - ev->touchPoints().at(0).pos().toPoint()).manhattanLength() > 15) - reset(); - break; - case QEvent::TouchEnd: - reset(); - break; - default: - break; - } - return false; -} - -/*! \internal */ -void QTapAndHoldGesture::timerEvent(QTimerEvent *event) -{ - Q_D(QTapAndHoldGesture); - if (event->timerId() != d->timer.timerId()) - return; - if (d->iteration == QTapAndHoldGesturePrivate::iterationCount) { - d->timer.stop(); - setState(Qt::GestureFinished); - emit triggered(); - } else { - setState(Qt::GestureStarted); - emit triggered(); - } - ++d->iteration; -} - -/*! \internal */ -void QTapAndHoldGesture::reset() +QPoint QPanGesture::pos() const { - Q_D(QTapAndHoldGesture); - if (state() != Qt::NoGesture) - emit cancelled(); - setState(Qt::NoGesture); - d->timer.stop(); - d->iteration = 0; + Q_D(const QPanGesture); + return d->pos; } QT_END_NAMESPACE diff --git a/src/gui/kernel/qstandardgestures.h b/src/gui/kernel/qstandardgestures.h index 030aac8..c6f6d9b 100644 --- a/src/gui/kernel/qstandardgestures.h +++ b/src/gui/kernel/qstandardgestures.h @@ -81,22 +81,6 @@ private: friend class QWidget; }; -class QTapAndHoldGesturePrivate; -class Q_GUI_EXPORT QTapAndHoldGesture : public QGesture -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QTapAndHoldGesture) - -public: - QTapAndHoldGesture(QWidget *parent); - - bool filterEvent(QEvent *event); - void reset(); - -protected: - void timerEvent(QTimerEvent *event); -}; - QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h index dd4fbc0..0fe24ee 100644 --- a/src/gui/kernel/qstandardgestures_p.h +++ b/src/gui/kernel/qstandardgestures_p.h @@ -85,20 +85,6 @@ public: #endif }; -class QTapAndHoldGesturePrivate : public QGesturePrivate -{ - Q_DECLARE_PUBLIC(QTapAndHoldGesture) - -public: - QTapAndHoldGesturePrivate() - : iteration(0) { } - - QBasicTimer timer; - int iteration; - static const int iterationCount; - static const int iterationTimeout; -}; - QT_END_NAMESPACE #endif // QSTANDARDGESTURES_P_H -- cgit v0.12 From 47c191d3c6b9c3fbe062068167888bed434ab6e2 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 4 Aug 2009 13:37:35 +0200 Subject: Removed the startPos/lastPos/pos from the gesture classes. It doesn't make much sense to have that low-level info neither in the base QGesture class, nor in the QPanGesture, as the latter one has offset properties instead. Reviewed-by: trustme --- src/gui/kernel/qgesture.cpp | 45 ------------------------------------ src/gui/kernel/qgesture.h | 14 ++--------- src/gui/kernel/qgesture_p.h | 11 --------- src/gui/kernel/qstandardgestures.cpp | 43 ---------------------------------- src/gui/kernel/qstandardgestures.h | 3 --- src/gui/widgets/qtextedit.cpp | 8 +++---- 6 files changed, 6 insertions(+), 118 deletions(-) diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index 1f98013..32ac4f8 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -205,51 +205,6 @@ void QGesture::setState(Qt::GestureState state) } /*! - \property QGesture::startPos - - \brief The start position of the gesture (if relevant). -*/ -QPoint QGesture::startPos() const -{ - return d_func()->startPos; -} - -void QGesture::setStartPos(const QPoint &point) -{ - d_func()->startPos = point; -} - -/*! - \property QGesture::lastPos - - \brief The last recorded position of the gesture (if relevant). -*/ -QPoint QGesture::lastPos() const -{ - return d_func()->lastPos; -} - -void QGesture::setLastPos(const QPoint &point) -{ - d_func()->lastPos = point; -} - -/*! - \property QGesture::pos - - \brief The current position of the gesture (if relevant). -*/ -QPoint QGesture::pos() const -{ - return d_func()->pos; -} - -void QGesture::setPos(const QPoint &point) -{ - d_func()->pos = point; -} - -/*! Sets the \a graphicsItem the gesture is filtering events for. The gesture will install an event filter to the \a graphicsItem and diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h index 1cd9cae..0735160 100644 --- a/src/gui/kernel/qgesture.h +++ b/src/gui/kernel/qgesture.h @@ -64,10 +64,6 @@ class Q_GUI_EXPORT QGesture : public QObject Q_PROPERTY(Qt::GestureState state READ state) - Q_PROPERTY(QPoint startPos READ startPos WRITE setStartPos) - Q_PROPERTY(QPoint lastPos READ lastPos WRITE setLastPos) - Q_PROPERTY(QPoint pos READ pos WRITE setPos) - public: explicit QGesture(QObject *parent = 0); ~QGesture(); @@ -80,19 +76,13 @@ public: virtual void reset(); Qt::GestureState state() const; - void setState(Qt::GestureState state); - - QPoint startPos() const; - void setStartPos(const QPoint &point); - QPoint lastPos() const; - void setLastPos(const QPoint &point); - QPoint pos() const; - void setPos(const QPoint &point); protected: QGesture(QGesturePrivate &dd, QObject *parent); bool eventFilter(QObject*, QEvent*); + void setState(Qt::GestureState state); + Q_SIGNALS: void started(); void triggered(); diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h index 99f572f..56eaee7 100644 --- a/src/gui/kernel/qgesture_p.h +++ b/src/gui/kernel/qgesture_p.h @@ -73,22 +73,11 @@ public: { } - void init(const QPoint &startPos, const QPoint &lastPos, - const QPoint &pos) - { - this->startPos = startPos; - this->lastPos = lastPos; - this->pos = pos; - } QGraphicsItem *graphicsItem; QGraphicsItem *eventFilterProxyGraphicsItem; Qt::GestureState state; - - QPoint startPos; - QPoint lastPos; - QPoint pos; }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index e4b9abb..4753416 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -269,13 +269,8 @@ void QPanGesture::reset() */ QSize QPanGesture::totalOffset() const { -#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) Q_D(const QPanGesture); return d->totalOffset; -#else - QPoint pt = pos() - startPos(); - return QSize(pt.x(), pt.y()); -#endif } /*! @@ -286,46 +281,8 @@ QSize QPanGesture::totalOffset() const */ QSize QPanGesture::lastOffset() const { -#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) Q_D(const QPanGesture); return d->lastOffset; -#else - QPoint pt = pos() - lastPos(); - return QSize(pt.x(), pt.y()); -#endif -} - -/*! - \property QPanGesture::startPos - - \brief The start position of the gesture. -*/ -QPoint QPanGesture::startPos() const -{ - Q_D(const QPanGesture); - return d->startPos; -} - -/*! - \property QPanGesture::lastPos - - \brief The last recorded position of the gesture. -*/ -QPoint QPanGesture::lastPos() const -{ - Q_D(const QPanGesture); - return d->lastPos; -} - -/*! - \property QPanGesture::pos - - \brief The current position of the gesture. -*/ -QPoint QPanGesture::pos() const -{ - Q_D(const QPanGesture); - return d->pos; } QT_END_NAMESPACE diff --git a/src/gui/kernel/qstandardgestures.h b/src/gui/kernel/qstandardgestures.h index c6f6d9b..c734fba 100644 --- a/src/gui/kernel/qstandardgestures.h +++ b/src/gui/kernel/qstandardgestures.h @@ -70,9 +70,6 @@ public: QSize totalOffset() const; QSize lastOffset() const; - QPoint startPos() const; - QPoint lastPos() const; - QPoint pos() const; private: bool event(QEvent *event); diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp index e80df92..c095f5c 100644 --- a/src/gui/widgets/qtextedit.cpp +++ b/src/gui/widgets/qtextedit.cpp @@ -2625,12 +2625,12 @@ void QTextEditPrivate::_q_gestureTriggered() return; QScrollBar *hBar = q->horizontalScrollBar(); QScrollBar *vBar = q->verticalScrollBar(); - QPoint delta = g->pos() - (g->lastPos().isNull() ? g->pos() : g->lastPos()); + QSize delta = g->lastOffset(); if (!delta.isNull()) { if (QApplication::isRightToLeft()) - delta.rx() *= -1; - int newX = hBar->value() - delta.x(); - int newY = vBar->value() - delta.y(); + delta.rwidth() *= -1; + int newX = hBar->value() - delta.width(); + int newY = vBar->value() - delta.height(); hbar->setValue(newX); vbar->setValue(newY); } -- cgit v0.12 From 6d9143ebffc10a58d8d62e57e3378adae4af92cd Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 4 Aug 2009 10:37:39 +0200 Subject: Don't try to make direct system calls on Linux. Accept that we cannot do everything, so users using outdated toolchains may have threading problems (leaking file descriptors). It's not like this is a recent problem anyway... Reviewed-By: Bradley T. Hughes --- src/corelib/kernel/qcore_unix.cpp | 73 --------------------------------------- src/corelib/kernel/qcore_unix_p.h | 34 +++++------------- src/network/socket/qnet_unix_p.h | 2 +- 3 files changed, 10 insertions(+), 99 deletions(-) diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp index b57d385..efa9c6d 100644 --- a/src/corelib/kernel/qcore_unix.cpp +++ b/src/corelib/kernel/qcore_unix.cpp @@ -161,76 +161,3 @@ int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, } QT_END_NAMESPACE - -#ifdef Q_OS_LINUX -// Don't wait for libc to supply the calls we need -// Make syscalls directly - -# if defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204 -// glibc 2.4 has syscall(...) -# include -# include -# else -// no syscall(...) -static inline int syscall(...) { errno = ENOSYS; return -1;} -# endif - -# ifndef __NR_dup3 -# if defined(__i386__) -# define __NR_dup3 330 -# define __NR_pipe2 331 -# elif defined(__x86_64__) -# define __NR_dup3 292 -# define __NR_pipe2 293 -# elif defined(__ia64__) -# define __NR_dup3 1316 -# define __NR_pipe2 1317 -# else -// set the syscalls to absurd numbers so that they'll cause ENOSYS errors -# warning "Please port the pipe2/dup3 code to this platform" -# define __NR_dup3 -1 -# define __NR_pipe2 -1 -# endif -# endif - -# if !defined(__NR_socketcall) && !defined(__NR_accept4) -# if defined(__x86_64__) -# define __NR_accept4 288 -# elif defined(__ia64__) -// not assigned yet to IA-64 -# define __NR_accept4 -1 -# else -// set the syscalls to absurd numbers so that they'll cause ENOSYS errors -# warning "Please port the accept4 code to this platform" -# define __NR_accept4 -1 -# endif -# endif - -QT_BEGIN_NAMESPACE -namespace QtLibcSupplement { - int pipe2(int pipes[], int flags) - { - return syscall(__NR_pipe2, pipes, flags); - } - - int dup3(int oldfd, int newfd, int flags) - { - return syscall(__NR_dup3, oldfd, newfd, flags); - } - - int accept4(int s, sockaddr *addr, QT_SOCKLEN_T *addrlen, int flags) - { -# if defined(__NR_socketcall) - // This platform uses socketcall() instead of raw syscalls - // the SYS_ACCEPT4 number is cross-platform: 18 - return syscall(__NR_socketcall, 18, &s); -# else - return syscall(__NR_accept4, s, addr, addrlen, flags); -# endif - - Q_UNUSED(addr); Q_UNUSED(addrlen); Q_UNUSED(flags); // they're actually used - } -} -QT_END_NAMESPACE -#endif // Q_OS_LINUX - diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index 69ebb05..3bdd5ec 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -73,32 +73,16 @@ struct sockaddr; -#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204 -// Linux supports thread-safe FD_CLOEXEC +#if defined(Q_OS_LINUX) && defined(O_CLOEXEC) # define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 1 - -// add defines for the consts for Linux -# ifndef O_CLOEXEC -# define O_CLOEXEC 02000000 -# endif -# ifndef FD_DUPFD_CLOEXEC -# define F_DUPFD_CLOEXEC 1030 -# endif -# ifndef SOCK_CLOEXEC -# define SOCK_CLOEXEC O_CLOEXEC -# endif -# ifndef SOCK_NONBLOCK -# define SOCK_NONBLOCK O_NONBLOCK -# endif -# ifndef MSG_CMSG_CLOEXEC -# define MSG_CMSG_CLOEXEC 0x40000000 -# endif - QT_BEGIN_NAMESPACE namespace QtLibcSupplement { - Q_CORE_EXPORT int accept4(int, sockaddr *, QT_SOCKLEN_T *, int flags); - Q_CORE_EXPORT int dup3(int oldfd, int newfd, int flags); - Q_CORE_EXPORT int pipe2(int pipes[], int flags); + inline int accept4(int, sockaddr *, QT_SOCKLEN_T *, int) + { errno = ENOSYS; return -1; } + inline int dup3(int, int, int) + { errno = ENOSYS; return -1; } + inline int pipe2(int [], int ) + { errno = ENOSYS; return -1; } } QT_END_NAMESPACE using namespace QT_PREPEND_NAMESPACE(QtLibcSupplement); @@ -190,7 +174,7 @@ static inline int qt_safe_pipe(int pipefd[2], int flags = 0) #endif register int ret; -#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC +#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC && defined(O_CLOEXEC) // use pipe2 flags |= O_CLOEXEC; ret = ::pipe2(pipefd, flags); // pipe2 is Linux-specific and is documented not to return EINTR @@ -246,7 +230,7 @@ static inline int qt_safe_dup2(int oldfd, int newfd, int flags = FD_CLOEXEC) Q_ASSERT(flags == FD_CLOEXEC || flags == 0); register int ret; -#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC +#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC && defined(O_CLOEXEC) // use dup3 if (flags & FD_CLOEXEC) { EINTR_LOOP(ret, ::dup3(oldfd, newfd, O_CLOEXEC)); diff --git a/src/network/socket/qnet_unix_p.h b/src/network/socket/qnet_unix_p.h index f38c2fc..040b3ec 100644 --- a/src/network/socket/qnet_unix_p.h +++ b/src/network/socket/qnet_unix_p.h @@ -85,7 +85,7 @@ static inline int qt_safe_socket(int domain, int type, int protocol, int flags = Q_ASSERT((flags & ~O_NONBLOCK) == 0); register int fd; -#ifdef SOCK_CLOEXEC +#if defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) int newtype = type | SOCK_CLOEXEC; if (flags & O_NONBLOCK) newtype |= SOCK_NONBLOCK; -- cgit v0.12 From 9081e1e65681aab1c1d8a913b1a493fe1d37e837 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 3 Aug 2009 18:43:54 +0200 Subject: Clean up old Jambi code: there's a way of getting the QObject d-pointer --- src/corelib/kernel/qobject.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 7bf209a..c989d15 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -3897,19 +3897,12 @@ QDebug operator<<(QDebug dbg, const QObject *o) { Synonym for QList. */ -#ifdef QT_JAMBI_BUILD -class QDPtrAccessor : public QObject { -public: - QObjectData *d() const { return d_ptr; } -}; -#endif - void qDeleteInEventHandler(QObject *o) { #ifdef QT_JAMBI_BUILD if (!o) return; - ((QDPtrAccessor *) o)->d()->inEventHandler = false; + QObjectPrivate::get(o)->inEventHandler = false; #endif delete o; } -- cgit v0.12 From d6e7238903d381bf2c2c9f89c17085e714384e87 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 31 Jul 2009 18:46:11 +0200 Subject: Reorganise QObjectPrivate so that it's easier to tell what's in it. Also rename QDeclarativeData to QObjectDeletionNotification, since it has no relation to declarative UI. It's just notification of the object's deletion. Make the destructor non-inline and place it in qobject.cpp, so that the virtual table is emitted there and exported from QtCore. Also move the QObjectData destructor to qobject.cpp. This means you cannot create any class deriving directly from QObjectData outside QtCore, which is the intention anyways (it's a private class and only QObjectPrivate derives from it). Reviewed-by: Bradley T. Hughes --- src/corelib/kernel/qobject.cpp | 16 +++--- src/corelib/kernel/qobject_p.h | 113 +++++++++++++++++++++-------------------- src/gui/kernel/qwidget.cpp | 7 ++- 3 files changed, 66 insertions(+), 70 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index c989d15..1938012 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -122,8 +122,11 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *) } } +QObjectData::~QObjectData() {} +QObjectDeletionNotification::~QObjectDeletionNotification() {} + QObjectPrivate::QObjectPrivate(int version) - : threadData(0), currentSender(0), declarativeData(0), connectionLists(0), senders(0) + : threadData(0), connectionLists(0), senders(0), currentSender(0), deletionNotification(0), objectGuards(0) { if (version != QObjectPrivateVersion) qFatal("Cannot mix incompatible Qt libraries"); @@ -144,7 +147,6 @@ QObjectPrivate::QObjectPrivate(int version) inEventHandler = false; inThreadChangeEvent = false; deleteWatch = 0; - objectGuards = 0; metaObject = 0; hasGuards = false; } @@ -767,6 +769,8 @@ QObject::~QObject() } emit destroyed(this); + if (d->deletionNotification) + d->deletionNotification->destroyed(this); { QMutexLocker locker(signalSlotLock(this)); @@ -844,14 +848,6 @@ QObject::~QObject() d->eventFilters.clear(); - // As declarativeData is in a union with currentChildBeingDeleted, this must - // be done (and declarativeData set back to 0) before deleting children. - if(d->declarativeData) { - QDeclarativeData *dd = d->declarativeData; - d->declarativeData = 0; - dd->destroyed(this); - } - if (!d->children.isEmpty()) d->deleteChildren(); diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 0b41c9a..52b4658 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -82,63 +82,21 @@ void Q_CORE_EXPORT qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet extern QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set; -inline QObjectData::~QObjectData() {} - enum { QObjectPrivateVersion = QT_VERSION }; -class QDeclarativeData +class Q_CORE_EXPORT QObjectDeletionNotification { public: - virtual ~QDeclarativeData() {} - virtual void destroyed(QObject *) {} + virtual ~QObjectDeletionNotification(); + virtual void destroyed(QObject *) = 0; }; +typedef QObjectDeletionNotification QDeclarativeData; // remove me when Declarative UI updates class Q_CORE_EXPORT QObjectPrivate : public QObjectData { Q_DECLARE_PUBLIC(QObject) public: - QObjectPrivate(int version = QObjectPrivateVersion); - virtual ~QObjectPrivate(); - -#ifdef QT3_SUPPORT - QList pendingChildInsertedEvents; - void sendPendingChildInsertedEvents(); - void removePendingChildInsertedEvents(QObject *child); -#else - // preserve binary compatibility with code compiled without Qt 3 support - QList unused; -#endif - - // id of the thread that owns the object - QThreadData *threadData; - void moveToThread_helper(); - void setThreadData_helper(QThreadData *currentData, QThreadData *targetData); - void _q_reregisterTimers(void *pointer); - - struct Sender - { - QObject *sender; - int signal; - int ref; - }; - // object currently activating the object - Sender *currentSender; - - QDeclarativeData *declarativeData; - - bool isSender(const QObject *receiver, const char *signal) const; - QObjectList receiverList(const char *signal) const; - QObjectList senderList() const; - - QList > eventFilters; - - void setParent_helper(QObject *); - - void deleteChildren(); - - static void clearGuards(QObject *); - struct ExtraData { #ifndef QT_NO_USERDATA @@ -147,12 +105,7 @@ public: QList propertyNames; QList propertyValues; }; - ExtraData *extraData; - mutable quint32 connectedSignals[2]; - - QString objectName; - // Note: you must hold the signalSlotLock() before accessing the lists below or calling the functions struct Connection { QObject *sender; @@ -167,11 +120,34 @@ public: }; typedef QList ConnectionList; - QObjectConnectionListVector *connectionLists; + struct Sender + { + QObject *sender; + int signal; + int ref; + }; + + + QObjectPrivate(int version = QObjectPrivateVersion); + virtual ~QObjectPrivate(); + void deleteChildren(); + + void setParent_helper(QObject *); + void moveToThread_helper(); + void setThreadData_helper(QThreadData *currentData, QThreadData *targetData); + void _q_reregisterTimers(void *pointer); + + bool isSender(const QObject *receiver, const char *signal) const; + QObjectList receiverList(const char *signal) const; + QObjectList senderList() const; + void addConnection(int signal, Connection *c); void cleanConnectionLists(); - Connection *senders; //linked list; +#ifdef QT3_SUPPORT + void sendPendingChildInsertedEvents(); + void removePendingChildInsertedEvents(QObject *child); +#endif static Sender *setCurrentSender(QObject *receiver, Sender *sender); @@ -180,13 +156,38 @@ public: Sender *previousSender); static int *setDeleteWatch(QObjectPrivate *d, int *newWatch); static void resetDeleteWatch(QObjectPrivate *d, int *oldWatch, int deleteWatch); - - int *deleteWatch; - QGuard *objectGuards; + static void clearGuards(QObject *); static QObjectPrivate *get(QObject *o) { return o->d_func(); } + +public: + QString objectName; + ExtraData *extraData; // extra data set by the user + QThreadData *threadData; // id of the thread that owns the object + + QObjectConnectionListVector *connectionLists; + + Connection *senders; // linked list of connections connected to this object + Sender *currentSender; // object currently activating the object + mutable quint32 connectedSignals[2]; // 64-bit, so doesn't cause padding on 64-bit platforms + +#ifdef QT3_SUPPORT + QList pendingChildInsertedEvents; +#else + // preserve binary compatibility with code compiled without Qt 3 support + // ### why? + QList unused; +#endif + + QList > eventFilters; + + // these objects are all used to indicate that a QObject was deleted + // plus QPointer, which keeps a separate list + QObjectDeletionNotification *deletionNotification; + QGuard *objectGuards; + int *deleteWatch; }; inline void q_guard_addGuard(QGuard *g) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 765b26f..075f9c3 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1375,10 +1375,9 @@ QWidget::~QWidget() // set all QPointers for this object to zero QObjectPrivate::clearGuards(this); - if(d->declarativeData) { - QDeclarativeData *dd = d->declarativeData; - d->declarativeData = 0; - dd->destroyed(this); + if (d->deletionNotification) { + d->deletionNotification->destroyed(this); + d->deletionNotification = 0; // don't activate again in ~QObject } if (!d->children.isEmpty()) -- cgit v0.12 From a654df7aa466775b0f9a6e4b33319c228f5634b2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 3 Aug 2009 14:56:49 +0200 Subject: Add QWeakPointer::data, which thread-unsafely returns the tracked pointer This function allows one to retrieve the pointer out of a QWeakPointer without promoting it to QSharedPointer first. That means there are no guarantees that the object won't get deleted. Reviewed-by: Bradley T. Hughes --- src/corelib/tools/qsharedpointer.cpp | 76 ++++++++++++++++++++++++++++++++- src/corelib/tools/qsharedpointer_impl.h | 1 + 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 2ca612e..ef4dfac 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -128,7 +128,7 @@ To access the pointer that QWeakPointer is tracking, you must first create a QSharedPointer object and verify if the pointer - is null or not. + is null or not. See QWeakPointer::toStrongRef() for more information. \sa QSharedPointer */ @@ -210,6 +210,8 @@ If \tt T is a derived type of the template parameter of this class, QSharedPointer will perform an automatic cast. Otherwise, you will get a compiler error. + + \sa QWeakPointer::toStrongRef() */ /*! @@ -362,6 +364,8 @@ Returns a weak reference object that shares the pointer referenced by this object. + + \sa QWeakPointer::QWeakPointer(const QSharedPointer &) */ /*! @@ -478,10 +482,78 @@ */ /*! + \fn T *QWeakPointer::data() const + \since 4.6 + + Returns the value of the pointer being tracked by this QWeakPointer, + \b without ensuring that it cannot get deleted. To have that guarantee, + use toStrongRef(), which returns a QSharedPointer object. If this + function can determine that the pointer has already been deleted, it + returns 0. + + It is ok to obtain the value of the pointer and using that value itself, + like for example in debugging statements: + + \code + qDebug("Tracking %p", weakref.data()); + \endcode + + However, dereferencing the pointer is only allowed if you can guarantee + by external means that the pointer does not get deleted. For example, + if you can be certain that no other thread can delete it, nor the + functions that you may call. + + If that is the case, then the following code is valid: + + \code + // this pointer cannot be used in another thread + // so other threads cannot delete it + QWeakPointer weakref = obtainReference(); + + Object *obj = weakref.data(); + if (obj) { + // if the pointer wasn't deleted yet, we know it can't get + // deleted by our own code here nor the functions we call + otherFunction(obj); + } + \endcode + + Use this function with care. + + \sa isNull(), toStrongRef() +*/ + +/*! \fn QSharedPointer QWeakPointer::toStrongRef() const Promotes this weak reference to a strong one and returns a - QSharedPointer object holding that reference. + QSharedPointer object holding that reference. When promoting to + QSharedPointer, this function verifies if the object has been deleted + already or not. If it hasn't, this function increases the reference + count to the shared object, thus ensuring that it will not get + deleted. + + Since this function can fail to obtain a valid strong reference to the + shared object, you should always verify if the conversion succeeded, + by calling QSharedPointer::isNull() on the returned object. + + For example, the following code promotes a QWeakPointer that was held + to a strong reference and, if it succeeded, it prints the value of the + integer that was held: + + \code + QWeakPointer weakref; + + // ... + + QSharedPointer strong = weakref.toStrongRef(); + if (strong) + qDebug() << "The value is:" << *strong; + else + qDebug() << "The value has already been deleted"; + \endcode + + \sa QSharedPointer::QSharedPointer(const QWeakPointer &) */ /*! diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 9fa8df4..e8e3812 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -492,6 +492,7 @@ public: inline bool isNull() const { return d == 0 || d->strongref == 0 || value == 0; } inline operator RestrictedBool() const { return isNull() ? 0 : &QWeakPointer::value; } inline bool operator !() const { return isNull(); } + inline T *data() const { return d == 0 || d->strongref == 0 ? 0 : value; } inline QWeakPointer() : d(0), value(0) { } inline ~QWeakPointer() { if (d && !d->weakref.deref()) delete d; } -- cgit v0.12 From 6e9d84fcadc07b8f11d9e0eb046c25152eba1235 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 4 Aug 2009 16:33:09 +0200 Subject: Added the license header to the example. --- .../gestures/imageviewer/tapandholdgesture.cpp | 41 ++++++++++++++++++++++ examples/gestures/imageviewer/tapandholdgesture.h | 41 ++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/examples/gestures/imageviewer/tapandholdgesture.cpp b/examples/gestures/imageviewer/tapandholdgesture.cpp index c6f6779..ff5284e 100644 --- a/examples/gestures/imageviewer/tapandholdgesture.cpp +++ b/examples/gestures/imageviewer/tapandholdgesture.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include "tapandholdgesture.h" #include diff --git a/examples/gestures/imageviewer/tapandholdgesture.h b/examples/gestures/imageviewer/tapandholdgesture.h index 711a1af..e0d50b5 100644 --- a/examples/gestures/imageviewer/tapandholdgesture.h +++ b/examples/gestures/imageviewer/tapandholdgesture.h @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #ifndef TAPANDHOLDGESTURE_H #define TAPANDHOLDGESTURE_H -- cgit v0.12 From ed375675d4a4f6fd63edeb242e23c87b3de4be6f Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Tue, 21 Jul 2009 13:37:43 +0200 Subject: Fix: Gtk native dialogs do not repaint when zero-timers are used The problem was that our glib timers were given too high priority, effectively starving the Gtk event loop. By assigning our timer source, G_PRIORITY_DEFAULT_IDLE we ensure that all gtk+ events are handled first, thus allowing the native dialogs to respond and repaint properly. Task-number: 258433 Reviewed-by: bhughes --- src/corelib/kernel/qeventdispatcher_glib.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp index 7610631..2bbe560 100644 --- a/src/corelib/kernel/qeventdispatcher_glib.cpp +++ b/src/corelib/kernel/qeventdispatcher_glib.cpp @@ -263,6 +263,7 @@ QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(GMainContext *context) (void) new (&timerSource->timerList) QTimerInfoList(); timerSource->processEventsFlags = QEventLoop::AllEvents; g_source_set_can_recurse(&timerSource->source, true); + g_source_set_priority(&timerSource->source, G_PRIORITY_DEFAULT_IDLE); g_source_attach(&timerSource->source, mainContext); } -- cgit v0.12 From c9a449af8d17e493950a63ca3f8a22232968c47e Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Tue, 4 Aug 2009 16:54:07 +0200 Subject: Make file extension case insensitive with the Gtk+ file dialog The Qt dialog treats extension filters as case insensitive where the default behavior of the Gtk+ file dialog is to be case sensitive. The GtkFileFilter allows only simple glob syntax to be used so we basically rewrite the extension string from .xyz to .[xX][yY][zZ]. Task-number: 259155 Reviewed-by: joao --- src/gui/styles/gtksymbols.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/gui/styles/gtksymbols.cpp b/src/gui/styles/gtksymbols.cpp index be9b10a..b2c53f3 100644 --- a/src/gui/styles/gtksymbols.cpp +++ b/src/gui/styles/gtksymbols.cpp @@ -733,7 +733,24 @@ static void setupGtkFileChooser(GtkWidget* gtkFileChooser, QWidget *parent, QGtk::gtk_file_filter_set_name(gtkFilter, qPrintable(name.isEmpty() ? extensions.join(QLS(", ")) : name)); foreach (const QString &fileExtension, extensions) { - QGtk::gtk_file_filter_add_pattern (gtkFilter, qPrintable(fileExtension)); + // Note Gtk file dialogs are by default case sensitive + // and only supports basic glob syntax so we + // rewrite .xyz to .[xX][yY][zZ] + QString caseInsensitive; + for (int i = 0 ; i < fileExtension.length() ; ++i) { + QChar ch = fileExtension.at(i); + if (ch.isLetter()) { + caseInsensitive.append( + QLatin1Char('[') + + ch.toLower() + + ch.toUpper() + + QLatin1Char(']')); + } else { + caseInsensitive.append(ch); + } + } + QGtk::gtk_file_filter_add_pattern (gtkFilter, qPrintable(caseInsensitive)); + } QGtk::gtk_file_chooser_add_filter((GtkFileChooser*)gtkFileChooser, gtkFilter); if (selectedFilter && (rawfilter == *selectedFilter)) -- cgit v0.12 From 31edb4d5a63b9b3c28cce1c4ca6eb99f62a09759 Mon Sep 17 00:00:00 2001 From: Matthew Cattell Date: Tue, 4 Aug 2009 16:45:46 +0200 Subject: qregext filter changed to support additional parameter/unicode changed the QRegExp filter back to the old form plus an additional piece to allow international characters. the new regular expression now allows a file type filter to contain a bracketed description prior to the filter set itself. 259105 Andy Shaw --- src/gui/dialogs/qfiledialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index 8b4e1b1..1ec94b6 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -2838,7 +2838,8 @@ void QFileDialogPrivate::_q_goToDirectory(const QString &path) } const char *qt_file_dialog_filter_reg_exp = - "^([^()]*)\\(([a-zA-Z0-9_.*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$"; +"(\\W|[a-zA-Z0-9 -]*)\\(([a-zA-Z0-9_.*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$"; + // Makes a list of filters from a normal filter string "Image Files (*.png *.jpg)" QStringList qt_clean_filter_list(const QString &filter) -- cgit v0.12 From 83ff02450ea74468fec441e632ddc2cfda2b251c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 4 Aug 2009 18:01:33 +0200 Subject: Revert "Remove currentChildBeingDeleted from QObjectPrivate." This reverts commit 128717b171f01c82e5f0fb83f5923d4f7b9cfc10. The change broke Alien because QWidget no longer has the native window handle in its own private. It needs to access the top-level window (or the one with the native handle) in order to perform some operations. The problem is that it needs to do that in the destructor. And we cleared the parent before the destructor was run. Technically speaking, reverting is the correct thing to do, since the parent *still* exists when the child is deleted. --- src/corelib/kernel/qobject.cpp | 29 +++++++++++++++++------------ src/corelib/kernel/qobject_p.h | 1 + 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 1938012..0801418 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -126,7 +126,7 @@ QObjectData::~QObjectData() {} QObjectDeletionNotification::~QObjectDeletionNotification() {} QObjectPrivate::QObjectPrivate(int version) - : threadData(0), connectionLists(0), senders(0), currentSender(0), deletionNotification(0), objectGuards(0) + : threadData(0), connectionLists(0), senders(0), currentSender(0), currentChildBeingDeleted(0), deletionNotification(0), objectGuards(0) { if (version != QObjectPrivateVersion) qFatal("Cannot mix incompatible Qt libraries"); @@ -1855,13 +1855,12 @@ void QObjectPrivate::deleteChildren() // don't use qDeleteAll as the destructor of the child might // delete siblings for (int i = 0; i < children.count(); ++i) { - QObject *child = children.at(i); + currentChildBeingDeleted = children.at(i); children[i] = 0; - if (child) - child->d_func()->parent = 0; - delete child; + delete currentChildBeingDeleted; } children.clear(); + currentChildBeingDeleted = 0; wasDeleted = reallyWasDeleted; } @@ -1872,14 +1871,20 @@ void QObjectPrivate::setParent_helper(QObject *o) return; if (parent) { QObjectPrivate *parentD = parent->d_func(); - const int index = parentD->children.indexOf(q); - if (parentD->wasDeleted) { - parentD->children[index] = 0; + if (parentD->wasDeleted && wasDeleted + && parentD->currentChildBeingDeleted == q) { + // don't do anything since QObjectPrivate::deleteChildren() already + // cleared our entry in parentD->children. } else { - parentD->children.removeAt(index); - if (sendChildEvents && parentD->receiveChildEvents) { - QChildEvent e(QEvent::ChildRemoved, q); - QCoreApplication::sendEvent(parent, &e); + const int index = parentD->children.indexOf(q); + if (parentD->wasDeleted) { + parentD->children[index] = 0; + } else { + parentD->children.removeAt(index); + if (sendChildEvents && parentD->receiveChildEvents) { + QChildEvent e(QEvent::ChildRemoved, q); + QCoreApplication::sendEvent(parent, &e); + } } } } diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 52b4658..a7f3a5a 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -182,6 +182,7 @@ public: #endif QList > eventFilters; + QObject *currentChildBeingDeleted; // these objects are all used to indicate that a QObject was deleted // plus QPointer, which keeps a separate list -- cgit v0.12 From a22f422b20299a501c307b21a6095ece87749124 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 4 Aug 2009 18:43:10 +0200 Subject: Restore the old name for QObjectDeletionNotification. If we're going to do changes to simplify some of the Declarative UI enablers, let's do them all at once. That way, the adaptation necessary happens only once, as opposed to every time we do the changes. I tried not to break by leaving a typedef, but obviously the QObjectPrivate member isn't affected by the typedef... Reviewed-by: Trust Me --- src/corelib/kernel/qobject.cpp | 8 ++++---- src/corelib/kernel/qobject_p.h | 7 +++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 0801418..7e7dcaf 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -123,10 +123,10 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *) } QObjectData::~QObjectData() {} -QObjectDeletionNotification::~QObjectDeletionNotification() {} +QDeclarativeData::~QDeclarativeData() {} QObjectPrivate::QObjectPrivate(int version) - : threadData(0), connectionLists(0), senders(0), currentSender(0), currentChildBeingDeleted(0), deletionNotification(0), objectGuards(0) + : threadData(0), connectionLists(0), senders(0), currentSender(0), currentChildBeingDeleted(0), declarativeData(0), objectGuards(0) { if (version != QObjectPrivateVersion) qFatal("Cannot mix incompatible Qt libraries"); @@ -769,8 +769,8 @@ QObject::~QObject() } emit destroyed(this); - if (d->deletionNotification) - d->deletionNotification->destroyed(this); + if (d->declarativeData) + d->declarativeData->destroyed(this); { QMutexLocker locker(signalSlotLock(this)); diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index a7f3a5a..e58ee6c 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -84,13 +84,12 @@ extern QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set; enum { QObjectPrivateVersion = QT_VERSION }; -class Q_CORE_EXPORT QObjectDeletionNotification +class Q_CORE_EXPORT QDeclarativeData { public: - virtual ~QObjectDeletionNotification(); + virtual ~QDeclarativeData(); virtual void destroyed(QObject *) = 0; }; -typedef QObjectDeletionNotification QDeclarativeData; // remove me when Declarative UI updates class Q_CORE_EXPORT QObjectPrivate : public QObjectData { @@ -186,7 +185,7 @@ public: // these objects are all used to indicate that a QObject was deleted // plus QPointer, which keeps a separate list - QObjectDeletionNotification *deletionNotification; + QDeclarativeData *declarativeData; QGuard *objectGuards; int *deleteWatch; }; -- cgit v0.12 From 8e01aa83880bf9cc669106f1e219abd3b3fca186 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 4 Aug 2009 20:06:04 +0200 Subject: Fixed bug where Q[Styled]ItemDelegate edition wouldn't terminate when the item lost focus to an unrelated dialog. The tests against the active modal window was unnecessary. Task-number: 257859 Reviewed-by: olivier --- src/gui/itemviews/qitemdelegate.cpp | 7 +----- src/gui/itemviews/qstyleditemdelegate.cpp | 8 +------ tests/auto/qitemdelegate/tst_qitemdelegate.cpp | 33 ++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/gui/itemviews/qitemdelegate.cpp b/src/gui/itemviews/qitemdelegate.cpp index aff715c..962ce54 100644 --- a/src/gui/itemviews/qitemdelegate.cpp +++ b/src/gui/itemviews/qitemdelegate.cpp @@ -1238,12 +1238,7 @@ bool QItemDelegate::eventFilter(QObject *object, QEvent *event) if (QDragManager::self() && QDragManager::self()->object != 0) return false; #endif - // Opening a modal dialog will start a new eventloop - // that will process the deleteLater event. - if (QApplication::activeModalWidget() - && !QApplication::activeModalWidget()->isAncestorOf(editor) - && qobject_cast(QApplication::activeModalWidget())) - return false; + emit commitData(editor); emit closeEditor(editor, NoHint); } diff --git a/src/gui/itemviews/qstyleditemdelegate.cpp b/src/gui/itemviews/qstyleditemdelegate.cpp index 7ec2afe..8faf0be 100644 --- a/src/gui/itemviews/qstyleditemdelegate.cpp +++ b/src/gui/itemviews/qstyleditemdelegate.cpp @@ -686,13 +686,7 @@ bool QStyledItemDelegate::eventFilter(QObject *object, QEvent *event) if (QDragManager::self() && QDragManager::self()->object != 0) return false; #endif - // Opening a modal dialog will start a new eventloop - // that will process the deleteLater event. - QWidget *activeModalWidget = QApplication::activeModalWidget(); - if (activeModalWidget - && !activeModalWidget->isAncestorOf(editor) - && qobject_cast(activeModalWidget)) - return false; + emit commitData(editor); emit closeEditor(editor, NoHint); } diff --git a/tests/auto/qitemdelegate/tst_qitemdelegate.cpp b/tests/auto/qitemdelegate/tst_qitemdelegate.cpp index 65dd86f..6714de3 100644 --- a/tests/auto/qitemdelegate/tst_qitemdelegate.cpp +++ b/tests/auto/qitemdelegate/tst_qitemdelegate.cpp @@ -61,6 +61,7 @@ #include #include #include +#include Q_DECLARE_METATYPE(QAbstractItemDelegate::EndEditHint) @@ -230,6 +231,8 @@ private slots: void editorEvent(); void enterKey_data(); void enterKey(); + + void task257859_finalizeEdit(); }; @@ -1124,6 +1127,36 @@ void tst_QItemDelegate::enterKey() QCOMPARE(editor && editor->hasFocus(), expectedFocus); } +void tst_QItemDelegate::task257859_finalizeEdit() +{ + QStandardItemModel model; + model.appendRow(new QStandardItem()); + + QListView view; + view.setModel(&model); + view.show(); + QApplication::setActiveWindow(&view); + view.setFocus(); + QTest::qWait(30); + + QModelIndex index = model.index(0, 0); + view.edit(index); + QTest::qWait(30); + + QList lineEditors = qFindChildren(view.viewport()); + QCOMPARE(lineEditors.count(), 1); + + QPointer editor = lineEditors.at(0); + QCOMPARE(editor->hasFocus(), true); + + QDialog dialog; + QTimer::singleShot(100, &dialog, SLOT(close())); + dialog.exec(); + + QTest::qWait(10); + + QVERIFY(!editor); +} // ### _not_ covered: -- cgit v0.12 From 2843c97f5310f4636c933ced56570ab7db2b707e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 4 Aug 2009 21:05:35 +0200 Subject: Fix compilation after my last change to qobject_p.h I renamed deletionNotification back to its original name. I had forgotten that QWidget needed a similar change. Reviewed-by: Trust Me --- src/gui/kernel/qwidget.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 075f9c3..a827967 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1375,9 +1375,9 @@ QWidget::~QWidget() // set all QPointers for this object to zero QObjectPrivate::clearGuards(this); - if (d->deletionNotification) { - d->deletionNotification->destroyed(this); - d->deletionNotification = 0; // don't activate again in ~QObject + if (d->declarativeData) { + d->declarativeData->destroyed(this); + d->declarativeData = 0; // don't activate again in ~QObject } if (!d->children.isEmpty()) -- cgit v0.12 From a4ede01350b506c9908241f0b9002f560cc0949f Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 5 Aug 2009 13:21:00 +1000 Subject: Fixes casing issue in the PSQL driver. The record and primaryIndex functions don't take into account that psql treats different casing as different entities when enquoted. --- src/sql/drivers/psql/qsql_psql.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index c61c526..4fd0c11 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -940,7 +940,7 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const case QPSQLDriver::Version6: stmt = QLatin1String("select pg_att1.attname, int(pg_att1.atttypid), pg_cl.relname " "from pg_attribute pg_att1, pg_attribute pg_att2, pg_class pg_cl, pg_index pg_ind " - "where lower(pg_cl.relname) = '%1_pkey' " + "where pg_cl.relname = '%1_pkey' " "and pg_cl.oid = pg_ind.indexrelid " "and pg_att2.attrelid = pg_ind.indexrelid " "and pg_att1.attrelid = pg_ind.indrelid " @@ -951,7 +951,7 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const case QPSQLDriver::Version71: stmt = QLatin1String("select pg_att1.attname, pg_att1.atttypid::int, pg_cl.relname " "from pg_attribute pg_att1, pg_attribute pg_att2, pg_class pg_cl, pg_index pg_ind " - "where lower(pg_cl.relname) = '%1_pkey' " + "where pg_cl.relname = '%1_pkey' " "and pg_cl.oid = pg_ind.indexrelid " "and pg_att2.attrelid = pg_ind.indexrelid " "and pg_att1.attrelid = pg_ind.indrelid " @@ -1016,7 +1016,7 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, " "int(pg_attribute.attrelid), pg_attribute.attnum " "from pg_class, pg_attribute " - "where lower(pg_class.relname) = '%1' " + "where pg_class.relname = '%1' " "and pg_attribute.attnum > 0 " "and pg_attribute.attrelid = pg_class.oid "); break; @@ -1025,7 +1025,7 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, " "pg_attribute.attrelid::int, pg_attribute.attnum " "from pg_class, pg_attribute " - "where lower(pg_class.relname) = '%1' " + "where pg_class.relname = '%1' " "and pg_attribute.attnum > 0 " "and pg_attribute.attrelid = pg_class.oid "); break; @@ -1036,7 +1036,7 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const "from pg_class, pg_attribute " "left join pg_attrdef on (pg_attrdef.adrelid = " "pg_attribute.attrelid and pg_attrdef.adnum = pg_attribute.attnum) " - "where lower(pg_class.relname) = '%1' " + "where pg_class.relname = '%1' " "and pg_attribute.attnum > 0 " "and pg_attribute.attrelid = pg_class.oid " "order by pg_attribute.attnum "); -- cgit v0.12 From 7e8e53cded4622ac35ff115e26e074de6722d1a0 Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 5 Aug 2009 13:38:44 +1000 Subject: Get more database tests working/passing. --- tests/auto/qsqldatabase/tst_databases.h | 12 +++++++++++- tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 10 +++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/tests/auto/qsqldatabase/tst_databases.h b/tests/auto/qsqldatabase/tst_databases.h index 8ee74df..ad70471 100644 --- a/tests/auto/qsqldatabase/tst_databases.h +++ b/tests/auto/qsqldatabase/tst_databases.h @@ -219,7 +219,7 @@ public: // addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 3307 ); // addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 3308, "CLIENT_COMPRESS=1;CLIENT_SSL=1" ); // MySQL 4.1.1 // addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 3309, "CLIENT_COMPRESS=1;CLIENT_SSL=1" ); // MySQL 5.0.18 Linux -// addDb( "QMYSQL3", "testdb", "troll", "trond", "iceblink.nokia.troll.no" ); // MySQL 5.0.13 Windows +// addDb( "QMYSQL3", "testdb", "troll", "trond", "silence.nokia.troll.no" ); // MySQL 5.1.36 Windows // addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "mysql4-nokia.trolltech.com.au" ); // MySQL 4.1.22-2.el4 linux // addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "mysql5-nokia.trolltech.com.au" ); // MySQL 5.0.45-7.el5 linux @@ -481,6 +481,16 @@ public: return QString(); } + static QString getPSQLVersion( const QSqlDatabase &db ) + { + QSqlQuery q(db); + q.exec( "select version()" ); + if(q.next()) + return q.value( 0 ).toString(); + else + return QString(); + } + QStringList dbNames; int counter; }; diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index ff62741..de4fe8f 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -1057,6 +1057,7 @@ void tst_QSqlDatabase::recordMySQL() int major = tst_Databases::getMySqlVersion( db ).section( QChar('.'), 0, 0 ).toInt(); int minor = tst_Databases::getMySqlVersion( db ).section( QChar('.'), 1, 1 ).toInt(); int revision = tst_Databases::getMySqlVersion( db ).section( QChar('.'), 2, 2 ).toInt(); + int vernum = (major << 16) + (minor << 8) + revision; #ifdef QT3_SUPPORT /* The below is broken in mysql below 5.0.15 @@ -1064,7 +1065,7 @@ void tst_QSqlDatabase::recordMySQL() specifically: Before MySQL 5.0.15, the pad value is space. Values are right-padded with space on insert, and trailing spaces are removed on select. */ - if ( major >5 || ( major == 5 && minor > 0) || ( major == 5 && minor == 0 && revision >= 15) ) { + if( vernum >= ((5 << 16) + 15) ) { bin10 = FieldDef("binary(10)", QVariant::ByteArray, QByteArray(Q3CString("123abc "))); varbin10 = FieldDef("varbinary(10)", QVariant::ByteArray, QByteArray(Q3CString("123abcv "))); } @@ -1594,6 +1595,11 @@ void tst_QSqlDatabase::bug_249059() QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + QString version=tst_Databases::getPSQLVersion( db ); + double ver=version.section(QChar::fromLatin1('.'),0,1).toDouble(); + if (ver < 7.3) + QSKIP("Test requires PostgreSQL >= 7.3", SkipSingle); + QSqlQuery q(db); QString tableName = qTableName("bug_249059"); QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (dt timestamp, t time)").arg(tableName))); @@ -2006,8 +2012,6 @@ void tst_QSqlDatabase::mysql_multiselect() CHECK_DATABASE(db); QSqlQuery q(db); - QVERIFY_SQL(q, exec("select version()")); - QVERIFY_SQL(q, next()); QString version=tst_Databases::getMySqlVersion( db ); double ver=version.section(QChar::fromLatin1('.'),0,1).toDouble(); if (ver < 4.1) -- cgit v0.12 From e7052de274f6a201be628441d144dbbef5868948 Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Wed, 5 Aug 2009 14:26:56 +1000 Subject: Merge AudioServices into mainline. --- bin/syncqt | 1 + config.tests/unix/alsa/alsa.pro | 4 + config.tests/unix/alsa/alsatest.cpp | 6 + configure | 36 +- configure.exe | Bin 1896493 -> 1134080 bytes demos/qtdemo/xml/examples.xml | 5 + doc/src/examples-overview.qdoc | 11 + doc/src/examples.qdoc | 8 + doc/src/examples/audiodevices.qdoc | 54 ++ doc/src/examples/audioinput.qdoc | 54 ++ doc/src/examples/audiooutput.qdoc | 52 ++ examples/examples.pro | 1 + examples/multimedia/README | 34 + examples/multimedia/audio/audio.pro | 10 + .../multimedia/audio/audiodevices/audiodevices.cpp | 272 ++++++ .../multimedia/audio/audiodevices/audiodevices.h | 79 ++ .../multimedia/audio/audiodevices/audiodevices.pro | 12 + .../audio/audiodevices/audiodevicesbase.ui | 255 ++++++ examples/multimedia/audio/audiodevices/main.cpp | 55 ++ .../multimedia/audio/audioinput/audioinput.cpp | 376 +++++++++ examples/multimedia/audio/audioinput/audioinput.h | 144 ++++ .../multimedia/audio/audioinput/audioinput.pro | 12 + examples/multimedia/audio/audioinput/main.cpp | 55 ++ .../multimedia/audio/audiooutput/audiooutput.cpp | 280 +++++++ .../multimedia/audio/audiooutput/audiooutput.h | 112 +++ .../multimedia/audio/audiooutput/audiooutput.pro | 11 + examples/multimedia/audio/audiooutput/main.cpp | 56 ++ examples/multimedia/multimedia.pro | 8 + mkspecs/features/qt.prf | 3 +- src/corelib/global/qglobal.h | 14 + src/multimedia/audio/audio.pri | 56 ++ src/multimedia/audio/qaudio.cpp | 102 +++ src/multimedia/audio/qaudio.h | 71 ++ src/multimedia/audio/qaudio_mac.cpp | 142 ++++ src/multimedia/audio/qaudio_mac_p.h | 144 ++++ src/multimedia/audio/qaudiodevicefactory.cpp | 250 ++++++ src/multimedia/audio/qaudiodevicefactory_p.h | 100 +++ src/multimedia/audio/qaudiodeviceid.cpp | 168 ++++ src/multimedia/audio/qaudiodeviceid.h | 94 +++ src/multimedia/audio/qaudiodeviceid_p.h | 82 ++ src/multimedia/audio/qaudiodeviceinfo.cpp | 270 ++++++ src/multimedia/audio/qaudiodeviceinfo.h | 102 +++ src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp | 394 +++++++++ src/multimedia/audio/qaudiodeviceinfo_alsa_p.h | 113 +++ src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp | 357 ++++++++ src/multimedia/audio/qaudiodeviceinfo_mac_p.h | 97 +++ src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp | 378 +++++++++ src/multimedia/audio/qaudiodeviceinfo_win32_p.h | 108 +++ src/multimedia/audio/qaudioengine.cpp | 343 ++++++++ src/multimedia/audio/qaudioengine.h | 131 +++ src/multimedia/audio/qaudioengineplugin.cpp | 54 ++ src/multimedia/audio/qaudioengineplugin.h | 93 +++ src/multimedia/audio/qaudioformat.cpp | 335 ++++++++ src/multimedia/audio/qaudioformat.h | 103 +++ src/multimedia/audio/qaudioinput.cpp | 400 +++++++++ src/multimedia/audio/qaudioinput.h | 108 +++ src/multimedia/audio/qaudioinput_alsa_p.cpp | 688 +++++++++++++++ src/multimedia/audio/qaudioinput_alsa_p.h | 151 ++++ src/multimedia/audio/qaudioinput_mac_p.cpp | 930 +++++++++++++++++++++ src/multimedia/audio/qaudioinput_mac_p.h | 171 ++++ src/multimedia/audio/qaudioinput_win32_p.cpp | 540 ++++++++++++ src/multimedia/audio/qaudioinput_win32_p.h | 154 ++++ src/multimedia/audio/qaudiooutput.cpp | 403 +++++++++ src/multimedia/audio/qaudiooutput.h | 109 +++ src/multimedia/audio/qaudiooutput_alsa_p.cpp | 706 ++++++++++++++++ src/multimedia/audio/qaudiooutput_alsa_p.h | 159 ++++ src/multimedia/audio/qaudiooutput_mac_p.cpp | 700 ++++++++++++++++ src/multimedia/audio/qaudiooutput_mac_p.h | 171 ++++ src/multimedia/audio/qaudiooutput_win32_p.cpp | 502 +++++++++++ src/multimedia/audio/qaudiooutput_win32_p.h | 154 ++++ src/multimedia/multimedia.pro | 11 + src/plugins/audio/audio.pro | 3 + src/plugins/plugins.pro | 1 + src/src.pro | 4 + tests/auto/auto.pro | 4 + tests/auto/qaudiodeviceid/qaudiodeviceid.pro | 7 + tests/auto/qaudiodeviceid/tst_qaudiodeviceid.cpp | 98 +++ tests/auto/qaudiodeviceinfo/qaudiodeviceinfo.pro | 7 + .../auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp | 159 ++++ tests/auto/qaudioformat/qaudioformat.pro | 7 + tests/auto/qaudioformat/tst_qaudioformat.cpp | 180 ++++ tests/auto/qaudioinput/qaudioinput.pro | 7 + tests/auto/qaudioinput/tst_qaudioinput.cpp | 120 +++ tests/auto/qaudiooutput/4.wav | Bin 0 -> 5538 bytes tests/auto/qaudiooutput/qaudiooutput.pro | 12 + tests/auto/qaudiooutput/tst_qaudiooutput.cpp | 156 ++++ tests/auto/tests.xml | 8 + tools/configure/configureapp.cpp | 15 + 88 files changed, 12950 insertions(+), 2 deletions(-) create mode 100644 config.tests/unix/alsa/alsa.pro create mode 100644 config.tests/unix/alsa/alsatest.cpp create mode 100644 doc/src/examples/audiodevices.qdoc create mode 100644 doc/src/examples/audioinput.qdoc create mode 100644 doc/src/examples/audiooutput.qdoc create mode 100644 examples/multimedia/README create mode 100644 examples/multimedia/audio/audio.pro create mode 100644 examples/multimedia/audio/audiodevices/audiodevices.cpp create mode 100644 examples/multimedia/audio/audiodevices/audiodevices.h create mode 100644 examples/multimedia/audio/audiodevices/audiodevices.pro create mode 100644 examples/multimedia/audio/audiodevices/audiodevicesbase.ui create mode 100644 examples/multimedia/audio/audiodevices/main.cpp create mode 100644 examples/multimedia/audio/audioinput/audioinput.cpp create mode 100644 examples/multimedia/audio/audioinput/audioinput.h create mode 100644 examples/multimedia/audio/audioinput/audioinput.pro create mode 100644 examples/multimedia/audio/audioinput/main.cpp create mode 100644 examples/multimedia/audio/audiooutput/audiooutput.cpp create mode 100644 examples/multimedia/audio/audiooutput/audiooutput.h create mode 100644 examples/multimedia/audio/audiooutput/audiooutput.pro create mode 100644 examples/multimedia/audio/audiooutput/main.cpp create mode 100644 examples/multimedia/multimedia.pro create mode 100644 src/multimedia/audio/audio.pri create mode 100644 src/multimedia/audio/qaudio.cpp create mode 100644 src/multimedia/audio/qaudio.h create mode 100644 src/multimedia/audio/qaudio_mac.cpp create mode 100644 src/multimedia/audio/qaudio_mac_p.h create mode 100644 src/multimedia/audio/qaudiodevicefactory.cpp create mode 100644 src/multimedia/audio/qaudiodevicefactory_p.h create mode 100644 src/multimedia/audio/qaudiodeviceid.cpp create mode 100644 src/multimedia/audio/qaudiodeviceid.h create mode 100644 src/multimedia/audio/qaudiodeviceid_p.h create mode 100644 src/multimedia/audio/qaudiodeviceinfo.cpp create mode 100644 src/multimedia/audio/qaudiodeviceinfo.h create mode 100644 src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp create mode 100644 src/multimedia/audio/qaudiodeviceinfo_alsa_p.h create mode 100644 src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp create mode 100644 src/multimedia/audio/qaudiodeviceinfo_mac_p.h create mode 100644 src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp create mode 100644 src/multimedia/audio/qaudiodeviceinfo_win32_p.h create mode 100644 src/multimedia/audio/qaudioengine.cpp create mode 100644 src/multimedia/audio/qaudioengine.h create mode 100644 src/multimedia/audio/qaudioengineplugin.cpp create mode 100644 src/multimedia/audio/qaudioengineplugin.h create mode 100644 src/multimedia/audio/qaudioformat.cpp create mode 100644 src/multimedia/audio/qaudioformat.h create mode 100644 src/multimedia/audio/qaudioinput.cpp create mode 100644 src/multimedia/audio/qaudioinput.h create mode 100644 src/multimedia/audio/qaudioinput_alsa_p.cpp create mode 100644 src/multimedia/audio/qaudioinput_alsa_p.h create mode 100644 src/multimedia/audio/qaudioinput_mac_p.cpp create mode 100644 src/multimedia/audio/qaudioinput_mac_p.h create mode 100644 src/multimedia/audio/qaudioinput_win32_p.cpp create mode 100644 src/multimedia/audio/qaudioinput_win32_p.h create mode 100644 src/multimedia/audio/qaudiooutput.cpp create mode 100644 src/multimedia/audio/qaudiooutput.h create mode 100644 src/multimedia/audio/qaudiooutput_alsa_p.cpp create mode 100644 src/multimedia/audio/qaudiooutput_alsa_p.h create mode 100644 src/multimedia/audio/qaudiooutput_mac_p.cpp create mode 100644 src/multimedia/audio/qaudiooutput_mac_p.h create mode 100644 src/multimedia/audio/qaudiooutput_win32_p.cpp create mode 100644 src/multimedia/audio/qaudiooutput_win32_p.h create mode 100644 src/multimedia/multimedia.pro create mode 100644 src/plugins/audio/audio.pro create mode 100644 tests/auto/qaudiodeviceid/qaudiodeviceid.pro create mode 100644 tests/auto/qaudiodeviceid/tst_qaudiodeviceid.cpp create mode 100644 tests/auto/qaudiodeviceinfo/qaudiodeviceinfo.pro create mode 100644 tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp create mode 100644 tests/auto/qaudioformat/qaudioformat.pro create mode 100644 tests/auto/qaudioformat/tst_qaudioformat.cpp create mode 100644 tests/auto/qaudioinput/qaudioinput.pro create mode 100644 tests/auto/qaudioinput/tst_qaudioinput.cpp create mode 100644 tests/auto/qaudiooutput/4.wav create mode 100644 tests/auto/qaudiooutput/qaudiooutput.pro create mode 100644 tests/auto/qaudiooutput/tst_qaudiooutput.cpp diff --git a/bin/syncqt b/bin/syncqt index 6c4de6a..589659f 100755 --- a/bin/syncqt +++ b/bin/syncqt @@ -43,6 +43,7 @@ my %modules = ( # path to module name map "QtDBus" => "$basedir/src/dbus", "QtWebKit" => "$basedir/src/3rdparty/webkit/WebCore", "phonon" => "$basedir/src/phonon", + "QtMultimedia" => "$basedir/src/multimedia", ); my %moduleheaders = ( # restrict the module headers to those found in relative path "QtWebKit" => "../WebKit/qt/Api", diff --git a/config.tests/unix/alsa/alsa.pro b/config.tests/unix/alsa/alsa.pro new file mode 100644 index 0000000..4931d38 --- /dev/null +++ b/config.tests/unix/alsa/alsa.pro @@ -0,0 +1,4 @@ +SOURCES = alsatest.cpp +LIBS+=-lasound +CONFIG -= qt dylib +mac:CONFIG -= app_bundle diff --git a/config.tests/unix/alsa/alsatest.cpp b/config.tests/unix/alsa/alsatest.cpp new file mode 100644 index 0000000..af2f5d9 --- /dev/null +++ b/config.tests/unix/alsa/alsatest.cpp @@ -0,0 +1,6 @@ +#include +int main(int argc,char **argv) +{ + return 0; +} + diff --git a/configure b/configure index 095d040..1d1f826 100755 --- a/configure +++ b/configure @@ -609,6 +609,7 @@ CFG_NOBUILD_PARTS="" CFG_RELEASE_QMAKE=no CFG_PHONON=auto CFG_PHONON_BACKEND=yes +CFG_MULTIMEDIA=yes CFG_SVG=yes CFG_WEBKIT=auto # (yes|no|auto) @@ -709,6 +710,7 @@ OPT_VERBOSE=no OPT_HELP= CFG_SILENT=no CFG_GRAPHICS_SYSTEM=default +CFG_ALSA=auto # initalize variables used for installation QT_INSTALL_PREFIX= @@ -848,7 +850,7 @@ while [ "$#" -gt 0 ]; do VAL=no ;; #Qt style yes options - -incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xshape|-xinput|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-universal|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-svg|-webkit|-scripttools|-rpath|-force-pkg-config) + -incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xshape|-xinput|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-universal|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-svg|-webkit|-scripttools|-rpath|-force-pkg-config) VAR=`echo $1 | sed "s,^-\(.*\),\1,"` VAL=yes ;; @@ -1976,6 +1978,13 @@ while [ "$#" -gt 0 ]; do UNKNOWN_OPT=yes fi ;; + multimedia) + if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then + CFG_MULTIMEDIA="$VAL" + else + UNKNOWN_OPT=yes + fi + ;; *) UNKNOWN_OPT=yes ;; @@ -3152,6 +3161,7 @@ Usage: $relconf [-h] [-prefix ] [-prefix-install] [-bindir ] [-libdir [-no-optimized-qmake] [-optimized-qmake] [-no-xmlpatterns] [-xmlpatterns] [-no-phonon] [-phonon] [-no-phonon-backend] [-phonon-backend] [-no-openssl] [-openssl] [-openssl-linked] + [-no-multimedia] [-multimedia] [-no-gtkstyle] [-gtkstyle] [-no-svg] [-svg] [-no-webkit] [-webkit] [-no-scripttools] [-scripttools] @@ -3292,6 +3302,9 @@ fi -no-phonon-backend.. Do not build the platform phonon plugin. + -phonon-backend..... Build the platform phonon plugin. + -no-multimedia ..... Do not build the multimedia module. + * -multimedia ........ Build the multimedia module. + -no-svg ............ Do not build the SVG module. + -svg ............... Build the SVG module. @@ -5664,6 +5677,14 @@ if [ "$CFG_PTMALLOC" != "no" ]; then QMakeVar add QMAKE_LFLAGS "$outpath/lib/libptmalloc3.a" fi +if [ "$CFG_ALSA" = "auto" ]; then + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/alsa "alsa" $L_FLAGS $I_FLAGS $l_FLAGS; then + CFG_ALSA=yes + else + CFG_ALSA=no + fi +fi + #------------------------------------------------------------------------------- # ask for all that hasn't been auto-detected or specified in the arguments #------------------------------------------------------------------------------- @@ -6104,6 +6125,10 @@ if [ "$CFG_EXCEPTIONS" != "no" ]; then QTCONFIG_CONFIG="$QTCONFIG_CONFIG exceptions" fi +if [ "$CFG_ALSA" = "yes" ]; then + QT_CONFIG="$QT_CONFIG alsa" +fi + # # Some Qt modules are too advanced in C++ for some old compilers # Detect here the platforms where they are known to work. @@ -6275,6 +6300,12 @@ else QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_SCRIPTTOOLS" fi +if [ "$CFG_MULTIMEDIA" = "yes" ]; then + QT_CONFIG="$QT_CONFIG multimedia" +else + QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_MULTIMEDIA" +fi + if [ "$CFG_EXCEPTIONS" = "no" ]; then case "$COMPILER" in g++*) @@ -6776,6 +6807,7 @@ fi [ "$CFG_XFIXES" = "runtime" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_RUNTIME_XFIXES" [ "$CFG_XRANDR" = "runtime" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_RUNTIME_XRANDR" [ "$CFG_XINPUT" = "runtime" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_RUNTIME_XINPUT" +[ "$CFG_ALSA" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_ALSA" # sort QCONFIG_FLAGS for neatness if we can [ '!' -z "$AWK" ] && QCONFIG_FLAGS=`echo $QCONFIG_FLAGS | $AWK '{ gsub(" ", "\n"); print }' | sort | uniq` @@ -7135,6 +7167,7 @@ echo "QtConcurrent code.... $CFG_CONCURRENT" echo "QtScriptTools module $CFG_SCRIPTTOOLS" echo "QtXmlPatterns module $CFG_XMLPATTERNS" echo "Phonon module ....... $CFG_PHONON" +echo "Multimedia module ... $CFG_MULTIMEDIA" echo "SVG module .......... $CFG_SVG" echo "WebKit module ....... $CFG_WEBKIT" echo "STL support ......... $CFG_STL" @@ -7285,6 +7318,7 @@ if [ "$PLATFORM_MAC" = "yes" ] && [ "$CFG_FRAMEWORK" = "yes" ] && [ "$CFG_DEBUG" echo "NOTE: Mac OS X frameworks implicitly build debug and release Qt libraries." echo fi +echo "alsa support ........ $CFG_ALSA" echo sepath=`echo "$relpath" | sed -e 's/\\./\\\\./g'` diff --git a/configure.exe b/configure.exe index 322819e..cf5885a 100644 Binary files a/configure.exe and b/configure.exe differ diff --git a/demos/qtdemo/xml/examples.xml b/demos/qtdemo/xml/examples.xml index 006bfd0..1b0b533 100644 --- a/demos/qtdemo/xml/examples.xml +++ b/demos/qtdemo/xml/examples.xml @@ -154,6 +154,11 @@ + + + + + diff --git a/doc/src/examples-overview.qdoc b/doc/src/examples-overview.qdoc index 4313c43..3db4a45 100644 --- a/doc/src/examples-overview.qdoc +++ b/doc/src/examples-overview.qdoc @@ -238,6 +238,17 @@ These examples demonstrate the basic techniques used to take advantage of OpenGL in Qt applications. + \section1 \l{Qt Examples#Multimedia}{Multimedia} + + \l{Qt Examples#Multimedia} + + Qt provides low-level audio support on linux,windows and mac platforms by default and + an audio plugin API to allow developers to implement there own audio support for + custom devices and platforms. + + These examples demonstrate the basic techniques used to take advantage of + Audio API in Qt applications. + \section1 \l{Qt Examples#SQL}{SQL} \l{Qt Examples#SQL}{\inlineimage sql-examples.png diff --git a/doc/src/examples.qdoc b/doc/src/examples.qdoc index e85acd1..74a9bd8 100644 --- a/doc/src/examples.qdoc +++ b/doc/src/examples.qdoc @@ -255,6 +255,14 @@ \o \l{phonon/musicplayer}{Music Player}\raisedaster \endlist + \section1 Multimedia + + \list + \o \l{multimedia/audio/audiodevices}{Audio Devices}\raisedaster + \o \l{multimedia/audio/audiooutput}{Audio Output}\raisedaster + \o \l{multimedia/audio/audioinput}{Audio Input}\raisedaster + \endlist + \section1 Qt Designer \list diff --git a/doc/src/examples/audiodevices.qdoc b/doc/src/examples/audiodevices.qdoc new file mode 100644 index 0000000..3b8cdd8 --- /dev/null +++ b/doc/src/examples/audiodevices.qdoc @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example multimedia/audio/audiodevices + \title Audio Devices Example + + The Audio Devices example demonstrates the basic use of QAudioDeviceInfo class + provided with Qt. + + Qt provides the QAudioDeviceInfo class to enable audio querying within + a standard application user interface. + + This example allows you to browse audio devices available and try out different + configurations to see if they are supported. +*/ diff --git a/doc/src/examples/audioinput.qdoc b/doc/src/examples/audioinput.qdoc new file mode 100644 index 0000000..5dfe76e --- /dev/null +++ b/doc/src/examples/audioinput.qdoc @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example multimedia/audio/audioinput + \title AudioInput Example + + The Audio Input example demonstrates the basic use of QAudioInput class + provided with Qt. + + Qt provides the QAudioInput class to enable audio functionality within + a standard application user interface. + + This example uses a fast-fourier transform on the input audio from the microphone + and displays the output. +*/ diff --git a/doc/src/examples/audiooutput.qdoc b/doc/src/examples/audiooutput.qdoc new file mode 100644 index 0000000..9c8a75f --- /dev/null +++ b/doc/src/examples/audiooutput.qdoc @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example multimedia/audio/audiooutput + \title Audio Output Example + + The Audio Output example demonstrates the basic use of the QAudioOutput class + provided with Qt. + + This example provides a tone generator to supply continuous audio playback. + The first button allows pause and resume of the playback. + The second button allows toggling between push and pull modes of operation. +*/ diff --git a/examples/examples.pro b/examples/examples.pro index 5855e4f..e6cece9 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -26,6 +26,7 @@ SUBDIRS = \ multitouch \ gestures +contains(QT_CONFIG, multimedia):!static: SUBDIRS += multimedia contains(QT_CONFIG, phonon):!static: SUBDIRS += phonon contains(QT_CONFIG, webkit): SUBDIRS += webkit embedded:SUBDIRS += qws diff --git a/examples/multimedia/README b/examples/multimedia/README new file mode 100644 index 0000000..aa78e36 --- /dev/null +++ b/examples/multimedia/README @@ -0,0 +1,34 @@ + +The example launcher provided with Qt can be used to explore each of the +examples in this directory. + +Documentation for these examples can be found via the Tutorial and Examples +link in the main Qt documentation. + + +Finding the Qt Examples and Demos launcher +========================================== + +On Windows: + +The launcher can be accessed via the Windows Start menu. Select the menu +entry entitled "Qt Examples and Demos" entry in the submenu containing +the Qt tools. + +On Mac OS X: + +For the binary distribution, the qtdemo executable is installed in the +/Developer/Applications/Qt directory. For the source distribution, it is +installed alongside the other Qt tools on the path specified when Qt is +configured. + +On Unix/Linux: + +The qtdemo executable is installed alongside the other Qt tools on the path +specified when Qt is configured. + +On all platforms: + +The source code for the launcher can be found in the demos/qtdemo directory +in the Qt package. This example is built at the same time as the Qt libraries, +tools, examples, and demonstrations. diff --git a/examples/multimedia/audio/audio.pro b/examples/multimedia/audio/audio.pro new file mode 100644 index 0000000..c64bb34 --- /dev/null +++ b/examples/multimedia/audio/audio.pro @@ -0,0 +1,10 @@ +TEMPLATE = subdirs +SUBDIRS = audioinput \ + audiooutput \ + audiodevices + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/audio +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS audio.pro README +sources.path = $$[QT_INSTALL_EXAMPLES]/multimedia/audio +INSTALLS += target sources diff --git a/examples/multimedia/audio/audiodevices/audiodevices.cpp b/examples/multimedia/audio/audiodevices/audiodevices.cpp new file mode 100644 index 0000000..2a3af98 --- /dev/null +++ b/examples/multimedia/audio/audiodevices/audiodevices.cpp @@ -0,0 +1,272 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include + +#include "audiodevices.h" + +AudioDevicesBase::AudioDevicesBase( QMainWindow *parent, Qt::WFlags f ) +{ + Q_UNUSED(parent) + Q_UNUSED(f) + setupUi( this ); +} + +AudioDevicesBase::~AudioDevicesBase() {} + + +AudioTest::AudioTest( QMainWindow *parent, Qt::WFlags f ) + : AudioDevicesBase( parent, f ) +{ + mode = QAudio::AudioOutput; + modeBox->addItem("Input"); + modeBox->addItem("Output"); + + connect(testButton,SIGNAL(clicked()),SLOT(test())); + connect(modeBox,SIGNAL(activated(int)),SLOT(modeChanged(int))); + connect(deviceBox,SIGNAL(activated(int)),SLOT(deviceChanged(int))); + connect(frequencyBox,SIGNAL(activated(int)),SLOT(freqChanged(int))); + connect(channelsBox,SIGNAL(activated(int)),SLOT(channelChanged(int))); + connect(codecsBox,SIGNAL(activated(int)),SLOT(codecChanged(int))); + connect(sampleSizesBox,SIGNAL(activated(int)),SLOT(sampleSizeChanged(int))); + connect(sampleTypesBox,SIGNAL(activated(int)),SLOT(sampleTypeChanged(int))); + connect(endianBox,SIGNAL(activated(int)),SLOT(endianChanged(int))); + + device = 0; + + modeBox->setCurrentIndex(0); + modeChanged(0); + deviceBox->setCurrentIndex(0); + deviceChanged(0); +} + +AudioTest::~AudioTest() +{ +} + +void AudioTest::test() +{ + // tries to set all the settings picked. + + if(device) { + if(device->isFormatSupported(settings)) { + logOutput->append("Success"); + nearestFreq->setText(""); + nearestChannel->setText(""); + nearestCodec->setText(""); + nearestSampleSize->setText(""); + nearestSampleType->setText(""); + nearestEndian->setText(""); + } else { + QAudioFormat nearest = device->nearestFormat(settings); + logOutput->append(tr("Failed")); + nearestFreq->setText(QString("%1").arg(nearest.frequency())); + nearestChannel->setText(QString("%1").arg(nearest.channels())); + nearestCodec->setText(nearest.codec()); + nearestSampleSize->setText(QString("%1").arg(nearest.sampleSize())); + + switch(nearest.sampleType()) { + case QAudioFormat::SignedInt: + nearestSampleType->setText("SignedInt"); + break; + case QAudioFormat::UnSignedInt: + nearestSampleType->setText("UnSignedInt"); + break; + case QAudioFormat::Float: + nearestSampleType->setText("Float"); + break; + case QAudioFormat::Unknown: + nearestSampleType->setText("Unknown"); + } + switch(nearest.byteOrder()) { + case QAudioFormat::LittleEndian: + nearestEndian->setText("LittleEndian"); + break; + case QAudioFormat::BigEndian: + nearestEndian->setText("BigEndian"); + } + } + } + else + logOutput->append("No Device"); +} + +void AudioTest::modeChanged(int idx) +{ + // mode has changed + if(idx == 0) + mode=QAudio::AudioInput; + else + mode=QAudio::AudioOutput; + + deviceBox->clear(); + QList devices = QAudioDeviceInfo::deviceList(mode); + for(int i = 0; i < devices.size(); ++i) { + deviceBox->addItem(QAudioDeviceInfo(devices.at(i)).deviceName(), qVariantFromValue(devices.at(i))); + } +} + +void AudioTest::deviceChanged(int idx) +{ + delete device; + device = 0; + + if (deviceBox->count() == 0) + return; + + // device has changed + deviceHandle = deviceBox->itemData(idx).value(); + device = new QAudioDeviceInfo(deviceHandle, this); + + frequencyBox->clear(); + QList freqz = device->supportedFrequencies(); + for(int i = 0; i < freqz.size(); ++i) + frequencyBox->addItem(QString("%1").arg(freqz.at(i))); + if(freqz.size()) + settings.setFrequency(freqz.at(0)); + + channelsBox->clear(); + QList chz = device->supportedChannels(); + for(int i = 0; i < chz.size(); ++i) + channelsBox->addItem(QString("%1").arg(chz.at(i))); + if(chz.size()) + settings.setChannels(chz.at(0)); + + codecsBox->clear(); + QStringList codecz = device->supportedCodecs(); + for(int i = 0; i < codecz.size(); ++i) + codecsBox->addItem(QString("%1").arg(codecz.at(i))); + if(codecz.size()) + settings.setCodec(codecz.at(0)); + // Add false to create failed condition! + codecsBox->addItem("audio/mpeg"); + + sampleSizesBox->clear(); + QList sampleSizez = device->supportedSampleSizes(); + for(int i = 0; i < sampleSizez.size(); ++i) + sampleSizesBox->addItem(QString("%1").arg(sampleSizez.at(i))); + if(sampleSizez.size()) + settings.setSampleSize(sampleSizez.at(0)); + + sampleTypesBox->clear(); + QList sampleTypez = device->supportedSampleTypes(); + for(int i = 0; i < sampleTypez.size(); ++i) { + switch(sampleTypez.at(i)) { + case QAudioFormat::SignedInt: + sampleTypesBox->addItem("SignedInt"); + break; + case QAudioFormat::UnSignedInt: + sampleTypesBox->addItem("UnSignedInt"); + break; + case QAudioFormat::Float: + sampleTypesBox->addItem("Float"); + break; + case QAudioFormat::Unknown: + sampleTypesBox->addItem("Unknown"); + } + if(sampleTypez.size()) + settings.setSampleType(sampleTypez.at(0)); + } + + endianBox->clear(); + QList endianz = device->supportedByteOrders(); + for(int i = 0; i < endianz.size(); ++i) { + switch(endianz.at(i)) { + case QAudioFormat::LittleEndian: + endianBox->addItem("Little Endian"); + break; + case QAudioFormat::BigEndian: + endianBox->addItem("Big Endian"); + break; + } + } + if(endianz.size()) + settings.setByteOrder(endianz.at(0)); +} + +void AudioTest::freqChanged(int idx) +{ + // freq has changed + settings.setFrequency(frequencyBox->itemText(idx).toInt()); +} + +void AudioTest::channelChanged(int idx) +{ + settings.setChannels(channelsBox->itemText(idx).toInt()); +} + +void AudioTest::codecChanged(int idx) +{ + settings.setCodec(codecsBox->itemText(idx)); +} + +void AudioTest::sampleSizeChanged(int idx) +{ + settings.setSampleSize(sampleSizesBox->itemText(idx).toInt()); +} + +void AudioTest::sampleTypeChanged(int idx) +{ + switch(sampleTypesBox->itemText(idx).toInt()) { + case QAudioFormat::SignedInt: + settings.setSampleType(QAudioFormat::SignedInt); + break; + case QAudioFormat::UnSignedInt: + settings.setSampleType(QAudioFormat::UnSignedInt); + break; + case QAudioFormat::Float: + settings.setSampleType(QAudioFormat::Float); + } +} + +void AudioTest::endianChanged(int idx) +{ + switch(endianBox->itemText(idx).toInt()) { + case QAudioFormat::LittleEndian: + settings.setByteOrder(QAudioFormat::LittleEndian); + break; + case QAudioFormat::BigEndian: + settings.setByteOrder(QAudioFormat::BigEndian); + } +} + diff --git a/examples/multimedia/audio/audiodevices/audiodevices.h b/examples/multimedia/audio/audiodevices/audiodevices.h new file mode 100644 index 0000000..34a531b --- /dev/null +++ b/examples/multimedia/audio/audiodevices/audiodevices.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include +#include + +#include "ui_audiodevicesbase.h" + +class AudioDevicesBase : public QMainWindow, public Ui::AudioDevicesBase +{ +public: + AudioDevicesBase( QMainWindow *parent = 0, Qt::WFlags f = 0 ); + virtual ~AudioDevicesBase(); +}; + +class AudioTest : public AudioDevicesBase +{ + Q_OBJECT +public: + AudioTest( QMainWindow *parent = 0, Qt::WFlags f = 0 ); + virtual ~AudioTest(); + + QAudioDeviceId deviceHandle; + QAudioDeviceInfo* device; + QAudioFormat settings; + QAudio::Mode mode; + +private slots: + void modeChanged(int idx); + void deviceChanged(int idx); + void freqChanged(int idx); + void channelChanged(int idx); + void codecChanged(int idx); + void sampleSizeChanged(int idx); + void sampleTypeChanged(int idx); + void endianChanged(int idx); + void test(); +}; + diff --git a/examples/multimedia/audio/audiodevices/audiodevices.pro b/examples/multimedia/audio/audiodevices/audiodevices.pro new file mode 100644 index 0000000..adc4890 --- /dev/null +++ b/examples/multimedia/audio/audiodevices/audiodevices.pro @@ -0,0 +1,12 @@ +HEADERS = audiodevices.h +SOURCES = audiodevices.cpp \ + main.cpp +FORMS += audiodevicesbase.ui + +QT += multimedia + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/audio/audiodevices +sources.files = $$SOURCES *.h $$RESOURCES $$FORMS audiodevices.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/multimedia/audio/audiodevices +INSTALLS += target sources diff --git a/examples/multimedia/audio/audiodevices/audiodevicesbase.ui b/examples/multimedia/audio/audiodevices/audiodevicesbase.ui new file mode 100644 index 0000000..674f201 --- /dev/null +++ b/examples/multimedia/audio/audiodevices/audiodevicesbase.ui @@ -0,0 +1,255 @@ + + AudioDevicesBase + + + + 0 + 0 + 504 + 702 + + + + AudioDevicesBase + + + + + 0 + 28 + 504 + 653 + + + + + + 40 + 21 + 321 + 506 + + + + + + + + 1 + 0 + + + + Device + + + + + + + Mode + + + + + + + + + + + + + QFrame::Panel + + + QFrame::Raised + + + Actual Settings + + + Qt::AlignCenter + + + + + + + QFrame::Panel + + + QFrame::Raised + + + Nearest Settings + + + Qt::AlignCenter + + + + + + + Frequency + + + + + + + Frequency + + + + + + + + + + + + + Channels + + + + + + + Channel + + + + + + + + + + + + + Codecs + + + + + + + Codec + + + + + + + + + + + + + SampleSize + + + + + + + SampleSize + + + + + + + + + + + + + SampleType + + + + + + + SampleType + + + + + + + + + + + + + Endianess + + + + + + + Endianess + + + + + + + + + + + + + + 0 + 40 + + + + + + + + Test + + + + + + + + + + 0 + 0 + 504 + 28 + + + + + + + 0 + 681 + 504 + 21 + + + + + + + diff --git a/examples/multimedia/audio/audiodevices/main.cpp b/examples/multimedia/audio/audiodevices/main.cpp new file mode 100644 index 0000000..12e413e --- /dev/null +++ b/examples/multimedia/audio/audiodevices/main.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "audiodevices.h" + +int main(int argv, char **args) +{ + QApplication app(argv, args); + app.setApplicationName("Audio Device Test"); + + AudioTest audio; + audio.show(); + + return app.exec(); +} diff --git a/examples/multimedia/audio/audioinput/audioinput.cpp b/examples/multimedia/audio/audioinput/audioinput.cpp new file mode 100644 index 0000000..ae7d84c --- /dev/null +++ b/examples/multimedia/audio/audioinput/audioinput.cpp @@ -0,0 +1,376 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include +#include +#include "audioinput.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +Spectrum::Spectrum(QObject* parent, QAudioInput* device, float* out) + :QIODevice( parent ) +{ + input = device; + output = out; + + unsigned int i; + + // Allocate sample buffer and initialize sin and cos lookup tables + fftState = (fft_state *) malloc (sizeof(fft_state)); + + for(i = 0; i < BUFFER_SIZE; i++) { + bitReverse[i] = reverseBits(i); + } + for(i = 0; i < BUFFER_SIZE / 2; i++) { + float j = 2 * M_PI * i / BUFFER_SIZE; + costable[i] = cos(j); + sintable[i] = sin(j); + } +} + +Spectrum::~Spectrum() +{ +} + +void Spectrum::start() +{ + open(QIODevice::WriteOnly); +} + +void Spectrum::stop() +{ + close(); +} + +qint64 Spectrum::readData(char *data, qint64 maxlen) +{ + Q_UNUSED(data) + Q_UNUSED(maxlen) + + return 0; +} + +qint64 Spectrum::writeData(const char *data, qint64 len) +{ + performFFT((sound_sample*)data); + emit update(); + + return len; +} + +int Spectrum::reverseBits(unsigned int initial) { + // BIT-REVERSE-COPY(a,A) + + unsigned int reversed = 0, loop; + for(loop = 0; loop < BUFFER_SIZE_LOG; loop++) { + reversed <<= 1; + reversed += (initial & 1); + initial >>= 1; + } + return reversed; +} + +void Spectrum::performFFT(const sound_sample *input) { + /* Convert to reverse bit order for FFT */ + prepFFT(input, fftState->real, fftState->imag); + + /* Calculate FFT */ + calcFFT(fftState->real, fftState->imag); + + /* Convert FFT to intensities */ + outputFFT(fftState->real, fftState->imag); +} + +void Spectrum::prepFFT(const sound_sample *input, float * re, float * im) { + unsigned int i; + float *realptr = re; + float *imagptr = im; + + /* Get input, in reverse bit order */ + for(i = 0; i < BUFFER_SIZE; i++) { + *realptr++ = input[bitReverse[i]]; + *imagptr++ = 0; + } +} + +void Spectrum::calcFFT(float * re, float * im) { + unsigned int i, j, k; + unsigned int exchanges; + float fact_real, fact_imag; + float tmp_real, tmp_imag; + unsigned int factfact; + + /* Set up some variables to reduce calculation in the loops */ + exchanges = 1; + factfact = BUFFER_SIZE / 2; + + /* divide and conquer method */ + for(i = BUFFER_SIZE_LOG; i != 0; i--) { + for(j = 0; j != exchanges; j++) { + fact_real = costable[j * factfact]; + fact_imag = sintable[j * factfact]; + for(k = j; k < BUFFER_SIZE; k += exchanges << 1) { + int k1 = k + exchanges; + tmp_real = fact_real * re[k1] - fact_imag * im[k1]; + tmp_imag = fact_real * im[k1] + fact_imag * re[k1]; + re[k1] = re[k] - tmp_real; + im[k1] = im[k] - tmp_imag; + re[k] += tmp_real; + im[k] += tmp_imag; + } + } + exchanges <<= 1; + factfact >>= 1; + } +} + +void Spectrum::outputFFT(const float * re, const float * im) { + const float *realptr = re; + const float *imagptr = im; + float *outputptr = output; + + float *endptr = output + BUFFER_SIZE / 2; + + /* Convert FFT to intensities */ + + while(outputptr <= endptr) { + *outputptr = (*realptr * *realptr) + (*imagptr * *imagptr); + outputptr++; realptr++; imagptr++; + } + *output /= 4; + *endptr /= 4; +} + + +RenderArea::RenderArea(QWidget *parent) + : QWidget(parent) +{ + setBackgroundRole(QPalette::Base); + setAutoFillBackground(true); + + samples = 0; + sampleSize = 0; + setMinimumHeight(30); + setMinimumWidth(200); +} + +void RenderArea::paintEvent(QPaintEvent * /* event */) +{ + QPainter painter(this); + + if(sampleSize == 0) + return; + + painter.setPen(Qt::red); + int max = 0; + for(int i=0;i max) + max = m; + } + int x1,y1,x2,y2; + + for(int i=0;i<10;i++) { + x1 = painter.viewport().left()+11; + y1 = painter.viewport().top()+10+i; + x2 = painter.viewport().right()-20-max; + y2 = painter.viewport().top()+10+i; + if(x2 < painter.viewport().left()+10) + x2 = painter.viewport().left()+10; + + painter.drawLine(QPoint(x1,y1),QPoint(x2,y2)); + } + + painter.setPen(Qt::black); + painter.drawRect(QRect(painter.viewport().left()+10, painter.viewport().top()+10, + painter.viewport().right()-20, painter.viewport().bottom()-20)); +} + +void RenderArea::spectrum(float* output, int size) +{ + samples = output; + sampleSize = size; + repaint(); +} + + +InputTest::InputTest() +{ + QWidget *window = new QWidget; + QVBoxLayout* layout = new QVBoxLayout; + + canvas = new RenderArea; + layout->addWidget(canvas); + + deviceBox = new QComboBox(this); + QList devices = QAudioDeviceInfo::deviceList(QAudio::AudioInput); + for(int i = 0; i < devices.size(); ++i) { + deviceBox->addItem(QAudioDeviceInfo(devices.at(i)).deviceName(), qVariantFromValue(devices.at(i))); + } + connect(deviceBox,SIGNAL(activated(int)),SLOT(deviceChanged(int))); + layout->addWidget(deviceBox); + + button = new QPushButton(this); + button->setText(tr("Click for Push Mode")); + connect(button,SIGNAL(clicked()),SLOT(toggleMode())); + layout->addWidget(button); + + button2 = new QPushButton(this); + button2->setText(tr("Click To Suspend")); + connect(button2,SIGNAL(clicked()),SLOT(toggleSuspend())); + layout->addWidget(button2); + + window->setLayout(layout); + setCentralWidget(window); + window->show(); + + buffer = new char[BUFFER_SIZE*10]; + output = new float[1024]; + + pullMode = true; + + format.setFrequency(8000); + format.setChannels(1); + format.setSampleSize(8); + format.setSampleType(QAudioFormat::UnSignedInt); + format.setByteOrder(QAudioFormat::LittleEndian); + format.setCodec("audio/pcm"); + + audioInput = new QAudioInput(format,this); + connect(audioInput,SIGNAL(notify()),SLOT(status())); + connect(audioInput,SIGNAL(stateChanged(QAudio::State)),SLOT(state(QAudio::State))); + spec = new Spectrum(this,audioInput,output); + connect(spec,SIGNAL(update()),SLOT(refreshDisplay())); + spec->start(); + audioInput->start(spec); +} + +InputTest::~InputTest() {} + +void InputTest::status() +{ + qWarning()<<"bytesReady = "<bytesReady()<<" bytes, clock = "<clock()<<"ms, totalTime = "<totalTime()/1000<<"ms"; +} + +void InputTest::readMore() +{ + if(!audioInput) + return; + qint64 len = audioInput->bytesReady(); + if(len > BUFFER_SIZE*10) + len = BUFFER_SIZE*10; + qint64 l = input->read(buffer,len); + if(l > 0) { + spec->write(buffer,l); + } +} + +void InputTest::toggleMode() +{ + // Change bewteen pull and push modes + audioInput->stop(); + + if(pullMode) { + button->setText(tr("Click for Push Mode")); + input = audioInput->start(0); + connect(input,SIGNAL(readyRead()),SLOT(readMore())); + pullMode = false; + } else { + button->setText(tr("Click for Pull Mode")); + pullMode = true; + audioInput->start(spec); + } +} + +void InputTest::toggleSuspend() +{ + // toggle suspend/resume + if(audioInput->state() == QAudio::SuspendState) { + qWarning()<<"status: Suspended, resume()"; + audioInput->resume(); + button2->setText("Click To Suspend"); + } else if (audioInput->state() == QAudio::ActiveState) { + qWarning()<<"status: Active, suspend()"; + audioInput->suspend(); + button2->setText("Click To Resume"); + } else if (audioInput->state() == QAudio::StopState) { + qWarning()<<"status: Stopped, resume()"; + audioInput->resume(); + button2->setText("Click To Suspend"); + } else if (audioInput->state() == QAudio::IdleState) { + qWarning()<<"status: IdleState"; + } +} + +void InputTest::state(QAudio::State state) +{ + qWarning()<<" state="<spectrum(output,256); + canvas->repaint(); +} + +void InputTest::deviceChanged(int idx) +{ + spec->stop(); + audioInput->stop(); + audioInput->disconnect(this); + delete audioInput; + + device = deviceBox->itemData(idx).value(); + audioInput = new QAudioInput(device, format, this); + connect(audioInput,SIGNAL(notify()),SLOT(status())); + connect(audioInput,SIGNAL(stateChanged(QAudio::State)),SLOT(state(QAudio::State))); + spec->start(); + audioInput->start(spec); +} diff --git a/examples/multimedia/audio/audioinput/audioinput.h b/examples/multimedia/audio/audioinput/audioinput.h new file mode 100644 index 0000000..3a6b356 --- /dev/null +++ b/examples/multimedia/audio/audioinput/audioinput.h @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include + +#define BUFFER_SIZE_LOG 9 +#define BUFFER_SIZE (1 << BUFFER_SIZE_LOG) + +struct _struct_fft_state { + float real[BUFFER_SIZE]; + float imag[BUFFER_SIZE]; +}; +typedef _struct_fft_state fft_state; +typedef short int sound_sample; + +class Spectrum : public QIODevice +{ + Q_OBJECT +public: + Spectrum(QObject* parent, QAudioInput* device, float* out); + ~Spectrum(); + + void start(); + void stop(); + + qint64 readData(char *data, qint64 maxlen); + qint64 writeData(const char *data, qint64 len); + + QAudioInput* input; + float* output; + fft_state* fftState; + + unsigned int bitReverse[BUFFER_SIZE]; + float sintable[BUFFER_SIZE / 2]; + float costable[BUFFER_SIZE / 2]; + + void prepFFT (const sound_sample *input, float *re, float *im); + void calcFFT (float *re, float *im); + void outputFFT (const float *re, const float *im); + int reverseBits (unsigned int initial); + void performFFT (const sound_sample *input); + +signals: + void update(); +}; + + +class RenderArea : public QWidget +{ + Q_OBJECT + +public: + RenderArea(QWidget *parent = 0); + + void spectrum(float* output, int size); + +protected: + void paintEvent(QPaintEvent *event); + +private: + QPixmap pixmap; + + float* samples; + int sampleSize; +}; + +class InputTest : public QMainWindow +{ + Q_OBJECT +public: + InputTest(); + ~InputTest(); + + QAudioDeviceId device; + QAudioFormat format; + QAudioInput* audioInput; + Spectrum* spec; + QIODevice* input; + RenderArea* canvas; + + bool pullMode; + + QPushButton* button; + QPushButton* button2; + QComboBox* deviceBox; + + char* buffer; + float* output; + +private slots: + void refreshDisplay(); + void status(); + void readMore(); + void toggleMode(); + void toggleSuspend(); + void state(QAudio::State s); + void deviceChanged(int idx); +}; + diff --git a/examples/multimedia/audio/audioinput/audioinput.pro b/examples/multimedia/audio/audioinput/audioinput.pro new file mode 100644 index 0000000..d930750 --- /dev/null +++ b/examples/multimedia/audio/audioinput/audioinput.pro @@ -0,0 +1,12 @@ +HEADERS = audioinput.h +SOURCES = audioinput.cpp \ + main.cpp + +QT += multimedia + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/audio/audioinput +sources.files = $$SOURCES *.h $$RESOURCES $$FORMS audioinput.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/multimedia/audio/audioinput +INSTALLS += target sources + diff --git a/examples/multimedia/audio/audioinput/main.cpp b/examples/multimedia/audio/audioinput/main.cpp new file mode 100644 index 0000000..64a9b04 --- /dev/null +++ b/examples/multimedia/audio/audioinput/main.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "audioinput.h" + +int main(int argv, char **args) +{ + QApplication app(argv, args); + app.setApplicationName("Audio Input Test"); + + InputTest input; + input.show(); + + return app.exec(); +} diff --git a/examples/multimedia/audio/audiooutput/audiooutput.cpp b/examples/multimedia/audio/audiooutput/audiooutput.cpp new file mode 100644 index 0000000..be26f19 --- /dev/null +++ b/examples/multimedia/audio/audiooutput/audiooutput.cpp @@ -0,0 +1,280 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include +#include +#include "audiooutput.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +Generator::Generator(QObject *parent) + :QIODevice( parent ) +{ + finished = false; + buffer = new char[SECONDS*44100*4+1000]; + t=buffer; + len=fillData(t+4,450,SECONDS); /* left channel, 450Hz sine */ + len+=fillData(t+6,452,SECONDS); /* right channel, 452Hz sine */ + putLong(t,len); + putLong(buffer+4,len+8+16+8); + pos = 0; + total = len+8+16+8; +} + +Generator::~Generator() +{ + delete [] buffer; +} + +void Generator::start() +{ + open(QIODevice::ReadOnly); +} + +void Generator::stop() +{ + close(); +} + +int Generator::putShort(char *t, unsigned int value) +{ + *(unsigned char *)(t++)=value&255; + *(unsigned char *)(t)=(value/256)&255; + return 2; +} + +int Generator::putLong(char *t, unsigned int value) +{ + *(unsigned char *)(t++)=value&255; + *(unsigned char *)(t++)=(value/256)&255; + *(unsigned char *)(t++)=(value/(256*256))&255; + *(unsigned char *)(t)=(value/(256*256*256))&255; + return 4; +} + +int Generator::fillData(char *start, int frequency, int seconds) +{ + int i, len=0; + int value; + for(i=0; i 16384) + len = 16384; + + if(len < (SECONDS*44100*4+1000)-pos) { + // Normal + memcpy(data,t+pos,len); + pos+=len; + return len; + } else { + // Whats left and reset to start + qint64 left = (SECONDS*44100*4+1000)-pos; + memcpy(data,t+pos,left); + pos=0; + return left; + } +} + +qint64 Generator::writeData(const char *data, qint64 len) +{ + Q_UNUSED(data); + Q_UNUSED(len); + + return 0; +} + +AudioTest::AudioTest() +{ + QWidget *window = new QWidget; + QVBoxLayout* layout = new QVBoxLayout; + + deviceBox = new QComboBox(this); + QList devices = QAudioDeviceInfo::deviceList(QAudio::AudioOutput); + for(int i = 0; i < devices.size(); ++i) { + deviceBox->addItem(QAudioDeviceInfo(devices.at(i)).deviceName(), qVariantFromValue(devices.at(i))); + } + connect(deviceBox,SIGNAL(activated(int)),SLOT(deviceChanged(int))); + layout->addWidget(deviceBox); + + button = new QPushButton(this); + button->setText(tr("Click for Push Mode")); + connect(button,SIGNAL(clicked()),SLOT(toggle())); + layout->addWidget(button); + + button2 = new QPushButton(this); + button2->setText(tr("Click To Suspend")); + connect(button2,SIGNAL(clicked()),SLOT(togglePlay())); + layout->addWidget(button2); + + window->setLayout(layout); + setCentralWidget(window); + window->show(); + + buffer = new char[BUFFER_SIZE]; + + gen = new Generator(this); + + pullMode = true; + + timer = new QTimer(this); + connect(timer,SIGNAL(timeout()),SLOT(writeMore())); + + gen->start(); + + settings.setFrequency(44100); + settings.setChannels(2); + settings.setSampleSize(16); + settings.setCodec("audio/pcm"); + settings.setByteOrder(QAudioFormat::LittleEndian); + settings.setSampleType(QAudioFormat::SignedInt); + audioOutput = new QAudioOutput(settings,this); + connect(audioOutput,SIGNAL(notify()),SLOT(status())); + connect(audioOutput,SIGNAL(stateChanged(QAudio::State)),SLOT(state(QAudio::State))); + + audioOutput->start(gen); +} + +AudioTest::~AudioTest() +{ + delete [] buffer; +} + +void AudioTest::deviceChanged(int idx) +{ + timer->stop(); + gen->stop(); + audioOutput->stop(); + audioOutput->disconnect(this); + delete audioOutput; + + device = deviceBox->itemData(idx).value(); + audioOutput = new QAudioOutput(device,settings,this); + connect(audioOutput,SIGNAL(notify()),SLOT(status())); + connect(audioOutput,SIGNAL(stateChanged(QAudio::State)),SLOT(state(QAudio::State))); + gen->start(); + audioOutput->start(gen); +} + +void AudioTest::status() +{ + qWarning()<<"byteFree = "<bytesFree()<<" bytes, clock = "<clock()<<"ms, totalTime = "<totalTime()/1000<<"ms"; +} + +void AudioTest::writeMore() +{ + if(!audioOutput) + return; + + if(audioOutput->state() == QAudio::StopState) + return; + + int l; + int out; + + int chunks = audioOutput->bytesFree()/audioOutput->periodSize(); + while(chunks) { + l = gen->read(buffer,audioOutput->periodSize()); + if(l > 0) + out = output->write(buffer,l); + if(l != audioOutput->periodSize()) + break; + chunks--; + } +} + +void AudioTest::toggle() +{ + // Change between pull and push modes + + timer->stop(); + audioOutput->stop(); + + if (pullMode) { + button->setText("Click for Pull Mode"); + output = audioOutput->start(0); + pullMode = false; + timer->start(20); + } else { + button->setText("Click for Push Mode"); + pullMode = true; + audioOutput->start(gen); + } +} + +void AudioTest::togglePlay() +{ + // toggle suspend/resume + if(audioOutput->state() == QAudio::SuspendState) { + qWarning()<<"status: Suspended, resume()"; + audioOutput->resume(); + button2->setText("Click To Suspend"); + } else if (audioOutput->state() == QAudio::ActiveState) { + qWarning()<<"status: Active, suspend()"; + audioOutput->suspend(); + button2->setText("Click To Resume"); + } else if (audioOutput->state() == QAudio::StopState) { + qWarning()<<"status: Stopped, resume()"; + audioOutput->resume(); + button2->setText("Click To Suspend"); + } else if (audioOutput->state() == QAudio::IdleState) { + qWarning()<<"status: IdleState"; + } +} + +void AudioTest::state(QAudio::State state) +{ + qWarning()<<" state="< + +#define BUFFER_SIZE 32768 +#define SECONDS 3 + +#include +#include +#include +#include +#include +#include + +#include + +class Generator : public QIODevice +{ + Q_OBJECT +public: + Generator(QObject *parent); + ~Generator(); + + void start(); + void stop(); + + char *t; + int len; + int pos; + int total; + char *buffer; + bool finished; + int chunk_size; + + qint64 readData(char *data, qint64 maxlen); + qint64 writeData(const char *data, qint64 len); + +private: + int putShort(char *t, unsigned int value); + int putLong(char *t, unsigned int value); + int fillData(char *start, int frequency, int seconds); +}; + +class AudioTest : public QMainWindow +{ + Q_OBJECT +public: + AudioTest(); + ~AudioTest(); + + QAudioDeviceId device; + Generator* gen; + QAudioOutput* audioOutput; + QIODevice* output; + QTimer* timer; + QAudioFormat settings; + + bool pullMode; + char* buffer; + + QPushButton* button; + QPushButton* button2; + QComboBox* deviceBox; + +private slots: + void status(); + void writeMore(); + void toggle(); + void togglePlay(); + void state(QAudio::State s); + void deviceChanged(int idx); +}; + diff --git a/examples/multimedia/audio/audiooutput/audiooutput.pro b/examples/multimedia/audio/audiooutput/audiooutput.pro new file mode 100644 index 0000000..08f43ce --- /dev/null +++ b/examples/multimedia/audio/audiooutput/audiooutput.pro @@ -0,0 +1,11 @@ +HEADERS = audiooutput.h +SOURCES = audiooutput.cpp \ + main.cpp + +QT += multimedia + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/audio/audiooutput +sources.files = $$SOURCES *.h $$RESOURCES $$FORMS audiooutput.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/multimedia/audio/audiooutput +INSTALLS += target sources diff --git a/examples/multimedia/audio/audiooutput/main.cpp b/examples/multimedia/audio/audiooutput/main.cpp new file mode 100644 index 0000000..fc319bd --- /dev/null +++ b/examples/multimedia/audio/audiooutput/main.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include + +#include "audiooutput.h" + +int main(int argv, char **args) +{ + QApplication app(argv, args); + app.setApplicationName("Audio Output Test"); + + AudioTest audio; + audio.show(); + + return app.exec(); +} diff --git a/examples/multimedia/multimedia.pro b/examples/multimedia/multimedia.pro new file mode 100644 index 0000000..ac78b15 --- /dev/null +++ b/examples/multimedia/multimedia.pro @@ -0,0 +1,8 @@ +TEMPLATE = subdirs +SUBDIRS = audio + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/multimedia +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS multimedia.pro README +sources.path = $$[QT_INSTALL_EXAMPLES]/multimedia +INSTALLS += target sources diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index 1bac953..a03a313 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -36,7 +36,7 @@ INCLUDEPATH = $$QMAKE_INCDIR_QT $$INCLUDEPATH #prepending prevents us from picki win32:INCLUDEPATH += $$QMAKE_INCDIR_QT/ActiveQt # As order does matter for static libs, we reorder the QT variable here -TMPLIBS = webkit phonon dbus testlib script scripttools svg qt3support sql xmlpatterns xml egl opengl openvg gui network core +TMPLIBS = multimedia webkit phonon dbus testlib script scripttools svg qt3support sql xmlpatterns xml egl opengl openvg gui network core for(QTLIB, $$list($$TMPLIBS)) { contains(QT, $$QTLIB): QT_ORDERED += $$QTLIB } @@ -152,6 +152,7 @@ for(QTLIB, $$list($$lower($$unique(QT)))) { else:isEqual(QTLIB, dbus):qlib = QtDBus else:isEqual(QTLIB, phonon):qlib = phonon else:isEqual(QTLIB, webkit):qlib = QtWebKit + else:isEqual(QTLIB, multimedia):qlib = QtMultimedia else:message("Unknown QT: $$QTLIB"):qlib = !isEmpty(qlib) { target_qt:isEqual(TARGET, qlib) { diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 18d5a9f..1711f16 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1173,6 +1173,11 @@ class QDataStream; # else # define Q_OPENGL_EXPORT Q_DECL_IMPORT # endif +# if defined(QT_BUILD_MULTIMEDIA_LIB) +# define Q_MULTIMEDIA_EXPORT Q_DECL_EXPORT +# else +# define Q_MULTIMEDIA_EXPORT Q_DECL_IMPORT +# endif # if defined(QT_BUILD_OPENVG_LIB) # define Q_OPENVG_EXPORT Q_DECL_EXPORT # else @@ -1217,6 +1222,7 @@ class QDataStream; # define Q_SVG_EXPORT Q_DECL_IMPORT # define Q_CANVAS_EXPORT Q_DECL_IMPORT # define Q_OPENGL_EXPORT Q_DECL_IMPORT +# define Q_MULTIMEDIA_EXPORT Q_DECL_IMPORT # define Q_OPENVG_EXPORT Q_DECL_IMPORT # define Q_XML_EXPORT Q_DECL_IMPORT # define Q_XMLPATTERNS_EXPORT Q_DECL_IMPORT @@ -1243,6 +1249,7 @@ class QDataStream; # define Q_NETWORK_EXPORT Q_DECL_EXPORT # define Q_SVG_EXPORT Q_DECL_EXPORT # define Q_OPENGL_EXPORT Q_DECL_EXPORT +# define Q_MULTIMEDIA_EXPORT Q_DECL_EXPORT # define Q_OPENVG_EXPORT Q_DECL_EXPORT # define Q_XML_EXPORT Q_DECL_EXPORT # define Q_XMLPATTERNS_EXPORT Q_DECL_EXPORT @@ -1256,6 +1263,7 @@ class QDataStream; # define Q_NETWORK_EXPORT # define Q_SVG_EXPORT # define Q_OPENGL_EXPORT +# define Q_MULTIMEDIA_EXPORT # define Q_XML_EXPORT # define Q_XMLPATTERNS_EXPORT # define Q_SCRIPT_EXPORT @@ -2305,12 +2313,14 @@ QT3_SUPPORT Q_CORE_EXPORT const char *qInstallPathSysconf(); #define QT_MODULE_DBUS 0x08000 #define QT_MODULE_SCRIPTTOOLS 0x10000 #define QT_MODULE_OPENVG 0x20000 +#define QT_MODULE_MULTIMEDIA 0x40000 /* Qt editions */ #define QT_EDITION_CONSOLE (QT_MODULE_CORE \ | QT_MODULE_NETWORK \ | QT_MODULE_SQL \ | QT_MODULE_SCRIPT \ + | QT_MODULE_MULTIMEDIA \ | QT_MODULE_XML \ | QT_MODULE_XMLPATTERNS \ | QT_MODULE_TEST \ @@ -2326,6 +2336,7 @@ QT3_SUPPORT Q_CORE_EXPORT const char *qInstallPathSysconf(); | QT_MODULE_OPENGL \ | QT_MODULE_OPENVG \ | QT_MODULE_SQL \ + | QT_MODULE_MULTIMEDIA \ | QT_MODULE_XML \ | QT_MODULE_XMLPATTERNS \ | QT_MODULE_SCRIPT \ @@ -2374,6 +2385,9 @@ QT_LICENSED_MODULE(OpenVG) #if (QT_EDITION & QT_MODULE_SQL) QT_LICENSED_MODULE(Sql) #endif +#if (QT_EDITION & QT_MODULE_MULTIMEDIA) +QT_LICENSED_MODULE(Multimedia) +#endif #if (QT_EDITION & QT_MODULE_XML) QT_LICENSED_MODULE(Xml) #endif diff --git a/src/multimedia/audio/audio.pri b/src/multimedia/audio/audio.pri new file mode 100644 index 0000000..3ddb23b --- /dev/null +++ b/src/multimedia/audio/audio.pri @@ -0,0 +1,56 @@ +HEADERS += $$PWD/qaudio.h \ + $$PWD/qaudioformat.h \ + $$PWD/qaudioinput.h \ + $$PWD/qaudiooutput.h \ + $$PWD/qaudiodeviceinfo.h \ + $$PWD/qaudioengineplugin.h \ + $$PWD/qaudioengine.h \ + $$PWD/qaudiodevicefactory_p.h \ + $$PWD/qaudiodeviceid.h \ + $$PWD/qaudiodeviceid_p.h + + +SOURCES += $$PWD/qaudio.cpp \ + $$PWD/qaudioformat.cpp \ + $$PWD/qaudiodeviceinfo.cpp \ + $$PWD/qaudiooutput.cpp \ + $$PWD/qaudioinput.cpp \ + $$PWD/qaudioengineplugin.cpp \ + $$PWD/qaudioengine.cpp \ + $$PWD/qaudiodevicefactory.cpp \ + $$PWD/qaudiodeviceid.cpp + +mac { + HEADERS += $$PWD/qaudioinput_mac_p.h \ + $$PWD/qaudiooutput_mac_p.h \ + $$PWD/qaudiodeviceinfo_mac_p.h \ + $$PWD/qaudio_mac_p.h + + SOURCES += $$PWD/qaudiodeviceinfo_mac_p.cpp \ + $$PWD/qaudiooutput_mac_p.cpp \ + $$PWD/qaudioinput_mac_p.cpp \ + $$PWD/qaudio_mac.cpp + + LIBS += -framework CoreAudio -framework AudioUnit -framework AudioToolbox + +} else:win32 { + + HEADERS += $$PWD/qaudioinput_win32_p.h $$PWD/qaudiooutput_win32_p.h $$PWD/qaudiodeviceinfo_win32_p.h + SOURCES += $$PWD/qaudiodeviceinfo_win32_p.cpp \ + $$PWD/qaudiooutput_win32_p.cpp \ + $$PWD/qaudioinput_win32_p.cpp + !wince*:LIBS += -lwinmm + wince*:LIBS += -lcoredll + +} else:unix { + unix:contains(QT_CONFIG, alsa) { + linux-*|freebsd-*|openbsd-*:{ + DEFINES += HAS_ALSA + HEADERS += $$PWD/qaudiooutput_alsa_p.h $$PWD/qaudioinput_alsa_p.h $$PWD/qaudiodeviceinfo_alsa_p.h + SOURCES += $$PWD/qaudiodeviceinfo_alsa_p.cpp \ + $$PWD/qaudiooutput_alsa_p.cpp \ + $$PWD/qaudioinput_alsa_p.cpp + LIBS += -lasound + } + } +} diff --git a/src/multimedia/audio/qaudio.cpp b/src/multimedia/audio/qaudio.cpp new file mode 100644 index 0000000..5ba6493 --- /dev/null +++ b/src/multimedia/audio/qaudio.cpp @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include + + +QT_BEGIN_NAMESPACE + +namespace QAudio +{ + +class RegisterMetaTypes +{ +public: + RegisterMetaTypes() + { + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); + } + +} _register; + +} + +/*! + \namespace QAudio + \brief The QAudio namespace contains enums used by the audio classes. + \since 4.6 +*/ + +/*! + \enum QAudio::Error + + \value NoError No errors have occurred + \value OpenError An error opening the audio device + \value IOError An error occurred during read/write of audio device + \value UnderrunError Audio data is not being fed to the audio device at a fast enough rate + \value FatalError A non-recoverable error has occurred, the audio device is not usable at this time. +*/ + +/*! + \enum QAudio::State + + \value ActiveState Audio data is being processed, this state is set after start() is called + and while audio data is available to be processed. + \value SuspendState The audio device is in a suspended state, this state will only be entered + after suspend() is called. + \value StopState The audio device is closed, not processing any audio data + \value IdleState The QIODevice passed in has no data and audio system's buffer is empty, this state + is set after start() is called and while no audio data is available to be processed. +*/ + +/*! + \enum QAudio::Mode + + \value AudioOutput audio output device + \value AudioInput audio input device +*/ + + +QT_END_NAMESPACE + diff --git a/src/multimedia/audio/qaudio.h b/src/multimedia/audio/qaudio.h new file mode 100644 index 0000000..b996cc6 --- /dev/null +++ b/src/multimedia/audio/qaudio.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#ifndef QAUDIO_H +#define QAUDIO_H + + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +namespace QAudio +{ + enum Error { NoError, OpenError, IOError, UnderrunError, FatalError }; + enum State { ActiveState, SuspendState, StopState, IdleState }; + enum Mode { AudioInput, AudioOutput }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +Q_DECLARE_METATYPE(QAudio::Error); +Q_DECLARE_METATYPE(QAudio::State); +Q_DECLARE_METATYPE(QAudio::Mode); + +#endif // QAUDIO_H diff --git a/src/multimedia/audio/qaudio_mac.cpp b/src/multimedia/audio/qaudio_mac.cpp new file mode 100644 index 0000000..cfa7ca3 --- /dev/null +++ b/src/multimedia/audio/qaudio_mac.cpp @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qaudio_mac_p.h" + +QT_BEGIN_NAMESPACE + +// Debugging +QDebug operator<<(QDebug dbg, const QAudioFormat& audioFormat) +{ + dbg.nospace() << "QAudioFormat(" << + audioFormat.frequency() << "," << + audioFormat.channels() << "," << + audioFormat.sampleSize()<< "," << + audioFormat.codec() << "," << + audioFormat.byteOrder() << "," << + audioFormat.sampleType() << ")"; + + return dbg.space(); +} + + +// Conversion +QAudioFormat toQAudioFormat(AudioStreamBasicDescription const& sf) +{ + QAudioFormat audioFormat; + + audioFormat.setFrequency(sf.mSampleRate); + audioFormat.setChannels(sf.mChannelsPerFrame); + audioFormat.setSampleSize(sf.mBitsPerChannel); + audioFormat.setCodec(QString::fromLatin1("audio/pcm")); + audioFormat.setByteOrder(sf.mFormatFlags & kLinearPCMFormatFlagIsBigEndian != 0 ? QAudioFormat::BigEndian : QAudioFormat::LittleEndian); + QAudioFormat::SampleType type = QAudioFormat::UnSignedInt; + if ((sf.mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) != 0) + type = QAudioFormat::SignedInt; + else if ((sf.mFormatFlags & kLinearPCMFormatFlagIsFloat) != 0) + type = QAudioFormat::Float; + audioFormat.setSampleType(type); + + return audioFormat; +} + +AudioStreamBasicDescription toAudioStreamBasicDescription(QAudioFormat const& audioFormat) +{ + AudioStreamBasicDescription sf; + + sf.mFormatFlags = kAudioFormatFlagIsPacked; + sf.mSampleRate = audioFormat.frequency(); + sf.mFramesPerPacket = 1; + sf.mChannelsPerFrame = audioFormat.channels(); + sf.mBitsPerChannel = audioFormat.sampleSize(); + sf.mBytesPerFrame = sf.mChannelsPerFrame * (sf.mBitsPerChannel / 8); + sf.mBytesPerPacket = sf.mFramesPerPacket * sf.mBytesPerFrame; + sf.mFormatID = kAudioFormatLinearPCM; + + switch (audioFormat.sampleType()) { + case QAudioFormat::SignedInt: sf.mFormatFlags |= kAudioFormatFlagIsSignedInteger; break; + case QAudioFormat::UnSignedInt: /* default */ break; + case QAudioFormat::Float: sf.mFormatFlags |= kAudioFormatFlagIsFloat; break; + case QAudioFormat::Unknown: default: break; + } + + return sf; +} + +// QAudioRingBuffer +QAudioRingBuffer::QAudioRingBuffer(int bufferSize): + m_bufferSize(bufferSize) +{ + m_buffer = new char[m_bufferSize]; + reset(); +} + +QAudioRingBuffer::~QAudioRingBuffer() +{ + delete m_buffer; +} + +int QAudioRingBuffer::used() const +{ + return m_bufferUsed; +} + +int QAudioRingBuffer::free() const +{ + return m_bufferSize - m_bufferUsed; +} + +int QAudioRingBuffer::size() const +{ + return m_bufferSize; +} + +void QAudioRingBuffer::reset() +{ + m_readPos = 0; + m_writePos = 0; + m_bufferUsed = 0; +} + +QT_END_NAMESPACE + + diff --git a/src/multimedia/audio/qaudio_mac_p.h b/src/multimedia/audio/qaudio_mac_p.h new file mode 100644 index 0000000..8e2d522 --- /dev/null +++ b/src/multimedia/audio/qaudio_mac_p.h @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + + +#ifndef QAUDIO_MAC_P_H +#define QAUDIO_MAC_P_H + +#include + +#include +#include + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + + +extern QDebug operator<<(QDebug dbg, const QAudioFormat& audioFormat); + +extern QAudioFormat toQAudioFormat(const AudioStreamBasicDescription& streamFormat); +extern AudioStreamBasicDescription toAudioStreamBasicDescription(QAudioFormat const& audioFormat); + +class QAudioRingBuffer +{ +public: + typedef QPair Region; + + QAudioRingBuffer(int bufferSize); + ~QAudioRingBuffer(); + + Region acquireReadRegion(int size) + { + const int used = m_bufferUsed.fetchAndAddAcquire(0); + + if (used > 0) { + const int readSize = qMin(size, qMin(m_bufferSize - m_readPos, used)); + + return readSize > 0 ? Region(m_buffer + m_readPos, readSize) : Region(0, 0); + } + + return Region(0, 0); + } + + void releaseReadRegion(Region const& region) + { + m_readPos = (m_readPos + region.second) % m_bufferSize; + + m_bufferUsed.fetchAndAddRelease(-region.second); + } + + Region acquireWriteRegion(int size) + { + const int free = m_bufferSize - m_bufferUsed.fetchAndAddAcquire(0); + + if (free > 0) { + const int writeSize = qMin(size, qMin(m_bufferSize - m_writePos, free)); + + return writeSize > 0 ? Region(m_buffer + m_writePos, writeSize) : Region(0, 0); + } + + return Region(0, 0); + } + + void releaseWriteRegion(Region const& region) + { + m_writePos = (m_writePos + region.second) % m_bufferSize; + + m_bufferUsed.fetchAndAddRelease(region.second); + } + + int used() const; + int free() const; + int size() const; + + void reset(); + +private: + int m_bufferSize; + int m_readPos; + int m_writePos; + char* m_buffer; + QAtomicInt m_bufferUsed; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QAUDIO_MAC_P_H + + diff --git a/src/multimedia/audio/qaudiodevicefactory.cpp b/src/multimedia/audio/qaudiodevicefactory.cpp new file mode 100644 index 0000000..35e9c91 --- /dev/null +++ b/src/multimedia/audio/qaudiodevicefactory.cpp @@ -0,0 +1,250 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include "qaudiodevicefactory_p.h" +#include "qaudiodeviceid_p.h" + +#if defined(Q_OS_WIN) +#include "qaudiodeviceinfo_win32_p.h" +#include "qaudiooutput_win32_p.h" +#include "qaudioinput_win32_p.h" +#elif defined(Q_OS_MAC) +#include "qaudiodeviceinfo_mac_p.h" +#include "qaudiooutput_mac_p.h" +#include "qaudioinput_mac_p.h" +#elif defined(HAS_ALSA) +#include "qaudiodeviceinfo_alsa_p.h" +#include "qaudiooutput_alsa_p.h" +#include "qaudioinput_alsa_p.h" +#endif + +QT_BEGIN_NAMESPACE + +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, + (QAudioEngineFactoryInterface_iid, QLatin1String("/audio"), Qt::CaseInsensitive)) + + +class QNullDeviceInfo : public QAbstractAudioDeviceInfo +{ +public: + QAudioFormat preferredFormat() const { qWarning()<<"using null deviceinfo, none available"; return QAudioFormat(); } + bool isFormatSupported(const QAudioFormat& ) const { return false; } + QAudioFormat nearestFormat(const QAudioFormat& ) const { return QAudioFormat(); } + QString deviceName() const { return QString(); } + QStringList codecList() { return QStringList(); } + QList frequencyList() { return QList(); } + QList channelsList() { return QList(); } + QList sampleSizeList() { return QList(); } + QList byteOrderList() { return QList(); } + QList sampleTypeList() { return QList(); } +}; + +class QNullInputDevice : public QAbstractAudioInput +{ +public: + QIODevice* start(QIODevice* ) { qWarning()<<"using null input device, none available"; return 0; } + void stop() {} + void reset() {} + void suspend() {} + void resume() {} + int bytesReady() const { return 0; } + int periodSize() const { return 0; } + void setBufferSize(int ) {} + int bufferSize() const { return 0; } + void setNotifyInterval(int ) {} + int notifyInterval() const { return 0; } + qint64 totalTime() const { return 0; } + qint64 clock() const { return 0; } + QAudio::Error error() const { return QAudio::OpenError; } + QAudio::State state() const { return QAudio::StopState; } + QAudioFormat format() const { return QAudioFormat(); } +}; + +class QNullOutputDevice : public QAbstractAudioOutput +{ +public: + QIODevice* start(QIODevice* ) { qWarning()<<"using null output device, none available"; return 0; } + void stop() {} + void reset() {} + void suspend() {} + void resume() {} + int bytesFree() const { return 0; } + int periodSize() const { return 0; } + void setBufferSize(int ) {} + int bufferSize() const { return 0; } + void setNotifyInterval(int ) {} + int notifyInterval() const { return 0; } + qint64 totalTime() const { return 0; } + qint64 clock() const { return 0; } + QAudio::Error error() const { return QAudio::OpenError; } + QAudio::State state() const { return QAudio::StopState; } + QAudioFormat format() const { return QAudioFormat(); } +}; + +QList QAudioDeviceFactory::deviceList(QAudio::Mode mode) +{ + QList devices; +#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA)) + foreach (const QByteArray &handle, QAudioDeviceInfoPrivate::deviceList(mode)) + devices += createDeviceId(QLatin1String("builtin"), mode, handle); +#endif + QFactoryLoader* l = loader(); + + foreach (QString const& key, l->keys()) { + QAudioEngineFactoryInterface* plugin = qobject_cast(l->instance(key)); + if (plugin) { + foreach (QByteArray const& handle, plugin->deviceList(mode)) + devices += createDeviceId(key, mode, handle); + } + + delete plugin; + } + + return devices; +} + +QAudioDeviceId QAudioDeviceFactory::defaultInputDevice() +{ + QAudioEngineFactoryInterface* plugin = qobject_cast(loader()->instance(QLatin1String("default"))); + + if (plugin) { + QList list = plugin->deviceList(QAudio::AudioInput); + if (list.size() > 0) + return createDeviceId(QLatin1String("default"), QAudio::AudioInput, list.at(0)); + } +#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA)) + return createDeviceId(QLatin1String("builtin"), QAudio::AudioInput, QAudioDeviceInfoPrivate::defaultInputDevice()); +#endif + return QAudioDeviceId(); +} + +QAudioDeviceId QAudioDeviceFactory::defaultOutputDevice() +{ + QAudioEngineFactoryInterface* plugin = qobject_cast(loader()->instance(QLatin1String("default"))); + + if (plugin) { + QList list = plugin->deviceList(QAudio::AudioOutput); + if (list.size() > 0) + return createDeviceId(QLatin1String("default"), QAudio::AudioOutput, list.at(0)); + } +#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA)) + return createDeviceId(QLatin1String("builtin"), QAudio::AudioOutput, QAudioDeviceInfoPrivate::defaultOutputDevice()); +#endif + return QAudioDeviceId(); +} + +QAbstractAudioDeviceInfo* QAudioDeviceFactory::audioDeviceInfo(QAudioDeviceId const& id) +{ + if (id.isNull()) + return new QNullDeviceInfo(); +#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA)) + if (id.d->key == QLatin1String("builtin")) + return new QAudioDeviceInfoPrivate(id.d->handle, QAudio::Mode(id.d->mode)); +#endif + QAudioEngineFactoryInterface* plugin = qobject_cast(loader()->instance(id.d->key)); + + if (plugin) + return plugin->createDeviceInfo(id.d->handle, QAudio::Mode(id.d->mode)); + + return new QNullDeviceInfo(); +} + +QAbstractAudioInput* QAudioDeviceFactory::createDefaultInputDevice(QAudioFormat const &format) +{ + return createInputDevice(defaultInputDevice(), format); +} + +QAbstractAudioOutput* QAudioDeviceFactory::createDefaultOutputDevice(QAudioFormat const &format) +{ + return createOutputDevice(defaultOutputDevice(), format); +} + +QAbstractAudioInput* QAudioDeviceFactory::createInputDevice(QAudioDeviceId const& id, QAudioFormat const &format) +{ + if (id.isNull()) + return new QNullInputDevice(); +#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA)) + if (id.d->key == QLatin1String("builtin")) { + if(!defaultInputDevice().isNull()) + return new QAudioInputPrivate(id.d->handle, format); + else + return new QNullInputDevice(); + } +#endif + QAudioEngineFactoryInterface* plugin = qobject_cast(loader()->instance((id.d->key))); + + if (plugin) + return plugin->createInput(id.d->handle, format); + + return new QNullInputDevice(); +} + +QAbstractAudioOutput* QAudioDeviceFactory::createOutputDevice(QAudioDeviceId const& id, QAudioFormat const &format) +{ + if (id.isNull()) + return new QNullOutputDevice(); +#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA)) + if (id.d->key == QLatin1String("builtin")) { + if(!defaultOutputDevice().isNull()) + return new QAudioOutputPrivate(id.d->handle, format); + else + return new QNullOutputDevice(); + } +#endif + QAudioEngineFactoryInterface* plugin = qobject_cast(loader()->instance(id.d->key)); + + if (plugin) + return plugin->createOutput(id.d->handle, format); + + return new QNullOutputDevice(); +} + +QAudioDeviceId QAudioDeviceFactory::createDeviceId(QString const& key, int mode, QByteArray const& handle) +{ + return QAudioDeviceId(new QAudioDeviceIdPrivate(key, mode, handle)); +} + +QT_END_NAMESPACE + diff --git a/src/multimedia/audio/qaudiodevicefactory_p.h b/src/multimedia/audio/qaudiodevicefactory_p.h new file mode 100644 index 0000000..a8e2b28 --- /dev/null +++ b/src/multimedia/audio/qaudiodevicefactory_p.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#ifndef QAUDIODEVICEFACTORY_P_H +#define QAUDIODEVICEFACTORY_P_H + +#include +#include +#include + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +class QAbstractAudioInput; +class QAbstractAudioOutput; + + +class QAudioDeviceFactory +{ +public: + static QList deviceList(QAudio::Mode mode); + + static QAudioDeviceId defaultInputDevice(); + static QAudioDeviceId defaultOutputDevice(); + + static QAbstractAudioDeviceInfo* audioDeviceInfo(QAudioDeviceId const &device); + + static QAbstractAudioInput* createDefaultInputDevice(QAudioFormat const &format); + static QAbstractAudioOutput* createDefaultOutputDevice(QAudioFormat const &format); + + static QAbstractAudioInput* createInputDevice(QAudioDeviceId const &device, QAudioFormat const &format); + static QAbstractAudioOutput* createOutputDevice(QAudioDeviceId const &device, QAudioFormat const &format); + + static QAbstractAudioInput* createNullInput(); + static QAbstractAudioOutput* createNullOutput(); + + static QAudioDeviceId createDeviceId(QString const& key, int mode, QByteArray const& handle); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QAUDIODEVICEFACTORY_P_H + diff --git a/src/multimedia/audio/qaudiodeviceid.cpp b/src/multimedia/audio/qaudiodeviceid.cpp new file mode 100644 index 0000000..21a9cd8 --- /dev/null +++ b/src/multimedia/audio/qaudiodeviceid.cpp @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +#include +#include "qaudiodeviceid_p.h" + + +QT_BEGIN_NAMESPACE + +/*! + \class QAudioDeviceId + \brief The QAudioDeviceId class provides means for identifying a unique input or output device on a system. + + \inmodule QtMultimedia + \ingroup multimedia + \since 4.6 + + \sa QAudioDeviceInfo, QAudioOutput, QAudioInput +*/ + +/*! + Construct a new null QAudioDeviceId. +*/ + +QAudioDeviceId::QAudioDeviceId() +{ +} + +/*! + Copy the QAudDeviceId referenced by \a other. +*/ + +QAudioDeviceId::QAudioDeviceId(const QAudioDeviceId &other): + d(other.d) +{ +} + +/*! + Destroy the QAudioDeviceId. +*/ + +QAudioDeviceId::~QAudioDeviceId() +{ +} + +/*! + Make a copy of the \a other QAudioDeviceId. +*/ + +QAudioDeviceId& QAudioDeviceId::operator=(const QAudioDeviceId &other) +{ + d = other.d; + return *this; +} + +/*! + Compare with the \a other QAudioDeviceId, return true if they are the same; + otherwise false. +*/ + +bool QAudioDeviceId::operator==(const QAudioDeviceId &other) const +{ + return (d.constData() == 0 && other.d.constData() == 0) || + (d.constData() != 0 && other.d.constData() != 0 && + d->key == other.d->key && d->mode == other.d->mode && d->handle == other.d->handle); +} + +/*! + Compare with the \a other QAudioDeviceId, return false if they are the same; + otherwise true. +*/ + +bool QAudioDeviceId::operator!=(const QAudioDeviceId &other) const +{ + return !(*this == other); +} + +/*! + Returns true if this is not a valid QAudioDeviceId; otherwise false. +*/ + +bool QAudioDeviceId::isNull() const +{ + return d.constData() == 0; +} + +/*! + \internal +*/ + +QAudioDeviceId::QAudioDeviceId(QAudioDeviceIdPrivate* data): + d(data) +{ +} + +/*! + \internal +*/ + +QAudioDeviceIdPrivate::QAudioDeviceIdPrivate(QString const& k, int m, QByteArray const& h): + key(k), mode(m), handle(h) +{ +} + +#ifndef QT_NO_DATASTREAM +Q_MULTIMEDIA_EXPORT QDataStream &operator<<(QDataStream &s, const QAudioDeviceId &id) +{ + s << id.d->key << id.d->mode << id.d->handle; + return s; +} + +Q_MULTIMEDIA_EXPORT QDataStream &operator>>(QDataStream &s, QAudioDeviceId &id) +{ + QString key; + int mode; + QByteArray handle; + + s >> key >> mode >> handle; + id = QAudioDeviceId(new QAudioDeviceIdPrivate(key, mode, handle)); + + return s; +} +#endif + + +QT_END_NAMESPACE diff --git a/src/multimedia/audio/qaudiodeviceid.h b/src/multimedia/audio/qaudiodeviceid.h new file mode 100644 index 0000000..f9188d3 --- /dev/null +++ b/src/multimedia/audio/qaudiodeviceid.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QAUDIODEVICEID_H +#define QAUDIODEVICEID_H + +#include +#include + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + + +class QAudioDeviceFactory; +class QAudioDeviceIdPrivate; + +class Q_MULTIMEDIA_EXPORT QAudioDeviceId +{ + friend class QAudioDeviceFactory; + friend Q_MULTIMEDIA_EXPORT QDataStream &operator<<(QDataStream&, const QAudioDeviceId&); + friend Q_MULTIMEDIA_EXPORT QDataStream &operator>>(QDataStream&, QAudioDeviceId&); + +public: + QAudioDeviceId(); + QAudioDeviceId(const QAudioDeviceId &other); + ~QAudioDeviceId(); + + QAudioDeviceId& operator=(const QAudioDeviceId &other); + bool operator==(const QAudioDeviceId &id) const; + bool operator!=(const QAudioDeviceId &id) const; + + bool isNull() const; + +private: + QAudioDeviceId(QAudioDeviceIdPrivate *data); + + QSharedDataPointer d; +}; + +#ifndef QT_NO_DATASTREAM +Q_MULTIMEDIA_EXPORT QDataStream &operator<<(QDataStream&, const QAudioDeviceId&); +Q_MULTIMEDIA_EXPORT QDataStream &operator>>(QDataStream&, QAudioDeviceId&); +#endif + +QT_END_NAMESPACE + +QT_END_HEADER + +Q_DECLARE_METATYPE(QAudioDeviceId); + + +#endif // QAUDIODEVICEID_H diff --git a/src/multimedia/audio/qaudiodeviceid_p.h b/src/multimedia/audio/qaudiodeviceid_p.h new file mode 100644 index 0000000..3034574 --- /dev/null +++ b/src/multimedia/audio/qaudiodeviceid_p.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#ifndef QAUDIODEVICEIDPRIVATE_H +#define QAUDIODEVICEIDPRIVATE_H + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + + +class QAudioDeviceIdPrivate : public QSharedData +{ +public: + QAudioDeviceIdPrivate(QString const& k, int m, QByteArray const& h); + + QString key; + int mode; + QByteArray handle; +}; + + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QAUDIODEVICEIDPRIVATE_H diff --git a/src/multimedia/audio/qaudiodeviceinfo.cpp b/src/multimedia/audio/qaudiodeviceinfo.cpp new file mode 100644 index 0000000..c1895d7 --- /dev/null +++ b/src/multimedia/audio/qaudiodeviceinfo.cpp @@ -0,0 +1,270 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qaudiodevicefactory_p.h" +#include +#include + + +QT_BEGIN_NAMESPACE + +/*! + \class QAudioDeviceInfo + \brief The QAudioDeviceInfo class provides an interface to query audio devices and their functionality. + + \inmodule QtMultimedia + \ingroup multimedia + \since 4.6 + + QAudioDeviceInfo lets you query for audio devices--such as sound + cards and USB headsets--that are currently available on the system. + The audio devices available are dependent on the platform or audio plugins installed. + + You can also query each device for the formats it supports. A + format in this context is a set consisting of a specific byte + order, channel, codec, frequency, sample rate, and sample type. A + format is represented by the QAudioFormat class. + + The values supported by the the device for each of these + parameters can be fetched with + supportedByteOrders(), supportedChannels(), supportedCodecs(), + supportedFrequencies(), supportedSampleSizes(), and + supportedSampleTypes(). The combinations supported are dependent on the platform, + audio plugins installed and the audio device capabilities. If you need a specific format, you can check if + the device supports it with isFormatSupported(), or fetch a + supported format that is as close as possible to the format with + nearestFormat(). + + A QAudioDeviceInfo is constructed with a QAudioDeviceId, which is + an identifier for a physical device. It is used by Qt to construct + classes that communicate with the device--such as + QAudioDeviceInfo, QAudioInput, and QAudioOutput. The static + functions defaultInputDevice(), defaultOutputDevice(), and + deviceList() let you get a hold of the ids for all available + devices. You fetch ids based on whether you will use the device + for input or output; this is specified by the QAudio::Mode enum. + The QAudioDeviceId returned are only valid for the QAudio::Mode. + + For instance: + + \code + foreach(QAudioDeviceId audioId, QAudioDeviceInfo::deviceList(QAudio::AudioOutput)) { + QAudioDeviceInfo info(audioId); + qDebug() << "Device name: " << info.deviceName(); + } + \endcode + + In this code sample, we loop through all devices that are able to output + sound, i.e., play an audio stream in a supported format. For each device we + find, we simply print the deviceName(). + + \sa QAudioOutput, QAudioInput, QAudioDeviceId +*/ + +/*! + Construct a new audio device info and attach it to \a parent. + Using the audio device with the specified \a id. +*/ + +QAudioDeviceInfo::QAudioDeviceInfo(const QAudioDeviceId &id, QObject *parent): + QObject(parent) +{ + d = QAudioDeviceFactory::audioDeviceInfo(id); +} + +/*! + Destroy this audio device info. +*/ + +QAudioDeviceInfo::~QAudioDeviceInfo() +{ + delete d; +} + +/*! + Returns human readable name of audio device. + + Device names vary depending on platform/audio plugin being used. + + They are a unique string identifiers for the audio device. + + eg. default, Intel, U0x46d0x9a4 +*/ + +QString QAudioDeviceInfo::deviceName() const +{ + return d->deviceName(); +} + +/*! + Returns true if \a settings are supported by the audio device of this QAudioDeviceInfo. +*/ + +bool QAudioDeviceInfo::isFormatSupported(const QAudioFormat &settings) const +{ + return d->isFormatSupported(settings); +} + +/*! + Returns QAudioFormat of default settings. + + These settings are provided by the platform/audio plugin being used. + + They also are dependent on the QAudio::Mode being used. + + A typical audio system would provide something like: + \list + \o Input settings: 8000Hz mono 8 bit. + \o Output settings: 44100Hz stereo 16 bit little endian. + \endlist +*/ + +QAudioFormat QAudioDeviceInfo::preferredFormat() const +{ + return d->preferredFormat(); +} + +/*! + Returns closest QAudioFormat to \a settings that system audio supports. + + These settings are provided by the platform/audio plugin being used. + + They also are dependent on the QAudio::Mode being used. +*/ + +QAudioFormat QAudioDeviceInfo::nearestFormat(const QAudioFormat &settings) const +{ + return d->nearestFormat(settings); +} + +/*! + Returns a list of supported codecs. + + All platform and plugin implementations should provide support for: + + "audio/pcm" - Linear PCM + + For writing plugins to support additional codecs refer to: + + http://www.iana.org/assignments/media-types/audio/ +*/ + +QStringList QAudioDeviceInfo::supportedCodecs() const +{ + return d->codecList(); +} + +/*! + Returns a list of supported frequencies. +*/ + +QList QAudioDeviceInfo::supportedFrequencies() const +{ + return d->frequencyList(); +} + +/*! + Returns a list of supported channels. +*/ + +QList QAudioDeviceInfo::supportedChannels() const +{ + return d->channelsList(); +} + +/*! + Returns a list of supported sample sizes. +*/ + +QList QAudioDeviceInfo::supportedSampleSizes() const +{ + return d->sampleSizeList(); +} + +/*! + Returns a list of supported byte orders. +*/ + +QList QAudioDeviceInfo::supportedByteOrders() const +{ + return d->byteOrderList(); +} + +/*! + Returns a list of supported sample types. +*/ + +QList QAudioDeviceInfo::supportedSampleTypes() const +{ + return d->sampleTypeList(); +} + +/*! + Returns the name of the default input audio device. + All platform and audio plugin implementations provide a default audio device to use. +*/ + +QAudioDeviceId QAudioDeviceInfo::defaultInputDevice() +{ + return QAudioDeviceFactory::defaultInputDevice(); +} + +/*! + Returns the name of the default output audio device. + All platform and audio plugin implementations provide a default audio device to use. +*/ + +QAudioDeviceId QAudioDeviceInfo::defaultOutputDevice() +{ + return QAudioDeviceFactory::defaultOutputDevice(); +} + +/*! + Returns a list of audio devices that support \a mode. +*/ + +QList QAudioDeviceInfo::deviceList(QAudio::Mode mode) +{ + return QAudioDeviceFactory::deviceList(mode); +} + +QT_END_NAMESPACE + diff --git a/src/multimedia/audio/qaudiodeviceinfo.h b/src/multimedia/audio/qaudiodeviceinfo.h new file mode 100644 index 0000000..444a00a --- /dev/null +++ b/src/multimedia/audio/qaudiodeviceinfo.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#ifndef QAUDIODEVICEINFO_H +#define QAUDIODEVICEINFO_H + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + + +class QAbstractAudioDeviceInfo; + +class Q_MULTIMEDIA_EXPORT QAudioDeviceInfo : public QObject +{ + Q_OBJECT + +public: + explicit QAudioDeviceInfo(const QAudioDeviceId &id, QObject *parent = 0); + ~QAudioDeviceInfo(); + + QString deviceName() const; + + bool isFormatSupported(const QAudioFormat &format) const; + QAudioFormat preferredFormat() const; + QAudioFormat nearestFormat(const QAudioFormat &format) const; + + QStringList supportedCodecs() const; + QList supportedFrequencies() const; + QList supportedChannels() const; + QList supportedSampleSizes() const; + QList supportedByteOrders() const; + QList supportedSampleTypes() const; + + static QAudioDeviceId defaultInputDevice(); + static QAudioDeviceId defaultOutputDevice(); + + static QList deviceList(QAudio::Mode mode); + +private: + Q_DISABLE_COPY(QAudioDeviceInfo) + + QAbstractAudioDeviceInfo* d; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QAUDIODEVICEINFO_H diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp new file mode 100644 index 0000000..fe45f82 --- /dev/null +++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp @@ -0,0 +1,394 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qaudiodeviceinfo_alsa_p.h" + +QAudioDeviceInfoPrivate::QAudioDeviceInfoPrivate(QByteArray dev, QAudio::Mode mode) +{ + handle = 0; + + device = QLatin1String(dev); + this->mode = mode; +} + +QAudioDeviceInfoPrivate::~QAudioDeviceInfoPrivate() +{ + close(); +} + +bool QAudioDeviceInfoPrivate::isFormatSupported(const QAudioFormat& format) const +{ + return testSettings(format); +} + +QAudioFormat QAudioDeviceInfoPrivate::preferredFormat() const +{ + QAudioFormat nearest; + if(mode == QAudio::AudioOutput) { + nearest.setFrequency(44100); + nearest.setChannels(2); + nearest.setByteOrder(QAudioFormat::LittleEndian); + nearest.setSampleType(QAudioFormat::SignedInt); + nearest.setSampleSize(16); + nearest.setCodec(tr("audio/pcm")); + } else { + nearest.setFrequency(8000); + nearest.setChannels(1); + nearest.setSampleType(QAudioFormat::SignedInt); + nearest.setSampleSize(8); + nearest.setCodec(tr("audio/pcm")); + } + return nearest; +} + +QAudioFormat QAudioDeviceInfoPrivate::nearestFormat(const QAudioFormat& format) const +{ + if(testSettings(format)) + return format; + else + return preferredFormat(); +} + +QString QAudioDeviceInfoPrivate::deviceName() const +{ + return device; +} + +QStringList QAudioDeviceInfoPrivate::codecList() +{ + updateLists(); + return codecz; +} + +QList QAudioDeviceInfoPrivate::frequencyList() +{ + updateLists(); + return freqz; +} + +QList QAudioDeviceInfoPrivate::channelsList() +{ + updateLists(); + return channelz; +} + +QList QAudioDeviceInfoPrivate::sampleSizeList() +{ + updateLists(); + return sizez; +} + +QList QAudioDeviceInfoPrivate::byteOrderList() +{ + updateLists(); + return byteOrderz; +} + +QList QAudioDeviceInfoPrivate::sampleTypeList() +{ + updateLists(); + return typez; +} + +bool QAudioDeviceInfoPrivate::open() +{ + int err = 0; + QString dev = device; + if(!dev.contains(tr("default"))) { + int idx = snd_card_get_index(dev.toLocal8Bit().constData()); + dev = QString(tr("hw:%1,0")).arg(idx); + } + if(mode == QAudio::AudioOutput) { + err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_PLAYBACK,0); + } else { + err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_CAPTURE,0); + } + if(err < 0) { + handle = 0; + return false; + } + return true; +} + +void QAudioDeviceInfoPrivate::close() +{ + if(handle) + snd_pcm_close(handle); + handle = 0; +} + +bool QAudioDeviceInfoPrivate::testSettings(const QAudioFormat& format) const +{ + // Set nearest to closest settings that do work. + // See if what is in settings will work (return value). + + int err = 0; + snd_pcm_t* handle; + snd_pcm_hw_params_t *params; + QString dev = device; + + // open() + if(!dev.contains(tr("default"))) { + int idx = snd_card_get_index(dev.toLocal8Bit().constData()); + dev = QString(tr("hw:%1,0")).arg(idx); + } + if(mode == QAudio::AudioOutput) { + err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_PLAYBACK,0); + } else { + err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_CAPTURE,0); + } + if(err < 0) { + handle = 0; + return false; + } + + bool testChannel = false; + bool testCodec = false; + bool testFreq = false; + bool testType = false; + bool testSize = false; + + int dir = 0; + + snd_pcm_nonblock( handle, 0 ); + snd_pcm_hw_params_alloca( ¶ms ); + snd_pcm_hw_params_any( handle, params ); + + // For now, just accept only audio/pcm codec + if(!format.codec().startsWith(tr("audio/pcm"))) { + err=-1; + } else + testCodec = true; + + if(err>=0 && format.channels() != -1) { + err = snd_pcm_hw_params_test_channels(handle,params,format.channels()); + if(err>=0) + err = snd_pcm_hw_params_set_channels(handle,params,format.channels()); + if(err>=0) + testChannel = true; + } + + if(err>=0 && format.frequency() != -1) { + err = snd_pcm_hw_params_test_rate(handle,params,format.frequency(),0); + if(err>=0) + err = snd_pcm_hw_params_set_rate(handle,params,format.frequency(),dir); + if(err>=0) + testFreq = true; + } + + if((err>=0 && format.sampleSize() != -1) && + (format.sampleType() != QAudioFormat::Unknown)) { + switch(format.sampleSize()) { + case 8: + if(format.sampleType() == QAudioFormat::SignedInt) + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S8); + else if(format.sampleType() == QAudioFormat::UnSignedInt) + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U8); + break; + case 16: + if(format.sampleType() == QAudioFormat::SignedInt) { + if(format.byteOrder() == QAudioFormat::LittleEndian) + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE); + else if(format.byteOrder() == QAudioFormat::BigEndian) + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_BE); + } else if(format.sampleType() == QAudioFormat::UnSignedInt) { + if(format.byteOrder() == QAudioFormat::LittleEndian) + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_LE); + else if(format.byteOrder() == QAudioFormat::BigEndian) + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_BE); + } + break; + case 32: + if(format.sampleType() == QAudioFormat::SignedInt) { + if(format.byteOrder() == QAudioFormat::LittleEndian) + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_LE); + else if(format.byteOrder() == QAudioFormat::BigEndian) + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_BE); + } else if(format.sampleType() == QAudioFormat::UnSignedInt) { + if(format.byteOrder() == QAudioFormat::LittleEndian) + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_LE); + else if(format.byteOrder() == QAudioFormat::BigEndian) + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_BE); + } + } + if(err>=0) { + testSize = true; + testType = true; + } + } + if(err>=0) + err = snd_pcm_hw_params(handle, params); + + if(err == 0) { + // settings work + // close() + if(handle) + snd_pcm_close(handle); + return true; + } + if(handle) + snd_pcm_close(handle); + + return false; +} + +void QAudioDeviceInfoPrivate::updateLists() +{ + // redo all lists based on current settings + freqz.clear(); + channelz.clear(); + sizez.clear(); + byteOrderz.clear(); + typez.clear(); + codecz.clear(); + + if(!handle) + open(); + + if(!handle) + return; + + for(int i=0; i<(int)MAX_SAMPLE_RATES; i++) { + //if(snd_pcm_hw_params_test_rate(handle, params, SAMPLE_RATES[i], dir) == 0) + freqz.append(SAMPLE_RATES[i]); + } + channelz.append(1); + channelz.append(2); + sizez.append(8); + sizez.append(16); + sizez.append(32); + byteOrderz.append(QAudioFormat::LittleEndian); + byteOrderz.append(QAudioFormat::BigEndian); + typez.append(QAudioFormat::SignedInt); + typez.append(QAudioFormat::UnSignedInt); + typez.append(QAudioFormat::Float); + codecz.append(tr("audio/pcm")); + close(); +} + +QList QAudioDeviceInfoPrivate::deviceList(QAudio::Mode mode) +{ + QAudio::Mode _m; + QList devices; + QByteArray filter; + QString dir; + + // Create a list of all current audio devices that support mode + void **hints, **n; + char *name, *descr, *io; + + if(snd_device_name_hint(-1, "pcm", &hints) < 0) { + qWarning()<<"no alsa devices available"; + return devices; + } + n = hints; + + while (*n != NULL) { + _m = QAudio::AudioOutput; + name = snd_device_name_get_hint(*n, "NAME"); + descr = snd_device_name_get_hint(*n, "DESC"); + io = snd_device_name_get_hint(*n, "IOID"); + dir = QString::fromUtf8(io); + if((name != NULL) && (descr != NULL) && ((io == NULL) || (dir.length() ==filter.length()))) { + if(dir.length() == 5) + _m = QAudio::AudioInput; + if(io == NULL) + _m = mode; + + QString str = tr(name); + + if(str.contains(tr("default"))) { + int pos = str.indexOf(tr("="),0); + devices.append(str.mid(pos+1).toLocal8Bit().constData()); + } + } + if(name != NULL) + free(name); + if(descr != NULL) + free(descr); + if(io != NULL) + free(io); + n++; + } + snd_device_name_free_hint(hints); + + if(devices.size() > 0) { + devices.append("default"); + if(mode == QAudio::AudioInput) { + filter.append("Input"); + } else { + filter.append("Output"); + } + } + + return devices; +} + +QByteArray QAudioDeviceInfoPrivate::defaultInputDevice() +{ + QList devices = deviceList(QAudio::AudioInput); + if(devices.size() == 0) + return QByteArray(); + + return QByteArray("default"); +} + +QByteArray QAudioDeviceInfoPrivate::defaultOutputDevice() +{ + QList devices = deviceList(QAudio::AudioOutput); + if(devices.size() == 0) + return QByteArray(); + + return QByteArray("default"); +} + + diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h new file mode 100644 index 0000000..3ac9239 --- /dev/null +++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + + +#ifndef QAUDIODEVICEINFOALSA_H +#define QAUDIODEVICEINFOALSA_H + +#include + +#include +#include +#include +#include + +#include +#include +#include + +const unsigned int MAX_SAMPLE_RATES = 5; +const unsigned int SAMPLE_RATES[] = + { 8000, 11025, 22050, 44100, 48000 }; + +class QAudioDeviceInfoPrivate : public QAbstractAudioDeviceInfo +{ + Q_OBJECT +public: + QAudioDeviceInfoPrivate(QByteArray dev,QAudio::Mode mode); + ~QAudioDeviceInfoPrivate(); + + bool testSettings(const QAudioFormat& format) const; + void updateLists(); + QAudioFormat preferredFormat() const; + bool isFormatSupported(const QAudioFormat& format) const; + QAudioFormat nearestFormat(const QAudioFormat& format) const; + QString deviceName() const; + QStringList codecList(); + QList frequencyList(); + QList channelsList(); + QList sampleSizeList(); + QList byteOrderList(); + QList sampleTypeList(); + static QByteArray defaultInputDevice(); + static QByteArray defaultOutputDevice(); + static QList deviceList(QAudio::Mode); + +private: + bool open(); + void close(); + + QString device; + QAudio::Mode mode; + QAudioFormat nearest; + QList freqz; + QList channelz; + QList sizez; + QList byteOrderz; + QStringList codecz; + QList typez; + snd_pcm_t* handle; + snd_pcm_hw_params_t *params; +}; + +#endif + diff --git a/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp new file mode 100644 index 0000000..c94e0c4 --- /dev/null +++ b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp @@ -0,0 +1,357 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include +#include +#include + +#include +#include "qaudio_mac_p.h" +#include "qaudiodeviceinfo_mac_p.h" + + + +QT_BEGIN_NAMESPACE + + +QAudioDeviceInfoPrivate::QAudioDeviceInfoPrivate(QByteArray const& handle, QAudio::Mode) +{ + QDataStream ds(handle); + quint32 did, tm; + + ds >> did >> tm >> name; + deviceId = AudioDeviceID(did); + mode = QAudio::Mode(tm); +} + +bool QAudioDeviceInfoPrivate::isFormatSupported(const QAudioFormat& format) const +{ + return format.codec() == QString::fromLatin1("audio/pcm"); +} + +QAudioFormat QAudioDeviceInfoPrivate::preferredFormat() const +{ + QAudioFormat rc; + + UInt32 propSize = 0; + + if (AudioDeviceGetPropertyInfo(deviceId, + 0, + mode == QAudio::AudioInput, + kAudioDevicePropertyStreams, + &propSize, + 0) == noErr) { + + const int sc = propSize / sizeof(AudioStreamID); + + if (sc > 0) { + AudioStreamID* streams = new AudioStreamID[sc]; + + if (AudioDeviceGetProperty(deviceId, + 0, + mode == QAudio::AudioInput, + kAudioDevicePropertyStreams, + &propSize, + streams) == noErr) { + + for (int i = 0; i < sc; ++i) { + if (AudioStreamGetPropertyInfo(streams[i], + 0, + kAudioStreamPropertyPhysicalFormat, + &propSize, + 0) == noErr) { + + AudioStreamBasicDescription sf; + + if (AudioStreamGetProperty(streams[i], + 0, + kAudioStreamPropertyPhysicalFormat, + &propSize, + &sf) == noErr) { + rc = toQAudioFormat(sf); + break; + } + } + } + } + + delete streams; + } + } + + return rc; +} + +QAudioFormat QAudioDeviceInfoPrivate::nearestFormat(const QAudioFormat& format) const +{ + QAudioFormat rc(format); + QAudioFormat target = preferredFormat(); + + if (!format.codec().isEmpty() && format.codec() != QString::fromLatin1("audio/pcm")) + return QAudioFormat(); + + rc.setCodec(QString::fromLatin1("audio/pcm")); + + if (rc.frequency() != target.frequency()) + rc.setFrequency(target.frequency()); + if (rc.channels() != target.channels()) + rc.setChannels(target.channels()); + if (rc.sampleSize() != target.sampleSize()) + rc.setSampleSize(target.sampleSize()); + if (rc.byteOrder() != target.byteOrder()) + rc.setByteOrder(target.byteOrder()); + if (rc.sampleType() != target.sampleType()) + rc.setSampleType(target.sampleType()); + + return rc; +} + +QString QAudioDeviceInfoPrivate::deviceName() const +{ + return name; +} + +QStringList QAudioDeviceInfoPrivate::codecList() +{ + return QStringList() << QString::fromLatin1("audio/pcm"); +} + +QList QAudioDeviceInfoPrivate::frequencyList() +{ + QSet rc; + + // Add some common frequencies + rc << 8000 << 11025 << 22050 << 44100; + + // + UInt32 propSize = 0; + + if (AudioDeviceGetPropertyInfo(deviceId, + 0, + mode == QAudio::AudioInput, + kAudioDevicePropertyAvailableNominalSampleRates, + &propSize, + 0) == noErr) { + + const int pc = propSize / sizeof(AudioValueRange); + + if (pc > 0) { + AudioValueRange* vr = new AudioValueRange[pc]; + + if (AudioDeviceGetProperty(deviceId, + 0, + mode == QAudio::AudioInput, + kAudioDevicePropertyAvailableNominalSampleRates, + &propSize, + vr) == noErr) { + + for (int i = 0; i < pc; ++i) + rc << vr[i].mMaximum; + } + + delete vr; + } + } + + return rc.toList(); +} + +QList QAudioDeviceInfoPrivate::channelsList() +{ + QList rc; + + // Can mix down to 1 channel + rc << 1; + + UInt32 propSize = 0; + int channels = 0; + + if (AudioDeviceGetPropertyInfo(deviceId, + 0, + mode == QAudio::AudioInput, + kAudioDevicePropertyStreamConfiguration, + &propSize, + 0) == noErr) { + + AudioBufferList* audioBufferList = static_cast(qMalloc(propSize)); + + if (audioBufferList != 0) { + if (AudioDeviceGetProperty(deviceId, + 0, + mode == QAudio::AudioInput, + kAudioDevicePropertyStreamConfiguration, + &propSize, + audioBufferList) == noErr) { + + for (int i = 0; i < int(audioBufferList->mNumberBuffers); ++i) { + channels += audioBufferList->mBuffers[i].mNumberChannels; + rc << channels; + } + } + + qFree(audioBufferList); + } + } + + return rc; +} + +QList QAudioDeviceInfoPrivate::sampleSizeList() +{ + return QList() << 8 << 16 << 24 << 32 << 64; +} + +QList QAudioDeviceInfoPrivate::byteOrderList() +{ + return QList() << QAudioFormat::LittleEndian << QAudioFormat::BigEndian; +} + +QList QAudioDeviceInfoPrivate::sampleTypeList() +{ + return QList() << QAudioFormat::SignedInt << QAudioFormat::UnSignedInt << QAudioFormat::Float; +} + +static QByteArray get_device_info(AudioDeviceID audioDevice, QAudio::Mode mode) +{ + UInt32 size; + QByteArray device; + QDataStream ds(&device, QIODevice::WriteOnly); + AudioStreamBasicDescription sf; + CFStringRef name; + Boolean isInput = mode == QAudio::AudioInput; + + // Id + ds << quint32(audioDevice); + + // Mode + size = sizeof(AudioStreamBasicDescription); + if (AudioDeviceGetProperty(audioDevice, 0, isInput, kAudioDevicePropertyStreamFormat, + &size, &sf) != noErr) { + return QByteArray(); + } + ds << quint32(mode); + + // Name + size = sizeof(CFStringRef); + if (AudioDeviceGetProperty(audioDevice, 0, isInput, kAudioObjectPropertyName, + &size, &name) != noErr) { + qWarning() << "QAudioDeviceInfo: Unable to find device name"; + } + ds << QCFString::toQString(name); + + CFRelease(name); + + return device; +} + +QByteArray QAudioDeviceInfoPrivate::defaultInputDevice() +{ + AudioDeviceID audioDevice; + UInt32 size = sizeof(audioDevice); + + if (AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &size, + &audioDevice) != noErr) { + qWarning() << "QAudioDeviceInfo: Unable to find default input device"; + return QByteArray(); + } + + return get_device_info(audioDevice, QAudio::AudioInput); +} + +QByteArray QAudioDeviceInfoPrivate::defaultOutputDevice() +{ + AudioDeviceID audioDevice; + UInt32 size = sizeof(audioDevice); + + if (AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &size, + &audioDevice) != noErr) { + qWarning() << "QAudioDeviceInfo: Unable to find default output device"; + return QByteArray(); + } + + return get_device_info(audioDevice, QAudio::AudioOutput); +} + +QList QAudioDeviceInfoPrivate::deviceList(QAudio::Mode mode) +{ + QList devices; + + UInt32 propSize = 0; + + if (AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &propSize, 0) == noErr) { + + const int dc = propSize / sizeof(AudioDeviceID); + + if (dc > 0) { + AudioDeviceID* audioDevices = new AudioDeviceID[dc]; + + if (AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &propSize, audioDevices) == noErr) { + for (int i = 0; i < dc; ++i) { + QByteArray info = get_device_info(audioDevices[i], mode); + if (!info.isNull()) + devices << info; + } + } + + delete audioDevices; + } + } + + return devices; +} + + +QT_END_NAMESPACE + diff --git a/src/multimedia/audio/qaudiodeviceinfo_mac_p.h b/src/multimedia/audio/qaudiodeviceinfo_mac_p.h new file mode 100644 index 0000000..ee593de --- /dev/null +++ b/src/multimedia/audio/qaudiodeviceinfo_mac_p.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + + +#ifndef QDEVICEINFO_MAC_P_H +#define QDEVICEINFO_MAC_P_H + +#include + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QAudioDeviceInfoPrivate : public QAbstractAudioDeviceInfo +{ +public: + AudioDeviceID deviceId; + QString name; + QAudio::Mode mode; + + QAudioDeviceInfoPrivate(QByteArray const& handle, QAudio::Mode mode); + + bool isFormatSupported(const QAudioFormat& format) const; + QAudioFormat preferredFormat() const; + QAudioFormat nearestFormat(const QAudioFormat& format) const; + + QString deviceName() const; + + QStringList codecList(); + QList frequencyList(); + QList channelsList(); + QList sampleSizeList(); + QList byteOrderList(); + QList sampleTypeList(); + + static QByteArray defaultInputDevice(); + static QByteArray defaultOutputDevice(); + + static QList deviceList(QAudio::Mode mode); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QDEVICEINFO_MAC_P_H diff --git a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp new file mode 100644 index 0000000..1a1995a --- /dev/null +++ b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp @@ -0,0 +1,378 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + + +#include +#include +#include "qaudiodeviceinfo_win32_p.h" + +// For mingw toolchain mmsystem.h only defines half the defines, so add if needed. +#ifndef WAVE_FORMAT_44M08 +#define WAVE_FORMAT_44M08 0x00000100 +#define WAVE_FORMAT_44S08 0x00000200 +#define WAVE_FORMAT_44M16 0x00000400 +#define WAVE_FORMAT_44S16 0x00000800 +#define WAVE_FORMAT_48M08 0x00001000 +#define WAVE_FORMAT_48S08 0x00002000 +#define WAVE_FORMAT_48M16 0x00004000 +#define WAVE_FORMAT_48S16 0x00008000 +#define WAVE_FORMAT_96M08 0x00010000 +#define WAVE_FORMAT_96S08 0x00020000 +#define WAVE_FORMAT_96M16 0x00040000 +#define WAVE_FORMAT_96S16 0x00080000 +#endif + + +QAudioDeviceInfoPrivate::QAudioDeviceInfoPrivate(QByteArray dev, QAudio::Mode mode) +{ + device = QLatin1String(dev); + this->mode = mode; +} + +QAudioDeviceInfoPrivate::~QAudioDeviceInfoPrivate() +{ + close(); +} + +bool QAudioDeviceInfoPrivate::isFormatSupported(const QAudioFormat& format) const +{ + return testSettings(format); +} + +QAudioFormat QAudioDeviceInfoPrivate::preferredFormat() const +{ + QAudioFormat nearest; + if(mode == QAudio::AudioOutput) { + nearest.setFrequency(44100); + nearest.setChannels(2); + nearest.setByteOrder(QAudioFormat::LittleEndian); + nearest.setSampleType(QAudioFormat::SignedInt); + nearest.setSampleSize(16); + nearest.setCodec(tr("audio/pcm")); + } else { + nearest.setFrequency(11025); + nearest.setChannels(1); + nearest.setSampleType(QAudioFormat::SignedInt); + nearest.setSampleSize(8); + nearest.setCodec(tr("audio/pcm")); + } + return nearest; +} + +QAudioFormat QAudioDeviceInfoPrivate::nearestFormat(const QAudioFormat& format) const +{ + if(testSettings(format)) + return format; + else + return preferredFormat(); +} + +QString QAudioDeviceInfoPrivate::deviceName() const +{ + return device; +} + +QStringList QAudioDeviceInfoPrivate::codecList() +{ + updateLists(); + return codecz; +} + +QList QAudioDeviceInfoPrivate::frequencyList() +{ + updateLists(); + return freqz; +} + +QList QAudioDeviceInfoPrivate::channelsList() +{ + updateLists(); + return channelz; +} + +QList QAudioDeviceInfoPrivate::sampleSizeList() +{ + updateLists(); + return sizez; +} + +QList QAudioDeviceInfoPrivate::byteOrderList() +{ + updateLists(); + return byteOrderz; +} + +QList QAudioDeviceInfoPrivate::sampleTypeList() +{ + updateLists(); + return typez; +} + + +bool QAudioDeviceInfoPrivate::open() +{ + return true; +} + +void QAudioDeviceInfoPrivate::close() +{ +} + +bool QAudioDeviceInfoPrivate::testSettings(const QAudioFormat& format) const +{ + // Set nearest to closest settings that do work. + // See if what is in settings will work (return value). + + bool testChannel = false; + bool testCodec = false; + bool testFreq = false; + + int err = 0; + + // For now, just accept only audio/pcm codec + if(!format.codec().startsWith(tr("audio/pcm"))) { + err=-1; + } else + testCodec = true; + + if(err>=0 && format.channels() != -1) { + testChannel = true; + } + + if(err>=0 && format.frequency() != -1) { + testFreq = true; + } + + if(err == 0) { + // settings work + return true; + } + return false; +} + +void QAudioDeviceInfoPrivate::updateLists() +{ + // redo all lists based on current settings + bool base = false; + bool match = false; + DWORD fmt = NULL; + QString tmp; + + if(device.compare(tr("default")) == 0) + base = true; + + if(mode == QAudio::AudioOutput) { + WAVEOUTCAPS woc; + unsigned long iNumDevs,i; + iNumDevs = waveOutGetNumDevs(); + for(i=0;i QAudioDeviceInfoPrivate::deviceList(QAudio::Mode mode) +{ + Q_UNUSED(mode) + + QList devices; + + devices.append("default"); + + if(mode == QAudio::AudioOutput) { + WAVEOUTCAPS woc; + unsigned long iNumDevs,i; + iNumDevs = waveOutGetNumDevs(); + for(i=0;i +#include +#include +#include + +#include +#include + + +const unsigned int MAX_SAMPLE_RATES = 5; +const unsigned int SAMPLE_RATES[] = { 8000, 11025, 22050, 44100, 48000 }; + +class QAudioDeviceInfoPrivate : public QAbstractAudioDeviceInfo +{ + Q_OBJECT + +public: + QAudioDeviceInfoPrivate(QByteArray dev,QAudio::Mode mode); + ~QAudioDeviceInfoPrivate(); + + bool open(); + void close(); + + bool testSettings(const QAudioFormat& format) const; + void updateLists(); + QAudioFormat preferredFormat() const; + bool isFormatSupported(const QAudioFormat& format) const; + QAudioFormat nearestFormat(const QAudioFormat& format) const; + QString deviceName() const; + QStringList codecList(); + QList frequencyList(); + QList channelsList(); + QList sampleSizeList(); + QList byteOrderList(); + QList sampleTypeList(); + static QByteArray defaultInputDevice(); + static QByteArray defaultOutputDevice(); + static QList deviceList(QAudio::Mode); + +private: + QAudio::Mode mode; + QString device; + QAudioFormat nearest; + QList freqz; + QList channelz; + QList sizez; + QList byteOrderz; + QStringList codecz; + QList typez; +}; + +#endif diff --git a/src/multimedia/audio/qaudioengine.cpp b/src/multimedia/audio/qaudioengine.cpp new file mode 100644 index 0000000..930977e --- /dev/null +++ b/src/multimedia/audio/qaudioengine.cpp @@ -0,0 +1,343 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QAbstractAudioDeviceInfo + \brief The QAbstractAudioDeviceInfo class provides access for QAudioDeviceInfo to access the audio + device provided by the plugin. + \internal + + \ingroup multimedia + + This class implements the audio functionality for + QAudioDeviceInfo, i.e., QAudioDeviceInfo keeps a + QAbstractAudioDeviceInfo and routes function calls to it. For a + description of the functionality that QAbstractAudioDeviceInfo + implements, you can read the class and functions documentation of + QAudioDeviceInfo. + + \sa QAudioDeviceInfo +*/ + +/*! + \fn virtual QAudioFormat QAbstractAudioDeviceInfo::preferredFormat() const + Returns the nearest settings. +*/ + +/*! + \fn virtual bool QAbstractAudioDeviceInfo::isFormatSupported(const QAudioFormat& format) const + Returns true if \a format is available from audio device. +*/ + +/*! + \fn virtual QAudioFormat QAbstractAudioDeviceInfo::nearestFormat(const QAudioFormat& format) const + Returns the nearest settings \a format. +*/ + +/*! + \fn virtual QString QAbstractAudioDeviceInfo::deviceName() const + Returns the audio device name. +*/ + +/*! + \fn virtual QStringList QAbstractAudioDeviceInfo::codecList() + Returns the list of currently available codecs. +*/ + +/*! + \fn virtual QList QAbstractAudioDeviceInfo::frequencyList() + Returns the list of currently available frequencies. +*/ + +/*! + \fn virtual QList QAbstractAudioDeviceInfo::channelsList() + Returns the list of currently available channels. +*/ + +/*! + \fn virtual QList QAbstractAudioDeviceInfo::sampleSizeList() + Returns the list of currently available sample sizes. +*/ + +/*! + \fn virtual QList QAbstractAudioDeviceInfo::byteOrderList() + Returns the list of currently available byte orders. +*/ + +/*! + \fn virtual QList QAbstractAudioDeviceInfo::sampleTypeList() + Returns the list of currently available sample types. +*/ + +/*! + \class QAbstractAudioOutput + \brief The QAbstractAudioOutput class provides access for QAudioOutput to access the audio + device provided by the plugin. + \internal + + \ingroup multimedia + + QAbstractAudioOutput implements audio functionality for + QAudioOutput, i.e., QAudioOutput routes function calls to + QAbstractAudioOutput. For a description of the functionality that + is implemented, see the QAudioOutput class and function + descriptions. + + \sa QAudioOutput +*/ + +/*! + \fn virtual QIODevice* QAbstractAudioOutput::start(QIODevice* device) + Uses the \a device as the QIODevice to transfer data. If \a device is null then the class + creates an internal QIODevice. Returns a pointer to the QIODevice being used to handle + the data transfer. This QIODevice can be used to write() audio data directly. Passing a + QIODevice allows the data to be transfered without any extra code. +*/ + +/*! + \fn virtual void QAbstractAudioOutput::stop() + Stops the audio output. +*/ + +/*! + \fn virtual void QAbstractAudioOutput::reset() + Drops all audio data in the buffers, resets buffers to zero. +*/ + +/*! + \fn virtual void QAbstractAudioOutput::suspend() + Stops processing audio data, preserving buffered audio data. +*/ + +/*! + \fn virtual void QAbstractAudioOutput::resume() + Resumes processing audio data after a suspend() +*/ + +/*! + \fn virtual int QAbstractAudioOutput::bytesFree() const + Returns the free space available in bytes in the audio buffer. +*/ + +/*! + \fn virtual int QAbstractAudioOutput::periodSize() const + Returns the period size in bytes. +*/ + +/*! + \fn virtual void QAbstractAudioOutput::setBufferSize(int value) + Sets the audio buffer size to \a value in bytes. +*/ + +/*! + \fn virtual int QAbstractAudioOutput::bufferSize() const + Returns the audio buffer size in bytes. +*/ + +/*! + \fn virtual void QAbstractAudioOutput::setNotifyInterval(int ms) + Sets the interval for notify() signal to be emitted. This is based on the \a ms + of audio data processed not on actual real-time. The resolution of the timer + is platform specific. +*/ + +/*! + \fn virtual int QAbstractAudioOutput::notifyInterval() const + Returns the notify interval in milliseconds. +*/ + +/*! + \fn virtual qint64 QAbstractAudioOutput::totalTime() const + Returns the amount of audio data processed since start() was called in milliseconds. +*/ + +/*! + \fn virtual qint64 QAbstractAudioOutput::clock() const + Returns the milliseconds since start() was called, including time in Idle and suspend states. +*/ + +/*! + \fn virtual QAudio::Error QAbstractAudioOutput::error() const + Returns the error state. +*/ + +/*! + \fn virtual QAudio::State QAbstractAudioOutput::state() const + Returns the state of audio processing. +*/ + +/*! + \fn virtual QAudioFormat QAbstractAudioOutput::format() const + Returns the QAudioFormat being used. +*/ + +/*! + \fn QAbstractAudioOutput::stateChanged(QAudio::State state) + This signal is emitted when the device \a state has changed. +*/ + +/*! + \fn QAbstractAudioOutput::notify() + This signal is emitted when x ms of audio data has been processed + the interval set by setNotifyInterval(x). +*/ + + +/*! + \class QAbstractAudioInput + \brief The QAbstractAudioInput class provides access for QAudioInput to access the audio + device provided by the plugin. + \internal + + \ingroup multimedia + + QAudioDeviceInput keeps an instance of QAbstractAudioInput and + routes calls to functions of the same name to QAbstractAudioInput. + This means that it is QAbstractAudioInput that implements the + audio functionality. For a description of the functionality, see + the QAudioInput class description. + + \sa QAudioInput +*/ + +/*! + \fn virtual QIODevice* QAbstractAudioInput::start(QIODevice* device) + Uses the \a device as the QIODevice to transfer data. If \a device is null + then the class creates an internal QIODevice. Returns a pointer to the + QIODevice being used to handle the data transfer. This QIODevice can be used to + read() audio data directly. Passing a QIODevice allows the data to be transfered + without any extra code. +*/ + +/*! + \fn virtual void QAbstractAudioInput::stop() + Stops the audio input. +*/ + +/*! + \fn virtual void QAbstractAudioInput::reset() + Drops all audio data in the buffers, resets buffers to zero. +*/ + +/*! + \fn virtual void QAbstractAudioInput::suspend() + Stops processing audio data, preserving buffered audio data. +*/ + +/*! + \fn virtual void QAbstractAudioInput::resume() + Resumes processing audio data after a suspend(). +*/ + +/*! + \fn virtual int QAbstractAudioInput::bytesReady() const + Returns the amount of audio data available to read in bytes. +*/ + +/*! + \fn virtual int QAbstractAudioInput::periodSize() const + Returns the period size in bytes. +*/ + +/*! + \fn virtual void QAbstractAudioInput::setBufferSize(int value) + Sets the audio buffer size to \a value in milliseconds. +*/ + +/*! + \fn virtual int QAbstractAudioInput::bufferSize() const + Returns the audio buffer size in milliseconds. +*/ + +/*! + \fn virtual void QAbstractAudioInput::setNotifyInterval(int ms) + Sets the interval for notify() signal to be emitted. This is based + on the \a ms of audio data processed not on actual real-time. + The resolution of the timer is platform specific. +*/ + +/*! + \fn virtual int QAbstractAudioInput::notifyInterval() const + Returns the notify interval in milliseconds. +*/ + +/*! + \fn virtual qint64 QAbstractAudioInput::totalTime() const + Returns the amount of audio data processed since start() was called in milliseconds. +*/ + +/*! + \fn virtual qint64 QAbstractAudioInput::clock() const + Returns the milliseconds since start() was called, including time in Idle and suspend states. +*/ + +/*! + \fn virtual QAudio::Error QAbstractAudioInput::error() const + Returns the error state. +*/ + +/*! + \fn virtual QAudio::State QAbstractAudioInput::state() const + Returns the state of audio processing. +*/ + +/*! + \fn virtual QAudioFormat QAbstractAudioInput::format() const + Returns the QAudioFormat being used +*/ + +/*! + \fn QAbstractAudioInput::stateChanged(QAudio::State state) + This signal is emitted when the device \a state has changed. +*/ + +/*! + \fn QAbstractAudioInput::notify() + This signal is emitted when x ms of audio data has been processed + the interval set by setNotifyInterval(x). +*/ + + +QT_END_NAMESPACE diff --git a/src/multimedia/audio/qaudioengine.h b/src/multimedia/audio/qaudioengine.h new file mode 100644 index 0000000..b0aa762 --- /dev/null +++ b/src/multimedia/audio/qaudioengine.h @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QAUDIOENGINE_H +#define QAUDIOENGINE_H + +#include +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +class Q_MULTIMEDIA_EXPORT QAbstractAudioDeviceInfo : public QObject +{ + Q_OBJECT + +public: + virtual QAudioFormat preferredFormat() const = 0; + virtual bool isFormatSupported(const QAudioFormat &format) const = 0; + virtual QAudioFormat nearestFormat(const QAudioFormat &format) const = 0; + virtual QString deviceName() const = 0; + virtual QStringList codecList() = 0; + virtual QList frequencyList() = 0; + virtual QList channelsList() = 0; + virtual QList sampleSizeList() = 0; + virtual QList byteOrderList() = 0; + virtual QList sampleTypeList() = 0; +}; + +class Q_MULTIMEDIA_EXPORT QAbstractAudioOutput : public QObject +{ + Q_OBJECT + +public: + virtual QIODevice* start(QIODevice* device) = 0; + virtual void stop() = 0; + virtual void reset() = 0; + virtual void suspend() = 0; + virtual void resume() = 0; + virtual int bytesFree() const = 0; + virtual int periodSize() const = 0; + virtual void setBufferSize(int value) = 0; + virtual int bufferSize() const = 0; + virtual void setNotifyInterval(int milliSeconds) = 0; + virtual int notifyInterval() const = 0; + virtual qint64 totalTime() const = 0; + virtual qint64 clock() const = 0; + virtual QAudio::Error error() const = 0; + virtual QAudio::State state() const = 0; + virtual QAudioFormat format() const = 0; + +Q_SIGNALS: + void stateChanged(QAudio::State); + void notify(); +}; + +class Q_MULTIMEDIA_EXPORT QAbstractAudioInput : public QObject +{ + Q_OBJECT + +public: + virtual QIODevice* start(QIODevice* device) = 0; + virtual void stop() = 0; + virtual void reset() = 0; + virtual void suspend() = 0; + virtual void resume() = 0; + virtual int bytesReady() const = 0; + virtual int periodSize() const = 0; + virtual void setBufferSize(int value) = 0; + virtual int bufferSize() const = 0; + virtual void setNotifyInterval(int milliSeconds) = 0; + virtual int notifyInterval() const = 0; + virtual qint64 totalTime() const = 0; + virtual qint64 clock() const = 0; + virtual QAudio::Error error() const = 0; + virtual QAudio::State state() const = 0; + virtual QAudioFormat format() const = 0; + +Q_SIGNALS: + void stateChanged(QAudio::State); + void notify(); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QAUDIOENGINE_H diff --git a/src/multimedia/audio/qaudioengineplugin.cpp b/src/multimedia/audio/qaudioengineplugin.cpp new file mode 100644 index 0000000..6e39004 --- /dev/null +++ b/src/multimedia/audio/qaudioengineplugin.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include + +QT_BEGIN_NAMESPACE + +QAudioEnginePlugin::QAudioEnginePlugin(QObject* parent) : + QObject(parent) +{} + +QAudioEnginePlugin::~QAudioEnginePlugin() +{} + +QT_END_NAMESPACE diff --git a/src/multimedia/audio/qaudioengineplugin.h b/src/multimedia/audio/qaudioengineplugin.h new file mode 100644 index 0000000..8eab2d7 --- /dev/null +++ b/src/multimedia/audio/qaudioengineplugin.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#ifndef QAUDIOENGINEPLUGIN_H +#define QAUDIOENGINEPLUGIN_H + +#include +#include +#include + +#include +#include +#include + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +struct Q_MULTIMEDIA_EXPORT QAudioEngineFactoryInterface : public QFactoryInterface +{ + virtual QList deviceList(QAudio::Mode) const = 0; + virtual QAbstractAudioInput* createInput(const QByteArray& device, const QAudioFormat& format = QAudioFormat()) = 0; + virtual QAbstractAudioOutput* createOutput(const QByteArray& device, const QAudioFormat& format = QAudioFormat()) = 0; + virtual QAbstractAudioDeviceInfo* createDeviceInfo(const QByteArray& device, QAudio::Mode mode) = 0; +}; + +#define QAudioEngineFactoryInterface_iid \ + "com.nokia.qt.QAudioEngineFactoryInterface" +Q_DECLARE_INTERFACE(QAudioEngineFactoryInterface, QAudioEngineFactoryInterface_iid) + +class Q_MULTIMEDIA_EXPORT QAudioEnginePlugin : public QObject, public QAudioEngineFactoryInterface +{ + Q_OBJECT + Q_INTERFACES(QAudioEngineFactoryInterface:QFactoryInterface) + +public: + QAudioEnginePlugin(QObject *parent = 0); + ~QAudioEnginePlugin(); + + virtual QStringList keys() const = 0; + virtual QList deviceList(QAudio::Mode) const = 0; + virtual QAbstractAudioInput* createInput(const QByteArray& device, const QAudioFormat& format = QAudioFormat()) = 0; + virtual QAbstractAudioOutput* createOutput(const QByteArray& device, const QAudioFormat& format = QAudioFormat()) = 0; + virtual QAbstractAudioDeviceInfo* createDeviceInfo(const QByteArray& device, QAudio::Mode mode) = 0; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QAUDIOENGINEPLUGIN_H diff --git a/src/multimedia/audio/qaudioformat.cpp b/src/multimedia/audio/qaudioformat.cpp new file mode 100644 index 0000000..6632c63 --- /dev/null +++ b/src/multimedia/audio/qaudioformat.cpp @@ -0,0 +1,335 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + + +QT_BEGIN_NAMESPACE + + +class QAudioFormatPrivate : public QSharedData +{ +public: + QAudioFormatPrivate() + { + frequency = -1; + channels = -1; + sampleSize = -1; + byteOrder = QAudioFormat::Endian(QSysInfo::ByteOrder); + sampleType = QAudioFormat::Unknown; + } + + QString codec; + QAudioFormat::Endian byteOrder; + QAudioFormat::SampleType sampleType; + + int frequency; + int channels; + int sampleSize; +}; + +/*! + \class QAudioFormat + \brief The QAudioFormat class stores audio parameter information. + + \inmodule QtMultimedia + \ingroup multimedia + \since 4.6 + + An audio format specifies how data in an audio stream is arranged, + i.e, how the stream is to be interpreted. The encoding itself is + specified by the codec() used for the stream. + + In addition to the encoding, QAudioFormat contains other + parameters that further specify how the audio data is arranged. + These are the frequency, the number of channels, the sample size, + the sample type, and the byte order. The following table describes + these in more detail. + + \table + \header + \o Parameter + \o Description + \row + \o Frequency + \o Samples per second of audio data in Hertz. + \row + \o Number of channels + \o The number of audio channels (typically one for mono + or two for stereo) + \row + \o Sample size + \o How much data is stored in each sample (typically 8 + or 16) + \row + \o Sample type + \o Numerical representation of sample (typically signed integer, + unsigned integer or float) + \row + \o Byte order + \o Byte ordering of sample (typically little endian, big endian) + \endtable + + You can obtain audio formats compatible with the audio device used + through functions in QAudioDeviceInfo. This class also lets you + query available parameter values for a device, so that you can set + the parameters yourself. See the QAudioDeviceInfo class + description for details. +*/ + +/*! + Construct a new audio format. + + Values are initialized as follows: + \list + \o frequency() = -1 + \o channels() = -1 + \o sampleSize() = -1 + \o byteOrder() = QAudioFormat::Endian(QSysInfo::ByteOrder) + \o sampleType() = QAudioFormat::Unknown + \c codec() = "" + \endlist +*/ + +QAudioFormat::QAudioFormat(): + d(new QAudioFormatPrivate) +{ +} + +/*! + Construct a new audio format using \a other. +*/ + +QAudioFormat::QAudioFormat(const QAudioFormat &other): + d(other.d) +{ +} + +/*! + Destroy this audio format. +*/ + +QAudioFormat::~QAudioFormat() +{ +} + +/*! + Assigns \a other to this QAudioFormat implementation. +*/ + +QAudioFormat& QAudioFormat::operator=(const QAudioFormat &other) +{ + d = other.d; + return *this; +} + +/*! + Returns true if this QAudioFormat is equal to the \a other + QAudioFormat; otherwise returns false. + + All elements of QAudioFormat are used for the comparison. +*/ + +bool QAudioFormat::operator==(const QAudioFormat &other) const +{ + return d->frequency == other.d->frequency && + d->channels == other.d->channels && + d->sampleSize == other.d->sampleSize && + d->byteOrder == other.d->byteOrder && + d->codec == other.d->codec && + d->sampleType == other.d->sampleType; +} + +/*! + Returns true if this QAudioFormat is not equal to the \a other + QAudioFormat; otherwise returns false. + + All elements of QAudioFormat are used for the comparison. +*/ + +bool QAudioFormat::operator!=(const QAudioFormat& other) const +{ + return !(*this == other); +} + +/*! + Returns true if any of the parameters are invalid. +*/ + +bool QAudioFormat::isNull() const +{ + return d->frequency == -1 && d->channels == -1 && + d->sampleSize == -1 && + d->byteOrder == QAudioFormat::Endian(QSysInfo::ByteOrder) && + d->sampleType == QAudioFormat::Unknown && + d->codec.isNull(); +} + +/*! + Sets the frequency to \a frequency. +*/ + +void QAudioFormat::setFrequency(int frequency) +{ + d->frequency = frequency; +} + +/*! + Returns the current frequency value. +*/ + +int QAudioFormat::frequency() const +{ + return d->frequency; +} + +/*! + Sets the channels to \a channels. +*/ + +void QAudioFormat::setChannels(int channels) +{ + d->channels = channels; +} + +/*! + Returns the current channel value. +*/ + +int QAudioFormat::channels() const +{ + return d->channels; +} + +/*! + Sets the sampleSize to \a sampleSize. +*/ + +void QAudioFormat::setSampleSize(int sampleSize) +{ + d->sampleSize = sampleSize; +} + +/*! + Returns the current sampleSize value. +*/ + +int QAudioFormat::sampleSize() const +{ + return d->sampleSize; +} + +/*! + Sets the codec to \a codec. + + \sa QAudioDeviceInfo::supportedCodecs() +*/ + +void QAudioFormat::setCodec(QString codec) +{ + d->codec = codec; +} + +/*! + Returns the current codec value. + + \sa QAudioDeviceInfo::supportedCodecs() +*/ + +QString QAudioFormat::codec() const +{ + return d->codec; +} + +/*! + Sets the byteOrder to \a byteOrder. +*/ + +void QAudioFormat::setByteOrder(QAudioFormat::Endian byteOrder) +{ + d->byteOrder = byteOrder; +} + +/*! + Returns the current byteOrder value. +*/ + +QAudioFormat::Endian QAudioFormat::byteOrder() const +{ + return d->byteOrder; +} + +/*! + Sets the sampleType to \a sampleType. +*/ + +void QAudioFormat::setSampleType(QAudioFormat::SampleType sampleType) +{ + d->sampleType = sampleType; +} + +/*! + Returns the current SampleType value. +*/ + +QAudioFormat::SampleType QAudioFormat::sampleType() const +{ + return d->sampleType; +} + +/*! + \enum QAudioFormat::SampleType + + \value Unknown Not Set + \value SignedInt samples are signed integers + \value UnSignedInt samples are unsigned intergers + \value Float samples are floats +*/ + +/*! + \enum QAudioFormat::Endian + + \value BigEndian samples are big endian byte order + \value LittleEndian samples are little endian byte order +*/ + +QT_END_NAMESPACE + diff --git a/src/multimedia/audio/qaudioformat.h b/src/multimedia/audio/qaudioformat.h new file mode 100644 index 0000000..c740969 --- /dev/null +++ b/src/multimedia/audio/qaudioformat.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#ifndef QAUDIOFORMAT_H +#define QAUDIOFORMAT_H + +#include +#include +#include + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + + +class QAudioFormatPrivate; + +class Q_MULTIMEDIA_EXPORT QAudioFormat +{ +public: + enum SampleType { Unknown, SignedInt, UnSignedInt, Float }; + enum Endian { BigEndian = QSysInfo::BigEndian, LittleEndian = QSysInfo::LittleEndian }; + + QAudioFormat(); + QAudioFormat(const QAudioFormat &other); + ~QAudioFormat(); + + QAudioFormat& operator=(const QAudioFormat &other); + bool operator==(const QAudioFormat &other) const; + bool operator!=(const QAudioFormat &other) const; + + bool isNull() const; + + void setFrequency(int frequency); + int frequency() const; + + void setChannels(int channels); + int channels() const; + + void setSampleSize(int sampleSize); + int sampleSize() const; + + void setCodec(QString codec); + QString codec() const; + + void setByteOrder(QAudioFormat::Endian byteOrder); + QAudioFormat::Endian byteOrder() const; + + void setSampleType(QAudioFormat::SampleType sampleType); + QAudioFormat::SampleType sampleType() const; + +private: + QSharedDataPointer d; +}; + + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QAUDIOFORMAT_H diff --git a/src/multimedia/audio/qaudioinput.cpp b/src/multimedia/audio/qaudioinput.cpp new file mode 100644 index 0000000..17cacc6 --- /dev/null +++ b/src/multimedia/audio/qaudioinput.cpp @@ -0,0 +1,400 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include +#include +#include + +#include "qaudiodevicefactory_p.h" + + +QT_BEGIN_NAMESPACE + +/*! + \class QAudioInput + \brief The QAudioInput class provides an interface for receiving audio data from an audio input device. + + \inmodule QtMultimedia + \ingroup multimedia + \since 4.6 + + You can construct an audio input with the system's + \l{QAudioDeviceInfo::defaultInputDevice()}{default audio input + device}. It is also possible to create QAudioInput with a + specific QAudioDeviceId. When you create the audio input, you + should also send in the QAudioFormat to be used for the recording + (see the QAudioFormat class description for details). + + To record to a file: + + QAudioInput lets you record audio with an audio input device. The + default constructor of this class will use the systems default + audio device, but you can also specify a QAudioDeviceId for a + specific device. You also need to pass in the QAudioFormat in + which you wish to record. + + Starting up the QAudioInput is simply a matter of calling start() + with a QIODevice opened for writing. For instance, to record to a + file, you can: + + \code + { + QFile outputFile; + outputFile.setFileName("/tmp/test.raw"); + outputFile.open( QIODevice::WriteOnly | QIODevice::Truncate ); + + QAudioFormat format; + // set up the format you want, eg. + format.setFrequency(8000); + format.setChannels(1); + format.setSampleSize(8); + format.setCodec("audio/pcm"); + format.setByteOrder(QAudioFormat::LittleEndian); + format.setSampleType(QAudioFormat::UnSignedInt); + + QAudioInput *audio = new QAudioInput(format, this); + QTimer::singleShot(3000, this, SLOT(stopRecording())); + audio->start(outputFile); + // Records audio for 3000ms + } + \endcode + + This will start recording if the format specified is supported by + the input device (you can check this with + QAudioDeviceInfo::isFormatSupported(). In case there are any + snags, use the error() function to check what went wrong. We stop + recording in the \c stopRecording() slot. + + \code + void stopRecording() + { + audio->stop(); + outputFile->close(); + } + \endcode + + At any point in time, QAudioInput will be in one of four states: + active, suspended, stopped, or idle. These states are specified by + the QAudio::State enum. You can request a state change directly through + suspend(), resume(), stop(), reset(), and start(). The current + state is reported by state(). QAudioOutput will also signal you + when the state changes (stateChanged()). + + QAudioInput provides several ways of measuring the time that has + passed since the start() of the recording. The \c totalTime() + function returns the length of the stream in microseconds written, + i.e., it leaves out the times the audio input was suspended or idle. + The clock() function returns the time elapsed since start() was called regardless of + which states the QAudioInput has been in. + + If an error should occur, you can fetch its reason with error(). + The possible error reasons are described by the QAudio::Error enum. + + \sa QAudioOutput, QAudioDeviceInfo +*/ + +/*! + Construct a new audio input and attach it to \a parent. + The default audio input device is used with the output + \a format parameters. +*/ + +QAudioInput::QAudioInput(const QAudioFormat &format, QObject *parent): + QObject(parent) +{ + d = QAudioDeviceFactory::createDefaultInputDevice(format); + connect(d, SIGNAL(notify()), SIGNAL(notify())); + connect(d, SIGNAL(stateChanged(QAudio::State)), SIGNAL(stateChanged(QAudio::State))); +} + +/*! + Construct a new audio input and attach it to \a parent. + The \a id of the audio input device is used with the input + \a format parameters. +*/ + +QAudioInput::QAudioInput(const QAudioDeviceId &id, const QAudioFormat &format, QObject *parent): + QObject(parent) +{ + d = QAudioDeviceFactory::createInputDevice(id, format); + connect(d, SIGNAL(notify()), SIGNAL(notify())); + connect(d, SIGNAL(stateChanged(QAudio::State)), SIGNAL(stateChanged(QAudio::State))); +} + +/*! + Destroy this audio input. +*/ + +QAudioInput::~QAudioInput() +{ + delete d; +} + +/*! + Uses the \a device as the QIODevice to transfer data. + If \a device is null then the class creates an internal QIODevice. + Returns a pointer to the QIODevice being used to handle the data + transfer. This QIODevice can be used to read() audio data + directly. + Passing a QIODevice allows the data to be transfered without any extra code. + All that is required is to open the QIODevice. + + /sa QIODevice +*/ + +QIODevice* QAudioInput::start(QIODevice* device) +{ + /* + PULL MODE (valid QIODevice) + -If currently not StopState, stop + -If previous start was push mode, delete internal QIODevice. + -open audio input. + If ok, NoError and ActiveState, else OpenError and StopState. + -emit stateChanged() + -return device + + PUSH MODE (device = 0) + -If currently not StopState, stop + -If no internal QIODevice, create one. + -open audio input. + -If ok, NoError and IdleState, else OpenError and StopState + -emit stateChanged() + -return internal QIODevice + */ + return d->start(device); +} + +/*! + Returns the QAudioFormat being used. +*/ + +QAudioFormat QAudioInput::format() const +{ + return d->format(); +} + +/*! + Stops the audio input. +*/ + +void QAudioInput::stop() +{ + /* + -If StopState, return + -set to StopState + -detach from audio device + -emit stateChanged() + */ + d->stop(); +} + +/*! + Drops all audio data in the buffers, resets buffers to zero. +*/ + +void QAudioInput::reset() +{ + /* + -drop all buffered audio, set buffers to zero. + -call stop() + */ + d->reset(); +} + +/*! + Stops processing audio data, preserving buffered audio data. +*/ + +void QAudioInput::suspend() +{ + /* + -If not ActiveState|IdleState, return + -stop processing audio, saving all buffered audio data + -set NoError and SuspendState + -emit stateChanged() + */ + d->suspend(); +} + +/*! + Resumes processing audio data after a suspend(). +*/ + +void QAudioInput::resume() +{ + /* + -If SuspendState, return + -resume audio + -(PULL MODE): set ActiveState, NoError + -(PUSH MODE): set IdleState, NoError + -kick start audio if needed + -emit stateChanged() + */ + d->resume(); +} + +/*! + Sets the audio buffer size to \a value milliseconds. + + Note: This function can be called anytime before start(), calls to this + are ignored after start(). It should not be assumed that the buffer size + set is the actual buffer size used, calling bufferSize() anytime after start() + will return the actual buffer size being used. + +*/ + +void QAudioInput::setBufferSize(int value) +{ + d->setBufferSize(value); +} + +/*! + Returns the audio buffer size in milliseconds. + + If called before start(), returns platform default value. + If called before start() but setBufferSize() was called prior, returns value set by setBufferSize(). + If called after start(), returns the actual buffer size being used. This may not be what was set previously + by setBufferSize(). + +*/ + +int QAudioInput::bufferSize() const +{ + return d->bufferSize(); +} + +/*! + Returns the amount of audio data available to read in bytes. +*/ + +int QAudioInput::bytesReady() const +{ + /* + -If not ActiveState|IdleState, return 0 + -return amount of audio data available to read + */ + return d->bytesReady(); +} + +/*! + Returns the period size in bytes. + + Note: This is the recommended read size in bytes. +*/ + +int QAudioInput::periodSize() const +{ + return d->periodSize(); +} + +/*! + Sets the interval for notify() signal to be emitted. + This is based on the \a ms of audio data processed + not on actual real-time. The resolution of the timer is platform specific. +*/ + +void QAudioInput::setNotifyInterval(int ms) +{ + d->setNotifyInterval(ms); +} + +/*! + Returns the notify interval in milliseconds. +*/ + +int QAudioInput::notifyInterval() const +{ + return d->notifyInterval(); +} + +/*! + Returns the amount of audio data processed since start() + was called in microseconds. +*/ + +qint64 QAudioInput::totalTime() const +{ + return d->totalTime(); +} + +/*! + Returns the microseconds since start() was called, including time in Idle and + Suspend states. +*/ + +qint64 QAudioInput::clock() const +{ + return d->clock(); +} + +/*! + Returns the error state. +*/ + +QAudio::Error QAudioInput::error() const +{ + return d->error(); +} + +/*! + Returns the state of audio processing. +*/ + +QAudio::State QAudioInput::state() const +{ + return d->state(); +} + +/*! + \fn QAudioInput::stateChanged(QAudio::State state) + This signal is emitted when the device \a state has changed. +*/ + +/*! + \fn QAudioInput::notify() + This signal is emitted when x ms of audio data has been processed + the interval set by setNotifyInterval(x). +*/ + +QT_END_NAMESPACE + diff --git a/src/multimedia/audio/qaudioinput.h b/src/multimedia/audio/qaudioinput.h new file mode 100644 index 0000000..b0f1aed --- /dev/null +++ b/src/multimedia/audio/qaudioinput.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#ifndef QAUDIOINPUT_H +#define QAUDIOINPUT_H + +#include +#include + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + + +class QAbstractAudioInput; + +class Q_MULTIMEDIA_EXPORT QAudioInput : public QObject +{ + Q_OBJECT + +public: + explicit QAudioInput(const QAudioFormat &format = QAudioFormat(), QObject *parent = 0); + explicit QAudioInput(const QAudioDeviceId &id, const QAudioFormat &format = QAudioFormat(), QObject *parent = 0); + ~QAudioInput(); + + QAudioFormat format() const; + + QIODevice* start(QIODevice *device = 0); + void stop(); + void reset(); + void suspend(); + void resume(); + + void setBufferSize(int bytes); + int bufferSize() const; + + int bytesReady() const; + int periodSize() const; + + void setNotifyInterval(int milliSeconds); + int notifyInterval() const; + + qint64 totalTime() const; + qint64 clock() const; + + QAudio::Error error() const; + QAudio::State state() const; + +Q_SIGNALS: + void stateChanged(QAudio::State); + void notify(); + +private: + Q_DISABLE_COPY(QAudioInput); + + QAbstractAudioInput* d; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QAUDIOINPUT_H diff --git a/src/multimedia/audio/qaudioinput_alsa_p.cpp b/src/multimedia/audio/qaudioinput_alsa_p.cpp new file mode 100644 index 0000000..6f00469 --- /dev/null +++ b/src/multimedia/audio/qaudioinput_alsa_p.cpp @@ -0,0 +1,688 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include "qaudioinput_alsa_p.h" + +//#define DEBUG_AUDIO 1 + +QAudioInputPrivate::QAudioInputPrivate(const QByteArray &device, const QAudioFormat& audioFormat): + settings(audioFormat) +{ + bytesAvailable = 0; + handle = 0; + ahandler = 0; + access = SND_PCM_ACCESS_RW_INTERLEAVED; + pcmformat = SND_PCM_FORMAT_S16; + buffer_size = 0; + period_size = 0; + buffer_time = 100000; + period_time = 20000; + totalTimeValue = 0; + intervalTime = 1000; + audioBuffer = 0; + errorState = QAudio::NoError; + deviceState = QAudio::StopState; + audioSource = 0; + pullMode = true; + resuming = false; + + QStringList list1 = QString(tr(device)).split(tr(":")); + m_device = QByteArray(list1.at(0).toLocal8Bit().constData()); + + timer = new QTimer(this); + connect(timer,SIGNAL(timeout()),SLOT(userFeed())); +} + +QAudioInputPrivate::~QAudioInputPrivate() +{ + close(); + disconnect(timer, SIGNAL(timeout())); + QCoreApplication::processEvents(); + delete timer; +} + +QAudio::Error QAudioInputPrivate::error() const +{ + return errorState; +} + +QAudio::State QAudioInputPrivate::state() const +{ + return deviceState; +} + + +QAudioFormat QAudioInputPrivate::format() const +{ + return settings; +} + +int QAudioInputPrivate::xrun_recovery(int err) +{ + int count = 0; + bool reset = false; + + if(err == -EPIPE) { + errorState = QAudio::UnderrunError; + err = snd_pcm_prepare(handle); + if(err < 0) + reset = true; + + } else if((err == -ESTRPIPE)||(err == -EIO)) { + errorState = QAudio::IOError; + while((err = snd_pcm_resume(handle)) == -EAGAIN){ + usleep(100); + count++; + if(count > 5) { + reset = true; + break; + } + } + if(err < 0) { + err = snd_pcm_prepare(handle); + if(err < 0) + reset = true; + } + } + if(reset) { + close(); + open(); + snd_pcm_prepare(handle); + return 0; + } + return err; +} + +int QAudioInputPrivate::setFormat() +{ + snd_pcm_format_t format = SND_PCM_FORMAT_S16; + + if(settings.sampleSize() == 8) { + format = SND_PCM_FORMAT_U8; + } else if(settings.sampleSize() == 16) { + if(settings.sampleType() == QAudioFormat::SignedInt) { + if(settings.byteOrder() == QAudioFormat::LittleEndian) + format = SND_PCM_FORMAT_S16_LE; + else + format = SND_PCM_FORMAT_S16_BE; + } else if(settings.sampleType() == QAudioFormat::UnSignedInt) { + if(settings.byteOrder() == QAudioFormat::LittleEndian) + format = SND_PCM_FORMAT_U16_LE; + else + format = SND_PCM_FORMAT_U16_BE; + } + } else if(settings.sampleSize() == 24) { + if(settings.sampleType() == QAudioFormat::SignedInt) { + if(settings.byteOrder() == QAudioFormat::LittleEndian) + format = SND_PCM_FORMAT_S24_LE; + else + format = SND_PCM_FORMAT_S24_BE; + } else if(settings.sampleType() == QAudioFormat::UnSignedInt) { + if(settings.byteOrder() == QAudioFormat::LittleEndian) + format = SND_PCM_FORMAT_U24_LE; + else + format = SND_PCM_FORMAT_U24_BE; + } + } else if(settings.sampleSize() == 32) { + if(settings.sampleType() == QAudioFormat::SignedInt) { + if(settings.byteOrder() == QAudioFormat::LittleEndian) + format = SND_PCM_FORMAT_S32_LE; + else + format = SND_PCM_FORMAT_S32_BE; + } else if(settings.sampleType() == QAudioFormat::UnSignedInt) { + if(settings.byteOrder() == QAudioFormat::LittleEndian) + format = SND_PCM_FORMAT_U32_LE; + else + format = SND_PCM_FORMAT_U32_BE; + } else if(settings.sampleType() == QAudioFormat::Float) { + if(settings.byteOrder() == QAudioFormat::LittleEndian) + format = SND_PCM_FORMAT_FLOAT_LE; + else + format = SND_PCM_FORMAT_FLOAT_BE; + } + } else if(settings.sampleSize() == 64) { + if(settings.byteOrder() == QAudioFormat::LittleEndian) + format = SND_PCM_FORMAT_FLOAT64_LE; + else + format = SND_PCM_FORMAT_FLOAT64_BE; + } + + return snd_pcm_hw_params_set_format( handle, hwparams, format); +} + +QIODevice* QAudioInputPrivate::start(QIODevice* device) +{ + if(deviceState != QAudio::StopState) + close(); + + if(!pullMode && audioSource) { + delete audioSource; + } + + if(device) { + //set to pull mode + pullMode = true; + audioSource = device; + } else { + //set to push mode + pullMode = false; + audioSource = new InputPrivate(this); + audioSource->open(QIODevice::ReadOnly | QIODevice::Unbuffered); + } + + if( !open() ) + return 0; + + emit stateChanged(deviceState); + + return audioSource; +} + +void QAudioInputPrivate::stop() +{ + if(deviceState == QAudio::StopState) + return; + + deviceState = QAudio::StopState; + + close(); + emit stateChanged(deviceState); +} + +bool QAudioInputPrivate::open() +{ +#ifdef DEBUG_AUDIO + QTime now(QTime::currentTime()); + qDebug()<start(period_time*chunks/2000); + + errorState = QAudio::NoError; + deviceState = QAudio::ActiveState; + + totalTimeValue = 0; + + return true; +} + +void QAudioInputPrivate::close() +{ + deviceState = QAudio::StopState; + timer->stop(); + + if ( handle ) { + snd_pcm_drop( handle ); + snd_pcm_close( handle ); + handle = 0; + delete [] audioBuffer; + audioBuffer=0; + } +} + +int QAudioInputPrivate::bytesReady() const +{ + if(resuming) + return period_size; + + if(deviceState != QAudio::ActiveState) + return 0; + int frames = snd_pcm_avail_update(handle); + if((int)frames > (int)buffer_frames) + frames = buffer_frames; + + return snd_pcm_frames_to_bytes(handle, frames); +} + +qint64 QAudioInputPrivate::read(char* data, qint64 len) +{ + Q_UNUSED(data) + Q_UNUSED(len) + // Read in some audio data and write it to QIODevice, pull mode + if ( !handle ) + return 0; + + bytesAvailable = bytesReady(); + + int count=0, err = 0; + while(count < 5) { + int chunks = bytesAvailable/period_size; + int frames = chunks*period_frames; + if(frames > (int)buffer_frames) + frames = buffer_frames; + int readFrames = snd_pcm_readi(handle, audioBuffer, frames); + if (readFrames >= 0) { + err = snd_pcm_frames_to_bytes(handle, readFrames); +#ifdef DEBUG_AUDIO + qDebug()< 0) { + // got some send it onward +#ifdef DEBUG_AUDIO + qDebug()<<"PULL: frames to write to QIODevice = "<< + snd_pcm_bytes_to_frames( handle, (int)err )<<" ("<write(audioBuffer,err); + if(l < 0) { + close(); + errorState = QAudio::IOError; + deviceState = QAudio::StopState; + emit stateChanged(deviceState); + } else if(l == 0) { + errorState = QAudio::NoError; + deviceState = QAudio::IdleState; + } else { + totalTimeValue += snd_pcm_bytes_to_frames(handle, err)*1000000/settings.frequency(); + resuming = false; + errorState = QAudio::NoError; + deviceState = QAudio::ActiveState; + } + return l; + } + return 0; +} + +void QAudioInputPrivate::resume() +{ + if(deviceState == QAudio::SuspendState) { + int err = 0; + + if(handle) { + err = snd_pcm_prepare( handle ); + if(err < 0) + xrun_recovery(err); + + err = snd_pcm_start(handle); + if(err < 0) + xrun_recovery(err); + + bytesAvailable = buffer_size; + } + resuming = true; + deviceState = QAudio::ActiveState; + int chunks = buffer_size/period_size; + timer->start(buffer_time*chunks/2000); + emit stateChanged(deviceState); + } +} + +void QAudioInputPrivate::setBufferSize(int value) +{ + buffer_size = value; +} + +int QAudioInputPrivate::bufferSize() const +{ + return buffer_size; +} + +int QAudioInputPrivate::periodSize() const +{ + return period_size; +} + +void QAudioInputPrivate::setNotifyInterval(int ms) +{ + intervalTime = ms; +} + +int QAudioInputPrivate::notifyInterval() const +{ + return intervalTime; +} + +qint64 QAudioInputPrivate::totalTime() const +{ + return totalTimeValue; +} + +void QAudioInputPrivate::suspend() +{ + if(deviceState == QAudio::ActiveState||resuming) { + timer->stop(); + deviceState = QAudio::SuspendState; + emit stateChanged(deviceState); + } +} + +void QAudioInputPrivate::userFeed() +{ + if(deviceState == QAudio::StopState || deviceState == QAudio::SuspendState) + return; +#ifdef DEBUG_AUDIO + QTime now(QTime::currentTime()); + qDebug()<(audioSource); + a->trigger(); + } + bytesAvailable = bytesReady(); + + if(deviceState != QAudio::ActiveState) + return true; + + if(timeStamp.elapsed() > intervalTime && intervalTime > 50) { + emit notify(); + timeStamp.restart(); + } + return true; +} + +qint64 QAudioInputPrivate::clock() const +{ + if(!handle) + return 0; + + if(deviceState != QAudio::ActiveState) + return 0; + + snd_pcm_status_t* status; + snd_pcm_status_alloca(&status); + + snd_timestamp_t t1,t2; + if( snd_pcm_status(handle, status) >= 0) { + snd_pcm_status_get_tstamp(status,&t1); + snd_pcm_status_get_trigger_tstamp(status,&t2); + t1.tv_sec-=t2.tv_sec; + + signed long l = (signed long)t1.tv_usec - (signed long)t2.tv_usec; + if(l < 0) { + t1.tv_sec--; + l = -l; + l %= 1000000; + } + return ((t1.tv_sec * 1000)+l/1000); + } else + return 0; +} + +void QAudioInputPrivate::reset() +{ + if(handle) + snd_pcm_reset(handle); +} + +void QAudioInputPrivate::drain() +{ + if(handle) + snd_pcm_drain(handle); +} + +InputPrivate::InputPrivate(QAudioInputPrivate* audio) +{ + audioDevice = qobject_cast(audio); +} + +InputPrivate::~InputPrivate() +{ +} + +qint64 InputPrivate::readData( char* data, qint64 len) +{ + // push mode, user read() called + if((audioDevice->state() != QAudio::ActiveState) && !audioDevice->resuming) + return 0; + + int readFrames; + int count=0, err = 0; + + while(count < 5) { + int frames = snd_pcm_bytes_to_frames(audioDevice->handle, len); + readFrames = snd_pcm_readi(audioDevice->handle, data, frames); + if (readFrames >= 0) { + err = snd_pcm_frames_to_bytes(audioDevice->handle, readFrames); +#ifdef DEBUG_AUDIO + qDebug()<errorState = QAudio::IOError; + err = 0; + break; + } else { + if(readFrames == -EPIPE) { + audioDevice->errorState = QAudio::UnderrunError; + err = snd_pcm_prepare(audioDevice->handle); + } else if(readFrames == -ESTRPIPE) { + err = snd_pcm_prepare(audioDevice->handle); + } + if(err != 0) break; + } + count++; + } + if(err > 0 && readFrames > 0) { + audioDevice->totalTimeValue += readFrames*1000/audioDevice->settings.frequency()*1000; + audioDevice->deviceState = QAudio::ActiveState; + return err; + } + return 0; +} + +qint64 InputPrivate::writeData(const char* data, qint64 len) +{ + Q_UNUSED(data) + Q_UNUSED(len) + return 0; +} + +void InputPrivate::trigger() +{ + emit readyRead(); +} + diff --git a/src/multimedia/audio/qaudioinput_alsa_p.h b/src/multimedia/audio/qaudioinput_alsa_p.h new file mode 100644 index 0000000..21c8064 --- /dev/null +++ b/src/multimedia/audio/qaudioinput_alsa_p.h @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + + +#ifndef QAUDIOINPUTALSA_H +#define QAUDIOINPUTALSA_H + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +class InputPrivate; + +class QAudioInputPrivate : public QAbstractAudioInput +{ + Q_OBJECT +public: + QAudioInputPrivate(const QByteArray &device, const QAudioFormat& audioFormat); + ~QAudioInputPrivate(); + + qint64 read(char* data, qint64 len); + + QIODevice* start(QIODevice* device = 0); + void stop(); + void reset(); + void suspend(); + void resume(); + int bytesReady() const; + int periodSize() const; + void setBufferSize(int value); + int bufferSize() const; + void setNotifyInterval(int milliSeconds); + int notifyInterval() const; + qint64 totalTime() const; + qint64 clock() const; + QAudio::Error error() const; + QAudio::State state() const; + QAudioFormat format() const; + bool resuming; + snd_pcm_t* handle; + qint64 totalTimeValue; + QIODevice* audioSource; + QAudioFormat settings; + QAudio::Error errorState; + QAudio::State deviceState; + +private slots: + void userFeed(); + bool deviceReady(); + +private: + int xrun_recovery(int err); + int setFormat(); + bool open(); + void close(); + void drain(); + + QTimer* timer; + QTime timeStamp; + int intervalTime; + char* audioBuffer; + int bytesAvailable; + QByteArray m_device; + bool pullMode; + int buffer_size; + int period_size; + unsigned int buffer_time; + unsigned int period_time; + snd_pcm_uframes_t buffer_frames; + snd_pcm_uframes_t period_frames; + snd_async_handler_t* ahandler; + snd_pcm_access_t access; + snd_pcm_format_t pcmformat; + snd_timestamp_t* timestamp; + snd_pcm_hw_params_t *hwparams; +}; + +class InputPrivate : public QIODevice +{ + Q_OBJECT +public: + InputPrivate(QAudioInputPrivate* audio); + ~InputPrivate(); + + qint64 readData( char* data, qint64 len); + qint64 writeData(const char* data, qint64 len); + + void trigger(); +private: + QAudioInputPrivate *audioDevice; +}; + +#endif diff --git a/src/multimedia/audio/qaudioinput_mac_p.cpp b/src/multimedia/audio/qaudioinput_mac_p.cpp new file mode 100644 index 0000000..5400c85 --- /dev/null +++ b/src/multimedia/audio/qaudioinput_mac_p.cpp @@ -0,0 +1,930 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include + +#include +#include + +#include "qaudio_mac_p.h" +#include "qaudioinput_mac_p.h" + + +QT_BEGIN_NAMESPACE + + +namespace +{ + +static const int default_buffer_size = 4 * 1024; + +class QAudioBufferList +{ +public: + QAudioBufferList(AudioStreamBasicDescription const& streamFormat): + owner(false), + sf(streamFormat) + { + const bool isInterleaved = (sf.mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0; + const int numberOfBuffers = isInterleaved ? 1 : sf.mChannelsPerFrame; + + dataSize = 0; + + bfs = reinterpret_cast(qMalloc(sizeof(AudioBufferList) + + (sizeof(AudioBuffer) * numberOfBuffers))); + + bfs->mNumberBuffers = numberOfBuffers; + for (int i = 0; i < numberOfBuffers; ++i) { + bfs->mBuffers[i].mNumberChannels = isInterleaved ? numberOfBuffers : 1; + bfs->mBuffers[i].mDataByteSize = 0; + bfs->mBuffers[i].mData = 0; + } + } + + QAudioBufferList(AudioStreamBasicDescription const& streamFormat, char* buffer, int bufferSize): + owner(false), + sf(streamFormat), + bfs(0) + { + dataSize = bufferSize; + + bfs = reinterpret_cast(qMalloc(sizeof(AudioBufferList) + sizeof(AudioBuffer))); + + bfs->mNumberBuffers = 1; + bfs->mBuffers[0].mNumberChannels = 1; + bfs->mBuffers[0].mDataByteSize = dataSize; + bfs->mBuffers[0].mData = buffer; + } + + QAudioBufferList(AudioStreamBasicDescription const& streamFormat, int framesToBuffer): + owner(true), + sf(streamFormat), + bfs(0) + { + const bool isInterleaved = (sf.mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0; + const int numberOfBuffers = isInterleaved ? 1 : sf.mChannelsPerFrame; + + dataSize = framesToBuffer * sf.mBytesPerFrame; + + bfs = reinterpret_cast(qMalloc(sizeof(AudioBufferList) + + (sizeof(AudioBuffer) * numberOfBuffers))); + bfs->mNumberBuffers = numberOfBuffers; + for (int i = 0; i < numberOfBuffers; ++i) { + bfs->mBuffers[i].mNumberChannels = isInterleaved ? numberOfBuffers : 1; + bfs->mBuffers[i].mDataByteSize = dataSize; + bfs->mBuffers[i].mData = qMalloc(dataSize); + } + } + + ~QAudioBufferList() + { + if (owner) { + for (UInt32 i = 0; i < bfs->mNumberBuffers; ++i) + qFree(bfs->mBuffers[i].mData); + } + + qFree(bfs); + } + + AudioBufferList* audioBufferList() const + { + return bfs; + } + + char* data(int buffer = 0) const + { + return static_cast(bfs->mBuffers[buffer].mData); + } + + qint64 bufferSize(int buffer = 0) const + { + return bfs->mBuffers[buffer].mDataByteSize; + } + + int frameCount(int buffer = 0) const + { + return bfs->mBuffers[buffer].mDataByteSize / sf.mBytesPerFrame; + } + + int packetCount(int buffer = 0) const + { + return bfs->mBuffers[buffer].mDataByteSize / sf.mBytesPerPacket; + } + + int packetSize() const + { + return sf.mBytesPerPacket; + } + + void reset() + { + for (UInt32 i = 0; i < bfs->mNumberBuffers; ++i) + bfs->mBuffers[i].mDataByteSize = dataSize; + } + +private: + bool owner; + int dataSize; + AudioStreamBasicDescription sf; + AudioBufferList* bfs; +}; + +class QAudioPacketFeeder +{ +public: + QAudioPacketFeeder(QAudioBufferList* abl): + audioBufferList(abl) + { + totalPackets = audioBufferList->packetCount(); + position = 0; + } + + bool feed(AudioBufferList& dst, UInt32& packetCount) + { + if (position == totalPackets) { + dst.mBuffers[0].mDataByteSize = 0; + packetCount = 0; + return false; + } + + if (totalPackets - position < packetCount) + packetCount = totalPackets - position; + + dst.mBuffers[0].mDataByteSize = packetCount * audioBufferList->packetSize(); + dst.mBuffers[0].mData = audioBufferList->data() + (position * audioBufferList->packetSize()); + + position += packetCount; + + return true; + } + +private: + UInt32 totalPackets; + UInt32 position; + QAudioBufferList* audioBufferList; +}; + +class QAudioInputBuffer : public QObject +{ + Q_OBJECT + +public: + QAudioInputBuffer(int bufferSize, + int maxPeriodSize, + AudioStreamBasicDescription const& inputFormat, + AudioStreamBasicDescription const& outputFormat, + QObject* parent): + QObject(parent), + m_deviceError(false), + m_inputFormat(inputFormat), + m_outputFormat(outputFormat) + { + m_maxPeriodSize = maxPeriodSize; + m_periodTime = m_maxPeriodSize / m_outputFormat.mBytesPerFrame * 1000 / m_outputFormat.mSampleRate; + m_buffer = new QAudioRingBuffer(bufferSize + (bufferSize % maxPeriodSize == 0 ? 0 : maxPeriodSize - (bufferSize % maxPeriodSize))); + m_inputBufferList = new QAudioBufferList(m_inputFormat); + + m_flushTimer = new QTimer(this); + connect(m_flushTimer, SIGNAL(timeout()), SLOT(flushBuffer())); + + if (inputFormat.mSampleRate != outputFormat.mSampleRate) { + if (AudioConverterNew(&m_inputFormat, &m_outputFormat, &m_audioConverter) != noErr) { + qWarning() << "QAudioInput: Unable to create an Audio Converter"; + m_audioConverter = 0; + } + } + } + + ~QAudioInputBuffer() + { + delete m_buffer; + } + + qint64 renderFromDevice(AudioUnit audioUnit, + AudioUnitRenderActionFlags* ioActionFlags, + const AudioTimeStamp* inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames) + { + const bool wasEmpty = m_buffer->used() == 0; + + OSStatus err; + qint64 framesRendered = 0; + + m_inputBufferList->reset(); + err = AudioUnitRender(audioUnit, + ioActionFlags, + inTimeStamp, + inBusNumber, + inNumberFrames, + m_inputBufferList->audioBufferList()); + + if (m_audioConverter != 0) { + QAudioPacketFeeder feeder(m_inputBufferList); + + bool wecan = true; + int copied = 0; + + const int available = m_buffer->free(); + + while (err == noErr && wecan) { + QAudioRingBuffer::Region region = m_buffer->acquireWriteRegion(available); + + if (region.second > 0) { + AudioBufferList output; + output.mNumberBuffers = 1; + output.mBuffers[0].mNumberChannels = 1; + output.mBuffers[0].mDataByteSize = region.second; + output.mBuffers[0].mData = region.first; + + UInt32 packetSize = region.second / m_outputFormat.mBytesPerPacket; + err = AudioConverterFillComplexBuffer(m_audioConverter, + converterCallback, + &feeder, + &packetSize, + &output, + 0); + + region.second = output.mBuffers[0].mDataByteSize; + copied += region.second; + + m_buffer->releaseWriteRegion(region); + } + else + wecan = false; + } + + framesRendered += copied / m_outputFormat.mBytesPerFrame; + } + else { + const int available = m_inputBufferList->bufferSize(); + bool wecan = true; + int copied = 0; + + while (wecan && copied < available) { + QAudioRingBuffer::Region region = m_buffer->acquireWriteRegion(available - copied); + + if (region.second > 0) { + memcpy(region.first, m_inputBufferList->data() + copied, region.second); + copied += region.second; + } + else + wecan = false; + + m_buffer->releaseWriteRegion(region); + } + + framesRendered = copied / m_outputFormat.mBytesPerFrame; + } + + if (wasEmpty && framesRendered > 0) + emit readyRead(); + + return framesRendered; + } + + qint64 readBytes(char* data, qint64 len) + { + bool wecan = true; + qint64 bytesCopied = 0; + + len -= len % m_maxPeriodSize; + while (wecan && bytesCopied < len) { + QAudioRingBuffer::Region region = m_buffer->acquireReadRegion(len - bytesCopied); + + if (region.second > 0) { + memcpy(data + bytesCopied, region.first, region.second); + bytesCopied += region.second; + } + else + wecan = false; + + m_buffer->releaseReadRegion(region); + } + + return bytesCopied; + } + + void setFlushDevice(QIODevice* device) + { + if (m_device != device) + m_device = device; + } + + void startFlushTimer() + { + if (m_device != 0) { + m_flushTimer->start((m_buffer->size() - (m_maxPeriodSize * 2)) / m_maxPeriodSize * m_periodTime); + } + } + + void stopFlushTimer() + { + m_flushTimer->stop(); + } + + void flush(bool all = false) + { + const int used = m_buffer->used(); + const int readSize = all ? used : used - (used % m_maxPeriodSize); + + if (readSize > 0) { + bool wecan = true; + int flushed = 0; + + while (!m_deviceError && wecan && flushed < readSize) { + QAudioRingBuffer::Region region = m_buffer->acquireReadRegion(readSize - flushed); + + if (region.second > 0) { + int bytesWritten = m_device->write(region.first, region.second); + if (bytesWritten < 0) { + stopFlushTimer(); + m_deviceError = true; + } + else { + region.second = bytesWritten; + flushed += bytesWritten; + wecan = bytesWritten != 0; + } + } + else + wecan = false; + + m_buffer->releaseReadRegion(region); + } + } + } + + void reset() + { + m_buffer->reset(); + m_deviceError = false; + } + + int available() const + { + return m_buffer->free(); + } + + int used() const + { + return m_buffer->used(); + } + +signals: + void readyRead(); + +private slots: + void flushBuffer() + { + flush(); + } + +private: + bool m_deviceError; + int m_maxPeriodSize; + int m_periodTime; + QIODevice* m_device; + QTimer* m_flushTimer; + QAudioRingBuffer* m_buffer; + QAudioBufferList* m_inputBufferList; + AudioConverterRef m_audioConverter; + AudioStreamBasicDescription m_inputFormat; + AudioStreamBasicDescription m_outputFormat; + + const static OSStatus as_empty = 'qtem'; + + // Converter callback + static OSStatus converterCallback(AudioConverterRef inAudioConverter, + UInt32* ioNumberDataPackets, + AudioBufferList* ioData, + AudioStreamPacketDescription** outDataPacketDescription, + void* inUserData) + { + Q_UNUSED(inAudioConverter); + Q_UNUSED(outDataPacketDescription); + + QAudioPacketFeeder* feeder = static_cast(inUserData); + + if (!feeder->feed(*ioData, *ioNumberDataPackets)) + return as_empty; + + return noErr; + } +}; + + +class MacInputDevice : public QIODevice +{ + Q_OBJECT + +public: + MacInputDevice(QAudioInputBuffer* audioBuffer, QObject* parent): + QIODevice(parent), + m_audioBuffer(audioBuffer) + { + open(QIODevice::ReadOnly | QIODevice::Unbuffered); + connect(m_audioBuffer, SIGNAL(readyRead()), SIGNAL(readyRead())); + } + + qint64 readData(char* data, qint64 len) + { + return m_audioBuffer->readBytes(data, len); + } + + qint64 writeData(const char* data, qint64 len) + { + Q_UNUSED(data); + Q_UNUSED(len); + + return 0; + } + + bool isSequential() const + { + return true; + } + +private: + QAudioInputBuffer* m_audioBuffer; +}; + +} + + +QAudioInputPrivate::QAudioInputPrivate(const QByteArray& device, QAudioFormat const& format): + audioFormat(format) +{ + QDataStream ds(device); + quint32 did, mode; + + ds >> did >> mode; + + if (QAudio::Mode(mode) == QAudio::AudioOutput) + errorCode = QAudio::OpenError; + else { + isOpen = false; + audioDeviceId = AudioDeviceID(did); + audioUnit = 0; + startTime = 0; + totalFrames = 0; + audioBuffer = 0; + internalBufferSize = default_buffer_size; + clockFrequency = AudioGetHostClockFrequency() / 1000; + errorCode = QAudio::NoError; + stateCode = QAudio::StopState; + + intervalTimer = new QTimer(this); + intervalTimer->setInterval(1000); + connect(intervalTimer, SIGNAL(timeout()), SIGNAL(notify())); + } +} + +QAudioInputPrivate::~QAudioInputPrivate() +{ + close(); +} + +bool QAudioInputPrivate::open() +{ + UInt32 size = 0; + + if (isOpen) + return true; + + ComponentDescription cd; + cd.componentType = kAudioUnitType_Output; + cd.componentSubType = kAudioUnitSubType_HALOutput; + cd.componentManufacturer = kAudioUnitManufacturer_Apple; + cd.componentFlags = 0; + cd.componentFlagsMask = 0; + + // Open + Component cp = FindNextComponent(NULL, &cd); + if (cp == 0) { + qWarning() << "QAudioInput: Failed to find HAL Output component"; + return false; + } + + if (OpenAComponent(cp, &audioUnit) != noErr) { + qWarning() << "QAudioInput: Unable to Open Output Component"; + return false; + } + + // Set mode + // switch to input mode + UInt32 enable = 1; + if (AudioUnitSetProperty(audioUnit, + kAudioOutputUnitProperty_EnableIO, + kAudioUnitScope_Input, + 1, + &enable, + sizeof(enable)) != noErr) { + qWarning() << "QAudioInput: Unabled to switch to input mode (Enable Input)"; + return false; + } + + enable = 0; + if (AudioUnitSetProperty(audioUnit, + kAudioOutputUnitProperty_EnableIO, + kAudioUnitScope_Output, + 0, + &enable, + sizeof(enable)) != noErr) { + qWarning() << "QAudioInput: Unabled to switch to input mode (Disable output)"; + return false; + } + + // register callback + AURenderCallbackStruct cb; + cb.inputProc = inputCallback; + cb.inputProcRefCon = this; + + if (AudioUnitSetProperty(audioUnit, + kAudioOutputUnitProperty_SetInputCallback, + kAudioUnitScope_Global, + 0, + &cb, + sizeof(cb)) != noErr) { + qWarning() << "QAudioInput: Failed to set AudioUnit callback"; + return false; + } + + // Set Audio Device + if (AudioUnitSetProperty(audioUnit, + kAudioOutputUnitProperty_CurrentDevice, + kAudioUnitScope_Global, + 0, + &audioDeviceId, + sizeof(audioDeviceId)) != noErr) { + qWarning() << "QAudioInput: Unable to use configured device"; + return false; + } + + // Set format + streamFormat = toAudioStreamBasicDescription(audioFormat); + + size = sizeof(deviceFormat); + if (AudioUnitGetProperty(audioUnit, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Input, + 1, + &deviceFormat, + &size) != noErr) { + qWarning() << "QAudioInput: Unable to retrieve device format"; + return false; + } + + // If the device frequency is different to the requested use a converter + if (deviceFormat.mSampleRate != streamFormat.mSampleRate) { + AudioUnitSetProperty(audioUnit, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Output, + 1, + &deviceFormat, + sizeof(streamFormat)); + } + else { + AudioUnitSetProperty(audioUnit, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Output, + 1, + &streamFormat, + sizeof(streamFormat)); + } + + // Setup buffers + UInt32 numberOfFrames; + size = sizeof(UInt32); + if (AudioUnitGetProperty(audioUnit, + kAudioDevicePropertyBufferFrameSize, + kAudioUnitScope_Global, + 0, + &numberOfFrames, + &size) != noErr) { + qWarning() << "QAudioInput: Failed to get audio period size"; + return false; + } + + // Allocate buffer + periodSizeBytes = (numberOfFrames * streamFormat.mSampleRate / deviceFormat.mSampleRate) * + streamFormat.mBytesPerFrame; + if (internalBufferSize < periodSizeBytes * 2) + internalBufferSize = periodSizeBytes * 2; + else + internalBufferSize -= internalBufferSize % streamFormat.mBytesPerFrame; + + audioBuffer = new QAudioInputBuffer(internalBufferSize, + periodSizeBytes, + deviceFormat, + streamFormat, + this); + + audioIO = new MacInputDevice(audioBuffer, this); + + // Init + if (AudioUnitInitialize(audioUnit) != noErr) { + qWarning() << "QAudioInput: Failed to initialize AudioUnit"; + return false; + } + + isOpen = true; + + return isOpen; +} + +void QAudioInputPrivate::close() +{ + if (audioUnit != 0) { + AudioOutputUnitStop(audioUnit); + AudioUnitUninitialize(audioUnit); + CloseComponent(audioUnit); + } + + delete audioBuffer; +} + +QAudioFormat QAudioInputPrivate::format() const +{ + return audioFormat; +} + +QIODevice* QAudioInputPrivate::start(QIODevice* device) +{ + QIODevice* op = device; + + if (!open()) { + stateCode = QAudio::StopState; + errorCode = QAudio::OpenError; + return audioIO; + } + + reset(); + audioBuffer->reset(); + audioBuffer->setFlushDevice(op); + + if (op == 0) + op = audioIO; + + // Start + startTime = AudioGetCurrentHostTime(); + totalFrames = 0; + + audioThreadStart(); + + return op; +} + +void QAudioInputPrivate::stop() +{ + QMutexLocker lock(&mutex); + if (stateCode != QAudio::StopState) { + audioThreadStop(); + audioBuffer->flush(true); + + errorCode = QAudio::NoError; + stateCode = QAudio::StopState; + QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode)); + } +} + +void QAudioInputPrivate::reset() +{ + QMutexLocker lock(&mutex); + if (stateCode != QAudio::StopState) { + audioThreadStop(); + + errorCode = QAudio::NoError; + stateCode = QAudio::StopState; + QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode)); + } +} + +void QAudioInputPrivate::suspend() +{ + QMutexLocker lock(&mutex); + if (stateCode == QAudio::ActiveState || stateCode == QAudio::IdleState) { + audioThreadStop(); + + errorCode = QAudio::NoError; + stateCode = QAudio::SuspendState; + QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode)); + } +} + +void QAudioInputPrivate::resume() +{ + QMutexLocker lock(&mutex); + if (stateCode == QAudio::SuspendState) { + audioThreadStart(); + + errorCode = QAudio::NoError; + stateCode = QAudio::ActiveState; + QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode)); + } +} + +int QAudioInputPrivate::bytesReady() const +{ + return audioBuffer->used(); +} + +int QAudioInputPrivate::periodSize() const +{ + return periodSizeBytes; +} + +void QAudioInputPrivate::setBufferSize(int bs) +{ + internalBufferSize = bs; +} + +int QAudioInputPrivate::bufferSize() const +{ + return internalBufferSize; +} + +void QAudioInputPrivate::setNotifyInterval(int milliSeconds) +{ + intervalTimer->setInterval(milliSeconds); +} + +int QAudioInputPrivate::notifyInterval() const +{ + return intervalTimer->interval(); +} + +qint64 QAudioInputPrivate::totalTime() const +{ + return totalFrames * 1000000 / audioFormat.frequency(); +} + +qint64 QAudioInputPrivate::clock() const +{ + return (AudioGetCurrentHostTime() - startTime) / (clockFrequency / 1000); +} + +QAudio::Error QAudioInputPrivate::error() const +{ + return errorCode; +} + +QAudio::State QAudioInputPrivate::state() const +{ + return stateCode; +} + +void QAudioInputPrivate::audioThreadStop() +{ + stopTimers(); + if (audioThreadState.testAndSetAcquire(Running, Stopped)) + threadFinished.wait(&mutex); +} + +void QAudioInputPrivate::audioThreadStart() +{ + startTimers(); + audioThreadState = Running; + AudioOutputUnitStart(audioUnit); +} + +void QAudioInputPrivate::audioDeviceStop() +{ + AudioOutputUnitStop(audioUnit); + audioThreadState = Stopped; + threadFinished.wakeOne(); +} + +void QAudioInputPrivate::audioDeviceFull() +{ + QMutexLocker lock(&mutex); + if (stateCode == QAudio::ActiveState) { + audioDeviceStop(); + + errorCode = QAudio::UnderrunError; + stateCode = QAudio::IdleState; + QMetaObject::invokeMethod(this, "deviceStopped", Qt::QueuedConnection); + } +} + +void QAudioInputPrivate::audioDeviceError() +{ + QMutexLocker lock(&mutex); + if (stateCode == QAudio::ActiveState) { + audioDeviceStop(); + + errorCode = QAudio::IOError; + stateCode = QAudio::StopState; + QMetaObject::invokeMethod(this, "deviceStopped", Qt::QueuedConnection); + } +} + +void QAudioInputPrivate::startTimers() +{ + audioBuffer->startFlushTimer(); + intervalTimer->start(); +} + +void QAudioInputPrivate::stopTimers() +{ + audioBuffer->stopFlushTimer(); + intervalTimer->stop(); +} + +void QAudioInputPrivate::deviceStopped() +{ + stopTimers(); + emit stateChanged(stateCode); +} + +// Input callback +OSStatus QAudioInputPrivate::inputCallback(void* inRefCon, + AudioUnitRenderActionFlags* ioActionFlags, + const AudioTimeStamp* inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList* ioData) +{ + Q_UNUSED(ioData); + + QAudioInputPrivate* d = static_cast(inRefCon); + + const int threadState = d->audioThreadState.fetchAndAddAcquire(0); + if (threadState == Stopped) + d->audioDeviceStop(); + else { + qint64 framesWritten; + + framesWritten = d->audioBuffer->renderFromDevice(d->audioUnit, + ioActionFlags, + inTimeStamp, + inBusNumber, + inNumberFrames); + + if (framesWritten > 0) + d->totalFrames += framesWritten; + else if (framesWritten == 0) + d->audioDeviceFull(); + else if (framesWritten < 0) + d->audioDeviceError(); + } + + return noErr; +} + + +QT_END_NAMESPACE + +#include "qaudioinput_mac_p.moc" + diff --git a/src/multimedia/audio/qaudioinput_mac_p.h b/src/multimedia/audio/qaudioinput_mac_p.h new file mode 100644 index 0000000..98ef9ce --- /dev/null +++ b/src/multimedia/audio/qaudioinput_mac_p.h @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + + +#ifndef QAUDIOINPUT_MAC_P_H +#define QAUDIOINPUT_MAC_P_H + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QTimer; +class QIODevice; + +namespace +{ +class QAudioInputBuffer; +} + +class QAudioInputPrivate : public QAbstractAudioInput +{ + Q_OBJECT + +public: + bool isOpen; + int periodSizeBytes; + int internalBufferSize; + qint64 totalFrames; + QAudioFormat audioFormat; + QIODevice* audioIO; + AudioUnit audioUnit; + AudioDeviceID audioDeviceId; + Float64 clockFrequency; + UInt64 startTime; + QAudio::Error errorCode; + QAudio::State stateCode; + QAudioInputBuffer* audioBuffer; + QMutex mutex; + QWaitCondition threadFinished; + QAtomicInt audioThreadState; + QTimer* intervalTimer; + AudioStreamBasicDescription streamFormat; + AudioStreamBasicDescription deviceFormat; + + QAudioInputPrivate(const QByteArray& device, QAudioFormat const& format); + ~QAudioInputPrivate(); + + bool open(); + void close(); + + QAudioFormat format() const; + + QIODevice* start(QIODevice* device); + void stop(); + void reset(); + void suspend(); + void resume(); + void idle(); + + int bytesReady() const; + int periodSize() const; + + void setBufferSize(int value); + int bufferSize() const; + + void setNotifyInterval(int milliSeconds); + int notifyInterval() const; + + qint64 totalTime() const; + qint64 clock() const; + + QAudio::Error error() const; + QAudio::State state() const; + + void audioThreadStart(); + void audioThreadStop(); + + void audioDeviceStop(); + void audioDeviceFull(); + void audioDeviceError(); + + void startTimers(); + void stopTimers(); + +signals: + void stateChanged(QAudio::State); + void notify(); + +private slots: + void deviceStopped(); + +private: + enum { Running, Stopped }; + + // Input callback + static OSStatus inputCallback(void* inRefCon, + AudioUnitRenderActionFlags* ioActionFlags, + const AudioTimeStamp* inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList* ioData); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QAUDIOINPUT_MAC_P_H diff --git a/src/multimedia/audio/qaudioinput_win32_p.cpp b/src/multimedia/audio/qaudioinput_win32_p.cpp new file mode 100644 index 0000000..e5b6e0d --- /dev/null +++ b/src/multimedia/audio/qaudioinput_win32_p.cpp @@ -0,0 +1,540 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + + +#include "qaudioinput_win32_p.h" + +//#define DEBUG_AUDIO 1 + + +QAudioInputPrivate::QAudioInputPrivate(const QByteArray &device, const QAudioFormat& audioFormat): + settings(audioFormat) +{ + bytesAvailable = 0; + buffer_size = 0; + period_size = 0; + m_device = device; + totalTimeValue = 0; + intervalTime = 1000; + errorState = QAudio::NoError; + deviceState = QAudio::StopState; + audioSource = 0; + pullMode = true; + resuming = false; + + connect(this,SIGNAL(processMore()),SLOT(deviceReady())); + + InitializeCriticalSection(&waveInCriticalSection); +} + +QAudioInputPrivate::~QAudioInputPrivate() +{ + close(); + DeleteCriticalSection(&waveInCriticalSection); +} + +void CALLBACK QAudioInputPrivate::waveInProc( HWAVEIN hWaveIn, UINT uMsg, + DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 ) +{ + Q_UNUSED(dwParam1) + Q_UNUSED(dwParam2) + Q_UNUSED(hWaveIn) + + QAudioInputPrivate* qAudio; + qAudio = (QAudioInputPrivate*)(dwInstance); + if(!qAudio) + return; + + switch(uMsg) { + case WIM_OPEN: + break; + case WIM_DATA: + EnterCriticalSection(&waveInCriticalSection); + if(qAudio->waveFreeBlockCount > 0) + qAudio->waveFreeBlockCount--; + LeaveCriticalSection(&waveInCriticalSection); + qAudio->feedback(); + break; + case WIM_CLOSE: + break; + default: + return; + } +} + +WAVEHDR* QAudioInputPrivate::allocateBlocks(int size, int count) +{ + int i; + unsigned char* buffer; + WAVEHDR* blocks; + DWORD totalBufferSize = (size + sizeof(WAVEHDR))*count; + + if((buffer=(unsigned char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, + totalBufferSize)) == 0) { + qWarning("QAudioInput: Memory allocation error"); + return 0; + } + blocks = (WAVEHDR*)buffer; + buffer += sizeof(WAVEHDR)*count; + for(i = 0; i < count; i++) { + blocks[i].dwBufferLength = size; + blocks[i].lpData = (LPSTR)buffer; + blocks[i].dwBytesRecorded=0; + blocks[i].dwUser = 0L; + blocks[i].dwFlags = 0L; + blocks[i].dwLoops = 0L; + result = waveInPrepareHeader(hWaveIn,&blocks[i], sizeof(WAVEHDR)); + if(result != MMSYSERR_NOERROR) { + qWarning("QAudioInput: Can't prepare block %d",i); + return 0; + } + buffer += size; + } + return blocks; +} + +void QAudioInputPrivate::freeBlocks(WAVEHDR* blockArray) +{ + HeapFree(GetProcessHeap(), 0, blockArray); +} + +QAudio::Error QAudioInputPrivate::error() const +{ + return errorState; +} + +QAudio::State QAudioInputPrivate::state() const +{ + return deviceState; +} + +QAudioFormat QAudioInputPrivate::format() const +{ + return settings; +} + +QIODevice* QAudioInputPrivate::start(QIODevice* device) +{ + if(deviceState != QAudio::StopState) + close(); + + if(!pullMode && audioSource) { + delete audioSource; + } + + if(device) { + //set to pull mode + pullMode = true; + audioSource = device; + } else { + //set to push mode + pullMode = false; + audioSource = new InputPrivate(this); + audioSource->open(QIODevice::ReadOnly | QIODevice::Unbuffered); + } + + if( !open() ) + return 0; + + emit stateChanged(deviceState); + + return audioSource; +} + +void QAudioInputPrivate::stop() +{ + if(deviceState == QAudio::StopState) + return; + + deviceState = QAudio::StopState; + + close(); + emit stateChanged(deviceState); +} + +bool QAudioInputPrivate::open() +{ +#ifdef DEBUG_AUDIO + QTime now(QTime::currentTime()); + qDebug()<> 3) * wfx.nChannels; + wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec; + + UINT_PTR devId = WAVE_MAPPER; + + WAVEINCAPS wic; + unsigned long iNumDevs,ii; + iNumDevs = waveInGetNumDevs(); + for(ii=0;ii 0) { + if(pullMode) { + l = audioSource->write(waveBlocks[header].lpData, + waveBlocks[header].dwBytesRecorded); +#ifdef DEBUG_AUDIO + qDebug()<<"IN: "<= buffer_size/period_size) + header = 0; + p+=l; + + if(!pullMode) { + if(l+period_size > len && waveFreeBlockCount == buffer_size/period_size) + done = true; + } else { + if(waveFreeBlockCount == buffer_size/period_size) + done = true; + } + written+=l; + } +#ifdef DEBUG_AUDIO + qDebug()<<"read in len="<(audioSource); + a->trigger(); + } + if(deviceState != QAudio::ActiveState) + return true; + + if(timeStamp.elapsed() > intervalTime && intervalTime > 50) { + emit notify(); + timeStamp.restart(); + } + return true; +} + +qint64 QAudioInputPrivate::clock() const +{ + if(deviceState != QAudio::ActiveState) + return 0; + + return timeStampOpened.elapsed(); +} + +void QAudioInputPrivate::reset() +{ + close(); +} + +InputPrivate::InputPrivate(QAudioInputPrivate* audio) +{ + audioDevice = qobject_cast(audio); +} + +InputPrivate::~InputPrivate() {} + +qint64 InputPrivate::readData( char* data, qint64 len) +{ + // push mode, user read() called + if(audioDevice->deviceState != QAudio::ActiveState) + return 0; + // Read in some audio data + return audioDevice->read(data,len); +} + +qint64 InputPrivate::writeData(const char* data, qint64 len) +{ + Q_UNUSED(data) + Q_UNUSED(len) + + emit readyRead(); + return 0; +} + +void InputPrivate::trigger() +{ + emit readyRead(); +} + diff --git a/src/multimedia/audio/qaudioinput_win32_p.h b/src/multimedia/audio/qaudioinput_win32_p.h new file mode 100644 index 0000000..32464f0 --- /dev/null +++ b/src/multimedia/audio/qaudioinput_win32_p.h @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#ifndef QAUDIOINPUTWIN_H +#define QAUDIOINPUTWIN_H + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +static CRITICAL_SECTION waveInCriticalSection; + +class QAudioInputPrivate : public QAbstractAudioInput +{ + Q_OBJECT +public: + QAudioInputPrivate(const QByteArray &device, const QAudioFormat& audioFormat); + ~QAudioInputPrivate(); + + qint64 read(char* data, qint64 len); + + QAudioFormat format() const; + QIODevice* start(QIODevice* device = 0); + void stop(); + void reset(); + void suspend(); + void resume(); + int bytesReady() const; + int periodSize() const; + void setBufferSize(int value); + int bufferSize() const; + void setNotifyInterval(int milliSeconds); + int notifyInterval() const; + qint64 totalTime() const; + qint64 clock() const; + QAudio::Error error() const; + QAudio::State state() const; + + QIODevice* audioSource; + QAudioFormat settings; + QAudio::Error errorState; + QAudio::State deviceState; + +private: + qint32 buffer_size; + qint32 period_size; + qint32 header; + QByteArray m_device; + int bytesAvailable; + int intervalTime; + QTime timeStamp; + QTime timeStampOpened; + qint64 totalTimeValue; + bool pullMode; + bool resuming; + WAVEFORMATEX wfx; + HWAVEIN hWaveIn; + MMRESULT result; + WAVEHDR* waveBlocks; + volatile int waveFreeBlockCount; + int waveCurrentBlock; + + static void CALLBACK waveInProc( HWAVEIN hWaveIn, UINT uMsg, + DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 ); + + WAVEHDR* allocateBlocks(int size, int count); + void freeBlocks(WAVEHDR* blockArray); + bool open(); + void close(); + +private slots: + void feedback(); + bool deviceReady(); + +signals: + void processMore(); +}; + +class InputPrivate : public QIODevice +{ + Q_OBJECT +public: + InputPrivate(QAudioInputPrivate* audio); + ~InputPrivate(); + + qint64 readData( char* data, qint64 len); + qint64 writeData(const char* data, qint64 len); + + void trigger(); +private: + QAudioInputPrivate *audioDevice; +}; + +#endif diff --git a/src/multimedia/audio/qaudiooutput.cpp b/src/multimedia/audio/qaudiooutput.cpp new file mode 100644 index 0000000..785da61 --- /dev/null +++ b/src/multimedia/audio/qaudiooutput.cpp @@ -0,0 +1,403 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include +#include +#include + +#include "qaudiodevicefactory_p.h" + + +QT_BEGIN_NAMESPACE + +/*! + \class QAudioOutput + \brief The QAudioOutput class provides an interface for sending audio data to an audio output device. + + \inmodule QtMultimedia + \ingroup multimedia + \since 4.6 + + You can construct an audio output with the system's + \l{QAudioDeviceInfo::defaultOutputDevice()}{default audio output + device}. It is also possible to create QAudioOutput with a + specific QAudioDeviceId. When you create the audio output, you + should also send in the QAudioFormat to be used for the playback + (see the QAudioFormat class description for details). + + To play a file: + + Starting to play an audio stream is simply a matter of calling + start() with a QIODevice. QAudioOutput will then fetch the data it + needs from the io device. So playing back an audio file is as + simple as: + + \code + QFile inputFile; + inputFile.setFileName("/tmp/test.raw"); + inputFile.open(QIODevice::ReadOnly); + + QAudioFormat format; + // Set up the format, eg. + format.setFrequency(8000); + format.setChannels(1); + format.setSampleSize(8); + format.setCodec("audio/pcm"); + format.setByteOrder(QAudioFormat::LittleEndian); + format.setSampleType(QAudioFormat::UnSignedInt); + + QAudioOutput *audio = new QAudioOutput(format, this); + connect(audio,SIGNAL(stateChanged(QAudio::State)),SLOT(finishedPlaying(QAudio::State))); + audio->start(inputFile); + + \endcode + + The file will start playing assuming that the audio system and + output device support it. If you run out of luck, check what's + up with the error() function. + + After the file has finished playing, we need to stop the device: + + \code + void finishedPlaying(QAudio::State state) + { + if(state == QAudio::IdleState) { + audio->stop(); + inputFile.close(); + } + } + \endcode + + At any given time, the QAudioOutput will be in one of four states: + active, suspended, stopped, or idle. These states are described + by the QAudio::State enum. + State changes are reported through the stateChanged() signal. You + can use this signal to, for instance, update the GUI of the + application; the mundane example here being changing the state of + a \c { play/pause } button. You request a state change directly + with suspend(), stop(), reset(), resume(), and start(). + + While the stream is playing, you can set a notify interval in + milliseconds with setNotifyInterval(). This interval specifies the + time between two emissions of the notify() signal. This is + relative to the position in the stream, i.e., if the QAudioOutput + is in the SuspendedState or the IdleState, the notify() signal is + not emitted. A typical use-case would be to update a + \l{QSlider}{slider} that allows seeking in the stream. + If you want the time since playback started regardless of which + states the audio output has been in, clock() is the function for you. + + If an error occurs, you can fetch the \l{QAudio::Error}{error + type} with the error() function. Please see the QAudio::Error enum + for a description of the possible errors that are reported. + + If an error is encountered state changes to QAudio::StopState. + + \sa QAudioInput, QAudioDeviceInfo +*/ + +/*! + Construct a new audio output and attach it to \a parent. + The default audio output device is used with the output + \a format parameters. +*/ + +QAudioOutput::QAudioOutput(const QAudioFormat &format, QObject *parent): + QObject(parent) +{ + d = QAudioDeviceFactory::createDefaultOutputDevice(format); + connect(d, SIGNAL(notify()), SIGNAL(notify())); + connect(d, SIGNAL(stateChanged(QAudio::State)), SIGNAL(stateChanged(QAudio::State))); +} + +/*! + Construct a new audio output and attach it to \a parent. + The \a id of the audio output device is used with the output + \a format parameters. +*/ + +QAudioOutput::QAudioOutput(const QAudioDeviceId &id, const QAudioFormat &format, QObject *parent): + QObject(parent) +{ + d = QAudioDeviceFactory::createOutputDevice(id, format); + connect(d, SIGNAL(notify()), SIGNAL(notify())); + connect(d, SIGNAL(stateChanged(QAudio::State)), SIGNAL(stateChanged(QAudio::State))); +} + +/*! + Destroys this audio output. +*/ + +QAudioOutput::~QAudioOutput() +{ + delete d; +} + +/*! + Returns the QAudioFormat being used. + +*/ + +QAudioFormat QAudioOutput::format() const +{ + return d->format(); +} + +/*! + Uses the \a device as the QIODevice to transfer data. + If \a device is null then the class creates an internal QIODevice. + Returns a pointer to the QIODevice being used to handle the data + transfer. This QIODevice can be used to write() audio data + directly. + Passing a QIODevice allows the data to be transfered without any extra code. + All that is required is to open the QIODevice. + + /sa QIODevice +*/ + +QIODevice* QAudioOutput::start(QIODevice* device) +{ + /* + PULL MODE (valid QIODevice) + -If currently not StopState, stop. + -If previous start was push mode, delete internal QIODevice. + -open audio output. + -If ok, NoError and ActiveState, else OpenError and StopState + -emit stateChanged() + -return device + + PUSH MODE (device = 0) + -If currently not StopState, stop. + -If no internal QIODevice, create one. + -open audio output. + -If ok, NoError and IdleState, else OpenError and StopState + -emit stateChanged() + -return internal QIODevice + */ + return d->start(device); +} + +/*! + Stops the audio output. +*/ + +void QAudioOutput::stop() +{ + /* + -If StopState, return + -set to StopState + -detach from audio device + -emit stateChanged() + */ + d->stop(); +} + +/*! + Drops all audio data in the buffers, resets buffers to zero. +*/ + +void QAudioOutput::reset() +{ + /* + -drop all buffered audio, set buffers to zero. + -call stop() + */ + d->reset(); +} + +/*! + Stops processing audio data, preserving buffered audio data. +*/ + +void QAudioOutput::suspend() +{ + /* + -If not ActiveState|IdleState, return + -stop processing audio, saving all buffered audio data + -set NoError and SuspendState + -emit stateChanged() + */ + d->suspend(); +} + +/*! + Resumes processing audio data after a suspend(). +*/ + +void QAudioOutput::resume() +{ + /* + -If SuspendState, return + -resume audio + -(PULL MODE): set ActiveState, NoError + -(PUSH MODE): set IdleState, NoError + -kick start audio if needed + -emit stateChanged() + */ + d->resume(); +} + +/*! + Returns the free space available in bytes in the audio buffer. +*/ + +int QAudioOutput::bytesFree() const +{ + /* + -If not ActiveState|IdleState, return 0 + -return space available in audio buffer in bytes + */ + return d->bytesFree(); +} + +/*! + Returns the period size in bytes. + + Note: This is the recommended write size in bytes. +*/ + +int QAudioOutput::periodSize() const +{ + return d->periodSize(); +} + +/*! + Sets the audio buffer size to \a value in bytes. + + Note: This function can be called anytime before start(), calls to this + are ignored after start(). It should not be assumed that the buffer size + set is the actual buffer size used, calling bufferSize() anytime after start() + will return the actual buffer size being used. +*/ + +void QAudioOutput::setBufferSize(int value) +{ + d->setBufferSize(value); +} + +/*! + Returns the audio buffer size in bytes. + + If called before start(), returns platform default value. + If called before start() but setBufferSize() was called prior, returns value set by setBufferSize(). + If called after start(), returns the actual buffer size being used. This may not be what was set previously + by setBufferSize(). + +*/ + +int QAudioOutput::bufferSize() const +{ + return d->bufferSize(); +} + +/*! + Sets the interval for notify() signal to be emitted. + This is based on the \a ms of audio data processed + not on actual real-time. The resolution of the timer is platform specific. +*/ + +void QAudioOutput::setNotifyInterval(int ms) +{ + d->setNotifyInterval(ms); +} + +/*! + Returns the notify interval in milliseconds. +*/ + +int QAudioOutput::notifyInterval() const +{ + return d->notifyInterval(); +} + +/*! + Returns the amount of audio data processed since start() + was called in microseconds. +*/ + +qint64 QAudioOutput::totalTime() const +{ + return d->totalTime(); +} + +/*! + Returns the microseconds since start() was called, including time in Idle and + Suspend states. +*/ + +qint64 QAudioOutput::clock() const +{ + return d->clock(); +} + +/*! + Returns the error state. +*/ + +QAudio::Error QAudioOutput::error() const +{ + return d->error(); +} + +/*! + Returns the state of audio processing. +*/ + +QAudio::State QAudioOutput::state() const +{ + return d->state(); +} + +/*! + \fn QAudioOutput::stateChanged(QAudio::State state) + This signal is emitted when the device \a state has changed. + This is the current state of the audio output. +*/ + +/*! + \fn QAudioOutput::notify() + This signal is emitted when x ms of audio data has been processed + the interval set by setNotifyInterval(x). +*/ + +QT_END_NAMESPACE diff --git a/src/multimedia/audio/qaudiooutput.h b/src/multimedia/audio/qaudiooutput.h new file mode 100644 index 0000000..95e28ea --- /dev/null +++ b/src/multimedia/audio/qaudiooutput.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#ifndef QAUDIOOUTPUT_H +#define QAUDIOOUTPUT_H + +#include +#include + +#include +#include +#include + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + + +class QAbstractAudioOutput; + +class Q_MULTIMEDIA_EXPORT QAudioOutput : public QObject +{ + Q_OBJECT + +public: + explicit QAudioOutput(const QAudioFormat &format = QAudioFormat(), QObject *parent = 0); + explicit QAudioOutput(const QAudioDeviceId &id, const QAudioFormat &format = QAudioFormat(), QObject *parent = 0); + ~QAudioOutput(); + + QAudioFormat format() const; + + QIODevice* start(QIODevice *device = 0); + void stop(); + void reset(); + void suspend(); + void resume(); + + void setBufferSize(int bytes); + int bufferSize() const; + + int bytesFree() const; + int periodSize() const; + + void setNotifyInterval(int milliSeconds); + int notifyInterval() const; + + qint64 totalTime() const; + qint64 clock() const; + + QAudio::Error error() const; + QAudio::State state() const; + +Q_SIGNALS: + void stateChanged(QAudio::State); + void notify(); + +private: + Q_DISABLE_COPY(QAudioOutput) + + QAbstractAudioOutput* d; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QAUDIOOUTPUT_H diff --git a/src/multimedia/audio/qaudiooutput_alsa_p.cpp b/src/multimedia/audio/qaudiooutput_alsa_p.cpp new file mode 100644 index 0000000..d41c449 --- /dev/null +++ b/src/multimedia/audio/qaudiooutput_alsa_p.cpp @@ -0,0 +1,706 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include "qaudiooutput_alsa_p.h" + +//#define DEBUG_AUDIO 1 + +QAudioOutputPrivate::QAudioOutputPrivate(const QByteArray &device, const QAudioFormat& audioFormat): + settings(audioFormat) +{ + bytesAvailable = 0; + handle = 0; + ahandler = 0; + access = SND_PCM_ACCESS_RW_INTERLEAVED; + pcmformat = SND_PCM_FORMAT_S16; + buffer_frames = 0; + period_frames = 0; + buffer_size = 0; + period_size = 0; + buffer_time = 100000; + period_time = 20000; + totalTimeValue = 0; + intervalTime = 1000; + audioBuffer = 0; + errorState = QAudio::NoError; + deviceState = QAudio::StopState; + audioSource = 0; + pullMode = true; + resuming = false; + opened = false; + + QStringList list1 = QString(tr(device)).split(tr(":")); + m_device = QByteArray(list1.at(0).toLocal8Bit().constData()); + + timer = new QTimer(this); + connect(timer,SIGNAL(timeout()),SLOT(userFeed())); +} + +QAudioOutputPrivate::~QAudioOutputPrivate() +{ + close(); + disconnect(timer, SIGNAL(timeout())); + QCoreApplication::processEvents(); + delete timer; +} + +QAudio::Error QAudioOutputPrivate::error() const +{ + return errorState; +} + +QAudio::State QAudioOutputPrivate::state() const +{ + return deviceState; +} + +void QAudioOutputPrivate::async_callback(snd_async_handler_t *ahandler) +{ + QAudioOutputPrivate* audioOut; + + audioOut = static_cast + (snd_async_handler_get_callback_private(ahandler)); + + if((audioOut->deviceState==QAudio::ActiveState)||(audioOut->resuming)) + audioOut->feedback(); +} + +int QAudioOutputPrivate::xrun_recovery(int err) +{ + int count = 0; + bool reset = false; + + if(err == -EPIPE) { + errorState = QAudio::UnderrunError; + err = snd_pcm_prepare(handle); + if(err < 0) + reset = true; + + } else if((err == -ESTRPIPE)||(err == -EIO)) { + errorState = QAudio::IOError; + while((err = snd_pcm_resume(handle)) == -EAGAIN){ + usleep(100); + count++; + if(count > 5) { + reset = true; + break; + } + } + if(err < 0) { + err = snd_pcm_prepare(handle); + if(err < 0) + reset = true; + } + } + if(reset) { + close(); + open(); + snd_pcm_prepare(handle); + return 0; + } + return err; +} + +int QAudioOutputPrivate::setFormat() +{ + snd_pcm_format_t pcmformat = SND_PCM_FORMAT_S16; + + if(settings.sampleSize() == 8) { + pcmformat = SND_PCM_FORMAT_U8; + + } else if(settings.sampleSize() == 16) { + if(settings.sampleType() == QAudioFormat::SignedInt) { + if(settings.byteOrder() == QAudioFormat::LittleEndian) + pcmformat = SND_PCM_FORMAT_S16_LE; + else + pcmformat = SND_PCM_FORMAT_S16_BE; + } else if(settings.sampleType() == QAudioFormat::UnSignedInt) { + if(settings.byteOrder() == QAudioFormat::LittleEndian) + pcmformat = SND_PCM_FORMAT_U16_LE; + else + pcmformat = SND_PCM_FORMAT_U16_BE; + } + } else if(settings.sampleSize() == 24) { + if(settings.sampleType() == QAudioFormat::SignedInt) { + if(settings.byteOrder() == QAudioFormat::LittleEndian) + pcmformat = SND_PCM_FORMAT_S24_LE; + else + pcmformat = SND_PCM_FORMAT_S24_BE; + } else if(settings.sampleType() == QAudioFormat::UnSignedInt) { + if(settings.byteOrder() == QAudioFormat::LittleEndian) + pcmformat = SND_PCM_FORMAT_U24_LE; + else + pcmformat = SND_PCM_FORMAT_U24_BE; + } + } else if(settings.sampleSize() == 32) { + if(settings.sampleType() == QAudioFormat::SignedInt) { + if(settings.byteOrder() == QAudioFormat::LittleEndian) + pcmformat = SND_PCM_FORMAT_S32_LE; + else + pcmformat = SND_PCM_FORMAT_S32_BE; + } else if(settings.sampleType() == QAudioFormat::UnSignedInt) { + if(settings.byteOrder() == QAudioFormat::LittleEndian) + pcmformat = SND_PCM_FORMAT_U32_LE; + else + pcmformat = SND_PCM_FORMAT_U32_BE; + } else if(settings.sampleType() == QAudioFormat::Float) { + if(settings.byteOrder() == QAudioFormat::LittleEndian) + pcmformat = SND_PCM_FORMAT_FLOAT_LE; + else + pcmformat = SND_PCM_FORMAT_FLOAT_BE; + } + } else if(settings.sampleSize() == 64) { + if(settings.byteOrder() == QAudioFormat::LittleEndian) + pcmformat = SND_PCM_FORMAT_FLOAT64_LE; + else + pcmformat = SND_PCM_FORMAT_FLOAT64_BE; + } + + return snd_pcm_hw_params_set_format( handle, hwparams, pcmformat); +} + +QIODevice* QAudioOutputPrivate::start(QIODevice* device) +{ + if(deviceState != QAudio::StopState) + deviceState = QAudio::StopState; + + errorState = QAudio::NoError; + + // Handle change of mode + if(audioSource && pullMode && !device) { + // pull -> push + close(); + audioSource = 0; + } else if(audioSource && !pullMode && device) { + // push -> pull + close(); + delete audioSource; + audioSource = 0; + } + + if(device) { + //set to pull mode + pullMode = true; + audioSource = device; + deviceState = QAudio::ActiveState; + } else { + //set to push mode + if(!audioSource) { + audioSource = new OutputPrivate(this); + audioSource->open(QIODevice::WriteOnly|QIODevice::Unbuffered); + } + pullMode = false; + deviceState = QAudio::IdleState; + } + + open(); + + emit stateChanged(deviceState); + + return audioSource; +} + +void QAudioOutputPrivate::stop() +{ + if(deviceState == QAudio::StopState) + return; + deviceState = QAudio::StopState; + close(); + emit stateChanged(deviceState); +} + +bool QAudioOutputPrivate::open() +{ + if(opened) + return true; + +#ifdef DEBUG_AUDIO + QTime now(QTime::currentTime()); + qDebug()<start(period_time/1000); + + errorState = QAudio::NoError; + totalTimeValue = 0; + opened = true; + + return true; +} + +void QAudioOutputPrivate::close() +{ + deviceState = QAudio::StopState; + timer->stop(); + + if ( handle ) { + snd_pcm_drain( handle ); + snd_pcm_close( handle ); + handle = 0; + delete [] audioBuffer; + audioBuffer=0; + } + if(!pullMode && audioSource) { + delete audioSource; + audioSource = 0; + } + opened = false; +} + +int QAudioOutputPrivate::bytesFree() const +{ + if(resuming) + return period_size; + + if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState) + return 0; + int frames = snd_pcm_avail_update(handle); + if((int)frames > (int)buffer_frames) + frames = buffer_frames; + + return snd_pcm_frames_to_bytes(handle, frames); +} + +qint64 QAudioOutputPrivate::write( const char *data, qint64 len ) +{ + // Write out some audio data + if ( !handle ) + return 0; +#ifdef DEBUG_AUDIO + qDebug()<<"frames to write out = "<< + snd_pcm_bytes_to_frames( handle, (int)len )<<" ("< 0) { + totalTimeValue += err*1000000/settings.frequency(); + resuming = false; + errorState = QAudio::NoError; + deviceState = QAudio::ActiveState; + return snd_pcm_frames_to_bytes( handle, err ); + } else + err = xrun_recovery(err); + + if(err < 0) { + close(); + errorState = QAudio::FatalError; + deviceState = QAudio::StopState; + emit stateChanged(deviceState); + } + return 0; +} + +int QAudioOutputPrivate::periodSize() const +{ + return period_size; +} + +void QAudioOutputPrivate::setBufferSize(int value) +{ + if(deviceState == QAudio::StopState) + buffer_size = value; +} + +int QAudioOutputPrivate::bufferSize() const +{ + return buffer_size; +} + +void QAudioOutputPrivate::setNotifyInterval(int ms) +{ + intervalTime = ms; +} + +int QAudioOutputPrivate::notifyInterval() const +{ + return intervalTime; +} + +qint64 QAudioOutputPrivate::totalTime() const +{ + return totalTimeValue; +} + +void QAudioOutputPrivate::resume() +{ + if(deviceState == QAudio::SuspendState) { + int err = 0; + + if(handle) { + err = snd_pcm_prepare( handle ); + if(err < 0) + xrun_recovery(err); + + err = snd_pcm_start(handle); + if(err < 0) + xrun_recovery(err); + + bytesAvailable = (int)snd_pcm_frames_to_bytes(handle, buffer_frames); + } + resuming = true; + if(pullMode) + deviceState = QAudio::ActiveState; + else + deviceState = QAudio::IdleState; + + errorState = QAudio::NoError; + timer->start(period_time/1000); + emit stateChanged(deviceState); + } +} + +QAudioFormat QAudioOutputPrivate::format() const +{ + return settings; +} + +void QAudioOutputPrivate::suspend() +{ + if(deviceState == QAudio::ActiveState || deviceState == QAudio::IdleState || resuming) { + timer->stop(); + deviceState = QAudio::SuspendState; + errorState = QAudio::NoError; + emit stateChanged(deviceState); + } +} + +void QAudioOutputPrivate::userFeed() +{ + if(deviceState == QAudio::StopState || deviceState == QAudio::SuspendState) + return; +#ifdef DEBUG_AUDIO + QTime now(QTime::currentTime()); + qDebug()<acquireReadRegion((maxFrames - framesRead) * m_bytesPerFrame); + + if (region.second > 0) { + region.second -= region.second % m_bytesPerFrame; + memcpy(data + (framesRead * m_bytesPerFrame), region.first, region.second); + framesRead += region.second / m_bytesPerFrame; + } + else + wecan = false; + + m_buffer->releaseReadRegion(region); + } + + if (framesRead == 0 && m_deviceError) + framesRead = -1; + + return framesRead; + } + + qint64 writeBytes(const char* data, qint64 maxSize) + { + bool wecan = true; + qint64 bytesWritten = 0; + + maxSize -= maxSize % m_bytesPerFrame; + while (wecan && bytesWritten < maxSize) { + QAudioRingBuffer::Region region = m_buffer->acquireWriteRegion(maxSize - bytesWritten); + + if (region.second > 0) { + memcpy(region.first, data + bytesWritten, region.second); + bytesWritten += region.second; + } + else + wecan = false; + + m_buffer->releaseWriteRegion(region); + } + + if (bytesWritten > 0) + emit readyRead(); + + return bytesWritten; + } + + int available() const + { + return m_buffer->free(); + } + + void reset() + { + m_buffer->reset(); + m_deviceError = false; + } + + void setPrefetchDevice(QIODevice* device) + { + if (m_device != device) { + m_device = device; + if (m_device != 0) + fillBuffer(); + } + } + + void startFillTimer() + { + if (m_device != 0) + m_fillTimer->start(m_buffer->size() / 2 / m_maxPeriodSize * m_periodTime); + } + + void stopFillTimer() + { + m_fillTimer->stop(); + } + +signals: + void readyRead(); + +private slots: + void fillBuffer() + { + const int free = m_buffer->free(); + const int writeSize = free - (free % m_maxPeriodSize); + + if (writeSize > 0) { + bool wecan = true; + int filled = 0; + + while (!m_deviceError && wecan && filled < writeSize) { + QAudioRingBuffer::Region region = m_buffer->acquireWriteRegion(writeSize - filled); + + if (region.second > 0) { + region.second = m_device->read(region.first, region.second); + if (region.second > 0) + filled += region.second; + else if (region.second == 0) + wecan = false; + else if (region.second < 0) { + m_fillTimer->stop(); + region.second = 0; + m_deviceError = true; + } + } + else + wecan = false; + + m_buffer->releaseWriteRegion(region); + } + + if (filled > 0) + emit readyRead(); + } + } + +private: + bool m_deviceError; + int m_maxPeriodSize; + int m_bytesPerFrame; + int m_periodTime; + QIODevice* m_device; + QTimer* m_fillTimer; + QAudioRingBuffer* m_buffer; +}; + + +} + +class MacOutputDevice : public QIODevice +{ + Q_OBJECT + +public: + MacOutputDevice(QAudioOutputBuffer* audioBuffer, QObject* parent): + QIODevice(parent), + m_audioBuffer(audioBuffer) + { + open(QIODevice::WriteOnly | QIODevice::Unbuffered); + } + + qint64 readData(char* data, qint64 len) + { + Q_UNUSED(data); + Q_UNUSED(len); + + return 0; + } + + qint64 writeData(const char* data, qint64 len) + { + return m_audioBuffer->writeBytes(data, len); + } + + bool isSequential() const + { + return true; + } + +private: + QAudioOutputBuffer* m_audioBuffer; +}; + + +QAudioOutputPrivate::QAudioOutputPrivate(const QByteArray& device, const QAudioFormat& format): + audioFormat(format) +{ + QDataStream ds(device); + quint32 did, mode; + + ds >> did >> mode; + + if (QAudio::Mode(mode) == QAudio::AudioInput) + errorCode = QAudio::OpenError; + else { + isOpen = false; + audioDeviceId = AudioDeviceID(did); + audioUnit = 0; + audioIO = 0; + startTime = 0; + totalFrames = 0; + audioBuffer = 0; + internalBufferSize = default_buffer_size; + clockFrequency = AudioGetHostClockFrequency() / 1000; + errorCode = QAudio::NoError; + stateCode = QAudio::StopState; + audioThreadState = Stopped; + + intervalTimer = new QTimer(this); + intervalTimer->setInterval(1000); + connect(intervalTimer, SIGNAL(timeout()), SIGNAL(notify())); + } +} + +QAudioOutputPrivate::~QAudioOutputPrivate() +{ + close(); +} + +bool QAudioOutputPrivate::open() +{ + if (errorCode != QAudio::NoError) + return false; + + if (isOpen) + return true; + + ComponentDescription cd; + cd.componentType = kAudioUnitType_Output; + cd.componentSubType = kAudioUnitSubType_HALOutput; + cd.componentManufacturer = kAudioUnitManufacturer_Apple; + cd.componentFlags = 0; + cd.componentFlagsMask = 0; + + // Open + Component cp = FindNextComponent(NULL, &cd); + if (cp == 0) { + qWarning() << "QAudioOutput: Failed to find HAL Output component"; + return false; + } + + if (OpenAComponent(cp, &audioUnit) != noErr) { + qWarning() << "QAudioOutput: Unable to Open Output Component"; + return false; + } + + // register callback + AURenderCallbackStruct cb; + cb.inputProc = renderCallback; + cb.inputProcRefCon = this; + + if (AudioUnitSetProperty(audioUnit, + kAudioUnitProperty_SetRenderCallback, + kAudioUnitScope_Global, + 0, + &cb, + sizeof(cb)) != noErr) { + qWarning() << "QAudioOutput: Failed to set AudioUnit callback"; + return false; + } + + // Set Audio Device + if (AudioUnitSetProperty(audioUnit, + kAudioOutputUnitProperty_CurrentDevice, + kAudioUnitScope_Global, + 0, + &audioDeviceId, + sizeof(audioDeviceId)) != noErr) { + qWarning() << "QAudioOutput: Unable to use configured device"; + return false; + } + + // Set stream format + streamFormat = toAudioStreamBasicDescription(audioFormat); + + UInt32 size = sizeof(deviceFormat); + if (AudioUnitGetProperty(audioUnit, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Input, + 0, + &deviceFormat, + &size) != noErr) { + qWarning() << "QAudioOutput: Unable to retrieve device format"; + return false; + } + + if (AudioUnitSetProperty(audioUnit, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Input, + 0, + &streamFormat, + sizeof(streamFormat)) != noErr) { + qWarning() << "QAudioOutput: Unable to Set Stream information"; + return false; + } + + // Allocate buffer + UInt32 numberOfFrames = 0; + size = sizeof(UInt32); + if (AudioUnitGetProperty(audioUnit, + kAudioDevicePropertyBufferFrameSize, + kAudioUnitScope_Global, + 0, + &numberOfFrames, + &size) != noErr) { + qWarning() << "QAudioInput: Failed to get audio period size"; + return false; + } + + periodSizeBytes = (numberOfFrames * streamFormat.mSampleRate / deviceFormat.mSampleRate) * + streamFormat.mBytesPerFrame; + if (internalBufferSize < periodSizeBytes * 2) + internalBufferSize = periodSizeBytes * 2; + else + internalBufferSize -= internalBufferSize % streamFormat.mBytesPerFrame; + + audioBuffer = new QAudioOutputBuffer(internalBufferSize, periodSizeBytes, audioFormat); + connect(audioBuffer, SIGNAL(readyRead()), SLOT(inputReady())); // Pull + + audioIO = new MacOutputDevice(audioBuffer, this); + + // Init + if (AudioUnitInitialize(audioUnit)) { + qWarning() << "QAudioOutput: Failed to initialize AudioUnit"; + return false; + } + + isOpen = true; + + return true; +} + +void QAudioOutputPrivate::close() +{ + if (audioUnit != 0) { + AudioOutputUnitStop(audioUnit); + AudioUnitUninitialize(audioUnit); + CloseComponent(audioUnit); + } + + delete audioBuffer; +} + +QAudioFormat QAudioOutputPrivate::format() const +{ + return audioFormat; +} + +QIODevice* QAudioOutputPrivate::start(QIODevice* device) +{ + QIODevice* op = device; + + if (!open()) { + stateCode = QAudio::StopState; + errorCode = QAudio::OpenError; + return audioIO; + } + + reset(); + audioBuffer->reset(); + audioBuffer->setPrefetchDevice(op); + + if (op == 0) { + op = audioIO; + stateCode = QAudio::IdleState; + } + else + stateCode = QAudio::ActiveState; + + // Start + errorCode = QAudio::NoError; + totalFrames = 0; + startTime = AudioGetCurrentHostTime(); + + if (stateCode == QAudio::ActiveState) + audioThreadStart(); + + return op; +} + +void QAudioOutputPrivate::stop() +{ + QMutexLocker lock(&mutex); + if (stateCode != QAudio::StopState) { + audioThreadDrain(); + + stateCode = QAudio::StopState; + errorCode = QAudio::NoError; + QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode)); + } +} + +void QAudioOutputPrivate::reset() +{ + QMutexLocker lock(&mutex); + if (stateCode != QAudio::StopState) { + audioThreadStop(); + + stateCode = QAudio::StopState; + errorCode = QAudio::NoError; + QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode)); + } +} + +void QAudioOutputPrivate::suspend() +{ + QMutexLocker lock(&mutex); + if (stateCode == QAudio::ActiveState || stateCode == QAudio::IdleState) { + audioThreadStop(); + + stateCode = QAudio::SuspendState; + errorCode = QAudio::NoError; + QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode)); + } +} + +void QAudioOutputPrivate::resume() +{ + QMutexLocker lock(&mutex); + if (stateCode == QAudio::SuspendState) { + audioThreadStart(); + + stateCode = QAudio::ActiveState; + errorCode = QAudio::NoError; + QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode)); + } +} + +int QAudioOutputPrivate::bytesFree() const +{ + return audioBuffer->available(); +} + +int QAudioOutputPrivate::periodSize() const +{ + return periodSizeBytes; +} + +void QAudioOutputPrivate::setBufferSize(int bs) +{ + if (stateCode == QAudio::StopState) + internalBufferSize = bs; +} + +int QAudioOutputPrivate::bufferSize() const +{ + return internalBufferSize; +} + +void QAudioOutputPrivate::setNotifyInterval(int milliSeconds) +{ + intervalTimer->setInterval(milliSeconds); +} + +int QAudioOutputPrivate::notifyInterval() const +{ + return intervalTimer->interval(); +} + +qint64 QAudioOutputPrivate::totalTime() const +{ + return totalFrames * 1000000 / audioFormat.frequency(); +} + +qint64 QAudioOutputPrivate::clock() const +{ + return (AudioGetCurrentHostTime() - startTime) / (clockFrequency / 1000); +} + +QAudio::Error QAudioOutputPrivate::error() const +{ + return errorCode; +} + +QAudio::State QAudioOutputPrivate::state() const +{ + return stateCode; +} + +void QAudioOutputPrivate::audioThreadStart() +{ + startTimers(); + audioThreadState = Running; + AudioOutputUnitStart(audioUnit); +} + +void QAudioOutputPrivate::audioThreadStop() +{ + stopTimers(); + if (audioThreadState.testAndSetAcquire(Running, Stopped)) + threadFinished.wait(&mutex); +} + +void QAudioOutputPrivate::audioThreadDrain() +{ + stopTimers(); + if (audioThreadState.testAndSetAcquire(Running, Draining)) + threadFinished.wait(&mutex); +} + +void QAudioOutputPrivate::audioDeviceStop() +{ + AudioOutputUnitStop(audioUnit); + audioThreadState = Stopped; + threadFinished.wakeOne(); +} + +void QAudioOutputPrivate::audioDeviceIdle() +{ + QMutexLocker lock(&mutex); + if (stateCode == QAudio::ActiveState) { + audioDeviceStop(); + + errorCode = QAudio::UnderrunError; + stateCode = QAudio::IdleState; + QMetaObject::invokeMethod(this, "deviceStopped", Qt::QueuedConnection); + } +} + +void QAudioOutputPrivate::audioDeviceError() +{ + QMutexLocker lock(&mutex); + if (stateCode == QAudio::ActiveState) { + audioDeviceStop(); + + errorCode = QAudio::IOError; + stateCode = QAudio::StopState; + QMetaObject::invokeMethod(this, "deviceStopped", Qt::QueuedConnection); + } +} + +void QAudioOutputPrivate::startTimers() +{ + audioBuffer->startFillTimer(); + intervalTimer->start(); +} + +void QAudioOutputPrivate::stopTimers() +{ + audioBuffer->stopFillTimer(); + intervalTimer->stop(); +} + + +void QAudioOutputPrivate::deviceStopped() +{ + intervalTimer->stop(); + emit stateChanged(stateCode); +} + +void QAudioOutputPrivate::inputReady() +{ + QMutexLocker lock(&mutex); + if (stateCode == QAudio::IdleState) { + audioThreadStart(); + + stateCode = QAudio::ActiveState; + errorCode = QAudio::NoError; + + QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode)); + } +} + + +OSStatus QAudioOutputPrivate::renderCallback(void* inRefCon, + AudioUnitRenderActionFlags* ioActionFlags, + const AudioTimeStamp* inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList* ioData) +{ + Q_UNUSED(ioActionFlags) + Q_UNUSED(inTimeStamp) + Q_UNUSED(inBusNumber) + Q_UNUSED(inNumberFrames) + + QAudioOutputPrivate* d = static_cast(inRefCon); + + const int threadState = d->audioThreadState.fetchAndAddAcquire(0); + if (threadState == Stopped) { + ioData->mBuffers[0].mDataByteSize = 0; + d->audioDeviceStop(); + } + else { + const UInt32 bytesPerFrame = d->streamFormat.mBytesPerFrame; + qint64 framesRead; + + framesRead = d->audioBuffer->readFrames((char*)ioData->mBuffers[0].mData, + ioData->mBuffers[0].mDataByteSize / bytesPerFrame); + + if (framesRead > 0) { + ioData->mBuffers[0].mDataByteSize = framesRead * bytesPerFrame; + d->totalFrames += framesRead; + } + else { + ioData->mBuffers[0].mDataByteSize = 0; + if (framesRead == 0) { + if (threadState == Draining) + d->audioDeviceStop(); + else + d->audioDeviceIdle(); + } + else + d->audioDeviceError(); + } + } + + return noErr; +} + + +QT_END_NAMESPACE + +#include "qaudiooutput_mac_p.moc" + diff --git a/src/multimedia/audio/qaudiooutput_mac_p.h b/src/multimedia/audio/qaudiooutput_mac_p.h new file mode 100644 index 0000000..c85cab4 --- /dev/null +++ b/src/multimedia/audio/qaudiooutput_mac_p.h @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#ifndef QAUDIOOUTPUT_MAC_P_H +#define QAUDIOOUTPUT_MAC_P_H + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QIODevice; + +namespace +{ +class QAudioOutputBuffer; +} + +class QAudioOutputPrivate : public QAbstractAudioOutput +{ + Q_OBJECT + +public: + bool isOpen; + int internalBufferSize; + int periodSizeBytes; + qint64 totalFrames; + QAudioFormat audioFormat; + QIODevice* audioIO; + AudioDeviceID audioDeviceId; + AudioUnit audioUnit; + Float64 clockFrequency; + UInt64 startTime; + AudioStreamBasicDescription deviceFormat; + AudioStreamBasicDescription streamFormat; + QAudioOutputBuffer* audioBuffer; + QAtomicInt audioThreadState; + QWaitCondition threadFinished; + QMutex mutex; + QTimer* intervalTimer; + + QAudio::Error errorCode; + QAudio::State stateCode; + + QAudioOutputPrivate(const QByteArray& device, const QAudioFormat& format); + ~QAudioOutputPrivate(); + + bool open(); + void close(); + + QAudioFormat format() const; + + QIODevice* start(QIODevice* device); + void stop(); + void reset(); + void suspend(); + void resume(); + + int bytesFree() const; + int periodSize() const; + + void setBufferSize(int value); + int bufferSize() const; + + void setNotifyInterval(int milliSeconds); + int notifyInterval() const; + + qint64 totalTime() const; + qint64 clock() const; + + QAudio::Error error() const; + QAudio::State state() const; + + void audioThreadStart(); + void audioThreadStop(); + void audioThreadDrain(); + + void audioDeviceStop(); + void audioDeviceIdle(); + void audioDeviceError(); + + void startTimers(); + void stopTimers(); + +signals: + void stateChanged(QAudio::State); + void notify(); + +private slots: + void deviceStopped(); + void inputReady(); + +private: + enum { Running, Draining, Stopped }; + + static OSStatus renderCallback(void* inRefCon, + AudioUnitRenderActionFlags* ioActionFlags, + const AudioTimeStamp* inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList* ioData); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/multimedia/audio/qaudiooutput_win32_p.cpp b/src/multimedia/audio/qaudiooutput_win32_p.cpp new file mode 100644 index 0000000..f681936 --- /dev/null +++ b/src/multimedia/audio/qaudiooutput_win32_p.cpp @@ -0,0 +1,502 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qaudiooutput_win32_p.h" + +//#define DEBUG_AUDIO 1 + +QAudioOutputPrivate::QAudioOutputPrivate(const QByteArray &device, const QAudioFormat& audioFormat): + settings(audioFormat) +{ + bytesAvailable = 0; + buffer_size = 0; + period_size = 0; + m_device = device; + totalTimeValue = 0; + intervalTime = 1000; + audioBuffer = 0; + errorState = QAudio::NoError; + deviceState = QAudio::StopState; + audioSource = 0; + pullMode = true; + InitializeCriticalSection(&waveOutCriticalSection); +} + +QAudioOutputPrivate::~QAudioOutputPrivate() +{ + close(); + DeleteCriticalSection(&waveOutCriticalSection); +} + +void CALLBACK QAudioOutputPrivate::waveOutProc( HWAVEOUT hWaveOut, UINT uMsg, + DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 ) +{ + Q_UNUSED(dwParam1) + Q_UNUSED(dwParam2) + Q_UNUSED(hWaveOut) + + QAudioOutputPrivate* qAudio; + qAudio = (QAudioOutputPrivate*)(dwInstance); + if(!qAudio) + return; + + switch(uMsg) { + case WOM_OPEN: + qAudio->feedback(); + break; + case WOM_CLOSE: + return; + case WOM_DONE: + EnterCriticalSection(&waveOutCriticalSection); + qAudio->waveFreeBlockCount++; + if(qAudio->waveFreeBlockCount >= qAudio->buffer_size/qAudio->period_size) + qAudio->waveFreeBlockCount = qAudio->buffer_size/qAudio->period_size; + LeaveCriticalSection(&waveOutCriticalSection); + qAudio->feedback(); + break; + default: + return; + } +} + +WAVEHDR* QAudioOutputPrivate::allocateBlocks(int size, int count) +{ + int i; + unsigned char* buffer; + WAVEHDR* blocks; + DWORD totalBufferSize = (size + sizeof(WAVEHDR))*count; + + if((buffer=(unsigned char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, + totalBufferSize)) == 0) { + qWarning("QAudioOutput: Memory allocation error"); + return 0; + } + blocks = (WAVEHDR*)buffer; + buffer += sizeof(WAVEHDR)*count; + for(i = 0; i < count; i++) { + blocks[i].dwBufferLength = size; + blocks[i].lpData = (LPSTR)buffer; + buffer += size; + } + return blocks; +} + +void QAudioOutputPrivate::freeBlocks(WAVEHDR* blockArray) +{ + HeapFree(GetProcessHeap(), 0, blockArray); +} + +QAudioFormat QAudioOutputPrivate::format() const +{ + return settings; +} + +QIODevice* QAudioOutputPrivate::start(QIODevice* device) +{ + if(deviceState != QAudio::StopState) + close(); + + if(!pullMode && audioSource) { + delete audioSource; + } + + if(device) { + //set to pull mode + pullMode = true; + audioSource = device; + deviceState = QAudio::ActiveState; + } else { + //set to push mode + pullMode = false; + audioSource = new OutputPrivate(this); + audioSource->open(QIODevice::WriteOnly|QIODevice::Unbuffered); + deviceState = QAudio::IdleState; + } + + if( !open() ) + return 0; + + emit stateChanged(deviceState); + + return audioSource; +} + +void QAudioOutputPrivate::stop() +{ + if(deviceState == QAudio::StopState) + return; + deviceState = QAudio::StopState; + close(); + if(!pullMode && audioSource) { + delete audioSource; + audioSource = 0; + } + emit stateChanged(deviceState); +} + +bool QAudioOutputPrivate::open() +{ +#ifdef DEBUG_AUDIO + QTime now(QTime::currentTime()); + qDebug()<> 3) * wfx.nChannels; + wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec; + + UINT_PTR devId = WAVE_MAPPER; + + WAVEOUTCAPS woc; + unsigned long iNumDevs,ii; + iNumDevs = waveOutGetNumDevs(); + for(ii=0;ii 0) { + if(waveFreeBlockCount==0) + break; + + if(current->dwFlags & WHDR_PREPARED) + waveOutUnprepareHeader(hWaveOut, current, sizeof(WAVEHDR)); + + if(l < period_size) + remain = l; + else + remain = period_size; + memcpy(current->lpData, p, remain); + + l -= remain; + p += remain; + current->dwBufferLength = remain; + waveOutPrepareHeader(hWaveOut, current, sizeof(WAVEHDR)); + waveOutWrite(hWaveOut, current, sizeof(WAVEHDR)); + + EnterCriticalSection(&waveOutCriticalSection); + waveFreeBlockCount--; + LeaveCriticalSection(&waveOutCriticalSection); +#ifdef DEBUG_AUDIO + qDebug("write out l=%d, waveFreeBlockCount=%d", + current->dwBufferLength,waveFreeBlockCount); +#endif + totalTimeValue += current->dwBufferLength + /(settings.channels()*(settings.sampleSize()/8)) + *1000000/settings.frequency();; + waveCurrentBlock++; + waveCurrentBlock %= buffer_size/period_size; + current = &waveBlocks[waveCurrentBlock]; + current->dwUser = 0; + } + return (len-l); +} + +void QAudioOutputPrivate::resume() +{ + if(deviceState == QAudio::SuspendState) { + deviceState = QAudio::ActiveState; + errorState = QAudio::NoError; + waveOutRestart(hWaveOut); + QTimer::singleShot(10, this, SLOT(feedback())); + emit stateChanged(deviceState); + } +} + +void QAudioOutputPrivate::suspend() +{ + if(deviceState == QAudio::ActiveState) { + waveOutPause(hWaveOut); + deviceState = QAudio::SuspendState; + errorState = QAudio::NoError; + emit stateChanged(deviceState); + } +} + +void QAudioOutputPrivate::feedback() +{ +#ifdef DEBUG_AUDIO + QTime now(QTime::currentTime()); + qDebug()<= period_size) + QMetaObject::invokeMethod(this, "deviceReady", Qt::QueuedConnection); + } +} + +bool QAudioOutputPrivate::deviceReady() +{ + if(pullMode) { + int i = 0; + int chunks = bytesAvailable/period_size; +#ifdef DEBUG_AUDIO + qDebug()<<"deviceReady() avail="< +#include +#include +#include + +#include +#include + + +class tst_QAudioDeviceId : public QObject +{ + Q_OBJECT + +public: + tst_QAudioDeviceId(QObject* parent=0) : QObject(parent) {} + +private slots: + void checkNull(); + void checkEquality(); +}; + +void tst_QAudioDeviceId::checkNull() +{ + // Default constructed is null. + QAudioDeviceId deviceId0; + QVERIFY(deviceId0.isNull()); + + // Null is transferred + QAudioDeviceId deviceId1(deviceId0); + QVERIFY(deviceId1.isNull()); +} + +void tst_QAudioDeviceId::checkEquality() +{ + QAudioDeviceId deviceId0; + QAudioDeviceId deviceId1; + + // Null ids are equivalent + QVERIFY(deviceId0 == deviceId1); + QVERIFY(!(deviceId0 != deviceId1)); + + deviceId1 = QAudioDeviceInfo::defaultOutputDevice(); + + // Different + QVERIFY(deviceId0 != deviceId1); + QVERIFY(!(deviceId0 == deviceId1)); + + // Same + deviceId0 = deviceId1; + + QVERIFY(deviceId0 == deviceId1); + QVERIFY(!(deviceId0 != deviceId1)); +} + +QTEST_MAIN(tst_QAudioDeviceId) + +#include "tst_qaudiodeviceid.moc" diff --git a/tests/auto/qaudiodeviceinfo/qaudiodeviceinfo.pro b/tests/auto/qaudiodeviceinfo/qaudiodeviceinfo.pro new file mode 100644 index 0000000..695987c --- /dev/null +++ b/tests/auto/qaudiodeviceinfo/qaudiodeviceinfo.pro @@ -0,0 +1,7 @@ +load(qttest_p4) + +DEFINES += SRCDIR=\\\"$$PWD/\\\" + +SOURCES += tst_qaudiodeviceinfo.cpp + +QT = core multimedia diff --git a/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp b/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp new file mode 100644 index 0000000..c2cd97e --- /dev/null +++ b/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include +#include + +#include +#include + + +class tst_QAudioDeviceInfo : public QObject +{ + Q_OBJECT +public: + tst_QAudioDeviceInfo(QObject* parent=0) : QObject(parent) {} + +private slots: + void checkAvailableDefaultInput(); + void checkAvailableDefaultOutput(); + void outputList(); + void codecs(); + void channels(); + void sampleSizes(); + void byteOrders(); + void sampleTypes(); + void frequencies(); + void isformat(); + void preferred(); + void nearest(); + +private: + QAudioDeviceInfo* device; +}; + +void tst_QAudioDeviceInfo::checkAvailableDefaultInput() +{ + QVERIFY(!QAudioDeviceInfo::defaultInputDevice().isNull()); +} + +void tst_QAudioDeviceInfo::checkAvailableDefaultOutput() +{ + QVERIFY(!QAudioDeviceInfo::defaultOutputDevice().isNull()); +} + +void tst_QAudioDeviceInfo::outputList() +{ + QList devices = QAudioDeviceInfo::deviceList(QAudio::AudioOutput); + QVERIFY(devices.size() > 0); + device = new QAudioDeviceInfo(devices.at(0), this); +} + +void tst_QAudioDeviceInfo::codecs() +{ + QStringList avail = device->supportedCodecs(); + QVERIFY(avail.size() > 0); +} + +void tst_QAudioDeviceInfo::channels() +{ + QList avail = device->supportedChannels(); + QVERIFY(avail.size() > 0); +} + +void tst_QAudioDeviceInfo::sampleSizes() +{ + QList avail = device->supportedSampleSizes(); + QVERIFY(avail.size() > 0); +} + +void tst_QAudioDeviceInfo::byteOrders() +{ + QList avail = device->supportedByteOrders(); + QVERIFY(avail.size() > 0); +} + +void tst_QAudioDeviceInfo::sampleTypes() +{ + QList avail = device->supportedSampleTypes(); + QVERIFY(avail.size() > 0); +} + +void tst_QAudioDeviceInfo::frequencies() +{ + QList avail = device->supportedFrequencies(); + QVERIFY(avail.size() > 0); +} + +void tst_QAudioDeviceInfo::isformat() +{ + QAudioFormat format; + format.setFrequency(44100); + format.setChannels(2); + format.setSampleType(QAudioFormat::SignedInt); + format.setByteOrder(QAudioFormat::LittleEndian); + format.setSampleSize(16); + format.setCodec("audio/pcm"); + + // Should always be true for these format + QVERIFY(device->isFormatSupported(format)); +} + +void tst_QAudioDeviceInfo::preferred() +{ + QAudioFormat format = device->preferredFormat(); + QVERIFY(format.frequency() == 44100); + QVERIFY(format.channels() == 2); +} + +void tst_QAudioDeviceInfo::nearest() +{ + QAudioFormat format1, format2; + format1.setFrequency(8000); + format2 = device->nearestFormat(format1); + QVERIFY(format2.frequency() == 44100); +} + +QTEST_MAIN(tst_QAudioDeviceInfo) + +#include "tst_qaudiodeviceinfo.moc" diff --git a/tests/auto/qaudioformat/qaudioformat.pro b/tests/auto/qaudioformat/qaudioformat.pro new file mode 100644 index 0000000..78962d7 --- /dev/null +++ b/tests/auto/qaudioformat/qaudioformat.pro @@ -0,0 +1,7 @@ +load(qttest_p4) + +DEFINES += SRCDIR=\\\"$$PWD/\\\" + +SOURCES += tst_qaudioformat.cpp + +QT = core multimedia diff --git a/tests/auto/qaudioformat/tst_qaudioformat.cpp b/tests/auto/qaudioformat/tst_qaudioformat.cpp new file mode 100644 index 0000000..bcfc78f --- /dev/null +++ b/tests/auto/qaudioformat/tst_qaudioformat.cpp @@ -0,0 +1,180 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include +#include + +#include +#include + + +class tst_QAudioFormat : public QObject +{ + Q_OBJECT + +public: + tst_QAudioFormat(QObject* parent=0) : QObject(parent) {} + +private slots: + void checkNull(); + void checkFrequency(); + void checkChannels(); + void checkSampleSize(); + void checkCodec(); + void checkByteOrder(); + void checkSampleType(); + void checkEquality(); + void checkAssignment(); +}; + +void tst_QAudioFormat::checkNull() +{ + // Default constructed QAudioFormat is null. + QAudioFormat audioFormat0; + QVERIFY(audioFormat0.isNull()); + + // Null is transferred + QAudioFormat audioFormat1(audioFormat0); + QVERIFY(audioFormat1.isNull()); + + // Null is voided on activity + audioFormat0.setFrequency(44100); + QVERIFY(!audioFormat0.isNull()); +} + +void tst_QAudioFormat::checkFrequency() +{ + QAudioFormat audioFormat; + audioFormat.setFrequency(44100); + QVERIFY(audioFormat.frequency() == 44100); +} + +void tst_QAudioFormat::checkChannels() +{ + QAudioFormat audioFormat; + audioFormat.setChannels(2); + QVERIFY(audioFormat.channels() == 2); +} + +void tst_QAudioFormat::checkSampleSize() +{ + QAudioFormat audioFormat; + audioFormat.setSampleSize(16); + QVERIFY(audioFormat.sampleSize() == 16); +} + +void tst_QAudioFormat::checkCodec() +{ + QAudioFormat audioFormat; + audioFormat.setCodec(QString::fromLatin1("audio/pcm")); + QVERIFY(audioFormat.codec() == QString::fromLatin1("audio/pcm")); +} + +void tst_QAudioFormat::checkByteOrder() +{ + QAudioFormat audioFormat; + audioFormat.setByteOrder(QAudioFormat::LittleEndian); + QVERIFY(audioFormat.byteOrder() == QAudioFormat::LittleEndian); +} + +void tst_QAudioFormat::checkSampleType() +{ + QAudioFormat audioFormat; + audioFormat.setSampleType(QAudioFormat::SignedInt); + QVERIFY(audioFormat.sampleType() == QAudioFormat::SignedInt); +} + +void tst_QAudioFormat::checkEquality() +{ + QAudioFormat audioFormat0; + QAudioFormat audioFormat1; + + // Null formats are equivalent + QVERIFY(audioFormat0 == audioFormat1); + QVERIFY(!(audioFormat0 != audioFormat1)); + + // on filled formats + audioFormat0.setFrequency(8000); + audioFormat0.setChannels(1); + audioFormat0.setSampleSize(8); + audioFormat0.setCodec("audio/pcm"); + audioFormat0.setByteOrder(QAudioFormat::LittleEndian); + audioFormat0.setSampleType(QAudioFormat::UnSignedInt); + + audioFormat1.setFrequency(8000); + audioFormat1.setChannels(1); + audioFormat1.setSampleSize(8); + audioFormat1.setCodec("audio/pcm"); + audioFormat1.setByteOrder(QAudioFormat::LittleEndian); + audioFormat1.setSampleType(QAudioFormat::UnSignedInt); + + QVERIFY(audioFormat0 == audioFormat1); + QVERIFY(!(audioFormat0 != audioFormat1)); + + audioFormat0.setFrequency(44100); + QVERIFY(audioFormat0 != audioFormat1); + QVERIFY(!(audioFormat0 == audioFormat1)); +} + +void tst_QAudioFormat::checkAssignment() +{ + QAudioFormat audioFormat0; + QAudioFormat audioFormat1; + + audioFormat0.setFrequency(8000); + audioFormat0.setChannels(1); + audioFormat0.setSampleSize(8); + audioFormat0.setCodec("audio/pcm"); + audioFormat0.setByteOrder(QAudioFormat::LittleEndian); + audioFormat0.setSampleType(QAudioFormat::UnSignedInt); + + audioFormat1 = audioFormat0; + QVERIFY(audioFormat1 == audioFormat0); + + QAudioFormat audioFormat2(audioFormat0); + QVERIFY(audioFormat2 == audioFormat0); +} + +QTEST_MAIN(tst_QAudioFormat) + +#include "tst_qaudioformat.moc" diff --git a/tests/auto/qaudioinput/qaudioinput.pro b/tests/auto/qaudioinput/qaudioinput.pro new file mode 100644 index 0000000..8a03749 --- /dev/null +++ b/tests/auto/qaudioinput/qaudioinput.pro @@ -0,0 +1,7 @@ +load(qttest_p4) + +DEFINES += SRCDIR=\\\"$$PWD/\\\" + +SOURCES += tst_qaudioinput.cpp + +QT = core multimedia diff --git a/tests/auto/qaudioinput/tst_qaudioinput.cpp b/tests/auto/qaudioinput/tst_qaudioinput.cpp new file mode 100644 index 0000000..6e16320 --- /dev/null +++ b/tests/auto/qaudioinput/tst_qaudioinput.cpp @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include + + +class tst_QAudioInput : public QObject +{ + Q_OBJECT +public: + tst_QAudioInput(QObject* parent=0) : QObject(parent) {} + +private slots: + void initTestCase(); + void settings(); + void notifyInterval(); + void pullFile(); + +private: + QAudioFormat format; + QAudioInput* audio; +}; + +void tst_QAudioInput::initTestCase() +{ + format.setFrequency(8000); + format.setChannels(1); + format.setSampleSize(8); + format.setCodec("audio/pcm"); + format.setByteOrder(QAudioFormat::LittleEndian); + format.setSampleType(QAudioFormat::UnSignedInt); + + audio = new QAudioInput(format, this); +} + +void tst_QAudioInput::settings() +{ + QAudioFormat f = audio->format(); + + QVERIFY(format.channels() == f.channels()); + QVERIFY(format.frequency() == f.frequency()); + QVERIFY(format.sampleSize() == f.sampleSize()); + QVERIFY(format.codec() == f.codec()); + QVERIFY(format.byteOrder() == f.byteOrder()); + QVERIFY(format.sampleType() == f.sampleType()); +} + +void tst_QAudioInput::notifyInterval() +{ + QVERIFY(audio->notifyInterval() == 1000); // Default + + audio->setNotifyInterval(500); + QVERIFY(audio->notifyInterval() == 500); // Custom + + audio->setNotifyInterval(1000); // reset +} + +void tst_QAudioInput::pullFile() +{ + QFile filename(SRCDIR "test.raw"); + filename.open( QIODevice::WriteOnly | QIODevice::Truncate ); + + QSignalSpy readSignal(audio, SIGNAL(notify())); + audio->start(&filename); + + QTest::qWait(5000); + + QVERIFY(readSignal.count() > 0); + QVERIFY(audio->totalTime() > 0); + + audio->stop(); + filename.close(); +} + +QTEST_MAIN(tst_QAudioInput) + +#include "tst_qaudioinput.moc" diff --git a/tests/auto/qaudiooutput/4.wav b/tests/auto/qaudiooutput/4.wav new file mode 100644 index 0000000..e31b0609 Binary files /dev/null and b/tests/auto/qaudiooutput/4.wav differ diff --git a/tests/auto/qaudiooutput/qaudiooutput.pro b/tests/auto/qaudiooutput/qaudiooutput.pro new file mode 100644 index 0000000..6c07c64 --- /dev/null +++ b/tests/auto/qaudiooutput/qaudiooutput.pro @@ -0,0 +1,12 @@ +load(qttest_p4) + +DEFINES += SRCDIR=\\\"$$PWD/\\\" + +SOURCES += tst_qaudiooutput.cpp + +QT = core multimedia + +wince*: { + deploy.sources += 4.wav + DEPLOYMENT = deploy +} diff --git a/tests/auto/qaudiooutput/tst_qaudiooutput.cpp b/tests/auto/qaudiooutput/tst_qaudiooutput.cpp new file mode 100644 index 0000000..0f94faa --- /dev/null +++ b/tests/auto/qaudiooutput/tst_qaudiooutput.cpp @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + + +#include +#include +#include +#include +#include +#include + + +class tst_QAudioOutput : public QObject +{ + Q_OBJECT +public: + tst_QAudioOutput(QObject* parent=0) : QObject(parent) {} + +private slots: + void initTestCase(); + void settings(); + void notifyInterval(); + void pullFile(); + void pushFile(); + +private: + QAudioFormat format; + QAudioOutput* audio; +}; + +void tst_QAudioOutput::initTestCase() +{ + format.setFrequency(8000); + format.setChannels(1); + format.setSampleSize(8); + format.setCodec("audio/pcm"); + format.setByteOrder(QAudioFormat::LittleEndian); + format.setSampleType(QAudioFormat::UnSignedInt); + + audio = new QAudioOutput(format, this); +} + +void tst_QAudioOutput::settings() +{ + QAudioFormat f = audio->format(); + + QVERIFY(format.channels() == f.channels()); + QVERIFY(format.frequency() == f.frequency()); + QVERIFY(format.sampleSize() == f.sampleSize()); + QVERIFY(format.codec() == f.codec()); + QVERIFY(format.byteOrder() == f.byteOrder()); + QVERIFY(format.sampleType() == f.sampleType()); +} + +void tst_QAudioOutput::notifyInterval() +{ + QVERIFY(audio->notifyInterval() == 1000); // Default + + audio->setNotifyInterval(500); + QVERIFY(audio->notifyInterval() == 500); // Custom + + audio->setNotifyInterval(1000); // reset +} + +void tst_QAudioOutput::pullFile() +{ + QFile filename(SRCDIR "4.wav"); + QVERIFY(filename.exists()); + filename.open(QIODevice::ReadOnly); + + QSignalSpy readSignal(audio, SIGNAL(notify())); + audio->setNotifyInterval(100); + audio->start(&filename); + + QTestEventLoop::instance().enterLoop(1); + // 4.wav is a little less than 700ms, so notify should fire 6 times! + QVERIFY(readSignal.count() >= 6); + QVERIFY(audio->totalTime() == 692250); + + audio->stop(); + filename.close(); +} + +void tst_QAudioOutput::pushFile() +{ + QFile filename(SRCDIR "4.wav"); + QVERIFY(filename.exists()); + filename.open(QIODevice::ReadOnly); + + const qint64 fileSize = filename.size(); + + QIODevice* feed = audio->start(0); + + char* buffer = new char[fileSize]; + filename.read(buffer, fileSize); + + qint64 counter=0; + qint64 written=0; + while(written < fileSize) { + written+=feed->write(buffer+written,fileSize-written); + QTest::qWait(20); + counter++; + } + QTestEventLoop::instance().enterLoop(1); + + QVERIFY(written == fileSize); + QVERIFY(audio->totalTime() == 692250); + + audio->stop(); + filename.close(); + delete [] buffer; + delete audio; +} + +QTEST_MAIN(tst_QAudioOutput) + +#include "tst_qaudiooutput.moc" diff --git a/tests/auto/tests.xml b/tests/auto/tests.xml index a5386b2..ccfc380 100644 --- a/tests/auto/tests.xml +++ b/tests/auto/tests.xml @@ -271,6 +271,10 @@ + + + + @@ -676,6 +680,10 @@ + + + + diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index c938919..f32e7dc 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -245,6 +245,7 @@ Configure::Configure( int& argc, char** argv ) dictionary[ "XMLPATTERNS" ] = "auto"; dictionary[ "PHONON" ] = "auto"; dictionary[ "PHONON_BACKEND" ] = "yes"; + dictionary[ "MULTIMEDIA" ] = "yes"; dictionary[ "DIRECTSHOW" ] = "no"; dictionary[ "WEBKIT" ] = "auto"; dictionary[ "PLUGIN_MANIFESTS" ] = "yes"; @@ -843,6 +844,10 @@ void Configure::parseCmdLine() dictionary[ "XMLPATTERNS" ] = "no"; } else if( configCmdLine.at(i) == "-xmlpatterns" ) { dictionary[ "XMLPATTERNS" ] = "yes"; + } else if( configCmdLine.at(i) == "-no-multimedia" ) { + dictionary[ "MULTIMEDIA" ] = "no"; + } else if( configCmdLine.at(i) == "-multimedia" ) { + dictionary[ "MULTIMEDIA" ] = "yes"; } else if( configCmdLine.at(i) == "-no-phonon" ) { dictionary[ "PHONON" ] = "no"; } else if( configCmdLine.at(i) == "-phonon" ) { @@ -1425,6 +1430,7 @@ bool Configure::displayHelp() "[-no-openssl] [-no-dbus] [-dbus] [-dbus-linked] [-platform ]\n" "[-qtnamespace ] [-qtlibinfix ] [-no-phonon]\n" "[-phonon] [-no-phonon-backend] [-phonon-backend]\n" + "[-no-multimedia] [-multimedia]\n" "[-no-webkit] [-webkit]\n" "[-no-scripttools] [-scripttools]\n" "[-graphicssystem raster|opengl]\n\n", 0, 7); @@ -1599,6 +1605,8 @@ bool Configure::displayHelp() desc("PHONON", "yes", "-phonon", "Compile the Phonon module (Phonon is built if a decent C++ compiler is used.)"); desc("PHONON_BACKEND","no", "-no-phonon-backend","Do not compile the platform-specific Phonon backend-plugin"); desc("PHONON_BACKEND","yes","-phonon-backend", "Compile in the platform-specific Phonon backend-plugin"); + desc("MULTIMEDIA", "no", "-no-multimedia", "Do not compile the multimedia module"); + desc("MULTIMEDIA", "yes","-multimedia", "Compile in multimedia module"); desc("WEBKIT", "no", "-no-webkit", "Do not compile in the WebKit module"); desc("WEBKIT", "yes", "-webkit", "Compile in the WebKit module (WebKit is built if a decent C++ compiler is used.)"); desc("SCRIPTTOOLS", "no", "-no-scripttools", "Do not build the QtScriptTools module."); @@ -1867,6 +1875,8 @@ bool Configure::checkAvailability(const QString &part) if (!findFile("msdmo.lib")) cout << "msdmo.lib not found" << endl; if (!findFile("d3d9.h")) cout << "d3d9.h not found" << endl; } + } else if (part == "MULTIMEDIA") { + available = true; } else if (part == "WEBKIT") { available = (dictionary.value("QMAKESPEC") == "win32-msvc2005") || (dictionary.value("QMAKESPEC") == "win32-msvc2008") || (dictionary.value("QMAKESPEC") == "win32-g++"); } else if (part == "SCRIPTTOOLS") { @@ -2302,6 +2312,9 @@ void Configure::generateOutputVars() qtConfig += "phonon-backend"; } + if (dictionary["MULTIMEDIA"] == "yes") + qtConfig += "multimedia"; + if (dictionary["WEBKIT"] == "yes") qtConfig += "webkit"; @@ -2662,6 +2675,7 @@ void Configure::generateConfigfiles() if(dictionary["IPV6"] == "no") qconfigList += "QT_NO_IPV6"; if(dictionary["WEBKIT"] == "no") qconfigList += "QT_NO_WEBKIT"; if(dictionary["PHONON"] == "no") qconfigList += "QT_NO_PHONON"; + if(dictionary["MULTIMEDIA"] == "no") qconfigList += "QT_NO_MULTIMEDIA"; if(dictionary["XMLPATTERNS"] == "no") qconfigList += "QT_NO_XMLPATTERNS"; if(dictionary["SCRIPTTOOLS"] == "no") qconfigList += "QT_NO_SCRIPTTOOLS"; @@ -2920,6 +2934,7 @@ void Configure::displayConfig() cout << "QtDBus support.............." << dictionary[ "DBUS" ] << endl; cout << "QtXmlPatterns support......." << dictionary[ "XMLPATTERNS" ] << endl; cout << "Phonon support.............." << dictionary[ "PHONON" ] << endl; + cout << "Multimedia support.........." << dictionary[ "MULTIMEDIA" ] << endl; cout << "WebKit support.............." << dictionary[ "WEBKIT" ] << endl; cout << "QtScriptTools support......." << dictionary[ "SCRIPTTOOLS" ] << endl; cout << "Graphics System............." << dictionary[ "GRAPHICS_SYSTEM" ] << endl; -- cgit v0.12 From bedfccd293740b00b7cc9f212c119433a4d82d12 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 5 Aug 2009 07:35:40 +0200 Subject: Compile fix (QGraphicsItem::setXRotation was removed). a6ea9ce6990003856ecadcca8ce9ddf37949363d removed this function; the benchmark was not updated. Reviewed-by: TrustMe --- tests/benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/tests/benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp index d072d08..42f2e6b 100644 --- a/tests/benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp @@ -34,7 +34,6 @@ private slots: void shear(); void translate(); void setRotation(); - void setRotationXYZ(); }; tst_QGraphicsItem::tst_QGraphicsItem() @@ -150,18 +149,7 @@ void tst_QGraphicsItem::setRotation() QGraphicsItem *item = scene.addRect(QRectF(0, 0, 100, 100)); QBENCHMARK { - item->setXRotation(45); - item->transform(); // prevent lazy optimizing - } -} - -void tst_QGraphicsItem::setRotationXYZ() -{ - QGraphicsScene scene; - QGraphicsItem *item = scene.addRect(QRectF(0, 0, 100, 100)); - - QBENCHMARK { - item->setRotation(45, 45, 45); + item->setRotation(45); item->transform(); // prevent lazy optimizing } } -- cgit v0.12 From b0470cd7553d26e73929bf9719eea9f49aeb6824 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 5 Aug 2009 08:16:59 +0200 Subject: Add benchmarks for QGraphicsItem::setParenItem(). Ensure we test simple and deep constructs of setParentItem(). These benchmarks don't cover slowness in ancestor flag updating. QVariant is already identified as a contributor to this slowness, as is updating of the depth value (a deep tree crawl). Reviewed-by: Aaron Kennedy --- tests/benchmarks/qgraphicsitem/qgraphicsitem.pro | 1 - .../benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp | 26 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/tests/benchmarks/qgraphicsitem/qgraphicsitem.pro b/tests/benchmarks/qgraphicsitem/qgraphicsitem.pro index c8fc07b..726bb96 100644 --- a/tests/benchmarks/qgraphicsitem/qgraphicsitem.pro +++ b/tests/benchmarks/qgraphicsitem/qgraphicsitem.pro @@ -3,4 +3,3 @@ TEMPLATE = app TARGET = tst_qgraphicsitem SOURCES += tst_qgraphicsitem.cpp - diff --git a/tests/benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp index 42f2e6b..62a5b5c 100644 --- a/tests/benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp @@ -25,6 +25,8 @@ public slots: void cleanup(); private slots: + void setParentItem(); + void setParentItem_deep(); void setPos_data(); void setPos(); void setTransform_data(); @@ -52,6 +54,30 @@ void tst_QGraphicsItem::cleanup() { } +void tst_QGraphicsItem::setParentItem() +{ + QBENCHMARK { + QGraphicsRectItem rect; + QGraphicsRectItem *childRect = new QGraphicsRectItem; + childRect->setParentItem(&rect); + } +} + +void tst_QGraphicsItem::setParentItem_deep() +{ + QBENCHMARK { + QGraphicsRectItem rect; + QGraphicsRectItem *lastRect = ▭ + for (int i = 0; i < 10; ++i) { + QGraphicsRectItem *childRect = new QGraphicsRectItem; + childRect->setParentItem(lastRect); + lastRect = childRect; + } + QGraphicsItem *first = rect.children().first(); + first->setParentItem(0); + } +} + void tst_QGraphicsItem::setPos_data() { QTest::addColumn("pos"); -- cgit v0.12 From b008dfbd67176948f6fdf830dc99d23a538a6b9c Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 5 Aug 2009 08:45:44 +0200 Subject: Add benchmark for deleting an item with many children. Task-number: 229124 Reviewed-by: TrustMe --- tests/benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp index 62a5b5c..ee27ebe 100644 --- a/tests/benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp @@ -27,6 +27,7 @@ public slots: private slots: void setParentItem(); void setParentItem_deep(); + void deleteItemWithManyChildren(); void setPos_data(); void setPos(); void setTransform_data(); @@ -78,6 +79,16 @@ void tst_QGraphicsItem::setParentItem_deep() } } +void tst_QGraphicsItem::deleteItemWithManyChildren() +{ + QBENCHMARK { + QGraphicsRectItem *rect = new QGraphicsRectItem; + for (int i = 0; i < 1000; ++i) + new QGraphicsRectItem(rect); + delete rect; + } +} + void tst_QGraphicsItem::setPos_data() { QTest::addColumn("pos"); -- cgit v0.12 From decc287134139c61da5610afc060a6ca8d09f368 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 4 Aug 2009 15:59:25 +0200 Subject: Cocoa: Menus show old selected values. We never told Cocoa that it needed to redraw the window view when a window was shown. This is implicit if the window is shown for the first time, but needs to be done explicit if you hide and show it again. Task-number: 254672 Reviewed-by: bnilsen --- src/gui/kernel/qwidget_mac.mm | 6 ++++++ tests/auto/qwidget_window/tst_qwidget_window.cpp | 24 +++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 8913c89..057df81 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -3249,6 +3249,12 @@ void QWidgetPrivate::show_sys() #ifndef QT_MAC_USE_COCOA SizeWindow(window, q->width(), q->height(), true); #endif + +#ifdef QT_MAC_USE_COCOA + // Make sure that we end up sending a repaint event to + // the widget if the window has been visible one before: + [qt_mac_get_contentview_for(window) setNeedsDisplay:YES]; +#endif if(qt_mac_is_macsheet(q)) { qt_event_request_showsheet(q); } else if(qt_mac_is_macdrawer(q)) { diff --git a/tests/auto/qwidget_window/tst_qwidget_window.cpp b/tests/auto/qwidget_window/tst_qwidget_window.cpp index f059abe..6dddfe8 100644 --- a/tests/auto/qwidget_window/tst_qwidget_window.cpp +++ b/tests/auto/qwidget_window/tst_qwidget_window.cpp @@ -78,6 +78,7 @@ private slots: void tst_windowFilePath(); void tst_showWithoutActivating(); + void tst_paintEventOnSecondShow(); }; void tst_QWidget_window::initTestCase() @@ -150,7 +151,9 @@ class TestWidget : public QWidget { public: int m_first, m_next; - void reset(){ m_first = m_next = 0; } + bool paintEventReceived; + + void reset(){ m_first = m_next = 0; paintEventReceived = false; } bool event(QEvent *event) { switch (event->type()) { @@ -162,6 +165,10 @@ public: m_next = event->type(); else m_first = event->type(); + break; + case QEvent::Paint: + paintEventReceived = true; + break; default: break; } @@ -300,5 +307,20 @@ void tst_QWidget_window::tst_showWithoutActivating() #endif // Q_WS_X11 } +void tst_QWidget_window::tst_paintEventOnSecondShow() +{ + TestWidget w; + w.show(); + w.hide(); + + w.reset(); + w.show(); +#ifdef Q_WS_X11 + QTest::qWait(500); +#endif + QApplication::processEvents(); + QVERIFY(w.paintEventReceived); +} + QTEST_MAIN(tst_QWidget_window) #include "tst_qwidget_window.moc" -- cgit v0.12 From 83c76bb2d1eeca2003720d243ef656aa241a3d49 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Wed, 5 Aug 2009 10:27:44 +0200 Subject: qdoc: Removed the "No such group" qdoc error. This error was printed if you used a \ingroup xxx, but there was no \group xxx anywhere. Now we will stop using the \group command, but we will retain the \ingroup command for use with the \annotatedlist command. --- tools/qdoc3/tree.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/qdoc3/tree.cpp b/tools/qdoc3/tree.cpp index d75af70..f832062 100644 --- a/tools/qdoc3/tree.cpp +++ b/tools/qdoc3/tree.cpp @@ -575,10 +575,12 @@ void Tree::resolveGroups() if (fake && fake->subType() == Node::Group) { fake->addGroupMember(i.value()); } +#if 0 else { if (prevGroup != i.key()) i.value()->doc().location().warning(tr("No such group '%1'").arg(i.key())); } +#endif prevGroup = i.key(); } -- cgit v0.12 From a3cb29b310f3d8b4de919bb19d98ae93edde7c85 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 5 Aug 2009 11:01:12 +0200 Subject: sequential animation group: add autotest for pause/resume --- .../tst_qsequentialanimationgroup.cpp | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp b/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp index 97ff04b..744ba52 100644 --- a/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp +++ b/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp @@ -88,6 +88,7 @@ private slots: void currentAnimationWithZeroDuration(); void insertAnimation(); void clearAnimations(); + void pauseResume(); }; tst_QSequentialAnimationGroup::tst_QSequentialAnimationGroup() @@ -1644,5 +1645,40 @@ void tst_QSequentialAnimationGroup::clearAnimations() QCOMPARE(group.state(), QAbstractAnimation::Running); } +void tst_QSequentialAnimationGroup::pauseResume() +{ + QObject dummy; + dummy.setProperty("foo", 0); + QParallelAnimationGroup group; + QPropertyAnimation *anim = new QPropertyAnimation(&dummy, "foo", &group); + anim->setDuration(250); + anim->setEndValue(250); + QSignalSpy spy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + QCOMPARE(group.duration(), 250); + group.start(); + QTest::qWait(100); + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(anim->state(), QAnimationGroup::Running); + QCOMPARE(spy.count(), 1); + spy.clear(); + const int currentTime = group.currentTime(); + QCOMPARE(anim->currentTime(), currentTime); + + group.pause(); + QCOMPARE(group.state(), QAnimationGroup::Paused); + QCOMPARE(group.currentTime(), currentTime); + QCOMPARE(anim->state(), QAnimationGroup::Paused); + QCOMPARE(anim->currentTime(), currentTime); + QCOMPARE(spy.count(), 1); + spy.clear(); + + group.resume(); + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(group.currentTime(), currentTime); + QCOMPARE(anim->state(), QAnimationGroup::Running); + QCOMPARE(anim->currentTime(), currentTime); + QCOMPARE(spy.count(), 1); +} + QTEST_MAIN(tst_QSequentialAnimationGroup) #include "tst_qsequentialanimationgroup.moc" -- cgit v0.12 From bcf41cf9dbe9921bb50b8cf2fcdcd9884e94412f Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 5 Aug 2009 11:03:55 +0200 Subject: Make \annotatedlist work also in pages that are not \group pages. The command right now only lists the classes in the group, in alphabetical order. Not ideal for integrating into overviews, where the list should be ordered by relevance. --- tools/qdoc3/htmlgenerator.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index 425c50b..6b15f96 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -539,16 +539,13 @@ int HtmlGenerator::generateAtom(const Atom *atom, break; case Atom::AnnotatedList: { - const FakeNode *fake = static_cast(relative); - if (fake && !fake->groupMembers().isEmpty()) { - QList values = tre->groups().values(atom->string()); - QMap nodeMap; - for (int i = 0; i < values.size(); ++i) { - const Node* n = values.at(i); - nodeMap.insert(n->name(),n); - } - generateAnnotatedList(fake, marker, nodeMap); + QList values = tre->groups().values(atom->string()); + QMap nodeMap; + for (int i = 0; i < values.size(); ++i) { + const Node* n = values.at(i); + nodeMap.insert(n->name(),n); } + generateAnnotatedList(relative, marker, nodeMap); } break; case Atom::GeneratedList: -- cgit v0.12 From 118c82b0988c671045de448ffabc7ba95f015a69 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 5 Aug 2009 10:42:46 +0200 Subject: Fixes hangup when pressing key in QListWidget If there is severals matching items but all of them are disabled, it would have produced an infinite loop. Block the loop once we reach an already matched item. Task-number: 258949 Reviewed-by: Thierry --- src/gui/itemviews/qabstractitemview.cpp | 7 +++++++ tests/auto/qlistwidget/tst_qlistwidget.cpp | 23 ++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index 8594968..f7d5f1b 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -2666,6 +2666,7 @@ void QAbstractItemView::keyboardSearch(const QString &search) QModelIndex current = start; QModelIndexList match; QModelIndex firstMatch; + QModelIndex startMatch; QModelIndexList previous; do { match = d->model->match(current, Qt::DisplayRole, searchString); @@ -2682,6 +2683,12 @@ void QAbstractItemView::keyboardSearch(const QString &search) if (row >= d->model->rowCount(firstMatch.parent())) row = 0; current = firstMatch.sibling(row, firstMatch.column()); + + //avoid infinite loop if all the matching items are disabled. + if (!startMatch.isValid()) + startMatch = firstMatch; + else if (startMatch == firstMatch) + break; } } while (current != start && firstMatch.isValid()); } diff --git a/tests/auto/qlistwidget/tst_qlistwidget.cpp b/tests/auto/qlistwidget/tst_qlistwidget.cpp index a56a470..e38ef20 100644 --- a/tests/auto/qlistwidget/tst_qlistwidget.cpp +++ b/tests/auto/qlistwidget/tst_qlistwidget.cpp @@ -128,6 +128,8 @@ private slots: void setSortingEnabled(); void task199503_crashWhenCleared(); void task217070_scrollbarsAdjusted(); + void task258949_keypressHangup(); + protected slots: void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last) @@ -994,7 +996,7 @@ void tst_QListWidget::sortHiddenItems() for (int k = 0; k < tw->count(); ++k) QCOMPARE(persistent.at(k).row(), expectedRows.at(k)); - + delete tw; } @@ -1498,5 +1500,24 @@ void tst_QListWidget::task217070_scrollbarsAdjusted() } } +void tst_QListWidget::task258949_keypressHangup() +{ + QListWidget lw; + for (int y = 0; y < 5; y++) { + QListWidgetItem *lwi = new QListWidgetItem(&lw); + lwi->setText(y ? "1" : "0"); + if (y) + lwi->setFlags(Qt::ItemIsSelectable); + } + + lw.show(); + lw.setCurrentIndex(lw.model()->index(0,0)); + QCOMPARE(lw.currentIndex(), lw.model()->index(0,0)); + QTest::qWait(30); + QTest::keyPress(&lw, '1'); //this used to freeze + QTest::qWait(30); + QCOMPARE(lw.currentIndex(), lw.model()->index(0,0)); +} + QTEST_MAIN(tst_QListWidget) #include "tst_qlistwidget.moc" -- cgit v0.12 From e3e1ea6c52473f120f8baee57e189ddc1c8671cb Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 5 Aug 2009 11:11:37 +0200 Subject: QMenu: fix a crash depending on styles We were calling pixelMetric and sizeFromContents with a NULL styleoption That crashes on mac and might also with other styles. --- src/gui/widgets/qmenu.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 67bb10a..05426a0 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -225,13 +225,17 @@ void QMenuPrivate::updateActionRects() const dh = popupGeometry(QApplication::desktop()->screenNumber(q)).height(), y = 0; QStyle *style = q->style(); - const int hmargin = style->pixelMetric(QStyle::PM_MenuHMargin, 0, q), - vmargin = style->pixelMetric(QStyle::PM_MenuVMargin, 0, q), - icone = style->pixelMetric(QStyle::PM_SmallIconSize, 0, q); - const int fw = style->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q); - - const int sfcMargin = style->sizeFromContents(QStyle::CT_Menu, 0, QApplication::globalStrut(), q).width() - QApplication::globalStrut().width(); + QStyleOption opt; + opt.init(q); + const int hmargin = style->pixelMetric(QStyle::PM_MenuHMargin, &opt, q), + vmargin = style->pixelMetric(QStyle::PM_MenuVMargin, &opt, q), + icone = style->pixelMetric(QStyle::PM_SmallIconSize, &opt, q); + const int fw = style->pixelMetric(QStyle::PM_MenuPanelWidth, &opt, q); + const int deskFw = style->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, &opt, q); + + const int sfcMargin = style->sizeFromContents(QStyle::CT_Menu, &opt, QApplication::globalStrut(), q).width() - QApplication::globalStrut().width(); const int min_column_width = q->minimumWidth() - (sfcMargin + leftmargin + rightmargin + 2 * (fw + hmargin)); + const int tearoffHeight = tearoff ? style->pixelMetric(QStyle::PM_MenuTearoffHeight, &opt, q) : 0; //for compatability now - will have to refactor this away.. tabWidth = 0; @@ -307,7 +311,7 @@ void QMenuPrivate::updateActionRects() const max_column_width = qMax(min_column_width, qMax(max_column_width, sz.width())); //wrapping if (!scroll && - y+sz.height()+vmargin > dh - (style->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q) * 2)) { + y+sz.height()+vmargin > dh - (deskFw * 2)) { ncols++; y = vmargin; } @@ -322,7 +326,7 @@ void QMenuPrivate::updateActionRects() const //calculate position const int base_y = vmargin + fw + topmargin + (scroll ? scroll->scrollOffset : 0) + - (tearoff ? style->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, q) : 0); + tearoffHeight; int x = hmargin + fw + leftmargin; y = base_y; @@ -331,7 +335,7 @@ void QMenuPrivate::updateActionRects() const if (rect.isNull()) continue; if (!scroll && - y+rect.height() > dh - (style->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q) * 2)) { + y+rect.height() > dh - deskFw * 2) { x += max_column_width + hmargin; y = base_y; } -- cgit v0.12 From 5f52d473eec0f1b46200b06dd7f5e16cb5c57c05 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Wed, 5 Aug 2009 10:57:13 +0200 Subject: Fix compilation when QT_NO_HTTP is defined Note however you still need to -nomake examples -nomake demos when configuring Qt. Reviewed-by: Thiago Task: 259179 --- src/network/access/qhttpnetworkheader.cpp | 3 +++ src/network/access/qhttpnetworkreply_p.h | 1 + src/network/access/qhttpnetworkrequest.cpp | 4 ++++ src/qt3support/network/q3http.cpp | 2 +- src/qt3support/network/q3http.h | 5 ++--- src/qt3support/network/q3network.cpp | 2 +- tools/assistant/tools/assistant/installdialog.cpp | 2 ++ tools/assistant/tools/assistant/installdialog.h | 4 ++++ 8 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/network/access/qhttpnetworkheader.cpp b/src/network/access/qhttpnetworkheader.cpp index 5af9764..88cc484 100644 --- a/src/network/access/qhttpnetworkheader.cpp +++ b/src/network/access/qhttpnetworkheader.cpp @@ -41,6 +41,7 @@ #include "qhttpnetworkheader_p.h" +#ifndef QT_NO_HTTP QT_BEGIN_NAMESPACE @@ -121,3 +122,5 @@ bool QHttpNetworkHeaderPrivate::operator==(const QHttpNetworkHeaderPrivate &othe QT_END_NAMESPACE + +#endif diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index 76aa947..65ed4ce 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -52,6 +52,7 @@ // // We mean it. // +#include #ifndef QT_NO_HTTP #ifndef QT_NO_COMPRESS diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp index 02ba629..32d51f3 100644 --- a/src/network/access/qhttpnetworkrequest.cpp +++ b/src/network/access/qhttpnetworkrequest.cpp @@ -41,6 +41,8 @@ #include "qhttpnetworkrequest_p.h" +#ifndef QT_NO_HTTP + QT_BEGIN_NAMESPACE QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(QHttpNetworkRequest::Operation op, @@ -259,3 +261,5 @@ int QHttpNetworkRequest::minorVersion() const QT_END_NAMESPACE +#endif + diff --git a/src/qt3support/network/q3http.cpp b/src/qt3support/network/q3http.cpp index a38edad..e44dfe8 100644 --- a/src/qt3support/network/q3http.cpp +++ b/src/qt3support/network/q3http.cpp @@ -42,7 +42,7 @@ #include #include "q3http.h" -#ifndef QT_NO_NETWORKPROTOCOL_HTTP +#ifndef QT_NO_HTTP #include "q3socket.h" #include "qtextstream.h" diff --git a/src/qt3support/network/q3http.h b/src/qt3support/network/q3http.h index 93ab00e..5311764 100644 --- a/src/qt3support/network/q3http.h +++ b/src/qt3support/network/q3http.h @@ -52,8 +52,7 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE QT_MODULE(Qt3Support) - -#ifndef QT_NO_NETWORKPROTOCOL_HTTP +#ifndef QT_NO_HTTP class Q3Socket; class QTimerEvent; @@ -269,7 +268,7 @@ private: friend class Q3HttpPGHRequest; }; -#endif // QT_NO_NETWORKPROTOCOL_HTTP +#endif // QT_NO_HTTP QT_END_NAMESPACE diff --git a/src/qt3support/network/q3network.cpp b/src/qt3support/network/q3network.cpp index 3a6a6f0..1f918d1 100644 --- a/src/qt3support/network/q3network.cpp +++ b/src/qt3support/network/q3network.cpp @@ -63,7 +63,7 @@ void q3InitNetworkProtocols() #ifndef QT_NO_NETWORKPROTOCOL_FTP Q3NetworkProtocol::registerNetworkProtocol( QLatin1String("ftp"), new Q3NetworkProtocolFactory< Q3Ftp > ); #endif -#ifndef QT_NO_NETWORKPROTOCOL_HTTP +#ifndef QT_NO_HTTP Q3NetworkProtocol::registerNetworkProtocol( QLatin1String("http"), new Q3NetworkProtocolFactory< Q3Http > ); #endif } diff --git a/tools/assistant/tools/assistant/installdialog.cpp b/tools/assistant/tools/assistant/installdialog.cpp index 5a8dfea..2574f1f 100644 --- a/tools/assistant/tools/assistant/installdialog.cpp +++ b/tools/assistant/tools/assistant/installdialog.cpp @@ -56,6 +56,7 @@ #include QT_BEGIN_NAMESPACE +#ifndef QT_NO_HTTP #define QCH_FILENAME 92943 #define QCH_NAMESPACE 92944 @@ -335,4 +336,5 @@ void InstallDialog::browseDirectories() m_ui.pathLineEdit->setText(dir); } +#endif QT_END_NAMESPACE diff --git a/tools/assistant/tools/assistant/installdialog.h b/tools/assistant/tools/assistant/installdialog.h index 62759ec..9e18a22b9 100644 --- a/tools/assistant/tools/assistant/installdialog.h +++ b/tools/assistant/tools/assistant/installdialog.h @@ -47,6 +47,8 @@ #include #include "ui_installdialog.h" +#ifndef QT_NO_HTTP + QT_BEGIN_NAMESPACE class QHttp; @@ -98,4 +100,6 @@ private: QT_END_NAMESPACE +#endif + #endif // INSTALLDIALOG_H -- cgit v0.12 From c379e151adc9c781f8f1e3d33cf68b3137868185 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 5 Aug 2009 11:11:52 +0200 Subject: cetest: add support for cetcpsync (our simple ActiveSync replacement) Reviewed-By: mauricek --- .../qtestlib/wince/cetest/cetcpsyncconnection.cpp | 198 +++++++++++++++++++++ tools/qtestlib/wince/cetest/cetcpsyncconnection.h | 82 +++++++++ tools/qtestlib/wince/cetest/cetest.pro | 19 +- tools/qtestlib/wince/cetest/deployment.cpp | 2 + tools/qtestlib/wince/cetest/main.cpp | 11 +- 5 files changed, 305 insertions(+), 7 deletions(-) create mode 100644 tools/qtestlib/wince/cetest/cetcpsyncconnection.cpp create mode 100644 tools/qtestlib/wince/cetest/cetcpsyncconnection.h diff --git a/tools/qtestlib/wince/cetest/cetcpsyncconnection.cpp b/tools/qtestlib/wince/cetest/cetcpsyncconnection.cpp new file mode 100644 index 0000000..bebcd1c --- /dev/null +++ b/tools/qtestlib/wince/cetest/cetcpsyncconnection.cpp @@ -0,0 +1,198 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "CeTcpSyncConnection.h" +#include +#include +#include + +extern void debugOutput(const QString& text, int level); + +CeTcpSyncConnection::CeTcpSyncConnection() + : AbstractRemoteConnection() + , connected(false) +{ +} + +CeTcpSyncConnection::~CeTcpSyncConnection() +{ + if (isConnected()) + disconnect(); +} + +bool CeTcpSyncConnection::connect(QVariantList&) +{ + // We connect with each command, so this is always true + // The command itself will fail then + if (system("cetcpsync noop") != 0) + return false; + connected = true; + return true; +} + +void CeTcpSyncConnection::disconnect() +{ + connected = false; +} + +bool CeTcpSyncConnection::isConnected() const +{ + return connected; +} + +inline QString boolToString(bool b) +{ + return b ? "true" : "false"; +} + +static bool fileTimeFromString(FILETIME& ft, const QString& str) +{ + int idx = str.indexOf("*"); + if (idx <= 0) + return false; + bool ok; + ft.dwLowDateTime = str.left(idx).toULong(&ok); + if (!ok) + return false; + ft.dwHighDateTime = str.mid(idx+1).toULong(&ok); + return ok; +} + +static QString fileTimeToString(FILETIME& ft) +{ + return QString::number(ft.dwLowDateTime) + "*" + QString::number(ft.dwHighDateTime); +} + +bool CeTcpSyncConnection::copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists) +{ + QString cmd = "cetcpsync copyFileToDevice \"" + localSource + "\" \"" + deviceDest + "\" " + boolToString(failIfExists); + return system(qPrintable(cmd)) == 0; +} + +bool CeTcpSyncConnection::copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive) +{ + QString cmd = "cetcpsync copyDirectoryToDevice \"" + localSource + "\" \"" + deviceDest + "\" " + boolToString(recursive); + return system(qPrintable(cmd)) == 0; +} + +bool CeTcpSyncConnection::copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists) +{ + QString cmd = "cetcpsync copyFileFromDevice \"" + deviceSource + "\" \"" + localDest + "\" " + boolToString(failIfExists); + return system(qPrintable(cmd)) == 0; +} + +bool CeTcpSyncConnection::copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive) +{ + QString cmd = "cetcpsync copyDirectoryFromDevice \"" + deviceSource + "\" \"" + localDest + "\" " + boolToString(recursive); + return system(qPrintable(cmd)) == 0; +} + +bool CeTcpSyncConnection::copyFile(const QString &srcFile, const QString &destFile, bool failIfExists) +{ + QString cmd = "cetcpsync copyFile \"" + srcFile + "\" \"" + destFile + "\" " + boolToString(failIfExists); + return system(qPrintable(cmd)) == 0; +} + +bool CeTcpSyncConnection::copyDirectory(const QString &srcDirectory, const QString &destDirectory, + bool recursive) +{ + QString cmd = "cetcpsync copyDirectory \"" + srcDirectory + "\" \"" + destDirectory + "\" " + boolToString(recursive); + return system(qPrintable(cmd)) == 0; +} + +bool CeTcpSyncConnection::deleteFile(const QString &fileName) +{ + QString cmd = "cetcpsync deleteFile \"" + fileName + "\""; + return system(qPrintable(cmd)) == 0; +} + +bool CeTcpSyncConnection::deleteDirectory(const QString &directory, bool recursive, bool failIfContentExists) +{ + QString cmd = "cetcpsync deleteDirectory \"" + directory + "\" " + boolToString(recursive) + " " + boolToString(failIfContentExists); + return system(qPrintable(cmd)) == 0; +} + +bool CeTcpSyncConnection::execute(QString program, QString arguments, int timeout, int *returnValue) +{ + QString cmd = "cetcpsync execute \"" + program + "\" \"" + arguments + "\" " + QString::number(timeout); + int exitCode = system(qPrintable(cmd)); + if (returnValue) + *returnValue = exitCode; + return true; +} + +bool CeTcpSyncConnection::createDirectory(const QString &path, bool deleteBefore) +{ + QString cmd = "cetcpsync createDirectory \"" + path + "\" " + boolToString(deleteBefore); + return system(qPrintable(cmd)) == 0; +} + +bool CeTcpSyncConnection::timeStampForLocalFileTime(FILETIME* fTime) const +{ + QString cmd = "cetcpsync timeStampForLocalFileTime " + fileTimeToString(*fTime) + " >filetime.txt"; + if (system(qPrintable(cmd)) != 0) + return false; + + QFile file("filetime.txt"); + if (!file.open(QIODevice::ReadOnly)) + return false; + + bool result = fileTimeFromString(*fTime, file.readLine()); + file.close(); + file.remove(); + return result; +} + +bool CeTcpSyncConnection::fileCreationTime(const QString &fileName, FILETIME* deviceCreationTime) const +{ + QString cmd = "cetcpsync fileCreationTime \"" + fileName + "\" >filetime.txt"; + if (system(qPrintable(cmd)) != 0) + return false; + + QFile file("filetime.txt"); + if (!file.open(QIODevice::ReadOnly)) + return false; + + bool result = fileTimeFromString(*deviceCreationTime, file.readLine()); + file.close(); + file.remove(); + return result; +} diff --git a/tools/qtestlib/wince/cetest/cetcpsyncconnection.h b/tools/qtestlib/wince/cetest/cetcpsyncconnection.h new file mode 100644 index 0000000..1ef8423 --- /dev/null +++ b/tools/qtestlib/wince/cetest/cetcpsyncconnection.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CETCPSYNC_REMOTECONNECTION_H +#define CETCPSYNC_REMOTECONNECTION_H + +#include "remoteconnection.h" + +class CeTcpSyncConnection : public AbstractRemoteConnection +{ +public: + CeTcpSyncConnection(); + virtual ~CeTcpSyncConnection(); + + bool connect(QVariantList &list = QVariantList()); + void disconnect(); + bool isConnected() const; + + // These functions are designed for transfer between desktop and device + // Caution: deviceDest path has to be device specific (eg. no drive letters for CE) + bool copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists = false); + bool copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive = true); + bool copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists = false); + bool copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive = true); + + bool timeStampForLocalFileTime(FILETIME*) const; + bool fileCreationTime(const QString &fileName, FILETIME*) const; + + // These functions only work on files existing on the device + bool copyFile(const QString&, const QString&, bool failIfExists = false); + bool copyDirectory(const QString&, const QString&, bool recursive = true); + bool deleteFile(const QString&); + bool deleteDirectory(const QString&, bool recursive = true, bool failIfContentExists = false); + bool moveFile(const QString&, const QString&, bool FailIfExists = false); + bool moveDirectory(const QString&, const QString&, bool recursive = true); + + bool createDirectory(const QString&, bool deleteBefore=false); + + bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL); +private: + bool connected; +}; + +#endif diff --git a/tools/qtestlib/wince/cetest/cetest.pro b/tools/qtestlib/wince/cetest/cetest.pro index d66fa33..c6eba7f 100644 --- a/tools/qtestlib/wince/cetest/cetest.pro +++ b/tools/qtestlib/wince/cetest/cetest.pro @@ -28,20 +28,27 @@ DEPENDPATH += $$QT_BUILD_TREE/src/corelib/tools $$QT_BUILD_TREE/src/corelib/io # Input HEADERS += \ remoteconnection.h \ - activesyncconnection.h \ deployment.h SOURCES += \ remoteconnection.cpp \ - activesyncconnection.cpp \ deployment.cpp \ main.cpp -win32-msvc*:LIBS += ole32.lib advapi32.lib rapi.lib +win32-msvc*:LIBS += ole32.lib advapi32.lib + +isEmpty(QT_CE_RAPI_INC) { + DEFINES += QT_CETEST_NO_ACTIVESYNC + HEADERS += cetcpsyncconnection.h + SOURCES += cetcpsyncconnection.cpp +} else { + HEADERS += activesyncconnection.h + SOURCES += activesyncconnection.cpp + win32-msvc*:LIBS += rapi.lib + INCLUDEPATH += $$QT_CE_RAPI_INC + LIBS += -L$$QT_CE_RAPI_LIB +} include(qmake_include.pri) include(bootstrapped.pri) include($$QT_SOURCE_TREE/src/script/script.pri) - -INCLUDEPATH += $$QT_CE_RAPI_INC -LIBS += -L$$QT_CE_RAPI_LIB diff --git a/tools/qtestlib/wince/cetest/deployment.cpp b/tools/qtestlib/wince/cetest/deployment.cpp index 68f0197..c64ae26 100644 --- a/tools/qtestlib/wince/cetest/deployment.cpp +++ b/tools/qtestlib/wince/cetest/deployment.cpp @@ -168,6 +168,7 @@ void DeploymentHandler::initQtDeploy(QMakeProject *project, DeploymentList &depl } } +#ifndef QT_CETEST_NO_ACTIVESYNC // QtRemote deployment. We always deploy to \Windows if (!project->values("QMAKE_LIBDIR").isEmpty()) { QString remoteLibName = QLatin1String("QtRemote.dll"); @@ -177,6 +178,7 @@ void DeploymentHandler::initQtDeploy(QMakeProject *project, DeploymentList &depl else debugOutput(QString::fromLatin1("Could not find QtRemote. Might not be able to launch target executable"),0); } +#endif // C-runtime deployment QString runtime = project->values("QT_CE_C_RUNTIME").join(QLatin1String(" ")); diff --git a/tools/qtestlib/wince/cetest/main.cpp b/tools/qtestlib/wince/cetest/main.cpp index 782f6d9..e0e475c 100644 --- a/tools/qtestlib/wince/cetest/main.cpp +++ b/tools/qtestlib/wince/cetest/main.cpp @@ -39,7 +39,12 @@ ** ****************************************************************************/ -#include "activesyncconnection.h" +#ifdef QT_CETEST_NO_ACTIVESYNC +# include "cetcpsyncconnection.h" +#else +# include "activesyncconnection.h" +#endif + #include "deployment.h" #include #include @@ -290,7 +295,11 @@ int main(int argc, char **argv) projectDeploymentList.append(CopyItem(TestConfiguration::localExecutable , TestConfiguration::remoteExecutable)); // deploy +#ifdef QT_CETEST_NO_ACTIVESYNC + CeTcpSyncConnection connection; +#else ActiveSyncConnection connection; +#endif if (!connection.connect()) { cout << "Error: Could not connect to device!" << endl; return -1; -- cgit v0.12 From ad8247fcbe7d7e3e3c0227d54f6abc2ef6160f9b Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 5 Aug 2009 11:33:22 +0200 Subject: initial revision of cetcpsyncserver cetcpsync is our simple ActiveSync replacement for Windows CE devices. This is the server which has to run on the device. Reviewed-By: mauricek --- .../wince/cetcpsyncserver/cetcpsyncserver.pro | 17 + tools/qtestlib/wince/cetcpsyncserver/commands.cpp | 646 +++++++++++++++++++++ tools/qtestlib/wince/cetcpsyncserver/commands.h | 292 ++++++++++ .../wince/cetcpsyncserver/connectionmanager.cpp | 138 +++++ .../wince/cetcpsyncserver/connectionmanager.h | 83 +++ tools/qtestlib/wince/cetcpsyncserver/main.cpp | 63 ++ .../wince/cetcpsyncserver/transfer_global.h | 159 +++++ 7 files changed, 1398 insertions(+) create mode 100644 tools/qtestlib/wince/cetcpsyncserver/cetcpsyncserver.pro create mode 100644 tools/qtestlib/wince/cetcpsyncserver/commands.cpp create mode 100644 tools/qtestlib/wince/cetcpsyncserver/commands.h create mode 100644 tools/qtestlib/wince/cetcpsyncserver/connectionmanager.cpp create mode 100644 tools/qtestlib/wince/cetcpsyncserver/connectionmanager.h create mode 100644 tools/qtestlib/wince/cetcpsyncserver/main.cpp create mode 100644 tools/qtestlib/wince/cetcpsyncserver/transfer_global.h diff --git a/tools/qtestlib/wince/cetcpsyncserver/cetcpsyncserver.pro b/tools/qtestlib/wince/cetcpsyncserver/cetcpsyncserver.pro new file mode 100644 index 0000000..bd01d2d --- /dev/null +++ b/tools/qtestlib/wince/cetcpsyncserver/cetcpsyncserver.pro @@ -0,0 +1,17 @@ +TEMPLATE = app +TARGET = cetcpsyncsvr +DEPENDPATH += . +QT -= gui +QT += network + +CONFIG += console + +HEADERS += \ + connectionmanager.h \ + commands.h \ + transfer_global.h + +SOURCES += \ + connectionmanager.cpp \ + commands.cpp \ + main.cpp diff --git a/tools/qtestlib/wince/cetcpsyncserver/commands.cpp b/tools/qtestlib/wince/cetcpsyncserver/commands.cpp new file mode 100644 index 0000000..64869c4 --- /dev/null +++ b/tools/qtestlib/wince/cetcpsyncserver/commands.cpp @@ -0,0 +1,646 @@ +#include "commands.h" +#include +#include +#include +#include + +#ifdef Q_OS_WINCE +#include +#endif + +///////////////////////////////////////////////////// +// Abstract Command Implementation // +///////////////////////////////////////////////////// +AbstractCommand::AbstractCommand() +: m_socket(0) +{ +} + +AbstractCommand::~AbstractCommand() +{ +} + +void AbstractCommand::reportSuccess() +{ + m_socket->write(COMMAND_SUCCESS, strlen(COMMAND_SUCCESS)); + m_socket->waitForBytesWritten(); +} + +void AbstractCommand::reportError() +{ + m_socket->write(COMMAND_ERROR, strlen(COMMAND_ERROR)); + m_socket->waitForBytesWritten(); +} + +void AbstractCommand::dataReceived(QByteArray&) +{ + debugOutput(1, "AbstractCommand::dataReceived NOT SUPPOSED TO BE HERE"); +} + +void AbstractCommand::commandFinished() +{ + debugOutput(1, "AbstractCommand::commandFinished()NOT SUPPOSED TO BE HERE"); +} + +void AbstractCommand::setSocket(QTcpSocket* socket) +{ + debugOutput(0, "AbstractCommand::setSocket()"); + Q_ASSERT(socket); + m_socket = socket; + connect(m_socket, SIGNAL(readyRead()), this, SLOT(_readData())); + reportSuccess(); +} + +QTcpSocket* AbstractCommand::socket() +{ + return m_socket; +} + +void AbstractCommand::_readData() +{ + QByteArray arr = m_socket->readAll(); + dataReceived(arr); +} + +void AbstractCommand::_disconnect() +{ +} + +///////////////////////////////////////////////////// +// Create File Command Implementation // +///////////////////////////////////////////////////// +CreateFileCommand::CreateFileCommand() +: m_dataCount(0) +{ + debugOutput(0, "CreateFileCommand::CreateFileCommand"); + m_options.fileSize= -1; +} + +CreateFileCommand::~CreateFileCommand() +{ + debugOutput(0, "CreateFileCommand::~CreateFileCommand"); + if (m_file.isOpen()) { + fprintf(stderr, "****************FILE IS STILL OPENED AND HAVENT FINISHED WRITING**********************\n"); + fprintf(stderr, "Current: %d Expected: %d\n", m_dataCount , m_options.fileSize); + m_file.close(); + } +} + +void CreateFileCommand::dataReceived(QByteArray &data) +{ + bool successful = true; + // If we haven't received the options yet + if (m_options.fileSize == -1) { + CreateFileOptions* opt = (CreateFileOptions*) data.data(); + memcpy(&m_options , opt , sizeof(CreateFileOptions)); + + if (QFileInfo(QString::fromLatin1(m_options.fileName)).exists()) { + if (m_options.overwriteExisting) { +#ifdef Q_OS_WINCE + SetFileAttributes(QFileInfo(m_options.fileName).absoluteFilePath().utf16(), FILE_ATTRIBUTE_NORMAL); +#endif + QFile::remove(m_options.fileName); + } else + successful = false; + } + m_file.setFileName(QString::fromLatin1(m_options.fileName)); + if (!m_file.open(QIODevice::WriteOnly)) + successful = false; + else + debugOutput(3, QString::fromLatin1("Creating file: %1").arg(m_options.fileName)); + } else { // write buffer on disc + if (!m_file.isOpen()) + return; + m_file.write(data); + m_dataCount += data.size(); + if (m_dataCount >= m_options.fileSize) { + // We do not care about more data than announced + m_file.close(); + } + } + + if (successful) + reportSuccess(); + else + reportError(); +} + +void CreateFileCommand::commandFinished() +{ + debugOutput(0, "CreateFileCommand::commandFinished"); +#ifdef Q_OS_WIN + // We need to set the file attributes for intelligent time comparisons + QString tmpFile = QString::fromLatin1(m_options.fileName); + HANDLE handle = CreateFile(tmpFile.utf16(), GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + if (handle != INVALID_HANDLE_VALUE) { + SetFileTime(handle, &(m_options.fileTime), NULL, NULL); + CloseHandle(handle); + } + SetFileAttributes(tmpFile.utf16(), m_options.fileAttributes); +#endif +} + +///////////////////////////////////////////////////// +// Create Directory Command Implementation // +///////////////////////////////////////////////////// +CreateDirectoryCommand::CreateDirectoryCommand() + : AbstractCommand() +{ + debugOutput(0, "CreateDirectoryCommand::CreateDirectoryCommand"); +} + +CreateDirectoryCommand::~CreateDirectoryCommand() +{ + debugOutput(0, "CreateDirectoryCommand::~CreateDirectoryCommand()"); +} + +void CreateDirectoryCommand::dataReceived(QByteArray &data) +{ + debugOutput(0, "CreateDirectoryCommand::dataReceived()"); + CreateDirectoryOptions* options = (CreateDirectoryOptions*) data.data(); + debugOutput(3, QString::fromLatin1("Creating directory: %1").arg(options->dirName)); + bool success = true; + QDir dir; + if (options->recursively) + success = dir.mkpath(options->dirName); + else + success = dir.mkdir(options->dirName); + + if (success) + reportSuccess(); + else + reportError(); +} + +void CreateDirectoryCommand::commandFinished() +{ + debugOutput(0, "CreateDirectoryCommand::commandFinished()"); +} + +///////////////////////////////////////////////////// +// Copy File Command Implementation // +///////////////////////////////////////////////////// +CopyFileCommand::CopyFileCommand() + : AbstractCommand() +{ + debugOutput(0, "CopyFileCommand::CopyFileCommand()"); +} + +CopyFileCommand::~CopyFileCommand() +{ + debugOutput(0, "CopyFileCommand::~CopyFileCommand()"); +} + +void CopyFileCommand::dataReceived(QByteArray &data) +{ + debugOutput(0, "CopyFileCommand::dataReceived()"); + CopyFileOptions* options = (CopyFileOptions*) data.data(); + debugOutput(3, QString::fromLatin1("Copy File: %1 -> %2").arg(options->from).arg(options->to)); + bool success = true; + if (QFileInfo(options->to).exists()) { + if (options->overwriteExisting) + QFile::remove(options->to); + else + success = false; + } + if (success) + if (!QFile::copy(options->from , options->to)) + success = false; + + if (success) + reportSuccess(); + else + reportError(); +} + +void CopyFileCommand::commandFinished() +{ + debugOutput(0, "CopyFileCommand::commandFinished()"); +} + +///////////////////////////////////////////////////// +// Copy Directory Command Implementation // +///////////////////////////////////////////////////// +CopyDirectoryCommand::CopyDirectoryCommand() + : AbstractCommand() +{ + debugOutput(0, "CopyDirectoryCommand::CopyDirectoryCommand()"); +} + +CopyDirectoryCommand::~CopyDirectoryCommand() +{ + debugOutput(0, "CopyDirectoryCommand::~CopyDirectoryCommand()"); +} + +void CopyDirectoryCommand::dataReceived(QByteArray &data) +{ + debugOutput(0, "CopyDirectoryCommand::dataReceived()"); + CopyDirectoryOptions* options = (CopyDirectoryOptions*) data.data(); + debugOutput(3, QString::fromLatin1("Copy Directory: %1 %2").arg(options->from).arg(options->to)); + if (copyDir(QLatin1String(options->from) , QLatin1String(options->to) , options->recursive)) + reportSuccess(); + else + reportError(); +} + +void CopyDirectoryCommand::commandFinished() +{ + debugOutput(0, "CopyDirectoryCommand::commandFinished()"); +} + +bool CopyDirectoryCommand::copyDir(const QString &from, const QString &to, bool recursive) +{ + QDir().mkpath(to); + QDir sourceDir(from); + QDir destDir(to); + QStringList entries = sourceDir.entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot); + foreach (QString item , entries) { + QString itemFrom = sourceDir.absoluteFilePath(item); + QString itemTo = destDir.absoluteFilePath(item); + if (QFileInfo(item).isDir()) { + if (recursive && !copyDir(itemFrom, itemTo, recursive)) + return false; + } else { + if (!QFile::copy(itemFrom, itemTo)) + return false; + } + } + return true; +} + +///////////////////////////////////////////////////// +// Delete File Command Implementation // +///////////////////////////////////////////////////// +DeleteFileCommand::DeleteFileCommand() + : AbstractCommand() +{ + debugOutput(0, "DeleteFileCommand::DeleteFileCommand()"); +} + +DeleteFileCommand::~DeleteFileCommand() +{ + debugOutput(0, "DeleteFileCommand::~DeleteFileCommand()"); +} + +void DeleteFileCommand::dataReceived(QByteArray &data) +{ + debugOutput(0, "DeleteFileCommand::dataReceived()"); + DeleteFileOptions* options = (DeleteFileOptions*) data.data(); + debugOutput(3, QString::fromLatin1("Delete File: %1").arg(options->fileName)); + bool success = true; + QFile file(options->fileName); + if (file.exists()) { +#ifdef Q_OS_WINCE + SetFileAttributes(QFileInfo(options->fileName).absoluteFilePath().utf16(), FILE_ATTRIBUTE_NORMAL); +#endif + success = file.remove(); + } else + success = false; + + if (success) + reportSuccess(); + else + reportError(); +} + +void DeleteFileCommand::commandFinished() +{ + debugOutput(0, "DeleteFileCommand::commandFinished()"); +} + +///////////////////////////////////////////////////// +// Delete Directory Command Implementation // +///////////////////////////////////////////////////// +DeleteDirectoryCommand::DeleteDirectoryCommand() + : AbstractCommand() +{ + debugOutput(0, "DeleteDirectoryCommand::DeleteDirectoryCommand()"); +} + +DeleteDirectoryCommand::~DeleteDirectoryCommand() +{ + debugOutput(0, "DeleteDirectoryCommand::~DeleteDirectoryCommand()"); +} + +void DeleteDirectoryCommand::dataReceived(QByteArray &data) +{ + debugOutput(0, "DeleteDirectoryCommand::dataReceived()"); + DeleteDirectoryOptions* options = (DeleteDirectoryOptions*) data.data(); + debugOutput(3, QString::fromLatin1("Delete directory: %1").arg(options->dirName)); + if (deleteDirectory(QLatin1String(options->dirName), options->recursive, options->failIfContentExists)) + reportSuccess(); + else + reportError(); +} + +void DeleteDirectoryCommand::commandFinished() +{ + debugOutput(0, "DeleteDirectoryCommand::commandFinished()"); +} + +bool DeleteDirectoryCommand::deleteDirectory(const QString &dirName, bool recursive, bool failIfContentExists) +{ + QDir dir(dirName); + if (!dir.exists()) + return false; + + QStringList itemList = dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); + if (itemList.size() > 0 && failIfContentExists) + return false; + + foreach (QString item, itemList) { + QString itemName = dir.absoluteFilePath(item); + if (QFileInfo(itemName).isDir()) { + if (recursive && !deleteDirectory(itemName, recursive, failIfContentExists)) + return false; + } else { + if (!dir.remove(item)) + return false; + } + } + QString lastName = dir.dirName(); + dir.cdUp(); + dir.rmpath(lastName); + return true; +} + +///////////////////////////////////////////////////// +// Execute Command Implementation // +///////////////////////////////////////////////////// +ExecuteCommand::ExecuteCommand() + : AbstractCommand() + , m_argumentCount(0) + , m_timeout(-1) +{ + debugOutput(0, "ExecuteCommand::ExecuteCommand()"); +} + +ExecuteCommand::~ExecuteCommand() +{ + debugOutput(0, "ExecuteCommand::~ExecuteCommand()"); +} + +void ExecuteCommand::dataReceived(QByteArray &data) +{ + debugOutput(0, "ExecuteCommand::dataReceived()"); + + if (m_argumentCount == 0) { + ExecuteOptions* options = (ExecuteOptions*) data.data(); + if (!QFileInfo(options->appName).exists()) { + debugOutput(1, "Error execute: application does not exist"); + reportError(); + return; + } + + m_program = QLatin1String(options->appName); + m_argumentCount = options->argumentsCount; + m_waitFinished = options->waitForFinished; + m_timeout = options->timeout; + if (m_argumentCount == 0) + m_argumentCount = -1; // to trigger startup on next receive + reportSuccess(); + } else if (m_arguments.size() < m_argumentCount) { + m_arguments += data; + reportSuccess(); + } else { // do the execution + if (data == COMMAND_SUCCESS) + _doExecute(); + } +} + +void ExecuteCommand::_doExecute() +{ + debugOutput(0, "ExecuteCommand::_doExecute()"); + debugOutput(3, QString::fromLatin1("Execute: %1 %2").arg(m_program).arg(m_arguments.join(" "))); + if (m_waitFinished) { + QProcess process; + process.start(m_program, m_arguments); + if (process.waitForFinished(m_timeout) == false || process.exitCode() < 0) + reportError(); + else + reportSuccess(); + } else { + if (QProcess::startDetached(m_program, m_arguments)) + reportSuccess(); + else + reportError(); + } +} +void ExecuteCommand::commandFinished() +{ + debugOutput(0,"ExecuteCommand::commandFinished()"); +} + +///////////////////////////////////////////////////// +// Read File Implementation // +///////////////////////////////////////////////////// +ReadFileCommand::ReadFileCommand() + : AbstractCommand() + , m_currentPos(0) +{ + debugOutput(0, "ReadFileCommand::ReadFileCommand()"); + m_fileName.clear(); +} + +ReadFileCommand::~ReadFileCommand() +{ + debugOutput(0, "ReadFileCommand::~ReadFileCommand()"); + if (m_file.isOpen()) + m_file.close(); +} + +void ReadFileCommand::dataReceived(QByteArray &data) +{ + debugOutput(0, "ReadFileCommand::dataReceived()"); + if (m_fileName.isEmpty()) { + ReadFileOptions* option = (ReadFileOptions*) data.data(); + m_fileName = QLatin1String(option->fileName); + QFileInfo info(m_fileName); + m_file.setFileName(m_fileName); + ReadFileReply reply; + if (!info.exists() || !info.isFile() || !m_file.open(QIODevice::ReadOnly)) + reply.fileValid = false; + else + reply.fileValid = true; + reply.fileSize = info.size(); + m_fileSize = reply.fileSize; + socket()->write((char*) &reply, sizeof(reply)); + debugOutput(3, QString::fromLatin1("Reading file: %1").arg(m_fileName)); + } else { + QTcpSocket* sock = socket(); // design failure??? + if (data != COMMAND_SUCCESS || m_currentPos >= m_fileSize) { + sock->disconnectFromHost(); + return; + } + const int bufferSize = 1024; + QByteArray buffer = m_file.read(bufferSize); + m_currentPos += buffer.size(); + sock->write(buffer); + sock->waitForBytesWritten(); + } +} + +void ReadFileCommand::commandFinished() +{ + debugOutput(0, "ReadFileCommand::commandFinished()"); +} + +///////////////////////////////////////////////////// +// Read Directory Implementation // +///////////////////////////////////////////////////// +ReadDirectoryCommand::ReadDirectoryCommand() + : AbstractCommand() + , m_iterator(0) +{ + debugOutput(0, "ReadDirectoryCommand::ReadDirectoryCommand"); + m_dirName.clear(); +} + +ReadDirectoryCommand::~ReadDirectoryCommand() +{ + debugOutput(0, "ReadDirectoryCommand::~ReadDirectoryCommand()"); + delete m_iterator; +} + +void ReadDirectoryCommand::dataReceived(QByteArray &data) +{ + debugOutput(0, "ReadDirectoryCommand::dataReceived()"); + QTcpSocket* sock = socket(); + if (m_dirName.isEmpty()) { + ReadDirectoryOptions* option = (ReadDirectoryOptions*) data.data(); + QFileInfo info(QLatin1String(option->dirName)); + debugOutput(3, QString::fromLatin1("Reading Directory entries: %1").arg(option->dirName)); + ReadDirectoryReply reply; + if (!info.exists() || !info.isDir()) { + reply.itemCount = -1; + reply.entryValid = false; + } else { + m_dirName = QLatin1String(option->dirName); + m_dir.setPath(m_dirName); + m_iterator = new QDirIterator(m_dir); + reply.itemCount = m_dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot).size(); + reply.entryValid = true; + } + sock->write((char*) &reply, sizeof(reply)); + sock->waitForBytesWritten(); + } else { + if (data != COMMAND_SUCCESS) { + qDebug() << "Something went wrong in the meantime"; + return; + } + ReadDirectoryItem reply; + if (m_iterator->hasNext()) { + m_iterator->next(); + QFileInfo info = m_iterator->fileInfo(); + strcpy(reply.name, qPrintable(info.absoluteFilePath())); + reply.isDirectory = info.isDir(); + if (!reply.isDirectory) + reply.size = info.size(); + } + reply.hasMore = m_iterator->hasNext(); + sock->write((char*) &reply, sizeof(reply)); + sock->waitForBytesWritten(); + } +} + +void ReadDirectoryCommand::commandFinished() +{ + debugOutput(0, "ReadDirectoryCommand::commandFinished()"); +} + +///////////////////////////////////////////////////// +// File Time Implementation // +///////////////////////////////////////////////////// +FileTimeCommand::FileTimeCommand() + : AbstractCommand() +{ + debugOutput(0, "FileTimeCommand::FileTimeCommand()"); +} + +FileTimeCommand::~FileTimeCommand() +{ + debugOutput(0, "FileTimeCommand::~FileTimeCommand()"); +} + +void FileTimeCommand::dataReceived(QByteArray &data) +{ + debugOutput(0, "FileTimeCommand::dataReceived()"); + FileTimeOptions* option = (FileTimeOptions*) data.data(); + + FILETIME resultTime; + resultTime.dwLowDateTime = -1; + resultTime.dwHighDateTime = -1; + +#ifdef Q_OS_WIN + QString fileName = QLatin1String(option->fileName); + HANDLE deviceHandle = CreateFile(fileName.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); + debugOutput(3, QString::fromLatin1("Asking FileTime: %1").arg(fileName)); + if (deviceHandle != INVALID_HANDLE_VALUE) { + FILETIME deviceCreationTime; + if (GetFileTime(deviceHandle, &deviceCreationTime, NULL, NULL)) { + resultTime = deviceCreationTime; + } + CloseHandle(deviceHandle); + } +#endif + QTcpSocket* sock = socket(); + sock->write((char*) &resultTime, sizeof(resultTime)); + sock->waitForBytesWritten(); +} + +void FileTimeCommand::commandFinished() +{ + debugOutput(0, "FileTimeCommand::commandFinished()"); +} + +///////////////////////////////////////////////////// +// Time Stamp Implementation // +///////////////////////////////////////////////////// +TimeStampCommand::TimeStampCommand() + : AbstractCommand() +{ + debugOutput(0, "TimeStampCommand::TimeStampCommand()"); +} + +TimeStampCommand::~TimeStampCommand() +{ + debugOutput(0, "TimeStampCommand::~TimeStampCommand()"); +} + +void TimeStampCommand::dataReceived(QByteArray &data) +{ + debugOutput(0, "TimeStampCommand::dataReceived()"); + FILETIME resultTime; + resultTime.dwLowDateTime = -1; + resultTime.dwHighDateTime = -1; + +#ifdef Q_OS_WIN + FILETIME stampTime = *((FILETIME*)data.data()); + + QString tmpFile = QString::fromLatin1("\\qt_tmp_ftime_convert"); + HANDLE remoteHandle = CreateFile(tmpFile.utf16(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + if (remoteHandle != INVALID_HANDLE_VALUE) { + if (!SetFileTime(remoteHandle, &stampTime, NULL, NULL)) { + CloseHandle(remoteHandle); + } else { + CloseHandle(remoteHandle); + remoteHandle = CreateFile(tmpFile.utf16(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); + if (remoteHandle != INVALID_HANDLE_VALUE) { + if (GetFileTime(remoteHandle, &stampTime, NULL, NULL)) + resultTime = stampTime; + CloseHandle(remoteHandle); + DeleteFile(tmpFile.utf16()); + } + } + } + debugOutput(3, QString::fromLatin1("Asking TimeStamp")); +#endif + QTcpSocket* sock = socket(); + sock->write((char*) &resultTime, sizeof(resultTime)); + sock->waitForBytesWritten(); +} + +void TimeStampCommand::commandFinished() +{ + debugOutput(0, "TimeStampCommand::commandFinished()"); +} diff --git a/tools/qtestlib/wince/cetcpsyncserver/commands.h b/tools/qtestlib/wince/cetcpsyncserver/commands.h new file mode 100644 index 0000000..356c1aa --- /dev/null +++ b/tools/qtestlib/wince/cetcpsyncserver/commands.h @@ -0,0 +1,292 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef COMMANDS_INCL +#define COMMANDS_INCL + +#include "transfer_global.h" + +#include +#include +#include +#include +#include +#include + +// debug output +#define DEBUG_LEVEL 2 +inline void debugOutput(int level, const char* text) +{ + if (level >= DEBUG_LEVEL) + qDebug() << text; +} + +inline void debugOutput(int level, const QString &text) +{ + if (level >= DEBUG_LEVEL) + qDebug() << text; +} +// Basic abtract command class +class AbstractCommand : public QObject +{ + Q_OBJECT +public: + AbstractCommand(); + virtual ~AbstractCommand(); + + void setSocket(QTcpSocket*); + QTcpSocket* socket(); + + void reportSuccess(); + void reportError(); + +public slots: + virtual void dataReceived(QByteArray&); + virtual void commandFinished(); + +private slots: + void _readData(); + void _disconnect(); + +private: + QTcpSocket* m_socket; +}; + +// File Creation class +class CreateFileCommand : public AbstractCommand +{ + Q_OBJECT +public: + CreateFileCommand(); + ~CreateFileCommand(); + +public slots: + void dataReceived(QByteArray&); + void commandFinished(); + +private: + CreateFileOptions m_options; + QFile m_file; + int m_dataCount; +}; + +inline AbstractCommand* instCreateFile() { return new CreateFileCommand(); } + +// Directory Creation class +class CreateDirectoryCommand : public AbstractCommand +{ + Q_OBJECT +public: + CreateDirectoryCommand(); + ~CreateDirectoryCommand(); + +public slots: + void dataReceived(QByteArray&); + void commandFinished(); +}; +inline AbstractCommand* instCreateDirectory() { return new CreateDirectoryCommand(); } + +// File copy class +class CopyFileCommand : public AbstractCommand +{ + Q_OBJECT +public: + CopyFileCommand(); + ~CopyFileCommand(); + +public slots: + void dataReceived(QByteArray&); + void commandFinished(); +}; +inline AbstractCommand* instCopyFile() { return new CopyFileCommand(); } + +// Copy directory class +class CopyDirectoryCommand : public AbstractCommand +{ + Q_OBJECT +public: + CopyDirectoryCommand(); + ~CopyDirectoryCommand(); + +public slots: + void dataReceived(QByteArray&); + void commandFinished(); +private: + bool copyDir(const QString &from, const QString &to, bool recursive); +}; +inline AbstractCommand* instCopyDirectory() { return new CopyDirectoryCommand(); } + +// Delete File class +class DeleteFileCommand : public AbstractCommand +{ + Q_OBJECT +public: + DeleteFileCommand(); + ~DeleteFileCommand(); +public slots: + void dataReceived(QByteArray&); + void commandFinished(); +}; +inline AbstractCommand* instDeleteFile() { return new DeleteFileCommand(); } + +// Delete Directory class +class DeleteDirectoryCommand : public AbstractCommand +{ + Q_OBJECT +public: + DeleteDirectoryCommand(); + ~DeleteDirectoryCommand(); +public slots: + void dataReceived(QByteArray&); + void commandFinished(); +private: + bool deleteDirectory(const QString &dirName, bool recursive, bool failIfContentExists); +}; +inline AbstractCommand* instDeleteDirectory() { return new DeleteDirectoryCommand(); } + +// Execute application class +class ExecuteCommand : public AbstractCommand +{ + Q_OBJECT +public: + ExecuteCommand(); + ~ExecuteCommand(); +public slots: + void dataReceived(QByteArray&); + void commandFinished(); +private: + void _doExecute(); + QString m_program; + QStringList m_arguments; + int m_argumentCount; + bool m_waitFinished; + int m_timeout; +}; +inline AbstractCommand* instExecution() { return new ExecuteCommand(); } + +// Read File class +class ReadFileCommand : public AbstractCommand +{ + Q_OBJECT +public: + ReadFileCommand(); + ~ReadFileCommand(); +public slots: + void dataReceived(QByteArray&); + void commandFinished(); +private: + QString m_fileName; + QFile m_file; + qint64 m_currentPos; + qint64 m_fileSize; +}; +inline AbstractCommand* instReadFile() { return new ReadFileCommand(); } + +// Read Directory class +class ReadDirectoryCommand : public AbstractCommand +{ + Q_OBJECT +public: + ReadDirectoryCommand(); + ~ReadDirectoryCommand(); +public slots: + void dataReceived(QByteArray&); + void commandFinished(); +private: + QString m_dirName; + QDir m_dir; + QDirIterator* m_iterator; +}; +inline AbstractCommand* instReadDirectory() { return new ReadDirectoryCommand(); } + +// Read File Time class +class FileTimeCommand : public AbstractCommand +{ + Q_OBJECT +public: + FileTimeCommand(); + ~FileTimeCommand(); +public slots: + void dataReceived(QByteArray&); + void commandFinished(); +}; +inline AbstractCommand* instFileTime() { return new FileTimeCommand(); } + +// Time stamp class +class TimeStampCommand : public AbstractCommand +{ + Q_OBJECT +public: + TimeStampCommand(); + ~TimeStampCommand(); +public slots: + void dataReceived(QByteArray&); + void commandFinished(); +}; +inline AbstractCommand* instTimeStamp() { return new TimeStampCommand(); } + +// Access part +typedef AbstractCommand* (*instantiator)(); + +struct CommandInfo +{ + CommandInfo(const QString &name, instantiator func) : commandName(name) , commandFunc(func) { } + QString commandName; + instantiator commandFunc; +}; + +inline QList availableCommands() +{ + QList list; + list.append(CommandInfo(QLatin1String(COMMAND_CREATE_FILE), instCreateFile)); + list.append(CommandInfo(QLatin1String(COMMAND_CREATE_DIRECTORY), instCreateDirectory)); + list.append(CommandInfo(QLatin1String(COMMAND_COPY_FILE), instCopyFile)); + list.append(CommandInfo(QLatin1String(COMMAND_COPY_DIRECTORY), instCopyDirectory)); + list.append(CommandInfo(QLatin1String(COMMAND_DELETE_FILE), instDeleteFile)); + list.append(CommandInfo(QLatin1String(COMMAND_DELETE_DIRECTORY), instDeleteDirectory)); + list.append(CommandInfo(QLatin1String(COMMAND_EXECUTE), instExecution)); + list.append(CommandInfo(QLatin1String(COMMAND_READ_FILE), instReadFile)); + list.append(CommandInfo(QLatin1String(COMMAND_READ_DIRECTORY), instReadDirectory)); + list.append(CommandInfo(QLatin1String(COMMAND_FILE_TIME), instFileTime)); + list.append(CommandInfo(QLatin1String(COMMAND_TIME_STAMP), instTimeStamp)); + return list; +} + +#endif diff --git a/tools/qtestlib/wince/cetcpsyncserver/connectionmanager.cpp b/tools/qtestlib/wince/cetcpsyncserver/connectionmanager.cpp new file mode 100644 index 0000000..901cd12 --- /dev/null +++ b/tools/qtestlib/wince/cetcpsyncserver/connectionmanager.cpp @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "connectionmanager.h" +#include "commands.h" +#include + +ConnectionManager::ConnectionManager() + : QObject() + , m_server(0) +{ + debugOutput(0, "ConnectionManager::ConnectionManager()"); +} + +ConnectionManager::~ConnectionManager() +{ + debugOutput(0, "ConnectionManager::~ConnectionManager()"); + cleanUp(); +} + +bool ConnectionManager::init() +{ + debugOutput(0, "ConnectionManager::init()"); + debugOutput(3, "Initializing server..."); + cleanUp(); + m_server = new QTcpServer(this); + connect(m_server, SIGNAL(newConnection()), this, SLOT(newConnection())); + bool result = m_server->listen(QHostAddress::Any, SERVER_PORT); + if (!result) + debugOutput(3, QString::fromLatin1(" Error: Server start failed:") + m_server->errorString()); + debugOutput(3, " Waiting for action"); + return result; +} + +void ConnectionManager::cleanUp() +{ + debugOutput(0, "ConnectionManager::cleanUp()"); + + if (m_server) { + debugOutput(1, "Removing server instance..."); + disconnect(m_server, SIGNAL(newConnection()), this, SLOT(newConnection())); + delete m_server; + m_server = 0; + } +} + +void ConnectionManager::newConnection() +{ + debugOutput(0, "ConnectionManager::newConnection()"); + + QTcpSocket* connection = m_server->nextPendingConnection(); + if (!connection) { + debugOutput(3, "Received connection has empty socket"); + return; + } + debugOutput(0, QString::fromLatin1(" received a connection: %1").arg((int) connection)); + new Connection(connection); +} + +Connection::Connection(QTcpSocket *socket) + : QObject() + , m_connection(socket) + , m_command(0) +{ + connect(m_connection, SIGNAL(readyRead()), this, SLOT(receiveCommand())); + connect(m_connection, SIGNAL(disconnected()), this, SLOT(closedConnection())); +} + +Connection::~Connection() +{ + if (m_command) { + m_command->commandFinished(); + delete m_command; + m_command = 0; + } + delete m_connection; +} + +void Connection::receiveCommand() +{ + QByteArray arr = m_connection->readAll(); + debugOutput(1, QString::fromLatin1("Command received: ") + (arr)); + QList commands = availableCommands(); + for(QList::iterator it = commands.begin(); it != commands.end(); ++it) { + if (it->commandName == QString::fromLatin1(arr)) { + debugOutput(1, "Found command in list"); + disconnect(m_connection, SIGNAL(readyRead()), this, SLOT(receiveCommand())); + AbstractCommand* command = (*it).commandFunc(); + command->setSocket(m_connection); + m_command = command; + return; + } + } + debugOutput(2, QString::fromLatin1("Unknown command received: ") + (arr)); +} + +void Connection::closedConnection() +{ + debugOutput(0, "connection being closed..."); + this->deleteLater(); +} diff --git a/tools/qtestlib/wince/cetcpsyncserver/connectionmanager.h b/tools/qtestlib/wince/cetcpsyncserver/connectionmanager.h new file mode 100644 index 0000000..21183ac --- /dev/null +++ b/tools/qtestlib/wince/cetcpsyncserver/connectionmanager.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef CONNECTION_MANAGER_INCL +#define CONNECTION_MANAGER_INCL + +#include "transfer_global.h" +#include "commands.h" + +#include +#include + +class Connection : public QObject +{ + Q_OBJECT +public: + Connection(QTcpSocket* socket); + ~Connection(); + +public slots: + void receiveCommand(); + void closedConnection(); + +private: + QTcpSocket* m_connection; + AbstractCommand* m_command; +}; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + ConnectionManager(); + ~ConnectionManager(); + + bool init(); + +public slots: + void cleanUp(); + void newConnection(); + +private: + QTcpServer* m_server; +}; + +#endif diff --git a/tools/qtestlib/wince/cetcpsyncserver/main.cpp b/tools/qtestlib/wince/cetcpsyncserver/main.cpp new file mode 100644 index 0000000..19d38ea --- /dev/null +++ b/tools/qtestlib/wince/cetcpsyncserver/main.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "connectionmanager.h" + +#include +#include + +void messageOutput(QtMsgType type, const char *msg) +{ + switch(type) { + case QtDebugMsg: fprintf(stderr, "Debug: %s\n", msg); break; + case QtWarningMsg: fprintf(stderr, "Warning: %s\n", msg); break; + default: fprintf(stderr, "Some Msg: %s\n", msg); break; + } +} + +int main(int argc, char **argv) +{ + qInstallMsgHandler(messageOutput); + + QCoreApplication app(argc, argv); + ConnectionManager manager; + manager.init(); + return app.exec(); +} diff --git a/tools/qtestlib/wince/cetcpsyncserver/transfer_global.h b/tools/qtestlib/wince/cetcpsyncserver/transfer_global.h new file mode 100644 index 0000000..5b6ff23 --- /dev/null +++ b/tools/qtestlib/wince/cetcpsyncserver/transfer_global.h @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef TRANSFER_GLOBAL_H +#define TRANSFER_GLOBAL_H + +#include +#ifdef Q_OS_WIN +#include +#endif + +#define SERVER_PORT 12145 + +#define MAX_NAME_LENGTH 512 +#define MAX_ARGUMENTS 10 + +// Defines for commands sent/received +#define COMMAND_CREATE_FILE "CREATEFILE" +#define COMMAND_CREATE_DIRECTORY "CREATEDIR" +#define COMMAND_COPY_FILE "COPYFILE" +#define COMMAND_COPY_DIRECTORY "COPYDIR" +#define COMMAND_DELETE_FILE "DELETEFILE" +#define COMMAND_DELETE_DIRECTORY "DELETEDIR" +#define COMMAND_EXECUTE "EXECUTE" +#define COMMAND_QUIT_SERVER "QUIT" +#define COMMAND_FILE_TIME "FILETIME" +#define COMMAND_TIME_STAMP "TIMESTAMP" + +// Report back commands +#define COMMAND_SUCCESS "SUCCESS" +#define COMMAND_ERROR "ERROR" + +// Defines for commands that send data back to requester +#define COMMAND_READ_FILE "READFILE" +#define COMMAND_READ_DIRECTORY "READDIR" + +#include +// Option-Structures for commands + +struct CreateFileOptions +{ + char fileName[MAX_NAME_LENGTH]; +#ifdef Q_OS_WIN + FILETIME fileTime; + DWORD fileAttributes; +#endif + int fileSize; + bool overwriteExisting; +}; + +struct CreateDirectoryOptions +{ + char dirName[MAX_NAME_LENGTH]; + bool recursively; // in case of \foo\bar create \foo if it does not exist +}; + +struct CopyFileOptions +{ + char from[MAX_NAME_LENGTH]; + char to[MAX_NAME_LENGTH]; + bool overwriteExisting; +}; + +struct CopyDirectoryOptions +{ + char from[MAX_NAME_LENGTH]; + char to[MAX_NAME_LENGTH]; + bool recursive; +}; + +struct DeleteFileOptions +{ + char fileName[MAX_NAME_LENGTH]; +}; + +struct DeleteDirectoryOptions +{ + char dirName[MAX_NAME_LENGTH]; + bool recursive; + bool failIfContentExists; +}; + +struct ExecuteOptions +{ + char appName[MAX_NAME_LENGTH]; + int argumentsCount; + bool waitForFinished; + int timeout; +}; + +struct ReadFileOptions +{ + char fileName[MAX_NAME_LENGTH]; +}; + +struct ReadFileReply +{ + qint64 fileSize; + bool fileValid; +}; + +struct ReadDirectoryOptions +{ + char dirName[MAX_NAME_LENGTH]; +}; + +struct ReadDirectoryItem +{ + char name[MAX_NAME_LENGTH]; + qint64 size; + bool isDirectory; + bool hasMore; +}; + +#define FileTimeOptions ReadFileOptions + +struct ReadDirectoryReply +{ + bool entryValid; + int itemCount; // might change during iteration +}; +#endif -- cgit v0.12 From a34ec3bf9d6077bdc62cb48e116751788996fd99 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 5 Aug 2009 11:34:48 +0200 Subject: initial revision of cetcpsync This is the desktop client for communicating with a Windows CE device that runs the cetcpsync server. Reviewed-By: mauricek --- tools/qtestlib/wince/cetcpsync/cetcpsync.pro | 22 + tools/qtestlib/wince/cetcpsync/main.cpp | 191 +++++++ .../wince/cetcpsync/qtcesterconnection.cpp | 551 +++++++++++++++++++++ .../qtestlib/wince/cetcpsync/qtcesterconnection.h | 86 ++++ .../qtestlib/wince/cetcpsync/remoteconnection.cpp | 65 +++ tools/qtestlib/wince/cetcpsync/remoteconnection.h | 81 +++ 6 files changed, 996 insertions(+) create mode 100644 tools/qtestlib/wince/cetcpsync/cetcpsync.pro create mode 100644 tools/qtestlib/wince/cetcpsync/main.cpp create mode 100644 tools/qtestlib/wince/cetcpsync/qtcesterconnection.cpp create mode 100644 tools/qtestlib/wince/cetcpsync/qtcesterconnection.h create mode 100644 tools/qtestlib/wince/cetcpsync/remoteconnection.cpp create mode 100644 tools/qtestlib/wince/cetcpsync/remoteconnection.h diff --git a/tools/qtestlib/wince/cetcpsync/cetcpsync.pro b/tools/qtestlib/wince/cetcpsync/cetcpsync.pro new file mode 100644 index 0000000..d1d7c99 --- /dev/null +++ b/tools/qtestlib/wince/cetcpsync/cetcpsync.pro @@ -0,0 +1,22 @@ +TARGET = cetcpsync +DESTDIR = ../../../../bin +CONFIG += console +CONFIG -= app_bundle +QT += network +QT -= gui +TEMPLATE = app + +build_all:!build_pass { + CONFIG -= build_all + CONFIG += release +} + +INCLUDEPATH += ../cetcpsyncserver + +SOURCES += main.cpp \ + remoteconnection.cpp \ + qtcesterconnection.cpp + +HEADERS += \ + remoteconnection.h \ + qtcesterconnection.h diff --git a/tools/qtestlib/wince/cetcpsync/main.cpp b/tools/qtestlib/wince/cetcpsync/main.cpp new file mode 100644 index 0000000..73c7350 --- /dev/null +++ b/tools/qtestlib/wince/cetcpsync/main.cpp @@ -0,0 +1,191 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include "qtcesterconnection.h" + +using namespace std; + +static void showUsage() +{ + cout << "cetcpsync is meant to be used by cetest internally." << endl + << "For usage instructions remoteconnection.h could be useful." << endl; +} + +const int debugLevel = 0; +void debugOutput(const QString& text, int level) +{ + if (level <= debugLevel) + cout << qPrintable(text) << endl; +} + +class Exception +{ +public: + Exception(const QString& msg = QString()) + : m_message(msg) + {} + + QString message() { return m_message; } + +protected: + QString m_message; +}; + +class TooFewParametersException : public Exception +{ +public: + TooFewParametersException(const QLatin1String& cmd, int expectedParameterCount) + { + m_message = QLatin1String("Command ") + cmd + QLatin1String(" needs at least "); + m_message.append(QString::number(expectedParameterCount)); + m_message.append(QLatin1String(" parameters.")); + } +}; + +static void fileTimeFromString(FILETIME& ft, const QString& str) +{ + int idx = str.indexOf("*"); + if (idx <= 0) + return; + ft.dwLowDateTime = str.left(idx).toULong(); + ft.dwHighDateTime = str.mid(idx+1).toULong(); +} + +static QString fileTimeToString(FILETIME& ft) +{ + return QString::number(ft.dwLowDateTime) + "*" + QString::number(ft.dwHighDateTime); +} + +static int execCommand(const QLatin1String& cmd, int argc, char* argv[]) +{ + int retval = 0; + bool success = true; + QtCesterConnection connection; + if (cmd == "copyFileToDevice") { + if (argc < 3) + throw TooFewParametersException(cmd, 3); + success = connection.copyFileToDevice(argv[0], argv[1], argv[2] == "true"); + } else if (cmd == "copyDirectoryToDevice") { + if (argc < 3) + throw TooFewParametersException(cmd, 3); + success = connection.copyDirectoryToDevice(argv[0], argv[1], argv[2] == "true"); + } else if (cmd == "copyFileFromDevice") { + if (argc < 3) + throw TooFewParametersException(cmd, 3); + success = connection.copyFileFromDevice(argv[0], argv[1], argv[2] == "true"); + } else if (cmd == "copyDirectoryFromDevice") { + if (argc < 3) + throw TooFewParametersException(cmd, 3); + success = connection.copyDirectoryFromDevice(argv[0], argv[1], argv[2] == "true"); + } else if (cmd == "timeStampForLocalFileTime") { + if (argc < 1) + throw TooFewParametersException(cmd, 1); + FILETIME ft; + fileTimeFromString(ft, argv[0]); + success = connection.timeStampForLocalFileTime(&ft); + if (success) + cout << qPrintable(fileTimeToString(ft)); + } else if (cmd == "fileCreationTime") { + if (argc < 1) + throw TooFewParametersException(cmd, 1); + FILETIME ft; + success = connection.fileCreationTime(argv[0], &ft); + if (success) + cout << qPrintable(fileTimeToString(ft)); + } else if (cmd == "copyFile") { + if (argc < 3) + throw TooFewParametersException(cmd, 3); + success = connection.copyFile(argv[0], argv[1], argv[2] == "true"); + } else if (cmd == "copyDirectory") { + if (argc < 3) + throw TooFewParametersException(cmd, 3); + success = connection.copyDirectory(argv[0], argv[1], argv[2] == "true"); + } else if (cmd == "deleteFile") { + if (argc < 1) + throw TooFewParametersException(cmd, 1); + success = connection.deleteFile(argv[0]); + } else if (cmd == "deleteDirectory") { + if (argc < 3) + throw TooFewParametersException(cmd, 3); + success = connection.deleteDirectory(argv[0], argv[1] == "true", argv[2] == "true"); + } else if (cmd == "moveFile") { + if (argc < 3) + throw TooFewParametersException(cmd, 3); + success = connection.moveFile(argv[0], argv[1], argv[2] == "true"); + } else if (cmd == "moveDirectory") { + if (argc < 3) + throw TooFewParametersException(cmd, 3); + success = connection.moveDirectory(argv[0], argv[1], argv[2] == "true"); + } else if (cmd == "createDirectory") { + if (argc < 2) + throw TooFewParametersException(cmd, 2); + success = connection.createDirectory(argv[0], argv[1] == "true"); + } else if (cmd == "execute") { + if (argc < 3) + throw TooFewParametersException(cmd, 3); + int timeout = QString(argv[2]).toInt(); + success = connection.execute(argv[0], argv[1], timeout, &retval); + } else if (cmd == "noop") { + // do nothing :) + success = true; + } else { + throw Exception("unknown command"); + } + + return success ? retval : 1; +} + +int main(int argc, char *argv[]) +{ + if (argc <= 1) { + showUsage(); + return 0; + } + + QLatin1String param(argv[1]); + int result = 1; + try { + result = execCommand(param, argc - 2, argv + 2); + } catch (Exception e) { + cerr << "Error: " << qPrintable(e.message()); + } + return result; +} diff --git a/tools/qtestlib/wince/cetcpsync/qtcesterconnection.cpp b/tools/qtestlib/wince/cetcpsync/qtcesterconnection.cpp new file mode 100644 index 0000000..4a8ae2b --- /dev/null +++ b/tools/qtestlib/wince/cetcpsync/qtcesterconnection.cpp @@ -0,0 +1,551 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "qtcesterconnection.h" +#include +#include +#include +#include +#include +#include + +extern void debugOutput(const QString& text, int level); + +#pragma warning(disable:4996) + +#define END_ERROR(s, a) \ + if(a) qDebug() << a; \ + _freeSocket(s); \ + return false; + +QtCesterConnection::QtCesterConnection() + : AbstractRemoteConnection() +{ +} + +QtCesterConnection::~QtCesterConnection() +{ +} + +bool QtCesterConnection::connect(QVariantList&) +{ + // We connect with each command, so this is always true + // The command itself will fail then + connected = true; + return true; +} + +void QtCesterConnection::disconnect() +{ + connected = false; +} + +bool QtCesterConnection::isConnected() const +{ + return connected; +} + +bool QtCesterConnection::copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists) +{ + debugOutput( qPrintable(QString::fromLatin1("Copy File: %1 -> %2").arg(localSource).arg(deviceDest)),0); + QFile localFile(localSource); + QFileInfo info(localSource); + if (!localFile.exists() || !localFile.open(QIODevice::ReadOnly)) { + qDebug() << "Could not open File!"; + return false; + } + + QTcpSocket* socket = 0; + if (!_initCommand(socket, COMMAND_CREATE_FILE)) { + END_ERROR(socket, "Could not initialized command"); + } + + CreateFileOptions option; + strcpy(option.fileName, qPrintable(deviceDest)); +#ifdef Q_OS_WIN + // Copy FileTime for update verification + FILETIME creationTime, accessTime, writeTime; + HANDLE localHandle = CreateFile(localSource.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); + if (localHandle != INVALID_HANDLE_VALUE) { + if (GetFileTime(localHandle, &creationTime, &accessTime, &writeTime)) { + LocalFileTimeToFileTime(&writeTime, &writeTime); + option.fileTime = writeTime; + } + CloseHandle(localHandle); + } + DWORD attributes = GetFileAttributes(localSource.utf16()); + if (attributes != -1 ) + option.fileAttributes = attributes; +#endif + option.fileSize = info.size(); + option.overwriteExisting = !failIfExists; + + if (!_sendData(socket, (char*) &option, sizeof(option))) { + END_ERROR(socket, "Could not send options..."); + } + + if (!_checkResult(socket)) { + END_ERROR(socket, "Server did not accept configuration"); + } + + int bytesWritten = 0; + const int bufferSize = 1024; + QByteArray data; + while (bytesWritten < option.fileSize) { + data = localFile.read(bufferSize); + bytesWritten += data.size(); +#ifdef Q_OS_WIN + wprintf( L"%s -> %s (%d / %d) %d %%\r", localSource.utf16() , deviceDest.utf16(), + bytesWritten , option.fileSize, (100*bytesWritten)/option.fileSize ); +#endif + if (!_sendData(socket, data.constData(), data.size())) { + END_ERROR(socket, "Error during file transfer"); + } + if (!_checkResult(socket)) { + END_ERROR(socket, "Got some strange result"); + } + } +#ifdef Q_OS_WIN + wprintf( L"\n"); // We should jump to next line... +#endif + if (bytesWritten != option.fileSize) { + END_ERROR(socket, "Did not send sufficient data"); + } + _freeSocket(socket); + return true; +} + +bool QtCesterConnection::copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive) +{ + QTcpSocket* socket = NULL; + QFileInfo info(localSource); + if (!info.exists() || !info.isDir()) { + END_ERROR(socket, "Input directory invalid"); + } + + createDirectory(deviceDest, true); + QDir dir(localSource); + QFileInfoList list = dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); + foreach(QFileInfo item, list) { + QString targetName = deviceDest + QLatin1String("\\") + item.fileName(); + if (item.isDir()) { + if (recursive) { + if (!copyDirectoryToDevice(item.absoluteFilePath() , targetName, recursive)) + return false; + } + } else { + if (!copyFileToDevice(item.absoluteFilePath(), targetName)) + return false; + } + } + return true; +} + +bool QtCesterConnection::copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists) +{ + QFile targetFile(localDest); + QTcpSocket* socket = 0; + if (targetFile.exists() && failIfExists) { + END_ERROR(socket, "Local file not supposed to be overwritten"); + } + + if (!targetFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { + END_ERROR(socket, "Could not open local file for writing"); + } + + if (!_initCommand(socket, COMMAND_READ_FILE)) { + END_ERROR(socket, "Could not establish connection"); + } + + ReadFileOptions option; + strcpy(option.fileName, qPrintable(deviceSource)); + if (!_sendData(socket, (char*) &option, sizeof(option))) { + END_ERROR(socket, "Could not send options"); + } + + QByteArray data; + if (!_receiveData(socket, data)) { + END_ERROR(socket, "Did not receive any data"); + } + + ReadFileReply* reply = (ReadFileReply*) data.data(); + if (!reply->fileValid) { + END_ERROR(socket, "Requested file invalid"); + } + + int fileSize = reply->fileSize; + int currentSize = 0; + // ### TODO: make a little bit more error-prone + do { + _sendData(socket, COMMAND_SUCCESS, strlen(COMMAND_SUCCESS)); + _receiveData(socket, data); + currentSize += data.size(); + targetFile.write(data); + } while(currentSize < fileSize); + + _freeSocket(socket); + targetFile.close(); + return true; +} + +bool QtCesterConnection::copyDirectoryFromDevice(const QString& /*deviceSource*/ + , const QString& /*localDest*/ + , bool /*recursive*/) +{ + qDebug() << "To be implemented!! Should not be needed for autotest system"; + exit(-1); + return false; +} + +bool QtCesterConnection::copyFile(const QString &srcFile, const QString &destFile, bool failIfExists) +{ + QTcpSocket* socket = 0; + if (!_initCommand(socket, COMMAND_COPY_FILE)) { + END_ERROR(socket, "Could not establish connection for copy"); + } + + CopyFileOptions option; + strcpy(option.from, qPrintable(srcFile)); + strcpy(option.to, qPrintable(destFile)); + option.overwriteExisting = !failIfExists; + if (!_sendData(socket, (char*) &option, sizeof(option))) { + END_ERROR(socket, "Could not send copy options"); + } + + if (!_checkResult(socket)) { + END_ERROR(socket, "Copy failed"); + } + + _freeSocket(socket); + return true; +} + +bool QtCesterConnection::copyDirectory(const QString &srcDirectory, const QString &destDirectory, + bool recursive) +{ + QTcpSocket* socket = 0; + if (!_initCommand(socket, COMMAND_COPY_DIRECTORY)) { + END_ERROR(socket, "Could not establish connection for dir copy"); + } + + CopyDirectoryOptions option; + strcpy(option.from, qPrintable(srcDirectory)); + strcpy(option.to, qPrintable(destDirectory)); + option.recursive = recursive; + if (!_sendData(socket, (char*) &option, sizeof(option))) { + END_ERROR(socket, "Could not send dir copy options"); + } + + if (!_checkResult(socket)) { + END_ERROR(socket, "Dir Copy failed"); + } + + _freeSocket(socket); + return true; +} + +bool QtCesterConnection::deleteFile(const QString &fileName) +{ + QTcpSocket* socket = 0; + if (!_initCommand(socket, COMMAND_DELETE_FILE)) { + END_ERROR(socket, "Could not establish connection for file deletion"); + } + + DeleteFileOptions option; + strcpy(option.fileName, qPrintable(fileName)); + if (!_sendData(socket, (char*) &option, sizeof(option))) { + END_ERROR(socket, "Could not send file options"); + } + + if (!_checkResult(socket)) { + END_ERROR(socket, "File Deletion failed"); + } + + _freeSocket(socket); + return true; +} + +bool QtCesterConnection::deleteDirectory(const QString &directory, bool recursive, bool failIfContentExists) +{ + QTcpSocket* socket = 0; + if (!_initCommand(socket, COMMAND_DELETE_DIRECTORY)) { + END_ERROR(socket, "Could not establish connection for dir deletion"); + } + + DeleteDirectoryOptions option; + strcpy(option.dirName, qPrintable(directory)); + option.recursive = recursive; + option.failIfContentExists = failIfContentExists; + if (!_sendData(socket, (char*) &option, sizeof(option))) { + END_ERROR(socket, "Could not send dir options"); + } + + if (!_checkResult(socket)) { + // we do not write an error as this will fail a lot on recursive. + END_ERROR(socket, 0); + } + + _freeSocket(socket); + return true; +} + +bool QtCesterConnection::execute(QString program, + QString arguments, + int timeout, + int *returnValue) +{ + QTcpSocket* socket = 0; + if (!_initCommand(socket, COMMAND_EXECUTE)) { + END_ERROR(socket, "Could not establish connection for dir deletion"); + } + + ExecuteOptions options; + strcpy(options.appName, qPrintable(program)); + QStringList argList = arguments.split(QLatin1Char(' ')); + options.argumentsCount = qMin(argList.size(), MAX_ARGUMENTS); + options.waitForFinished = true; + options.timeout = timeout; + if (!_sendData(socket, (char*) &options, sizeof(options))) { + END_ERROR(socket, "Could not send dir options"); + } + if (!_checkResult(socket)) { + END_ERROR(socket, "Did not receive an answer"); + } + + for (int i=0; i < options.argumentsCount; ++i) { + char someData[MAX_NAME_LENGTH]; + strcpy(someData, qPrintable(argList[i])); + if (!_sendData(socket, someData, MAX_NAME_LENGTH)) { + END_ERROR(socket, "Could not send argument"); + } + if (!_checkResult(socket)) { + END_ERROR(socket, "Failure in argument send"); + } + } + + // trigger the startup + if (!_sendData(socket, COMMAND_SUCCESS, strlen(COMMAND_SUCCESS))) { + END_ERROR(socket, "Could not trigger startup"); + } + + const int waitTime = 60 * 60 * 1000; + if (!socket->waitForReadyRead(waitTime)) { + END_ERROR(socket, "Process timed out"); + } + + QByteArray result = socket->readAll(); + if (result != COMMAND_SUCCESS) { + if (returnValue) + *returnValue = -1; // just some at least + END_ERROR(socket, "Application did not start or returned error"); + } + + if (returnValue) + *returnValue = 0; + _freeSocket(socket); + return true; +} + +bool QtCesterConnection::createDirectory(const QString &path, bool deleteBefore) +{ + if (deleteBefore) + deleteDirectory(path, true, true); + + QTcpSocket* socket = 0; + if (!_initCommand(socket, COMMAND_CREATE_DIRECTORY)) { + END_ERROR(socket, "Could not establish connection for dir creation"); + } + + CreateDirectoryOptions option; + strcpy(option.dirName, qPrintable(path)); + option.recursively = true; + if (!_sendData(socket, (char*) &option, sizeof(option))) { + END_ERROR(socket, "Could not send dir options"); + } + + if (!_checkResult(socket)) { + END_ERROR(socket, "Dir creation failed"); + } + + _freeSocket(socket); + return true; +} + +bool QtCesterConnection::timeStampForLocalFileTime(FILETIME* fTime) const +{ + if (!fTime) + return false; + + FILETIME copyTime = *fTime; + LocalFileTimeToFileTime(©Time, ©Time); + + QTcpSocket* socket = 0; + if (!_initCommand(socket, COMMAND_TIME_STAMP)) { + END_ERROR(socket, "Could not establish time stamp connection"); + } + + if (!_sendData(socket, (char*) ©Time, sizeof(copyTime))) { + END_ERROR(socket, "Could not send stamp time"); + } + + QByteArray data; + if (!_receiveData(socket, data)) { + END_ERROR(socket, "Did not receive time stamp or connection interrupted"); + } + + copyTime = *((FILETIME*)data.data()); + if (copyTime.dwLowDateTime == -1 && copyTime.dwHighDateTime == -1) { + END_ERROR(socket, "remote Time stamp failed!"); + } + + *fTime = copyTime; + _freeSocket(socket); + return true; +} + +bool QtCesterConnection::fileCreationTime(const QString &fileName, FILETIME* deviceCreationTime) const +{ + if (!deviceCreationTime) + return false; + + QTcpSocket* socket = 0; + if (!_initCommand(socket, COMMAND_FILE_TIME)) { + END_ERROR(socket, "Could not establish connection for file time access"); + } + + FileTimeOptions option; + strcpy(option.fileName, qPrintable(fileName)); + if (!_sendData(socket, (char*) &option, sizeof(option))) { + END_ERROR(socket, "Could not send file time name"); + } + + QByteArray data; + if (!_receiveData(socket, data)) { + END_ERROR(socket, "File Time request failed"); + } + + FILETIME* resultTime = (FILETIME*) data.data(); + if (resultTime->dwLowDateTime == -1 && resultTime->dwHighDateTime == -1) { + END_ERROR(socket, 0); + debugOutput("Could not access file time", 0); + } + + *deviceCreationTime = *resultTime; + _freeSocket(socket); + return true; +} + +bool QtCesterConnection::_createSocket(QTcpSocket*& result) const +{ + QTcpSocket* sock = new QTcpSocket(); + QByteArray ipAddress = qgetenv("DEVICE_IP"); + if (ipAddress.isEmpty()) { + qWarning("Error: You need to have DEVICE_IP set"); + exit(0); + } + sock->connectToHost(QHostAddress(QString(ipAddress)), 12145); + + if (!sock->waitForConnected()) { + qDebug() << "connection timeout..."; + result = NULL; + return false; + } + result = sock; + return true; +} + +void QtCesterConnection::_freeSocket(QTcpSocket*& sock) const +{ + if (!sock) + return; + if (sock->state() == QAbstractSocket::ConnectedState) { + sock->disconnectFromHost(); + // seems like no need to wait + //sock->waitForDisconnected(); + } + delete sock; + sock = NULL; +#ifdef Q_OS_WIN + Sleep(100); +#endif +} + +bool QtCesterConnection::_initCommand(QTcpSocket*& sock, const char* command) const +{ + QTcpSocket* socket = NULL; + if (!_createSocket(socket)) { + END_ERROR(socket, "Could not connect to server"); + } + + if (!_sendData(socket, command, strlen(command)) || + !_checkResult(socket)) { + END_ERROR(socket, "Cound not send command"); + } + sock = socket; + return true; +} + +bool QtCesterConnection::_sendData(QTcpSocket*& sock, const char* data, int dataSize) const +{ + int amount = sock->write(data, dataSize); + if (amount != dataSize) { + fprintf(stderr, "*******COULD NOT SEND ENOUGH DATA*************\n"); + } + return sock->waitForBytesWritten(); +} + +bool QtCesterConnection::_receiveData(QTcpSocket*& sock, QByteArray& data) const +{ + if (!sock->waitForReadyRead()) { + qDebug() << "did not receive any data"; + return false; + } + data = sock->readAll(); + return true; +} + +bool QtCesterConnection::_checkResult(QTcpSocket*& sock) const +{ + QByteArray response; + if (!_receiveData(sock, response) || response != COMMAND_SUCCESS) + return false; + return true; +} + diff --git a/tools/qtestlib/wince/cetcpsync/qtcesterconnection.h b/tools/qtestlib/wince/cetcpsync/qtcesterconnection.h new file mode 100644 index 0000000..d7b8393 --- /dev/null +++ b/tools/qtestlib/wince/cetcpsync/qtcesterconnection.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef ACTIVESYNC_REMOTECONNECTION_H +#define ACTIVESYNC_REMOTECONNECTION_H + +#include "remoteconnection.h" + +class QTcpSocket; + +class QtCesterConnection : public AbstractRemoteConnection +{ +public: + QtCesterConnection(); + virtual ~QtCesterConnection(); + + bool connect(QVariantList &list = QVariantList()); + void disconnect(); + bool isConnected() const; + + // These functions are designed for transfer between desktop and device + // Caution: deviceDest path has to be device specific (eg. no drive letters for CE) + bool copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists = false); + bool copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive = true); + bool copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists = false); + bool copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive = true); + + bool timeStampForLocalFileTime(FILETIME*) const; + bool fileCreationTime(const QString &fileName, FILETIME*) const; + + // These functions only work on files existing on the device + bool copyFile(const QString&, const QString&, bool failIfExists = false); + bool copyDirectory(const QString&, const QString&, bool recursive = true); + bool deleteFile(const QString&); + bool deleteDirectory(const QString&, bool recursive = true, bool failIfContentExists = false); + bool createDirectory(const QString&, bool deleteBefore=false); + + bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL); +private: + bool _createSocket(QTcpSocket*&) const; + void _freeSocket(QTcpSocket*&) const; + bool _initCommand(QTcpSocket*&, const char*) const; + bool _sendData(QTcpSocket*&, const char* data, int dataSize) const; + bool _receiveData(QTcpSocket*&, QByteArray&) const; + bool _checkResult(QTcpSocket*&) const; + bool connected; +}; + +#endif diff --git a/tools/qtestlib/wince/cetcpsync/remoteconnection.cpp b/tools/qtestlib/wince/cetcpsync/remoteconnection.cpp new file mode 100644 index 0000000..b197c5c --- /dev/null +++ b/tools/qtestlib/wince/cetcpsync/remoteconnection.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "remoteconnection.h" + +AbstractRemoteConnection::AbstractRemoteConnection() +{ +} + +AbstractRemoteConnection::~AbstractRemoteConnection() +{ +} + +// Slow but should be ok... +bool AbstractRemoteConnection::moveFile(const QString &src, const QString &dest, bool FailIfExists) +{ + bool result = copyFile(src, dest, FailIfExists); + deleteFile(src); + return result; +} + +// Slow but should be ok... +bool AbstractRemoteConnection::moveDirectory(const QString &src, const QString &dest, bool recursive) +{ + bool result = copyDirectory(src, dest, true); + deleteDirectory(src, recursive); + return result; +} diff --git a/tools/qtestlib/wince/cetcpsync/remoteconnection.h b/tools/qtestlib/wince/cetcpsync/remoteconnection.h new file mode 100644 index 0000000..fae6f7f --- /dev/null +++ b/tools/qtestlib/wince/cetcpsync/remoteconnection.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef REMOTECONNECTION_H +#define REMOTECONNECTION_H + +#include +#include +#include +class AbstractRemoteConnection +{ +public: + AbstractRemoteConnection(); + virtual ~AbstractRemoteConnection(); + + virtual bool connect(QVariantList&) = 0; + virtual void disconnect() = 0; + virtual bool isConnected() const = 0; + + // These functions are designed for transfer between desktop and device + // Caution: deviceDest path has to be device specific (eg. no drive letters for CE) + virtual bool copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists = false) = 0; + virtual bool copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive = true) = 0; + virtual bool copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists = false) = 0; + virtual bool copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive = true) = 0; + + // For "intelligent deployment" we need to investigate on filetimes on the device + virtual bool timeStampForLocalFileTime(FILETIME*) const = 0; + virtual bool fileCreationTime(const QString &fileName, FILETIME*) const = 0; + + // These functions only work on files existing on the device + virtual bool copyFile(const QString&, const QString&, bool failIfExists = false) = 0; + virtual bool copyDirectory(const QString&, const QString&, bool recursive = true) = 0; + virtual bool deleteFile(const QString&) = 0; + virtual bool deleteDirectory(const QString&, bool recursive = true, bool failIfContentExists = false) = 0; + bool moveFile(const QString&, const QString&, bool FailIfExists = false); + bool moveDirectory(const QString&, const QString&, bool recursive = true); + + virtual bool createDirectory(const QString&, bool deleteBefore=false) = 0; + + virtual bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL) = 0; +}; + +#endif -- cgit v0.12 From f78bd88cbb8fd4c32e487eed716f089b6f5cfe28 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 5 Aug 2009 12:58:39 +0200 Subject: Workaround a crash in qdoc. Caused by an odd number of classes it seems. --- tools/qdoc3/htmlgenerator.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index 6b15f96..df63138 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -2097,6 +2097,11 @@ void HtmlGenerator::generateCompactList(const Node *relative, currentOffsetInParagraph[i] = 0; } + if (currentParagraphNo[i] >= NumParagraphs) { + qDebug() << "### Internal error ###" << __FILE__ << __LINE__; + currentParagraphNo[i] = NumParagraphs - 1; + } + out() << ""; if (currentOffsetInParagraph[i] == 0) { // start a new paragraph -- cgit v0.12 From 0002516329cbbf5fb0b677835353bf7ccd4e425f Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 5 Aug 2009 13:01:02 +0200 Subject: missing license header added in cetcpsyncsvr Reviewed-by: TrustMe --- tools/qtestlib/wince/cetcpsyncserver/commands.cpp | 40 +++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tools/qtestlib/wince/cetcpsyncserver/commands.cpp b/tools/qtestlib/wince/cetcpsyncserver/commands.cpp index 64869c4..0c4d3bc 100644 --- a/tools/qtestlib/wince/cetcpsyncserver/commands.cpp +++ b/tools/qtestlib/wince/cetcpsyncserver/commands.cpp @@ -1,3 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ #include "commands.h" #include #include -- cgit v0.12 From 770ce0a8cd7493e3be3e7accf7133778336c6f5d Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 5 Aug 2009 13:02:18 +0200 Subject: small cleanup in cetest Reviewed-by: TrustMe --- .../qtestlib/wince/cetest/cetcpsyncconnection.cpp | 31 +++++++++++----------- tools/qtestlib/wince/cetest/cetest.pro | 4 +-- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/tools/qtestlib/wince/cetest/cetcpsyncconnection.cpp b/tools/qtestlib/wince/cetest/cetcpsyncconnection.cpp index bebcd1c..f00d2b8 100644 --- a/tools/qtestlib/wince/cetest/cetcpsyncconnection.cpp +++ b/tools/qtestlib/wince/cetest/cetcpsyncconnection.cpp @@ -44,6 +44,7 @@ #include #include +static const QString ceTcpSyncProgram = ceTcpSyncProgram + ""; extern void debugOutput(const QString& text, int level); CeTcpSyncConnection::CeTcpSyncConnection() @@ -62,7 +63,7 @@ bool CeTcpSyncConnection::connect(QVariantList&) { // We connect with each command, so this is always true // The command itself will fail then - if (system("cetcpsync noop") != 0) + if (system(ceTcpSyncProgram + " noop") != 0) return false; connected = true; return true; @@ -103,56 +104,56 @@ static QString fileTimeToString(FILETIME& ft) bool CeTcpSyncConnection::copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists) { - QString cmd = "cetcpsync copyFileToDevice \"" + localSource + "\" \"" + deviceDest + "\" " + boolToString(failIfExists); + QString cmd = ceTcpSyncProgram + " copyFileToDevice \"" + localSource + "\" \"" + deviceDest + "\" " + boolToString(failIfExists); return system(qPrintable(cmd)) == 0; } bool CeTcpSyncConnection::copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive) { - QString cmd = "cetcpsync copyDirectoryToDevice \"" + localSource + "\" \"" + deviceDest + "\" " + boolToString(recursive); + QString cmd = ceTcpSyncProgram + " copyDirectoryToDevice \"" + localSource + "\" \"" + deviceDest + "\" " + boolToString(recursive); return system(qPrintable(cmd)) == 0; } bool CeTcpSyncConnection::copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists) { - QString cmd = "cetcpsync copyFileFromDevice \"" + deviceSource + "\" \"" + localDest + "\" " + boolToString(failIfExists); + QString cmd = ceTcpSyncProgram + " copyFileFromDevice \"" + deviceSource + "\" \"" + localDest + "\" " + boolToString(failIfExists); return system(qPrintable(cmd)) == 0; } bool CeTcpSyncConnection::copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive) { - QString cmd = "cetcpsync copyDirectoryFromDevice \"" + deviceSource + "\" \"" + localDest + "\" " + boolToString(recursive); + QString cmd = ceTcpSyncProgram + " copyDirectoryFromDevice \"" + deviceSource + "\" \"" + localDest + "\" " + boolToString(recursive); return system(qPrintable(cmd)) == 0; } bool CeTcpSyncConnection::copyFile(const QString &srcFile, const QString &destFile, bool failIfExists) { - QString cmd = "cetcpsync copyFile \"" + srcFile + "\" \"" + destFile + "\" " + boolToString(failIfExists); + QString cmd = ceTcpSyncProgram + " copyFile \"" + srcFile + "\" \"" + destFile + "\" " + boolToString(failIfExists); return system(qPrintable(cmd)) == 0; } bool CeTcpSyncConnection::copyDirectory(const QString &srcDirectory, const QString &destDirectory, bool recursive) { - QString cmd = "cetcpsync copyDirectory \"" + srcDirectory + "\" \"" + destDirectory + "\" " + boolToString(recursive); + QString cmd = ceTcpSyncProgram + " copyDirectory \"" + srcDirectory + "\" \"" + destDirectory + "\" " + boolToString(recursive); return system(qPrintable(cmd)) == 0; } bool CeTcpSyncConnection::deleteFile(const QString &fileName) { - QString cmd = "cetcpsync deleteFile \"" + fileName + "\""; + QString cmd = ceTcpSyncProgram + " deleteFile \"" + fileName + "\""; return system(qPrintable(cmd)) == 0; } bool CeTcpSyncConnection::deleteDirectory(const QString &directory, bool recursive, bool failIfContentExists) { - QString cmd = "cetcpsync deleteDirectory \"" + directory + "\" " + boolToString(recursive) + " " + boolToString(failIfContentExists); + QString cmd = ceTcpSyncProgram + " deleteDirectory \"" + directory + "\" " + boolToString(recursive) + " " + boolToString(failIfContentExists); return system(qPrintable(cmd)) == 0; } bool CeTcpSyncConnection::execute(QString program, QString arguments, int timeout, int *returnValue) { - QString cmd = "cetcpsync execute \"" + program + "\" \"" + arguments + "\" " + QString::number(timeout); + QString cmd = ceTcpSyncProgram + " execute \"" + program + "\" \"" + arguments + "\" " + QString::number(timeout); int exitCode = system(qPrintable(cmd)); if (returnValue) *returnValue = exitCode; @@ -161,17 +162,17 @@ bool CeTcpSyncConnection::execute(QString program, QString arguments, int timeou bool CeTcpSyncConnection::createDirectory(const QString &path, bool deleteBefore) { - QString cmd = "cetcpsync createDirectory \"" + path + "\" " + boolToString(deleteBefore); + QString cmd = ceTcpSyncProgram + " createDirectory \"" + path + "\" " + boolToString(deleteBefore); return system(qPrintable(cmd)) == 0; } bool CeTcpSyncConnection::timeStampForLocalFileTime(FILETIME* fTime) const { - QString cmd = "cetcpsync timeStampForLocalFileTime " + fileTimeToString(*fTime) + " >filetime.txt"; + QString cmd = ceTcpSyncProgram + " timeStampForLocalFileTime " + fileTimeToString(*fTime) + " >qt_cetcpsyncdata.txt"; if (system(qPrintable(cmd)) != 0) return false; - QFile file("filetime.txt"); + QFile file("qt_cetcpsyncdata.txt"); if (!file.open(QIODevice::ReadOnly)) return false; @@ -183,11 +184,11 @@ bool CeTcpSyncConnection::timeStampForLocalFileTime(FILETIME* fTime) const bool CeTcpSyncConnection::fileCreationTime(const QString &fileName, FILETIME* deviceCreationTime) const { - QString cmd = "cetcpsync fileCreationTime \"" + fileName + "\" >filetime.txt"; + QString cmd = ceTcpSyncProgram + " fileCreationTime \"" + fileName + "\" >qt_cetcpsyncdata.txt"; if (system(qPrintable(cmd)) != 0) return false; - QFile file("filetime.txt"); + QFile file("qt_cetcpsyncdata.txt"); if (!file.open(QIODevice::ReadOnly)) return false; diff --git a/tools/qtestlib/wince/cetest/cetest.pro b/tools/qtestlib/wince/cetest/cetest.pro index c6eba7f..a6b79da 100644 --- a/tools/qtestlib/wince/cetest/cetest.pro +++ b/tools/qtestlib/wince/cetest/cetest.pro @@ -35,7 +35,7 @@ SOURCES += \ deployment.cpp \ main.cpp -win32-msvc*:LIBS += ole32.lib advapi32.lib +LIBS += ole32.lib advapi32.lib isEmpty(QT_CE_RAPI_INC) { DEFINES += QT_CETEST_NO_ACTIVESYNC @@ -44,7 +44,7 @@ isEmpty(QT_CE_RAPI_INC) { } else { HEADERS += activesyncconnection.h SOURCES += activesyncconnection.cpp - win32-msvc*:LIBS += rapi.lib + LIBS += rapi.lib INCLUDEPATH += $$QT_CE_RAPI_INC LIBS += -L$$QT_CE_RAPI_LIB } -- cgit v0.12 From 0ba2e3c4fa088a5467279cf851b2b49697ccad5c Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 5 Aug 2009 13:14:16 +0200 Subject: Re-enable the use of Common Item Dialog This was disabled by patch bf305bc2e488ad4f08c49767246f31a81218991e Reviewed-by: Thomas Hartmann --- src/gui/dialogs/qfiledialog_win.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/dialogs/qfiledialog_win.cpp b/src/gui/dialogs/qfiledialog_win.cpp index 9bf82c3..c542ff0 100644 --- a/src/gui/dialogs/qfiledialog_win.cpp +++ b/src/gui/dialogs/qfiledialog_win.cpp @@ -59,7 +59,9 @@ #endif #include - +#if !defined(Q_WS_WINCE) +#include +#endif #include #if defined(__IFileDialog_INTERFACE_DEFINED__) \ -- cgit v0.12 From cb599c5ea32e8e5ff81318038b432272f107b1fe Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 30 Jul 2009 12:58:06 +0200 Subject: Fix compilation on AIX: -I/usr/include cannot be used. The reason is that the C++ compiler needs to add -I/usr/vacpp/include before -I/usr/include, so our adding of -I/usr/include changes the order. This causes a compilation error in the C++ header xlocinfo.h. In any case, these checks done in qmake are unnecessary. If the OpenSSL headers are in one of those include paths, they will be found on their own already. Reviewed-By: Bradley T. Hughes (cherry picked from commit 04f7834fcd8db4ecb6a4c53de42ac83f571b37c8) --- config.tests/unix/openssl/openssl.pri | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/config.tests/unix/openssl/openssl.pri b/config.tests/unix/openssl/openssl.pri index bc95479..f069396 100644 --- a/config.tests/unix/openssl/openssl.pri +++ b/config.tests/unix/openssl/openssl.pri @@ -1,9 +1,3 @@ -!cross_compile { - TRY_INCLUDEPATHS = /include /usr/include /usr/local/include $$QMAKE_INCDIR $$INCLUDEPATH - # LSB doesn't allow using headers from /include or /usr/include - linux-lsb-g++:TRY_INCLUDEPATHS = $$QMAKE_INCDIR $$INCLUDEPATH - for(p, TRY_INCLUDEPATHS) { - pp = $$join(p, "", "", "/openssl") - exists($$pp):INCLUDEPATH *= $$p - } -} +# Empty file since Qt 4.6 +# I'm too lazy to find all places where this file is included + -- cgit v0.12 From b4f1f4de1a0df7028440faaff146ac1560dc6169 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 5 Aug 2009 13:17:39 +0200 Subject: MainWindow: fixed an update issue when moving a separator A non painted (ie. garbage) area could appear if you had a fixed size dock widget and you moved the separator. The previous place where the separator was painted was not updated --- src/gui/widgets/qmainwindowlayout.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index 3936a67..55afa70 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -1988,6 +1988,9 @@ void QMainWindowLayout::timerEvent(QTimerEvent *e) if (movingSeparatorOrigin == movingSeparatorPos) return; + //when moving the separator, we need to update the previous position + parentWidget()->update(layoutState.dockAreaLayout.separatorRegion()); + layoutState = savedState; layoutState.dockAreaLayout.separatorMove(movingSeparator, movingSeparatorOrigin, movingSeparatorPos); -- cgit v0.12 From 90480b9a25568858d1383e0aab6f5708a7dabd4f Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 5 Aug 2009 13:19:29 +0200 Subject: Fix a bug when activating HideNameFilterDetails on Windows filedialog. The HideNameFilterDetails was not taken in account for windows file dialog. This patch fix that. For Windows Vista and later we use now the new COMMON_ITEM_DIALOG API (in master) where it add always the filter extension like *.txt so no point to take that flag in account. Task-number: None, during testing Reviewed-by: prasanth --- src/gui/dialogs/qfiledialog.cpp | 2 +- src/gui/dialogs/qfiledialog_win.cpp | 28 ++++++++++++++++++---------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index c8ce162..6977731 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -219,7 +219,7 @@ Q_GUI_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook the native file dialog is used unless you use a subclass of QFileDialog that contains the Q_OBJECT macro. \value ReadOnly Indicates that the model is readonly. - \value HideNameFilterDetails Indicates if the is hidden or not. + \value HideNameFilterDetails Indicates if the filter extension (e.g. *.bmp) is hidden or not. This value is obsolete and does nothing since Qt 4.5: diff --git a/src/gui/dialogs/qfiledialog_win.cpp b/src/gui/dialogs/qfiledialog_win.cpp index 9a478aa..37a25e5 100644 --- a/src/gui/dialogs/qfiledialog_win.cpp +++ b/src/gui/dialogs/qfiledialog_win.cpp @@ -163,15 +163,22 @@ static QStringList qt_win_make_filters_list(const QString &filter) } // Makes a NUL-oriented Windows filter from a Qt filter. -static QString qt_win_filter(const QString &filter) +static QString qt_win_filter(const QString &filter, bool hideFiltersDetails) { QStringList filterLst = qt_win_make_filters_list(filter); QStringList::Iterator it = filterLst.begin(); QString winfilters; + QRegExp r(QString::fromLatin1(qt_file_dialog_filter_reg_exp)); for (; it != filterLst.end(); ++it) { QString subfilter = *it; if (!subfilter.isEmpty()) { - winfilters += subfilter; + if (hideFiltersDetails) { + int index = r.indexIn(subfilter); + if (index >= 0) + winfilters += r.cap(1); + } else { + winfilters += subfilter; + } winfilters += QChar(); winfilters += qt_win_extract_filter(subfilter); winfilters += QChar(); @@ -377,11 +384,12 @@ QString qt_win_get_open_file_name(const QFileDialogArgs &args, modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true); modal_widget.setParent(args.parent, Qt::Window); QApplicationPrivate::enterModal(&modal_widget); + bool hideFiltersDetails = args.options & QFileDialog::HideNameFilterDetails; QT_WA({ // Use Unicode strings and API OPENFILENAME* ofn = qt_win_make_OFN(args.parent, args.selection, args.directory, args.caption, - qt_win_filter(args.filter), + qt_win_filter(args.filter, hideFiltersDetails), QFileDialog::ExistingFile, args.options); if (idx) @@ -395,7 +403,7 @@ QString qt_win_get_open_file_name(const QFileDialogArgs &args, // Use ANSI strings and API OPENFILENAMEA* ofn = qt_win_make_OFNA(args.parent, args.selection, args.directory, args.caption, - qt_win_filter(args.filter), + qt_win_filter(args.filter, hideFiltersDetails), QFileDialog::ExistingFile, args.options); if (idx) @@ -452,7 +460,7 @@ QString qt_win_get_save_file_name(const QFileDialogArgs &args, modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true); modal_widget.setParent(args.parent, Qt::Window); QApplicationPrivate::enterModal(&modal_widget); - + bool hideFiltersDetails = args.options & QFileDialog::HideNameFilterDetails; // This block is used below for the lpstrDefExt member. // Note that the current MSDN docs document this member wrong. // It should rather be documented as "the default extension if no extension was given and if the @@ -469,12 +477,11 @@ QString qt_win_get_save_file_name(const QFileDialogArgs &args, defaultSaveExt.clear(); } } - QT_WA({ // Use Unicode strings and API OPENFILENAME *ofn = qt_win_make_OFN(args.parent, args.selection, args.directory, args.caption, - qt_win_filter(args.filter), + qt_win_filter(args.filter, hideFiltersDetails), QFileDialog::AnyFile, args.options); @@ -491,7 +498,7 @@ QString qt_win_get_save_file_name(const QFileDialogArgs &args, // Use ANSI strings and API OPENFILENAMEA *ofn = qt_win_make_OFNA(args.parent, args.selection, args.directory, args.caption, - qt_win_filter(args.filter), + qt_win_filter(args.filter, hideFiltersDetails), QFileDialog::AnyFile, args.options); QByteArray asciiExt = defaultSaveExt.toAscii(); @@ -558,10 +565,11 @@ QStringList qt_win_get_open_file_names(const QFileDialogArgs &args, modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true); modal_widget.setParent(args.parent, Qt::Window); QApplicationPrivate::enterModal(&modal_widget); + bool hideFiltersDetails = args.options & QFileDialog::HideNameFilterDetails; QT_WA({ OPENFILENAME* ofn = qt_win_make_OFN(args.parent, args.selection, args.directory, args.caption, - qt_win_filter(args.filter), + qt_win_filter(args.filter, hideFiltersDetails), QFileDialog::ExistingFiles, args.options); if (idx) @@ -594,7 +602,7 @@ QStringList qt_win_get_open_file_names(const QFileDialogArgs &args, } , { OPENFILENAMEA* ofn = qt_win_make_OFNA(args.parent, args.selection, args.directory, args.caption, - qt_win_filter(args.filter), + qt_win_filter(args.filter, hideFiltersDetails), QFileDialog::ExistingFiles, args.options); if (idx) -- cgit v0.12 From ca2a9d87d81095f6ff7b821e3d8cbe120a6d9b23 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 5 Aug 2009 13:13:33 +0200 Subject: Fix regressions introduced by 31edb4d5a63b9b3c28cce1c4ca6eb99f62a09759 The commit 31edb4d5a63b9b3c28cce1c4ca6eb99f62a09759 introduced regressions in filters which breaks the mac native dialog, the non native dialog with HideNameFilterDetails activated. Task-number:259105 Reviewed-by:olivier Reviewed-by:prasanth --- src/gui/dialogs/qfiledialog.cpp | 14 ++++++---- src/gui/dialogs/qfiledialog_win.cpp | 2 ++ tests/auto/qfiledialog/tst_qfiledialog.cpp | 43 ++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index 1ec94b6..f000033 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -394,6 +394,9 @@ QList QFileDialog::sidebarUrls() const static const qint32 QFileDialogMagic = 0xbe; +const char *qt_file_dialog_filter_reg_exp = +"^(.*)\\(([a-zA-Z0-9_.*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$"; + /*! \since 4.3 Saves the state of the dialog's layout, history and current directory. @@ -984,8 +987,13 @@ void QFileDialog::setNameFilters(const QStringList &filters) if (testOption(HideNameFilterDetails)) { QStringList strippedFilters; + QRegExp r(QString::fromLatin1(qt_file_dialog_filter_reg_exp)); for (int i = 0; i < cleanedFilters.count(); ++i) { - strippedFilters.append(cleanedFilters[i].mid(0, cleanedFilters[i].indexOf(QLatin1String(" (")))); + QString filterName; + int index = r.indexIn(cleanedFilters[i]); + if (index >= 0) + filterName = r.cap(1); + strippedFilters.append(filterName.simplified()); } d->qFileDialogUi->fileTypeCombo->addItems(strippedFilters); } else { @@ -2837,10 +2845,6 @@ void QFileDialogPrivate::_q_goToDirectory(const QString &path) } } -const char *qt_file_dialog_filter_reg_exp = -"(\\W|[a-zA-Z0-9 -]*)\\(([a-zA-Z0-9_.*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$"; - - // Makes a list of filters from a normal filter string "Image Files (*.png *.jpg)" QStringList qt_clean_filter_list(const QString &filter) { diff --git a/src/gui/dialogs/qfiledialog_win.cpp b/src/gui/dialogs/qfiledialog_win.cpp index c542ff0..02469b2 100644 --- a/src/gui/dialogs/qfiledialog_win.cpp +++ b/src/gui/dialogs/qfiledialog_win.cpp @@ -443,6 +443,8 @@ static bool qt_win_set_IFileDialogOptions(IFileDialog *pfd, QString subfilter = *it; if (!subfilter.isEmpty()) { offsets< + diff --git a/doc/src/examples.qdoc b/doc/src/examples.qdoc index 74a9bd8..7f9264b 100644 --- a/doc/src/examples.qdoc +++ b/doc/src/examples.qdoc @@ -330,6 +330,7 @@ \o \l{statemachine/eventtransitions}{Event Transitions}\raisedaster \o \l{statemachine/factorial}{Factorial States}\raisedaster \o \l{statemachine/pingpong}{Ping Pong States}\raisedaster + \o \l{statemachine/rogue}{Rogue}\raisedaster \o \l{statemachine/trafficlight}{Traffic Light}\raisedaster \o \l{statemachine/twowaybutton}{Two-way Button}\raisedaster \endlist diff --git a/doc/src/examples/rogue.qdoc b/doc/src/examples/rogue.qdoc new file mode 100644 index 0000000..8fa2c69 --- /dev/null +++ b/doc/src/examples/rogue.qdoc @@ -0,0 +1,222 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example statemachine/rogue + \title Rogue Example + + The Rogue example shows how to use the Qt state machine for event + handling. + + \image rogue-example.png + + This example implements a simple text based game. Do you see the + \c{@} in the screenshot? That's you, the rogue. The \c{#} + characters are walls, and the dots represent floor. In a real + game, other ASCII characters would represent all kinds of objects + and creatures. For instance, ancient dragons (\c{D}'s) or food + rations (\c{%}'s). But let's not get carried away. In this game, + the rogue is simply running around in an empty room. + + The rogue is moved with the keypad (2, 4, 8, 6). That aside, we + have implemented a \c quit command that triggers if the player + types \c {q}. The player is then asked if he/she really wants to + quit. + + Most games have commands that need more than one key press and + that may require a different sequence of keys based on questions + asked the user. In this game, only the \c quit command falls under + this category, but for the sake of argument, let's imagine a + fully-fledged game with a rich set of commands. If we were to + implement these by catching key events in + \l{QWidget::}{keyPressEvent()}, we would have to keep a lot of + class member variables to track the sequence of keys already typed + (or find some other way of deducing the current state of a + command). This can easily lead to spaghetti, which is--as we all + well know, I'm sure--unpleasant. With a state machine, on the + other hand, separate states can wait for a single key press, and + that makes our lives a lot simpler. + + The example consists of two classes: + + \list + \o \c Window draws the text display of the game and sets + up the state machine. The window also has a status bar + above the area in which the rouge moves. + \o \c MovementTransition is a transition that carries out + a single move of the rogue. + \endlist + + Before we embark on a code walkthrough, it is necessary to take a + closer look at the design of the machine. Here is a state chart + that shows what we want to achieve: + + \image rogue-statechart.png + + The input state waits for a key press to start a new command. + When receiving a key it recognizes, it transitions to one of the + two commands of the game; though, as we will see, movement is + handled by the transition itself. The quit state waits for the + player to answer yes or no (by typing \c y or \c n) when asked + whether he/she really wants to quit the game. + + The chart demonstrates how we use one state to wait for a single + key press. The press received may trigger one of the transitions + connected to the state. + + \section1 Window Class Definition + + The \c Window class is a widget that draws the text display of the + game. It also sets up the state machine, i.e., creates and + connects the states in the machine. It is the key events from this + widget that are used by the machine. + + \snippet examples/statemachine/rogue/window.h 0 + + \c Direction specifies the direction in which the rogue is to + move. We use this in \c movePlayer(), which moves the rogue and + repaints the window. The game has a status line above the area in + which the rogue moves. The \c status property contains the text of + this line. We use a property because the QState class allows + setting any Qt \l{Qt's Property System}{property} when entered. + More on this later. + + \snippet examples/statemachine/rogue/window.h 1 + + The \c map is an array with the characters that are currently + displayed. We set up the array in \c setupMap(), and update it + when the rogue is moved. \c pX and \c pY is the current position + of the rogue. \c WIDTH and \c HEIGHT are macros specifying the + dimensions of the map. + + The \c paintEvent() function is left out of this walkthrough. We + also do not discuss other code that does not concern the state + machine (the \c setupMap(), \c status(), \c setStatus(), \c + movePlayer(), and \c sizeHint() functions). If you wish to take a + look at the code, click on the link for the \c window.cpp file at + the top of this page. + + \section1 Window Class Implementation + + Here is the constructor of \c Window: + + \snippet examples/statemachine/rogue/window.cpp 0 + \dots + \snippet examples/statemachine/rogue/window.cpp 1 + + The player starts off at position (5, 5). We then set up the map + and statemachine. Let's proceed with the \c buildMachine() + function: + + \snippet examples/statemachine/rogue/window.cpp 2 + + We enter \c inputState when the machine is started and from the \c + quitState if the user wants to continue playing. We then set the + status to a helpful reminder of how to play the game. + + First, the \c Movement transition is added to the input state. + This will enable the rogue to be moved with the keypad. Notice + that we don't set a target state for the movement transition. This + will cause the transition to be triggered (and the + \l{QAbstractTransition::}{onTransition()} function to be invoked), + but the machine will not leave the \c inputState. If we had set \c + inputState as the target state, we would first have left and then + entered the \c inputState again. + + \snippet examples/statemachine/rogue/window.cpp 3 + + When we enter \c quitState, we update the status bar of the + window. + + \c QKeyEventTransition is a utility class that removes the hassle + of implementing transitions for \l{QKeyEvent}s. We simply need to + specify the key on which the transition should trigger and the + target state of the transition. + + \snippet examples/statemachine/rogue/window.cpp 4 + + The transition from \c inputState allows triggering the quit state + when the player types \c {q}. + + \snippet examples/statemachine/rogue/window.cpp 5 + + The machine is set up, so it's time to start it. + + \section1 The MovementTransition Class + + \c MovementTransition is triggered when the player request the + rogue to be moved (by typing 2, 4, 6, or 8) when the machine is in + the \c inputState. + + \snippet examples/statemachine/rogue/movementtransition.h 0 + + In the constructor, we tell QEventTransition to only send + \l{QEvent::}{KeyPress} events to the + \l{QAbstractTransition::}{eventTest()} function: + + \snippet examples/statemachine/rogue/movementtransition.h 1 + + The KeyPress events come wrapped in \l{QWrappedEvent}s. \c event + must be confirmed to be a wrapped event because Qt uses other + events internally. After that, it is simply a matter of checking + which key has been pressed. + + Let's move on to the \c onTransition() function: + + \snippet examples/statemachine/rogue/movementtransition.h 2 + + When \c onTransition() is invoked, we know that we have a + \l{QEvent::}{KeyPress} event with 2, 4, 6, or 8, i.e., the event + is already unwrapped. + + \section1 The Roguelike Tradition + + You might have been wondering why the game features a rogue. Well, + these kinds of text based dungeon exploration games date back to a + game called, yes, "Rogue". Although outflanked by the technology + of modern 3D computer games, roguelikes have a solid community of + hard-core, devoted followers. + + Playing these games can be surprisingly addictive (despite the + lack of graphics). Angband, the perhaps most well-known rougelike, + is found here: \l{http://rephial.org/}. +*/ + diff --git a/doc/src/images/rogue-example.png b/doc/src/images/rogue-example.png new file mode 100644 index 0000000..7aeb0e5 Binary files /dev/null and b/doc/src/images/rogue-example.png differ diff --git a/doc/src/images/rogue-statechart.png b/doc/src/images/rogue-statechart.png new file mode 100644 index 0000000..c5f4048 Binary files /dev/null and b/doc/src/images/rogue-statechart.png differ diff --git a/examples/statemachine/rogue/main.cpp b/examples/statemachine/rogue/main.cpp new file mode 100644 index 0000000..0c2fb2d --- /dev/null +++ b/examples/statemachine/rogue/main.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "window.h" + +int main(int argv, char **args) +{ + QApplication app(argv, args); + + Window window; + window.show(); + + return app.exec(); +} + diff --git a/examples/statemachine/rogue/movementtransition.h b/examples/statemachine/rogue/movementtransition.h new file mode 100644 index 0000000..929077d --- /dev/null +++ b/examples/statemachine/rogue/movementtransition.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MOVEMENTTRANSITION_H +#define MOVEMENTTRANSITION_H + +#include + +#include "window.h" + +//![0] +class MovementTransition : public QEventTransition +{ + Q_OBJECT + +public: + MovementTransition(Window *window) : + QEventTransition(window, QEvent::KeyPress) { + this->window = window; + } +//![0] + +//![1] +protected: + bool eventTest(QEvent *event) { + if (event->type() == QEvent::Wrapped && + static_cast(event)->event()->type() == QEvent::KeyPress) { + QEvent *wrappedEvent = static_cast(event)->event(); + + QKeyEvent *keyEvent = static_cast(wrappedEvent); + int key = keyEvent->key(); + + return key == Qt::Key_2 || key == Qt::Key_8 || key == Qt::Key_6 || + key == Qt::Key_4; + } + return false; + } +//![1] + +//![2] + void onTransition(QEvent *event) { + QKeyEvent *keyEvent = static_cast( + static_cast(event)->event()); + + int key = keyEvent->key(); + switch (key) { + case Qt::Key_4: + window->movePlayer(Window::Left); + break; + case Qt::Key_8: + window->movePlayer(Window::Up); + break; + case Qt::Key_6: + window->movePlayer(Window::Right); + break; + case Qt::Key_2: + window->movePlayer(Window::Down); + break; + default: + ; + } + } +//![2] + +private: + Window *window; +}; + +#endif + diff --git a/examples/statemachine/rogue/rogue.pro b/examples/statemachine/rogue/rogue.pro new file mode 100644 index 0000000..1571854 --- /dev/null +++ b/examples/statemachine/rogue/rogue.pro @@ -0,0 +1,11 @@ +HEADERS = window.h \ + movementtransition.h +SOURCES = main.cpp \ + window.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/rogue +sources.files = $$SOURCES $$HEADERS *.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/rogue +INSTALLS += target sources + diff --git a/examples/statemachine/rogue/window.cpp b/examples/statemachine/rogue/window.cpp new file mode 100644 index 0000000..39565a3 --- /dev/null +++ b/examples/statemachine/rogue/window.cpp @@ -0,0 +1,201 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "window.h" +#include "movementtransition.h" + +//![0] +Window::Window() +{ + pX = 5; + pY = 5; +//![0] + + QFontDatabase database; + QFont font; + if (database.families().contains("Monospace")) + font = QFont("Monospace", 12); + else { + foreach (QString family, database.families()) { + if (database.isFixedPitch(family)) { + font = QFont(family, 12); + break; + } + } + } + setFont(font); + +//![1] + setupMap(); + buildMachine(); +} +//![1] + +void Window::setStatus(const QString &status) +{ + myStatus = status; + repaint(); +} + +QString Window::status() const +{ + return myStatus; +} + +void Window::paintEvent(QPaintEvent * /* event */) +{ + QFontMetrics metrics(font()); + QPainter painter(this); + int fontHeight = metrics.height(); + int fontWidth = metrics.width('X'); + int yPos = fontHeight; + int xPos; + + painter.fillRect(rect(), Qt::black); + painter.setPen(Qt::white); + + painter.drawText(QPoint(0, yPos), status()); + + for (int y = 0; y < HEIGHT; ++y) { + yPos += fontHeight; + xPos = 0; + + for (int x = 0; x < WIDTH; ++x) { + if (y == pY && x == pX) { + xPos += fontWidth; + continue; + } + + painter.drawText(QPoint(xPos, yPos), map[x][y]); + xPos += fontWidth; + } + } + painter.drawText(QPoint(pX * fontWidth, (pY + 2) * fontHeight), QChar('@')); +} + +QSize Window::sizeHint() const +{ + QFontMetrics metrics(font()); + + return QSize(metrics.width('X') * WIDTH, metrics.height() * (HEIGHT + 1)); +} + +//![2] +void Window::buildMachine() +{ + machine = new QStateMachine; + + QState *inputState = new QState(machine); + inputState->assignProperty(this, "status", "Move the rogue with 2, 4, 6, and 8"); + + MovementTransition *transition = new MovementTransition(this); + inputState->addTransition(transition); +//![2] + +//![3] + QState *quitState = new QState(machine); + quitState->assignProperty(this, "status", "Really quit(y/n)?"); + + QKeyEventTransition *yesTransition = new + QKeyEventTransition(this, QEvent::KeyPress, Qt::Key_Y); + yesTransition->setTargetState(new QFinalState(machine)); + quitState->addTransition(yesTransition); + + QKeyEventTransition *noTransition = + new QKeyEventTransition(this, QEvent::KeyPress, Qt::Key_N); + noTransition->setTargetState(inputState); + quitState->addTransition(noTransition); +//![3] + +//![4] + QKeyEventTransition *quitTransition = + new QKeyEventTransition(this, QEvent::KeyPress, Qt::Key_Q); + quitTransition->setTargetState(quitState); + inputState->addTransition(quitTransition); +//![4] + +//![5] + machine->setInitialState(inputState); + + connect(machine, SIGNAL(finished()), qApp, SLOT(quit())); + + machine->start(); +} +//![5] + +void Window::movePlayer(Direction direction) +{ + switch (direction) { + case Left: + if (map[pX - 1][pY] != '#') + --pX; + break; + case Right: + if (map[pX + 1][pY] != '#') + ++pX; + break; + case Up: + if (map[pX][pY - 1] != '#') + --pY; + break; + case Down: + if (map[pX][pY + 1] != '#') + ++pY; + break; + } + repaint(); +} + +void Window::setupMap() +{ + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + + for (int x = 0; x < WIDTH; ++x) + for (int y = 0; y < HEIGHT; ++y) { + if (x == 0 || x == WIDTH - 1 || y == 0 || y == HEIGHT - 1 || qrand() % 40 == 0) + map[x][y] = '#'; + else + map[x][y] = '.'; + } +} + diff --git a/examples/statemachine/rogue/window.h b/examples/statemachine/rogue/window.h new file mode 100644 index 0000000..bcd86bd --- /dev/null +++ b/examples/statemachine/rogue/window.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class QState; +class QStateMachine; +class QTransition; + +#define WIDTH 35 +#define HEIGHT 20 + +//![0] +class Window : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QString status READ status WRITE setStatus) + +public: + enum Direction { Up, Down, Left, Right }; + + Window(); + + void movePlayer(Direction direction); + void setStatus(const QString &status); + QString status() const; + + QSize sizeHint() const; + +protected: + void paintEvent(QPaintEvent *event); +//![0] + +//![1] +private: + void buildMachine(); + void setupMap(); + + QChar map[WIDTH][HEIGHT]; + int pX, pY; + + QStateMachine *machine; + QString myStatus; +}; +//![1] + +#endif + diff --git a/examples/statemachine/statemachine.pro b/examples/statemachine/statemachine.pro index ea3e7a8..298c0ae 100644 --- a/examples/statemachine/statemachine.pro +++ b/examples/statemachine/statemachine.pro @@ -3,6 +3,7 @@ SUBDIRS = \ eventtransitions \ factorial \ pingpong \ + rogue \ trafficlight \ twowaybutton -- cgit v0.12 From 41d27eac40cecbc0067be9622c9bc1c579582a47 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 7 Aug 2009 13:17:05 +0200 Subject: Autotest: ensure we don't mishandle SSL certificates with NULs This is a vulnerability in some implementations. Qt isn't affected because... well, we never implemented the decoding of escape sequences :-) --- .../more-certificates/badguy-nul-cn.crt | 81 ++++++++++++++++++++++ tests/auto/qsslcertificate/tst_qsslcertificate.cpp | 17 +++++ 2 files changed, 98 insertions(+) create mode 100644 tests/auto/qsslcertificate/more-certificates/badguy-nul-cn.crt diff --git a/tests/auto/qsslcertificate/more-certificates/badguy-nul-cn.crt b/tests/auto/qsslcertificate/more-certificates/badguy-nul-cn.crt new file mode 100644 index 0000000..b899733 --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/badguy-nul-cn.crt @@ -0,0 +1,81 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=GB, ST=Berkshire, L=Newbury, O=My Company Ltd, OU=CA, CN=NULL-friendly CA + Validity + Not Before: Aug 4 07:33:43 2009 GMT + Not After : Aug 2 07:33:43 2019 GMT + Subject: CN=www.bank.com\x00.badguy.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:cd:26:70:96:a9:a6:5d:3e:9c:ed:0f:08:15:5a: + 7c:17:25:68:68:af:13:b9:ad:41:fa:12:54:e2:84: + 72:7d:58:d1:e2:40:42:c1:59:ed:05:3d:aa:10:53: + 70:00:88:3a:77:a0:c0:56:9e:ac:7d:21:2a:71:44: + 51:08:bc:17:07:da:a8:a3:76:dc:51:bc:1b:8a:f6: + 02:1a:55:bf:46:b4:44:6b:27:5e:be:e5:17:8b:56: + b2:c6:82:36:11:83:a8:bf:f7:2f:0d:17:f6:cd:47: + b5:6f:2b:a6:41:b6:8d:33:5f:ea:ea:8b:b1:1a:e2: + 99:38:ff:59:5b:0a:a1:71:13:ca:37:3f:b9:b0:1e: + 91:9a:c8:93:35:0c:4a:e0:9d:f4:d2:61:c7:4e:5b: + 41:0a:7c:31:54:99:db:f5:65:ce:80:d3:c2:02:37: + 64:fd:54:12:7b:ea:ac:85:59:5c:17:e1:2e:f6:d0: + a8:f2:d0:2e:94:59:2f:c2:a6:5f:da:07:de:7b:2e: + 14:07:ed:e4:27:24:37:9d:09:2e:b1:f9:5a:48:b9: + 80:24:43:e6:cb:c7:6e:35:df:d5:69:34:ff:e6:d6: + 9e:e8:76:66:6e:5f:59:01:3c:96:3b:ec:72:0b:3c: + 1e:95:0f:ce:68:13:9c:22:dd:1b:b5:44:28:50:4a: + 05:7f + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 33:15:24:BE:DA:66:3A:06:8B:D9:27:34:3A:AF:62:40:E4:95:66:5D + X509v3 Authority Key Identifier: + keyid:0A:69:39:5F:9D:30:04:18:08:2E:02:0E:E6:EA:9D:B2:26:F6:E2:6A + + Signature Algorithm: sha1WithRSAEncryption + 32:65:23:1f:c8:d9:53:84:82:d0:0a:eb:14:51:24:03:bc:6c: + 1b:2a:5a:fe:1b:f0:e8:69:0c:2b:19:86:cf:7f:32:76:d8:2b: + d2:cf:8b:c4:d1:b6:5b:9c:60:a3:99:2e:92:72:06:ce:de:8b: + d2:a2:d2:89:7c:13:a9:0b:4e:be:12:09:e5:d6:28:3a:ac:a7: + 26:56:94:7f:13:ee:64:7d:de:94:60:75:c1:bc:55:97:d4:aa: + 13:8e:02:d8:b0:b0:70:53:ae:18:53:ce:aa:b2:2c:85:3e:e3: + f3:e1:26:f3:fa:5c:ee:f8:7b:0b:c6:39:b5:04:33:5e:ae:b8: + 5e:0e:66:cc:a8:c0:6a:0d:ec:60:c1:c5:d9:39:ea:bd:1b:8f: + 1c:7d:16:38:b1:e8:c8:37:01:aa:4b:99:df:e4:0f:10:be:61: + ee:9a:cf:cd:27:05:46:00:60:d8:6a:74:08:32:3c:8b:90:01: + 6a:07:33:0c:6c:90:db:ea:fb:6a:17:1a:76:bb:73:14:27:e1: + a4:7e:d5:dd:30:b1:5d:f2:0e:aa:d4:b2:d5:4c:f6:4f:91:2a: + 07:f4:37:c1:cf:48:19:c5:fe:7e:92:96:a8:df:50:6a:31:92: + a3:b1:14:fe:41:cc:49:62:98:4d:ea:c5:ba:05:2d:49:c3:22: + 72:ef:41:09 +-----BEGIN CERTIFICATE----- +MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQUFADB0MQswCQYDVQQGEwJHQjES +MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N +eSBDb21wYW55IEx0ZDELMAkGA1UECxMCQ0ExGTAXBgNVBAMTEE5VTEwtZnJpZW5k +bHkgQ0EwHhcNMDkwODA0MDczMzQzWhcNMTkwODAyMDczMzQzWjAjMSEwHwYDVQQD +Exh3d3cuYmFuay5jb20ALmJhZGd1eS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDNJnCWqaZdPpztDwgVWnwXJWhorxO5rUH6ElTihHJ9WNHiQELB +We0FPaoQU3AAiDp3oMBWnqx9ISpxRFEIvBcH2qijdtxRvBuK9gIaVb9GtERrJ16+ +5ReLVrLGgjYRg6i/9y8NF/bNR7VvK6ZBto0zX+rqi7Ea4pk4/1lbCqFxE8o3P7mw +HpGayJM1DErgnfTSYcdOW0EKfDFUmdv1Zc6A08ICN2T9VBJ76qyFWVwX4S720Kjy +0C6UWS/Cpl/aB957LhQH7eQnJDedCS6x+VpIuYAkQ+bLx24139VpNP/m1p7odmZu +X1kBPJY77HILPB6VD85oE5wi3Ru1RChQSgV/AgMBAAGjezB5MAkGA1UdEwQCMAAw +LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G +A1UdDgQWBBQzFSS+2mY6BovZJzQ6r2JA5JVmXTAfBgNVHSMEGDAWgBQKaTlfnTAE +GAguAg7m6p2yJvbiajANBgkqhkiG9w0BAQUFAAOCAQEAMmUjH8jZU4SC0ArrFFEk +A7xsGypa/hvw6GkMKxmGz38ydtgr0s+LxNG2W5xgo5kuknIGzt6L0qLSiXwTqQtO +vhIJ5dYoOqynJlaUfxPuZH3elGB1wbxVl9SqE44C2LCwcFOuGFPOqrIshT7j8+Em +8/pc7vh7C8Y5tQQzXq64Xg5mzKjAag3sYMHF2TnqvRuPHH0WOLHoyDcBqkuZ3+QP +EL5h7prPzScFRgBg2Gp0CDI8i5ABagczDGyQ2+r7ahcadrtzFCfhpH7V3TCxXfIO +qtSy1Uz2T5EqB/Q3wc9IGcX+fpKWqN9QajGSo7EU/kHMSWKYTerFugUtScMicu9B +CQ== +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp index 7fd92d6..80ac228 100644 --- a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp +++ b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp @@ -100,6 +100,7 @@ private slots: void fromPath(); void certInfo(); void task256066toPem(); + void nulInCN(); // ### add tests for certificate bundles (multiple certificates concatenated into a single // structure); both PEM and DER formatted #endif @@ -727,6 +728,22 @@ void tst_QSslCertificate::task256066toPem() QCOMPARE(pem1, pem2); } +void tst_QSslCertificate::nulInCN() +{ + QList certList = + QSslCertificate::fromPath(SRCDIR "more-certificates/badguy-nul-cn.crt"); + QCOMPARE(certList.size(), 1); + + const QSslCertificate &cert = certList.at(0); + QVERIFY(!cert.isNull()); + + QString cn = cert.subjectInfo(QSslCertificate::CommonName); + QVERIFY(cn != "www.bank.com"); + + static const char realCN[] = "www.bank.com\\x00.badguy.com"; + QCOMPARE(cn, QString::fromLatin1(realCN, sizeof realCN - 1)); +} + #endif // QT_NO_OPENSSL QTEST_MAIN(tst_QSslCertificate) -- cgit v0.12 From 79c488a28819b58eed519fb3df2705b8c6e35e05 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 15 Jul 2009 17:22:11 +0200 Subject: Add functionality tests for XSync. It was reported to be auto-detected, but wasn't. Apparently, AIX 6's X11 doesn't have this. Reviewed-By: Denis Dzyubenko (cherry picked from commit 0a63875d787e1b035ace2c76fa1d0de6329127d7) --- config.tests/x11/xsync/xsync.cpp | 11 +++++++++++ config.tests/x11/xsync/xsync.pro | 3 +++ configure | 36 +++++++++++++++++++++++++++++++++++- 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 config.tests/x11/xsync/xsync.cpp create mode 100644 config.tests/x11/xsync/xsync.pro diff --git a/config.tests/x11/xsync/xsync.cpp b/config.tests/x11/xsync/xsync.cpp new file mode 100644 index 0000000..a23fb08 --- /dev/null +++ b/config.tests/x11/xsync/xsync.cpp @@ -0,0 +1,11 @@ +#include +#include +#include + +int main(int, char **) +{ + XSyncValue value; + (void*)&XSyncIntToValue; + (void*)&XSyncCreateCounter; + return 0; +} diff --git a/config.tests/x11/xsync/xsync.pro b/config.tests/x11/xsync/xsync.pro new file mode 100644 index 0000000..58b8238 --- /dev/null +++ b/config.tests/x11/xsync/xsync.pro @@ -0,0 +1,3 @@ +CONFIG += x11 +CONFIG -= qt +SOURCES = xsync.cpp diff --git a/configure b/configure index 2b81cab..b5baadb 100755 --- a/configure +++ b/configure @@ -570,6 +570,7 @@ CFG_DEBUG_RELEASE=no CFG_SHARED=yes CFG_SM=auto CFG_XSHAPE=auto +CFG_XSYNC=auto CFG_XINERAMA=runtime CFG_XFIXES=runtime CFG_ZLIB=auto @@ -831,7 +832,7 @@ while [ "$#" -gt 0 ]; do VAL=no ;; #Qt style yes options - -incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xinput|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-universal|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-svg|-webkit|-scripttools|-rpath|-force-pkg-config) + -incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xshape|-xinput|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-universal|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-svg|-webkit|-scripttools|-rpath|-force-pkg-config) VAR=`echo $1 | sed "s,^-\(.*\),\1,"` VAL=yes ;; @@ -1419,6 +1420,13 @@ while [ "$#" -gt 0 ]; do UNKNOWN_OPT=yes fi ;; + xsync) + if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then + CFG_XSYNC="$VAL" + else + UNKNOWN_OPT=yes + fi + ;; xinput) if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ] || [ "$VAL" = "runtime" ]; then CFG_XINPUT="$VAL" @@ -3480,6 +3488,10 @@ Qt/X11 only: $SHY -xshape ............ Compile XShape support. Requires X11/extensions/shape.h. + $SHN -no-xsync .......... Do not compile XSync support. + $SHY -xsync ............. Compile XSync support. + Requires X11/extensions/sync.h. + $XAN -no-xinerama ....... Do not compile Xinerama (multihead) support. $XAY -xinerama .......... Compile Xinerama support. Requires X11/extensions/Xinerama.h and libXinerama. @@ -4993,6 +5005,23 @@ if [ "$PLATFORM_X11" = "yes" ]; then fi fi + # auto-detect XSync support + if [ "$CFG_XSYNC" != "no" ]; then + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xsync "XSync" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then + CFG_XSYNC=yes + else + if [ "$CFG_XSYNC" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then + echo "XSync support cannot be enabled due to functionality tests!" + echo " Turn on verbose messaging (-v) to $0 to see the final report." + echo " If you believe this message is in error you may use the continue" + echo " switch (-continue) to $0 to continue." + exit 101 + else + CFG_XSYNC=no + fi + fi + fi + # auto-detect Xinerama support if [ "$CFG_XINERAMA" != "no" ]; then if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xinerama "Xinerama" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then @@ -5791,6 +5820,9 @@ if [ "$PLATFORM_X11" = "yes" ]; then if [ "$CFG_XSHAPE" = "yes" ]; then QT_CONFIG="$QT_CONFIG xshape" fi + if [ "$CFG_XSYNC" = "yes" ]; then + QT_CONFIG="$QT_CONFIG xsync" + fi if [ "$CFG_XINERAMA" = "yes" ]; then QT_CONFIG="$QT_CONFIG xinerama" QMakeVar set QMAKE_LIBS_X11 '-lXinerama $$QMAKE_LIBS_X11' @@ -6503,6 +6535,7 @@ fi [ "$CFG_XRENDER" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_XRENDER" [ "$CFG_MITSHM" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_MITSHM" [ "$CFG_XSHAPE" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_SHAPE" +[ "$CFG_XSYNC" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_XSYNC" [ "$CFG_XINPUT" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_XINPUT QT_NO_TABLET" [ "$CFG_XCURSOR" = "runtime" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_RUNTIME_XCURSOR" @@ -6944,6 +6977,7 @@ fi if [ "$PLATFORM_X11" = "yes" ]; then echo "NAS sound support ... $CFG_NAS" echo "XShape support ...... $CFG_XSHAPE" + echo "XSync support ....... $CFG_XSYNC" echo "Xinerama support .... $CFG_XINERAMA" echo "Xcursor support ..... $CFG_XCURSOR" echo "Xfixes support ...... $CFG_XFIXES" -- cgit v0.12 From 923134936e132e857b663c4837f66565dfa3d9e6 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 16 Jul 2009 15:38:27 +0200 Subject: xlC 7 cannot compile QtConcurrent with these templates here (cherry picked from commit cb64ac587249f5dc6563a035e2ef5a3ad2bc5d13) --- src/corelib/concurrent/qfuture.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/concurrent/qfuture.h b/src/corelib/concurrent/qfuture.h index 47015ee..f2db5ac 100644 --- a/src/corelib/concurrent/qfuture.h +++ b/src/corelib/concurrent/qfuture.h @@ -210,7 +210,7 @@ public: bool operator==(const QFuture &other) const { return (d == other.d); } bool operator!=(const QFuture &other) const { return (d != other.d); } -#ifndef QT_NO_MEMBER_TEMPLATES +#if !defined(QT_NO_MEMBER_TEMPLATES) && !defined(Q_CC_XLC) template QFuture(const QFuture &other) : d(other.d) -- cgit v0.12 From 3eb12a43e3cf673ec0608833551b25f153af1aa3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 30 Jul 2009 16:40:06 +0200 Subject: Fix compilation with xlC 7: operands to ?: must match. "../shared/qm.cpp", line 556.45: 1540-0207 (S) No common type found for operands with type "const char [7]" and "QByteArray". Reviewed-by: Trust Me (cherry picked from commit 3ae2cab9c8bd1790a00da2755ac036143a3a35f4) --- tools/linguist/shared/qm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/linguist/shared/qm.cpp b/tools/linguist/shared/qm.cpp index 381f5c5..231ec84 100644 --- a/tools/linguist/shared/qm.cpp +++ b/tools/linguist/shared/qm.cpp @@ -546,7 +546,7 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) //qDebug() << "NUMITEMS: " << numItems; QTextCodec *codec = QTextCodec::codecForName( - cd.m_codecForSource.isEmpty() ? "Latin1" : cd.m_codecForSource); + cd.m_codecForSource.isEmpty() ? QByteArray("Latin1") : cd.m_codecForSource); QTextCodec *utf8Codec = 0; if (codec->name() != "UTF-8") utf8Codec = QTextCodec::codecForName("UTF-8"); -- cgit v0.12 From c39436c722e778460366995877d66a8935d2d636 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 31 Jul 2009 10:30:44 +0200 Subject: Fix compilation with xlC 7: operands to ?: must match. See 3ae2cab9c8bd1790a00da2755ac036143a3a35f4 for another similar fix. Reviewed-by: Trust Me (cherry picked from commit 18fbfdf0f774198e2e1277e064cc3a8eb9dbb29d) --- tools/linguist/shared/po.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/linguist/shared/po.cpp b/tools/linguist/shared/po.cpp index 4850cfd..575e751 100644 --- a/tools/linguist/shared/po.cpp +++ b/tools/linguist/shared/po.cpp @@ -359,7 +359,7 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) const QChar quote = QLatin1Char('"'); const QChar newline = QLatin1Char('\n'); QTextStream in(&dev); - in.setCodec(cd.m_codecForSource.isEmpty() ? "UTF-8" : cd.m_codecForSource); + in.setCodec(cd.m_codecForSource.isEmpty() ? QByteArray("UTF-8") : cd.m_codecForSource); bool error = false; // format of a .po file entry: @@ -552,7 +552,7 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd) { bool ok = true; QTextStream out(&dev); - out.setCodec(cd.m_outputCodec.isEmpty() ? "UTF-8" : cd.m_outputCodec); + out.setCodec(cd.m_outputCodec.isEmpty() ? QByteArray("UTF-8") : cd.m_outputCodec); bool first = true; if (translator.messages().isEmpty() || !translator.messages().first().sourceText().isEmpty()) { -- cgit v0.12 From 3c2b9047be4f4f835e59c13d5038b907c629451f Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 7 Aug 2009 14:01:11 +0200 Subject: adjust some ifdefs so they are easy to remove with a script In preparation of making the old QtScript back-end a separate package/solution. --- src/script/qscriptable.cpp | 4 ++-- src/script/qscriptable_p.h | 4 ++-- src/script/qscriptclassdata.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/script/qscriptable.cpp b/src/script/qscriptable.cpp index 5da9e95..94468de 100644 --- a/src/script/qscriptable.cpp +++ b/src/script/qscriptable.cpp @@ -39,10 +39,10 @@ ** ****************************************************************************/ -#ifndef QT_NO_QOBJECT - #include "qscriptable.h" +#ifndef QT_NO_QOBJECT + #ifndef QT_NO_SCRIPT #include "qscriptable_p.h" diff --git a/src/script/qscriptable_p.h b/src/script/qscriptable_p.h index 8ea65ed..1d297d9 100644 --- a/src/script/qscriptable_p.h +++ b/src/script/qscriptable_p.h @@ -55,7 +55,7 @@ // We mean it. // -#if !defined(QT_NO_QOBJECT) && !defined(QT_NO_SCRIPT) +#ifndef QT_NO_SCRIPT QT_BEGIN_NAMESPACE @@ -79,6 +79,6 @@ public: QT_END_NAMESPACE -#endif // QT_NO_QOBJECT && QT_NO_SCRIPT +#endif // QT_NO_SCRIPT #endif diff --git a/src/script/qscriptclassdata.cpp b/src/script/qscriptclassdata.cpp index 08e7220..576a519 100644 --- a/src/script/qscriptclassdata.cpp +++ b/src/script/qscriptclassdata.cpp @@ -114,4 +114,4 @@ QScriptClassDataIterator::~QScriptClassDataIterator() QT_END_NAMESPACE -#endif +#endif // QT_NO_SCRIPT -- cgit v0.12 From f37b4ab8c8116abc2f71128e308b938c90ec5b8a Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 7 Aug 2009 14:01:26 +0200 Subject: QDockWidget: Make visibilityChanged more accurate Task-number: 258459 --- src/gui/widgets/qdockarealayout.cpp | 2 +- src/gui/widgets/qdockwidget.cpp | 2 +- tests/auto/qdockwidget/tst_qdockwidget.cpp | 19 ++++++++++++++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index ee29b55..cad6903 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -1545,7 +1545,7 @@ void QDockAreaLayoutInfo::apply(bool animate) QRect geo = w->geometry(); widgetAnimator.animate(w, r, animate); - if (!w->isHidden()) { + if (!w->isHidden() && w->window()->isVisible()) { QDockWidget *dw = qobject_cast(w); if (!r.isValid() && geo.right() >= 0 && geo.bottom() >= 0) { dw->lower(); diff --git a/src/gui/widgets/qdockwidget.cpp b/src/gui/widgets/qdockwidget.cpp index 5810c81..e60f099 100644 --- a/src/gui/widgets/qdockwidget.cpp +++ b/src/gui/widgets/qdockwidget.cpp @@ -1390,7 +1390,7 @@ bool QDockWidget::event(QEvent *event) break; case QEvent::Show: d->toggleViewAction->setChecked(true); - emit visibilityChanged(true); + emit visibilityChanged(geometry().right() >= 0 && geometry().bottom() >= 0); break; #endif case QEvent::ApplicationLayoutDirectionChange: diff --git a/tests/auto/qdockwidget/tst_qdockwidget.cpp b/tests/auto/qdockwidget/tst_qdockwidget.cpp index 9b0e706..16bb12d 100644 --- a/tests/auto/qdockwidget/tst_qdockwidget.cpp +++ b/tests/auto/qdockwidget/tst_qdockwidget.cpp @@ -91,6 +91,7 @@ private slots: void task169808_setFloating(); void task237438_setFloatingCrash(); void task248604_infiniteResize(); + void task258459_visibilityChanged(); }; // Testing get/set functions @@ -730,7 +731,7 @@ void tst_QDockWidget::task169808_setFloating() return QSize(20,20); } - void paintEvent(QPaintEvent *e) + void paintEvent(QPaintEvent *) { QPainter p(this); p.fillRect(rect(), Qt::red); @@ -798,5 +799,21 @@ void tst_QDockWidget::task248604_infiniteResize() } +void tst_QDockWidget::task258459_visibilityChanged() +{ + QMainWindow win; + QDockWidget dock1, dock2; + win.addDockWidget(Qt::RightDockWidgetArea, &dock1); + win.tabifyDockWidget(&dock1, &dock2); + QSignalSpy spy1(&dock1, SIGNAL(visibilityChanged(bool))); + QSignalSpy spy2(&dock2, SIGNAL(visibilityChanged(bool))); + win.show(); + QTest::qWait(200); + QCOMPARE(spy1.count(), 1); + QCOMPARE(spy1.first().first().toBool(), false); //dock1 is invisible + QCOMPARE(spy2.count(), 1); + QCOMPARE(spy2.first().first().toBool(), true); //dock1 is visible +} + QTEST_MAIN(tst_QDockWidget) #include "tst_qdockwidget.moc" -- cgit v0.12 From f419f3f229444f31ca879276713799f6af73195e Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 12 May 2009 20:26:58 +0200 Subject: Refactor the code that reads the KDE config in one file Move the code out of qapplication_x11.cpp, and qcommonstyle.cpp to qkde.cpp into the QKde namespace. This removes few of the code duplication, and is much cleaner. This will also let us install hook easily later. Reviewed-by: Jens Bache-Wiig --- src/gui/kernel/kernel.pri | 6 +- src/gui/kernel/qapplication_p.h | 1 - src/gui/kernel/qapplication_x11.cpp | 202 ++++++------------------------------ src/gui/kernel/qkde.cpp | 159 ++++++++++++++++++++++++++++ src/gui/kernel/qkde_p.h | 76 ++++++++++++++ src/gui/kernel/qt_x11_p.h | 3 +- src/gui/styles/qcommonstyle.cpp | 39 ++++--- 7 files changed, 297 insertions(+), 189 deletions(-) create mode 100644 src/gui/kernel/qkde.cpp create mode 100644 src/gui/kernel/qkde_p.h diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index e6eff6e..d9deefe 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -100,7 +100,8 @@ unix:x11 { INCLUDEPATH += ../3rdparty/xorg HEADERS += \ kernel/qx11embed_x11.h \ - kernel/qx11info_x11.h + kernel/qx11info_x11.h \ + kernel/qkde_p.h SOURCES += \ kernel/qapplication_x11.cpp \ @@ -114,7 +115,8 @@ unix:x11 { kernel/qwidgetcreate_x11.cpp \ kernel/qx11embed_x11.cpp \ kernel/qx11info_x11.cpp \ - kernel/qkeymapper_x11.cpp + kernel/qkeymapper_x11.cpp \ + kernel/qkde.cpp contains(QT_CONFIG, glib) { SOURCES += \ diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 700d1ab..c4ce2ea 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -284,7 +284,6 @@ public: #if defined(Q_WS_X11) #ifndef QT_NO_SETTINGS - static QString kdeHome(); static QString x11_desktop_style(); static bool x11_apply_settings(); #endif diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 4016563..32e7e3c 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -83,6 +83,7 @@ #include "qtimer.h" #include "qlibrary.h" #include +#include "qkde_p.h" #if !defined (QT_NO_TABLET) extern "C" { @@ -813,33 +814,6 @@ Q_GUI_EXPORT void qt_x11_apply_settings_in_all_apps() PropModeReplace, (unsigned char *)stamp.data(), stamp.size()); } -static int kdeSessionVersion() -{ - static int kdeVersion = 0; - if (!kdeVersion) - kdeVersion = QString::fromLocal8Bit(qgetenv("KDE_SESSION_VERSION")).toInt(); - return kdeVersion; -} - -/*! \internal - Gets the current KDE 3 or 4 home path -*/ -QString QApplicationPrivate::kdeHome() -{ - static QString kdeHomePath; - if (kdeHomePath.isEmpty()) { - kdeHomePath = QString::fromLocal8Bit(qgetenv("KDEHOME")); - if (kdeHomePath.isEmpty()) { - QDir homeDir(QDir::homePath()); - QString kdeConfDir(QLatin1String("/.kde")); - if (4 == kdeSessionVersion() && homeDir.exists(QLatin1String(".kde4"))) - kdeConfDir = QLatin1String("/.kde4"); - kdeHomePath = QDir::homePath() + kdeConfDir; - } - } - return kdeHomePath; -} - /*! \internal apply the settings to the application */ @@ -905,8 +879,8 @@ bool QApplicationPrivate::x11_apply_settings() QFont font(QApplication::font()); QString fontDescription; // Override Qt font if KDE4 settings can be used - if (4 == kdeSessionVersion()) { - QSettings kdeSettings(kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat); + if (X11->desktopEnvironment == DE_KDE && X11->desktopVersion >= 4) { + QSettings kdeSettings(QKde::kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat); fontDescription = kdeSettings.value(QLatin1String("font")).toString(); if (fontDescription.isEmpty()) { // KDE stores fonts without quotes @@ -936,7 +910,6 @@ bool QApplicationPrivate::x11_apply_settings() // read new QStyle QString stylename = settings.value(QLatin1String("style")).toString(); - if (stylename.isEmpty() && QApplicationPrivate::styleOverride.isNull() && X11->use_xrender) { stylename = x11_desktop_style(); } @@ -1094,22 +1067,6 @@ static void qt_set_input_encoding() XFree((char *)data); } -// Reads a KDE color setting -static QColor kdeColor(const QString &key, const QSettings &kdeSettings) -{ - QVariant variant = kdeSettings.value(key); - if (variant.isValid()) { - QStringList values = variant.toStringList(); - if (values.size() == 3) { - int r = values[0].toInt(); - int g = values[1].toInt(); - int b = values[2].toInt(); - return QColor(r, g, b); - } - } - return QColor(); -} - // set font, foreground and background from x11 resources. The // arguments may override the resource settings. static void qt_set_x11_resources(const char* font = 0, const char* fg = 0, @@ -1276,9 +1233,10 @@ static void qt_set_x11_resources(const char* font = 0, const char* fg = 0, QApplicationPrivate::setSystemFont(fnt); } + // QGtkStyle sets it's own system palette + bool gtkStyle = QApplicationPrivate::app_style && QApplicationPrivate::app_style->inherits("QGtkStyle"); bool kdeColors = (QApplication::desktopSettingsAware() && X11->desktopEnvironment == DE_KDE); - - if (kdeColors || (button || !resBG.isEmpty() || !resFG.isEmpty())) {// set app colors + if (!gtkStyle && (kdeColors || (button || !resBG.isEmpty() || !resFG.isEmpty()))) {// set app colors bool allowX11ColorNames = QColor::allowX11ColorNames(); QColor::setAllowX11ColorNames(true); @@ -1314,45 +1272,6 @@ static void qt_set_x11_resources(const char* font = 0, const char* fg = 0, bright_mode = true; } - if (kdeColors) { - const QSettings theKdeSettings( - QApplicationPrivate::kdeHome() - + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat); - - // Setup KDE palette - QColor color; - color = kdeColor(QLatin1String("buttonBackground"), theKdeSettings); - if (!color.isValid()) - color = kdeColor(QLatin1String("Colors:Button/BackgroundNormal"), theKdeSettings); - if (color.isValid()) - btn = color; - - color = kdeColor(QLatin1String("background"), theKdeSettings); - if (!color.isValid()) - color = kdeColor(QLatin1String("Colors:Window/BackgroundNormal"), theKdeSettings); - if (color.isValid()) - bg = color; - - color = kdeColor(QLatin1String("foreground"), theKdeSettings); - if (!color.isValid()) - color = kdeColor(QLatin1String("Colors:View/ForegroundNormal"), theKdeSettings); - if (color.isValid()) { - fg = color; - } - - color = kdeColor(QLatin1String("windowForeground"), theKdeSettings); - if (!color.isValid()) - color = kdeColor(QLatin1String("Colors:Window/ForegroundNormal"), theKdeSettings); - if (color.isValid()) - wfg = color; - - color = kdeColor(QLatin1String("windowBackground"), theKdeSettings); - if (!color.isValid()) - color = kdeColor(QLatin1String("Colors:View/BackgroundNormal"), theKdeSettings); - if (color.isValid()) - base = color; - } - QPalette pal(fg, btn, btn.lighter(125), btn.darker(130), btn.darker(120), wfg.isValid() ? wfg : fg, Qt::white, base, bg); QColor disabled((fg.red() + btn.red()) / 2, (fg.green() + btn.green())/ 2, @@ -1365,50 +1284,6 @@ static void qt_set_x11_resources(const char* font = 0, const char* fg = 0, highlight = QColor(selectBackground); highlightText = QColor(selectForeground); } - // Use KDE3 or KDE4 color settings if present - if (kdeColors) { - const QSettings theKdeSettings( - QApplicationPrivate::kdeHome() - + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat); - - QColor color = kdeColor(QLatin1String("selectBackground"), theKdeSettings); - if (!color.isValid()) - color = kdeColor(QLatin1String("Colors:Selection/BackgroundNormal"), theKdeSettings); - if (color.isValid()) - highlight = color; - - color = kdeColor(QLatin1String("selectForeground"), theKdeSettings); - if (!color.isValid()) - color = kdeColor(QLatin1String("Colors:Selection/ForegroundNormal"), theKdeSettings); - if (color.isValid()) - highlightText = color; - - color = kdeColor(QLatin1String("alternateBackground"), theKdeSettings); - if (!color.isValid()) - color = kdeColor(QLatin1String("Colors:View/BackgroundAlternate"), theKdeSettings); - if (color.isValid()) - pal.setColor(QPalette::AlternateBase, color); - else - pal.setBrush(QPalette::AlternateBase, pal.base().color().darker(110)); - - color = kdeColor(QLatin1String("buttonForeground"), theKdeSettings); - if (!color.isValid()) - color = kdeColor(QLatin1String("Colors:Button/ForegroundNormal"), theKdeSettings); - if (color.isValid()) - pal.setColor(QPalette::ButtonText, color); - - color = kdeColor(QLatin1String("linkColor"), theKdeSettings); - if (!color.isValid()) - color = kdeColor(QLatin1String("Colors:View/ForegroundLink"), theKdeSettings); - if (color.isValid()) - pal.setColor(QPalette::Link, color); - - color = kdeColor(QLatin1String("visitedLinkColor"), theKdeSettings); - if (!color.isValid()) - color = kdeColor(QLatin1String("Colors:View/ForegroundVisited"), theKdeSettings); - if (color.isValid()) - pal.setColor(QPalette::LinkVisited, color); - } if (highlight.isValid() && highlightText.isValid()) { pal.setColor(QPalette::Highlight, highlight); @@ -1431,10 +1306,9 @@ static void qt_set_x11_resources(const char* font = 0, const char* fg = 0, pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::darkBlue); } - // QGtkStyle sets it's own system palette - if (!(QApplicationPrivate::app_style && QApplicationPrivate::app_style->inherits("QGtkStyle"))) { - QApplicationPrivate::setSystemPalette(pal); - } + if (kdeColors) + pal = QKde::kdePalette().resolve(pal); + QApplicationPrivate::setSystemPalette(pal); QColor::setAllowX11ColorNames(allowX11ColorNames); } @@ -2315,6 +2189,7 @@ void qt_init(QApplicationPrivate *priv, int, X11->compositingManagerRunning = XGetSelectionOwner(X11->display, ATOM(_NET_WM_CM_S0)); X11->desktopEnvironment = DE_UNKNOWN; + X11->desktopVersion = 0; // See if the current window manager is using the freedesktop.org spec to give its name Window windowManagerWindow = XNone; @@ -2390,6 +2265,9 @@ void qt_init(QApplicationPrivate *priv, int, XFree((char *)data); } + if (X11->desktopEnvironment == DE_KDE) + X11->desktopVersion = QString::fromLocal8Bit(qgetenv("KDE_SESSION_VERSION")).toInt(); + qt_set_input_encoding(); qt_set_x11_resources(appFont, appFGCol, appBGCol, appBTNCol); @@ -2657,44 +2535,30 @@ void qt_init(QApplicationPrivate *priv, int, QString QApplicationPrivate::x11_desktop_style() { QString stylename; - QStringList availableStyles = QStyleFactory::keys(); - // Override Qt style if KDE4 settings can be used - if (4 == kdeSessionVersion()) { - QSettings kdeSettings(kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat); - QString kde4Style = kdeSettings.value(QLatin1String("widgetStyle"), - QLatin1String("Oxygen")).toString(); - foreach (const QString &style, availableStyles) { - if (style.toLower() == kde4Style.toLower()) - stylename = kde4Style; - } - // Set QGtkStyle for GNOME - } else if (X11->desktopEnvironment == DE_GNOME) { + switch(X11->desktopEnvironment) { + case DE_KDE: + stylename = QKde::kdeStyle(); + break; + case DE_GNOME: { + QStringList availableStyles = QStyleFactory::keys(); + // Set QGtkStyle for GNOME if available QString gtkStyleKey = QString::fromLatin1("GTK+"); - if (availableStyles.contains(gtkStyleKey)) + if (availableStyles.contains(gtkStyleKey)) { stylename = gtkStyleKey; - } - - if (stylename.isEmpty()) { - switch(X11->desktopEnvironment) { - case DE_KDE: - if (X11->use_xrender) - stylename = QLatin1String("plastique"); - else - stylename = QLatin1String("windows"); - break; - case DE_GNOME: - if (X11->use_xrender) - stylename = QLatin1String("cleanlooks"); - else - stylename = QLatin1String("windows"); - break; - case DE_CDE: - stylename = QLatin1String("cde"); - break; - default: - // Don't do anything break; } + if (X11->use_xrender) + stylename = QLatin1String("cleanlooks"); + else + stylename = QLatin1String("windows"); + break; + } + case DE_CDE: + stylename = QLatin1String("cde"); + break; + default: + // Don't do anything + break; } return stylename; } diff --git a/src/gui/kernel/qkde.cpp b/src/gui/kernel/qkde.cpp new file mode 100644 index 0000000..96ff21e --- /dev/null +++ b/src/gui/kernel/qkde.cpp @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qkde_p.h" +#include +#include +#include +#include +#include "QtGui/qstylefactory.h" +#include "qt_x11_p.h" + +#if defined(Q_WS_X11) + +QT_BEGIN_NAMESPACE + +/*! \internal +Gets the current KDE home path +like "/home/troll/.kde" +*/ +QString QKde::kdeHome() +{ + static QString kdeHomePath; + if (kdeHomePath.isEmpty()) { + kdeHomePath = QString::fromLocal8Bit(qgetenv("KDEHOME")); + if (kdeHomePath.isEmpty()) { + QDir homeDir(QDir::homePath()); + QString kdeConfDir(QLatin1String("/.kde")); + if (4 == X11->desktopVersion && homeDir.exists(QLatin1String(".kde4"))) + kdeConfDir = QLatin1String("/.kde4"); + kdeHomePath = QDir::homePath() + kdeConfDir; + } + } + return kdeHomePath; +} + +/*!\internal + Reads the color from the config, and store it in the palette with the given color role if found + */ +static bool kdeColor(QPalette *pal, QPalette::ColorRole role, const QSettings &kdeSettings, const QString &kde4Key, const QString &kde3Key = QString()) +{ + QVariant variant = kdeSettings.value(kde4Key); + if (!variant.isValid()) + QVariant variant = kdeSettings.value(kde3Key); + if (variant.isValid()) { + QStringList values = variant.toStringList(); + if (values.size() == 3) { + int r = values[0].toInt(); + int g = values[1].toInt(); + int b = values[2].toInt(); + pal->setBrush(role, QColor(r, g, b)); + return true; + } + } + return false; +} + + +/*!\internal + Returns the KDE palette +*/ +QPalette QKde::kdePalette() +{ + const QSettings theKdeSettings(QKde::kdeHome() + + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat); + QPalette pal; + + // Setup KDE palette + kdeColor(&pal, QPalette::Button, theKdeSettings, QLatin1String("Colors:Button/BackgroundNormal"), QLatin1String("buttonBackground")); + kdeColor(&pal, QPalette::Window, theKdeSettings, QLatin1String("Colors:Window/BackgroundNormal"), QLatin1String("background")); + kdeColor(&pal, QPalette::Text, theKdeSettings, QLatin1String("Colors:View/ForegroundNormal"), QLatin1String("foreground")); + kdeColor(&pal, QPalette::WindowText, theKdeSettings, QLatin1String("Colors:Window/ForegroundNormal"), QLatin1String("windowForeground")); + kdeColor(&pal, QPalette::Base, theKdeSettings, QLatin1String("Colors:View/BackgroundNormal"), QLatin1String("windowBackground")); + kdeColor(&pal, QPalette::Highlight, theKdeSettings, QLatin1String("Colors:Selection/BackgroundNormal"), QLatin1String("selectBackground")); + kdeColor(&pal, QPalette::HighlightedText, theKdeSettings, QLatin1String("Colors:Selection/ForegroundNormal"), QLatin1String("selectForeground")); + kdeColor(&pal, QPalette::AlternateBase, theKdeSettings, QLatin1String("Colors:View/BackgroundAlternate"), QLatin1String("alternateBackground")); + kdeColor(&pal, QPalette::ButtonText, theKdeSettings, QLatin1String("Colors:Button/ForegroundNormal"), QLatin1String("buttonForeground")); + kdeColor(&pal, QPalette::Link, theKdeSettings, QLatin1String("Colors:View/ForegroundLink"), QLatin1String("linkColor")); + kdeColor(&pal, QPalette::LinkVisited, theKdeSettings, QLatin1String("Colors:View/ForegroundVisited"), QLatin1String("visitedLinkColor")); + //## TODO tooltip color + + return pal; +} + +/*!\internal + Returns the name of the QStyle to use. + (read from the kde config if needed) +*/ +QString QKde::kdeStyle() +{ + if (X11->desktopVersion >= 4) { + QSettings kdeSettings(QKde::kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat); + QString style = kdeSettings.value(QLatin1String("widgetStyle"), QLatin1String("Oxygen")).toString(); + + QStringList availableStyles = QStyleFactory::keys(); + if(availableStyles.contains(style, Qt::CaseInsensitive)) + return style; + } + + if (X11->use_xrender) + return QLatin1String("plastique"); + else + return QLatin1String("windows"); + + return QString(); +} + +/*!\internal + placeholder to load icon from kde. + to be implemented + */ +QIcon QKde::kdeIcon(const QString &name) +{ + //###todo + return QIcon(); +} + +QT_END_NAMESPACE + +#endif //Q_WS_X11 + diff --git a/src/gui/kernel/qkde_p.h b/src/gui/kernel/qkde_p.h new file mode 100644 index 0000000..ac760bd --- /dev/null +++ b/src/gui/kernel/qkde_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QKDE_H +#define QKDE_H + +#include +#include +#include + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// +#if defined(Q_WS_X11) + + +QT_BEGIN_NAMESPACE + +// This namespace contains helper function to help KDE integration +namespace QKde { + QString kdeHome(); + QString kdeStyle(); + QPalette kdePalette(); + QIcon kdeIcon(const QString &name); +} + + +QT_END_NAMESPACE + +#endif // Q_WS_X11 +#endif // QKDE_H diff --git a/src/gui/kernel/qt_x11_p.h b/src/gui/kernel/qt_x11_p.h index 1ac51e0..44652d3 100644 --- a/src/gui/kernel/qt_x11_p.h +++ b/src/gui/kernel/qt_x11_p.h @@ -515,7 +515,8 @@ struct QX11Data char *startupId; - DesktopEnvironment desktopEnvironment; + DesktopEnvironment desktopEnvironment : 8; + uint desktopVersion : 8; /* Used only for KDE */ /* Warning: if you modify this list, modify the names of atoms in qapplication_x11.cpp as well! */ enum X11Atom { diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index ba28e75..c7feb25 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -63,7 +63,7 @@ #include #include #include -#include +#include <../kernel/qkde_p.h> #include #include #include @@ -842,12 +842,6 @@ static void drawArrow(const QStyle *style, const QStyleOptionToolButton *toolbut #ifdef Q_WS_X11 // These functions are used to parse the X11 freedesktop icon spec -static int kdeVersion() -{ - static int kdeVersion = qgetenv("KDE_SESSION_VERSION").toInt(); - return kdeVersion; -} - void QCommonStylePrivate::lookupIconTheme() const { if (!themeName.isEmpty()) @@ -856,7 +850,7 @@ void QCommonStylePrivate::lookupIconTheme() const QString dataDirs = QString::fromLocal8Bit(getenv("XDG_DATA_DIRS")); if (dataDirs.isEmpty()) dataDirs = QLatin1String("/usr/local/share/:/usr/share/"); - dataDirs += QLatin1Char(':') + QApplicationPrivate::kdeHome() + QLatin1String("/share"); + dataDirs += QLatin1Char(':') + QKde::kdeHome() + QLatin1String("/share"); dataDirs.prepend(QDir::homePath() + QLatin1String("/:")); QStringList kdeDirs = QString::fromLocal8Bit(getenv("KDEDIRS")).split(QLatin1Char(':'), QString::SkipEmptyParts); foreach (const QString &dirName, kdeDirs) @@ -865,9 +859,10 @@ void QCommonStylePrivate::lookupIconTheme() const QFileInfo fileInfo(QLatin1String("/usr/share/icons/default.kde")); QDir dir(fileInfo.canonicalFilePath()); - QString kdeDefault = kdeVersion() >= 4 ? QString::fromLatin1("oxygen") : QString::fromLatin1("crystalsvg"); + QString kdeDefault = (X11->desktopEnvironment != DE_KDE || X11->desktopVersion >= 4) + ? QString::fromLatin1("oxygen") : QString::fromLatin1("crystalsvg"); QString defaultTheme = fileInfo.exists() ? dir.dirName() : kdeDefault; - QSettings settings(QApplicationPrivate::kdeHome() + + QSettings settings(QKde::kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat); settings.beginGroup(QLatin1String("Icons")); themeName = settings.value(QLatin1String("Theme"), defaultTheme).toString(); @@ -979,8 +974,15 @@ QPixmap QCommonStylePrivate::findIconHelper(int size, return pixmap; } +/*! \internal + find a pixmap with the given size and name from the freedesktop theme. +*/ QPixmap QCommonStylePrivate::findIcon(int size, const QString &name) const { + QIcon icon = QKde::kdeIcon(name); + if (!icon.isNull()) + return icon.pixmap(size); + QPixmap pixmap; QString pixmapName = QLatin1String("$qt") + name + QString::number(size); @@ -995,12 +997,17 @@ QPixmap QCommonStylePrivate::findIcon(int size, const QString &name) const return pixmap; } +/*! \internal + create an Icon from the freedesktop theme. + */ QIcon QCommonStylePrivate::createIcon(const QString &name) const { - QIcon icon; - icon.addPixmap(findIcon(16, name)); - icon.addPixmap(findIcon(24, name)); - icon.addPixmap(findIcon(32, name)); + QIcon icon = QKde::kdeIcon(name); + if (icon.isNull()) { + icon.addPixmap(findIcon(16, name)); + icon.addPixmap(findIcon(24, name)); + icon.addPixmap(findIcon(32, name)); + } return icon; } /*!internal @@ -1012,8 +1019,8 @@ from the KDE configuration file int QCommonStylePrivate::lookupToolButtonStyle() const { int result = Qt::ToolButtonIconOnly; - if (kdeVersion() >= 4) { - QSettings settings(QApplicationPrivate::kdeHome() + + if (X11->desktopEnvironment == DE_KDE && X11->desktopVersion >= 4) { + QSettings settings(QKde::kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat); settings.beginGroup(QLatin1String("Toolbar style")); QString toolbarStyle = settings.value(QLatin1String("ToolButtonStyle"), QLatin1String("TextBesideIcon")).toString(); -- cgit v0.12 From 6993e77d2cd147098c6ddab187469a9177ea134e Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Fri, 7 Aug 2009 15:06:23 +0200 Subject: Doc - Improving the documentation for QListWidget and QListWidgetItem Reviewed-By: TrustMe --- src/gui/itemviews/qlistwidget.cpp | 446 +++++++++++++++++++------------------- 1 file changed, 228 insertions(+), 218 deletions(-) diff --git a/src/gui/itemviews/qlistwidget.cpp b/src/gui/itemviews/qlistwidget.cpp index 2565657..6351496 100644 --- a/src/gui/itemviews/qlistwidget.cpp +++ b/src/gui/itemviews/qlistwidget.cpp @@ -447,21 +447,20 @@ Qt::DropActions QListModel::supportedDropActions() const \ingroup model-view - QListWidgetItem is used to represent items in a list provided by the - QListWidget class. Each item can hold several pieces of information, - and will display these appropriately. + A QListWidgetItem represents a single item in a QListWidget. Each item can + hold several pieces of information, and will display them appropriately. - The item view convenience classes use a classic item-based interface - rather than a pure model/view approach. For a more flexible list view - widget, consider using the QListView class with a standard model. + The item view convenience classes use a classic item-based interface rather + than a pure model/view approach. For a more flexible list view widget, + consider using the QListView class with a standard model. - List items can be automatically inserted into a list when they are - constructed by specifying the list widget: + List items can be inserted automatically into a list, when they are + constructed, by specifying the list widget: \snippet doc/src/snippets/qlistwidget-using/mainwindow.cpp 2 - They can also be created without a parent widget, and later inserted into - a list (see \l{QListWidget::insertItem()}). + Alternatively, list items can also be created without a parent widget, and + later inserted into a list using QListWidget::insertItem(). List items are typically used to display text() and an icon(). These are set with the setText() and setIcon() functions. The appearance of the text @@ -471,22 +470,24 @@ Qt::DropActions QListModel::supportedDropActions() const with setToolTip(), setStatusTip(), and setWhatsThis(). By default, items are enabled, selectable, checkable, and can be the source - of a drag and drop operation. + of drag and drop operations. + Each item's flags can be changed by calling setFlags() with the appropriate - value (see \l{Qt::ItemFlags}). Checkable items can be checked, unchecked and + value (see Qt::ItemFlags). Checkable items can be checked, unchecked and partially checked with the setCheckState() function. The corresponding - checkState() function indicates what check state the item currently has. + checkState() function indicates the item's current check state. + + The isHidden() function can be used to determine whether the item is + hidden. To hide an item, use setHidden(). - The isHidden() function can be used to determine whether the - item is hidden. Items can be hidden with setHidden(). \section1 Subclassing When subclassing QListWidgetItem to provide custom items, it is possible to - define new types for them so that they can be distinguished from standard - items. The constructors for subclasses that require this feature need to - call the base class constructor with a new type value equal to or greater - than \l UserType. + define new types for them enabling them to be distinguished from standard + items. For subclasses that require this feature, ensure that you call the + base class constructor with a new type value equal to or greater than + \l UserType, within \e your constructor. \sa QListWidget, {Model/View Programming}, QTreeWidgetItem, QTableWidgetItem */ @@ -515,59 +516,58 @@ Qt::DropActions QListModel::supportedDropActions() const /*! \fn QListWidget *QListWidgetItem::listWidget() const - Returns the list widget that contains the item. + Returns the list widget containing the item. */ /*! - \fn void QListWidgetItem::setSelected(bool select) - \since 4.2 + \fn void QListWidgetItem::setSelected(bool select) + \since 4.2 - Sets the selected state of the item to \a select. + Sets the selected state of the item to \a select. - \sa isSelected() + \sa isSelected() */ /*! - \fn bool QListWidgetItem::isSelected() const - \since 4.2 + \fn bool QListWidgetItem::isSelected() const + \since 4.2 - Returns true if the item is selected, otherwise returns false. + Returns true if the item is selected; otherwise returns false. - \sa setSelected() + \sa setSelected() */ /*! - \fn void QListWidgetItem::setHidden(bool hide) - \since 4.2 + \fn void QListWidgetItem::setHidden(bool hide) + \since 4.2 - Hides the item if \a hide is true, otherwise shows the item. + Hides the item if \a hide is true; otherwise shows the item. - \sa isHidden() + \sa isHidden() */ /*! - \fn bool QListWidgetItem::isHidden() const - \since 4.2 + \fn bool QListWidgetItem::isHidden() const + \since 4.2 - Returns true if the item is hidden, otherwise returns false. + Returns true if the item is hidden; otherwise returns false. - \sa setHidden() + \sa setHidden() */ /*! \fn QListWidgetItem::QListWidgetItem(QListWidget *parent, int type) Constructs an empty list widget item of the specified \a type with the - given \a parent. - If the parent is not specified, the item will need to be inserted into a - list widget with QListWidget::insertItem(). + given \a parent. If \a parent is not specified, the item will need to be + inserted into a list widget with QListWidget::insertItem(). - \note that this constructor inserts this same object into the model of - the parent that is passed to the constructor. If the model is sorted then - the behavior of the insert is undetermined since the model will call - the '<' operator method on this object which has still not yet been - constructed. In this case it would be better not to specify the parent - and use the QListWidget::insertItem method to insert the item instead. + This constructor inserts the item into the model of the parent that is + passed to the constructor. If the model is sorted then the behavior of the + insert is undetermined since the model will call the \c '<' operator method + on the item which, at this point, is not yet constructed. To avoid the + undetermined behavior, we recommend not to specify the parent and use + QListWidget::insertItem() instead. \sa type() */ @@ -586,16 +586,15 @@ QListWidgetItem::QListWidgetItem(QListWidget *view, int type) \fn QListWidgetItem::QListWidgetItem(const QString &text, QListWidget *parent, int type) Constructs an empty list widget item of the specified \a type with the - given \a text and \a parent. - If the parent is not specified, the item will need to be inserted into a - list widget with QListWidget::insertItem(). + given \a text and \a parent. If the parent is not specified, the item will + need to be inserted into a list widget with QListWidget::insertItem(). - \note that this constructor inserts this same object into the model of - the parent that is passed to the constructor. If the model is sorted then - the behavior of the insert is undetermined since the model will call - the '<' operator method on this object which has still not yet been - constructed. In this case it would be better not to specify the parent - and use the QListWidget::insertItem method to insert the item instead. + This constructor inserts the item into the model of the parent that is + passed to the constructor. If the model is sorted then the behavior of the + insert is undetermined since the model will call the \c '<' operator method + on the item which, at this point, is not yet constructed. To avoid the + undetermined behavior, we recommend not to specify the parent and use + QListWidget::insertItem() instead. \sa type() */ @@ -616,16 +615,16 @@ QListWidgetItem::QListWidgetItem(const QString &text, QListWidget *view, int typ \fn QListWidgetItem::QListWidgetItem(const QIcon &icon, const QString &text, QListWidget *parent, int type) Constructs an empty list widget item of the specified \a type with the - given \a icon, \a text and \a parent. - If the parent is not specified, the item will need to be inserted into a - list widget with QListWidget::insertItem(). + given \a icon, \a text and \a parent. If the parent is not specified, the + item will need to be inserted into a list widget with + QListWidget::insertItem(). - \note that this constructor inserts this same object into the model of - the parent that is passed to the constructor. If the model is sorted then - the behavior of the insert is undetermined since the model will call - the '<' operator method on this object which has still not yet been - constructed. In this case it would be better not to specify the parent - and use the QListWidget::insertItem method to insert the item instead. + This constructor inserts the item into the model of the parent that is + passed to the constructor. If the model is sorted then the behavior of the + insert is undetermined since the model will call the \c '<' operator method + on the item which, at this point, is not yet constructed. To avoid the + undetermined behavior, we recommend not to specify the parent and use + QListWidget::insertItem() instead. \sa type() */ @@ -645,7 +644,7 @@ QListWidgetItem::QListWidgetItem(const QIcon &icon,const QString &text, } /*! - Destroys the list item. + Destroys the list item. */ QListWidgetItem::~QListWidgetItem() { @@ -655,7 +654,7 @@ QListWidgetItem::~QListWidgetItem() } /*! - Creates an exact copy of the item. + Creates an exact copy of the item. */ QListWidgetItem *QListWidgetItem::clone() const { @@ -663,11 +662,10 @@ QListWidgetItem *QListWidgetItem::clone() const } /*! - This function sets the data for a given \a role to the given \a value (see - \l{Qt::ItemDataRole}). Reimplement this function if you need - extra roles or special behavior for certain roles. + Sets the data for a given \a role to the given \a value. Reimplement this + function if you need extra roles or special behavior for certain roles. - \sa Qt::ItemDataRole, data() + \sa Qt::ItemDataRole, data() */ void QListWidgetItem::setData(int role, const QVariant &value) { @@ -689,9 +687,10 @@ void QListWidgetItem::setData(int role, const QVariant &value) } /*! - This function returns the item's data for a given \a role (see - Qt::ItemDataRole). Reimplement this function if you need - extra roles or special behavior for certain roles. + Returns the item's data for a given \a role. Reimplement this function if + you need extra roles or special behavior for certain roles. + + \sa Qt::ItemDataRole, setData() */ QVariant QListWidgetItem::data(int role) const { @@ -703,8 +702,8 @@ QVariant QListWidgetItem::data(int role) const } /*! - Returns true if this item's text is less then \a other item's text; - otherwise returns false. + Returns true if this item's text is less then \a other item's text; + otherwise returns false. */ bool QListWidgetItem::operator<(const QListWidgetItem &other) const { @@ -740,8 +739,8 @@ void QListWidgetItem::write(QDataStream &out) const /*! \since 4.1 - Constructs a copy of \a other. Note that type() and listWidget() - are not copied. + Constructs a copy of \a other. Note that type() and listWidget() are not + copied. This function is useful when reimplementing clone(). @@ -756,8 +755,8 @@ QListWidgetItem::QListWidgetItem(const QListWidgetItem &other) } /*! - Assigns \a other's data and flags to this item. Note that type() - and listWidget() are not copied. + Assigns \a other's data and flags to this item. Note that type() and + listWidget() are not copied. This function is useful when reimplementing clone(). @@ -805,9 +804,9 @@ QDataStream &operator>>(QDataStream &in, QListWidgetItem &item) #endif // QT_NO_DATASTREAM /*! - \fn Qt::ItemFlags QListWidgetItem::flags() const + \fn Qt::ItemFlags QListWidgetItem::flags() const - Returns the item flags for this item (see \l{Qt::ItemFlags}). + Returns the item flags for this item (see \l{Qt::ItemFlags}). */ /*! @@ -851,15 +850,17 @@ QDataStream &operator>>(QDataStream &in, QListWidgetItem &item) */ /*! - \fn QFont QListWidgetItem::font() const + \fn QFont QListWidgetItem::font() const - Returns the font used to display this list item's text. + Returns the font used to display this list item's text. */ /*! - \fn int QListWidgetItem::textAlignment() const + \fn int QListWidgetItem::textAlignment() const + + Returns the text alignment for the list item. - Returns the text alignment for the list item (see \l{Qt::AlignmentFlag}). + \sa Qt::AlignmentFlag */ /*! @@ -905,26 +906,26 @@ QDataStream &operator>>(QDataStream &in, QListWidgetItem &item) */ /*! - \fn QSize QListWidgetItem::sizeHint() const - \since 4.1 + \fn QSize QListWidgetItem::sizeHint() const + \since 4.1 - Returns the size hint set for the list item. + Returns the size hint set for the list item. */ /*! - \fn void QListWidgetItem::setSizeHint(const QSize &size) - \since 4.1 + \fn void QListWidgetItem::setSizeHint(const QSize &size) + \since 4.1 - Sets the size hint for the list item to be \a size. - If no size hint is set, the item delegate will compute the - size hint based on the item data. + Sets the size hint for the list item to be \a size. If no size hint is set, + the item delegate will compute the size hint based on the item data. */ /*! - \fn void QListWidgetItem::setFlags(Qt::ItemFlags flags) + \fn void QListWidgetItem::setFlags(Qt::ItemFlags flags) + + Sets the item flags for the list item to \a flags. - Sets the item flags for the list item to \a flags (see - \l{Qt::ItemFlags}). + \sa Qt::ItemFlags */ void QListWidgetItem::setFlags(Qt::ItemFlags aflags) { itemFlags = aflags; @@ -953,10 +954,10 @@ void QListWidgetItem::setFlags(Qt::ItemFlags aflags) { \fn void QListWidgetItem::setStatusTip(const QString &statusTip) Sets the status tip for the list item to the text specified by - \a statusTip. QListWidget mouse tracking needs to be enabled for this + \a statusTip. QListWidget mouseTracking needs to be enabled for this feature to work. - \sa statusTip() setToolTip() setWhatsThis() + \sa statusTip(), setToolTip(), setWhatsThis(), QWidget::setMouseTracking() */ /*! @@ -964,29 +965,30 @@ void QListWidgetItem::setFlags(Qt::ItemFlags aflags) { Sets the tooltip for the list item to the text specified by \a toolTip. - \sa toolTip() setStatusTip() setWhatsThis() + \sa toolTip(), setStatusTip(), setWhatsThis() */ /*! \fn void QListWidgetItem::setWhatsThis(const QString &whatsThis) - Sets the "What's This?" help for the list item to the text specified - by \a whatsThis. + Sets the "What's This?" help for the list item to the text specified by + \a whatsThis. - \sa whatsThis() setStatusTip() setToolTip() + \sa whatsThis(), setStatusTip(), setToolTip() */ /*! - \fn void QListWidgetItem::setFont(const QFont &font) + \fn void QListWidgetItem::setFont(const QFont &font) - Sets the font used when painting the item to the given \a font. + Sets the font used when painting the item to the given \a font. */ /*! - \fn void QListWidgetItem::setTextAlignment(int alignment) + \fn void QListWidgetItem::setTextAlignment(int alignment) + + Sets the list item's text alignment to \a alignment. - Sets the list item's text alignment to \a alignment (see - \l{Qt::AlignmentFlag}). + \sa Qt::AlignmentFlag */ /*! @@ -1127,10 +1129,10 @@ void QListWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, \ingroup model-view \mainclass - QListWidget is a convenience class that provides a list view similar to - the one supplied by QListView, but with a classic item-based interface - for adding and removing items. QListWidget uses an internal model to - manage each QListWidgetItem in the list. + QListWidget is a convenience class that provides a list view similar to the + one supplied by QListView, but with a classic item-based interface for + adding and removing items. QListWidget uses an internal model to manage + each QListWidgetItem in the list. For a more flexible list view widget, use the QListView class with a standard model. @@ -1145,23 +1147,23 @@ void QListWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, function. There are two ways to add items to the list: they can be constructed with - the list widget as their parent widget, or they can be constructed with - no parent widget and added to the list later. If a list widget already - exists when the items are constructed, the first method is easier to use: + the list widget as their parent widget, or they can be constructed with no + parent widget and added to the list later. If a list widget already exists + when the items are constructed, the first method is easier to use: \snippet doc/src/snippets/qlistwidget-using/mainwindow.cpp 1 - If you need to insert a new item into the list at a particular position, - it is more required to construct the item without a parent widget and - use the insertItem() function to place it within the list. The list - widget will take ownership of the item. + If you need to insert a new item into the list at a particular position, it + is more required to construct the item without a parent widget and use the + insertItem() function to place it within the list. The list widget will + take ownership of the item. \snippet doc/src/snippets/qlistwidget-using/mainwindow.cpp 6 \snippet doc/src/snippets/qlistwidget-using/mainwindow.cpp 7 - For multiple items, insertItems() can be used instead. The number of - items in the list is found with the count() function. - To remove items from the list, use takeItem(). + For multiple items, insertItems() can be used instead. The number of items + in the list is found with the count() function. To remove items from the + list, use takeItem(). The current item in the list can be found with currentItem(), and changed with setCurrentItem(). The user can also change the current item by @@ -1187,9 +1189,9 @@ void QListWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, Inserts the \a item at the end of the list widget. - \warning A QListWidgetItem can only be added to a - QListWidget once. Adding the same QListWidgetItem multiple - times to a QListWidget will result in undefined behavior. + \warning A QListWidgetItem can only be added to a QListWidget once. Adding + the same QListWidgetItem multiple times to a QListWidget will result in + undefined behavior. \sa insertItem() */ @@ -1197,8 +1199,7 @@ void QListWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, /*! \fn void QListWidget::addItem(const QString &label) - Inserts an item with the text \a label at the end of the list - widget. + Inserts an item with the text \a label at the end of the list widget. */ /*! @@ -1212,8 +1213,8 @@ void QListWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, /*! \fn void QListWidget::itemPressed(QListWidgetItem *item) - This signal is emitted with the specified \a item when a mouse button is pressed - on an item in the widget. + This signal is emitted with the specified \a item when a mouse button is + pressed on an item in the widget. \sa itemClicked(), itemDoubleClicked() */ @@ -1221,8 +1222,8 @@ void QListWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, /*! \fn void QListWidget::itemClicked(QListWidgetItem *item) - This signal is emitted with the specified \a item when a mouse button is clicked - on an item in the widget. + This signal is emitted with the specified \a item when a mouse button is + clicked on an item in the widget. \sa itemPressed(), itemDoubleClicked() */ @@ -1230,8 +1231,8 @@ void QListWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, /*! \fn void QListWidget::itemDoubleClicked(QListWidgetItem *item) - This signal is emitted with the specified \a item when a mouse button is double - clicked on an item in the widget. + This signal is emitted with the specified \a item when a mouse button is + double clicked on an item in the widget. \sa itemClicked(), itemPressed() */ @@ -1239,20 +1240,21 @@ void QListWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, /*! \fn void QListWidget::itemActivated(QListWidgetItem *item) - This signal is emitted when the \a item is activated. The \a item - is activated when the user clicks or double clicks on it, - depending on the system configuration. It is also activated when - the user presses the activation key (on Windows and X11 this is - the \gui Return key, on Mac OS X it is \key{Ctrl+0}). + This signal is emitted when the \a item is activated. The \a item is + activated when the user clicks or double clicks on it, depending on the + system configuration. It is also activated when the user presses the + activation key (on Windows and X11 this is the \gui Return key, on Mac OS + X it is \key{Ctrl+0}). */ /*! \fn void QListWidget::itemEntered(QListWidgetItem *item) - This signal is emitted when the mouse cursor enters an item. The - \a item is the item entered. This signal is only emitted when - mouseTracking is turned on, or when a mouse button is pressed - while moving into an item. + This signal is emitted when the mouse cursor enters an item. The \a item is + the item entered. This signal is only emitted when mouseTracking is turned + on, or when a mouse button is pressed while moving into an item. + + \sa QWidget::setMouseTracking() */ /*! @@ -1264,24 +1266,28 @@ void QListWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, /*! \fn void QListWidget::currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous) - This signal is emitted whenever the current item changes. The \a - previous item is the item that previously had the focus, \a - current is the new current item. + This signal is emitted whenever the current item changes. + + \a previous is the item that previously had the focus; \a current is the + new current item. */ /*! - \fn void QListWidget::currentTextChanged(const QString ¤tText) + \fn void QListWidget::currentTextChanged(const QString ¤tText) - This signal is emitted whenever the current item changes. The \a currentText - is the text data in the current item. If there is no current item, the \a currentText - is invalid. + This signal is emitted whenever the current item changes. + + \a currentText is the text data in the current item. If there is no current + item, the \a currentText is invalid. */ /*! - \fn void QListWidget::currentRowChanged(int currentRow) + \fn void QListWidget::currentRowChanged(int currentRow) - This signal is emitted whenever the current item changes. The \a currentRow - is the row of the current item. If there is no current item, the \a currentRow is -1. + This signal is emitted whenever the current item changes. + + \a currentRow is the row of the current item. If there is no current item, + the \a currentRow is -1. */ /*! @@ -1289,15 +1295,15 @@ void QListWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, This signal is emitted whenever the selection changes. - \sa selectedItems() QListWidgetItem::isSelected() currentItemChanged() + \sa selectedItems(), QListWidgetItem::isSelected(), currentItemChanged() */ /*! - \since 4.3 + \since 4.3 - \fn void QListWidget::removeItemWidget(QListWidgetItem *item) + \fn void QListWidget::removeItemWidget(QListWidgetItem *item) - Removes the widget set on the given \a item. + Removes the widget set on the given \a item. */ /*! @@ -1361,8 +1367,8 @@ void QListWidget::insertItem(int row, QListWidgetItem *item) } /*! - Inserts an item with the text \a label in the list widget at the - position given by \a row. + Inserts an item with the text \a label in the list widget at the position + given by \a row. \sa addItem() */ @@ -1387,11 +1393,11 @@ void QListWidget::insertItems(int row, const QStringList &labels) } /*! - Removes and returns the item from the given \a row in the list widget; otherwise - returns 0. + Removes and returns the item from the given \a row in the list widget; + otherwise returns 0. - Items removed from a list widget will not be managed by Qt, and will need to be - deleted manually. + Items removed from a list widget will not be managed by Qt, and will need + to be deleted manually. \sa insertItem(), addItem() */ @@ -1405,8 +1411,8 @@ QListWidgetItem *QListWidget::takeItem(int row) } /*! - \property QListWidget::count - \brief the number of items in the list including any hidden items. + \property QListWidget::count + \brief the number of items in the list including any hidden items. */ int QListWidget::count() const @@ -1416,7 +1422,7 @@ int QListWidget::count() const } /*! - Returns the current item. + Returns the current item. */ QListWidgetItem *QListWidget::currentItem() const { @@ -1426,9 +1432,9 @@ QListWidgetItem *QListWidget::currentItem() const /*! - Sets the current item to \a item. + Sets the current item to \a item. - Depending on the current selection mode, the item may also be selected. + Depending on the current selection mode, the item may also be selected. */ void QListWidget::setCurrentItem(QListWidgetItem *item) { @@ -1436,8 +1442,8 @@ void QListWidget::setCurrentItem(QListWidgetItem *item) } /*! - \since 4.4 - Set the current item to \a item, using the given \a command. + \since 4.4 + Set the current item to \a item, using the given \a command. */ void QListWidget::setCurrentItem(QListWidgetItem *item, QItemSelectionModel::SelectionFlags command) { @@ -1445,10 +1451,10 @@ void QListWidget::setCurrentItem(QListWidgetItem *item, QItemSelectionModel::Sel } /*! - \property QListWidget::currentRow - \brief the row of the current item. + \property QListWidget::currentRow + \brief the row of the current item. - Depending on the current selection mode, the row may also be selected. + Depending on the current selection mode, the row may also be selected. */ int QListWidget::currentRow() const @@ -1469,9 +1475,9 @@ void QListWidget::setCurrentRow(int row) } /*! - \since 4.4 + \since 4.4 - Sets the current row to be the given \a row, using the given \a command, + Sets the current row to be the given \a row, using the given \a command, */ void QListWidget::setCurrentRow(int row, QItemSelectionModel::SelectionFlags command) { @@ -1498,7 +1504,7 @@ QListWidgetItem *QListWidget::itemAt(const QPoint &p) const /*! - Returns the rectangle on the viewport occupied by the item at \a item. + Returns the rectangle on the viewport occupied by the item at \a item. */ QRect QListWidget::visualItemRect(const QListWidgetItem *item) const { @@ -1508,7 +1514,7 @@ QRect QListWidget::visualItemRect(const QListWidgetItem *item) const } /*! - Sorts all the items in the list widget according to the specified \a order. + Sorts all the items in the list widget according to the specified \a order. */ void QListWidget::sortItems(Qt::SortOrder order) { @@ -1522,8 +1528,10 @@ void QListWidget::sortItems(Qt::SortOrder order) \property QListWidget::sortingEnabled \brief whether sorting is enabled - If this property is true, sorting is enabled for the list; if the - property is false, sorting is not enabled. The default value is false. + If this property is true, sorting is enabled for the list; if the property + is false, sorting is not enabled. + + The default value is false. */ void QListWidget::setSortingEnabled(bool enable) { @@ -1538,7 +1546,7 @@ bool QListWidget::isSortingEnabled() const } /*! - \internal + \internal */ Qt::SortOrder QListWidget::sortOrder() const { @@ -1547,7 +1555,7 @@ Qt::SortOrder QListWidget::sortOrder() const } /*! - Starts editing the \a item if it is editable. + Starts editing the \a item if it is editable. */ void QListWidget::editItem(QListWidgetItem *item) @@ -1557,9 +1565,10 @@ void QListWidget::editItem(QListWidgetItem *item) } /*! - Opens an editor for the given \a item. The editor remains open after editing. + Opens an editor for the given \a item. The editor remains open after + editing. - \sa closePersistentEditor() + \sa closePersistentEditor() */ void QListWidget::openPersistentEditor(QListWidgetItem *item) { @@ -1569,9 +1578,9 @@ void QListWidget::openPersistentEditor(QListWidgetItem *item) } /*! - Closes the persistent editor for the given \a item. + Closes the persistent editor for the given \a item. - \sa openPersistentEditor() + \sa openPersistentEditor() */ void QListWidget::closePersistentEditor(QListWidgetItem *item) { @@ -1597,9 +1606,10 @@ QWidget *QListWidget::itemWidget(QListWidgetItem *item) const Sets the \a widget to be displayed in the give \a item. - This function should only be used to display static content in the place of a list - widget item. If you want to display custom dynamic content or implement a custom - editor widget, use QListView and subclass QItemDelegate instead. + This function should only be used to display static content in the place of + a list widget item. If you want to display custom dynamic content or + implement a custom editor widget, use QListView and subclass QItemDelegate + instead. \sa {Delegate Classes} */ @@ -1611,11 +1621,11 @@ void QListWidget::setItemWidget(QListWidgetItem *item, QWidget *widget) } /*! - Returns true if \a item is selected; otherwise returns false. + Returns true if \a item is selected; otherwise returns false. - \obsolete + \obsolete - This function is deprecated. Use \l{QListWidgetItem::isSelected()} instead. + This function is deprecated. Use QListWidgetItem::isSelected() instead. */ bool QListWidget::isItemSelected(const QListWidgetItem *item) const { @@ -1625,12 +1635,12 @@ bool QListWidget::isItemSelected(const QListWidgetItem *item) const } /*! - Selects or deselects the given \a item depending on whether \a select is - true of false. + Selects or deselects the given \a item depending on whether \a select is + true of false. - \obsolete + \obsolete - This function is deprecated. Use \l{QListWidgetItem::setSelected()} instead. + This function is deprecated. Use QListWidgetItem::setSelected() instead. */ void QListWidget::setItemSelected(const QListWidgetItem *item, bool select) { @@ -1650,7 +1660,7 @@ void QListWidget::setItemSelected(const QListWidgetItem *item, bool select) } /*! - Returns a list of all selected items in the list widget. + Returns a list of all selected items in the list widget. */ QList QListWidget::selectedItems() const @@ -1664,7 +1674,8 @@ QList QListWidget::selectedItems() const } /*! - Finds items with the text that matches the string \a text using the given \a flags. + Finds items with the text that matches the string \a text using the given + \a flags. */ QList QListWidget::findItems(const QString &text, Qt::MatchFlags flags) const @@ -1679,11 +1690,11 @@ QList QListWidget::findItems(const QString &text, Qt::MatchFla } /*! - Returns true if the \a item is explicitly hidden; otherwise returns false. + Returns true if the \a item is explicitly hidden; otherwise returns false. - \obsolete + \obsolete - This function is deprecated. Use \l{QListWidgetItem::isHidden()} instead. + This function is deprecated. Use QListWidgetItem::isHidden() instead. */ bool QListWidget::isItemHidden(const QListWidgetItem *item) const { @@ -1691,11 +1702,11 @@ bool QListWidget::isItemHidden(const QListWidgetItem *item) const } /*! - If \a hide is true, the \a item will be hidden; otherwise it will be shown. + If \a hide is true, the \a item will be hidden; otherwise it will be shown. - \obsolete + \obsolete - This function is deprecated. Use \l{QListWidgetItem::setHidden()} instead. + This function is deprecated. Use QListWidgetItem::setHidden() instead. */ void QListWidget::setItemHidden(const QListWidgetItem *item, bool hide) { @@ -1703,9 +1714,9 @@ void QListWidget::setItemHidden(const QListWidgetItem *item, bool hide) } /*! - Scrolls the view if necessary to ensure that the \a item is - visible. The \a hint parameter specifies more precisely where the - \a item should be located after the operation. + Scrolls the view if necessary to ensure that the \a item is visible. + + \a hint specifies where the \a item should be located after the operation. */ void QListWidget::scrollToItem(const QListWidgetItem *item, QAbstractItemView::ScrollHint hint) @@ -1718,7 +1729,7 @@ void QListWidget::scrollToItem(const QListWidgetItem *item, QAbstractItemView::S /*! Removes all items and selections in the view. - \note All items will be permanently deleted. + \warning All items will be permanently deleted. */ void QListWidget::clear() { @@ -1743,8 +1754,8 @@ QStringList QListWidget::mimeTypes() const \a items. The format used to describe the items is obtained from the mimeTypes() function. - If the list of items is empty, 0 is returned rather than a serialized - empty list. + If the list of items is empty, 0 is returned instead of a serialized empty + list. */ QMimeData *QListWidget::mimeData(const QList) const { @@ -1753,10 +1764,9 @@ QMimeData *QListWidget::mimeData(const QList) const #ifndef QT_NO_DRAGANDDROP /*! - Handles the \a data supplied by an external drag and drop operation - that ended with the given \a action in the given \a index. - Returns true if the data and action can be handled by the model; - otherwise returns false. + Handles \a data supplied by an external drag and drop operation that ended + with the given \a action in the given \a index. Returns true if \a data and + \a action can be handled by the model; otherwise returns false. \sa supportedDropActions() */ @@ -1823,9 +1833,9 @@ void QListWidget::dropEvent(QDropEvent *event) { } /*! - Returns the drop actions supported by this view. + Returns the drop actions supported by this view. - \sa Qt::DropActions + \sa Qt::DropActions */ Qt::DropActions QListWidget::supportedDropActions() const { @@ -1835,9 +1845,9 @@ Qt::DropActions QListWidget::supportedDropActions() const #endif // QT_NO_DRAGANDDROP /*! - Returns a list of pointers to the items contained in the \a data object. - If the object was not created by a QListWidget in the same process, the list - is empty. + Returns a list of pointers to the items contained in the \a data object. If + the object was not created by a QListWidget in the same process, the list + is empty. */ QList QListWidget::items(const QMimeData *data) const { @@ -1848,7 +1858,7 @@ QList QListWidget::items(const QMimeData *data) const } /*! - Returns the QModelIndex assocated with the given \a item. + Returns the QModelIndex assocated with the given \a item. */ QModelIndex QListWidget::indexFromItem(QListWidgetItem *item) const @@ -1858,7 +1868,7 @@ QModelIndex QListWidget::indexFromItem(QListWidgetItem *item) const } /*! - Returns a pointer to the QListWidgetItem assocated with the given \a index. + Returns a pointer to the QListWidgetItem assocated with the given \a index. */ QListWidgetItem *QListWidget::itemFromIndex(const QModelIndex &index) const @@ -1870,7 +1880,7 @@ QListWidgetItem *QListWidget::itemFromIndex(const QModelIndex &index) const } /*! - \internal + \internal */ void QListWidget::setModel(QAbstractItemModel * /*model*/) { -- cgit v0.12 From 658c30c214070e8ff05ddaf1cb7b161c1b73f5ce Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Fri, 7 Aug 2009 15:09:30 +0200 Subject: Doc - Removing trailing whitespaces Reviewed-By: TrustMe --- src/gui/itemviews/qlistwidget.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gui/itemviews/qlistwidget.cpp b/src/gui/itemviews/qlistwidget.cpp index 6351496..b518ff2 100644 --- a/src/gui/itemviews/qlistwidget.cpp +++ b/src/gui/itemviews/qlistwidget.cpp @@ -561,7 +561,7 @@ Qt::DropActions QListModel::supportedDropActions() const Constructs an empty list widget item of the specified \a type with the given \a parent. If \a parent is not specified, the item will need to be inserted into a list widget with QListWidget::insertItem(). - + This constructor inserts the item into the model of the parent that is passed to the constructor. If the model is sorted then the behavior of the insert is undetermined since the model will call the \c '<' operator method @@ -588,7 +588,7 @@ QListWidgetItem::QListWidgetItem(QListWidget *view, int type) Constructs an empty list widget item of the specified \a type with the given \a text and \a parent. If the parent is not specified, the item will need to be inserted into a list widget with QListWidget::insertItem(). - + This constructor inserts the item into the model of the parent that is passed to the constructor. If the model is sorted then the behavior of the insert is undetermined since the model will call the \c '<' operator method @@ -618,14 +618,14 @@ QListWidgetItem::QListWidgetItem(const QString &text, QListWidget *view, int typ given \a icon, \a text and \a parent. If the parent is not specified, the item will need to be inserted into a list widget with QListWidget::insertItem(). - + This constructor inserts the item into the model of the parent that is passed to the constructor. If the model is sorted then the behavior of the insert is undetermined since the model will call the \c '<' operator method on the item which, at this point, is not yet constructed. To avoid the undetermined behavior, we recommend not to specify the parent and use QListWidget::insertItem() instead. - + \sa type() */ QListWidgetItem::QListWidgetItem(const QIcon &icon,const QString &text, @@ -1267,7 +1267,7 @@ void QListWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, \fn void QListWidget::currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous) This signal is emitted whenever the current item changes. - + \a previous is the item that previously had the focus; \a current is the new current item. */ @@ -1276,7 +1276,7 @@ void QListWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, \fn void QListWidget::currentTextChanged(const QString ¤tText) This signal is emitted whenever the current item changes. - + \a currentText is the text data in the current item. If there is no current item, the \a currentText is invalid. */ @@ -1285,7 +1285,7 @@ void QListWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, \fn void QListWidget::currentRowChanged(int currentRow) This signal is emitted whenever the current item changes. - + \a currentRow is the row of the current item. If there is no current item, the \a currentRow is -1. */ -- cgit v0.12 From dfa284220498a1e32ab3133f203bcb41cfa136b7 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Fri, 7 Aug 2009 15:08:09 +0200 Subject: Refactor QTestCharBuffer a bit Use a static buffer for small strings, and making it oom safe. We can now see messages up to 512 bytes even if we run out of memory (important for OOM tests). Also, testlogging (< 512 bytes per line) should again work without a single allocation. Reviewed-By: Rohan McGovern --- src/testlib/qabstracttestlogger.cpp | 47 ++++++++++++++++++++++ src/testlib/qabstracttestlogger_p.h | 52 +++++++++++++++++++----- src/testlib/qplaintestlogger.cpp | 10 ++--- src/testlib/qtest_global.h | 1 - src/testlib/qtestbasicstreamer.cpp | 40 +++++++++---------- src/testlib/qtestbasicstreamer.h | 11 ++--- src/testlib/qtestcase.cpp | 37 ----------------- src/testlib/qtestlightxmlstreamer.cpp | 70 ++++++++++++++++---------------- src/testlib/qtestlightxmlstreamer.h | 6 +-- src/testlib/qtestxmlstreamer.cpp | 61 ++++++++++++++-------------- src/testlib/qtestxmlstreamer.h | 6 +-- src/testlib/qtestxunitstreamer.cpp | 43 ++++++++++---------- src/testlib/qtestxunitstreamer.h | 8 ++-- src/testlib/qxmltestlogger.cpp | 75 ++++++++++++++++++----------------- src/testlib/qxmltestlogger_p.h | 8 ++-- 15 files changed, 257 insertions(+), 218 deletions(-) diff --git a/src/testlib/qabstracttestlogger.cpp b/src/testlib/qabstracttestlogger.cpp index 6482ec9..2fa535e 100644 --- a/src/testlib/qabstracttestlogger.cpp +++ b/src/testlib/qabstracttestlogger.cpp @@ -43,8 +43,11 @@ #include "QtTest/private/qtestlog_p.h" #include "QtTest/qtestassert.h" +#include "QtCore/qbytearray.h" + #include #include +#include #ifndef Q_OS_WIN #include @@ -106,4 +109,48 @@ void QAbstractTestLogger::stopLogging() QTest::stream = 0; } +namespace QTest +{ + +extern void filter_unprintable(char *str); + +/*! \internal + */ +int qt_asprintf(QTestCharBuffer *str, const char *format, ...) +{ + static const int MAXSIZE = 1024*1024*2; + + Q_ASSERT(str); + + int size = str->size(); + + va_list ap; + int res = 0; + + for (;;) { + va_start(ap, format); + res = qvsnprintf(str->data(), size, format, ap); + va_end(ap); + str->data()[size - 1] = '\0'; + if (res >= 0 && res < size) { + // We succeeded + break; + } + // buffer wasn't big enough, try again. + // Note, we're assuming that a result of -1 is always due to running out of space. + size *= 2; + if (size > MAXSIZE) { + break; + } + if (!str->reset(size)) + break; // out of memory - take what we have + } + + filter_unprintable(str->data()); + + return res; +} + +} + QT_END_NAMESPACE diff --git a/src/testlib/qabstracttestlogger_p.h b/src/testlib/qabstracttestlogger_p.h index 588184e..1834086 100644 --- a/src/testlib/qabstracttestlogger_p.h +++ b/src/testlib/qabstracttestlogger_p.h @@ -101,27 +101,26 @@ public: struct QTestCharBuffer { - inline QTestCharBuffer() - : buf(0) - {} + enum { InitialSize = 512 }; - inline ~QTestCharBuffer() + inline QTestCharBuffer() + : _size(InitialSize), buf(staticBuf) { - delete[] buf; - buf = 0; + staticBuf[0] = '\0'; } - inline operator void*() + inline ~QTestCharBuffer() { - return buf; + if (buf != staticBuf) + qFree(buf); } - inline operator char*() + inline char *data() { return buf; } - inline operator char**() + inline char **buffer() { return &buf; } @@ -131,10 +130,43 @@ struct QTestCharBuffer return buf; } + inline int size() const + { + return _size; + } + + inline bool reset(int newSize) + { + char *newBuf = 0; + if (buf == staticBuf) { + // if we point to our internal buffer, we need to malloc first + newBuf = reinterpret_cast(qMalloc(newSize)); + } else { + // if we already malloc'ed, just realloc + newBuf = reinterpret_cast(qRealloc(buf, newSize)); + } + + // if the allocation went wrong (newBuf == 0), we leave the object as is + if (!newBuf) + return false; + + _size = newSize; + buf = newBuf; + return true; + } + private: + int _size; char* buf; + char staticBuf[InitialSize]; }; +namespace QTest +{ + int qt_asprintf(QTestCharBuffer *buf, const char *format, ...); +} + + QT_END_NAMESPACE #endif diff --git a/src/testlib/qplaintestlogger.cpp b/src/testlib/qplaintestlogger.cpp index e075b36..2515c51 100644 --- a/src/testlib/qplaintestlogger.cpp +++ b/src/testlib/qplaintestlogger.cpp @@ -180,7 +180,7 @@ namespace QTest { : ""; const char *filler = (tag[0] && gtag[0]) ? ":" : ""; if (file) { - QTest::qt_asprintf(buf, "%s: %s::%s(%s%s%s)%s%s\n" + QTest::qt_asprintf(&buf, "%s: %s::%s(%s%s%s)%s%s\n" #ifdef Q_OS_WIN "%s(%d) : failure location\n" #else @@ -189,14 +189,14 @@ namespace QTest { , type, QTestResult::currentTestObjectName(), fn, gtag, filler, tag, msg[0] ? " " : "", msg, file, line); } else { - QTest::qt_asprintf(buf, "%s: %s::%s(%s%s%s)%s%s\n", + QTest::qt_asprintf(&buf, "%s: %s::%s(%s%s%s)%s%s\n", type, QTestResult::currentTestObjectName(), fn, gtag, filler, tag, msg[0] ? " " : "", msg); } // In colored mode, printf above stripped our nonprintable control characters. // Put them back. - memcpy(buf, type, strlen(type)); - outputMessage(buf); + memcpy(buf.data(), type, strlen(type)); + outputMessage(buf.data()); } template @@ -207,7 +207,7 @@ namespace QTest { int digits = 0; qreal divisor = 1; - + while (num / divisor >= 1) { divisor *= 10; ++digits; diff --git a/src/testlib/qtest_global.h b/src/testlib/qtest_global.h index c40f0ad..b5b0fc0 100644 --- a/src/testlib/qtest_global.h +++ b/src/testlib/qtest_global.h @@ -82,7 +82,6 @@ namespace QTest enum TestFailMode { Abort = 1, Continue = 2 }; int Q_TESTLIB_EXPORT qt_snprintf(char *str, int size, const char *format, ...); - int qt_asprintf(char **str, const char *format, ...); } QT_END_NAMESPACE diff --git a/src/testlib/qtestbasicstreamer.cpp b/src/testlib/qtestbasicstreamer.cpp index aac57ba..89de7d8 100644 --- a/src/testlib/qtestbasicstreamer.cpp +++ b/src/testlib/qtestbasicstreamer.cpp @@ -68,39 +68,39 @@ QTestBasicStreamer::QTestBasicStreamer() QTestBasicStreamer::~QTestBasicStreamer() {} -void QTestBasicStreamer::formatStart(const QTestElement *element, char **formatted) const +void QTestBasicStreamer::formatStart(const QTestElement *element, QTestCharBuffer *formatted) const { if(!element || !formatted ) return; - QTest::qt_asprintf(formatted, ""); + formatted->data()[0] = '\0'; } -void QTestBasicStreamer::formatEnd(const QTestElement *element, char **formatted) const +void QTestBasicStreamer::formatEnd(const QTestElement *element, QTestCharBuffer *formatted) const { if(!element || !formatted ) return; - QTest::qt_asprintf(formatted, ""); + formatted->data()[0] = '\0'; } -void QTestBasicStreamer::formatBeforeAttributes(const QTestElement *element, char **formatted) const +void QTestBasicStreamer::formatBeforeAttributes(const QTestElement *element, QTestCharBuffer *formatted) const { if(!element || !formatted ) return; - QTest::qt_asprintf(formatted, ""); + formatted->data()[0] = '\0'; } -void QTestBasicStreamer::formatAfterAttributes(const QTestElement *element, char **formatted) const +void QTestBasicStreamer::formatAfterAttributes(const QTestElement *element, QTestCharBuffer *formatted) const { if(!element || !formatted ) return; - QTest::qt_asprintf(formatted, ""); + formatted->data()[0] = '\0'; } -void QTestBasicStreamer::formatAttributes(const QTestElement *, const QTestElementAttribute *attribute, char **formatted) const +void QTestBasicStreamer::formatAttributes(const QTestElement *, const QTestElementAttribute *attribute, QTestCharBuffer *formatted) const { if(!attribute || !formatted ) return; - QTest::qt_asprintf(formatted, ""); + formatted->data()[0] = '\0'; } void QTestBasicStreamer::output(QTestElement *element) const @@ -125,22 +125,22 @@ void QTestBasicStreamer::outputElements(QTestElement *element, bool) const while (element) { hasChildren = element->childElements(); - formatStart(element, buf); - outputString(buf); + formatStart(element, &buf); + outputString(buf.data()); - formatBeforeAttributes(element, buf); - outputString(buf); + formatBeforeAttributes(element, &buf); + outputString(buf.data()); outputElementAttributes(element, element->attributes()); - formatAfterAttributes(element, buf); - outputString(buf); + formatAfterAttributes(element, &buf); + outputString(buf.data()); if(hasChildren) outputElements(element->childElements(), true); - formatEnd(element, buf); - outputString(buf); + formatEnd(element, &buf); + outputString(buf.data()); element = element->previousElement(); } @@ -150,8 +150,8 @@ void QTestBasicStreamer::outputElementAttributes(const QTestElement* element, QT { QTestCharBuffer buf; while(attribute){ - formatAttributes(element, attribute, buf); - outputString(buf); + formatAttributes(element, attribute, &buf); + outputString(buf.data()); attribute = attribute->nextElement(); } } diff --git a/src/testlib/qtestbasicstreamer.h b/src/testlib/qtestbasicstreamer.h index 432dd22..cabbf34 100644 --- a/src/testlib/qtestbasicstreamer.h +++ b/src/testlib/qtestbasicstreamer.h @@ -53,6 +53,7 @@ QT_MODULE(Test) class QTestElement; class QTestElementAttribute; class QTestLogger; +class QTestCharBuffer; class QTestBasicStreamer { @@ -71,11 +72,11 @@ class QTestBasicStreamer const QTestLogger *logger() const; protected: - virtual void formatStart(const QTestElement *element, char **formatted) const; - virtual void formatEnd(const QTestElement *element, char **formatted) const; - virtual void formatBeforeAttributes(const QTestElement *element, char **formatted) const; - virtual void formatAfterAttributes(const QTestElement *element, char **formatted) const; - virtual void formatAttributes(const QTestElement *element, const QTestElementAttribute *attribute, char **formatted) const; + virtual void formatStart(const QTestElement *element, QTestCharBuffer *formatted) const; + virtual void formatEnd(const QTestElement *element, QTestCharBuffer *formatted) const; + virtual void formatBeforeAttributes(const QTestElement *element, QTestCharBuffer *formatted) const; + virtual void formatAfterAttributes(const QTestElement *element, QTestCharBuffer *formatted) const; + virtual void formatAttributes(const QTestElement *element, const QTestElementAttribute *attribute, QTestCharBuffer *formatted) const; virtual void outputElements(QTestElement *element, bool isChildElement = false) const; virtual void outputElementAttributes(const QTestElement *element, QTestElementAttribute *attribute) const; diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index ac4ca83..1866197 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -820,43 +820,6 @@ void filter_unprintable(char *str) /*! \internal */ -int qt_asprintf(char **str, const char *format, ...) -{ - static const int MAXSIZE = 1024*1024*2; - - int size = 32; - delete[] *str; - *str = new char[size]; - - va_list ap; - int res = 0; - - for (;;) { - va_start(ap, format); - res = qvsnprintf(*str, size, format, ap); - va_end(ap); - (*str)[size - 1] = '\0'; - if (res >= 0 && res < size) { - // We succeeded - break; - } - // buffer wasn't big enough, try again. - // Note, we're assuming that a result of -1 is always due to running out of space. - size *= 2; - if (size > MAXSIZE) { - break; - } - delete[] *str; - *str = new char[size]; - } - - filter_unprintable(*str); - - return res; -} - -/*! \internal - */ int qt_snprintf(char *str, int size, const char *format, ...) { va_list ap; diff --git a/src/testlib/qtestlightxmlstreamer.cpp b/src/testlib/qtestlightxmlstreamer.cpp index e176201..b84f531 100644 --- a/src/testlib/qtestlightxmlstreamer.cpp +++ b/src/testlib/qtestlightxmlstreamer.cpp @@ -59,7 +59,7 @@ QTestLightXmlStreamer::QTestLightXmlStreamer() QTestLightXmlStreamer::~QTestLightXmlStreamer() {} -void QTestLightXmlStreamer::formatStart(const QTestElement *element, char **formatted) const +void QTestLightXmlStreamer::formatStart(const QTestElement *element, QTestCharBuffer *formatted) const { if(!element || !formatted) return; @@ -67,14 +67,14 @@ void QTestLightXmlStreamer::formatStart(const QTestElement *element, char **form switch(element->elementType()){ case QTest::LET_TestCase: { QTestCharBuffer quotedTf; - QXmlTestLogger::xmlQuote(quotedTf, element->attributeValue(QTest::AI_Name)); + QXmlTestLogger::xmlQuote("edTf, element->attributeValue(QTest::AI_Name)); QTest::qt_asprintf(formatted, "\n", quotedTf.constData()); break; } case QTest::LET_Failure: { QTestCharBuffer cdataDesc; - QXmlTestLogger::xmlCdata(cdataDesc, element->attributeValue(QTest::AI_Description)); + QXmlTestLogger::xmlCdata(&cdataDesc, element->attributeValue(QTest::AI_Description)); QTest::qt_asprintf(formatted, " \n", cdataDesc.constData()); @@ -84,8 +84,8 @@ void QTestLightXmlStreamer::formatStart(const QTestElement *element, char **form // assuming type and attribute names don't need quoting QTestCharBuffer quotedFile; QTestCharBuffer cdataDesc; - QXmlTestLogger::xmlQuote(quotedFile, element->attributeValue(QTest::AI_File)); - QXmlTestLogger::xmlCdata(cdataDesc, element->attributeValue(QTest::AI_Description)); + QXmlTestLogger::xmlQuote("edFile, element->attributeValue(QTest::AI_File)); + QXmlTestLogger::xmlCdata(&cdataDesc, element->attributeValue(QTest::AI_Description)); QTest::qt_asprintf(formatted, "\n \n\n", element->attributeValue(QTest::AI_Type), @@ -100,8 +100,8 @@ void QTestLightXmlStreamer::formatStart(const QTestElement *element, char **form // assuming value and iterations don't need quoting QTestCharBuffer quotedMetric; QTestCharBuffer quotedTag; - QXmlTestLogger::xmlQuote(quotedMetric, element->attributeValue(QTest::AI_Metric)); - QXmlTestLogger::xmlQuote(quotedTag, element->attributeValue(QTest::AI_Tag)); + QXmlTestLogger::xmlQuote("edMetric, element->attributeValue(QTest::AI_Metric)); + QXmlTestLogger::xmlQuote("edTag, element->attributeValue(QTest::AI_Tag)); QTest::qt_asprintf(formatted, "\n", element->attributeName(QTest::AI_Metric), @@ -115,11 +115,11 @@ void QTestLightXmlStreamer::formatStart(const QTestElement *element, char **form break; } default: - QTest::qt_asprintf(formatted, ""); + formatted->data()[0] = '\0'; } } -void QTestLightXmlStreamer::formatEnd(const QTestElement *element, char **formatted) const +void QTestLightXmlStreamer::formatEnd(const QTestElement *element, QTestCharBuffer *formatted) const { if(!element || !formatted) return; @@ -129,47 +129,47 @@ void QTestLightXmlStreamer::formatEnd(const QTestElement *element, char **format QTest::qt_asprintf(formatted, "\n\n"); else QTest::qt_asprintf(formatted, "\n"); + } else { + formatted->data()[0] = '\0'; } - else - QTest::qt_asprintf(formatted, ""); } -void QTestLightXmlStreamer::formatBeforeAttributes(const QTestElement *element, char **formatted) const +void QTestLightXmlStreamer::formatBeforeAttributes(const QTestElement *element, QTestCharBuffer *formatted) const { if(!element || !formatted) return; - if (element->elementType() == QTest::LET_TestCase && element->attribute(QTest::AI_Result)){ - QTestCharBuffer buf; - QTestCharBuffer quotedFile; - QXmlTestLogger::xmlQuote(quotedFile, element->attributeValue(QTest::AI_File)); - - QTest::qt_asprintf(buf, "%s=\"%s\" %s=\"%s\"", - element->attributeName(QTest::AI_File), - quotedFile.constData(), - element->attributeName(QTest::AI_Line), - element->attributeValue(QTest::AI_Line)); - - if( !element->childElements() ) - QTest::qt_asprintf(formatted, "\n", - element->attributeValue(QTest::AI_Result), buf.constData()); - else - QTest::qt_asprintf(formatted, "\n", - element->attributeValue(QTest::AI_Result), buf.constData()); - }else{ - QTest::qt_asprintf(formatted, ""); + if (element->elementType() == QTest::LET_TestCase && element->attribute(QTest::AI_Result)) { + QTestCharBuffer buf; + QTestCharBuffer quotedFile; + QXmlTestLogger::xmlQuote("edFile, element->attributeValue(QTest::AI_File)); + + QTest::qt_asprintf(&buf, "%s=\"%s\" %s=\"%s\"", + element->attributeName(QTest::AI_File), + quotedFile.constData(), + element->attributeName(QTest::AI_Line), + element->attributeValue(QTest::AI_Line)); + + if( !element->childElements() ) + QTest::qt_asprintf(formatted, "\n", + element->attributeValue(QTest::AI_Result), buf.constData()); + else + QTest::qt_asprintf(formatted, "\n", + element->attributeValue(QTest::AI_Result), buf.constData()); + } else { + formatted->data()[0] = '\0'; } } void QTestLightXmlStreamer::output(QTestElement *element) const { QTestCharBuffer buf; - QTest::qt_asprintf(buf, "\n %s\n %s\n", + QTest::qt_asprintf(&buf, "\n %s\n %s\n", qVersion(), QTEST_VERSION_STR ); - outputString(buf); + outputString(buf.constData()); - QTest::qt_asprintf(buf, "\n"); - outputString(buf); + QTest::qt_asprintf(&buf, "\n"); + outputString(buf.constData()); QTestBasicStreamer::output(element); } diff --git a/src/testlib/qtestlightxmlstreamer.h b/src/testlib/qtestlightxmlstreamer.h index 6dafdcc..e147e5c 100644 --- a/src/testlib/qtestlightxmlstreamer.h +++ b/src/testlib/qtestlightxmlstreamer.h @@ -59,9 +59,9 @@ class QTestLightXmlStreamer: public QTestBasicStreamer QTestLightXmlStreamer(); ~QTestLightXmlStreamer(); - void formatStart(const QTestElement *element, char **formatted) const; - void formatEnd(const QTestElement *element, char **formatted) const; - void formatBeforeAttributes(const QTestElement *element, char **formatted) const; + void formatStart(const QTestElement *element, QTestCharBuffer *formatted) const; + void formatEnd(const QTestElement *element, QTestCharBuffer *formatted) const; + void formatBeforeAttributes(const QTestElement *element, QTestCharBuffer *formatted) const; void output(QTestElement *element) const; }; diff --git a/src/testlib/qtestxmlstreamer.cpp b/src/testlib/qtestxmlstreamer.cpp index 1b6e674..c72d648 100644 --- a/src/testlib/qtestxmlstreamer.cpp +++ b/src/testlib/qtestxmlstreamer.cpp @@ -60,7 +60,7 @@ QTestXmlStreamer::QTestXmlStreamer() QTestXmlStreamer::~QTestXmlStreamer() {} -void QTestXmlStreamer::formatStart(const QTestElement *element, char **formatted) const +void QTestXmlStreamer::formatStart(const QTestElement *element, QTestCharBuffer *formatted) const { if(!element || !formatted) return; @@ -68,20 +68,20 @@ void QTestXmlStreamer::formatStart(const QTestElement *element, char **formatted switch(element->elementType()){ case QTest::LET_TestCase: { QTestCharBuffer quotedTf; - QXmlTestLogger::xmlQuote(quotedTf, element->attributeValue(QTest::AI_Name)); + QXmlTestLogger::xmlQuote("edTf, element->attributeValue(QTest::AI_Name)); QTest::qt_asprintf(formatted, "\n", quotedTf.constData()); break; } case QTest::LET_Failure: { QTestCharBuffer cdataDesc; - QXmlTestLogger::xmlCdata(cdataDesc, element->attributeValue(QTest::AI_Description)); + QXmlTestLogger::xmlCdata(&cdataDesc, element->attributeValue(QTest::AI_Description)); QTestCharBuffer location; QTestCharBuffer quotedFile; - QXmlTestLogger::xmlQuote(quotedFile, element->attributeValue(QTest::AI_File)); + QXmlTestLogger::xmlQuote("edFile, element->attributeValue(QTest::AI_File)); - QTest::qt_asprintf(location, "%s=\"%s\" %s=\"%s\"", + QTest::qt_asprintf(&location, "%s=\"%s\" %s=\"%s\"", element->attributeName(QTest::AI_File), quotedFile.constData(), element->attributeName(QTest::AI_Line), @@ -89,7 +89,7 @@ void QTestXmlStreamer::formatStart(const QTestElement *element, char **formatted if (element->attribute(QTest::AI_Tag)) { QTestCharBuffer cdataTag; - QXmlTestLogger::xmlCdata(cdataTag, element->attributeValue(QTest::AI_Tag)); + QXmlTestLogger::xmlCdata(&cdataTag, element->attributeValue(QTest::AI_Tag)); QTest::qt_asprintf(formatted, "\n" " \n" " \n" @@ -108,8 +108,8 @@ void QTestXmlStreamer::formatStart(const QTestElement *element, char **formatted // assuming type and attribute names don't need quoting QTestCharBuffer quotedFile; QTestCharBuffer cdataDesc; - QXmlTestLogger::xmlQuote(quotedFile, element->attributeValue(QTest::AI_File)); - QXmlTestLogger::xmlCdata(cdataDesc, element->attributeValue(QTest::AI_Description)); + QXmlTestLogger::xmlQuote("edFile, element->attributeValue(QTest::AI_File)); + QXmlTestLogger::xmlCdata(&cdataDesc, element->attributeValue(QTest::AI_Description)); QTest::qt_asprintf(formatted, "\n \n\n", element->attributeValue(QTest::AI_Type), @@ -124,8 +124,8 @@ void QTestXmlStreamer::formatStart(const QTestElement *element, char **formatted // assuming value and iterations don't need quoting QTestCharBuffer quotedMetric; QTestCharBuffer quotedTag; - QXmlTestLogger::xmlQuote(quotedMetric, element->attributeValue(QTest::AI_Metric)); - QXmlTestLogger::xmlQuote(quotedTag, element->attributeValue(QTest::AI_Tag)); + QXmlTestLogger::xmlQuote("edMetric, element->attributeValue(QTest::AI_Metric)); + QXmlTestLogger::xmlQuote("edTag, element->attributeValue(QTest::AI_Tag)); QTest::qt_asprintf(formatted, "\n", element->attributeName(QTest::AI_Metric), @@ -139,23 +139,23 @@ void QTestXmlStreamer::formatStart(const QTestElement *element, char **formatted break; } default: - QTest::qt_asprintf(formatted, ""); + formatted->data()[0] = '\0'; } } -void QTestXmlStreamer::formatEnd(const QTestElement *element, char **formatted) const +void QTestXmlStreamer::formatEnd(const QTestElement *element, QTestCharBuffer *formatted) const { if(!element || !formatted) return; if (element->elementType() == QTest::LET_TestCase) { QTest::qt_asprintf(formatted, "\n"); + } else { + formatted->data()[0] = '\0'; } - else - QTest::qt_asprintf(formatted, ""); } -void QTestXmlStreamer::formatBeforeAttributes(const QTestElement *element, char **formatted) const +void QTestXmlStreamer::formatBeforeAttributes(const QTestElement *element, QTestCharBuffer *formatted) const { if(!element || !formatted) return; @@ -163,9 +163,9 @@ void QTestXmlStreamer::formatBeforeAttributes(const QTestElement *element, char if (element->elementType() == QTest::LET_TestCase && element->attribute(QTest::AI_Result)){ QTestCharBuffer buf; QTestCharBuffer quotedFile; - QXmlTestLogger::xmlQuote(quotedFile, element->attributeValue(QTest::AI_File)); + QXmlTestLogger::xmlQuote("edFile, element->attributeValue(QTest::AI_File)); - QTest::qt_asprintf(buf, "%s=\"%s\" %s=\"%s\"", + QTest::qt_asprintf(&buf, "%s=\"%s\" %s=\"%s\"", element->attributeName(QTest::AI_File), quotedFile.constData(), element->attributeName(QTest::AI_Line), @@ -174,12 +174,11 @@ void QTestXmlStreamer::formatBeforeAttributes(const QTestElement *element, char if( !element->childElements() ) { QTest::qt_asprintf(formatted, "\n", element->attributeValue(QTest::AI_Result), buf.constData()); + } else { + formatted->data()[0] = '\0'; } - else { - QTest::qt_asprintf(formatted, ""); - } - }else{ - QTest::qt_asprintf(formatted, ""); + } else { + formatted->data()[0] = '\0'; } } @@ -187,23 +186,23 @@ void QTestXmlStreamer::output(QTestElement *element) const { QTestCharBuffer buf; QTestCharBuffer quotedTc; - QXmlTestLogger::xmlQuote(quotedTc, QTestResult::currentTestObjectName()); + QXmlTestLogger::xmlQuote("edTc, QTestResult::currentTestObjectName()); - QTest::qt_asprintf(buf, "\n\n", + QTest::qt_asprintf(&buf, "\n\n", quotedTc.constData()); - outputString(buf); + outputString(buf.constData()); - QTest::qt_asprintf(buf, "\n %s\n %s\n", + QTest::qt_asprintf(&buf, "\n %s\n %s\n", qVersion(), QTEST_VERSION_STR ); - outputString(buf); + outputString(buf.constData()); - QTest::qt_asprintf(buf, "\n"); - outputString(buf); + QTest::qt_asprintf(&buf, "\n"); + outputString(buf.constData()); QTestBasicStreamer::output(element); - QTest::qt_asprintf(buf, "\n"); - outputString(buf); + QTest::qt_asprintf(&buf, "\n"); + outputString(buf.constData()); } QT_END_NAMESPACE diff --git a/src/testlib/qtestxmlstreamer.h b/src/testlib/qtestxmlstreamer.h index a601f60..6e1ae84 100644 --- a/src/testlib/qtestxmlstreamer.h +++ b/src/testlib/qtestxmlstreamer.h @@ -59,9 +59,9 @@ class QTestXmlStreamer: public QTestBasicStreamer QTestXmlStreamer(); ~QTestXmlStreamer(); - void formatStart(const QTestElement *element, char **formatted) const; - void formatEnd(const QTestElement *element, char **formatted) const; - void formatBeforeAttributes(const QTestElement *element, char **formatted) const; + void formatStart(const QTestElement *element, QTestCharBuffer *formatted) const; + void formatEnd(const QTestElement *element, QTestCharBuffer *formatted) const; + void formatBeforeAttributes(const QTestElement *element, QTestCharBuffer *formatted) const; void output(QTestElement *element) const; }; diff --git a/src/testlib/qtestxunitstreamer.cpp b/src/testlib/qtestxunitstreamer.cpp index d5d2631..932b70b 100644 --- a/src/testlib/qtestxunitstreamer.cpp +++ b/src/testlib/qtestxunitstreamer.cpp @@ -73,7 +73,7 @@ void QTestXunitStreamer::indentForElement(const QTestElement* element, char* buf } } -void QTestXunitStreamer::formatStart(const QTestElement *element, char **formatted) const +void QTestXunitStreamer::formatStart(const QTestElement *element, QTestCharBuffer *formatted) const { if(!element || !formatted ) return; @@ -85,8 +85,7 @@ void QTestXunitStreamer::formatStart(const QTestElement *element, char **formatt if (element->elementType() == QTest::LET_Error) { if (element->parentElement()->elementType() == QTest::LET_SystemError) { QTest::qt_asprintf(formatted, "elementName()); } -void QTestXunitStreamer::formatEnd(const QTestElement *element, char **formatted) const +void QTestXunitStreamer::formatEnd(const QTestElement *element, QTestCharBuffer *formatted) const { - if(!element || !formatted ) + if (!element || !formatted ) return; - if(!element->childElements()){ - QTest::qt_asprintf(formatted, ""); + if (!element->childElements()){ + formatted->data()[0] = '\0'; return; } @@ -111,7 +110,7 @@ void QTestXunitStreamer::formatEnd(const QTestElement *element, char **formatted QTest::qt_asprintf(formatted, "%s\n", indent, element->elementName()); } -void QTestXunitStreamer::formatAttributes(const QTestElement* element, const QTestElementAttribute *attribute, char **formatted) const +void QTestXunitStreamer::formatAttributes(const QTestElement* element, const QTestElementAttribute *attribute, QTestCharBuffer *formatted) const { if(!attribute || !formatted ) return; @@ -136,15 +135,14 @@ void QTestXunitStreamer::formatAttributes(const QTestElement* element, const QTe if (key) { QTestCharBuffer quotedValue; - QXmlTestLogger::xmlQuote(quotedValue, attribute->value()); + QXmlTestLogger::xmlQuote("edValue, attribute->value()); QTest::qt_asprintf(formatted, " %s=\"%s\"", key, quotedValue.constData()); - } - else { - QTest::qt_asprintf(formatted, ""); + } else { + formatted->data()[0] = '\0'; } } -void QTestXunitStreamer::formatAfterAttributes(const QTestElement *element, char **formatted) const +void QTestXunitStreamer::formatAfterAttributes(const QTestElement *element, QTestCharBuffer *formatted) const { if(!element || !formatted ) return; @@ -153,8 +151,7 @@ void QTestXunitStreamer::formatAfterAttributes(const QTestElement *element, char if (element->elementType() == QTest::LET_Error) { if (element->parentElement()->elementType() == QTest::LET_SystemError) { QTest::qt_asprintf(formatted, "]]>\n"); - } - else { + } else { QTest::qt_asprintf(formatted, " -->\n"); } return; @@ -187,22 +184,22 @@ void QTestXunitStreamer::outputElements(QTestElement *element, bool) const hasChildren = element->childElements(); if(element->elementType() != QTest::LET_Benchmark){ - formatStart(element, buf); - outputString(buf); + formatStart(element, &buf); + outputString(buf.data()); - formatBeforeAttributes(element, buf); - outputString(buf); + formatBeforeAttributes(element, &buf); + outputString(buf.data()); outputElementAttributes(element, element->attributes()); - formatAfterAttributes(element, buf); - outputString(buf); + formatAfterAttributes(element, &buf); + outputString(buf.data()); if(hasChildren) outputElements(element->childElements(), true); - formatEnd(element, buf); - outputString(buf); + formatEnd(element, &buf); + outputString(buf.data()); } element = element->previousElement(); } diff --git a/src/testlib/qtestxunitstreamer.h b/src/testlib/qtestxunitstreamer.h index 044307f..43ff03d 100644 --- a/src/testlib/qtestxunitstreamer.h +++ b/src/testlib/qtestxunitstreamer.h @@ -58,10 +58,10 @@ class QTestXunitStreamer: public QTestBasicStreamer QTestXunitStreamer(); ~QTestXunitStreamer(); - void formatStart(const QTestElement *element, char **formatted) const; - void formatEnd(const QTestElement *element, char **formatted) const; - void formatAfterAttributes(const QTestElement *element, char **formatted) const; - void formatAttributes(const QTestElement *element, const QTestElementAttribute *attribute, char **formatted) const; + void formatStart(const QTestElement *element, QTestCharBuffer *formatted) const; + void formatEnd(const QTestElement *element, QTestCharBuffer *formatted) const; + void formatAfterAttributes(const QTestElement *element, QTestCharBuffer *formatted) const; + void formatAttributes(const QTestElement *element, const QTestElementAttribute *attribute, QTestCharBuffer *formatted) const; void output(QTestElement *element) const; void outputElements(QTestElement *element, bool isChildElement = false) const; diff --git a/src/testlib/qxmltestlogger.cpp b/src/testlib/qxmltestlogger.cpp index fca7bfc..494acb4 100644 --- a/src/testlib/qxmltestlogger.cpp +++ b/src/testlib/qxmltestlogger.cpp @@ -108,19 +108,19 @@ void QXmlTestLogger::startLogging() if (xmlmode == QXmlTestLogger::Complete) { QTestCharBuffer quotedTc; - xmlQuote(quotedTc, QTestResult::currentTestObjectName()); - QTest::qt_asprintf(buf, + xmlQuote("edTc, QTestResult::currentTestObjectName()); + QTest::qt_asprintf(&buf, "\n" "\n", quotedTc.constData()); - outputString(buf); + outputString(buf.constData()); } - QTest::qt_asprintf(buf, + QTest::qt_asprintf(&buf, "\n" " %s\n" " "QTEST_VERSION_STR"\n" "\n", qVersion()); - outputString(buf); + outputString(buf.constData()); } void QXmlTestLogger::stopLogging() @@ -136,9 +136,9 @@ void QXmlTestLogger::enterTestFunction(const char *function) { QTestCharBuffer buf; QTestCharBuffer quotedFunction; - xmlQuote(quotedFunction, function); - QTest::qt_asprintf(buf, "\n", quotedFunction.constData()); - outputString(buf); + xmlQuote("edFunction, function); + QTest::qt_asprintf(&buf, "\n", quotedFunction.constData()); + outputString(buf.constData()); } void QXmlTestLogger::leaveTestFunction() @@ -219,12 +219,12 @@ void QXmlTestLogger::addIncident(IncidentTypes type, const char *description, QTestCharBuffer cdataTag; QTestCharBuffer cdataDescription; - xmlQuote(quotedFile, file); - xmlCdata(cdataGtag, gtag); - xmlCdata(cdataTag, tag); - xmlCdata(cdataDescription, description); + xmlQuote("edFile, file); + xmlCdata(&cdataGtag, gtag); + xmlCdata(&cdataTag, tag); + xmlCdata(&cdataDescription, description); - QTest::qt_asprintf(buf, + QTest::qt_asprintf(&buf, QTest::incidentFormatString(QTest::isEmpty(description), notag), QTest::xmlIncidentType2String(type), quotedFile.constData(), line, @@ -233,7 +233,7 @@ void QXmlTestLogger::addIncident(IncidentTypes type, const char *description, cdataTag.constData(), cdataDescription.constData()); - outputString(buf); + outputString(buf.constData()); } void QXmlTestLogger::addBenchmarkResult(const QBenchmarkResult &result) @@ -242,18 +242,18 @@ void QXmlTestLogger::addBenchmarkResult(const QBenchmarkResult &result) QTestCharBuffer quotedMetric; QTestCharBuffer quotedTag; - xmlQuote(quotedMetric, + xmlQuote("edMetric, QBenchmarkGlobalData::current->measurer->metricText().toAscii().constData()); - xmlQuote(quotedTag, result.context.tag.toAscii().constData()); + xmlQuote("edTag, result.context.tag.toAscii().constData()); QTest::qt_asprintf( - buf, + &buf, QTest::benchmarkResultFormatString(), quotedMetric.constData(), quotedTag.constData(), QByteArray::number(result.value).constData(), //no 64-bit qt_snprintf support result.iterations); - outputString(buf); + outputString(buf.constData()); } void QXmlTestLogger::addMessage(MessageTypes type, const char *message, @@ -270,12 +270,12 @@ void QXmlTestLogger::addMessage(MessageTypes type, const char *message, QTestCharBuffer cdataTag; QTestCharBuffer cdataDescription; - xmlQuote(quotedFile, file); - xmlCdata(cdataGtag, gtag); - xmlCdata(cdataTag, tag); - xmlCdata(cdataDescription, message); + xmlQuote("edFile, file); + xmlCdata(&cdataGtag, gtag); + xmlCdata(&cdataTag, tag); + xmlCdata(&cdataDescription, message); - QTest::qt_asprintf(buf, + QTest::qt_asprintf(&buf, QTest::messageFormatString(QTest::isEmpty(message), notag), QTest::xmlMessageType2String(type), quotedFile.constData(), line, @@ -284,7 +284,7 @@ void QXmlTestLogger::addMessage(MessageTypes type, const char *message, cdataTag.constData(), cdataDescription.constData()); - outputString(buf); + outputString(buf.constData()); } /* @@ -292,10 +292,11 @@ void QXmlTestLogger::addMessage(MessageTypes type, const char *message, XML characters as necessary so that dest is suitable for use in an XML quoted attribute string. */ -int QXmlTestLogger::xmlQuote(char* dest, char const* src, size_t n) +int QXmlTestLogger::xmlQuote(QTestCharBuffer* destBuf, char const* src, size_t n) { if (n == 0) return 0; + char *dest = destBuf->data(); *dest = 0; if (!src) return 0; @@ -351,10 +352,12 @@ int QXmlTestLogger::xmlQuote(char* dest, char const* src, size_t n) Copy up to n characters from the src string into dest, escaping any special strings such that dest is suitable for use in an XML CDATA section. */ -int QXmlTestLogger::xmlCdata(char* dest, char const* src, size_t n) +int QXmlTestLogger::xmlCdata(QTestCharBuffer *destBuf, char const* src, size_t n) { if (!n) return 0; + char *dest = destBuf->data(); + if (!src || n == 1) { *dest = 0; return 0; @@ -394,25 +397,23 @@ int QXmlTestLogger::xmlCdata(char* dest, char const* src, size_t n) return (dest-begin); } -typedef int (*StringFormatFunction)(char*,char const*,size_t); +typedef int (*StringFormatFunction)(QTestCharBuffer*,char const*,size_t); /* A wrapper for string functions written to work with a fixed size buffer so they can be called with a dynamically allocated buffer. */ -int allocateStringFn(char** str, char const* src, StringFormatFunction func) +int allocateStringFn(QTestCharBuffer* str, char const* src, StringFormatFunction func) { static const int MAXSIZE = 1024*1024*2; - int size = 32; - delete[] *str; - *str = new char[size]; + int size = str->size(); int res = 0; for (;;) { - res = func(*str, src, size); - (*str)[size - 1] = '\0'; + res = func(str, src, size); + str->data()[size - 1] = '\0'; if (res < size) { // We succeeded or fatally failed break; @@ -422,19 +423,19 @@ int allocateStringFn(char** str, char const* src, StringFormatFunction func) if (size > MAXSIZE) { break; } - delete[] *str; - *str = new char[size]; + if (!str->reset(size)) + break; // ran out of memory - bye } return res; } -int QXmlTestLogger::xmlQuote(char** str, char const* src) +int QXmlTestLogger::xmlQuote(QTestCharBuffer* str, char const* src) { return allocateStringFn(str, src, QXmlTestLogger::xmlQuote); } -int QXmlTestLogger::xmlCdata(char** str, char const* src) +int QXmlTestLogger::xmlCdata(QTestCharBuffer* str, char const* src) { return allocateStringFn(str, src, QXmlTestLogger::xmlCdata); } diff --git a/src/testlib/qxmltestlogger_p.h b/src/testlib/qxmltestlogger_p.h index a7cc00a..e14504c 100644 --- a/src/testlib/qxmltestlogger_p.h +++ b/src/testlib/qxmltestlogger_p.h @@ -79,10 +79,10 @@ public: void addMessage(MessageTypes type, const char *message, const char *file = 0, int line = 0); - static int xmlCdata(char** dest, char const* src); - static int xmlQuote(char** dest, char const* src); - static int xmlCdata(char* dest, char const* src, size_t n); - static int xmlQuote(char* dest, char const* src, size_t n); + static int xmlCdata(QTestCharBuffer *dest, char const* src); + static int xmlQuote(QTestCharBuffer *dest, char const* src); + static int xmlCdata(QTestCharBuffer *dest, char const* src, size_t n); + static int xmlQuote(QTestCharBuffer *dest, char const* src, size_t n); private: XmlMode xmlmode; -- cgit v0.12 From 56d84a7dcbbaee6402d1d43bba879b135839ad61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Fri, 7 Aug 2009 15:34:31 +0200 Subject: Don't crash if we are drawing an empty image. Reviewed-by: gunnar --- src/gui/painting/qpaintengine_raster.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 74456dd..b260f41 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -2542,6 +2542,9 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe qDebug() << " - QRasterPaintEngine::drawImage(), r=" << r << " sr=" << sr << " image=" << img.size() << "depth=" << img.depth(); #endif + if (r.isEmpty()) + return; + Q_D(QRasterPaintEngine); QRasterPaintEngineState *s = state(); const bool aa = s->flags.antialiased || s->flags.bilinear; -- cgit v0.12 From f99e01bccb5e2b686c0d98ea3743e9fcf48ce8d2 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Fri, 7 Aug 2009 16:09:45 +0200 Subject: Fix build warning gcc was complaining about format string not being a string literal. Also fixes the small chance that error messages would be bogus if they contain printf control characters. Reviewed-by: Bradley T. Hughes --- src/tools/uic/uic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/uic/uic.cpp b/src/tools/uic/uic.cpp index f789980..14576e2 100644 --- a/src/tools/uic/uic.cpp +++ b/src/tools/uic/uic.cpp @@ -184,7 +184,7 @@ DomUI *Uic::parseUiFile(QXmlStreamReader &reader) if (reader.hasError()) { delete ui; ui = 0; - fprintf(stderr, qPrintable(QString::fromLatin1("uic: Error in line %1, column %2 : %3\n") + fprintf(stderr, "%s\n", qPrintable(QString::fromLatin1("uic: Error in line %1, column %2 : %3") .arg(reader.lineNumber()).arg(reader.columnNumber()) .arg(reader.errorString()))); } -- cgit v0.12 From 132a319dc782ef1feebe6582fb6f05dc91df74bb Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Fri, 7 Aug 2009 07:28:27 -0700 Subject: Fix compiler error on GCC 4.2.0 mips/sh3 Before this patch gcc would fail with this message: internal compiler error: in add_virtual_operand, at tree-ssa-operands.c:1317 Reviewed-by: Volker Hilsheimer --- src/gui/graphicsview/qgraphicsview.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index ca55f2e..92f8816 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -2209,8 +2209,7 @@ QPolygonF QGraphicsView::mapToScene(const QRect &rect) const QPointF br = scrollOffset + r.bottomRight(); QPointF bl = scrollOffset + r.bottomLeft(); - QPolygonF poly; - poly.resize(4); + QPolygonF poly(4); if (!d->identityMatrix) { QTransform x = d->matrix.inverted(); poly[0] = x.map(tl); @@ -2313,8 +2312,7 @@ QPolygon QGraphicsView::mapFromScene(const QRectF &rect) const br -= scrollOffset; bl -= scrollOffset; - QPolygon poly; - poly.resize(4); + QPolygon poly(4); poly[0] = tl.toPoint(); poly[1] = tr.toPoint(); poly[2] = br.toPoint(); @@ -3647,8 +3645,7 @@ QRectF QGraphicsViewPrivate::mapToScene(const QRectF &rect) const QPointF br = scrollOffset + rect.bottomRight(); QPointF bl = scrollOffset + rect.bottomLeft(); - QPolygonF poly; - poly.resize(4); + QPolygonF poly(4); if (!identityMatrix) { QTransform x = matrix.inverted(); poly[0] = x.map(tl); -- cgit v0.12 From d13418effc5f00474541ae513a30c9a42c2a1cb3 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 7 Aug 2009 17:14:31 +0200 Subject: QItemSelectionModel did not send selectionChanged signal when deleting an item in a tree-like model with one of its grand-children being selected. Added recursive deselection for the model. Task-number: 232634 Reviewed-by: thierry --- src/gui/itemviews/qitemselectionmodel.cpp | 22 +++++++++++++++++++- src/gui/itemviews/qitemselectionmodel_p.h | 2 ++ .../tst_qitemselectionmodel.cpp | 24 ++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/gui/itemviews/qitemselectionmodel.cpp b/src/gui/itemviews/qitemselectionmodel.cpp index 9dad95f..0f35ac1 100644 --- a/src/gui/itemviews/qitemselectionmodel.cpp +++ b/src/gui/itemviews/qitemselectionmodel.cpp @@ -593,10 +593,30 @@ void QItemSelectionModelPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &pare // update selectionsx QModelIndex tl = model->index(start, 0, parent); QModelIndex br = model->index(end, model->columnCount(parent) - 1, parent); - q->select(QItemSelection(tl, br), QItemSelectionModel::Deselect); + recursiveDeselect(QItemSelectionRange(tl, br)); finalize(); } +void QItemSelectionModelPrivate::recursiveDeselect(const QItemSelectionRange &range) +{ + Q_Q(QItemSelectionModel); + + QItemSelection sel(range.topLeft(), range.bottomRight()); + q->select(sel, QItemSelectionModel::Deselect); + + QModelIndexList idxList = range.indexes(); + QModelIndexList::const_iterator it = idxList.begin(); + for (; it != idxList.end(); ++it) + { + if (!model->hasChildren(*it)) + continue; + + const QModelIndex &firstChild = it->child(0,0); + const QModelIndex &lastChild = it->child(model->rowCount(*it) - 1, model->columnCount(*it) - 1); + recursiveDeselect(QItemSelectionRange(firstChild, lastChild)); + } +} + /*! \internal */ diff --git a/src/gui/itemviews/qitemselectionmodel_p.h b/src/gui/itemviews/qitemselectionmodel_p.h index 18ad506..8176d4c 100644 --- a/src/gui/itemviews/qitemselectionmodel_p.h +++ b/src/gui/itemviews/qitemselectionmodel_p.h @@ -77,6 +77,8 @@ public: void _q_layoutAboutToBeChanged(); void _q_layoutChanged(); + void recursiveDeselect(const QItemSelectionRange &range); + inline void remove(QList &r) { QList::const_iterator it = r.constBegin(); diff --git a/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp b/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp index 0541b46..05e23f1 100644 --- a/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp +++ b/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp @@ -90,6 +90,7 @@ private slots: void merge(); void task119433_isRowSelected(); void task252069_rowIntersectsSelection(); + void task232634_childrenDeselectionSignal(); private: QAbstractItemModel *model; @@ -2187,5 +2188,28 @@ void tst_QItemSelectionModel::task252069_rowIntersectsSelection() QVERIFY(!selected.columnIntersectsSelection(5, QModelIndex())); } +void tst_QItemSelectionModel::task232634_childrenDeselectionSignal() +{ + QStandardItemModel model; + + QStandardItem *parentItem = model.invisibleRootItem(); + for (int i = 0; i < 4; ++i) { + QStandardItem *item = new QStandardItem(QString("item %0").arg(i)); + parentItem->appendRow(item); + parentItem = item; + } + + QModelIndex root = model.index(0,0); + QModelIndex par = root.child(0,0); + QModelIndex sel = par.child(0,0); + + QItemSelectionModel selectionModel(&model); + selectionModel.select(sel, QItemSelectionModel::SelectCurrent); + + QSignalSpy deselectSpy(&selectionModel, SIGNAL(selectionChanged(const QItemSelection& , const QItemSelection&))); + model.removeRows(0, 1, root); + QVERIFY(deselectSpy.count() == 1); +} + QTEST_MAIN(tst_QItemSelectionModel) #include "tst_qitemselectionmodel.moc" -- cgit v0.12 From e54e4f19ec2fd06f9d383b2cd83a565479e3cced Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Mon, 10 Aug 2009 10:36:01 +1000 Subject: Add a private function for conversion a QPixmap into a VGImage Custom OpenVG pixmap filters written by users will need to access the VGImage form of a QPixmap. The qPixmapToVGImage() function is provided for this purpose, as a private API. Reviewed-by: Sarah Smith --- src/openvg/qpixmapdata_vg.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index 90fd9a5..6f2024f 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -341,4 +341,29 @@ QImage::Format QVGPixmapData::sourceFormat() const return QImage::Format_ARGB32_Premultiplied; } +/* + \internal + + Returns the VGImage that is storing the contents of \a pixmap. + Returns VG_INVALID_HANDLE if \a pixmap is not owned by the OpenVG + graphics system or \a pixmap is invalid. + + This function is typically used to access the backing store + for a pixmap when executing raw OpenVG calls. It must only + be used when a QPainter is active and the OpenVG paint engine + is in use by the QPainter. + + \sa {QtOpenVG Module} +*/ +Q_OPENVG_EXPORT VGImage qPixmapToVGImage(const QPixmap& pixmap) +{ + QPixmapData *pd = pixmap.pixmapData(); + if (pd->classId() == QPixmapData::OpenVGClass) { + QVGPixmapData *vgpd = static_cast(pd); + if (vgpd->isValid()) + return vgpd->toVGImage(); + } + return VG_INVALID_HANDLE; +} + QT_END_NAMESPACE -- cgit v0.12 From 341ba562a81c4be1264020c207a940d5c7fd5de7 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Mon, 10 Aug 2009 14:27:49 +1000 Subject: Make checksdk give a nonzero exit code when it's asked for an SDK which isn't available. Reviewed-by: Michael Goddard --- tools/checksdk/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/checksdk/main.cpp b/tools/checksdk/main.cpp index 6322eb7..b36aa32 100644 --- a/tools/checksdk/main.cpp +++ b/tools/checksdk/main.cpp @@ -161,5 +161,5 @@ int main(int argc, char **argv) } } qWarning("Could not find specified SDK: %s" , qPrintable(sdkName)); - return 0; -} \ No newline at end of file + return -1; +} -- cgit v0.12 From bb97f90ef340d668f3dc04026aa034b33a997453 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Mon, 10 Aug 2009 14:47:13 +1000 Subject: Set default QGraphicsTransform3D axis to (0, 0, 1) The docs said that the default axis was (0, 0, 1), but the code and unit tests were using (0, 0, 0). Modify the code to match the docs because (0, 0, 0) is not very useful. Also optimize the calculation of sin/cos values for 90, 180, and 270 degrees. Reviewed-by: Aaron Kennedy --- src/gui/graphicsview/qgraphicstransform.cpp | 37 +++++++++++++++------- .../qgraphicstransform/tst_qgraphicstransform.cpp | 22 ++++++++++++- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/gui/graphicsview/qgraphicstransform.cpp b/src/gui/graphicsview/qgraphicstransform.cpp index 778cd94..ae88641 100644 --- a/src/gui/graphicsview/qgraphicstransform.cpp +++ b/src/gui/graphicsview/qgraphicstransform.cpp @@ -80,11 +80,7 @@ #include "qgraphicsitem_p.h" #include "qgraphicstransform_p.h" #include - -#include -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif +#include QT_BEGIN_NAMESPACE @@ -355,7 +351,6 @@ public: QGraphicsRotationPrivate() : angle(0) {} QPointF origin; - qreal originY; qreal angle; }; @@ -475,13 +470,18 @@ void QGraphicsRotation::applyTo(QTransform *t) const By default the axis is (0, 0, 1), giving QGraphicsRotation3D the same default behavior as QGraphicsRotation (i.e., rotation around the Z axis). + Note: the final rotation is the combined effect of a rotation in + 3D space followed by a projection back to 2D. If several rotations + are performed in succession, they will not behave as expected unless + they were all around the Z axis. + \sa QGraphicsTransform, QGraphicsItem::setRotation(), QTransform::rotate() */ class QGraphicsRotation3DPrivate : public QGraphicsRotationPrivate { public: - QGraphicsRotation3DPrivate() {} + QGraphicsRotation3DPrivate() : axis(0, 0, 1) {} QVector3D axis; }; @@ -526,6 +526,7 @@ void QGraphicsRotation3D::setAxis(const QVector3D &axis) update(); } +const qreal deg2rad = qreal(0.017453292519943295769); // pi/180 static const qreal inv_dist_to_plane = 1. / 1024.; /*! @@ -535,13 +536,27 @@ void QGraphicsRotation3D::applyTo(QTransform *t) const { Q_D(const QGraphicsRotation3D); - if (d->angle == 0. || + qreal a = d->angle; + + if (a == 0. || (d->axis.z() == 0. && d->axis.y() == 0 && d->axis.x() == 0)) return; - qreal rad = d->angle * 2. * M_PI / 360.; - qreal c = ::cos(rad); - qreal s = ::sin(rad); + qreal c, s; + if (a == 90. || a == -270.) { + s = 1.; + c = 0.; + } else if (a == 270. || a == -90.) { + s = -1.; + c = 0.; + } else if (a == 180.) { + s = 0.; + c = -1.; + } else { + qreal b = deg2rad*a; + s = qSin(b); + c = qCos(b); + } qreal x = d->axis.x(); qreal y = d->axis.y(); diff --git a/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp b/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp index 672b1f1..c9481da 100644 --- a/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp +++ b/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp @@ -137,7 +137,10 @@ void tst_QGraphicsTransform::rotation() void tst_QGraphicsTransform::rotation3d() { QGraphicsRotation3D rotation; - rotation.setOrigin(QPointF(10, 10)); + QCOMPARE(rotation.axis().x(), (qreal)0); + QCOMPARE(rotation.axis().y(), (qreal)0); + QCOMPARE(rotation.axis().z(), (qreal)1); + QCOMPARE(rotation.angle(), (qreal)0); QTransform t; rotation.applyTo(&t); @@ -147,6 +150,23 @@ void tst_QGraphicsTransform::rotation3d() rotation.setAngle(180); + QTransform t180; + t180.rotate(180.0f); + + QCOMPARE(t, QTransform()); + QVERIFY(qFuzzyCompare(rotation.transform(), t180)); + + rotation.setAxis(QVector3D(0, 0, 0)); + rotation.setOrigin(QPointF(10, 10)); + + t = QTransform(); + rotation.applyTo(&t); + + QCOMPARE(t, QTransform()); + QCOMPARE(rotation.transform(), QTransform()); + + rotation.setAngle(180); + QCOMPARE(t, QTransform()); QCOMPARE(rotation.transform(), QTransform()); -- cgit v0.12 From 5d01d0cde28f2ac1ff9b5d8ca731edcf38725051 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Mon, 10 Aug 2009 15:31:00 +1000 Subject: Emit axisChanged() when the QGraphicsRotation3D axis changes. Reviewed-by: Aaron Kennedy --- src/gui/graphicsview/qgraphicstransform.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/graphicsview/qgraphicstransform.cpp b/src/gui/graphicsview/qgraphicstransform.cpp index ae88641..775a0d5 100644 --- a/src/gui/graphicsview/qgraphicstransform.cpp +++ b/src/gui/graphicsview/qgraphicstransform.cpp @@ -522,8 +522,11 @@ QVector3D QGraphicsRotation3D::axis() void QGraphicsRotation3D::setAxis(const QVector3D &axis) { Q_D(QGraphicsRotation3D); + if (d->axis == axis) + return; d->axis = axis; update(); + emit axisChanged(); } const qreal deg2rad = qreal(0.017453292519943295769); // pi/180 -- cgit v0.12 From 6cc14b9bd84de30471db40f73b119ba33356a6ba Mon Sep 17 00:00:00 2001 From: Keith Isdale Date: Mon, 10 Aug 2009 17:19:20 +1000 Subject: In a .pro file the include() function does not warn if specified file can not be found change that behavior to warn by default. Currently the default behavior of include() in a .pro file is not to warn if the supplied file argument can not be found which can lead to hard to find build errors. The include() will now,by default, warn if the specified file can not be found. If a warning is not required because the included file is optional then example use in the .pro file: include(SomePriFile.pri", "", true) Task-number:259398 Reviewed-by:Marius Storm-Olsen --- mkspecs/features/qt_config.prf | 2 +- qmake/project.cpp | 13 +++++++++---- src/3rdparty/webkit/WebCore/WebCore.pro | 2 +- src/corelib/arch/arch.pri | 2 +- src/qbase.pri | 2 +- src/xmlpatterns/query.pri | 2 +- src/xmlpatterns/xmlpatterns.pro | 2 +- tests/auto/qaccessibility_mac/qaccessibility_mac.pro | 2 +- tests/auto/qmake/testdata/functions/functions.pro | 2 +- tools/assistant/compat/lib/lib.pro | 2 +- tools/designer/src/components/lib/lib.pro | 2 +- tools/designer/src/lib/lib.pro | 2 +- tools/designer/src/uitools/uitools.pro | 2 +- 13 files changed, 21 insertions(+), 16 deletions(-) diff --git a/mkspecs/features/qt_config.prf b/mkspecs/features/qt_config.prf index 779c2e5..0a2d985 100644 --- a/mkspecs/features/qt_config.prf +++ b/mkspecs/features/qt_config.prf @@ -4,7 +4,7 @@ isEmpty(QMAKE_QT_CONFIG)|!exists($$QMAKE_QT_CONFIG) { else:exists($$_QMAKE_CACHE_):infile($$_QMAKE_CACHE_, QT_BUILD_TREE):QMAKE_QT_CONFIG = $$fromfile($$_QMAKE_CACHE_, QT_BUILD_TREE)/mkspecs/qconfig.pri else:exists($$[QT_INSTALL_DATA]/mkspecs/qconfig.pri):QMAKE_QT_CONFIG = $$[QT_INSTALL_DATA]/mkspecs/qconfig.pri } -!exists($$QMAKE_QT_CONFIG)|!include($$QMAKE_QT_CONFIG) { +!exists($$QMAKE_QT_CONFIG)|!include($$QMAKE_QT_CONFIG, "", true) { debug(1, "Cannot load qconfig.pri!") } else { debug(1, "Loaded .qconfig.pri from ($$QMAKE_QT_CONFIG)") diff --git a/qmake/project.cpp b/qmake/project.cpp index 4fefbab..6687e9a 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -2693,10 +2693,15 @@ QMakeProject::doProjectTest(QString func, QList args_list, QMap= 2) { if(func_t == T_INCLUDE) { parseInto = args[1]; + if (args.count() == 3){ + QString sarg = args[2]; + if (sarg.toLower() == "true" || sarg.toInt()) + ignore_error = true; + } } else { QString sarg = args[1]; ignore_error = (sarg.toLower() == "true" || sarg.toInt()); @@ -2738,8 +2743,8 @@ QMakeProject::doProjectTest(QString func, QList args_list, QMap= IncludeFailure) { diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro index e49ab13..2eb7c08 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pro +++ b/src/3rdparty/webkit/WebCore/WebCore.pro @@ -3159,7 +3159,7 @@ xpathbison.dependency_type = TYPE_C xpathbison.variable_out = GENERATED_SOURCES addExtraCompilerWithHeader(xpathbison) -include($$PWD/../WebKit/qt/Api/headers.pri) +include($$PWD/../WebKit/qt/Api/headers.pri, "", true) HEADERS += $$WEBKIT_API_HEADERS !CONFIG(QTDIR_build) { target.path = $$[QT_INSTALL_LIBS] diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri index dd3141a..18f54ee 100644 --- a/src/corelib/arch/arch.pri +++ b/src/corelib/arch/arch.pri @@ -25,4 +25,4 @@ vxworks:HEADERS += arch/qatomic_vxworks.h QT_ARCH_CPP = $$QT_SOURCE_TREE/src/corelib/arch/$$QT_ARCH DEPENDPATH += $$QT_ARCH_CPP -include($$QT_ARCH_CPP/arch.pri) +include($$QT_ARCH_CPP/arch.pri, "", true) diff --git a/src/qbase.pri b/src/qbase.pri index 0ab04e6..9e2d26f 100644 --- a/src/qbase.pri +++ b/src/qbase.pri @@ -13,7 +13,7 @@ mac:!contains(QMAKE_EXT_C, .mm):QMAKE_EXT_C += .mm #load up the headers info CONFIG += qt_install_headers HEADERS_PRI = $$QT_BUILD_TREE/include/$$TARGET/headers.pri -include($$HEADERS_PRI)|clear(HEADERS_PRI) +include($$HEADERS_PRI, "", true)|clear(HEADERS_PRI) #version overriding win32 { diff --git a/src/xmlpatterns/query.pri b/src/xmlpatterns/query.pri index e09a618..fab1940 100644 --- a/src/xmlpatterns/query.pri +++ b/src/xmlpatterns/query.pri @@ -11,4 +11,4 @@ include($$PWD/parser/parser.pri) include($$PWD/projection/projection.pri) include($$PWD/type/type.pri) include($$PWD/utils/utils.pri) -include($$PWD/qobjectmodel/qobjectmodel.pri) +include($$PWD/qobjectmodel/qobjectmodel.pri, "", true) diff --git a/src/xmlpatterns/xmlpatterns.pro b/src/xmlpatterns/xmlpatterns.pro index fb6aa1a..0e6270e 100644 --- a/src/xmlpatterns/xmlpatterns.pro +++ b/src/xmlpatterns/xmlpatterns.pro @@ -25,7 +25,7 @@ include($$PWD/schema/schema.pri) include($$PWD/schematron/schematron.pri) include($$PWD/type/type.pri) include($$PWD/utils/utils.pri) -include($$PWD/qobjectmodel/qobjectmodel.pri) +include($$PWD/qobjectmodel/qobjectmodel.pri, "", true) wince*: { # The Microsoft MIPS compiler crashes if /Og is specified diff --git a/tests/auto/qaccessibility_mac/qaccessibility_mac.pro b/tests/auto/qaccessibility_mac/qaccessibility_mac.pro index b32a7e5..47f72d1 100644 --- a/tests/auto/qaccessibility_mac/qaccessibility_mac.pro +++ b/tests/auto/qaccessibility_mac/qaccessibility_mac.pro @@ -11,7 +11,7 @@ requires(mac) # builds (where QTDIR points to the build directory). # autotest + shadow build is not supported :) exists($$(QTDIR)/tools/designer/src/lib/uilib/uilib.pri) { - include($$(QTDIR)/tools/designer/src/lib/uilib/uilib.pri) + include($$(QTDIR)/tools/designer/src/lib/uilib/uilib.pri, "", true) INCLUDEPATH += $$(QTDIR)/tools/designer/src/uitools SOURCES += $$(QTDIR)/tools/designer/src/uitools/quiloader.cpp HEADERS += $$(QTDIR)/tools/designer/src/uitools/quiloader.h diff --git a/tests/auto/qmake/testdata/functions/functions.pro b/tests/auto/qmake/testdata/functions/functions.pro index 9ed92f96..5e089e4 100644 --- a/tests/auto/qmake/testdata/functions/functions.pro +++ b/tests/auto/qmake/testdata/functions/functions.pro @@ -46,7 +46,7 @@ isEmpty( CONFIG ) { } #include -include( infiletest.pro ) +include( infiletest.pro, "", true ) !contains( DEFINES, QT_DLL ) { message( "FAILED: include function: $$DEFINES" ) } diff --git a/tools/assistant/compat/lib/lib.pro b/tools/assistant/compat/lib/lib.pro index d4b5a47..e50d470 100644 --- a/tools/assistant/compat/lib/lib.pro +++ b/tools/assistant/compat/lib/lib.pro @@ -32,7 +32,7 @@ contains(CONFIG, static) { #load up the headers info CONFIG += qt_install_headers HEADERS_PRI = $$QT_BUILD_TREE/include/QtAssistant/headers.pri -include($$HEADERS_PRI)|clear(HEADERS_PRI) +include($$HEADERS_PRI, "", true)|clear(HEADERS_PRI) #mac frameworks mac:!static:contains(QT_CONFIG, qt_framework) { diff --git a/tools/designer/src/components/lib/lib.pro b/tools/designer/src/components/lib/lib.pro index 4515b66..92cf387 100644 --- a/tools/designer/src/components/lib/lib.pro +++ b/tools/designer/src/components/lib/lib.pro @@ -24,7 +24,7 @@ QMAKE_TARGET_DESCRIPTION = Graphical user interface designer. #load up the headers info CONFIG += qt_install_headers HEADERS_PRI = $$QT_BUILD_TREE/include/QtDesigner/headers.pri -include($$HEADERS_PRI)|clear(HEADERS_PRI) +include($$HEADERS_PRI, "", true)|clear(HEADERS_PRI) #mac frameworks mac:!static:contains(QT_CONFIG, qt_framework) { diff --git a/tools/designer/src/lib/lib.pro b/tools/designer/src/lib/lib.pro index e0f2f23..495976d 100644 --- a/tools/designer/src/lib/lib.pro +++ b/tools/designer/src/lib/lib.pro @@ -34,7 +34,7 @@ QMAKE_TARGET_DESCRIPTION = Graphical user interface designer. #load up the headers info CONFIG += qt_install_headers HEADERS_PRI = $$QT_BUILD_TREE/include/QtDesigner/headers.pri -include($$HEADERS_PRI)|clear(HEADERS_PRI) +include($$HEADERS_PRI, "", true)|clear(HEADERS_PRI) #mac frameworks mac:CONFIG += explicitlib diff --git a/tools/designer/src/uitools/uitools.pro b/tools/designer/src/uitools/uitools.pro index a20abf0..34e4877 100644 --- a/tools/designer/src/uitools/uitools.pro +++ b/tools/designer/src/uitools/uitools.pro @@ -22,7 +22,7 @@ include(../lib/uilib/uilib.pri) HEADERS += quiloader.h SOURCES += quiloader.cpp -include($$QT_BUILD_TREE/include/QtUiTools/headers.pri) +include($$QT_BUILD_TREE/include/QtUiTools/headers.pri, "", true) quitools_headers.files = $$SYNCQT.HEADER_FILES $$SYNCQT.HEADER_CLASSES quitools_headers.path = $$[QT_INSTALL_HEADERS]/QtUiTools INSTALLS += quitools_headers -- cgit v0.12 From 2be387f3e94f84cf0167cdc3871de0d0af85c62d Mon Sep 17 00:00:00 2001 From: David Faure Date: Mon, 10 Aug 2009 09:37:18 +0200 Subject: Make QTimeLine::start() restart from the beginning as the documentation says. The documentation implies that start restarts. Which it did, but only if the timeline was finished _and_ the duration hadn't been changed meanwhile. So after a setDuration(), start() would do nothing, which was unexpected. Merge-request: 1145 Reviewed-by: Olivier Goffart --- src/corelib/tools/qtimeline.cpp | 9 ++++---- tests/auto/qtimeline/tst_qtimeline.cpp | 41 +++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/corelib/tools/qtimeline.cpp b/src/corelib/tools/qtimeline.cpp index e32fc03..7402ba6 100644 --- a/src/corelib/tools/qtimeline.cpp +++ b/src/corelib/tools/qtimeline.cpp @@ -663,6 +663,7 @@ qreal QTimeLine::valueForTime(int msec) const second). You can change the update interval by calling setUpdateInterval(). + The timeline will start from position 0, or the end if going backward. If you want to resume a stopped timeline without restarting, you can call resume() instead. @@ -675,10 +676,8 @@ void QTimeLine::start() qWarning("QTimeLine::start: already running"); return; } - int curTime = d->currentTime; - if (curTime == d->duration && d->direction == Forward) - curTime = 0; - else if (curTime == 0 && d->direction == Backward) + int curTime = 0; + if (d->direction == Backward) curTime = d->duration; d->timerId = startTimer(d->updateInterval); d->startTime = curTime; @@ -694,7 +693,7 @@ void QTimeLine::start() frame and value at regular intervals. In contrast to start(), this function does not restart the timeline before - is resumes. + it resumes. \sa start(), updateInterval(), frameChanged(), valueChanged() */ diff --git a/tests/auto/qtimeline/tst_qtimeline.cpp b/tests/auto/qtimeline/tst_qtimeline.cpp index e6e75ff..4ce1f4b 100644 --- a/tests/auto/qtimeline/tst_qtimeline.cpp +++ b/tests/auto/qtimeline/tst_qtimeline.cpp @@ -81,6 +81,7 @@ private slots: void outOfRange(); void stateInFinishedSignal(); void resume(); + void restart(); protected slots: void finishedSlot(); @@ -177,7 +178,7 @@ void tst_QTimeLine::currentTime() QCOMPARE(spy.count(), 1); spy.clear(); QCOMPARE(timeLine.currentTime(), timeLine.duration()/2); - timeLine.start(); + timeLine.resume(); // Let it update on its own QTest::qWait(timeLine.duration()/4); QCOMPARE(timeLine.state(), QTimeLine::Running); @@ -699,5 +700,43 @@ void tst_QTimeLine::resume() } } +void tst_QTimeLine::restart() +{ + QTimeLine timeLine(100); + timeLine.setFrameRange(0,9); + + timeLine.start(); + QTest::qWait(timeLine.duration()*2); + QCOMPARE(timeLine.currentFrame(), timeLine.endFrame()); + QCOMPARE(timeLine.state(), QTimeLine::NotRunning); + + // A restart with the same duration + timeLine.start(); + QCOMPARE(timeLine.state(), QTimeLine::Running); + QCOMPARE(timeLine.currentFrame(), timeLine.startFrame()); + QCOMPARE(timeLine.currentTime(), 0); + QTest::qWait(250); + QCOMPARE(timeLine.currentFrame(), timeLine.endFrame()); + QCOMPARE(timeLine.state(), QTimeLine::NotRunning); + + // Set a smaller duration and restart + timeLine.setDuration(50); + timeLine.start(); + QCOMPARE(timeLine.state(), QTimeLine::Running); + QCOMPARE(timeLine.currentFrame(), timeLine.startFrame()); + QCOMPARE(timeLine.currentTime(), 0); + QTest::qWait(250); + QCOMPARE(timeLine.currentFrame(), timeLine.endFrame()); + QCOMPARE(timeLine.state(), QTimeLine::NotRunning); + + // Set a longer duration and restart + timeLine.setDuration(150); + timeLine.start(); + QCOMPARE(timeLine.state(), QTimeLine::Running); + QCOMPARE(timeLine.currentFrame(), timeLine.startFrame()); + QCOMPARE(timeLine.currentTime(), 0); +} + QTEST_MAIN(tst_QTimeLine) + #include "tst_qtimeline.moc" -- cgit v0.12 From 7aa2d76dfc4a107f38c5cb0aac00a0b31d0fbbb6 Mon Sep 17 00:00:00 2001 From: Morten Sorvig Date: Mon, 10 Aug 2009 10:14:12 +0200 Subject: Add QBENCMARK_ONCE to QTestLib. The code block associated with QBENCHMARK_ONCE macro will only be executed once, whether the backend returns a valid result or not. The "-iterations" command line argument is also ignored. This is useful for benchmarking code that has side effects. Revby: jasplin --- src/testlib/qbenchmark.cpp | 13 +++++++++++-- src/testlib/qbenchmark.h | 10 ++++++++-- src/testlib/qbenchmark_p.h | 1 + src/testlib/qtestcase.cpp | 19 +++++++++++++++++++ .../benchlibwalltime/tst_benchlibwalltime.cpp | 11 +++++++++++ tests/auto/selftests/expected_benchlibwalltime.txt | 5 ++++- 6 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/testlib/qbenchmark.cpp b/src/testlib/qbenchmark.cpp index 9cdf232..bad3379 100644 --- a/src/testlib/qbenchmark.cpp +++ b/src/testlib/qbenchmark.cpp @@ -116,7 +116,7 @@ int QBenchmarkGlobalData::adjustMedianIterationCount() QBenchmarkTestMethodData *QBenchmarkTestMethodData::current; QBenchmarkTestMethodData::QBenchmarkTestMethodData() -:resultAccepted(false), iterationCount(-1) +:resultAccepted(false), runOnce(false), iterationCount(-1) { } @@ -157,6 +157,11 @@ void QBenchmarkTestMethodData::setResult(qint64 value) if (QBenchmarkGlobalData::current->iterationCount != -1) accepted = true; + if (QBenchmarkTestMethodData::current->runOnce) { + iterationCount = 1; + accepted = true; + } + // Test the result directly without calling the measurer if the minimum time // has been specifed on the command line with -minimumvalue. else if (QBenchmarkGlobalData::current->walltimeMinimum != -1) @@ -179,10 +184,12 @@ void QBenchmarkTestMethodData::setResult(qint64 value) drive the benchmarking loop. It is repsonsible for starting and stopping the timing measurements as well as calling the result reporting functions. */ -QTest::QBenchmarkIterationController::QBenchmarkIterationController() +QTest::QBenchmarkIterationController::QBenchmarkIterationController(RunMode runMode) { QTest::beginBenchmarkMeasurement(); i = 0; + if (runMode == RunOnce) + QBenchmarkTestMethodData::current->runOnce = true; } /*! \internal */ @@ -195,6 +202,8 @@ QTest::QBenchmarkIterationController::~QBenchmarkIterationController() */ bool QTest::QBenchmarkIterationController::isDone() { + if (QBenchmarkTestMethodData::current->runOnce) + return i > 0; return i >= QTest::iterationCount(); } diff --git a/src/testlib/qbenchmark.h b/src/testlib/qbenchmark.h index c06bfc0..87d34e7 100644 --- a/src/testlib/qbenchmark.h +++ b/src/testlib/qbenchmark.h @@ -64,7 +64,8 @@ namespace QTest class Q_TESTLIB_EXPORT QBenchmarkIterationController { public: - QBenchmarkIterationController(); + enum RunMode { RepeatUntilValidMeasurement, RunOnce }; + QBenchmarkIterationController(RunMode runMode); ~QBenchmarkIterationController(); bool isDone(); void next(); @@ -74,7 +75,12 @@ public: } #define QBENCHMARK \ - for (QTest::QBenchmarkIterationController __iteration_controller; __iteration_controller.isDone() == false; __iteration_controller.next()) + for (QTest::QBenchmarkIterationController __iteration_controller(QTest::QBenchmarkIterationController::RepeatUntilValidMeasurement); \ + __iteration_controller.isDone() == false; __iteration_controller.next()) + +#define QBENCHMARK_ONCE \ + for (QTest::QBenchmarkIterationController __iteration_controller(QTest::QBenchmarkIterationController::RunOnce); \ + __iteration_controller.isDone() == false; __iteration_controller.next()) QT_END_NAMESPACE diff --git a/src/testlib/qbenchmark_p.h b/src/testlib/qbenchmark_p.h index 25f9cdc..185d656 100644 --- a/src/testlib/qbenchmark_p.h +++ b/src/testlib/qbenchmark_p.h @@ -171,6 +171,7 @@ public: QBenchmarkResult result; bool resultAccepted; + bool runOnce; int iterationCount; }; diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 1866197..21a686e 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -351,6 +351,25 @@ QT_BEGIN_NAMESPACE {Chapter 5: Writing a Benchmark}{Writing a Benchmark} */ +/*! + \macro QBENCHMARK_ONCE + + \relates QTest + + This macro is used to measure the performance of code within a test. + The code to be benchmarked is contained within a code block following + this macro. + + Unlike QBENCHMARK, the contents of the contained code block is only run + once. The elapsed time will be reported as "0" if it's to short to + be measured by the selected backend. (Use) + + \sa {QTestLib Manual#Creating a Benchmark}{Creating a Benchmark}, + {Chapter 5: Writing a Benchmark}{Writing a Benchmark} +*/ + + + /*! \enum QTest::SkipMode This enum describes the modes for skipping tests during execution diff --git a/tests/auto/selftests/benchlibwalltime/tst_benchlibwalltime.cpp b/tests/auto/selftests/benchlibwalltime/tst_benchlibwalltime.cpp index de65599..8474144f 100644 --- a/tests/auto/selftests/benchlibwalltime/tst_benchlibwalltime.cpp +++ b/tests/auto/selftests/benchlibwalltime/tst_benchlibwalltime.cpp @@ -50,6 +50,7 @@ class tst_BenchlibWalltime: public QObject private slots: void waitForOneThousand(); void waitForFourThousand(); + void qbenchmark_once(); }; void tst_BenchlibWalltime::waitForOneThousand() @@ -66,6 +67,16 @@ void tst_BenchlibWalltime::waitForFourThousand() } } +void tst_BenchlibWalltime::qbenchmark_once() +{ + int iterations = 0; + QBENCHMARK_ONCE { + ++iterations; + } + QCOMPARE(iterations, 1); +} + + QTEST_MAIN(tst_BenchlibWalltime) #include "tst_benchlibwalltime.moc" diff --git a/tests/auto/selftests/expected_benchlibwalltime.txt b/tests/auto/selftests/expected_benchlibwalltime.txt index 03f2465..ec2d020 100644 --- a/tests/auto/selftests/expected_benchlibwalltime.txt +++ b/tests/auto/selftests/expected_benchlibwalltime.txt @@ -7,6 +7,9 @@ PASS : tst_BenchlibWalltime::waitForOneThousand() RESULT : tst_BenchlibWalltime::waitForFourThousand(): 4,000 msec per iteration (total: 4000, iterations: 1) PASS : tst_BenchlibWalltime::waitForFourThousand() +RESULT : tst_BenchlibWalltime::qbenchmark_once(): + 0 msec per iteration (total: 0, iterations: 1) +PASS : tst_BenchlibWalltime::qbenchmark_once() PASS : tst_BenchlibWalltime::cleanupTestCase() -Totals: 4 passed, 0 failed, 0 skipped +Totals: 5 passed, 0 failed, 0 skipped ********* Finished testing of tst_BenchlibWalltime ********* -- cgit v0.12 From 76b8707e813c4b139a9ebd38b5ae0585d4afc425 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 24 Jul 2009 11:59:07 +0200 Subject: Remove spurious paranthesis in container docs --- doc/src/containers.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/containers.qdoc b/doc/src/containers.qdoc index 11a4b0b..2a34716 100644 --- a/doc/src/containers.qdoc +++ b/doc/src/containers.qdoc @@ -682,7 +682,7 @@ \header \o{1,2} \o{2,1} Key lookup \o{2,1} Insertion \header \o Average \o Worst case \o Average \o Worst case \row \o QMap \o O(log \e n) \o O(log \e n) \o O(log \e n) \o O(log \e n) - \row \o QMultiMap \o O((log \e n) \o O(log \e n) \o O(log \e n) \o O(log \e n) + \row \o QMultiMap \o O(log \e n) \o O(log \e n) \o O(log \e n) \o O(log \e n) \row \o QHash \o Amort. O(1) \o O(\e n) \o Amort. O(1) \o O(\e n) \row \o QSet \o Amort. O(1) \o O(\e n) \o Amort. O(1) \o O(\e n) \endtable -- cgit v0.12 From f0495e760e1e942481b8e0371b2700fd78519bb8 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Mon, 10 Aug 2009 10:57:45 +0200 Subject: Xml patterns: remove line in .pro file that added the schematron dir this line was dragged in from the Xml schema branch, but there is no schematron in Qt. Reviewed-by: TrustMe --- src/xmlpatterns/xmlpatterns.pro | 1 - 1 file changed, 1 deletion(-) diff --git a/src/xmlpatterns/xmlpatterns.pro b/src/xmlpatterns/xmlpatterns.pro index 0e6270e..bb8e452 100644 --- a/src/xmlpatterns/xmlpatterns.pro +++ b/src/xmlpatterns/xmlpatterns.pro @@ -22,7 +22,6 @@ include($$PWD/janitors/janitors.pri) include($$PWD/parser/parser.pri) include($$PWD/projection/projection.pri) include($$PWD/schema/schema.pri) -include($$PWD/schematron/schematron.pri) include($$PWD/type/type.pri) include($$PWD/utils/utils.pri) include($$PWD/qobjectmodel/qobjectmodel.pri, "", true) -- cgit v0.12 From 89f0156b21b4cff8fec0cee283d75f413cf36c61 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Mon, 10 Aug 2009 11:10:03 +0200 Subject: Link with winscw again compiler mangles "struct" and "class" differently, so make sure that QTestCharBuffer is always forward declared as "struct". --- src/testlib/qtestbasicstreamer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testlib/qtestbasicstreamer.h b/src/testlib/qtestbasicstreamer.h index cabbf34..932f5c3 100644 --- a/src/testlib/qtestbasicstreamer.h +++ b/src/testlib/qtestbasicstreamer.h @@ -53,7 +53,7 @@ QT_MODULE(Test) class QTestElement; class QTestElementAttribute; class QTestLogger; -class QTestCharBuffer; +struct QTestCharBuffer; class QTestBasicStreamer { -- cgit v0.12 From 167b333e2c428947264f283f6eec275b27f8f0db Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Mon, 10 Aug 2009 11:21:48 +0200 Subject: Fix default QWidget size on X servers with Xinerama The default widget size is normally calculated from the root window size, but when running on an X server with Xinerama enabled, the root window spans all screens, making the widget far to large. Use the default screen's size instead to give the widget a size that should fit on a single screen. --- src/gui/kernel/qwidget_x11.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index 2a3d2f3..cf65af3 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -512,6 +512,13 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO dialog = popup = false; // force these flags off data.crect.setRect(0, 0, sw, sh); } else if (topLevel && !q->testAttribute(Qt::WA_Resized)) { + QDesktopWidget *desktopWidget = qApp->desktop(); + if (desktopWidget->isVirtualDesktop()) { + QRect r = desktopWidget->screenGeometry(); + sw = r.width(); + sh = r.height(); + } + int width = sw / 2; int height = 4 * sh / 10; if (extra) { -- cgit v0.12 From 468b157ab5496cdab6ff751312dba5376901d533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Mon, 10 Aug 2009 12:47:31 +0200 Subject: Whitespace cleanup --- src/corelib/tools/qtimeline.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/tools/qtimeline.cpp b/src/corelib/tools/qtimeline.cpp index 7402ba6..b6511d5 100644 --- a/src/corelib/tools/qtimeline.cpp +++ b/src/corelib/tools/qtimeline.cpp @@ -212,7 +212,7 @@ void QTimeLinePrivate::setCurrentTime(int msecs) applies an interpolation algorithm to generate these value. You can choose from a set of predefined timeline algorithms by calling setCurveShape(). - + Note that by default, QTimeLine uses the EaseInOut curve shape, which provides a value that grows slowly, then grows steadily, and finally grows slowly. For a custom timeline, you can reimplement @@ -549,7 +549,7 @@ void QTimeLine::setCurveShape(CurveShape shape) case CosineCurve: setEasingCurve(QEasingCurve(QEasingCurve::CosineCurve)); break; - } + } } /*! @@ -559,7 +559,7 @@ void QTimeLine::setCurveShape(CurveShape shape) Specifies the easing curve that the timeline will use. If both easing curve and curveShape are set, the last set property will - override the previous one. (If valueForTime() is reimplemented it will + override the previous one. (If valueForTime() is reimplemented it will override both) */ -- cgit v0.12 From ec1a146dd7f8582d3053ed54420d26141e98155c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Mon, 10 Aug 2009 12:48:13 +0200 Subject: Remove unused member. --- src/corelib/tools/qtimeline.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/corelib/tools/qtimeline.cpp b/src/corelib/tools/qtimeline.cpp index b6511d5..6dbad34 100644 --- a/src/corelib/tools/qtimeline.cpp +++ b/src/corelib/tools/qtimeline.cpp @@ -69,7 +69,6 @@ public: int currentLoopCount; int currentTime; - int elapsedTime; int timerId; QTime timer; -- cgit v0.12 From 17bffacda99055831bb4c8c6e7da39ec15415519 Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Mon, 10 Aug 2009 13:01:34 +0200 Subject: Moved tests/auto/runQtXmlPatternsTests.sh to devtools/shell --- tests/auto/runQtXmlPatternsTests.sh | 61 ------------------------------------- 1 file changed, 61 deletions(-) delete mode 100755 tests/auto/runQtXmlPatternsTests.sh diff --git a/tests/auto/runQtXmlPatternsTests.sh b/tests/auto/runQtXmlPatternsTests.sh deleted file mode 100755 index 41d6c83..0000000 --- a/tests/auto/runQtXmlPatternsTests.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/sh -# Runs all the tests specific to QtXmlPatterns in one go. - -# If you add a test, remember to update ./auto.pro too. -# checkxmlfiles is not part of Patternist, but since it shares test code -# and use Patternist, we include it as well. -# -# Sorted alphabetically, with the difference that xmlpatternsxqts appears -# before xmlpattersview, xmlpatternsdiagnosticsts, and xmlpatternsxslts, since -# they have the former as dependency. -tests=" \ -checkxmlfiles \ -patternistexamplefiletree \ -patternistexamples \ -patternistheaders \ -qabstractmessagehandler \ -qabstracturiresolver \ -qabstractxmlforwarditerator \ -qabstractxmlnodemodel \ -qabstractxmlreceiver \ -qapplicationargumentparser \ -qautoptr \ -qsimplexmlnodemodel \ -qsourcelocation \ -qtokenautomaton \ -qxmlformatter \ -qxmlitem \ -qxmlname \ -qxmlnamepool \ -qxmlnodemodelindex \ -qxmlquery \ -qxmlresultitems \ -qxmlserializer \ -xmlpatterns \ -xmlpatternsxqts \ -xmlpatternsdiagnosticsts \ -xmlpatternsschema \ -xmlpatternsschemats \ -xmlpatternsview \ -xmlpatternsxslts" - -os=`uname` - -for test in $tests; do - cd $test - make distclean - qmake - make - - if [ $os = "Darwin" ]; then - ./tst_"$test".app/Contents/MacOS/tst_"$test" - else - ./tst_$test - fi - - if [ $? -ne 0 ]; then - exit $? - else - cd .. - fi -done -- cgit v0.12 From 47f58dfad1eb7fe61a523597023df33f3d320377 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Sat, 8 Aug 2009 23:58:46 +0200 Subject: Made the QGesture::reset function protected. By default the QGesture::reset function is protected, and it can be made public in the derived class if necessary. Reviewed-by: trustme --- src/gui/kernel/qgesture.h | 3 +-- src/gui/kernel/qstandardgestures.h | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h index 7da37c4..839fdca 100644 --- a/src/gui/kernel/qgesture.h +++ b/src/gui/kernel/qgesture.h @@ -73,14 +73,13 @@ public: void setGraphicsItem(QGraphicsItem *); QGraphicsItem *graphicsItem() const; - virtual void reset(); - Qt::GestureState state() const; protected: QGesture(QGesturePrivate &dd, QObject *parent); bool eventFilter(QObject*, QEvent*); + virtual void reset(); void updateState(Qt::GestureState state); Q_SIGNALS: diff --git a/src/gui/kernel/qstandardgestures.h b/src/gui/kernel/qstandardgestures.h index c734fba..03a1374 100644 --- a/src/gui/kernel/qstandardgestures.h +++ b/src/gui/kernel/qstandardgestures.h @@ -66,11 +66,13 @@ public: QPanGesture(QWidget *parent); bool filterEvent(QEvent *event); - void reset(); QSize totalOffset() const; QSize lastOffset() const; +protected: + void reset(); + private: bool event(QEvent *event); bool eventFilter(QObject *receiver, QEvent *event); -- cgit v0.12 From 6826490774d66e0470fc1e5848ab89b3a0d0bb86 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 5 Aug 2009 18:57:25 +0200 Subject: Implemented QPinchGesture. Added a new standard gesture, which is implemented using a native zoom and rotate gestures on Windows and with a direct touch event handling on other platforms. Improved pan support - we subscribe to native pan gesture only when it's really needed, and we pass proper flags for single finger horizontal/vertical panning. Reviewed-by: Richard Moe Gustavsen --- src/gui/kernel/qapplication_p.h | 3 + src/gui/kernel/qapplication_win.cpp | 21 ++-- src/gui/kernel/qevent_p.h | 5 +- src/gui/kernel/qstandardgestures.cpp | 210 ++++++++++++++++++++++++++++++++++- src/gui/kernel/qstandardgestures.h | 39 +++++++ src/gui/kernel/qstandardgestures_p.h | 25 +++++ src/gui/kernel/qwidget_win.cpp | 40 ++++--- 7 files changed, 316 insertions(+), 27 deletions(-) diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index c4ce2ea..9953907 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -235,6 +235,7 @@ typedef struct tagGESTUREINFO # define GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY 0x00000004 # define GC_ZOOM 0x00000001 +# define GC_ROTATE 0x00000001 typedef struct tagGESTURECONFIG { @@ -243,6 +244,8 @@ typedef struct tagGESTURECONFIG DWORD dwBlock; } GESTURECONFIG; +# define GID_ROTATE_ANGLE_FROM_ARGUMENT(arg) ((((double)(arg) / 65535.0) * 4.0 * 3.14159265) - 2.0*3.14159265) + #endif // WM_GESTURE #endif // Q_WS_WIN diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index bdee6ec..cb67409 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -3721,17 +3721,18 @@ bool QETWidget::translateGestureEvent(const MSG &msg) QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); BOOL bResult = qAppPriv->GetGestureInfo((HANDLE)msg.lParam, &gi); + if (bResult) { + const QPoint widgetPos = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); + QWidget *alienWidget = !internalWinId() ? this : childAt(widgetPos); + if (alienWidget && alienWidget->internalWinId()) + alienWidget = 0; + QWidget *widget = alienWidget ? alienWidget : this; - const QPoint widgetPos = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); - QWidget *alienWidget = !internalWinId() ? this : childAt(widgetPos); - if (alienWidget && alienWidget->internalWinId()) - alienWidget = 0; - QWidget *widget = alienWidget ? alienWidget : this; + QNativeGestureEvent event; + event.sequenceId = gi.dwSequenceID; + event.position = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); + event.argument = gi.ullArguments; - QNativeGestureEvent event; - event.sequenceId = gi.dwSequenceID; - event.position = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); - if (bResult) { switch (gi.dwID) { case GID_BEGIN: event.gestureType = QNativeGestureEvent::GestureBegin; @@ -3746,6 +3747,8 @@ bool QETWidget::translateGestureEvent(const MSG &msg) event.gestureType = QNativeGestureEvent::Pan; break; case GID_ROTATE: + event.gestureType = QNativeGestureEvent::Rotate; + break; case GID_TWOFINGERTAP: case GID_ROLLOVER: default: diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h index b21b35c..2ff672b 100644 --- a/src/gui/kernel/qevent_p.h +++ b/src/gui/kernel/qevent_p.h @@ -133,9 +133,9 @@ public: }; QNativeGestureEvent() - : QEvent(QEvent::NativeGesture), gestureType(None), percentage(0), direction(0, 0) + : QEvent(QEvent::NativeGesture), gestureType(None), percentage(0) #ifdef Q_WS_WIN - , sequenceId(0) + , sequenceId(0), argument(0) #endif { } @@ -146,6 +146,7 @@ public: QSize direction; #ifdef Q_WS_WIN ulong sequenceId; + quint64 argument; #endif }; diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index 7078dbf..ac03cd2 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -132,8 +132,7 @@ bool QPanGesture::eventFilter(QObject *receiver, QEvent *event) it = qAppPriv->widgetGestures.find(static_cast(receiver)); if (it == qAppPriv->widgetGestures.end()) return false; - QPanGesture *gesture = it.value().pan; - if (this != gesture) + if (this != it.value().pan) return false; Qt::GestureState nextState = Qt::NoGesture; switch(ev->gestureType) { @@ -162,7 +161,7 @@ bool QPanGesture::eventFilter(QObject *receiver, QEvent *event) d->totalOffset += d->lastOffset; } d->lastPosition = ev->position; - gesture->updateState(nextState); + updateState(nextState); return true; } #endif @@ -248,6 +247,7 @@ void QPanGesture::reset() d->panFinishedTimer = 0; } #endif + QGesture::reset(); } /*! @@ -273,6 +273,210 @@ QSize QPanGesture::lastOffset() const return d->lastOffset; } + +/*! + \class QPinchGesture + \since 4.6 + + \brief The QPinchGesture class represents a Pinch gesture, + providing additional information related to zooming and/or rotation. +*/ + +/*! + Creates a new Pinch gesture handler object and marks it as a child of \a + parent. + + On some platform like Windows it's necessary to provide a non-null widget + as \a parent to get native gesture support. +*/ +QPinchGesture::QPinchGesture(QWidget *parent) + : QGesture(*new QPinchGesturePrivate, parent) +{ + if (parent) { + QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + qAppPriv->widgetGestures[parent].pinch = this; +#ifdef Q_WS_WIN + qt_widget_private(parent)->winSetupGestures(); +#endif + } +} + +/*! \internal */ +bool QPinchGesture::event(QEvent *event) +{ + switch (event->type()) { + case QEvent::ParentAboutToChange: + if (QWidget *w = qobject_cast(parent())) { + getQApplicationPrivateInternal()->widgetGestures[w].pinch = 0; +#ifdef Q_WS_WIN + qt_widget_private(w)->winSetupGestures(); +#endif + } + break; + case QEvent::ParentChange: + if (QWidget *w = qobject_cast(parent())) { + getQApplicationPrivateInternal()->widgetGestures[w].pinch = this; +#ifdef Q_WS_WIN + qt_widget_private(w)->winSetupGestures(); +#endif + } + break; + default: + break; + } + return QObject::event(event); +} + +bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event) +{ +#ifdef Q_WS_WIN + Q_D(QPinchGesture); + if (receiver->isWidgetType() && event->type() == QEvent::NativeGesture) { + QNativeGestureEvent *ev = static_cast(event); + QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + QApplicationPrivate::WidgetStandardGesturesMap::iterator it; + it = qAppPriv->widgetGestures.find(static_cast(receiver)); + if (it == qAppPriv->widgetGestures.end()) + return false; + if (this != it.value().pinch) + return false; + Qt::GestureState nextState = Qt::NoGesture; + switch(ev->gestureType) { + case QNativeGestureEvent::GestureBegin: + // next we might receive the first gesture update event, so we + // prepare for it. + d->state = Qt::NoGesture; + d->scaleFactor = d->lastScaleFactor = 1; + d->rotationAngle = d->lastRotationAngle = 0; + d->startCenterPoint = d->centerPoint = d->lastCenterPoint = QPoint(); + d->initialDistance = 0; + return false; + case QNativeGestureEvent::Rotate: + d->lastRotationAngle = d->rotationAngle; + d->rotationAngle = -1 * GID_ROTATE_ANGLE_FROM_ARGUMENT(ev->argument); + nextState = Qt::GestureUpdated; + event->accept(); + break; + case QNativeGestureEvent::Zoom: + if (d->initialDistance != 0) { + d->lastScaleFactor = d->scaleFactor; + int distance = int(qint64(ev->argument)); + d->scaleFactor = (qreal) distance / d->initialDistance; + } else { + d->initialDistance = int(qint64(ev->argument)); + } + nextState = Qt::GestureUpdated; + event->accept(); + break; + case QNativeGestureEvent::GestureEnd: + if (state() == Qt::NoGesture) + return false; // some other gesture has ended + nextState = Qt::GestureFinished; + break; + default: + return false; + } + if (d->startCenterPoint.isNull()) + d->startCenterPoint = d->centerPoint; + d->lastCenterPoint = d->centerPoint; + d->centerPoint = static_cast(receiver)->mapFromGlobal(ev->position); + updateState(nextState); + return true; + } +#endif + return QGesture::eventFilter(receiver, event); +} + +/*! \internal */ +bool QPinchGesture::filterEvent(QEvent *event) +{ + Q_UNUSED(event); + return false; +} + +/*! \internal */ +void QPinchGesture::reset() +{ + Q_D(QPinchGesture); + d->scaleFactor = d->lastScaleFactor = 0; + d->rotationAngle = d->lastRotationAngle = 0; + d->startCenterPoint = d->centerPoint = d->lastCenterPoint = QPoint(); + QGesture::reset(); +} + +/*! + \property QPinchGesture::scaleFactor + + Specifies a scale factor of the pinch gesture. +*/ +qreal QPinchGesture::scaleFactor() const +{ + return d_func()->scaleFactor; +} + +/*! + \property QPinchGesture::lastScaleFactor + + Specifies a previous scale factor of the pinch gesture. +*/ +qreal QPinchGesture::lastScaleFactor() const +{ + return d_func()->lastScaleFactor; +} + +/*! + \property QPinchGesture::rotationAngle + + Specifies a rotation angle of the gesture. +*/ +qreal QPinchGesture::rotationAngle() const +{ + return d_func()->rotationAngle; +} + +/*! + \property QPinchGesture::lastRotationAngle + + Specifies a previous rotation angle of the gesture. +*/ +qreal QPinchGesture::lastRotationAngle() const +{ + return d_func()->lastRotationAngle; +} + +/*! + \property QPinchGesture::centerPoint + + Specifies a center point of the gesture. The point can be used as a center + point that the object is rotated around. +*/ +QPoint QPinchGesture::centerPoint() const +{ + return d_func()->centerPoint; +} + +/*! + \property QPinchGesture::lastCenterPoint + + Specifies a previous center point of the gesture. +*/ +QPoint QPinchGesture::lastCenterPoint() const +{ + return d_func()->lastCenterPoint; +} + +/*! + \property QPinchGesture::startCenterPoint + + Specifies an initial center point of the gesture. Difference between the + startCenterPoint and the centerPoint is the distance at which pinching + fingers has shifted. +*/ +QPoint QPinchGesture::startCenterPoint() const +{ + return d_func()->startCenterPoint; +} + QT_END_NAMESPACE #include "moc_qstandardgestures.cpp" diff --git a/src/gui/kernel/qstandardgestures.h b/src/gui/kernel/qstandardgestures.h index 03a1374..adee740 100644 --- a/src/gui/kernel/qstandardgestures.h +++ b/src/gui/kernel/qstandardgestures.h @@ -80,6 +80,45 @@ private: friend class QWidget; }; +class QPinchGesturePrivate; +class Q_GUI_EXPORT QPinchGesture : public QGesture +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QPinchGesture) + + Q_PROPERTY(qreal scaleFactor READ scaleFactor) + Q_PROPERTY(qreal lastScaleFactor READ lastScaleFactor) + + Q_PROPERTY(qreal rotationAngle READ rotationAngle) + Q_PROPERTY(qreal lastRotationAngle READ lastRotationAngle) + + Q_PROPERTY(QPoint startCenterPoint READ startCenterPoint) + Q_PROPERTY(QPoint lastCenterPoint READ lastCenterPoint) + Q_PROPERTY(QPoint centerPoint READ centerPoint) + +public: + QPinchGesture(QWidget *parent); + + bool filterEvent(QEvent *event); + void reset(); + + QPoint startCenterPoint() const; + QPoint lastCenterPoint() const; + QPoint centerPoint() const; + + qreal scaleFactor() const; + qreal lastScaleFactor() const; + + qreal rotationAngle() const; + qreal lastRotationAngle() const; + +private: + bool event(QEvent *event); + bool eventFilter(QObject *receiver, QEvent *event); + + friend class QWidget; +}; + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h index 0fe24ee..43636d0 100644 --- a/src/gui/kernel/qstandardgestures_p.h +++ b/src/gui/kernel/qstandardgestures_p.h @@ -85,6 +85,31 @@ public: #endif }; +class QPinchGesturePrivate : public QGesturePrivate +{ + Q_DECLARE_PUBLIC(QPinchGesture) + +public: + QPinchGesturePrivate() + : scaleFactor(0), lastScaleFactor(0), + rotationAngle(0), lastRotationAngle(0) +#ifdef Q_WS_WIN + ,initialDistance(0) +#endif + { + } + qreal scaleFactor; + qreal lastScaleFactor; + qreal rotationAngle; + qreal lastRotationAngle; + QPoint startCenterPoint; + QPoint lastCenterPoint; + QPoint centerPoint; +#ifdef Q_WS_WIN + int initialDistance; +#endif +}; + QT_END_NAMESPACE #endif // QSTANDARDGESTURES_P_H diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp index 7cfa111..510df7f 100644 --- a/src/gui/kernel/qwidget_win.cpp +++ b/src/gui/kernel/qwidget_win.cpp @@ -1160,6 +1160,8 @@ void QWidgetPrivate::show_sys() data.window_state |= Qt::WindowMaximized; } + winSetupGestures(); + invalidateBuffer(q->rect()); } #endif //Q_WS_WINCE @@ -2058,8 +2060,11 @@ void QWidgetPrivate::winSetupGestures() Q_Q(QWidget); if (!q) return; - extern QApplicationPrivate* getQApplicationPrivateInternal(); - QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + q->setAttribute(Qt::WA_DontCreateNativeAncestors); + q->setAttribute(Qt::WA_NativeWindow); + if (!q->isVisible()) + return; + QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); bool needh = false; bool needv = false; bool singleFingerPanEnabled = false; @@ -2072,34 +2077,43 @@ void QWidgetPrivate::winSetupGestures() QScrollBar *vbar = asa->verticalScrollBar(); Qt::ScrollBarPolicy hbarpolicy = asa->horizontalScrollBarPolicy(); Qt::ScrollBarPolicy vbarpolicy = asa->verticalScrollBarPolicy(); - needh = (hbarpolicy == Qt::ScrollBarAlwaysOn - || (hbarpolicy == Qt::ScrollBarAsNeeded && hbar->minimum() < hbar->maximum())); - needv = (vbarpolicy == Qt::ScrollBarAlwaysOn - || (vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum())); + needh = (hbarpolicy == Qt::ScrollBarAlwaysOn || + (hbarpolicy == Qt::ScrollBarAsNeeded && hbar->minimum() < hbar->maximum())); + needv = (vbarpolicy == Qt::ScrollBarAlwaysOn || + (vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum())); singleFingerPanEnabled = asa->d_func()->singleFingerPanEnabled; } else { winid = q->winId(); } if (qAppPriv->SetGestureConfig) { - GESTURECONFIG gc[2]; + GESTURECONFIG gc[3]; + memset(gc, 0, sizeof(gc)); gc[0].dwID = GID_PAN; - if (gestures.pan || needh || needv) { + if (gestures.pan) { gc[0].dwWant = GC_PAN; - gc[0].dwBlock = 0; if (needv && singleFingerPanEnabled) gc[0].dwWant |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY; + else + gc[0].dwBlock |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY; if (needh && singleFingerPanEnabled) gc[0].dwWant |= GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY; + else + gc[0].dwBlock |= GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY; } else { - gc[0].dwWant = 0; gc[0].dwBlock = GC_PAN; } gc[1].dwID = GID_ZOOM; - if (gestures.pinch) { + if (gestures.pinch) gc[1].dwWant = GC_ZOOM; - gc[1].dwBlock = 0; - } + else + gc[1].dwBlock = GC_ZOOM; + gc[2].dwID = GID_ROTATE; + if (gestures.pinch) + gc[2].dwWant = GC_ROTATE; + else + gc[2].dwBlock = GC_ROTATE; + Q_ASSERT(winid); qAppPriv->SetGestureConfig(winid, 0, sizeof(gc)/sizeof(gc[0]), gc, sizeof(gc[0])); } -- cgit v0.12 From 65ba2c18a9a3ec82331c0ccab47edc8e252192df Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 10 Aug 2009 13:45:24 +0200 Subject: Fixed an assert that could happen when the mediaSource is deleted When using streaming, it could happen that the last reference to the MediaSource is in another thread. So the objects are destroyed from another thread. In which case we would delete QObject (ioDevice) in another thread. That is fixed by calling deleteLater which will ensure that they are deleted in their own thread. Note: there was a nother assert that could happen due to a race condition in the worker thread. That is also fixed with this patch. Reviewed-by: jbache --- src/3rdparty/phonon/ds9/mediaobject.cpp | 55 ++++++++++-------------------- src/3rdparty/phonon/ds9/mediaobject.h | 1 - src/3rdparty/phonon/phonon/mediasource.cpp | 8 +++-- 3 files changed, 24 insertions(+), 40 deletions(-) diff --git a/src/3rdparty/phonon/ds9/mediaobject.cpp b/src/3rdparty/phonon/ds9/mediaobject.cpp index 10782c2..b163ad4 100644 --- a/src/3rdparty/phonon/ds9/mediaobject.cpp +++ b/src/3rdparty/phonon/ds9/mediaobject.cpp @@ -57,24 +57,6 @@ namespace Phonon { } - WorkerThread::Work WorkerThread::dequeueWork() - { - QMutexLocker locker(&m_mutex); - if (m_finished) { - return Work(); - } - Work ret = m_queue.dequeue(); - - //we ensure to have the wait condition in the right state - if (m_queue.isEmpty()) { - m_waitCondition.reset(); - } else { - m_waitCondition.set(); - } - - return ret; - } - void WorkerThread::run() { while (m_finished == false) { @@ -88,11 +70,6 @@ namespace Phonon } DWORD result = ::WaitForMultipleObjects(count, handles, FALSE, INFINITE); if (result == WAIT_OBJECT_0) { - if (m_finished) { - //that's the end of the thread execution - return; - } - handleTask(); } else { //this is the event management @@ -199,22 +176,25 @@ namespace Phonon void WorkerThread::handleTask() { - const Work w = dequeueWork(); - - if (m_finished) { + QMutexLocker locker(&m_mutex); + if (m_finished || m_queue.isEmpty()) { return; } - HRESULT hr = S_OK; + const Work w = m_queue.dequeue(); - { - QMutexLocker locker(&m_mutex); - m_currentRender = w.graph; - m_currentRenderId = w.id; + //we ensure to have the wait condition in the right state + if (m_queue.isEmpty()) { + m_waitCondition.reset(); + } else { + m_waitCondition.set(); } + HRESULT hr = S_OK; + + m_currentRender = w.graph; + m_currentRenderId = w.id; if (w.task == ReplaceGraph) { - QMutexLocker locker(&m_mutex); int index = -1; for(int i = 0; i < FILTER_COUNT; ++i) { if (m_graphHandle[i].graph == w.oldGraph) { @@ -237,6 +217,9 @@ namespace Phonon m_graphHandle[index].handle = h; } } else if (w.task == Render) { + //we need to unlock here because the use might trigger a call to abort + //which uses the same mutex + locker.unlock(); if (w.filter) { //let's render pins w.graph->AddFilter(w.filter, 0); @@ -255,6 +238,7 @@ namespace Phonon if (hr != E_ABORT) { emit asyncRenderFinished(w.id, hr, w.graph); } + locker.relock(); } else if (w.task == Seek) { //that's a seekrequest ComPointer mediaSeeking(w.graph, IID_IMediaSeeking); @@ -327,11 +311,8 @@ namespace Phonon } } - { - QMutexLocker locker(&m_mutex); - m_currentRender = Graph(); - m_currentRenderId = 0; - } + m_currentRender = Graph(); + m_currentRenderId = 0; } void WorkerThread::abortCurrentRender(qint16 renderId) diff --git a/src/3rdparty/phonon/ds9/mediaobject.h b/src/3rdparty/phonon/ds9/mediaobject.h index 2c34ffc..fe52604 100644 --- a/src/3rdparty/phonon/ds9/mediaobject.h +++ b/src/3rdparty/phonon/ds9/mediaobject.h @@ -135,7 +135,6 @@ namespace Phonon }; QList decoders; //for the state change requests }; - Work dequeueWork(); void handleTask(); Graph m_currentRender; diff --git a/src/3rdparty/phonon/phonon/mediasource.cpp b/src/3rdparty/phonon/phonon/mediasource.cpp index 0a21c87..c003af9 100644 --- a/src/3rdparty/phonon/phonon/mediasource.cpp +++ b/src/3rdparty/phonon/phonon/mediasource.cpp @@ -140,8 +140,12 @@ MediaSourcePrivate::~MediaSourcePrivate() { #ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM if (autoDelete) { - delete stream; - delete ioDevice; + //here we use deleteLater because this object + //might be destroyed from another thread + if (stream) + stream->deleteLater(); + if (ioDevice) + ioDevice->deleteLater(); } #endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM } -- cgit v0.12 From 2a1dcf7a47d81ad8b492c312dfd5e422ba2e3cd0 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 10 Aug 2009 14:57:30 +0200 Subject: qdoc: List the NOTIFY signal function in the property doc. --- tools/qdoc3/cppcodeparser.cpp | 3 +++ tools/qdoc3/generator.cpp | 2 +- tools/qdoc3/htmlgenerator.cpp | 8 ++++++++ tools/qdoc3/node.h | 5 +++-- tools/qdoc3/tree.cpp | 3 +++ 5 files changed, 18 insertions(+), 3 deletions(-) diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp index 562684b..12ec7f3 100644 --- a/tools/qdoc3/cppcodeparser.cpp +++ b/tools/qdoc3/cppcodeparser.cpp @@ -1737,6 +1737,9 @@ 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); + } } match(Tok_RightParen); return true; diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp index e92f53b..9538dfe 100644 --- a/tools/qdoc3/generator.cpp +++ b/tools/qdoc3/generator.cpp @@ -283,7 +283,7 @@ bool Generator::generateText(const Text& text, bool Generator::generateQmlText(const Text& text, const Node *relative, CodeMarker *marker, - const QString& qmlName) + const QString& /* qmlName */ ) { const Atom* atom = text.firstAtom(); if (atom == 0) diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index 26874e1..c203c62 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -3420,6 +3420,14 @@ void HtmlGenerator::generateDetailedMember(const Node *node, out() << "

Access functions:

\n"; generateSectionList(section, node, marker, CodeMarker::Accessors); } + + Section notifiers; + notifiers.members += property->notifiers(); + + if (!notifiers.members.isEmpty()) { + out() << "

Notifier signal:

\n"; + generateSectionList(notifiers, node, marker, CodeMarker::Accessors); + } } else if (node->type() == Node::Enum) { const EnumNode *enume = static_cast(node); diff --git a/tools/qdoc3/node.h b/tools/qdoc3/node.h index 17ec447..61f2a76 100644 --- a/tools/qdoc3/node.h +++ b/tools/qdoc3/node.h @@ -590,8 +590,8 @@ class FunctionNode : public LeafNode class PropertyNode : public LeafNode { public: - enum FunctionRole { Getter, Setter, Resetter }; - enum { NumFunctionRoles = Resetter + 1 }; + enum FunctionRole { Getter, Setter, Resetter, Notifier }; + enum { NumFunctionRoles = Notifier + 1 }; PropertyNode(InnerNode *parent, const QString& name); virtual ~PropertyNode() { } @@ -609,6 +609,7 @@ class PropertyNode : public LeafNode NodeList getters() const { return functions(Getter); } NodeList setters() const { return functions(Setter); } NodeList resetters() const { return functions(Resetter); } + NodeList notifiers() const { return functions(Notifier); } bool isStored() const { return fromTrool(sto, storedDefault()); } bool isDesignable() const { return fromTrool(des, designableDefault()); } const PropertyNode *overriddenFrom() const { return overrides; } diff --git a/tools/qdoc3/tree.cpp b/tools/qdoc3/tree.cpp index f832062..a5e22f1 100644 --- a/tools/qdoc3/tree.cpp +++ b/tools/qdoc3/tree.cpp @@ -485,6 +485,7 @@ void Tree::resolveProperties() QString getterName = (*propEntry)[PropertyNode::Getter]; QString setterName = (*propEntry)[PropertyNode::Setter]; QString resetterName = (*propEntry)[PropertyNode::Resetter]; + QString notifierName = (*propEntry)[PropertyNode::Notifier]; NodeList::ConstIterator c = parent->childNodes().begin(); while (c != parent->childNodes().end()) { @@ -499,6 +500,8 @@ void Tree::resolveProperties() property->addFunction(function, PropertyNode::Setter); } else if (function->name() == resetterName) { property->addFunction(function, PropertyNode::Resetter); + } else if (function->name() == notifierName) { + property->addFunction(function, PropertyNode::Notifier); } } } -- cgit v0.12 From 4fe7c464be95fbbcb663a21f9519024486123248 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 10 Aug 2009 11:26:01 +0200 Subject: Compile fix with namespaces --- examples/statemachine/rogue/window.h | 2 ++ src/corelib/kernel/qeventdispatcher_unix.cpp | 2 +- src/corelib/tools/qsharedpointer.cpp | 10 ++++++++++ src/gui/graphicsview/qgraphicstransform_p.h | 4 ++++ src/gui/image/qimagepixmapcleanuphooks.cpp | 3 +++ src/network/access/qnetworkcookie.h | 6 +++--- 6 files changed, 23 insertions(+), 4 deletions(-) diff --git a/examples/statemachine/rogue/window.h b/examples/statemachine/rogue/window.h index bcd86bd..1df566d 100644 --- a/examples/statemachine/rogue/window.h +++ b/examples/statemachine/rogue/window.h @@ -44,9 +44,11 @@ #include +QT_BEGIN_NAMESPACE class QState; class QStateMachine; class QTransition; +QT_END_NAMESPACE #define WIDTH 35 #define HEIGHT 20 diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index 7982d4c..da15148 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -627,7 +627,7 @@ QEventDispatcherUNIX::~QEventDispatcherUNIX() int QEventDispatcherUNIX::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, timeval *timeout) { - return ::qt_safe_select(nfds, readfds, writefds, exceptfds, timeout); + return qt_safe_select(nfds, readfds, writefds, exceptfds, timeout); } /*! diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index f18dee8..cdb7d1d 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -867,6 +867,8 @@ #if !defined(QT_NO_QOBJECT) #include "../kernel/qobject_p.h" +QT_BEGIN_NAMESPACE + /*! \internal This function is called for a just-created QObject \a obj, to enable @@ -910,6 +912,9 @@ QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::ge } return d->sharedRefcount; } + +QT_END_NAMESPACE + #endif @@ -932,6 +937,8 @@ QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::ge # include # include +QT_BEGIN_NAMESPACE + static inline QByteArray saveBacktrace() __attribute__((always_inline)); static inline QByteArray saveBacktrace() { @@ -992,6 +999,9 @@ static void printBacktrace(QByteArray stacktrace) waitpid(child, 0, 0); } } + +QT_END_NAMESPACE + # endif // BACKTRACE_SUPPORTED namespace { diff --git a/src/gui/graphicsview/qgraphicstransform_p.h b/src/gui/graphicsview/qgraphicstransform_p.h index 2d36eda..467021f 100644 --- a/src/gui/graphicsview/qgraphicstransform_p.h +++ b/src/gui/graphicsview/qgraphicstransform_p.h @@ -55,6 +55,8 @@ #include "private/qobject_p.h" +QT_BEGIN_NAMESPACE + class QGraphicsItem; class QGraphicsTransformPrivate : public QObjectPrivate { @@ -70,4 +72,6 @@ public: static void updateItem(QGraphicsItem *item); }; +QT_END_NAMESPACE + #endif // QGRAPHICSTRANSFORM_P_H diff --git a/src/gui/image/qimagepixmapcleanuphooks.cpp b/src/gui/image/qimagepixmapcleanuphooks.cpp index 7d1c5fb..789700a 100644 --- a/src/gui/image/qimagepixmapcleanuphooks.cpp +++ b/src/gui/image/qimagepixmapcleanuphooks.cpp @@ -43,6 +43,8 @@ #include "qpixmapdata_p.h" +QT_BEGIN_NAMESPACE + // Legacy, single instance hooks: ### Qt 5: remove typedef void (*_qt_pixmap_cleanup_hook)(int); typedef void (*_qt_pixmap_cleanup_hook_64)(qint64); @@ -108,3 +110,4 @@ void QImagePixmapCleanupHooks::executeImageHooks(qint64 key) qt_image_cleanup_hook_64(key); } +QT_END_NAMESPACE diff --git a/src/network/access/qnetworkcookie.h b/src/network/access/qnetworkcookie.h index ef309a8..4bc3f3f 100644 --- a/src/network/access/qnetworkcookie.h +++ b/src/network/access/qnetworkcookie.h @@ -106,9 +106,6 @@ private: }; Q_DECLARE_TYPEINFO(QNetworkCookie, Q_MOVABLE_TYPE); -// ### Qt5 remove this include -#include "qnetworkcookiejar.h" - #ifndef QT_NO_DEBUG_STREAM class QDebug; Q_NETWORK_EXPORT QDebug operator<<(QDebug, const QNetworkCookie &); @@ -116,6 +113,9 @@ Q_NETWORK_EXPORT QDebug operator<<(QDebug, const QNetworkCookie &); QT_END_NAMESPACE +// ### Qt5 remove this include +#include "qnetworkcookiejar.h" + Q_DECLARE_METATYPE(QNetworkCookie) Q_DECLARE_METATYPE(QList) -- cgit v0.12 From cbf60a676402eebae558568a2da4574a20f7a27e Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 10 Aug 2009 15:10:22 +0200 Subject: Compile fix for QStringBuilder auto test --- tests/auto/qstringbuilder/scenario1.pro | 1 + tests/auto/qstringbuilder/scenario2.pro | 1 + tests/auto/qstringbuilder/scenario3.pro | 1 + tests/auto/qstringbuilder/scenario4.pro | 1 + tests/auto/qstringbuilder/tst_qstringbuilder.cpp | 11 +---- tests/auto/qstringbuilder/tst_qstringbuilder.h | 55 ++++++++++++++++++++++++ 6 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 tests/auto/qstringbuilder/tst_qstringbuilder.h diff --git a/tests/auto/qstringbuilder/scenario1.pro b/tests/auto/qstringbuilder/scenario1.pro index 4ce7156..d72451c 100644 --- a/tests/auto/qstringbuilder/scenario1.pro +++ b/tests/auto/qstringbuilder/scenario1.pro @@ -3,6 +3,7 @@ load(qttest_p4) QT = core SOURCES += scenario1.cpp +HEADERS += tst_qstringbuilder.h DEFINES += SCENARIO=1 diff --git a/tests/auto/qstringbuilder/scenario2.pro b/tests/auto/qstringbuilder/scenario2.pro index 64c46e2..78e0c68 100644 --- a/tests/auto/qstringbuilder/scenario2.pro +++ b/tests/auto/qstringbuilder/scenario2.pro @@ -3,5 +3,6 @@ load(qttest_p4) QT = core SOURCES += scenario2.cpp +HEADERS += tst_qstringbuilder.h DEFINES += SCENARIO=2 diff --git a/tests/auto/qstringbuilder/scenario3.pro b/tests/auto/qstringbuilder/scenario3.pro index beedffd..7b9e5af 100644 --- a/tests/auto/qstringbuilder/scenario3.pro +++ b/tests/auto/qstringbuilder/scenario3.pro @@ -3,5 +3,6 @@ load(qttest_p4) QT = core SOURCES += scenario3.cpp +HEADERS += tst_qstringbuilder.h DEFINES += SCENARIO=3 diff --git a/tests/auto/qstringbuilder/scenario4.pro b/tests/auto/qstringbuilder/scenario4.pro index 1c45a70..1b62b25 100644 --- a/tests/auto/qstringbuilder/scenario4.pro +++ b/tests/auto/qstringbuilder/scenario4.pro @@ -3,5 +3,6 @@ load(qttest_p4) QT = core SOURCES += scenario4.cpp +HEADERS += tst_qstringbuilder.h DEFINES += SCENARIO=4 diff --git a/tests/auto/qstringbuilder/tst_qstringbuilder.cpp b/tests/auto/qstringbuilder/tst_qstringbuilder.cpp index 72889bc..86f6ada 100644 --- a/tests/auto/qstringbuilder/tst_qstringbuilder.cpp +++ b/tests/auto/qstringbuilder/tst_qstringbuilder.cpp @@ -86,20 +86,13 @@ #endif #include +#include "tst_qstringbuilder.h" //TESTED_CLASS=QStringBuilder //TESTED_FILES=qstringbuilder.cpp #define LITERAL "some literal" -class tst_QStringBuilder : public QObject -{ - Q_OBJECT - -private slots: - void scenario(); -}; - void tst_QStringBuilder::scenario() { QLatin1Literal l1literal(LITERAL); @@ -138,5 +131,3 @@ void tst_QStringBuilder::scenario() } QTEST_APPLESS_MAIN(tst_QStringBuilder) - -#include "tst_qstringbuilder.moc" diff --git a/tests/auto/qstringbuilder/tst_qstringbuilder.h b/tests/auto/qstringbuilder/tst_qstringbuilder.h new file mode 100644 index 0000000..92c66d8 --- /dev/null +++ b/tests/auto/qstringbuilder/tst_qstringbuilder.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TST_QSTRINGBUILDER_H +#define TST_QSTRINGBUILDER_H + +#include + +class tst_QStringBuilder : public QObject +{ + Q_OBJECT + +private slots: + void scenario(); +}; + +#endif -- cgit v0.12 From 56f58a397ace5985571995ddfce98a99c490ebf8 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Mon, 10 Aug 2009 15:45:02 +0200 Subject: Removed unused member in QApplicationPrivate The appAllTouchPoints variable isn't used on Windows, remove it. --- src/gui/kernel/qapplication_p.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 9953907..f809672 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -527,7 +527,6 @@ public: static PtrCloseTouchInputHandle CloseTouchInputHandle; QHash touchInputIDToTouchPointID; - QList appAllTouchPoints; bool translateTouchEvent(const MSG &msg); PtrGetGestureInfo GetGestureInfo; -- cgit v0.12 From 24aa36349b9fc0be9d9bf80b0db607588e0a54f6 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Mon, 10 Aug 2009 15:50:43 +0200 Subject: Doc: Fix qdoc warnings --- src/gui/kernel/qgesture.cpp | 2 +- src/testlib/qabstracttestlogger.cpp | 4 +++- src/testlib/qbenchmark.cpp | 8 +++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index 38e8851..672fc1c 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -204,7 +204,7 @@ Qt::GestureState QGesture::state() const \a state, and it should be called after all the internal properties have been initialized. - \sa started, triggered, finished, cancelled + \sa started(), triggered(), finished(), cancelled() */ void QGesture::updateState(Qt::GestureState state) { diff --git a/src/testlib/qabstracttestlogger.cpp b/src/testlib/qabstracttestlogger.cpp index 2fa535e..6b4b375 100644 --- a/src/testlib/qabstracttestlogger.cpp +++ b/src/testlib/qabstracttestlogger.cpp @@ -114,7 +114,9 @@ namespace QTest extern void filter_unprintable(char *str); -/*! \internal +/*! + \fn int QTest::qt_asprintf(QTestCharBuffer *buf, const char *format, ...); + \internal */ int qt_asprintf(QTestCharBuffer *str, const char *format, ...) { diff --git a/src/testlib/qbenchmark.cpp b/src/testlib/qbenchmark.cpp index bad3379..eaec02f 100644 --- a/src/testlib/qbenchmark.cpp +++ b/src/testlib/qbenchmark.cpp @@ -179,11 +179,17 @@ void QBenchmarkTestMethodData::setResult(qint64 value) QBenchmarkResult(QBenchmarkGlobalData::current->context, value, iterationCount); } -/*! \internal +/*! + \class QTest::QBenchmarkIterationController + \internal + The QBenchmarkIterationController class is used by the QBENCHMARK macro to drive the benchmarking loop. It is repsonsible for starting and stopping the timing measurements as well as calling the result reporting functions. */ + +/*! \internal +*/ QTest::QBenchmarkIterationController::QBenchmarkIterationController(RunMode runMode) { QTest::beginBenchmarkMeasurement(); -- cgit v0.12 From 0c98e05dfeccdca99bc180ccccd04b38305ad025 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 10 Aug 2009 16:07:33 +0200 Subject: Compile fix on Linux. Reviewed-by: brad The declaration of getQApplicationPrivateInternal was only available as 'friend' on Q_WS_WIN. --- src/gui/kernel/qapplication.h | 4 ---- src/gui/kernel/qapplication_win.cpp | 11 +++-------- src/gui/kernel/qstandardgestures.cpp | 8 ++++---- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h index 19ae085..58e0cc3 100644 --- a/src/gui/kernel/qapplication.h +++ b/src/gui/kernel/qapplication.h @@ -375,10 +375,6 @@ private: friend class QDirectPainterPrivate; #endif -#if defined(Q_WS_WIN) - friend QApplicationPrivate* getQApplicationPrivateInternal(); -#endif - #if defined(Q_WS_MAC) || defined(Q_WS_X11) Q_PRIVATE_SLOT(d_func(), void _q_alertTimeOut()) #endif diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index cb67409..d5448db 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -428,11 +428,6 @@ extern QCursor *qt_grab_cursor(); #define __export #endif -QApplicationPrivate* getQApplicationPrivateInternal() -{ - return qApp->d_func(); -} - extern "C" LRESULT CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM); class QETWidget : public QWidget // event translator widget @@ -1461,7 +1456,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam // we receive the message for each toplevel window included internal hidden ones, // but the aboutToQuit signal should be emitted only once. - QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); if (endsession && !qAppPriv->aboutToQuitEmitted) { qAppPriv->aboutToQuitEmitted = true; int index = QApplication::staticMetaObject.indexOfSignal("aboutToQuit()"); @@ -1648,7 +1643,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam } else { switch (message) { case WM_TOUCH: - result = getQApplicationPrivateInternal()->translateTouchEvent(msg); + result = QApplicationPrivate::instance()->translateTouchEvent(msg); break; case WM_KEYDOWN: // keyboard event case WM_SYSKEYDOWN: @@ -3719,7 +3714,7 @@ bool QETWidget::translateGestureEvent(const MSG &msg) memset(&gi, 0, sizeof(GESTUREINFO)); gi.cbSize = sizeof(GESTUREINFO); - QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); BOOL bResult = qAppPriv->GetGestureInfo((HANDLE)msg.lParam, &gi); if (bResult) { const QPoint widgetPos = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index ac03cd2..b4c3787 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -293,7 +293,7 @@ QPinchGesture::QPinchGesture(QWidget *parent) : QGesture(*new QPinchGesturePrivate, parent) { if (parent) { - QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); qAppPriv->widgetGestures[parent].pinch = this; #ifdef Q_WS_WIN qt_widget_private(parent)->winSetupGestures(); @@ -307,7 +307,7 @@ bool QPinchGesture::event(QEvent *event) switch (event->type()) { case QEvent::ParentAboutToChange: if (QWidget *w = qobject_cast(parent())) { - getQApplicationPrivateInternal()->widgetGestures[w].pinch = 0; + QApplicationPrivate::instance()->widgetGestures[w].pinch = 0; #ifdef Q_WS_WIN qt_widget_private(w)->winSetupGestures(); #endif @@ -315,7 +315,7 @@ bool QPinchGesture::event(QEvent *event) break; case QEvent::ParentChange: if (QWidget *w = qobject_cast(parent())) { - getQApplicationPrivateInternal()->widgetGestures[w].pinch = this; + QApplicationPrivate::instance()->widgetGestures[w].pinch = this; #ifdef Q_WS_WIN qt_widget_private(w)->winSetupGestures(); #endif @@ -333,7 +333,7 @@ bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event) Q_D(QPinchGesture); if (receiver->isWidgetType() && event->type() == QEvent::NativeGesture) { QNativeGestureEvent *ev = static_cast(event); - QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); QApplicationPrivate::WidgetStandardGesturesMap::iterator it; it = qAppPriv->widgetGestures.find(static_cast(receiver)); if (it == qAppPriv->widgetGestures.end()) -- cgit v0.12 From eeb206d41d386d4d3dee1ff2813d132d15f670d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Mon, 10 Aug 2009 16:16:16 +0200 Subject: Compile and work on Linux. Reviewed-by: Kim --- tests/arthur/lance/main.cpp | 2 +- tests/arthur/lance/widgets.h | 39 +++++++++++++++++++++------------------ 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/tests/arthur/lance/main.cpp b/tests/arthur/lance/main.cpp index f95b426..0c9f3d8 100644 --- a/tests/arthur/lance/main.cpp +++ b/tests/arthur/lance/main.cpp @@ -271,7 +271,7 @@ int main(int argc, char **argv) QString format = QString(argv[++i]).toLower(); imageFormat = QImage::Format_Invalid; - static const unsigned int formatCount = + static const int formatCount = sizeof(imageFormats) / sizeof(imageFormats[0]); for (int ff = 0; ff < formatCount; ++ff) { if (QLatin1String(imageFormats[ff].name) == format) { diff --git a/tests/arthur/lance/widgets.h b/tests/arthur/lance/widgets.h index 7247608..61691dc 100644 --- a/tests/arthur/lance/widgets.h +++ b/tests/arthur/lance/widgets.h @@ -56,6 +56,9 @@ #include #include #include +#include +#include + #include @@ -96,8 +99,8 @@ public: OnScreenWidget(const QString &file, QWidget *parent = 0) : T(parent), - m_view_mode(RenderView), - m_filename(file) + m_filename(file), + m_view_mode(RenderView) { QSettings settings("Trolltech", "lance"); for (int i=0; i<10; ++i) { @@ -117,36 +120,36 @@ public: } if (m_baseline.isNull()) { - setWindowTitle("Rendering: '" + file + "'. No baseline available"); + T::setWindowTitle("Rendering: '" + file + "'. No baseline available"); } else { - setWindowTitle("Rendering: '" + file + "'. Shortcuts: 1=render, 2=baseline, 3=difference"); + T::setWindowTitle("Rendering: '" + file + "'. Shortcuts: 1=render, 2=baseline, 3=difference"); StupidWorkaround *workaround = new StupidWorkaround(this, &m_view_mode); QSignalMapper *mapper = new QSignalMapper(this); - connect(mapper, SIGNAL(mapped(int)), workaround, SLOT(setViewMode(int))); - connect(mapper, SIGNAL(mapped(QString)), this, SLOT(setWindowTitle(QString))); + T::connect(mapper, SIGNAL(mapped(int)), workaround, SLOT(setViewMode(int))); + T::connect(mapper, SIGNAL(mapped(QString)), this, SLOT(setWindowTitle(QString))); QAction *renderViewAction = new QAction("Render View", this); renderViewAction->setShortcut(Qt::Key_1); - connect(renderViewAction, SIGNAL(triggered()), mapper, SLOT(map())); + T::connect(renderViewAction, SIGNAL(triggered()), mapper, SLOT(map())); mapper->setMapping(renderViewAction, RenderView); mapper->setMapping(renderViewAction, "Render View: " + file); - addAction(renderViewAction); + T::addAction(renderViewAction); QAction *baselineAction = new QAction("Baseline", this); baselineAction->setShortcut(Qt::Key_2); - connect(baselineAction, SIGNAL(triggered()), mapper, SLOT(map())); + T::connect(baselineAction, SIGNAL(triggered()), mapper, SLOT(map())); mapper->setMapping(baselineAction, BaselineView); mapper->setMapping(baselineAction, "Baseline View: " + file); - addAction(baselineAction); + T::addAction(baselineAction); QAction *differenceAction = new QAction("Differenfe View", this); differenceAction->setShortcut(Qt::Key_3); - connect(differenceAction, SIGNAL(triggered()), mapper, SLOT(map())); + T::connect(differenceAction, SIGNAL(triggered()), mapper, SLOT(map())); mapper->setMapping(differenceAction, DifferenceView); mapper->setMapping(differenceAction, "Difference View" + file); - addAction(differenceAction); + T::addAction(differenceAction); } @@ -178,7 +181,7 @@ public: } } - void OnScreenWidget::paintRenderView() + void paintRenderView() { QPainter pt; QPaintDevice *dev = this; @@ -233,7 +236,7 @@ public: } if (m_render_view.isNull()) { - m_render_view = window()->windowSurface()->grabWidget(this); + m_render_view = T::window()->windowSurface()->grabWidget(this); m_render_view.save("renderView.png"); } } @@ -242,7 +245,7 @@ public: QPainter p(this); if (m_baseline.isNull()) { - p.drawText(rect(), Qt::AlignCenter, + p.drawText(T::rect(), Qt::AlignCenter, "No baseline found\n" "file '" + m_baseline_name + "' does not exist..."); return; @@ -258,7 +261,7 @@ public: QPixmap generateDifference() { - QImage img(size(), QImage::Format_RGB32); + QImage img(T::size(), QImage::Format_RGB32); img.fill(0); QPainter p(&img); @@ -275,13 +278,13 @@ public: void paintDifferenceView() { QPainter p(this); if (m_baseline.isNull()) { - p.drawText(rect(), Qt::AlignCenter, + p.drawText(T::rect(), Qt::AlignCenter, "No baseline found\n" "file '" + m_baseline_name + "' does not exist..."); return; } - p.fillRect(rect(), Qt::black); + p.fillRect(T::rect(), Qt::black); p.drawPixmap(0, 0, generateDifference()); } -- cgit v0.12 From 9c4ed99ede2de8dae005cef9a6c519e2b561a54f Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 10 Aug 2009 16:15:03 +0200 Subject: Fixed a possible problem when unplugging a QToolBar The 'break' statement was misplaced... This was found thanks to coverity --- src/gui/widgets/qtoolbararealayout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/qtoolbararealayout.cpp b/src/gui/widgets/qtoolbararealayout.cpp index b4a0ef0..afd526a 100644 --- a/src/gui/widgets/qtoolbararealayout.cpp +++ b/src/gui/widgets/qtoolbararealayout.cpp @@ -1156,8 +1156,8 @@ QLayoutItem *QToolBarAreaLayout::unplug(const QList &path, QToolBarAreaLayo if (!next.skip()) { newExtraSpace = next.pos - previous.pos - pick(line.o, previous.sizeHint()); previous.resize(line.o, next.pos - previous.pos); + break; } - break; } break; } -- cgit v0.12 From f4dba5394f6772a61af56fd25052e29a44de89ed Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 10 Aug 2009 16:27:51 +0200 Subject: Doc: Clarified the behavior of QDir::exists(). Task-number: 259091 Reviewed-by: Trust Me --- src/corelib/io/qdir.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 072eb27..cb0fdeb 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -1541,9 +1541,11 @@ bool QDir::isReadable() const /*! \overload - Returns true if the \e directory exists; otherwise returns false. - (If a file with the same name is found this function will return - false). + Returns true if the directory exists; otherwise returns false. + (If a file with the same name is found this function will return false). + + The overload of this function that accepts an argument is used to test + for the presence of files and directories within a directory. \sa QFileInfo::exists(), QFile::exists() */ @@ -1773,8 +1775,11 @@ bool QDir::rename(const QString &oldName, const QString &newName) /*! Returns true if the file called \a name exists; otherwise returns - false. Unless \a name contains an absolute file path, the file - name is assumed to be relative to the current directory. + false. + + Unless \a name contains an absolute file path, the file name is assumed + to be relative to the directory itself, so this function is typically used + to check for the presence of files within a directory. \sa QFileInfo::exists(), QFile::exists() */ -- cgit v0.12 From a4b6a5ccf5146dc5fbe2b8363b4c6fb73a8d975e Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Mon, 10 Aug 2009 16:33:25 +0200 Subject: Doc: add \since 4.6 for new functions --- src/corelib/kernel/qmetaobject.cpp | 2 ++ src/testlib/qtestcase.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index d43c5dd..f153c7e 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -2488,6 +2488,7 @@ bool QMetaProperty::isUser(const QObject *object) const } /*! + \since 4.6 Returns true if the property is constant; otherwise returns false. A property is constant if the \c{Q_PROPERTY()}'s \c CONSTANT attribute @@ -2502,6 +2503,7 @@ bool QMetaProperty::isConstant() const } /*! + \since 4.6 Returns true if the property is final; otherwise returns false. A property is final if the \c{Q_PROPERTY()}'s \c FINAL attribute diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 21a686e..51e767c 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -353,6 +353,7 @@ QT_BEGIN_NAMESPACE /*! \macro QBENCHMARK_ONCE + \since 4.6 \relates QTest -- cgit v0.12 From 724d7721331b444a6dd817cd4e12909a2cae709a Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 10 Aug 2009 16:34:12 +0200 Subject: Doc: Fixed spelling mistake and some acronyms. Task-number: 259268 Reviewed-by: Trust Me --- src/network/access/qhttp.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/network/access/qhttp.cpp b/src/network/access/qhttp.cpp index faa2398..4c06848 100644 --- a/src/network/access/qhttp.cpp +++ b/src/network/access/qhttp.cpp @@ -1597,11 +1597,11 @@ QHttp::~QHttp() This enum is used to specify the mode of connection to use: - \value ConnectionModeHttp The connection is a regular Http connection to the server - \value ConnectionModeHttps The Https protocol is used and the connection is encrypted using SSL. + \value ConnectionModeHttp The connection is a regular HTTP connection to the server + \value ConnectionModeHttps The HTTPS protocol is used and the connection is encrypted using SSL. - When using the Https mode, care should be taken to connect to the sslErrors signal, and - handle possible Ssl errors. + When using the HTTPS mode, care should be taken to connect to the sslErrors signal, and + handle possible SSL errors. \sa QSslSocket */ @@ -2039,7 +2039,7 @@ int QHttp::setHost(const QString &hostName, quint16 port) port \a port using the connection mode \a mode. If port is 0, it will use the default port for the \a mode used - (80 for Http and 443 fopr Https). + (80 for HTTP and 443 for HTTPS). The function does not block; instead, it returns immediately. The request is scheduled, and its execution is performed asynchronously. The -- cgit v0.12 From 41537bb8ea6f6174690d244a1cc07678f4bf4229 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Mon, 10 Aug 2009 16:47:41 +0200 Subject: fix issues reported by Coverity --- src/corelib/statemachine/qhistorystate.cpp | 4 +--- src/corelib/statemachine/qstate_p.h | 2 +- src/corelib/statemachine/qstatemachine.cpp | 1 + 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/corelib/statemachine/qhistorystate.cpp b/src/corelib/statemachine/qhistorystate.cpp index e5ca837..d21eee9 100644 --- a/src/corelib/statemachine/qhistorystate.cpp +++ b/src/corelib/statemachine/qhistorystate.cpp @@ -120,7 +120,7 @@ QT_BEGIN_NAMESPACE */ QHistoryStatePrivate::QHistoryStatePrivate() - : defaultState(0) + : defaultState(0), historyType(QHistoryState::ShallowHistory) { } @@ -135,8 +135,6 @@ QHistoryStatePrivate *QHistoryStatePrivate::get(QHistoryState *q) QHistoryState::QHistoryState(QState *parent) : QAbstractState(*new QHistoryStatePrivate, parent) { - Q_D(QHistoryState); - d->historyType = ShallowHistory; } /*! Constructs a new history state of the given \a type, with the given \a diff --git a/src/corelib/statemachine/qstate_p.h b/src/corelib/statemachine/qstate_p.h index 20eb5ea..c43a26c 100644 --- a/src/corelib/statemachine/qstate_p.h +++ b/src/corelib/statemachine/qstate_p.h @@ -64,7 +64,7 @@ QT_BEGIN_NAMESPACE struct QPropertyAssignment { QPropertyAssignment() - : object(0) {} + : object(0), explicitlySet(true) {} QPropertyAssignment(QObject *o, const QByteArray &n, const QVariant &v, bool es = true) : object(o), propertyName(n), value(v), explicitlySet(es) diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 9cb1d4d..5926176 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -209,6 +209,7 @@ QStateMachinePrivate::QStateMachinePrivate() processing = false; processingScheduled = false; stop = false; + stopProcessingReason = EventQueueEmpty; error = QStateMachine::NoError; globalRestorePolicy = QStateMachine::DoNotRestoreProperties; signalEventGenerator = 0; -- cgit v0.12 From 66f26230a463fef12e8c95ea7819e476e038d4f8 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 10 Aug 2009 16:53:28 +0200 Subject: Linguist: Fixed spehling error. --- tools/linguist/linguist/mainwindow.cpp | 10 +++++----- tools/linguist/linguist/mainwindow.ui | 6 +++--- tools/linguist/linguist/messageeditor.cpp | 2 +- tools/linguist/linguist/messageeditor.h | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tools/linguist/linguist/mainwindow.cpp b/tools/linguist/linguist/mainwindow.cpp index bb79b19..22ff46a 100644 --- a/tools/linguist/linguist/mainwindow.cpp +++ b/tools/linguist/linguist/mainwindow.cpp @@ -482,9 +482,9 @@ MainWindow::MainWindow() readConfig(); m_statistics = 0; - connect(m_ui.actionLenghtVariants, SIGNAL(toggled(bool)), - m_messageEditor, SLOT(setLenghtVariants(bool))); - m_messageEditor->setLenghtVariants(m_ui.actionLenghtVariants->isChecked()); + connect(m_ui.actionLengthVariants, SIGNAL(toggled(bool)), + m_messageEditor, SLOT(setLengthVariants(bool))); + m_messageEditor->setLengthVariants(m_ui.actionLengthVariants->isChecked()); m_focusWatcher = new FocusWatcher(m_messageEditor, this); m_contextView->installEventFilter(m_focusWatcher); @@ -2521,7 +2521,7 @@ void MainWindow::readConfig() config.value(settingPath("Validators/PhraseMatch"), true).toBool()); m_ui.actionPlaceMarkerMatches->setChecked( config.value(settingPath("Validators/PlaceMarkers"), true).toBool()); - m_ui.actionLenghtVariants->setChecked( + m_ui.actionLengthVariants->setChecked( config.value(settingPath("Options/LengthVariants"), false).toBool()); recentFiles().readConfig(); @@ -2548,7 +2548,7 @@ void MainWindow::writeConfig() config.setValue(settingPath("Validators/PlaceMarkers"), m_ui.actionPlaceMarkerMatches->isChecked()); config.setValue(settingPath("Options/LengthVariants"), - m_ui.actionLenghtVariants->isChecked()); + m_ui.actionLengthVariants->isChecked()); config.setValue(settingPath("MainWindowState"), saveState()); recentFiles().writeConfig(); diff --git a/tools/linguist/linguist/mainwindow.ui b/tools/linguist/linguist/mainwindow.ui index 613241b..9dfb1ff 100644 --- a/tools/linguist/linguist/mainwindow.ui +++ b/tools/linguist/linguist/mainwindow.ui @@ -116,7 +116,7 @@ - + @@ -878,12 +878,12 @@ Ctrl+W - + true - Lenght Variants + Length Variants diff --git a/tools/linguist/linguist/messageeditor.cpp b/tools/linguist/linguist/messageeditor.cpp index 9e598a8..e911389 100644 --- a/tools/linguist/linguist/messageeditor.cpp +++ b/tools/linguist/linguist/messageeditor.cpp @@ -710,7 +710,7 @@ void MessageEditor::setEditingEnabled(int model, bool enabled) updateCanPaste(); } -void MessageEditor::setLenghtVariants(bool on) +void MessageEditor::setLengthVariants(bool on) { m_lengthVariants = on; foreach (const MessageEditorData &ed, m_editors) diff --git a/tools/linguist/linguist/messageeditor.h b/tools/linguist/linguist/messageeditor.h index 4106036..b195a04 100644 --- a/tools/linguist/linguist/messageeditor.h +++ b/tools/linguist/linguist/messageeditor.h @@ -110,7 +110,7 @@ public slots: void beginFromSource(); void setEditorFocus(); void setTranslation(int latestModel, const QString &translation); - void setLenghtVariants(bool on); + void setLengthVariants(bool on); private slots: void editorCreated(QTextEdit *); -- cgit v0.12 From cbd8a54f8c55e1982430fc929e9d74f977699428 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 10 Aug 2009 16:54:24 +0200 Subject: Translations: Purged and updated German of Assistant/Linguist/Help. --- translations/assistant_de.ts | 304 +++-------- translations/linguist_de.ts | 1180 +++++++----------------------------------- translations/qt_help_de.ts | 40 +- 3 files changed, 310 insertions(+), 1214 deletions(-) diff --git a/translations/assistant_de.ts b/translations/assistant_de.ts index f702465..ce32062 100644 --- a/translations/assistant_de.ts +++ b/translations/assistant_de.ts @@ -52,11 +52,11 @@ Neuer Ordner - + - - - + + + Bookmarks Lesezeichen @@ -66,7 +66,7 @@ + - + Delete Folder Ordner löschen @@ -79,12 +79,12 @@ BookmarkManager - + Bookmarks Lesezeichen - + Remove Entfernen @@ -94,7 +94,7 @@ Wenn Sie diesen Ordner löschen, wird auch<br>dessen kompletter Inhalt gelöscht. Möchten Sie wirklich fortfahren? - + New Folder Neuer Ordner @@ -103,25 +103,17 @@ BookmarkWidget - + Filter: Filter: - Bookmarks - Lesezeichen - - - + Remove Entfernen - You are going to delete a Folder, this will also<br>remove it's content. Are you sure to continue? - Wenn Sie dieses Verzeichnis löschen, wird auch<br>dessen kompletter Inhalt gelöscht! Fortfahren? - - - + Delete Folder Ordner löschen @@ -151,11 +143,7 @@ Lesezeichen umbenennen - Search for: - Suchen: - - - + Add Hinzufügen @@ -163,7 +151,7 @@ CentralWidget - + Add new page Neue Seite hinzufügen @@ -173,7 +161,7 @@ Aktuelle Seite schließen - + Print Document Drucken @@ -184,7 +172,7 @@ unbekannt - + Add New Page Neue Seite hinzufügen @@ -204,7 +192,7 @@ Lesezeichen für diese Seite hinzufügen ... - + Search Suchen @@ -212,7 +200,7 @@ ContentWindow - + Open Link Link öffnen @@ -225,10 +213,6 @@ FilterNameDialogClass - FilterNameDialog - FilterNameDialog - - Add Filter Name Filternamen hinzufügen @@ -242,7 +226,7 @@ FindWidget - + Previous Zurück @@ -303,12 +287,6 @@ Hilfe - Unable to launch web browser. - - Der Webbrowser konnte nicht gestarted werden. - - - OK OK @@ -362,13 +340,13 @@ InstallDialog - + Install Documentation Dokumentation installieren - + Downloading documentation info... Dokumentationsinformation herunterladen ... @@ -462,20 +440,20 @@ MainWindow - - + + Index Index - - + + Contents Inhalt - - + + Bookmarks Lesezeichen @@ -485,24 +463,20 @@ Suchen - - - + + + Qt Assistant Qt Assistant - + Unfiltered Ohne Filter - File - Datei - - - + Page Set&up... S&eite einrichten ... @@ -517,111 +491,62 @@ &Drucken ... - CTRL+P - CTRL+P - - - + New &Tab Neuer &Tab - CTRL+T - CTRL+T - - &Close Tab Tab &schließen - CTRL+W - CTRL+W - - &Quit &Beenden - - CTRL+Q - CTRL+Q - - - Edit - Bearbeiten - - - + &Copy selected Text Ausgewählten Text &kopieren - Ctrl+C - Ctrl+C - - - + &Find in Text... &Textsuche ... - Ctrl+F - Ctrl+F - - - + Find &Next &Weitersuchen - F3 - F3 - - Find &Previous &Vorheriges suchen - Shift+F3 - Shift+F3 - - Preferences... Einstellungen ... - View - Ansicht - - Zoom &in &Vergrößern - Ctrl++ - Ctrl++ - - - + Zoom &out Ver&kleinern - Ctrl+- - Ctrl+- - - - + Normal &Size Standard&größe - + Ctrl+0 Ctrl+0 @@ -636,30 +561,17 @@ ALT+I - ALT+B - ALT+B - - ALT+S ALT+S - Go - Gehe - - &Home &Startseite - - Ctrl+Home - Ctrl+Home - - - + &Back &Rückwärts @@ -669,12 +581,12 @@ &Vorwärts - + Sync with Table of Contents Seite mit Inhalt-Tab abgleichen - + Next Page Nächste Seite @@ -699,15 +611,7 @@ Lesezeichen hinzufügen ... - CTRL+B - CTRL+B - - - Help - Hilfe - - - + About... Über ... @@ -747,38 +651,22 @@ Der zugehörige Inhaltseintrag konnte nicht gefunden werden. - Open Source Edition - Open Source Edition - - - This version of Qt Assistant is part of the Qt Open Source Edition, for use in the development of Open Source applications. Qt is a comprehensive C++ framework for cross-platform application development. - This version of Qt Assistant is part of the Qt Open Source Edition, for use in the development of Open Source applications. Qt is a comprehensive C++ framework for cross-platform application development. - - - You need a commercial Qt license for development of proprietary (closed source) applications. Please see <a href="http://qtsoftware.com/company/model.html">qtsoftware.com/company/model.html</a> for an overview of Qt licensing. - You need a commercial Qt license for development of proprietary (closed source) applications. Please see <a href="http://qtsoftware.com/company/model.html">qtsoftware.com/company/model.html</a> for an overview of Qt licensing. - - - This program is licensed to you under the terms of the Qt Commercial License Agreement. For details, see the file LICENSE that came with this software distribution. - This program is licensed to you under the terms of the Qt Commercial License Agreement. For details, see the file LICENSE that came with this software distribution. - - - + About %1 Über %1 - + Updating search index Suchindex wird aufgebaut - + Looking for Qt Documentation... Suche nach Qt-Dokumentation ... - + &Window &Fenster @@ -798,54 +686,47 @@ Zoom - Add - Hinzufügen - - - Remove - Entfernen - - - + &File &Datei - + &Edit &Bearbeiten - + &View &Ansicht - + &Go &Gehe zu + + ALT+Home + + + &Bookmarks &Lesezeichen - + &Help &Hilfe - You need a commercial Qt license for development of proprietary (closed source) applications. Please see <a href="http://qtsoftware.com/company/about/businessmodel">http://qtsoftware.com/company/about/businessmodel</a> for an overview of Qt licensing. - Sie benötigen eine kommerzielle Qt Lizenz für die Entwicklung von proprietären (geschlossenen) Anwendungen. Besuchen Sie <a href="http://qtsoftware.com/company/about/businessmodel">http://qtsoftware.com/company/about/businessmodel</a> um sich einen Überblick über die Qt Lizenzvergabe zu verschaffen. - - - + ALT+O ALT+O - + CTRL+D CTRL+D @@ -853,15 +734,7 @@ PreferencesDialog - From Local File System... - Von Dateisystem... - - - Download from Help Server... - Von Hilfe-Server herunterladen... - - - + Add Documentation Dokumentation hinzufügen @@ -902,7 +775,7 @@ OK - + Use custom settings Benutzerdefinierte Einstellungen verwenden @@ -980,22 +853,6 @@ Hinzufügen ... - Network - Netzwerk - - - Use Http Proxy - Http Proxy - - - Http Proxy: - Http Proxy: - - - Port: - Port: - - Options Einstellungen @@ -1015,14 +872,35 @@ Homepage Startseite + + + On help start: + Zu Beginn: + + + + Show my home page + Startseite zeigen + + + + Show a blank page + Leere Seite zeigen + + + + Show my tabs from last session + Reiter aus letzter Sitzung zeigen + + + + Blank Page + Leere Seite + QObject - New Folder - Neuer Ordner - - The specified collection file does not exist! Die angegebene Katalogdatei (collection file) kann nicht gefunden werden. @@ -1085,7 +963,7 @@ Qt Assistant - + Could not register documentation file %1 @@ -1128,12 +1006,6 @@ Grund: The specified collection file could not be read! Die angegebene Katalogdatei (collection file) kann nicht gelesen werden. - - - - Bookmark - Lesezeichen - RemoteControl @@ -1170,10 +1042,6 @@ Grund: Select All Alles markieren - - Open Link - Link öffnen - TopicChooser diff --git a/translations/linguist_de.ts b/translations/linguist_de.ts index 48f1f2e..8924b6e 100644 --- a/translations/linguist_de.ts +++ b/translations/linguist_de.ts @@ -2,24 +2,9 @@ - - - - (New Entry) - (Neuer Eintrag) - - - - @default - - (New Phrase) - (Neue Phrase) - - - AboutDialog - + Qt Linguist Qt Linguist @@ -76,11 +61,6 @@ - Note that the modified entries will be reset to unfinished if 'Set translated entries to finished' above is unchecked. - Beachten Sie, dass die geänderten Einträge in den Status 'unerledigt' zurückgesetzt werden, wenn 'Übersetzung als erledigt markieren' deaktiviert ist. - - - Translate also finished entries Erledigte Einträge übersetzen @@ -101,11 +81,6 @@ - The batch translator will search through the selected phrase books in the order given above. - Der automatische Übersetzer wird in der angegebenen Reihenfolge durch die ausgewählten Wörterbücher gehen. - - - &Run &Ausführen @@ -114,6 +89,16 @@ Cancel Abbrechen + + + Note that the modified entries will be reset to unfinished if 'Set translated entries to finished' above is unchecked + Geänderte Einträge werden als unerledigt gekennzeichnet, wenn die obige Einstellung 'Übersetzung als erledigt markieren' nicht aktiviert ist + + + + The batch translator will search through the selected phrase books in the order given above + Der automatische Übersetzer wird in der angegebenen Reihenfolge durch die ausgewählten Wörterbücher gehen + DataModel @@ -156,61 +141,6 @@ Es wird mit einer einfachen Universalform gearbeitet. - EditorPage - - Source text - Ursprungstext - - - This area shows the source text. - Dieser Bereich zeigt den Ursprungstext. - - - This area shows a comment that may guide you, and the context in which the text occurs. - Dieser Bereich zeigt eventuelle Kommentare und den Kontext, in dem der Text auftritt. - - - Existing %1 translation - Existierende Übersetzung %1 - - - Translation - Übersetzung - - - %1 translation - Übersetzung %1 - - - %1 translation (%2) - Übersetzung %1 (%2) - - - This is where you can enter or modify the translation of some source text. - Hier können Sie die Übersetzung des Ursprungstextes eingeben bzw. ändern. - - - German - Deutsch - - - Japanese - Japanisch - - - French - Französisch - - - Polish - Polnisch - - - Chinese - Chinesisch - - - ErrorsView @@ -251,19 +181,11 @@ Es wird mit einer einfachen Universalform gearbeitet. FindDialog - Qt Linguist - Qt Linguist - - This window allows you to search for some text in the translation source file. Dieses Fenster erlaubt die Suche in der Übersetzungsdatei. - Find what: - Suchen nach: - - Type in the text to search for. Geben Sie den Text ein, nach dem gesucht werden soll. @@ -279,37 +201,21 @@ Es wird mit einer einfachen Universalform gearbeitet. Wenn aktiviert, wird in den Ursprungstexten gesucht. - Source texts - Ursprungsstexte - - Translations are searched when checked. Wenn ausgewählt, wird in den Übersetzungen gesucht. - Translations - Übersetzungen - - Texts such as 'TeX' and 'tex' are considered as different when checked. Wenn aktiviert, werden Texte wie 'TeX' und 'tex' als unterschiedlich betrachtet. - Match case - Groß-/Kleinschreibung beachten - - Comments and contexts are searched when checked. Wenn ausgewählt, werden Kommentare und Kontextnamen durchsucht. - Comments - Kommentare - - Find Suchen @@ -365,10 +271,6 @@ Es wird mit einer einfachen Universalform gearbeitet. Abbrechen - Ignore accelerators - Kurztasten ignorieren - - Choose Edit|Find from the menu bar or press Ctrl+F to pop up the Find dialog @@ -376,16 +278,56 @@ Es wird mit einer einfachen Universalform gearbeitet. - FormHolder + FormMultiWidget + + + Alt+Delete + translate, but don't change + + + + + Shift+Alt+Insert + translate, but don't change + + + + + Alt+Insert + translate, but don't change + + + + + Confirmation - Qt Linguist + Bestätigung - Qt Linguist + - Preview Form - Vorschau + + Delete non-empty length variant? + Soll die ausgefüllte Längenvariante gelöscht werden? LRelease - + + Dropped %n message(s) which had no ID. + + Es wurde ein Eintrag ohne Bezeichner gelöscht. + Es wurde %n Einträge ohne Bezeichner gelöscht. + + + + + Excess context/disambiguation dropped from %n message(s). + + Es wurde überflüssiger Kontext beziehungsweise überflüssige Infomation zur Unterscheidung bei einem Eintrag entfernt. + Es wurde überflüssiger Kontext beziehungsweise überflüssige Infomation zur Unterscheidung bei %n Einträgen entfernt. + + + + Generated %n translation(s) (%1 finished and %2 unfinished) @@ -408,89 +350,6 @@ Es wird mit einer einfachen Universalform gearbeitet. - LanguagesDialog - - Open Translation File - Öffne Übersetzungsdatei - - - Qt translation sources (%1);;Qt translation sources (*.ts);;XLIFF localization files (*.xlf);;All files (*) - Qt Übersetzungsdateien (%1);;Qt Übersetzungsdateien (*.ts);;XLIFF Lokalisierungsdateien (*.xlf);;Alle Dateien (*) - - - Auxiliary Languages - Unterstützende Sprachen - - - Locale - Regionalschema - - - File - Datei - - - <html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Move selected language up</p></body></html> - <html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Bewege ausgewählte Sprache herauf</p></body></html> - - - up - Hoch - - - <html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;">Move selected language down</p></body></html> - <html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;">Bewege ausgewählte Sprache herunter</p></body></html> - - - down - Herunter - - - <html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Remove selected language</p></body></html> - <html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Entferne ausgewählte Sprache</p></body></html> - - - remove - Entfernen - - - <html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Open auxiliary language files</p></body></html> - <html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Öffne unterstützende Sprachen</p></body></html> - - - ... - ... - - - OK - OK - - - MainWindow @@ -538,10 +397,6 @@ p, li { white-space: pre-wrap; } &Werkzeugleisten - Too&ls - &Werkzeuge - - &Help &Hilfe @@ -557,19 +412,11 @@ p, li { white-space: pre-wrap; } &Datei - Re&cently Opened Files - &Zuletzt geöffnete Dateien - - &Edit &Bearbeiten - &New - &Neu - - &Open... Ö&ffnen ... @@ -612,51 +459,26 @@ p, li { white-space: pre-wrap; } - Previous unfinished item. - Vorheriger unerledigter Eintrag. - - - Move to the previous unfinished item. Zum vorherigen unerledigten Eintrag gehen. - Next unfinished item. - Nächster unerledigter Eintrag. - - - Move to the next unfinished item. Zum nächsten unerledigten Eintrag gehen. - Move to previous item. - Zum vorigen Eintrag gehen. - - - Move to the previous item. Zum vorigen Eintrag gehen. - Next item. - Nächster Eintrag. - - - Move to the next item. Zum nächsten Eintrag gehen. - Mark item as done and move to the next unfinished item. - Eintrag als erledigt markieren und zum nächsten unerledigten Eintrag gehen. - - - Mark this item as done and move to the next unfinished item. Diesen Eintrag als erledigt markieren und zum nächsten unerledigten Eintrag gehen. @@ -667,21 +489,11 @@ p, li { white-space: pre-wrap; } - Toggle the validity check of accelerators. - Prüfung der Tastenkürzel ein- bzw. ausschalten. - - - Toggle the validity check of accelerators, i.e. whether the number of ampersands in the source and translation text is the same. If the check fails, a message is shown in the warnings window. Die Prüfung der Tastenkürzel, das heißt, die Übereinstimmung der kaufmännischen Und-Zeichen in Quelle und Übersetzung ein- bzw. ausschalten. Bei Fehlschlag wird eine Warnung im Hinweis-Fenster angezeigt. - Toggle the validity check of ending punctuation. - Prüfung der Satzendezeichen am Ende des Textes ein- bzw. ausschalten. - - - Toggle the validity check of ending punctuation. If the check fails, a message is shown in the warnings window. Die Prüfung der Satzendezeichen am Ende des Textes ein- bzw. ausschalten. Bei Fehlschlag wird eine Warnung im Hinweis-Fenster angezeigt. @@ -692,11 +504,6 @@ p, li { white-space: pre-wrap; } - Toggle the validity check of place markers. - Prüfung der Platzhalter ein- bzw. ausschalten. - - - Toggle the validity check of place markers, i.e. whether %1, %2, ... are used consistently in the source text and translation text. If the check fails, a message is shown in the warnings window. Die Prüfung der Platzhalter, das heißt, ob %1, %2 usw. in Ursprungstext und Übersetzung übereinstimmend verwendet werden, ein- bzw. ausschalten. Bei Fehlschlag wird eine Warnung im Hinweis-Fenster angezeigt. @@ -716,14 +523,14 @@ p, li { white-space: pre-wrap; } Ctrl+S + - Save &As... Speichern &unter... - + Save As... Speichern unter ... @@ -748,10 +555,6 @@ p, li { white-space: pre-wrap; } &Drucken ... - Print a list of all the phrases in the current Qt translation source file. - Drucke die Liste aller Übersetzungen in der aktuellen Qt Übersetzungsdatei. - - Ctrl+P Ctrl+P @@ -762,10 +565,6 @@ p, li { white-space: pre-wrap; } &Rückgängig - Undo the last editing operation performed on the translation. - Mache die letzte Änderung an der Übersetzung rückgängig. - - Recently Opened &Files Zu&letzt bearbeitete Dateien @@ -916,10 +715,6 @@ p, li { white-space: pre-wrap; } Ctrl+W - Moves to the previous unfinished item. - Gehe zum letzten unerledigten Eintrag. - - Ctrl+K Ctrl+K @@ -930,23 +725,11 @@ p, li { white-space: pre-wrap; } &Nächster Unerledigter - Moves to the next unfinished item. - Gehe zum nächsten unerledigten Eintrag. - - - Ctrl+L - Ctrl+L - - P&rev V&orheriger - Moves to the previous item. - Gehe zum letzten Eintrag. - - Ctrl+Shift+K Ctrl+Shift+K @@ -957,27 +740,11 @@ p, li { white-space: pre-wrap; } Nä&chster - Moves to the next item. - Gehe zum nächsten Eintrag. - - - Ctrl+Shift+L - Ctrl+Shift+L - - &Done and Next &Fertig und Nächster - Marks this item as done and moves to the next unfinished item. - Markiere diesen Eintrag als erledigt und gehe zum nächsten unerledigten Eintrg. - - - &Begin from source - Übernehme &Ursprungstext - - Copies the source text into the translation field. Kopiert den Ursprungstext in das Übersetzungsfeld. @@ -993,38 +760,21 @@ p, li { white-space: pre-wrap; } &Kurzbefehle - Toggle validity checks of accelerators. - Aktiviere/Deaktiviere Validitätsprüfung für Kurztasten. - - &Ending Punctuation &Punktierung am Ende - Toggle validity checks of ending punctuation. - Aktiviere/Deaktiviere Validitätsprüfung für Punktierung am Ende des Textes. - - &Phrase matches &Wörterbuch - Toggle checking that phrase suggestions are used. - Überprüfung, ob Wörterbucheinträge benutzt werden, aktivieren/deaktivieren. - - - Place &Marker Matches Platz&halter - Toggle validity checks of place markers. - Aktiviere/Deaktiviere Validitätsprüfung für Platzhalter . - - &New Phrase Book... &Neues Wörterbuch ... @@ -1140,36 +890,31 @@ p, li { white-space: pre-wrap; } Die Übersetzung aller Einträge ersetzen, die dem Suchtext entsprechen. + - &Batch Translation... &Automatische Übersetzung ... - + Batch translate all entries using the information in the phrase books. Alle Einträge automatisch mit Hilfe des Wörterbuchs übersetzen. + - Release As... Freigeben unter ... - - Create a Qt message file suitable for released applications from the current message file. The filename will automatically be determined from the name of the .ts file. - Eine Qt-Nachrichtendatei aus der aktuellen Übersetzungsdatei erzeugen. Der Dateiname wird automatisch aus dem Namen der TS-Datei abgeleitet. - - - + This is the application's main window. - + Source text Ursprungstext @@ -1181,17 +926,17 @@ p, li { white-space: pre-wrap; } - + Context Kontext - + Items Einträge - + This panel lists the source contexts. Dieser Bereich zeigt die Kontexte an. @@ -1219,10 +964,10 @@ p, li { white-space: pre-wrap; } MOD status bar: file(s) modified - + Geändert - + Loading... Lade ... @@ -1275,14 +1020,19 @@ Soll die erstgenannte Datei übersprungen werden? Datei gespeichert. - - + + <center><img src=":/images/splash.png"/></img><p>%1</p></center><p>Qt Linguist is a tool for adding translations to Qt applications.</p><p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).</p><p>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.</p> + + + + + Release Freigeben - + Qt message files for released applications (*.qm) All files (*) Qt-Nachrichtendateien (*.qm) @@ -1295,7 +1045,7 @@ Alle Dateien (*) Datei erzeugt. - + Printing... Drucke ... @@ -1346,7 +1096,7 @@ Alle Dateien (*) - + @@ -1358,18 +1108,11 @@ Alle Dateien (*) Qt Linguist - + Cannot find the string '%1'. Kann Zeichenkette '%1' nicht finden. - - Translated %n entries to '%1' - - Ein Eintrag wurde mit '%1' übersetzt - %n Einträge wurden mit '%1' übersetzt - - Search And Translate in '%1' - Qt Linguist @@ -1463,16 +1206,7 @@ Alle Dateien (*) Version %1 - Open Source Edition - Open Source Edition - - - - <center><img src=":/images/splash.png"/></img><p>%1</p></center><p>Qt Linguist is a tool for adding translations to Qt applications.</p><p>%2</p><p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).</p><p>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.</p> - <center><img src=":/images/splash.png"/></img><p>%1</p></center><p>Qt Linguist ist ein Werkzeug zum Übersetzen von Qt-Anwendungen.</p><p>%2</p><p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).</p><p>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.</p> - - - + Do you want to save the modified files? Möchten Sie die geänderten Dateien speichern? @@ -1559,13 +1293,13 @@ Alle Dateien (*) Alles speichern - + &Release All Alles f&reigeben - + Close All Alle schließen @@ -1590,37 +1324,37 @@ Alle Dateien (*) Suchen und &übersetzen ... - + File Datei - - + + Edit Bearbeiten - - + + Translation Übersetzung - - + + Validation Validierung - - + + Help Hilfe - + Cannot read from phrase book '%1'. Wörterbuch '%1' kann nicht gelesen werden. @@ -1650,7 +1384,7 @@ Alle Dateien (*) Möchten Sie das Wörterbuch '%1' speichern? - + All Alle @@ -1670,21 +1404,13 @@ Alle Dateien (*) F5 - - + + Translation File &Settings... E&instellungen ... - Other &Languages... - A&ndere Sprachen... - - - Edit which other languages to show. - Welche anderen Sprachen sollen dargestellt werden. - - - + &Add to Phrase Book Zum Wörterbuch &hinzufügen @@ -1703,22 +1429,93 @@ Alle Dateien (*) Ctrl+Shift+J Ctrl+Shift+J - - - MessageEditor - - German - Deutsch + + Previous unfinished item + Vorheriger unerledigter Eintrag - - Japanese - Japanisch + + Next unfinished item + Nächster unerledigter Eintrag - - French + + Move to previous item + Zum vorigen Eintrag gehen + + + + Next item + Nächster Eintrag + + + + Mark item as done and move to the next unfinished item + Eintrag als erledigt markieren und zum nächsten unerledigten Eintrag gehen + + + + Copies the source text into the translation field + Kopiert den Ursprungstext in das Übersetzungsfeld + + + + Toggle the validity check of accelerators + Prüfung der Tastenkürzel ein- bzw. ausschalten + + + + Toggle the validity check of ending punctuation + Prüfung der Satzendezeichen am Ende des Textes ein- bzw. ausschalten + + + + Toggle checking that phrase suggestions are used + Überprüfung, ob Wörterbucheinträge benutzt werden, aktivieren/deaktivieren + + + + Toggle the validity check of place markers + Prüfung der Platzhalter ein- bzw. ausschalten' + + + + Create a Qt message file suitable for released applications from the current message file. The filename will automatically be determined from the name of the TS file. + Eine Qt-Nachrichtendatei aus der aktuellen Übersetzungsdatei erzeugen. Der Dateiname wird automatisch aus dem Namen der TS-Datei abgeleitet. + + + + Length Variants + Längenvarianten + + + + MessageEditor + + + + This is the right panel of the main window. + + + + + Russian + Russisch + + + + German + Deutsch + + + + Japanese + Japanisch + + + + French Französisch @@ -1732,7 +1529,7 @@ Alle Dateien (*) Chinesisch - + This whole panel allows you to view and edit the translation of some source text. Dieser Bereich erlaubt die Darstellung und Änderung der Übersetzung eines Textes. @@ -1747,7 +1544,7 @@ Alle Dateien (*) Dieser Bereich zeigt den Ursprungstext. - + Source text (Plural) Ursprungstext (Plural) @@ -1757,7 +1554,7 @@ Alle Dateien (*) Dieser Bereich zeigt die Pluralform des Ursprungstexts. - + Developer comments Hinweise des Entwicklers @@ -1772,12 +1569,12 @@ Alle Dateien (*) Hier können Sie Hinweise für den eigenen Gebrauch eintragen. Diese haben keinen Einflusse auf die Übersetzung. - + %1 translation (%2) Übersetzung %1 (%2) - + This is where you can enter or modify the translation of the above source text. Hier können Sie die Übersetzung des Ursprungstextes eingeben bzw. ändern. @@ -1792,56 +1589,16 @@ Alle Dateien (*) %1 Hinweise des Übersetzers - + '%1' Line: %2 '%1' Zeile: %2 - - %1 Translation (%2) - Übersetzung %1 (%2) - - - bell - bell - - - backspace - Rücktaste - - - new page - Neue Seite - - - new line - Neue Zeile - - - carriage return - Carriage Return - - - tab - Tab - MessageModel - Context - Kontext - - - Items - Einträge - - - Index - Index - - Completion status for %1 Bearbeitungsstand von %1 @@ -1863,16 +1620,9 @@ Zeile: %2 - MessagesTreeView - - Done - Done - - - MsgEdit - + This is the right panel of the main window. @@ -1881,17 +1631,18 @@ Zeile: %2 PhraseBookBox - %1 - %2[*] - %1 - %2[*] - - - + Go to Phrase > Edit Phrase Book... The dialog that pops up is a PhraseBookBox. - + + (New Entry) + (Neuer Eintrag) + + + %1[*] - Qt Linguist %1[*] - Qt Linguist @@ -1911,10 +1662,6 @@ Zeile: %2 Wörterbuch bearbeiten - This window allows you to add, modify, or delete phrases in a phrase book. - Dieses Fenster erlaubt das Hinzufügen, Ändern und Entfernen von Einträgen aus dem Wörterbuch. - - This window allows you to add, modify, or delete entries in a phrase book. Dieses Fenster erlaubt das Hinzufügen, Ändern und Entfernen von Wörterbuch-Einträgen. @@ -1975,18 +1722,6 @@ Zeile: %2 &Einstellungen ... - &New Phrase - &Neuer Eintrag - - - Click here to remove the phrase from the phrase book. - Entferne den Eintrag aus dem Wörterbuch. - - - &Remove Phrase - &Entferne Eintrag - - Click here to save the changes made. Änderungen speichern. @@ -2028,7 +1763,7 @@ Zeile: %2 PhraseView - + Insert Einfügen @@ -2056,7 +1791,7 @@ Zeile: %2 Kompilierte Qt-Übersetzungen - + Translation files (%1);; Übersetzungsdateien (%1);; @@ -2077,26 +1812,11 @@ Zeile: %2 Qt Linguist - - C++ source files - C++-Quelltextdateien - - - - Java source files - Java-Quelltextdateien - - - + GNU Gettext localization files GNU-Gettext-Übersetzungsdateien - - Qt Script source files - Qt-Skript-Quelltextdateien - - Qt translation sources (format 1.1) Qt-Übersetzungsdateien (Formatversion 1.1) @@ -2112,61 +1832,17 @@ Zeile: %2 Qt-Übersetzungsdateien (aktuelles Format) - - Qt Designer form files - Formulardateien für Qt Designer - - - - Qt Jambi form files - Formulardateien für Qt Jambi - - - + XLIFF localization files XLIFF-Übersetzungsdateien - + Qt Linguist 'Phrase Book' Qt-Linguist-Wörterbuch - QtWindowListMenu - - Tile - Teilen - - - Cascade - Kaskadieren - - - Close - Schließen - - - Close All - Alle schließen - - - - SortedMessagesModel - - Source text - Ursprungstext - - - Translation - Übersetzung - - - Index - Index - - - SourceCodeView @@ -2192,10 +1868,6 @@ Zeile: %2 Statistiken - &Close - &Schließen - - Translation Übersetzung @@ -2232,406 +1904,8 @@ Zeile: %2 - TrPreviewTool - - <No Translation> - <Keine Übersetzung> - - - Open Forms - Öffne Maske - - - User interface form files (*.ui);;All files (*.*) - User Interface Masken Dateien (*.ui);;Alle Dateien (*.*) - - - Could not load form file(s): - - Könnte Quelldateien nicht laden: - - - - Load Translation - Lade Übersetzung - - - Translation files (*.qm);;All files (*.*) - Übersetzungsdateien (*.qm);;Alle Dateien (*.*) - - - Could not load translation file: - - Konnte Übersetzungsdatei nicht laden: - - - - Could not reload translation file(s): - - Konnte Übersetzungsdateien nicht erneut laden: - - - - Qt Translation Preview Tool: Warning - Qt Vorschau: Warnung - - - About - Info - - - Could not load form file: -%1. - Konnte Maskendatei nicht laden. -%1. - - - - TrPreviewToolClass - - Qt Translation Preview Tool - Qt Vorschau Tool - - - &View - &Ansicht - - - &Views - &Ansichten - - - &Help - &Hilfe - - - &File - &Datei - - - Forms - Masken - - - &Open Form... - &Öffne Maske... - - - &Load Translation... - &Lade Übersetzung... - - - &Reload Translations - Lade Übersetzungen &neu - - - F5 - F5 - - - &Close - &Schließen - - - About - Info - - - About Qt - Über Qt - - - - TrWindow - - Context - Kontext - - - This panel lists the source contexts. - Dieser Bereich zeigt die Kontexte an. - - - Strings - Zeichenketten - - - Phrases and guesses - Wörterbuch und Vorschläge - - - Source code - Quelltext - - - Warnings - Warnungen - - - MOD - MOD - - - Loading... - Lade... - - - Qt Linguist - Qt Linguist - - - Cannot open '%1'. - Kann '%1' nicht öffnen. - - - %n source phrase(s) loaded. - - Einen Ursprungstext geladen. - %n Ursprungstexte geladen. - - - - Open Translation File - Öffne Übersetzungsdatei - - - Qt translation sources (*.ts);;XLIFF localization files (*.xlf);;All files (*) - Qt Übersetzungsdateien (*.ts);;Qt Übersetzungsdateien (*.ts);;Alle Dateien (*) - - - File saved. - Datei gespeichert. - - - Cannot save '%1'. - Kann '%1' nicht speichern. - - - Qt translation source (*.ts) -XLIFF localization file (*.xlf) -All files (*) - Qt Übersetzungsdateien (*.ts) -Qt Übersetzungsdateien (*.ts) -Alle Dateien (*) - - - Release - Freigeben - - - Qt message files for released applications (*.qm) -All files (*) - Qt Nachrichtendateien (*.qm) -Alle Dateien (*) - - - File created. - Datei erzeugt. - - - Printing... - Drucke... - - - Context: %1 - Kontext: %1 - - - finished - erledigt - - - unresolved - ungelöst - - - obsolete - veraltet - - - Printing... (page %1) - Drucke... (Seite %1) - - - Printing completed - Drucken beendet - - - Printing aborted - Drucken abgebrochen - - - Search wrapped. - Suche beginnt von oben. - - - Cannot find the string '%1'. - Kann Zeichenkette '%1' nicht finden. - - - Translate - Übersetzungen - - - Translated %n entries to '%1' - - Ein Eintrag wurde mit '%1' übersetzt - %n Einträge wurden mit '%1' übersetzt - - - - Create New Phrase Book - Erzeugen eines neuen Wörterbuchs - - - Qt phrase books (*.qph) -All files (*) - Qt Wörterbücher (*.qph) -Alle Dateien (*) - - - A file called '%1' already exists. Please choose another name. - Die Datei '%1' existiert schon. Bitte wählen Sie einen anderen Namen. - - - Phrase book created. - Wörterbuch erzeugt. - - - Open Phrase Book - Öffne Wörterbuch - - - Qt phrase books (*.qph);;All files (*) - Qt Wörterbücher (*.qph);;Alle Dateien (*) - - - %n phrase(s) loaded. - - Ein Wörterbucheintrag geladen. - %n Wörterbucheinträge geladen. - - - - Add to phrase book - Hinzufügen zum Wörterbuch - - - Adding phrase to phrasebook %1 - Eintrag zu Wörterbuch %1 hinzufügen - - - Select phrase book to add to - Zu welchem Wörterbuch soll der Eintrag hinzugefügt werden? - - - Unable to launch Qt Assistant (%1) - Kann Qt Assistant nicht starten (%1) - - - Version %1 - Version %1 - - - Open Source Edition - Open Source Edition - - - <center><img src=":/images/splash.png"/></img><p>%1</p></center><p>Qt Linguist is a tool for adding translations to Qt applications.</p><p>%2</p><p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).</p><p>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.</p> - <center><img src=":/images/splash.png"/></img><p>%1</p></center><p>Qt Linguist ist ein Werkzeug zum Übersetzen von Qt Anwendungen.</p><p>%2</p><p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).</p><p>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.</p> - - - Do you want to save '%1'? - Wollen Sie '%1' speichern? - - - Qt Linguist by Trolltech[*] - Qt Linguist von Trolltech[*] - - - %1 - %2[*] - %1 - %2[*] - - - Qt Linguist by Trolltech - Qt Linguist von Trolltech - - - No untranslated phrases left. - Alle Einträge sind übersetzt. - - - &Window - &Fenster - - - Minimize - Minimieren - - - Ctrl+M - Ctrl+M - - - Display the manual for %1. - Zeige Handbuch für %1 an. - - - Display information about %1. - Zeige Informationen über %1 an. - - - File - Datei - - - Edit - Bearbeiten - - - Translation - Übersetzung - - - Validation - Validierung - - - Help - Hilfe - - - Cannot read from phrase book '%1'. - Kann Wörterbuch '%1' nicht lesen. - - - Close this phrase book. - Schließe dieses Wörterbuch. - - - Allow you to add, modify, or delete phrases of this phrase book. - Erlaubt das Hinzufügen, Ändern und Entfernen von Einträgen aus dem Wörterbuch. - - - Print the entries of the phrase book. - Drucke die Einträge des Wörterbuchs. - - - Cannot create phrase book '%1'. - Kann Wörterbuch '%1' nicht erzeugen. - - - Do you want to save phrasebook '%1'? - Wollen Sie das Wörterbuch '%1' speichern? - - - TranslateDialog - Qt Linguist - Qt Linguist - - This window allows you to search for some text in the translation source file. Dieses Fenster erlaubt die Suche in der Übersetzungsdatei. @@ -2703,25 +1977,6 @@ Alle Dateien (*) - TranslationSettings - - Qt Linguist - Translation file settings - Qt Linguist - Einstellungen der Übersetzungsdatei - - - Target language - Zielsprache - - - Language - Sprache - - - Country/Region - Land/Region - - - TranslationSettingsDialog @@ -2755,47 +2010,4 @@ Alle Dateien (*) Zielsprache - - databaseTranslationDialog - - Qt Linguist - Batch Translation - Qt Linguist - Automatische Übersetzung - - - Options - Optionen - - - Only translate entries with no translation - Übersetze nur Einträge ohne bisherige Übersetzung - - - Set translated entries to finished - Markiere Übersetzung als erledigt - - - Phrase book preference - Wörterbücher - - - Move up - Nach oben - - - Move down - Nach unten - - - The batch translator will search through the selected phrasebooks in the order given above. - Der automatische Übersetzer wird in der angegebenen Reihenfolge durch die ausgewählten Wörterbücher gehen. - - - &Run - &Ausführen - - - &Cancel - &Abbrechen - - diff --git a/translations/qt_help_de.ts b/translations/qt_help_de.ts index 9d48661..8e6cb85 100644 --- a/translations/qt_help_de.ts +++ b/translations/qt_help_de.ts @@ -111,8 +111,9 @@ QHelpDBReader - + Cannot open database '%1' '%2': %3 + The placeholders are: %1 - The name of the database which cannot be opened %2 - The unique id for the connection %3 - The actual error string Kann Datenbank nicht öffnen: '%1' '%2': %3 @@ -200,17 +201,22 @@ Dateien einfügen... - + + The referenced file %1 must be inside or within a subdirectory of (%2). Skipping it. + Die referenzierte Datei %1 muss sich im Verzeichnis %2 oder in einem Unterverzeichnis davon befinden. Sie wird übersprungen. + + + The file %1 does not exist! Skipping it. Die Datei %1 existiert nicht. Wird übersprungen. - + Cannot open file %1! Skipping it. Die Datei %1 kann nicht geöffnet werden. Wird übersprungen. - + The filter %1 is already registered! Der Filter %1 ist bereits registriert. @@ -243,17 +249,27 @@ QHelpSearchQueryWidget - + Search for: Suche nach: + + Previous search + Vorige Suche + + + + Next search + Nächste Suche + + Search Suche - + Advanced search Erweiterte Suche @@ -263,22 +279,22 @@ Worte <B>ähnlich</B> zu: - + <B>without</B> the words: <B>ohne</B> die Wörter: - + with <B>exact phrase</B>: mit der <B>genauen Wortgruppe</B>: - + with <B>all</B> of the words: mit <B>allen</B> Wörtern: - + with <B>at least one</B> of the words: mit <B>irgendeinem</B> der Wörter: @@ -307,7 +323,7 @@ Ohne Titel - + Unknown token. Unbekanntes Token. @@ -347,7 +363,7 @@ Fehlendes Attribut in Schlagwort in Zeile %1. - + The input file %1 could not be opened! Die Eingabe-Datei %1 kann nicht geöffnet werden. -- cgit v0.12 From 4111f8d417409579d591798c491f9f2aa7c0021d Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Mon, 10 Aug 2009 16:54:28 +0200 Subject: New mkspecs for Windows Mobile 6.5 We need extra mkspecs for Windows Mobile 6.5 to support gestures, since gestures are only supported with 6.5 Reviewed-by: Maurice --- .../default_post.prf | 1 + mkspecs/wincewm65professional-msvc2005/qmake.conf | 5 +++ .../wincewm65professional-msvc2005/qplatformdefs.h | 42 +++++++++++++++++++++ .../default_post.prf | 1 + mkspecs/wincewm65professional-msvc2008/qmake.conf | 3 ++ .../wincewm65professional-msvc2008/qplatformdefs.h | 43 ++++++++++++++++++++++ 6 files changed, 95 insertions(+) create mode 100644 mkspecs/wincewm65professional-msvc2005/default_post.prf create mode 100644 mkspecs/wincewm65professional-msvc2005/qmake.conf create mode 100644 mkspecs/wincewm65professional-msvc2005/qplatformdefs.h create mode 100644 mkspecs/wincewm65professional-msvc2008/default_post.prf create mode 100644 mkspecs/wincewm65professional-msvc2008/qmake.conf create mode 100644 mkspecs/wincewm65professional-msvc2008/qplatformdefs.h diff --git a/mkspecs/wincewm65professional-msvc2005/default_post.prf b/mkspecs/wincewm65professional-msvc2005/default_post.prf new file mode 100644 index 0000000..86bc964 --- /dev/null +++ b/mkspecs/wincewm65professional-msvc2005/default_post.prf @@ -0,0 +1 @@ +include(../wincewm60professional-msvc2005/default_post.prf) diff --git a/mkspecs/wincewm65professional-msvc2005/qmake.conf b/mkspecs/wincewm65professional-msvc2005/qmake.conf new file mode 100644 index 0000000..b4ae096 --- /dev/null +++ b/mkspecs/wincewm65professional-msvc2005/qmake.conf @@ -0,0 +1,5 @@ +include(../wincewm60professional-msvc2005/qmake.conf) + +DEFINES += QT_WINCE_GESTURES +QMAKE_LIBS_GUI += TouchGestureCore.lib + diff --git a/mkspecs/wincewm65professional-msvc2005/qplatformdefs.h b/mkspecs/wincewm65professional-msvc2005/qplatformdefs.h new file mode 100644 index 0000000..4317bc1 --- /dev/null +++ b/mkspecs/wincewm65professional-msvc2005/qplatformdefs.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake spec 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../wincewm60professional-msvc2005/qplatformdefs.h" diff --git a/mkspecs/wincewm65professional-msvc2008/default_post.prf b/mkspecs/wincewm65professional-msvc2008/default_post.prf new file mode 100644 index 0000000..c854561 --- /dev/null +++ b/mkspecs/wincewm65professional-msvc2008/default_post.prf @@ -0,0 +1 @@ +include(../wincewm65professional-msvc2005/default_post.prf) diff --git a/mkspecs/wincewm65professional-msvc2008/qmake.conf b/mkspecs/wincewm65professional-msvc2008/qmake.conf new file mode 100644 index 0000000..552c7c8 --- /dev/null +++ b/mkspecs/wincewm65professional-msvc2008/qmake.conf @@ -0,0 +1,3 @@ +include(../wincewm65professional-msvc2005/qmake.conf) +QMAKE_COMPILER_DEFINES -= _MSC_VER=1400 +QMAKE_COMPILER_DEFINES += _MSC_VER=1500 diff --git a/mkspecs/wincewm65professional-msvc2008/qplatformdefs.h b/mkspecs/wincewm65professional-msvc2008/qplatformdefs.h new file mode 100644 index 0000000..7f724f9 --- /dev/null +++ b/mkspecs/wincewm65professional-msvc2008/qplatformdefs.h @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake spec 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../wincewm65professional-msvc2005/qplatformdefs.h" + -- cgit v0.12 From 9a92aee8ff94a1b705e92f895831f9437762da75 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Mon, 10 Aug 2009 16:56:22 +0200 Subject: Gesture support for Windows Mobile 6.5 Gestures on Windows Mobile 6.5 rely on a statically linked library, that is added in the mkspecs for Windows Mobile 6.5 In the case the gesture functions do not have been resolved (==0), we do not call them. Reviewed-by: Joerg --- src/gui/kernel/qapplication_win.cpp | 58 ++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index bdee6ec..281be33 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -51,6 +51,9 @@ extern void qt_wince_hide_taskbar(HWND hwnd); //defined in qguifunctions_wince.c #ifdef Q_WS_WINCE_WM #include #include +#ifdef QT_WINCE_GESTURES +#include +#endif #endif #include "qapplication.h" @@ -815,30 +818,41 @@ void qt_init(QApplicationPrivate *priv, int) ptrSetProcessDPIAware(); #endif + priv->GetGestureInfo = 0; + priv->GetGestureExtraArgs = 0; + +#ifdef Q_WS_WINCE_WM + priv->GetGestureInfo = (PtrGetGestureInfo) &TKGetGestureInfo; + priv->GetGestureExtraArgs = (PtrGetGestureExtraArgs) &TKGetGestureExtraArguments; + priv->CloseGestureInfoHandle = (PtrCloseGestureInfoHandle) 0; + priv->SetGestureConfig = (PtrSetGestureConfig) 0; + priv->GetGestureConfig = (PtrGetGestureConfig) 0; +#else priv->GetGestureInfo = - (PtrGetGestureInfo)QLibrary::resolve(QLatin1String("user32"), - "GetGestureInfo"); + (PtrGetGestureInfo)QLibrary::resolve(QLatin1String("user32"), + "GetGestureInfo"); priv->GetGestureExtraArgs = - (PtrGetGestureExtraArgs)QLibrary::resolve(QLatin1String("user32"), - "GetGestureExtraArgs"); + (PtrGetGestureExtraArgs)QLibrary::resolve(QLatin1String("user32"), + "GetGestureExtraArgs"); priv->CloseGestureInfoHandle = - (PtrCloseGestureInfoHandle)QLibrary::resolve(QLatin1String("user32"), - "CloseGestureInfoHandle"); + (PtrCloseGestureInfoHandle)QLibrary::resolve(QLatin1String("user32"), + "CloseGestureInfoHandle"); + priv->SetGestureConfig = + (PtrSetGestureConfig)QLibrary::resolve(QLatin1String("user32"), + "SetGestureConfig"); priv->SetGestureConfig = - (PtrSetGestureConfig)QLibrary::resolve(QLatin1String("user32"), - "SetGestureConfig"); - priv->GetGestureConfig = - (PtrGetGestureConfig)QLibrary::resolve(QLatin1String("user32"), - "GetGestureConfig"); + (PtrGetGestureConfig)QLibrary::resolve(QLatin1String("user32"), + "GetGestureConfig"); priv->BeginPanningFeedback = - (PtrBeginPanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"), - "BeginPanningFeedback"); + (PtrBeginPanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"), + "BeginPanningFeedback"); priv->UpdatePanningFeedback = - (PtrUpdatePanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"), - "UpdatePanningFeedback"); + (PtrUpdatePanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"), + "UpdatePanningFeedback"); priv->EndPanningFeedback = (PtrEndPanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"), "EndPanningFeedback"); +#endif } /***************************************************************************** @@ -3720,7 +3734,16 @@ bool QETWidget::translateGestureEvent(const MSG &msg) gi.cbSize = sizeof(GESTUREINFO); QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); - BOOL bResult = qAppPriv->GetGestureInfo((HANDLE)msg.lParam, &gi); +#ifdef Q_WS_WINCE_WM +#define GID_ZOOM 0xf000 +#define GID_ROTATE 0xf001 +#define GID_TWOFINGERTAP 0xf002 +#define GID_ROLLOVER 0xf003 +#endif + BOOL bResult = false; + if (qAppPriv->GetGestureInfo) + bResult = qAppPriv->GetGestureInfo((HANDLE)msg.lParam, &gi); + const QPoint widgetPos = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); QWidget *alienWidget = !internalWinId() ? this : childAt(widgetPos); @@ -3751,7 +3774,8 @@ bool QETWidget::translateGestureEvent(const MSG &msg) default: break; } - qAppPriv->CloseGestureInfoHandle((HANDLE)msg.lParam); + if (qAppPriv->CloseGestureInfoHandle) + qAppPriv->CloseGestureInfoHandle((HANDLE)msg.lParam); if (event.gestureType != QNativeGestureEvent::None) qt_sendSpontaneousEvent(widget, &event); } else { -- cgit v0.12 From d918f98a4ab80405e0fe75fadf8491069a4c7ab8 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Mon, 10 Aug 2009 17:02:32 +0200 Subject: Make chooseConfig work on some EGL implementations According to the spec, if we pass a 0 out pointer, EGL should tell us how many configurations are available. However, we pass a 0 out pointer, but say that it's 256 elements big, it confuses some implementations. Fix that by passing a 0 out pointer and saying that it has space for 0 elements. Now we correctly get the amount of available configs. Reviewed-by: Rhys Weatherley --- src/gui/egl/qegl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index ebdac9a..1c45a58 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -95,7 +95,7 @@ bool QEglContext::chooseConfig do { // Get the number of matching configurations for this set of properties. EGLint matching = 0; - if (!eglChooseConfig(dpy, props.properties(), 0, 256, &matching) || !matching) + if (!eglChooseConfig(dpy, props.properties(), 0, 0, &matching) || !matching) continue; // If we want the best pixel format, then return the first -- cgit v0.12 From c3610da4be9b12bfe01b565db5ed2508da88c120 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 10 Aug 2009 12:13:46 +0200 Subject: tst_QSharedPointer fixed for Windows CE We cannot create too many threads on Windows CE. Reviewed-By: thartman --- tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index 1101a08..516729c 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -1373,7 +1373,9 @@ void tst_QSharedPointer::threadStressTest_data() QTest::newRow("5+10") << 5 << 10; QTest::newRow("5+30") << 5 << 30; +#ifndef Q_OS_WINCE QTest::newRow("100+100") << 100 << 100; +#endif } void tst_QSharedPointer::threadStressTest() -- cgit v0.12 From a6d51bc97a923bd990e5188035f7c913456138f7 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 10 Aug 2009 15:12:08 +0200 Subject: respect QAbstractSpinBox::NoButtons in windowsce / windowsmobile styles Code is adapted from QCommonStyle which handles this case for other styles. Reviewed-by: thartman --- src/gui/styles/qwindowscestyle.cpp | 6 +++++- src/gui/styles/qwindowsmobilestyle.cpp | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/gui/styles/qwindowscestyle.cpp b/src/gui/styles/qwindowscestyle.cpp index 997fc72..cd13dd8 100644 --- a/src/gui/styles/qwindowscestyle.cpp +++ b/src/gui/styles/qwindowscestyle.cpp @@ -1951,7 +1951,11 @@ QRect QWindowsCEStyle::subControlRect(ComplexControl control, const QStyleOption rect = QRect(x, y , bs.width(), bs.height()); break; case SC_SpinBoxEditField: - rect = QRect(lx, fw, rx-2, spinbox->rect.height() - 2*fw); + if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) { + rect = QRect(lx, fw, spinbox->rect.width() - 2*fw - 2, spinbox->rect.height() - 2*fw); + } else { + rect = QRect(lx, fw, rx-2, spinbox->rect.height() - 2*fw); + } break; case SC_SpinBoxFrame: rect = spinbox->rect; diff --git a/src/gui/styles/qwindowsmobilestyle.cpp b/src/gui/styles/qwindowsmobilestyle.cpp index c70b4c8..e708042 100644 --- a/src/gui/styles/qwindowsmobilestyle.cpp +++ b/src/gui/styles/qwindowsmobilestyle.cpp @@ -2984,7 +2984,11 @@ QRect QWindowsMobileStyle::subControlRect(ComplexControl control, const QStyleOp rect = QRect(x + bs.width(), 0, bs.width(), bs.height()); break; case SC_SpinBoxEditField: + if (spinBox->buttonSymbols == QAbstractSpinBox::NoButtons) { + rect = QRect(lx, fw, spinBox->rect.width() - 2*fw - 2, spinBox->rect.height() - 2*fw); + } else { rect = QRect(lx, fw, rx-2, spinBox->rect.height() - 2*fw); + } break; case SC_SpinBoxFrame: rect = spinBox->rect; -- cgit v0.12 From 8262b8b7dfda60446685eed8ec373c4da252cbeb Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 10 Aug 2009 15:18:35 +0200 Subject: remove compiler warning for Windows CE whitespaces fixed Reviewed-by: TrustMe --- src/corelib/io/qprocess_win.cpp | 46 ++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index eae17b4..d8da606 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -372,32 +372,30 @@ void QProcessPrivate::startProcess() qDebug(" pass environment : %s", environment.isEmpty() ? "no" : "yes"); #endif - DWORD dwCreationFlags = CREATE_NO_WINDOW; - #if defined(Q_OS_WINCE) - QString fullPathProgram = program; - if (!QDir::isAbsolutePath(fullPathProgram)) - fullPathProgram = QFileInfo(fullPathProgram).absoluteFilePath(); - fullPathProgram.replace(QLatin1Char('/'), QLatin1Char('\\')); - success = CreateProcess((wchar_t*)fullPathProgram.utf16(), - (wchar_t*)args.utf16(), - 0, 0, false, 0, 0, 0, 0, pid); + QString fullPathProgram = program; + if (!QDir::isAbsolutePath(fullPathProgram)) + fullPathProgram = QFileInfo(fullPathProgram).absoluteFilePath(); + fullPathProgram.replace(QLatin1Char('/'), QLatin1Char('\\')); + success = CreateProcess((wchar_t*)fullPathProgram.utf16(), + (wchar_t*)args.utf16(), + 0, 0, false, 0, 0, 0, 0, pid); #else - dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT; - STARTUPINFOW startupInfo = { sizeof( STARTUPINFO ), 0, 0, 0, - (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, - (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, - 0, 0, 0, - STARTF_USESTDHANDLES, - 0, 0, 0, - stdinChannel.pipe[0], stdoutChannel.pipe[1], stderrChannel.pipe[1] - }; - success = CreateProcess(0, (wchar_t*)args.utf16(), - 0, 0, TRUE, dwCreationFlags, - environment ? envlist.data() : 0, - workingDirectory.isEmpty() ? 0 - : (wchar_t*)QDir::toNativeSeparators(workingDirectory).utf16(), - &startupInfo, pid); + DWORD dwCreationFlags = CREATE_NO_WINDOW; + dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT; + STARTUPINFOW startupInfo = { sizeof( STARTUPINFO ), 0, 0, 0, + (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, + (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, + 0, 0, 0, + STARTF_USESTDHANDLES, + 0, 0, 0, + stdinChannel.pipe[0], stdoutChannel.pipe[1], stderrChannel.pipe[1] + }; + success = CreateProcess(0, (wchar_t*)args.utf16(), + 0, 0, TRUE, dwCreationFlags, + environment ? envlist.data() : 0, + workingDirectory.isEmpty() ? 0 : (wchar_t*)QDir::toNativeSeparators(workingDirectory).utf16(), + &startupInfo, pid); if (stdinChannel.pipe[0] != INVALID_Q_PIPE) { CloseHandle(stdinChannel.pipe[0]); -- cgit v0.12 From 33e9b82813f5573be6e5a780524044a2170d8dd4 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 10 Aug 2009 17:00:27 +0200 Subject: don't test dbus stuff where no dbus is Reviewed-by: Leo --- tests/auto/auto.pro | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index d3e295b..d7f27bd 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -106,8 +106,6 @@ SUBDIRS += \ qdate \ qdatetime \ qdatetimeedit \ - qdbuspendingcall \ - qdbuspendingreply \ qdebug \ qdesktopservices \ qdesktopwidget \ @@ -457,6 +455,8 @@ unix:!embedded:contains(QT_CONFIG, dbus):SUBDIRS += \ qdbusmarshall \ qdbusmetaobject \ qdbusmetatype \ + qdbuspendingcall \ + qdbuspendingreply \ qdbusperformance \ qdbusreply \ qdbusthreading \ -- cgit v0.12 From 70b5327e51481bf7b91d8fad50e3fc9ff3a1e888 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 10 Aug 2009 12:13:02 +0200 Subject: QtWebKit compile fix for Windows CE There's no getenv on Windows CE. Reviewed-By: Simon Hausmann --- src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp index 1a45fe6..613a72f 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp @@ -105,7 +105,7 @@ void QWEBKIT_EXPORT qt_drt_overwritePluginDirectories() PluginDatabase* db = PluginDatabase::installedPlugins(/* populate */ false); Vector paths; - String qtPath(getenv("QTWEBKIT_PLUGIN_PATH")); + String qtPath(qgetenv("QTWEBKIT_PLUGIN_PATH").data()); qtPath.split(UChar(':'), /* allowEmptyEntries */ false, paths); db->setPluginDirectories(paths); -- cgit v0.12 From 35ef002453cbe9841e23a7d33064a51dbe99fb06 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Mon, 10 Aug 2009 17:15:03 +0200 Subject: Manual merge --- src/gui/kernel/qapplication_win.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 5843c34..bb910b7 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -3728,7 +3728,7 @@ bool QETWidget::translateGestureEvent(const MSG &msg) memset(&gi, 0, sizeof(GESTUREINFO)); gi.cbSize = sizeof(GESTUREINFO); - QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); #ifdef Q_WS_WINCE_WM #define GID_ZOOM 0xf000 #define GID_ROTATE 0xf001 @@ -3739,8 +3739,6 @@ bool QETWidget::translateGestureEvent(const MSG &msg) if (qAppPriv->GetGestureInfo) bResult = qAppPriv->GetGestureInfo((HANDLE)msg.lParam, &gi); - QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); - BOOL bResult = qAppPriv->GetGestureInfo((HANDLE)msg.lParam, &gi); if (bResult) { const QPoint widgetPos = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); QWidget *alienWidget = !internalWinId() ? this : childAt(widgetPos); -- cgit v0.12 From 13a31fe82845f8b1f4d86919080d3b2a87c4d061 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Mon, 10 Aug 2009 17:15:03 +0200 Subject: Introducing icon theme support Added some static functions to QIcon to support desktop themes based on the freedesktop spec. It is not intended to replace KIcon and the intention is to use it when available to share icon cache between applications. Applications currently using icon themes are Assistant, Designer and the textedit demo. Reviewed-by: ogoffart --- demos/textedit/textedit.cpp | 65 +- doc/src/snippets/code/src_gui_image_qicon.cpp | 9 + src/gui/gui.pro | 1 - src/gui/image/image.pri | 3 + src/gui/image/qicon.cpp | 226 ++++-- src/gui/image/qicon.h | 10 + src/gui/image/qicon_p.h | 138 ++++ src/gui/image/qiconloader.cpp | 599 ++++++++++++++++ src/gui/image/qiconloader_p.h | 185 +++++ src/gui/kernel/qapplication_x11.cpp | 4 +- src/gui/styles/gtksymbols.cpp | 8 +- src/gui/styles/gtksymbols_p.h | 1 + src/gui/styles/qcleanlooksstyle.cpp | 563 +-------------- src/gui/styles/qcleanlooksstyle_p.h | 2 - src/gui/styles/qcommonstyle.cpp | 770 ++++++--------------- src/gui/styles/qcommonstyle_p.h | 13 - src/gui/styles/qgtkstyle.cpp | 96 +-- src/gui/styles/qgtkstyle.h | 4 + .../testtheme/16x16/actions/appointment-new.png | Bin 0 -> 897 bytes .../testtheme/22x22/actions/appointment-new.png | Bin 0 -> 1411 bytes .../testtheme/32x32/actions/appointment-new.png | Bin 0 -> 2399 bytes tests/auto/qicon/icons/testtheme/index.theme | 492 +++++++++++++ .../icons/testtheme/scalable/actions/svg-only.svg | 425 ++++++++++++ .../themeparent/16x16/actions/address-book-new.png | Bin 0 -> 796 bytes .../themeparent/16x16/actions/appointment-new.png | Bin 0 -> 897 bytes .../themeparent/22x22/actions/address-book-new.png | Bin 0 -> 924 bytes .../themeparent/22x22/actions/appointment-new.png | Bin 0 -> 1411 bytes .../themeparent/32x32/actions/address-book-new.png | Bin 0 -> 1897 bytes .../themeparent/32x32/actions/appointment-new.png | Bin 0 -> 2399 bytes tests/auto/qicon/icons/themeparent/index.theme | 492 +++++++++++++ .../scalable/actions/address-book-new.svg | 389 +++++++++++ .../scalable/actions/appointment-new.svg | 425 ++++++++++++ tests/auto/qicon/tst_qicon.cpp | 67 ++ tools/assistant/compat/mainwindow.cpp | 10 + tools/assistant/tools/assistant/mainwindow.cpp | 13 + .../components/buddyeditor/buddyeditor_plugin.cpp | 5 +- .../components/formeditor/formwindowmanager.cpp | 22 +- .../signalsloteditor/signalsloteditor_plugin.cpp | 3 +- .../tabordereditor/tabordereditor_plugin.cpp | 4 +- tools/designer/src/designer/qdesigner_actions.cpp | 7 +- tools/designer/src/lib/shared/actioneditor.cpp | 18 +- tools/designer/src/lib/shared/qtresourceview.cpp | 10 +- 42 files changed, 3784 insertions(+), 1295 deletions(-) create mode 100644 src/gui/image/qicon_p.h create mode 100644 src/gui/image/qiconloader.cpp create mode 100644 src/gui/image/qiconloader_p.h create mode 100644 tests/auto/qicon/icons/testtheme/16x16/actions/appointment-new.png create mode 100644 tests/auto/qicon/icons/testtheme/22x22/actions/appointment-new.png create mode 100644 tests/auto/qicon/icons/testtheme/32x32/actions/appointment-new.png create mode 100644 tests/auto/qicon/icons/testtheme/index.theme create mode 100644 tests/auto/qicon/icons/testtheme/scalable/actions/svg-only.svg create mode 100644 tests/auto/qicon/icons/themeparent/16x16/actions/address-book-new.png create mode 100644 tests/auto/qicon/icons/themeparent/16x16/actions/appointment-new.png create mode 100644 tests/auto/qicon/icons/themeparent/22x22/actions/address-book-new.png create mode 100644 tests/auto/qicon/icons/themeparent/22x22/actions/appointment-new.png create mode 100644 tests/auto/qicon/icons/themeparent/32x32/actions/address-book-new.png create mode 100644 tests/auto/qicon/icons/themeparent/32x32/actions/appointment-new.png create mode 100644 tests/auto/qicon/icons/themeparent/index.theme create mode 100644 tests/auto/qicon/icons/themeparent/scalable/actions/address-book-new.svg create mode 100644 tests/auto/qicon/icons/themeparent/scalable/actions/appointment-new.svg diff --git a/demos/textedit/textedit.cpp b/demos/textedit/textedit.cpp index d1e12bb..31b419a 100644 --- a/demos/textedit/textedit.cpp +++ b/demos/textedit/textedit.cpp @@ -158,14 +158,16 @@ void TextEdit::setupFileActions() QAction *a; - a = new QAction(QIcon(rsrcPath + "/filenew.png"), tr("&New"), this); + QIcon newIcon = QIcon::fromTheme("document-new", QIcon(rsrcPath + "/filenew.png")); + a = new QAction( newIcon, tr("&New"), this); a->setPriority(QAction::LowPriority); a->setShortcut(QKeySequence::New); connect(a, SIGNAL(triggered()), this, SLOT(fileNew())); tb->addAction(a); menu->addAction(a); - a = new QAction(QIcon(rsrcPath + "/fileopen.png"), tr("&Open..."), this); + a = new QAction(QIcon::fromTheme("document-open", QIcon(rsrcPath + "/fileopen.png")), + tr("&Open..."), this); a->setShortcut(QKeySequence::Open); connect(a, SIGNAL(triggered()), this, SLOT(fileOpen())); tb->addAction(a); @@ -173,7 +175,8 @@ void TextEdit::setupFileActions() menu->addSeparator(); - actionSave = a = new QAction(QIcon(rsrcPath + "/filesave.png"), tr("&Save"), this); + actionSave = a = new QAction(QIcon::fromTheme("document-save", QIcon(rsrcPath + "/filesave.png")), + tr("&Save"), this); a->setShortcut(QKeySequence::Save); connect(a, SIGNAL(triggered()), this, SLOT(fileSave())); a->setEnabled(false); @@ -187,17 +190,21 @@ void TextEdit::setupFileActions() menu->addSeparator(); #ifndef QT_NO_PRINTER - a = new QAction(QIcon(rsrcPath + "/fileprint.png"), tr("&Print..."), this); + a = new QAction(QIcon::fromTheme("document-print", QIcon(rsrcPath + "/fileprint.png")), + tr("&Print..."), this); + a->setPriority(QAction::LowPriority); a->setShortcut(QKeySequence::Print); connect(a, SIGNAL(triggered()), this, SLOT(filePrint())); tb->addAction(a); menu->addAction(a); - a = new QAction(QIcon(rsrcPath + "/fileprint.png"), tr("Print Preview..."), this); + a = new QAction(QIcon::fromTheme("fileprint", QIcon(rsrcPath + "/fileprint.png")), + tr("Print Preview..."), this); connect(a, SIGNAL(triggered()), this, SLOT(filePrintPreview())); menu->addAction(a); - a = new QAction(QIcon(rsrcPath + "/exportpdf.png"), tr("&Export PDF..."), this); + a = new QAction(QIcon::fromTheme("exportpdf", QIcon(rsrcPath + "/exportpdf.png")), + tr("&Export PDF..."), this); a->setPriority(QAction::LowPriority); a->setShortcut(Qt::CTRL + Qt::Key_D); connect(a, SIGNAL(triggered()), this, SLOT(filePrintPdf())); @@ -218,32 +225,36 @@ void TextEdit::setupEditActions() QToolBar *tb = new QToolBar(this); tb->setWindowTitle(tr("Edit Actions")); addToolBar(tb); - QMenu *menu = new QMenu(tr("&Edit"), this); menuBar()->addMenu(menu); QAction *a; - a = actionUndo = new QAction(QIcon(rsrcPath + "/editundo.png"), tr("&Undo"), this); + a = actionUndo = new QAction(QIcon::fromTheme("edit-undo", QIcon(rsrcPath + "/editundo.png")), + tr("&Undo"), this); a->setShortcut(QKeySequence::Undo); tb->addAction(a); menu->addAction(a); - a = actionRedo = new QAction(QIcon(rsrcPath + "/editredo.png"), tr("&Redo"), this); + a = actionRedo = new QAction(QIcon::fromTheme("edit-redo", QIcon(rsrcPath + "/editredo.png")), + tr("&Redo"), this); a->setPriority(QAction::LowPriority); a->setShortcut(QKeySequence::Redo); tb->addAction(a); menu->addAction(a); menu->addSeparator(); - a = actionCut = new QAction(QIcon(rsrcPath + "/editcut.png"), tr("Cu&t"), this); + a = actionCut = new QAction(QIcon::fromTheme("edit-cut", QIcon(rsrcPath + "/editcut.png")), + tr("Cu&t"), this); a->setPriority(QAction::LowPriority); a->setShortcut(QKeySequence::Cut); tb->addAction(a); menu->addAction(a); - a = actionCopy = new QAction(QIcon(rsrcPath + "/editcopy.png"), tr("&Copy"), this); + a = actionCopy = new QAction(QIcon::fromTheme("edit-copy", QIcon(rsrcPath + "/editcopy.png")), + tr("&Copy"), this); a->setPriority(QAction::LowPriority); a->setShortcut(QKeySequence::Copy); tb->addAction(a); menu->addAction(a); - a = actionPaste = new QAction(QIcon(rsrcPath + "/editpaste.png"), tr("&Paste"), this); + a = actionPaste = new QAction(QIcon::fromTheme("edit-paste", QIcon(rsrcPath + "/editpaste.png")), + tr("&Paste"), this); a->setPriority(QAction::LowPriority); a->setShortcut(QKeySequence::Paste); tb->addAction(a); @@ -260,10 +271,11 @@ void TextEdit::setupTextActions() QMenu *menu = new QMenu(tr("F&ormat"), this); menuBar()->addMenu(menu); - actionTextBold = new QAction(QIcon(rsrcPath + "/textbold.png"), tr("&Bold"), this); - actionTextBold->setPriority(QAction::LowPriority); + actionTextBold = new QAction(QIcon::fromTheme("format-text-bold", QIcon(rsrcPath + "/textbold.png")), + tr("&Bold"), this); actionTextBold->setShortcut(Qt::CTRL + Qt::Key_B); - QFont bold; + actionTextBold->setPriority(QAction::LowPriority); + QFont bold; bold.setBold(true); actionTextBold->setFont(bold); connect(actionTextBold, SIGNAL(triggered()), this, SLOT(textBold())); @@ -271,7 +283,8 @@ void TextEdit::setupTextActions() menu->addAction(actionTextBold); actionTextBold->setCheckable(true); - actionTextItalic = new QAction(QIcon(rsrcPath + "/textitalic.png"), tr("&Italic"), this); + actionTextItalic = new QAction(QIcon::fromTheme("format-text-italic", QIcon(rsrcPath + "/textitalic.png")), + tr("&Italic"), this); actionTextItalic->setPriority(QAction::LowPriority); actionTextItalic->setShortcut(Qt::CTRL + Qt::Key_I); QFont italic; @@ -282,9 +295,10 @@ void TextEdit::setupTextActions() menu->addAction(actionTextItalic); actionTextItalic->setCheckable(true); - actionTextUnderline = new QAction(QIcon(rsrcPath + "/textunder.png"), tr("&Underline"), this); - actionTextUnderline->setPriority(QAction::LowPriority); + actionTextUnderline = new QAction(QIcon::fromTheme("format-text-underline", QIcon(rsrcPath + "/textunder.png")), + tr("&Underline"), this); actionTextUnderline->setShortcut(Qt::CTRL + Qt::Key_U); + actionTextUnderline->setPriority(QAction::LowPriority); QFont underline; underline.setUnderline(true); actionTextUnderline->setFont(underline); @@ -300,15 +314,16 @@ void TextEdit::setupTextActions() // Make sure the alignLeft is always left of the alignRight if (QApplication::isLeftToRight()) { - actionAlignLeft = new QAction(QIcon(rsrcPath + "/textleft.png"), tr("&Left"), grp); - actionAlignCenter = new QAction(QIcon(rsrcPath + "/textcenter.png"), tr("C&enter"), grp); - actionAlignRight = new QAction(QIcon(rsrcPath + "/textright.png"), tr("&Right"), grp); + actionAlignLeft = new QAction(QIcon::fromTheme("format-justify-left", QIcon(rsrcPath + "/textleft.png")), + tr("&Left"), grp); + actionAlignCenter = new QAction(QIcon::fromTheme("format-justify-center", QIcon(rsrcPath + "/textcenter.png")), tr("C&enter"), grp); + actionAlignRight = new QAction(QIcon::fromTheme("format-justify-right", QIcon(rsrcPath + "/textright.png")), tr("&Right"), grp); } else { - actionAlignRight = new QAction(QIcon(rsrcPath + "/textright.png"), tr("&Right"), grp); - actionAlignCenter = new QAction(QIcon(rsrcPath + "/textcenter.png"), tr("C&enter"), grp); - actionAlignLeft = new QAction(QIcon(rsrcPath + "/textleft.png"), tr("&Left"), grp); + actionAlignRight = new QAction(QIcon::fromTheme("format-justify-right", QIcon(rsrcPath + "/textright.png")), tr("&Right"), grp); + actionAlignCenter = new QAction(QIcon::fromTheme("format-justify-center", QIcon(rsrcPath + "/textcenter.png")), tr("C&enter"), grp); + actionAlignLeft = new QAction(QIcon::fromTheme("format-justify-left", QIcon(rsrcPath + "/textleft.png")), tr("&Left"), grp); } - actionAlignJustify = new QAction(QIcon(rsrcPath + "/textjustify.png"), tr("&Justify"), grp); + actionAlignJustify = new QAction(QIcon::fromTheme("format-justify-fill", QIcon(rsrcPath + "/textjustify.png")), tr("&Justify"), grp); actionAlignLeft->setShortcut(Qt::CTRL + Qt::Key_L); actionAlignLeft->setCheckable(true); diff --git a/doc/src/snippets/code/src_gui_image_qicon.cpp b/doc/src/snippets/code/src_gui_image_qicon.cpp index 2b7c893..455fd84 100644 --- a/doc/src/snippets/code/src_gui_image_qicon.cpp +++ b/doc/src/snippets/code/src_gui_image_qicon.cpp @@ -20,3 +20,12 @@ void MyWidget::drawIcon(QPainter *painter, QPoint pos) painter->drawPixmap(pos, pixmap); } //! [2] + +//! [3] + QIcon undoicon = QIcon::fromTheme("edit-undo"); +//! [3] + +//! [4] + QIcon undoicon = QIcon::fromTheme("edit-undo", QIcon(":/undo.png")); +//! [4] + diff --git a/src/gui/gui.pro b/src/gui/gui.pro index b77bfdc..a49d680 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -46,4 +46,3 @@ contains(DEFINES,QT_EVAL):include($$QT_SOURCE_TREE/src/corelib/eval.pri) QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtGui.dynlist DEFINES += Q_INTERNAL_QAPP_SRC - diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri index b9c36dc..baf2125 100644 --- a/src/gui/image/image.pri +++ b/src/gui/image/image.pri @@ -6,6 +6,8 @@ HEADERS += \ image/qbitmap.h \ image/qicon.h \ + image/qicon_p.h \ + image/qiconloader_p.h \ image/qiconengine.h \ image/qiconengineplugin.h \ image/qimage.h \ @@ -32,6 +34,7 @@ HEADERS += \ SOURCES += \ image/qbitmap.cpp \ image/qicon.cpp \ + image/qiconloader.cpp \ image/qimage.cpp \ image/qimageiohandler.cpp \ image/qimagereader.cpp \ diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index fa407c7..7a43514 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -40,9 +40,11 @@ ****************************************************************************/ #include "qicon.h" +#include "qicon_p.h" #include "qiconengine.h" #include "qiconengineplugin.h" #include "private/qfactoryloader_p.h" +#include "private/qiconloader_p.h" #include "qapplication.h" #include "qstyleoption.h" #include "qpainter.h" @@ -50,6 +52,7 @@ #include "qstyle.h" #include "qpixmapcache.h" #include "qvariant.h" +#include "qcache.h" #include "qdebug.h" #ifdef Q_WS_MAC @@ -57,6 +60,11 @@ #include #endif +#ifdef Q_WS_X11 +#include "private/qt_x11_p.h" +#include "private/qkde_p.h" +#endif + QT_BEGIN_NAMESPACE /*! @@ -94,73 +102,14 @@ QT_BEGIN_NAMESPACE static QBasicAtomicInt serialNumCounter = Q_BASIC_ATOMIC_INITIALIZER(1); -class QIconPrivate -{ -public: - QIconPrivate(): engine(0), ref(1), serialNum(serialNumCounter.fetchAndAddRelaxed(1)), detach_no(0), engine_version(2), v1RefCount(0) {} - - ~QIconPrivate() { - if (engine_version == 1) { - if (!v1RefCount->deref()) { - delete engine; - delete v1RefCount; - } - } else if (engine_version == 2) { - delete engine; - } - } - - QIconEngine *engine; - - QAtomicInt ref; - int serialNum; - int detach_no; - int engine_version; - - QAtomicInt *v1RefCount; -}; - - -struct QPixmapIconEngineEntry +QIconPrivate::QIconPrivate() + : engine(0), ref(1), + serialNum(serialNumCounter.fetchAndAddRelaxed(1)), + detach_no(0), + engine_version(2), + v1RefCount(0) { - QPixmapIconEngineEntry():mode(QIcon::Normal), state(QIcon::Off){} - QPixmapIconEngineEntry(const QPixmap &pm, QIcon::Mode m = QIcon::Normal, QIcon::State s = QIcon::Off) - :pixmap(pm), size(pm.size()), mode(m), state(s){} - QPixmapIconEngineEntry(const QString &file, const QSize &sz = QSize(), QIcon::Mode m = QIcon::Normal, QIcon::State s = QIcon::Off) - :fileName(file), size(sz), mode(m), state(s){} - QPixmap pixmap; - QString fileName; - QSize size; - QIcon::Mode mode; - QIcon::State state; - bool isNull() const {return (fileName.isEmpty() && pixmap.isNull()); } -}; - -class QPixmapIconEngine : public QIconEngineV2 { -public: - QPixmapIconEngine(); - QPixmapIconEngine(const QPixmapIconEngine &); - ~QPixmapIconEngine(); - void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state); - QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state); - QPixmapIconEngineEntry *bestMatch(const QSize &size, QIcon::Mode mode, QIcon::State state, bool sizeOnly); - QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state); - void addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state); - void addFile(const QString &fileName, const QSize &size, QIcon::Mode mode, QIcon::State state); - - // v2 functions - QString key() const; - QIconEngineV2 *clone() const; - bool read(QDataStream &in); - bool write(QDataStream &out) const; - void virtual_hook(int id, void *data); - -private: - QPixmapIconEngineEntry *tryMatch(const QSize &size, QIcon::Mode mode, QIcon::State state); - QVector pixmaps; - - friend QDataStream &operator<<(QDataStream &s, const QIcon &icon); -}; +} QPixmapIconEngine::QPixmapIconEngine() { @@ -918,6 +867,146 @@ QList QIcon::availableSizes(Mode mode, State state) const return engine->availableSizes(mode, state); } +/*! + \since 4.6 + + Sets the search paths for icon themes. + \sa themeSearchPaths(), fromTheme() +*/ +void QIcon::setThemeSearchPaths(const QStringList &paths) +{ + QIconLoader::instance()->setThemeSearchPath(paths); +} + +/*! + \since 4.6 + + Returns the search paths for icon themes. + + The default value will depend on the platform: + + On X11, the search path will use the XDG_DATA_DIRS environment + variable if available. + + On Windows the search path defaults to [Application Directory]/icons + + On Mac the default search path will search in the + [Contents/Resources/icons] part of the application bundle. + + \sa setThemeSearchPaths(), fromName() +*/ +QStringList QIcon::themeSearchPaths() +{ + return QIconLoader::instance()->themeSearchPaths(); +} + +/*! + \since 4.6 + + Sets the current icon theme. + + The name should correspond to a directory name in the + current \ themeSearchPath() containing an index.theme + file describing it's contents.. + +*/ +void QIcon::setThemeName(const QString &path) +{ + QIconLoader::instance()->setThemeName(path); +} + +/*! + \since 4.6 + + Returns the name of the current icon theme. + + On X11, the current icon theme depends on your desktop + settings. On other platforms it is not set by default. + + \sa themeSearchPaths(), themeIcon(), fromTheme(), hasThemeIcon() +*/ +QString QIcon::themeName() +{ + return QIconLoader::instance()->themeName(); +} + +/*! + \since 4.6 + + Returns the QIcon corresponding to \a name in the current + icon theme. If no such icon is found in the current theme + \a fallback is return instead. + + To use an icon theme on Windows or Mac, you will need to + bundle a compliant theme with your application and make sure + it is located in your themeSarchPaths. + + The lastest version of the freedesktop icon specification and naming + spesification can be obtained here: + http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html + http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html + + To fetch an icon from the current icon theme: + + \snippet doc/src/snippets/code/src_gui_image_qicon.cpp 3 + + Or if you want to provide a guaranteed fallback for platforms that + do not support theme icons, you can use the second argument: + + \snippet doc/src/snippets/code/src_gui_image_qicon.cpp 4 + + \note By default, only X11 will support themed icons. In order to + use themed icons on Mac and Windows, you will have to bundle a + compliant theme in one of your themeSearchPaths() and set the + appropriate themeName(). + + \sa themeName(), themeSearchPaths() +*/ +QIcon QIcon::fromTheme(const QString &name, const QIcon &fallback) +{ + + static QCache iconCache; + + QIcon icon; + +#ifdef Q_WS_X11 + if (X11->desktopEnvironment == DE_KDE) { + icon = QKde::kdeIcon(name); + if (!icon.isNull()) + return icon; + } +#endif + + if (iconCache.contains(name)) { + icon = *iconCache.object(name); + } else { + QIcon *cachedIcon = new QIcon(new QIconLoaderEngine(name)); + iconCache.insert(name, cachedIcon); + icon = *cachedIcon; + } + + if (icon.availableSizes().isEmpty()) + return fallback; + + return icon; +} + +/*! + \since 4.6 + + Returns true if there is an icon available for a \a name in the current + icon theme, otherwise returns false. + + \sa themeSearchPaths(), fromTheme() +*/ +bool QIcon::hasThemeIcon(const QString &name) +{ + QIcon icon = fromTheme(name); + + return !icon.isNull(); +} + + /***************************************************************************** QIcon stream functions *****************************************************************************/ @@ -989,6 +1078,11 @@ QDataStream &operator>>(QDataStream &s, QIcon &icon) QIconEngineV2 *engine = new QPixmapIconEngine; icon.d->engine = engine; engine->read(s); + } else if (key == QLatin1String("QIconLoaderEngine")) { + icon.d = new QIconPrivate; + QIconEngineV2 *engine = new QIconLoaderEngine(); + icon.d->engine = engine; + engine->read(s); #if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) } else if (QIconEngineFactoryInterfaceV2 *factory = qobject_cast(loaderV2()->instance(key))) { if (QIconEngineV2 *engine= factory->create()) { diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h index c318e14..2a71717 100644 --- a/src/gui/image/qicon.h +++ b/src/gui/image/qicon.h @@ -97,6 +97,16 @@ public: QList availableSizes(Mode mode = Normal, State state = Off) const; + static QIcon fromTheme(const QString &name, const QIcon &fallback = QIcon()); + static bool hasThemeIcon(const QString &name); + + static QStringList themeSearchPaths(); + static void setThemeSearchPaths(const QStringList &searchpath); + + static QString themeName(); + static void setThemeName(const QString &path); + + #ifdef QT3_SUPPORT enum Size { Small, Large, Automatic = Small }; static QT3_SUPPORT void setPixmapSize(Size which, const QSize &size); diff --git a/src/gui/image/qicon_p.h b/src/gui/image/qicon_p.h new file mode 100644 index 0000000..ccac4c3 --- /dev/null +++ b/src/gui/image/qicon_p.h @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QICON_P_H +#define QICON_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QIconPrivate +{ +public: + QIconPrivate(); + + ~QIconPrivate() { + if (engine_version == 1) { + if (!v1RefCount->deref()) { + delete engine; + delete v1RefCount; + } + } else if (engine_version == 2) { + delete engine; + } + } + + QIconEngine *engine; + + QAtomicInt ref; + int serialNum; + int detach_no; + int engine_version; + + QAtomicInt *v1RefCount; +}; + + +struct QPixmapIconEngineEntry +{ + QPixmapIconEngineEntry():mode(QIcon::Normal), state(QIcon::Off){} + QPixmapIconEngineEntry(const QPixmap &pm, QIcon::Mode m = QIcon::Normal, QIcon::State s = QIcon::Off) + :pixmap(pm), size(pm.size()), mode(m), state(s){} + QPixmapIconEngineEntry(const QString &file, const QSize &sz = QSize(), QIcon::Mode m = QIcon::Normal, QIcon::State s = QIcon::Off) + :fileName(file), size(sz), mode(m), state(s){} + QPixmap pixmap; + QString fileName; + QSize size; + QIcon::Mode mode; + QIcon::State state; + bool isNull() const {return (fileName.isEmpty() && pixmap.isNull()); } +}; + + + +class QPixmapIconEngine : public QIconEngineV2 { +public: + QPixmapIconEngine(); + QPixmapIconEngine(const QPixmapIconEngine &); + ~QPixmapIconEngine(); + void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state); + QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state); + QPixmapIconEngineEntry *bestMatch(const QSize &size, QIcon::Mode mode, QIcon::State state, bool sizeOnly); + QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state); + void addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state); + void addFile(const QString &fileName, const QSize &size, QIcon::Mode mode, QIcon::State state); + + // v2 functions + QString key() const; + QIconEngineV2 *clone() const; + bool read(QDataStream &in); + bool write(QDataStream &out) const; + void virtual_hook(int id, void *data); + +private: + QPixmapIconEngineEntry *tryMatch(const QSize &size, QIcon::Mode mode, QIcon::State state); + QVector pixmaps; + + friend QDataStream &operator<<(QDataStream &s, const QIcon &icon); + friend class QIconThemeEngine; +}; + +QT_END_NAMESPACE + +#endif // QICON_P_H diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp new file mode 100644 index 0000000..6bf8d3b --- /dev/null +++ b/src/gui/image/qiconloader.cpp @@ -0,0 +1,599 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef Q_WS_MAC +#include +#endif + +#ifdef Q_WS_X11 +#include +#include +#endif + +QT_BEGIN_NAMESPACE + +Q_GLOBAL_STATIC(QIconLoader, iconLoaderInstance) + +static QString systemThemeName() +{ + QString result; +#ifdef Q_WS_X11 + if (X11->desktopEnvironment == DE_GNOME) { + result = QGtk::getGConfString(QLatin1String("/desktop/gnome/interface/icon_theme"), + QLatin1String("gnome")); + } else if (X11->desktopEnvironment == DE_KDE) { + QString kdeDefault = X11->desktopVersion >= 4 ? + QString::fromLatin1("oxygen") : + QString::fromLatin1("crystalsvg"); + + QSettings settings(QKde::kdeHome() + + QLatin1String("/share/config/kdeglobals"), + QSettings::IniFormat); + + settings.beginGroup(QLatin1String("Icons")); + + result = settings.value(QLatin1String("Theme"), kdeDefault).toString(); + } +#endif + return result; +} + +static QString fallbackTheme() +{ + QString defaultTheme = systemThemeName(); + if (defaultTheme.isEmpty()) + defaultTheme = QLatin1String("hicolor"); + return defaultTheme; +} + +QIconLoader::QIconLoader() : + m_themeKey(1), m_supportsSvg(false) +{ + m_systemTheme = systemThemeName(); + + QFactoryLoader iconFactoryLoader(QIconEngineFactoryInterfaceV2_iid, + QLatin1String("/iconengines"), + Qt::CaseInsensitive); + if (iconFactoryLoader.keys().contains(QLatin1String("svg"))) + m_supportsSvg = true; +} + +QIconLoader *QIconLoader::instance() +{ + return iconLoaderInstance(); +} + +// Queries the system theme and invalidates existing +// icons if the theme has changed. +void QIconLoader::updateSystemTheme() +{ + // Only change if this is not explicitly set by the user + if (m_userTheme.isEmpty()) { + QString theme = systemThemeName(); + if (theme != m_systemTheme) { + m_systemTheme = theme; + invalidateKey(); + } + } +} + +void QIconLoader::setThemeName(const QString &themeName) +{ + m_userTheme = themeName; + invalidateKey(); +} + +void QIconLoader::setThemeSearchPath(const QStringList &searchPaths) +{ + m_iconDirs = searchPaths; + themeList.clear(); + invalidateKey(); +} + +QStringList QIconLoader::themeSearchPaths() const +{ + if (m_iconDirs.isEmpty()) { + +#if defined(Q_WS_X11) + + QString xdgDirString = QFile::decodeName(getenv("XDG_DATA_DIRS")); + if (xdgDirString.isEmpty()) + xdgDirString = QLatin1String("/usr/local/share/:/usr/share/"); + + QStringList xdgDirs = xdgDirString.split(QLatin1Char(':')); + + for (int i = 0 ; i < xdgDirs.size() ; ++i) { + QDir dir(xdgDirs[i]); + if (dir.exists()) + m_iconDirs.append(dir.path() + + QLatin1String("/icons")); + } + + if (X11->desktopEnvironment == DE_KDE) { + + m_iconDirs << QLatin1Char(':') + + QKde::kdeHome() + + QLatin1String("/share/icons"); + QStringList kdeDirs = + QFile::decodeName(getenv("KDEDIRS")).split(QLatin1Char(':')); + + for (int i = 0 ; i< kdeDirs.count() ; ++i) { + QDir dir(QLatin1Char(':') + kdeDirs.at(i) + + QLatin1String("/share/icons")); + if (dir.exists()) + m_iconDirs.append(dir.path()); + } + } + + // Add home directory first in search path + QDir homeDir(QDir::homePath() + QLatin1String("/.icons")); + if (homeDir.exists()) + m_iconDirs.prepend(homeDir.path()); + +#elif defined(Q_WS_WIN) + m_iconDirs.append(qApp->applicationDirPath() + + QLatin1String("/icons")); +#elif defined(Q_WS_MAC) + m_iconDirs.append(qApp->applicationDirPath() + + QLatin1String("/../Resources/icons")); +#endif + } + return m_iconDirs; +} + +QIconTheme::QIconTheme(const QString &themeName) + : m_valid(false) +{ + QFile themeIndex; + + QList keyList; + QStringList iconDirs = QIcon::themeSearchPaths(); + for ( int i = 0 ; i < iconDirs.size() ; ++i) { + QDir iconDir(iconDirs[i]); + QString themeDir = iconDir.path() + QLatin1Char('/') + themeName; + themeIndex.setFileName(themeDir + QLatin1String("/index.theme")); + if (themeIndex.exists()) { + m_contentDir = themeDir; + m_valid = true; + break; + } + } + + if (themeIndex.exists()) { + const QSettings indexReader(themeIndex.fileName(), QSettings::IniFormat); + QStringListIterator keyIterator(indexReader.allKeys()); + while (keyIterator.hasNext()) { + + const QString key = keyIterator.next(); + if (key.endsWith(QLatin1String("/Size"))) { + // Note the QSettings ini-format does not accept + // slashes in key names, hence we have to cheat + if (int size = indexReader.value(key).toInt()) { + QString directoryKey = key.left(key.size() - 5); + QIconDirInfo dirInfo(directoryKey); + dirInfo.size = size; + QString type = indexReader.value(directoryKey + + QLatin1String("/Type") + ).toString(); + + if (type == QLatin1String("Fixed")) + dirInfo.type = QIconDirInfo::Fixed; + else if (type == QLatin1String("Scalable")) + dirInfo.type = QIconDirInfo::Scalable; + else + dirInfo.type = QIconDirInfo::Threshold; + + dirInfo.threshold = indexReader.value(directoryKey + + QLatin1String("/Threshold"), + 2).toInt(); + + dirInfo.minSize = indexReader.value(directoryKey + + QLatin1String("/MinSize"), + size).toInt(); + + dirInfo.maxSize = indexReader.value(directoryKey + + QLatin1String("/MaxSize"), + size).toInt(); + m_keyList.append(dirInfo); + } + } + } + + // Parent themes provide fallbacks for missing icons + m_parents = indexReader.value( + QLatin1String("Icon Theme/Inherits")).toStringList(); + + // Ensure a default platform fallback for all themes + if (m_parents.isEmpty()) + m_parents.append(fallbackTheme()); + + // Ensure that all themes fall back to hicolor + if (!m_parents.isEmpty()) + m_parents.append(QLatin1String("hicolor")); + } +} + +QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName, + const QString &iconName, + QStringList &visited) const +{ + QThemeIconEntries entries; + Q_ASSERT(!themeName.isEmpty()); + + QPixmap pixmap; + + // Used to protect against potential recursions + visited << themeName; + + QIconTheme theme = themeList.value(themeName); + if (!theme.isValid()) { + theme = QIconTheme(themeName); + if (!theme.isValid()) + theme = fallbackTheme(); + + themeList.insert(themeName, theme); + } + + QString contentDir = theme.contentDir() + QLatin1Char('/'); + QList subDirs = theme.keyList(); + + const QString svgext(QLatin1String(".svg")); + const QString pngext(QLatin1String(".png")); + + // Add all relevant files + for (int i = 0; i < subDirs.size() ; ++i) { + const QIconDirInfo &dirInfo = subDirs.at(i); + QString subdir = dirInfo.path; + QDir currentDir(contentDir + subdir); + + if (dirInfo.type == QIconDirInfo::Scalable && m_supportsSvg && + currentDir.exists(iconName + svgext)) { + ScalableEntry *iconEntry = new ScalableEntry; + iconEntry->dir = dirInfo; + iconEntry->filename = currentDir.filePath(iconName + svgext); + entries.append(iconEntry); + + } else if (currentDir.exists(iconName + pngext)) { + PixmapEntry *iconEntry = new PixmapEntry; + iconEntry->dir = dirInfo; + iconEntry->filename = currentDir.filePath(iconName + pngext); + // Notice we ensure that pixmap entries allways come before + // scalable to preserve search order afterwards + entries.prepend(iconEntry); + } + } + + if (entries.isEmpty()) { + const QStringList parents = theme.parents(); + // Search recursively through inherited themes + for (int i = 0 ; i < parents.size() ; ++i) { + + const QString parentTheme = parents.at(i).trimmed(); + + if (!visited.contains(parentTheme)) // guard against recursion + entries = findIconHelper(parentTheme, iconName, visited); + + if (!entries.isEmpty()) // success + break; + } + } + return entries; +} + +QThemeIconEntries QIconLoader::loadIcon(const QString &name) const +{ + if (!themeName().isEmpty()) { + QStringList visited; + return findIconHelper(themeName(), name, visited); + } + + return QThemeIconEntries(); +} + + +// -------- Icon Loader Engine -------- // + + +QIconLoaderEngine::QIconLoaderEngine(const QString& iconName) + : m_iconName(iconName), m_key(0) +{ +} + +QIconLoaderEngine::~QIconLoaderEngine() +{ + while (!m_entries.isEmpty()) + delete m_entries.takeLast(); + Q_ASSERT(m_entries.size() == 0); +} + +QIconLoaderEngine::QIconLoaderEngine(const QIconLoaderEngine &other) + : QIconEngineV2(other), + m_iconName(other.m_iconName), + m_key(0) +{ +} + +QIconEngineV2 *QIconLoaderEngine::clone() const +{ + return new QIconLoaderEngine(*this); +} + +bool QIconLoaderEngine::read(QDataStream &in) { + in >> m_iconName; + return true; +} + +bool QIconLoaderEngine::write(QDataStream &out) const +{ + out << m_iconName; + return true; +} + +bool QIconLoaderEngine::hasIcon() const +{ + return !(m_entries.isEmpty()); +} + +// Lazily load the icon +void QIconLoaderEngine::ensureLoaded() +{ + if (!(iconLoaderInstance()->themeKey() == m_key)) { + + while (!m_entries.isEmpty()) + delete m_entries.takeLast(); + + Q_ASSERT(m_entries.size() == 0); + m_entries = iconLoaderInstance()->loadIcon(m_iconName); + m_key = iconLoaderInstance()->themeKey(); + } +} + +void QIconLoaderEngine::paint(QPainter *painter, const QRect &rect, + QIcon::Mode mode, QIcon::State state) +{ + QSize pixmapSize = rect.size(); +#if defined(Q_WS_MAC) + pixmapSize *= qt_mac_get_scalefactor(); +#endif + painter->drawPixmap(rect, pixmap(pixmapSize, mode, state)); +} + +/* + * This algorithm is defined by the freedesktop spec: + * http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html + */ +static bool directoryMatchesSize(const QIconDirInfo &dir, int iconsize) +{ + if (dir.type == QIconDirInfo::Fixed) { + return dir.size == iconsize; + + } else if (dir.type == QIconDirInfo::Scalable) { + return dir.size <= dir.maxSize && + iconsize >= dir.minSize; + + } else if (dir.type == QIconDirInfo::Threshold) { + return iconsize >= dir.size - dir.threshold && + iconsize <= dir.size + dir.threshold; + } + + Q_ASSERT(1); // Not a valid value + return false; +} + +/* + * This algorithm is defined by the freedesktop spec: + * http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html + */ +static int directorySizeDistance(const QIconDirInfo &dir, int iconsize) +{ + if (dir.type == QIconDirInfo::Fixed) { + return qAbs(dir.size - iconsize); + + } else if (dir.type == QIconDirInfo::Scalable) { + if (iconsize < dir.minSize) + return dir.minSize - iconsize; + else if (iconsize > dir.maxSize) + return iconsize - dir.maxSize; + else + return 0; + + } else if (dir.type == QIconDirInfo::Threshold) { + if (iconsize < dir.size - dir.threshold) + return dir.minSize - iconsize; + else if (iconsize > dir.size + dir.threshold) + return iconsize - dir.maxSize; + else return 0; + } + + Q_ASSERT(1); // Not a valid value + return INT_MAX; +} + +QIconLoaderEngineEntry *QIconLoaderEngine::entryForSize(const QSize &size) +{ + int iconsize = qMin(size.width(), size.height()); + + // Note that m_entries are sorted so that png-files + // come first + + // Search for exact matches first + for (int i = 0; i < m_entries.count(); ++i) { + QIconLoaderEngineEntry *entry = m_entries.at(i); + if (directoryMatchesSize(entry->dir, iconsize)) { + return entry; + } + } + + // Find the minimum distance icon + int minimalSize = INT_MAX; + QIconLoaderEngineEntry *closestMatch = 0; + for (int i = 0; i < m_entries.count(); ++i) { + QIconLoaderEngineEntry *entry = m_entries.at(i); + int distance = directorySizeDistance(entry->dir, iconsize); + if (distance < minimalSize) { + minimalSize = distance; + closestMatch = entry; + } + } + return closestMatch; +} + +/* + * Returns the actual icon size. For scalable svg's this is equivalent + * to the requested size. Otherwise the closest match is returned. + * + * todo: the spec is a bit fuzzy in this area, but we should probably + * allow scaling down pixmap icons as well. + * + */ +QSize QIconLoaderEngine::actualSize(const QSize &size, QIcon::Mode mode, + QIcon::State state) +{ + ensureLoaded(); + + QIconLoaderEngineEntry *entry = entryForSize(size); + if (entry) { + const QIconDirInfo &dir = entry->dir; + if (dir.type == QIconDirInfo::Scalable) + return size; + else + return QSize(dir.size, dir.size); + } + return QIconEngineV2::actualSize(size, mode, state); +} + +QPixmap PixmapEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) +{ + Q_UNUSED(state); + + // Ensure that basePixmap is lazily initialized before generating the + // key, otherwise the cache key is not unique + if (basePixmap.isNull()) + basePixmap.load(filename); + + int actualSize = qMin(size.width(), size.height()); + QString key = QLatin1String("$qt_theme_") + + QString::number(basePixmap.cacheKey(), 16) + + QLatin1Char('_') + + QString::number(mode) + + QLatin1Char('_') + + QString::number(qApp->palette().cacheKey(), 16) + + QLatin1Char('_') + + QString::number(actualSize); + + QPixmap cachedPixmap; + if (QPixmapCache::find(key, &cachedPixmap)) { + return cachedPixmap; + } else { + QStyleOption opt(0); + opt.palette = qApp->palette(); + cachedPixmap = qApp->style()->generatedIconPixmap(mode, basePixmap, &opt); + QPixmapCache::insert(key, cachedPixmap); + } + return cachedPixmap; +} + +QPixmap ScalableEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) +{ + if (svgIcon.isNull()) + svgIcon = QIcon(filename); + + // Simply reuse svg icon engine + return svgIcon.pixmap(size, mode, state); +} + +QPixmap QIconLoaderEngine::pixmap(const QSize &size, QIcon::Mode mode, + QIcon::State state) +{ + ensureLoaded(); + + QIconLoaderEngineEntry *entry = entryForSize(size); + if (entry) + return entry->pixmap(size, mode, state); + + return QPixmap(); +} + +QString QIconLoaderEngine::key() const +{ + return QLatin1String("QIconLoaderEngine"); +} + +void QIconLoaderEngine::virtual_hook(int id, void *data) +{ + ensureLoaded(); + + switch (id) { + case QIconEngineV2::AvailableSizesHook: + { + QIconEngineV2::AvailableSizesArgument &arg + = *reinterpret_cast(data); + const QList directoryKey = iconLoaderInstance()->theme().keyList(); + arg.sizes.clear(); + + // Gets all sizes from the DirectoryInfo entries + for (int i = 0 ; i < m_entries.size() ; ++i) { + int size = m_entries.at(i)->dir.size; + arg.sizes.append(QSize(size, size)); + } + } + break; + default: + QIconEngineV2::virtual_hook(id, data); + } +} + +QT_END_NAMESPACE diff --git a/src/gui/image/qiconloader_p.h b/src/gui/image/qiconloader_p.h new file mode 100644 index 0000000..707107c --- /dev/null +++ b/src/gui/image/qiconloader_p.h @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDESKTOPICON_P_H +#define QDESKTOPICON_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QIconLoader; + +struct QIconDirInfo +{ + enum Type { Fixed, Scalable, Threshold }; + QIconDirInfo(const QString &_path = QString()) : + path(_path), + size(0), + maxSize(0), + minSize(0), + threshold(0), + type(Threshold) {} + QString path; + short size; + short maxSize; + short minSize; + short threshold; + Type type : 4; +}; + +class QIconLoaderEngineEntry + { +public: + virtual QPixmap pixmap(const QSize &size, + QIcon::Mode mode, + QIcon::State state) = 0; + QString filename; + QIconDirInfo dir; + static int count; +}; + +struct ScalableEntry : public QIconLoaderEngineEntry +{ + QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state); + QIcon svgIcon; +}; + +struct PixmapEntry : public QIconLoaderEngineEntry +{ + QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state); + QPixmap basePixmap; +}; + +typedef QList QThemeIconEntries; + +class QIconLoaderEngine : public QIconEngineV2 +{ +public: + QIconLoaderEngine(const QString& iconName = QString()); + ~QIconLoaderEngine(); + + void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state); + QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state); + QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state); + QIconEngineV2 *clone() const; + bool read(QDataStream &in); + bool write(QDataStream &out) const; + +private: + QString key() const; + bool hasIcon() const; + void ensureLoaded(); + void virtual_hook(int id, void *data); + QIconLoaderEngineEntry *entryForSize(const QSize &size); + QIconLoaderEngine(const QIconLoaderEngine &other); + QThemeIconEntries m_entries; + QString m_iconName; + uint m_key; + + friend class QIconLoader; +}; + +class QIconTheme +{ +public: + QIconTheme(const QString &name); + QIconTheme() : m_valid(false) {}; + QStringList parents() { return m_parents; } + QList keyList() { return m_keyList; } + QString contentDir() { return m_contentDir; } + bool isValid() { return m_valid; } + +private: + QString m_contentDir; + QList m_keyList; + QStringList m_parents; + bool m_valid; +}; + +class QIconLoader : public QObject +{ +public: + QIconLoader(); + QThemeIconEntries loadIcon(const QString &iconName) const; + uint themeKey() const { return m_themeKey; } + + QString themeName() const { return m_userTheme.isEmpty() ? m_systemTheme : m_userTheme; } + void setThemeName(const QString &themeName); + QIconTheme theme() { return themeList.value(themeName()); } + void setThemeSearchPath(const QStringList &searchPaths); + QStringList themeSearchPaths() const; + QIconDirInfo dirInfo(int dirindex); + static QIconLoader *instance(); + void updateSystemTheme(); + void invalidateKey() { m_themeKey++; } + +private: + QThemeIconEntries findIconHelper(const QString &themeName, + const QString &iconName, + QStringList &visited) const; + uint m_themeKey; + bool m_supportsSvg; + + mutable QString m_userTheme; + mutable QString m_systemTheme; + mutable QStringList m_iconDirs; + mutable QHash themeList; +}; + +QT_END_NAMESPACE + +#endif // QDESKTOPICON_P_H diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 32e7e3c..221101a 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -78,6 +78,7 @@ #include #include #include +#include #include "qstyle.h" #include "qmetaobject.h" #include "qtimer.h" @@ -1087,7 +1088,6 @@ static void qt_set_x11_resources(const char* font = 0, const char* fg = 0, if (QApplication::desktopSettingsAware()) { // first, read from settings QApplicationPrivate::x11_apply_settings(); - // the call to QApplication::style() below creates the system // palette, which breaks the logic after the RESOURCE_MANAGER // loop... so I have to save this value to be able to use it later @@ -1328,6 +1328,8 @@ static void qt_set_x11_resources(const char* font = 0, const char* fg = 0, QApplication::setEffectEnabled(Qt::UI_AnimateToolBox, effects.contains(QLatin1String("animatetoolbox"))); } + + QIconLoader::instance()->updateSystemTheme(); } diff --git a/src/gui/styles/gtksymbols.cpp b/src/gui/styles/gtksymbols.cpp index f947ac1..c8b4fda 100644 --- a/src/gui/styles/gtksymbols.cpp +++ b/src/gui/styles/gtksymbols.cpp @@ -60,6 +60,7 @@ #include #include +#include #include #include @@ -341,9 +342,9 @@ static bool resolveGConf() typedef int (*x11ErrorHandler)(Display*, XErrorEvent*); -static QString getGConfString(const QString &value) +QString QGtk::getGConfString(const QString &value, const QString &fallback) { - QString retVal; + QString retVal = fallback; if (resolveGConf()) { g_type_init(); GConfClient* client = QGtk::gconf_client_get_default(); @@ -393,7 +394,7 @@ static QString getThemeName() // Fall back to gconf if (themeName.isEmpty() && resolveGConf()) - themeName = getGConfString(QLS("/desktop/gnome/interface/gtk_theme")); + themeName = QGtk::getGConfString(QLS("/desktop/gnome/interface/gtk_theme")); return themeName; } @@ -561,6 +562,7 @@ void QGtkStyleUpdateScheduler::updateTheme() QApplication::sendEvent(widget, &e); } } + QIconLoader::instance()->updateSystemTheme(); } static void add_widget(GtkWidget *widget) diff --git a/src/gui/styles/gtksymbols_p.h b/src/gui/styles/gtksymbols_p.h index 18c6dc5..68e970a 100644 --- a/src/gui/styles/gtksymbols_p.h +++ b/src/gui/styles/gtksymbols_p.h @@ -216,6 +216,7 @@ public: static QString openDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options); static QStringList openFilenames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options); + static QString getGConfString(const QString &key, const QString &fallback = QString()); static Ptr_gtk_container_forall gtk_container_forall; static Ptr_gtk_init gtk_init; diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp index 8f88781..1782e36 100644 --- a/src/gui/styles/qcleanlooksstyle.cpp +++ b/src/gui/styles/qcleanlooksstyle.cpp @@ -462,26 +462,6 @@ static const char * const qt_cleanlooks_checkbox_checked[] = { " ", " "}; -#ifdef Q_WS_X11 -extern "C" { - struct GConfClient; - struct GError; - typedef void (*Ptr_g_type_init)(); - typedef GConfClient* (*Ptr_gconf_client_get_default)(); - typedef char* (*Ptr_gconf_client_get_string)(GConfClient*, const char*, GError **); - typedef void (*Ptr_g_object_unref)(void *); - typedef void (*Ptr_g_error_free)(GError *); - typedef void (*Ptr_g_free)(void*); -} - -static Ptr_g_type_init p_g_type_init = 0; -static Ptr_gconf_client_get_default p_gconf_client_get_default = 0; -static Ptr_gconf_client_get_string p_gconf_client_get_string = 0; -static Ptr_g_object_unref p_g_object_unref = 0; -static Ptr_g_error_free p_g_error_free = 0; -static Ptr_g_free p_g_free = 0; -#endif - static void qt_cleanlooks_draw_gradient(QPainter *painter, const QRect &rect, const QColor &gradientStart, const QColor &gradientStop, Direction direction = TopDown, QBrush bgBrush = QBrush()) { @@ -3848,17 +3828,6 @@ QSize QCleanlooksStyle::sizeFromContents(ContentsType type, const QStyleOption * void QCleanlooksStyle::polish(QApplication *app) { QWindowsStyle::polish(app); -#ifdef Q_WS_X11 - Q_D(QCleanlooksStyle); - - QString dataDirs = QLatin1String(getenv("XDG_DATA_DIRS")); - - if (dataDirs.isEmpty()) - dataDirs = QLatin1String("/usr/local/share/:/usr/share/"); - - dataDirs.prepend(QDir::homePath() + QLatin1String("/:")); - d->iconDirs = dataDirs.split(QLatin1Char(':')); -#endif } /*! @@ -4376,44 +4345,6 @@ QRect QCleanlooksStyle::subElementRect(SubElement sr, const QStyleOption *opt, c return r; } -void QCleanlooksStylePrivate::lookupIconTheme() const -{ -#ifdef Q_WS_X11 - - if (themeName.isEmpty()) { - //resolve glib and gconf functions - p_g_type_init = (Ptr_g_type_init)QLibrary::resolve(QLatin1String("gobject-2.0"), 0, "g_type_init"); - p_gconf_client_get_default = (Ptr_gconf_client_get_default)QLibrary::resolve(QLatin1String("gconf-2"), 4, "gconf_client_get_default"); - p_gconf_client_get_string = (Ptr_gconf_client_get_string)QLibrary::resolve(QLatin1String("gconf-2"), 4, "gconf_client_get_string"); - p_g_object_unref = (Ptr_g_object_unref)QLibrary::resolve(QLatin1String("gobject-2.0"), 0, "g_object_unref"); - p_g_error_free = (Ptr_g_error_free)QLibrary::resolve(QLatin1String("glib-2.0"), 0, "g_error_free"); - p_g_free = (Ptr_g_free)QLibrary::resolve(QLatin1String("glib-2.0"), 0, "g_free"); - - if (p_g_type_init && - p_gconf_client_get_default && - p_gconf_client_get_string && - p_g_object_unref && - p_g_error_free && - p_g_free) { - - p_g_type_init(); - GConfClient* client = p_gconf_client_get_default(); - GError *err = 0; - char *str = p_gconf_client_get_string(client, "/desktop/gnome/interface/icon_theme", &err); - if (!err) { - themeName = QString::fromUtf8(str); - p_g_free(str); - } - p_g_object_unref(client); - if (err) - p_g_error_free (err); - } - if (themeName.isEmpty()) - themeName = QLatin1String("gnome"); - } -#endif -} - /*! \internal */ @@ -4421,165 +4352,6 @@ QIcon QCleanlooksStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const { -#ifdef Q_WS_X11 - Q_D(const QCleanlooksStyle); - if (!QApplication::desktopSettingsAware()) - return QWindowsStyle::standardIconImplementation(standardIcon, option, widget); - QIcon icon; - QPixmap pixmap; - QPixmap link; - d->lookupIconTheme(); - switch (standardIcon) { - case SP_DirIcon: { - icon = QIcon(proxy()->standardPixmap(standardIcon, option, widget)); - icon.addPixmap(proxy()->standardPixmap(SP_DirClosedIcon, option, widget), - QIcon::Normal, QIcon::Off); - pixmap = d->findIcon(16, QLatin1String("gnome-fs-directory.png")); - if (!pixmap.isNull()) - icon.addPixmap(pixmap, QIcon::Normal, QIcon::Off); - pixmap = d->findIcon(48, QLatin1String("gnome-fs-directory.png")); - if (!pixmap.isNull()) - icon.addPixmap(pixmap, QIcon::Normal, QIcon::Off); - pixmap = d->findIcon(16, QLatin1String("gnome-fs-directory-accept.png")); - if (!pixmap.isNull()) - icon.addPixmap(pixmap, QIcon::Normal, QIcon::On); - pixmap = d->findIcon(16, QLatin1String("gnome-fs-directory-accept.png")); - if (!pixmap.isNull()) - icon.addPixmap(pixmap, QIcon::Normal, QIcon::On); - } - break; - case SP_DirLinkIcon: - { - icon = QIcon(proxy()->standardPixmap(standardIcon, option, widget)); - QPixmap link = d->findIcon(12, QLatin1String("emblem-symbolic-link.png")); - if (!link.isNull()) { - icon.addPixmap(proxy()->standardPixmap(SP_DirLinkIcon, option, widget)); - pixmap = d->findIcon(16, QLatin1String("gnome-fs-directory.png")); - if (!pixmap.isNull()) { - QPainter painter(&pixmap); - painter.drawPixmap(8, 8, 8, 8, link); - painter.end(); - icon.addPixmap(pixmap); - } - } - break; - } - case SP_FileIcon: - { - icon = d->createIcon(QLatin1String("unknown.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("gnome-fs-regular.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("stock_new.png")); - break; - } - case SP_DialogCloseButton: - { - icon = d->createIcon(QLatin1String("gtk-close.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("stock-close.png")); - break; - } - case SP_DirHomeIcon: - { - icon = d->createIcon(QLatin1String("folder_home.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("gnome_home.png")); - break; - } - case SP_DriveFDIcon: - { - icon = d->createIcon(QLatin1String("gnome-dev-floppy.png")); - break; - } - case SP_ComputerIcon: - { - icon = d->createIcon(QLatin1String("gnome-fs-client.png")); - break; - } - case SP_DesktopIcon: - { - icon = d->createIcon(QLatin1String("gnome-fs-desktop.png")); - break; - } - case SP_TrashIcon: - { - icon = d->createIcon(QLatin1String("gnome-fs-trash-empty.png")); - break; - } - case SP_DriveCDIcon: - case SP_DriveDVDIcon: - { - icon = d->createIcon(QLatin1String("gnome-dev-cdrom.png")); - break; - } - case SP_DriveHDIcon: - { - icon = d->createIcon(QLatin1String("gnome-dev-harddisk.png")); - break; - } - case SP_ArrowUp: - { - icon = d->createIcon(QLatin1String("stock_up.png")); - break; - } - case SP_ArrowDown: - { - icon = d->createIcon(QLatin1String("stock_down.png")); - break; - } - case SP_ArrowRight: - { - icon = d->createIcon(QLatin1String("stock_right.png")); - break; - } - case SP_ArrowLeft: - { - icon = d->createIcon(QLatin1String("stock_left.png")); - break; - } - case SP_BrowserReload: - { - icon = d->createIcon(QLatin1String("view-refresh.png")); - break; - } - case SP_BrowserStop: - { - pixmap = d->findIcon(24, QLatin1String("stop.png")); - break; - } - case SP_FileLinkIcon: - { - icon = QIcon(proxy()->standardPixmap(standardIcon, option, widget)); - QPixmap link = d->findIcon(12, QLatin1String("emblem-symbolic-link.png")); - if (!link.isNull()) { - icon.addPixmap(proxy()->standardPixmap(SP_FileLinkIcon,option, widget)); - pixmap = d->findIcon(16, QLatin1String("unknown.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(16, QLatin1String("stock_new.png")); - if (!pixmap.isNull()) { - QPainter painter(&pixmap); - painter.drawPixmap(8, 8, 8, 8, link); - painter.end(); - icon.addPixmap(pixmap); - } - } - break; - } - case SP_ArrowForward: - if (QApplication::layoutDirection() == Qt::RightToLeft) - return standardIconImplementation(SP_ArrowLeft, option, widget); - return standardIconImplementation(SP_ArrowRight, option, widget); - case SP_ArrowBack: - if (QApplication::layoutDirection() == Qt::RightToLeft) - return standardIconImplementation(SP_ArrowRight, option, widget); - return standardIconImplementation(SP_ArrowLeft, option, widget); - default: - icon = QIcon(proxy()->standardPixmap(standardIcon, option, widget)); - } - if (!icon.isNull()) - return icon; -#endif // Q_WS_X11 return QWindowsStyle::standardIconImplementation(standardIcon, option, widget); } @@ -4589,341 +4361,10 @@ QIcon QCleanlooksStyle::standardIconImplementation(StandardPixmap standardIcon, QPixmap QCleanlooksStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget) const { -#ifdef Q_WS_X11 - Q_D(const QCleanlooksStyle); QPixmap pixmap; - if (!QApplication::desktopSettingsAware()) - return QWindowsStyle::standardPixmap(standardPixmap, opt, widget); - d->lookupIconTheme(); + #ifndef QT_NO_IMAGEFORMAT_XPM switch (standardPixmap) { - case SP_MessageBoxInformation: - { - pixmap = d->findIcon(48, QLatin1String("dialog-info.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(48, QLatin1String("stock_dialog-info.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_MessageBoxWarning: - { - pixmap = d->findIcon(48, QLatin1String("dialog-warning.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(48, QLatin1String("stock_dialog-warning.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_MessageBoxCritical: - { - pixmap = d->findIcon(48, QLatin1String("dialog-error.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(48, QLatin1String("stock_dialog-error.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_MessageBoxQuestion: - { - pixmap = d->findIcon(48, QLatin1String("dialog-question.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_DirHomeIcon: - { - pixmap = d->findIcon(16, QLatin1String("folder_home.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(16, QLatin1String("gnome_home.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_DialogOpenButton: - case SP_DirOpenIcon: - { - pixmap = d->findIcon(24, QLatin1String("stock_open.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_FileIcon: - { - pixmap = d->findIcon(24, QLatin1String("unknown.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(24, QLatin1String("gnome-fs-regular.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(24, QLatin1String("stock_new.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_FileLinkIcon: - { - pixmap = d->findIcon(24, QLatin1String("emblem-symbolic-link.png")); - if (!pixmap.isNull()) { - QPixmap fileIcon = d->findIcon(24, QLatin1String("unknown.png")); - if (fileIcon.isNull()) - fileIcon = d->findIcon(24, QLatin1String("stock_new.png")); - if (!fileIcon.isNull()) { - QPainter painter(&fileIcon); - painter.setRenderHint(QPainter::SmoothPixmapTransform); - painter.drawPixmap(12, 12, 12, 12, pixmap); - return fileIcon; - } - } - break; - } - case SP_DirClosedIcon: - case SP_DirIcon: - { - pixmap = d->findIcon(24, QLatin1String("gnome-fs-directory.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_DirLinkIcon: - { - pixmap = d->findIcon(24, QLatin1String("emblem-symbolic-link.png")); - if (!pixmap.isNull()) { - QPixmap dirIcon = d->findIcon(24, QLatin1String("gnome-fs-directory.png")); - if (!dirIcon.isNull()) { - QPainter painter(&dirIcon); - painter.setRenderHint(QPainter::SmoothPixmapTransform); - painter.drawPixmap(12, 12, 12, 12, pixmap); - return dirIcon; - } - } - break; - } - case SP_DriveFDIcon: - { - pixmap = d->findIcon(24, QLatin1String("gnome-dev-floppy.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_ComputerIcon: - { - pixmap = d->findIcon(24, QLatin1String("gnome-fs-client.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_DesktopIcon: - { - pixmap = d->findIcon(24, QLatin1String("gnome-fs-desktop.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_TrashIcon: - { - pixmap = d->findIcon(24, QLatin1String("gnome-fs-trash-empty.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_DriveCDIcon: - case SP_DriveDVDIcon: - { - pixmap = d->findIcon(24, QLatin1String("gnome-dev-cdrom.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_DriveHDIcon: - { - pixmap = d->findIcon(24, QLatin1String("gnome-dev-harddisk.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_FileDialogToParent: - { - pixmap = d->findIcon(16, QLatin1String("stock_up.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_FileDialogNewFolder: - { - pixmap = d->findIcon(16, QLatin1String("stock_new-dir.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_ArrowUp: - { - pixmap = d->findIcon(16, QLatin1String("stock_up.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_ArrowDown: - { - pixmap = d->findIcon(16, QLatin1String("stock_down.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_ArrowRight: - { - pixmap = d->findIcon(16, QLatin1String("stock_right.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_ArrowLeft: - { - pixmap = d->findIcon(16, QLatin1String("stock_left.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_DialogCloseButton: - { - pixmap = d->findIcon(24, QLatin1String("gtk-close.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(24, QLatin1String("stock-close.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_DialogApplyButton: - { - pixmap = d->findIcon(24, QLatin1String("dialog-apply.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(24, QLatin1String("stock-apply.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_DialogResetButton: - { - pixmap = d->findIcon(24, QLatin1String("gtk-clear.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_DialogHelpButton: - { - pixmap = d->findIcon(24, QLatin1String("gtk-help.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_DialogOkButton: - { - pixmap = d->findIcon(24, QLatin1String("dialog-ok.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(24, QLatin1String("stock-ok.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_DialogCancelButton: - { - pixmap = d->findIcon(24, QLatin1String("dialog-cancel.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(24, QLatin1String("stock-cancel.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(24, QLatin1String("process-stop.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_DialogSaveButton: - { - pixmap = d->findIcon(24, QLatin1String("stock_save.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_BrowserStop: - { - pixmap = d->findIcon(16, QLatin1String("process-stop.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_BrowserReload: - { - pixmap = d->findIcon(16, QLatin1String("view-refresh.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_MediaPlay: - { - pixmap = d->findIcon(24, QLatin1String("media-playback-start.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_MediaPause: - { - pixmap = d->findIcon(24, QLatin1String("media-playback-pause.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_MediaStop: - { - pixmap = d->findIcon(24, QLatin1String("media-playback-stop.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_MediaVolume: - { - pixmap = d->findIcon(16, QLatin1String("audio-volume-medium.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_MediaVolumeMuted: - { - pixmap = d->findIcon(16, QLatin1String("audio-volume-muted.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_MediaSeekForward: - { - pixmap = d->findIcon(24, QLatin1String("media-seek-forward.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_MediaSeekBackward: - { - pixmap = d->findIcon(24, QLatin1String("media-seek-backward.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_MediaSkipForward: - { - pixmap = d->findIcon(24, QLatin1String("media-skip-forward.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_MediaSkipBackward: - { - pixmap = d->findIcon(24, QLatin1String("media-skip-backward.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_TitleBarMenuButton: - case SP_TitleBarShadeButton: - case SP_TitleBarUnshadeButton: - case SP_TitleBarMaxButton: - case SP_TitleBarContextHelpButton: - return QWindowsStyle::standardPixmap(standardPixmap, opt, widget); case SP_TitleBarNormalButton: return QPixmap((const char **)dock_widget_restore_xpm); case SP_TitleBarMinButton: @@ -4936,7 +4377,7 @@ QPixmap QCleanlooksStyle::standardPixmap(StandardPixmap standardPixmap, const QS break; } #endif //QT_NO_IMAGEFORMAT_XPM -#endif //Q_WS_X11 + return QWindowsStyle::standardPixmap(standardPixmap, opt, widget); } diff --git a/src/gui/styles/qcleanlooksstyle_p.h b/src/gui/styles/qcleanlooksstyle_p.h index a26d40d..d325499 100644 --- a/src/gui/styles/qcleanlooksstyle_p.h +++ b/src/gui/styles/qcleanlooksstyle_p.h @@ -71,8 +71,6 @@ public: ~QCleanlooksStylePrivate() { } - - void lookupIconTheme() const; }; QT_END_NAMESPACE diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index c7feb25..3878856 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -840,176 +840,8 @@ static void drawArrow(const QStyle *style, const QStyleOptionToolButton *toolbut #endif // QT_NO_TOOLBUTTON - #ifdef Q_WS_X11 // These functions are used to parse the X11 freedesktop icon spec -void QCommonStylePrivate::lookupIconTheme() const -{ - if (!themeName.isEmpty()) - return; - - QString dataDirs = QString::fromLocal8Bit(getenv("XDG_DATA_DIRS")); - if (dataDirs.isEmpty()) - dataDirs = QLatin1String("/usr/local/share/:/usr/share/"); - dataDirs += QLatin1Char(':') + QKde::kdeHome() + QLatin1String("/share"); - dataDirs.prepend(QDir::homePath() + QLatin1String("/:")); - QStringList kdeDirs = QString::fromLocal8Bit(getenv("KDEDIRS")).split(QLatin1Char(':'), QString::SkipEmptyParts); - foreach (const QString &dirName, kdeDirs) - dataDirs.append(QLatin1Char(':') + dirName + QLatin1String("/share")); - iconDirs = dataDirs.split(QLatin1Char(':')); - - QFileInfo fileInfo(QLatin1String("/usr/share/icons/default.kde")); - QDir dir(fileInfo.canonicalFilePath()); - QString kdeDefault = (X11->desktopEnvironment != DE_KDE || X11->desktopVersion >= 4) - ? QString::fromLatin1("oxygen") : QString::fromLatin1("crystalsvg"); - QString defaultTheme = fileInfo.exists() ? dir.dirName() : kdeDefault; - QSettings settings(QKde::kdeHome() + - QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat); - settings.beginGroup(QLatin1String("Icons")); - themeName = settings.value(QLatin1String("Theme"), defaultTheme).toString(); -} - -QIconTheme QCommonStylePrivate::parseIndexFile(const QString &themeName) const -{ - Q_Q(const QCommonStyle); - QIconTheme theme; - QFile themeIndex; - QStringList parents; - QHash dirList; - - for ( int i = 0 ; i < iconDirs.size() && !themeIndex.exists() ; ++i) { - QString contentDir = QLatin1String(iconDirs[i].startsWith(QDir::homePath()) ? - "/.icons/" : "/icons/"); - themeIndex.setFileName(iconDirs[i] + contentDir + - themeName + QLatin1String("/index.theme")); - } - - if (themeIndex.open(QIODevice::ReadOnly | QIODevice::Text)) { - - QTextStream in(&themeIndex); - - while (!in.atEnd()) { - - QString line = in.readLine(); - - if (line.startsWith(QLatin1String("Inherits="))) { - line = line.right(line.length() - 9); - parents = line.split(QLatin1Char(',')); - } - - if (line.startsWith(QLatin1Char('['))) { - line = line.trimmed(); - line.chop(1); - QString dirName = line.right(line.length() - 1); - if (!in.atEnd()) { - line = in.readLine(); - int size; - if (line.startsWith(QLatin1String("Size="))) { - size = line.right(line.length() - 5).toInt(); - if (size) - dirList.insertMulti(size, dirName); - } - } - } - } - } - - if (q->inherits("QPlastiqueStyle")) { - QFileInfo fileInfo(QLatin1String("/usr/share/icons/default.kde")); - QDir dir(fileInfo.canonicalFilePath()); - QString defaultKDETheme = dir.exists() ? dir.dirName() : QString::fromLatin1("crystalsvg"); - if (!parents.contains(defaultKDETheme) && themeName != defaultKDETheme) - parents.append(defaultKDETheme); - } else if (parents.isEmpty() && themeName != QLatin1String("hicolor")) { - parents.append(QLatin1String("hicolor")); - } - theme = QIconTheme(dirList, parents); - return theme; -} - -QPixmap QCommonStylePrivate::findIconHelper(int size, - const QString &themeName, - const QString &iconName, - QStringList &visited) const -{ - QPixmap pixmap; - - if (!themeName.isEmpty()) { - - visited << themeName; - QIconTheme theme = themeList.value(themeName); - - if (!theme.isValid()) { - theme = parseIndexFile(themeName); - themeList.insert(themeName, theme); - } - - if (!theme.isValid()) - return QPixmap(); - - QList subDirs = theme.dirList().values(size); - - for ( int i = 0 ; i < iconDirs.size() ; ++i) { - for ( int j = 0 ; j < subDirs.size() ; ++j) { - QString contentDir = (iconDirs[i].startsWith(QDir::homePath())) ? - QLatin1String("/.icons/") : QLatin1String("/icons/"); - QString fileName = iconDirs[i] + contentDir + themeName + QLatin1Char('/') + subDirs[j] + QLatin1Char('/') + iconName; - QFile file(fileName); - if (file.exists()) - pixmap.load(fileName); - if (!pixmap.isNull()) - break; - } - } - - if (pixmap.isNull()) { - QStringList parents = theme.parents(); - //search recursively through inherited themes - for (int i = 0 ; pixmap.isNull() && i < parents.size() ; ++i) { - QString parentTheme = parents[i].trimmed(); - if (!visited.contains(parentTheme)) //guard against endless recursion - pixmap = findIconHelper(size, parentTheme, iconName, visited); - } - } - } - return pixmap; -} - -/*! \internal - find a pixmap with the given size and name from the freedesktop theme. -*/ -QPixmap QCommonStylePrivate::findIcon(int size, const QString &name) const -{ - QIcon icon = QKde::kdeIcon(name); - if (!icon.isNull()) - return icon.pixmap(size); - - QPixmap pixmap; - QString pixmapName = QLatin1String("$qt") + name + QString::number(size); - - if (QPixmapCache::find(pixmapName, pixmap)) - return pixmap; - - if (!themeName.isEmpty()) { - QStringList visited; - pixmap = findIconHelper(size, themeName, name, visited); - } - QPixmapCache::insert(pixmapName, pixmap); - return pixmap; -} -/*! \internal - create an Icon from the freedesktop theme. - */ -QIcon QCommonStylePrivate::createIcon(const QString &name) const -{ - QIcon icon = QKde::kdeIcon(name); - if (icon.isNull()) { - icon.addPixmap(findIcon(16, name)); - icon.addPixmap(findIcon(24, name)); - icon.addPixmap(findIcon(32, name)); - } - return icon; -} /*!internal Checks if you are running KDE and looks up the toolbar @@ -4859,8 +4691,24 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid ret = int(QStyleHelper::dpiScaled(6.)); break; - case PM_TabBarIconSize: case PM_ToolBarIconSize: +#ifdef Q_WS_X11 + if (X11->desktopVersion >= 4) { + static int iconSize = 0; + if (!iconSize) { + QSettings settings(QKde::kdeHome() + + QLatin1String("/share/config/kdeglobals"), + QSettings::IniFormat); + settings.beginGroup(QLatin1String("ToolbarIcons")); + iconSize = settings.value(QLatin1String("Size"), QLatin1String("22")).toInt(); + } + ret = iconSize; + } else +#endif + ret = proxy()->pixelMetric(PM_SmallIconSize, opt, widget); + break; + + case PM_TabBarIconSize: case PM_ListViewIconSize: ret = proxy()->pixelMetric(PM_SmallIconSize, opt, widget); break; @@ -5371,293 +5219,161 @@ QPixmap QCommonStyle::standardPixmap(StandardPixmap sp, const QStyleOption *opti Q_UNUSED(widget); Q_UNUSED(sp); #else -#ifdef Q_WS_X11 - Q_D(const QCommonStyle); QPixmap pixmap; - if (QApplication::desktopSettingsAware()) { - d->lookupIconTheme(); + + if (QApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty()) { switch (sp) { case SP_DirHomeIcon: - { - pixmap = d->findIcon(16, QLatin1String("folder_home.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } + pixmap = QIcon::fromTheme(QLatin1String("user-home")).pixmap(16); + break; case SP_MessageBoxInformation: - { - pixmap = d->findIcon(32, QLatin1String("messagebox_info.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } + pixmap = QIcon::fromTheme(QLatin1String("messagebox_info")).pixmap(16); + break; case SP_MessageBoxWarning: - { - pixmap = d->findIcon(32, QLatin1String("messagebox_warning.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } + pixmap = QIcon::fromTheme(QLatin1String("messagebox_warning")).pixmap(16); + break; case SP_MessageBoxCritical: - { - pixmap = d->findIcon(32, QLatin1String("messagebox_critical.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } + pixmap = QIcon::fromTheme(QLatin1String("messagebox_critical")).pixmap(16); + break; case SP_MessageBoxQuestion: - { - pixmap = d->findIcon(32, QLatin1String("help.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } + pixmap = QIcon::fromTheme(QLatin1String("help")).pixmap(16); + break; case SP_DialogOpenButton: case SP_DirOpenIcon: - { - pixmap = d->findIcon(16, QLatin1String("folder-open.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(16, QLatin1String("folder_open.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } + pixmap = QIcon::fromTheme(QLatin1String("folder-open")).pixmap(16); + break; case SP_FileIcon: - { - pixmap = d->findIcon(16, QLatin1String("text-x-generic.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(16, QLatin1String("empty.png")); - if (!pixmap.isNull()) - return pixmap; - break; - } - case SP_FileLinkIcon: - { - pixmap = d->findIcon(16, QLatin1String("link_overlay.png")); - if (!pixmap.isNull()) { - QPixmap fileIcon = d->findIcon(16, QLatin1String("text-x-generic.png")); - if (fileIcon.isNull()) - fileIcon = d->findIcon(16, QLatin1String("empty.png")); - if (!fileIcon.isNull()) { - QPainter painter(&fileIcon); - painter.drawPixmap(0, 0, 16, 16, pixmap); - return fileIcon; - } - } - break; - } + pixmap = QIcon::fromTheme(QLatin1String("text-x-generic"), + QIcon::fromTheme(QLatin1String("empty"))).pixmap(16); + break; case SP_DirClosedIcon: case SP_DirIcon: - { - pixmap = d->findIcon(16, QLatin1String("folder.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("folder")).pixmap(16); break; - } - case SP_DirLinkIcon: - { - pixmap = d->findIcon(16, QLatin1String("link_overlay.png")); - if (!pixmap.isNull()) { - QPixmap dirIcon = d->findIcon(16, QLatin1String("folder.png")); - if (!dirIcon.isNull()) { - QPainter painter(&dirIcon); - painter.drawPixmap(0, 0, 16, 16, pixmap); - return dirIcon; - } - } - break; - } case SP_DriveFDIcon: - { - pixmap = d->findIcon(16, QLatin1String("media-floppy.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(16, QLatin1String("3floppy_unmount.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("media-floppy"), + QIcon::fromTheme(QLatin1String("3floppy_unmount"))).pixmap(16); break; - } case SP_ComputerIcon: - { - pixmap = d->findIcon(16, QLatin1String("computer.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(16, QLatin1String("system.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("computer"), + QIcon::fromTheme(QLatin1String("system"))).pixmap(16); break; - } case SP_DesktopIcon: - { - pixmap = d->findIcon(16, QLatin1String("user-desktop.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(16, QLatin1String("desktop.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("user-desktop"), + QIcon::fromTheme(QLatin1String("desktop"))).pixmap(16); break; - } case SP_TrashIcon: - { - pixmap = d->findIcon(16, QLatin1String("user-trash.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(16, QLatin1String("trashcan_empty.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("user-trash"), + QIcon::fromTheme(QLatin1String("trashcan_empty"))).pixmap(16); break; - } case SP_DriveCDIcon: case SP_DriveDVDIcon: - { - pixmap = d->findIcon(16, QLatin1String("media-optical.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(16, QLatin1String("cdrom_unmount.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("media-optical"), + QIcon::fromTheme(QLatin1String("cdrom_unmount"))).pixmap(16); break; - } case SP_DriveHDIcon: - { - pixmap = d->findIcon(16, QLatin1String("drive-harddisk.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(16, QLatin1String("hdd_unmount.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("drive-harddisk"), + QIcon::fromTheme(QLatin1String("hdd_unmount"))).pixmap(16); break; - } case SP_FileDialogToParent: - { - pixmap = d->findIcon(32, QLatin1String("go-up.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(32, QLatin1String("up.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("go-up"), + QIcon::fromTheme(QLatin1String("up"))).pixmap(16); break; - } case SP_FileDialogNewFolder: - { - pixmap = d->findIcon(16, QLatin1String("folder_new.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("folder_new")).pixmap(16); break; - } case SP_ArrowUp: - { - pixmap = d->findIcon(32, QLatin1String("go-up.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(32, QLatin1String("up.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("go-up"), + QIcon::fromTheme(QLatin1String("up"))).pixmap(16); break; - } case SP_ArrowDown: - { - pixmap = d->findIcon(32, QLatin1String("go-down.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(32, QLatin1String("down.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("go-down"), + QIcon::fromTheme(QLatin1String("down"))).pixmap(16); break; - } case SP_ArrowRight: - { - pixmap = d->findIcon(32, QLatin1String("go-next.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(32, QLatin1String("forward.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("go-next"), + QIcon::fromTheme(QLatin1String("forward"))).pixmap(16); break; - } case SP_ArrowLeft: - { - pixmap = d->findIcon(32, QLatin1String("go-previous.png")); - if (pixmap.isNull()) - pixmap = d->findIcon(32, QLatin1String("back.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("go-previous"), + QIcon::fromTheme(QLatin1String("back"))).pixmap(16); break; - } case SP_FileDialogDetailedView: - { - pixmap = d->findIcon(16, QLatin1String("view_detailed.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("view_detailed")).pixmap(16); break; - } - case SP_FileDialogListView: - { - pixmap = d->findIcon(16, QLatin1String("view_icon.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("view_icon")).pixmap(16); break; - } case SP_BrowserReload: - { - pixmap = d->findIcon(32, QLatin1String("reload.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("reload")).pixmap(16); break; - } case SP_BrowserStop: - { - pixmap = d->findIcon(32, QLatin1String("stop.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("process-stop")).pixmap(16); break; - } case SP_MediaPlay: - { - pixmap = d->findIcon(16, QLatin1String("player_play.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("media-playback-start")).pixmap(16); break; - } case SP_MediaPause: - { - pixmap = d->findIcon(16, QLatin1String("player_pause.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("media-playback-pause")).pixmap(16); break; - } case SP_MediaStop: - { - pixmap = d->findIcon(16, QLatin1String("player_stop.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("media-playback-stop")).pixmap(16); break; - } case SP_MediaSeekForward: - { - pixmap = d->findIcon(16, QLatin1String("player_fwd.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("media-seek-forward")).pixmap(16); break; - } case SP_MediaSeekBackward: - { - pixmap = d->findIcon(16, QLatin1String("player_rew.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("media-seek-backward")).pixmap(16); break; - } case SP_MediaSkipForward: - { - pixmap = d->findIcon(16, QLatin1String("player_end.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("media-skip-backward")).pixmap(16); break; - } case SP_MediaSkipBackward: - { - pixmap = d->findIcon(16, QLatin1String("player_start.png")); - if (!pixmap.isNull()) - return pixmap; + pixmap = QIcon::fromTheme(QLatin1String("media-skip-backward")).pixmap(16); + break; + case SP_DialogResetButton: + pixmap = QIcon::fromTheme(QLatin1String("edit-clear")).pixmap(24); + break; + case SP_DialogHelpButton: + pixmap = QIcon::fromTheme(QLatin1String("help-contents")).pixmap(24); + break; + case SP_DialogCancelButton: + pixmap = QIcon::fromTheme(QLatin1String("process-stop")).pixmap(24); + break; + case SP_DialogSaveButton: + pixmap = QIcon::fromTheme(QLatin1String("document-save")).pixmap(24); break; + case SP_FileLinkIcon: + pixmap = QIcon::fromTheme(QLatin1String("emblem-symbolic-link")).pixmap(16); + if (!pixmap.isNull()) { + QPixmap fileIcon = QIcon::fromTheme(QLatin1String("text-x-generic")).pixmap(16); + if (fileIcon.isNull()) + fileIcon = QIcon::fromTheme(QLatin1String("empty")).pixmap(16); + if (!fileIcon.isNull()) { + QPainter painter(&fileIcon); + painter.drawPixmap(0, 0, 16, 16, pixmap); + return fileIcon; + } } - + break; + case SP_DirLinkIcon: + pixmap = QIcon::fromTheme(QLatin1String("emblem-symbolic-link")).pixmap(16); + if (!pixmap.isNull()) { + QPixmap dirIcon = QIcon::fromTheme(QLatin1String("folder")).pixmap(16); + if (!dirIcon.isNull()) { + QPainter painter(&dirIcon); + painter.drawPixmap(0, 0, 16, 16, pixmap); + return dirIcon; + } + } + break; default: break; } } -#endif //Q_WS_X11 + + if (!pixmap.isNull()) + return pixmap; #endif //QT_NO_IMAGEFORMAT_PNG switch (sp) { #ifndef QT_NO_IMAGEFORMAT_XPM @@ -5793,254 +5509,178 @@ QIcon QCommonStyle::standardIconImplementation(StandardPixmap standardIcon, cons const QWidget *widget) const { QIcon icon; - if (QApplication::desktopSettingsAware()) { -#ifdef Q_WS_X11 - Q_D(const QCommonStyle); - d->lookupIconTheme(); - QPixmap pixmap; + if (QApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty()) { switch (standardIcon) { case SP_DirHomeIcon: - { - icon = d->createIcon(QLatin1String("folder_home.png")); + icon = QIcon::fromTheme(QLatin1String("user-home")); break; - } case SP_MessageBoxInformation: - { - icon = d->createIcon(QLatin1String("dialog-information.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("messagebox_info.png")); + icon = QIcon::fromTheme(QLatin1String("dialog-information")); break; - } case SP_MessageBoxWarning: - { - icon = d->createIcon(QLatin1String("dialog-warning.png")); - icon = d->createIcon(QLatin1String("dialog-warning.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("messagebox_warning.png")); + icon = QIcon::fromTheme(QLatin1String("dialog-warning")); break; - } case SP_MessageBoxCritical: - { - icon = d->createIcon(QLatin1String("dialog-error.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("messagebox_critical.png")); + icon = QIcon::fromTheme(QLatin1String("dialog-error")); break; - } case SP_MessageBoxQuestion: - { - icon = d->createIcon(QLatin1String("help.png")); + icon = QIcon::fromTheme(QLatin1String("dialog-question")); break; - } case SP_DialogOpenButton: case SP_DirOpenIcon: - { - icon = d->createIcon(QLatin1String("folder-open.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("folder_open.png")); + icon = QIcon::fromTheme(QLatin1String("folder-open")); break; - } case SP_FileIcon: - { - icon = d->createIcon(QLatin1String("text-x-generic.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("empty.png")); + icon = QIcon::fromTheme(QLatin1String("text-x-generic")); break; - } case SP_DirClosedIcon: case SP_DirIcon: - { - icon = d->createIcon(QLatin1String("folder.png")); + icon = QIcon::fromTheme(QLatin1String("folder")); break; - } case SP_DriveFDIcon: - { - icon = d->createIcon(QLatin1String("floppy_unmount.png")); + icon = QIcon::fromTheme(QLatin1String("floppy_unmount")); break; - } case SP_ComputerIcon: - { - icon = d->createIcon(QLatin1String("computer.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("system.png")); + icon = QIcon::fromTheme(QLatin1String("computer"), + QIcon::fromTheme(QLatin1String("system"))); break; - } case SP_DesktopIcon: - { - icon = d->createIcon(QLatin1String("user-desktop.png")); + icon = QIcon::fromTheme(QLatin1String("user-desktop")); break; - } case SP_TrashIcon: - { - icon = d->createIcon(QLatin1String("user-trash.png")); + icon = QIcon::fromTheme(QLatin1String("user-trash")); break; - } case SP_DriveCDIcon: case SP_DriveDVDIcon: - { - icon = d->createIcon(QLatin1String("media-optical.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("cdrom_unmount.png")); + icon = QIcon::fromTheme(QLatin1String("media-optical")); break; - } case SP_DriveHDIcon: - { - icon = d->createIcon(QLatin1String("drive-harddisk.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("hdd_unmount.png")); + icon = QIcon::fromTheme(QLatin1String("drive-harddisk")); break; - } case SP_FileDialogToParent: - { - icon = d->createIcon(QLatin1String("go-up.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("up.png")); + icon = QIcon::fromTheme(QLatin1String("go-up")); break; - } case SP_FileDialogNewFolder: - { - icon = d->createIcon(QLatin1String("folder_new.png")); + icon = QIcon::fromTheme(QLatin1String("folder-new")); break; - } case SP_ArrowUp: - { - icon = d->createIcon(QLatin1String("go-up.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("up.png")); + icon = QIcon::fromTheme(QLatin1String("go-up")); break; - } case SP_ArrowDown: - { - icon = d->createIcon(QLatin1String("go-down.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("down.png")); + icon = QIcon::fromTheme(QLatin1String("go-down")); break; - } case SP_ArrowRight: - { - icon = d->createIcon(QLatin1String("go-next.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("forward.png")); + icon = QIcon::fromTheme(QLatin1String("go-next")); break; - } case SP_ArrowLeft: - { - icon = d->createIcon(QLatin1String("go-previous.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("back.png")); + icon = QIcon::fromTheme(QLatin1String("go-previous")); + break; + case SP_DialogHelpButton: + icon = QIcon::fromTheme(QLatin1String("help-contents")); + break; + case SP_DialogCancelButton: + icon = QIcon::fromTheme(QLatin1String("process-stop")); + break; + case SP_DialogCloseButton: + icon = QIcon::fromTheme(QLatin1String("window-close")); + break; + case SP_DialogApplyButton: + icon = QIcon::fromTheme(QLatin1String("dialog-ok-apply")); + break; + case SP_DialogOkButton: + icon = QIcon::fromTheme(QLatin1String("dialog-ok")); break; - } case SP_FileDialogDetailedView: - { - icon = d->createIcon(QLatin1String("view-list-details.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("view_detailed.png")); + icon = QIcon::fromTheme(QLatin1String("view-list-details")); break; - } case SP_FileDialogListView: - { - icon = d->createIcon(QLatin1String("view-list-icons.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("view_icon.png")); + icon = QIcon::fromTheme(QLatin1String("view-list-icons")); break; - } case SP_BrowserReload: - { - icon = d->createIcon(QLatin1String("view-refresh.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("reload.png")); + icon = QIcon::fromTheme(QLatin1String("view-refresh")); break; - } case SP_BrowserStop: - { - icon = d->createIcon(QLatin1String("process-stop.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("stop.png")); + icon = QIcon::fromTheme(QLatin1String("process-stop")); break; - } case SP_MediaPlay: - { - icon = d->createIcon(QLatin1String("media-playback-start.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("player_play.png")); + icon = QIcon::fromTheme(QLatin1String("media-playback-start")); break; - } case SP_MediaPause: - { - icon = d->createIcon(QLatin1String("media-playback-pause.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("player_pause.png")); + icon = QIcon::fromTheme(QLatin1String("media-playback-pause")); break; - } case SP_MediaStop: - { - icon = d->createIcon(QLatin1String("media-playback-stop.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("player_stop.png")); + icon = QIcon::fromTheme(QLatin1String("media-playback-stop")); break; - } case SP_MediaSeekForward: - { - icon = d->createIcon(QLatin1String("media-skip-forward.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("player_fwd.png")); + icon = QIcon::fromTheme(QLatin1String("media-seek-forward")); break; - } case SP_MediaSeekBackward: - { - icon = d->createIcon(QLatin1String("media-skip-backward.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("player_rew.png")); + icon = QIcon::fromTheme(QLatin1String("media-seek-backward")); break; - } case SP_MediaSkipForward: - { - icon = d->createIcon(QLatin1String("media-skip-forward.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("player_end.png")); + icon = QIcon::fromTheme(QLatin1String("media-skip-forward")); break; - } case SP_MediaSkipBackward: - { - icon = d->createIcon(QLatin1String("media-skip-backward.png")); - if (icon.isNull()) - icon = d->createIcon(QLatin1String("player_start.png")); + icon = QIcon::fromTheme(QLatin1String("media-skip-backward")); break; - } - - case SP_FileLinkIcon: { - icon = QIcon(proxy()->standardPixmap(standardIcon, option, widget)); - QPixmap pixmap = d->findIcon(32, QLatin1String("link_overlay.png")); - if (!pixmap.isNull()) { - QPixmap fileIcon = d->findIcon(32, QLatin1String("text-x-generic.png")); - if (fileIcon.isNull()) - fileIcon = d->findIcon(32, QLatin1String("empty.png")); - if (!fileIcon.isNull()) { - QPainter painter(&fileIcon); - painter.drawPixmap(0, 0, 32, 32, pixmap); - icon.addPixmap(fileIcon); + case SP_MediaVolume: + icon = QIcon::fromTheme(QLatin1String("audio-volume-medium")); + break; + case SP_MediaVolumeMuted: + icon = QIcon::fromTheme(QLatin1String("audio-volume-muted")); + break; + case SP_DialogResetButton: + icon = QIcon::fromTheme(QLatin1String("edit-clear")); + break; + case SP_ArrowForward: + if (QApplication::layoutDirection() == Qt::RightToLeft) + return standardIconImplementation(SP_ArrowLeft, option, widget); + return standardIconImplementation(SP_ArrowRight, option, widget); + case SP_ArrowBack: + if (QApplication::layoutDirection() == Qt::RightToLeft) + return standardIconImplementation(SP_ArrowRight, option, widget); + return standardIconImplementation(SP_ArrowLeft, option, widget); + case SP_FileLinkIcon: + { + QIcon linkIcon = QIcon::fromTheme(QLatin1String("emblem-symbolic-link")); + if (!linkIcon.isNull()) { + QIcon baseIcon = standardIconImplementation(SP_FileIcon, option, widget); + const QList sizes = baseIcon.availableSizes(QIcon::Normal, QIcon::Off); + for (int i = 0 ; i < sizes.size() ; ++i) { + int size = sizes[i].width(); + QPixmap basePixmap = baseIcon.pixmap(size); + QPixmap linkPixmap = linkIcon.pixmap(size/2); + QPainter painter(&basePixmap); + painter.drawPixmap(size/2, size/2, linkPixmap); + icon.addPixmap(basePixmap); + } } } - } - break; - case SP_DirLinkIcon: { - icon = QIcon(proxy()->standardPixmap(standardIcon, option, widget)); - QPixmap pixmap = d->findIcon(32, QLatin1String("link_overlay.png")); - if (!pixmap.isNull()) { - QPixmap fileIcon = d->findIcon(32, QLatin1String("folder.png")); - if (!fileIcon.isNull()) { - QPainter painter(&fileIcon); - painter.drawPixmap(0, 0, 32, 32, pixmap); - icon.addPixmap(fileIcon); + break; + case SP_DirLinkIcon: + { + QIcon linkIcon = QIcon::fromTheme(QLatin1String("emblem-symbolic-link")); + if (!linkIcon.isNull()) { + QIcon baseIcon = standardIconImplementation(SP_DirIcon, option, widget); + const QList sizes = baseIcon.availableSizes(QIcon::Normal, QIcon::Off); + for (int i = 0 ; i < sizes.size() ; ++i) { + int size = sizes[i].width(); + QPixmap basePixmap = baseIcon.pixmap(size); + QPixmap linkPixmap = linkIcon.pixmap(size/2); + QPainter painter(&basePixmap); + painter.drawPixmap(size/2, size/2, linkPixmap); + icon.addPixmap(basePixmap); + } } - } } break; default: break; } + if (!icon.isNull()) return icon; -#elif defined(Q_WS_MAC) +#if defined(Q_WS_MAC) OSType iconType = 0; switch (standardIcon) { case QStyle::SP_MessageBoxQuestion: @@ -6131,11 +5771,9 @@ QIcon QCommonStyle::standardIconImplementation(StandardPixmap standardIcon, cons ReleaseIconRef(overlayIcon); return retIcon; } - -#endif //Q_WS_X11 || Q_WS_MAC +#endif // Q_WS_MAC } - switch (standardIcon) { #ifndef QT_NO_IMAGEFORMAT_PNG case SP_FileDialogNewFolder: diff --git a/src/gui/styles/qcommonstyle_p.h b/src/gui/styles/qcommonstyle_p.h index f2af5b2..cff46e6 100644 --- a/src/gui/styles/qcommonstyle_p.h +++ b/src/gui/styles/qcommonstyle_p.h @@ -122,20 +122,7 @@ public: } #endif mutable QIcon tabBarcloseButtonIcon; - -//icon detection on X11 -#ifdef Q_WS_X11 - void lookupIconTheme() const; int lookupToolButtonStyle() const; - QIcon createIcon(const QString &) const; - QPixmap findIcon(int size, const QString &) const; - QPixmap findIconHelper(int size, const QString &, const QString &, QStringList &visited) const; - QIconTheme parseIndexFile(const QString &themeName) const; - mutable QString themeName; - mutable QStringList iconDirs; - mutable QHash themeList; -#endif - }; QT_END_NAMESPACE diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 660b4c3..f6d8c88 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -3239,6 +3239,7 @@ QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option, return newSize; } + /*! \reimp */ QPixmap QGtkStyle::standardPixmap(StandardPixmap sp, const QStyleOption *option, const QWidget *widget) const @@ -3271,65 +3272,80 @@ QPixmap QGtkStyle::standardPixmap(StandardPixmap sp, const QStyleOption *option, } break; - case SP_DialogDiscardButton: { + case SP_DialogDiscardButton: return QGtkPainter::getIcon(GTK_STOCK_DELETE); - } - - case SP_DialogOkButton: { + case SP_DialogOkButton: return QGtkPainter::getIcon(GTK_STOCK_OK); - } - - case SP_DialogCancelButton: { + case SP_DialogCancelButton: return QGtkPainter::getIcon(GTK_STOCK_CANCEL); - } - - case SP_DialogYesButton: { + case SP_DialogYesButton: return QGtkPainter::getIcon(GTK_STOCK_YES); - } - - case SP_DialogNoButton: { + case SP_DialogNoButton: return QGtkPainter::getIcon(GTK_STOCK_NO); - } - - case SP_DialogOpenButton: { + case SP_DialogOpenButton: return QGtkPainter::getIcon(GTK_STOCK_OPEN); - } - - case SP_DialogCloseButton: { + case SP_DialogCloseButton: return QGtkPainter::getIcon(GTK_STOCK_CLOSE); - } - - case SP_DialogApplyButton: { + case SP_DialogApplyButton: return QGtkPainter::getIcon(GTK_STOCK_APPLY); - } - - case SP_DialogSaveButton: { + case SP_DialogSaveButton: return QGtkPainter::getIcon(GTK_STOCK_SAVE); - } - - case SP_MessageBoxWarning: { + case SP_MessageBoxWarning: return QGtkPainter::getIcon(GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG); - } - - case SP_MessageBoxQuestion: { + case SP_MessageBoxQuestion: return QGtkPainter::getIcon(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG); - } - - case SP_MessageBoxInformation: { + case SP_MessageBoxInformation: return QGtkPainter::getIcon(GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG); - } - - case SP_MessageBoxCritical: { + case SP_MessageBoxCritical: return QGtkPainter::getIcon(GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_DIALOG); - } - default: return QCleanlooksStyle::standardPixmap(sp, option, widget); } + return pixmap; +} - return QPixmap(); +/*! + \internal +*/ +QIcon QGtkStyle::standardIconImplementation(StandardPixmap standardIcon, + const QStyleOption *option, + const QWidget *widget) const +{ + if (!QGtk::isThemeAvailable()) + return QCleanlooksStyle::standardIconImplementation(standardIcon, option, widget); + switch (standardIcon) { + case SP_DialogDiscardButton: + return QGtkPainter::getIcon(GTK_STOCK_DELETE); + case SP_DialogOkButton: + return QGtkPainter::getIcon(GTK_STOCK_OK); + case SP_DialogCancelButton: + return QGtkPainter::getIcon(GTK_STOCK_CANCEL); + case SP_DialogYesButton: + return QGtkPainter::getIcon(GTK_STOCK_YES); + case SP_DialogNoButton: + return QGtkPainter::getIcon(GTK_STOCK_NO); + case SP_DialogOpenButton: + return QGtkPainter::getIcon(GTK_STOCK_OPEN); + case SP_DialogCloseButton: + return QGtkPainter::getIcon(GTK_STOCK_CLOSE); + case SP_DialogApplyButton: + return QGtkPainter::getIcon(GTK_STOCK_APPLY); + case SP_DialogSaveButton: + return QGtkPainter::getIcon(GTK_STOCK_SAVE); + case SP_MessageBoxWarning: + return QGtkPainter::getIcon(GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG); + case SP_MessageBoxQuestion: + return QGtkPainter::getIcon(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG); + case SP_MessageBoxInformation: + return QGtkPainter::getIcon(GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG); + case SP_MessageBoxCritical: + return QGtkPainter::getIcon(GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_DIALOG); + default: + return QCleanlooksStyle::standardIconImplementation(standardIcon, option, widget); + } } + /*! \reimp */ QRect QGtkStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const { diff --git a/src/gui/styles/qgtkstyle.h b/src/gui/styles/qgtkstyle.h index e12f175..f12de52 100644 --- a/src/gui/styles/qgtkstyle.h +++ b/src/gui/styles/qgtkstyle.h @@ -106,6 +106,10 @@ public: void unpolish(QWidget *widget); void unpolish(QApplication *app); + +protected Q_SLOTS: + QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, + const QWidget *widget = 0) const; }; diff --git a/tests/auto/qicon/icons/testtheme/16x16/actions/appointment-new.png b/tests/auto/qicon/icons/testtheme/16x16/actions/appointment-new.png new file mode 100644 index 0000000..18b7c67 Binary files /dev/null and b/tests/auto/qicon/icons/testtheme/16x16/actions/appointment-new.png differ diff --git a/tests/auto/qicon/icons/testtheme/22x22/actions/appointment-new.png b/tests/auto/qicon/icons/testtheme/22x22/actions/appointment-new.png new file mode 100644 index 0000000..d676ffd Binary files /dev/null and b/tests/auto/qicon/icons/testtheme/22x22/actions/appointment-new.png differ diff --git a/tests/auto/qicon/icons/testtheme/32x32/actions/appointment-new.png b/tests/auto/qicon/icons/testtheme/32x32/actions/appointment-new.png new file mode 100644 index 0000000..85daef3 Binary files /dev/null and b/tests/auto/qicon/icons/testtheme/32x32/actions/appointment-new.png differ diff --git a/tests/auto/qicon/icons/testtheme/index.theme b/tests/auto/qicon/icons/testtheme/index.theme new file mode 100644 index 0000000..e18736a --- /dev/null +++ b/tests/auto/qicon/icons/testtheme/index.theme @@ -0,0 +1,492 @@ +[Icon Theme] +_Name=Test +_Comment=Test Theme +Inherits=crystalsvg, themeparent +Example=x-directory-normal + +# KDE Specific Stuff +DisplayDepth=32 +LinkOverlay=link_overlay +LockOverlay=lock_overlay +ZipOverlay=zip_overlay +DesktopDefault=48 +DesktopSizes=16,22,32,48,64,72,96,128 +ToolbarDefault=22 +ToolbarSizes=16,22,32,48 +MainToolbarDefault=22 +MainToolbarSizes=16,22,32,48 +SmallDefault=16 +SmallSizes=16 +PanelDefault=32 +PanelSizes=16,22,32,48,64,72,96,128 + +# Directory list +Directories=16x16/actions,16x16/apps,16x16/categories,16x16/devices,16x16/emblems,16x16/emotes,16x16/mimetypes,16x16/places,16x16/status,22x22/actions,22x22/apps,22x22/categories,22x22/devices,22x22/emblems,22x22/emotes,22x22/mimetypes,22x22/places,22x22/status,24x24/actions,24x24/apps,24x24/categories,24x24/devices,24x24/emblems,24x24/emotes,24x24/mimetypes,24x24/places,24x24/status,32x32/actions,32x32/apps,32x32/categories,32x32/devices,32x32/emblems,32x32/emotes,32x32/mimetypes,32x32/places,32x32/status,48x48/actions,48x48/apps,48x48/categories,48x48/devices,48x48/emblems,48x48/emotes,48x48/mimetypes,48x48/places,48x48/status,64x64/actions,64x64/apps,64x64/categories,64x64/devices,64x64/emblems,64x64/emotes,64x64/mimetypes,64x64/places,64x64/status,72x72/actions,72x72/apps,72x72/categories,72x72/devices,72x72/emblems,72x72/emotes,72x72/mimetypes,72x72/places,72x72/status,96x96/actions,96x96/apps,96x96/categories,96x96/devices,96x96/emblems,96x96/emotes,96x96/mimetypes,96x96/places,96x96/status,128x128/actions,128x128/apps,128x128/categories,128x128/devices,128x128/emblems,128x128/emotes,128x128/mimetypes,128x128/places,128x128/status,scalable/actions,scalable/apps,scalable/categories,scalable/devices,scalable/emblems,scalable/emotes,scalable/mimetypes,scalable/places,scalable/status + +[16x16/actions] +Size=16 +Context=Actions +Type=Fixed + +[16x16/apps] +Size=16 +Context=Applications +Type=Fixed + +[16x16/categories] +Size=16 +Context=Categories +Type=Fixed + +[16x16/devices] +Size=16 +Context=Devices +Type=Fixed + +[16x16/emblems] +Size=16 +Context=Emblems +Type=Fixed + +[16x16/emotes] +Size=16 +Context=Emotes +Type=Fixed + +[16x16/mimetypes] +Size=16 +Context=MimeTypes +Type=Fixed + +[16x16/places] +Size=16 +Context=Places +Type=Fixed + +[16x16/status] +Size=16 +Context=Status +Type=Fixed + +[22x22/actions] +Size=22 +Context=Actions +Type=Fixed + +[22x22/apps] +Size=22 +Context=Applications +Type=Fixed + +[22x22/categories] +Size=22 +Context=Categories +Type=Fixed + +[22x22/devices] +Size=22 +Context=Devices +Type=Fixed + +[22x22/emblems] +Size=22 +Context=Emblems +Type=Fixed + +[22x22/emotes] +Size=22 +Context=Emotes +Type=Fixed + +[22x22/mimetypes] +Size=22 +Context=MimeTypes +Type=Fixed + +[22x22/places] +Size=22 +Context=Places +Type=Fixed + +[22x22/status] +Size=22 +Context=Status +Type=Fixed + +[24x24/actions] +Size=24 +Context=Actions +Type=Fixed + +[24x24/apps] +Size=24 +Context=Applications +Type=Fixed + +[24x24/categories] +Size=24 +Context=Categories +Type=Fixed + +[24x24/devices] +Size=24 +Context=Devices +Type=Fixed + +[24x24/emblems] +Size=24 +Context=Emblems +Type=Fixed + +[24x24/emotes] +Size=24 +Context=Emotes +Type=Fixed + +[24x24/mimetypes] +Size=24 +Context=MimeTypes +Type=Fixed + +[24x24/places] +Size=24 +Context=Places +Type=Fixed + +[24x24/status] +Size=24 +Context=Status +Type=Fixed + +[32x32/actions] +Size=32 +Context=Actions +Type=Fixed + +[32x32/apps] +Size=32 +Context=Applications +Type=Fixed + +[32x32/categories] +Size=32 +Context=Categories +Type=Fixed + +[32x32/devices] +Size=32 +Context=Devices +Type=Fixed + +[32x32/emblems] +Size=32 +Context=Emblems +Type=Fixed + +[32x32/emotes] +Size=32 +Context=Emotes +Type=Fixed + +[32x32/mimetypes] +Size=32 +Context=MimeTypes +Type=Fixed + +[32x32/places] +Size=32 +Context=Places +Type=Fixed + +[32x32/status] +Size=32 +Context=Status +Type=Fixed + +[48x48/actions] +Size=48 +Context=Actions +Type=Fixed + +[48x48/apps] +Size=48 +Context=Applications +Type=Fixed + +[48x48/categories] +Size=48 +Context=Categories +Type=Fixed + +[48x48/devices] +Size=48 +Context=Devices +Type=Fixed + +[48x48/emblems] +Size=48 +Context=Emblems +Type=Fixed + +[48x48/emotes] +Size=48 +Context=Emotes +Type=Fixed + +[48x48/mimetypes] +Size=48 +Context=MimeTypes +Type=Fixed + +[48x48/places] +Size=48 +Context=Places +Type=Fixed + +[48x48/status] +Size=48 +Context=Status +Type=Fixed + +[64x64/actions] +Size=64 +Context=Actions +Type=Fixed + +[64x64/apps] +Size=64 +Context=Applications +Type=Fixed + +[64x64/categories] +Size=64 +Context=Categories +Type=Fixed + +[64x64/devices] +Size=64 +Context=Devices +Type=Fixed + +[64x64/emblems] +Size=64 +Context=Emblems +Type=Fixed + +[64x64/emotes] +Size=64 +Context=Emotes +Type=Fixed + +[64x64/mimetypes] +Size=64 +Context=MimeTypes +Type=Fixed + +[64x64/places] +Size=64 +Context=Places +Type=Fixed + +[64x64/status] +Size=64 +Context=Status +Type=Fixed + +[72x72/actions] +Size=72 +Context=Actions +Type=Fixed + +[72x72/apps] +Size=72 +Context=Applications +Type=Fixed + +[72x72/categories] +Size=72 +Context=Categories +Type=Fixed + +[72x72/devices] +Size=72 +Context=Devices +Type=Fixed + +[72x72/emblems] +Size=72 +Context=Emblems +Type=Fixed + +[72x72/emotes] +Size=72 +Context=Emotes +Type=Fixed + +[72x72/mimetypes] +Size=72 +Context=MimeTypes +Type=Fixed + +[72x72/places] +Size=72 +Context=Places +Type=Fixed + +[72x72/status] +Size=72 +Context=Status +Type=Fixed + +[96x96/actions] +Size=96 +Context=Actions +Type=Fixed + +[96x96/apps] +Size=96 +Context=Applications +Type=Fixed + +[96x96/categories] +Size=96 +Context=Categories +Type=Fixed + +[96x96/devices] +Size=96 +Context=Devices +Type=Fixed + +[96x96/emblems] +Size=96 +Context=Emblems +Type=Fixed + +[96x96/emotes] +Size=96 +Context=Emotes +Type=Fixed + +[96x96/mimetypes] +Size=96 +Context=MimeTypes +Type=Fixed + +[96x96/places] +Size=96 +Context=Places +Type=Fixed + +[96x96/status] +Size=96 +Context=Status +Type=Fixed + +[128x128/actions] +Size=128 +Context=Actions +Type=Fixed + +[128x128/apps] +Size=128 +Context=Applications +Type=Fixed + +[128x128/categories] +Size=128 +Context=Categories +Type=Fixed + +[128x128/devices] +Size=128 +Context=Devices +Type=Fixed + +[128x128/emblems] +Size=128 +Context=Emblems +Type=Fixed + +[128x128/emotes] +Size=128 +Context=Emotes +Type=Fixed + +[128x128/mimetypes] +Size=128 +Context=MimeTypes +Type=Fixed + +[128x128/places] +Size=128 +Context=Places +Type=Fixed + +[128x128/status] +Size=128 +Context=Status +Type=Fixed + +[scalable/actions] +Size=48 +Context=Actions +Type=Scalable +MinSize=32 +MaxSize=256 + +[scalable/apps] +Size=48 +Context=Applications +Type=Scalable +MinSize=32 +MaxSize=256 + +[scalable/categories] +Size=48 +Context=Categories +Type=Scalable +MinSize=32 +MaxSize=256 + +[scalable/devices] +Size=48 +Context=Devices +Type=Scalable +MinSize=32 +MaxSize=256 + +[scalable/emblems] +Size=48 +Context=Emblems +Type=Scalable +MinSize=32 +MaxSize=256 + +[scalable/emotes] +Size=48 +Context=Emotes +Type=Scalable +Minsize=32 +MaxSize=256 + +[scalable/mimetypes] +Size=48 +Context=MimeTypes +Type=Scalable +MinSize=32 +MaxSize=256 + +[scalable/places] +Size=48 +Context=Places +Type=Scalable +MinSize=32 +MaxSize=256 + +[scalable/status] +Size=48 +Context=Status +Type=Scalable +MinSize=32 +MaxSize=256 diff --git a/tests/auto/qicon/icons/testtheme/scalable/actions/svg-only.svg b/tests/auto/qicon/icons/testtheme/scalable/actions/svg-only.svg new file mode 100644 index 0000000..4cb14f8 --- /dev/null +++ b/tests/auto/qicon/icons/testtheme/scalable/actions/svg-only.svg @@ -0,0 +1,425 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + New Appointment + + + appointment + new + meeting + rvsp + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/qicon/icons/themeparent/16x16/actions/address-book-new.png b/tests/auto/qicon/icons/themeparent/16x16/actions/address-book-new.png new file mode 100644 index 0000000..2098cfd Binary files /dev/null and b/tests/auto/qicon/icons/themeparent/16x16/actions/address-book-new.png differ diff --git a/tests/auto/qicon/icons/themeparent/16x16/actions/appointment-new.png b/tests/auto/qicon/icons/themeparent/16x16/actions/appointment-new.png new file mode 100644 index 0000000..18b7c67 Binary files /dev/null and b/tests/auto/qicon/icons/themeparent/16x16/actions/appointment-new.png differ diff --git a/tests/auto/qicon/icons/themeparent/22x22/actions/address-book-new.png b/tests/auto/qicon/icons/themeparent/22x22/actions/address-book-new.png new file mode 100644 index 0000000..fad446c Binary files /dev/null and b/tests/auto/qicon/icons/themeparent/22x22/actions/address-book-new.png differ diff --git a/tests/auto/qicon/icons/themeparent/22x22/actions/appointment-new.png b/tests/auto/qicon/icons/themeparent/22x22/actions/appointment-new.png new file mode 100644 index 0000000..d676ffd Binary files /dev/null and b/tests/auto/qicon/icons/themeparent/22x22/actions/appointment-new.png differ diff --git a/tests/auto/qicon/icons/themeparent/32x32/actions/address-book-new.png b/tests/auto/qicon/icons/themeparent/32x32/actions/address-book-new.png new file mode 100644 index 0000000..420139d Binary files /dev/null and b/tests/auto/qicon/icons/themeparent/32x32/actions/address-book-new.png differ diff --git a/tests/auto/qicon/icons/themeparent/32x32/actions/appointment-new.png b/tests/auto/qicon/icons/themeparent/32x32/actions/appointment-new.png new file mode 100644 index 0000000..85daef3 Binary files /dev/null and b/tests/auto/qicon/icons/themeparent/32x32/actions/appointment-new.png differ diff --git a/tests/auto/qicon/icons/themeparent/index.theme b/tests/auto/qicon/icons/themeparent/index.theme new file mode 100644 index 0000000..e536a0b --- /dev/null +++ b/tests/auto/qicon/icons/themeparent/index.theme @@ -0,0 +1,492 @@ +[Icon Theme] +_Name=Test +_Comment=Test Theme +Inherits=gnome,crystalsvg +Example=x-directory-normal + +# KDE Specific Stuff +DisplayDepth=32 +LinkOverlay=link_overlay +LockOverlay=lock_overlay +ZipOverlay=zip_overlay +DesktopDefault=48 +DesktopSizes=16,22,32,48,64,72,96,128 +ToolbarDefault=22 +ToolbarSizes=16,22,32,48 +MainToolbarDefault=22 +MainToolbarSizes=16,22,32,48 +SmallDefault=16 +SmallSizes=16 +PanelDefault=32 +PanelSizes=16,22,32,48,64,72,96,128 + +# Directory list +Directories=16x16/actions,16x16/apps,16x16/categories,16x16/devices,16x16/emblems,16x16/emotes,16x16/mimetypes,16x16/places,16x16/status,22x22/actions,22x22/apps,22x22/categories,22x22/devices,22x22/emblems,22x22/emotes,22x22/mimetypes,22x22/places,22x22/status,24x24/actions,24x24/apps,24x24/categories,24x24/devices,24x24/emblems,24x24/emotes,24x24/mimetypes,24x24/places,24x24/status,32x32/actions,32x32/apps,32x32/categories,32x32/devices,32x32/emblems,32x32/emotes,32x32/mimetypes,32x32/places,32x32/status,48x48/actions,48x48/apps,48x48/categories,48x48/devices,48x48/emblems,48x48/emotes,48x48/mimetypes,48x48/places,48x48/status,64x64/actions,64x64/apps,64x64/categories,64x64/devices,64x64/emblems,64x64/emotes,64x64/mimetypes,64x64/places,64x64/status,72x72/actions,72x72/apps,72x72/categories,72x72/devices,72x72/emblems,72x72/emotes,72x72/mimetypes,72x72/places,72x72/status,96x96/actions,96x96/apps,96x96/categories,96x96/devices,96x96/emblems,96x96/emotes,96x96/mimetypes,96x96/places,96x96/status,128x128/actions,128x128/apps,128x128/categories,128x128/devices,128x128/emblems,128x128/emotes,128x128/mimetypes,128x128/places,128x128/status,scalable/actions,scalable/apps,scalable/categories,scalable/devices,scalable/emblems,scalable/emotes,scalable/mimetypes,scalable/places,scalable/status + +[16x16/actions] +Size=16 +Context=Actions +Type=Fixed + +[16x16/apps] +Size=16 +Context=Applications +Type=Fixed + +[16x16/categories] +Size=16 +Context=Categories +Type=Fixed + +[16x16/devices] +Size=16 +Context=Devices +Type=Fixed + +[16x16/emblems] +Size=16 +Context=Emblems +Type=Fixed + +[16x16/emotes] +Size=16 +Context=Emotes +Type=Fixed + +[16x16/mimetypes] +Size=16 +Context=MimeTypes +Type=Fixed + +[16x16/places] +Size=16 +Context=Places +Type=Fixed + +[16x16/status] +Size=16 +Context=Status +Type=Fixed + +[22x22/actions] +Size=22 +Context=Actions +Type=Fixed + +[22x22/apps] +Size=22 +Context=Applications +Type=Fixed + +[22x22/categories] +Size=22 +Context=Categories +Type=Fixed + +[22x22/devices] +Size=22 +Context=Devices +Type=Fixed + +[22x22/emblems] +Size=22 +Context=Emblems +Type=Fixed + +[22x22/emotes] +Size=22 +Context=Emotes +Type=Fixed + +[22x22/mimetypes] +Size=22 +Context=MimeTypes +Type=Fixed + +[22x22/places] +Size=22 +Context=Places +Type=Fixed + +[22x22/status] +Size=22 +Context=Status +Type=Fixed + +[24x24/actions] +Size=24 +Context=Actions +Type=Fixed + +[24x24/apps] +Size=24 +Context=Applications +Type=Fixed + +[24x24/categories] +Size=24 +Context=Categories +Type=Fixed + +[24x24/devices] +Size=24 +Context=Devices +Type=Fixed + +[24x24/emblems] +Size=24 +Context=Emblems +Type=Fixed + +[24x24/emotes] +Size=24 +Context=Emotes +Type=Fixed + +[24x24/mimetypes] +Size=24 +Context=MimeTypes +Type=Fixed + +[24x24/places] +Size=24 +Context=Places +Type=Fixed + +[24x24/status] +Size=24 +Context=Status +Type=Fixed + +[32x32/actions] +Size=32 +Context=Actions +Type=Fixed + +[32x32/apps] +Size=32 +Context=Applications +Type=Fixed + +[32x32/categories] +Size=32 +Context=Categories +Type=Fixed + +[32x32/devices] +Size=32 +Context=Devices +Type=Fixed + +[32x32/emblems] +Size=32 +Context=Emblems +Type=Fixed + +[32x32/emotes] +Size=32 +Context=Emotes +Type=Fixed + +[32x32/mimetypes] +Size=32 +Context=MimeTypes +Type=Fixed + +[32x32/places] +Size=32 +Context=Places +Type=Fixed + +[32x32/status] +Size=32 +Context=Status +Type=Fixed + +[48x48/actions] +Size=48 +Context=Actions +Type=Fixed + +[48x48/apps] +Size=48 +Context=Applications +Type=Fixed + +[48x48/categories] +Size=48 +Context=Categories +Type=Fixed + +[48x48/devices] +Size=48 +Context=Devices +Type=Fixed + +[48x48/emblems] +Size=48 +Context=Emblems +Type=Fixed + +[48x48/emotes] +Size=48 +Context=Emotes +Type=Fixed + +[48x48/mimetypes] +Size=48 +Context=MimeTypes +Type=Fixed + +[48x48/places] +Size=48 +Context=Places +Type=Fixed + +[48x48/status] +Size=48 +Context=Status +Type=Fixed + +[64x64/actions] +Size=64 +Context=Actions +Type=Fixed + +[64x64/apps] +Size=64 +Context=Applications +Type=Fixed + +[64x64/categories] +Size=64 +Context=Categories +Type=Fixed + +[64x64/devices] +Size=64 +Context=Devices +Type=Fixed + +[64x64/emblems] +Size=64 +Context=Emblems +Type=Fixed + +[64x64/emotes] +Size=64 +Context=Emotes +Type=Fixed + +[64x64/mimetypes] +Size=64 +Context=MimeTypes +Type=Fixed + +[64x64/places] +Size=64 +Context=Places +Type=Fixed + +[64x64/status] +Size=64 +Context=Status +Type=Fixed + +[72x72/actions] +Size=72 +Context=Actions +Type=Fixed + +[72x72/apps] +Size=72 +Context=Applications +Type=Fixed + +[72x72/categories] +Size=72 +Context=Categories +Type=Fixed + +[72x72/devices] +Size=72 +Context=Devices +Type=Fixed + +[72x72/emblems] +Size=72 +Context=Emblems +Type=Fixed + +[72x72/emotes] +Size=72 +Context=Emotes +Type=Fixed + +[72x72/mimetypes] +Size=72 +Context=MimeTypes +Type=Fixed + +[72x72/places] +Size=72 +Context=Places +Type=Fixed + +[72x72/status] +Size=72 +Context=Status +Type=Fixed + +[96x96/actions] +Size=96 +Context=Actions +Type=Fixed + +[96x96/apps] +Size=96 +Context=Applications +Type=Fixed + +[96x96/categories] +Size=96 +Context=Categories +Type=Fixed + +[96x96/devices] +Size=96 +Context=Devices +Type=Fixed + +[96x96/emblems] +Size=96 +Context=Emblems +Type=Fixed + +[96x96/emotes] +Size=96 +Context=Emotes +Type=Fixed + +[96x96/mimetypes] +Size=96 +Context=MimeTypes +Type=Fixed + +[96x96/places] +Size=96 +Context=Places +Type=Fixed + +[96x96/status] +Size=96 +Context=Status +Type=Fixed + +[128x128/actions] +Size=128 +Context=Actions +Type=Fixed + +[128x128/apps] +Size=128 +Context=Applications +Type=Fixed + +[128x128/categories] +Size=128 +Context=Categories +Type=Fixed + +[128x128/devices] +Size=128 +Context=Devices +Type=Fixed + +[128x128/emblems] +Size=128 +Context=Emblems +Type=Fixed + +[128x128/emotes] +Size=128 +Context=Emotes +Type=Fixed + +[128x128/mimetypes] +Size=128 +Context=MimeTypes +Type=Fixed + +[128x128/places] +Size=128 +Context=Places +Type=Fixed + +[128x128/status] +Size=128 +Context=Status +Type=Fixed + +[scalable/actions] +Size=48 +Context=Actions +Type=Scalable +MinSize=32 +MaxSize=256 + +[scalable/apps] +Size=48 +Context=Applications +Type=Scalable +MinSize=32 +MaxSize=256 + +[scalable/categories] +Size=48 +Context=Categories +Type=Scalable +MinSize=32 +MaxSize=256 + +[scalable/devices] +Size=48 +Context=Devices +Type=Scalable +MinSize=32 +MaxSize=256 + +[scalable/emblems] +Size=48 +Context=Emblems +Type=Scalable +MinSize=32 +MaxSize=256 + +[scalable/emotes] +Size=48 +Context=Emotes +Type=Scalable +Minsize=32 +MaxSize=256 + +[scalable/mimetypes] +Size=48 +Context=MimeTypes +Type=Scalable +MinSize=32 +MaxSize=256 + +[scalable/places] +Size=48 +Context=Places +Type=Scalable +MinSize=32 +MaxSize=256 + +[scalable/status] +Size=48 +Context=Status +Type=Scalable +MinSize=32 +MaxSize=256 diff --git a/tests/auto/qicon/icons/themeparent/scalable/actions/address-book-new.svg b/tests/auto/qicon/icons/themeparent/scalable/actions/address-book-new.svg new file mode 100644 index 0000000..600a82c --- /dev/null +++ b/tests/auto/qicon/icons/themeparent/scalable/actions/address-book-new.svg @@ -0,0 +1,389 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Addess Book - New + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + + address + contact + book + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/qicon/icons/themeparent/scalable/actions/appointment-new.svg b/tests/auto/qicon/icons/themeparent/scalable/actions/appointment-new.svg new file mode 100644 index 0000000..4cb14f8 --- /dev/null +++ b/tests/auto/qicon/icons/themeparent/scalable/actions/appointment-new.svg @@ -0,0 +1,425 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + New Appointment + + + appointment + new + meeting + rvsp + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/qicon/tst_qicon.cpp b/tests/auto/qicon/tst_qicon.cpp index a266c16..545ca09 100644 --- a/tests/auto/qicon/tst_qicon.cpp +++ b/tests/auto/qicon/tst_qicon.cpp @@ -74,6 +74,7 @@ private slots: void availableSizes(); void streamAvailableSizes_data(); void streamAvailableSizes(); + void fromTheme(); void task184901_badCache(); void task223279_inconsistentAddFile(); @@ -605,6 +606,72 @@ void tst_QIcon::task184901_badCache() QVERIFY( icon.pixmap(32, QIcon::Normal).toImage() == icon.pixmap(32, QIcon::Disabled).toImage() ); } +void tst_QIcon::fromTheme() +{ + const QString prefix = QLatin1String(SRCDIR) + QLatin1String("/"); + QString searchPath = prefix + QLatin1String("/icons"); + QIcon::setThemeSearchPaths(QStringList() << searchPath); + QVERIFY(QIcon::themeSearchPaths().size() == 1); + QCOMPARE(searchPath, QIcon::themeSearchPaths()[0]); + + QString themeName("testtheme"); + QIcon::setThemeName(themeName); + QCOMPARE(QIcon::themeName(), themeName); + + // Test normal icon + QIcon appointmentIcon = QIcon::fromTheme("appointment-new"); + QVERIFY(!appointmentIcon.isNull()); + QVERIFY(!appointmentIcon.availableSizes(QIcon::Normal, QIcon::Off).isEmpty()); + QVERIFY(appointmentIcon.availableSizes().contains(QSize(16, 16))); + QVERIFY(appointmentIcon.availableSizes().contains(QSize(32, 32))); + QVERIFY(appointmentIcon.availableSizes().contains(QSize(22, 22))); + + // Test icon from parent theme + QIcon abIcon = QIcon::fromTheme("address-book-new"); + QVERIFY(!abIcon.isNull()); + QVERIFY(QIcon::hasThemeIcon("address-book-new")); + QVERIFY(!abIcon.availableSizes().isEmpty()); + + // Test non existing icon + QIcon noIcon = QIcon::fromTheme("broken-icon"); + QVERIFY(noIcon.isNull()); + QVERIFY(!QIcon::hasThemeIcon("broken-icon")); + + // Test non existing icon with fallback + noIcon = QIcon::fromTheme("broken-icon", abIcon); + QVERIFY(noIcon.cacheKey() == abIcon.cacheKey()); + + // Test svg-only icon + noIcon = QIcon::fromTheme("svg-icon", abIcon); + QVERIFY(!noIcon.availableSizes().isEmpty()); + + QByteArray ba; + // write to QByteArray + { + QBuffer buffer(&ba); + buffer.open(QIODevice::WriteOnly); + QDataStream stream(&buffer); + stream << abIcon; + } + + // read from QByteArray + { + QBuffer buffer(&ba); + buffer.open(QIODevice::ReadOnly); + QDataStream stream(&buffer); + QIcon i; + stream >> i; + QCOMPARE(i.isNull(), abIcon.isNull()); + QCOMPARE(i.availableSizes(), abIcon.availableSizes()); + } + + // Make sure setting the theme name clears the state + QIcon::setThemeName(""); + abIcon = QIcon::fromTheme("address-book-new"); + QVERIFY(abIcon.isNull()); +} + + void tst_QIcon::task223279_inconsistentAddFile() { QIcon icon1; diff --git a/tools/assistant/compat/mainwindow.cpp b/tools/assistant/compat/mainwindow.cpp index 670b144..9d308df 100644 --- a/tools/assistant/compat/mainwindow.cpp +++ b/tools/assistant/compat/mainwindow.cpp @@ -140,6 +140,16 @@ MainWindow::MainWindow() ui.actionZoomIn->setIcon(QIcon(MacIconPath + QLatin1String("/zoomin.png"))); ui.actionSyncToc->setIcon(QIcon(MacIconPath + QLatin1String("/synctoc.png"))); ui.actionHelpWhatsThis->setIcon(QIcon(MacIconPath + QLatin1String("/whatsthis.png"))); +#elif defined(Q_WS_X11) + ui.actionGoNext->setIcon(QIcon::fromTheme("go-next" , ui.actionGoNext->icon())); + ui.actionGoPrevious->setIcon(QIcon::fromTheme("go-previous" , ui.actionGoPrevious->icon())); + ui.actionGoHome->setIcon(QIcon::fromTheme("user-home" , ui.actionGoHome->icon())); + ui.actionEditCopy->setIcon(QIcon::fromTheme("edit-copy" , ui.actionEditCopy->icon())); + ui.actionEditFind->setIcon(QIcon::fromTheme("edit-find" , ui.actionEditFind->icon())); + ui.actionFilePrint->setIcon(QIcon::fromTheme("document-print" , ui.actionFilePrint->icon())); + ui.actionZoomOut->setIcon(QIcon::fromTheme("zoom-out" , ui.actionZoomOut->icon())); + ui.actionZoomIn->setIcon(QIcon::fromTheme("zoom-in" , ui.actionZoomIn->icon())); + ui.actionSyncToc->setIcon(QIcon::fromTheme("view-refresh" , ui.actionSyncToc->icon())); #endif } diff --git a/tools/assistant/tools/assistant/mainwindow.cpp b/tools/assistant/tools/assistant/mainwindow.cpp index bc73b80..a0d4fbf 100644 --- a/tools/assistant/tools/assistant/mainwindow.cpp +++ b/tools/assistant/tools/assistant/mainwindow.cpp @@ -545,6 +545,19 @@ void MainWindow::setupActions() m_aboutAction = menu->addAction(tr("About..."), this, SLOT(showAboutDialog())); m_aboutAction->setMenuRole(QAction::AboutRole); +#ifdef Q_WS_X11 + m_backAction->setIcon(QIcon::fromTheme("go-previous" , m_backAction->icon())); + m_nextAction->setIcon(QIcon::fromTheme("go-next" , m_nextAction->icon())); + m_zoomInAction->setIcon(QIcon::fromTheme("zoom-in" , m_zoomInAction->icon())); + m_zoomOutAction->setIcon(QIcon::fromTheme("zoom-out" , m_zoomOutAction->icon())); + m_resetZoomAction->setIcon(QIcon::fromTheme("zoom-original" , m_resetZoomAction->icon())); + m_syncAction->setIcon(QIcon::fromTheme("view-refresh" , m_syncAction->icon())); + m_copyAction->setIcon(QIcon::fromTheme("edit-copy" , m_copyAction->icon())); + m_findAction->setIcon(QIcon::fromTheme("edit-find" , m_findAction->icon())); + m_homeAction->setIcon(QIcon::fromTheme("go-home" , m_homeAction->icon())); + m_printAction->setIcon(QIcon::fromTheme("document-print" , m_printAction->icon())); +#endif + QToolBar *navigationBar = addToolBar(tr("Navigation Toolbar")); navigationBar->setObjectName(QLatin1String("NavigationToolBar")); navigationBar->addAction(m_backAction); diff --git a/tools/designer/src/components/buddyeditor/buddyeditor_plugin.cpp b/tools/designer/src/components/buddyeditor/buddyeditor_plugin.cpp index ff0c3c6..cf838a2 100644 --- a/tools/designer/src/components/buddyeditor/buddyeditor_plugin.cpp +++ b/tools/designer/src/components/buddyeditor/buddyeditor_plugin.cpp @@ -72,8 +72,9 @@ void BuddyEditorPlugin::initialize(QDesignerFormEditorInterface *core) m_action = new QAction(tr("Edit Buddies"), this); m_action->setObjectName(QLatin1String("__qt_edit_buddies_action")); - m_action->setIcon(QIcon(core->resourceLocation() + QLatin1String("/buddytool.png"))); - m_action->setIcon(QIcon(core->resourceLocation() + QLatin1String("/buddytool.png"))); + QIcon buddyIcon = QIcon::fromTheme("designer-edit-buddy", + QIcon(core->resourceLocation() + QLatin1String("/buddytool.png"))); + m_action->setIcon(buddyIcon); m_action->setEnabled(false); setParent(core); diff --git a/tools/designer/src/components/formeditor/formwindowmanager.cpp b/tools/designer/src/components/formeditor/formwindowmanager.cpp index 993bae9..a2a0a40 100644 --- a/tools/designer/src/components/formeditor/formwindowmanager.cpp +++ b/tools/designer/src/components/formeditor/formwindowmanager.cpp @@ -443,7 +443,8 @@ void FormWindowManager::setupActions() m_actionVerticalLayout->setEnabled(false); connect(m_actionVerticalLayout, SIGNAL(triggered()), this, SLOT(createLayout())); - QAction *actionFormLayout = new QAction(createIconSet(QLatin1String("editform.png")), tr("Lay Out in a &Form Layout"), this); + QIcon formIcon = QIcon::fromTheme("designer-form-layout", createIconSet(QLatin1String("editform.png"))); + QAction *actionFormLayout = new QAction(formIcon, tr("Lay Out in a &Form Layout"), this); actionFormLayout->setObjectName(QLatin1String("__qt_form_layout_action")); actionFormLayout->setShortcut(Qt::CTRL + Qt::Key_6); actionFormLayout->setStatusTip(tr("Lays out the selected widgets in a form layout")); @@ -510,15 +511,30 @@ void FormWindowManager::setupActions() m_actionUndo = m_undoGroup->createUndoAction(this); m_actionUndo->setEnabled(false); - m_actionUndo->setIcon(createIconSet(QLatin1String("undo.png"))); + + m_actionUndo->setIcon(QIcon::fromTheme("edit-undo", createIconSet(QLatin1String("undo.png")))); m_actionRedo = m_undoGroup->createRedoAction(this); m_actionRedo->setEnabled(false); - m_actionRedo->setIcon(createIconSet(QLatin1String("redo.png"))); + m_actionRedo->setIcon(QIcon::fromTheme("edit-redo", createIconSet(QLatin1String("redo.png")))); m_actionShowFormWindowSettingsDialog = new QAction(tr("Form &Settings..."), this); m_actionShowFormWindowSettingsDialog->setObjectName(QLatin1String("__qt_form_settings_action")); connect(m_actionShowFormWindowSettingsDialog, SIGNAL(triggered()), this, SLOT(slotActionShowFormWindowSettingsDialog())); m_actionShowFormWindowSettingsDialog->setEnabled(false); + + + m_actionCopy->setIcon(QIcon::fromTheme("edit-copy", m_actionCopy->icon())); + m_actionCut->setIcon(QIcon::fromTheme("edit-cut", m_actionCut->icon())); + m_actionPaste->setIcon(QIcon::fromTheme("edit-paste", m_actionPaste->icon())); + + // These do not currently exist, but will allow theme authors to fill in the gaps + m_actionBreakLayout->setIcon(QIcon::fromTheme("designer-break-layout", m_actionBreakLayout->icon())); + m_actionGridLayout->setIcon(QIcon::fromTheme("designer-grid-layout", m_actionGridLayout->icon())); + m_actionHorizontalLayout->setIcon(QIcon::fromTheme("designer-horizontal-layout", m_actionHorizontalLayout->icon())); + m_actionVerticalLayout->setIcon(QIcon::fromTheme("designer-vertical-layout", m_actionVerticalLayout->icon())); + m_actionSplitHorizontal->setIcon(QIcon::fromTheme("designer-split-horizontal", m_actionSplitHorizontal->icon())); + m_actionSplitVertical->setIcon(QIcon::fromTheme("designer-split-vertical", m_actionSplitVertical->icon())); + m_actionAdjustSize->setIcon(QIcon::fromTheme("designer-adjust-size", m_actionAdjustSize->icon())); } void FormWindowManager::slotActionCutActivated() diff --git a/tools/designer/src/components/signalsloteditor/signalsloteditor_plugin.cpp b/tools/designer/src/components/signalsloteditor/signalsloteditor_plugin.cpp index e664ae7..a113041 100644 --- a/tools/designer/src/components/signalsloteditor/signalsloteditor_plugin.cpp +++ b/tools/designer/src/components/signalsloteditor/signalsloteditor_plugin.cpp @@ -72,7 +72,8 @@ void SignalSlotEditorPlugin::initialize(QDesignerFormEditorInterface *core) m_action = new QAction(tr("Edit Signals/Slots"), this); m_action->setObjectName(QLatin1String("__qt_edit_signals_slots_action")); m_action->setShortcut(tr("F4")); - QIcon icon(QIcon(core->resourceLocation() + QLatin1String("/signalslottool.png"))); + QIcon icon = QIcon::fromTheme("designer-edit-signals", + QIcon(core->resourceLocation() + QLatin1String("/signalslottool.png"))); m_action->setIcon(icon); m_action->setEnabled(false); diff --git a/tools/designer/src/components/tabordereditor/tabordereditor_plugin.cpp b/tools/designer/src/components/tabordereditor/tabordereditor_plugin.cpp index 9b051c9..ddddd08 100644 --- a/tools/designer/src/components/tabordereditor/tabordereditor_plugin.cpp +++ b/tools/designer/src/components/tabordereditor/tabordereditor_plugin.cpp @@ -72,7 +72,9 @@ void TabOrderEditorPlugin::initialize(QDesignerFormEditorInterface *core) m_action = new QAction(tr("Edit Tab Order"), this); m_action->setObjectName(QLatin1String("_qt_edit_tab_order_action")); - m_action->setIcon(QIcon(core->resourceLocation() + QLatin1String("/tabordertool.png"))); + QIcon icon = QIcon::fromTheme("designer-edit-tabs", + QIcon(core->resourceLocation() + QLatin1String("/tabordertool.png"))); + m_action->setIcon(icon); m_action->setEnabled(false); setParent(core); diff --git a/tools/designer/src/designer/qdesigner_actions.cpp b/tools/designer/src/designer/qdesigner_actions.cpp index c671386..567a13e 100644 --- a/tools/designer/src/designer/qdesigner_actions.cpp +++ b/tools/designer/src/designer/qdesigner_actions.cpp @@ -200,6 +200,10 @@ QDesignerActions::QDesignerActions(QDesignerWorkbench *workbench) #endif m_previewManager(0) { + m_newFormAction->setIcon(QIcon::fromTheme("document-new", m_newFormAction->icon())); + m_openFormAction->setIcon(QIcon::fromTheme("document-open", m_openFormAction->icon())); + m_saveFormAction->setIcon(QIcon::fromTheme("document-save", m_saveFormAction->icon())); + Q_ASSERT(m_core != 0); qdesigner_internal::QDesignerFormWindowManager *ifwm = qobject_cast(m_core->formWindowManager()); Q_ASSERT(ifwm); @@ -323,7 +327,8 @@ QDesignerActions::QDesignerActions(QDesignerWorkbench *workbench) shortcuts.append(QKeySequence(Qt::Key_Escape)); #endif m_editWidgetsAction->setShortcuts(shortcuts); - m_editWidgetsAction->setIcon(QIcon(m_core->resourceLocation() + QLatin1String("/widgettool.png"))); + QIcon fallback(m_core->resourceLocation() + QLatin1String("/widgettool.png")); + m_editWidgetsAction->setIcon(QIcon::fromTheme("designer-edit-widget", fallback)); connect(m_editWidgetsAction, SIGNAL(triggered()), this, SLOT(editWidgetsSlot())); m_editWidgetsAction->setChecked(true); m_editWidgetsAction->setEnabled(false); diff --git a/tools/designer/src/lib/shared/actioneditor.cpp b/tools/designer/src/lib/shared/actioneditor.cpp index 1a236d6..a931b8a 100644 --- a/tools/designer/src/lib/shared/actioneditor.cpp +++ b/tools/designer/src/lib/shared/actioneditor.cpp @@ -147,7 +147,8 @@ ActionEditor::ActionEditor(QDesignerFormEditorInterface *core, QWidget *parent, toolbar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); l->addWidget(toolbar); // edit actions - m_actionNew->setIcon(createIconSet(QLatin1String("filenew.png"))); + QIcon documentNewIcon = QIcon::fromTheme("document-new", createIconSet(QLatin1String("filenew.png"))); + m_actionNew->setIcon(documentNewIcon); m_actionNew->setEnabled(false); connect(m_actionNew, SIGNAL(triggered()), this, SLOT(slotNewAction())); toolbar->addAction(m_actionNew); @@ -156,15 +157,18 @@ ActionEditor::ActionEditor(QDesignerFormEditorInterface *core, QWidget *parent, m_actionCut->setEnabled(false); connect(m_actionCut, SIGNAL(triggered()), this, SLOT(slotCut())); - m_actionCut->setIcon(createIconSet(QLatin1String("editcut.png"))); + QIcon editCutIcon = QIcon::fromTheme("edit-cut", createIconSet(QLatin1String("editcut.png"))); + m_actionCut->setIcon(editCutIcon); m_actionCopy->setEnabled(false); connect(m_actionCopy, SIGNAL(triggered()), this, SLOT(slotCopy())); - m_actionCopy->setIcon(createIconSet(QLatin1String("editcopy.png"))); + QIcon editCopyIcon = QIcon::fromTheme("edit-copy", createIconSet(QLatin1String("editcopy.png"))); + m_actionCopy->setIcon(editCopyIcon); toolbar->addAction(m_actionCopy); connect(m_actionPaste, SIGNAL(triggered()), this, SLOT(slotPaste())); - m_actionPaste->setIcon(createIconSet(QLatin1String("editpaste.png"))); + QIcon editPasteIcon = QIcon::fromTheme("edit-paste", createIconSet(QLatin1String("editpaste.png"))); + m_actionPaste->setIcon(editPasteIcon); toolbar->addAction(m_actionPaste); m_actionEdit->setEnabled(false); @@ -172,7 +176,8 @@ ActionEditor::ActionEditor(QDesignerFormEditorInterface *core, QWidget *parent, connect(m_actionNavigateToSlot, SIGNAL(triggered()), this, SLOT(navigateToSlotCurrentAction())); - m_actionDelete->setIcon(createIconSet(QLatin1String("editdelete.png"))); + QIcon editDeleteIcon = QIcon::fromTheme("edit-delete", createIconSet(QLatin1String("editdelete.png"))); + m_actionDelete->setIcon(editDeleteIcon); m_actionDelete->setEnabled(false); connect(m_actionDelete, SIGNAL(triggered()), this, SLOT(slotDelete())); toolbar->addAction(m_actionDelete); @@ -243,7 +248,8 @@ QToolButton *ActionEditor::createConfigureMenuButton(const QString &t, QMenu **p { QToolButton *configureButton = new QToolButton; QAction *configureAction = new QAction(t, configureButton); - configureAction->setIcon(createIconSet(QLatin1String("configure.png"))); + QIcon configureIcon = QIcon::fromTheme("document-properties", createIconSet(QLatin1String("configure.png"))); + configureAction->setIcon(configureIcon); QMenu *configureMenu = new QMenu; configureAction->setMenu(configureMenu); configureButton->setDefaultAction(configureAction); diff --git a/tools/designer/src/lib/shared/qtresourceview.cpp b/tools/designer/src/lib/shared/qtresourceview.cpp index 40be3e6..f55f7ae 100644 --- a/tools/designer/src/lib/shared/qtresourceview.cpp +++ b/tools/designer/src/lib/shared/qtresourceview.cpp @@ -582,17 +582,21 @@ QtResourceView::QtResourceView(QDesignerFormEditorInterface *core, QWidget *pare { d_ptr->q_ptr = this; - d_ptr->m_editResourcesAction = new QAction(qdesigner_internal::createIconSet(QLatin1String("edit.png")), tr("Edit Resources..."), this); + QIcon editIcon = QIcon::fromTheme("document-properties", qdesigner_internal::createIconSet(QLatin1String("edit.png"))); + d_ptr->m_editResourcesAction = new QAction(editIcon, tr("Edit Resources..."), this); d_ptr->m_toolBar->addAction(d_ptr->m_editResourcesAction); connect(d_ptr->m_editResourcesAction, SIGNAL(triggered()), this, SLOT(slotEditResources())); d_ptr->m_editResourcesAction->setEnabled(false); - d_ptr->m_reloadResourcesAction = new QAction(qdesigner_internal::createIconSet(QLatin1String("reload.png")), tr("Reload"), this); + QIcon refreshIcon = QIcon::fromTheme("view-refresh", qdesigner_internal::createIconSet(QLatin1String("reload.png"))); + d_ptr->m_reloadResourcesAction = new QAction(refreshIcon, tr("Reload"), this); + d_ptr->m_toolBar->addAction(d_ptr->m_reloadResourcesAction); connect(d_ptr->m_reloadResourcesAction, SIGNAL(triggered()), this, SLOT(slotReloadResources())); d_ptr->m_reloadResourcesAction->setEnabled(false); - d_ptr->m_copyResourcePathAction = new QAction(qdesigner_internal::createIconSet(QLatin1String("editcopy.png")), tr("Copy Path"), this); + QIcon copyIcon = QIcon::fromTheme("edit-copy", qdesigner_internal::createIconSet(QLatin1String("editcopy.png"))); + d_ptr->m_copyResourcePathAction = new QAction(copyIcon, tr("Copy Path"), this); connect(d_ptr->m_copyResourcePathAction, SIGNAL(triggered()), this, SLOT(slotCopyResourcePath())); d_ptr->m_copyResourcePathAction->setEnabled(false); -- cgit v0.12 From f9605d3f396043e5b893470acaeb4c726361e9dc Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Mon, 10 Aug 2009 18:19:53 +0200 Subject: Make QGtkStyle react properly to font changes in GNOME We only reacted to font changes before when the whole theme changed. Two things had to be fixed to support this. We need to check if the font changed in QGtkStyle::updateTheme and we need to make sure that QApplication does not reset these settings for us. Reviewed-by: joao --- src/gui/kernel/qapplication_x11.cpp | 36 ++++++++++++++++++++---------------- src/gui/styles/gtksymbols.cpp | 6 +++++- src/gui/styles/qgtkstyle.cpp | 2 +- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 221101a..470b433 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -871,28 +871,32 @@ bool QApplicationPrivate::x11_apply_settings() } // ### Fix properly for 4.6 - if (!(QApplicationPrivate::app_style && QApplicationPrivate::app_style->inherits("QGtkStyle"))) { + bool usingGtkSettings = QApplicationPrivate::app_style && QApplicationPrivate::app_style->inherits("QGtkStyle"); + if (!usingGtkSettings) { if (groupCount == QPalette::NColorGroups) QApplicationPrivate::setSystemPalette(pal); } if (!appFont) { - QFont font(QApplication::font()); - QString fontDescription; - // Override Qt font if KDE4 settings can be used - if (X11->desktopEnvironment == DE_KDE && X11->desktopVersion >= 4) { - QSettings kdeSettings(QKde::kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat); - fontDescription = kdeSettings.value(QLatin1String("font")).toString(); - if (fontDescription.isEmpty()) { - // KDE stores fonts without quotes - fontDescription = kdeSettings.value(QLatin1String("font")).toStringList().join(QLatin1String(",")); + // ### Fix properly for 4.6 + if (!usingGtkSettings) { + QFont font(QApplication::font()); + QString fontDescription; + // Override Qt font if KDE4 settings can be used + if (X11->desktopVersion == 4) { + QSettings kdeSettings(QKde::kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat); + fontDescription = kdeSettings.value(QLatin1String("font")).toString(); + if (fontDescription.isEmpty()) { + // KDE stores fonts without quotes + fontDescription = kdeSettings.value(QLatin1String("font")).toStringList().join(QLatin1String(",")); + } + } + if (fontDescription.isEmpty()) + fontDescription = settings.value(QLatin1String("font")).toString(); + if (!fontDescription .isEmpty()) { + font.fromString(fontDescription ); + QApplicationPrivate::setSystemFont(font); } - } - if (fontDescription.isEmpty()) - fontDescription = settings.value(QLatin1String("font")).toString(); - if (!fontDescription .isEmpty()) { - font.fromString(fontDescription ); - QApplicationPrivate::setSystemFont(font); } } diff --git a/src/gui/styles/gtksymbols.cpp b/src/gui/styles/gtksymbols.cpp index c8b4fda..2d8d6e2 100644 --- a/src/gui/styles/gtksymbols.cpp +++ b/src/gui/styles/gtksymbols.cpp @@ -547,9 +547,13 @@ void QGtkStyleUpdateScheduler::updateTheme() { static QString oldTheme(QLS("qt_not_set")); QPixmapCache::clear(); + + QFont font = QGtk::getThemeFont(); + if (QApplication::font() != font) + qApp->setFont(font); + if (oldTheme != getThemeName()) { oldTheme = getThemeName(); - qApp->setFont(QGtk::getThemeFont()); QPalette newPalette = qApp->style()->standardPalette(); QApplicationPrivate::setSystemPalette(newPalette); QApplication::setPalette(newPalette); diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index f6d8c88..5f56230 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -1,4 +1,4 @@ -/******* ********************************************************************* +/**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Nokia Corporation (qt-info@nokia.com) -- cgit v0.12 From 4096911423fcd52c59d83f153b3a83ae99312a70 Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Mon, 10 Aug 2009 19:23:04 +0200 Subject: Add a Widget for manual testing of the tablet API The QTabletWidget shows the informations provided by the last QTabletEvent. --- tests/manual/qtabletevent/main.cpp | 9 ++ tests/manual/qtabletevent/qtabletevent.pro | 13 +++ tests/manual/qtabletevent/tabletwidget.cpp | 150 +++++++++++++++++++++++++++++ tests/manual/qtabletevent/tabletwidget.h | 32 ++++++ 4 files changed, 204 insertions(+) create mode 100644 tests/manual/qtabletevent/main.cpp create mode 100644 tests/manual/qtabletevent/qtabletevent.pro create mode 100644 tests/manual/qtabletevent/tabletwidget.cpp create mode 100644 tests/manual/qtabletevent/tabletwidget.h diff --git a/tests/manual/qtabletevent/main.cpp b/tests/manual/qtabletevent/main.cpp new file mode 100644 index 0000000..4014d58 --- /dev/null +++ b/tests/manual/qtabletevent/main.cpp @@ -0,0 +1,9 @@ +#include +#include "tabletwidget.h" + +int main(int argc, char **argv) { + QApplication app(argc, argv); + TabletWidget tabletWidget; + tabletWidget.showMaximized(); + return app.exec(); +} diff --git a/tests/manual/qtabletevent/qtabletevent.pro b/tests/manual/qtabletevent/qtabletevent.pro new file mode 100644 index 0000000..e0ed549 --- /dev/null +++ b/tests/manual/qtabletevent/qtabletevent.pro @@ -0,0 +1,13 @@ +###################################################################### +# Automatically generated by qmake (2.01a) Mon Aug 10 17:02:09 2009 +###################################################################### + +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += main.cpp\ + tabletwidget.cpp +HEADERS += tabletwidget.h diff --git a/tests/manual/qtabletevent/tabletwidget.cpp b/tests/manual/qtabletevent/tabletwidget.cpp new file mode 100644 index 0000000..4d6a365 --- /dev/null +++ b/tests/manual/qtabletevent/tabletwidget.cpp @@ -0,0 +1,150 @@ +#include "tabletwidget.h" +#include +#include + +TabletWidget::TabletWidget() +{ + QPalette newPalette = palette(); + newPalette.setColor(QPalette::Window, Qt::white); + setPalette(newPalette); + qApp->installEventFilter(this); + resetAttributes(); +} + +bool TabletWidget::eventFilter(QObject *, QEvent *ev) +{ + switch (ev->type()) { + case QEvent::TabletEnterProximity: + case QEvent::TabletLeaveProximity: + case QEvent::TabletMove: + case QEvent::TabletPress: + case QEvent::TabletRelease: + { + QTabletEvent *event = static_cast(ev); + mType = event->type(); + mPos = event->pos(); + mGPos = event->globalPos(); + mHiResGlobalPos = event->hiResGlobalPos(); + mDev = event->device(); + mPointerType = event->pointerType(); + mUnique = event->uniqueId(); + mXT = event->xTilt(); + mYT = event->yTilt(); + mZ = event->z(); + mPress = event->pressure(); + mTangential = event->tangentialPressure(); + mRot = event->rotation(); + if (isVisible()) + update(); + break; + } + case QEvent::MouseMove: + { + resetAttributes(); + QMouseEvent *event = static_cast(ev); + mType = event->type(); + mPos = event->pos(); + mGPos = event->globalPos(); + } + default: + break; + } + return false; +} + +void TabletWidget::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + + QStringList eventInfo; + + QString typeString("Event type: "); + switch (mType) { + case QEvent::TabletEnterProximity: + typeString += "QEvent::TabletEnterProximity"; + break; + case QEvent::TabletLeaveProximity: + typeString += "QEvent::TabletLeaveProximity"; + break; + case QEvent::TabletMove: + typeString += "QEvent::TabletMove"; + break; + case QEvent::TabletPress: + typeString += "QEvent::TabletPress"; + break; + case QEvent::TabletRelease: + typeString += "QEvent::TabletRelease"; + break; + case QEvent::MouseMove: + typeString += "QEvent::MouseMove"; + break; + } + eventInfo << typeString; + + eventInfo << QString("Global position: %1 %2").arg(QString::number(mGPos.x()), QString::number(mGPos.y())); + eventInfo << QString("Local position: %1 %2").arg(QString::number(mPos.x()), QString::number(mPos.y())); + if (mType == QEvent::TabletEnterProximity || mType == QEvent::TabletLeaveProximity + || mType == QEvent::TabletMove || mType == QEvent::TabletPress + || mType == QEvent::TabletRelease) { + + eventInfo << QString("Hight res global position: %1 %2").arg(QString::number(mHiResGlobalPos.x()), QString::number(mHiResGlobalPos.y())); + + QString pointerType("Pointer type: "); + switch (mPointerType) { + case QTabletEvent::UnknownPointer: + pointerType += "QTabletEvent::UnknownPointer"; + break; + case QTabletEvent::Pen: + pointerType += "QTabletEvent::Pen"; + break; + case QTabletEvent::Cursor: + pointerType += "QTabletEvent::Cursor"; + break; + case QTabletEvent::Eraser: + pointerType += "QTabletEvent::Eraser"; + break; + } + eventInfo << pointerType; + + + QString deviceString = "Device type: "; + switch (mDev) { + case QTabletEvent::NoDevice: + deviceString += "QTabletEvent::NoDevice"; + break; + case QTabletEvent::Puck: + deviceString += "QTabletEvent::Puck"; + break; + case QTabletEvent::Stylus: + deviceString += "QTabletEvent::Stylus"; + break; + case QTabletEvent::Airbrush: + deviceString += "QTabletEvent::Airbrush"; + break; + case QTabletEvent::FourDMouse: + deviceString += "QTabletEvent::FourDMouse"; + break; + case QTabletEvent::RotationStylus: + deviceString += "QTabletEvent::RotationStylus"; + break; + } + eventInfo << deviceString; + + eventInfo << QString("Pressure: %1").arg(QString::number(mPress)); + eventInfo << QString("Tangential pressure: %1").arg(QString::number(mTangential)); + eventInfo << QString("Rotation: %1").arg(QString::number(mRot)); + eventInfo << QString("xTilt: %1").arg(QString::number(mXT)); + eventInfo << QString("yTilt: %1").arg(QString::number(mYT)); + eventInfo << QString("z: %1").arg(QString::number(mZ)); + + eventInfo << QString("Unique Id: %1").arg(QString::number(mUnique)); + } + + painter.drawText(rect(), eventInfo.join("\n")); +} + +void TabletWidget::tabletEvent(QTabletEvent *event) +{ + event->accept(); +} + diff --git a/tests/manual/qtabletevent/tabletwidget.h b/tests/manual/qtabletevent/tabletwidget.h new file mode 100644 index 0000000..b0efef2 --- /dev/null +++ b/tests/manual/qtabletevent/tabletwidget.h @@ -0,0 +1,32 @@ +#ifndef TABLETWIDGET_H +#define TABLETWIDGET_H + +#include +#include + +// a widget showing the information of the last tablet event +class TabletWidget : public QWidget +{ +public: + TabletWidget(); +protected: + bool eventFilter(QObject *obj, QEvent *ev); + void tabletEvent(QTabletEvent *event); + void paintEvent(QPaintEvent *event); +private: + void resetAttributes() { + mType = mDev = mPointerType = mXT = mYT = mZ = 0; + mPress = mTangential = mRot = 0.0; + mPos = mGPos = QPoint(); + mHiResGlobalPos = QPointF(); + mUnique = 0; + } + int mType; + QPoint mPos, mGPos; + QPointF mHiResGlobalPos; + int mDev, mPointerType, mXT, mYT, mZ; + qreal mPress, mTangential, mRot; + qint64 mUnique; +}; + +#endif // TABLETWIDGET_H -- cgit v0.12 From 557b8c58023ad0bdbd79bf25b770dc873a57cad1 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 10 Aug 2009 19:37:30 +0200 Subject: Doc: Documented the use of spaces in qmake variables. Reviewed-by: Trust Me --- doc/src/qmake-manual.qdoc | 23 +++++++++++++++++++++-- doc/src/snippets/qmake/spaces.pro | 9 +++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 doc/src/snippets/qmake/spaces.pro diff --git a/doc/src/qmake-manual.qdoc b/doc/src/qmake-manual.qdoc index 211d7e9..3363881 100644 --- a/doc/src/qmake-manual.qdoc +++ b/doc/src/qmake-manual.qdoc @@ -258,6 +258,8 @@ on strings and lists of values. These are described in the chapter on \l{qmake Advanced Usage}. + \section3 Whitespace + Normally, variables are used to contain whitespace-separated lists of values. However, it is sometimes necessary to specify values containing spaces. These must be quoted in the following way: @@ -265,7 +267,10 @@ \snippet doc/src/snippets/qmake/quoting.pro 0 The quoted text is treated as a single item in the list of values held by - the variable. + the variable. This approach is used to deal with paths that contain spaces, + particularly on the Windows platform. See the documentation for the + \l{qmake Variable Reference#INCLUDEPATH}{INCLUDEPATH} and + \l{qmake Variable Reference#LIBS}{LIBS} variables for examples. \section2 Comments @@ -380,7 +385,7 @@ This is ignored if \c warn_off is specified. \row \o warn_off \o The compiler should output as few warnings as possible. \row \o copy_dir_files \o Enables the install rule to also copy directories, not just files. - \endtable + \endtable The \c debug_and_release option is special in that it enables \e both debug and release versions of a project to be built. In such a case, the Makefile that @@ -1369,6 +1374,13 @@ \snippet doc/src/snippets/code/doc_src_qmake-manual.qdoc 35 + To specify a path containing spaces, quote the path using the technique + mentioned in the \l{qmake Project Files#Whitespace}{qmake Project Files} + document. For example, paths with spaces can be specified on Windows + and Unix platforms in the following way: + + \snippet doc/src/snippets/qmake/spaces.pro quoting include paths with spaces + \target INSTALLS \section1 INSTALLS @@ -1422,6 +1434,13 @@ \snippet doc/src/snippets/code/doc_src_qmake-manual.qdoc 38 + To specify a path containing spaces, quote the path using the technique + mentioned in the \l{qmake Project Files#Whitespace}{qmake Project Files} + document. For example, paths with spaces can be specified on Windows + and Unix platforms in the following way: + + \snippet doc/src/snippets/qmake/spaces.pro quoting library paths with spaces + \bold{Note:} On Windows, specifying libraries with the \c{-l} option, as in the above example, will cause the library with the highest version number to be used; for example, \c{libmath2.lib} could potentially be used diff --git a/doc/src/snippets/qmake/spaces.pro b/doc/src/snippets/qmake/spaces.pro new file mode 100644 index 0000000..c78e984 --- /dev/null +++ b/doc/src/snippets/qmake/spaces.pro @@ -0,0 +1,9 @@ +#! [quoting library paths with spaces] +win32:LIBS += "C:/mylibs/extra libs/extra.lib" +unix:LIBS += -L"/home/user/extra libs" -lextra +#! [quoting library paths with spaces] + +#! [quoting include paths with spaces] +win32:INCLUDEPATH += "C:/mylibs/extra headers" +unix:INCLUDEPATH += "/home/user/extra headers" +#! [quoting include paths with spaces] -- cgit v0.12 From dd9d869300d34725bc480d827f91b3103c84f045 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 10 Aug 2009 19:50:01 +0200 Subject: fixing the Windows CE build after adding gesture support We must guard the code with QT_WINCE_GESTURES. Reviewed-by: TrustMe --- src/gui/kernel/qapplication_win.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index bb910b7..a0142e1 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -816,13 +816,13 @@ void qt_init(QApplicationPrivate *priv, int) priv->GetGestureInfo = 0; priv->GetGestureExtraArgs = 0; -#ifdef Q_WS_WINCE_WM +#if defined(Q_WS_WINCE_WM) && defined(QT_WINCE_GESTURES) priv->GetGestureInfo = (PtrGetGestureInfo) &TKGetGestureInfo; priv->GetGestureExtraArgs = (PtrGetGestureExtraArgs) &TKGetGestureExtraArguments; priv->CloseGestureInfoHandle = (PtrCloseGestureInfoHandle) 0; priv->SetGestureConfig = (PtrSetGestureConfig) 0; priv->GetGestureConfig = (PtrGetGestureConfig) 0; -#else +#elif !defined(Q_WS_WINCE) priv->GetGestureInfo = (PtrGetGestureInfo)QLibrary::resolve(QLatin1String("user32"), "GetGestureInfo"); @@ -1252,7 +1252,10 @@ void QApplication::beep() static void alert_widget(QWidget *widget, int duration) { -#ifndef Q_OS_WINCE +#ifdef Q_OS_WINCE + Q_UNUSED(widget); + Q_UNUSED(duration); +#else bool stopFlash = duration < 0; if (widget && (!widget->isActiveWindow() || stopFlash)) { @@ -3729,10 +3732,14 @@ bool QETWidget::translateGestureEvent(const MSG &msg) gi.cbSize = sizeof(GESTUREINFO); QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); -#ifdef Q_WS_WINCE_WM +#if defined(Q_WS_WINCE_WM) && defined(QT_WINCE_GESTURES) +#undef GID_ZOOM #define GID_ZOOM 0xf000 +#undef GID_ROTATE #define GID_ROTATE 0xf001 +#undef GID_TWOFINGERTAP #define GID_TWOFINGERTAP 0xf002 +#undef GID_ROLLOVER #define GID_ROLLOVER 0xf003 #endif BOOL bResult = false; -- cgit v0.12 From 36c93eca351218ce43a0c6346209d364737b6b84 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 10 Aug 2009 20:46:16 +0200 Subject: Better implementation for commit d13418effc5f00474541ae513a30c9a42c2a1cb3. The previous version could run in an endless loop with infinite models. Reviewed-by: olivier --- src/gui/itemviews/qitemselectionmodel.cpp | 60 +++++++++++++--------- src/gui/itemviews/qitemselectionmodel_p.h | 2 - .../tst_qitemselectionmodel.cpp | 30 +++++++++++ 3 files changed, 66 insertions(+), 26 deletions(-) diff --git a/src/gui/itemviews/qitemselectionmodel.cpp b/src/gui/itemviews/qitemselectionmodel.cpp index 0f35ac1..06c345f 100644 --- a/src/gui/itemviews/qitemselectionmodel.cpp +++ b/src/gui/itemviews/qitemselectionmodel.cpp @@ -590,31 +590,43 @@ void QItemSelectionModelPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &pare emit q->currentColumnChanged(currentIndex, old); } - // update selectionsx - QModelIndex tl = model->index(start, 0, parent); - QModelIndex br = model->index(end, model->columnCount(parent) - 1, parent); - recursiveDeselect(QItemSelectionRange(tl, br)); - finalize(); -} - -void QItemSelectionModelPrivate::recursiveDeselect(const QItemSelectionRange &range) -{ - Q_Q(QItemSelectionModel); - - QItemSelection sel(range.topLeft(), range.bottomRight()); - q->select(sel, QItemSelectionModel::Deselect); - - QModelIndexList idxList = range.indexes(); - QModelIndexList::const_iterator it = idxList.begin(); - for (; it != idxList.end(); ++it) - { - if (!model->hasChildren(*it)) - continue; - - const QModelIndex &firstChild = it->child(0,0); - const QModelIndex &lastChild = it->child(model->rowCount(*it) - 1, model->columnCount(*it) - 1); - recursiveDeselect(QItemSelectionRange(firstChild, lastChild)); + QItemSelection deselected; + QItemSelection::iterator it = currentSelection.begin(); + while (it != currentSelection.end()) { + if (it->topLeft().parent() != parent) { // Check parents until reaching root or contained in range + QModelIndex itParent = it->topLeft().parent(); + while (itParent.isValid() && itParent.parent() != parent) + itParent = itParent.parent(); + + if (parent.isValid() && start <= itParent.row() && itParent.row() <= end) { + deselected.append(*it); + it = currentSelection.erase(it); + } else { + ++it; + } + } else if (start <= it->bottom() && it->bottom() <= end // Full inclusion + && start <= it->top() && it->top() <= end) { + deselected.append(*it); + it = currentSelection.erase(it); + } else if (start <= it->top() && it->top() <= end) { // Top intersection + deselected.append(QItemSelectionRange(it->topLeft(), model->index(end, it->left(), it->parent()))); + it = currentSelection.insert(it, QItemSelectionRange(model->index(end + 1, it->left(), it->parent()), + it->bottomRight())); + it = currentSelection.erase(++it); + } else if (start <= it->bottom() && it->bottom() <= end) { // Bottom intersection + deselected.append(QItemSelectionRange(model->index(start, it->right(), it->parent()), it->bottomRight())); + it = currentSelection.insert(it, QItemSelectionRange(it->topLeft(), + model->index(start - 1, it->right(), it->parent()))); + it = currentSelection.erase(++it); + } else { + if (it->top() < start && end < it->bottom()) // Middle intersection (do nothing) + deselected.append(QItemSelectionRange(model->index(start, it->right(), it->parent()), + model->index(end, it->left(), it->parent()))); + ++it; + } } + + emit q->selectionChanged(QItemSelection(), deselected); } /*! diff --git a/src/gui/itemviews/qitemselectionmodel_p.h b/src/gui/itemviews/qitemselectionmodel_p.h index 8176d4c..18ad506 100644 --- a/src/gui/itemviews/qitemselectionmodel_p.h +++ b/src/gui/itemviews/qitemselectionmodel_p.h @@ -77,8 +77,6 @@ public: void _q_layoutAboutToBeChanged(); void _q_layoutChanged(); - void recursiveDeselect(const QItemSelectionRange &range); - inline void remove(QList &r) { QList::const_iterator it = r.constBegin(); diff --git a/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp b/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp index 05e23f1..ec21f79 100644 --- a/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp +++ b/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp @@ -2209,6 +2209,36 @@ void tst_QItemSelectionModel::task232634_childrenDeselectionSignal() QSignalSpy deselectSpy(&selectionModel, SIGNAL(selectionChanged(const QItemSelection& , const QItemSelection&))); model.removeRows(0, 1, root); QVERIFY(deselectSpy.count() == 1); + + // More testing stress for the patch. + model.clear(); + selectionModel.clear(); + + parentItem = model.invisibleRootItem(); + for (int i = 0; i < 2; ++i) { + QStandardItem *item = new QStandardItem(QString("item %0").arg(i)); + parentItem->appendRow(item); + } + for (int i = 0; i < 2; ++i) { + parentItem = model.invisibleRootItem()->child(i, 0); + for (int j = 0; j < 2; ++j) { + QStandardItem *item = new QStandardItem(QString("item %0.%1").arg(i).arg(j)); + parentItem->appendRow(item); + } + } + + sel = model.index(0, 0).child(0, 0); + selectionModel.select(sel, QItemSelectionModel::Select); + QModelIndex sel2 = model.index(1, 0).child(0, 0); + selectionModel.select(sel2, QItemSelectionModel::Select); + + QVERIFY(selectionModel.selection().contains(sel)); + QVERIFY(selectionModel.selection().contains(sel2)); + deselectSpy.clear(); + model.removeRow(0, model.index(0, 0)); + QVERIFY(deselectSpy.count() == 1); + QVERIFY(!selectionModel.selection().contains(sel)); + QVERIFY(selectionModel.selection().contains(sel2)); } QTEST_MAIN(tst_QItemSelectionModel) -- cgit v0.12 From a675f83543d9a8bb61cb5f5227c6793ae343cc80 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Mon, 10 Aug 2009 21:51:31 +0200 Subject: Doc: Fix links and qdoc warnings. --- src/gui/image/qicon.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index 7a43514..b7759e4 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -870,7 +870,7 @@ QList QIcon::availableSizes(Mode mode, State state) const /*! \since 4.6 - Sets the search paths for icon themes. + Sets the search paths for icon themes to \a paths. \sa themeSearchPaths(), fromTheme() */ void QIcon::setThemeSearchPaths(const QStringList &paths) @@ -893,7 +893,7 @@ void QIcon::setThemeSearchPaths(const QStringList &paths) On Mac the default search path will search in the [Contents/Resources/icons] part of the application bundle. - \sa setThemeSearchPaths(), fromName() + \sa setThemeSearchPaths(), fromTheme() */ QStringList QIcon::themeSearchPaths() { @@ -923,7 +923,7 @@ void QIcon::setThemeName(const QString &path) On X11, the current icon theme depends on your desktop settings. On other platforms it is not set by default. - \sa themeSearchPaths(), themeIcon(), fromTheme(), hasThemeIcon() + \sa themeSearchPaths(), fromTheme(), hasThemeIcon() */ QString QIcon::themeName() { -- cgit v0.12 From 6c3c9d812a730d5bc1bcd6261befe077a65be594 Mon Sep 17 00:00:00 2001 From: Bill King Date: Tue, 11 Aug 2009 08:23:30 +1000 Subject: Fixes coverity warning of uninit variable. --- 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 4fd0c11..fccc622 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -158,7 +158,7 @@ void QPSQLDriverPrivate::appendTables(QStringList &tl, QSqlQuery &t, QChar type) class QPSQLResultPrivate { public: - QPSQLResultPrivate(QPSQLResult *qq): q(qq), driver(0), result(0), currentSize(-1) {} + QPSQLResultPrivate(QPSQLResult *qq): q(qq), driver(0), result(0), currentSize(-1), preparedQueriesEnabled(false) {} QPSQLResult *q; const QPSQLDriverPrivate *driver; -- cgit v0.12 From b2690f454d3a9066f6651afb1f398f9fbaebac28 Mon Sep 17 00:00:00 2001 From: Bill King Date: Tue, 11 Aug 2009 10:12:27 +1000 Subject: Make compile. --- src/gui/image/qiconloader.cpp | 1 + src/gui/image/qiconloader_p.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp index 6bf8d3b..e6e3074 100644 --- a/src/gui/image/qiconloader.cpp +++ b/src/gui/image/qiconloader.cpp @@ -53,6 +53,7 @@ #include #include #include +#include #ifdef Q_WS_MAC #include diff --git a/src/gui/image/qiconloader_p.h b/src/gui/image/qiconloader_p.h index 707107c..08d6cfe 100644 --- a/src/gui/image/qiconloader_p.h +++ b/src/gui/image/qiconloader_p.h @@ -58,6 +58,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE -- cgit v0.12 From 276ad6012620864d4e9fb4a9cb45bcf904c9fbc3 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Tue, 11 Aug 2009 12:58:44 +1000 Subject: Use a linked list for signal/slot ConnectionList Using a linked list, rather than a QList improves connection performance by eliminating the QList allocation costs. Reviewed-by: brad --- src/corelib/kernel/qobject.cpp | 116 +++++++++++++++++++++++++++-------------- src/corelib/kernel/qobject_p.h | 9 +++- 2 files changed, 86 insertions(+), 39 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 6520170..371770f 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -257,11 +257,13 @@ bool QObjectPrivate::isSender(const QObject *receiver, const char *signal) const QMutexLocker locker(signalSlotLock(q)); if (connectionLists) { if (signal_index < connectionLists->count()) { - const ConnectionList &connectionList = connectionLists->at(signal_index); - for (int i = 0; i < connectionList.count(); ++i) { - const QObjectPrivate::Connection *c = connectionList.at(i); + const QObjectPrivate::Connection *c = + connectionLists->at(signal_index).first; + + while (c) { if (c->receiver == receiver) return true; + c = c->nextConnectionList; } } } @@ -279,11 +281,12 @@ QObjectList QObjectPrivate::receiverList(const char *signal) const QMutexLocker locker(signalSlotLock(q)); if (connectionLists) { if (signal_index < connectionLists->count()) { - const ConnectionList &connectionList = connectionLists->at(signal_index); - for (int i = 0; i < connectionList.count(); ++i) { - const QObjectPrivate::Connection *c = connectionList.at(i); + const QObjectPrivate::Connection *c = connectionLists->at(signal_index).first; + + while (c) { if (c->receiver) returnValue << c->receiver; + c = c->nextConnectionList; } } } @@ -308,7 +311,13 @@ void QObjectPrivate::addConnection(int signal, Connection *c) connectionLists->resize(signal + 1); ConnectionList &connectionList = (*connectionLists)[signal]; - connectionList.append(c); + if (connectionList.last) { + connectionList.last->nextConnectionList = c; + } else { + connectionList.first = c; + } + connectionList.last = c; + cleanConnectionLists(); } @@ -317,14 +326,32 @@ void QObjectPrivate::cleanConnectionLists() if (connectionLists->dirty && !connectionLists->inUse) { // remove broken connections for (int signal = -1; signal < connectionLists->count(); ++signal) { - QObjectPrivate::ConnectionList &connectionList = (*connectionLists)[signal]; - for (int i = 0; i < connectionList.count(); ++i) { - QObjectPrivate::Connection *c = connectionList.at(i); - if (!c->receiver) { + QObjectPrivate::ConnectionList &connectionList = + (*connectionLists)[signal]; + + // Set to the last entry in the connection list that was *not* + // deleted. This is needed to update the list's last pointer + // at the end of the cleanup. + QObjectPrivate::Connection *last = 0; + + QObjectPrivate::Connection **prev = &connectionList.first; + QObjectPrivate::Connection *c = *prev; + while (c) { + if (c->receiver) { + last = c; + prev = &c->nextConnectionList; + c = *prev; + } else { + QObjectPrivate::Connection *next = c->nextConnectionList; + *prev = next; delete c; - connectionList.removeAt(i--); + c = next; } } + + // Correct the connection list's last pointer. As + // conectionList.last could equal last, this could be a noop + connectionList.last = last; } connectionLists->dirty = false; } @@ -797,17 +824,19 @@ QObject::~QObject() if (d->connectionLists) { ++d->connectionLists->inUse; for (int signal = -1; signal < d->connectionLists->count(); ++signal) { - QObjectPrivate::ConnectionList &connectionList = (*d->connectionLists)[signal]; - for (int i = 0; i < connectionList.count(); ++i) { - QObjectPrivate::Connection *c = connectionList[i]; + QObjectPrivate::ConnectionList &connectionList = + (*d->connectionLists)[signal]; + + while (QObjectPrivate::Connection *c = connectionList.first) { if (!c->receiver) { + connectionList.first = c->nextConnectionList; delete c; continue; } QMutex *m = signalSlotLock(c->receiver); bool needToUnlock = QOrderedMutexLocker::relock(locker.mutex(), m); - c = connectionList[i]; + if (c->receiver) { *c->prev = c->next; if (c->next) c->next->prev = c->prev; @@ -815,6 +844,7 @@ QObject::~QObject() if (needToUnlock) m->unlock(); + connectionList.first = c->nextConnectionList; delete c; } } @@ -2412,11 +2442,11 @@ int QObject::receivers(const char *signal) const QMutexLocker locker(signalSlotLock(this)); if (d->connectionLists) { if (signal_index < d->connectionLists->count()) { - const QObjectPrivate::ConnectionList &connectionList = - d->connectionLists->at(signal_index); - for (int i = 0; i < connectionList.count(); ++i) { - const QObjectPrivate::Connection *c = connectionList.at(i); + const QObjectPrivate::Connection *c = + d->connectionLists->at(signal_index).first; + while (c) { receivers += c->receiver ? 1 : 0; + c = c->nextConnectionList; } } } @@ -2861,11 +2891,13 @@ bool QMetaObject::connect(const QObject *sender, int signal_index, if (type & Qt::UniqueConnection) { QObjectConnectionListVector *connectionLists = s->d_func()->connectionLists; if (connectionLists && connectionLists->count() > signal_index) { - QObjectPrivate::ConnectionList &connectionList = (*connectionLists)[signal_index]; - for (int i = 0; i < connectionList.count(); ++i) { - QObjectPrivate::Connection *c2 = connectionList.at(i); + const QObjectPrivate::Connection *c2 = + (*connectionLists)[signal_index].first; + + while (c2) { if (c2->receiver == receiver && c2->method == method_index) return false; + c2 = c2->nextConnectionList; } } type &= Qt::UniqueConnection - 1; @@ -2877,6 +2909,7 @@ bool QMetaObject::connect(const QObject *sender, int signal_index, c->method = method_index; c->connectionType = type; c->argumentTypes = types; + c->nextConnectionList = 0; c->prev = &r->d_func()->senders; c->next = *c->prev; *c->prev = c; @@ -2926,9 +2959,9 @@ bool QMetaObject::disconnect(const QObject *sender, int signal_index, if (signal_index < 0) { // remove from all connection lists for (signal_index = -1; signal_index < connectionLists->count(); ++signal_index) { - QObjectPrivate::ConnectionList &connectionList = (*connectionLists)[signal_index]; - for (int i = 0; i < connectionList.count(); ++i) { - QObjectPrivate::Connection *c = connectionList[i]; + QObjectPrivate::Connection *c = + (*connectionLists)[signal_index].first; + while (c) { if (c->receiver && (r == 0 || (c->receiver == r && (method_index < 0 || c->method == method_index)))) { @@ -2937,7 +2970,6 @@ bool QMetaObject::disconnect(const QObject *sender, int signal_index, if (!receiverMutex && senderMutex != m) { // need to relock this receiver and sender in the correct order needToUnlock = QOrderedMutexLocker::relock(senderMutex, m); - c = connectionList[i]; } if (c->receiver) { *c->prev = c->next; @@ -2952,12 +2984,13 @@ bool QMetaObject::disconnect(const QObject *sender, int signal_index, success = true; connectionLists->dirty = true; } + c = c->nextConnectionList; } } } else if (signal_index < connectionLists->count()) { - QObjectPrivate::ConnectionList &connectionList = (*connectionLists)[signal_index]; - for (int i = 0; i < connectionList.count(); ++i) { - QObjectPrivate::Connection *c = connectionList[i]; + QObjectPrivate::Connection *c = + (*connectionLists)[signal_index].first; + while (c) { if (c->receiver && (r == 0 || (c->receiver == r && (method_index < 0 || c->method == method_index)))) { @@ -2966,7 +2999,6 @@ bool QMetaObject::disconnect(const QObject *sender, int signal_index, if (!receiverMutex && senderMutex != m) { // need to relock this receiver and sender in the correct order needToUnlock = QOrderedMutexLocker::relock(senderMutex, m); - c = connectionList[i]; } if (c->receiver) { *c->prev = c->next; @@ -2980,6 +3012,7 @@ bool QMetaObject::disconnect(const QObject *sender, int signal_index, success = true; connectionLists->dirty = true; } + c = c->nextConnectionList; } } @@ -3144,9 +3177,14 @@ void QMetaObject::activate(QObject *sender, int from_signal_index, int to_signal signal = to_signal_index; continue; } - int count = connectionLists->at(signal).count(); - for (int i = 0; i < count; ++i) { - QObjectPrivate::Connection *c = connectionLists->at(signal)[i]; + + QObjectPrivate::Connection *c = connectionLists->at(signal).first; + if (!c) continue; + // We need to check against last here to ensure that signals added + // during the signal emission are not emitted in this emission. + QObjectPrivate::Connection *last = connectionLists->at(signal).last; + + do { if (!c->receiver) continue; @@ -3208,7 +3246,7 @@ void QMetaObject::activate(QObject *sender, int from_signal_index, int to_signal if (connectionLists->orphaned) break; - } + } while (c != last && (c = c->nextConnectionList) != 0); if (connectionLists->orphaned) break; @@ -3527,11 +3565,12 @@ void QObject::dumpObjectInfo() qDebug(" signal: %s", signal.signature()); // receivers - const QObjectPrivate::ConnectionList &connectionList = d->connectionLists->at(signal_index); - for (int i = 0; i < connectionList.count(); ++i) { - const QObjectPrivate::Connection *c = connectionList.at(i); + const QObjectPrivate::Connection *c = + d->connectionLists->at(signal_index).first; + while (c) { if (!c->receiver) { qDebug(" "); + c = c->nextConnectionList; continue; } const QMetaObject *receiverMetaObject = c->receiver->metaObject(); @@ -3540,6 +3579,7 @@ void QObject::dumpObjectInfo() receiverMetaObject->className(), c->receiver->objectName().isEmpty() ? "unnamed" : qPrintable(c->receiver->objectName()), method.signature()); + c = c->nextConnectionList; } } } else { diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 5d17bfd..4f8f1b9 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -113,12 +113,19 @@ public: int method; uint connectionType : 3; // 0 == auto, 1 == direct, 2 == queued, 4 == blocking QBasicAtomicPointer argumentTypes; + // The next pointer for the singly-linked ConnectionList + Connection *nextConnectionList; //senders linked list Connection *next; Connection **prev; ~Connection(); }; - typedef QList ConnectionList; + // ConnectionList is a singly-linked list + struct ConnectionList { + ConnectionList() : first(0), last(0) {} + Connection *first; + Connection *last; + }; struct Sender { -- cgit v0.12 From b200e79d5df436f2c881f8a2bc5534ee53e664d5 Mon Sep 17 00:00:00 2001 From: Bill King Date: Tue, 11 Aug 2009 13:50:12 +1000 Subject: Fixes false fails in interbase autotests. --- tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp | 3 +++ tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 4 ++++ tests/auto/qsqlquery/tst_qsqlquery.cpp | 2 ++ 3 files changed, 9 insertions(+) diff --git a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp index e5a9b01..0f30656 100644 --- a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp +++ b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp @@ -524,6 +524,9 @@ void tst_Q3SqlCursor::unicode() if ( !db.driver()->hasFeature( QSqlDriver::Unicode ) ) { QSKIP( "DBMS not Unicode capable", SkipSingle ); } + // ascii in the data storage, can't transliterate properly. invalid test. + if(db.driverName().startsWith("QIBASE") && (db.databaseName() == "silence.nokia.troll.no:c:\\ibase\\testdb_ascii" || db.databaseName() == "/opt/interbase/qttest.gdb")) + QSKIP("Can't transliterate extended unicode to ascii", SkipSingle); Q3SqlCursor cur( qTableName( "qtest_unicode" ), true, db ); QSqlRecord* irec = cur.primeInsert(); diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index fe4c86e..83569b4 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -2274,6 +2274,10 @@ void tst_QSqlDatabase::eventNotificationPSQL() QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); +#if defined(Q_OS_LINUX) + QSKIP( "Event support doesn't work on linux", SkipAll ); +#endif + QSqlQuery query(db); QString procedureName = qTableName("posteventProc"); diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index f3dd920..e1823e6 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -1611,6 +1611,8 @@ void tst_QSqlQuery::prepare_bind_exec() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); + if(db.driverName().startsWith("QIBASE") && (db.databaseName() == "silence.nokia.troll.no:c:\\ibase\\testdb_ascii" || db.databaseName() == "/opt/interbase/qttest.gdb")) + QSKIP("Can't transliterate extended unicode to ascii", SkipSingle); { // new scope for SQLITE -- cgit v0.12 From f5795d4e84b132f5c8640c73265763ecfda566d3 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 11 Aug 2009 09:02:17 +0200 Subject: compile fix for Win32 use correct function pointer (Get) Reviewed-by: Thomas Hartmann --- src/gui/kernel/qapplication_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index a0142e1..45e6645 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -835,7 +835,7 @@ void qt_init(QApplicationPrivate *priv, int) priv->SetGestureConfig = (PtrSetGestureConfig)QLibrary::resolve(QLatin1String("user32"), "SetGestureConfig"); - priv->SetGestureConfig = + priv->GetGestureConfig = (PtrGetGestureConfig)QLibrary::resolve(QLatin1String("user32"), "GetGestureConfig"); priv->BeginPanningFeedback = -- cgit v0.12 From 20050c010038ab10c29b68833b2054b87dd59a33 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 11 Aug 2009 09:28:27 +0200 Subject: Compile QtGui on Linux with no Gtk development package present. --- src/gui/image/qiconloader.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp index e6e3074..2204ac9 100644 --- a/src/gui/image/qiconloader.cpp +++ b/src/gui/image/qiconloader.cpp @@ -73,8 +73,12 @@ static QString systemThemeName() QString result; #ifdef Q_WS_X11 if (X11->desktopEnvironment == DE_GNOME) { +#if defined(QT_NO_STYLE_GTK) + result = QLatin1String("gnome"); +#else result = QGtk::getGConfString(QLatin1String("/desktop/gnome/interface/icon_theme"), QLatin1String("gnome")); +#endif } else if (X11->desktopEnvironment == DE_KDE) { QString kdeDefault = X11->desktopVersion >= 4 ? QString::fromLatin1("oxygen") : -- cgit v0.12 From 9ccaa95e7dbae96527b3ec502d4c604a4d691aec Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 11 Aug 2009 09:36:12 +0200 Subject: Tr-Fixes in Qt Designer. --- .../designer/src/components/propertyeditor/previewframe.cpp | 12 ++++++------ tools/designer/src/lib/shared/pluginmanager.cpp | 2 +- tools/designer/src/lib/shared/previewmanager.cpp | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/tools/designer/src/components/propertyeditor/previewframe.cpp b/tools/designer/src/components/propertyeditor/previewframe.cpp index 33073e2..913a476 100644 --- a/tools/designer/src/components/propertyeditor/previewframe.cpp +++ b/tools/designer/src/components/propertyeditor/previewframe.cpp @@ -42,15 +42,17 @@ #include "previewframe.h" #include "previewwidget.h" +#include +#include #include #include #include #include -#include QT_BEGIN_NAMESPACE -namespace { +namespace qdesigner_internal { + class PreviewMdiArea: public QMdiArea { public: PreviewMdiArea(QWidget *parent = 0) : QMdiArea(parent) {} @@ -65,13 +67,11 @@ namespace { QPainter p(paintWidget); p.fillRect(rect(), paintWidget->palette().color(backgroundRole()).dark()); p.setPen(QPen(Qt::white)); + //: Palette editor background p.drawText(0, height() / 2, width(), height(), Qt::AlignHCenter, - tr("The moose in the noose\nate the goose who was loose.")); + QCoreApplication::translate("qdesigner_internal::PreviewMdiArea", "The moose in the noose\nate the goose who was loose.")); return true; } -} - -namespace qdesigner_internal { PreviewFrame::PreviewFrame(QWidget *parent) : QFrame(parent), diff --git a/tools/designer/src/lib/shared/pluginmanager.cpp b/tools/designer/src/lib/shared/pluginmanager.cpp index b8c1c40..58d6c5c 100644 --- a/tools/designer/src/lib/shared/pluginmanager.cpp +++ b/tools/designer/src/lib/shared/pluginmanager.cpp @@ -331,7 +331,7 @@ static bool parsePropertySpecs(QXmlStreamReader &sr, const bool noTr = notrS == QLatin1String("true") || notrS == QLatin1String("1"); QDesignerCustomWidgetSharedData::StringPropertyType v(typeStringToType(type, &typeOk), !noTr); if (!typeOk) { - *errorMessage = QDesignerPluginManager::tr("'%1' is not a valid string property specification!").arg(type); + *errorMessage = QDesignerPluginManager::tr("'%1' is not a valid string property specification.").arg(type); return false; } rc->insert(name, v); diff --git a/tools/designer/src/lib/shared/previewmanager.cpp b/tools/designer/src/lib/shared/previewmanager.cpp index 890bfc1..81bf6fb 100644 --- a/tools/designer/src/lib/shared/previewmanager.cpp +++ b/tools/designer/src/lib/shared/previewmanager.cpp @@ -257,7 +257,9 @@ void PreviewDeviceSkin::slotPopupMenu() connect(directionGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotDirection(QAction*))); directionGroup->setExclusive(true); m_directionUpAction = createCheckableActionIntData(tr("&Portrait"), DirectionUp, m_direction, directionGroup, this); + //: Rotate form preview counter-clockwise m_directionLeftAction = createCheckableActionIntData(tr("Landscape (&CCW)"), DirectionLeft, m_direction, directionGroup, this); + //: Rotate form preview clockwise m_directionRightAction = createCheckableActionIntData(tr("&Landscape (CW)"), DirectionRight, m_direction, directionGroup, this); m_closeAction = new QAction(tr("&Close"), this); connect(m_closeAction, SIGNAL(triggered()), parentWidget(), SLOT(close())); -- cgit v0.12 From ec82f4fee841cc312a2d3517de36941ad8bee158 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 11 Aug 2009 09:36:49 +0200 Subject: Updated and purged German translation of Qt Designer. --- translations/designer_de.ts | 653 +++++++++++++++++++++++--------------------- 1 file changed, 336 insertions(+), 317 deletions(-) diff --git a/translations/designer_de.ts b/translations/designer_de.ts index 5109544..405e424 100644 --- a/translations/designer_de.ts +++ b/translations/designer_de.ts @@ -2,30 +2,6 @@ - - - - <object> - <Objekt> - - - - <signal> - <Signal> - - - - <slot> - <Slot> - - - - The moose in the noose -ate the goose who was loose. - - - - AbstractFindWidget @@ -202,34 +178,6 @@ ate the goose who was loose. - BrushManagerProxy - - - The element '%1' is missing the required attribute '%2'. - Bei dem Element fehlt das erforderliche Attribut '%2'. - - - - Empty brush name encountered. - Fehlender Name bei der Brush-Definition. - - - - An unexpected element '%1' was encountered. - Ein ungültiges Element '%1' wurde festgestellt. - - - - An error occurred when reading the brush definition file '%1' at line line %2, column %3: %4 - Fehler beim Lesen der Brush-Datei '%1' bei Zeile %2, Spalte %3: %4 - - - - An error occurred when reading the resource file '%1' at line %2, column %3: %4 - Fehler beim Lesen der Ressourcen-Datei '%1' bei Zeile %2, Spalte %3: %4 - - - BrushPropertyManager @@ -565,7 +513,7 @@ ate the goose who was loose. Werkzeugleiste löschen - + Set action text Text der Aktion setzen @@ -576,12 +524,12 @@ ate the goose who was loose. - + Move action Aktion verschieben - + Change Title Titel ändern @@ -626,7 +574,7 @@ ate the goose who was loose. Tabellarisches Layout vereinfachen - + Create button group Buttons gruppieren @@ -680,7 +628,7 @@ ate the goose who was loose. Skript ändern - + Changed '%1' of '%2' '%1' von '%2' geändert @@ -759,6 +707,24 @@ ate the goose who was loose. + ConnectionDelegate + + + <object> + <Objekt> + + + + <signal> + <Signal> + + + + <slot> + <Slot> + + + DPI_Chooser @@ -782,7 +748,7 @@ ate the goose who was loose. Designer - + Qt Designer Qt Designer @@ -807,17 +773,7 @@ ate the goose who was loose. Haben Sie ein Layout eingefügt? - - Invalid ui file: The root element <ui> is missing. - Fehler beim Lesen der ui-Datei: Das Wurzelelement <ui> fehlt. - - - - An error has occurred while reading the ui file at line %1, column %2: %3 - Fehler beim Lesen der ui-Datei bei Zeile %1, Spalte %2: %3 - - - + This file cannot be read because it was created using %1. Die Datei kann nicht gelesen werden, da sie mit %1 erzeugt wurde. @@ -827,17 +783,27 @@ ate the goose who was loose. Die Datei kann nicht gelesen werden, da sie mit dem Designer der Version %1 erzeugt wurde. - + This file cannot be read because the extra info extension failed to load. Die Datei kann nicht gelesen werden (Fehler beim Laden der Daten der ExtraInfoExtension). - + The converted file could not be read. Die konvertierte Datei konnte nicht gelesen werden. - + + Invalid UI file: The root element <ui> is missing. + Fehler beim Lesen der ui-Datei: Das Wurzelelement <ui> fehlt. + + + + An error has occurred while reading the UI file at line %1, column %2: %3 + Fehler beim Lesen der ui-Datei bei Zeile %1, Spalte %2: %3 + + + This file was created using Designer from Qt-%1 and will be converted to a new form by Qt Designer. Die Datei wurde mit dem Designer der Version %1 erzeugt und wird zu einem neuen Formular konvertiert. @@ -859,7 +825,7 @@ ate the goose who was loose. Bitte wandeln Sie sie mit dem Befehl <b>uic3&nbsp;-convert</b> zum Format von Qt 4. - + Custom Widgets Benutzerdefinierte Widgets @@ -993,7 +959,7 @@ ate the goose who was loose. EmbeddedOptionsControl - + <html><table><tr><td><b>Font</b></td><td>%1, %2</td></tr><tr><td><b>Style</b></td><td>%3</td></tr><tr><td><b>Resolution</b></td><td>%4 x %5</td></tr></table></html> Format embedded device profile description <html><table><tr><td><b>Font</b></td><td>%1, %2</td></tr><tr><td><b>Stil</b></td><td>%3</td></tr><tr><td><b>Auflösung</b></td><td>%4 x %5</td></tr></table></html> @@ -1068,7 +1034,7 @@ ate the goose who was loose. FormBuilder - + Invalid stretch value for '%1': '%2' Parsing layout stretch values Ungültiger Stretch-Wert für '%1': '%2' @@ -1150,7 +1116,7 @@ ate the goose who was loose. FormWindow - + Unexpected element <%1> Ungültiges Element <%1> @@ -1241,14 +1207,6 @@ ate the goose who was loose. - LanguageResourceDialog - - - Choose Resource - Ressource auswählen - - - MainWindowBase @@ -1336,17 +1294,9 @@ ate the goose who was loose. - NewFormWidget - - - Unable to open the form template file '%1': %2 - Die Formularvorlage %1 konnte nicht geöffnet werden: %2 - - - ObjectInspectorModel - + Object Objekt @@ -1369,7 +1319,7 @@ ate the goose who was loose. ObjectNameDialog - + Change Object Name Objektnamen bearbeiten @@ -1389,7 +1339,7 @@ ate the goose who was loose. 1 - 1 + 1 @@ -1403,21 +1353,6 @@ ate the goose who was loose. PreviewConfigurationWidget - - Default - Vorgabe - - - - None - Kein - - - - Browse... - Durchsuchen... - - Form Formular @@ -1451,7 +1386,7 @@ ate the goose who was loose. PromotionModel - + Not used Usage of promoted widgets Nicht verwendet @@ -1475,12 +1410,12 @@ ate the goose who was loose. - An error has occurred while reading the ui file at line %1, column %2: %3 + An error has occurred while reading the UI file at line %1, column %2: %3 Fehler beim Lesen der ui-Datei bei Zeile %1, Spalte %2: %3 - Invalid ui file: The root element <ui> is missing. + Invalid UI file: The root element <ui> is missing. Fehler beim Lesen der ui-Datei: Das Wurzelelement <ui> fehlt. @@ -1489,7 +1424,7 @@ ate the goose who was loose. Es konnte kein Widget der Klasse '%1' erzeugt werden. - + Attempt to add child that is not of class QWizardPage to QWizard. Es wurde versucht, einem Objekt der Klasse QWizard eine Seite hinzuzufügen, die nicht vom Typ QWizardPage ist. @@ -1505,7 +1440,7 @@ This indicates an inconsistency in the ui-file. Leeres Widget-Item in %1 '%2'. - + Flags property are not supported yet. Eigenschaften des Typs "Flag" werden nicht unterstützt. @@ -1676,22 +1611,17 @@ Script: %3 Einstellungen... - + Clear &Menu Menü &löschen - + CTRL+SHIFT+S CTRL+SHIFT+S - - CTRL+Q - CTRL+Q - - - + CTRL+R CTRL+R @@ -1745,7 +1675,7 @@ Script: %3 Designer-UI-Dateien (*.%1);;Alle Dateien (*) - + %1 already exists. Do you want to replace it? Die Datei %1 existiert bereits. @@ -1757,7 +1687,7 @@ Möchten Sie sie überschreiben? Das Formular %1 wurde gespeichert... - + &Recent Forms &Zuletzt bearbeitete Formulare @@ -1841,7 +1771,7 @@ Möchten Sie einen anderen Namen eingeben oder ein neues Formular erzeugen?Vorschau &schließen - + Save &Image... &Vorschaubild speichern... @@ -1856,7 +1786,7 @@ Möchten Sie einen anderen Namen eingeben oder ein neues Formular erzeugen?&Zusätzliche Schriftarten... - + The file %1 could not be opened. Reason: %2 Would you like to retry or select a different file? @@ -1890,7 +1820,7 @@ Möchten Sie es noch einmal versuchen? Die Datei %1 konnte nicht geschrieben werden. - + &New... &Neu... @@ -1921,17 +1851,17 @@ Möchten Sie es noch einmal versuchen? - + &Close &Schließen - + View &Code... &Code anzeigen... - + Save Form As Formular unter einem anderen Namen speichern @@ -1963,7 +1893,7 @@ Möchten Sie es noch einmal versuchen? %1 wurde gedruckt. - + ALT+CTRL+S ALT+CTRL+S @@ -2062,7 +1992,7 @@ Möchten Sie es noch einmal versuchen? QDesignerMenu - + Type Here Geben Sie Text ein @@ -2072,7 +2002,7 @@ Möchten Sie es noch einmal versuchen? Trenner hinzufügen - + Insert separator Trenner einfügen @@ -2088,12 +2018,12 @@ Möchten Sie es noch einmal versuchen? - + Add separator Trenner hinzufügen - + Insert action Aktion einfügen @@ -2101,12 +2031,12 @@ Möchten Sie es noch einmal versuchen? QDesignerMenuBar - + Type Here Geben Sie Text ein - + Remove Menu '%1' Menü '%1' öschen @@ -2124,12 +2054,27 @@ Möchten Sie es noch einmal versuchen? QDesignerPluginManager - + An XML error was encountered when parsing the XML of the custom widget %1: %2 Fehler beim Auswerten des XML des benutzerdefinierten Widgets %1: %2 - + + A required attribute ('%1') is missing. + Bei dem Element fehlt ein erforderliches Attribut ('%1'). + + + + An invalid property specification ('%1') was encountered. Supported types: %2 + '%1' ist keine gültige Spezifikation einer Eigenschaft. Die folgenden Typen werden unterstützt: %2 + + + + '%1' is not a valid string property specification. + '%1' ist keine gültige Spezifikation einer Zeichenketten-Eigenschaft. + + + The XML of the custom widget %1 does not contain any of the elements <widget> or <ui>. Der XML-Code für das Widget %1 enthält kein gültiges Wurzelelement (<widget>, <ui>). @@ -2155,12 +2100,12 @@ Möchten Sie es noch einmal versuchen? QDesignerResource - + The layout type '%1' is not supported, defaulting to grid. Der Layout-Typ '%1' wird nicht unterstützt; es wurde ein Grid-Layout erzeugt. - + The container extension of the widget '%1' (%2) returned a widget not managed by Designer '%3' (%4) when queried for page #%5. Container pages should only be added by specifying them in XML returned by the domXml() method of the custom widget. Die Container-Extension des Widgets '%1' (%2) gab für Seite %5 ein Widget '%3' (%4) zurück, was nicht von Designer verwaltet wird. @@ -2228,30 +2173,7 @@ Container-Seiten sollten ausschließlich im XML der domXML()-Methode spezifizier Widget Box - Widgetbox - - - - QDesignerWidgetBox - - - An error has been encountered at line %1 of %2: %3 - Fehler bei Zeile %1 von %2: %3 - - - - Unexpected element <%1> encountered when parsing for <widget> or <ui> - Es wurde ein Element <%1> gefunden; (anstatt <widget> or <ui>) - - - - Unexpected end of file encountered when parsing widgets. - Vorzeitiges Dateiende beim Lesen der Widget-Box-Konfiguration. - - - - A widget element could not be found. - Es fehlt das Widget-Element. + Widget-Box @@ -2292,12 +2214,12 @@ Container-Seiten sollten ausschließlich im XML der domXML()-Methode spezifizier Werkzeugleisten - + Save Forms? Formulare speichern? - + &View &Ansicht @@ -2307,7 +2229,12 @@ Container-Seiten sollten ausschließlich im XML der domXML()-Methode spezifizier &Einstellungen - + + Widget Box + Widgetbox + + + If you do not review your documents, all your changes will be lost. Die Änderungen gehen verloren, wenn Sie sich die Formulare nicht noch einmal ansehen. @@ -2338,7 +2265,7 @@ Container-Seiten sollten ausschließlich im XML der domXML()-Methode spezifizier - The file <b>%1</b> is not a valid Designer ui file. + The file <b>%1</b> is not a valid Designer UI file. Die Datei <b>%1</b> ist keine gültige Designer-Datei. @@ -2353,7 +2280,7 @@ Container-Seiten sollten ausschließlich im XML der domXML()-Methode spezifizier QFormBuilder - + An empty class name was passed on to %1 (object name: '%2'). Empty class name passed to widget factory method Der Methode %1 wurde ein leerer Klassennamen übergeben (Name '%2'). @@ -2369,7 +2296,7 @@ Container-Seiten sollten ausschließlich im XML der domXML()-Methode spezifizier QFormBuilder konnte kein Objekt der Klasse '%1' erzeugen. - + The layout type `%1' is not supported. Layouts des Typs `%1' werden nicht unterstützt. @@ -2393,16 +2320,6 @@ Container-Seiten sollten ausschließlich im XML der domXML()-Methode spezifizier The property %1 could not be written. The type %2 is not supported yet. Die Eigenschaft %1 konnte nicht geschrieben werden, da der Typ %2 nicht unterstützt wird. - - - The enumeration-value '%1' is invalid. The default value '%2' will be used instead. - Der Aufzählungswert '%1' ist ungültig. Der Vorgabewert '%2' wird verwendet. - - - - The flag-value '%1' is invalid. Zero will be used instead. - Der Maskenwert '%1' ist ungültig. Es wird 0 verwendet. - QStackedWidgetEventFilter @@ -2447,7 +2364,8 @@ Container-Seiten sollten ausschließlich im XML der domXML()-Methode spezifizier Seite %1 von %2 - + + Insert Page Seite einfügen @@ -2455,7 +2373,7 @@ Container-Seiten sollten ausschließlich im XML der domXML()-Methode spezifizier QStackedWidgetPreviewEventFilter - + Go to previous page of %1 '%2' (%3/%4). Gehe zur vorigen Seite von %1 '%2' (%3/%4). @@ -2488,7 +2406,8 @@ Container-Seiten sollten ausschließlich im XML der domXML()-Methode spezifizier Seite %1 von %2 - + + Insert Page Seite einfügen @@ -2759,7 +2678,7 @@ Container-Seiten sollten ausschließlich im XML der domXML()-Methode spezifizier QtGradientEditor - + Start X Anfangswert X @@ -2811,6 +2730,36 @@ Container-Seiten sollten ausschließlich im XML der domXML()-Methode spezifizier Winkel + + Linear + Linear + + + + Radial + Radial + + + + Conical + Konisch + + + + Pad + Auffüllen + + + + Repeat + Wiederholen + + + + Reflect + Spiegeln + + Form Form @@ -3087,31 +3036,31 @@ Container-Seiten sollten ausschließlich im XML der domXML()-Methode spezifizier Möchten Sie den ausgewählten Gradienten löschen? - + New... Neu... - - + + Edit... Ändern... - - + + Rename Umbenennen - - + + Remove Löschen - + Gradient View Gradientenanzeige @@ -3119,7 +3068,6 @@ Container-Seiten sollten ausschließlich im XML der domXML()-Methode spezifizier QtGradientViewDialog - Select Gradient Gradienten auswählen @@ -3545,24 +3493,24 @@ Dies kann zum Beispiel eine Sprachkennung wie "_de" sein. QtResourceView - + Size: %1 x %2 %3 Größe: %1 x %2 %3 - + Edit Resources... Ressourcen bearbeiten... - + Reload Neu laden - + Copy Path Pfad kopieren @@ -3570,7 +3518,7 @@ Dies kann zum Beispiel eine Sprachkennung wie "_de" sein. QtResourceViewDialog - + Select Resource Ressource auswählen @@ -3834,7 +3782,7 @@ Möchten Sie sie überschreiben? ScriptErrorDialog - + An error occurred while running the scripts for "%1": Bei der Ausführung der Skripte für "%1" sind Fehler aufgetreten: @@ -3978,8 +3926,8 @@ Möchten Sie sie überschreiben? - - %1<br/>%2<br/>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).<br/><br/>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.<br/> + + %1<br/>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).<br/><br/>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.<br/> @@ -3994,7 +3942,7 @@ Möchten Sie sie überschreiben? qdesigner_internal::ActionEditor - + Actions Aktionen @@ -4009,7 +3957,7 @@ Möchten Sie sie überschreiben? Löschen - + New action Neue Aktion @@ -4019,7 +3967,7 @@ Möchten Sie sie überschreiben? Aktion ändern - + Edit... Ändern... @@ -4049,7 +3997,7 @@ Möchten Sie sie überschreiben? Alles auswählen - + Icon View Icon-Ansicht @@ -4059,7 +4007,7 @@ Möchten Sie sie überschreiben? Detaillierte Ansicht - + Remove actions Aktionen löschen @@ -4074,7 +4022,7 @@ Möchten Sie sie überschreiben? Verwendet in - + Configure Action Editor Aktionseditor konfigurieren @@ -4113,9 +4061,37 @@ Möchten Sie sie überschreiben? + qdesigner_internal::BrushManagerProxy + + + The element '%1' is missing the required attribute '%2'. + Bei dem Element fehlt das erforderliche Attribut '%2'. + + + + Empty brush name encountered. + Fehlender Name bei der Brush-Definition. + + + + An unexpected element '%1' was encountered. + Ein ungültiges Element '%1' wurde festgestellt. + + + + An error occurred when reading the brush definition file '%1' at line line %2, column %3: %4 + Fehler beim Lesen der Brush-Datei '%1' bei Zeile %2, Spalte %3: %4 + + + + An error occurred when reading the resource file '%1' at line %2, column %3: %4 + Fehler beim Lesen der Ressourcen-Datei '%1' bei Zeile %2, Spalte %3: %4 + + + qdesigner_internal::BuddyEditor - + Add buddy Buddy hinzufügen @@ -4149,7 +4125,7 @@ Möchten Sie sie überschreiben? qdesigner_internal::BuddyEditorPlugin - + Edit Buddies Buddies bearbeiten @@ -4157,7 +4133,7 @@ Möchten Sie sie überschreiben? qdesigner_internal::BuddyEditorTool - + Edit Buddies Buddies bearbeiten @@ -4211,7 +4187,7 @@ Möchten Sie sie überschreiben? qdesigner_internal::CodeDialog - + Save... Speichern... @@ -4269,7 +4245,7 @@ Möchten Sie sie überschreiben? qdesigner_internal::ColorAction - + Text Color Schriftfarbe @@ -4277,7 +4253,7 @@ Möchten Sie sie überschreiben? qdesigner_internal::ComboBoxTaskMenu - + Edit Items... Einträge ändern... @@ -4369,7 +4345,7 @@ Möchten Sie sie überschreiben? qdesigner_internal::ContainerWidgetTaskMenu - + Insert Page Before Current Page Seite davor einfügen @@ -4432,7 +4408,7 @@ Möchten Sie sie überschreiben? qdesigner_internal::DesignerPropertyManager - + AlignLeft Linksbündig ausrichten @@ -4773,7 +4749,7 @@ Möchten Sie sie überschreiben? Fehler beim Einfügen - + Lay out Layout @@ -4784,7 +4760,7 @@ Möchten Sie sie überschreiben? Widget einfügen - + Paste %n action(s) Eine Aktion einfügen @@ -4820,7 +4796,7 @@ Möchten Sie sie überschreiben? Bitte lösen Sie das Layout des gewünschten Containers auf und wählen Sie ihn erneut aus, um die Widgets einzufügen. - + Select Ancestor Übergeordnetes Widget auswählen @@ -4830,7 +4806,7 @@ Möchten Sie sie überschreiben? Ein auf QMainWindow basierendes Formular enthält kein zentrales Widget. - + Raise widgets Widgets nach vorn bringen @@ -4843,7 +4819,7 @@ Möchten Sie sie überschreiben? qdesigner_internal::FormWindowBase - + Delete Löschen @@ -4856,7 +4832,7 @@ Möchten Sie sie überschreiben? qdesigner_internal::FormWindowManager - + Cu&t &Ausschneiden @@ -4958,7 +4934,7 @@ Möchten Sie sie überschreiben? Ordnet die ausgewählten Objekte senkrecht an - + Lay Out in a &Grid Objekte &tabellarisch anordnen @@ -5008,12 +4984,12 @@ Möchten Sie sie überschreiben? Vorschau des Formulars - + Form &Settings... Formular&einstellungen... - + Break Layout Layout auflösen @@ -5034,7 +5010,7 @@ Möchten Sie sie überschreiben? Formulareinstellungen - %1 - + Removes empty columns and rows Entfernt unbesetzte Zeilen und Spalten @@ -5108,7 +5084,7 @@ Möchten Sie sie überschreiben? qdesigner_internal::GroupBoxTaskMenu - + Change title... Titel ändern... @@ -5124,7 +5100,7 @@ Möchten Sie sie überschreiben? qdesigner_internal::IconSelector - + The pixmap file '%1' cannot be read. Die Pixmap-Datei '%1' kann nicht gelesen werden. @@ -5222,13 +5198,13 @@ Möchten Sie sie überschreiben? Eigenschaften &<< - + Properties &>> Eigenschaften &>> - + Items List Liste der Elemente @@ -5276,7 +5252,7 @@ Möchten Sie sie überschreiben? qdesigner_internal::LabelTaskMenu - + Change rich text... Formatierbaren Text ändern... @@ -5287,9 +5263,17 @@ Möchten Sie sie überschreiben? + qdesigner_internal::LanguageResourceDialog + + + Choose Resource + Ressource auswählen + + + qdesigner_internal::LineEditTaskMenu - + Change text... Text ändern... @@ -5297,7 +5281,7 @@ Möchten Sie sie überschreiben? qdesigner_internal::ListWidgetEditor - + Edit List Widget List-Widget ändern @@ -5315,7 +5299,7 @@ Möchten Sie sie überschreiben? qdesigner_internal::ListWidgetTaskMenu - + Edit Items... Elemente ändern... @@ -5351,7 +5335,7 @@ Möchten Sie sie überschreiben? qdesigner_internal::MenuTaskMenu - + Remove Löschen @@ -5451,7 +5435,7 @@ Please select another name. qdesigner_internal::NewFormWidget - + Default size Vorgabe @@ -5497,7 +5481,12 @@ Please select another name. Das Formular konnte nicht geladen werden - + + Unable to open the form template file '%1': %2 + Die Formularvorlage '%1' konnte nicht geöffnet werden: %2 + + + Internal error: No template selected. Interner Fehler: Es ist keine Vorlage selektiert. @@ -5530,7 +5519,7 @@ Please select another name. qdesigner_internal::NewPromotedClassPanel - + Add Hinzufügen @@ -5568,23 +5557,20 @@ Please select another name. qdesigner_internal::ObjectInspector - - &Find in Text... - &Suchen... - - - - qdesigner_internal::ObjectInspector::ObjectInspectorPrivate - - + Change Current Page Seite wechseln + + + &Find in Text... + &Suchen... + qdesigner_internal::OrderDialog - + Index %1 (%2) Position %1 (%2) @@ -5665,7 +5651,7 @@ Please select another name. qdesigner_internal::PaletteEditorButton - + Change Palette Palette ändern @@ -5673,7 +5659,7 @@ Please select another name. qdesigner_internal::PaletteModel - + Color Role Farbrolle @@ -5725,7 +5711,7 @@ Please select another name. qdesigner_internal::PlainTextEditorDialog - + Edit text Text bearbeiten @@ -5767,10 +5753,6 @@ Please select another name. New custom widget plugins have been found. Es wurden neuinstallierten Plugins mit benutzerdefinierten Widgets gefunden. - - 1 - 1 - qdesigner_internal::PreviewActionGroup @@ -5781,9 +5763,24 @@ Please select another name. - qdesigner_internal::PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate + qdesigner_internal::PreviewConfigurationWidget + + + Default + Vorgabe + + + + None + Kein + + + + Browse... + Durchsuchen... + - + Load Custom Device Skin Benutzerdefinierten Geräte-Skin laden @@ -5818,7 +5815,24 @@ Please select another name. qdesigner_internal::PreviewDeviceSkin - + + &Portrait + &Hochformat + + + + Landscape (&CCW) + Rotate form preview counter-clockwise + Querformat (&entgegen Uhrzeigersinn) + + + + &Landscape (CW) + Rotate form preview clockwise + Querformat (im &Uhrzeigersinn) + + + &Close &Schließen @@ -5826,12 +5840,22 @@ Please select another name. qdesigner_internal::PreviewManager - + %1 - [Preview] %1 - [Vorschau] + qdesigner_internal::PreviewMdiArea + + + The moose in the noose +ate the goose who was loose. + Palette editor background + + + + qdesigner_internal::PreviewWidget @@ -5943,7 +5967,7 @@ Please select another name. qdesigner_internal::PropertyEditor - + Add Dynamic Property... Dynamische Eigenschaft hinzufügen... @@ -6178,7 +6202,7 @@ Klasse: %2 qdesigner_internal::QDesignerWidgetBox - + Unexpected element <%1> Ungültiges Element <%1> @@ -6196,44 +6220,31 @@ Klasse: %2 %2 Der XML-Code für das Widget %1 enthält keine Widgets.%2 - - - qdesigner_internal::QtGradientEditor - - - Linear - Linear - - - - Radial - Radial - - - Conical - Konisch + + An error has been encountered at line %1 of %2: %3 + Fehler bei Zeile %1 von %2: %3 - - Pad - Auffüllen + + Unexpected element <%1> encountered when parsing for <widget> or <ui> + An Stelle des erwarteten <widget>- oder <ui>-Elementes wurde <%1> gefunden - - Repeat - Wiederholen + + Unexpected end of file encountered when parsing widgets. + Vorzeitiges Dateiende beim Lesen der Widget-Box-Konfiguration. - - Reflect - Spiegeln + + A widget element could not be found. + Es fehlt das Widget-Element. qdesigner_internal::QtGradientStopsController - + H H @@ -6408,7 +6419,7 @@ Klasse: %2 qdesigner_internal::ScriptDialog - + Edit script Skript bearbeiten @@ -6458,7 +6469,7 @@ Klasse: %2 qdesigner_internal::SignalSlotEditorPlugin - + Edit Signals/Slots Signale und Slots bearbeiten @@ -6471,7 +6482,7 @@ Klasse: %2 qdesigner_internal::SignalSlotEditorTool - + Edit Signals/Slots Signale und Slots bearbeiten @@ -6479,7 +6490,7 @@ Klasse: %2 qdesigner_internal::StatusBarTaskMenu - + Remove Löschen @@ -6487,7 +6498,7 @@ Klasse: %2 qdesigner_internal::StringListEditorButton - + Change String List Zeichenkettenliste ändern @@ -6495,7 +6506,7 @@ Klasse: %2 qdesigner_internal::StyleSheetEditorDialog - + Edit Style Sheet Stylesheet bearbeiten @@ -6562,7 +6573,7 @@ Klasse: %2 qdesigner_internal::TabOrderEditorPlugin - + Edit Tab Order Tabulatorreihenfolge bearbeiten @@ -6570,7 +6581,7 @@ Klasse: %2 qdesigner_internal::TabOrderEditorTool - + Edit Tab Order Tabulatorreihenfolge bearbeiten @@ -6578,7 +6589,7 @@ Klasse: %2 qdesigner_internal::TableWidgetEditor - + New Column Neue Spalte @@ -6603,13 +6614,13 @@ Klasse: %2 Eigenschaften &<< - + Properties &>> Eigenschaften &>> - + Edit Table Widget Table Widget ändern @@ -6627,7 +6638,7 @@ Klasse: %2 qdesigner_internal::TableWidgetTaskMenu - + Edit Items... Elemente ändern... @@ -6658,7 +6669,7 @@ Klasse: %2 qdesigner_internal::TextEditTaskMenu - + Change HTML... HTML ändern... @@ -6681,7 +6692,7 @@ Klasse: %2 qdesigner_internal::TextEditor - + Choose Resource... Ressource auswählen... @@ -6691,12 +6702,12 @@ Klasse: %2 Datei auswählen... - + Choose a File - + ... ... @@ -6704,7 +6715,7 @@ Klasse: %2 qdesigner_internal::ToolBarEventFilter - + Insert Separator Trenner einfügen @@ -6732,7 +6743,7 @@ Klasse: %2 qdesigner_internal::TreeWidgetEditor - + &Columns &Spalten @@ -6747,24 +6758,24 @@ Klasse: %2 Gemeinsame Eigenschaften - + New Item Neues Element - + Properties &<< Eigenschaften &<< - + Properties &>> Eigenschaften &>> - + New Column Neue Spalte @@ -6784,13 +6795,13 @@ Klasse: %2 Elemente + - New Subitem - + New &Subitem Neues &untergeordnetes Element @@ -6858,7 +6869,7 @@ Klasse: %2 qdesigner_internal::TreeWidgetTaskMenu - + Edit Items... Elemente ändern... @@ -6866,7 +6877,7 @@ Klasse: %2 qdesigner_internal::WidgetBox - + Warning: Widget creation failed in the widget box. This could be caused by invalid custom widget XML. Warnung: Die Erzeugung des Widgets in der Widget-Box schlug fehl. Das könnte durch fehlerhaften XML-Code benutzerdefinierter Widgets verursacht worden sein. @@ -6884,7 +6895,7 @@ Klasse: %2 Benutzerdefinierte Widgets - + Expand all Alles aufklappen @@ -6925,7 +6936,7 @@ Klasse: %2 qdesigner_internal::WidgetEditorTool - + Edit Widgets Widgets bearbeiten @@ -6933,7 +6944,7 @@ Klasse: %2 qdesigner_internal::WidgetFactory - + The custom widget factory registered for widgets of class %1 returned 0. Die Factory für benutzerdefinierte Widgets der Klasse %1 gab einen 0-Zeiger zurück. @@ -6986,4 +6997,12 @@ This indicates an inconsistency in the ui-file. %1 % + + qdesigner_internal::ZoomablePreviewDeviceSkin + + + &Zoom + &Vergrößern + + -- cgit v0.12 From dadb7b7ad36c43757d96b540b40cc3d81dca69d2 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 11 Aug 2009 11:36:48 +0200 Subject: QTableView with swapped headers PageUp/PageDown bug QTableView with header-swapped rows wouldn't scroll correctly when PageUp or PageDown pressed. Simplified calculation for next currentIndex provided in QTableView::moveCursor. Task-number: 259308 Reviewed-by: olivier --- src/gui/itemviews/qtableview.cpp | 17 ++++++++-------- tests/auto/qtableview/tst_qtableview.cpp | 33 ++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp index 2009499..8fc99a0 100644 --- a/src/gui/itemviews/qtableview.cpp +++ b/src/gui/itemviews/qtableview.cpp @@ -1197,17 +1197,16 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi visualRow = bottom; break; case MovePageUp: { - int top = 0; - while (top < bottom && d->isVisualRowHiddenOrDisabled(top, visualColumn)) - ++top; - int newRow = qMax(rowAt(visualRect(current).top() - d->viewport->height()), top); - return d->model->index(qBound(0, newRow, bottom), current.column(), d->root); + int newRow = rowAt(visualRect(current).top() - d->viewport->height()); + if (newRow == -1) + newRow = d->logicalRow(0); + return d->model->index(newRow, current.column(), d->root); } case MovePageDown: { - int newRow = qMin(rowAt(visualRect(current).bottom() + d->viewport->height()), bottom); - if (newRow < 0) - newRow = bottom; - return d->model->index(qBound(0, newRow, bottom), current.column(), d->root); + int newRow = rowAt(visualRect(current).bottom() + d->viewport->height()); + if (newRow == -1) + newRow = d->logicalRow(bottom); + return d->model->index(newRow, current.column(), d->root); }} int logicalRow = d->logicalRow(visualRow); diff --git a/tests/auto/qtableview/tst_qtableview.cpp b/tests/auto/qtableview/tst_qtableview.cpp index eb39dd7..597e24a 100644 --- a/tests/auto/qtableview/tst_qtableview.cpp +++ b/tests/auto/qtableview/tst_qtableview.cpp @@ -42,6 +42,7 @@ #include #include +#include "../../shared/util.h" //TESTED_CLASS= //TESTED_FILES= @@ -177,6 +178,7 @@ private slots: void task227953_setRootIndex(); void task240266_veryBigColumn(); void task248688_autoScrollNavigation(); + void task259308_scrollVerticalHeaderSwappedSections(); void mouseWheel_data(); void mouseWheel(); @@ -3253,6 +3255,37 @@ void tst_QTableView::addColumnWhileEditing() QCOMPARE(editor->geometry(), view.visualRect(last)); } +void tst_QTableView::task259308_scrollVerticalHeaderSwappedSections() +{ + QStandardItemModel model; + model.setRowCount(50); + model.setColumnCount(2); + for (int row = 0; row < model.rowCount(); ++row) + for (int col = 0; col < model.columnCount(); ++col) { + const QModelIndex &idx = model.index(row, col); + model.setData(idx, QVariant(row), Qt::EditRole); + } + + QTableView tv; + tv.setModel(&model); + tv.show(); + tv.verticalHeader()->swapSections(0, model.rowCount() - 1); + + QTest::qWait(60); + QTest::keyClick(&tv, Qt::Key_PageUp); // PageUp won't scroll when at top + QTRY_COMPARE(tv.rowAt(0), tv.verticalHeader()->logicalIndex(0)); + + int newRow = tv.rowAt(tv.viewport()->height()); + if (newRow == tv.rowAt(tv.viewport()->height() - 1)) // Overlapping row + newRow++; + QTest::keyClick(&tv, Qt::Key_PageDown); // Scroll down and check current + QTRY_COMPARE(tv.currentIndex().row(), newRow); + + tv.setCurrentIndex(model.index(0, 0)); + QTest::qWait(60); + QTest::keyClick(&tv, Qt::Key_PageDown); // PageDown won't scroll when at the bottom + QTRY_COMPARE(tv.rowAt(tv.viewport()->height() - 1), tv.verticalHeader()->logicalIndex(model.rowCount() - 1)); +} QTEST_MAIN(tst_QTableView) #include "tst_qtableview.moc" -- cgit v0.12 From 73b61029b00e12f313f9097d665539792d53e885 Mon Sep 17 00:00:00 2001 From: Morten Sorvig Date: Tue, 11 Aug 2009 13:13:11 +0200 Subject: Fix BC breakage caused by commit 7aa2d76d. Code compiled with 4.5 expects to find the QBenchmarkIterationController() constructor, so ad an overload instead of replacing it. --- src/testlib/qbenchmark.cpp | 7 +++++++ src/testlib/qbenchmark.h | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/testlib/qbenchmark.cpp b/src/testlib/qbenchmark.cpp index eaec02f..42ce662 100644 --- a/src/testlib/qbenchmark.cpp +++ b/src/testlib/qbenchmark.cpp @@ -197,6 +197,13 @@ QTest::QBenchmarkIterationController::QBenchmarkIterationController(RunMode runM if (runMode == RunOnce) QBenchmarkTestMethodData::current->runOnce = true; } + +QTest::QBenchmarkIterationController::QBenchmarkIterationController() +{ + QTest::beginBenchmarkMeasurement(); + i = 0; +} + /*! \internal */ QTest::QBenchmarkIterationController::~QBenchmarkIterationController() diff --git a/src/testlib/qbenchmark.h b/src/testlib/qbenchmark.h index 87d34e7..7b1792d 100644 --- a/src/testlib/qbenchmark.h +++ b/src/testlib/qbenchmark.h @@ -65,6 +65,7 @@ class Q_TESTLIB_EXPORT QBenchmarkIterationController { public: enum RunMode { RepeatUntilValidMeasurement, RunOnce }; + QBenchmarkIterationController(); QBenchmarkIterationController(RunMode runMode); ~QBenchmarkIterationController(); bool isDone(); @@ -75,7 +76,7 @@ public: } #define QBENCHMARK \ - for (QTest::QBenchmarkIterationController __iteration_controller(QTest::QBenchmarkIterationController::RepeatUntilValidMeasurement); \ + for (QTest::QBenchmarkIterationController __iteration_controller(); \ __iteration_controller.isDone() == false; __iteration_controller.next()) #define QBENCHMARK_ONCE \ -- cgit v0.12 From 72ce054c0f5ed1691ad4056f03e240b69a39e8c7 Mon Sep 17 00:00:00 2001 From: Morten Sorvig Date: Tue, 11 Aug 2009 13:16:45 +0200 Subject: Compile. --- src/testlib/qbenchmark.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testlib/qbenchmark.h b/src/testlib/qbenchmark.h index 7b1792d..a9f38de 100644 --- a/src/testlib/qbenchmark.h +++ b/src/testlib/qbenchmark.h @@ -76,7 +76,7 @@ public: } #define QBENCHMARK \ - for (QTest::QBenchmarkIterationController __iteration_controller(); \ + for (QTest::QBenchmarkIterationController __iteration_controller; \ __iteration_controller.isDone() == false; __iteration_controller.next()) #define QBENCHMARK_ONCE \ -- cgit v0.12 From 507c0ff17beeddfd281a4e978c2612031ce49154 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 11 Aug 2009 13:16:51 +0200 Subject: Phonon: improve locking to make it safer to load a source Task-number: 259482 --- src/3rdparty/phonon/ds9/mediaobject.cpp | 32 ++++++++++++++++++++------------ src/3rdparty/phonon/ds9/mediaobject.h | 3 ++- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/3rdparty/phonon/ds9/mediaobject.cpp b/src/3rdparty/phonon/ds9/mediaobject.cpp index b163ad4..a4feef6 100644 --- a/src/3rdparty/phonon/ds9/mediaobject.cpp +++ b/src/3rdparty/phonon/ds9/mediaobject.cpp @@ -192,8 +192,11 @@ namespace Phonon HRESULT hr = S_OK; - m_currentRender = w.graph; - m_currentRenderId = w.id; + { + QMutexLocker locker(&m_currentMutex); + m_currentRender = w.graph; + m_currentRenderId = w.id; + } if (w.task == ReplaceGraph) { int index = -1; for(int i = 0; i < FILTER_COUNT; ++i) { @@ -217,9 +220,6 @@ namespace Phonon m_graphHandle[index].handle = h; } } else if (w.task == Render) { - //we need to unlock here because the use might trigger a call to abort - //which uses the same mutex - locker.unlock(); if (w.filter) { //let's render pins w.graph->AddFilter(w.filter, 0); @@ -238,7 +238,6 @@ namespace Phonon if (hr != E_ABORT) { emit asyncRenderFinished(w.id, hr, w.graph); } - locker.relock(); } else if (w.task == Seek) { //that's a seekrequest ComPointer mediaSeeking(w.graph, IID_IMediaSeeking); @@ -311,12 +310,22 @@ namespace Phonon } } - m_currentRender = Graph(); - m_currentRenderId = 0; + { + QMutexLocker locker(&m_currentMutex); + m_currentRender = Graph(); + m_currentRenderId = 0; + } } void WorkerThread::abortCurrentRender(qint16 renderId) { + { + QMutexLocker locker(&m_currentMutex); + if (m_currentRender && m_currentRenderId == renderId) { + m_currentRender->Abort(); + } + } + QMutexLocker locker(&m_mutex); bool found = false; for(int i = 0; !found && i < m_queue.size(); ++i) { @@ -324,12 +333,11 @@ namespace Phonon if (w.id == renderId) { found = true; m_queue.removeAt(i); + if (m_queue.isEmpty()) { + m_waitCondition.reset(); + } } } - - if (m_currentRender && m_currentRenderId == renderId) { - m_currentRender->Abort(); - } } //tells the thread to stop processing diff --git a/src/3rdparty/phonon/ds9/mediaobject.h b/src/3rdparty/phonon/ds9/mediaobject.h index fe52604..a6beb5f 100644 --- a/src/3rdparty/phonon/ds9/mediaobject.h +++ b/src/3rdparty/phonon/ds9/mediaobject.h @@ -143,7 +143,8 @@ namespace Phonon bool m_finished; quint16 m_currentWorkId; QWinWaitCondition m_waitCondition; - QMutex m_mutex; + QMutex m_mutex; // mutex for the m_queue, m_finished and m_currentWorkId + QMutex m_currentMutex; //mutex for current renderer and id //this is for WaitForMultipleObjects struct -- cgit v0.12 From 19059f306d1d8154bb330b7c428982baf6a964ec Mon Sep 17 00:00:00 2001 From: Morten Sorvig Date: Tue, 11 Aug 2009 13:20:17 +0200 Subject: Perform the variable initalizations _before_ starting the clock. Removes a few of cycles erronously included in the results. --- src/testlib/qbenchmark.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/testlib/qbenchmark.cpp b/src/testlib/qbenchmark.cpp index 42ce662..8a2cc44 100644 --- a/src/testlib/qbenchmark.cpp +++ b/src/testlib/qbenchmark.cpp @@ -192,16 +192,16 @@ void QBenchmarkTestMethodData::setResult(qint64 value) */ QTest::QBenchmarkIterationController::QBenchmarkIterationController(RunMode runMode) { - QTest::beginBenchmarkMeasurement(); i = 0; if (runMode == RunOnce) QBenchmarkTestMethodData::current->runOnce = true; + QTest::beginBenchmarkMeasurement(); } QTest::QBenchmarkIterationController::QBenchmarkIterationController() { - QTest::beginBenchmarkMeasurement(); i = 0; + QTest::beginBenchmarkMeasurement(); } /*! \internal -- cgit v0.12 From 78f64021650372f177a62d1b46e5cd33dc3a3250 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 11 Aug 2009 13:57:28 +0200 Subject: Phonon: Video widget on Windows flickers when going to next video Now we just disable the updates during a short amount of time. This should give enough time to the video to start. Task-number: 251776 --- src/3rdparty/phonon/ds9/videowidget.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/3rdparty/phonon/ds9/videowidget.cpp b/src/3rdparty/phonon/ds9/videowidget.cpp index 34ff8cb..07b9cf3 100644 --- a/src/3rdparty/phonon/ds9/videowidget.cpp +++ b/src/3rdparty/phonon/ds9/videowidget.cpp @@ -84,7 +84,19 @@ namespace Phonon void setCurrentRenderer(AbstractVideoRenderer *renderer) { m_currentRenderer = renderer; - update(); + //we disallow repaint on that widget for just a fraction of second + //this allows better transition between videos + setUpdatesEnabled(false); + m_flickerFreeTimer.start(20, this); + } + + void timerEvent(QTimerEvent *e) + { + if (e->timerId() == m_flickerFreeTimer.timerId()) { + m_flickerFreeTimer.stop(); + setUpdatesEnabled(true); + } + QWidget::timerEvent(e); } QSize sizeHint() const @@ -160,6 +172,7 @@ namespace Phonon VideoWidget *m_node; AbstractVideoRenderer *m_currentRenderer; QVariant m_restoreScreenSaverActive; + QBasicTimer m_flickerFreeTimer; }; VideoWidget::VideoWidget(QWidget *parent) -- cgit v0.12 From c1c4f55b099f38cb5b50c24378d74acf91ef964a Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Tue, 11 Aug 2009 14:14:23 +0200 Subject: Doc - Some documentation fixes for Model View documentation together with some clarification (Task 229722) on what is a current item, what are selected items, etc. Task: 229722 Reviewed-By: TrustMe --- doc/src/model-view-programming.qdoc | 220 +++++++++++++++++++++--------------- 1 file changed, 126 insertions(+), 94 deletions(-) diff --git a/doc/src/model-view-programming.qdoc b/doc/src/model-view-programming.qdoc index 7d7db19..0c7ea2f 100644 --- a/doc/src/model-view-programming.qdoc +++ b/doc/src/model-view-programming.qdoc @@ -373,13 +373,12 @@ In the model/view architecture, the model provides a standard interface that views and delegates use to access data. In Qt, the standard - interface is defined by the QAbstractItemModel class. No matter how - the items of data are stored in any underlying data structure, all - subclasses of QAbstractItemModel represent the data as a hierarchical - structure containing tables of items. - Views use this \e convention to access items of data in the model, but - they are not restricted in the way that they present this information - to the user. + interface is defined by the QAbstractItemModel class. No matter how the + items of data are stored in any underlying data structure, all subclasses + of QAbstractItemModel represent the data as a hierarchical structure + containing tables of items. Views use this \e convention to access items + of data in the model, but they are not restricted in the way that they + present this information to the user. \image modelview-models.png @@ -393,27 +392,26 @@ \section2 Model Indexes To ensure that the representation of the data is kept separate from the - way it is accessed, the concept of a \e{model index} is introduced. - Each piece of information that can be obtained via a model is - represented by a model index. Views and delegates use these indexes to - request items of data to display. + way it is accessed, the concept of a \e{model index} is introduced. Each + piece of information that can be obtained via a model is represented by + a model index. Views and delegates use these indexes to request items of + data to display. - As a result, only the model needs to know how to obtain data, and the - type of data managed by the model can be defined fairly generally. - Model indexes contain a pointer to the model that created them, and - this prevents confusion when working with more than one model. + As a result, only the model needs to know how to obtain data, and the type + of data managed by the model can be defined fairly generally. Model indexes + contain a pointer to the model that created them, and this prevents + confusion when working with more than one model. \snippet doc/src/snippets/code/doc_src_model-view-programming.qdoc 0 - Model indexes provide \e temporary references to pieces of information, - and can be used to retrieve or modify data via the model. Since models - may reorganize their internal structures from time to time, model - indexes may become invalid, and \e{should not be stored}. If a - long-term reference to a piece of information is required, a - \e{persistent model index} must be created. This provides a reference - to the information that the model keeps up-to-date. - Temporary model indexes are provided by the QModelIndex class, and - persistent model indexes are provided by the QPersistentModelIndex + Model indexes provide \e temporary references to pieces of information, and + can be used to retrieve or modify data via the model. Since models may + reorganize their internal structures from time to time, model indexes may + become invalid, and \e{should not be stored}. If a long-term reference to a + piece of information is required, a \e{persistent model index} must be + created. This provides a reference to the information that the model keeps + up-to-date. Temporary model indexes are provided by the QModelIndex class, + and persistent model indexes are provided by the QPersistentModelIndex class. To obtain a model index that corresponds to an item of data, three @@ -423,30 +421,29 @@ \section2 Rows and Columns - In its most basic form, a model can be accessed as a simple table - in which items are located by their row and column numbers. \e{This does - not mean that the underlying pieces of data are stored in an array - structure}; the use of row and column numbers is only a convention to - allow components to communicate with each other. - We can retrieve information about any given item by specifying its row - and column numbers to the model, and we receive an index that - represents the item: + In its most basic form, a model can be accessed as a simple table in which + items are located by their row and column numbers. \e{This does not mean + that the underlying pieces of data are stored in an array structure}; the + use of row and column numbers is only a convention to allow components to + communicate with each other. We can retrieve information about any given + item by specifying its row and column numbers to the model, and we receive + an index that represents the item: \snippet doc/src/snippets/code/doc_src_model-view-programming.qdoc 1 - Models that provide interfaces to simple, single level data structures - like lists and tables do not need any other information to be provided - but, as the above code indicates, we need to supply more information - when obtaining a model index. + Models that provide interfaces to simple, single level data structures like + lists and tables do not need any other information to be provided but, as + the above code indicates, we need to supply more information when obtaining + a model index. \table \row \i \inlineimage modelview-tablemodel.png \i \bold{Rows and columns} The diagram shows a representation of a basic table model in which each - item is located by a pair of row and column numbers. - By passing the relevant row and column numbers to the model we - obtain a model index that refers to an item of data. + item is located by a pair of row and column numbers. We obtain a model + index that refers to an item of data by passing the relevant row and + column numbers to the model. \snippet doc/src/snippets/code/doc_src_model-view-programming.qdoc 2 @@ -458,17 +455,16 @@ \section2 Parents of Items The table-like interface to item data provided by models is ideal when - using data in a table or list view; the row and column number system - maps exactly to the way the views display items. - However, structures such as tree views require the model to expose a more - flexible interface to the items within. As a result, each item can also be - the parent of another table of items, in much the same way that a top-level - item in a tree view can contain another list of items. - - When requesting an index for a model item, we must provide some - information about the item's parent. Outside the model, the only way to - refer to an item is through a model index, so a parent model index must - also be given: + using data in a table or list view; the row and column number system maps + exactly to the way the views display items. However, structures such as + tree views require the model to expose a more flexible interface to the + items within. As a result, each item can also be the parent of another + table of items, in much the same way that a top-level item in a tree view + can contain another list of items. + + When requesting an index for a model item, we must provide some information + about the item's parent. Outside the model, the only way to refer to an + item is through a model index, so a parent model index must also be given: \snippet doc/src/snippets/code/doc_src_model-view-programming.qdoc 3 @@ -476,14 +472,16 @@ \row \i \inlineimage modelview-treemodel.png \i \bold{Parents, rows, and columns} - The diagram shows a representation of a tree model in which each item - is referred to by a parent, a row number, and a column number. + The diagram shows a representation of a tree model in which each item is + referred to by a parent, a row number, and a column number. Items "A" and "C" are represented as top-level siblings in the model: + \snippet doc/src/snippets/code/doc_src_model-view-programming.qdoc 4 Item "A" has a number of children. A model index for item "B" is obtained with the following code: + \snippet doc/src/snippets/code/doc_src_model-view-programming.qdoc 5 \endtable @@ -492,9 +490,8 @@ Items in a model can perform various \e roles for other components, allowing different kinds of data to be supplied for different situations. For example, Qt::DisplayRole is used to access a string that can be - displayed as text in a view. - Typically, items contain data for a number of different roles, and the - standard roles are defined by Qt::ItemDataRole. + displayed as text in a view. Typically, items contain data for a number of + different roles, and the standard roles are defined by Qt::ItemDataRole. We can ask the model for the item's data by passing it the model index corresponding to the item, and by specifying a role to obtain the type @@ -510,13 +507,13 @@ Views can display the roles in different ways, so it is important to supply appropriate information for each role. - The \l{Creating New Models} section covers some specific uses of roles - in more detail. + The \l{Creating New Models} section covers some specific uses of roles in + more detail. \endtable - Most common uses for item data are covered by the standard roles defined - in Qt::ItemDataRole. By supplying appropriate item data for each role, - models can provide hints to views and delegates about how items should be + Most common uses for item data are covered by the standard roles defined in + Qt::ItemDataRole. By supplying appropriate item data for each role, models + can provide hints to views and delegates about how items should be presented to the user. Different kinds of views have the freedom to interpret or ignore this information as required. It is also possible to define additional roles for application-specific purposes. @@ -983,42 +980,77 @@ \section1 Concepts - The selection model used in the new item view classes offers many - improvements over the selection model used in Qt 3. It provides a - more general description of selections based on the facilities of - the model/view architecture. Although the standard classes for - manipulating selections are sufficient for the item views provided, - the selection model allows you to create specialized selection models - to suit the requirements for your own item models and views. - - Information about the items selected in a view is stored in an instance - of the \l QItemSelectionModel class. This maintains model indexes for - items in a single model, and is independent of any views. Since there - can be many views onto a model, it is possible to share selections - between views, allowing applications to show multiple views in a - consistent way. - - Selections are made up of \e{selection ranges}. These efficiently - maintain information about large selections of items by recording - only the starting and ending model indexes for each range of selected - items. Non-contiguous selections of items are constructed by using - more than one selection range to describe the selection. - - Selections are applied to a collection of model indexes held by - a selection model. The most recent selection of items applied is - known as the \e{current selection}. The effects of this selection can - be modified even after its application through the use of certain - types of selection commands. These are discussed later in this - section. + The selection model used in the item view classes offers many improvements + over the selection model used in Qt 3. It provides a more general + description of selections based on the facilities of the model/view + architecture. Although the standard classes for manipulating selections are + sufficient for the item views provided, the selection model allows you to + create specialized selection models to suit the requirements for your own + item models and views. + + Information about the items selected in a view is stored in an instance of + the \l QItemSelectionModel class. This maintains model indexes for items in + a single model, and is independent of any views. Since there can be many + views onto a model, it is possible to share selections between views, + allowing applications to show multiple views in a consistent way. + + Selections are made up of \e{selection ranges}. These efficiently maintain + information about large selections of items by recording only the starting + and ending model indexes for each range of selected items. Non-contiguous + selections of items are constructed by using more than one selection range + to describe the selection. + + Selections are applied to a collection of model indexes held by a selection + model. The most recent selection of items applied is known as the + \e{current selection}. The effects of this selection can be modified even + after its application through the use of certain types of selection + commands. These are discussed later in this section. + + + \section2 Current Item and Selected Items + + In a view, there is always a current item and a selected item - two + independent states. An item can be the current item and selected at the + same time. The view is responsible for ensuring that there is always a + current item as keyboard navigation, for example, requires a current item. + + The table below highlights the differences between current item and + selected items. + + \table + \header + \o Current Item + \o Selected Items + + \row + \o There can only be one current item. + \o There can be multiple selected items. + \row + \o The current item will be changed with key navigation or mouse + button clicks. + \o The selected state of items is set or unset, depending on several + pre-defined modes - e.g., single selection, multiple selection, + etc. - when the user interacts with the items. + \row + \o The current item will be edited if the edit key, \gui F2, is + pressed or the item is double-clicked (provided that editing is + enabled). + \o The current item can be used together with an anchor to specify a + range that should be selected or deselected (or a combination of + the two). + \row + \o The current item is indicated by the focus rectangle. + \o The selected items are indicated with the selection rectangle. + \endtable When manipulating selections, it is often helpful to think of - \l QItemSelectionModel as a record of the selection state of all the - items in an item model. Once a selection model is set up, collections - of items can be selected, deselected, or their selection states can - be toggled without the need to know which items are already selected. - The indexes of all selected items can be retrieved at any time, and - other components can be informed of changes to the selection model - via the signals and slots mechanism. + \l QItemSelectionModel as a record of the selection state of all the items + in an item model. Once a selection model is set up, collections of items + can be selected, deselected, or their selection states can be toggled + without the need to know which items are already selected. The indexes of + all selected items can be retrieved at any time, and other components can + be informed of changes to the selection model via the signals and slots + mechanism. \section1 Using a Selection Model -- cgit v0.12 From 50f6168a7e0f76124830d63981bb1b8c2fa67f8c Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Tue, 11 Aug 2009 14:17:02 +0200 Subject: Remove trailing whitespace Reviewed-By: TrustMe --- doc/src/model-view-programming.qdoc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/doc/src/model-view-programming.qdoc b/doc/src/model-view-programming.qdoc index 0c7ea2f..2a077da 100644 --- a/doc/src/model-view-programming.qdoc +++ b/doc/src/model-view-programming.qdoc @@ -1015,7 +1015,7 @@ current item as keyboard navigation, for example, requires a current item. The table below highlights the differences between current item and - selected items. + selected items. \table \header @@ -1432,7 +1432,7 @@ \snippet doc/src/snippets/stringlistmodel/model.h 3 \section2 Making the Model Editable - + A delegate checks whether an item is editable before creating an editor. The model must let the delegate know that its items are editable. We do this by returning the correct flags for each item in @@ -1468,7 +1468,7 @@ is limited to just one model index. Also the data() function needs to be changed to add the Qt::EditRole test: - + \snippet doc/src/snippets/stringlistmodel/model.cpp 1 \section2 Inserting and Removing Rows @@ -2481,4 +2481,3 @@ {fetchMore()} must be reimplemented as their default implementation returns false and does nothing. */ - -- cgit v0.12 From 1056df7f11e4c7964a72e89d02bd3016ccd2c9f1 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Tue, 11 Aug 2009 13:10:03 +0200 Subject: Add support for hooking BeginPaint/EndPaint on 64Bit Windows Webkit uses the runtime patching trick explained by "Feng Yuan" for hooking these paint functions. It currently supports only 32bit assembly code. This patch adds support for 64Bit version. Since inline-assemblies are not supported for 64Bit, we have use a seperate .asm file. Reviewed-by: Simon Hausmann Reviewed-by: Thiago Macieira --- src/3rdparty/webkit/WebCore/WebCore.pro | 17 ++++++++ .../webkit/WebCore/plugins/win/PaintHooks.asm | 50 ++++++++++++++++++++++ .../webkit/WebCore/plugins/win/PluginViewWin.cpp | 46 +++++++++++++++++++- 3 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 src/3rdparty/webkit/WebCore/plugins/win/PaintHooks.asm diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro index 2eb7c08..68da1d6 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pro +++ b/src/3rdparty/webkit/WebCore/WebCore.pro @@ -3218,3 +3218,20 @@ CONFIG(QTDIR_build):isEqual(QT_MAJOR_VERSION, 4):greaterThan(QT_MINOR_VERSION, 4 CONFIG += no_debug_info } +!win32-g++:win32:contains(QMAKE_HOST.arch, x86_64):{ + asm_compiler.commands = ml64 /c + asm_compiler.commands += /Fo ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} + asm_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)} + asm_compiler.input = ASM_SOURCES + asm_compiler.variable_out = OBJECTS + asm_compiler.name = compiling[asm] ${QMAKE_FILE_IN} + silent:asm_compiler.commands = @echo compiling[asm] ${QMAKE_FILE_IN} && $$asm_compiler.commands + QMAKE_EXTRA_COMPILERS += asm_compiler + + ASM_SOURCES += \ + plugins/win/PaintHooks.asm + if(win32-msvc2005|win32-msvc2008):equals(TEMPLATE_PREFIX, "vc") { + SOURCES += \ + plugins/win/PaintHooks.asm + } +} diff --git a/src/3rdparty/webkit/WebCore/plugins/win/PaintHooks.asm b/src/3rdparty/webkit/WebCore/plugins/win/PaintHooks.asm new file mode 100644 index 0000000..9128663 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/plugins/win/PaintHooks.asm @@ -0,0 +1,50 @@ +;/* +; Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) +; +; This library is free software; you can redistribute it and/or +; modify it under the terms of the GNU Library General Public +; License as published by the Free Software Foundation; either +; version 2 of the License, or (at your option) any later version. +; +; This library is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; Library General Public License for more details. +; +; You should have received a copy of the GNU Library General Public License +; along with this library; see the file COPYING.LIB. If not, write to +; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +; Boston, MA 02110-1301, USA. +;*/ + +;HDC __stdcall _HBeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint); + +PUBLIC _HBeginPaint + +_TEXT SEGMENT + +_HBeginPaint PROC + mov r10,rcx + mov eax,1017h + syscall + ret +_HBeginPaint ENDP + +_TEXT ENDS + +;BOOL __stdcall _HEndPaint(HWND hWnd, const PAINTSTRUCT* lpPaint); + +PUBLIC _HEndPaint + +_TEXT SEGMENT + +_HEndPaint PROC + mov r10,rcx + mov eax,1019h + syscall + ret +_HEndPaint ENDP + +_TEXT ENDS + +END diff --git a/src/3rdparty/webkit/WebCore/plugins/win/PluginViewWin.cpp b/src/3rdparty/webkit/WebCore/plugins/win/PluginViewWin.cpp index c97984d..4fc03dc 100644 --- a/src/3rdparty/webkit/WebCore/plugins/win/PluginViewWin.cpp +++ b/src/3rdparty/webkit/WebCore/plugins/win/PluginViewWin.cpp @@ -117,6 +117,14 @@ static BYTE* beginPaint; static unsigned endPaintSysCall; static BYTE* endPaint; +typedef HDC (WINAPI *PtrBeginPaint)(HWND, PAINTSTRUCT*); +typedef BOOL (WINAPI *PtrEndPaint)(HWND, const PAINTSTRUCT*); + +#if PLATFORM(WIN_OS) && PLATFORM(X86_64) && COMPILER(MSVC) +extern "C" HDC __stdcall _HBeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint); +extern "C" BOOL __stdcall _HEndPaint(HWND hWnd, const PAINTSTRUCT* lpPaint); +#endif + HDC WINAPI PluginView::hookedBeginPaint(HWND hWnd, PAINTSTRUCT* lpPaint) { PluginView* pluginView = reinterpret_cast(GetProp(hWnd, kWebPluginViewProperty)); @@ -139,12 +147,14 @@ HDC WINAPI PluginView::hookedBeginPaint(HWND hWnd, PAINTSTRUCT* lpPaint) : "memory" ); return result; -#else +#elif defined(_M_IX86) // Call through to the original BeginPaint. __asm mov eax, beginPaintSysCall __asm push lpPaint __asm push hWnd __asm call beginPaint +#else + return _HBeginPaint(hWnd, lpPaint); #endif } @@ -166,12 +176,14 @@ BOOL WINAPI PluginView::hookedEndPaint(HWND hWnd, const PAINTSTRUCT* lpPaint) : "a" (endPaintSysCall), "g" (lpPaint), "g" (hWnd), "m" (*endPaint) ); return result; -#else +#elif defined (_M_IX86) // Call through to the original EndPaint. __asm mov eax, endPaintSysCall __asm push lpPaint __asm push hWnd __asm call endPaint +#else + return _HEndPaint(hWnd, lpPaint); #endif } @@ -184,6 +196,7 @@ static void hook(const char* module, const char* proc, unsigned& sysCallID, BYTE pProc = reinterpret_cast(reinterpret_cast(GetProcAddress(hMod, proc))); +#if COMPILER(GCC) || defined(_M_IX86) if (pProc[0] != 0xB8) return; @@ -199,6 +212,35 @@ static void hook(const char* module, const char* proc, unsigned& sysCallID, BYTE *reinterpret_cast(pProc + 1) = reinterpret_cast(pNewProc) - reinterpret_cast(pProc + 5); pProc += 5; +#else + /* Disassembly of BeginPaint() + 00000000779FC5B0 4C 8B D1 mov r10,rcx + 00000000779FC5B3 B8 17 10 00 00 mov eax,1017h + 00000000779FC5B8 0F 05 syscall + 00000000779FC5BA C3 ret + 00000000779FC5BB 90 nop + 00000000779FC5BC 90 nop + 00000000779FC5BD 90 nop + 00000000779FC5BE 90 nop + 00000000779FC5BF 90 nop + 00000000779FC5C0 90 nop + 00000000779FC5C1 90 nop + 00000000779FC5C2 90 nop + 00000000779FC5C3 90 nop + */ + // Check for the signature as in the above disassembly + DWORD guard = 0xB8D18B4C; + if (*reinterpret_cast(pProc) != guard) + return; + + DWORD flOldProtect; + VirtualProtect(pProc, 12, PAGE_EXECUTE_READWRITE, & flOldProtect); + pProc[0] = 0x48; // mov rax, this + pProc[1] = 0xb8; + *(__int64*)(pProc+2) = (__int64)pNewProc; + pProc[10] = 0xff; // jmp rax + pProc[11] = 0xe0; +#endif } static void setUpOffscreenPaintingHooks(HDC (WINAPI*hookedBeginPaint)(HWND, PAINTSTRUCT*), BOOL (WINAPI*hookedEndPaint)(HWND, const PAINTSTRUCT*)) -- cgit v0.12 From 1c4a75de75157f0ffa0a75d8c5f177bf45119c50 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Tue, 11 Aug 2009 13:20:16 +0200 Subject: Fix compile error on 64Bit Added new overload with int64 parameter. Reviewed-by: Simon Hausmann --- .../webkit/JavaScriptCore/runtime/UString.cpp | 31 ++++++++++++++++++++++ .../webkit/JavaScriptCore/runtime/UString.h | 3 +++ 2 files changed, 34 insertions(+) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/UString.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/UString.cpp index 118751e..f64219c 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/UString.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/UString.cpp @@ -942,6 +942,37 @@ UString UString::from(int i) return UString(p, static_cast(end - p)); } +#if PLATFORM(WIN_OS) && PLATFORM(X86_64) && COMPILER(MSVC) +UString UString::from(int64_t i) +{ + UChar buf[1 + sizeof(i) * 3]; + UChar* end = buf + sizeof(buf) / sizeof(UChar); + UChar* p = end; + + if (i == 0) + *--p = '0'; + else if (i == LLONG_MIN) { + char minBuf[1 + sizeof(i) * 3]; + snprintf(minBuf, sizeof(minBuf) - 1, "%I64d", LLONG_MIN); + return UString(minBuf); + } else { + bool negative = false; + if (i < 0) { + negative = true; + i = -i; + } + while (i) { + *--p = static_cast((i % 10) + '0'); + i /= 10; + } + if (negative) + *--p = '-'; + } + + return UString(p, static_cast(end - p)); +} +#endif + UString UString::from(unsigned int u) { UChar buf[sizeof(u) * 3]; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/UString.h b/src/3rdparty/webkit/JavaScriptCore/runtime/UString.h index d01b75d..f2572a9 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/UString.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/UString.h @@ -256,6 +256,9 @@ namespace JSC { } static UString from(int); +#if PLATFORM(WIN_OS) && PLATFORM(X86_64) && COMPILER(MSVC) + static UString from(int64_t i); +#endif static UString from(unsigned int); static UString from(long); static UString from(double); -- cgit v0.12 From 0d3a88ae2f4f4c9b356ee093ba6d166b92256a56 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Tue, 11 Aug 2009 14:15:49 +0200 Subject: Fix Whitespace errors Reviewed-by: Trust Me --- .../webkit/WebCore/plugins/win/PaintHooks.asm | 30 +++++++++++----------- .../webkit/WebCore/plugins/win/PluginViewWin.cpp | 28 ++++++++++---------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/3rdparty/webkit/WebCore/plugins/win/PaintHooks.asm b/src/3rdparty/webkit/WebCore/plugins/win/PaintHooks.asm index 9128663..1508813 100644 --- a/src/3rdparty/webkit/WebCore/plugins/win/PaintHooks.asm +++ b/src/3rdparty/webkit/WebCore/plugins/win/PaintHooks.asm @@ -16,35 +16,35 @@ ; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ; Boston, MA 02110-1301, USA. ;*/ - + ;HDC __stdcall _HBeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint); -PUBLIC _HBeginPaint +PUBLIC _HBeginPaint -_TEXT SEGMENT +_TEXT SEGMENT _HBeginPaint PROC - mov r10,rcx - mov eax,1017h - syscall - ret + mov r10,rcx + mov eax,1017h + syscall + ret _HBeginPaint ENDP -_TEXT ENDS +_TEXT ENDS ;BOOL __stdcall _HEndPaint(HWND hWnd, const PAINTSTRUCT* lpPaint); -PUBLIC _HEndPaint +PUBLIC _HEndPaint -_TEXT SEGMENT +_TEXT SEGMENT _HEndPaint PROC - mov r10,rcx - mov eax,1019h - syscall - ret + mov r10,rcx + mov eax,1019h + syscall + ret _HEndPaint ENDP -_TEXT ENDS +_TEXT ENDS END diff --git a/src/3rdparty/webkit/WebCore/plugins/win/PluginViewWin.cpp b/src/3rdparty/webkit/WebCore/plugins/win/PluginViewWin.cpp index 4fc03dc..2687186 100644 --- a/src/3rdparty/webkit/WebCore/plugins/win/PluginViewWin.cpp +++ b/src/3rdparty/webkit/WebCore/plugins/win/PluginViewWin.cpp @@ -214,22 +214,22 @@ static void hook(const char* module, const char* proc, unsigned& sysCallID, BYTE pProc += 5; #else /* Disassembly of BeginPaint() - 00000000779FC5B0 4C 8B D1 mov r10,rcx - 00000000779FC5B3 B8 17 10 00 00 mov eax,1017h - 00000000779FC5B8 0F 05 syscall - 00000000779FC5BA C3 ret - 00000000779FC5BB 90 nop - 00000000779FC5BC 90 nop - 00000000779FC5BD 90 nop - 00000000779FC5BE 90 nop - 00000000779FC5BF 90 nop - 00000000779FC5C0 90 nop - 00000000779FC5C1 90 nop - 00000000779FC5C2 90 nop - 00000000779FC5C3 90 nop + 00000000779FC5B0 4C 8B D1 mov r10,rcx + 00000000779FC5B3 B8 17 10 00 00 mov eax,1017h + 00000000779FC5B8 0F 05 syscall + 00000000779FC5BA C3 ret + 00000000779FC5BB 90 nop + 00000000779FC5BC 90 nop + 00000000779FC5BD 90 nop + 00000000779FC5BE 90 nop + 00000000779FC5BF 90 nop + 00000000779FC5C0 90 nop + 00000000779FC5C1 90 nop + 00000000779FC5C2 90 nop + 00000000779FC5C3 90 nop */ // Check for the signature as in the above disassembly - DWORD guard = 0xB8D18B4C; + DWORD guard = 0xB8D18B4C; if (*reinterpret_cast(pProc) != guard) return; -- cgit v0.12 From b81b46407299c0b03fffab60d6d87cc71b57cd34 Mon Sep 17 00:00:00 2001 From: axis Date: Tue, 11 Aug 2009 14:28:37 +0200 Subject: Wrote an autotest to expose a bug in the GLib event dispatcher. Zero timers don't fire on the first pass in the GLib event dispatcher. Ideally I should fix the bug of course, but time doesn't permit at the moment. Submitting this test instead as a "reminder". The UNIX event dispatcher passes the test, and it also passes if moved to the end of the slots. Task: 259505 --- tests/auto/qtimer/tst_qtimer.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/auto/qtimer/tst_qtimer.cpp b/tests/auto/qtimer/tst_qtimer.cpp index 43b7553..8c8f1e3 100644 --- a/tests/auto/qtimer/tst_qtimer.cpp +++ b/tests/auto/qtimer/tst_qtimer.cpp @@ -73,6 +73,7 @@ public slots: void init(); void cleanup(); private slots: + void zeroTimer(); void singleShotTimeout(); void timeout(); void livelock_data(); @@ -129,6 +130,20 @@ void tst_QTimer::cleanup() { } +void tst_QTimer::zeroTimer() +{ + TimerHelper helper; + QTimer timer; + timer.setInterval(0); + timer.start(); + + connect(&timer, SIGNAL(timeout()), &helper, SLOT(timeout())); + + QCoreApplication::processEvents(); + + QCOMPARE(helper.count, 1); +} + void tst_QTimer::singleShotTimeout() { TimerHelper helper; @@ -482,4 +497,3 @@ void tst_QTimer::restartedTimerFiresTooSoon() QTEST_MAIN(tst_QTimer) #include "tst_qtimer.moc" -\ -- cgit v0.12 From e08c698d48a3179515e0392843c77efcac892134 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 11 Aug 2009 14:40:12 +0200 Subject: Phonon::VideoWidget still flickering small patch to make sure even the native events of the pending ones won't trigger anything in the paintevent Task-number: 251776 --- src/3rdparty/phonon/ds9/videowidget.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/3rdparty/phonon/ds9/videowidget.cpp b/src/3rdparty/phonon/ds9/videowidget.cpp index 07b9cf3..091be16 100644 --- a/src/3rdparty/phonon/ds9/videowidget.cpp +++ b/src/3rdparty/phonon/ds9/videowidget.cpp @@ -118,6 +118,8 @@ namespace Phonon void paintEvent(QPaintEvent *e) { + if (!updatesEnabled()) + return; //this avoids repaint from native events checkCurrentRenderingMode(); m_currentRenderer->repaintCurrentFrame(this, e->rect()); } -- cgit v0.12 From bead88ed4149202638167499e50148ae9fb7ab3e Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Tue, 11 Aug 2009 14:42:53 +0200 Subject: Allow make utilities other than "make" Instead of hard coding "make", use "$MAKE". If $MAKE is not set, configure will export it for us when searching for "make". Reviewed-by: Bradley T. Hughes --- config.tests/mac/crc.test | 6 +++--- config.tests/unix/compile.test | 6 +++--- config.tests/unix/doubleformat.test | 2 +- config.tests/unix/endian.test | 4 ++-- config.tests/unix/ptrsize.test | 4 ++-- config.tests/x11/notype.test | 4 ++-- configure | 2 ++ 7 files changed, 15 insertions(+), 13 deletions(-) diff --git a/config.tests/mac/crc.test b/config.tests/mac/crc.test index 1a16204..644ff75 100755 --- a/config.tests/mac/crc.test +++ b/config.tests/mac/crc.test @@ -52,13 +52,13 @@ test -d "$OUTDIR/$TEST" || mkdir -p "$OUTDIR/$TEST" cd "$OUTDIR/$TEST" -make distclean >/dev/null 2>&1 +$MAKE distclean >/dev/null 2>&1 "$OUTDIR/bin/qmake" -nocache -spec "$QMKSPEC" "CONFIG+=$QMAKE_CONFIG" "LIBS*=$LFLAGS" "INCLUDEPATH*=$INCLUDEPATH" "QMAKE_CXXFLAGS*=$CXXFLAGS" "$SRCDIR/$TEST/$EXE.pro" -o "$OUTDIR/$TEST/Makefile" if [ "$VERBOSE" = "yes" ]; then - make + $MAKE else - make >/dev/null 2>&1 + $MAKE >/dev/null 2>&1 fi diff --git a/config.tests/unix/compile.test b/config.tests/unix/compile.test index 550890f..67a4636 100755 --- a/config.tests/unix/compile.test +++ b/config.tests/unix/compile.test @@ -64,14 +64,14 @@ test -d "$OUTDIR/$TEST" || mkdir -p "$OUTDIR/$TEST" cd "$OUTDIR/$TEST" -test -r Makefile && make distclean >/dev/null 2>&1 +test -r Makefile && $MAKE distclean >/dev/null 2>&1 "$OUTDIR/bin/qmake" -nocache -spec "$QMKSPEC" "CONFIG+=$QMAKE_CONFIG" "LIBS*=$LFLAGS" "LIBS+=$MAC_ARCH_LFLAGS" "INCLUDEPATH*=$INCLUDEPATH" "QMAKE_CXXFLAGS*=$CXXFLAGS" "QMAKE_CXXFLAGS+=$MAC_ARCH_CXXFLAGS" "$SRCDIR/$TEST/$EXE.pro" -o "$OUTDIR/$TEST/Makefile" if [ "$VERBOSE" = "yes" ]; then - make + $MAKE else - make >/dev/null 2>&1 + $MAKE >/dev/null 2>&1 fi [ -x "$EXE" ] && SUCCESS=yes diff --git a/config.tests/unix/doubleformat.test b/config.tests/unix/doubleformat.test index 3e707c5..953efd8 100755 --- a/config.tests/unix/doubleformat.test +++ b/config.tests/unix/doubleformat.test @@ -14,7 +14,7 @@ test -d "$OUTDIR/config.tests/unix/doubleformat" || mkdir -p "$OUTDIR/config.tes cd "$OUTDIR/config.tests/unix/doubleformat" DOUBLEFORMAT="UNKNOWN" -[ "$VERBOSE" = "yes" ] && make || make >/dev/null 2>&1 +[ "$VERBOSE" = "yes" ] && $MAKE || $MAKE >/dev/null 2>&1 if [ -f ./doubleformattest ]; then : # nop diff --git a/config.tests/unix/endian.test b/config.tests/unix/endian.test index 2c21652..4755b1f 100755 --- a/config.tests/unix/endian.test +++ b/config.tests/unix/endian.test @@ -15,7 +15,7 @@ cd "$OUTDIR/config.tests/unix/endian" ENDIAN="UNKNOWN" -[ "$VERBOSE" = "yes" ] && make || make >/dev/null 2>&1 +[ "$VERBOSE" = "yes" ] && $MAKE || $MAKE >/dev/null 2>&1 if [ -f ./endiantest.exe ]; then binary=./endiantest.exe @@ -40,7 +40,7 @@ elif strings $binary | grep MostSignificantByteFirst >/dev/null 2>&1; then fi # make clean as this tests is compiled for both the host and the target -make distclean +$MAKE distclean # done if [ "$ENDIAN" = "LITTLE" ]; then diff --git a/config.tests/unix/ptrsize.test b/config.tests/unix/ptrsize.test index 1307cec..c1d80ee 100755 --- a/config.tests/unix/ptrsize.test +++ b/config.tests/unix/ptrsize.test @@ -14,9 +14,9 @@ test -d "$OUTDIR/config.tests/unix/ptrsize" || mkdir -p "$OUTDIR/config.tests/un cd "$OUTDIR/config.tests/unix/ptrsize" if [ "$VERBOSE" = "yes" ]; then - (make clean && make) + ($MAKE clean && $MAKE) else - (make clean && make) >/dev/null 2>&1 + ($MAKE clean && $MAKE) >/dev/null 2>&1 fi RETVAL=$? diff --git a/config.tests/x11/notype.test b/config.tests/x11/notype.test index a522491..3a01d8f 100755 --- a/config.tests/x11/notype.test +++ b/config.tests/x11/notype.test @@ -31,9 +31,9 @@ if [ $XPLATFORM = "solaris-g++" -o $XPLATFORM = "hpux-g++" -o $XPLATFORM = "aix- cd "$OUTDIR/config.tests/x11/notype" if [ "$VERBOSE" = "yes" ]; then - make + $MAKE else - make >/dev/null 2>&1 + $MAKE >/dev/null 2>&1 fi [ -x notypetest ] && NOTYPE=no diff --git a/configure b/configure index cca6847..7b7cc1c 100755 --- a/configure +++ b/configure @@ -2200,6 +2200,8 @@ if [ -z "$MAKE" ]; then echo >&2 "Cannot proceed." exit 1 fi + # export MAKE, we need it later in the config.tests + export MAKE fi fi ### help -- cgit v0.12 From cd649261f902c96c065d44591f6ee76a9b2be5dc Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 11 Aug 2009 14:46:40 +0200 Subject: Phonon: avoids assert when switching source The problem was that when switching source, the previous one was still running. So we now explicitly stop it. --- src/3rdparty/phonon/ds9/mediaobject.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/3rdparty/phonon/ds9/mediaobject.cpp b/src/3rdparty/phonon/ds9/mediaobject.cpp index a4feef6..22f1527 100644 --- a/src/3rdparty/phonon/ds9/mediaobject.cpp +++ b/src/3rdparty/phonon/ds9/mediaobject.cpp @@ -512,6 +512,8 @@ namespace Phonon qSwap(m_graphs[0], m_graphs[1]); //swap the graphs + m_graphs[1]->stop(); //make sure we stop the previous graph + if (currentGraph()->mediaSource().type() != Phonon::MediaSource::Invalid && catchComError(currentGraph()->renderResult())) { setState(Phonon::ErrorState); -- cgit v0.12 From ca28af7c530e60f55556aa7efc6fe19660be53b1 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Tue, 11 Aug 2009 13:13:25 +0200 Subject: Fixed uploading of glyphs to the glyph cache in the GL2 engine. Upload the glyph one scanline at a time to work around what probably is a driver bug. This replaces a previous fix 6d0290b2202d4fc084595ba678c2a2d984392e72. Reviewed-by: Tom --- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index a3475c7..3f14fdf 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -261,11 +261,21 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph) if (mask.format() == QImage::Format_RGB32) { glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, m_height - c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits()); } else { - // If the width of the uploaded data is not a multiple of four bytes, we get some garbage - // in the glyph cache, probably because of a driver bug. - // Convert to ARGB32 to get a multiple of 4 bytes per line. - mask = mask.convertToFormat(QImage::Format_ARGB32); - glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits()); +#ifdef QT_OPENGL_ES2 + glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_ALPHA, GL_UNSIGNED_BYTE, mask.bits()); +#else + // glTexSubImage2D() might cause some garbage to appear in the texture if the mask width is + // not a multiple of four bytes. The bug appeared on a computer with 32-bit Windows Vista + // and nVidia GeForce 8500GT. GL_UNPACK_ALIGNMENT is set to four bytes, 'mask' has a + // multiple of four bytes per line, and most of the glyph shows up correctly in the + // texture, which makes me think that this is a driver bug. + // One workaround is to make sure the mask width is a multiple of four bytes, for instance + // by converting it to a format with four bytes per pixel. Another is to copy one line at a + // time. + + for (uint i = 0; i < maskHeight; ++i) + glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, maskWidth, 1, GL_ALPHA, GL_UNSIGNED_BYTE, mask.scanLine(i)); +#endif } } -- cgit v0.12 From 12b344960c386c11423dc158a7ca866149208a3b Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 21 Jul 2009 14:57:14 +0200 Subject: Adding Windows Mobile 6.5 style --- src/gui/styles/qwindowsmobilestyle.cpp | 4252 ++++++++++++++++++++++++++++++-- src/gui/styles/qwindowsmobilestyle_p.h | 39 + 2 files changed, 4020 insertions(+), 271 deletions(-) diff --git a/src/gui/styles/qwindowsmobilestyle.cpp b/src/gui/styles/qwindowsmobilestyle.cpp index c70b4c8..1408c70f 100644 --- a/src/gui/styles/qwindowsmobilestyle.cpp +++ b/src/gui/styles/qwindowsmobilestyle.cpp @@ -669,10 +669,3852 @@ static const char * const min_small_xpm[] = { " ++++++++++++ ", " "}; +#ifdef Q_WS_WINCE_WM + +static char * sbhandleup_xpm[] = { +"26 41 45 1", +" c None", +". c #000000", +"+ c #E7E7E7", +"@ c #D6D7D6", +"# c #949294", +"$ c #737573", +"% c #636563", +"& c #636163", +"* c #5A5D5A", +"= c #5A595A", +"- c #525552", +"; c #525152", +"> c #4A4D4A", +", c #7B797B", +"' c #CECFCE", +") c #CED3CE", +"! c #6B6D6B", +"~ c #6B696B", +"{ c #737173", +"] c #7B7D7B", +"^ c #848684", +"/ c #848284", +"( c #8C8A8C", +"_ c #8C8E8C", +": c #B5B2B5", +"< c #FFFFFF", +"[ c #949694", +"} c #B5B6B5", +"| c #9C9A9C", +"1 c #ADAEAD", +"2 c #9C9E9C", +"3 c #BDBABD", +"4 c #BDBEBD", +"5 c #F7F3F7", +"6 c #C6C3C6", +"7 c #C6C7C6", +"8 c #A5A2A5", +"9 c #CECBCE", +"0 c #FFFBFF", +"a c #ADAAAD", +"b c #A5A6A5", +"c c #D6D3D6", +"d c #B5BAB5", +"e c #DEDFDE", +"f c #DEDBDE", +"..........................", +"+@#$%%&&&**===---;;;;>=,'+", +"+@#$%%&&&**===---;;;;>=$'+", +")$!!~~%%&&&**===---;;;;>;'", +"#{$]],,$${{{!!~~%%%&&&*-;]", +"#{$]],,$${{{!!~~%%%&&&*-;]", +",$^//]],,$${{{!!~~%%%&&*;*", +",,(^^//]],$${!!!!!~~%%%&-*", +",,(^^//]],$${!!!!!~~%%%&-*", +"]]_((^^//]$!%%~!{{!!~~%%-*", +"//#__((^^]{:<<:~!{{{!!~~=*", +"//#__((^^]{:<<:~!{{{!!~~=&", +"//###__(/$:<<<<:~{${{!!~*&", +"^^[[##_^]:<<<<<<}!{$${{!*%", +"^^[[##_^]:<<<<<<}!{$${{!*%", +"((|[[#_/:<<<<<<<<}!$$${{&~", +"((||[#^1<<<<1:<<<<}!$$$$&~", +"((||[#^1<<<<1:<<<<}!$$$$&~", +"__2|#(1<<<<}],}<<<<}{$,$%~", +"##2|_1<<<<}^((]3<<<<}{$,~!", +"##2|_1<<<<}^((]3<<<<}{$,~!", +"##2#1<<<<3^###(/4<<<<}{,~{", +"##2#1<<<<3^###(/4<<<<}{,~!", +"[[2_5<<<4(#|[[#_/6<<<<,,!{", +"[|2_5<<4_[||||[[_/7<<<,]{$", +"[|2_5<<4_[||||[[_/7<<<,]{$", +"||8_5<6#|2222|||[_/9<<,]{$", +"228#06[28888222||[_/'<,/$,", +"228#06[28888222||[_/'<,/$,", +"22a|6[8bbbb88822||[(/c](,]", +"881b8baaabbbb88222|[(^(_,]", +"881b8baaabbbb88222|[(^(_,]", +"88111111aaabbb88822|[###]/", +"bb:::11111aaabbb8822||[[/^", +"bb:::11111aaabbb8822||[[//", +"bb:::::1111aaabbb8822||[/(", +"3a1::::::1111aaabb8822|_^8", +"da1::::::1111aaabb8822|_^8", +"e1aaabbbb888822||[[##__((@", +"+e4:aaabbbb88822||[[[#[b@+", +"+e4:aaabbbb88822||[[[#[bf+"}; + +static char * sbhandledown_xpm[] = { +"26 40 46 1", +" c None", +". c #E7E7E7", +"+ c #DEDFDE", +"@ c #BDBEBD", +"# c #B5B2B5", +"$ c #ADAAAD", +"% c #A5A6A5", +"& c #A5A2A5", +"* c #9C9E9C", +"= c #9C9A9C", +"- c #949694", +"; c #949294", +"> c #D6D7D6", +", c #DEDBDE", +"' c #D6DBD6", +") c #ADAEAD", +"! c #8C8E8C", +"~ c #8C8A8C", +"{ c #BDBABD", +"] c #848684", +"^ c #B5BAB5", +"/ c #848284", +"( c #848A84", +"_ c #7B7D7B", +": c #7B797B", +"< c #C6C3C6", +"[ c #D6D3D6", +"} c #FFFBFF", +"| c #CECFCE", +"1 c #FFFFFF", +"2 c #737573", +"3 c #F7F3F7", +"4 c #CECBCE", +"5 c #737173", +"6 c #C6C7C6", +"7 c #6B6D6B", +"8 c #B5B6B5", +"9 c #6B696B", +"0 c #636563", +"a c #636163", +"b c #5A5D5A", +"c c #5A595A", +"d c #525552", +"e c #525152", +"f c #4A4D4A", +"g c #C6CBC6", +".+@#$$$%%%%&&&**==---;-%>.", +".+@#$$$%%%%&&&**==---;-%,.", +"')$$$%%%%&&&&**==--;;!!~~>", +"{$)######))))$$$%%&&**=!]&", +"^$)######))))$$$%%&&**=!]&", +"%%#####))))$$$%%%&&**==-/(", +"%%###)))))$$$%%%&&**==--/]", +"%%###)))))$$$%%%&&**==--//", +"&&))))))$$$%%%&&&**=-;;;_/", +"&&)%&%$$$%%%%&&***=-~]~!:_", +"&&)%&%$$$%%%%&&***=-~]~!:_", +"**$=<-&%%%%&&&**==-~/[_~:_", +"**&;}<-*&&&&***==-!/|1:/2:", +"**&;}<-*&&&&***==-!/|1:/2:", +"==&!31<;=****===-!/411:_5:", +"-=*!311@!-====--!/6111:_52", +"-=*!311@!-====--!/6111:_52", +"--*!3111@~;=--;!/<1111::75", +";;*;)1111{];;;~/@111185:95", +";;*;)1111{];;;~/@111185:97", +";;*=!)11118]~~_{1111852:97", +";;*=!)11118]~~_{1111852:97", +"!!*=;~)11118_:81111852:207", +"~~==-;])1111)#1111872222a9", +"~~==-;])1111)#1111872222a9", +"~~=--;!/#111111118722255a0", +"]]--;;!]_#11111187522557b0", +"]]--;;!]_#11111187522557b0", +"//;;;!!~/2#1111#95255779ba", +"//;!!~~]]_5#11#975557799cb", +"//;!!~~]]_5#11#975557799ca", +"__!~~]]//_27009755779900db", +"::~]]//__:2257777799000adb", +"::~]]//__:2257777799000adb", +":2]//__::225557799000aabeb", +";52__::225557799000aaabde_", +";52__::225557799000aaabde_", +"[2779900aaabbcccdddeeeefeg", +".>;200aaabbcccdddeeeefc:|.", +".>;200aaabbcccdddeeeefc2|."}; + +static char * sbgripdown_xpm[] = { +"26 34 39 1", +" c None", +". c #949294", +"+ c #9C9E9C", +"@ c #9C9A9C", +"# c #949694", +"$ c #8C8E8C", +"% c #8C8A8C", +"& c #848684", +"* c #848284", +"= c #7B7D7B", +"- c #7B797B", +"; c #6B696B", +"> c #636563", +", c #737573", +"' c #636163", +") c #737173", +"! c #5A5D5A", +"~ c #6B6D6B", +"{ c #5A595A", +"] c #B5B6B5", +"^ c #BDBEBD", +"/ c #ADAEAD", +"( c #BDBABD", +"_ c #525552", +": c #313031", +"< c #525152", +"[ c #ADAAAD", +"} c #BDBAB5", +"| c #4A4D4A", +"1 c #4A494A", +"2 c #C6C3C6", +"3 c #C6CBC6", +"4 c #E7E7E7", +"5 c #DEDFDE", +"6 c #E7E3E7", +"7 c #DEE3DE", +"8 c #CECBCE", +"9 c #8C928C", +"0 c #CECFCE", +"..+++@@@###...$$%&&**==-;>", +"$.++@@@@##...$$%%&**==-->>", +"$$+@@@@###..$$%%&&*==--,>>", +"$$@@@@###..$$%%&&**==-,,>'", +"%%@@@###..$$$%&&**==--,,''", +"%%@@###..$$$%&&**==--,,)''", +"%%@###...$$%%&&*==--,,))'!", +"&&###...$$%%&&**==--,)))!!", +"&&##...$$%%&&**==--,,))~!!", +"&&#...$$%%&&**==--,,))~~!{", +"**...$$%%&&**==--,,))~~;!{", +"**..$$%%&&**===--,)))~~;{{", +"**.$$%%&]^&===//,,))~~;;{{", +"==$$%%&&]^*==-((,))~~;;>{_", +"==$%%&&***::--,,::~~;;;>__", +"==%%&&&**=::-,,)::~~;;>>__", +"--%&&&**==--,,)))~~;;>>>__", +"--&&&**==--,,)))~~;;>>>'_<", +",-&&**==]^-,))[[~;;>>>''<<", +",,&**==-]^-)))}};;>>>'''<<", +",,**==--,,::)~~;::>>'''!<<", +"))*==--,,)::~~;;::>'''!!<|", +"))==--,,)))~~;;;>>'''!!!||", +"))=--,,)))~~;;;>>'''!!!{||", +"~~--,,)))~~;;;>>'''!!!{{||", +"~~-,,)))~~;;>>>'''!!!{{{|1", +";;,,)))~~;;>>>'''!!!{{{_1<", +"~;,)))~~;;>>>'''!!!{{{__1'", +"%>~))~~;;>>>'''!!!{{{__|1$", +"2>>~~~;;>>>''!!!{{{{__<113", +"4%'';;;>>>''!!!{{{{__<11%4", +"45-!!'>>>''!!!{{{{_<|11)64", +"447+!{{___<<<||||1111|+444", +"444489~__<<<||||111>$04444"}; + +static char * sbgripup_xpm[] = { +"26 34 38 1", +" c None", +". c #E7E7E7", +"+ c #D6DBD6", +"@ c #C6C7C6", +"# c #B5B6B5", +"$ c #ADAEAD", +"% c #ADAAAD", +"& c #A5A6A5", +"* c #A5A2A5", +"= c #BDBEBD", +"- c #DEDFDE", +"; c #C6CBC6", +"> c #9C9E9C", +", c #E7E3E7", +"' c #BDBABD", +") c #B5B2B5", +"! c #9C9A9C", +"~ c #DEE3DE", +"{ c #949694", +"] c #D6D7D6", +"^ c #949294", +"/ c #DEDBDE", +"( c #8C8E8C", +"_ c #8C8A8C", +": c #848684", +"< c #D6D3CE", +"[ c #CECBCE", +"} c #D6D3D6", +"| c #848284", +"1 c #313031", +"2 c #7B7D7B", +"3 c #CECFCE", +"4 c #CECBC6", +"5 c #7B797B", +"6 c #737573", +"7 c #737173", +"8 c #6B6D6B", +"9 c #6B696B", +"....+@#$$%%%%&&&***$=-....", +"...;$$$$$%%%&&&&**>>>>@...", +".,'$$)#'#####)))$$$%*!!$~.", +".=$)#'''####))))$$$%%*!{'.", +"]$$''''#####)))$$$%%%&*{^/", +"=$#'''#####)))$$$$%%&&&!^#", +"$$'''#####))))$$$%%%&&*>(!", +"$$''#####))))$$$%%%&&&*>(^", +"$$######))))$$$$%%&&&**>(_", +"%$#####))))$$$$%%%&&***>__", +"%$####))))$$$$%%%&&&**>>__", +"%%###)))))$$$%%%&&&**>>>_:", +"%%##))))<])$$%[[&&***>>!::", +"%%#)))))<]$$%%}<&&**>>!!:|", +"&%)))))$$$11%%&&11*>>>!!:|", +"&&))))$$$$11%&&&11*>>!!{||", +"&&)))$$$$$%%%&&&**>>!!!{|2", +"&&))$$$$$%%%&&&**>>>!!{{|2", +"*&)$$$$$3]%&&&4@*>>!!{{{22", +"**$$$$$%3]%&&&<<>>!!!{{^25", +"**$$$$%%%%11&**>11!!{{^^25", +"**$$$%%%%&11***>11!!{{^^55", +"**$$%%%%&&&***>>!!!{{^^(55", +">>$%%%%&&&***>>>!!{{^^((56", +">>%%%%&&&&***>>!!!{{^^((66", +">>%%%&&&&***>>!!!{{^^((_67", +"!>%%&&&&***>>>!!{{{^^(__67", +"!!%&&&&***>>>!!!{{^^((_:77", +"!!&&&&***>>>!!!{{^^((__:77", +"!!&&&****>>!!!{{^^^(__::78", +"{!&&****>>>!!{{{^^((_::|88", +"{{&****>>>!!!{{^^((__:||88", +"{{****>>>!!!{{^^^(__::|289", +"{{***>>>!!!{{{^^((_::||289"}; + +static char * sbgripmiddle_xpm[] = { +"26 2 12 1", +" c None", +". c #949294", +"+ c #A5A2A5", +"@ c #9C9E9C", +"# c #9C9A9C", +"$ c #949694", +"% c #8C8E8C", +"& c #8C8A8C", +"* c #848684", +"= c #848284", +"- c #7B7D7B", +"; c #6B696B", +"..++@@@###$$$..%%&&*==--;;", +"..++@@@###$$$..%%&&*==--;;"}; + + +static char * listviewhighmiddle_xpm[] = { +"8 46 197 2", +" c None", +". c #66759E", +"+ c #6C789D", +"@ c #6A789E", +"# c #6B789E", +"$ c #6A779D", +"% c #6C789C", +"& c #6F7D9B", +"* c #6F7D9A", +"= c #9DB6EE", +"- c #9DB6ED", +"; c #9CB6ED", +"> c #A1B6EF", +", c #A2B6F0", +"' c #93AAE9", +") c #95ABEA", +"! c #94ABEA", +"~ c #94A9E8", +"{ c #8BA8EA", +"] c #8BA7EA", +"^ c #8AA7EA", +"/ c #8EAAE8", +"( c #8FAAE8", +"_ c #88A2E7", +": c #8CA3E8", +"< c #8BA3E7", +"[ c #8BA3E8", +"} c #8BA2E7", +"| c #8CA2E7", +"1 c #8DA2E7", +"2 c #87A1E8", +"3 c #87A1E9", +"4 c #86A0E8", +"5 c #86A1E7", +"6 c #87A2E7", +"7 c #859EE9", +"8 c #849DE9", +"9 c #869EE9", +"0 c #869FE9", +"a c #7C9BEA", +"b c #7C9CEA", +"c c #7B9CEA", +"d c #7C9BE9", +"e c #7E9CE9", +"f c #7B9AEA", +"g c #7C99E9", +"h c #7C9AEA", +"i c #7B9AE8", +"j c #7A9AEA", +"k c #7996E1", +"l c #7C96E4", +"m c #7B96E3", +"n c #7B95E3", +"o c #7E95E5", +"p c #7E95E6", +"q c #7292E1", +"r c #7490DF", +"s c #7591E0", +"t c #7590DF", +"u c #7392E1", +"v c #6D8CDE", +"w c #6F8EDD", +"x c #6E8DDD", +"y c #6E8DDE", +"z c #6F8EDE", +"A c #6E8EDE", +"B c #718EDD", +"C c #728EDD", +"D c #6B89E0", +"E c #6C89DF", +"F c #6D89E0", +"G c #6D89DF", +"H c #6C88DF", +"I c #6D88DF", +"J c #6D86DD", +"K c #6086E0", +"L c #6686E0", +"M c #6586E0", +"N c #6486E0", +"O c #6485E0", +"P c #6786DF", +"Q c #5F85E0", +"R c #6583DE", +"S c #6683DE", +"T c #6682DD", +"U c #6086DF", +"V c #5F86E0", +"W c #567ED7", +"X c #567ED8", +"Y c #557DD7", +"Z c #5A7FD8", +"` c #6281DA", +" . c #5379D9", +".. c #5278D9", +"+. c #547BD8", +"@. c #4C73D7", +"#. c #4B72D2", +"$. c #4C73D4", +"%. c #4C73D3", +"&. c #4B72D4", +"*. c #4F75D3", +"=. c #5074D2", +"-. c #4971D0", +";. c #4871D0", +">. c #335ECF", +",. c #325ECB", +"'. c #335ECD", +"). c #335ECE", +"!. c #325DCD", +"~. c #2E59C9", +"{. c #3059C9", +"]. c #2F59C9", +"^. c #2F59C8", +"/. c #2B59CA", +"(. c #3355C6", +"_. c #3354C5", +":. c #3156C7", +"<. c #3056C7", +"[. c #3355C7", +"}. c #3355C5", +"|. c #254EBF", +"1. c #1F51C1", +"2. c #234FC0", +"3. c #234FBF", +"4. c #2350C0", +"5. c #1E50BE", +"6. c #1D50C0", +"7. c #264DBE", +"8. c #264CBD", +"9. c #254DBE", +"0. c #244EBF", +"a. c #254DBF", +"b. c #234CBF", +"c. c #244CC0", +"d. c #244BC0", +"e. c #234BC0", +"f. c #234BBF", +"g. c #234CBE", +"h. c #2049B7", +"i. c #2A49B5", +"j. c #2749B5", +"k. c #2749B6", +"l. c #2D49B4", +"m. c #2649B6", +"n. c #2946B5", +"o. c #2A48B6", +"p. c #2947B5", +"q. c #2946B6", +"r. c #2848B6", +"s. c #2549B5", +"t. c #2648B6", +"u. c #2744B5", +"v. c #2744B4", +"w. c #2744AF", +"x. c #2543B4", +"y. c #2543B2", +"z. c #2442B2", +"A. c #2442B3", +"B. c #2442B5", +"C. c #2543B3", +"D. c #1F40B1", +"E. c #1E40B1", +"F. c #243EAE", +"G. c #273BAC", +"H. c #263DAC", +"I. c #253CAB", +"J. c #273CAB", +"K. c #273CAC", +"L. c #263BAA", +"M. c #253CAE", +"N. c #263BA6", +"O. c #253BA5", +"P. c #253AA5", +"Q. c #253BA6", +"R. c #253CA7", +"S. c #263AA6", +"T. c #243CA6", +"U. c #253CA5", +"V. c #273BA8", +"W. c #2F4DA4", +"X. c #2F4DA3", +"Y. c #1B2F85", +"Z. c #B5B5B6", +"`. c #B5B5B5", +" + c #B5B6B6", +".+ c #B5B4B6", +"++ c #C2C3C5", +"@+ c #C0C3C3", +"#+ c #C1C3C4", +"$+ c #E3E3E3", +"%+ c #E3E3E4", +"&+ c #E4E3E4", +"*+ c #E2E3E4", +"=+ c #ECEEEB", +"-+ c #EBEDEA", +";+ c #EEF0ED", +">+ c #EFF0EE", +". + @ @ # # $ % ", +"& & * & & & & & ", +"= = - = = ; > , ", +"' ) ! ! ! ) ' ~ ", +"{ ] { { { ^ / ( ", +"_ : < [ : } | 1 ", +"2 2 2 3 2 4 5 6 ", +"7 7 7 7 7 8 9 0 ", +"a b a a a c d e ", +"f g h h h h i j ", +"k l m m m n o p ", +"q q q q q q q q ", +"r r s s s t q u ", +"v w x y z A B C ", +"D E F F G F H I ", +"J K L M N O P Q ", +"R R S S S T U V ", +"W W X X X Y Z ` ", +" . . . . ...+.W ", +" . . . . ..... .", +"@.#.$.$.%.&.*.=.", +"-.-.;.-.-.-.-.-.", +">.,.'.).).!.!.>.", +"~.{.].^.].^././.", +"(.(.(.(.(._.:.<.", +"(.(.[.[.[.[.(.}.", +"|.1.2.3.3.4.5.6.", +"7.7.7.7.7.8.9.0.", +"a.b.c.d.c.e.f.g.", +"h.i.j.k.j.k.l.m.", +"n.o.p.q.r.p.s.t.", +"u.u.v.u.u.u.u.u.", +"w.x.y.z.A.y.B.C.", +"D.D.E.D.D.D.D.D.", +"D.D.E.D.D.D.D.D.", +"F.G.H.I.J.K.L.M.", +"N.N.O.N.N.P.Q.R.", +"N.N.S.N.N.N.N.N.", +"T.N.T.T.T.U.N.V.", +"W.W.X.W.W.W.W.W.", +"W.W.W.W.W.W.W.W.", +"Y.Y.Y.Y.Y.Y.Y.Y.", +"Z.`. + +.+Z.`.`.", +"++@+#+#+#+#+@+@+", +"$+%+&+&+*+%+%+%+", +"=+-+;+-+-+>+-+-+"}; + + + +static char * listviewhighcornerleft_xpm[] = { +"100 46 1475 2", +" c None", +". c #FBFBFC", +"+ c #E8EAE7", +"@ c #758DC3", +"# c #42599E", +"$ c #28418A", +"% c #19418F", +"& c #3F5695", +"* c #415896", +"= c #435A98", +"- c #445C99", +"; c #465E9B", +"> c #48609B", +", c #49629C", +"' c #4A639D", +") c #49639D", +"! c #4A629D", +"~ c #4B639D", +"{ c #4B649D", +"] c #4C659D", +"^ c #4D669D", +"/ c #4E689D", +"( c #506A9D", +"_ c #516A9D", +": c #536B9C", +"< c #546C9C", +"[ c #566D9B", +"} c #576D9B", +"| c #586E9C", +"1 c #5B6F9D", +"2 c #61739D", +"3 c #63749E", +"4 c #64749E", +"5 c #68769E", +"6 c #6A779E", +"7 c #6B789E", +"8 c #66759E", +"9 c #6C789D", +"0 c #EEF0ED", +"a c #D0D3DC", +"b c #3E51A3", +"c c #28428B", +"d c #29428C", +"e c #425996", +"f c #455C99", +"g c #485F9C", +"h c #49619E", +"i c #4A63A0", +"j c #4B64A1", +"k c #4B65A1", +"l c #4C66A2", +"m c #4D67A2", +"n c #4F69A1", +"o c #516AA1", +"p c #536CA0", +"q c #556DA1", +"r c #576EA0", +"s c #586F9F", +"t c #586E9F", +"u c #596F9E", +"v c #5A6F9E", +"w c #5C709E", +"x c #5E719E", +"y c #5F729F", +"z c #62739F", +"A c #63739E", +"B c #64749D", +"C c #65749E", +"D c #69769D", +"E c #6C799E", +"F c #6D799F", +"G c #707D9F", +"H c #717F9E", +"I c #6E7AA1", +"J c #6C789E", +"K c #6F7C9C", +"L c #6F7D9B", +"M c #2A4AA0", +"N c #4971D0", +"O c #4C72D8", +"P c #5472C0", +"Q c #5573BF", +"R c #5774BF", +"S c #5875BF", +"T c #5976C1", +"U c #5A76C1", +"V c #5C78C2", +"W c #5E7AC2", +"X c #607CC3", +"Y c #627EC3", +"Z c #637FC4", +"` c #6581C5", +" . c #6682C6", +".. c #6783C7", +"+. c #6984C8", +"@. c #6B85C9", +"#. c #6D87CA", +"$. c #6F89CB", +"%. c #718CCD", +"&. c #748ECF", +"*. c #7690D0", +"=. c #7992D2", +"-. c #7A93D3", +";. c #7C95D5", +">. c #7F98D7", +",. c #8099D8", +"'. c #859CDB", +"). c #8AA0DD", +"!. c #8DA3DF", +"~. c #8FA5E0", +"{. c #90A5E0", +"]. c #91A6E1", +"^. c #91A5E1", +"/. c #90A4E0", +"(. c #8EA3DE", +"_. c #92A6E2", +":. c #8FA4DF", +"<. c #90A5DE", +"[. c #90A5DC", +"}. c #90A6DB", +"|. c #91A6E0", +"1. c #93A7E2", +"2. c #95AAE6", +"3. c #99AEEA", +"4. c #9AB2EA", +"5. c #99B1E9", +"6. c #99B1E7", +"7. c #98AFE6", +"8. c #93A8E2", +"9. c #97ACE7", +"0. c #9AB3EB", +"a. c #9DB5ED", +"b. c #9DB6EE", +"c. c #375095", +"d. c #4056AD", +"e. c #506DCD", +"f. c #4360CC", +"g. c #345ED6", +"h. c #335ECF", +"i. c #355ED6", +"j. c #355FD6", +"k. c #365FD6", +"l. c #355FD0", +"m. c #3760D5", +"n. c #3A63D4", +"o. c #3C63D1", +"p. c #3B63CD", +"q. c #3B63C9", +"r. c #3B62C9", +"s. c #3D63C8", +"t. c #4065C5", +"u. c #4567C5", +"v. c #496BC5", +"w. c #4F70C7", +"x. c #5273C8", +"y. c #5475CA", +"z. c #5777CB", +"A. c #5879CD", +"B. c #5A7BCE", +"C. c #5D7DCF", +"D. c #5F7ECF", +"E. c #617FD0", +"F. c #6381D1", +"G. c #6583D2", +"H. c #6785D2", +"I. c #6886D3", +"J. c #6A88D4", +"K. c #6C89D5", +"L. c #6E8BD6", +"M. c #708CD7", +"N. c #718DD8", +"O. c #738EDA", +"P. c #748FDB", +"Q. c #7691DC", +"R. c #7893DD", +"S. c #7994DD", +"T. c #7A96DE", +"U. c #7B97DF", +"V. c #7C98E0", +"W. c #7E9AE2", +"X. c #7F9BE3", +"Y. c #829DE4", +"Z. c #849FE5", +"`. c #87A0E6", +" + c #88A1E7", +".+ c #89A2E6", +"++ c #8CA3E7", +"@+ c #8EA5E9", +"#+ c #8EA6E9", +"$+ c #8FA7E9", +"%+ c #8FA8E8", +"&+ c #8FA9E8", +"*+ c #91A9E8", +"=+ c #90A7E8", +"-+ c #8FA8EA", +";+ c #90AAEA", +">+ c #93ABEA", +",+ c #95ABEA", +"'+ c #93ABE9", +")+ c #94ABEA", +"!+ c #90A9EA", +"~+ c #93AAE9", +"{+ c #273E7E", +"]+ c #345ED5", +"^+ c #3D60CE", +"/+ c #3D60CF", +"(+ c #345ECF", +"_+ c #335ED0", +":+ c #355FD3", +"<+ c #3A60CE", +"[+ c #3A5FCB", +"}+ c #385FC9", +"|+ c #3B60C8", +"1+ c #3C63CB", +"2+ c #3E64CB", +"3+ c #4166CA", +"4+ c #4568C9", +"5+ c #4A6CC7", +"6+ c #4F71C8", +"7+ c #5172CA", +"8+ c #5475CE", +"9+ c #5678D3", +"0+ c #597CD6", +"a+ c #5C7ED7", +"b+ c #5E7FD8", +"c+ c #6181D9", +"d+ c #6383DA", +"e+ c #6585DA", +"f+ c #6786DB", +"g+ c #6988DC", +"h+ c #6B8ADD", +"i+ c #6D8BDE", +"j+ c #6F8DDE", +"k+ c #718EDF", +"l+ c #728FE0", +"m+ c #7390E1", +"n+ c #7390E2", +"o+ c #7491E3", +"p+ c #7592E4", +"q+ c #7693E4", +"r+ c #7794E5", +"s+ c #7894E5", +"t+ c #7995E6", +"u+ c #7B96E6", +"v+ c #7C97E7", +"w+ c #7D9AE8", +"x+ c #7F9CE9", +"y+ c #829DE9", +"z+ c #849EE9", +"A+ c #859EE9", +"B+ c #87A0E7", +"C+ c #8AA2E7", +"D+ c #8BA3E8", +"E+ c #89A2E7", +"F+ c #8CA6EA", +"G+ c #8BA6EA", +"H+ c #8BA7EA", +"I+ c #8CA3E8", +"J+ c #8BA8EA", +"K+ c #8CA7EA", +"L+ c #8CA8EA", +"M+ c #4659C7", +"N+ c #355ECF", +"O+ c #3660CF", +"P+ c #3860CE", +"Q+ c #3961CD", +"R+ c #3B61CB", +"S+ c #3B61CA", +"T+ c #3D62CA", +"U+ c #3D63CA", +"V+ c #4165CB", +"W+ c #456ACB", +"X+ c #4B6FCD", +"Y+ c #5174CE", +"Z+ c #5275D1", +"`+ c #5477D4", +" @ c #5678D9", +".@ c #587ADB", +"+@ c #597BDB", +"@@ c #5B7DDC", +"#@ c #5E7FDC", +"$@ c #6081DD", +"%@ c #6283DE", +"&@ c #6484DF", +"*@ c #6787E0", +"=@ c #6989E1", +"-@ c #6B8BE1", +";@ c #6D8DE2", +">@ c #6F8EE3", +",@ c #718FE4", +"'@ c #7290E4", +")@ c #7491E5", +"!@ c #7692E6", +"~@ c #7793E5", +"{@ c #7894E6", +"]@ c #7895E7", +"^@ c #7996E8", +"/@ c #7A97E8", +"(@ c #7B98E9", +"_@ c #7D99E8", +":@ c #7F9AE8", +"<@ c #7F9BE9", +"[@ c #7F9CEA", +"}@ c #859EE8", +"|@ c #859FE8", +"1@ c #85A0E9", +"2@ c #869FE9", +"3@ c #86A1E7", +"4@ c #86A0E9", +"5@ c #87A1E7", +"6@ c #88A2E7", +"7@ c #87A1E9", +"8@ c #5A6FCA", +"9@ c #365FCF", +"0@ c #345ED0", +"a@ c #385FCC", +"b@ c #385FCE", +"c@ c #3A61CC", +"d@ c #3B62CD", +"e@ c #3E64CD", +"f@ c #4167CF", +"g@ c #4469CF", +"h@ c #486CD1", +"i@ c #4D71D2", +"j@ c #5175D4", +"k@ c #5376D6", +"l@ c #5578DA", +"m@ c #5679DC", +"n@ c #587BDD", +"o@ c #5A7DDE", +"p@ c #5D80DE", +"q@ c #5F82DF", +"r@ c #6284DF", +"s@ c #6585E0", +"t@ c #6787E1", +"u@ c #6988E2", +"v@ c #6B8AE2", +"w@ c #6D8CE3", +"x@ c #6E8DE3", +"y@ c #708EE4", +"z@ c #718FE3", +"A@ c #7391E4", +"B@ c #7592E5", +"C@ c #7895E5", +"D@ c #7996E6", +"E@ c #7A97E6", +"F@ c #7B98E7", +"G@ c #7A98E8", +"H@ c #7B99E9", +"I@ c #7E9AE9", +"J@ c #7D9AE9", +"K@ c #7E9AEA", +"L@ c #809CE9", +"M@ c #819DE8", +"N@ c #7F9BEA", +"O@ c #819DE9", +"P@ c #819CE9", +"Q@ c #839EE9", +"R@ c #839EE8", +"S@ c #839DEA", +"T@ c #859FE9", +"U@ c #87A0E8", +"V@ c #86A0E8", +"W@ c #87A1E8", +"X@ c #3760CF", +"Y@ c #3A61CE", +"Z@ c #3A62CD", +"`@ c #3F66CE", +" # c #4368D0", +".# c #466CD2", +"+# c #496DD5", +"@# c #4E72D6", +"## c #5175D8", +"$# c #5276DA", +"%# c #5578DC", +"&# c #577ADC", +"*# c #597CDD", +"=# c #5B7DDD", +"-# c #5D7FDE", +";# c #5E81DE", +"># c #6183DF", +",# c #6386DF", +"'# c #6687E0", +")# c #6888E0", +"!# c #6A89E1", +"~# c #6C8AE1", +"{# c #6E8CE2", +"]# c #6F8DE2", +"^# c #7390E4", +"/# c #7390E3", +"(# c #7491E4", +"_# c #7693E5", +":# c #7895E6", +"<# c #7896E6", +"[# c #7997E7", +"}# c #7B97E7", +"|# c #7B98E8", +"1# c #7C98E8", +"2# c #7E9BE9", +"3# c #809CEA", +"4# c #819CEA", +"5# c #839DE9", +"6# c #365FD0", +"7# c #3660D0", +"8# c #3961CF", +"9# c #3B63CF", +"0# c #3D64D0", +"a# c #4067D0", +"b# c #4469D2", +"c# c #466BD3", +"d# c #496ED5", +"e# c #4C71D6", +"f# c #4E72D8", +"g# c #5074D9", +"h# c #5376DB", +"i# c #5578DB", +"j# c #587ADC", +"k# c #5B7CDC", +"l# c #5D7EDD", +"m# c #5F80DD", +"n# c #6081DE", +"o# c #6383DE", +"p# c #6686DF", +"q# c #6887E0", +"r# c #6988E0", +"s# c #6B89E1", +"t# c #6C8AE0", +"u# c #6E8CE1", +"v# c #708EE2", +"w# c #718FE2", +"x# c #7290E3", +"y# c #7391E2", +"z# c #7492E1", +"A# c #7592E2", +"B# c #7691E3", +"C# c #7591E3", +"D# c #7692E3", +"E# c #7693E3", +"F# c #7793E4", +"G# c #7893E4", +"H# c #7994E5", +"I# c #7D97E8", +"J# c #7E98E8", +"K# c #7D98E8", +"L# c #7D99E9", +"M# c #7D9BEA", +"N# c #7D9CEA", +"O# c #7E99E8", +"P# c #7D9AEA", +"Q# c #7C9BEA", +"R# c #7C9CEA", +"S# c #355FCF", +"T# c #3860D0", +"U# c #3A62D0", +"V# c #3C64D1", +"W# c #4167D1", +"X# c #4369D3", +"Y# c #466BD4", +"Z# c #486DD5", +"`# c #4A6ED7", +" $ c #4C70D8", +".$ c #5478D9", +"+$ c #577BDA", +"@$ c #597DDB", +"#$ c #5B7EDB", +"$$ c #5D7FDC", +"%$ c #6182DE", +"&$ c #6284DE", +"*$ c #6485DF", +"=$ c #6586DF", +"-$ c #6787DF", +";$ c #6888DF", +">$ c #6A8ADF", +",$ c #6C8BE0", +"'$ c #6D8CE0", +")$ c #6E8DE1", +"!$ c #6F8DE1", +"~$ c #708EE1", +"{$ c #718FE0", +"]$ c #728FE1", +"^$ c #7390E0", +"/$ c #738FE0", +"($ c #7490E1", +"_$ c #7590E1", +":$ c #7591E1", +"<$ c #7592E1", +"[$ c #7692E2", +"}$ c #7794E2", +"|$ c #7894E3", +"1$ c #7996E3", +"2$ c #7A96E5", +"3$ c #7B98E6", +"4$ c #7B9AE8", +"5$ c #7C99E8", +"6$ c #7C96E5", +"7$ c #7D97E7", +"8$ c #7C99E9", +"9$ c #7B9AE9", +"0$ c #7B9AEA", +"a$ c #5B6DCF", +"b$ c #305EC8", +"c$ c #335ECE", +"d$ c #305ECA", +"e$ c #345FCF", +"f$ c #3761D0", +"g$ c #3A62D1", +"h$ c #3C64D2", +"i$ c #4066D3", +"j$ c #466BD5", +"k$ c #486ED6", +"l$ c #4A6ED6", +"m$ c #4D71D8", +"n$ c #4F72D9", +"o$ c #5073D9", +"p$ c #4F72D8", +"q$ c #5074D8", +"r$ c #5276D9", +"s$ c #587ADA", +"t$ c #5B7CDB", +"u$ c #5D7EDC", +"v$ c #5F7FDD", +"w$ c #6081DC", +"x$ c #6182DD", +"y$ c #6283DD", +"z$ c #6484DE", +"A$ c #6585DD", +"B$ c #6787DE", +"C$ c #6988DF", +"D$ c #6A89DE", +"E$ c #6C8ADF", +"F$ c #6D8BDF", +"G$ c #6E8CE0", +"H$ c #6F8DE0", +"I$ c #718EE0", +"J$ c #728FDF", +"K$ c #728FDE", +"L$ c #7290E0", +"M$ c #7190E0", +"N$ c #7291E0", +"O$ c #7191E0", +"P$ c #7392E1", +"Q$ c #7493E1", +"R$ c #7594E1", +"S$ c #7594E2", +"T$ c #7694E2", +"U$ c #7695E2", +"V$ c #7A96E4", +"W$ c #7895E2", +"X$ c #7A96E2", +"Y$ c #7A96E3", +"Z$ c #7B96E3", +"`$ c #7996E1", +" % c #7C96E4", +".% c #305EC9", +"+% c #315ECC", +"@% c #325ECE", +"#% c #3760D0", +"$% c #3962D1", +"%% c #3E66D3", +"&% c #4268D4", +"*% c #446BD5", +"=% c #476CD6", +"-% c #496ED7", +";% c #4B6FD7", +">% c #4C70D7", +",% c #4E71D7", +"'% c #5074D7", +")% c #5276D8", +"!% c #5376D8", +"~% c #5779DA", +"{% c #597ADA", +"]% c #5A7BDB", +"^% c #5B7CDA", +"/% c #5D7EDB", +"(% c #5E7FDB", +"_% c #6182DB", +":% c #6384DC", +"<% c #6586DD", +"[% c #6686DC", +"}% c #6887DD", +"|% c #6988DD", +"1% c #6A8ADE", +"2% c #6B8BDE", +"3% c #6C8CDE", +"4% c #6E8DDF", +"5% c #6E8CDF", +"6% c #6D8DDF", +"7% c #6C8BDF", +"8% c #6F8DDF", +"9% c #718FDF", +"0% c #7290DF", +"a% c #7391E0", +"b% c #7491E0", +"c% c #7292E1", +"d% c #3959C5", +"e% c #345BC5", +"f% c #315EC8", +"g% c #355BC5", +"h% c #325EC8", +"i% c #315ECB", +"j% c #345DCC", +"k% c #335ECD", +"l% c #345ECD", +"m% c #355FCE", +"n% c #3862D0", +"o% c #3E66D2", +"p% c #456BD5", +"q% c #476CD5", +"r% c #4B6ED7", +"s% c #4B6FD6", +"t% c #4B6FD5", +"u% c #4D71D6", +"v% c #5073D7", +"w% c #5174D7", +"x% c #5275D8", +"y% c #5577D8", +"z% c #5678D8", +"A% c #5779D9", +"B% c #587AD8", +"C% c #597CD9", +"D% c #5B7DD9", +"E% c #5D7FDA", +"F% c #5F80DB", +"G% c #6182DC", +"H% c #6484DC", +"I% c #6585DC", +"J% c #6787DD", +"K% c #6988DE", +"L% c #6B8ADE", +"M% c #6B8ADF", +"N% c #6989DE", +"O% c #6B89DE", +"P% c #6E8BDF", +"Q% c #708CDE", +"R% c #708DDF", +"S% c #708FDF", +"T% c #728EDF", +"U% c #6F8EDD", +"V% c #728EDD", +"W% c #7390DF", +"X% c #7490DF", +"Y% c #335DC8", +"Z% c #3759C5", +"`% c #3859C5", +" & c #335EC8", +".& c #325DCA", +"+& c #345CCB", +"@& c #335DCC", +"#& c #345DCD", +"$& c #355FCD", +"%& c #3861D0", +"&& c #3B64D1", +"*& c #3E65D2", +"=& c #4168D3", +"-& c #456AD5", +";& c #4B6ED5", +">& c #4C6FD4", +",& c #4D70D5", +"'& c #4F72D6", +")& c #5173D6", +"!& c #5375D7", +"~& c #5476D8", +"{& c #5577D7", +"]& c #5477D8", +"^& c #5677D8", +"/& c #5879D9", +"(& c #597AD9", +"_& c #5C7DDA", +":& c #6080DC", +"<& c #6080DB", +"[& c #6181DC", +"}& c #6282DC", +"|& c #6383DD", +"1& c #6484DD", +"2& c #6686DE", +"3& c #6685DE", +"4& c #6786DE", +"5& c #6687DE", +"6& c #6887DE", +"7& c #6987DE", +"8& c #6788DF", +"9& c #6785DF", +"0& c #6B89DF", +"a& c #6C89DF", +"b& c #6F8DDD", +"c& c #6D8CDE", +"d& c #445BBB", +"e& c #3759BE", +"f& c #375AC6", +"g& c #355CC8", +"h& c #345CCA", +"i& c #355ECC", +"j& c #365FCD", +"k& c #3761CE", +"l& c #3A63D0", +"m& c #3D65D1", +"n& c #466AD4", +"o& c #476BD4", +"p& c #486CD3", +"q& c #4A6ED4", +"r& c #4B6ED4", +"s& c #4E71D6", +"t& c #4F71D5", +"u& c #5072D6", +"v& c #5274D7", +"w& c #5273D7", +"x& c #5274D6", +"y& c #5476D7", +"z& c #5779D8", +"A& c #587AD9", +"B& c #5A7CDA", +"C& c #5C7DDB", +"D& c #5D7EDA", +"E& c #6081DA", +"F& c #6181DB", +"G& c #6283DC", +"H& c #6483DD", +"I& c #6483DE", +"J& c #6585DE", +"K& c #6786DF", +"L& c #6886DE", +"M& c #6887DF", +"N& c #6987DF", +"O& c #6A88DF", +"P& c #6786E0", +"Q& c #6A86DE", +"R& c #6B89E0", +"S& c #365BC8", +"T& c #365CC8", +"U& c #375DCA", +"V& c #375FCB", +"W& c #3860CD", +"X& c #3C63D0", +"Y& c #4167D2", +"Z& c #4268D2", +"`& c #4368D2", +" * c #4367D2", +".* c #4568D2", +"+* c #466AD2", +"@* c #496CD3", +"#* c #4A6DD3", +"$* c #4A6DD4", +"%* c #4D70D4", +"&* c #4F72D5", +"** c #4C70D4", +"=* c #4E72D5", +"-* c #5173D5", +";* c #5375D6", +">* c #597BDA", +",* c #5B7DDA", +"'* c #5C7EDB", +")* c #5D7FDB", +"!* c #5E80DB", +"~* c #5E81DA", +"{* c #5F81DB", +"]* c #5F82DB", +"^* c #6384DD", +"/* c #6384DE", +"(* c #6585DF", +"_* c #6486E0", +":* c #6583DD", +"<* c #6386E0", +"[* c #6686E0", +"}* c #6B86DD", +"|* c #6D86DD", +"1* c #6086E0", +"2* c #5573CD", +"3* c #3959C3", +"4* c #3959C4", +"5* c #3759C0", +"6* c #375BC7", +"7* c #365CC7", +"8* c #395FCC", +"9* c #3B62CE", +"0* c #3E64D0", +"a* c #4066D1", +"b* c #4166D1", +"c* c #4064CF", +"d* c #4065CF", +"e* c #4266D0", +"f* c #4468D1", +"g* c #4569D1", +"h* c #476BD2", +"i* c #466AD1", +"j* c #476AD2", +"k* c #456AD1", +"l* c #496DD2", +"m* c #4A6FD3", +"n* c #496ED2", +"o* c #4B70D4", +"p* c #4D71D4", +"q* c #4E72D4", +"r* c #5073D4", +"s* c #5174D5", +"t* c #5175D5", +"u* c #5276D6", +"v* c #5377D6", +"w* c #5478D7", +"x* c #5579D7", +"y* c #567AD8", +"z* c #577BD9", +"A* c #597CD8", +"B* c #5A7DD9", +"C* c #5A7ED9", +"D* c #5B7FDA", +"E* c #5C80DA", +"F* c #5D80DA", +"G* c #5E81DB", +"H* c #5D80DB", +"I* c #6082DC", +"J* c #6183DD", +"K* c #6183DE", +"L* c #6082DB", +"M* c #6282DE", +"N* c #6682DE", +"O* c #6583DE", +"P* c #3759BF", +"Q* c #375AC2", +"R* c #375AC1", +"S* c #375AC4", +"T* c #395DCA", +"U* c #3A5ECA", +"V* c #3C60CC", +"W* c #3D61CD", +"X* c #3D61CC", +"Y* c #3C61CD", +"Z* c #3E62CD", +"`* c #3F64CE", +" = c #4266CF", +".= c #4468D0", +"+= c #4267CF", +"@= c #4166CE", +"#= c #4065CE", +"$= c #4166CD", +"%= c #4267CE", +"&= c #456AD0", +"*= c #4368CE", +"== c #4468CF", +"-= c #4569D0", +";= c #486BD1", +">= c #4B6FD3", +",= c #4C70D3", +"'= c #4F73D4", +")= c #5275D5", +"!= c #5477D6", +"~= c #577BD7", +"{= c #587CD8", +"]= c #577CD8", +"^= c #597DD9", +"/= c #5A7DDA", +"(= c #597DDA", +"_= c #587CDA", +":= c #5A7EDA", +"<= c #567BD8", +"[= c #557AD9", +"}= c #567BD9", +"|= c #577CD9", +"1= c #587DD9", +"2= c #587ED9", +"3= c #577ED8", +"4= c #587DD8", +"5= c #587ED8", +"6= c #567ED7", +"7= c #526ABD", +"8= c #3759C1", +"9= c #385BC7", +"0= c #395CC8", +"a= c #3B5DC9", +"b= c #3B5ECA", +"c= c #3A5FCA", +"d= c #3B60CC", +"e= c #3C61CC", +"f= c #3D62CD", +"g= c #3E63CD", +"h= c #3C61CB", +"i= c #3C61CA", +"j= c #3D62CB", +"k= c #3F64CC", +"l= c #4065CD", +"m= c #4669D0", +"n= c #476AD0", +"o= c #496BD1", +"p= c #4A6DD2", +"q= c #4B6ED2", +"r= c #4D71D3", +"s= c #4E73D4", +"t= c #4F74D4", +"u= c #5075D5", +"v= c #5276D5", +"w= c #5377D7", +"x= c #5278D7", +"y= c #5277D6", +"z= c #5378D7", +"A= c #5379D8", +"B= c #5379D9", +"C= c #5278D8", +"D= c #5178D7", +"E= c #3355C0", +"F= c #3556C1", +"G= c #395AC6", +"H= c #385AC7", +"I= c #395BC7", +"J= c #395EC9", +"K= c #395FCA", +"L= c #3B60CA", +"M= c #3B60CB", +"N= c #375DC7", +"O= c #385EC8", +"P= c #395FC9", +"Q= c #3A60CA", +"R= c #3D63CC", +"S= c #4367CF", +"T= c #476BD1", +"U= c #4A6ED2", +"V= c #4B6FD2", +"W= c #4C6FD2", +"X= c #4D70D1", +"Y= c #4E71D2", +"Z= c #4E72D2", +"`= c #4E74D4", +" - c #4E75D5", +".- c #4E75D4", +"+- c #4F75D3", +"@- c #5075D2", +"#- c #5075D3", +"$- c #5177D7", +"%- c #5178D8", +"&- c #4F75D5", +"*- c #5076D5", +"=- c #4F76D6", +"-- c #5279D9", +";- c #3C52B1", +">- c #3656C3", +",- c #3757C5", +"'- c #3758C6", +")- c #3759C6", +"!- c #375BC6", +"~- c #385CC7", +"{- c #385DC8", +"]- c #365CC6", +"^- c #355BC6", +"/- c #355CC6", +"(- c #365DC7", +"_- c #375EC8", +":- c #375CC6", +"<- c #385EC6", +"[- c #3A5FC7", +"}- c #3C60C8", +"|- c #3D61C9", +"1- c #3E62CA", +"2- c #4063CC", +"3- c #4165CE", +"4- c #4268D0", +"5- c #4269D1", +"6- c #436AD2", +"7- c #446AD2", +"8- c #456BD2", +"9- c #496CD1", +"0- c #4C6CD0", +"a- c #4D6CCF", +"b- c #4E6DD0", +"c- c #4F6ECF", +"d- c #4E6FCF", +"e- c #4C70CF", +"f- c #4A71D0", +"g- c #4F6FCF", +"h- c #4B71D0", +"i- c #4A72D1", +"j- c #4B73D4", +"k- c #4F70D0", +"l- c #4C73D3", +"m- c #4C73D6", +"n- c #4B72D2", +"o- c #4B71D1", +"p- c #4C73D7", +"q- c #3354C0", +"r- c #3152BE", +"s- c #3052BE", +"t- c #3051BF", +"u- c #2E4FBF", +"v- c #2E4FBE", +"w- c #2E50BF", +"x- c #2F50BF", +"y- c #3156C4", +"z- c #2F56C5", +"A- c #2E57C5", +"B- c #2F57C5", +"C- c #3057C6", +"D- c #3258C6", +"E- c #3459C7", +"F- c #365AC7", +"G- c #385BC8", +"H- c #3B5DCA", +"I- c #3B5DCB", +"J- c #3C5ECC", +"K- c #3C60CD", +"L- c #3C62CE", +"M- c #3D65D0", +"N- c #3D66D1", +"O- c #4166D2", +"P- c #4667D2", +"Q- c #4A67D1", +"R- c #4C68D0", +"S- c #4C69CF", +"T- c #4D6BCE", +"U- c #4E6DCD", +"V- c #4E6ECE", +"W- c #4E6DCE", +"X- c #4970D0", +"Y- c #4770D0", +"Z- c #4B6BCE", +"`- c #4A6CCE", +" ; c #496DCF", +".; c #476FD0", +"+; c #4870D0", +"@; c #486DCF", +"#; c #242F79", +"$; c #2F41AC", +"%; c #2040B8", +"&; c #2041B8", +"*; c #2243B3", +"=; c #2243B8", +"-; c #2343B8", +";; c #2444B8", +">; c #2445B8", +",; c #2445B6", +"'; c #2445B7", +"); c #2444B9", +"!; c #2949BE", +"~; c #2649BF", +"{; c #234BBF", +"]; c #224CBF", +"^; c #224AC0", +"/; c #244CC0", +"(; c #254DC0", +"_; c #254DC1", +":; c #264DC2", +"<; c #274EC3", +"[; c #274CC3", +"}; c #274DC4", +"|; c #254DC5", +"1; c #214EC5", +"2; c #204FC6", +"3; c #1F50C8", +"4; c #2151C9", +"5; c #2B53C8", +"6; c #3154C7", +"7; c #3255C6", +"8; c #2F57C7", +"9; c #2C58C9", +"0; c #2D59CA", +"a; c #2D58C9", +"b; c #2E5BCC", +"c; c #325ECC", +"d; c #325ECB", +"e; c #1F40B1", +"f; c #1F40B2", +"g; c #1F40B3", +"h; c #2A44BD", +"i; c #2845BE", +"j; c #2745BE", +"k; c #2646BF", +"l; c #2546BE", +"m; c #2347BF", +"n; c #2147BF", +"o; c #2048C0", +"p; c #1D48C0", +"q; c #1C48C0", +"r; c #1B47C0", +"s; c #1C48BF", +"t; c #1E49BE", +"u; c #214ABD", +"v; c #244CBD", +"w; c #264DBE", +"x; c #254EC0", +"y; c #214FC2", +"z; c #1B51C5", +"A; c #1C51C7", +"B; c #2250C8", +"C; c #2A52C8", +"D; c #3254C6", +"E; c #3355C5", +"F; c #3154C8", +"G; c #3355C6", +"H; c #2F57C8", +"I; c #2E58C9", +"J; c #2E59C9", +"K; c #3059C9", +"L; c #2040B6", +"M; c #2743BB", +"N; c #2844BC", +"O; c #2743BD", +"P; c #2844BE", +"Q; c #2844BD", +"R; c #2346BE", +"S; c #2047BF", +"T; c #1E48C0", +"U; c #1D47C0", +"V; c #1D49BF", +"W; c #1F49BF", +"X; c #204ABE", +"Y; c #254DBF", +"Z; c #234EC0", +"`; c #2050C1", +" > c #1C51C3", +".> c #1F51C6", +"+> c #2651C8", +"@> c #2D53C7", +"#> c #3155C6", +"$> c #3155C7", +"%> c #3355C7", +"&> c #3254C7", +"*> c #1E40B1", +"=> c #2141B8", +"-> c #2442B9", +";> c #2744BB", +">> c #2945BB", +",> c #2A45BB", +"'> c #2944BA", +")> c #2745BB", +"!> c #2545BC", +"~> c #2246BD", +"{> c #2047BE", +"]> c #1F47BD", +"^> c #1D48BE", +"/> c #1E49C0", +"(> c #1F4AC0", +"_> c #214BBF", +":> c #244CBE", +"<> c #254DBE", +"[> c #244DBE", +"}> c #224FBF", +"|> c #2051C1", +"1> c #2151C3", +"2> c #2252C5", +"3> c #2151C1", +"4> c #2851C6", +"5> c #2A50C6", +"6> c #2E54C6", +"7> c #1F51C2", +"8> c #1D52C5", +"9> c #2651C9", +"0> c #2950C7", +"a> c #2D40A5", +"b> c #2040B0", +"c> c #1F40B0", +"d> c #223CAE", +"e> c #233CAE", +"f> c #253BAC", +"g> c #253BAD", +"h> c #233CB0", +"i> c #213EB2", +"j> c #1F3FB4", +"k> c #1E40B6", +"l> c #1F3FB7", +"m> c #1E3EB8", +"n> c #1F3FB8", +"o> c #2040B7", +"p> c #2141B6", +"q> c #2140B7", +"r> c #2241B6", +"s> c #2342B5", +"t> c #2442B6", +"u> c #2543B5", +"v> c #2643B4", +"w> c #2544B6", +"x> c #2346B8", +"y> c #2247B9", +"z> c #2048BC", +"A> c #1F48BF", +"B> c #2049C0", +"C> c #214AC0", +"D> c #224BBF", +"E> c #234CBE", +"F> c #244DBF", +"G> c #234CBF", +"H> c #264DC0", +"I> c #274EBF", +"J> c #264DBF", +"K> c #254EBF", +"L> c #2050C0", +"M> c #1F51C1", +"N> c #1E42A4", +"O> c #263BA6", +"P> c #253BA7", +"Q> c #253CA7", +"R> c #1E41A5", +"S> c #1F40AF", +"T> c #273AAC", +"U> c #1E40B0", +"V> c #1F40B5", +"W> c #1F40B6", +"X> c #1F40B8", +"Y> c #1E40B8", +"Z> c #1F3EB8", +"`> c #203FB7", +" , c #2240B6", +"., c #2341B7", +"+, c #2345B9", +"@, c #2147BB", +"#, c #2148BA", +"$, c #2049BB", +"%, c #2049BD", +"&, c #2049BF", +"*, c #224BBE", +"=, c #244DBD", +"-, c #244CBF", +";, c #182969", +">, c #273BAD", +",, c #2739AB", +"', c #263AAC", +"), c #243CAE", +"!, c #233DAE", +"~, c #213EAF", +"{, c #1F3FB0", +"], c #2040B4", +"^, c #1F3FB6", +"/, c #1E3EB7", +"(, c #2240B7", +"_, c #2341B6", +":, c #2543B4", +"<, c #2644B3", +"[, c #2544B5", +"}, c #2545B5", +"|, c #2547B6", +"1, c #2548B7", +"2, c #2349BA", +"3, c #1F49BE", +"4, c #2149BD", +"5, c #2049BE", +"6, c #214BBE", +"7, c #2249BE", +"8, c #234CBD", +"9, c #2149BE", +"0, c #1E49BF", +"a, c #253BA9", +"b, c #253BAB", +"c, c #263AAB", +"d, c #213DAF", +"e, c #203EAF", +"f, c #1D40AF", +"g, c #1D40B0", +"h, c #1E40B4", +"i, c #2241B7", +"j, c #2643B6", +"k, c #2744B5", +"l, c #2643B5", +"m, c #2346B6", +"n, c #2147B7", +"o, c #2644B6", +"p, c #2247B7", +"q, c #2248B8", +"r, c #2647B7", +"s, c #2549B7", +"t, c #2645B7", +"u, c #2148B8", +"v, c #2847B6", +"w, c #2549B6", +"x, c #2849B6", +"y, c #2049B7", +"z, c #2A49B5", +"A, c #243BA4", +"B, c #253BA5", +"C, c #253BA6", +"D, c #263AA7", +"E, c #263AA8", +"F, c #2739AA", +"G, c #243CAD", +"H, c #223DAE", +"I, c #1F3EAF", +"J, c #1E3FB0", +"K, c #1D40B1", +"L, c #1E3FB1", +"M, c #1F3FB3", +"N, c #1F3FB5", +"O, c #2140B6", +"P, c #2140B8", +"Q, c #2744B4", +"R, c #2746B6", +"S, c #2947B6", +"T, c #2946B5", +"U, c #2A48B6", +"V, c #3551A8", +"W, c #1F399C", +"X, c #143D9F", +"Y, c #263BA5", +"Z, c #273BA8", +"`, c #273BAA", +" ' c #263AAD", +".' c #233CAD", +"+' c #213DAE", +"@' c #203FB2", +"#' c #2342B6", +"$' c #2443B6", +"%' c #2543B6", +"&' c #2644B5", +"*' c #133D9E", +"=' c #263BA7", +"-' c #263BA9", +";' c #273BA9", +">' c #263AAA", +",' c #2539AB", +"'' c #2639AB", +")' c #253AAC", +"!' c #243BAD", +"~' c #223DAF", +"{' c #203FB0", +"]' c #2040B1", +"^' c #2140B3", +"/' c #2543B1", +"(' c #2744AF", +"_' c #1A3CA0", +":' c #1D3BA2", +"<' c #233BA4", +"[' c #263AA5", +"}' c #253AA5", +"|' c #263AA6", +"1' c #263BA4", +"2' c #243BA5", +"3' c #263BA8", +"4' c #223EAF", +"5' c #3B4CA5", +"6' c #1D379A", +"7' c #1E389C", +"8' c #1E399F", +"9' c #1F3BA2", +"0' c #1F3BA3", +"a' c #213BA4", +"b' c #233AA3", +"c' c #243AA3", +"d' c #2539A4", +"e' c #253AA6", +"f' c #243BA7", +"g' c #253CAA", +"h' c #253CAC", +"i' c #253CAD", +"j' c #253CAE", +"k' c #243DAE", +"l' c #213FAF", +"m' c #223FAF", +"n' c #2040AF", +"o' c #253D93", +"p' c #1D3894", +"q' c #1F379A", +"r' c #1E389B", +"s' c #1D399C", +"t' c #1C3A9D", +"u' c #1B3A9D", +"v' c #183B9E", +"w' c #163C9E", +"x' c #153C9E", +"y' c #163B9D", +"z' c #173B9D", +"A' c #193A9D", +"B' c #1C3A9E", +"C' c #1F3AA1", +"D' c #223AA4", +"E' c #253BA8", +"F' c #273BA7", +"G' c #263CAB", +"H' c #263CAC", +"I' c #243EAE", +"J' c #273BAC", +"K' c #2A3795", +"L' c #1F389B", +"M' c #1D389B", +"N' c #1C399C", +"O' c #1B399C", +"P' c #1A3A9D", +"Q' c #1D399B", +"R' c #1B399B", +"S' c #1A3A9C", +"T' c #1B3A9F", +"U' c #1D3AA0", +"V' c #203BA2", +"W' c #203BA3", +"X' c #2639A6", +"Y' c #1B3692", +"Z' c #1C3794", +"`' c #1D3796", +" ) c #1E3898", +".) c #1E389A", +"+) c #1F399B", +"@) c #1A399C", +"#) c #193A9E", +"$) c #1A3BA0", +"%) c #1C3BA2", +"&) c #1D3CA3", +"*) c #203CA4", +"=) c #223BA5", +"-) c #3C4699", +";) c #2B4595", +">) c #1C3793", +",) c #1D3895", +"') c #1E3897", +")) c #1F3998", +"!) c #1F3999", +"~) c #1F399A", +"{) c #1E399C", +"]) c #1C3B9E", +"^) c #1D3BA0", +"/) c #1E3CA2", +"() c #223CA5", +"_) c #243CA6", +":) c #596FA9", +"<) c #3B4894", +"[) c #314993", +"}) c #29499F", +"|) c #28489E", +"1) c #2B4BA1", +"2) c #2C4BA1", +"3) c #2D4CA2", +"4) c #2E4CA3", +"5) c #2F4CA4", +"6) c #2E4CA4", +"7) c #2F4DA3", +"8) c #2F4DA4", +"9) c #D3D5D2", +"0) c #3B4794", +"a) c #314791", +"b) c #304892", +"c) c #304893", +"d) c #2F4995", +"e) c #2F4997", +"f) c #2D4A9A", +"g) c #2A4A9D", +"h) c #294A9F", +"i) c #284AA0", +"j) c #294AA0", +"k) c #2B4AA1", +"l) c #2D4CA3", +"m) c #C9CAC9", +"n) c #455D9B", +"o) c #242F78", +"p) c #1B2F85", +"q) c #C6C3C8", +"r) c #B5B2B6", +"s) c #B5B7B4", +"t) c #B5B7B3", +"u) c #B5B2B5", +"v) c #B5B3B4", +"w) c #B5B5B4", +"x) c #B5B6B3", +"y) c #B5B4B4", +"z) c #B5B3B5", +"A) c #B5B4B5", +"B) c #B5B5B5", +"C) c #B5B5B3", +"D) c #B5B5B6", +"E) c #BAC3BE", +"F) c #B9C3BD", +"G) c #C1C3C4", +"H) c #BFC3C2", +"I) c #B9C3BE", +"J) c #BBC3BF", +"K) c #BDC3C1", +"L) c #C0C3C3", +"M) c #BEC3C1", +"N) c #C2C3C5", +"O) c #E6E3E8", +"P) c #E0E2DF", +"Q) c #E1E1E1", +"R) c #E2E1E3", +"S) c #E4E1E6", +"T) c #E4E2E7", +"U) c #E4E2E6", +"V) c #E3E3E4", +"W) c #E2E3E3", +"X) c #E1E3E2", +"Y) c #E3E3E3", +"Z) c #E3E3E2", +"`) c #EBEDEA", +" ! c #EAECE9", +".! c #E9EBE8", +"+! c #ECEEEB", +". . + @ # $ $ $ $ $ $ $ % $ $ $ $ $ % $ $ $ $ $ $ % $ $ $ $ $ % $ $ $ $ $ $ $ $ $ % $ $ & * = - ; > , , ' ) ! ! ~ { ] ^ / ( _ : < [ } | | 1 2 3 3 4 4 4 4 4 4 4 5 6 4 4 4 5 6 7 8 9 4 5 6 7 8 9 6 7 8 9 ", +"0 a b % $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ c d d d d $ $ $ $ $ c d e f g h i i i i j k l m n o p q r s t u v w x y z 4 A B C D 9 9 E 9 E F G H I F J K L L L L J K L L L L L L L L ", +"@ % M N O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O P Q R S T U V W X Y Z ` ...+.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.b.b.b.b.b.", +"c.$ d.O e.f.g.g.g.h.g.g.g.g.g.h.h.g.g.g.g.g.h.h.g.g.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +.+++@+#+$+@+$+%+&+*+=+$+-+;+>+,+'+)+!+;+>+,+~+,+>+,+~+,+", +"$ {+N N f.f.f.f.h.h.h.g.f.f.h.h.h.h.g.f.f.h.h.h.h.]+^+/+(+h._+:+<+[+}+|+1+2+3+4+5+6+7+8+9+0+a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+r+s+t+u+v+w+x+y+z+A+B+.+C+D+E+D+F+G+H+C+I+F+G+J+K+L+H+F+G+J+K+L+H+J+H+J+H+", +"{+{+N N M+M+h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.N+N+h.h.(+O+P+P+Q+R+S+T+U+V+W+X+Y+Z+`+ @.@+@@@#@$@%@&@*@=@-@;@>@,@'@)@!@~@{@]@^@/@(@_@:@<@[@[@y+}@|@1@A+1@2@3@ +2@4@2@5@C+D+6@D+7@5@C+D+6@I+C+D+6@I+", +"{+{+8@N M+M+h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.9@9@0@N+a@b@c@d@e@f@g@h@i@j@k@l@m@n@o@p@q@r@s@t@u@v@w@x@y@z@A@B@q+r+C@D@E@F@G@H@_@I@J@K@<@L@M@N@O@P@Q@R@S@T@A+A+U@V@W@W@A+2@U@V@W@W@U@V@W@W@", +"{+{+8@N f.M+h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.(+(+(+9@9@X@Y@Z@e@`@ #.#+#@###$#%#&#*#=#-#;#>#,#'#)#!#~#{#]#z@^#/#(#p+_#r+:#s+t+<#[#}#|#|#1#_@|#_@_@2#L@3#4#y+y+5#z+z+z+5#z+z+z+z+A+A+A+A+A+", +"{+{+8@8@f.f.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.(+6#7#8#9#0#a#b#c#d#e#f#g#h#i#j#k#l#m#n#o#&@p#q#r#s#t#u#v#w#x#x#y#y#z#A#B#C#D#E#E#F#G#H#F#H#H#u+v+I#J#K#L#J@J@M#N#O#P#M#M#M#N#M#Q#Q#R#", +"$ {+8@e.f.f.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.S#l.7#T#U#V#W#X#Y#Z#`# $f#g###.$+$@$#$$$$@%$&$*$=$-$;$>$,$'$)$!$~$~${$]$^$/$($($_$_$:$<$_$<$[$}$|$|$1$2$2$3$}#4$5$6$7$8$8$9$8$8$8$0$8$", +"$ {+a$e.f.f.h.h.h.h.h.h.h.h.h.b$h.c$c$c$c$c$d$c$c$c$c$c$c$c$c$c$c$e$e$7#f$g$h$i$X#j$k$l$m$n$o$p$q$r$l@s$t$u$v$w$x$y$z$A$B$C$D$E$F$G$G$H$I$J$J$K$K$J$L$L$L$L$L$M$N$O$P$Q$R$S$T$U$1$V$T$W$X$Y$1$V$Y$Z$`$ %", +"$ $ a$a$f.f.b$b$b$b$b$b$b$b$b$b$b$b$b$b$b$b$b$b$.%b$b$b$.%d$+%+%@%h.e$l.#%$%h$%%&%*%=%-%;%>%,%'%)%!% @ @~%{%]%^%/%(%w$_%:%<%[%}%|%D$1%2%3%4%5%4%4%6%5%5%4%4%4%5%7%5%8%9%L$0%a%a%a%P$b%P$P$z#z#z#P$c%c%c%", +"$ $ 8@e.f.f.d%b$b$b$b$b$d%b$b$b$b$b$b$e%f%b$b$b$b$b$g%h%b$.%i%i%j%k%l%m%X@n%h$o%&%p%q%`#r%s%t%u%v%w%x%y% @z%A%B%C%D%E%F%G%:%H%I%[%J%}%K%|%D$K%D$D$L%M%M%M%M%M%D$N%O%i+P%j+Q%R%S%T%0%U%V%W%W%W%W%X%X%X%X%", +"$ $ 8@8@f.f.d%d%b$b$b$b$d%d%b$b$b$h%Y%Z%Z%h%f%f%h%Y%`%`% &h%h%.&+&@&#&$&X@%&&&*&=&-&j$Z#+#;&>&,&'&)&)&!&~&{&]&^&/&(&^%_&(%:&<&[&}&|&1&A$A$2&3&4&4&5&B$6&7&B$7&8&9&6&7&0&a&a&i+i+i+b&a&a&j+U%c&U%j+U%c&U%", +"$ $ 8@8@d&e&d%d%d%d%d%d%d%d%d%d%d%`%d%d%d%d%`%`%`%d%d%d%d%`%`%f&g&h&j%i&j&k&l&m&=&X#Y#n&o&p&q&r&>&s&t&t&u&v&w&x&y&{&z&A&B&C&D&(%(%F%F%E&F&}&}&|&G&|&H&1&I%I&A$1&}&z$z$J&K&L&M&N&O&0&P&Q&0&a&R&a&a&a&R&a&", +"{+$ 8@8@e&e&d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%`%f&S&T&U&V&W&Y@X&Y&Z&`& *.*+*@*#*@*r&$*#*r&%*&***=*-*;*y&z%A%z&A&A&>*B&,*,*'*)*!*!*~*{*F&}&{*}&{*]*G%G%y$^*/*J&(*2&_*:*<*=$[*}*<*=$<*|*1*", +"{+{+8@2*e&e&d%d%d%d%d%d%d%d%d%e&3*4*4*4*4*4*5*4*4*4*4*4*4*4*4*4*`%f&6*6*7*8*9*0*a*b*c*d*e*f*g*h*i*j*+*k*h*l*m*n*m*o*p*q*r*s*t*u*v*w*x*y*y*z*A*B*C*D*E*F*G*E*G*F*H*G*F*~*]*{*I*x$J*K*L*G%K*M*o#o#I&N*O*O*", +"{+{+8@2*e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&P*e&e&e&e&e&e&P*P*e&e&e&P*P*5*Q*R*S*T*U*V*W*X*Y*Z*`*d* =.=+=@=#=$=%=g@&=*===-=i*;=l*>=,=q*'=s*)=k@!=x*~={=]=^=/=(=_=:=(=<=<=]=[=}=|=]=]=1=2=3=|=4=5=2=2=2=3=6=6=6=", +"{+{+7=e.e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&P*P*8=9=0=a=b=U*c=d=e=f=e@#=g=h=i=i=j=k=k=l=%===m=n=o=p=q=,=r=s=t=u=v=v*w=x=x=y=z=z=A=z=A=B=C=B=D=C=B=x=B=B=B=B=B=B=B=B=B=B=B=B=B=B=", +"{+{+7=7=e&e&e&e&E=E=e&e&e&e&E=E=E=e&e&e&e&E=E=E=e&e&e&e&E=E=e&e&e&e&E=E=E=F=d%G=G=H=I=J=K=L=M=R+}+N=O=P=Q=j=i=h=R=e@@=S=-=T=h@l*U=V=W=X=Y=Z=`= - - -.-+-@- -#-$-%-$-&-*-$-=-%-----C=$-%---------B=B=B=B=", +"{+{+7=7=;-;-E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=>-,-'-)-!-6*~-{-{-]-^-/-/-(-_-:-N=<-[-}-|-1-2-3- =4-5-6-7-8-9-0-0-a-b-c-d-e-f-g-h-h-i-j-k-h-h-i-j-l-m-n-o-i-j-l-m-n-j-l-p-n-", +"{+{+7=7=;-;-E=E=E=E=E=E=E=E=q-r-s-t-t-u-u-v-v-v-u-w-x-u-u-u-u-u-u-u-u-v-v-u-u-u-u-u-v-v-u-u-u-u-v-v-u-y-z-A-B-C-D-E-E-F-G-H-I-J-K-L-M-N-O-P-Q-R-S-T-U-U-V-W-V-e-X-Y-Z-`- ;.;Y-N N +;@;.;Y-N N N N N N N ", +"#;#;d&d&$;$;%;%;%;%;%;%;%;%;&;*;=;-;-;-;;;>;,;>;>;>;;;>;>;>;>;>;>;>;>;>;';);>;>;>;>;>;';>;>;>;>;>;';);!;~;{;];^;/;(;_;_;:;<;[;};};|;1;2;3;4;5;6;7;8;9;9;0;a;0;0;b;h.a;0;0;b;h.c;h.d;0;b;h.c;h.d;h.c;h.d;", +"#;#;;-;-$;$;e;e;e;e;e;e;e;e;e;e;e;f;f;f;f;e;e;e;f;f;f;f;f;f;f;f;f;f;f;f;g;%;f;f;f;f;f;g;f;f;f;f;f;g;%;h;i;j;k;l;m;n;o;p;q;r;r;s;t;u;v;w;x;y;z;A;B;C;6;D;E;F;G;G;H;I;F;G;G;H;I;J;J;K;G;H;I;J;J;K;I;J;J;K;", +"#;#;;-;-$;$;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;L;e;e;e;e;e;e;e;e;e;e;e;e;L;M;N;O;P;Q;i;i;k;R;S;T;U;q;q;V;W;X;{;Y;Z;`; >.>+>@>#>+>$>6;#>#>+>%>&>G;G;G;G;G;&>G;G;G;G;G;G;G;G;G;", +"#;#;d.;-$;$;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;*>e;e;e;e;e;e;e;e;e;e;e;e;*>=>->;>>>,>'>'>)>!>~>{>]>^>^>V;V;/>(>_>:><>[>}>|>1>2>3>2>4>5>6>7>8>9>0>G;G;G;G;9>0>G;G;G;G;G;G;G;G;", +"#;#;d.d.a>a>e;e;e;e;e;e;e;e;e;e;b>b>c>c>c>c>c>b>e;e;e;e;e;e;e;e;e;e;e;e;e;e;d>e>f>g>h>i>j>k>l>l>m>m>n>n>o>o>p>q>r>r>s>t>u>v>v>u>w>';x>y>z>t;A>B>C>D>E>E>F>G>F>H>H>I>F>Y;J>w;K>L>K>M>J>w;K>L>K>M>K>L>K>M>", +"#;#;d.d.a>a>N>e;N>O>O>O>N>e;N>O>O>P>Q>R>S>R>Q>O>O>O>N>e;N>O>O>O>N>e;N>N>O>T>e;e;e;U>U>U>U>f;V>W>o>o>o>o>X>X>Y>Y>n>n>Z>Z>`> ,.,t>t>u>u>w>+,@,#,$,%,A>&,*,=,B>[>-,w;<>C>[>-,w;w;w;w;w;-,w;w;w;w;w;w;w;w;w;", +"#;;,;-;-a>a>N>N>N>O>O>O>N>N>N>O>O>O>O>N>N>N>O>O>O>O>N>N>N>O>O>O>N>N>N>N>O>>,,,,,,,',g>),!,~,{,{,*>U>e;f;],o>%;o>^,^,/,/,l>q>(,_,t>u>:,<,v>[,},|,1,2,%,%,3,4,5,6,7,8,9,5,6,0,G>G>Y;G>6,0,G>G>Y;G>G>G>Y;G>", +";,;,;-;-O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>P>a,b,',',c,c,f>),e>d,e,{,{,U>U>f,f,U>U>g,g,*>g;h,^,^,`>`>q>i,t>j,k,k,l,w>m,n,o,p,q,r,s,t,p,u,v,w,x,y,z,u,v,w,x,y,z,w,x,y,z,", +";,;,b b O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>A,A,A,B,C,D,E,F,c,',g>G,!,H,~,e,{,I,J,J,K,K,U>f,f,J,L,M,N,L;O,i,P,.,l,Q,k,k,k,k,k,k,R,v,k,k,k,R,v,S,T,U,k,R,v,S,T,U,v,S,T,U,", +";,;,b V,W,W,X,X,O>X,X,X,X,X,O>X,X,X,X,X,X,O>X,X,X,X,X,X,O>X,X,X,X,X,O>X,X,O>O>O>O>B,B,B,B,Y,O>O>Z,`,T>T> '',g>.'+'e,{,{,e,+'+'e,e,{,J,K,e;@'N,O,#'$'%'%'j,%'j,&'k,k,%'j,&'k,k,k,k,k,&'k,k,k,k,k,k,k,k,k,", +";,;,b V,W,W,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,*'O>O>O>O>O>O>O>O>B,B,A,A,B,C,='-'`,;'>'>',''')'!'!'e>e>~'~'~,~,{'{,*>*>e;]']']']']']'^'/']']']'^'/':,(':,]'^'/':,(':,/':,(':,", +";,;,V,V,W,W,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,_':'<'['}'|'|'O>O>O>O>O>O>O>Y,Y,1'1'B,B,2'2'C,3'-'>'c,)')'!'),4'{'e;]'e;*>*>e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;", +";,;,5'5'W,W,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,W,6'6'6'7'8'9'0'a'b'c'd'd'}'}'O>O>O>O>O>O>O>O>Y,1'1'['['e'e'f'g'h'i'j'k'G,),!,l'j'm'n'b>b>),m'b>e;e;e;e;e;b>e;e;e;e;e;e;e;e;e;", +";,;,b b o'o'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'W,q'q'q'r's't'u'v'w'x'y'z'A'B'C'D'2'2'B,B,O>O>O>O>O>O>O>O>O>O>O>Y,Y,C,C,='='='E'F'3'3'3'G'Z,='F'F'G'H'I'J'F'F'G'H'I'J'G'H'I'J'", +";,;,b b K'K'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'W,W,W,W,W,L'L'q'r'M'N'O'P'u'N's'Q'R'S'A'T'U'C'V'9'0'W'D'}'X'|'O>O>B,B,O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>", +";,;,b b K'K'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'Y'Y'Y'Z'`' ).)+)+)+)W,W,W,W,L'L'q'q'r'r's'M'N'P'@)A'#)$)%)&)*)=)B,|'|'O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>", +"{+;,$ -);)K'p'p'o'p'p'p'p'p'o'p'p'p'p'p'p'o'p'p'p'p'p'p'o'p'p'p'p'p'o'o'p'p'p'p'p'p'p'p'p'p'>)>)Y'Y'>)Z',)')))!)~)+)W,W,W,W,W,W,W,W,W,W,W,L'L'{)s't'])^)/)])/)/)O>()])/)/)O>()O>_)O>/)O>()O>_)O>()O>_)O>", +":);,;,;)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)[)M M M M M M M M M M M M M M M M M M })})|)|)})M M 1)2)3)4)5)6)6)6)7)7)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)", +"9)#;;,;,$ -)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)0)a)a)a)b)c)d)e)f)g)h)i)i)j)j)M M M M M M M M M M M })})})})M k)k)M M k)l)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)", +"+ 9)m)n)$ #;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;o)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)", +"+ + 9)a m)q)r)s)r)s)r)s)r)s)r)r)s)r)s)r)s)r)r)s)r)s)r)s)r)s)r)s)r)s)r)s)r)t)u)v)w)x)x)w)y)z)A)A)B)B)B)B)w)w)C)C)w)w)B)B)B)B)B)w)w)w)w)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)D)B)B)B)B)B)D)B)B)B)D)B)", +". + + 9)9)9)q)E)q)E)q)E)q)E)q)q)E)q)E)q)E)q)q)E)q)E)q)E)q)E)q)E)q)E)q)E)q)F)G)H)E)I)J)K)H)L)L)L)L)L)L)L)H)H)M)M)H)H)L)L)G)L)L)H)H)H)H)L)L)L)L)L)L)L)L)L)L)L)L)L)L)L)L)L)L)L)L)L)N)L)L)L)L)L)N)L)L)L)N)L)", +". . 0 . + O)P)O)P)O)P)O)P)O)P)P)O)P)O)P)O)P)P)O)P)O)P)O)P)O)P)O)P)O)P)O)P)O)Q)R)S)T)U)V)W)X)W)W)V)V)V)V)V)V)V)V)Y)Y)Z)Z)Y)Z)Z)Y)Y)V)V)V)V)V)V)V)V)V)V)V)V)V)V)V)V)V)V)V)V)V)V)V)Y)V)V)V)V)V)Y)V)V)V)Y)V)", +". . . 0 0 0 . 0 0 0 + 0 + 0 + 0 + 0 + 0 + 0 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 0 `) !+ + + .! !`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)+!`)`)`)`)`)+!`)`)`)+!`)"}; + + +static char * listviewhighcornerright_xpm[] = { +"100 46 780 2", +" c None", +". c #6A779D", +"+ c #6C789C", +"@ c #6C789D", +"# c #6B789D", +"$ c #6A779E", +"% c #66759E", +"& c #64749E", +"* c #63749E", +"= c #61739D", +"- c #576D9B", +"; c #556C9C", +"> c #4D679D", +", c #4A649D", +"' c #49629D", +") c #465E9C", +"! c #40579C", +"~ c #3B5394", +"{ c #2C4E97", +"] c #314993", +"^ c #2B4595", +"/ c #1B4296", +"( c #253D93", +"_ c #19418F", +": c #0F3C96", +"< c #42599E", +"[ c #758DC3", +"} c #E8EAE7", +"| c #EEF0ED", +"1 c #FBFBFC", +"2 c #6F7D9B", +"3 c #6F7D9A", +"4 c #6E7B9C", +"5 c #67759E", +"6 c #63739E", +"7 c #62739D", +"8 c #596F9C", +"9 c #4A639D", +"0 c #47609C", +"a c #445B9F", +"b c #3E5697", +"c c #2E509A", +"d c #2D509A", +"e c #2D4F99", +"f c #2D4F98", +"g c #28418A", +"h c #3E51A3", +"i c #D0D3DC", +"j c #A1B6EF", +"k c #A2B6F0", +"l c #A1B6F0", +"m c #A3B6F0", +"n c #A0B6EF", +"o c #9DB6EE", +"p c #9CB5EF", +"q c #9CB2F0", +"r c #9FB5EE", +"s c #9CB4EB", +"t c #9AB3EC", +"u c #9AB0EC", +"v c #9DB3EB", +"w c #9BB4EC", +"x c #9BB4EE", +"y c #9BB1EF", +"z c #9BB0F0", +"A c #90ACF0", +"B c #93ABEE", +"C c #91A8EB", +"D c #8BA3E8", +"E c #88A1E7", +"F c #809DE9", +"G c #7A99E8", +"H c #7491E5", +"I c #698AE4", +"J c #6184E3", +"K c #507EDC", +"L c #4E7CDB", +"M c #4F7DDC", +"N c #5479DA", +"O c #567BDC", +"P c #577CDD", +"Q c #5074DA", +"R c #5174DB", +"S c #5175DC", +"T c #5276DD", +"U c #4D71DE", +"V c #4C72D8", +"W c #3A6CE0", +"X c #2B49A6", +"Y c #E0E2DF", +"Z c #93AAE9", +"` c #94A9E8", +" . c #94AAE9", +".. c #93A9E9", +"+. c #92AAE9", +"@. c #8DA9E8", +"#. c #8CA7E9", +"$. c #92ABE9", +"%. c #8EAAE9", +"&. c #8EA9E9", +"*. c #8FAAE9", +"=. c #8CA8E9", +"-. c #8CA2E7", +";. c #86A1E6", +">. c #839EE9", +",. c #7F9CE9", +"'. c #7A97E8", +"). c #7693E7", +"!. c #6E8EE8", +"~. c #678AE9", +"{. c #5D84E3", +"]. c #577CDF", +"^. c #4E77DF", +"/. c #4A70DB", +"(. c #4870DB", +"_. c #4870DC", +":. c #4770E3", +"<. c #496FDC", +"[. c #486EDB", +"}. c #466FE4", +"|. c #466EE3", +"1. c #4167D9", +"2. c #4066D8", +"3. c #3F66D8", +"4. c #3D64D7", +"5. c #3960DA", +"6. c #476DD9", +"7. c #446EE5", +"8. c #305EC8", +"9. c #8EAAE8", +"0. c #8FAAE8", +"a. c #91AAE9", +"b. c #8FA9E8", +"c. c #8BA8E8", +"d. c #8AA7E9", +"e. c #8BA5EA", +"f. c #8AA7E8", +"g. c #87A2E6", +"h. c #859FE8", +"i. c #7F9DE8", +"j. c #7C9AE8", +"k. c #7B95E7", +"l. c #7090E8", +"m. c #6B8BE9", +"n. c #6386E6", +"o. c #5881E1", +"p. c #5479DE", +"q. c #4D74DE", +"r. c #476EDB", +"s. c #446EE1", +"t. c #446EE0", +"u. c #446EDF", +"v. c #446DE0", +"w. c #426ADF", +"x. c #3C64DA", +"y. c #4360CC", +"z. c #D3D5D2", +"A. c #E6E3E8", +"B. c #8DA2E7", +"C. c #8CA6EA", +"D. c #8DA3E9", +"E. c #88A2E7", +"F. c #87A1E7", +"G. c #8AA1E7", +"H. c #849EE9", +"I. c #7D9AE9", +"J. c #7B98E8", +"K. c #7796E5", +"L. c #7191E7", +"M. c #688CE9", +"N. c #6687E5", +"O. c #5C83E1", +"P. c #557BDE", +"Q. c #4F76DE", +"R. c #4C72DE", +"S. c #456EDF", +"T. c #426AD9", +"U. c #4269D9", +"V. c #4269D8", +"W. c #3D64D9", +"X. c #3A61DA", +"Y. c #345ED6", +"Z. c #335ECF", +"`. c #C6C3C8", +" + c #86A1E7", +".+ c #87A2E7", +"++ c #87A0E7", +"@+ c #859EE8", +"#+ c #849DE9", +"$+ c #7E9BE9", +"%+ c #7A99E9", +"&+ c #7A95E5", +"*+ c #7593E7", +"=+ c #6F8EE9", +"-+ c #668AE5", +";+ c #6386E0", +">+ c #5B82DF", +",+ c #5379DE", +"'+ c #5075DE", +")+ c #4B6FDC", +"!+ c #446AD7", +"~+ c #4269D6", +"{+ c #4269D5", +"]+ c #3E65D7", +"^+ c #C9CAC9", +"/+ c #869EE9", +"(+ c #859FE9", +"_+ c #849FE9", +":+ c #829DE8", +"<+ c #819DE8", +"[+ c #7B9AE9", +"}+ c #7A96E6", +"|+ c #7290E8", +"1+ c #698CE6", +"2+ c #6689E0", +"3+ c #5D84E0", +"4+ c #587FDF", +"5+ c #5377DD", +"6+ c #4B74DE", +"7+ c #496BD8", +"8+ c #7C9BE9", +"9+ c #7E9CE9", +"0+ c #7D9AEA", +"a+ c #7D9BEA", +"b+ c #7D98E8", +"c+ c #7C98E8", +"d+ c #7796E4", +"e+ c #7592E6", +"f+ c #7390E1", +"g+ c #698DE0", +"h+ c #6588DE", +"i+ c #5E84E0", +"j+ c #5880DF", +"k+ c #5479DC", +"l+ c #4F75DE", +"m+ c #4A6FDB", +"n+ c #436AD7", +"o+ c #3F65D7", +"p+ c #BAC3BE", +"q+ c #7B9AE8", +"r+ c #7B9AEA", +"s+ c #7A9AEA", +"t+ c #7B99E9", +"u+ c #7D97E7", +"v+ c #7D95E6", +"w+ c #7D95E5", +"x+ c #7C95E6", +"y+ c #7493E3", +"z+ c #7290DF", +"A+ c #6C8DDE", +"B+ c #6B89E1", +"C+ c #6486DF", +"D+ c #5D81DF", +"E+ c #567DDE", +"F+ c #4F73DE", +"G+ c #496EDA", +"H+ c #355ED6", +"I+ c #345ED5", +"J+ c #7E95E5", +"K+ c #7C97E8", +"L+ c #7C97E7", +"M+ c #7B94E6", +"N+ c #7A95E4", +"O+ c #7695E5", +"P+ c #7694E4", +"Q+ c #7994E6", +"R+ c #7995E4", +"S+ c #7594E4", +"T+ c #7391E2", +"U+ c #6E8EDE", +"V+ c #6B8ADE", +"W+ c #6688DF", +"X+ c #5F84E0", +"Y+ c #5980E0", +"Z+ c #4D72DD", +"`+ c #456BD7", +" @ c #4168D6", +".@ c #3C64D7", +"+@ c #335ED0", +"@@ c #4659C7", +"#@ c #7292E1", +"$@ c #7392E1", +"%@ c #7492E1", +"&@ c #718FDF", +"*@ c #6F8EDE", +"=@ c #6D8BDE", +"-@ c #6B88DF", +";@ c #597FDF", +">@ c #557ADD", +",@ c #5176DC", +"'@ c #4D74DD", +")@ c #496DDA", +"!@ c #3860D8", +"~@ c #7391E0", +"{@ c #7290DE", +"]@ c #6D8EDD", +"^@ c #6D8DDD", +"/@ c #7190E0", +"(@ c #6C8DDD", +"_@ c #6B89DF", +":@ c #6487E0", +"<@ c #6085DF", +"[@ c #5F81DE", +"}@ c #567EDE", +"|@ c #4F74D9", +"1@ c #466BD7", +"2@ c #4067D5", +"3@ c #3C63D7", +"4@ c #335ED3", +"5@ c #335ED1", +"6@ c #718EDD", +"7@ c #728EDD", +"8@ c #748EDD", +"9@ c #708EDD", +"0@ c #6F8DDD", +"a@ c #6E8DDD", +"b@ c #6C8ADE", +"c@ c #6C89DF", +"d@ c #6988DF", +"e@ c #6387DF", +"f@ c #6282DE", +"g@ c #5681E0", +"h@ c #577BDD", +"i@ c #5277DB", +"j@ c #4D73D8", +"k@ c #4A70D8", +"l@ c #436AD5", +"m@ c #3F66D6", +"n@ c #3C63D8", +"o@ c #3960D8", +"p@ c #3860D7", +"q@ c #335ED2", +"r@ c #345ED4", +"s@ c #6C88DF", +"t@ c #6D88DF", +"u@ c #6B89DE", +"v@ c #6888DF", +"w@ c #6587E0", +"x@ c #6989DF", +"y@ c #6687E0", +"z@ c #6287E0", +"A@ c #6281DD", +"B@ c #5881E0", +"C@ c #557ADB", +"D@ c #5176D9", +"E@ c #4E75D7", +"F@ c #4A6FD8", +"G@ c #476BD6", +"H@ c #4067D6", +"I@ c #3C62D7", +"J@ c #3C60D4", +"K@ c #365ED1", +"L@ c #345ED3", +"M@ c #6786DF", +"N@ c #5F85E0", +"O@ c #5F86E0", +"P@ c #6186DF", +"Q@ c #6286E0", +"R@ c #6284DF", +"S@ c #6384DF", +"T@ c #5B7FDE", +"U@ c #577DDC", +"V@ c #557BDA", +"W@ c #5278D8", +"X@ c #4E76D6", +"Y@ c #4C72D7", +"Z@ c #486DD8", +"`@ c #4469D6", +" # c #3F62D2", +".# c #3C60CF", +"+# c #345ECF", +"@# c #6086DF", +"## c #6085E0", +"$# c #6285DF", +"%# c #6383DD", +"&# c #6481DC", +"*# c #6380DD", +"=# c #6183DE", +"-# c #6083DD", +";# c #6081DC", +"># c #6080DD", +",# c #6083DE", +"'# c #6181DC", +")# c #6280DD", +"!# c #577EDB", +"~# c #557CD7", +"{# c #4F76D6", +"]# c #4E74D7", +"^# c #466CD7", +"/# c #3B64D6", +"(# c #4261CD", +"_# c #375FCE", +":# c #5A7FD8", +"<# c #6281DA", +"[# c #5F81D8", +"}# c #5C80D8", +"|# c #557DD7", +"1# c #577ED8", +"2# c #567ED7", +"3# c #587DD8", +"4# c #577DD8", +"5# c #587ED8", +"6# c #567DD8", +"7# c #5379D9", +"8# c #5177D7", +"9# c #4D74D5", +"0# c #486ED9", +"a# c #4068D4", +"b# c #3D65D2", +"c# c #4361CC", +"d# c #345ECE", +"e# c #325DCF", +"f# c #2C5AD1", +"g# c #3959C5", +"h# c #547BD8", +"i# c #567DD7", +"j# c #557BD8", +"k# c #5279D9", +"l# c #5278D9", +"m# c #4D74D6", +"n# c #4B71D8", +"o# c #496CD8", +"p# c #4669D7", +"q# c #3D66D3", +"r# c #3F62CF", +"s# c #4260CC", +"t# c #5379D8", +"u# c #4E75D4", +"v# c #4C73D7", +"w# c #476CD7", +"x# c #4869D0", +"y# c #4067D2", +"z# c #3D64D1", +"A# c #4261CC", +"B# c #395FCE", +"C# c #4F75D3", +"D# c #5074D2", +"E# c #5174D1", +"F# c #5175D1", +"G# c #4F74D3", +"H# c #4C73D5", +"I# c #4C73D4", +"J# c #4A72D1", +"K# c #4B70CF", +"L# c #506CCC", +"M# c #4D6BCE", +"N# c #4167D0", +"O# c #3D65D1", +"P# c #3F63CF", +"Q# c #3B5FCD", +"R# c #3159CD", +"S# c #4971D0", +"T# c #4870CF", +"U# c #4C6FCF", +"V# c #4E6CCE", +"W# c #4E6BCE", +"X# c #4769CF", +"Y# c #3D66D0", +"Z# c #3C65D1", +"`# c #4062CE", +" $ c #3D5FCD", +".$ c #365FCF", +"+$ c #325DCD", +"@$ c #2D5AD0", +"#$ c #3859C5", +"$$ c #355FCF", +"%$ c #355ECF", +"&$ c #335ECE", +"*$ c #305CCD", +"=$ c #2B5ACE", +"-$ c #3056C9", +";$ c #2553C6", +">$ c #2153C8", +",$ c #1F4FC7", +"'$ c #274CC5", +")$ c #214AC7", +"!$ c #1C48C8", +"~$ c #1244C9", +"{$ c #1043C9", +"]$ c #1144C9", +"^$ c #2A45BE", +"/$ c #2744B5", +"($ c #1D49C0", +"_$ c #2B58DE", +":$ c #002D94", +"<$ c #2B59CA", +"[$ c #2A59CA", +"}$ c #2E57C8", +"|$ c #3255C6", +"1$ c #3355C5", +"2$ c #1C52C8", +"3$ c #1D50C7", +"4$ c #234FC6", +"5$ c #264CC5", +"6$ c #1D48C7", +"7$ c #1245C8", +"8$ c #1F44C2", +"9$ c #2945BE", +"0$ c #2A45BD", +"a$ c #2040BF", +"b$ c #3156C7", +"c$ c #3056C7", +"d$ c #3354C5", +"e$ c #3355C6", +"f$ c #3255C5", +"g$ c #3254C5", +"h$ c #1952C7", +"i$ c #1951C8", +"j$ c #2050C7", +"k$ c #274CC4", +"l$ c #244CC6", +"m$ c #1F49C7", +"n$ c #1E47C5", +"o$ c #2045C3", +"p$ c #1C44BF", +"q$ c #2045BE", +"r$ c #2040B8", +"s$ c #3254C6", +"t$ c #3055C6", +"u$ c #2A54C6", +"v$ c #2353C7", +"w$ c #3054C5", +"x$ c #2F55C5", +"y$ c #2A54C5", +"z$ c #2553C5", +"A$ c #2F54C5", +"B$ c #3155C6", +"C$ c #2A54C7", +"D$ c #1A52C8", +"E$ c #204FC2", +"F$ c #264DC6", +"G$ c #234BC5", +"H$ c #1D48C1", +"I$ c #1E48BF", +"J$ c #2646BE", +"K$ c #2B45BD", +"L$ c #1E43BE", +"M$ c #2643BF", +"N$ c #2243BF", +"O$ c #3049BC", +"P$ c #1E50BE", +"Q$ c #1D50C0", +"R$ c #1D50BF", +"S$ c #1852C1", +"T$ c #1E51C0", +"U$ c #214FBF", +"V$ c #2050C0", +"W$ c #244EBF", +"X$ c #2151C0", +"Y$ c #234FBF", +"Z$ c #2350C0", +"`$ c #2351C0", +" % c #244FBF", +".% c #2250C0", +"+% c #2051C0", +"@% c #1E50C0", +"#% c #244DBE", +"$% c #274DBF", +"%% c #244CBF", +"&% c #1C48C0", +"*% c #2247BF", +"=% c #2C44BD", +"-% c #1C44BE", +";% c #1444BF", +">% c #1841BF", +",% c #1F40BF", +"'% c #254DBE", +")% c #224FBE", +"!% c #224FBF", +"~% c #234EBF", +"{% c #254CBD", +"]% c #244DBD", +"^% c #244CBD", +"/% c #264DBE", +"(% c #264DBD", +"_% c #214BC0", +":% c #1D48C0", +"<% c #2347BF", +"[% c #2B44BD", +"}% c #2444BE", +"|% c #0F42BF", +"1% c #0641BF", +"2% c #0F41BF", +"3% c #1741BE", +"4% c #1F40BD", +"5% c #234BBF", +"6% c #234CBE", +"7% c #214BBE", +"8% c #244CBE", +"9% c #214ABE", +"0% c #214ABF", +"a% c #1F48C0", +"b% c #2746BE", +"c% c #1F43BE", +"d% c #0941BE", +"e% c #0342BA", +"f% c #0242BC", +"g% c #1241B8", +"h% c #1F40B7", +"i% c #2F41AC", +"j% c #2644AE", +"k% c #2D49B4", +"l% c #2649B6", +"m% c #2949B7", +"n% c #2849B5", +"o% c #2149B8", +"p% c #1E49B9", +"q% c #1F48B8", +"r% c #1F49B9", +"s% c #2545B6", +"t% c #2744B7", +"u% c #2844B7", +"v% c #2043B8", +"w% c #1241B7", +"x% c #1340B8", +"y% c #0D41B8", +"z% c #1941B8", +"A% c #1F40B8", +"B% c #203FB8", +"C% c #2549B5", +"D% c #2648B6", +"E% c #2547B7", +"F% c #2248B7", +"G% c #2048B7", +"H% c #2346B6", +"I% c #2146B6", +"J% c #2247B7", +"K% c #2148B7", +"L% c #2743B4", +"M% c #2643B5", +"N% c #2542B6", +"O% c #1D42B7", +"P% c #0E42B8", +"Q% c #0C41B8", +"R% c #1341B8", +"S% c #1740B8", +"T% c #1C41B8", +"U% c #1F40B1", +"V% c #2644B5", +"W% c #2544B5", +"X% c #2544B4", +"Y% c #2444B5", +"Z% c #2444B4", +"`% c #2744B4", +" & c #2241B7", +".& c #1D41B8", +"+& c #0B42B8", +"@& c #0942B8", +"#& c #0C42B8", +"$& c #0F41B8", +"%& c #1641B8", +"&& c #2442B5", +"*& c #2543B3", +"=& c #2342B2", +"-& c #2341B4", +";& c #2141B3", +">& c #2141B5", +",& c #2140B5", +"'& c #2040B5", +")& c #1C40B7", +"!& c #1B41B3", +"~& c #0142B6", +"{& c #0E41B7", +"]& c #1141B7", +"^& c #1440B2", +"/& c #113FB0", +"(& c #1440B0", +"_& c #213EAF", +":& c #233DAE", +"<& c #223EAF", +"[& c #1E40B1", +"}& c #173EAD", +"|& c #1440AF", +"1& c #0D40AF", +"2& c #0941B0", +"3& c #0D3FAE", +"4& c #1B3CAC", +"5& c #233CAD", +"6& c #203FB0", +"7& c #273BAD", +"8& c #1D40B0", +"9& c #2040B1", +"0& c #1E40B0", +"a& c #1C40B0", +"b& c #1B3DAC", +"c& c #143DAC", +"d& c #193DAD", +"e& c #1B3DAD", +"f& c #173DAD", +"g& c #153DAC", +"h& c #1C3CAC", +"i& c #243CAD", +"j& c #213FB0", +"k& c #263BAA", +"l& c #253CAE", +"m& c #273AAC", +"n& c #273AAD", +"o& c #253BAD", +"p& c #1D3CAC", +"q& c #243BAD", +"r& c #1E3CAC", +"s& c #263BAD", +"t& c #1A3DAC", +"u& c #143DAB", +"v& c #163DAC", +"w& c #1A3CAC", +"x& c #1F3CAD", +"y& c #263BAB", +"z& c #263BA6", +"A& c #1E42A4", +"B& c #2D40A5", +"C& c #253BA6", +"D& c #253CA7", +"E& c #263AA5", +"F& c #253BA7", +"G& c #1E3BA6", +"H& c #193DA6", +"I& c #173DA5", +"J& c #143DA6", +"K& c #1A3DA7", +"L& c #133DA6", +"M& c #123DA5", +"N& c #1A3CA7", +"O& c #243BA6", +"P& c #263AA7", +"Q& c #273BA7", +"R& c #263AA6", +"S& c #223BA6", +"T& c #1D3BA6", +"U& c #173CA6", +"V& c #133DA5", +"W& c #1B3DA6", +"X& c #193DA5", +"Y& c #123DA4", +"Z& c #163CA5", +"`& c #213CA6", +" * c #273BA8", +".* c #263BA7", +"+* c #253BA5", +"@* c #263BA5", +"#* c #1C3BA6", +"$* c #1B3BA9", +"%* c #133BA8", +"&* c #0A3BA7", +"** c #083AA6", +"=* c #123CA5", +"-* c #0839A8", +";* c #0239A6", +">* c #123AA8", +",* c #1F49C8", +"'* c #2F4DA4", +")* c #2E4DA3", +"!* c #384CA4", +"~* c #3C4DA7", +"{* c #394EA7", +"]* c #3B4CA5", +"^* c #3C52B1", +"/* c #3551A8", +"(* c #3759BE", +"_* c #4161C7", +":* c #0033A8", +"<* c #596FA9", +"[* c #2F4DA3", +"}* c #2D4BA5", +"|* c #2E4CA4", +"1* c #2C4AA5", +"2* c #2D4BA4", +"3* c #354DA4", +"4* c #3A4BA4", +"5* c #394DA6", +"6* c #4056AD", +"7* c #445BBB", +"8* c #B5B7B4", +"9* c #1B2F85", +"0* c #242F79", +"a* c #B5B5B5", +"b* c #B5B2B6", +"c* c #C0C3C3", +"d* c #E3E3E4", +"e* c #EBEDEA", +". + @ + # $ % & # $ % & # $ % & # $ % & & * = - ; > , ' ) ! ~ { { { { { { { ] ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ / / / ( / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / _ _ / / : / < [ } | | | 1 1 ", +"2 2 2 2 3 2 4 @ 3 2 4 @ 3 2 4 @ 3 2 4 @ # 5 6 7 8 ; > 9 0 a b c d e f { { { ] ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ( ( ( ( ( ( ( ( ( / / / / / / / / / / / / / / / / / _ _ _ _ _ _ _ _ _ _ _ g g _ / / : : : h i } 1 | 1 ", +"j k l m n o p q n o p q r s t u v w x y z A B C D E F G H I J K L M N O P O O Q R S T T T T T T T T T T T T T T T T T T U U U U U U U U U U U U U U U U U U U U U U U U U U U U V V V U U W X : [ Y | | ", +"Z ` . ...+.@.#...+.@.#.Z $.%.&.Z $.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.6.7.8.: h Y } 1 ", +"9.0.a.b.c.c.d.e.f.c.d.e.f.c.d.e.f.c.d.e.g.h.i.j.k.l.m.n.o.p.q.r.s.s.t.u.u.v.w.x.4.4.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.y.5.7.6.: / z.A.} ", +"-.B.C.D.-.E.g.F.G.E.g.F.G.E.g.F.G.E.g.F.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.V.U.U.W.X.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Z.y.Y.7.7.: : `.z.} ", +" +.+g.;.++F.@+#+++F.@+#+++F.@+#+++F.@+#+$+%+&+*+=+-+;+>+,+'+)+!+~+{+]+{+{+4.4.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.Y.Y.5.5.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Z.Z.Z.y.y.5.7.7.: : ^+z.Y ", +"/+(+_+#+H.H.>.:+H.H.>.:+H.H.>.:+H.H.>.<+[+}+*+|+1+2+3+4+5+6+7+{+{+4.4.4.4.4.4.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.Y.Y.Y.Y.Y.Y.Y.5.Y.Y.Y.Y.Y.Y.Y.Y.5.Y.Y.5.5.5.5.Y.Y.Y.Y.Y.Y.Z.Z.Z.Z.y.y.y.y.y.y.7.7.: : ^+i } ", +"8+9+0+0+a+0+0+b+a+0+0+b+a+0+0+b+a+0+0+c+d+e+f+g+h+i+j+k+l+m+n+o+4.4.4.4.5.5.5.5.5.5.Y.Y.5.5.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Y.Y.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.7.7.: : p+z.Y ", +"q+r+r+s+t+u+v+w+t+u+v+w+t+u+v+w+t+u+x+&+y+z+A+B+C+D+E+5+F+G+~+4.4.4.4.5.5.5.5.5.H+Y.Y.Y.Y.Y.Y.Y.Y.I+Y.Z.Y.Y.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.7.7.: : `.z.A.", +"J+v+K+L+M+N+O+P+Q+R+O+P+Q+R+O+P+Q+R+O+S+T+U+V+W+X+Y+P.T Z+`+ @4.4..@5.5.5.5.5.5.Y.Y.Y.I+I+I+I+I++@+@Z.Z.Y.Y.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.@@Z.7.7.: : p+z.Y ", +"#@$@$@%@%@$@#@&@#@#@#@&@#@#@#@&@#@#@#@*@=@-@;+i+;@>@,@'@)@ @4.X.5.5.H+Y.Y.Y.!@Y.Y.I++@+@Z.Z.+@Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.y.Z.6.6.: : `.z.A.", +"#@$@~@~@~@{@]@^@/@{@]@^@/@{@]@^@/@{@]@(@_@:@<@[@}@k+|@V 1@2@3@5.5.5.Y.Y.I+4@I+5@+@Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.y.Z.6.6.: : p+z.Y ", +"6@7@8@9@0@a@b@c@a@a@b@c@a@a@b@c@a@a@b@d@e@<@f@g@h@i@j@k@l@m@n@o@o@p@Y.I+q@q@r@+@Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.y.Z.6.6.: : `.z.A.", +"s@t@u@_@_@v@w@w@x@v@w@w@x@v@y@y@x@v@:@z@A@B@P C@D@E@F@G@H@I@J@K@5@+@+@+@r@I+L@Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.@@Z.W W : : p+z.Y ", +"M@N@O@P@C+Q@Q@R@C+;+Q@R@C+;+;+S@C+Q@Q@R@T@U@V@W@X@Y@Z@`@4. #.#+#Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.8.Z.Z.Z.Z.8.8.Z.Z.y.@@@@W W : : `.z.A.", +"@#O@O@##$#%#&#*#=#-#;#>#,#-#;#>#,#-#'#)#!#~#W@{#]#k@^#H@/#(#_#Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.8.8.Z.Z.Z.Z.Z.Z.Z.8.8.8.8.8.8.8.8.8.8.8.Z.Z.y.y.@@W W : : p+z.Y ", +":#<#[#}#|#1#2#3#4#5#1#4#4#1#1#4#4#1#1#6#7#8#9#V 0#`+a#b#c#d#e#Z.Z.Z.f#Z.Z.Z.f#f#f#f#f#f#f#f#f#f#g#g#g#g#g#8.8.8.8.8.8.8.8.8.g#g#g#g#8.g#8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.y.y.@@W W : : `.z.A.", +"h#2#i#6#|#j#7#k#|#j#7#7#|#j#7#7#|#j#7#l#8#m#n#n#o#p#q#r#s#d#e#Z.Z.Z.f#f#f#f#Z.f#f#g#g#g#g#g#g#g#g#g#g#g#g#8.8.8.g#g#8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.y.y.y.y.8.8.8.y.y.@@W W : : p+z.Y ", +"l#7#7#l#7#7#7#W@7#7#7#W@7#7#k#W@t#7#7#W@u#v#n#w#x#y#z#A#B#Z.e#f#f#Z.f#f#f#Z.Z.g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#8.8.8.g#g#g#g#8.8.g#g#g#g#g#g#8.8.g#8.8.y.8.8.y.y.8.y.y.y.y.@@W W : : `.z.A.", +"C#D#E#F#G#H#I#J#G#H#I#J#G#H#I#J#G#H#I#J#K#L#M#N#O#P#s#Q#+#f#R#f#f#f#f#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#@@@@y.y.@@@@y.y.W W : : p+z.Y ", +"S#S#S#S#S#T#S#U#S#T#S#U#S#T#S#U#S#T#S#U#V#W#X#Y#Z#`# $.$+$@$#$g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#@@@@@@@@@@@@@@@@@@y.y.W W : : `.z.A.", +"+$Z..$$$%$+$&$*$%$+$&$*$%$+$&$*$%$+$&$*$=$-$;$>$,$'$)$!$~${$]$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$/$/$/$/$($($_$_$:$:$p+z.Y ", +"<$<$<$<$<$[$}$|$<$[$}$|$<$[$}$|$<$[$}$|$1$2$3$4$5$)$6$7$8$9$0$a$a$a$a$a$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$/$/$/$^$^$^$/$/$/$/$/$/$/$/$/$/$/$/$/$/$($($_$_$:$:$`.z.A.", +"b$c$c$c$d$e$e$f$g$|$|$1$d$e$e$1$d$e$e$1$h$i$j$k$l$m$n$o$p$9$q$a$a$a$a$a$a$a$a$^$a$a$^$^$^$^$^$^$a$r$r$r$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$($($_$_$:$:$p+z.Y ", +"e$1$s$s$1$t$u$v$w$x$y$z$A$x$u$v$g$B$C$>$D$E$F$G$H$I$J$K$L$M$N$a$a$a$a$a$a$a$a$^$r$r$a$^$^$^$a$r$r$r$r$r$/$^$r$^$^$^$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$O$($_$_$:$:$`.z.A.", +"P$Q$R$S$T$U$V$W$X$Y$Z$W$`$ %.%W$+%U$@%#%$%%%&%($*%=%-%;%>%>%,%r$r$r$r$r$a$a$a$/$/$/$r$r$r$r$r$r$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$O$($_$_$:$:$p+z.Y ", +"'%W$)%!%~%{%'%]%~%^%'%]%~%^%'%]%~%^%/%(%_%&%:%<%[%}%|%1%2%3%4%r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$/$r$/$/$r$r$r$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$r$/$/$/$/$/$O$($_$_$:$:$`.z.A.", +"5%6%'%'%6%7%8%9%6%7%8%9%6%7%8%9%6%7%8%0%&%a%<%b%[%c%d%e%f%g%h%r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$/$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$/$/$/$/$/$/$/$/$/$/$/$/$/$/$r$r$/$/$r$r$/$r$i%j%O$($_$_$:$:$p+z.Y ", +"k%l%m%n%o%o%p%q%o%o%r%q%o%o%r%q%o%o%p%q%s%t%/$u%v%w%x%y%z%A%B%r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$/$/$/$/$/$/$/$r$r$i%i%i%r$r$i%i%i%i%i%i%i%i%i%i%i%i%r$/$/$j%j%j%j%j%j%j%j%j%O$($_$_$:$:$`.z.A.", +"C%D%E%F%G%H%I%J%K%H%I%J%K%H%I%J%K%H%I%J%L%M%N%O%P%Q%R%S%T%A%B%r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$U%U%r$r$i%i%/$/$r$r$/$/$/$/$r$r$i%i%i%i%i%i%i%i%i%i%i%i%i%i%j%i%j%j%j%j%j%j%j%j%j%j%j%j%j%O$($_$_$:$:$p+z.Y ", +"/$/$/$/$V%V%W%X%W%Y%Y%Z%W%W%Y%Z%W%W%W%`%`% &B%.&+&@&#&$&%&A%B%r$r$r$U%U%U%U%r$U%U%U%U%U%U%U%U%U%U%i%i%i%i%i%i%i%i%/$/$/$i%i%i%i%i%i%i%i%i%j%j%j%j%i%i%i%i%i%j%j%j%i%i%j%j%j%j%j%j%j%j%O$($_$_$:$:$`.z.A.", +"&&*&=&-&=&;&>&,&=&;&>&,&=&;&>&,&=&;&>&'&)&!&~&{&]&^&/&(&_&:&<&U%U%U%U%U%U%U%U%U%U%U%U%U%i%i%U%U%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%O$($_$_$:$:$p+z.Y ", +"U%U%U%U%U%U%U%U%U%U%U%U%U%U%U%U%U%U%U%U%[&}&|&1&2&3&4&5&_&6&U%7&U%U%U%U%U%U%U%U%i%i%U%U%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%O$O$_$_$:$:$`.z.A.", +"U%U%U%U%U%U%[&8&U%9&[&0&U%9&[&0&U%9&[&a&:&b&c&d&e&f&g&h&i&<&j&U%U%U%U%U%U%U%U%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%O$O$_$_$:$:$p+z.Y ", +"k&l&m&7&7&n&o&p&7&n&q&r&s&s&q&r&s&n&o&p&t&u&u&g&v&w&x&q&n&m&y&7&7&U%U%7&z&7&z&U%A&B&i%i%B&B&i%i%B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&i%B&O$O$_$_$:$:$`.z.A.", +"C&D&E&z&z&E&F&G&z&E&F&G&z&E&F&G&z&E&F&G&H&I&J&K&L&M&N&O&P&Q&z&z&z&z&z&z&z&z&z&z&z&z&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&O$O$_$_$:$:$p+z.Y ", +"z&z&z&z&R&S&T&U&R&S&T&U&R&S&T&U&R&S&T&U&V&V&W&X&Y&Z&`&C&R&z&z&z&z&z&z&z&z&z&z&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&O$O$_$_$:$:$^+z.A.", +"z& *.*+*@*#*$*%*@*#*$*%*@*#*$*%*@*#*$*%*&***=*-*;*>*k&P&+*z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&B&B&B&B&z&z&z&B&B&B&z&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&/$O$O$@@_$,*:$/ ^+z.Y ", +"'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*)*'*!*~*{*]*^*^*^*/*/*/*/*/*/*/*^*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*^*/*/*/*/*/*h h ^*h h ^*^*h h ^*^*^*^*h ^*^*^*^*h ^*^*^*(*_*_*_*_*_$:*:$<*`.z.} ", +"'*'*'*'*'*[*}*|*'*[*}*|*'*[*}*|*'*[*}*|*1*1*2*}*}*2*[*)*3*4*5*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*h h h h h h h h h h h h h h h h 6*7*_*_*_*_*^*:*:$: 8*z.Y } ", +"9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*( <*8*^+z.Y } 1 ", +"a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*8*b*8*b*8*b*8*b*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*8*8*8*b*8*`.z.A.Y | | ", +"c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*p+`.p+`.p+`.p+`.`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+^+`.^+^+z.z.Y Y | | 1 ", +"d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*A.Y A.Y A.Y A.Y Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y } } | | | | 1 1 ", +"e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*} | } | } | } | | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | | | | 1 | | | 1 1 1 "}; + + +static char * tabmiddle_xpm[] = { +"33 42 32 1", +" c None", +". c #CECFEF", +"+ c #CECBE7", +"@ c #C6C7E7", +"# c #C6CBE7", +"$ c #BDBEDE", +"% c #BDC3DE", +"& c #CECBEF", +"* c #B5B6D6", +"= c #ADAECE", +"- c #ADB2CE", +"; c #BDBAD6", +"> c #B5BAD6", +", c #C6C3DE", +"' c #ADAAC6", +") c #B5B2CE", +"! c #B5B6CE", +"~ c #A5A2BD", +"{ c #A5A6BD", +"] c #9C9EB5", +"^ c #9CA2BD", +"/ c #ADAEC6", +"( c #C6C3E7", +"_ c #9C9AB5", +": c #A5A6C6", +"< c #949AAD", +"[ c #A5AAC6", +"} c #9496AD", +"| c #BDBADE", +"1 c #BDBED6", +"2 c #9CA2B5", +"3 c #A5AABD", +"..........................+@.#.#.", +"........................$@%&#.#..", +"......................**$$@@&#.#.", +".....................=-;>,%+@.#..", +"....................'')!$$@@&#.#.", +"...................~{=)$$@@&#.#..", +"..................]^'/;;(%&#.#...", +"................._]:/*>,%&@.#.#..", +".................<{[)!$%+@.#.#...", +"................}~{=!$%@@.#......", +"................]^/-|$@@.#.......", +"................]'/*;@@&#........", +"...............<~[)>,%&#.#.......", +"...............]~=)$%+#.#........", +"...............]'/;1@@.#.........", +"...............~{)*,%&#..........", +"...............2/-$$@#...........", +"...............~[*>(@&#..........", +"...............^=)$%+#...........", +"...............{'*>(@.#..........", +"...............^=)$%+#...........", +"...............{'*>(@.#..........", +"...............^=)$%+#...........", +"...............{'*>(@.#..........", +"...............^=)$%+#...........", +"...............{'*>(@.#..........", +"...............^=)$%+#...........", +"...............{'*>@@.#..........", +"...............^=!$%&#...........", +"...............{/*;@@.#..........", +"...............{)!$%&#...........", +"..............]'/;1@@.#..........", +"..............23)>,%&#...........", +"..............~=-$$@@.#..........", +".............]{/*;@@.#...........", +"............<^[)>,%&#............", +"............]{/!$%@@.#...........", +"..........]^[-!$%@@.#............", +".........]^3/!>$@@.#.............", +".......<]^3/!>$@@&#..............", +".....<]2{[/!>$%@&#.#.............", +"}<<_]2{3/-!>$%@&#.#.............."}; + + +static char * tabselectedbeginn_xpm[] = { +"33 39 28 1", +" c None", +". c #CECFEF", +"+ c #EFF3EF", +"@ c #FFFBFF", +"# c #F7FBF7", +"$ c #FFFFFF", +"% c #EFEFEF", +"& c #F7F7F7", +"* c #DEDFDE", +"= c #E7E7E7", +"- c #D6D3D6", +"; c #DEE3DE", +"> c #EFEBEF", +", c #F7F3F7", +"' c #CECBCE", +") c #CECFCE", +"! c #D6D7D6", +"~ c #DEDBDE", +"{ c #E7EBE7", +"] c #C6C7C6", +"^ c #E7E3E7", +"/ c #BDC3BD", +"( c #CED3CE", +"_ c #BDBABD", +": c #C6C3C6", +"< c #C6CBC6", +"[ c #D6DBD6", +"} c #BDBEBD", +"..........................+@#$#$$", +"........................%%&&@#$#$", +"......................*==%%&&@#$$", +"....................--*;>%,&@#$#$", +"...................')!~={,+@#$#$$", +"...................]-!^=%%&&@#$#$", +"................../'(~;>%&&@#$#$$", +"................._])!*={,&@#$#$$$", +"................_])~*>%&&$#$$$$$$", +"................:%&&$#$$$$$$$$", +".............../)!^{,&@#$$$$$$$$$", +"...............](*^%+@#$$$$$$$$$$", +"...............]!~=%&&$$$$$$$$$$$", +"...............'(*=,+@#$$$$$$$$$$", +"...............%&&$$$$$$$$$$$", +"...............'-^=,+@#$$$$$$$$$$", +"...............%&#$$$$$$$$$$$", +"...............'-^=,+@#$$$$$$$$$$", +"...............%&#$$$$$$$$$$$", +"...............'-^=,+@#$$$$$$$$$$", +"...............%&#$$$$$$$$$$$", +"...............'-^=,+@#$$$$$$$$$$", +"...............%&#$$$$$$$$$$$", +"...............'!^=,&@#$$$$$$$$$$", +"...............<~*>%&#$$$$$$$$$$$", +"...............)!^{,&@#$$$$$$$$$$", +"..............])~;%+@#$$$$$$$$$$$", +"..............]-[={&&$#$$$$$$$$$$", +".............])!^=,&@#$$$$$$$$$$$", +"............:'-*^%+@#$$$$$$$$$$$$", +"............])~*>%&&$#$$$$$$$$$$$", +"...........:'!*={,&@#$$$$$$$$$$$$", +"..........:'-~^=,+@#$$$$$$$$$$$$$", +".......}]'-~^=%,&@#$$$$$$$$$$$$$$", +".....}:])-~^=%,+@#$#$$$$$$$$$$$$$", +"}}}:]')-!*^=%,&@#$#$$$$$$$$$$$$$$"}; + + +static char * tabselectedend_xpm[] = { +"33 42 33 1", +" c None", +". c #FFFFFF", +"+ c #CECBE7", +"@ c #C6C7E7", +"# c #CECFEF", +"$ c #C6CBE7", +"% c #BDBEDE", +"& c #BDC3DE", +"* c #CECBEF", +"= c #B5B6D6", +"- c #ADAECE", +"; c #ADB2CE", +"> c #BDBAD6", +", c #B5BAD6", +"' c #C6C3DE", +") c #ADAAC6", +"! c #B5B2CE", +"~ c #B5B6CE", +"{ c #A5A2BD", +"] c #A5A6BD", +"^ c #9C9EB5", +"/ c #9CA2BD", +"( c #ADAEC6", +"_ c #C6C3E7", +": c #9C9AB5", +"< c #A5A6C6", +"[ c #949AAD", +"} c #A5AAC6", +"| c #9496AD", +"1 c #BDBADE", +"2 c #BDBED6", +"3 c #9CA2B5", +"4 c #A5AABD", +"..........................+@#$#$#", +"........................%@&*$#$##", +"......................==%%@@*$#$#", +".....................-;>,'&+@#$##", +"....................))!~%%@@*$#$#", +"...................{]-!%%@@*$#$##", +"..................^/)(>>_&*$#$###", +".................:^<(=,'&*@#$#$##", +".................[]}!~%&+@#$#$###", +"................|{]-~%&@@#$######", +"................^/(;1%@@#$#######", +"................^)(=>@@*$########", +"...............[{}!,'&*$#$#######", +"...............^{-!%&+$#$########", +"...............^)(>2@@#$#########", +"...............{]!='&*$##########", +"...............3(;%%@$###########", +"...............{}=,_@*$##########", +".............../-!%&+$###########", +"...............])=,_@#$##########", +".............../-!%&+$###########", +"...............])=,_@#$##########", +".............../-!%&+$###########", +"...............])=,_@#$##########", +".............../-!%&+$###########", +"...............])=,_@#$##########", +".............../-!%&+$###########", +"...............])=,@@#$##########", +".............../-~%&*$###########", +"...............](=>@@#$##########", +"...............]!~%&*$###########", +"..............^)(>2@@#$##########", +"..............34!,'&*$###########", +"..............{-;%%@@#$##########", +".............^](=>@@#$###########", +"............[/}!,'&*$############", +"............^](~%&@@#$###########", +"..........^/};~%&@@#$############", +".........^/4(~,%@@#$#############", +".......[^/4(~,%@@*$##############", +".....[^3]}(~,%&@*$#$#############", +"|[[:^3]4(;~,%&@*$#$##############"}; + + +static char * tabend_xpm[] = { +"33 42 3 1", +" c None", +". c #CECFEF", +"+ c #FFFFFF", +"..........................+++++++", +"........................+++++++++", +"......................+++++++++++", +".....................++++++++++++", +"....................+++++++++++++", +"...................++++++++++++++", +"..................+++++++++++++++", +".................++++++++++++++++", +".................++++++++++++++++", +"................+++++++++++++++++", +"................+++++++++++++++++", +"................+++++++++++++++++", +"...............++++++++++++++++++", +"...............++++++++++++++++++", +"...............++++++++++++++++++", +"...............++++++++++++++++++", +"...............++++++++++++++++++", +"...............++++++++++++++++++", +"...............++++++++++++++++++", +"...............++++++++++++++++++", +"...............++++++++++++++++++", +"...............++++++++++++++++++", +"...............++++++++++++++++++", +"...............++++++++++++++++++", +"...............++++++++++++++++++", +"...............++++++++++++++++++", +"...............++++++++++++++++++", +"...............++++++++++++++++++", +"...............++++++++++++++++++", +"...............++++++++++++++++++", +"...............++++++++++++++++++", +"..............+++++++++++++++++++", +"..............+++++++++++++++++++", +"..............+++++++++++++++++++", +".............++++++++++++++++++++", +"............+++++++++++++++++++++", +"............+++++++++++++++++++++", +"..........+++++++++++++++++++++++", +".........++++++++++++++++++++++++", +".......++++++++++++++++++++++++++", +".....++++++++++++++++++++++++++++", +"+++++++++++++++++++++++++++++++++"}; + + + + +QColor fromHsl(QColor c) +{ + const qreal h = c.hueF(); + const qreal s = c.saturationF(); + const qreal l = c.valueF(); + + qreal ca[3] = {0, 0, 0}; + + if (s == 0 || h == 1) { + // achromatic case + ca[0] = ca[1] = ca[2] = l; + } else { + // chromatic case + qreal temp2; + if (l < qreal(0.5)) + temp2 = l * (qreal(1.0) + s); + else + temp2 = l + s - (l * s); + + const qreal temp1 = (qreal(2.0) * l) - temp2; + qreal temp3[3] = { h + (qreal(1.0) / qreal(3.0)), + h, + h - (qreal(1.0) / qreal(3.0)) }; + + for (int i = 0; i != 3; ++i) { + if (temp3[i] < qreal(0.0)) + temp3[i] += qreal(1.0); + else if (temp3[i] > qreal(1.0)) + temp3[i] -= qreal(1.0); + + const qreal sixtemp3 = temp3[i] * qreal(6.0); + + if (sixtemp3 < qreal(1.0)) + ca[i] = ((temp1 + (temp2 - temp1) * sixtemp3)); + else if ((temp3[i] * qreal(2.0)) < qreal(1.0)) + ca[i] = (temp2); + else if ((temp3[i] * qreal(3.0)) < qreal(2.0)) + ca[i] = temp1 + (temp2 -temp1) * (qreal(2.0) /qreal(3.0) - temp3[i]) * qreal(6.0); + else ca[i] = temp1; + } + } + + return QColor::fromRgbF(ca[0], ca[1], ca[2]); +} + +#define Q_MAX_3(a, b, c) ( ( a > b && a > c) ? a : (b > c ? b : c) ) +#define Q_MIN_3(a, b, c) ( ( a < b && a < c) ? a : (b < c ? b : c) ) + +QColor toHsl(QColor c) +{ + QColor color; + qreal h; + qreal s; + qreal l; + + const qreal r = c.redF(); + const qreal g = c.greenF(); + const qreal b = c.blueF(); + const qreal max = Q_MAX_3(r, g, b); + const qreal min = Q_MIN_3(r, g, b); + const qreal delta = max - min; + const qreal delta2 = max + min; + const qreal lightness = qreal(0.5) * delta2; + l = (lightness); + if (qFuzzyIsNull(delta)) { + // achromatic case, hue is undefined + h = 0; + s = 0; + } else { + // chromatic case + qreal hue = 0; + if (lightness < qreal(0.5)) + s = ((delta / delta2)); + else + s = ((delta / (qreal(2.0) - delta2))); + if (qFuzzyCompare(r, max)) { + hue = ((g - b) /delta); + } else if (qFuzzyCompare(g, max)) { + hue = (2.0 + (b - r) / delta); + } else if (qFuzzyCompare(b, max)) { + hue = (4.0 + (r - g) / delta); + } else { + Q_ASSERT_X(false, "QColor::toHsv", "internal error"); + } + hue *= 60.0; + if (hue < 0.0) + hue += 360.0; + h = (hue * 100); + } + + h = h / 36000; + + return QColor::fromHsvF(h, s, l); +} + +void contrastImage(QImage *image) +{ + QVector colorTable = image->colorTable(); + for (int i=2;i< colorTable.size();i++) { + QColor c(colorTable.at(i)); + c.toHsv(); + if (c.value() < 150) + c = Qt::black; + else + c = Qt::white; + colorTable[i] = c.rgb(); + } + image->setColorTable(colorTable); +} + +void tintColor(QColor &color, QColor tintColor, qreal _saturation) +{ + tintColor = toHsl(tintColor); + color = toHsl(color); + qreal hue = tintColor.hueF(); + + qreal saturation = color.saturationF(); + if (_saturation) + saturation = _saturation; + qreal lightness = color.valueF(); + color.setHsvF(hue, saturation, lightness); + + color = fromHsl(color); + color.toRgb(); +} + +void tintImagePal(QImage *image, QColor color, qreal saturation) +{ + QVector colorTable = image->colorTable(); + for (int i=2;i< colorTable.size();i++) { + QColor c(toHsl(colorTable.at(i))); + tintColor(c, color, saturation); + colorTable[i] = c.rgb(); + } + image->setColorTable(colorTable); +} + + +void tintImage(QImage *image, QColor color, qreal saturation) +{ + *image = image->convertToFormat(QImage::Format_RGB32); + + for (int x = 0; x < image->width(); x++) + for (int y = 0; y < image->height(); y++) { + QColor c(image->pixel(x,y)); + tintColor(c, color, saturation); + image->setPixel(x, y, c.rgb()); + } +} + +#endif //Q_WS_WINCE_WM enum QSliderDirection { SliderUp, SliderDown, SliderLeft, SliderRight }; +void QWindowsMobileStylePrivate::tintImagesButton(QColor color) +{ + if (currentTintButton == color) + return; + + imageTabEnd = QImage(tabend_xpm); + imageTabSelectedEnd = QImage(tabselectedend_xpm); + imageTabSelectedBegin = QImage(tabselectedbeginn_xpm); + imageTabMiddle = QImage(tabmiddle_xpm); + tintImage(&imageTabEnd, color, 0.0); + tintImage(&imageTabSelectedEnd, color, 0.0); + tintImage(&imageTabSelectedBegin, color, 0.0); + tintImage(&imageTabMiddle, color, 0.0); + + if (!doubleControls) { + int height = imageTabMiddle.height() / 2 + 1; + imageTabEnd = imageTabEnd.scaledToHeight(height); + imageTabMiddle = imageTabMiddle.scaledToHeight(height); + imageTabSelectedEnd = imageTabSelectedEnd.scaledToHeight(height); + imageTabSelectedBegin = imageTabSelectedBegin.scaledToHeight(height); + } +} + +void QWindowsMobileStylePrivate::tintImagesHigh(QColor color) +{ + if (currentTintHigh == color) + return; + currentTintHigh = color; + tintListViewHighlight(color); + imageScrollbarHandleUpHigh = imageScrollbarHandleUp; + imageScrollbarHandleDownHigh = imageScrollbarHandleDown; + tintImagePal(&imageScrollbarHandleDownHigh, color, qreal(0.8)); + tintImagePal(&imageScrollbarHandleUpHigh, color, qreal(0.8)); +} + +void QWindowsMobileStylePrivate::tintListViewHighlight(QColor color) +{ + imageListViewHighlightCornerRight = QImage(listviewhighcornerright_xpm); + tintImage(&imageListViewHighlightCornerRight, color, qreal(0.0)); + + imageListViewHighlightCornerLeft = QImage(listviewhighcornerleft_xpm); + tintImage(&imageListViewHighlightCornerLeft, color, qreal(0.0)); + + imageListViewHighlightMiddle = QImage(listviewhighmiddle_xpm); + tintImage(&imageListViewHighlightMiddle, color, qreal(0.0)); + + int height = imageListViewHighlightMiddle.height(); + if (!doubleControls) { + height = height / 2; + imageListViewHighlightCornerRight = imageListViewHighlightCornerRight.scaledToHeight(height); + imageListViewHighlightCornerLeft = imageListViewHighlightCornerLeft.scaledToHeight(height); + imageListViewHighlightMiddle = imageListViewHighlightMiddle.scaledToHeight(height); + } +} + +void QWindowsMobileStylePrivate::setupWindowsMobileStyle65() +{ +#ifdef Q_WS_WINCE_WM + wm65 = true; + if (wm65) { + imageScrollbarHandleUp = QImage(sbhandleup_xpm); + imageScrollbarHandleDown = QImage(sbhandledown_xpm); + imageScrollbarGripUp = QImage(sbgripup_xpm); + imageScrollbarGripDown = QImage(sbgripdown_xpm); + imageScrollbarGripMiddle = QImage(sbgripmiddle_xpm); + + if (!doubleControls) { + imageScrollbarHandleUp = imageScrollbarHandleUp.scaledToHeight(imageScrollbarHandleUp.height() / 2); + imageScrollbarHandleDown = imageScrollbarHandleDown.scaledToHeight(imageScrollbarHandleDown.height() / 2); + imageScrollbarGripMiddle = imageScrollbarGripMiddle.scaledToHeight(imageScrollbarGripMiddle.height() / 2); + imageScrollbarGripUp = imageScrollbarGripUp.scaledToHeight(imageScrollbarGripUp.height() / 2); + imageScrollbarGripDown = imageScrollbarGripDown.scaledToHeight(imageScrollbarGripDown.height() / 2); + } else { + } + tintImagesHigh(Qt::blue); + } +#endif //Q_WS_WINCE_WM +} + +void QWindowsMobileStylePrivate::drawTabBarTab(QPainter *painter, const QStyleOptionTab *tab) +{ +#ifdef Q_WS_WINCE_WM + if (wm65) { + tintImagesButton(tab->palette.button().color()); + QRect r; + r.setTopLeft(tab->rect.topRight() - QPoint(imageTabMiddle.width(), 0)); + r.setBottomRight(tab->rect.bottomRight()); + if (tab->state & QStyle::State_Selected) { + painter->fillRect(tab->rect, tab->palette.window()); + } else { + painter->fillRect(tab->rect, QColor(imageTabMiddle.pixel(0,0))); + } + if (tab->selectedPosition == QStyleOptionTab::NextIsSelected) { + painter->drawImage(r, imageTabSelectedBegin); + } else if (tab->position == QStyleOptionTab::End || + tab->position == QStyleOptionTab::OnlyOneTab) { + if (!(tab->state & QStyle::State_Selected)) { + painter->drawImage(r, imageTabEnd); + } + } else if (tab->state & QStyle::State_Selected) { + painter->drawImage(r, imageTabSelectedEnd); + } else { + painter->drawImage(r, imageTabMiddle); + } + if (tab->position == QStyleOptionTab::Beginning && ! (tab->state & QStyle::State_Selected)) { + painter->drawImage(tab->rect.topLeft() - QPoint(imageTabMiddle.width() * 0.60, 0), imageTabSelectedEnd); + } + //imageTabBarBig + return; + } +#endif //Q_WS_WINCE_WM + painter->save(); + painter->setPen(tab->palette.shadow().color()); + if (doubleControls) { + QPen pen = painter->pen(); + pen.setWidth(2); + pen.setCapStyle(Qt::FlatCap); + painter->setPen(pen); + } + if(tab->shape == QTabBar::RoundedNorth) { + if (tab->state & QStyle::State_Selected) { + painter->fillRect(tab->rect, tab->palette.light()); + painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight()); + } + else { + painter->fillRect(tab->rect, tab->palette.button()); + painter->drawLine(tab->rect.bottomLeft() , tab->rect.bottomRight()); + painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight()); + } + } + else if(tab->shape == QTabBar::RoundedSouth) { + if (tab->state & QStyle::State_Selected) { + painter->fillRect(tab->rect.adjusted(0,-2,0,0), tab->palette.light()); + painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight()); + } + else { + painter->fillRect(tab->rect, tab->palette.button()); + if (doubleControls) + painter->drawLine(tab->rect.topLeft() + QPoint(0,1), tab->rect.topRight() + QPoint(0,1)); + else + painter->drawLine(tab->rect.topLeft(), tab->rect.topRight()); + painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight()); + } + } + else if(tab->shape == QTabBar::RoundedEast) { + if (tab->state & QStyle::State_Selected) { + painter->fillRect(tab->rect, tab->palette.light()); + painter->drawLine(tab->rect.topLeft(), tab->rect.topRight()); + } + else { + painter->fillRect(tab->rect, tab->palette.button()); + painter->drawLine(tab->rect.topLeft(), tab->rect.bottomLeft()); + painter->drawLine(tab->rect.topLeft(), tab->rect.topRight()); + } + } + else if(tab->shape == QTabBar::RoundedWest) { + if (tab->state & QStyle::State_Selected) { + painter->fillRect(tab->rect, tab->palette.light()); + painter->drawLine(tab->rect.bottomLeft(), tab->rect.bottomRight()); + } + else { + painter->fillRect(tab->rect, tab->palette.button()); + painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight()); + painter->drawLine(tab->rect.bottomLeft(), tab->rect.bottomRight()); + } + } + painter->restore(); +} + +void QWindowsMobileStylePrivate::drawPanelItemViewSelected(QPainter *painter, const QStyleOptionViewItemV4 *option, QRect rect) +{ +#ifdef Q_WS_WINCE_WM + if (wm65) { + QRect r; + if (rect.isValid()) + r = rect; + else + r = option->rect; + tintImagesHigh(option->palette.highlight().color()); + + painter->setPen(QColor(Qt::lightGray)); + + if (option->viewItemPosition == QStyleOptionViewItemV4::Middle) { + painter->drawImage(r, imageListViewHighlightMiddle); + } else if (option->viewItemPosition == QStyleOptionViewItemV4::Beginning) { + painter->drawImage(r.adjusted(10, 0, 0, 0), imageListViewHighlightMiddle); + } else if (option->viewItemPosition == QStyleOptionViewItemV4::End) { + painter->drawImage(r.adjusted(0, 0, -10, 0), imageListViewHighlightMiddle); + } else { + painter->drawImage(r.adjusted(10, 0, -10, 0), imageListViewHighlightMiddle); + } + + QImage cornerLeft = imageListViewHighlightCornerLeft; + QImage cornerRight = imageListViewHighlightCornerRight; + + int width = r.width() > cornerRight.width() ? r.width() : cornerRight.width(); + + if ((width * 2) > r.width()) { + width = (r.width() - 5) / 2; + } + + cornerLeft = cornerLeft.scaled(width, r.height()); + cornerRight = cornerRight.scaled(width, r.height()); + + if ((option->viewItemPosition == QStyleOptionViewItemV4::Beginning) || (option->viewItemPosition == QStyleOptionViewItemV4::OnlyOne) || !option->viewItemPosition) { + painter->drawImage(r.topLeft(), cornerLeft); + } + if ((option->viewItemPosition == QStyleOptionViewItemV4::End) || (option->viewItemPosition == QStyleOptionViewItemV4::OnlyOne) || !option->viewItemPosition) { + painter->drawImage(r.topRight() - QPoint(cornerRight.width(),0), cornerRight); + } + return; + } +#endif //Q_WS_WINCE_WM + QPalette::ColorGroup cg = option->state & QStyle::State_Enabled + ? QPalette::Normal : QPalette::Disabled; + + if (rect.isValid()) + painter->fillRect(rect, option->palette.brush(cg, QPalette::Highlight)); + else + painter->fillRect(option->rect, option->palette.brush(cg, QPalette::Highlight)); +} + +void QWindowsMobileStylePrivate::drawScrollbarGrip(QPainter *p, QStyleOptionSlider *newScrollbar, const QStyleOptionComplex *option, bool drawCompleteFrame) +{ +#ifdef Q_WS_WINCE_WM + if (wm65) { + if (newScrollbar->orientation == Qt::Horizontal) { + QTransform transform; + transform.rotate(-90); + QRect r = newScrollbar->rect; + p->drawImage(r.adjusted(10, 0, -10, 0), imageScrollbarGripMiddle.transformed(transform)); + p->drawImage(r.topLeft(), imageScrollbarGripUp.transformed(transform)); + p->drawImage(r.topRight() - QPoint(imageScrollbarGripDown.height() - 1, 0), imageScrollbarGripDown.transformed(transform)); + } else { + QRect r = newScrollbar->rect; + p->drawImage(r.adjusted(0, 10, 0, -10), imageScrollbarGripMiddle); + p->drawImage(r.topLeft(), imageScrollbarGripUp); + p->drawImage(r.bottomLeft() - QPoint(0, imageScrollbarGripDown.height() - 1), imageScrollbarGripDown); + } + return ; + } +#endif + if (newScrollbar->orientation == Qt::Horizontal) { + p->fillRect(newScrollbar->rect,option->palette.button()); + QRect r = newScrollbar->rect; + p->drawLine(r.topLeft(), r.bottomLeft()); + p->drawLine(r.topRight(), r.bottomRight()); + if (smartphone) { + p->drawLine(r.topLeft(), r.topRight()); + p->drawLine(r.bottomLeft(), r.bottomRight()); + } + } + else { + p->fillRect(newScrollbar->rect,option->palette.button()); + QRect r = newScrollbar->rect; + p->drawLine(r.topLeft(), r.topRight()); + p->drawLine(r.bottomLeft(), r.bottomRight()); + if (smartphone) { + p->drawLine(r.topLeft(), r.bottomLeft()); + p->drawLine(r.topRight(), r.bottomRight()); + } + } + if (newScrollbar->state & QStyle::State_HasFocus) { + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*newScrollbar); + fropt.rect.setRect(newScrollbar->rect.x() + 2, newScrollbar->rect.y() + 2, + newScrollbar->rect.width() - 5, + newScrollbar->rect.height() - 5); + } + int gripMargin = doubleControls ? 4 : 2; + int doubleLines = doubleControls ? 2 : 1; + //If there is a frame around the scrollbar (abstractScrollArea), + //then the margin is different, because of the missing frame + int gripMarginFrame = doubleControls ? 3 : 1; + if (drawCompleteFrame) + gripMarginFrame = 0; + //draw grips + if (!smartphone) + if (newScrollbar->orientation == Qt::Horizontal) { + for (int i = -3; i < 3; i += 2) { + p->drawLine( + QPoint(newScrollbar->rect.center().x() + i * doubleLines + 1, + newScrollbar->rect.top() + gripMargin +gripMarginFrame), + QPoint(newScrollbar->rect.center().x() + i * doubleLines + 1, + newScrollbar->rect.bottom() - gripMargin)); + } + } else { + for (int i = -2; i < 4 ; i += 2) { + p->drawLine( + QPoint(newScrollbar->rect.left() + gripMargin + gripMarginFrame , + newScrollbar->rect.center().y() + 1 + i * doubleLines - 1), + QPoint(newScrollbar->rect.right() - gripMargin, + newScrollbar->rect.center().y() + 1 + i * doubleLines - 1)); + } + } + if (!smartphone) { + QRect r; + if (doubleControls) + r = option->rect.adjusted(1, 1, -1, 0); + else + r = option->rect.adjusted(0, 0, -1, 0); + if (drawCompleteFrame && doubleControls) + r.adjust(0, 0, 0, -1); + //Check if the scrollbar is part of an abstractItemView and draw the frame according + if (drawCompleteFrame) + p->drawRect(r); + else + if (newScrollbar->orientation == Qt::Horizontal) + p->drawLine(r.topLeft(), r.topRight()); + else + p->drawLine(r.topLeft(), r.bottomLeft()); + } +} + +void QWindowsMobileStylePrivate::drawScrollbarHandleUp(QPainter *p, QStyleOptionSlider *opt, bool completeFrame, bool ) +{ +#ifdef Q_WS_WINCE_WM + if (wm65) { + tintImagesHigh(opt->palette.highlight().color()); + QRect r = opt->rect; + if (opt->orientation == Qt::Horizontal) { + QTransform transform; + transform.rotate(-90); + if (opt->state & QStyle::State_Sunken) + p->drawImage(r.topLeft(), imageScrollbarHandleUpHigh.transformed(transform)); + else + p->drawImage(r.topLeft(), imageScrollbarHandleUp.transformed(transform)); + } else { + if (opt->state & QStyle::State_Sunken) + p->drawImage(r.topLeft(), imageScrollbarHandleUpHigh); + else + p->drawImage(r.topLeft(), imageScrollbarHandleUp); + } + return ; + } +#endif .//Q_WS_WINCE_WM + + QBrush fill = opt->palette.button(); + if (opt->state & QStyle::State_Sunken) + fill = opt->palette.shadow(); + + QStyleOption arrowOpt = *opt; + if (doubleControls) + arrowOpt.rect = opt->rect.adjusted(4, 6, -5, -3); + else + arrowOpt.rect = opt->rect.adjusted(5, 6, -4, -3); + + bool horizontal = (opt->orientation == Qt::Horizontal); + + if (horizontal) { + p->fillRect(opt->rect,fill); + QRect r = opt->rect.adjusted(0,0,1,0); + p->drawLine(r.topRight(), r.bottomRight()); + if (doubleControls) + arrowOpt.rect.adjust(0, -2 ,0, -2); + q_func()->drawPrimitive(QStyle::PE_IndicatorArrowLeft, &arrowOpt, p, 0); + } else { + p->fillRect(opt->rect,fill); + QRect r = opt->rect.adjusted(0, 0, 0, 1); + p->drawLine(r.bottomLeft(), r.bottomRight()); + if (completeFrame) + arrowOpt.rect.adjust(-2, 0, -2, 0); + if (doubleControls) + arrowOpt.rect.adjust(0, -4 , 0, -4); + if (completeFrame && doubleControls) + arrowOpt.rect.adjust(2, 0, 2, 0); + q_func()->drawPrimitive(QStyle::PE_IndicatorArrowUp, &arrowOpt, p, 0); + } +} + +void QWindowsMobileStylePrivate::drawScrollbarHandleDown(QPainter *p, QStyleOptionSlider *opt, bool completeFrame, bool secondScrollBar) +{ + +#ifdef Q_WS_WINCE_WM + if (wm65) { + tintImagesHigh(opt->palette.highlight().color()); + QRect r = opt->rect; + if (opt->orientation == Qt::Horizontal) { + QTransform transform; + transform.rotate(-90); + if (opt->state & QStyle::State_Sunken) + p->drawImage(r.topLeft(), imageScrollbarHandleDownHigh.transformed(transform)); + else + p->drawImage(r.topLeft(), imageScrollbarHandleDown.transformed(transform)); + } else { + if (opt->state & QStyle::State_Sunken) + p->drawImage(r.topLeft(), imageScrollbarHandleDownHigh); + else + p->drawImage(r.topLeft(), imageScrollbarHandleDown); + } + return ; + } +#endif .//Q_WS_WINCE_WM + + QBrush fill = opt->palette.button(); + if (opt->state & QStyle::State_Sunken) + fill = opt->palette.shadow(); + + QStyleOption arrowOpt = *opt; + if (doubleControls) + arrowOpt.rect = opt->rect.adjusted(4, 0, -5, 3); + else + arrowOpt.rect = opt->rect.adjusted(5, 6, -4, -3); + + bool horizontal = (opt->orientation == Qt::Horizontal); + + if (horizontal) { + p->fillRect(opt->rect,fill); + QRect r = opt->rect.adjusted(0, 0, 0, 0); + p->drawLine(r.topLeft(), r.bottomLeft()); + if (secondScrollBar) + p->drawLine(r.topRight(), r.bottomRight()); + if (doubleControls) + arrowOpt.rect.adjust(0, 4, 0, 4 ); + q_func()->drawPrimitive(QStyle::PE_IndicatorArrowRight, &arrowOpt, p, 0); + } else { + p->fillRect(opt->rect,fill); + QRect r = opt->rect.adjusted(0, -1, 0, -1); + p->drawLine(r.topLeft(), r.topRight()); + if (secondScrollBar) + p->drawLine(r.bottomLeft() + QPoint(0,1), r.bottomRight() + QPoint(0, 1)); + if (completeFrame) + arrowOpt.rect.adjust(-2, 0, -2, 0); + if (doubleControls) + arrowOpt.rect.adjust(1, 0, 1, 0 ); + if (completeFrame && doubleControls) + arrowOpt.rect.adjust(1, 0, 1, 0); + q_func()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &arrowOpt, p, 0); + } +} + +void QWindowsMobileStylePrivate::drawScrollbarGroove(QPainter *p,const QStyleOptionSlider *opt) +{ +#ifdef Q_OS_WINCE_WM + if (wm65) { + p->fillRect(opt->rect,QColor(231, 231, 231)); + return ; + } +#endif + QBrush fill; + if (smartphone) { + fill = opt->palette.light(); + p->fillRect(opt->rect,fill); + fill = opt->palette.button(); + QImage image; +#ifndef QT_NO_IMAGEFORMAT_XPM + if (opt->orientation == Qt::Horizontal) + image = QImage(vertlines_xpm); + else + image = QImage(horlines_xpm); +#endif + image.setColor(1, opt->palette.button().color().rgb()); + fill.setTextureImage(image); + } + else { + fill = opt->palette.light(); + } + p->fillRect(opt->rect,fill); +} + QWindowsMobileStyle::QWindowsMobileStyle(QWindowsMobileStylePrivate &dd) : QWindowsStyle(dd) { qApp->setEffectEnabled(Qt::UI_FadeMenu, false); qApp->setEffectEnabled(Qt::UI_AnimateMenu, false); @@ -721,6 +4563,9 @@ QWindowsMobileStylePrivate::QWindowsMobileStylePrivate() :QWindowsStylePrivate() imageNormalize = QImage(normal_small_xpm); } + setupWindowsMobileStyle65(); + + imageArrowDownBig = QImage(arrowdown_big_xpm); imageArrowUpBig = QImage(arrowdown_big_xpm).mirrored(); imageArrowLeftBig = QImage(arrowleft_big_xpm); @@ -1373,21 +5218,37 @@ void QWindowsMobileStyle::drawPrimitive(PrimitiveElement element, const QStyleOp } switch (tab->shape) { case QTabBar::RoundedNorth: +#ifdef Q_WS_WINCE_WM + if (!d->wm65) +#endif + { if (d->doubleControls) - painter->drawLine(rect.topLeft() + QPoint(0, 1), rect.topRight() + QPoint(0, 1)); + painter->drawLine(rect.topLeft() + QPoint(0, 1), rect.topRight() + QPoint(0, 1)); else painter->drawLine(rect.topLeft(), rect.topRight()); + } break; case QTabBar::RoundedSouth: +#ifdef Q_WS_WINCE_WM + if (!d->wm65) +#endif + { if (d->doubleControls) painter->drawLine(rect.bottomLeft(), rect.bottomRight()); else painter->drawLine(rect.bottomLeft(), rect.bottomRight()); + } break; case QTabBar::RoundedEast: +#ifdef Q_WS_WINCE_WM + if (!d->wm65) +#endif painter->drawLine(rect.topRight(), rect.bottomRight()); break; case QTabBar::RoundedWest: +#ifdef Q_WS_WINCE_WM + if (!d->wm65) +#endif painter->drawLine(rect.topLeft(), rect.bottomLeft()); break; case QTabBar::TriangularWest: @@ -1406,6 +5267,47 @@ void QWindowsMobileStyle::drawPrimitive(PrimitiveElement element, const QStyleOp } break; #endif //QT_NO_TABBAR +#ifndef QT_NO_ITEMVIEWS + case PE_PanelItemViewRow: + if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast(option)) { + QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled + ? QPalette::Normal : QPalette::Disabled; + if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active)) + cg = QPalette::Inactive; + + if ((vopt->state & QStyle::State_Selected) && proxy()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, option, widget)) + d->drawPanelItemViewSelected(painter, vopt); + else if (vopt->features & QStyleOptionViewItemV2::Alternate) + painter->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::AlternateBase)); + else if (!(vopt->state & QStyle::State_Enabled)) + painter->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::Base)); + } + break; + case PE_PanelItemViewItem: + if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast(option)) { + QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled + ? QPalette::Normal : QPalette::Disabled; + if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active)) + cg = QPalette::Inactive; + + if (vopt->showDecorationSelected && (vopt->state & QStyle::State_Selected)) { + d->drawPanelItemViewSelected(painter, vopt); + } else { + if (vopt->backgroundBrush.style() != Qt::NoBrush) { + QPointF oldBO = painter->brushOrigin(); + painter->setBrushOrigin(vopt->rect.topLeft()); + painter->fillRect(vopt->rect, vopt->backgroundBrush); + painter->setBrushOrigin(oldBO); + } + + if (vopt->state & QStyle::State_Selected) { + QRect textRect = subElementRect(QStyle::SE_ItemViewItemText, option, widget); + d->drawPanelItemViewSelected(painter, vopt, textRect); + } + } + } + break; +#endif //QT_NO_ITEMVIEWS case PE_FrameWindow: { QPalette popupPal = option->palette; @@ -1586,67 +5488,10 @@ void QWindowsMobileStyle::drawControl(ControlElement element, const QStyleOption break; case CE_TabBarTabShape: if (const QStyleOptionTab *tab = qstyleoption_cast(option)) { + if (tab->shape == QTabBar::RoundedNorth || tab->shape == QTabBar::RoundedEast || tab->shape == QTabBar::RoundedSouth || tab->shape == QTabBar::RoundedWest) { - - painter->save(); - painter->setPen(tab->palette.shadow().color()); - if (d->doubleControls) { - QPen pen = painter->pen(); - pen.setWidth(2); - pen.setCapStyle(Qt::FlatCap); - painter->setPen(pen); - } - if(tab->shape == QTabBar::RoundedNorth) { - if (tab->state & State_Selected) { - painter->fillRect(tab->rect, tab->palette.light()); - painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight()); - } - else { - painter->fillRect(tab->rect, tab->palette.button()); - painter->drawLine(tab->rect.bottomLeft() , tab->rect.bottomRight()); - painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight()); - } - } - else if(tab->shape == QTabBar::RoundedSouth) { - - if (tab->state & State_Selected) { - painter->fillRect(tab->rect.adjusted(0,-2,0,0), tab->palette.light()); - painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight()); - } - else { - painter->fillRect(tab->rect, tab->palette.button()); - if (d->doubleControls) - painter->drawLine(tab->rect.topLeft() + QPoint(0,1), tab->rect.topRight() + QPoint(0,1)); - else - painter->drawLine(tab->rect.topLeft(), tab->rect.topRight()); - painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight()); - } - } - else if(tab->shape == QTabBar::RoundedEast) { - if (tab->state & State_Selected) { - painter->fillRect(tab->rect, tab->palette.light()); - painter->drawLine(tab->rect.topLeft(), tab->rect.topRight()); - } - else { - painter->fillRect(tab->rect, tab->palette.button()); - painter->drawLine(tab->rect.topLeft(), tab->rect.bottomLeft()); - painter->drawLine(tab->rect.topLeft(), tab->rect.topRight()); - } - } - else if(tab->shape == QTabBar::RoundedWest) { - if (tab->state & State_Selected) { - painter->fillRect(tab->rect, tab->palette.light()); - painter->drawLine(tab->rect.bottomLeft(), tab->rect.bottomRight()); - } - else { - painter->fillRect(tab->rect, tab->palette.button()); - painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight()); - painter->drawLine(tab->rect.bottomLeft(), tab->rect.bottomRight()); - } - } - - painter->restore(); + d->drawTabBarTab(painter, tab); } else { QCommonStyle::drawControl(element, option, painter, widget); } @@ -2118,26 +5963,8 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl painter->setPen(pen); } if (const QStyleOptionSlider *scrollbar = qstyleoption_cast(option)) { + d->drawScrollbarGroove(painter, scrollbar); // Make a copy here and reset it for each primitive. - QBrush fill; - if (d->smartphone) { - fill = option->palette.light(); - painter->fillRect(option->rect,fill); - fill = option->palette.button(); - QImage image; -#ifndef QT_NO_IMAGEFORMAT_XPM - if (scrollbar->orientation == Qt::Horizontal) - image = QImage(vertlines_xpm); - else - image = QImage(horlines_xpm); -#endif - image.setColor(1, option->palette.button().color().rgb()); - fill.setTextureImage(image); - } - else { - fill = option->palette.light(); - } - painter->fillRect(option->rect,fill); QStyleOptionSlider newScrollbar = *scrollbar; State saveFlags = scrollbar->state; //Check if the scrollbar is part of an abstractItemView and draw the frame according @@ -2163,34 +5990,7 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl if (newScrollbar.rect.isValid()) { if (!(scrollbar->activeSubControls & SC_ScrollBarSubLine)) newScrollbar.state &= ~(State_Sunken | State_MouseOver); - QStyleOption arrowOpt = newScrollbar; - if (d->doubleControls) - arrowOpt.rect = newScrollbar.rect.adjusted(4, 6, -5, -3); - else - arrowOpt.rect = newScrollbar.rect.adjusted(5, 6, -4, -3); - QBrush fill = option->palette.button(); - if (newScrollbar.state & State_Sunken) - fill = option->palette.shadow(); - if (scrollbar->orientation == Qt::Horizontal) { - painter->fillRect(newScrollbar.rect,fill); - QRect r = newScrollbar.rect.adjusted(0,0,1,0); - painter->drawLine(r.topRight(), r.bottomRight()); - if (d->doubleControls) - arrowOpt.rect.adjust(0, -2 ,0, -2); - drawPrimitive(PE_IndicatorArrowLeft, &arrowOpt, painter, widget); - } - else { - painter->fillRect(newScrollbar.rect,fill); - QRect r = newScrollbar.rect.adjusted(0, 0, 0, 1); - painter->drawLine(r.bottomLeft(), r.bottomRight()); - if (drawCompleteFrame) - arrowOpt.rect.adjust(-2, 0, -2, 0); - if (d->doubleControls) - arrowOpt.rect.adjust(0, -4 , 0, -4); - if (drawCompleteFrame && d->doubleControls) - arrowOpt.rect.adjust(2, 0, 2, 0); - drawPrimitive(PE_IndicatorArrowUp, &arrowOpt, painter, widget); - } + d->drawScrollbarHandleUp(painter, &newScrollbar, drawCompleteFrame, secondScrollBar); } } if (scrollbar->subControls & SC_ScrollBarAddLine) { @@ -2200,168 +6000,20 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl if (newScrollbar.rect.isValid()) { if (!(scrollbar->activeSubControls & SC_ScrollBarAddLine)) newScrollbar.state &= ~(State_Sunken | State_MouseOver); - QStyleOption arrowOpt = newScrollbar; - if (d->doubleControls) - arrowOpt.rect = newScrollbar.rect.adjusted(4, 0, -5, 3); - else - arrowOpt.rect = newScrollbar.rect.adjusted(5, 6, -4, -3); - QBrush fill = option->palette.button(); - if (newScrollbar.state & State_Sunken) - fill = option->palette.shadow(); - if (scrollbar->orientation == Qt::Horizontal) { - painter->fillRect(newScrollbar.rect,fill); - QRect r = newScrollbar.rect.adjusted(0, 0, 0, 0); - painter->drawLine(r.topLeft(), r.bottomLeft()); - if (secondScrollBar) - painter->drawLine(r.topRight(), r.bottomRight()); - if (d->doubleControls) - arrowOpt.rect.adjust(0, 4, 0, 4 ); - drawPrimitive(PE_IndicatorArrowRight, &arrowOpt, painter, widget); - } - else { - painter->fillRect(newScrollbar.rect,fill); - QRect r = newScrollbar.rect.adjusted(0, -1, 0, -1); - painter->drawLine(r.topLeft(), r.topRight()); - if (secondScrollBar) - painter->drawLine(r.bottomLeft() + QPoint(0,1), r.bottomRight() + QPoint(0, 1)); - if (drawCompleteFrame) - arrowOpt.rect.adjust(-2, 0, -2, 0); - if (d->doubleControls) - arrowOpt.rect.adjust(1, 0, 1, 0 ); - if (drawCompleteFrame && d->doubleControls) - arrowOpt.rect.adjust(1, 0, 1, 0); - drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter, widget); - } - } - } - if (scrollbar->subControls & SC_ScrollBarSubPage) { - newScrollbar.rect = scrollbar->rect; - newScrollbar.state = saveFlags; - newScrollbar.rect = subControlRect(control, &newScrollbar, SC_ScrollBarSubPage, widget); - if (newScrollbar.rect.isValid()) { - if (!(scrollbar->activeSubControls & SC_ScrollBarSubPage)) - newScrollbar.state &= ~(State_Sunken | State_MouseOver); - if (scrollbar->orientation == Qt::Horizontal) { - QRect r = newScrollbar.rect.adjusted(0, 0, 0, 0); - } - else{ - QRect r = newScrollbar.rect.adjusted(0, 0, 0, 0); - } - } - } - if (scrollbar->subControls & SC_ScrollBarAddPage) { - newScrollbar.rect = scrollbar->rect; - newScrollbar.state = saveFlags; - newScrollbar.rect = subControlRect(control, &newScrollbar, SC_ScrollBarAddPage, widget); - if (newScrollbar.rect.isValid()) { - if (!(scrollbar->activeSubControls & SC_ScrollBarAddPage)) - newScrollbar.state &= ~(State_Sunken | State_MouseOver); - if (scrollbar->orientation == Qt::Horizontal) { - QRect r = newScrollbar.rect.adjusted(0, 0, 0, -1); - } - else { - QRect r = newScrollbar.rect.adjusted(0, 0,- 1, 0); - } - } - } - if (scrollbar->subControls & SC_ScrollBarFirst) { - newScrollbar.rect = scrollbar->rect; - newScrollbar.state = saveFlags; - newScrollbar.rect = subControlRect(control, &newScrollbar, SC_ScrollBarFirst, widget); - if (newScrollbar.rect.isValid()) { - if (!(scrollbar->activeSubControls & SC_ScrollBarFirst)) - newScrollbar.state &= ~(State_Sunken | State_MouseOver); - QRect r = newScrollbar.rect; - } - } - if (scrollbar->subControls & SC_ScrollBarLast) { - newScrollbar.rect = scrollbar->rect; - newScrollbar.state = saveFlags; - newScrollbar.rect = subControlRect(control, &newScrollbar, SC_ScrollBarLast, widget); - if (newScrollbar.rect.isValid()) { - if (!(scrollbar->activeSubControls & SC_ScrollBarLast)) - newScrollbar.state &= ~(State_Sunken | State_MouseOver); - QRect r = newScrollbar.rect; + d->drawScrollbarHandleDown(painter, &newScrollbar, drawCompleteFrame, secondScrollBar); } } if (scrollbar->subControls & SC_ScrollBarSlider) { - newScrollbar.rect = scrollbar->rect; - newScrollbar.state = saveFlags; - newScrollbar.rect = subControlRect(control, &newScrollbar, SC_ScrollBarSlider, widget); - if (newScrollbar.rect.isValid()) { - if (!(scrollbar->activeSubControls & SC_ScrollBarSlider)) - newScrollbar.state &= ~(State_Sunken | State_MouseOver); - if (scrollbar->orientation == Qt::Horizontal) { - painter->fillRect(newScrollbar.rect,option->palette.button()); - QRect r = newScrollbar.rect; - painter->drawLine(r.topLeft(), r.bottomLeft()); - painter->drawLine(r.topRight(), r.bottomRight()); - if (d->smartphone) { - painter->drawLine(r.topLeft(), r.topRight()); - painter->drawLine(r.bottomLeft(), r.bottomRight()); - } - } - else { - painter->fillRect(newScrollbar.rect,option->palette.button()); - QRect r = newScrollbar.rect; - painter->drawLine(r.topLeft(), r.topRight()); - painter->drawLine(r.bottomLeft(), r.bottomRight()); - if (d->smartphone) { - painter->drawLine(r.topLeft(), r.bottomLeft()); - painter->drawLine(r.topRight(), r.bottomRight()); - } - } - if (scrollbar->state & State_HasFocus) { - QStyleOptionFocusRect fropt; - fropt.QStyleOption::operator=(newScrollbar); - fropt.rect.setRect(newScrollbar.rect.x() + 2, newScrollbar.rect.y() + 2, - newScrollbar.rect.width() - 5, - newScrollbar.rect.height() - 5); - } - } - } - int gripMargin = d->doubleControls ? 4 : 2; - int doubleLines = d->doubleControls ? 2 : 1; - //If there is a frame around the scrollbar (abstractScrollArea), - //then the margin is different, because of the missing frame - int gripMarginFrame = d->doubleControls ? 3 : 1; - if (drawCompleteFrame) - gripMarginFrame = 0; - //draw grips - if (!d->smartphone) - if (scrollbar->orientation == Qt::Horizontal) { - for (int i = -3; i < 3; i += 2) { - painter->drawLine( - QPoint(newScrollbar.rect.center().x() + i * doubleLines + 1, - newScrollbar.rect.top() + gripMargin +gripMarginFrame), - QPoint(newScrollbar.rect.center().x() + i * doubleLines + 1, - newScrollbar.rect.bottom() - gripMargin)); - } - } else { - for (int i = -2; i < 4 ; i += 2) { - painter->drawLine( - QPoint(newScrollbar.rect.left() + gripMargin + gripMarginFrame , - newScrollbar.rect.center().y() + 1 + i * doubleLines - 1), - QPoint(newScrollbar.rect.right() - gripMargin, - newScrollbar.rect.center().y() + 1 + i * doubleLines - 1)); - } - } - if (!d->smartphone) { - QRect r; - if (d->doubleControls) - r = option->rect.adjusted(1, 1, -1, 0); - else - r = option->rect.adjusted(0, 0, -1, 0); - if (drawCompleteFrame && d->doubleControls) - r.adjust(0, 0, 0, -1); - //Check if the scrollbar is part of an abstractItemView and draw the frame according - if (drawCompleteFrame) - painter->drawRect(r); - else - if (scrollbar->orientation == Qt::Horizontal) - painter->drawLine(r.topLeft(), r.topRight()); - else - painter->drawLine(r.topLeft(), r.bottomLeft()); + + newScrollbar.rect = scrollbar->rect; + newScrollbar.state = saveFlags; + newScrollbar.rect = subControlRect(control, &newScrollbar, SC_ScrollBarSlider, widget); + + if (newScrollbar.rect.isValid()) { + if (!(scrollbar->activeSubControls & SC_ScrollBarSlider)) + newScrollbar.state &= ~(State_Sunken | State_MouseOver); + d->drawScrollbarGrip(painter, &newScrollbar, option, drawCompleteFrame); + } } } painter->restore(); @@ -2719,11 +6371,25 @@ QSize QWindowsMobileStyle::sizeFromContents(ContentsType type, const QStyleOptio newSize = QSize(newSize.width() + 1, newSize.height()); break; case CT_TabBarTab: - newSize += QSize(0,0); + if (d_func()->doubleControls) + newSize = QSize(newSize.width(), 42); + else + newSize = QSize(newSize.width(), 21); break; case CT_HeaderSection: newSize += QSize(4, 2); break; +#ifndef QT_NO_ITEMVIEWS +#ifdef Q_WS_WINCE_WM + case CT_ItemViewItem: + if (d_func()->wm65) + if (d_func()->doubleControls) + newSize.setHeight(46); + else + newSize.setHeight(23); + break; +#endif //Q_WS_WINCE_WM +#endif //QT_NO_ITEMVIEWS default: break; } @@ -2751,7 +6417,7 @@ QRect QWindowsMobileStyle::subElementRect(SubElement element, const QStyleOption break; default: break; - #ifndef QT_NO_SLIDER +#ifndef QT_NO_SLIDER case SE_SliderFocusRect: if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) { rect = slider->rect; @@ -2762,6 +6428,14 @@ QRect QWindowsMobileStyle::subElementRect(SubElement element, const QStyleOption rect.adjust(-1, -1, 0, 0); break; #endif // QT_NO_SLIDER +#ifndef QT_NO_ITEMVIEWS + case SE_ItemViewItemFocusRect: +#ifdef Q_WS_WINCE_WM + if (d->wm65) + rect = QRect(); +#endif + break; +#endif //QT_NO_ITEMVIEWS } return rect; } @@ -2778,9 +6452,20 @@ QRect QWindowsMobileStyle::subControlRect(ComplexControl control, const QStyleOp case CC_ScrollBar: if (const QStyleOptionSlider *scrollbar = qstyleoption_cast(option)) { int sliderButtonExtent = pixelMetric(PM_ScrollBarExtent, scrollbar, widget); - int sliderlen; float stretchFactor = 1.4f; int sliderButtonExtentDir = int (sliderButtonExtent * stretchFactor); + +#ifdef Q_WS_WINCE_WM + if (d->wm65) +#else + if (false) +#endif //Q_WS_WINCE_WM + { + sliderButtonExtent = d->imageScrollbarHandleUp.width(); + sliderButtonExtentDir = d->imageScrollbarHandleUp.height(); + } + + int sliderlen; int maxlen = ((scrollbar->orientation == Qt::Horizontal) ? scrollbar->rect.width() : scrollbar->rect.height()) - (sliderButtonExtentDir * 2); // calculate slider length @@ -3318,15 +7003,36 @@ int QWindowsMobileStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, co d->doubleControls ? ret = 42 : ret = 21; break; case PM_ScrollBarSliderMin: - d->doubleControls ? ret = 36 : ret = 18; +#ifdef Q_WS_WINCE_WM + if (d->wm65) +#else + if (false) +#endif + { + d->doubleControls ? ret = 68 : ret = 34; + } else { + d->doubleControls ? ret = 36 : ret = 18; + } break; case PM_ScrollBarExtent: { - //Check if the scrollbar is part of an abstractItemView and set size according + if (d->smartphone) ret = 9; else d->doubleControls ? ret = 25 : ret = 13; + +#ifdef Q_WS_WINCE_WM + if (d->wm65) +#else + if (false) +#endif + { + d->doubleControls ? ret = 26 : ret = 13; + break; + } + #ifndef QT_NO_SCROLLAREA + //Check if the scrollbar is part of an abstractItemView and set size according if (widget) if (QWidget *parent = widget->parentWidget()) if (qobject_cast(parent->parentWidget())) @@ -3466,6 +7172,10 @@ QPixmap QWindowsMobileStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPi switch (iconMode) { case QIcon::Selected: { +#ifdef Q_WS_WINCE_WM + if (d_func()->wm65) + return pixmap; +#endif //Q_WS_WINCE_WM QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32); int imgh = img.height(); int imgw = img.width(); diff --git a/src/gui/styles/qwindowsmobilestyle_p.h b/src/gui/styles/qwindowsmobilestyle_p.h index 4f20bce3..59c07d8 100644 --- a/src/gui/styles/qwindowsmobilestyle_p.h +++ b/src/gui/styles/qwindowsmobilestyle_p.h @@ -67,6 +67,9 @@ public: QWindowsMobileStylePrivate(); bool doubleControls; bool smartphone; +#ifdef Q_WS_WINCE_WM + bool wm65; +#endif QImage imageRadioButton; QImage imageRadioButtonChecked; @@ -85,6 +88,42 @@ public: QImage imageMaximize; QImage imageNormalize; QImage imageMinimize; + + void setupWindowsMobileStyle65(); + +#ifdef Q_WS_WINCE_WM + //Windows Mobile 6.5 images + QImage imageScrollbarHandleUp; + QImage imageScrollbarHandleDown; + QImage imageScrollbarHandleUpHigh; + QImage imageScrollbarHandleDownHigh; + QImage imageScrollbarGripUp; + QImage imageScrollbarGripDown; + QImage imageScrollbarGripMiddle; + QImage imageListViewHighlightCornerLeft; + QImage imageListViewHighlightCornerRight; + QImage imageListViewHighlightMiddle; + QImage imageTabEnd; + QImage imageTabSelectedEnd; + QImage imageTabSelectedBegin; + QImage imageTabMiddle; + + QColor currentTintHigh; + QColor currentTintButton; + + void tintImagesHigh(QColor color); + void tintImagesButton(QColor color); + void tintListViewHighlight(QColor color); + void drawPanelItemViewSelected(QPainter *painter, const QStyleOptionViewItemV4 *option, QRect rect = QRect()); + + void drawScrollbarHandleUp(QPainter *p, QStyleOptionSlider *opt, bool completeFrame = false, bool secondScrollBar = false); + void drawScrollbarHandleDown(QPainter *p, QStyleOptionSlider *opt, bool completeFrame = false, bool secondScrollBar = false); + void drawScrollbarGroove(QPainter *p, const QStyleOptionSlider *opt); + void drawScrollbarGrip(QPainter *p, QStyleOptionSlider *newScrollbar, const QStyleOptionComplex *option, bool drawCompleteFrame); + void drawTabBarTab(QPainter *p, const QStyleOptionTab *tab); + +#endif //Q_WS_WINCE_WM + }; QT_END_NAMESPACE -- cgit v0.12 From 64c5e55bdd53fbde6a5485eba15da501411a22ca Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 11 Aug 2009 15:20:59 +0200 Subject: using proxy() --- src/gui/styles/qwindowsmobilestyle.cpp | 206 ++++++++++++++++----------------- 1 file changed, 103 insertions(+), 103 deletions(-) diff --git a/src/gui/styles/qwindowsmobilestyle.cpp b/src/gui/styles/qwindowsmobilestyle.cpp index 1408c70f..ce2c806 100644 --- a/src/gui/styles/qwindowsmobilestyle.cpp +++ b/src/gui/styles/qwindowsmobilestyle.cpp @@ -75,8 +75,9 @@ #ifdef Q_WS_WINCE #include "qt_windows.h" #include "qguifunctions_wince.h" -extern bool qt_wince_is_high_dpi(); //defined in qguifunctions_wince.cpp -extern bool qt_wince_is_smartphone(); //defined in qguifunctions_wince.cpp +extern bool qt_wince_is_high_dpi(); //defined in qguifunctions_wince.cpp +extern bool qt_wince_is_smartphone(); //defined in qguifunctions_wince.cpp +extern bool qt_wince_is_windows_mobile_65(); //defined in qguifunctions_wince.cpp #endif // Q_WS_WINCE QT_BEGIN_NAMESPACE @@ -4410,7 +4411,7 @@ void QWindowsMobileStylePrivate::drawScrollbarHandleUp(QPainter *p, QStyleOption p->drawLine(r.topRight(), r.bottomRight()); if (doubleControls) arrowOpt.rect.adjust(0, -2 ,0, -2); - q_func()->drawPrimitive(QStyle::PE_IndicatorArrowLeft, &arrowOpt, p, 0); + q_func()->proxy()->drawPrimitive(QStyle::PE_IndicatorArrowLeft, &arrowOpt, p, 0); } else { p->fillRect(opt->rect,fill); QRect r = opt->rect.adjusted(0, 0, 0, 1); @@ -4421,7 +4422,7 @@ void QWindowsMobileStylePrivate::drawScrollbarHandleUp(QPainter *p, QStyleOption arrowOpt.rect.adjust(0, -4 , 0, -4); if (completeFrame && doubleControls) arrowOpt.rect.adjust(2, 0, 2, 0); - q_func()->drawPrimitive(QStyle::PE_IndicatorArrowUp, &arrowOpt, p, 0); + q_func()->proxy()->drawPrimitive(QStyle::PE_IndicatorArrowUp, &arrowOpt, p, 0); } } @@ -4469,7 +4470,7 @@ void QWindowsMobileStylePrivate::drawScrollbarHandleDown(QPainter *p, QStyleOpti p->drawLine(r.topRight(), r.bottomRight()); if (doubleControls) arrowOpt.rect.adjust(0, 4, 0, 4 ); - q_func()->drawPrimitive(QStyle::PE_IndicatorArrowRight, &arrowOpt, p, 0); + q_func()->proxy()->drawPrimitive(QStyle::PE_IndicatorArrowRight, &arrowOpt, p, 0); } else { p->fillRect(opt->rect,fill); QRect r = opt->rect.adjusted(0, -1, 0, -1); @@ -4482,7 +4483,7 @@ void QWindowsMobileStylePrivate::drawScrollbarHandleDown(QPainter *p, QStyleOpti arrowOpt.rect.adjust(1, 0, 1, 0 ); if (completeFrame && doubleControls) arrowOpt.rect.adjust(1, 0, 1, 0); - q_func()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &arrowOpt, p, 0); + q_func()->proxy()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &arrowOpt, p, 0); } } @@ -5001,7 +5002,7 @@ void QWindowsMobileStyle::drawPrimitive(PrimitiveElement element, const QStyleOp case PE_IndicatorSpinPlus: case PE_IndicatorSpinMinus: { QRect r = option->rect; - int fw = pixelMetric(PM_DefaultFrameWidth, option, widget)+2; + int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget)+2; QRect br = r.adjusted(fw, fw, -fw, -fw); int offset = (option->state & State_Sunken) ? 1 : 0; int step = (br.width() + 4) / 5; @@ -5038,8 +5039,8 @@ void QWindowsMobileStyle::drawPrimitive(PrimitiveElement element, const QStyleOp break; } if (option->state & State_Sunken) - painter->translate(pixelMetric(PM_ButtonShiftHorizontal), - pixelMetric(PM_ButtonShiftVertical)); + painter->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal), + proxy()->pixelMetric(PM_ButtonShiftVertical)); if (option->state & State_Enabled) { painter->translate(option->rect.x() + option->rect.width() / 2, option->rect.y() + option->rect.height() / 2); @@ -5301,7 +5302,7 @@ void QWindowsMobileStyle::drawPrimitive(PrimitiveElement element, const QStyleOp } if (vopt->state & QStyle::State_Selected) { - QRect textRect = subElementRect(QStyle::SE_ItemViewItemText, option, widget); + QRect textRect = proxy()->subElementRect(QStyle::SE_ItemViewItemText, option, widget); d->drawPanelItemViewSelected(painter, vopt, textRect); } } @@ -5403,25 +5404,25 @@ void QWindowsMobileStyle::drawControl(ControlElement element, const QStyleOption case CE_PushButtonBevel: if (const QStyleOptionButton *button = qstyleoption_cast(option)) { QRect br = button->rect; - int dbi = pixelMetric(PM_ButtonDefaultIndicator, button, widget); + int dbi = proxy()->pixelMetric(PM_ButtonDefaultIndicator, button, widget); if (button->features & QStyleOptionButton::AutoDefaultButton) br.setCoords(br.left() + dbi, br.top() + dbi, br.right() - dbi, br.bottom() - dbi); QStyleOptionButton tmpBtn = *button; tmpBtn.rect = br; - drawPrimitive(PE_PanelButtonCommand, &tmpBtn, painter, widget); + proxy()->drawPrimitive(PE_PanelButtonCommand, &tmpBtn, painter, widget); if (button->features & QStyleOptionButton::HasMenu) { - int mbi = pixelMetric(PM_MenuButtonIndicator, button, widget); + int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, button, widget); QRect ir = button->rect; QStyleOptionButton newButton = *button; if (d->doubleControls) newButton.rect = QRect(ir.right() - mbi, ir.height() - 30, mbi, ir.height() - 4); else newButton.rect = QRect(ir.right() - mbi, ir.height() - 20, mbi, ir.height() - 4); - drawPrimitive(PE_IndicatorArrowDown, &newButton, painter, widget); + proxy()->drawPrimitive(PE_IndicatorArrowDown, &newButton, painter, widget); } if (button->features & QStyleOptionButton::DefaultButton) - drawPrimitive(PE_FrameDefaultButton, option, painter, widget); + proxy()->drawPrimitive(PE_FrameDefaultButton, option, painter, widget); } break; case CE_RadioButton: @@ -5429,19 +5430,19 @@ void QWindowsMobileStyle::drawControl(ControlElement element, const QStyleOption if (const QStyleOptionButton *button = qstyleoption_cast(option)) { bool isRadio = (element == CE_RadioButton); QStyleOptionButton subopt = *button; - subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator + subopt.rect = proxy()->subElementRect(isRadio ? SE_RadioButtonIndicator : SE_CheckBoxIndicator, button, widget); - drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox, + proxy()->drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox, &subopt, painter, widget); - subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents + subopt.rect = proxy()->subElementRect(isRadio ? SE_RadioButtonContents : SE_CheckBoxContents, button, widget); - drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, painter, widget); + proxy()->drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, painter, widget); if (button->state & State_HasFocus) { QStyleOptionFocusRect fropt; fropt.QStyleOption::operator=(*button); - fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect + fropt.rect = proxy()->subElementRect(isRadio ? SE_RadioButtonFocusRect : SE_CheckBoxFocusRect, button, widget); - drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); + proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); } } break; @@ -5455,7 +5456,7 @@ void QWindowsMobileStyle::drawControl(ControlElement element, const QStyleOption QRect textRect = button->rect; if (!button->icon.isNull()) { pix = button->icon.pixmap(button->iconSize, button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled); - drawItemPixmap(painter, button->rect, alignment, pix); + proxy()->drawItemPixmap(painter, button->rect, alignment, pix); if (button->direction == Qt::RightToLeft) textRect.setRight(textRect.right() - button->iconSize.width() - 4); else @@ -5463,10 +5464,10 @@ void QWindowsMobileStyle::drawControl(ControlElement element, const QStyleOption } if (!button->text.isEmpty()){ if (button->state & State_Enabled) - drawItemText(painter, textRect, alignment | Qt::TextShowMnemonic, + proxy()->drawItemText(painter, textRect, alignment | Qt::TextShowMnemonic, button->palette, false, button->text, QPalette::WindowText); else - drawItemText(painter, textRect, alignment | Qt::TextShowMnemonic, + proxy()->drawItemText(painter, textRect, alignment | Qt::TextShowMnemonic, button->palette, false, button->text, QPalette::Mid); } } @@ -5482,8 +5483,8 @@ void QWindowsMobileStyle::drawControl(ControlElement element, const QStyleOption #ifndef QT_NO_TABBAR case CE_TabBarTab: if (const QStyleOptionTab *tab = qstyleoption_cast(option)) { - drawControl(CE_TabBarTabShape, tab, painter, widget); - drawControl(CE_TabBarTabLabel, tab, painter, widget); + proxy()->drawControl(CE_TabBarTabShape, tab, painter, widget); + proxy()->drawControl(CE_TabBarTabLabel, tab, painter, widget); } break; case CE_TabBarTabShape: @@ -5522,17 +5523,17 @@ void QWindowsMobileStyle::drawControl(ControlElement element, const QStyleOption if (const QStyleOptionHeader *header = qstyleoption_cast(option)) { QRegion clipRegion = painter->clipRegion(); painter->setClipRect(option->rect); - drawControl(CE_HeaderSection, header, painter, widget); + proxy()->drawControl(CE_HeaderSection, header, painter, widget); QStyleOptionHeader subopt = *header; - subopt.rect = subElementRect(SE_HeaderLabel, header, widget); + subopt.rect = proxy()->subElementRect(SE_HeaderLabel, header, widget); if (header->state & State_Sunken) subopt.palette.setColor(QPalette::ButtonText, header->palette.brightText().color()); subopt.state |= QStyle::State_On; if (subopt.rect.isValid()) - drawControl(CE_HeaderLabel, &subopt, painter, widget); + proxy()->drawControl(CE_HeaderLabel, &subopt, painter, widget); if (header->sortIndicator != QStyleOptionHeader::None) { - subopt.rect = subElementRect(SE_HeaderArrow, option, widget); - drawPrimitive(PE_IndicatorHeaderArrow, &subopt, painter, widget); + subopt.rect = proxy()->subElementRect(SE_HeaderArrow, option, widget); + proxy()->drawPrimitive(PE_IndicatorHeaderArrow, &subopt, painter, widget); } painter->setClipRegion(clipRegion); } @@ -5677,14 +5678,14 @@ void QWindowsMobileStyle::drawControl(ControlElement element, const QStyleOption painter->setFont(newFont); QPalette palette = dwOpt->palette; palette.setColor(QPalette::Window, inactiveCaptionTextColor); - QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, option, widget); + QRect titleRect = proxy()->subElementRect(SE_DockWidgetTitleBarText, option, widget); if (verticalTitleBar) { titleRect = QRect(r.left() + rect.bottom() - titleRect.bottom(), r.top() + titleRect.left() - rect.left(), titleRect.height(), titleRect.width()); } - drawItemText(painter, titleRect, + proxy()->drawItemText(painter, titleRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, palette, dwOpt->state & State_Enabled, dwOpt->title, floating ? (active ? QPalette::BrightText : QPalette::Window) : QPalette::WindowText); @@ -5734,7 +5735,7 @@ void QWindowsMobileStyle::drawControl(ControlElement element, const QStyleOption point.rx() += pixw; if ((button->state & (State_On | State_Sunken)) && button->direction == Qt::RightToLeft) - point.rx() -= pixelMetric(PM_ButtonShiftHorizontal, option, widget) * 2; + point.rx() -= proxy()->pixelMetric(PM_ButtonShiftHorizontal, option, widget) * 2; painter->drawPixmap(visualPos(button->direction, button->rect, point), pixmap); @@ -5750,9 +5751,9 @@ void QWindowsMobileStyle::drawControl(ControlElement element, const QStyleOption tf |= Qt::AlignHCenter; } if (button->state & State_Enabled) - drawItemText(painter, ir, tf, button->palette, true, button->text, colorRole); + proxy()->drawItemText(painter, ir, tf, button->palette, true, button->text, colorRole); else - drawItemText(painter, ir, tf, button->palette, true, button->text, QPalette::Mid); + proxy()->drawItemText(painter, ir, tf, button->palette, true, button->text, QPalette::Mid); painter->restore(); } break; @@ -5772,11 +5773,11 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl #ifndef QT_NO_SLIDER case CC_Slider: if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) { - int thickness = pixelMetric(PM_SliderControlThickness, slider, widget); - int len = pixelMetric(PM_SliderLength, slider, widget); + int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget); + int len = proxy()->pixelMetric(PM_SliderLength, slider, widget); int ticks = slider->tickPosition; - QRect groove = subControlRect(CC_Slider, slider, SC_SliderGroove, widget); - QRect handle = subControlRect(CC_Slider, slider, SC_SliderHandle, widget); + QRect groove = proxy()->subControlRect(CC_Slider, slider, SC_SliderGroove, widget); + QRect handle = proxy()->subControlRect(CC_Slider, slider, SC_SliderHandle, widget); if ((slider->subControls & SC_SliderGroove) && groove.isValid()) { int mid = thickness / 2; @@ -5827,8 +5828,8 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl if (slider->state & State_HasFocus) { QStyleOptionFocusRect fropt; fropt.QStyleOption::operator=(*slider); - fropt.rect = subElementRect(SE_SliderFocusRect, slider, widget); - drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); + fropt.rect = proxy()->subElementRect(SE_SliderFocusRect, slider, widget); + proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); } if ((tickAbove && tickBelow) || (!tickAbove && !tickBelow)) { Qt::BGMode oldMode = painter->backgroundMode(); @@ -5986,7 +5987,7 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl saveFlags |= State_Enabled; if (scrollbar->subControls & SC_ScrollBarSubLine) { newScrollbar.state = saveFlags; - newScrollbar.rect = subControlRect(control, &newScrollbar, SC_ScrollBarSubLine, widget); + newScrollbar.rect = proxy()->subControlRect(control, &newScrollbar, SC_ScrollBarSubLine, widget); if (newScrollbar.rect.isValid()) { if (!(scrollbar->activeSubControls & SC_ScrollBarSubLine)) newScrollbar.state &= ~(State_Sunken | State_MouseOver); @@ -5996,7 +5997,7 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl if (scrollbar->subControls & SC_ScrollBarAddLine) { newScrollbar.rect = scrollbar->rect; newScrollbar.state = saveFlags; - newScrollbar.rect = subControlRect(control, &newScrollbar, SC_ScrollBarAddLine, widget); + newScrollbar.rect = proxy()->subControlRect(control, &newScrollbar, SC_ScrollBarAddLine, widget); if (newScrollbar.rect.isValid()) { if (!(scrollbar->activeSubControls & SC_ScrollBarAddLine)) newScrollbar.state &= ~(State_Sunken | State_MouseOver); @@ -6007,7 +6008,7 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl newScrollbar.rect = scrollbar->rect; newScrollbar.state = saveFlags; - newScrollbar.rect = subControlRect(control, &newScrollbar, SC_ScrollBarSlider, widget); + newScrollbar.rect = proxy()->subControlRect(control, &newScrollbar, SC_ScrollBarSlider, widget); if (newScrollbar.rect.isValid()) { if (!(scrollbar->activeSubControls & SC_ScrollBarSlider)) @@ -6030,8 +6031,8 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl isTabWidget = (qobject_cast(parent->parentWidget())); #endif //QT_NO_TABWIDGET - button = subControlRect(control, toolbutton, SC_ToolButton, widget); - menuarea = subControlRect(control, toolbutton, SC_ToolButtonMenu, widget); + button = proxy()->subControlRect(control, toolbutton, SC_ToolButton, widget); + menuarea = proxy()->subControlRect(control, toolbutton, SC_ToolButtonMenu, widget); State buttonFlags = toolbutton->state; if (buttonFlags & State_AutoRaise) { if (!(buttonFlags & State_MouseOver)) { @@ -6048,7 +6049,7 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl if (toolbutton->subControls & SC_ToolButton) { tool.rect = button; tool.state = buttonFlags; - drawPrimitive(PE_PanelButtonTool, &tool, painter, widget); + proxy()->drawPrimitive(PE_PanelButtonTool, &tool, painter, widget); } if (toolbutton->subControls & SC_ToolButtonMenu) { tool.rect = menuarea; @@ -6057,7 +6058,7 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl toolMenu = *toolbutton; toolMenu.state = menuFlags; if (buttonFlags & State_Sunken) - drawPrimitive(PE_PanelButtonTool, &toolMenu, painter, widget); + proxy()->drawPrimitive(PE_PanelButtonTool, &toolMenu, painter, widget); QStyleOption arrowOpt(0); arrowOpt.rect = tool.rect; arrowOpt.palette = tool.palette; @@ -6069,25 +6070,25 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl painter->fillRect(menuarea, option->palette.shadow()); } arrowOpt.state = flags; - drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter, widget); + proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter, widget); } if (toolbutton->state & State_HasFocus) { QStyleOptionFocusRect focusRect; focusRect.QStyleOption::operator=(*toolbutton); focusRect.rect.adjust(3, 3, -3, -3); if (toolbutton->features & QStyleOptionToolButton::Menu) - focusRect.rect.adjust(0, 0, -pixelMetric(QStyle::PM_MenuButtonIndicator, + focusRect.rect.adjust(0, 0, -proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator, toolbutton, widget), 0); - drawPrimitive(PE_FrameFocusRect, &focusRect, painter, widget); + proxy()->drawPrimitive(PE_FrameFocusRect, &focusRect, painter, widget); } QStyleOptionToolButton label = *toolbutton; if (isTabWidget) label.state = toolbutton->state; else label.state = toolbutton->state & State_Enabled; - int fw = pixelMetric(PM_DefaultFrameWidth, option, widget); + int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget); label.rect = button.adjusted(fw, fw, -fw, -fw); - drawControl(CE_ToolButtonLabel, &label, painter, widget); + proxy()->drawControl(CE_ToolButtonLabel, &label, painter, widget); } break; @@ -6101,15 +6102,15 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl painter->setFont(font); QStyleOptionGroupBox groupBoxFont = *groupBox; groupBoxFont.fontMetrics = QFontMetrics(font); - QRect textRect = subControlRect(CC_GroupBox, &groupBoxFont, SC_GroupBoxLabel, widget); - QRect checkBoxRect = subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget).adjusted(0,0,0,0); + QRect textRect = proxy()->subControlRect(CC_GroupBox, &groupBoxFont, SC_GroupBoxLabel, widget); + QRect checkBoxRect = proxy()->subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget).adjusted(0,0,0,0); if (groupBox->subControls & QStyle::SC_GroupBoxFrame) { QStyleOptionFrameV2 frame; frame.QStyleOption::operator=(*groupBox); frame.features = groupBox->features; frame.lineWidth = groupBox->lineWidth; frame.midLineWidth = groupBox->midLineWidth; - frame.rect = subControlRect(CC_GroupBox, option, SC_GroupBoxFrame, widget); + frame.rect = proxy()->subControlRect(CC_GroupBox, option, SC_GroupBoxFrame, widget); painter->save(); QRegion region(groupBox->rect); if (!groupBox->text.isEmpty()) { @@ -6119,7 +6120,7 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl finalRect.adjust(ltr ? -4 : 0, 0, ltr ? 0 : 4, 0); region -= finalRect; } - drawPrimitive(PE_FrameGroupBox, &frame, painter, widget); + proxy()->drawPrimitive(PE_FrameGroupBox, &frame, painter, widget); painter->restore(); } // Draw checkbox @@ -6127,7 +6128,7 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl QStyleOptionButton box; box.QStyleOption::operator=(*groupBox); box.rect = checkBoxRect; - drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget); + proxy()->drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget); } // Draw title if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) { @@ -6143,17 +6144,17 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl alignment |= Qt::TextHideMnemonic; if (groupBox->state & State_Enabled) - drawItemText(painter, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | alignment, + proxy()->drawItemText(painter, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | alignment, groupBox->palette, true, groupBox->text, textColor.isValid() ? QPalette::NoRole : QPalette::Link); else - drawItemText(painter, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | alignment, + proxy()->drawItemText(painter, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | alignment, groupBox->palette, true, groupBox->text, QPalette::Mid); if (groupBox->state & State_HasFocus) { QStyleOptionFocusRect fropt; fropt.QStyleOption::operator=(*groupBox); fropt.rect = textRect; - drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); + proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); } } painter->restore(); @@ -6166,11 +6167,11 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl if (const QStyleOptionComboBox *cmb = qstyleoption_cast(option)) { QBrush editBrush = cmb->palette.brush(QPalette::Base); if ((cmb->subControls & SC_ComboBoxFrame) && cmb->frame) - qDrawPlainRect(painter, option->rect, option->palette.shadow().color(), pixelMetric(PM_ComboBoxFrameWidth, option, widget), &editBrush); + qDrawPlainRect(painter, option->rect, option->palette.shadow().color(), proxy()->pixelMetric(PM_ComboBoxFrameWidth, option, widget), &editBrush); else painter->fillRect(option->rect, editBrush); State flags = State_None; - QRect ar = subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget); + QRect ar = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget); if ((option->state & State_On)) { painter->fillRect(ar.adjusted(0, 0, 1, 1),cmb->palette.brush(QPalette::Shadow)); } @@ -6186,9 +6187,9 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl arrowOpt.rect = ar; arrowOpt.palette = cmb->palette; arrowOpt.state = flags; - drawPrimitive(PrimitiveElement(PE_IndicatorArrowDownBig), &arrowOpt, painter, widget); + proxy()->drawPrimitive(PrimitiveElement(PE_IndicatorArrowDownBig), &arrowOpt, painter, widget); if (cmb->subControls & SC_ComboBoxEditField) { - QRect re = subControlRect(CC_ComboBox, cmb, SC_ComboBoxEditField, widget); + QRect re = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxEditField, widget); if (cmb->state & State_HasFocus && !cmb->editable) painter->fillRect(re.x(), re.y(), re.width(), re.height(), cmb->palette.brush(QPalette::Highlight)); @@ -6202,11 +6203,11 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl if (cmb->state & State_HasFocus && !cmb->editable) { QStyleOptionFocusRect focus; focus.QStyleOption::operator=(*cmb); - focus.rect = subElementRect(SE_ComboBoxFocusRect, cmb, widget); + focus.rect = proxy()->subElementRect(SE_ComboBoxFocusRect, cmb, widget); focus.state |= State_FocusAtBorder; focus.backgroundColor = cmb->palette.highlight().color(); if ((option->state & State_On)) - drawPrimitive(PE_FrameFocusRect, &focus, painter, widget); + proxy()->drawPrimitive(PE_FrameFocusRect, &focus, painter, widget); } } } @@ -6222,8 +6223,8 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl int primitiveElement; if (spinBox->frame && (spinBox->subControls & SC_SpinBoxFrame)) { - QRect r = subControlRect(CC_SpinBox, spinBox, SC_SpinBoxFrame, widget); - qDrawPlainRect(painter, r, option->palette.shadow().color(),pixelMetric(PM_SpinBoxFrameWidth, option, widget),0); + QRect r = proxy()->subControlRect(CC_SpinBox, spinBox, SC_SpinBoxFrame, widget); + qDrawPlainRect(painter, r, option->palette.shadow().color(), proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget),0); } QPalette shadePal(option->palette); shadePal.setColor(QPalette::Button, option->palette.light().color()); @@ -6245,13 +6246,13 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl } primitiveElement = (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorArrowUpBig : PE_IndicatorArrowUpBig); - copy.rect = subControlRect(CC_SpinBox, spinBox, SC_SpinBoxUp, widget); + copy.rect = proxy()->subControlRect(CC_SpinBox, spinBox, SC_SpinBoxUp, widget); if (copy.state & (State_Sunken | State_On)) - qDrawPlainRect(painter, copy.rect, option->palette.shadow().color(),pixelMetric(PM_SpinBoxFrameWidth, option, widget), ©.palette.brush(QPalette::Shadow)); + qDrawPlainRect(painter, copy.rect, option->palette.shadow().color(), proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget), ©.palette.brush(QPalette::Shadow)); else - qDrawPlainRect(painter, copy.rect, option->palette.shadow().color(),pixelMetric(PM_SpinBoxFrameWidth, option, widget), ©.palette.brush(QPalette::Base)); - copy.rect.adjust(pixelMetric(PM_SpinBoxFrameWidth, option, widget), 0, -pixelMetric(PM_SpinBoxFrameWidth, option, widget), 0); - drawPrimitive(PrimitiveElement(primitiveElement), ©, painter, widget); + qDrawPlainRect(painter, copy.rect, option->palette.shadow().color(), proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget), ©.palette.brush(QPalette::Base)); + copy.rect.adjust(proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget), 0, -pixelMetric(PM_SpinBoxFrameWidth, option, widget), 0); + proxy()->drawPrimitive(PrimitiveElement(primitiveElement), ©, painter, widget); } if (spinBox->subControls & SC_SpinBoxDown) { copy.subControls = SC_SpinBoxDown; @@ -6271,23 +6272,23 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl } primitiveElement = (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorArrowDownBig : PE_IndicatorArrowDownBig); - copy.rect = subControlRect(CC_SpinBox, spinBox, SC_SpinBoxDown, widget); - qDrawPlainRect(painter, copy.rect, option->palette.shadow().color(),pixelMetric(PM_SpinBoxFrameWidth, option, widget), ©.palette.brush(QPalette::Base)); + copy.rect = proxy()->subControlRect(CC_SpinBox, spinBox, SC_SpinBoxDown, widget); + qDrawPlainRect(painter, copy.rect, option->palette.shadow().color(), proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget), ©.palette.brush(QPalette::Base)); if (copy.state & (State_Sunken | State_On)) - qDrawPlainRect(painter, copy.rect, option->palette.shadow().color(),pixelMetric(PM_SpinBoxFrameWidth, option, widget), ©.palette.brush(QPalette::Shadow)); + qDrawPlainRect(painter, copy.rect, option->palette.shadow().color(), proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget), ©.palette.brush(QPalette::Shadow)); else - qDrawPlainRect(painter, copy.rect, option->palette.shadow().color(),pixelMetric(PM_SpinBoxFrameWidth, option, widget), ©.palette.brush(QPalette::Base)); + qDrawPlainRect(painter, copy.rect, option->palette.shadow().color(), proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget), ©.palette.brush(QPalette::Base)); copy.rect.adjust(3, 0, -4, 0); if (primitiveElement == PE_IndicatorArrowUp || primitiveElement == PE_IndicatorArrowDown) { - int frameWidth = pixelMetric(PM_SpinBoxFrameWidth, option, widget); + int frameWidth = proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget); copy.rect = copy.rect.adjusted(frameWidth, frameWidth, -frameWidth, -frameWidth); - drawPrimitive(PrimitiveElement(primitiveElement), ©, painter, widget); + proxy()->drawPrimitive(PrimitiveElement(primitiveElement), ©, painter, widget); } else { - drawPrimitive(PrimitiveElement(primitiveElement), ©, painter, widget); + proxy()->drawPrimitive(PrimitiveElement(primitiveElement), ©, painter, widget); } if (spinBox->frame && (spinBox->subControls & SC_SpinBoxFrame)) { - QRect r = subControlRect(CC_SpinBox, spinBox, SC_SpinBoxEditField, widget); + QRect r = proxy()->subControlRect(CC_SpinBox, spinBox, SC_SpinBoxEditField, widget); } } } @@ -6312,7 +6313,7 @@ QSize QWindowsMobileStyle::sizeFromContents(ContentsType type, const QStyleOptio h = newSize.height(); int defwidth = 0; if (button->features & QStyleOptionButton::AutoDefaultButton) - defwidth = 2 * pixelMetric(PM_ButtonDefaultIndicator, button, widget); + defwidth = 2 * proxy()->pixelMetric(PM_ButtonDefaultIndicator, button, widget); if (w < 75 + defwidth && button->icon.isNull()) w = 75 + defwidth; if (h < 23 + defwidth) @@ -6335,9 +6336,9 @@ QSize QWindowsMobileStyle::sizeFromContents(ContentsType type, const QStyleOptio if (const QStyleOptionButton *button = qstyleoption_cast(option)) { bool isRadio = (type == CT_RadioButton); QRect irect = visualRect(button->direction, button->rect, - subElementRect(isRadio ? SE_RadioButtonIndicator + proxy()->subElementRect(isRadio ? SE_RadioButtonIndicator : SE_CheckBoxIndicator, button, widget)); - int h = pixelMetric(isRadio ? PM_ExclusiveIndicatorHeight + int h = proxy()->pixelMetric(isRadio ? PM_ExclusiveIndicatorHeight : PM_IndicatorHeight, button, widget); int margins = (!button->icon.isNull() && button->text.isEmpty()) ? 0 : 10; if (d_func()->doubleControls) @@ -6349,7 +6350,7 @@ QSize QWindowsMobileStyle::sizeFromContents(ContentsType type, const QStyleOptio #ifndef QT_NO_COMBOBOX case CT_ComboBox: if (const QStyleOptionComboBox *comboBox = qstyleoption_cast(option)) { - int fw = comboBox->frame ? pixelMetric(PM_ComboBoxFrameWidth, option, widget) * 2 : 0; + int fw = comboBox->frame ? proxy()->pixelMetric(PM_ComboBoxFrameWidth, option, widget) * 2 : 0; newSize = QSize(newSize.width() + fw + 9, newSize.height() + fw-4); //Nine is a magic Number - See CommonStyle for real magic (23) } break; @@ -6357,7 +6358,7 @@ QSize QWindowsMobileStyle::sizeFromContents(ContentsType type, const QStyleOptio #ifndef QT_NO_SPINBOX case CT_SpinBox: if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast(option)) { - int fw = spinBox->frame ? pixelMetric(PM_SpinBoxFrameWidth, option, widget) * 2 : 0; + int fw = spinBox->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget) * 2 : 0; newSize = QSize(newSize.width() + fw-5, newSize.height() + fw-6); } break; @@ -6451,7 +6452,7 @@ QRect QWindowsMobileStyle::subControlRect(ComplexControl control, const QStyleOp #ifndef QT_NO_SCROLLBAR case CC_ScrollBar: if (const QStyleOptionSlider *scrollbar = qstyleoption_cast(option)) { - int sliderButtonExtent = pixelMetric(PM_ScrollBarExtent, scrollbar, widget); + int sliderButtonExtent = proxy()->pixelMetric(PM_ScrollBarExtent, scrollbar, widget); float stretchFactor = 1.4f; int sliderButtonExtentDir = int (sliderButtonExtent * stretchFactor); @@ -6473,7 +6474,7 @@ QRect QWindowsMobileStyle::subControlRect(ComplexControl control, const QStyleOp uint range = scrollbar->maximum - scrollbar->minimum; sliderlen = (qint64(scrollbar->pageStep) * maxlen) / (range + scrollbar->pageStep); - int slidermin = pixelMetric(PM_ScrollBarSliderMin, scrollbar, widget); + int slidermin = proxy()->pixelMetric(PM_ScrollBarSliderMin, scrollbar, widget); if (sliderlen < slidermin || range > INT_MAX / 2) sliderlen = slidermin; if (sliderlen > maxlen) @@ -6568,7 +6569,7 @@ QRect QWindowsMobileStyle::subControlRect(ComplexControl control, const QStyleOp #ifndef QT_NO_TOOLBUTTON case CC_ToolButton: if (const QStyleOptionToolButton *toolButton = qstyleoption_cast(option)) { - int mbi = pixelMetric(PM_MenuButtonIndicator, toolButton, widget); + int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolButton, widget); rect = toolButton->rect; switch (subControl) { case SC_ToolButton: @@ -6594,12 +6595,12 @@ QRect QWindowsMobileStyle::subControlRect(ComplexControl control, const QStyleOp #ifndef QT_NO_SLIDER case CC_Slider: if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) { - int tickOffset = pixelMetric(PM_SliderTickmarkOffset, slider, widget); - int thickness = pixelMetric(PM_SliderControlThickness, slider, widget); + int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider, widget); + int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget); switch (subControl) { case SC_SliderHandle: { int sliderPos = 0; - int len = pixelMetric(PM_SliderLength, slider, widget); + int len = proxy()->pixelMetric(PM_SliderLength, slider, widget); bool horizontal = slider->orientation == Qt::Horizontal; sliderPos = sliderPositionFromValue(slider->minimum, slider->maximum, slider->sliderPosition, @@ -6652,7 +6653,7 @@ QRect QWindowsMobileStyle::subControlRect(ComplexControl control, const QStyleOp case CC_SpinBox: if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast(option)) { QSize bs; - int fw = spinBox->frame ? pixelMetric(PM_SpinBoxFrameWidth, spinBox, widget) : 0; + int fw = spinBox->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, spinBox, widget) : 0; bs.setHeight(qMax(d->doubleControls ? 28 : 14, (spinBox->rect.height()))); // 1.6 -approximate golden mean bs.setWidth(qMax(d->doubleControls ? 28 : 14, qMin((bs.height()*7/8), (spinBox->rect.width() / 8)))); @@ -6663,7 +6664,7 @@ QRect QWindowsMobileStyle::subControlRect(ComplexControl control, const QStyleOp rx = x - fw; switch (subControl) { case SC_SpinBoxUp: - rect = QRect(x+pixelMetric(PM_SpinBoxFrameWidth, option, widget), 0 , bs.width(), bs.height()); + rect = QRect(x + proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget), 0 , bs.width(), bs.height()); break; case SC_SpinBoxDown: rect = QRect(x + bs.width(), 0, bs.width(), bs.height()); @@ -6709,7 +6710,7 @@ QRect QWindowsMobileStyle::subControlRect(ComplexControl control, const QStyleOp } int frameWidth = 0; if (groupBox->text.size()) { - frameWidth = pixelMetric(PM_DefaultFrameWidth, groupBox, widget); + frameWidth = proxy()->pixelMetric(PM_DefaultFrameWidth, groupBox, widget); rect = frameRect.adjusted(frameWidth, frameWidth + topHeight + labelMargin, -frameWidth, -frameWidth); } else { @@ -6730,8 +6731,8 @@ QRect QWindowsMobileStyle::subControlRect(ComplexControl control, const QStyleOp rect.setHeight(h); else rect.setHeight(0); - int indicatorWidth = pixelMetric(PM_IndicatorWidth, option, widget); - int indicatorSpace = pixelMetric(PM_CheckBoxLabelSpacing, option, widget) - 1; + int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, option, widget); + int indicatorSpace = proxy()->pixelMetric(PM_CheckBoxLabelSpacing, option, widget) - 1; bool hasCheckBox = groupBox->subControls & QStyle::SC_GroupBoxCheckBox; int checkBoxSize = hasCheckBox ? (indicatorWidth + indicatorSpace) : 0; @@ -6745,7 +6746,7 @@ QRect QWindowsMobileStyle::subControlRect(ComplexControl control, const QStyleOp int left = 2; // Adjust for check box if (subControl == SC_GroupBoxCheckBox) { - int indicatorHeight = pixelMetric(PM_IndicatorHeight, option, widget); + int indicatorHeight = proxy()->pixelMetric(PM_IndicatorHeight, option, widget); left = ltr ? totalRect.left() : (totalRect.right() - indicatorWidth); int top = totalRect.top() + (fontMetrics.height() - indicatorHeight) / 2; totalRect.setRect(left, top, indicatorWidth, indicatorHeight); @@ -6941,7 +6942,6 @@ int QWindowsMobileStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, co case PM_RadioButtonLabelSpacing: ret = d->doubleControls ? 6 * 2 : 6; break; - break; // Returns the number of pixels to use for the business part of the // slider (i.e., the non-tickmark portion). The remaining space is shared // equally between the tickmark regions. @@ -6960,7 +6960,7 @@ int QWindowsMobileStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, co } int thick = 8; if (ticks != QSlider::TicksBothSides && ticks != QSlider::NoTicks) - thick += pixelMetric(PM_SliderLength, sl, widget) / 4; + thick += proxy()->pixelMetric(PM_SliderLength, sl, widget) / 4; space -= thick; if (space > 0) @@ -6982,7 +6982,7 @@ int QWindowsMobileStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, co d->doubleControls ? ret = 64 : ret = 32; break; case PM_IconViewIconSize: - ret = pixelMetric(PM_LargeIconSize, opt, widget); + ret = proxy()->pixelMetric(PM_LargeIconSize, opt, widget); break; case PM_ToolBarIconSize: d->doubleControls ? ret = 2 * windowsMobileIconSize : ret = windowsMobileIconSize; -- cgit v0.12 From 2a4cce47072d8ec71127cf17650683e17a8cdaca Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 11 Aug 2009 15:22:00 +0200 Subject: adding qt_wince_is_windows_mobile_65() --- src/gui/kernel/qguifunctions_wince.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/gui/kernel/qguifunctions_wince.cpp b/src/gui/kernel/qguifunctions_wince.cpp index 011c726..aba06d5 100644 --- a/src/gui/kernel/qguifunctions_wince.cpp +++ b/src/gui/kernel/qguifunctions_wince.cpp @@ -256,6 +256,31 @@ bool qt_wince_is_platform(const QString &platformString) { return false; } +int qt_wince_get_build() +{ + OSVERSIONINFO osvi; + osvi.dwOSVersionInfoSize = sizeof(osvi); + if (GetVersionEx(&osvi)) { + return osvi.dwBuildNumber; + } + return 0; +} + +int qt_wince_get_version() +{ + OSVERSIONINFO osvi; + osvi.dwOSVersionInfoSize = sizeof(osvi); + if (GetVersionEx(&osvi)) { + return (osvi.dwMajorVersion * 10 + osvi.dwMinorVersion); + } + return 0; +} + +bool qt_wince_is_windows_mobile_65() +{ + return ((qt_wince_get_version() == 52) && (qt_wince_get_build() > 2000)); +} + bool qt_wince_is_pocket_pc() { return qt_wince_is_platform(QString::fromLatin1("PocketPC")); } -- cgit v0.12 From 4f97f62eb4c8f6ebe9bc7a8f30f3f0219a456c75 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 11 Aug 2009 15:22:18 +0200 Subject: activate wm65 style only for wm65 --- src/gui/styles/qwindowsmobilestyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/styles/qwindowsmobilestyle.cpp b/src/gui/styles/qwindowsmobilestyle.cpp index ce2c806..014e46e 100644 --- a/src/gui/styles/qwindowsmobilestyle.cpp +++ b/src/gui/styles/qwindowsmobilestyle.cpp @@ -4114,7 +4114,7 @@ void QWindowsMobileStylePrivate::tintListViewHighlight(QColor color) void QWindowsMobileStylePrivate::setupWindowsMobileStyle65() { #ifdef Q_WS_WINCE_WM - wm65 = true; + wm65 = qt_wince_is_windows_mobile_65(); if (wm65) { imageScrollbarHandleUp = QImage(sbhandleup_xpm); imageScrollbarHandleDown = QImage(sbhandledown_xpm); -- cgit v0.12 From cb7e836d917eb43a9664c0f6b3e02788c0d78919 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 11 Aug 2009 16:01:16 +0200 Subject: Cleanup of Windows Mobile Style Reviewed-by: Maurice --- src/gui/styles/qwindowsmobilestyle.cpp | 137 +++++++++++++++------------------ 1 file changed, 61 insertions(+), 76 deletions(-) diff --git a/src/gui/styles/qwindowsmobilestyle.cpp b/src/gui/styles/qwindowsmobilestyle.cpp index 014e46e..7376f16 100644 --- a/src/gui/styles/qwindowsmobilestyle.cpp +++ b/src/gui/styles/qwindowsmobilestyle.cpp @@ -3996,21 +3996,6 @@ QColor toHsl(QColor c) return QColor::fromHsvF(h, s, l); } -void contrastImage(QImage *image) -{ - QVector colorTable = image->colorTable(); - for (int i=2;i< colorTable.size();i++) { - QColor c(colorTable.at(i)); - c.toHsv(); - if (c.value() < 150) - c = Qt::black; - else - c = Qt::white; - colorTable[i] = c.rgb(); - } - image->setColorTable(colorTable); -} - void tintColor(QColor &color, QColor tintColor, qreal _saturation) { tintColor = toHsl(tintColor); @@ -4167,62 +4152,62 @@ void QWindowsMobileStylePrivate::drawTabBarTab(QPainter *painter, const QStyleOp return; } #endif //Q_WS_WINCE_WM - painter->save(); - painter->setPen(tab->palette.shadow().color()); - if (doubleControls) { - QPen pen = painter->pen(); - pen.setWidth(2); - pen.setCapStyle(Qt::FlatCap); - painter->setPen(pen); - } - if(tab->shape == QTabBar::RoundedNorth) { - if (tab->state & QStyle::State_Selected) { - painter->fillRect(tab->rect, tab->palette.light()); - painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight()); - } - else { - painter->fillRect(tab->rect, tab->palette.button()); - painter->drawLine(tab->rect.bottomLeft() , tab->rect.bottomRight()); - painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight()); - } - } - else if(tab->shape == QTabBar::RoundedSouth) { - if (tab->state & QStyle::State_Selected) { - painter->fillRect(tab->rect.adjusted(0,-2,0,0), tab->palette.light()); - painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight()); - } - else { - painter->fillRect(tab->rect, tab->palette.button()); - if (doubleControls) - painter->drawLine(tab->rect.topLeft() + QPoint(0,1), tab->rect.topRight() + QPoint(0,1)); - else - painter->drawLine(tab->rect.topLeft(), tab->rect.topRight()); - painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight()); - } - } - else if(tab->shape == QTabBar::RoundedEast) { - if (tab->state & QStyle::State_Selected) { - painter->fillRect(tab->rect, tab->palette.light()); - painter->drawLine(tab->rect.topLeft(), tab->rect.topRight()); - } - else { - painter->fillRect(tab->rect, tab->palette.button()); - painter->drawLine(tab->rect.topLeft(), tab->rect.bottomLeft()); - painter->drawLine(tab->rect.topLeft(), tab->rect.topRight()); - } - } - else if(tab->shape == QTabBar::RoundedWest) { - if (tab->state & QStyle::State_Selected) { - painter->fillRect(tab->rect, tab->palette.light()); - painter->drawLine(tab->rect.bottomLeft(), tab->rect.bottomRight()); - } - else { - painter->fillRect(tab->rect, tab->palette.button()); - painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight()); - painter->drawLine(tab->rect.bottomLeft(), tab->rect.bottomRight()); - } - } - painter->restore(); + painter->save(); + painter->setPen(tab->palette.shadow().color()); + if (doubleControls) { + QPen pen = painter->pen(); + pen.setWidth(2); + pen.setCapStyle(Qt::FlatCap); + painter->setPen(pen); + } + if(tab->shape == QTabBar::RoundedNorth) { + if (tab->state & QStyle::State_Selected) { + painter->fillRect(tab->rect, tab->palette.light()); + painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight()); + } + else { + painter->fillRect(tab->rect, tab->palette.button()); + painter->drawLine(tab->rect.bottomLeft() , tab->rect.bottomRight()); + painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight()); + } + } + else if(tab->shape == QTabBar::RoundedSouth) { + if (tab->state & QStyle::State_Selected) { + painter->fillRect(tab->rect.adjusted(0,-2,0,0), tab->palette.light()); + painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight()); + } + else { + painter->fillRect(tab->rect, tab->palette.button()); + if (doubleControls) + painter->drawLine(tab->rect.topLeft() + QPoint(0,1), tab->rect.topRight() + QPoint(0,1)); + else + painter->drawLine(tab->rect.topLeft(), tab->rect.topRight()); + painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight()); + } + } + else if(tab->shape == QTabBar::RoundedEast) { + if (tab->state & QStyle::State_Selected) { + painter->fillRect(tab->rect, tab->palette.light()); + painter->drawLine(tab->rect.topLeft(), tab->rect.topRight()); + } + else { + painter->fillRect(tab->rect, tab->palette.button()); + painter->drawLine(tab->rect.topLeft(), tab->rect.bottomLeft()); + painter->drawLine(tab->rect.topLeft(), tab->rect.topRight()); + } + } + else if(tab->shape == QTabBar::RoundedWest) { + if (tab->state & QStyle::State_Selected) { + painter->fillRect(tab->rect, tab->palette.light()); + painter->drawLine(tab->rect.bottomLeft(), tab->rect.bottomRight()); + } + else { + painter->fillRect(tab->rect, tab->palette.button()); + painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight()); + painter->drawLine(tab->rect.bottomLeft(), tab->rect.bottomRight()); + } + } + painter->restore(); } void QWindowsMobileStylePrivate::drawPanelItemViewSelected(QPainter *painter, const QStyleOptionViewItemV4 *option, QRect rect) @@ -4391,7 +4376,7 @@ void QWindowsMobileStylePrivate::drawScrollbarHandleUp(QPainter *p, QStyleOption } return ; } -#endif .//Q_WS_WINCE_WM +#endif //Q_WS_WINCE_WM QBrush fill = opt->palette.button(); if (opt->state & QStyle::State_Sunken) @@ -4448,7 +4433,7 @@ void QWindowsMobileStylePrivate::drawScrollbarHandleDown(QPainter *p, QStyleOpti } return ; } -#endif .//Q_WS_WINCE_WM +#endif //Q_WS_WINCE_WM QBrush fill = opt->palette.button(); if (opt->state & QStyle::State_Sunken) @@ -4491,14 +4476,14 @@ void QWindowsMobileStylePrivate::drawScrollbarGroove(QPainter *p,const QStyleOpt { #ifdef Q_OS_WINCE_WM if (wm65) { - p->fillRect(opt->rect,QColor(231, 231, 231)); + p->fillRect(opt->rect, QColor(231, 231, 231)); return ; } #endif QBrush fill; if (smartphone) { fill = opt->palette.light(); - p->fillRect(opt->rect,fill); + p->fillRect(opt->rect, fill); fill = opt->palette.button(); QImage image; #ifndef QT_NO_IMAGEFORMAT_XPM @@ -4513,7 +4498,7 @@ void QWindowsMobileStylePrivate::drawScrollbarGroove(QPainter *p,const QStyleOpt else { fill = opt->palette.light(); } - p->fillRect(opt->rect,fill); + p->fillRect(opt->rect, fill); } QWindowsMobileStyle::QWindowsMobileStyle(QWindowsMobileStylePrivate &dd) : QWindowsStyle(dd) { -- cgit v0.12 From c6030230d0af230cfcf084cc7bc16515c863c37b Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 11 Aug 2009 16:20:57 +0200 Subject: Make QFileInfo::isSymlink() work for symlinks on Windows This feature on Windows was added in Windows 2000, but its not so easy to utilize until at least Vista was released. Reviewed-by: Marius Storm-Olsen --- src/corelib/io/qfsfileengine_win.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 819034a..7c75525 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1525,6 +1525,8 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil ret |= FileType; } } else if (d->doStat()) { + if (d->fileAttrib & FILE_ATTRIBUTE_REPARSE_POINT) + ret |= LinkType; if (d->fileAttrib & FILE_ATTRIBUTE_DIRECTORY) { ret |= DirectoryType; } else { -- cgit v0.12 From 01cb98e141d201d7f7efd83dabefc7938759694b Mon Sep 17 00:00:00 2001 From: Matthew Cattell Date: Tue, 11 Aug 2009 16:38:34 +0200 Subject: QDateTimeEdit: setFrame property is respected when a popup calendar has been set. The hasFrame() or frame property of the QStyleOptionSpinBox was not being copiedthrough to the QStyleOptionComboBox inside the paintEvent method if a calendarPopup had been enabled. Task-number:259510 Reviewed-by:Jens Bache-Wiig --- src/gui/widgets/qdatetimeedit.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/widgets/qdatetimeedit.cpp b/src/gui/widgets/qdatetimeedit.cpp index cb76876..96d5619 100644 --- a/src/gui/widgets/qdatetimeedit.cpp +++ b/src/gui/widgets/qdatetimeedit.cpp @@ -2270,6 +2270,7 @@ void QDateTimeEdit::paintEvent(QPaintEvent *event) optCombo.init(this); optCombo.editable = true; + optCombo.frame = opt.frame; optCombo.subControls = opt.subControls; optCombo.activeSubControls = opt.activeSubControls; optCombo.state = opt.state; -- cgit v0.12 From 54ad9d0e8527eef9ce027f90d7c0ec1d9051833a Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Tue, 11 Aug 2009 16:50:45 +0200 Subject: QWidget::isHidden documentation clarification. Reviewed-by: Kavindra --- src/gui/kernel/qwidget.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index f705761..0dfc6e3 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -6863,9 +6863,12 @@ void QWidgetPrivate::hide_helper() widgets that are not visible. - Widgets are hidden if they were created as independent - windows or as children of visible widgets, or if hide() or setVisible(false) was called. - + Widgets are hidden if: + \list + \o they were created as independent windows, + \o they were created as children of visible widgets, + \o hide() or setVisible(false) was called. + \endlist */ -- cgit v0.12 From 71fd7e60c43392f2c21598a0c9d28b7aa5204cda Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 11 Aug 2009 16:55:15 +0200 Subject: Doc: Added information about quoting of path strings. Task-number: None Reviewed-by: Andy Shaw Review-was: Tentative --- doc/src/qmake-manual.qdoc | 19 +++++++++++++------ doc/src/snippets/qmake/spaces.pro | 8 ++++---- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/doc/src/qmake-manual.qdoc b/doc/src/qmake-manual.qdoc index 3363881..1463da7 100644 --- a/doc/src/qmake-manual.qdoc +++ b/doc/src/qmake-manual.qdoc @@ -262,15 +262,20 @@ Normally, variables are used to contain whitespace-separated lists of values. However, it is sometimes necessary to specify values containing - spaces. These must be quoted in the following way: + spaces. These must be quoted by using the + \l{qmake Function Reference#quote-string}{quote()} function in the following way: \snippet doc/src/snippets/qmake/quoting.pro 0 The quoted text is treated as a single item in the list of values held by - the variable. This approach is used to deal with paths that contain spaces, - particularly on the Windows platform. See the documentation for the + the variable. A similar approach is used to deal with paths that contain + spaces, particularly when defining the \l{qmake Variable Reference#INCLUDEPATH}{INCLUDEPATH} and - \l{qmake Variable Reference#LIBS}{LIBS} variables for examples. + \l{qmake Variable Reference#LIBS}{LIBS} variables for the Windows platform. + In cases like these, the \l{qmake Function Reference#quote(string)}{quote()} + function can be used in the following way: + + \snippet doc/src/snippets/qmake/spaces.pro quoting include paths with spaces \section2 Comments @@ -1377,7 +1382,8 @@ To specify a path containing spaces, quote the path using the technique mentioned in the \l{qmake Project Files#Whitespace}{qmake Project Files} document. For example, paths with spaces can be specified on Windows - and Unix platforms in the following way: + and Unix platforms by using the \l{qmake Function Reference#quote-string}{quote()} + function in the following way: \snippet doc/src/snippets/qmake/spaces.pro quoting include paths with spaces @@ -1437,7 +1443,8 @@ To specify a path containing spaces, quote the path using the technique mentioned in the \l{qmake Project Files#Whitespace}{qmake Project Files} document. For example, paths with spaces can be specified on Windows - and Unix platforms in the following way: + and Unix platforms by using the \l{qmake Function Reference#quote-string}{quote()} + function in the following way: \snippet doc/src/snippets/qmake/spaces.pro quoting library paths with spaces diff --git a/doc/src/snippets/qmake/spaces.pro b/doc/src/snippets/qmake/spaces.pro index c78e984..544ef05 100644 --- a/doc/src/snippets/qmake/spaces.pro +++ b/doc/src/snippets/qmake/spaces.pro @@ -1,9 +1,9 @@ #! [quoting library paths with spaces] -win32:LIBS += "C:/mylibs/extra libs/extra.lib" -unix:LIBS += -L"/home/user/extra libs" -lextra +win32:LIBS += $$quote(C:/mylibs/extra libs/extra.lib) +unix:LIBS += $$quote(-L/home/user/extra libs) -lextra #! [quoting library paths with spaces] #! [quoting include paths with spaces] -win32:INCLUDEPATH += "C:/mylibs/extra headers" -unix:INCLUDEPATH += "/home/user/extra headers" +win32:INCLUDEPATH += $$quote(C:/mylibs/extra headers) +unix:INCLUDEPATH += $$quote(/home/user/extra headers) #! [quoting include paths with spaces] -- cgit v0.12 From 8f5c9f36fac630abb262205f98c7fa562ec6b814 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 11 Aug 2009 16:57:04 +0200 Subject: Doc: Added information about the Qt::AutoCompatConnection enum value. Task-number: 235850 Reviewed-by: Trust Me --- doc/src/classes/qnamespace.qdoc | 7 ++++++- doc/src/porting4.qdoc | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/doc/src/classes/qnamespace.qdoc b/doc/src/classes/qnamespace.qdoc index a49e079..18ecd7b 100644 --- a/doc/src/classes/qnamespace.qdoc +++ b/doc/src/classes/qnamespace.qdoc @@ -514,7 +514,6 @@ slots. In particular, it determines whether a particular signal is delivered to a slot immediately or queued for delivery at a later time. - \omitvalue AutoCompatConnection \value DirectConnection When emitted, the signal is immediately delivered to the slot. \value QueuedConnection When emitted, the signal is queued until the event loop is able to deliver it to the slot. @@ -533,6 +532,12 @@ not already connected to the same slot before connecting, otherwise, the connection will fail. This value was introduced in Qt 4.6. + \value AutoCompatConnection + The default connection type for signals and slots when Qt 3 support + is enabled. Equivalent to AutoConnection for connections but will cause warnings + to be output under certain circumstances. See + \l{Porting to Qt 4#Compatibility Signals and Slots}{Compatibility Signals and Slots} + for further information. With queued connections, the parameters must be of types that are known to Qt's meta-object system, because Qt needs to copy the arguments to store them diff --git a/doc/src/porting4.qdoc b/doc/src/porting4.qdoc index 963b918..286e10d 100644 --- a/doc/src/porting4.qdoc +++ b/doc/src/porting4.qdoc @@ -561,6 +561,21 @@ \note Setting widget attributes to disable key features of Qt's widget rendering model may also cause other features to be disabled. + \section1 Compatibility Signals and Slots + + When \c QT3_SUPPORT is defined, the default connection type for signals + and slots is the Qt::AutoCompatConnection type. This allows so-called + \e compatibility signals and slots (defined in Qt 3 support mode to provide + Qt 3 compatibility features) to be connected to other signals and + slots. + + However, if Qt is compiled with debugging output enabled, and the + developer uses other connection types to connect to compatibility + signals and slots (perhaps by building their application without Qt 3 + support enabled), then Qt will output warnings to the console to + indicate that compatibility connections are being made. This is intended + to be used as an aid in the process of porting a Qt 3 application to Qt 4. + \section1 QAccel The \c QAccel class has been renamed Q3Accel and moved to the -- cgit v0.12 From ac174ba05db74eb5928ac5d3408bca201adf29ca Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 11 Aug 2009 16:58:56 +0200 Subject: Doc: Fixed qdoc markup. Reviewed-by: Trust Me --- doc/src/examples/moveblocks.qdoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/src/examples/moveblocks.qdoc b/doc/src/examples/moveblocks.qdoc index 7e42307..a0049ec 100644 --- a/doc/src/examples/moveblocks.qdoc +++ b/doc/src/examples/moveblocks.qdoc @@ -169,7 +169,7 @@ remember which state was the last state to which we transitioned. \snippet examples/animation/moveblocks/main.cpp 11 - + We select the next state we are going to transition to, and post a \c StateSwitchEvent, which we know will trigger the \c StateSwitchTransition to the selected state. @@ -198,8 +198,8 @@ \section1 The StateSwitchEvent Class \c StateSwitchEvent inherits QEvent, and holds a number that has - been assigned to a state and state switch transition by \c - StateSwitcher. We have already seen how it is used to trigger \c + been assigned to a state and state switch transition by + \c StateSwitcher. We have already seen how it is used to trigger \c{StateSwitchTransition}s in \c StateSwitcher. \snippet examples/animation/moveblocks/main.cpp 15 -- cgit v0.12 From 37a8926fd8aa1971a4d0a8b04facf63c631b9367 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 11 Aug 2009 10:26:31 +0200 Subject: fix warnings for the qreal == float case Reviewed-by: mauricek --- src/gui/graphicsview/qgraphicsscene_p.h | 4 ++-- src/gui/styles/qstylehelper.cpp | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index a4bbdd2..7415591 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -267,9 +267,9 @@ static inline void _q_adjustRect(QRectF *rect) { Q_ASSERT(rect); if (!rect->width()) - rect->adjust(-0.00001, 0, 0.00001, 0); + rect->adjust(qreal(-0.00001), 0, qreal(0.00001), 0); if (!rect->height()) - rect->adjust(0, -0.00001, 0, 0.00001); + rect->adjust(0, qreal(-0.00001), 0, qreal(0.00001)); } static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item) diff --git a/src/gui/styles/qstylehelper.cpp b/src/gui/styles/qstylehelper.cpp index 4877ec4..402c4d1 100644 --- a/src/gui/styles/qstylehelper.cpp +++ b/src/gui/styles/qstylehelper.cpp @@ -250,8 +250,8 @@ void drawDial(const QStyleOptionSlider *option, QPainter *painter) QRadialGradient shadowGradient(shadowRect.center().x(), shadowRect.center().y(), shadowRect.width()/2.0, shadowRect.center().x(), shadowRect.center().y()); - shadowGradient.setColorAt(0.91, QColor(0, 0, 0, 40)); - shadowGradient.setColorAt(1.0, Qt::transparent); + shadowGradient.setColorAt(qreal(0.91), QColor(0, 0, 0, 40)); + shadowGradient.setColorAt(qreal(1.0), Qt::transparent); p->setBrush(shadowGradient); p->setPen(Qt::NoPen); p->translate(shadowSize, shadowSize); @@ -263,8 +263,8 @@ void drawDial(const QStyleOptionSlider *option, QPainter *painter) br.width()*1.3, br.center().x(), br.center().y() - br.height()/2); gradient.setColorAt(0, buttonColor.lighter(110)); - gradient.setColorAt(0.5, buttonColor); - gradient.setColorAt(0.501, buttonColor.darker(102)); + gradient.setColorAt(qreal(0.5), buttonColor); + gradient.setColorAt(qreal(0.501), buttonColor.darker(102)); gradient.setColorAt(1, buttonColor.darker(115)); p->setBrush(gradient); } else { @@ -290,21 +290,21 @@ void drawDial(const QStyleOptionSlider *option, QPainter *painter) END_STYLE_PIXMAPCACHE - QPointF dp = calcRadialPos(option, 0.70); + QPointF dp = calcRadialPos(option, qreal(0.70)); buttonColor = buttonColor.lighter(104); - buttonColor.setAlphaF(0.8); - const qreal ds = r/7.0; + buttonColor.setAlphaF(qreal(0.8)); + const qreal ds = r/qreal(7.0); QRectF dialRect(dp.x() - ds, dp.y() - ds, 2*ds, 2*ds); QRadialGradient dialGradient(dialRect.center().x() + dialRect.width()/2, dialRect.center().y() + dialRect.width(), dialRect.width()*2, dialRect.center().x(), dialRect.center().y()); dialGradient.setColorAt(1, buttonColor.darker(140)); - dialGradient.setColorAt(0.4, buttonColor.darker(120)); + dialGradient.setColorAt(qreal(0.4), buttonColor.darker(120)); dialGradient.setColorAt(0, buttonColor.darker(110)); if (penSize > 3.0) { painter->setPen(QPen(QColor(0, 0, 0, 25), penSize)); - painter->drawLine(calcRadialPos(option, 0.90), calcRadialPos(option, 0.96)); + painter->drawLine(calcRadialPos(option, qreal(0.90)), calcRadialPos(option, qreal(0.96))); } painter->setBrush(dialGradient); -- cgit v0.12 From d45b0ee01402c2474652f6afd2cd1e8564d8071c Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 11 Aug 2009 16:03:03 +0200 Subject: QPoint comparision operators use qFuzzyIsNull instead of qFuzzyCompare qFuzzyCompare doesn't support 0 as parameter. So this function is pretty useless for QPoint, where coordinates can be zero. Reviewed-by: Harald Fernengel --- src/corelib/tools/qpoint.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qpoint.h b/src/corelib/tools/qpoint.h index df35eaa..8d653b0 100644 --- a/src/corelib/tools/qpoint.h +++ b/src/corelib/tools/qpoint.h @@ -302,12 +302,12 @@ inline QPointF &QPointF::operator*=(qreal c) inline bool operator==(const QPointF &p1, const QPointF &p2) { - return qFuzzyCompare(p1.xp, p2.xp) && qFuzzyCompare(p1.yp, p2.yp); + return qFuzzyIsNull(p1.xp - p2.xp) && qFuzzyIsNull(p1.yp - p2.yp); } inline bool operator!=(const QPointF &p1, const QPointF &p2) { - return !qFuzzyCompare(p1.xp, p2.xp) || !qFuzzyCompare(p1.yp, p2.yp); + return !qFuzzyIsNull(p1.xp - p2.xp) || !qFuzzyIsNull(p1.yp - p2.yp); } inline const QPointF operator+(const QPointF &p1, const QPointF &p2) -- cgit v0.12 From ee7d7a4f3016e8ca94bde5c2328676e31bf4eba2 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 11 Aug 2009 11:53:41 +0200 Subject: fix QTextFormat::doubleProperty where qreal is float This function was too strict. It returned 0 if the property wasn't of type QVariant::Double. Now it tests for QMetaType::Float too. Reviewed-by: kh1 Reviewed-by: mauricek --- src/gui/text/qtextformat.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index a3dd83e..fd0c17f 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -875,7 +875,8 @@ int QTextFormat::intProperty(int propertyId) const /*! Returns the value of the property specified by \a propertyId. If the - property isn't of QVariant::Double type, 0 is returned instead. + property isn't of QVariant::Double or QMetaType::Float type, 0 is + returned instead. \sa setProperty() boolProperty() intProperty() stringProperty() colorProperty() lengthProperty() lengthVectorProperty() Property */ @@ -884,9 +885,9 @@ qreal QTextFormat::doubleProperty(int propertyId) const if (!d) return 0.; const QVariant prop = d->property(propertyId); - if (prop.type() != QVariant::Double) + if (prop.type() != QVariant::Double && prop.type() != QMetaType::Float) return 0.; - return prop.toDouble(); // #### + return qVariantValue(prop); } /*! -- cgit v0.12 From 204c771ab5c0ef62c76ead594bfeacc3627ab108 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 11 Aug 2009 17:56:43 +0200 Subject: fix tst_QPixmapCache::clear for Windows CE This test used too much memory for Windows CE <= 5. Reviewed-by: thartman --- tests/auto/qpixmapcache/tst_qpixmapcache.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tests/auto/qpixmapcache/tst_qpixmapcache.cpp b/tests/auto/qpixmapcache/tst_qpixmapcache.cpp index e71bd5d..7866df8 100644 --- a/tests/auto/qpixmapcache/tst_qpixmapcache.cpp +++ b/tests/auto/qpixmapcache/tst_qpixmapcache.cpp @@ -392,14 +392,19 @@ void tst_QPixmapCache::clear() QPixmap p1(10, 10); p1.fill(Qt::red); - for (int i = 0; i < 20000; ++i) +#ifdef Q_OS_WINCE + const int numberOfKeys = 10000; +#else + const int numberOfKeys = 20000; +#endif + for (int i = 0; i < numberOfKeys; ++i) QVERIFY(QPixmapCache::find("x" + QString::number(i)) == 0); - for (int j = 0; j < 20000; ++j) + for (int j = 0; j < numberOfKeys; ++j) QPixmapCache::insert(QString::number(j), p1); int num = 0; - for (int k = 0; k < 20000; ++k) { + for (int k = 0; k < numberOfKeys; ++k) { if (QPixmapCache::find(QString::number(k), p1)) ++num; } @@ -407,7 +412,7 @@ void tst_QPixmapCache::clear() QPixmapCache::clear(); - for (int k = 0; k < 20000; ++k) + for (int k = 0; k < numberOfKeys; ++k) QVERIFY(QPixmapCache::find(QString::number(k)) == 0); //The int part of the API @@ -415,12 +420,12 @@ void tst_QPixmapCache::clear() p2.fill(Qt::red); QList keys; - for (int k = 0; k < 20000; ++k) + for (int k = 0; k < numberOfKeys; ++k) keys.append(QPixmapCache::insert(p2)); QPixmapCache::clear(); - for (int k = 0; k < 20000; ++k) { + for (int k = 0; k < numberOfKeys; ++k) { QVERIFY(QPixmapCache::find(keys.at(k), &p1) == 0); QCOMPARE(getPrivate(keys[k])->isValid, false); } -- cgit v0.12 From eb4efda5c8a9a32c38945e26f68217b170b87ffb Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:14 +0200 Subject: QFSFileEngine::mkdir fix on Windows This function now returns early if a non-directory is met in the path. Something like /foo/bar/&&/ will bail out early. Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_win.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 7c75525..11d1ca6 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -958,9 +958,13 @@ bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) con if (slash) { QString chunk = dirName.left(slash); bool existed = false; - if (!isDirPath(chunk, &existed) && !existed) { - if (!mkDir(chunk)) + if (!isDirPath(chunk, &existed)) { + if (!existed) { + if (!mkDir(chunk)) + return false; + } else { return false; + } } } } -- cgit v0.12 From d703c131bae6fb89672a55e1bcd735e2514e75ac Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:16 +0200 Subject: don't set FileType flag when link's target doesn't exists Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_win.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 11d1ca6..25fbae8 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -896,7 +896,7 @@ static inline bool rmDir(const QString &path) static inline bool isDirPath(const QString &dirPath, bool *existed) { QString path = dirPath; - if (path.length() == 2 &&path.at(1) == QLatin1Char(':')) + if (path.length() == 2 && path.at(1) == QLatin1Char(':')) path += QLatin1Char('\\'); DWORD fileAttrib = ::GetFileAttributes((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16()); @@ -1523,9 +1523,10 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil ret |= LinkType; QString l = readLink(d->filePath); if (!l.isEmpty()) { - if (isDirPath(l, 0)) + bool existed = false; + if (isDirPath(l, &existed) && existed) ret |= DirectoryType; - else + else if (existed) ret |= FileType; } } else if (d->doStat()) { -- cgit v0.12 From c9fb4ac3483c492f32e4f42987935478d4e89eb8 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:18 +0200 Subject: micro-optimization in QFSFileEngine::mkdir Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_unix.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index c0b6820..075aa7c 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -414,15 +414,15 @@ bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) con if ((st.st_mode & S_IFMT) != S_IFDIR) return false; } else if (QT_MKDIR(chunk, 0777) != 0) { - return false; + return false; } } } return true; } #if defined(Q_OS_DARWIN) // Mac X doesn't support trailing /'s - if (dirName[dirName.length() - 1] == QLatin1Char('/')) - dirName = dirName.left(dirName.length() - 1); + if (dirName.endsWith(QLatin1Char('/'))) + dirName.chop(1); #endif return (QT_MKDIR(QFile::encodeName(dirName), 0777) == 0); } -- cgit v0.12 From bcbaeff0332e30f020f031b99efcc69d9707f962 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:20 +0200 Subject: replace QFile::exists() by QT_STAT() respectively which is a bit faster since it doesn't creates new file engine instance Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_unix.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 075aa7c..cde5272 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -76,10 +76,14 @@ static QByteArray openModeToFopenMode(QIODevice::OpenMode flags, const QString & if ((flags & QIODevice::ReadOnly) && !(flags & QIODevice::Truncate)) { mode = "rb"; if (flags & QIODevice::WriteOnly) { - if (!fileName.isEmpty() &&QFile::exists(fileName)) - mode = "rb+"; - else + QT_STATBUF statBuf; + if (!fileName.isEmpty() + && QT_STAT(QFile::encodeName(fileName), &statBuf) == 0 + && (statBuf.st_mode & S_IFMT) == S_IFREG) { + mode += "+"; + } else { mode = "wb+"; + } } } else if (flags & QIODevice::WriteOnly) { mode = "wb"; -- cgit v0.12 From 0e193b51c995395c92f8b1d0b67a782314772c6c Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:23 +0200 Subject: avoid needless const_cast-s tried_stat, could_stat, need_lstat, and is_link are members marked as mutable; prefer mutable over const_cast Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_unix.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index cde5272..029d422 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -524,18 +524,19 @@ QFileInfoList QFSFileEngine::drives() bool QFSFileEnginePrivate::doStat() const { - if (tried_stat == 0) { - QFSFileEnginePrivate *that = const_cast(this); + if (!tried_stat) { + tried_stat = true; + could_stat = false; + if (fh && nativeFilePath.isEmpty()) { // ### actually covers two cases: d->fh and when the file is not open - that->could_stat = (QT_FSTAT(fileno(fh), &st) == 0); + could_stat = (QT_FSTAT(QT_FILENO(fh), &st) == 0); } else if (fd == -1) { // ### actually covers two cases: d->fh and when the file is not open - that->could_stat = (QT_STAT(nativeFilePath.constData(), &st) == 0); + could_stat = (QT_STAT(nativeFilePath.constData(), &st) == 0); } else { - that->could_stat = (QT_FSTAT(fd, &st) == 0); + could_stat = (QT_FSTAT(fd, &st) == 0); } - that->tried_stat = 1; } return could_stat; } @@ -543,10 +544,10 @@ bool QFSFileEnginePrivate::doStat() const bool QFSFileEnginePrivate::isSymlink() const { if (need_lstat) { - QFSFileEnginePrivate *that = const_cast(this); - that->need_lstat = false; + need_lstat = false; + QT_STATBUF st; // don't clobber our main one - that->is_link = (QT_LSTAT(nativeFilePath.constData(), &st) == 0) ? S_ISLNK(st.st_mode) : false; + is_link = (QT_LSTAT(nativeFilePath.constData(), &st) == 0) ? S_ISLNK(st.st_mode) : false; } return is_link; } -- cgit v0.12 From 7fe0dfb80efd67886a33fe8b37e9714175925688 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:25 +0200 Subject: avoid crash when testing HiddenFlag and BaseName is empty Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_unix.cpp | 3 ++- tests/auto/qfileinfo/tst_qfileinfo.cpp | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 029d422..4d451e6 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -656,7 +656,8 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const ret |= LocalDiskFlag; if (exists) ret |= ExistsFlag; - if (fileName(BaseName)[0] == QLatin1Char('.') + QString baseName = fileName(BaseName); + if ((baseName.size() > 0 && baseName.at(0) == QLatin1Char('.')) #if !defined(QWS) && defined(Q_OS_MAC) || _q_isMacHidden(d->filePath) #endif diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index a87e306..e2800e5 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -974,6 +974,9 @@ void tst_QFileInfo::isHidden_data() foreach (const QFileInfo& info, QDir::drives()) { QTest::newRow(qPrintable("drive." + info.path())) << info.path() << false; } +#if !defined(Q_OS_WIN) + QTest::newRow("/bin/") << QString::fromLatin1("/bin/") << false; +#endif #ifdef Q_OS_MAC QTest::newRow("mac_etc") << QString::fromLatin1("/etc") << true; QTest::newRow("mac_private_etc") << QString::fromLatin1("/private/etc") << false; -- cgit v0.12 From f36fb8b2b63b3734cc2bd66b329ca4fef1204845 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:27 +0200 Subject: '.' and '..' must not be hidden _unix code always sets HiddenFlag for special dirs which is wrong; also there is some inconsistence under win: * FindFirstFile sets FILE_ATTRIBUTE_HIDDEN flag for ".." of hidden dir *even* if parent dir is not hidden; * GetFileAttributes sets FILE_ATTRIBUTE_HIDDEN flag for ".." *only* if parent dir is hidden. so, _win part sets HiddenFlag wrong too; finally, we never test parent dir's flags; futhermore hidden special dirs (dotAndDotDot) makes dir iterator's filtering a bit more complex Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_unix.cpp | 18 +++++++++++------- src/corelib/io/qfsfileengine_win.cpp | 7 ++++--- tests/auto/qfileinfo/tst_qfileinfo.cpp | 13 +++++++++++++ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 4d451e6..ff10a44 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -656,15 +656,19 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const ret |= LocalDiskFlag; if (exists) ret |= ExistsFlag; - QString baseName = fileName(BaseName); - if ((baseName.size() > 0 && baseName.at(0) == QLatin1Char('.')) + if (d->filePath == QLatin1String("/")) { + ret |= RootFlag; + } else { + QString baseName = fileName(BaseName); + if ((baseName.size() > 1 + && baseName.at(0) == QLatin1Char('.') && baseName.at(1) != QLatin1Char('.')) #if !defined(QWS) && defined(Q_OS_MAC) - || _q_isMacHidden(d->filePath) + || _q_isMacHidden(d->filePath) #endif - ) - ret |= HiddenFlag; - if (d->filePath == QLatin1String("/")) - ret |= RootFlag; + ) { + ret |= HiddenFlag; + } + } } return ret; } diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 25fbae8..c2b993b 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1542,12 +1542,13 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil if (type & FlagsMask) { if(d->doStat()) { ret |= QAbstractFileEngine::FileFlags(ExistsFlag | LocalDiskFlag); - if (d->fileAttrib & FILE_ATTRIBUTE_HIDDEN) - ret |= HiddenFlag; if (d->filePath == QLatin1String("/") || (d->filePath.at(0).isLetter() && d->filePath.mid(1,d->filePath.length()) == QLatin1String(":/")) || isUncRoot(d->filePath)) { ret |= RootFlag; - ret &= ~HiddenFlag; + } else if (d->fileAttrib & FILE_ATTRIBUTE_HIDDEN) { + QString baseName = fileName(BaseName); + if (baseName != QLatin1String(".") && baseName != QLatin1String("..")) + ret |= HiddenFlag; } } } diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index e2800e5..fa2bd6e 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -974,9 +974,22 @@ void tst_QFileInfo::isHidden_data() foreach (const QFileInfo& info, QDir::drives()) { QTest::newRow(qPrintable("drive." + info.path())) << info.path() << false; } + +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + QTest::newRow("C:/RECYCLER") << QString::fromLatin1("C:/RECYCLER") << true; + QTest::newRow("C:/RECYCLER/.") << QString::fromLatin1("C:/RECYCLER/.") << false; + QTest::newRow("C:/RECYCLER/..") << QString::fromLatin1("C:/RECYCLER/..") << false; +#endif +#if defined(Q_OS_UNIX) + QTest::newRow("~/.qt") << QDir::homePath() + QString("/.qt") << true; + QTest::newRow("~/.qt/.") << QDir::homePath() + QString("/.qt/.") << false; + QTest::newRow("~/.qt/..") << QDir::homePath() + QString("/.qt/..") << false; +#endif + #if !defined(Q_OS_WIN) QTest::newRow("/bin/") << QString::fromLatin1("/bin/") << false; #endif + #ifdef Q_OS_MAC QTest::newRow("mac_etc") << QString::fromLatin1("/etc") << true; QTest::newRow("mac_private_etc") << QString::fromLatin1("/private/etc") << false; -- cgit v0.12 From 53576b4d3c3e7325d01efba6c4da80299492f2db Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:30 +0200 Subject: QFSFileEngine must set LocalDiskFlag regardless file exists or not LocalDiskFlag actually means "Local File Engine" and can be effectively used for testing file path for target storage type (local/network/virtual and so on) Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_win.cpp | 5 +++-- tests/auto/qfileinfo/tst_qfileinfo.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index c2b993b..52fe44e 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1540,8 +1540,9 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil } } if (type & FlagsMask) { - if(d->doStat()) { - ret |= QAbstractFileEngine::FileFlags(ExistsFlag | LocalDiskFlag); + ret |= LocalDiskFlag; + if (d->doStat()) { + ret |= ExistsFlag; if (d->filePath == QLatin1String("/") || (d->filePath.at(0).isLetter() && d->filePath.mid(1,d->filePath.length()) == QLatin1String(":/")) || isUncRoot(d->filePath)) { ret |= RootFlag; diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index fa2bd6e..306ca49 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -147,6 +147,9 @@ private slots: void isBundle_data(); void isBundle(); + void isLocalFs_data(); + void isLocalFs(); + void refresh(); #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) @@ -1024,6 +1027,29 @@ void tst_QFileInfo::isBundle() QCOMPARE(fi.isBundle(), isBundle); } +void tst_QFileInfo::isLocalFs_data() +{ + QTest::addColumn("path"); + QTest::addColumn("isLocalFs"); + + QTest::newRow("local root") << QString::fromLatin1("/") << true; + QTest::newRow("local non-existent file") << QString::fromLatin1("/abrakadabra.boo") << true; + + QTest::newRow("qresource root") << QString::fromLatin1(":/") << false; +} + +void tst_QFileInfo::isLocalFs() +{ + QFETCH(QString, path); + QFETCH(bool, isLocalFs); + + QFileInfo info(path); + QFileInfoPrivate *privateInfo = getPrivate(info); + QVERIFY(privateInfo->data->fileEngine); + QCOMPARE(bool(privateInfo->data->fileEngine->fileFlags(QAbstractFileEngine::LocalDiskFlag) + & QAbstractFileEngine::LocalDiskFlag), isLocalFs); +} + void tst_QFileInfo::refresh() { #if defined(Q_OS_WINCE) -- cgit v0.12 From 7fe142cfcf27632a455ce193fa57c131afea61cc Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:33 +0200 Subject: move dubbed code into static funtion Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_win.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 52fe44e..2c9b977 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -337,6 +337,13 @@ static bool uncShareExists(const QString &server) return false; } +static bool isDriveRoot(const QString &path) +{ + return (path.length() == 3 + && path.at(0).isLetter() && path.at(1) == QLatin1Char(':') + && path.at(2) == QLatin1Char('/')); +} + static QString nativeAbsoluteFilePathCore(const QString &path) { QString ret; @@ -1217,8 +1224,8 @@ bool QFSFileEnginePrivate::doStat() const could_stat = fileAttrib != INVALID_FILE_ATTRIBUTES; if (!could_stat) { #if !defined(Q_OS_WINCE) - if (!fname.isEmpty() && fname.at(0).isLetter() && fname.mid(1, fname.length()) == QLatin1String(":/")) { - // an empty drive ?? + if (isDriveRoot(fname)) { + // a valid drive ?? DWORD drivesBitmask = ::GetLogicalDrives(); int drivebit = 1 << (fname.at(0).toUpper().unicode() - QLatin1Char('A').unicode()); if (drivesBitmask & drivebit) { @@ -1543,8 +1550,7 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil ret |= LocalDiskFlag; if (d->doStat()) { ret |= ExistsFlag; - if (d->filePath == QLatin1String("/") || (d->filePath.at(0).isLetter() && d->filePath.mid(1,d->filePath.length()) == QLatin1String(":/")) - || isUncRoot(d->filePath)) { + if (d->filePath == QLatin1String("/") || isDriveRoot(d->filePath) || isUncRoot(d->filePath)) { ret |= RootFlag; } else if (d->fileAttrib & FILE_ATTRIBUTE_HIDDEN) { QString baseName = fileName(BaseName); -- cgit v0.12 From 2c36b1ec645991535ca974dc9e0d5ce812f0708a Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:35 +0200 Subject: don't mix calculated and forced permission bits this commit just moves closing bracket to the function end Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_win.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 2c9b977..a512bd6 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1481,25 +1481,25 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const //### what to do with permissions if we don't use NTFS // for now just add all permissions and what about exe missions ?? // also qt_ntfs_permission_lookup is now not set by defualt ... should it ? - ret |= QAbstractFileEngine::ReadOtherPerm | QAbstractFileEngine::ReadGroupPerm + ret |= QAbstractFileEngine::ReadOtherPerm | QAbstractFileEngine::ReadGroupPerm | QAbstractFileEngine::ReadOwnerPerm | QAbstractFileEngine::ReadUserPerm | QAbstractFileEngine::WriteUserPerm | QAbstractFileEngine::WriteOwnerPerm | QAbstractFileEngine::WriteGroupPerm | QAbstractFileEngine::WriteOtherPerm; - } - if (doStat()) { - if (ret & (QAbstractFileEngine::WriteOwnerPerm | QAbstractFileEngine::WriteUserPerm | - QAbstractFileEngine::WriteGroupPerm | QAbstractFileEngine::WriteOtherPerm)) { - if (fileAttrib & FILE_ATTRIBUTE_READONLY) - ret &= ~(QAbstractFileEngine::WriteOwnerPerm | QAbstractFileEngine::WriteUserPerm | - QAbstractFileEngine::WriteGroupPerm | QAbstractFileEngine::WriteOtherPerm); - } + if (doStat()) { + if (ret & (QAbstractFileEngine::WriteOwnerPerm | QAbstractFileEngine::WriteUserPerm | + QAbstractFileEngine::WriteGroupPerm | QAbstractFileEngine::WriteOtherPerm)) { + if (fileAttrib & FILE_ATTRIBUTE_READONLY) + ret &= ~(QAbstractFileEngine::WriteOwnerPerm | QAbstractFileEngine::WriteUserPerm | + QAbstractFileEngine::WriteGroupPerm | QAbstractFileEngine::WriteOtherPerm); + } - QString ext = filePath.right(4).toLower(); - if (ext == QLatin1String(".exe") || ext == QLatin1String(".com") || ext == QLatin1String(".bat") || - ext == QLatin1String(".pif") || ext == QLatin1String(".cmd") || (fileAttrib & FILE_ATTRIBUTE_DIRECTORY)) - ret |= QAbstractFileEngine::ExeOwnerPerm | QAbstractFileEngine::ExeGroupPerm | - QAbstractFileEngine::ExeOtherPerm | QAbstractFileEngine::ExeUserPerm; + QString ext = filePath.right(4).toLower(); + if (ext == QLatin1String(".exe") || ext == QLatin1String(".com") || ext == QLatin1String(".bat") || + ext == QLatin1String(".pif") || ext == QLatin1String(".cmd") || (fileAttrib & FILE_ATTRIBUTE_DIRECTORY)) + ret |= QAbstractFileEngine::ExeOwnerPerm | QAbstractFileEngine::ExeGroupPerm | + QAbstractFileEngine::ExeOtherPerm | QAbstractFileEngine::ExeUserPerm; + } } return ret; } -- cgit v0.12 From 1ff4c70e181e79456690a23a3af97cfef52c9f5e Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:37 +0200 Subject: don't mix link's target's permissions with link's Exe*Perm bits Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_win.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index a512bd6..9e341b9 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1494,7 +1494,8 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const QAbstractFileEngine::WriteGroupPerm | QAbstractFileEngine::WriteOtherPerm); } - QString ext = filePath.right(4).toLower(); + QString fname = filePath.endsWith(QLatin1String(".lnk")) ? readLink(filePath) : filePath; + QString ext = fname.right(4).toLower(); if (ext == QLatin1String(".exe") || ext == QLatin1String(".com") || ext == QLatin1String(".bat") || ext == QLatin1String(".pif") || ext == QLatin1String(".cmd") || (fileAttrib & FILE_ATTRIBUTE_DIRECTORY)) ret |= QAbstractFileEngine::ExeOwnerPerm | QAbstractFileEngine::ExeGroupPerm | -- cgit v0.12 From a7e9efcb96a93f23636e8bc98bb89b705a82cbf4 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:39 +0200 Subject: optimize longFileName() a bit isUncPath() is always called with native separator-ed paths, so we can avoid needless comparisons; don't declare isUncPath() under CE since it never used Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_win.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 9e341b9..a6c2c17 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -295,13 +295,14 @@ static bool isUncRoot(const QString &server) return localPath.isEmpty(); } +#if !defined(Q_OS_WINCE) static bool isUncPath(const QString &path) { - // Starts with // or \\, but not \\. or //. - return (path.startsWith(QLatin1String("//")) - || path.startsWith(QLatin1String("\\\\"))) - && (path.size() > 2 && path.at(2) != QLatin1Char('.')); + // Starts with \\, but not \\. + return (path.startsWith(QLatin1String("\\\\")) + && path.size() > 2 && path.at(2) != QLatin1Char('.')); } +#endif static bool isRelativePath(const QString &path) { @@ -398,7 +399,7 @@ QString QFSFileEnginePrivate::longFileName(const QString &path) #if !defined(Q_OS_WINCE) QString prefix = QLatin1String("\\\\?\\"); if (isUncPath(absPath)) { - prefix = QLatin1String("\\\\?\\UNC\\"); + prefix.append(QLatin1String("UNC\\")); // "\\\\?\\UNC\\" absPath.remove(0, 2); } return prefix + absPath; -- cgit v0.12 From 085d1cb57d240e5335517ccd08da699d4faeed6a Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:42 +0200 Subject: minor optimizations -in most cases GetFullPathName returns string with at least path.size() chars; -". " isn't valid path; ". " isn't valid path too...should we to pay more? Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_win.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index a6c2c17..3a5e9f4 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -349,7 +349,7 @@ static QString nativeAbsoluteFilePathCore(const QString &path) { QString ret; #if !defined(Q_OS_WINCE) - QVarLengthArray buf(MAX_PATH); + QVarLengthArray buf(qMax(MAX_PATH, path.size() + 1)); wchar_t *fileName = 0; DWORD retLen = GetFullPathName((wchar_t*)path.utf16(), buf.size(), buf.data(), &fileName); if (retLen > (DWORD)buf.size()) { @@ -375,15 +375,8 @@ static QString nativeAbsoluteFilePath(const QString &path) // (which is an invalid filename) this function will strip the space off and viola, // the file is later reported as existing. Therefore, we re-add the whitespace that // was at the end of path in order to keep the filename invalid. - int i = path.size() - 1; - while (i >= 0 && path.at(i) == QLatin1Char(' ')) --i; - int extraws = path.size() - 1 - i; - if (extraws >= 0) { - while (extraws) { - absPath.append(QLatin1Char(' ')); - --extraws; - } - } + if (!path.isEmpty() && path.at(path.size() - 1) == QLatin1Char(' ')) + absPath.append(QLatin1Char(' ')); return absPath; } -- cgit v0.12 From 7c46245633a1edfbdc1ff770a28a7d5e7a5739bf Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:44 +0200 Subject: optimize inlines in QFSFileEngine un-inline isDirPath() since it too large for this (reduce size of QtCore binary in a few kilobytes) Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_unix.cpp | 6 +++--- src/corelib/io/qfsfileengine_win.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index ff10a44..50ed46d 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -70,7 +70,7 @@ QT_BEGIN_NAMESPACE Returns the stdlib open string corresponding to a QIODevice::OpenMode. */ -static QByteArray openModeToFopenMode(QIODevice::OpenMode flags, const QString &fileName = QString()) +static inline QByteArray openModeToFopenMode(QIODevice::OpenMode flags, const QString &fileName) { QByteArray mode; if ((flags & QIODevice::ReadOnly) && !(flags & QIODevice::Truncate)) { @@ -109,7 +109,7 @@ static QByteArray openModeToFopenMode(QIODevice::OpenMode flags, const QString & Returns the stdio open flags corresponding to a QIODevice::OpenMode. */ -static int openModeToOpenFlags(QIODevice::OpenMode mode) +static inline int openModeToOpenFlags(QIODevice::OpenMode mode) { int oflags = QT_OPEN_RDONLY; #ifdef QT_LARGEFILE_SUPPORT @@ -138,7 +138,7 @@ static int openModeToOpenFlags(QIODevice::OpenMode mode) Sets the file descriptor to close on exec. That is, the file descriptor is not inherited by child processes. */ -static bool setCloseOnExec(int fd) +static inline bool setCloseOnExec(int fd) { return fd != -1 && fcntl(fd, F_SETFD, FD_CLOEXEC) != -1; } diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 3a5e9f4..e669752 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -296,7 +296,7 @@ static bool isUncRoot(const QString &server) } #if !defined(Q_OS_WINCE) -static bool isUncPath(const QString &path) +static inline bool isUncPath(const QString &path) { // Starts with \\, but not \\. return (path.startsWith(QLatin1String("\\\\")) @@ -304,7 +304,7 @@ static bool isUncPath(const QString &path) } #endif -static bool isRelativePath(const QString &path) +static inline bool isRelativePath(const QString &path) { return !(path.startsWith(QLatin1Char('/')) || (path.length() >= 2 @@ -338,7 +338,7 @@ static bool uncShareExists(const QString &server) return false; } -static bool isDriveRoot(const QString &path) +static inline bool isDriveRoot(const QString &path) { return (path.length() == 3 && path.at(0).isLetter() && path.at(1) == QLatin1Char(':') @@ -894,7 +894,7 @@ static inline bool rmDir(const QString &path) return ::RemoveDirectory((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16()); } -static inline bool isDirPath(const QString &dirPath, bool *existed) +static bool isDirPath(const QString &dirPath, bool *existed) { QString path = dirPath; if (path.length() == 2 && path.at(1) == QLatin1Char(':')) -- cgit v0.12 From 96a578afeaf2ee08db3eeea0f0250e8b08bcf9b6 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:46 +0200 Subject: merge nativeAbsoluteFilePath and nativeAbsoluteFilePathCore Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_win.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index e669752..edf65d2 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -345,9 +345,9 @@ static inline bool isDriveRoot(const QString &path) && path.at(2) == QLatin1Char('/')); } -static QString nativeAbsoluteFilePathCore(const QString &path) +static QString nativeAbsoluteFilePath(const QString &path) { - QString ret; + QString absPath; #if !defined(Q_OS_WINCE) QVarLengthArray buf(qMax(MAX_PATH, path.size() + 1)); wchar_t *fileName = 0; @@ -357,19 +357,13 @@ static QString nativeAbsoluteFilePathCore(const QString &path) retLen = GetFullPathName((wchar_t*)path.utf16(), buf.size(), buf.data(), &fileName); } if (retLen != 0) - ret = QString::fromWCharArray(buf.data(), retLen); + absPath = QString::fromWCharArray(buf.data(), retLen); #else if (path.startsWith(QLatin1Char('/')) || path.startsWith(QLatin1Char('\\'))) - ret = QDir::toNativeSeparators(path); + absPath = QDir::toNativeSeparators(path); else - ret = QDir::toNativeSeparators(QDir::cleanPath(qfsPrivateCurrentDir + QLatin1Char('/') + path)); + absPath = QDir::toNativeSeparators(QDir::cleanPath(qfsPrivateCurrentDir + QLatin1Char('/') + path)); #endif - return ret; -} - -static QString nativeAbsoluteFilePath(const QString &path) -{ - QString absPath = nativeAbsoluteFilePathCore(path); // This is really ugly, but GetFullPathName strips off whitespace at the end. // If you for instance write ". " in the lineedit of QFileDialog, // (which is an invalid filename) this function will strip the space off and viola, -- cgit v0.12 From 1693931ac92a6a7d98eb28acda371f2d7c9c6dc2 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:48 +0200 Subject: code clean-up and style fixes remove unused includes; tabs -> whitespaces; clean extra whitespaces Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_iterator.cpp | 1 - src/corelib/io/qfsfileengine_iterator_p.h | 2 +- src/corelib/io/qfsfileengine_iterator_unix.cpp | 2 +- src/corelib/io/qfsfileengine_iterator_win.cpp | 12 +++----- src/corelib/io/qfsfileengine_unix.cpp | 4 +-- src/corelib/io/qfsfileengine_win.cpp | 41 +++++++++++--------------- 6 files changed, 25 insertions(+), 37 deletions(-) diff --git a/src/corelib/io/qfsfileengine_iterator.cpp b/src/corelib/io/qfsfileengine_iterator.cpp index 35b388f..52fc80d 100644 --- a/src/corelib/io/qfsfileengine_iterator.cpp +++ b/src/corelib/io/qfsfileengine_iterator.cpp @@ -79,4 +79,3 @@ QFileInfo QFSFileEngineIterator::currentFileInfo() const QT_END_NAMESPACE #endif // QT_NO_FSFILEENGINE - diff --git a/src/corelib/io/qfsfileengine_iterator_p.h b/src/corelib/io/qfsfileengine_iterator_p.h index 7829fff..342ef8d 100644 --- a/src/corelib/io/qfsfileengine_iterator_p.h +++ b/src/corelib/io/qfsfileengine_iterator_p.h @@ -89,4 +89,4 @@ QT_END_NAMESPACE #endif // QT_NO_FSFILEENGINE -#endif +#endif // QFSFILEENGINE_ITERATOR_P_H diff --git a/src/corelib/io/qfsfileengine_iterator_unix.cpp b/src/corelib/io/qfsfileengine_iterator_unix.cpp index a6c965c..107a500 100644 --- a/src/corelib/io/qfsfileengine_iterator_unix.cpp +++ b/src/corelib/io/qfsfileengine_iterator_unix.cpp @@ -56,7 +56,7 @@ public: #if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) , mt_file(0) #endif - { } + {} DIR *dir; dirent *dirEntry; diff --git a/src/corelib/io/qfsfileengine_iterator_win.cpp b/src/corelib/io/qfsfileengine_iterator_win.cpp index dd4ddf3..3d9c20e 100644 --- a/src/corelib/io/qfsfileengine_iterator_win.cpp +++ b/src/corelib/io/qfsfileengine_iterator_win.cpp @@ -39,14 +39,11 @@ ** ****************************************************************************/ -#include "qdebug.h" #include "qfsfileengine_iterator_p.h" #include "qfsfileengine_p.h" #include "qplatformdefs.h" #include -#include -#include QT_BEGIN_NAMESPACE @@ -56,7 +53,7 @@ public: inline QFSFileEngineIteratorPlatformSpecificData() : uncShareIndex(-1), findFileHandle(INVALID_HANDLE_VALUE), done(false), uncFallback(false) - { } + {} QFSFileEngineIterator *it; @@ -68,7 +65,6 @@ public: bool done; bool uncFallback; - void advance(); void saveCurrentFileName(); }; @@ -116,10 +112,10 @@ bool QFSFileEngineIterator::hasNext() const { if (platform->done) return false; - + if (platform->uncFallback) return platform->uncShareIndex > 0 && platform->uncShareIndex <= platform->uncShares.size(); - + if (platform->findFileHandle == INVALID_HANDLE_VALUE) { QString path = this->path(); // Local directory @@ -151,7 +147,7 @@ bool QFSFileEngineIterator::hasNext() const platform->done = true; } } else { - platform->done = true; + platform->done = true; } } diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 50ed46d..7d91764 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -582,7 +582,7 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const { Q_D(const QFSFileEngine); // Force a stat, so that we're guaranteed to get up-to-date results - if (type & QAbstractFileEngine::FileFlag(QAbstractFileEngine::Refresh)) { + if (type & Refresh) { d->tried_stat = 0; d->need_lstat = 1; } @@ -777,7 +777,7 @@ QString QFSFileEngine::fileName(FileName file) const s[len] = '\0'; ret += QFile::decodeName(QByteArray(s)); #if defined(__GLIBC__) && !defined(PATH_MAX) - ::free(s); + ::free(s); #endif if (!ret.startsWith(QLatin1Char('/'))) { diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index edf65d2..0cddee3 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -47,10 +47,6 @@ #include "qfile.h" #include "qdir.h" -#include "qtemporaryfile.h" -#ifndef QT_NO_REGEXP -# include "qregexp.h" -#endif #include "private/qmutexpool_p.h" #include "qvarlengtharray.h" #include "qdatetime.h" @@ -125,7 +121,7 @@ static TRUSTEE_W currentUserTrusteeW; typedef BOOL (WINAPI *PtrOpenProcessToken)(HANDLE, DWORD, PHANDLE ); static PtrOpenProcessToken ptrOpenProcessToken = 0; -typedef BOOL (WINAPI *PtrGetUserProfileDirectoryW)( HANDLE, LPWSTR, LPDWORD); +typedef BOOL (WINAPI *PtrGetUserProfileDirectoryW)(HANDLE, LPWSTR, LPDWORD); static PtrGetUserProfileDirectoryW ptrGetUserProfileDirectoryW = 0; typedef BOOL (WINAPI *PtrSetFilePointerEx)(HANDLE, LARGE_INTEGER, PLARGE_INTEGER, DWORD); static PtrSetFilePointerEx ptrSetFilePointerEx = 0; @@ -266,7 +262,7 @@ bool QFSFileEnginePrivate::uncListSharesOnServer(const QString &server, QStringL do { res = ptrNetShareEnum((wchar_t*)server.utf16(), 1, (LPBYTE *)&BufPtr, DWORD(-1), &er, &tr, &resume); if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA) { - p=BufPtr; + p = BufPtr; for (i = 1; i <= er; ++i) { if (list && p->shi1_type == 0) list->append(QString::fromWCharArray(p->shi1_netname)); @@ -276,7 +272,6 @@ bool QFSFileEnginePrivate::uncListSharesOnServer(const QString &server, QStringL ptrNetApiBufferFree(BufPtr); } while (res==ERROR_MORE_DATA); return res == ERROR_SUCCESS; - } return false; } @@ -306,10 +301,11 @@ static inline bool isUncPath(const QString &path) static inline bool isRelativePath(const QString &path) { + // drive, e.g. "a:", or UNC root, e.q. "//" return !(path.startsWith(QLatin1Char('/')) || (path.length() >= 2 && ((path.at(0).isLetter() && path.at(1) == QLatin1Char(':')) - || (path.at(0) == QLatin1Char('/') && path.at(1) == QLatin1Char('/'))))); // drive, e.g. a: + || (path.at(0) == QLatin1Char('/') && path.at(1) == QLatin1Char('/'))))); } static QString fixIfRelativeUncPath(const QString &path) @@ -328,12 +324,8 @@ static bool uncShareExists(const QString &server) QStringList parts = server.split(QLatin1Char('\\'), QString::SkipEmptyParts); if (parts.count()) { QStringList shares; - if (QFSFileEnginePrivate::uncListSharesOnServer(QLatin1String("\\\\") + parts.at(0), &shares)) { - if (parts.count() >= 2) - return shares.contains(parts.at(1), Qt::CaseInsensitive); - else - return true; - } + if (QFSFileEnginePrivate::uncListSharesOnServer(QLatin1String("\\\\") + parts.at(0), &shares)) + return parts.count() >= 2 ? shares.contains(parts.at(1), Qt::CaseInsensitive) : true; } return false; } @@ -400,8 +392,8 @@ QString QFSFileEnginePrivate::longFileName(const QString &path) */ void QFSFileEnginePrivate::nativeInitFileName() { - QString path = longFileName(QDir::toNativeSeparators(fixIfRelativeUncPath(filePath))); - nativeFilePath = QByteArray((const char *)path.utf16(), path.size() * 2 + 1); + QString path = longFileName(QDir::toNativeSeparators(fixIfRelativeUncPath(filePath))); + nativeFilePath = QByteArray((const char *)path.utf16(), path.size() * 2 + 1); } /* @@ -423,8 +415,7 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE }; // WriteOnly can create files, ReadOnly cannot. - DWORD creationDisp = (openMode & QIODevice::WriteOnly) - ? OPEN_ALWAYS : OPEN_EXISTING; + DWORD creationDisp = (openMode & QIODevice::WriteOnly) ? OPEN_ALWAYS : OPEN_EXISTING; // Create the file handle. fileHandle = CreateFile((const wchar_t*)nativeFilePath.constData(), @@ -1145,10 +1136,10 @@ QFileInfoList QFSFileEngine::drives() char driveName[] = "A:/"; while(driveBits) { - if(driveBits & 1) - ret.append(QString::fromLatin1(driveName)); - driveName[0]++; - driveBits = driveBits >> 1; + if(driveBits & 1) + ret.append(QString::fromLatin1(driveName)); + driveName[0]++; + driveBits = driveBits >> 1; } return ret; #else @@ -1501,7 +1492,7 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil Q_D(const QFSFileEngine); QAbstractFileEngine::FileFlags ret = 0; // Force a stat, so that we're guaranteed to get up-to-date results - if (type & QAbstractFileEngine::FileFlag(QAbstractFileEngine::Refresh)) { + if (type & Refresh) { d->tried_stat = 0; } @@ -1647,10 +1638,11 @@ QString QFSFileEngine::fileName(FileName file) const bool QFSFileEngine::isRelativePath() const { Q_D(const QFSFileEngine); + // drive, e.g. "a:", or UNC root, e.q. "//" return !(d->filePath.startsWith(QLatin1Char('/')) || (d->filePath.length() >= 2 && ((d->filePath.at(0).isLetter() && d->filePath.at(1) == QLatin1Char(':')) - || (d->filePath.at(0) == QLatin1Char('/') && d->filePath.at(1) == QLatin1Char('/'))))); // drive, e.g. a: + || (d->filePath.at(0) == QLatin1Char('/') && d->filePath.at(1) == QLatin1Char('/'))))); } uint QFSFileEngine::ownerId(FileOwner /*own*/) const @@ -1966,4 +1958,5 @@ void QFSFileEnginePrivate::mapHandleClose() } } #endif + QT_END_NAMESPACE -- cgit v0.12 From e0059d1d01a7c1d76ed86cccf8253d0ebd18f575 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 6 Apr 2009 18:28:13 +0200 Subject: Handle multi-length strings in the low-level formatting code Patch originally from Oswald on Jira QT-10, with few a modifications. If a string contains multiple variants sorted by decreasing length, separated by \x9c, it will try to paint the longest variant which fits into the bounding box. Reviewed-by: Oswald Buddenhagen Task-Number: QT-10 --- src/gui/painting/qpainter.cpp | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 8192fb7..c3fc14b 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -7486,12 +7486,14 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, int *underlinePositions = underlinePositionStack; QFontMetricsF fm(fnt); - QString text = str; + int offset = 0; +start_lenghtVariant: + bool hasMoreLenghtVariants = false; // compatible behaviour to the old implementation. Replace // tabs by spaces - QChar *chr = text.data(); - const QChar *end = chr + str.length(); + QChar *chr = text.data() + offset; + QChar *end = text.data() + text.length(); bool has_tab = false; while (chr != end) { if (*chr == QLatin1Char('\r') || (singleline && *chr == QLatin1Char('\n'))) { @@ -7502,12 +7504,17 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, ++maxUnderlines; } else if (*chr == QLatin1Char('\t')) { has_tab = true; + } else if (*chr == QChar(ushort(0x9c))) { + // string with multiple length variants + end = chr; + hasMoreLenghtVariants = true; + break; } ++chr; } if (has_tab) { if (!expandtabs) { - chr = text.data(); + chr = text.data() + offset; while (chr != end) { if (*chr == QLatin1Char('\t')) *chr = QLatin1Char(' '); @@ -7518,12 +7525,13 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, } } + QChar *cout = end; if (hidemnmemonic || showmnemonic) { if (maxUnderlines > 32) underlinePositions = new int[maxUnderlines]; - QChar *cout = text.data(); + cout = text.data() + offset; QChar *cin = cout; - int l = str.length(); + int l = end - cout; while (l) { if (*cin == QLatin1Char('&')) { ++cin; @@ -7538,9 +7546,6 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, ++cin; --l; } - int newlen = cout - text.unicode(); - if (newlen != text.length()) - text.resize(newlen); } // no need to do extra work for underlines if we don't paint @@ -7551,13 +7556,12 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, qreal height = 0; qreal width = 0; - QStackTextEngine engine(text, fnt); + QString finalText = text.mid(offset, cout - (text.data() + offset)); + QStackTextEngine engine(finalText, fnt); if (option) { engine.option = *option; } - - engine.option.setTextDirection(layout_direction); if (tf & Qt::AlignJustify) engine.option.setAlignment(Qt::AlignJustify); @@ -7573,7 +7577,7 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, textLayout.setCacheEnabled(true); textLayout.engine()->underlinePositions = underlinePositions; - if (text.isEmpty()) { + if (finalText.isEmpty()) { height = fm.height(); width = 0; tf |= Qt::TextDontPrint; @@ -7638,6 +7642,10 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, } } QRectF bounds = QRectF(r.x() + xoff, r.y() + yoff, width, height); + if (hasMoreLenghtVariants && !r.contains(bounds)) { + offset = end - text.data() + 1; + goto start_lenghtVariant; + } if (brect) *brect = bounds; -- cgit v0.12 From c225767b9b50336432e39cd589637df4fe721d62 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 11 May 2009 12:45:51 +0200 Subject: Add the Qt::TextLongestVariant flag so QFontMetrics::size returns the size of the biggest string In case the strings contains multiple strings separated by \x9c Reviewed-by: Oswald Buddenhagen Task-number: QT-10 --- doc/src/classes/qnamespace.qdoc | 1 + src/corelib/global/qnamespace.h | 3 ++- src/gui/painting/qpainter.cpp | 3 ++- src/gui/text/qfontmetrics.cpp | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/src/classes/qnamespace.qdoc b/doc/src/classes/qnamespace.qdoc index 18ecd7b..5872d04 100644 --- a/doc/src/classes/qnamespace.qdoc +++ b/doc/src/classes/qnamespace.qdoc @@ -490,6 +490,7 @@ \omitvalue WordBreak \omitvalue TextForceLeftToRight \omitvalue TextForceRightToLeft + \omitvalue TextLongestVariant Always use the longest variant when computing the size of a multi-variant string You can use as many modifier flags as you want, except that Qt::TextSingleLine and Qt::TextWordWrap cannot be combined. diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index f172d77..4024fce 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -233,7 +233,8 @@ public: TextHideMnemonic = 0x8000, TextJustificationForced = 0x10000, TextForceLeftToRight = 0x20000, - TextForceRightToLeft = 0x40000 + TextForceRightToLeft = 0x40000, + TextLongestVariant = 0x80000 #if defined(QT3_SUPPORT) && !defined(Q_MOC_RUN) ,SingleLine = TextSingleLine, diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index c3fc14b..4d9b43a 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -7642,7 +7642,8 @@ start_lenghtVariant: } } QRectF bounds = QRectF(r.x() + xoff, r.y() + yoff, width, height); - if (hasMoreLenghtVariants && !r.contains(bounds)) { + + if (hasMoreLenghtVariants && !(tf & Qt::TextLongestVariant) && !r.contains(bounds)) { offset = end - text.data() + 1; goto start_lenghtVariant; } diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 012c0f6..47d3864 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -798,7 +798,7 @@ QRect QFontMetrics::boundingRect(const QRect &rect, int flags, const QString &te */ QSize QFontMetrics::size(int flags, const QString &text, int tabStops, int *tabArray) const { - return boundingRect(QRect(0,0,0,0), flags, text, tabStops, tabArray).size(); + return boundingRect(QRect(0,0,0,0), flags | Qt::TextLongestVariant, text, tabStops, tabArray).size(); } /*! -- cgit v0.12 From caebd2676dda37fb7ab11c3b994fd341f88b0de0 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 11 May 2009 12:46:58 +0200 Subject: Make QFontMetrics::elidedText aware of multi-length strings Reviewed-by: Oswald Buddenhagen Task-number: QT-10 --- src/gui/text/qfontmetrics.cpp | 17 ++++++++++++++-- tests/auto/qfontmetrics/tst_qfontmetrics.cpp | 30 +++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 47d3864..5c5320f 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -859,8 +859,21 @@ QRect QFontMetrics::tightBoundingRect(const QString &text) const language. */ -QString QFontMetrics::elidedText(const QString &text, Qt::TextElideMode mode, int width, int flags) const -{ +QString QFontMetrics::elidedText(const QString &_text, Qt::TextElideMode mode, int width, int flags) const +{ + QString text = _text; + if (!(flags & Qt::TextLongestVariant)) { + int posA = 0; + int posB = text.indexOf(QLatin1Char('\x9c')); + while (posB >= 0) { + QString portion = text.mid(posA, posB - posA); + if (size(flags, portion).width() <= width) + return portion; + posA = posB + 1; + posB = text.indexOf(QLatin1Char('\x9c'), posA); + } + text = text.mid(posA); + } QStackTextEngine engine(text, QFont(d)); return engine.elidedText(mode, width, flags); } diff --git a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp index 5658055..cae1126 100644 --- a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp +++ b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp @@ -71,6 +71,7 @@ private slots: void elidedText(); void veryNarrowElidedText(); void averageCharWidth(); + void elidedMultiLenght(); }; tst_QFontMetrics::tst_QFontMetrics() @@ -168,7 +169,8 @@ void tst_QFontMetrics::elidedText_data() QTest::addColumn("font"); QTest::addColumn("text"); - QTest::newRow("helvetica hello") << QFont("helvetica",10) << QString("hello"); + QTest::newRow("helvetica hello") << QFont("helvetica",10) << QString("hello") ; + QTest::newRow("helvetica hello &Bye") << QFont("helvetica",10) << QString("hello&Bye") ; } @@ -178,9 +180,9 @@ void tst_QFontMetrics::elidedText() QFETCH(QString, text); QFontMetrics fm(font); int w = fm.width(text); - QString newtext = fm.elidedText(text,Qt::ElideRight,w); + QString newtext = fm.elidedText(text,Qt::ElideRight,w, 0); QCOMPARE(text,newtext); // should not elide - newtext = fm.elidedText(text,Qt::ElideRight,w-1); + newtext = fm.elidedText(text,Qt::ElideRight,w-1, 0); QVERIFY(text != newtext); // should elide } @@ -201,5 +203,27 @@ void tst_QFontMetrics::averageCharWidth() QVERIFY(fmf.averageCharWidth() != 0); } +void tst_QFontMetrics::elidedMultiLenght() +{ + QString text1 = "Long Text 1\x9cShorter\x9csmall"; + QString text1_long = "Long Text 1"; + QString text1_short = "Shorter"; + QString text1_small = "small"; + QFontMetrics fm = QFontMetrics(QFont()); + int width_long = fm.width(text1_long); + QCOMPARE(fm.elidedText(text1,Qt::ElideRight, 8000), text1_long); + QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_long), text1_long); + QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_long - 1), text1_short); + int width_short = fm.width(text1_short); + QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_short), text1_short); + QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_short - 1), text1_small); + + QChar ellipsisChar(0x2026); + QString text1_el = QString::fromLatin1("sm") + ellipsisChar; + int width_small = fm.width(text1_el); + QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_small + 1), text1_el); + +} + QTEST_MAIN(tst_QFontMetrics) #include "tst_qfontmetrics.moc" -- cgit v0.12 From 60ca03709c7e9845b997520dab70ac1ac76787dd Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 20 Apr 2009 12:51:57 +0200 Subject: Change QFontMetrics::width to return the width of the longest variant if the string is a multi-length one Task-number: QT-10 Reviewed-by: Oswald Buddenhagen --- src/gui/text/qfontmetrics.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 5c5320f..4229d5b 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -528,12 +528,14 @@ int QFontMetrics::rightBearing(QChar ch) const */ int QFontMetrics::width(const QString &text, int len) const { + int pos = text.indexOf(QLatin1Char('\x9c')); + QString txt = (pos == -1) ? text : text.left(pos); if (len < 0) - len = text.length(); + len = txt.length(); if (len == 0) return 0; - QTextEngine layout(text, d); + QTextEngine layout(txt, d); layout.ignoreBidi = true; return qRound(layout.width(0, len)); } -- cgit v0.12 From 5c4c47facfcb75b0277872a0fac813ab41700e5e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 11 Aug 2009 19:12:07 +0200 Subject: Optimize qt_format_text test operations: try not to detach Reviewed-by: Oswald Buddenhagen --- src/gui/painting/qpainter.cpp | 68 ++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 40 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 4d9b43a..cd4ea86 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -7480,10 +7480,9 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, if (!painter) tf |= Qt::TextDontPrint; - int maxUnderlines = 0; + uint maxUnderlines = 0; int numUnderlines = 0; - int underlinePositionStack[32]; - int *underlinePositions = underlinePositionStack; + QVarLengthArray underlinePositions(1); QFontMetricsF fm(fnt); QString text = str; @@ -7492,54 +7491,46 @@ start_lenghtVariant: bool hasMoreLenghtVariants = false; // compatible behaviour to the old implementation. Replace // tabs by spaces - QChar *chr = text.data() + offset; - QChar *end = text.data() + text.length(); bool has_tab = false; - while (chr != end) { - if (*chr == QLatin1Char('\r') || (singleline && *chr == QLatin1Char('\n'))) { - *chr = QLatin1Char(' '); - } else if (*chr == QLatin1Char('\n')) { - *chr = QChar::LineSeparator; - } else if (*chr == QLatin1Char('&')) { + int old_offset = offset; + for (; offset < text.length(); offset++) { + QChar chr = text.at(offset); + if (chr == QLatin1Char('\r') || (singleline && chr == QLatin1Char('\n'))) { + text[offset] = QLatin1Char(' '); + } else if (chr == QLatin1Char('\n')) { + chr = QChar::LineSeparator; + } else if (chr == QLatin1Char('&')) { ++maxUnderlines; - } else if (*chr == QLatin1Char('\t')) { + } else if (chr == QLatin1Char('\t')) { + if (!expandtabs) { + text[offset] = QLatin1Char(' '); + } else if (!tabarraylen && !tabstops) { + tabstops = qRound(fm.width(QLatin1Char('x'))*8); + } has_tab = true; - } else if (*chr == QChar(ushort(0x9c))) { + } else if (chr == QChar(ushort(0x9c))) { // string with multiple length variants - end = chr; hasMoreLenghtVariants = true; break; } - ++chr; - } - if (has_tab) { - if (!expandtabs) { - chr = text.data() + offset; - while (chr != end) { - if (*chr == QLatin1Char('\t')) - *chr = QLatin1Char(' '); - ++chr; - } - } else if (!tabarraylen && !tabstops) { - tabstops = qRound(fm.width(QLatin1Char('x'))*8); - } } - QChar *cout = end; - if (hidemnmemonic || showmnemonic) { - if (maxUnderlines > 32) - underlinePositions = new int[maxUnderlines]; - cout = text.data() + offset; + int length = offset - old_offset; + if ((hidemnmemonic || showmnemonic) && maxUnderlines > 0) { + underlinePositions.resize(maxUnderlines + 1); + + QChar *cout = text.data() + old_offset; QChar *cin = cout; - int l = end - cout; + int l = length; while (l) { if (*cin == QLatin1Char('&')) { ++cin; + --length; --l; if (!l) break; if (*cin != QLatin1Char('&') && !hidemnmemonic) - underlinePositions[numUnderlines++] = cout - text.unicode(); + underlinePositions[numUnderlines++] = cout - text.data() - old_offset; } *cout = *cin; ++cout; @@ -7556,7 +7547,7 @@ start_lenghtVariant: qreal height = 0; qreal width = 0; - QString finalText = text.mid(offset, cout - (text.data() + offset)); + QString finalText = text.mid(old_offset, length); QStackTextEngine engine(finalText, fnt); if (option) { engine.option = *option; @@ -7575,7 +7566,7 @@ start_lenghtVariant: engine.forceJustification = true; QTextLayout textLayout(&engine); textLayout.setCacheEnabled(true); - textLayout.engine()->underlinePositions = underlinePositions; + textLayout.engine()->underlinePositions = underlinePositions.data(); if (finalText.isEmpty()) { height = fm.height(); @@ -7644,7 +7635,7 @@ start_lenghtVariant: QRectF bounds = QRectF(r.x() + xoff, r.y() + yoff, width, height); if (hasMoreLenghtVariants && !(tf & Qt::TextLongestVariant) && !r.contains(bounds)) { - offset = end - text.data() + 1; + offset++; goto start_lenghtVariant; } if (brect) @@ -7673,9 +7664,6 @@ start_lenghtVariant: painter->restore(); } } - - if (underlinePositions != underlinePositionStack) - delete [] underlinePositions; } /*! -- cgit v0.12 From 9605898c99490c9ad2b8cc1eb367d5531a18d1e3 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 11 Aug 2009 20:30:16 +0200 Subject: Doc: Fixed code snippets in QReadLocker and QWriteLocker documentation. Reviewed-by: Trust Me --- doc/src/snippets/code/src_corelib_thread_qreadwritelock.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/src/snippets/code/src_corelib_thread_qreadwritelock.cpp b/doc/src/snippets/code/src_corelib_thread_qreadwritelock.cpp index f0f4935..dd4f533 100644 --- a/doc/src/snippets/code/src_corelib_thread_qreadwritelock.cpp +++ b/doc/src/snippets/code/src_corelib_thread_qreadwritelock.cpp @@ -38,9 +38,9 @@ QReadWriteLock lock; QByteArray readData() { - locker.lockForRead(); + lock.lockForRead(); ... - locker.unlock(); + lock.unlock(); return data; } //! [2] @@ -62,8 +62,8 @@ QReadWriteLock lock; void writeData(const QByteArray &data) { - locker.lockForWrite(); + lock.lockForWrite(); ... - locker.unlock(); + lock.unlock(); } //! [4] -- cgit v0.12 From 4d2436df6e4af090158adaa916dedf7ee5f757f0 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 11 Aug 2009 21:02:29 +0200 Subject: Update the css_borderimage test to test the menubar as well The menu bar is currently broken with border-image, fix is about to be commited Task-number: 230363 --- .../baseline/css_borderimage_allwidgets.ui | 399 +++++++++++---------- 1 file changed, 218 insertions(+), 181 deletions(-) diff --git a/tests/auto/uiloader/baseline/css_borderimage_allwidgets.ui b/tests/auto/uiloader/baseline/css_borderimage_allwidgets.ui index baba66b..0ece79a 100644 --- a/tests/auto/uiloader/baseline/css_borderimage_allwidgets.ui +++ b/tests/auto/uiloader/baseline/css_borderimage_allwidgets.ui @@ -1,209 +1,246 @@ - Form - + MainWindow + 0 0 - 553 - 368 + 606 + 388 - Form + MainWindow * { border-image: url("images/pushbutton.png") 6 6 6 6; border-width:6px; } - - - - - - - - - - Each widget should have a background image. including the top level - - - true - - - - - - - PushButton - - - - - - - 24 - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - PushButton - - - - - - - - - - RadioButton - - - - - - - true - - - - - 0 - 0 - 260 - 197 - + + + + + + + + + + + Each widget should have a background image. including the top level + + + true - - - - - Qt::Horizontal - - - - - - - - - - RadioButton - - - - - - - RadioButton - - - - - - - CheckBox - - - - - - - CheckBox - - - - - - - - - - - - - GroupBox - - - - - - CheckBox - - - - - - - Line Edit - - - - - - + + + - New Item + PushButton + + + + + + + 24 + + + + + + + Qt::Vertical + + + + 20 + 40 + - - + + + + + + + + + + - New Item + PushButton - - + + + + + + + - New Item + RadioButton + + + + + + + true - - + + + + 0 + 0 + 260 + 197 + + + + + + + Qt::Horizontal + + + + + + + + + + RadioButton + + + + + + + RadioButton + + + + + + + CheckBox + + + + + + + CheckBox + + + + + + + + + + + + + + GroupBox + + + + - New Item + CheckBox - - + + + + - New Item + Line Edit - - - - - - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - + + + + + + + New Item + + + + + New Item + + + + + New Item + + + + + New Item + + + + + New Item + + + + + + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + 0 + 0 + 606 + 36 + + + + + File + + + + + + + Edit + + + + + + + + + Open + + + + + Close + + -- cgit v0.12 From b564809ddc3d894b31eff58833e4b71f9e7ae7a2 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 11 Aug 2009 21:02:51 +0200 Subject: QMenuBar does not respect the border-image stylesheet property Added WA_StyledBackground to QMenuBar when using style sheets. This also implies that CE_PanelMenuBar (drawing only the menubar border) no longer needs to be drawn. Tested in uiloader/baselne/css_borderimage_allwidgets.ui. Task-number: 230363 Reviewed-by: olivier --- src/gui/styles/qstylesheetstyle.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index 5f6d4ab..7523883 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -2734,6 +2734,9 @@ void QStyleSheetStyle::polish(QWidget *w) #ifndef QT_NO_MDIAREA || qobject_cast(w) #endif +#ifndef QT_NO_MENUBAR + || qobject_cast(w) +#endif || qobject_cast(w)) { w->setAttribute(Qt::WA_StyledBackground, true); } @@ -3456,6 +3459,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q case CE_MenuEmptyArea: case CE_MenuBarEmptyArea: if (rule.hasDrawable()) { + // Drawn by PE_Widget return; } break; @@ -3606,6 +3610,11 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q subRule.drawRule(p, opt->rect); QCommonStyle::drawControl(ce, &mi, p, w); } else { + if (rule.hasDrawable() && !(opt->state & QStyle::State_Selected)) { + // So that the menu bar background is not hidden by the items + mi.palette.setColor(QPalette::Window, Qt::transparent); + mi.palette.setColor(QPalette::Button, Qt::transparent); + } baseStyle()->drawControl(ce, &mi, p, w); } } @@ -4189,7 +4198,6 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op #endif //fall tghought case PE_PanelMenu: - case PE_PanelMenuBar: case PE_PanelStatusBar: if(rule.hasDrawable()) { rule.drawRule(p, opt->rect); @@ -4197,6 +4205,13 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op } break; + case PE_PanelMenuBar: + if (rule.hasDrawable()) { + // Drawn by PE_Widget + return; + } + break; + case PE_IndicatorToolBarSeparator: case PE_IndicatorToolBarHandle: { PseudoElement ps = pe == PE_IndicatorToolBarHandle ? PseudoElement_ToolBarHandle : PseudoElement_ToolBarSeparator; -- cgit v0.12 From 84ff44e7ecf9ef28ebedfedf170ec45fe0cb9ffd Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Wed, 12 Aug 2009 12:45:52 +1000 Subject: Update stale license headers. Reviewed-by: Trust Me --- tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.cpp | 41 ++++++++++++++++++---- tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.h | 41 ++++++++++++++++++---- .../xmlpatternsxqts/lib/XSDTestSuiteHandler.cpp | 41 ++++++++++++++++++---- .../auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.h | 41 ++++++++++++++++++---- 4 files changed, 140 insertions(+), 24 deletions(-) diff --git a/tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.cpp b/tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.cpp index b19eb91..b18e4f7 100644 --- a/tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.cpp +++ b/tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.cpp @@ -1,14 +1,43 @@ /**************************************************************************** ** -** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the Patternist project on Trolltech Labs. +** This file is part of the autotests of the Qt Toolkit. ** -** $TROLLTECH_GPL_LICENSE$ +** $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 either Technology Preview License Agreement or the +** Beta Release License Agreement. ** -*************************************************************************** -*/ +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ #include #include diff --git a/tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.h b/tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.h index ce84988..30b5a02 100644 --- a/tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.h +++ b/tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.h @@ -1,14 +1,43 @@ /**************************************************************************** ** -** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the Patternist project on Trolltech Labs. +** This file is part of the autotests of the Qt Toolkit. ** -** $TROLLTECH_GPL_LICENSE$ +** $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 either Technology Preview License Agreement or the +** Beta Release License Agreement. ** -*************************************************************************** -*/ +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ #ifndef PatternistSDK_XSDTSTestCase_H #define PatternistSDK_XSDTSTestCase_H diff --git a/tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.cpp b/tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.cpp index b6ee379..a0e30a0 100644 --- a/tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.cpp +++ b/tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.cpp @@ -1,14 +1,43 @@ /**************************************************************************** ** -** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the Patternist project on Trolltech Labs. +** This file is part of the autotests of the Qt Toolkit. ** -** $TROLLTECH_GPL_LICENSE$ +** $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 either Technology Preview License Agreement or the +** Beta Release License Agreement. ** -*************************************************************************** -*/ +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ #include diff --git a/tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.h b/tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.h index 8c57e82..7b039f4 100644 --- a/tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.h +++ b/tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.h @@ -1,14 +1,43 @@ /**************************************************************************** ** -** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary