From add4d83be92f332246adf851d89c27b60b4737dc Mon Sep 17 00:00:00 2001 From: David Boddie Date: Fri, 4 Dec 2009 16:57:36 +0100 Subject: Doc: Added links to missing examples and placeholder documentation. Reviewed-by: Trust Me --- doc/src/examples/fademessage.qdoc | 10 +++++++++- doc/src/getting-started/examples.qdoc | 16 +++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/doc/src/examples/fademessage.qdoc b/doc/src/examples/fademessage.qdoc index ecea095..6063fa7 100644 --- a/doc/src/examples/fademessage.qdoc +++ b/doc/src/examples/fademessage.qdoc @@ -43,5 +43,13 @@ \example effects/fademessage \title Fade Message Effect Example - \image fademessageeffect-example.png + \raw HTML +
+ \endraw + \inlineimage fademessageeffect-example.png + \inlineimage fademessageeffect-example-faded.png + \raw HTML +
+ \endraw + */ diff --git a/doc/src/getting-started/examples.qdoc b/doc/src/getting-started/examples.qdoc index f0a6799..2d4f5c9 100644 --- a/doc/src/getting-started/examples.qdoc +++ b/doc/src/getting-started/examples.qdoc @@ -546,6 +546,14 @@ \o \l{graphicsview/portedcanvas}{Ported Canvas} \endlist + Some examples demonstrate the use of graphics effects with canvas items. + + \list + \o \l{effects/blurpicker}{Blur Picker Effect} + \o \l{effects/fademessage}{Fade Message Effect} + \o \l{effects/lighting}{Lighting Effect} + \endlist + Examples marked with an asterisk (*) are fully documented. */ @@ -851,11 +859,13 @@ \section1 Multimedia - Qt provides low-level audio support on linux,windows and mac platforms by default and - an audio plugin API to allow developers to implement there own audio support for + Qt provides low-level audio support on Linux, Windows and Mac OS X by default and + an audio plugin API to allow developers to implement their own audio support for custom devices and platforms. - These examples demonstrate the basic techniques used to take advantage of + \section1 Audio Handling + + These examples demonstrate the basic techniques used to take advantage of the Audio API in Qt applications. \list -- cgit v0.12 From 4b09e47add266c44b15bd3748cf2ef948b8512fb Mon Sep 17 00:00:00 2001 From: David Boddie Date: Fri, 4 Dec 2009 16:58:55 +0100 Subject: Doc: Whitespace fix. Reviewed-by: Trust Me --- doc/src/modules.qdoc | 91 ++++++++++++++++++++++++++-------------------------- 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/doc/src/modules.qdoc b/doc/src/modules.qdoc index 3058b84..5e759db 100644 --- a/doc/src/modules.qdoc +++ b/doc/src/modules.qdoc @@ -409,59 +409,58 @@ */ /*! - \module QtSvg - \title QtSvg Module - \since 4.1 - \contentspage All Qt Modules - \previouspage QtSql - \nextpage QtWebKit - \ingroup modules + \module QtSvg + \title QtSvg Module + \since 4.1 + \contentspage All Qt Modules + \previouspage QtSql + \nextpage QtWebKit + \ingroup modules - \brief The QtSvg module provides classes for displaying the contents of SVG - files. + \brief The QtSvg module provides classes for displaying and creating SVG files. - To include the definitions of the module's classes, use the - following directive: + To include the definitions of the module's classes, use the + following directive: - \snippet doc/src/snippets/code/doc_src_qtsvg.qdoc 0 + \snippet doc/src/snippets/code/doc_src_qtsvg.qdoc 0 - To link against the module, add this line to your \l qmake \c - .pro file: + To link against the module, add this line to your \l qmake \c + .pro file: - \snippet doc/src/snippets/code/doc_src_qtsvg.qdoc 1 + \snippet doc/src/snippets/code/doc_src_qtsvg.qdoc 1 - The QtSvg module is part of the \l{Qt Full Framework Edition} and the - \l{Open Source Versions of Qt}. + The QtSvg module is part of the \l{Qt Full Framework Edition} and the + \l{Open Source Versions of Qt}. - \section1 License Information - - Some code for arc handling in this module is derived from code with - the following license: - - \legalese - Copyright 2002 USC/Information Sciences Institute - - Permission to use, copy, modify, distribute, and sell this software - and its documentation for any purpose is hereby granted without - fee, provided that the above copyright notice appear in all copies - and that both that copyright notice and this permission notice - appear in supporting documentation, and that the name of - Information Sciences Institute not be used in advertising or - publicity pertaining to distribution of the software without - specific, written prior permission. Information Sciences Institute - makes no representations about the suitability of this software for - any purpose. It is provided "as is" without express or implied - warranty. - - INFORMATION SCIENCES INSTITUTE DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL INFORMATION SCIENCES - INSTITUTE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA - OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. - \endlegalese + \section1 License Information + + Some code for arc handling in this module is derived from code with + the following license: + + \legalese + Copyright 2002 USC/Information Sciences Institute + + Permission to use, copy, modify, distribute, and sell this software + and its documentation for any purpose is hereby granted without + fee, provided that the above copyright notice appear in all copies + and that both that copyright notice and this permission notice + appear in supporting documentation, and that the name of + Information Sciences Institute not be used in advertising or + publicity pertaining to distribution of the software without + specific, written prior permission. Information Sciences Institute + makes no representations about the suitability of this software for + any purpose. It is provided "as is" without express or implied + warranty. + + INFORMATION SCIENCES INSTITUTE DISCLAIMS ALL WARRANTIES WITH REGARD + TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL INFORMATION SCIENCES + INSTITUTE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA + OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + \endlegalese */ /*! -- cgit v0.12 From 8577da4a70be7400b1dc7d2265a31de46f8e8bb9 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Fri, 4 Dec 2009 16:59:25 +0100 Subject: Doc: Fixed license information as requested by Legal. Reviewed-by: Trust Me --- doc/src/frameworks-technologies/dnd.qdoc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/doc/src/frameworks-technologies/dnd.qdoc b/doc/src/frameworks-technologies/dnd.qdoc index a7b1622..65fddfb 100644 --- a/doc/src/frameworks-technologies/dnd.qdoc +++ b/doc/src/frameworks-technologies/dnd.qdoc @@ -426,6 +426,7 @@ \legalese Copyright 1996 Daniel Dardailler. + Copyright 1999 Matt Koss Permission to use, copy, modify, distribute, and sell this software for any purpose is hereby granted without fee, provided that the above @@ -436,13 +437,11 @@ written prior permission. Daniel Dardailler makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. - - Modifications Copyright 1999 Matt Koss, under the same license as - above. \endlegalese - \omit NOTE: The copyright notice is from qmotifdnd_x11.cpp. \endomit + \omit NOTE: The original version of this copyright notice can be found + in qmotifdnd_x11.cpp. \endomit - Note: The Motif Drag \& Drop Protocol only allows receivers to + \note The Motif Drag \& Drop Protocol only allows receivers to request data in response to a QDropEvent. If you attempt to request data in response to e.g. a QDragMoveEvent, an empty QByteArray is returned. -- cgit v0.12 From f4f28a0d32758476a3f5733054a50b9b36392288 Mon Sep 17 00:00:00 2001 From: Mikkel Krautz Date: Mon, 7 Dec 2009 12:43:20 +0100 Subject: Don't forget to append current $MAC_CONFIG_TEST_COMMANDLINE when setting the SDK to use. Merge-request: 2254 Reviewed-by: Oswald Buddenhagen --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 6dc3898..ee5bbb9 100755 --- a/configure +++ b/configure @@ -2894,7 +2894,7 @@ fi # pass on $CFG_SDK to the configure tests. if [ '!' -z "$CFG_SDK" ]; then - MAC_CONFIG_TEST_COMMANDLINE="-sdk $CFG_SDK" + MAC_CONFIG_TEST_COMMANDLINE="$MAC_CONFIG_TEST_COMMANDLINE -sdk $CFG_SDK" fi # find the default framework value -- cgit v0.12 From 74b0c482b1edf606e1326c9053c612a7e514dee4 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 7 Dec 2009 15:59:20 +0100 Subject: Doc: Fixed references to "old" 2.x and "new" 3.x font name conventions. Reviewed-by: Trust Me As-reported-by: Eskil --- src/gui/text/qfontdatabase.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 7e93aa0..e9c7b89 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -1482,13 +1482,13 @@ QString QFontDatabase::styleString(const QFontInfo &fontInfo) and style will look attractive. If the font family is available from two or more foundries the - foundry name is included in the family name, e.g. "Helvetica - [Adobe]" and "Helvetica [Cronyx]". When you specify a family you - can either use the old hyphenated Qt 2.x "foundry-family" format, - e.g. "Cronyx-Helvetica", or the new bracketed Qt 3.x "family - [foundry]" format e.g. "Helvetica [Cronyx]". If the family has a - foundry it is always returned, e.g. by families(), using the - bracketed format. + foundry name is included in the family name; for example: + "Helvetica [Adobe]" and "Helvetica [Cronyx]". When you specify a + family, you can either use the old hyphenated "foundry-family" + format or the bracketed "family [foundry]" format; for example: + "Cronyx-Helvetica" or "Helvetica [Cronyx]". If the family has a + foundry it is always returned using the bracketed format, as is + the case with the value returned by families(). The font() function returns a QFont given a family, style and point size. -- cgit v0.12 From adef8ffa48c908dda1e2f048469c1e08eec088e3 Mon Sep 17 00:00:00 2001 From: ck Date: Tue, 8 Dec 2009 12:03:47 +0100 Subject: Assistant: Fix race condition in index creation. Reviewed-by: kh1 --- tools/assistant/lib/qhelpindexwidget.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tools/assistant/lib/qhelpindexwidget.cpp b/tools/assistant/lib/qhelpindexwidget.cpp index 475a1fe..6cf1a72 100644 --- a/tools/assistant/lib/qhelpindexwidget.cpp +++ b/tools/assistant/lib/qhelpindexwidget.cpp @@ -130,6 +130,7 @@ void QHelpIndexProvider::stopCollecting() m_abort = true; m_mutex.unlock(); wait(); + m_abort = false; } QStringList QHelpIndexProvider::indices() const @@ -164,7 +165,6 @@ void QHelpIndexProvider::run() foreach (QString dbFileName, m_helpEngine->fileNameReaderMap.keys()) { m_mutex.lock(); if (m_abort) { - m_abort = false; m_mutex.unlock(); return; } @@ -181,7 +181,6 @@ void QHelpIndexProvider::run() foreach (QString s, lst) indicesSet.insert(s); if (m_abort) { - m_abort = false; m_mutex.unlock(); return; } @@ -194,7 +193,6 @@ void QHelpIndexProvider::run() m_mutex.lock(); m_indices = indicesSet.values(); qSort(m_indices.begin(), m_indices.end(), caseInsensitiveLessThan); - m_abort = false; m_mutex.unlock(); } -- cgit v0.12 From f906c0388ebb88b97e40618d448b0df72ebfebc5 Mon Sep 17 00:00:00 2001 From: kh1 Date: Tue, 8 Dec 2009 14:12:28 +0100 Subject: Fix broken delete key, some cleanup. Reviewed-by: ck --- .../assistant/tools/assistant/bookmarkmanager.cpp | 116 ++++++++++++--------- 1 file changed, 68 insertions(+), 48 deletions(-) diff --git a/tools/assistant/tools/assistant/bookmarkmanager.cpp b/tools/assistant/tools/assistant/bookmarkmanager.cpp index 70f3157..523525e 100644 --- a/tools/assistant/tools/assistant/bookmarkmanager.cpp +++ b/tools/assistant/tools/assistant/bookmarkmanager.cpp @@ -69,9 +69,12 @@ BookmarkDialog::BookmarkDialog(BookmarkManager *manager, const QString &title, , m_title(title) , bookmarkManager(manager) { + ui.setupUi(this); + installEventFilter(this); + ui.treeView->installEventFilter(this); + ui.treeView->viewport()->installEventFilter(this); - ui.setupUi(this); ui.bookmarkEdit->setText(title); ui.newFolderButton->setVisible(false); ui.buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); @@ -264,12 +267,14 @@ void BookmarkDialog::currentChanged(const QModelIndex ¤t) bool BookmarkDialog::eventFilter(QObject *object, QEvent *e) { - if (object == this && e->type() == QEvent::KeyPress) { - QKeyEvent *ke = static_cast(e); + if (object != ui.treeView && object != ui.treeView->viewport()) + return QWidget::eventFilter(object, e); - QModelIndex index = ui.treeView->currentIndex(); + if (e->type() == QEvent::KeyPress) { + QKeyEvent *ke = static_cast(e); switch (ke->key()) { case Qt::Key_F2: { + const QModelIndex &index = ui.treeView->currentIndex(); const QModelIndex &source = proxyModel->mapToSource(index); QStandardItem *item = bookmarkManager->treeBookmarkModel()->itemFromIndex(source); @@ -281,13 +286,13 @@ bool BookmarkDialog::eventFilter(QObject *object, QEvent *e) } break; case Qt::Key_Delete: { + const QModelIndex &index = ui.treeView->currentIndex(); bookmarkManager->removeBookmarkItem(ui.treeView, proxyModel->mapToSource(index)); ui.bookmarkFolders->clear(); ui.bookmarkFolders->addItems(bookmarkManager->bookmarkFolders()); QString name = tr("Bookmarks"); - index = ui.treeView->currentIndex(); if (index.isValid()) name = index.data().toString(); ui.bookmarkFolders->setCurrentIndex(ui.bookmarkFolders->findText(name)); @@ -297,6 +302,7 @@ bool BookmarkDialog::eventFilter(QObject *object, QEvent *e) break; } } + return QObject::eventFilter(object, e); } @@ -312,7 +318,10 @@ BookmarkWidget::BookmarkWidget(BookmarkManager *manager, QWidget *parent, , bookmarkManager(manager) { setup(showButtons); + installEventFilter(this); + treeView->installEventFilter(this); + treeView->viewport()->installEventFilter(this); } BookmarkWidget::~BookmarkWidget() @@ -484,7 +493,6 @@ void BookmarkWidget::setup(bool showButtons) treeView->setAutoExpandDelay(1000); treeView->setDropIndicatorShown(true); treeView->header()->setVisible(false); - treeView->viewport()->installEventFilter(this); treeView->setContextMenuPolicy(Qt::CustomContextMenu); connect(treeView, SIGNAL(expanded(QModelIndex)), this, @@ -530,59 +538,71 @@ void BookmarkWidget::focusInEvent(QFocusEvent *e) bool BookmarkWidget::eventFilter(QObject *object, QEvent *e) { - if ((object == this) || (object == treeView->viewport())) { - QModelIndex index = treeView->currentIndex(); - if (e->type() == QEvent::KeyPress) { - QKeyEvent *ke = static_cast(e); - if (index.isValid() && searchField->text().isEmpty()) { + if (object != this && object != treeView + && object != treeView->viewport()) { + return QWidget::eventFilter(object, e); + } + + if (e->type() == QEvent::KeyPress) { + QKeyEvent *ke = static_cast(e); + const bool tree = object == treeView || object == treeView->viewport(); + switch (ke->key()) { + case Qt::Key_F2: { + const QModelIndex &index = treeView->currentIndex(); const QModelIndex &src = filterBookmarkModel->mapToSource(index); - if (ke->key() == Qt::Key_F2) { - QStandardItem *item = - bookmarkManager->treeBookmarkModel()->itemFromIndex(src); - if (item) { + if (tree && searchField->text().isEmpty()) { + if (QStandardItem *item = bookmarkManager->treeBookmarkModel() + ->itemFromIndex(src)) { item->setEditable(true); treeView->edit(index); item->setEditable(false); } - } else if (ke->key() == Qt::Key_Delete) { - bookmarkManager->removeBookmarkItem(treeView, src); } - } + } break; + + case Qt::Key_Enter: { + case Qt::Key_Return: + if (tree) { + const QString &data = treeView->selectionModel()->currentIndex() + .data(Qt::UserRole + 10).toString(); + if (!data.isEmpty() && data != QLatin1String("Folder")) + emit requestShowLink(data); + } + } break; - switch (ke->key()) { - default: break; - case Qt::Key_Up: { - case Qt::Key_Down: + case Qt::Key_Delete: { + const QModelIndex &index = treeView->currentIndex(); + const QModelIndex &src = filterBookmarkModel->mapToSource(index); + if (tree && searchField->text().isEmpty()) + bookmarkManager->removeBookmarkItem(treeView, src); + } break; + + case Qt::Key_Up: { + case Qt::Key_Down: + if (!tree) treeView->subclassKeyPressEvent(ke); - } break; - - case Qt::Key_Enter: { - case Qt::Key_Return: - index = treeView->selectionModel()->currentIndex(); - if (index.isValid()) { - QString data = index.data(Qt::UserRole + 10).toString(); - if (!data.isEmpty() && data != QLatin1String("Folder")) - emit requestShowLink(data); - } - } break; + } break; - case Qt::Key_Escape: { - emit escapePressed(); - } break; - } - } else if (e->type() == QEvent::MouseButtonRelease) { - if (index.isValid()) { - QMouseEvent *me = static_cast(e); - bool controlPressed = me->modifiers() & Qt::ControlModifier; - if(((me->button() == Qt::LeftButton) && controlPressed) - || (me->button() == Qt::MidButton)) { - QString data = index.data(Qt::UserRole + 10).toString(); - if (!data.isEmpty() && data != QLatin1String("Folder")) - CentralWidget::instance()->setSourceInNewTab(data); - } - } + case Qt::Key_Escape: { + emit escapePressed(); + } break; + + default: break; } } + + if (e->type() == QEvent::MouseButtonRelease) { + QMouseEvent *me = static_cast(e); + bool controlPressed = me->modifiers() & Qt::ControlModifier; + if(((me->button() == Qt::LeftButton) && controlPressed) + || (me->button() == Qt::MidButton)) { + const QModelIndex &index = treeView->currentIndex(); + const QString &data = index.data(Qt::UserRole + 10).toString(); + if (!data.isEmpty() && data != QLatin1String("Folder")) + CentralWidget::instance()->setSourceInNewTab(data); + } + } + return QWidget::eventFilter(object, e); } -- cgit v0.12 From 970f19bdb55cd559e9ef97228d30fd52b20e39cb Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 8 Dec 2009 20:28:45 +0100 Subject: Fix crash in QDBusPendingReply/QDBusReply in case of unconnected calls. If we made calls on a QDBusConnection that isn't connected, the d pointer is 0. Ensure we don't crash. Task-number: QTBUG-6571 Reviewed-by: Bradley T. Hughes --- src/dbus/qdbuspendingcall.cpp | 2 +- src/dbus/qdbuspendingreply.h | 1 + .../qdbuspendingreply/tst_qdbuspendingreply.cpp | 25 ++++++++++++++++++++++ tests/auto/qdbusreply/tst_qdbusreply.cpp | 16 ++++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/dbus/qdbuspendingcall.cpp b/src/dbus/qdbuspendingcall.cpp index d10179e..d8eb53e 100644 --- a/src/dbus/qdbuspendingcall.cpp +++ b/src/dbus/qdbuspendingcall.cpp @@ -310,7 +310,7 @@ QDBusPendingCall &QDBusPendingCall::operator=(const QDBusPendingCall &other) bool QDBusPendingCall::isFinished() const { - return d && (d->replyMessage.type() != QDBusMessage::InvalidMessage); + return !d || (d->replyMessage.type() != QDBusMessage::InvalidMessage); } void QDBusPendingCall::waitForFinished() diff --git a/src/dbus/qdbuspendingreply.h b/src/dbus/qdbuspendingreply.h index b7f54e4..4f90c98 100644 --- a/src/dbus/qdbuspendingreply.h +++ b/src/dbus/qdbuspendingreply.h @@ -188,6 +188,7 @@ public: private: inline void calculateMetaTypes() { + if (!d) return; int typeIds[Count > 0 ? Count : 1]; // use at least one since zero-sized arrays aren't valid ForEach::fillMetaTypes(typeIds); setMetaTypes(Count, typeIds); diff --git a/tests/auto/qdbuspendingreply/tst_qdbuspendingreply.cpp b/tests/auto/qdbuspendingreply/tst_qdbuspendingreply.cpp index 6398d9c..82e6389 100644 --- a/tests/auto/qdbuspendingreply/tst_qdbuspendingreply.cpp +++ b/tests/auto/qdbuspendingreply/tst_qdbuspendingreply.cpp @@ -93,6 +93,7 @@ private slots: } void init(); + void unconnected(); void simpleTypes(); void complexTypes(); void wrongTypes(); @@ -252,6 +253,30 @@ void tst_QDBusPendingReply::init() QVERIFY(iface->isValid()); } +void tst_QDBusPendingReply::unconnected() +{ + QDBusConnection con("invalid stored connection"); + QVERIFY(!con.isConnected()); + QDBusInterface iface("doesnt.matter", "/", "doesnt.matter", con); + QVERIFY(!iface.isValid()); + + QDBusPendingReply<> rvoid = iface.asyncCall("ReloadConfig"); + QVERIFY(rvoid.isFinished()); + QVERIFY(!rvoid.isValid()); + QVERIFY(rvoid.isError()); + rvoid.waitForFinished(); + QVERIFY(!rvoid.isValid()); + QVERIFY(rvoid.isError()); + + QDBusPendingReply rstring = iface.asyncCall("GetId"); + QVERIFY(rstring.isFinished()); + QVERIFY(!rstring.isValid()); + QVERIFY(rstring.isError()); + rstring.waitForFinished(); + QVERIFY(!rstring.isValid()); + QVERIFY(rstring.isError()); +} + void tst_QDBusPendingReply::simpleTypes() { QDBusPendingReply<> rvoid = iface->asyncCall("retrieveVoid"); diff --git a/tests/auto/qdbusreply/tst_qdbusreply.cpp b/tests/auto/qdbusreply/tst_qdbusreply.cpp index 9866302..e36d288 100644 --- a/tests/auto/qdbusreply/tst_qdbusreply.cpp +++ b/tests/auto/qdbusreply/tst_qdbusreply.cpp @@ -93,6 +93,7 @@ private slots: } void init(); + void unconnected(); void simpleTypes(); void complexTypes(); void wrongTypes(); @@ -236,6 +237,21 @@ void tst_QDBusReply::init() QVERIFY(iface->isValid()); } +void tst_QDBusReply::unconnected() +{ + QDBusConnection con("invalid stored connection"); + QVERIFY(!con.isConnected()); + QDBusInterface iface("doesnt.matter", "/", "doesnt.matter", con); + QVERIFY(!iface.isValid()); + + QDBusReply rvoid = iface.asyncCall("ReloadConfig"); + QVERIFY(!rvoid.isValid()); + + QDBusReply rstring = iface.asyncCall("GetId"); + QVERIFY(!rstring.isValid()); + QVERIFY(rstring.value().isEmpty()); +} + void tst_QDBusReply::simpleTypes() { QDBusReply rbool = iface->call(QDBus::BlockWithGui, "retrieveBool"); -- cgit v0.12 From a405437ca9294bf4f0f974739bd1130e165491b8 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 9 Dec 2009 13:46:00 +0200 Subject: Access to image needs to be protected in QS60PixmapData The image can get corrupted if access to it is not properly surrounded with beginDataAccess and endDataAccess calls. Task-number: QTBUG-6050 Reviewed-by: Jani Hautakangas --- src/gui/image/qpixmap_s60.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp index dc33ade..610317d 100644 --- a/src/gui/image/qpixmap_s60.cpp +++ b/src/gui/image/qpixmap_s60.cpp @@ -820,7 +820,9 @@ void* QS60PixmapData::toNativeType(NativeType type) 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. + beginDataAccess(); image.invertPixels(); + endDataAccess(); needsCopy = true; } @@ -828,7 +830,9 @@ void* QS60PixmapData::toNativeType(NativeType type) QImage source; if (convertToArgb32) { + beginDataAccess(); source = image.convertToFormat(QImage::Format_ARGB32); + endDataAccess(); displayMode = EColor16MA; } else { source = image; @@ -858,7 +862,9 @@ void* QS60PixmapData::toNativeType(NativeType type) if(displayMode == EGray2) { // restore pixels + beginDataAccess(); image.invertPixels(); + endDataAccess(); } return reinterpret_cast(bitmap); -- cgit v0.12 From ae8a4cfa053b6976933e0d65586ef561d9a209da Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 9 Dec 2009 14:51:42 +0200 Subject: Missing library added to QStringList benchmark for Symbian builds QStringList benchmark uses some std classes which indirectly need pthread library. Task-number: QTBUG-6594 Reviewed-by: Janne Anttila --- tests/benchmarks/qstringlist/qstringlist.pro | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/benchmarks/qstringlist/qstringlist.pro b/tests/benchmarks/qstringlist/qstringlist.pro index f9ebd59..11cceb0 100644 --- a/tests/benchmarks/qstringlist/qstringlist.pro +++ b/tests/benchmarks/qstringlist/qstringlist.pro @@ -2,3 +2,5 @@ load(qttest_p4) TARGET = tst_qstringlist QT -= gui SOURCES += main.cpp + +symbian: LIBS += -llibpthread -- cgit v0.12 From be927c3978347f95b7eeba53fb6750dbf7e188ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20Meril=C3=A4?= Date: Wed, 9 Dec 2009 15:49:47 +0200 Subject: QS60Style: Do not let QCommonStyle draw PE_PanelScrollAreaCorner If QS60Style lets QCommonStyle to draw PE_PanelScrollAreaCorner, common style draws transparent small rect to the end of scrollbar. This is due to our style's palette's Base is Qt::Transparent. Error is only visible when two dialogs/windows are on top of each other and their background is such that a hole in the upper dialog's background will make the hole "visible" (i.e. background is not similar). As a fix, QS60Style should not let QCommonStyle draw the primitive, but instead handle itself (and do nothing with it). Task-number: QTBUG-6657 Reviewed-by: Alessandro Portale --- src/gui/styles/qs60style.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 93b517f..98f4aaf 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -2238,11 +2238,13 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti } break; + case PE_PanelScrollAreaCorner: + break; + // todo: items are below with #ifdefs "just in case". in final version, remove all non-required cases case PE_FrameLineEdit: case PE_IndicatorDockWidgetResizeHandle: case PE_PanelTipLabel: - case PE_PanelScrollAreaCorner: #ifndef QT_NO_TABBAR case PE_IndicatorTabTear: // No tab tear in S60 -- cgit v0.12 From 4d9ef7c20bedd715f3d8d7c644942d688716f785 Mon Sep 17 00:00:00 2001 From: axis Date: Wed, 9 Dec 2009 14:11:30 +0100 Subject: Rewrote most of the regular pointer handling. The old implementation had been hacked on for a while and needed cleanup. The new code is heavily based on looking at the behavior of other platforms. It also reuses more of the cross platform code, which improves the handling of Enter and Leave events. We also switched to letting Symbian grab the pointer automatically when pressing down the mouse button, which improves things considerably compared to doing it ourselves. Popups should also work a lot better after this fix, since they were not really handled at all in the old code. The old code had calls to set the Symbian cursor sprite. This code has been removed since that code is now being called from within dispatchEnterLeaveEvents(). In addition, there was code to check whether the up key event had been left out by the platform. This was solved a bit differently now, instead putting the code in the section that handles virtual mouse, since that is where the problem occurs. Task: QTBUG-4990 RevBy: Shane Kearns AutoTest: N/A, Platform specific code that an autotest cannot catch. Lots of manual testing was done on normal examples as well drag'n'drop examples and it seemed to work fine. --- src/gui/kernel/qapplication_s60.cpp | 170 +++++++++++++++++------------------- src/gui/kernel/qt_s60_p.h | 14 +++ 2 files changed, 94 insertions(+), 90 deletions(-) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index ab57c32..27f2644 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -361,6 +361,8 @@ void QSymbianControl::ConstructL(bool isWindowOwning, bool desktop) SetFocusing(true); m_longTapDetector = QLongTapTimer::NewL(this); + + DrawableWindow()->SetPointerGrab(ETrue); } } @@ -472,41 +474,6 @@ void QSymbianControl::HandlePointerEventL(const TPointerEvent& pEvent) QT_TRYCATCH_LEAVING(HandlePointerEvent(pEvent)); } -typedef QPair Event; - -/* - * Helper function called by HandlePointerEvent - separated to keep that function readable - */ -static void generateEnterLeaveEvents(QList &events, QWidget *widgetUnderPointer, - QPoint globalPos, Qt::MouseButton button, Qt::KeyboardModifiers modifiers) -{ - //moved to another widget, create enter and leave events - if (S60->lastPointerEventTarget) { - QMouseEvent mEventLeave(QEvent::Leave, S60->lastPointerEventTarget->mapFromGlobal( - S60->lastCursorPos), S60->lastCursorPos, button, QApplicationPrivate::mouse_buttons, - modifiers); - events.append(Event(S60->lastPointerEventTarget, mEventLeave)); - } - if (widgetUnderPointer) { - QMouseEvent mEventEnter(QEvent::Enter, widgetUnderPointer->mapFromGlobal(globalPos), - globalPos, button, QApplicationPrivate::mouse_buttons, modifiers); - - events.append(Event(widgetUnderPointer, mEventEnter)); -#ifndef QT_NO_CURSOR - S60->curWin = widgetUnderPointer->effectiveWinId(); - if (!QApplication::overrideCursor()) { -#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS - if (S60->brokenPointerCursors) - qt_symbian_set_pointer_sprite(widgetUnderPointer->cursor()); - else -#endif - qt_symbian_setWindowCursor(widgetUnderPointer->cursor(), S60->curWin); - } -#endif - } -} - - void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent) { QMouseEvent::Type type; @@ -514,85 +481,77 @@ void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent) mapS60MouseEventTypeToQt(&type, &button, &pEvent); Qt::KeyboardModifiers modifiers = mapToQtModifiers(pEvent.iModifiers); - if (type == QMouseEvent::None) - return; - - // store events for later sending/saving - QList events; - QPoint widgetPos = QPoint(pEvent.iPosition.iX, pEvent.iPosition.iY); TPoint controlScreenPos = PositionRelativeToScreen(); QPoint globalPos = QPoint(controlScreenPos.iX, controlScreenPos.iY) + widgetPos; + S60->lastCursorPos = globalPos; + S60->lastPointerEventPos = widgetPos; - // widgets interested in the event - QWidget *widgetUnderPointer = qwidget->childAt(widgetPos); - if (!widgetUnderPointer) - widgetUnderPointer = qwidget; //i.e. this container widget + QWidget *mouseGrabber = QWidget::mouseGrabber(); - QWidget *widgetWithMouseGrab = QWidget::mouseGrabber(); + QWidget *popupWidget = qApp->activePopupWidget(); + QWidget *popupReceiver = 0; + if (popupWidget) { + QWidget *popupChild = popupWidget->childAt(popupWidget->mapFromGlobal(globalPos)); + popupReceiver = popupChild ? popupChild : popupWidget; + } - // handle auto grab of pointer when pressing / releasing - if (!widgetWithMouseGrab && type == QEvent::MouseButtonPress) { - //if previously auto-grabbed, generate a fake mouse release (platform bug: mouse release event was lost) - if (S60->mousePressTarget) { - QMouseEvent mEvent(QEvent::MouseButtonRelease, S60->mousePressTarget->mapFromGlobal(globalPos), globalPos, - button, QApplicationPrivate::mouse_buttons, modifiers); - events.append(Event(S60->mousePressTarget,mEvent)); + if (mouseGrabber) { + if (popupReceiver) { + sendMouseEvent(popupReceiver, type, globalPos, button, modifiers); + } else { + sendMouseEvent(mouseGrabber, type, globalPos, button, modifiers); } - //auto grab the mouse - widgetWithMouseGrab = S60->mousePressTarget = widgetUnderPointer; - widgetWithMouseGrab->grabMouse(); - } - if (widgetWithMouseGrab && widgetWithMouseGrab == S60->mousePressTarget && type == QEvent::MouseButtonRelease) { - //release the auto grab - note this release event still goes to the autograb widget - S60->mousePressTarget = 0; - widgetWithMouseGrab->releaseMouse(); + // No Enter/Leave events in grabbing mode. + return; } - QWidget *widgetToReceiveMouseEvent; - if (widgetWithMouseGrab) - widgetToReceiveMouseEvent = widgetWithMouseGrab; - else - widgetToReceiveMouseEvent = widgetUnderPointer; - - //queue QEvent::Enter and QEvent::Leave, if the pointer has moved - if (widgetUnderPointer != S60->lastPointerEventTarget && (type == QEvent::MouseButtonPress || type == QEvent::MouseButtonDblClick || type == QEvent::MouseMove)) - generateEnterLeaveEvents(events, widgetUnderPointer, globalPos, button, modifiers); + QWidget *widgetUnderPointer = qwidget->childAt(widgetPos); + if (!widgetUnderPointer) + widgetUnderPointer = qwidget; - //save global state - S60->lastCursorPos = globalPos; - S60->lastPointerEventPos = widgetPos; + QApplicationPrivate::dispatchEnterLeave(widgetUnderPointer, S60->lastPointerEventTarget); S60->lastPointerEventTarget = widgetUnderPointer; + QWidget *receiver; + if (!popupReceiver && S60->mousePressTarget && type != QEvent::MouseButtonPress) { + receiver = S60->mousePressTarget; + if (type == QEvent::MouseButtonRelease) + S60->mousePressTarget = 0; + } else { + receiver = popupReceiver ? popupReceiver : widgetUnderPointer; + if (type == QEvent::MouseButtonPress) + S60->mousePressTarget = receiver; + } + #if !defined(QT_NO_CURSOR) && !defined(Q_SYMBIAN_FIXED_POINTER_CURSORS) if (S60->brokenPointerCursors) qt_symbian_move_cursor_sprite(); #endif - //queue this event. - Q_ASSERT(widgetToReceiveMouseEvent); - QMouseEvent mEvent(type, widgetToReceiveMouseEvent->mapFromGlobal(globalPos), globalPos, + sendMouseEvent(receiver, type, globalPos, button, modifiers); +} + +void QSymbianControl::sendMouseEvent( + QWidget *receiver, + QEvent::Type type, + const QPoint &globalPos, + Qt::MouseButton button, + Qt::KeyboardModifiers modifiers) +{ + Q_ASSERT(receiver); + QMouseEvent mEvent(type, receiver->mapFromGlobal(globalPos), globalPos, button, QApplicationPrivate::mouse_buttons, modifiers); - events.append(Event(widgetToReceiveMouseEvent,mEvent)); QEventDispatcherS60 *dispatcher; // It is theoretically possible for someone to install a different event dispatcher. - if ((dispatcher = qobject_cast(widgetToReceiveMouseEvent->d_func()->threadData->eventDispatcher)) != 0) { + if ((dispatcher = qobject_cast(receiver->d_func()->threadData->eventDispatcher)) != 0) { if (dispatcher->excludeUserInputEvents()) { - for (int i=0;i < events.count();++i) - { - Event next = events[i]; - dispatcher->saveInputEvent(this, next.first, new QMouseEvent(next.second)); - } + dispatcher->saveInputEvent(this, receiver, new QMouseEvent(mEvent)); return; } } - //send events in the queue - for (int i=0;i < events.count();++i) - { - Event next = events[i]; - sendMouseEvent(next.first, &(next.second)); - } + sendMouseEvent(receiver, &mEvent); } bool QSymbianControl::sendMouseEvent(QWidget *widget, QMouseEvent *mEvent) @@ -672,27 +631,58 @@ TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCod fakeEvent.iType = TPointerEvent::EButton1Up; S60->virtualMouseAccel = 1; S60->virtualMouseLastKey = 0; + switch (keyCode) { + case Qt::Key_Left: + S60->virtualMousePressedKeys &= ~QS60Data::Left; + break; + case Qt::Key_Right: + S60->virtualMousePressedKeys &= ~QS60Data::Right; + break; + case Qt::Key_Up: + S60->virtualMousePressedKeys &= ~QS60Data::Up; + break; + case Qt::Key_Down: + S60->virtualMousePressedKeys &= ~QS60Data::Down; + break; + case Qt::Key_Select: + S60->virtualMousePressedKeys &= ~QS60Data::Select; + break; + } } else if (type == EEventKey) { switch (keyCode) { case Qt::Key_Left: + S60->virtualMousePressedKeys |= QS60Data::Left; x -= S60->virtualMouseAccel; fakeEvent.iType = TPointerEvent::EMove; break; case Qt::Key_Right: + S60->virtualMousePressedKeys |= QS60Data::Right; x += S60->virtualMouseAccel; fakeEvent.iType = TPointerEvent::EMove; break; case Qt::Key_Up: + S60->virtualMousePressedKeys |= QS60Data::Up; y -= S60->virtualMouseAccel; fakeEvent.iType = TPointerEvent::EMove; break; case Qt::Key_Down: + S60->virtualMousePressedKeys |= QS60Data::Down; y += S60->virtualMouseAccel; fakeEvent.iType = TPointerEvent::EMove; break; case Qt::Key_Select: - fakeEvent.iType = TPointerEvent::EButton1Down; + // Platform bug. If you start pressing several keys simultaneously (for + // example for drag'n'drop), Symbian starts producing spurious up and + // down messages for some keys. Therefore, make sure we have a clean slate + // of pressed keys before starting a new button press. + if (S60->virtualMousePressedKeys != 0) { + S60->virtualMousePressedKeys |= QS60Data::Select; + return EKeyWasConsumed; + } else { + S60->virtualMousePressedKeys |= QS60Data::Select; + fakeEvent.iType = TPointerEvent::EButton1Down; + } break; } } diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index 08f8bb5..737e9d7 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -103,6 +103,14 @@ public: int defaultDpiY; WId curWin; int virtualMouseLastKey; + enum PressedKeys { + Select = 0x1, + Right = 0x2, + Down = 0x4, + Left = 0x8, + Up = 0x10 + }; + int virtualMousePressedKeys; // of the above type, but avoids casting problems int virtualMouseAccel; int virtualMouseMaxAccel; #ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS @@ -192,6 +200,12 @@ private: TKeyResponse OfferKeyEvent(const TKeyEvent& aKeyEvent,TEventCode aType); TKeyResponse sendKeyEvent(QWidget *widget, QKeyEvent *keyEvent); bool sendMouseEvent(QWidget *widget, QMouseEvent *mEvent); + void sendMouseEvent( + QWidget *receiver, + QEvent::Type type, + const QPoint &globalPos, + Qt::MouseButton button, + Qt::KeyboardModifiers modifiers); void HandleLongTapEventL( const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation ); #ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER void translateAdvancedPointerEvent(const TAdvancedPointerEvent *event); -- cgit v0.12 From 0160b439764726800f9b4c55acee8d554e1b1413 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 10 Dec 2009 11:04:01 +0100 Subject: Update polish translations --- translations/assistant_pl.ts | 56 +- translations/designer_pl.ts | 34 +- translations/linguist_pl.ts | 50 +- translations/qt_help_pl.ts | 45 +- translations/qt_pl.ts | 1316 ++++++++++++++++++++++++++++++------------ translations/qvfb_pl.ts | 11 +- 6 files changed, 1040 insertions(+), 472 deletions(-) diff --git a/translations/assistant_pl.ts b/translations/assistant_pl.ts index 069b5a0..0ef3251 100644 --- a/translations/assistant_pl.ts +++ b/translations/assistant_pl.ts @@ -78,7 +78,7 @@ BookmarkManager - + Bookmarks Zakładki @@ -102,7 +102,7 @@ BookmarkWidget - + Filter: Filtr: @@ -150,7 +150,7 @@ CentralWidget - + Add new page Dodaj nową stronę @@ -165,7 +165,7 @@ Wydrukuj dokument - + unknown nieznany @@ -191,7 +191,7 @@ Dodaj zakładkę dla tej strony... - + Search Wyszukaj @@ -225,7 +225,7 @@ FindWidget - + Previous Poprzedni @@ -281,7 +281,7 @@ HelpViewer - + Help Pomoc @@ -326,7 +326,7 @@ Wy&szukaj: - + Open Link Otwórz odsyłacz @@ -440,19 +440,19 @@ MainWindow - + Index Indeks - - + + Contents Spis treści - - + + Bookmarks Zakładki @@ -462,14 +462,14 @@ Wyszukaj - - - + + + Qt Assistant Qt Assistant - + Unfiltered Nieprzefiltrowany @@ -515,7 +515,12 @@ Znajdź w &tekście... - + + &Find + &Znajdź + + + Find &Next Znajdź &następny @@ -585,7 +590,12 @@ Znajdź bieżącą stronę w spisie treści - + + Sync + + + + Next Page Następna strona @@ -635,7 +645,7 @@ Przefiltrowane przez: - + Address Toolbar Pasek adresu @@ -660,7 +670,7 @@ Uaktualnianie indeksu wyszukiwawczego - + Looking for Qt Documentation... Szukanie dokumentacji Qt... @@ -962,7 +972,7 @@ Qt Assistant - + Could not register documentation file %1 @@ -1024,7 +1034,7 @@ Powód: SearchWidget - + &Copy S&kopiuj diff --git a/translations/designer_pl.ts b/translations/designer_pl.ts index f9c6dd0..005ad5a4 100644 --- a/translations/designer_pl.ts +++ b/translations/designer_pl.ts @@ -517,12 +517,12 @@ - + Move action Przenieś akcję - + Change Title Zmień tytuł @@ -703,7 +703,7 @@ ConnectionDelegate - + <object> <obiekt> @@ -1028,7 +1028,7 @@ FormBuilder - + Invalid stretch value for '%1': '%2' Parsing layout stretch values Niepoprawna wartość rozciągniecia dla '%1': '%2' @@ -1413,7 +1413,7 @@ Niepoprawny plik UI: brak głównego elementu <ui>. - + The creation of a widget of the class '%1' failed. Utworzenie widżetu klasy '%1' nie powiodło się. @@ -2277,7 +2277,7 @@ Strony pojemników powinny być dodawane jedynie poprzez wyspecyfikowanie ich w QFormBuilder - + An empty class name was passed on to %1 (object name: '%2'). Empty class name passed to widget factory method Pusta nazwa klasy została przekazana do %1 (nazwa obiektu: '%2'). @@ -4709,7 +4709,7 @@ Czy chcesz nadpisać szablon? The file "%1" has changed outside Designer. Do you want to reload it? - Plik "%1" zmienił się na zewnątrz Designera. Czy chcesz go ponownie załadować? + Plik "%1" zmienił się na zewnątrz Designera. Czy chcesz go ponownie załadować? @@ -4834,7 +4834,7 @@ Czy chcesz nadpisać szablon? qdesigner_internal::FormWindowManager - + Cu&t Wy&tnij @@ -5560,18 +5560,15 @@ Wybierz inną nazwę. qdesigner_internal::ObjectInspector - - &Find in Text... - Z&najdź w tekście... - - - - qdesigner_internal::ObjectInspector::ObjectInspectorPrivate - - + Change Current Page Zmień bieżącą stronę + + + &Find in Text... + Z&najdź w tekście... + qdesigner_internal::OrderDialog @@ -5785,9 +5782,6 @@ Wybierz inną nazwę. Browse... Przeglądaj... - - - qdesigner_internal::PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate Load Custom Device Skin diff --git a/translations/linguist_pl.ts b/translations/linguist_pl.ts index cdff54b..963c39b 100644 --- a/translations/linguist_pl.ts +++ b/translations/linguist_pl.ts @@ -4,7 +4,7 @@ AboutDialog - + Qt Linguist Qt Linguist @@ -110,11 +110,17 @@ + <p>[more duplicates omitted] <p>[pominięto resztę powtórzeń] - + + <p>* ID: %1 + <p>* identyfikator: %1 + + + <p>* Context: %1<br>* Source: %2 <p>* Kontekst: %1<br>* Źródło: %2 @@ -124,7 +130,7 @@ <br>* Komentarz: %3 - + Linguist does not know the plural rules for '%1'. Will assume a single universal form. Linguist nie zna reguł liczby mnogiej dla "%1". @@ -312,7 +318,7 @@ Przyjmie on uniwersalną formę liczby pojedynczej. LRelease - + Dropped %n message(s) which had no ID. Opuszczono %n wyrażenie które nie miało identyfikatora. @@ -714,7 +720,7 @@ Przyjmie on uniwersalną formę liczby pojedynczej. Zamienia tłumaczenia we wszystkich pasujących do wzorca wpisach. - + This is the application's main window. @@ -732,27 +738,27 @@ Przyjmie on uniwersalną formę liczby pojedynczej. - + Context Kontekst - + Items Elementy - + This panel lists the source contexts. Ten panel pokazuje listę kontekstów. - + Strings Tłumaczenia - + Phrases and guesses Wyrażenia i podpowiedzi @@ -773,7 +779,7 @@ Przyjmie on uniwersalną formę liczby pojedynczej. MOD - + Loading... Ładowanie... @@ -811,7 +817,7 @@ Czy chcesz pominąć pierwszy plik? - + Related files (%1);; Związane pliki (%1);; @@ -1176,7 +1182,7 @@ Wszystkie pliki (*) Czy chcesz zachować książke wyrażeń '%1'? - + All Wszystko @@ -1242,7 +1248,7 @@ Wszystkie pliki (*) - + Translation Tłumaczenie @@ -1579,7 +1585,7 @@ Wszystkie pliki (*) Tutaj można wprowadzić komentarze na własny użytek. One nie mają wpływu na przetłumaczoną aplikację. - + %1 translation (%2) Tłumaczenie na język %1 (%2) @@ -1609,7 +1615,7 @@ Linia: %2 MessageModel - + Completion status for %1 Stan ukończenia dla %1 @@ -1632,7 +1638,7 @@ Linia: %2 MsgEdit - + This is the right panel of the main window. @@ -1811,8 +1817,8 @@ Linia: %2 Wszystkie pliki (*) - - + + @@ -1847,7 +1853,7 @@ Linia: %2 Pliki XLIFF - + Qt Linguist 'Phrase Book' Qt Linguist "Książka wyrażeń" @@ -1998,12 +2004,12 @@ Linia: %2 TranslationSettingsDialog - + Any Country Dowolny kraj - + Settings for '%1' - Qt Linguist Ustawienia dla '%1' - Qt Linguist diff --git a/translations/qt_help_pl.ts b/translations/qt_help_pl.ts index 220f70c..f2eb6c9 100644 --- a/translations/qt_help_pl.ts +++ b/translations/qt_help_pl.ts @@ -32,13 +32,9 @@ QHelpCollectionHandler - The collection file is not set up yet! - Plik z kolekcją nie jest jeszcze ustawiony! - - The collection file '%1' is not set up yet! - + Plik z kolekcją "%1" nie jest jeszcze ustawiony! @@ -59,31 +55,27 @@ The collection file '%1' already exists! - + Plik z kolekcją "%1" już istnieje! Unknown filter '%1'! - + Nieznany filtr "%1"! Invalid documentation file '%1'! - + Niepoprawny plik z dokumentacją "%1"! Cannot register namespace '%1'! - + Nie można zarejestrować przestrzeni nazw "%1"! Cannot open database '%1' to optimize! - - - - The specified collection file already exists! - Podany plik z kolekcją już istnieje! + Nie można otworzyć bazy danych "%1" do zoptymalizowania! @@ -96,10 +88,6 @@ Nie można skopiować pliku z kolekcją: %1 - Unknown filter! - Nieznany filtr! - - Cannot register filter %1! Nie można zarejestrować pliku %1! @@ -110,10 +98,6 @@ Nie można otworzyć pliku z dokumentacją %1! - Invalid documentation file! - Niepoprawny plik z dokumentacją! - - The namespace %1 was not registered! Przestrzeń nazw %1 nie została zarejestrowana! @@ -123,14 +107,6 @@ Namespace %1 already exists! Przestrzeń nazw %1 już istnieje! - - Cannot register namespace! - Nie można zarejestrować przestrzeni nazw! - - - Cannot open database to optimize! - Nie można otworzyć bazy danych do zoptymalizowania! - QHelpDBReader @@ -144,7 +120,7 @@ QHelpEngineCore - + The specified namespace does not exist! Podana przestrzeń nazw nie istnieje! @@ -152,7 +128,7 @@ QHelpEngineCorePrivate - + Cannot open documentation file %1: %2! Nie można otworzyć pliku z dokumentacją %1: %2! @@ -342,11 +318,6 @@ QObject - - Untitled - Nienazwany - - Unknown token. Nieznany znak. diff --git a/translations/qt_pl.ts b/translations/qt_pl.ts index f79ecb0..6368b8f 100644 --- a/translations/qt_pl.ts +++ b/translations/qt_pl.ts @@ -4,7 +4,7 @@ CloseButton - + Close Tab Zamknij kartę @@ -12,7 +12,7 @@ FakeReply - + Fake error ! @@ -58,7 +58,7 @@ Phonon::AudioOutput - + <html>The audio playback device <b>%1</b> does not work.<br/>Falling back to <b>%2</b>.</html> <html>Urządzenie dźwiękowe <b>%1</b> nie działa.<br/>Przywracanie do <b>%2</b>.</html> @@ -76,7 +76,7 @@ Phonon::Gstreamer::Backend - + Warning: You do not seem to have the package gstreamer0.10-plugins-good installed. Some video features have been disabled. Ostrzeżenie: Wygląda na to, że pakiet gstreamer0.10-plugins-good nie jest zainstalowany w tym systemie. @@ -96,7 +96,7 @@ Obsługa dźwięku i wideo została wyłączona Cannot start playback. -Check your Gstreamer installation and make sure you +Check your GStreamer installation and make sure you have libgstreamer-plugins-base installed. Nie można rozpocząć odtwarzania. @@ -109,10 +109,10 @@ zainstalowałeś libgstreamer-plugins-base. Brak wymaganego kodeka. Aby odtworzyć zawartość musisz zainstalować poniższy kodek: %0 - + - + @@ -121,12 +121,12 @@ zainstalowałeś libgstreamer-plugins-base. Nie można otworzyć źródła mediów. - + Invalid source type. Niepoprawny typ źródła. - + Could not locate media source. Nie można znaleźć źródła mediów. @@ -144,7 +144,7 @@ zainstalowałeś libgstreamer-plugins-base. Phonon::MMF - + Audio Output Wyjście dźwięku @@ -166,12 +166,12 @@ zainstalowałeś libgstreamer-plugins-base. Phonon::MMF::EffectFactory - audio equalizer + Audio Equalizer Korektor graficzny - Bass boost + Bass Boost Wzmocnienie basów @@ -202,6 +202,14 @@ zainstalowałeś libgstreamer-plugins-base. + Phonon::MMF::MediaObject + + + Media type could not be determined + Nie można określić typu mediów + + + Phonon::VolumeSlider @@ -268,7 +276,7 @@ zainstalowałeś libgstreamer-plugins-base. Q3FileDialog - + %1 File not found. Check path and filename. @@ -285,7 +293,7 @@ Sprawdź ścieżkę i nazwę pliku. - + All Files (*) Wszystkie pliki (*) @@ -905,8 +913,8 @@ na QAbstractSocket - - + + Connection refused Połączenie odrzucone @@ -925,8 +933,8 @@ na Przekroczony czas połączenia - - + + Operation on socket is not supported Operacja na gnieździe nieobsługiwana @@ -970,7 +978,7 @@ na Press - Wciśnij + Wciśnij @@ -996,7 +1004,7 @@ na Niekompatybilność biblioteki Qt - + QT_LAYOUT_DIRECTION Translate this string to the string 'LTR' in left-to-right languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout. LTR @@ -1173,7 +1181,7 @@ na QDB2Driver - + Unable to connect Nie można nawiązać połączenia @@ -1196,7 +1204,7 @@ na QDB2Result - + Unable to execute statement Nie można wykonać polecenia @@ -1284,7 +1292,7 @@ na QDialogButtonBox - + Abort Przerwij @@ -1511,7 +1519,7 @@ na Cannot remove source file - Nie można usunąć oryginalnego pilku + Nie można usunąć oryginalnego pliku @@ -1575,7 +1583,7 @@ Proszę o sprawdzenie podanej nazwy pliku. Czy na pewno chcesz skasować '%1'? - + Recent Places Ostatnie miejsca @@ -1586,7 +1594,7 @@ Proszę o sprawdzenie podanej nazwy pliku. Powrót - + Could not delete directory. Nie można skasować katalogu. @@ -1803,9 +1811,8 @@ Proszę o sprawdzenie podanej nazwy pliku. - %1 bytes - %1 b + %1 bajtów @@ -1854,62 +1861,67 @@ Proszę o sprawdzenie podanej nazwy pliku. Computer Komputer + + + %1 byte(s) + %1 bajt(ów) + QFontDatabase - + Normal Normalny - + - + Bold Pogrubiony - - + + Demi Bold Na wpół pogrubiony - + - + Black it's about font weight Bardzo gruby - + Demi Na wpół - + Light it's about font weight Cienki - - + + Italic Kursywa - - + + Oblique Pochyły - + Any Każdy @@ -2073,6 +2085,11 @@ Proszę o sprawdzenie podanej nazwy pliku. Runic Runiczny + + + N'Ko + N'Ko + QFontDialog @@ -2272,7 +2289,7 @@ Proszę o sprawdzenie podanej nazwy pliku. QHostInfo - + Unknown error Nieznany błąd @@ -2326,7 +2343,7 @@ Proszę o sprawdzenie podanej nazwy pliku. Podłączony do hosta %1 - + Connection closed Połączenie zakończone @@ -2633,7 +2650,7 @@ Proszę o sprawdzenie podanej nazwy pliku. QIODevice - + No space left on device Brak wolnego miejsca na urządzeniu @@ -2653,7 +2670,7 @@ Proszę o sprawdzenie podanej nazwy pliku. Zbyt wiele otwartych plików - + Unknown error Nieznany błąd @@ -2717,7 +2734,7 @@ Proszę o sprawdzenie podanej nazwy pliku. Błąd podczas weryfikacji danych we wtyczce '%1' - + The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5] Wtyczka '%1' używa niepoprawnej wersji biblioteki QT. (%2.%3.%4) [%5] @@ -2769,37 +2786,37 @@ Proszę o sprawdzenie podanej nazwy pliku. QLineEdit - + &Copy S&kopiuj - + Cu&t W&ytnij - + Delete Skasuj - + &Paste &Wklej - + &Redo &Przywróć - + Select All Zaznacz wszystko - + &Undo &Cofnij @@ -2808,7 +2825,7 @@ Proszę o sprawdzenie podanej nazwy pliku. QLocalServer - + %1: Name error %1: Błąd nazwy @@ -2902,7 +2919,7 @@ Proszę o sprawdzenie podanej nazwy pliku. QMYSQLDriver - + Unable to begin transaction Nie można rozpocząć transakcji @@ -2912,7 +2929,7 @@ Proszę o sprawdzenie podanej nazwy pliku. Nie można potwierdzić transakcji - + Unable to connect Nie można nawiązać połączenia @@ -2922,7 +2939,7 @@ Proszę o sprawdzenie podanej nazwy pliku. Nie można otworzyć bazy danych ' - + Unable to rollback transaction Nie można wycofać transakcji @@ -2930,7 +2947,7 @@ Proszę o sprawdzenie podanej nazwy pliku. QMYSQLResult - + Unable to bind outvalues Nie można powiązać wartości zewnętrznych @@ -2951,12 +2968,13 @@ Proszę o sprawdzenie podanej nazwy pliku. Nie można wykonać polecenia - + + Unable to fetch data Nie można pobrać danych - + Unable to prepare statement Nie można przygotować polecenia @@ -3332,27 +3350,30 @@ Proszę o sprawdzenie podanej nazwy pliku. QNetworkAccessFileBackend + Request for opening non-local file %1 Żądanie otwarcia zdalnego pliku %1 - + + Error opening %1: %2 Błąd otwierania %1: %2 - + Write error writing to %1: %2 Błąd w trakcie zapisywania do %1: %2 - + + Cannot open %1: Path is a directory Nie można otworzyć %1: Ścieżka jest katalogiem - + Read error reading from %1: %2 Błąd w trakcie czytania z %1: %2 @@ -3418,7 +3439,7 @@ Proszę o sprawdzenie podanej nazwy pliku. QOCIDriver - + Unable to initialize QOCIDriver Nie można dokonać inicjalizacji @@ -3447,8 +3468,8 @@ Proszę o sprawdzenie podanej nazwy pliku. QOCIResult - - + + Unable to bind column for batch execute Nie można powiązać kolumny dla wykonania zestawu poleceń @@ -3552,7 +3573,7 @@ Proszę o sprawdzenie podanej nazwy pliku. Nie można przygotować polecenia - + Unable to fetch last @@ -3611,7 +3632,7 @@ Proszę o sprawdzenie podanej nazwy pliku. QPPDOptionsModel - + Name Nazwa @@ -3927,7 +3948,7 @@ Proszę o sprawdzenie podanej nazwy pliku. Wydrukuj zakres - + unknown nieznany @@ -3975,12 +3996,12 @@ Proszę o sprawdzenie podanej nazwy pliku. Wydrukuj - + Print To File ... Wydrukuj do pliku ... - + File %1 is not writable. Please choose a different file name. Plik %1 jest plikiem tylko do odczytu. @@ -4171,7 +4192,7 @@ Proszę wybrać inną nazwę pliku. Niestandardowy - + &Options >> &Opcje >> @@ -4483,7 +4504,7 @@ Proszę wybrać inną nazwę pliku. QProcess - + Could not open input redirection for reading Nie można otworzyć wejściowego przekierowania do odczytu @@ -4500,7 +4521,7 @@ Proszę wybrać inną nazwę pliku. Błąd zasobów (błąd forkowania): %1 - + @@ -4664,7 +4685,7 @@ Proszę wybrać inną nazwę pliku. QSQLiteDriver - + Error closing database Błąd zamykania bazy danych @@ -4707,8 +4728,8 @@ Proszę wybrać inną nazwę pliku. Nie można wykonać polecenia - - + + Unable to fetch row Nie można pobrać wiersza danych @@ -4719,7 +4740,7 @@ Proszę wybrać inną nazwę pliku. Nie można skasować polecenia - + No query Brak zapytania @@ -4744,7 +4765,7 @@ Proszę wybrać inną nazwę pliku. Ignore-count - + Licznik pominięć @@ -4754,7 +4775,7 @@ Proszę wybrać inną nazwę pliku. Hit-count - Ilość trafień + Licznik trafień @@ -5031,7 +5052,7 @@ Proszę wybrać inną nazwę pliku. Debug Output - Wyjscie debuggera + Wyjście debuggera @@ -5167,7 +5188,7 @@ Proszę wybrać inną nazwę pliku. - + %1: permission denied %1: brak dostępu @@ -5262,7 +5283,7 @@ Proszę wybrać inną nazwę pliku. QShortcut - + + + @@ -5273,12 +5294,12 @@ Proszę wybrać inną nazwę pliku. Alt - + Back Back - + Backspace Backspace @@ -5288,7 +5309,7 @@ Proszę wybrać inną nazwę pliku. Backtab - + Bass Boost Wzmocnienie basów @@ -5303,7 +5324,7 @@ Proszę wybrać inną nazwę pliku. Basy w górę - + Call Wywołaj @@ -5313,289 +5334,734 @@ Proszę wybrać inną nazwę pliku. Caps Lock - + CapsLock CapsLock - - Context1 - Kontekst1 + + Monitor Brightness Up + Zwiększ jasność monitora - Context2 - Kontekst2 + Monitor Brightness Down + Zmniejsz jasność monitora - Context3 - Kontekst3 + Keyboard Light On/Off + - Context4 - Kontekst4 + Keyboard Brightness Up + - - - Ctrl - Ctrl + + Keyboard Brightness Down + - - Del - Del + + Power Off + - - Delete - Delete + + Wake Up + - - Down - Dół + + Eject + Wysuń - - End - End + + Screensaver + Wygaszacz ekranu - - Enter - Enter + + WWW + WWW - - Esc - Esc + + Sleep + - - Escape - Escape + + LightBulb + - - F%1 - F%1 + + Shop + Sklep - - Favorites - Ulubione + + History + Historia - - Flip - Odwróć + + Add Favorite + Dodaj do ulubionych - - Forward - Do przodu + + Hot Links + - - Hangup - Zawieś + + Adjust Brightness + - - Help - Pomoc + + Finance + - - Home - Home + + Community + Społeczność - - Home Page - Strona startowa + + Audio Rewind + - - Ins - Ins + + Back Forward + - - Insert - Insert + + Application Left + - - Launch (0) - Uruchom (0) + + Application Right + - Launch (1) - Uruchom (1) + Book + Książka - Launch (2) - Uruchom (2) + CD + CD - Launch (3) - Uruchom (3) + Calculator + Kalkulator - Launch (4) - Uruchom (4) + Clear + Wyczyść - Launch (5) - Uruchom (5) + Clear Grab + - Launch (6) - Uruchom (6) + Close + Zamknij - Launch (7) - Uruchom (7) + Copy + Skopiuj - Launch (8) - Uruchom (8) + Cut + Wytnij - Launch (9) - Uruchom (9) + Display + - Launch (A) - Uruchom (A) + DOS + DOS - Launch (B) - Uruchom (B) + Documents + Dokumenty - Launch (C) - Uruchom (C) + Spreadsheet + - Launch (D) - Uruchom (D) + Browser + Przeglądarka - Launch (E) - Uruchom (E) + Game + - Launch (F) - Uruchom (F) + Go + Przejdź - - Launch Mail - Uruchom program pocztowy + + iTouch + iTouch - Launch Media - Uruchom przeglądarkę mediów + Logoff + - - Left - Lewo + + Market + Rynek - - Media Next - Następna ścieżka + + Meeting + Spotkanie - - Media Play - Odtwarzaj + + Keyboard Menu + - - Media Previous - Poprzednia ścieżka + + Menu PB + - - Media Record - Nagrywaj + + My Sites + Moje strony - - Media Stop - Zatrzymaj + + News + Wiadomości - - Menu - Menu + + Home Office + - - - Meta - Meta + + Option + Opcje - - No - Nie + + Paste + Wklej - - Num Lock - Num Lock + + Phone + Telefon - Number Lock - Number Lock + Reply + Odpowiedz - - NumLock - NumLock + + Reload + Przeładuj - - Open URL - Otwórz adres + + Rotate Windows + Obróć okna - - Page Down - Strona do góry + + Rotation PB + - - Page Up - Strona w dół - + + Rotation KB + + + + + Save + Zachowaj + + + + Send + Wyślij + + + + Spellchecker + + + + + Split Screen + Podziel ekran + + + + Support + Pomoc techniczna + + + + Task Panel + + + + + Terminal + Terminal + + + + Tools + Narzędzia + + + + Travel + Podróże + + + + Video + Wideo + + + + Word Processor + + + + + XFer + + + + + Zoom In + Powiększ + + + + Zoom Out + Pomniejsz + + + + Away + + + + + Messenger + + + + + WebCam + WebCam + + + + Mail Forward + + + + + Pictures + Zdjęcia + + + + Music + Muzyka + + + + Battery + Bateria + + + + Bluetooth + Bluetooth + + + + Wireless + Bezprzewodowy + + + + Ultra Wide Band + + + + + Audio Forward + + + + + Audio Repeat + + + + + Audio Random Play + + + + + Subtitle + Napisy + + + + Audio Cycle Track + + + + + Time + Czas + + + + View + Widok + + + + Top Menu + Menu główne + + + + Suspend + + + + + Hibernate + + + + + Context1 + Kontekst1 + + + + Context2 + Kontekst2 + + + + Context3 + Kontekst3 + + + + Context4 + Kontekst4 + + + + + Ctrl + Ctrl + + + + Del + Del + + + + Delete + Delete + + + + Down + Dół + + + + End + End + + + + Enter + Enter + + + + Esc + Esc + + + + Escape + Escape + + + + F%1 + F%1 + + + + Favorites + Ulubione + + + + Flip + Odwróć + + + + Forward + Do przodu + + + + Hangup + Zawieś + + + + Help + Pomoc + + + + Home + Home + + + + Home Page + Strona startowa + + + + Ins + Ins + + + + Insert + Insert + + + + Launch (0) + Uruchom (0) + + + + Launch (1) + Uruchom (1) + + + + Launch (2) + Uruchom (2) + + + + Launch (3) + Uruchom (3) + + + + Launch (4) + Uruchom (4) + + + + Launch (5) + Uruchom (5) + + + + Launch (6) + Uruchom (6) + + + + Launch (7) + Uruchom (7) + + + + Launch (8) + Uruchom (8) + + + + Launch (9) + Uruchom (9) + + + + Launch (A) + Uruchom (A) + + + + Launch (B) + Uruchom (B) + + + + Launch (C) + Uruchom (C) + + + + Launch (D) + Uruchom (D) + + + + Launch (E) + Uruchom (E) + + + + Launch (F) + Uruchom (F) + - + + Launch Mail + Uruchom program pocztowy + + + + Launch Media + Uruchom przeglądarkę mediów + + + + Left + Lewo + + + + Media Next + Następna ścieżka + + + + Media Play + Odtwarzaj + + + + Media Previous + Poprzednia ścieżka + + + + Media Record + Nagrywaj + + + + Media Stop + Zatrzymaj + + + + Menu + Menu + + + + + Meta + Meta + + + + No + Nie + + + + Num Lock + Num Lock + + + + Number Lock + Number Lock + + + + NumLock + NumLock + + + + Open URL + Otwórz adres + + + + Page Down + Strona do góry + + + + Page Up + Strona w dół + + + Pause Pauza @@ -5615,17 +6081,17 @@ Proszę wybrać inną nazwę pliku. Print - + Print Screen Wydrukuj zawartość ekranu - + Refresh Odśwież - + Return Powrót @@ -5635,38 +6101,39 @@ Proszę wybrać inną nazwę pliku. Prawo - + Scroll Lock Scroll Lock - + ScrollLock ScrollLock - + Search Szukaj - + + Select Wybierz - + Shift Shift - + Space Spacja - + Standby Tryb oczekiwania @@ -5676,22 +6143,22 @@ Proszę wybrać inną nazwę pliku. Zatrzymaj - + SysReq SysReq - + System Request Żądanie systemu - + Tab Tabulator - + Treble Down Soprany w dół @@ -5701,12 +6168,12 @@ Proszę wybrać inną nazwę pliku. Soprany w górę - + Up Góra - + Volume Down Przycisz @@ -5721,7 +6188,7 @@ Proszę wybrać inną nazwę pliku. Zrób głośniej - + Yes Tak @@ -5822,7 +6289,7 @@ Proszę wybrać inną nazwę pliku. Nieznany kod błędu (0x%1) pośrednika SOCKS wersji 5 - + Network operation timed out Przekroczony czas operacji sieciowej @@ -5830,7 +6297,7 @@ Proszę wybrać inną nazwę pliku. QSoftKeyManager - + Ok OK @@ -5855,7 +6322,7 @@ Proszę wybrać inną nazwę pliku. Anuluj - + Exit Wyjście @@ -5958,7 +6425,12 @@ Proszę wybrać inną nazwę pliku. Niepoprawna lub pusta lista szyfrów (%1) - + + Private key does not certify public key, %1 + Prywatny klucz nie uwiarygodnia publicznego, %1 + + + Error creating SSL session, %1 Błąd tworzenia sesji SSL, %1 @@ -5983,15 +6455,125 @@ Proszę wybrać inną nazwę pliku. Błąd ładowania prywatnego klucza, %1 - - Private key does not certificate public key, %1 - Prywatny klucz nie uwiarygodnia publicznego, %1 + + No error + Brak błędu + + + + The issuer certificate could not be found + Nie można odnaleźć wydawcy certyfikatu + + + + The certificate signature could not be decrypted + Nie można odszyfrować podpisu certyfikatu + + + + The public key in the certificate could not be read + Nie można odczytać publicznego klucza w certyfikacie + + + + The signature of the certificate is invalid + Niepoprawny podpis certyfikatu + + + + The certificate is not yet valid + Certyfikat nie jest jeszcze ważny + + + + The certificate has expired + Certyfikat utracił ważność + + + + The certificate's notBefore field contains an invalid time + Pole "notBefore" certyfikatu zawiera niepoprawną datę + + + + The certificate's notAfter field contains an invalid time + Pole "notAfter" certyfikatu zawiera niepoprawną datę + + + + The certificate is self-signed, and untrusted + + + + + The root certificate of the certificate chain is self-signed, and untrusted + + + + + The issuer certificate of a locally looked up certificate could not be found + + + + + No certificates could be verified + + + + + One of the CA certificates is invalid + + + + + The basicConstraints path length parameter has been exceeded + + + + + The supplied certificate is unsuitable for this purpose + + + + + The root CA certificate is not trusted for this purpose + + + + + The root CA certificate is marked to reject the specified purpose + + + + + The current candidate issuer certificate was rejected because its subject name did not match the issuer name of the current certificate + + + + + The current candidate issuer certificate was rejected because its issuer name and serial number was present and did not match the authority key identifier of the current certificate + + + + + The peer did not present any certificate + + + + + The host name did not match any of the valid hosts for this certificate + + + + + Unknown error + Nieznany błąd QStateMachine - + Missing initial state in compound state '%1' Brak stanu początkowego w stanie złożonym '%1' @@ -6045,7 +6627,7 @@ Proszę wybrać inną nazwę pliku. QTDSDriver - + Unable to open connection Nie można otworzyć połączenia @@ -6079,7 +6661,7 @@ Proszę wybrać inną nazwę pliku. QTextControl - + &Copy S&kopiuj @@ -6179,7 +6761,7 @@ Proszę wybrać inną nazwę pliku. QUnicodeControlCharacterMenu - + Insert Unicode control character Wstaw znak kontroli Unicode @@ -6237,7 +6819,7 @@ Proszę wybrać inną nazwę pliku. QWebFrame - + Request cancelled Prośba anulowana @@ -6657,13 +7239,13 @@ Proszę wybrać inną nazwę pliku. Movie time scrubber Media controller element - + Suwak czasu Movie time scrubber thumb Media controller element - + Uchwyt suwaka czasu @@ -6779,7 +7361,7 @@ Proszę wybrać inną nazwę pliku. Wizytator sieciowy - %2 - + Bad HTTP request Niepoprawna komenda HTTP @@ -6883,7 +7465,7 @@ Proszę wybrać inną nazwę pliku. - + JavaScript Alert - %1 Ostrzeżenie JavaScript - %1 @@ -6908,9 +7490,9 @@ Proszę wybrać inną nazwę pliku. Skrypt na tej stronie nie działa poprawnie. Czy chcesz przerwać ten skrypt? - + Move the cursor to the next character - Przesuń kursor do nastepnego znaku + Przesuń kursor do następnego znaku @@ -6920,7 +7502,7 @@ Proszę wybrać inną nazwę pliku. Move the cursor to the next word - Przesuń kursor do nastepnego słowa + Przesuń kursor do następnego słowa @@ -6930,7 +7512,7 @@ Proszę wybrać inną nazwę pliku. Move the cursor to the next line - Przesuń kursor do nastepnej linii + Przesuń kursor do następnej linii @@ -7080,7 +7662,7 @@ Proszę wybrać inną nazwę pliku. Insert Bulleted List - Wstaw listę wypunktową + Wstaw listę wypunktowaną @@ -7129,7 +7711,7 @@ Proszę wybrać inną nazwę pliku. QWidget - + * * @@ -7557,7 +8139,7 @@ Proszę wybrać inną nazwę pliku. The standalone pseudo attribute must appear after the encoding. - Pseudo atrybut "standalone" musi pojawić sie po "encoding". + Pseudo atrybut "standalone" musi pojawić się po "encoding". @@ -7752,17 +8334,22 @@ Proszę wybrać inną nazwę pliku. A positional predicate must evaluate to a single numeric value. - Wynikiem predykatu pozycyjnego musi być pojedyńcza wartość liczbowa. + Wynikiem predykatu pozycyjnego musi być pojedyncza wartość liczbowa. + + + + The target name in a processing instruction cannot be %1 in any combination of upper and lower case. Therefore, %2 is invalid. + Docelowa nazwa w instrukcji przetwarzania nie może być %1 w żadnej kombinacji wielkich i małych liter. Dlatego nazwa %2 jest niepoprawna. - + %1 is not a valid target name in a processing instruction. It must be a %2 value, e.g. %3. %1 nie jest poprawną nazwą docelową w instrukcji przetwarzania. Nazwa musi być wartością %2, np. %3. The last step in a path must contain either nodes or atomic values. It cannot be a mixture between the two. - Ostatni krok w ścieżce musi zawierać albo wezły albo wartości atomowe. Nie może zawierać obu jednocześnie. + Ostatni krok w ścieżce musi zawierać albo węzły albo wartości atomowe. Nie może zawierać obu jednocześnie. @@ -7818,7 +8405,7 @@ Proszę wybrać inną nazwę pliku. %1 must be followed by %2 or %3, not at the end of the replacement string. - Po %1 musi następowac %2 lub %3, lecz nie na końcu zastępczego ciągu. + Po %1 musi następować %2 lub %3, lecz nie na końcu zastępczego ciągu. @@ -7907,7 +8494,12 @@ Proszę wybrać inną nazwę pliku. %1 jest nieznanym typem schematu. - + + A template with name %1 has already been declared. + Szablon o nazwie %1 został już zadeklarowany. + + + Only one %1 declaration can occur in the query prolog. Tylko jedna deklaracja %1 może się pojawić w prologu zapytania. @@ -7962,12 +8554,7 @@ Proszę wybrać inną nazwę pliku. Cecha "Import modułu" nie jest obsługiwana - - No value is available for the external variable by name %1. - Brak wartości dla zewnętrznej zmiennej o nazwie %1. - - - + The namespace %1 is reserved; therefore user defined functions may not use it. Try the predefined prefix %2, which exists for these cases. Przestrzeń nazw %1 jest zarezerwowana, dlatego funkcje zdefiniowane przez użytkownika nie mogą jej użyć. Spróbuj predefiniowany przedrostek %2, który istnieje w takich przypadkach. @@ -7987,12 +8574,7 @@ Proszę wybrać inną nazwę pliku. Zewnętrzne funkcje nie są obsługiwane. Wszystkie obsługiwane funkcje mogą być używane bezpośrednio, bez ich uprzedniego deklarowania jako zewnętrzne - - An argument by name %1 has already been declared. Every argument name must be unique. - Argument o nazwie %1 został już zadeklarowany. Każda nazwa argumentu musi być unikatowa. - - - + The name of a variable bound in a for-expression must be different from the positional variable. Hence, the two variables named %1 collide. Nazwa zmiennej powiązanej w wyrażeniu "for" musi być inna od zmiennej pozycjonującej. W związku z tym dwie zmienne o nazwie %1 kolidują ze sobą. @@ -8019,12 +8601,12 @@ Proszę wybrać inną nazwę pliku. W3C XML Schema identity constraint selector - Selektor ograniczenia jednostki W3C XML Schema + Selektor narzucenia niepowtarzalności W3C XML Schema W3C XML Schema identity constraint field - Pole ograniczenia jednostki W3C XML Schema + Pole narzucenia niepowtarzalności W3C XML Schema @@ -8032,37 +8614,37 @@ Proszę wybrać inną nazwę pliku. Wystąpiła konstrukcja która jest niedozwolona w bieżącym języku (%1). - - No variable by name %1 exists - Zmienna o nazwie %1 nie istnieje - - - - A template by name %1 has already been declared. - Szablon o nazwie %1 został już zadeklarowany. + + The keyword %1 cannot occur with any other mode name. + Słowo kluczowe %1 nie może wystąpić z inną nazwą trybu. - - The keyword %1 cannot occur with any other mode name. - Słowo kluczowe %1 nie może wystapić z inną nazwą trybu. + + No variable with name %1 exists + Zmienna o nazwie %1 nie istnieje - - The value of attribute %1 must of type %2, which %3 isn't. + + The value of attribute %1 must be of type %2, which %3 isn't. Wartość atrybutu %1 musi być typu %2, którym nie jest %3. - The prefix %1 can not be bound. By default, it is already bound to the namespace %2. + The prefix %1 cannot be bound. By default, it is already bound to the namespace %2. Przedrostek %1 nie może być powiązany. Jest on domyślnie powiązany z przestrzenią nazw %2. - A variable by name %1 has already been declared. + A variable with name %1 has already been declared. Zmienna o nazwie %1 została już zadeklarowana. - + + No value is available for the external variable with name %1. + Brak wartości dla zewnętrznej zmiennej o nazwie %1. + + + A stylesheet function must have a prefixed name. Funkcja arkusza stylu musi zawierać nazwę z przedrostkiem. @@ -8072,7 +8654,12 @@ Proszę wybrać inną nazwę pliku. Przestrzeń nazw dla funkcji zdefiniowanej przez użytkownika nie może być pusta (spróbuj predefiniowany przedrostek %1, który stworzono specjalnie do takich sytuacji) - + + An argument with name %1 has already been declared. Every argument name must be unique. + Argument o nazwie %1 został już zadeklarowany. Każda nazwa argumentu musi być unikatowa. + + + When function %1 is used for matching inside a pattern, the argument must be a variable reference or a string literal. Gdy funkcja %1 jest wykorzystana do dopasowania wewnątrz wzorca, jej argument musi być referencją do zmiennej lub napisem. @@ -8113,11 +8700,16 @@ Proszę wybrać inną nazwę pliku. - No function by name %1 is available. + No function with name %1 is available. Żadna funkcja o nazwie %1 nie jest dostępna. - + + An attribute with name %1 has already appeared on this element. + Atrybut o nazwie %1 już się pojawił w tym elemencie. + + + The namespace URI cannot be the empty string when binding to a prefix, %1. Przestrzeń nazw URI nie może być pustym ciągiem w powiązaniu z przedrostkiem, %1. @@ -8152,12 +8744,7 @@ Proszę wybrać inną nazwę pliku. Przestrzeń nazw URI nie może być stałą i nie może używać zawartych w niej wyrażeń. - - An attribute by name %1 has already appeared on this element. - Atrybut o nazwie %1 już się pojawił w tym elemencie. - - - + A direct element constructor is not well-formed. %1 is ended with %2. Konstruktor elementu bezpośredniego nie jest dobrze sformatowany. %1 jest zakończony %2. @@ -8262,11 +8849,6 @@ Proszę wybrać inną nazwę pliku. Modulus division (%1) by zero (%2) is undefined. Dzielenie modulo (%1) przez zero (%2) jest niezdefiniowane. - - - The target name in a processing instruction cannot be %1 in any combination of upper and lower case. Therefore, is %2 invalid. - Docelowa nazwa w instrukcji przetwarzania nie może być %1 w żadnej kombinacji wielkich i małych liter. Dlatego nazwa %2 jest niepoprawna. - %1 takes at most %n argument(s). %2 is therefore invalid. @@ -8409,7 +8991,7 @@ Proszę wybrać inną nazwę pliku. In a simplified stylesheet module, attribute %1 must be present. - W uproszczonym module arkuszu stylu musi wystapić atrybut %1. + W uproszczonym module arkuszu stylu musi wystąpić atrybut %1. @@ -8419,7 +9001,7 @@ Proszę wybrać inną nazwę pliku. Element %1 must have at least one of the attributes %2 or %3. - Element %1 musi posiadać przynajmiej jeden z atrybutów: %2 lub %3. + Element %1 musi posiadać przynajmniej jeden z atrybutów: %2 lub %3. @@ -8531,12 +9113,12 @@ Proszę wybrać inną nazwę pliku. %1 is not allowed to derive from %2 by restriction as the latter defines it as final. - Nie można wywieść %1 z %2 ograniczając go ponieważ jest on zdefiniowany jako ostateczny. + Nie można wywieść %1 z %2 ograniczając go ponieważ jest on zdefiniowany jako końcowy. %1 is not allowed to derive from %2 by extension as the latter defines it as final. - Nie można wywieść %1 z %2 rozszerzając go ponieważ jest on zdefiniowany jako ostateczny. + Nie można wywieść %1 z %2 rozszerzając go ponieważ jest on zdefiniowany jako końcowy. @@ -8562,13 +9144,13 @@ Proszę wybrać inną nazwę pliku. Simple type %1 cannot derive from %2 as the latter defines restriction as final. - Typ prosty %1 nie może wywodzić się z %2 ponieważ ten ostatni jest zdefiniowany jako ostateczny. + Typ prosty %1 nie może wywodzić się z %2 ponieważ ten ostatni jest zdefiniowany jako końcowy. Variety of item type of %1 must be either atomic or union. - Typem elementu %1 musi być albo typ atomowy albo unia. + Typem elementów listy %1 musi być albo typ atomowy albo unia. @@ -8595,12 +9177,12 @@ Proszę wybrać inną nazwę pliku. Base type of simple type %1 has defined derivation by restriction as final. - Typ podstawowy dla typu prostego %1 ma zdefiniowane wywodzenie poprzez ograniczenie jako ostateczne. + Typ podstawowy dla typu prostego %1 ma zdefiniowane wywodzenie poprzez ograniczenie jako końcowe. Item type of base type does not match item type of %1. - Typ elementu w podstawowym typie nie pasuje do typu %1. + Typ elementów listy typu podstawowego nie pasuje do typu elementów listy %1. @@ -8657,7 +9239,7 @@ Proszę wybrać inną nazwę pliku. Content model of complex type %1 is not a valid extension of content model of %2. - Model zawartości typu złożonego %1 nie jest poprawnym rozszerzenien modelu zawartości %2. + Model zawartości typu złożonego %1 nie jest poprawnym rozszerzeniem modelu zawartości %2. @@ -8687,7 +9269,7 @@ Proszę wybrać inną nazwę pliku. Item type of simple type %1 cannot be a complex type. - Typ elementu w prostym typie %1 nie może być typem złożonym. + Typ elementów listy w prostym typie %1 nie może być typem złożonym. @@ -8731,7 +9313,7 @@ Proszę wybrać inną nazwę pliku. %1 facet contains invalid regular expression - Aspekt %1 zawiera niepoprawe wyrażenie regularne + Aspekt %1 zawiera niepoprawne wyrażenie regularne @@ -8902,7 +9484,7 @@ Proszę wybrać inną nazwę pliku. processContent of base wildcard must be weaker than derived wildcard. - "processContent" podstawowego znacznika musi być słabszy od wywiedzionego znacznika. + "processContent" podstawowego dżokera musi być słabszy od wywiedzionego dżokera. @@ -8913,7 +9495,7 @@ Proszę wybrać inną nazwę pliku. Particle contains non-deterministic wildcards. - Element zawiera nieokreślone znaczniki. + Element zawiera nieokreślone dżokery. @@ -8933,13 +9515,13 @@ Proszę wybrać inną nazwę pliku. - Derived attribute %1 does not exists in the base definition. - Wywyiedziony atrybut %1 nie istnieje w podstawowej definicji. + Derived attribute %1 does not exist in the base definition. + Wywiedziony atrybut %1 nie istnieje w podstawowej definicji. Derived attribute %1 does not match the wildcard in the base definition. - Wywiedziony atrybut %1 nie pasuje do znacznika w podstawowej definicji. + Wywiedziony atrybut %1 nie pasuje do dżokera w podstawowej definicji. @@ -8954,12 +9536,12 @@ Proszę wybrać inną nazwę pliku. Derived wildcard is not a subset of the base wildcard. - Wywiedziony znacznik nie jest podzbiorem podstawowego znacznika. + Wywiedziony dżoker nie jest podzbiorem podstawowego dżokera. %1 of derived wildcard is not a valid restriction of %2 of base wildcard - %1 wywiedzionego znacznika nie jest poprawnym ograniczeniem %2 podstawowego znacznika + %1 wywiedzionego dżokera nie jest poprawnym ograniczeniem %2 podstawowego dżokera @@ -8984,12 +9566,12 @@ Proszę wybrać inną nazwę pliku. %1 references identity constraint %2 that is no %3 or %4 element. - %1 odwołuje się do ograniczenia jednostki %2 które nie jest elementem %3 ani %4. + %1 odwołuje się do narzucenia niepowtarzalności %2 które nie jest elementem %3 ani %4. %1 has a different number of fields from the identity constraint %2 that it references. - %1 posiada inna liczbę pól od ograniczenia jednostki %2 które się do niego odwołuje. + %1 posiada inna liczbę pól od narzucenia niepowtarzalności %2 które się do niego odwołuje. @@ -8999,7 +9581,7 @@ Proszę wybrać inną nazwę pliku. Item type %1 of %2 element cannot be resolved. - Nie można rozwiązać typu elementu %1 w elemencie %2. + Nie można rozwiązać typu elementów listy %1 w elemencie %2. @@ -9100,17 +9682,17 @@ Proszę wybrać inną nazwę pliku. Attribute wildcard of %1 is not a valid restriction of attribute wildcard of base type %2. - Znacznik atrybutu %1 nie jest poprawnym ograniczeniem znacznika atrybutu typu podstawowego %2. + Atrybut dżokera %1 nie jest poprawnym ograniczeniem atrybutu dżokera typu podstawowego %2. %1 has attribute wildcard but its base type %2 has not. - %1 posiada znacznik atrybutu lecz jego typ podstawowy %2 go nie posiada. + %1 posiada atrybut dżokera lecz jego typ podstawowy %2 go nie posiada. Union of attribute wildcard of type %1 and attribute wildcard of its base type %2 is not expressible. - Nie można wyrazić unii znacznika atrybutu typu %1 i znacznika atrybutu jego typu podstawowego %2. + Nie można wyrazić unii atrybutu dżokera typu %1 i atrybutu dżokera jego typu podstawowego %2. @@ -9181,17 +9763,17 @@ Proszę wybrać inną nazwę pliku. Element %1 does not match namespace constraint of wildcard in base particle. - Element %1 nie pasuje do znacznika w ograniczeniu przestrzeni nazw w elemencie podstawowym. + Element %1 nie pasuje do ograniczenia przestrzeni nazw dżokera w elemencie podstawowym. Wildcard in derived particle is not a valid subset of wildcard in base particle. - Znacznik w wywiedzionym elemencie nie jest poprawnym podzbiorem znacznika w elemencie podstawowym. + Dżoker w wywiedzionym elemencie nie jest poprawnym podzbiorem dżokera w elemencie podstawowym. processContent of wildcard in derived particle is weaker than wildcard in base particle. - "processContent" znacznika w wywiedzionym elemencie jest słabszy od znacznika w podstawowym elemencie. + "processContent" dżokera w wywiedzionym elemencie jest słabszy od dżokera w podstawowym elemencie. @@ -9385,7 +9967,7 @@ Proszę wybrać inną nazwę pliku. - Component with id %1 has been defined previously. + Component with ID %1 has been defined previously. Komponent o identyfikatorze %1 został uprzednio zdefiniowany. @@ -9421,7 +10003,7 @@ Proszę wybrać inną nazwę pliku. Identity constraint %1 already defined. - Ograniczenie jednostki %1 jest już zdefiniowane. + Narzucenie niepowtarzalności %1 jest już zdefiniowane. @@ -9800,11 +10382,16 @@ Proszę wybrać inną nazwę pliku. - Fixed value constrained not allowed if element is nillable. + Fixed value constraint not allowed if element is nillable. Ograniczenie stałej wartości jest niedozwolone gdy element jest zerowalny. - + + Element %1 cannot contain other elements, as it has a fixed content. + Element %1 nie może zawierać innych elementów ponieważ posiada on stałą zawartość. + + + Specified type %1 is not validly substitutable with element type %2. Podany typ %1 nie jest poprawnie zastępowalny typem elementu %2. @@ -9848,19 +10435,14 @@ Proszę wybrać inną nazwę pliku. Element %1 zawiera niedozwolony text. - - Element %1 can not contain other elements, as it has a fixed content. - Element %1 nie może zawierać innych elementów ponieważ posiada on stałą zawartość. - - - + Element %1 is missing required attribute %2. Brak wymaganego atrybutu %2 w elemencie %1. Attribute %1 does not match the attribute wildcard. - Atrybut %1 nie pasuje do znacznika atrybutu. + Atrybut %1 nie pasuje do atrybutu dżokera. @@ -9912,7 +10494,7 @@ Proszę wybrać inną nazwę pliku. No referenced value found for key reference %1. - Brak wartości do której odwołuje sie klucz %1. + Brak wartości do której odwołuje się klucz %1. diff --git a/translations/qvfb_pl.ts b/translations/qvfb_pl.ts index bc3313e..9b85ad9 100644 --- a/translations/qvfb_pl.ts +++ b/translations/qvfb_pl.ts @@ -4,7 +4,7 @@ AnimationSaveWidget - + Record Nagraj @@ -260,6 +260,11 @@ BGR format format BGR + + + 800x480 + 800x480 + DeviceSkin @@ -322,12 +327,12 @@ QVFb - + Browse... Przeglądaj... - + Load Custom Skin... Załaduj skórki użytkownika... -- cgit v0.12 From 6db765ddb88ab8d64560902b75724fc1fca42551 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 10 Dec 2009 12:14:31 +0200 Subject: Fixed "make run" target for targets with special characters in them. Some misc whitespace got fixed, too. Reviewed-by: Janne Anttila --- qmake/generators/symbian/symmake_abld.cpp | 24 ++++++++++++------------ qmake/generators/symbian/symmake_sbsv2.cpp | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/qmake/generators/symbian/symmake_abld.cpp b/qmake/generators/symbian/symmake_abld.cpp index 6225720..f2baf46 100644 --- a/qmake/generators/symbian/symmake_abld.cpp +++ b/qmake/generators/symbian/symmake_abld.cpp @@ -88,15 +88,15 @@ void SymbianAbldMakefileGenerator::writeMkFile(const QString& wrapperFileName, b t << "# ==============================================================================" << "\n" << endl; t << endl << endl; - + t << "MAKE = make" << endl; t << endl; - + t << "VISUAL_CFG = RELEASE" << endl; - t << "ifeq \"$(CFG)\" \"UDEB\"" << endl; - t << "VISUAL_CFG = DEBUG" << endl; - t << "endif" << endl; - t << endl; + t << "ifeq \"$(CFG)\" \"UDEB\"" << endl; + t << "VISUAL_CFG = DEBUG" << endl; + t << "endif" << endl; + t << endl; t << DO_NOTHING_TARGET " :" << endl; t << "\t" << "@rem " DO_NOTHING_TARGET << endl << endl; @@ -113,8 +113,8 @@ void SymbianAbldMakefileGenerator::writeMkFile(const QString& wrapperFileName, b cleanDepsWinscw.append(WINSCW_DEPLOYMENT_CLEAN_TARGET); finalDeps.append(DO_NOTHING_TARGET); finalDepsWinscw.append(WINSCW_DEPLOYMENT_TARGET); - wrapperTargets << WINSCW_DEPLOYMENT_TARGET - << WINSCW_DEPLOYMENT_CLEAN_TARGET + wrapperTargets << WINSCW_DEPLOYMENT_TARGET + << WINSCW_DEPLOYMENT_CLEAN_TARGET << STORE_BUILD_TARGET; } else { buildDeps.append(CREATE_TEMPS_TARGET " " PRE_TARGETDEPS_TARGET " " STORE_BUILD_TARGET); @@ -153,9 +153,9 @@ void SymbianAbldMakefileGenerator::writeMkFile(const QString& wrapperFileName, b QString makefile(Option::fixPathToTargetOS(fileInfo(wrapperFileName).canonicalFilePath())); foreach(QString target, wrapperTargets) { t << target << " : " << makefile << endl; - t << "\t-$(MAKE) -f \"" << makefile << "\" " << target << " QT_SIS_TARGET=$(VISUAL_CFG)-$(PLATFORM)" << endl << endl; - } - + t << "\t-$(MAKE) -f \"" << makefile << "\" " << target << " QT_SIS_TARGET=$(VISUAL_CFG)-$(PLATFORM)" << endl << endl; + } + t << endl; } // if(ft.open(QIODevice::WriteOnly)) } @@ -375,7 +375,7 @@ void SymbianAbldMakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, bool // Create execution target if (debugPlatforms.contains("winscw") && targetType == TypeExe) { t << "run:" << endl; - t << "\t-call " << epocRoot() << "epoc32\\release\\winscw\\udeb\\" << removePathSeparators(escapeFilePath(fileFixify(project->first("TARGET"))).append(".exe")) << endl << endl; + t << "\t-call " << epocRoot() << "epoc32\\release\\winscw\\udeb\\" << fixedTarget << ".exe" << endl << endl; } } diff --git a/qmake/generators/symbian/symmake_sbsv2.cpp b/qmake/generators/symbian/symmake_sbsv2.cpp index c7eae64..ad22cfd 100644 --- a/qmake/generators/symbian/symmake_sbsv2.cpp +++ b/qmake/generators/symbian/symmake_sbsv2.cpp @@ -234,7 +234,7 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo // create execution target if (debugPlatforms.contains("winscw") && targetType == TypeExe) { t << "run:" << endl; - t << "\t-call " << epocRoot() << "epoc32/release/winscw/udeb/" << removePathSeparators(escapeFilePath(fileFixify(project->first("TARGET"))).append(".exe")) << endl << endl; + t << "\t-call " << epocRoot() << "epoc32/release/winscw/udeb/" << fixedTarget << ".exe" << endl << endl; } } -- cgit v0.12 From 8d790367928765c861bd437583d12849517839ba Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 10 Dec 2009 12:15:26 +0200 Subject: Fixed containers-sequential benchmark for Symbian - RVCT 2.2. couldn't compile static templated function f(), so changed it to non-static, as it should make no difference for this test. - Limited insert_Large tests to fit to typical Symbian device memory. - Some whitespace fixed, too. Task-number: QTBUG-6592 Reviewed-by: Janne Anttila --- tests/benchmarks/containers-sequential/main.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/benchmarks/containers-sequential/main.cpp b/tests/benchmarks/containers-sequential/main.cpp index 76643ca..885db3e 100644 --- a/tests/benchmarks/containers-sequential/main.cpp +++ b/tests/benchmarks/containers-sequential/main.cpp @@ -59,7 +59,7 @@ public: }; template -static T * f(T *ts) // dummy function to prevent code from being optimized away by the compiler +T * f(T *ts) // dummy function to prevent code from being optimized away by the compiler { return ts; } @@ -81,7 +81,7 @@ class UseCases_QVector : public UseCases void lookup(int size) { QVector v; - + T t; for (int i = 0; i < size; ++i) v.append(t); @@ -113,7 +113,7 @@ class UseCases_stdvector : public UseCases void lookup(int size) { std::vector v; - + T t; for (int i = 0; i < size; ++i) v.push_back(t); @@ -132,6 +132,13 @@ struct Large { // A "large" item type int x[1000]; }; +// Symbian devices typically have limited memory +#ifdef Q_OS_SYMBIAN +# define LARGE_MAX_SIZE 2000 +#else +# define LARGE_MAX_SIZE 20000 +#endif + class tst_vector_vs_std : public QObject { Q_OBJECT @@ -190,7 +197,7 @@ void tst_vector_vs_std::insert_Large_data() QTest::addColumn("useStd"); QTest::addColumn("size"); - for (int size = 10; size < 20000; size += 100) { + for (int size = 10; size < LARGE_MAX_SIZE; size += 100) { const QByteArray sizeString = QByteArray::number(size); QTest::newRow(("std::vector-Large--" + sizeString).constData()) << true << size; QTest::newRow(("QVector-Large--" + sizeString).constData()) << false << size; @@ -236,7 +243,7 @@ void tst_vector_vs_std::lookup_Large_data() QTest::addColumn("useStd"); QTest::addColumn("size"); - for (int size = 10; size < 20000; size += 100) { + for (int size = 10; size < LARGE_MAX_SIZE; size += 100) { const QByteArray sizeString = QByteArray::number(size); QTest::newRow(("std::vector-Large--" + sizeString).constData()) << true << size; QTest::newRow(("QVector-Large--" + sizeString).constData()) << false << size; -- cgit v0.12 From e355ade4712fa63794403dae3fda807a58e8b88d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20Meril=C3=A4?= Date: Thu, 10 Dec 2009 12:50:43 +0200 Subject: List item is not highlighted before navigating the list QS60Style does not draw highlight for a list that user has not navigated in yet. Once user makes navigation attempt, highlight is drawn to correct index. This was due to that QS60Style only used State_Selected for deducing where highlight should be drawn to. Task-number: QTBUG-6357 Reviewed-by: Janne Anttila --- src/gui/styles/qs60style.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 98f4aaf..18ad44d 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -1317,6 +1317,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, painter->setClipRect(voptAdj.rect); const bool isSelected = (vopt->state & QStyle::State_Selected); + const bool hasFocus = (vopt->state & QStyle::State_HasFocus); bool isScrollBarVisible = false; int scrollBarWidth = 0; @@ -1359,7 +1360,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, } else { QCommonStyle::drawPrimitive(PE_PanelItemViewItem, &voptAdj, painter, widget);} // draw the focus rect - if (isSelected) { + if (isSelected | hasFocus) { QRect highlightRect = option->rect.adjusted(1,1,-1,-1); QAbstractItemView::SelectionBehavior selectionBehavior = itemView ? itemView->selectionBehavior() : QAbstractItemView::SelectItems; -- cgit v0.12 From c8ac0418fa47316bf4f288a8c0b07611b388c3c6 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Thu, 10 Dec 2009 12:30:04 +0100 Subject: Fix .gitignore to not ignore qdoc.pro Remove an old ignore that was introduced before qdoc moved to $QTDIR/bin Reviewed-by: Oswald Buddenhagen --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 33c9b7c..2069ad5 100644 --- a/.gitignore +++ b/.gitignore @@ -93,7 +93,6 @@ tests/auto/qprocess/fileWriterProcess.txt .com.apple.timemachine.supported tests/auto/qlibrary/libmylib.so* tests/auto/qresourceengine/runtime_resource.rcc -tools/qdoc3/qdoc3* tools/qtestlib/updater/updater* tools/activeqt/testcon/testcon.tlb translations/*.qm -- cgit v0.12 From 2fa94ee5569c91435e68f578f29a712dcfd37e4f Mon Sep 17 00:00:00 2001 From: Tero Saarni Date: Wed, 18 Nov 2009 14:04:08 +0200 Subject: Can't delete selected characters from FEP using backspace touch button. When selection was deleted, the changes where not updated on virtual keyboard. Added new connection to notify when text has changed. Task-number: QTBUG-4847 Reviewed-by: Markku Luukkainen Merge-request: 2149 Signed-off-by: axis --- src/gui/widgets/qlineedit_p.cpp | 5 +++++ src/gui/widgets/qplaintextedit.cpp | 3 +++ src/gui/widgets/qtextedit.cpp | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/src/gui/widgets/qlineedit_p.cpp b/src/gui/widgets/qlineedit_p.cpp index 4437fef..bdf7993 100644 --- a/src/gui/widgets/qlineedit_p.cpp +++ b/src/gui/widgets/qlineedit_p.cpp @@ -149,6 +149,11 @@ void QLineEditPrivate::init(const QString& txt) #endif QObject::connect(control, SIGNAL(cursorPositionChanged(int,int)), q, SLOT(updateMicroFocus())); + +#if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) + QObject::connect(control, SIGNAL(textChanged(const QString &)), + q, SLOT(updateMicroFocus())); +#endif // for now, going completely overboard with updates. QObject::connect(control, SIGNAL(selectionChanged()), diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index 89fe7b8..31f8bb4 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -761,6 +761,9 @@ void QPlainTextEditPrivate::init(const QString &txt) QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SLOT(_q_cursorPositionChanged())); QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged())); +#if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) + QObject::connect(control, SIGNAL(textChanged(const QString &)), q, SLOT(updateMicroFocus())); +#endif // set a null page size initially to avoid any relayouting until the textedit // is shown. relayoutDocument() will take care of setting the page size to the diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp index 1bc0bf1..f79c870 100644 --- a/src/gui/widgets/qtextedit.cpp +++ b/src/gui/widgets/qtextedit.cpp @@ -158,6 +158,11 @@ void QTextEditPrivate::init(const QString &html) QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged())); QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged())); +#if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) + QObject::connect(control, SIGNAL(textChanged(const QString &)), q, SLOT(updateMicroFocus())); +#endif + + QTextDocument *doc = control->document(); // set a null page size initially to avoid any relayouting until the textedit // is shown. relayoutDocument() will take care of setting the page size to the -- cgit v0.12 From 9fd117106c4c18fc5299816ab62cdaeb574b608d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 9 Dec 2009 13:36:52 +0100 Subject: Fix crash in QFontDialog::getFont() on Mac 10.4 [NSFontManager setTarget] is not available on 10.4. Rev-by: Richard Moe Gustavsen --- src/gui/dialogs/qfontdialog_mac.mm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/dialogs/qfontdialog_mac.mm b/src/gui/dialogs/qfontdialog_mac.mm index dacb54c..b9f918f 100644 --- a/src/gui/dialogs/qfontdialog_mac.mm +++ b/src/gui/dialogs/qfontdialog_mac.mm @@ -394,7 +394,9 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont) } [mFontPanel setDelegate:nil]; [[NSFontManager sharedFontManager] setDelegate:nil]; +#ifdef QT_MAC_USE_COCOA [[NSFontManager sharedFontManager] setTarget:nil]; +#endif } @end @@ -518,7 +520,9 @@ void *QFontDialogPrivate::openCocoaFontPanel(const QFont &initial, extraHeight:dialogExtraHeight]; [ourPanel setDelegate:delegate]; [[NSFontManager sharedFontManager] setDelegate:delegate]; +#ifdef QT_MAC_USE_COCOA [[NSFontManager sharedFontManager] setTarget:delegate]; +#endif setFont(delegate, initial); // hack to get correct initial layout -- cgit v0.12 From bfe12d2965130203a27c6d28d06b10a63cd0f2e8 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 10 Dec 2009 17:14:21 +0100 Subject: Designer: Handle "visible"-properties of item view headers correctly. Implement the property sheet (isChanged/reset) correctly and do a hack for resetting the visibility. Task-number: QTBUG-6505 Reviewed-by: Jarek Kobus --- .../formeditor/itemview_propertysheet.cpp | 183 +++++++++------------ .../components/formeditor/itemview_propertysheet.h | 10 +- 2 files changed, 88 insertions(+), 105 deletions(-) diff --git a/tools/designer/src/components/formeditor/itemview_propertysheet.cpp b/tools/designer/src/components/formeditor/itemview_propertysheet.cpp index 38f73e7..96d159a 100644 --- a/tools/designer/src/components/formeditor/itemview_propertysheet.cpp +++ b/tools/designer/src/components/formeditor/itemview_propertysheet.cpp @@ -45,6 +45,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -54,41 +55,27 @@ struct Property { Property() : m_sheet(0),m_id(-1) {} Property(QDesignerPropertySheetExtension *sheet, int id) : m_sheet(sheet), m_id(id) {} - bool operator==(const Property &p) { return m_sheet == p.m_sheet && m_id == p.m_id; } - uint qHash() { - return ((int)(m_sheet-(QDesignerPropertySheetExtension*)(0))) & m_id; - } QDesignerPropertySheetExtension *m_sheet; int m_id; }; -class ItemViewPropertySheetPrivate { +typedef QMap FakePropertyMap; -public: - ItemViewPropertySheetPrivate(QHeaderView *horizontalHeader, - QHeaderView *verticalHeader, - QObject *parent); +struct ItemViewPropertySheetPrivate { + ItemViewPropertySheetPrivate(QDesignerFormEditorInterface *core, + QHeaderView *horizontalHeader, + QHeaderView *verticalHeader); - inline void createMapping(int fakeId, QHeaderView *header, const QString &headerName); inline QStringList realPropertyNames(); inline QString fakePropertyName(const QString &prefix, const QString &realName); - QDesignerFormEditorInterface *m_core; - - // Maps index of fake property - // to index of real property in respective sheet - QHash m_propertyIdMap; + // Maps index of fake property to index of real property in respective sheet + FakePropertyMap m_propertyIdMap; - // Maps name of fake property - // to name of real property + // Maps name of fake property to name of real property QHash m_propertyNameMap; -private: - static QDesignerFormEditorInterface *formEditorForObject(QObject *o); - - QHeaderView *m_hHeader; - QHeaderView *m_vHeader; QHash m_propertySheet; QStringList m_realPropertyNames; }; @@ -111,43 +98,18 @@ using namespace qdesigner_internal; /***************** ItemViewPropertySheetPrivate *********************/ -ItemViewPropertySheetPrivate::ItemViewPropertySheetPrivate(QHeaderView *horizontalHeader, - QHeaderView *verticalHeader, - QObject *parent) - : m_core(formEditorForObject(parent)), - m_hHeader(horizontalHeader), - m_vHeader(verticalHeader) +ItemViewPropertySheetPrivate::ItemViewPropertySheetPrivate(QDesignerFormEditorInterface *core, + QHeaderView *horizontalHeader, + QHeaderView *verticalHeader) { if (horizontalHeader) m_propertySheet.insert(horizontalHeader, qt_extension - (m_core->extensionManager(), horizontalHeader)); + (core->extensionManager(), horizontalHeader)); if (verticalHeader) m_propertySheet.insert(verticalHeader, qt_extension - (m_core->extensionManager(), verticalHeader)); -} - -// Find the form editor in the hierarchy. -// We know that the parent of the sheet is the extension manager -// whose parent is the core. -QDesignerFormEditorInterface *ItemViewPropertySheetPrivate::formEditorForObject(QObject *o) -{ - do { - if (QDesignerFormEditorInterface* core = qobject_cast(o)) - return core; - o = o->parent(); - } while(o); - Q_ASSERT(o); - return 0; -} - -void ItemViewPropertySheetPrivate::createMapping(int fakeId, QHeaderView *header, - const QString &headerName) -{ - const int realPropertyId = m_propertySheet.value(header)->indexOf(headerName); - QDesignerPropertySheetExtension *propertySheet = m_propertySheet.value(header); - m_propertyIdMap.insert(fakeId, Property(propertySheet, realPropertyId)); + (core->extensionManager(), verticalHeader)); } QStringList ItemViewPropertySheetPrivate::realPropertyNames() @@ -194,46 +156,19 @@ QString ItemViewPropertySheetPrivate::fakePropertyName(const QString &prefix, ItemViewPropertySheet::ItemViewPropertySheet(QTreeView *treeViewObject, QObject *parent) : QDesignerPropertySheet(treeViewObject, parent), - d(new ItemViewPropertySheetPrivate(treeViewObject->header(), 0, parent)) + d(new ItemViewPropertySheetPrivate(core(), treeViewObject->header(), 0)) { - QHeaderView *hHeader = treeViewObject->header(); - - foreach (const QString &realPropertyName, d->realPropertyNames()) { - const QString fakePropertyName - = d->fakePropertyName(QLatin1String("header"), realPropertyName); - d->createMapping(createFakeProperty(fakePropertyName, 0), hHeader, realPropertyName); - } - - foreach (int id, d->m_propertyIdMap.keys()) { - setAttribute(id, true); - setPropertyGroup(id, QLatin1String(headerGroup)); - } + initHeaderProperties(treeViewObject->header(), QLatin1String("header")); } - ItemViewPropertySheet::ItemViewPropertySheet(QTableView *tableViewObject, QObject *parent) : QDesignerPropertySheet(tableViewObject, parent), - d(new ItemViewPropertySheetPrivate(tableViewObject->horizontalHeader(), - tableViewObject->verticalHeader(), parent)) + d(new ItemViewPropertySheetPrivate(core(), + tableViewObject->horizontalHeader(), + tableViewObject->verticalHeader())) { - QHeaderView *hHeader = tableViewObject->horizontalHeader(); - QHeaderView *vHeader = tableViewObject->verticalHeader(); - - foreach (const QString &realPropertyName, d->realPropertyNames()) { - const QString fakePropertyName - = d->fakePropertyName(QLatin1String("horizontalHeader"), realPropertyName); - d->createMapping(createFakeProperty(fakePropertyName, 0), hHeader, realPropertyName); - } - foreach (const QString &realPropertyName, d->realPropertyNames()) { - const QString fakePropertyName - = d->fakePropertyName(QLatin1String("verticalHeader"), realPropertyName); - d->createMapping(createFakeProperty(fakePropertyName, 0), vHeader, realPropertyName); - } - - foreach (int id, d->m_propertyIdMap.keys()) { - setAttribute(id, true); - setPropertyGroup(id, QLatin1String(headerGroup)); - } + initHeaderProperties(tableViewObject->horizontalHeader(), QLatin1String("horizontalHeader")); + initHeaderProperties(tableViewObject->verticalHeader(), QLatin1String("verticalHeader")); } ItemViewPropertySheet::~ItemViewPropertySheet() @@ -241,6 +176,24 @@ ItemViewPropertySheet::~ItemViewPropertySheet() delete d; } +void ItemViewPropertySheet::initHeaderProperties(QHeaderView *hv, const QString &prefix) +{ + QDesignerPropertySheetExtension *headerSheet = d->m_propertySheet.value(hv); + Q_ASSERT(headerSheet); + const QString headerGroupS = QLatin1String(headerGroup); + foreach (const QString &realPropertyName, d->realPropertyNames()) { + const int headerIndex = headerSheet->indexOf(realPropertyName); + Q_ASSERT(headerIndex != -1); + const QVariant defaultValue = realPropertyName == QLatin1String(visibleProperty) ? + QVariant(true) : headerSheet->property(headerIndex); + const QString fakePropertyName = d->fakePropertyName(prefix, realPropertyName); + const int fakeIndex = createFakeProperty(fakePropertyName, defaultValue); + d->m_propertyIdMap.insert(fakeIndex, Property(headerSheet, headerIndex)); + setAttribute(fakeIndex, true); + setPropertyGroup(fakeIndex, headerGroupS); + } +} + /*! Returns the mapping of fake property names to real property names */ @@ -251,19 +204,17 @@ QHash ItemViewPropertySheet::propertyNameMap() const QVariant ItemViewPropertySheet::property(int index) const { - if (d->m_propertyIdMap.contains(index)) { - Property realProperty = d->m_propertyIdMap.value(index); - return realProperty.m_sheet->property(realProperty.m_id); - } else { - return QDesignerPropertySheet::property(index); - } + const FakePropertyMap::const_iterator it = d->m_propertyIdMap.constFind(index); + if (it != d->m_propertyIdMap.constEnd()) + return it.value().m_sheet->property(it.value().m_id); + return QDesignerPropertySheet::property(index); } void ItemViewPropertySheet::setProperty(int index, const QVariant &value) { - if (d->m_propertyIdMap.contains(index)) { - Property realProperty = d->m_propertyIdMap.value(index); - realProperty.m_sheet->setProperty(realProperty.m_id, value); + const FakePropertyMap::iterator it = d->m_propertyIdMap.find(index); + if (it != d->m_propertyIdMap.end()) { + it.value().m_sheet->setProperty(it.value().m_id, value); } else { QDesignerPropertySheet::setProperty(index, value); } @@ -271,18 +222,46 @@ void ItemViewPropertySheet::setProperty(int index, const QVariant &value) void ItemViewPropertySheet::setChanged(int index, bool changed) { - if (d->m_propertyIdMap.contains(index)) { - Property realProperty = d->m_propertyIdMap.value(index); - realProperty.m_sheet->setChanged(realProperty.m_id, changed); + const FakePropertyMap::iterator it = d->m_propertyIdMap.find(index); + if (it != d->m_propertyIdMap.end()) { + it.value().m_sheet->setChanged(it.value().m_id, changed); + } else { + QDesignerPropertySheet::setChanged(index, changed); } - QDesignerPropertySheet::setChanged(index, changed); +} + +bool ItemViewPropertySheet::isChanged(int index) const +{ + const FakePropertyMap::const_iterator it = d->m_propertyIdMap.constFind(index); + if (it != d->m_propertyIdMap.constEnd()) + return it.value().m_sheet->isChanged(it.value().m_id); + return QDesignerPropertySheet::isChanged(index); +} + +bool ItemViewPropertySheet::hasReset(int index) const +{ + const FakePropertyMap::const_iterator it = d->m_propertyIdMap.constFind(index); + if (it != d->m_propertyIdMap.constEnd()) + return it.value().m_sheet->hasReset(it.value().m_id); + return QDesignerPropertySheet::hasReset(index); } bool ItemViewPropertySheet::reset(int index) { - if (d->m_propertyIdMap.contains(index)) { - Property realProperty = d->m_propertyIdMap.value(index); - return realProperty.m_sheet->reset(realProperty.m_id); + const FakePropertyMap::iterator it = d->m_propertyIdMap.find(index); + if (it != d->m_propertyIdMap.end()) { + QDesignerPropertySheetExtension *headerSheet = it.value().m_sheet; + const int headerIndex = it.value().m_id; + const bool resetRC = headerSheet->reset(headerIndex); + // Resetting for "visible" might fail and the stored default + // of the Widget database is "false" due to the widget not being + // visible at the time it was determined. Reset to "true" manually. + if (!resetRC && headerSheet->propertyName(headerIndex) == QLatin1String(visibleProperty)) { + headerSheet->setProperty(headerIndex, QVariant(true)); + headerSheet->setChanged(headerIndex, false); + return true; + } + return resetRC; } else { return QDesignerPropertySheet::reset(index); } diff --git a/tools/designer/src/components/formeditor/itemview_propertysheet.h b/tools/designer/src/components/formeditor/itemview_propertysheet.h index a926339..dbcd63d 100644 --- a/tools/designer/src/components/formeditor/itemview_propertysheet.h +++ b/tools/designer/src/components/formeditor/itemview_propertysheet.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE namespace qdesigner_internal { -class ItemViewPropertySheetPrivate; +struct ItemViewPropertySheetPrivate; class ItemViewPropertySheet: public QDesignerPropertySheet { @@ -69,11 +69,15 @@ public: QVariant property(int index) const; void setProperty(int index, const QVariant &value); - void setChanged(int index, bool changed); + virtual void setChanged(int index, bool changed); + virtual bool isChanged(int index) const; - bool reset(int index); + virtual bool hasReset(int index) const; + virtual bool reset(int index); private: + void initHeaderProperties(QHeaderView *hv, const QString &prefix); + ItemViewPropertySheetPrivate *d; }; -- cgit v0.12 From 14c1572d3333358682d7e5dc8a6474dbb12ae0e3 Mon Sep 17 00:00:00 2001 From: ck Date: Thu, 10 Dec 2009 18:27:04 +0100 Subject: Assistant: Add documentation for -remove-search-index. Reviewed-by: David Boddie --- doc/src/development/assistant-manual.qdoc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/src/development/assistant-manual.qdoc b/doc/src/development/assistant-manual.qdoc index 8de500e..5a30e43 100644 --- a/doc/src/development/assistant-manual.qdoc +++ b/doc/src/development/assistant-manual.qdoc @@ -130,7 +130,7 @@ \o -collectionFile \o Uses the specified collection file instead of the default one. \row - \o -showUrl URL + \o -showUrl \o Shows the document referenced by URL. \row \o -enableRemoteControl @@ -156,7 +156,12 @@ \o Unregisters the specified compressed help file from the given collection file. \row - \o -setCurrentFilter filter + \o -remove-search-index + \o Purges the help search engine's index. This option is + useful in case the associated index files get corrupted. + \QA will re-index the documentation at the next start-up. + \row + \o -setCurrentFilter \o Sets the given filter as the active filter. \row \o -quiet -- cgit v0.12 From 1bbb6e4db246d7be69a7592e2e700f79d7858d5a Mon Sep 17 00:00:00 2001 From: Morten Sorvig Date: Thu, 10 Sep 2009 08:49:56 +0200 Subject: Add a mkspec for selecting gcc-4.0 on Mac OS X. This has one known use case: compiling with the 10.4u SDKi on 10.6. (cherry picked from commit 855f1705ceb15c303b55fcced8b0303d90352a44) --- mkspecs/macx-g++40/Info.plist.app | 20 ++++++ mkspecs/macx-g++40/Info.plist.lib | 18 +++++ mkspecs/macx-g++40/qmake.conf | 20 ++++++ mkspecs/macx-g++40/qplatformdefs.h | 132 +++++++++++++++++++++++++++++++++++++ 4 files changed, 190 insertions(+) create mode 100644 mkspecs/macx-g++40/Info.plist.app create mode 100644 mkspecs/macx-g++40/Info.plist.lib create mode 100644 mkspecs/macx-g++40/qmake.conf create mode 100644 mkspecs/macx-g++40/qplatformdefs.h diff --git a/mkspecs/macx-g++40/Info.plist.app b/mkspecs/macx-g++40/Info.plist.app new file mode 100644 index 0000000..393b615 --- /dev/null +++ b/mkspecs/macx-g++40/Info.plist.app @@ -0,0 +1,20 @@ + + + + + CFBundleIconFile + @ICON@ + CFBundlePackageType + APPL + CFBundleGetInfoString + Created by Qt/QMake + CFBundleSignature + @TYPEINFO@ + CFBundleExecutable + @EXECUTABLE@ + CFBundleIdentifier + com.yourcompany.@EXECUTABLE@ + NOTE + This file was generated by Qt/QMake. + + diff --git a/mkspecs/macx-g++40/Info.plist.lib b/mkspecs/macx-g++40/Info.plist.lib new file mode 100644 index 0000000..97609ed --- /dev/null +++ b/mkspecs/macx-g++40/Info.plist.lib @@ -0,0 +1,18 @@ + + + + + CFBundlePackageType + FMWK + CFBundleShortVersionString + @SHORT_VERSION@ + CFBundleGetInfoString + Created by Qt/QMake + CFBundleSignature + @TYPEINFO@ + CFBundleExecutable + @LIBRARY@ + NOTE + Please, do NOT change this file -- It was generated by Qt/QMake. + + diff --git a/mkspecs/macx-g++40/qmake.conf b/mkspecs/macx-g++40/qmake.conf new file mode 100644 index 0000000..d6fd09d --- /dev/null +++ b/mkspecs/macx-g++40/qmake.conf @@ -0,0 +1,20 @@ +#macx-g++ (different from g++.conf) + +# +# qmake configuration for macx-g++ +# +# Mac OS X + command-line compiler +# + +MAKEFILE_GENERATOR = UNIX +TEMPLATE = app +CONFIG += qt warn_on release app_bundle incremental global_init_link_order lib_version_first plugin_no_soname link_prl +QT += core gui +QMAKE_INCREMENTAL_STYLE = sublib + +QMAKE_CC = gcc-4.0 +QMAKE_CXX = g++-4.0 + +include(../common/mac-g++.conf) + +load(qt_config) diff --git a/mkspecs/macx-g++40/qplatformdefs.h b/mkspecs/macx-g++40/qplatformdefs.h new file mode 100644 index 0000000..98e5eaf --- /dev/null +++ b/mkspecs/macx-g++40/qplatformdefs.h @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** 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 qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 QPLATFORMDEFS_H +#define QPLATFORMDEFS_H + +// Get Qt defines/settings + +#include "qglobal.h" + +// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs + +#include + + +// We are hot - unistd.h should have turned on the specific APIs we requested + + +#include +#include +#include +#include +#include +#include +#define QT_NO_LIBRARY_UNLOAD + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef QT_NO_IPV6IFNAME +#include +#endif + +#define QT_FOPEN ::fopen +#define QT_FSEEK ::fseeko +#define QT_FTELL ::ftello +#define QT_FGETPOS ::fgetpos +#define QT_FSETPOS ::fsetpos +#define QT_FPOS_T fpos_t +#define QT_OFF_T off_t + +#define QT_STATBUF struct stat +#define QT_STATBUF4TSTAT struct stat +#define QT_STAT ::stat +#define QT_FSTAT ::fstat +#define QT_LSTAT ::lstat +#define QT_STAT_REG S_IFREG +#define QT_STAT_DIR S_IFDIR +#define QT_STAT_MASK S_IFMT +#define QT_STAT_LNK S_IFLNK +#define QT_SOCKET_CONNECT ::connect +#define QT_SOCKET_BIND ::bind +#define QT_FILENO fileno +#define QT_OPEN ::open +#define QT_CLOSE ::close +#define QT_TRUNCATE ::truncate +#define QT_FTRUNCATE ::ftruncate +#define QT_LSEEK ::lseek +#define QT_READ ::read +#define QT_WRITE ::write +#define QT_ACCESS ::access +#define QT_GETCWD ::getcwd +#define QT_CHDIR ::chdir +#define QT_MKDIR ::mkdir +#define QT_RMDIR ::rmdir +#define QT_OPEN_LARGEFILE 0 +#define QT_OPEN_RDONLY O_RDONLY +#define QT_OPEN_WRONLY O_WRONLY +#define QT_OPEN_RDWR O_RDWR +#define QT_OPEN_CREAT O_CREAT +#define QT_OPEN_TRUNC O_TRUNC +#define QT_OPEN_APPEND O_APPEND + +#define QT_SIGNAL_RETTYPE void +#define QT_SIGNAL_ARGS int +#define QT_SIGNAL_IGNORE (void (*)(int))1 + +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4) +#define QT_SOCKLEN_T socklen_t +#else +#define QT_SOCKLEN_T int +#endif + +#define QT_SNPRINTF ::snprintf +#define QT_VSNPRINTF ::vsnprintf + + +#endif // QPLATFORMDEFS_H -- cgit v0.12 From 8a09d0dfe1010a4b56afa448ff9ee7bb9bdd7427 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 11 Dec 2009 13:03:17 +0200 Subject: Made QFile benchmark compile and run for Symbian - Temporary files need to be deleted after each test, as there is no space to have several 40MB files on typical device. - Read buffer must be allocated dynamically, as Symbian devices have limited stack. - Moved metatype declarations to proper place - Changed _exit() -> exit() - Removed assert from around mkdir - dir creation fails if dir exists, and dir was not created in release builds. - Added QDir::Files to readSmallFiles test directory filter to actually find the files to read. - Fixed filenames to absolute in readSmallFiles test so that it'll find the files even if they are not in current dir. - Write a linefeed to the end of each created file in createSmallFiles, so that the files created have proper size - Only create 1/10th of files in createSmallFiles for Symbian to speed up the test to bearable level. - Added missing ::flose() call to QFileFromPosixBenchmark of open(). - Skipped Windows specific tests on non-Windows platform as just failing them left temporary files to disk Task-number: QTBUG-6593 Reviewed-by: MariusSO --- tests/benchmarks/qfile/main.cpp | 58 +++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/tests/benchmarks/qfile/main.cpp b/tests/benchmarks/qfile/main.cpp index d3f6ab5..4217077 100644 --- a/tests/benchmarks/qfile/main.cpp +++ b/tests/benchmarks/qfile/main.cpp @@ -128,12 +128,18 @@ private: QString tmpDirName; }; +Q_DECLARE_METATYPE(tst_qfile::BenchmarkType) +Q_DECLARE_METATYPE(QIODevice::OpenMode) +Q_DECLARE_METATYPE(QIODevice::OpenModeFlag) + void tst_qfile::createFile() { + removeFile(); // Cleanup in case previous test case aborted before cleaning up + QTemporaryFile tmpFile; tmpFile.setAutoRemove(false); if (!tmpFile.open()) - ::_exit(1); + ::exit(1); filename = tmpFile.fileName(); tmpFile.close(); } @@ -217,7 +223,6 @@ void tst_qfile::readBigFile_data(BenchmarkType type, QIODevice::OpenModeFlag t, for (int i=0; i fileList; Q_FOREACH(QString file, files) { - QFile *f = new QFile(file); + QFile *f = new QFile(tmpDirName+ "/" + file); f->open(QIODevice::ReadOnly|textMode|bufferedMode); fileList.append(f); } @@ -576,7 +601,7 @@ void tst_qfile::readSmallFiles() case(QFSFileEngineBenchmark): { QList fileList; Q_FOREACH(QString file, files) { - QFSFileEngine *fse = new QFSFileEngine(file); + QFSFileEngine *fse = new QFSFileEngine(tmpDirName+ "/" + file); fse->open(QIODevice::ReadOnly|textMode|bufferedMode); fileList.append(fse); } @@ -596,7 +621,7 @@ void tst_qfile::readSmallFiles() case(PosixBenchmark): { QList fileList; Q_FOREACH(QString file, files) { - fileList.append(::fopen(QFile::encodeName(file).constData(), "rb")); + fileList.append(::fopen(QFile::encodeName(tmpDirName+ "/" + file).constData(), "rb")); } QBENCHMARK { @@ -640,11 +665,10 @@ void tst_qfile::readSmallFiles() } break; } -} -Q_DECLARE_METATYPE(tst_qfile::BenchmarkType) -Q_DECLARE_METATYPE(QIODevice::OpenMode) -Q_DECLARE_METATYPE(QIODevice::OpenModeFlag) + removeSmallFiles(); + delete[] buffer; +} QTEST_MAIN(tst_qfile) -- cgit v0.12 From ce9a43bd8b72f8820639fa89d628e303583f4090 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Fri, 11 Dec 2009 14:08:34 +0200 Subject: QS60Style: Slider groove is incorrect Style uses just a line as slider groove, when S60 provides themed graphics for it as well. Task-number: QTBUG-6723 Reviewed-by: Janne Koskinen --- src/gui/styles/qs60style.cpp | 35 ++++++++++++++++++++++++----------- src/gui/styles/qs60style_p.h | 5 +++++ src/gui/styles/qs60style_s60.cpp | 38 +++++++++++++++++++++----------------- 3 files changed, 50 insertions(+), 28 deletions(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 18ad44d..536b6ad 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -204,6 +204,13 @@ void QS60StylePrivate::drawSkinElement(SkinElements element, QPainter *painter, break; case SE_SliderHandleVertical: drawPart(QS60StyleEnums::SP_QgnIndiSliderEdit, painter, rect, flags | SF_PointEast); + case SE_SliderGrooveVertical: + drawRow(QS60StyleEnums::SP_QgnGrafNsliderEndLeft, QS60StyleEnums::SP_QgnGrafNsliderMiddle, + QS60StyleEnums::SP_QgnGrafNsliderEndRight, Qt::Vertical, painter, rect, flags | SF_PointEast); + break; + case SE_SliderGrooveHorizontal: + drawRow(QS60StyleEnums::SP_QgnGrafNsliderEndLeft, QS60StyleEnums::SP_QgnGrafNsliderMiddle, + QS60StyleEnums::SP_QgnGrafNsliderEndRight, Qt::Horizontal, painter, rect, flags | SF_PointNorth); break; case SE_TabBarTabEastActive: drawRow(QS60StyleEnums::SP_QgnGrafTabActiveL, QS60StyleEnums::SP_QgnGrafTabActiveM, @@ -807,7 +814,12 @@ QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlag //ratio of 1:2 for horizontal tab bars (and 2:1 for vertical ones). result.setWidth(result.height()>>1); break; - case QS60StyleEnums::SP_QgnIndiSliderEdit: + + case QS60StyleEnums::SP_QgnGrafNsliderEndLeft: + case QS60StyleEnums::SP_QgnGrafNsliderEndRight: + case QS60StyleEnums::SP_QgnGrafNsliderMiddle: + result.setWidth(result.height()>>1); + break; result.scale(pixelMetric(QStyle::PM_SliderLength), pixelMetric(QStyle::PM_SliderControlThickness), Qt::IgnoreAspectRatio); break; @@ -928,19 +940,20 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom case CC_Slider: if (const QStyleOptionSlider *optionSlider = qstyleoption_cast(option)) { - // The groove is just a centered line. Maybe a qgn_graf_line_* at some point const QRect sliderGroove = subControlRect(control, optionSlider, SC_SliderGroove, widget); - const QPoint sliderGrooveCenter = sliderGroove.center(); const bool horizontal = optionSlider->orientation == Qt::Horizontal; - painter->save(); - if (widget) - painter->setPen(widget->palette().windowText().color()); - if (horizontal) - painter->drawLine(0, sliderGrooveCenter.y(), sliderGroove.right(), sliderGrooveCenter.y()); - else - painter->drawLine(sliderGrooveCenter.x(), 0, sliderGrooveCenter.x(), sliderGroove.bottom()); - painter->restore(); + //Highlight +/* if (optionSlider->state & QStyle::State_HasFocus) + drawPrimitive(PE_FrameFocusRect, optionSlider, painter, widget);*/ + + //Groove graphics + const QS60StylePrivate::SkinElements grooveElement = horizontal ? + QS60StylePrivate::SE_SliderGrooveHorizontal : + QS60StylePrivate::SE_SliderGrooveVertical; + QS60StylePrivate::drawSkinElement(grooveElement, painter, sliderGroove, flags); + + //Handle graphics const QRect sliderHandle = subControlRect(control, optionSlider, SC_SliderHandle, widget); const QS60StylePrivate::SkinElements handleElement = horizontal ? QS60StylePrivate::SE_SliderHandleHorizontal : QS60StylePrivate::SE_SliderHandleVertical; diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index eed66dc..b0982e4 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -119,6 +119,9 @@ public: SP_QgnGrafTabPassiveL, SP_QgnGrafTabPassiveM, SP_QgnGrafTabPassiveR, + SP_QgnGrafNsliderEndLeft, + SP_QgnGrafNsliderEndRight, + SP_QgnGrafNsliderMiddle, SP_QgnIndiCheckboxOff, SP_QgnIndiCheckboxOn, SP_QgnIndiHlColSuper, // Available in S60 release 3.2 and later. @@ -313,6 +316,8 @@ public: SE_ScrollBarHandleVertical, SE_SliderHandleHorizontal, SE_SliderHandleVertical, + SE_SliderGrooveVertical, + SE_SliderGrooveHorizontal, SE_TabBarTabEastActive, SE_TabBarTabEastInactive, SE_TabBarTabNorthActive, diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index fbea644..f8bc6da 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -128,23 +128,27 @@ private: }; const partMapEntry QS60StyleModeSpecifics::m_partMap[] = { - /* SP_QgnGrafBarWait */ {KAknsIIDQgnGrafBarWaitAnim, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnGrafBarFrameCenter */ {KAknsIIDQgnGrafBarFrameCenter, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnGrafBarFrameSideL */ {KAknsIIDQgnGrafBarFrameSideL, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnGrafBarFrameSideR */ {KAknsIIDQgnGrafBarFrameSideR, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnGrafBarProgress */ {KAknsIIDQgnGrafBarProgress, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnGrafScrollArrowDown */ {KAknsIIDQgnGrafScrollArrowDown, EDrawGulIcon, ES60_All, -1,-1}, - /* SP_QgnGrafScrollArrowLeft */ {KAknsIIDQgnGrafScrollArrowLeft, EDrawGulIcon, ES60_All, -1,-1}, - /* SP_QgnGrafScrollArrowRight */ {KAknsIIDQgnGrafScrollArrowRight, EDrawGulIcon, ES60_All, -1,-1}, - /* SP_QgnGrafScrollArrowUp */ {KAknsIIDQgnGrafScrollArrowUp, EDrawGulIcon, ES60_All, -1,-1}, - /* SP_QgnGrafTabActiveL */ {KAknsIIDQgnGrafTabActiveL, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnGrafTabActiveM */ {KAknsIIDQgnGrafTabActiveM, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnGrafTabActiveR */ {KAknsIIDQgnGrafTabActiveR, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnGrafTabPassiveL */ {KAknsIIDQgnGrafTabPassiveL, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnGrafTabPassiveM */ {KAknsIIDQgnGrafTabPassiveM, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnGrafTabPassiveR */ {KAknsIIDQgnGrafTabPassiveR, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnIndiCheckboxOff */ {KAknsIIDQgnIndiCheckboxOff, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnIndiCheckboxOn */ {KAknsIIDQgnIndiCheckboxOn, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnGrafBarWait */ {KAknsIIDQgnGrafBarWaitAnim, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnGrafBarFrameCenter */ {KAknsIIDQgnGrafBarFrameCenter, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnGrafBarFrameSideL */ {KAknsIIDQgnGrafBarFrameSideL, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnGrafBarFrameSideR */ {KAknsIIDQgnGrafBarFrameSideR, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnGrafBarProgress */ {KAknsIIDQgnGrafBarProgress, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnGrafScrollArrowDown */ {KAknsIIDQgnGrafScrollArrowDown, EDrawGulIcon, ES60_All, -1,-1}, + /* SP_QgnGrafScrollArrowLeft */ {KAknsIIDQgnGrafScrollArrowLeft, EDrawGulIcon, ES60_All, -1,-1}, + /* SP_QgnGrafScrollArrowRight */ {KAknsIIDQgnGrafScrollArrowRight, EDrawGulIcon, ES60_All, -1,-1}, + /* SP_QgnGrafScrollArrowUp */ {KAknsIIDQgnGrafScrollArrowUp, EDrawGulIcon, ES60_All, -1,-1}, + /* SP_QgnGrafTabActiveL */ {KAknsIIDQgnGrafTabActiveL, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnGrafTabActiveM */ {KAknsIIDQgnGrafTabActiveM, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnGrafTabActiveR */ {KAknsIIDQgnGrafTabActiveR, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnGrafTabPassiveL */ {KAknsIIDQgnGrafTabPassiveL, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnGrafTabPassiveM */ {KAknsIIDQgnGrafTabPassiveM, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnGrafTabPassiveR */ {KAknsIIDQgnGrafTabPassiveR, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnGrafNsliderEndLeft */ {KAknsIIDQgnGrafNsliderEndLeft, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnGrafNsliderEndRight */ {KAknsIIDQgnGrafNsliderEndRight, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnGrafNsliderMiddle */ {KAknsIIDQgnGrafNsliderMiddle, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnIndiCheckboxOff */ {KAknsIIDQgnIndiCheckboxOff, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnIndiCheckboxOn */ {KAknsIIDQgnIndiCheckboxOn, EDrawIcon, ES60_All, -1,-1}, + // Following 5 items (SP_QgnIndiHlColSuper - SP_QgnIndiHlLineStraight) are available starting from S60 release 3.2. // In 3.1 CommonStyle drawing is used for these QTreeView elements, since no similar icons in AVKON UI. /* SP_QgnIndiHlColSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d5 /* KAknsIIDQgnIndiHlColSuper */}, -- cgit v0.12 From 57a4d8279a64a7844c2a2bf2b45846563c4c3eb5 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Fri, 11 Dec 2009 14:12:16 +0200 Subject: QS60Style: Style does not support pressed state for sliders Currently there is no visual clue that slider is "sunken" (pressed state). There is S60 theme graphic for it, so lets use it. Task-number: QTBUG-6722 Reviewed-by: Janne Koskinen --- src/gui/styles/qs60style.cpp | 23 ++++++++++++++--- src/gui/styles/qs60style_p.h | 5 +++- src/gui/styles/qs60style_s60.cpp | 54 +++++++++++++++++++++------------------- 3 files changed, 52 insertions(+), 30 deletions(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 536b6ad..f33ad5d 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -200,10 +200,17 @@ void QS60StylePrivate::drawSkinElement(SkinElements element, QPainter *painter, QS60StyleEnums::SP_QsnCpScrollHandleBottom, Qt::Vertical, painter, rect, flags | SF_PointNorth); break; case SE_SliderHandleHorizontal: - drawPart(QS60StyleEnums::SP_QgnIndiSliderEdit, painter, rect, flags | SF_PointNorth); + drawPart(QS60StyleEnums::SP_QgnGrafNsliderMarker, painter, rect, flags | SF_PointNorth); break; case SE_SliderHandleVertical: - drawPart(QS60StyleEnums::SP_QgnIndiSliderEdit, painter, rect, flags | SF_PointEast); + drawPart(QS60StyleEnums::SP_QgnGrafNsliderMarker, painter, rect, flags | SF_PointEast); + break; + case SE_SliderHandleSelectedHorizontal: + drawPart(QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected, painter, rect, flags | SF_PointNorth); + break; + case SE_SliderHandleSelectedVertical: + drawPart(QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected, painter, rect, flags | SF_PointEast); + break; case SE_SliderGrooveVertical: drawRow(QS60StyleEnums::SP_QgnGrafNsliderEndLeft, QS60StyleEnums::SP_QgnGrafNsliderMiddle, QS60StyleEnums::SP_QgnGrafNsliderEndRight, Qt::Vertical, painter, rect, flags | SF_PointEast); @@ -820,6 +827,9 @@ QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlag case QS60StyleEnums::SP_QgnGrafNsliderMiddle: result.setWidth(result.height()>>1); break; + + case QS60StyleEnums::SP_QgnGrafNsliderMarker: + case QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected: result.scale(pixelMetric(QStyle::PM_SliderLength), pixelMetric(QStyle::PM_SliderControlThickness), Qt::IgnoreAspectRatio); break; @@ -955,8 +965,13 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom //Handle graphics const QRect sliderHandle = subControlRect(control, optionSlider, SC_SliderHandle, widget); - const QS60StylePrivate::SkinElements handleElement = - horizontal ? QS60StylePrivate::SE_SliderHandleHorizontal : QS60StylePrivate::SE_SliderHandleVertical; + QS60StylePrivate::SkinElements handleElement; + if (optionSlider->state & QStyle::State_Sunken) + handleElement = + horizontal ? QS60StylePrivate::SE_SliderHandleSelectedHorizontal : QS60StylePrivate::SE_SliderHandleSelectedVertical; + else + handleElement = + horizontal ? QS60StylePrivate::SE_SliderHandleHorizontal : QS60StylePrivate::SE_SliderHandleVertical; QS60StylePrivate::drawSkinElement(handleElement, painter, sliderHandle, flags); } break; diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index b0982e4..ab17e2a 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -134,7 +134,8 @@ public: SP_QgnIndiNaviArrowRight, SP_QgnIndiRadiobuttOff, SP_QgnIndiRadiobuttOn, - SP_QgnIndiSliderEdit, + SP_QgnGrafNsliderMarker, + SP_QgnGrafNsliderMarkerSelected, SP_QgnIndiSubMenu, SP_QgnNoteErased, SP_QgnNoteError, @@ -316,6 +317,8 @@ public: SE_ScrollBarHandleVertical, SE_SliderHandleHorizontal, SE_SliderHandleVertical, + SE_SliderHandleSelectedHorizontal, + SE_SliderHandleSelectedVertical, SE_SliderGrooveVertical, SE_SliderGrooveHorizontal, SE_TabBarTabEastActive, diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index f8bc6da..49d8017 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -151,29 +151,30 @@ const partMapEntry QS60StyleModeSpecifics::m_partMap[] = { // Following 5 items (SP_QgnIndiHlColSuper - SP_QgnIndiHlLineStraight) are available starting from S60 release 3.2. // In 3.1 CommonStyle drawing is used for these QTreeView elements, since no similar icons in AVKON UI. - /* SP_QgnIndiHlColSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d5 /* KAknsIIDQgnIndiHlColSuper */}, - /* SP_QgnIndiHlExpSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d6 /* KAknsIIDQgnIndiHlExpSuper */}, - /* SP_QgnIndiHlLineBranch */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d7 /* KAknsIIDQgnIndiHlLineBranch */}, - /* SP_QgnIndiHlLineEnd */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d8 /* KAknsIIDQgnIndiHlLineEnd */}, - /* SP_QgnIndiHlLineStraight */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d9 /* KAknsIIDQgnIndiHlLineStraight */}, - /* SP_QgnIndiMarkedAdd */ {KAknsIIDQgnIndiMarkedAdd, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnIndiNaviArrowLeft */ {KAknsIIDQgnIndiNaviArrowLeft, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnIndiNaviArrowRight */ {KAknsIIDQgnIndiNaviArrowRight, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnIndiRadiobuttOff */ {KAknsIIDQgnIndiRadiobuttOff, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnIndiRadiobuttOn */ {KAknsIIDQgnIndiRadiobuttOn, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnIndiSliderEdit */ {KAknsIIDQgnIndiSliderEdit, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnIndiSubMenu */ {KAknsIIDQgnIndiSubmenu, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnNoteErased */ {KAknsIIDQgnNoteErased, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnNoteError */ {KAknsIIDQgnNoteError, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnNoteInfo */ {KAknsIIDQgnNoteInfo, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnNoteOk */ {KAknsIIDQgnNoteOk, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnNoteQuery */ {KAknsIIDQgnNoteQuery, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnNoteWarning */ {KAknsIIDQgnNoteWarning, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnPropFileSmall */ {KAknsIIDQgnPropFileSmall, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnPropFolderCurrent */ {KAknsIIDQgnPropFolderCurrent, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnPropFolderSmall */ {KAknsIIDQgnPropFolderSmall, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnPropFolderSmallNew */ {KAknsIIDQgnPropFolderSmallNew, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnPropPhoneMemcLarge */ {KAknsIIDQgnPropPhoneMemcLarge, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnIndiHlColSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d5 /* KAknsIIDQgnIndiHlColSuper */}, + /* SP_QgnIndiHlExpSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d6 /* KAknsIIDQgnIndiHlExpSuper */}, + /* SP_QgnIndiHlLineBranch */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d7 /* KAknsIIDQgnIndiHlLineBranch */}, + /* SP_QgnIndiHlLineEnd */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d8 /* KAknsIIDQgnIndiHlLineEnd */}, + /* SP_QgnIndiHlLineStraight */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d9 /* KAknsIIDQgnIndiHlLineStraight */}, + /* SP_QgnIndiMarkedAdd */ {KAknsIIDQgnIndiMarkedAdd, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnIndiNaviArrowLeft */ {KAknsIIDQgnIndiNaviArrowLeft, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnIndiNaviArrowRight */ {KAknsIIDQgnIndiNaviArrowRight, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnIndiRadiobuttOff */ {KAknsIIDQgnIndiRadiobuttOff, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnIndiRadiobuttOn */ {KAknsIIDQgnIndiRadiobuttOn, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnGrafNsliderMarker */ {KAknsIIDQgnGrafNsliderMarker, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnGrafNsliderMarkerSelected */ {KAknsIIDQgnGrafNsliderMarkerSelected, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnIndiSubMenu */ {KAknsIIDQgnIndiSubmenu, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnNoteErased */ {KAknsIIDQgnNoteErased, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnNoteError */ {KAknsIIDQgnNoteError, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnNoteInfo */ {KAknsIIDQgnNoteInfo, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnNoteOk */ {KAknsIIDQgnNoteOk, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnNoteQuery */ {KAknsIIDQgnNoteQuery, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnNoteWarning */ {KAknsIIDQgnNoteWarning, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnPropFileSmall */ {KAknsIIDQgnPropFileSmall, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnPropFolderCurrent */ {KAknsIIDQgnPropFolderCurrent, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnPropFolderSmall */ {KAknsIIDQgnPropFolderSmall, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnPropFolderSmallNew */ {KAknsIIDQgnPropFolderSmallNew, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnPropPhoneMemcLarge */ {KAknsIIDQgnPropPhoneMemcLarge, EDrawIcon, ES60_All, -1,-1}, // 3.1 & 3.2 do not have pressed state for scrollbar, so use normal scrollbar graphics instead. /* SP_QsnCpScrollHandleBottomPressed*/ {KAknsIIDQsnCpScrollHandleBottom, EDrawIcon, ES60_3_X, EAknsMajorGeneric, 0x20f8}, /*KAknsIIDQsnCpScrollHandleBottomPressed*/ @@ -435,8 +436,11 @@ void QS60StyleModeSpecifics::fallbackInfo(const QS60StyleEnums::SkinParts &style case QS60StyleEnums::SP_QgnIndiRadiobuttOn: fallbackIndex = EMbmAvkonQgn_indi_radiobutt_on; break; - case QS60StyleEnums::SP_QgnIndiSliderEdit: - fallbackIndex = EMbmAvkonQgn_indi_slider_edit; + case QS60StyleEnums::SP_QgnGrafNsliderMarker: + fallbackIndex = EMbmAvkonQgn_graf_nslider_marker; + break; + case QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected: + fallbackIndex = EMbmAvkonQgn_graf_nslider_marker_selected; break; case QS60StyleEnums::SP_QgnIndiSubMenu: fallbackIndex = EMbmAvkonQgn_indi_submenu; -- cgit v0.12 From dacbb8b055815f629e2eeccdb7d4ca4cc5a2f839 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 11 Dec 2009 14:10:11 +0100 Subject: Update Polish translations --- translations/designer_pl.ts | 74 ++++++++++++++++++++++----------------------- translations/qt_pl.ts | 24 +++++++-------- 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/translations/designer_pl.ts b/translations/designer_pl.ts index 005ad5a4..acd1827 100644 --- a/translations/designer_pl.ts +++ b/translations/designer_pl.ts @@ -1050,7 +1050,7 @@ Preview Zoom - Powiększenie podglądu + Powiększanie podglądu @@ -1259,7 +1259,7 @@ Show this Dialog on Startup - Pokaż to okno przy uruchamianiu + Pokazuj to okno przy uruchamianiu @@ -1594,7 +1594,7 @@ Skrypt: %3 Edit Widgets - Edytuj widżety + Modyfikuj widżety @@ -1803,7 +1803,7 @@ Czy chcesz zaktualizować położenie pliku lub wygenerować nowy formularz? &Print... - Wy&drukuj... + &Drukuj... @@ -2669,7 +2669,7 @@ Strony pojemników powinny być dodawane jedynie poprzez wyspecyfikowanie ich w Edit Gradient - Edytuj gradient + Modyfikuj gradient @@ -3042,7 +3042,7 @@ Strony pojemników powinny być dodawane jedynie poprzez wyspecyfikowanie ich w Edit... - Edytuj... + Modyfikuj... @@ -3499,7 +3499,7 @@ jako: Edit Resources... - Edytuj zasoby... + Modyfikuj zasoby... @@ -3961,12 +3961,12 @@ Czy chcesz nadpisać szablon? Edit action - Edytuj akcję + Modyfikuj akcję Edit... - Edytuj... + Modyfikuj... @@ -4126,7 +4126,7 @@ Czy chcesz nadpisać szablon? Edit Buddies - Edytuj skojarzone etykiety + Modyfikuj skojarzone etykiety @@ -4134,7 +4134,7 @@ Czy chcesz nadpisać szablon? Edit Buddies - Edytuj skojarzone etykiety + Modyfikuj skojarzone etykiety @@ -4254,7 +4254,7 @@ Czy chcesz nadpisać szablon? Edit Items... - Edytuj elementy... + Modyfikuj elementy... @@ -4653,7 +4653,7 @@ Czy chcesz nadpisać szablon? Edit the selected profile - Edytuj zaznaczony profil + Modyfikuj zaznaczony profil @@ -4673,7 +4673,7 @@ Czy chcesz nadpisać szablon? Edit Profile - Edytuj profil + Modyfikuj profil @@ -4725,7 +4725,7 @@ Czy chcesz nadpisać szablon? Edit contents - Edytuj zawartość + Modyfikuj zawartość @@ -5290,12 +5290,12 @@ Czy chcesz nadpisać szablon? Edit List Widget - Edytuj listę + Modyfikuj listę Edit Combobox - Edytuj combobox + Modyfikuj combobox @@ -5303,7 +5303,7 @@ Czy chcesz nadpisać szablon? Edit Items... - Edytuj elementy... + Modyfikuj elementy... @@ -5608,7 +5608,7 @@ Wybierz inną nazwę. Edit Palette - Edytuj paletę + Modyfikuj paletę @@ -5716,7 +5716,7 @@ Wybierz inną nazwę. Edit text - Edytuj tekst + Modyfikuj tekst @@ -6196,12 +6196,12 @@ Klasa: %2 Edit ToolTip - Edytuj podpowiedź + Modyfikuj podpowiedź Edit WhatsThis - Edytuj "Co to jest" + Modyfikuj "Co to jest" @@ -6326,7 +6326,7 @@ Klasa: %2 Edit text - Edytuj tekst + Modyfikuj tekst @@ -6427,7 +6427,7 @@ Klasa: %2 Edit script - Edytuj skrypt + Modyfikuj skrypt @@ -6477,7 +6477,7 @@ Klasa: %2 Edit Signals/Slots - Edytuj sygnały/sloty + Modyfikuj sygnały/sloty @@ -6490,7 +6490,7 @@ Klasa: %2 Edit Signals/Slots - Edytuj sygnały/sloty + Modyfikuj sygnały/sloty @@ -6514,7 +6514,7 @@ Klasa: %2 Edit Style Sheet - Edytuj arkusz stylu + Modyfikuj arkusz stylu @@ -6581,7 +6581,7 @@ Klasa: %2 Edit Tab Order - Edytuj kolejność tabulacji + Modyfikuj kolejność tabulacji @@ -6589,7 +6589,7 @@ Klasa: %2 Edit Tab Order - Edytuj kolejność tabulacji + Modyfikuj kolejność tabulacji @@ -6597,7 +6597,7 @@ Klasa: %2 Edit Table Widget - Edytuj tablę + Modyfikuj tablę @@ -6646,7 +6646,7 @@ Klasa: %2 Edit Items... - Edytuj elementy... + Modyfikuj elementy... @@ -6682,12 +6682,12 @@ Klasa: %2 Edit HTML - Edytuj HTML + Modyfikuj HTML Edit Text - Edytuj tekst + Modyfikuj tekst @@ -6751,7 +6751,7 @@ Klasa: %2 Edit Tree Widget - Edytuj drzewo + Modyfikuj drzewo @@ -6877,7 +6877,7 @@ Klasa: %2 Edit Items... - Edytuj elementy... + Modyfikujj elementy... @@ -6928,7 +6928,7 @@ Klasa: %2 Edit name - Edytuj nazwę + Modyfikuj nazwę @@ -6944,7 +6944,7 @@ Klasa: %2 Edit Widgets - Edytuj widżety + Modyfikuj widżety diff --git a/translations/qt_pl.ts b/translations/qt_pl.ts index 6368b8f..fabec70 100644 --- a/translations/qt_pl.ts +++ b/translations/qt_pl.ts @@ -3940,12 +3940,12 @@ Proszę o sprawdzenie podanej nazwy pliku. Print all - Wydrukuj wszystko + Drukuj wszystko Print range - Wydrukuj zakres + Drukuj zakres @@ -3993,12 +3993,12 @@ Proszę o sprawdzenie podanej nazwy pliku. Print - Wydrukuj + Drukowanie Print To File ... - Wydrukuj do pliku ... + Drukuj do pliku ... @@ -4034,7 +4034,7 @@ Proszę wybrać inną nazwę pliku. Print selection - Wydrukuj zaznaczone + Drukuj zaznaczone @@ -4200,7 +4200,7 @@ Proszę wybrać inną nazwę pliku. &Print - &Drukuj + Wy&drukuj @@ -4210,12 +4210,12 @@ Proszę wybrać inną nazwę pliku. Print to File (PDF) - Wydrukuj do pliku (PDF) + Drukuj do pliku (PDF) Print to File (Postscript) - Wydrukuj do pliku (Postscript) + Drukuj do pliku (Postscript) @@ -4243,7 +4243,7 @@ Proszę wybrać inną nazwę pliku. Print Preview - Wydrukuj podgląd + Podgląd wydruku @@ -4370,12 +4370,12 @@ Proszę wybrać inną nazwę pliku. Print range - Wydrukuj zakres + Zakres wydruku Print all - Wydrukuj wszystko + Drukuj wszystko @@ -6078,7 +6078,7 @@ Proszę wybrać inną nazwę pliku. Print - Print + Wydrukuj -- cgit v0.12 From 69e8626652aa85d64d4a3fd9e88cfc71b4e5baed Mon Sep 17 00:00:00 2001 From: Aleksandar Sasha Babic Date: Fri, 11 Dec 2009 13:59:54 +0100 Subject: Slow spinbox on N95 when using keys Up/Down In the style demo, spinbox widget, we noticed that to go from 0 to 99 , with key Up, takes 35 seconds. This was too slow. It turned out that no acceleration has been implementd when using keyboard, although acceleration works when mouse used. We fixed this by using timer events, as it is the case for mouse events. We also needed to get what is the keyboard repat rate interval from system. This value is used to set timer intervals in more natural way. Task-number: QT-927 Reviewed-by: janarve --- src/gui/widgets/qabstractspinbox.cpp | 67 ++++++++++++++++++++++++++++++------ src/gui/widgets/qabstractspinbox_p.h | 3 +- 2 files changed, 58 insertions(+), 12 deletions(-) diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/gui/widgets/qabstractspinbox.cpp index a18af4f..8257a16 100644 --- a/src/gui/widgets/qabstractspinbox.cpp +++ b/src/gui/widgets/qabstractspinbox.cpp @@ -65,6 +65,11 @@ #include #endif +#if defined(Q_OS_SYMBIAN) +#include +#include +#endif + //#define QABSTRACTSPINBOX_QSBDEBUG #ifdef QABSTRACTSPINBOX_QSBDEBUG # define QASBDEBUG qDebug @@ -939,10 +944,12 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event) d->edit->setCursorPosition(d->prefix.size()); int steps = 1; + bool isPgUpOrDown = false; switch (event->key()) { case Qt::Key_PageUp: case Qt::Key_PageDown: steps *= 10; + isPgUpOrDown = true; case Qt::Key_Up: case Qt::Key_Down: { #ifdef QT_KEYPAD_NAVIGATION @@ -964,7 +971,13 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event) if (style()->styleHint(QStyle::SH_SpinBox_AnimateButton, 0, this)) { d->buttonState = (Keyboard | (up ? Up : Down)); } - stepBy(steps); + if (d->spinClickTimerId == -1) + stepBy(steps); + if(event->isAutoRepeat() && !isPgUpOrDown) { + if(d->spinClickThresholdTimerId == -1 && d->spinClickTimerId == -1) { + d->updateState(up, true); + } + } #ifndef QT_NO_ACCESSIBILITY QAccessible::updateAccessibility(this, 0, QAccessible::ValueChanged); #endif @@ -1061,8 +1074,7 @@ void QAbstractSpinBox::keyReleaseEvent(QKeyEvent *event) { Q_D(QAbstractSpinBox); - if (d->buttonState & Keyboard && !event->isAutoRepeat() - && style()->styleHint(QStyle::SH_SpinBox_AnimateButton, 0, this)) { + if (d->buttonState & Keyboard && !event->isAutoRepeat()) { d->reset(); } else { d->edit->event(event); @@ -1148,6 +1160,36 @@ void QAbstractSpinBox::hideEvent(QHideEvent *event) QWidget::hideEvent(event); } + +/*! + \internal + + Used when acceleration is turned on. We need to get the + keyboard auto repeat rate from OS. This value is used as + argument when starting acceleration related timers. + + Every platform should, either, use native calls to obtain + the value or hard code some reasonable rate. + + Remember that time value should be given in msecs. +*/ +static int getKeyboardAutoRepeatRate() { + int ret = 30; +#if defined(Q_OS_SYMBIAN) + TTimeIntervalMicroSeconds32 initialTime; + TTimeIntervalMicroSeconds32 time; + S60->wsSession().GetKeyboardRepeatRate(initialTime, time); + ret = time.Int() / 1000; // msecs +#elif defined(Q_OS_WIN) + DWORD time; + if (SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &time, 0) != FALSE) + ret = static_cast(1000 / static_cast(time)); // msecs +#else +#pragma message("Using default guesstimated value for keyboard repeat rate") +#endif + return ret; // msecs +} + /*! \reimp */ @@ -1160,14 +1202,17 @@ void QAbstractSpinBox::timerEvent(QTimerEvent *event) if (event->timerId() == d->spinClickThresholdTimerId) { killTimer(d->spinClickThresholdTimerId); d->spinClickThresholdTimerId = -1; - d->spinClickTimerId = startTimer(d->spinClickTimerInterval); + d->effectiveSpinRepeatRate = d->buttonState & Keyboard + ? getKeyboardAutoRepeatRate() + : d->spinClickTimerInterval; + d->spinClickTimerId = startTimer(d->effectiveSpinRepeatRate); doStep = true; } else if (event->timerId() == d->spinClickTimerId) { if (d->accelerate) { - d->acceleration = d->acceleration + (int)(d->spinClickTimerInterval * 0.05); - if (d->spinClickTimerInterval - d->acceleration >= 10) { + d->acceleration = d->acceleration + (int)(d->effectiveSpinRepeatRate * 0.05); + if (d->effectiveSpinRepeatRate - d->acceleration >= 10) { killTimer(d->spinClickTimerId); - d->spinClickTimerId = startTimer(d->spinClickTimerInterval - d->acceleration); + d->spinClickTimerId = startTimer(d->effectiveSpinRepeatRate - d->acceleration); } } doStep = true; @@ -1308,8 +1353,8 @@ void QAbstractSpinBox::mouseReleaseEvent(QMouseEvent *event) QAbstractSpinBoxPrivate::QAbstractSpinBoxPrivate() : edit(0), type(QVariant::Invalid), spinClickTimerId(-1), spinClickTimerInterval(100), spinClickThresholdTimerId(-1), spinClickThresholdTimerInterval(-1), - buttonState(None), cachedText(QLatin1String("\x01")), cachedState(QValidator::Invalid), - pendingEmit(false), readOnly(false), wrapping(false), + effectiveSpinRepeatRate(1), buttonState(None), cachedText(QLatin1String("\x01")), + cachedState(QValidator::Invalid), pendingEmit(false), readOnly(false), wrapping(false), ignoreCursorPositionChanged(false), frame(true), accelerate(false), keyboardTracking(true), cleared(false), ignoreUpdateEdit(false), correctionMode(QAbstractSpinBox::CorrectToPreviousValue), acceleration(0), hoverControl(QStyle::SC_None), buttonSymbols(QAbstractSpinBox::UpDownArrows), validator(0) @@ -1554,7 +1599,7 @@ void QAbstractSpinBoxPrivate::reset() Updates the state of the spinbox. */ -void QAbstractSpinBoxPrivate::updateState(bool up) +void QAbstractSpinBoxPrivate::updateState(bool up, bool fromKeyboard /* = false */) { Q_Q(QAbstractSpinBox); if ((up && (buttonState & Up)) || (!up && (buttonState & Down))) @@ -1563,7 +1608,7 @@ void QAbstractSpinBoxPrivate::updateState(bool up) if (q && (q->stepEnabled() & (up ? QAbstractSpinBox::StepUpEnabled : QAbstractSpinBox::StepDownEnabled))) { spinClickThresholdTimerId = q->startTimer(spinClickThresholdTimerInterval); - buttonState = (up ? (Mouse | Up) : (Mouse | Down)); + buttonState = (up ? Up : Down) | (fromKeyboard ? Keyboard : Mouse); q->stepBy(up ? 1 : -1); #ifndef QT_NO_ACCESSIBILITY QAccessible::updateAccessibility(q, 0, QAccessible::ValueChanged); diff --git a/src/gui/widgets/qabstractspinbox_p.h b/src/gui/widgets/qabstractspinbox_p.h index 3020cbc..55f94d7 100644 --- a/src/gui/widgets/qabstractspinbox_p.h +++ b/src/gui/widgets/qabstractspinbox_p.h @@ -98,7 +98,7 @@ public: void init(); void reset(); - void updateState(bool up); + void updateState(bool up, bool fromKeyboard = false); QString stripped(const QString &text, int *pos = 0) const; bool specialValue() const; virtual QVariant getZeroVariant() const; @@ -129,6 +129,7 @@ public: QVariant value, minimum, maximum, singleStep; QVariant::Type type; int spinClickTimerId, spinClickTimerInterval, spinClickThresholdTimerId, spinClickThresholdTimerInterval; + int effectiveSpinRepeatRate; uint buttonState; mutable QString cachedText; mutable QVariant cachedValue; -- cgit v0.12 From d1fd7e611651bea5497048c8f16df8de9618f6ba Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Fri, 11 Dec 2009 15:35:57 +0200 Subject: QS60Style: Groove changes caused build break of S60 3.1 3.1 does not have theme graphics IDs that we use in style, so it cannot be compiled in 3.1. As a fallback, 3.1 will use the previous method of drawing a slider. Reviewed-by: Alessandro Portale --- src/gui/styles/qs60style.cpp | 22 ++++++++++++++++++---- src/gui/styles/qs60style_p.h | 1 + src/gui/styles/qs60style_s60.cpp | 19 ++++++++++++------- src/gui/styles/qs60style_simulated.cpp | 5 +++++ 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index f33ad5d..17db53d 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -958,10 +958,24 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom drawPrimitive(PE_FrameFocusRect, optionSlider, painter, widget);*/ //Groove graphics - const QS60StylePrivate::SkinElements grooveElement = horizontal ? - QS60StylePrivate::SE_SliderGrooveHorizontal : - QS60StylePrivate::SE_SliderGrooveVertical; - QS60StylePrivate::drawSkinElement(grooveElement, painter, sliderGroove, flags); + if (QS60StylePrivate::hasSliderGrooveGraphic()) { + const QS60StylePrivate::SkinElements grooveElement = horizontal ? + QS60StylePrivate::SE_SliderGrooveHorizontal : + QS60StylePrivate::SE_SliderGrooveVertical; + QS60StylePrivate::drawSkinElement(grooveElement, painter, sliderGroove, flags); + } else { + const QRect sliderGroove = subControlRect(control, optionSlider, SC_SliderGroove, widget); + const QPoint sliderGrooveCenter = sliderGroove.center(); + const bool horizontal = optionSlider->orientation == Qt::Horizontal; + painter->save(); + if (widget) + painter->setPen(widget->palette().windowText().color()); + if (horizontal) + painter->drawLine(0, sliderGrooveCenter.y(), sliderGroove.right(), sliderGrooveCenter.y()); + else + painter->drawLine(sliderGrooveCenter.x(), 0, sliderGrooveCenter.x(), sliderGroove.bottom()); + painter->restore(); + } //Handle graphics const QRect sliderHandle = subControlRect(control, optionSlider, SC_SliderHandle, widget); diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index ab17e2a..65d7574 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -411,6 +411,7 @@ public: static bool isTouchSupported(); static bool isToolBarBackground(); + static bool hasSliderGrooveGraphic(); // calculates average color based on button skin graphics (minus borders). QColor colorFromFrameGraphics(SkinFrameElements frame) const; diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index 49d8017..48a6801 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -143,9 +143,9 @@ const partMapEntry QS60StyleModeSpecifics::m_partMap[] = { /* SP_QgnGrafTabPassiveL */ {KAknsIIDQgnGrafTabPassiveL, EDrawIcon, ES60_All, -1,-1}, /* SP_QgnGrafTabPassiveM */ {KAknsIIDQgnGrafTabPassiveM, EDrawIcon, ES60_All, -1,-1}, /* SP_QgnGrafTabPassiveR */ {KAknsIIDQgnGrafTabPassiveR, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnGrafNsliderEndLeft */ {KAknsIIDQgnGrafNsliderEndLeft, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnGrafNsliderEndRight */ {KAknsIIDQgnGrafNsliderEndRight, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnGrafNsliderMiddle */ {KAknsIIDQgnGrafNsliderMiddle, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnGrafNsliderEndLeft */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19cf /* KAknsIIDQgnGrafNsliderEndLeft */}, + /* SP_QgnGrafNsliderEndRight */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d0 /* KAknsIIDQgnGrafNsliderEndRight */}, + /* SP_QgnGrafNsliderMiddle */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d2 /* KAknsIIDQgnGrafNsliderMiddle */}, /* SP_QgnIndiCheckboxOff */ {KAknsIIDQgnIndiCheckboxOff, EDrawIcon, ES60_All, -1,-1}, /* SP_QgnIndiCheckboxOn */ {KAknsIIDQgnIndiCheckboxOn, EDrawIcon, ES60_All, -1,-1}, @@ -161,8 +161,8 @@ const partMapEntry QS60StyleModeSpecifics::m_partMap[] = { /* SP_QgnIndiNaviArrowRight */ {KAknsIIDQgnIndiNaviArrowRight, EDrawIcon, ES60_All, -1,-1}, /* SP_QgnIndiRadiobuttOff */ {KAknsIIDQgnIndiRadiobuttOff, EDrawIcon, ES60_All, -1,-1}, /* SP_QgnIndiRadiobuttOn */ {KAknsIIDQgnIndiRadiobuttOn, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnGrafNsliderMarker */ {KAknsIIDQgnGrafNsliderMarker, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnGrafNsliderMarkerSelected */ {KAknsIIDQgnGrafNsliderMarkerSelected, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnGrafNsliderMarker */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d1 /* KAknsIIDQgnGrafNsliderMarker */}, + /* SP_QgnGrafNsliderMarkerSelected */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x1a4a /* KAknsIIDQgnGrafNsliderMarkerSelected */}, /* SP_QgnIndiSubMenu */ {KAknsIIDQgnIndiSubmenu, EDrawIcon, ES60_All, -1,-1}, /* SP_QgnNoteErased */ {KAknsIIDQgnNoteErased, EDrawIcon, ES60_All, -1,-1}, /* SP_QgnNoteError */ {KAknsIIDQgnNoteError, EDrawIcon, ES60_All, -1,-1}, @@ -437,10 +437,10 @@ void QS60StyleModeSpecifics::fallbackInfo(const QS60StyleEnums::SkinParts &style fallbackIndex = EMbmAvkonQgn_indi_radiobutt_on; break; case QS60StyleEnums::SP_QgnGrafNsliderMarker: - fallbackIndex = EMbmAvkonQgn_graf_nslider_marker; + fallbackIndex = 17572; /* EMbmAvkonQgn_graf_nslider_marker */ break; case QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected: - fallbackIndex = EMbmAvkonQgn_graf_nslider_marker_selected; + fallbackIndex = 17574; /* EMbmAvkonQgn_graf_nslider_marker_selected */ break; case QS60StyleEnums::SP_QgnIndiSubMenu: fallbackIndex = EMbmAvkonQgn_indi_submenu; @@ -595,6 +595,11 @@ bool QS60StylePrivate::isToolBarBackground() return (QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2); } +bool QS60StylePrivate::hasSliderGrooveGraphic() +{ + return QSysInfo::s60Version() != QSysInfo::SV_S60_3_1; +} + QPoint qt_s60_fill_background_offset(const QWidget *targetWidget) { CCoeControl *control = targetWidget->effectiveWinId(); diff --git a/src/gui/styles/qs60style_simulated.cpp b/src/gui/styles/qs60style_simulated.cpp index 55d5771..e49854f 100644 --- a/src/gui/styles/qs60style_simulated.cpp +++ b/src/gui/styles/qs60style_simulated.cpp @@ -337,6 +337,11 @@ bool QS60StylePrivate::isToolBarBackground() return true; } +bool QS60StylePrivate::hasSliderGrooveGraphic() +{ + return false; +} + QFont QS60StylePrivate::s60Font_specific(QS60StyleEnums::FontCategories fontCategory, int pointSize) { QFont result; -- cgit v0.12 From bf8e5ae8b05d8e6efeaa36c1c556a4b2f52ffed1 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Fri, 11 Dec 2009 15:46:57 +0200 Subject: QS60Style: Theme graphics for QSlider in 3.1 These were missed from previous fix. Reviewed-by: Alessandro Portale --- src/gui/styles/qs60style_s60.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index 48a6801..d5b3f73 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -143,6 +143,8 @@ const partMapEntry QS60StyleModeSpecifics::m_partMap[] = { /* SP_QgnGrafTabPassiveL */ {KAknsIIDQgnGrafTabPassiveL, EDrawIcon, ES60_All, -1,-1}, /* SP_QgnGrafTabPassiveM */ {KAknsIIDQgnGrafTabPassiveM, EDrawIcon, ES60_All, -1,-1}, /* SP_QgnGrafTabPassiveR */ {KAknsIIDQgnGrafTabPassiveR, EDrawIcon, ES60_All, -1,-1}, + + // In 3.1 there is no slider groove. /* SP_QgnGrafNsliderEndLeft */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19cf /* KAknsIIDQgnGrafNsliderEndLeft */}, /* SP_QgnGrafNsliderEndRight */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d0 /* KAknsIIDQgnGrafNsliderEndRight */}, /* SP_QgnGrafNsliderMiddle */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d2 /* KAknsIIDQgnGrafNsliderMiddle */}, @@ -161,8 +163,10 @@ const partMapEntry QS60StyleModeSpecifics::m_partMap[] = { /* SP_QgnIndiNaviArrowRight */ {KAknsIIDQgnIndiNaviArrowRight, EDrawIcon, ES60_All, -1,-1}, /* SP_QgnIndiRadiobuttOff */ {KAknsIIDQgnIndiRadiobuttOff, EDrawIcon, ES60_All, -1,-1}, /* SP_QgnIndiRadiobuttOn */ {KAknsIIDQgnIndiRadiobuttOn, EDrawIcon, ES60_All, -1,-1}, - /* SP_QgnGrafNsliderMarker */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d1 /* KAknsIIDQgnGrafNsliderMarker */}, - /* SP_QgnGrafNsliderMarkerSelected */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x1a4a /* KAknsIIDQgnGrafNsliderMarkerSelected */}, + + // In 3.1 there different slider graphic and no pressed state. + /* SP_QgnGrafNsliderMarker */ {KAknsIIDQgnIndiSliderEdit, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d1 /* KAknsIIDQgnGrafNsliderMarker */}, + /* SP_QgnGrafNsliderMarkerSelected */ {KAknsIIDQgnIndiSliderEdit, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x1a4a /* KAknsIIDQgnGrafNsliderMarkerSelected */}, /* SP_QgnIndiSubMenu */ {KAknsIIDQgnIndiSubmenu, EDrawIcon, ES60_All, -1,-1}, /* SP_QgnNoteErased */ {KAknsIIDQgnNoteErased, EDrawIcon, ES60_All, -1,-1}, /* SP_QgnNoteError */ {KAknsIIDQgnNoteError, EDrawIcon, ES60_All, -1,-1}, -- cgit v0.12 From 8f28b68bcd1e18529ebece8c94133443b925ebab Mon Sep 17 00:00:00 2001 From: Aleksandar Sasha Babic Date: Fri, 11 Dec 2009 15:03:19 +0100 Subject: qreal-ization In some places we do have direct math related calls. Almost all are calling the double precision functions even if the args and results are float. This leads to unnecessary float->double and double->float transitions. By using wrapper functions we can control which functrion variants are effectively called. Task-number: QTBUG-4894 Reviewed-by: Shane Kearns --- src/corelib/tools/qline.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp index d0afb7a..8112757 100644 --- a/src/corelib/tools/qline.cpp +++ b/src/corelib/tools/qline.cpp @@ -574,7 +574,7 @@ qreal QLineF::angle() const const qreal dx = pt2.x() - pt1.x(); const qreal dy = pt2.y() - pt1.y(); - const qreal theta = atan2(-dy, dx) * 360.0 / M_2PI; + const qreal theta = qAtan2(-dy, dx) * 360.0 / M_2PI; const qreal theta_normalized = theta < 0 ? theta + 360 : theta; @@ -814,7 +814,7 @@ qreal QLineF::angle(const QLineF &l) const qreal cos_line = (dx()*l.dx() + dy()*l.dy()) / (length()*l.length()); qreal rad = 0; // only accept cos_line in the range [-1,1], if it is outside, use 0 (we return 0 rather than PI for those cases) - if (cos_line >= -1.0 && cos_line <= 1.0) rad = acos( cos_line ); + if (cos_line >= -1.0 && cos_line <= 1.0) rad = qAcos( cos_line ); return rad * 360 / M_2PI; } -- cgit v0.12 From 5b7e896355f555cc24ee1d181f622aa2856db0fc Mon Sep 17 00:00:00 2001 From: Aleksandar Sasha Babic Date: Fri, 11 Dec 2009 15:35:40 +0100 Subject: qreal-ization Using math wrapper functions instead direct call. This gives us top-level control to what (single/double) precision we are effectively using. Task-number: QTBUG-4894 Reviewed-by: janarve --- src/3rdparty/easing/easing.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/3rdparty/easing/easing.cpp b/src/3rdparty/easing/easing.cpp index 81af40f..7d70a4d 100644 --- a/src/3rdparty/easing/easing.cpp +++ b/src/3rdparty/easing/easing.cpp @@ -252,7 +252,7 @@ static qreal easeOutInQuint(qreal t) */ static qreal easeInSine(qreal t) { - return (t == 1.0) ? 1.0 : -::cos(t * M_PI_2) + 1.0; + return (t == 1.0) ? 1.0 : -::qCos(t * M_PI_2) + 1.0; } /** @@ -263,7 +263,7 @@ static qreal easeInSine(qreal t) */ static qreal easeOutSine(qreal t) { - return ::sin(t* M_PI_2); + return ::qSin(t* M_PI_2); } /** @@ -274,7 +274,7 @@ static qreal easeOutSine(qreal t) */ static qreal easeInOutSine(qreal t) { - return -0.5 * (::cos(M_PI*t) - 1); + return -0.5 * (::qCos(M_PI*t) - 1); } /** @@ -397,15 +397,15 @@ static qreal easeInElastic_helper(qreal t, qreal b, qreal c, qreal d, qreal a, q if (t_adj==1) return b+c; qreal s; - if(a < ::fabs(c)) { + if(a < ::qFabs(c)) { a = c; s = p / 4.0f; } else { - s = p / (2 * M_PI) * ::asin(c / a); + s = p / (2 * M_PI) * ::qAsin(c / a); } t_adj -= 1.0f; - return -(a*::qPow(2.0f,10*t_adj) * ::sin( (t_adj*d-s)*(2*M_PI)/p )) + b; + return -(a*::qPow(2.0f,10*t_adj) * ::qSin( (t_adj*d-s)*(2*M_PI)/p )) + b; } /** @@ -431,10 +431,10 @@ static qreal easeOutElastic_helper(qreal t, qreal /*b*/, qreal c, qreal /*d*/, q a = c; s = p / 4.0f; } else { - s = p / (2 * M_PI) * ::asin(c / a); + s = p / (2 * M_PI) * ::qAsin(c / a); } - return (a*::qPow(2.0f,-10*t) * ::sin( (t-s)*(2*M_PI)/p ) + c); + return (a*::qPow(2.0f,-10*t) * ::qSin( (t-s)*(2*M_PI)/p ) + c); } /** @@ -469,11 +469,11 @@ static qreal easeInOutElastic(qreal t, qreal a, qreal p) a = 1.0; s = p / 4.0f; } else { - s = p / (2 * M_PI) * ::asin(1.0 / a); + s = p / (2 * M_PI) * ::qAsin(1.0 / a); } - if (t < 1) return -.5*(a*::qPow(2.0f,10*(t-1)) * ::sin( (t-1-s)*(2*M_PI)/p )); - return a*::qPow(2.0f,-10*(t-1)) * ::sin( (t-1-s)*(2*M_PI)/p )*.5 + 1.0; + if (t < 1) return -.5*(a*::qPow(2.0f,10*(t-1)) * ::qSin( (t-1-s)*(2*M_PI)/p )); + return a*::qPow(2.0f,-10*(t-1)) * ::qSin( (t-1-s)*(2*M_PI)/p )*.5 + 1.0; } /** -- cgit v0.12 From b2f4c48d5d3096e7c12fd51b8bc6bdabe2c6fd7b Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 14 Dec 2009 10:55:57 +0200 Subject: Skipped the most memory intensive tests in QByteArray benchmark. Symbian devices typically have limited memory, so skipping the cases that require tens of megabytes or more of memory. Task-number: QTBUG-6780 Reviewed-by: Janne Anttila --- tests/benchmarks/qbytearray/main.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/benchmarks/qbytearray/main.cpp b/tests/benchmarks/qbytearray/main.cpp index 6a481f1..78c5b16 100644 --- a/tests/benchmarks/qbytearray/main.cpp +++ b/tests/benchmarks/qbytearray/main.cpp @@ -73,6 +73,11 @@ void tst_qbytearray::append() { QFETCH(int, size); +#ifdef Q_OS_SYMBIAN + if (size > 1000000) + QSKIP("Skipped due to limited memory in many Symbian devices.", SkipSingle); +#endif + QByteArray ba; QBENCHMARK { QByteArray ba2(size, 'x'); -- cgit v0.12 From dff377e72c1c84aefd81cf92da75d65562bec6b6 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 14 Dec 2009 11:10:26 +0100 Subject: Designer: Show actions in action editor in QKeySequence::NativeText format as in Property editor and elsewhere for consistence. Task-number: QTBUG-6760 --- tools/designer/src/lib/shared/actionrepository.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/designer/src/lib/shared/actionrepository.cpp b/tools/designer/src/lib/shared/actionrepository.cpp index 1655d07..83e64e6 100644 --- a/tools/designer/src/lib/shared/actionrepository.cpp +++ b/tools/designer/src/lib/shared/actionrepository.cpp @@ -226,7 +226,7 @@ void ActionModel::setItems(QDesignerFormEditorInterface *core, QAction *action, item->setText(action->text()); item->setToolTip(action->text()); // shortcut - const QString shortcut = actionShortCut(core, action).value().toString(); + const QString shortcut = actionShortCut(core, action).value().toString(QKeySequence::NativeText); item = sl[ShortCutColumn]; item->setText(shortcut); item->setToolTip(shortcut); -- cgit v0.12 From 0f18542566e72efc09a21c7f69927159d7ca2df5 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 14 Dec 2009 12:51:25 +0100 Subject: doc: Fixed erroneous qdoc error message. qdoc reported a "No documentation" error for images used in examples, but these images aren't supposed to have documentation. Task-number: QTBUG-4484 --- tools/qdoc3/generator.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp index 9389268..95319ca 100644 --- a/tools/qdoc3/generator.cpp +++ b/tools/qdoc3/generator.cpp @@ -323,7 +323,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) const FakeNode *fake = static_cast(node); if (fake->subType() == Node::Example) generateExampleFiles(fake, marker); - else if (fake->subType() == Node::File) + else if ((fake->subType() == Node::File) || (fake->subType() == Node::Image)) quiet = true; } @@ -547,9 +547,6 @@ void Generator::generateFileList(const FakeNode* fake, ++count; QString file = child->name(); - if (file == "network/qftp/images/dir.png") - qDebug() << "FILE:" << file; - openedList.next(); text << Atom(Atom::ListItemNumber, openedList.numberString()) << Atom(Atom::ListItemLeft, openedList.styleString()) -- cgit v0.12 From 83d333a2b181cbd5c87219599fdc188757261269 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Mon, 14 Dec 2009 13:55:36 +0200 Subject: FEP indicator shown in status pane when it should not FEP indicator is shown in few cases in statusbar when it should not be. Case a) Application contains item view. QAbstractItemView is initialized as having WA_InputMethodEnabled on, irregardless of functionality of each separate cell. So we need to check the model for the itemview cell about to receive focus, is it editable. If it isn't then, we'll set the WA_InputMethodEnabled as false. This will fix the FEP indicators in a lot of cases: lists with cells, empty lists, combobox lists, ... Case b) Combobox also initializes itself with WA_InputMethodEnabled active. Even if the fix a) fixed the list inside combobox, the widget itself when receiving focus needs also fixing. If we check the editable flag of combobox when initializing the comment, we can set the flag off. Task-number: QTBUG-5705 Reviewed-by: axis --- src/gui/itemviews/qabstractitemview.cpp | 19 +++++++++++++++++-- src/gui/widgets/qcombobox.cpp | 5 ++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index de6e6cb..d0aac2a 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -2065,9 +2065,13 @@ void QAbstractItemView::focusInEvent(QFocusEvent *event) { Q_D(QAbstractItemView); QAbstractScrollArea::focusInEvent(event); - if (selectionModel() + + const QItemSelectionModel* model = selectionModel(); + const bool currentIndexValid = currentIndex().isValid(); + + if (model && !d->currentIndexSet - && !currentIndex().isValid()) { + && !currentIndexValid) { bool autoScroll = d->autoScroll; d->autoScroll = false; QModelIndex index = moveCursor(MoveNext, Qt::NoModifier); // first visible index @@ -2075,6 +2079,17 @@ void QAbstractItemView::focusInEvent(QFocusEvent *event) selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate); d->autoScroll = autoScroll; } + + if (model && currentIndexValid) { + if (currentIndex().flags() != Qt::ItemIsEditable) + setAttribute(Qt::WA_InputMethodEnabled, false); + else + setAttribute(Qt::WA_InputMethodEnabled); + } + + if (!currentIndexValid) + setAttribute(Qt::WA_InputMethodEnabled, false); + d->viewport->update(); } diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index bd1d8ba..b7dd20c 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -931,7 +931,10 @@ void QComboBoxPrivate::init() QSizePolicy::ComboBox)); setLayoutItemMargins(QStyle::SE_ComboBoxLayoutItem); q->setModel(new QStandardItemModel(0, 1, q)); - q->setAttribute(Qt::WA_InputMethodEnabled); + if (!q->isEditable()) + q->setAttribute(Qt::WA_InputMethodEnabled, false); + else + q->setAttribute(Qt::WA_InputMethodEnabled); } QComboBoxPrivateContainer* QComboBoxPrivate::viewContainer() -- cgit v0.12 From 2c6749c38a2538639de86355856414b0d21317cf Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 14 Dec 2009 15:18:37 +0200 Subject: Fixed QGraphicsView benchmark for Symbian. - Added deployment of jpeg plugin - Reduced deep stacking recursion from 1000 -> 200 in order to not run out of stack. - Bunch of whitespace fixes. Task-number: QTBUG-6779 Reviewed-by: Janne Anttila --- tests/benchmarks/qgraphicsview/qgraphicsview.pro | 8 + .../benchmarks/qgraphicsview/tst_qgraphicsview.cpp | 238 +++++++++++---------- 2 files changed, 130 insertions(+), 116 deletions(-) diff --git a/tests/benchmarks/qgraphicsview/qgraphicsview.pro b/tests/benchmarks/qgraphicsview/qgraphicsview.pro index d9db8c9..927d731 100644 --- a/tests/benchmarks/qgraphicsview/qgraphicsview.pro +++ b/tests/benchmarks/qgraphicsview/qgraphicsview.pro @@ -6,3 +6,11 @@ SOURCES += tst_qgraphicsview.cpp RESOURCES += qgraphicsview.qrc include(chiptester/chiptester.pri) + +symbian { + qt_not_deployed { + plugins.sources = qjpeg.dll + plugins.path = imageformats + DEPLOYMENT += plugins + } +} diff --git a/tests/benchmarks/qgraphicsview/tst_qgraphicsview.cpp b/tests/benchmarks/qgraphicsview/tst_qgraphicsview.cpp index aadd56c..cf65e5d 100644 --- a/tests/benchmarks/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/benchmarks/qgraphicsview/tst_qgraphicsview.cpp @@ -62,25 +62,25 @@ class QEventWaiter : public QEventLoop { public: QEventWaiter(QObject *receiver, QEvent::Type type) - : waiting(false), t(type) + : waiting(false), t(type) { - receiver->installEventFilter(this); + receiver->installEventFilter(this); } void wait() { - waiting = true; - exec(); + waiting = true; + exec(); } bool eventFilter(QObject *receiver, QEvent *event) { - Q_UNUSED(receiver); - if (waiting && event->type() == t) { - waiting = false; - exit(); - } - return false; + Q_UNUSED(receiver); + if (waiting && event->type() == t) { + waiting = false; + exit(); + } + return false; } private: @@ -166,20 +166,26 @@ void tst_QGraphicsView::paintSingleItem() QImage image(100, 100, QImage::Format_ARGB32_Premultiplied); QPainter painter(&image); QBENCHMARK { - view.viewport()->render(&painter); + view.viewport()->render(&painter); } } +#ifdef Q_OS_SYMBIAN +# define DEEP_STACKING_COUNT 200 +#else +# define DEEP_STACKING_COUNT 1000 +#endif + void tst_QGraphicsView::paintDeepStackingItems() { QGraphicsScene scene(0, 0, 100, 100); QGraphicsRectItem *item = scene.addRect(0, 0, 10, 10); QGraphicsRectItem *lastRect = item; - for (int i = 0; i < 1000; ++i) { - QGraphicsRectItem *rect = scene.addRect(0, 0, 10, 10); - rect->setPos(1, 1); - rect->setParentItem(lastRect); - lastRect = rect; + for (int i = 0; i < DEEP_STACKING_COUNT; ++i) { + QGraphicsRectItem *rect = scene.addRect(0, 0, 10, 10); + rect->setPos(1, 1); + rect->setParentItem(lastRect); + lastRect = rect; } QGraphicsView view(&scene); @@ -192,7 +198,7 @@ void tst_QGraphicsView::paintDeepStackingItems() QImage image(100, 100, QImage::Format_ARGB32_Premultiplied); QPainter painter(&image); QBENCHMARK { - view.viewport()->render(&painter); + view.viewport()->render(&painter); } } @@ -202,11 +208,11 @@ void tst_QGraphicsView::paintDeepStackingItems_clipped() QGraphicsRectItem *item = scene.addRect(0, 0, 10, 10); item->setFlag(QGraphicsItem::ItemClipsChildrenToShape); QGraphicsRectItem *lastRect = item; - for (int i = 0; i < 1000; ++i) { - QGraphicsRectItem *rect = scene.addRect(0, 0, 10, 10); - rect->setPos(1, 1); - rect->setParentItem(lastRect); - lastRect = rect; + for (int i = 0; i < DEEP_STACKING_COUNT; ++i) { + QGraphicsRectItem *rect = scene.addRect(0, 0, 10, 10); + rect->setPos(1, 1); + rect->setParentItem(lastRect); + lastRect = rect; } QGraphicsView view(&scene); @@ -219,7 +225,7 @@ void tst_QGraphicsView::paintDeepStackingItems_clipped() QImage image(100, 100, QImage::Format_ARGB32_Premultiplied); QPainter painter(&image); QBENCHMARK { - view.viewport()->render(&painter); + view.viewport()->render(&painter); } } @@ -239,8 +245,8 @@ void tst_QGraphicsView::moveSingleItem() int n = 1; QBENCHMARK { item->setPos(25 * n, 25 * n); - waiter.wait(); - n = n ? 0 : 1; + waiter.wait(); + n = n ? 0 : 1; } } @@ -382,18 +388,18 @@ void tst_QGraphicsView::chipTester() tester.setOpenGL(opengl); tester.setOperation(ChipTester::Operation(operation)); QBENCHMARK { - tester.runBenchmark(); + tester.runBenchmark(); } } static void addChildHelper(QGraphicsItem *parent, int n, bool rotate) { if (!n) - return; + return; QGraphicsRectItem *item = new QGraphicsRectItem(QRectF(0, 0, 50, 50), parent); item->setPos(10, 10); if (rotate) - item->rotate(10); + item->rotate(10); addChildHelper(item, n - 1, rotate); } @@ -421,12 +427,12 @@ void tst_QGraphicsView::deepNesting() QGraphicsScene scene; for (int y = 0; y < 15; ++y) { - for (int x = 0; x < 15; ++x) { - QGraphicsItem *item1 = scene.addRect(QRectF(0, 0, 50, 50)); - if (rotate) item1->rotate(10); - item1->setPos(x * 25, y * 25); - addChildHelper(item1, 30, rotate); - } + for (int x = 0; x < 15; ++x) { + QGraphicsItem *item1 = scene.addRect(QRectF(0, 0, 50, 50)); + if (rotate) item1->rotate(10); + item1->setPos(x * 25, y * 25); + addChildHelper(item1, 30, rotate); + } } scene.setItemIndexMethod(bsp ? QGraphicsScene::BspTreeIndex : QGraphicsScene::NoIndex); scene.setSortCacheEnabled(sortCache); @@ -441,11 +447,11 @@ void tst_QGraphicsView::deepNesting() QBENCHMARK { #ifdef CALLGRIND_DEBUG - CALLGRIND_START_INSTRUMENTATION + CALLGRIND_START_INSTRUMENTATION #endif - view.viewport()->repaint(); + view.viewport()->repaint(); #ifdef CALLGRIND_DEBUG - CALLGRIND_STOP_INSTRUMENTATION + CALLGRIND_STOP_INSTRUMENTATION #endif } } @@ -456,36 +462,36 @@ public: AnimatedPixmapItem(int x, int y, bool rot, bool scal, QGraphicsItem *parent = 0) : QGraphicsPixmapItem(parent), rotateFactor(0), scaleFactor(0) { - rotate = rot; - scale = scal; - xspeed = x; - yspeed = y; + rotate = rot; + scale = scal; + xspeed = x; + yspeed = y; } protected: void advance(int i) - { - if (!i) - return; - int x = int(pos().x()) + pixmap().width(); - x += xspeed; - x = (x % (300 + pixmap().width() * 2)) - pixmap().width(); - int y = int(pos().y()) + pixmap().width(); - y += yspeed; - y = (y % (300 + pixmap().width() * 2)) - pixmap().width(); - setPos(x, y); - - int rot = rotateFactor; - int sca = scaleFactor; + { + if (!i) + return; + int x = int(pos().x()) + pixmap().width(); + x += xspeed; + x = (x % (300 + pixmap().width() * 2)) - pixmap().width(); + int y = int(pos().y()) + pixmap().width(); + y += yspeed; + y = (y % (300 + pixmap().width() * 2)) - pixmap().width(); + setPos(x, y); + + int rot = rotateFactor; + int sca = scaleFactor; if (rotate) - rotateFactor = 1 + (rot + xspeed) % 360; + rotateFactor = 1 + (rot + xspeed) % 360; if (scale) - scaleFactor = 1 + (sca + yspeed) % 50; + scaleFactor = 1 + (sca + yspeed) % 50; - if (rotate || scale) { - qreal s = 0.5 + scaleFactor / 50.0; - setTransform(QTransform().rotate(rotateFactor).scale(s, s)); - } + if (rotate || scale) { + qreal s = 0.5 + scaleFactor / 50.0; + setTransform(QTransform().rotate(rotateFactor).scale(s, s)); + } } private: @@ -543,38 +549,38 @@ void tst_QGraphicsView::imageRiver() view.show(); QPixmap pix(":/images/designer.png"); - QVERIFY(!pix.isNull()); + QVERIFY(!pix.isNull()); QList items; QFile file(":/random.data"); QVERIFY(file.open(QIODevice::ReadOnly)); QDataStream str(&file); for (int i = 0; i < 100; ++i) { - AnimatedPixmapItem *item; - if (direction == 0) item = new AnimatedPixmapItem((i % 4) + 1, 0, rotation, scale); - if (direction == 1) item = new AnimatedPixmapItem(0, (i % 4) + 1, rotation, scale); - if (direction == 2) item = new AnimatedPixmapItem((i % 4) + 1, (i % 4) + 1, rotation, scale); - item->setPixmap(pix); + AnimatedPixmapItem *item; + if (direction == 0) item = new AnimatedPixmapItem((i % 4) + 1, 0, rotation, scale); + if (direction == 1) item = new AnimatedPixmapItem(0, (i % 4) + 1, rotation, scale); + if (direction == 2) item = new AnimatedPixmapItem((i % 4) + 1, (i % 4) + 1, rotation, scale); + item->setPixmap(pix); int rnd1, rnd2; str >> rnd1 >> rnd2; - item->setPos(-pix.width() + rnd1 % (view.width() + pix.width()), - -pix.height() + rnd2 % (view.height() + pix.height())); - scene.addItem(item); + item->setPos(-pix.width() + rnd1 % (view.width() + pix.width()), + -pix.height() + rnd2 % (view.height() + pix.height())); + scene.addItem(item); } view.count = 0; QBENCHMARK { #ifdef CALLGRIND_DEBUG - CALLGRIND_START_INSTRUMENTATION + CALLGRIND_START_INSTRUMENTATION #endif - for (int i = 0; i < 100; ++i) { - scene.advance(); - while (view.count < (i+1)) - qApp->processEvents(); - } + for (int i = 0; i < 100; ++i) { + scene.advance(); + while (view.count < (i+1)) + qApp->processEvents(); + } #ifdef CALLGRIND_DEBUG - CALLGRIND_STOP_INSTRUMENTATION + CALLGRIND_STOP_INSTRUMENTATION #endif } } @@ -585,38 +591,38 @@ public: AnimatedTextItem(int x, int y, bool rot, bool scal, QGraphicsItem *parent = 0) : QGraphicsSimpleTextItem(parent), rotateFactor(0), scaleFactor(25) { - setText("River of text"); - rotate = rot; - scale = scal; - xspeed = x; - yspeed = y; + setText("River of text"); + rotate = rot; + scale = scal; + xspeed = x; + yspeed = y; } protected: void advance(int i) - { - if (!i) - return; - QRect r = boundingRect().toRect(); - int x = int(pos().x()) + r.width(); - x += xspeed; - x = (x % (300 + r.width() * 2)) - r.width(); - int y = int(pos().y()) + r.width(); - y += yspeed; - y = (y % (300 + r.width() * 2)) - r.width(); - setPos(x, y); - - int rot = rotateFactor; - int sca = scaleFactor; + { + if (!i) + return; + QRect r = boundingRect().toRect(); + int x = int(pos().x()) + r.width(); + x += xspeed; + x = (x % (300 + r.width() * 2)) - r.width(); + int y = int(pos().y()) + r.width(); + y += yspeed; + y = (y % (300 + r.width() * 2)) - r.width(); + setPos(x, y); + + int rot = rotateFactor; + int sca = scaleFactor; if (rotate) - rotateFactor = 1 + (rot + xspeed) % 360; + rotateFactor = 1 + (rot + xspeed) % 360; if (scale) - scaleFactor = 1 + (sca + yspeed) % 50; + scaleFactor = 1 + (sca + yspeed) % 50; - if (rotate || scale) { - qreal s = 0.5 + scaleFactor / 50.0; - setTransform(QTransform().rotate(rotateFactor).scale(s, s)); - } + if (rotate || scale) { + qreal s = 0.5 + scaleFactor / 50.0; + setTransform(QTransform().rotate(rotateFactor).scale(s, s)); + } } private: @@ -657,37 +663,37 @@ void tst_QGraphicsView::textRiver() view.show(); QPixmap pix(":/images/designer.png"); - QVERIFY(!pix.isNull()); + QVERIFY(!pix.isNull()); QList items; QFile file(":/random.data"); QVERIFY(file.open(QIODevice::ReadOnly)); QDataStream str(&file); for (int i = 0; i < 100; ++i) { - AnimatedTextItem *item; - if (direction == 0) item = new AnimatedTextItem((i % 4) + 1, 0, rotation, scale); - if (direction == 1) item = new AnimatedTextItem(0, (i % 4) + 1, rotation, scale); - if (direction == 2) item = new AnimatedTextItem((i % 4) + 1, (i % 4) + 1, rotation, scale); + AnimatedTextItem *item; + if (direction == 0) item = new AnimatedTextItem((i % 4) + 1, 0, rotation, scale); + if (direction == 1) item = new AnimatedTextItem(0, (i % 4) + 1, rotation, scale); + if (direction == 2) item = new AnimatedTextItem((i % 4) + 1, (i % 4) + 1, rotation, scale); int rnd1, rnd2; str >> rnd1 >> rnd2; - item->setPos(-pix.width() + rnd1 % (view.width() + pix.width()), - -pix.height() + rnd2 % (view.height() + pix.height())); - scene.addItem(item); + item->setPos(-pix.width() + rnd1 % (view.width() + pix.width()), + -pix.height() + rnd2 % (view.height() + pix.height())); + scene.addItem(item); } view.count = 0; QBENCHMARK { #ifdef CALLGRIND_DEBUG - CALLGRIND_START_INSTRUMENTATION + CALLGRIND_START_INSTRUMENTATION #endif - for (int i = 0; i < 100; ++i) { - scene.advance(); - while (view.count < (i+1)) - qApp->processEvents(); - } + for (int i = 0; i < 100; ++i) { + scene.advance(); + while (view.count < (i+1)) + qApp->processEvents(); + } #ifdef CALLGRIND_DEBUG - CALLGRIND_STOP_INSTRUMENTATION + CALLGRIND_STOP_INSTRUMENTATION #endif } } -- cgit v0.12 From 693ad0f9ca5ee424dc1e3c7aca88adb4915f5cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 7 Dec 2009 14:29:25 +0100 Subject: Improved raster blur implementation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We use more bits of precision in the fixed point exponential blur algorithm, which allows more fine-grained radii which is required for animating the blur. Also optimize the implementation a bit by transposing the image instead of blurring vertically which isn't very cache-efficient. Reviewed-by: Bjørn Erik Nilsen --- src/gui/image/qpixmapfilter.cpp | 358 +++++++++++++++++++++++++++++++++------- 1 file changed, 299 insertions(+), 59 deletions(-) diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp index 3723500..6289efe 100644 --- a/src/gui/image/qpixmapfilter.cpp +++ b/src/gui/image/qpixmapfilter.cpp @@ -52,6 +52,10 @@ #include "private/qgraphicssystem_p.h" #include "private/qpaintengineex_p.h" #include "private/qpaintengine_raster_p.h" +#include "qmath.h" +#include "private/qmath_p.h" +#include "private/qmemrotate_p.h" +#include "private/qdrawhelper_p.h" #ifndef QT_NO_GRAPHICSEFFECT QT_BEGIN_NAMESPACE @@ -585,97 +589,327 @@ QGraphicsBlurEffect::BlurHints QPixmapBlurFilter::blurHints() const return d->hints; } +const qreal radiusScale = qreal(2.5); + /*! \internal */ QRectF QPixmapBlurFilter::boundingRectFor(const QRectF &rect) const { Q_D(const QPixmapBlurFilter); - const qreal delta = d->radius + 1; + const qreal delta = radiusScale * d->radius + 1; return rect.adjusted(-delta, -delta, delta, delta); } // Blur the image according to the blur radius // Based on exponential blur algorithm by Jani Huhtanen -// (maximum radius is set to 16) -static QImage blurred(const QImage& image, const QRect& rect, int radius, bool alphaOnly = false) + +template +static inline void blurrow( QImage & im, int line, int alpha); + +/* +* expblur(QImage &img, int radius) +* +* In-place blur of image 'img' with kernel +* of approximate radius 'radius'. +* +* Blurs with two sided exponential impulse +* response. +* +* aprec = precision of alpha parameter +* in fixed-point format 0.aprec +* +* zprec = precision of state parameters +* zR,zG,zB and zA in fp format 8.zprec +*/ +template +void expblur(QImage &img, qreal radius, bool improvedQuality = false, int transposed = 0) { - int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 }; - int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius-1]; + // halve the radius if we're using two passes + if (improvedQuality) + radius *= 0.5; + + Q_ASSERT(img.format() == QImage::Format_ARGB32_Premultiplied + || img.format() == QImage::Format_RGB32); + + // choose the alpha such that pixels at radius distance from a fully + // saturated pixel will have an alpha component of no greater than + // the cutOffIntensity + const qreal cutOffIntensity = 2; + int alpha = radius <= qreal(1e-5) + ? ((1 << aprec)-1) + : qRound((1<(img, row, alpha); + } - QImage result = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); - int r1 = rect.top(); - int r2 = rect.bottom(); - int c1 = rect.left(); - int c2 = rect.right(); + QImage temp(img.height(), img.width(), img.format()); + if (transposed >= 0) { + if (img.depth() == 8) { + qt_memrotate270(reinterpret_cast(img.bits()), + img.width(), img.height(), img.bytesPerLine(), + reinterpret_cast(temp.bits()), + temp.bytesPerLine()); + } else { + qt_memrotate270(reinterpret_cast(img.bits()), + img.width(), img.height(), img.bytesPerLine(), + reinterpret_cast(temp.bits()), + temp.bytesPerLine()); + } + } else { + if (img.depth() == 8) { + qt_memrotate90(reinterpret_cast(img.bits()), + img.width(), img.height(), img.bytesPerLine(), + reinterpret_cast(temp.bits()), + temp.bytesPerLine()); + } else { + qt_memrotate90(reinterpret_cast(img.bits()), + img.width(), img.height(), img.bytesPerLine(), + reinterpret_cast(temp.bits()), + temp.bytesPerLine()); + } + } - int bpl = result.bytesPerLine(); - int rgba[4]; - unsigned char* p; + img_height = temp.height(); + for (int row = 0; row < img_height; ++row) { + for (int i = 0; i <= improvedQuality; ++i) + blurrow(temp, row, alpha); + } - int i1 = 0; - int i2 = 3; + if (transposed == 0) { + qt_memrotate90(reinterpret_cast(temp.bits()), + temp.width(), temp.height(), temp.bytesPerLine(), + reinterpret_cast(img.bits()), + img.bytesPerLine()); + } else { + img = temp; + } +} - if (alphaOnly) - i1 = i2 = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3); +template +static inline int static_shift(int value) +{ + if (shift == 0) + return value; + else if (shift > 0) + return value << (uint(shift) & 0x1f); + else + return value >> (uint(-shift) & 0x1f); +} + +template +static inline void blurinner(uchar *bptr, int &zR, int &zG, int &zB, int &zA, int alpha) +{ + QRgb *pixel = (QRgb *)bptr; + +#define Z_MASK (0xff << zprec) + const int A_zprec = static_shift(*pixel) & Z_MASK; + const int R_zprec = static_shift(*pixel) & Z_MASK; + const int G_zprec = static_shift(*pixel) & Z_MASK; + const int B_zprec = static_shift(*pixel) & Z_MASK; +#undef Z_MASK + + const int zR_zprec = zR >> aprec; + const int zG_zprec = zG >> aprec; + const int zB_zprec = zB >> aprec; + const int zA_zprec = zA >> aprec; + + zR += alpha * (R_zprec - zR_zprec); + zG += alpha * (G_zprec - zG_zprec); + zB += alpha * (B_zprec - zB_zprec); + zA += alpha * (A_zprec - zA_zprec); + +#define ZA_MASK (0xff << (zprec + aprec)) + *pixel = + static_shift<24 - zprec - aprec>(zA & ZA_MASK) + | static_shift<16 - zprec - aprec>(zR & ZA_MASK) + | static_shift<8 - zprec - aprec>(zG & ZA_MASK) + | static_shift<-zprec - aprec>(zB & ZA_MASK); +#undef ZA_MASK +} + +const int alphaIndex = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3); + +template +static inline void blurinner_alphaOnly(uchar *bptr, int &z, int alpha) +{ + const int A_zprec = int(*(bptr)) << zprec; + const int z_zprec = z >> aprec; + z += alpha * (A_zprec - z_zprec); + *(bptr) = z >> (zprec + aprec); +} + +template +static inline void blurrow(QImage & im, int line, int alpha) +{ + uchar *bptr = im.scanLine(line); + + int zR = 0, zG = 0, zB = 0, zA = 0; - for (int col = c1; col <= c2; col++) { - p = result.scanLine(r1) + col * 4; - for (int i = i1; i <= i2; i++) - rgba[i] = p[i] << 4; + if (alphaOnly && im.format() != QImage::Format_Indexed8) + bptr += alphaIndex; - p += bpl; - for (int j = r1; j < r2; j++, p += bpl) - for (int i = i1; i <= i2; i++) - p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4; + const int stride = im.depth() >> 3; + const int im_width = im.width(); + for (int index = 0; index < im_width; ++index) { + if (alphaOnly) + blurinner_alphaOnly(bptr, zA, alpha); + else + blurinner(bptr, zR, zG, zB, zA, alpha); + bptr += stride; } - for (int row = r1; row <= r2; row++) { - p = result.scanLine(row) + c1 * 4; - for (int i = i1; i <= i2; i++) - rgba[i] = p[i] << 4; + bptr -= stride; - p += 4; - for (int j = c1; j < c2; j++, p += 4) - for (int i = i1; i <= i2; i++) - p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4; + for (int index = im_width - 2; index >= 0; --index) { + bptr -= stride; + if (alphaOnly) + blurinner_alphaOnly(bptr, zA, alpha); + else + blurinner(bptr, zR, zG, zB, zA, alpha); } +} + +#define AVG(a,b) ( ((((a)^(b)) & 0xfefefefeUL) >> 1) + ((a)&(b)) ) +#define AVG16(a,b) ( ((((a)^(b)) & 0xf7deUL) >> 1) + ((a)&(b)) ) - for (int col = c1; col <= c2; col++) { - p = result.scanLine(r2) + col * 4; - for (int i = i1; i <= i2; i++) - rgba[i] = p[i] << 4; +Q_GUI_EXPORT QImage qt_halfScaled(const QImage &source) +{ + QImage srcImage = source; + + if (source.format() == QImage::Format_Indexed8) { + // assumes grayscale + QImage dest(source.width() / 2, source.height() / 2, srcImage.format()); + + const uchar *src = reinterpret_cast(const_cast(srcImage).bits()); + int sx = srcImage.bytesPerLine(); + int sx2 = sx << 1; + + uchar *dst = reinterpret_cast(dest.bits()); + int dx = dest.bytesPerLine(); + int ww = dest.width(); + int hh = dest.height(); + + for (int y = hh; y; --y, dst += dx, src += sx2) { + const uchar *p1 = src; + const uchar *p2 = src + sx; + uchar *q = dst; + for (int x = ww; x; --x, ++q, p1 += 2, p2 += 2) + *q = ((int(p1[0]) + int(p1[1]) + int(p2[0]) + int(p2[1])) + 2) >> 2; + } + + return dest; + } else if (source.format() == QImage::Format_ARGB8565_Premultiplied) { + QImage dest(source.width() / 2, source.height() / 2, srcImage.format()); + + const uchar *src = reinterpret_cast(const_cast(srcImage).bits()); + int sx = srcImage.bytesPerLine(); + int sx2 = sx << 1; + + uchar *dst = reinterpret_cast(dest.bits()); + int dx = dest.bytesPerLine(); + int ww = dest.width(); + int hh = dest.height(); + + for (int y = hh; y; --y, dst += dx, src += sx2) { + const uchar *p1 = src; + const uchar *p2 = src + sx; + uchar *q = dst; + for (int x = ww; x; --x, q += 3, p1 += 6, p2 += 6) { + // alpha + q[0] = AVG(AVG(p1[0], p1[3]), AVG(p2[0], p2[3])); + // rgb + const quint16 p16_1 = (p1[2] << 8) | p1[1]; + const quint16 p16_2 = (p1[5] << 8) | p1[4]; + const quint16 p16_3 = (p2[2] << 8) | p2[1]; + const quint16 p16_4 = (p2[5] << 8) | p2[4]; + const quint16 result = AVG16(AVG16(p16_1, p16_2), AVG16(p16_3, p16_4)); + q[1] = result & 0xff; + q[2] = result >> 8; + } + } - p -= bpl; - for (int j = r1; j < r2; j++, p -= bpl) - for (int i = i1; i <= i2; i++) - p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4; + return dest; + } else if (source.format() != QImage::Format_ARGB32_Premultiplied + && source.format() != QImage::Format_RGB32) + { + srcImage = source.convertToFormat(QImage::Format_ARGB32_Premultiplied); } - for (int row = r1; row <= r2; row++) { - p = result.scanLine(row) + c2 * 4; - for (int i = i1; i <= i2; i++) - rgba[i] = p[i] << 4; + QImage dest(source.width() / 2, source.height() / 2, srcImage.format()); + + const quint32 *src = reinterpret_cast(const_cast(srcImage).bits()); + int sx = srcImage.bytesPerLine() >> 2; + int sx2 = sx << 1; - p -= 4; - for (int j = c1; j < c2; j++, p -= 4) - for (int i = i1; i <= i2; i++) - p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4; + quint32 *dst = reinterpret_cast(dest.bits()); + int dx = dest.bytesPerLine() >> 2; + int ww = dest.width(); + int hh = dest.height(); + + for (int y = hh; y; --y, dst += dx, src += sx2) { + const quint32 *p1 = src; + const quint32 *p2 = src + sx; + quint32 *q = dst; + for (int x = ww; x; --x, q++, p1 += 2, p2 += 2) + *q = AVG(AVG(p1[0], p1[1]), AVG(p2[0], p2[1])); } - return result; + return dest; +} + +Q_GUI_EXPORT void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0) +{ + if (blurImage.format() != QImage::Format_ARGB32_Premultiplied + && blurImage.format() != QImage::Format_RGB32) + { + blurImage = blurImage.convertToFormat(QImage::Format_ARGB32_Premultiplied); + } + + qreal scale = 1; + if (radius >= 4) { + blurImage = qt_halfScaled(blurImage); + scale = 2; + radius *= 0.5; + } + + if (alphaOnly) + expblur<12, 10, true>(blurImage, radius, quality, transposed); + else + expblur<12, 10, false>(blurImage, radius, quality, transposed); + + if (p) { + p->scale(scale, scale); + p->setRenderHint(QPainter::SmoothPixmapTransform); + p->drawImage(QRect(0, 0, blurImage.width(), blurImage.height()), blurImage); + } +} + +Q_GUI_EXPORT void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0) +{ + if (blurImage.format() == QImage::Format_Indexed8) + expblur<12, 10, true>(blurImage, radius, quality, transposed); + else + expblur<12, 10, false>(blurImage, radius, quality, transposed); } /*! \internal */ -void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF &srcRect) const +void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF &rect) const { Q_D(const QPixmapBlurFilter); if (!painter->isActive()) return; - if (d->radius <= 0) { + QRectF srcRect = rect; + if (srcRect.isNull()) + srcRect = src.rect(); + + if (d->radius <= 1) { painter->drawPixmap(srcRect.translated(p), src, srcRect); return; } @@ -684,7 +918,7 @@ void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap static_cast(painter->paintEngine())->pixmapFilter(type(), this) : 0; QPixmapBlurFilter *blurFilter = static_cast(filter); if (blurFilter) { - blurFilter->setRadius(d->radius); + blurFilter->setRadius(radiusScale * d->radius); blurFilter->setBlurHints(d->hints); blurFilter->draw(painter, p, src, srcRect); return; @@ -693,17 +927,17 @@ void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap QImage srcImage; QImage destImage; - if (srcRect.isNull()) { + if (srcRect == src.rect()) { srcImage = src.toImage(); - destImage = blurred(srcImage, srcImage.rect(), qRound(d->radius)); } else { QRect rect = srcRect.toAlignedRect().intersected(src.rect()); - srcImage = src.copy(rect).toImage(); - destImage = blurred(srcImage, srcImage.rect(), qRound(d->radius)); } - painter->drawImage(p, destImage); + QTransform transform = painter->worldTransform(); + painter->translate(p); + qt_blurImage(painter, srcImage, radiusScale * d->radius, (d->hints & QGraphicsBlurEffect::QualityHint), false); + painter->setWorldTransform(transform); } // grayscales the image to dest (could be same). If rect isn't defined @@ -1095,7 +1329,13 @@ void QPixmapDropShadowFilter::draw(QPainter *p, tmpPainter.end(); // blur the alpha channel - tmp = blurred(tmp, tmp.rect(), qRound(d->radius), true); + QImage blurred(tmp.size(), QImage::Format_ARGB32_Premultiplied); + blurred.fill(0); + QPainter blurPainter(&blurred); + qt_blurImage(&blurPainter, tmp, d->radius, false, true); + blurPainter.end(); + + tmp = blurred; // blacken the image... tmpPainter.begin(&tmp); -- cgit v0.12 From be525c78c8ac44e7c188a45a4e04a1d80ad9ba51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 7 Dec 2009 10:06:12 +0100 Subject: Optimize QGraphicsItemEffectSourcePrivate::pixmap() for QGraphicsPixmapItems. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even for DeviceCoordinate mode we can return the raw pixmap if the graphics item size is untransformed. Reviewed-by: Bjørn Erik Nilsen --- src/gui/graphicsview/qgraphicsitem.cpp | 18 ++++---- tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp | 49 ++++++++++++++++++++++ 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index d955f16..b6820f7 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -10717,7 +10717,6 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context"); return QPixmap(); } - if (!item->d_ptr->scene) return QPixmap(); QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func(); @@ -10725,9 +10724,11 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP const QRectF sourceRect = boundingRect(system); QRectF effectRectF; + bool unpadded = false; if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) { if (info) { effectRectF = item->graphicsEffect()->boundingRectFor(boundingRect(Qt::DeviceCoordinates)); + unpadded = (effectRectF.size() == sourceRect.size()); if (info && system == Qt::LogicalCoordinates) effectRectF = info->painter->worldTransform().inverted().mapRect(effectRectF); } else { @@ -10739,6 +10740,7 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP effectRectF = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5); } else { effectRectF = sourceRect; + unpadded = true; } QRect effectRect = effectRectF.toAlignedRect(); @@ -10746,6 +10748,14 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP if (offset) *offset = effectRect.topLeft(); + bool untransformed = !deviceCoordinates + || info->painter->worldTransform().type() <= QTransform::TxTranslate; + if (untransformed && unpadded && isPixmap()) { + if (offset) + *offset = boundingRect(system).topLeft().toPoint(); + return static_cast(item)->pixmap(); + } + if (deviceCoordinates) { // Clip to viewport rect. int left, top, right, bottom; @@ -10773,12 +10783,6 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP if (effectRect.isEmpty()) return QPixmap(); - if (system == Qt::LogicalCoordinates - && effectRect.size() == sourceRect.size() - && isPixmap()) { - return static_cast(item)->pixmap(); - } - QPixmap pixmap(effectRect.size()); pixmap.fill(Qt::transparent); QPainter pixmapPainter(&pixmap); diff --git a/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp b/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp index 259df4d..69fc118 100644 --- a/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp +++ b/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp @@ -69,6 +69,7 @@ private slots: void opacity(); void grayscale(); void colorize(); + void drawPixmapItem(); }; void tst_QGraphicsEffect::initTestCase() @@ -465,6 +466,54 @@ void tst_QGraphicsEffect::colorize() QCOMPARE(image.pixel(10, 10), qRgb(122, 193, 66)); } +class PixmapItemEffect : public QGraphicsEffect +{ +public: + PixmapItemEffect(const QPixmap &source) + : QGraphicsEffect() + , pixmap(source) + , repaints(0) + {} + + QRectF boundingRectFor(const QRectF &rect) const + { return rect; } + + void draw(QPainter *painter) + { + QVERIFY(sourcePixmap(Qt::LogicalCoordinates).pixmapData() == pixmap.pixmapData()); + QVERIFY((painter->worldTransform().type() <= QTransform::TxTranslate) == (sourcePixmap(Qt::DeviceCoordinates).pixmapData() == pixmap.pixmapData())); + + ++repaints; + } + QPixmap pixmap; + int repaints; +}; + +void tst_QGraphicsEffect::drawPixmapItem() +{ + QImage image(32, 32, QImage::Format_RGB32); + QPainter p(&image); + p.fillRect(0, 0, 32, 16, Qt::blue); + p.fillRect(0, 16, 32, 16, Qt::red); + p.end(); + + QGraphicsScene scene; + QGraphicsPixmapItem *item = new QGraphicsPixmapItem(QPixmap::fromImage(image)); + scene.addItem(item); + + PixmapItemEffect *effect = new PixmapItemEffect(item->pixmap()); + item->setGraphicsEffect(effect); + + QGraphicsView view(&scene); + view.show(); + QTest::qWaitForWindowShown(&view); + + item->rotate(180); + QTest::qWait(50); + + QTRY_VERIFY(effect->repaints >= 2); +} + QTEST_MAIN(tst_QGraphicsEffect) #include "tst_qgraphicseffect.moc" -- cgit v0.12 From 8bbb0e70d189d7027494004a8dece8aeb4e37366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 11 Dec 2009 12:21:49 +0100 Subject: Fixed bug in QGraphicsPixmapItem shortcut for graphics effects. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to take the pixmap item's drawing offset into consideration. Reviewed-by: Bjørn Erik Nilsen --- src/gui/effects/qgraphicseffect.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp index d6cabaa..4f7ffc8 100644 --- a/src/gui/effects/qgraphicseffect.cpp +++ b/src/gui/effects/qgraphicseffect.cpp @@ -313,7 +313,10 @@ QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offse // Shortcut, no cache for childless pixmap items... const QGraphicsItem *item = graphicsItem(); if (system == Qt::LogicalCoordinates && mode == QGraphicsEffect::NoPad && item && isPixmap()) { - return ((QGraphicsPixmapItem *) item)->pixmap(); + const QGraphicsPixmapItem *pixmapItem = static_cast(item); + if (offset) + *offset = pixmapItem->offset().toPoint(); + return pixmapItem->pixmap(); } if (system == Qt::DeviceCoordinates && item -- cgit v0.12 From 21c31b4a3ae972a4c2f03adebd43a2d6a27f8c93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 11 Dec 2009 12:24:23 +0100 Subject: Added InvalidateReason to invalidateCache to optimize effects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This lets us ignore the invalidateCache call when the transform of a graphics item with an effect changes, and the cached system is LogicalCoordinates and cached mode is not PadToEffectiveBoundingRect. Reviewed-by: Bjørn Erik Nilsen --- src/gui/effects/qgraphicseffect.cpp | 10 +++++++--- src/gui/effects/qgraphicseffect_p.h | 11 ++++++++++- src/gui/graphicsview/qgraphicsscene.cpp | 7 +++++-- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp index 4f7ffc8..dafea52 100644 --- a/src/gui/effects/qgraphicseffect.cpp +++ b/src/gui/effects/qgraphicseffect.cpp @@ -374,10 +374,14 @@ QGraphicsEffectSourcePrivate::~QGraphicsEffectSourcePrivate() invalidateCache(); } -void QGraphicsEffectSourcePrivate::invalidateCache(bool effectRectChanged) const +void QGraphicsEffectSourcePrivate::invalidateCache(InvalidateReason reason) const { - if (effectRectChanged && m_cachedMode != QGraphicsEffect::PadToEffectiveBoundingRect) + if (m_cachedMode != QGraphicsEffect::PadToEffectiveBoundingRect + && (reason == EffectRectChanged + || reason == TransformChanged + && m_cachedSystem == Qt::LogicalCoordinates)) return; + QPixmapCache::remove(m_cacheKey); } @@ -523,7 +527,7 @@ void QGraphicsEffect::updateBoundingRect() Q_D(QGraphicsEffect); if (d->source) { d->source->d_func()->effectBoundingRectChanged(); - d->source->d_func()->invalidateCache(true); + d->source->d_func()->invalidateCache(QGraphicsEffectSourcePrivate::EffectRectChanged); } } diff --git a/src/gui/effects/qgraphicseffect_p.h b/src/gui/effects/qgraphicseffect_p.h index 0011eef..cab7a48 100644 --- a/src/gui/effects/qgraphicseffect_p.h +++ b/src/gui/effects/qgraphicseffect_p.h @@ -108,6 +108,13 @@ public: , m_cachedMode(QGraphicsEffect::PadToTransparentBorder) {} + enum InvalidateReason + { + TransformChanged, + EffectRectChanged, + SourceChanged + }; + virtual ~QGraphicsEffectSourcePrivate(); virtual void detach() = 0; virtual QRectF boundingRect(Qt::CoordinateSystem system) const = 0; @@ -121,7 +128,9 @@ public: virtual QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset = 0, QGraphicsEffect::PixmapPadMode mode = QGraphicsEffect::PadToTransparentBorder) const = 0; virtual void effectBoundingRectChanged() = 0; - void invalidateCache(bool effectRectChanged = false) const; + + void invalidateCache(InvalidateReason reason = SourceChanged) const; + Qt::CoordinateSystem currentCachedSystem() const { return m_cachedSystem; } friend class QGraphicsScenePrivate; friend class QGraphicsItem; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 2af90b8..ff3c1bb 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4658,10 +4658,13 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * painter->setWorldTransform(*transformPtr); painter->setOpacity(opacity); - if (sourced->lastEffectTransform != painter->worldTransform()) { + if (sourced->currentCachedSystem() != Qt::LogicalCoordinates + && sourced->lastEffectTransform != painter->worldTransform()) + { sourced->lastEffectTransform = painter->worldTransform(); - sourced->invalidateCache(); + sourced->invalidateCache(QGraphicsEffectSourcePrivate::TransformChanged); } + item->d_ptr->graphicsEffect->draw(painter); painter->setWorldTransform(restoreTransform); sourced->info = 0; -- cgit v0.12 From b543f356ca9f4a1db72e937968f06804df7c17bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 11 Dec 2009 12:28:58 +0100 Subject: Fixed bug in graphics effects caching of graphics item hierarchies. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure to invalidate the cache if the transform of a sub-item changes. Reviewed-by: Bjørn Erik Nilsen --- src/gui/graphicsview/qgraphicsitem.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index b6820f7..fbfd8e6 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -7177,9 +7177,16 @@ void QGraphicsItem::prepareGeometryChange() QGraphicsItem *parent = this; while ((parent = parent->d_ptr->parent)) { - parent->d_ptr->dirtyChildrenBoundingRect = 1; + QGraphicsItemPrivate *parentp = parent->d_ptr.data(); + parentp->dirtyChildrenBoundingRect = 1; // ### Only do this if the parent's effect applies to the entire subtree. - parent->d_ptr->notifyBoundingRectChanged = 1; + parentp->notifyBoundingRectChanged = 1; +#ifndef QT_NO_GRAPHICSEFFECT + if (parentp->scene && parentp->graphicsEffect) { + parentp->notifyInvalidated = 1; + static_cast(parentp->graphicsEffect->d_func()->source->d_func())->invalidateCache(); + } +#endif } } -- cgit v0.12 From 9c4a79038fcd2c2a90a277db81aaadac50eaa59a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 7 Dec 2009 10:03:42 +0100 Subject: Optimized blur / drop shadow effects for the GL 2 paint engine. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do the blur in half the resolution in software and then upload the result as a texture and smooth-scale it on the GPU. This leads to stable and decent performance regardless of the blur radius, and simplifies the implementation quite a bit. Reviewed-by: Bjørn Erik Nilsen --- src/gui/effects/qgraphicseffect.cpp | 11 +- src/gui/image/qpixmapfilter.cpp | 17 +- src/gui/painting/qmemrotate.cpp | 21 + src/gui/painting/qmemrotate_p.h | 2 + .../gl2paintengineex/qglcustomshaderstage_p.h | 2 +- .../gl2paintengineex/qpaintengineex_opengl2_p.h | 3 - src/opengl/qgl.cpp | 41 +- src/opengl/qglpixmapfilter.cpp | 754 +++++---------------- 8 files changed, 237 insertions(+), 614 deletions(-) diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp index dafea52..a523bab 100644 --- a/src/gui/effects/qgraphicseffect.cpp +++ b/src/gui/effects/qgraphicseffect.cpp @@ -844,22 +844,19 @@ QRectF QGraphicsBlurEffect::boundingRectFor(const QRectF &rect) const void QGraphicsBlurEffect::draw(QPainter *painter) { Q_D(QGraphicsBlurEffect); - if (d->filter->radius() <= 0) { + if (d->filter->radius() < 1) { drawSource(painter); return; } PixmapPadMode mode = PadToEffectiveBoundingRect; if (painter->paintEngine()->type() == QPaintEngine::OpenGL2) - mode = PadToTransparentBorder; + mode = NoPad; // Draw pixmap in device coordinates to avoid pixmap scaling. QPoint offset; - const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, mode); - QTransform restoreTransform = painter->worldTransform(); - painter->setWorldTransform(QTransform()); + QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset, mode); d->filter->draw(painter, offset, pixmap); - painter->setWorldTransform(restoreTransform); } /*! @@ -1040,7 +1037,7 @@ void QGraphicsDropShadowEffect::draw(QPainter *painter) PixmapPadMode mode = PadToEffectiveBoundingRect; if (painter->paintEngine()->type() == QPaintEngine::OpenGL2) - mode = PadToTransparentBorder; + mode = NoPad; // Draw pixmap in device coordinates to avoid pixmap scaling. QPoint offset; diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp index 6289efe..9c7c28e 100644 --- a/src/gui/image/qpixmapfilter.cpp +++ b/src/gui/image/qpixmapfilter.cpp @@ -627,7 +627,7 @@ void expblur(QImage &img, qreal radius, bool improvedQuality = false, int transp { // halve the radius if we're using two passes if (improvedQuality) - radius *= 0.5; + radius *= qreal(0.5); Q_ASSERT(img.format() == QImage::Format_ARGB32_Premultiplied || img.format() == QImage::Format_RGB32); @@ -638,7 +638,7 @@ void expblur(QImage &img, qreal radius, bool improvedQuality = false, int transp const qreal cutOffIntensity = 2; int alpha = radius <= qreal(1e-5) ? ((1 << aprec)-1) - : qRound((1<= 4) { blurImage = qt_halfScaled(blurImage); scale = 2; - radius *= 0.5; + radius *= qreal(0.5); } if (alphaOnly) @@ -896,6 +896,8 @@ Q_GUI_EXPORT void qt_blurImage(QImage &blurImage, qreal radius, bool quality, in expblur<12, 10, false>(blurImage, radius, quality, transposed); } +bool qt_scaleForTransform(const QTransform &transform, qreal *scale); + /*! \internal */ @@ -914,11 +916,16 @@ void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap return; } + qreal scaledRadius = radiusScale * d->radius; + qreal scale; + if (qt_scaleForTransform(painter->transform(), &scale)) + scaledRadius /= scale; + QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ? static_cast(painter->paintEngine())->pixmapFilter(type(), this) : 0; QPixmapBlurFilter *blurFilter = static_cast(filter); if (blurFilter) { - blurFilter->setRadius(radiusScale * d->radius); + blurFilter->setRadius(scaledRadius); blurFilter->setBlurHints(d->hints); blurFilter->draw(painter, p, src, srcRect); return; @@ -936,7 +943,7 @@ void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap QTransform transform = painter->worldTransform(); painter->translate(p); - qt_blurImage(painter, srcImage, radiusScale * d->radius, (d->hints & QGraphicsBlurEffect::QualityHint), false); + qt_blurImage(painter, srcImage, scaledRadius, (d->hints & QGraphicsBlurEffect::QualityHint), false); painter->setWorldTransform(transform); } diff --git a/src/gui/painting/qmemrotate.cpp b/src/gui/painting/qmemrotate.cpp index 67dc2c7..e3a6f78 100644 --- a/src/gui/painting/qmemrotate.cpp +++ b/src/gui/painting/qmemrotate.cpp @@ -572,5 +572,26 @@ QT_IMPL_MEMROTATE(quint32, qrgb_generic16) QT_IMPL_MEMROTATE(quint16, qrgb_generic16) #endif +struct qrgb_gl_rgba +{ +public: + inline qrgb_gl_rgba(quint32 v) { + if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) + data = ((v << 16) & 0xff0000) | ((v >> 16) & 0xff) | (v & 0xff00ff00); + else + data = (v << 8) | ((v >> 24) & 0xff); + } + + inline operator quint32() const { return data; } + +private: + quint32 data; +} Q_PACKED; + +void Q_GUI_EXPORT qt_memrotate90_gl(const quint32 *src, int srcWidth, int srcHeight, int srcStride, + quint32 *dest, int dstStride) +{ + qt_memrotate90_template(src, srcWidth, srcHeight, srcStride, reinterpret_cast(dest), dstStride); +} QT_END_NAMESPACE diff --git a/src/gui/painting/qmemrotate_p.h b/src/gui/painting/qmemrotate_p.h index 676a880..8aee575 100644 --- a/src/gui/painting/qmemrotate_p.h +++ b/src/gui/painting/qmemrotate_p.h @@ -81,6 +81,8 @@ QT_BEGIN_NAMESPACE void Q_GUI_QWS_EXPORT qt_memrotate180(const srctype*, int, int, int, desttype*, int); \ void Q_GUI_QWS_EXPORT qt_memrotate270(const srctype*, int, int, int, desttype*, int) +void Q_GUI_EXPORT qt_memrotate90(const quint32*, int, int, int, quint32*, int); + QT_DECL_MEMROTATE(quint32, quint32); QT_DECL_MEMROTATE(quint32, quint16); QT_DECL_MEMROTATE(quint16, quint32); diff --git a/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h b/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h index e319389..e0033be 100644 --- a/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h +++ b/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h @@ -68,7 +68,7 @@ class Q_OPENGL_EXPORT QGLCustomShaderStage public: QGLCustomShaderStage(); virtual ~QGLCustomShaderStage(); - virtual void setUniforms(QGLShaderProgram*) = 0; + virtual void setUniforms(QGLShaderProgram*) {} void setUniformsDirty(); diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 0084476..77ca3a8 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -291,10 +291,7 @@ public: QScopedPointer convolutionFilter; QScopedPointer colorizeFilter; QScopedPointer blurFilter; - QScopedPointer animationBlurFilter; - QScopedPointer fastBlurFilter; QScopedPointer dropShadowFilter; - QScopedPointer fastDropShadowFilter; QSet pathCaches; QVector unusedVBOSToClean; diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index b6f8919..2a3ce54 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2063,6 +2063,29 @@ QGLTexture *QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G // #define QGL_BIND_TEXTURE_DEBUG +// map from Qt's ARGB endianness-dependent format to GL's big-endian RGBA layout +static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type) +{ + const int width = img.width(); + const int height = img.height(); + + if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV + || (pixel_type == GL_UNSIGNED_BYTE && QSysInfo::ByteOrder == QSysInfo::LittleEndian)) + { + for (int i = 0; i < height; ++i) { + uint *p = (uint *) img.scanLine(i); + for (int x = 0; x < width; ++x) + p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00); + } + } else { + for (int i = 0; i < height; ++i) { + uint *p = (uint *) img.scanLine(i); + for (int x = 0; x < width; ++x) + p[x] = (p[x] << 8) | ((p[x] >> 24) & 0xff); + } + } +} + QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint internalFormat, const qint64 key, QGLContext::BindOptions options) { @@ -2215,23 +2238,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G // 32 in the switch above is for the RGB16 case, where we set // the format to GL_RGB Q_ASSERT(img.depth() == 32); - const int width = img.width(); - const int height = img.height(); - - if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV - || (pixel_type == GL_UNSIGNED_BYTE && QSysInfo::ByteOrder == QSysInfo::LittleEndian)) { - for (int i=0; i < height; ++i) { - uint *p = (uint *) img.scanLine(i); - for (int x=0; x> 16) & 0xff) | (p[x] & 0xff00ff00); - } - } else { - for (int i=0; i < height; ++i) { - uint *p = (uint *) img.scanLine(i); - for (int x=0; x> 24) & 0xff); - } - } + qgl_byteSwapImage(img, pixel_type); } #ifdef QT_OPENGL_ES // OpenGL/ES requires that the internal and external formats be identical. diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp index c478630..c0a0460 100644 --- a/src/opengl/qglpixmapfilter.cpp +++ b/src/opengl/qglpixmapfilter.cpp @@ -55,11 +55,17 @@ #include "qgl_p.h" #include "private/qapplication_p.h" +#include "private/qdrawhelper_p.h" +#include "private/qmemrotate_p.h" #include "private/qmath_p.h" #include "qmath.h" QT_BEGIN_NAMESPACE +// qpixmapfilter.cpp +void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0); +QImage qt_halfScaled(const QImage &source); + void QGLPixmapFilterBase::bindTexture(const QPixmap &src) const { const_cast(QGLContext::currentContext())->d_func()->bindTexture(src, GL_TEXTURE_2D, GL_RGBA, QGLContext::BindOptions(QGLContext::DefaultBindOption | QGLContext::MemoryManagedBindOption)); @@ -102,48 +108,21 @@ private: class QGLPixmapBlurFilter : public QGLCustomShaderStage, public QGLPixmapFilter { public: - QGLPixmapBlurFilter(QGraphicsBlurEffect::BlurHints hints); - - void setUniforms(QGLShaderProgram *program); - - static QByteArray generateGaussianShader(int radius, bool singlePass = false, bool dropShadow = false); + QGLPixmapBlurFilter(); protected: bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const; - -private: - - mutable QSize m_textureSize; - mutable bool m_horizontalBlur; - mutable bool m_singlePass; - mutable bool m_animatedBlur; - - mutable qreal m_t; - mutable QSize m_targetSize; - - mutable bool m_haveCached; - mutable int m_cachedRadius; - mutable QGraphicsBlurEffect::BlurHints m_hints; }; class QGLPixmapDropShadowFilter : public QGLCustomShaderStage, public QGLPixmapFilter { public: - QGLPixmapDropShadowFilter(QGraphicsBlurEffect::BlurHints hints); + QGLPixmapDropShadowFilter(); void setUniforms(QGLShaderProgram *program); protected: bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const; - -private: - mutable QSize m_textureSize; - mutable bool m_horizontalBlur; - mutable bool m_singlePass; - - mutable bool m_haveCached; - mutable int m_cachedRadius; - mutable QGraphicsBlurEffect::BlurHints m_hints; }; extern QGLWidget *qt_gl_share_widget(); @@ -158,31 +137,14 @@ QPixmapFilter *QGL2PaintEngineEx::pixmapFilter(int type, const QPixmapFilter *pr return d->colorizeFilter.data(); case QPixmapFilter::BlurFilter: { - const QPixmapBlurFilter *proto = static_cast(prototype); - if (proto->blurHints() & QGraphicsBlurEffect::AnimationHint) { - if (!d->animationBlurFilter) - d->animationBlurFilter.reset(new QGLPixmapBlurFilter(proto->blurHints())); - return d->animationBlurFilter.data(); - } - if ((proto->blurHints() & QGraphicsBlurEffect::QualityHint) && proto->radius() > 5) { - if (!d->blurFilter) - d->blurFilter.reset(new QGLPixmapBlurFilter(QGraphicsBlurEffect::QualityHint)); - return d->blurFilter.data(); - } - if (!d->fastBlurFilter) - d->fastBlurFilter.reset(new QGLPixmapBlurFilter(QGraphicsBlurEffect::PerformanceHint)); - return d->fastBlurFilter.data(); + if (!d->blurFilter) + d->blurFilter.reset(new QGLPixmapBlurFilter()); + return d->blurFilter.data(); } case QPixmapFilter::DropShadowFilter: { - const QPixmapDropShadowFilter *proto = static_cast(prototype); - if (proto->blurRadius() <= 5) { - if (!d->fastDropShadowFilter) - d->fastDropShadowFilter.reset(new QGLPixmapDropShadowFilter(QGraphicsBlurEffect::PerformanceHint)); - return d->fastDropShadowFilter.data(); - } if (!d->dropShadowFilter) - d->dropShadowFilter.reset(new QGLPixmapDropShadowFilter(QGraphicsBlurEffect::QualityHint)); + d->dropShadowFilter.reset(new QGLPixmapDropShadowFilter()); return d->dropShadowFilter.data(); } @@ -311,59 +273,43 @@ bool QGLPixmapConvolutionFilter::processGL(QPainter *painter, const QPointF &pos return true; } -static const char *qt_gl_texture_sampling_helper = - "lowp float texture2DAlpha(lowp sampler2D src, highp vec2 srcCoords) {\n" - " return texture2D(src, srcCoords).a;\n" - "}\n"; - -QGLPixmapBlurFilter::QGLPixmapBlurFilter(QGraphicsBlurEffect::BlurHints hints) - : m_animatedBlur(false) - , m_haveCached(false) - , m_cachedRadius(0) - , m_hints(hints) -{ -} - -// should be even numbers as they will be divided by two -static const int qCachedBlurLevels[] = { 6, 14, 30 }; -static const int qNumCachedBlurTextures = sizeof(qCachedBlurLevels) / sizeof(*qCachedBlurLevels); -static const int qMaxCachedBlurLevel = qCachedBlurLevels[qNumCachedBlurTextures - 1]; - -static qreal qLogBlurLevel(int level) +QGLPixmapBlurFilter::QGLPixmapBlurFilter() { - static bool initialized = false; - static qreal logBlurLevelCache[qNumCachedBlurTextures]; - if (!initialized) { - for (int i = 0; i < qNumCachedBlurTextures; ++i) - logBlurLevelCache[i] = qLn(qCachedBlurLevels[i]); - initialized = true; - } - return logBlurLevelCache[level]; } class QGLBlurTextureInfo { public: - QGLBlurTextureInfo(QSize size, GLuint textureIds[]) - : m_size(size) + QGLBlurTextureInfo(const QImage &image, GLuint tex, qreal r) + : m_texture(tex) + , m_radius(r) { - for (int i = 0; i < qNumCachedBlurTextures; ++i) - m_textureIds[i] = textureIds[i]; + m_paddedImage << image; } ~QGLBlurTextureInfo() { - glDeleteTextures(qNumCachedBlurTextures, m_textureIds); + glDeleteTextures(1, &m_texture); } - QSize size() const { return m_size; } - GLuint textureId(int i) const { return m_textureIds[i]; } + QImage paddedImage(int scaleLevel = 0) const; + GLuint texture() const { return m_texture; } + qreal radius() const { return m_radius; } private: - GLuint m_textureIds[qNumCachedBlurTextures]; - QSize m_size; + mutable QList m_paddedImage; + GLuint m_texture; + qreal m_radius; }; +QImage QGLBlurTextureInfo::paddedImage(int scaleLevel) const +{ + for (int i = m_paddedImage.size() - 1; i <= scaleLevel; ++i) + m_paddedImage << qt_halfScaled(m_paddedImage.at(i)); + + return m_paddedImage.at(scaleLevel); +} + class QGLBlurTextureCache : public QObject { public: @@ -373,7 +319,6 @@ public: ~QGLBlurTextureCache(); QGLBlurTextureInfo *takeBlurTextureInfo(const QPixmap &pixmap); - bool fitsInCache(const QPixmap &pixmap) const; bool hasBlurTextureInfo(const QPixmap &pixmap) const; void insertBlurTextureInfo(const QPixmap &pixmap, QGLBlurTextureInfo *info); void clearBlurTextureInfo(const QPixmap &pixmap); @@ -458,12 +403,7 @@ void QGLBlurTextureCache::insertBlurTextureInfo(const QPixmap &pixmap, QGLBlurTe if (timerId) killTimer(timerId); - timerId = startTimer(1000); -} - -bool QGLBlurTextureCache::fitsInCache(const QPixmap &pixmap) const -{ - return pixmap.width() * pixmap.height() <= cache.maxCost(); + timerId = startTimer(8000); } void QGLBlurTextureCache::pixmapDestroyed(QPixmap *pixmap) @@ -474,567 +414,219 @@ void QGLBlurTextureCache::pixmapDestroyed(QPixmap *pixmap) } } -static const char *qt_gl_interpolate_filter = - "uniform lowp float interpolationValue;" - "uniform lowp sampler2D interpolateTarget;" - "uniform highp vec4 interpolateMapping;" - "lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords)" - "{" - " return mix(texture2D(interpolateTarget, interpolateMapping.xy + interpolateMapping.zw * srcCoords)," - " texture2D(src, srcCoords), interpolationValue);" - "}"; +static const int qAnimatedBlurLevelIncrement = 16; +static const int qMaxBlurHalfScaleLevel = 1; -static void initializeTexture(GLuint id, int width, int height) +static GLuint generateBlurTexture(const QSize &size, GLenum format = GL_RGBA) { - glBindTexture(GL_TEXTURE_2D, id); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glBindTexture(GL_TEXTURE_2D, 0); + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexImage2D(GL_TEXTURE_2D, 0, format, size.width(), size.height(), 0, format, + GL_UNSIGNED_BYTE, 0); + return texture; } -bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &) const +static inline uint nextMultiple(uint x, uint multiplier) { - QGLPixmapBlurFilter *filter = const_cast(this); - - QGLContext *ctx = const_cast(QGLContext::currentContext()); - QGLBlurTextureCache *blurTextureCache = QGLBlurTextureCache::cacheForContext(ctx); - - if ((m_hints & QGraphicsBlurEffect::AnimationHint) && blurTextureCache->fitsInCache(src)) { - QRect targetRect = src.rect().adjusted(-qMaxCachedBlurLevel, -qMaxCachedBlurLevel, qMaxCachedBlurLevel, qMaxCachedBlurLevel); - // ensure even dimensions (going to divide by two) - targetRect.setWidth((targetRect.width() + 1) & ~1); - targetRect.setHeight((targetRect.height() + 1) & ~1); - - QGLBlurTextureInfo *info = 0; - if (blurTextureCache->hasBlurTextureInfo(src)) { - info = blurTextureCache->takeBlurTextureInfo(src); - } else { - m_animatedBlur = false; - m_hints = QGraphicsBlurEffect::QualityHint; - m_singlePass = false; - - QGLFramebufferObjectFormat format; - format.setInternalTextureFormat(GLenum(GL_RGBA)); - QGLFramebufferObject *fbo = qgl_fbo_pool()->acquire(targetRect.size() / 2, format, true); - - if (!fbo) - return false; - - QPainter fboPainter(fbo); - QGL2PaintEngineEx *engine = static_cast(fboPainter.paintEngine()); - - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); - - // ensure GL_LINEAR filtering is used for scaling down to half the size - fboPainter.setRenderHint(QPainter::SmoothPixmapTransform); - fboPainter.setCompositionMode(QPainter::CompositionMode_Source); - fboPainter.drawPixmap(qMaxCachedBlurLevel / 2, qMaxCachedBlurLevel / 2, - targetRect.width() / 2 - qMaxCachedBlurLevel, targetRect.height() / 2 - qMaxCachedBlurLevel, src); - - GLuint textures[qNumCachedBlurTextures]; // blur textures - glGenTextures(qNumCachedBlurTextures, textures); - GLuint temp; // temp texture - glGenTextures(1, &temp); - - initializeTexture(temp, fbo->width(), fbo->height()); - m_textureSize = fbo->size(); - - int currentBlur = 0; - - QRect fboRect(0, 0, fbo->width(), fbo->height()); - GLuint sourceTexture = fbo->texture(); - for (int i = 0; i < qNumCachedBlurTextures; ++i) { - int targetBlur = qCachedBlurLevels[i] / 2; - - int blurDelta = qRound(qSqrt(targetBlur * targetBlur - currentBlur * currentBlur)); - QByteArray source = generateGaussianShader(blurDelta); - filter->setSource(source); - - currentBlur = targetBlur; - - // now we're going to be nasty and keep using the same FBO with different textures - glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - GL_TEXTURE_2D, temp, 0); - - m_horizontalBlur = true; - filter->setOnPainter(&fboPainter); - engine->drawTexture(fboRect, sourceTexture, fbo->size(), fboRect); - filter->removeFromPainter(&fboPainter); - - sourceTexture = textures[i]; - initializeTexture(sourceTexture, fbo->width(), fbo->height()); - - glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - GL_TEXTURE_2D, textures[i], 0); - - m_horizontalBlur = false; - filter->setOnPainter(&fboPainter); - engine->drawTexture(fboRect, temp, fbo->size(), fboRect); - filter->removeFromPainter(&fboPainter); - } + uint mod = x % multiplier; + if (mod == 0) + return x; + return x + multiplier - mod; +} - glDeleteTextures(1, &temp); +void qt_memrotate90_gl(const quint32 *src, int srcWidth, int srcHeight, int srcStride, + quint32 *dest, int dstStride); - // reattach the original FBO texture - glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - GL_TEXTURE_2D, fbo->texture(), 0); +bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &) const +{ + if (radius() < 1) { + painter->drawPixmap(pos, src); + return true; + } - fboPainter.end(); + qreal actualRadius = radius(); - qgl_fbo_pool()->release(fbo); + QGLPixmapBlurFilter *filter = const_cast(this); - info = new QGLBlurTextureInfo(fboRect.size(), textures); - } + QGLContext *ctx = const_cast(QGLContext::currentContext()); - if (!m_haveCached || !m_animatedBlur) { - m_haveCached = true; - m_animatedBlur = true; - m_hints = QGraphicsBlurEffect::AnimationHint; - filter->setSource(qt_gl_interpolate_filter); - } + QGLBlurTextureCache *blurTextureCache = QGLBlurTextureCache::cacheForContext(ctx); + QGLBlurTextureInfo *info = 0; + int padding = nextMultiple(qCeil(actualRadius), qAnimatedBlurLevelIncrement); + QRect targetRect = src.rect().adjusted(-padding, -padding, padding, padding); - QGL2PaintEngineEx *engine = static_cast(painter->paintEngine()); - painter->setRenderHint(QPainter::SmoothPixmapTransform); - filter->setOnPainter(painter); + // pad so that we'll be able to half-scale qMaxBlurHalfScaleLevel times + targetRect.setWidth((targetRect.width() + (qMaxBlurHalfScaleLevel-1)) & ~(qMaxBlurHalfScaleLevel-1)); + targetRect.setHeight((targetRect.height() + (qMaxBlurHalfScaleLevel-1)) & ~(qMaxBlurHalfScaleLevel-1)); - qreal logRadius = qLn(radius()); + QSize textureSize; - int t; - for (t = -1; t < qNumCachedBlurTextures - 2; ++t) { - if (logRadius < qLogBlurLevel(t+1)) - break; - } + info = blurTextureCache->takeBlurTextureInfo(src); + if (!info || info->radius() < actualRadius) { + QSize paddedSize = targetRect.size() / 2; - qreal logBase = t >= 0 ? qLogBlurLevel(t) : 0; - m_t = qBound(qreal(0), (logRadius - logBase) / (qLogBlurLevel(t+1) - logBase), qreal(1)); + QImage padded(paddedSize.height(), paddedSize.width(), QImage::Format_ARGB32_Premultiplied); + padded.fill(0); - m_textureSize = info->size(); + if (info) { + int oldPadding = qRound(info->radius()); - glActiveTexture(GL_TEXTURE0 + 3); - if (t >= 0) { - glBindTexture(GL_TEXTURE_2D, info->textureId(t)); - m_targetSize = info->size(); + QPainter p(&padded); + p.setCompositionMode(QPainter::CompositionMode_Source); + p.drawImage((padding - oldPadding) / 2, (padding - oldPadding) / 2, info->paddedImage()); + p.end(); } else { - QGLTexture *texture = - ctx->d_func()->bindTexture(src, GL_TEXTURE_2D, GL_RGBA, - QGLContext::InternalBindOption - | QGLContext::CanFlipNativePixmapBindOption); - m_targetSize = src.size(); - if (!(texture->options & QGLContext::InvertedYBindOption)) - m_targetSize.setHeight(-m_targetSize.height()); + // TODO: combine byteswapping and memrotating into one by declaring + // custom GL_RGBA pixel type and qt_colorConvert template for it + QImage prepadded = qt_halfScaled(src.toImage()).convertToFormat(QImage::Format_ARGB32_Premultiplied); + + // byte-swap and memrotates in one go + qt_memrotate90_gl(reinterpret_cast(prepadded.bits()), + prepadded.width(), prepadded.height(), prepadded.bytesPerLine(), + reinterpret_cast(padded.scanLine(padding / 2)) + padding / 2, + padded.bytesPerLine()); } - // restrict the target rect to the max of the radii we are interpolating between - int radiusDelta = qMaxCachedBlurLevel - qCachedBlurLevels[t+1]; - targetRect = targetRect.translated(pos.toPoint()).adjusted(radiusDelta, radiusDelta, -radiusDelta, -radiusDelta); - - radiusDelta /= 2; - QRect sourceRect = QRect(QPoint(), m_textureSize).adjusted(radiusDelta, radiusDelta, -radiusDelta, -radiusDelta); - - engine->drawTexture(targetRect, info->textureId(t+1), m_textureSize, sourceRect); + delete info; + info = new QGLBlurTextureInfo(padded, generateBlurTexture(paddedSize), padding); - glActiveTexture(GL_TEXTURE0 + 3); - glBindTexture(GL_TEXTURE_2D, 0); - - filter->removeFromPainter(painter); - blurTextureCache->insertBlurTextureInfo(src, info); - - return true; - } - - if (blurTextureCache->hasBlurTextureInfo(src)) - blurTextureCache->clearBlurTextureInfo(src); - - int actualRadius = qRound(radius()); - int filterRadius = actualRadius; - int fastRadii[] = { 1, 2, 3, 5, 8, 15, 25 }; - if (!(m_hints & QGraphicsBlurEffect::QualityHint)) { - uint i = 0; - for (; i < (sizeof(fastRadii)/sizeof(*fastRadii))-1; ++i) { - if (fastRadii[i+1] > filterRadius) - break; - } - filterRadius = fastRadii[i]; + textureSize = paddedSize; + } else { + textureSize = QSize(info->paddedImage().height(), info->paddedImage().width()); } - m_singlePass = filterRadius <= 3; - - if (!m_haveCached || m_animatedBlur || filterRadius != m_cachedRadius) { - // Only regenerate the shader from source if parameters have changed. - m_haveCached = true; - m_animatedBlur = false; - m_cachedRadius = filterRadius; - QByteArray source = generateGaussianShader(filterRadius, m_singlePass); - filter->setSource(source); + actualRadius *= qreal(0.5); + int level = 1; + for (; level < qMaxBlurHalfScaleLevel; ++level) { + if (actualRadius <= 16) + break; + actualRadius *= qreal(0.5); } - QRect targetRect = QRectF(src.rect()).translated(pos).adjusted(-actualRadius, -actualRadius, actualRadius, actualRadius).toAlignedRect(); + const int s = (1 << level); - if (m_singlePass) { - // prepare for updateUniforms - m_textureSize = src.size(); + int prepadding = qRound(info->radius()); + padding = qMin(prepadding, qCeil(actualRadius) << level); + targetRect = src.rect().adjusted(-padding, -padding, padding, padding); - // ensure GL_LINEAR filtering is used - painter->setRenderHint(QPainter::SmoothPixmapTransform); - filter->setOnPainter(painter); - QBrush pixmapBrush = src; - pixmapBrush.setTransform(QTransform::fromTranslate(pos.x(), pos.y())); - painter->fillRect(targetRect, pixmapBrush); - filter->removeFromPainter(painter); - } else { - QGLFramebufferObjectFormat format; - format.setInternalTextureFormat(GLenum(src.hasAlphaChannel() ? GL_RGBA : GL_RGB)); - QGLFramebufferObject *fbo = qgl_fbo_pool()->acquire(targetRect.size(), format); + targetRect.setWidth(targetRect.width() & ~(s-1)); + targetRect.setHeight(targetRect.height() & ~(s-1)); - if (!fbo) - return false; + int paddingDelta = (prepadding - padding) >> level; - // prepare for updateUniforms - m_textureSize = src.size(); + QRect subRect(paddingDelta, paddingDelta, targetRect.width() >> level, targetRect.height() >> level); + QImage sourceImage = info->paddedImage(level-1); - // horizontal pass, to pixmap - m_horizontalBlur = true; + QImage subImage(subRect.height(), subRect.width(), QImage::Format_ARGB32_Premultiplied); + qt_rectcopy((QRgb *)subImage.bits(), ((QRgb *)sourceImage.scanLine(paddingDelta)) + paddingDelta, + 0, 0, subRect.height(), subRect.width(), subImage.bytesPerLine(), sourceImage.bytesPerLine()); - QPainter fboPainter(fbo); + GLuint texture = info->texture(); - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); + qt_blurImage(subImage, actualRadius, blurHints() & QGraphicsBlurEffect::QualityHint, 1); - // ensure GL_LINEAR filtering is used - fboPainter.setRenderHint(QPainter::SmoothPixmapTransform); - fboPainter.setCompositionMode(QPainter::CompositionMode_Source); - filter->setOnPainter(&fboPainter); - QBrush pixmapBrush = src; - pixmapBrush.setTransform(QTransform::fromTranslate(actualRadius, actualRadius)); - fboPainter.fillRect(QRect(0, 0, targetRect.width(), targetRect.height()), pixmapBrush); - filter->removeFromPainter(&fboPainter); - fboPainter.end(); + // subtract one pixel off the end to prevent the bilinear sampling from sampling uninitialized data + QRect textureSubRect = subImage.rect().adjusted(0, 0, -1, -1); + QRectF targetRectF = QRectF(targetRect).adjusted(0, 0, -targetRect.width() / qreal(textureSize.width()), -targetRect.height() / qreal(textureSize.height())); - QGL2PaintEngineEx *engine = static_cast(painter->paintEngine()); + glBindTexture(GL_TEXTURE_2D, texture); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subImage.width(), subImage.height(), GL_RGBA, + GL_UNSIGNED_BYTE, const_cast(subImage).bits()); - // vertical pass, to painter - m_horizontalBlur = false; - m_textureSize = fbo->size(); + QGL2PaintEngineEx *engine = static_cast(painter->paintEngine()); + painter->setRenderHint(QPainter::SmoothPixmapTransform); - painter->save(); - // ensure GL_LINEAR filtering is used - painter->setRenderHint(QPainter::SmoothPixmapTransform); - filter->setOnPainter(painter); - engine->drawTexture(targetRect, fbo->texture(), fbo->size(), QRect(QPoint(), targetRect.size()).translated(0, fbo->height() - targetRect.height())); - filter->removeFromPainter(painter); - painter->restore(); + // texture is flipped on the y-axis + targetRectF = QRectF(targetRectF.x(), targetRectF.bottom(), targetRectF.width(), -targetRectF.height()); + engine->drawTexture(targetRectF.translated(pos), texture, textureSize, textureSubRect); - qgl_fbo_pool()->release(fbo); - } + blurTextureCache->insertBlurTextureInfo(src, info); return true; } -void QGLPixmapBlurFilter::setUniforms(QGLShaderProgram *program) -{ - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - if (m_animatedBlur) { - program->setUniformValue("interpolateTarget", 3); - program->setUniformValue("interpolationValue", GLfloat(m_t)); - - if (m_textureSize == m_targetSize) { - program->setUniformValue("interpolateMapping", 0.0f, 0.0f, 1.0f, 1.0f); - } else { - float offsetX = (-qMaxCachedBlurLevel - 0.5) / qreal(m_targetSize.width()); - float offsetY = (-qMaxCachedBlurLevel - 0.5) / qreal(m_targetSize.height()); - - if (m_targetSize.height() < 0) - offsetY = 1 + offsetY; - - float scaleX = 2.0f * qreal(m_textureSize.width()) / qreal(m_targetSize.width()); - float scaleY = 2.0f * qreal(m_textureSize.height()) / qreal(m_targetSize.height()); - - program->setUniformValue("interpolateMapping", offsetX, offsetY, scaleX, scaleY); - } - - return; - } +static const char *qt_gl_drop_shadow_filter = + "uniform lowp vec4 shadowColor;" + "lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords)" + "{" + " return shadowColor * texture2D(src, srcCoords.yx).a;" + "}"; - if (m_hints & QGraphicsBlurEffect::QualityHint) { - if (m_singlePass) - program->setUniformValue("delta", 1.0 / m_textureSize.width(), 1.0 / m_textureSize.height()); - else 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 { - qreal blur = radius() / qreal(m_cachedRadius); - - if (m_singlePass) - program->setUniformValue("delta", blur / m_textureSize.width(), blur / m_textureSize.height()); - else 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) +QGLPixmapDropShadowFilter::QGLPixmapDropShadowFilter() { - return exp(-dx * dx / (2 * sigma * sigma)) / (Q_2PI * sigma * sigma); + setSource(qt_gl_drop_shadow_filter); } -QByteArray QGLPixmapBlurFilter::generateGaussianShader(int radius, bool singlePass, bool dropShadow) +bool QGLPixmapDropShadowFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const { - Q_ASSERT(radius >= 1); - - radius = qMin(127, radius); - - static QCache shaderSourceCache; - uint key = radius | (int(singlePass) << 7) | (int(dropShadow) << 8); - QByteArray *cached = shaderSourceCache.object(key); - if (cached) - return *cached; - - QByteArray source; - source.reserve(1000); - source.append(qt_gl_texture_sampling_helper); - - source.append("uniform highp vec2 delta;\n"); - if (dropShadow) - source.append("uniform mediump vec4 shadowColor;\n"); - source.append("lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords) {\n"); - - QVector sampleOffsets; - QVector weights; - - QVector gaussianComponents; - - qreal sigma = radius / 1.65; - - 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; - - 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; - } - - int limit = sampleOffsets.size(); - if (singlePass) - limit *= limit; - - QByteArray baseCoordinate = "srcCoords"; - - for (int i = 0; i < limit; ++i) { - QByteArray coordinate = baseCoordinate; - - qreal weight; - if (singlePass) { - const int xIndex = i % sampleOffsets.size(); - const int yIndex = i / sampleOffsets.size(); - - const qreal deltaX = sampleOffsets.at(xIndex); - const qreal deltaY = sampleOffsets.at(yIndex); - weight = weights.at(xIndex) * weights.at(yIndex); - - if (!qFuzzyCompare(deltaX, deltaY)) { - coordinate.append(" + vec2(delta.x * float("); - coordinate.append(QByteArray::number(deltaX)); - coordinate.append("), delta.y * float("); - coordinate.append(QByteArray::number(deltaY)); - coordinate.append("))"); - } else if (!qFuzzyIsNull(deltaX)) { - coordinate.append(" + delta * float("); - coordinate.append(QByteArray::number(deltaX)); - coordinate.append(")"); - } - } else { - const qreal delta = sampleOffsets.at(i); - weight = weights.at(i); - if (!qFuzzyIsNull(delta)) { - coordinate.append(" + delta * float("); - coordinate.append(QByteArray::number(delta)); - coordinate.append(")"); - } - } - - if (i == 0) { - if (dropShadow) - source.append(" mediump float sample = "); - else - source.append(" mediump vec4 sample = "); - } else { - if (dropShadow) - source.append(" sample += "); - else - source.append(" sample += "); - } + QGLPixmapDropShadowFilter *filter = const_cast(this); - source.append("texture2D(src, "); - source.append(coordinate); - source.append(")"); + qreal r = blurRadius(); + QRectF targetRectUnaligned = QRectF(src.rect()).translated(pos + offset()).adjusted(-r, -r, r, r); + QRect targetRect = targetRectUnaligned.toAlignedRect(); - if (dropShadow) - source.append(".a"); + // ensure even dimensions (going to divide by two) + targetRect.setWidth((targetRect.width() + 1) & ~1); + targetRect.setHeight((targetRect.height() + 1) & ~1); - if (!qFuzzyCompare(weight, qreal(1))) { - source.append(" * float("); - source.append(QByteArray::number(weight)); - source.append(");\n"); - } else { - source.append(";\n"); - } - } + QGLContext *ctx = const_cast(QGLContext::currentContext()); + QGLBlurTextureCache *blurTextureCache = QGLBlurTextureCache::cacheForContext(ctx); - source.append(" return "); - if (dropShadow) - source.append("shadowColor * "); - source.append("sample;\n"); - source.append("}\n"); + QGLBlurTextureInfo *info = blurTextureCache->takeBlurTextureInfo(src); + if (!info || info->radius() != r) { + QImage half = qt_halfScaled(src.toImage().alphaChannel()); - cached = new QByteArray(source); - shaderSourceCache.insert(key, cached); + qreal rx = r + targetRect.left() - targetRectUnaligned.left(); + qreal ry = r + targetRect.top() - targetRectUnaligned.top(); - return source; -} + QImage image = QImage(targetRect.size() / 2, QImage::Format_Indexed8); + image.setColorTable(half.colorTable()); + image.fill(0); + int dx = qRound(rx * qreal(0.5)); + int dy = qRound(ry * qreal(0.5)); + qt_rectcopy(image.bits(), half.bits(), dx, dy, + half.width(), half.height(), + image.bytesPerLine(), half.bytesPerLine()); -QGLPixmapDropShadowFilter::QGLPixmapDropShadowFilter(QGraphicsBlurEffect::BlurHints hints) - : m_haveCached(false) - , m_cachedRadius(0) - , m_hints(hints) -{ -} + qt_blurImage(image, r * qreal(0.5), false, 1); -bool QGLPixmapDropShadowFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const -{ - QGLPixmapDropShadowFilter *filter = const_cast(this); + GLuint texture = generateBlurTexture(image.size(), GL_ALPHA); - int actualRadius = qRound(blurRadius()); - int filterRadius = actualRadius; - m_singlePass = filterRadius <= 3; + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image.width(), image.height(), GL_ALPHA, + GL_UNSIGNED_BYTE, image.bits()); - if (!m_haveCached || filterRadius != m_cachedRadius) { - // Only regenerate the shader from source if parameters have changed. - m_haveCached = true; - m_cachedRadius = filterRadius; - QByteArray source = QGLPixmapBlurFilter::generateGaussianShader(filterRadius, m_singlePass, true); - filter->setSource(source); + info = new QGLBlurTextureInfo(image, texture, r); } - QRect targetRect = QRectF(src.rect()).translated(pos + offset()).adjusted(-actualRadius, -actualRadius, actualRadius, actualRadius).toAlignedRect(); - - if (m_singlePass) { - // prepare for updateUniforms - m_textureSize = src.size(); - - painter->save(); - // ensure GL_LINEAR filtering is used - painter->setRenderHint(QPainter::SmoothPixmapTransform); - filter->setOnPainter(painter); - QBrush pixmapBrush = src; - pixmapBrush.setTransform(QTransform::fromTranslate(pos.x() + offset().x(), pos.y() + offset().y())); - painter->fillRect(targetRect, pixmapBrush); - filter->removeFromPainter(painter); - painter->restore(); - } else { - QGLFramebufferObjectFormat format; - format.setInternalTextureFormat(GLenum(src.hasAlphaChannel() ? GL_RGBA : GL_RGB)); - QGLFramebufferObject *fbo = qgl_fbo_pool()->acquire(targetRect.size(), format); - - if (!fbo) - return false; - - // prepare for updateUniforms - m_textureSize = src.size(); - - // horizontal pass, to pixmap - m_horizontalBlur = true; - - QPainter fboPainter(fbo); + GLuint texture = info->texture(); - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); - - // ensure GL_LINEAR filtering is used - fboPainter.setRenderHint(QPainter::SmoothPixmapTransform); - fboPainter.setCompositionMode(QPainter::CompositionMode_Source); - filter->setOnPainter(&fboPainter); - QBrush pixmapBrush = src; - pixmapBrush.setTransform(QTransform::fromTranslate(actualRadius, actualRadius)); - fboPainter.fillRect(QRect(0, 0, targetRect.width(), targetRect.height()), pixmapBrush); - filter->removeFromPainter(&fboPainter); - fboPainter.end(); - - QGL2PaintEngineEx *engine = static_cast(painter->paintEngine()); + filter->setOnPainter(painter); - // vertical pass, to painter - m_horizontalBlur = false; - m_textureSize = fbo->size(); + QGL2PaintEngineEx *engine = static_cast(painter->paintEngine()); + painter->setRenderHint(QPainter::SmoothPixmapTransform); - painter->save(); - // ensure GL_LINEAR filtering is used - painter->setRenderHint(QPainter::SmoothPixmapTransform); - filter->setOnPainter(painter); - engine->drawTexture(targetRect, fbo->texture(), fbo->size(), QRectF(0, fbo->height() - targetRect.height(), targetRect.width(), targetRect.height())); - filter->removeFromPainter(painter); - painter->restore(); + engine->drawTexture(targetRect, texture, info->paddedImage().size(), info->paddedImage().rect()); - qgl_fbo_pool()->release(fbo); - } + filter->removeFromPainter(painter); // Now draw the actual pixmap over the top. painter->drawPixmap(pos, src, srcRect); + blurTextureCache->insertBlurTextureInfo(src, info); + return true; } void QGLPixmapDropShadowFilter::setUniforms(QGLShaderProgram *program) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - QColor col = color(); - if (m_horizontalBlur && !m_singlePass) { - program->setUniformValue("shadowColor", 1.0f, 1.0f, 1.0f, 1.0f); - } else { - qreal alpha = col.alphaF(); - program->setUniformValue("shadowColor", col.redF() * alpha, - col.greenF() * alpha, - col.blueF() * alpha, - alpha); - } - - if (m_hints & QGraphicsBlurEffect::QualityHint) { - if (m_singlePass) - program->setUniformValue("delta", 1.0 / m_textureSize.width(), 1.0 / m_textureSize.height()); - else 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 { - qreal blur = blurRadius() / qreal(m_cachedRadius); - - if (m_singlePass) - program->setUniformValue("delta", blur / m_textureSize.width(), blur / m_textureSize.height()); - else if (m_horizontalBlur) - program->setUniformValue("delta", blur / m_textureSize.width(), 0.0); - else - program->setUniformValue("delta", 0.0, blur / m_textureSize.height()); - } + qreal alpha = col.alphaF(); + program->setUniformValue("shadowColor", col.redF() * alpha, + col.greenF() * alpha, + col.blueF() * alpha, + alpha); } QT_END_NAMESPACE -- cgit v0.12 From 19a2bd42d11d070e229cf00c43d6aa777d590415 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Mon, 14 Dec 2009 15:02:53 +0100 Subject: Add "nocopy" mode for seperate-debug-info to configure This patch was written by Harald Fernengel for Maemo5 port. This effectively just adds -g to QMAKE_CFLAGS & QMAKE_CXXFLAGS and is mainly for packagers who want to build Qt in release mode and still have debug symbols, but will want to strip those debug symbols out themselves (rather than let Qt do it). Reviewed-By: Harald Fernengel Reviewed-By: Thiago Macieira --- configure | 7 +++++++ mkspecs/features/unix/separate_debug_info.prf | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 6dc3898..f186944 100755 --- a/configure +++ b/configure @@ -712,6 +712,7 @@ CFG_PTMALLOC=no CFG_STL=auto CFG_PRECOMPILE=auto CFG_SEPARATE_DEBUG_INFO=auto +CFG_SEPARATE_DEBUG_INFO_NOCOPY=no CFG_REDUCE_EXPORTS=auto CFG_MMX=auto CFG_3DNOW=auto @@ -1543,6 +1544,9 @@ while [ "$#" -gt 0 ]; do separate-debug-info) if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then CFG_SEPARATE_DEBUG_INFO="$VAL" + elif [ "$VAL" = "nocopy" ] ; then + CFG_SEPARATE_DEBUG_INFO="yes" + CFG_SEPARATE_DEBUG_INFO_NOCOPY="yes" else UNKNOWN_OPT=yes fi @@ -6083,6 +6087,9 @@ if [ "$CFG_SEPARATE_DEBUG_INFO" = "yes" ]; then QMakeVar add QMAKE_CXXFLAGS -g QMAKE_CONFIG="$QMAKE_CONFIG separate_debug_info" fi +if [ "$CFG_SEPARATE_DEBUG_INFO_NOCOPY" = "yes" ] ; then + QMAKE_CONFIG="$QMAKE_CONFIG separate_debug_info_nocopy" +fi [ "$CFG_MMX" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG mmx" [ "$CFG_3DNOW" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG 3dnow" [ "$CFG_SSE" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG sse" diff --git a/mkspecs/features/unix/separate_debug_info.prf b/mkspecs/features/unix/separate_debug_info.prf index 0c95baf..c675828 100644 --- a/mkspecs/features/unix/separate_debug_info.prf +++ b/mkspecs/features/unix/separate_debug_info.prf @@ -1,5 +1,5 @@ -!staticlib:!static:!contains(TEMPLATE, subdirs):!isEmpty(QMAKE_OBJCOPY) { +!separate_debug_info_nocopy:!staticlib:!static:!contains(TEMPLATE, subdirs):!isEmpty(QMAKE_OBJCOPY) { QMAKE_SEPARATE_DEBUG_INFO = (test -z \"$(DESTDIR)\" || cd \"$(DESTDIR)\" ; targ=`basename $(TARGET)`; $$QMAKE_OBJCOPY --only-keep-debug \"\$\$targ\" \"\$\$targ.debug\" && $$QMAKE_OBJCOPY --strip-debug \"\$\$targ\" && $$QMAKE_OBJCOPY --add-gnu-debuglink=\"\$\$targ.debug\" \"\$\$targ\" && chmod -x \"\$\$targ.debug\" ) ; QMAKE_INSTALL_SEPARATE_DEBUG_INFO = test -z "$(DESTDIR)" || cd \"$(DESTDIR)\" ; $(INSTALL_FILE) `basename $(TARGET)`.debug $(INSTALL_ROOT)/\$\$target_path/ -- cgit v0.12 From e45b9b43b427128295ff00a6f09c451c766c17e2 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Mon, 14 Dec 2009 15:57:02 +0100 Subject: Make mkspec/unsupported/linux-host-g++ use correct include Reviewed-By: Trustme --- mkspecs/unsupported/linux-host-g++/qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/unsupported/linux-host-g++/qmake.conf b/mkspecs/unsupported/linux-host-g++/qmake.conf index 237477c..8a480c4 100644 --- a/mkspecs/unsupported/linux-host-g++/qmake.conf +++ b/mkspecs/unsupported/linux-host-g++/qmake.conf @@ -134,5 +134,5 @@ QMAKE_MKDIR = mkdir -p QMAKE_INSTALL_FILE = install -m 644 -p QMAKE_INSTALL_PROGRAM = install -m 755 -p -include(../common/unix.conf) +include(../../common/unix.conf) load(qt_config) -- cgit v0.12 From df512b3bc5c4e10c5dc0410dbc4d6bdfe9d593f1 Mon Sep 17 00:00:00 2001 From: ninerider Date: Mon, 23 Nov 2009 15:03:42 +0100 Subject: Compilation fix for Windows Mobile The default style (plastique) used was not available if not included in the build. Using now the windows style instead. Reviewed-by: Maurice --- tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp b/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp index d3087dc..ab110e6 100644 --- a/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp +++ b/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp @@ -146,7 +146,7 @@ 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 -#ifdef Q_WS_S60 +#if defined( Q_WS_S60 )|| defined (Q_WS_WINCE) QApplication::setStyle(new QWindowsStyle); #else QApplication::setStyle(new QPlastiqueStyle); -- cgit v0.12 From 7e9e5bc366ef76ec1f4b5f683f84e6beb66fa0ea Mon Sep 17 00:00:00 2001 From: ninerider Date: Tue, 24 Nov 2009 14:45:19 +0100 Subject: Removed the chip demo for windows CE The chip demo causes a memory exception on most Windows CE devices. For now we simply will not include this demo in the package for Windows CE. In the future a specialized version might be created. Reviewed-by: Maurice --- demos/demos.pro | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/demos/demos.pro b/demos/demos.pro index a943bfd..5a9b6db 100644 --- a/demos/demos.pro +++ b/demos/demos.pro @@ -20,7 +20,24 @@ symbian: SUBDIRS = \ demos_shared \ demos_deform \ demos_pathstroke - + +wince*: SUBDIRS = \ + demos_shared \ + demos_deform \ + demos_gradients \ + demos_pathstroke \ + demos_affine \ + demos_composition \ + demos_books \ + demos_interview \ + demos_mainwindow \ + demos_spreadsheet \ + demos_textedit \ + # demos_chip \ + demos_embeddeddialogs \ + demos_undo \ + demos_sub-attaq + contains(QT_CONFIG, opengl):!contains(QT_CONFIG, opengles1):!contains(QT_CONFIG, opengles1cl):!contains(QT_CONFIG, opengles2):{ SUBDIRS += demos_boxes } @@ -33,7 +50,7 @@ wince*|symbian|embedded|x11: SUBDIRS += embedded !cross_compile:{ contains(QT_BUILD_PARTS, tools):{ !wince*:SUBDIRS += demos_sqlbrowser demos_qtdemo -wince*: SUBDIRS += demos_sqlbrowser +wince*:SUBDIRS += demos_sqlbrowser } } contains(QT_CONFIG, phonon):!static:SUBDIRS += demos_mediaplayer -- cgit v0.12 From a72468e820c2922540737c053eef27d033c2e77b Mon Sep 17 00:00:00 2001 From: ninerider Date: Thu, 3 Dec 2009 13:31:01 +0100 Subject: Test fixed for Windows CE. Some test very corrected, the low level file descriptor tests mostly skipped as well as the multiple memory mapping of a file, which resulted in the file handle not beeign properly released. Reviewed-by: thartman --- tests/auto/qfile/tst_qfile.cpp | 75 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 13 deletions(-) diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index 7ee5665..2b2f431 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -220,6 +220,9 @@ public: private: enum FileType { OpenQFile, OpenFd, OpenStream }; + void openStandardStreamsFileDescriptors(); + void openStandardStreamsBufferedStreams(); + bool openFd(QFile &file, QIODevice::OpenMode mode) { int fdMode = QT_OPEN_LARGEFILE | QT_OPEN_BINARY; @@ -554,6 +557,10 @@ void tst_QFile::size() QFETCH( QString, filename ); QFETCH( qint64, size ); +#ifdef Q_WS_WINCE + filename = QFileInfo(filename).absoluteFilePath(); +#endif + { QFile f( filename ); QCOMPARE( f.size(), size ); @@ -564,24 +571,29 @@ void tst_QFile::size() { QFile f; - int fd = QT_OPEN(filename.toLocal8Bit().constData(), QT_OPEN_RDONLY); - QVERIFY( fd != -1 ); - QVERIFY( f.open(fd, QIODevice::ReadOnly) ); + FILE* stream = QT_FOPEN(filename.toLocal8Bit().constData(), "rb"); + QVERIFY( stream ); + QVERIFY( f.open(stream, QIODevice::ReadOnly) ); QCOMPARE( f.size(), size ); f.close(); - QT_CLOSE(fd); + fclose(stream); } { +#ifdef Q_WS_WINCE + QSKIP("Currently low level file I/O not well supported on Windows CE", SkipSingle); +#endif QFile f; - FILE* stream = QT_FOPEN(filename.toLocal8Bit().constData(), "rb"); - QVERIFY( stream ); - QVERIFY( f.open(stream, QIODevice::ReadOnly) ); + + int fd = QT_OPEN(filename.toLocal8Bit().constData(), QT_OPEN_RDONLY); + + QVERIFY( fd != -1 ); + QVERIFY( f.open(fd, QIODevice::ReadOnly) ); QCOMPARE( f.size(), size ); f.close(); - fclose(stream); + QT_CLOSE(fd); } } @@ -603,6 +615,7 @@ void tst_QFile::seek() QVERIFY(file.seek(10)); QCOMPARE(file.pos(), qint64(10)); QCOMPARE(file.size(), qint64(0)); + file.close(); QFile::remove("newfile.txt"); } @@ -1128,9 +1141,15 @@ void tst_QFile::copyFallback() QVERIFY(QFile::exists("file-copy-destination.txt")); QVERIFY(!file.isOpen()); +#ifdef Q_WS_WINCE // Need to reset permissions on Windows to be able to delete QVERIFY(QFile::setPermissions("file-copy-destination.txt", - QFile::ReadOwner | QFile::WriteOwner)); + QFile::WriteOther)); +#else + // Need to reset permissions on Windows to be able to delete + QVERIFY(QFile::setPermissions("file-copy-destination.txt", + QFile::ReadOwner | QFile::WriteOwner)); +#endif QVERIFY(QFile::remove("file-copy-destination.txt")); // Fallback copy of open file. @@ -1139,6 +1158,7 @@ void tst_QFile::copyFallback() QVERIFY(QFile::exists("file-copy-destination.txt")); QVERIFY(!file.isOpen()); + file.close(); QFile::remove("file-copy-destination.txt"); } @@ -2239,6 +2259,7 @@ void tst_QFile::rename() QFile file(source); QCOMPARE(file.rename(destination), result); + if (result) QCOMPARE(file.error(), QFile::NoError); else @@ -2367,6 +2388,7 @@ void tst_QFile::appendAndRead() QCOMPARE(readFile.read(1 << j).size(), 1 << j); } + readFile.close(); QFile::remove(QLatin1String("appendfile.txt")); } @@ -2608,10 +2630,15 @@ void tst_QFile::map() QFETCH(QFile::FileError, error); QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile"; + +#ifdef Q_WS_WINCE + fileName = QFileInfo(fileName).absoluteFilePath(); +#endif + if (QFile::exists(fileName)) { QVERIFY(QFile::setPermissions(fileName, QFile::WriteOwner | QFile::ReadOwner | QFile::WriteUser | QFile::ReadUser)); - QFile::remove(fileName); + QFile::remove(fileName); } QFile file(fileName); @@ -2650,8 +2677,13 @@ void tst_QFile::map() QCOMPARE(file.error(), QFile::NoError); // hpux wont let you map multiple times. -#if !defined(Q_OS_HPUX) && !defined(Q_USE_DEPRECATED_MAP_API) +#if !defined(Q_OS_HPUX) && !defined(Q_USE_DEPRECATED_MAP_API) && !defined(Q_OS_WINCE) // exotic test to make sure that multiple maps work + + // note: windows ce does not reference count mutliple maps + // it's essentially just the same reference but it + // cause a resource lock on the file which prevents it + // from being removed uchar *memory1 = file.map(0, file.size()); uchar *memory1 = file.map(0, file.size()); QCOMPARE(file.error(), QFile::NoError); uchar *memory2 = file.map(0, file.size()); @@ -2687,7 +2719,6 @@ void tst_QFile::map() QVERIFY(!memory); QVERIFY(file.setPermissions(originalPermissions)); } - QVERIFY(file.remove()); } @@ -2800,8 +2831,14 @@ void tst_QFile::openDirectory() f1.close(); } -void tst_QFile::openStandardStreams() +void tst_QFile::openStandardStreamsFileDescriptors() { +#ifdef Q_WS_WINCE + //allthough Windows CE (not mobile!) has functions that allow redirecting + //the standard file descriptors to a file (see SetStdioPathW/GetStdioPathW) + //it does not have functions to simply open them like below . + QSKIP("Opening standard streams on Windows CE via descriptor not implemented", SkipAll); +#endif // Using file descriptors { QFile in; @@ -2826,7 +2863,13 @@ void tst_QFile::openStandardStreams() QCOMPARE( err.size(), (qint64)0 ); QVERIFY( err.isSequential() ); } +} +void tst_QFile::openStandardStreamsBufferedStreams() +{ +#if defined (Q_OS_WIN) || defined(Q_OS_SYMBIAN) + QSKIP("Unix only test.", SkipAll); +#endif // Using streams { QFile in; @@ -2853,6 +2896,12 @@ void tst_QFile::openStandardStreams() } } +void tst_QFile::openStandardStreams() +{ + openStandardStreamsFileDescriptors(); + openStandardStreamsBufferedStreams(); +} + void tst_QFile::writeNothing() { for (int i = 0; i < 3; ++i) { -- cgit v0.12 From adba8e01f0069d240bf0b97175f54e38271acd19 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 14 Dec 2009 16:37:31 +0100 Subject: QNAM Code: Do not re-abort or continue processing notifications. This should finally enable us to use DirectConnection in QNetworkReplyHandler of QtWebKit. Reviewed-by: thiago --- src/network/access/qnetworkreplyimpl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index c20812e..1667c10 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -273,7 +273,7 @@ void QNetworkReplyImplPrivate::handleNotifications() if (state != Working) return; - while (!current.isEmpty()) { + while (state == Working && !current.isEmpty()) { InternalNotifications notification = current.dequeue(); switch (notification) { case NotifyDownstreamReadyWrite: @@ -580,7 +580,7 @@ QNetworkReplyImpl::~QNetworkReplyImpl() void QNetworkReplyImpl::abort() { Q_D(QNetworkReplyImpl); - if (d->state == QNetworkReplyImplPrivate::Aborted) + if (d->state == QNetworkReplyImplPrivate::Finished || d->state == QNetworkReplyImplPrivate::Aborted) return; // stop both upload and download -- cgit v0.12 From 2ba459c2adcaa4d0f865956048ac2e24f3fe6924 Mon Sep 17 00:00:00 2001 From: mae Date: Mon, 14 Dec 2009 17:13:23 +0100 Subject: QPlainTextEdit scrolling issue with folded paragraphs With Qt Creator, we could reproduce scrolling problems when paragraphs were folded away. Effectively the first "visible" block could be an invisible one, resulting in firstVisibleBlock() returning something bogus. The result were drawing errors. Reviewed-by: con --- src/gui/widgets/qplaintextedit.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index 89fe7b8..028ffe8 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -684,8 +684,12 @@ void QPlainTextEditPrivate::ensureVisible(int position, bool center, bool forceC qreal h = center ? line.naturalTextRect().center().y() : line.naturalTextRect().bottom(); + QTextBlock previousVisibleBlock = block; while (h < height && block.previous().isValid()) { - block = block.previous(); + previousVisibleBlock = block; + do { + block = block.previous(); + } while (!block.isVisible() && block.previous().isValid()); h += q->blockBoundingRect(block).height(); } @@ -699,8 +703,8 @@ void QPlainTextEditPrivate::ensureVisible(int position, bool center, bool forceC ++l; } - if (block.next().isValid() && l >= lineCount) { - block = block.next(); + if (l >= lineCount) { + block = previousVisibleBlock; l = 0; } setTopBlock(block.blockNumber(), l); -- cgit v0.12 From 74bec871abb48baadf239fd12e77bb85924436a1 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 14 Dec 2009 15:10:33 +0100 Subject: Fix QMetaObject::connect and disconnect with "dynamic signals" QML might pass index that are larger that the method cound. We must not call QMetaObjectPrivate::originalClone in that case as this would read invalid memory Reviewed-by: brad --- src/corelib/kernel/qmetaobject.cpp | 1 + src/corelib/kernel/qobject.cpp | 43 +++++------ tests/auto/qobject/tst_qobject.cpp | 144 +++++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+), 20 deletions(-) diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 6e6da19..72d6786 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -2648,6 +2648,7 @@ const char* QMetaClassInfo::value() const */ int QMetaObjectPrivate::originalClone(const QMetaObject *mobj, int local_method_index) { + Q_ASSERT(local_method_index < get(mobj)->methodCount); int handle = get(mobj)->methodData + 5 * local_method_index; while (mobj->d.data[handle + 4] & MethodCloned) { Q_ASSERT(local_method_index > 0); diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 85915c2..4370ee0 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2850,6 +2850,27 @@ void QObject::disconnectNotify(const char *) { } +/* \internal + convert a signal index from the method range to the signal range + */ +static int methodIndexToSignalIndex(const QMetaObject *metaObject, int signal_index) +{ + if (signal_index < 0) + return signal_index; + while (metaObject && metaObject->methodOffset() > signal_index) + metaObject = metaObject->superClass(); + + if (metaObject) { + int signalOffset, methodOffset; + computeOffsets(metaObject, &signalOffset, &methodOffset); + if (signal_index < metaObject->methodCount()) + signal_index = QMetaObjectPrivate::originalClone(metaObject, signal_index - methodOffset) + signalOffset; + else + signal_index = signal_index - methodOffset + signalOffset; + } + return signal_index; +} + /*!\internal \a types is a 0-terminated vector of meta types for queued connections. @@ -2860,16 +2881,7 @@ void QObject::disconnectNotify(const char *) bool QMetaObject::connect(const QObject *sender, int signal_index, const QObject *receiver, int method_index, int type, int *types) { - if (signal_index > 0) { - const QMetaObject *mo = sender->metaObject(); - while (mo && mo->methodOffset() > signal_index) - mo = mo->superClass(); - if (mo) { - int signalOffset, methodOffset; - computeOffsets(mo, &signalOffset, &methodOffset); - signal_index = QMetaObjectPrivate::originalClone(mo, signal_index - methodOffset) + signalOffset; - } - } + signal_index = methodIndexToSignalIndex(sender->metaObject(), signal_index); return QMetaObjectPrivate::connect(sender, signal_index, receiver, method_index, type, types); } @@ -2938,16 +2950,7 @@ bool QMetaObjectPrivate::connect(const QObject *sender, int signal_index, bool QMetaObject::disconnect(const QObject *sender, int signal_index, const QObject *receiver, int method_index) { - if (signal_index > 0) { - const QMetaObject *mo = sender->metaObject(); - while (mo && mo->methodOffset() > signal_index) - mo = mo->superClass(); - if (mo) { - int signalOffset, methodOffset; - computeOffsets(mo, &signalOffset, &methodOffset); - signal_index = QMetaObjectPrivate::originalClone(mo, signal_index - methodOffset) + signalOffset; - } - } + signal_index = methodIndexToSignalIndex(sender->metaObject(), signal_index); return QMetaObjectPrivate::disconnect(sender, signal_index, receiver, method_index); } diff --git a/tests/auto/qobject/tst_qobject.cpp b/tests/auto/qobject/tst_qobject.cpp index a2524aa..75d7a0a 100644 --- a/tests/auto/qobject/tst_qobject.cpp +++ b/tests/auto/qobject/tst_qobject.cpp @@ -126,6 +126,7 @@ private slots: void deleteQObjectWhenDeletingEvent(); void overloads(); void isSignalConnected(); + void qMetaObjectConnect(); protected: }; @@ -3125,5 +3126,148 @@ void tst_QObject::isSignalConnected() QCOMPARE(o.rec, 2); } +void tst_QObject::qMetaObjectConnect() +{ + SenderObject *s = new SenderObject; + ReceiverObject *r1 = new ReceiverObject; + ReceiverObject *r2 = new ReceiverObject; + r1->reset(); + r2->reset(); + ReceiverObject::sequence = 0; + + int signal1Index = s->metaObject()->indexOfSignal("signal1()"); + int signal3Index = s->metaObject()->indexOfSignal("signal3()"); + int slot1Index = r1->metaObject()->indexOfSlot("slot1()"); + int slot2Index = r1->metaObject()->indexOfSlot("slot2()"); + int slot3Index = r1->metaObject()->indexOfSlot("slot3()"); + + QVERIFY(slot1Index > 0); + QVERIFY(slot2Index > 0); + QVERIFY(slot3Index > 0); + + QVERIFY( QMetaObject::connect( s, signal1Index, r1, slot1Index) ); + QVERIFY( QMetaObject::connect( s, signal3Index, r2, slot3Index) ); + QVERIFY( QMetaObject::connect( s, -1, r2, slot2Index) ); + + QCOMPARE( r1->count_slot1, 0 ); + QCOMPARE( r1->count_slot2, 0 ); + QCOMPARE( r1->count_slot3, 0 ); + QCOMPARE( r2->count_slot1, 0 ); + QCOMPARE( r2->count_slot2, 0 ); + QCOMPARE( r2->count_slot3, 0 ); + + s->emitSignal1(); + + QCOMPARE( r1->count_slot1, 1 ); + QCOMPARE( r1->count_slot2, 0 ); + QCOMPARE( r1->count_slot3, 0 ); + QCOMPARE( r2->count_slot1, 0 ); + QCOMPARE( r2->count_slot2, 1 ); + QCOMPARE( r2->count_slot3, 0 ); + + s->emitSignal2(); + s->emitSignal3(); + s->emitSignal4(); + + QCOMPARE( r1->count_slot1, 1 ); + QCOMPARE( r1->count_slot2, 0 ); + QCOMPARE( r1->count_slot3, 0 ); + QCOMPARE( r2->count_slot1, 0 ); + QCOMPARE( r2->count_slot2, 4 ); + QCOMPARE( r2->count_slot3, 1 ); + + QVERIFY( QMetaObject::disconnect( s, signal1Index, r1, slot1Index) ); + QVERIFY( QMetaObject::disconnect( s, signal3Index, r2, slot3Index) ); + QVERIFY( QMetaObject::disconnect( s, -1, r2, slot2Index) ); + + s->emitSignal1(); + s->emitSignal2(); + s->emitSignal3(); + s->emitSignal4(); + + QCOMPARE( r1->count_slot1, 1 ); + QCOMPARE( r1->count_slot2, 0 ); + QCOMPARE( r1->count_slot3, 0 ); + QCOMPARE( r2->count_slot1, 0 ); + QCOMPARE( r2->count_slot2, 4 ); + QCOMPARE( r2->count_slot3, 1 ); + + //some "dynamic" signal + QVERIFY( QMetaObject::connect( s, s->metaObject()->methodOffset() + 20, r1, slot3Index) ); + QVERIFY( QMetaObject::connect( s, s->metaObject()->methodOffset() + 35, r2, slot1Index) ); + QVERIFY( QMetaObject::connect( s, -1, r1, slot2Index) ); + + r1->reset(); + r2->reset(); + + void *args[] = { 0 , 0 }; + QMetaObject::activate(s, s->metaObject()->methodOffset() + 20, args); + QMetaObject::activate(s, s->metaObject()->methodOffset() + 48, args); + QCOMPARE( r1->count_slot1, 0 ); + QCOMPARE( r1->count_slot2, 2 ); + QCOMPARE( r1->count_slot3, 1 ); + QCOMPARE( r2->count_slot1, 0 ); + QCOMPARE( r2->count_slot2, 0 ); + QCOMPARE( r2->count_slot3, 0 ); + + QMetaObject::activate(s, s->metaObject()->methodOffset() + 35, args); + s->emitSignal1(); + s->emitSignal2(); + + QCOMPARE( r1->count_slot1, 0 ); + QCOMPARE( r1->count_slot2, 5 ); + QCOMPARE( r1->count_slot3, 1 ); + QCOMPARE( r2->count_slot1, 1 ); + QCOMPARE( r2->count_slot2, 0 ); + QCOMPARE( r2->count_slot3, 0 ); + + delete s; + r1->reset(); + r2->reset(); + +#define SIGNAL_INDEX(S) obj1.metaObject()->indexOfSignal(QMetaObject::normalizedSignature(#S)) + OverloadObject obj1; + QObject obj2, obj3; + + QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(int)) , r1, slot1Index); + QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(QObject *, QObject *, QObject *)) , r2, slot1Index); + + QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(QObject *, QObject *, QObject *, QObject *)) , r1, slot2Index); + QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(QObject *)) , r2, slot2Index); + QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(int, int)) , r1, slot3Index); + + emit obj1.sig(0.5); //connected to nothing + emit obj1.sig(1, 'a'); //connected to nothing + QCOMPARE( r1->count_slot1, 0 ); + QCOMPARE( r1->count_slot2, 0 ); + QCOMPARE( r1->count_slot3, 0 ); + QCOMPARE( r2->count_slot1, 0 ); + QCOMPARE( r2->count_slot2, 0 ); + QCOMPARE( r2->count_slot3, 0 ); + + emit obj1.sig(1); //this signal is connected + emit obj1.sig(&obj2); + + QCOMPARE( r1->count_slot1, 1 ); + QCOMPARE( r1->count_slot2, 0 ); + QCOMPARE( r1->count_slot3, 1 ); + QCOMPARE( r2->count_slot1, 0 ); + QCOMPARE( r2->count_slot2, 1 ); + QCOMPARE( r2->count_slot3, 0 ); + + emit obj1.sig(&obj2, &obj3); //this signal is connected + + QCOMPARE( r1->count_slot1, 1 ); + QCOMPARE( r1->count_slot2, 1 ); + QCOMPARE( r1->count_slot3, 1 ); + QCOMPARE( r2->count_slot1, 1 ); + QCOMPARE( r2->count_slot2, 1 ); + QCOMPARE( r2->count_slot3, 0 ); + + delete r1; + delete r2; + +} + QTEST_MAIN(tst_QObject) #include "tst_qobject.moc" -- cgit v0.12 From 2fe3395812b6497e7151e556686a82cfd763f243 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 14 Dec 2009 19:51:13 +0100 Subject: Doc: Minor fixes to language. Reviewed-by: Trust Me --- src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp index 1bdc3ed..88b7271 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp @@ -3407,9 +3407,9 @@ quint64 QWebPage::bytesReceived() const /*! \fn void QWebPage::unsupportedContent(QNetworkReply *reply) - This signals is emitted when webkit cannot handle a link the user navigated to. + This signal is emitted when WebKit cannot handle a link the user navigated to. - At signal emissions time the meta data of the QNetworkReply \a reply is available. + At signal emission time the meta-data of the QNetworkReply \a reply is available. \note This signal is only emitted if the forwardUnsupportedContent property is set to true. -- cgit v0.12 From ad4ca2152c161f7023e5febcf9e90c0652b8e57d Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 14 Dec 2009 19:54:33 +0100 Subject: Doc: Fixed an image reference. Reviewed-by: Trust Me --- src/gui/kernel/qevent.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index c4a25e1..3579c79 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -409,7 +409,7 @@ QMouseEventEx::~QMouseEventEx() consider a top-level window A containing a child B which in turn contains a child C (all with mouse tracking enabled): - \image hoverEvents.png + \image hoverevents.png Now, if you move the cursor from the top to the bottom in the middle of A, you will get the following QEvent::MouseMove events: @@ -432,7 +432,7 @@ QMouseEventEx::~QMouseEventEx() \o A::HoverMove, B::HoverMove \o A::HoverMove, B::HoverMove, C::HoverMove \endlist - + */ /*! -- cgit v0.12 From cd0c4934ed60a3eae12d85d93aa950e9296cdb83 Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Mon, 14 Dec 2009 21:22:58 +0100 Subject: Change some examples of Webkit to create the mainwindow on the stack --- examples/webkit/fancybrowser/main.cpp | 4 ++-- examples/webkit/googlechat/main.cpp | 4 ++-- examples/webkit/previewer/main.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/webkit/fancybrowser/main.cpp b/examples/webkit/fancybrowser/main.cpp index 7f3c983..7ca862d 100644 --- a/examples/webkit/fancybrowser/main.cpp +++ b/examples/webkit/fancybrowser/main.cpp @@ -45,7 +45,7 @@ int main(int argc, char * argv[]) { QApplication app(argc, argv); - MainWindow *browser = new MainWindow; - browser->show(); + MainWindow browser; + browser.show(); return app.exec(); } diff --git a/examples/webkit/googlechat/main.cpp b/examples/webkit/googlechat/main.cpp index 6b5e11f..ca94131 100644 --- a/examples/webkit/googlechat/main.cpp +++ b/examples/webkit/googlechat/main.cpp @@ -49,7 +49,7 @@ int main(int argc, char * argv[]) QNetworkProxyFactory::setUseSystemConfiguration(true); - GoogleChat *chat = new GoogleChat; - chat->show(); + GoogleChat chat; + chat.show(); return app.exec(); } diff --git a/examples/webkit/previewer/main.cpp b/examples/webkit/previewer/main.cpp index 183b03f..1c80c19 100644 --- a/examples/webkit/previewer/main.cpp +++ b/examples/webkit/previewer/main.cpp @@ -46,8 +46,8 @@ int main(int argc, char * argv[]) { QApplication app(argc, argv); - MainWindow *mainWindow = new MainWindow; - mainWindow->show(); + MainWindow mainWindow; + mainWindow.show(); return app.exec(); } //! [0] -- cgit v0.12 From 82ec0a6c26c683dedd20fb6dd3923dce98c3f7e3 Mon Sep 17 00:00:00 2001 From: Bill King Date: Tue, 15 Dec 2009 13:09:12 +1000 Subject: (ODBC) Fixes segfault when error string is larger than 256 chars. SqlServer can throw custom error messages (via RaiseError) that can be up to 8000 chars long. Fixed this with a pre-query as to the length of the error string, then allocating enough space to retrieve the whole error string at once. Task-number: QTBUG-6618 Reviewed-by: Derick Hawcroft --- src/sql/drivers/odbc/qsql_odbc.cpp | 23 +++++++++++++++++------ tests/auto/qsqlquery/tst_qsqlquery.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index e686873..fdf0c2c 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -172,28 +172,39 @@ static QString qWarnODBCHandle(int handleType, SQLHANDLE handle, int *nativeCode SQLSMALLINT msgLen = 0; SQLRETURN r = SQL_NO_DATA; SQLTCHAR state_[SQL_SQLSTATE_SIZE+1]; - SQLTCHAR description_[SQL_MAX_MESSAGE_LENGTH]; + QVarLengthArray description_(SQL_MAX_MESSAGE_LENGTH); QString result; int i = 1; description_[0] = 0; + r = SQLGetDiagRec(handleType, + handle, + i, + state_, + &nativeCode_, + 0, + NULL, + &msgLen); + if(r == SQL_NO_DATA) + return QString(); + description_.resize(msgLen+1); do { r = SQLGetDiagRec(handleType, handle, i, - (SQLTCHAR*)state_, + state_, &nativeCode_, - (SQLTCHAR*)description_, - SQL_MAX_MESSAGE_LENGTH, /* in bytes, not in characters */ + description_.data(), + description_.size(), &msgLen); if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { if (nativeCode) *nativeCode = nativeCode_; QString tmpstore; #ifdef UNICODE - tmpstore = QString((const QChar*)description_, msgLen); + tmpstore = QString((const QChar*)description_.data(), msgLen); #else - tmpstore = QString::fromLocal8Bit((const char*)description_, msgLen); + tmpstore = QString::fromLocal8Bit((const char*)description_.data(), msgLen); #endif if(result != tmpstore) { if(!result.isEmpty()) diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index a8908fd..2a55c32 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -201,6 +201,8 @@ private slots: void QTBUG_5251(); void QTBUG_6421_data() { generic_data("QOCI"); } void QTBUG_6421(); + void QTBUG_6618_data() { generic_data("QODBC"); } + void QTBUG_6618(); private: // returns all database connections @@ -2961,5 +2963,27 @@ void tst_QSqlQuery::QTBUG_6421() QCOMPARE(q.value(0).toString(), QLatin1String("\"COL3\"")); } +void tst_QSqlQuery::QTBUG_6618() +{ + QFETCH( QString, dbName ); + QSqlDatabase db = QSqlDatabase::database( dbName ); + CHECK_DATABASE( db ); + if (!tst_Databases::isSqlServer( db )) + QSKIP("SQL Server specific test", SkipSingle); + + QSqlQuery q(db); + q.exec( "drop procedure " + qTableName( "tst_raiseError" ) ); //non-fatal + QString errorString; + for (int i=0;i<110;i++) + errorString+="reallylong"; + errorString+=" error"; + QVERIFY_SQL( q, exec("create procedure " + qTableName( "tst_raiseError" ) + " as\n" + "begin\n" + " raiserror('" + errorString + "', 16, 1)\n" + "end\n" )); + q.exec( "{call " + qTableName( "tst_raiseError" ) + "}" ); + QVERIFY(q.lastError().text().contains(errorString)); +} + QTEST_MAIN( tst_QSqlQuery ) #include "tst_qsqlquery.moc" -- cgit v0.12 From c5ae0ffd52ee3f2964404bf85dee55712fb6bd8c Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Tue, 15 Dec 2009 11:11:20 +1000 Subject: Add an image allocation pool to the OpenVG paint engine Some OpenVG GPU's have limitations on the amount of memory available to create VGImage's. When the memory runs out, vgCreateImage() will fail. This change introduces QVGImagePool, which keeps track of all QVGPixmapData image allocations and ejects least-recently-used pixmaps when GPU memory is exhausted. Task-number: QT-2554 Reviewed-by: trustme --- src/openvg/openvg.pro | 6 +- src/openvg/qpaintengine_vg.cpp | 16 ++- src/openvg/qpixmapdata_vg.cpp | 92 +++++++++------ src/openvg/qpixmapdata_vg_p.h | 17 ++- src/openvg/qpixmapfilter_vg.cpp | 25 +++-- src/openvg/qvgimagepool.cpp | 215 ++++++++++++++++++++++++++++++++++++ src/openvg/qvgimagepool_p.h | 157 ++++++++++++++++++++++++++ src/openvg/qwindowsurface_vgegl.cpp | 4 + 8 files changed, 479 insertions(+), 53 deletions(-) create mode 100644 src/openvg/qvgimagepool.cpp create mode 100644 src/openvg/qvgimagepool_p.h diff --git a/src/openvg/openvg.pro b/src/openvg/openvg.pro index 8927c4c..c8c9917 100644 --- a/src/openvg/openvg.pro +++ b/src/openvg/openvg.pro @@ -16,11 +16,13 @@ HEADERS += \ qpaintengine_vg_p.h \ qpixmapdata_vg_p.h \ qpixmapfilter_vg_p.h \ - qvgcompositionhelper_p.h + qvgcompositionhelper_p.h \ + qvgimagepool_p.h SOURCES += \ qpaintengine_vg.cpp \ qpixmapdata_vg.cpp \ - qpixmapfilter_vg.cpp + qpixmapfilter_vg.cpp \ + qvgimagepool.cpp contains(QT_CONFIG, egl) { HEADERS += \ diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index 6b829dd..04fee08 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -43,6 +43,7 @@ #include "qpixmapdata_vg_p.h" #include "qpixmapfilter_vg_p.h" #include "qvgcompositionhelper_p.h" +#include "qvgimagepool_p.h" #if !defined(QT_NO_EGL) #include #include "qwindowsurface_vgegl_p.h" @@ -1018,7 +1019,7 @@ static VGImage toVGImage const uchar *pixels = img.bits(); - VGImage vgImg = vgCreateImage + VGImage vgImg = QVGImagePool::instance()->createPermanentImage (format, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER); vgImageSubData (vgImg, pixels, img.bytesPerLine(), format, 0, 0, @@ -1063,7 +1064,7 @@ static VGImage toVGImageSubRect const uchar *pixels = img.bits() + bpp * sr.x() + img.bytesPerLine() * sr.y(); - VGImage vgImg = vgCreateImage + VGImage vgImg = QVGImagePool::instance()->createPermanentImage (format, sr.width(), sr.height(), VG_IMAGE_QUALITY_FASTER); vgImageSubData (vgImg, pixels, img.bytesPerLine(), format, 0, 0, @@ -1084,7 +1085,7 @@ static VGImage toVGImageWithOpacity(const QImage & image, qreal opacity) const uchar *pixels = img.bits(); - VGImage vgImg = vgCreateImage + VGImage vgImg = QVGImagePool::instance()->createPermanentImage (VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER); vgImageSubData (vgImg, pixels, img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, @@ -1106,7 +1107,7 @@ static VGImage toVGImageWithOpacitySubRect const uchar *pixels = img.bits(); - VGImage vgImg = vgCreateImage + VGImage vgImg = QVGImagePool::instance()->createPermanentImage (VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER); vgImageSubData (vgImg, pixels, img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, @@ -1194,6 +1195,12 @@ VGPaintType QVGPaintEnginePrivate::setBrush if (pd->classId() == QPixmapData::OpenVGClass) { QVGPixmapData *vgpd = static_cast(pd); vgImg = vgpd->toVGImage(); + + // We don't want the pool to reclaim this image + // because we cannot predict when the paint object + // will stop using it. Replacing the image with + // new data will make the paint object invalid. + vgpd->detachImageFromPool(); } else { vgImg = toVGImage(*(pd->buffer())); deref = true; @@ -1201,6 +1208,7 @@ VGPaintType QVGPaintEnginePrivate::setBrush } else if (pd->classId() == QPixmapData::OpenVGClass) { QVGPixmapData *vgpd = static_cast(pd); vgImg = vgpd->toVGImage(opacity); + vgpd->detachImageFromPool(); } else { vgImg = toVGImageWithOpacity(*(pd->buffer()), opacity); deref = true; diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index af6f0f0..358ec4d 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -43,6 +43,7 @@ #include "qpaintengine_vg_p.h" #include #include "qvg_p.h" +#include "qvgimagepool_p.h" #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE #include @@ -63,6 +64,8 @@ QVGPixmapData::QVGPixmapData(PixelType type) vgImageOpacity = VG_INVALID_HANDLE; cachedOpacity = 1.0f; recreate = true; + inImagePool = false; + inLRU = false; #if !defined(QT_NO_EGL) context = 0; qt_vg_register_pixmap(this); @@ -78,32 +81,43 @@ QVGPixmapData::~QVGPixmapData() #endif } +void QVGPixmapData::destroyImages() +{ + if (inImagePool) { + QVGImagePool *pool = QVGImagePool::instance(); + if (vgImage != VG_INVALID_HANDLE) + pool->releaseImage(this, vgImage); + if (vgImageOpacity != VG_INVALID_HANDLE) + pool->releaseImage(this, vgImageOpacity); + } else { + if (vgImage != VG_INVALID_HANDLE) + vgDestroyImage(vgImage); + if (vgImageOpacity != VG_INVALID_HANDLE) + vgDestroyImage(vgImageOpacity); + } + vgImage = VG_INVALID_HANDLE; + vgImageOpacity = VG_INVALID_HANDLE; + inImagePool = false; +} + void QVGPixmapData::destroyImageAndContext() { if (vgImage != VG_INVALID_HANDLE) { // We need to have a context current to destroy the image. #if !defined(QT_NO_EGL) if (context->isCurrent()) { - vgDestroyImage(vgImage); - if (vgImageOpacity != VG_INVALID_HANDLE) - vgDestroyImage(vgImageOpacity); + destroyImages(); } else { // We don't currently have a widget surface active, but we // need a surface to make the context current. So use the // shared pbuffer surface instead. context->makeCurrent(qt_vg_shared_surface()); - vgDestroyImage(vgImage); - if (vgImageOpacity != VG_INVALID_HANDLE) - vgDestroyImage(vgImageOpacity); + destroyImages(); context->lazyDoneCurrent(); } #else - vgDestroyImage(vgImage); - if (vgImageOpacity != VG_INVALID_HANDLE) - vgDestroyImage(vgImageOpacity); + destroyImages(); #endif - vgImage = VG_INVALID_HANDLE; - vgImageOpacity = VG_INVALID_HANDLE; } #if !defined(QT_NO_EGL) if (context) { @@ -234,26 +248,22 @@ VGImage QVGPixmapData::toVGImage() context = qt_vg_create_context(0, QInternal::Pixmap); #endif - if (recreate && prevSize != QSize(w, h)) { - if (vgImage != VG_INVALID_HANDLE) { - vgDestroyImage(vgImage); - vgImage = VG_INVALID_HANDLE; - } - if (vgImageOpacity != VG_INVALID_HANDLE) { - vgDestroyImage(vgImageOpacity); - vgImageOpacity = VG_INVALID_HANDLE; - } - } else if (recreate) { + if (recreate && prevSize != QSize(w, h)) + destroyImages(); + else if (recreate) cachedOpacity = -1.0f; // Force opacity image to be refreshed later. - } if (vgImage == VG_INVALID_HANDLE) { - vgImage = vgCreateImage - (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER); + vgImage = QVGImagePool::instance()->createImageForPixmap + (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER, this); // Bail out if we run out of GPU memory - try again next time. if (vgImage == VG_INVALID_HANDLE) return VG_INVALID_HANDLE; + + inImagePool = true; + } else if (inImagePool) { + QVGImagePool::instance()->useImage(this); } if (!source.isNull() && recreate) { @@ -282,8 +292,13 @@ VGImage QVGPixmapData::toVGImage(qreal opacity) // Create an alternative image for the selected opacity. if (vgImageOpacity == VG_INVALID_HANDLE || cachedOpacity != opacity) { if (vgImageOpacity == VG_INVALID_HANDLE) { - vgImageOpacity = vgCreateImage - (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER); + if (inImagePool) { + vgImageOpacity = QVGImagePool::instance()->createImageForPixmap + (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER, this); + } else { + vgImageOpacity = vgCreateImage + (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER); + } // Bail out if we run out of GPU memory - try again next time. if (vgImageOpacity == VG_INVALID_HANDLE) @@ -308,6 +323,14 @@ VGImage QVGPixmapData::toVGImage(qreal opacity) #endif } +void QVGPixmapData::detachImageFromPool() +{ + if (inImagePool) { + QVGImagePool::instance()->detachImage(this); + inImagePool = false; + } +} + void QVGPixmapData::hibernate() { // If the image was imported (e.g, from an SgImage under Symbian), @@ -319,6 +342,14 @@ void QVGPixmapData::hibernate() destroyImageAndContext(); } +void QVGPixmapData::reclaimImages() +{ + if (!inImagePool) + return; + forceToImage(); + destroyImages(); +} + extern int qt_defaultDpiX(); extern int qt_defaultDpiY(); @@ -411,14 +442,7 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type) if (!context) context = qt_vg_create_context(0, QInternal::Pixmap); - if (vgImage != VG_INVALID_HANDLE) { - vgDestroyImage(vgImage); - vgImage = VG_INVALID_HANDLE; - } - if (vgImageOpacity != VG_INVALID_HANDLE) { - vgDestroyImage(vgImageOpacity); - vgImageOpacity = VG_INVALID_HANDLE; - } + destroyImages(); prevSize = QSize(); TInt err = 0; diff --git a/src/openvg/qpixmapdata_vg_p.h b/src/openvg/qpixmapdata_vg_p.h index c0bb098..4ff95c1 100644 --- a/src/openvg/qpixmapdata_vg_p.h +++ b/src/openvg/qpixmapdata_vg_p.h @@ -63,6 +63,7 @@ class RSGImage; QT_BEGIN_NAMESPACE class QEglContext; +class QVGImagePool; #if !defined(QT_NO_EGL) class QVGPixmapData; @@ -101,6 +102,9 @@ public: // Return the VGImage form for a specific opacity setting. virtual VGImage toVGImage(qreal opacity); + // Detach this image from the image pool. + virtual void detachImageFromPool(); + // Release the VG resources associated with this pixmap and copy // the pixmap's contents out of the GPU back into main memory. // The VG resource will be automatically recreated the next time @@ -109,6 +113,10 @@ public: // process via a SgImage). virtual void hibernate(); + // Called when the QVGImagePool wants to reclaim this pixmap's + // VGImage objects to reuse storage. + virtual void reclaimImages(); + QSize size() const { return QSize(w, h); } #if defined(Q_OS_SYMBIAN) @@ -123,8 +131,13 @@ protected: void cleanup(); #endif -#if !defined(QT_NO_EGL) private: + QVGPixmapData *nextLRU; + QVGPixmapData *prevLRU; + bool inLRU; + friend class QVGImagePool; + +#if !defined(QT_NO_EGL) QVGPixmapData *next; QVGPixmapData *prev; @@ -140,6 +153,7 @@ protected: qreal cachedOpacity; mutable QImage source; mutable bool recreate; + bool inImagePool; #if !defined(QT_NO_EGL) mutable QEglContext *context; #endif @@ -148,6 +162,7 @@ protected: QImage::Format sourceFormat() const; void destroyImageAndContext(); + void destroyImages(); }; QT_END_NAMESPACE diff --git a/src/openvg/qpixmapfilter_vg.cpp b/src/openvg/qpixmapfilter_vg.cpp index e17c728..aa526ed 100644 --- a/src/openvg/qpixmapfilter_vg.cpp +++ b/src/openvg/qpixmapfilter_vg.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qpixmapfilter_vg_p.h" +#include "qvgimagepool_p.h" #include #include @@ -82,9 +83,9 @@ void QVGPixmapConvolutionFilter::draw return; QSize size = pd->size(); - VGImage dstImage = vgCreateImage + VGImage dstImage = QVGImagePool::instance()->createTemporaryImage (VG_sARGB_8888_PRE, size.width(), size.height(), - VG_IMAGE_QUALITY_FASTER); + VG_IMAGE_QUALITY_FASTER, pd); if (dstImage == VG_INVALID_HANDLE) return; @@ -124,7 +125,7 @@ void QVGPixmapConvolutionFilter::draw if(child != dstImage) vgDestroyImage(child); - vgDestroyImage(dstImage); + QVGImagePool::instance()->releaseImage(0, dstImage); } QVGPixmapColorizeFilter::QVGPixmapColorizeFilter() @@ -155,9 +156,9 @@ void QVGPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const return; QSize size = pd->size(); - VGImage dstImage = vgCreateImage + VGImage dstImage = QVGImagePool::instance()->createTemporaryImage (VG_sARGB_8888_PRE, size.width(), size.height(), - VG_IMAGE_QUALITY_FASTER); + VG_IMAGE_QUALITY_FASTER, pd); if (dstImage == VG_INVALID_HANDLE) return; @@ -217,7 +218,7 @@ void QVGPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const if(child != dstImage) vgDestroyImage(child); - vgDestroyImage(dstImage); + QVGImagePool::instance()->releaseImage(0, dstImage); } QVGPixmapDropShadowFilter::QVGPixmapDropShadowFilter() @@ -248,9 +249,9 @@ void QVGPixmapDropShadowFilter::draw(QPainter *painter, const QPointF &dest, con return; QSize size = pd->size(); - VGImage dstImage = vgCreateImage + VGImage dstImage = QVGImagePool::instance()->createTemporaryImage (VG_A_8, size.width(), size.height(), - VG_IMAGE_QUALITY_FASTER); + VG_IMAGE_QUALITY_FASTER, pd); if (dstImage == VG_INVALID_HANDLE) return; @@ -282,7 +283,7 @@ void QVGPixmapDropShadowFilter::draw(QPainter *painter, const QPointF &dest, con if(child != dstImage) vgDestroyImage(child); - vgDestroyImage(dstImage); + QVGImagePool::instance()->releaseImage(0, dstImage); // Now draw the actual pixmap over the top. painter->drawPixmap(dest, src, srect); @@ -316,9 +317,9 @@ void QVGPixmapBlurFilter::draw(QPainter *painter, const QPointF &dest, const QPi return; QSize size = pd->size(); - VGImage dstImage = vgCreateImage + VGImage dstImage = QVGImagePool::instance()->createTemporaryImage (VG_sARGB_8888_PRE, size.width(), size.height(), - VG_IMAGE_QUALITY_FASTER); + VG_IMAGE_QUALITY_FASTER, pd); if (dstImage == VG_INVALID_HANDLE) return; @@ -347,7 +348,7 @@ void QVGPixmapBlurFilter::draw(QPainter *painter, const QPointF &dest, const QPi if(child != dstImage) vgDestroyImage(child); - vgDestroyImage(dstImage); + QVGImagePool::instance()->releaseImage(0, dstImage); } #endif diff --git a/src/openvg/qvgimagepool.cpp b/src/openvg/qvgimagepool.cpp new file mode 100644 index 0000000..93e6e03 --- /dev/null +++ b/src/openvg/qvgimagepool.cpp @@ -0,0 +1,215 @@ +/**************************************************************************** +** +** 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 QtOpenVG 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 "qvgimagepool_p.h" +#include "qpixmapdata_vg_p.h" + +QT_BEGIN_NAMESPACE + +static QVGImagePool *qt_vg_image_pool = 0; + +class QVGImagePoolPrivate +{ +public: + QVGImagePoolPrivate() : lruFirst(0), lruLast(0) {} + + QVGPixmapData *lruFirst; + QVGPixmapData *lruLast; +}; + +QVGImagePool::QVGImagePool() + : d_ptr(new QVGImagePoolPrivate()) +{ +} + +QVGImagePool::~QVGImagePool() +{ +} + +QVGImagePool *QVGImagePool::instance() +{ + if (!qt_vg_image_pool) + qt_vg_image_pool = new QVGImagePool(); + return qt_vg_image_pool; +} + +void QVGImagePool::setImagePool(QVGImagePool *pool) +{ + if (qt_vg_image_pool != pool) + delete qt_vg_image_pool; + qt_vg_image_pool = pool; +} + +VGImage QVGImagePool::createTemporaryImage(VGImageFormat format, + VGint width, VGint height, + VGbitfield allowedQuality, + QVGPixmapData *keepData) +{ + VGImage image; + do { + image = vgCreateImage(format, width, height, allowedQuality); + if (image != VG_INVALID_HANDLE) + return image; + } while (reclaimSpace(format, width, height, keepData)); + qWarning("QVGImagePool: cannot reclaim sufficient space for a %dx%d temporary image", + width, height); + return VG_INVALID_HANDLE; +} + +VGImage QVGImagePool::createImageForPixmap(VGImageFormat format, + VGint width, VGint height, + VGbitfield allowedQuality, + QVGPixmapData *data) +{ + VGImage image; + do { + image = vgCreateImage(format, width, height, allowedQuality); + if (image != VG_INVALID_HANDLE) { + if (data) + moveToHeadOfLRU(data); + return image; + } + } while (reclaimSpace(format, width, height, data)); + qWarning("QVGImagePool: cannot reclaim sufficient space for a %dx%d pixmap", + width, height); + return VG_INVALID_HANDLE; +} + +VGImage QVGImagePool::createPermanentImage(VGImageFormat format, + VGint width, VGint height, + VGbitfield allowedQuality) +{ + VGImage image; + do { + image = vgCreateImage(format, width, height, allowedQuality); + if (image != VG_INVALID_HANDLE) + return image; + } while (reclaimSpace(format, width, height, 0)); + qWarning("QVGImagePool: cannot reclaim sufficient space for a %dx%d image", + width, height); + return VG_INVALID_HANDLE; +} + +void QVGImagePool::releaseImage(QVGPixmapData *data, VGImage image) +{ + // Very simple strategy at the moment: just destroy the image. + if (data) + removeFromLRU(data); + vgDestroyImage(image); +} + +void QVGImagePool::useImage(QVGPixmapData *data) +{ + moveToHeadOfLRU(data); +} + +void QVGImagePool::detachImage(QVGPixmapData *data) +{ + removeFromLRU(data); +} + +bool QVGImagePool::reclaimSpace(VGImageFormat format, + VGint width, VGint height, + QVGPixmapData *data) +{ + Q_UNUSED(format); // For future use in picking the best image to eject. + Q_UNUSED(width); + Q_UNUSED(height); + + if (data) + moveToHeadOfLRU(data); + + QVGPixmapData *lrudata = pixmapLRU(); + if (lrudata && lrudata != data) { + lrudata->reclaimImages(); + return true; + } + + return false; +} + +void QVGImagePool::hibernate() +{ + // Nothing to do here at the moment since the pool does not + // retain VGImage's after they have been released. +} + +void QVGImagePool::moveToHeadOfLRU(QVGPixmapData *data) +{ + Q_D(QVGImagePool); + if (data->inLRU) { + if (!data->prevLRU) + return; // Already at the head of the list. + removeFromLRU(data); + } + data->inLRU = true; + data->nextLRU = d->lruFirst; + data->prevLRU = 0; + if (d->lruFirst) + d->lruFirst->prevLRU = data; + else + d->lruLast = data; + d->lruFirst = data; +} + +void QVGImagePool::removeFromLRU(QVGPixmapData *data) +{ + Q_D(QVGImagePool); + if (!data->inLRU) + return; + if (data->nextLRU) + data->nextLRU->prevLRU = data->prevLRU; + else + d->lruLast = data->prevLRU; + if (data->prevLRU) + data->prevLRU->nextLRU = data->nextLRU; + else + d->lruFirst = data->nextLRU; + data->inLRU = false; +} + +QVGPixmapData *QVGImagePool::pixmapLRU() +{ + Q_D(QVGImagePool); + return d->lruLast; +} + +QT_END_NAMESPACE diff --git a/src/openvg/qvgimagepool_p.h b/src/openvg/qvgimagepool_p.h new file mode 100644 index 0000000..66a4998 --- /dev/null +++ b/src/openvg/qvgimagepool_p.h @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** 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 QtOpenVG 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 QVGIMAGEPOOL_P_H +#define QVGIMAGEPOOL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qvg.h" +#include + +QT_BEGIN_NAMESPACE + +class QVGPixmapData; +class QVGImagePoolPrivate; + +class Q_OPENVG_EXPORT QVGImagePool +{ +public: + QVGImagePool(); + virtual ~QVGImagePool(); + + static QVGImagePool *instance(); + + // This function can be used from system-specific graphics system + // plugins to alter the image allocation strategy. + static void setImagePool(QVGImagePool *pool); + + // Create a new VGImage from the pool with the specified parameters + // that is not associated with a pixmap. The VGImage is returned to + // the pool when releaseImage() is called. + // + // This function will call reclaimSpace() when vgCreateImage() fails. + // + // This function is typically called when allocating temporary + // VGImage's for pixmap filters. The "keepData" object will not + // be reclaimed if reclaimSpace() needs to be called. + virtual VGImage createTemporaryImage(VGImageFormat format, + VGint width, VGint height, + VGbitfield allowedQuality, + QVGPixmapData *keepData = 0); + + // Create a new VGImage with the specified parameters and associate + // it with "data". The QVGPixmapData will be notified when the + // VGImage needs to be reclaimed by the pool. + // + // This function will call reclaimSpace() when vgCreateImage() fails. + virtual VGImage createImageForPixmap(VGImageFormat format, + VGint width, VGint height, + VGbitfield allowedQuality, + QVGPixmapData *data); + + // Create a permanent VGImage with the specified parameters. + // If there is insufficient space for the vgCreateImage call, + // then this function will call reclaimSpace() and try again. + // + // The caller is responsible for calling vgDestroyImage() + // when it no longer needs the VGImage, as the image is not + // recorded in the image pool. + // + // This function is typically used for pattern brushes where + // the OpenVG engine is responsible for managing the lifetime + // of the VGImage, destroying it automatically when the brush + // is no longer in use. + virtual VGImage createPermanentImage(VGImageFormat format, + VGint width, VGint height, + VGbitfield allowedQuality); + + // Release a VGImage that is no longer required. + virtual void releaseImage(QVGPixmapData *data, VGImage image); + + // Notify the pool that a QVGPixmapData object is using + // an image again. This allows the pool to move the image + // within a least-recently-used list of QVGPixmapData objects. + virtual void useImage(QVGPixmapData *data); + + // Notify the pool that the VGImage's associated with a + // QVGPixmapData are being detached from the pool. The caller + // will become responsible for calling vgDestroyImage(). + virtual void detachImage(QVGPixmapData *data); + + // Reclaim space for an image allocation with the specified parameters. + // Returns true if space was reclaimed, or false if there is no + // further space that can be reclaimed. The "data" parameter + // indicates the pixmap that is trying to obtain space which should + // not itself be reclaimed. + virtual bool reclaimSpace(VGImageFormat format, + VGint width, VGint height, + QVGPixmapData *data); + + // Hibernate the image pool because the context is about to be + // destroyed. All VGImage's left in the pool should be released. + virtual void hibernate(); + +protected: + // Helper functions for managing the LRU list of QVGPixmapData objects. + void moveToHeadOfLRU(QVGPixmapData *data); + void removeFromLRU(QVGPixmapData *data); + QVGPixmapData *pixmapLRU(); + +private: + QScopedPointer d_ptr; + + Q_DECLARE_PRIVATE(QVGImagePool) + Q_DISABLE_COPY(QVGImagePool) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/openvg/qwindowsurface_vgegl.cpp b/src/openvg/qwindowsurface_vgegl.cpp index 1571083..bda6096 100644 --- a/src/openvg/qwindowsurface_vgegl.cpp +++ b/src/openvg/qwindowsurface_vgegl.cpp @@ -42,6 +42,7 @@ #include "qwindowsurface_vgegl_p.h" #include "qpaintengine_vg_p.h" #include "qpixmapdata_vg_p.h" +#include "qvgimagepool_p.h" #include "qvg_p.h" #if !defined(QT_NO_EGL) @@ -360,6 +361,9 @@ void qt_vg_hibernate_pixmaps(QVGSharedContext *shared) pd = pd->next; } + // Hibernate any remaining VGImage's in the image pool. + QVGImagePool::instance()->hibernate(); + // Don't need the current context any more. shared->context->lazyDoneCurrent(); -- cgit v0.12 From 7a3c595421b98087da638a5e706320d0d936d828 Mon Sep 17 00:00:00 2001 From: Tristan Chabredier Date: Tue, 15 Dec 2009 10:20:29 +0100 Subject: Fix compilation on HP-UX 11.11. Error was: thread/qthread_unix.cpp: In static member function 'static int QThread::idealThreadCount()': thread/qthread_unix.cpp:325: error: aggregate 'pst_dynamic psd' has incomplete type and cannot be defined thread/qthread_unix.cpp:326: error: 'pstat_getdynamic' was not declared in this scope Task-number: QTBUG-6576 Reviewed-by: Thiago Macieira --- mkspecs/hpux-g++-64/qmake.conf | 4 ++-- mkspecs/hpux-g++-64/qplatformdefs.h | 2 +- src/corelib/thread/qthread_unix.cpp | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/mkspecs/hpux-g++-64/qmake.conf b/mkspecs/hpux-g++-64/qmake.conf index 38595c9..f76bd4e 100644 --- a/mkspecs/hpux-g++-64/qmake.conf +++ b/mkspecs/hpux-g++-64/qmake.conf @@ -15,7 +15,7 @@ QMAKE_LEX = flex QMAKE_LEXFLAGS = QMAKE_YACC = yacc QMAKE_YACCFLAGS = -d -QMAKE_CFLAGS = +DA2.0W +QMAKE_CFLAGS = QMAKE_CFLAGS_DEPS = -M QMAKE_CFLAGS_WARN_ON = -Wall -W QMAKE_CFLAGS_WARN_OFF = -w @@ -51,7 +51,7 @@ QMAKE_LINK = g++ QMAKE_LINK_SHLIB = g++ QMAKE_LINK_C = gcc QMAKE_LINK_C_SHLIB = gcc -QMAKE_LFLAGS = +DA2.0W -Wl,+s -lpthread +QMAKE_LFLAGS = -Wl,+s -lpthread QMAKE_LFLAGS_RELEASE = QMAKE_LFLAGS_DEBUG = QMAKE_LFLAGS_SHLIB = -fPIC -shared diff --git a/mkspecs/hpux-g++-64/qplatformdefs.h b/mkspecs/hpux-g++-64/qplatformdefs.h index a8d06d8..ac13799 100644 --- a/mkspecs/hpux-g++-64/qplatformdefs.h +++ b/mkspecs/hpux-g++-64/qplatformdefs.h @@ -145,7 +145,7 @@ #define QT_SIGNAL_ARGS int #define QT_SIGNAL_IGNORE SIG_IGN -#define QT_SOCKLEN_T int +#define QT_SOCKLEN_T socklen_t #endif // QPLATFORMDEFS_H diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index 21b5e65..0309c67 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -74,6 +74,10 @@ # endif #endif +#ifdef Q_OS_HPUX +#include +#endif + #if defined(Q_OS_MAC) # ifdef qDebug # define old_qDebug qDebug -- cgit v0.12 From 1f4a4cca0067b1d4a9784f00e41c3fc1aca1f712 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Mon, 14 Dec 2009 16:27:25 +0100 Subject: Optimisations to gesture event filtering. Now we don't filter some events through the gesture manager and use QMap instead of QHash, which seem to be a bit faster in our cases. Reviewed-by: Olivier Goffart --- src/gui/kernel/qapplication.cpp | 46 +++++++++++++++++++++++++++++++++----- src/gui/kernel/qgesturemanager.cpp | 42 +++++++++++++++++----------------- src/gui/kernel/qgesturemanager_p.h | 4 ++-- 3 files changed, 64 insertions(+), 28 deletions(-) diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 8c63968..bd13423 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -3629,12 +3629,46 @@ bool QApplication::notify(QObject *receiver, QEvent *e) // walk through parents and check for gestures if (qt_gestureManager) { - if (receiver->isWidgetType()) { - if (qt_gestureManager->filterEvent(static_cast(receiver), e)) - return true; - } else if (QGesture *gesture = qobject_cast(receiver)) { - if (qt_gestureManager->filterEvent(gesture, e)) - return true; + switch (e->type()) { + case QEvent::Paint: + case QEvent::MetaCall: + case QEvent::DeferredDelete: + case QEvent::DragEnter: case QEvent::DragMove: case QEvent::DragLeave: + case QEvent::Drop: case QEvent::DragResponse: + case QEvent::ChildAdded: case QEvent::ChildPolished: +#ifdef QT3_SUPPORT + case QEvent::ChildInsertedRequest: + case QEvent::ChildInserted: + case QEvent::LayoutHint: +#endif + case QEvent::ChildRemoved: + case QEvent::UpdateRequest: + case QEvent::UpdateLater: + case QEvent::AccessibilityPrepare: + case QEvent::LocaleChange: + case QEvent::Style: + case QEvent::IconDrag: + case QEvent::StyleChange: + case QEvent::AccessibilityHelp: + case QEvent::AccessibilityDescription: + case QEvent::GraphicsSceneDragEnter: + case QEvent::GraphicsSceneDragMove: + case QEvent::GraphicsSceneDragLeave: + case QEvent::GraphicsSceneDrop: + case QEvent::DynamicPropertyChange: + case QEvent::NetworkReplyUpdated: + break; + default: + if (receiver->isWidgetType()) { + if (qt_gestureManager->filterEvent(static_cast(receiver), e)) + return true; + } else { + // a special case for events that go to QGesture objects. + // We pass the object to the gesture manager and it'll figure + // out if it's QGesture or not. + if (qt_gestureManager->filterEvent(receiver, e)) + return true; + } } } diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index 192f9ac..d7cbebd 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -187,10 +187,8 @@ QGesture *QGestureManager::getState(QObject *object, QGestureRecognizer *recogni #endif } - QList states = - m_objectGestures.value(QGestureManager::ObjectGesture(object, type)); // check if the QGesture for this recognizer has already been created - foreach (QGesture *state, states) { + foreach (QGesture *state, m_objectGestures.value(QGestureManager::ObjectGesture(object, type))) { if (m_gestureToRecognizer.value(state) == recognizer) return state; } @@ -215,14 +213,13 @@ QGesture *QGestureManager::getState(QObject *object, QGestureRecognizer *recogni return state; } -bool QGestureManager::filterEventThroughContexts(const QMultiHash &contexts, QEvent *event) { QSet triggeredGestures; QSet finishedGestures; QSet newMaybeGestures; - QSet canceledGestures; QSet notGestures; // TODO: sort contexts by the gesture type and check if one of the contexts @@ -231,7 +228,7 @@ bool QGestureManager::filterEventThroughContexts(const QMultiHash::const_iterator ContextIterator; + typedef QMultiMap::const_iterator ContextIterator; for (ContextIterator cit = contexts.begin(), ce = contexts.end(); cit != ce; ++cit) { Qt::GestureType gestureType = cit.value(); QMap::const_iterator @@ -271,6 +268,9 @@ bool QGestureManager::filterEventThroughContexts(const QMultiHash startedGestures = triggeredGestures - m_activeGestures; triggeredGestures &= m_activeGestures; @@ -280,8 +280,7 @@ bool QGestureManager::filterEventThroughContexts(const QMultiHash activeToCancelGestures = m_activeGestures & notGestures; - canceledGestures += activeToCancelGestures; + QSet canceledGestures = m_activeGestures & notGestures; // start timers for new gestures in maybe state foreach (QGesture *state, newMaybeGestures) { @@ -449,14 +448,14 @@ void QGestureManager::cleanupGesturesForRemovedRecognizer(QGesture *gesture) // return true if accepted (consumed) bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) { - QSet types; - QMultiHash contexts; + QMap types; + QMultiMap contexts; QWidget *w = receiver; typedef QMap::const_iterator ContextIterator; if (!w->d_func()->gestureContext.isEmpty()) { for(ContextIterator it = w->d_func()->gestureContext.begin(), e = w->d_func()->gestureContext.end(); it != e; ++it) { - types.insert(it.key()); + types.insert(it.key(), 0); contexts.insertMulti(w, it.key()); } } @@ -468,7 +467,7 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) e = w->d_func()->gestureContext.end(); it != e; ++it) { if (!(it.value() & Qt::DontStartGestureOnChildren)) { if (!types.contains(it.key())) { - types.insert(it.key()); + types.insert(it.key(), 0); contexts.insertMulti(w, it.key()); } } @@ -477,20 +476,20 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) break; w = w->parentWidget(); } - return filterEventThroughContexts(contexts, event); + return contexts.isEmpty() ? false : filterEventThroughContexts(contexts, event); } #ifndef QT_NO_GRAPHICSVIEW bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event) { - QSet types; - QMultiHash contexts; + QMap types; + QMultiMap contexts; QGraphicsObject *item = receiver; if (!item->QGraphicsItem::d_func()->gestureContext.isEmpty()) { typedef QMap::const_iterator ContextIterator; for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(), e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) { - types.insert(it.key()); + types.insert(it.key(), 0); contexts.insertMulti(item, it.key()); } } @@ -503,20 +502,23 @@ bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event) e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) { if (!(it.value() & Qt::DontStartGestureOnChildren)) { if (!types.contains(it.key())) { - types.insert(it.key()); + types.insert(it.key(), 0); contexts.insertMulti(item, it.key()); } } } item = item->parentObject(); } - return filterEventThroughContexts(contexts, event); + return contexts.isEmpty() ? false : filterEventThroughContexts(contexts, event); } #endif -bool QGestureManager::filterEvent(QGesture *state, QEvent *event) +bool QGestureManager::filterEvent(QObject *receiver, QEvent *event) { - QMultiHash contexts; + if (!m_gestureToRecognizer.contains(static_cast(receiver))) + return false; + QGesture *state = static_cast(receiver); + QMultiMap contexts; contexts.insert(state, state->gestureType()); return filterEventThroughContexts(contexts, event); } diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h index 4efa10b..5329d1d 100644 --- a/src/gui/kernel/qgesturemanager_p.h +++ b/src/gui/kernel/qgesturemanager_p.h @@ -73,7 +73,7 @@ public: void unregisterGestureRecognizer(Qt::GestureType type); bool filterEvent(QWidget *receiver, QEvent *event); - bool filterEvent(QGesture *receiver, QEvent *event); + bool filterEvent(QObject *receiver, QEvent *event); #ifndef QT_NO_GRAPHICSVIEW bool filterEvent(QGraphicsObject *receiver, QEvent *event); #endif //QT_NO_GRAPHICSVIEW @@ -86,7 +86,7 @@ public: protected: void timerEvent(QTimerEvent *event); - bool filterEventThroughContexts(const QMultiHash &contexts, + bool filterEventThroughContexts(const QMultiMap &contexts, QEvent *event); private: -- cgit v0.12 From 44f7c1e097582a704a06ccbbf516536b88ddcd3a Mon Sep 17 00:00:00 2001 From: dka Date: Mon, 12 Oct 2009 16:25:23 +0300 Subject: Changes to support locale change event for symbian platform Subscribing to the locale change notification to be able to update the system locale whenever the user changes the current system locale. Also changed the initialization of the system locale to make construction of the QLocale object as lightweight as possible. So now the default contructor just creates a QLocale and QSystemLocale objects, but doesn't try to fill the cache in the latter with data from the system and postpones it until it is actually requested (most applications create QLocale objects on the stack and might not even use the data from the system locale, so we don't need to initialize system locale right away). Modified-by: axis Modified-by: Denis Dzyubenko Reviewed-by: Denis Dzyubenko Reviewed-by: axis --- src/corelib/kernel/qcore_symbian_p.h | 3 +- src/corelib/kernel/qcoreapplication.cpp | 10 +++ src/corelib/kernel/qcoreapplication.h | 4 ++ src/corelib/kernel/qcoreapplication_p.h | 4 ++ src/corelib/tools/qlocale.cpp | 43 +++++++++--- src/corelib/tools/qlocale_p.h | 5 +- src/corelib/tools/qlocale_symbian.cpp | 121 ++++++++++++++++++++++++++++++-- src/plugins/s60/src/qlocale_3_1.cpp | 8 +++ 8 files changed, 181 insertions(+), 17 deletions(-) diff --git a/src/corelib/kernel/qcore_symbian_p.h b/src/corelib/kernel/qcore_symbian_p.h index f86bfd3..2ef48b5 100644 --- a/src/corelib/kernel/qcore_symbian_p.h +++ b/src/corelib/kernel/qcore_symbian_p.h @@ -139,7 +139,8 @@ enum S60PluginFuncOrdinals S60Plugin_GetLongDateFormatSpec = 3, S60Plugin_GetShortDateFormatSpec = 4, S60Plugin_LocalizedDirectoryName = 5, - S60Plugin_GetSystemDrive = 6 + S60Plugin_GetSystemDrive = 6, + S60Plugin_RefreshLocaleInfo = 7 }; Q_CORE_EXPORT TLibraryFunction qt_resolveS60PluginFunc(int ordinal); diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 8a55bad..93df45d 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -69,6 +69,7 @@ # include # include "qeventdispatcher_symbian_p.h" # include "private/qcore_symbian_p.h" +# include "private/qlocale_p.h" #elif defined(Q_OS_UNIX) # if !defined(QT_NO_GLIB) # include "qeventdispatcher_glib_p.h" @@ -2601,4 +2602,13 @@ int QCoreApplication::loopLevel() \sa Q_OBJECT, QObject::tr(), QObject::trUtf8() */ +#if defined(Q_OS_SYMBIAN) +void QCoreApplicationPrivate::_q_symbianRegisterLocaleNotifier() +{ + QLocalePrivate::symbianRegisterLocaleNotifier(); +} +#endif + QT_END_NAMESPACE + +#include "moc_qcoreapplication.cpp" diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h index 097b8b4..152a775 100644 --- a/src/corelib/kernel/qcoreapplication.h +++ b/src/corelib/kernel/qcoreapplication.h @@ -196,6 +196,10 @@ private: static QCoreApplication *self; +#if defined(Q_OS_SYMBIAN) + Q_PRIVATE_SLOT(d_func(), void _q_symbianRegisterLocaleNotifier()) +#endif + Q_DISABLE_COPY(QCoreApplication) friend class QEventDispatcherUNIXPrivate; diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index bf43f88..39e50c4 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -122,6 +122,10 @@ public: static uint attribs; static inline bool testAttribute(uint flag) { return attribs & (1 << flag); } + +#if defined(Q_OS_SYMBIAN) + void _q_symbianRegisterLocaleNotifier(); +#endif }; QT_END_NAMESPACE diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 4a66b92..22114c2 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -129,6 +129,10 @@ inline bool isascii(int c) } #endif +#if defined(Q_OS_SYMBIAN) +void symbianUpdateSystemPrivate(); +#endif + /****************************************************************************** ** Helpers for accessing Qt locale database */ @@ -1388,7 +1392,8 @@ QSystemLocale::QSystemLocale() /*! \internal */ QSystemLocale::QSystemLocale(bool) -{ } +{ +} /*! Deletes the object. @@ -1407,16 +1412,29 @@ static const QSystemLocale *systemLocale() { if (_systemLocale) return _systemLocale; +#if defined(Q_OS_SYMBIAN) + symbianInitSystemLocale(); +#endif return QSystemLocale_globalSystemLocale(); } -void QLocalePrivate::updateSystemPrivate() +void QLocalePrivate::updateSystemPrivate(bool initialize) { const QSystemLocale *sys_locale = systemLocale(); if (!system_lp) system_lp = globalLocalePrivate(); *system_lp = *sys_locale->fallbackLocale().d(); + system_lp->m_language_id = 0; +#if defined(Q_OS_SYMBIAN) + RDebug::Print(_L("updateSystemPrivate")); +#endif + if (!initialize) + return; + +#if defined(Q_OS_SYMBIAN) + symbianUpdateSystemPrivate(); +#endif QVariant res = sys_locale->query(QSystemLocale::LanguageId, QVariant()); if (!res.isNull()) system_lp->m_language_id = res.toInt(); @@ -1446,12 +1464,12 @@ void QLocalePrivate::updateSystemPrivate() } #endif -static const QLocalePrivate *systemPrivate() +static const QLocalePrivate *systemPrivate(bool initialize = true) { #ifndef QT_NO_SYSTEMLOCALE // copy over the information from the fallback locale and modify if (!system_lp || system_lp->m_language_id == 0) - QLocalePrivate::updateSystemPrivate(); + QLocalePrivate::updateSystemPrivate(initialize); return system_lp; #else @@ -1459,10 +1477,10 @@ static const QLocalePrivate *systemPrivate() #endif } -static const QLocalePrivate *defaultPrivate() +static const QLocalePrivate *defaultPrivate(bool initialize = true) { if (!default_lp) - default_lp = systemPrivate(); + default_lp = systemPrivate(initialize); return default_lp; } @@ -2169,7 +2187,7 @@ QLocale::QLocale() : v(0) { p.numberOptions = default_number_options; - p.index = localePrivateIndex(defaultPrivate()); + p.index = localePrivateIndex(defaultPrivate(false)); } /*! @@ -2199,7 +2217,7 @@ QLocale::QLocale(Language language, Country country) // If not found, should default to system if (d->languageId() == QLocale::C && language != QLocale::C) { p.numberOptions = default_number_options; - p.index = localePrivateIndex(defaultPrivate()); + p.index = localePrivateIndex(defaultPrivate(false)); } else { p.numberOptions = 0; p.index = localePrivateIndex(d); @@ -2283,6 +2301,7 @@ void QLocale::setDefault(const QLocale &locale) */ QLocale::Language QLocale::language() const { + systemPrivate(); // make sure inline data is initialized from the system. return Language(d()->languageId()); } @@ -2293,6 +2312,7 @@ QLocale::Language QLocale::language() const */ QLocale::Country QLocale::country() const { + systemPrivate(); // make sure inline data is initialized from the system. return Country(d()->countryId()); } @@ -3021,6 +3041,7 @@ QDateTime QLocale::toDateTime(const QString &string, const QString &format) cons */ QChar QLocale::decimalPoint() const { + systemPrivate(); // make sure inline data is initialized from the system. return d()->decimal(); } @@ -3031,6 +3052,7 @@ QChar QLocale::decimalPoint() const */ QChar QLocale::groupSeparator() const { + systemPrivate(); // make sure inline data is initialized from the system. return d()->group(); } @@ -3041,6 +3063,7 @@ QChar QLocale::groupSeparator() const */ QChar QLocale::percent() const { + systemPrivate(); // make sure inline data is initialized from the system. return d()->percent(); } @@ -3051,6 +3074,7 @@ QChar QLocale::percent() const */ QChar QLocale::zeroDigit() const { + systemPrivate(); // make sure inline data is initialized from the system. return d()->zero(); } @@ -3061,6 +3085,7 @@ QChar QLocale::zeroDigit() const */ QChar QLocale::negativeSign() const { + systemPrivate(); // make sure inline data is initialized from the system. return d()->minus(); } @@ -3071,6 +3096,7 @@ QChar QLocale::negativeSign() const */ QChar QLocale::positiveSign() const { + systemPrivate(); // make sure inline data is initialized from the system. return d()->plus(); } @@ -3081,6 +3107,7 @@ QChar QLocale::positiveSign() const */ QChar QLocale::exponential() const { + systemPrivate(); // make sure inline data is initialized from the system. return d()->exponential(); } diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h index 0123a6e..63e9e0f 100644 --- a/src/corelib/tools/qlocale_p.h +++ b/src/corelib/tools/qlocale_p.h @@ -132,7 +132,10 @@ public: CharBuff *result) const; inline char digitToCLocale(const QChar &c) const; - static void updateSystemPrivate(); + static void updateSystemPrivate(bool initialize = true); +#if defined(Q_OS_SYMBIAN) + static void symbianRegisterLocaleNotifier(); +#endif enum NumberMode { IntegerMode, DoubleStandardMode, DoubleScientificMode }; bool validateChars(const QString &str, NumberMode numMode, QByteArray *buff, int decDigits = -1) const; diff --git a/src/corelib/tools/qlocale_symbian.cpp b/src/corelib/tools/qlocale_symbian.cpp index 1273d06..c4ad67c 100644 --- a/src/corelib/tools/qlocale_symbian.cpp +++ b/src/corelib/tools/qlocale_symbian.cpp @@ -46,11 +46,95 @@ #include #include +#include +#include #include "private/qcore_symbian_p.h" - +#include "private/qcoreapplication_p.h" +#include "qlocale_p.h" +#include "qdebug.h" QT_BEGIN_NAMESPACE +class CLocaleChangeNotifier : public CActive +{ +public: + static CLocaleChangeNotifier *NewL(); + ~CLocaleChangeNotifier(); + +private: + CLocaleChangeNotifier(); + void ConstructL(); + void RunL(); + void DoCancel(); + +private: + RChangeNotifier changeNotifier; +}; + +static CLocaleChangeNotifier *qt_changeNotifier = NULL; + +CLocaleChangeNotifier *CLocaleChangeNotifier::NewL() +{ + CLocaleChangeNotifier *self = new (ELeave) CLocaleChangeNotifier(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; +} + +CLocaleChangeNotifier::CLocaleChangeNotifier() + : CActive(CActive::EPriorityStandard) +{ +} + + +CLocaleChangeNotifier::~CLocaleChangeNotifier() +{ + Cancel(); + changeNotifier.Close(); +} + +void CLocaleChangeNotifier::ConstructL() +{ + changeNotifier.Create(); + CActiveScheduler::Add(this); + SetActive(); +} + +void CLocaleChangeNotifier::DoCancel() +{ + changeNotifier.LogonCancel(); +} + +void CLocaleChangeNotifier::RunL() +{ + SetActive(); + if (changeNotifier.Logon(iStatus) == KErrNone) { + if (iStatus.Int() == EChangesLocale) { + RDebug::Print(_L("notifier:locale changed")); + QT_TRYCATCH_LEAVING(QLocalePrivate::updateSystemPrivate()); + } else { + RDebug::Print(_L("notifier:something else changed")); + } + } else { + RDebug::Print(_L("notifier:logon failed")); + } +} + +static void qt_cleanupLocaleNotifier() +{ + delete qt_changeNotifier; + qt_changeNotifier = NULL; +} + +void QLocalePrivate::symbianRegisterLocaleNotifier() +{ + if (!qt_changeNotifier) { + QT_TRAP_THROWING(qt_changeNotifier = CLocaleChangeNotifier::NewL()); + qAddPostRoutine(qt_cleanupLocaleNotifier); + } +} + // Located in qlocale.cpp extern void getLangAndCountry(const QString &name, QLocale::Language &lang, QLocale::Country &cntry); @@ -65,6 +149,7 @@ static FormatFunc ptrTimeFormatL = NULL; static FormatSpecFunc ptrGetTimeFormatSpec = NULL; static FormatSpecFunc ptrGetLongDateFormatSpec = NULL; static FormatSpecFunc ptrGetShortDateFormatSpec = NULL; +static FormatSpecFunc ptrRefreshLocaleInfo = NULL; // Default functions if functions cannot be resolved static void defaultTimeFormatL(TTime&, TDes& des, const TDesC&, const TLocale&) @@ -214,6 +299,8 @@ static const char *jp_locale_dep[] = { */ static QString s60ToQtFormat(const QString &sys_fmt) { + RDebug::Print(_L("Time Format \"%S\""), &timeFormat); + TLocale *locale = _s60Locale.GetLocale(); QString result; @@ -679,6 +766,8 @@ static QString symbianDateFormat(bool short_format) dateFormat.Set(ptrGetLongDateFormatSpec(_s60Locale)); } + RDebug::Print(_L("symDateFormat: \"%S\""), &dateFormat); + return s60ToQtFormat(qt_TDesC2QString(dateFormat)); } @@ -688,6 +777,8 @@ static QString symbianDateFormat(bool short_format) */ static QString symbianTimeFormat() { + TPtrC timeFormat = ptrGetTimeFormatSpec(_s60Locale); + RDebug::Print(_L("symTimeFormat: \"%S\""), &timeFormat); return s60ToQtFormat(qt_TDesC2QString(ptrGetTimeFormatSpec(_s60Locale))); } @@ -771,22 +862,35 @@ static QLocale::MeasurementSystem symbianMeasurementSystem() return QLocale::MetricSystem; } -QLocale QSystemLocale::fallbackLocale() const +void symbianUpdateSystemPrivate() { + RDebug::Print(_L("symbianUpdateSystemPrivate")); // load system data before query calls + _s60Locale.LoadSystemSettings(); + if (ptrRefreshLocaleInfo) + ptrRefreshLocaleInfo(); +} + +void symbianInitSystemLocale() +{ + RDebug::Print(_L("symbianInitSystemLocale")); static QBasicAtomicInt initDone = Q_BASIC_ATOMIC_INITIALIZER(0); if (initDone.testAndSetRelaxed(0, 1)) { - _s60Locale.LoadSystemSettings(); + if (!qt_changeNotifier) { + QMetaObject::invokeMethod(qApp, SLOT(_q_symbianRegisterLocaleNotifier()), Qt::AutoConnection); + } // Initialize platform version dependent function pointers ptrTimeFormatL = reinterpret_cast - (qt_resolveS60PluginFunc(S60Plugin_TimeFormatL)); + (qt_resolveS60PluginFunc(S60Plugin_TimeFormatL)); ptrGetTimeFormatSpec = reinterpret_cast - (qt_resolveS60PluginFunc(S60Plugin_GetTimeFormatSpec)); + (qt_resolveS60PluginFunc(S60Plugin_GetTimeFormatSpec)); ptrGetLongDateFormatSpec = reinterpret_cast - (qt_resolveS60PluginFunc(S60Plugin_GetLongDateFormatSpec)); + (qt_resolveS60PluginFunc(S60Plugin_GetLongDateFormatSpec)); ptrGetShortDateFormatSpec = reinterpret_cast - (qt_resolveS60PluginFunc(S60Plugin_GetShortDateFormatSpec)); + (qt_resolveS60PluginFunc(S60Plugin_GetShortDateFormatSpec)); + ptrRefreshLocaleInfo = reinterpret_cast + (qt_resolveS60PluginFunc(S60Plugin_RefreshLocaleInfo)); if (!ptrTimeFormatL) ptrTimeFormatL = &defaultTimeFormatL; if (!ptrGetTimeFormatSpec) @@ -801,7 +905,10 @@ QLocale QSystemLocale::fallbackLocale() const } while(initDone != 2) QThread::yieldCurrentThread(); +} +QLocale QSystemLocale::fallbackLocale() const +{ TLanguage lang = User::Language(); QString locale = QLatin1String(qt_symbianLocaleName(lang)); return QLocale(locale); diff --git a/src/plugins/s60/src/qlocale_3_1.cpp b/src/plugins/s60/src/qlocale_3_1.cpp index beeee7f..d597861 100644 --- a/src/plugins/s60/src/qlocale_3_1.cpp +++ b/src/plugins/s60/src/qlocale_3_1.cpp @@ -50,6 +50,7 @@ _LIT(KLocaleIndependent, "%F"); static TBuf<10> dateFormat; static TBuf<10> timeFormat; +#define _DEBUG static void initialiseDateFormat() { if(dateFormat.Length()) @@ -146,3 +147,10 @@ EXPORT_C TPtrC defaultGetShortDateFormatSpec(TExtendedLocale&) initialiseDateFormat(); return TPtrC(dateFormat); } + +EXPORT_C void refreshLocaleInfo() +{ + // clear the buffers, so next time we re-read data from the system. + dateFormat.Zero(); + timeFormat.Zero(); +} -- cgit v0.12 From 66d28ef6125294113d6f9b04abdc10d935d0f4b5 Mon Sep 17 00:00:00 2001 From: miniak Date: Tue, 15 Dec 2009 10:38:07 +0100 Subject: Allow the WM_TASKBARCREATED message through the UIPI filter on Windows Vista and higher This is necessary to allow Windows Explorer send the WM_TASKBARCREATED message to a Qt application (to recreate its QSystemTrayIcon-s) even when it is running in a higher UIPI privilege level. Merge-request: 1626 Reviewed-by: Denis Dzyubenko Reviewed-by: Prasanth Ullattil --- src/gui/util/qsystemtrayicon_win.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/gui/util/qsystemtrayicon_win.cpp b/src/gui/util/qsystemtrayicon_win.cpp index 362be5b..474555b 100644 --- a/src/gui/util/qsystemtrayicon_win.cpp +++ b/src/gui/util/qsystemtrayicon_win.cpp @@ -83,7 +83,11 @@ struct Q_NOTIFYICONIDENTIFIER { GUID guidItem; }; +#define Q_MSGFLT_ALLOW 1 + typedef HRESULT (WINAPI *PtrShell_NotifyIconGetRect)(const Q_NOTIFYICONIDENTIFIER* identifier, RECT* iconLocation); +typedef BOOL (WINAPI *PtrChangeWindowMessageFilter)(UINT message, DWORD dwFlag); +typedef BOOL (WINAPI *PtrChangeWindowMessageFilterEx)(HWND hWnd, UINT message, DWORD action, void* pChangeFilterStruct); class QSystemTrayIconSys : QWidget { @@ -143,6 +147,23 @@ QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *object) if (!MYWM_TASKBARCREATED) { MYWM_TASKBARCREATED = RegisterWindowMessage(L"TaskbarCreated"); } + + // Allow the WM_TASKBARCREATED message through the UIPI filter on Windows Vista and higher + static PtrChangeWindowMessageFilterEx pChangeWindowMessageFilterEx = + (PtrChangeWindowMessageFilterEx)QLibrary::resolve(QLatin1String("user32"), "ChangeWindowMessageFilterEx"); + + if (pChangeWindowMessageFilterEx) { + // Call the safer ChangeWindowMessageFilterEx API if available + pChangeWindowMessageFilterEx(winId(), MYWM_TASKBARCREATED, Q_MSGFLT_ALLOW, 0); + } else { + static PtrChangeWindowMessageFilter pChangeWindowMessageFilter = + (PtrChangeWindowMessageFilter)QLibrary::resolve(QLatin1String("user32"), "ChangeWindowMessageFilter"); + + if (pChangeWindowMessageFilter) { + // Call the deprecated ChangeWindowMessageFilter API otherwise + pChangeWindowMessageFilter(MYWM_TASKBARCREATED, Q_MSGFLT_ALLOW); + } + } } QSystemTrayIconSys::~QSystemTrayIconSys() -- cgit v0.12 From 9305fba2d3a69c50aad6d6b96a6ca37801d72f9e Mon Sep 17 00:00:00 2001 From: axis Date: Tue, 15 Dec 2009 11:01:20 +0100 Subject: Enabled input method update code for all platforms. These don't have to be platform specific. RevBy: Trust me --- src/gui/widgets/qlineedit_p.cpp | 2 -- src/gui/widgets/qplaintextedit.cpp | 2 -- src/gui/widgets/qtextedit.cpp | 3 --- 3 files changed, 7 deletions(-) diff --git a/src/gui/widgets/qlineedit_p.cpp b/src/gui/widgets/qlineedit_p.cpp index bdf7993..4122bc4 100644 --- a/src/gui/widgets/qlineedit_p.cpp +++ b/src/gui/widgets/qlineedit_p.cpp @@ -150,10 +150,8 @@ void QLineEditPrivate::init(const QString& txt) QObject::connect(control, SIGNAL(cursorPositionChanged(int,int)), q, SLOT(updateMicroFocus())); -#if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) QObject::connect(control, SIGNAL(textChanged(const QString &)), q, SLOT(updateMicroFocus())); -#endif // for now, going completely overboard with updates. QObject::connect(control, SIGNAL(selectionChanged()), diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index 31f8bb4..f79931a 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -761,9 +761,7 @@ void QPlainTextEditPrivate::init(const QString &txt) QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SLOT(_q_cursorPositionChanged())); QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged())); -#if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) QObject::connect(control, SIGNAL(textChanged(const QString &)), q, SLOT(updateMicroFocus())); -#endif // set a null page size initially to avoid any relayouting until the textedit // is shown. relayoutDocument() will take care of setting the page size to the diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp index f79c870..63fac2a 100644 --- a/src/gui/widgets/qtextedit.cpp +++ b/src/gui/widgets/qtextedit.cpp @@ -158,11 +158,8 @@ void QTextEditPrivate::init(const QString &html) QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged())); QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged())); -#if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) QObject::connect(control, SIGNAL(textChanged(const QString &)), q, SLOT(updateMicroFocus())); -#endif - QTextDocument *doc = control->document(); // set a null page size initially to avoid any relayouting until the textedit // is shown. relayoutDocument() will take care of setting the page size to the -- cgit v0.12 From d6cd6c59dae36b2890baae98f0bf94b23e5509da Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 14 Dec 2009 14:09:36 +0100 Subject: Clicking on a selected item wouldn't reset the selection anymore. Before commit 88ecc8c8250505129ccff2660c60412996e2fd85, this case was handled during the mouse release event, but was responsible for selections being made twice sometimes. We now check whether a selection actually happened during the mouse press event. If not, we will try to select again during the mouse release event. Auto-test included. Reviewed-by: Thierry Task-number: QTBUG-6753 --- src/gui/itemviews/qabstractitemview.cpp | 9 ++++++--- src/gui/itemviews/qabstractitemview_p.h | 1 + .../qabstractitemview/tst_qabstractitemview.cpp | 23 ++++++++++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index 4a450b7..47b5f66 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -70,6 +70,7 @@ QAbstractItemViewPrivate::QAbstractItemViewPrivate() itemDelegate(0), selectionModel(0), ctrlDragSelectionFlag(QItemSelectionModel::NoUpdate), + noSelectionOnMousePress(false), selectionMode(QAbstractItemView::ExtendedSelection), selectionBehavior(QAbstractItemView::SelectItems), currentlyCommittingEditor(0), @@ -1622,6 +1623,7 @@ void QAbstractItemView::mousePressEvent(QMouseEvent *event) d->pressedIndex = index; d->pressedModifiers = event->modifiers(); QItemSelectionModel::SelectionFlags command = selectionCommand(index, event); + d->noSelectionOnMousePress = command == QItemSelectionModel::NoUpdate || !index.isValid(); QPoint offset = d->offset(); if ((command & QItemSelectionModel::Current) == 0) d->pressedPosition = pos + offset; @@ -1760,9 +1762,10 @@ void QAbstractItemView::mouseReleaseEvent(QMouseEvent *event) d->ctrlDragSelectionFlag = QItemSelectionModel::NoUpdate; - //in the case the user presses on no item we might decide to clear the selection - if (d->selectionModel && !index.isValid()) - d->selectionModel->select(QModelIndex(), selectionCommand(index, event)); + if (d->selectionModel && d->noSelectionOnMousePress) { + d->noSelectionOnMousePress = false; + d->selectionModel->select(index, selectionCommand(index, event)); + } setState(NoState); diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index 0b5cfbe..7fc6780 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -347,6 +347,7 @@ public: QMap > columnDelegates; QPointer selectionModel; QItemSelectionModel::SelectionFlag ctrlDragSelectionFlag; + bool noSelectionOnMousePress; QAbstractItemView::SelectionMode selectionMode; QAbstractItemView::SelectionBehavior selectionBehavior; diff --git a/tests/auto/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/qabstractitemview/tst_qabstractitemview.cpp index 6479829..bf3af63 100644 --- a/tests/auto/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/qabstractitemview/tst_qabstractitemview.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -226,6 +227,7 @@ private slots: void shiftSelectionAfterRubberbandSelection(); void ctrlRubberbandSelection(); void QTBUG6407_extendedSelection(); + void QTBUG6753_selectOnSelection(); }; class MyAbstractItemDelegate : public QAbstractItemDelegate @@ -1475,5 +1477,26 @@ void tst_QAbstractItemView::QTBUG6407_extendedSelection() } +void tst_QAbstractItemView::QTBUG6753_selectOnSelection() +{ + QTableWidget table(5, 5); + for (int i = 0; i < table.rowCount(); ++i) + for (int j = 0; j < table.columnCount(); ++j) + table.setItem(i, j, new QTableWidgetItem("choo-be-doo-wah")); + + table.show(); + table.setSelectionMode(QAbstractItemView::ExtendedSelection); + table.selectAll(); + QTest::qWaitForWindowShown(&table); + QModelIndex item = table.model()->index(1,1); + QRect itemRect = table.visualRect(item); + QTest::mouseMove(table.viewport(), itemRect.center()); + QTest::mouseClick(table.viewport(), Qt::LeftButton, Qt::NoModifier, itemRect.center()); + QTest::qWait(20); + + QCOMPARE(table.selectedItems().count(), 1); + QCOMPARE(table.selectedItems().first(), table.item(item.row(), item.column())); +} + QTEST_MAIN(tst_QAbstractItemView) #include "tst_qabstractitemview.moc" -- cgit v0.12 From 9f8d3a39606abc3888fb9f19594b7db54f5306be Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Tue, 15 Dec 2009 10:29:27 +0100 Subject: Calling removeToolBar() on native Mac toolbars (Cocoa) causes crash. The hash and the list which stores the references are already cleared by the delegate function toolbarDidRemoveItem: There is no need to remove them manually after a call to [NSToolbar removeItemAtIndex]. Task-number: QTBUG-6200 Reviewed-by: Richard Moe Gustavsen --- src/gui/widgets/qmainwindowlayout_mac.mm | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm index 8d8ffa7..6d50678 100644 --- a/src/gui/widgets/qmainwindowlayout_mac.mm +++ b/src/gui/widgets/qmainwindowlayout_mac.mm @@ -463,9 +463,6 @@ void QMainWindowLayout::removeFromMacToolbar(QToolBar *toolbar) NSToolbarItem *item = static_cast(it.key()); [[qt_mac_window_for(layoutState.mainWindow->window()) toolbar] removeItemAtIndex:toolbarItemsCopy.indexOf(item)]; - // In Carbon this hash and list gets emptied via events. In Cocoa, we have to do it ourselves here. - it = unifiedToolbarHash.erase(it); - qtoolbarsInUnifiedToolbarList.removeAll(toolbar); #endif break; } -- cgit v0.12 From 5a1b5fc1b6233ee2e1f99d6c5f6ff1115341d02f Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 15 Dec 2009 12:21:30 +0200 Subject: Fixed qgraphicsview autotest build for winscw. NokiaX86 compiler doesn't like QCOMPAREs unless the compared pointers are cast correctly. Reviewed-by: Janne Anttila --- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 797e1fb..69df39b 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -3601,7 +3601,7 @@ void tst_QGraphicsView::inputMethodSensitivity() item->setFlag(QGraphicsItem::ItemIsFocusable); scene.addItem(item); scene.setFocusItem(item); - QCOMPARE(scene.focusItem(), item); + QCOMPARE(scene.focusItem(), static_cast(item)); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); item->setFlag(QGraphicsItem::ItemAcceptsInputMethod, false); @@ -3616,35 +3616,35 @@ void tst_QGraphicsView::inputMethodSensitivity() scene.addItem(item2); scene.setFocusItem(item2); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); - QCOMPARE(scene.focusItem(), item2); + QCOMPARE(scene.focusItem(), static_cast(item2)); scene.setFocusItem(item); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); - QCOMPARE(scene.focusItem(), item); + QCOMPARE(scene.focusItem(), static_cast(item)); view.setScene(0); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); - QCOMPARE(scene.focusItem(), item); + QCOMPARE(scene.focusItem(), static_cast(item)); view.setScene(&scene); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); - QCOMPARE(scene.focusItem(), item); + QCOMPARE(scene.focusItem(), static_cast(item)); scene.setFocusItem(item2); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); - QCOMPARE(scene.focusItem(), item2); + QCOMPARE(scene.focusItem(), static_cast(item2)); view.setScene(0); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); - QCOMPARE(scene.focusItem(), item2); + QCOMPARE(scene.focusItem(), static_cast(item2)); scene.setFocusItem(item); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); - QCOMPARE(scene.focusItem(), item); + QCOMPARE(scene.focusItem(), static_cast(item)); view.setScene(&scene); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); - QCOMPARE(scene.focusItem(), item); + QCOMPARE(scene.focusItem(), static_cast(item)); } class InputContextTester : public QInputContext @@ -3878,7 +3878,7 @@ void tst_QGraphicsView::QTBUG_5859_exposedRect() { lastBackgroundExposedRect = rect; } QRectF lastBackgroundExposedRect; }; - + class CustomRectItem : public QGraphicsRectItem { public: -- cgit v0.12 From a0ce8bba1aae7c1aaf189b83bfe83eb6b80bf0bf Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Tue, 15 Dec 2009 13:09:09 +0200 Subject: QS60Style: Remove layouts with mirrored information Currently QS60Style stores pixel metrics values (96 of them for each layout) in a static lookup table. There is one "line" for each screensize, orientation and layout direction (ten in total). This fix removes the layout direction specific "lines" as there are only two pixel metrics values that differ depending on direction. We can handle those two inside QS60Style::pixelMetrics() and thus remove half of the rows, and thus gain 16*96*5 ~ 8kB of RAM. Task-number: QTBUG-6803 Reviewed-by: Alessandro Portale --- src/gui/styles/qs60style.cpp | 27 +++---- src/gui/styles/qs60style_s60.cpp | 20 +---- util/s60pixelmetrics/pm_mapper.hrh | 9 +-- util/s60pixelmetrics/pm_mapper.rss | 4 +- util/s60pixelmetrics/pm_mapperapp.cpp | 138 ++++++--------------------------- util/s60pixelmetrics/pm_mapperapp.h | 14 +--- util/s60pixelmetrics/pm_mapperview.cpp | 12 +-- util/s60pixelmetrics/pm_mapperview.h | 2 +- 8 files changed, 50 insertions(+), 176 deletions(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 17db53d..ed86f5a 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -88,16 +88,11 @@ static const qreal goldenRatio = 1.618; const layoutHeader QS60StylePrivate::m_layoutHeaders[] = { // *** generated layout data *** -{240,320,1,15,true,"QVGA Landscape Mirrored"}, -{240,320,1,15,false,"QVGA Landscape"}, -{320,240,1,15,true,"QVGA Portrait Mirrored"}, -{320,240,1,15,false,"QVGA Portrait"}, -{360,640,1,15,true,"NHD Landscape Mirrored"}, -{360,640,1,15,false,"NHD Landscape"}, -{640,360,1,15,true,"NHD Portrait Mirrored"}, -{640,360,1,15,false,"NHD Portrait"}, -{352,800,1,12,true,"E90 Landscape Mirrored"}, -{352,800,1,12,false,"E90 Landscape"} +{240,320,1,15,"QVGA Landscape"}, +{320,240,1,15,"QVGA Portrait"}, +{360,640,1,15,"NHD Landscape"}, +{640,360,1,15,"NHD Portrait"}, +{352,800,1,12,"E90 Landscape"} // *** End of generated data *** }; const int QS60StylePrivate::m_numberOfLayouts = @@ -105,15 +100,10 @@ const int QS60StylePrivate::m_numberOfLayouts = const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = { // *** generated pixel metrics *** -{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,-909,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,3,3,4,9,13,-909,5,51,11,5,0,6,3,3,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1}, {5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,-909,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,3,3,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1}, -{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,7,4,4,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1}, {5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1}, -{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,8,5,5,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, {7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, -{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,5,5,6,8,19,-909,7,74,22,7,0,8,5,5,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, {7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,5,5,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, -{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,5,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,8,6,5,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1}, {7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1} // *** End of generated data *** }; @@ -2329,6 +2319,13 @@ int QS60Style::pixelMetric(PixelMetric metric, const QStyleOption *option, const metricValue = -menuWidth; } } + //if layout direction is mirrored, switch left and right border margins + if (option && option->direction == Qt::RightToLeft) { + if (metric == PM_LayoutLeftMargin) + metricValue = QS60StylePrivate::pixelMetric(PM_LayoutRightMargin); + else if (metric == PM_LayoutRightMargin) + metricValue = QS60StylePrivate::pixelMetric(PM_LayoutLeftMargin); + } return metricValue; } diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index d5b3f73..13ac301 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -960,37 +960,23 @@ void QS60StylePrivate::setActiveLayout() { const QSize activeScreenSize(screenSize()); int activeLayoutIndex = -1; - const bool mirrored = !QApplication::isLeftToRight(); const short screenHeight = (short)activeScreenSize.height(); const short screenWidth = (short)activeScreenSize.width(); for (int i=0; i #include -#include // KAknLayoutId #include #include @@ -89,7 +88,7 @@ _LIT(KEndBraceWithCommaAndCRLF, "},\n"); _LIT(KCRLF, "\n"); // Number of header lines in layout data. -const TInt KHeaderValues = 5; +const TInt KHeaderValues = 4; // ============================ MEMBER FUNCTIONS =============================== @@ -156,37 +155,27 @@ void CPixelMetricsMapperAppUi::HandleCommandL( TInt aCommand ) Exit(); break; case ECmdSwitchOutput: + { + HBufC* buffer = HBufC::NewLC( 100 ); + TPtr bufferPtr = buffer->Des(); + TBool last = ETrue; + bufferPtr.Append(_L("Output switched to ")); iFileOutputOn = !iFileOutputOn; + if (iFileOutputOn) + bufferPtr.Append(_L("file.")); + else + bufferPtr.Append(_L("screen.")); + ShowL( *buffer, last ); + } break; case ECmdStatus: { ClearL(); // layout - CRepository* repository = NULL; - TInt value = KErrNotFound; - TRAPD(ret, repository = CRepository::NewL(KCRUidAvkon)); - if (ret == KErrNone) - { - ret = repository->Get(KAknLayoutId, value); - } - delete repository; - ret= 0; HBufC* buffer = HBufC::NewLC( 100 ); TPtr bufferPtr = buffer->Des(); - bufferPtr.Append(_L("Layout: ")); - if (ret==KErrNone) - { - bufferPtr.AppendNum(value); - } - else - { - bufferPtr.Append(_L("(error) ")); - bufferPtr.AppendNum(ret); - } TBool last = ETrue; - ShowL( *buffer, last ); - bufferPtr.Zero(); // Orientation bufferPtr.Append(_L("Orientation: ")); @@ -201,12 +190,6 @@ void CPixelMetricsMapperAppUi::HandleCommandL( TInt aCommand ) ShowL( *buffer, last ); bufferPtr.Zero(); - // Automode - bufferPtr.Append(_L("AutoMode: ")); - bufferPtr.AppendNum((TInt)iAutoMode); - ShowL( *buffer, last ); - bufferPtr.Zero(); - CAknLayoutConfig::TScreenMode localAppScreenMode = CAknSgcClient::ScreenMode(); TInt hashValue = localAppScreenMode.ScreenStyleHash(); TPixelsTwipsAndRotation pixels = CAknSgcClient::PixelsAndRotation(); @@ -261,47 +244,24 @@ void CPixelMetricsMapperAppUi::HandleCommandL( TInt aCommand ) CleanupStack::PopAndDestroy( buffer ); } break; - case ECmdSwitchMirroring: - { - // set the shared data value - CRepository* repository = NULL; - TRAPD(ret, repository = CRepository::NewL(KCRUidAvkon)); - if (ret == KErrNone) - { - TInt value = KErrNotFound; - repository->Get(KAknLayoutId, value); - if ( value == EAknLayoutIdELAF) - { - value = EAknLayoutIdABRW; - } - else if (value ==EAknLayoutIdABRW) - { - value = EAknLayoutIdELAF; - } - ret = repository->Set(KAknLayoutId, value); - } - delete repository; - // now inform all open apps of the switch - TWsEvent event; - event.SetType(KEikDynamicLayoutVariantSwitch); - iEikonEnv->WsSession().SendEventToAllWindowGroups(event); - } - break; case ECmdSwitchOrientation: { ClearL(); + HBufC* buffer = HBufC::NewLC( 100 ); + TPtr bufferPtr = buffer->Des(); + TBool last = ETrue; + #ifndef __SERIES60_31__ if (!iAvkonAppUi->OrientationCanBeChanged()) { - HBufC* buffer = HBufC::NewLC( 100 ); - TPtr bufferPtr = buffer->Des(); bufferPtr.Append(_L("Orientation cannot be changed.")); - TBool last = EFalse; ShowL( *buffer, last ); bufferPtr.Zero(); delete buffer; + break; } #endif //__SERIES60_31__ + if ( iAvkonAppUi->Orientation() == CAknAppUiBase::EAppUiOrientationPortrait) { iAvkonAppUi->SetOrientationL(CAknAppUiBase::EAppUiOrientationLandscape); @@ -314,15 +274,11 @@ void CPixelMetricsMapperAppUi::HandleCommandL( TInt aCommand ) { // unspecified iAvkonAppUi->SetOrientationL(CAknAppUiBase::EAppUiOrientationLandscape); - /*User::After(100000); - HBufC* buffer = HBufC::NewLC( 100 ); - TPtr bufferPtr = buffer->Des(); - bufferPtr.Append(_L("Orientation unspecified.")); - TBool last = EFalse; - ShowL( *buffer, last ); - bufferPtr.Zero(); - delete buffer;*/ } + bufferPtr.Append(_L("Orientation changed.")); + ShowL( *buffer, last ); + bufferPtr.Zero(); + delete buffer; break; } case ECmdStartCalculations: @@ -362,12 +318,6 @@ void CPixelMetricsMapperAppUi::HandleCommandL( TInt aCommand ) tgt.AppendNum(version.minorVersion, EDecimal); // put minor version into text file ShowL( tgt, last ); tgt.Zero(); - // MIRRORED - TBool mirrored = AknLayoutUtils::LayoutMirrored(); - tgt.Append(_L("mirrored: \t")); - tgt.AppendNum(mirrored, EDecimal); // put mirrored state into text file - ShowL( tgt, last ); - tgt.Zero(); } TInt myValue = KErrNotFound; @@ -385,33 +335,15 @@ void CPixelMetricsMapperAppUi::HandleCommandL( TInt aCommand ) if (index==QStyle::PM_SubMenuOverlap) index = QStyle::PM_CustomBase; index++; } - if (iAutoMode && !iMode) - { - HandleCommandL(ECmdSwitchMirroring); - iMode = ETrue; - } } break; case ECmdCreateHeaderFile: CreateHeaderFileL(); break; - case ECmdSetAutoMode: - iAutoMode = !iAutoMode; default: break; } } -void CPixelMetricsMapperAppUi::DoAutoOperationL() - { - HandleCommandL(ECmdStartCalculations); - iMode = EFalse; - HandleCommandL(ECmdSwitchMirroring); - } - -TBool CPixelMetricsMapperAppUi::ReadyForAutoOp() const - { - return (iAutoMode && iMode); - } // ----------------------------------------------------------------------------- // @@ -834,21 +766,7 @@ void CPixelMetricsMapperAppUi::CreateHeaderFileL() const User::LeaveIfError( lex.Val(nextValue) ); if ( loop <= KHeaderValues-1) { - if (loop == KHeaderValues -1 ) // true / false values - { - if (nextValue == 1) - { - bufferLayoutHdr.Append(_L("true")); - } - else - { - bufferLayoutHdr.Append(_L("false")); - } - } - else - { - bufferLayoutHdr.AppendNum(nextValue); - } + bufferLayoutHdr.AppendNum(nextValue); } else { @@ -882,13 +800,11 @@ TFileName CPixelMetricsMapperAppUi::CreateLayoutNameL(TFileText& aFileHandle) co // Layout data is deployed like this: // first line - height // second line - width - // fifth line mirror info TFileName lines; TFileName layoutName; TInt height = -666; TInt width = -666; - TInt mirroring = -666; // Collect name information. for (TInt i=0; i<6; i++) { @@ -907,10 +823,6 @@ TFileName CPixelMetricsMapperAppUi::CreateLayoutNameL(TFileText& aFileHandle) co { error = myLexer.Val(width); } - if (i==4) //mirror info is fourth - { - error = myLexer.Val(mirroring); - } User::LeaveIfError(error); } @@ -966,10 +878,6 @@ TFileName CPixelMetricsMapperAppUi::CreateLayoutNameL(TFileText& aFileHandle) co { layoutName.Append(_L("Portrait")); } - if (mirroring) - { - layoutName.Append(_L(" Mirrored")); - } return layoutName; } diff --git a/util/s60pixelmetrics/pm_mapperapp.h b/util/s60pixelmetrics/pm_mapperapp.h index cd119bc..aa6a63b 100644 --- a/util/s60pixelmetrics/pm_mapperapp.h +++ b/util/s60pixelmetrics/pm_mapperapp.h @@ -111,7 +111,7 @@ class CPixelMetricsMapperAppUi : public CAknViewAppUi /** * Constructor. */ - CPixelMetricsMapperAppUi(); + CPixelMetricsMapperAppUi(); /** * Symbian 2nd phase constructor. @@ -123,12 +123,6 @@ class CPixelMetricsMapperAppUi : public CAknViewAppUi */ ~CPixelMetricsMapperAppUi(); - public: - void DoAutoOperationL(); - - TBool ReadyForAutoOp() const; - - private: // Functions from base classes /** @@ -158,18 +152,16 @@ class CPixelMetricsMapperAppUi : public CAknViewAppUi private: // Data // Test view. - CPixelMetricsMapperView* iView; + CPixelMetricsMapperView* iView; CEikDialog* iDialog; TBool iFileOutputOn; + TBool iMode; CFbsBitmap* icon; CFbsBitmap* iconMask; - TBool iAutoMode; - TBool iMode; - }; diff --git a/util/s60pixelmetrics/pm_mapperview.cpp b/util/s60pixelmetrics/pm_mapperview.cpp index 82b825d..04bc3e8 100644 --- a/util/s60pixelmetrics/pm_mapperview.cpp +++ b/util/s60pixelmetrics/pm_mapperview.cpp @@ -129,8 +129,6 @@ void CPixelMetricsMapperViewContainer::ShowL( const TDesC& aString, TBool& aLast fileName.Append('_'); fileName.AppendNum(width); - if (AknLayoutUtils::LayoutMirrored()) - fileName.Append(_L("_mirrored")); fileName.Append(_L(".txt")); TInt err=file.Open(fs,fileName,EFileStreamText|EFileWrite|EFileShareAny); @@ -263,11 +261,9 @@ void CPixelMetricsMapperViewContainer::HandleResourceChange(TInt aType) mainPaneRect ); SetRect( mainPaneRect ); - CPixelMetricsMapperAppUi* myApp = static_cast (ControlEnv()->AppUi()); - if (myApp->ReadyForAutoOp()) - myApp->DoAutoOperationL(); } - if (iListbox) iListbox->HandleResourceChange(aType); + if (iListbox) + iListbox->HandleResourceChange(aType); } @@ -329,6 +325,7 @@ void CPixelMetricsMapperView::HandleCommandL( TInt aCommand ) AppUi()->HandleCommandL( aCommand ); } + // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- @@ -342,6 +339,7 @@ void CPixelMetricsMapperView::HandleStatusPaneSizeChange() } } + // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- @@ -358,6 +356,7 @@ void CPixelMetricsMapperView::DoActivateL( AppUi()->AddToViewStackL( *this, iView ); } + // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- @@ -372,4 +371,5 @@ void CPixelMetricsMapperView::DoDeactivate() iView = NULL; } + // End of File diff --git a/util/s60pixelmetrics/pm_mapperview.h b/util/s60pixelmetrics/pm_mapperview.h index be40a15..36376cd 100644 --- a/util/s60pixelmetrics/pm_mapperview.h +++ b/util/s60pixelmetrics/pm_mapperview.h @@ -219,7 +219,7 @@ class CPixelMetricsMapperView : public CAknView private: // Data // The view container. - CPixelMetricsMapperViewContainer* iView; + CPixelMetricsMapperViewContainer* iView; }; -- cgit v0.12 From da918327fdaaf45774c074d911882141cf77ea7e Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 15 Dec 2009 13:15:34 +0100 Subject: Fix vertical text centering on Mac OS X Change 04d18b38 fixed the windows and ft font engines so that the height reported in QFontMetrics is now correct, but this make vertical text centering one off as the platform defaults is to round down rather than up when the vertical position of the text is in the middle of a pixel. When this was fixed in change 1de8a5b, the vertical centering broke on Mac, since it still reported a too great font height. This patch applies the same hack to the mac font engines to report the correct font height. Task-number: QTBUG-6770 Reviewed-by: joerg --- src/gui/text/qfontengine_mac.mm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index a4e7c04..a75d70f 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -404,7 +404,9 @@ QFixed QCoreTextFontEngine::ascent() const } QFixed QCoreTextFontEngine::descent() const { - return QFixed::fromReal(CTFontGetDescent(ctfont)).ceil(); + // subtract a pixel to even out the historical +1 in QFontMetrics::height(). + // Fix in Qt 5. + return QFixed::fromReal(CTFontGetDescent(ctfont)).ceil() - 1; } QFixed QCoreTextFontEngine::leading() const { @@ -1406,7 +1408,9 @@ QFixed QFontEngineMac::ascent() const QFixed QFontEngineMac::descent() const { - return m_descent; + // subtract a pixel to even out the historical +1 in QFontMetrics::height(). + // Fix in Qt 5. + return m_descent - 1; } QFixed QFontEngineMac::leading() const -- cgit v0.12 From 100ad353689b8203988c87afe30953d59bdad736 Mon Sep 17 00:00:00 2001 From: Aleksandar Sasha Babic Date: Tue, 15 Dec 2009 13:14:20 +0100 Subject: qreal-ization Using math wrapper functions instead direct call. This gives us top-level control to what (single/double) precision we are effectively using. Task-number: QTBUG-4894 Reviewed-by: janarve Reviewed-by: Kim Motoyoshi Kalland --- src/svg/qsvghandler.cpp | 8 ++++---- src/svg/qsvgstyle.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index 3ed918e..b2619bf 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -1147,12 +1147,12 @@ static QMatrix parseTransformationMatrix(const QStringRef &value) if (points.count() != 1) goto error; const qreal deg2rad = qreal(0.017453292519943295769); - matrix.shear(tan(points[0]*deg2rad), 0); + matrix.shear(qTan(points[0]*deg2rad), 0); } else if (state == SkewY) { if (points.count() != 1) goto error; const qreal deg2rad = qreal(0.017453292519943295769); - matrix.shear(0, tan(points[0]*deg2rad)); + matrix.shear(0, qTan(points[0]*deg2rad)); } } error: @@ -1481,8 +1481,8 @@ static void pathArc(QPainterPath &path, yc = 0.5 * (y0 + y1) + sfactor * (x1 - x0); /* (xc, yc) is center of the circle. */ - th0 = atan2(y0 - yc, x0 - xc); - th1 = atan2(y1 - yc, x1 - xc); + th0 = qAtan2(y0 - yc, x0 - xc); + th1 = qAtan2(y1 - yc, x1 - xc); th_arc = th1 - th0; if (th_arc < 0 && sweep_flag) diff --git a/src/svg/qsvgstyle.cpp b/src/svg/qsvgstyle.cpp index 57927fd..c67f7d2 100644 --- a/src/svg/qsvgstyle.cpp +++ b/src/svg/qsvgstyle.cpp @@ -771,7 +771,7 @@ void QSvgAnimateTransform::resolveMatrix(QSvgNode *node) qreal transXDiff = (to1-from1) * percentOfAnimation; qreal transX = from1 + transXDiff; m_transform = QTransform(); - m_transform.shear(tan(transX * deg2rad), 0); + m_transform.shear(qTan(transX * deg2rad), 0); break; } case SkewY: { @@ -786,7 +786,7 @@ void QSvgAnimateTransform::resolveMatrix(QSvgNode *node) qreal transYDiff = (to1 - from1) * percentOfAnimation; qreal transY = from1 + transYDiff; m_transform = QTransform(); - m_transform.shear(0, tan(transY * deg2rad)); + m_transform.shear(0, qTan(transY * deg2rad)); break; } default: -- cgit v0.12 From 4391014d4533e60dc4e5e413db50b21f68f4658c Mon Sep 17 00:00:00 2001 From: Aleksandar Sasha Babic Date: Tue, 15 Dec 2009 13:50:01 +0100 Subject: qreal-ization Using math wrapper functions instead direct call. This gives us top-level control to what (single/double) precision we are effectively using. Task-number: QTBUG-4894 Reviewed-by: janarve Reviewed-by: Kim Motoyoshi Kalland --- src/gui/graphicsview/qgridlayoutengine.cpp | 3 ++- src/gui/painting/qbezier.cpp | 20 ++++++++++---------- src/gui/painting/qdrawhelper.cpp | 12 ++++++------ src/gui/painting/qpathclipper.cpp | 2 +- src/gui/painting/qstroker.cpp | 4 ++-- src/gui/styles/qcommonstyle.cpp | 2 +- src/gui/styles/qstylehelper.cpp | 2 +- src/gui/widgets/qdial.cpp | 3 ++- 8 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/gui/graphicsview/qgridlayoutengine.cpp b/src/gui/graphicsview/qgridlayoutengine.cpp index f61360a..9497a2f 100644 --- a/src/gui/graphicsview/qgridlayoutengine.cpp +++ b/src/gui/graphicsview/qgridlayoutengine.cpp @@ -51,6 +51,7 @@ #include "qvarlengtharray.h" #include +#include QT_BEGIN_NAMESPACE @@ -70,7 +71,7 @@ static void insertOrRemoveItems(QVector &items, int index, int delta) static qreal growthFactorBelowPreferredSize(qreal desired, qreal sumAvailable, qreal sumDesired) { Q_ASSERT(sumDesired != 0.0); - return desired * ::pow(sumAvailable / sumDesired, desired / sumDesired); + return desired * qPow(sumAvailable / sumDesired, desired / sumDesired); } static qreal fixedDescent(qreal descent, qreal ascent, qreal targetSize) diff --git a/src/gui/painting/qbezier.cpp b/src/gui/painting/qbezier.cpp index a6b4cef..f626494 100644 --- a/src/gui/painting/qbezier.cpp +++ b/src/gui/painting/qbezier.cpp @@ -497,7 +497,7 @@ static bool addCircle(const QBezier *b, qreal offset, QBezier *o) cos_a = 1.; if (cos_a < -1.) cos_a = -1; - angles[i] = acos(cos_a)/Q_PI; + angles[i] = qAcos(cos_a)/Q_PI; } if (angles[0] + angles[1] > 1.) { @@ -816,17 +816,17 @@ bool QBezier::findIntersections(const QBezier &a, const QBezier &b, QVector > *t) { if (IntersectBB(a, b)) { - QPointF la1(fabs((a.x3 - a.x2) - (a.x2 - a.x1)), - fabs((a.y3 - a.y2) - (a.y2 - a.y1))); - QPointF la2(fabs((a.x4 - a.x3) - (a.x3 - a.x2)), - fabs((a.y4 - a.y3) - (a.y3 - a.y2))); + QPointF la1(qFabs((a.x3 - a.x2) - (a.x2 - a.x1)), + qFabs((a.y3 - a.y2) - (a.y2 - a.y1))); + QPointF la2(qFabs((a.x4 - a.x3) - (a.x3 - a.x2)), + qFabs((a.y4 - a.y3) - (a.y3 - a.y2))); QPointF la; if (la1.x() > la2.x()) la.setX(la1.x()); else la.setX(la2.x()); if (la1.y() > la2.y()) la.setY(la1.y()); else la.setY(la2.y()); - QPointF lb1(fabs((b.x3 - b.x2) - (b.x2 - b.x1)), - fabs((b.y3 - b.y2) - (b.y2 - b.y1))); - QPointF lb2(fabs((b.x4 - b.x3) - (b.x3 - b.x2)), - fabs((b.y4 - b.y3) - (b.y3 - b.y2))); + QPointF lb1(qFabs((b.x3 - b.x2) - (b.x2 - b.x1)), + qFabs((b.y3 - b.y2) - (b.y2 - b.y1))); + QPointF lb2(qFabs((b.x4 - b.x3) - (b.x3 - b.x2)), + qFabs((b.y4 - b.y3) - (b.y3 - b.y2))); QPointF lb; if (lb1.x() > lb2.x()) lb.setX(lb1.x()); else lb.setX(lb2.x()); if (lb1.y() > lb2.y()) lb.setY(lb1.y()); else lb.setY(lb2.y()); @@ -1120,7 +1120,7 @@ static inline void bindInflectionPoint(const QBezier &bez, const qreal t, qreal ey = 3 * (right.y2 - right.y3); qreal s4 = qAbs(6 * (ey * ax - ex * ay) / qSqrt(ex * ex + ey * ey)) + 0.00001f; - qreal tf = pow(qreal(9 * flatness / s4), qreal(1./3.)); + qreal tf = qPow(qreal(9 * flatness / s4), qreal(1./3.)); *tMinus = t - (1 - t) * tf; *tPlus = t + (1 - t) * tf; } diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 4df7f8a..23236ec 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1182,7 +1182,7 @@ static const uint * QT_FASTCALL fetchConicalGradient(uint *buffer, const Operato rx -= data->gradient.conical.center.x; ry -= data->gradient.conical.center.y; while (buffer < end) { - qreal angle = atan2(ry, rx) + data->gradient.conical.angle; + qreal angle = qAtan2(ry, rx) + data->gradient.conical.angle; *buffer = qt_gradient_pixel(&data->gradient, 1 - angle / (2*Q_PI)); @@ -1196,7 +1196,7 @@ static const uint * QT_FASTCALL fetchConicalGradient(uint *buffer, const Operato if (!rw) rw = 1; while (buffer < end) { - qreal angle = atan2(ry/rw - data->gradient.conical.center.x, + qreal angle = qAtan2(ry/rw - data->gradient.conical.center.x, rx/rw - data->gradient.conical.center.y) + data->gradient.conical.angle; @@ -7140,17 +7140,17 @@ void qt_build_pow_tables() { } #else for (int i=0; i<256; ++i) { - qt_pow_rgb_gamma[i] = uchar(qRound(pow(i / qreal(255.0), smoothing) * 255)); - qt_pow_rgb_invgamma[i] = uchar(qRound(pow(i / qreal(255.), 1 / smoothing) * 255)); + qt_pow_rgb_gamma[i] = uchar(qRound(qPow(i / qreal(255.0), smoothing) * 255)); + qt_pow_rgb_invgamma[i] = uchar(qRound(qPow(i / qreal(255.), 1 / smoothing) * 255)); } #endif #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) const qreal gray_gamma = 2.31; for (int i=0; i<256; ++i) - qt_pow_gamma[i] = uint(qRound(pow(i / qreal(255.), gray_gamma) * 2047)); + qt_pow_gamma[i] = uint(qRound(qPow(i / qreal(255.), gray_gamma) * 2047)); for (int i=0; i<2048; ++i) - qt_pow_invgamma[i] = uchar(qRound(pow(i / 2047.0, 1 / gray_gamma) * 255)); + qt_pow_invgamma[i] = uchar(qRound(qPow(i / 2047.0, 1 / gray_gamma) * 255)); #endif } diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp index 51d6195..a41ab6d 100644 --- a/src/gui/painting/qpathclipper.cpp +++ b/src/gui/painting/qpathclipper.cpp @@ -1209,7 +1209,7 @@ static qreal computeAngle(const QPointF &v) } #else // doesn't seem to be robust enough - return atan2(v.x(), v.y()) + Q_PI; + return qAtan2(v.x(), v.y()) + Q_PI; #endif } diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index 228a6b1..8bb4728 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -910,8 +910,8 @@ QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLengt } } - int startSegment = int(floor(startAngle / 90)); - int endSegment = int(floor((startAngle + sweepLength) / 90)); + int startSegment = int(qFloor(startAngle / 90)); + int endSegment = int(qFloor((startAngle + sweepLength) / 90)); qreal startT = (startAngle - startSegment * 90) / 90; qreal endT = (startAngle + sweepLength - endSegment * 90) / 90; diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index 5028e5f..c1beb6a 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -2775,7 +2775,7 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt, QSize size = (sr == SE_TabBarTabLeftButton) ? tab->leftButtonSize : tab->rightButtonSize; int w = size.width(); int h = size.height(); - int midHeight = static_cast(ceil(float(tr.height() - h) / 2)); + int midHeight = static_cast(qCeil(float(tr.height() - h) / 2)); int midWidth = ((tr.width() - w) / 2); bool atTheTop = true; diff --git a/src/gui/styles/qstylehelper.cpp b/src/gui/styles/qstylehelper.cpp index af30f15..f5af960 100644 --- a/src/gui/styles/qstylehelper.cpp +++ b/src/gui/styles/qstylehelper.cpp @@ -154,7 +154,7 @@ qreal angle(const QPointF &p1, const QPointF &p2) } qreal m = -(y2 - y1) / (x2 - x1); - _angle = atan(m) * rad_factor; + _angle = qAtan(m) * rad_factor; if (p1.x() < p2.x()) _angle = 180 - _angle; diff --git a/src/gui/widgets/qdial.cpp b/src/gui/widgets/qdial.cpp index 95e6ed5..dc02c02 100644 --- a/src/gui/widgets/qdial.cpp +++ b/src/gui/widgets/qdial.cpp @@ -59,6 +59,7 @@ #ifndef QT_NO_ACCESSIBILITY #include "qaccessible.h" #endif +#include QT_BEGIN_NAMESPACE @@ -135,7 +136,7 @@ int QDialPrivate::valueFromPoint(const QPoint &p) const Q_Q(const QDial); double yy = (double)q->height()/2.0 - p.y(); double xx = (double)p.x() - q->width()/2.0; - double a = (xx || yy) ? atan2(yy, xx) : 0; + double a = (xx || yy) ? qAtan2(yy, xx) : 0; if (a < Q_PI / -2) a = a + Q_PI * 2; -- cgit v0.12 From 8152bd167c1a728c54a9976297bb53e09d131d66 Mon Sep 17 00:00:00 2001 From: Aleksandar Sasha Babic Date: Tue, 15 Dec 2009 14:29:31 +0100 Subject: qreal-ization Using Symbian Math package. Benhcmarks are showing that some Symbian native math functions (trigonometric, exp, pow ...) are faster then their Open C counterparts. Task-number: QTBUG-4894 Reviewed-by: Iain --- src/corelib/kernel/qmath.h | 154 ++++++++++++++++++++++++++++++++------------- 1 file changed, 109 insertions(+), 45 deletions(-) diff --git a/src/corelib/kernel/qmath.h b/src/corelib/kernel/qmath.h index 820f424..16e6bb7 100644 --- a/src/corelib/kernel/qmath.h +++ b/src/corelib/kernel/qmath.h @@ -46,6 +46,10 @@ #include +#ifdef Q_OS_SYMBIAN +# include +#endif + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -88,82 +92,130 @@ inline qreal qFabs(qreal v) inline qreal qSin(qreal v) { -#ifdef QT_USE_MATH_H_FLOATS - if (sizeof(qreal) == sizeof(float)) - return sinf(float(v)); - else +#ifdef Q_OS_SYMBIAN + TReal sin_v; + Math::Sin(sin_v, static_cast(v)); + return static_cast(sin_v); +#else +# ifdef QT_USE_MATH_H_FLOATS + if (sizeof(qreal) == sizeof(float)) + return sinf(float(v)); + else +# endif + return sin(v); #endif - return sin(v); } inline qreal qCos(qreal v) { -#ifdef QT_USE_MATH_H_FLOATS - if (sizeof(qreal) == sizeof(float)) - return cosf(float(v)); - else +#ifdef Q_OS_SYMBIAN + TReal cos_v; + Math::Cos(cos_v, static_cast(v)); + return static_cast(cos_v); +#else +# ifdef QT_USE_MATH_H_FLOATS + if (sizeof(qreal) == sizeof(float)) + return cosf(float(v)); + else +# endif + return cos(v); #endif - return cos(v); } inline qreal qTan(qreal v) { -#ifdef QT_USE_MATH_H_FLOATS - if (sizeof(qreal) == sizeof(float)) - return tanf(float(v)); - else +#ifdef Q_OS_SYMBIAN + TReal tan_v; + Math::Tan(tan_v, static_cast(v)); + return static_cast(tan_v); +#else +# ifdef QT_USE_MATH_H_FLOATS + if (sizeof(qreal) == sizeof(float)) + return tanf(float(v)); + else +# endif + return tan(v); #endif - return tan(v); } inline qreal qAcos(qreal v) { -#ifdef QT_USE_MATH_H_FLOATS - if (sizeof(qreal) == sizeof(float)) - return acosf(float(v)); - else +#ifdef Q_OS_SYMBIAN + TReal acos_v; + Math::ACos(acos_v, static_cast(v)); + return static_cast(acos_v); +#else +# ifdef QT_USE_MATH_H_FLOATS + if (sizeof(qreal) == sizeof(float)) + return acosf(float(v)); + else +# endif + return acos(v); #endif - return acos(v); } inline qreal qAsin(qreal v) { -#ifdef QT_USE_MATH_H_FLOATS - if (sizeof(qreal) == sizeof(float)) - return asinf(float(v)); - else +#ifdef Q_OS_SYMBIAN + TReal asin_v; + Math::ASin(asin_v, static_cast(v)); + return static_cast(asin_v); +#else +# ifdef QT_USE_MATH_H_FLOATS + if (sizeof(qreal) == sizeof(float)) + return asinf(float(v)); + else +# endif + return asin(v); #endif - return asin(v); } inline qreal qAtan(qreal v) { -#ifdef QT_USE_MATH_H_FLOATS - if(sizeof(qreal) == sizeof(float)) - return atanf(float(v)); - else +#ifdef Q_OS_SYMBIAN + TReal atan_v; + Math::ATan(atan_v, static_cast(v)); + return static_cast(atan_v); +#else +# ifdef QT_USE_MATH_H_FLOATS + if(sizeof(qreal) == sizeof(float)) + return atanf(float(v)); + else +# endif + return atan(v); #endif - return atan(v); } inline qreal qAtan2(qreal x, qreal y) { -#ifdef QT_USE_MATH_H_FLOATS - if(sizeof(qreal) == sizeof(float)) - return atan2f(float(x), float(y)); - else +#ifdef Q_OS_SYMBIAN + TReal atan2_v; + Math::ATan(atan2_v, static_cast(x), static_cast(y)); + return static_cast(atan2_v); +#else +# ifdef QT_USE_MATH_H_FLOATS + if(sizeof(qreal) == sizeof(float)) + return atan2f(float(x), float(y)); + else +# endif + return atan2(x, y); #endif - return atan2(x, y); } inline qreal qSqrt(qreal v) { -#ifdef QT_USE_MATH_H_FLOATS - if (sizeof(qreal) == sizeof(float)) - return sqrtf(float(v)); - else +#ifdef Q_OS_SYMBIAN + TReal sqrt_v; + Math::Sqrt(sqrt_v, static_cast(v)); + return static_cast(sqrt_v); +#else +# ifdef QT_USE_MATH_H_FLOATS + if (sizeof(qreal) == sizeof(float)) + return sqrtf(float(v)); + else +# endif + return sqrt(v); #endif - return sqrt(v); } inline qreal qLn(qreal v) @@ -178,19 +230,31 @@ inline qreal qLn(qreal v) inline qreal qExp(qreal v) { +#ifdef Q_OS_SYMBIAN + TReal exp_v; + Math::Exp(exp_v, static_cast(v)); + return static_cast(exp_v); +#else // only one signature // exists, exp(double) return exp(v); +#endif } inline qreal qPow(qreal x, qreal y) { -#ifdef QT_USE_MATH_H_FLOATS - if (sizeof(qreal) == sizeof(float)) - return powf(float(x), float(y)); - else +#ifdef Q_OS_SYMBIAN + TReal pow_v; + Math::Pow(pow_v, static_cast(x), static_cast(y)); + return static_cast(pow_v); +#else +# ifdef QT_USE_MATH_H_FLOATS + if (sizeof(qreal) == sizeof(float)) + return powf(float(x), float(y)); + else +# endif + return pow(x, y); #endif - return pow(x, y); } #ifndef M_PI -- cgit v0.12 From ebe0c4dfe4d1abb06bdd57783e2a850d67354d93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 15 Dec 2009 12:43:00 +0100 Subject: Got rid of unused variable compiler warning. --- src/opengl/qglpixmapfilter.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp index c0a0460..d4bcbe9 100644 --- a/src/opengl/qglpixmapfilter.cpp +++ b/src/opengl/qglpixmapfilter.cpp @@ -447,8 +447,6 @@ bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const qreal actualRadius = radius(); - QGLPixmapBlurFilter *filter = const_cast(this); - QGLContext *ctx = const_cast(QGLContext::currentContext()); QGLBlurTextureCache *blurTextureCache = QGLBlurTextureCache::cacheForContext(ctx); -- cgit v0.12 From a88cb5b07d635525bd300a59ed24540ae286fd08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 15 Dec 2009 15:35:48 +0100 Subject: Attempt at fixing compilation on Symbian. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Symbian compiler seems to have a problem with forward declarations of template functions. Reviewed-by: Bjørn Erik Nilsen --- src/gui/image/qpixmapfilter.cpp | 171 +++++++++++++++++++--------------------- 1 file changed, 83 insertions(+), 88 deletions(-) diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp index 9c7c28e..caa0752 100644 --- a/src/gui/image/qpixmapfilter.cpp +++ b/src/gui/image/qpixmapfilter.cpp @@ -601,94 +601,6 @@ QRectF QPixmapBlurFilter::boundingRectFor(const QRectF &rect) const return rect.adjusted(-delta, -delta, delta, delta); } -// Blur the image according to the blur radius -// Based on exponential blur algorithm by Jani Huhtanen - -template -static inline void blurrow( QImage & im, int line, int alpha); - -/* -* expblur(QImage &img, int radius) -* -* In-place blur of image 'img' with kernel -* of approximate radius 'radius'. -* -* Blurs with two sided exponential impulse -* response. -* -* aprec = precision of alpha parameter -* in fixed-point format 0.aprec -* -* zprec = precision of state parameters -* zR,zG,zB and zA in fp format 8.zprec -*/ -template -void expblur(QImage &img, qreal radius, bool improvedQuality = false, int transposed = 0) -{ - // halve the radius if we're using two passes - if (improvedQuality) - radius *= qreal(0.5); - - Q_ASSERT(img.format() == QImage::Format_ARGB32_Premultiplied - || img.format() == QImage::Format_RGB32); - - // choose the alpha such that pixels at radius distance from a fully - // saturated pixel will have an alpha component of no greater than - // the cutOffIntensity - const qreal cutOffIntensity = 2; - int alpha = radius <= qreal(1e-5) - ? ((1 << aprec)-1) - : qRound((1<(img, row, alpha); - } - - QImage temp(img.height(), img.width(), img.format()); - if (transposed >= 0) { - if (img.depth() == 8) { - qt_memrotate270(reinterpret_cast(img.bits()), - img.width(), img.height(), img.bytesPerLine(), - reinterpret_cast(temp.bits()), - temp.bytesPerLine()); - } else { - qt_memrotate270(reinterpret_cast(img.bits()), - img.width(), img.height(), img.bytesPerLine(), - reinterpret_cast(temp.bits()), - temp.bytesPerLine()); - } - } else { - if (img.depth() == 8) { - qt_memrotate90(reinterpret_cast(img.bits()), - img.width(), img.height(), img.bytesPerLine(), - reinterpret_cast(temp.bits()), - temp.bytesPerLine()); - } else { - qt_memrotate90(reinterpret_cast(img.bits()), - img.width(), img.height(), img.bytesPerLine(), - reinterpret_cast(temp.bits()), - temp.bytesPerLine()); - } - } - - img_height = temp.height(); - for (int row = 0; row < img_height; ++row) { - for (int i = 0; i <= improvedQuality; ++i) - blurrow(temp, row, alpha); - } - - if (transposed == 0) { - qt_memrotate90(reinterpret_cast(temp.bits()), - temp.width(), temp.height(), temp.bytesPerLine(), - reinterpret_cast(img.bits()), - img.bytesPerLine()); - } else { - img = temp; - } -} - template static inline int static_shift(int value) { @@ -773,6 +685,89 @@ static inline void blurrow(QImage & im, int line, int alpha) } } +/* +* expblur(QImage &img, int radius) +* +* Based on exponential blur algorithm by Jani Huhtanen +* +* In-place blur of image 'img' with kernel +* of approximate radius 'radius'. +* +* Blurs with two sided exponential impulse +* response. +* +* aprec = precision of alpha parameter +* in fixed-point format 0.aprec +* +* zprec = precision of state parameters +* zR,zG,zB and zA in fp format 8.zprec +*/ +template +void expblur(QImage &img, qreal radius, bool improvedQuality = false, int transposed = 0) +{ + // halve the radius if we're using two passes + if (improvedQuality) + radius *= qreal(0.5); + + Q_ASSERT(img.format() == QImage::Format_ARGB32_Premultiplied + || img.format() == QImage::Format_RGB32); + + // choose the alpha such that pixels at radius distance from a fully + // saturated pixel will have an alpha component of no greater than + // the cutOffIntensity + const qreal cutOffIntensity = 2; + int alpha = radius <= qreal(1e-5) + ? ((1 << aprec)-1) + : qRound((1<(img, row, alpha); + } + + QImage temp(img.height(), img.width(), img.format()); + if (transposed >= 0) { + if (img.depth() == 8) { + qt_memrotate270(reinterpret_cast(img.bits()), + img.width(), img.height(), img.bytesPerLine(), + reinterpret_cast(temp.bits()), + temp.bytesPerLine()); + } else { + qt_memrotate270(reinterpret_cast(img.bits()), + img.width(), img.height(), img.bytesPerLine(), + reinterpret_cast(temp.bits()), + temp.bytesPerLine()); + } + } else { + if (img.depth() == 8) { + qt_memrotate90(reinterpret_cast(img.bits()), + img.width(), img.height(), img.bytesPerLine(), + reinterpret_cast(temp.bits()), + temp.bytesPerLine()); + } else { + qt_memrotate90(reinterpret_cast(img.bits()), + img.width(), img.height(), img.bytesPerLine(), + reinterpret_cast(temp.bits()), + temp.bytesPerLine()); + } + } + + img_height = temp.height(); + for (int row = 0; row < img_height; ++row) { + for (int i = 0; i <= improvedQuality; ++i) + blurrow(temp, row, alpha); + } + + if (transposed == 0) { + qt_memrotate90(reinterpret_cast(temp.bits()), + temp.width(), temp.height(), temp.bytesPerLine(), + reinterpret_cast(img.bits()), + img.bytesPerLine()); + } else { + img = temp; + } +} #define AVG(a,b) ( ((((a)^(b)) & 0xfefefefeUL) >> 1) + ((a)&(b)) ) #define AVG16(a,b) ( ((((a)^(b)) & 0xf7deUL) >> 1) + ((a)&(b)) ) -- cgit v0.12 From acaaf55b118322d7edc80e401b20187cf6251683 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Tue, 15 Dec 2009 17:05:35 +0100 Subject: doc: Final fix. Example image links now display the image. Task-number: QTBUG-4484 --- tools/qdoc3/generator.cpp | 42 +++++++++++++++++++++++++++++++++++++++++- tools/qdoc3/generator.h | 2 ++ tools/qdoc3/htmlgenerator.cpp | 4 ++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp index 95319ca..56fca06 100644 --- a/tools/qdoc3/generator.cpp +++ b/tools/qdoc3/generator.cpp @@ -65,6 +65,8 @@ QMap Generator::imgFileExts; QSet Generator::outputFormats; QStringList Generator::imageFiles; QStringList Generator::imageDirs; +QStringList Generator::exampleDirs; +QStringList Generator::exampleImgExts; QString Generator::outDir; QString Generator::project; @@ -120,12 +122,19 @@ void Generator::initialize(const Config &config) if (!dirInfo.mkdir(outDir + "/images")) config.lastLocation().fatal(tr("Cannot create output directory '%1'") .arg(outDir + "/images")); + if (!dirInfo.mkdir(outDir + "/images/used-in-examples")) + config.lastLocation().fatal(tr("Cannot create output directory '%1'") + .arg(outDir + "/images/used-in-examples")); } imageFiles = config.getStringList(CONFIG_IMAGES); imageDirs = config.getStringList(CONFIG_IMAGEDIRS); + exampleDirs = config.getStringList(CONFIG_EXAMPLEDIRS); + exampleImgExts = config.getStringList(CONFIG_EXAMPLES + Config::dot + + CONFIG_IMAGEEXTENSIONS); - QString imagesDotFileExtensions = CONFIG_IMAGES + Config::dot + CONFIG_FILEEXTENSIONS; + QString imagesDotFileExtensions = + CONFIG_IMAGES + Config::dot + CONFIG_FILEEXTENSIONS; QSet formats = config.subVars(imagesDotFileExtensions); QSet::ConstIterator f = formats.begin(); while (f != formats.end()) { @@ -530,6 +539,13 @@ void Generator::generateInheritedBy(const ClassNode *classe, } } +/*! + This function is called when the documentation for an + example is being formatted. It outputs the list of source + files comprising the example, and the list of images used + by the example. The images are copied into a subtree of + \c{...doc/html/images/used-in-examples/...} + */ void Generator::generateFileList(const FakeNode* fake, CodeMarker* marker, Node::SubType subtype, @@ -546,6 +562,30 @@ void Generator::generateFileList(const FakeNode* fake, if (child->subType() == subtype) { ++count; QString file = child->name(); + if (subtype == Node::Image) { + if (!file.isEmpty()) { + QDir dirInfo; + QString userFriendlyFilePath; + QString srcPath = Config::findFile(fake->location(), + QStringList(), + exampleDirs, + file, + exampleImgExts, + userFriendlyFilePath); + userFriendlyFilePath.truncate(userFriendlyFilePath.lastIndexOf('/')); + + QString imgOutDir = outDir + "/images/used-in-examples/" + userFriendlyFilePath; + if (!dirInfo.mkpath(imgOutDir)) + fake->location().fatal(tr("Cannot create output directory '%1'") + .arg(imgOutDir)); + + QString imgOutName = Config::copyFile(fake->location(), + srcPath, + file, + imgOutDir); + } + + } openedList.next(); text << Atom(Atom::ListItemNumber, openedList.numberString()) diff --git a/tools/qdoc3/generator.h b/tools/qdoc3/generator.h index 7667789..cc1ea25 100644 --- a/tools/qdoc3/generator.h +++ b/tools/qdoc3/generator.h @@ -183,6 +183,8 @@ class Generator static QSet outputFormats; static QStringList imageFiles; static QStringList imageDirs; + static QStringList exampleDirs; + static QStringList exampleImgExts; static QString outDir; static QString project; }; diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index 8711c6b..ae7bd81 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -3429,6 +3429,8 @@ QString HtmlGenerator::fileName(const Node *node) if (node->type() == Node::Fake) { if (static_cast(node)->subType() == Node::ExternalPage) return node->name(); + if (static_cast(node)->subType() == Node::Image) + return node->name(); } return PageGenerator::fileName(node); } @@ -4000,6 +4002,8 @@ QString HtmlGenerator::getLink(const Atom *atom, if (path.isEmpty()) { link = linkForNode(*node, relative); + if (*node && (*node)->subType() == Node::Image) + link = "images/used-in-examples/" + link; if (targetAtom) link += "#" + refForAtom(targetAtom, *node); } -- cgit v0.12 From cc70bffdfb1539eceb355cf172fce75efa5e7589 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 15 Dec 2009 17:22:38 +0100 Subject: Add QT_DEBUG_X11_VISUAL_SELECTION to aid debugging X11/EGL --- src/opengl/qgl_x11egl.cpp | 46 +++++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index a868e83..b10e7e9 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -173,10 +173,16 @@ void QGLWidget::updateOverlayGL() //handle overlay } +//#define QT_DEBUG_X11_VISUAL_SELECTION 1 + bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig config, const QX11Info &x11Info, bool useArgbVisual) { bool foundVisualIsArgb = useArgbVisual; +#ifdef QT_DEBUG_X11_VISUAL_SELECTION + qDebug("qt_egl_setup_x11_visual() - useArgbVisual=%d", useArgbVisual); +#endif + memset(&vi, 0, sizeof(XVisualInfo)); EGLint eglConfigColorSize; @@ -199,7 +205,9 @@ bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig conf XRenderPictFormat *format; format = XRenderFindVisualFormat(x11Info.display(), chosenVisualInfo->visual); if (format->type == PictTypeDirect && format->direct.alphaMask) { -// qDebug("Using ARGB X Visual ID (%d) provided by EGL", (int)vi.visualid); +#ifdef QT_DEBUG_X11_VISUAL_SELECTION + qDebug("Using ARGB X Visual ID (%d) provided by EGL", (int)vi.visualid); +#endif foundVisualIsArgb = true; vi = *chosenVisualInfo; } @@ -212,7 +220,9 @@ bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig conf #endif { if (eglConfigColorSize == chosenVisualInfo->depth) { -// qDebug("Using opaque X Visual ID (%d) provided by EGL", (int)vi.visualid); +#ifdef QT_DEBUG_X11_VISUAL_SELECTION + qDebug("Using opaque X Visual ID (%d) provided by EGL", (int)vi.visualid); +#endif vi = *chosenVisualInfo; } else qWarning("Warning: EGL suggested using X visual ID %d (%d bpp) for config %d (%d bpp), but the depths do not match!", @@ -248,7 +258,9 @@ bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig conf if (format->type == PictTypeDirect && format->direct.alphaMask) { vi = matchingVisuals[i]; foundVisualIsArgb = true; -// qDebug("Using X Visual ID (%d) for ARGB visual as provided by XRender", (int)vi.visualid); +#ifdef QT_DEBUG_X11_VISUAL_SELECTION + qDebug("Using X Visual ID (%d) for ARGB visual as provided by XRender", (int)vi.visualid); +#endif break; } } @@ -272,24 +284,28 @@ bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig conf } else qWarning(" - Falling back to X11 suggested depth (%d)", depth); } -// else -// qDebug("Using X Visual ID (%d) for EGL provided depth (%d)", (int)vi.visualid, depth); +#ifdef QT_DEBUG_X11_VISUAL_SELECTION + else + qDebug("Using X Visual ID (%d) for EGL provided depth (%d)", (int)vi.visualid, depth); +#endif // Don't try to use ARGB now unless the visual is 32-bit - even then it might stil fail :-( if (useArgbVisual) foundVisualIsArgb = vi.depth == 32; //### We might at some point (soon) get ARGB4444 } -// qDebug("Visual Info:"); -// qDebug(" bits_per_rgb=%d", vi.bits_per_rgb); -// qDebug(" red_mask=0x%x", vi.red_mask); -// qDebug(" green_mask=0x%x", vi.green_mask); -// qDebug(" blue_mask=0x%x", vi.blue_mask); -// qDebug(" colormap_size=%d", vi.colormap_size); -// qDebug(" c_class=%d", vi.c_class); -// qDebug(" depth=%d", vi.depth); -// qDebug(" screen=%d", vi.screen); -// qDebug(" visualid=%d", vi.visualid); +#ifdef QT_DEBUG_X11_VISUAL_SELECTION + qDebug("Visual Info:"); + qDebug(" bits_per_rgb=%d", vi.bits_per_rgb); + qDebug(" red_mask=0x%x", vi.red_mask); + qDebug(" green_mask=0x%x", vi.green_mask); + qDebug(" blue_mask=0x%x", vi.blue_mask); + qDebug(" colormap_size=%d", vi.colormap_size); + qDebug(" c_class=%d", vi.c_class); + qDebug(" depth=%d", vi.depth); + qDebug(" screen=%d", vi.screen); + qDebug(" visualid=%d", vi.visualid); +#endif return foundVisualIsArgb; } -- cgit v0.12 From 6b29466ed7b5328ee61c1751bd4efb72f70946d3 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 15 Dec 2009 17:26:37 +0100 Subject: Fix QGLWidgets created with an alpha channel on X11/EGL If the QGLWidget's QGLFormat says it should have an alpha channel, try to find an ARGB Visual. Reviewed-By: Trond Task-number: QT-2602 --- src/opengl/qgl_x11egl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index b10e7e9..19026b3 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -336,7 +336,7 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, // If the application has set WA_TranslucentBackground and not explicitly set // the alpha buffer size to zero, modify the format so it have an alpha channel QGLFormat& fmt = d->glcx->d_func()->glFormat; - const bool tryArgbVisual = testAttribute(Qt::WA_TranslucentBackground); + const bool tryArgbVisual = testAttribute(Qt::WA_TranslucentBackground) || fmt.alpha(); if (tryArgbVisual && fmt.alphaBufferSize() == -1) fmt.setAlphaBufferSize(1); -- cgit v0.12 From 4b5b74835f6323415f7df43ddb74caa078c4ab62 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Tue, 15 Dec 2009 16:48:03 +0100 Subject: fix Cocoa build with change 83940f25, we used LIBS_PRIVATE on the Mac; somewhere the line where we linked against the Mac libs in the network kernel was lost. Reviewed-By: Thiago --- src/network/kernel/kernel.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri index 8aa6ff4..d3e9774 100644 --- a/src/network/kernel/kernel.pri +++ b/src/network/kernel/kernel.pri @@ -23,7 +23,7 @@ SOURCES += kernel/qauthenticator.cpp \ unix:SOURCES += kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp win32:SOURCES += kernel/qhostinfo_win.cpp kernel/qnetworkinterface_win.cpp -mac:LIBS+= -framework SystemConfiguration +mac:LIBS+= -framework SystemConfiguration -framework CoreFoundation mac:SOURCES += kernel/qnetworkproxy_mac.cpp else:win32:SOURCES += kernel/qnetworkproxy_win.cpp else:SOURCES += kernel/qnetworkproxy_generic.cpp -- cgit v0.12 From 0bde9d70b1a327b973a3e65efb138ff508ec4986 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 15 Dec 2009 18:08:40 +0100 Subject: Add autotest for creating a QGLWidget with alpha channel Task-number: QT-2602 --- tests/auto/qgl/tst_qgl.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/auto/qgl/tst_qgl.cpp b/tests/auto/qgl/tst_qgl.cpp index 5dc072d..7b701eb 100644 --- a/tests/auto/qgl/tst_qgl.cpp +++ b/tests/auto/qgl/tst_qgl.cpp @@ -75,6 +75,7 @@ private slots: void graphicsViewClipping(); void partialGLWidgetUpdates_data(); void partialGLWidgetUpdates(); + void glWidgetWithAlpha(); void glWidgetRendering(); void glFBOSimpleRendering(); void glFBORendering(); @@ -927,6 +928,17 @@ void tst_QGL::glPBufferRendering() QFUZZY_COMPARE_IMAGES(fb, reference); } +void tst_QGL::glWidgetWithAlpha() +{ + QGLWidget* w = new QGLWidget(QGLFormat(QGL::AlphaChannel)); + w->show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(w); +#endif + + delete w; +} + class GLWidget : public QGLWidget { public: -- cgit v0.12 From 9f3ae04fae52cd37855b135a0f2f519d1c5b969c Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 15 Dec 2009 18:11:05 +0100 Subject: Fix EGL surface leaks when re-parenting QGLWidget on X11/EGL When a QGLWidget is re-parented, it's native X11 window usually gets destroyed and re-created. This also happens when you set a window attribute or flag. On EGL, we must destroy the surface for the window before destroying the window itself, otherwise we can leak the surface. This also fixes lots of BadDrawable errors when running the autotests (which were due to surface leaks!). Reviewed-By: TrustMe --- src/opengl/qgl.cpp | 5 +++++ src/opengl/qgl.h | 1 + src/opengl/qgl_egl.cpp | 34 +++++++++++++++++++++------------- src/opengl/qgl_p.h | 1 + 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 2a3ce54..32534aa 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -3810,6 +3810,11 @@ bool QGLWidget::event(QEvent *e) } #if defined(QT_OPENGL_ES) + // A re-parent is likely to destroy the X11 window and re-create it. It is important + // that we free the EGL surface _before_ the winID changes - otherwise we can leak. + if (e->type() == QEvent::ParentAboutToChange) + d->glcx->d_func()->destroyEglSurfaceForDevice(); + if ((e->type() == QEvent::ParentChange) || (e->type() == QEvent::WindowStateChange)) { // The window may have been re-created during re-parent or state change - if so, the EGL // surface will need to be re-created. diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index 079953f..2076c46 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -546,6 +546,7 @@ private: friend class QGLPixelBuffer; friend class QGLPixelBufferPrivate; friend class QGLContext; + friend class QGLContextPrivate; friend class QGLOverlayWidget; friend class QOpenGLPaintEngine; friend class QGLPaintDevice; diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp index fbf0349..839e8eb 100644 --- a/src/opengl/qgl_egl.cpp +++ b/src/opengl/qgl_egl.cpp @@ -142,19 +142,7 @@ void QGLContext::reset() d->cleanup(); doneCurrent(); if (d->eglContext) { - if (d->eglSurface != EGL_NO_SURFACE) { -#ifdef Q_WS_X11 - // Make sure we don't call eglDestroySurface on a surface which - // was created for a different winId: - if (d->paintDevice->devType() == QInternal::Widget) { - QGLWidget* w = static_cast(d->paintDevice); - - if (w->d_func()->eglSurfaceWindowId == w->winId()) - eglDestroySurface(d->eglContext->display(), d->eglSurface); - } else -#endif - eglDestroySurface(d->eglContext->display(), d->eglSurface); - } + d->destroyEglSurfaceForDevice(); delete d->eglContext; } d->eglContext = 0; @@ -198,6 +186,26 @@ void QGLContext::swapBuffers() const d->eglContext->swapBuffers(d->eglSurface); } +void QGLContextPrivate::destroyEglSurfaceForDevice() +{ + if (eglSurface != EGL_NO_SURFACE) { +#ifdef Q_WS_X11 + // Make sure we don't call eglDestroySurface on a surface which + // was created for a different winId: + if (paintDevice->devType() == QInternal::Widget) { + QGLWidget* w = static_cast(paintDevice); + + if (w->d_func()->eglSurfaceWindowId == w->winId()) + eglDestroySurface(eglContext->display(), eglSurface); + else + qWarning("WARNING: Potential EGL surface leak!"); + } else +#endif + eglDestroySurface(eglContext->display(), eglSurface); + eglSurface = EGL_NO_SURFACE; + } +} + void QGLWidget::setMouseTracking(bool enable) { QWidget::setMouseTracking(enable); diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 11770d3..99c0f33 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -288,6 +288,7 @@ public: #if defined(QT_OPENGL_ES) QEglContext *eglContext; EGLSurface eglSurface; + void destroyEglSurfaceForDevice(); #elif defined(Q_WS_X11) || defined(Q_WS_MAC) void* cx; #endif -- cgit v0.12 From 802efaf0b20e08bcc04763a288a05551121493e8 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 15 Dec 2009 18:20:45 +0100 Subject: Fix autotest which checks for sample buffers Change c4d66e27 made sample buffers on EGL platforms to default to off, matching desktop GL. This patch fixes the autotest which was still testing for the old behaviour. Reviewed-By: TrustMe --- tests/auto/qgl/tst_qgl.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/auto/qgl/tst_qgl.cpp b/tests/auto/qgl/tst_qgl.cpp index 7b701eb..532e550 100644 --- a/tests/auto/qgl/tst_qgl.cpp +++ b/tests/auto/qgl/tst_qgl.cpp @@ -252,15 +252,10 @@ void tst_QGL::getSetCheck() // bool QGLFormat::sampleBuffers() // void QGLFormat::setSampleBuffers(bool) -#if !defined(QT_OPENGL_ES_2) QCOMPARE(false, obj1.sampleBuffers()); QVERIFY(!obj1.testOption(QGL::SampleBuffers)); QVERIFY(obj1.testOption(QGL::NoSampleBuffers)); -#else - QCOMPARE(true, obj1.sampleBuffers()); - QVERIFY(obj1.testOption(QGL::SampleBuffers)); - QVERIFY(!obj1.testOption(QGL::NoSampleBuffers)); -#endif + obj1.setSampleBuffers(false); QCOMPARE(false, obj1.sampleBuffers()); QVERIFY(obj1.testOption(QGL::NoSampleBuffers)); -- cgit v0.12 From 2a2dec6666f8f38e9240784b423ce69b18e1064e Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 15 Dec 2009 21:00:18 +0100 Subject: Doc: Modified the coding style of the Audio Devices example. This commit will be a duplicate of the same change applied elsewhere. Reviewed-by: Kurt Korbatits --- examples/multimedia/audiodevices/audiodevices.cpp | 81 +++++++++------------- examples/multimedia/audiodevices/audiodevices.h | 6 +- examples/multimedia/audiodevices/audiodevices.pro | 2 +- .../multimedia/audiodevices/audiodevicesbase.ui | 64 ++++++++++++----- 4 files changed, 84 insertions(+), 69 deletions(-) diff --git a/examples/multimedia/audiodevices/audiodevices.cpp b/examples/multimedia/audiodevices/audiodevices.cpp index e205e03..45c7a53 100644 --- a/examples/multimedia/audiodevices/audiodevices.cpp +++ b/examples/multimedia/audiodevices/audiodevices.cpp @@ -40,45 +40,33 @@ ****************************************************************************/ -#include #include #include "audiodevices.h" -AudioDevicesBase::AudioDevicesBase( QMainWindow *parent, Qt::WFlags f ) +AudioDevicesBase::AudioDevicesBase(QWidget *parent, Qt::WFlags f) + : QMainWindow(parent, f) { - Q_UNUSED(parent) - Q_UNUSED(f) - setupUi( this ); + setupUi(this); } AudioDevicesBase::~AudioDevicesBase() {} -AudioTest::AudioTest( QMainWindow *parent, Qt::WFlags f ) - : AudioDevicesBase( parent, f ) +AudioTest::AudioTest(QWidget *parent, Qt::WFlags f) + : AudioDevicesBase(parent, f) { - nearestFreq->setDisabled(true); - nearestChannel->setDisabled(true); - nearestCodec->setDisabled(true); - nearestSampleSize->setDisabled(true); - nearestSampleType->setDisabled(true); - nearestEndian->setDisabled(true); - logOutput->setDisabled(true); - mode = QAudio::AudioOutput; - modeBox->addItem("Input"); - modeBox->addItem("Output"); - connect(testButton,SIGNAL(clicked()),SLOT(test())); - connect(modeBox,SIGNAL(activated(int)),SLOT(modeChanged(int))); - connect(deviceBox,SIGNAL(activated(int)),SLOT(deviceChanged(int))); - connect(frequencyBox,SIGNAL(activated(int)),SLOT(freqChanged(int))); - connect(channelsBox,SIGNAL(activated(int)),SLOT(channelChanged(int))); - connect(codecsBox,SIGNAL(activated(int)),SLOT(codecChanged(int))); - connect(sampleSizesBox,SIGNAL(activated(int)),SLOT(sampleSizeChanged(int))); - connect(sampleTypesBox,SIGNAL(activated(int)),SLOT(sampleTypeChanged(int))); - connect(endianBox,SIGNAL(activated(int)),SLOT(endianChanged(int))); + connect(testButton, SIGNAL(clicked()), SLOT(test())); + connect(modeBox, SIGNAL(activated(int)), SLOT(modeChanged(int))); + connect(deviceBox, SIGNAL(activated(int)), SLOT(deviceChanged(int))); + connect(frequencyBox, SIGNAL(activated(int)), SLOT(freqChanged(int))); + connect(channelsBox, SIGNAL(activated(int)), SLOT(channelChanged(int))); + connect(codecsBox, SIGNAL(activated(int)), SLOT(codecChanged(int))); + connect(sampleSizesBox, SIGNAL(activated(int)), SLOT(sampleSizeChanged(int))); + connect(sampleTypesBox, SIGNAL(activated(int)), SLOT(sampleTypeChanged(int))); + connect(endianBox, SIGNAL(activated(int)), SLOT(endianChanged(int))); modeBox->setCurrentIndex(0); modeChanged(0); @@ -98,7 +86,7 @@ void AudioTest::test() if (!deviceInfo.isNull()) { if (deviceInfo.isFormatSupported(settings)) { - logOutput->append("Success"); + logOutput->append(tr("Success")); nearestFreq->setText(""); nearestChannel->setText(""); nearestCodec->setText(""); @@ -136,16 +124,16 @@ void AudioTest::test() } } else - logOutput->append("No Device"); + logOutput->append(tr("No Device")); } void AudioTest::modeChanged(int idx) { // mode has changed - if(idx == 0) - mode=QAudio::AudioInput; + if (idx == 0) + mode = QAudio::AudioInput; else - mode=QAudio::AudioOutput; + mode = QAudio::AudioOutput; deviceBox->clear(); foreach (const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::availableDevices(mode)) @@ -162,37 +150,37 @@ void AudioTest::deviceChanged(int idx) frequencyBox->clear(); QList freqz = deviceInfo.supportedFrequencies(); - for(int i = 0; i < freqz.size(); ++i) + for (int i = 0; i < freqz.size(); ++i) frequencyBox->addItem(QString("%1").arg(freqz.at(i))); - if(freqz.size()) + if (freqz.size()) settings.setFrequency(freqz.at(0)); channelsBox->clear(); QList chz = deviceInfo.supportedChannels(); - for(int i = 0; i < chz.size(); ++i) + for (int i = 0; i < chz.size(); ++i) channelsBox->addItem(QString("%1").arg(chz.at(i))); - if(chz.size()) + if (chz.size()) settings.setChannels(chz.at(0)); codecsBox->clear(); QStringList codecz = deviceInfo.supportedCodecs(); - for(int i = 0; i < codecz.size(); ++i) + for (int i = 0; i < codecz.size(); ++i) codecsBox->addItem(QString("%1").arg(codecz.at(i))); - if(codecz.size()) + if (codecz.size()) settings.setCodec(codecz.at(0)); // Add false to create failed condition! codecsBox->addItem("audio/test"); sampleSizesBox->clear(); QList sampleSizez = deviceInfo.supportedSampleSizes(); - for(int i = 0; i < sampleSizez.size(); ++i) + for (int i = 0; i < sampleSizez.size(); ++i) sampleSizesBox->addItem(QString("%1").arg(sampleSizez.at(i))); - if(sampleSizez.size()) + if (sampleSizez.size()) settings.setSampleSize(sampleSizez.at(0)); sampleTypesBox->clear(); QList sampleTypez = deviceInfo.supportedSampleTypes(); - for(int i = 0; i < sampleTypez.size(); ++i) { + for (int i = 0; i < sampleTypez.size(); ++i) { switch(sampleTypez.at(i)) { case QAudioFormat::SignedInt: sampleTypesBox->addItem("SignedInt"); @@ -206,14 +194,14 @@ void AudioTest::deviceChanged(int idx) case QAudioFormat::Unknown: sampleTypesBox->addItem("Unknown"); } - if(sampleTypez.size()) + if (sampleTypez.size()) settings.setSampleType(sampleTypez.at(0)); } endianBox->clear(); QList endianz = deviceInfo.supportedByteOrders(); - for(int i = 0; i < endianz.size(); ++i) { - switch(endianz.at(i)) { + for (int i = 0; i < endianz.size(); ++i) { + switch (endianz.at(i)) { case QAudioFormat::LittleEndian: endianBox->addItem("Little Endian"); break; @@ -222,7 +210,7 @@ void AudioTest::deviceChanged(int idx) break; } } - if(endianz.size()) + if (endianz.size()) settings.setByteOrder(endianz.at(0)); } @@ -249,7 +237,7 @@ void AudioTest::sampleSizeChanged(int idx) void AudioTest::sampleTypeChanged(int idx) { - switch(sampleTypesBox->itemText(idx).toInt()) { + switch (sampleTypesBox->itemText(idx).toInt()) { case QAudioFormat::SignedInt: settings.setSampleType(QAudioFormat::SignedInt); break; @@ -263,7 +251,7 @@ void AudioTest::sampleTypeChanged(int idx) void AudioTest::endianChanged(int idx) { - switch(endianBox->itemText(idx).toInt()) { + switch (endianBox->itemText(idx).toInt()) { case QAudioFormat::LittleEndian: settings.setByteOrder(QAudioFormat::LittleEndian); break; @@ -271,4 +259,3 @@ void AudioTest::endianChanged(int idx) settings.setByteOrder(QAudioFormat::BigEndian); } } - diff --git a/examples/multimedia/audiodevices/audiodevices.h b/examples/multimedia/audiodevices/audiodevices.h index 5fe5547..bd4b7c4 100644 --- a/examples/multimedia/audiodevices/audiodevices.h +++ b/examples/multimedia/audiodevices/audiodevices.h @@ -49,7 +49,7 @@ class AudioDevicesBase : public QMainWindow, public Ui::AudioDevicesBase { public: - AudioDevicesBase( QMainWindow *parent = 0, Qt::WFlags f = 0 ); + AudioDevicesBase(QWidget *parent = 0, Qt::WFlags f = 0); virtual ~AudioDevicesBase(); }; @@ -57,10 +57,10 @@ class AudioTest : public AudioDevicesBase { Q_OBJECT public: - AudioTest( QMainWindow *parent = 0, Qt::WFlags f = 0 ); + AudioTest(QWidget *parent = 0, Qt::WFlags f = 0); virtual ~AudioTest(); - QAudioDeviceInfo deviceInfo; + QAudioDeviceInfo deviceInfo; QAudioFormat settings; QAudio::Mode mode; diff --git a/examples/multimedia/audiodevices/audiodevices.pro b/examples/multimedia/audiodevices/audiodevices.pro index 232da09..1cb4679 100644 --- a/examples/multimedia/audiodevices/audiodevices.pro +++ b/examples/multimedia/audiodevices/audiodevices.pro @@ -1,7 +1,7 @@ HEADERS = audiodevices.h SOURCES = audiodevices.cpp \ main.cpp -FORMS += audiodevicesbase.ui +FORMS += audiodevicesbase.ui QT += multimedia diff --git a/examples/multimedia/audiodevices/audiodevicesbase.ui b/examples/multimedia/audiodevices/audiodevicesbase.ui index 5207338..faa39dc 100644 --- a/examples/multimedia/audiodevices/audiodevicesbase.ui +++ b/examples/multimedia/audiodevices/audiodevicesbase.ui @@ -11,7 +11,7 @@ - AudioDevicesBase + Audio Devices @@ -41,7 +41,18 @@ - + + + + Input + + + + + Output + + + @@ -93,7 +104,11 @@ - + + + false + + @@ -113,7 +128,11 @@ - + + + false + + @@ -133,7 +152,11 @@ - + + + false + + @@ -153,7 +176,11 @@ - + + + false + + @@ -173,7 +200,11 @@ - + + + false + + @@ -193,10 +224,17 @@ - + + + false + + + + false + 0 @@ -216,16 +254,6 @@ - - - - 0 - 0 - 504 - 19 - - - -- cgit v0.12 From 0414a73942272d8e863e464b3fbffeb9982964c1 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 15 Dec 2009 22:25:00 +0100 Subject: Fix moc generated code with dummy Q_PROPERTY If there is properties, we cannot skip the code that substract the property number from the id Task-number: QTBUG-5590 Reviewed-by: Brad --- src/tools/moc/generator.cpp | 11 ----------- tests/auto/moc/tst_moc.cpp | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 8fcc0df..1a75cf6 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -725,16 +725,6 @@ void Generator::generateMetacall() needEditable |= p.editable.endsWith(')'); needUser |= p.user.endsWith(')'); } - bool needAnything = needGet - | needSet - | needReset - | needDesignable - | needScriptable - | needStored - | needEditable - | needUser; - if (!needAnything) - goto skip_properties; fprintf(out, "\n#ifndef QT_NO_PROPERTIES\n "); if (needElse) @@ -904,7 +894,6 @@ void Generator::generateMetacall() fprintf(out, "\n#endif // QT_NO_PROPERTIES"); } - skip_properties: if (methodList.size() || cdef->signalList.size() || cdef->propertyList.size()) fprintf(out, "\n "); fprintf(out,"return _id;\n}\n"); diff --git a/tests/auto/moc/tst_moc.cpp b/tests/auto/moc/tst_moc.cpp index 2316ba2..1ca2b3a 100644 --- a/tests/auto/moc/tst_moc.cpp +++ b/tests/auto/moc/tst_moc.cpp @@ -489,6 +489,7 @@ private slots: void constructors(); void typenameWithUnsigned(); void warnOnVirtualSignal(); + void QTBUG5590_dummyProperty(); signals: void sigWithUnsignedArg(unsigned foo); void sigWithSignedArg(signed foo); @@ -1216,6 +1217,40 @@ void tst_Moc::warnOnVirtualSignal() #endif } + +class QTBUG5590_DummyObject: public QObject +{ + Q_OBJECT + Q_PROPERTY(bool dummy) +}; + +class QTBUG5590_PropertyObject: public QTBUG5590_DummyObject +{ + Q_OBJECT + Q_PROPERTY(int value READ value WRITE setValue) + Q_PROPERTY(int value2 READ value2 WRITE setValue2) + + public: + QTBUG5590_PropertyObject() : m_value(85), m_value2(40) { } + int value() const { return m_value; } + void setValue(int value) { m_value = value; } + int value2() const { return m_value2; } + void setValue2(int value) { m_value2 = value; } + private: + int m_value, m_value2; +}; + +void tst_Moc::QTBUG5590_dummyProperty() +{ + QTBUG5590_PropertyObject o; + QCOMPARE(o.property("value").toInt(), 85); + QCOMPARE(o.property("value2").toInt(), 40); + o.setProperty("value", 32); + QCOMPARE(o.value(), 32); + o.setProperty("value2", 82); + QCOMPARE(o.value2(), 82); +} + QTEST_APPLESS_MAIN(tst_Moc) #include "tst_moc.moc" -- cgit v0.12 From a43868ca114562502618b4e9c3dd096c65c2e192 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Wed, 16 Dec 2009 12:17:41 +0200 Subject: Long informative texts causes messagebox to grow outside of screen area Currently if we launch QMessageBox::aboutQt(), the dialog grows too large to fit into any kind of device display. To fix this, we have added a QTextEdit instead of QLabel into QMessageBox. QTextEdit automatically adds scrollbars to its content, if the text won't fit into the designated area. This change causes error QTBUG-6853. This is due to that QTextEdit does not support activating external links. Task-number: QTBUG-3232 Reviewed-by: Alessandro Portale --- src/gui/dialogs/qmessagebox.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/gui/dialogs/qmessagebox.cpp b/src/gui/dialogs/qmessagebox.cpp index a318c43..8ec8d1c 100644 --- a/src/gui/dialogs/qmessagebox.cpp +++ b/src/gui/dialogs/qmessagebox.cpp @@ -188,6 +188,9 @@ public: bool autoAddOkButton; QAbstractButton *detectedEscapeButton; QLabel *informativeLabel; +#ifdef Q_OS_SYMBIAN + QTextEdit *textEdit; +#endif QPointer receiverToDisconnectOnClose; QByteArray memberToDisconnectOnClose; QByteArray signalToDisconnectOnClose; @@ -2459,10 +2462,24 @@ void QMessageBox::setInformativeText(const QString &text) #endif label->setWordWrap(true); QGridLayout *grid = static_cast(layout()); +#ifdef Q_OS_SYMBIAN + label->hide(); + QTextEdit *textEdit = new QTextEdit(this); + textEdit->setReadOnly(true); + grid->addWidget(textEdit, 1, 1, 1, 1); + d->textEdit = textEdit; +#else grid->addWidget(label, 1, 1, 1, 1); +#endif d->informativeLabel = label; } d->informativeLabel->setText(text); + +#ifdef Q_OS_SYMBIAN + //We need to put the informative label inside textEdit to enable scrolling of long texts. + d->textEdit->setText(d->informativeLabel->text()); +#endif + d->updateSize(); } -- cgit v0.12 From d0d5d9d8e6d7815a0c97af28a7d231bfb9e83c19 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 16 Dec 2009 11:30:44 +0100 Subject: Revert "Changes to support locale change event for symbian platform" Revert a change that is not yet complete and was pushed by mistake. This reverts commit 44f7c1e097582a704a06ccbbf516536b88ddcd3a. --- src/corelib/kernel/qcore_symbian_p.h | 3 +- src/corelib/kernel/qcoreapplication.cpp | 10 --- src/corelib/kernel/qcoreapplication.h | 4 -- src/corelib/kernel/qcoreapplication_p.h | 4 -- src/corelib/tools/qlocale.cpp | 43 +++--------- src/corelib/tools/qlocale_p.h | 5 +- src/corelib/tools/qlocale_symbian.cpp | 121 ++------------------------------ src/plugins/s60/src/qlocale_3_1.cpp | 8 --- 8 files changed, 17 insertions(+), 181 deletions(-) diff --git a/src/corelib/kernel/qcore_symbian_p.h b/src/corelib/kernel/qcore_symbian_p.h index 2ef48b5..f86bfd3 100644 --- a/src/corelib/kernel/qcore_symbian_p.h +++ b/src/corelib/kernel/qcore_symbian_p.h @@ -139,8 +139,7 @@ enum S60PluginFuncOrdinals S60Plugin_GetLongDateFormatSpec = 3, S60Plugin_GetShortDateFormatSpec = 4, S60Plugin_LocalizedDirectoryName = 5, - S60Plugin_GetSystemDrive = 6, - S60Plugin_RefreshLocaleInfo = 7 + 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 93df45d..8a55bad 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -69,7 +69,6 @@ # include # include "qeventdispatcher_symbian_p.h" # include "private/qcore_symbian_p.h" -# include "private/qlocale_p.h" #elif defined(Q_OS_UNIX) # if !defined(QT_NO_GLIB) # include "qeventdispatcher_glib_p.h" @@ -2602,13 +2601,4 @@ int QCoreApplication::loopLevel() \sa Q_OBJECT, QObject::tr(), QObject::trUtf8() */ -#if defined(Q_OS_SYMBIAN) -void QCoreApplicationPrivate::_q_symbianRegisterLocaleNotifier() -{ - QLocalePrivate::symbianRegisterLocaleNotifier(); -} -#endif - QT_END_NAMESPACE - -#include "moc_qcoreapplication.cpp" diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h index 152a775..097b8b4 100644 --- a/src/corelib/kernel/qcoreapplication.h +++ b/src/corelib/kernel/qcoreapplication.h @@ -196,10 +196,6 @@ private: static QCoreApplication *self; -#if defined(Q_OS_SYMBIAN) - Q_PRIVATE_SLOT(d_func(), void _q_symbianRegisterLocaleNotifier()) -#endif - Q_DISABLE_COPY(QCoreApplication) friend class QEventDispatcherUNIXPrivate; diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index 39e50c4..bf43f88 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -122,10 +122,6 @@ public: static uint attribs; static inline bool testAttribute(uint flag) { return attribs & (1 << flag); } - -#if defined(Q_OS_SYMBIAN) - void _q_symbianRegisterLocaleNotifier(); -#endif }; QT_END_NAMESPACE diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 22114c2..4a66b92 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -129,10 +129,6 @@ inline bool isascii(int c) } #endif -#if defined(Q_OS_SYMBIAN) -void symbianUpdateSystemPrivate(); -#endif - /****************************************************************************** ** Helpers for accessing Qt locale database */ @@ -1392,8 +1388,7 @@ QSystemLocale::QSystemLocale() /*! \internal */ QSystemLocale::QSystemLocale(bool) -{ -} +{ } /*! Deletes the object. @@ -1412,29 +1407,16 @@ static const QSystemLocale *systemLocale() { if (_systemLocale) return _systemLocale; -#if defined(Q_OS_SYMBIAN) - symbianInitSystemLocale(); -#endif return QSystemLocale_globalSystemLocale(); } -void QLocalePrivate::updateSystemPrivate(bool initialize) +void QLocalePrivate::updateSystemPrivate() { const QSystemLocale *sys_locale = systemLocale(); if (!system_lp) system_lp = globalLocalePrivate(); *system_lp = *sys_locale->fallbackLocale().d(); - system_lp->m_language_id = 0; -#if defined(Q_OS_SYMBIAN) - RDebug::Print(_L("updateSystemPrivate")); -#endif - if (!initialize) - return; - -#if defined(Q_OS_SYMBIAN) - symbianUpdateSystemPrivate(); -#endif QVariant res = sys_locale->query(QSystemLocale::LanguageId, QVariant()); if (!res.isNull()) system_lp->m_language_id = res.toInt(); @@ -1464,12 +1446,12 @@ void QLocalePrivate::updateSystemPrivate(bool initialize) } #endif -static const QLocalePrivate *systemPrivate(bool initialize = true) +static const QLocalePrivate *systemPrivate() { #ifndef QT_NO_SYSTEMLOCALE // copy over the information from the fallback locale and modify if (!system_lp || system_lp->m_language_id == 0) - QLocalePrivate::updateSystemPrivate(initialize); + QLocalePrivate::updateSystemPrivate(); return system_lp; #else @@ -1477,10 +1459,10 @@ static const QLocalePrivate *systemPrivate(bool initialize = true) #endif } -static const QLocalePrivate *defaultPrivate(bool initialize = true) +static const QLocalePrivate *defaultPrivate() { if (!default_lp) - default_lp = systemPrivate(initialize); + default_lp = systemPrivate(); return default_lp; } @@ -2187,7 +2169,7 @@ QLocale::QLocale() : v(0) { p.numberOptions = default_number_options; - p.index = localePrivateIndex(defaultPrivate(false)); + p.index = localePrivateIndex(defaultPrivate()); } /*! @@ -2217,7 +2199,7 @@ QLocale::QLocale(Language language, Country country) // If not found, should default to system if (d->languageId() == QLocale::C && language != QLocale::C) { p.numberOptions = default_number_options; - p.index = localePrivateIndex(defaultPrivate(false)); + p.index = localePrivateIndex(defaultPrivate()); } else { p.numberOptions = 0; p.index = localePrivateIndex(d); @@ -2301,7 +2283,6 @@ void QLocale::setDefault(const QLocale &locale) */ QLocale::Language QLocale::language() const { - systemPrivate(); // make sure inline data is initialized from the system. return Language(d()->languageId()); } @@ -2312,7 +2293,6 @@ QLocale::Language QLocale::language() const */ QLocale::Country QLocale::country() const { - systemPrivate(); // make sure inline data is initialized from the system. return Country(d()->countryId()); } @@ -3041,7 +3021,6 @@ QDateTime QLocale::toDateTime(const QString &string, const QString &format) cons */ QChar QLocale::decimalPoint() const { - systemPrivate(); // make sure inline data is initialized from the system. return d()->decimal(); } @@ -3052,7 +3031,6 @@ QChar QLocale::decimalPoint() const */ QChar QLocale::groupSeparator() const { - systemPrivate(); // make sure inline data is initialized from the system. return d()->group(); } @@ -3063,7 +3041,6 @@ QChar QLocale::groupSeparator() const */ QChar QLocale::percent() const { - systemPrivate(); // make sure inline data is initialized from the system. return d()->percent(); } @@ -3074,7 +3051,6 @@ QChar QLocale::percent() const */ QChar QLocale::zeroDigit() const { - systemPrivate(); // make sure inline data is initialized from the system. return d()->zero(); } @@ -3085,7 +3061,6 @@ QChar QLocale::zeroDigit() const */ QChar QLocale::negativeSign() const { - systemPrivate(); // make sure inline data is initialized from the system. return d()->minus(); } @@ -3096,7 +3071,6 @@ QChar QLocale::negativeSign() const */ QChar QLocale::positiveSign() const { - systemPrivate(); // make sure inline data is initialized from the system. return d()->plus(); } @@ -3107,7 +3081,6 @@ QChar QLocale::positiveSign() const */ QChar QLocale::exponential() const { - systemPrivate(); // make sure inline data is initialized from the system. return d()->exponential(); } diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h index 63e9e0f..0123a6e 100644 --- a/src/corelib/tools/qlocale_p.h +++ b/src/corelib/tools/qlocale_p.h @@ -132,10 +132,7 @@ public: CharBuff *result) const; inline char digitToCLocale(const QChar &c) const; - static void updateSystemPrivate(bool initialize = true); -#if defined(Q_OS_SYMBIAN) - static void symbianRegisterLocaleNotifier(); -#endif + static void updateSystemPrivate(); enum NumberMode { IntegerMode, DoubleStandardMode, DoubleScientificMode }; bool validateChars(const QString &str, NumberMode numMode, QByteArray *buff, int decDigits = -1) const; diff --git a/src/corelib/tools/qlocale_symbian.cpp b/src/corelib/tools/qlocale_symbian.cpp index c4ad67c..1273d06 100644 --- a/src/corelib/tools/qlocale_symbian.cpp +++ b/src/corelib/tools/qlocale_symbian.cpp @@ -46,94 +46,10 @@ #include #include -#include -#include #include "private/qcore_symbian_p.h" -#include "private/qcoreapplication_p.h" -#include "qlocale_p.h" -#include "qdebug.h" - -QT_BEGIN_NAMESPACE - -class CLocaleChangeNotifier : public CActive -{ -public: - static CLocaleChangeNotifier *NewL(); - ~CLocaleChangeNotifier(); - -private: - CLocaleChangeNotifier(); - void ConstructL(); - void RunL(); - void DoCancel(); - -private: - RChangeNotifier changeNotifier; -}; - -static CLocaleChangeNotifier *qt_changeNotifier = NULL; - -CLocaleChangeNotifier *CLocaleChangeNotifier::NewL() -{ - CLocaleChangeNotifier *self = new (ELeave) CLocaleChangeNotifier(); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(); - return self; -} - -CLocaleChangeNotifier::CLocaleChangeNotifier() - : CActive(CActive::EPriorityStandard) -{ -} -CLocaleChangeNotifier::~CLocaleChangeNotifier() -{ - Cancel(); - changeNotifier.Close(); -} - -void CLocaleChangeNotifier::ConstructL() -{ - changeNotifier.Create(); - CActiveScheduler::Add(this); - SetActive(); -} - -void CLocaleChangeNotifier::DoCancel() -{ - changeNotifier.LogonCancel(); -} - -void CLocaleChangeNotifier::RunL() -{ - SetActive(); - if (changeNotifier.Logon(iStatus) == KErrNone) { - if (iStatus.Int() == EChangesLocale) { - RDebug::Print(_L("notifier:locale changed")); - QT_TRYCATCH_LEAVING(QLocalePrivate::updateSystemPrivate()); - } else { - RDebug::Print(_L("notifier:something else changed")); - } - } else { - RDebug::Print(_L("notifier:logon failed")); - } -} - -static void qt_cleanupLocaleNotifier() -{ - delete qt_changeNotifier; - qt_changeNotifier = NULL; -} - -void QLocalePrivate::symbianRegisterLocaleNotifier() -{ - if (!qt_changeNotifier) { - QT_TRAP_THROWING(qt_changeNotifier = CLocaleChangeNotifier::NewL()); - qAddPostRoutine(qt_cleanupLocaleNotifier); - } -} +QT_BEGIN_NAMESPACE // Located in qlocale.cpp extern void getLangAndCountry(const QString &name, QLocale::Language &lang, QLocale::Country &cntry); @@ -149,7 +65,6 @@ static FormatFunc ptrTimeFormatL = NULL; static FormatSpecFunc ptrGetTimeFormatSpec = NULL; static FormatSpecFunc ptrGetLongDateFormatSpec = NULL; static FormatSpecFunc ptrGetShortDateFormatSpec = NULL; -static FormatSpecFunc ptrRefreshLocaleInfo = NULL; // Default functions if functions cannot be resolved static void defaultTimeFormatL(TTime&, TDes& des, const TDesC&, const TLocale&) @@ -299,8 +214,6 @@ static const char *jp_locale_dep[] = { */ static QString s60ToQtFormat(const QString &sys_fmt) { - RDebug::Print(_L("Time Format \"%S\""), &timeFormat); - TLocale *locale = _s60Locale.GetLocale(); QString result; @@ -766,8 +679,6 @@ static QString symbianDateFormat(bool short_format) dateFormat.Set(ptrGetLongDateFormatSpec(_s60Locale)); } - RDebug::Print(_L("symDateFormat: \"%S\""), &dateFormat); - return s60ToQtFormat(qt_TDesC2QString(dateFormat)); } @@ -777,8 +688,6 @@ static QString symbianDateFormat(bool short_format) */ static QString symbianTimeFormat() { - TPtrC timeFormat = ptrGetTimeFormatSpec(_s60Locale); - RDebug::Print(_L("symTimeFormat: \"%S\""), &timeFormat); return s60ToQtFormat(qt_TDesC2QString(ptrGetTimeFormatSpec(_s60Locale))); } @@ -862,35 +771,22 @@ static QLocale::MeasurementSystem symbianMeasurementSystem() return QLocale::MetricSystem; } -void symbianUpdateSystemPrivate() +QLocale QSystemLocale::fallbackLocale() const { - RDebug::Print(_L("symbianUpdateSystemPrivate")); // load system data before query calls - _s60Locale.LoadSystemSettings(); - if (ptrRefreshLocaleInfo) - ptrRefreshLocaleInfo(); -} - -void symbianInitSystemLocale() -{ - RDebug::Print(_L("symbianInitSystemLocale")); static QBasicAtomicInt initDone = Q_BASIC_ATOMIC_INITIALIZER(0); if (initDone.testAndSetRelaxed(0, 1)) { - if (!qt_changeNotifier) { - QMetaObject::invokeMethod(qApp, SLOT(_q_symbianRegisterLocaleNotifier()), Qt::AutoConnection); - } + _s60Locale.LoadSystemSettings(); // Initialize platform version dependent function pointers ptrTimeFormatL = reinterpret_cast - (qt_resolveS60PluginFunc(S60Plugin_TimeFormatL)); + (qt_resolveS60PluginFunc(S60Plugin_TimeFormatL)); ptrGetTimeFormatSpec = reinterpret_cast - (qt_resolveS60PluginFunc(S60Plugin_GetTimeFormatSpec)); + (qt_resolveS60PluginFunc(S60Plugin_GetTimeFormatSpec)); ptrGetLongDateFormatSpec = reinterpret_cast - (qt_resolveS60PluginFunc(S60Plugin_GetLongDateFormatSpec)); + (qt_resolveS60PluginFunc(S60Plugin_GetLongDateFormatSpec)); ptrGetShortDateFormatSpec = reinterpret_cast - (qt_resolveS60PluginFunc(S60Plugin_GetShortDateFormatSpec)); - ptrRefreshLocaleInfo = reinterpret_cast - (qt_resolveS60PluginFunc(S60Plugin_RefreshLocaleInfo)); + (qt_resolveS60PluginFunc(S60Plugin_GetShortDateFormatSpec)); if (!ptrTimeFormatL) ptrTimeFormatL = &defaultTimeFormatL; if (!ptrGetTimeFormatSpec) @@ -905,10 +801,7 @@ void symbianInitSystemLocale() } while(initDone != 2) QThread::yieldCurrentThread(); -} -QLocale QSystemLocale::fallbackLocale() const -{ TLanguage lang = User::Language(); QString locale = QLatin1String(qt_symbianLocaleName(lang)); return QLocale(locale); diff --git a/src/plugins/s60/src/qlocale_3_1.cpp b/src/plugins/s60/src/qlocale_3_1.cpp index d597861..beeee7f 100644 --- a/src/plugins/s60/src/qlocale_3_1.cpp +++ b/src/plugins/s60/src/qlocale_3_1.cpp @@ -50,7 +50,6 @@ _LIT(KLocaleIndependent, "%F"); static TBuf<10> dateFormat; static TBuf<10> timeFormat; -#define _DEBUG static void initialiseDateFormat() { if(dateFormat.Length()) @@ -147,10 +146,3 @@ EXPORT_C TPtrC defaultGetShortDateFormatSpec(TExtendedLocale&) initialiseDateFormat(); return TPtrC(dateFormat); } - -EXPORT_C void refreshLocaleInfo() -{ - // clear the buffers, so next time we re-read data from the system. - dateFormat.Zero(); - timeFormat.Zero(); -} -- cgit v0.12 From 8fdf9f14c662b8d92cd232e09baf526476fcb297 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 16 Dec 2009 12:24:28 +0100 Subject: fix build with namespaced qt --- tools/linguist/lrelease/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/linguist/lrelease/main.cpp b/tools/linguist/lrelease/main.cpp index c45459a..b8e8eb2 100644 --- a/tools/linguist/lrelease/main.cpp +++ b/tools/linguist/lrelease/main.cpp @@ -55,6 +55,8 @@ #include #include +QT_USE_NAMESPACE + #ifdef QT_BOOTSTRAPPED static void initBinaryDir( #ifndef Q_OS_WIN -- cgit v0.12 From e1706eab16a4cd7f64665249717cc293d3a1ce93 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 16 Dec 2009 13:14:15 +0100 Subject: Fixes: Ensure QMAKE_LFLAGS+=/MACHINE:X64 works for vcproj files RevBy: Marius SO Details: It worked fine for Makefiles since no checking is done of the flags. Now its fixed so it works for vcproj files too making it easier for people to build 64bit targets in Visual Studio. --- qmake/generators/win32/msvc_objectmodel.cpp | 4 +++- qmake/generators/win32/msvc_objectmodel.h | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index 7dc456e..593a075 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -1394,8 +1394,10 @@ bool VCLinkerTool::parseOption(const char* option) case 0x0005bb6: // X86 TargetMachine = machineX86; break; - // so we put the others in AdditionalOptions... case 0x0005b94: // X64 + TargetMachine = machineX64; + break; + // so we put the others in AdditionalOptions... case 0x0046063: // AM33 case 0x000466d: // ARM case 0x0004795: // CEE diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h index d178d30..f7fdf3a 100644 --- a/qmake/generators/win32/msvc_objectmodel.h +++ b/qmake/generators/win32/msvc_objectmodel.h @@ -298,7 +298,8 @@ enum linkProgressOption { }; enum machineTypeOption { machineNotSet, - machineX86 + machineX86, + machineX64 = 17 }; enum midlCharOption { midlCharUnsigned, -- cgit v0.12 From 0568fb9f428a84a344baaa5c53395db4b99f082c Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 16 Dec 2009 13:14:12 +0100 Subject: Text cursor is not shown properly in line edits on Mac OS X. The mac stlye disables the blinking cursor when there is a selection in the line edit. The cursor is not shown back when this selection is removed (either by mouse or key press events). This patch watches the selection changed signal from the line control and updates the cursor status accordingly. Task-number: QTBUG-6378 Reviewed-by: Olivier Goffart --- src/gui/widgets/qlineedit.h | 1 + src/gui/widgets/qlineedit_p.cpp | 17 ++++++++++++++++- src/gui/widgets/qlineedit_p.h | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/qlineedit.h b/src/gui/widgets/qlineedit.h index 594e488..3f159f6 100644 --- a/src/gui/widgets/qlineedit.h +++ b/src/gui/widgets/qlineedit.h @@ -288,6 +288,7 @@ private: #ifdef QT_KEYPAD_NAVIGATION Q_PRIVATE_SLOT(d_func(), void _q_editFocusChange(bool)) #endif + Q_PRIVATE_SLOT(d_func(), void _q_selectionChanged()) }; #endif // QT_NO_LINEEDIT diff --git a/src/gui/widgets/qlineedit_p.cpp b/src/gui/widgets/qlineedit_p.cpp index 4437fef..23ab817 100644 --- a/src/gui/widgets/qlineedit_p.cpp +++ b/src/gui/widgets/qlineedit_p.cpp @@ -126,6 +126,21 @@ void QLineEditPrivate::_q_editFocusChange(bool e) } #endif +void QLineEditPrivate::_q_selectionChanged() +{ + Q_Q(QLineEdit); + if (control->preeditAreaText().isEmpty()) { + QStyleOptionFrameV2 opt; + q->initStyleOption(&opt); + bool showCursor = control->hasSelectedText() ? + q->style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, q): + true; + setCursorVisible(showCursor); + } + + emit q->selectionChanged(); +} + void QLineEditPrivate::init(const QString& txt) { Q_Q(QLineEdit); @@ -138,7 +153,7 @@ void QLineEditPrivate::init(const QString& txt) QObject::connect(control, SIGNAL(cursorPositionChanged(int,int)), q, SLOT(_q_cursorPositionChanged(int,int))); QObject::connect(control, SIGNAL(selectionChanged()), - q, SIGNAL(selectionChanged())); + q, SLOT(_q_selectionChanged())); QObject::connect(control, SIGNAL(accepted()), q, SIGNAL(returnPressed())); QObject::connect(control, SIGNAL(editingFinished()), diff --git a/src/gui/widgets/qlineedit_p.h b/src/gui/widgets/qlineedit_p.h index dc648e8..f13dce2 100644 --- a/src/gui/widgets/qlineedit_p.h +++ b/src/gui/widgets/qlineedit_p.h @@ -128,7 +128,7 @@ public: #ifdef QT_KEYPAD_NAVIGATION void _q_editFocusChange(bool); #endif - + void _q_selectionChanged(); #ifndef QT_NO_COMPLETER void _q_completionHighlighted(QString); #endif -- cgit v0.12 From 4b815774358c3c981dc8bbbcb0dd68abe2e812f2 Mon Sep 17 00:00:00 2001 From: Jani Hautakangas Date: Wed, 16 Dec 2009 15:21:10 +0200 Subject: Fix for QTBUG-4908 SVG transparency rendering problem. QPixmap::copy discarded alpha channel. This fix also removes usage of member variables CFbsBitGc and CFbsBitmapDevice. Now those are used only in function scope. Reviewed-by: Sami Merila --- src/gui/image/qpixmap_s60.cpp | 97 +++++++++++++-------------------- src/gui/image/qpixmap_s60_p.h | 6 +- src/gui/painting/qwindowsurface_s60.cpp | 8 ++- tests/auto/qpixmap/tst_qpixmap.cpp | 6 ++ 4 files changed, 51 insertions(+), 66 deletions(-) diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp index 610317d..8194db5 100644 --- a/src/gui/image/qpixmap_s60.cpp +++ b/src/gui/image/qpixmap_s60.cpp @@ -235,7 +235,7 @@ static CFbsBitmap* uncompress(CFbsBitmap* bitmap) QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL()); bitmapGc->Activate(bitmapDevice); - bitmapGc->DrawBitmap(TPoint(), bitmap); + bitmapGc->BitBlt(TPoint(), bitmap); delete bitmapGc; delete bitmapDevice; @@ -346,8 +346,6 @@ QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap) QS60PixmapData::QS60PixmapData(PixelType type) : QRasterPixmapData(type), symbianBitmapDataAccess(new QSymbianBitmapDataAccess), cfbsBitmap(0), - bitmapDevice(0), - bitmapGc(0), pengine(0), bytes(0), formatLocked(false) @@ -385,8 +383,6 @@ void QS60PixmapData::resize(int width, int height) if(cfbsBitmap->SizeInPixels() != newSize) { cfbsBitmap->Resize(TSize(width, height)); - bitmapDevice->Resize(TSize(width, height)); - bitmapGc->Resized(); if(pengine) { delete pengine; pengine = 0; @@ -397,21 +393,10 @@ void QS60PixmapData::resize(int width, int height) } } -bool QS60PixmapData::initSymbianBitmapContext() -{ - QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(cfbsBitmap)); - QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL()); - bitmapGc->Activate(bitmapDevice); - - return true; -} - void QS60PixmapData::release() { if (cfbsBitmap) { QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); - delete bitmapGc; - delete bitmapDevice; delete cfbsBitmap; lock.relock(); } @@ -419,8 +404,6 @@ void QS60PixmapData::release() delete pengine; image = QImage(); cfbsBitmap = 0; - bitmapGc = 0; - bitmapDevice = 0; pengine = 0; bytes = 0; } @@ -428,42 +411,52 @@ void QS60PixmapData::release() /*! * Takes ownership of bitmap. Used by window surface */ -void QS60PixmapData::fromSymbianBitmap(CFbsBitmap* bitmap) +void QS60PixmapData::fromSymbianBitmap(CFbsBitmap* bitmap, bool lockFormat) { - cfbsBitmap = bitmap; - formatLocked = true; + Q_ASSERT(bitmap); - if(!initSymbianBitmapContext()) { - qWarning("Could not create CBitmapContext"); - release(); - return; - } + release(); + + cfbsBitmap = bitmap; + formatLocked = lockFormat; - setSerialNumber(cfbsBitmap->Handle()); + setSerialNumber(cfbsBitmap->Handle()); - UPDATE_BUFFER(); + UPDATE_BUFFER(); - // Create default palette if needed - if (cfbsBitmap->DisplayMode() == EGray2) { - image.setColorCount(2); - image.setColor(0, QColor(Qt::color0).rgba()); - image.setColor(1, QColor(Qt::color1).rgba()); + // Create default palette if needed + if (cfbsBitmap->DisplayMode() == EGray2) { + image.setColorCount(2); + image.setColor(0, QColor(Qt::color0).rgba()); + image.setColor(1, QColor(Qt::color1).rgba()); //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 if (cfbsBitmap->DisplayMode() == EGray256) { - for (int i=0; i < 256; ++i) - image.setColor(i, qRgb(i, i, i)); - }else if (cfbsBitmap->DisplayMode() == EColor256) { - const TColor256Util *palette = TColor256Util::Default(); - for (int i=0; i < 256; ++i) - image.setColor(i, (QRgb)(palette->Color256(i).Value())); - } + } else if (cfbsBitmap->DisplayMode() == EGray256) { + for (int i=0; i < 256; ++i) + image.setColor(i, qRgb(i, i, i)); + } else if (cfbsBitmap->DisplayMode() == EColor256) { + const TColor256Util *palette = TColor256Util::Default(); + for (int i=0; i < 256; ++i) + image.setColor(i, (QRgb)(palette->Color256(i).Value())); + } +} + +QImage QS60PixmapData::toImage(const QRect &r) const +{ + QS60PixmapData *that = const_cast(this); + that->beginDataAccess(); + QImage copy = that->image.copy(r); + that->endDataAccess(); + + return copy; } void QS60PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags) { + release(); + QImage sourceImage; if (pixelType() == BitmapType) { @@ -517,8 +510,8 @@ void QS60PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags } cfbsBitmap = createSymbianCFbsBitmap(TSize(sourceImage.width(), sourceImage.height()), mode); - if (!(cfbsBitmap && initSymbianBitmapContext())) { - qWarning("Could not create CFbsBitmap and/or CBitmapContext"); + if (!cfbsBitmap) { + qWarning("Could not create CFbsBitmap"); release(); return; } @@ -544,17 +537,8 @@ void QS60PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags void QS60PixmapData::copy(const QPixmapData *data, const QRect &rect) { - if (data->pixelType() == BitmapType) { - QBitmap::fromImage(data->toImage().copy(rect)); - return; - } - const QS60PixmapData *s60Data = static_cast(data); - - resize(rect.width(), rect.height()); - cfbsBitmap->SetDisplayMode(s60Data->cfbsBitmap->DisplayMode()); - - bitmapGc->BitBlt(TPoint(0, 0), s60Data->cfbsBitmap, qt_QRect2TRect(rect)); + fromImage(s60Data->toImage(rect), Qt::AutoColor | Qt::OrderedAlphaDither); } bool QS60PixmapData::scroll(int dx, int dy, const QRect &rect) @@ -661,12 +645,7 @@ void QS60PixmapData::setAlphaChannel(const QPixmap &alphaChannel) QImage QS60PixmapData::toImage() const { - QS60PixmapData *that = const_cast(this); - that->beginDataAccess(); - QImage copy = that->image.copy(); - that->endDataAccess(); - - return copy; + return toImage(QRect()); } QPaintEngine* QS60PixmapData::paintEngine() const diff --git a/src/gui/image/qpixmap_s60_p.h b/src/gui/image/qpixmap_s60_p.h index 8631ebd..2d93622 100644 --- a/src/gui/image/qpixmap_s60_p.h +++ b/src/gui/image/qpixmap_s60_p.h @@ -109,14 +109,12 @@ public: private: void release(); - void fromSymbianBitmap(CFbsBitmap* bitmap); - bool initSymbianBitmapContext(); + void fromSymbianBitmap(CFbsBitmap* bitmap, bool lockFormat=false); + QImage toImage(const QRect &r) const; QSymbianBitmapDataAccess *symbianBitmapDataAccess; CFbsBitmap *cfbsBitmap; - CFbsBitmapDevice *bitmapDevice; - CFbsBitGc *bitmapGc; QPaintEngine *pengine; uchar* bytes; diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp index c66da71..15427c6 100644 --- a/src/gui/painting/qwindowsurface_s60.cpp +++ b/src/gui/painting/qwindowsurface_s60.cpp @@ -68,12 +68,14 @@ QS60WindowSurface::QS60WindowSurface(QWidget* widget) mode = EColor16MA; // Try for transparency anyway // We create empty CFbsBitmap here -> it will be resized in setGeometry - CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap); // CBase derived object needs check on new + CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap); // CBase derived object needs check on new qt_symbian_throwIfError( bitmap->Create( TSize(0, 0), mode ) ); QS60PixmapData *data = new QS60PixmapData(QPixmapData::PixmapType); - data->fromSymbianBitmap(bitmap); - d_ptr->device = QPixmap(data); + if (data) { + data->fromSymbianBitmap(bitmap, true); + d_ptr->device = QPixmap(data); + } setStaticContentsSupport(true); } diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index 0effd01..0164c9d 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -1289,6 +1289,12 @@ void tst_QPixmap::copy() QPixmap expected(10, 10); expected.fill(Qt::blue); QVERIFY(lenientCompare(dest, expected)); + + QPixmap trans; + trans.fill(Qt::transparent); + + QPixmap transCopy = trans.copy(); + QVERIFY(pixmapsAreEqual(&trans, &transCopy)); } #ifdef QT3_SUPPORT -- cgit v0.12 From 06034e9ab2560e777f457fedc8a8cf4380461fed Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 16 Dec 2009 13:21:44 +0200 Subject: Fixed events benchmark postEvent function The postEvent function was causing problems in Symbian because it couldn't handle multiple iterations of the benchmark. - Moved event allocation inside QBENCHMARK so that each iteration will have a fresh event object. - Added resetting of the PingPong counters inside QBENCHMARK. - Used QTestEventLoop::instance().exitLoop() instead of QCoreApplication::quit() to make the cases beyond first to actually test something meaningful. - Added a "first time" case to postEvent_data, as the first time the event loop is used it takes much longer that the subsequent times, at least in Symbian, so that skewed the results. Task-number: QTBUG-6688 Reviewed-by: axis --- tests/benchmarks/events/main.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tests/benchmarks/events/main.cpp b/tests/benchmarks/events/main.cpp index 7c9de8f..09d6c53 100644 --- a/tests/benchmarks/events/main.cpp +++ b/tests/benchmarks/events/main.cpp @@ -47,6 +47,7 @@ class PingPong : public QObject { public: void setPeer(QObject *peer); + void resetCounter() {m_counter = 100;} protected: bool event(QEvent *e); @@ -69,7 +70,7 @@ bool PingPong::event(QEvent *) QEvent *e = new QEvent(QEvent::User); QCoreApplication::postEvent(m_peer, e); } else { - QCoreApplication::quit(); + QTestEventLoop::instance().exitLoop(); } return true; } @@ -149,6 +150,10 @@ void EventsBench::sendEvent() void EventsBench::postEvent_data() { QTest::addColumn("filterEvents"); + // The first time an eventloop is executed, the case runs radically slower at least + // on some platforms, so test the "no eventfilter" case to get a comparable results + // with the "eventfilter" case. + QTest::newRow("first time, no eventfilter") << false; QTest::newRow("no eventfilter") << false; QTest::newRow("eventfilter") << true; } @@ -164,8 +169,14 @@ void EventsBench::postEvent() ping.installEventFilter(this); pong.installEventFilter(this); } - QEvent *e = new QEvent(QEvent::User); + QBENCHMARK { + // In case multiple iterations are done, event needs to be created inside the QBENCHMARK, + // or it gets deleted once first iteration exits and can cause a crash. Similarly, + // ping and pong need their counters reset. + QEvent *e = new QEvent(QEvent::User); + ping.resetCounter(); + pong.resetCounter(); QCoreApplication::postEvent(&ping, e); QTestEventLoop::instance().enterLoop( 61 ); } -- cgit v0.12 From 851344b93b797a9c6fb13f8c6d4ede0594040633 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 16 Dec 2009 15:06:25 +0200 Subject: Fixed qdiriterator benchmark for Symbian Deployment was handled similarly to WinCE. Some whitespace was also removed. Task-number: QTBUG-6690 Reviewed-by: Janne Anttila --- tests/benchmarks/qdiriterator/main.cpp | 10 +++++----- tests/benchmarks/qdiriterator/qdiriterator.pro | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/benchmarks/qdiriterator/main.cpp b/tests/benchmarks/qdiriterator/main.cpp index 2a400e3..9e4e53e 100644 --- a/tests/benchmarks/qdiriterator/main.cpp +++ b/tests/benchmarks/qdiriterator/main.cpp @@ -73,7 +73,7 @@ private slots: void tst_qdiriterator::data() { -#ifdef Q_OS_WINCE +#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) QByteArray qtdir = qPrintable(QCoreApplication::applicationDirPath()); qtdir += "/depot"; #else @@ -148,9 +148,9 @@ static int posix_helper(const char *dirpath) int count = 0; while ((entry = ::readdir(dir))) { - if (qstrcmp(entry->d_name, ".") == 0) + if (qstrcmp(entry->d_name, ".") == 0) continue; - if (qstrcmp(entry->d_name, "..") == 0) + if (qstrcmp(entry->d_name, "..") == 0) continue; ++count; QByteArray ba = dirpath; @@ -198,7 +198,7 @@ void tst_qdiriterator::diriterator() //QDir::AllEntries | QDir::Hidden, QDir::Files, QDirIterator::Subdirectories); - + while (dir.hasNext()) { dir.next(); //printf("%s\n", qPrintable(dir.fileName())); @@ -231,7 +231,7 @@ void tst_qdiriterator::fsiterator() //QDir::Files | QDir::NoDotAndDotDot, QDir::Files, QFileSystemIterator::Subdirectories); - + for (; !dir.atEnd(); dir.next()) { dump && printf("%d %s\n", dir.fileInfo().isDir(), diff --git a/tests/benchmarks/qdiriterator/qdiriterator.pro b/tests/benchmarks/qdiriterator/qdiriterator.pro index fb4b753..e06d746 100755 --- a/tests/benchmarks/qdiriterator/qdiriterator.pro +++ b/tests/benchmarks/qdiriterator/qdiriterator.pro @@ -15,7 +15,7 @@ SOURCES += main.cpp SOURCES += qfilesystemiterator.cpp HEADERS += qfilesystemiterator.h -wince*: { +wince*|symbian: { corelibdir.sources = $$QT_SOURCE_TREE/src/corelib corelibdir.path = ./depot/src DEPLOYMENT += corelibdir -- cgit v0.12 From a2ec72ee604181892050093669b870580708842d Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 16 Dec 2009 15:59:05 +0200 Subject: Fixed qstylesheetstyle benchmark for Symbian The benchmark ran out of stack for large grids somewhere inside QWidget::show(). Skipped show cases for large grids in Symbian, since we cannot increase application stack any further. Also removed some unnecessary whitespace. Task-number: QTBUG-6693 Reviewed-by: Janne Anttila --- tests/benchmarks/qstylesheetstyle/main.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/tests/benchmarks/qstylesheetstyle/main.cpp b/tests/benchmarks/qstylesheetstyle/main.cpp index 19efcab..d6fa48c 100644 --- a/tests/benchmarks/qstylesheetstyle/main.cpp +++ b/tests/benchmarks/qstylesheetstyle/main.cpp @@ -49,16 +49,16 @@ class tst_qstylesheetstyle : public QObject private slots: void empty(); void empty_events(); - + void simple(); void simple_events(); - + void grid_data(); void grid(); - + private: QWidget *buildSimpleWidgets(); - + }; @@ -103,7 +103,7 @@ void tst_qstylesheetstyle::empty_events() delete w; } -static const char *simple_css = +static const char *simple_css = " QLineEdit { background: red; } QPushButton { border: 1px solid yellow; color: pink; } \n" " QCheckBox { margin: 3px 5px; background-color:red; } QAbstractButton { background-color: #456; } \n" " QFrame { padding: 3px; } QLabel { color: black } QSpinBox:hover { background-color:blue; } "; @@ -138,7 +138,7 @@ void tst_qstylesheetstyle::grid_data() QTest::addColumn("events"); QTest::addColumn("show"); QTest::addColumn("N"); - for (int n = 5; n <= 25; n += 5) { + for (int n = 5; n <= 25; n += 5) { const QByteArray nString = QByteArray::number(n*n); QTest::newRow(("simple--" + nString).constData()) << false << false << n; QTest::newRow(("events--" + nString).constData()) << true << false << n; @@ -153,6 +153,13 @@ void tst_qstylesheetstyle::grid() QFETCH(bool, show); QFETCH(int, N); +#ifdef Q_OS_SYMBIAN + // Symbian has limited stack (max 80k), which will run out when N >= 20 due to + // QWidget::show() using recursion among grid labels somewhere down the line. + if (show && N >= 20) + QSKIP("Grid too big for device to show", SkipSingle); +#endif + QWidget *w = new QWidget(); QGridLayout *layout = new QGridLayout(w); w->setLayout(layout); -- cgit v0.12 From f9d962ac5d738b26d3c939f83fe6d32bd3202535 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Thu, 10 Dec 2009 17:52:18 +0100 Subject: Do not call macToQtFormat twice in QLocale. We already convert date/time format inside the getMacDateFormat, so no reason to do it again later. Reviewed-by: Prasanth --- src/corelib/tools/qlocale.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 4a66b92..8645f17 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -1187,14 +1187,14 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const } case DateFormatLong: case DateFormatShort: - return macToQtFormat(getMacDateFormat(type == DateFormatShort + return getMacDateFormat(type == DateFormatShort ? kCFDateFormatterShortStyle - : kCFDateFormatterLongStyle)); + : kCFDateFormatterLongStyle); case TimeFormatLong: case TimeFormatShort: - return macToQtFormat(getMacTimeFormat(type == TimeFormatShort + return getMacTimeFormat(type == TimeFormatShort ? kCFDateFormatterShortStyle - : kCFDateFormatterLongStyle)); + : kCFDateFormatterLongStyle); case DayNameLong: case DayNameShort: return macDayName(in.toInt(), (type == DayNameShort)); -- cgit v0.12 From cc598ec6b0d396ab11de20a3f21064522578960c Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Fri, 11 Dec 2009 17:54:22 +0100 Subject: Doc fix: mark QFileOpenEvent::url to be available since 4.6 Reviewed-by: trustme --- src/gui/kernel/qevent.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index c4a25e1..e836eda 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -3023,7 +3023,7 @@ QShowEvent::~QShowEvent() This event is only used to notify the application of a request. It may be safely ignored. - \note This class is currently supported for Mac Os X only. + \note This class is currently supported for Mac OS X only. */ /*! @@ -3066,6 +3066,8 @@ QFileOpenEvent::~QFileOpenEvent() \fn QUrl QFileOpenEvent::url() const Returns the url that is being opened. + + \since 4.6 */ QUrl QFileOpenEvent::url() const { -- cgit v0.12 From 6d84ab27595ad9b570ccaf5a3230e83aa878ef06 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 15 Dec 2009 17:07:13 +0100 Subject: An optimisation to QTextStream Using QLocale::operator== is faster than comparing languages, because when getting a language from a default constructed QLocale object, it initializes the system locale and quieries the system which languge it supports. Reviewed-by: Olivier Goffart --- src/corelib/io/qtextstream.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 594718e..47f340c 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -440,7 +440,7 @@ QTextStreamPrivate::QTextStreamPrivate(QTextStream *q_ptr) readConverterSavedState(0), #endif readConverterSavedStateOffset(0), - locale(QLocale::C) + locale(QLocale::c()) { this->q_ptr = q_ptr; reset(); @@ -1806,8 +1806,7 @@ QTextStreamPrivate::NumberParsingStatus QTextStreamPrivate::getNumber(qulonglong if (ch.isDigit()) { val *= 10; val += ch.digitValue(); - } else if (locale.language() != QLocale::C - && ch == locale.groupSeparator()) { + } else if (locale != QLocale::c() && ch == locale.groupSeparator()) { continue; } else { ungetChar(ch); @@ -1958,7 +1957,7 @@ bool QTextStreamPrivate::getReal(double *f) else if (lc == locale.negativeSign().toLower() || lc == locale.positiveSign().toLower()) input = InputSign; - else if (locale.language() != QLocale::C // backward-compatibility + else if (locale != QLocale::c() // backward-compatibility && lc == locale.groupSeparator().toLower()) input = InputDigit; // well, it isn't a digit, but no one cares. else @@ -2283,7 +2282,7 @@ bool QTextStreamPrivate::putNumber(qulonglong number, bool negative) // add thousands group separators. For backward compatibility we // don't add a group separator for C locale. - if (locale.language() != QLocale::C) + if (locale != QLocale::c()) flags |= QLocalePrivate::ThousandsGroup; const QLocalePrivate *dd = locale.d(); -- cgit v0.12 From cbe70d58bc1667b2e09f78a5d4427e7d071a2354 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 16 Dec 2009 15:44:11 +0100 Subject: Fixed wheel event delivery in graphicsview. We don't need to flip the y-coordinate of window- and view-local coordinates because they are flipped already. Reviewed-by: Prasanth --- src/gui/kernel/qcocoaview_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index ddd8ca6..6c06746 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -777,7 +777,7 @@ extern "C" { NSPoint windowPoint = [theEvent locationInWindow]; NSPoint globalPoint = [[theEvent window] convertBaseToScreen:windowPoint]; NSPoint localPoint = [self convertPoint:windowPoint fromView:nil]; - QPoint qlocal = QPoint(localPoint.x, flipYCoordinate(localPoint.y)); + QPoint qlocal = QPoint(localPoint.x, localPoint.y); QPoint qglobal = QPoint(globalPoint.x, flipYCoordinate(globalPoint.y)); Qt::MouseButtons buttons = QApplication::mouseButtons(); bool wheelOK = false; -- cgit v0.12 From 11ec7b3694feed8514f9559c7b732ad6217e88c6 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 17 Dec 2009 10:27:37 +1000 Subject: Disable benchlibwalltime test. The test is inherently dependent on the timing behavior of the test machine. For now, it seems too difficult to ensure this works everywhere. --- tests/auto/selftests/tst_selftests.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/auto/selftests/tst_selftests.cpp b/tests/auto/selftests/tst_selftests.cpp index 579f4eb..ed3b08e 100644 --- a/tests/auto/selftests/tst_selftests.cpp +++ b/tests/auto/selftests/tst_selftests.cpp @@ -182,12 +182,12 @@ void tst_Selftests::runSubTest_data() #endif QTest::newRow("benchlibeventcounter") << "benchlibeventcounter" << QStringList("-eventcounter"); QTest::newRow("benchliboptions") << "benchliboptions" << QStringList("-eventcounter"); - QTest::newRow("benchlibwalltime") << "benchlibwalltime" << QStringList(); - //### This test is affected by the speed of the CPU and whether the tick counter is - //### monotonically increasing. It won't work on some machines so leave it off by default. + //### These tests are affected by timing and whether the CPU tick counter is + //### monotonically increasing. They won't work on some machines so leave them off by default. //### Feel free to uncomment for your own testing. #if 0 + QTest::newRow("benchlibwalltime") << "benchlibwalltime" << QStringList(); QTest::newRow("benchlibtickcounter") << "benchlibtickcounter" << QStringList("-tickcounter"); #endif -- cgit v0.12 From 7371d787d9b2667132c0caadb9964189b1d8c9fc Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 17 Dec 2009 11:17:11 +1000 Subject: Disable depth testing during the 2D QGLWidget::renderText() Also document the depth testing conditions for the 2D and 3D versions of the function. Task-number: QTBUG-5041 Reviewed-by: Daniel Pope --- src/opengl/qgl.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 32534aa..466e851 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -4302,6 +4302,7 @@ static void qt_save_gl_state() glDisable(GL_CULL_FACE); glDisable(GL_LIGHTING); glDisable(GL_STENCIL_TEST); + glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } @@ -4355,6 +4356,10 @@ static void qt_gl_draw_text(QPainter *p, int x, int y, const QString &str, \note This function clears the stencil buffer. \note This function is not supported on OpenGL/ES systems. + + \note This function temporarily disables depth-testing when the + text is drawn. + \l{Overpainting Example}{Overpaint} with QPainter::drawText() instead. */ @@ -4445,6 +4450,13 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font, have the labels move with the model as it is rotated etc. \note This function is not supported on OpenGL/ES systems. + + \note If depth testing is enabled before this function is called, + then the drawn text will be depth-tested against the models that + have already been drawn in the scene. Use \c{glDisable(GL_DEPTH_TEST)} + before calling this function to annotate the models without + depth-testing the text. + \l{Overpainting Example}{Overpaint} with QPainter::drawText() instead. */ void QGLWidget::renderText(double x, double y, double z, const QString &str, const QFont &font, int) -- cgit v0.12 From 65fe21e8c1cfb70e5b763818928c6570bb67b5e3 Mon Sep 17 00:00:00 2001 From: Bill King Date: Thu, 17 Dec 2009 13:49:31 +1000 Subject: (OCI) Fixes problem with clobs being handled as binary CLOB/NCLOB/LONG are actually strings, so treat them as such. Task-number: QTBUG-4461 Reviewed-by: Justin McPherson --- src/sql/drivers/oci/qsql_oci.cpp | 4 ++-- tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp index f130087..a384ba0 100644 --- a/src/sql/drivers/oci/qsql_oci.cpp +++ b/src/sql/drivers/oci/qsql_oci.cpp @@ -517,7 +517,7 @@ QVariant::Type qDecodeOCIType(const QString& ocitype, QSql::NumericalPrecisionPo } else if (ocitype == QLatin1String("LONG") || ocitype == QLatin1String("NCLOB") || ocitype == QLatin1String("CLOB")) - type = QVariant::ByteArray; + type = QVariant::String; else if (ocitype == QLatin1String("RAW") || ocitype == QLatin1String("LONG RAW") || ocitype == QLatin1String("ROWID") || ocitype == QLatin1String("BLOB") || ocitype == QLatin1String("CFILE") || ocitype == QLatin1String("BFILE")) @@ -543,6 +543,7 @@ QVariant::Type qDecodeOCIType(int ocitype, QSql::NumericalPrecisionPolicy precis case SQLT_AVC: case SQLT_RDD: case SQLT_LNG: + case SQLT_CLOB: #ifdef SQLT_INTERVAL_YM case SQLT_INTERVAL_YM: #endif @@ -584,7 +585,6 @@ QVariant::Type qDecodeOCIType(int ocitype, QSql::NumericalPrecisionPolicy precis case SQLT_NTY: case SQLT_REF: case SQLT_RID: - case SQLT_CLOB: type = QVariant::ByteArray; break; case SQLT_DAT: diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index cb4e103..4f89708 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -942,9 +942,9 @@ void tst_QSqlDatabase::recordOCI() FieldDef("raw(2000)", QVariant::ByteArray, QByteArray(Q3CString("blah6")), false), FieldDef("blob", QVariant::ByteArray, QByteArray(Q3CString("blah7"))), #endif -//FIXME FieldDef("clob", QVariant::CString, Q3CString("blah8")), -//FIXME FieldDef("nclob", QVariant::CString, Q3CString("blah9")), -//X FieldDef("bfile", QVariant::ByteArray, QByteArray(Q3CString("blah10"))), + FieldDef("clob", QVariant::String, QString("blah8")), + FieldDef("nclob", QVariant::String, QString("blah9")), + FieldDef("bfile", QVariant::ByteArray, QByteArray("blah10")), intytm, intdts, -- cgit v0.12 From cc5ae2db39bd5cb5e7710b1b7ce1b5c92b705450 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 17 Dec 2009 14:54:05 +1000 Subject: Update FBO docs to describe how QPainter changes the GL state Using a QPainter on a QGLFramebufferObject will not return the GL context to its original conditions, especially with the OpenGL2 paint engine. Update the docs to make this clearer. Task-number: QTBUG-6712 Reviewed-by: Daniel Pope --- src/opengl/qglframebufferobject.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index d0297c9..4b5c30a 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -597,6 +597,12 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, the constructors that take a QGLFramebufferObject parameter, and set the QGLFramebufferObject::samples() property to a non-zero value. + When painting to a QGLFramebufferObject using QPainter, the state of + the current GL context will be altered by the paint engine to reflect + its needs. Applications should not rely upon the GL state being reset + to its original conditions, particularly the current shader program, + GL viewport, texture units, and drawing modes. + For multisample framebuffer objects a color render buffer is created, otherwise a texture with the specified texture target is created. The color render buffer or texture will have the specified internal -- cgit v0.12 From 91cc7d1dabfd5f42db45bedefad78a63e63c4dc8 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Thu, 17 Dec 2009 10:13:21 +0100 Subject: Fixed parsing of svg paths. Commit 928ee705 introduced a bug which affected paths with relative offsets. Task-number: QTBUG-6867 Reviewed-by: Trond --- src/svg/qsvghandler.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index b2619bf..ac220bd 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -1578,8 +1578,8 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path) count--; break; } - x = x0 = num[0] + offsetX; - y = y0 = num[1] + offsetY; + x = num[0] + offsetX; + y = num[1] + offsetY; num += 2; count -= 2; path.lineTo(x, y); @@ -1592,8 +1592,8 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path) count--; break; } - x = x0 = num[0]; - y = y0 = num[1]; + x = num[0]; + y = num[1]; num += 2; count -= 2; path.lineTo(x, y); -- cgit v0.12 From bc01bb10da23d0d2308cf02a16947be836bc9a21 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Thu, 17 Dec 2009 10:20:46 +0100 Subject: Avoid timer starvation when handling many X11 events After commit d0d0fdb8e46351b4ab8492de31e5363ef6662b57, timers are normally run at idle priority. This makes it possible for the X11 handler to starve timers indefinitely. Fix this by enforcing one normal priority pass of the timer source after we have processed all X11 events. This has the added benefit of keeping animation timers smooth and consistent, which is the intention of this change. Reviewed-by: Jens Bache-Wiig --- src/corelib/kernel/qeventdispatcher_glib.cpp | 5 +++++ src/corelib/kernel/qeventdispatcher_glib_p.h | 2 ++ src/gui/kernel/qguieventdispatcher_glib.cpp | 2 ++ 3 files changed, 9 insertions(+) diff --git a/src/corelib/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp index 665b73e..16871c3 100644 --- a/src/corelib/kernel/qeventdispatcher_glib.cpp +++ b/src/corelib/kernel/qeventdispatcher_glib.cpp @@ -341,6 +341,11 @@ QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(GMainContext *context) g_source_attach(&idleTimerSource->source, mainContext); } +void QEventDispatcherGlibPrivate::runTimersOnceWithNormalPriority() +{ + timerSource->runWithIdlePriority = false; +} + QEventDispatcherGlib::QEventDispatcherGlib(QObject *parent) : QAbstractEventDispatcher(*(new QEventDispatcherGlibPrivate), parent) { diff --git a/src/corelib/kernel/qeventdispatcher_glib_p.h b/src/corelib/kernel/qeventdispatcher_glib_p.h index 6a4e726..57cbf94 100644 --- a/src/corelib/kernel/qeventdispatcher_glib_p.h +++ b/src/corelib/kernel/qeventdispatcher_glib_p.h @@ -110,6 +110,8 @@ public: GSocketNotifierSource *socketNotifierSource; GTimerSource *timerSource; GIdleTimerSource *idleTimerSource; + + void runTimersOnceWithNormalPriority(); }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qguieventdispatcher_glib.cpp b/src/gui/kernel/qguieventdispatcher_glib.cpp index f8a638c..a252499 100644 --- a/src/gui/kernel/qguieventdispatcher_glib.cpp +++ b/src/gui/kernel/qguieventdispatcher_glib.cpp @@ -152,6 +152,8 @@ static gboolean x11EventSourceDispatch(GSource *s, GSourceFunc callback, gpointe out: + source->d->runTimersOnceWithNormalPriority(); + if (callback) callback(user_data); return true; -- cgit v0.12 From 274afe71968739b3387d0250baa59845e912e0c0 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Thu, 17 Dec 2009 10:20:03 +0100 Subject: Stack overflow when closing a Color panel in Cocoa. The QCocoaColorPanelDelegate was going into an infinite recrusion in this particular case. The patch guards the delegate from calling accept() or reject() more than once. Task-number: QTBUG-6636 Reviewed-by: Richard Moe Gustavsen --- src/gui/dialogs/qcolordialog_mac.mm | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/gui/dialogs/qcolordialog_mac.mm b/src/gui/dialogs/qcolordialog_mac.mm index 53d2e1e..5753954 100644 --- a/src/gui/dialogs/qcolordialog_mac.mm +++ b/src/gui/dialogs/qcolordialog_mac.mm @@ -79,6 +79,7 @@ QT_USE_NAMESPACE BOOL mHackedPanel; NSInteger mResultCode; BOOL mDialogIsExecuting; + BOOL mResultSet; } - (id)initWithColorPanel:(NSColorPanel *)panel stolenContentView:(NSView *)stolenContentView @@ -116,6 +117,7 @@ QT_USE_NAMESPACE mHackedPanel = (okButton != 0); mResultCode = NSCancelButton; mDialogIsExecuting = false; + mResultSet = false; if (mHackedPanel) { [self relayout]; @@ -159,11 +161,13 @@ QT_USE_NAMESPACE - (BOOL)windowShouldClose:(id)window { Q_UNUSED(window); - if (mHackedPanel) { - [self onCancelClicked]; - } else { + if (!mHackedPanel) [self updateQtColor]; + if (mDialogIsExecuting) { [self finishOffWithCode:NSCancelButton]; + } else { + mResultSet = true; + mPriv->colorDialog()->reject(); } return true; } @@ -240,11 +244,12 @@ QT_USE_NAMESPACE - (void)onCancelClicked { - Q_ASSERT(mHackedPanel); - [[mStolenContentView window] close]; - delete mQtColor; - mQtColor = new QColor(); - [self finishOffWithCode:NSCancelButton]; + if (mHackedPanel) { + [[mStolenContentView window] close]; + delete mQtColor; + mQtColor = new QColor(); + [self finishOffWithCode:NSCancelButton]; + } } - (void)updateQtColor @@ -306,10 +311,16 @@ QT_USE_NAMESPACE } else { // Since we are not in a modal event loop, we can safely close // down QColorDialog - if (mResultCode == NSCancelButton) - mPriv->colorDialog()->reject(); - else - mPriv->colorDialog()->accept(); + // Calling accept() or reject() can in turn call closeCocoaColorPanel. + // This check will prevent any such recursion. + if (!mResultSet) { + mResultSet = true; + if (mResultCode == NSCancelButton) { + mPriv->colorDialog()->reject(); + } else { + mPriv->colorDialog()->accept(); + } + } } } -- cgit v0.12 From 7dcf7e6f2593a2d2e3ee5768e27cdf17500c90c9 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Thu, 17 Dec 2009 11:23:19 +0100 Subject: Stop the configuration if the test compiler cannot be found. Author: Adrian Constantin Reviewed-by: Thiago Macieira --- configure | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/configure b/configure index 8d9d371..04f17bd 100755 --- a/configure +++ b/configure @@ -2922,6 +2922,10 @@ fi QMAKE_CONF_COMPILER=`getQMakeConf "$XQMAKESPEC" | grep "^QMAKE_CXX[^_A-Z0-9]" | sed "s,.* *= *\(.*\)$,\1," | tail -1` TEST_COMPILER="$CC" [ -z "$TEST_COMPILER" ] && TEST_COMPILER=$QMAKE_CONF_COMPILER +if [ -z "$TEST_COMPILER" ]; then + echo "ERROR: Cannot set the compiler for the configuration tests" + exit 1 +fi # auto-detect precompiled header support if [ "$CFG_PRECOMPILE" = "auto" ]; then -- cgit v0.12 From e2ed04bac3cd353711bfd50eba3232692b40ab99 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Thu, 17 Dec 2009 11:26:31 +0100 Subject: Configure support for multiple include levels in qmake.conf hierarchy. If a configuration file included in qmake.conf had an include statements of its own, the variables defined in the second level of included files were not parsed by getQMakeConf function from configure. Author: Adrian Constantin Reviewed-by: Thiago Macieira --- configure | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/configure b/configure index 04f17bd..1b1799c 100755 --- a/configure +++ b/configure @@ -106,6 +106,28 @@ QMakeVar() echo "$2" "$eq" "$3" >> "$QMAKE_VARS_FILE" } +# Helper function for getQMakeConf. It parses include statements in +# qmake.conf and prints out the expanded file +getQMakeConf1() +{ + while read line; do case "$line" in + include*) + inc_file=`echo "$line" | sed -n -e "/^include.*(.*)/s/include.*(\(.*\)).*$/\1/p"` + current_dir=`dirname "$1"` + conf_file="$current_dir/$inc_file" + if [ ! -e "$conf_file" ]; then + echo "WARNING: Unable to find file $conf_file" >&2 + continue + fi + getQMakeConf1 "$conf_file" + ;; + *) + echo "$line" + ;; + esac; done < "$1" +} + + # relies on $QMAKESPEC being set correctly. parses include statements in # qmake.conf and prints out the expanded file getQMakeConf() @@ -114,15 +136,7 @@ getQMakeConf() if [ -n "$1" ]; then tmpSPEC="$1" fi - $AWK -v "QMAKESPEC=$tmpSPEC" ' -/^include\(.+\)$/{ - fname = QMAKESPEC "/" substr($0, 9, length($0) - 9) - while ((getline line < fname) > 0) - print line - close(fname) - next -} -{ print }' "$tmpSPEC/qmake.conf" + getQMakeConf1 "$tmpSPEC/qmake.conf" } # relies on $TEST_COMPILER being set correctly -- cgit v0.12 From ea8d13b61097ec295721b1e6f2bf614d12253c8c Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 17 Dec 2009 13:17:21 +0100 Subject: doc: Added discussion on connecting signals that have default arg values. Task-number: QTBUG-3913 --- doc/src/objectmodel/signalsandslots.qdoc | 39 ++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/doc/src/objectmodel/signalsandslots.qdoc b/doc/src/objectmodel/signalsandslots.qdoc index 9515904..d5e3280 100644 --- a/doc/src/objectmodel/signalsandslots.qdoc +++ b/doc/src/objectmodel/signalsandslots.qdoc @@ -376,6 +376,45 @@ Some irrelevant member functions have been omitted from this example. + \section1 Signals And Slots With Default Arguments + + The signatures of signals and slots may contain arguments, and the + arguments can have defualt values. Consider QObject::destroyed(): + + \code + void destroyed(QObject* = 0); + \endcode + + When a QObject is deleted, it emits this QObject::destroyed() + signal. We want to catch this signal, wherever we might have a + dangling reference to the deleted QObject, so we can clean it up. + A suitable slot signature might be: + + \code + void objectDestroyed(QObject* obj = 0); + \endcode + + To connect the signal to the slot, we use QObject::connect() and + the \c{SIGNAL()} and \c{SLOT()} macros. The rule about whether to + include arguments or not in the \c{SIGNAL()} and \c{SLOT()} + macros, if the arguments have default values, is that the + signature passed to the \c{SIGNAL()} macro must \e not have fewer + arguments than the signature passed to the \c{SLOT()} macro. + + All of these would work: + \code + connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(Qbject*))); + connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed())); + connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed())); + \endcode + But this one won't work: + \code + connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed(QObject*))); + \endcode + + ...because the slot will be expecting a QObject that the signal + will not send. This connection will report a runtime error. + \section1 Advanced Signals and Slots Usage For cases where you may require information on the sender of the -- cgit v0.12 From 7698c6d25fb1e017a84ec67c08eb4c3dc3568515 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 17 Dec 2009 13:49:27 +0100 Subject: Doc: setFeature snippet was in the wrong place Reviewed-by: Niels Weber --- src/xml/sax/qxml.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp index 0a87412..27ec3bd 100644 --- a/src/xml/sax/qxml.cpp +++ b/src/xml/sax/qxml.cpp @@ -3063,11 +3063,11 @@ void QXmlSimpleReaderPrivate::initIncrementalParsing() Aspects of the parsing behavior can be adapted using setFeature() and setProperty(). + \snippet doc/src/snippets/code/src_xml_sax_qxml.cpp 0 + QXmlSimpleReader is not reentrant. If you want to use the class in threaded code, lock the code using QXmlSimpleReader with a locking mechanism, such as a QMutex. - - \snippet doc/src/snippets/code/src_xml_sax_qxml.cpp 0 */ static inline bool is_S(QChar ch) -- cgit v0.12 From 124a77d258346d8d1bbffa7c42249d09433bc18f Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 17 Dec 2009 15:10:55 +0200 Subject: Fixed QCoeFepInputContext::widgetDestroyed Calling SetFocus twice here was obsolete and caused intermittent panics. Replaced them with proper queueInputCapabilitiesChanged call. Task-number: QTBUG-6519 Reviewed-by: axis --- src/gui/inputmethod/qcoefepinputcontext_s60.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index a295d66..1bf7662 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -139,8 +139,7 @@ void QCoeFepInputContext::widgetDestroyed(QWidget *w) // Make sure that the input capabilities of whatever new widget got focused are queried. CCoeControl *ctrl = w->effectiveWinId(); if (ctrl->IsFocused()) { - ctrl->SetFocus(false); - ctrl->SetFocus(true); + queueInputCapabilitiesChanged(); } } -- cgit v0.12 From 05d1efb5322651cbe227c9fd6ac200cfff423a91 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 17 Dec 2009 15:33:04 +0200 Subject: WeatherInfo now shows Oslo info upon launch instead of blank screen Task-number: QTBUG-6367 Reviewed-by: Janne Anttila --- demos/embedded/weatherinfo/weatherinfo.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/demos/embedded/weatherinfo/weatherinfo.cpp b/demos/embedded/weatherinfo/weatherinfo.cpp index 842f05b..3b78a5f 100644 --- a/demos/embedded/weatherinfo/weatherinfo.cpp +++ b/demos/embedded/weatherinfo/weatherinfo.cpp @@ -105,9 +105,8 @@ private slots: void delayedInit() { #if defined(Q_OS_SYMBIAN) qt_SetDefaultIap(); -#else - request("Oslo"); #endif + request("Oslo"); } private slots: -- cgit v0.12 From c74d9d92f0d9c372de71ccf865edffae92a92d98 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Thu, 17 Dec 2009 14:45:04 +0100 Subject: Doc: fix typo Fixes: QTBUG-6539 --- src/network/access/qnetworkreply.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp index 9ab4057..e6ca367 100644 --- a/src/network/access/qnetworkreply.cpp +++ b/src/network/access/qnetworkreply.cpp @@ -171,7 +171,7 @@ QNetworkReplyPrivate::QNetworkReplyPrivate() \value UnknownProxyError an unknown proxy-related error was detected - \value UnknownContentError an unknonwn error related to + \value UnknownContentError an unknown error related to the remote content was detected \value ProtocolFailure a breakdown in protocol was -- cgit v0.12 From ca30ced65ead8e81dfcb25178f4bfb6244487356 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Thu, 17 Dec 2009 14:34:16 +0100 Subject: GL2Engine: Don't mark brush as dirty if it hasn't changed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the same brush is used over and over again, this gives a huge performance boost (measured to be 25% faster on desktop and 73% faster on SGX). Reviewed-By: Samuel Rødal --- .../gl2paintengineex/qglengineshadermanager.cpp | 1 + .../gl2paintengineex/qpaintengineex_opengl2.cpp | 69 ++++++++++++---------- .../gl2paintengineex/qpaintengineex_opengl2_p.h | 5 +- 3 files changed, 41 insertions(+), 34 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 8a8f483..1187c2d 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -406,6 +406,7 @@ void QGLEngineShaderManager::setDirty() void QGLEngineShaderManager::setSrcPixelType(Qt::BrushStyle style) { + Q_ASSERT(style != Qt::NoBrush); if (srcPixelType == PixelSrcType(style)) return; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index fb9bcb4..8ca2fd4 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -386,19 +386,25 @@ inline QColor qt_premultiplyColor(QColor c, GLfloat opacity) } -void QGL2PaintEngineExPrivate::setBrush(const QBrush* brush) +void QGL2PaintEngineExPrivate::setBrush(const QBrush& brush) { + Q_ASSERT(brush.style() != Qt::NoBrush); + + if (qbrush_fast_equals(currentBrush, brush)) + return; + currentBrush = brush; + brushTextureDirty = true; brushUniformsDirty = true; - if (currentBrush->style() == Qt::TexturePattern - && qHasPixmapTexture(*brush) && brush->texture().isQBitmap()) + if (currentBrush.style() == Qt::TexturePattern + && qHasPixmapTexture(brush) && brush.texture().isQBitmap()) { shaderManager->setSrcPixelType(QGLEngineShaderManager::TextureSrcWithPattern); } else { - shaderManager->setSrcPixelType(currentBrush->style()); + shaderManager->setSrcPixelType(currentBrush.style()); } - shaderManager->optimiseForBrushTransform(currentBrush->transform()); + shaderManager->optimiseForBrushTransform(currentBrush.transform()); } @@ -420,7 +426,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() { Q_Q(QGL2PaintEngineEx); // qDebug("QGL2PaintEngineExPrivate::updateBrushTexture()"); - Qt::BrushStyle style = currentBrush->style(); + Qt::BrushStyle style = currentBrush.style(); if ( (style >= Qt::Dense1Pattern) && (style <= Qt::DiagCrossPattern) ) { // Get the image data for the pattern @@ -433,7 +439,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() else if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) { // Gradiant brush: All the gradiants use the same texture - const QGradient* g = currentBrush->gradient(); + const QGradient* g = currentBrush.gradient(); // We apply global opacity in the fragment shaders, so we always pass 1.0 // for opacity to the cache. @@ -450,7 +456,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, q->state()->renderHints & QPainter::SmoothPixmapTransform); } else if (style == Qt::TexturePattern) { - const QPixmap& texPixmap = currentBrush->texture(); + const QPixmap& texPixmap = currentBrush.texture(); glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); QGLTexture *tex = ctx->d_func()->bindTexture(texPixmap, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption); @@ -464,15 +470,15 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() void QGL2PaintEngineExPrivate::updateBrushUniforms() { // qDebug("QGL2PaintEngineExPrivate::updateBrushUniforms()"); - Qt::BrushStyle style = currentBrush->style(); + Qt::BrushStyle style = currentBrush.style(); if (style == Qt::NoBrush) return; - QTransform brushQTransform = currentBrush->transform(); + QTransform brushQTransform = currentBrush.transform(); if (style == Qt::SolidPattern) { - QColor col = qt_premultiplyColor(currentBrush->color(), (GLfloat)q->state()->opacity); + QColor col = qt_premultiplyColor(currentBrush.color(), (GLfloat)q->state()->opacity); shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::FragmentColor), col); } else { @@ -480,7 +486,7 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() QPointF translationPoint; if (style <= Qt::DiagCrossPattern) { - QColor col = qt_premultiplyColor(currentBrush->color(), (GLfloat)q->state()->opacity); + QColor col = qt_premultiplyColor(currentBrush.color(), (GLfloat)q->state()->opacity); shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::PatternColor), col); @@ -488,7 +494,7 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); } else if (style == Qt::LinearGradientPattern) { - const QLinearGradient *g = static_cast(currentBrush->gradient()); + const QLinearGradient *g = static_cast(currentBrush.gradient()); QPointF realStart = g->start(); QPointF realFinal = g->finalStop(); @@ -508,7 +514,7 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); } else if (style == Qt::ConicalGradientPattern) { - const QConicalGradient *g = static_cast(currentBrush->gradient()); + const QConicalGradient *g = static_cast(currentBrush.gradient()); translationPoint = g->center(); GLfloat angle = -(g->angle() * 2 * Q_PI) / 360.0; @@ -519,7 +525,7 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); } else if (style == Qt::RadialGradientPattern) { - const QRadialGradient *g = static_cast(currentBrush->gradient()); + const QRadialGradient *g = static_cast(currentBrush.gradient()); QPointF realCenter = g->center(); QPointF realFocal = g->focalPoint(); qreal realRadius = g->radius(); @@ -537,10 +543,10 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); } else if (style == Qt::TexturePattern) { - const QPixmap& texPixmap = currentBrush->texture(); + const QPixmap& texPixmap = currentBrush.texture(); - if (qHasPixmapTexture(*currentBrush) && currentBrush->texture().isQBitmap()) { - QColor col = qt_premultiplyColor(currentBrush->color(), (GLfloat)q->state()->opacity); + if (qHasPixmapTexture(currentBrush) && currentBrush.texture().isQBitmap()) { + QColor col = qt_premultiplyColor(currentBrush.color(), (GLfloat)q->state()->opacity); shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::PatternColor), col); } @@ -561,7 +567,7 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() QTransform gl_to_qt(1, 0, 0, -1, 0, height); QTransform inv_matrix; if (style == Qt::TexturePattern && textureInvertedY == -1) - inv_matrix = gl_to_qt * (QTransform(1, 0, 0, -1, 0, currentBrush->texture().height()) * brushQTransform * matrix).inverted() * translate; + inv_matrix = gl_to_qt * (QTransform(1, 0, 0, -1, 0, currentBrush.texture().height()) * brushQTransform * matrix).inverted() * translate; else inv_matrix = gl_to_qt * (brushQTransform * matrix).inverted() * translate; @@ -866,7 +872,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) // Check to see if there's any hints if (path.shape() == QVectorPath::RectangleHint) { QGLRect rect(points[0].x(), points[0].y(), points[2].x(), points[2].y()); - prepareForDraw(currentBrush->isOpaque()); + prepareForDraw(currentBrush.isOpaque()); composite(rect); } else if (path.isConvex()) { @@ -914,7 +920,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) #endif } - prepareForDraw(currentBrush->isOpaque()); + prepareForDraw(currentBrush.isOpaque()); glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); #ifdef QT_OPENGL_CACHE_AS_VBOS glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); @@ -933,7 +939,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) path.makeCacheable(); vertexCoordinateArray.clear(); vertexCoordinateArray.addPath(path, inverseScale, false); - prepareForDraw(currentBrush->isOpaque()); + prepareForDraw(currentBrush.isOpaque()); drawVertexArrays(vertexCoordinateArray, GL_TRIANGLE_FAN); } @@ -958,7 +964,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT); } - prepareForDraw(currentBrush->isOpaque()); + prepareForDraw(currentBrush.isOpaque()); if (inRenderText) prepareDepthRangeForRenderText(); @@ -1155,10 +1161,10 @@ bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) : QGLEngineShaderManager::NoOpacity; if (stateHasOpacity && (mode != ImageDrawingMode)) { // Using a brush - bool brushIsPattern = (currentBrush->style() >= Qt::Dense1Pattern) && - (currentBrush->style() <= Qt::DiagCrossPattern); + bool brushIsPattern = (currentBrush.style() >= Qt::Dense1Pattern) && + (currentBrush.style() <= Qt::DiagCrossPattern); - if ((currentBrush->style() == Qt::SolidPattern) || brushIsPattern) + if ((currentBrush.style() == Qt::SolidPattern) || brushIsPattern) opacityMode = QGLEngineShaderManager::NoOpacity; // Global opacity handled by srcPixel shader } } @@ -1286,7 +1292,7 @@ void QGL2PaintEngineEx::fill(const QVectorPath &path, const QBrush &brush) d->matrixDirty = true; } - d->setBrush(&brush); + d->setBrush(brush); d->fill(path); if (doOffset) { @@ -1325,7 +1331,7 @@ void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) } bool opaque = penBrush.isOpaque() && s->opacity > 0.99; - d->setBrush(&penBrush); + d->setBrush(penBrush); d->transferMode(BrushDrawingMode); // updateMatrix() is responsible for setting the inverse scale on @@ -1604,7 +1610,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, QFontEngineGly glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray.data()); QBrush pensBrush = q->state()->pen.brush(); - setBrush(&pensBrush); + setBrush(pensBrush); if (inRenderText) prepareDepthRangeForRenderText(); @@ -1649,7 +1655,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, QFontEngineGly q->state()->opacity = 1; opacityUniformDirty = true; pensBrush = Qt::white; - setBrush(&pensBrush); + setBrush(pensBrush); } compositionModeDirty = false; // I can handle this myself, thank you very much @@ -1670,7 +1676,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, QFontEngineGly q->state()->opacity = oldOpacity; opacityUniformDirty = true; pensBrush = q->state()->pen.brush(); - setBrush(&pensBrush); + setBrush(pensBrush); } compositionModeDirty = false; @@ -1815,6 +1821,7 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) d->opacityUniformDirty = true; d->needsSync = true; d->use_system_clip = !systemClip().isEmpty(); + d->currentBrush = QBrush(); d->dirtyStencilRegion = QRect(0, 0, d->width, d->height); d->stencilClean = true; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 77ca3a8..33ce24d 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -171,7 +171,6 @@ public: q(q_ptr), width(0), height(0), ctx(0), - currentBrush(0), inverseScale(1), shaderManager(0), inRenderText(false) @@ -185,7 +184,7 @@ public: void updateCompositionMode(); void updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id = -1); - void setBrush(const QBrush* brush); + void setBrush(const QBrush& brush); void transferMode(EngineMode newMode); void resetGLState(); @@ -244,7 +243,7 @@ public: QRect currentScissorBounds; uint maxClip; - const QBrush* currentBrush; // May not be the state's brush! + QBrush currentBrush; // May not be the state's brush! GLfloat inverseScale; -- cgit v0.12 From 17977f5067ab75541029d7278776ea8ff999ee77 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 17 Dec 2009 15:54:42 +0100 Subject: Designer: Fix compilation with -static on Mac OS X Avoid linking the solutions used by Designer twice (in the two Designer libraries). Just use the include paths in case of static linking. Reviewed-by: Carlos Duclos Task-number: QTBUG-6863 --- .../src/components/objectinspector/objectinspector.pri | 8 +++++++- .../designer/src/components/propertyeditor/propertyeditor.pri | 11 +++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/tools/designer/src/components/objectinspector/objectinspector.pri b/tools/designer/src/components/objectinspector/objectinspector.pri index 280a1dc..733c4b3 100644 --- a/tools/designer/src/components/objectinspector/objectinspector.pri +++ b/tools/designer/src/components/objectinspector/objectinspector.pri @@ -1,4 +1,10 @@ -include($$QT_SOURCE_TREE/tools/shared/findwidget/findwidget.pri) +# --- The Find widget is also linked into the designer_shared library. +# Avoid conflict when linking statically +contains(CONFIG, static) { + INCLUDEPATH *= $$QT_SOURCE_TREE/tools/shared/findwidget +} else { + include($$QT_SOURCE_TREE/tools/shared/findwidget/findwidget.pri) +} INCLUDEPATH += $$PWD diff --git a/tools/designer/src/components/propertyeditor/propertyeditor.pri b/tools/designer/src/components/propertyeditor/propertyeditor.pri index d3e44a5..a8ed37e 100644 --- a/tools/designer/src/components/propertyeditor/propertyeditor.pri +++ b/tools/designer/src/components/propertyeditor/propertyeditor.pri @@ -4,8 +4,15 @@ INCLUDEPATH += $$PWD -include($$QT_SOURCE_TREE/tools/shared/qtpropertybrowser/qtpropertybrowser.pri) -include($$QT_SOURCE_TREE/tools/shared/qtgradienteditor/qtcolorbutton.pri) +# --- Property browser is also linked into the designer_shared library. +# Avoid conflict when linking statically +contains(CONFIG, static) { + INCLUDEPATH *= $$QT_SOURCE_TREE/tools/shared/qtpropertybrowser + INCLUDEPATH *= $$QT_SOURCE_TREE/tools/shared/qtgradienteditor +} else { + include($$QT_SOURCE_TREE/tools/shared/qtpropertybrowser/qtpropertybrowser.pri) + include($$QT_SOURCE_TREE/tools/shared/qtgradienteditor/qtcolorbutton.pri) +} FORMS += $$PWD/paletteeditor.ui \ $$PWD/stringlisteditor.ui \ -- cgit v0.12 From face84c73a2196432020dda18755af7955d2de39 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Wed, 16 Dec 2009 14:10:36 +0100 Subject: Change QHostInfo to use 5 parallel lookup threads Instead of sequentially looking up and potentially taking a long time, we now do work in parallel. Reviewed-by: ogoffart Reviewed-by: lars --- src/network/kernel/qhostinfo.cpp | 297 ++++++++++++++++++++++----------- src/network/kernel/qhostinfo_p.h | 148 ++++++---------- src/network/kernel/qhostinfo_win.cpp | 6 +- tests/auto/qhostinfo/tst_qhostinfo.cpp | 49 +++++- 4 files changed, 305 insertions(+), 195 deletions(-) diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index 98a39cd..e77a425 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -60,11 +60,9 @@ QT_BEGIN_NAMESPACE -Q_GLOBAL_STATIC(QHostInfoAgent, theAgent) -void QHostInfoAgent::staticCleanup() -{ - theAgent()->cleanup(); -} +#ifndef QT_NO_THREAD +Q_GLOBAL_STATIC(QHostInfoLookupManager, theHostInfoLookupManager) +#endif //#define QHOSTINFO_DEBUG @@ -143,6 +141,9 @@ static QBasicAtomicInt theIdCounter = Q_BASIC_ATOMIC_INITIALIZER(1); \snippet doc/src/snippets/code/src_network_kernel_qhostinfo.cpp 4 + \note There is no guarantee on the order the signals will be emitted + if you start multiple requests with lookupHost(). + \sa abortHostLookup(), addresses(), error(), fromName() */ int QHostInfo::lookupHost(const QString &name, QObject *receiver, @@ -159,38 +160,32 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver, qRegisterMetaType("QHostInfo"); -#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) - QWindowsSockInit bust; // makes sure WSAStartup was callled -#endif - - QScopedPointer result(new QHostInfoResult); - result.data()->autoDelete = false; - QObject::connect(result.data(), SIGNAL(resultsReady(QHostInfo)), - receiver, member); - int id = result.data()->lookupId = theIdCounter.fetchAndAddRelaxed(1); + int id = theIdCounter.fetchAndAddRelaxed(1); // generate unique ID if (name.isEmpty()) { - QHostInfo info(id); - info.setError(QHostInfo::HostNotFound); - info.setErrorString(QObject::tr("No host name given")); - QMetaObject::invokeMethod(result.data(), "emitResultsReady", Qt::QueuedConnection, - Q_ARG(QHostInfo, info)); - result.take()->autoDelete = true; + QHostInfo hostInfo(id); + hostInfo.setError(QHostInfo::HostNotFound); + hostInfo.setErrorString(QObject::tr("No host name given")); + QScopedPointer result(new QHostInfoResult); + QObject::connect(result.data(), SIGNAL(resultsReady(QHostInfo)), + receiver, member, Qt::QueuedConnection); + result.data()->emitResultsReady(hostInfo); return id; } - QHostInfoAgent *agent = theAgent(); - agent->addHostName(name, result.take()); - -#if !defined QT_NO_THREAD - if (!agent->isRunning()) - agent->start(); +#ifdef QT_NO_THREAD + QHostInfo hostInfo = QHostInfoAgent::fromName(name); + hostInfo.setLookupId(id); + QScopedPointer result(new QHostInfoResult); + QObject::connect(result.data(), SIGNAL(resultsReady(QHostInfo)), + receiver, member, Qt::QueuedConnection); + result.data()->emitResultsReady(hostInfo); #else -// if (!agent->isRunning()) - agent->run(); -// else -// agent->wakeOne(); + QHostInfoRunnable* runnable = new QHostInfoRunnable(name, id); + QObject::connect(&runnable->resultEmitter, SIGNAL(resultsReady(QHostInfo)), receiver, member, Qt::QueuedConnection); + theHostInfoLookupManager()->scheduleLookup(runnable); #endif + return id; } @@ -201,8 +196,12 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver, */ void QHostInfo::abortHostLookup(int id) { - QHostInfoAgent *agent = theAgent(); - agent->abortLookup(id); +#ifndef QT_NO_THREAD + theHostInfoLookupManager()->abortLookup(id); +#else + // we cannot abort if it was non threaded.. the result signal has already been posted + Q_UNUSED(id); +#endif } /*! @@ -228,70 +227,6 @@ QHostInfo QHostInfo::fromName(const QString &name) } /*! - \internal - Pops a query off the queries list, performs a blocking call to - QHostInfoAgent::lookupHost(), and emits the resultsReady() - signal. This process repeats until the queries list is empty. -*/ -void QHostInfoAgent::run() -{ -#ifndef QT_NO_THREAD - // Dont' allow thread termination during event delivery, but allow it - // during the actual blocking host lookup stage. - setTerminationEnabled(false); - forever -#endif - { - QHostInfoQuery *query; - { -#ifndef QT_NO_THREAD - // the queries list is shared between threads. lock all - // access to it. - QMutexLocker locker(&mutex); - if (!quit && queries.isEmpty()) - cond.wait(&mutex); - if (quit) { - // Reset the quit variable in case QCoreApplication is - // destroyed and recreated. - quit = false; - break; - } - if (queries.isEmpty()) - continue; -#else - if (queries.isEmpty()) - return; -#endif - query = queries.takeFirst(); - pendingQueryId = query->object->lookupId; - } - -#if defined(QHOSTINFO_DEBUG) - qDebug("QHostInfoAgent::run(%p): looking up \"%s\"", this, - query->hostName.toLatin1().constData()); -#endif - -#ifndef QT_NO_THREAD - // Start query - allow termination at this point, but not outside. We - // don't want to all termination during event delivery, but we don't - // want the lookup to prevent the app from quitting (the agent - // destructor terminates the thread). - setTerminationEnabled(true); -#endif - QHostInfo info = fromName(query->hostName); -#ifndef QT_NO_THREAD - setTerminationEnabled(false); -#endif - - int id = query->object->lookupId; - info.setLookupId(id); - if (pendingQueryId == id) - query->object->emitResultsReady(info); - delete query; - } -} - -/*! \enum QHostInfo::HostInfoError This enum describes the various errors that can occur when trying @@ -467,4 +402,174 @@ void QHostInfo::setErrorString(const QString &str) \sa hostName() */ +#ifndef QT_NO_THREAD +QHostInfoRunnable::QHostInfoRunnable(QString hn, int i) : toBeLookedUp(hn), id(i) +{ + setAutoDelete(true); +} + +// the QHostInfoLookupManager will at some point call this via a QThreadPool +void QHostInfoRunnable::run() +{ + QHostInfoLookupManager *manager = theHostInfoLookupManager(); + // check aborted + if (manager->wasAborted(id)) { + manager->lookupFinished(this); + return; + } + + // check cache + // FIXME + + // if not in cache: OS lookup + QHostInfo hostInfo = QHostInfoAgent::fromName(toBeLookedUp); + + // save to cache + // FIXME + + // check aborted again + if (manager->wasAborted(id)) { + manager->lookupFinished(this); + return; + } + + // signal emission + hostInfo.setLookupId(id); + resultEmitter.emitResultsReady(hostInfo); + + manager->lookupFinished(this); + + // thread goes back to QThreadPool +} + +QHostInfoLookupManager::QHostInfoLookupManager() : mutex(QMutex::Recursive), wasDeleted(false) +{ + moveToThread(QCoreApplicationPrivate::mainThread()); + threadPool.setMaxThreadCount(5); // do 5 DNS lookups in parallel +} + +QHostInfoLookupManager::~QHostInfoLookupManager() +{ + wasDeleted = true; +} + +void QHostInfoLookupManager::work() +{ + if (wasDeleted) + return; + + // goals of this function: + // - launch new lookups via the thread pool + // - make sure only one lookup per host/IP is in progress + + QMutexLocker locker(&mutex); + + if (!finishedLookups.isEmpty()) { + // remove ID from aborted if it is in there + for (int i = 0; i < finishedLookups.length(); i++) { + abortedLookups.removeAll(finishedLookups.at(i)->id); + } + + finishedLookups.clear(); + } + + if (!postponedLookups.isEmpty()) { + // try to start the postponed ones + + QMutableListIterator iterator(postponedLookups); + while (iterator.hasNext()) { + QHostInfoRunnable* postponed = iterator.next(); + + // check if none of the postponed hostnames is currently running + bool alreadyRunning = false; + for (int i = 0; i < currentLookups.length(); i++) { + if (currentLookups.at(i)->toBeLookedUp == postponed->toBeLookedUp) { + alreadyRunning = true; + break; + } + } + if (!alreadyRunning) { + iterator.remove(); + scheduledLookups.prepend(postponed); // prepend! we want to finish it ASAP + } + } + } + + if (!scheduledLookups.isEmpty()) { + // try to start the new ones + QMutableListIterator iterator(scheduledLookups); + while (iterator.hasNext()) { + QHostInfoRunnable *scheduled = iterator.next(); + + // check if a lookup for this host is already running, then postpone + for (int i = 0; i < currentLookups.size(); i++) { + if (currentLookups.at(i)->toBeLookedUp == scheduled->toBeLookedUp) { + iterator.remove(); + postponedLookups.append(scheduled); + scheduled = 0; + break; + } + } + + if (scheduled && threadPool.tryStart(scheduled)) { + // runnable now running in new thread, track this in currentLookups + iterator.remove(); + currentLookups.append(scheduled); + } else if (scheduled) { + // wanted to start, but could not because thread pool is busy + break; + } else { + // was postponed, continue iterating + continue; + } + }; + } +} + +// called by QHostInfo +void QHostInfoLookupManager::scheduleLookup(QHostInfoRunnable *r) +{ + if (wasDeleted) + return; + + QMutexLocker locker(&this->mutex); + scheduledLookups.enqueue(r); + work(); +} + +// called by QHostInfo +void QHostInfoLookupManager::abortLookup(int id) +{ + if (wasDeleted) + return; + + QMutexLocker locker(&this->mutex); + if (!abortedLookups.contains(id)) + abortedLookups.append(id); +} + +// called from QHostInfoRunnable +bool QHostInfoLookupManager::wasAborted(int id) +{ + if (wasDeleted) + return true; + + QMutexLocker locker(&this->mutex); + return abortedLookups.contains(id); +} + +// called from QHostInfoRunnable +void QHostInfoLookupManager::lookupFinished(QHostInfoRunnable *r) +{ + if (wasDeleted) + return; + + QMutexLocker locker(&this->mutex); + currentLookups.removeOne(r); + finishedLookups.append(r); + work(); +} + +#endif // QT_NO_THREAD + QT_END_NAMESPACE diff --git a/src/network/kernel/qhostinfo_p.h b/src/network/kernel/qhostinfo_p.h index afd3570..643bb73 100644 --- a/src/network/kernel/qhostinfo_p.h +++ b/src/network/kernel/qhostinfo_p.h @@ -61,17 +61,17 @@ #include "QtCore/qobject.h" #include "QtCore/qpointer.h" -#if !defined QT_NO_THREAD +#ifndef QT_NO_THREAD #include "QtCore/qthread.h" -# define QHostInfoAgentBase QThread -#else -# define QHostInfoAgentBase QObject +#include "QtCore/qthreadpool.h" +#include "QtCore/qmutex.h" +#include "QtCore/qrunnable.h" +#include "QtCore/qlist.h" +#include "QtCore/qqueue.h" #endif QT_BEGIN_NAMESPACE -static const int QHOSTINFO_THREAD_WAIT = 250; // ms - class QHostInfoResult : public QObject { Q_OBJECT @@ -79,102 +79,18 @@ public Q_SLOTS: inline void emitResultsReady(const QHostInfo &info) { emit resultsReady(info); - if (autoDelete) - delete this; } Q_SIGNALS: - void resultsReady(const QHostInfo &info); - -public: - int lookupId; - bool autoDelete; + void resultsReady(const QHostInfo info); }; -struct QHostInfoQuery -{ - inline QHostInfoQuery() : object(0) {} - inline ~QHostInfoQuery() { delete object; } - inline QHostInfoQuery(const QString &name, QHostInfoResult *result) - : hostName(name), object(result) {} - - QString hostName; - QHostInfoResult *object; -}; - -class QHostInfoAgent : public QHostInfoAgentBase +// needs to be QObject because fromName calls tr() +class QHostInfoAgent : public QObject { Q_OBJECT public: - inline QHostInfoAgent() - { - // There is a chance that there will be two instances of - // QHostInfoAgent if two threads try to get Q_GLOBAL_STATIC - // object at the same time. The second object will be deleted - // immediately before anyone uses it, but we need to be - // careful about what we do in the constructor. - static QBasicAtomicInt done = Q_BASIC_ATOMIC_INITIALIZER(0); - if (done.testAndSetRelaxed(0, 1)) - qAddPostRoutine(staticCleanup); - moveToThread(QCoreApplicationPrivate::mainThread()); - quit = false; - pendingQueryId = -1; - } - inline ~QHostInfoAgent() - { cleanup(); } - - void run(); static QHostInfo fromName(const QString &hostName); - - inline void addHostName(const QString &name, QHostInfoResult *result) - { - QMutexLocker locker(&mutex); - queries << new QHostInfoQuery(name, result); - cond.wakeOne(); - } - - inline void abortLookup(int id) - { - QMutexLocker locker(&mutex); - for (int i = 0; i < queries.size(); ++i) { - QHostInfoResult *result = queries.at(i)->object; - if (result->lookupId == id) { - result->disconnect(); - delete queries.takeAt(i); - return; - } - } - if (pendingQueryId == id) - pendingQueryId = -1; - } - - static void staticCleanup(); - -public Q_SLOTS: - inline void cleanup() - { - { - QMutexLocker locker(&mutex); - qDeleteAll(queries); - queries.clear(); - quit = true; - cond.wakeOne(); - } -#ifndef QT_NO_THREAD - if (!wait(QHOSTINFO_THREAD_WAIT)) { - terminate(); - // Don't wait forever; see QTBUG-5296. - wait(QHOSTINFO_THREAD_WAIT); - } -#endif - } - -private: - QList queries; - QMutex mutex; - QWaitCondition cond; - volatile bool quit; - int pendingQueryId; }; class QHostInfoPrivate @@ -194,6 +110,52 @@ public: int lookupId; }; +#ifndef QT_NO_THREAD +// the following classes are used for the (normal) case: We use multiple threads to lookup DNS + +class QHostInfoRunnable : public QRunnable +{ +public: + QHostInfoRunnable (QString hn, int i); + void run(); + + QString toBeLookedUp; + int id; + QHostInfoResult resultEmitter; +}; + +class QHostInfoLookupManager : public QObject +{ + Q_OBJECT +public: + QHostInfoLookupManager(); + ~QHostInfoLookupManager(); + + void work(); + + // called from QHostInfo + void scheduleLookup(QHostInfoRunnable *r); + void abortLookup(int id); + + // called from QHostInfoRunnable + void lookupFinished(QHostInfoRunnable *r); + bool wasAborted(int id); + +protected: + QList currentLookups; // in progress + QList postponedLookups; // postponed because in progress for same host + QQueue scheduledLookups; // not yet started + QList finishedLookups; // recently finished + QList abortedLookups; // ids of aborted lookups + + QThreadPool threadPool; + + QMutex mutex; + + bool wasDeleted; +}; +#endif + QT_END_NAMESPACE #endif // QHOSTINFO_P_H diff --git a/src/network/kernel/qhostinfo_win.cpp b/src/network/kernel/qhostinfo_win.cpp index 720aaa5..727a8b0 100644 --- a/src/network/kernel/qhostinfo_win.cpp +++ b/src/network/kernel/qhostinfo_win.cpp @@ -105,11 +105,7 @@ static void resolveLibrary() #include QMutex qPrivCEMutex; #endif -/* - Performs a blocking call to gethostbyname or getaddrinfo, stores - the results in a QHostInfo structure and emits the - resultsReady() signal. -*/ + QHostInfo QHostInfoAgent::fromName(const QString &hostName) { #if defined(Q_OS_WINCE) diff --git a/tests/auto/qhostinfo/tst_qhostinfo.cpp b/tests/auto/qhostinfo/tst_qhostinfo.cpp index 4d63e10..348c41b 100644 --- a/tests/auto/qhostinfo/tst_qhostinfo.cpp +++ b/tests/auto/qhostinfo/tst_qhostinfo.cpp @@ -88,6 +88,7 @@ #endif #include "../network-settings.h" +#include "../../shared/util.h" //TESTED_CLASS= //TESTED_FILES= @@ -124,6 +125,9 @@ private slots: void raceCondition(); void threadSafety(); + void multipleSameLookups(); + void multipleDifferentLookups(); + protected slots: void resultsReady(const QHostInfo &); @@ -131,6 +135,7 @@ private: bool ipv6LookupsAvailable; bool ipv6Available; bool lookupDone; + int lookupsDoneCounter; QHostInfo lookupResults; }; @@ -411,11 +416,53 @@ void tst_QHostInfo::threadSafety() } } +// this test is for the multi-threaded QHostInfo rewrite. It is about getting results at all, +// not about getting correct IPs +void tst_QHostInfo::multipleSameLookups() +{ + const int COUNT = 10; + lookupsDoneCounter = 0; + + for (int i = 0; i < COUNT; i++) + QHostInfo::lookupHost("localhost", this, SLOT(resultsReady(const QHostInfo))); + + QTRY_VERIFY(lookupsDoneCounter == COUNT); + + // spin two seconds more to see if it is not more :) + QTestEventLoop::instance().enterLoop(2); + QTRY_VERIFY(lookupsDoneCounter == COUNT); +} + +// this test is for the multi-threaded QHostInfo rewrite. It is about getting results at all, +// not about getting correct IPs +void tst_QHostInfo::multipleDifferentLookups() +{ + QStringList hostnameList; + hostnameList << "www.ovi.com" << "www.nokia.com" << "qt.nokia.com" << "www.trolltech.com" << "troll.no" + << "www.qtcentre.org" << "forum.nokia.com" << "www.forum.nokia.com" << "wiki.forum.nokia.com" + << "www.nokia.no" << "nokia.de" << "127.0.0.1" << "----"; + + const int COUNT = hostnameList.size(); + lookupsDoneCounter = 0; + + for (int i = 0; i < hostnameList.size(); i++) + QHostInfo::lookupHost(hostnameList.at(i), this, SLOT(resultsReady(const QHostInfo))); + + // give some time + QTestEventLoop::instance().enterLoop(5); + // try_verify gives some more time + QTRY_VERIFY(lookupsDoneCounter == COUNT); + + // spin two seconds more to see if it is not more than expected + QTestEventLoop::instance().enterLoop(2); + QTRY_VERIFY(lookupsDoneCounter == COUNT); +} + void tst_QHostInfo::resultsReady(const QHostInfo &hi) { lookupDone = true; lookupResults = hi; - + lookupsDoneCounter++; QTestEventLoop::instance().exitLoop(); } -- cgit v0.12 From d64c29e18cedace91bea31d83b62e5c0b6c6049e Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Thu, 17 Dec 2009 15:11:42 +0100 Subject: Fixed QResource to respect the explicitely set locale MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using QResource directly, the loader should respect the locale that the user asked to use for the resource. Reviewed-by: João Abecasis --- src/corelib/io/qresource.cpp | 2 +- tests/auto/qresourceengine/tst_qresourceengine.cpp | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 5c543d4..a061ad1 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -273,7 +273,7 @@ QResourcePrivate::load(const QString &file) QString cleaned = cleanPath(file); for(int i = 0; i < list->size(); ++i) { QResourceRoot *res = list->at(i); - const int node = res->findNode(cleaned); + const int node = res->findNode(cleaned, locale); if(node != -1) { if(related.isEmpty()) { container = res->isContainer(node); diff --git a/tests/auto/qresourceengine/tst_qresourceengine.cpp b/tests/auto/qresourceengine/tst_qresourceengine.cpp index cc6eda3..ed7de23 100644 --- a/tests/auto/qresourceengine/tst_qresourceengine.cpp +++ b/tests/auto/qresourceengine/tst_qresourceengine.cpp @@ -62,6 +62,7 @@ private slots: void searchPath_data(); void searchPath(); void doubleSlashInRoot(); + void setLocale(); private: QString builddir; @@ -460,6 +461,27 @@ void tst_QResourceEngine::doubleSlashInRoot() QVERIFY(QFile::exists("://secondary_root/runtime_resource/search_file.txt")); } +void tst_QResourceEngine::setLocale() +{ + QLocale::setDefault(QLocale::c()); + + // default constructed QResource gets the default locale + QResource resource; + resource.setFileName("aliasdir/aliasdir.txt"); + QVERIFY(!resource.isCompressed()); + + // change the default locale and make sure it doesn't affect the resource + QLocale::setDefault(QLocale("de_CH")); + QVERIFY(!resource.isCompressed()); + + // then explicitly set the locale on qresource + resource.setLocale(QLocale("de_CH")); + QVERIFY(resource.isCompressed()); + + // the reset the default locale back + QLocale::setDefault(QLocale::system()); +} + QTEST_MAIN(tst_QResourceEngine) #include "tst_qresourceengine.moc" -- cgit v0.12 From 12a4be8cfea62249fd44a1e0c60642972a48f17e Mon Sep 17 00:00:00 2001 From: Bill King Date: Fri, 18 Dec 2009 08:40:37 +1000 Subject: Cleanup qsqldatabase test case a little bit. --- tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index 4f89708..13cb3be 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -768,9 +768,7 @@ void tst_QSqlDatabase::checkValues(const FieldDef fieldDefs[], QSqlDatabase db) rec->setValue(fieldDefs[ i ].fieldName(), fieldDefs[ i ].val); // qDebug(QString("inserting %1 into %2").arg(fieldDefs[ i ].val.toString()).arg(fieldDefs[ i ].fieldName())); } - if (!cur.insert()) { - QFAIL(QString("Couldn't insert record: %1 %2").arg(cur.lastError().databaseText()).arg(cur.lastError().driverText())); - } + QVERIFY_SQL(cur, insert()); cur.setForwardOnly(true); QVERIFY_SQL(cur, select("id = " + QString::number(pkey - 1))); QVERIFY_SQL(cur, next()); @@ -833,9 +831,7 @@ void tst_QSqlDatabase::checkNullValues(const FieldDef fieldDefs[], QSqlDatabase else rec->setValue(fieldDefs[ i ].fieldName(), fieldDefs[ i ].val); } - if (!cur.insert()) { - QFAIL(QString("Couldn't insert record: %1 %2").arg(cur.lastError().databaseText()).arg(cur.lastError().driverText())); - } + QVERIFY_SQL(cur, insert()); cur.setForwardOnly(true); QVERIFY_SQL(cur, select("id = " + QString::number(pkey - 1))); QVERIFY_SQL(cur, next()); @@ -937,20 +933,18 @@ void tst_QSqlDatabase::recordOCI() FieldDef("nvarchar2(20)", QVariant::String, QString("blah4")), FieldDef("number(10,5)", QVariant::Double, 1.1234567), FieldDef("date", QVariant::DateTime, dt), -#ifdef QT3_SUPPORT -//X? FieldDef("long raw", QVariant::ByteArray, QByteArray(Q3CString("blah5"))), - FieldDef("raw(2000)", QVariant::ByteArray, QByteArray(Q3CString("blah6")), false), - FieldDef("blob", QVariant::ByteArray, QByteArray(Q3CString("blah7"))), -#endif + FieldDef("long raw", QVariant::ByteArray, QByteArray("blah5")), + FieldDef("raw(2000)", QVariant::ByteArray, QByteArray("blah6"), false), + FieldDef("blob", QVariant::ByteArray, QByteArray("blah7")), FieldDef("clob", QVariant::String, QString("blah8")), FieldDef("nclob", QVariant::String, QString("blah9")), FieldDef("bfile", QVariant::ByteArray, QByteArray("blah10")), intytm, - intdts, - tsdef, - tstzdef, - tsltzdef, +// intdts, +// tsdef, +// tstzdef, +// tsltzdef, FieldDef() }; -- cgit v0.12 From 7e22fc06165e6eb4ca74e228a9677905e12b1454 Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Fri, 18 Dec 2009 10:56:28 +1000 Subject: no audiodevices found using QAudioDeviceInfo::availableDevices on Ubuntu Task-number:QTBUG-6866 Reviewed-by:Justin McPherson --- src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp index 9645fa8..f58f5be 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp @@ -403,6 +403,7 @@ void QAudioDeviceInfoInternal::updateLists() QList QAudioDeviceInfoInternal::availableDevices(QAudio::Mode mode) { + QList allDevices; QList devices; QByteArray filter; @@ -430,6 +431,7 @@ QList QAudioDeviceInfoInternal::availableDevices(QAudio::Mode mode) if((name != NULL) && (descr != NULL) && ((io == NULL) || (io == filter))) { QString deviceName = QLatin1String(name); QString deviceDescription = QLatin1String(descr); + allDevices.append(deviceName.toLocal8Bit().constData()); if(deviceDescription.contains(QLatin1String("Default Audio Device"))) devices.append(deviceName.toLocal8Bit().constData()); } @@ -457,6 +459,9 @@ QList QAudioDeviceInfoInternal::availableDevices(QAudio::Mode mode) if (idx > 0) devices.append("default"); #endif + if (devices.size() == 0 && allDevices.size() > 0) + return allDevices; + return devices; } -- cgit v0.12 From d31dd9d5d9e8f647f095014523937bcfb0348121 Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Fri, 18 Dec 2009 10:57:40 +1000 Subject: The "audioinput" multimedia example locks up the audio input/output Task-number:QTBUG-5633 Reviewed-by:Justin McPherson --- src/multimedia/audio/qaudioinput_win32_p.cpp | 38 ++++++++++++++++++--------- src/multimedia/audio/qaudiooutput_win32_p.cpp | 8 ++++++ 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/multimedia/audio/qaudioinput_win32_p.cpp b/src/multimedia/audio/qaudioinput_win32_p.cpp index b7f9ffd..f50a547 100644 --- a/src/multimedia/audio/qaudioinput_win32_p.cpp +++ b/src/multimedia/audio/qaudioinput_win32_p.cpp @@ -153,6 +153,14 @@ WAVEHDR* QAudioInputPrivate::allocateBlocks(int size, int count) void QAudioInputPrivate::freeBlocks(WAVEHDR* blockArray) { + WAVEHDR* blocks = blockArray; + + int count = buffer_size/period_size; + + for(int i = 0; i < count; i++) { + waveInUnprepareHeader(hWaveIn,&blocks[i], sizeof(WAVEHDR)); + blocks+=sizeof(WAVEHDR); + } HeapFree(GetProcessHeap(), 0, blockArray); } @@ -222,11 +230,6 @@ bool QAudioInputPrivate::open() } else { period_size = buffer_size/5; } -#ifdef Q_OS_WINCE - // For wince reduce size to 40ms for buffer size and 20ms period - buffer_size = settings.frequency()*settings.channels()*(settings.sampleSize()/8)*0.04; - period_size = buffer_size/2; -#endif timeStamp.restart(); elapsedTimeOffset = 0; wfx.nSamplesPerSec = settings.frequency(); @@ -317,7 +320,7 @@ void QAudioInputPrivate::close() deviceState = QAudio::StoppedState; int count = 0; - while(!finished && count < 100) { + while(!finished && count < 500) { count++; Sleep(10); } @@ -349,9 +352,10 @@ qint64 QAudioInputPrivate::read(char* data, qint64 len) char* p = data; qint64 l = 0; qint64 written = 0; + while(!done) { // Read in some audio data - if(waveBlocks[header].dwBytesRecorded > 0) { + if(waveBlocks[header].dwBytesRecorded > 0 && waveBlocks[header].dwFlags & WHDR_DONE) { if(pullMode) { l = audioSource->write(waveBlocks[header].lpData, waveBlocks[header].dwBytesRecorded); @@ -394,6 +398,9 @@ qint64 QAudioInputPrivate::read(char* data, qint64 len) //no data, not ready yet, next time return 0; } + + waveInUnprepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR)); + EnterCriticalSection(&waveInCriticalSection); waveFreeBlockCount++; LeaveCriticalSection(&waveInCriticalSection); @@ -401,17 +408,22 @@ qint64 QAudioInputPrivate::read(char* data, qint64 len) waveBlocks[header].dwFlags = 0L; result = waveInPrepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR)); if(result != MMSYSERR_NOERROR) { + result = waveInPrepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR)); qWarning("QAudioInput: failed to prepare block %d,err=%d",header,result); - errorState = QAudio::OpenError; - deviceState = QAudio::StoppedState; - emit stateChanged(deviceState); + errorState = QAudio::IOError; + EnterCriticalSection(&waveInCriticalSection); + waveFreeBlockCount--; + LeaveCriticalSection(&waveInCriticalSection); + return 0; } result = waveInAddBuffer(hWaveIn, &waveBlocks[header], sizeof(WAVEHDR)); if(result != MMSYSERR_NOERROR) { qWarning("QAudioInput: failed to setup block %d,err=%d",header,result); - errorState = QAudio::OpenError; - deviceState = QAudio::StoppedState; - emit stateChanged(deviceState); + errorState = QAudio::IOError; + EnterCriticalSection(&waveInCriticalSection); + waveFreeBlockCount--; + LeaveCriticalSection(&waveInCriticalSection); + return 0; } header++; if(header >= buffer_size/period_size) diff --git a/src/multimedia/audio/qaudiooutput_win32_p.cpp b/src/multimedia/audio/qaudiooutput_win32_p.cpp index 2cfc472..02c8cfe 100644 --- a/src/multimedia/audio/qaudiooutput_win32_p.cpp +++ b/src/multimedia/audio/qaudiooutput_win32_p.cpp @@ -147,6 +147,14 @@ WAVEHDR* QAudioOutputPrivate::allocateBlocks(int size, int count) void QAudioOutputPrivate::freeBlocks(WAVEHDR* blockArray) { + WAVEHDR* blocks = blockArray; + + int count = buffer_size/period_size; + + for(int i = 0; i < count; i++) { + waveOutUnprepareHeader(hWaveOut,&blocks[i], sizeof(WAVEHDR)); + blocks+=sizeof(WAVEHDR); + } HeapFree(GetProcessHeap(), 0, blockArray); } -- cgit v0.12 From a4550c49e982aa0218ab7097b814678505f8482c Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Fri, 18 Dec 2009 14:07:39 +1000 Subject: Check if the scene exists before attempting to set its focus item. Prevents crashing when an item involved in the scope chain is set to be visible but it isn't part of a scene. Reviewed-by: Alexis Menard --- src/gui/graphicsview/qgraphicsitem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 90cc132..03e8b09 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -2181,7 +2181,7 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo } // Enable subfocus - if (newVisible) { + if (scene && newVisible) { QGraphicsItem *p = parent; bool done = false; while (p) { -- cgit v0.12 From 87777f7c0f4c3e338d23d2c3d368a8a484a35a6e Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Fri, 18 Dec 2009 15:01:07 +1000 Subject: Align GL_RGB lines on a 4-byte boundary when uploading pixmap textures Previous code was aligning lines on a 3-byte boundary. Task-number: QTBUG-6902 Reviewed-by: Julian de Bhal --- src/opengl/qpixmapdata_gl.cpp | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index 4e1d50d..92c990b 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -341,22 +341,11 @@ void QGLPixmapData::ensureCreated() const if (!m_source.isNull()) { if (external_format == GL_RGB) { - QImage tx = m_source.convertToFormat(QImage::Format_RGB32); - - QVector pixelData(w * h * 3); - uchar *p = &pixelData[0]; - QRgb *src = (QRgb *)tx.bits(); - - for (int i = 0; i < w * h; ++i) { - *p++ = qRed(*src); - *p++ = qGreen(*src); - *p++ = qBlue(*src); - ++src; - } + const QImage tx = m_source.convertToFormat(QImage::Format_RGB888); glBindTexture(target, m_texture.id); glTexSubImage2D(target, 0, 0, 0, w, h, external_format, - GL_UNSIGNED_BYTE, &pixelData[0]); + GL_UNSIGNED_BYTE, tx.bits()); } else { const QImage tx = ctx->d_func()->convertToGLFormat(m_source, true, external_format); -- cgit v0.12 From 4a580b972a90660dc90ef7becea5dfde2a056a4b Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Fri, 18 Dec 2009 15:55:07 +1000 Subject: Prevent access to non-existent memory in triagulating stroker In the triangulating stroker, the last point was being duplicated in dashed paths. But because QDataBuffer::add() takes a ref to a float rather than a float, it would resize the data buffer and then try to fetch the values out of a pointer to the original buffer memory. This change copies the values into temporary variables before resizing the array. Task-number: QTBUG-6045 Reviewed-by: Sarah Smith --- src/opengl/gl2paintengineex/qtriangulatingstroker.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp index 6082f49..395b8a3 100644 --- a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp +++ b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp @@ -62,8 +62,14 @@ void QTriangulatingStroker::endCapOrJoinClosed(const qreal *start, const qreal * endCap(cur); } int count = m_vertices.size(); - m_vertices.add(m_vertices.at(count-2)); - m_vertices.add(m_vertices.at(count-1)); + + // Copy the (x, y) values because QDataBuffer::add(const float& t) + // may resize the buffer, which will leave t pointing at the + // previous buffer's memory region if we don't copy first. + float x = m_vertices.at(count-2); + float y = m_vertices.at(count-1); + m_vertices.add(x); + m_vertices.add(y); } -- cgit v0.12 From 371420d5f31a04b91c01807139d49e97db040bee Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 18 Dec 2009 10:06:20 +0100 Subject: doc: Fixed typos. Task-number: QTBUG-6898 --- doc/src/qt4-intro.qdoc | 2 +- src/activeqt/container/qaxbase.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/qt4-intro.qdoc b/doc/src/qt4-intro.qdoc index fb1d0e4..a90544f 100644 --- a/doc/src/qt4-intro.qdoc +++ b/doc/src/qt4-intro.qdoc @@ -549,7 +549,7 @@ the state machine, it is also easier to use the framework for animating GUIs, for instance. - See \l{The State Machine Framework} documentation for more infromation. + See \l{The State Machine Framework} documentation for more information. \section1 Multi-Touch and Gestures diff --git a/src/activeqt/container/qaxbase.cpp b/src/activeqt/container/qaxbase.cpp index 3795f56..ed7ac29 100644 --- a/src/activeqt/container/qaxbase.cpp +++ b/src/activeqt/container/qaxbase.cpp @@ -909,7 +909,7 @@ QAxMetaObject *QAxBase::internalMetaObject() const \property QAxBase::control \brief the name of the COM object wrapped by this QAxBase object. - Setting this property initilializes the COM object. Any COM object + Setting this property initializes the COM object. Any COM object previously set is shut down. The most efficient way to set this property is by using the -- cgit v0.12 From 4100b42403399e600e935d15d940c4ac6000816f Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Fri, 18 Dec 2009 10:27:59 +0100 Subject: Fixed crash when parsing invalid polygons in svgs. Since a 2D point consists of two coordinates, it was assumed that polygons and polylines were described with an even number of coordinates. When the number of coordinates was odd, the program would read out of bounds and cause an assert failure. Task-number: QTBUG-6899 Reviewed-by: Gunnar --- src/svg/qsvghandler.cpp | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index 4384bf6..2a27aa1 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -2722,14 +2722,8 @@ static QSvgNode *createPolygonNode(QSvgNode *parent, const QChar *s = pointsStr.constData(); QVector points = parseNumbersList(s); QPolygonF poly(points.count()/2); - int i = 0; - QVector::const_iterator itr = points.constBegin(); - while (itr != points.constEnd()) { - qreal one = *itr; ++itr; - qreal two = *itr; ++itr; - poly[i] = QPointF(one, two); - ++i; - } + for (int i = 0; i < poly.size(); ++i) + poly[i] = QPointF(points.at(2 * i), points.at(2 * i + 1)); QSvgNode *polygon = new QSvgPolygon(parent, poly); return polygon; } @@ -2744,14 +2738,8 @@ static QSvgNode *createPolylineNode(QSvgNode *parent, const QChar *s = pointsStr.constData(); QVector points = parseNumbersList(s); QPolygonF poly(points.count()/2); - int i = 0; - QVector::const_iterator itr = points.constBegin(); - while (itr != points.constEnd()) { - qreal one = *itr; ++itr; - qreal two = *itr; ++itr; - poly[i] = QPointF(one, two); - ++i; - } + for (int i = 0; i < poly.size(); ++i) + poly[i] = QPointF(points.at(2 * i), points.at(2 * i + 1)); QSvgNode *line = new QSvgPolyline(parent, poly); return line; -- cgit v0.12 From f0ee2077e61fc8014d74bc94afd1907efc9f3272 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 18 Dec 2009 10:50:39 +0100 Subject: Add Q_OBJECT to QBalloonTip so it can be intreospected by styles. Reviewed-by: jbache --- src/gui/util/qsystemtrayicon_p.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/util/qsystemtrayicon_p.h b/src/gui/util/qsystemtrayicon_p.h index 86de366..029a259 100644 --- a/src/gui/util/qsystemtrayicon_p.h +++ b/src/gui/util/qsystemtrayicon_p.h @@ -94,6 +94,7 @@ public: class QBalloonTip : public QWidget { + Q_OBJECT public: static void showBalloon(QSystemTrayIcon::MessageIcon icon, const QString& title, const QString& msg, QSystemTrayIcon *trayIcon, -- cgit v0.12 From 37e845d6710ea81aacc33c8ef21308e2cc0cab0d Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 17 Dec 2009 14:09:30 +0100 Subject: Optimize QThreadStorage with QVector QThreadStorageData::get might be accessed very often. QMap lookup has proven to be too slow. We can expect about 20 instances of QThreadStorage in a typical applications (tested with some KDE applications) So a QVector is more suited Note: we now re-use the ids. Which means that if the QThreadStorage is destroyed before the QThread, and another one is created, we might get crashes (instead of a warning printed to the console) Reviewed-by: brad --- src/corelib/thread/qthread_p.h | 2 +- src/corelib/thread/qthreadstorage.cpp | 97 ++++++++-------- tests/benchmarks/benchmarks.pro | 3 +- tests/benchmarks/qthreadstorage/qthreadstorage.pro | 6 + .../qthreadstorage/tst_qthreadstorage.cpp | 124 +++++++++++++++++++++ 5 files changed, 183 insertions(+), 49 deletions(-) create mode 100644 tests/benchmarks/qthreadstorage/qthreadstorage.pro create mode 100644 tests/benchmarks/qthreadstorage/tst_qthreadstorage.cpp diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index af68434..3db308f 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -202,7 +202,7 @@ public: QStack eventLoops; QPostEventList postEventList; bool canWait; - QMap tls; + QVector tls; QMutex mutex; diff --git a/src/corelib/thread/qthreadstorage.cpp b/src/corelib/thread/qthreadstorage.cpp index 8b1f255..a7d53d0 100644 --- a/src/corelib/thread/qthreadstorage.cpp +++ b/src/corelib/thread/qthreadstorage.cpp @@ -71,27 +71,32 @@ void qtsDebug(const char *fmt, ...) # define DEBUG_MSG if(false)qDebug #endif -static QBasicAtomicInt idCounter = Q_BASIC_ATOMIC_INITIALIZER(INT_MAX); Q_GLOBAL_STATIC(QMutex, mutex) -typedef QMap DestructorMap; +typedef QVector DestructorMap; Q_GLOBAL_STATIC(DestructorMap, destructors) QThreadStorageData::QThreadStorageData(void (*func)(void *)) - : id(idCounter.fetchAndAddRelaxed(-1)) { QMutexLocker locker(mutex()); - destructors()->insert(id, func); - + DestructorMap *destr = destructors(); + for (id = 0; id < destr->count(); id++) { + if (destr->at(id) == 0) + break; + } + if (id == destr->count()) { + destr->append(func); + } else { + (*destr)[id] = func; + } DEBUG_MSG("QThreadStorageData: Allocated id %d, destructor %p", id, func); } QThreadStorageData::~QThreadStorageData() { + DEBUG_MSG("QThreadStorageData: Released id %d", id); QMutexLocker locker(mutex()); if (destructors()) - destructors()->remove(id); - - DEBUG_MSG("QThreadStorageData: Released id %d", id); + (*destructors())[id] = 0; } void **QThreadStorageData::get() const @@ -101,14 +106,17 @@ void **QThreadStorageData::get() const qWarning("QThreadStorage::get: QThreadStorage can only be used with threads started with QThread"); return 0; } - QMap::const_iterator it = data->tls.constFind(id); + QVector &tls = data->tls; + if (tls.size() <= id) + tls.resize(id + 1); + void **v = &tls[id]; + DEBUG_MSG("QThreadStorageData: Returning storage %d, data %p, for thread %p", id, - it != data->tls.end() ? it.value() : 0, + *v, data->thread); - // const_cast below is a bit evil - but we have to make sure not to detach here - // otherwise we'll go bonkers in oom situations - return it != data->tls.constEnd() && it.value() != 0 ? const_cast(&it.value()) : 0; + + return *v ? v : 0; } void **QThreadStorageData::set(void *p) @@ -118,51 +126,46 @@ void **QThreadStorageData::set(void *p) qWarning("QThreadStorage::set: QThreadStorage can only be used with threads started with QThread"); return 0; } + QVector &tls = data->tls; + if (tls.size() <= id) + tls.resize(id + 1); + + void *&value = tls[id]; + // delete any previous data + if (value != 0) { + DEBUG_MSG("QThreadStorageData: Deleting previous storage %d, data %p, for thread %p", + id, + value, + data->thread); - QMap::iterator it = data->tls.find(id); - if (it != data->tls.end()) { - // delete any previous data - if (it.value() != 0) { - DEBUG_MSG("QThreadStorageData: Deleting previous storage %d, data %p, for thread %p", - id, - it.value(), - data->thread); - - void *q = it.value(); - it.value() = 0; - - QMutexLocker locker(mutex()); - void (*destructor)(void *) = destructors()->value(id); - locker.unlock(); + QMutexLocker locker(mutex()); + void (*destructor)(void *) = destructors()->value(id); + locker.unlock(); - destructor(q); - } + void *q = value; + value = 0; - // store new data - it.value() = p; - DEBUG_MSG("QThreadStorageData: Set storage %d for thread %p to %p", id, data->thread, p); - } else { - it = data->tls.insert(id, p); - DEBUG_MSG("QThreadStorageData: Inserted storage %d, data %p, for thread %p", id, p, data->thread); + destructor(q); } - return &it.value(); + // store new data + value = p; + DEBUG_MSG("QThreadStorageData: Set storage %d for thread %p to %p", id, data->thread, p); + return &value; } void QThreadStorageData::finish(void **p) { - QMap *tls = reinterpret_cast *>(p); + QVector *tls = reinterpret_cast *>(p); if (!tls || tls->isEmpty() || !mutex()) return; // nothing to do DEBUG_MSG("QThreadStorageData: Destroying storage for thread %p", QThread::currentThread()); - QMap::iterator it = tls->begin(); - while (it != tls->end()) { - int id = it.key(); - void *q = it.value(); - it.value() = 0; - ++it; + for(int i = tls->size() - 1; i >= 0; i--) { + void *&value = (*tls)[i]; + void *q = value; + value = 0; if (!q) { // data already deleted @@ -170,16 +173,16 @@ void QThreadStorageData::finish(void **p) } QMutexLocker locker(mutex()); - void (*destructor)(void *) = destructors()->value(id); + void (*destructor)(void *) = destructors()->value(i); locker.unlock(); if (!destructor) { if (QThread::currentThread()) qWarning("QThreadStorage: Thread %p exited after QThreadStorage %d destroyed", - QThread::currentThread(), id); + QThread::currentThread(), i); continue; } - destructor(q); + destructor(q); //crash here might mean the thread exited after qthreadstorage was destroyed } tls->clear(); } diff --git a/tests/benchmarks/benchmarks.pro b/tests/benchmarks/benchmarks.pro index bffa009..bb20dcf 100644 --- a/tests/benchmarks/benchmarks.pro +++ b/tests/benchmarks/benchmarks.pro @@ -36,7 +36,8 @@ SUBDIRS = containers-associative \ qstringbuilder \ qstylesheetstyle \ qsvgrenderer \ - qtableview + qtableview \ + qthreadstorage diff --git a/tests/benchmarks/qthreadstorage/qthreadstorage.pro b/tests/benchmarks/qthreadstorage/qthreadstorage.pro new file mode 100644 index 0000000..f9c1978 --- /dev/null +++ b/tests/benchmarks/qthreadstorage/qthreadstorage.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qthreadstorage + +SOURCES += tst_qthreadstorage.cpp + diff --git a/tests/benchmarks/qthreadstorage/tst_qthreadstorage.cpp b/tests/benchmarks/qthreadstorage/tst_qthreadstorage.cpp new file mode 100644 index 0000000..c00bf5a --- /dev/null +++ b/tests/benchmarks/qthreadstorage/tst_qthreadstorage.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** 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 + +//TESTED_FILES= + +QThreadStorage dummy[8]; + +QThreadStorage tls1; + +class tst_QThreadStorage : public QObject +{ + Q_OBJECT + +public: + tst_QThreadStorage(); + virtual ~tst_QThreadStorage(); + +public slots: + void init(); + void cleanup(); + +private slots: + void construct(); + void get(); + void set(); +}; + +tst_QThreadStorage::tst_QThreadStorage() +{ +} + +tst_QThreadStorage::~tst_QThreadStorage() +{ +} + +void tst_QThreadStorage::init() +{ + dummy[1].setLocalData(new int(5)); + dummy[2].setLocalData(new int(4)); + dummy[3].setLocalData(new int(3)); + tls1.setLocalData(new QString()); +} + +void tst_QThreadStorage::cleanup() +{ +} + +void tst_QThreadStorage::construct() +{ + QBENCHMARK { + QThreadStorage ts; + } +} + + +void tst_QThreadStorage::get() +{ + QThreadStorage ts; + ts.setLocalData(new int(45)); + + int count = 0; + QBENCHMARK { + int *i = ts.localData(); + count += *i; + } + ts.setLocalData(0); +} + +void tst_QThreadStorage::set() +{ + QThreadStorage ts; + + int count = 0; + QBENCHMARK { + ts.setLocalData(new int(count)); + count++; + } + ts.setLocalData(0); +} + + +QTEST_MAIN(tst_QThreadStorage) +#include "tst_qthreadstorage.moc" -- cgit v0.12 From 03f28cfc174dbad3d9531b29b6dfed9983ea5d73 Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Fri, 18 Dec 2009 13:42:35 +0100 Subject: Improve the performance of the Anomaly browser demo Some minor changes to improve the demo: -use QUrl::fromUserInput() -scroll a surface instead of moving the widgets to minimize the repaint -use the animation framework instead of QTimeLine --- demos/embedded/anomaly/src/BrowserWindow.cpp | 146 ++++++++++++--------------- demos/embedded/anomaly/src/BrowserWindow.h | 12 ++- 2 files changed, 70 insertions(+), 88 deletions(-) diff --git a/demos/embedded/anomaly/src/BrowserWindow.cpp b/demos/embedded/anomaly/src/BrowserWindow.cpp index 1036735..1163b6a 100644 --- a/demos/embedded/anomaly/src/BrowserWindow.cpp +++ b/demos/embedded/anomaly/src/BrowserWindow.cpp @@ -43,92 +43,44 @@ #include #include +#include +#include #include "BrowserView.h" #include "HomeView.h" BrowserWindow::BrowserWindow() - : QWidget() - , m_homeView(0) - , m_browserView(0) + : m_slidingSurface(new QWidget(this)) + , m_homeView(new HomeView(m_slidingSurface)) + , m_browserView(new BrowserView(m_slidingSurface)) + , m_animation(new QPropertyAnimation(this, "slideValue")) { - m_timeLine = new QTimeLine(300, this); - m_timeLine->setCurveShape(QTimeLine::EaseInOutCurve); - QTimer::singleShot(0, this, SLOT(initialize())); -} - -void BrowserWindow::initialize() -{ - m_homeView = new HomeView(this); - m_browserView = new BrowserView(this); + m_slidingSurface->setAutoFillBackground(true); - m_homeView->hide(); m_homeView->resize(size()); - m_homeView->move(0, 0); - m_browserView->hide(); m_browserView->resize(size()); - m_browserView->move(0, 0); connect(m_homeView, SIGNAL(addressEntered(QString)), SLOT(gotoAddress(QString))); connect(m_homeView, SIGNAL(urlActivated(QUrl)), SLOT(navigate(QUrl))); connect(m_browserView, SIGNAL(menuButtonClicked()), SLOT(showHomeView())); - m_homeView->setVisible(false); - m_browserView->setVisible(false); - slide(0); + m_animation->setDuration(200); + connect(m_animation, SIGNAL(finished()), SLOT(animationFinished())); - connect(m_timeLine, SIGNAL(frameChanged(int)), SLOT(slide(int))); + setSlideValue(0.0f); } - -// from Demo Browser -QUrl guessUrlFromString(const QString &string) +void BrowserWindow::gotoAddress(const QString &address) { - QString urlStr = string.trimmed(); - QRegExp test(QLatin1String("^[a-zA-Z]+\\:.*")); - - // Check if it looks like a qualified URL. Try parsing it and see. - bool hasSchema = test.exactMatch(urlStr); - if (hasSchema) { - QUrl url = QUrl::fromEncoded(urlStr.toUtf8(), QUrl::TolerantMode); - if (url.isValid()) - return url; - } - - // Might be a file. - if (QFile::exists(urlStr)) { - QFileInfo info(urlStr); - return QUrl::fromLocalFile(info.absoluteFilePath()); - } - - // Might be a shorturl - try to detect the schema. - if (!hasSchema) { - int dotIndex = urlStr.indexOf(QLatin1Char('.')); - if (dotIndex != -1) { - QString prefix = urlStr.left(dotIndex).toLower(); - QString schema = (prefix == QString("ftp")) ? prefix.toLatin1() : QString("http"); - QString location = schema + "://" + urlStr; - QUrl url = QUrl::fromEncoded(location.toUtf8(), QUrl::TolerantMode); - if (url.isValid()) - return url; - } - } - - // Fall back to QUrl's own tolerant parser. - QUrl url = QUrl::fromEncoded(string.toUtf8(), QUrl::TolerantMode); - - // finally for cases where the user just types in a hostname add http - if (url.scheme().isEmpty()) - url = QUrl::fromEncoded("http://" + string.toUtf8(), QUrl::TolerantMode); - return url; + m_browserView->navigate(QUrl::fromUserInput(address)); + showBrowserView(); } -void BrowserWindow::gotoAddress(const QString &address) +void BrowserWindow::animationFinished() { - m_browserView->navigate(guessUrlFromString(address)); - showBrowserView(); + m_animation->setDirection(QAbstractAnimation::Forward); } void BrowserWindow::navigate(const QUrl &url) @@ -137,31 +89,44 @@ void BrowserWindow::navigate(const QUrl &url) showBrowserView(); } -void BrowserWindow::slide(int pos) +void BrowserWindow::setSlideValue(qreal slideRatio) { - m_browserView->move(pos, 0); - m_homeView->move(pos - width(), 0); - m_browserView->show(); - m_homeView->show(); + // we use a ratio to handle resize corectly + const int pos = -qRound(slideRatio * width()); + m_slidingSurface->scroll(pos - m_homeView->x(), 0); + + if (qFuzzyCompare(slideRatio, static_cast(1.0f))) { + m_browserView->show(); + m_homeView->hide(); + } else if (qFuzzyCompare(slideRatio, static_cast(0.0f))) { + m_homeView->show(); + m_browserView->hide(); + } else { + m_browserView->show(); + m_homeView->show(); + } } -void BrowserWindow::showHomeView() +qreal BrowserWindow::slideValue() const { - if (m_timeLine->state() != QTimeLine::NotRunning) - return; + Q_ASSERT(m_slidingSurface->x() < width()); + return static_cast(qAbs(m_homeView->x())) / width(); +} - m_timeLine->setFrameRange(0, width()); - m_timeLine->start(); +void BrowserWindow::showHomeView() +{ + m_animation->setStartValue(slideValue()); + m_animation->setEndValue(0.0f); + m_animation->start(); m_homeView->setFocus(); } void BrowserWindow::showBrowserView() { - if (m_timeLine->state() != QTimeLine::NotRunning) - return; + m_animation->setStartValue(slideValue()); + m_animation->setEndValue(1.0f); + m_animation->start(); - m_timeLine->setFrameRange(width(), 0); - m_timeLine->start(); m_browserView->setFocus(); } @@ -170,18 +135,31 @@ void BrowserWindow::keyReleaseEvent(QKeyEvent *event) QWidget::keyReleaseEvent(event); if (event->key() == Qt::Key_F3) { - if (m_homeView->isVisible()) - showBrowserView(); - else + if (m_animation->state() == QAbstractAnimation::Running) { + const QAbstractAnimation::Direction direction = m_animation->direction() == QAbstractAnimation::Forward + ? QAbstractAnimation::Forward + : QAbstractAnimation::Backward; + m_animation->setDirection(direction); + } else if (qFuzzyCompare(slideValue(), static_cast(1.0f))) showHomeView(); + else + showBrowserView(); + event->accept(); } } void BrowserWindow::resizeEvent(QResizeEvent *event) { - if (m_homeView) - m_homeView->resize(size()); + const QSize newSize = event->size(); + m_slidingSurface->resize(newSize.width() * 2, newSize.height()); + + m_homeView->resize(newSize); + m_homeView->move(0, 0); + + m_browserView->resize(newSize); + m_browserView->move(newSize.width(), 0); - if (m_browserView) - m_browserView->resize(size()); + const QSize oldSize = event->oldSize(); + const qreal oldSlidingRatio = static_cast(qAbs(m_slidingSurface->x())) / oldSize.width(); + setSlideValue(oldSlidingRatio); } diff --git a/demos/embedded/anomaly/src/BrowserWindow.h b/demos/embedded/anomaly/src/BrowserWindow.h index 9647efb..2b77939 100644 --- a/demos/embedded/anomaly/src/BrowserWindow.h +++ b/demos/embedded/anomaly/src/BrowserWindow.h @@ -43,7 +43,7 @@ #define BROWSERWINDOW_H #include -class QTimeLine; +class QPropertyAnimation; class QUrl; class BrowserView; @@ -52,28 +52,32 @@ class HomeView; class BrowserWindow : public QWidget { Q_OBJECT + Q_PROPERTY(qreal slideValue READ slideValue WRITE setSlideValue) public: BrowserWindow(); private slots: - void initialize(); void navigate(const QUrl &url); void gotoAddress(const QString &address); + void animationFinished(); public slots: void showBrowserView(); void showHomeView(); - void slide(int); protected: void keyReleaseEvent(QKeyEvent *event); void resizeEvent(QResizeEvent *event); private: + void setSlideValue(qreal); + qreal slideValue() const; + + QWidget *m_slidingSurface; HomeView *m_homeView; BrowserView *m_browserView; - QTimeLine *m_timeLine; + QPropertyAnimation *m_animation; }; #endif // BROWSERWINDOW_H -- cgit v0.12 From 1aa7d5922930c4195bc8747a19524a7e5021c4e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 17 Dec 2009 15:35:23 +0100 Subject: NEON configure detection and initial blend function implementations. Adds new NEON configure test and -no-neon configure option. NEON implementations can also be turned off by setting the QT_NO_NEON environment variable. Performance improvements (in frames per second): - Blending ARGB32 on RGB32/ARGB32, mostly opaque: 71 % - Blending ARGB32 on RGB32/ARGB32, no opaque pixels: 108 % - Blending ARGB32 on RGB32/ARGB32, with 0.5 opacity: 158 % - Blending RGB32 on RGB32/ARGB32, with 0.5 opacity: 189 % Task-number: QTBUG-6684 Reviewed-by: Gunnar Sletta Reviewed-by: Paul Olav Tvete --- config.tests/unix/neon/neon.cpp | 51 +++++++ config.tests/unix/neon/neon.pro | 2 + configure | 22 ++- src/gui/painting/painting.pri | 7 + src/gui/painting/qblendfunctions.cpp | 2 +- src/gui/painting/qdrawhelper.cpp | 16 ++- src/gui/painting/qdrawhelper_neon.cpp | 260 ++++++++++++++++++++++++++++++++++ src/gui/painting/qdrawhelper_neon_p.h | 76 ++++++++++ 8 files changed, 432 insertions(+), 4 deletions(-) create mode 100644 config.tests/unix/neon/neon.cpp create mode 100644 config.tests/unix/neon/neon.pro create mode 100644 src/gui/painting/qdrawhelper_neon.cpp create mode 100644 src/gui/painting/qdrawhelper_neon_p.h diff --git a/config.tests/unix/neon/neon.cpp b/config.tests/unix/neon/neon.cpp new file mode 100644 index 0000000..c31a9fd --- /dev/null +++ b/config.tests/unix/neon/neon.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** 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 config.tests 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 + +int main(int, char**) +{ + int32x4_t null = vdupq_n_s32(0x0); + + int result; + vst1q_lane_s32(&result, null, 0); + return result; +} diff --git a/config.tests/unix/neon/neon.pro b/config.tests/unix/neon/neon.pro new file mode 100644 index 0000000..de20c4e --- /dev/null +++ b/config.tests/unix/neon/neon.pro @@ -0,0 +1,2 @@ +SOURCES = neon.cpp +CONFIG -= x11 qt diff --git a/configure b/configure index 2114863..22e6bd4 100755 --- a/configure +++ b/configure @@ -745,6 +745,7 @@ CFG_HOST_ENDIAN=auto CFG_DOUBLEFORMAT=auto CFG_ARMFPA=auto CFG_IWMMXT=no +CFG_NEON=auto CFG_CLOCK_GETTIME=auto CFG_CLOCK_MONOTONIC=auto CFG_MREMAP=auto @@ -1604,6 +1605,13 @@ while [ "$#" -gt 0 ]; do iwmmxt) CFG_IWMMXT="yes" ;; + neon) + if [ "$VAL" = "no" ]; then + CFG_NEON="$VAL" + else + UNKNOWN_OPT=yes + fi + ;; reduce-relocations) if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then CFG_REDUCE_RELOCATIONS="$VAL" @@ -3889,6 +3897,7 @@ Qt for Embedded Linux only: -iwmmxt ............ Compile using the iWMMXt instruction set (available on some XScale CPUs). + -no-neon ........... Do not compile with use of NEON instructions. EOF fi @@ -4509,6 +4518,15 @@ if [ "$CFG_IWMMXT" = "yes" ]; then fi fi +# detect neon support +if ([ "$CFG_ARCH" = "arm" ] || [ "$CFG_ARCH" = "armv6" ]) && [ "${CFG_NEON}" = "auto" ]; then + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/neon "neon" $L_FLAGS $I_FLAGS $l_FLAGS "-mfpu=neon"; then + CFG_NEON=yes + else + CFG_NEON=no + fi +fi + # detect zlib if [ "$CFG_ZLIB" = "no" ]; then # Note: Qt no longer support builds without zlib @@ -6124,6 +6142,7 @@ fi [ "$CFG_SSE" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG sse" [ "$CFG_SSE2" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG sse2" [ "$CFG_IWMMXT" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG iwmmxt" +[ "$CFG_NEON" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG neon" [ "$PLATFORM_MAC" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG $CFG_MAC_ARCHS" if [ "$CFG_IPV6" = "yes" ]; then QT_CONFIG="$QT_CONFIG ipv6" @@ -7416,8 +7435,9 @@ echo "Declarative module .. $CFG_DECLARATIVE" echo "STL support ......... $CFG_STL" echo "PCH support ......... $CFG_PRECOMPILE" echo "MMX/3DNOW/SSE/SSE2.. ${CFG_MMX}/${CFG_3DNOW}/${CFG_SSE}/${CFG_SSE2}" -if [ "${CFG_ARCH}" = "arm" ]; then +if [ "$CFG_ARCH" = "arm" ] || [ "$CFG_ARCH" = "armv6" ]; then echo "iWMMXt support ...... ${CFG_IWMMXT}" + echo "NEON support ........ ${CFG_NEON}" fi [ "${PLATFORM_QWS}" != "yes" ] && echo "Graphics System ..... $CFG_GRAPHICS_SYSTEM" echo "IPv6 support ........ $CFG_IPV6" diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 628a109..0b1e79a 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -379,6 +379,13 @@ symbian { QMAKE_CXXFLAGS.ARMCC *= -O3 } +neon { + DEFINES += QT_HAVE_NEON + HEADERS += painting/qdrawhelper_neon_p.h + SOURCES += painting/qdrawhelper_neon.cpp + QMAKE.CXXFLAGS *= -mfpu=neon +} + contains(QT_CONFIG, zlib) { INCLUDEPATH += ../3rdparty/zlib } else:!contains(QT_CONFIG, no-zlib) { diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp index 1d15dac..81d1515 100644 --- a/src/gui/painting/qblendfunctions.cpp +++ b/src/gui/painting/qblendfunctions.cpp @@ -605,7 +605,7 @@ static void qt_blend_argb32_on_argb32(uchar *destPixels, int dbpl, } -static void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl, +void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, int w, int h, int const_alpha) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 23236ec..84cf5cc 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -7725,7 +7726,8 @@ enum CPUFeatures { SSE = 0x10, SSE2 = 0x20, CMOV = 0x40, - IWMMXT = 0x80 + IWMMXT = 0x80, + NEON = 0x100 }; static uint detectCPUFeatures() @@ -7751,6 +7753,9 @@ static uint detectCPUFeatures() // runtime detection only available when running as a previlegied process static const bool doIWMMXT = !qgetenv("QT_NO_IWMMXT").toInt(); return doIWMMXT ? IWMMXT : 0; +#elif defined(QT_HAVE_NEON) + static const bool doNEON = !qgetenv("QT_NO_NEON").toInt(); + return doNEON ? NEON : 0; #else uint features = 0; #if defined(__x86_64__) || defined(Q_OS_WIN64) @@ -8122,7 +8127,14 @@ void qInitDrawhelperAsm() qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_armv6; qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_armv6; qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_armv6; -#endif // Q_CC_RVCT && QT_HAVE_ARMV6 +#elif defined(QT_HAVE_NEON) + if (features & NEON) { + qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; + qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; + qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; + qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; + } +#endif if (functionForModeSolidAsm) { const int destinationMode = QPainter::CompositionMode_Destination; diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp new file mode 100644 index 0000000..7fe11bf --- /dev/null +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -0,0 +1,260 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 + +#ifdef QT_HAVE_NEON + +#include +#include + +QT_BEGIN_NAMESPACE + +static inline int16x8_t qvdiv_255_s16(int16x8_t x, int16x8_t half) +{ + // result = (x + (x >> 8) + 0x80) >> 8 + + const int16x8_t temp = vshrq_n_s16(x, 8); // x >> 8 + const int16x8_t sum_part = vaddq_s16(x, half); // x + 0x80 + const int16x8_t sum = vaddq_s16(temp, sum_part); + + return vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(sum), 8)); +} + +static inline int16x8_t qvbyte_mul_s16(int16x8_t x, int16x8_t alpha, int16x8_t half) +{ + // t = qRound(x * alpha / 255.0) + + const int16x8_t t = vmulq_s16(x, alpha); // t + return qvdiv_255_s16(t, half); +} + +static inline int16x8_t qvinterpolate_pixel_255(int16x8_t x, int16x8_t a, int16x8_t y, int16x8_t b, int16x8_t half) +{ + // t = x * a + y * b + + const int16x8_t ta = vmulq_s16(x, a); + const int16x8_t tb = vmulq_s16(y, b); + + return qvdiv_255_s16(vaddq_s16(ta, tb), half); +} + +static inline int16x8_t qvsource_over_s16(int16x8_t src16, int16x8_t dst16, int16x8_t half, int16x8_t full) +{ + const int16x4_t alpha16_high = vdup_lane_s16(vget_high_s16(src16), 3); + const int16x4_t alpha16_low = vdup_lane_s16(vget_low_s16(src16), 3); + + const int16x8_t alpha16 = vsubq_s16(full, vcombine_s16(alpha16_low, alpha16_high)); + + return vaddq_s16(src16, qvbyte_mul_s16(dst16, alpha16, half)); +} + +void qt_blend_argb32_on_argb32_neon(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha) +{ + const uint *src = (const uint *) srcPixels; + uint *dst = (uint *) destPixels; + int16x8_t half = vdupq_n_s16(0x80); + int16x8_t full = vdupq_n_s16(0xff); + if (const_alpha == 256) { + for (int y = 0; y < h; ++y) { + int x = 0; + for (; x < w-3; x += 4) { + int32x4_t src32 = vld1q_s32((int32_t *)&src[x]); + if ((src[x] & src[x+1] & src[x+2] & src[x+3]) >= 0xff000000) { + // all opaque + vst1q_s32((int32_t *)&dst[x], src32); + } else if (src[x] | src[x+1] | src[x+2] | src[x+3]) { + int32x4_t dst32 = vld1q_s32((int32_t *)&dst[x]); + + const uint8x16_t src8 = vreinterpretq_u8_s32(src32); + const uint8x16_t dst8 = vreinterpretq_u8_s32(dst32); + + const uint8x8_t src8_low = vget_low_u8(src8); + const uint8x8_t dst8_low = vget_low_u8(dst8); + + const uint8x8_t src8_high = vget_high_u8(src8); + const uint8x8_t dst8_high = vget_high_u8(dst8); + + const int16x8_t src16_low = vreinterpretq_s16_u16(vmovl_u8(src8_low)); + const int16x8_t dst16_low = vreinterpretq_s16_u16(vmovl_u8(dst8_low)); + + const int16x8_t src16_high = vreinterpretq_s16_u16(vmovl_u8(src8_high)); + const int16x8_t dst16_high = vreinterpretq_s16_u16(vmovl_u8(dst8_high)); + + const int16x8_t result16_low = qvsource_over_s16(src16_low, dst16_low, half, full); + const int16x8_t result16_high = qvsource_over_s16(src16_high, dst16_high, half, full); + + const int32x2_t result32_low = vreinterpret_s32_s8(vmovn_s16(result16_low)); + const int32x2_t result32_high = vreinterpret_s32_s8(vmovn_s16(result16_high)); + + vst1q_s32((int32_t *)&dst[x], vcombine_s32(result32_low, result32_high)); + } + } + for (; x= 0xff000000) + dst[x] = s; + else if (s != 0) + dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s)); + } + dst = (quint32 *)(((uchar *) dst) + dbpl); + src = (const quint32 *)(((const uchar *) src) + sbpl); + } + } else if (const_alpha != 0) { + const_alpha = (const_alpha * 255) >> 8; + int16x8_t const_alpha16 = vdupq_n_s16(const_alpha); + for (int y = 0; y < h; ++y) { + int x = 0; + for (; x < w-3; x += 4) { + if (src[x] | src[x+1] | src[x+2] | src[x+3]) { + int32x4_t src32 = vld1q_s32((int32_t *)&src[x]); + int32x4_t dst32 = vld1q_s32((int32_t *)&dst[x]); + + const uint8x16_t src8 = vreinterpretq_u8_s32(src32); + const uint8x16_t dst8 = vreinterpretq_u8_s32(dst32); + + const uint8x8_t src8_low = vget_low_u8(src8); + const uint8x8_t dst8_low = vget_low_u8(dst8); + + const uint8x8_t src8_high = vget_high_u8(src8); + const uint8x8_t dst8_high = vget_high_u8(dst8); + + const int16x8_t src16_low = vreinterpretq_s16_u16(vmovl_u8(src8_low)); + const int16x8_t dst16_low = vreinterpretq_s16_u16(vmovl_u8(dst8_low)); + + const int16x8_t src16_high = vreinterpretq_s16_u16(vmovl_u8(src8_high)); + const int16x8_t dst16_high = vreinterpretq_s16_u16(vmovl_u8(dst8_high)); + + const int16x8_t srcalpha16_low = qvbyte_mul_s16(src16_low, const_alpha16, half); + const int16x8_t srcalpha16_high = qvbyte_mul_s16(src16_high, const_alpha16, half); + + const int16x8_t result16_low = qvsource_over_s16(srcalpha16_low, dst16_low, half, full); + const int16x8_t result16_high = qvsource_over_s16(srcalpha16_high, dst16_high, half, full); + + const int32x2_t result32_low = vreinterpret_s32_s8(vmovn_s16(result16_low)); + const int32x2_t result32_high = vreinterpret_s32_s8(vmovn_s16(result16_high)); + + vst1q_s32((int32_t *)&dst[x], vcombine_s32(result32_low, result32_high)); + } + } + for (; x> 8; + int one_minus_const_alpha = 255 - const_alpha; + int16x8_t const_alpha16 = vdupq_n_s16(const_alpha); + int16x8_t one_minus_const_alpha16 = vdupq_n_s16(255 - const_alpha); + for (int y = 0; y < h; ++y) { + int x = 0; + for (; x < w-3; x += 4) { + int32x4_t src32 = vld1q_s32((int32_t *)&src[x]); + int32x4_t dst32 = vld1q_s32((int32_t *)&dst[x]); + + const uint8x16_t src8 = vreinterpretq_u8_s32(src32); + const uint8x16_t dst8 = vreinterpretq_u8_s32(dst32); + + const uint8x8_t src8_low = vget_low_u8(src8); + const uint8x8_t dst8_low = vget_low_u8(dst8); + + const uint8x8_t src8_high = vget_high_u8(src8); + const uint8x8_t dst8_high = vget_high_u8(dst8); + + const int16x8_t src16_low = vreinterpretq_s16_u16(vmovl_u8(src8_low)); + const int16x8_t dst16_low = vreinterpretq_s16_u16(vmovl_u8(dst8_low)); + + const int16x8_t src16_high = vreinterpretq_s16_u16(vmovl_u8(src8_high)); + const int16x8_t dst16_high = vreinterpretq_s16_u16(vmovl_u8(dst8_high)); + + const int16x8_t result16_low = qvinterpolate_pixel_255(src16_low, const_alpha16, dst16_low, one_minus_const_alpha16, half); + const int16x8_t result16_high = qvinterpolate_pixel_255(src16_high, const_alpha16, dst16_high, one_minus_const_alpha16, half); + + const int32x2_t result32_low = vreinterpret_s32_s8(vmovn_s16(result16_low)); + const int32x2_t result32_high = vreinterpret_s32_s8(vmovn_s16(result16_high)); + + vst1q_s32((int32_t *)&dst[x], vcombine_s32(result32_low, result32_high)); + } + for (; x + +QT_BEGIN_NAMESPACE + +#ifdef QT_HAVE_NEON + +void qt_blend_argb32_on_argb32_neon(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha); + +void qt_blend_rgb32_on_rgb32_neon(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha); + +#endif // QT_HAVE_NEON + +QT_END_NAMESPACE + +#endif // QDRAWHELPER_NEON_P_H -- cgit v0.12 From a8bdfca489dfb610961fd808d5cb896516131ed4 Mon Sep 17 00:00:00 2001 From: axis Date: Fri, 18 Dec 2009 09:58:03 +0100 Subject: Switched two files to BSD license. This is needed because they become a static library that is linked into every application. RevBy: Espen Riskedal --- src/s60main/qts60main.cpp | 56 ++++++++++++++++++++--------------------- src/s60main/qts60main_mcrt0.cpp | 52 ++++++++++++++++++-------------------- 2 files changed, 52 insertions(+), 56 deletions(-) diff --git a/src/s60main/qts60main.cpp b/src/s60main/qts60main.cpp index 725b17c..9f2d8c4 100644 --- a/src/s60main/qts60main.cpp +++ b/src/s60main/qts60main.cpp @@ -6,35 +6,33 @@ ** ** 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_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/s60main/qts60main_mcrt0.cpp b/src/s60main/qts60main_mcrt0.cpp index edc2fb8..b9a720b 100644 --- a/src/s60main/qts60main_mcrt0.cpp +++ b/src/s60main/qts60main_mcrt0.cpp @@ -6,35 +6,33 @@ ** ** 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_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: ** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. ** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** $QT_END_LICENSE$ ** ****************************************************************************/ -- cgit v0.12 From 12e2c9075e694897ae52048c2069f57a22ef4031 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 18 Dec 2009 14:23:13 +0100 Subject: doc: Added a missing \sa command, plus a \l in the text. Task-number: QTBUG-6288 --- src/corelib/kernel/qobject.cpp | 15 ++++++++------- tools/qdoc3/cppcodeparser.cpp | 6 +++--- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 4370ee0..305ec4f 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -578,12 +578,13 @@ int QMetaCallEvent::placeMetaCall(QObject *object) protected functions connectNotify() and disconnectNotify() make it possible to track connections. - QObjects organize themselves in object trees. When you create a - QObject with another object as parent, the object will - automatically add itself to the parent's children() list. The - parent takes ownership of the object; i.e., it will automatically - delete its children in its destructor. You can look for an object - by name and optionally type using findChild() or findChildren(). + QObjects organize themselves in \l {Object Trees and Object + Ownership} {object trees}. When you create a QObject with another + object as parent, the object will automatically add itself to the + parent's children() list. The parent takes ownership of the + object; i.e., it will automatically delete its children in its + destructor. You can look for an object by name and optionally type + using findChild() or findChildren(). Every object has an objectName() and its class name can be found via the corresponding metaObject() (see QMetaObject::className()). @@ -682,7 +683,7 @@ int QMetaCallEvent::placeMetaCall(QObject *object) \l{Writing Source Code for Translation} document. \sa QMetaObject, QPointer, QObjectCleanupHandler, Q_DISABLE_COPY() - {Object Trees and Object Ownership} + \sa {Object Trees and Object Ownership} */ /*! diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp index 41a2456..9ec7fdf 100644 --- a/tools/qdoc3/cppcodeparser.cpp +++ b/tools/qdoc3/cppcodeparser.cpp @@ -2318,9 +2318,9 @@ void CppCodeParser::createExampleFileNodes(FakeNode *fake) exampleFile.mid(sizeOfBoringPartOfName), Node::File); foreach (const QString &imageFile, imageFiles) { - FakeNode* newFake = new FakeNode(fake, - imageFile.mid(sizeOfBoringPartOfName), - Node::Image); + new FakeNode(fake, + imageFile.mid(sizeOfBoringPartOfName), + Node::Image); } } -- cgit v0.12 From c673c77b7d82b7201d8715679a27d0836d11e50e Mon Sep 17 00:00:00 2001 From: axis Date: Fri, 18 Dec 2009 13:33:14 +0100 Subject: Fixed two incorrect signal connections. RevBy: Friedemann Kleint --- src/gui/widgets/qplaintextedit.cpp | 2 +- src/gui/widgets/qtextedit.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index 5e7d06e..a3624d6 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -765,7 +765,7 @@ void QPlainTextEditPrivate::init(const QString &txt) QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SLOT(_q_cursorPositionChanged())); QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged())); - QObject::connect(control, SIGNAL(textChanged(const QString &)), q, SLOT(updateMicroFocus())); + QObject::connect(control, SIGNAL(textChanged()), q, SLOT(updateMicroFocus())); // set a null page size initially to avoid any relayouting until the textedit // is shown. relayoutDocument() will take care of setting the page size to the diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp index 63fac2a..5d8f134 100644 --- a/src/gui/widgets/qtextedit.cpp +++ b/src/gui/widgets/qtextedit.cpp @@ -158,7 +158,7 @@ void QTextEditPrivate::init(const QString &html) QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged())); QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged())); - QObject::connect(control, SIGNAL(textChanged(const QString &)), q, SLOT(updateMicroFocus())); + QObject::connect(control, SIGNAL(textChanged()), q, SLOT(updateMicroFocus())); QTextDocument *doc = control->document(); // set a null page size initially to avoid any relayouting until the textedit -- cgit v0.12 From 315c09c3873f7c5d8b785443372bf975bae47ee7 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 18 Dec 2009 14:17:44 +0100 Subject: Make sure mappings are created for columns when indexes newly become parents. Also move the modeltest related tests to the modeltest subdirectory Merge-request: 2262 Reviewed-by: Olivier Goffart --- src/gui/itemviews/qsortfilterproxymodel.cpp | 27 ++ tests/auto/headers/tst_headers.cpp | 4 +- tests/auto/modeltest/dynamictreemodel.cpp | 328 +++++++++++++++++++++ tests/auto/modeltest/dynamictreemodel.h | 199 +++++++++++++ tests/auto/modeltest/modeltest.cpp | 20 +- tests/auto/modeltest/modeltest.pro | 4 +- tests/auto/modeltest/tst_modeltest.cpp | 35 ++- tests/auto/qabstractitemmodel/dynamictreemodel.cpp | 328 --------------------- tests/auto/qabstractitemmodel/dynamictreemodel.h | 199 ------------- .../auto/qabstractitemmodel/qabstractitemmodel.pro | 7 +- 10 files changed, 607 insertions(+), 544 deletions(-) create mode 100644 tests/auto/modeltest/dynamictreemodel.cpp create mode 100644 tests/auto/modeltest/dynamictreemodel.h delete mode 100644 tests/auto/qabstractitemmodel/dynamictreemodel.cpp delete mode 100644 tests/auto/qabstractitemmodel/dynamictreemodel.h diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index fc82f30..95d6bc8 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -734,6 +734,33 @@ void QSortFilterProxyModelPrivate::source_items_inserted( } } + if (model->rowCount(source_parent) == delta_item_count) { + // Items were inserted where there were none before. + // If it was new rows make sure to create mappings for columns so that a + // valid mapping can be retreived later and vice-versa. + + QVector &orthogonal_proxy_to_source = (orient == Qt::Horizontal) ? m->source_rows : m->source_columns; + QVector &orthogonal_source_to_proxy = (orient == Qt::Horizontal) ? m->proxy_rows : m->proxy_columns; + + if (orthogonal_source_to_proxy.isEmpty()) { + const int ortho_end = (orient == Qt::Horizontal) ? model->rowCount(source_parent) : model->columnCount(source_parent); + + for (int ortho_item = 0; ortho_item < ortho_end; ++ortho_item) { + if ((orient == Qt::Horizontal) ? q->filterAcceptsRow(ortho_item, source_parent) + : q->filterAcceptsColumn(ortho_item, source_parent)) { + orthogonal_proxy_to_source.append(ortho_item); + } + } + orthogonal_source_to_proxy.resize(orthogonal_proxy_to_source.size()); + + if (orient == Qt::Horizontal) { + // We're reacting to columnsInserted, but we've just inserted new rows. Sort them. + sort_source_rows(orthogonal_proxy_to_source, source_parent); + } + build_source_to_proxy_mapping(orthogonal_proxy_to_source, orthogonal_source_to_proxy); + } + } + // Sort and insert the items if (orient == Qt::Vertical) // Only sort rows sort_source_rows(source_items, source_parent); diff --git a/tests/auto/headers/tst_headers.cpp b/tests/auto/headers/tst_headers.cpp index 36d25fe..329143d 100644 --- a/tests/auto/headers/tst_headers.cpp +++ b/tests/auto/headers/tst_headers.cpp @@ -217,8 +217,8 @@ void tst_Headers::licenseCheck() QCOMPARE(content.at(i++), QString("/****************************************************************************")); if (licenseType != "3RDPARTY") { QCOMPARE(content.at(i++), QString("**")); - if (sourceFile.endsWith("/tests/auto/qabstractitemmodel/dynamictreemodel.cpp") - || sourceFile.endsWith("/tests/auto/qabstractitemmodel/dynamictreemodel.h") + if (sourceFile.endsWith("/tests/auto/modeltest/dynamictreemodel.cpp") + || sourceFile.endsWith("/tests/auto/modeltest/dynamictreemodel.h") || sourceFile.endsWith("/src/network/kernel/qnetworkproxy_p.h")) { // These files are not copyrighted by Nokia. diff --git a/tests/auto/modeltest/dynamictreemodel.cpp b/tests/auto/modeltest/dynamictreemodel.cpp new file mode 100644 index 0000000..24d3ab3 --- /dev/null +++ b/tests/auto/modeltest/dynamictreemodel.cpp @@ -0,0 +1,328 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Stephen Kelly +** 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 "dynamictreemodel.h" + +#include +#include +#include + + +DynamicTreeModel::DynamicTreeModel(QObject *parent) + : QAbstractItemModel(parent), + nextId(1) +{ +} + +QModelIndex DynamicTreeModel::index(int row, int column, const QModelIndex &parent) const +{ +// if (column != 0) +// return QModelIndex(); + + + if ( column < 0 || row < 0 ) + return QModelIndex(); + + QList > childIdColumns = m_childItems.value(parent.internalId()); + + + if (childIdColumns.size() == 0) + return QModelIndex(); + + if (column >= childIdColumns.size()) + return QModelIndex(); + + QList rowIds = childIdColumns.at(column); + + if ( row >= rowIds.size()) + return QModelIndex(); + + qint64 id = rowIds.at(row); + + return createIndex(row, column, reinterpret_cast(id)); + +} + +qint64 DynamicTreeModel::findParentId(qint64 searchId) const +{ + if (searchId <= 0) + return -1; + + QHashIterator > > i(m_childItems); + while (i.hasNext()) + { + i.next(); + QListIterator > j(i.value()); + while (j.hasNext()) + { + QList l = j.next(); + if (l.contains(searchId)) + { + return i.key(); + } + } + } + return -1; +} + +QModelIndex DynamicTreeModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + return QModelIndex(); + + qint64 searchId = index.internalId(); + qint64 parentId = findParentId(searchId); + // Will never happen for valid index, but what the hey... + if (parentId <= 0) + return QModelIndex(); + + qint64 grandParentId = findParentId(parentId); + if (grandParentId < 0) + grandParentId = 0; + + int column = 0; + QList childList = m_childItems.value(grandParentId).at(column); + + int row = childList.indexOf(parentId); + + return createIndex(row, column, reinterpret_cast(parentId)); + +} + +int DynamicTreeModel::rowCount(const QModelIndex &index ) const +{ + QList > cols = m_childItems.value(index.internalId()); + + if (cols.size() == 0 ) + return 0; + + if (index.column() > 0) + return 0; + + return cols.at(0).size(); +} + +int DynamicTreeModel::columnCount(const QModelIndex &index ) const +{ +// Q_UNUSED(index); + return m_childItems.value(index.internalId()).size(); +} + +QVariant DynamicTreeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (Qt::DisplayRole == role) + { + return m_items.value(index.internalId()); + } + return QVariant(); +} + +void DynamicTreeModel::clear() +{ + m_items.clear(); + m_childItems.clear(); + nextId = 1; + reset(); +} + + +ModelChangeCommand::ModelChangeCommand( DynamicTreeModel *model, QObject *parent ) + : QObject(parent), m_model(model), m_numCols(1), m_startRow(-1), m_endRow(-1) +{ + +} + +QModelIndex ModelChangeCommand::findIndex(QList rows) +{ + const int col = 0; + QModelIndex parent = QModelIndex(); + QListIterator i(rows); + while (i.hasNext()) + { + parent = m_model->index(i.next(), col, parent); + Q_ASSERT(parent.isValid()); + } + return parent; +} + +ModelInsertCommand::ModelInsertCommand(DynamicTreeModel *model, QObject *parent ) + : ModelChangeCommand(model, parent) +{ + +} + +void ModelInsertCommand::doCommand() +{ + QModelIndex parent = findIndex(m_rowNumbers); + m_model->beginInsertRows(parent, m_startRow, m_endRow); + qint64 parentId = parent.internalId(); + for (int row = m_startRow; row <= m_endRow; row++) + { + for(int col = 0; col < m_numCols; col++ ) + { + if (m_model->m_childItems[parentId].size() <= col) + { + m_model->m_childItems[parentId].append(QList()); + } +// QString name = QUuid::createUuid().toString(); + qint64 id = m_model->newId(); + QString name = QString::number(id); + + m_model->m_items.insert(id, name); + m_model->m_childItems[parentId][col].insert(row, id); + + } + } + m_model->endInsertRows(); +} + + +ModelMoveCommand::ModelMoveCommand(DynamicTreeModel *model, QObject *parent) + : ModelChangeCommand(model, parent) +{ + +} +bool ModelMoveCommand::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) +{ + return m_model->beginMoveRows(srcParent, srcStart, srcEnd, destParent, destRow); +} + +void ModelMoveCommand::doCommand() +{ + QModelIndex srcParent = findIndex(m_rowNumbers); + QModelIndex destParent = findIndex(m_destRowNumbers); + + if (!emitPreSignal(srcParent, m_startRow, m_endRow, destParent, m_destRow)) + { + return; + } + + for (int column = 0; column < m_numCols; ++column) + { + QList l = m_model->m_childItems.value(srcParent.internalId())[column].mid(m_startRow, m_endRow - m_startRow + 1 ); + + for (int i = m_startRow; i <= m_endRow ; i++) + { + m_model->m_childItems[srcParent.internalId()][column].removeAt(m_startRow); + } + int d; + if (m_destRow < m_startRow) + d = m_destRow; + else + { + if (srcParent == destParent) + d = m_destRow - (m_endRow - m_startRow + 1); + else + d = m_destRow - (m_endRow - m_startRow) + 1; + } + + foreach(const qint64 id, l) + { + m_model->m_childItems[destParent.internalId()][column].insert(d++, id); + } + } + + emitPostSignal(); +} + +void ModelMoveCommand::emitPostSignal() +{ + m_model->endMoveRows(); +} + +ModelResetCommand::ModelResetCommand(DynamicTreeModel* model, QObject* parent) + : ModelMoveCommand(model, parent) +{ + +} + +ModelResetCommand::~ModelResetCommand() +{ + +} + +bool ModelResetCommand::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) +{ + Q_UNUSED(srcParent); + Q_UNUSED(srcStart); + Q_UNUSED(srcEnd); + Q_UNUSED(destParent); + Q_UNUSED(destRow); + + return true; +} + +void ModelResetCommand::emitPostSignal() +{ + m_model->reset(); +} + +ModelResetCommandFixed::ModelResetCommandFixed(DynamicTreeModel* model, QObject* parent) + : ModelMoveCommand(model, parent) +{ + +} + +ModelResetCommandFixed::~ModelResetCommandFixed() +{ + +} + +bool ModelResetCommandFixed::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) +{ + Q_UNUSED(srcParent); + Q_UNUSED(srcStart); + Q_UNUSED(srcEnd); + Q_UNUSED(destParent); + Q_UNUSED(destRow); + + m_model->beginResetModel(); + return true; +} + +void ModelResetCommandFixed::emitPostSignal() +{ + m_model->endResetModel(); +} + diff --git a/tests/auto/modeltest/dynamictreemodel.h b/tests/auto/modeltest/dynamictreemodel.h new file mode 100644 index 0000000..3f0d90d --- /dev/null +++ b/tests/auto/modeltest/dynamictreemodel.h @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Stephen Kelly +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DYNAMICTREEMODEL_H +#define DYNAMICTREEMODEL_H + +#include + +#include +#include + + +template class QList; + +class DynamicTreeModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + DynamicTreeModel(QObject *parent = 0); + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &index) const; + int rowCount(const QModelIndex &index = QModelIndex()) const; + int columnCount(const QModelIndex &index = QModelIndex()) const; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + + void clear(); + +protected slots: + + /** + Finds the parent id of the string with id @p searchId. + + Returns -1 if not found. + */ + qint64 findParentId(qint64 searchId) const; + +private: + QHash m_items; + QHash > > m_childItems; + qint64 nextId; + qint64 newId() { return nextId++; }; + + QModelIndex m_nextParentIndex; + int m_nextRow; + + int m_depth; + int maxDepth; + + friend class ModelInsertCommand; + friend class ModelMoveCommand; + friend class ModelResetCommand; + friend class ModelResetCommandFixed; + +}; + + +class ModelChangeCommand : public QObject +{ + Q_OBJECT +public: + + ModelChangeCommand( DynamicTreeModel *model, QObject *parent = 0 ); + + virtual ~ModelChangeCommand() {} + + void setAncestorRowNumbers(QList rowNumbers) { m_rowNumbers = rowNumbers; } + + QModelIndex findIndex(QList rows); + + void setStartRow(int row) { m_startRow = row; } + + void setEndRow(int row) { m_endRow = row; } + + void setNumCols(int cols) { m_numCols = cols; } + + virtual void doCommand() = 0; + +protected: + DynamicTreeModel* m_model; + QList m_rowNumbers; + int m_numCols; + int m_startRow; + int m_endRow; + +}; + +typedef QList ModelChangeCommandList; + +class ModelInsertCommand : public ModelChangeCommand +{ + Q_OBJECT + +public: + + ModelInsertCommand(DynamicTreeModel *model, QObject *parent = 0 ); + virtual ~ModelInsertCommand() {} + + virtual void doCommand(); +}; + + +class ModelMoveCommand : public ModelChangeCommand +{ + Q_OBJECT +public: + ModelMoveCommand(DynamicTreeModel *model, QObject *parent); + + virtual ~ModelMoveCommand() {} + + virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow); + + virtual void doCommand(); + + virtual void emitPostSignal(); + + void setDestAncestors( QList rows ) { m_destRowNumbers = rows; } + + void setDestRow(int row) { m_destRow = row; } + +protected: + QList m_destRowNumbers; + int m_destRow; +}; + +/** + A command which does a move and emits a reset signal. +*/ +class ModelResetCommand : public ModelMoveCommand +{ + Q_OBJECT +public: + ModelResetCommand(DynamicTreeModel* model, QObject* parent = 0); + + virtual ~ModelResetCommand(); + + virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow); + virtual void emitPostSignal(); + +}; + +/** + A command which does a move and emits a beginResetModel and endResetModel signals. +*/ +class ModelResetCommandFixed : public ModelMoveCommand +{ + Q_OBJECT +public: + ModelResetCommandFixed(DynamicTreeModel* model, QObject* parent = 0); + + virtual ~ModelResetCommandFixed(); + + virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow); + virtual void emitPostSignal(); + +}; + + +#endif diff --git a/tests/auto/modeltest/modeltest.cpp b/tests/auto/modeltest/modeltest.cpp index 39d00f6..0ca9e14 100644 --- a/tests/auto/modeltest/modeltest.cpp +++ b/tests/auto/modeltest/modeltest.cpp @@ -475,8 +475,8 @@ void ModelTest::data() void ModelTest::rowsAboutToBeInserted ( const QModelIndex &parent, int start, int end ) { // Q_UNUSED(end); - qDebug() << "rowsAboutToBeInserted" << "start=" << start << "end=" << end << "parent=" << model->data ( parent ).toString() - << "current count of parent=" << model->rowCount ( parent ); // << "display of last=" << model->data( model->index(start-1, 0, parent) ); +// qDebug() << "rowsAboutToBeInserted" << "start=" << start << "end=" << end << "parent=" << model->data ( parent ).toString() +// << "current count of parent=" << model->rowCount ( parent ); // << "display of last=" << model->data( model->index(start-1, 0, parent) ); // qDebug() << model->index(start-1, 0, parent) << model->data( model->index(start-1, 0, parent) ); Changing c; c.parent = parent; @@ -495,14 +495,14 @@ void ModelTest::rowsInserted ( const QModelIndex & parent, int start, int end ) { Changing c = insert.pop(); Q_ASSERT ( c.parent == parent ); - qDebug() << "rowsInserted" << "start=" << start << "end=" << end << "oldsize=" << c.oldSize - << "parent=" << model->data ( parent ).toString() << "current rowcount of parent=" << model->rowCount ( parent ); - - for (int ii=start; ii <= end; ii++) - { - qDebug() << "itemWasInserted:" << ii << model->data ( model->index ( ii, 0, parent )); - } - qDebug(); +// qDebug() << "rowsInserted" << "start=" << start << "end=" << end << "oldsize=" << c.oldSize +// << "parent=" << model->data ( parent ).toString() << "current rowcount of parent=" << model->rowCount ( parent ); + +// for (int ii=start; ii <= end; ii++) +// { +// qDebug() << "itemWasInserted:" << ii << model->data ( model->index ( ii, 0, parent )); +// } +// qDebug(); Q_ASSERT ( c.oldSize + ( end - start + 1 ) == model->rowCount ( parent ) ); Q_ASSERT ( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) ); diff --git a/tests/auto/modeltest/modeltest.pro b/tests/auto/modeltest/modeltest.pro index 6655d85..f157da0 100644 --- a/tests/auto/modeltest/modeltest.pro +++ b/tests/auto/modeltest/modeltest.pro @@ -1,6 +1,6 @@ load(qttest_p4) -SOURCES += tst_modeltest.cpp modeltest.cpp -HEADERS += modeltest.h +SOURCES += tst_modeltest.cpp modeltest.cpp dynamictreemodel.cpp +HEADERS += modeltest.h dynamictreemodel.h diff --git a/tests/auto/modeltest/tst_modeltest.cpp b/tests/auto/modeltest/tst_modeltest.cpp index a719168..78aa79f 100644 --- a/tests/auto/modeltest/tst_modeltest.cpp +++ b/tests/auto/modeltest/tst_modeltest.cpp @@ -44,6 +44,7 @@ #include #include "modeltest.h" +#include "dynamictreemodel.h" class tst_ModelTest : public QObject @@ -64,6 +65,7 @@ private slots: void stringListModel(); void treeWidgetModel(); void standardItemModel(); + void testInsertThroughProxy(); }; @@ -143,7 +145,38 @@ void tst_ModelTest::standardItemModel() model.insertRows(0,5, model.index(1,1)); model.insertColumns(0,5, model.index(1,3)); - +} + +void tst_ModelTest::testInsertThroughProxy() +{ + DynamicTreeModel *model = new DynamicTreeModel(this); + + QSortFilterProxyModel *proxy = new QSortFilterProxyModel(this); + proxy->setSourceModel(model); + + new ModelTest(proxy, this); + + ModelInsertCommand *insertCommand = new ModelInsertCommand(model, this); + insertCommand->setNumCols(4); + insertCommand->setStartRow(0); + insertCommand->setEndRow(9); + // Parent is QModelIndex() + insertCommand->doCommand(); + + insertCommand = new ModelInsertCommand(model, this); + insertCommand->setNumCols(4); + insertCommand->setAncestorRowNumbers(QList() << 5); + insertCommand->setStartRow(0); + insertCommand->setEndRow(9); + insertCommand->doCommand(); + + ModelMoveCommand *moveCommand = new ModelMoveCommand(model, this); + moveCommand->setNumCols(4); + moveCommand->setStartRow(0); + moveCommand->setEndRow(0); + moveCommand->setDestRow(9); + moveCommand->setDestAncestors(QList() << 5); + moveCommand->doCommand(); } QTEST_MAIN(tst_ModelTest) diff --git a/tests/auto/qabstractitemmodel/dynamictreemodel.cpp b/tests/auto/qabstractitemmodel/dynamictreemodel.cpp deleted file mode 100644 index 24d3ab3..0000000 --- a/tests/auto/qabstractitemmodel/dynamictreemodel.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Stephen Kelly -** 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 "dynamictreemodel.h" - -#include -#include -#include - - -DynamicTreeModel::DynamicTreeModel(QObject *parent) - : QAbstractItemModel(parent), - nextId(1) -{ -} - -QModelIndex DynamicTreeModel::index(int row, int column, const QModelIndex &parent) const -{ -// if (column != 0) -// return QModelIndex(); - - - if ( column < 0 || row < 0 ) - return QModelIndex(); - - QList > childIdColumns = m_childItems.value(parent.internalId()); - - - if (childIdColumns.size() == 0) - return QModelIndex(); - - if (column >= childIdColumns.size()) - return QModelIndex(); - - QList rowIds = childIdColumns.at(column); - - if ( row >= rowIds.size()) - return QModelIndex(); - - qint64 id = rowIds.at(row); - - return createIndex(row, column, reinterpret_cast(id)); - -} - -qint64 DynamicTreeModel::findParentId(qint64 searchId) const -{ - if (searchId <= 0) - return -1; - - QHashIterator > > i(m_childItems); - while (i.hasNext()) - { - i.next(); - QListIterator > j(i.value()); - while (j.hasNext()) - { - QList l = j.next(); - if (l.contains(searchId)) - { - return i.key(); - } - } - } - return -1; -} - -QModelIndex DynamicTreeModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - return QModelIndex(); - - qint64 searchId = index.internalId(); - qint64 parentId = findParentId(searchId); - // Will never happen for valid index, but what the hey... - if (parentId <= 0) - return QModelIndex(); - - qint64 grandParentId = findParentId(parentId); - if (grandParentId < 0) - grandParentId = 0; - - int column = 0; - QList childList = m_childItems.value(grandParentId).at(column); - - int row = childList.indexOf(parentId); - - return createIndex(row, column, reinterpret_cast(parentId)); - -} - -int DynamicTreeModel::rowCount(const QModelIndex &index ) const -{ - QList > cols = m_childItems.value(index.internalId()); - - if (cols.size() == 0 ) - return 0; - - if (index.column() > 0) - return 0; - - return cols.at(0).size(); -} - -int DynamicTreeModel::columnCount(const QModelIndex &index ) const -{ -// Q_UNUSED(index); - return m_childItems.value(index.internalId()).size(); -} - -QVariant DynamicTreeModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - if (Qt::DisplayRole == role) - { - return m_items.value(index.internalId()); - } - return QVariant(); -} - -void DynamicTreeModel::clear() -{ - m_items.clear(); - m_childItems.clear(); - nextId = 1; - reset(); -} - - -ModelChangeCommand::ModelChangeCommand( DynamicTreeModel *model, QObject *parent ) - : QObject(parent), m_model(model), m_numCols(1), m_startRow(-1), m_endRow(-1) -{ - -} - -QModelIndex ModelChangeCommand::findIndex(QList rows) -{ - const int col = 0; - QModelIndex parent = QModelIndex(); - QListIterator i(rows); - while (i.hasNext()) - { - parent = m_model->index(i.next(), col, parent); - Q_ASSERT(parent.isValid()); - } - return parent; -} - -ModelInsertCommand::ModelInsertCommand(DynamicTreeModel *model, QObject *parent ) - : ModelChangeCommand(model, parent) -{ - -} - -void ModelInsertCommand::doCommand() -{ - QModelIndex parent = findIndex(m_rowNumbers); - m_model->beginInsertRows(parent, m_startRow, m_endRow); - qint64 parentId = parent.internalId(); - for (int row = m_startRow; row <= m_endRow; row++) - { - for(int col = 0; col < m_numCols; col++ ) - { - if (m_model->m_childItems[parentId].size() <= col) - { - m_model->m_childItems[parentId].append(QList()); - } -// QString name = QUuid::createUuid().toString(); - qint64 id = m_model->newId(); - QString name = QString::number(id); - - m_model->m_items.insert(id, name); - m_model->m_childItems[parentId][col].insert(row, id); - - } - } - m_model->endInsertRows(); -} - - -ModelMoveCommand::ModelMoveCommand(DynamicTreeModel *model, QObject *parent) - : ModelChangeCommand(model, parent) -{ - -} -bool ModelMoveCommand::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) -{ - return m_model->beginMoveRows(srcParent, srcStart, srcEnd, destParent, destRow); -} - -void ModelMoveCommand::doCommand() -{ - QModelIndex srcParent = findIndex(m_rowNumbers); - QModelIndex destParent = findIndex(m_destRowNumbers); - - if (!emitPreSignal(srcParent, m_startRow, m_endRow, destParent, m_destRow)) - { - return; - } - - for (int column = 0; column < m_numCols; ++column) - { - QList l = m_model->m_childItems.value(srcParent.internalId())[column].mid(m_startRow, m_endRow - m_startRow + 1 ); - - for (int i = m_startRow; i <= m_endRow ; i++) - { - m_model->m_childItems[srcParent.internalId()][column].removeAt(m_startRow); - } - int d; - if (m_destRow < m_startRow) - d = m_destRow; - else - { - if (srcParent == destParent) - d = m_destRow - (m_endRow - m_startRow + 1); - else - d = m_destRow - (m_endRow - m_startRow) + 1; - } - - foreach(const qint64 id, l) - { - m_model->m_childItems[destParent.internalId()][column].insert(d++, id); - } - } - - emitPostSignal(); -} - -void ModelMoveCommand::emitPostSignal() -{ - m_model->endMoveRows(); -} - -ModelResetCommand::ModelResetCommand(DynamicTreeModel* model, QObject* parent) - : ModelMoveCommand(model, parent) -{ - -} - -ModelResetCommand::~ModelResetCommand() -{ - -} - -bool ModelResetCommand::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) -{ - Q_UNUSED(srcParent); - Q_UNUSED(srcStart); - Q_UNUSED(srcEnd); - Q_UNUSED(destParent); - Q_UNUSED(destRow); - - return true; -} - -void ModelResetCommand::emitPostSignal() -{ - m_model->reset(); -} - -ModelResetCommandFixed::ModelResetCommandFixed(DynamicTreeModel* model, QObject* parent) - : ModelMoveCommand(model, parent) -{ - -} - -ModelResetCommandFixed::~ModelResetCommandFixed() -{ - -} - -bool ModelResetCommandFixed::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) -{ - Q_UNUSED(srcParent); - Q_UNUSED(srcStart); - Q_UNUSED(srcEnd); - Q_UNUSED(destParent); - Q_UNUSED(destRow); - - m_model->beginResetModel(); - return true; -} - -void ModelResetCommandFixed::emitPostSignal() -{ - m_model->endResetModel(); -} - diff --git a/tests/auto/qabstractitemmodel/dynamictreemodel.h b/tests/auto/qabstractitemmodel/dynamictreemodel.h deleted file mode 100644 index 3f0d90d..0000000 --- a/tests/auto/qabstractitemmodel/dynamictreemodel.h +++ /dev/null @@ -1,199 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Stephen Kelly -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DYNAMICTREEMODEL_H -#define DYNAMICTREEMODEL_H - -#include - -#include -#include - - -template class QList; - -class DynamicTreeModel : public QAbstractItemModel -{ - Q_OBJECT - -public: - DynamicTreeModel(QObject *parent = 0); - - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; - QModelIndex parent(const QModelIndex &index) const; - int rowCount(const QModelIndex &index = QModelIndex()) const; - int columnCount(const QModelIndex &index = QModelIndex()) const; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - - void clear(); - -protected slots: - - /** - Finds the parent id of the string with id @p searchId. - - Returns -1 if not found. - */ - qint64 findParentId(qint64 searchId) const; - -private: - QHash m_items; - QHash > > m_childItems; - qint64 nextId; - qint64 newId() { return nextId++; }; - - QModelIndex m_nextParentIndex; - int m_nextRow; - - int m_depth; - int maxDepth; - - friend class ModelInsertCommand; - friend class ModelMoveCommand; - friend class ModelResetCommand; - friend class ModelResetCommandFixed; - -}; - - -class ModelChangeCommand : public QObject -{ - Q_OBJECT -public: - - ModelChangeCommand( DynamicTreeModel *model, QObject *parent = 0 ); - - virtual ~ModelChangeCommand() {} - - void setAncestorRowNumbers(QList rowNumbers) { m_rowNumbers = rowNumbers; } - - QModelIndex findIndex(QList rows); - - void setStartRow(int row) { m_startRow = row; } - - void setEndRow(int row) { m_endRow = row; } - - void setNumCols(int cols) { m_numCols = cols; } - - virtual void doCommand() = 0; - -protected: - DynamicTreeModel* m_model; - QList m_rowNumbers; - int m_numCols; - int m_startRow; - int m_endRow; - -}; - -typedef QList ModelChangeCommandList; - -class ModelInsertCommand : public ModelChangeCommand -{ - Q_OBJECT - -public: - - ModelInsertCommand(DynamicTreeModel *model, QObject *parent = 0 ); - virtual ~ModelInsertCommand() {} - - virtual void doCommand(); -}; - - -class ModelMoveCommand : public ModelChangeCommand -{ - Q_OBJECT -public: - ModelMoveCommand(DynamicTreeModel *model, QObject *parent); - - virtual ~ModelMoveCommand() {} - - virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow); - - virtual void doCommand(); - - virtual void emitPostSignal(); - - void setDestAncestors( QList rows ) { m_destRowNumbers = rows; } - - void setDestRow(int row) { m_destRow = row; } - -protected: - QList m_destRowNumbers; - int m_destRow; -}; - -/** - A command which does a move and emits a reset signal. -*/ -class ModelResetCommand : public ModelMoveCommand -{ - Q_OBJECT -public: - ModelResetCommand(DynamicTreeModel* model, QObject* parent = 0); - - virtual ~ModelResetCommand(); - - virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow); - virtual void emitPostSignal(); - -}; - -/** - A command which does a move and emits a beginResetModel and endResetModel signals. -*/ -class ModelResetCommandFixed : public ModelMoveCommand -{ - Q_OBJECT -public: - ModelResetCommandFixed(DynamicTreeModel* model, QObject* parent = 0); - - virtual ~ModelResetCommandFixed(); - - virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow); - virtual void emitPostSignal(); - -}; - - -#endif diff --git a/tests/auto/qabstractitemmodel/qabstractitemmodel.pro b/tests/auto/qabstractitemmodel/qabstractitemmodel.pro index a31868b..52c4e96 100644 --- a/tests/auto/qabstractitemmodel/qabstractitemmodel.pro +++ b/tests/auto/qabstractitemmodel/qabstractitemmodel.pro @@ -1,6 +1,9 @@ load(qttest_p4) -SOURCES += tst_qabstractitemmodel.cpp dynamictreemodel.cpp -HEADERS += dynamictreemodel.h + +INCLUDEPATH += $$PWD/../modeltest + +SOURCES += tst_qabstractitemmodel.cpp ../modeltest/dynamictreemodel.cpp ../modeltest/modeltest.cpp +HEADERS += ../modeltest/dynamictreemodel.h ../modeltest/modeltest.h -- cgit v0.12 From bc3c35220e445cb0cffdc0af55f2071566dbffa0 Mon Sep 17 00:00:00 2001 From: Aleksandar Sasha Babic Date: Fri, 18 Dec 2009 13:28:14 +0100 Subject: Fixing compile issue on Windows CE Reviewed-by: TrustMe --- src/gui/widgets/qabstractspinbox.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/gui/widgets/qabstractspinbox.cpp index c036c32..a59cd48 100644 --- a/src/gui/widgets/qabstractspinbox.cpp +++ b/src/gui/widgets/qabstractspinbox.cpp @@ -1180,12 +1180,10 @@ static int getKeyboardAutoRepeatRate() { TTimeIntervalMicroSeconds32 time; S60->wsSession().GetKeyboardRepeatRate(initialTime, time); ret = time.Int() / 1000; // msecs -#elif defined(Q_OS_WIN) +#elif defined(Q_OS_WIN) and !defined(Q_OS_WINCE) DWORD time; if (SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &time, 0) != FALSE) ret = static_cast(1000 / static_cast(time)); // msecs -#else -#pragma message("Using default guesstimated value for keyboard repeat rate") #endif return ret; // msecs } -- cgit v0.12 From 82a35ed3f1dede556e9ab6e30b86997c4a8f0fd1 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 18 Dec 2009 15:13:09 +0000 Subject: Make the layout{,AboutToBe}Changed signals in the QSortFilterProxyModel match its source. Merge-request: 2266 Reviewed-by: Olivier Goffart --- src/gui/itemviews/qsortfilterproxymodel.cpp | 6 +- tests/auto/modeltest/tst_modeltest.cpp | 122 +++++++++++++++++++++++++--- 2 files changed, 115 insertions(+), 13 deletions(-) diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index 95d6bc8..646a3a1 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -1198,9 +1198,10 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutAboutToBeChanged() { Q_Q(QSortFilterProxyModel); saved_persistent_indexes.clear(); + emit q->layoutAboutToBeChanged(); if (persistent.indexes.isEmpty()) return; - emit q->layoutAboutToBeChanged(); + saved_persistent_indexes = store_persistent_indexes(); } @@ -1208,7 +1209,8 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutChanged() { Q_Q(QSortFilterProxyModel); if (saved_persistent_indexes.isEmpty()) { - q->invalidate(); + clear_mapping(); + emit q->layoutChanged(); return; } diff --git a/tests/auto/modeltest/tst_modeltest.cpp b/tests/auto/modeltest/tst_modeltest.cpp index 78aa79f..262b966 100644 --- a/tests/auto/modeltest/tst_modeltest.cpp +++ b/tests/auto/modeltest/tst_modeltest.cpp @@ -66,6 +66,7 @@ private slots: void treeWidgetModel(); void standardItemModel(); void testInsertThroughProxy(); + void moveSourceItems(); }; @@ -94,15 +95,15 @@ void tst_ModelTest::stringListModel() { QStringListModel model; QSortFilterProxyModel proxy; - + ModelTest t1(&model); ModelTest t2(&proxy); - + proxy.setSourceModel(&model); - + model.setStringList(QStringList() << "2" << "3" << "1"); model.setStringList(QStringList() << "a" << "e" << "plop" << "b" << "c" ); - + proxy.setDynamicSortFilter(true); proxy.setFilterRegExp(QRegExp("[^b]")); } @@ -112,7 +113,7 @@ void tst_ModelTest::treeWidgetModel() QTreeWidget widget; ModelTest t1(widget.model()); - + QTreeWidgetItem *root = new QTreeWidgetItem(&widget, QStringList("root")); for (int i = 0; i < 20; ++i) { new QTreeWidgetItem(root, QStringList(QString::number(i))); @@ -122,7 +123,7 @@ void tst_ModelTest::treeWidgetModel() QTreeWidgetItem *parent = new QTreeWidgetItem(&widget, QStringList("parent")); new QTreeWidgetItem(parent, QStringList("child")); widget.setItemHidden(parent, true); - + widget.sortByColumn(0); } @@ -130,19 +131,19 @@ void tst_ModelTest::standardItemModel() { QStandardItemModel model(10,10); QSortFilterProxyModel proxy; - - + + ModelTest t1(&model); ModelTest t2(&proxy); - + proxy.setSourceModel(&model); - + model.insertRows(2, 5); model.removeRows(4, 5); model.insertColumns(2, 5); model.removeColumns(4, 5); - + model.insertRows(0,5, model.index(1,1)); model.insertColumns(0,5, model.index(1,3)); } @@ -179,5 +180,104 @@ void tst_ModelTest::testInsertThroughProxy() moveCommand->doCommand(); } +/** + Makes the persistent index list publicly accessible +*/ +class AccessibleProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT +public: + AccessibleProxyModel(QObject *parent = 0) : QSortFilterProxyModel(parent) {} + + QModelIndexList persistent() + { + return persistentIndexList(); + } +}; + +class ObservingObject : public QObject +{ + Q_OBJECT +public: + ObservingObject(AccessibleProxyModel *proxy, QObject *parent = 0) + : QObject(parent), + m_proxy(proxy) + { + connect(m_proxy, SIGNAL(layoutAboutToBeChanged()), SLOT(storePersistent())); + connect(m_proxy, SIGNAL(layoutChanged()), SLOT(checkPersistent())); + } + +public slots: + + void storePersistent(const QModelIndex &parent) + { + for (int row = 0; row < m_proxy->rowCount(parent); ++row) { + QModelIndex proxyIndex = m_proxy->index(row, 0, parent); + QModelIndex sourceIndex = m_proxy->mapToSource(proxyIndex); + Q_ASSERT(proxyIndex.isValid()); + Q_ASSERT(sourceIndex.isValid()); + m_persistentSourceIndexes.append(sourceIndex); + m_persistentProxyIndexes.append(proxyIndex); + if (m_proxy->hasChildren(proxyIndex)) + storePersistent(proxyIndex); + } + } + + void storePersistent() + { + m_persistentSourceIndexes.clear(); + m_persistentProxyIndexes.clear(); + Q_ASSERT(m_proxy->persistent().isEmpty()); + storePersistent(QModelIndex()); + Q_ASSERT(!m_proxy->persistent().isEmpty()); + } + + void checkPersistent() + { + for (int row = 0; row < m_persistentProxyIndexes.size(); ++row) { + QModelIndex updatedProxy = m_persistentProxyIndexes.at(row); + QModelIndex updatedSource = m_persistentSourceIndexes.at(row); + } + for (int row = 0; row < m_persistentProxyIndexes.size(); ++row) { + QModelIndex updatedProxy = m_persistentProxyIndexes.at(row); + QModelIndex updatedSource = m_persistentSourceIndexes.at(row); + QCOMPARE(m_proxy->mapToSource(updatedProxy), updatedSource); + } + } + +private: + AccessibleProxyModel *m_proxy; + QList m_persistentSourceIndexes; + QList m_persistentProxyIndexes; +}; + +void tst_ModelTest::moveSourceItems() +{ + DynamicTreeModel *model = new DynamicTreeModel(this); + AccessibleProxyModel *proxy = new AccessibleProxyModel(this); + proxy->setSourceModel(model); + + ModelInsertCommand *insertCommand = new ModelInsertCommand(model, this); + insertCommand->setStartRow(0); + insertCommand->setEndRow(2); + insertCommand->doCommand(); + + insertCommand = new ModelInsertCommand(model, this); + insertCommand->setAncestorRowNumbers(QList() << 1); + insertCommand->setStartRow(0); + insertCommand->setEndRow(2); + insertCommand->doCommand(); + + ObservingObject observer(proxy); + + ModelMoveCommand *moveCommand = new ModelMoveCommand(model, this); + moveCommand->setStartRow(0); + moveCommand->setEndRow(0); + moveCommand->setDestAncestors(QList() << 1); + moveCommand->setDestRow(0); + moveCommand->doCommand(); +} + + QTEST_MAIN(tst_ModelTest) #include "tst_modeltest.moc" -- cgit v0.12 From c8e7e728f897cce45e9f94dbf16be6731f92e414 Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Fri, 18 Dec 2009 14:54:23 +0100 Subject: Fix a bug in resizing the anomaly browser demo. The sliding surface does not move, the position of the children must be used to find the correct layout. --- demos/embedded/anomaly/src/BrowserWindow.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/demos/embedded/anomaly/src/BrowserWindow.cpp b/demos/embedded/anomaly/src/BrowserWindow.cpp index 1163b6a..30b6b91 100644 --- a/demos/embedded/anomaly/src/BrowserWindow.cpp +++ b/demos/embedded/anomaly/src/BrowserWindow.cpp @@ -150,6 +150,9 @@ void BrowserWindow::keyReleaseEvent(QKeyEvent *event) void BrowserWindow::resizeEvent(QResizeEvent *event) { + const QSize oldSize = event->oldSize(); + const qreal oldSlidingRatio = static_cast(qAbs(m_homeView->x())) / oldSize.width(); + const QSize newSize = event->size(); m_slidingSurface->resize(newSize.width() * 2, newSize.height()); @@ -159,7 +162,5 @@ void BrowserWindow::resizeEvent(QResizeEvent *event) m_browserView->resize(newSize); m_browserView->move(newSize.width(), 0); - const QSize oldSize = event->oldSize(); - const qreal oldSlidingRatio = static_cast(qAbs(m_slidingSurface->x())) / oldSize.width(); setSlideValue(oldSlidingRatio); } -- cgit v0.12 From 51be60532af93ac6526e76db4085283465c5baa6 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Fri, 18 Dec 2009 16:54:16 +0100 Subject: Fixes bug when using AnchorUnderMouse for GraphicsView transformation. We now automatically enable mouse tracking on the viewport of the GraphicsView when setting AnchorUnderMouse as transformationAnchor or resizeAnchor. Autotest included. Task-number: QTBUG-6835 Reviewed-by: bnilsen --- src/gui/graphicsview/qgraphicsview.cpp | 19 ++++- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 97 ++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 3 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index ffe64aa..3bb40fb 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -1208,6 +1208,11 @@ void QGraphicsView::setTransformationAnchor(ViewportAnchor anchor) { Q_D(QGraphicsView); d->transformationAnchor = anchor; + + // Ensure mouse tracking is enabled in the case we are using AnchorUnderMouse + // in order to have up-to-date information for centering the view. + if (d->transformationAnchor == AnchorUnderMouse) + d->viewport->setMouseTracking(true); } /*! @@ -1235,6 +1240,11 @@ void QGraphicsView::setResizeAnchor(ViewportAnchor anchor) { Q_D(QGraphicsView); d->resizeAnchor = anchor; + + // Ensure mouse tracking is enabled in the case we are using AnchorUnderMouse + // in order to have up-to-date information for centering the view. + if (d->resizeAnchor == AnchorUnderMouse) + d->viewport->setMouseTracking(true); } /*! @@ -2597,9 +2607,12 @@ void QGraphicsView::setupViewport(QWidget *widget) } // We are only interested in mouse tracking if items - // accept hover events or use non-default cursors. - if (d->scene && (!d->scene->d_func()->allItemsIgnoreHoverEvents - || !d->scene->d_func()->allItemsUseDefaultCursor)) { + // accept hover events or use non-default cursors or if + // AnchorUnderMouse is used as transformation or resize anchor. + if ((d->scene && (!d->scene->d_func()->allItemsIgnoreHoverEvents + || !d->scene->d_func()->allItemsUseDefaultCursor)) + || d->transformationAnchor == AnchorUnderMouse + || d->resizeAnchor == AnchorUnderMouse) { widget->setMouseTracking(true); } diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 69df39b..9e4321b 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -211,6 +211,7 @@ private slots: void centerOnDirtyItem(); void mouseTracking(); void mouseTracking2(); + void mouseTracking3(); void render(); void exposeRegion(); void update_data(); @@ -3403,6 +3404,102 @@ void tst_QGraphicsView::mouseTracking2() QCOMPARE(spy.count(), 1); } +void tst_QGraphicsView::mouseTracking3() +{ + // Mouse tracking should be automatically enabled if AnchorUnderMouse is used for + // view transform or resize. We never disable mouse tracking if it is already enabled. + + { // Make sure we enable mouse tracking when using AnchorUnderMouse for view transformation. + QGraphicsScene scene(-10000, -10000, 20000, 20000); + QGraphicsView view(&scene); + QVERIFY(!view.viewport()->hasMouseTracking()); + + view.setTransformationAnchor(QGraphicsView::AnchorUnderMouse); + QVERIFY(view.viewport()->hasMouseTracking()); + } + + { // Make sure we enable mouse tracking when using AnchorUnderMouse for view resizing. + QGraphicsScene scene(-10000, -10000, 20000, 20000); + QGraphicsView view(&scene); + QVERIFY(!view.viewport()->hasMouseTracking()); + + view.setResizeAnchor(QGraphicsView::AnchorUnderMouse); + QVERIFY(view.viewport()->hasMouseTracking()); + } + + { // Make sure we don't disable mouse tracking in setViewport/setScene (transformation anchor). + QGraphicsView view; + view.setTransformationAnchor(QGraphicsView::AnchorUnderMouse); + QVERIFY(view.viewport()->hasMouseTracking()); + + QWidget *viewport = new QWidget; + view.setViewport(viewport); + QVERIFY(viewport->hasMouseTracking()); + + QGraphicsScene scene(-10000, -10000, 20000, 20000); + view.setScene(&scene); + QVERIFY(viewport->hasMouseTracking()); + } + + { // Make sure we don't disable mouse tracking in setViewport/setScene (resize anchor). + QGraphicsView view; + view.setResizeAnchor(QGraphicsView::AnchorUnderMouse); + QVERIFY(view.viewport()->hasMouseTracking()); + + QWidget *viewport = new QWidget; + view.setViewport(viewport); + QVERIFY(viewport->hasMouseTracking()); + + QGraphicsScene scene(-10000, -10000, 20000, 20000); + view.setScene(&scene); + QVERIFY(viewport->hasMouseTracking()); + } + + // Make sure we don't disable mouse tracking when adding an item (transformation anchor). + { // Adding an item to the scene before the scene is set on the view. + QGraphicsScene scene(-10000, -10000, 20000, 20000); + QGraphicsRectItem *item = new QGraphicsRectItem(10, 10, 10, 10); + scene.addItem(item); + + QGraphicsView view; + view.setTransformationAnchor(QGraphicsView::AnchorUnderMouse); + view.setScene(&scene); + QVERIFY(view.viewport()->hasMouseTracking()); + } + + { // Adding an item to the scene after the scene is set on the view. + QGraphicsScene scene(-10000, -10000, 20000, 20000); + QGraphicsView view(&scene); + view.setTransformationAnchor(QGraphicsView::AnchorUnderMouse); + + QGraphicsRectItem *item = new QGraphicsRectItem(10, 10, 10, 10); + scene.addItem(item); + QVERIFY(view.viewport()->hasMouseTracking()); + } + + // Make sure we don't disable mouse tracking when adding an item (resize anchor). + { // Adding an item to the scene before the scene is set on the view. + QGraphicsScene scene(-10000, -10000, 20000, 20000); + QGraphicsRectItem *item = new QGraphicsRectItem(10, 10, 10, 10); + scene.addItem(item); + + QGraphicsView view; + view.setResizeAnchor(QGraphicsView::AnchorUnderMouse); + view.setScene(&scene); + QVERIFY(view.viewport()->hasMouseTracking()); + } + + { // Adding an item to the scene after the scene is set on the view. + QGraphicsScene scene(-10000, -10000, 20000, 20000); + QGraphicsView view(&scene); + view.setResizeAnchor(QGraphicsView::AnchorUnderMouse); + + QGraphicsRectItem *item = new QGraphicsRectItem(10, 10, 10, 10); + scene.addItem(item); + QVERIFY(view.viewport()->hasMouseTracking()); + } +} + class RenderTester : public QGraphicsRectItem { public: -- cgit v0.12 From f708b248aec810a1dcad1f13e1c16390244c9834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Fri, 18 Dec 2009 17:48:10 +0100 Subject: Fixed QPixmap::load() to not modify referenced copies. This is a bad regression from 4.5. QPixmap::load() would modify all references to the same QPixmap object. Task-number: QTBUG-6840 Reviewed-by: Kim --- src/gui/image/qpixmap.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 617cfe5..7e4597e 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -831,14 +831,13 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers if (QPixmapCache::find(key, *this)) return true; - if (!data) - data = QPixmapData::create(0, 0, QPixmapData::PixmapType); - - if (data->fromFile(fileName, format, flags)) { + QPixmapData *tmp = QPixmapData::create(0, 0, QPixmapData::PixmapType); + if (tmp->fromFile(fileName, format, flags)) { + data = tmp; QPixmapCache::insert(key, *this); return true; } - + delete tmp; return false; } -- cgit v0.12 From 05b1d910221ca5d9bf2165fd1aad4606537bdd9f Mon Sep 17 00:00:00 2001 From: David Laing Date: Mon, 21 Dec 2009 16:12:01 +1000 Subject: Fix for WinCE compilation of QAbstractSpinBox. --- src/gui/widgets/qabstractspinbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/gui/widgets/qabstractspinbox.cpp index a59cd48..e26d5c3 100644 --- a/src/gui/widgets/qabstractspinbox.cpp +++ b/src/gui/widgets/qabstractspinbox.cpp @@ -1180,7 +1180,7 @@ static int getKeyboardAutoRepeatRate() { TTimeIntervalMicroSeconds32 time; S60->wsSession().GetKeyboardRepeatRate(initialTime, time); ret = time.Int() / 1000; // msecs -#elif defined(Q_OS_WIN) and !defined(Q_OS_WINCE) +#elif defined(Q_OS_WIN) && !defined(Q_OS_WINCE) DWORD time; if (SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &time, 0) != FALSE) ret = static_cast(1000 / static_cast(time)); // msecs -- cgit v0.12 From 072a571fc0c41610b76465d76eb635b959eaad37 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 21 Dec 2009 12:35:50 +0200 Subject: Forwarded return value from QtMainWrapper() to E32Main() exit code. Previously only leaves from QtMainWrapper() were forwarded. Task-number: QTBUG-6422 Reviewed-by: axis --- src/s60main/qts60main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/s60main/qts60main.cpp b/src/s60main/qts60main.cpp index 9f2d8c4..8923fb9 100644 --- a/src/s60main/qts60main.cpp +++ b/src/s60main/qts60main.cpp @@ -52,7 +52,7 @@ GLDEF_C TInt E32Main() { CTrapCleanup *cleanupStack = q_check_ptr(CTrapCleanup::New()); TInt err = 0; - TRAP(err, QtMainWrapper()); + TRAP(err, err = QtMainWrapper()); delete cleanupStack; return err; -- cgit v0.12 From 3e45dbcc89a9f2284d8ab89e0c75bd7b275e6b61 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 21 Dec 2009 12:49:12 +0200 Subject: RVCT 2.2 compiler can't handle static inline functions with templates. Removed static keywords from offending functions. Reviewed-by: axis --- src/gui/image/qpixmapfilter.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp index caa0752..78a6b43 100644 --- a/src/gui/image/qpixmapfilter.cpp +++ b/src/gui/image/qpixmapfilter.cpp @@ -602,7 +602,7 @@ QRectF QPixmapBlurFilter::boundingRectFor(const QRectF &rect) const } template -static inline int static_shift(int value) +inline int static_shift(int value) { if (shift == 0) return value; @@ -613,7 +613,7 @@ static inline int static_shift(int value) } template -static inline void blurinner(uchar *bptr, int &zR, int &zG, int &zB, int &zA, int alpha) +inline void blurinner(uchar *bptr, int &zR, int &zG, int &zB, int &zA, int alpha) { QRgb *pixel = (QRgb *)bptr; @@ -646,7 +646,7 @@ static inline void blurinner(uchar *bptr, int &zR, int &zG, int &zB, int &zA, in const int alphaIndex = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3); template -static inline void blurinner_alphaOnly(uchar *bptr, int &z, int alpha) +inline void blurinner_alphaOnly(uchar *bptr, int &z, int alpha) { const int A_zprec = int(*(bptr)) << zprec; const int z_zprec = z >> aprec; @@ -655,7 +655,7 @@ static inline void blurinner_alphaOnly(uchar *bptr, int &z, int alpha) } template -static inline void blurrow(QImage & im, int line, int alpha) +inline void blurrow(QImage & im, int line, int alpha) { uchar *bptr = im.scanLine(line); -- cgit v0.12 From 71ee64f5a44dc310272b14fe6cd913b2e75672ed Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Mon, 21 Dec 2009 13:28:47 +0200 Subject: Edit focus should not be lost unless by explicit action Currently non-touch devices lose edit focus if window switch happens. I.e. in cases when screensaver activates, an incoming call occurs, a global notification is shown... With this fix, edit focus remain active, until user removes the focus explicitly. Task-number: 4792 Reviewed-by: axis --- src/gui/kernel/qapplication.cpp | 6 +++++- src/gui/text/qtextcontrol.cpp | 6 +++++- src/gui/widgets/qlineedit.cpp | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index bd13423..4165c95 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -2096,7 +2096,11 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason) if (prev) { #ifdef QT_KEYPAD_NAVIGATION if (QApplication::keypadNavigationEnabled()) { - if (prev->hasEditFocus() && reason != Qt::PopupFocusReason) + if (prev->hasEditFocus() && reason != Qt::PopupFocusReason +#ifdef Q_OS_SYMBIAN + && reason != Qt::ActiveWindowFocusReason +#endif + ) prev->setEditFocus(false); } #endif diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index f96f66b..f523226 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -1938,7 +1938,11 @@ void QTextControlPrivate::focusEvent(QFocusEvent *e) emit q->updateRequest(q->selectionRect()); if (e->gotFocus()) { #ifdef QT_KEYPAD_NAVIGATION - if (!QApplication::keypadNavigationEnabled() || (hasEditFocus && e->reason() == Qt::PopupFocusReason)) { + if (!QApplication::keypadNavigationEnabled() || (hasEditFocus && (e->reason() == Qt::PopupFocusReason +#ifdef Q_OS_SYMBIAN + || e->reason() == Qt::ActiveWindowFocusReason +#endif + ))) { #endif cursorOn = (interactionFlags & Qt::TextSelectableByKeyboard); if (interactionFlags & Qt::TextEditable) { diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index 15dcda2..573b2b5 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -1761,7 +1761,11 @@ void QLineEdit::focusInEvent(QFocusEvent *e) d->clickCausedFocus = 1; } #ifdef QT_KEYPAD_NAVIGATION - if (!QApplication::keypadNavigationEnabled() || (hasEditFocus() && e->reason() == Qt::PopupFocusReason)){ + if (!QApplication::keypadNavigationEnabled() || (hasEditFocus() && ( e->reason() == Qt::PopupFocusReason +#ifdef Q_OS_SYMBIAN + || e->reason() == Qt::ActiveWindowFocusReason +#endif + ))) { #endif d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime()); QStyleOptionFrameV2 opt; -- cgit v0.12 From cba4d931bec2cb910e4dc149e0bc5d441cd64511 Mon Sep 17 00:00:00 2001 From: Carlos Manuel Duclos Vergara Date: Mon, 21 Dec 2009 12:03:44 +0100 Subject: Fixing a problem with xmlpatterns, where code from tools/xmlpatterns was being included by src/xmlpatterns. Reviewed-by: Peter Hartmann --- src/xmlpatterns/api/api.pri | 116 ++++---- src/xmlpatterns/api/qcoloringmessagehandler.cpp | 198 ++++++++++++++ src/xmlpatterns/api/qcoloringmessagehandler_p.h | 98 +++++++ src/xmlpatterns/api/qcoloroutput.cpp | 348 ++++++++++++++++++++++++ src/xmlpatterns/api/qcoloroutput_p.h | 133 +++++++++ src/xmlpatterns/xmlpatterns.pro | 34 ++- tools/xmlpatterns/main.cpp | 2 +- tools/xmlpatterns/main.h | 10 +- tools/xmlpatterns/qcoloringmessagehandler.cpp | 199 -------------- tools/xmlpatterns/qcoloringmessagehandler_p.h | 98 ------- tools/xmlpatterns/qcoloroutput.cpp | 348 ------------------------ tools/xmlpatterns/qcoloroutput_p.h | 133 --------- tools/xmlpatterns/xmlpatterns.pro | 8 +- 13 files changed, 854 insertions(+), 871 deletions(-) create mode 100644 src/xmlpatterns/api/qcoloringmessagehandler.cpp create mode 100644 src/xmlpatterns/api/qcoloringmessagehandler_p.h create mode 100644 src/xmlpatterns/api/qcoloroutput.cpp create mode 100644 src/xmlpatterns/api/qcoloroutput_p.h delete mode 100644 tools/xmlpatterns/qcoloringmessagehandler.cpp delete mode 100644 tools/xmlpatterns/qcoloringmessagehandler_p.h delete mode 100644 tools/xmlpatterns/qcoloroutput.cpp delete mode 100644 tools/xmlpatterns/qcoloroutput_p.h diff --git a/src/xmlpatterns/api/api.pri b/src/xmlpatterns/api/api.pri index 9fcc2f5..a0adf75 100644 --- a/src/xmlpatterns/api/api.pri +++ b/src/xmlpatterns/api/api.pri @@ -1,59 +1,57 @@ -HEADERS += $$PWD/qabstractxmlforwarditerator_p.h \ - $$PWD/qabstractmessagehandler.h \ - $$PWD/qabstracturiresolver.h \ - $$PWD/qabstractxmlnodemodel.h \ - $$PWD/qabstractxmlnodemodel_p.h \ - $$PWD/qabstractxmlpullprovider_p.h \ - $$PWD/qabstractxmlreceiver.h \ - $$PWD/qabstractxmlreceiver_p.h \ - $$PWD/qdeviceresourceloader_p.h \ - $$PWD/qiodevicedelegate_p.h \ - $$PWD/qnetworkaccessdelegator_p.h \ - $$PWD/qpullbridge_p.h \ - $$PWD/qresourcedelegator_p.h \ - $$PWD/qsimplexmlnodemodel.h \ - $$PWD/qsourcelocation.h \ - $$PWD/quriloader_p.h \ - $$PWD/qvariableloader_p.h \ - $$PWD/qxmlformatter.h \ - $$PWD/qxmlname.h \ - $$PWD/qxmlnamepool.h \ - $$PWD/qxmlquery.h \ - $$PWD/qxmlquery_p.h \ - $$PWD/qxmlresultitems.h \ - $$PWD/qxmlresultitems_p.h \ - $$PWD/qxmlschema.h \ - $$PWD/qxmlschema_p.h \ - $$PWD/qxmlschemavalidator.h \ - $$PWD/qxmlschemavalidator_p.h \ - $$PWD/qxmlserializer.h \ - $$PWD/qxmlserializer_p.h \ - $$PWD/../../../tools/xmlpatterns/qcoloringmessagehandler_p.h \ - $$PWD/../../../tools/xmlpatterns/qcoloroutput_p.h - -SOURCES += $$PWD/qvariableloader.cpp \ - $$PWD/qabstractmessagehandler.cpp \ - $$PWD/qabstracturiresolver.cpp \ - $$PWD/qabstractxmlnodemodel.cpp \ - $$PWD/qabstractxmlpullprovider.cpp \ - $$PWD/qabstractxmlreceiver.cpp \ - $$PWD/qiodevicedelegate.cpp \ - $$PWD/qnetworkaccessdelegator.cpp \ - $$PWD/qpullbridge.cpp \ - $$PWD/qresourcedelegator.cpp \ - $$PWD/qsimplexmlnodemodel.cpp \ - $$PWD/qsourcelocation.cpp \ - $$PWD/quriloader.cpp \ - $$PWD/qxmlformatter.cpp \ - $$PWD/qxmlname.cpp \ - $$PWD/qxmlnamepool.cpp \ - $$PWD/qxmlquery.cpp \ - $$PWD/qxmlresultitems.cpp \ - $$PWD/qxmlschema.cpp \ - $$PWD/qxmlschema_p.cpp \ - $$PWD/qxmlschemavalidator.cpp \ - $$PWD/qxmlserializer.cpp \ - $$PWD/../../../tools/xmlpatterns/qcoloringmessagehandler.cpp \ - $$PWD/../../../tools/xmlpatterns/qcoloroutput.cpp - -INCLUDEPATH += $$PWD/../../../tools/xmlpatterns/ +HEADERS += $$PWD/qabstractxmlforwarditerator_p.h \ + $$PWD/qabstractmessagehandler.h \ + $$PWD/qabstracturiresolver.h \ + $$PWD/qabstractxmlnodemodel.h \ + $$PWD/qabstractxmlnodemodel_p.h \ + $$PWD/qabstractxmlpullprovider_p.h \ + $$PWD/qabstractxmlreceiver.h \ + $$PWD/qabstractxmlreceiver_p.h \ + $$PWD/qdeviceresourceloader_p.h \ + $$PWD/qiodevicedelegate_p.h \ + $$PWD/qnetworkaccessdelegator_p.h \ + $$PWD/qpullbridge_p.h \ + $$PWD/qresourcedelegator_p.h \ + $$PWD/qsimplexmlnodemodel.h \ + $$PWD/qsourcelocation.h \ + $$PWD/quriloader_p.h \ + $$PWD/qvariableloader_p.h \ + $$PWD/qxmlformatter.h \ + $$PWD/qxmlname.h \ + $$PWD/qxmlnamepool.h \ + $$PWD/qxmlquery.h \ + $$PWD/qxmlquery_p.h \ + $$PWD/qxmlresultitems.h \ + $$PWD/qxmlresultitems_p.h \ + $$PWD/qxmlschema.h \ + $$PWD/qxmlschema_p.h \ + $$PWD/qxmlschemavalidator.h \ + $$PWD/qxmlschemavalidator_p.h \ + $$PWD/qxmlserializer.h \ + $$PWD/qxmlserializer_p.h \ + $$PWD/qcoloringmessagehandler_p.h \ + $$PWD/qcoloroutput_p.h \ + $$PWD/qxmlpatternistcli_p.h +SOURCES += $$PWD/qvariableloader.cpp \ + $$PWD/qabstractmessagehandler.cpp \ + $$PWD/qabstracturiresolver.cpp \ + $$PWD/qabstractxmlnodemodel.cpp \ + $$PWD/qabstractxmlpullprovider.cpp \ + $$PWD/qabstractxmlreceiver.cpp \ + $$PWD/qiodevicedelegate.cpp \ + $$PWD/qnetworkaccessdelegator.cpp \ + $$PWD/qpullbridge.cpp \ + $$PWD/qresourcedelegator.cpp \ + $$PWD/qsimplexmlnodemodel.cpp \ + $$PWD/qsourcelocation.cpp \ + $$PWD/quriloader.cpp \ + $$PWD/qxmlformatter.cpp \ + $$PWD/qxmlname.cpp \ + $$PWD/qxmlnamepool.cpp \ + $$PWD/qxmlquery.cpp \ + $$PWD/qxmlresultitems.cpp \ + $$PWD/qxmlschema.cpp \ + $$PWD/qxmlschema_p.cpp \ + $$PWD/qxmlschemavalidator.cpp \ + $$PWD/qxmlserializer.cpp \ + $$PWD/qcoloringmessagehandler.cpp \ + $$PWD/qcoloroutput.cpp diff --git a/src/xmlpatterns/api/qcoloringmessagehandler.cpp b/src/xmlpatterns/api/qcoloringmessagehandler.cpp new file mode 100644 index 0000000..7d3eb6f --- /dev/null +++ b/src/xmlpatterns/api/qcoloringmessagehandler.cpp @@ -0,0 +1,198 @@ +/**************************************************************************** +** +** 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 QtCore 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 "qcoloringmessagehandler_p.h" +#include "qxmlpatternistcli_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ColoringMessageHandler::ColoringMessageHandler(QObject *parent) : QAbstractMessageHandler(parent) +{ + m_classToColor.insert(QLatin1String("XQuery-data"), Data); + m_classToColor.insert(QLatin1String("XQuery-expression"), Keyword); + m_classToColor.insert(QLatin1String("XQuery-function"), Keyword); + m_classToColor.insert(QLatin1String("XQuery-keyword"), Keyword); + m_classToColor.insert(QLatin1String("XQuery-type"), Keyword); + m_classToColor.insert(QLatin1String("XQuery-uri"), Data); + m_classToColor.insert(QLatin1String("XQuery-filepath"), Data); + + /* If you're tuning the colors, take it easy laddie. Take into account: + * + * - Get over your own taste, there's others too on this planet + * - Make sure it works well on black & white + * - Make sure it works well on white & black + */ + insertMapping(Location, CyanForeground); + insertMapping(ErrorCode, RedForeground); + insertMapping(Keyword, BlueForeground); + insertMapping(Data, BlueForeground); + insertMapping(RunningText, DefaultColor); +} + +void ColoringMessageHandler::handleMessage(QtMsgType type, + const QString &description, + const QUrl &identifier, + const QSourceLocation &sourceLocation) +{ + const bool hasLine = sourceLocation.line() != -1; + + switch(type) + { + case QtWarningMsg: + { + if(hasLine) + { + writeUncolored(QXmlPatternistCLI::tr("Warning in %1, at line %2, column %3: %4").arg(QString::fromLatin1(sourceLocation.uri().toEncoded()), + QString::number(sourceLocation.line()), + QString::number(sourceLocation.column()), + colorifyDescription(description))); + } + else + { + writeUncolored(QXmlPatternistCLI::tr("Warning in %1: %2").arg(QString::fromLatin1(sourceLocation.uri().toEncoded()), + colorifyDescription(description))); + } + + break; + } + case QtFatalMsg: + { + const QString errorCode(identifier.fragment()); + Q_ASSERT(!errorCode.isEmpty()); + QUrl uri(identifier); + uri.setFragment(QString()); + + QString location; + + if(sourceLocation.isNull()) + location = QXmlPatternistCLI::tr("Unknown location"); + else + location = QString::fromLatin1(sourceLocation.uri().toEncoded()); + + QString errorId; + /* If it's a standard error code, we don't want to output the + * whole URI. */ + if(uri.toString() == QLatin1String("http://www.w3.org/2005/xqt-errors")) + errorId = errorCode; + else + errorId = QString::fromLatin1(identifier.toEncoded()); + + if(hasLine) + { + writeUncolored(QXmlPatternistCLI::tr("Error %1 in %2, at line %3, column %4: %5").arg(colorify(errorId, ErrorCode), + colorify(location, Location), + colorify(QString::number(sourceLocation.line()), Location), + colorify(QString::number(sourceLocation.column()), Location), + colorifyDescription(description))); + } + else + { + writeUncolored(QXmlPatternistCLI::tr("Error %1 in %2: %3").arg(colorify(errorId, ErrorCode), + colorify(location, Location), + colorifyDescription(description))); + } + break; + } + case QtCriticalMsg: + /* Fallthrough. */ + case QtDebugMsg: + { + Q_ASSERT_X(false, Q_FUNC_INFO, + "message() is not supposed to receive QtCriticalMsg or QtDebugMsg."); + return; + } + } +} + +QString ColoringMessageHandler::colorifyDescription(const QString &in) const +{ + QXmlStreamReader reader(in); + QString result; + result.reserve(in.size()); + ColorType currentColor = RunningText; + + while(!reader.atEnd()) + { + reader.readNext(); + + switch(reader.tokenType()) + { + case QXmlStreamReader::StartElement: + { + if(reader.name() == QLatin1String("span")) + { + Q_ASSERT(m_classToColor.contains(reader.attributes().value(QLatin1String("class")).toString())); + currentColor = m_classToColor.value(reader.attributes().value(QLatin1String("class")).toString()); + } + + continue; + } + case QXmlStreamReader::Characters: + { + result.append(colorify(reader.text().toString(), currentColor)); + continue; + } + case QXmlStreamReader::EndElement: + { + currentColor = RunningText; + continue; + } + /* Fallthrough, */ + case QXmlStreamReader::StartDocument: + /* Fallthrough, */ + case QXmlStreamReader::EndDocument: + continue; + default: + Q_ASSERT_X(false, Q_FUNC_INFO, + "Unexpected node."); + } + } + + Q_ASSERT_X(!reader.hasError(), Q_FUNC_INFO, + "The output from Patternist must be well-formed."); + return result; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/api/qcoloringmessagehandler_p.h b/src/xmlpatterns/api/qcoloringmessagehandler_p.h new file mode 100644 index 0000000..3e8d18b --- /dev/null +++ b/src/xmlpatterns/api/qcoloringmessagehandler_p.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** 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 XMLPatterns 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 purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ColoringMessageHandler_h +#define Patternist_ColoringMessageHandler_h + +#include + +#include "qcoloroutput_p.h" +#include "qabstractmessagehandler.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + class ColoringMessageHandler : public QAbstractMessageHandler + , private ColorOutput + { + public: + ColoringMessageHandler(QObject *parent = 0); + + protected: + virtual void handleMessage(QtMsgType type, + const QString &description, + const QUrl &identifier, + const QSourceLocation &sourceLocation); + + private: + QString colorifyDescription(const QString &in) const; + + enum ColorType + { + RunningText, + Location, + ErrorCode, + Keyword, + Data + }; + + QHash m_classToColor; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qcoloroutput.cpp b/src/xmlpatterns/api/qcoloroutput.cpp new file mode 100644 index 0000000..4f27fd5 --- /dev/null +++ b/src/xmlpatterns/api/qcoloroutput.cpp @@ -0,0 +1,348 @@ +/**************************************************************************** +** +** 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 QtXmlPatterns 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 "qcoloroutput_p.h" + +// TODO: rename insertMapping() to insertColorMapping() +// TODO: Use a smart pointer for managing ColorOutputPrivate *d; +// TODO: break out the C++ example into a snippet file + +/* This include must appear here, because if it appears at the beginning of the file for + * instance, it breaks build -- "qglobal.h:628: error: template with + * C linkage" -- on Mac OS X 10.4. */ +#ifndef Q_OS_WIN +#include +#endif + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +namespace QPatternist +{ + class ColorOutputPrivate + { + public: + ColorOutputPrivate() : currentColorID(-1) + + { + /* - QIODevice::Unbuffered because we want it to appear when the user actually calls, performance + * is considered of lower priority. + */ + m_out.open(stderr, QIODevice::WriteOnly | QIODevice::Unbuffered); + + coloringEnabled = isColoringPossible(); + } + + ColorOutput::ColorMapping colorMapping; + int currentColorID; + bool coloringEnabled; + + static const char *const foregrounds[]; + static const char *const backgrounds[]; + + inline void write(const QString &msg) + { + m_out.write(msg.toLocal8Bit()); + } + + static QString escapeCode(const QString &in) + { + QString result; + result.append(QChar(0x1B)); + result.append(QLatin1Char('[')); + result.append(in); + result.append(QLatin1Char('m')); + return result; + } + + private: + QFile m_out; + + /*! + Returns true if it's suitable to send colored output to \c stderr. + */ + inline bool isColoringPossible() const + { +# if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) + /* Windows doesn't at all support ANSI escape codes, unless + * the user install a "device driver". See the Wikipedia links in the + * class documentation for details. */ + return false; +# else + /* We use QFile::handle() to get the file descriptor. It's a bit unsure + * whether it's 2 on all platforms and in all cases, so hopefully this layer + * of abstraction helps handle such cases. */ + return isatty(m_out.handle()); +# endif + } + }; +} + +const char *const ColorOutputPrivate::foregrounds[] = +{ + "0;30", + "0;34", + "0;32", + "0;36", + "0;31", + "0;35", + "0;33", + "0;37", + "1;30", + "1;34", + "1;32", + "1;36", + "1;31", + "1;35", + "1;33", + "1;37" +}; + +const char *const ColorOutputPrivate::backgrounds[] = +{ + "0;40", + "0;44", + "0;42", + "0;46", + "0;41", + "0;45", + "0;43" +}; + +/*! + \since 4.4 + \nonreentrant + \brief Outputs colored messages to \c stderr. + \internal + + ColorOutput is a convenience class for outputting messages to \c stderr + using color escape codes, as mandated in ECMA-48. ColorOutput will only + color output when it is detected to be suitable. For instance, if \c stderr is + detected to be attached to a file instead of a TTY, no coloring will be done. + + ColorOutput does its best attempt. but it is generally undefined what coloring + or effect the various coloring flags has. It depends strongly on what terminal + software that is being used. + + When using `echo -e 'my escape sequence'`, \033 works as an initiator but not + when printing from a C++ program, despite having escaped the backslash. + That's why we below use characters with value 0x1B. + + It can be convenient to subclass ColorOutput with a private scope, such that the + functions are directly available in the class using it. + + \section1 Usage + + To output messages, call write() or writeUncolored(). write() takes as second + argument an integer, which ColorOutput uses as a lookup key to find the color + it should color the text in. The mapping from keys to colors is done using + insertMapping(). Typically this is used by having enums for the various kinds + of messages, which subsequently are registered. + + \code + enum MyMessage + { + Error, + Important + }; + + ColorOutput output; + output.insertMapping(Error, ColorOutput::RedForeground); + output.insertMapping(Import, ColorOutput::BlueForeground); + + output.write("This is important", Important); + output.write("Jack, I'm only the selected official!", Error); + \endcode + + \sa {http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html} {Bash Prompt HOWTO, 6.1. Colours} + {http://linuxgazette.net/issue51/livingston-blade.html} {Linux Gazette, Tweaking Eterm, Edward Livingston-Blade} + {http://www.ecma-international.org/publications/standards/Ecma-048.htm} {Standard ECMA-48, Control Functions for Coded Character Sets, ECMA International}, + {http://en.wikipedia.org/wiki/ANSI_escape_code} {Wikipedia, ANSI escape code} + {http://linuxgazette.net/issue65/padala.html} {Linux Gazette, So You Like Color!, Pradeep Padala} + */ + +/*! + \enum ColorOutput::ColorCode + + \value DefaultColor ColorOutput performs no coloring. This typically means black on white + or white on black, depending on the settings of the user's terminal. + */ + +/*! + Sets the color mapping to be \a cMapping. + + Negative values are disallowed. + + \sa colorMapping(), insertMapping() + */ +void ColorOutput::setColorMapping(const ColorMapping &cMapping) +{ + d->colorMapping = cMapping; +} + +/*! + Returns the color mappings in use. + + \sa setColorMapping(), insertMapping() + */ +ColorOutput::ColorMapping ColorOutput::colorMapping() const +{ + return d->colorMapping; +} + +/*! + Constructs a ColorOutput instance, ready for use. + */ +ColorOutput::ColorOutput() : d(new ColorOutputPrivate()) +{ +} + +/*! + Destructs this ColorOutput instance. + */ +ColorOutput::~ColorOutput() +{ + delete d; +} + +/*! + Sends \a message to \c stderr, using the color looked up in colorMapping() using \a colorID. + + If \a color isn't available in colorMapping(), result and behavior is undefined. + + If \a colorID is 0, which is the default value, the previously used coloring is used. ColorOutput + is initialized to not color at all. + + If \a message is empty, effects are undefined. + + \a message will be printed as is. For instance, no line endings will be inserted. + */ +void ColorOutput::write(const QString &message, int colorID) +{ + d->write(colorify(message, colorID)); +} + +/*! + Writes \a message to \c stderr as if for instance + QTextStream would have been used, and adds a line ending at the end. + + This function can be practical to use such that one can use ColorOutput for all forms of writing. + */ +void ColorOutput::writeUncolored(const QString &message) +{ + d->write(message + QLatin1Char('\n')); +} + +/*! + Treats \a message and \a colorID identically to write(), but instead of writing + \a message to \c stderr, it is prepared for being written to \c stderr, but is then + returned. + + This is useful when the colored string is inserted into a translated string(dividing + the string into several small strings prevents proper translation). + */ +QString ColorOutput::colorify(const QString &message, int colorID) const +{ + Q_ASSERT_X(colorID == -1 || d->colorMapping.contains(colorID), Q_FUNC_INFO, + qPrintable(QString::fromLatin1("There is no color registered by id %1").arg(colorID))); + Q_ASSERT_X(!message.isEmpty(), Q_FUNC_INFO, "It makes no sense to attempt to print an empty string."); + + if(colorID != -1) + d->currentColorID = colorID; + + if(d->coloringEnabled && colorID != -1) + { + const int color(d->colorMapping.value(colorID)); + + /* If DefaultColor is set, we don't want to color it. */ + if(color & DefaultColor) + return message; + + const int foregroundCode = (int(color) & ForegroundMask) >> ForegroundShift; + const int backgroundCode = (int(color) & BackgroundMask) >> BackgroundShift; + QString finalMessage; + bool closureNeeded = false; + + if(foregroundCode) + { + finalMessage.append(ColorOutputPrivate::escapeCode(QLatin1String(ColorOutputPrivate::foregrounds[foregroundCode - 1]))); + closureNeeded = true; + } + + if(backgroundCode) + { + finalMessage.append(ColorOutputPrivate::escapeCode(QLatin1String(ColorOutputPrivate::backgrounds[backgroundCode - 1]))); + closureNeeded = true; + } + + finalMessage.append(message); + + if(closureNeeded) + { + finalMessage.append(QChar(0x1B)); + finalMessage.append(QLatin1String("[0m")); + } + + return finalMessage; + } + else + return message; +} + +/*! + Adds a color mapping from \a colorID to \a colorCode, for this ColorOutput instance. + + This is a convenience function for creating a ColorOutput::ColorMapping instance and + calling setColorMapping(). + + \sa colorMapping(), setColorMapping() + */ +void ColorOutput::insertMapping(int colorID, const ColorCode colorCode) +{ + d->colorMapping.insert(colorID, colorCode); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/api/qcoloroutput_p.h b/src/xmlpatterns/api/qcoloroutput_p.h new file mode 100644 index 0000000..1917ec7 --- /dev/null +++ b/src/xmlpatterns/api/qcoloroutput_p.h @@ -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 XMLPatterns 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 purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ColorOutput_h +#define Patternist_ColorOutput_h + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + class ColorOutputPrivate; + + class ColorOutput + { + enum + { + ForegroundShift = 10, + BackgroundShift = 20, + SpecialShift = 20, + ForegroundMask = ((1 << ForegroundShift) - 1) << ForegroundShift, + BackgroundMask = ((1 << BackgroundShift) - 1) << BackgroundShift + }; + + public: + enum ColorCodeComponent + { + BlackForeground = 1 << ForegroundShift, + BlueForeground = 2 << ForegroundShift, + GreenForeground = 3 << ForegroundShift, + CyanForeground = 4 << ForegroundShift, + RedForeground = 5 << ForegroundShift, + PurpleForeground = 6 << ForegroundShift, + BrownForeground = 7 << ForegroundShift, + LightGrayForeground = 8 << ForegroundShift, + DarkGrayForeground = 9 << ForegroundShift, + LightBlueForeground = 10 << ForegroundShift, + LightGreenForeground = 11 << ForegroundShift, + LightCyanForeground = 12 << ForegroundShift, + LightRedForeground = 13 << ForegroundShift, + LightPurpleForeground = 14 << ForegroundShift, + YellowForeground = 15 << ForegroundShift, + WhiteForeground = 16 << ForegroundShift, + + BlackBackground = 1 << BackgroundShift, + BlueBackground = 2 << BackgroundShift, + GreenBackground = 3 << BackgroundShift, + CyanBackground = 4 << BackgroundShift, + RedBackground = 5 << BackgroundShift, + PurpleBackground = 6 << BackgroundShift, + BrownBackground = 7 << BackgroundShift, + DefaultColor = 1 << SpecialShift + }; + + typedef QFlags ColorCode; + typedef QHash ColorMapping; + + ColorOutput(); + ~ColorOutput(); + + void setColorMapping(const ColorMapping &cMapping); + ColorMapping colorMapping() const; + void insertMapping(int colorID, const ColorCode colorCode); + + void writeUncolored(const QString &message); + void write(const QString &message, int color = -1); + QString colorify(const QString &message, int color = -1) const; + + private: + ColorOutputPrivate *d; + Q_DISABLE_COPY(ColorOutput) + }; +} + +Q_DECLARE_OPERATORS_FOR_FLAGS(QPatternist::ColorOutput::ColorCode) + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/xmlpatterns.pro b/src/xmlpatterns/xmlpatterns.pro index 1df497d..a224762 100644 --- a/src/xmlpatterns/xmlpatterns.pro +++ b/src/xmlpatterns/xmlpatterns.pro @@ -1,15 +1,14 @@ -TARGET = QtXmlPatterns -QPRO_PWD = $$PWD -QT = core network -DEFINES += QT_BUILD_XMLPATTERNS_LIB QT_NO_USING_NAMESPACE +TARGET = QtXmlPatterns +QPRO_PWD = $$PWD +QT = core \ + network +DEFINES += QT_BUILD_XMLPATTERNS_LIB \ + QT_NO_USING_NAMESPACE win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x61000000 - -unix:QMAKE_PKGCONFIG_REQUIRES = QtCore QtNetwork - +unix:QMAKE_PKGCONFIG_REQUIRES = QtCore \ + QtNetwork include(../qbase.pri) - PRECOMPILED_HEADER = ../corelib/global/qt_pch.h - include($$PWD/common.pri) include($$PWD/acceltree/acceltree.pri) include($$PWD/api/api.pri) @@ -25,14 +24,13 @@ include($$PWD/schema/schema.pri) include($$PWD/type/type.pri) include($$PWD/utils/utils.pri) include($$PWD/qobjectmodel/qobjectmodel.pri, "", true) +wince*:# The Microsoft MIPS compiler crashes if /Og is specified +: -wince*: { - # The Microsoft MIPS compiler crashes if /Og is specified - # -O2/1 expands to /Og plus additional arguments. - contains(DEFINES, MIPS): { - QMAKE_CXXFLAGS_RELEASE ~= s/-O2/-Oi -Ot -Oy -Ob2/ - QMAKE_CXXFLAGS_RELEASE ~= s/-O1/-Os -Oy -Ob2/ - } +# -O2/1 expands to /Og plus additional arguments. +contains(DEFINES, MIPS): { + QMAKE_CXXFLAGS_RELEASE ~= s/-O2/-Oi -Ot -Oy -Ob2/ + QMAKE_CXXFLAGS_RELEASE ~= s/-O1/-Os -Oy -Ob2/ } - -symbian:TARGET.UID3=0x2001E62B +symbian:TARGET.UID3 = 0x2001E62B +HEADERS += diff --git a/tools/xmlpatterns/main.cpp b/tools/xmlpatterns/main.cpp index 604523b..76853b5 100644 --- a/tools/xmlpatterns/main.cpp +++ b/tools/xmlpatterns/main.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -58,7 +59,6 @@ #include "private/qautoptr_p.h" #include "qapplicationargument_p.h" #include "qapplicationargumentparser_p.h" -#include "qcoloringmessagehandler_p.h" #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) /* Needed for opening stdout with _fdopen & friends. io.h seems to not be diff --git a/tools/xmlpatterns/main.h b/tools/xmlpatterns/main.h index cdef999..76b7097 100644 --- a/tools/xmlpatterns/main.h +++ b/tools/xmlpatterns/main.h @@ -54,21 +54,13 @@ #include -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - class QXmlPatternistCLI { public: - Q_DECLARE_TR_FUNCTIONS(QXmlPatternistCLI) + Q_DECLARE_TR_FUNCTIONS(QXmlPatternistCLI) private: inline QXmlPatternistCLI(); Q_DISABLE_COPY(QXmlPatternistCLI) }; -QT_END_NAMESPACE - -QT_END_HEADER - #endif diff --git a/tools/xmlpatterns/qcoloringmessagehandler.cpp b/tools/xmlpatterns/qcoloringmessagehandler.cpp deleted file mode 100644 index a639ddd..0000000 --- a/tools/xmlpatterns/qcoloringmessagehandler.cpp +++ /dev/null @@ -1,199 +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 QtCore 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 "main.h" - -#include "qcoloringmessagehandler_p.h" - -QT_BEGIN_NAMESPACE - -using namespace QPatternist; - -ColoringMessageHandler::ColoringMessageHandler(QObject *parent) : QAbstractMessageHandler(parent) -{ - m_classToColor.insert(QLatin1String("XQuery-data"), Data); - m_classToColor.insert(QLatin1String("XQuery-expression"), Keyword); - m_classToColor.insert(QLatin1String("XQuery-function"), Keyword); - m_classToColor.insert(QLatin1String("XQuery-keyword"), Keyword); - m_classToColor.insert(QLatin1String("XQuery-type"), Keyword); - m_classToColor.insert(QLatin1String("XQuery-uri"), Data); - m_classToColor.insert(QLatin1String("XQuery-filepath"), Data); - - /* If you're tuning the colors, take it easy laddie. Take into account: - * - * - Get over your own taste, there's others too on this planet - * - Make sure it works well on black & white - * - Make sure it works well on white & black - */ - insertMapping(Location, CyanForeground); - insertMapping(ErrorCode, RedForeground); - insertMapping(Keyword, BlueForeground); - insertMapping(Data, BlueForeground); - insertMapping(RunningText, DefaultColor); -} - -void ColoringMessageHandler::handleMessage(QtMsgType type, - const QString &description, - const QUrl &identifier, - const QSourceLocation &sourceLocation) -{ - const bool hasLine = sourceLocation.line() != -1; - - switch(type) - { - case QtWarningMsg: - { - if(hasLine) - { - writeUncolored(QXmlPatternistCLI::tr("Warning in %1, at line %2, column %3: %4").arg(QString::fromLatin1(sourceLocation.uri().toEncoded()), - QString::number(sourceLocation.line()), - QString::number(sourceLocation.column()), - colorifyDescription(description))); - } - else - { - writeUncolored(QXmlPatternistCLI::tr("Warning in %1: %2").arg(QString::fromLatin1(sourceLocation.uri().toEncoded()), - colorifyDescription(description))); - } - - break; - } - case QtFatalMsg: - { - const QString errorCode(identifier.fragment()); - Q_ASSERT(!errorCode.isEmpty()); - QUrl uri(identifier); - uri.setFragment(QString()); - - QString location; - - if(sourceLocation.isNull()) - location = QXmlPatternistCLI::tr("Unknown location"); - else - location = QString::fromLatin1(sourceLocation.uri().toEncoded()); - - QString errorId; - /* If it's a standard error code, we don't want to output the - * whole URI. */ - if(uri.toString() == QLatin1String("http://www.w3.org/2005/xqt-errors")) - errorId = errorCode; - else - errorId = QString::fromLatin1(identifier.toEncoded()); - - if(hasLine) - { - writeUncolored(QXmlPatternistCLI::tr("Error %1 in %2, at line %3, column %4: %5").arg(colorify(errorId, ErrorCode), - colorify(location, Location), - colorify(QString::number(sourceLocation.line()), Location), - colorify(QString::number(sourceLocation.column()), Location), - colorifyDescription(description))); - } - else - { - writeUncolored(QXmlPatternistCLI::tr("Error %1 in %2: %3").arg(colorify(errorId, ErrorCode), - colorify(location, Location), - colorifyDescription(description))); - } - break; - } - case QtCriticalMsg: - /* Fallthrough. */ - case QtDebugMsg: - { - Q_ASSERT_X(false, Q_FUNC_INFO, - "message() is not supposed to receive QtCriticalMsg or QtDebugMsg."); - return; - } - } -} - -QString ColoringMessageHandler::colorifyDescription(const QString &in) const -{ - QXmlStreamReader reader(in); - QString result; - result.reserve(in.size()); - ColorType currentColor = RunningText; - - while(!reader.atEnd()) - { - reader.readNext(); - - switch(reader.tokenType()) - { - case QXmlStreamReader::StartElement: - { - if(reader.name() == QLatin1String("span")) - { - Q_ASSERT(m_classToColor.contains(reader.attributes().value(QLatin1String("class")).toString())); - currentColor = m_classToColor.value(reader.attributes().value(QLatin1String("class")).toString()); - } - - continue; - } - case QXmlStreamReader::Characters: - { - result.append(colorify(reader.text().toString(), currentColor)); - continue; - } - case QXmlStreamReader::EndElement: - { - currentColor = RunningText; - continue; - } - /* Fallthrough, */ - case QXmlStreamReader::StartDocument: - /* Fallthrough, */ - case QXmlStreamReader::EndDocument: - continue; - default: - Q_ASSERT_X(false, Q_FUNC_INFO, - "Unexpected node."); - } - } - - Q_ASSERT_X(!reader.hasError(), Q_FUNC_INFO, - "The output from Patternist must be well-formed."); - return result; -} - -QT_END_NAMESPACE diff --git a/tools/xmlpatterns/qcoloringmessagehandler_p.h b/tools/xmlpatterns/qcoloringmessagehandler_p.h deleted file mode 100644 index 3e8d18b..0000000 --- a/tools/xmlpatterns/qcoloringmessagehandler_p.h +++ /dev/null @@ -1,98 +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 XMLPatterns 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 purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. - -#ifndef Patternist_ColoringMessageHandler_h -#define Patternist_ColoringMessageHandler_h - -#include - -#include "qcoloroutput_p.h" -#include "qabstractmessagehandler.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -namespace QPatternist -{ - class ColoringMessageHandler : public QAbstractMessageHandler - , private ColorOutput - { - public: - ColoringMessageHandler(QObject *parent = 0); - - protected: - virtual void handleMessage(QtMsgType type, - const QString &description, - const QUrl &identifier, - const QSourceLocation &sourceLocation); - - private: - QString colorifyDescription(const QString &in) const; - - enum ColorType - { - RunningText, - Location, - ErrorCode, - Keyword, - Data - }; - - QHash m_classToColor; - }; -} - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/tools/xmlpatterns/qcoloroutput.cpp b/tools/xmlpatterns/qcoloroutput.cpp deleted file mode 100644 index 4f27fd5..0000000 --- a/tools/xmlpatterns/qcoloroutput.cpp +++ /dev/null @@ -1,348 +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 QtXmlPatterns 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 "qcoloroutput_p.h" - -// TODO: rename insertMapping() to insertColorMapping() -// TODO: Use a smart pointer for managing ColorOutputPrivate *d; -// TODO: break out the C++ example into a snippet file - -/* This include must appear here, because if it appears at the beginning of the file for - * instance, it breaks build -- "qglobal.h:628: error: template with - * C linkage" -- on Mac OS X 10.4. */ -#ifndef Q_OS_WIN -#include -#endif - -QT_BEGIN_NAMESPACE - -using namespace QPatternist; - -namespace QPatternist -{ - class ColorOutputPrivate - { - public: - ColorOutputPrivate() : currentColorID(-1) - - { - /* - QIODevice::Unbuffered because we want it to appear when the user actually calls, performance - * is considered of lower priority. - */ - m_out.open(stderr, QIODevice::WriteOnly | QIODevice::Unbuffered); - - coloringEnabled = isColoringPossible(); - } - - ColorOutput::ColorMapping colorMapping; - int currentColorID; - bool coloringEnabled; - - static const char *const foregrounds[]; - static const char *const backgrounds[]; - - inline void write(const QString &msg) - { - m_out.write(msg.toLocal8Bit()); - } - - static QString escapeCode(const QString &in) - { - QString result; - result.append(QChar(0x1B)); - result.append(QLatin1Char('[')); - result.append(in); - result.append(QLatin1Char('m')); - return result; - } - - private: - QFile m_out; - - /*! - Returns true if it's suitable to send colored output to \c stderr. - */ - inline bool isColoringPossible() const - { -# if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) - /* Windows doesn't at all support ANSI escape codes, unless - * the user install a "device driver". See the Wikipedia links in the - * class documentation for details. */ - return false; -# else - /* We use QFile::handle() to get the file descriptor. It's a bit unsure - * whether it's 2 on all platforms and in all cases, so hopefully this layer - * of abstraction helps handle such cases. */ - return isatty(m_out.handle()); -# endif - } - }; -} - -const char *const ColorOutputPrivate::foregrounds[] = -{ - "0;30", - "0;34", - "0;32", - "0;36", - "0;31", - "0;35", - "0;33", - "0;37", - "1;30", - "1;34", - "1;32", - "1;36", - "1;31", - "1;35", - "1;33", - "1;37" -}; - -const char *const ColorOutputPrivate::backgrounds[] = -{ - "0;40", - "0;44", - "0;42", - "0;46", - "0;41", - "0;45", - "0;43" -}; - -/*! - \since 4.4 - \nonreentrant - \brief Outputs colored messages to \c stderr. - \internal - - ColorOutput is a convenience class for outputting messages to \c stderr - using color escape codes, as mandated in ECMA-48. ColorOutput will only - color output when it is detected to be suitable. For instance, if \c stderr is - detected to be attached to a file instead of a TTY, no coloring will be done. - - ColorOutput does its best attempt. but it is generally undefined what coloring - or effect the various coloring flags has. It depends strongly on what terminal - software that is being used. - - When using `echo -e 'my escape sequence'`, \033 works as an initiator but not - when printing from a C++ program, despite having escaped the backslash. - That's why we below use characters with value 0x1B. - - It can be convenient to subclass ColorOutput with a private scope, such that the - functions are directly available in the class using it. - - \section1 Usage - - To output messages, call write() or writeUncolored(). write() takes as second - argument an integer, which ColorOutput uses as a lookup key to find the color - it should color the text in. The mapping from keys to colors is done using - insertMapping(). Typically this is used by having enums for the various kinds - of messages, which subsequently are registered. - - \code - enum MyMessage - { - Error, - Important - }; - - ColorOutput output; - output.insertMapping(Error, ColorOutput::RedForeground); - output.insertMapping(Import, ColorOutput::BlueForeground); - - output.write("This is important", Important); - output.write("Jack, I'm only the selected official!", Error); - \endcode - - \sa {http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html} {Bash Prompt HOWTO, 6.1. Colours} - {http://linuxgazette.net/issue51/livingston-blade.html} {Linux Gazette, Tweaking Eterm, Edward Livingston-Blade} - {http://www.ecma-international.org/publications/standards/Ecma-048.htm} {Standard ECMA-48, Control Functions for Coded Character Sets, ECMA International}, - {http://en.wikipedia.org/wiki/ANSI_escape_code} {Wikipedia, ANSI escape code} - {http://linuxgazette.net/issue65/padala.html} {Linux Gazette, So You Like Color!, Pradeep Padala} - */ - -/*! - \enum ColorOutput::ColorCode - - \value DefaultColor ColorOutput performs no coloring. This typically means black on white - or white on black, depending on the settings of the user's terminal. - */ - -/*! - Sets the color mapping to be \a cMapping. - - Negative values are disallowed. - - \sa colorMapping(), insertMapping() - */ -void ColorOutput::setColorMapping(const ColorMapping &cMapping) -{ - d->colorMapping = cMapping; -} - -/*! - Returns the color mappings in use. - - \sa setColorMapping(), insertMapping() - */ -ColorOutput::ColorMapping ColorOutput::colorMapping() const -{ - return d->colorMapping; -} - -/*! - Constructs a ColorOutput instance, ready for use. - */ -ColorOutput::ColorOutput() : d(new ColorOutputPrivate()) -{ -} - -/*! - Destructs this ColorOutput instance. - */ -ColorOutput::~ColorOutput() -{ - delete d; -} - -/*! - Sends \a message to \c stderr, using the color looked up in colorMapping() using \a colorID. - - If \a color isn't available in colorMapping(), result and behavior is undefined. - - If \a colorID is 0, which is the default value, the previously used coloring is used. ColorOutput - is initialized to not color at all. - - If \a message is empty, effects are undefined. - - \a message will be printed as is. For instance, no line endings will be inserted. - */ -void ColorOutput::write(const QString &message, int colorID) -{ - d->write(colorify(message, colorID)); -} - -/*! - Writes \a message to \c stderr as if for instance - QTextStream would have been used, and adds a line ending at the end. - - This function can be practical to use such that one can use ColorOutput for all forms of writing. - */ -void ColorOutput::writeUncolored(const QString &message) -{ - d->write(message + QLatin1Char('\n')); -} - -/*! - Treats \a message and \a colorID identically to write(), but instead of writing - \a message to \c stderr, it is prepared for being written to \c stderr, but is then - returned. - - This is useful when the colored string is inserted into a translated string(dividing - the string into several small strings prevents proper translation). - */ -QString ColorOutput::colorify(const QString &message, int colorID) const -{ - Q_ASSERT_X(colorID == -1 || d->colorMapping.contains(colorID), Q_FUNC_INFO, - qPrintable(QString::fromLatin1("There is no color registered by id %1").arg(colorID))); - Q_ASSERT_X(!message.isEmpty(), Q_FUNC_INFO, "It makes no sense to attempt to print an empty string."); - - if(colorID != -1) - d->currentColorID = colorID; - - if(d->coloringEnabled && colorID != -1) - { - const int color(d->colorMapping.value(colorID)); - - /* If DefaultColor is set, we don't want to color it. */ - if(color & DefaultColor) - return message; - - const int foregroundCode = (int(color) & ForegroundMask) >> ForegroundShift; - const int backgroundCode = (int(color) & BackgroundMask) >> BackgroundShift; - QString finalMessage; - bool closureNeeded = false; - - if(foregroundCode) - { - finalMessage.append(ColorOutputPrivate::escapeCode(QLatin1String(ColorOutputPrivate::foregrounds[foregroundCode - 1]))); - closureNeeded = true; - } - - if(backgroundCode) - { - finalMessage.append(ColorOutputPrivate::escapeCode(QLatin1String(ColorOutputPrivate::backgrounds[backgroundCode - 1]))); - closureNeeded = true; - } - - finalMessage.append(message); - - if(closureNeeded) - { - finalMessage.append(QChar(0x1B)); - finalMessage.append(QLatin1String("[0m")); - } - - return finalMessage; - } - else - return message; -} - -/*! - Adds a color mapping from \a colorID to \a colorCode, for this ColorOutput instance. - - This is a convenience function for creating a ColorOutput::ColorMapping instance and - calling setColorMapping(). - - \sa colorMapping(), setColorMapping() - */ -void ColorOutput::insertMapping(int colorID, const ColorCode colorCode) -{ - d->colorMapping.insert(colorID, colorCode); -} - -QT_END_NAMESPACE diff --git a/tools/xmlpatterns/qcoloroutput_p.h b/tools/xmlpatterns/qcoloroutput_p.h deleted file mode 100644 index 1917ec7..0000000 --- a/tools/xmlpatterns/qcoloroutput_p.h +++ /dev/null @@ -1,133 +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 XMLPatterns 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 purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. - -#ifndef Patternist_ColorOutput_h -#define Patternist_ColorOutput_h - -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -namespace QPatternist -{ - class ColorOutputPrivate; - - class ColorOutput - { - enum - { - ForegroundShift = 10, - BackgroundShift = 20, - SpecialShift = 20, - ForegroundMask = ((1 << ForegroundShift) - 1) << ForegroundShift, - BackgroundMask = ((1 << BackgroundShift) - 1) << BackgroundShift - }; - - public: - enum ColorCodeComponent - { - BlackForeground = 1 << ForegroundShift, - BlueForeground = 2 << ForegroundShift, - GreenForeground = 3 << ForegroundShift, - CyanForeground = 4 << ForegroundShift, - RedForeground = 5 << ForegroundShift, - PurpleForeground = 6 << ForegroundShift, - BrownForeground = 7 << ForegroundShift, - LightGrayForeground = 8 << ForegroundShift, - DarkGrayForeground = 9 << ForegroundShift, - LightBlueForeground = 10 << ForegroundShift, - LightGreenForeground = 11 << ForegroundShift, - LightCyanForeground = 12 << ForegroundShift, - LightRedForeground = 13 << ForegroundShift, - LightPurpleForeground = 14 << ForegroundShift, - YellowForeground = 15 << ForegroundShift, - WhiteForeground = 16 << ForegroundShift, - - BlackBackground = 1 << BackgroundShift, - BlueBackground = 2 << BackgroundShift, - GreenBackground = 3 << BackgroundShift, - CyanBackground = 4 << BackgroundShift, - RedBackground = 5 << BackgroundShift, - PurpleBackground = 6 << BackgroundShift, - BrownBackground = 7 << BackgroundShift, - DefaultColor = 1 << SpecialShift - }; - - typedef QFlags ColorCode; - typedef QHash ColorMapping; - - ColorOutput(); - ~ColorOutput(); - - void setColorMapping(const ColorMapping &cMapping); - ColorMapping colorMapping() const; - void insertMapping(int colorID, const ColorCode colorCode); - - void writeUncolored(const QString &message); - void write(const QString &message, int color = -1); - QString colorify(const QString &message, int color = -1) const; - - private: - ColorOutputPrivate *d; - Q_DISABLE_COPY(ColorOutput) - }; -} - -Q_DECLARE_OPERATORS_FOR_FLAGS(QPatternist::ColorOutput::ColorCode) - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/tools/xmlpatterns/xmlpatterns.pro b/tools/xmlpatterns/xmlpatterns.pro index 47f5a48..8cd321c 100644 --- a/tools/xmlpatterns/xmlpatterns.pro +++ b/tools/xmlpatterns/xmlpatterns.pro @@ -17,16 +17,12 @@ CONFIG -= app_bundle # in libQtXmlPatterns. See src/xmlpatterns/api/api.pri. SOURCES = main.cpp \ qapplicationargument.cpp \ - qapplicationargumentparser.cpp \ - qcoloringmessagehandler.cpp \ - qcoloroutput.cpp + qapplicationargumentparser.cpp HEADERS = main.h \ qapplicationargument.cpp \ - qapplicationargumentparser.cpp \ - qcoloringmessagehandler_p.h \ - qcoloroutput_p.h + qapplicationargumentparser.cpp symbian: TARGET.UID3 = 0xA000D7C9 -- cgit v0.12 From 19ce714373bbf405e199e421e55673f1b8326ea7 Mon Sep 17 00:00:00 2001 From: Aleksandar Sasha Babic Date: Mon, 21 Dec 2009 14:37:50 +0100 Subject: Fixing compile error on armcc armcc has issues with templated static inline functions, have to remove "static" keyword Reviewed-by: sroedal --- src/gui/image/qpixmapfilter.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp index caa0752..939b86d 100644 --- a/src/gui/image/qpixmapfilter.cpp +++ b/src/gui/image/qpixmapfilter.cpp @@ -602,7 +602,7 @@ QRectF QPixmapBlurFilter::boundingRectFor(const QRectF &rect) const } template -static inline int static_shift(int value) +inline int qt_static_shift(int value) { if (shift == 0) return value; @@ -613,15 +613,15 @@ static inline int static_shift(int value) } template -static inline void blurinner(uchar *bptr, int &zR, int &zG, int &zB, int &zA, int alpha) +inline void qt_blurinner(uchar *bptr, int &zR, int &zG, int &zB, int &zA, int alpha) { QRgb *pixel = (QRgb *)bptr; #define Z_MASK (0xff << zprec) - const int A_zprec = static_shift(*pixel) & Z_MASK; - const int R_zprec = static_shift(*pixel) & Z_MASK; - const int G_zprec = static_shift(*pixel) & Z_MASK; - const int B_zprec = static_shift(*pixel) & Z_MASK; + const int A_zprec = qt_static_shift(*pixel) & Z_MASK; + const int R_zprec = qt_static_shift(*pixel) & Z_MASK; + const int G_zprec = qt_static_shift(*pixel) & Z_MASK; + const int B_zprec = qt_static_shift(*pixel) & Z_MASK; #undef Z_MASK const int zR_zprec = zR >> aprec; @@ -636,17 +636,17 @@ static inline void blurinner(uchar *bptr, int &zR, int &zG, int &zB, int &zA, in #define ZA_MASK (0xff << (zprec + aprec)) *pixel = - static_shift<24 - zprec - aprec>(zA & ZA_MASK) - | static_shift<16 - zprec - aprec>(zR & ZA_MASK) - | static_shift<8 - zprec - aprec>(zG & ZA_MASK) - | static_shift<-zprec - aprec>(zB & ZA_MASK); + qt_static_shift<24 - zprec - aprec>(zA & ZA_MASK) + | qt_static_shift<16 - zprec - aprec>(zR & ZA_MASK) + | qt_static_shift<8 - zprec - aprec>(zG & ZA_MASK) + | qt_static_shift<-zprec - aprec>(zB & ZA_MASK); #undef ZA_MASK } const int alphaIndex = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3); template -static inline void blurinner_alphaOnly(uchar *bptr, int &z, int alpha) +inline void qt_blurinner_alphaOnly(uchar *bptr, int &z, int alpha) { const int A_zprec = int(*(bptr)) << zprec; const int z_zprec = z >> aprec; @@ -655,7 +655,7 @@ static inline void blurinner_alphaOnly(uchar *bptr, int &z, int alpha) } template -static inline void blurrow(QImage & im, int line, int alpha) +inline void qt_blurrow(QImage & im, int line, int alpha) { uchar *bptr = im.scanLine(line); @@ -668,9 +668,9 @@ static inline void blurrow(QImage & im, int line, int alpha) const int im_width = im.width(); for (int index = 0; index < im_width; ++index) { if (alphaOnly) - blurinner_alphaOnly(bptr, zA, alpha); + qt_blurinner_alphaOnly(bptr, zA, alpha); else - blurinner(bptr, zR, zG, zB, zA, alpha); + qt_blurinner(bptr, zR, zG, zB, zA, alpha); bptr += stride; } @@ -679,9 +679,9 @@ static inline void blurrow(QImage & im, int line, int alpha) for (int index = im_width - 2; index >= 0; --index) { bptr -= stride; if (alphaOnly) - blurinner_alphaOnly(bptr, zA, alpha); + qt_blurinner_alphaOnly(bptr, zA, alpha); else - blurinner(bptr, zR, zG, zB, zA, alpha); + qt_blurinner(bptr, zR, zG, zB, zA, alpha); } } @@ -723,7 +723,7 @@ void expblur(QImage &img, qreal radius, bool improvedQuality = false, int transp int img_height = img.height(); for (int row = 0; row < img_height; ++row) { for (int i = 0; i <= improvedQuality; ++i) - blurrow(img, row, alpha); + qt_blurrow(img, row, alpha); } QImage temp(img.height(), img.width(), img.format()); @@ -756,7 +756,7 @@ void expblur(QImage &img, qreal radius, bool improvedQuality = false, int transp img_height = temp.height(); for (int row = 0; row < img_height; ++row) { for (int i = 0; i <= improvedQuality; ++i) - blurrow(temp, row, alpha); + qt_blurrow(temp, row, alpha); } if (transposed == 0) { -- cgit v0.12 From ddf34f39efcbe679f1a8216df58da0c61e98ec79 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 21 Dec 2009 14:30:40 +0100 Subject: update harfbuzz to 2b78f0d78ad3075fd1657d1260b31219e1a5155 Fix a regression in Hebrew text rendering that got introduced in Harfbuzz. Fix some uninitialized variables. Task-number: http://bugreports.qt.nokia.com/browse/QTBUG-6436 Reviewed-by: Simon Hausmann --- src/3rdparty/harfbuzz/src/harfbuzz-hebrew.c | 4 +--- src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp | 3 +++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-hebrew.c b/src/3rdparty/harfbuzz/src/harfbuzz-hebrew.c index 2bda386..67029be 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-hebrew.c +++ b/src/3rdparty/harfbuzz/src/harfbuzz-hebrew.c @@ -56,8 +56,6 @@ HB_Bool HB_HebrewShape(HB_ShaperItem *shaper_item) assert(shaper_item->item.script == HB_Script_Hebrew); - HB_HeuristicSetGlyphAttributes(shaper_item); - #ifndef NO_OPENTYPE if (HB_SelectScript(shaper_item, hebrew_features)) { @@ -65,7 +63,7 @@ HB_Bool HB_HebrewShape(HB_ShaperItem *shaper_item) if (!HB_ConvertStringToGlyphIndices(shaper_item)) return FALSE; - + HB_HeuristicSetGlyphAttributes(shaper_item); HB_OpenTypeShape(shaper_item, /*properties*/0); return HB_OpenTypePosition(shaper_item, availableGlyphs, /*doLogClusters*/TRUE); } diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp index bfb03ab..bfc7bd4 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp +++ b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp @@ -980,6 +980,7 @@ HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc) HB_Stream gdefStream; gdefStream = getTableStream(font, tableFunc, TTAG_GDEF); + error = HB_Err_Not_Covered; if (!gdefStream || (error = HB_Load_GDEF_Table(gdefStream, &face->gdef))) { //DEBUG("error loading gdef table: %d", error); face->gdef = 0; @@ -987,6 +988,7 @@ HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc) //DEBUG() << "trying to load gsub table"; stream = getTableStream(font, tableFunc, TTAG_GSUB); + error = HB_Err_Not_Covered; if (!stream || (error = HB_Load_GSUB_Table(stream, &face->gsub, face->gdef, gdefStream))) { face->gsub = 0; if (error != HB_Err_Not_Covered) { @@ -998,6 +1000,7 @@ HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc) _hb_close_stream(stream); stream = getTableStream(font, tableFunc, TTAG_GPOS); + error = HB_Err_Not_Covered; if (!stream || (error = HB_Load_GPOS_Table(stream, &face->gpos, face->gdef, gdefStream))) { face->gpos = 0; DEBUG("error loading gpos table: %d", error); -- cgit v0.12 From 032036bfb3e69c41b9a3c557d4c9322d55154e25 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 21 Dec 2009 14:58:28 +0100 Subject: Warn when calling QFileInfo::absolutePath() on an improper object. Merge-request: 1821 Reviewed-by: Simon Hausmann Reviewed-by: Olivier Goffart --- src/corelib/io/qfileinfo.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 61081a1..0a435b9 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -573,6 +573,8 @@ QString QFileInfo::canonicalFilePath() const QString QFileInfo::absolutePath() const { Q_D(const QFileInfo); + if (d->data->fileName.isEmpty()) + qWarning("QFileInfo::absolutePath: Constructed with empty filename"); if(!d->data->fileEngine) return QLatin1String(""); return d->getFileName(QAbstractFileEngine::AbsolutePathName); -- cgit v0.12 From a0f557d8576b233ba0c5417ff020a5aa438c4805 Mon Sep 17 00:00:00 2001 From: Carlos Manuel Duclos Vergara Date: Mon, 21 Dec 2009 15:17:10 +0100 Subject: Adding missing file. Reviewed-by: Peter Hartmann --- src/xmlpatterns/api/qxmlpatternistcli_p.h | 74 +++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/xmlpatterns/api/qxmlpatternistcli_p.h diff --git a/src/xmlpatterns/api/qxmlpatternistcli_p.h b/src/xmlpatterns/api/qxmlpatternistcli_p.h new file mode 100644 index 0000000..072e4aa --- /dev/null +++ b/src/xmlpatterns/api/qxmlpatternistcli_p.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** 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 XMLPatterns 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 purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_Cli_h +#define Patternist_Cli_h + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QXmlPatternistCLI +{ +public: + Q_DECLARE_TR_FUNCTIONS(QXmlPatternistCLI) +private: + inline QXmlPatternistCLI(); + Q_DISABLE_COPY(QXmlPatternistCLI) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif -- cgit v0.12 From 4d20d1f9a307b8c3b032fd548bdfd077a91440f3 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 18 Dec 2009 15:59:30 +0000 Subject: Fixes to winscw def files Reviewed-by: TrustMe --- src/s60installs/bwins/QtGuiu.def | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index d50e85f..7a629d7 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -2503,7 +2503,7 @@ EXPORTS ?cacheMode@QMovie@@QAE?AW4CacheMode@1@XZ @ 2502 NONAME ; enum QMovie::CacheMode QMovie::cacheMode(void) ?cacheMode@QMovie@@QBE?AW4CacheMode@1@XZ @ 2503 NONAME ; enum QMovie::CacheMode QMovie::cacheMode(void) const ?cacheStatistics@QFont@@SAXXZ @ 2504 NONAME ; void QFont::cacheStatistics(void) - ?cacheType@QTextureGlyphCache@@QBE?AW4Type@QFontEngineGlyphCache@@XZ @ 2505 NONAME ; enum QFontEngineGlyphCache::Type QTextureGlyphCache::cacheType(void) const + ?cacheType@QTextureGlyphCache@@QBE?AW4Type@QFontEngineGlyphCache@@XZ @ 2505 NONAME ABSENT ; enum QFontEngineGlyphCache::Type QTextureGlyphCache::cacheType(void) const ?calcEffectiveOpacity@QGraphicsItemPrivate@@QBEMXZ @ 2506 NONAME ; float QGraphicsItemPrivate::calcEffectiveOpacity(void) const ?calculateTabWidth@QTextEngine@@QBE?AUQFixed@@HU2@@Z @ 2507 NONAME ; struct QFixed QTextEngine::calculateTabWidth(int, struct QFixed) const ?calendarPopup@QDateTimeEdit@@QBE_NXZ @ 2508 NONAME ; bool QDateTimeEdit::calendarPopup(void) const @@ -4299,7 +4299,7 @@ EXPORTS ?expandingDirections@QSpacerItem@@UBE?AV?$QFlags@W4Orientation@Qt@@@@XZ @ 4298 NONAME ; class QFlags QSpacerItem::expandingDirections(void) const ?expandingDirections@QWidgetItem@@UBE?AV?$QFlags@W4Orientation@Qt@@@@XZ @ 4299 NONAME ; class QFlags QWidgetItem::expandingDirections(void) const ?expandsOnDoubleClick@QTreeView@@QBE_NXZ @ 4300 NONAME ; bool QTreeView::expandsOnDoubleClick(void) const - ?expireGlyphCache@QFontEngine@@AAEXXZ @ 4301 NONAME ; void QFontEngine::expireGlyphCache(void) + ?expireGlyphCache@QFontEngine@@AAEXXZ @ 4301 NONAME ABSENT ; void QFontEngine::expireGlyphCache(void) ?extension@QDialog@@QBEPAVQWidget@@XZ @ 4302 NONAME ; class QWidget * QDialog::extension(void) const ?extension@QGraphicsEllipseItem@@MBE?AVQVariant@@ABV2@@Z @ 4303 NONAME ; class QVariant QGraphicsEllipseItem::extension(class QVariant const &) const ?extension@QGraphicsItem@@MBE?AVQVariant@@ABV2@@Z @ 4304 NONAME ; class QVariant QGraphicsItem::extension(class QVariant const &) const @@ -4933,8 +4933,8 @@ EXPORTS ?globalY@QMouseEvent@@QBEHXZ @ 4932 NONAME ; int QMouseEvent::globalY(void) const ?globalY@QTabletEvent@@QBEHXZ @ 4933 NONAME ; int QTabletEvent::globalY(void) const ?globalY@QWheelEvent@@QBEHXZ @ 4934 NONAME ; int QWheelEvent::globalY(void) const - ?glyphCache@QFontEngine@@QBEPAVQFontEngineGlyphCache@@PAXABVQTransform@@@Z @ 4935 NONAME ; class QFontEngineGlyphCache * QFontEngine::glyphCache(void *, class QTransform const &) const - ?glyphCache@QFontEngine@@QBEPAVQFontEngineGlyphCache@@W4Type@2@ABVQTransform@@@Z @ 4936 NONAME ; class QFontEngineGlyphCache * QFontEngine::glyphCache(enum QFontEngineGlyphCache::Type, class QTransform const &) const + ?glyphCache@QFontEngine@@QBEPAVQFontEngineGlyphCache@@PAXABVQTransform@@@Z @ 4935 NONAME ABSENT ; class QFontEngineGlyphCache * QFontEngine::glyphCache(void *, class QTransform const &) const + ?glyphCache@QFontEngine@@QBEPAVQFontEngineGlyphCache@@W4Type@2@ABVQTransform@@@Z @ 4936 NONAME ABSENT ; class QFontEngineGlyphCache * QFontEngine::glyphCache(enum QFontEngineGlyphCache::Type, class QTransform const &) const ?glyphCount@QFontEngine@@UBEHXZ @ 4937 NONAME ; int QFontEngine::glyphCount(void) const ?glyphMargin@QTextureGlyphCache@@UBEHXZ @ 4938 NONAME ; int QTextureGlyphCache::glyphMargin(void) const ?gotFocus@QFocusEvent@@QBE_NXZ @ 4939 NONAME ; bool QFocusEvent::gotFocus(void) const @@ -9103,7 +9103,7 @@ EXPORTS ?setGestureCancelPolicy@QGesture@@QAEXW4GestureCancelPolicy@1@@Z @ 9102 NONAME ; void QGesture::setGestureCancelPolicy(enum QGesture::GestureCancelPolicy) ?setGlobalStrut@QApplication@@SAXABVQSize@@@Z @ 9103 NONAME ; void QApplication::setGlobalStrut(class QSize const &) ?setGlyphCache@QFontEngine@@QAEXPAXPAVQFontEngineGlyphCache@@@Z @ 9104 NONAME ; void QFontEngine::setGlyphCache(void *, class QFontEngineGlyphCache *) - ?setGlyphCache@QFontEngine@@QAEXW4Type@QFontEngineGlyphCache@@PAV3@@Z @ 9105 NONAME ; void QFontEngine::setGlyphCache(enum QFontEngineGlyphCache::Type, class QFontEngineGlyphCache *) + ?setGlyphCache@QFontEngine@@QAEXW4Type@QFontEngineGlyphCache@@PAV3@@Z @ 9105 NONAME ABSENT ; void QFontEngine::setGlyphCache(enum QFontEngineGlyphCache::Type, class QFontEngineGlyphCache *) ?setGraphicsEffect@QGraphicsItem@@QAEXPAVQGraphicsEffect@@@Z @ 9106 NONAME ; void QGraphicsItem::setGraphicsEffect(class QGraphicsEffect *) ?setGraphicsEffect@QWidget@@QAEXPAVQGraphicsEffect@@@Z @ 9107 NONAME ; void QWidget::setGraphicsEffect(class QGraphicsEffect *) ?setGraphicsEffectSource@QGraphicsEffectPrivate@@QAEXPAVQGraphicsEffectSource@@@Z @ 9108 NONAME ; void QGraphicsEffectPrivate::setGraphicsEffectSource(class QGraphicsEffectSource *) @@ -12522,4 +12522,7 @@ EXPORTS ?addCacheData@QVectorPath@@QBEPAUCacheEntry@1@PAVQPaintEngineEx@@PAXP6AX01@Z@Z @ 12521 NONAME ; struct QVectorPath::CacheEntry * QVectorPath::addCacheData(class QPaintEngineEx *, void *, void (*)(class QPaintEngineEx *, void *)) const ?discardUpdateRequest@QGraphicsItemPrivate@@QBE_N_N00@Z @ 12522 NONAME ; bool QGraphicsItemPrivate::discardUpdateRequest(bool, bool, bool) const ?makeCacheable@QVectorPath@@QBEXXZ @ 12523 NONAME ; void QVectorPath::makeCacheable(void) const + ??0Tab@QTextOption@@QAE@ABU01@@Z @ 12524 NONAME ; QTextOption::Tab::Tab(struct QTextOption::Tab const &) + ?effectiveBoundingRect@QGraphicsItemPrivate@@QBE?AVQRectF@@ABV2@@Z @ 12525 NONAME ; class QRectF QGraphicsItemPrivate::effectiveBoundingRect(class QRectF const &) const + ?glyphCache@QFontEngine@@QBEPAVQFontEngineGlyphCache@@PAXW4Type@2@ABVQTransform@@@Z @ 12526 NONAME ; class QFontEngineGlyphCache * QFontEngine::glyphCache(void *, enum QFontEngineGlyphCache::Type, class QTransform const &) const -- cgit v0.12 From f61a32948da3cac4b83123267ae8c5d2fa0525f6 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 18 Dec 2009 17:24:56 +0000 Subject: Tool for launching symbian apps on the phone from windows command line The tool uses TRK to launch the application. TRK is a debug agent, available as a signed package for consumer phones. For Nokia phones, it is distributed with carbide; for other manufacturers it can be downloaded from their developer websites. The launcher code is reused from Qt creator, with a patch to allow us to pass command line arguments to the process being launched. The "make run" target is enhanced to support running on target as well as the emulator. Like the "make sis" target, the last platform to have been built is the one that will be launched. The runonphone tool needs to be built in a Qt environment configured for windows, and requires at least windows XP (Symbian development requires windows XP SP2). Current proposal is to include a statically linked exe in the bin directory for binary packages. Reviewed-by: Janne Koskinen --- qmake/generators/symbian/symmake.cpp | 19 + qmake/generators/symbian/symmake.h | 1 + qmake/generators/symbian/symmake_abld.cpp | 6 +- qmake/generators/symbian/symmake_sbsv2.cpp | 6 +- tools/runonphone/main.cpp | 158 ++++ tools/runonphone/runonphone.pro | 19 + tools/runonphone/serenum.h | 43 + tools/runonphone/serenum_win.cpp | 101 +++ tools/runonphone/trk/bluetoothlistener.cpp | 212 +++++ tools/runonphone/trk/bluetoothlistener.h | 89 ++ tools/runonphone/trk/bluetoothlistener_gui.cpp | 99 +++ tools/runonphone/trk/bluetoothlistener_gui.h | 75 ++ tools/runonphone/trk/callback.h | 148 ++++ tools/runonphone/trk/communicationstarter.cpp | 248 ++++++ tools/runonphone/trk/communicationstarter.h | 148 ++++ tools/runonphone/trk/launcher.cpp | 683 +++++++++++++++ tools/runonphone/trk/launcher.h | 155 ++++ tools/runonphone/trk/trk.pri | 23 + tools/runonphone/trk/trkdevice.cpp | 1061 ++++++++++++++++++++++++ tools/runonphone/trk/trkdevice.h | 121 +++ tools/runonphone/trk/trkutils.cpp | 474 +++++++++++ tools/runonphone/trk/trkutils.h | 177 ++++ tools/runonphone/trksignalhandler.cpp | 108 +++ tools/runonphone/trksignalhandler.h | 55 ++ 24 files changed, 4219 insertions(+), 10 deletions(-) create mode 100644 tools/runonphone/main.cpp create mode 100644 tools/runonphone/runonphone.pro create mode 100644 tools/runonphone/serenum.h create mode 100644 tools/runonphone/serenum_win.cpp create mode 100644 tools/runonphone/trk/bluetoothlistener.cpp create mode 100644 tools/runonphone/trk/bluetoothlistener.h create mode 100644 tools/runonphone/trk/bluetoothlistener_gui.cpp create mode 100644 tools/runonphone/trk/bluetoothlistener_gui.h create mode 100644 tools/runonphone/trk/callback.h create mode 100644 tools/runonphone/trk/communicationstarter.cpp create mode 100644 tools/runonphone/trk/communicationstarter.h create mode 100644 tools/runonphone/trk/launcher.cpp create mode 100644 tools/runonphone/trk/launcher.h create mode 100644 tools/runonphone/trk/trk.pri create mode 100644 tools/runonphone/trk/trkdevice.cpp create mode 100644 tools/runonphone/trk/trkdevice.h create mode 100644 tools/runonphone/trk/trkutils.cpp create mode 100644 tools/runonphone/trk/trkutils.h create mode 100644 tools/runonphone/trksignalhandler.cpp create mode 100644 tools/runonphone/trksignalhandler.h diff --git a/qmake/generators/symbian/symmake.cpp b/qmake/generators/symbian/symmake.cpp index 8379ed9..14177b5 100644 --- a/qmake/generators/symbian/symmake.cpp +++ b/qmake/generators/symbian/symmake.cpp @@ -1852,3 +1852,22 @@ void SymbianMakefileGenerator::generateDistcleanTargets(QTextStream& t) t << "distclean: clean dodistclean" << endl; t << endl; } + +void SymbianMakefileGenerator::generateExecutionTargets(QTextStream& t, const QStringList& platforms) +{ + // create execution targets + if (targetType == TypeExe) { + if (platforms.contains("winscw")) { + t << "ifeq (\"DEBUG-winscw\", \"$(QT_SIS_TARGET)\")" << endl; + t << "run:" << endl; + t << "\t-call " << epocRoot() << "epoc32/release/winscw/udeb/" << fixedTarget << ".exe " << "$(QT_RUN_OPTIONS)" << endl; + t << "else" << endl; + } + t << "run: sis" << endl; + t << "\trunonphone --sis " << fixedTarget << "_$(QT_SIS_TARGET).sis " << fixedTarget << ".exe " << "$(QT_RUN_OPTIONS)" << endl; + if (platforms.contains("winscw")) { + t << "endif" << endl; + } + t << endl; + } +} diff --git a/qmake/generators/symbian/symmake.h b/qmake/generators/symbian/symmake.h index 1a20e64..6949842 100644 --- a/qmake/generators/symbian/symmake.h +++ b/qmake/generators/symbian/symmake.h @@ -148,6 +148,7 @@ protected: void writeSisTargets(QTextStream &t); void generateDistcleanTargets(QTextStream& t); + void generateExecutionTargets(QTextStream& t, const QStringList& platforms); // Subclass implements virtual void writeBldInfExtensionRulesPart(QTextStream& t, const QString &iconTargetFile) = 0; diff --git a/qmake/generators/symbian/symmake_abld.cpp b/qmake/generators/symbian/symmake_abld.cpp index f2baf46..4ecaae3 100644 --- a/qmake/generators/symbian/symmake_abld.cpp +++ b/qmake/generators/symbian/symmake_abld.cpp @@ -372,11 +372,7 @@ void SymbianAbldMakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, bool t << "\t-bldmake clean" << endl; t << endl; - // Create execution target - if (debugPlatforms.contains("winscw") && targetType == TypeExe) { - t << "run:" << endl; - t << "\t-call " << epocRoot() << "epoc32\\release\\winscw\\udeb\\" << fixedTarget << ".exe" << endl << endl; - } + generateExecutionTargets(t, debugPlatforms); } void SymbianAbldMakefileGenerator::writeBldInfExtensionRulesPart(QTextStream& t, const QString &iconTargetFile) diff --git a/qmake/generators/symbian/symmake_sbsv2.cpp b/qmake/generators/symbian/symmake_sbsv2.cpp index ad22cfd..5f5c5c4 100644 --- a/qmake/generators/symbian/symmake_sbsv2.cpp +++ b/qmake/generators/symbian/symmake_sbsv2.cpp @@ -231,11 +231,7 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo t << "\t-$(SBS) reallyclean" << endl; t << endl; - // create execution target - if (debugPlatforms.contains("winscw") && targetType == TypeExe) { - t << "run:" << endl; - t << "\t-call " << epocRoot() << "epoc32/release/winscw/udeb/" << fixedTarget << ".exe" << endl << endl; - } + generateExecutionTargets(t, debugPlatforms); } void SymbianSbsv2MakefileGenerator::writeBldInfExtensionRulesPart(QTextStream& t, const QString &iconTargetFile) diff --git a/tools/runonphone/main.cpp b/tools/runonphone/main.cpp new file mode 100644 index 0000000..8404906 --- /dev/null +++ b/tools/runonphone/main.cpp @@ -0,0 +1,158 @@ +/************************************************************************** +** +** This file is part of the tools applications of the Qt Toolkit. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ +#include +#include +#include +#include +#include "trkutils.h" +#include "trkdevice.h" +#include "launcher.h" + +#include "trksignalhandler.h" +#include "serenum.h" + +void printUsage() +{ + qDebug() << "runtest [options] [program arguments]" << endl + << "-s, --sis specify sis file to install" << endl + << "-p, --portname specify COM port to use by device name" << endl + << "-f, --portfriendlyname specify COM port to use by friendly name" << endl + << endl + << "USB COM ports can usually be autodetected" << endl; +} + +int main(int argc, char *argv[]) +{ + QCoreApplication a(argc, argv); + + QString serialPortName; + QString serialPortFriendlyName; + QString sisFile; + QString exeFile; + QString cmdLine; + QStringList args = QCoreApplication::arguments(); + for (int i=1;i ports = enumerateSerialPorts(); + foreach(SerialPortId id, ports) { + qDebug() << "Port Name: " << id.portName << ", " + << "Friendly Name:" << id.friendlyName << endl; + if(serialPortName.isEmpty()) { + if(id.friendlyName.isEmpty() && + (id.friendlyName.contains("symbian", Qt::CaseInsensitive) || + id.friendlyName.contains("s60", Qt::CaseInsensitive) || + id.friendlyName.contains("nokia", Qt::CaseInsensitive))) + serialPortName = id.portName; + else if (!id.friendlyName.isEmpty() && + id.friendlyName.contains(serialPortFriendlyName)) + serialPortName = id.portName; + } + } + } + + QScopedPointer launcher; + + if(sisFile.isEmpty()) { + launcher.reset(new trk::Launcher(trk::Launcher::ActionCopyRun)); + launcher->setCopyFileName(exeFile, QString("c:\\sys\\bin\\") + exeFile); + qDebug() << "System TRK required to copy EXE, use --sis if using Application TRK" << endl; + } else { + launcher.reset(new trk::Launcher(trk::Launcher::ActionCopyInstallRun)); + launcher->addStartupActions(trk::Launcher::ActionInstall); + launcher->setCopyFileName(sisFile, "c:\\data\\testtemp.sis"); + launcher->setInstallFileName("c:\\data\\testtemp.sis"); + } + qDebug() << "Connecting to target via " << serialPortName << endl; + launcher->setTrkServerName(QString("\\\\.\\") + serialPortName); + + launcher->setFileName(QString("c:\\sys\\bin\\") + exeFile); + launcher->setCommandLineArgs(cmdLine); + + TrkSignalHandler handler; + + QObject::connect(launcher.data(), SIGNAL(copyingStarted()), &handler, SLOT(copyingStarted())); + QObject::connect(launcher.data(), SIGNAL(canNotConnect(const QString &)), &handler, SLOT(canNotConnect(const QString &))); + QObject::connect(launcher.data(), SIGNAL(canNotCreateFile(const QString &, const QString &)), &handler, SLOT(canNotCreateFile(const QString &, const QString &))); + QObject::connect(launcher.data(), SIGNAL(canNotWriteFile(const QString &, const QString &)), &handler, SLOT(canNotWriteFile(const QString &, const QString &))); + QObject::connect(launcher.data(), SIGNAL(canNotCloseFile(const QString &, const QString &)), &handler, SLOT(canNotCloseFile(const QString &, const QString &))); + QObject::connect(launcher.data(), SIGNAL(installingStarted()), &handler, SLOT(installingStarted())); + QObject::connect(launcher.data(), SIGNAL(canNotInstall(const QString &, const QString &)), &handler, SLOT(canNotInstall(const QString &, const QString &))); + QObject::connect(launcher.data(), SIGNAL(installingFinished()), &handler, SLOT(installingFinished())); + QObject::connect(launcher.data(), SIGNAL(startingApplication()), &handler, SLOT(startingApplication())); + QObject::connect(launcher.data(), SIGNAL(applicationRunning(uint)), &handler, SLOT(applicationRunning(uint))); + QObject::connect(launcher.data(), SIGNAL(canNotRun(const QString &)), &handler, SLOT(canNotRun(const QString &))); + QObject::connect(launcher.data(), SIGNAL(applicationOutputReceived(const QString &)), &handler, SLOT(applicationOutputReceived(const QString &))); + QObject::connect(launcher.data(), SIGNAL(copyProgress(int)), &handler, SLOT(copyProgress(int))); + QObject::connect(launcher.data(), SIGNAL(stateChanged(int)), &handler, SLOT(stateChanged(int))); + QObject::connect(launcher.data(), SIGNAL(finished()), &handler, SLOT(finished())); + + QString errorMessage; + if(!launcher->startServer(&errorMessage)) { + qWarning() << errorMessage; + return 1; + } + + return a.exec(); +} + diff --git a/tools/runonphone/runonphone.pro b/tools/runonphone/runonphone.pro new file mode 100644 index 0000000..d243121 --- /dev/null +++ b/tools/runonphone/runonphone.pro @@ -0,0 +1,19 @@ +TEMPLATE = app + +QT -= gui +CONFIG += console +CONFIG -= app_bundle + +include(trk/trk.pri) + +SOURCES += main.cpp \ + trksignalhandler.cpp + +HEADERS += trksignalhandler.h \ + serenum.h + +windows { + SOURCES += serenum_win.cpp + LIBS += -lsetupapi \ + -luuid +} diff --git a/tools/runonphone/serenum.h b/tools/runonphone/serenum.h new file mode 100644 index 0000000..a0c810c --- /dev/null +++ b/tools/runonphone/serenum.h @@ -0,0 +1,43 @@ +/************************************************************************** +** +** This file is part of the tools applications of the Qt Toolkit. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ +#ifndef WIN32SERENUM_H +#define WIN32SERENUM_H + +#include +#include + +struct SerialPortId +{ + QString portName; + QString friendlyName; +}; + +QList enumerateSerialPorts(); + +#endif // WIN32SERENUM_H diff --git a/tools/runonphone/serenum_win.cpp b/tools/runonphone/serenum_win.cpp new file mode 100644 index 0000000..1cf5789 --- /dev/null +++ b/tools/runonphone/serenum_win.cpp @@ -0,0 +1,101 @@ +/************************************************************************** +** +** This file is part of the tools applications of the Qt Toolkit. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ +#include "serenum.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//{4d36e978-e325-11ce-bfc1-08002be10318} +//DEFINE_GUID(GUID_DEVCLASS_PORTS, 0x4D36E978, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 ); + +QList enumerateSerialPorts() +{ + DWORD index=0; + SP_DEVINFO_DATA info; + GUID guid = GUID_DEVCLASS_PORTS; + HDEVINFO infoset = SetupDiGetClassDevs(&guid, 0, 0, DIGCF_PRESENT); + QString valueName(16384, 0); + QList list; + + for (index=0;;index++) { + ZeroMemory(&info, sizeof(SP_DEVINFO_DATA)); + info.cbSize = sizeof(SP_DEVINFO_DATA); + if (!SetupDiEnumDeviceInfo(infoset, index, &info)) + break; + QString friendlyName; + QString portName; + DWORD size=0; + SetupDiGetDeviceRegistryProperty(infoset, &info, SPDRP_FRIENDLYNAME, 0, 0, 0, &size); + QByteArray ba(size, 0); + if(SetupDiGetDeviceRegistryProperty(infoset, &info, SPDRP_FRIENDLYNAME, 0, (BYTE*)(ba.data()), size, 0)) { + friendlyName = QString((const QChar*)(ba.constData()), ba.size() / 2 - 1); + } + HKEY key = SetupDiOpenDevRegKey(infoset, &info, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); + if(key != INVALID_HANDLE_VALUE) { +#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600 + //RegGetValue not supported on XP, SHRegGetValue not supported by mingw :( + for (DWORD dwi=0;;dwi++) { + DWORD vsize = valueName.size(); + if (ERROR_SUCCESS == RegEnumValue(key, dwi, (WCHAR*)(valueName.data()), &vsize, 0, 0, 0, &size)) { + if (valueName.startsWith("PortName")) { + QByteArray ba(size, 0); + vsize = valueName.size(); + if(ERROR_SUCCESS == RegEnumValue(key, dwi, (WCHAR*)(valueName.data()), &vsize, 0, 0, (BYTE*)(ba.data()), &size)) { + portName = QString((const QChar*)(ba.constData()), ba.size() / 2 - 1); + } + } + } else { + break; + } + } +#else + if (ERROR_SUCCESS == SHRegGetValue(key, 0, "PortName", SRRF_RT_REG_SZ, 0, &size)) { + QByteArray ba(size, 0); + if (ERROR_SUCCESS == RegGetValue(key, 0, "PortName", SRRF_RT_REG_SZ, (BYTE*)(ba.data()), &size)) { + portName = QString((const QChar*)(ba.constData()), ba.size() / 2 - 1); + } + } +#endif + RegCloseKey(key); + } + SerialPortId id; + id.portName = portName; + id.friendlyName = friendlyName; + list.append(id); + } + SetupDiDestroyDeviceInfoList(infoset); + return list; +} + diff --git a/tools/runonphone/trk/bluetoothlistener.cpp b/tools/runonphone/trk/bluetoothlistener.cpp new file mode 100644 index 0000000..1f5ccbe --- /dev/null +++ b/tools/runonphone/trk/bluetoothlistener.cpp @@ -0,0 +1,212 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "bluetoothlistener.h" +#include "trkdevice.h" + +#include + +#ifdef Q_OS_UNIX +# include +# include +#else +# include +#endif + +// Process id helpers. +#ifdef Q_OS_WIN +inline DWORD processId(const QProcess &p) +{ + if (const Q_PID processInfoStruct = p.pid()) + return processInfoStruct->dwProcessId; + return 0; +} +#else +inline Q_PID processId(const QProcess &p) +{ + return p.pid(); +} +#endif + + +enum { debug = 0 }; + +namespace trk { + +struct BluetoothListenerPrivate { + BluetoothListenerPrivate(); + QString device; + QProcess process; +#ifdef Q_OS_WIN + DWORD pid; +#else + Q_PID pid; +#endif + bool printConsoleMessages; + BluetoothListener::Mode mode; +}; + +BluetoothListenerPrivate::BluetoothListenerPrivate() : + pid(0), + printConsoleMessages(false), + mode(BluetoothListener::Listen) +{ +} + +BluetoothListener::BluetoothListener(QObject *parent) : + QObject(parent), + d(new BluetoothListenerPrivate) +{ + d->process.setProcessChannelMode(QProcess::MergedChannels); + + connect(&d->process, SIGNAL(readyReadStandardError()), + this, SLOT(slotStdError())); + connect(&d->process, SIGNAL(readyReadStandardOutput()), + this, SLOT(slotStdOutput())); + connect(&d->process, SIGNAL(finished(int, QProcess::ExitStatus)), + this, SLOT(slotProcessFinished(int,QProcess::ExitStatus))); + connect(&d->process, SIGNAL(error(QProcess::ProcessError)), + this, SLOT(slotProcessError(QProcess::ProcessError))); +} + +BluetoothListener::~BluetoothListener() +{ + const int trc = terminateProcess(); + if (debug) + qDebug() << "~BluetoothListener: terminated" << trc; + delete d; +} + +BluetoothListener::Mode BluetoothListener::mode() const +{ + return d->mode; +} + +void BluetoothListener::setMode(Mode m) +{ + d->mode = m; +} + +bool BluetoothListener::printConsoleMessages() const +{ + return d->printConsoleMessages; +} + +void BluetoothListener::setPrintConsoleMessages(bool p) +{ + d->printConsoleMessages = p; +} + +int BluetoothListener::terminateProcess() +{ + enum { TimeOutMS = 200 }; + if (debug) + qDebug() << "terminateProcess" << d->process.pid() << d->process.state(); + if (d->process.state() == QProcess::NotRunning) + return -1; + emitMessage(tr("%1: Stopping listener %2...").arg(d->device).arg(processId(d->process))); + // When listening, the process should terminate by itself after closing the connection + if (mode() == Listen && d->process.waitForFinished(TimeOutMS)) + return 0; +#ifdef Q_OS_UNIX + kill(d->process.pid(), SIGHUP); // Listens for SIGHUP + if (d->process.waitForFinished(TimeOutMS)) + return 1; +#endif + d->process.terminate(); + if (d->process.waitForFinished(TimeOutMS)) + return 2; + d->process.kill(); + return 3; +} + +bool BluetoothListener::start(const QString &device, QString *errorMessage) +{ + if (d->process.state() != QProcess::NotRunning) { + *errorMessage = QLatin1String("Internal error: Still running."); + return false; + } + d->device = device; + const QString binary = QLatin1String("rfcomm"); + QStringList arguments; + arguments << QLatin1String("-r") + << (d->mode == Listen ? QLatin1String("listen") : QLatin1String("watch")) + << device << QString(QLatin1Char('1')); + if (debug) + qDebug() << binary << arguments; + emitMessage(tr("%1: Starting Bluetooth listener %2...").arg(device, binary)); + d->pid = 0; + d->process.start(binary, arguments); + if (!d->process.waitForStarted()) { + *errorMessage = tr("Unable to run '%1': %2").arg(binary, d->process.errorString()); + return false; + } + d->pid = processId(d->process); // Forgets it after crash/termination + emitMessage(tr("%1: Bluetooth listener running (%2).").arg(device).arg(processId(d->process))); + return true; +} + +void BluetoothListener::slotStdOutput() +{ + emitMessage(QString::fromLocal8Bit(d->process.readAllStandardOutput())); +} + +void BluetoothListener::emitMessage(const QString &m) +{ + if (d->printConsoleMessages || debug) + qDebug("%s\n", qPrintable(m)); + emit message(m); +} + +void BluetoothListener::slotStdError() +{ + emitMessage(QString::fromLocal8Bit(d->process.readAllStandardError())); +} + +void BluetoothListener::slotProcessFinished(int ex, QProcess::ExitStatus state) +{ + switch (state) { + case QProcess::NormalExit: + emitMessage(tr("%1: Process %2 terminated with exit code %3.") + .arg(d->device).arg(d->pid).arg(ex)); + break; + case QProcess::CrashExit: + emitMessage(tr("%1: Process %2 crashed.").arg(d->device).arg(d->pid)); + break; + } + emit terminated(); +} + +void BluetoothListener::slotProcessError(QProcess::ProcessError error) +{ + emitMessage(tr("%1: Process error %2: %3") + .arg(d->device).arg(error).arg(d->process.errorString())); +} + +} // namespace trk diff --git a/tools/runonphone/trk/bluetoothlistener.h b/tools/runonphone/trk/bluetoothlistener.h new file mode 100644 index 0000000..a20ba30 --- /dev/null +++ b/tools/runonphone/trk/bluetoothlistener.h @@ -0,0 +1,89 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef BLUETOOTHLISTENER_H +#define BLUETOOTHLISTENER_H + +#include +#include + +namespace trk { +struct BluetoothListenerPrivate; + +/* BluetoothListener: Starts a helper process watching connections on a + * Bluetooth device, Linux only: + * The rfcomm command is used. It process can be started in the background + * while connection attempts (TrkDevice::open()) are made in the foreground. */ + +class BluetoothListener : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(BluetoothListener) +public: + // The Mode property must be set before calling start(). + enum Mode { + Listen, /* Terminate after client closed (read: Trk app + * on the phone terminated or disconnected).*/ + Watch // Keep running, watch for next connection from client + }; + + explicit BluetoothListener(QObject *parent = 0); + virtual ~BluetoothListener(); + + Mode mode() const; + void setMode(Mode m); + + bool start(const QString &device, QString *errorMessage); + + // Print messages on the console. + bool printConsoleMessages() const; + void setPrintConsoleMessages(bool p); + +signals: + void terminated(); + void message(const QString &); + +public slots: + void emitMessage(const QString &m); // accessed by starter + +private slots: + void slotStdOutput(); + void slotStdError(); + void slotProcessFinished(int, QProcess::ExitStatus); + void slotProcessError(QProcess::ProcessError error); + +private: + int terminateProcess(); + + BluetoothListenerPrivate *d; +}; + +} // namespace trk + +#endif // BLUETOOTHLISTENER_H diff --git a/tools/runonphone/trk/bluetoothlistener_gui.cpp b/tools/runonphone/trk/bluetoothlistener_gui.cpp new file mode 100644 index 0000000..9b6dbd3 --- /dev/null +++ b/tools/runonphone/trk/bluetoothlistener_gui.cpp @@ -0,0 +1,99 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "bluetoothlistener_gui.h" +#include "bluetoothlistener.h" +#include "communicationstarter.h" + +#include +#include +#include +#include + +namespace trk { + +PromptStartCommunicationResult + promptStartCommunication(BaseCommunicationStarter &starter, + const QString &msgBoxTitle, + const QString &msgBoxText, + QWidget *msgBoxParent, + QString *errorMessage) +{ + errorMessage->clear(); + // Initial connection attempt. + switch (starter.start()) { + case BaseCommunicationStarter::Started: + break; + case BaseCommunicationStarter::ConnectionSucceeded: + return PromptStartCommunicationConnected; + case BaseCommunicationStarter::StartError: + *errorMessage = starter.errorString(); + return PromptStartCommunicationError; + } + // Run the starter with the event loop of a message box, have the box + // closed by the signals of the starter. + QMessageBox messageBox(QMessageBox::Information, msgBoxTitle, msgBoxText, QMessageBox::Cancel, msgBoxParent); + QObject::connect(&starter, SIGNAL(connected()), &messageBox, SLOT(close())); + QObject::connect(&starter, SIGNAL(timeout()), &messageBox, SLOT(close())); + messageBox.exec(); + // Only starter.state() is reliable here to obtain the state. + switch (starter.state()) { + case AbstractBluetoothStarter::Running: + *errorMessage = QCoreApplication::translate("trk::promptStartCommunication", "Connection on %1 canceled.").arg(starter.device()); + return PromptStartCommunicationCanceled; + case AbstractBluetoothStarter::TimedOut: + *errorMessage = starter.errorString(); + return PromptStartCommunicationError; + case AbstractBluetoothStarter::Connected: + break; + } + return PromptStartCommunicationConnected; +} + +PromptStartCommunicationResult + promptStartSerial(BaseCommunicationStarter &starter, + QWidget *msgBoxParent, + QString *errorMessage) +{ + const QString title = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for App TRK"); + const QString message = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for App TRK to start on %1...").arg(starter.device()); + return promptStartCommunication(starter, title, message, msgBoxParent, errorMessage); +} + +PromptStartCommunicationResult + promptStartBluetooth(BaseCommunicationStarter &starter, + QWidget *msgBoxParent, + QString *errorMessage) +{ + const QString title = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for Bluetooth Connection"); + const QString message = QCoreApplication::translate("trk::promptStartCommunication", "Connecting to %1...").arg(starter.device()); + return promptStartCommunication(starter, title, message, msgBoxParent, errorMessage); +} + +} // namespace trk diff --git a/tools/runonphone/trk/bluetoothlistener_gui.h b/tools/runonphone/trk/bluetoothlistener_gui.h new file mode 100644 index 0000000..83cce42 --- /dev/null +++ b/tools/runonphone/trk/bluetoothlistener_gui.h @@ -0,0 +1,75 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef BLUETOOTHLISTENER_GUI_H +#define BLUETOOTHLISTENER_GUI_H + +#include + +QT_BEGIN_NAMESPACE +class QWidget; +QT_END_NAMESPACE + +namespace trk { +class BaseCommunicationStarter; + +/* promptStartCommunication(): Convenience functions that + * prompt the user to start a communication (launching or + * connecting TRK) using a modal message box in which they can cancel. + * Pass in the starter with device and parameters set up. */ + +enum PromptStartCommunicationResult { + PromptStartCommunicationConnected, + PromptStartCommunicationCanceled, + PromptStartCommunicationError +}; + +PromptStartCommunicationResult + promptStartCommunication(BaseCommunicationStarter &starter, + const QString &msgBoxTitle, + const QString &msgBoxText, + QWidget *msgBoxParent, + QString *errorMessage); + +// Convenience to start a serial connection (messages prompting +// to launch Trk). +PromptStartCommunicationResult + promptStartSerial(BaseCommunicationStarter &starter, + QWidget *msgBoxParent, + QString *errorMessage); + +// Convenience to start blue tooth connection (messages +// prompting to connect). +PromptStartCommunicationResult + promptStartBluetooth(BaseCommunicationStarter &starter, + QWidget *msgBoxParent, + QString *errorMessage); +} // namespace trk + +#endif // BLUETOOTHLISTENER_GUI_H diff --git a/tools/runonphone/trk/callback.h b/tools/runonphone/trk/callback.h new file mode 100644 index 0000000..375f167 --- /dev/null +++ b/tools/runonphone/trk/callback.h @@ -0,0 +1,148 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef DEBUGGER_CALLBACK_H +#define DEBUGGER_CALLBACK_H + +#include + +namespace trk { +namespace Internal { + +/* Helper class for the 1-argument functor: + * Cloneable base class for the implementation which is + * invokeable with the argument. */ +template +class CallbackImplBase +{ + Q_DISABLE_COPY(CallbackImplBase) +public: + CallbackImplBase() {} + virtual CallbackImplBase *clone() const = 0; + virtual void invoke(Argument a) = 0; + virtual ~CallbackImplBase() {} +}; + +/* Helper class for the 1-argument functor: Implementation for + * a class instance with a member function pointer. */ +template +class CallbackMemberPtrImpl : public CallbackImplBase +{ +public: + typedef void (Class::*MemberFuncPtr)(Argument); + + CallbackMemberPtrImpl(Class *instance, + MemberFuncPtr memberFunc) : + m_instance(instance), + m_memberFunc(memberFunc) {} + + virtual CallbackImplBase *clone() const + { + return new CallbackMemberPtrImpl(m_instance, m_memberFunc); + } + + virtual void invoke(Argument a) + { (m_instance->*m_memberFunc)(a); } +private: + Class *m_instance; + MemberFuncPtr m_memberFunc; +}; + +} // namespace Internal + +/* Default-constructible, copyable 1-argument functor providing an + * operator()(Argument) that invokes a member function of a class: + * \code +class Foo { +public: + void print(const std::string &); +}; +... +Foo foo; +Callback f1(&foo, &Foo::print); +f1("test"); +\endcode */ + +template +class Callback +{ +public: + Callback() : m_impl(0) {} + + template + Callback(Class *instance, void (Class::*memberFunc)(Argument)) : + m_impl(new Internal::CallbackMemberPtrImpl(instance, memberFunc)) + {} + + ~Callback() + { + clean(); + } + + Callback(const Callback &rhs) : + m_impl(0) + { + if (rhs.m_impl) + m_impl = rhs.m_impl->clone(); + } + + Callback &operator=(const Callback &rhs) + { + if (this != &rhs) { + clean(); + if (rhs.m_impl) + m_impl = rhs.m_impl->clone(); + } + return *this; + } + + bool isNull() const { return m_impl == 0; } + operator bool() const { return !isNull(); } + + void operator()(Argument a) + { + if (m_impl) + m_impl->invoke(a); + } + +private: + void clean() + { + if (m_impl) { + delete m_impl; + m_impl = 0; + } + } + + Internal::CallbackImplBase *m_impl; +}; + +} // namespace trk + +#endif // DEBUGGER_CALLBACK_H diff --git a/tools/runonphone/trk/communicationstarter.cpp b/tools/runonphone/trk/communicationstarter.cpp new file mode 100644 index 0000000..b425db2 --- /dev/null +++ b/tools/runonphone/trk/communicationstarter.cpp @@ -0,0 +1,248 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "communicationstarter.h" +#include "bluetoothlistener.h" +#include "trkdevice.h" + +#include +#include + +namespace trk { + +// --------------- AbstractBluetoothStarter +struct BaseCommunicationStarterPrivate { + explicit BaseCommunicationStarterPrivate(const BaseCommunicationStarter::TrkDevicePtr &d); + + const BaseCommunicationStarter::TrkDevicePtr trkDevice; + BluetoothListener *listener; + QTimer *timer; + int intervalMS; + int attempts; + int n; + QString device; + QString errorString; + BaseCommunicationStarter::State state; +}; + +BaseCommunicationStarterPrivate::BaseCommunicationStarterPrivate(const BaseCommunicationStarter::TrkDevicePtr &d) : + trkDevice(d), + listener(0), + timer(0), + intervalMS(1000), + attempts(-1), + n(0), + device(QLatin1String("/dev/rfcomm0")), + state(BaseCommunicationStarter::TimedOut) +{ +} + +BaseCommunicationStarter::BaseCommunicationStarter(const TrkDevicePtr &trkDevice, QObject *parent) : + QObject(parent), + d(new BaseCommunicationStarterPrivate(trkDevice)) +{ +} + +BaseCommunicationStarter::~BaseCommunicationStarter() +{ + stopTimer(); + delete d; +} + +void BaseCommunicationStarter::stopTimer() +{ + if (d->timer && d->timer->isActive()) + d->timer->stop(); +} + +bool BaseCommunicationStarter::initializeStartupResources(QString *errorMessage) +{ + errorMessage->clear(); + return true; +} + +BaseCommunicationStarter::StartResult BaseCommunicationStarter::start() +{ + if (state() == Running) { + d->errorString = QLatin1String("Internal error, attempt to re-start BaseCommunicationStarter.\n"); + return StartError; + } + // Before we instantiate timers, and such, try to open the device, + // which should succeed if another listener is already running in + // 'Watch' mode + if (d->trkDevice->open(d->device , &(d->errorString))) + return ConnectionSucceeded; + // Pull up resources for next attempt + d->n = 0; + if (!initializeStartupResources(&(d->errorString))) + return StartError; + // Start timer + if (!d->timer) { + d->timer = new QTimer; + connect(d->timer, SIGNAL(timeout()), this, SLOT(slotTimer())); + } + d->timer->setInterval(d->intervalMS); + d->timer->setSingleShot(false); + d->timer->start(); + d->state = Running; + return Started; +} + +BaseCommunicationStarter::State BaseCommunicationStarter::state() const +{ + return d->state; +} + +int BaseCommunicationStarter::intervalMS() const +{ + return d->intervalMS; +} + +void BaseCommunicationStarter::setIntervalMS(int i) +{ + d->intervalMS = i; + if (d->timer) + d->timer->setInterval(i); +} + +int BaseCommunicationStarter::attempts() const +{ + return d->attempts; +} + +void BaseCommunicationStarter::setAttempts(int a) +{ + d->attempts = a; +} + +QString BaseCommunicationStarter::device() const +{ + return d->device; +} + +void BaseCommunicationStarter::setDevice(const QString &dv) +{ + d->device = dv; +} + +QString BaseCommunicationStarter::errorString() const +{ + return d->errorString; +} + +void BaseCommunicationStarter::slotTimer() +{ + ++d->n; + // Check for timeout + if (d->attempts >= 0 && d->n >= d->attempts) { + stopTimer(); + d->errorString = tr("%1: timed out after %n attempts using an interval of %2ms.", 0, d->n) + .arg(d->device).arg(d->intervalMS); + d->state = TimedOut; + emit timeout(); + } else { + // Attempt n to connect? + if (d->trkDevice->open(d->device , &(d->errorString))) { + stopTimer(); + const QString msg = tr("%1: Connection attempt %2 succeeded.").arg(d->device).arg(d->n); + emit message(msg); + d->state = Connected; + emit connected(); + } else { + const QString msg = tr("%1: Connection attempt %2 failed: %3 (retrying)...") + .arg(d->device).arg(d->n).arg(d->errorString); + emit message(msg); + } + } +} + +// --------------- AbstractBluetoothStarter + +AbstractBluetoothStarter::AbstractBluetoothStarter(const TrkDevicePtr &trkDevice, QObject *parent) : + BaseCommunicationStarter(trkDevice, parent) +{ +} + +bool AbstractBluetoothStarter::initializeStartupResources(QString *errorMessage) +{ + // Create the listener and forward messages to it. + BluetoothListener *listener = createListener(); + connect(this, SIGNAL(message(QString)), listener, SLOT(emitMessage(QString))); + return listener->start(device(), errorMessage); +} + +// -------- ConsoleBluetoothStarter +ConsoleBluetoothStarter::ConsoleBluetoothStarter(const TrkDevicePtr &trkDevice, + QObject *listenerParent, + QObject *parent) : +AbstractBluetoothStarter(trkDevice, parent), +m_listenerParent(listenerParent) +{ +} + +BluetoothListener *ConsoleBluetoothStarter::createListener() +{ + BluetoothListener *rc = new BluetoothListener(m_listenerParent); + rc->setMode(BluetoothListener::Listen); + rc->setPrintConsoleMessages(true); + return rc; +} + +bool ConsoleBluetoothStarter::startBluetooth(const TrkDevicePtr &trkDevice, + QObject *listenerParent, + const QString &device, + int attempts, + QString *errorMessage) +{ + // Set up a console starter to print to stdout. + ConsoleBluetoothStarter starter(trkDevice, listenerParent); + starter.setDevice(device); + starter.setAttempts(attempts); + switch (starter.start()) { + case Started: + break; + case ConnectionSucceeded: + return true; + case StartError: + *errorMessage = starter.errorString(); + return false; + } + // Run the starter with an event loop. @ToDo: Implement + // some asynchronous keypress read to cancel. + QEventLoop eventLoop; + connect(&starter, SIGNAL(connected()), &eventLoop, SLOT(quit())); + connect(&starter, SIGNAL(timeout()), &eventLoop, SLOT(quit())); + eventLoop.exec(QEventLoop::ExcludeUserInputEvents); + if (starter.state() != AbstractBluetoothStarter::Connected) { + *errorMessage = starter.errorString(); + return false; + } + return true; +} +} // namespace trk diff --git a/tools/runonphone/trk/communicationstarter.h b/tools/runonphone/trk/communicationstarter.h new file mode 100644 index 0000000..6f9f6d1 --- /dev/null +++ b/tools/runonphone/trk/communicationstarter.h @@ -0,0 +1,148 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef COMMUNICATIONSTARTER_H +#define COMMUNICATIONSTARTER_H + +#include +#include + +namespace trk { +class TrkDevice; +class BluetoothListener; +struct BaseCommunicationStarterPrivate; + +/* BaseCommunicationStarter: A QObject that repeatedly tries to open a + * trk device until a connection succeeds or a timeout occurs (emitting + * signals), allowing to do something else in the foreground (local event loop + * [say QMessageBox] or some asynchronous operation). If the initial + * connection attempt in start() fails, the + * virtual initializeStartupResources() is called to initialize resources + * required to pull up the communication (namely Bluetooth listeners). + * The base class can be used as is to prompt the user to launch App TRK for a + * serial communication as this requires no further resource setup. */ + +class BaseCommunicationStarter : public QObject { + Q_OBJECT + Q_DISABLE_COPY(BaseCommunicationStarter) +public: + typedef QSharedPointer TrkDevicePtr; + + enum State { Running, Connected, TimedOut }; + + explicit BaseCommunicationStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); + virtual ~BaseCommunicationStarter(); + + int intervalMS() const; + void setIntervalMS(int i); + + int attempts() const; + void setAttempts(int a); + + QString device() const; + void setDevice(const QString &); + + State state() const; + QString errorString() const; + + enum StartResult { + Started, // Starter is now running. + ConnectionSucceeded, /* Initial connection attempt succeeded, + * no need to keep running. */ + StartError // Error occurred during start. + }; + + StartResult start(); + +signals: + void connected(); + void timeout(); + void message(const QString &); + +private slots: + void slotTimer(); + +protected: + virtual bool initializeStartupResources(QString *errorMessage); + +private: + inline void stopTimer(); + + BaseCommunicationStarterPrivate *d; +}; + +/* AbstractBluetoothStarter: Repeatedly tries to open a trk Bluetooth + * device. Note that in case a Listener is already running mode, the + * connection will succeed immediately. + * initializeStartupResources() is implemented to fire up the listener. + * Introduces a new virtual createListener() that derived classes must + * implement as a factory function that creates and sets up the + * listener (mode, message connection, etc). */ + +class AbstractBluetoothStarter : public BaseCommunicationStarter { + Q_OBJECT + Q_DISABLE_COPY(AbstractBluetoothStarter) +public: + +protected: + explicit AbstractBluetoothStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); + + // Implemented to fire up the listener. + virtual bool initializeStartupResources(QString *errorMessage); + // New virtual: Overwrite to create and parametrize the listener. + virtual BluetoothListener *createListener() = 0; +}; + +/* ConsoleBluetoothStarter: Convenience class for console processes. Creates a + * listener in "Listen" mode with the messages redirected to standard output. */ + +class ConsoleBluetoothStarter : public AbstractBluetoothStarter { + Q_OBJECT + Q_DISABLE_COPY(ConsoleBluetoothStarter) +public: + static bool startBluetooth(const TrkDevicePtr& trkDevice, + QObject *listenerParent, + const QString &device, + int attempts, + QString *errorMessage); + +protected: + virtual BluetoothListener *createListener(); + +private: + explicit ConsoleBluetoothStarter(const TrkDevicePtr& trkDevice, + QObject *listenerParent, + QObject *parent = 0); + + QObject *m_listenerParent; +}; + +} // namespace trk + +#endif // COMMUNICATIONSTARTER_H diff --git a/tools/runonphone/trk/launcher.cpp b/tools/runonphone/trk/launcher.cpp new file mode 100644 index 0000000..aa3a4e6 --- /dev/null +++ b/tools/runonphone/trk/launcher.cpp @@ -0,0 +1,683 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "launcher.h" +#include "trkutils.h" +#include "trkdevice.h" +#include "bluetoothlistener.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace trk { + +struct LauncherPrivate { + struct CopyState { + QString sourceFileName; + QString destinationFileName; + uint copyFileHandle; + QScopedPointer data; + int position; + }; + + explicit LauncherPrivate(const TrkDevicePtr &d); + + TrkDevicePtr m_device; + QString m_trkServerName; + QByteArray m_trkReadBuffer; + Launcher::State m_state; + + void logMessage(const QString &msg); + // Debuggee state + Session m_session; // global-ish data (process id, target information) + + CopyState m_copyState; + QString m_fileName; + QString m_commandLineArgs; + QString m_installFileName; + int m_verbose; + Launcher::Actions m_startupActions; + bool m_closeDevice; +}; + +LauncherPrivate::LauncherPrivate(const TrkDevicePtr &d) : + m_device(d), + m_state(Launcher::Disconnected), + m_verbose(0), + m_closeDevice(true) +{ + if (m_device.isNull()) + m_device = TrkDevicePtr(new TrkDevice); +} + +Launcher::Launcher(Actions startupActions, + const TrkDevicePtr &dev, + QObject *parent) : + QObject(parent), + d(new LauncherPrivate(dev)) +{ + d->m_startupActions = startupActions; + connect(d->m_device.data(), SIGNAL(messageReceived(trk::TrkResult)), this, SLOT(handleResult(trk::TrkResult))); + connect(this, SIGNAL(finished()), d->m_device.data(), SLOT(close())); +} + +Launcher::~Launcher() +{ + logMessage("Shutting down.\n"); + delete d; +} + +Launcher::State Launcher::state() const +{ + return d->m_state; +} + +void Launcher::setState(State s) +{ + if (s != d->m_state) { + d->m_state = s; + emit stateChanged(s); + } +} + +void Launcher::addStartupActions(trk::Launcher::Actions startupActions) +{ + d->m_startupActions = Actions(d->m_startupActions | startupActions); +} + +void Launcher::setTrkServerName(const QString &name) +{ + d->m_trkServerName = name; +} + +QString Launcher::trkServerName() const +{ + return d->m_trkServerName; +} + +TrkDevicePtr Launcher::trkDevice() const +{ + return d->m_device; +} + +void Launcher::setFileName(const QString &name) +{ + d->m_fileName = name; +} + +void Launcher::setCopyFileName(const QString &srcName, const QString &dstName) +{ + d->m_copyState.sourceFileName = srcName; + d->m_copyState.destinationFileName = dstName; +} + +void Launcher::setInstallFileName(const QString &name) +{ + d->m_installFileName = name; +} + +void Launcher::setCommandLineArgs(const QString &args) +{ + d->m_commandLineArgs = args; +} + +void Launcher::setSerialFrame(bool b) +{ + d->m_device->setSerialFrame(b); +} + +bool Launcher::serialFrame() const +{ + return d->m_device->serialFrame(); +} + + +bool Launcher::closeDevice() const +{ + return d->m_closeDevice; +} + +void Launcher::setCloseDevice(bool c) +{ + d->m_closeDevice = c; +} + +bool Launcher::startServer(QString *errorMessage) +{ + errorMessage->clear(); + if (d->m_verbose) { + const QString msg = QString::fromLatin1("Port=%1 Executable=%2 Package=%3 Remote Package=%4 Install file=%5") + .arg(d->m_trkServerName, d->m_fileName, d->m_copyState.sourceFileName, d->m_copyState.destinationFileName, d->m_installFileName); + logMessage(msg); + } + if (d->m_startupActions & ActionCopy) { + if (d->m_copyState.sourceFileName.isEmpty()) { + qWarning("No local filename given for copying package."); + return false; + } else if (d->m_copyState.destinationFileName.isEmpty()) { + qWarning("No remote filename given for copying package."); + return false; + } + } + if (d->m_startupActions & ActionInstall && d->m_installFileName.isEmpty()) { + qWarning("No package name given for installing."); + return false; + } + if (d->m_startupActions & ActionRun && d->m_fileName.isEmpty()) { + qWarning("No remote executable given for running."); + return false; + } + if (!d->m_device->isOpen() && !d->m_device->open(d->m_trkServerName, errorMessage)) + return false; + if (d->m_closeDevice) { + connect(this, SIGNAL(finished()), d->m_device.data(), SLOT(close())); + } else { + disconnect(this, SIGNAL(finished()), d->m_device.data(), 0); + } + setState(Connecting); + // Set up the temporary 'waiting' state if we do not get immediate connection + QTimer::singleShot(1000, this, SLOT(slotWaitingForTrk())); + d->m_device->sendTrkInitialPing(); + d->m_device->sendTrkMessage(TrkDisconnect); // Disconnect, as trk might be still connected + d->m_device->sendTrkMessage(TrkSupported, TrkCallback(this, &Launcher::handleSupportMask)); + d->m_device->sendTrkMessage(TrkCpuType, TrkCallback(this, &Launcher::handleCpuType)); + d->m_device->sendTrkMessage(TrkVersions, TrkCallback(this, &Launcher::handleTrkVersion)); + if (d->m_startupActions != ActionPingOnly) + d->m_device->sendTrkMessage(TrkConnect, TrkCallback(this, &Launcher::handleConnect)); + return true; +} + +void Launcher::slotWaitingForTrk() +{ + // Set temporary state if we are still in connected state + if (state() == Connecting) + setState(WaitingForTrk); +} + +void Launcher::handleConnect(const TrkResult &result) +{ + if (result.errorCode()) { + emit canNotConnect(result.errorString()); + return; + } + setState(Connected); + if (d->m_startupActions & ActionCopy) + copyFileToRemote(); + else if (d->m_startupActions & ActionInstall) + installRemotePackageSilently(); + else if (d->m_startupActions & ActionRun) + startInferiorIfNeeded(); +} + +void Launcher::setVerbose(int v) +{ + d->m_verbose = v; + d->m_device->setVerbose(v); +} + +void Launcher::logMessage(const QString &msg) +{ + if (d->m_verbose) + qDebug() << "LAUNCHER: " << qPrintable(msg); +} + +void Launcher::terminate() +{ + switch (state()) { + case DeviceDescriptionReceived: + case Connected: + if (d->m_session.pid) { + QByteArray ba; + appendShort(&ba, 0x0000, TargetByteOrder); + appendInt(&ba, d->m_session.pid, TargetByteOrder); + d->m_device->sendTrkMessage(TrkDeleteItem, TrkCallback(this, &Launcher::handleRemoteProcessKilled), ba); + return; + } + if (d->m_copyState.copyFileHandle) + closeRemoteFile(true); + disconnectTrk(); + break; + case Disconnected: + break; + case Connecting: + case WaitingForTrk: + setState(Disconnected); + emit finished(); + break; + } +} + +void Launcher::handleRemoteProcessKilled(const TrkResult &result) +{ + Q_UNUSED(result) + disconnectTrk(); +} + +void Launcher::handleResult(const TrkResult &result) +{ + QByteArray prefix = "READ BUF: "; + QByteArray str = result.toString().toUtf8(); + if (result.isDebugOutput) { // handle application output + logMessage("APPLICATION OUTPUT: " + result.data); + emit applicationOutputReceived(result.data); + return; + } + switch (result.code) { + case TrkNotifyAck: + break; + case TrkNotifyNak: { // NAK + logMessage(prefix + "NAK: " + str); + //logMessage(prefix << "TOKEN: " << result.token); + logMessage(prefix + "ERROR: " + errorMessage(result.data.at(0))); + break; + } + case TrkNotifyStopped: { // Notified Stopped + logMessage(prefix + "NOTE: STOPPED " + str); + // 90 01 78 6a 40 40 00 00 07 23 00 00 07 24 00 00 + //const char *data = result.data.data(); +// uint addr = extractInt(data); //code address: 4 bytes; code base address for the library +// uint pid = extractInt(data + 4); // ProcessID: 4 bytes; +// uint tid = extractInt(data + 8); // ThreadID: 4 bytes + //logMessage(prefix << " ADDR: " << addr << " PID: " << pid << " TID: " << tid); + d->m_device->sendTrkAck(result.token); + break; + } + case TrkNotifyException: { // Notify Exception (obsolete) + logMessage(prefix + "NOTE: EXCEPTION " + str); + d->m_device->sendTrkAck(result.token); + break; + } + case TrkNotifyInternalError: { // + logMessage(prefix + "NOTE: INTERNAL ERROR: " + str); + d->m_device->sendTrkAck(result.token); + break; + } + + // target->host OS notification + case TrkNotifyCreated: { // Notify Created + /* + const char *data = result.data.data(); + byte error = result.data.at(0); + byte type = result.data.at(1); // type: 1 byte; for dll item, this value is 2. + uint pid = extractInt(data + 2); // ProcessID: 4 bytes; + uint tid = extractInt(data + 6); //threadID: 4 bytes + uint codeseg = extractInt(data + 10); //code address: 4 bytes; code base address for the library + uint dataseg = extractInt(data + 14); //data address: 4 bytes; data base address for the library + uint len = extractShort(data + 18); //length: 2 bytes; length of the library name string to follow + QByteArray name = result.data.mid(20, len); // name: library name + + logMessage(prefix + "NOTE: LIBRARY LOAD: " + str); + logMessage(prefix + "TOKEN: " + result.token); + logMessage(prefix + "ERROR: " + int(error)); + logMessage(prefix + "TYPE: " + int(type)); + logMessage(prefix + "PID: " + pid); + logMessage(prefix + "TID: " + tid); + logMessage(prefix + "CODE: " + codeseg); + logMessage(prefix + "DATA: " + dataseg); + logMessage(prefix + "LEN: " + len); + logMessage(prefix + "NAME: " + name); + */ + + if (result.data.size() < 10) + break; + QByteArray ba; + ba.append(result.data.mid(2, 8)); + d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE"); + //d->m_device->sendTrkAck(result.token) + break; + } + case TrkNotifyDeleted: { // NotifyDeleted + const ushort itemType = (unsigned char)result.data.at(1); + const ushort len = result.data.size() > 12 ? extractShort(result.data.data() + 10) : ushort(0); + const QString name = len ? QString::fromAscii(result.data.mid(12, len)) : QString(); + logMessage(QString::fromLatin1("%1 %2 UNLOAD: %3"). + arg(QString::fromAscii(prefix)).arg(itemType ? QLatin1String("LIB") : QLatin1String("PROCESS")). + arg(name)); + d->m_device->sendTrkAck(result.token); + if (itemType == 0 // process + && result.data.size() >= 10 + && d->m_session.pid == extractInt(result.data.data() + 6)) { + disconnectTrk(); + } + break; + } + case TrkNotifyProcessorStarted: { // NotifyProcessorStarted + logMessage(prefix + "NOTE: PROCESSOR STARTED: " + str); + d->m_device->sendTrkAck(result.token); + break; + } + case TrkNotifyProcessorStandBy: { // NotifyProcessorStandby + logMessage(prefix + "NOTE: PROCESSOR STANDBY: " + str); + d->m_device->sendTrkAck(result.token); + break; + } + case TrkNotifyProcessorReset: { // NotifyProcessorReset + logMessage(prefix + "NOTE: PROCESSOR RESET: " + str); + d->m_device->sendTrkAck(result.token); + break; + } + default: { + logMessage(prefix + "INVALID: " + str); + break; + } + } +} + +QString Launcher::deviceDescription(unsigned verbose) const +{ + return d->m_session.deviceDescription(verbose); +} + +void Launcher::handleTrkVersion(const TrkResult &result) +{ + if (result.errorCode() || result.data.size() < 5) { + if (d->m_startupActions == ActionPingOnly) { + setState(Disconnected); + emit finished(); + } + return; + } + d->m_session.trkAppVersion.trkMajor = result.data.at(1); + d->m_session.trkAppVersion.trkMinor = result.data.at(2); + d->m_session.trkAppVersion.protocolMajor = result.data.at(3); + d->m_session.trkAppVersion.protocolMinor = result.data.at(4); + setState(DeviceDescriptionReceived); + // Ping mode: Log & Terminate + if (d->m_startupActions == ActionPingOnly) { + qWarning("%s", qPrintable(deviceDescription())); + setState(Disconnected); + emit finished(); + } +} + +void Launcher::handleFileCreation(const TrkResult &result) +{ + if (result.errorCode() || result.data.size() < 6) { + emit canNotCreateFile(d->m_copyState.destinationFileName, result.errorString()); + disconnectTrk(); + return; + } + const char *data = result.data.data(); + d->m_copyState.copyFileHandle = extractInt(data + 2); + QFile file(d->m_copyState.sourceFileName); + file.open(QIODevice::ReadOnly); + d->m_copyState.data.reset(new QByteArray(file.readAll())); + d->m_copyState.position = 0; + file.close(); + continueCopying(); +} + +void Launcher::handleCopy(const TrkResult &result) +{ + if (result.errorCode() || result.data.size() < 4) { + closeRemoteFile(true); + emit canNotWriteFile(d->m_copyState.destinationFileName, result.errorString()); + disconnectTrk(); + } else { + continueCopying(extractShort(result.data.data() + 2)); + } +} + +void Launcher::continueCopying(uint lastCopiedBlockSize) +{ + int size = d->m_copyState.data->length(); + d->m_copyState.position += lastCopiedBlockSize; + if (size == 0) + emit copyProgress(100); + else { + int percent = qMin((d->m_copyState.position*100)/size, 100); + emit copyProgress(percent); + } + if (d->m_copyState.position < size) { + QByteArray ba; + appendInt(&ba, d->m_copyState.copyFileHandle, TargetByteOrder); + appendString(&ba, d->m_copyState.data->mid(d->m_copyState.position, 2048), TargetByteOrder, false); + d->m_device->sendTrkMessage(TrkWriteFile, TrkCallback(this, &Launcher::handleCopy), ba); + } else { + closeRemoteFile(); + } +} + +void Launcher::closeRemoteFile(bool failed) +{ + QByteArray ba; + appendInt(&ba, d->m_copyState.copyFileHandle, TargetByteOrder); + appendDateTime(&ba, QDateTime::currentDateTime(), TargetByteOrder); + d->m_device->sendTrkMessage(TrkCloseFile, + failed ? TrkCallback() : TrkCallback(this, &Launcher::handleFileCopied), + ba); + d->m_copyState.data.reset(); + d->m_copyState.copyFileHandle = 0; + d->m_copyState.position = 0; +} + +void Launcher::handleFileCopied(const TrkResult &result) +{ + if (result.errorCode()) + emit canNotCloseFile(d->m_copyState.destinationFileName, result.errorString()); + if (d->m_startupActions & ActionInstall) + installRemotePackageSilently(); + else if (d->m_startupActions & ActionRun) + startInferiorIfNeeded(); + else + disconnectTrk(); +} + +void Launcher::handleCpuType(const TrkResult &result) +{ + logMessage("HANDLE CPU TYPE: " + result.toString()); + if(result.errorCode() || result.data.size() < 7) + return; + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 + // [80 03 00 04 00 00 04 00 00 00] + d->m_session.cpuMajor = result.data.at(1); + d->m_session.cpuMinor = result.data.at(2); + d->m_session.bigEndian = result.data.at(3); + d->m_session.defaultTypeSize = result.data.at(4); + d->m_session.fpTypeSize = result.data.at(5); + d->m_session.extended1TypeSize = result.data.at(6); + //d->m_session.extended2TypeSize = result.data[6]; +} + +void Launcher::handleCreateProcess(const TrkResult &result) +{ + if (result.errorCode()) { + emit canNotRun(result.errorString()); + disconnectTrk(); + return; + } + // 40 00 00] + //logMessage(" RESULT: " + result.toString()); + // [80 08 00 00 00 01 B5 00 00 01 B6 78 67 40 00 00 40 00 00] + const char *data = result.data.data(); + d->m_session.pid = extractInt(data + 1); + d->m_session.tid = extractInt(data + 5); + d->m_session.codeseg = extractInt(data + 9); + d->m_session.dataseg = extractInt(data + 13); + if (d->m_verbose) { + const QString msg = QString::fromLatin1("Process id: %1 Thread id: %2 code: 0x%3 data: 0x%4"). + arg(d->m_session.pid).arg(d->m_session.tid).arg(d->m_session.codeseg, 0, 16). + arg(d->m_session.dataseg, 0 ,16); + logMessage(msg); + } + emit applicationRunning(d->m_session.pid); + QByteArray ba; + appendInt(&ba, d->m_session.pid); + appendInt(&ba, d->m_session.tid); + d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE"); +} + +void Launcher::handleWaitForFinished(const TrkResult &result) +{ + logMessage(" FINISHED: " + stringFromArray(result.data)); + setState(Disconnected); + emit finished(); +} + +void Launcher::handleSupportMask(const TrkResult &result) +{ + if (result.errorCode() || result.data.size() < 32) + return; + const char *data = result.data.data() + 1; + + QByteArray str; + for (int i = 0; i < 32; ++i) { + //str.append(" [" + formatByte(data[i]) + "]: "); + for (int j = 0; j < 8; ++j) + if (data[i] & (1 << j)) + str.append(QByteArray::number(i * 8 + j, 16) + " "); + } + logMessage("SUPPORTED: " + str); +} + + +void Launcher::cleanUp() +{ + // + //---IDE------------------------------------------------------ + // Command: 0x41 Delete Item + // Sub Cmd: Delete Process + //ProcessID: 0x0000071F (1823) + // [41 24 00 00 00 00 07 1F] + QByteArray ba; + appendByte(&ba, 0x00); + appendByte(&ba, 0x00); + appendInt(&ba, d->m_session.pid); + d->m_device->sendTrkMessage(TrkDeleteItem, TrkCallback(), ba, "Delete process"); + + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 + // [80 24 00] + + //---IDE------------------------------------------------------ + // Command: 0x1C Clear Break + // [1C 25 00 00 00 0A 78 6A 43 40] + + //---TRK------------------------------------------------------ + // Command: 0xA1 Notify Deleted + // [A1 09 00 00 00 00 00 00 00 00 07 1F] + //---IDE------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 + // [80 09 00] + + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 + // [80 25 00] + + //---IDE------------------------------------------------------ + // Command: 0x1C Clear Break + // [1C 26 00 00 00 0B 78 6A 43 70] + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 + // [80 26 00] + + + //---IDE------------------------------------------------------ + // Command: 0x02 Disconnect + // [02 27] +// sendTrkMessage(0x02, TrkCallback(this, &Launcher::handleDisconnect)); + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 +} + +void Launcher::disconnectTrk() +{ + d->m_device->sendTrkMessage(TrkDisconnect, TrkCallback(this, &Launcher::handleWaitForFinished)); +} + +void Launcher::copyFileToRemote() +{ + emit copyingStarted(); + QByteArray ba; + appendByte(&ba, 0x10); + appendString(&ba, d->m_copyState.destinationFileName.toLocal8Bit(), TargetByteOrder, false); + d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileCreation), ba); +} + +void Launcher::installRemotePackageSilently() +{ + emit installingStarted(); + QByteArray ba; + appendByte(&ba, 'C'); + appendString(&ba, d->m_installFileName.toLocal8Bit(), TargetByteOrder, false); + d->m_device->sendTrkMessage(TrkInstallFile, TrkCallback(this, &Launcher::handleInstallPackageFinished), ba); +} + +void Launcher::handleInstallPackageFinished(const TrkResult &result) +{ + if (result.errorCode()) { + emit canNotInstall(d->m_installFileName, result.errorString()); + disconnectTrk(); + return; + } else { + emit installingFinished(); + } + if (d->m_startupActions & ActionRun) { + startInferiorIfNeeded(); + } else { + disconnectTrk(); + } +} + +void Launcher::startInferiorIfNeeded() +{ + emit startingApplication(); + if (d->m_session.pid != 0) { + logMessage("Process already 'started'"); + return; + } + // It's not started yet + QByteArray ba; + appendShort(&ba, 0, TargetByteOrder); // create new process + appendByte(&ba, 0); // options - currently unused + + if(d->m_commandLineArgs.isEmpty()) { + appendString(&ba, d->m_fileName.toLocal8Bit(), TargetByteOrder); + } else { + QByteArray ba2; + ba2.append(d->m_fileName.toLocal8Bit()); + ba2.append('\0'); + ba2.append(d->m_commandLineArgs.toLocal8Bit()); + appendString(&ba, ba2, TargetByteOrder); + } + d->m_device->sendTrkMessage(TrkCreateItem, TrkCallback(this, &Launcher::handleCreateProcess), ba); // Create Item +} +} // namespace trk diff --git a/tools/runonphone/trk/launcher.h b/tools/runonphone/trk/launcher.h new file mode 100644 index 0000000..799c77a --- /dev/null +++ b/tools/runonphone/trk/launcher.h @@ -0,0 +1,155 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ +#ifndef LAUNCHER_H +#define LAUNCHER_H + +#include "trkdevice.h" + +#include +#include +#include + +namespace trk { + +struct TrkResult; +struct TrkMessage; +struct LauncherPrivate; + +typedef QSharedPointer TrkDevicePtr; + +class Launcher : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(Launcher) +public: + typedef void (Launcher::*TrkCallBack)(const TrkResult &); + + enum Actions { + ActionPingOnly = 0x0, + ActionCopy = 0x1, + ActionInstall = 0x2, + ActionCopyInstall = ActionCopy | ActionInstall, + ActionRun = 0x4, + ActionCopyRun = ActionCopy | ActionRun, + ActionInstallRun = ActionInstall | ActionRun, + ActionCopyInstallRun = ActionCopy | ActionInstall | ActionRun + }; + + enum State { Disconnected, Connecting, Connected, + WaitingForTrk, // This occurs only if the initial ping times out after + // a reasonable timeout, indicating that Trk is not + // running. Note that this will never happen with + // Bluetooth as communication immediately starts + // after connecting. + DeviceDescriptionReceived }; + + explicit Launcher(trk::Launcher::Actions startupActions = trk::Launcher::ActionPingOnly, + const TrkDevicePtr &trkDevice = TrkDevicePtr(), + QObject *parent = 0); + ~Launcher(); + + State state() const; + + void addStartupActions(trk::Launcher::Actions startupActions); + void setTrkServerName(const QString &name); + QString trkServerName() const; + void setFileName(const QString &name); + void setCopyFileName(const QString &srcName, const QString &dstName); + void setInstallFileName(const QString &name); + void setCommandLineArgs(const QString &args); + bool startServer(QString *errorMessage); + void setVerbose(int v); + void setSerialFrame(bool b); + bool serialFrame() const; + // Close device or leave it open + bool closeDevice() const; + void setCloseDevice(bool c); + + TrkDevicePtr trkDevice() const; + + // becomes valid after successful execution of ActionPingOnly + QString deviceDescription(unsigned verbose = 0u) const; + +signals: + void copyingStarted(); + void canNotConnect(const QString &errorMessage); + void canNotCreateFile(const QString &filename, const QString &errorMessage); + void canNotWriteFile(const QString &filename, const QString &errorMessage); + void canNotCloseFile(const QString &filename, const QString &errorMessage); + void installingStarted(); + void canNotInstall(const QString &packageFilename, const QString &errorMessage); + void installingFinished(); + void startingApplication(); + void applicationRunning(uint pid); + void canNotRun(const QString &errorMessage); + void finished(); + void applicationOutputReceived(const QString &output); + void copyProgress(int percent); + void stateChanged(int); + +public slots: + void terminate(); + +private slots: + void handleResult(const trk::TrkResult &data); + void slotWaitingForTrk(); + +private: + // kill process and breakpoints + void cleanUp(); + void disconnectTrk(); + + void handleRemoteProcessKilled(const TrkResult &result); + void handleConnect(const TrkResult &result); + void handleFileCreation(const TrkResult &result); + void handleCopy(const TrkResult &result); + void continueCopying(uint lastCopiedBlockSize = 0); + void closeRemoteFile(bool failed = false); + void handleFileCopied(const TrkResult &result); + void handleInstallPackageFinished(const TrkResult &result); + void handleCpuType(const TrkResult &result); + void handleCreateProcess(const TrkResult &result); + void handleWaitForFinished(const TrkResult &result); + void handleStop(const TrkResult &result); + void handleSupportMask(const TrkResult &result); + void handleTrkVersion(const TrkResult &result); + + void copyFileToRemote(); + void installRemotePackageSilently(); + void startInferiorIfNeeded(); + + void logMessage(const QString &msg); + void setState(State s); + + LauncherPrivate *d; +}; + +} // namespace Trk + +#endif // LAUNCHER_H diff --git a/tools/runonphone/trk/trk.pri b/tools/runonphone/trk/trk.pri new file mode 100644 index 0000000..2ce17c0 --- /dev/null +++ b/tools/runonphone/trk/trk.pri @@ -0,0 +1,23 @@ +INCLUDEPATH *= $$PWD + +# Input +HEADERS += $$PWD/callback.h \ + $$PWD/trkutils.h \ + $$PWD/trkdevice.h \ + $$PWD/launcher.h \ + $$PWD/bluetoothlistener.h \ + $$PWD/communicationstarter.h + +SOURCES += $$PWD/trkutils.cpp \ + $$PWD/trkdevice.cpp \ + $$PWD/launcher.cpp \ + $$PWD/bluetoothlistener.cpp \ + $$PWD/communicationstarter.cpp + +# Tests/trklauncher is a console application +contains(QT, gui) { + HEADERS += $$PWD/bluetoothlistener_gui.h + SOURCES += $$PWD/bluetoothlistener_gui.cpp +} else { + message(Trk: Console ...) +} diff --git a/tools/runonphone/trk/trkdevice.cpp b/tools/runonphone/trk/trkdevice.cpp new file mode 100644 index 0000000..a76cff7 --- /dev/null +++ b/tools/runonphone/trk/trkdevice.cpp @@ -0,0 +1,1061 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "trkdevice.h" +#include "trkutils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef Q_OS_WIN +# include +#else +# include + +# include +# include +# include +# include +# include +# include +# include +/* Required headers for select() according to POSIX.1-2001 */ +# include +/* Required headers for select() according to earlier standards: + #include + #include + #include +*/ +#endif + +#ifdef Q_OS_WIN + +// Format windows error from GetLastError() value: +// TODO: Use the one provided by the utils lib. +QString winErrorMessage(unsigned long error) +{ + QString rc = QString::fromLatin1("#%1: ").arg(error); + ushort *lpMsgBuf; + + const int len = FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER + | FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, error, 0, (LPTSTR)&lpMsgBuf, 0, NULL); + if (len) { + rc = QString::fromUtf16(lpMsgBuf, len); + LocalFree(lpMsgBuf); + } else { + rc += QString::fromLatin1(""); + } + return rc; +} + +#endif + +namespace trk { + +/////////////////////////////////////////////////////////////////////// +// +// TrkMessage +// +/////////////////////////////////////////////////////////////////////// + +/* A message to be send to TRK, triggering a callback on receipt + * of the answer. */ +struct TrkMessage +{ + explicit TrkMessage(byte code = 0u, byte token = 0u, + TrkCallback callback = TrkCallback()); + + byte code; + byte token; + QByteArray data; + QVariant cookie; + TrkCallback callback; +}; + +TrkMessage::TrkMessage(byte c, byte t, TrkCallback cb) : + code(c), + token(t), + callback(cb) +{ +} + +} // namespace trk + +Q_DECLARE_METATYPE(trk::TrkMessage) +Q_DECLARE_METATYPE(trk::TrkResult) + +namespace trk { + +/////////////////////////////////////////////////////////////////////// +// +// TrkWriteQueue: Mixin class that manages a write queue of Trk messages. +// pendingMessage()/notifyWriteResult() should be called from a worked/timer +// that writes the messages. The class does not take precautions for multithreading. +// A no-op message is simply taken off the queue. The calling class +// can use the helper invokeNoopMessage() to trigger its callback. +// +/////////////////////////////////////////////////////////////////////// + +class TrkWriteQueue +{ + Q_DISABLE_COPY(TrkWriteQueue) +public: + explicit TrkWriteQueue(); + + // Enqueue messages. + void queueTrkMessage(byte code, TrkCallback callback, + const QByteArray &data, const QVariant &cookie); + void queueTrkInitialPing(); + + // Call this from the device read notification with the results. + void slotHandleResult(const TrkResult &result, QMutex *mutex = 0); + + // pendingMessage() can be called periodically in a timer to retrieve + // the pending messages to be sent. + enum PendingMessageResult { + NoMessage, // No message in queue. + PendingMessage, /* There is a queued message. The calling class + * can write it out and use notifyWriteResult() + * to notify about the result. */ + NoopMessageDequeued // A no-op message has been dequeued. see invokeNoopMessage(). + }; + + PendingMessageResult pendingMessage(TrkMessage *message); + // Notify the queue about the success of the write operation + // after taking the pendingMessage off. + enum WriteResult { + WriteOk, + WriteFailedDiscard, // Discard failed message + WriteFailedKeep, // Keep failed message + }; + void notifyWriteResult(WriteResult ok); + + // Helper function that invokes the callback of a no-op message + static void invokeNoopMessage(trk::TrkMessage); + +private: + typedef QMap TokenMessageMap; + + byte nextTrkWriteToken(); + + byte m_trkWriteToken; + QQueue m_trkWriteQueue; + TokenMessageMap m_writtenTrkMessages; + bool m_trkWriteBusy; +}; + +TrkWriteQueue::TrkWriteQueue() : + m_trkWriteToken(0), + m_trkWriteBusy(false) +{ +} + +byte TrkWriteQueue::nextTrkWriteToken() +{ + ++m_trkWriteToken; + if (m_trkWriteToken == 0) + ++m_trkWriteToken; + return m_trkWriteToken; +} + +void TrkWriteQueue::queueTrkMessage(byte code, TrkCallback callback, + const QByteArray &data, const QVariant &cookie) +{ + const byte token = code == TRK_WRITE_QUEUE_NOOP_CODE ? + byte(0) : nextTrkWriteToken(); + TrkMessage msg(code, token, callback); + msg.data = data; + msg.cookie = cookie; + m_trkWriteQueue.append(msg); +} + +TrkWriteQueue::PendingMessageResult TrkWriteQueue::pendingMessage(TrkMessage *message) +{ + // Invoked from timer, try to flush out message queue + if (m_trkWriteBusy || m_trkWriteQueue.isEmpty()) + return NoMessage; + // Handle the noop message, just invoke CB in slot (ower thread) + if (m_trkWriteQueue.front().code == TRK_WRITE_QUEUE_NOOP_CODE) { + *message = m_trkWriteQueue.dequeue(); + return NoopMessageDequeued; + } + // Insert into map fir answers (as reading threads might get an + // answer before notifyWriteResult(true)) is called. + *message = m_trkWriteQueue.front(); + m_writtenTrkMessages.insert(message->token, *message); + m_trkWriteBusy = true; + return PendingMessage; +} + +void TrkWriteQueue::invokeNoopMessage(trk::TrkMessage noopMessage) +{ + TrkResult result; + result.code = noopMessage.code; + result.token = noopMessage.token; + result.data = noopMessage.data; + result.cookie = noopMessage.cookie; + noopMessage.callback(result); +} + +void TrkWriteQueue::notifyWriteResult(WriteResult wr) +{ + // On success, dequeue message and await result + const byte token = m_trkWriteQueue.front().token; + switch (wr) { + case WriteOk: + m_trkWriteQueue.dequeue(); + break; + case WriteFailedKeep: + case WriteFailedDiscard: + m_writtenTrkMessages.remove(token); + m_trkWriteBusy = false; + if (wr == WriteFailedDiscard) + m_trkWriteQueue.dequeue(); + break; + } +} + +void TrkWriteQueue::slotHandleResult(const TrkResult &result, QMutex *mutex) +{ + // Find which request the message belongs to and invoke callback + // if ACK or on NAK if desired. + if (mutex) + mutex->lock(); + m_trkWriteBusy = false; + const TokenMessageMap::iterator it = m_writtenTrkMessages.find(result.token); + if (it == m_writtenTrkMessages.end()) { + if (mutex) + mutex->unlock(); + return; + } + TrkCallback callback = it.value().callback; + const QVariant cookie = it.value().cookie; + m_writtenTrkMessages.erase(it); + if (mutex) + mutex->unlock(); + // Invoke callback + if (callback) { + TrkResult result1 = result; + result1.cookie = cookie; + callback(result1); + } +} + +void TrkWriteQueue::queueTrkInitialPing() +{ + // Ping, reset sequence count + m_trkWriteToken = 0; + m_trkWriteQueue.append(TrkMessage(TrkPing, 0)); +} + +/////////////////////////////////////////////////////////////////////// +// +// DeviceContext to be shared between threads +// +/////////////////////////////////////////////////////////////////////// + +struct DeviceContext { + DeviceContext(); +#ifdef Q_OS_WIN + HANDLE device; + OVERLAPPED readOverlapped; + OVERLAPPED writeOverlapped; +#else + QFile file; +#endif + bool serialFrame; + QMutex mutex; +}; + +DeviceContext::DeviceContext() : +#ifdef Q_OS_WIN + device(INVALID_HANDLE_VALUE), +#endif + serialFrame(true) +{ +} + +/////////////////////////////////////////////////////////////////////// +// +// TrkWriterThread: A thread operating a TrkWriteQueue. +// with exception of the handling of the TRK_WRITE_QUEUE_NOOP_CODE +// synchronization message. The invocation of the callback is then +// done by the thread owning the TrkWriteQueue, while pendingMessage() is called +// from another thread. This happens via a Qt::BlockingQueuedConnection. + +/////////////////////////////////////////////////////////////////////// + +class WriterThread : public QThread { + Q_OBJECT + Q_DISABLE_COPY(WriterThread) +public: + explicit WriterThread(const QSharedPointer &context); + + // Enqueue messages. + void queueTrkMessage(byte code, TrkCallback callback, + const QByteArray &data, const QVariant &cookie); + void queueTrkInitialPing(); + + // Call this from the device read notification with the results. + void slotHandleResult(const TrkResult &result); + + virtual void run(); + +signals: + void error(const QString &); + void internalNoopMessageDequeued(const trk::TrkMessage&); + +public slots: + bool trkWriteRawMessage(const TrkMessage &msg); + void terminate(); + void tryWrite(); + +private slots: + void invokeNoopMessage(const trk::TrkMessage &); + +private: + bool write(const QByteArray &data, QString *errorMessage); + inline int writePendingMessage(); + + const QSharedPointer m_context; + QMutex m_dataMutex; + QMutex m_waitMutex; + QWaitCondition m_waitCondition; + TrkWriteQueue m_queue; + bool m_terminate; +}; + +WriterThread::WriterThread(const QSharedPointer &context) : + m_context(context), + m_terminate(false) +{ + static const int trkMessageMetaId = qRegisterMetaType(); + Q_UNUSED(trkMessageMetaId) + connect(this, SIGNAL(internalNoopMessageDequeued(trk::TrkMessage)), + this, SLOT(invokeNoopMessage(trk::TrkMessage)), Qt::BlockingQueuedConnection); +} + +void WriterThread::run() +{ + while (writePendingMessage() == 0) ; +} + +int WriterThread::writePendingMessage() +{ + enum { MaxAttempts = 100, RetryIntervalMS = 200 }; + + // Wait. Use a timeout in case something is already queued before we + // start up or some weird hanging exit condition + m_waitMutex.lock(); + m_waitCondition.wait(&m_waitMutex, 100); + m_waitMutex.unlock(); + if (m_terminate) + return 1; + // Send off message + m_dataMutex.lock(); + TrkMessage message; + const TrkWriteQueue::PendingMessageResult pr = m_queue.pendingMessage(&message); + m_dataMutex.unlock(); + switch (pr) { + case TrkWriteQueue::NoMessage: + break; + case TrkWriteQueue::PendingMessage: { + // Untested: try to re-send a few times + bool success = false; + for (int r = 0; !success && (r < MaxAttempts); r++) { + success = trkWriteRawMessage(message); + if (!success) { + emit error(QString::fromLatin1("Write failure, attempt %1 of %2.").arg(r).arg(int(MaxAttempts))); + if (m_terminate) + return 1; + QThread::msleep(RetryIntervalMS); + } + } + // Notify queue. If still failed, give up. + m_dataMutex.lock(); + m_queue.notifyWriteResult(success ? TrkWriteQueue::WriteOk : TrkWriteQueue::WriteFailedDiscard); + m_dataMutex.unlock(); + } + break; + case TrkWriteQueue::NoopMessageDequeued: + // Sync with thread that owns us via a blocking signal + emit internalNoopMessageDequeued(message); + break; + } // switch + return 0; +} + +void WriterThread::invokeNoopMessage(const trk::TrkMessage &msg) +{ + TrkWriteQueue::invokeNoopMessage(msg); +} + +void WriterThread::terminate() +{ + m_terminate = true; + m_waitCondition.wakeAll(); + wait(); + m_terminate = false; +} + +#ifdef Q_OS_WIN + +static inline QString msgTerminated(int size) +{ + return QString::fromLatin1("Terminated with %1 bytes pending.").arg(size); +} + +// Interruptible synchronous write function. +static inline bool overlappedSyncWrite(HANDLE file, + const bool &terminateFlag, + const char *data, + DWORD size, DWORD *charsWritten, + OVERLAPPED *overlapped, + QString *errorMessage) +{ + if (WriteFile(file, data, size, charsWritten, overlapped)) + return true; + const DWORD writeError = GetLastError(); + if (writeError != ERROR_IO_PENDING) { + *errorMessage = QString::fromLatin1("WriteFile failed: %1").arg(winErrorMessage(writeError)); + return false; + } + // Wait for written or thread terminated + const DWORD timeoutMS = 200; + const unsigned maxAttempts = 20; + DWORD wr = WaitForSingleObject(overlapped->hEvent, timeoutMS); + for (unsigned n = 0; wr == WAIT_TIMEOUT && n < maxAttempts && !terminateFlag; + wr = WaitForSingleObject(overlapped->hEvent, timeoutMS), n++); + if (terminateFlag) { + *errorMessage = msgTerminated(size); + return false; + } + switch (wr) { + case WAIT_OBJECT_0: + break; + case WAIT_TIMEOUT: + *errorMessage = QString::fromLatin1("Write timed out."); + return false; + default: + *errorMessage = QString::fromLatin1("Error while waiting for WriteFile results: %1").arg(winErrorMessage(GetLastError())); + return false; + } + if (!GetOverlappedResult(file, overlapped, charsWritten, TRUE)) { + *errorMessage = QString::fromLatin1("Error writing %1 bytes: %2").arg(size).arg(winErrorMessage(GetLastError())); + return false; + } + return true; +} +#endif + +bool WriterThread::write(const QByteArray &data, QString *errorMessage) +{ + QMutexLocker locker(&m_context->mutex); +#ifdef Q_OS_WIN + DWORD charsWritten; + if (!overlappedSyncWrite(m_context->device, m_terminate, data.data(), data.size(), &charsWritten, &m_context->writeOverlapped, errorMessage)) { + return false; + } + FlushFileBuffers(m_context->device); + return true; +#else + if (m_context->file.write(data) == -1 || !m_context->file.flush()) { + *errorMessage = QString::fromLatin1("Cannot write: %1").arg(m_context->file.errorString()); + return false; + } + return true; +#endif +} + +bool WriterThread::trkWriteRawMessage(const TrkMessage &msg) +{ + const QByteArray ba = frameMessage(msg.code, msg.token, msg.data, m_context->serialFrame); + QString errorMessage; + const bool rc = write(ba, &errorMessage); + if (!rc) { + qWarning("%s\n", qPrintable(errorMessage)); + emit error(errorMessage); + } + return rc; +} + +void WriterThread::tryWrite() +{ + m_waitCondition.wakeAll(); +} + +void WriterThread::queueTrkMessage(byte code, TrkCallback callback, + const QByteArray &data, const QVariant &cookie) +{ + m_dataMutex.lock(); + m_queue.queueTrkMessage(code, callback, data, cookie); + m_dataMutex.unlock(); + tryWrite(); +} + +void WriterThread::queueTrkInitialPing() +{ + m_dataMutex.lock(); + m_queue.queueTrkInitialPing(); + m_dataMutex.unlock(); + tryWrite(); +} + +// Call this from the device read notification with the results. +void WriterThread::slotHandleResult(const TrkResult &result) +{ + m_queue.slotHandleResult(result, &m_dataMutex); + tryWrite(); // Have messages been enqueued in-between? +} + +/////////////////////////////////////////////////////////////////////// +// +// ReaderThreadBase: Base class for a thread that reads data from +// the device, decodes the messages and emit signals for the messages. +// A Qt::BlockingQueuedConnection should be used for the message signal +// to ensure messages are processed in the correct sequence. +// +/////////////////////////////////////////////////////////////////////// + +class ReaderThreadBase : public QThread { + Q_OBJECT + Q_DISABLE_COPY(ReaderThreadBase) +public: + +signals: + void messageReceived(const trk::TrkResult &result, const QByteArray &rawData); + +protected: + explicit ReaderThreadBase(const QSharedPointer &context); + void processData(const QByteArray &a); + void processData(char c); + + const QSharedPointer m_context; + +private: + void readMessages(); + + QByteArray m_trkReadBuffer; +}; + +ReaderThreadBase::ReaderThreadBase(const QSharedPointer &context) : + m_context(context) +{ + static const int trkResultMetaId = qRegisterMetaType(); + Q_UNUSED(trkResultMetaId) +} + +void ReaderThreadBase::processData(const QByteArray &a) +{ + m_trkReadBuffer += a; + readMessages(); +} + +void ReaderThreadBase::processData(char c) +{ + m_trkReadBuffer += c; + if (m_trkReadBuffer.size() > 1) + readMessages(); +} + +void ReaderThreadBase::readMessages() +{ + TrkResult r; + QByteArray rawData; + while (extractResult(&m_trkReadBuffer, m_context->serialFrame, &r, &rawData)) { + emit messageReceived(r, rawData); + } +} + +#ifdef Q_OS_WIN +/////////////////////////////////////////////////////////////////////// +// +// WinReaderThread: A thread reading from the device using Windows API. +// Waits on an overlapped I/O handle and an event that tells the thread to +// terminate. +// +/////////////////////////////////////////////////////////////////////// + +class WinReaderThread : public ReaderThreadBase { + Q_OBJECT + Q_DISABLE_COPY(WinReaderThread) +public: + explicit WinReaderThread(const QSharedPointer &context); + ~WinReaderThread(); + + virtual void run(); + +signals: + void error(const QString &); + +public slots: + void terminate(); + +private: + enum Handles { FileHandle, TerminateEventHandle, HandleCount }; + + inline int tryRead(); + + HANDLE m_handles[HandleCount]; +}; + +WinReaderThread::WinReaderThread(const QSharedPointer &context) : + ReaderThreadBase(context) +{ + m_handles[FileHandle] = NULL; + m_handles[TerminateEventHandle] = CreateEvent(NULL, FALSE, FALSE, NULL); +} + +WinReaderThread::~WinReaderThread() +{ + CloseHandle(m_handles[TerminateEventHandle]); +} + +// Return 0 to continue or error code +int WinReaderThread::tryRead() +{ + enum { BufSize = 1024 }; + char buffer[BufSize]; + // Check if there are already bytes waiting. If not, wait for first byte + COMSTAT comStat; + if (!ClearCommError(m_context->device, NULL, &comStat)){ + emit error(QString::fromLatin1("ClearCommError failed: %1").arg(winErrorMessage(GetLastError()))); + return -7; + } + const DWORD bytesToRead = qMax(DWORD(1), qMin(comStat.cbInQue, DWORD(BufSize))); + // Trigger read + DWORD bytesRead = 0; + if (ReadFile(m_context->device, &buffer, bytesToRead, &bytesRead, &m_context->readOverlapped)) { + if (bytesRead == 1) { + processData(buffer[0]); + } else { + processData(QByteArray(buffer, bytesRead)); + } + return 0; + } + const DWORD readError = GetLastError(); + if (readError != ERROR_IO_PENDING) { + emit error(QString::fromLatin1("Read error: %1").arg(winErrorMessage(readError))); + return -1; + } + // Wait for either termination or data + const DWORD wr = WaitForMultipleObjects(HandleCount, m_handles, false, INFINITE); + if (wr == WAIT_FAILED) { + emit error(QString::fromLatin1("Wait failed: %1").arg(winErrorMessage(GetLastError()))); + return -2; + } + if (wr - WAIT_OBJECT_0 == TerminateEventHandle) { + return 1; // Terminate + } + // Check data + if (!GetOverlappedResult(m_context->device, &m_context->readOverlapped, &bytesRead, true)) { + emit error(QString::fromLatin1("GetOverlappedResult failed: %1").arg(winErrorMessage(GetLastError()))); + return -3; + } + if (bytesRead == 1) { + processData(buffer[0]); + } else { + processData(QByteArray(buffer, bytesRead)); + } + return 0; +} + +void WinReaderThread::run() +{ + m_handles[FileHandle] = m_context->readOverlapped.hEvent; + while ( tryRead() == 0) ; +} + +void WinReaderThread::terminate() +{ + SetEvent(m_handles[TerminateEventHandle]); + wait(); +} + +typedef WinReaderThread ReaderThread; + +#else + +/////////////////////////////////////////////////////////////////////// +// +// UnixReaderThread: A thread reading from the device. +// Uses select() to wait and a special ioctl() to find out the number +// of bytes queued. For clean termination, the self-pipe trick is used. +// The class maintains a pipe, on whose read end the select waits besides +// the device file handle. To terminate, a byte is written to the pipe. +// +/////////////////////////////////////////////////////////////////////// + +static inline QString msgUnixCallFailedErrno(const char *func, int errorNumber) +{ + return QString::fromLatin1("Call to %1() failed: %2").arg(QLatin1String(func), QString::fromLocal8Bit(strerror(errorNumber))); +} + +class UnixReaderThread : public ReaderThreadBase { + Q_OBJECT + Q_DISABLE_COPY(UnixReaderThread) +public: + explicit UnixReaderThread(const QSharedPointer &context); + ~UnixReaderThread(); + + virtual void run(); + +signals: + void error(const QString &); + +public slots: + void terminate(); + +private: + inline int tryRead(); + + int m_terminatePipeFileDescriptors[2]; +}; + +UnixReaderThread::UnixReaderThread(const QSharedPointer &context) : + ReaderThreadBase(context) +{ + m_terminatePipeFileDescriptors[0] = m_terminatePipeFileDescriptors[1] = -1; + // Set up pipes for termination. Should not fail + if (pipe(m_terminatePipeFileDescriptors) < 0) + qWarning("%s\n", qPrintable(msgUnixCallFailedErrno("pipe", errno))); +} + +UnixReaderThread::~UnixReaderThread() +{ + close(m_terminatePipeFileDescriptors[0]); + close(m_terminatePipeFileDescriptors[1]); +} + +int UnixReaderThread::tryRead() +{ + fd_set readSet, tempReadSet, tempExceptionSet; + struct timeval timeOut; + const int fileDescriptor = m_context->file.handle(); + FD_ZERO(&readSet); + FD_SET(fileDescriptor, &readSet); + FD_SET(m_terminatePipeFileDescriptors[0], &readSet); + const int maxFileDescriptor = qMax(m_terminatePipeFileDescriptors[0], fileDescriptor); + int result = 0; + do { + memcpy(&tempReadSet, &readSet, sizeof(fd_set)); + memcpy(&tempExceptionSet, &readSet, sizeof(fd_set)); + timeOut.tv_sec = 1; + timeOut.tv_usec = 0; + result = select(maxFileDescriptor + 1, &tempReadSet, NULL, &tempExceptionSet, &timeOut); + } while ( result < 0 && errno == EINTR ); + // Timeout? + if (result == 0) + return 0; + // Something wrong? + if (result < 0) { + emit error(msgUnixCallFailedErrno("select", errno)); + return -1; + } + // Did the exception set trigger on the device? + if (FD_ISSET(fileDescriptor,&tempExceptionSet)) { + emit error(QLatin1String("An Exception occurred on the device.")); + return -2; + } + // Check termination pipe. + if (FD_ISSET(m_terminatePipeFileDescriptors[0], &tempReadSet) + || FD_ISSET(m_terminatePipeFileDescriptors[0], &tempExceptionSet)) + return 1; + + // determine number of pending bytes and read + int numBytes; + if (ioctl(fileDescriptor, FIONREAD, &numBytes) < 0) { + emit error(msgUnixCallFailedErrno("ioctl", errno)); + return -1; + } + m_context->mutex.lock(); + const QByteArray data = m_context->file.read(numBytes); + m_context->mutex.unlock(); + processData(data); + return 0; +} + +void UnixReaderThread::run() +{ + // Read loop + while (tryRead() == 0) + ; +} + +void UnixReaderThread::terminate() +{ + // Trigger select() by writing to the pipe + char c = 0; + write(m_terminatePipeFileDescriptors[1], &c, 1); + wait(); +} + +typedef UnixReaderThread ReaderThread; + +#endif + +/////////////////////////////////////////////////////////////////////// +// +// TrkDevicePrivate +// +/////////////////////////////////////////////////////////////////////// + +struct TrkDevicePrivate +{ + TrkDevicePrivate(); + + QSharedPointer deviceContext; + QSharedPointer writerThread; + QSharedPointer readerThread; + + QByteArray trkReadBuffer; + int verbose; + QString errorString; +}; + +/////////////////////////////////////////////////////////////////////// +// +// TrkDevice +// +/////////////////////////////////////////////////////////////////////// + +TrkDevicePrivate::TrkDevicePrivate() : + deviceContext(new DeviceContext), + verbose(0) +{ +} + +/////////////////////////////////////////////////////////////////////// +// +// TrkDevice +// +/////////////////////////////////////////////////////////////////////// + +TrkDevice::TrkDevice(QObject *parent) : + QObject(parent), + d(new TrkDevicePrivate) +{} + +TrkDevice::~TrkDevice() +{ + close(); + delete d; +} + +bool TrkDevice::open(const QString &port, QString *errorMessage) +{ + if (d->verbose) + qDebug() << "Opening" << port << "is open: " << isOpen() << " serialFrame=" << serialFrame(); + close(); +#ifdef Q_OS_WIN + d->deviceContext->device = CreateFile(port.toStdWString().c_str(), + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING|FILE_FLAG_OVERLAPPED, + NULL); + + if (INVALID_HANDLE_VALUE == d->deviceContext->device) { + *errorMessage = QString::fromLatin1("Could not open device '%1': %2").arg(port, winErrorMessage(GetLastError())); + return false; + } + memset(&d->deviceContext->readOverlapped, 0, sizeof(OVERLAPPED)); + d->deviceContext->readOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + memset(&d->deviceContext->writeOverlapped, 0, sizeof(OVERLAPPED)); + d->deviceContext->writeOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (d->deviceContext->readOverlapped.hEvent == NULL || d->deviceContext->writeOverlapped.hEvent == NULL) { + *errorMessage = QString::fromLatin1("Failed to create events: %1").arg(winErrorMessage(GetLastError())); + return false; + } +#else + d->deviceContext->file.setFileName(port); + if (!d->deviceContext->file.open(QIODevice::ReadWrite|QIODevice::Unbuffered)) { + *errorMessage = QString::fromLatin1("Cannot open %1: %2").arg(port, d->deviceContext->file.errorString()); + return false; + } + + struct termios termInfo; + if (tcgetattr(d->deviceContext->file.handle(), &termInfo) < 0) { + *errorMessage = QString::fromLatin1("Unable to retrieve terminal settings: %1 %2").arg(errno).arg(QString::fromAscii(strerror(errno))); + return false; + } + // Turn off terminal echo as not get messages back, among other things + termInfo.c_cflag |= CREAD|CLOCAL; + termInfo.c_lflag &= (~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG)); + termInfo.c_iflag &= (~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY)); + termInfo.c_oflag &= (~OPOST); + termInfo.c_cc[VMIN] = 0; + termInfo.c_cc[VINTR] = _POSIX_VDISABLE; + termInfo.c_cc[VQUIT] = _POSIX_VDISABLE; + termInfo.c_cc[VSTART] = _POSIX_VDISABLE; + termInfo.c_cc[VSTOP] = _POSIX_VDISABLE; + termInfo.c_cc[VSUSP] = _POSIX_VDISABLE; + if (tcsetattr(d->deviceContext->file.handle(), TCSAFLUSH, &termInfo) < 0) { + *errorMessage = QString::fromLatin1("Unable to apply terminal settings: %1 %2").arg(errno).arg(QString::fromAscii(strerror(errno))); + return false; + } +#endif + d->readerThread = QSharedPointer(new ReaderThread(d->deviceContext)); + connect(d->readerThread.data(), SIGNAL(error(QString)), this, SLOT(emitError(QString)), + Qt::QueuedConnection); + connect(d->readerThread.data(), SIGNAL(messageReceived(trk::TrkResult,QByteArray)), + this, SLOT(slotMessageReceived(trk::TrkResult,QByteArray)), + Qt::QueuedConnection); + d->readerThread->start(); + + d->writerThread = QSharedPointer(new WriterThread(d->deviceContext)); + connect(d->writerThread.data(), SIGNAL(error(QString)), this, SLOT(emitError(QString)), + Qt::QueuedConnection); + d->writerThread->start(); + + if (d->verbose) + qDebug() << "Opened" << port; + return true; +} + +void TrkDevice::close() +{ + if (!isOpen()) + return; + if (d->readerThread) + d->readerThread->terminate(); + if (d->writerThread) + d->writerThread->terminate(); +#ifdef Q_OS_WIN + CloseHandle(d->deviceContext->device); + d->deviceContext->device = INVALID_HANDLE_VALUE; + CloseHandle(d->deviceContext->readOverlapped.hEvent); + CloseHandle(d->deviceContext->writeOverlapped.hEvent); + d->deviceContext->readOverlapped.hEvent = d->deviceContext->writeOverlapped.hEvent = NULL; +#else + d->deviceContext->file.close(); +#endif + if (d->verbose) + emitLogMessage("Close"); +} + +bool TrkDevice::isOpen() const +{ +#ifdef Q_OS_WIN + return d->deviceContext->device != INVALID_HANDLE_VALUE; +#else + return d->deviceContext->file.isOpen(); +#endif +} + +QString TrkDevice::errorString() const +{ + return d->errorString; +} + +bool TrkDevice::serialFrame() const +{ + return d->deviceContext->serialFrame; +} + +void TrkDevice::setSerialFrame(bool f) +{ + d->deviceContext->serialFrame = f; +} + +int TrkDevice::verbose() const +{ + return d->verbose; +} + +void TrkDevice::setVerbose(int b) +{ + d->verbose = b; +} + +void TrkDevice::slotMessageReceived(const trk::TrkResult &result, const QByteArray &rawData) +{ + d->writerThread->slotHandleResult(result); + emit messageReceived(result); + if (!rawData.isEmpty()) + emit rawDataReceived(rawData); +} + +void TrkDevice::emitError(const QString &s) +{ + d->errorString = s; + qWarning("%s\n", qPrintable(s)); + emit error(s); +} + +void TrkDevice::sendTrkMessage(byte code, TrkCallback callback, + const QByteArray &data, const QVariant &cookie) +{ + if (!d->writerThread.isNull()) { + if (d->verbose > 1) + qDebug() << "Sending " << code << data.toHex(); + d->writerThread->queueTrkMessage(code, callback, data, cookie); + } +} + +void TrkDevice::sendTrkInitialPing() +{ + if (!d->writerThread.isNull()) + d->writerThread->queueTrkInitialPing(); +} + +bool TrkDevice::sendTrkAck(byte token) +{ + if (d->writerThread.isNull()) + return false; + // The acknowledgement must not be queued! + TrkMessage msg(0x80, token); + msg.token = token; + msg.data.append('\0'); + return d->writerThread->trkWriteRawMessage(msg); + // 01 90 00 07 7e 80 01 00 7d 5e 7e +} + +void TrkDevice::emitLogMessage(const QString &msg) +{ + if (d->verbose) + qDebug("%s\n", qPrintable(msg)); + emit logMessage(msg); +} + +} // namespace trk + +#include "trkdevice.moc" diff --git a/tools/runonphone/trk/trkdevice.h b/tools/runonphone/trk/trkdevice.h new file mode 100644 index 0000000..632dea1 --- /dev/null +++ b/tools/runonphone/trk/trkdevice.h @@ -0,0 +1,121 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef TRKDEVICE_H +#define TRKDEVICE_H + +#include "callback.h" + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QIODevice; +QT_END_NAMESPACE + +namespace trk { + +struct TrkResult; +struct TrkMessage; +struct TrkDevicePrivate; + +/* TrkDevice: Implements a Windows COM or Linux device for + * Trk communications. Provides synchronous write and asynchronous + * read operation. + * The serialFrames property specifies whether packets are encapsulated in + * "0x90 " frames, which is currently the case for serial ports. + * Contains a write message queue allowing + * for queueing messages with a notification callback. If the message receives + * an ACK, the callback is invoked. + * The special message TRK_WRITE_QUEUE_NOOP_CODE code can be used for synchronisation. + * The respective message will not be sent, the callback is just invoked. */ + +enum { TRK_WRITE_QUEUE_NOOP_CODE = 0x7f }; + +typedef trk::Callback TrkCallback; + +class TrkDevice : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool serialFrame READ serialFrame WRITE setSerialFrame) + Q_PROPERTY(bool verbose READ verbose WRITE setVerbose) +public: + explicit TrkDevice(QObject *parent = 0); + virtual ~TrkDevice(); + + bool open(const QString &port, QString *errorMessage); + bool isOpen() const; + + QString errorString() const; + + bool serialFrame() const; + void setSerialFrame(bool f); + + int verbose() const; + void setVerbose(int b); + + // Enqueue a message with a notification callback. + void sendTrkMessage(unsigned char code, + TrkCallback callBack = TrkCallback(), + const QByteArray &data = QByteArray(), + const QVariant &cookie = QVariant()); + + // Enqeue an initial ping + void sendTrkInitialPing(); + + // Send an Ack synchronously, bypassing the queue + bool sendTrkAck(unsigned char token); + +signals: + void messageReceived(const trk::TrkResult &result); + // Emitted with the contents of messages enclosed in 07e, not for log output + void rawDataReceived(const QByteArray &data); + void error(const QString &msg); + void logMessage(const QString &msg); + +private slots: + void slotMessageReceived(const trk::TrkResult &result, const QByteArray &a); + +protected slots: + void emitError(const QString &msg); + void emitLogMessage(const QString &msg); + +public slots: + void close(); + +private: + void readMessages(); + TrkDevicePrivate *d; +}; + +} // namespace trk + +#endif // TRKDEVICE_H diff --git a/tools/runonphone/trk/trkutils.cpp b/tools/runonphone/trk/trkutils.cpp new file mode 100644 index 0000000..256d4ad --- /dev/null +++ b/tools/runonphone/trk/trkutils.cpp @@ -0,0 +1,474 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "trkutils.h" +#include + +#include +#include +#include +#include +#include + +#define logMessage(s) do { qDebug() << "TRKCLIENT: " << s; } while (0) + +namespace trk { + +TrkAppVersion::TrkAppVersion() +{ + reset(); +} + +void TrkAppVersion::reset() +{ + trkMajor = trkMinor= protocolMajor = protocolMinor = 0; +} + +Session::Session() +{ + reset(); +} + +void Session::reset() +{ + cpuMajor = 0; + cpuMinor = 0; + bigEndian = 0; + defaultTypeSize = 0; + fpTypeSize = 0; + extended1TypeSize = 0; + extended2TypeSize = 0; + pid = 0; + tid = 0; + codeseg = 0; + dataseg = 0; + + currentThread = 0; + libraries.clear(); + trkAppVersion.reset(); +} + +QString formatCpu(int major, int minor) +{ + //: CPU description of an S60 device + //: %1 major verison, %2 minor version + //: %3 real name of major verison, %4 real name of minor version + const QString str = QCoreApplication::translate("trk::Session", "CPU: v%1.%2%3%4"); + QString majorStr; + QString minorStr; + switch (major) { + case 0x04: + majorStr = " ARM"; + break; + } + switch (minor) { + case 0x00: + minorStr = " 920T"; + break; + } + return str.arg(major).arg(minor).arg(majorStr).arg(minorStr); + } + +QString formatTrkVersion(const TrkAppVersion &version) +{ + QString str = QCoreApplication::translate("trk::Session", + "App TRK: v%1.%2 TRK protocol: v%3.%4"); + str = str.arg(version.trkMajor).arg(version.trkMinor); + return str.arg(version.protocolMajor).arg(version.protocolMinor); +} + +QString Session::deviceDescription(unsigned verbose) const +{ + if (!cpuMajor) + return QString(); + + //: s60description + //: description of an S60 device + //: %1 CPU description, %2 endianness + //: %3 default type size (if any), %4 float size (if any) + //: %5 TRK version + QString msg = QCoreApplication::translate("trk::Session", "%1, %2%3%4, %5"); + QString endianness = bigEndian + ? QCoreApplication::translate("trk::Session", "big endian") + : QCoreApplication::translate("trk::Session", "little endian"); + msg = msg.arg(formatCpu(cpuMajor, cpuMinor)).arg(endianness); + //: The separator in a list of strings + QString defaultTypeSizeStr; + QString fpTypeSizeStr; + if (verbose && defaultTypeSize) + //: will be inserted into s60description + defaultTypeSizeStr = QCoreApplication::translate("trk::Session", ", type size: %1").arg(defaultTypeSize); + if (verbose && fpTypeSize) + //: will be inserted into s60description + fpTypeSizeStr = QCoreApplication::translate("trk::Session", ", float size: %1").arg(fpTypeSize); + msg = msg.arg(defaultTypeSizeStr).arg(fpTypeSizeStr); + return msg.arg(formatTrkVersion(trkAppVersion)); +} + + +// FIXME: Use the QByteArray based version below? +QString stringFromByte(byte c) +{ + return QString("%1 ").arg(c, 2, 16, QChar('0')); +} + +QString stringFromArray(const QByteArray &ba, int maxLen) +{ + QString str; + QString ascii; + const int size = maxLen == -1 ? ba.size() : qMin(ba.size(), maxLen); + for (int i = 0; i < size; ++i) { + //if (i == 5 || i == ba.size() - 2) + // str += " "; + int c = byte(ba.at(i)); + str += QString("%1 ").arg(c, 2, 16, QChar('0')); + if (i >= 8 && i < ba.size() - 2) + ascii += QChar(c).isPrint() ? QChar(c) : QChar('.'); + } + if (size != ba.size()) { + str += "..."; + ascii += "..."; + } + return str + " " + ascii; +} + +QByteArray hexNumber(uint n, int digits) +{ + QByteArray ba = QByteArray::number(n, 16); + if (digits == 0 || ba.size() == digits) + return ba; + return QByteArray(digits - ba.size(), '0') + ba; +} + +QByteArray hexxNumber(uint n, int digits) +{ + return "0x" + hexNumber(n, digits); +} + +TrkResult::TrkResult() : + code(0), + token(0), + isDebugOutput(false) +{ +} + +void TrkResult::clear() +{ + code = token= 0; + isDebugOutput = false; + data.clear(); + cookie = QVariant(); +} + +QString TrkResult::toString() const +{ + QString res = stringFromByte(code) + "[" + stringFromByte(token); + res.chop(1); + return res + "] " + stringFromArray(data); +} + +QByteArray frameMessage(byte command, byte token, const QByteArray &data, bool serialFrame) +{ + byte s = command + token; + for (int i = 0; i != data.size(); ++i) + s += data.at(i); + byte checksum = 255 - (s & 0xff); + //int x = s + ~s; + //logMessage("check: " << s << checksum << x; + + QByteArray response; + response.reserve(data.size() + 3); + response.append(char(command)); + response.append(char(token)); + response.append(data); + response.append(char(checksum)); + + QByteArray encodedData = encode7d(response); + + QByteArray ba; + ba.reserve(encodedData.size() + 6); + if (serialFrame) { + ba.append(char(0x01)); + ba.append(char(0x90)); + const ushort encodedSize = encodedData.size() + 2; // 2 x 0x7e + appendShort(&ba, encodedSize, BigEndian); + } + ba.append(char(0x7e)); + ba.append(encodedData); + ba.append(char(0x7e)); + + return ba; +} + +/* returns 0 if array doesn't represent a result, +otherwise returns the length of the result data */ +ushort isValidTrkResult(const QByteArray &buffer, bool serialFrame) +{ + if (serialFrame) { + // Serial protocol with length info + if (buffer.length() < 4) + return 0; + if (buffer.at(0) != 0x01 || byte(buffer.at(1)) != 0x90) + return 0; + const ushort len = extractShort(buffer.data() + 2); + return (buffer.size() >= len + 4) ? len : ushort(0); + } + // Frameless protocol without length info + const char delimiter = char(0x7e); + const int firstDelimiterPos = buffer.indexOf(delimiter); + // Regular message delimited by 0x7e..0x7e + if (firstDelimiterPos == 0) { + const int endPos = buffer.indexOf(delimiter, firstDelimiterPos + 1); + return endPos != -1 ? endPos + 1 - firstDelimiterPos : 0; + } + // Some ASCII log message up to first delimiter or all + return firstDelimiterPos != -1 ? firstDelimiterPos : buffer.size(); +} + +bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *result, QByteArray *rawData) +{ + result->clear(); + if(rawData) + rawData->clear(); + const ushort len = isValidTrkResult(*buffer, serialFrame); + if (!len) + return false; + // handle receiving application output, which is not a regular command + const int delimiterPos = serialFrame ? 4 : 0; + if (buffer->at(delimiterPos) != 0x7e) { + result->isDebugOutput = true; + result->data = buffer->mid(delimiterPos, len); + result->data.replace("\r\n", "\n"); + *buffer->remove(0, delimiterPos + len); + return true; + } + // FIXME: what happens if the length contains 0xfe? + // Assume for now that it passes unencoded! + const QByteArray data = decode7d(buffer->mid(delimiterPos + 1, len - 2)); + if(rawData) + *rawData = data; + *buffer->remove(0, delimiterPos + len); + + byte sum = 0; + for (int i = 0; i < data.size(); ++i) // 3 = 2 * 0xfe + sum + sum += byte(data.at(i)); + if (sum != 0xff) + logMessage("*** CHECKSUM ERROR: " << byte(sum)); + + result->code = data.at(0); + result->token = data.at(1); + result->data = data.mid(2, data.size() - 3); + //logMessage(" REST BUF: " << stringFromArray(*buffer)); + //logMessage(" CURR DATA: " << stringFromArray(data)); + //QByteArray prefix = "READ BUF: "; + //logMessage((prefix + "HEADER: " + stringFromArray(header).toLatin1()).data()); + return true; +} + +ushort extractShort(const char *data) +{ + return byte(data[0]) * 256 + byte(data[1]); +} + +uint extractInt(const char *data) +{ + uint res = byte(data[0]); + res *= 256; res += byte(data[1]); + res *= 256; res += byte(data[2]); + res *= 256; res += byte(data[3]); + return res; +} + +QString quoteUnprintableLatin1(const QByteArray &ba) +{ + QString res; + char buf[10]; + for (int i = 0, n = ba.size(); i != n; ++i) { + const byte c = ba.at(i); + if (isprint(c)) { + res += c; + } else { + qsnprintf(buf, sizeof(buf) - 1, "\\%x", int(c)); + res += buf; + } + } + return res; +} + +QByteArray decode7d(const QByteArray &ba) +{ + QByteArray res; + res.reserve(ba.size()); + for (int i = 0; i < ba.size(); ++i) { + byte c = byte(ba.at(i)); + if (c == 0x7d) { + ++i; + c = 0x20 ^ byte(ba.at(i)); + } + res.append(c); + } + //if (res != ba) + // logMessage("DECODED: " << stringFromArray(ba) + // << " -> " << stringFromArray(res)); + return res; +} + +QByteArray encode7d(const QByteArray &ba) +{ + QByteArray res; + res.reserve(ba.size() + 2); + for (int i = 0; i < ba.size(); ++i) { + byte c = byte(ba.at(i)); + if (c == 0x7e || c == 0x7d) { + res.append(0x7d); + res.append(0x20 ^ c); + } else { + res.append(c); + } + } + //if (res != ba) + // logMessage("ENCODED: " << stringFromArray(ba) + // << " -> " << stringFromArray(res)); + return res; +} + +void appendByte(QByteArray *ba, byte b) +{ + ba->append(b); +} + +void appendShort(QByteArray *ba, ushort s, Endianness endian) +{ + if (endian == BigEndian) { + ba->append(s / 256); + ba->append(s % 256); + } else { + ba->append(s % 256); + ba->append(s / 256); + } +} + +void appendInt(QByteArray *ba, uint i, Endianness endian) +{ + const uchar b3 = i % 256; i /= 256; + const uchar b2 = i % 256; i /= 256; + const uchar b1 = i % 256; i /= 256; + const uchar b0 = i; + ba->reserve(ba->size() + 4); + if (endian == BigEndian) { + ba->append(b0); + ba->append(b1); + ba->append(b2); + ba->append(b3); + } else { + ba->append(b3); + ba->append(b2); + ba->append(b1); + ba->append(b0); + } +} + +void appendString(QByteArray *ba, const QByteArray &str, Endianness endian, bool appendNullTerminator) +{ + const int fullSize = str.size() + (appendNullTerminator ? 1 : 0); + appendShort(ba, fullSize, endian); // count the terminating \0 + ba->append(str); + if (appendNullTerminator) + ba->append('\0'); +} + +void appendDateTime(QByteArray *ba, QDateTime dateTime, Endianness endian) +{ + // convert the QDateTime to UTC and append its representation to QByteArray + // format is the same as in FAT file system + dateTime = dateTime.toUTC(); + const QTime utcTime = dateTime.time(); + const QDate utcDate = dateTime.date(); + uint fatDateTime = (utcTime.hour() << 11 | utcTime.minute() << 5 | utcTime.second()/2) << 16; + fatDateTime |= (utcDate.year()-1980) << 9 | utcDate.month() << 5 | utcDate.day(); + appendInt(ba, fatDateTime, endian); +} + +QByteArray errorMessage(byte code) +{ + switch (code) { + case 0x00: return "No error"; + case 0x01: return "Generic error in CWDS message"; + case 0x02: return "Unexpected packet size in send msg"; + case 0x03: return "Internal error occurred in CWDS"; + case 0x04: return "Escape followed by frame flag"; + case 0x05: return "Bad FCS in packet"; + case 0x06: return "Packet too long"; + case 0x07: return "Sequence ID not expected (gap in sequence)"; + + case 0x10: return "Command not supported"; + case 0x11: return "Command param out of range"; + case 0x12: return "An option was not supported"; + case 0x13: return "Read/write to invalid memory"; + case 0x14: return "Read/write invalid registers"; + case 0x15: return "Exception occurred in CWDS"; + case 0x16: return "Targeted system or thread is running"; + case 0x17: return "Breakpoint resources (HW or SW) exhausted"; + case 0x18: return "Requested breakpoint conflicts with existing one"; + + case 0x20: return "General OS-related error"; + case 0x21: return "Request specified invalid process"; + case 0x22: return "Request specified invalid thread"; + } + return "Unknown error"; +} + +uint swapEndian(uint in) +{ + return (in>>24) | ((in<<8) & 0x00FF0000) | ((in>>8) & 0x0000FF00) | (in<<24); +} + +int TrkResult::errorCode() const +{ + // NAK means always error, else data sized 1 with a non-null element + const bool isNAK = code == 0xff; + if (data.size() != 1 && !isNAK) + return 0; + if (const int errorCode = data.at(0)) + return errorCode; + return isNAK ? 0xff : 0; +} + +QString TrkResult::errorString() const +{ + // NAK means always error, else data sized 1 with a non-null element + if (code == 0xff) + return "NAK"; + if (data.size() < 1) + return "Unknown error packet"; + return errorMessage(data.at(0)); +} + +} // namespace trk + diff --git a/tools/runonphone/trk/trkutils.h b/tools/runonphone/trk/trkutils.h new file mode 100644 index 0000000..4ba51fa --- /dev/null +++ b/tools/runonphone/trk/trkutils.h @@ -0,0 +1,177 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef DEBUGGER_TRK_UTILS +#define DEBUGGER_TRK_UTILS + +#include +#include +#include +#include + +typedef unsigned char byte; + +QT_BEGIN_NAMESPACE +class QDateTime; +QT_END_NAMESPACE + +namespace trk { + +enum Command { + TrkPing = 0x00, + TrkConnect = 0x01, + TrkDisconnect = 0x02, + TrkVersions = 0x04, + TrkSupported = 0x05, + TrkCpuType = 0x06, + TrkHostVersions = 0x09, + TrkContinue = 0x18, + TrkCreateItem = 0x40, + TrkDeleteItem = 0x41, + + TrkWriteFile = 0x48, + TrkOpenFile = 0x4a, + TrkCloseFile = 0x4b, + TrkInstallFile = 0x4d, + TrkInstallFile2 = 0x4e, + + TrkNotifyAck = 0x80, + TrkNotifyNak = 0xff, + TrkNotifyStopped = 0x90, + TrkNotifyException = 0x91, + TrkNotifyInternalError = 0x92, + TrkNotifyCreated = 0xa0, + TrkNotifyDeleted = 0xa1, + TrkNotifyProcessorStarted = 0xa2, + TrkNotifyProcessorStandBy = 0xa6, + TrkNotifyProcessorReset = 0xa7 +}; + +QByteArray decode7d(const QByteArray &ba); +QByteArray encode7d(const QByteArray &ba); + +inline byte extractByte(const char *data) { return *data; } +ushort extractShort(const char *data); +uint extractInt(const char *data); + +QString quoteUnprintableLatin1(const QByteArray &ba); + +// produces "xx xx xx " +QString stringFromArray(const QByteArray &ba, int maxLen = - 1); + +enum Endianness +{ + LittleEndian, + BigEndian, + TargetByteOrder = BigEndian, +}; + +void appendByte(QByteArray *ba, byte b); +void appendShort(QByteArray *ba, ushort s, Endianness = TargetByteOrder); +void appendInt(QByteArray *ba, uint i, Endianness = TargetByteOrder); +void appendString(QByteArray *ba, const QByteArray &str, Endianness = TargetByteOrder, bool appendNullTerminator = true); +void appendDateTime(QByteArray *ba, QDateTime dateTime, Endianness = TargetByteOrder); + +struct Library +{ + Library() {} + + QByteArray name; + uint codeseg; + uint dataseg; +}; + +struct TrkAppVersion { + TrkAppVersion(); + void reset(); + + int trkMajor; + int trkMinor; + int protocolMajor; + int protocolMinor; +}; + +struct Session +{ + Session(); + void reset(); + QString deviceDescription(unsigned verbose) const; + + // Trk feedback + byte cpuMajor; + byte cpuMinor; + byte bigEndian; + byte defaultTypeSize; + byte fpTypeSize; + byte extended1TypeSize; + byte extended2TypeSize; + TrkAppVersion trkAppVersion; + uint pid; + uint tid; + uint codeseg; + uint dataseg; + QHash addressToBP; + + typedef QList Libraries; + Libraries libraries; + + // Gdb request + uint currentThread; + QStringList modules; +}; + +struct TrkResult +{ + TrkResult(); + void clear(); + QString toString() const; + // 0 for no error. + int errorCode() const; + QString errorString() const; + + byte code; + byte token; + QByteArray data; + QVariant cookie; + bool isDebugOutput; +}; + +// returns a QByteArray containing optionally +// the serial frame [0x01 0x90 ] and 0x7e encoded7d(ba) 0x7e +QByteArray frameMessage(byte command, byte token, const QByteArray &data, bool serialFrame); +ushort isValidTrkResult(const QByteArray &buffer, bool serialFrame); +bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *r, QByteArray *rawData = 0); +QByteArray errorMessage(byte code); +QByteArray hexNumber(uint n, int digits = 0); +QByteArray hexxNumber(uint n, int digits = 0); // prepends '0x', too +uint swapEndian(uint in); + +} // namespace trk + +#endif // DEBUGGER_TRK_UTILS diff --git a/tools/runonphone/trksignalhandler.cpp b/tools/runonphone/trksignalhandler.cpp new file mode 100644 index 0000000..15282dd --- /dev/null +++ b/tools/runonphone/trksignalhandler.cpp @@ -0,0 +1,108 @@ +/************************************************************************** +** +** This file is part of the tools applications of the Qt Toolkit. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ +#include +#include +#include "trksignalhandler.h" + +void TrkSignalHandler::copyingStarted() +{ + qDebug() << "Copying...\n"; +} + +void TrkSignalHandler::canNotConnect(const QString &errorMessage) +{ + qWarning() << "Cannot Connect - " << errorMessage; +} + +void TrkSignalHandler::canNotCreateFile(const QString &filename, const QString &errorMessage) +{ + qWarning() << "Cannot create file (" << filename << ") - " << errorMessage << "\n"; +} + +void TrkSignalHandler::canNotWriteFile(const QString &filename, const QString &errorMessage) +{ + qWarning() << "Cannot write file (" << filename << ") - " << errorMessage << "\n"; +} + +void TrkSignalHandler::canNotCloseFile(const QString &filename, const QString &errorMessage) +{ + qWarning() << "Cannot close file (" << filename << ") - " << errorMessage << "\n"; +} + +void TrkSignalHandler::installingStarted() +{ + qDebug() << "Installing...\n"; +} + +void TrkSignalHandler::canNotInstall(const QString &packageFilename, const QString &errorMessage) +{ + qWarning() << "Cannot install file (" << packageFilename << ") - " << errorMessage << "\n"; +} + +void TrkSignalHandler::installingFinished() +{ + qDebug() << "Installing finished\n"; +} + +void TrkSignalHandler::startingApplication() +{ + qDebug() << "Starting app...\n"; +} + +void TrkSignalHandler::applicationRunning(uint pid) +{ + qDebug() << "Running...\n"; +} + +void TrkSignalHandler::canNotRun(const QString &errorMessage) +{ + qWarning() << "Cannot run - " << errorMessage << "\n"; +} + +void TrkSignalHandler::finished() +{ + qDebug() << "Done.\n"; + QCoreApplication::quit(); +} + +void TrkSignalHandler::applicationOutputReceived(const QString &output) +{ + qDebug() << "> " << output; +} + +void TrkSignalHandler::copyProgress(int percent) +{ + qDebug() << percent << "%"; +} + +void TrkSignalHandler::stateChanged(int state) +{ + qDebug() << "State" << state; +} + diff --git a/tools/runonphone/trksignalhandler.h b/tools/runonphone/trksignalhandler.h new file mode 100644 index 0000000..1c40a17 --- /dev/null +++ b/tools/runonphone/trksignalhandler.h @@ -0,0 +1,55 @@ +/************************************************************************** +** +** This file is part of the tools applications of the Qt Toolkit. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ +#ifndef TRKSIGNALHANDLER_H +#define TRKSIGNALHANDLER_H +#include +#include + +class TrkSignalHandler : public QObject +{ + Q_OBJECT +public slots: + void copyingStarted(); + void canNotConnect(const QString &errorMessage); + void canNotCreateFile(const QString &filename, const QString &errorMessage); + void canNotWriteFile(const QString &filename, const QString &errorMessage); + void canNotCloseFile(const QString &filename, const QString &errorMessage); + void installingStarted(); + void canNotInstall(const QString &packageFilename, const QString &errorMessage); + void installingFinished(); + void startingApplication(); + void applicationRunning(uint pid); + void canNotRun(const QString &errorMessage); + void finished(); + void applicationOutputReceived(const QString &output); + void copyProgress(int percent); + void stateChanged(int); +}; + +#endif // TRKSIGNALHANDLER_H -- cgit v0.12 From 020b10e8288c981bffe1a6470ece25ec6c532b73 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Mon, 21 Dec 2009 13:45:18 +0100 Subject: Drag and drop icon not updated correctly in Cocoa. QDragMoveEvent is compressed using the answer rect in QCocoaView. The result of the last sendEvent is saved, so that we dont have to generate a new event always. This saved result was not updated correctly when the event was ignored. Task-number: QTBUG-5186 Reviewed-by: Richard Moe Gustavsen --- src/gui/kernel/qcocoaview_mac.mm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 6c06746..3352dbd 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -349,7 +349,9 @@ extern "C" { // since we accepted the drag enter event, the widget expects // future drage move events. // ### check if we need to treat this like the drag enter event. - nsActions = QT_PREPEND_NAMESPACE(qt_mac_mapDropAction)(qDEEvent.dropAction()); + nsActions = NSDragOperationNone; + // Save as ignored in the answer rect. + qDMEvent.setDropAction(Qt::IgnoreAction); } else { nsActions = QT_PREPEND_NAMESPACE(qt_mac_mapDropAction)(qDMEvent.dropAction()); } @@ -357,7 +359,6 @@ extern "C" { return nsActions; } } - - (NSDragOperation)draggingUpdated:(id < NSDraggingInfo >)sender { NSPoint windowPoint = [sender draggingLocation]; @@ -402,13 +403,15 @@ extern "C" { qDMEvent.setDropAction(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).lastAction); qDMEvent.accept(); QApplication::sendEvent(qwidget, &qDMEvent); - qt_mac_copy_answer_rect(qDMEvent); NSDragOperation operation = qt_mac_mapDropAction(qDMEvent.dropAction()); if (!qDMEvent.isAccepted() || qDMEvent.dropAction() == Qt::IgnoreAction) { // ignore this event (we will still receive further notifications) operation = NSDragOperationNone; + // Save as ignored in the answer rect. + qDMEvent.setDropAction(Qt::IgnoreAction); } + qt_mac_copy_answer_rect(qDMEvent); return operation; } -- cgit v0.12 From 3f0a7ff17d6dba19ab3d73e3336990bedbfe14e7 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 21 Dec 2009 21:21:18 +0100 Subject: Updated WebKit from /home/shausman/src/webkit/trunk to qtwebkit/qtwebkit-4.6 ( de77f8ee69c434bde9306c8f407ee2e443a00188 ) Changes in WebKit/qt since the last update: ++ b/WebKit/qt/ChangeLog 2009-12-21 David Boddie Reviewed by Simon Hausmann. Doc: Minor fixes to language. * Api/qwebpage.cpp: 2009-12-15 Holger Hans Peter Freyther Reviewed by NOBODY (OOPS!). [Qt] Do not disable the inspector on show and hide https://bugs.webkit.org/show_bug.cgi?id=31851 On Qt/X11 with some window managers the window will be hidden when switching windows. In this case all the results are gone when coming back to the window. Attempt to use the CloseEvent to figure out if the window was closed and withdrawn as this is more friendly to the user of the inspector client. * Api/qwebinspector.cpp: (QWebInspector::event): (QWebInspector::hideEvent): 2009-12-13 Simon Hausmann Reviewed by Holger Freyther. [Qt] Re-enable QWebView::renderHints property for Qt for Symbian https://bugs.webkit.org/show_bug.cgi?id=28273 The bug in Qt's moc that triggered a linking error when declaring this property has been fixed and we can remove the workaround. * Api/qwebview.h: 2009-11-30 Abhinav Mithal Reviewed by Simon Hausmann. [Qt][Symbian] Report SymbianOS in user agent string for Symbian https://bugs.webkit.org/show_bug.cgi?id=31961 * Api/qwebpage.cpp: (QWebPage::userAgentForUrl): --- src/3rdparty/webkit/VERSION | 2 +- src/3rdparty/webkit/WebCore/ChangeLog | 13 +++++ .../webkit/WebCore/svg/graphics/SVGImage.cpp | 5 ++ .../webkit/WebCore/svg/graphics/SVGImage.h | 2 + .../webkit/WebKit/qt/Api/qwebinspector.cpp | 5 +- src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp | 56 ++++++++++++++++++++-- src/3rdparty/webkit/WebKit/qt/Api/qwebview.h | 5 -- src/3rdparty/webkit/WebKit/qt/ChangeLog | 50 +++++++++++++++++++ 8 files changed, 125 insertions(+), 13 deletions(-) diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 62acbdf..e6813a1 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - 9de63cde0ac8aa08e207d4ffce2846df1a44a364 + de77f8ee69c434bde9306c8f407ee2e443a00188 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index 4f6146f..c60a5d4 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,16 @@ +2009-12-21 Andreas Kling + + Reviewed by Darin Adler. + + Fix assertion failure when dragging an SVG image. + https://bugs.webkit.org/show_bug.cgi?id=32511 + + Test: fast/images/drag-svg-as-image.html + + * svg/graphics/SVGImage.cpp: + (WebCore::SVGImage::filenameExtension): Return "svg" + * svg/graphics/SVGImage.h: + 2009-11-23 Simon Hausmann Reviewed by Kenneth Rohde Christiansen. diff --git a/src/3rdparty/webkit/WebCore/svg/graphics/SVGImage.cpp b/src/3rdparty/webkit/WebCore/svg/graphics/SVGImage.cpp index 0a506f8..b74e912 100644 --- a/src/3rdparty/webkit/WebCore/svg/graphics/SVGImage.cpp +++ b/src/3rdparty/webkit/WebCore/svg/graphics/SVGImage.cpp @@ -267,6 +267,11 @@ bool SVGImage::dataChanged(bool allDataReceived) return m_page; } +String SVGImage::filenameExtension() const +{ + return "svg"; +} + } #endif // ENABLE(SVG) diff --git a/src/3rdparty/webkit/WebCore/svg/graphics/SVGImage.h b/src/3rdparty/webkit/WebCore/svg/graphics/SVGImage.h index 2cea91a..0f05429 100644 --- a/src/3rdparty/webkit/WebCore/svg/graphics/SVGImage.h +++ b/src/3rdparty/webkit/WebCore/svg/graphics/SVGImage.h @@ -47,6 +47,8 @@ namespace WebCore { private: virtual ~SVGImage(); + virtual String filenameExtension() const; + virtual void setContainerSize(const IntSize&); virtual bool usesContainerSize() const; virtual bool hasRelativeWidth() const; diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebinspector.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebinspector.cpp index f43cbbf..1145744 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebinspector.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebinspector.cpp @@ -139,6 +139,9 @@ QSize QWebInspector::sizeHint() const /*! \reimp */ bool QWebInspector::event(QEvent* ev) { + if (ev->type() == QEvent::Close && d->page) + d->page->d->inspectorController()->setWindowVisible(false); + return QWidget::event(ev); } @@ -159,8 +162,6 @@ void QWebInspector::showEvent(QShowEvent* event) /*! \reimp */ void QWebInspector::hideEvent(QHideEvent* event) { - if (d->page) - d->page->d->inspectorController()->setWindowVisible(false); } /*! \internal */ diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp index 88b7271..35f6e0c 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp @@ -3080,7 +3080,7 @@ QString QWebPage::userAgentForUrl(const QUrl& url) const Q_UNUSED(url) QString ua = QLatin1String("Mozilla/5.0 (" - // Plastform + // Platform #ifdef Q_WS_MAC "Macintosh" #elif defined Q_WS_QWS @@ -3089,19 +3089,22 @@ QString QWebPage::userAgentForUrl(const QUrl& url) const "Windows" #elif defined Q_WS_X11 "X11" +#elif defined Q_OS_SYMBIAN + "SymbianOS" #else "Unknown" #endif - "; " + // Placeholder for Platform Version + "%1; " // Placeholder for security strength (N or U) - "%1; " + "%2; " // Subplatform" #ifdef Q_OS_AIX "AIX" #elif defined Q_OS_WIN32 - "%2" + "%3" #elif defined Q_OS_DARWIN #ifdef __i386__ || __x86_64__ "Intel Mac OS X" @@ -3153,6 +3156,8 @@ QString QWebPage::userAgentForUrl(const QUrl& url) const "Sun Solaris" #elif defined Q_OS_ULTRIX "DEC Ultrix" +#elif defined Q_WS_S60 + "Series60" #elif defined Q_OS_UNIX "UNIX BSD/SYSV system" #elif defined Q_OS_UNIXWARE @@ -3160,7 +3165,28 @@ QString QWebPage::userAgentForUrl(const QUrl& url) const #else "Unknown" #endif - "; "); + // Placeholder for SubPlatform Version + "%4; "); + + // Platform Version + QString osVer; +#ifdef Q_OS_SYMBIAN + QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion(); + switch (symbianVersion) { + case QSysInfo::SV_9_2: + osVer = "/9.2"; + break; + case QSysInfo::SV_9_3: + osVer = "/9.3"; + break; + case QSysInfo::SV_9_4: + osVer = "/9.4"; + break; + default: + osVer = "Unknown"; + } +#endif + ua = ua.arg(osVer); QChar securityStrength(QLatin1Char('N')); #if !defined(QT_NO_OPENSSL) @@ -3224,6 +3250,26 @@ QString QWebPage::userAgentForUrl(const QUrl& url) const ua = QString(ua).arg(ver); #endif + // SubPlatform Version + QString subPlatformVer; +#ifdef Q_OS_SYMBIAN + QSysInfo::S60Version s60Version = QSysInfo::s60Version(); + switch (s60Version) { + case QSysInfo::SV_S60_3_1: + subPlatformVer = "/3.1"; + break; + case QSysInfo::SV_S60_3_2: + subPlatformVer = "/3.2"; + break; + case QSysInfo::SV_S60_5_0: + subPlatformVer = "/5.0"; + break; + default: + subPlatformVer = " Unknown"; + } +#endif + ua = ua.arg(subPlatformVer); + // Language QLocale locale; if (view()) diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebview.h b/src/3rdparty/webkit/WebKit/qt/Api/qwebview.h index e9c1ec8..0f79c70 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebview.h +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebview.h @@ -51,12 +51,7 @@ class QWEBKIT_EXPORT QWebView : public QWidget { Q_PROPERTY(qreal textSizeMultiplier READ textSizeMultiplier WRITE setTextSizeMultiplier DESIGNABLE false) Q_PROPERTY(qreal zoomFactor READ zoomFactor WRITE setZoomFactor) -// FIXME: temporary work around for elftran issue that it couldn't find the QPainter::staticMetaObject -// symbol from Qt lib; it should be reverted after the right symbol is exported. -// See bug: http://qt.nokia.com/developer/task-tracker/index_html?method=entry&id=258893 -#if defined(Q_QDOC) || !defined(Q_OS_SYMBIAN) Q_PROPERTY(QPainter::RenderHints renderHints READ renderHints WRITE setRenderHints) -#endif Q_FLAGS(QPainter::RenderHints) public: explicit QWebView(QWidget* parent = 0); diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index 2f0bf17..37d527fa 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,53 @@ +2009-12-21 David Boddie + + Reviewed by Simon Hausmann. + + Doc: Minor fixes to language. + + * Api/qwebpage.cpp: + +2009-12-15 Holger Hans Peter Freyther + + Reviewed by NOBODY (OOPS!). + + [Qt] Do not disable the inspector on show and hide + https://bugs.webkit.org/show_bug.cgi?id=31851 + + On Qt/X11 with some window managers the window will be + hidden when switching windows. In this case all the results + are gone when coming back to the window. + + Attempt to use the CloseEvent to figure out if the window + was closed and withdrawn as this is more friendly to the + user of the inspector client. + + * Api/qwebinspector.cpp: + (QWebInspector::event): + (QWebInspector::hideEvent): + +2009-12-13 Simon Hausmann + + Reviewed by Holger Freyther. + + [Qt] Re-enable QWebView::renderHints property for Qt for Symbian + + https://bugs.webkit.org/show_bug.cgi?id=28273 + + The bug in Qt's moc that triggered a linking error when declaring this + property has been fixed and we can remove the workaround. + + * Api/qwebview.h: + +2009-11-30 Abhinav Mithal + + Reviewed by Simon Hausmann. + + [Qt][Symbian] Report SymbianOS in user agent string for Symbian + https://bugs.webkit.org/show_bug.cgi?id=31961 + + * Api/qwebpage.cpp: + (QWebPage::userAgentForUrl): + 2009-11-28 Simon Hausmann Reviewed by Kenneth Rohde Christiansen. -- cgit v0.12 From 5dfea4dc59c01e57dad0d64b8ef2226220256778 Mon Sep 17 00:00:00 2001 From: Bill King Date: Tue, 22 Dec 2009 13:02:33 +1000 Subject: Clean up oracle data type tests. --- tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 37 ++++++++++++---------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index 13cb3be..1d39c67 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -903,12 +903,8 @@ void tst_QSqlDatabase::recordOCI() CHECK_DATABASE(db); // runtime check for Oracle version since V8 doesn't support TIMESTAMPs - if (tst_Databases::getOraVersion(db) >= 9) { - qDebug("Detected Oracle >= 9, TIMESTAMP test enabled"); - hasTimeStamp = true; - } else { - qDebug("Detected Oracle < 9, TIMESTAMP test disabled"); - } + if (tst_Databases::getOraVersion(db) >= 9) + hasTimeStamp = true; FieldDef tsdef; FieldDef tstzdef; @@ -919,11 +915,11 @@ void tst_QSqlDatabase::recordOCI() static const QDateTime dt(QDate::currentDate(), QTime(1, 2, 3, 0)); if (hasTimeStamp) { - tsdef = FieldDef("timestamp", QVariant::DateTime, dt); - tstzdef = FieldDef("timestamp with time zone", QVariant::DateTime, dt); - tsltzdef = FieldDef("timestamp with local time zone", QVariant::DateTime, dt); - intytm = FieldDef("interval year to month", QVariant::String, QString("+01-01")); - intdts = FieldDef("interval day to second", QVariant::String, QString("+01 00:00:01.000000")); + tsdef = FieldDef("timestamp", QVariant::DateTime, dt); + tstzdef = FieldDef("timestamp with time zone", QVariant::DateTime, dt); + tsltzdef = FieldDef("timestamp with local time zone", QVariant::DateTime, dt); + intytm = FieldDef("interval year to month", QVariant::String, QString("+01-01")); + intdts = FieldDef("interval day to second", QVariant::String, QString("+01 00:00:01.000000")); } const FieldDef fieldDefs[] = { @@ -938,14 +934,14 @@ void tst_QSqlDatabase::recordOCI() FieldDef("blob", QVariant::ByteArray, QByteArray("blah7")), FieldDef("clob", QVariant::String, QString("blah8")), FieldDef("nclob", QVariant::String, QString("blah9")), - FieldDef("bfile", QVariant::ByteArray, QByteArray("blah10")), +// FieldDef("bfile", QVariant::ByteArray, QByteArray("blah10")), - intytm, -// intdts, -// tsdef, -// tstzdef, -// tsltzdef, - FieldDef() + intytm, + intdts, + tsdef, + tstzdef, + tsltzdef, + FieldDef() }; const int fieldCount = createFieldTable(fieldDefs, db); @@ -953,9 +949,8 @@ void tst_QSqlDatabase::recordOCI() commonFieldTest(fieldDefs, db, fieldCount); checkNullValues(fieldDefs, db); - for (int i = 0; i < ITERATION_COUNT; ++i) { - checkValues(fieldDefs, db); - } + for (int i = 0; i < ITERATION_COUNT; ++i) + checkValues(fieldDefs, db); // some additional tests QSqlRecord rec = db.record(qTableName("qtestfields")); -- cgit v0.12 From c6019a54323629425383b7200498e10e3efa70af Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Tue, 22 Dec 2009 16:33:53 +1000 Subject: Remove unused legacy code from the jpeg image plugin A long time ago, in a Qt version far, far, away there was a parameter string mechanism for asking for header details, requesting scaling, and so on. This has since been replaced with actual real API's and it is no longer possible to pass such parameter strings to the image plugins. This change removes the crufty beloved old code. Reviewed-by: Sarah Smith --- src/plugins/imageformats/jpeg/qjpeghandler.cpp | 144 ++----------------------- src/plugins/imageformats/jpeg/qjpeghandler.h | 1 - 2 files changed, 11 insertions(+), 134 deletions(-) diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp index 54bbcda..aa239ec 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp +++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp @@ -84,7 +84,7 @@ class QImageSmoothScaler public: QImageSmoothScaler(const int w, const int h, const QImage &src); QImageSmoothScaler(const int srcWidth, const int srcHeight, - const char *parameters); + const int dstWidth, const int dstHeight); virtual ~QImageSmoothScaler(void); @@ -123,33 +123,9 @@ QImageSmoothScaler::QImageSmoothScaler(const int w, const int h, } QImageSmoothScaler::QImageSmoothScaler(const int srcWidth, const int srcHeight, - const char *parameters) + const int dstWidth, const int dstHeight) { - char sModeStr[1024]; - int t1; - int t2; - int dstWidth; - int dstHeight; - - sModeStr[0] = '\0'; - d = new QImageSmoothScalerPrivate; -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400 - sscanf_s(parameters, "Scale( %i, %i, %1023s )", &dstWidth, &dstHeight, sModeStr, sizeof(sModeStr)); -#else - sscanf(parameters, "Scale( %i, %i, %s )", &dstWidth, &dstHeight, sModeStr); -#endif - QString sModeQStr = QString::fromLatin1(sModeStr); - - t1 = srcWidth * dstHeight; - t2 = srcHeight * dstWidth; - - if (((sModeQStr == QLatin1String("ScaleMin")) && (t1 > t2)) || ((sModeQStr == QLatin1String("ScaleMax")) && (t2 < t2))) { - dstHeight = t2 / srcWidth; - } else if (sModeQStr != QLatin1String("ScaleFree")) { - dstWidth = t1 / srcHeight; - } - d->setup(srcWidth, srcHeight, dstWidth, dstHeight, 0); } @@ -467,8 +443,8 @@ QImage QImageSmoothScaler::scale() class jpegSmoothScaler : public QImageSmoothScaler { public: - jpegSmoothScaler(struct jpeg_decompress_struct *info, const char *params): - QImageSmoothScaler(info->output_width, info->output_height, params) + jpegSmoothScaler(struct jpeg_decompress_struct *info, int dstWidth, int dstHeight) + : QImageSmoothScaler(info->output_width, info->output_height, dstWidth, dstHeight) { cinfo = info; cols24Bit = scaledWidth() * 3; @@ -637,18 +613,6 @@ inline my_jpeg_source_mgr::my_jpeg_source_mgr(QIODevice *device) } -static void scaleSize(int &reqW, int &reqH, int imgW, int imgH, Qt::AspectRatioMode mode) -{ - if (mode == Qt::IgnoreAspectRatio) - return; - int t1 = imgW * reqH; - int t2 = reqW * imgH; - if ((mode == Qt::KeepAspectRatio && (t1 > t2)) || (mode == Qt::KeepAspectRatioByExpanding && (t1 < t2))) - reqH = t2 / imgW; - else - reqW = t1 / imgH; -} - static bool read_jpeg_size(QIODevice *device, int &w, int &h) { bool rt = false; @@ -763,8 +727,7 @@ static bool ensureValidImage(QImage *dest, struct jpeg_decompress_struct *info, } static bool read_jpeg_image(QIODevice *device, QImage *outImage, - const QByteArray ¶meters, QSize scaledSize, - int inQuality ) + QSize scaledSize, int inQuality ) { #ifdef QT_NO_IMAGE_SMOOTHSCALE Q_UNUSED( scaledSize ); @@ -794,16 +757,9 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, if (quality < 0) quality = 75; - QString params = QString::fromLatin1(parameters); - params.simplified(); - int sWidth = 0, sHeight = 0; - char sModeStr[1024] = ""; - Qt::AspectRatioMode sMode; - #ifndef QT_NO_IMAGE_SMOOTHSCALE // If high quality not required, shrink image during decompression - if (scaledSize.isValid() && !scaledSize.isEmpty() && quality < HIGH_QUALITY_THRESHOLD - && !params.contains(QLatin1String("GetHeaderInformation")) ) { + if (scaledSize.isValid() && !scaledSize.isEmpty() && quality < HIGH_QUALITY_THRESHOLD) { cinfo.scale_denom = qMin(cinfo.image_width / scaledSize.width(), cinfo.image_width / scaledSize.height()); if (cinfo.scale_denom < 2) { @@ -829,93 +785,15 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, (void) jpeg_start_decompress(&cinfo); - if (params.contains(QLatin1String("GetHeaderInformation"))) { - if (!ensureValidImage(outImage, &cinfo, true)) - longjmp(jerr.setjmp_buffer, 1); - } else if (params.contains(QLatin1String("Scale"))) { -#if defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(Q_OS_WINCE) - sscanf_s(params.toLatin1().data(), "Scale(%i, %i, %1023s)", - &sWidth, &sHeight, sModeStr, sizeof(sModeStr)); -#else - sscanf(params.toLatin1().data(), "Scale(%i, %i, %1023s)", - &sWidth, &sHeight, sModeStr); -#endif - - QString sModeQStr(QString::fromLatin1(sModeStr)); - if (sModeQStr == QLatin1String("IgnoreAspectRatio")) { - sMode = Qt::IgnoreAspectRatio; - } else if (sModeQStr == QLatin1String("KeepAspectRatio")) { - sMode = Qt::KeepAspectRatio; - } else if (sModeQStr == QLatin1String("KeepAspectRatioByExpanding")) { - sMode = Qt::KeepAspectRatioByExpanding; - } else { - qDebug("read_jpeg_image: invalid aspect ratio mode \"%s\", see QImage::AspectRatioMode documentation", sModeStr); - sMode = Qt::KeepAspectRatio; - } - -// qDebug("Parameters ask to scale the image to %i x %i AspectRatioMode: %s", sWidth, sHeight, sModeStr); - scaleSize(sWidth, sHeight, cinfo.output_width, cinfo.output_height, sMode); -// qDebug("Scaling the jpeg to %i x %i", sWidth, sHeight, sModeStr); - - if (cinfo.output_components == 3 || cinfo.output_components == 4) { - if (outImage->size() != QSize(sWidth, sHeight) || outImage->format() != QImage::Format_RGB32) - *outImage = QImage(sWidth, sHeight, QImage::Format_RGB32); - } else if (cinfo.output_components == 1) { - if (outImage->size() != QSize(sWidth, sHeight) || outImage->format() != QImage::Format_Indexed8) - *outImage = QImage(sWidth, sHeight, QImage::Format_Indexed8); - outImage->setColorCount(256); - for (int i = 0; i < 256; ++i) - outImage->setColor(i, qRgb(i,i,i)); - } else { - // Unsupported format - } - if (outImage->isNull()) - longjmp(jerr.setjmp_buffer, 1); - - if (!outImage->isNull()) { - QImage tmpImage(cinfo.output_width, 1, QImage::Format_RGB32); - uchar* inData = tmpImage.bits(); - uchar* outData = outImage->bits(); - int out_bpl = outImage->bytesPerLine(); - while (cinfo.output_scanline < cinfo.output_height) { - int outputLine = sHeight * cinfo.output_scanline / cinfo.output_height; - (void) jpeg_read_scanlines(&cinfo, &inData, 1); - if (cinfo.output_components == 3) { - uchar *in = inData; - QRgb *out = (QRgb*)outData + outputLine * out_bpl; - for (uint i=0; i= HIGH_QUALITY_THRESHOLD) { - jpegSmoothScaler scaler(&cinfo, QString().sprintf("Scale( %d, %d, ScaleFree )", - scaledSize.width(), - scaledSize.height()).toLatin1().data()); + jpegSmoothScaler scaler(&cinfo, scaledSize.width(), scaledSize.height()); *outImage = scaler.scale(); + } else #endif - } else { + { if (!ensureValidImage(outImage, &cinfo)) longjmp(jerr.setjmp_buffer, 1); @@ -1224,7 +1102,7 @@ bool QJpegHandler::read(QImage *image) { if (!canRead()) return false; - return read_jpeg_image(device(), image, parameters, scaledSize, quality); + return read_jpeg_image(device(), image, scaledSize, quality); } bool QJpegHandler::write(const QImage &image) diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.h b/src/plugins/imageformats/jpeg/qjpeghandler.h index 654c078..0a14a88 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler.h +++ b/src/plugins/imageformats/jpeg/qjpeghandler.h @@ -66,7 +66,6 @@ public: private: int quality; - QByteArray parameters; QSize scaledSize; }; -- cgit v0.12 From 2a20705f874ddad55282f22fabfe30927729ae50 Mon Sep 17 00:00:00 2001 From: Janne Koskinen Date: Tue, 22 Dec 2009 10:56:22 +0200 Subject: Daylight savings time for Symbian. Ask DST from Symbian's timezone server. This commit makes datetime functions slower. Small room for optimisation with keeping the server connection always open. Task-number: QTBUG-6859 Reviewed-by: Aleksandar Sasha Babic --- src/corelib/corelib.pro | 2 ++ src/corelib/tools/qdatetime.cpp | 60 +++++++++++++++++++++------------- tests/auto/qdatetime/tst_qdatetime.cpp | 7 ++++ 3 files changed, 46 insertions(+), 23 deletions(-) diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index 9a15bf1..7f33791 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -35,4 +35,6 @@ symbian: { # Workaroud for problems with paging this dll MMP_RULES -= PAGED MMP_RULES *= UNPAGED + # Timezone server + LIBS += -ltzclient } diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index db6435e..240f0cf 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -75,6 +75,7 @@ #if defined(Q_OS_SYMBIAN) #include +#include #endif QT_BEGIN_NAMESPACE @@ -3721,23 +3722,32 @@ static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time) #elif defined(Q_OS_SYMBIAN) // months and days are zero index based _LIT(KUnixEpoch, "19700000:000000.000000"); - TTimeIntervalSeconds utcOffset = User::UTCOffset(); TTimeIntervalSeconds tTimeIntervalSecsSince1Jan1970UTC(secsSince1Jan1970UTC); TTime epochTTime; TInt err = epochTTime.Set(KUnixEpoch); tm res; if(err == KErrNone) { TTime utcTTime = epochTTime + tTimeIntervalSecsSince1Jan1970UTC; - utcTTime = utcTTime + utcOffset; - TDateTime utcDateTime = utcTTime.DateTime(); - res.tm_sec = utcDateTime.Second(); - res.tm_min = utcDateTime.Minute(); - res.tm_hour = utcDateTime.Hour(); - res.tm_mday = utcDateTime.Day() + 1; // non-zero based index for tm struct - res.tm_mon = utcDateTime.Month(); - res.tm_year = utcDateTime.Year() - 1900; - res.tm_isdst = 0; - brokenDown = &res; + TRAP(err, + RTz tz; + User::LeaveIfError(tz.Connect()); + CleanupClosePushL(tz); + res.tm_isdst = tz.IsDaylightSavingOnL(*tz.GetTimeZoneIdL(),utcTTime); + User::LeaveIfError(tz.ConvertToLocalTime(utcTTime)); + CleanupStack::PopAndDestroy(&tz)); + if (KErrNone == err) { + TDateTime localDateTime = utcTTime.DateTime(); + res.tm_sec = localDateTime.Second(); + res.tm_min = localDateTime.Minute(); + res.tm_hour = localDateTime.Hour(); + res.tm_mday = localDateTime.Day() + 1; // non-zero based index for tm struct + res.tm_mon = localDateTime.Month(); + res.tm_year = localDateTime.Year() - 1900; + // Symbian's timezone server doesn't know how to handle DST before year 1997 + if (res.tm_year < 97) + res.tm_isdst = -1; + brokenDown = &res; + } } #elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) // use the reentrant version of localtime() where available @@ -3812,23 +3822,27 @@ static void localToUtc(QDate &date, QTime &time, int isdst) #elif defined(Q_OS_SYMBIAN) // months and days are zero index based _LIT(KUnixEpoch, "19700000:000000.000000"); - TTimeIntervalSeconds utcOffset = TTimeIntervalSeconds(0 - User::UTCOffset().Int()); TTimeIntervalSeconds tTimeIntervalSecsSince1Jan1970UTC(secsSince1Jan1970UTC); TTime epochTTime; TInt err = epochTTime.Set(KUnixEpoch); tm res; if(err == KErrNone) { - TTime utcTTime = epochTTime + tTimeIntervalSecsSince1Jan1970UTC; - utcTTime = utcTTime + utcOffset; - TDateTime utcDateTime = utcTTime.DateTime(); - res.tm_sec = utcDateTime.Second(); - res.tm_min = utcDateTime.Minute(); - res.tm_hour = utcDateTime.Hour(); - res.tm_mday = utcDateTime.Day() + 1; // non-zero based index for tm struct - res.tm_mon = utcDateTime.Month(); - res.tm_year = utcDateTime.Year() - 1900; - res.tm_isdst = (int)isdst; - brokenDown = &res; + TTime localTTime = epochTTime + tTimeIntervalSecsSince1Jan1970UTC; + RTz tz; + if (KErrNone == tz.Connect()) { + if (KErrNone == tz.ConvertToUniversalTime(localTTime)) { + TDateTime utcDateTime = localTTime.DateTime(); + res.tm_sec = utcDateTime.Second(); + res.tm_min = utcDateTime.Minute(); + res.tm_hour = utcDateTime.Hour(); + res.tm_mday = utcDateTime.Day() + 1; // non-zero based index for tm struct + res.tm_mon = utcDateTime.Month(); + res.tm_year = utcDateTime.Year() - 1900; + res.tm_isdst = (int)isdst; + brokenDown = &res; + } + tz.Close(); + } } #elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) // use the reentrant version of gmtime() where available diff --git a/tests/auto/qdatetime/tst_qdatetime.cpp b/tests/auto/qdatetime/tst_qdatetime.cpp index 1140402..32fa398 100644 --- a/tests/auto/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/qdatetime/tst_qdatetime.cpp @@ -147,9 +147,16 @@ Q_DECLARE_METATYPE(QTime) tst_QDateTime::tst_QDateTime() { +#ifdef Q_OS_SYMBIAN + // Symbian's timezone server cannot handle DST correctly for dates before year 1997 + uint x1 = QDateTime(QDate(2000, 1, 1), QTime()).toTime_t(); + uint x2 = QDateTime(QDate(2000, 6, 1), QTime()).toTime_t(); + europeanTimeZone = (x1 == 946681200 && x2 == 959810400); +#else uint x1 = QDateTime(QDate(1990, 1, 1), QTime()).toTime_t(); uint x2 = QDateTime(QDate(1990, 6, 1), QTime()).toTime_t(); europeanTimeZone = (x1 == 631148400 && x2 == 644191200); +#endif } tst_QDateTime::~tst_QDateTime() -- cgit v0.12 From 495952fb67efd283bfc41b8d9017bc0d1e163638 Mon Sep 17 00:00:00 2001 From: axis Date: Tue, 22 Dec 2009 10:46:34 +0100 Subject: Fixed incorrect headers. AutoTest: Passed RevBy: Paul Olav Tvete --- tools/runonphone/main.cpp | 41 +++++++++++++++++--------- tools/runonphone/serenum.h | 41 +++++++++++++++++--------- tools/runonphone/serenum_win.cpp | 41 +++++++++++++++++--------- tools/runonphone/trk/bluetoothlistener.cpp | 40 ++++++++++++++++--------- tools/runonphone/trk/bluetoothlistener.h | 40 ++++++++++++++++--------- tools/runonphone/trk/bluetoothlistener_gui.cpp | 40 ++++++++++++++++--------- tools/runonphone/trk/bluetoothlistener_gui.h | 40 ++++++++++++++++--------- tools/runonphone/trk/callback.h | 40 ++++++++++++++++--------- tools/runonphone/trk/communicationstarter.cpp | 40 ++++++++++++++++--------- tools/runonphone/trk/communicationstarter.h | 40 ++++++++++++++++--------- tools/runonphone/trk/launcher.cpp | 40 ++++++++++++++++--------- tools/runonphone/trk/launcher.h | 41 +++++++++++++++++--------- tools/runonphone/trk/trkdevice.cpp | 40 ++++++++++++++++--------- tools/runonphone/trk/trkdevice.h | 40 ++++++++++++++++--------- tools/runonphone/trk/trkutils.cpp | 40 ++++++++++++++++--------- tools/runonphone/trk/trkutils.h | 40 ++++++++++++++++--------- tools/runonphone/trksignalhandler.cpp | 41 +++++++++++++++++--------- tools/runonphone/trksignalhandler.h | 41 +++++++++++++++++--------- 18 files changed, 474 insertions(+), 252 deletions(-) diff --git a/tools/runonphone/main.cpp b/tools/runonphone/main.cpp index 8404906..58d8c3b 100644 --- a/tools/runonphone/main.cpp +++ b/tools/runonphone/main.cpp @@ -1,20 +1,19 @@ -/************************************************************************** -** -** This file is part of the tools applications of the Qt Toolkit. -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +/**************************************************************************** ** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** Commercial Usage +** This file is part of the tools applications of the Qt Toolkit. ** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** $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 @@ -22,10 +21,24 @@ ** 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. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. +** 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 diff --git a/tools/runonphone/serenum.h b/tools/runonphone/serenum.h index a0c810c..e7ab2d1 100644 --- a/tools/runonphone/serenum.h +++ b/tools/runonphone/serenum.h @@ -1,20 +1,19 @@ -/************************************************************************** -** -** This file is part of the tools applications of the Qt Toolkit. -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +/**************************************************************************** ** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** Commercial Usage +** This file is part of the tools applications of the Qt Toolkit. ** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** $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 @@ -22,10 +21,24 @@ ** 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. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. +** 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 WIN32SERENUM_H #define WIN32SERENUM_H diff --git a/tools/runonphone/serenum_win.cpp b/tools/runonphone/serenum_win.cpp index 1cf5789..ec11c3c 100644 --- a/tools/runonphone/serenum_win.cpp +++ b/tools/runonphone/serenum_win.cpp @@ -1,20 +1,19 @@ -/************************************************************************** -** -** This file is part of the tools applications of the Qt Toolkit. -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +/**************************************************************************** ** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** Commercial Usage +** This file is part of the tools applications of the Qt Toolkit. ** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** $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 @@ -22,10 +21,24 @@ ** 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. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. +** 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 "serenum.h" #include #include diff --git a/tools/runonphone/trk/bluetoothlistener.cpp b/tools/runonphone/trk/bluetoothlistener.cpp index 1f5ccbe..73be9f4 100644 --- a/tools/runonphone/trk/bluetoothlistener.cpp +++ b/tools/runonphone/trk/bluetoothlistener.cpp @@ -1,20 +1,19 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +/**************************************************************************** ** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** Commercial Usage +** This file is part of the tools applications of the Qt Toolkit. ** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** $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 @@ -22,10 +21,23 @@ ** 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. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. +** 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 "bluetoothlistener.h" #include "trkdevice.h" diff --git a/tools/runonphone/trk/bluetoothlistener.h b/tools/runonphone/trk/bluetoothlistener.h index a20ba30..0baec74 100644 --- a/tools/runonphone/trk/bluetoothlistener.h +++ b/tools/runonphone/trk/bluetoothlistener.h @@ -1,20 +1,19 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +/**************************************************************************** ** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** Commercial Usage +** This file is part of the tools applications of the Qt Toolkit. ** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** $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 @@ -22,10 +21,23 @@ ** 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. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. +** 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 BLUETOOTHLISTENER_H #define BLUETOOTHLISTENER_H diff --git a/tools/runonphone/trk/bluetoothlistener_gui.cpp b/tools/runonphone/trk/bluetoothlistener_gui.cpp index 9b6dbd3..d2fd72d 100644 --- a/tools/runonphone/trk/bluetoothlistener_gui.cpp +++ b/tools/runonphone/trk/bluetoothlistener_gui.cpp @@ -1,20 +1,19 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +/**************************************************************************** ** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** Commercial Usage +** This file is part of the tools applications of the Qt Toolkit. ** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** $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 @@ -22,10 +21,23 @@ ** 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. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. +** 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 "bluetoothlistener_gui.h" #include "bluetoothlistener.h" diff --git a/tools/runonphone/trk/bluetoothlistener_gui.h b/tools/runonphone/trk/bluetoothlistener_gui.h index 83cce42..3b2ec17 100644 --- a/tools/runonphone/trk/bluetoothlistener_gui.h +++ b/tools/runonphone/trk/bluetoothlistener_gui.h @@ -1,20 +1,19 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +/**************************************************************************** ** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** Commercial Usage +** This file is part of the tools applications of the Qt Toolkit. ** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** $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 @@ -22,10 +21,23 @@ ** 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. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. +** 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 BLUETOOTHLISTENER_GUI_H #define BLUETOOTHLISTENER_GUI_H diff --git a/tools/runonphone/trk/callback.h b/tools/runonphone/trk/callback.h index 375f167..4e12c5e 100644 --- a/tools/runonphone/trk/callback.h +++ b/tools/runonphone/trk/callback.h @@ -1,20 +1,19 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +/**************************************************************************** ** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** Commercial Usage +** This file is part of the tools applications of the Qt Toolkit. ** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** $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 @@ -22,10 +21,23 @@ ** 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. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. +** 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 DEBUGGER_CALLBACK_H #define DEBUGGER_CALLBACK_H diff --git a/tools/runonphone/trk/communicationstarter.cpp b/tools/runonphone/trk/communicationstarter.cpp index b425db2..0251976 100644 --- a/tools/runonphone/trk/communicationstarter.cpp +++ b/tools/runonphone/trk/communicationstarter.cpp @@ -1,20 +1,19 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +/**************************************************************************** ** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** Commercial Usage +** This file is part of the tools applications of the Qt Toolkit. ** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** $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 @@ -22,10 +21,23 @@ ** 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. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. +** 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 "communicationstarter.h" #include "bluetoothlistener.h" diff --git a/tools/runonphone/trk/communicationstarter.h b/tools/runonphone/trk/communicationstarter.h index 6f9f6d1..08defde 100644 --- a/tools/runonphone/trk/communicationstarter.h +++ b/tools/runonphone/trk/communicationstarter.h @@ -1,20 +1,19 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +/**************************************************************************** ** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** Commercial Usage +** This file is part of the tools applications of the Qt Toolkit. ** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** $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 @@ -22,10 +21,23 @@ ** 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. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. +** 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 COMMUNICATIONSTARTER_H #define COMMUNICATIONSTARTER_H diff --git a/tools/runonphone/trk/launcher.cpp b/tools/runonphone/trk/launcher.cpp index aa3a4e6..90ad602 100644 --- a/tools/runonphone/trk/launcher.cpp +++ b/tools/runonphone/trk/launcher.cpp @@ -1,20 +1,19 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +/**************************************************************************** ** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** Commercial Usage +** This file is part of the tools applications of the Qt Toolkit. ** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** $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 @@ -22,10 +21,23 @@ ** 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. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. +** 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 "launcher.h" #include "trkutils.h" diff --git a/tools/runonphone/trk/launcher.h b/tools/runonphone/trk/launcher.h index 799c77a..29ee967 100644 --- a/tools/runonphone/trk/launcher.h +++ b/tools/runonphone/trk/launcher.h @@ -1,20 +1,19 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +/**************************************************************************** ** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** Commercial Usage +** This file is part of the tools applications of the Qt Toolkit. ** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** $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 @@ -22,10 +21,24 @@ ** 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. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. +** 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 LAUNCHER_H #define LAUNCHER_H diff --git a/tools/runonphone/trk/trkdevice.cpp b/tools/runonphone/trk/trkdevice.cpp index a76cff7..d31fff1 100644 --- a/tools/runonphone/trk/trkdevice.cpp +++ b/tools/runonphone/trk/trkdevice.cpp @@ -1,20 +1,19 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +/**************************************************************************** ** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** Commercial Usage +** This file is part of the tools applications of the Qt Toolkit. ** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** $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 @@ -22,10 +21,23 @@ ** 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. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. +** 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 "trkdevice.h" #include "trkutils.h" diff --git a/tools/runonphone/trk/trkdevice.h b/tools/runonphone/trk/trkdevice.h index 632dea1..41e7a6e 100644 --- a/tools/runonphone/trk/trkdevice.h +++ b/tools/runonphone/trk/trkdevice.h @@ -1,20 +1,19 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +/**************************************************************************** ** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** Commercial Usage +** This file is part of the tools applications of the Qt Toolkit. ** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** $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 @@ -22,10 +21,23 @@ ** 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. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. +** 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 TRKDEVICE_H #define TRKDEVICE_H diff --git a/tools/runonphone/trk/trkutils.cpp b/tools/runonphone/trk/trkutils.cpp index 256d4ad..4fb4f1b 100644 --- a/tools/runonphone/trk/trkutils.cpp +++ b/tools/runonphone/trk/trkutils.cpp @@ -1,20 +1,19 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +/**************************************************************************** ** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** Commercial Usage +** This file is part of the tools applications of the Qt Toolkit. ** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** $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 @@ -22,10 +21,23 @@ ** 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. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. +** 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 "trkutils.h" #include diff --git a/tools/runonphone/trk/trkutils.h b/tools/runonphone/trk/trkutils.h index 4ba51fa..632c0d89 100644 --- a/tools/runonphone/trk/trkutils.h +++ b/tools/runonphone/trk/trkutils.h @@ -1,20 +1,19 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +/**************************************************************************** ** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** Commercial Usage +** This file is part of the tools applications of the Qt Toolkit. ** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** $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 @@ -22,10 +21,23 @@ ** 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. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. +** 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 DEBUGGER_TRK_UTILS #define DEBUGGER_TRK_UTILS diff --git a/tools/runonphone/trksignalhandler.cpp b/tools/runonphone/trksignalhandler.cpp index 15282dd..afb1918 100644 --- a/tools/runonphone/trksignalhandler.cpp +++ b/tools/runonphone/trksignalhandler.cpp @@ -1,20 +1,19 @@ -/************************************************************************** -** -** This file is part of the tools applications of the Qt Toolkit. -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +/**************************************************************************** ** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** Commercial Usage +** This file is part of the tools applications of the Qt Toolkit. ** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** $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 @@ -22,10 +21,24 @@ ** 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. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. +** 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 "trksignalhandler.h" diff --git a/tools/runonphone/trksignalhandler.h b/tools/runonphone/trksignalhandler.h index 1c40a17..2b3f3a0 100644 --- a/tools/runonphone/trksignalhandler.h +++ b/tools/runonphone/trksignalhandler.h @@ -1,20 +1,19 @@ -/************************************************************************** -** -** This file is part of the tools applications of the Qt Toolkit. -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +/**************************************************************************** ** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** Commercial Usage +** This file is part of the tools applications of the Qt Toolkit. ** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** $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 @@ -22,10 +21,24 @@ ** 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. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. +** 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 TRKSIGNALHANDLER_H #define TRKSIGNALHANDLER_H #include -- cgit v0.12 From b2e5e2158529f49390ec597cda823c72336b23ff Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Tue, 22 Dec 2009 12:47:50 +0100 Subject: Memory leak when using QWidget::setWindowIcon() in Carbon. The icon was not released when destroying the window. Task-number: QTBUG-6973 Reviewed-by: Richard Moe Gustavsen --- src/gui/kernel/qwidget_mac.mm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 7dc4d85..0213af9 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -4493,10 +4493,14 @@ void QWidgetPrivate::createTLSysExtra() void QWidgetPrivate::deleteTLSysExtra() { #ifndef QT_MAC_USE_COCOA - if(extra->topextra->group) { + if (extra->topextra->group) { qt_mac_release_window_group(extra->topextra->group); extra->topextra->group = 0; } + if (extra->topextra->windowIcon) { + ReleaseIconRef(extra->topextra->windowIcon); + extra->topextra->windowIcon = 0; + } #endif } -- cgit v0.12 From c24da6375547e0648beaf0b6d2fb91ff312aacdd Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 22 Dec 2009 14:22:09 +0200 Subject: Added more specific clean targets for Symbian builds Also fixed sbsv2 build targets 'make release' and 'make debug'. Task-number: QTBUG-5156 Reviewed-by: Janne Koskinen --- qmake/generators/symbian/symmake_abld.cpp | 22 +++++++++++++++++ qmake/generators/symbian/symmake_sbsv2.cpp | 38 +++++++++++++++++++++++++++--- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/qmake/generators/symbian/symmake_abld.cpp b/qmake/generators/symbian/symmake_abld.cpp index 4ecaae3..065af48 100644 --- a/qmake/generators/symbian/symmake_abld.cpp +++ b/qmake/generators/symbian/symmake_abld.cpp @@ -372,6 +372,28 @@ void SymbianAbldMakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, bool t << "\t-bldmake clean" << endl; t << endl; + t << "clean-debug: $(ABLD)" << endl; + foreach(QString item, debugPlatforms) { + t << "\t$(ABLD)" << testClause << " reallyclean " << item << " udeb" << endl; + } + t << endl; + t << "clean-release: $(ABLD)" << endl; + foreach(QString item, releasePlatforms) { + t << "\t$(ABLD)" << testClause << " reallyclean " << item << " urel" << endl; + } + t << endl; + + // For more specific builds, targets are in this form: clean-build-platform, e.g. clean-release-armv5 + foreach(QString item, debugPlatforms) { + t << "clean-debug-" << item << ": $(ABLD)" << endl; + t << "\t$(ABLD)" << testClause << " reallyclean " << item << " udeb" << endl; + } + foreach(QString item, releasePlatforms) { + t << "clean-release-" << item << ": $(ABLD)" << endl; + t << "\t$(ABLD)" << testClause << " reallyclean " << item << " urel" << endl; + } + t << endl; + generateExecutionTargets(t, debugPlatforms); } diff --git a/qmake/generators/symbian/symmake_sbsv2.cpp b/qmake/generators/symbian/symmake_sbsv2.cpp index 5f5c5c4..7d6119d 100644 --- a/qmake/generators/symbian/symmake_sbsv2.cpp +++ b/qmake/generators/symbian/symmake_sbsv2.cpp @@ -171,18 +171,26 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo t << "\t$(QMAKE)" << endl; t << endl; + QString winscw("winscw"); t << "debug: " << BLD_INF_FILENAME << endl; + t << "\t$(SBS)"; foreach(QString item, debugPlatforms) { - t << "\t$(SBS) -c " << item << "_udeb" << testClause << endl; + if(QString::compare(item, winscw) == 0) + t << " -c " << item << "_udeb.mwccinc" << testClause; + else + t << " -c " << item << "_udeb" << testClause; } t << endl; t << "release: " << BLD_INF_FILENAME << endl; + t << "\t$(SBS)"; foreach(QString item, releasePlatforms) { - t << "\t$(SBS) -c " << item << "_urel" << testClause << endl; + if(QString::compare(item, winscw) == 0) + t << " -c " << item << "_urel.mwccinc" << testClause; + else + t << " -c " << item << "_urel" << testClause; } t << endl; - QString winscw("winscw"); // For more specific builds, targets are in this form: build-platform, e.g. release-armv5 foreach(QString item, debugPlatforms) { t << "debug-" << item << ": " << BLD_INF_FILENAME << endl; @@ -231,6 +239,30 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo t << "\t-$(SBS) reallyclean" << endl; t << endl; + t << "clean-debug: " << BLD_INF_FILENAME << endl; + t << "\t$(SBS) reallyclean"; + foreach(QString item, debugPlatforms) { + t << " -c " << item << "_udeb" << testClause; + } + t << endl; + t << "clean-release: " << BLD_INF_FILENAME << endl; + t << "\t$(SBS) reallyclean"; + foreach(QString item, releasePlatforms) { + t << " -c " << item << "_urel" << testClause; + } + t << endl; + + // For more specific builds, targets are in this form: clean-build-platform, e.g. clean-release-armv5 + foreach(QString item, debugPlatforms) { + t << "clean-debug-" << item << ": " << BLD_INF_FILENAME << endl; + t << "\t$(SBS) reallyclean -c " << item << "_udeb" << testClause << endl; + } + foreach(QString item, releasePlatforms) { + t << "clean-release-" << item << ": " << BLD_INF_FILENAME << endl; + t << "\t$(SBS) reallyclean -c " << item << "_urel" << testClause << endl; + } + t << endl; + generateExecutionTargets(t, debugPlatforms); } -- cgit v0.12 From f5cf5593cb60687034a86faaa4e958428393b0a3 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 22 Dec 2009 15:36:28 +0200 Subject: Changed make sis only require .make.cache if QT_SIS_TARGET is not set. The .make.cache file contents are ignored if QT_SIS_TARGET environment variable is set, so there is no point in requiring its existence in those cases. Task-number: QTBUG-4617 Reviewed-by: Janne Anttila --- qmake/generators/symbian/symmake.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qmake/generators/symbian/symmake.cpp b/qmake/generators/symbian/symmake.cpp index 14177b5..ddda848 100644 --- a/qmake/generators/symbian/symmake.cpp +++ b/qmake/generators/symbian/symmake.cpp @@ -1764,7 +1764,9 @@ void SymbianMakefileGenerator::writeSisTargets(QTextStream &t) { t << SIS_TARGET ": " RESTORE_BUILD_TARGET << endl; QString siscommand = QString("\t$(if $(wildcard %1_template.%2),$(if $(wildcard %3)," \ - "$(MAKE) -s -f $(MAKEFILE) %4,$(MAKE) -s -f $(MAKEFILE) %5)," \ + "$(MAKE) -s -f $(MAKEFILE) %4," \ + "$(if $(QT_SIS_TARGET),$(MAKE) -s -f $(MAKEFILE) %4," \ + "$(MAKE) -s -f $(MAKEFILE) %5))," \ "$(MAKE) -s -f $(MAKEFILE) %6)") .arg(fixedTarget) .arg("pkg") @@ -1789,7 +1791,7 @@ void SymbianMakefileGenerator::writeSisTargets(QTextStream &t) t << endl; t << FAIL_SIS_NOCACHE_TARGET ":" << endl; - t << "\t$(error Project has to be build before calling 'SIS' target)" << endl; + t << "\t$(error Project has to be built or QT_SIS_TARGET environment variable has to be set before calling 'SIS' target)" << endl; t << endl; -- cgit v0.12 From b97aedb9e68c6fe610aff10792c92b2292da0b07 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 22 Dec 2009 13:37:06 +0100 Subject: Fix build with neon instructions enabled but not set in mkspec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-By: Samuel Rødal --- src/gui/painting/painting.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 0b1e79a..a6cc9c7 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -383,7 +383,7 @@ neon { DEFINES += QT_HAVE_NEON HEADERS += painting/qdrawhelper_neon_p.h SOURCES += painting/qdrawhelper_neon.cpp - QMAKE.CXXFLAGS *= -mfpu=neon + QMAKE_CXXFLAGS *= -mfpu=neon } contains(QT_CONFIG, zlib) { -- cgit v0.12 From 2b4d3391fd922dfc5ac28815bbd5f36c4041b658 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Mon, 21 Dec 2009 16:36:14 +0100 Subject: Add GLfloat[2][2] & GLfloat[3][3] uniform setters to QGLShaderProgram Reviewed-By: Rhys Weatherley --- src/opengl/qglshaderprogram.cpp | 67 +++++++++++++++++++++++++++++++++++++++++ src/opengl/qglshaderprogram.h | 4 +++ 2 files changed, 71 insertions(+) diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index b4191dc..f9737a56 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -2275,6 +2275,42 @@ void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x4& value \overload Sets the uniform variable at \a location in the current context + to a 2x2 matrix \a value. The matrix elements must be specified + in column-major order. + + \sa setAttributeValue() + \since 4.6.2 +*/ +void QGLShaderProgram::setUniformValue(int location, const GLfloat value[2][2]) +{ + Q_D(QGLShaderProgram); + Q_UNUSED(d); + if (location != -1) + glUniformMatrix2fv(location, 1, GL_FALSE, value[0]); +} + +/*! + \overload + + Sets the uniform variable at \a location in the current context + to a 3x3 matrix \a value. The matrix elements must be specified + in column-major order. + + \sa setAttributeValue() + \since 4.6.2 +*/ +void QGLShaderProgram::setUniformValue(int location, const GLfloat value[3][3]) +{ + Q_D(QGLShaderProgram); + Q_UNUSED(d); + if (location != -1) + glUniformMatrix3fv(location, 1, GL_FALSE, value[0]); +} + +/*! + \overload + + Sets the uniform variable at \a location in the current context to a 4x4 matrix \a value. The matrix elements must be specified in column-major order. @@ -2288,6 +2324,37 @@ void QGLShaderProgram::setUniformValue(int location, const GLfloat value[4][4]) glUniformMatrix4fv(location, 1, GL_FALSE, value[0]); } + +/*! + \overload + + Sets the uniform variable called \a name in the current context + to a 2x2 matrix \a value. The matrix elements must be specified + in column-major order. + + \sa setAttributeValue() + \since 4.6.2 +*/ +void QGLShaderProgram::setUniformValue(const char *name, const GLfloat value[2][2]) +{ + setUniformValue(uniformLocation(name), value); +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context + to a 3x3 matrix \a value. The matrix elements must be specified + in column-major order. + + \sa setAttributeValue() + \since 4.6.2 +*/ +void QGLShaderProgram::setUniformValue(const char *name, const GLfloat value[3][3]) +{ + setUniformValue(uniformLocation(name), value); +} + /*! \overload diff --git a/src/opengl/qglshaderprogram.h b/src/opengl/qglshaderprogram.h index deeaee2..4eb80dd 100644 --- a/src/opengl/qglshaderprogram.h +++ b/src/opengl/qglshaderprogram.h @@ -216,6 +216,8 @@ public: void setUniformValue(int location, const QMatrix4x2& value); void setUniformValue(int location, const QMatrix4x3& value); void setUniformValue(int location, const QMatrix4x4& value); + void setUniformValue(int location, const GLfloat value[2][2]); + void setUniformValue(int location, const GLfloat value[3][3]); void setUniformValue(int location, const GLfloat value[4][4]); void setUniformValue(int location, const QTransform& value); @@ -242,6 +244,8 @@ public: void setUniformValue(const char *name, const QMatrix4x2& value); void setUniformValue(const char *name, const QMatrix4x3& value); void setUniformValue(const char *name, const QMatrix4x4& value); + void setUniformValue(const char *name, const GLfloat value[2][2]); + void setUniformValue(const char *name, const GLfloat value[3][3]); void setUniformValue(const char *name, const GLfloat value[4][4]); void setUniformValue(const char *name, const QTransform& value); -- cgit v0.12 From b784d4991b186037ccd2b60ae3101697a2251160 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 22 Dec 2009 09:10:14 +0100 Subject: Handle broken shaders better in the GL2 engine's shader manager The shader manager will now a) not seg-fault and b) actually tell you which shader has the error. Reviewed-By: Kim --- .../gl2paintengineex/qglengineshadermanager.cpp | 191 ++++++++++++--------- 1 file changed, 114 insertions(+), 77 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 1187c2d..9d545b9 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -170,13 +170,15 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context) source.append(qShaderSnippets[MainVertexShader]); source.append(qShaderSnippets[PositionOnlyVertexShader]); vertexShader = new QGLShader(QGLShader::Vertex, context, this); - vertexShader->compileSourceCode(source); + if (!vertexShader->compileSourceCode(source)) + qWarning("Vertex shader for simpleShaderProg (MainVertexShader & PositionOnlyVertexShader) failed to compile"); source.clear(); source.append(qShaderSnippets[MainFragmentShader]); source.append(qShaderSnippets[ShockingPinkSrcFragmentShader]); fragShader = new QGLShader(QGLShader::Fragment, context, this); - fragShader->compileSourceCode(source); + if (!fragShader->compileSourceCode(source)) + qWarning("Fragment shader for simpleShaderProg (MainFragmentShader & ShockingPinkSrcFragmentShader) failed to compile"); simpleShaderProg = new QGLShaderProgram(context, this); simpleShaderProg->addShader(vertexShader); @@ -193,13 +195,15 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context) source.append(qShaderSnippets[MainWithTexCoordsVertexShader]); source.append(qShaderSnippets[UntransformedPositionVertexShader]); vertexShader = new QGLShader(QGLShader::Vertex, context, this); - vertexShader->compileSourceCode(source); + if (!vertexShader->compileSourceCode(source)) + qWarning("Vertex shader for blitShaderProg (MainWithTexCoordsVertexShader & UntransformedPositionVertexShader) failed to compile"); source.clear(); source.append(qShaderSnippets[MainFragmentShader]); source.append(qShaderSnippets[ImageSrcFragmentShader]); fragShader = new QGLShader(QGLShader::Fragment, context, this); - fragShader->compileSourceCode(source); + if (!fragShader->compileSourceCode(source)) + qWarning("Fragment shader for blitShaderProg (MainFragmentShader & ImageSrcFragmentShader) failed to compile"); blitShaderProg = new QGLShaderProgram(context, this); blitShaderProg->addShader(vertexShader); @@ -234,84 +238,95 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS } } - QByteArray source; - source.append(qShaderSnippets[prog.mainFragShader]); - source.append(qShaderSnippets[prog.srcPixelFragShader]); - if (prog.srcPixelFragShader == CustomImageSrcFragmentShader) - source.append(prog.customStageSource); - if (prog.compositionFragShader) - source.append(qShaderSnippets[prog.compositionFragShader]); - if (prog.maskFragShader) - source.append(qShaderSnippets[prog.maskFragShader]); - QGLShader* fragShader = new QGLShader(QGLShader::Fragment, ctxGuard.context(), this); - fragShader->compileSourceCode(source); - - source.clear(); - source.append(qShaderSnippets[prog.mainVertexShader]); - source.append(qShaderSnippets[prog.positionVertexShader]); - QGLShader* vertexShader = new QGLShader(QGLShader::Vertex, ctxGuard.context(), this); - vertexShader->compileSourceCode(source); + QGLShader *vertexShader = 0; + QGLShader *fragShader = 0; + QGLEngineShaderProg *newProg = 0; + bool success = false; + + do { + QByteArray source; + source.append(qShaderSnippets[prog.mainFragShader]); + source.append(qShaderSnippets[prog.srcPixelFragShader]); + if (prog.srcPixelFragShader == CustomImageSrcFragmentShader) + source.append(prog.customStageSource); + if (prog.compositionFragShader) + source.append(qShaderSnippets[prog.compositionFragShader]); + if (prog.maskFragShader) + source.append(qShaderSnippets[prog.maskFragShader]); + fragShader = new QGLShader(QGLShader::Fragment, ctxGuard.context(), this); + QByteArray description; +#if defined(QT_DEBUG) + // Name the shader for easier debugging + description.append("Fragment shader: main="); + description.append(snippetNameStr(prog.mainFragShader)); + description.append(", srcPixel="); + description.append(snippetNameStr(prog.srcPixelFragShader)); + if (prog.compositionFragShader) { + description.append(", composition="); + description.append(snippetNameStr(prog.compositionFragShader)); + } + if (prog.maskFragShader) { + description.append(", mask="); + description.append(snippetNameStr(prog.maskFragShader)); + } + fragShader->setObjectName(QString::fromLatin1(description)); +#endif + if (!fragShader->compileSourceCode(source)) { + qWarning() << "Warning:" << description << "failed to compile!"; + break; + } + source.clear(); + source.append(qShaderSnippets[prog.mainVertexShader]); + source.append(qShaderSnippets[prog.positionVertexShader]); + vertexShader = new QGLShader(QGLShader::Vertex, ctxGuard.context(), this); #if defined(QT_DEBUG) - // Name the shaders for easier debugging - QByteArray description; - description.append("Fragment shader: main="); - description.append(snippetNameStr(prog.mainFragShader)); - description.append(", srcPixel="); - description.append(snippetNameStr(prog.srcPixelFragShader)); - if (prog.compositionFragShader) { - description.append(", composition="); - description.append(snippetNameStr(prog.compositionFragShader)); - } - if (prog.maskFragShader) { - description.append(", mask="); - description.append(snippetNameStr(prog.maskFragShader)); - } - fragShader->setObjectName(QString::fromLatin1(description)); - - description.clear(); - description.append("Vertex shader: main="); - description.append(snippetNameStr(prog.mainVertexShader)); - description.append(", position="); - description.append(snippetNameStr(prog.positionVertexShader)); - vertexShader->setObjectName(QString::fromLatin1(description)); + // Name the shader for easier debugging + description.clear(); + description.append("Vertex shader: main="); + description.append(snippetNameStr(prog.mainVertexShader)); + description.append(", position="); + description.append(snippetNameStr(prog.positionVertexShader)); + vertexShader->setObjectName(QString::fromLatin1(description)); #endif + if (!vertexShader->compileSourceCode(source)) { + qWarning() << "Warning:" << description << "failed to compile!"; + break; + } - QGLEngineShaderProg* newProg = new QGLEngineShaderProg(prog); - - // If the shader program's not found in the cache, create it now. - newProg->program = new QGLShaderProgram(ctxGuard.context(), this); - newProg->program->addShader(vertexShader); - newProg->program->addShader(fragShader); - - // We have to bind the vertex attribute names before the program is linked: - newProg->program->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); - if (newProg->useTextureCoords) - newProg->program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); - if (newProg->useOpacityAttribute) - newProg->program->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR); - - newProg->program->link(); - if (!newProg->program->isLinked()) { - QLatin1String none("none"); - QLatin1String br("\n"); - QString error; - error = QLatin1String("Shader program failed to link,") + newProg = new QGLEngineShaderProg(prog); + + // If the shader program's not found in the cache, create it now. + newProg->program = new QGLShaderProgram(ctxGuard.context(), this); + newProg->program->addShader(vertexShader); + newProg->program->addShader(fragShader); + + // We have to bind the vertex attribute names before the program is linked: + newProg->program->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); + if (newProg->useTextureCoords) + newProg->program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); + if (newProg->useOpacityAttribute) + newProg->program->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR); + + newProg->program->link(); + if (!newProg->program->isLinked()) { + QLatin1String none("none"); + QLatin1String br("\n"); + QString error; + error = QLatin1String("Shader program failed to link,") #if defined(QT_DEBUG) - + br - + QLatin1String(" Shaders Used:") + br - + QLatin1String(" ") + vertexShader->objectName() + QLatin1String(": ") + br - + QLatin1String(vertexShader->sourceCode()) + br - + QLatin1String(" ") + fragShader->objectName() + QLatin1String(": ") + br - + QLatin1String(fragShader->sourceCode()) + br + + br + + QLatin1String(" Shaders Used:") + br + + QLatin1String(" ") + vertexShader->objectName() + QLatin1String(": ") + br + + QLatin1String(vertexShader->sourceCode()) + br + + QLatin1String(" ") + fragShader->objectName() + QLatin1String(": ") + br + + QLatin1String(fragShader->sourceCode()) + br #endif - + QLatin1String(" Error Log:\n") - + QLatin1String(" ") + newProg->program->log(); - qWarning() << error; - delete newProg; // Deletes the QGLShaderProgram in it's destructor - newProg = 0; - } - else { + + QLatin1String(" Error Log:\n") + + QLatin1String(" ") + newProg->program->log(); + qWarning() << error; + break; + } if (cachedPrograms.count() > 30) { // The cache is full, so delete the last 5 programs in the list. // These programs will be least used, as a program us bumped to @@ -323,6 +338,22 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS } cachedPrograms.insert(0, newProg); + + success = true; + } while (false); + + // Clean up everything if we weren't successful + if (!success) { + if (newProg) { + delete newProg; // Also deletes the QGLShaderProgram which in turn deletes the QGLShaders + newProg = 0; + } + else { + if (vertexShader) + delete vertexShader; + if (fragShader) + delete fragShader; + } } return newProg; @@ -364,6 +395,9 @@ QGLEngineShaderManager::~QGLEngineShaderManager() uint QGLEngineShaderManager::getUniformLocation(Uniform id) { + if (!currentShaderProg) + return 0; + QVector &uniformLocations = currentShaderProg->uniformLocations; if (uniformLocations.isEmpty()) uniformLocations.fill(GLuint(-1), NumUniforms); @@ -468,7 +502,10 @@ void QGLEngineShaderManager::removeCustomStage() QGLShaderProgram* QGLEngineShaderManager::currentProgram() { - return currentShaderProg->program; + if (currentShaderProg) + return currentShaderProg->program; + else + return simpleProgram(); } QGLShaderProgram* QGLEngineShaderManager::simpleProgram() -- cgit v0.12 From 8908c2575b76789652aab4f623d60734707c3a54 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 22 Dec 2009 10:57:19 +0100 Subject: Use 3x3 PMV matrices rather than 4x4 in the GL2 engine QGraphicsView based applications will set a new transform for every item before it's painted. This leads to lots of updates to the PMV matrix. So switching to a 3x3 rather than a 4x4 gives us less data to pass to GL for each QGraphicsItem which gets rendered. It also means the vertex shader is more efficient. However, this patch only gives a maximum 2.5% speed improvement on the SGX, which seems to be only due to the faster vertex shader rather than the reduced amount of data we pass to GL. Reviewed-By: Kim --- .../gl2paintengineex/qglengineshadersource_p.h | 66 +++++++++++----------- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 58 +++++++++---------- .../gl2paintengineex/qpaintengineex_opengl2_p.h | 2 +- 3 files changed, 62 insertions(+), 64 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index 2407979..46de124 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -99,12 +99,15 @@ static const char* const qglslMainWithTexCoordsAndOpacityVertexShader = "\ opacity = opacityArray; \ }"; +// NOTE: We let GL do the perspective correction so texture lookups in the fragment +// shader are also perspective corrected. static const char* const qglslPositionOnlyVertexShader = "\ - attribute highp vec4 vertexCoordsArray;\ - uniform highp mat4 pmvMatrix;\ + attribute highp vec2 vertexCoordsArray;\ + uniform highp mat3 pmvMatrix;\ void setPosition(void)\ {\ - gl_Position = pmvMatrix * vertexCoordsArray;\ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \ + gl_Position = vec4(transformedPos.xy, 0.0, transformedPos.z); \ }"; static const char* const qglslUntransformedPositionVertexShader = "\ @@ -116,20 +119,19 @@ static const char* const qglslUntransformedPositionVertexShader = "\ // Pattern Brush - This assumes the texture size is 8x8 and thus, the inverted size is 0.125 static const char* const qglslPositionWithPatternBrushVertexShader = "\ - attribute highp vec4 vertexCoordsArray; \ - uniform highp mat4 pmvMatrix; \ + attribute highp vec2 vertexCoordsArray; \ + uniform highp mat3 pmvMatrix; \ uniform mediump vec2 halfViewportSize; \ uniform highp vec2 invertedTextureSize; \ uniform highp mat3 brushTransform; \ varying highp vec2 patternTexCoords; \ void setPosition(void) { \ - gl_Position = pmvMatrix * vertexCoordsArray;\ - gl_Position.xy = gl_Position.xy / gl_Position.w; \ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \ + gl_Position.xy = transformedPos.xy / transformedPos.z; \ mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1.0); \ mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \ - gl_Position.w = invertedHTexCoordsZ; \ + gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \ patternTexCoords.xy = (hTexCoords.xy * 0.125) * invertedHTexCoordsZ; \ }"; @@ -147,20 +149,19 @@ static const char* const qglslPatternBrushSrcFragmentShader = "\ // Linear Gradient Brush static const char* const qglslPositionWithLinearGradientBrushVertexShader = "\ - attribute highp vec4 vertexCoordsArray; \ - uniform highp mat4 pmvMatrix; \ + attribute highp vec2 vertexCoordsArray; \ + uniform highp mat3 pmvMatrix; \ uniform mediump vec2 halfViewportSize; \ uniform highp vec3 linearData; \ uniform highp mat3 brushTransform; \ varying mediump float index; \ void setPosition() { \ - gl_Position = pmvMatrix * vertexCoordsArray;\ - gl_Position.xy = gl_Position.xy / gl_Position.w; \ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \ + gl_Position.xy = transformedPos.xy / transformedPos.z; \ mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \ - gl_Position.w = invertedHTexCoordsZ; \ + gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \ index = (dot(linearData.xy, hTexCoords.xy) * linearData.z) * invertedHTexCoordsZ; \ }"; @@ -178,20 +179,19 @@ static const char* const qglslLinearGradientBrushSrcFragmentShader = "\ // Conical Gradient Brush static const char* const qglslPositionWithConicalGradientBrushVertexShader = "\ - attribute highp vec4 vertexCoordsArray;\ - uniform highp mat4 pmvMatrix;\ + attribute highp vec2 vertexCoordsArray;\ + uniform highp mat3 pmvMatrix;\ uniform mediump vec2 halfViewportSize; \ uniform highp mat3 brushTransform; \ varying highp vec2 A; \ void setPosition(void)\ {\ - gl_Position = pmvMatrix * vertexCoordsArray;\ - gl_Position.xy = gl_Position.xy / gl_Position.w; \ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \ + gl_Position.xy = transformedPos.xy / transformedPos.z; \ mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \ - gl_Position.w = invertedHTexCoordsZ; \ + gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \ A = hTexCoords.xy * invertedHTexCoordsZ; \ }"; @@ -215,8 +215,8 @@ static const char* const qglslConicalGradientBrushSrcFragmentShader = "\n\ // Radial Gradient Brush static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\ - attribute highp vec4 vertexCoordsArray;\ - uniform highp mat4 pmvMatrix;\ + attribute highp vec2 vertexCoordsArray;\ + uniform highp mat3 pmvMatrix;\ uniform mediump vec2 halfViewportSize; \ uniform highp mat3 brushTransform; \ uniform highp vec2 fmp; \ @@ -224,13 +224,12 @@ static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\ varying highp vec2 A; \ void setPosition(void) \ {\ - gl_Position = pmvMatrix * vertexCoordsArray;\ - gl_Position.xy = gl_Position.xy / gl_Position.w; \ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \ + gl_Position.xy = transformedPos.xy / transformedPos.z; \ mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \ - gl_Position.w = invertedHTexCoordsZ; \ + gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \ A = hTexCoords.xy * invertedHTexCoordsZ; \ b = 2.0 * dot(A, fmp); \ }"; @@ -253,20 +252,19 @@ static const char* const qglslRadialGradientBrushSrcFragmentShader = "\ // Texture Brush static const char* const qglslPositionWithTextureBrushVertexShader = "\ - attribute highp vec4 vertexCoordsArray; \ - uniform highp mat4 pmvMatrix; \ + attribute highp vec2 vertexCoordsArray; \ + uniform highp mat3 pmvMatrix; \ uniform mediump vec2 halfViewportSize; \ uniform highp vec2 invertedTextureSize; \ uniform highp mat3 brushTransform; \ varying highp vec2 textureCoords; \ void setPosition(void) { \ - gl_Position = pmvMatrix * vertexCoordsArray;\ - gl_Position.xy = gl_Position.xy / gl_Position.w; \ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \ + gl_Position.xy = transformedPos.xy / transformedPos.z; \ mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \ - gl_Position.w = invertedHTexCoordsZ; \ + gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \ textureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \ }"; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 8ca2fd4..f52ed92 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -583,37 +583,37 @@ void QGL2PaintEngineExPrivate::updateMatrix() { // qDebug("QGL2PaintEngineExPrivate::updateMatrix()"); - // We set up the 4x4 transformation matrix on the vertex shaders to - // be the equivalent of glOrtho(0, w, h, 0, -1, 1) * transform: - // - // | 2/width 0 0 -1 | | m11 m21 0 dx | - // | 0 -2/height 0 1 | | m12 m22 0 dy | - // | 0 0 -1 0 | * | 0 0 1 0 | - // | 0 0 0 1 | | m13 m23 0 m33 | - // - // We expand out the multiplication to save the cost of a full 4x4 - // matrix multiplication as most of the components are trivial. const QTransform& transform = q->state()->matrix; - qreal wfactor = 2.0 / width; - qreal hfactor = -2.0 / height; - - pmvMatrix[0][0] = wfactor * transform.m11() - transform.m13(); - pmvMatrix[0][1] = hfactor * transform.m12() + transform.m13(); - pmvMatrix[0][2] = 0.0; - pmvMatrix[0][3] = transform.m13(); - pmvMatrix[1][0] = wfactor * transform.m21() - transform.m23(); - pmvMatrix[1][1] = hfactor * transform.m22() + transform.m23(); - pmvMatrix[1][2] = 0.0; - pmvMatrix[1][3] = transform.m23(); - pmvMatrix[2][0] = 0.0; - pmvMatrix[2][1] = 0.0; - pmvMatrix[2][2] = -1.0; - pmvMatrix[2][3] = 0.0; - pmvMatrix[3][0] = wfactor * transform.dx() - transform.m33(); - pmvMatrix[3][1] = hfactor * transform.dy() + transform.m33(); - pmvMatrix[3][2] = 0.0; - pmvMatrix[3][3] = transform.m33(); + // The projection matrix converts from Qt's coordinate system to GL's coordinate system + // * GL's viewport is 2x2, Qt's is width x height + // * GL has +y -> -y going from bottom -> top, Qt is the other way round + // * GL has [0,0] in the center, Qt has it in the top-left + // + // This results in the Projection matrix below, which is multiplied by the painter's + // transformation matrix, as shown below: + // + // Projection Matrix Painter Transform + // ------------------------------------------------ ------------------------ + // | 2.0 / width | 0.0 | -1.0 | | m11 | m21 | dx | + // | 0.0 | -2.0 / height | 1.0 | * | m12 | m22 | dy | + // | 0.0 | 0.0 | 1.0 | | m13 | m23 | m33 | + // ------------------------------------------------ ------------------------ + // + // NOTE: The resultant matrix is also transposed, as GL expects column-major matracies + + const GLfloat wfactor = 2.0f / width; + const GLfloat hfactor = -2.0f / height; + + pmvMatrix[0][0] = (wfactor * transform.m11()) - transform.m13(); + pmvMatrix[1][0] = (wfactor * transform.m21()) - transform.m23(); + pmvMatrix[2][0] = (wfactor * transform.dx() ) - transform.m33(); + pmvMatrix[0][1] = (hfactor * transform.m12()) + transform.m13(); + pmvMatrix[1][1] = (hfactor * transform.m22()) + transform.m23(); + pmvMatrix[2][1] = (hfactor * transform.dy() ) + transform.m33(); + pmvMatrix[0][2] = transform.m13(); + pmvMatrix[1][2] = transform.m23(); + pmvMatrix[2][2] = transform.m33(); // 1/10000 == 0.0001, so we have good enough res to cover curves // that span the entire widget... diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 33ce24d..f1ec6e6 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -254,7 +254,7 @@ public: GLfloat staticVertexCoordinateArray[8]; GLfloat staticTextureCoordinateArray[8]; - GLfloat pmvMatrix[4][4]; + GLfloat pmvMatrix[3][3]; QGLEngineShaderManager* shaderManager; -- cgit v0.12 From be2acbcd6cfbaa75b502157061c385129e8f0b35 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Wed, 23 Dec 2009 09:16:41 +1000 Subject: Use libjpeg's builtin scaler for implementing setScaledSize() The libjpeg library has builtin support for scaling to 1/2, 1/4, and 1/8 the original size very quickly. Use this in the implementation of setScaledSize() to get close to the desired size and then scale with QImageSmoothScaler the rest of the way. Task-number: QT-2023 Reviewed-by: Daniel Pope --- src/plugins/imageformats/jpeg/qjpeghandler.cpp | 5 ++--- tests/auto/qimagereader/tst_qimagereader.cpp | 10 +++++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp index aa239ec..8da6610 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp +++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp @@ -758,10 +758,9 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, quality = 75; #ifndef QT_NO_IMAGE_SMOOTHSCALE - // If high quality not required, shrink image during decompression - if (scaledSize.isValid() && !scaledSize.isEmpty() && quality < HIGH_QUALITY_THRESHOLD) { + if (!scaledSize.isEmpty()) { cinfo.scale_denom = qMin(cinfo.image_width / scaledSize.width(), - cinfo.image_width / scaledSize.height()); + cinfo.image_height / scaledSize.height()); if (cinfo.scale_denom < 2) { cinfo.scale_denom = 1; } else if (cinfo.scale_denom < 4) { diff --git a/tests/auto/qimagereader/tst_qimagereader.cpp b/tests/auto/qimagereader/tst_qimagereader.cpp index 15b1c1c..630cc03 100644 --- a/tests/auto/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/qimagereader/tst_qimagereader.cpp @@ -322,7 +322,15 @@ void tst_QImageReader::setScaledSize_data() QTest::newRow("PPM: test") << "test.ppm" << QSize(10, 10) << QByteArray("ppm"); QTest::newRow("XBM: gnus") << "gnus" << QSize(200, 200) << QByteArray("xbm"); #ifdef QTEST_HAVE_JPEG - QTest::newRow("JPEG: beavis") << "beavis" << QSize(200, 200) << QByteArray("jpeg"); + QTest::newRow("JPEG: beavis A") << "beavis" << QSize(200, 200) << QByteArray("jpeg"); + QTest::newRow("JPEG: beavis B") << "beavis" << QSize(175, 175) << QByteArray("jpeg"); + QTest::newRow("JPEG: beavis C") << "beavis" << QSize(100, 100) << QByteArray("jpeg"); + QTest::newRow("JPEG: beavis D") << "beavis" << QSize(100, 200) << QByteArray("jpeg"); + QTest::newRow("JPEG: beavis E") << "beavis" << QSize(200, 100) << QByteArray("jpeg"); + QTest::newRow("JPEG: beavis F") << "beavis" << QSize(87, 87) << QByteArray("jpeg"); + QTest::newRow("JPEG: beavis G") << "beavis" << QSize(50, 45) << QByteArray("jpeg"); + QTest::newRow("JPEG: beavis H") << "beavis" << QSize(43, 43) << QByteArray("jpeg"); + QTest::newRow("JPEG: beavis I") << "beavis" << QSize(25, 25) << QByteArray("jpeg"); #endif // QTEST_HAVE_JPEG #ifdef QTEST_HAVE_GIF QTest::newRow("GIF: earth") << "earth" << QSize(200, 200) << QByteArray("gif"); -- cgit v0.12 From 762496dba277f31e55a216c9761a51bf306adec0 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Wed, 23 Dec 2009 11:48:55 +1000 Subject: Add support for ClipRect to the jpeg image plugin The jpeg is read and scanlines discarded until the clip region is found (libjpeg doesn't support direct seeking). This is faster than the previous approach of reading the entire jpeg and then clipping. Task-number: QT-2023 Reviewed-by: Sarah Smith Reviewed-by: Daniel Pope --- src/plugins/imageformats/jpeg/qjpeghandler.cpp | 233 ++++++++++++++++--------- src/plugins/imageformats/jpeg/qjpeghandler.h | 2 + 2 files changed, 149 insertions(+), 86 deletions(-) diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp index 8da6610..7165c38 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp +++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp @@ -90,9 +90,6 @@ public: QImage scale(); -protected: - int scaledWidth(void) const; - private: QImageSmoothScalerPrivate *d; virtual QRgb *scanLine(const int line = 0, const QImage *src = 0); @@ -140,11 +137,6 @@ void QImageSmoothScalerPrivate::setup(const int srcWidth, const int srcHeight, hasAlpha = hasAlphaChannel; } -int QImageSmoothScaler::scaledWidth() const -{ - return d->cols; -} - QImageSmoothScaler::~QImageSmoothScaler() { delete d; @@ -443,20 +435,18 @@ QImage QImageSmoothScaler::scale() class jpegSmoothScaler : public QImageSmoothScaler { public: - jpegSmoothScaler(struct jpeg_decompress_struct *info, int dstWidth, int dstHeight) - : QImageSmoothScaler(info->output_width, info->output_height, dstWidth, dstHeight) + jpegSmoothScaler(struct jpeg_decompress_struct *info, const QSize& dstSize, const QRect& clipRect) + : QImageSmoothScaler(clipRect.width(), clipRect.height(), + dstSize.width(), dstSize.height()) { - cinfo = info; - cols24Bit = scaledWidth() * 3; - - cacheHeight = 1; - imageCache = QImage( info->output_width, cacheHeight, QImage::Format_RGB32 ); + cinfo = info; + clip = clipRect; + imageCache = QImage(info->output_width, 1, QImage::Format_RGB32); } private: - int cols24Bit; + QRect clip; QImage imageCache; - int cacheHeight; struct jpeg_decompress_struct *cinfo; QRgb *scanLine(const int line = 0, const QImage *src = 0) @@ -468,33 +458,42 @@ private: Q_UNUSED(src); uchar* data = imageCache.bits(); + + // Read ahead if we haven't reached the first clipped scanline yet. + while (int(cinfo->output_scanline) < clip.y() && + cinfo->output_scanline < cinfo->output_height) + jpeg_read_scanlines(cinfo, &data, 1); + + // Read the next scanline. We assume that "line" + // will never be >= clip.height(). jpeg_read_scanlines(cinfo, &data, 1); - out = (QRgb*)imageCache.scanLine(0); + if (cinfo->output_scanline == cinfo->output_height) + jpeg_finish_decompress(cinfo); + + out = ((QRgb*)data) + clip.x(); // // The smooth scale algorithm only works on 32-bit images; // convert from (8|24) bits to 32. // if (cinfo->output_components == 1) { - in = (uchar*)out + scaledWidth(); - for (uint i = scaledWidth(); i--; ) { - in--; + in = data + clip.right(); + for (int i = clip.width(); i--; ) { out[i] = qRgb(*in, *in, *in); + in--; } - } else if (cinfo->out_color_space == JCS_CMYK) { - int cols32Bit = scaledWidth() * 4; - in = (uchar*)out + cols32Bit; - for (uint i = scaledWidth(); i--; ) { - in -= 4; - int k = in[3]; - out[i] = qRgb(k * in[0] / 255, k * in[1] / 255, k * in[2] / 255); - //out[i] = qRgb(in[0], in[1], in[2]); - } - } else { - in = (uchar*)out + cols24Bit; - for (uint i = scaledWidth(); i--; ) { - in -= 3; + } else if (cinfo->out_color_space == JCS_CMYK) { + in = data + clip.right() * 4; + for (int i = clip.width(); i--; ) { + int k = in[3]; + out[i] = qRgb(k * in[0] / 255, k * in[1] / 255, k * in[2] / 255); + in -= 4; + } + } else { + in = data + clip.right() * 3; + for (int i = clip.width(); i--; ) { out[i] = qRgb(in[0], in[1], in[2]); + in -= 3; } } @@ -693,7 +692,7 @@ static bool read_jpeg_format(QIODevice *device, QImage::Format &format) } static bool ensureValidImage(QImage *dest, struct jpeg_decompress_struct *info, - bool dummy = false) + const QSize& size) { QImage::Format format; switch (info->output_components) { @@ -708,13 +707,8 @@ static bool ensureValidImage(QImage *dest, struct jpeg_decompress_struct *info, return false; // unsupported format } - const QSize size(info->output_width, info->output_height); if (dest->size() != size || dest->format() != format) { - static uchar dummyImage[1]; - if (dummy) // Create QImage but don't read the pixels - *dest = QImage(dummyImage, size.width(), size.height(), format); - else - *dest = QImage(size, format); + *dest = QImage(size, format); if (format == QImage::Format_Indexed8) { dest->setColorCount(256); @@ -727,12 +721,9 @@ static bool ensureValidImage(QImage *dest, struct jpeg_decompress_struct *info, } static bool read_jpeg_image(QIODevice *device, QImage *outImage, - QSize scaledSize, int inQuality ) + QSize scaledSize, const QRect& clipRect, + int inQuality ) { -#ifdef QT_NO_IMAGE_SMOOTHSCALE - Q_UNUSED( scaledSize ); -#endif - struct jpeg_decompress_struct cinfo; struct my_jpeg_source_mgr *iod_src = new my_jpeg_source_mgr(device); @@ -757,10 +748,17 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, if (quality < 0) quality = 75; -#ifndef QT_NO_IMAGE_SMOOTHSCALE + // Determine the scale factor to pass to libjpeg for quick downscaling. if (!scaledSize.isEmpty()) { - cinfo.scale_denom = qMin(cinfo.image_width / scaledSize.width(), - cinfo.image_height / scaledSize.height()); + if (clipRect.isEmpty()) { + cinfo.scale_denom = + qMin(cinfo.image_width / scaledSize.width(), + cinfo.image_height / scaledSize.height()); + } else { + cinfo.scale_denom = + qMin(clipRect.width() / scaledSize.width(), + clipRect.height() / scaledSize.height()); + } if (cinfo.scale_denom < 2) { cinfo.scale_denom = 1; } else if (cinfo.scale_denom < 4) { @@ -771,9 +769,19 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, cinfo.scale_denom = 8; } cinfo.scale_num = 1; + if (!clipRect.isEmpty()) { + // Correct the scale factor so that we clip accurately. + // It is recommended that the clip rectangle be aligned + // on an 8-pixel boundary for best performance. + while (cinfo.scale_denom > 1 && + ((clipRect.x() % cinfo.scale_denom) != 0 || + (clipRect.y() % cinfo.scale_denom) != 0 || + (clipRect.width() % cinfo.scale_denom) != 0 || + (clipRect.height() % cinfo.scale_denom) != 0)) { + cinfo.scale_denom /= 2; + } + } } -#endif - // If high quality not required, use fast decompression if( quality < HIGH_QUALITY_THRESHOLD ) { @@ -781,54 +789,102 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, cinfo.do_fancy_upsampling = FALSE; } + (void) jpeg_calc_output_dimensions(&cinfo); - (void) jpeg_start_decompress(&cinfo); + // Determine the clip region to extract. + QRect imageRect(0, 0, cinfo.output_width, cinfo.output_height); + QRect clip; + if (clipRect.isEmpty()) { + clip = imageRect; + } else if (cinfo.scale_denom == 1) { + clip = clipRect.intersected(imageRect); + } else { + // The scale factor was corrected above to ensure that + // we don't miss pixels when we scale the clip rectangle. + clip = QRect(clipRect.x() / int(cinfo.scale_denom), + clipRect.y() / int(cinfo.scale_denom), + clipRect.width() / int(cinfo.scale_denom), + clipRect.height() / int(cinfo.scale_denom)); + clip = clip.intersected(imageRect); + } #ifndef QT_NO_IMAGE_SMOOTHSCALE - if (scaledSize.isValid() && scaledSize != QSize(cinfo.output_width, cinfo.output_height) + if (scaledSize.isValid() && scaledSize != clip.size() && quality >= HIGH_QUALITY_THRESHOLD) { - jpegSmoothScaler scaler(&cinfo, scaledSize.width(), scaledSize.height()); + (void) jpeg_start_decompress(&cinfo); + + jpegSmoothScaler scaler(&cinfo, scaledSize, clip); *outImage = scaler.scale(); } else #endif { - if (!ensureValidImage(outImage, &cinfo)) + // Allocate memory for the clipped QImage. + if (!ensureValidImage(outImage, &cinfo, clip.size())) longjmp(jerr.setjmp_buffer, 1); - uchar* data = outImage->bits(); - int bpl = outImage->bytesPerLine(); - while (cinfo.output_scanline < cinfo.output_height) { - uchar *d = data + cinfo.output_scanline * bpl; - (void) jpeg_read_scanlines(&cinfo, - &d, - 1); - } - (void) jpeg_finish_decompress(&cinfo); - - if (cinfo.output_components == 3) { - // Expand 24->32 bpp. - for (uint j=0; jscanLine(j) + cinfo.output_width * 3; - QRgb *out = (QRgb*)outImage->scanLine(j); - - for (uint i=cinfo.output_width; i--;) { - in-=3; - out[i] = qRgb(in[0], in[1], in[2]); + // Avoid memcpy() overhead if grayscale with no clipping. + bool quickGray = (cinfo.output_components == 1 && + clip == imageRect); + if (!quickGray) { + // Ask the jpeg library to allocate a temporary row. + // The library will automatically delete it for us later. + // The libjpeg docs say we should do this before calling + // jpeg_start_decompress(). We can't use "new" here + // because we are inside the setjmp() block and an error + // in the jpeg input stream would cause a memory leak. + JSAMPARRAY rows = (cinfo.mem->alloc_sarray) + ((j_common_ptr)&cinfo, JPOOL_IMAGE, + cinfo.output_width * cinfo.output_components, 1); + + (void) jpeg_start_decompress(&cinfo); + + while (cinfo.output_scanline < cinfo.output_height) { + int y = int(cinfo.output_scanline) - clip.y(); + if (y >= clip.height()) + break; // We've read the entire clip region, so abort. + + (void) jpeg_read_scanlines(&cinfo, rows, 1); + + if (y < 0) + continue; // Haven't reached the starting line yet. + + if (cinfo.output_components == 3) { + // Expand 24->32 bpp. + uchar *in = rows[0] + clip.x() * 3; + QRgb *out = (QRgb*)outImage->scanLine(y); + for (int i = 0; i < clip.width(); ++i) { + *out++ = qRgb(in[0], in[1], in[2]); + in += 3; + } + } else if (cinfo.out_color_space == JCS_CMYK) { + // Convert CMYK->RGB. + uchar *in = rows[0] + clip.x() * 4; + QRgb *out = (QRgb*)outImage->scanLine(y); + for (int i = 0; i < clip.width(); ++i) { + int k = in[3]; + *out++ = qRgb(k * in[0] / 255, k * in[1] / 255, + k * in[2] / 255); + in += 4; + } + } else if (cinfo.output_components == 1) { + // Grayscale. + memcpy(outImage->scanLine(y), + rows[0] + clip.x(), clip.width()); } } - } else if (cinfo.out_color_space == JCS_CMYK) { - for (uint j = 0; j < cinfo.output_height; ++j) { - uchar *in = outImage->scanLine(j) + cinfo.output_width * 4; - QRgb *out = (QRgb*)outImage->scanLine(j); - - for (uint i = cinfo.output_width; i--; ) { - in-=4; - int k = in[3]; - out[i] = qRgb(k * in[0] / 255, k * in[1] / 255, k * in[2] / 255); - } + } else { + // Load unclipped grayscale data directly into the QImage. + (void) jpeg_start_decompress(&cinfo); + while (cinfo.output_scanline < cinfo.output_height) { + uchar *row = outImage->scanLine(cinfo.output_scanline); + (void) jpeg_read_scanlines(&cinfo, &row, 1); } } + + if (cinfo.output_scanline == cinfo.output_height) + (void) jpeg_finish_decompress(&cinfo); + if (cinfo.density_unit == 1) { outImage->setDotsPerMeterX(int(100. * cinfo.X_density / 2.54)); outImage->setDotsPerMeterY(int(100. * cinfo.Y_density / 2.54)); @@ -837,7 +893,7 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, outImage->setDotsPerMeterY(int(100. * cinfo.Y_density)); } - if (scaledSize.isValid() && scaledSize != QSize(cinfo.output_width, cinfo.output_height)) + if (scaledSize.isValid() && scaledSize != clip.size()) *outImage = outImage->scaled(scaledSize, Qt::IgnoreAspectRatio, Qt::FastTransformation); } } @@ -1101,7 +1157,7 @@ bool QJpegHandler::read(QImage *image) { if (!canRead()) return false; - return read_jpeg_image(device(), image, scaledSize, quality); + return read_jpeg_image(device(), image, scaledSize, clipRect, quality); } bool QJpegHandler::write(const QImage &image) @@ -1115,6 +1171,7 @@ bool QJpegHandler::supportsOption(ImageOption option) const #ifndef QT_NO_IMAGE_SMOOTHSCALE || option == ScaledSize #endif + || option == ClipRect || option == Size || option == ImageFormat; } @@ -1127,6 +1184,8 @@ QVariant QJpegHandler::option(ImageOption option) const } else if (option == ScaledSize) { return scaledSize; #endif + } else if (option == ClipRect) { + return clipRect; } else if (option == Size) { if (canRead() && !device()->isSequential()) { qint64 pos = device()->pos(); @@ -1157,6 +1216,8 @@ void QJpegHandler::setOption(ImageOption option, const QVariant &value) else if ( option == ScaledSize ) scaledSize = value.toSize(); #endif + else if ( option == ClipRect ) + clipRect = value.toRect(); } QByteArray QJpegHandler::name() const diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.h b/src/plugins/imageformats/jpeg/qjpeghandler.h index 0a14a88..108b131 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler.h +++ b/src/plugins/imageformats/jpeg/qjpeghandler.h @@ -44,6 +44,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -67,6 +68,7 @@ public: private: int quality; QSize scaledSize; + QRect clipRect; }; QT_END_NAMESPACE -- cgit v0.12 From 61f214e60a074cbaf2413b2c77ed5a4cfd638edb Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Wed, 23 Dec 2009 15:10:15 +1000 Subject: Implement ScaledClipRect in the jpeg image plugin Where possible, we convert the post-scale clip rectangle into a pre-scale clip rectangle because it is more efficient to clip first. Task-number: QT-2023 Reviewed-by: Sarah Smith Reviewed-by: Daniel Pope --- src/plugins/imageformats/jpeg/qjpeghandler.cpp | 55 +++++++++++++++++++++----- src/plugins/imageformats/jpeg/qjpeghandler.h | 1 + 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp index 7165c38..11608ef 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp +++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp @@ -721,8 +721,8 @@ static bool ensureValidImage(QImage *dest, struct jpeg_decompress_struct *info, } static bool read_jpeg_image(QIODevice *device, QImage *outImage, - QSize scaledSize, const QRect& clipRect, - int inQuality ) + QSize scaledSize, QRect scaledClipRect, + QRect clipRect, int inQuality ) { struct jpeg_decompress_struct cinfo; @@ -748,6 +748,42 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, if (quality < 0) quality = 75; + // If possible, merge the scaledClipRect into either scaledSize + // or clipRect to avoid doing a separate scaled clipping pass. + // Best results are achieved by clipping before scaling, not after. + if (!scaledClipRect.isEmpty()) { + if (scaledSize.isEmpty() && clipRect.isEmpty()) { + // No clipping or scaling before final clip. + clipRect = scaledClipRect; + scaledClipRect = QRect(); + } else if (scaledSize.isEmpty()) { + // Clipping, but no scaling: combine the clip regions. + scaledClipRect.translate(clipRect.topLeft()); + clipRect = scaledClipRect.intersected(clipRect); + scaledClipRect = QRect(); + } else if (clipRect.isEmpty()) { + // No clipping, but scaling: if we can map back to an + // integer pixel boundary, then clip before scaling. + if ((cinfo.image_width % scaledSize.width()) == 0 && + (cinfo.image_height % scaledSize.height()) == 0) { + int x = scaledClipRect.x() * cinfo.image_width / + scaledSize.width(); + int y = scaledClipRect.y() * cinfo.image_height / + scaledSize.height(); + int width = (scaledClipRect.right() + 1) * + cinfo.image_width / scaledSize.width() - x; + int height = (scaledClipRect.bottom() + 1) * + cinfo.image_height / scaledSize.height() - y; + clipRect = QRect(x, y, width, height); + scaledSize = scaledClipRect.size(); + scaledClipRect = QRect(); + } + } else { + // Clipping and scaling: too difficult to figure out, + // and not a likely use case, so do it the long way. + } + } + // Determine the scale factor to pass to libjpeg for quick downscaling. if (!scaledSize.isEmpty()) { if (clipRect.isEmpty()) { @@ -900,6 +936,8 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, jpeg_destroy_decompress(&cinfo); delete iod_src; + if (!scaledClipRect.isEmpty()) + *outImage = outImage->copy(scaledClipRect); return !outImage->isNull(); } @@ -1157,7 +1195,7 @@ bool QJpegHandler::read(QImage *image) { if (!canRead()) return false; - return read_jpeg_image(device(), image, scaledSize, clipRect, quality); + return read_jpeg_image(device(), image, scaledSize, scaledClipRect, clipRect, quality); } bool QJpegHandler::write(const QImage &image) @@ -1168,9 +1206,8 @@ bool QJpegHandler::write(const QImage &image) bool QJpegHandler::supportsOption(ImageOption option) const { return option == Quality -#ifndef QT_NO_IMAGE_SMOOTHSCALE || option == ScaledSize -#endif + || option == ScaledClipRect || option == ClipRect || option == Size || option == ImageFormat; @@ -1180,10 +1217,10 @@ QVariant QJpegHandler::option(ImageOption option) const { if (option == Quality) { return quality; -#ifndef QT_NO_IMAGE_SMOOTHSCALE } else if (option == ScaledSize) { return scaledSize; -#endif + } else if (option == ScaledClipRect) { + return scaledClipRect; } else if (option == ClipRect) { return clipRect; } else if (option == Size) { @@ -1212,10 +1249,10 @@ void QJpegHandler::setOption(ImageOption option, const QVariant &value) { if (option == Quality) quality = value.toInt(); -#ifndef QT_NO_IMAGE_SMOOTHSCALE else if ( option == ScaledSize ) scaledSize = value.toSize(); -#endif + else if ( option == ScaledClipRect ) + scaledClipRect = value.toRect(); else if ( option == ClipRect ) clipRect = value.toRect(); } diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.h b/src/plugins/imageformats/jpeg/qjpeghandler.h index 108b131..6870cd6 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler.h +++ b/src/plugins/imageformats/jpeg/qjpeghandler.h @@ -68,6 +68,7 @@ public: private: int quality; QSize scaledSize; + QRect scaledClipRect; QRect clipRect; }; -- cgit v0.12 From 09cd5f7324b8346f1df43a3dff61d337073a6358 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Wed, 23 Dec 2009 11:10:24 +0200 Subject: Device flickers badly when orientation change occurs Currently what happens when orientation changes is: 1. Application gets notification that status pane size has changed. 2. Qt resizes S60Data to new size, and sends resize event. 3. Application redraws itself. But style is still using incorrect screen size internally, so background brush is incorrect. Redrawing thus might showup white rect on-screen. 4. Style gets notification that orientation is changed and style then deletes existing background brush. 5. Style creates a new background brush and sends events to all toplevel widgets that style has changed 6. Widgets might draw themselves with new style background brush. What this fix changes is: 1. When application first tries to redraw itself, style notices that the background brush size does not match to active screen size. 2. Style immediately re-creates background brush 3. Since cachekey for pixmaps won't match, new background is not drawn until after background brush has been updated to application palette. 4. Due to #1 style needs to remove deletion of background brush from clearCaches to avoid deleting (and re-creating) background twice. Task-number: QTBUG-6428 Reviewed-by: Janne Koskinen --- src/gui/styles/qs60style.cpp | 1 - src/gui/styles/qs60style_s60.cpp | 17 ++++++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index ed86f5a..01b9fa4 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -372,7 +372,6 @@ void QS60StylePrivate::clearCaches(CacheClearReason reason) case CC_LayoutChange: // when layout changes, the colors remain in cache, but graphics and fonts can change m_mappedFontsCache.clear(); - deleteBackground(); QPixmapCache::clear(); break; case CC_ThemeChange: diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index 13ac301..fb9665a 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -1133,9 +1133,21 @@ QPixmap QS60StylePrivate::frame(SkinFrameElements frame, const QSize &size, Skin QPixmap QS60StylePrivate::backgroundTexture() { + bool createNewBackground = false; if (!m_background) { + createNewBackground = true; + } else { + //if background brush does not match screensize, re-create it + if (m_background->width() != S60->screenWidthInPixels || + m_background->height() != S60->screenHeightInPixels) { + delete m_background; + createNewBackground = true; + } + } + + if (createNewBackground) { QPixmap background = part(QS60StyleEnums::SP_QsnBgScreen, - QSize(S60->screenWidthInPixels, S60->screenHeightInPixels), 0, SkinElementFlags()); + QSize(S60->screenWidthInPixels, S60->screenHeightInPixels), 0, SkinElementFlags()); m_background = new QPixmap(background); } return *m_background; @@ -1143,8 +1155,7 @@ QPixmap QS60StylePrivate::backgroundTexture() QSize QS60StylePrivate::screenSize() { - const TSize screenSize = QS60Data::screenDevice()->SizeInPixels(); - return QSize(screenSize.iWidth, screenSize.iHeight); + return QSize(S60->screenWidthInPixels, S60->screenHeightInPixels); } QS60Style::QS60Style() -- cgit v0.12 From 6928ffb7533d23f0be220116a7b11d90bee72fb5 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Wed, 23 Dec 2009 13:25:51 +0200 Subject: QWidget with the window flag Qt::Dialog is not decorated as a dialog Previously style casted widgets to QDialog to see if it is able to draw dialog background theme graphic. As a fix, we now query window flag from the widget and if it is equivalent of Qt::Dialog, draw dialog background. Task-number: QTBUG-5930 Reviewed-by: Janne Koskinen --- src/gui/styles/qs60style.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 01b9fa4..b386c28 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -339,7 +339,7 @@ QColor QS60StylePrivate::lighterColor(const QColor &baseColor) bool QS60StylePrivate::drawsOwnThemeBackground(const QWidget *widget) { - return qobject_cast (widget); + return (widget ? (widget->windowType() == Qt::Dialog) : false); } QFont QS60StylePrivate::s60Font( -- cgit v0.12 From 7eb0abe8cd9f810905ec079e45ece1ed7fc9b9aa Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Wed, 23 Dec 2009 13:37:50 +0200 Subject: Setting background color to a QDialog doesn't work Since dialogs use their own theme graphics for background, regular method of checking the palette fails (as generic background brush is probably unchanged). Therefore to check if the dialog background is using default (=theme graphic), it needs to check the cache key value of background - so that it matches with the one in stored theme palette. Task-number: QTBUG-5898 Reviewed-by: Janne Koskinen --- src/gui/styles/qs60style.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index b386c28..e370ed0 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -2160,7 +2160,10 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti || qobject_cast (widget) #endif //QT_NO_MENU ) { - if (QS60StylePrivate::canDrawThemeBackground(option->palette.base())) + //Need extra check since dialogs have their own theme background + if (QS60StylePrivate::canDrawThemeBackground(option->palette.base()) && + option->palette.window().texture().cacheKey() == + QS60StylePrivate::m_themePalette->window().texture().cacheKey()) QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_OptionsMenu, painter, option->rect, flags); else commonStyleDraws = true; -- cgit v0.12 From 5f7b681661d8067b3fd954f04b7a25d833f5c92a Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 23 Dec 2009 14:17:59 +0200 Subject: Changed autodetection logic for stlport version and sqlite in Symbian To support building Qt as part of Symbian SDK where epoc32 is not yet populated, changed the autodetection logic in determining stlport version. Now, we assume that we want the new version, unless only the old version exists on SDK already. Sqlite binaries export autodetection is now skipped if CONFIG value symbian_no_export_sqlite exists, allowing clean builds to explicitly suppress exporting. Task-number: QTBUG-6971 Reviewed-by: axis --- mkspecs/features/symbian/platform_paths.prf | 22 +++++++++++++--------- .../sqldrivers/sqlite_symbian/sqlite_symbian.pro | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/mkspecs/features/symbian/platform_paths.prf b/mkspecs/features/symbian/platform_paths.prf index bec9811..f5caae0 100644 --- a/mkspecs/features/symbian/platform_paths.prf +++ b/mkspecs/features/symbian/platform_paths.prf @@ -216,10 +216,11 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { OS_LAYER_SSL_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/openssl) # stlportv5 is preferred over stlport as it has the throwing version of operator new - exists($${EPOCROOT}epoc32/include/stdapis/stlportv5) { - OS_LAYER_STDCPP_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/stlportv5) - } else { + exists($${EPOCROOT}epoc32/include/stdapis/stlport) \ + :!exists($${EPOCROOT}epoc32/include/stdapis/stlportv5) { OS_LAYER_STDCPP_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/stlport) + } else { + OS_LAYER_STDCPP_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/stlportv5) } OS_LAYER_BOOST_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/boost) @@ -427,12 +428,15 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { /epoc32/include/stdapis/openssl # stlportv5 is preferred over stlport as it has the throwing version of operator new - exists($${EPOCROOT}epoc32/include/osextensions/stdapis/stlportv5)|exists($${EPOCROOT}epoc32/include/stdapis/stlportv5) { - OS_LAYER_STDCPP_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/stlportv5) \ - /epoc32/include/stdapis/stlportv5 - } else { - OS_LAYER_STDCPP_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/stlport) \ - /epoc32/include/stdapis/stlport + OS_LAYER_STDCPP_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/stlportv5) \ + /epoc32/include/stdapis/stlportv5 + exists($${EPOCROOT}epoc32/include/osextensions/stdapis/stlport) \ + |exists($${EPOCROOT}epoc32/include/stdapis/stlport) { + !exists($${EPOCROOT}epoc32/include/osextensions/stdapis/stlportv5) \ + :!exists($${EPOCROOT}epoc32/include/stdapis/stlportv5) { + OS_LAYER_STDCPP_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/stlport) \ + /epoc32/include/stdapis/stlport + } } OS_LAYER_BOOST_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/boost) \ diff --git a/src/plugins/sqldrivers/sqlite_symbian/sqlite_symbian.pro b/src/plugins/sqldrivers/sqlite_symbian/sqlite_symbian.pro index 9687908..691cce1 100644 --- a/src/plugins/sqldrivers/sqlite_symbian/sqlite_symbian.pro +++ b/src/plugins/sqldrivers/sqlite_symbian/sqlite_symbian.pro @@ -3,7 +3,7 @@ TEMPLATE = subdirs # We just want to export the sqlite3 binaries for Symbian for platforms that do not have them. symbian { - !exists($${EPOCROOT}epoc32/release/armv5/lib/sqlite3.dso) { + !symbian_no_export_sqlite:!exists($${EPOCROOT}epoc32/release/armv5/lib/sqlite3.dso) { BLD_INF_RULES.prj_exports += ":zip SQLite3_v9.2.zip" } } -- cgit v0.12 From 01cf310d21b17d8f57911ae194eaa0ca2472d155 Mon Sep 17 00:00:00 2001 From: Janne Koskinen Date: Wed, 23 Dec 2009 15:33:49 +0200 Subject: Revert "Daylight savings time for Symbian." Reverted due to buildbreak on 3.2 ARMV5 Urel. This reverts commit 2a20705f874ddad55282f22fabfe30927729ae50. --- src/corelib/corelib.pro | 2 -- src/corelib/tools/qdatetime.cpp | 60 +++++++++++++--------------------- tests/auto/qdatetime/tst_qdatetime.cpp | 7 ---- 3 files changed, 23 insertions(+), 46 deletions(-) diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index 7f33791..9a15bf1 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -35,6 +35,4 @@ symbian: { # Workaroud for problems with paging this dll MMP_RULES -= PAGED MMP_RULES *= UNPAGED - # Timezone server - LIBS += -ltzclient } diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 240f0cf..db6435e 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -75,7 +75,6 @@ #if defined(Q_OS_SYMBIAN) #include -#include #endif QT_BEGIN_NAMESPACE @@ -3722,32 +3721,23 @@ static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time) #elif defined(Q_OS_SYMBIAN) // months and days are zero index based _LIT(KUnixEpoch, "19700000:000000.000000"); + TTimeIntervalSeconds utcOffset = User::UTCOffset(); TTimeIntervalSeconds tTimeIntervalSecsSince1Jan1970UTC(secsSince1Jan1970UTC); TTime epochTTime; TInt err = epochTTime.Set(KUnixEpoch); tm res; if(err == KErrNone) { TTime utcTTime = epochTTime + tTimeIntervalSecsSince1Jan1970UTC; - TRAP(err, - RTz tz; - User::LeaveIfError(tz.Connect()); - CleanupClosePushL(tz); - res.tm_isdst = tz.IsDaylightSavingOnL(*tz.GetTimeZoneIdL(),utcTTime); - User::LeaveIfError(tz.ConvertToLocalTime(utcTTime)); - CleanupStack::PopAndDestroy(&tz)); - if (KErrNone == err) { - TDateTime localDateTime = utcTTime.DateTime(); - res.tm_sec = localDateTime.Second(); - res.tm_min = localDateTime.Minute(); - res.tm_hour = localDateTime.Hour(); - res.tm_mday = localDateTime.Day() + 1; // non-zero based index for tm struct - res.tm_mon = localDateTime.Month(); - res.tm_year = localDateTime.Year() - 1900; - // Symbian's timezone server doesn't know how to handle DST before year 1997 - if (res.tm_year < 97) - res.tm_isdst = -1; - brokenDown = &res; - } + utcTTime = utcTTime + utcOffset; + TDateTime utcDateTime = utcTTime.DateTime(); + res.tm_sec = utcDateTime.Second(); + res.tm_min = utcDateTime.Minute(); + res.tm_hour = utcDateTime.Hour(); + res.tm_mday = utcDateTime.Day() + 1; // non-zero based index for tm struct + res.tm_mon = utcDateTime.Month(); + res.tm_year = utcDateTime.Year() - 1900; + res.tm_isdst = 0; + brokenDown = &res; } #elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) // use the reentrant version of localtime() where available @@ -3822,27 +3812,23 @@ static void localToUtc(QDate &date, QTime &time, int isdst) #elif defined(Q_OS_SYMBIAN) // months and days are zero index based _LIT(KUnixEpoch, "19700000:000000.000000"); + TTimeIntervalSeconds utcOffset = TTimeIntervalSeconds(0 - User::UTCOffset().Int()); TTimeIntervalSeconds tTimeIntervalSecsSince1Jan1970UTC(secsSince1Jan1970UTC); TTime epochTTime; TInt err = epochTTime.Set(KUnixEpoch); tm res; if(err == KErrNone) { - TTime localTTime = epochTTime + tTimeIntervalSecsSince1Jan1970UTC; - RTz tz; - if (KErrNone == tz.Connect()) { - if (KErrNone == tz.ConvertToUniversalTime(localTTime)) { - TDateTime utcDateTime = localTTime.DateTime(); - res.tm_sec = utcDateTime.Second(); - res.tm_min = utcDateTime.Minute(); - res.tm_hour = utcDateTime.Hour(); - res.tm_mday = utcDateTime.Day() + 1; // non-zero based index for tm struct - res.tm_mon = utcDateTime.Month(); - res.tm_year = utcDateTime.Year() - 1900; - res.tm_isdst = (int)isdst; - brokenDown = &res; - } - tz.Close(); - } + TTime utcTTime = epochTTime + tTimeIntervalSecsSince1Jan1970UTC; + utcTTime = utcTTime + utcOffset; + TDateTime utcDateTime = utcTTime.DateTime(); + res.tm_sec = utcDateTime.Second(); + res.tm_min = utcDateTime.Minute(); + res.tm_hour = utcDateTime.Hour(); + res.tm_mday = utcDateTime.Day() + 1; // non-zero based index for tm struct + res.tm_mon = utcDateTime.Month(); + res.tm_year = utcDateTime.Year() - 1900; + res.tm_isdst = (int)isdst; + brokenDown = &res; } #elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) // use the reentrant version of gmtime() where available diff --git a/tests/auto/qdatetime/tst_qdatetime.cpp b/tests/auto/qdatetime/tst_qdatetime.cpp index 32fa398..1140402 100644 --- a/tests/auto/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/qdatetime/tst_qdatetime.cpp @@ -147,16 +147,9 @@ Q_DECLARE_METATYPE(QTime) tst_QDateTime::tst_QDateTime() { -#ifdef Q_OS_SYMBIAN - // Symbian's timezone server cannot handle DST correctly for dates before year 1997 - uint x1 = QDateTime(QDate(2000, 1, 1), QTime()).toTime_t(); - uint x2 = QDateTime(QDate(2000, 6, 1), QTime()).toTime_t(); - europeanTimeZone = (x1 == 946681200 && x2 == 959810400); -#else uint x1 = QDateTime(QDate(1990, 1, 1), QTime()).toTime_t(); uint x2 = QDateTime(QDate(1990, 6, 1), QTime()).toTime_t(); europeanTimeZone = (x1 == 631148400 && x2 == 644191200); -#endif } tst_QDateTime::~tst_QDateTime() -- cgit v0.12 From 2df5bd18c21e0d7a48a61558d06d861118de03e2 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Wed, 23 Dec 2009 16:03:28 +0200 Subject: QComboboxes are squeezed in QVGA screens ComboBoxes and SpinBoxes are squeezed in QVGA screens, due to dodgy style calculations. This fix ensures that sub-widget buttons for these widgets are always square. Task-number: QT-2158 (internal) Reviewed-by: axis --- src/gui/styles/qs60style.cpp | 60 +++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index e370ed0..1affc58 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -991,10 +991,11 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom buttonOption.QStyleOption::operator=(*cmb); const int maxHeight = cmbxFrame.height(); const int maxWidth = cmbxFrame.width() - cmbxEditField.width(); - const int topLeftPoint = direction ? cmbxEditField.right()+1 : cmbxEditField.left()+1-maxWidth; + const int topLeftPoint = direction ? + (cmbxEditField.right() + 1) : (cmbxEditField.left() + 1 - maxWidth); const QRect buttonRect(topLeftPoint, cmbxEditField.top(), maxWidth, maxHeight); buttonOption.rect = buttonRect; - buttonOption.state = cmb->state & (State_Enabled | State_MouseOver); + buttonOption.state = cmb->state; drawPrimitive(PE_PanelButtonCommand, &buttonOption, painter, widget); // draw label background - label itself is drawn separately @@ -2107,27 +2108,28 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti case PE_IndicatorSpinDown: case PE_IndicatorSpinUp: if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast(option)) { - QStyleOptionSpinBox optionSpinBox = *spinBox; - if (QS60StylePrivate::canDrawThemeBackground(optionSpinBox.palette.base())) { + if (QS60StylePrivate::canDrawThemeBackground(spinBox->palette.base())) { + QStyleOptionSpinBox optionSpinBox = *spinBox; const QS60StyleEnums::SkinParts part = (element == PE_IndicatorSpinUp) ? QS60StyleEnums::SP_QgnGrafScrollArrowUp : QS60StyleEnums::SP_QgnGrafScrollArrowDown; - const int adjustment = qMin(optionSpinBox.rect.width(), optionSpinBox.rect.height())/6; - optionSpinBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment ); - QS60StylePrivate::drawSkinPart(part, painter, optionSpinBox.rect,flags); + const int iconMargin = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth) >> 1; + optionSpinBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? iconMargin : -iconMargin ); + QS60StylePrivate::drawSkinPart(part, painter, optionSpinBox.rect, flags); } else { commonStyleDraws = true; } } +#endif //QT_NO_SPINBOX #ifndef QT_NO_COMBOBOX - else if (const QStyleOptionFrame *cmb = qstyleoption_cast(option)) { + if (const QStyleOptionFrame *cmb = qstyleoption_cast(option)) { if (QS60StylePrivate::canDrawThemeBackground( option->palette.base())) { // We want to draw down arrow here for comboboxes as well. + QStyleOptionFrame optionsComboBox = *cmb; const QS60StyleEnums::SkinParts part = QS60StyleEnums::SP_QgnGrafScrollArrowDown; - QStyleOptionFrame comboBox = *cmb; - const int adjustment = qMin(comboBox.rect.width(), comboBox.rect.height())/6; - comboBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment ); - QS60StylePrivate::drawSkinPart(part, painter, comboBox.rect,flags); + const int iconMargin = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth) >> 1; + optionsComboBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? iconMargin : -iconMargin ); + QS60StylePrivate::drawSkinPart(part, painter, optionsComboBox.rect, flags); } else { commonStyleDraws = true; } @@ -2150,7 +2152,6 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti } #endif //QT_NO_COMBOBOX break; -#endif //QT_NO_SPINBOX case PE_Widget: if (QS60StylePrivate::drawsOwnThemeBackground(widget) #ifndef QT_NO_COMBOBOX @@ -2525,7 +2526,8 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize) + 2*buttonMargin; QSize buttonSize; buttonSize.setHeight(qMax(8, spinbox->rect.height() - frameThickness)); - buttonSize.setWidth(buttonWidth); + //width should at least be equal to height + buttonSize.setWidth(qMax(buttonSize.height(), buttonWidth)); buttonSize = buttonSize.expandedTo(QApplication::globalStrut()); const int y = frameThickness + spinbox->rect.y(); @@ -2535,12 +2537,12 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple case SC_SpinBoxUp: if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) return QRect(); - ret = QRect(x, y, buttonWidth, buttonSize.height()); + ret = QRect(x, y, buttonSize.width(), buttonSize.height()); break; case SC_SpinBoxDown: if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) return QRect(); - ret = QRect(x+buttonSize.width(), y, buttonWidth, buttonSize.height()); + ret = QRect(x + buttonSize.width(), y, buttonSize.width(), buttonSize.height()); break; case SC_SpinBoxEditField: if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) @@ -2570,29 +2572,29 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple ret = cmb->rect; const int width = cmb->rect.width(); const int height = cmb->rect.height(); + const int buttonIconSize = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize); const int buttonMargin = cmb->frame ? 2 : 0; // lets use spinbox frame here as well, as no combobox specific value available. const int frameThickness = cmb->frame ? pixelMetric(PM_SpinBoxFrameWidth, cmb, widget) : 0; - const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize); + const int buttonWidth = qMax(cmb->rect.height(), buttonIconSize); + const int xposMod = (cmb->rect.x()) + width - buttonMargin - buttonWidth; + const int ypos = cmb->rect.y(); QSize buttonSize; - buttonSize.setHeight(qMax(8, (cmb->rect.height()>>1) - frameThickness)); //minimum of 8 pixels - buttonSize.setWidth(buttonWidth+2*buttonMargin); + buttonSize.setWidth(buttonWidth + 2 * buttonMargin); + buttonSize.setHeight(qMax(8, (cmb->rect.height() >> 1) - frameThickness)); //buttons should be squares buttonSize = buttonSize.expandedTo(QApplication::globalStrut()); switch (scontrol) { case SC_ComboBoxArrow: - ret.setRect( - ret.x() + ret.width() - buttonMargin - buttonWidth, - ret.y() + buttonMargin, - buttonWidth, - height - 2*buttonMargin); + ret.setRect(xposMod, ypos + buttonMargin, buttonWidth, height - 2 * buttonMargin); break; case SC_ComboBoxEditField: { - ret.setRect( - ret.x() + frameThickness, - ret.y() + frameThickness, - ret.width() - 2*frameThickness - buttonSize.width(), - ret.height() - 2*frameThickness); + const int withFrameX = cmb->rect.x() + cmb->rect.width() - frameThickness - buttonSize.width(); + ret = QRect( + frameThickness, + frameThickness, + withFrameX - frameThickness, + cmb->rect.height() - 2 * frameThickness); } break; default: -- cgit v0.12 From 0c21eed51e67a584fcb331ee2c9fb65bc11fb633 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Wed, 23 Dec 2009 16:12:26 +0200 Subject: Correcting white space in QS60Style Reviewed-by: TrustMe --- src/gui/styles/qs60style.cpp | 152 +++++++++++++++++++++---------------------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 1affc58..12e1696 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -310,8 +310,8 @@ QColor QS60StylePrivate::stateColor(const QColor &color, const QStyleOption *opt QColor hsvColor = retColor.toHsv(); int colorSat = hsvColor.saturation(); int colorVal = hsvColor.value(); - colorSat = (colorSat!=0) ? (colorSat>>1) : 128; - colorVal = (colorVal!=0) ? (colorVal>>1) : 128; + colorSat = (colorSat != 0) ? (colorSat >> 1) : 128; + colorVal = (colorVal != 0) ? (colorVal >> 1) : 128; hsvColor.setHsv(hsvColor.hue(), colorSat, colorVal); retColor = hsvColor.toRgb(); } @@ -399,10 +399,10 @@ QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const if (!cachedColorExists) { const int frameCornerWidth = pixelMetric(PM_Custom_FrameCornerWidth); const int frameCornerHeight = pixelMetric(PM_Custom_FrameCornerHeight); - Q_ASSERT(2*frameCornerWidth<32); - Q_ASSERT(2*frameCornerHeight<32); + Q_ASSERT(2 * frameCornerWidth < 32); + Q_ASSERT(2 * frameCornerHeight < 32); - const QImage frameImage = QS60StylePrivate::frame(frame, QSize(32,32)).toImage(); + const QImage frameImage = QS60StylePrivate::frame(frame, QSize(32, 32)).toImage(); Q_ASSERT(frameImage.bytesPerLine() > 0); if (frameImage.isNull()) return Qt::black; @@ -417,14 +417,14 @@ QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const int skips = 0; int estimations = 0; - const int topBorderLastPixel = frameCornerHeight*frameImage.width()-1; - const int bottomBorderFirstPixel = frameImage.width()*frameImage.height()-frameCornerHeight*frameImage.width()-1; - const int rightBorderFirstPixel = frameImage.width()-frameCornerWidth; + const int topBorderLastPixel = frameCornerHeight*frameImage.width() - 1; + const int bottomBorderFirstPixel = frameImage.width() * frameImage.height() - frameCornerHeight*frameImage.width() - 1; + const int rightBorderFirstPixel = frameImage.width() - frameCornerWidth; const int leftBorderLastPixel = frameCornerWidth; while ((skips + estimations) < pixels) { - if ((skips+estimations) > topBorderLastPixel && - (skips+estimations) < bottomBorderFirstPixel) { + if ((skips + estimations) > topBorderLastPixel && + (skips + estimations) < bottomBorderFirstPixel) { for (int rowIndex = 0; rowIndex < frameImage.width(); rowIndex++) { if (rowIndex > leftBorderLastPixel && rowIndex < rightBorderFirstPixel) { @@ -529,18 +529,18 @@ void QS60StylePrivate::drawRow(QS60StyleEnums::SkinParts start, endRect = startRect.translated(rect.width() - startRect.width(), 0); middleRect.adjust(startRect.width(), 0, -startRect.width(), 0); if (startRect.bottomRight().x() > endRect.topLeft().x()) { - const int overlap = (startRect.bottomRight().x() - endRect.topLeft().x())>>1; - startRect.setWidth(startRect.width()-overlap); - endRect.adjust(overlap,0,0,0); + const int overlap = (startRect.bottomRight().x() - endRect.topLeft().x()) >> 1; + startRect.setWidth(startRect.width() - overlap); + endRect.adjust(overlap, 0, 0, 0); } } else { startRect.setHeight(qMin((rect.height() >> 1) - 1, startRect.height())); endRect = startRect.translated(0, rect.height() - startRect.height()); middleRect.adjust(0, startRect.height(), 0, -startRect.height()); if (startRect.topRight().y() > endRect.bottomLeft().y()) { - const int overlap = (startRect.topRight().y() - endRect.bottomLeft().y())>>1; - startRect.setHeight(startRect.height()-overlap); - endRect.adjust(0,overlap,0,0); + const int overlap = (startRect.topRight().y() - endRect.bottomLeft().y()) >> 1; + startRect.setHeight(startRect.height() - overlap); + endRect.adjust(0, overlap, 0, 0); } } @@ -808,13 +808,13 @@ QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlag case QS60StyleEnums::SP_QgnGrafTabActiveL: //Returned QSize for tabs must not be square, but narrow rectangle with width:height //ratio of 1:2 for horizontal tab bars (and 2:1 for vertical ones). - result.setWidth(result.height()>>1); + result.setWidth(result.height() >> 1); break; case QS60StyleEnums::SP_QgnGrafNsliderEndLeft: case QS60StyleEnums::SP_QgnGrafNsliderEndRight: case QS60StyleEnums::SP_QgnGrafNsliderMiddle: - result.setWidth(result.height()>>1); + result.setWidth(result.height() >> 1); break; case QS60StyleEnums::SP_QgnGrafNsliderMarker: @@ -1381,9 +1381,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, const QModelIndex index = vopt->index; //todo: Draw cell background only once - for the first cell. QStyleOptionViewItemV4 voptAdj2 = voptAdj; - const QModelIndex indexFirst = itemView->model()->index(0,0); + const QModelIndex indexFirst = itemView->model()->index(0, 0); const QModelIndex indexLast = itemView->model()->index( - itemView->model()->rowCount()-1,itemView->model()->columnCount()-1); + itemView->model()->rowCount() - 1, itemView->model()->columnCount() -1); if (itemView->viewport()) voptAdj2.rect = QRect( itemView->visualRect(indexFirst).topLeft(), itemView->visualRect(indexLast).bottomRight()).intersect(itemView->viewport()->rect()); @@ -1618,12 +1618,12 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, QPixmap tabIcon = optionTab.icon.pixmap(iconSize, (optionTab.state & State_Enabled) ? QIcon::Normal : QIcon::Disabled); if (tab->text.isEmpty()) - painter->drawPixmap(tr.center().x() - (tabIcon.height() >>1), - tr.center().y() - (tabIcon.height() >>1), + painter->drawPixmap(tr.center().x() - (tabIcon.height() >> 1), + tr.center().y() - (tabIcon.height() >> 1), tabIcon); else painter->drawPixmap(tr.left() + tabOverlap, - tr.center().y() - (tabIcon.height() >>1), + tr.center().y() - (tabIcon.height() >> 1), tabIcon); tr.setLeft(tr.left() + iconSize.width() + 4); } @@ -1652,7 +1652,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, if (optionProgressBar->orientation == Qt::Horizontal) { progressRect.setWidth(int(progressRect.width() * progressFactor)); if(optionProgressBar->direction == Qt::RightToLeft) - progressRect.translate(optionProgressBar->rect.width()-progressRect.width(),0); + progressRect.translate(optionProgressBar->rect.width()-progressRect.width(), 0); progressRect.adjust(1, 0, -1, 0); } else { progressRect.adjust(0, 1, 0, -1); @@ -1718,18 +1718,18 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, optionCheckBox.QStyleOptionMenuItem::operator=(*menuItem); optionCheckBox.rect.setWidth(pixelMetric(PM_IndicatorWidth)); optionCheckBox.rect.setHeight(pixelMetric(PM_IndicatorHeight)); - const int moveByX = optionCheckBox.rect.width()+vSpacing; + const int moveByX = optionCheckBox.rect.width() + vSpacing; if (optionMenuItem.direction == Qt::LeftToRight) { - textRect.translate(moveByX,0); + textRect.translate(moveByX, 0); iconRect.translate(moveByX, 0); - iconRect.setWidth(iconRect.width()+vSpacing); - textRect.setWidth(textRect.width()-moveByX-vSpacing); - optionCheckBox.rect.translate(vSpacing/2, hSpacing/2); + iconRect.setWidth(iconRect.width() + vSpacing); + textRect.setWidth(textRect.width() - moveByX - vSpacing); + optionCheckBox.rect.translate(vSpacing >> 1, hSpacing >> 1); } else { - textRect.setWidth(textRect.width()-moveByX); - iconRect.setWidth(iconRect.width()+vSpacing); - iconRect.translate(-optionCheckBox.rect.width()-vSpacing, 0); - optionCheckBox.rect.translate(textRect.width()+iconRect.width(),0); + textRect.setWidth(textRect.width() - moveByX); + iconRect.setWidth(iconRect.width() + vSpacing); + iconRect.translate(-optionCheckBox.rect.width() - vSpacing, 0); + optionCheckBox.rect.translate(textRect.width() + iconRect.width(), 0); } drawPrimitive(PE_IndicatorMenuCheckMark, &optionCheckBox, painter, widget); } @@ -1740,9 +1740,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, if (itemWithIcon) { drawItemPixmap(painter, iconRect, text_flags, pix); if (optionMenuItem.direction == Qt::LeftToRight) - textRect.translate(vSpacing,0); + textRect.translate(vSpacing, 0); else - textRect.translate(-vSpacing,0); + textRect.translate(-vSpacing, 0); textRect.setWidth(textRect.width()-vSpacing); } @@ -1750,7 +1750,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, if (drawSubMenuIndicator) { QStyleOptionMenuItem arrowOptions; arrowOptions.QStyleOption::operator=(*menuItem); - const int indicatorWidth = (pixelMetric(PM_ListViewIconSize, option, widget)>>1) + + const int indicatorWidth = (pixelMetric(PM_ListViewIconSize, option, widget) >> 1) + pixelMetric(QStyle::PM_LayoutVerticalSpacing, option, widget); if (optionMenuItem.direction == Qt::LeftToRight) arrowOptions.rect.setLeft(textRect.right()); @@ -1795,8 +1795,8 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, painter->save(); QPen linePen = QPen(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 1, header)); const int penWidth = (header->orientation == Qt::Horizontal) ? - linePen.width()+QS60StylePrivate::pixelMetric(PM_Custom_BoldLineWidth) - : linePen.width()+QS60StylePrivate::pixelMetric(PM_Custom_ThinLineWidth); + linePen.width() + QS60StylePrivate::pixelMetric(PM_Custom_BoldLineWidth) + : linePen.width() + QS60StylePrivate::pixelMetric(PM_Custom_ThinLineWidth); linePen.setWidth(penWidth); painter->setPen(linePen); if (header->orientation == Qt::Horizontal){ @@ -1815,7 +1815,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, //Make cornerButton slightly smaller so that it is not on top of table border graphic. QStyleOptionHeader subopt = *header; const int borderTweak = - QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth)>>1; + QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth) >> 1; if (subopt.direction == Qt::LeftToRight) subopt.rect.adjust(borderTweak, borderTweak, 0, -borderTweak); else @@ -1908,9 +1908,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, } else { const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); if (option->direction == Qt::LeftToRight) - headerRect.adjust(-2*frameWidth, 0, 0, 0); + headerRect.adjust(-2 * frameWidth, 0, 0, 0); else - headerRect.adjust(0, 0, 2*frameWidth, 0); + headerRect.adjust(0, 0, 2 * frameWidth, 0); } if (option->palette.brush(QPalette::Button).color() == Qt::transparent) QS60StylePrivate::drawSkinElement( @@ -2033,7 +2033,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti QRect tickRect = option->rect; const int frameBorderWidth = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth); // adjust tickmark rect to exclude frame border - tickRect.adjust(0,-frameBorderWidth,0,-frameBorderWidth); + tickRect.adjust(0, -frameBorderWidth, 0, -frameBorderWidth); QS60StyleEnums::SkinParts skinPart = QS60StyleEnums::SP_QgnIndiMarkedAdd; QS60StylePrivate::drawSkinPart(skinPart, painter, tickRect, (flags | QS60StylePrivate::SF_ColorSkinned)); @@ -2045,7 +2045,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti case PE_IndicatorRadioButton: { QRect buttonRect = option->rect; //there is empty (a. 33%) space in svg graphics for radiobutton - const qreal reduceWidth = (qreal)buttonRect.width()/3.0; + const qreal reduceWidth = (qreal)buttonRect.width() / 3.0; const qreal rectWidth = (qreal)option->rect.width() != 0 ? option->rect.width() : 1.0; // Try to occupy the full area const qreal scaler = 1 + (reduceWidth/rectWidth); @@ -2147,7 +2147,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti // We want to draw down arrow here for comboboxes as well. QStyleOptionFrame comboBox = *cmb; const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); - comboBox.rect.adjust(0,frameWidth,0,-frameWidth); + comboBox.rect.adjust(0, frameWidth, 0, -frameWidth); QCommonStyle::drawPrimitive(element, &comboBox, painter, widget); } #endif //QT_NO_COMBOBOX @@ -2341,22 +2341,22 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, case CT_ToolButton: sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); //FIXME properly - style should calculate the location of border frame-part - sz += QSize(2*pixelMetric(PM_ButtonMargin), 2*pixelMetric(PM_ButtonMargin)); + sz += QSize(2 * pixelMetric(PM_ButtonMargin), 2 * pixelMetric(PM_ButtonMargin)); if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast(opt)) if (toolBtn->subControls & SC_ToolButtonMenu) - sz += QSize(pixelMetric(PM_MenuButtonIndicator),0); + sz += QSize(pixelMetric(PM_MenuButtonIndicator), 0); break; case CT_PushButton: sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); //FIXME properly - style should calculate the location of border frame-part - sz += QSize(2*pixelMetric(PM_ButtonMargin), 2*pixelMetric(PM_ButtonMargin)); + sz += QSize(2 * pixelMetric(PM_ButtonMargin), 2 * pixelMetric(PM_ButtonMargin)); if (const QAbstractButton *buttonWidget = (qobject_cast(widget))) if (buttonWidget->isCheckable()) sz += QSize(pixelMetric(PM_IndicatorWidth) + pixelMetric(PM_CheckBoxLabelSpacing), 0); break; case CT_LineEdit: if (const QStyleOptionFrame *f = qstyleoption_cast(opt)) - sz += QSize(2*f->lineWidth, 4*f->lineWidth); + sz += QSize(2 * f->lineWidth, 4 * f->lineWidth); break; case CT_TabBarTab: { @@ -2371,7 +2371,7 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, if (QS60StylePrivate::isTouchSupported()) //Make itemview easier to use in touch devices //QCommonStyle does not adjust height with horizontal margin, it only adjusts width - sz.setHeight(sz.height() + 2*pixelMetric(QStyle::PM_FocusFrameVMargin)); + sz.setHeight(sz.height() + 2 * pixelMetric(QStyle::PM_FocusFrameVMargin)); break; default: sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); @@ -2387,10 +2387,10 @@ int QS60Style::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w int retValue = -1; switch (sh) { case SH_Table_GridLineColor: - retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors,2,0).rgba()); + retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 2, 0).rgba()); break; case SH_GroupBox_TextLabelColor: - retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors,6,0).rgba()); + retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0).rgba()); break; case SH_ScrollBar_ScrollWhenPointerLeavesControl: retValue = true; @@ -2472,7 +2472,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple sliderlen = (qint64(scrollbarOption->pageStep) * maxlen) / (range + scrollbarOption->pageStep); const int slidermin = pixelMetric(PM_ScrollBarSliderMin, scrollbarOption, widget); - if (sliderlen < slidermin || range > (INT_MAX>>1)) + if (sliderlen < slidermin || range > (INT_MAX >> 1)) sliderlen = slidermin; if (sliderlen > maxlen) sliderlen = maxlen; @@ -2523,7 +2523,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast(option)) { const int frameThickness = spinbox->frame ? pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0; const int buttonMargin = spinbox->frame ? 2 : 0; - const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize) + 2*buttonMargin; + const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize) + 2 * buttonMargin; QSize buttonSize; buttonSize.setHeight(qMax(8, spinbox->rect.height() - frameThickness)); //width should at least be equal to height @@ -2531,7 +2531,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple buttonSize = buttonSize.expandedTo(QApplication::globalStrut()); const int y = frameThickness + spinbox->rect.y(); - const int x = spinbox->rect.x() + spinbox->rect.width() - frameThickness - 2*buttonSize.width(); + const int x = spinbox->rect.x() + spinbox->rect.width() - frameThickness - 2 * buttonSize.width(); switch (scontrol) { case SC_SpinBoxUp: @@ -2549,14 +2549,14 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple ret = QRect( frameThickness, frameThickness, - spinbox->rect.width() - 2*frameThickness, - spinbox->rect.height() - 2*frameThickness); + spinbox->rect.width() - 2 * frameThickness, + spinbox->rect.height() - 2 * frameThickness); else ret = QRect( frameThickness, frameThickness, x - frameThickness, - spinbox->rect.height() - 2*frameThickness); + spinbox->rect.height() - 2 * frameThickness); break; case SC_SpinBoxFrame: ret = spinbox->rect; @@ -2611,7 +2611,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple //slightly indent text and boxes, so that dialog border does not mess with them. const int horizontalSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing); - ret.adjust(2,horizontalSpacing-3,0,0); + ret.adjust(2, horizontalSpacing - 3, 0, 0); } break; case SC_GroupBoxFrame: { @@ -2619,7 +2619,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple const int tbHeight = textBox.height(); ret.translate(0, -ret.y()); // include title to within the groupBox frame - ret.setHeight(ret.height()+tbHeight); + ret.setHeight(ret.height() + tbHeight); if (widget && ret.bottom() > widget->rect().bottom()) ret.setBottom(widget->rect().bottom()); } @@ -2631,7 +2631,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple break; case CC_ToolButton: if (const QStyleOptionToolButton *toolButton = qstyleoption_cast(option)) { - const int indicatorRect = pixelMetric(PM_MenuButtonIndicator) + 2*pixelMetric(PM_ButtonMargin); + const int indicatorRect = pixelMetric(PM_MenuButtonIndicator) + 2 * pixelMetric(PM_ButtonMargin); const int border = pixelMetric(PM_ButtonMargin) + pixelMetric(PM_DefaultFrameWidth); ret = toolButton->rect; const bool popup = (toolButton->features & @@ -2669,13 +2669,13 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con // in S60 the input text box doesn't start from line Edit's TL, but // a bit indented. QRect lineEditRect = opt->rect; - const int adjustment = opt->rect.height()>>2; - lineEditRect.adjust(adjustment,0,0,0); + const int adjustment = opt->rect.height() >> 2; + lineEditRect.adjust(adjustment, 0, 0, 0); ret = lineEditRect; } break; case SE_TabBarTearIndicator: - ret = QRect(0,0,0,0); + ret = QRect(0, 0, 0, 0); break; case SE_TabWidgetTabBar: if (const QStyleOptionTabWidgetFrame *optionTab = qstyleoption_cast(opt)) { @@ -2697,12 +2697,12 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con // make sure that gain does not set the rect outside of widget boundaries if (twf->direction == Qt::RightToLeft) { if ((ret.left() - gain) < widget->rect().left()) - gain = widget->rect().left()-ret.left(); - ret.adjust(-gain,0,0,0); + gain = widget->rect().left() - ret.left(); + ret.adjust(-gain, 0, 0, 0); } else { if ((ret.right() + gain) > widget->rect().right()) - gain = widget->rect().right()-ret.right(); - ret.adjust(0,0,gain,0); + gain = widget->rect().right() - ret.right(); + ret.adjust(0, 0, gain, 0); } } break; @@ -2710,8 +2710,8 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con default: { if (widget) { if ((ret.bottom() + gain) > widget->rect().bottom()) - gain = widget->rect().bottom()-ret.bottom(); - ret.adjust(0,0,0,gain); + gain = widget->rect().bottom() - ret.bottom(); + ret.adjust(0, 0, 0, gain); } break; } @@ -2737,7 +2737,7 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing); //const int horizontalSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing); const int checkBoxRectWidth = subElementRect(SE_ItemViewItemCheckIndicator, opt, widget).width(); - ret.adjust(-checkBoxRectWidth-verticalSpacing,0,-checkBoxRectWidth-verticalSpacing,0); + ret.adjust(-checkBoxRectWidth - verticalSpacing, 0, -checkBoxRectWidth - verticalSpacing, 0); } } else if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast(opt)) { const bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable; @@ -2762,9 +2762,9 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu){ // submenu indicator is very small, so lets halve the rect if (menuItem->direction == Qt::LeftToRight) - ret.adjust(0,0,-(indicatorWidth >> 1),0); + ret.adjust(0, 0, -(indicatorWidth >> 1), 0); else - ret.adjust((indicatorWidth >> 1),0,0,0); + ret.adjust((indicatorWidth >> 1), 0, 0, 0); } } } @@ -2788,14 +2788,14 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con const int itemHeight = opt->rect.height(); int heightOffset = 0; if (indicatorHeight < itemHeight) - heightOffset = ((itemHeight - indicatorHeight)>>1); + heightOffset = ((itemHeight - indicatorHeight) >> 1); if (checkBoxOnly) { // Move rect and make it slightly smaller, so that // a) highlight border does not cross the rect // b) in s60 list checkbox is smaller than normal checkbox //todo; magic three - ret.setRect(opt->rect.left()+3, opt->rect.top() + heightOffset, - indicatorWidth-3, indicatorHeight-3); + ret.setRect(opt->rect.left() + 3, opt->rect.top() + heightOffset, + indicatorWidth - 3, indicatorHeight - 3); } else { ret.setRect(opt->rect.right() - indicatorWidth - spacing, opt->rect.top() + heightOffset, indicatorWidth, indicatorHeight); @@ -2959,7 +2959,7 @@ QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const { const int iconDimension = QS60StylePrivate::pixelMetric(QStyle::PM_ToolBarIconSize); - const QRect iconSize = (!option) ? QRect(0,0,iconDimension,iconDimension) : option->rect; + const QRect iconSize = (!option) ? QRect(0, 0, iconDimension, iconDimension) : option->rect; QS60StyleEnums::SkinParts part; QS60StylePrivate::SkinElementFlags adjustedFlags; if (option) -- cgit v0.12 From 2751cdb118f2ac0ba39613e2064471333904c770 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Wed, 23 Dec 2009 16:14:01 +0200 Subject: Minor optimization for QS60Style Ask selected state only once in QS60Style when handling element CE_TabBarTabLabel. Reviewed-by: TrustMe --- src/gui/styles/qs60style.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 12e1696..bcc993a 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -1571,16 +1571,16 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, f.setPointSizeF(f.pointSizeF() * KTabFontMul); painter->setFont(f); - if (option->state & QStyle::State_Selected){ + const bool selected = optionTab.state & State_Selected; + if (selected) optionTab.palette.setColor(QPalette::Active, QPalette::WindowText, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 3, option)); - } const bool verticalTabs = optionTab.shape == QTabBar::RoundedEast || optionTab.shape == QTabBar::RoundedWest || optionTab.shape == QTabBar::TriangularEast || optionTab.shape == QTabBar::TriangularWest; - const bool selected = optionTab.state & State_Selected; + if (verticalTabs) { painter->save(); int newX, newY, newRotation; -- cgit v0.12 From 65313ba793c0e7cec265a224feadb8e53fbf2681 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 25 Dec 2009 15:46:45 +0100 Subject: Add two new mkspecs for SunCC with stlport. Untested, but not used anywhere yet, so this cannot cause any problems. --- mkspecs/solaris-cc-64-stlport/qmake.conf | 8 ++++++++ mkspecs/solaris-cc-64-stlport/qplatformdefs.h | 1 + mkspecs/solaris-cc-stlport/qmake.conf | 8 ++++++++ mkspecs/solaris-cc-stlport/qplatformdefs.h | 1 + 4 files changed, 18 insertions(+) create mode 100644 mkspecs/solaris-cc-64-stlport/qmake.conf create mode 100644 mkspecs/solaris-cc-64-stlport/qplatformdefs.h create mode 100644 mkspecs/solaris-cc-stlport/qmake.conf create mode 100644 mkspecs/solaris-cc-stlport/qplatformdefs.h diff --git a/mkspecs/solaris-cc-64-stlport/qmake.conf b/mkspecs/solaris-cc-64-stlport/qmake.conf new file mode 100644 index 0000000..3437b8f --- /dev/null +++ b/mkspecs/solaris-cc-64-stlport/qmake.conf @@ -0,0 +1,8 @@ +# +# qmake configuration for solaris-cc-64-stlport +# + +include(../solaris-cc-64/qmake.conf) + +QMAKE_CXXFLAGS += -library=stlport4 +QMAKE_LFLAGS += -library=stlport4 diff --git a/mkspecs/solaris-cc-64-stlport/qplatformdefs.h b/mkspecs/solaris-cc-64-stlport/qplatformdefs.h new file mode 100644 index 0000000..17bc159 --- /dev/null +++ b/mkspecs/solaris-cc-64-stlport/qplatformdefs.h @@ -0,0 +1 @@ +#include "../solaris-cc-64/qplatformdefs.h" diff --git a/mkspecs/solaris-cc-stlport/qmake.conf b/mkspecs/solaris-cc-stlport/qmake.conf new file mode 100644 index 0000000..b0df45e --- /dev/null +++ b/mkspecs/solaris-cc-stlport/qmake.conf @@ -0,0 +1,8 @@ +# +# qmake configuration for solaris-cc-stlport +# + +include(../solaris-cc/qmake.conf) + +QMAKE_CXXFLAGS += -library=stlport4 +QMAKE_LFLAGS += -library=stlport4 diff --git a/mkspecs/solaris-cc-stlport/qplatformdefs.h b/mkspecs/solaris-cc-stlport/qplatformdefs.h new file mode 100644 index 0000000..7bedf35 --- /dev/null +++ b/mkspecs/solaris-cc-stlport/qplatformdefs.h @@ -0,0 +1 @@ +#include "../solaris-cc/qplatformdefs.h" -- cgit v0.12 From 90f22ce77a8f3b5a568b9c19df1798ef30afcbd2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 25 Dec 2009 16:01:31 +0100 Subject: Fix build on ARMv6 when NEON is detected. The compiler requires -mfpu=neon to enable NEON instructions. --- src/gui/painting/painting.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 0b1e79a..a6cc9c7 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -383,7 +383,7 @@ neon { DEFINES += QT_HAVE_NEON HEADERS += painting/qdrawhelper_neon_p.h SOURCES += painting/qdrawhelper_neon.cpp - QMAKE.CXXFLAGS *= -mfpu=neon + QMAKE_CXXFLAGS *= -mfpu=neon } contains(QT_CONFIG, zlib) { -- cgit v0.12 From 7a0fb8407b0737d6f10181846dd49791e094fd88 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Fri, 25 Dec 2009 17:09:52 +0100 Subject: FTBFS on hurd-i386 because since clock_gettime is not available there qt4-x11 reverts to using gettimeofday, but it doesn't include where the latter is defined. Debian bug #533526 Task-number: QTBUG-6961 Reviewed-by: Thiago Macieira --- src/corelib/concurrent/qtconcurrentiteratekernel.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/corelib/concurrent/qtconcurrentiteratekernel.cpp b/src/corelib/concurrent/qtconcurrentiteratekernel.cpp index 15b8ecd..e93394f 100644 --- a/src/corelib/concurrent/qtconcurrentiteratekernel.cpp +++ b/src/corelib/concurrent/qtconcurrentiteratekernel.cpp @@ -46,6 +46,9 @@ #include #include #elif defined(Q_OS_UNIX) +#if defined(Q_OS_HURD) +#include +#endif #include #include #elif defined(Q_OS_WIN) -- cgit v0.12 From 11c2d1e5d5a2bbf00230e40f11d2047572f32cd6 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 26 Dec 2009 00:06:25 +0100 Subject: Add missing license headers to the new solaris-cc-stlport mkspecs. Reviewed-by: Trust Me --- mkspecs/solaris-cc-64-stlport/qplatformdefs.h | 41 +++++++++++++++++++++++++++ mkspecs/solaris-cc-stlport/qplatformdefs.h | 41 +++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/mkspecs/solaris-cc-64-stlport/qplatformdefs.h b/mkspecs/solaris-cc-64-stlport/qplatformdefs.h index 17bc159..7c88722 100644 --- a/mkspecs/solaris-cc-64-stlport/qplatformdefs.h +++ b/mkspecs/solaris-cc-64-stlport/qplatformdefs.h @@ -1 +1,42 @@ +/**************************************************************************** +** +** 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 qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 "../solaris-cc-64/qplatformdefs.h" diff --git a/mkspecs/solaris-cc-stlport/qplatformdefs.h b/mkspecs/solaris-cc-stlport/qplatformdefs.h index 7bedf35..bb75c1f 100644 --- a/mkspecs/solaris-cc-stlport/qplatformdefs.h +++ b/mkspecs/solaris-cc-stlport/qplatformdefs.h @@ -1 +1,42 @@ +/**************************************************************************** +** +** 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 qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 "../solaris-cc/qplatformdefs.h" -- cgit v0.12 From e6f6ba99253aaac496083b4cf122b095f21b43b3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 26 Dec 2009 00:07:01 +0100 Subject: Fix warning on 64-bit build with MSVC. Task-number: QTBUG-3792 Reviewed-by: Trust Me --- src/corelib/io/qdebug.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h index ff8c6c8..c1c7812 100644 --- a/src/corelib/io/qdebug.h +++ b/src/corelib/io/qdebug.h @@ -93,7 +93,7 @@ public: inline QDebug &maybeSpace() { if (stream->space) stream->ts << ' '; return *this; } inline QDebug &operator<<(QChar t) { stream->ts << '\'' << t << '\''; return maybeSpace(); } - inline QDebug &operator<<(QBool t) { stream->ts << (bool(t) ? "true" : "false"); return maybeSpace(); } + inline QDebug &operator<<(QBool t) { stream->ts << (bool(t != 0) ? "true" : "false"); return maybeSpace(); } inline QDebug &operator<<(bool t) { stream->ts << (t ? "true" : "false"); return maybeSpace(); } inline QDebug &operator<<(char t) { stream->ts << t; return maybeSpace(); } inline QDebug &operator<<(signed short t) { stream->ts << t; return maybeSpace(); } -- cgit v0.12 From 63bd10ae61ed0b877344b217e57eb87f77256e98 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 26 Dec 2009 00:47:02 +0100 Subject: Don't include dlfcn.h unconditionally. Task-number: QTBUG-3344 Reviewed-by: Trust Me --- mkspecs/linux-g++/qplatformdefs.h | 1 - src/gui/embedded/qscreen_qws.cpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/linux-g++/qplatformdefs.h b/mkspecs/linux-g++/qplatformdefs.h index ecfbc73..00f1b51 100644 --- a/mkspecs/linux-g++/qplatformdefs.h +++ b/mkspecs/linux-g++/qplatformdefs.h @@ -67,7 +67,6 @@ #include #include #include -#include #include #include diff --git a/src/gui/embedded/qscreen_qws.cpp b/src/gui/embedded/qscreen_qws.cpp index ae5570f..07bb258 100644 --- a/src/gui/embedded/qscreen_qws.cpp +++ b/src/gui/embedded/qscreen_qws.cpp @@ -3150,6 +3150,7 @@ int QScreen::subScreenIndexAt(const QPoint &p) const #if 0 #ifdef QT_LOADABLE_MODULES +#include // ### needs update after driver init changes -- cgit v0.12