From 91c1ec98c10d8ce89932f7df69e3de33d80beeff Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Wed, 23 Sep 2009 16:48:31 +1000 Subject: Fix compile error in MEDIA_SERVER code. Reviewed-by: Gareth Pethig --- src/gui/kernel/qsound_qws.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qsound_qws.cpp b/src/gui/kernel/qsound_qws.cpp index 33a0922..8595faa 100644 --- a/src/gui/kernel/qsound_qws.cpp +++ b/src/gui/kernel/qsound_qws.cpp @@ -279,7 +279,7 @@ QAuBucketQWS::QAuBucketQWS( QAuServerQWS *server, QSound *sound, QObject* parent sound->setObjectName( m_id.toString() ); - m_channel = new QCopChannel(QLatin1String("QPE/QSound/") + m_id ), this ); + m_channel = new QCopChannel(QLatin1String("QPE/QSound/") + m_id, this ); connect( m_channel, SIGNAL(received(QString,QByteArray)), this, SLOT(processMessage(QString,QByteArray)) ); -- cgit v0.12 From 24071323009135108023698ef2f8b266f5437f5c Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 22 Sep 2009 16:28:15 +0200 Subject: QJpegImageHandle: Avoid smooth scalling when it should not. Task-number: QTBUG-3211 Task-number: 236875 Reviewed-by: Alex --- src/plugins/imageformats/jpeg/qjpeghandler.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp index 5fcbb5f..3b23e56 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp +++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp @@ -895,7 +895,8 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, (void) jpeg_finish_decompress(&cinfo); } #ifndef QT_NO_IMAGE_SMOOTHSCALE - } else if (scaledSize.isValid()) { + } else if (scaledSize.isValid() && scaledSize != QSize(cinfo.output_width, cinfo.output_height) + && quality >= HIGH_QUALITY_THRESHOLD) { jpegSmoothScaler scaler(&cinfo, QString().sprintf("Scale( %d, %d, ScaleFree )", scaledSize.width(), @@ -946,6 +947,9 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, outImage->setDotsPerMeterX(int(100. * cinfo.X_density)); outImage->setDotsPerMeterY(int(100. * cinfo.Y_density)); } + + if (scaledSize.isValid() && scaledSize != QSize(cinfo.output_width, cinfo.output_height)) + *outImage = outImage->scaled(scaledSize, Qt::IgnoreAspectRatio, Qt::FastTransformation); } } -- cgit v0.12 From e73d4d577410ce0724c818cd0d4a28b7ff7350bb Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 23 Sep 2009 10:01:37 +0200 Subject: Fix compilation errors in qcombobox autotest Dependency on windows style, without including the header file Needed static casts to compare QWidget* with QComboBox* at least for the Nokia x86 compiler. Reviewed-by: axis --- tests/auto/qcombobox/tst_qcombobox.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/auto/qcombobox/tst_qcombobox.cpp b/tests/auto/qcombobox/tst_qcombobox.cpp index b549af6..8dfe836 100644 --- a/tests/auto/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/qcombobox/tst_qcombobox.cpp @@ -77,6 +77,9 @@ #include #include "../../shared/util.h" #include +#ifndef QT_NO_STYLE_WINDOWS +#include +#endif //TESTED_CLASS= //TESTED_FILES= @@ -2140,7 +2143,7 @@ void tst_QComboBox::task247863_keyBoardSelection() combo.addItem( QLatin1String("222")); combo.show(); QApplication::setActiveWindow(&combo); - QTRY_COMPARE(QApplication::activeWindow(), &combo); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(&combo)); QSignalSpy spy(&combo, SIGNAL(activated(const QString &))); qApp->setEffectEnabled(Qt::UI_AnimateCombo, false); @@ -2161,7 +2164,7 @@ void tst_QComboBox::task220195_keyBoardSelection2() combo.addItem( QLatin1String("foo3")); combo.show(); QApplication::setActiveWindow(&combo); - QTRY_COMPARE(QApplication::activeWindow(), &combo); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(&combo)); combo.setCurrentIndex(-1); QVERIFY(combo.currentText().isNull()); @@ -2353,6 +2356,9 @@ void tst_QComboBox::subControlRectsWithOffset() void tst_QComboBox::task260974_menuItemRectangleForComboBoxPopup() { +#ifdef QT_NO_STYLE_WINDOWS + QSKIP("test depends on windows style", QTest::SkipAll); +#else class TestStyle: public QWindowsStyle { public: @@ -2385,6 +2391,7 @@ void tst_QComboBox::task260974_menuItemRectangleForComboBoxPopup() QTRY_VERIFY(style.discoveredRect.width() <= comboBox.width()); } +#endif } QTEST_MAIN(tst_QComboBox) -- cgit v0.12 From d05b4b85ebdf520895faa1e360aa673b739866a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Wed, 23 Sep 2009 10:51:27 +0200 Subject: Added a comment to clarify the purpose of a piece of code. Reviewed-by: Trust Me --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 25f4184..9db1de8 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -297,7 +297,7 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph) for (int y = 0; y < maskHeight; ++y) { uchar *src = (uchar *) mask.scanLine(y); for (int x = 0; x < maskWidth; ++x) - src[x] = -src[x]; + src[x] = -src[x]; // convert 0 and 1 into 0 and 255 } } -- cgit v0.12 From 4d7b6f75073eb2559cbc3e63db6743641539ac4e Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 23 Sep 2009 10:49:54 +0200 Subject: tests/auto/qaudiooutput deployment rules fixed for Windows CE Reviewed-by: TrustMe --- tests/auto/qaudiooutput/qaudiooutput.pro | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/auto/qaudiooutput/qaudiooutput.pro b/tests/auto/qaudiooutput/qaudiooutput.pro index 6c07c64..8657edb 100644 --- a/tests/auto/qaudiooutput/qaudiooutput.pro +++ b/tests/auto/qaudiooutput/qaudiooutput.pro @@ -1,12 +1,14 @@ load(qttest_p4) -DEFINES += SRCDIR=\\\"$$PWD/\\\" - SOURCES += tst_qaudiooutput.cpp QT = core multimedia -wince*: { - deploy.sources += 4.wav - DEPLOYMENT = deploy +wince* { + deploy.sources += 4.wav + DEPLOYMENT = deploy + DEFINES += SRCDIR=\\\"\\\" + QT += gui +} else { + DEFINES += SRCDIR=\\\"$$PWD/\\\" } -- cgit v0.12 From 05647bc3a8d5085885dca398682b8b315bc79e6c Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 23 Sep 2009 10:52:35 +0200 Subject: tests/auto/qaudioinput deployment rules fixed for Windows CE Reviewed-by: TrustMe --- tests/auto/qaudioinput/qaudioinput.pro | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/auto/qaudioinput/qaudioinput.pro b/tests/auto/qaudioinput/qaudioinput.pro index 8a03749..f545a11 100644 --- a/tests/auto/qaudioinput/qaudioinput.pro +++ b/tests/auto/qaudioinput/qaudioinput.pro @@ -1,7 +1,15 @@ load(qttest_p4) -DEFINES += SRCDIR=\\\"$$PWD/\\\" - SOURCES += tst_qaudioinput.cpp QT = core multimedia + +wince* { + deploy.sources += 4.wav + DEPLOYMENT = deploy + DEFINES += SRCDIR=\\\"\\\" + QT += gui +} else { + DEFINES += SRCDIR=\\\"$$PWD/\\\" +} + -- cgit v0.12 From b3a9565c99c44cdf4d3236de211110382c7b908b Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 23 Sep 2009 10:53:36 +0200 Subject: more meaningful output in tst_QAudioOutput::pullFile Reviewed-by: TrustMe --- tests/auto/qaudiooutput/tst_qaudiooutput.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/auto/qaudiooutput/tst_qaudiooutput.cpp b/tests/auto/qaudiooutput/tst_qaudiooutput.cpp index 6356fb3..db2444b 100644 --- a/tests/auto/qaudiooutput/tst_qaudiooutput.cpp +++ b/tests/auto/qaudiooutput/tst_qaudiooutput.cpp @@ -117,37 +117,37 @@ void tst_QAudioOutput::notifyInterval() void tst_QAudioOutput::pullFile() { if(available) { - QFile filename(SRCDIR "4.wav"); - QVERIFY(filename.exists()); - filename.open(QIODevice::ReadOnly); + QFile file(SRCDIR "4.wav"); + QVERIFY(file.exists()); + file.open(QIODevice::ReadOnly); QSignalSpy readSignal(audio, SIGNAL(notify())); audio->setNotifyInterval(100); - audio->start(&filename); + audio->start(&file); QTestEventLoop::instance().enterLoop(1); + QCOMPARE(audio->totalTime(), qint64(692250)); // 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(); + file.close(); } } void tst_QAudioOutput::pushFile() { if(available) { - QFile filename(SRCDIR "4.wav"); - QVERIFY(filename.exists()); - filename.open(QIODevice::ReadOnly); + QFile file(SRCDIR "4.wav"); + QVERIFY(file.exists()); + file.open(QIODevice::ReadOnly); - const qint64 fileSize = filename.size(); + const qint64 fileSize = file.size(); QIODevice* feed = audio->start(0); char* buffer = new char[fileSize]; - filename.read(buffer, fileSize); + file.read(buffer, fileSize); qint64 counter=0; qint64 written=0; @@ -162,7 +162,7 @@ void tst_QAudioOutput::pushFile() QVERIFY(audio->totalTime() == 692250); audio->stop(); - filename.close(); + file.close(); delete [] buffer; delete audio; } -- cgit v0.12 From 0ab4d027de7ed6ae0c848499aacea8a23dc9042c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Wed, 23 Sep 2009 11:06:45 +0200 Subject: Small API addition: Make addChildLayoutItem available for subclasses. Many people have requested this. And since its protected it does not really pollute the API a lot. Task: QTBUG-3524 Reviewed-by: mbm --- src/gui/graphicsview/qgraphicslayout.cpp | 18 ++++++++++++++++++ src/gui/graphicsview/qgraphicslayout.h | 1 + 2 files changed, 19 insertions(+) diff --git a/src/gui/graphicsview/qgraphicslayout.cpp b/src/gui/graphicsview/qgraphicslayout.cpp index 0e4df71..f9800bc 100644 --- a/src/gui/graphicsview/qgraphicslayout.cpp +++ b/src/gui/graphicsview/qgraphicslayout.cpp @@ -419,6 +419,24 @@ void QGraphicsLayout::widgetEvent(QEvent *e) \sa itemAt(), count() */ +/*! + This function is a convenience function provided for custom layouts, and will go through + all items in the layout and reparent their graphics items to the closest QGraphicsWidget + ancestor of the layout. + + If \a layoutItem is already in a different layout, it will be removed from that layout. + + If custom layouts want special behaviour they can ignore to use this function, and implement + their own behaviour. + + \sa graphicsItem() + */ +void QGraphicsLayout::addChildLayoutItem(QGraphicsLayoutItem *layoutItem) +{ + Q_D(QGraphicsLayout); + d->addChildLayoutItem(layoutItem); +} + QT_END_NAMESPACE #endif //QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicslayout.h b/src/gui/graphicsview/qgraphicslayout.h index e872980..e214a62 100644 --- a/src/gui/graphicsview/qgraphicslayout.h +++ b/src/gui/graphicsview/qgraphicslayout.h @@ -78,6 +78,7 @@ public: protected: QGraphicsLayout(QGraphicsLayoutPrivate &, QGraphicsLayoutItem *); + void addChildLayoutItem(QGraphicsLayoutItem *layoutItem); private: Q_DISABLE_COPY(QGraphicsLayout) -- cgit v0.12 From 55cb8b6d1765d1446ae046a54d98aceeba9d9146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 23 Sep 2009 12:04:54 +0200 Subject: Fix autotest compilation --- tests/auto/q3table/tst_q3table.cpp | 2 +- tests/auto/qprogressbar/tst_qprogressbar.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/auto/q3table/tst_q3table.cpp b/tests/auto/q3table/tst_q3table.cpp index 1fe4412..ca65852 100644 --- a/tests/auto/q3table/tst_q3table.cpp +++ b/tests/auto/q3table/tst_q3table.cpp @@ -1379,7 +1379,7 @@ void tst_Q3Table::dateTimeEdit() TimeTableItem *ti = new TimeTableItem(testWidget); testWidget->setItem(0, 0, ti); testWidget->show(); - QTest::qWaitForWindowShown(&testWidget); + QTest::qWaitForWindowShown(testWidget); #ifdef WAITS QTest::qWait(50); #endif diff --git a/tests/auto/qprogressbar/tst_qprogressbar.cpp b/tests/auto/qprogressbar/tst_qprogressbar.cpp index ea9798b..d86094d 100644 --- a/tests/auto/qprogressbar/tst_qprogressbar.cpp +++ b/tests/auto/qprogressbar/tst_qprogressbar.cpp @@ -48,6 +48,8 @@ #include #include +#include "../../shared/util.h" + //TESTED_CLASS= //TESTED_FILES= -- cgit v0.12 From 77ac469063064a85cfec79fdc8d45cee0fa8e426 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 23 Sep 2009 13:39:40 +0300 Subject: Removed explicit TARGET.EPOCHEAPSIZE statements from script tests Large enough max heap for script tests is now defined by default for all tests in qttest_p4.prf, so removed the statements from individual script tests. Reviewed-by: Janne Anttila --- tests/auto/qscriptengine/qscriptengine.pro | 1 - tests/auto/qscriptextqobject/qscriptextqobject.pro | 4 ---- tests/auto/qscriptjstestsuite/qscriptjstestsuite.pro | 10 ++++------ tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro | 2 -- 4 files changed, 4 insertions(+), 13 deletions(-) diff --git a/tests/auto/qscriptengine/qscriptengine.pro b/tests/auto/qscriptengine/qscriptengine.pro index f72c070..d4c0f4c 100644 --- a/tests/auto/qscriptengine/qscriptengine.pro +++ b/tests/auto/qscriptengine/qscriptengine.pro @@ -12,5 +12,4 @@ wince*|symbian*: { symbian: { TARGET.UID3 = 0xE0340006 DEFINES += SYMBIAN_SRCDIR_UID=$$lower($$replace(TARGET.UID3,"0x","")) - TARGET.EPOCHEAPSIZE="0x100000 0x1000000 // Min 1Mb, max 16Mb" } diff --git a/tests/auto/qscriptextqobject/qscriptextqobject.pro b/tests/auto/qscriptextqobject/qscriptextqobject.pro index 9da7f47..140a4e6 100644 --- a/tests/auto/qscriptextqobject/qscriptextqobject.pro +++ b/tests/auto/qscriptextqobject/qscriptextqobject.pro @@ -1,7 +1,3 @@ load(qttest_p4) QT = core gui script SOURCES += tst_qscriptextqobject.cpp - -symbian: { - TARGET.EPOCHEAPSIZE="0x100000 0x1000000 // Min 1Mb, max 16Mb" -} diff --git a/tests/auto/qscriptjstestsuite/qscriptjstestsuite.pro b/tests/auto/qscriptjstestsuite/qscriptjstestsuite.pro index 06b861e..07a4672 100644 --- a/tests/auto/qscriptjstestsuite/qscriptjstestsuite.pro +++ b/tests/auto/qscriptjstestsuite/qscriptjstestsuite.pro @@ -1,12 +1,10 @@ load(qttest_p4) QT = core script SOURCES += tst_qscriptjstestsuite.cpp -symbian { - TARGET.EPOCHEAPSIZE = 0x020000 0xA00000 -} else { - DEFINES += SRCDIR=\\\"$$PWD\\\" -} -wince*|symbian*: { + +!symbian: DEFINES += SRCDIR=\\\"$$PWD\\\" + +wince*|symbian: { testFiles.sources = tests testFiles.path = . DEPLOYMENT += testFiles diff --git a/tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro b/tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro index 3f641b5..03e26bd 100644 --- a/tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro +++ b/tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro @@ -8,5 +8,3 @@ testFiles.sources = tests testFiles.path = . DEPLOYMENT += testFiles } - -symbian:TARGET.EPOCHEAPSIZE = 0x00020000 0x02000000 -- cgit v0.12 From d1d65ed17d0f21e979a98ab695aa9e50c6ee078c Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Wed, 23 Sep 2009 12:50:12 +0200 Subject: Make gtkstyle work on non-developer machines again While refactoring gtkstyle in 4.6, the "0" .so suffix was dropped. This patch restores the 4.5 behavior to look for *.so.0 since the *.so is only available if you install the gtk developer packages. Reviewed-by: jbache --- src/gui/styles/gtksymbols.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/styles/gtksymbols.cpp b/src/gui/styles/gtksymbols.cpp index 23d25bd..1cb0ca4 100644 --- a/src/gui/styles/gtksymbols.cpp +++ b/src/gui/styles/gtksymbols.cpp @@ -211,7 +211,8 @@ static QString classPath(GtkWidget *widget) static void resolveGtk() { - QLibrary libgtk(QLS("gtk-x11-2.0")); + // enforce the "0" suffix, so we'll open libgtk-x11-2.0.so.0 + QLibrary libgtk(QLS("gtk-x11-2.0"), 0, 0); QGtk::gtk_init = (Ptr_gtk_init)libgtk.resolve("gtk_init"); QGtk::gtk_window_new = (Ptr_gtk_window_new)libgtk.resolve("gtk_window_new"); QGtk::gtk_style_attach = (Ptr_gtk_style_attach)libgtk.resolve("gtk_style_attach"); -- cgit v0.12 From a5f3e301a2026649704c71e0039fbddf0cda96fe Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Wed, 23 Sep 2009 21:00:19 +1000 Subject: Add platform-specific README's. These files were previously added to source packages by the packaging system. There's no reason why these files shouldn't be available to repo users too. Reviewed-by: Trust Me --- README.s60 | 181 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.wince | 44 +++++++++++++++ 2 files changed, 225 insertions(+) create mode 100644 README.s60 create mode 100644 README.wince diff --git a/README.s60 b/README.s60 new file mode 100644 index 0000000..c3108af --- /dev/null +++ b/README.s60 @@ -0,0 +1,181 @@ +This is Qt version %VERSION%. + +Qt is a comprehensive cross-platform C++ application framework. With +this pre-release you can make advanced graphical applications and +utilize TCP/IP connections. More specifically, these modules are now +available for S60: + +QtCore - http://doc.trolltech.com/4.5/qtcore.html +QtGui - http://doc.trolltech.com/4.5/qtgui.html +QtNetwork - http://doc.trolltech.com/4.5/qtnetwork.html +QtScript - http://doc.trolltech.com/4.5/qtscript.html +QtSql - http://doc.trolltech.com/4.5/qtsql.html +QtSvg - http://doc.trolltech.com/4.5/qtsvg.html +QtTest - http://doc.trolltech.com/4.5/qttest.html +QtWebKit - http://doc.trolltech.com/4.5/qtwebkit.html +QtXml - http://doc.trolltech.com/4.5/qtxml.html +Phonon - http://doc.trolltech.com/4.5/phonon-module.html + +INSTALLING Qt + +Follow the instructions in the INSTALL file. + +REFERENCE DOCUMENTATION + +The Qt reference documentation is available locally in Qt's doc/html +directory or at http://doc.trolltech.com/4.5/index.html + +SUPPORTED PLATFORMS + +For this release, the following platforms have been tested: + + S60 3.1, 3.2 and 5.0 + +with these compilers: + + WINSCW (Emulator, X86) + RVCT (Hardware, ARM) + GCCE (Hardware, ARM)* + +The current version of GCCE cannot compile the Qt libraries +themselves as it has issues with global static data in DLLs. +However, we supply precompiled Qt libraries compiled with RVCT +that can be used instead. This makes it possible to write and +compile Qt applications using GCCE by linking to these +precompiled binaries. For more information on this issue see: +http://www3.symbian.com/faq.nsf/0/B8542F039C193CCC802573DA0011DFA7 + +HOW TO REPORT A BUG + +We have set up a special mailinglist for feedback on the S60 port. +Bug-reports, feedback or questions all go to this list. +Please go to http://pepper.troll.no/s60prereleases/ +for details on how to subscribe to the list. + +Before posting, please consult the FAQ and the list of known issues: +http://labs.trolltech.com/page/QtforS60FAQ +http://labs.trolltech.com/page/QtforS60KnownIssues + +Always include the following information in your bug report: the name +and version number of your compiler; the name and version number of +your operating system; the version of Qt you are using, and what +configure options it was compiled with. + +If the problem you are reporting is only visible at run-time, try to +create a small test program that shows the problem when run. Often, +such a program can be created with some minor changes to one of the +many example programs in Qt's examples directory. + + + INSTALLING Qt/S60 Version %VERSION% + +1. Install needed IDE and SDKs + + Make sure you have the following installed: + + - Carbide.c++ v2.0.0 or higher: + http://www.forum.nokia.com/main/resources/tools_and_sdks/carbide_cpp/ + + Note: It may be necessary to update the Carbide compiler. + See http://pepper.troll.no/s60prereleases/patches/ for instructions + how to check your compiler version and how to patch it, if needed. + + - S60 Platform SDK 3rd Edition FP1 or higher: + http://www.forum.nokia.com/main/resources/tools_and_sdks/S60SDK/ + + - Open C/C++ v1.6.0 or higher. Install this to all S60 SDKs you plan to use Qt with: + http://www.forum.nokia.com/main/resources/technologies/openc_cpp/ + + - Building Qt libraries for real device requires RVCT 2.2 [build 616] or later: + http://www.arm.com/products/DevTools/RVCT.html + + Make sure you have the following packages installed on any device you want to use to + run Qt applications. These packages can be found under nokia_plugin directory in any + S60 SDK where you have installed Open C/C++: + + - nokia_plugin\openc\s60opencsis\pips_s60_.sis + - nokia_plugin\openc\s60opencsis\openc_ssl_s60_.sis + - nokia_plugin\opencpp\s60opencppsis\stdcpp_s60_.sis + + These instructions assume the above tools are installed and + that the enviroment variables for your compiler are set correctly. + + Note: Users of S60 Platform SDK 3rd Edition FP1 also need special updates: + http://pepper.troll.no/s60prereleases/patches/ + +2. Install Qt + + Uncompress the package into the directory you want Qt installed, + e.g. C:\Qt\%VERSION%. + + Note: Qt must be installed on the same drive as the S60 SDK you are + using, and the install path must not contain any whitespaces. + +3. Environment variables + + In order to build and use Qt, the PATH environment variable needs + to be extended: + + PATH - to locate qmake, moc and other Qt tools + + This is done by adding c:\Qt\%VERSION%\bin to the PATH variable. + + On Windows the PATH can be extended by navigating to + "Control Panel->System->Advanced->Environment variables". + + In addition, you must configure the environment for use with the S60 + emulator. This is done by locating the Carbide.c++ submenu on the Start + menu, and choosing "Configure environment for WINSCW command line". + +4. Configure Qt + + To configure Qt for S60, do: + + cd \Qt\%VERSION% + configure -platform win32-mwc -xplatform symbian-abld + + For other options, type "configure -help" to get a list of all available + options. + +5. Build Qt + + To build Qt for the device, type: + + make release-armv5 + + To build Qt for the emulator, type: + + make debug-winscw + + Congratulations, Qt is now ready to use. + +6. Running Qt demos + + We've included a subset of the Qt demos in this package for you to try out. + An excellent starting point is the "fluidlauncher" demo. To run the demo on + a real device, you first have to install the Qt libraries on the device: + + cd src\s60installs + createpackage -i qt_libs_armv5_urel.pkg + + Note: You will need to supply certificate that allows installation of + binaries with "All -Tcb" capability to your device. + + Similarly, install fluidlauncher to the device: + + cd embedded\fluidlauncher + createpackage -i fluidlauncher_armv5_urel.pkg + + This will create a self-signed fluidlauncher_armv5_urel.sisx and install it to your device. + + To run the demos on the emulator simply navigate to the directory of the demo and run: + + make run + + Or, if you need to supply arguments to the program, navigate to + %EPOCROOT%\Epoc32\release\winscw\udeb\ and start any of the Qt demos located there, + for example: + + wiggly.exe -small-screen + + We hope you will enjoy using Qt. diff --git a/README.wince b/README.wince new file mode 100644 index 0000000..27dfd60 --- /dev/null +++ b/README.wince @@ -0,0 +1,44 @@ + Signing on Windows CE. + +Windows CE provides a security mechanism to ask the user to confirm +that he wants to use an application/library, which is unknown to the +system. This process gets repeated for each dependency of an +application, meaning each library the application links to, which is +not recognized yet. + +To simplify this process you can use signatures and certificates. A +certificate gets installed on the device and each file which is +signed with the according certificate can be launched without the +security warning. + +In case you want to use signatures for your project written in Qt, +configure provides the -signature option. You need to specify the +location of the .pfx file and qmake adds the signing step to the +build rules. + +If you need to select a separate signature for a specific project, +or you only want to sign this single project, you can use the +"SIGNATURE_FILE = foo.pfx" rule inside the project file. + +The above decribed rules apply for command line makefiles as well as +Visual Studio projects generated by qmake. + +Microsoft usually ships development signatures inside the SDK packages. +You can find them in the Tools subdirectory of the SDK root folder. + +Example: + +1. calling configure with signing enabled: +configure.exe -platform win32-msvc2005 -xplatform wincewm50pocket-msvc2005 +-signature C:\some\path\SDKSamplePrivDeveloper.pfx + +2. using pro file to specify signature +[inside .pro file] +... +TARGET = foo + +wince*: { + SIGNATURE_FILE = somepath\customSignature.pfx +} +... + -- cgit v0.12 From 0f23b6def41928c3312837deb20f824dde8ef486 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Wed, 23 Sep 2009 21:09:39 +1000 Subject: Remove supported platforms from dist/README. This is a maintenance headache. Just reference the canonical supported platforms list instead. Reviewed-by: Trust Me --- dist/README | 51 ++------------------------------------------------- 1 file changed, 2 insertions(+), 49 deletions(-) diff --git a/dist/README b/dist/README index d8ab958..05475e7 100644 --- a/dist/README +++ b/dist/README @@ -6,7 +6,7 @@ http://qt.nokia.com/doc/latest/qt4-intro.html for details. The Qt 4.x series is not binary compatible or source compatible with the 3.x series. For more information on porting from Qt 3 to Qt 4, see -http://qt.nokia.com/doc/latest/porting4.html . +http://qt.nokia.com/doc/latest/porting4.html. INSTALLING Qt @@ -37,58 +37,11 @@ The Qt reference documentation is available locally in Qt's doc/html directory. You can use Qt Assistant to view it; to launch Assistant, type 'assistant' on the command line or use the Start menu. On Mac OS X, you can find it in /Developer/Applications/Qt. The latest -documentation is available at http://qt.nokia.com/doc/ . +documentation is available at http://qt.nokia.com/doc/. SUPPORTED PLATFORMS -For this release, the following platforms have been tested: - - win32-g++ (mingw) - win32-msvc - win32-msvc2003 - win32-msvc2005 - win32-msvc2008 - - aix-xlc - aix-xlc-64 - hpux-acc - hpux-acc-64 - hpux-acc-o64 - hpux-g++ - hpux-g++-64 - hpuxi-acc-32 - hpuxi-acc-64 - linux-g++ - linux-icc - linux-icc-32 - linux-icc-64 - solaris-cc - solaris-cc-64 - solaris-g++ - solaris-g++-64 - - macx-g++ - macx-g++42 - - qws/linux-x86-g++ - qws/linux-arm-g++ - - wince50standard-armv4i-msvc2005 - wince50standard-armv4i-msvc2008 - wince50standard-mipsii-msvc2005 - wince50standard-mipsii-msvc2008 - wince50standard-x86-msvc2005 - wince50standard-x86-msvc2008 - wincewm50pocket-msvc2005 - wincewm50pocket-msvc2008 - wincewm50smart-msvc2005 - wincewm50smart-msvc2008 - wincewm60professional-msvc2005 - wincewm60professional-msvc2008 - wincewm60standard-msvc2005 - wincewm60standard-msvc2008 - For a complete list of supported platforms, see http://qt.nokia.com/doc/latest/supported-platforms.html. -- cgit v0.12 From b50c1540cc06860aab0d46f27566dce6d9fc53cf Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 23 Sep 2009 13:04:11 +0200 Subject: tst_QFileSystemWatcher::watchFileAndItsDirectory fixed for Windows CE We skip parts of watchDirectory for the same reason. Reviewed-by: thartman --- tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp index 489a1ed..32cbed3 100644 --- a/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp +++ b/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp @@ -487,6 +487,9 @@ void tst_QFileSystemWatcher::watchFileAndItsDirectory() timer.start(3000); eventLoop.exec(); QCOMPARE(fileChangedSpy.count(), 0); +#ifdef Q_OS_WINCE + QEXPECT_FAIL("poller", "Directory does not get updated on file removal(See #137910)", Abort); +#endif #if defined(Q_OS_SYMBIAN) && defined(Q_CC_RVCT) // Since native watcher is always used in real devices, this poller issue is irrelevant // Symbian file system does not change modification time on a directory when a file inside is changed -- cgit v0.12 From 767e833c6cd83e233adf00acea15a2581e905299 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 23 Sep 2009 13:30:31 +0200 Subject: Fix tst_QWidget::showMaximized on X11 On X11 We have to wait we get the size change from the window manager Reviewed-by: Jason Barron --- tests/auto/qwidget/tst_qwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 6cfa23b..b7ffd15 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -2000,7 +2000,7 @@ void tst_QWidget::showMaximized() QWidget widget; widget.setGeometry(0, 0, 10, 10); widget.showMaximized(); - QVERIFY(widget.size().width() > 20 && widget.size().height() > 20); + QTRY_VERIFY(widget.size().width() > 20 && widget.size().height() > 20); } #ifdef QT3_SUPPORT -- cgit v0.12 From d74b951c7380f8a210c701152ddafe6481c1a43b Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 23 Sep 2009 13:35:53 +0200 Subject: Fix new test so it works on QWS --- tests/auto/qapplication/tst_qapplication.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qapplication/tst_qapplication.cpp b/tests/auto/qapplication/tst_qapplication.cpp index c53fca8..abcacef 100644 --- a/tests/auto/qapplication/tst_qapplication.cpp +++ b/tests/auto/qapplication/tst_qapplication.cpp @@ -154,7 +154,7 @@ public: void tst_QApplication::sendEventsOnProcessEvents() { int argc = 0; - QApplication app(argc, 0); + QApplication app(argc, 0, QApplication::GuiServer); EventSpy spy; app.installEventFilter(&spy); -- cgit v0.12 From af71faf8cb2c9cbf34c408b81ce7ae1ef6c6403e Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Wed, 23 Sep 2009 12:40:05 +0200 Subject: QNAM HTTP Code: Properly remove aborted requests from processing This fixes a crash that occured because aborted requests were not properly removed from the channel.alreadyPipelinedRequests. Task-number: QTBUG-4507 Reviewed-by: Peter Hartmann --- src/network/access/qhttpnetworkconnection.cpp | 38 ++++++++++++++++++++-- .../access/qhttpnetworkconnectionchannel.cpp | 3 +- src/network/access/qhttpnetworkreply.cpp | 3 +- src/network/access/qhttpnetworkreply_p.h | 1 + 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 2aa84d0..27c0ed4 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -588,19 +588,53 @@ QString QHttpNetworkConnectionPrivate::errorDetail(QNetworkReply::NetworkError e return errorString; } +// this is called from the destructor of QHttpNetworkReply. It is called when +// the reply was finished correctly or when it was aborted. void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply) { Q_Q(QHttpNetworkConnection); - // remove the from active list. + // check if the reply is currently being processed or it is pipelined in for (int i = 0; i < channelCount; ++i) { + // is the reply associated the currently processing of this channel? if (channels[i].reply == reply) { channels[i].reply = 0; - if (reply->d_func()->isConnectionCloseEnabled()) + + if (!reply->isFinished() && !channels[i].alreadyPipelinedRequests.isEmpty()) { + // the reply had to be prematurely removed, e.g. it was not finished + // therefore we have to requeue the already pipelined requests. + channels[i].requeueCurrentlyPipelinedRequests(); + } + + // if HTTP mandates we should close + // or the reply is not finished yet, e.g. it was aborted + // we have to close that connection + if (reply->d_func()->isConnectionCloseEnabled() || !reply->isFinished()) channels[i].close(); + QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); return; } + + // is the reply inside the pipeline of this channel already? + for (int j = 0; j < channels[i].alreadyPipelinedRequests.length(); j++) { + if (channels[i].alreadyPipelinedRequests.at(j).second == reply) { + // Remove that HttpMessagePair + channels[i].alreadyPipelinedRequests.removeAt(j); + + channels[i].requeueCurrentlyPipelinedRequests(); + + // Since some requests had already been pipelined, but we removed + // one and re-queued the others + // we must force a connection close after the request that is + // currently in processing has been finished. + if (channels[i].reply) + channels[i].reply->d_func()->forceConnectionCloseEnabled = true; + + QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); + return; + } + } } // remove from the high priority queue if (!highPriorityQueue.isEmpty()) { diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 641b35b..beab9af 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -542,6 +542,7 @@ void QHttpNetworkConnectionChannel::allDone() if (resendCurrent || reply->d_func()->isConnectionCloseEnabled() || socket->state() != QAbstractSocket::ConnectedState) { // move the pipelined ones back to the main queue requeueCurrentlyPipelinedRequests(); + close(); } else { // there were requests pipelined in and we can continue HttpMessagePair messagePair = alreadyPipelinedRequests.takeFirst(); @@ -601,7 +602,6 @@ void QHttpNetworkConnectionChannel::requeueCurrentlyPipelinedRequests() connection->d_func()->requeueRequest(alreadyPipelinedRequests.at(i)); alreadyPipelinedRequests.clear(); - close(); QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); } @@ -758,6 +758,7 @@ void QHttpNetworkConnectionChannel::_q_disconnected() state = QHttpNetworkConnectionChannel::IdleState; requeueCurrentlyPipelinedRequests(); + close(); } diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index c953ebf..e990704 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -198,6 +198,7 @@ QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl) majorVersion(0), minorVersion(0), bodyLength(0), contentRead(0), totalProgress(0), chunkedTransferEncoding(false), connectionCloseEnabled(true), + forceConnectionCloseEnabled(false), currentChunkSize(0), currentChunkRead(0), connection(0), initInflate(false), autoDecompress(false), responseData(), requestIsPrepared(false) ,pipeliningUsed(false) @@ -564,7 +565,7 @@ bool QHttpNetworkReplyPrivate::isChunked() bool QHttpNetworkReplyPrivate::isConnectionCloseEnabled() { - return connectionCloseEnabled; + return connectionCloseEnabled || forceConnectionCloseEnabled; } // note this function can only be used for non-chunked, non-compressed with diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index ded1d44..1073560 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -213,6 +213,7 @@ public: QByteArray fragment; // used for header, status, chunk header etc, not for reply data bool chunkedTransferEncoding; bool connectionCloseEnabled; + bool forceConnectionCloseEnabled; qint64 currentChunkSize; qint64 currentChunkRead; QPointer connection; -- cgit v0.12 From 154f2ba23c87a0d316e3a9c263efa7dd3bbef6ce Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Tue, 22 Sep 2009 13:15:56 +0200 Subject: QRingBuffer: Try to minimize memory consumption while it is empty Try not to hold an unused 4k QByteArray. This may introduce a performance regression e.g. for QNetworkReply in exchange for lower memory usage. We will see if this is really the case. Reviewed-by: Thiago --- src/corelib/tools/qringbuffer_p.h | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h index b2df054..c44346c 100644 --- a/src/corelib/tools/qringbuffer_p.h +++ b/src/corelib/tools/qringbuffer_p.h @@ -147,9 +147,20 @@ public: --tailBuffer; head = 0; } + + if (isEmpty()) + clear(); // try to minify/squeeze us } inline char *reserve(int bytes) { + // if this is a fresh empty QRingBuffer + if (bufferSize == 0) { + buffers[0].resize(qMax(basicBlockSize, bytes)); + bufferSize += bytes; + tail = bytes; + return buffers[tailBuffer].data(); + } + bufferSize += bytes; // if there is already enough space, simply return. @@ -208,6 +219,9 @@ public: --tailBuffer; tail = buffers.at(tailBuffer).size(); } + + if (isEmpty()) + clear(); // try to minify/squeeze us } inline bool isEmpty() const { @@ -244,11 +258,10 @@ public: } inline void clear() { - if(!buffers.isEmpty()) { - buffers.erase(buffers.begin() + 1, buffers.end()); - if (buffers.at(0).size() != basicBlockSize) - buffers[0].resize(basicBlockSize); - } + buffers.erase(buffers.begin() + 1, buffers.end()); + buffers[0].resize(0); + buffers[0].squeeze(); + head = tail = 0; tailBuffer = 0; bufferSize = 0; -- cgit v0.12 From e5ecc1970e6d83fa69461a2bff22f43e5116f5f5 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 23 Sep 2009 14:04:10 +0200 Subject: Fall back to pixmaps in xp style when toplevel is translucent The "fast path" will write bad premlutiplied pixels into the backbuffer so the blending will be broken, plus that the window does not get mouse events for alpha=0 pixels. Reviewed-by: Marius Storm-Olsen --- src/gui/styles/qwindowsxpstyle.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/gui/styles/qwindowsxpstyle.cpp b/src/gui/styles/qwindowsxpstyle.cpp index 0dc1832..9c374d8 100644 --- a/src/gui/styles/qwindowsxpstyle.cpp +++ b/src/gui/styles/qwindowsxpstyle.cpp @@ -621,12 +621,21 @@ void QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData) QMatrix m = painter->matrix(); bool complexXForm = m.m11() != 1.0 || m.m22() != 1.0 || m.m12() != 0.0 || m.m21() != 0.0; + bool translucentToplevel = false; + QPaintDevice *pdev = painter->device(); + if (pdev->devType() == QInternal::Widget) { + QWidget *win = ((QWidget *) pdev)->window(); + translucentToplevel = win->testAttribute(Qt::WA_TranslucentBackground); + } + bool useFallback = painter->paintEngine()->getDC() == 0 || painter->opacity() != 1.0 || themeData.rotate || complexXForm || themeData.mirrorVertically - || (themeData.mirrorHorizontally && pDrawThemeBackgroundEx == 0); + || (themeData.mirrorHorizontally && pDrawThemeBackgroundEx == 0) + || translucentToplevel; + if (!useFallback) drawBackgroundDirectly(themeData); else -- cgit v0.12 From bbcef4e4b596324aeda80e0aa7d313c586454740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Wed, 23 Sep 2009 14:39:22 +0200 Subject: Don't warn of an unused 'window' argument. --- src/testlib/qtestsystem.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/testlib/qtestsystem.h b/src/testlib/qtestsystem.h index 540b18d..a9a2193 100644 --- a/src/testlib/qtestsystem.h +++ b/src/testlib/qtestsystem.h @@ -76,8 +76,10 @@ namespace QTest #if defined(Q_WS_X11) qt_x11_wait_for_window_manager(window); #elif defined(Q_WS_QWS) + Q_UNUSED(window); qWait(100); #else + Q_UNUSED(window); qWait(50); #endif return true; -- cgit v0.12 From 0cb5038a3e5d3a6b0c33d081b89c6fe47cfc0b1b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 23 Sep 2009 14:35:06 +0200 Subject: Try to support Qt 4.4-style Phonon includes in Qt. This introduces an undocumented "phonon_compat" subdir and also adds it to the INCLUDEPATH when QT += phonon is specified. With this, these styles of #includes should be supported: #include #include #include #include #include #include Still need to check if the headers get installed during "make install". I couldn't find where in our code that is done. BT: yes Reviewed-By: Trust Me --- bin/syncqt | 10 ++++++++-- mkspecs/features/qt.prf | 8 ++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/bin/syncqt b/bin/syncqt index 01c519e..5cb5d86 100755 --- a/bin/syncqt +++ b/bin/syncqt @@ -843,9 +843,15 @@ foreach (@modules_to_sync) { $master_contents .= "#endif\n"; unless($showonly) { - unless ($lib eq "phonon") { + my @master_includes; + if ($lib eq "phonon") { + push @master_includes, "$out_basedir/include/phonon_compat/phonon/phonon"; + push @master_includes, "$out_basedir/include/phonon/Phonon/Phonon"; + } else { + push @master_includes, "$out_basedir/include/$lib/$lib"; + } + foreach my $master_include (@master_includes) { #generate the "master" include file - my $master_include = "$out_basedir/include/$lib/$lib"; $pri_install_files .= fixPaths($master_include, "$modules{$lib}") . " "; #get the master file installed too if($master_include && -e "$master_include") { open MASTERINCLUDE, "<$master_include"; diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index b3d6a5f..2b2a42c 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -158,8 +158,12 @@ for(QTLIB, $$list($$lower($$unique(QT)))) { else:isEqual(QTLIB, scripttools):qlib = QtScriptTools else:isEqual(QTLIB, testlib):qlib = QtTest else:isEqual(QTLIB, dbus):qlib = QtDBus - else:isEqual(QTLIB, phonon):qlib = phonon - else:isEqual(QTLIB, webkit):qlib = QtWebKit + else:isEqual(QTLIB, phonon) { + qlib = phonon + INCLUDEPATH += $$QMAKE_INCDIR_QT/phonon_compat/phonon + INCLUDEPATH += $$QMAKE_INCDIR_QT/phonon_compat + INCLUDEPATH += $$QMAKE_INCDIR_QT/phonon/Phonon + } else:isEqual(QTLIB, webkit):qlib = QtWebKit else:isEqual(QTLIB, multimedia):qlib = QtMultimedia else:message("Unknown QT: $$QTLIB"):qlib = !isEmpty(qlib) { -- cgit v0.12 From a33c1ca39ef8cb2485dbde3c0454873f58c0b733 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 23 Sep 2009 15:01:44 +0200 Subject: Try to stabilize this test --- tests/auto/qcopchannel/tst_qcopchannel.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/auto/qcopchannel/tst_qcopchannel.cpp b/tests/auto/qcopchannel/tst_qcopchannel.cpp index 93d037e..9a3be6c 100644 --- a/tests/auto/qcopchannel/tst_qcopchannel.cpp +++ b/tests/auto/qcopchannel/tst_qcopchannel.cpp @@ -49,6 +49,7 @@ #include #include +#include "../../shared/util.h" class tst_QCopChannel : public QObject { @@ -110,7 +111,7 @@ void tst_QCopChannel::sendreceivemp() testSend(channelName, "msg", "data"); QApplication::processEvents(); - QCOMPARE(spy.count(), 1); + QTRY_COMPARE(spy.count(), 1); QList args = spy.takeFirst(); QCOMPARE(args.at(0).toString(), QString("msg")); @@ -134,7 +135,7 @@ void tst_QCopChannel::sendreceivesp() QCOMPARE(spy.count(), 0); QCopChannel::send(channelName, "msg", "data"); QApplication::processEvents(); - QCOMPARE(spy.count(), 1); + QTRY_COMPARE(spy.count(), 1); QList args = spy.takeFirst(); QCOMPARE(args.at(0).toString(), QString("msg")); -- cgit v0.12 From 7dedc5699842d2651859e36b0ca843ec4d173056 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 23 Sep 2009 14:55:25 +0200 Subject: Fixed parsing of html header in the qtextcodec. The QTextCodec::codecForHtml used to expect http-equiv attribute before the charset attribute in the meta header, which is not always the case. Reviewed-by: Simon Hausmann --- src/corelib/codecs/qtextcodec.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index 3ef9f7e..4f0e13c 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -1536,12 +1536,14 @@ QTextCodec *QTextCodec::codecForHtml(const QByteArray &ba, QTextCodec *defaultCo if (!c) { QByteArray header = ba.left(512).toLower(); if ((pos = header.indexOf("http-equiv=")) != -1) { - pos = header.indexOf("charset=", pos) + int(strlen("charset=")); - if (pos != -1) { - int pos2 = header.indexOf('\"', pos+1); - QByteArray cs = header.mid(pos, pos2-pos); - // qDebug("found charset: %s", cs.data()); - c = QTextCodec::codecForName(cs); + if ((pos = header.lastIndexOf("meta ", pos)) != -1) { + pos = header.indexOf("charset=", pos) + int(strlen("charset=")); + if (pos != -1) { + int pos2 = header.indexOf('\"', pos+1); + QByteArray cs = header.mid(pos, pos2-pos); + // qDebug("found charset: %s", cs.data()); + c = QTextCodec::codecForName(cs); + } } } } -- cgit v0.12 From 2e27c5a11488d5b7aa6831ba30a8c11bf71fb07a Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Wed, 23 Sep 2009 09:11:56 +0200 Subject: Fix a warning about an unused variable. Reviewed-by: TrustMe --- src/corelib/kernel/qcoreapplication.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index c575509..9a93685 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -345,7 +345,7 @@ void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver) } #elif defined(Q_OS_SYMBIAN) && defined (QT_NO_DEBUG) // no implementation in release builds, but keep the symbol present -void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver) +void QCoreApplicationPrivate::checkReceiverThread(QObject * /* receiver */) { } #endif -- cgit v0.12 From 5e11ae8dc8594f648105f8a62baf1b82c909fd2a Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Tue, 11 Aug 2009 08:39:12 +0200 Subject: Implement Qt::WA_AcceptTouchEvents on S60 Turning this attribute ends up calling RWindow::EnabledAdvancedPointers(), which tells Symbian to send us multiple pointer events with extended info. Reviewed-by: Jason Barron --- src/gui/kernel/qwidget.cpp | 2 +- src/gui/kernel/qwidget_p.h | 1 + src/gui/kernel/qwidget_s60.cpp | 12 ++++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 6f5781c..53ef682 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -10397,7 +10397,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) break; case Qt::WA_AcceptTouchEvents: -#if defined(Q_WS_WIN) || defined(Q_WS_MAC) +#if defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_WS_S60) if (on) d->registerTouchWindow(); #endif diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 5a9c48c..296c5b1 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -693,6 +693,7 @@ public: static QWidget *keyboardGrabber; void s60UpdateIsOpaque(); void reparentChildren(); + void registerTouchWindow(); #endif }; diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 4fef020..2e6139b 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -299,6 +299,9 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de destroyw->ControlEnv()->AppUi()->RemoveFromStack(destroyw); CBase::Delete(destroyw); } + + if (q->testAttribute(Qt::WA_AcceptTouchEvents)) + registerTouchWindow(); } @@ -800,6 +803,15 @@ void QWidgetPrivate::setMask_sys(const QRegion& /* region */) } +void QWidgetPrivate::registerTouchWindow() +{ + Q_Q(QWidget); + if (q->testAttribute(Qt::WA_WState_Created) && q->windowType() != Qt::Desktop) { + RWindow *rwindow = static_cast(q->effectiveWinId()->DrawableWindow()); + rwindow->EnableAdvancedPointers(); + } +} + int QWidget::metric(PaintDeviceMetric m) const { Q_D(const QWidget); -- cgit v0.12 From 48d0f84958fdc2dcffab75f33842a9dbc3d4d7b1 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Tue, 11 Aug 2009 09:39:26 +0200 Subject: Implement advanced pointer handling on S60 Since we only get one pointer event at a time, we need to keep a list of all known touch points in QApplicationPrivate (otherwise the QTouchEvent won't contain enough points). The QApplication machinery can handle having inactive touch-points in the list, so at the moment we don't clear the list. We treat PointerNumber zero as the primary touch point, and only send regular mouse events for that pointer, never for the others. Reviewed-by: Jason Barron --- src/gui/kernel/qapplication_p.h | 5 +++ src/gui/kernel/qapplication_s60.cpp | 76 ++++++++++++++++++++++++++++++++++++- src/gui/kernel/qt_s60_p.h | 1 + 3 files changed, 80 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 707caaa..aec21fd 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -576,6 +576,11 @@ public: void _q_readRX71MultiTouchEvents(); #endif +#if defined(Q_WS_S60) + int maxTouchPressure; + QList appAllTouchPoints; +#endif + private: #ifdef Q_WS_QWS QMap maxWindowRects; diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index a5d07fd..58aca83 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -368,8 +368,77 @@ void QSymbianControl::HandleLongTapEventL( const TPoint& aPenEventLocation, cons m_previousEventLongTap = true; } +void QSymbianControl::translateAdvancedPointerEvent(const TAdvancedPointerEvent *event) +{ + QApplicationPrivate *d = QApplicationPrivate::instance(); + + QRect screenGeometry = qApp->desktop()->screenGeometry(qwidget); + + while (d->appAllTouchPoints.count() <= event->PointerNumber()) + d->appAllTouchPoints.append(QTouchEvent::TouchPoint(d->appAllTouchPoints.count())); + + Qt::TouchPointStates allStates = 0; + for (int i = 0; i < d->appAllTouchPoints.count(); ++i) { + QTouchEvent::TouchPoint &touchPoint = d->appAllTouchPoints[i]; + + if (touchPoint.id() == event->PointerNumber()) { + Qt::TouchPointStates state; + switch (event->iType) { + case TPointerEvent::EButton1Down: + case TPointerEvent::EEnterHighPressure: + state = Qt::TouchPointPressed; + break; + case TPointerEvent::EButton1Up: + case TPointerEvent::EExitCloseProximity: + state = Qt::TouchPointReleased; + break; + case TPointerEvent::EDrag: + state = Qt::TouchPointMoved; + break; + default: + // how likely is this to happen? + state = Qt::TouchPointStationary; + break; + } + if (event->PointerNumber() == 0) + state |= Qt::TouchPointPrimary; + touchPoint.setState(state); + + QPointF screenPos = QPointF(event->iPosition.iX, event->iPosition.iY); + touchPoint.setScreenPos(screenPos); + touchPoint.setNormalizedPos(QPointF(screenPos.x() / screenGeometry.width(), + screenPos.y() / screenGeometry.height())); + + touchPoint.setPressure(event->Pressure() / qreal(d->maxTouchPressure)); + } else if (touchPoint.state() != Qt::TouchPointReleased) { + // all other active touch points should be marked as stationary + touchPoint.setState(Qt::TouchPointStationary); + } + + allStates |= touchPoint.state(); + } + + if ((allStates & Qt::TouchPointStateMask) == Qt::TouchPointReleased) { + // all touch points released + d->appAllTouchPoints.clear(); + } + + QApplicationPrivate::translateRawTouchEvent(qwidget, + QTouchEvent::TouchScreen, + d->appAllTouchPoints); +} + void QSymbianControl::HandlePointerEventL(const TPointerEvent& pEvent) { + if (pEvent.IsAdvancedPointerEvent()) { + const TAdvancedPointerEvent *advancedPointerEvent = pEvent.AdvancedPointerEvent(); + translateAdvancedPointerEvent(advancedPointerEvent); + if (advancedPointerEvent->PointerNumber() != 0) { + // only send mouse events for the first touch point + return; + } + } + m_longTapDetector->PointerEventL(pEvent); QT_TRYCATCH_LEAVING(HandlePointerEvent(pEvent)); } @@ -1441,9 +1510,12 @@ TUint QApplicationPrivate::resolveS60ScanCode(TInt scanCode, TUint keysym) } } - void QApplicationPrivate::initializeMultitouch_sys() -{ } +{ + if (HAL::Get(HALData::EPointer3DMaxPressure, maxTouchPressure) != KErrNone) + maxTouchPressure = KMaxTInt; +} + void QApplicationPrivate::cleanupMultitouch_sys() { } diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index aa39f9d..9939f2c 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -167,6 +167,7 @@ private: TKeyResponse sendKeyEvent(QWidget *widget, QKeyEvent *keyEvent); bool sendMouseEvent(QWidget *widget, QMouseEvent *mEvent); void HandleLongTapEventL( const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation ); + void translateAdvancedPointerEvent(const TAdvancedPointerEvent *event); private: QWidget *qwidget; -- cgit v0.12 From 7dcf984f85a3a75ce4c078cc931bd9d2304bc235 Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Wed, 23 Sep 2009 08:31:23 +0200 Subject: Modify functions for native pixmap data conversion on Symbian. We need a way to support converion to and from multiple native pixmap types from multiple pixmap backends. Instead of adding more virtual functions to QPixmapData, make the existing one more generic but pass an opaque pointer and a type and do some internal casting. Currently this function is Symbian only, but could easily be extended to work on other platforms. Reviewed-by: Aleksandar Babic Reviewed-by: Jani Hautakangas --- src/gui/image/qpixmap.h | 6 +- src/gui/image/qpixmap_s60.cpp | 410 +++++++++++++++++++++--------------------- src/gui/image/qpixmap_s60_p.h | 21 ++- src/gui/image/qpixmapdata.cpp | 5 +- src/gui/image/qpixmapdata_p.h | 15 +- src/openvg/qpixmapdata_vg.cpp | 266 ++++++++++++++------------- src/openvg/qpixmapdata_vg_p.h | 4 +- 7 files changed, 376 insertions(+), 351 deletions(-) diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h index 2ed65ea..a891637 100644 --- a/src/gui/image/qpixmap.h +++ b/src/gui/image/qpixmap.h @@ -161,10 +161,8 @@ public: #endif #if defined(Q_OS_SYMBIAN) - enum ConversionMode { CopyData, DuplicateHandle }; - - CFbsBitmap *toSymbianCFbsBitmap(ConversionMode mode = DuplicateHandle) const; - static QPixmap fromSymbianCFbsBitmap(CFbsBitmap *bitmap, ConversionMode mode = DuplicateHandle); + CFbsBitmap *toSymbianCFbsBitmap() const; + static QPixmap fromSymbianCFbsBitmap(CFbsBitmap *bitmap); RSgImage* toSymbianRSgImage() const; static QPixmap fromSymbianRSgImage(RSgImage *sgImage); #endif diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp index 303e923..cab6116 100644 --- a/src/gui/image/qpixmap_s60.cpp +++ b/src/gui/image/qpixmap_s60.cpp @@ -297,231 +297,55 @@ QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h) } /*! - \enum QPixmap::ConversionMode - - \bold{Symbian only:} This enum defines how the conversion between \c - CFbsBitmap and QPixmap is performed. - - \warning This enum is only available on Symbian. - - \value CopyData Copied CFbsBitmap data. - - \value DuplicateHandle Duplicates CFbsBitmap handle. This also means - that pixmap data will be explicitly shared. - - \sa fromSymbianCFbsBitmap(), toSymbianCFbsBitmap() -*/ - - -/*! - \fn CFbsBitmap *QPixmap::toSymbianCFbsBitmap(ConversionMode mode) + \fn CFbsBitmap *QPixmap::toSymbianCFbsBitmap() \since 4.6 - Creates \c CFbsBitmap that is equivalent to the QPixmap, based on - the given \a mode. If the creation then this function returns 0. + Creates a \c CFbsBitmap that is equivalent to the QPixmap. Internally this + function will try to duplicate the handle instead of copying the data, + however in scenarios where this is not possible the data will be copied. + If the creation fails or the pixmap is null, then this function returns 0. It is the caller's responsibility to release the \c CFbsBitmap data after use either by deleting the bitmap or calling \c Reset(). - \warning On S60 3.1 and S60 3.2 conversion mode will always be CopyData - if QPixmap pixels have alpha values. + \warning On S60 3.1 and S60 3.2, semi-transparent pixmaps are always copied + and not duplicated. \warning This function is only available on Symbian OS. \sa fromSymbianCFbsBitmap() */ -CFbsBitmap *QPixmap::toSymbianCFbsBitmap(ConversionMode mode) const +CFbsBitmap *QPixmap::toSymbianCFbsBitmap() const { - QS60PixmapData *s60data = static_cast(data.data()); - - if (isNull() || !s60data->cfbsBitmap) + QPixmapData *data = pixmapData(); + if (data->isNull()) return 0; - bool convertToArgb32 = false; - - QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion(); - if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3) { - // Convert argb32_premultiplied to argb32 since Symbian 9.2 and Symbian 9.3 do - // not support premultipied format. - - if (s60data->image.format() == QImage::Format_ARGB32_Premultiplied) { - mode = CopyData; - convertToArgb32 = true; - } - } - - CFbsBitmap *bitmap = 0; - - TDisplayMode displayMode = s60data->cfbsBitmap->DisplayMode(); - - if(displayMode == EGray2) { - //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid - //So invert mono bitmaps so that masks work correctly. - s60data->image.invertPixels(); - mode = CopyData; - } - - if (mode == CopyData) { - QImage source; - - if (convertToArgb32) { - source = s60data->image.convertToFormat(QImage::Format_ARGB32); - displayMode = EColor16MA; - } else { - source = s60data->image; - } - - CFbsBitmap *newBitmap = createSymbianCFbsBitmap(TSize(source.width(), source.height()), displayMode); - const uchar *sptr = source.bits(); - s60data->symbianBitmapDataAccess->beginDataAccess(newBitmap); - - uchar *dptr = (uchar*)newBitmap->DataAddress(); - Mem::Copy(dptr, sptr, source.numBytes()); - - s60data->symbianBitmapDataAccess->endDataAccess(newBitmap); - - bitmap = newBitmap; - } else { - - QT_TRAP_THROWING(bitmap = new (ELeave) CFbsBitmap); - - TInt err = bitmap->Duplicate(s60data->cfbsBitmap->Handle()); - if (err != KErrNone) { - qWarning("Could not duplicate CFbsBitmap"); - delete bitmap; - bitmap = 0; - } - } - - if(displayMode == EGray2) { - // restore pixels - s60data->image.invertPixels(); - } - - return bitmap; + return reinterpret_cast(data->toNativeType(QPixmapData::FbsBitmap)); } /*! - \fn QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap, ConversionMode mode) + \fn QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap) \since 4.6 - Creates a QPixmap from native \c CFbsBitmap \a bitmap. The conversion - is based on the specified \a mode. Conversion mode is always QPixmap::CopyData - if given \a bitmap does not have display mode of TDisplayMode::EGray2, - \c TDisplayMode::EColor16MU or \c TDisplayMode::EColor16MAP. - + Creates a QPixmap from a \c CFbsBitmap \a bitmap. Internally this function + will try to duplicate the bitmap handle instead of copying the data, however + in scenarios where this is not possible the data will be copied. + To be sure that QPixmap does not modify your original instance, you should + make a copy of your \c CFbsBitmap before calling this function. If the CFbsBitmap is not valid this function will return a null QPixmap. \warning This function is only available on Symbian OS. \sa toSymbianCFbsBitmap(), {QPixmap#Pixmap Conversion}{Pixmap Conversion} */ -QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap, ConversionMode mode) +QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap) { - if (bitmap) { - - bool deleteSourceBitmap = false; - -#ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE - - // Rasterize extended bitmaps - - TUid extendedBitmapType = bitmap->ExtendedBitmapType(); - if (extendedBitmapType != KNullUid) { - CFbsBitmap *rasterBitmap = createSymbianCFbsBitmap(bitmap->SizeInPixels(), EColor16MA); - - CFbsBitmapDevice *rasterBitmapDev = 0; - QT_TRAP_THROWING(rasterBitmapDev = CFbsBitmapDevice::NewL(rasterBitmap)); - - CFbsBitGc *rasterBitmapGc = 0; - TInt err = rasterBitmapDev->CreateContext(rasterBitmapGc); - if (err != KErrNone) { - delete rasterBitmap; - delete rasterBitmapDev; - rasterBitmapDev = 0; - return QPixmap(); - } - - rasterBitmapGc->BitBlt(TPoint( 0, 0), bitmap); - - bitmap = rasterBitmap; - - delete rasterBitmapDev; - delete rasterBitmapGc; - - rasterBitmapDev = 0; - rasterBitmapGc = 0; - - deleteSourceBitmap = true; - } -#endif - - - deleteSourceBitmap = bitmap->IsCompressedInRAM(); - CFbsBitmap *sourceBitmap = uncompress(bitmap); - - TDisplayMode displayMode = sourceBitmap->DisplayMode(); - QImage::Format format = qt_TDisplayMode2Format(displayMode); - - QImage::Format opaqueFormat = QNativeImage::systemFormat(); - QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied; - - if (format != opaqueFormat && format != alphaFormat && format != QImage::Format_MonoLSB) - mode = CopyData; - - - QPixmapData::PixelType type = (format!=QImage::Format_MonoLSB) - ? QPixmapData::PixmapType - : QPixmapData::BitmapType; - - QS60PixmapData *pixmapData = 0; - - if (mode == CopyData) { - - TSize size = sourceBitmap->SizeInPixels(); - - QSymbianBitmapDataAccess da; - da.beginDataAccess(sourceBitmap); - uchar *bytes = (uchar*)sourceBitmap->DataAddress(); - QImage img = QImage(bytes, size.iWidth, size.iHeight, format); - da.endDataAccess(sourceBitmap); - - pixmapData = new QS60PixmapData(type); - pixmapData->fromImage(img, Qt::AutoColor); - - if(deleteSourceBitmap) - delete sourceBitmap; - - if(displayMode == EGray2) { - //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid - //So invert mono bitmaps so that masks work correctly. - pixmapData->image.invertPixels(); - } - } else { - CFbsBitmap* duplicate = 0; - QT_TRAP_THROWING(duplicate = new (ELeave) CFbsBitmap); - - TInt err = duplicate->Duplicate(sourceBitmap->Handle()); - if (err != KErrNone) { - qWarning("Could not duplicate CFbsBitmap"); - - if(deleteSourceBitmap) - delete sourceBitmap; - - delete duplicate; - return QPixmap(); - } - - pixmapData = new QS60PixmapData(type); - pixmapData->fromSymbianBitmap(duplicate); - - if(deleteSourceBitmap) - delete sourceBitmap; - } - - return QPixmap(pixmapData); - } + if (!bitmap) + return QPixmap(); - return QPixmap(); + QPixmap pixmap; + pixmap.pixmapData()->fromNativeType(reinterpret_cast(bitmap), QPixmapData::FbsBitmap); + return pixmap; } QS60PixmapData::QS60PixmapData(PixelType type) : QRasterPixmapData(type), @@ -921,7 +745,7 @@ QPixmap QPixmap::fromSymbianRSgImage(RSgImage *sgImage) return QPixmap(); QPixmap pixmap; - pixmap.pixmapData()->fromRSgImage(sgImage); + pixmap.pixmapData()->fromNativeType(reinterpret_cast(sgImage), QPixmapData::SgImage); return pixmap; } @@ -949,9 +773,193 @@ RSgImage *QPixmap::toSymbianRSgImage() const if (isNull()) return 0; - RSgImage *sgImage = pixmapData()->toRSgImage(); + RSgImage *sgImage = reinterpret_cast(pixmapData()->toNativeType(QPixmapData::SgImage)); return sgImage; } +void* QS60PixmapData::toNativeType(NativeType type) +{ + if (type == QPixmapData::SgImage) { + return 0; + } else if (type == QPixmapData::FbsBitmap) { + + if (isNull() || !cfbsBitmap) + return 0; + + bool convertToArgb32 = false; + bool needsCopy = false; + + QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion(); + if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3) { + // Convert argb32_premultiplied to argb32 since Symbian 9.2 and Symbian 9.3 do + // not support premultipied format. + + if (image.format() == QImage::Format_ARGB32_Premultiplied) { + needsCopy = true; + convertToArgb32 = true; + } + } + + CFbsBitmap *bitmap = 0; + + TDisplayMode displayMode = cfbsBitmap->DisplayMode(); + + if(displayMode == EGray2) { + //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid + //So invert mono bitmaps so that masks work correctly. + image.invertPixels(); + needsCopy = true; + } + + if (needsCopy) { + QImage source; + + if (convertToArgb32) { + source = image.convertToFormat(QImage::Format_ARGB32); + displayMode = EColor16MA; + } else { + source = image; + } + + CFbsBitmap *newBitmap = createSymbianCFbsBitmap(TSize(source.width(), source.height()), displayMode); + const uchar *sptr = source.bits(); + symbianBitmapDataAccess->beginDataAccess(newBitmap); + + uchar *dptr = (uchar*)newBitmap->DataAddress(); + Mem::Copy(dptr, sptr, source.numBytes()); + + symbianBitmapDataAccess->endDataAccess(newBitmap); + + bitmap = newBitmap; + } else { + + QT_TRAP_THROWING(bitmap = new (ELeave) CFbsBitmap); + + TInt err = bitmap->Duplicate(cfbsBitmap->Handle()); + if (err != KErrNone) { + qWarning("Could not duplicate CFbsBitmap"); + delete bitmap; + bitmap = 0; + } + } + + if(displayMode == EGray2) { + // restore pixels + image.invertPixels(); + } + + return reinterpret_cast(bitmap); + + } + + return 0; +} + +void QS60PixmapData::fromNativeType(void* pixmap, NativeType nativeType) +{ + if (nativeType == QPixmapData::SgImage) { + return; + } else if (nativeType == QPixmapData::FbsBitmap && pixmap) { + + CFbsBitmap *bitmap = reinterpret_cast(pixmap); + + bool deleteSourceBitmap = false; + bool needsCopy = false; + +#ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE + + // Rasterize extended bitmaps + + TUid extendedBitmapType = bitmap->ExtendedBitmapType(); + if (extendedBitmapType != KNullUid) { + CFbsBitmap *rasterBitmap = createSymbianCFbsBitmap(bitmap->SizeInPixels(), EColor16MA); + + CFbsBitmapDevice *rasterBitmapDev = 0; + QT_TRAP_THROWING(rasterBitmapDev = CFbsBitmapDevice::NewL(rasterBitmap)); + + CFbsBitGc *rasterBitmapGc = 0; + TInt err = rasterBitmapDev->CreateContext(rasterBitmapGc); + if (err != KErrNone) { + delete rasterBitmap; + delete rasterBitmapDev; + rasterBitmapDev = 0; + return; + } + + rasterBitmapGc->BitBlt(TPoint( 0, 0), bitmap); + + bitmap = rasterBitmap; + + delete rasterBitmapDev; + delete rasterBitmapGc; + + rasterBitmapDev = 0; + rasterBitmapGc = 0; + + deleteSourceBitmap = true; + } +#endif + + + deleteSourceBitmap = bitmap->IsCompressedInRAM(); + CFbsBitmap *sourceBitmap = uncompress(bitmap); + + TDisplayMode displayMode = sourceBitmap->DisplayMode(); + QImage::Format format = qt_TDisplayMode2Format(displayMode); + + QImage::Format opaqueFormat = QNativeImage::systemFormat(); + QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied; + + if (format != opaqueFormat && format != alphaFormat && format != QImage::Format_MonoLSB) + needsCopy = true; + + + type = (format != QImage::Format_MonoLSB) + ? QPixmapData::PixmapType + : QPixmapData::BitmapType; + + if (needsCopy) { + + TSize size = sourceBitmap->SizeInPixels(); + + QSymbianBitmapDataAccess da; + da.beginDataAccess(sourceBitmap); + uchar *bytes = (uchar*)sourceBitmap->DataAddress(); + QImage img = QImage(bytes, size.iWidth, size.iHeight, format); + da.endDataAccess(sourceBitmap); + + fromImage(img, Qt::AutoColor); + + if(deleteSourceBitmap) + delete sourceBitmap; + + if(displayMode == EGray2) { + //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid + //So invert mono bitmaps so that masks work correctly. + image.invertPixels(); + } + } else { + CFbsBitmap* duplicate = 0; + QT_TRAP_THROWING(duplicate = new (ELeave) CFbsBitmap); + + TInt err = duplicate->Duplicate(sourceBitmap->Handle()); + if (err != KErrNone) { + qWarning("Could not duplicate CFbsBitmap"); + + if(deleteSourceBitmap) + delete sourceBitmap; + + delete duplicate; + return; + } + + fromSymbianBitmap(duplicate); + + if(deleteSourceBitmap) + delete sourceBitmap; + } + } +} + QT_END_NAMESPACE diff --git a/src/gui/image/qpixmap_s60_p.h b/src/gui/image/qpixmap_s60_p.h index 21f1bb3..4498c05 100644 --- a/src/gui/image/qpixmap_s60_p.h +++ b/src/gui/image/qpixmap_s60_p.h @@ -66,17 +66,17 @@ class QSymbianBitmapDataAccess; class QSymbianFbsHeapLock { public: - + enum LockAction { Unlock }; - + explicit QSymbianFbsHeapLock(LockAction a); ~QSymbianFbsHeapLock(); - void relock(); - + void relock(); + private: - + LockAction action; bool wasLocked; }; @@ -102,13 +102,16 @@ public: void beginDataAccess(); void endDataAccess(bool readOnly=false) const; + void* toNativeType(NativeType type); + void fromNativeType(void* pixmap, NativeType type); + private: - void release(); - void fromSymbianBitmap(CFbsBitmap* bitmap); - bool initSymbianBitmapContext(); + void release(); + void fromSymbianBitmap(CFbsBitmap* bitmap); + bool initSymbianBitmapContext(); QSymbianBitmapDataAccess *symbianBitmapDataAccess; - + CFbsBitmap *cfbsBitmap; CFbsBitmapDevice *bitmapDevice; CBitmapContext *bitmapContext; diff --git a/src/gui/image/qpixmapdata.cpp b/src/gui/image/qpixmapdata.cpp index 65899a4..93fc2eb 100644 --- a/src/gui/image/qpixmapdata.cpp +++ b/src/gui/image/qpixmapdata.cpp @@ -224,14 +224,15 @@ QImage* QPixmapData::buffer() } #if defined(Q_OS_SYMBIAN) -RSgImage* QPixmapData::toRSgImage() +void* QPixmapData::toNativeType(NativeType /* type */) { return 0; } -void QPixmapData::fromRSgImage(RSgImage* rsgImage) +void QPixmapData::fromNativeType(void* /* pixmap */, NativeType /* typre */) { return; } #endif + QT_END_NAMESPACE diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h index 5920a06..3e85236 100644 --- a/src/gui/image/qpixmapdata_p.h +++ b/src/gui/image/qpixmapdata_p.h @@ -56,10 +56,6 @@ #include #include -#if defined(Q_OS_SYMBIAN) -class RSgImage; -#endif - QT_BEGIN_NAMESPACE class Q_GUI_EXPORT QPixmapData @@ -70,6 +66,12 @@ public: // Must match QPixmap::Type PixmapType, BitmapType }; +#if defined(Q_OS_SYMBIAN) + enum NativeType { + FbsBitmap, + SgImage + }; +#endif enum ClassId { RasterClass, X11Class, MacClass, DirectFBClass, OpenGLClass, OpenVGClass, CustomClass = 1024 }; @@ -114,8 +116,8 @@ public: inline bool isNull() const { return is_null; } #if defined(Q_OS_SYMBIAN) - virtual RSgImage* toRSgImage(); - virtual void fromRSgImage(RSgImage* rsgImage); + virtual void* toNativeType(NativeType type); + virtual void fromNativeType(void* pixmap, NativeType type); #endif protected: @@ -129,6 +131,7 @@ private: friend class QPixmap; friend class QGLContextPrivate; friend class QX11PixmapData; + friend class QS60PixmapData; friend class QGLTextureCache; //Needs to check the reference count friend class QExplicitlySharedDataPointer; diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index 53975d7..38a89e6 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -381,167 +381,179 @@ void QVGPixmapData::cleanup() source = QImage(); } -void QVGPixmapData::fromRSgImage(RSgImage* sgImage) +void QVGPixmapData::fromNativeType(void* pixmap, NativeType type) { - Q_UNUSED(sgImage); #if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL) - // when "0" used as argument then - // default display, context are used - if (!context) - context = qt_vg_create_context(0); + if (type == QPixmapData::SgImage && pixmap) { + RSgImage *sgImage = reinterpret_cast(pixmap); + // when "0" used as argument then + // default display, context are used + if (!context) + context = qt_vg_create_context(0); - if (vgImage != VG_INVALID_HANDLE) { - vgDestroyImage(vgImage); - vgImage = VG_INVALID_HANDLE; - } - if (vgImageOpacity != VG_INVALID_HANDLE) { - vgDestroyImage(vgImageOpacity); - vgImageOpacity = VG_INVALID_HANDLE; - } + if (vgImage != VG_INVALID_HANDLE) { + vgDestroyImage(vgImage); + vgImage = VG_INVALID_HANDLE; + } + if (vgImageOpacity != VG_INVALID_HANDLE) { + vgDestroyImage(vgImageOpacity); + vgImageOpacity = VG_INVALID_HANDLE; + } - TInt err = 0; + TInt err = 0; - err = SgDriver::Open(); - if(err != KErrNone) { - cleanup(); - return; - } + err = SgDriver::Open(); + if(err != KErrNone) { + cleanup(); + return; + } - if(sgImage->IsNull()) { - cleanup(); - SgDriver::Close(); - return; - } + if(sgImage->IsNull()) { + cleanup(); + SgDriver::Close(); + return; + } - TSgImageInfo sgImageInfo; - err = sgImage->GetInfo(sgImageInfo); - if(err != KErrNone) { - cleanup(); - SgDriver::Close(); - return; - } + TSgImageInfo sgImageInfo; + err = sgImage->GetInfo(sgImageInfo); + if(err != KErrNone) { + cleanup(); + SgDriver::Close(); + return; + } - pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR"); - pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR"); - pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); + pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR"); + pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR"); + pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); - if(eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) { - cleanup(); - SgDriver::Close(); - return; - } + if(eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) { + cleanup(); + SgDriver::Close(); + return; + } - const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE}; - EGLImageKHR eglImage = eglCreateImageKHR(context->display(), - EGL_NO_CONTEXT, - EGL_NATIVE_PIXMAP_KHR, - (EGLClientBuffer)sgImage, - (EGLint*)KEglImageAttribs); + const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE}; + EGLImageKHR eglImage = eglCreateImageKHR(context->display(), + EGL_NO_CONTEXT, + EGL_NATIVE_PIXMAP_KHR, + (EGLClientBuffer)sgImage, + (EGLint*)KEglImageAttribs); + + if(eglGetError() != EGL_SUCCESS) { + cleanup(); + SgDriver::Close(); + return; + } - if(eglGetError() != EGL_SUCCESS) { - cleanup(); - SgDriver::Close(); - return; - } + vgImage = vgCreateEGLImageTargetKHR(eglImage); + if(vgGetError() != VG_NO_ERROR) { + cleanup(); + eglDestroyImageKHR(context->display(), eglImage); + SgDriver::Close(); + return; + } - vgImage = vgCreateEGLImageTargetKHR(eglImage); - if(vgGetError() != VG_NO_ERROR) { - cleanup(); + w = sgImageInfo.iSizeInPixels.iWidth; + h = sgImageInfo.iSizeInPixels.iHeight; + d = 32; // We always use ARGB_Premultiplied for VG pixmaps. + is_null = (w <= 0 || h <= 0); + source = QImage(); + recreate = false; + setSerialNumber(++qt_vg_pixmap_serial); + // release stuff eglDestroyImageKHR(context->display(), eglImage); SgDriver::Close(); - return; - } + } else if (type == QPixmapData::FbsBitmap) { - w = sgImageInfo.iSizeInPixels.iWidth; - h = sgImageInfo.iSizeInPixels.iHeight; - d = 32; // We always use ARGB_Premultiplied for VG pixmaps. - is_null = (w <= 0 || h <= 0); - source = QImage(); - recreate = false; - setSerialNumber(++qt_vg_pixmap_serial); - // release stuff - eglDestroyImageKHR(context->display(), eglImage); - SgDriver::Close(); + } #else + Q_UNUSED(pixmap); + Q_UNUSED(type); #endif } -RSgImage* QVGPixmapData::toRSgImage() +void* QVGPixmapData::toNativeType(NativeType type) { #if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL) - toVGImage(); - - if(!isValid() || vgImage == VG_INVALID_HANDLE) - return 0; - - TInt err = 0; + if (type == QPixmapData::SgImage) { + toVGImage(); + + if(!isValid() || vgImage == VG_INVALID_HANDLE) + return 0; + + TInt err = 0; + + err = SgDriver::Open(); + if(err != KErrNone) + return 0; + + TSgImageInfo sgInfo; + sgInfo.iPixelFormat = EUidPixelFormatARGB_8888_PRE; + sgInfo.iSizeInPixels.SetSize(w, h); + sgInfo.iUsage = ESgUsageOpenVgImage | ESgUsageOpenVgTarget; + sgInfo.iShareable = ETrue; + sgInfo.iCpuAccess = ESgCpuAccessNone; + sgInfo.iScreenId = KSgScreenIdMain; //KSgScreenIdAny; + sgInfo.iUserAttributes = NULL; + sgInfo.iUserAttributeCount = 0; + + RSgImage *sgImage = q_check_ptr(new RSgImage()); + err = sgImage->Create(sgInfo, NULL, NULL); + if(err != KErrNone) { + SgDriver::Close(); + return 0; + } - err = SgDriver::Open(); - if(err != KErrNone) - return 0; + pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR"); + pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR"); + pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); - TSgImageInfo sgInfo; - sgInfo.iPixelFormat = EUidPixelFormatARGB_8888_PRE; - sgInfo.iSizeInPixels.SetSize(w, h); - sgInfo.iUsage = ESgUsageOpenVgImage | ESgUsageOpenVgTarget; - sgInfo.iShareable = ETrue; - sgInfo.iCpuAccess = ESgCpuAccessNone; - sgInfo.iScreenId = KSgScreenIdMain; //KSgScreenIdAny; - sgInfo.iUserAttributes = NULL; - sgInfo.iUserAttributeCount = 0; - - RSgImage *sgImage = q_check_ptr(new RSgImage()); - err = sgImage->Create(sgInfo, NULL, NULL); - if(err != KErrNone) { - SgDriver::Close(); - return 0; - } + if(eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) { + SgDriver::Close(); + return 0; + } - pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR"); - pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR"); - pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); + const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE}; + EGLImageKHR eglImage = eglCreateImageKHR(context->display(), + EGL_NO_CONTEXT, + EGL_NATIVE_PIXMAP_KHR, + (EGLClientBuffer)sgImage, + (EGLint*)KEglImageAttribs); + if(eglGetError() != EGL_SUCCESS) { + sgImage->Close(); + SgDriver::Close(); + return 0; + } - if(eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) { - SgDriver::Close(); - return 0; - } + VGImage dstVgImage = vgCreateEGLImageTargetKHR(eglImage); + if(vgGetError() != VG_NO_ERROR) { + eglDestroyImageKHR(context->display(), eglImage); + sgImage->Close(); + SgDriver::Close(); + return 0; + } - const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE}; - EGLImageKHR eglImage = eglCreateImageKHR(context->display(), - EGL_NO_CONTEXT, - EGL_NATIVE_PIXMAP_KHR, - (EGLClientBuffer)sgImage, - (EGLint*)KEglImageAttribs); - if(eglGetError() != EGL_SUCCESS) { - sgImage->Close(); - SgDriver::Close(); - return 0; - } + vgCopyImage(dstVgImage, 0, 0, + vgImage, 0, 0, + w, h, VG_FALSE); - VGImage dstVgImage = vgCreateEGLImageTargetKHR(eglImage); - if(vgGetError() != VG_NO_ERROR) { + if(vgGetError() != VG_NO_ERROR) { + sgImage->Close(); + sgImage = 0; + } + // release stuff + vgDestroyImage(dstVgImage); eglDestroyImageKHR(context->display(), eglImage); - sgImage->Close(); SgDriver::Close(); + return reinterpret_cast(sgImage); + } else if (type == QPixmapData::FbsBitmap) { return 0; } - - vgCopyImage(dstVgImage, 0, 0, - vgImage, 0, 0, - w, h, VG_FALSE); - - if(vgGetError() != VG_NO_ERROR) { - sgImage->Close(); - sgImage = 0; - } - // release stuff - vgDestroyImage(dstVgImage); - eglDestroyImageKHR(context->display(), eglImage); - SgDriver::Close(); - return sgImage; #else + Q_UNUSED(type); return 0; #endif } #endif //Q_OS_SYMBIAN + QT_END_NAMESPACE diff --git a/src/openvg/qpixmapdata_vg_p.h b/src/openvg/qpixmapdata_vg_p.h index 122f596..99115df 100644 --- a/src/openvg/qpixmapdata_vg_p.h +++ b/src/openvg/qpixmapdata_vg_p.h @@ -95,8 +95,8 @@ public: QSize size() const { return QSize(w, h); } #if defined(Q_OS_SYMBIAN) - RSgImage* toRSgImage(); - void fromRSgImage(RSgImage* sgImage); + void* toNativeType(NativeType type); + void fromNativeType(void* pixmap, NativeType type); #endif protected: -- cgit v0.12 From 2966b2a95b0d7d161a6dc1a6edab3d6aa6edf004 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 22 Sep 2009 14:26:21 +0200 Subject: When using style sheets, the focus flag was not propagated to the children of complex widgets. Reviewed-by: Olivier --- src/gui/styles/qstylesheetstyle.cpp | 2 +- .../auto/qstylesheetstyle/tst_qstylesheetstyle.cpp | 55 ++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index e33b255..def82ae 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -1759,7 +1759,7 @@ QRenderRule QStyleSheetStyle::renderRule(const QWidget *w, const QStyleOption *o QStyle::SubControl subControl = knownPseudoElements[pseudoElement].subControl; if (!(complex->activeSubControls & subControl)) - state = QStyle::State(state & (QStyle::State_Enabled | QStyle::State_Horizontal)); + state &= (QStyle::State_Enabled | QStyle::State_Horizontal | QStyle::State_HasFocus); } switch (pseudoElement) { diff --git a/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp index e7d804a..e8fbd86 100644 --- a/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -95,6 +95,7 @@ private slots: void embeddedFonts(); void opaquePaintEvent_data(); void opaquePaintEvent(); + void complexWidgetFocus(); void task188195_baseBackground(); void task232085_spinBoxLineEditBg(); @@ -1447,6 +1448,60 @@ void tst_QStyleSheetStyle::opaquePaintEvent() QCOMPARE(cl.autoFillBackground(), !styled ); } +void tst_QStyleSheetStyle::complexWidgetFocus() +{ + // This test is a simplified version of the focusColors() test above. + + // Tests if colors can be changed by altering the focus of the widget. + // To avoid messy pixel-by-pixel comparison, we assume that the goal + // is reached if at least ten pixels of the right color can be found in + // the image. + // For this reason, we use unusual and extremely ugly colors! :-) + + QDialog frame; + // We only want to test the buttons colors. + frame.setStyleSheet("*:focus { background: black; color: black } " + "QSpinBox::up-button:focus, QSpinBox::down-button:focus { width: 15px; height: 15px; background: #e8ff66; color: #ff0084 } " + "QSpinBox::up-arrow:focus, QSpinBox::down-arrow:focus { width: 7px; height: 7px; background: #ff0084 } " + "QComboBox::drop-down:focus { background: #e8ff66; color: #ff0084 } " + "QComboBox::down-arrow:focus { width: 7px; height: 7px; background: #ff0084; color: #e8ff66 }"); + + QList widgets; + widgets << new QSpinBox; + widgets << new QComboBox; + + QLayout* layout = new QGridLayout; + layout->addWidget(new QLineEdit); // Avoids initial focus. + foreach (QWidget *widget, widgets) + layout->addWidget(widget); + frame.setLayout(layout); + + frame.show(); + QTest::qWaitForWindowShown(&frame); + QApplication::setActiveWindow(&frame); + foreach (QWidget *widget, widgets) { + widget->setFocus(); + QApplication::processEvents(); + + QImage image(frame.width(), frame.height(), QImage::Format_ARGB32); + frame.render(&image); + if (image.depth() < 24) { + QSKIP("Test doesn't support color depth < 24", SkipAll); + } + + QVERIFY2(testForColors(image, QColor(0xe8, 0xff, 0x66)), + (QString::fromLatin1(widget->metaObject()->className()) + + " did not contain background color #e8ff66, using style " + + QString::fromLatin1(qApp->style()->metaObject()->className())) + .toLocal8Bit().constData()); + QVERIFY2(testForColors(image, QColor(0xff, 0x00, 0x84)), + (QString::fromLatin1(widget->metaObject()->className()) + + " did not contain text color #ff0084, using style " + + QString::fromLatin1(qApp->style()->metaObject()->className())) + .toLocal8Bit().constData()); + } +} + void tst_QStyleSheetStyle::task188195_baseBackground() { QTreeView tree; -- cgit v0.12 From e97b99f249ed65c6cedfc23f751a9834641271cb Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 23 Sep 2009 14:52:08 +0200 Subject: Added QSlider to tst_QStyleSheetStyle::complexWidgetFocus. When using style sheets, QSlider::handle couldn't be customized if QSlider::groove wasn't. QComboBox::down-arrow:focus wasn't properly drawn. Reviewed-by: Olivier --- src/gui/styles/qstylesheetstyle.cpp | 20 +++++++++++++------- src/gui/styles/qwindowsstyle.cpp | 2 ++ tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp | 12 +++--------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index def82ae..0f3a88b 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -3136,19 +3136,25 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC if (const QStyleOptionSlider *slider = qstyleoption_cast(opt)) { rule.drawRule(p, opt->rect); - QRenderRule subRule = renderRule(w, opt, PseudoElement_SliderGroove); - if (!subRule.hasDrawable()) { - baseStyle()->drawComplexControl(cc, slider, p, w); - return; + QRenderRule grooveSubRule = renderRule(w, opt, PseudoElement_SliderGroove); + QRenderRule handleSubRule = renderRule(w, opt, PseudoElement_SliderHandle); + if (!grooveSubRule.hasDrawable()) { + QStyleOptionSlider slOpt(*slider); + bool handleHasRule = handleSubRule.hasDrawable(); + // If the style specifies a different handler rule, draw the groove without the handler. + if (handleHasRule) + slOpt.subControls &= ~SC_SliderHandle; + baseStyle()->drawComplexControl(cc, &slOpt, p, w); + if (!handleHasRule) + return; } QRect gr = subControlRect(cc, opt, SC_SliderGroove, w); if (slider->subControls & SC_SliderGroove) { - subRule.drawRule(p, gr); + grooveSubRule.drawRule(p, gr); } if (slider->subControls & SC_SliderHandle) { - QRenderRule subRule = renderRule(w, opt, PseudoElement_SliderHandle); QRect hr = subControlRect(cc, opt, SC_SliderHandle, w); QRenderRule subRule1 = renderRule(w, opt, PseudoElement_SliderSubPage); @@ -3169,7 +3175,7 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC subRule2.drawRule(p, r); } - subRule.drawRule(p, subRule.boxRect(hr, Margin)); + handleSubRule.drawRule(p, grooveSubRule.boxRect(hr, Margin)); } if (slider->subControls & SC_SliderTickmarks) { diff --git a/src/gui/styles/qwindowsstyle.cpp b/src/gui/styles/qwindowsstyle.cpp index 2ed9303..0f72440 100644 --- a/src/gui/styles/qwindowsstyle.cpp +++ b/src/gui/styles/qwindowsstyle.cpp @@ -3030,6 +3030,8 @@ void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComp ar.adjust(2, 2, -2, -2); if (opt->state & State_Enabled) flags |= State_Enabled; + if (opt->state & State_HasFocus) + flags |= State_HasFocus; if (sunkenArrow) flags |= State_Sunken; diff --git a/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp index e8fbd86..50bb846 100644 --- a/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -1459,16 +1459,15 @@ void tst_QStyleSheetStyle::complexWidgetFocus() // For this reason, we use unusual and extremely ugly colors! :-) QDialog frame; - // We only want to test the buttons colors. frame.setStyleSheet("*:focus { background: black; color: black } " - "QSpinBox::up-button:focus, QSpinBox::down-button:focus { width: 15px; height: 15px; background: #e8ff66; color: #ff0084 } " "QSpinBox::up-arrow:focus, QSpinBox::down-arrow:focus { width: 7px; height: 7px; background: #ff0084 } " - "QComboBox::drop-down:focus { background: #e8ff66; color: #ff0084 } " - "QComboBox::down-arrow:focus { width: 7px; height: 7px; background: #ff0084; color: #e8ff66 }"); + "QComboBox::down-arrow:focus { width: 7px; height: 7px; background: #ff0084 }" + "QSlider::handle:horizontal:focus { width: 7px; height: 7px; background: #ff0084 } "); QList widgets; widgets << new QSpinBox; widgets << new QComboBox; + widgets << new QSlider(Qt::Horizontal); QLayout* layout = new QGridLayout; layout->addWidget(new QLineEdit); // Avoids initial focus. @@ -1489,11 +1488,6 @@ void tst_QStyleSheetStyle::complexWidgetFocus() QSKIP("Test doesn't support color depth < 24", SkipAll); } - QVERIFY2(testForColors(image, QColor(0xe8, 0xff, 0x66)), - (QString::fromLatin1(widget->metaObject()->className()) - + " did not contain background color #e8ff66, using style " - + QString::fromLatin1(qApp->style()->metaObject()->className())) - .toLocal8Bit().constData()); QVERIFY2(testForColors(image, QColor(0xff, 0x00, 0x84)), (QString::fromLatin1(widget->metaObject()->className()) + " did not contain text color #ff0084, using style " -- cgit v0.12 From 465ae8e6180c812eb91279ee4ccf047a4de2932d Mon Sep 17 00:00:00 2001 From: Marius Bugge Monsen Date: Wed, 23 Sep 2009 15:30:00 +0200 Subject: Fix QGraphicsLinearLayout::layoutDirection test failure on cocoa. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The style influences the layout results. To get consistent results across platforms, we have to specify the style when testing. Reviewed-by: Jan-Arve Sæther --- tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp b/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp index 4a664a4..a5d79de 100644 --- a/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp +++ b/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp @@ -46,6 +46,8 @@ #include #include #include +#include +#include class tst_QGraphicsLinearLayout : public QObject { Q_OBJECT @@ -141,6 +143,9 @@ public: // It is only called once. void tst_QGraphicsLinearLayout::initTestCase() { + // since the style will influence the results, we have to ensure + // that the tests are run using the same style on all platforms + QApplication::setStyle(new QPlastiqueStyle); } // This will be called after the last test function is executed. -- cgit v0.12 From bfdee5f1658b1bac4a0d1b93c5a45dbc6709f9e3 Mon Sep 17 00:00:00 2001 From: mae Date: Wed, 23 Sep 2009 15:28:24 +0200 Subject: QTextCursor selection extension when inserting characters The change makes QTextCursor not extend the selection when inserting characters at the end of the selection, provided that the cursor position is at the end. Reviewed-by: Simon Hausmann Reviewed-by: Roberto Raggi --- src/gui/text/qtextcursor.cpp | 8 ++- tests/auto/qtextcursor/tst_qtextcursor.cpp | 94 ++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index 8b85d2d..ce62834 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -92,8 +92,12 @@ QTextCursorPrivate::AdjustResult QTextCursorPrivate::adjustPosition(int position { QTextCursorPrivate::AdjustResult result = QTextCursorPrivate::CursorMoved; // not(!) <= , so that inserting text adjusts the cursor correctly - if (position < positionOfChange || - (position == positionOfChange && op == QTextUndoCommand::KeepCursor)) { + if (position < positionOfChange + || (position == positionOfChange + && (op == QTextUndoCommand::KeepCursor + || anchor < position) + ) + ) { result = CursorUnchanged; } else { if (charsAddedOrRemoved < 0 && position < positionOfChange - charsAddedOrRemoved) diff --git a/tests/auto/qtextcursor/tst_qtextcursor.cpp b/tests/auto/qtextcursor/tst_qtextcursor.cpp index 88ecc73..d910c8d 100644 --- a/tests/auto/qtextcursor/tst_qtextcursor.cpp +++ b/tests/auto/qtextcursor/tst_qtextcursor.cpp @@ -147,6 +147,8 @@ private slots: void task244408_wordUnderCursor_data(); void task244408_wordUnderCursor(); + void adjustCursorsOnInsert(); + private: int blockCount(); @@ -1658,5 +1660,97 @@ void tst_QTextCursor::task244408_wordUnderCursor() QCOMPARE(cursor.selectedText(), expected); } +void tst_QTextCursor::adjustCursorsOnInsert() +{ + cursor.insertText("Some text before "); + int posBefore = cursor.position(); + cursor.insertText("selected text"); + int posAfter = cursor.position(); + cursor.insertText(" some text afterwards"); + + QTextCursor selection = cursor; + selection.setPosition(posBefore); + selection.setPosition(posAfter, QTextCursor::KeepAnchor); + + cursor.setPosition(posBefore-1); + cursor.insertText(QLatin1String("x")); + QCOMPARE(selection.anchor(), posBefore+1); + QCOMPARE(selection.position(), posAfter+1); + doc->undo(); + + cursor.setPosition(posBefore); + cursor.insertText(QLatin1String("x")); + QCOMPARE(selection.anchor(), posBefore+1); + QCOMPARE(selection.position(), posAfter+1); + doc->undo(); + + cursor.setPosition(posBefore+1); + cursor.insertText(QLatin1String("x")); + QCOMPARE(selection.anchor(), posBefore); + QCOMPARE(selection.position(), posAfter+1); + doc->undo(); + + cursor.setPosition(posAfter-1); + cursor.insertText(QLatin1String("x")); + QCOMPARE(selection.anchor(), posBefore); + QCOMPARE(selection.position(), posAfter+1); + doc->undo(); + + cursor.setPosition(posAfter); + cursor.insertText(QLatin1String("x")); + QCOMPARE(selection.anchor(), posBefore); + QCOMPARE(selection.position(), posAfter); + doc->undo(); + + cursor.setPosition(posAfter+1); + cursor.insertText(QLatin1String("x")); + QCOMPARE(selection.anchor(), posBefore); + QCOMPARE(selection.position(), posAfter); + doc->undo(); + + selection.setPosition(posAfter); + selection.setPosition(posBefore, QTextCursor::KeepAnchor); + + cursor.setPosition(posBefore-1); + cursor.insertText(QLatin1String("x")); + QCOMPARE(selection.position(), posBefore+1); + QCOMPARE(selection.anchor(), posAfter+1); + doc->undo(); + + cursor.setPosition(posBefore); + cursor.insertText(QLatin1String("x")); + QCOMPARE(selection.position(), posBefore+1); + QCOMPARE(selection.anchor(), posAfter+1); + doc->undo(); + + cursor.setPosition(posBefore+1); + cursor.insertText(QLatin1String("x")); + QCOMPARE(selection.position(), posBefore); + QCOMPARE(selection.anchor(), posAfter+1); + doc->undo(); + + cursor.setPosition(posAfter-1); + cursor.insertText(QLatin1String("x")); + QCOMPARE(selection.position(), posBefore); + QCOMPARE(selection.anchor(), posAfter+1); + doc->undo(); + + cursor.setPosition(posAfter); + cursor.insertText(QLatin1String("x")); + QCOMPARE(selection.position(), posBefore); + QCOMPARE(selection.anchor(), posAfter+1); + doc->undo(); + + cursor.setPosition(posAfter+1); + cursor.insertText(QLatin1String("x")); + QCOMPARE(selection.position(), posBefore); + QCOMPARE(selection.anchor(), posAfter); + doc->undo(); + + + + +} + QTEST_MAIN(tst_QTextCursor) #include "tst_qtextcursor.moc" -- cgit v0.12 From 061f4976c7a3f9ac86ccd289ee93fc64182de27d Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 23 Sep 2009 15:18:06 +0200 Subject: missing & in foreach --- tools/linguist/lupdate/cpp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index be86c93..6c56a56 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -1969,7 +1969,7 @@ void loadCPP(Translator &translator, const QStringList &filenames, ConversionDat CppFiles::setResults(filename, parser.getResults()); } - foreach (const QString filename, filenames) + foreach (const QString &filename, filenames) if (!CppFiles::isBlacklisted(filename)) if (Translator *tor = CppFiles::getResults(filename)->tor) foreach (const TranslatorMessage &msg, tor->messages()) -- cgit v0.12 From f64753362edf6c22879b1f39e83de1f69b8dda77 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 23 Sep 2009 10:55:40 +0200 Subject: simplify --- tools/linguist/lupdate/cpp.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index 6c56a56..9b7fdc8 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -1056,10 +1056,7 @@ QSet &CppFiles::blacklistedFiles() const ParseResults *CppFiles::getResults(const QString &cleanFile) { - ParseResultHash::ConstIterator it = parsedFiles().find(cleanFile); - if (it == parsedFiles().constEnd()) - return 0; - return *it; + return parsedFiles().value(cleanFile); } void CppFiles::setResults(const QString &cleanFile, const ParseResults *results) -- cgit v0.12 From 5fc344431354c00340d9727f64dbb3c29972f93d Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 18 Aug 2009 17:31:05 +0200 Subject: optimize directory scanning qdiroperator uses qregexp for filtering, which is sloooow. so use a hash lookup on extensions instead. --- tools/linguist/lupdate/main.cpp | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp index 3cba90d..e8cf121 100644 --- a/tools/linguist/lupdate/main.cpp +++ b/tools/linguist/lupdate/main.cpp @@ -62,23 +62,14 @@ static void printOut(const QString & out) } static void recursiveFileInfoList(const QDir &dir, - const QStringList &nameFilters, QDir::Filters filter, bool recursive, + const QSet &nameFilters, QDir::Filters filter, QFileInfoList *fileinfolist) { - if (recursive) - filter |= QDir::AllDirs; - QFileInfoList entries = dir.entryInfoList(nameFilters, filter); - - QFileInfoList::iterator it; - for (it = entries.begin(); it != entries.end(); ++it) { - QString fname = it->fileName(); - if (fname != QLatin1String(".") && fname != QLatin1String("..")) { - if (it->isDir()) - recursiveFileInfoList(QDir(it->absoluteFilePath()), nameFilters, filter, recursive, fileinfolist); - else - fileinfolist->append(*it); - } - } + foreach (const QFileInfo &fi, dir.entryInfoList(filter)) + if (fi.isDir()) + recursiveFileInfoList(QDir(fi.absoluteFilePath()), nameFilters, filter, fileinfolist); + else if (nameFilters.contains(fi.suffix())) + fileinfolist->append(fi); } static void printUsage() @@ -243,7 +234,7 @@ int main(int argc, char **argv) bool recursiveScan = true; QString extensions = m_defaultExtensions; - QStringList extensionsNameFilters; + QSet extensionsNameFilters; for (int i = 1; i < argc; ++i) { if (args.at(i) == QLatin1String("-ts")) @@ -418,15 +409,15 @@ int main(int argc, char **argv) foreach (QString ext, extensions.split(QLatin1Char(','))) { ext = ext.trimmed(); if (ext.startsWith(QLatin1Char('.'))) - ext.remove(0,1); - ext.insert(0, QLatin1String("*.")); - extensionsNameFilters << ext; + ext.remove(0, 1); + extensionsNameFilters.insert(ext); } } QDir::Filters filters = QDir::Files | QDir::NoSymLinks; + if (recursiveScan) + filters |= QDir::AllDirs | QDir::NoDotAndDotDot; QFileInfoList fileinfolist; - recursiveFileInfoList(dir, extensionsNameFilters, filters, - recursiveScan, &fileinfolist); + recursiveFileInfoList(dir, extensionsNameFilters, filters, &fileinfolist); int scanRootLen = dir.absolutePath().length(); foreach (const QFileInfo &fi, fileinfolist) { QString fn = QDir::cleanPath(fi.absoluteFilePath()); -- cgit v0.12 From 5bd5154ae0095a3e166e8be9347c613b2194e0be Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 18 Aug 2009 19:14:21 +0200 Subject: cut down use of qstring::simplified() --- tools/linguist/lupdate/cpp.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index 9b7fdc8..e72f1c9 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE /* qmake ignore Q_OBJECT */ -static const char MagicComment[] = "TRANSLATOR "; +static QString MagicComment(QLatin1String("TRANSLATOR")); #define STRING(s) static QString str##s(QLatin1String(#s)) @@ -1811,9 +1811,15 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) } sourcetext.resize(ptr - (ushort *)sourcetext.data()); } else { - comment = yyWord.simplified(); - if (comment.startsWith(QLatin1String(MagicComment))) { - comment.remove(0, sizeof(MagicComment) - 1); + const ushort *uc = (const ushort *)yyWord.unicode(); // Is zero-terminated + int idx = 0; + ushort c; + while ((c = uc[idx]) == ' ' || c == '\t' || c == '\n') + ++idx; + if (!memcmp(uc + idx, MagicComment.unicode(), MagicComment.length() * 2)) { + idx += MagicComment.length(); + comment = QString::fromRawData(yyWord.unicode() + idx, + yyWord.length() - idx).simplified(); int k = comment.indexOf(QLatin1Char(' ')); if (k == -1) { context = comment; @@ -1826,8 +1832,6 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) results->tor->setExtras(extra); extra.clear(); } - } else { - comment.detach(); } } yyTok = getToken(); -- cgit v0.12 From 2bc1550b3dfe05353c2cb72f9d980c67e68aceaf Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 18 Aug 2009 19:23:09 +0200 Subject: avoid isalpha() & isalnum() they are surprisingly expensive --- tools/linguist/lupdate/cpp.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index e72f1c9..c224e2f 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -561,12 +561,13 @@ uint CppParser::getToken() } } while (yyCh != '\n' && yyCh != EOF); yyCh = getChar(); - } else if (isalpha(yyCh) || yyCh == '_') { + } else if ((yyCh >= 'A' && yyCh <= 'Z') || (yyCh >= 'a' && yyCh <= 'z') || yyCh == '_') { ushort *ptr = (ushort *)yyWord.unicode(); do { *ptr++ = yyCh; yyCh = getChar(); - } while (isalnum(yyCh) || yyCh == '_'); + } while ((yyCh >= 'A' && yyCh <= 'Z') || (yyCh >= 'a' && yyCh <= 'z') + || (yyCh >= '0' && yyCh <= '9') || yyCh == '_'); yyWord.resize(ptr - (ushort *)yyWord.unicode()); //qDebug() << "IDENT: " << yyWord; -- cgit v0.12 From b17a8c5c1bc7d8c26f2bf35116de71d7b582751f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 18 Aug 2009 19:59:28 +0200 Subject: when matching strings, skip also leading comments --- tools/linguist/lupdate/cpp.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index c224e2f..b8f8451 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -1174,16 +1174,18 @@ bool CppParser::match(uint t) bool CppParser::matchString(QString *s) { - bool matches = (yyTok == Tok_String); + bool matches = false; s->clear(); - while (yyTok == Tok_String) { + forever { + while (yyTok == Tok_Comment) + yyTok = getToken(); + if (yyTok != Tok_String) + return matches; + matches = true; *s += yyWord; s->detach(); - do { - yyTok = getToken(); - } while (yyTok == Tok_Comment); + yyTok = getToken(); } - return matches; } bool CppParser::matchEncoding(bool *utf8) -- cgit v0.12 From d5d169a79fe199ad210d5625b20344bdc2814e60 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 18 Aug 2009 20:01:15 +0200 Subject: no need to actually compute number values. only 0 is special --- tools/linguist/lupdate/cpp.cpp | 55 ++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 37 deletions(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index b8f8451..8de403e 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -167,7 +167,6 @@ private: bool match(uint t); bool matchString(QString *s); bool matchEncoding(bool *utf8); - bool matchInteger(qlonglong *number); bool matchStringOrNull(QString *s); bool matchExpression(); @@ -202,7 +201,7 @@ private: Tok_Ident, Tok_Comment, Tok_String, Tok_Arrow, Tok_Colon, Tok_ColonColon, Tok_Equals, Tok_LeftBrace = 30, Tok_RightBrace, Tok_LeftParen, Tok_RightParen, Tok_Comma, Tok_Semicolon, - Tok_Integer = 40, + Tok_Null = 40, Tok_Integer, Tok_QuotedInclude = 50, Tok_AngledInclude, Tok_Other = 99 }; @@ -796,6 +795,17 @@ uint CppParser::getToken() yyCh = getChar(); return Tok_Semicolon; case '0': + yyCh = getChar(); + if (yyCh == 'x') { + do { + yyCh = getChar(); + } while ((yyCh >= '0' && yyCh <= '9') + || (yyCh >= 'a' && yyCh <= 'f') || (yyCh >= 'A' && yyCh <= 'F')); + return Tok_Integer; + } + if (yyCh < '0' || yyCh > '9') + return Tok_Null; + // Fallthrough case '1': case '2': case '3': @@ -805,25 +815,10 @@ uint CppParser::getToken() case '7': case '8': case '9': - { - QByteArray ba; - ba += yyCh; + do { yyCh = getChar(); - bool hex = yyCh == 'x'; - if (hex) { - ba += yyCh; - yyCh = getChar(); - } - while (hex ? isxdigit(yyCh) : isdigit(yyCh)) { - ba += yyCh; - yyCh = getChar(); - } - bool ok; - yyInteger = ba.toLongLong(&ok); - if (ok) - return Tok_Integer; - break; - } + } while (yyCh >= '0' && yyCh <= '9'); + return Tok_Integer; default: yyCh = getChar(); break; @@ -1211,28 +1206,14 @@ bool CppParser::matchEncoding(bool *utf8) if (yyWord == strDefaultCodec || yyWord == strCodecForTr) { *utf8 = false; yyTok = getToken(); - return true; + return true; } return false; } -bool CppParser::matchInteger(qlonglong *number) -{ - bool matches = (yyTok == Tok_Integer); - if (matches) { - yyTok = getToken(); - *number = yyInteger; - } - return matches; -} - bool CppParser::matchStringOrNull(QString *s) { - bool matches = matchString(s); - qlonglong num = 0; - if (!matches) - matches = matchInteger(&num); - return matches && num == 0; + return matchString(s) || match(Tok_Null); } /* @@ -1251,7 +1232,7 @@ bool CppParser::matchStringOrNull(QString *s) */ bool CppParser::matchExpression() { - if (match(Tok_Integer)) + if (match(Tok_Null) || match(Tok_Integer)) return true; int parenlevel = 0; -- cgit v0.12 From e4e45bc5bb3a4b38f8f726b26f863c1fdb5575f1 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 18 Aug 2009 20:09:47 +0200 Subject: take advantage of knowing that qstrings are zero-terminated internally --- tools/linguist/lupdate/cpp.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index 8de403e..3999b84 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -307,13 +307,12 @@ void CppParser::setInput(QTextStream &ts, const QString &fileName) uint CppParser::getChar() { - int len = yyInStr.size(); const ushort *uc = (const ushort *)yyInStr.unicode(); forever { - if (yyInPos >= len) - return EOF; uint c = uc[yyInPos++]; - if (c == '\\' && yyInPos < len) { + if (!c) + return EOF; + if (c == '\\') { if (uc[yyInPos] == '\n') { ++yyCurLineNo; ++yyInPos; @@ -322,13 +321,13 @@ uint CppParser::getChar() if (uc[yyInPos] == '\r') { ++yyCurLineNo; ++yyInPos; - if (yyInPos < len && uc[yyInPos] == '\n') + if (uc[yyInPos] == '\n') ++yyInPos; continue; } } if (c == '\r') { - if (yyInPos < len && uc[yyInPos] == '\n') + if (uc[yyInPos] == '\n') ++yyInPos; c = '\n'; ++yyCurLineNo; -- cgit v0.12 From 830fd43c53a9cd53d626b8f6fe3682d92df0cc59 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 18 Aug 2009 20:19:25 +0200 Subject: use a source char pointer instead of a string + index --- tools/linguist/lupdate/cpp.cpp | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index 3999b84..8e9933d 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -226,7 +226,7 @@ private: QTextCodec *yySourceCodec; bool yySourceIsUnicode; QString yyInStr; - int yyInPos; + const ushort *yyInPtr; // Parser state uint yyTok; @@ -254,7 +254,6 @@ CppParser::CppParser(ParseResults *_results) results = new ParseResults; directInclude = false; } - yyInPos = 0; yyBraceDepth = 0; yyParenDepth = 0; yyCurLineNo = 1; @@ -307,28 +306,32 @@ void CppParser::setInput(QTextStream &ts, const QString &fileName) uint CppParser::getChar() { - const ushort *uc = (const ushort *)yyInStr.unicode(); + const ushort *uc = yyInPtr; forever { - uint c = uc[yyInPos++]; - if (!c) + ushort c = *uc; + if (!c) { + yyInPtr = uc; return EOF; + } + ++uc; if (c == '\\') { - if (uc[yyInPos] == '\n') { + ushort cc = *uc; + if (cc == '\n') { ++yyCurLineNo; - ++yyInPos; + ++uc; continue; } - if (uc[yyInPos] == '\r') { + if (cc == '\r') { ++yyCurLineNo; - ++yyInPos; - if (uc[yyInPos] == '\n') - ++yyInPos; + ++uc; + if (*uc == '\n') + ++uc; continue; } } if (c == '\r') { - if (uc[yyInPos] == '\n') - ++yyInPos; + if (*uc == '\n') + ++uc; c = '\n'; ++yyCurLineNo; yyAtNewline = true; @@ -338,6 +341,7 @@ uint CppParser::getChar() } else if (c != ' ' && c != '\t' && c != '#') { yyAtNewline = false; } + yyInPtr = uc; return c; } } @@ -1355,6 +1359,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) bool yyTokColonSeen = false; // Start of c'tor's initializer list yyWord.reserve(yyInStr.size()); // Rather insane. That's because we do no length checking. + yyInPtr = (const ushort *)yyInStr.unicode(); yyCh = getChar(); yyTok = getToken(); while (yyTok != Tok_Eof) { -- cgit v0.12 From 13fa5aa35e6cbf6bf7710952f541810fee7bba27 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 18 Aug 2009 20:33:57 +0200 Subject: move static objects out of function scope cuts away a few thousand instructions. need to revisit this in case of making the parser a dynamic library. --- tools/linguist/lupdate/cpp.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index 8e9933d..f6ebfb1 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -1186,14 +1186,14 @@ bool CppParser::matchString(QString *s) } } +STRING(QApplication); +STRING(QCoreApplication); +STRING(UnicodeUTF8); +STRING(DefaultCodec); +STRING(CodecForTr); + bool CppParser::matchEncoding(bool *utf8) { - STRING(QApplication); - STRING(QCoreApplication); - STRING(UnicodeUTF8); - STRING(DefaultCodec); - STRING(CodecForTr); - if (yyTok != Tok_Ident) return false; if (yyWord == strQApplication || yyWord == strQCoreApplication) { -- cgit v0.12 From 313c49628ac74f647df0f3b1e2a660ebd1f4436c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 18 Sep 2009 12:35:12 +0200 Subject: remove dead code needsTrFunctions was never set any more --- tools/linguist/lupdate/cpp.cpp | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index f6ebfb1..c6f38a0 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -76,7 +76,7 @@ struct Namespace { Namespace() : isClass(false), - hasTrFunctions(false), needsTrFunctions(false), complained(false) + hasTrFunctions(false), complained(false) {} QString name; @@ -89,7 +89,6 @@ struct Namespace { bool isClass; bool hasTrFunctions; - bool needsTrFunctions; bool complained; // ... that tr functions are missing. }; @@ -875,7 +874,6 @@ Namespace *ParseResults::include(Namespace *that, const Namespace *other) // (though not necessary) if they are shared thisSub->isClass |= otherSub->isClass; thisSub->hasTrFunctions |= otherSub->hasTrFunctions; - thisSub->needsTrFunctions |= otherSub->needsTrFunctions; thisSub->complained |= otherSub->complained; if (Namespace *newSub = include(thisSub, otherSub)) { @@ -1843,17 +1841,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) #endif break; case Tok_RightBrace: - if (yyBraceDepth + 1 == namespaceDepths.count()) { - // class or namespace - Namespace *ns = namespaces.last(); - if (ns->needsTrFunctions && !ns->hasTrFunctions && !ns->complained) { - qWarning("%s:%d: Class '%s' lacks Q_OBJECT macro\n", - qPrintable(yyFileName), yyLineNo, - qPrintable(stringifyNamespace(namespaces))); - ns->complained = true; - } + if (yyBraceDepth + 1 == namespaceDepths.count()) // class or namespace truncateNamespaces(&namespaces, namespaceDepths.pop()); - } if (yyBraceDepth == namespaceDepths.count()) { // function, class or namespace if (!yyBraceDepth && !directInclude) { -- cgit v0.12 From dd499bac5ce01abe730d47a84c7ad3e29bc3cf4d Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 17 Sep 2009 19:21:15 +0200 Subject: remove more dead code no need for parameter "unresolved" --- tools/linguist/lupdate/cpp.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index c6f38a0..fce53af 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -1521,8 +1521,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) yyTok = getToken(); } NamespaceList nsl; - QStringList unresolved; - if (fullyQualify(namespaces, fullName, false, &nsl, &unresolved)) { + if (fullyQualify(namespaces, fullName, false, &nsl, 0)) { modifyNamespace(&namespaces); namespaces.last()->usings.insert(stringListifyNamespace(nsl)); } -- cgit v0.12 From b647762117f49a3e8d20ceba84c47d4fb2941722 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 18 Sep 2009 16:10:13 +0200 Subject: do not record class forward declarations they don't create useful namespaces and don't hold flags, so it is pointless to clutter the namespace maps with them. --- tools/linguist/lupdate/cpp.cpp | 55 +++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index fce53af..5dbb8e2 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -1394,8 +1394,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) } case Tok_friend: yyTok = getToken(); - // Ensure that these don't end up being interpreted as forward declarations - // (they are forwards, but with different namespacing). + // These are forward declarations, so ignore them. if (yyTok == Tok_class) yyTok = getToken(); break; @@ -1406,7 +1405,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) */ yyTok = getToken(); if (yyBraceDepth == namespaceDepths.count() && yyParenDepth == 0) { - QStringList fct; + QStringList quali; + QString fct; do { /* This code should execute only once, but we play @@ -1414,52 +1414,51 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) 'class Q_EXPORT QMessageBox', in which case 'QMessageBox' is the class name, not 'Q_EXPORT'. */ - text = yyWord; - text.detach(); - fct = QStringList(text); + fct = yyWord; + fct.detach(); yyTok = getToken(); } while (yyTok == Tok_Ident); while (yyTok == Tok_ColonColon) { yyTok = getToken(); if (yyTok != Tok_Ident) break; // Oops ... - text = yyWord; - text.detach(); - fct += text; + quali << fct; + fct = yyWord; + fct.detach(); yyTok = getToken(); } - if (fct.count() > 1) { - // Forward-declared class definitions can be namespaced - NamespaceList nsl; - if (!fullyQualify(namespaces, fct, true, &nsl, 0)) { - qWarning("%s:%d: Ignoring definition of undeclared qualified class\n", - qPrintable(yyFileName), yyLineNo); - break; - } - namespaceDepths.push(namespaces.count()); - namespaces = nsl; - } else { - namespaceDepths.push(namespaces.count()); - enterNamespace(&namespaces, fct.first()); - } - namespaces.last()->isClass = true; - while (yyTok == Tok_Comment) yyTok = getToken(); if (yyTok == Tok_Colon) { - // Skip any token until '{' since lupdate might do things wrong if it finds + // Skip any token until '{' since we might do things wrong if we find // a '::' token here. do { yyTok = getToken(); } while (yyTok != Tok_LeftBrace && yyTok != Tok_Eof); } else { if (yyTok != Tok_LeftBrace) { - // Obviously a forward decl - truncateNamespaces(&namespaces, namespaceDepths.pop()); + // Obviously a forward declaration. We skip those, as they + // don't create actually usable namespaces. break; } } + if (!quali.isEmpty()) { + // Forward-declared class definitions can be namespaced. + NamespaceList nsl; + if (!fullyQualify(namespaces, quali, true, &nsl, 0)) { + qWarning("%s:%d: Ignoring definition of undeclared qualified class\n", + qPrintable(yyFileName), yyLineNo); + break; + } + namespaceDepths.push(namespaces.count()); + namespaces = nsl; + } else { + namespaceDepths.push(namespaces.count()); + } + enterNamespace(&namespaces, fct); + namespaces.last()->isClass = true; + functionContext = namespaces; functionContextUnresolved.clear(); // Pointless prospectiveContext.clear(); -- cgit v0.12 From 57df91e20b8e669f4833e1f11dc2474d8118e0c9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 18 Sep 2009 17:52:10 +0200 Subject: optimize/clarify function context stringification --- tools/linguist/lupdate/cpp.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index 5dbb8e2..d5d2e10 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -1590,14 +1590,14 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) } while (!functionContext.at(idx - 1)->hasTrFunctions) { if (idx == 1 || !functionContext.at(idx - 2)->isClass) { - idx = functionContext.length(); + context = stringifyNamespace(functionContext); if (!functionContext.last()->complained) { qWarning("%s:%d: Class '%s' lacks Q_OBJECT macro\n", qPrintable(yyFileName), yyLineNo, - qPrintable(stringifyNamespace(functionContext))); + qPrintable(context)); functionContext.last()->complained = true; } - break; + goto gotctx; } --idx; } @@ -1626,19 +1626,20 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) NamespaceList nsl; QStringList unresolved; if (fullyQualify(functionContext, prefix.split(strColons), false, &nsl, &unresolved)) { + context = stringifyNamespace(nsl); if (!nsl.last()->hasTrFunctions && !nsl.last()->complained) { qWarning("%s:%d: Class '%s' lacks Q_OBJECT macro\n", qPrintable(yyFileName), yyLineNo, - qPrintable(stringifyNamespace(nsl))); + qPrintable(context)); nsl.last()->complained = true; } - context = stringifyNamespace(nsl); } else { context = (stringListifyNamespace(nsl) + unresolved).join(strColons); } prefix.clear(); } + gotctx: recordMessage(line, context, text, comment, extracomment, msgid, extra, utf8, plural); } extracomment.clear(); -- cgit v0.12 From 1c4dc6be0c5b6a730e5ae910afa8c4da986e37ee Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 23 Sep 2009 12:47:45 +0200 Subject: drastically improve lupdate's scalability do not import all data from included files into the current file (which turned out to be extremely expensive for 3rdparty/webkit), but do hierarchical lookups on demand. this makes the lookups as such much slower, of course, but it still pays off. --- tools/linguist/lupdate/cpp.cpp | 477 ++++++++++++++++++++++++----------------- 1 file changed, 280 insertions(+), 197 deletions(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index d5d2e10..c9b25f3 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -43,6 +43,7 @@ #include +#include #include #include #include @@ -62,53 +63,110 @@ static QString MagicComment(QLatin1String("TRANSLATOR")); //#define DIAGNOSE_RETRANSLATABILITY // FIXME: should make a runtime option of this -uint qHash(const QStringList &qsl) +class HashString { +public: + HashString() : m_hashed(false) {} + explicit HashString(const QString &str) : m_str(str), m_hashed(false) {} + void setValue(const QString &str) { m_str = str; m_hashed = false; } + const QString &value() const { return m_str; } + bool operator==(const HashString &other) const { return m_str == other.m_str; } +private: + QString m_str; + mutable uint m_hash; + mutable bool m_hashed; + friend uint qHash(const HashString &str); +}; + +uint qHash(const HashString &str) +{ + if (!str.m_hashed) { + str.m_hashed = true; + str.m_hash = qHash(str.m_str); + } + return str.m_hash; +} + +class HashStringList { +public: + explicit HashStringList(const QList &list) : m_list(list), m_hashed(false) {} + const QList &value() const { return m_list; } + bool operator==(const HashStringList &other) const { return m_list == other.m_list; } +private: + QList m_list; + mutable uint m_hash; + mutable bool m_hashed; + friend uint qHash(const HashStringList &list); +}; + +uint qHash(const HashStringList &list) { - uint hash = 0; - foreach (const QString &qs, qsl) { - hash ^= qHash(qs) ^ 0xa09df22f; - hash = (hash << 13) | (hash >> 19); + if (!list.m_hashed) { + list.m_hashed = true; + uint hash = 0; + foreach (const HashString &qs, list.m_list) { + hash ^= qHash(qs) ^ 0xa09df22f; + hash = (hash << 13) | (hash >> 19); + } + list.m_hash = hash; } - return hash; + return list.m_hash; } +typedef QList NamespaceList; + struct Namespace { Namespace() : - isClass(false), + classDef(0), hasTrFunctions(false), complained(false) {} - QString name; - QMap children; - QMap aliases; - QSet usings; - - int fileId; + QHash children; + QHash aliases; + QList usings; - bool isClass; + // Class declarations set no flags and create no namespaces, so they are ignored. + // Class definitions may appear multiple times - but only because we are trying to + // "compile" all sources irrespective of build configuration. + // Nested classes may be forward-declared inside a definition, and defined in another file. + // The latter will detach the class' child list, so clones need a backlink to the original + // definition (either one in case of multiple definitions). + Namespace *classDef; bool hasTrFunctions; bool complained; // ... that tr functions are missing. }; -typedef QList NamespaceList; +static int nextFileId; + +class VisitRecorder { +public: + VisitRecorder() + { + m_ba.resize(nextFileId); + } + bool tryVisit(int fileId) + { + if (m_ba.at(fileId)) + return false; + m_ba[fileId] = true; + return true; + } +private: + QBitArray m_ba; +}; struct ParseResults { ParseResults() { - static int nextFileId; - rootNamespace.fileId = nextFileId++; tor = 0; } - bool detachNamespace(Namespace **that); - Namespace *include(Namespace *that, const Namespace *other); - void unite(const ParseResults *other); + int fileId; Namespace rootNamespace; Translator *tor; - QSet allIncludes; + QSet includes; }; typedef QHash ParseResultHash; @@ -117,7 +175,7 @@ class CppFiles { public: static const ParseResults *getResults(const QString &cleanFile); - static void setResults(const QString &cleanFile, const ParseResults *results); + static void setResults(const QString &cleanFile, ParseResults *results); static bool isBlacklisted(const QString &cleanFile); static void setBlacklisted(const QString &cleanFile); @@ -135,13 +193,13 @@ public: void setTranslator(Translator *tor) { results->tor = tor; } void parse(const QString &initialContext, ConversionData &cd, QSet &inclusions); void parseInternal(ConversionData &cd, QSet &inclusions); - const ParseResults *getResults() const { return results; } + ParseResults *getResults() const { return results; } void deleteResults() { delete results; } struct SavedState { - QStringList namespaces; + NamespaceList namespaces; QStack namespaceDepths; - QStringList functionContext; + NamespaceList functionContext; QString functionContextUnresolved; QString pendingContext; }; @@ -183,15 +241,28 @@ private: static QString stringifyNamespace(const NamespaceList &namespaces); static QStringList stringListifyNamespace(const NamespaceList &namespaces); - void modifyNamespace(NamespaceList *namespaces); - NamespaceList resolveNamespaces(const QStringList &segments); - bool qualifyOne(const NamespaceList &namespaces, int nsIdx, const QString &segment, - NamespaceList *resolved); - bool fullyQualify(const NamespaceList &namespaces, const QStringList &segments, + typedef bool (CppParser::*VisitNamespaceCallback)(const Namespace *ns, void *context) const; + bool visitNamespace(const NamespaceList &namespaces, int nsCount, + VisitNamespaceCallback callback, void *context, + VisitRecorder &vr, const ParseResults *rslt) const; + bool visitNamespace(const NamespaceList &namespaces, int nsCount, + VisitNamespaceCallback callback, void *context) const; + static QStringList stringListifySegments(const QList &namespaces); + bool qualifyOneCallbackOwn(const Namespace *ns, void *context) const; + bool qualifyOneCallbackUsing(const Namespace *ns, void *context) const; + bool qualifyOne(const NamespaceList &namespaces, int nsCnt, const HashString &segment, + NamespaceList *resolved) const; + bool fullyQualify(const NamespaceList &namespaces, const QList &segments, bool isDeclaration, - NamespaceList *resolved, QStringList *unresolved); - void enterNamespace(NamespaceList *namespaces, const QString &name); + NamespaceList *resolved, QStringList *unresolved) const; + bool fullyQualify(const NamespaceList &namespaces, const QString &segments, + bool isDeclaration, + NamespaceList *resolved, QStringList *unresolved) const; + bool findNamespaceCallback(const Namespace *ns, void *context) const; + const Namespace *findNamespace(const NamespaceList &namespaces, int nsCount = -1) const; + void enterNamespace(NamespaceList *namespaces, const HashString &name, bool isClass); void truncateNamespaces(NamespaceList *namespaces, int lenght); + Namespace *modifyNamespace(NamespaceList *namespaces, bool tryOrigin = true); enum { Tok_Eof, Tok_class, Tok_friend, Tok_namespace, Tok_using, Tok_return, @@ -837,85 +908,40 @@ uint CppParser::getToken() void CppParser::saveState(SavedState *state) { - state->namespaces = stringListifyNamespace(namespaces); + state->namespaces = namespaces; state->namespaceDepths = namespaceDepths; - state->functionContext = stringListifyNamespace(functionContext); + state->functionContext = functionContext; state->functionContextUnresolved = functionContextUnresolved; state->pendingContext = pendingContext; } void CppParser::loadState(const SavedState *state) { - namespaces = resolveNamespaces(state->namespaces); + namespaces = state->namespaces; namespaceDepths = state->namespaceDepths; - functionContext = resolveNamespaces(state->functionContext); + functionContext = state->functionContext; functionContextUnresolved = state->functionContextUnresolved; pendingContext = state->pendingContext; } -bool ParseResults::detachNamespace(Namespace **that) -{ - if ((*that)->fileId != rootNamespace.fileId) { - Namespace *newThat = new Namespace; - *newThat = **that; - newThat->fileId = rootNamespace.fileId; - *that = newThat; - return true; - } - return false; -} - -Namespace *ParseResults::include(Namespace *that, const Namespace *other) +Namespace *CppParser::modifyNamespace(NamespaceList *namespaces, bool tryOrigin) { - Namespace *origThat = that; - foreach (Namespace *otherSub, other->children) { - if (Namespace *thisSub = that->children.value(otherSub->name)) { - // Don't make these cause a detach - it's best - // (though not necessary) if they are shared - thisSub->isClass |= otherSub->isClass; - thisSub->hasTrFunctions |= otherSub->hasTrFunctions; - thisSub->complained |= otherSub->complained; - - if (Namespace *newSub = include(thisSub, otherSub)) { - thisSub = newSub; - detachNamespace(&that); - that->children[thisSub->name] = thisSub; - } - } else { - detachNamespace(&that); - that->children[otherSub->name] = otherSub; - } - } - if ((that->aliases != other->aliases && !other->aliases.isEmpty()) - || (that->usings != other->usings && !other->usings.isEmpty())) { - detachNamespace(&that); - that->aliases.unite(other->aliases); - that->usings.unite(other->usings); - } - return (that != origThat) ? that : 0; -} - -void ParseResults::unite(const ParseResults *other) -{ - allIncludes.unite(other->allIncludes); - include(&rootNamespace, &other->rootNamespace); -} - -void CppParser::modifyNamespace(NamespaceList *namespaces) -{ - Namespace *pns = 0; - int i = namespaces->count(); - forever { - --i; - Namespace *ns = namespaces->at(i); - bool detached = results->detachNamespace(&ns); - if (pns) - ns->children[pns->name] = pns; - if (!detached) // Known to be true for root namespace - return; + Namespace *pns, *ns = &results->rootNamespace; + for (int i = 1; i < namespaces->count(); ++i) { pns = ns; - namespaces->replace(i, ns); + if (!(ns = pns->children.value(namespaces->at(i)))) { + do { + ns = new Namespace; + if (tryOrigin) + if (const Namespace *ons = findNamespace(*namespaces, i + 1)) + ns->classDef = ons->classDef; + pns->children.insert(namespaces->at(i), ns); + pns = ns; + } while (++i < namespaces->count()); + break; + } } + return ns; } QString CppParser::stringifyNamespace(const NamespaceList &namespaces) @@ -924,7 +950,7 @@ QString CppParser::stringifyNamespace(const NamespaceList &namespaces) for (int i = 1; i < namespaces.count(); ++i) { if (i > 1) ret += QLatin1String("::"); - ret += namespaces.at(i)->name; + ret += namespaces.at(i).value(); } return ret; } @@ -933,58 +959,102 @@ QStringList CppParser::stringListifyNamespace(const NamespaceList &namespaces) { QStringList ret; for (int i = 1; i < namespaces.count(); ++i) - ret << namespaces.at(i)->name; + ret << namespaces.at(i).value(); return ret; } -// This function is called only with known-existing namespaces -NamespaceList CppParser::resolveNamespaces(const QStringList &segments) +bool CppParser::visitNamespace(const NamespaceList &namespaces, int nsCount, + VisitNamespaceCallback callback, void *context, + VisitRecorder &vr, const ParseResults *rslt) const { - NamespaceList ret; - Namespace *ns = &results->rootNamespace; - ret << ns; - foreach (const QString &seg, segments) { - ns = ns->children.value(seg); - ret << ns; - } + const Namespace *ns = &rslt->rootNamespace; + for (int i = 1; i < nsCount; ++i) + if (!(ns = ns->children.value(namespaces.at(i)))) + goto supers; + if ((this->*callback)(ns, context)) + return true; +supers: + foreach (const ParseResults *sup, rslt->includes) + if (vr.tryVisit(sup->fileId) + && visitNamespace(namespaces, nsCount, callback, context, vr, sup)) + return true; + return false; +} + +bool CppParser::visitNamespace(const NamespaceList &namespaces, int nsCount, + VisitNamespaceCallback callback, void *context) const +{ + VisitRecorder vr; + return visitNamespace(namespaces, nsCount, callback, context, vr, results); +} + +QStringList CppParser::stringListifySegments(const QList &segments) +{ + QStringList ret; + for (int i = 0; i < segments.count(); ++i) + ret << segments.at(i).value(); return ret; } -bool CppParser::qualifyOne(const NamespaceList &namespaces, int nsIdx, const QString &segment, - NamespaceList *resolved) +struct QualifyOneData { + const NamespaceList &namespaces; + int nsCount; + const HashString &segment; + NamespaceList *resolved; + QSet visitedUsings; +}; + +bool CppParser::qualifyOneCallbackOwn(const Namespace *ns, void *context) const { - const Namespace *ns = namespaces.at(nsIdx); - QMap::ConstIterator cnsi = ns->children.constFind(segment); - if (cnsi != ns->children.constEnd()) { - *resolved = namespaces.mid(0, nsIdx + 1); - *resolved << *cnsi; + QualifyOneData *data = (QualifyOneData *)context; + if (ns->children.contains(data->segment)) { + *data->resolved = data->namespaces.mid(0, data->nsCount); + *data->resolved << data->segment; return true; } - QMap::ConstIterator nsai = ns->aliases.constFind(segment); + QHash::ConstIterator nsai = ns->aliases.constFind(data->segment); if (nsai != ns->aliases.constEnd()) { - *resolved = resolveNamespaces(*nsai); + *data->resolved = *nsai; return true; } - foreach (const QStringList &use, ns->usings) { - NamespaceList usedNs = resolveNamespaces(use); - if (qualifyOne(usedNs, usedNs.count() - 1, segment, resolved)) - return true; - } return false; } -bool CppParser::fullyQualify(const NamespaceList &namespaces, const QStringList &segments, +bool CppParser::qualifyOneCallbackUsing(const Namespace *ns, void *context) const +{ + QualifyOneData *data = (QualifyOneData *)context; + foreach (const HashStringList &use, ns->usings) + if (!data->visitedUsings.contains(use)) { + data->visitedUsings.insert(use); + if (qualifyOne(use.value(), use.value().count(), data->segment, data->resolved)) + return true; + } + return false; +} + +bool CppParser::qualifyOne(const NamespaceList &namespaces, int nsCnt, const HashString &segment, + NamespaceList *resolved) const +{ + QualifyOneData data = { namespaces, nsCnt, segment, resolved, QSet() }; + + if (visitNamespace(namespaces, nsCnt, &CppParser::qualifyOneCallbackOwn, &data)) + return true; + + return visitNamespace(namespaces, nsCnt, &CppParser::qualifyOneCallbackUsing, &data); +} + +bool CppParser::fullyQualify(const NamespaceList &namespaces, const QList &segments, bool isDeclaration, - NamespaceList *resolved, QStringList *unresolved) + NamespaceList *resolved, QStringList *unresolved) const { int nsIdx; int initSegIdx; - if (segments.first().isEmpty()) { + if (segments.first().value().isEmpty()) { // fully qualified if (segments.count() == 1) { resolved->clear(); - *resolved << &results->rootNamespace; + *resolved << HashString(QString()); return true; } initSegIdx = 1; @@ -995,12 +1065,12 @@ bool CppParser::fullyQualify(const NamespaceList &namespaces, const QStringList } do { - if (qualifyOne(namespaces, nsIdx, segments[initSegIdx], resolved)) { + if (qualifyOne(namespaces, nsIdx + 1, segments[initSegIdx], resolved)) { int segIdx = initSegIdx; while (++segIdx < segments.count()) { - if (!qualifyOne(*resolved, resolved->count() - 1, segments[segIdx], resolved)) { + if (!qualifyOne(*resolved, resolved->count(), segments[segIdx], resolved)) { if (unresolved) - *unresolved = segments.mid(segIdx); + *unresolved = stringListifySegments(segments.mid(segIdx)); return false; } } @@ -1008,23 +1078,47 @@ bool CppParser::fullyQualify(const NamespaceList &namespaces, const QStringList } } while (!isDeclaration && --nsIdx >= 0); resolved->clear(); - *resolved << &results->rootNamespace; + *resolved << HashString(QString()); if (unresolved) - *unresolved = segments.mid(initSegIdx); + *unresolved = stringListifySegments(segments.mid(initSegIdx)); return false; } -void CppParser::enterNamespace(NamespaceList *namespaces, const QString &name) +bool CppParser::fullyQualify(const NamespaceList &namespaces, const QString &quali, + bool isDeclaration, + NamespaceList *resolved, QStringList *unresolved) const +{ + static QString strColons(QLatin1String("::")); + + QList segments; + foreach (const QString &str, quali.split(strColons)) // XXX slow, but needs to be fast(?) + segments << HashString(str); + return fullyQualify(namespaces, segments, isDeclaration, resolved, unresolved); +} + +bool CppParser::findNamespaceCallback(const Namespace *ns, void *context) const { - Namespace *ns = namespaces->last()->children.value(name); - if (!ns) { - ns = new Namespace; - ns->fileId = results->rootNamespace.fileId; - ns->name = name; - modifyNamespace(namespaces); - namespaces->last()->children[name] = ns; + *((const Namespace **)context) = ns; + return true; +} + +const Namespace *CppParser::findNamespace(const NamespaceList &namespaces, int nsCount) const +{ + const Namespace *ns = 0; + if (nsCount == -1) + nsCount = namespaces.count(); + visitNamespace(namespaces, nsCount, &CppParser::findNamespaceCallback, &ns); + return ns; +} + +void CppParser::enterNamespace(NamespaceList *namespaces, const HashString &name, bool isClass) +{ + *namespaces << name; + if (!findNamespace(*namespaces)) { + Namespace *ns = modifyNamespace(namespaces, false); + if (isClass) + ns->classDef = ns; } - *namespaces << ns; } void CppParser::truncateNamespaces(NamespaceList *namespaces, int length) @@ -1056,8 +1150,9 @@ const ParseResults *CppFiles::getResults(const QString &cleanFile) return parsedFiles().value(cleanFile); } -void CppFiles::setResults(const QString &cleanFile, const ParseResults *results) +void CppFiles::setResults(const QString &cleanFile, ParseResults *results) { + results->fileId = nextFileId++; parsedFiles().insert(cleanFile, results); } @@ -1093,12 +1188,8 @@ void CppParser::processInclude(const QString &file, ConversionData &cd, QString fileExt = QFileInfo(cleanFile).suffix(); if (fileExt.isEmpty() || fileExt.startsWith(QLatin1Char('h'), Qt::CaseInsensitive)) { - if (results->allIncludes.contains(cleanFile)) - return; - results->allIncludes.insert(cleanFile); - if (const ParseResults *res = CppFiles::getResults(cleanFile)) { - results->unite(res); + results->includes.insert(res); return; } @@ -1128,8 +1219,8 @@ void CppParser::processInclude(const QString &file, ConversionData &cd, } parser.setInput(ts, cleanFile); parser.parse(cd.m_defaultContext, cd, inclusions); - CppFiles::setResults(cleanFile, parser.getResults()); - results->unite(parser.results); + CppFiles::setResults(cleanFile, parser.results); + results->includes.insert(parser.results); } else { CppParser parser(results); parser.namespaces = namespaces; @@ -1138,12 +1229,6 @@ void CppParser::processInclude(const QString &file, ConversionData &cd, parser.pendingContext = pendingContext; parser.setInput(ts, cleanFile); parser.parseInternal(cd, inclusions); - // Don't wreak havoc if not enough braces were found. - truncateNamespaces(&parser.namespaces, namespaces.count()); - truncateNamespaces(&parser.functionContext, functionContext.count()); - // Copy them back - the pointers might have changed. - namespaces = parser.namespaces; - functionContext = parser.functionContext; // Avoid that messages obtained by direct scanning are used CppFiles::setBlacklisted(cleanFile); } @@ -1330,7 +1415,7 @@ void CppParser::parse(const QString &initialContext, ConversionData &cd, if (results->tor) yyCodecIsUtf8 = (results->tor->codecName() == "UTF-8"); - namespaces << &results->rootNamespace; + namespaces << HashString(); functionContext = namespaces; functionContextUnresolved = initialContext; @@ -1405,8 +1490,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) */ yyTok = getToken(); if (yyBraceDepth == namespaceDepths.count() && yyParenDepth == 0) { - QStringList quali; - QString fct; + QList quali; + HashString fct; do { /* This code should execute only once, but we play @@ -1414,8 +1499,9 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) 'class Q_EXPORT QMessageBox', in which case 'QMessageBox' is the class name, not 'Q_EXPORT'. */ - fct = yyWord; - fct.detach(); + text = yyWord; + text.detach(); + fct.setValue(text); yyTok = getToken(); } while (yyTok == Tok_Ident); while (yyTok == Tok_ColonColon) { @@ -1423,8 +1509,9 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) if (yyTok != Tok_Ident) break; // Oops ... quali << fct; - fct = yyWord; - fct.detach(); + text = yyWord; + text.detach(); + fct.setValue(text); yyTok = getToken(); } while (yyTok == Tok_Comment) @@ -1456,8 +1543,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) } else { namespaceDepths.push(namespaces.count()); } - enterNamespace(&namespaces, fct); - namespaces.last()->isClass = true; + enterNamespace(&namespaces, fct, true); functionContext = namespaces; functionContextUnresolved.clear(); // Pointless @@ -1469,34 +1555,33 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) yyTokColonSeen = false; yyTok = getToken(); if (yyTok == Tok_Ident) { - QString ns = yyWord; - ns.detach(); + text = yyWord; + text.detach(); + HashString ns = HashString(text); yyTok = getToken(); if (yyTok == Tok_LeftBrace) { namespaceDepths.push(namespaces.count()); - enterNamespace(&namespaces, ns); + enterNamespace(&namespaces, ns, false); yyTok = getToken(); } else if (yyTok == Tok_Equals) { // e.g. namespace Is = OuterSpace::InnerSpace; - QStringList fullName; + QList fullName; yyTok = getToken(); if (yyTok == Tok_ColonColon) - fullName.append(QString()); + fullName.append(HashString(QString())); while (yyTok == Tok_ColonColon || yyTok == Tok_Ident) { if (yyTok == Tok_Ident) { text = yyWord; text.detach(); - fullName.append(text); + fullName.append(HashString(text)); } yyTok = getToken(); } if (fullName.isEmpty()) break; NamespaceList nsl; - if (fullyQualify(namespaces, fullName, false, &nsl, 0)) { - modifyNamespace(&namespaces); - namespaces.last()->aliases.insert(ns, stringListifyNamespace(nsl)); - } + if (fullyQualify(namespaces, fullName, false, &nsl, 0)) + modifyNamespace(&namespaces, false)->aliases[ns] = nsl; } } else if (yyTok == Tok_LeftBrace) { // Anonymous namespace @@ -1506,43 +1591,40 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) break; case Tok_using: yyTok = getToken(); + // XXX this should affect only the current scope, not the entire current namespace if (yyTok == Tok_namespace) { - QStringList fullName; + QList fullName; yyTok = getToken(); if (yyTok == Tok_ColonColon) - fullName.append(QString()); + fullName.append(HashString(QString())); while (yyTok == Tok_ColonColon || yyTok == Tok_Ident) { if (yyTok == Tok_Ident) { text = yyWord; text.detach(); - fullName.append(text); + fullName.append(HashString(text)); } yyTok = getToken(); } NamespaceList nsl; - if (fullyQualify(namespaces, fullName, false, &nsl, 0)) { - modifyNamespace(&namespaces); - namespaces.last()->usings.insert(stringListifyNamespace(nsl)); - } + if (fullyQualify(namespaces, fullName, false, &nsl, 0)) + modifyNamespace(&namespaces, false)->usings << HashStringList(nsl); } else { - QStringList fullName; + QList fullName; if (yyTok == Tok_ColonColon) - fullName.append(QString()); + fullName.append(HashString(QString())); while (yyTok == Tok_ColonColon || yyTok == Tok_Ident) { if (yyTok == Tok_Ident) { text = yyWord; text.detach(); - fullName.append(text); + fullName.append(HashString(text)); } yyTok = getToken(); } if (fullName.isEmpty()) break; NamespaceList nsl; - if (fullyQualify(namespaces, fullName, false, &nsl, 0)) { - modifyNamespace(&namespaces); - namespaces.last()->aliases.insert(nsl.last()->name, stringListifyNamespace(nsl)); - } + if (fullyQualify(namespaces, fullName, false, &nsl, 0)) + modifyNamespace(&namespaces, true)->aliases[nsl.last()] = nsl; } break; case Tok_tr: @@ -1570,8 +1652,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) } if (!pendingContext.isEmpty()) { QStringList unresolved; - if (!fullyQualify(namespaces, pendingContext.split(strColons), true, - &functionContext, &unresolved)) { + if (!fullyQualify(namespaces, pendingContext, true, &functionContext, &unresolved)) { functionContextUnresolved = unresolved.join(strColons); qWarning("%s:%d: Qualifying with unknown namespace/class %s::%s\n", qPrintable(yyFileName), yyLineNo, @@ -1588,14 +1669,15 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) qPrintable(yyFileName), yyLineNo); break; } - while (!functionContext.at(idx - 1)->hasTrFunctions) { - if (idx == 1 || !functionContext.at(idx - 2)->isClass) { + while (!findNamespace(functionContext, idx)->classDef->hasTrFunctions) { + if (idx == 1 || !findNamespace(functionContext, idx - 1)->classDef) { context = stringifyNamespace(functionContext); - if (!functionContext.last()->complained) { + Namespace *fctx = findNamespace(functionContext)->classDef; + if (!fctx->complained) { qWarning("%s:%d: Class '%s' lacks Q_OBJECT macro\n", qPrintable(yyFileName), yyLineNo, qPrintable(context)); - functionContext.last()->complained = true; + fctx->complained = true; } goto gotctx; } @@ -1603,7 +1685,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) } context.clear(); for (int i = 1;;) { - context += functionContext.at(i)->name; + context += functionContext.at(i).value(); if (++i == idx) break; context += strColons; @@ -1625,13 +1707,14 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) prefix.chop(2); NamespaceList nsl; QStringList unresolved; - if (fullyQualify(functionContext, prefix.split(strColons), false, &nsl, &unresolved)) { + if (fullyQualify(functionContext, prefix, false, &nsl, &unresolved)) { context = stringifyNamespace(nsl); - if (!nsl.last()->hasTrFunctions && !nsl.last()->complained) { + Namespace *fctx = findNamespace(nsl)->classDef; + if (!fctx->hasTrFunctions && !fctx->complained) { qWarning("%s:%d: Class '%s' lacks Q_OBJECT macro\n", qPrintable(yyFileName), yyLineNo, qPrintable(context)); - nsl.last()->complained = true; + fctx->complained = true; } } else { context = (stringListifyNamespace(nsl) + unresolved).join(strColons); @@ -1727,7 +1810,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) break; case Tok_Q_DECLARE_TR_FUNCTIONS: case Tok_Q_OBJECT: - namespaces.last()->hasTrFunctions = true; + modifyNamespace(&namespaces, true)->hasTrFunctions = true; yyTok = getToken(); break; case Tok_Ident: -- cgit v0.12 From 158a48e06134845a72dcab14452390641747d211 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 22 Sep 2009 20:26:24 +0200 Subject: namespaces *can* have tr() functions, after all ... by virtue of the Q_DECLARE_TR_FUNCTIONS macro. so remove the artificial limitation to classes (which was mostly an optimization anyway). --- tools/linguist/lupdate/cpp.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index c9b25f3..81623ab 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -117,7 +117,7 @@ typedef QList NamespaceList; struct Namespace { Namespace() : - classDef(0), + classDef(this), hasTrFunctions(false), complained(false) {} @@ -260,7 +260,7 @@ private: NamespaceList *resolved, QStringList *unresolved) const; bool findNamespaceCallback(const Namespace *ns, void *context) const; const Namespace *findNamespace(const NamespaceList &namespaces, int nsCount = -1) const; - void enterNamespace(NamespaceList *namespaces, const HashString &name, bool isClass); + void enterNamespace(NamespaceList *namespaces, const HashString &name); void truncateNamespaces(NamespaceList *namespaces, int lenght); Namespace *modifyNamespace(NamespaceList *namespaces, bool tryOrigin = true); @@ -1111,14 +1111,11 @@ const Namespace *CppParser::findNamespace(const NamespaceList &namespaces, int n return ns; } -void CppParser::enterNamespace(NamespaceList *namespaces, const HashString &name, bool isClass) +void CppParser::enterNamespace(NamespaceList *namespaces, const HashString &name) { *namespaces << name; - if (!findNamespace(*namespaces)) { - Namespace *ns = modifyNamespace(namespaces, false); - if (isClass) - ns->classDef = ns; - } + if (!findNamespace(*namespaces)) + modifyNamespace(namespaces, false); } void CppParser::truncateNamespaces(NamespaceList *namespaces, int length) @@ -1543,7 +1540,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) } else { namespaceDepths.push(namespaces.count()); } - enterNamespace(&namespaces, fct, true); + enterNamespace(&namespaces, fct); functionContext = namespaces; functionContextUnresolved.clear(); // Pointless @@ -1561,7 +1558,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) yyTok = getToken(); if (yyTok == Tok_LeftBrace) { namespaceDepths.push(namespaces.count()); - enterNamespace(&namespaces, ns, false); + enterNamespace(&namespaces, ns); yyTok = getToken(); } else if (yyTok == Tok_Equals) { // e.g. namespace Is = OuterSpace::InnerSpace; @@ -1670,7 +1667,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) break; } while (!findNamespace(functionContext, idx)->classDef->hasTrFunctions) { - if (idx == 1 || !findNamespace(functionContext, idx - 1)->classDef) { + if (idx == 1) { context = stringifyNamespace(functionContext); Namespace *fctx = findNamespace(functionContext)->classDef; if (!fctx->complained) { -- cgit v0.12 From 178945342d0d46ddde460f230c22d2acb9f930a8 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 22 Sep 2009 20:27:26 +0200 Subject: actually use the argument of Q_DECLARE_TR_FUNCTIONS which means that one can set an arbitrary context. as a side effect, this caches the stringified context of Q_OBJECT-derived classes. --- .../lupdate/testdata/good/parsecontexts/main.cpp | 9 +++ .../testdata/good/parsecontexts/project.ts.result | 9 +++ tools/linguist/lupdate/cpp.cpp | 68 +++++++++++++++++++--- 3 files changed, 77 insertions(+), 9 deletions(-) diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecontexts/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecontexts/main.cpp index 7e81b84..25c2c0d 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecontexts/main.cpp +++ b/tests/auto/linguist/lupdate/testdata/good/parsecontexts/main.cpp @@ -262,6 +262,15 @@ QString C2::foo() } +namespace Fooish { + Q_DECLARE_TR_FUNCTIONS(Bears::And::Spiders) +} + +void Fooish::bar() +{ + return tr("whatever the context", "Bears::And::Spiders"); +} + int main(int /*argc*/, char ** /*argv*/) { return 0; diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.ts.result index 9b00d53..2f21de2 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.ts.result +++ b/tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.ts.result @@ -102,6 +102,15 @@ + Bears::And::Spiders + + + whatever the context + Bears::And::Spiders + + + + C1 diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index 81623ab..44a8feb 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -133,6 +133,8 @@ struct Namespace { // definition (either one in case of multiple definitions). Namespace *classDef; + QString trQualification; + bool hasTrFunctions; bool complained; // ... that tr functions are missing. }; @@ -221,6 +223,7 @@ private: uint getChar(); uint getToken(); + bool getMacroArgs(); bool match(uint t); bool matchString(QString *s); bool matchEncoding(bool *utf8); @@ -416,6 +419,34 @@ uint CppParser::getChar() } } +// This ignores commas, parens and comments. +// IOW, it understands only a single, simple argument. +bool CppParser::getMacroArgs() +{ + // Failing this assertion would mean losing the preallocated buffer. + Q_ASSERT(yyWord.isDetached()); + yyWord.resize(0); + + while (isspace(yyCh)) + yyCh = getChar(); + if (yyCh != '(') + return false; + do { + yyCh = getChar(); + } while (isspace(yyCh)); + ushort *ptr = (ushort *)yyWord.unicode(); + while (yyCh != ')') { + if (yyCh == EOF) + return false; + *ptr++ = yyCh; + yyCh = getChar(); + } + yyCh = getChar(); + for (; ptr != (ushort *)yyWord.unicode() && isspace(*(ptr - 1)); --ptr) ; + yyWord.resize(ptr - (ushort *)yyWord.unicode()); + return true; +} + STRING(Q_OBJECT); STRING(Q_DECLARE_TR_FUNCTIONS); STRING(QT_TR_NOOP); @@ -1666,10 +1697,11 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) qPrintable(yyFileName), yyLineNo); break; } - while (!findNamespace(functionContext, idx)->classDef->hasTrFunctions) { + Namespace *fctx; + while (!(fctx = findNamespace(functionContext, idx)->classDef)->hasTrFunctions) { if (idx == 1) { context = stringifyNamespace(functionContext); - Namespace *fctx = findNamespace(functionContext)->classDef; + fctx = findNamespace(functionContext)->classDef; if (!fctx->complained) { qWarning("%s:%d: Class '%s' lacks Q_OBJECT macro\n", qPrintable(yyFileName), yyLineNo, @@ -1680,12 +1712,17 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) } --idx; } - context.clear(); - for (int i = 1;;) { - context += functionContext.at(i).value(); - if (++i == idx) - break; - context += strColons; + if (fctx->trQualification.isEmpty()) { + context.clear(); + for (int i = 1;;) { + context += functionContext.at(i).value(); + if (++i == idx) + break; + context += strColons; + } + fctx->trQualification = context; + } else { + context = fctx->trQualification; } } else { context = (stringListifyNamespace(functionContext) @@ -1705,8 +1742,13 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) NamespaceList nsl; QStringList unresolved; if (fullyQualify(functionContext, prefix, false, &nsl, &unresolved)) { - context = stringifyNamespace(nsl); Namespace *fctx = findNamespace(nsl)->classDef; + if (fctx->trQualification.isEmpty()) { + context = stringifyNamespace(nsl); + fctx->trQualification = context; + } else { + context = fctx->trQualification; + } if (!fctx->hasTrFunctions && !fctx->complained) { qWarning("%s:%d: Class '%s' lacks Q_OBJECT macro\n", qPrintable(yyFileName), yyLineNo, @@ -1806,6 +1848,14 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) extra.clear(); break; case Tok_Q_DECLARE_TR_FUNCTIONS: + if (getMacroArgs()) { + Namespace *ns = modifyNamespace(&namespaces, true); + ns->hasTrFunctions = true; + ns->trQualification = yyWord; + ns->trQualification.detach(); + } + yyTok = getToken(); + break; case Tok_Q_OBJECT: modifyNamespace(&namespaces, true)->hasTrFunctions = true; yyTok = getToken(); -- cgit v0.12 From 0040d5a582b7fb7e9719d7c04c8de272e2a1389d Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 23 Sep 2009 14:59:04 +0200 Subject: reduce peak memory consumption drop the parse results of files which are unlikely to be included (i.e., which are not headers). --- tools/linguist/lupdate/cpp.cpp | 100 ++++++++++++++++++++++++++++------------- 1 file changed, 70 insertions(+), 30 deletions(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index 44a8feb..0a710e2 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -120,6 +120,10 @@ struct Namespace { classDef(this), hasTrFunctions(false), complained(false) {} + ~Namespace() + { + qDeleteAll(children); + } QHash children; QHash aliases; @@ -159,30 +163,27 @@ private: }; struct ParseResults { - - ParseResults() - { - tor = 0; - } - int fileId; Namespace rootNamespace; - Translator *tor; QSet includes; }; typedef QHash ParseResultHash; +typedef QHash TranslatorHash; class CppFiles { public: static const ParseResults *getResults(const QString &cleanFile); static void setResults(const QString &cleanFile, ParseResults *results); + static const Translator *getTranslator(const QString &cleanFile); + static void setTranslator(const QString &cleanFile, const Translator *results); static bool isBlacklisted(const QString &cleanFile); static void setBlacklisted(const QString &cleanFile); private: static ParseResultHash &parsedFiles(); + static TranslatorHash &translatedFiles(); static QSet &blacklistedFiles(); }; @@ -192,10 +193,10 @@ public: CppParser(ParseResults *results = 0); void setInput(const QString &in); void setInput(QTextStream &ts, const QString &fileName); - void setTranslator(Translator *tor) { results->tor = tor; } + void setTranslator(Translator *_tor) { tor = _tor; } void parse(const QString &initialContext, ConversionData &cd, QSet &inclusions); void parseInternal(ConversionData &cd, QSet &inclusions); - ParseResults *getResults() const { return results; } + const ParseResults *recordResults(bool isHeader); void deleteResults() { delete results; } struct SavedState { @@ -311,6 +312,7 @@ private: QString prospectiveContext; QString pendingContext; ParseResults *results; + Translator *tor; bool directInclude; SavedState savedState; @@ -320,6 +322,7 @@ private: CppParser::CppParser(ParseResults *_results) { + tor = 0; if (_results) { results = _results; directInclude = true; @@ -1166,6 +1169,13 @@ ParseResultHash &CppFiles::parsedFiles() return parsed; } +TranslatorHash &CppFiles::translatedFiles() +{ + static TranslatorHash tors; + + return tors; +} + QSet &CppFiles::blacklistedFiles() { static QSet blacklisted; @@ -1184,6 +1194,16 @@ void CppFiles::setResults(const QString &cleanFile, ParseResults *results) parsedFiles().insert(cleanFile, results); } +const Translator *CppFiles::getTranslator(const QString &cleanFile) +{ + return translatedFiles().value(cleanFile); +} + +void CppFiles::setTranslator(const QString &cleanFile, const Translator *tor) +{ + translatedFiles().insert(cleanFile, tor); +} + bool CppFiles::isBlacklisted(const QString &cleanFile) { return blacklistedFiles().contains(cleanFile); @@ -1194,6 +1214,12 @@ void CppFiles::setBlacklisted(const QString &cleanFile) blacklistedFiles().insert(cleanFile); } +static bool isHeader(const QString &name) +{ + QString fileExt = QFileInfo(name).suffix(); + return fileExt.isEmpty() || fileExt.startsWith(QLatin1Char('h'), Qt::CaseInsensitive); +} + void CppParser::processInclude(const QString &file, ConversionData &cd, QSet &inclusions) { @@ -1212,17 +1238,15 @@ void CppParser::processInclude(const QString &file, ConversionData &cd, bool isIndirect = false; if (namespaces.count() == 1 && functionContext.count() == 1 && functionContextUnresolved.isEmpty() && pendingContext.isEmpty() - && !CppFiles::isBlacklisted(cleanFile)) { - QString fileExt = QFileInfo(cleanFile).suffix(); - if (fileExt.isEmpty() || fileExt.startsWith(QLatin1Char('h'), Qt::CaseInsensitive)) { - - if (const ParseResults *res = CppFiles::getResults(cleanFile)) { - results->includes.insert(res); - return; - } + && !CppFiles::isBlacklisted(cleanFile) + && isHeader(cleanFile)) { - isIndirect = true; + if (const ParseResults *res = CppFiles::getResults(cleanFile)) { + results->includes.insert(res); + return; } + + isIndirect = true; } QFile f(cleanFile); @@ -1247,8 +1271,7 @@ void CppParser::processInclude(const QString &file, ConversionData &cd, } parser.setInput(ts, cleanFile); parser.parse(cd.m_defaultContext, cd, inclusions); - CppFiles::setResults(cleanFile, parser.results); - results->includes.insert(parser.results); + results->includes.insert(parser.recordResults(true)); } else { CppParser parser(results); parser.namespaces = namespaces; @@ -1434,14 +1457,14 @@ void CppParser::recordMessage( msg.setExtras(extra); if ((utf8 || yyForceUtf8) && !yyCodecIsUtf8 && msg.needs8Bit()) msg.setUtf8(true); - results->tor->append(msg); + tor->append(msg); } void CppParser::parse(const QString &initialContext, ConversionData &cd, QSet &inclusions) { - if (results->tor) - yyCodecIsUtf8 = (results->tor->codecName() == "UTF-8"); + if (tor) + yyCodecIsUtf8 = (tor->codecName() == "UTF-8"); namespaces << HashString(); functionContext = namespaces; @@ -1657,7 +1680,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) break; case Tok_tr: case Tok_trUtf8: - if (!results->tor) + if (!tor) goto case_default; if (!sourcetext.isEmpty()) qWarning("%s:%d: //%% cannot be used with tr() / QT_TR_NOOP(). Ignoring\n", @@ -1770,7 +1793,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) break; case Tok_translateUtf8: case Tok_translate: - if (!results->tor) + if (!tor) goto case_default; if (!sourcetext.isEmpty()) qWarning("%s:%d: //%% cannot be used with translate() / QT_TRANSLATE_NOOP(). Ignoring\n", @@ -1825,7 +1848,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) extra.clear(); break; case Tok_trid: - if (!results->tor) + if (!tor) goto case_default; if (sourcetext.isEmpty()) { yyTok = getToken(); @@ -1871,7 +1894,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) } break; case Tok_Comment: - if (!results->tor) + if (!tor) goto case_default; if (yyWord.startsWith(QLatin1Char(':'))) { yyWord.remove(0, 1); @@ -1944,7 +1967,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) recordMessage(yyLineNo, context, QString(), comment, extracomment, QString(), TranslatorMessage::ExtraData(), false, false); extracomment.clear(); - results->tor->setExtras(extra); + tor->setExtras(extra); extra.clear(); } } @@ -2029,6 +2052,23 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) qPrintable(yyFileName), yyParenLineNo); } +const ParseResults *CppParser::recordResults(bool isHeader) +{ + if (tor) { + if (tor->messageCount()) + CppFiles::setTranslator(yyFileName, tor); + else + delete tor; + } + if (isHeader) { + CppFiles::setResults(yyFileName, results); + return results; + } else { + delete results; + return 0; + } +} + /* Fetches tr() calls in C++ code in UI files (inside "" tag). This mechanism is obsolete. @@ -2073,12 +2113,12 @@ void loadCPP(Translator &translator, const QStringList &filenames, ConversionDat parser.setTranslator(tor); QSet inclusions; parser.parse(cd.m_defaultContext, cd, inclusions); - CppFiles::setResults(filename, parser.getResults()); + parser.recordResults(isHeader(filename)); } foreach (const QString &filename, filenames) if (!CppFiles::isBlacklisted(filename)) - if (Translator *tor = CppFiles::getResults(filename)->tor) + if (const Translator *tor = CppFiles::getTranslator(filename)) foreach (const TranslatorMessage &msg, tor->messages()) translator.extend(msg); } -- cgit v0.12 From b9fd3e2836553dbe9c48c5d8784155b02a5699a2 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 23 Sep 2009 15:17:32 +0200 Subject: detect and eliminate forwarding headers this will save quite some hash lookups (even if in empty hashes) and make the VisitRecorder bitmap smaller. --- tools/linguist/lupdate/cpp.cpp | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index 0a710e2..ed41edb 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -175,7 +175,7 @@ class CppFiles { public: static const ParseResults *getResults(const QString &cleanFile); - static void setResults(const QString &cleanFile, ParseResults *results); + static void setResults(const QString &cleanFile, const ParseResults *results); static const Translator *getTranslator(const QString &cleanFile); static void setTranslator(const QString &cleanFile, const Translator *results); static bool isBlacklisted(const QString &cleanFile); @@ -1188,9 +1188,8 @@ const ParseResults *CppFiles::getResults(const QString &cleanFile) return parsedFiles().value(cleanFile); } -void CppFiles::setResults(const QString &cleanFile, ParseResults *results) +void CppFiles::setResults(const QString &cleanFile, const ParseResults *results) { - results->fileId = nextFileId++; parsedFiles().insert(cleanFile, results); } @@ -2055,14 +2054,28 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) const ParseResults *CppParser::recordResults(bool isHeader) { if (tor) { - if (tor->messageCount()) + if (tor->messageCount()) { CppFiles::setTranslator(yyFileName, tor); - else + } else { delete tor; + tor = 0; + } } if (isHeader) { - CppFiles::setResults(yyFileName, results); - return results; + const ParseResults *pr; + if (!tor && results->includes.count() == 1 + && results->rootNamespace.children.isEmpty() + && results->rootNamespace.aliases.isEmpty() + && results->rootNamespace.usings.isEmpty()) { + // This is a forwarding header. Slash it. + pr = *results->includes.begin(); + delete results; + } else { + results->fileId = nextFileId++; + pr = results; + } + CppFiles::setResults(yyFileName, pr); + return pr; } else { delete results; return 0; -- cgit v0.12 From 9d552fbf54a25b4bab7fff8a150ab0d03d524983 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 23 Sep 2009 15:30:24 +0200 Subject: Small change in the API of animations We're not taking a parameter in updateCurrentTime any more because that parameter was the total currenttime. So it was taking into account the currenttime and the currentloop at once. This was inconsistent Reviewed-by: Leo --- examples/animation/easing/animation.h | 4 ++-- src/corelib/animation/qabstractanimation.cpp | 18 +++++++++--------- src/corelib/animation/qabstractanimation.h | 2 +- src/corelib/animation/qparallelanimationgroup.cpp | 2 +- src/corelib/animation/qparallelanimationgroup.h | 2 +- src/corelib/animation/qpauseanimation.cpp | 3 +-- src/corelib/animation/qpauseanimation.h | 2 +- src/corelib/animation/qsequentialanimationgroup.cpp | 16 ++++++---------- src/corelib/animation/qsequentialanimationgroup.h | 2 +- src/corelib/animation/qsequentialanimationgroup_p.h | 2 +- src/corelib/animation/qvariantanimation.cpp | 3 +-- src/corelib/animation/qvariantanimation.h | 2 +- .../tst_qsequentialanimationgroup.cpp | 6 +++--- tests/benchmarks/qanimation/rectanimation.cpp | 4 ++-- tests/benchmarks/qanimation/rectanimation.h | 2 +- 15 files changed, 32 insertions(+), 38 deletions(-) diff --git a/examples/animation/easing/animation.h b/examples/animation/easing/animation.h index 45a7b17..78fdc14 100644 --- a/examples/animation/easing/animation.h +++ b/examples/animation/easing/animation.h @@ -68,7 +68,7 @@ public: m_path = QPainterPath(); } - void updateCurrentTime(int msecs) + void updateCurrentTime() { if (m_pathType == CirclePath) { if (m_path.isEmpty()) { @@ -90,7 +90,7 @@ public: updateCurrentValue(pt); emit valueChanged(pt); } else { - QPropertyAnimation::updateCurrentTime(msecs); + QPropertyAnimation::updateCurrentTime(); } } diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 6306882..9027be0 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -81,12 +81,12 @@ QAbstractAnimation provides pure virtual functions used by subclasses to track the progress of the animation: duration() and updateCurrentTime(). The duration() function lets you report a - duration for the animation (as discussed above). The current time - is delivered by the animation framework through calls to - updateCurrentTime(). By reimplementing this function, you can - track the animation progress. Note that neither the interval - between calls nor the number of calls to this function are - defined; though, it will normally be 60 updates per second. + duration for the animation (as discussed above). The animation + framework calls updateCurrentTime() when current time has changed. + By reimplementing this function, you can track the animation + progress. Note that neither the interval between calls nor the + number of calls to this function are defined; though, it will + normally be 60 updates per second. By reimplementing updateState(), you can track the animation's state changes, which is particularly useful for animations that @@ -604,7 +604,7 @@ void QAbstractAnimation::setCurrentTime(int msecs) } } - updateCurrentTime(msecs); + updateCurrentTime(); if (d->currentLoop != oldLoop) emit currentLoopChanged(d->currentLoop); @@ -705,10 +705,10 @@ bool QAbstractAnimation::event(QEvent *event) } /*! - \fn virtual void QAbstractAnimation::updateCurrentTime(int msecs) = 0; + \fn virtual void QAbstractAnimation::updateCurrentTime() = 0; This pure virtual function is called every time the animation's current - time changes. The \a msecs argument is the current time. + time changes. \sa updateState() */ diff --git a/src/corelib/animation/qabstractanimation.h b/src/corelib/animation/qabstractanimation.h index dc0af19..516f5e9 100644 --- a/src/corelib/animation/qabstractanimation.h +++ b/src/corelib/animation/qabstractanimation.h @@ -119,7 +119,7 @@ protected: QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent = 0); bool event(QEvent *event); - virtual void updateCurrentTime(int msecs) = 0; + virtual void updateCurrentTime() = 0; virtual void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); virtual void updateDirection(QAbstractAnimation::Direction direction); diff --git a/src/corelib/animation/qparallelanimationgroup.cpp b/src/corelib/animation/qparallelanimationgroup.cpp index 349090b..82d5224 100644 --- a/src/corelib/animation/qparallelanimationgroup.cpp +++ b/src/corelib/animation/qparallelanimationgroup.cpp @@ -125,7 +125,7 @@ int QParallelAnimationGroup::duration() const /*! \reimp */ -void QParallelAnimationGroup::updateCurrentTime(int) +void QParallelAnimationGroup::updateCurrentTime() { Q_D(QParallelAnimationGroup); if (d->animations.isEmpty()) diff --git a/src/corelib/animation/qparallelanimationgroup.h b/src/corelib/animation/qparallelanimationgroup.h index f013bc7..6afe4a7 100644 --- a/src/corelib/animation/qparallelanimationgroup.h +++ b/src/corelib/animation/qparallelanimationgroup.h @@ -67,7 +67,7 @@ protected: QParallelAnimationGroup(QParallelAnimationGroupPrivate &dd, QObject *parent); bool event(QEvent *event); - void updateCurrentTime(int msecs); + void updateCurrentTime(); void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); void updateDirection(QAbstractAnimation::Direction direction); diff --git a/src/corelib/animation/qpauseanimation.cpp b/src/corelib/animation/qpauseanimation.cpp index 8bfed08..c382b19 100644 --- a/src/corelib/animation/qpauseanimation.cpp +++ b/src/corelib/animation/qpauseanimation.cpp @@ -141,9 +141,8 @@ bool QPauseAnimation::event(QEvent *e) /*! \reimp */ -void QPauseAnimation::updateCurrentTime(int msecs) +void QPauseAnimation::updateCurrentTime() { - Q_UNUSED(msecs); } diff --git a/src/corelib/animation/qpauseanimation.h b/src/corelib/animation/qpauseanimation.h index 05eb3b3..caac9e9 100644 --- a/src/corelib/animation/qpauseanimation.h +++ b/src/corelib/animation/qpauseanimation.h @@ -68,7 +68,7 @@ public: protected: bool event(QEvent *e); - void updateCurrentTime(int msecs); + void updateCurrentTime(); private: Q_DISABLE_COPY(QPauseAnimation) diff --git a/src/corelib/animation/qsequentialanimationgroup.cpp b/src/corelib/animation/qsequentialanimationgroup.cpp index 53fc4f3..9ad433f 100644 --- a/src/corelib/animation/qsequentialanimationgroup.cpp +++ b/src/corelib/animation/qsequentialanimationgroup.cpp @@ -112,17 +112,13 @@ int QSequentialAnimationGroupPrivate::animationActualTotalDuration(int index) co return ret; } -QSequentialAnimationGroupPrivate::AnimationIndex QSequentialAnimationGroupPrivate::indexForTime(int msecs) const +QSequentialAnimationGroupPrivate::AnimationIndex QSequentialAnimationGroupPrivate::indexForCurrentTime() const { - Q_Q(const QSequentialAnimationGroup); Q_ASSERT(!animations.isEmpty()); AnimationIndex ret; int duration = 0; - // in case duration is -1, currentLoop will always be 0 - ret.timeOffset = currentLoop * q->duration(); - for (int i = 0; i < animations.size(); ++i) { duration = animationActualTotalDuration(i); @@ -131,8 +127,8 @@ QSequentialAnimationGroupPrivate::AnimationIndex QSequentialAnimationGroupPrivat // 2. it ends after msecs // 3. it is the last animation (this can happen in case there is at least 1 uncontrolled animation) // 4. it ends exactly in msecs and the direction is backwards - if (duration == -1 || msecs < (ret.timeOffset + duration) - || (msecs == (ret.timeOffset + duration) && direction == QAbstractAnimation::Backward)) { + if (duration == -1 || currentTime < (ret.timeOffset + duration) + || (currentTime == (ret.timeOffset + duration) && direction == QAbstractAnimation::Backward)) { ret.index = i; return ret; } @@ -338,13 +334,13 @@ int QSequentialAnimationGroup::duration() const /*! \reimp */ -void QSequentialAnimationGroup::updateCurrentTime(int msecs) +void QSequentialAnimationGroup::updateCurrentTime() { Q_D(QSequentialAnimationGroup); if (!d->currentAnimation) return; - const QSequentialAnimationGroupPrivate::AnimationIndex newAnimationIndex = d->indexForTime(msecs); + const QSequentialAnimationGroupPrivate::AnimationIndex newAnimationIndex = d->indexForCurrentTime(); // remove unneeded animations from actualDuration list while (newAnimationIndex.index < d->actualDuration.size()) @@ -363,7 +359,7 @@ void QSequentialAnimationGroup::updateCurrentTime(int msecs) d->setCurrentAnimation(newAnimationIndex.index); - const int newCurrentTime = msecs - newAnimationIndex.timeOffset; + const int newCurrentTime = d->currentTime - newAnimationIndex.timeOffset; if (d->currentAnimation) { d->currentAnimation->setCurrentTime(newCurrentTime); diff --git a/src/corelib/animation/qsequentialanimationgroup.h b/src/corelib/animation/qsequentialanimationgroup.h index e17e103..1c9e4cc 100644 --- a/src/corelib/animation/qsequentialanimationgroup.h +++ b/src/corelib/animation/qsequentialanimationgroup.h @@ -77,7 +77,7 @@ protected: QSequentialAnimationGroup(QSequentialAnimationGroupPrivate &dd, QObject *parent); bool event(QEvent *event); - void updateCurrentTime(int msecs); + void updateCurrentTime(); void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); void updateDirection(QAbstractAnimation::Direction direction); diff --git a/src/corelib/animation/qsequentialanimationgroup_p.h b/src/corelib/animation/qsequentialanimationgroup_p.h index 2e65cc0..ab41d35 100644 --- a/src/corelib/animation/qsequentialanimationgroup_p.h +++ b/src/corelib/animation/qsequentialanimationgroup_p.h @@ -79,7 +79,7 @@ public: }; int animationActualTotalDuration(int index) const; - AnimationIndex indexForTime(int msecs) const; + AnimationIndex indexForCurrentTime() const; void setCurrentAnimation(int index, bool intermediate = false); void activateCurrentAnimation(bool intermediate = false); diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp index c831a34..ae8bf2f 100644 --- a/src/corelib/animation/qvariantanimation.cpp +++ b/src/corelib/animation/qvariantanimation.cpp @@ -656,9 +656,8 @@ QVariant QVariantAnimation::interpolated(const QVariant &from, const QVariant &t /*! \reimp */ -void QVariantAnimation::updateCurrentTime(int msecs) +void QVariantAnimation::updateCurrentTime() { - Q_UNUSED(msecs); d_func()->recalculateCurrentInterval(); } diff --git a/src/corelib/animation/qvariantanimation.h b/src/corelib/animation/qvariantanimation.h index c803150..98c1aec 100644 --- a/src/corelib/animation/qvariantanimation.h +++ b/src/corelib/animation/qvariantanimation.h @@ -102,7 +102,7 @@ protected: QVariantAnimation(QVariantAnimationPrivate &dd, QObject *parent = 0); bool event(QEvent *event); - void updateCurrentTime(int msecs); + void updateCurrentTime(); void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); virtual void updateCurrentValue(const QVariant &value) = 0; diff --git a/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp b/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp index 209e68b..b14d6f8 100644 --- a/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp +++ b/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp @@ -169,10 +169,10 @@ public: int duration() const { return -1; /* not time driven */ } protected: - void updateCurrentTime(int msecs) + void updateCurrentTime() { - QPropertyAnimation::updateCurrentTime(msecs); - if (msecs >= QPropertyAnimation::duration()) + QPropertyAnimation::updateCurrentTime(); + if (currentTime() >= QPropertyAnimation::duration()) stop(); } }; diff --git a/tests/benchmarks/qanimation/rectanimation.cpp b/tests/benchmarks/qanimation/rectanimation.cpp index e5f2f57..5522847 100644 --- a/tests/benchmarks/qanimation/rectanimation.cpp +++ b/tests/benchmarks/qanimation/rectanimation.cpp @@ -73,9 +73,9 @@ int RectAnimation::duration() const } -void RectAnimation::updateCurrentTime(int msecs) +void RectAnimation::updateCurrentTime() { - qreal progress = m_easing.valueForProgress( qreal(msecs) / qreal(m_dura) ); + qreal progress = m_easing.valueForProgress( currentTime() / qreal(m_dura) ); QRect now; now.setCoords(interpolateInteger(m_start.left(), m_end.left(), progress), interpolateInteger(m_start.top(), m_end.top(), progress), diff --git a/tests/benchmarks/qanimation/rectanimation.h b/tests/benchmarks/qanimation/rectanimation.h index 84ec97d..995becb 100644 --- a/tests/benchmarks/qanimation/rectanimation.h +++ b/tests/benchmarks/qanimation/rectanimation.h @@ -58,7 +58,7 @@ public: void setDuration(int d); int duration() const; - virtual void updateCurrentTime(int msecs); + virtual void updateCurrentTime(); virtual void updateState(QAbstractAnimation::State state); private: -- cgit v0.12 From aed412fd14e39a356a886c5a472ceade3da56d13 Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Wed, 23 Sep 2009 15:50:49 +0200 Subject: Avoid calling ensureContext() in setGeometry. We can delay calling ensureContext() since it will happen when painting begins anyway. There is a chance that we can get to this function when a window is being hidden and if this is the first thing that happens in the application, there is no need to call ensureContext() yet. Reviewed-by: Rhys Weatherley --- src/openvg/qwindowsurface_vg.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/openvg/qwindowsurface_vg.cpp b/src/openvg/qwindowsurface_vg.cpp index 1997ee8..6cc2e27 100644 --- a/src/openvg/qwindowsurface_vg.cpp +++ b/src/openvg/qwindowsurface_vg.cpp @@ -85,7 +85,6 @@ void QVGWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoin void QVGWindowSurface::setGeometry(const QRect &rect) { QWindowSurface::setGeometry(rect); - d_ptr->ensureContext(window()); } bool QVGWindowSurface::scroll(const QRegion &area, int dx, int dy) -- cgit v0.12 From 77166549a95056a9e0ac78a1e2248c78406630a4 Mon Sep 17 00:00:00 2001 From: axis Date: Tue, 22 Sep 2009 13:48:38 +0200 Subject: Added support for using custom application objects on S60. With this patch, the application developer can use his own CEikApplication, CEikDocument and CEikAppUi classes with Qt, by deriving from QS60MainApplication, QSMainDocument and QS60MainAppUi, respectively. He can then register a factory function in the QApplication constructor to have his own objects created during the framework initialization. This patch also fixes some Qt code style issues. RevBy: Jason Barron RevBy: mread RevBy: Sami Merila RevBy: Shane Kearns --- .../snippets/code/src_corelib_global_qglobal.cpp | 3 + src/gui/kernel/qapplication.h | 14 ++ src/gui/kernel/qapplication_s60.cpp | 41 ++++- src/gui/kernel/qt_s60_p.h | 2 + src/gui/s60framework/qs60mainapplication.cpp | 81 ++++++--- src/gui/s60framework/qs60mainapplication.h | 79 +++++++++ src/gui/s60framework/qs60mainapplication_p.h | 58 +------ src/gui/s60framework/qs60mainappui.cpp | 181 ++++++++++++++------- src/gui/s60framework/qs60mainappui.h | 86 ++++++++++ src/gui/s60framework/qs60mainappui_p.h | 130 --------------- src/gui/s60framework/qs60maindocument.cpp | 99 +++++------ src/gui/s60framework/qs60maindocument.h | 80 +++++++++ src/gui/s60framework/qs60maindocument_p.h | 139 ---------------- src/gui/s60framework/s60framework.pri | 5 +- .../qs60mainapplication/qs60mainapplication.pro | 4 + .../tst_qs60mainapplication.cpp | 133 +++++++++++++++ 16 files changed, 666 insertions(+), 469 deletions(-) create mode 100644 src/gui/s60framework/qs60mainapplication.h create mode 100644 src/gui/s60framework/qs60mainappui.h delete mode 100644 src/gui/s60framework/qs60mainappui_p.h create mode 100644 src/gui/s60framework/qs60maindocument.h delete mode 100644 src/gui/s60framework/qs60maindocument_p.h create mode 100644 tests/auto/qs60mainapplication/qs60mainapplication.pro create mode 100644 tests/auto/qs60mainapplication/tst_qs60mainapplication.cpp diff --git a/doc/src/snippets/code/src_corelib_global_qglobal.cpp b/doc/src/snippets/code/src_corelib_global_qglobal.cpp index 3c61281..16b1073 100644 --- a/doc/src/snippets/code/src_corelib_global_qglobal.cpp +++ b/doc/src/snippets/code/src_corelib_global_qglobal.cpp @@ -529,3 +529,6 @@ class MyClass : public QObject qFuzzyCompare(1 + 0.0, 1 + 1.0e-200); // This will return true //! [46] +//! [47] +CApaApplication *myApplicationFactory(); +//! [47] diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h index 0562251..5f21a56 100644 --- a/src/gui/kernel/qapplication.h +++ b/src/gui/kernel/qapplication.h @@ -64,6 +64,9 @@ QT_BEGIN_HEADER #if defined(Q_OS_SYMBIAN) class TWsEvent; #endif +#if defined(Q_WS_S60) +class CApaApplication; +#endif QT_BEGIN_NAMESPACE @@ -114,6 +117,11 @@ class Q_GUI_EXPORT QApplication : public QCoreApplication public: enum Type { Tty, GuiClient, GuiServer }; + +#ifdef Q_WS_S60 + typedef CApaApplication * (*QS60MainApplicationFactory)(); +#endif + #ifndef qdoc QApplication(int &argc, char **argv, int = QT_VERSION); QApplication(int &argc, char **argv, bool GUIenabled, int = QT_VERSION); @@ -122,6 +130,9 @@ public: QApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE cmap = 0, int = QT_VERSION); QApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0, int = QT_VERSION); #endif +#if defined(Q_WS_S60) + QApplication(QApplication::QS60MainApplicationFactory factory, int &argc, char **argv, int = QT_VERSION); +#endif #endif virtual ~QApplication(); @@ -357,6 +368,9 @@ public: QApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE cmap = 0); QApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0); #endif +#if defined(Q_WS_S60) || defined(qdoc) + QApplication(QApplication::QS60MainApplicationFactory factory, int &argc, char **argv); +#endif #endif private: diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index a5d07fd..4ca9459 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -817,11 +817,50 @@ TTypeUid::Ptr QSymbianControl::MopSupplyObject(TTypeUid id) return CCoeControl::MopSupplyObject(id); } +/*! + \typedef QApplication::QS60MainApplicationFactory + + This is a typedef for a pointer to a function with the following + signature: + + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 47 + + \sa QApplication::QApplication(QApplication::QS60MainApplicationFactory, int &, char **) +*/ + +/*! + \since 4.6 + + Creates an application using the application factory given in + \a factory, and using \a argc command line arguments in \a argv. + \a factory can be leaving, but the error will be converted to a + standard exception. + + This function is only available on S60. +*/ +QApplication::QApplication(QApplication::QS60MainApplicationFactory factory, int &argc, char **argv) + : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient)) +{ + Q_D(QApplication); + S60->s60ApplicationFactory = factory; + d->construct(); +} + +QApplication::QApplication(QApplication::QS60MainApplicationFactory factory, int &argc, char **argv, int _internal) + : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient)) +{ + Q_D(QApplication); + S60->s60ApplicationFactory = factory; + d->construct(); + QApplicationPrivate::app_compile_version = _internal; +} + void qt_init(QApplicationPrivate * /* priv */, int) { if (!CCoeEnv::Static()) { // The S60 framework has not been initalized. We need to do it. - TApaApplicationFactory factory(NewApplication); + TApaApplicationFactory factory(S60->s60ApplicationFactory ? + S60->s60ApplicationFactory : newS60Application); CApaCommandLine* commandLine = 0; TInt err = CApaCommandLine::GetCommandLineFromProcessEnvironment(commandLine); // After this construction, CEikonEnv will be available from CEikonEnv::Static(). diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index aa39f9d..9734d26 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -61,6 +61,7 @@ #include "QtGui/qimage.h" #include "QtGui/qevent.h" #include "qpointer.h" +#include "qapplication.h" #include #include #include @@ -107,6 +108,7 @@ public: int mouseInteractionEnabled : 1; int virtualMouseRequired : 1; int qtOwnsS60Environment : 1; + QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type static inline void updateScreenSize(); static inline RWsSession& wsSession(); static inline RWindowGroup& windowGroup(); diff --git a/src/gui/s60framework/qs60mainapplication.cpp b/src/gui/s60framework/qs60mainapplication.cpp index f12ed1f..54fb3b1 100644 --- a/src/gui/s60framework/qs60mainapplication.cpp +++ b/src/gui/s60framework/qs60mainapplication.cpp @@ -41,53 +41,86 @@ // INCLUDE FILES #include -#include "qs60maindocument_p.h" +#include "qs60maindocument.h" #include "qs60mainapplication_p.h" +#include "qs60mainapplication.h" #include #include QT_BEGIN_NAMESPACE /** - * factory function to create the QtS60Main application class + * factory function to create the QS60Main application class */ -CApaApplication* NewApplication() +CApaApplication *newS60Application() { return new QS60MainApplication; } -// ============================ MEMBER FUNCTIONS =============================== +_LIT(KQtWrapperResourceFile, "\\resource\\apps\\s60main.rsc"); +/*! + * \class QS60MainApplication + * \obsolete + * \since 4.6 + * \brief Helper class for S60 migration + * + * The QS60MainApplication provides a helper class for use in migrating from existing S60 based + * applications to Qt based applications. It is used in the exact same way as the + * \c CAknApplication class from Symbian, but internally provides extensions used by Qt. + * + * When modifying old S60 applications that rely on implementing functions in \c CAknApplication, + * the class should be modified to inherit from this class instead of \c CAknApplication. Then the + * application can choose to override only certain functions. To make Qt use the custom application + * objects, pass a factory function to + * QApplication::QApplication(QApplication::QS60MainApplicationFactory, int &, char **). + * + * For more information on \c CAknApplication, please see the S60 documentation. + * + * Unlike other Qt classes, QS60MainApplication behaves like an S60 class, and can throw Symbian + * leaves. + * + * \sa QS60MainDocument, QS60MainAppUi, QApplication::QApplication(QApplication::QS60MainApplicationFactory, int &, char **) + */ -_LIT(KQtWrapperResourceFile, "\\resource\\apps\\s60main.rsc"); +/*! + * \brief Contructs an instance of QS60MainApplication. + */ +QS60MainApplication::QS60MainApplication() +{ +} -// ----------------------------------------------------------------------------- -// QS60MainApplication::CreateDocumentL() -// Creates CApaDocument object -// ----------------------------------------------------------------------------- -// -CApaDocument* QS60MainApplication::CreateDocumentL() +/*! + * \brief Destroys the QS60MainApplication. + */ +QS60MainApplication::~QS60MainApplication() +{ +} + +/*! + * \brief Creates an instance of QS60MainDocument. + * + * \sa QS60MainDocument + */ +CApaDocument *QS60MainApplication::CreateDocumentL() { // Create an QtS60Main document, and return a pointer to it - return (static_cast(QS60MainDocument::NewL(*this))); + return new (ELeave) QS60MainDocument(*this); } -// ----------------------------------------------------------------------------- -// QS60MainApplication::AppDllUid() -// Returns application UID -// ----------------------------------------------------------------------------- -// + +/*! + * \brief Returns the UID of the application. + */ TUid QS60MainApplication::AppDllUid() const { // Return the UID for the QtS60Main application - return ProcessUid(); + return RProcess().SecureId().operator TUid(); } -// ----------------------------------------------------------------------------- -// QS60MainApplication::ResourceFileName() -// Returns application resource filename -// ----------------------------------------------------------------------------- -// +/*! + * \brief Returns the resource file name. + */ TFileName QS60MainApplication::ResourceFileName() const { TFindFile finder(iCoeEnv->FsSession()); @@ -98,5 +131,3 @@ TFileName QS60MainApplication::ResourceFileName() const } QT_END_NAMESPACE - -// End of File diff --git a/src/gui/s60framework/qs60mainapplication.h b/src/gui/s60framework/qs60mainapplication.h new file mode 100644 index 0000000..457764c --- /dev/null +++ b/src/gui/s60framework/qs60mainapplication.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Symbian application wrapper of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QS60MAINAPPLICATION_H +#define QS60MAINAPPLICATION_H + +#include + +#ifdef Q_WS_S60 + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class Q_GUI_EXPORT QS60MainApplication : public CAknApplication +{ +public: + QS60MainApplication(); + // The virtuals are for qdoc. + virtual ~QS60MainApplication(); + + virtual TUid AppDllUid() const; + + virtual TFileName ResourceFileName() const; + +protected: + + virtual CApaDocument *CreateDocumentL(); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q_WS_S60 + +#endif // QS60MAINAPPLICATION_H diff --git a/src/gui/s60framework/qs60mainapplication_p.h b/src/gui/s60framework/qs60mainapplication_p.h index 40562da..863d872 100644 --- a/src/gui/s60framework/qs60mainapplication_p.h +++ b/src/gui/s60framework/qs60mainapplication_p.h @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the Symbian application wrapper of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage @@ -46,67 +46,21 @@ // 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. +// This file is not part of the Qt API. It exists for the convenience +// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header +// file may change from version to version without notice, or even be removed. // // We mean it. // -// INCLUDES -#include - #include -// CLASS DECLARATION +#include QT_BEGIN_NAMESPACE -CApaApplication* NewApplication(); - -static TUid ProcessUid() -{ - RProcess me; - TSecureId securId = me.SecureId(); - me.Close(); - return securId.operator TUid(); -} - -/** -* QS60MainApplication application class. -* Provides factory to create concrete document object. -* An instance of QS60MainApplication is the application part of the -* AVKON application framework for the QtS60Main example application. -*/ -class QS60MainApplication : public CAknApplication -{ -public: // Functions from base classes - - /** - * From CApaApplication, AppDllUid. - * @return Application's UID (KUidQtS60MainApp). - */ - TUid AppDllUid() const; - - /** - * From CApaApplication, ResourceFileName - * @return Application's resource filename (KUidQtS60MainApp). - */ - TFileName ResourceFileName() const; - -protected: // Functions from base classes - - /** - * From CApaApplication, CreateDocumentL. - * Creates QS60MainDocument document object. The returned - * pointer in not owned by the QS60MainApplication object. - * @return A pointer to the created document object. - */ - CApaDocument* CreateDocumentL(); -}; +CApaApplication *newS60Application(); QT_END_NAMESPACE #endif // QS60MAINAPPLICATION_P_H - -// End of File diff --git a/src/gui/s60framework/qs60mainappui.cpp b/src/gui/s60framework/qs60mainappui.cpp index 4f5227c..9e2333b 100644 --- a/src/gui/s60framework/qs60mainappui.cpp +++ b/src/gui/s60framework/qs60mainappui.cpp @@ -48,21 +48,42 @@ #include #include -#include "qs60mainappui_p.h" +#include "qs60mainappui.h" #include #include #include QT_BEGIN_NAMESPACE -// ============================ MEMBER FUNCTIONS =============================== - - -// ----------------------------------------------------------------------------- -// QS60MainAppUi::ConstructL() -// Symbian 2nd phase constructor can leave. -// ----------------------------------------------------------------------------- -// +/*! + * \class QS60MainAppUi + * \obsolete + * \since 4.6 + * \brief Helper class for S60 migration + * + * The QS60MainAppUi provides a helper class for use in migrating from existing S60 based + * applications to Qt based applications. It is used in the exact same way as the + * \c CAknAppUi class from Symbian, but internally provides extensions used by Qt. + * + * When modifying old S60 applications that rely on implementing functions in \c CAknAppUi, + * the class should be modified to inherit from this class instead of \c CAknAppUi. Then the + * application can choose to override only certain functions. + * + * For more information on \c CAknAppUi, please see the S60 documentation. + * + * Unlike other Qt classes, QS60MainAppUi behaves like an S60 class, and can throw Symbian + * leaves. + * + * \sa QS60MainDocument, QS60MainApplication + */ + +/*! + * \brief Second phase Symbian constructor. + * + * Constructs all the elements of the class that can cause a leave to happen. + * + * If you override this function, you should call the base class implementation as well. + */ void QS60MainAppUi::ConstructL() { // Cone's heap and handle checks on app destruction are not suitable for Qt apps, as many @@ -80,104 +101,142 @@ void QS60MainAppUi::ConstructL() nativeContainer->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS); } -// ----------------------------------------------------------------------------- -// QS60MainAppUi::QS60MainAppUi() -// C++ default constructor can NOT contain any code, that might leave. -// ----------------------------------------------------------------------------- -// +/*! + * \brief Contructs an instance of QS60MainAppUi. + */ QS60MainAppUi::QS60MainAppUi() { // No implementation required } -// ----------------------------------------------------------------------------- -// QS60MainAppUi::~QS60MainAppUi() -// Destructor. -// ----------------------------------------------------------------------------- -// +/*! + * \brief Destroys the QS60MainAppUi. + */ QS60MainAppUi::~QS60MainAppUi() { } -// ----------------------------------------------------------------------------- -// QS60MainAppUi::HandleCommandL() -// Takes care of command handling. -// ----------------------------------------------------------------------------- -// -void QS60MainAppUi::HandleCommandL(TInt aCommand) +/*! + * \brief Handles commands produced by the S60 framework. + * + * \a command holds the ID of the command to handle, and is S60 specific. + * + * If you override this function, you should call the base class implementation if you do not + * handle the command. + */ +void QS60MainAppUi::HandleCommandL(TInt command) { if (qApp) - qApp->symbianHandleCommand(aCommand); + QT_TRYCATCH_LEAVING(qApp->symbianHandleCommand(command)); } -// ----------------------------------------------------------------------------- -// QS60MainAppUi::HandleResourceChangeL() -// Takes care of event handling. -// ----------------------------------------------------------------------------- -// -void QS60MainAppUi::HandleResourceChangeL(TInt aType) +/*! + * \brief Handles a resource change in the S60 framework. + * + * Resource changes include layout switches. \a type holds the type of resource change that + * occurred. + * + * If you override this function, you should call the base class implementation if you do not + * handle the resource change. + */ +void QS60MainAppUi::HandleResourceChangeL(TInt type) { - CAknAppUi::HandleResourceChangeL(aType); + CAknAppUi::HandleResourceChangeL(type); if (qApp) - qApp->symbianResourceChange(aType); + QT_TRYCATCH_LEAVING(qApp->symbianResourceChange(type)); } -void QS60MainAppUi::HandleWsEventL(const TWsEvent& aEvent, CCoeControl *control) +/*! + * \brief Handles raw window server events. + * + * The event type and information is passed in \a event, while the receiving control is passed in + * \a destination. + * + * If you override this function, you should call the base class implementation if you do not + * handle the event. + */ +void QS60MainAppUi::HandleWsEventL(const TWsEvent& event, CCoeControl *destination) { int result = 0; if (qApp) QT_TRYCATCH_LEAVING( - result = qApp->s60ProcessEvent(const_cast(&aEvent)) + result = qApp->s60ProcessEvent(const_cast(&event)) ); if (result <= 0) - CAknAppUi::HandleWsEventL(aEvent, control); + CAknAppUi::HandleWsEventL(event, destination); } -// ----------------------------------------------------------------------------- -// Called by the framework when the application status pane -// size is changed. Passes the new client rectangle to the -// AppView -// ----------------------------------------------------------------------------- -// +/*! + * \brief Handles changes to the status pane size. + * + * Called by the framework when the application status pane size is changed. + * + * If you override this function, you should call the base class implementation if you do not + * handle the size change. + */ void QS60MainAppUi::HandleStatusPaneSizeChange() { - HandleResourceChangeL(KInternalStatusPaneChange); + TRAP_IGNORE(HandleResourceChangeL(KInternalStatusPaneChange)); HandleStackedControlsResourceChange(KInternalStatusPaneChange); } -void QS60MainAppUi::DynInitMenuBarL(TInt, CEikMenuBar *) +/*! + * \brief Dynamically initializes a menu bar. + * + * The resource associated with the menu is given in \a resourceId, and the actual menu bar is + * passed in \a menuBar. + * + * If you override this function, you should call the base class implementation as well. + */ +void QS60MainAppUi::DynInitMenuBarL(TInt /* resourceId */, CEikMenuBar * /* menuBar */) { } -void QS60MainAppUi::DynInitMenuPaneL(TInt aResourceId, CEikMenuPane *aMenuPane) +/*! + * \brief Dynamically initializes a menu pane. + * + * The resource associated with the menu is given in \a resourceId, and the actual menu pane is + * passed in \a menuPane. + * + * If you override this function, you should call the base class implementation as well. + */ +void QS60MainAppUi::DynInitMenuPaneL(TInt resourceId, CEikMenuPane *menuPane) { - if (aResourceId == R_QT_WRAPPERAPP_MENU) { - if (aMenuPane->NumberOfItemsInPane() <= 1) - qt_symbian_show_toplevel(aMenuPane); - - } else if (aResourceId != R_AVKON_MENUPANE_FEP_DEFAULT && aResourceId != R_AVKON_MENUPANE_EDITTEXT_DEFAULT && aResourceId != R_AVKON_MENUPANE_LANGUAGE_DEFAULT) { - qt_symbian_show_submenu(aMenuPane, aResourceId); + if (resourceId == R_QT_WRAPPERAPP_MENU) { + if (menuPane->NumberOfItemsInPane() <= 1) + QT_TRYCATCH_LEAVING(qt_symbian_show_toplevel(menuPane)); + + } else if (resourceId != R_AVKON_MENUPANE_FEP_DEFAULT + && resourceId != R_AVKON_MENUPANE_EDITTEXT_DEFAULT + && resourceId != R_AVKON_MENUPANE_LANGUAGE_DEFAULT) { + QT_TRYCATCH_LEAVING(qt_symbian_show_submenu(menuPane, resourceId)); } } -void QS60MainAppUi::RestoreMenuL(CCoeControl* aMenuWindow, TInt aMenuId, TMenuType aMenuType) +/*! + * \brief Restores a menu window. + * + * The menu window to restore is given in \a menuWindow. The resource ID and type of menu is given + * in \a resourceId and \a menuType, respectively. + * + * If you override this function, you should call the base class implementation as well. + */ +void QS60MainAppUi::RestoreMenuL(CCoeControl* menuWindow, TInt resourceId, TMenuType menuType) { - if ((aMenuId == R_QT_WRAPPERAPP_MENUBAR) || (aMenuId == R_AVKON_MENUPANE_FEP_DEFAULT)) { + if ((resourceId == R_QT_WRAPPERAPP_MENUBAR) || (resourceId == R_AVKON_MENUPANE_FEP_DEFAULT)) { TResourceReader reader; - iCoeEnv->CreateResourceReaderLC(reader, aMenuId); - aMenuWindow->ConstructFromResourceL(reader); + iCoeEnv->CreateResourceReaderLC(reader, resourceId); + menuWindow->ConstructFromResourceL(reader); CleanupStack::PopAndDestroy(); } - if (aMenuType == EMenuPane) - DynInitMenuPaneL(aMenuId, (CEikMenuPane*)aMenuWindow); + if (menuType == EMenuPane) + DynInitMenuPaneL(resourceId, (CEikMenuPane*)menuWindow); else - DynInitMenuBarL(aMenuId, (CEikMenuBar*)aMenuWindow); + DynInitMenuBarL(resourceId, (CEikMenuBar*)menuWindow); } QT_END_NAMESPACE - -// End of File diff --git a/src/gui/s60framework/qs60mainappui.h b/src/gui/s60framework/qs60mainappui.h new file mode 100644 index 0000000..c2c6ef2 --- /dev/null +++ b/src/gui/s60framework/qs60mainappui.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Symbian application wrapper of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QS60MAINAPPUI_H +#define QS60MAINAPPUI_H + +#include + +#ifdef Q_WS_S60 + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class Q_GUI_EXPORT QS60MainAppUi : public CAknAppUi +{ +public: + QS60MainAppUi(); + // The virtuals are for qdoc. + virtual ~QS60MainAppUi(); + + virtual void ConstructL(); + + virtual void RestoreMenuL(CCoeControl* menuWindow,TInt resourceId,TMenuType menuType); + virtual void DynInitMenuBarL(TInt resourceId, CEikMenuBar *menuBar); + virtual void DynInitMenuPaneL(TInt resourceId, CEikMenuPane *menuPane); + + virtual void HandleCommandL( TInt command ); + + virtual void HandleResourceChangeL(TInt type); + + virtual void HandleStatusPaneSizeChange(); + +protected: + virtual void HandleWsEventL(const TWsEvent& event, CCoeControl* destination); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q_WS_S60 + +#endif // QS60MAINAPPUI_H diff --git a/src/gui/s60framework/qs60mainappui_p.h b/src/gui/s60framework/qs60mainappui_p.h deleted file mode 100644 index 4b10833..0000000 --- a/src/gui/s60framework/qs60mainappui_p.h +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Symbian application wrapper of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QS60MAINAPPUI_P_H -#define QS60MAINAPPUI_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. -// - -// INCLUDES -#include - -#include - -QT_BEGIN_NAMESPACE - -// FORWARD DECLARATIONS - -// CLASS DECLARATION -/** -* QS60MainAppUi application UI class. -* Interacts with the user through the UI and request message processing -* from the handler class -*/ -class QS60MainAppUi : public CAknAppUi -{ -public: // Constructors and destructor - - /** - * ConstructL. - * 2nd phase constructor. - */ - void ConstructL(); - - /** - * QS60MainAppUi. - * C++ default constructor. This needs to be public due to - * the way the framework constructs the AppUi - */ - QS60MainAppUi(); - - /** - * ~QS60MainAppUi. - * Virtual Destructor. - */ - virtual ~QS60MainAppUi(); - -protected: - void RestoreMenuL(CCoeControl* aMenuWindow,TInt aMenuId,TMenuType aMenuType); - void DynInitMenuBarL(TInt aResourceId, CEikMenuBar *aMenuBar); - void DynInitMenuPaneL(TInt aResourceId, CEikMenuPane *aMenuPane); - -private: // Functions from base classes - - /** - * From CEikAppUi, HandleCommandL. - * Takes care of command handling. - * @param aCommand Command to be handled. - */ - void HandleCommandL( TInt aCommand ); - - /** - * From CAknAppUi, HandleResourceChangeL - * Handles resource change events such as layout switches in global level. - * @param aType event type. - */ - void HandleResourceChangeL(TInt aType); - - /** - * HandleStatusPaneSizeChange. - * Called by the framework when the application status pane - * size is changed. - */ - void HandleStatusPaneSizeChange(); - -protected: - void HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination); -}; - -QT_END_NAMESPACE - -#endif // QS60MAINAPPUI_P_H - -// End of File diff --git a/src/gui/s60framework/qs60maindocument.cpp b/src/gui/s60framework/qs60maindocument.cpp index ba66e98..52595db 100644 --- a/src/gui/s60framework/qs60maindocument.cpp +++ b/src/gui/s60framework/qs60maindocument.cpp @@ -39,77 +39,60 @@ ** ****************************************************************************/ -// INCLUDE FILES +#include "qs60mainappui.h" +#include "qs60maindocument.h" + #include -#include "qs60mainappui_p.h" -#include "qs60maindocument_p.h" QT_BEGIN_NAMESPACE -// ============================ MEMBER FUNCTIONS =============================== - -// ----------------------------------------------------------------------------- -// QS60MainDocument::NewL() -// Two-phased constructor. -// ----------------------------------------------------------------------------- -// -QS60MainDocument* QS60MainDocument::NewL(CEikApplication& aApp) -{ - QS60MainDocument* self = NewLC(aApp); - CleanupStack::Pop(self); - return self; -} - -// ----------------------------------------------------------------------------- -// QS60MainDocument::NewLC() -// Two-phased constructor. -// ----------------------------------------------------------------------------- -// -QS60MainDocument* QS60MainDocument::NewLC(CEikApplication& aApp) -{ - QS60MainDocument* self = new(ELeave) QS60MainDocument(aApp); - CleanupStack::PushL(self); - self->ConstructL(); - return self; -} - -// ----------------------------------------------------------------------------- -// QS60MainDocument::ConstructL() -// Symbian 2nd phase constructor can leave. -// ----------------------------------------------------------------------------- -// -void QS60MainDocument::ConstructL() -{ - // No implementation required -} +/*! + * \class QS60MainDocument + * \obsolete + * \since 4.6 + * \brief Helper class for S60 migration + * + * The QS60MainDocument provides a helper class for use in migrating from existing S60 based + * applications to Qt based applications. It is used in the exact same way as the + * \c CAknDocument class from Symbian, but internally provides extensions used by Qt. + * + * When modifying old S60 applications that rely on implementing functions in \c CAknDocument, + * the class should be modified to inherit from this class instead of \c CAknDocument. Then the + * application can choose to override only certain functions. + * + * For more information on \c CAknDocument, please see the S60 documentation. + * + * Unlike other Qt classes, QS60MainDocument behaves like an S60 class, and can throw Symbian + * leaves. + * + * \sa QS60MainApplication, QS60MainAppUi + */ -// ----------------------------------------------------------------------------- -// QS60MainDocument::QS60MainDocument() -// C++ default constructor can NOT contain any code, that might leave. -// ----------------------------------------------------------------------------- -// -QS60MainDocument::QS60MainDocument(CEikApplication& aApp) - : CAknDocument(aApp) +/*! + * \brief Constructs an instance of QS60MainDocument. + * + * \a mainApplication should contain a pointer to a QS60MainApplication instance. + */ +QS60MainDocument::QS60MainDocument(CEikApplication& mainApplication) + : CAknDocument(mainApplication) { // No implementation required } -// --------------------------------------------------------------------------- -// QS60MainDocument::~QS60MainDocument() -// Destructor. -// --------------------------------------------------------------------------- -// +/*! + * \brief Destroys the QS60MainDocument. + */ QS60MainDocument::~QS60MainDocument() { // No implementation required } -// --------------------------------------------------------------------------- -// QS60MainDocument::CreateAppUiL() -// Constructs CreateAppUi. -// --------------------------------------------------------------------------- -// -CEikAppUi* QS60MainDocument::CreateAppUiL() +/*! + * \brief Creates an instance of QS60MainAppUi. + * + * \sa QS60MainAppUi + */ +CEikAppUi *QS60MainDocument::CreateAppUiL() { // Create the application user interface, and return a pointer to it; // the framework takes ownership of this object @@ -117,5 +100,3 @@ CEikAppUi* QS60MainDocument::CreateAppUiL() } QT_END_NAMESPACE - -// End of File diff --git a/src/gui/s60framework/qs60maindocument.h b/src/gui/s60framework/qs60maindocument.h new file mode 100644 index 0000000..366d311 --- /dev/null +++ b/src/gui/s60framework/qs60maindocument.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Symbian application wrapper of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QS60MAINDOCUMENT_H +#define QS60MAINDOCUMENT_H + +#include + +#ifdef Q_WS_S60 + +#include + +class CEikApplication; + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QS60MainAppUi; + +class Q_GUI_EXPORT QS60MainDocument : public CAknDocument +{ +public: + + QS60MainDocument(CEikApplication &mainApplication); + // The virtuals are for qdoc. + virtual ~QS60MainDocument(); + +public: + + virtual CEikAppUi *CreateAppUiL(); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q_WS_S60 + +#endif // QS60MAINDOCUMENT_H diff --git a/src/gui/s60framework/qs60maindocument_p.h b/src/gui/s60framework/qs60maindocument_p.h deleted file mode 100644 index d7cee13..0000000 --- a/src/gui/s60framework/qs60maindocument_p.h +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Symbian application wrapper of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QS60MAINDOCUMENT_P_H -#define QS60MAINDOCUMENT_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. -// - -// INCLUDES -#include - -#include - -class CEikApplication; - -QT_BEGIN_NAMESPACE - -// FORWARD DECLARATIONS -class QS60MainAppUi; - -// CLASS DECLARATION - -/** -* QS60MainDocument application class. -* An instance of class QS60MainDocument is the Document part of the -* AVKON application framework for the QtS60Main application. -*/ -class QS60MainDocument : public CAknDocument -{ -public: // Constructors and destructor - - /** - * NewL. - * Two-phased constructor. - * Construct a QS60MainDocument for the AVKON application aApp - * using two phase construction, and return a pointer - * to the created object. - * @param aApp Application creating this document. - * @return A pointer to the created instance of QS60MainDocument. - */ - static QS60MainDocument* NewL( CEikApplication& aApp ); - - /** - * NewLC. - * Two-phased constructor. - * Construct a QS60MainDocument for the AVKON application aApp - * using two phase construction, and return a pointer - * to the created object. - * @param aApp Application creating this document. - * @return A pointer to the created instance of QS60MainDocument. - */ - static QS60MainDocument* NewLC( CEikApplication& aApp ); - - /** - * ~QS60MainDocument - * Virtual Destructor. - */ - virtual ~QS60MainDocument(); - -public: // Functions from base classes - - /** - * CreateAppUiL - * From CEikDocument, CreateAppUiL. - * Create a QS60MainAppUi object and return a pointer to it. - * The object returned is owned by the Uikon framework. - * @return Pointer to created instance of AppUi. - */ - CEikAppUi* CreateAppUiL(); - -private: // Constructors - - /** - * ConstructL - * 2nd phase constructor. - */ - void ConstructL(); - - /** - * QS60MainDocument. - * C++ default constructor. - * @param aApp Application creating this document. - */ - QS60MainDocument( CEikApplication& aApp ); - -}; - -QT_END_NAMESPACE - -#endif // QS60MAINDOCUMENT_P_H - -// End of File diff --git a/src/gui/s60framework/s60framework.pri b/src/gui/s60framework/s60framework.pri index f9a6d95..fea74fe 100644 --- a/src/gui/s60framework/s60framework.pri +++ b/src/gui/s60framework/s60framework.pri @@ -3,5 +3,6 @@ SOURCES += s60framework/qs60mainapplication.cpp \ s60framework/qs60maindocument.cpp HEADERS += s60framework/qs60mainapplication_p.h \ - s60framework/qs60mainappui_p.h \ - s60framework/qs60maindocument_p.h + s60framework/qs60mainapplication.h \ + s60framework/qs60mainappui.h \ + s60framework/qs60maindocument.h diff --git a/tests/auto/qs60mainapplication/qs60mainapplication.pro b/tests/auto/qs60mainapplication/qs60mainapplication.pro new file mode 100644 index 0000000..bbd6c30 --- /dev/null +++ b/tests/auto/qs60mainapplication/qs60mainapplication.pro @@ -0,0 +1,4 @@ +load(qttest_p4) +SOURCES += tst_qs60mainapplication.cpp + +symbian:LIBS += -lapparc -leikcore -lcone -lavkon diff --git a/tests/auto/qs60mainapplication/tst_qs60mainapplication.cpp b/tests/auto/qs60mainapplication/tst_qs60mainapplication.cpp new file mode 100644 index 0000000..78fcb86 --- /dev/null +++ b/tests/auto/qs60mainapplication/tst_qs60mainapplication.cpp @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include +#include +#include + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QS60MainApplication : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); +private slots: + void customQS60MainApplication(); +}; + +void tst_QS60MainApplication::initTestCase() +{ +} + +void tst_QS60MainApplication::cleanupTestCase() +{ +} + +void tst_QS60MainApplication::init() +{ +} + +void tst_QS60MainApplication::cleanup() +{ +} + +#ifdef Q_WS_S60 +bool appUiConstructed = false; + +class CustomMainAppUi : public QS60MainAppUi +{ +public: + CustomMainAppUi() + { + appUiConstructed = true; + } +}; + +class CustomMainDocument : public QS60MainDocument +{ +public: + CustomMainDocument(CEikApplication &eikApp) + : QS60MainDocument(eikApp) + { + } + CEikAppUi *CreateAppUiL() + { + return new (ELeave) CustomMainAppUi; + } +}; + +class CustomMainApplication : public QS60MainApplication +{ +protected: + CApaDocument *CreateDocumentL() + { + return new (ELeave) CustomMainDocument(*this); + } +}; + +CApaApplication *factory() +{ + return new (ELeave) CustomMainApplication; +} +#endif // Q_WS_S60 + +void tst_QS60MainApplication::customQS60MainApplication() +{ +#ifndef Q_WS_S60 + QSKIP("This is an S60-only test", SkipAll); +#else + int argc = 1; + char *argv = "tst_qs60mainapplication"; + QApplication app(factory, argc, &argv); + QVERIFY(appUiConstructed); +#endif +} + +QTEST_APPLESS_MAIN(tst_QS60MainApplication) +#include "tst_qs60mainapplication.moc" -- cgit v0.12 From 4184d85022e2fb3d90dfa4cb211ea5e8e968dec7 Mon Sep 17 00:00:00 2001 From: axis Date: Wed, 23 Sep 2009 10:57:28 +0200 Subject: Corrected typo. --- src/gui/kernel/qt_s60_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index 9734d26..905adc2 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -78,7 +78,7 @@ QT_BEGIN_NAMESPACE // Application internal HandleResourceChangeL events, -// system evens seems to start with 0x10 +// system events seems to start with 0x10 const TInt KInternalStatusPaneChange = 0x50000000; class QS60Data -- cgit v0.12 From f4c948dde1159b3a04a507781f1e0f89bd4b3b37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Wed, 23 Sep 2009 16:33:33 +0200 Subject: Add test for to see if the layout is stable if it has several solutions. Currently this fails, so we have to use QEXPECT_FAIL. --- .../tst_qgraphicsanchorlayout.cpp | 65 ++++++++++++++++++++-- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 385fb3e..2c4a253 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -64,6 +64,7 @@ private slots: void example(); void setSpacing(); void hardComplexS60(); + void stability(); void delete_anchor(); void conflicts(); void sizePolicy(); @@ -986,10 +987,26 @@ void tst_QGraphicsAnchorLayout::setSpacing() } -void tst_QGraphicsAnchorLayout::hardComplexS60() +/*! + Taken from "hard" complex case, found at + https://cwiki.nokia.com/S60QTUI/AnchorLayoutComplexCases + + This layout has a special property, since it has two possible solutions for its minimum size. + + For instance, when it is in its minimum size - the layout have two possible solutions: + 1. c.width == 10, e.width == 10 and g.width == 10 + (all others have width 0) + 2. d.width == 10 and g.width == 10 + (all others have width 0) + + It also has several solutions for preferred size. +*/ +static QGraphicsAnchorLayout *createAmbiguousS60Layout() { - // Test for "hard" complex case, taken from wiki - // https://cwiki.nokia.com/S60QTUI/AnchorLayoutComplexCases + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; + l->setContentsMargins(0, 0, 0, 0); + l->setSpacing(0); + QSizeF min(0, 10); QSizeF pref(50, 10); QSizeF max(100, 10); @@ -1002,9 +1019,6 @@ void tst_QGraphicsAnchorLayout::hardComplexS60() QGraphicsWidget *f = createItem(min, pref, max, "f"); QGraphicsWidget *g = createItem(min, pref, max, "g"); - QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; - l->setContentsMargins(0, 0, 0, 0); - // setAnchor(l, l, Qt::AnchorLeft, a, Qt::AnchorLeft, 10); setAnchor(l, a, Qt::AnchorRight, b, Qt::AnchorLeft, 10); @@ -1034,7 +1048,12 @@ void tst_QGraphicsAnchorLayout::hardComplexS60() setAnchor(l, a, Qt::AnchorBottom, d, Qt::AnchorBottom, 0); setAnchor(l, f, Qt::AnchorBottom, g, Qt::AnchorTop, 0); setAnchor(l, g, Qt::AnchorBottom, l, Qt::AnchorBottom, 0); + return l; +} +void tst_QGraphicsAnchorLayout::hardComplexS60() +{ + QGraphicsAnchorLayout *l = createAmbiguousS60Layout(); QCOMPARE(l->count(), 7); QGraphicsWidget *p = new QGraphicsWidget(0, Qt::Window); @@ -1050,6 +1069,40 @@ void tst_QGraphicsAnchorLayout::hardComplexS60() } +void tst_QGraphicsAnchorLayout::stability() +{ + QVector geometries; + geometries.resize(7); + QGraphicsWidget *p = new QGraphicsWidget(0, Qt::Window); + bool sameAsPreviousArrangement = true; + // it usually fails after 3-4 iterations + for (int pass = 0; pass < 20 && sameAsPreviousArrangement; ++pass) { + // In case we need to "scramble" the heap allocator to provoke this bug. + //static const int primes[] = {2, 3, 5, 13, 89, 233, 1597, 28657, 514229}; // fibo primes + //const int primeCount = sizeof(primes)/sizeof(int); + //int alloc = primes[pass % primeCount] + pass; + //void *mem = qMalloc(alloc); + //qFree(mem); + QGraphicsAnchorLayout *l = createAmbiguousS60Layout(); + p->setLayout(l); + QSizeF layoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize); + l->setGeometry(QRectF(QPointF(0,0), layoutMinimumSize)); + QApplication::processEvents(); + for (int i = l->count() - 1; i >=0 && sameAsPreviousArrangement; --i) { + QRectF geom = l->itemAt(i)->geometry(); + if (pass != 0) { + sameAsPreviousArrangement = (geometries[i] == geom); + } + geometries[i] = geom; + } + p->setLayout(0); // uninstalls and deletes the layout + QApplication::processEvents(); + } + delete p; + QEXPECT_FAIL("", "The layout have several solutions, but which solution it picks is not stable", Continue); + QCOMPARE(sameAsPreviousArrangement, true); +} + void tst_QGraphicsAnchorLayout::delete_anchor() { QGraphicsScene scene; -- cgit v0.12 From 74ba43ee9b82f46d07d4055af4e9ac7706701cea Mon Sep 17 00:00:00 2001 From: Jeremy Katz Date: Wed, 23 Sep 2009 17:29:10 +0200 Subject: Don't disable painting with multiple screens and VNC Task-number: QTBUG-4473 Reviewed-by: Paul --- src/gui/embedded/qscreenmulti_qws.cpp | 4 ++++ src/plugins/gfxdrivers/vnc/qscreenvnc_p.h | 2 ++ src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp | 20 ++++++++++++-------- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/gui/embedded/qscreenmulti_qws.cpp b/src/gui/embedded/qscreenmulti_qws.cpp index beeb6aa..3a23ca2 100644 --- a/src/gui/embedded/qscreenmulti_qws.cpp +++ b/src/gui/embedded/qscreenmulti_qws.cpp @@ -46,6 +46,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -230,6 +231,9 @@ bool QMultiScreen::connect(const QString &displaySpec) QStringList specs = dSpec.split(QLatin1Char(' '), QString::SkipEmptyParts); foreach (QString spec, specs) { const int id = getDisplayId(spec); + if (spec.startsWith("vnc:", Qt::CaseInsensitive)) { + spec.append(":noDisablePainting"); + } const QPoint offset = filterDisplayOffset(spec); QScreen *s = qt_get_screen(id, spec.toLatin1().constData()); s->setOffset(offset); diff --git a/src/plugins/gfxdrivers/vnc/qscreenvnc_p.h b/src/plugins/gfxdrivers/vnc/qscreenvnc_p.h index 9aad8f7..d7466d2 100644 --- a/src/plugins/gfxdrivers/vnc/qscreenvnc_p.h +++ b/src/plugins/gfxdrivers/vnc/qscreenvnc_p.h @@ -259,6 +259,8 @@ public: #endif QVNCScreen *q_ptr; + + bool noDisablePainting; }; class QRfbEncoder diff --git a/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp b/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp index e177f98..f28e160 100644 --- a/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp +++ b/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp @@ -195,8 +195,11 @@ void QVNCClientCursor::write() const QVNCScreenPrivate::QVNCScreenPrivate(QVNCScreen *parent) : dpiX(72), dpiY(72), doOnScreenSurface(false), refreshRate(25), - vncServer(0), q_ptr(parent) + vncServer(0), q_ptr(parent), noDisablePainting(false) { +#ifdef QT_BUILD_INTERNAL + noDisablePainting = (qgetenv("QT_VNC_NO_DISABLEPAINTING").toInt() <=0); +#endif #ifndef QT_NO_QWS_SIGNALHANDLER QWSSignalHandler::instance()->addObject(this); #endif @@ -615,7 +618,7 @@ void QVNCServer::newConnection() client->write(proto, 12); state = Protocol; - if (!qvnc_screen->screen()) + if (!qvnc_screen->screen() && !qvnc_screen->d_ptr->noDisablePainting) QWSServer::instance()->enablePainting(true); } @@ -2001,7 +2004,7 @@ void QVNCServer::discardClient() delete qvnc_cursor; qvnc_cursor = 0; #endif - if (!qvnc_screen->screen()) + if (!qvnc_screen->screen() && !qvnc_screen->d_ptr->noDisablePainting) QWSServer::instance()->enablePainting(false); } @@ -2184,6 +2187,9 @@ bool QVNCScreen::connect(const QString &displaySpec) d_ptr->dpiY = (dpiY > 0 ? dpiY : dpiX); } + if (args.contains(QLatin1String("noDisablePainting"))) + d_ptr->noDisablePainting = true; + QWSServer::setDefaultMouse("None"); QWSServer::setDefaultKeyboard("None"); @@ -2273,11 +2279,9 @@ bool QVNCScreen::initDevice() if (QProxyScreen::screen()) return ok; -#ifdef QT_BUILD_INTERNAL - if (qgetenv("QT_VNC_NO_DISABLEPAINTING").toInt() <= 0) -#endif - // No need to do painting while there's no clients attached - QWSServer::instance()->enablePainting(false); + // Disable painting if there is only 1 display and nothing is attached to the VNC server + if (!d_ptr->noDisablePainting) + QWSServer::instance()->enablePainting(false); return true; } -- cgit v0.12 From f494b7a9307675f8d6f4c1a6dd0ac07697705164 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 23 Sep 2009 15:06:36 +0200 Subject: Stabilize tst_QWidget::saveRestoreGeometry We need to wait for more condition before saving, otherwise what we save is not accurate (and the test fails) --- tests/auto/qwidget/tst_qwidget.cpp | 58 ++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index b7ffd15..811213a 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -2796,10 +2796,12 @@ void tst_QWidget::raise() QTest::qWait(50); UpdateWidget *onTop = new UpdateWidget(&topLevel); + onTop->reset(); onTop->resize(topLevel.size()); onTop->setAutoFillBackground(true); onTop->show(); QTest::qWait(50); + QTRY_VERIFY(onTop->numPaintEvents > 0); onTop->reset(); // Reset all the children. @@ -3072,7 +3074,7 @@ void tst_QWidget::saveRestoreGeometry() widget.resize(size); widget.show(); QTest::qWaitForWindowShown(&widget); - QTest::qWait(10); + QApplication::processEvents(); QTRY_COMPARE(widget.pos(), position); QCOMPARE(widget.size(), size); @@ -3099,7 +3101,7 @@ void tst_QWidget::saveRestoreGeometry() QVERIFY(widget.restoreGeometry(savedGeometry)); widget.show(); QTest::qWaitForWindowShown(&widget); - QTest::qWait(10); + QApplication::processEvents(); QTRY_COMPARE(widget.pos(), position); QCOMPARE(widget.size(), size); @@ -3114,7 +3116,8 @@ void tst_QWidget::saveRestoreGeometry() widget.resize(size); widget.show(); QTest::qWaitForWindowShown(&widget); - QTest::qWait(10); + QTest::qWait(100); + QTRY_COMPARE(widget.geometry().size(), size); QRect geom; @@ -3122,56 +3125,67 @@ void tst_QWidget::saveRestoreGeometry() savedGeometry = widget.saveGeometry(); geom = widget.geometry(); widget.setWindowState(widget.windowState() | Qt::WindowFullScreen); - QTest::qWait(10); QTRY_VERIFY((widget.windowState() & Qt::WindowFullScreen)); + QTest::qWait(100); QVERIFY(widget.restoreGeometry(savedGeometry)); - QTest::qWait(10); + QTest::qWait(20); + QTRY_VERIFY(!(widget.windowState() & Qt::WindowFullScreen)); QTRY_COMPARE(widget.geometry(), geom); - QVERIFY(!(widget.windowState() & Qt::WindowFullScreen)); //Restore to full screen widget.setWindowState(widget.windowState() | Qt::WindowFullScreen); - QTest::qWait(10); + QTest::qWait(20); QTRY_VERIFY((widget.windowState() & Qt::WindowFullScreen)); + QTest::qWait(200); savedGeometry = widget.saveGeometry(); geom = widget.geometry(); widget.setWindowState(widget.windowState() ^ Qt::WindowFullScreen); - QTest::qWait(10); - QTRY_VERIFY(widget.restoreGeometry(savedGeometry)); - QTest::qWait(10); + QTest::qWait(20); + QTRY_VERIFY(!(widget.windowState() & Qt::WindowFullScreen)); + QTest::qWait(200); + QVERIFY(widget.restoreGeometry(savedGeometry)); + QTest::qWait(20); + QTRY_VERIFY((widget.windowState() & Qt::WindowFullScreen)); QTRY_COMPARE(widget.geometry(), geom); QVERIFY((widget.windowState() & Qt::WindowFullScreen)); widget.setWindowState(widget.windowState() ^ Qt::WindowFullScreen); - QTest::qWait(10); + QTest::qWait(20); + QTRY_VERIFY(!(widget.windowState() & Qt::WindowFullScreen)); + QTest::qWait(20); //Restore from Maximised widget.move(position); widget.resize(size); - QTest::qWait(10); + QTest::qWait(20); + QTRY_COMPARE(widget.size(), size); + QTest::qWait(100); savedGeometry = widget.saveGeometry(); geom = widget.geometry(); widget.setWindowState(widget.windowState() | Qt::WindowMaximized); - QTest::qWait(10); + QTest::qWait(20); QTRY_VERIFY((widget.windowState() & Qt::WindowMaximized)); - QVERIFY(widget.geometry() != geom); + QTRY_VERIFY(widget.geometry() != geom); QVERIFY(widget.restoreGeometry(savedGeometry)); - QTest::qWait(10); - QCOMPARE(widget.geometry(), geom); + QTest::qWait(20); + QTRY_COMPARE(widget.geometry(), geom); QVERIFY(!(widget.windowState() & Qt::WindowMaximized)); //Restore to maximised widget.setWindowState(widget.windowState() | Qt::WindowMaximized); - QTest::qWait(10); + QTest::qWait(20); QTRY_VERIFY((widget.windowState() & Qt::WindowMaximized)); + QTest::qWait(100); geom = widget.geometry(); savedGeometry = widget.saveGeometry(); widget.setWindowState(widget.windowState() ^ Qt::WindowMaximized); - QTest::qWait(10); - QTRY_VERIFY(widget.restoreGeometry(savedGeometry)); - QTest::qWait(10); + QTest::qWait(20); + QTRY_VERIFY(!(widget.windowState() & Qt::WindowMaximized)); + QTest::qWait(20); + QVERIFY(widget.restoreGeometry(savedGeometry)); + QTest::qWait(20); + QTRY_VERIFY((widget.windowState() & Qt::WindowMaximized)); QTRY_COMPARE(widget.geometry(), geom); - QVERIFY((widget.windowState() & Qt::WindowMaximized)); } } @@ -7431,8 +7445,10 @@ void tst_QWidget::updateWhileMinimized() // Filter out activation change and focus events to avoid update() calls in QWidget. widget.updateOnActivationChangeAndFocusIn = false; widget.show(); + widget.reset(); QTest::qWaitForWindowShown(&widget); QApplication::processEvents(); + QTRY_VERIFY(widget.numPaintEvents > 0); // Minimize window. widget.showMinimized(); -- cgit v0.12 From 0ff0494f108bff514c4ef05a301769dc8962d66f Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 23 Sep 2009 16:47:03 +0200 Subject: Skip tst_QWidget::setWindowGeometry on X11 Since WindowManager operation are all assync, and we have no way to know if the window manager has finished playing with the window geometry, this test can't be reliable. Reviewed-by: Denis --- tests/auto/qwidget/tst_qwidget.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 811213a..126d571 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -4897,6 +4897,11 @@ void tst_QWidget::setWindowGeometry_data() void tst_QWidget::setWindowGeometry() { +#ifdef Q_WS_X11 + //Since WindowManager operation are all assync, and we have no way to know if the window + // manager has finished playing with the window geometry, this test can't be reliable. + QSKIP("Window Manager behaviour are too random for this test", SkipAll); +#endif QFETCH(QList, rects); QFETCH(int, windowFlags); QRect rect = rects.takeFirst(); @@ -5044,6 +5049,11 @@ void tst_QWidget::windowMoveResize_data() void tst_QWidget::windowMoveResize() { +#ifdef Q_WS_X11 + //Since WindowManager operation are all assync, and we have no way to know if the window + // manager has finished playing with the window geometry, this test can't be reliable. + QSKIP("Window Manager behaviour are too random for this test", SkipAll); +#endif #ifdef Q_OS_IRIX QSKIP("4DWM issues on IRIX makes this test fail", SkipAll); #endif -- cgit v0.12 From d5c9bf881c97785a61d056aeee645e768c8b0474 Mon Sep 17 00:00:00 2001 From: axis Date: Wed, 23 Sep 2009 17:57:39 +0200 Subject: Added ImhEmailCharactersOnly flag. RevBy: Trust me --- src/corelib/global/qnamespace.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index c39e602..741c06f 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1430,6 +1430,7 @@ public: ImhUppercaseOnly = 0x40000, ImhLowercaseOnly = 0x80000, ImhDialableCharactersOnly = 0x100000, + ImhEmailCharactersOnly = 0x200000, ImhExclusiveInputMask = 0xffff0000 }; -- cgit v0.12 From 02641e549e836984f575c9b3cc121513c5fda7d6 Mon Sep 17 00:00:00 2001 From: axis Date: Wed, 23 Sep 2009 17:59:42 +0200 Subject: Cleaned up input method hints documentation a bit. - Added missing docs for some flags. - Rearranged the values by type. RevBy: Trust me --- src/corelib/global/qnamespace.qdoc | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index fafbec5..18b4d67 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -2451,23 +2451,32 @@ \enum Qt::InputMethodHint \value ImhNone No hints. + + Flags that alter the behavior: + \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 ImhDigitsOnly 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. + + Flags that restrict input (exclusive flags): + + \value ImhDigitsOnly Only digits are allowed. + \value ImhFormattedNumbersOnly Only number input is allowed. This includes decimal point and minus sign. + \value ImhUppercaseOnly Only upper case letter input is allowed. + \value ImhLowercaseOnly Only lower case letter input is allowed. \value ImhDialableCharactersOnly Only characters suitable for phone dialling are allowed. + \value ImhEmailCharactersOnly Only characters suitable for email addresses are allowed. + + Masks: - \omitvalue ImhFormattedNumbersOnly - \omitvalue ImhExclusiveInputMask + \value ImhExclusiveInputMask This mask yields nonzero if any of the exclusive flags are used. - \note If several flags ending with \c Only are ORed together, the resulting character set will + \note If several exclusive flags 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. -- cgit v0.12 From 1950e27370ded75506e0129858bdad9a7c1b7a93 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 23 Sep 2009 14:38:44 +0200 Subject: tests/auto/QSvgGenerator pro file fixed Reviewed-by: TrustMe --- tests/auto/qsvggenerator/qsvggenerator.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qsvggenerator/qsvggenerator.pro b/tests/auto/qsvggenerator/qsvggenerator.pro index 450bcd3..1ccf8e9 100644 --- a/tests/auto/qsvggenerator/qsvggenerator.pro +++ b/tests/auto/qsvggenerator/qsvggenerator.pro @@ -15,6 +15,6 @@ wince*|symbian { wince* { DEFINES += SRCDIR=\\\"\\\" -} !symbian { +} else:!symbian { DEFINES += SRCDIR=\\\"$$PWD/\\\" } -- cgit v0.12 From 89261bc78f370bc54582e9fec736e6204c299ae1 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 23 Sep 2009 17:58:33 +0200 Subject: tests/auto/qpainter pro file fixed Reviewed-by: TrustMe --- tests/auto/qpainter/qpainter.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qpainter/qpainter.pro b/tests/auto/qpainter/qpainter.pro index 1b3659d..c8446d1 100644 --- a/tests/auto/qpainter/qpainter.pro +++ b/tests/auto/qpainter/qpainter.pro @@ -9,7 +9,7 @@ wince*|symbian*: { wince* { DEFINES += SRCDIR=\\\".\\\" -} !symbian { +} else:!symbian { DEFINES += SRCDIR=\\\"$$PWD\\\" } -- cgit v0.12 From affff618d68dd7f0c6c6abd2dd59ed151e45e220 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 23 Sep 2009 18:02:53 +0200 Subject: QLabel and QTextEdit autotest pro files fixed Reviewed-by: joerg --- tests/auto/qlabel/qlabel.pro | 2 +- tests/auto/qtextedit/qtextedit.pro | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qlabel/qlabel.pro b/tests/auto/qlabel/qlabel.pro index c274b4a..6d55c13 100644 --- a/tests/auto/qlabel/qlabel.pro +++ b/tests/auto/qlabel/qlabel.pro @@ -3,7 +3,7 @@ SOURCES += tst_qlabel.cpp wince*:{ DEFINES += SRCDIR=\\\"\\\" -} !symbian { +} else:!symbian { DEFINES += SRCDIR=\\\"$$PWD/\\\" } diff --git a/tests/auto/qtextedit/qtextedit.pro b/tests/auto/qtextedit/qtextedit.pro index 02f5dcb..3efabad 100644 --- a/tests/auto/qtextedit/qtextedit.pro +++ b/tests/auto/qtextedit/qtextedit.pro @@ -13,7 +13,7 @@ wince*|symbian*: { wince* { DEFINES += SRCDIR=\\\"./\\\" -} !symbian { +} else:!symbian { DEFINES += SRCDIR=\\\"$$PWD/\\\" } -- cgit v0.12 From af876ae5a55526afa4aedc3d8b214d66b50032e6 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 23 Sep 2009 18:04:46 +0200 Subject: Try to stabilize stylesheet test --- tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp index 50bb846..15ed56b 100644 --- a/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -974,10 +974,11 @@ void tst_QStyleSheetStyle::background() void tst_QStyleSheetStyle::tabAlignement() { QTabWidget tabWidget; - tabWidget.show(); - QTest::qWait(50); tabWidget.addTab(new QLabel("tab1"),"tab1"); tabWidget.resize(QSize(400,400)); + tabWidget.show(); + QTest::qWaitForWindowShown(&tabWidget); + QTest::qWait(50); QTabBar *bar = qFindChild(&tabWidget); QVERIFY(bar); //check the tab is on the right -- cgit v0.12 From 92b717cbfb94bffbdc1a4d22f67ad359ba81a439 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 23 Sep 2009 18:22:29 +0200 Subject: Stabilize QGraphicsEffect and QToolTip test --- tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp | 14 ++++++-------- tests/auto/qtooltip/tst_qtooltip.cpp | 9 +++++---- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp b/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp index ba3783b..0201bc4 100644 --- a/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp +++ b/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp @@ -48,6 +48,8 @@ #include #include +#include "../../shared/util.h" + //TESTED_CLASS= //TESTED_FILES= @@ -261,10 +263,8 @@ void tst_QGraphicsEffect::draw() QGraphicsView view(&scene); view.show(); -#ifdef Q_WS_X11 - qt_x11_wait_for_window_manager(&view); -#endif - QTest::qWait(100); + QTest::qWaitForWindowShown(&view); + QTRY_VERIFY(item->numRepaints > 0); item->reset(); // Make sure installing the effect triggers a repaint. @@ -361,10 +361,8 @@ void tst_QGraphicsEffect::opacity() QGraphicsView view(&scene); view.show(); -#ifdef Q_WS_X11 - qt_x11_wait_for_window_manager(&view); -#endif - QTest::qWait(100); + QTest::qWaitForWindowShown(&view); + QTRY_VERIFY(effect->numRepaints > 0); QCOMPARE(effect->m_opacity, qreal(0.5)); } diff --git a/tests/auto/qtooltip/tst_qtooltip.cpp b/tests/auto/qtooltip/tst_qtooltip.cpp index 2ad74a3..283effa 100644 --- a/tests/auto/qtooltip/tst_qtooltip.cpp +++ b/tests/auto/qtooltip/tst_qtooltip.cpp @@ -112,13 +112,14 @@ void tst_QToolTip::task183679() Widget_task183679 widget; widget.show(); -#ifdef Q_WS_X11 - qt_x11_wait_for_window_manager(&widget); -#endif + QApplication::setActiveWindow(&widget); + QTest::qWaitForWindowShown(&widget); + QTest::qWait(30); + widget.showDelayedToolTip(100); QTest::qWait(300); - QVERIFY(QToolTip::isVisible()); + QTRY_VERIFY(QToolTip::isVisible()); QTest::keyPress(&widget, key); -- cgit v0.12 From 454bedce14728e4f0575aadea6c454717c95d3fe Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 23 Sep 2009 18:43:59 +0200 Subject: Fix Q3TextBrowser It seems that the test machine has some different font configuration which makes the font weight different from the default one. Fixed the problem by resolving the font before comparing. Reviewed-by: Peter Hartmann --- tests/auto/q3textbrowser/tst_q3textbrowser.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/q3textbrowser/tst_q3textbrowser.cpp b/tests/auto/q3textbrowser/tst_q3textbrowser.cpp index 9a9f55c..b4c7e0d 100644 --- a/tests/auto/q3textbrowser/tst_q3textbrowser.cpp +++ b/tests/auto/q3textbrowser/tst_q3textbrowser.cpp @@ -97,6 +97,7 @@ void tst_Q3TextBrowser::setFont() { QFont f("Courier", 6); testWidget->setFont(f); + f = f.resolve(testWidget->font()); QVERIFY(testWidget->font() == f); } -- cgit v0.12 From 0f462990247d71e598346a8f96faf6d04cd4515e Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Wed, 23 Sep 2009 19:08:16 +0200 Subject: Compile fix for platforms prior to Symbian^3. The advanced pointer events are only available on Symbian^3 and higher so we need to make sure these are protected by an #ifdef. We might have to re-factor this later into a plugin in order to get this running on older versions. Reviewed-by: axis --- src/corelib/global/qglobal.h | 1 + src/gui/kernel/qapplication_s60.cpp | 6 ++++++ src/gui/kernel/qt_s60_p.h | 2 ++ src/gui/kernel/qwidget_s60.cpp | 2 ++ 4 files changed, 11 insertions(+) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index e722268..7fe67ec 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -2391,6 +2391,7 @@ QT3_SUPPORT Q_CORE_EXPORT const char *qInstallPathSysconf(); #define Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE //enabling new graphics resources #define QT_SYMBIAN_SUPPORTS_SGIMAGE +#define QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER #endif diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 1c198f9..27e8602 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -368,6 +368,7 @@ void QSymbianControl::HandleLongTapEventL( const TPoint& aPenEventLocation, cons m_previousEventLongTap = true; } +#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER void QSymbianControl::translateAdvancedPointerEvent(const TAdvancedPointerEvent *event) { QApplicationPrivate *d = QApplicationPrivate::instance(); @@ -427,9 +428,11 @@ void QSymbianControl::translateAdvancedPointerEvent(const TAdvancedPointerEvent QTouchEvent::TouchScreen, d->appAllTouchPoints); } +#endif void QSymbianControl::HandlePointerEventL(const TPointerEvent& pEvent) { +#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER if (pEvent.IsAdvancedPointerEvent()) { const TAdvancedPointerEvent *advancedPointerEvent = pEvent.AdvancedPointerEvent(); translateAdvancedPointerEvent(advancedPointerEvent); @@ -438,6 +441,7 @@ void QSymbianControl::HandlePointerEventL(const TPointerEvent& pEvent) return; } } +#endif m_longTapDetector->PointerEventL(pEvent); QT_TRYCATCH_LEAVING(HandlePointerEvent(pEvent)); @@ -1551,8 +1555,10 @@ TUint QApplicationPrivate::resolveS60ScanCode(TInt scanCode, TUint keysym) void QApplicationPrivate::initializeMultitouch_sys() { +#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER if (HAL::Get(HALData::EPointer3DMaxPressure, maxTouchPressure) != KErrNone) maxTouchPressure = KMaxTInt; +#endif } void QApplicationPrivate::cleanupMultitouch_sys() diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index 3a2dd2b..0d48634 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -169,7 +169,9 @@ private: TKeyResponse sendKeyEvent(QWidget *widget, QKeyEvent *keyEvent); bool sendMouseEvent(QWidget *widget, QMouseEvent *mEvent); void HandleLongTapEventL( const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation ); +#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER void translateAdvancedPointerEvent(const TAdvancedPointerEvent *event); +#endif private: QWidget *qwidget; diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 2e6139b..6b5e9b7 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -805,11 +805,13 @@ void QWidgetPrivate::setMask_sys(const QRegion& /* region */) void QWidgetPrivate::registerTouchWindow() { +#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER Q_Q(QWidget); if (q->testAttribute(Qt::WA_WState_Created) && q->windowType() != Qt::Desktop) { RWindow *rwindow = static_cast(q->effectiveWinId()->DrawableWindow()); rwindow->EnableAdvancedPointers(); } +#endif } int QWidget::metric(PaintDeviceMetric m) const -- cgit v0.12 From d2180e2fc3c56d56cd073a896d8449181ca28136 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 23 Sep 2009 19:48:16 +0200 Subject: Stabilize more test --- tests/auto/qcompleter/tst_qcompleter.cpp | 4 +--- tests/auto/qfiledialog/tst_qfiledialog.cpp | 3 +++ tests/auto/qheaderview/tst_qheaderview.cpp | 3 ++- tests/auto/qmenu/tst_qmenu.cpp | 2 ++ tests/auto/qspinbox/tst_qspinbox.cpp | 2 +- tests/auto/qstyle/tst_qstyle.cpp | 2 +- tests/auto/qtableview/tst_qtableview.cpp | 2 +- tests/auto/qtextbrowser/tst_qtextbrowser.cpp | 4 +--- 8 files changed, 12 insertions(+), 10 deletions(-) diff --git a/tests/auto/qcompleter/tst_qcompleter.cpp b/tests/auto/qcompleter/tst_qcompleter.cpp index 1baae90..f7b9d98 100644 --- a/tests/auto/qcompleter/tst_qcompleter.cpp +++ b/tests/auto/qcompleter/tst_qcompleter.cpp @@ -1011,6 +1011,7 @@ void tst_QCompleter::multipleWidgets() QWidget window; window.show(); QApplication::setActiveWindow(&window); + QApplicaion::qWaitForWindowShown(&window); QTRY_VERIFY(qApp->activeWindow() == &window); QFocusEvent focusIn(QEvent::FocusIn); @@ -1022,9 +1023,6 @@ void tst_QCompleter::multipleWidgets() comboBox->setFocus(); comboBox->show(); window.activateWindow(); -#ifdef Q_WS_X11 - qt_x11_wait_for_window_manager(&window); -#endif QApplication::setActiveWindow(&window); QTest::qWait(50); QTRY_VERIFY(qApp->focusWidget() == comboBox); diff --git a/tests/auto/qfiledialog/tst_qfiledialog.cpp b/tests/auto/qfiledialog/tst_qfiledialog.cpp index 18875e7..d6225cd 100644 --- a/tests/auto/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/qfiledialog/tst_qfiledialog.cpp @@ -1039,7 +1039,10 @@ void tst_QFiledialog::focus() QNonNativeFileDialog fd; fd.setDirectory(QDir::currentPath()); fd.show(); + QApplication::setActiveWindow(&fd); + QTest::qWaitForWindowShown(&fd); QTRY_COMPARE(fd.isVisible(), true); + QTRY_COMPARE(QApplication::activeWindow(), &fd); qApp->processEvents(); // make sure the tests work with focus follows mouse diff --git a/tests/auto/qheaderview/tst_qheaderview.cpp b/tests/auto/qheaderview/tst_qheaderview.cpp index 0be895b..920231d 100644 --- a/tests/auto/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/qheaderview/tst_qheaderview.cpp @@ -1434,7 +1434,8 @@ void tst_QHeaderView::focusPolicy() widget.show(); widget.setFocus(Qt::OtherFocusReason); - QTest::qWait(100); + QApplication::setActiveWindow(&widget); + QTest::qWaitForWindowShown(&widget); widget.activateWindow(); QTest::qWait(100); diff --git a/tests/auto/qmenu/tst_qmenu.cpp b/tests/auto/qmenu/tst_qmenu.cpp index a5bac37..d7f453e 100644 --- a/tests/auto/qmenu/tst_qmenu.cpp +++ b/tests/auto/qmenu/tst_qmenu.cpp @@ -440,7 +440,9 @@ void tst_QMenu::overrideMenuAction() m->addAction(aQuit); w.show(); + QApplication::setActiveWindow(&w); w.setFocus(); + QTest::qWaitForWindowShown(&w); QTRY_VERIFY(w.hasFocus()); //test of the action inside the menu diff --git a/tests/auto/qspinbox/tst_qspinbox.cpp b/tests/auto/qspinbox/tst_qspinbox.cpp index 80f185a..69347c4 100644 --- a/tests/auto/qspinbox/tst_qspinbox.cpp +++ b/tests/auto/qspinbox/tst_qspinbox.cpp @@ -752,8 +752,8 @@ void tst_QSpinBox::editingFinished() testFocusWidget->show(); QApplication::setActiveWindow(testFocusWidget); + QTest::qWaitForWindowShown(testFocusWidget); box->activateWindow(); - QTest::qWait(100);//qApp->processEvents(); box->setFocus(); QTRY_COMPARE(qApp->focusWidget(), box); diff --git a/tests/auto/qstyle/tst_qstyle.cpp b/tests/auto/qstyle/tst_qstyle.cpp index 8526be1..56776d7 100644 --- a/tests/auto/qstyle/tst_qstyle.cpp +++ b/tests/auto/qstyle/tst_qstyle.cpp @@ -219,7 +219,7 @@ void tst_QStyle::testStyleFactory() foreach (QString styleName , keys) { QStyle *style = QStyleFactory::create(styleName); - QVERIFY(style != 0); + QVERIFY2(style != 0, qPrintable(QString::fromLatin1("Fail to load style '%1'").arg(styleName))); delete style; } } diff --git a/tests/auto/qtableview/tst_qtableview.cpp b/tests/auto/qtableview/tst_qtableview.cpp index ce13d31..f5d5040 100644 --- a/tests/auto/qtableview/tst_qtableview.cpp +++ b/tests/auto/qtableview/tst_qtableview.cpp @@ -2908,11 +2908,11 @@ void tst_QTableView::tabFocus() QLineEdit *edit = new QLineEdit(&window); window.show(); + QApplication::setActiveWindow(&window); QTest::qWaitForWindowShown(&window); window.setFocus(); QTest::qWait(100); window.activateWindow(); - QApplication::setActiveWindow(&window); QTest::qWait(100); qApp->processEvents(); diff --git a/tests/auto/qtextbrowser/tst_qtextbrowser.cpp b/tests/auto/qtextbrowser/tst_qtextbrowser.cpp index 1f06dcf..829d580 100644 --- a/tests/auto/qtextbrowser/tst_qtextbrowser.cpp +++ b/tests/auto/qtextbrowser/tst_qtextbrowser.cpp @@ -63,10 +63,8 @@ class TestBrowser : public QTextBrowser public: inline TestBrowser() : htmlLoadAttempts(0) { show(); -#ifdef Q_WS_X11 - qt_x11_wait_for_window_manager(this); -#endif QApplication::setActiveWindow(this); + QTest::qWaitForWindowShown(this); activateWindow(); setFocus(); QTest::qWait(50); -- cgit v0.12 From b3f3ab74f07cbadb568a5e8ad4363f1e042ea40c Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 23 Sep 2009 20:30:21 +0200 Subject: Fix 3.1 build - move unimplemented RFs API to the S60 plugin RFs::GetSystemDrive doesn't exist in 3.1 (even though it is in the symbian documentation). Moved it to a new function in the S60 plugins. For 3.1, it returns EDriveC, for all other versions the RFs API is used Task-number: QT-805 Reviewed-by: Iain --- src/corelib/kernel/qcore_symbian_p.h | 3 +- src/corelib/kernel/qcoreapplication.cpp | 12 +++++-- src/plugins/s60/3_1/3_1.pro | 3 +- src/plugins/s60/3_2/3_2.pro | 8 +++-- src/plugins/s60/5_0/5_0.pro | 8 +++-- src/plugins/s60/bwins/qts60pluginu.def | 2 ++ src/plugins/s60/eabi/qts60pluginu.def | 2 ++ src/plugins/s60/src/qcoreapplication_3_1.cpp | 48 ++++++++++++++++++++++++++++ src/plugins/s60/src/qcoreapplication_3_2.cpp | 48 ++++++++++++++++++++++++++++ 9 files changed, 124 insertions(+), 10 deletions(-) create mode 100644 src/plugins/s60/src/qcoreapplication_3_1.cpp create mode 100644 src/plugins/s60/src/qcoreapplication_3_2.cpp diff --git a/src/corelib/kernel/qcore_symbian_p.h b/src/corelib/kernel/qcore_symbian_p.h index 5b243dc..56097bc 100644 --- a/src/corelib/kernel/qcore_symbian_p.h +++ b/src/corelib/kernel/qcore_symbian_p.h @@ -138,7 +138,8 @@ enum S60PluginFuncOrdinals S60Plugin_GetTimeFormatSpec = 2, S60Plugin_GetLongDateFormatSpec = 3, S60Plugin_GetShortDateFormatSpec = 4, - S60Plugin_LocalizedDirectoryName = 5 + S60Plugin_LocalizedDirectoryName = 5, + S60Plugin_GetSystemDrive = 6 }; Q_CORE_EXPORT TLibraryFunction qt_resolveS60PluginFunc(int ordinal); diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 9a93685..61b9ee7 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -111,6 +111,11 @@ private: QMutex *mtx; }; +#ifdef Q_OS_SYMBIAN +typedef TDriveNumber (*SystemDriveFunc)(RFs&); +static SystemDriveFunc PtrGetSystemDrive=0; +#endif + #if defined(Q_WS_WIN) || defined(Q_WS_MAC) extern QString qAppFileName(); #endif @@ -1820,8 +1825,11 @@ QString QCoreApplication::applicationDirPath() } if (err != KErrNone || (driveInfo.iDriveAtt & KDriveAttRom) || (driveInfo.iMediaAtt & KMediaAttWriteProtected)) { - driveChar = fs.GetSystemDriveChar(); - drive = fs.GetSystemDrive(); + if(!PtrGetSystemDrive) + PtrGetSystemDrive = reinterpret_cast(qt_resolveS60PluginFunc(S60Plugin_GetSystemDrive)); + Q_ASSERT(PtrGetSystemDrive); + drive = PtrGetSystemDrive(fs); + fs.DriveToChar(drive, driveChar); } qDriveChar = QChar(QLatin1Char(driveChar)).toUpper(); diff --git a/src/plugins/s60/3_1/3_1.pro b/src/plugins/s60/3_1/3_1.pro index 568a33c..58ff5ce 100644 --- a/src/plugins/s60/3_1/3_1.pro +++ b/src/plugins/s60/3_1/3_1.pro @@ -3,6 +3,7 @@ include(../s60pluginbase.pri) TARGET = qts60plugin_3_1 SOURCES += ../src/qlocale_3_1.cpp \ - ../src/qdesktopservices_3_1.cpp + ../src/qdesktopservices_3_1.cpp \ + ../src/qcoreapplication_3_1.cpp TARGET.UID3=0x2001E620 diff --git a/src/plugins/s60/3_2/3_2.pro b/src/plugins/s60/3_2/3_2.pro index 97409d3..4b28eb9 100644 --- a/src/plugins/s60/3_2/3_2.pro +++ b/src/plugins/s60/3_2/3_2.pro @@ -4,11 +4,13 @@ TARGET = qts60plugin_3_2 contains(S60_VERSION, 3.1) { SOURCES += ../src/qlocale_3_1.cpp \ - ../src/qdesktopservices_3_1.cpp + ../src/qdesktopservices_3_1.cpp \ + ../src/qcoreapplication_3_1.cpp } else { SOURCES += ../src/qlocale_3_2.cpp \ - ../src/qdesktopservices_3_2.cpp - LIBS += -ldirectorylocalizer + ../src/qdesktopservices_3_2.cpp \ + ../src/qcoreapplication_3_2.cpp + LIBS += -ldirectorylocalizer -lefsrv INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE } diff --git a/src/plugins/s60/5_0/5_0.pro b/src/plugins/s60/5_0/5_0.pro index d7c3cb2..4cdce12 100644 --- a/src/plugins/s60/5_0/5_0.pro +++ b/src/plugins/s60/5_0/5_0.pro @@ -4,11 +4,13 @@ TARGET = qts60plugin_5_0 contains(S60_VERSION, 3.1) { SOURCES += ../src/qlocale_3_1.cpp \ - ../src/qdesktopservices_3_1.cpp + ../src/qdesktopservices_3_1.cpp \ + ../src/qcoreapplication_3_1.cpp } else { SOURCES += ../src/qlocale_3_2.cpp \ - ../src/qdesktopservices_3_2.cpp - LIBS += -ldirectorylocalizer + ../src/qdesktopservices_3_2.cpp \ + ../src/qcoreapplication_3_2.cpp + LIBS += -ldirectorylocalizer -lefsrv INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE } diff --git a/src/plugins/s60/bwins/qts60pluginu.def b/src/plugins/s60/bwins/qts60pluginu.def index a082262..b4110a9 100644 --- a/src/plugins/s60/bwins/qts60pluginu.def +++ b/src/plugins/s60/bwins/qts60pluginu.def @@ -4,3 +4,5 @@ EXPORTS ?defaultGetLongDateFormatSpec@@YA?AVTPtrC16@@AAVTExtendedLocale@@@Z @ 3 NONAME ; class TPtrC16 defaultGetLongDateFormatSpec(class TExtendedLocale &) ?defaultGetShortDateFormatSpec@@YA?AVTPtrC16@@AAVTExtendedLocale@@@Z @ 4 NONAME ; class TPtrC16 defaultGetShortDateFormatSpec(class TExtendedLocale &) ?localizedDirectoryName@@YA?AVQString@@AAV1@@Z @ 5 NONAME ; class QString localizedDirectoryName(class QString &) + ?systemDrive@@YA?AW4TDriveNumber@@AAVRFs@@@Z @ 6 NONAME ; enum TDriveNumber systemDrive(class RFs &) + diff --git a/src/plugins/s60/eabi/qts60pluginu.def b/src/plugins/s60/eabi/qts60pluginu.def index d768436..df7895c 100644 --- a/src/plugins/s60/eabi/qts60pluginu.def +++ b/src/plugins/s60/eabi/qts60pluginu.def @@ -4,3 +4,5 @@ EXPORTS _Z28defaultGetLongDateFormatSpecR15TExtendedLocale @ 3 NONAME _Z29defaultGetShortDateFormatSpecR15TExtendedLocale @ 4 NONAME _Z22localizedDirectoryNameR7QString @ 5 NONAME + _Z11systemDriveR3RFs @ 6 NONAME + diff --git a/src/plugins/s60/src/qcoreapplication_3_1.cpp b/src/plugins/s60/src/qcoreapplication_3_1.cpp new file mode 100644 index 0000000..c7627ce --- /dev/null +++ b/src/plugins/s60/src/qcoreapplication_3_1.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +EXPORT_C TDriveNumber systemDrive(RFs&) +{ + return EDriveC; +} diff --git a/src/plugins/s60/src/qcoreapplication_3_2.cpp b/src/plugins/s60/src/qcoreapplication_3_2.cpp new file mode 100644 index 0000000..8d2794e --- /dev/null +++ b/src/plugins/s60/src/qcoreapplication_3_2.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +EXPORT_C TDriveNumber systemDrive(RFs& fs) +{ + return fs.GetSystemDrive(); +} -- cgit v0.12 From 5c5a6b387319095a2c2a589bb1e1d67b51854fc1 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 23 Sep 2009 20:21:17 +0200 Subject: Fix tst_QWidget::activateWindow on X11 On X11 one needs to wait logner for the reply for the window mabager All the QWidget tests passes on my X11 in about 30seconds now --- tests/auto/qwidget/tst_qwidget.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 126d571..d34d3c5 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -9232,9 +9232,10 @@ void tst_QWidget::activateWindow() mainwindow->setCentralWidget(label); mainwindow->setVisible(true); mainwindow->activateWindow(); + QTest::qWaitForWindowShown(&mainWindow); qApp->processEvents(); - QVERIFY(mainwindow->isActiveWindow()); + QTRY_VERIFY(mainwindow->isActiveWindow()); // Create second mainwindow and set it active QMainWindow* mainwindow2 = new QMainWindow(); @@ -9244,16 +9245,16 @@ void tst_QWidget::activateWindow() mainwindow2->activateWindow(); qApp->processEvents(); - QVERIFY(!mainwindow->isActiveWindow()); - QVERIFY(mainwindow2->isActiveWindow()); + QTRY_VERIFY(!mainwindow->isActiveWindow()); + QTRY_VERIFY(mainwindow2->isActiveWindow()); // Revert first mainwindow back to visible active mainwindow->setVisible(true); mainwindow->activateWindow(); qApp->processEvents(); - QVERIFY(mainwindow->isActiveWindow()); - QVERIFY(!mainwindow2->isActiveWindow()); + QTRY_VERIFY(mainwindow->isActiveWindow()); + QTRY_VERIFY(!mainwindow2->isActiveWindow()); } #ifdef Q_OS_SYMBIAN -- cgit v0.12 From f6b942b88ed2519b73c540120fde73390716173f Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 23 Sep 2009 21:03:01 +0200 Subject: Stabilize more tests --- tests/auto/q3table/tst_q3table.cpp | 4 + tests/auto/qstackedlayout/tst_qstackedlayout.cpp | 3 +- tests/auto/qwidget/tst_qwidget.cpp | 177 ++++++++++++----------- 3 files changed, 95 insertions(+), 89 deletions(-) diff --git a/tests/auto/q3table/tst_q3table.cpp b/tests/auto/q3table/tst_q3table.cpp index ca65852..f911dd4 100644 --- a/tests/auto/q3table/tst_q3table.cpp +++ b/tests/auto/q3table/tst_q3table.cpp @@ -51,6 +51,8 @@ #include #include +#include "../../shared/util.h" + #define WAITS 1 #ifdef WAITS #endif @@ -499,6 +501,8 @@ void tst_Q3Table::pageUpDownNavigation() void tst_Q3Table::simpleKeyboardNavigation() { + QApplication::setActiveWindow(testWidget); + QTRY_COMPARE(QApplication::activeWindow(), testWidget); QWidget *w; // Test for task #24726 diff --git a/tests/auto/qstackedlayout/tst_qstackedlayout.cpp b/tests/auto/qstackedlayout/tst_qstackedlayout.cpp index cdf84811..51f6c03 100644 --- a/tests/auto/qstackedlayout/tst_qstackedlayout.cpp +++ b/tests/auto/qstackedlayout/tst_qstackedlayout.cpp @@ -353,8 +353,9 @@ void tst_QStackedLayout::keepFocusAfterSetCurrent() stackLayout->setCurrentIndex(0); testWidget->show(); - QTest::qWait(25); QApplication::setActiveWindow(testWidget); + QTest::qWaitForWindowShown(testWidget); + QApplication::processEvents(); edit1->setFocus(); edit1->activateWindow(); diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index d34d3c5..2e66da2 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -2304,8 +2304,8 @@ void tst_QWidget::showMinimizedKeepsFocus() QCOMPARE(qApp->focusWidget(), static_cast(0)); window.showMinimized(); - QTest::qWait(100); - QVERIFY(window.isMinimized()); + QTest::qWait(30); + QTRY_VERIFY(window.isMinimized()); #ifdef Q_WS_QWS QEXPECT_FAIL("", "QWS does not implement showMinimized()", Continue); #endif @@ -2935,7 +2935,7 @@ void tst_QWidget::stackUnder() if (expectedPaintEvents == 1 && child->numPaintEvents == 2) QEXPECT_FAIL(0, "Mac and Windows issues double repaints for Z-Order change", Continue); #endif - QCOMPARE(child->numPaintEvents, expectedPaintEvents); + QTRY_COMPARE(child->numPaintEvents, expectedPaintEvents); QCOMPARE(child->numZOrderChangeEvents, 0); child->reset(); } @@ -3158,13 +3158,14 @@ void tst_QWidget::saveRestoreGeometry() widget.resize(size); QTest::qWait(20); QTRY_COMPARE(widget.size(), size); - QTest::qWait(100); + QTest::qWait(200); savedGeometry = widget.saveGeometry(); geom = widget.geometry(); widget.setWindowState(widget.windowState() | Qt::WindowMaximized); QTest::qWait(20); QTRY_VERIFY((widget.windowState() & Qt::WindowMaximized)); QTRY_VERIFY(widget.geometry() != geom); + QTest::qWait(100); QVERIFY(widget.restoreGeometry(savedGeometry)); QTest::qWait(20); QTRY_COMPARE(widget.geometry(), geom); @@ -3175,13 +3176,13 @@ void tst_QWidget::saveRestoreGeometry() widget.setWindowState(widget.windowState() | Qt::WindowMaximized); QTest::qWait(20); QTRY_VERIFY((widget.windowState() & Qt::WindowMaximized)); - QTest::qWait(100); + QTest::qWait(200); geom = widget.geometry(); savedGeometry = widget.saveGeometry(); widget.setWindowState(widget.windowState() ^ Qt::WindowMaximized); QTest::qWait(20); QTRY_VERIFY(!(widget.windowState() & Qt::WindowMaximized)); - QTest::qWait(20); + QTest::qWait(200); QVERIFY(widget.restoreGeometry(savedGeometry)); QTest::qWait(20); QTRY_VERIFY((widget.windowState() & Qt::WindowMaximized)); @@ -3245,8 +3246,8 @@ void tst_QWidget::restoreVersion1Geometry() QTest::qWait(100); if (expectedWindowState == Qt::WindowNoState) { - QCOMPARE(widget.pos(), expectedPosition); - QCOMPARE(widget.size(), expectedSize); + QTRY_COMPARE(widget.pos(), expectedPosition); + QTRY_COMPARE(widget.size(), expectedSize); } widget.showNormal(); @@ -5277,14 +5278,19 @@ public: const QRegion r = QRegion(region); \ for (int i = 0; i < r.rects().size(); ++i) { \ const QRect rect = r.rects().at(i); \ - const QPixmap pixmap = QPixmap::grabWindow(QDesktopWidget().winId(), \ + for (int t = 0; t < 5; t++) { \ + const QPixmap pixmap = QPixmap::grabWindow(QDesktopWidget().winId(), \ rect.left(), rect.top(), \ rect.width(), rect.height()); \ - QCOMPARE(pixmap.size(), rect.size()); \ - QPixmap expectedPixmap(pixmap); /* ensure equal formats */ \ - expectedPixmap.fill(color); \ - QCOMPARE(pixmap.toImage().pixel(0,0), QColor(color).rgb()); \ - QCOMPARE(pixmap, expectedPixmap); \ + QCOMPARE(pixmap.size(), rect.size()); \ + QPixmap expectedPixmap(pixmap); /* ensure equal formats */ \ + expectedPixmap.fill(color); \ + if (pixmap.toImage().pixel(0,0) != QColor(color).rgb() && t < 4 ) \ + { QTest::qWait(200); continue; } \ + QCOMPARE(pixmap.toImage().pixel(0,0), QColor(color).rgb()); \ + QCOMPARE(pixmap, expectedPixmap); \ + break; \ + } \ } \ } @@ -5324,8 +5330,8 @@ void tst_QWidget::moveChild() #ifdef QT_MAC_USE_COCOA QEXPECT_FAIL(0, "Cocoa compositor paints the entire content view, even when opaque", Continue); #endif - QCOMPARE(parent.r, QRegion(parent.rect()) - child.geometry()); - QCOMPARE(child.r, QRegion(child.rect())); + QTRY_COMPARE(parent.r, QRegion(parent.rect()) - child.geometry()); + QTRY_COMPARE(child.r, QRegion(child.rect())); VERIFY_COLOR(child.geometry().translated(tlwOffset), child.color); VERIFY_COLOR(QRegion(parent.geometry()) - child.geometry().translated(tlwOffset), @@ -5340,7 +5346,7 @@ void tst_QWidget::moveChild() QPoint pos = child.pos() + offset; child.move(pos); QTest::qWait(100); - QCOMPARE(pos, child.pos()); + QTRY_COMPARE(pos, child.pos()); QCOMPARE(parent.r, QRegion(oldGeometry) - child.geometry()); #if !defined(Q_WS_MAC) @@ -7388,8 +7394,8 @@ void tst_QWidget::repaintWhenChildDeleted() #endif w.show(); QTest::qWaitForWindowShown(&w); - QTest::qWait(30); - QCOMPARE(w.r, QRegion(w.rect())); + QTest::qWait(10); + QTRY_COMPARE(w.r, QRegion(w.rect())); w.r = QRegion(); { @@ -7397,13 +7403,13 @@ void tst_QWidget::repaintWhenChildDeleted() ColorWidget child(&w, Qt::blue); child.setGeometry(10, 10, 10, 10); child.show(); - QTest::qWait(100); - QCOMPARE(child.r, QRegion(child.rect())); + QTest::qWait(10); + QTRY_COMPARE(child.r, QRegion(child.rect())); w.r = QRegion(); } - QTest::qWait(100); - QCOMPARE(w.r, QRegion(10, 10, 10, 10)); + QTest::qWait(10); + QTRY_COMPARE(w.r, QRegion(10, 10, 10, 10)); } // task 175114 @@ -8070,10 +8076,8 @@ void tst_QWidget::resizeInPaintEvent() QWidget window; UpdateWidget widget(&window); window.show(); -#ifdef Q_WS_X11 - qt_x11_wait_for_window_manager(&window); -#endif - QTest::qWait(100); + QTest::qWaitForWindowShown(&window); + QTRY_VERIFY(widget.numPaintEvents > 0); widget.reset(); QCOMPARE(widget.numPaintEvents, 0); @@ -8085,9 +8089,9 @@ void tst_QWidget::resizeInPaintEvent() QCOMPARE(widget.numPaintEvents, 1); widget.numPaintEvents = 0; - QTest::qWait(100); + QTest::qWait(10); // Make sure the resize triggers another update. - QCOMPARE(widget.numPaintEvents, 1); + QTRY_COMPARE(widget.numPaintEvents, 1); } #endif @@ -8597,8 +8601,7 @@ void tst_QWidget::setClearAndResizeMask() topLevel.resize(150, 150); topLevel.show(); QTest::qWaitForWindowShown(&topLevel); - QTest::qWait(40); - + QTRY_VERIFY(topLevel.numPaintEvents > 0); topLevel.reset(); // Mask top-level widget @@ -8615,20 +8618,20 @@ void tst_QWidget::setClearAndResizeMask() // Clear top-level mask topLevel.clearMask(); QCOMPARE(topLevel.mask(), QRegion()); - QTest::qWait(100); + QTest::qWait(10); QRegion outsideOldMask(topLevel.rect()); outsideOldMask -= topLevelMask; #if defined(Q_WS_WIN) || defined(Q_WS_X11) // We don't control what's happening on other platforms. // and ensure that the top-level gets an update for the area outside the old mask. QTRY_VERIFY(topLevel.numPaintEvents > 0); - QCOMPARE(topLevel.paintedRegion, outsideOldMask); + QTRY_COMPARE(topLevel.paintedRegion, outsideOldMask); #endif UpdateWidget child(&topLevel); child.setAutoFillBackground(true); // NB! Opaque child. child.resize(100, 100); child.show(); - QTest::qWait(50); + QTest::qWait(10); child.reset(); topLevel.reset(); @@ -8656,10 +8659,10 @@ void tst_QWidget::setClearAndResizeMask() // Clear child widget mask child.clearMask(); - QCOMPARE(child.mask(), QRegion()); - QTest::qWait(50); + QTRY_COMPARE(child.mask(), QRegion()); + QTest::qWait(10); // and ensure that that the child widget gets an update for the area outside the old mask. - QCOMPARE(child.numPaintEvents, 1); + QTRY_COMPARE(child.numPaintEvents, 1); outsideOldMask = child.rect(); #ifndef Q_WS_MAC // Mac always issues a full update when calling setMask, and we cannot force it to not do so. @@ -8674,10 +8677,10 @@ void tst_QWidget::setClearAndResizeMask() // Mask child widget with a mask that is bigger than the rect child.setMask(QRegion(0, 0, 1000, 1000)); - QTest::qWait(50); + QTest::qWait(10); #ifdef Q_WS_MAC // Mac always issues a full update when calling setMask, and we cannot force it to not do so. - QCOMPARE(child.numPaintEvents, 1); + QTRY_COMPARE(child.numPaintEvents, 1); #else // and ensure that we don't get any updates at all. QCOMPARE(child.numPaintEvents, 0); @@ -8686,10 +8689,10 @@ void tst_QWidget::setClearAndResizeMask() // ...and the same applies when clearing the mask. child.clearMask(); - QTest::qWait(50); + QTest::qWait(10); #ifdef Q_WS_MAC // Mac always issues a full update when calling setMask, and we cannot force it to not do so. - QVERIFY(child.numPaintEvents > 0); + QTRY_VERIFY(child.numPaintEvents > 0); #else QCOMPARE(child.numPaintEvents, 0); #endif @@ -8752,10 +8755,9 @@ void tst_QWidget::maskedUpdate() grandChild.setMask(grandChildMask); topLevel.show(); -#ifdef Q_WS_X11 - qt_x11_wait_for_window_manager(&topLevel); -#endif - QTest::qWait(200); + QTest::qWaitForWindowShown(&topLevel); + QTRY_VERIFY(topLevel.numPaintEvents > 0); + #define RESET_WIDGETS \ topLevel.reset(); \ @@ -8773,29 +8775,29 @@ void tst_QWidget::maskedUpdate() // TopLevel update. RESET_WIDGETS; topLevel.update(); - QTest::qWait(100); + QTest::qWait(10); - QCOMPARE(topLevel.paintedRegion, topLevelMask); - QCOMPARE(child.paintedRegion, childMask); - QCOMPARE(grandChild.paintedRegion, grandChildMask); + QTRY_COMPARE(topLevel.paintedRegion, topLevelMask); + QTRY_COMPARE(child.paintedRegion, childMask); + QTRY_COMPARE(grandChild.paintedRegion, grandChildMask); // Child update. RESET_WIDGETS; child.update(); - QTest::qWait(100); + QTest::qWait(10); - QCOMPARE(topLevel.paintedRegion, childMask.translated(child.pos())); - QCOMPARE(child.paintedRegion, childMask); - QCOMPARE(grandChild.paintedRegion, grandChildMask); + QTRY_COMPARE(topLevel.paintedRegion, childMask.translated(child.pos())); + QTRY_COMPARE(child.paintedRegion, childMask); + QTRY_COMPARE(grandChild.paintedRegion, grandChildMask); // GrandChild update. RESET_WIDGETS; grandChild.update(); - QTest::qWait(100); + QTest::qWait(10); - QCOMPARE(topLevel.paintedRegion, grandChildMask.translated(grandChild.mapTo(&topLevel, QPoint()))); - QCOMPARE(child.paintedRegion, grandChildMask.translated(grandChild.pos())); - QCOMPARE(grandChild.paintedRegion, grandChildMask); + QTRY_COMPARE(topLevel.paintedRegion, grandChildMask.translated(grandChild.mapTo(&topLevel, QPoint()))); + QTRY_COMPARE(child.paintedRegion, grandChildMask.translated(grandChild.pos())); + QTRY_COMPARE(grandChild.paintedRegion, grandChildMask); topLevel.setAttribute(Qt::WA_OpaquePaintEvent); child.setAttribute(Qt::WA_OpaquePaintEvent); @@ -8807,41 +8809,41 @@ void tst_QWidget::maskedUpdate() // TopLevel update. RESET_WIDGETS; topLevel.update(); - QTest::qWait(100); + QTest::qWait(10); QRegion expectedTopLevelUpdate = topLevelMask; expectedTopLevelUpdate -= childMask.translated(child.pos()); // Subtract opaque children. - QCOMPARE(topLevel.paintedRegion, expectedTopLevelUpdate); - QCOMPARE(child.paintedRegion, QRegion()); - QCOMPARE(grandChild.paintedRegion, QRegion()); + QTRY_COMPARE(topLevel.paintedRegion, expectedTopLevelUpdate); + QTRY_COMPARE(child.paintedRegion, QRegion()); + QTRY_COMPARE(grandChild.paintedRegion, QRegion()); // Child update. RESET_WIDGETS; child.update(); - QTest::qWait(100); + QTest::qWait(10); - QCOMPARE(topLevel.paintedRegion, QRegion()); + QTRY_COMPARE(topLevel.paintedRegion, QRegion()); QRegion expectedChildUpdate = childMask; expectedChildUpdate -= grandChildMask.translated(grandChild.pos()); // Subtract oapque children. - QCOMPARE(child.paintedRegion, expectedChildUpdate); - QCOMPARE(grandChild.paintedRegion, QRegion()); + QTRY_COMPARE(child.paintedRegion, expectedChildUpdate); + QTRY_COMPARE(grandChild.paintedRegion, QRegion()); // GrandChild update. RESET_WIDGETS; grandChild.update(); - QTest::qWait(100); + QTest::qWait(10); - QCOMPARE(topLevel.paintedRegion, QRegion()); - QCOMPARE(child.paintedRegion, QRegion()); - QCOMPARE(grandChild.paintedRegion, grandChildMask); + QTRY_COMPARE(topLevel.paintedRegion, QRegion()); + QTRY_COMPARE(child.paintedRegion, QRegion()); + QTRY_COMPARE(grandChild.paintedRegion, grandChildMask); // GrandChild update. CLEAR_MASK(grandChild); grandChild.update(); - QTest::qWait(100); + QTest::qWait(10); - QCOMPARE(topLevel.paintedRegion, QRegion()); - QCOMPARE(child.paintedRegion, QRegion()); + QTRY_COMPARE(topLevel.paintedRegion, QRegion()); + QTRY_COMPARE(child.paintedRegion, QRegion()); QRegion expectedGrandChildUpdate = grandChild.rect(); // Clip with parent's mask. expectedGrandChildUpdate &= childMask.translated(-grandChild.pos()); @@ -8850,36 +8852,36 @@ void tst_QWidget::maskedUpdate() // GrandChild update. CLEAR_MASK(child); grandChild.update(); - QTest::qWait(100); + QTest::qWait(10); - QCOMPARE(topLevel.paintedRegion, QRegion()); - QCOMPARE(child.paintedRegion, QRegion()); + QTRY_COMPARE(topLevel.paintedRegion, QRegion()); + QTRY_COMPARE(child.paintedRegion, QRegion()); expectedGrandChildUpdate = grandChild.rect(); // Clip with parent's mask. expectedGrandChildUpdate &= topLevelMask.translated(-grandChild.mapTo(&topLevel, QPoint())); - QCOMPARE(grandChild.paintedRegion, expectedGrandChildUpdate); + QTRY_COMPARE(grandChild.paintedRegion, expectedGrandChildUpdate); // Child update. RESET_WIDGETS; child.update(); - QTest::qWait(100); + QTest::qWait(10); - QCOMPARE(topLevel.paintedRegion, QRegion()); + QTRY_COMPARE(topLevel.paintedRegion, QRegion()); expectedChildUpdate = child.rect(); // Clip with parent's mask. expectedChildUpdate &= topLevelMask.translated(-child.pos()); expectedChildUpdate -= grandChild.geometry(); // Subtract opaque children. - QCOMPARE(child.paintedRegion, expectedChildUpdate); - QCOMPARE(grandChild.paintedRegion, QRegion()); + QTRY_COMPARE(child.paintedRegion, expectedChildUpdate); + QTRY_COMPARE(grandChild.paintedRegion, QRegion()); // GrandChild update. CLEAR_MASK(topLevel); grandChild.update(); - QTest::qWait(100); + QTest::qWait(10); - QCOMPARE(topLevel.paintedRegion, QRegion()); - QCOMPARE(child.paintedRegion, QRegion()); - QCOMPARE(grandChild.paintedRegion, QRegion(grandChild.rect())); // Full update. + QTRY_COMPARE(topLevel.paintedRegion, QRegion()); + QTRY_COMPARE(child.paintedRegion, QRegion()); + QTRY_COMPARE(grandChild.paintedRegion, QRegion(grandChild.rect())); // Full update. } #if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_QWS) @@ -9164,16 +9166,15 @@ void tst_QWidget::rectOutsideCoordinatesLimit_task144779() main.show(); QTest::qWaitForWindowShown(&main); - QTest::qWait(10); + QTest::qWait(50); QCursor::setPos(main.pos()); //get the cursor out of the picture QTest::qWait(50); - QPixmap pixmap = QPixmap::grabWindow(main.winId()); QPixmap correct(main.size()); correct.fill(Qt::green); QRect center(100, 100, 200, 200); // to avoid the decorations - QCOMPARE(pixmap.toImage().copy(center), correct.toImage().copy(center)); + QTRY_COMPARE(QPixmap::grabWindow(main.winId()).toImage().copy(center), correct.toImage().copy(center)); } void tst_QWidget::inputFocus_task257832() @@ -9232,7 +9233,7 @@ void tst_QWidget::activateWindow() mainwindow->setCentralWidget(label); mainwindow->setVisible(true); mainwindow->activateWindow(); - QTest::qWaitForWindowShown(&mainWindow); + QTest::qWaitForWindowShown(mainwindow); qApp->processEvents(); QTRY_VERIFY(mainwindow->isActiveWindow()); -- cgit v0.12 From 63299bbbc34521785408163e3fd516779f343201 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 24 Sep 2009 09:50:04 +1000 Subject: Fix cubic paths in OpenVG The multitouch/dials example was displaying rendering artifacts on the dials in the default style. This was due to incorrect VGPath construction when sizeof(qreal) == sizeof(VGfloat). It was adding two VG_CUBIC_TO_ABS elements per cubic instead of one. Task-number: QT-2035 Reviewed-by: Sarah Smith --- src/openvg/qpaintengine_vg.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index 34f9cf8..3558c28 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -566,11 +566,11 @@ VGPath QVGPaintEnginePrivate::vectorPathToVGPath(const QVectorPath& path) case QPainterPath::LineToElement: segments.append(VG_LINE_TO_ABS); break; - case QPainterPath::CurveToElement: break; - - case QPainterPath::CurveToDataElement: + case QPainterPath::CurveToElement: segments.append(VG_CUBIC_TO_ABS); break; + case QPainterPath::CurveToDataElement: break; + } } if (path.hasImplicitClose()) -- cgit v0.12 From 94c7ea4ad2c12c11d1cdc33bc0455f6f0b432fc2 Mon Sep 17 00:00:00 2001 From: Bill King Date: Thu, 24 Sep 2009 10:04:19 +1000 Subject: Remove extraneous debug statement --- tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp index 073afae..49e087f 100644 --- a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp +++ b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp @@ -1037,8 +1037,6 @@ void tst_QSqlTableModel::insertBeforeDelete() model.setEditStrategy(QSqlTableModel::OnManualSubmit); QVERIFY_SQL(model, select()); - qDebug() << model.rowCount(); - QSqlRecord rec = model.record(); rec.setValue(0, 4); rec.setValue(1, QString("bill")); -- cgit v0.12 From b94e0ed8fafef214c0c549ebfb4b39338bece4a1 Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Thu, 24 Sep 2009 11:41:43 +1000 Subject: Mac audio; Remove signal re-decleration. Reviewed-by: Bill King --- src/multimedia/audio/qaudioinput_mac_p.h | 4 ---- src/multimedia/audio/qaudiooutput_mac_p.h | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/multimedia/audio/qaudioinput_mac_p.h b/src/multimedia/audio/qaudioinput_mac_p.h index b6cc5a7..a080648 100644 --- a/src/multimedia/audio/qaudioinput_mac_p.h +++ b/src/multimedia/audio/qaudioinput_mac_p.h @@ -145,10 +145,6 @@ public: void startTimers(); void stopTimers(); -signals: - void stateChanged(QAudio::State); - void notify(); - private slots: void deviceStopped(); diff --git a/src/multimedia/audio/qaudiooutput_mac_p.h b/src/multimedia/audio/qaudiooutput_mac_p.h index d5097dc..04b3239 100644 --- a/src/multimedia/audio/qaudiooutput_mac_p.h +++ b/src/multimedia/audio/qaudiooutput_mac_p.h @@ -145,10 +145,6 @@ public: void startTimers(); void stopTimers(); -signals: - void stateChanged(QAudio::State); - void notify(); - private slots: void deviceStopped(); void inputReady(); -- cgit v0.12 From 609dd32580b1e07213a2b2efdd4d854c34e8f6d7 Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Thu, 24 Sep 2009 11:46:06 +1000 Subject: Mac audio; emit stateChanged on start, don't flush in push mode. Reviewed-by: Bill King --- src/multimedia/audio/qaudioinput_mac_p.cpp | 7 +++++++ src/multimedia/audio/qaudiooutput_mac_p.cpp | 2 ++ 2 files changed, 9 insertions(+) diff --git a/src/multimedia/audio/qaudioinput_mac_p.cpp b/src/multimedia/audio/qaudioinput_mac_p.cpp index ba5801a..07fa3f4 100644 --- a/src/multimedia/audio/qaudioinput_mac_p.cpp +++ b/src/multimedia/audio/qaudioinput_mac_p.cpp @@ -376,6 +376,9 @@ public: void flush(bool all = false) { + if (m_device == 0) + return; + const int used = m_buffer->used(); const int readSize = all ? used : used - (used % m_maxPeriodSize); @@ -723,6 +726,10 @@ QIODevice* QAudioInputPrivate::start(QIODevice* device) audioThreadStart(); + stateCode = QAudio::ActiveState; + errorCode = QAudio::NoError; + emit stateChanged(stateCode); + return op; } diff --git a/src/multimedia/audio/qaudiooutput_mac_p.cpp b/src/multimedia/audio/qaudiooutput_mac_p.cpp index bf9a096..4364704 100644 --- a/src/multimedia/audio/qaudiooutput_mac_p.cpp +++ b/src/multimedia/audio/qaudiooutput_mac_p.cpp @@ -460,6 +460,8 @@ QIODevice* QAudioOutputPrivate::start(QIODevice* device) if (stateCode == QAudio::ActiveState) audioThreadStart(); + emit stateChanged(stateCode); + return op; } -- cgit v0.12 From fb50411e4c0c132631f8237933fbb0972fa4c9aa Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Thu, 24 Sep 2009 11:55:52 +1000 Subject: AudioService API changes; QString->const QString&, remove QAudioDeviceId use QAudioDeviceInfo. Reviewed-by: Bill King --- doc/src/snippets/audio/main.cpp | 3 +- .../multimedia/audio/audiodevices/audiodevices.cpp | 32 ++-- .../multimedia/audio/audiodevices/audiodevices.h | 3 +- .../multimedia/audio/audioinput/audioinput.cpp | 6 +- examples/multimedia/audio/audioinput/audioinput.h | 2 +- .../multimedia/audio/audiooutput/audiooutput.cpp | 8 +- .../multimedia/audio/audiooutput/audiooutput.h | 2 +- src/multimedia/audio/audio.pri | 7 +- src/multimedia/audio/qaudiodevicefactory.cpp | 83 +++++----- src/multimedia/audio/qaudiodevicefactory_p.h | 17 +-- src/multimedia/audio/qaudiodeviceid.cpp | 168 --------------------- src/multimedia/audio/qaudiodeviceid.h | 94 ------------ src/multimedia/audio/qaudiodeviceid_p.h | 82 ---------- src/multimedia/audio/qaudiodeviceinfo.cpp | 164 ++++++++++++++++---- src/multimedia/audio/qaudiodeviceinfo.h | 32 ++-- src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp | 38 ++--- src/multimedia/audio/qaudiodeviceinfo_alsa_p.h | 6 +- src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp | 28 ++-- src/multimedia/audio/qaudiodeviceinfo_mac_p.h | 4 +- src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp | 38 ++--- src/multimedia/audio/qaudiodeviceinfo_win32_p.h | 6 +- src/multimedia/audio/qaudioformat.cpp | 2 +- src/multimedia/audio/qaudioformat.h | 2 +- src/multimedia/audio/qaudioinput.cpp | 10 +- src/multimedia/audio/qaudioinput.h | 5 +- src/multimedia/audio/qaudiooutput.cpp | 8 +- src/multimedia/audio/qaudiooutput.h | 4 +- tests/auto/qaudiodeviceid/qaudiodeviceid.pro | 7 - tests/auto/qaudiodeviceid/tst_qaudiodeviceid.cpp | 118 --------------- .../auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp | 8 +- tests/auto/qaudioinput/tst_qaudioinput.cpp | 2 +- tests/auto/qaudiooutput/tst_qaudiooutput.cpp | 2 +- 32 files changed, 302 insertions(+), 689 deletions(-) delete mode 100644 src/multimedia/audio/qaudiodeviceid.cpp delete mode 100644 src/multimedia/audio/qaudiodeviceid.h delete mode 100644 src/multimedia/audio/qaudiodeviceid_p.h delete mode 100644 tests/auto/qaudiodeviceid/qaudiodeviceid.pro delete mode 100644 tests/auto/qaudiodeviceid/tst_qaudiodeviceid.cpp diff --git a/doc/src/snippets/audio/main.cpp b/doc/src/snippets/audio/main.cpp index e663115..0910865 100644 --- a/doc/src/snippets/audio/main.cpp +++ b/doc/src/snippets/audio/main.cpp @@ -98,8 +98,7 @@ private: //![2] format.setSampleType(QAudioFormat::SignedInt); - QAudioDeviceId id = QAudioDeviceInfo::defaultOutputDevice(); - QAudioDeviceInfo info(id); + QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice()); if (!info.isFormatSupported(format)) format = info.nearestFormat(format); diff --git a/examples/multimedia/audio/audiodevices/audiodevices.cpp b/examples/multimedia/audio/audiodevices/audiodevices.cpp index 0d305ff..4198605 100644 --- a/examples/multimedia/audio/audiodevices/audiodevices.cpp +++ b/examples/multimedia/audio/audiodevices/audiodevices.cpp @@ -80,8 +80,6 @@ AudioTest::AudioTest( QMainWindow *parent, Qt::WFlags f ) 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); @@ -98,8 +96,8 @@ void AudioTest::test() logOutput->clear(); logOutput->append("NOTE: an invalid codec audio/test exists for testing, to get a fail condition."); - if(device) { - if(device->isFormatSupported(settings)) { + if (!deviceInfo.isNull()) { + if (deviceInfo.isFormatSupported(settings)) { logOutput->append("Success"); nearestFreq->setText(""); nearestChannel->setText(""); @@ -108,7 +106,7 @@ void AudioTest::test() nearestSampleType->setText(""); nearestEndian->setText(""); } else { - QAudioFormat nearest = device->nearestFormat(settings); + QAudioFormat nearest = deviceInfo.nearestFormat(settings); logOutput->append(tr("Failed")); nearestFreq->setText(QString("%1").arg(nearest.frequency())); nearestChannel->setText(QString("%1").arg(nearest.channels())); @@ -150,40 +148,34 @@ void AudioTest::modeChanged(int idx) 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))); - } + foreach (const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::deviceList(mode)) + deviceBox->addItem(deviceInfo.deviceName(), qVariantFromValue(deviceInfo)); } 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); + deviceInfo = deviceBox->itemData(idx).value(); frequencyBox->clear(); - QList freqz = device->supportedFrequencies(); + QList freqz = deviceInfo.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(); + QList chz = deviceInfo.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(); + QStringList codecz = deviceInfo.supportedCodecs(); for(int i = 0; i < codecz.size(); ++i) codecsBox->addItem(QString("%1").arg(codecz.at(i))); if(codecz.size()) @@ -192,14 +184,14 @@ void AudioTest::deviceChanged(int idx) codecsBox->addItem("audio/test"); sampleSizesBox->clear(); - QList sampleSizez = device->supportedSampleSizes(); + QList sampleSizez = deviceInfo.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(); + QList sampleTypez = deviceInfo.supportedSampleTypes(); for(int i = 0; i < sampleTypez.size(); ++i) { switch(sampleTypez.at(i)) { case QAudioFormat::SignedInt: @@ -219,7 +211,7 @@ void AudioTest::deviceChanged(int idx) } endianBox->clear(); - QList endianz = device->supportedByteOrders(); + QList endianz = deviceInfo.supportedByteOrders(); for(int i = 0; i < endianz.size(); ++i) { switch(endianz.at(i)) { case QAudioFormat::LittleEndian: diff --git a/examples/multimedia/audio/audiodevices/audiodevices.h b/examples/multimedia/audio/audiodevices/audiodevices.h index acf492d..5fe5547 100644 --- a/examples/multimedia/audio/audiodevices/audiodevices.h +++ b/examples/multimedia/audio/audiodevices/audiodevices.h @@ -60,8 +60,7 @@ public: AudioTest( QMainWindow *parent = 0, Qt::WFlags f = 0 ); virtual ~AudioTest(); - QAudioDeviceId deviceHandle; - QAudioDeviceInfo* device; + QAudioDeviceInfo deviceInfo; QAudioFormat settings; QAudio::Mode mode; diff --git a/examples/multimedia/audio/audioinput/audioinput.cpp b/examples/multimedia/audio/audioinput/audioinput.cpp index a586bf3..c09e7d9 100644 --- a/examples/multimedia/audio/audioinput/audioinput.cpp +++ b/examples/multimedia/audio/audioinput/audioinput.cpp @@ -250,9 +250,9 @@ InputTest::InputTest() layout->addWidget(canvas); deviceBox = new QComboBox(this); - QList devices = QAudioDeviceInfo::deviceList(QAudio::AudioInput); + 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))); + deviceBox->addItem(devices.at(i).deviceName(), qVariantFromValue(devices.at(i))); } connect(deviceBox,SIGNAL(activated(int)),SLOT(deviceChanged(int))); layout->addWidget(deviceBox); @@ -367,7 +367,7 @@ void InputTest::deviceChanged(int idx) audioInput->disconnect(this); delete audioInput; - device = deviceBox->itemData(idx).value(); + 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))); diff --git a/examples/multimedia/audio/audioinput/audioinput.h b/examples/multimedia/audio/audioinput/audioinput.h index c1bc602..7ba6f1f 100644 --- a/examples/multimedia/audio/audioinput/audioinput.h +++ b/examples/multimedia/audio/audioinput/audioinput.h @@ -116,7 +116,7 @@ public: InputTest(); ~InputTest(); - QAudioDeviceId device; + QAudioDeviceInfo device; QAudioFormat format; QAudioInput* audioInput; Spectrum* spec; diff --git a/examples/multimedia/audio/audiooutput/audiooutput.cpp b/examples/multimedia/audio/audiooutput/audiooutput.cpp index d239eb0..19f7a3f 100644 --- a/examples/multimedia/audio/audiooutput/audiooutput.cpp +++ b/examples/multimedia/audio/audiooutput/audiooutput.cpp @@ -142,10 +142,8 @@ AudioTest::AudioTest() 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))); - } + foreach (const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::deviceList(QAudio::AudioOutput)) + deviceBox->addItem(deviceInfo.deviceName(), qVariantFromValue(deviceInfo)); connect(deviceBox,SIGNAL(activated(int)),SLOT(deviceChanged(int))); layout->addWidget(deviceBox); @@ -200,7 +198,7 @@ void AudioTest::deviceChanged(int idx) audioOutput->disconnect(this); delete audioOutput; - device = deviceBox->itemData(idx).value(); + 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))); diff --git a/examples/multimedia/audio/audiooutput/audiooutput.h b/examples/multimedia/audio/audiooutput/audiooutput.h index e2c22ee..a5c0289 100644 --- a/examples/multimedia/audio/audiooutput/audiooutput.h +++ b/examples/multimedia/audio/audiooutput/audiooutput.h @@ -87,7 +87,7 @@ public: AudioTest(); ~AudioTest(); - QAudioDeviceId device; + QAudioDeviceInfo device; Generator* gen; QAudioOutput* audioOutput; QIODevice* output; diff --git a/src/multimedia/audio/audio.pri b/src/multimedia/audio/audio.pri index c7fbbb0..c445941 100644 --- a/src/multimedia/audio/audio.pri +++ b/src/multimedia/audio/audio.pri @@ -5,9 +5,7 @@ HEADERS += $$PWD/qaudio.h \ $$PWD/qaudiodeviceinfo.h \ $$PWD/qaudioengineplugin.h \ $$PWD/qaudioengine.h \ - $$PWD/qaudiodevicefactory_p.h \ - $$PWD/qaudiodeviceid.h \ - $$PWD/qaudiodeviceid_p.h + $$PWD/qaudiodevicefactory_p.h SOURCES += $$PWD/qaudio.cpp \ @@ -17,8 +15,7 @@ SOURCES += $$PWD/qaudio.cpp \ $$PWD/qaudioinput.cpp \ $$PWD/qaudioengineplugin.cpp \ $$PWD/qaudioengine.cpp \ - $$PWD/qaudiodevicefactory.cpp \ - $$PWD/qaudiodeviceid.cpp + $$PWD/qaudiodevicefactory.cpp mac { HEADERS += $$PWD/qaudioinput_mac_p.h \ diff --git a/src/multimedia/audio/qaudiodevicefactory.cpp b/src/multimedia/audio/qaudiodevicefactory.cpp index 9ed1d70..8804fb6 100644 --- a/src/multimedia/audio/qaudiodevicefactory.cpp +++ b/src/multimedia/audio/qaudiodevicefactory.cpp @@ -44,7 +44,6 @@ #include #include #include "qaudiodevicefactory_p.h" -#include "qaudiodeviceid_p.h" #if defined(Q_OS_WIN) #include "qaudiodeviceinfo_win32_p.h" @@ -123,12 +122,12 @@ public: QAudioFormat format() const { return QAudioFormat(); } }; -QList QAudioDeviceFactory::deviceList(QAudio::Mode mode) +QList QAudioDeviceFactory::deviceList(QAudio::Mode mode) { - QList devices; + 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); + foreach (const QByteArray &handle, QAudioDeviceInfoInternal::deviceList(mode)) + devices << QAudioDeviceInfo(QLatin1String("builtin"), handle, mode); #endif QFactoryLoader* l = loader(); @@ -136,7 +135,7 @@ QList QAudioDeviceFactory::deviceList(QAudio::Mode mode) QAudioEngineFactoryInterface* plugin = qobject_cast(l->instance(key)); if (plugin) { foreach (QByteArray const& handle, plugin->deviceList(mode)) - devices += createDeviceId(key, mode, handle); + devices << QAudioDeviceInfo(key, handle, mode); } delete plugin; @@ -145,50 +144,51 @@ QList QAudioDeviceFactory::deviceList(QAudio::Mode mode) return devices; } -QAudioDeviceId QAudioDeviceFactory::defaultInputDevice() +QAudioDeviceInfo 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)); + return QAudioDeviceInfo(QLatin1String("default"), list.at(0), QAudio::AudioInput); } #if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA)) - return createDeviceId(QLatin1String("builtin"), QAudio::AudioInput, QAudioDeviceInfoPrivate::defaultInputDevice()); + return QAudioDeviceInfo(QLatin1String("builtin"), QAudioDeviceInfoInternal::defaultInputDevice(), QAudio::AudioInput); #endif - return QAudioDeviceId(); + return QAudioDeviceInfo(); } -QAudioDeviceId QAudioDeviceFactory::defaultOutputDevice() +QAudioDeviceInfo 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)); + return QAudioDeviceInfo(QLatin1String("default"), list.at(0), QAudio::AudioOutput); } #if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA)) - return createDeviceId(QLatin1String("builtin"), QAudio::AudioOutput, QAudioDeviceInfoPrivate::defaultOutputDevice()); + return QAudioDeviceInfo(QLatin1String("builtin"), QAudioDeviceInfoInternal::defaultOutputDevice(), QAudio::AudioOutput); #endif - return QAudioDeviceId(); + return QAudioDeviceInfo(); } -QAbstractAudioDeviceInfo* QAudioDeviceFactory::audioDeviceInfo(QAudioDeviceId const& id) +QAbstractAudioDeviceInfo* QAudioDeviceFactory::audioDeviceInfo(const QString &realm, const QByteArray &handle, QAudio::Mode mode) { - if (id.isNull()) - return new QNullDeviceInfo(); + QAbstractAudioDeviceInfo *rc = 0; + #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)); + if (realm == QLatin1String("builtin")) + return new QAudioDeviceInfoInternal(handle, mode); #endif - QAudioEngineFactoryInterface* plugin = qobject_cast(loader()->instance(id.d->key)); + QAudioEngineFactoryInterface* plugin = + qobject_cast(loader()->instance(realm)); if (plugin) - return plugin->createDeviceInfo(id.d->handle, QAudio::Mode(id.d->mode)); + rc = plugin->createDeviceInfo(handle, mode); - return new QNullDeviceInfo(); + return rc == 0 ? new QNullDeviceInfo() : rc; } QAbstractAudioInput* QAudioDeviceFactory::createDefaultInputDevice(QAudioFormat const &format) @@ -201,50 +201,39 @@ QAbstractAudioOutput* QAudioDeviceFactory::createDefaultOutputDevice(QAudioForma return createOutputDevice(defaultOutputDevice(), format); } -QAbstractAudioInput* QAudioDeviceFactory::createInputDevice(QAudioDeviceId const& id, QAudioFormat const &format) +QAbstractAudioInput* QAudioDeviceFactory::createInputDevice(QAudioDeviceInfo const& deviceInfo, QAudioFormat const &format) { - if (id.isNull()) + if (deviceInfo.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(); - } + if (deviceInfo.realm() == QLatin1String("builtin")) + return new QAudioInputPrivate(deviceInfo.handle(), format); #endif - QAudioEngineFactoryInterface* plugin = qobject_cast(loader()->instance((id.d->key))); + QAudioEngineFactoryInterface* plugin = + qobject_cast(loader()->instance(deviceInfo.realm())); if (plugin) - return plugin->createInput(id.d->handle, format); + return plugin->createInput(deviceInfo.handle(), format); return new QNullInputDevice(); } -QAbstractAudioOutput* QAudioDeviceFactory::createOutputDevice(QAudioDeviceId const& id, QAudioFormat const &format) +QAbstractAudioOutput* QAudioDeviceFactory::createOutputDevice(QAudioDeviceInfo const& deviceInfo, QAudioFormat const &format) { - if (id.isNull()) + if (deviceInfo.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(); - } + if (deviceInfo.realm() == QLatin1String("builtin")) + return new QAudioOutputPrivate(deviceInfo.handle(), format); #endif - QAudioEngineFactoryInterface* plugin = qobject_cast(loader()->instance(id.d->key)); + QAudioEngineFactoryInterface* plugin = + qobject_cast(loader()->instance(deviceInfo.realm())); if (plugin) - return plugin->createOutput(id.d->handle, format); + return plugin->createOutput(deviceInfo.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 index 8e4cf5a..008e4a8 100644 --- a/src/multimedia/audio/qaudiodevicefactory_p.h +++ b/src/multimedia/audio/qaudiodevicefactory_p.h @@ -57,7 +57,6 @@ #include #include -#include #include QT_BEGIN_HEADER @@ -68,28 +67,26 @@ QT_MODULE(Multimedia) class QAbstractAudioInput; class QAbstractAudioOutput; - +class QAbstractAudioDeviceInfo; class QAudioDeviceFactory { public: - static QList deviceList(QAudio::Mode mode); + static QList deviceList(QAudio::Mode mode); - static QAudioDeviceId defaultInputDevice(); - static QAudioDeviceId defaultOutputDevice(); + static QAudioDeviceInfo defaultInputDevice(); + static QAudioDeviceInfo defaultOutputDevice(); - static QAbstractAudioDeviceInfo* audioDeviceInfo(QAudioDeviceId const &device); + static QAbstractAudioDeviceInfo* audioDeviceInfo(const QString &realm, const QByteArray &handle, QAudio::Mode mode); 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* createInputDevice(QAudioDeviceInfo const &device, QAudioFormat const &format); + static QAbstractAudioOutput* createOutputDevice(QAudioDeviceInfo 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 diff --git a/src/multimedia/audio/qaudiodeviceid.cpp b/src/multimedia/audio/qaudiodeviceid.cpp deleted file mode 100644 index bdbc580..0000000 --- a/src/multimedia/audio/qaudiodeviceid.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the 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 Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include - -#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 deleted file mode 100644 index 61d0d9a..0000000 --- a/src/multimedia/audio/qaudiodeviceid.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the 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 Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef 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 deleted file mode 100644 index 113e1f0..0000000 --- a/src/multimedia/audio/qaudiodeviceid_p.h +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the 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 Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// -// 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 index e38a91e..dce2884 100644 --- a/src/multimedia/audio/qaudiodeviceinfo.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo.cpp @@ -46,12 +46,52 @@ QT_BEGIN_NAMESPACE +class QAudioDeviceInfoPrivate : public QSharedData +{ +public: + QAudioDeviceInfoPrivate():info(0) {} + QAudioDeviceInfoPrivate(const QString &r, const QByteArray &h, QAudio::Mode m): + realm(r), handle(h), mode(m) + { + info = QAudioDeviceFactory::audioDeviceInfo(realm, handle, mode); + } + + QAudioDeviceInfoPrivate(const QAudioDeviceInfoPrivate &other): + QSharedData(other), + realm(other.realm), handle(other.handle), mode(other.mode) + { + info = QAudioDeviceFactory::audioDeviceInfo(realm, handle, mode); + } + + QAudioDeviceInfoPrivate& operator=(const QAudioDeviceInfoPrivate &other) + { + delete info; + + realm = other.realm; + handle = other.handle; + mode = other.mode; + info = QAudioDeviceFactory::audioDeviceInfo(realm, handle, mode); + return *this; + } + + ~QAudioDeviceInfoPrivate() + { + delete info; + } + + QString realm; + QByteArray handle; + QAudio::Mode mode; + QAbstractAudioDeviceInfo* info; +}; + + /*! \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 @@ -77,41 +117,45 @@ QT_BEGIN_NAMESPACE \dots 8 \snippet doc/src/snippets/audio/main.cpp 2 - A QAudioDeviceInfo is constructed with a QAudioDeviceId, which is - an identifier for a physical device. It is used by Qt to construct + A QAudioDeviceInfo is used by Qt to construct classes that communicate with the device--such as - QAudioDeviceInfo, QAudioInput, and QAudioOutput. The static + 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. + deviceList() let you get a list of all available + devices. Devices are fetch according to the value of mode + this is specified by the QAudio::Mode enum. + The QAudioDeviceInfo 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(); - } + foreach(const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::deviceList(QAudio::AudioOutput)) + qDebug() << "Device name: " << deviceInfo.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 + \sa QAudioOutput, QAudioInput */ /*! - Construct a new audio device info and attach it to \a parent. - Using the audio device with the specified \a id. + Constructs an empty QAudioDeviceInfo object. */ -QAudioDeviceInfo::QAudioDeviceInfo(const QAudioDeviceId &id, QObject *parent): - QObject(parent) +QAudioDeviceInfo::QAudioDeviceInfo(): + d(new QAudioDeviceInfoPrivate) +{ +} + +/*! + Constructs a copy of \a other. +*/ + +QAudioDeviceInfo::QAudioDeviceInfo(const QAudioDeviceInfo& other): + d(other.d) { - d = QAudioDeviceFactory::audioDeviceInfo(id); } /*! @@ -120,7 +164,25 @@ QAudioDeviceInfo::QAudioDeviceInfo(const QAudioDeviceId &id, QObject *parent): QAudioDeviceInfo::~QAudioDeviceInfo() { - delete d; +} + +/*! + Sets the QAudioDeviceInfo object to be equal to \a other. +*/ + +QAudioDeviceInfo& QAudioDeviceInfo::operator=(const QAudioDeviceInfo &other) +{ + d = other.d; + return *this; +} + +/*! + Returns whether this QAudioDeviceInfo object holds a device definition. +*/ + +bool QAudioDeviceInfo::isNull() const +{ + return d->info == 0; } /*! @@ -135,7 +197,7 @@ QAudioDeviceInfo::~QAudioDeviceInfo() QString QAudioDeviceInfo::deviceName() const { - return d->deviceName(); + return isNull() ? QString() : d->info->deviceName(); } /*! @@ -144,7 +206,7 @@ QString QAudioDeviceInfo::deviceName() const bool QAudioDeviceInfo::isFormatSupported(const QAudioFormat &settings) const { - return d->isFormatSupported(settings); + return isNull() ? false : d->info->isFormatSupported(settings); } /*! @@ -163,7 +225,7 @@ bool QAudioDeviceInfo::isFormatSupported(const QAudioFormat &settings) const QAudioFormat QAudioDeviceInfo::preferredFormat() const { - return d->preferredFormat(); + return isNull() ? QAudioFormat() : d->info->preferredFormat(); } /*! @@ -176,7 +238,7 @@ QAudioFormat QAudioDeviceInfo::preferredFormat() const QAudioFormat QAudioDeviceInfo::nearestFormat(const QAudioFormat &settings) const { - return d->nearestFormat(settings); + return isNull() ? QAudioFormat() : d->info->nearestFormat(settings); } /*! @@ -193,7 +255,7 @@ QAudioFormat QAudioDeviceInfo::nearestFormat(const QAudioFormat &settings) const QStringList QAudioDeviceInfo::supportedCodecs() const { - return d->codecList(); + return isNull() ? QStringList() : d->info->codecList(); } /*! @@ -202,7 +264,7 @@ QStringList QAudioDeviceInfo::supportedCodecs() const QList QAudioDeviceInfo::supportedFrequencies() const { - return d->frequencyList(); + return isNull() ? QList() : d->info->frequencyList(); } /*! @@ -211,7 +273,7 @@ QList QAudioDeviceInfo::supportedFrequencies() const QList QAudioDeviceInfo::supportedChannels() const { - return d->channelsList(); + return isNull() ? QList() : d->info->channelsList(); } /*! @@ -220,7 +282,7 @@ QList QAudioDeviceInfo::supportedChannels() const QList QAudioDeviceInfo::supportedSampleSizes() const { - return d->sampleSizeList(); + return isNull() ? QList() : d->info->sampleSizeList(); } /*! @@ -229,7 +291,7 @@ QList QAudioDeviceInfo::supportedSampleSizes() const QList QAudioDeviceInfo::supportedByteOrders() const { - return d->byteOrderList(); + return isNull() ? QList() : d->info->byteOrderList(); } /*! @@ -238,7 +300,7 @@ QList QAudioDeviceInfo::supportedByteOrders() const QList QAudioDeviceInfo::supportedSampleTypes() const { - return d->sampleTypeList(); + return isNull() ? QList() : d->info->sampleTypeList(); } /*! @@ -246,7 +308,7 @@ QList QAudioDeviceInfo::supportedSampleTypes() const All platform and audio plugin implementations provide a default audio device to use. */ -QAudioDeviceId QAudioDeviceInfo::defaultInputDevice() +QAudioDeviceInfo QAudioDeviceInfo::defaultInputDevice() { return QAudioDeviceFactory::defaultInputDevice(); } @@ -256,7 +318,7 @@ QAudioDeviceId QAudioDeviceInfo::defaultInputDevice() All platform and audio plugin implementations provide a default audio device to use. */ -QAudioDeviceId QAudioDeviceInfo::defaultOutputDevice() +QAudioDeviceInfo QAudioDeviceInfo::defaultOutputDevice() { return QAudioDeviceFactory::defaultOutputDevice(); } @@ -265,10 +327,48 @@ QAudioDeviceId QAudioDeviceInfo::defaultOutputDevice() Returns a list of audio devices that support \a mode. */ -QList QAudioDeviceInfo::deviceList(QAudio::Mode mode) +QList QAudioDeviceInfo::deviceList(QAudio::Mode mode) { return QAudioDeviceFactory::deviceList(mode); } + +/*! + \internal +*/ + +QAudioDeviceInfo::QAudioDeviceInfo(const QString &realm, const QByteArray &handle, QAudio::Mode mode): + d(new QAudioDeviceInfoPrivate(realm, handle, mode)) +{ +} + +/*! + \internal +*/ + +QString QAudioDeviceInfo::realm() const +{ + return d->realm; +} + +/*! + \internal +*/ + +QByteArray QAudioDeviceInfo::handle() const +{ + return d->handle; +} + + +/*! + \internal +*/ + +QAudio::Mode QAudioDeviceInfo::mode() const +{ + return d->mode; +} + QT_END_NAMESPACE diff --git a/src/multimedia/audio/qaudiodeviceinfo.h b/src/multimedia/audio/qaudiodeviceinfo.h index b6adb85..53b9904 100644 --- a/src/multimedia/audio/qaudiodeviceinfo.h +++ b/src/multimedia/audio/qaudiodeviceinfo.h @@ -52,7 +52,7 @@ #include #include -#include + QT_BEGIN_HEADER @@ -60,17 +60,22 @@ QT_BEGIN_NAMESPACE QT_MODULE(Multimedia) +class QAudioDeviceFactory; -class QAbstractAudioDeviceInfo; - -class Q_MULTIMEDIA_EXPORT QAudioDeviceInfo : public QObject +class QAudioDeviceInfoPrivate; +class Q_MULTIMEDIA_EXPORT QAudioDeviceInfo { - Q_OBJECT + friend class QAudioDeviceFactory; public: - explicit QAudioDeviceInfo(const QAudioDeviceId &id, QObject *parent = 0); + QAudioDeviceInfo(); + QAudioDeviceInfo(const QAudioDeviceInfo& other); ~QAudioDeviceInfo(); + QAudioDeviceInfo& operator=(const QAudioDeviceInfo& other); + + bool isNull() const; + QString deviceName() const; bool isFormatSupported(const QAudioFormat &format) const; @@ -84,19 +89,24 @@ public: QList supportedByteOrders() const; QList supportedSampleTypes() const; - static QAudioDeviceId defaultInputDevice(); - static QAudioDeviceId defaultOutputDevice(); + static QAudioDeviceInfo defaultInputDevice(); + static QAudioDeviceInfo defaultOutputDevice(); - static QList deviceList(QAudio::Mode mode); + static QList deviceList(QAudio::Mode mode); private: - Q_DISABLE_COPY(QAudioDeviceInfo) + QAudioDeviceInfo(const QString &realm, const QByteArray &handle, QAudio::Mode mode); + QString realm() const; + QByteArray handle() const; + QAudio::Mode mode() const; - QAbstractAudioDeviceInfo* d; + QSharedDataPointer d; }; QT_END_NAMESPACE QT_END_HEADER +Q_DECLARE_METATYPE(QAudioDeviceInfo) + #endif // QAUDIODEVICEINFO_H diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp index c944cf0..dc24875 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE -QAudioDeviceInfoPrivate::QAudioDeviceInfoPrivate(QByteArray dev, QAudio::Mode mode) +QAudioDeviceInfoInternal::QAudioDeviceInfoInternal(QByteArray dev, QAudio::Mode mode) { handle = 0; @@ -62,17 +62,17 @@ QAudioDeviceInfoPrivate::QAudioDeviceInfoPrivate(QByteArray dev, QAudio::Mode mo this->mode = mode; } -QAudioDeviceInfoPrivate::~QAudioDeviceInfoPrivate() +QAudioDeviceInfoInternal::~QAudioDeviceInfoInternal() { close(); } -bool QAudioDeviceInfoPrivate::isFormatSupported(const QAudioFormat& format) const +bool QAudioDeviceInfoInternal::isFormatSupported(const QAudioFormat& format) const { return testSettings(format); } -QAudioFormat QAudioDeviceInfoPrivate::preferredFormat() const +QAudioFormat QAudioDeviceInfoInternal::preferredFormat() const { QAudioFormat nearest; if(mode == QAudio::AudioOutput) { @@ -97,7 +97,7 @@ QAudioFormat QAudioDeviceInfoPrivate::preferredFormat() const return nearest; } -QAudioFormat QAudioDeviceInfoPrivate::nearestFormat(const QAudioFormat& format) const +QAudioFormat QAudioDeviceInfoInternal::nearestFormat(const QAudioFormat& format) const { if(testSettings(format)) return format; @@ -105,48 +105,48 @@ QAudioFormat QAudioDeviceInfoPrivate::nearestFormat(const QAudioFormat& format) return preferredFormat(); } -QString QAudioDeviceInfoPrivate::deviceName() const +QString QAudioDeviceInfoInternal::deviceName() const { return device; } -QStringList QAudioDeviceInfoPrivate::codecList() +QStringList QAudioDeviceInfoInternal::codecList() { updateLists(); return codecz; } -QList QAudioDeviceInfoPrivate::frequencyList() +QList QAudioDeviceInfoInternal::frequencyList() { updateLists(); return freqz; } -QList QAudioDeviceInfoPrivate::channelsList() +QList QAudioDeviceInfoInternal::channelsList() { updateLists(); return channelz; } -QList QAudioDeviceInfoPrivate::sampleSizeList() +QList QAudioDeviceInfoInternal::sampleSizeList() { updateLists(); return sizez; } -QList QAudioDeviceInfoPrivate::byteOrderList() +QList QAudioDeviceInfoInternal::byteOrderList() { updateLists(); return byteOrderz; } -QList QAudioDeviceInfoPrivate::sampleTypeList() +QList QAudioDeviceInfoInternal::sampleTypeList() { updateLists(); return typez; } -bool QAudioDeviceInfoPrivate::open() +bool QAudioDeviceInfoInternal::open() { int err = 0; QString dev = device; @@ -166,14 +166,14 @@ bool QAudioDeviceInfoPrivate::open() return true; } -void QAudioDeviceInfoPrivate::close() +void QAudioDeviceInfoInternal::close() { if(handle) snd_pcm_close(handle); handle = 0; } -bool QAudioDeviceInfoPrivate::testSettings(const QAudioFormat& format) const +bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const { // Set nearest to closest settings that do work. // See if what is in settings will work (return value). @@ -324,7 +324,7 @@ bool QAudioDeviceInfoPrivate::testSettings(const QAudioFormat& format) const return false; } -void QAudioDeviceInfoPrivate::updateLists() +void QAudioDeviceInfoInternal::updateLists() { // redo all lists based on current settings freqz.clear(); @@ -358,7 +358,7 @@ void QAudioDeviceInfoPrivate::updateLists() close(); } -QList QAudioDeviceInfoPrivate::deviceList(QAudio::Mode mode) +QList QAudioDeviceInfoInternal::deviceList(QAudio::Mode mode) { QAudio::Mode _m; QList devices; @@ -416,7 +416,7 @@ QList QAudioDeviceInfoPrivate::deviceList(QAudio::Mode mode) return devices; } -QByteArray QAudioDeviceInfoPrivate::defaultInputDevice() +QByteArray QAudioDeviceInfoInternal::defaultInputDevice() { QList devices = deviceList(QAudio::AudioInput); if(devices.size() == 0) @@ -425,7 +425,7 @@ QByteArray QAudioDeviceInfoPrivate::defaultInputDevice() return QByteArray("default"); } -QByteArray QAudioDeviceInfoPrivate::defaultOutputDevice() +QByteArray QAudioDeviceInfoInternal::defaultOutputDevice() { QList devices = deviceList(QAudio::AudioOutput); if(devices.size() == 0) diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h index 9990281..10078ca 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h +++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h @@ -71,12 +71,12 @@ const unsigned int MAX_SAMPLE_RATES = 5; const unsigned int SAMPLE_RATES[] = { 8000, 11025, 22050, 44100, 48000 }; -class QAudioDeviceInfoPrivate : public QAbstractAudioDeviceInfo +class QAudioDeviceInfoInternal : public QAbstractAudioDeviceInfo { Q_OBJECT public: - QAudioDeviceInfoPrivate(QByteArray dev,QAudio::Mode mode); - ~QAudioDeviceInfoPrivate(); + QAudioDeviceInfoInternal(QByteArray dev,QAudio::Mode mode); + ~QAudioDeviceInfoInternal(); bool testSettings(const QAudioFormat& format) const; void updateLists(); diff --git a/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp index 957a5c7..ec07748 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp @@ -66,7 +66,7 @@ QT_BEGIN_NAMESPACE -QAudioDeviceInfoPrivate::QAudioDeviceInfoPrivate(QByteArray const& handle, QAudio::Mode) +QAudioDeviceInfoInternal::QAudioDeviceInfoInternal(QByteArray const& handle, QAudio::Mode) { QDataStream ds(handle); quint32 did, tm; @@ -76,12 +76,12 @@ QAudioDeviceInfoPrivate::QAudioDeviceInfoPrivate(QByteArray const& handle, QAudi mode = QAudio::Mode(tm); } -bool QAudioDeviceInfoPrivate::isFormatSupported(const QAudioFormat& format) const +bool QAudioDeviceInfoInternal::isFormatSupported(const QAudioFormat& format) const { return format.codec() == QString::fromLatin1("audio/pcm"); } -QAudioFormat QAudioDeviceInfoPrivate::preferredFormat() const +QAudioFormat QAudioDeviceInfoInternal::preferredFormat() const { QAudioFormat rc; @@ -134,7 +134,7 @@ QAudioFormat QAudioDeviceInfoPrivate::preferredFormat() const return rc; } -QAudioFormat QAudioDeviceInfoPrivate::nearestFormat(const QAudioFormat& format) const +QAudioFormat QAudioDeviceInfoInternal::nearestFormat(const QAudioFormat& format) const { QAudioFormat rc(format); QAudioFormat target = preferredFormat(); @@ -158,17 +158,17 @@ QAudioFormat QAudioDeviceInfoPrivate::nearestFormat(const QAudioFormat& format) return rc; } -QString QAudioDeviceInfoPrivate::deviceName() const +QString QAudioDeviceInfoInternal::deviceName() const { return name; } -QStringList QAudioDeviceInfoPrivate::codecList() +QStringList QAudioDeviceInfoInternal::codecList() { return QStringList() << QString::fromLatin1("audio/pcm"); } -QList QAudioDeviceInfoPrivate::frequencyList() +QList QAudioDeviceInfoInternal::frequencyList() { QSet rc; @@ -208,7 +208,7 @@ QList QAudioDeviceInfoPrivate::frequencyList() return rc.toList(); } -QList QAudioDeviceInfoPrivate::channelsList() +QList QAudioDeviceInfoInternal::channelsList() { QList rc; @@ -248,17 +248,17 @@ QList QAudioDeviceInfoPrivate::channelsList() return rc; } -QList QAudioDeviceInfoPrivate::sampleSizeList() +QList QAudioDeviceInfoInternal::sampleSizeList() { return QList() << 8 << 16 << 24 << 32 << 64; } -QList QAudioDeviceInfoPrivate::byteOrderList() +QList QAudioDeviceInfoInternal::byteOrderList() { return QList() << QAudioFormat::LittleEndian << QAudioFormat::BigEndian; } -QList QAudioDeviceInfoPrivate::sampleTypeList() +QList QAudioDeviceInfoInternal::sampleTypeList() { return QList() << QAudioFormat::SignedInt << QAudioFormat::UnSignedInt << QAudioFormat::Float; } @@ -296,7 +296,7 @@ static QByteArray get_device_info(AudioDeviceID audioDevice, QAudio::Mode mode) return device; } -QByteArray QAudioDeviceInfoPrivate::defaultInputDevice() +QByteArray QAudioDeviceInfoInternal::defaultInputDevice() { AudioDeviceID audioDevice; UInt32 size = sizeof(audioDevice); @@ -310,7 +310,7 @@ QByteArray QAudioDeviceInfoPrivate::defaultInputDevice() return get_device_info(audioDevice, QAudio::AudioInput); } -QByteArray QAudioDeviceInfoPrivate::defaultOutputDevice() +QByteArray QAudioDeviceInfoInternal::defaultOutputDevice() { AudioDeviceID audioDevice; UInt32 size = sizeof(audioDevice); @@ -324,7 +324,7 @@ QByteArray QAudioDeviceInfoPrivate::defaultOutputDevice() return get_device_info(audioDevice, QAudio::AudioOutput); } -QList QAudioDeviceInfoPrivate::deviceList(QAudio::Mode mode) +QList QAudioDeviceInfoInternal::deviceList(QAudio::Mode mode) { QList devices; diff --git a/src/multimedia/audio/qaudiodeviceinfo_mac_p.h b/src/multimedia/audio/qaudiodeviceinfo_mac_p.h index 7e8e752..60532a8 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_mac_p.h +++ b/src/multimedia/audio/qaudiodeviceinfo_mac_p.h @@ -62,14 +62,14 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -class QAudioDeviceInfoPrivate : public QAbstractAudioDeviceInfo +class QAudioDeviceInfoInternal : public QAbstractAudioDeviceInfo { public: AudioDeviceID deviceId; QString name; QAudio::Mode mode; - QAudioDeviceInfoPrivate(QByteArray const& handle, QAudio::Mode mode); + QAudioDeviceInfoInternal(QByteArray const& handle, QAudio::Mode mode); bool isFormatSupported(const QAudioFormat& format) const; QAudioFormat preferredFormat() const; diff --git a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp index ba9f5e2..69d5c94 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp @@ -74,23 +74,23 @@ QT_BEGIN_NAMESPACE #endif -QAudioDeviceInfoPrivate::QAudioDeviceInfoPrivate(QByteArray dev, QAudio::Mode mode) +QAudioDeviceInfoInternal::QAudioDeviceInfoInternal(QByteArray dev, QAudio::Mode mode) { device = QLatin1String(dev); this->mode = mode; } -QAudioDeviceInfoPrivate::~QAudioDeviceInfoPrivate() +QAudioDeviceInfoInternal::~QAudioDeviceInfoInternal() { close(); } -bool QAudioDeviceInfoPrivate::isFormatSupported(const QAudioFormat& format) const +bool QAudioDeviceInfoInternal::isFormatSupported(const QAudioFormat& format) const { return testSettings(format); } -QAudioFormat QAudioDeviceInfoPrivate::preferredFormat() const +QAudioFormat QAudioDeviceInfoInternal::preferredFormat() const { QAudioFormat nearest; if(mode == QAudio::AudioOutput) { @@ -110,7 +110,7 @@ QAudioFormat QAudioDeviceInfoPrivate::preferredFormat() const return nearest; } -QAudioFormat QAudioDeviceInfoPrivate::nearestFormat(const QAudioFormat& format) const +QAudioFormat QAudioDeviceInfoInternal::nearestFormat(const QAudioFormat& format) const { if(testSettings(format)) return format; @@ -118,58 +118,58 @@ QAudioFormat QAudioDeviceInfoPrivate::nearestFormat(const QAudioFormat& format) return preferredFormat(); } -QString QAudioDeviceInfoPrivate::deviceName() const +QString QAudioDeviceInfoInternal::deviceName() const { return device; } -QStringList QAudioDeviceInfoPrivate::codecList() +QStringList QAudioDeviceInfoInternal::codecList() { updateLists(); return codecz; } -QList QAudioDeviceInfoPrivate::frequencyList() +QList QAudioDeviceInfoInternal::frequencyList() { updateLists(); return freqz; } -QList QAudioDeviceInfoPrivate::channelsList() +QList QAudioDeviceInfoInternal::channelsList() { updateLists(); return channelz; } -QList QAudioDeviceInfoPrivate::sampleSizeList() +QList QAudioDeviceInfoInternal::sampleSizeList() { updateLists(); return sizez; } -QList QAudioDeviceInfoPrivate::byteOrderList() +QList QAudioDeviceInfoInternal::byteOrderList() { updateLists(); return byteOrderz; } -QList QAudioDeviceInfoPrivate::sampleTypeList() +QList QAudioDeviceInfoInternal::sampleTypeList() { updateLists(); return typez; } -bool QAudioDeviceInfoPrivate::open() +bool QAudioDeviceInfoInternal::open() { return true; } -void QAudioDeviceInfoPrivate::close() +void QAudioDeviceInfoInternal::close() { } -bool QAudioDeviceInfoPrivate::testSettings(const QAudioFormat& format) const +bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const { // Set nearest to closest settings that do work. // See if what is in settings will work (return value). @@ -199,7 +199,7 @@ bool QAudioDeviceInfoPrivate::testSettings(const QAudioFormat& format) const return false; } -void QAudioDeviceInfoPrivate::updateLists() +void QAudioDeviceInfoInternal::updateLists() { // redo all lists based on current settings bool base = false; @@ -333,7 +333,7 @@ void QAudioDeviceInfoPrivate::updateLists() } } -QList QAudioDeviceInfoPrivate::deviceList(QAudio::Mode mode) +QList QAudioDeviceInfoInternal::deviceList(QAudio::Mode mode) { Q_UNUSED(mode) @@ -367,12 +367,12 @@ QList QAudioDeviceInfoPrivate::deviceList(QAudio::Mode mode) return devices; } -QByteArray QAudioDeviceInfoPrivate::defaultOutputDevice() +QByteArray QAudioDeviceInfoInternal::defaultOutputDevice() { return QByteArray("default"); } -QByteArray QAudioDeviceInfoPrivate::defaultInputDevice() +QByteArray QAudioDeviceInfoInternal::defaultInputDevice() { return QByteArray("default"); } diff --git a/src/multimedia/audio/qaudiodeviceinfo_win32_p.h b/src/multimedia/audio/qaudiodeviceinfo_win32_p.h index 7cf7f45..0d2ee29 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_win32_p.h +++ b/src/multimedia/audio/qaudiodeviceinfo_win32_p.h @@ -68,13 +68,13 @@ QT_BEGIN_NAMESPACE const unsigned int MAX_SAMPLE_RATES = 5; const unsigned int SAMPLE_RATES[] = { 8000, 11025, 22050, 44100, 48000 }; -class QAudioDeviceInfoPrivate : public QAbstractAudioDeviceInfo +class QAudioDeviceInfoInternal : public QAbstractAudioDeviceInfo { Q_OBJECT public: - QAudioDeviceInfoPrivate(QByteArray dev,QAudio::Mode mode); - ~QAudioDeviceInfoPrivate(); + QAudioDeviceInfoInternal(QByteArray dev,QAudio::Mode mode); + ~QAudioDeviceInfoInternal(); bool open(); void close(); diff --git a/src/multimedia/audio/qaudioformat.cpp b/src/multimedia/audio/qaudioformat.cpp index c23e454..86fe85b 100644 --- a/src/multimedia/audio/qaudioformat.cpp +++ b/src/multimedia/audio/qaudioformat.cpp @@ -286,7 +286,7 @@ int QAudioFormat::sampleSize() const \sa QAudioDeviceInfo::supportedCodecs() */ -void QAudioFormat::setCodec(QString codec) +void QAudioFormat::setCodec(const QString &codec) { d->codec = codec; } diff --git a/src/multimedia/audio/qaudioformat.h b/src/multimedia/audio/qaudioformat.h index 4cd6e23..d5841ce 100644 --- a/src/multimedia/audio/qaudioformat.h +++ b/src/multimedia/audio/qaudioformat.h @@ -82,7 +82,7 @@ public: void setSampleSize(int sampleSize); int sampleSize() const; - void setCodec(QString codec); + void setCodec(const QString &codec); QString codec() const; void setByteOrder(QAudioFormat::Endian byteOrder); diff --git a/src/multimedia/audio/qaudioinput.cpp b/src/multimedia/audio/qaudioinput.cpp index 3c0d98e..858846f 100644 --- a/src/multimedia/audio/qaudioinput.cpp +++ b/src/multimedia/audio/qaudioinput.cpp @@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE 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 + specific QAudioDeviceInfo. 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). @@ -69,7 +69,7 @@ QT_BEGIN_NAMESPACE 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 + audio device, but you can also specify a QAudioDeviceInfo for a specific device. You also need to pass in the QAudioFormat in which you wish to record. @@ -154,14 +154,14 @@ QAudioInput::QAudioInput(const QAudioFormat &format, QObject *parent): /*! Construct a new audio input and attach it to \a parent. - The \a id of the audio input device is used with the input + The device referenced by \a audioDevice is used with the input \a format parameters. */ -QAudioInput::QAudioInput(const QAudioDeviceId &id, const QAudioFormat &format, QObject *parent): +QAudioInput::QAudioInput(const QAudioDeviceInfo &audioDevice, const QAudioFormat &format, QObject *parent): QObject(parent) { - d = QAudioDeviceFactory::createInputDevice(id, format); + d = QAudioDeviceFactory::createInputDevice(audioDevice, format); connect(d, SIGNAL(notify()), SIGNAL(notify())); connect(d, SIGNAL(stateChanged(QAudio::State)), SIGNAL(stateChanged(QAudio::State))); } diff --git a/src/multimedia/audio/qaudioinput.h b/src/multimedia/audio/qaudioinput.h index 277a6cf..c8094f5 100644 --- a/src/multimedia/audio/qaudioinput.h +++ b/src/multimedia/audio/qaudioinput.h @@ -48,7 +48,8 @@ #include #include -#include +#include + QT_BEGIN_HEADER @@ -65,7 +66,7 @@ class Q_MULTIMEDIA_EXPORT QAudioInput : public QObject public: explicit QAudioInput(const QAudioFormat &format = QAudioFormat(), QObject *parent = 0); - explicit QAudioInput(const QAudioDeviceId &id, const QAudioFormat &format = QAudioFormat(), QObject *parent = 0); + explicit QAudioInput(const QAudioDeviceInfo &audioDeviceInfo, const QAudioFormat &format = QAudioFormat(), QObject *parent = 0); ~QAudioInput(); QAudioFormat format() const; diff --git a/src/multimedia/audio/qaudiooutput.cpp b/src/multimedia/audio/qaudiooutput.cpp index 8a8edb4..3d3f5f5 100644 --- a/src/multimedia/audio/qaudiooutput.cpp +++ b/src/multimedia/audio/qaudiooutput.cpp @@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE 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 + specific QAudioDeviceInfo. 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). @@ -155,14 +155,14 @@ QAudioOutput::QAudioOutput(const QAudioFormat &format, QObject *parent): /*! Construct a new audio output and attach it to \a parent. - The \a id of the audio output device is used with the output + The device referenced by \a audioDevice is used with the output \a format parameters. */ -QAudioOutput::QAudioOutput(const QAudioDeviceId &id, const QAudioFormat &format, QObject *parent): +QAudioOutput::QAudioOutput(const QAudioDeviceInfo &audioDevice, const QAudioFormat &format, QObject *parent): QObject(parent) { - d = QAudioDeviceFactory::createOutputDevice(id, format); + d = QAudioDeviceFactory::createOutputDevice(audioDevice, format); connect(d, SIGNAL(notify()), SIGNAL(notify())); connect(d, SIGNAL(stateChanged(QAudio::State)), SIGNAL(stateChanged(QAudio::State))); } diff --git a/src/multimedia/audio/qaudiooutput.h b/src/multimedia/audio/qaudiooutput.h index 1ed3d06..bb3496e 100644 --- a/src/multimedia/audio/qaudiooutput.h +++ b/src/multimedia/audio/qaudiooutput.h @@ -48,7 +48,7 @@ #include #include -#include +#include QT_BEGIN_HEADER @@ -66,7 +66,7 @@ class Q_MULTIMEDIA_EXPORT QAudioOutput : public QObject public: explicit QAudioOutput(const QAudioFormat &format = QAudioFormat(), QObject *parent = 0); - explicit QAudioOutput(const QAudioDeviceId &id, const QAudioFormat &format = QAudioFormat(), QObject *parent = 0); + explicit QAudioOutput(const QAudioDeviceInfo &audioDeviceInfo, const QAudioFormat &format = QAudioFormat(), QObject *parent = 0); ~QAudioOutput(); QAudioFormat format() const; diff --git a/tests/auto/qaudiodeviceid/qaudiodeviceid.pro b/tests/auto/qaudiodeviceid/qaudiodeviceid.pro deleted file mode 100644 index e0c7d4d..0000000 --- a/tests/auto/qaudiodeviceid/qaudiodeviceid.pro +++ /dev/null @@ -1,7 +0,0 @@ -load(qttest_p4) - -DEFINES += SRCDIR=\\\"$$PWD/\\\" - -SOURCES += tst_qaudiodeviceid.cpp - -QT = core multimedia diff --git a/tests/auto/qaudiodeviceid/tst_qaudiodeviceid.cpp b/tests/auto/qaudiodeviceid/tst_qaudiodeviceid.cpp deleted file mode 100644 index 02e475e..0000000 --- a/tests/auto/qaudiodeviceid/tst_qaudiodeviceid.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include - -#include -#include - - -class tst_QAudioDeviceId : public QObject -{ - Q_OBJECT - -public: - tst_QAudioDeviceId(QObject* parent=0) : QObject(parent) {} - -private slots: - void initTestCase(); - void checkNull(); - void checkEquality(); - -private: - bool available; -}; - -void tst_QAudioDeviceId::initTestCase() -{ - // Only perform tests if audio output device exists! - QList devices = QAudioDeviceInfo::deviceList(QAudio::AudioOutput); - if(devices.size() > 0) - available = true; - else { - qWarning()<<"NOTE: no audio output device found, no test will be performed"; - available = false; - } -} - -void tst_QAudioDeviceId::checkNull() -{ - if(available) { - // Default constructed is null. - QAudioDeviceId deviceId0; - QVERIFY(deviceId0.isNull()); - - // Null is transferred - QAudioDeviceId deviceId1(deviceId0); - QVERIFY(deviceId1.isNull()); - } -} - -void tst_QAudioDeviceId::checkEquality() -{ - if(available) { - 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/tst_qaudiodeviceinfo.cpp b/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp index 45912e2..7b9a422 100644 --- a/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp +++ b/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp @@ -77,7 +77,7 @@ private: void tst_QAudioDeviceInfo::initTestCase() { // Only perform tests if audio output device exists! - QList devices = QAudioDeviceInfo::deviceList(QAudio::AudioOutput); + QList devices = QAudioDeviceInfo::deviceList(QAudio::AudioOutput); if(devices.size() > 0) available = true; else { @@ -90,7 +90,7 @@ void tst_QAudioDeviceInfo::checkAvailableDefaultInput() { // Only perform tests if audio input device exists! bool storeAvailable = available; - QList devices = QAudioDeviceInfo::deviceList(QAudio::AudioInput); + QList devices = QAudioDeviceInfo::deviceList(QAudio::AudioInput); if(devices.size() > 0) available = true; else { @@ -111,9 +111,9 @@ void tst_QAudioDeviceInfo::checkAvailableDefaultOutput() void tst_QAudioDeviceInfo::outputList() { if(available) { - QList devices = QAudioDeviceInfo::deviceList(QAudio::AudioOutput); + QList devices = QAudioDeviceInfo::deviceList(QAudio::AudioOutput); QVERIFY(devices.size() > 0); - device = new QAudioDeviceInfo(devices.at(0), this); + device = new QAudioDeviceInfo(devices.at(0)); } } diff --git a/tests/auto/qaudioinput/tst_qaudioinput.cpp b/tests/auto/qaudioinput/tst_qaudioinput.cpp index bf11961..7331072 100644 --- a/tests/auto/qaudioinput/tst_qaudioinput.cpp +++ b/tests/auto/qaudioinput/tst_qaudioinput.cpp @@ -75,7 +75,7 @@ void tst_QAudioInput::initTestCase() format.setSampleType(QAudioFormat::UnSignedInt); // Only perform tests if audio input device exists! - QList devices = QAudioDeviceInfo::deviceList(QAudio::AudioInput); + QList devices = QAudioDeviceInfo::deviceList(QAudio::AudioInput); if(devices.size() > 0) available = true; else { diff --git a/tests/auto/qaudiooutput/tst_qaudiooutput.cpp b/tests/auto/qaudiooutput/tst_qaudiooutput.cpp index db2444b..b45a57e 100644 --- a/tests/auto/qaudiooutput/tst_qaudiooutput.cpp +++ b/tests/auto/qaudiooutput/tst_qaudiooutput.cpp @@ -78,7 +78,7 @@ void tst_QAudioOutput::initTestCase() format.setSampleType(QAudioFormat::UnSignedInt); // Only perform tests if audio output device exists! - QList devices = QAudioDeviceInfo::deviceList(QAudio::AudioOutput); + QList devices = QAudioDeviceInfo::deviceList(QAudio::AudioOutput); if(devices.size() > 0) available = true; else { -- cgit v0.12 From 8a7a3d173d94cabc5bbfa2518f22849d1aa6f855 Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Thu, 24 Sep 2009 13:22:57 +1000 Subject: AudioServices; Nicer examples. Reviewed-by: Bill King --- doc/src/examples/audioinput.qdoc | 2 +- .../multimedia/audio/audioinput/audioinput.cpp | 198 ++++++--------------- examples/multimedia/audio/audioinput/audioinput.h | 40 ++--- .../multimedia/audio/audiooutput/audiooutput.cpp | 34 ++-- .../multimedia/audio/audiooutput/audiooutput.h | 2 - 5 files changed, 83 insertions(+), 193 deletions(-) diff --git a/doc/src/examples/audioinput.qdoc b/doc/src/examples/audioinput.qdoc index 0b1b551..ac44d75 100644 --- a/doc/src/examples/audioinput.qdoc +++ b/doc/src/examples/audioinput.qdoc @@ -49,6 +49,6 @@ 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 + This example calculates the maximum linear value of the input audio from the microphone and displays the output. */ diff --git a/examples/multimedia/audio/audioinput/audioinput.cpp b/examples/multimedia/audio/audioinput/audioinput.cpp index c09e7d9..05723ae 100644 --- a/examples/multimedia/audio/audioinput/audioinput.cpp +++ b/examples/multimedia/audio/audioinput/audioinput.cpp @@ -50,46 +50,31 @@ #include #include "audioinput.h" -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif +#define BUFFER_SIZE 4096 -Spectrum::Spectrum(QObject* parent, QAudioInput* device, float* out) +AudioInfo::AudioInfo(QObject* parent, QAudioInput* device) :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); - } + m_maxValue = 0; } -Spectrum::~Spectrum() +AudioInfo::~AudioInfo() { } -void Spectrum::start() +void AudioInfo::start() { open(QIODevice::WriteOnly); } -void Spectrum::stop() +void AudioInfo::stop() { close(); } -qint64 Spectrum::readData(char *data, qint64 maxlen) +qint64 AudioInfo::readData(char *data, qint64 maxlen) { Q_UNUSED(data) Q_UNUSED(maxlen) @@ -97,97 +82,39 @@ qint64 Spectrum::readData(char *data, qint64 maxlen) return 0; } -qint64 Spectrum::writeData(const char *data, qint64 len) +qint64 AudioInfo::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); + int samples = len/2; // 2 bytes per sample + int maxAmp = 32768; // max for S16 samples + bool clipping = false; - /* Calculate FFT */ - calcFFT(fftState->real, fftState->imag); - - /* Convert FFT to intensities */ - outputFFT(fftState->real, fftState->imag); -} + m_maxValue = 0; -void Spectrum::prepFFT(const sound_sample *input, float * re, float * im) { - unsigned int i; - float *realptr = re; - float *imagptr = im; + qint16* s = (qint16*)data; - /* Get input, in reverse bit order */ - for(i = 0; i < BUFFER_SIZE; i++) { - *realptr++ = input[bitReverse[i]]; - *imagptr++ = 0; - } -} + // sample format is S16LE, only! -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; + for(int i=0;i m_maxValue) m_maxValue = abs(sample); } -} + // check for clipping + if(m_maxValue>=(maxAmp-1)) clipping = true; -void Spectrum::outputFFT(const float * re, const float * im) { - const float *realptr = re; - const float *imagptr = im; - float *outputptr = output; + float value = ((float)m_maxValue/(float)maxAmp); + if(clipping) m_maxValue = 100; + else m_maxValue = (int)(value*100); - float *endptr = output + BUFFER_SIZE / 2; - - /* Convert FFT to intensities */ + emit update(); - while(outputptr <= endptr) { - *outputptr = (*realptr * *realptr) + (*imagptr * *imagptr); - outputptr++; realptr++; imagptr++; - } - *output /= 4; - *endptr /= 4; + return len; } +int AudioInfo::LinearMax() +{ + return m_maxValue; +} RenderArea::RenderArea(QWidget *parent) : QWidget(parent) @@ -195,8 +122,7 @@ RenderArea::RenderArea(QWidget *parent) setBackgroundRole(QPalette::Base); setAutoFillBackground(true); - samples = 0; - sampleSize = 0; + level = 0; setMinimumHeight(30); setMinimumWidth(200); } @@ -205,38 +131,32 @@ void RenderArea::paintEvent(QPaintEvent * /* event */) { QPainter painter(this); - if(sampleSize == 0) + painter.setPen(Qt::black); + painter.drawRect(QRect(painter.viewport().left()+10, painter.viewport().top()+10, + painter.viewport().right()-20, painter.viewport().bottom()-20)); + + if(level == 0) return; painter.setPen(Qt::red); - int max = 0; - for(int i=0;i max) - max = m; - } - int x1,y1,x2,y2; + int pos = ((painter.viewport().right()-20)-(painter.viewport().left()+11))*level/100; + 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; + x2 = painter.viewport().left()+20+pos; 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) +void RenderArea::setLevel(int value) { - samples = output; - sampleSize = size; + level = value; repaint(); } @@ -271,25 +191,25 @@ InputTest::InputTest() setCentralWidget(window); window->show(); - buffer = new char[BUFFER_SIZE*10]; - output = new float[1024]; + buffer = new char[BUFFER_SIZE]; pullMode = true; + // AudioInfo class only supports mono S16LE samples! format.setFrequency(8000); format.setChannels(1); - format.setSampleSize(8); - format.setSampleType(QAudioFormat::UnSignedInt); + format.setSampleSize(16); + format.setSampleType(QAudioFormat::SignedInt); 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); + audioinfo = new AudioInfo(this,audioInput); + connect(audioinfo,SIGNAL(update()),SLOT(refreshDisplay())); + audioinfo->start(); + audioInput->start(audioinfo); } InputTest::~InputTest() {} @@ -304,11 +224,11 @@ void InputTest::readMore() if(!audioInput) return; qint64 len = audioInput->bytesReady(); - if(len > BUFFER_SIZE*10) - len = BUFFER_SIZE*10; + if(len > 4096) + len = 4096; qint64 l = input->read(buffer,len); if(l > 0) { - spec->write(buffer,l); + audioinfo->write(buffer,l); } } @@ -317,15 +237,15 @@ void InputTest::toggleMode() // Change bewteen pull and push modes audioInput->stop(); - if(pullMode) { - button->setText(tr("Click for Push Mode")); + if (pullMode) { + button->setText(tr("Click for Pull Mode")); input = audioInput->start(0); connect(input,SIGNAL(readyRead()),SLOT(readMore())); pullMode = false; } else { - button->setText(tr("Click for Pull Mode")); + button->setText(tr("Click for Push Mode")); pullMode = true; - audioInput->start(spec); + audioInput->start(audioinfo); } } @@ -356,13 +276,13 @@ void InputTest::state(QAudio::State state) void InputTest::refreshDisplay() { - canvas->spectrum(output,256); + canvas->setLevel(audioinfo->LinearMax()); canvas->repaint(); } void InputTest::deviceChanged(int idx) { - spec->stop(); + audioinfo->stop(); audioInput->stop(); audioInput->disconnect(this); delete audioInput; @@ -371,6 +291,6 @@ void InputTest::deviceChanged(int idx) 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); + audioinfo->start(); + audioInput->start(audioinfo); } diff --git a/examples/multimedia/audio/audioinput/audioinput.h b/examples/multimedia/audio/audioinput/audioinput.h index 7ba6f1f..14e1bac 100644 --- a/examples/multimedia/audio/audioinput/audioinput.h +++ b/examples/multimedia/audio/audioinput/audioinput.h @@ -48,42 +48,25 @@ #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 +class AudioInfo : public QIODevice { Q_OBJECT public: - Spectrum(QObject* parent, QAudioInput* device, float* out); - ~Spectrum(); + AudioInfo(QObject* parent, QAudioInput* device); + ~AudioInfo(); void start(); void stop(); + int LinearMax(); + 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); +private: + int m_maxValue; signals: void update(); @@ -97,16 +80,14 @@ class RenderArea : public QWidget public: RenderArea(QWidget *parent = 0); - void spectrum(float* output, int size); + void setLevel(int value); protected: void paintEvent(QPaintEvent *event); private: + int level; QPixmap pixmap; - - float* samples; - int sampleSize; }; class InputTest : public QMainWindow @@ -119,7 +100,7 @@ public: QAudioDeviceInfo device; QAudioFormat format; QAudioInput* audioInput; - Spectrum* spec; + AudioInfo* audioinfo; QIODevice* input; RenderArea* canvas; @@ -130,7 +111,6 @@ public: QComboBox* deviceBox; char* buffer; - float* output; private slots: void refreshDisplay(); diff --git a/examples/multimedia/audio/audiooutput/audiooutput.cpp b/examples/multimedia/audio/audiooutput/audiooutput.cpp index 19f7a3f..9e532cd 100644 --- a/examples/multimedia/audio/audiooutput/audiooutput.cpp +++ b/examples/multimedia/audio/audiooutput/audiooutput.cpp @@ -50,18 +50,19 @@ #define M_PI 3.14159265358979323846 #endif +#define SECONDS 1 +#define FREQ 600 +#define SYSTEM_FREQ 44100 + Generator::Generator(QObject *parent) :QIODevice( parent ) { finished = false; - buffer = new char[SECONDS*44100*4+1000]; + buffer = new char[SECONDS*SYSTEM_FREQ*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); + len=fillData(t,FREQ,SECONDS); /* mono FREQHz sine */ pos = 0; - total = len+8+16+8; + total = len; } Generator::~Generator() @@ -86,21 +87,12 @@ int Generator::putShort(char *t, unsigned int value) 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) { + if(len < (SECONDS*SYSTEM_FREQ*2)-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; + qint64 left = (SECONDS*SYSTEM_FREQ*2)-pos; memcpy(data,t+pos,left); pos=0; return left; @@ -172,8 +164,8 @@ AudioTest::AudioTest() gen->start(); - settings.setFrequency(44100); - settings.setChannels(2); + settings.setFrequency(SYSTEM_FREQ); + settings.setChannels(1); settings.setSampleSize(16); settings.setCodec("audio/pcm"); settings.setByteOrder(QAudioFormat::LittleEndian); diff --git a/examples/multimedia/audio/audiooutput/audiooutput.h b/examples/multimedia/audio/audiooutput/audiooutput.h index a5c0289..6c07a3a 100644 --- a/examples/multimedia/audio/audiooutput/audiooutput.h +++ b/examples/multimedia/audio/audiooutput/audiooutput.h @@ -42,7 +42,6 @@ #include #define BUFFER_SIZE 32768 -#define SECONDS 3 #include #include @@ -76,7 +75,6 @@ public: private: int putShort(char *t, unsigned int value); - int putLong(char *t, unsigned int value); int fillData(char *start, int frequency, int seconds); }; -- cgit v0.12 From 856b36f49b567a1573d119b5606300c07649b443 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 24 Sep 2009 09:15:10 +0200 Subject: Compile tests --- tests/auto/qcompleter/tst_qcompleter.cpp | 2 +- tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/auto/qcompleter/tst_qcompleter.cpp b/tests/auto/qcompleter/tst_qcompleter.cpp index f7b9d98..43205e1 100644 --- a/tests/auto/qcompleter/tst_qcompleter.cpp +++ b/tests/auto/qcompleter/tst_qcompleter.cpp @@ -1011,7 +1011,7 @@ void tst_QCompleter::multipleWidgets() QWidget window; window.show(); QApplication::setActiveWindow(&window); - QApplicaion::qWaitForWindowShown(&window); + QTest::qWaitForWindowShown(&window); QTRY_VERIFY(qApp->activeWindow() == &window); QFocusEvent focusIn(QEvent::FocusIn); diff --git a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp index b92e140..f86e81d 100644 --- a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp +++ b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp @@ -55,10 +55,10 @@ public: int duration() const { return -1; /* not time driven */ } protected: - void updateCurrentTime(int msecs) + void updateCurrentTime() { - QPropertyAnimation::updateCurrentTime(msecs); - if (msecs >= QPropertyAnimation::duration()) + QPropertyAnimation::updateCurrentTime(); + if (currentTime() >= QPropertyAnimation::duration() || currentLoop() >= 1) stop(); } }; @@ -239,7 +239,7 @@ void tst_QPropertyAnimation::statesAndSignals() { QFETCH(bool, uncontrolled); QPropertyAnimation *anim; - if (uncontrolled) + if (uncontrolled) anim = new UncontrolledAnimation; else anim = new DummyPropertyAnimation; -- cgit v0.12 From e8a71fcacb21897418b80ac1977b3a5c64b4fb71 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 24 Sep 2009 01:12:29 +0200 Subject: Fixes for WebKit trunk import Updated file lists. Reviewed-by: Trust me --- util/webkit/mkdist-webkit | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/util/webkit/mkdist-webkit b/util/webkit/mkdist-webkit index 49d4785..3afccba 100755 --- a/util/webkit/mkdist-webkit +++ b/util/webkit/mkdist-webkit @@ -42,7 +42,7 @@ excluded_directories="$excluded_directories JavaScriptCore/JavaScriptCore.xcodep excluded_directories="$excluded_directories JavaScriptCore/tests" excluded_directories="$excluded_directories JavaScriptCore/API/tests" excluded_directories="$excluded_directories JavaScriptCore/JavaScriptCore.vcproj" -excluded_directories="$excluded_directories JavaScriptCore/JavaScriptCore.pro" +excluded_directories="$excluded_directories JavaScriptCore/JavaScriptCore.gyp" excluded_directories="$excluded_directories JavaScriptCore/wtf/wx" excluded_directories="$excluded_directories JavaScriptCore/wtf/gtk" excluded_directories="$excluded_directories JavaScriptCore/wtf/mac" @@ -51,9 +51,12 @@ excluded_directories="$excluded_directories JavaScriptCore/wtf/chromium" excluded_directories="$excluded_directories JavaScriptCore/wtf/haiku" excluded_directories="$excluded_directories WebCore/WebCore.vcproj" +excluded_directories="$excluded_directories WebCore/WebCore.gyp" excluded_directories="$excluded_directories WebCore/DerivedSources.make" excluded_directories="$excluded_directories WebCore/GNUmakefile.am" excluded_directories="$excluded_directories WebCore/WebCore.base.exp" +excluded_directories="$excluded_directories WebCore/WebCore.PluginHostProcess.exp" +excluded_directories="$excluded_directories WebCore/WebCore.OrientationEvents.exp" excluded_directories="$excluded_directories WebCore/WebCore.xcodeproj" excluded_directories="$excluded_directories WebCore/Configurations" @@ -145,6 +148,7 @@ excluded_directories="$excluded_directories WebKit/win" excluded_directories="$excluded_directories WebKit/wx" excluded_directories="$excluded_directories WebKit/cf" excluded_directories="$excluded_directories WebKit/haiku" +excluded_directories="$excluded_directories WebKit/chromium" excluded_directories="$excluded_directories WebKit/English.lproj WebKit/WebKit.xcodeproj" excluded_directories="$excluded_directories WebCore/English.lproj" -- cgit v0.12 From 6d21ee6269a40c0d70e358cc1149d332ca84f868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 23 Sep 2009 14:22:03 +0200 Subject: Made fast blur in GL 2 engine be radius independent. This is useful when animating the blur radius, as you don't want to suffer the hit of compiling / linking a new shader program for each radius the first time the animation is played. Also use the fast blur when the radius is 5 or below, as the quality difference is insignificant. Reviewed-by: Rhys Weatherley --- .../gl2paintengineex/qpaintengineex_opengl2_p.h | 1 + src/opengl/qglpixmapfilter.cpp | 236 +++++++++------------ 2 files changed, 97 insertions(+), 140 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 738626f..f245945 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -273,6 +273,7 @@ public: QScopedPointer convolutionFilter; QScopedPointer colorizeFilter; QScopedPointer blurFilter; + QScopedPointer fastBlurFilter; }; QT_END_NAMESPACE diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp index b48c497..b68ff45 100644 --- a/src/opengl/qglpixmapfilter.cpp +++ b/src/opengl/qglpixmapfilter.cpp @@ -102,7 +102,7 @@ private: class QGLPixmapBlurFilter : public QGLCustomShaderStage, public QGLPixmapFilter { public: - QGLPixmapBlurFilter(); + QGLPixmapBlurFilter(Qt::TransformationMode quality); void setUniforms(QGLShaderProgram *program); @@ -110,15 +110,14 @@ protected: bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const; private: - static QByteArray generateBlurShader(int radius, bool gaussianBlur); + static QByteArray generateGaussianShader(int radius); mutable QSize m_textureSize; - mutable bool m_horizontalBlur; mutable bool m_haveCached; mutable int m_cachedRadius; - mutable Qt::TransformationMode m_cachedQuality; + mutable Qt::TransformationMode m_quality; }; extern QGLWidget *qt_gl_share_widget(); @@ -132,10 +131,17 @@ QPixmapFilter *QGL2PaintEngineEx::pixmapFilter(int type, const QPixmapFilter *pr d->colorizeFilter.reset(new QGLPixmapColorizeFilter); return d->colorizeFilter.data(); - case QPixmapFilter::BlurFilter: + case QPixmapFilter::BlurFilter: { + const QPixmapBlurFilter *proto = static_cast(prototype); + if (proto->quality() == Qt::FastTransformation || proto->radius() <= 5) { + if (!d->fastBlurFilter) + d->fastBlurFilter.reset(new QGLPixmapBlurFilter(Qt::FastTransformation)); + return d->fastBlurFilter.data(); + } if (!d->blurFilter) - d->blurFilter.reset(new QGLPixmapBlurFilter); + d->blurFilter.reset(new QGLPixmapBlurFilter(Qt::SmoothTransformation)); return d->blurFilter.data(); + } case QPixmapFilter::ConvolutionFilter: if (!d->convolutionFilter) @@ -309,10 +315,29 @@ bool QGLPixmapConvolutionFilter::processGL(QPainter *, const QPointF &pos, const return true; } -QGLPixmapBlurFilter::QGLPixmapBlurFilter() - : m_haveCached(false), m_cachedRadius(5), - m_cachedQuality(Qt::FastTransformation) +static const char *qt_gl_blur_filter_fast = + "const int samples = 9;" + "uniform mediump vec2 delta;" + "lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords) {" + " mediump vec4 color = vec4(0.0, 0.0, 0.0, 0.0);" + " mediump float offset = (float(samples) - 1.0) / 2.0;" + " for (int i = 0; i < samples; i++) {" + " mediump vec2 coord = srcCoords + delta * (offset - float(i)) / offset;" + " color += texture2D(src, coord);" + " }" + " return color * (1.0 / float(samples));" + "}"; + +QGLPixmapBlurFilter::QGLPixmapBlurFilter(Qt::TransformationMode quality) + : m_haveCached(false) + , m_cachedRadius(5) + , m_quality(quality) { + if (quality == Qt::FastTransformation) { + QGLPixmapBlurFilter *filter = const_cast(this); + filter->setSource(qt_gl_blur_filter_fast); + m_haveCached = true; + } } bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &) const @@ -320,15 +345,11 @@ bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const QGLPixmapBlurFilter *filter = const_cast(this); int radius = this->radius(); - Qt::TransformationMode quality = this->quality(); - - if (!m_haveCached || radius != m_cachedRadius || - quality != m_cachedQuality) { + if (!m_haveCached || (m_quality == Qt::SmoothTransformation && radius != m_cachedRadius)) { // Only regenerate the shader from source if parameters have changed. m_haveCached = true; m_cachedRadius = radius; - m_cachedQuality = quality; - filter->setSource(generateBlurShader(radius, quality == Qt::SmoothTransformation)); + filter->setSource(generateGaussianShader(radius)); } QGLFramebufferObjectFormat format; @@ -386,12 +407,21 @@ bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const void QGLPixmapBlurFilter::setUniforms(QGLShaderProgram *program) { - program->setUniformValue("invTextureSize", 1.0 / m_textureSize.width(), 1.0 / m_textureSize.height()); + if (m_quality == Qt::SmoothTransformation) { + if (m_horizontalBlur) + program->setUniformValue("delta", 1.0 / m_textureSize.width(), 0.0); + else + program->setUniformValue("delta", 0.0, 1.0 / m_textureSize.height()); + } else { + // 1.4 is chosen to most closely match the blurriness of the gaussian blur + // at low radii + qreal blur = radius() / 1.4f; - if (m_horizontalBlur) - program->setUniformValue("delta", 1.0, 0.0); - else - program->setUniformValue("delta", 0.0, 1.0); + if (m_horizontalBlur) + program->setUniformValue("delta", blur / m_textureSize.width(), 0.0); + else + program->setUniformValue("delta", 0.0, blur / m_textureSize.height()); + } } static inline qreal gaussian(qreal dx, qreal sigma) @@ -399,68 +429,46 @@ static inline qreal gaussian(qreal dx, qreal sigma) return exp(-dx * dx / (2 * sigma * sigma)) / (Q_2PI * sigma * sigma); } -QByteArray QGLPixmapBlurFilter::generateBlurShader(int radius, bool gaussianBlur) +QByteArray QGLPixmapBlurFilter::generateGaussianShader(int radius) { Q_ASSERT(radius >= 1); QByteArray source; source.reserve(1000); - source.append("uniform highp vec2 invTextureSize;\n"); - - bool separateXY = true; - bool clip = false; - - if (separateXY) { - source.append("uniform highp vec2 delta;\n"); - - if (clip) - source.append("uniform highp vec2 clip;\n"); - } else if (clip) { - source.append("uniform highp vec4 clip;\n"); - } - + source.append("uniform highp vec2 delta;\n"); source.append("lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords) {\n"); QVector sampleOffsets; QVector weights; - if (gaussianBlur) { - QVector gaussianComponents; + QVector gaussianComponents; - qreal sigma = radius / 1.65; + qreal sigma = radius / 1.65; - qreal sum = 0; - for (int i = -radius; i <= radius; ++i) { - float value = gaussian(i, sigma); - gaussianComponents << value; - sum += value; - } + qreal sum = 0; + for (int i = -radius; i <= radius; ++i) { + float value = gaussian(i, sigma); + gaussianComponents << value; + sum += value; + } - // normalize - for (int i = 0; i < gaussianComponents.size(); ++i) - gaussianComponents[i] /= sum; + // normalize + for (int i = 0; i < gaussianComponents.size(); ++i) + gaussianComponents[i] /= sum; - for (int i = 0; i < gaussianComponents.size() - 1; i += 2) { - qreal weight = gaussianComponents.at(i) + gaussianComponents.at(i + 1); - qreal offset = i - radius + gaussianComponents.at(i + 1) / weight; + for (int i = 0; i < gaussianComponents.size() - 1; i += 2) { + qreal weight = gaussianComponents.at(i) + gaussianComponents.at(i + 1); + qreal offset = i - radius + gaussianComponents.at(i + 1) / weight; - sampleOffsets << offset; - weights << weight; - } + sampleOffsets << offset; + weights << weight; + } - // odd size ? - if (gaussianComponents.size() & 1) { - sampleOffsets << radius; - weights << gaussianComponents.last(); - } - } else { - for (int i = 0; i < radius; ++i) { - sampleOffsets << 2 * i - radius + 0.5; - weights << qreal(1); - } + // odd size ? + if (gaussianComponents.size() & 1) { sampleOffsets << radius; - weights << qreal(0.5); + weights << gaussianComponents.last(); } int currentVariable = 1; @@ -468,88 +476,36 @@ QByteArray QGLPixmapBlurFilter::generateBlurShader(int radius, bool gaussianBlur source.append(" mediump vec2 coord;\n"); qreal weightSum = 0; - if (separateXY) { - source.append(" mediump float c;\n"); - for (int i = 0; i < sampleOffsets.size(); ++i) { - qreal delta = sampleOffsets.at(i); - - ++currentVariable; - - QByteArray coordinate = "srcCoords"; - if (delta != qreal(0)) { - coordinate.append(" + invTextureSize * delta * float("); - coordinate.append(QByteArray::number(delta)); - coordinate.append(")"); - } - - source.append(" coord = "); - source.append(coordinate); - source.append(";\n"); + source.append(" mediump float c;\n"); + for (int i = 0; i < sampleOffsets.size(); ++i) { + qreal delta = sampleOffsets.at(i); + + ++currentVariable; - if (clip) { - source.append(" c = dot(coord, delta);\n"); - source.append(" if (c > clip.x && c < clip.y)\n "); - } - - source.append(" sample += texture2D(src, coord)"); - - weightSum += weights.at(i); - if (weights.at(i) != qreal(1)) { - source.append(" * float("); - source.append(QByteArray::number(weights.at(i))); - source.append(");\n"); - } else { - source.append(";\n"); - } + QByteArray coordinate = "srcCoords"; + if (delta != qreal(0)) { + coordinate.append(" + delta * float("); + coordinate.append(QByteArray::number(delta)); + coordinate.append(")"); } - } else { - for (int y = 0; y < sampleOffsets.size(); ++y) { - for (int x = 0; x < sampleOffsets.size(); ++x) { - QByteArray coordinate = "srcCoords"; - - qreal dx = sampleOffsets.at(x); - qreal dy = sampleOffsets.at(y); - - if (dx != qreal(0) || dy != qreal(0)) { - coordinate.append(" + invTextureSize * vec2(float("); - coordinate.append(QByteArray::number(dx)); - coordinate.append("), float("); - coordinate.append(QByteArray::number(dy)); - coordinate.append("))"); - } - - source.append(" coord = "); - source.append(coordinate); - source.append(";\n"); - - if (clip) - source.append(" if (coord.x > clip.x && coord.x < clip.y && coord.y > clip.z && coord.y < clip.w)\n "); - - source.append(" sample += texture2D(src, coord)"); - - ++currentVariable; - - weightSum += weights.at(x) * weights.at(y); - if ((weights.at(x) != qreal(1) || weights.at(y) != qreal(1))) { - source.append(" * float("); - source.append(QByteArray::number(weights.at(x) * weights.at(y))); - source.append(");\n"); - } else { - source.append(";\n"); - } - } + + source.append(" coord = "); + source.append(coordinate); + source.append(";\n"); + + source.append(" sample += texture2D(src, coord)"); + + weightSum += weights.at(i); + if (weights.at(i) != qreal(1)) { + source.append(" * float("); + source.append(QByteArray::number(weights.at(i))); + source.append(");\n"); + } else { + source.append(";\n"); } } source.append(" return "); - if (!gaussianBlur) { - source.append("float("); - if (separateXY) - source.append(QByteArray::number(1 / weightSum)); - else - source.append(QByteArray::number(1 / weightSum)); - source.append(") * "); - } source.append("sample;\n"); source.append("}\n"); -- cgit v0.12 From d57e2f4d01534f44dde629b71398783777fdad4e Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 24 Sep 2009 09:36:35 +0200 Subject: Stabilize Q3Table test If there is no focus widget while doing keyClick, the test crashes --- tests/auto/q3table/tst_q3table.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/auto/q3table/tst_q3table.cpp b/tests/auto/q3table/tst_q3table.cpp index f911dd4..770bf4d 100644 --- a/tests/auto/q3table/tst_q3table.cpp +++ b/tests/auto/q3table/tst_q3table.cpp @@ -523,6 +523,7 @@ void tst_Q3Table::simpleKeyboardNavigation() // After the first keyevent, the table starts editing the item w = testWidget->cellWidget(0, 0); + QVERIFY(w); #ifdef WAITS QTest::qWait(50); @@ -1205,12 +1206,17 @@ void tst_Q3Table::editCheck() EditCheckQ3Table table(10, 10, 0); table.show(); + QApplication::setActiveWindow(&table); QTest::qWaitForWindowShown(&table); + QTRY_COMPARE(QApplication::activeWindow(), &table); table.setCurrentCell(0, 0); #ifdef WAITS QTest::qWait(50); #endif QTest::keyClick(table.viewport(), Qt::Key_T); +#ifdef WAITS + QTest::qWait(50); +#endif // After the first keyevent, the table starts editing the item QLineEdit *le = qFindChild(testWidget->viewport(), "qt_lineeditor"); #ifdef WAITS @@ -1337,6 +1343,9 @@ void tst_Q3Table::valueChanged() testWidget->setItem(0, 0, ti); connect(testWidget,SIGNAL(valueChanged(int,int)),this,SLOT(onValueChanged(int,int))); testWidget->show(); + QApplication::setActiveWindow(testWidget); + QTest::qWaitForWindowShown(testWidget); + QTRY_COMPARE(QApplication::activeWindow(), testWidget); #ifdef WAITS QTest::qWait(50); #endif @@ -1344,6 +1353,7 @@ void tst_Q3Table::valueChanged() #ifdef WAITS QTest::qWait(50); #endif + QTRY_VERIFY(qApp->focusWidget()); QTest::keyClick(qApp->focusWidget(), Qt::Key_Enter); #ifdef WAITS QTest::qWait(50); @@ -1383,7 +1393,9 @@ void tst_Q3Table::dateTimeEdit() TimeTableItem *ti = new TimeTableItem(testWidget); testWidget->setItem(0, 0, ti); testWidget->show(); + QApplication::setActiveWindow(testWidget); QTest::qWaitForWindowShown(testWidget); + QTRY_COMPARE(QApplication::activeWindow(), testWidget); #ifdef WAITS QTest::qWait(50); #endif @@ -1391,6 +1403,7 @@ void tst_Q3Table::dateTimeEdit() #ifdef WAITS QTest::qWait(50); #endif + QTRY_VERIFY(qApp->focusWidget()); QTest::keyClick(qApp->focusWidget(), Qt::Key_Enter); #ifdef WAITS QTest::qWait(50); -- cgit v0.12