diff options
author | Martin Jones <martin.jones@nokia.com> | 2010-01-29 01:53:32 (GMT) |
---|---|---|
committer | Martin Jones <martin.jones@nokia.com> | 2010-01-29 01:53:32 (GMT) |
commit | 91a0da8d3674d832fde87c9c1bc5a4bdb959ac3d (patch) | |
tree | ef09bd890041b3c44f7be3322321c96174e94054 | |
parent | 687d50f05a1a2d9355f0990e845967930c57b985 (diff) | |
parent | fe129a59ab54e6c0194c546a02bc64e886c252d5 (diff) | |
download | Qt-91a0da8d3674d832fde87c9c1bc5a4bdb959ac3d.zip Qt-91a0da8d3674d832fde87c9c1bc5a4bdb959ac3d.tar.gz Qt-91a0da8d3674d832fde87c9c1bc5a4bdb959ac3d.tar.bz2 |
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
172 files changed, 3979 insertions, 2657 deletions
@@ -64,6 +64,7 @@ bin/qmake* bin/qdoc3* bin/qt3to4* bin/qtdemo* +bin/qttracereplay* bin/rcc* bin/uic* bin/patternist* diff --git a/bin/patch_capabilities.bat b/bin/patch_capabilities.bat new file mode 100644 index 0000000..6a0c4d7 --- /dev/null +++ b/bin/patch_capabilities.bat @@ -0,0 +1 @@ +@perl.exe -S %~dp0patch_capabilities.pl %* diff --git a/configure.exe b/configure.exe Binary files differindex d88da13..ed2b0b2 100644 --- a/configure.exe +++ b/configure.exe diff --git a/demos/embedded/fluidlauncher/backup_registration.xml b/demos/embedded/fluidlauncher/backup_registration.xml new file mode 100644 index 0000000..794e11d --- /dev/null +++ b/demos/embedded/fluidlauncher/backup_registration.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" standalone="yes"?> +<backup_registration> + <passive_backup> + <include_directory name = "\" /> + </passive_backup> + <system_backup/> + <restore requires_reboot = "no"/> +</backup_registration> diff --git a/demos/embedded/fluidlauncher/fluidlauncher.pro b/demos/embedded/fluidlauncher/fluidlauncher.pro index bb8835b..92d6e1e 100644 --- a/demos/embedded/fluidlauncher/fluidlauncher.pro +++ b/demos/embedded/fluidlauncher/fluidlauncher.pro @@ -207,8 +207,11 @@ symbian { saxbookmarks.sources += $$PWD/../../../examples/xml/saxbookmarks/jennifer.xbel saxbookmarks.path = /data/qt/saxbookmarks + fluidbackup.sources = backup_registration.xml + fluidbackup.path = /private/$$replace(TARGET.UID3, 0x,) + DEPLOYMENT += config files executables viewerimages saxbookmarks reg_resource resource \ - mifs desktopservices_music desktopservices_images + mifs desktopservices_music desktopservices_images fluidbackup TARGET.EPOCHEAPSIZE = 100000 20000000 } diff --git a/dist/changes-4.6.1 b/dist/changes-4.6.1 index 3df6887..4a567bb 100644 --- a/dist/changes-4.6.1 +++ b/dist/changes-4.6.1 @@ -247,6 +247,8 @@ QtSvg * [QTBUG-6867] Fixed regression in the parsing of paths with relative offsets. * [QTBUG-6899] Fixed crash when parsing invalid coordinate list. + - QtXmlPatterns + * [QTBUG-6771] Fixed static builds. Qt Plugins ---------- diff --git a/doc/src/development/assistant-manual.qdoc b/doc/src/development/assistant-manual.qdoc index 83d8679..c4eb615 100644 --- a/doc/src/development/assistant-manual.qdoc +++ b/doc/src/development/assistant-manual.qdoc @@ -182,7 +182,7 @@ will appear. Click a sub-item to make its page appear in the \e{Documentation} window. Click on the control next to an open item to hide its sub-items. \o The \gui{Index} window is used to look up key words or phrases. - See \l{The One-Minute Guide to Using Qt Assistant} for how to use this + See \l{Qt Assistant Manual#The One-Minute Guide to Using Qt Assistant}{The One-Minute Guide to Using Qt Assistant} for how to use this window. \o The \gui{Bookmarks} window lists any bookmarks you have made. Double click a bookmark to make its page appear in the \e{Documentation} window. diff --git a/doc/src/frameworks-technologies/qthelp.qdoc b/doc/src/frameworks-technologies/qthelp.qdoc index 079b080..3c80f04 100644 --- a/doc/src/frameworks-technologies/qthelp.qdoc +++ b/doc/src/frameworks-technologies/qthelp.qdoc @@ -264,7 +264,7 @@ help collection to keep track of a documentation set without relying on its file name. The Qt help system uses a namespace as identifier which is defined by the mandatory namespace tags. In the example - above, the namespace is "mycompany.com.myapplication.1_0". + above, the namespace is "mycompany.com.myapplication.1.0". \target Virtual Folders \section2 Virtual Folders diff --git a/doc/src/getting-started/examples.qdoc b/doc/src/getting-started/examples.qdoc index 2582c4f..6b4ec61 100644 --- a/doc/src/getting-started/examples.qdoc +++ b/doc/src/getting-started/examples.qdoc @@ -648,10 +648,10 @@ These examples show the use of graphics widgets and layouts. \list - \o \l{graphicsview/anchorlayouts}{Anchor Layouts} + \o \l{graphicsview/anchorlayout}{Anchor Layout} \o \l{graphicsview/flowlayout}{Flow Layout} - \o \l{graphicsview/simpleanchorlayouts}{Simple Anchor Layouts} - \o \l{graphicsview/weatheranchorlayouts}{Weather Anchor Layouts} + \o \l{graphicsview/simpleanchorlayout}{Simple Anchor Layout} + \o \l{graphicsview/weatheranchorlayout}{Weather Anchor Layout} \endlist Some examples demonstrate the use of graphics effects with canvas items. diff --git a/doc/src/snippets/code/doc_src_qthelp.qdoc b/doc/src/snippets/code/doc_src_qthelp.qdoc index 017879d..f7b880a 100644 --- a/doc/src/snippets/code/doc_src_qthelp.qdoc +++ b/doc/src/snippets/code/doc_src_qthelp.qdoc @@ -110,7 +110,7 @@ if (links.count()) { //! [7] <?xml version="1.0" encoding="UTF-8"?> <QtHelpProject version="1.0"> - <namespace>mycompany.com.myapplication.1_0</namespace> + <namespace>mycompany.com.myapplication.1.0</namespace> <virtualFolder>doc</virtualFolder> <customFilter name="My Application 1.0"> <filterAttribute>myapp</filterAttribute> diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index 0f06b92..a2933e9 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -65,7 +65,7 @@ QMAKE_LINK_OBJECT_SCRIPT= QMAKE_LIBS = -llibc -llibm -leuser -llibdl QMAKE_LIBS_CORE = $$QMAKE_LIBS -llibpthread -lefsrv -QMAKE_LIBS_GUI = $$QMAKE_LIBS_CORE -lfbscli -lbitgdi -lhal -lgdi -lws32 -lapgrfx -lcone -leikcore -lmediaclientaudio -leikcoctl -leiksrv -lapparc +QMAKE_LIBS_GUI = $$QMAKE_LIBS_CORE -lfbscli -lbitgdi -lhal -lgdi -lws32 -lapgrfx -lcone -leikcore -lmediaclientaudio -leikcoctl -leiksrv -lapparc -lcentralrepository QMAKE_LIBS_NETWORK = QMAKE_LIBS_EGL = -llibEGL QMAKE_LIBS_OPENGL = diff --git a/mkspecs/features/symbian/def_files.prf b/mkspecs/features/symbian/def_files.prf new file mode 100644 index 0000000..c29d4ec --- /dev/null +++ b/mkspecs/features/symbian/def_files.prf @@ -0,0 +1,26 @@ +# With DEF files enabled, removed exported symbols are treated as errors +# and there is binary compatibility between successive builds. + +CONFIG -= def_files_disabled + +!isEmpty(defFilePath) { + defBlock = \ + "$${LITERAL_HASH}ifdef WINSCW" \ + "DEFFILE $$defFilePath/bwins/$${TARGET}.def" \ + "$${LITERAL_HASH}elif defined EABI" \ + "DEFFILE $$defFilePath/eabi/$${TARGET}.def" \ + "$${LITERAL_HASH}endif" + + MMP_RULES += defBlock +} else { + # If defFilePath is not defined, then put the folders containing the DEF files at the + # same level as the .pro (and generated MMP) file(s) + defBlock = \ + "$${LITERAL_HASH}ifdef WINSCW" \ + "DEFFILE ./bwins/$${TARGET}.def" \ + "$${LITERAL_HASH}elif defined EABI" \ + "DEFFILE ./eabi/$${TARGET}.def" \ + "$${LITERAL_HASH}endif" + + MMP_RULES += defBlock +} diff --git a/mkspecs/features/symbian/def_files_disabled.prf b/mkspecs/features/symbian/def_files_disabled.prf new file mode 100644 index 0000000..d5c9505 --- /dev/null +++ b/mkspecs/features/symbian/def_files_disabled.prf @@ -0,0 +1,7 @@ +# With DEF files disabled, binary compatibility is broken every time you build + +CONFIG -= def_files + +# with EXPORTUNFROZEN enabled, new exports are included in the dll without +# needing to run abld/sbs freeze +MMP_RULES += EXPORTUNFROZEN diff --git a/qmake/generators/symbian/initprojectdeploy_symbian.cpp b/qmake/generators/symbian/initprojectdeploy_symbian.cpp index 755f73f..f3e3c3a 100644 --- a/qmake/generators/symbian/initprojectdeploy_symbian.cpp +++ b/qmake/generators/symbian/initprojectdeploy_symbian.cpp @@ -46,7 +46,6 @@ #include <qsettings.h> #include <qdebug.h> -#define PLUGIN_STUB_DIR "qmakepluginstubs" #define SYSBIN_DIR "\\sys\\bin" #define SUFFIX_DLL "dll" diff --git a/qmake/generators/symbian/initprojectdeploy_symbian.h b/qmake/generators/symbian/initprojectdeploy_symbian.h index 2f43818..e23e6a9 100644 --- a/qmake/generators/symbian/initprojectdeploy_symbian.h +++ b/qmake/generators/symbian/initprojectdeploy_symbian.h @@ -52,6 +52,8 @@ #include "epocroot.h" +#define PLUGIN_STUB_DIR "qmakepluginstubs" + struct CopyItem { CopyItem(const QString& f, const QString& t) : from(f) , to(t) { } diff --git a/qmake/generators/symbian/symmake.cpp b/qmake/generators/symbian/symmake.cpp index 6e76c9e..20e2d0e 100644 --- a/qmake/generators/symbian/symmake.cpp +++ b/qmake/generators/symbian/symmake.cpp @@ -40,7 +40,6 @@ ****************************************************************************/ #include "symmake.h" -#include "initprojectdeploy_symbian.h" #include <qstring.h> #include <qhash.h> @@ -62,6 +61,7 @@ #define BLD_INF_TAG_MMPFILES "prj_mmpfiles" #define BLD_INF_TAG_TESTMMPFILES "prj_testmmpfiles" #define BLD_INF_TAG_EXTENSIONS "prj_extensions" +#define BLD_INF_TAG_EXPORTS "prj_exports" #define RSS_RULES "RSS_RULES" #define RSS_RULES_BASE "RSS_RULES." @@ -202,6 +202,8 @@ bool SymbianMakefileGenerator::writeMakefile(QTextStream &t) // Generate pkg files if there are any actual files to deploy bool generatePkg = false; + DeploymentList depList; + if (targetType == TypeExe) { generatePkg = true; } else { @@ -214,10 +216,10 @@ bool SymbianMakefileGenerator::writeMakefile(QTextStream &t) } if (generatePkg) { - generatePkgFile(iconFile); + generatePkgFile(iconFile, depList); } - writeBldInfContent(t, generatePkg, iconFile); + writeBldInfContent(t, generatePkg, iconFile, depList); // Generate empty wrapper makefile here, because wrapper makefile must exist before writeMkFile, // but all required data is not yet available. @@ -272,7 +274,7 @@ bool SymbianMakefileGenerator::writeMakefile(QTextStream &t) return true; } -void SymbianMakefileGenerator::generatePkgFile(const QString &iconFile) +void SymbianMakefileGenerator::generatePkgFile(const QString &iconFile, DeploymentList &depList) { QString pkgFilename = QString("%1_template.%2") .arg(fixedTarget) @@ -396,7 +398,6 @@ void SymbianMakefileGenerator::generatePkgFile(const QString &iconFile) } // deploy any additional DEPLOYMENT files - DeploymentList depList; QString remoteTestPath; remoteTestPath = QString("!:\\private\\%1").arg(privateDirUid); @@ -1171,7 +1172,7 @@ void SymbianMakefileGenerator::writeMmpFileRulesPart(QTextStream& t) } } -void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploymentExtension, const QString &iconFile) +void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploymentExtension, const QString &iconFile, DeploymentList &depList) { // Read user defined bld inf rules @@ -1300,6 +1301,25 @@ void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploy t << item << endl; userBldInfRules.remove(BLD_INF_TAG_EXTENSIONS); + t << endl << BLD_INF_TAG_EXPORTS << endl << endl; + + // Generate export rules + + // Export any deployed plugin stubs under /epoc32/data/z to support ROM builds + for (int i = 0; i < depList.size(); ++i) { + int index = depList.at(i).from.indexOf(PLUGIN_STUB_DIR); + if (index != -1) { + t << QString("%1 /epoc32/data/z%2") + .arg(QString(depList.at(i).from).mid(index).replace('\\','/')) + .arg(QString(depList.at(i).to).mid(2).replace('\\','/')) << endl; + } + } + + userItems = userBldInfRules.value(BLD_INF_TAG_EXPORTS); + foreach(QString item, userItems) + t << item << endl; + userBldInfRules.remove(BLD_INF_TAG_EXPORTS); + // Add rest of the user defined content for (QMap<QString, QStringList>::iterator it = userBldInfRules.begin(); it != userBldInfRules.end(); ++it) { diff --git a/qmake/generators/symbian/symmake.h b/qmake/generators/symbian/symmake.h index 45209d1..77d61da 100644 --- a/qmake/generators/symbian/symmake.h +++ b/qmake/generators/symbian/symmake.h @@ -42,6 +42,7 @@ #ifndef SYMMAKEFILE_H #define SYMMAKEFILE_H +#include "initprojectdeploy_symbian.h" #include <makefile.h> QT_BEGIN_NAMESPACE @@ -86,7 +87,7 @@ protected: QString canonizePath(const QString& origPath); virtual bool writeMakefile(QTextStream &t); - void generatePkgFile(const QString &iconFile); + void generatePkgFile(const QString &iconFile, DeploymentList &depList); bool containsStartWithItem(const QChar &c, const QStringList& src); virtual void init(); @@ -106,7 +107,7 @@ protected: QString &checkString); void writeHeader(QTextStream &t); - void writeBldInfContent(QTextStream& t, bool addDeploymentExtension, const QString &iconFile); + void writeBldInfContent(QTextStream& t, bool addDeploymentExtension, const QString &iconFile, DeploymentList &depList); static bool removeDuplicatedStrings(QStringList& stringList); diff --git a/qmake/project.cpp b/qmake/project.cpp index 2ad6112..c2e033e 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -79,7 +79,7 @@ enum ExpandFunc { E_MEMBER=1, E_FIRST, E_LAST, E_CAT, E_FROMFILE, E_EVAL, E_LIST E_SPRINTF, E_JOIN, E_SPLIT, E_BASENAME, E_DIRNAME, E_SECTION, E_FIND, E_SYSTEM, E_UNIQUE, E_QUOTE, E_ESCAPE_EXPAND, E_UPPER, E_LOWER, E_FILES, E_PROMPT, E_RE_ESCAPE, E_REPLACE, - E_SIZE }; + E_SIZE, E_GENERATE_UID }; QMap<QString, ExpandFunc> qmake_expandFunctions() { static QMap<QString, ExpandFunc> *qmake_expand_functions = 0; @@ -111,6 +111,7 @@ QMap<QString, ExpandFunc> qmake_expandFunctions() qmake_expand_functions->insert("prompt", E_PROMPT); qmake_expand_functions->insert("replace", E_REPLACE); qmake_expand_functions->insert("size", E_SIZE); + qmake_expand_functions->insert("generate_uid", E_GENERATE_UID); } return *qmake_expand_functions; } @@ -1864,6 +1865,9 @@ QMakeProject::doProjectExpand(QString func, QStringList args, return doProjectExpand(func, args_list, place); } +// defined in symbian generator +extern QString generate_test_uid(const QString& target); + QStringList QMakeProject::doProjectExpand(QString func, QList<QStringList> args_list, QMap<QString, QStringList> &place) @@ -2301,6 +2305,14 @@ QMakeProject::doProjectExpand(QString func, QList<QStringList> args_list, ret += QString::number(size); } break; } + case E_GENERATE_UID: + if (args.count() != 1) { + fprintf(stderr, "%s:%d: generate_uid(var) requires one argument.\n", + parser.file.toLatin1().constData(), parser.line_no); + } else { + ret += generate_test_uid(args.first()); + } + break; default: { fprintf(stderr, "%s:%d: Unknown replace function: %s\n", parser.file.toLatin1().constData(), parser.line_no, diff --git a/src/3rdparty/webkit/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/JavaScriptCore/ChangeLog index e292418..b943840 100644 --- a/src/3rdparty/webkit/JavaScriptCore/ChangeLog +++ b/src/3rdparty/webkit/JavaScriptCore/ChangeLog @@ -10,17 +10,6 @@ (OpaqueJSClass::OpaqueJSClass): (OpaqueJSClassContextData::OpaqueJSClassContextData): -2010-01-07 Norbert Leser <norbert.leser@nokia.com> - - Reviewed by NOBODY (OOPS!). - - Added time-based optimization and increased optimization level to O3, - conditionally for COMPILER(RVCT), - for increasing performance of JavaScript execution. - (Default settings are Ospace and O2) - - * runtime/Structure.h: - 2009-11-19 Thiago Macieira <thiago.macieira@nokia.com> Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h index ecdd997..f355c53 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h @@ -45,12 +45,6 @@ #define DUMP_PROPERTYMAP_STATS 0 #endif -#if COMPILER(RVCT) -#pragma arm -#pragma Otime -#pragma O3 -#endif - namespace JSC { class MarkStack; diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 4f33e22..6fe71d6 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 - 8f6992f4e8f027818429d428393b08068eca9ffa + 8f5ca3ba5da63a47d4f90bbd867d3e8453443dd3 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index 02daf86..8e1c965 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,48 @@ +2010-01-17 Srinidhi Shreedhara <srinidhi.shreedhara@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] [Symbian] SetWindow call in npapi plugin does not happen when the cooridnates are negative + https://bugs.webkit.org/show_bug.cgi?id=33573 + + * plugins/symbian/PluginViewSymbian.cpp: + (WebCore::PluginView::setNPWindowIfNeeded): Remove tests for negative + coordinates for early return. + +2010-01-14 Norbert Leser <norbert.leser@nokia.com> + + Reviewed by Laszlo Gombos. + + Platform Symbian specific: + Added time-based optimization (-Otime) and increased optimization level to -O3, + conditionally for RVCT compiler (for ARM), for increasing performance + (primarily affecting JavaScript execution). + Default settings are -Ospace and -O2. + + No new tests needed because no new funtionality is introduced, + only potential regression on existing tests needs to be evaluated. + + * WebCore.pro: + +2010-01-13 Girish Ramakrishnan <girish@forwardbias.in> + + Reviewed by Simon Hausmann. + + [Qt/Win] Flash in QGraphicsWebView does not process hover correctly. + + https://bugs.webkit.org/show_bug.cgi?id=33591 + + Mouse hover does not work as expected with the flash in some sites. + - http://www.bbc.co.uk/ Hover over the map + - http://www.barbie.com/ Hover over the menu items (Games, Videos) + The problem appears to be that Flash queries NPNVnetscapeWindow on every + mouse hover. I do not how flash uses this value but returning 0 when flash + is in windowless mode solves the problem (When using QGraphicsWebView we + inject wmode opaque, thereby putting the plugin in windowless mode). + + * plugins/win/PluginViewWin.cpp: + (windowHandleForPageClient): + 2010-01-13 Miikka Heikkinen <miikka.heikkinen@digia.com> Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro index 1489fa0..04aba62 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pro +++ b/src/3rdparty/webkit/WebCore/WebCore.pro @@ -23,7 +23,9 @@ symbian: { TARGET.UID3 = 0x200267C2 # RO text (code) section in qtwebkit.dll exceeds allocated space for gcce udeb target. # Move RW-section base address to start from 0xE00000 instead of the toolchain default 0x400000. - QMAKE_LFLAGS.ARMCC += --rw-base 0xE00000 + MMP_RULES += "LINKEROPTION armcc --rw-base 0xE00000" + MMP_RULES += ALWAYS_BUILD_AS_ARM + QMAKE_CXXFLAGS.ARMCC += -OTime -O3 } include($$PWD/../WebKit.pri) diff --git a/src/3rdparty/webkit/WebCore/platform/PopupMenu.h b/src/3rdparty/webkit/WebCore/platform/PopupMenu.h index 2315f02..f2fffb5 100644 --- a/src/3rdparty/webkit/WebCore/platform/PopupMenu.h +++ b/src/3rdparty/webkit/WebCore/platform/PopupMenu.h @@ -44,6 +44,7 @@ typedef struct HBITMAP__* HBITMAP; namespace WebCore { class QWebPopup; } +class QGraphicsProxyWidget; #elif PLATFORM(GTK) typedef struct _GtkMenu GtkMenu; typedef struct _GtkMenuItem GtkMenuItem; @@ -147,6 +148,7 @@ private: void clear(); void populate(const IntRect&); QWebPopup* m_popup; + QGraphicsProxyWidget* m_proxy; #elif PLATFORM(WIN) // ScrollBarClient virtual void valueChanged(Scrollbar*); diff --git a/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp index f6ec4f7..989b34c 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp @@ -1,6 +1,7 @@ /* * This file is part of the popup menu implementation for <select> elements in WebCore. * + * Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in> * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * Copyright (C) 2006 Apple Computer, Inc. * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com @@ -35,6 +36,9 @@ #include <QAction> #include <QDebug> +#include <QGraphicsProxyWidget> +#include <QGraphicsScene> +#include <QGraphicsView> #include <QListWidget> #include <QListWidgetItem> #include <QMenu> @@ -46,6 +50,7 @@ namespace WebCore { PopupMenu::PopupMenu(PopupMenuClient* client) : m_popupClient(client) + , m_proxy(0) { m_popup = new QWebPopup(client); } @@ -53,6 +58,7 @@ PopupMenu::PopupMenu(PopupMenuClient* client) PopupMenu::~PopupMenu() { delete m_popup; + delete m_proxy; } void PopupMenu::clear() @@ -92,8 +98,19 @@ void PopupMenu::show(const IntRect& r, FrameView* v, int index) rect.moveTopLeft(v->contentsToWindow(r.topLeft())); rect.setHeight(m_popup->sizeHint().height()); - m_popup->setParent(client->ownerWidget()); - m_popup->setGeometry(rect); + if (QGraphicsView* view = qobject_cast<QGraphicsView*>(client->ownerWidget())) { + if (!m_proxy) { + m_proxy = new QGraphicsProxyWidget; + m_proxy->setWidget(m_popup); + view->scene()->addItem(m_proxy); + } else + m_proxy->setVisible(true); + m_proxy->setGeometry(rect); + } else { + m_popup->setParent(client->ownerWidget()); + m_popup->setGeometry(rect); + } + m_popup->setCurrentIndex(index); m_popup->exec(); } diff --git a/src/3rdparty/webkit/WebCore/platform/qt/QWebPopup.cpp b/src/3rdparty/webkit/WebCore/platform/qt/QWebPopup.cpp index d077079..f7ebbc7 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/QWebPopup.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/QWebPopup.cpp @@ -26,6 +26,7 @@ #include <QApplication> #include <QInputContext> #include <QMouseEvent> +#include <QGraphicsProxyWidget> namespace WebCore { @@ -67,6 +68,10 @@ void QWebPopup::hidePopup() } QComboBox::hidePopup(); + + if (QGraphicsProxyWidget* proxy = graphicsProxyWidget()) + proxy->setVisible(false); + if (!m_popupVisible) return; diff --git a/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp b/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp index 14e25b1..cf69723 100644 --- a/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp +++ b/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp @@ -280,8 +280,6 @@ void PluginView::setNPWindowIfNeeded() m_npWindow.width = m_windowRect.width(); m_npWindow.height = m_windowRect.height(); - if (m_npWindow.x < 0 || m_npWindow.y < 0 || m_npWindow.width <= 0 || m_npWindow.height <= 0) - return; PluginView::setCurrentPluginView(this); JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly); diff --git a/src/3rdparty/webkit/WebCore/plugins/win/PluginViewWin.cpp b/src/3rdparty/webkit/WebCore/plugins/win/PluginViewWin.cpp index b313afb..ab71273 100644 --- a/src/3rdparty/webkit/WebCore/plugins/win/PluginViewWin.cpp +++ b/src/3rdparty/webkit/WebCore/plugins/win/PluginViewWin.cpp @@ -86,7 +86,9 @@ static inline HWND windowHandleForPageClient(PlatformPageClient client) #if PLATFORM(QT) if (!client) return 0; - return client->ownerWidget()->winId(); + if (QWidget* pluginParent = qobject_cast<QWidget*>(client->pluginParent())) + return pluginParent->winId(); + return 0; #else return client; #endif diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp index 6d08c32..a289ec0 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp @@ -1708,8 +1708,14 @@ QWebPage::~QWebPage() FrameLoader *loader = d->mainFrame->d->frame->loader(); if (loader) loader->detachFromParent(); - if (d->inspector) - d->inspector->setPage(0); + if (d->inspector) { + // Since we have to delete an internal inspector, + // call setInspector(0) directly to prevent potential crashes + if (d->inspectorIsInternalOnly) + d->setInspector(0); + else + d->inspector->setPage(0); + } delete d; } diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index cd47982..ee555f3 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,13 @@ +2009-11-19 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Fix QWebInspector destruction problem. + https://bugs.webkit.org/show_bug.cgi?id=31664 + + * Api/qwebpage.cpp: + (QWebPage::~QWebPage): + 2010-01-14 Simon Hausmann <simon.hausmann@nokia.com> Reviewed by Kenneth Rohde Christiansen. diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 2b4ab47..cedb43f 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -299,8 +299,6 @@ void QUnifiedTimer::registerRunningAnimation(QAbstractAnimation *animation) return; if (QAbstractAnimationPrivate::get(animation)->isPause) { - if (animation->duration() == -1) - qDebug() << "toto"; runningPauseAnimations << animation; } else runningLeafAnimations++; diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 74e5f74..a131d6c 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -5932,7 +5932,7 @@ void QUrl::detach() */ bool QUrl::isDetached() const { - return d && d->ref == 1; + return !d || d->ref == 1; } diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index 1b167e2..3f69b4f 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -107,13 +107,13 @@ QT_BEGIN_NAMESPACE \value ApplicationLayoutDirectionChange The default application layout direction has changed. \value ApplicationPaletteChange The default application palette has changed. \value ApplicationWindowIconChange The application's icon has changed. - \value CloseSoftwareInputPanel A widget wants to close the software input panel (SIP). \value ChildAdded An object gets a child (QChildEvent). \value ChildInserted An object gets a child (QChildEvent). Qt3Support only, use ChildAdded instead. \value ChildPolished A widget child gets polished (QChildEvent). \value ChildRemoved An object loses a child (QChildEvent). \value Clipboard The clipboard contents have changed (QClipboardEvent). \value Close Widget was closed (QCloseEvent). + \value CloseSoftwareInputPanel A widget wants to close the software input panel (SIP). \value ContentsRectChange The margins of the widget's content rect changed. \value ContextMenu Context popup menu (QContextMenuEvent). \value CursorChange The widget's cursor has changed. diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index d2fbf5a..556093f 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -538,7 +538,7 @@ QByteArray qUncompress(const uchar* data, int nbytes) forever { ulong alloc = len; - d.reset(q_check_ptr(static_cast<QByteArray::Data *>(qRealloc(d.data(), sizeof(QByteArray::Data) + alloc)))); + d.reset(q_check_ptr(static_cast<QByteArray::Data *>(qRealloc(d.take(), sizeof(QByteArray::Data) + alloc)))); if (!d) { // we are not allowed to crash here when compiling with QT_NO_EXCEPTIONS qWarning("qUncompress: could not allocate enough memory to uncompress data"); @@ -551,7 +551,7 @@ QByteArray qUncompress(const uchar* data, int nbytes) switch (res) { case Z_OK: if (len != alloc) { - d.reset(q_check_ptr(static_cast<QByteArray::Data *>(qRealloc(d.data(), sizeof(QByteArray::Data) + len)))); + d.reset(q_check_ptr(static_cast<QByteArray::Data *>(qRealloc(d.take(), sizeof(QByteArray::Data) + len)))); if (!d) { // we are not allowed to crash here when compiling with QT_NO_EXCEPTIONS qWarning("qUncompress: could not allocate enough memory to uncompress data"); @@ -561,6 +561,7 @@ QByteArray qUncompress(const uchar* data, int nbytes) d->ref = 1; d->alloc = d->size = len; d->data = d->array; + d->array[len] = 0; return QByteArray(d.take(), 0, 0); diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp index 0ef92d9..b6a2df4 100644 --- a/src/corelib/tools/qeasingcurve.cpp +++ b/src/corelib/tools/qeasingcurve.cpp @@ -125,7 +125,7 @@ \value OutCubic \inlineimage qeasingcurve-outcubic.png \br Easing curve for a cubic (t^3) function: - decelerating from zero velocity. + decelerating to zero velocity. \value InOutCubic \inlineimage qeasingcurve-inoutcubic.png \br Easing curve for a cubic (t^3) function: @@ -141,7 +141,7 @@ \value OutQuart \inlineimage qeasingcurve-outquart.png \br Easing curve for a cubic (t^4) function: - decelerating from zero velocity. + decelerating to zero velocity. \value InOutQuart \inlineimage qeasingcurve-inoutquart.png \br Easing curve for a cubic (t^4) function: @@ -157,7 +157,7 @@ \value OutQuint \inlineimage qeasingcurve-outquint.png \br Easing curve for a cubic (t^5) function: - decelerating from zero velocity. + decelerating to zero velocity. \value InOutQuint \inlineimage qeasingcurve-inoutquint.png \br Easing curve for a cubic (t^5) function: diff --git a/src/declarative/graphicsitems/qmlgraphicsitem.cpp b/src/declarative/graphicsitems/qmlgraphicsitem.cpp index dd685d4..bd3c1ea 100644 --- a/src/declarative/graphicsitems/qmlgraphicsitem.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsitem.cpp @@ -1533,8 +1533,12 @@ void QmlGraphicsItem::setParentItem(QmlGraphicsItem *parent) QmlGraphicsItem *oldParent = parentItem(); if (parent == oldParent || !parent) return; + Q_D(QmlGraphicsItem); QObject::setParent(parent); - QGraphicsObject::setParentItem(parent); + d->setParentItemHelper(parent, /*newParentVariant=*/0, /*thisPointerVariant=*/0); + if (oldParent) + emit oldParent->childrenChanged(); + emit parentChanged(); } /*! diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri index 9268545..6f2f57f 100644 --- a/src/declarative/qml/qml.pri +++ b/src/declarative/qml/qml.pri @@ -32,9 +32,8 @@ SOURCES += \ $$PWD/qmlscriptparser.cpp \ $$PWD/qmlenginedebug.cpp \ $$PWD/qmlrewrite.cpp \ - $$PWD/qmlbindingvme.cpp \ $$PWD/qmlvaluetype.cpp \ - $$PWD/qmlbindingoptimizations.cpp \ + $$PWD/qmlcompiledbindings.cpp \ $$PWD/qmlxmlhttprequest.cpp \ $$PWD/qmlsqldatabase.cpp \ $$PWD/qmetaobjectbuilder.cpp \ @@ -95,13 +94,12 @@ HEADERS += \ $$PWD/qmldeclarativedata_p.h \ $$PWD/qmlerror.h \ $$PWD/qmlscriptparser_p.h \ - $$PWD/qmlbindingvme_p.h \ $$PWD/qmlenginedebug_p.h \ $$PWD/qmlrewrite_p.h \ $$PWD/qpodvector_p.h \ $$PWD/qbitfield_p.h \ $$PWD/qmlvaluetype_p.h \ - $$PWD/qmlbindingoptimizations_p.h \ + $$PWD/qmlcompiledbindings_p.h \ $$PWD/qmlxmlhttprequest_p.h \ $$PWD/qmlsqldatabase_p.h \ $$PWD/qmetaobjectbuilder_p.h \ diff --git a/src/declarative/qml/qmlbinding.cpp b/src/declarative/qml/qmlbinding.cpp index c0389a8..3e29a3c 100644 --- a/src/declarative/qml/qmlbinding.cpp +++ b/src/declarative/qml/qmlbinding.cpp @@ -147,7 +147,11 @@ void QmlBinding::update(QmlMetaProperty::WriteFlags flags) bool isUndefined = false; QVariant value = this->value(&isUndefined); - if (isUndefined && !data->error.isValid()) { + if (isUndefined && !data->error.isValid() && data->property.isResettable()) { + + data->property.reset(); + + } else if (isUndefined && !data->error.isValid()) { QUrl url = QUrl(data->url); int line = data->line; @@ -159,7 +163,7 @@ void QmlBinding::update(QmlMetaProperty::WriteFlags flags) data->error.setDescription(QLatin1String("Unable to assign [undefined] to ") + QLatin1String(QMetaType::typeName(data->property.propertyType()))); } else if (!isUndefined && data->property.object() && - !data->property.write(value, flags)) { + !data->property.write(value, flags)) { QUrl url = QUrl(data->url); int line = data->line; diff --git a/src/declarative/qml/qmlbindingoptimizations.cpp b/src/declarative/qml/qmlbindingoptimizations.cpp deleted file mode 100644 index 1e49636..0000000 --- a/src/declarative/qml/qmlbindingoptimizations.cpp +++ /dev/null @@ -1,173 +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 QtDeclarative 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 "qmlbindingoptimizations_p.h" - -#include "qmlcontext_p.h" -#include <QtDeclarative/qmlinfo.h> -#include "qmlbindingvme_p.h" - -QT_BEGIN_NAMESPACE - -int QmlOptimizedBindings::methodCount = -1; - -QmlOptimizedBindings::QmlOptimizedBindings(const char *program, QmlContext *context) -: m_program(program) -{ - if (methodCount == -1) - methodCount = QmlOptimizedBindings::staticMetaObject.methodCount(); - - m_config.target = this; - m_config.targetSlot = metaObject()->methodCount(); - - quint32 bindings = 0; - QmlBindingVME::init(m_program, &m_config, &m_signalTable, &bindings); - - m_bindings = new Binding[bindings]; - - QmlAbstractExpression::setContext(context); -} - -QmlOptimizedBindings::~QmlOptimizedBindings() -{ - delete [] m_bindings; -} - -QmlAbstractBinding *QmlOptimizedBindings::configBinding(int index, QObject *target, - QObject *scope, int property) -{ - Binding *rv = m_bindings + index; - - rv->index = index; - rv->property = property; - rv->target = target; - rv->scope = scope; - rv->parent = this; - - addref(); // This is decremented in Binding::destroy() - - return rv; -} - -void QmlOptimizedBindings::Binding::setEnabled(bool e, QmlMetaProperty::WriteFlags flags) -{ - if (e) { - addToObject(target); - update(flags); - } else { - removeFromObject(); - } - - QmlAbstractBinding::setEnabled(e, flags); - - if (enabled != e) { - enabled = e; - - if (e) update(flags); - } -} - -int QmlOptimizedBindings::Binding::propertyIndex() -{ - return property & 0xFFFF; -} - -void QmlOptimizedBindings::Binding::update(QmlMetaProperty::WriteFlags) -{ - parent->run(this); -} - -void QmlOptimizedBindings::Binding::destroy() -{ - enabled = false; - removeFromObject(); - parent->release(); -} - -int QmlOptimizedBindings::qt_metacall(QMetaObject::Call c, int id, void **) -{ - if (c == QMetaObject::InvokeMetaMethod && id >= methodCount) { - id -= methodCount; - - quint32 *reeval = m_signalTable + m_signalTable[id]; - quint32 count = *reeval; - ++reeval; - for (quint32 ii = 0; ii < count; ++ii) { - run(m_bindings + reeval[ii]); - } - } - return -1; -} - -void QmlOptimizedBindings::run(Binding *binding) -{ - if (!binding->enabled) - return; - if (binding->updating) - qWarning("ERROR: Circular binding"); - - QmlContext *context = QmlAbstractExpression::context(); - if (!context) { - qWarning("QmlOptimizedBindings: Attempted to evaluate an expression in an invalid context"); - return; - } - QmlContextPrivate *cp = QmlContextPrivate::get(context); - - if (binding->property & 0xFFFF0000) { - QmlEnginePrivate *ep = QmlEnginePrivate::get(cp->engine); - - QmlValueType *vt = ep->valueTypes[(binding->property >> 16) & 0xFF]; - Q_ASSERT(vt); - vt->read(binding->target, binding->property & 0xFFFF); - - QObject *target = vt; - QmlBindingVME::run(m_program, binding->index, &m_config, cp, binding, - binding->scope, target); - - vt->write(binding->target, binding->property & 0xFFFF, - QmlMetaProperty::DontRemoveBinding); - } else { - QmlBindingVME::run(m_program, binding->index, &m_config, cp, binding, - binding->scope, binding->target); - } -} - -QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlbindingvme_p.h b/src/declarative/qml/qmlbindingvme_p.h deleted file mode 100644 index 01280f0..0000000 --- a/src/declarative/qml/qmlbindingvme_p.h +++ /dev/null @@ -1,182 +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 QtDeclarative 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 QMLBINDINGVME_P_H -#define QMLBINDINGVME_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qglobal.h> -#include <private/qscriptdeclarativeclass_p.h> -#include "qmlexpression_p.h" -#include "qmlguard_p.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QObject; -class QmlContextPrivate; -class QmlBindingVME -{ -public: - struct Config { - Config() : target(0), targetSlot(-1), subscriptions(0), identifiers(0) {} - ~Config() { delete [] subscriptions; delete [] identifiers; } - QObject *target; - int targetSlot; - - struct Subscription { - struct Signal { - QmlGuard<QObject> source; - int notifyIndex; - }; - - struct Id { - inline Id(); - inline ~Id(); - inline void reset(); - Id *next; - Id**prev; - QObject *target; - int methodIndex; - }; - - enum { InvalidType, SignalType, IdType } type; - inline Subscription(); - inline ~Subscription(); - bool isSignal() const { return type == SignalType; } - bool isId() const { return type == IdType; } - inline Signal *signal(); - inline Id *id(); - union { - char signalData[sizeof(Signal)]; - char idData[sizeof(Id)]; - }; - }; - Subscription *subscriptions; - QScriptDeclarativeClass::PersistentIdentifier *identifiers; - }; - - static void init(const char *program, Config *config, - quint32 **sigTable, quint32 *bindingCount); - static void run(const char *program, int instr, - Config *config, QmlContextPrivate *context, QmlDelayedError *error, - QObject *scope, QObject *output); - static void dump(const char *); -}; - -QmlBindingVME::Config::Subscription::Subscription() -: type(InvalidType) -{ -} - -QmlBindingVME::Config::Subscription::~Subscription() -{ - if (type == SignalType) ((Signal *)signalData)->~Signal(); - else if (type == IdType) ((Id *)idData)->~Id(); -} - -QmlBindingVME::Config::Subscription::Id::Id() -: next(0), prev(0), target(0), methodIndex(-1) -{ -} - -QmlBindingVME::Config::Subscription::Id::~Id() -{ - reset(); -} - -void QmlBindingVME::Config::Subscription::Id::reset() -{ - if (next) next->prev = prev; - if (prev) *prev = next; - next = 0; - prev = 0; - target = 0; - methodIndex = -1; -} - -class QmlBindingCompilerPrivate; -class QmlBindingCompiler -{ -public: - QmlBindingCompiler(); - ~QmlBindingCompiler(); - - // Returns true if bindings were compiled - bool isValid() const; - - struct Expression - { - QmlParser::Object *component; - QmlParser::Object *context; - QmlParser::Property *property; - QmlParser::Variant expression; - QHash<QString, QmlParser::Object *> ids; - QmlEnginePrivate::Imports imports; - }; - - // -1 on failure, otherwise the binding index to use - int compile(const Expression &, QmlEnginePrivate *); - - // Returns the compiled program - QByteArray program() const; - -private: - QmlBindingCompilerPrivate *d; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QMLBINDINGVME_P_H - diff --git a/src/declarative/qml/qmlbindingvme.cpp b/src/declarative/qml/qmlcompiledbindings.cpp index 47f02b2..d09f7eb 100644 --- a/src/declarative/qml/qmlbindingvme.cpp +++ b/src/declarative/qml/qmlcompiledbindings.cpp @@ -39,7 +39,9 @@ ** ****************************************************************************/ -#include "qmlbindingvme_p.h" +#include "qmlcompiledbindings_p.h" + +#include <QtDeclarative/qmlinfo.h> #include <private/qmlcontext_p.h> #include <private/qmljsast_p.h> #include <private/qmljsengine_p.h> @@ -52,22 +54,6 @@ QT_BEGIN_NAMESPACE using namespace QmlJS; -QmlBindingVME::Config::Subscription::Signal *QmlBindingVME::Config::Subscription::signal() -{ - if (type == IdType) ((Id *)idData)->~Id(); - if (type != SignalType) new (signalData) Signal; - type = SignalType; - return (Signal *)signalData; -} - -QmlBindingVME::Config::Subscription::Id *QmlBindingVME::Config::Subscription::id() -{ - if (type == SignalType) ((Signal *)signalData)->~Signal(); - if (type != IdType) new (idData) Id; - type = IdType; - return (Id *)idData; -} - namespace { // Supported types: int, qreal, QString (needs constr/destr), QObject*, bool struct Register { @@ -106,7 +92,258 @@ struct Register { int type; // Optional type void *data[2]; // Object stored here }; +} + +class QmlCompiledBindingsPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QmlCompiledBindings) + +public: + QmlCompiledBindingsPrivate(); + virtual ~QmlCompiledBindingsPrivate(); + + struct Binding : public QmlAbstractBinding, public QmlDelayedError { + Binding() : enabled(false), updating(0), property(0), + scope(0), target(0), parent(0) {} + + // Inherited from QmlAbstractBinding + virtual void setEnabled(bool, QmlMetaProperty::WriteFlags flags); + virtual int propertyIndex(); + virtual void update(QmlMetaProperty::WriteFlags flags); + virtual void destroy(); + + int index:30; + bool enabled:1; + bool updating:1; + int property; + QObject *scope; + QObject *target; + + QmlCompiledBindingsPrivate *parent; + }; + + struct Subscription { + struct Signal { + QmlGuard<QObject> source; + int notifyIndex; + }; + + enum { InvalidType, SignalType, IdType } type; + inline Subscription(); + inline ~Subscription(); + bool isSignal() const { return type == SignalType; } + bool isId() const { return type == IdType; } + inline Signal *signal(); + inline QmlContextPrivate::IdNotifier *id(); + union { + char signalData[sizeof(Signal)]; + char idData[sizeof(QmlContextPrivate::IdNotifier)]; + }; + }; + Subscription *subscriptions; + QScriptDeclarativeClass::PersistentIdentifier *identifiers; + + void run(Binding *); + + const char *programData; + Binding *m_bindings; + quint32 *m_signalTable; + + static int methodCount; + + void init(); + void run(int instr, QmlContextPrivate *context, + QmlDelayedError *error, QObject *scope, QObject *output); + + + inline void unsubscribe(int subIndex); + inline void subscribeId(QmlContextPrivate *p, int idIndex, int subIndex); + inline void subscribe(QObject *o, int notifyIndex, int subIndex); + + QmlPropertyCache::Data *findproperty(QObject *obj, + const QScriptDeclarativeClass::Identifier &name, + QmlEnginePrivate *enginePriv, + QmlPropertyCache::Data &local); + bool findproperty(QObject *obj, + Register *output, + QmlEnginePrivate *enginePriv, + int subIdx, + const QScriptDeclarativeClass::Identifier &name, + bool isTerminal); + void findgeneric(Register *output, // value output + int subIdx, // Subscription index in config + QmlContextPrivate *context, // Context to search in + const QScriptDeclarativeClass::Identifier &name, + bool isTerminal); +}; + +QmlCompiledBindingsPrivate::QmlCompiledBindingsPrivate() +: subscriptions(0), identifiers(0) +{ +} + +QmlCompiledBindingsPrivate::~QmlCompiledBindingsPrivate() +{ + delete [] subscriptions; subscriptions = 0; + delete [] identifiers; identifiers = 0; +} + +QmlCompiledBindingsPrivate::Subscription::Subscription() +: type(InvalidType) +{ +} + +QmlCompiledBindingsPrivate::Subscription::~Subscription() +{ + if (type == SignalType) ((Signal *)signalData)->~Signal(); + else if (type == IdType) ((QmlContextPrivate::IdNotifier *)idData)->~IdNotifier(); +} + + +int QmlCompiledBindingsPrivate::methodCount = -1; + +QmlCompiledBindings::QmlCompiledBindings(const char *program, QmlContext *context) +: QObject(*(new QmlCompiledBindingsPrivate)) +{ + Q_D(QmlCompiledBindings); + + if (d->methodCount == -1) + d->methodCount = QmlCompiledBindings::staticMetaObject.methodCount(); + + d->programData = program; + + d->init(); + + QmlAbstractExpression::setContext(context); +} + +QmlCompiledBindings::~QmlCompiledBindings() +{ + Q_D(QmlCompiledBindings); + + delete [] d->m_bindings; +} + +QmlAbstractBinding *QmlCompiledBindings::configBinding(int index, QObject *target, + QObject *scope, int property) +{ + Q_D(QmlCompiledBindings); + + QmlCompiledBindingsPrivate::Binding *rv = d->m_bindings + index; + + rv->index = index; + rv->property = property; + rv->target = target; + rv->scope = scope; + rv->parent = d; + + addref(); // This is decremented in Binding::destroy() + + return rv; +} + +void QmlCompiledBindingsPrivate::Binding::setEnabled(bool e, QmlMetaProperty::WriteFlags flags) +{ + if (e) { + addToObject(target); + update(flags); + } else { + removeFromObject(); + } + QmlAbstractBinding::setEnabled(e, flags); + + if (enabled != e) { + enabled = e; + + if (e) update(flags); + } +} + +int QmlCompiledBindingsPrivate::Binding::propertyIndex() +{ + return property & 0xFFFF; +} + +void QmlCompiledBindingsPrivate::Binding::update(QmlMetaProperty::WriteFlags) +{ + parent->run(this); +} + +void QmlCompiledBindingsPrivate::Binding::destroy() +{ + enabled = false; + removeFromObject(); + parent->q_func()->release(); +} + +int QmlCompiledBindings::qt_metacall(QMetaObject::Call c, int id, void **) +{ + Q_D(QmlCompiledBindings); + + if (c == QMetaObject::InvokeMetaMethod && id >= d->methodCount) { + id -= d->methodCount; + + quint32 *reeval = d->m_signalTable + d->m_signalTable[id]; + quint32 count = *reeval; + ++reeval; + for (quint32 ii = 0; ii < count; ++ii) { + d->run(d->m_bindings + reeval[ii]); + } + } + return -1; +} + +void QmlCompiledBindingsPrivate::run(Binding *binding) +{ + Q_Q(QmlCompiledBindings); + + if (!binding->enabled) + return; + if (binding->updating) + qWarning("ERROR: Circular binding"); + + QmlContext *context = q->QmlAbstractExpression::context(); + if (!context) { + qWarning("QmlCompiledBindings: Attempted to evaluate an expression in an invalid context"); + return; + } + QmlContextPrivate *cp = QmlContextPrivate::get(context); + + if (binding->property & 0xFFFF0000) { + QmlEnginePrivate *ep = QmlEnginePrivate::get(cp->engine); + + QmlValueType *vt = ep->valueTypes[(binding->property >> 16) & 0xFF]; + Q_ASSERT(vt); + vt->read(binding->target, binding->property & 0xFFFF); + + QObject *target = vt; + run(binding->index, cp, binding, binding->scope, target); + + vt->write(binding->target, binding->property & 0xFFFF, + QmlMetaProperty::DontRemoveBinding); + } else { + run(binding->index, cp, binding, binding->scope, binding->target); + } +} + +QmlCompiledBindingsPrivate::Subscription::Signal *QmlCompiledBindingsPrivate::Subscription::signal() +{ + if (type == IdType) ((QmlContextPrivate::IdNotifier *)idData)->~IdNotifier(); + if (type != SignalType) new (signalData) Signal; + type = SignalType; + return (Signal *)signalData; +} + +QmlContextPrivate::IdNotifier *QmlCompiledBindingsPrivate::Subscription::id() +{ + if (type == SignalType) ((Signal *)signalData)->~Signal(); + if (type != IdType) new (idData) QmlContextPrivate::IdNotifier; + type = IdType; + return (QmlContextPrivate::IdNotifier *)idData; +} + +namespace { // This structure is exactly 8-bytes in size struct Instr { enum { @@ -411,68 +648,72 @@ struct QmlBindingCompilerPrivate QByteArray buildExceptionData() const; }; -inline void unsubscribe(int subIndex, QmlBindingVME::Config *config) +void QmlCompiledBindingsPrivate::unsubscribe(int subIndex) { - QmlBindingVME::Config::Subscription *sub = (config->subscriptions + subIndex); + Q_Q(QmlCompiledBindings); + + QmlCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex); if (sub->isSignal()) { - QmlBindingVME::Config::Subscription::Signal *s = sub->signal(); + QmlCompiledBindingsPrivate::Subscription::Signal *s = sub->signal(); if (s->source) #if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2)) QMetaObject::disconnectOne(s->source, s->notifyIndex, - config->target, config->targetSlot + subIndex); + q, methodCount + subIndex); #else // QTBUG-6781 QMetaObject::disconnect(s->source, s->notifyIndex, - config->target, config->targetSlot + subIndex); + q, methodCount + subIndex); #endif } else if (sub->isId()) { - sub->id()->reset(); + sub->id()->clear(); } } -inline void subscribeId(QmlContextPrivate *p, int idIndex, - int subIndex, QmlBindingVME::Config *config) +void QmlCompiledBindingsPrivate::subscribeId(QmlContextPrivate *p, int idIndex, int subIndex) { - unsubscribe(subIndex, config); + Q_Q(QmlCompiledBindings); + + unsubscribe(subIndex); if (p->idValues[idIndex]) { - QmlBindingVME::Config::Subscription *sub = (config->subscriptions + subIndex); - QmlBindingVME::Config::Subscription::Id *i = sub->id(); + QmlCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex); + QmlContextPrivate::IdNotifier *i = sub->id(); i->next = p->idValues[idIndex].bindings; i->prev = &p->idValues[idIndex].bindings; p->idValues[idIndex].bindings = i; if (i->next) i->next->prev = &i->next; - i->target = config->target; - i->methodIndex = config->targetSlot + subIndex; + i->target = q; + i->methodIndex = methodCount + subIndex; } } -inline void subscribe(QObject *o, int notifyIndex, - int subIndex, QmlBindingVME::Config *config) +void QmlCompiledBindingsPrivate::subscribe(QObject *o, int notifyIndex, int subIndex) { - QmlBindingVME::Config::Subscription *sub = (config->subscriptions + subIndex); + Q_Q(QmlCompiledBindings); + + QmlCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex); if (sub->isId()) - unsubscribe(subIndex, config); + unsubscribe(subIndex); - QmlBindingVME::Config::Subscription::Signal *s = sub->signal(); + QmlCompiledBindingsPrivate::Subscription::Signal *s = sub->signal(); if (o != s->source || notifyIndex != s->notifyIndex) { if (s->source) #if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2)) QMetaObject::disconnectOne(s->source, s->notifyIndex, - config->target, config->targetSlot + subIndex); + q, methodCount + subIndex); #else // QTBUG-6781 QMetaObject::disconnect(s->source, s->notifyIndex, - config->target, config->targetSlot + subIndex); + q, methodCount + subIndex); #endif s->source = o; s->notifyIndex = notifyIndex; if (s->source && s->notifyIndex != -1) - QMetaObject::connect(s->source, s->notifyIndex, config->target, - config->targetSlot + subIndex, Qt::DirectConnection); + QMetaObject::connect(s->source, s->notifyIndex, q, + methodCount + subIndex, Qt::DirectConnection); } } @@ -566,10 +807,11 @@ static QObject *variantToQObject(const QVariant &value, bool *ok) } } -static QmlPropertyCache::Data *findproperty(QObject *obj, - const QScriptDeclarativeClass::Identifier &name, - QmlEnginePrivate *enginePriv, - QmlPropertyCache::Data &local) +QmlPropertyCache::Data * +QmlCompiledBindingsPrivate::findproperty(QObject *obj, + const QScriptDeclarativeClass::Identifier &name, + QmlEnginePrivate *enginePriv, + QmlPropertyCache::Data &local) { QmlPropertyCache *cache = 0; QmlDeclarativeData *ddata = QmlDeclarativeData::get(obj); @@ -595,11 +837,10 @@ static QmlPropertyCache::Data *findproperty(QObject *obj, return property; } -static bool findproperty(QObject *obj, Register *output, - QmlEnginePrivate *enginePriv, - QmlBindingVME::Config *config, int subIdx, - const QScriptDeclarativeClass::Identifier &name, - bool isTerminal) +bool QmlCompiledBindingsPrivate::findproperty(QObject *obj, Register *output, + QmlEnginePrivate *enginePriv, + int subIdx, const QScriptDeclarativeClass::Identifier &name, + bool isTerminal) { if (!obj) { output->setUndefined(); @@ -611,7 +852,7 @@ static bool findproperty(QObject *obj, Register *output, if (property) { if (subIdx != -1) - subscribe(obj, property->notifyIndex, subIdx, config); + subscribe(obj, property->notifyIndex, subIdx); if (property->flags & QmlPropertyCache::Data::IsQObjectDerived) { void *args[] = { output->typeDataPtr(), 0 }; @@ -668,12 +909,11 @@ static bool findproperty(QObject *obj, Register *output, } } -static void findgeneric(Register *output, // value output - QmlBindingVME::Config *config, - int subIdx, // Subscription index in config - QmlContextPrivate *context, // Context to search in - const QScriptDeclarativeClass::Identifier &name, - bool isTerminal) +void QmlCompiledBindingsPrivate::findgeneric(Register *output, + int subIdx, + QmlContextPrivate *context, + const QScriptDeclarativeClass::Identifier &name, + bool isTerminal) { QmlEnginePrivate *enginePriv = QmlEnginePrivate::get(context->engine); @@ -685,8 +925,7 @@ static void findgeneric(Register *output, // val if (contextPropertyIndex != -1) { if (subIdx != -1) - subscribe(QmlContextPrivate::get(context), contextPropertyIndex + context->notifyIndex, - subIdx, config); + subscribe(QmlContextPrivate::get(context), contextPropertyIndex + context->notifyIndex, subIdx); if (contextPropertyIndex < context->idValueCount) { output->setQObject(context->idValues[contextPropertyIndex]); @@ -717,7 +956,7 @@ static void findgeneric(Register *output, // val if (QObject *root = context->defaultObjects.isEmpty()?0:context->defaultObjects.first()) { - if (findproperty(root, output, enginePriv, config, subIdx, name, isTerminal)) + if (findproperty(root, output, enginePriv, subIdx, name, isTerminal)) return; } @@ -732,20 +971,16 @@ static void findgeneric(Register *output, // val output->setUndefined(); } -/*! -Returns the signal/binding table. -*/ -void QmlBindingVME::init(const char *programData, Config *config, - quint32 **sigTable, quint32 *bindingCount) +void QmlCompiledBindingsPrivate::init() { Program *program = (Program *)programData; if (program->subscriptions) - config->subscriptions = new Config::Subscription[program->subscriptions]; + subscriptions = new QmlCompiledBindingsPrivate::Subscription[program->subscriptions]; if (program->identifiers) - config->identifiers = new QScriptDeclarativeClass::PersistentIdentifier[program->identifiers]; + identifiers = new QScriptDeclarativeClass::PersistentIdentifier[program->identifiers]; - *sigTable = (quint32 *)(program->data() + program->signalTableOffset); - *bindingCount = program->bindings; + m_signalTable = (quint32 *)(program->data() + program->signalTableOffset); + m_bindings = new QmlCompiledBindingsPrivate::Binding[program->bindings]; } static void throwException(int id, QmlDelayedError *error, @@ -769,9 +1004,9 @@ static void throwException(int id, QmlDelayedError *error, qWarning() << error->error; } -void QmlBindingVME::run(const char *programData, int instrIndex, - Config *config, QmlContextPrivate *context, QmlDelayedError *error, - QObject *scope, QObject *output) +void QmlCompiledBindingsPrivate::run(int instrIndex, + QmlContextPrivate *context, QmlDelayedError *error, + QObject *scope, QObject *output) { error->removeError(); @@ -791,17 +1026,15 @@ void QmlBindingVME::run(const char *programData, int instrIndex, break; case Instr::SubscribeId: - subscribeId(context, instr->subscribe.index, instr->subscribe.offset, config); + subscribeId(context, instr->subscribe.index, instr->subscribe.offset); break; case Instr::Subscribe: { QObject *o = 0; - int notifyIndex = instr->subscribe.index; - const Register &object = registers[instr->subscribe.reg]; if (!object.isUndefined()) o = object.getQObject(); - subscribe(o, instr->subscribe.index, instr->subscribe.offset, config); + subscribe(o, instr->subscribe.index, instr->subscribe.offset); } break; @@ -1084,14 +1317,13 @@ void QmlBindingVME::run(const char *programData, int instrIndex, return; case Instr::InitString: - if (!config->identifiers[instr->initstring.offset].identifier) { + if (!identifiers[instr->initstring.offset].identifier) { quint32 len = *(quint32 *)(data + instr->initstring.dataIdx); QChar *strdata = (QChar *)(data + instr->initstring.dataIdx + sizeof(quint32)); QString str = QString::fromRawData(strdata, len); - config->identifiers[instr->initstring.offset] = - engine->objectClass->createPersistentIdentifier(str); + identifiers[instr->initstring.offset] = engine->objectClass->createPersistentIdentifier(str); } break; @@ -1100,9 +1332,9 @@ void QmlBindingVME::run(const char *programData, int instrIndex, // We start the search in the parent context, as we know that the // name is not present in the current context or it would have been // found during the static compile - findgeneric(registers + instr->find.reg, config, instr->find.subscribeIndex, + findgeneric(registers + instr->find.reg, instr->find.subscribeIndex, QmlContextPrivate::get(context->parent), - config->identifiers[instr->find.name].identifier, + identifiers[instr->find.name].identifier, instr->common.type == Instr::FindGenericTerminal); break; @@ -1116,8 +1348,8 @@ void QmlBindingVME::run(const char *programData, int instrIndex, } findproperty(object.getQObject(), registers + instr->find.reg, - QmlEnginePrivate::get(context->engine), config, - instr->find.subscribeIndex, config->identifiers[instr->find.name].identifier, + QmlEnginePrivate::get(context->engine), + instr->find.subscribeIndex, identifiers[instr->find.name].identifier, instr->common.type == Instr::FindPropertyTerminal); } break; @@ -1186,9 +1418,9 @@ void QmlBindingVME::run(const char *programData, int instrIndex, } } -void QmlBindingVME::dump(const char *programData) +void QmlBindingCompiler::dump(const QByteArray &programData) { - const Program *program = (const Program *)programData; + const Program *program = (const Program *)programData.constData(); qWarning() << "Program.bindings:" << program->bindings; qWarning() << "Program.dataLength:" << program->dataLength; @@ -2513,5 +2745,5 @@ QByteArray QmlBindingCompiler::program() const } -QT_END_NAMESPACE +QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlbindingoptimizations_p.h b/src/declarative/qml/qmlcompiledbindings_p.h index 42b7d17..1d8fac4 100644 --- a/src/declarative/qml/qmlbindingoptimizations_p.h +++ b/src/declarative/qml/qmlcompiledbindings_p.h @@ -55,50 +55,57 @@ #include "qmlexpression_p.h" #include "qmlbinding.h" -#include "qmlbindingvme_p.h" QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -class QmlOptimizedBindings : public QObject, public QmlAbstractExpression, public QmlRefCount +class QmlBindingCompilerPrivate; +class QmlBindingCompiler { public: - QmlOptimizedBindings(const char *program, QmlContext *context); - virtual ~QmlOptimizedBindings(); + QmlBindingCompiler(); + ~QmlBindingCompiler(); + + // Returns true if bindings were compiled + bool isValid() const; + + struct Expression + { + QmlParser::Object *component; + QmlParser::Object *context; + QmlParser::Property *property; + QmlParser::Variant expression; + QHash<QString, QmlParser::Object *> ids; + QmlEnginePrivate::Imports imports; + }; + + // -1 on failure, otherwise the binding index to use + int compile(const Expression &, QmlEnginePrivate *); + + // Returns the compiled program + QByteArray program() const; + + static void dump(const QByteArray &); +private: + QmlBindingCompilerPrivate *d; +}; + +class QmlCompiledBindingsPrivate; +class QmlCompiledBindings : public QObject, public QmlAbstractExpression, public QmlRefCount +{ +public: + QmlCompiledBindings(const char *program, QmlContext *context); + virtual ~QmlCompiledBindings(); + QmlAbstractBinding *configBinding(int index, QObject *target, QObject *scope, int property); protected: int qt_metacall(QMetaObject::Call, int, void **); private: - struct Binding : public QmlAbstractBinding, public QmlDelayedError { - Binding() : enabled(false), updating(0), property(0), - scope(0), target(0), parent(0) {} - - // Inherited from QmlAbstractBinding - virtual void setEnabled(bool, QmlMetaProperty::WriteFlags flags); - virtual int propertyIndex(); - virtual void update(QmlMetaProperty::WriteFlags flags); - virtual void destroy(); - - int index:30; - bool enabled:1; - bool updating:1; - int property; - QObject *scope; - QObject *target; - - QmlOptimizedBindings *parent; - }; - void run(Binding *); - - QmlBindingVME::Config m_config; - const char *m_program; - Binding *m_bindings; - quint32 *m_signalTable; - - static int methodCount; + Q_DISABLE_COPY(QmlCompiledBindings); + Q_DECLARE_PRIVATE(QmlCompiledBindings); }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index 5937734..bb7abf3 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -64,7 +64,7 @@ #include "qmlglobal_p.h" #include "qmlscriptparser_p.h" #include "qmlbinding.h" -#include "qmlbindingvme_p.h" +#include "qmlcompiledbindings_p.h" #include <qfxperf_p_p.h> @@ -257,26 +257,30 @@ bool QmlCompiler::testLiteralAssignment(const QMetaProperty &prop, break; case QVariant::Color: { - QColor c = QmlStringConverters::colorFromString(string); - if (!c.isValid()) COMPILE_EXCEPTION(v, QCoreApplication::translate("QmlCompiler","Invalid property assignment: color expected")); + bool ok; + QmlStringConverters::colorFromString(string, &ok); + if (!ok) COMPILE_EXCEPTION(v, QCoreApplication::translate("QmlCompiler","Invalid property assignment: color expected")); } break; case QVariant::Date: { - QDate d = QDate::fromString(string, Qt::ISODate); - if (!d.isValid()) COMPILE_EXCEPTION(v, QCoreApplication::translate("QmlCompiler","Invalid property assignment: date expected")); + bool ok; + QmlStringConverters::dateFromString(string, &ok); + if (!ok) COMPILE_EXCEPTION(v, QCoreApplication::translate("QmlCompiler","Invalid property assignment: date expected")); } break; case QVariant::Time: { - QTime time = QTime::fromString(string, Qt::ISODate); - if (!time.isValid()) COMPILE_EXCEPTION(v, QCoreApplication::translate("QmlCompiler","Invalid property assignment: time expected")); + bool ok; + QmlStringConverters::timeFromString(string, &ok); + if (!ok) COMPILE_EXCEPTION(v, QCoreApplication::translate("QmlCompiler","Invalid property assignment: time expected")); } break; case QVariant::DateTime: { - QDateTime dateTime = QDateTime::fromString(string, Qt::ISODate); - if (!dateTime.isValid()) COMPILE_EXCEPTION(v, QCoreApplication::translate("QmlCompiler","Invalid property assignment: datetime expected")); + bool ok; + QmlStringConverters::dateTimeFromString(string, &ok); + if (!ok) COMPILE_EXCEPTION(v, QCoreApplication::translate("QmlCompiler","Invalid property assignment: datetime expected")); } break; case QVariant::Point: @@ -311,7 +315,7 @@ bool QmlCompiler::testLiteralAssignment(const QMetaProperty &prop, case QVariant::Vector3D: { bool ok; - QVector3D point = QmlStringConverters::vector3DFromString(string, &ok); + QmlStringConverters::vector3DFromString(string, &ok); if (!ok) COMPILE_EXCEPTION(v, QCoreApplication::translate("QmlCompiler","Invalid property assignment: 3D vector expected")); } break; @@ -417,7 +421,7 @@ void QmlCompiler::genLiteralAssignment(const QMetaProperty &prop, break; case QVariant::Date: { - QDate d = QDate::fromString(string, Qt::ISODate); + QDate d = QmlStringConverters::dateFromString(string); instr.type = QmlInstruction::StoreDate; instr.storeDate.propertyIndex = prop.propertyIndex(); instr.storeDate.value = d.toJulianDay(); @@ -425,7 +429,7 @@ void QmlCompiler::genLiteralAssignment(const QMetaProperty &prop, break; case QVariant::Time: { - QTime time = QTime::fromString(string, Qt::ISODate); + QTime time = QmlStringConverters::timeFromString(string); int data[] = { time.hour(), time.minute(), time.second(), time.msec() }; int index = output->indexForInt(data, 4); @@ -436,7 +440,7 @@ void QmlCompiler::genLiteralAssignment(const QMetaProperty &prop, break; case QVariant::DateTime: { - QDateTime dateTime = QDateTime::fromString(string, Qt::ISODate); + QDateTime dateTime = QmlStringConverters::dateTimeFromString(string); int data[] = { dateTime.date().toJulianDay(), dateTime.time().hour(), dateTime.time().minute(), @@ -2672,7 +2676,7 @@ bool QmlCompiler::completeComponentBuild() if (bindingCompiler.isValid()) { compileState.compiledBindingData = bindingCompiler.program(); - QmlBindingVME::dump(compileState.compiledBindingData); + QmlBindingCompiler::dump(compileState.compiledBindingData); } saveComponentState(); diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp index f97f142..0eb497d 100644 --- a/src/declarative/qml/qmlcontext.cpp +++ b/src/declarative/qml/qmlcontext.cpp @@ -45,7 +45,7 @@ #include "qmlexpression_p.h" #include "qmlengine_p.h" #include "qmlengine.h" -#include "qmlbindingoptimizations_p.h" +#include "qmlcompiledbindings_p.h" #include "qmlinfo.h" #include <qscriptengine.h> @@ -108,7 +108,7 @@ void QmlContextPrivate::destroyed(ContextGuard *guard) while(guard->bindings) { QObject *o = guard->bindings->target; int mi = guard->bindings->methodIndex; - guard->bindings->reset(); + guard->bindings->clear(); if (o) o->qt_metacall(QMetaObject::InvokeMetaMethod, mi, 0); } diff --git a/src/declarative/qml/qmlcontext_p.h b/src/declarative/qml/qmlcontext_p.h index ffb4298..cd7e1b6 100644 --- a/src/declarative/qml/qmlcontext_p.h +++ b/src/declarative/qml/qmlcontext_p.h @@ -59,7 +59,6 @@ #include "qmlengine_p.h" #include "qmlintegercache_p.h" #include "qmltypenamecache_p.h" -#include "qmlbindingvme_p.h" #include <QtCore/qhash.h> #include <QtScript/qscriptvalue.h> @@ -77,7 +76,7 @@ class QmlExpression; class QmlExpressionPrivate; class QmlAbstractExpression; class QmlBinding_Id; -class QmlOptimizedBindings; +class QmlCompiledBindings; class Q_DECLARATIVE_EXPORT QmlContextPrivate : public QObjectPrivate { @@ -114,15 +113,27 @@ public: QmlDeclarativeData *contextObjects; + struct IdNotifier + { + inline IdNotifier(); + inline ~IdNotifier(); + + inline void clear(); + + IdNotifier *next; + IdNotifier**prev; + QObject *target; + int methodIndex; + }; + struct ContextGuard : public QmlGuard<QObject> { - ContextGuard() : priv(0), bindings(0) {} + inline ContextGuard(); + inline ContextGuard &operator=(QObject *obj); + inline virtual void objectDestroyed(QObject *); + QmlContextPrivate *priv; - QmlBindingVME::Config::Subscription::Id *bindings; - ContextGuard &operator=(QObject *obj) { - (QmlGuard<QObject>&)*this = obj; return *this; - } - void objectDestroyed(QObject *) { priv->destroyed(this); } + IdNotifier *bindings; }; ContextGuard *idValues; int idValueCount; @@ -137,12 +148,45 @@ public: return static_cast<QmlContext *>(context->q_func()); } - QmlOptimizedBindings *optimizedBindings; + QmlCompiledBindings *optimizedBindings; // Only used for debugging QList<QPointer<QObject> > instances; }; +QmlContextPrivate::IdNotifier::IdNotifier() +: next(0), prev(0), target(0), methodIndex(-1) +{ +} + +QmlContextPrivate::IdNotifier::~IdNotifier() +{ + clear(); +} + +void QmlContextPrivate::IdNotifier::clear() +{ + if (next) next->prev = prev; + if (prev) *prev = next; + next = 0; prev = 0; target = 0; + methodIndex = -1; +} + +QmlContextPrivate::ContextGuard::ContextGuard() +: priv(0), bindings(0) +{ +} + +QmlContextPrivate::ContextGuard &QmlContextPrivate::ContextGuard::operator=(QObject *obj) +{ + (QmlGuard<QObject>&)*this = obj; return *this; +} + +void QmlContextPrivate::ContextGuard::objectDestroyed(QObject *) +{ + priv->destroyed(this); +} + QT_END_NAMESPACE #endif // QMLCONTEXT_P_H diff --git a/src/declarative/qml/qmlcontextscriptclass.cpp b/src/declarative/qml/qmlcontextscriptclass.cpp index eecc611..80d52ad 100644 --- a/src/declarative/qml/qmlcontextscriptclass.cpp +++ b/src/declarative/qml/qmlcontextscriptclass.cpp @@ -174,7 +174,8 @@ QmlContextScriptClass::queryProperty(QmlContext *bindContext, QObject *scopeObje if (scopeObject) { QScriptClass::QueryFlags rv = - ep->objectClass->queryProperty(scopeObject, name, flags, bindContext, QmlObjectScriptClass::ImplicitObject); + ep->objectClass->queryProperty(scopeObject, name, flags, bindContext, + QmlObjectScriptClass::ImplicitObject | QmlObjectScriptClass::SkipAttachedProperties); if (rv) { lastScopeObject = scopeObject; lastContext = bindContext; @@ -184,7 +185,8 @@ QmlContextScriptClass::queryProperty(QmlContext *bindContext, QObject *scopeObje for (int ii = cp->defaultObjects.count() - 1; ii >= 0; --ii) { QScriptClass::QueryFlags rv = - ep->objectClass->queryProperty(cp->defaultObjects.at(ii), name, flags, bindContext, QmlObjectScriptClass::ImplicitObject); + ep->objectClass->queryProperty(cp->defaultObjects.at(ii), name, flags, bindContext, + QmlObjectScriptClass::ImplicitObject | QmlObjectScriptClass::SkipAttachedProperties); if (rv) { lastDefaultObject = ii; diff --git a/src/declarative/qml/qmllistscriptclass.cpp b/src/declarative/qml/qmllistscriptclass.cpp index 441c410..d4cdc6e 100644 --- a/src/declarative/qml/qmllistscriptclass.cpp +++ b/src/declarative/qml/qmllistscriptclass.cpp @@ -49,7 +49,8 @@ QT_BEGIN_NAMESPACE struct ListData : public QScriptDeclarativeClass::Object { QmlGuard<QObject> object; int propertyIdx; - QmlListScriptClass::ListType type; + QmlListScriptClass::ListCategory type; + int propertyType; }; QmlListScriptClass::QmlListScriptClass(QmlEngine *e) @@ -65,7 +66,7 @@ QmlListScriptClass::~QmlListScriptClass() { } -QScriptValue QmlListScriptClass::newList(QObject *object, int propId, ListType type) +QScriptValue QmlListScriptClass::newList(QObject *object, int propId, ListCategory type, int propType) { QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine); @@ -76,6 +77,7 @@ QScriptValue QmlListScriptClass::newList(QObject *object, int propId, ListType t data->object = object; data->propertyIdx = propId; data->type = type; + data->propertyType = propType; return newObject(scriptEngine, this, data); } @@ -144,5 +146,28 @@ QmlListScriptClass::ScriptValue QmlListScriptClass::property(Object *obj, const } } +QVariant QmlListScriptClass::toVariant(Object *obj, bool *ok) +{ + ListData *data = (ListData *)obj; + + if (!data->object) { + if (ok) *ok = false; + return QVariant(); + } + + void *list = 0; + void *args[] = { &list, 0 }; + QMetaObject::metacall(data->object, QMetaObject::ReadProperty, + data->propertyIdx, args); + + if (!list) { + if (ok) *ok = false; + return QVariant(); + } + + if (ok) *ok = true; + return QVariant(data->propertyType, &list); +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qmllistscriptclass_p.h b/src/declarative/qml/qmllistscriptclass_p.h index 0c6c5b2..e484b34 100644 --- a/src/declarative/qml/qmllistscriptclass_p.h +++ b/src/declarative/qml/qmllistscriptclass_p.h @@ -64,13 +64,14 @@ public: QmlListScriptClass(QmlEngine *); ~QmlListScriptClass(); - enum ListType { QListPtr, QmlListPtr }; - QScriptValue newList(QObject *, int, ListType); + enum ListCategory { QListPtr, QmlListPtr }; + QScriptValue newList(QObject *, int, ListCategory, int); protected: virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &, QScriptClass::QueryFlags flags); virtual ScriptValue property(Object *, const Identifier &); + virtual QVariant toVariant(Object *, bool *ok); private: PersistentIdentifier m_lengthId; diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp index 4717782..0603a9c 100644 --- a/src/declarative/qml/qmlmetaproperty.cpp +++ b/src/declarative/qml/qmlmetaproperty.cpp @@ -51,6 +51,7 @@ #include "qmlengine.h" #include "qmlengine_p.h" #include "qmldeclarativedata_p.h" +#include "qmlstringconverters_p.h" #include <qfxperf_p_p.h> @@ -435,6 +436,17 @@ bool QmlMetaProperty::isDesignable() const } /*! + Returns true if the property is resettable, otherwise false. +*/ +bool QmlMetaProperty::isResettable() const +{ + if (type() & Property && d->core.isValid() && d->object) + return d->core.flags & QmlPropertyCache::Data::IsResettable; + else + return false; +} + +/*! Returns true if the QmlMetaProperty refers to a valid property, otherwise false. */ @@ -951,6 +963,14 @@ bool QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data void *a[] = { (void *)v.constData(), 0, &status, &flags}; QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); } + } else if (vt == QVariant::String) { + bool ok = false; + QVariant v = QmlStringConverters::variantFromString(value.toString(), t, &ok); + if (!ok) + return false; + + void *a[] = { (void *)v.constData(), 0, &status, &flags}; + QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); } else { return false; } @@ -967,6 +987,20 @@ bool QmlMetaProperty::write(const QVariant &value) const return write(value, 0); } +/*! + Resets the property value. +*/ +bool QmlMetaProperty::reset() const +{ + if (isResettable()) { + void *args[] = { 0 }; + QMetaObject::metacall(d->object, QMetaObject::ResetProperty, d->core.coreIndex, args); + return true; + } else { + return false; + } +} + bool QmlMetaProperty::write(const QVariant &value, QmlMetaProperty::WriteFlags flags) const { if (d->object && type() & Property && d->core.isValid() && isWritable()) diff --git a/src/declarative/qml/qmlmetaproperty.h b/src/declarative/qml/qmlmetaproperty.h index dcb5905..240f5a2 100644 --- a/src/declarative/qml/qmlmetaproperty.h +++ b/src/declarative/qml/qmlmetaproperty.h @@ -88,6 +88,7 @@ public: enum WriteFlag { BypassInterceptor = 0x01, DontRemoveBinding = 0x02 }; Q_DECLARE_FLAGS(WriteFlags, WriteFlag) bool write(const QVariant &, QmlMetaProperty::WriteFlags) const; + bool reset() const; bool hasChangedNotifier() const; bool needsChangedNotifier() const; @@ -108,6 +109,7 @@ public: bool isDefault() const; bool isWritable() const; bool isDesignable() const; + bool isResettable() const; bool isValid() const; QObject *object() const; diff --git a/src/declarative/qml/qmlobjectscriptclass.cpp b/src/declarative/qml/qmlobjectscriptclass.cpp index 86f0afc..5fd76c6 100644 --- a/src/declarative/qml/qmlobjectscriptclass.cpp +++ b/src/declarative/qml/qmlobjectscriptclass.cpp @@ -165,23 +165,25 @@ QmlObjectScriptClass::queryProperty(QObject *obj, const Identifier &name, if (lastData) return QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess; - if (!evalContext && context()) { - // Global object, QScriptContext activation object, QmlContext object - QScriptValue scopeNode = scopeChainValue(context(), -3); - Q_ASSERT(scopeNode.isValid()); - Q_ASSERT(scriptClass(scopeNode) == enginePrivate->contextClass); - - evalContext = enginePrivate->contextClass->contextFromValue(scopeNode); - } + if (!(hints & SkipAttachedProperties)) { + if (!evalContext && context()) { + // Global object, QScriptContext activation object, QmlContext object + QScriptValue scopeNode = scopeChainValue(context(), -3); + Q_ASSERT(scopeNode.isValid()); + Q_ASSERT(scriptClass(scopeNode) == enginePrivate->contextClass); + + evalContext = enginePrivate->contextClass->contextFromValue(scopeNode); + } - if (evalContext) { - QmlContextPrivate *cp = QmlContextPrivate::get(evalContext); + if (evalContext) { + QmlContextPrivate *cp = QmlContextPrivate::get(evalContext); - if (cp->imports) { - QmlTypeNameCache::Data *data = cp->imports->data(name); - if (data) { - lastTNData = data; - return QScriptClass::HandlesReadAccess; + if (cp->imports) { + QmlTypeNameCache::Data *data = cp->imports->data(name); + if (data) { + lastTNData = data; + return QScriptClass::HandlesReadAccess; + } } } } @@ -252,9 +254,9 @@ QmlObjectScriptClass::property(QObject *obj, const Identifier &name) } if (lastData->flags & QmlPropertyCache::Data::IsQList) { - return Value(scriptEngine, enginePriv->listClass->newList(obj, lastData->coreIndex, QmlListScriptClass::QListPtr)); + return Value(scriptEngine, enginePriv->listClass->newList(obj, lastData->coreIndex, QmlListScriptClass::QListPtr, lastData->propType)); } else if (lastData->flags & QmlPropertyCache::Data::IsQmlList) { - return Value(scriptEngine, enginePriv->listClass->newList(obj, lastData->coreIndex, QmlListScriptClass::QmlListPtr)); + return Value(scriptEngine, enginePriv->listClass->newList(obj, lastData->coreIndex, QmlListScriptClass::QmlListPtr, lastData->propType)); } else if (lastData->flags & QmlPropertyCache::Data::IsQObjectDerived) { QObject *rv = 0; void *args[] = { &rv, 0 }; @@ -352,12 +354,18 @@ void QmlObjectScriptClass::setProperty(QObject *obj, evalContext = enginePriv->contextClass->contextFromValue(scopeNode); } - // ### Can well known types be optimized? - QVariant v = QmlScriptClass::toVariant(engine, value); QmlAbstractBinding *delBinding = QmlMetaPropertyPrivate::setBinding(obj, *lastData, 0); if (delBinding) delBinding->destroy(); - QmlMetaPropertyPrivate::write(obj, *lastData, v, evalContext); + + if (value.isUndefined() && lastData->flags & QmlPropertyCache::Data::IsResettable) { + void *a[] = { 0 }; + QMetaObject::metacall(obj, QMetaObject::ResetProperty, lastData->coreIndex, a); + } else { + // ### Can well known types be optimized? + QVariant v = QmlScriptClass::toVariant(engine, value); + QmlMetaPropertyPrivate::write(obj, *lastData, v, evalContext); + } } bool QmlObjectScriptClass::isQObject() const diff --git a/src/declarative/qml/qmlobjectscriptclass_p.h b/src/declarative/qml/qmlobjectscriptclass_p.h index 36ba44f..ebb2c2a 100644 --- a/src/declarative/qml/qmlobjectscriptclass_p.h +++ b/src/declarative/qml/qmlobjectscriptclass_p.h @@ -136,6 +136,7 @@ private: QmlEngine *engine; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QmlObjectScriptClass::QueryHints); QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlpropertycache.cpp b/src/declarative/qml/qmlpropertycache.cpp index 77a3a47..51753b8 100644 --- a/src/declarative/qml/qmlpropertycache.cpp +++ b/src/declarative/qml/qmlpropertycache.cpp @@ -61,6 +61,8 @@ void QmlPropertyCache::Data::load(const QMetaProperty &p, QmlEngine *engine) flags |= Data::IsConstant; if (p.isWritable()) flags |= Data::IsWritable; + if (p.isResettable()) + flags |= Data::IsResettable; if (propType == qMetaTypeId<QmlBinding *>()) { flags |= Data::IsQmlBinding; diff --git a/src/declarative/qml/qmlpropertycache_p.h b/src/declarative/qml/qmlpropertycache_p.h index 8c3b75e..8d54e35 100644 --- a/src/declarative/qml/qmlpropertycache_p.h +++ b/src/declarative/qml/qmlpropertycache_p.h @@ -80,19 +80,20 @@ public: // Can apply to all properties, except IsFunction IsConstant = 0x00000001, IsWritable = 0x00000002, + IsResettable = 0x00000004, // These are mutualy exclusive - IsFunction = 0x00000004, - IsQObjectDerived = 0x00000008, - IsEnumType = 0x00000010, - IsQmlList = 0x00000020, - IsQList = 0x00000040, - IsQmlBinding = 0x00000080, - IsQScriptValue = 0x00000100, + IsFunction = 0x00000008, + IsQObjectDerived = 0x00000010, + IsEnumType = 0x00000020, + IsQmlList = 0x00000040, + IsQList = 0x00000080, + IsQmlBinding = 0x00000100, + IsQScriptValue = 0x00000200, // Apply only to IsFunctions - IsVMEFunction = 0x00000200, - HasArguments = 0x00000400 + IsVMEFunction = 0x00000400, + HasArguments = 0x00000800 }; Q_DECLARE_FLAGS(Flags, Flag) diff --git a/src/declarative/qml/qmlstringconverters.cpp b/src/declarative/qml/qmlstringconverters.cpp index c68654f..2963ab5 100644 --- a/src/declarative/qml/qmlstringconverters.cpp +++ b/src/declarative/qml/qmlstringconverters.cpp @@ -47,6 +47,7 @@ #include <QtCore/qrect.h> #include <QtCore/qsize.h> #include <QtCore/qvariant.h> +#include <QtCore/qdatetime.h> QT_BEGIN_NAMESPACE @@ -94,14 +95,43 @@ QVariant QmlStringConverters::variantFromString(const QString &s) if (ok) return QVariant(p); QSizeF sz = sizeFFromString(s, &ok); if (ok) return QVariant(sz); - bool b = boolFromString(s, &ok); - if (ok) return QVariant(b); QVector3D v = vector3DFromString(s, &ok); if (ok) return qVariantFromValue(v); return QVariant(s); } +QVariant QmlStringConverters::variantFromString(const QString &s, int preferredType, bool *ok) +{ + switch (preferredType) { + case QMetaType::QColor: + return QVariant::fromValue(colorFromString(s, ok)); + case QMetaType::QDate: + return QVariant::fromValue(dateFromString(s, ok)); + case QMetaType::QTime: + return QVariant::fromValue(timeFromString(s, ok)); + case QMetaType::QDateTime: + return QVariant::fromValue(dateTimeFromString(s, ok)); + case QMetaType::QPointF: + return QVariant::fromValue(pointFFromString(s, ok)); + case QMetaType::QPoint: + return QVariant::fromValue(pointFFromString(s, ok).toPoint()); + case QMetaType::QSizeF: + return QVariant::fromValue(sizeFFromString(s, ok)); + case QMetaType::QSize: + return QVariant::fromValue(sizeFFromString(s, ok).toSize()); + case QMetaType::QRectF: + return QVariant::fromValue(rectFFromString(s, ok)); + case QMetaType::QRect: + return QVariant::fromValue(rectFFromString(s, ok).toRect()); + case QMetaType::QVector3D: + return QVariant::fromValue(vector3DFromString(s, ok)); + default: + if (ok) *ok = false; + return QVariant(); + } +} + QColor QmlStringConverters::colorFromString(const QString &s, bool *ok) { if (s.startsWith(QLatin1Char('#')) && s.length() == 9) { @@ -120,6 +150,27 @@ QColor QmlStringConverters::colorFromString(const QString &s, bool *ok) } } +QDate QmlStringConverters::dateFromString(const QString &s, bool *ok) +{ + QDate d = QDate::fromString(s, Qt::ISODate); + if (ok) *ok = d.isValid(); + return d; +} + +QTime QmlStringConverters::timeFromString(const QString &s, bool *ok) +{ + QTime t = QTime::fromString(s, Qt::ISODate); + if (ok) *ok = t.isValid(); + return t; +} + +QDateTime QmlStringConverters::dateTimeFromString(const QString &s, bool *ok) +{ + QDateTime d = QDateTime::fromString(s, Qt::ISODate); + if (ok) *ok = d.isValid(); + return d; +} + //expects input of "x,y" QPointF QmlStringConverters::pointFFromString(const QString &s, bool *ok) { @@ -196,23 +247,6 @@ QRectF QmlStringConverters::rectFFromString(const QString &s, bool *ok) return QRectF(x, y, width, height); } -bool QmlStringConverters::boolFromString(const QString &str, bool *ok) -{ - if (str.isEmpty() || str == QLatin1String("false") || str == QLatin1String("0")) { - if (ok) - *ok = true; - return false; - } else if (str == QLatin1String("true") || str == QLatin1String("1")) { - if (ok) - *ok = true; - return true; - } - - if (ok) - *ok = false; - return true; -} - //expects input of "x,y,z" QVector3D QmlStringConverters::vector3DFromString(const QString &s, bool *ok) { diff --git a/src/declarative/qml/qmlstringconverters_p.h b/src/declarative/qml/qmlstringconverters_p.h index 380a904..dfc59ce 100644 --- a/src/declarative/qml/qmlstringconverters_p.h +++ b/src/declarative/qml/qmlstringconverters_p.h @@ -70,11 +70,15 @@ QT_BEGIN_NAMESPACE namespace QmlStringConverters { QVariant Q_DECLARATIVE_EXPORT variantFromString(const QString &); + QVariant Q_DECLARATIVE_EXPORT variantFromString(const QString &, int preferredType, bool *ok = 0); + QColor Q_DECLARATIVE_EXPORT colorFromString(const QString &, bool *ok = 0); + QDate Q_DECLARATIVE_EXPORT dateFromString(const QString &, bool *ok = 0); + QTime Q_DECLARATIVE_EXPORT timeFromString(const QString &, bool *ok = 0); + QDateTime Q_DECLARATIVE_EXPORT dateTimeFromString(const QString &, bool *ok = 0); QPointF Q_DECLARATIVE_EXPORT pointFFromString(const QString &, bool *ok = 0); QSizeF Q_DECLARATIVE_EXPORT sizeFFromString(const QString &, bool *ok = 0); QRectF Q_DECLARATIVE_EXPORT rectFFromString(const QString &, bool *ok = 0); - bool Q_DECLARATIVE_EXPORT boolFromString(const QString &, bool *ok = 0); QVector3D Q_DECLARATIVE_EXPORT vector3DFromString(const QString &, bool *ok = 0); }; diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp index 6b2e7af..e9a0449 100644 --- a/src/declarative/qml/qmlvme.cpp +++ b/src/declarative/qml/qmlvme.cpp @@ -57,7 +57,7 @@ #include "qmlvmemetaobject_p.h" #include "qmlbinding_p.h" #include "qmlcontext_p.h" -#include "qmlbindingoptimizations_p.h" +#include "qmlcompiledbindings_p.h" #include "qmlglobal_p.h" #include "qmlscriptstring.h" @@ -173,7 +173,7 @@ QObject *QmlVME::run(QmlVMEStack<QObject *> &stack, QmlContext *ctxt, if (instr.init.contextCache != -1) cp->setIdPropertyData(comp->contextCaches.at(instr.init.contextCache)); if (instr.init.compiledBinding != -1) - cp->optimizedBindings = new QmlOptimizedBindings(datas.at(instr.init.compiledBinding).constData(), ctxt); + cp->optimizedBindings = new QmlCompiledBindings(datas.at(instr.init.compiledBinding).constData(), ctxt); } break; diff --git a/src/declarative/util/qmlanimation.cpp b/src/declarative/util/qmlanimation.cpp index f5333a6..efb4159 100644 --- a/src/declarative/util/qmlanimation.cpp +++ b/src/declarative/util/qmlanimation.cpp @@ -1660,10 +1660,12 @@ void QmlPropertyAnimationPrivate::convertVariant(QVariant &variant, int type) \inherits Animation \brief The PropertyAnimation element allows you to animate property changes. - Animate a size property over 200ms, from its current size to 20-by-20: + Animate theObject's size property over 200ms, from its current size to 20-by-20: \code - PropertyAnimation { property: "size"; to: "20x20"; duration: 200 } + PropertyAnimation { target: theObject; property: "size"; to: "20x20"; duration: 200 } \endcode + + For an introduction to animation in QML, see \l{QML Animation}. */ QmlPropertyAnimation::QmlPropertyAnimation(QObject *parent) diff --git a/src/gui/dialogs/qdialog.cpp b/src/gui/dialogs/qdialog.cpp index 3650051..9ff2ad8 100644 --- a/src/gui/dialogs/qdialog.cpp +++ b/src/gui/dialogs/qdialog.cpp @@ -265,6 +265,14 @@ QDialog::QDialog(QWidget *parent, Qt::WindowFlags f) if (!qt_wince_is_smartphone()) setWindowFlags(windowFlags() | Qt::WindowOkButtonHint | QFlag(qt_wince_is_mobile() ? 0 : Qt::WindowCancelButtonHint)); #endif + +#ifdef Q_WS_S60 + if (S60->avkonComponentsSupportTransparency) { + bool noSystemBackground = testAttribute(Qt::WA_NoSystemBackground); + setAttribute(Qt::WA_TranslucentBackground); // also sets WA_NoSystemBackground + setAttribute(Qt::WA_NoSystemBackground, noSystemBackground); // restore system background attribute + } +#endif } #ifdef QT3_SUPPORT @@ -294,6 +302,14 @@ QDialog::QDialog(QDialogPrivate &dd, QWidget *parent, Qt::WindowFlags f) if (!qt_wince_is_smartphone()) setWindowFlags(windowFlags() | Qt::WindowOkButtonHint | QFlag(qt_wince_is_mobile() ? 0 : Qt::WindowCancelButtonHint)); #endif + +#ifdef Q_WS_S60 + if (S60->avkonComponentsSupportTransparency) { + bool noSystemBackground = testAttribute(Qt::WA_NoSystemBackground); + setAttribute(Qt::WA_TranslucentBackground); // also sets WA_NoSystemBackground + setAttribute(Qt::WA_NoSystemBackground, noSystemBackground); // restore system background attribute + } +#endif } /*! diff --git a/src/gui/dialogs/qprintpreviewdialog.cpp b/src/gui/dialogs/qprintpreviewdialog.cpp index 42be780..6723b53 100644 --- a/src/gui/dialogs/qprintpreviewdialog.cpp +++ b/src/gui/dialogs/qprintpreviewdialog.cpp @@ -207,6 +207,9 @@ public: QActionGroup *printerGroup; QAction *printAction; QAction *pageSetupAction; +#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA) + QAction *closeAction; +#endif QPointer<QObject> receiverToDisconnectOnClose; QByteArray memberToDisconnectOnClose; @@ -287,6 +290,9 @@ void QPrintPreviewDialogPrivate::init(QPrinter *_printer) toolbar->addSeparator(); toolbar->addAction(pageSetupAction); toolbar->addAction(printAction); +#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA) + toolbar->addAction(closeAction); +#endif // Cannot use the actions' triggered signal here, since it doesn't autorepeat QToolButton *zoomInButton = static_cast<QToolButton *>(toolbar->widgetForAction(zoomInAction)); @@ -406,6 +412,10 @@ void QPrintPreviewDialogPrivate::setupActions() qt_setupActionIcon(pageSetupAction, QLatin1String("page-setup")); QObject::connect(printAction, SIGNAL(triggered(bool)), q, SLOT(_q_print())); QObject::connect(pageSetupAction, SIGNAL(triggered(bool)), q, SLOT(_q_pageSetup())); +#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA) + closeAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Close")); + QObject::connect(closeAction, SIGNAL(triggered(bool)), q, SLOT(reject())); +#endif // Initial state: fitPageAction->setChecked(true); diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 616daaa..c53a893 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -798,8 +798,36 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch return; } - foreach (QGraphicsItem *child, children) - child->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false); + for (int i = 0; i < children.size(); ++i) + children.at(i)->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false); +} + +void QGraphicsItemPrivate::updateAncestorFlags() +{ + int flags = 0; + if (parent) { + // Inherit the parent's ancestor flags. + QGraphicsItemPrivate *pd = parent->d_ptr.data(); + flags = pd->ancestorFlags; + + // Add in flags from the parent. + if (pd->filtersDescendantEvents) + flags |= AncestorFiltersChildEvents; + if (pd->handlesChildEvents) + flags |= AncestorHandlesChildEvents; + if (pd->flags & QGraphicsItem::ItemClipsChildrenToShape) + flags |= AncestorClipsChildren; + if (pd->flags & QGraphicsItem::ItemIgnoresTransformations) + flags |= AncestorIgnoresTransformations; + } + + if (ancestorFlags == flags) + return; // No change; stop propagation. + ancestorFlags = flags; + + // Propagate to children recursively. + for (int i = 0; i < children.size(); ++i) + children.at(i)->d_ptr->updateAncestorFlags(); } /*! @@ -984,25 +1012,17 @@ QVariant QGraphicsItemPrivate::inputMethodQueryHelper(Qt::InputMethodQuery query prepareGeometryChange) if the item is in its destructor, i.e. inDestructor is 1. */ -void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) +void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const QVariant *newParentVariant, + const QVariant *thisPointerVariant) { Q_Q(QGraphicsItem); - if (newParent == q) { - qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this); - return; - } - if (newParent == parent) - return; - - const QVariant newParentVariant(q->itemChange(QGraphicsItem::ItemParentChange, - qVariantFromValue<QGraphicsItem *>(newParent))); - newParent = qVariantValue<QGraphicsItem *>(newParentVariant); if (newParent == parent) return; if (scene) { // Deliver the change to the index - scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParentVariant); + if (scene->d_func()->indexMethod != QGraphicsScene::NoIndex) + scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParent); // Disable scene pos notifications for old ancestors if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges)) @@ -1020,11 +1040,11 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) if (!inDestructor) q_ptr->prepareGeometryChange(); - const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(q)); if (parent) { // Remove from current parent parent->d_ptr->removeChild(q); - parent->itemChange(QGraphicsItem::ItemChildRemovedChange, thisPointerVariant); + if (thisPointerVariant) + parent->itemChange(QGraphicsItem::ItemChildRemovedChange, *thisPointerVariant); } // Update toplevelitem list. If this item is being deleted, its parent @@ -1042,7 +1062,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) QGraphicsItem *p = parent; QGraphicsItem *parentFocusScopeItem = 0; while (p) { - if (p->flags() & QGraphicsItem::ItemIsFocusScope) { + if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) { // If this item's focus scope's focus scope item points // to this item or a descendent, then clear it. QGraphicsItem *fsi = p->d_ptr->focusScopeItem; @@ -1055,6 +1075,10 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) p = p->d_ptr->parent; } + // Update graphics effect optimization flag + if (newParent && (graphicsEffect || mayHaveChildWithGraphicsEffect)) + newParent->d_ptr->updateChildWithGraphicsEffectFlagRecursively(); + // Update focus scope item ptr in new scope. QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem; if (newFocusScopeItem && newParent) { @@ -1063,11 +1087,11 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) QGraphicsItem *ancestorScope = 0; QGraphicsItem *p = subFocusItem->d_ptr->parent; while (p) { - if (p->flags() & QGraphicsItem::ItemIsFocusScope) + if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) ancestorScope = p; - if (p->isPanel()) + if (p->d_ptr->flags & QGraphicsItem::ItemIsPanel) break; - p = p->parentItem(); + p = p->d_ptr->parent; } if (ancestorScope) newFocusScopeItem = ancestorScope; @@ -1075,7 +1099,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) QGraphicsItem *p = newParent; while (p) { - if (p->flags() & QGraphicsItem::ItemIsFocusScope) { + if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) { p->d_ptr->focusScopeItem = newFocusScopeItem; // Ensure the new item is no longer the subFocusItem. The // only way to set focus on a child of a focus scope is @@ -1089,52 +1113,45 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) } if ((parent = newParent)) { - bool implicitUpdate = false; if (parent->d_func()->scene && parent->d_func()->scene != scene) { // Move this item to its new parent's scene parent->d_func()->scene->addItem(q); - implicitUpdate = true; } else if (!parent->d_func()->scene && scene) { // Remove this item from its former scene scene->removeItem(q); } parent->d_ptr->addChild(q); - parent->itemChange(QGraphicsItem::ItemChildAddedChange, thisPointerVariant); + if (thisPointerVariant) + parent->itemChange(QGraphicsItem::ItemChildAddedChange, *thisPointerVariant); if (scene) { - if (!implicitUpdate) - scene->d_func()->markDirty(q_ptr); - // Re-enable scene pos notifications for new ancestors if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges)) scene->d_func()->setScenePosItemEnabled(q, true); } + // Propagate dirty flags to the new parent + markParentDirty(/*updateBoundingRect=*/true); + // Inherit ancestor flags from the new parent. - updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2)); - updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1)); - updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape); - updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations); + updateAncestorFlags(); // Update item visible / enabled. - if (parent->isVisible() != visible) { - if (!parent->isVisible() || !explicitlyHidden) - setVisibleHelper(parent->isVisible(), /* explicit = */ false, /* update = */ !implicitUpdate); + if (parent->d_ptr->visible != visible) { + if (!parent->d_ptr->visible || !explicitlyHidden) + setVisibleHelper(parent->d_ptr->visible, /* explicit = */ false, /* update = */ false); } if (parent->isEnabled() != enabled) { - if (!parent->isEnabled() || !explicitlyDisabled) - setEnabledHelper(parent->isEnabled(), /* explicit = */ false, /* update = */ !implicitUpdate); + if (!parent->d_ptr->enabled || !explicitlyDisabled) + setEnabledHelper(parent->d_ptr->enabled, /* explicit = */ false, /* update = */ false); } // Auto-activate if visible and the parent is active. - if (q->isVisible() && parent->isActive()) + if (visible && parent->isActive()) q->setActive(true); } else { // Inherit ancestor flags from the new parent. - updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2)); - updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1)); - updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape); - updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations); + updateAncestorFlags(); if (!inDestructor) { // Update item visible / enabled. @@ -1142,10 +1159,6 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) setVisibleHelper(true, /* explicit = */ false); if (!enabled && !explicitlyDisabled) setEnabledHelper(true, /* explicit = */ false); - - // If the item is being deleted, the whole scene will be updated. - if (scene) - scene->d_func()->markDirty(q_ptr); } } @@ -1161,7 +1174,8 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) } // Deliver post-change notification - q->itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant); + if (newParentVariant) + q->itemChange(QGraphicsItem::ItemParentHasChanged, *newParentVariant); if (isObject) emit static_cast<QGraphicsObject *>(q)->parentChanged(); @@ -1351,7 +1365,7 @@ QGraphicsItem::~QGraphicsItem() d_ptr->scene->d_func()->removeItemHelper(this); } else { d_ptr->resetFocusProxy(); - d_ptr->setParentItemHelper(0); + setParentItem(0); } #ifndef QT_NO_GRAPHICSEFFECT @@ -1556,9 +1570,23 @@ const QGraphicsObject *QGraphicsItem::toGraphicsObject() const \sa parentItem(), childItems() */ -void QGraphicsItem::setParentItem(QGraphicsItem *parent) +void QGraphicsItem::setParentItem(QGraphicsItem *newParent) { - d_ptr->setParentItemHelper(parent); + if (newParent == this) { + qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this); + return; + } + if (newParent == d_ptr->parent) + return; + + const QVariant newParentVariant(itemChange(QGraphicsItem::ItemParentChange, + qVariantFromValue<QGraphicsItem *>(newParent))); + newParent = qVariantValue<QGraphicsItem *>(newParentVariant); + if (newParent == d_ptr->parent) + return; + + const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(this)); + d_ptr->setParentItemHelper(newParent, &newParentVariant, &thisPointerVariant); } /*! @@ -1608,7 +1636,7 @@ bool QGraphicsItem::isWidget() const */ bool QGraphicsItem::isWindow() const { - return isWidget() && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window); + return d_ptr->isWidget && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window); } /*! @@ -1645,9 +1673,9 @@ QGraphicsItem::GraphicsItemFlags QGraphicsItem::flags() const void QGraphicsItem::setFlag(GraphicsItemFlag flag, bool enabled) { if (enabled) - setFlags(flags() | flag); + setFlags(GraphicsItemFlags(d_ptr->flags) | flag); else - setFlags(flags() & ~flag); + setFlags(GraphicsItemFlags(d_ptr->flags) & ~flag); } /*! @@ -1694,8 +1722,8 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt()); if (quint32(d_ptr->flags) == quint32(flags)) return; - if (d_ptr->scene) - d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, quint32(flags)); + if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) + d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, &flags); // Flags that alter the geometry of the item (or its children). const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable); @@ -1704,7 +1732,7 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) d_ptr->paintedViewBoundingRectsNeedRepaint = 1; // Keep the old flags to compare the diff. - GraphicsItemFlags oldFlags = this->flags(); + GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags); // Update flags. d_ptr->flags = flags; @@ -1733,7 +1761,23 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) d_ptr->updateAncestorFlag(ItemIgnoresTransformations); } + if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) { + // NB! We change the flags directly here, so we must also update d_ptr->flags. + // Note that this has do be done before the ItemStacksBehindParent check + // below; otherwise we will loose the change. + + // Update stack-behind. + if (d_ptr->z < qreal(0.0)) + flags |= ItemStacksBehindParent; + else + flags &= ~ItemStacksBehindParent; + d_ptr->flags = flags; + } + if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) { + // NB! This check has to come after the ItemNegativeZStacksBehindParent + // check above. Be careful. + // Ensure child item sorting is up to date when toggling this flag. if (d_ptr->parent) d_ptr->parent->d_ptr->needSortChildren = 1; @@ -1747,10 +1791,6 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) d_ptr->scene->d_func()->updateInputMethodSensitivityInViews(); } - if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) { - // Update stack-behind. - setFlag(ItemStacksBehindParent, d_ptr->z < qreal(0.0)); - } if ((d_ptr->panelModality != NonModal) && d_ptr->scene @@ -2524,7 +2564,9 @@ void QGraphicsItem::setOpacity(qreal opacity) // Update. if (d_ptr->scene) { #ifndef QT_NO_GRAPHICSEFFECT - d_ptr->invalidateGraphicsEffectsRecursively(); + d_ptr->invalidateParentGraphicsEffectsRecursively(); + if (!(d_ptr->flags & ItemDoesntPropagateOpacityToChildren)) + d_ptr->invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::OpacityChanged); #endif //QT_NO_GRAPHICSEFFECT d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true, @@ -2569,6 +2611,8 @@ void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect) if (d_ptr->graphicsEffect) { delete d_ptr->graphicsEffect; d_ptr->graphicsEffect = 0; + } else if (d_ptr->parent) { + d_ptr->parent->d_ptr->updateChildWithGraphicsEffectFlagRecursively(); } if (effect) { @@ -2582,6 +2626,19 @@ void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect) } #endif //QT_NO_GRAPHICSEFFECT +void QGraphicsItemPrivate::updateChildWithGraphicsEffectFlagRecursively() +{ +#ifndef QT_NO_GRAPHICSEFFECT + QGraphicsItemPrivate *itemPrivate = this; + do { + // parent chain already notified? + if (itemPrivate->mayHaveChildWithGraphicsEffect) + return; + itemPrivate->mayHaveChildWithGraphicsEffect = 1; + } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0)); +#endif +} + /*! \internal \since 4.6 @@ -2998,9 +3055,16 @@ void QGraphicsItem::setActive(bool active) */ bool QGraphicsItem::hasFocus() const { + if (!d_ptr->scene || !d_ptr->scene->isActive()) + return false; + if (d_ptr->focusProxy) return d_ptr->focusProxy->hasFocus(); - return isActive() && (d_ptr->scene && d_ptr->scene->focusItem() == this); + + if (d_ptr->scene->d_func()->focusItem != this) + return false; + + return panel() == d_ptr->scene->d_func()->activePanel; } /*! @@ -4258,9 +4322,9 @@ void QGraphicsItem::setZValue(qreal z) if (newZ == d_ptr->z) return; - if (d_ptr->scene) { + if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) { // Z Value has changed, we have to notify the index. - d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, newZVariant); + d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, &newZ); } d_ptr->z = newZ; @@ -5027,7 +5091,7 @@ int QGraphicsItemPrivate::depth() const \internal */ #ifndef QT_NO_GRAPHICSEFFECT -void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively() +void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively() { QGraphicsItemPrivate *itemPrivate = this; do { @@ -5039,6 +5103,24 @@ void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively() } } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0)); } + +void QGraphicsItemPrivate::invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::InvalidateReason reason) +{ + if (!mayHaveChildWithGraphicsEffect) + return; + + for (int i = 0; i < children.size(); ++i) { + QGraphicsItemPrivate *childPrivate = children.at(i)->d_ptr.data(); + if (reason == OpacityChanged && (childPrivate->flags & QGraphicsItem::ItemIgnoresParentOpacity)) + continue; + if (childPrivate->graphicsEffect) { + childPrivate->notifyInvalidated = 1; + static_cast<QGraphicsItemEffectSourcePrivate *>(childPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache(); + } + + childPrivate->invalidateChildGraphicsEffectsRecursively(reason); + } +} #endif //QT_NO_GRAPHICSEFFECT /*! @@ -5283,7 +5365,7 @@ void QGraphicsItem::update(const QRectF &rect) // Make sure we notify effects about invalidated source. #ifndef QT_NO_GRAPHICSEFFECT - d_ptr->invalidateGraphicsEffectsRecursively(); + d_ptr->invalidateParentGraphicsEffectsRecursively(); #endif //QT_NO_GRAPHICSEFFECT if (CacheMode(d_ptr->cacheMode) != NoCache) { @@ -7176,19 +7258,7 @@ void QGraphicsItem::prepareGeometryChange() } } - QGraphicsItem *parent = this; - while ((parent = parent->d_ptr->parent)) { - QGraphicsItemPrivate *parentp = parent->d_ptr.data(); - parentp->dirtyChildrenBoundingRect = 1; - // ### Only do this if the parent's effect applies to the entire subtree. - parentp->notifyBoundingRectChanged = 1; -#ifndef QT_NO_GRAPHICSEFFECT - if (parentp->scene && parentp->graphicsEffect) { - parentp->notifyInvalidated = 1; - static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()->source->d_func())->invalidateCache(); - } -#endif - } + d_ptr->markParentDirty(/*updateBoundingRect=*/true); } /*! diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 2d34b80..5ad6cd5 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -153,7 +153,7 @@ public: dirtyChildren(0), localCollisionHack(0), inSetPosHelper(0), - needSortChildren(1), // ### can be 0 by default? + needSortChildren(0), allChildrenDirty(0), fullUpdatePending(0), flags(0), @@ -178,6 +178,8 @@ public: sequentialOrdering(1), updateDueToGraphicsEffect(0), scenePosDescendants(0), + pendingPolish(0), + mayHaveChildWithGraphicsEffect(0), globalStackingOrder(-1), q_ptr(0) { @@ -195,8 +197,10 @@ public: return item->d_ptr.data(); } + void updateChildWithGraphicsEffectFlagRecursively(); void updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag, AncestorFlag flag = NoFlag, bool enabled = false, bool root = true); + void updateAncestorFlags(); void setIsMemberOfGroup(bool enabled); void remapItemPos(QEvent *event, QGraphicsItem *item); QPointF genericMapFromScene(const QPointF &pos, const QWidget *viewport) const; @@ -223,13 +227,18 @@ public: bool ignoreDirtyBit = false, bool ignoreOpacity = false) const; int depth() const; #ifndef QT_NO_GRAPHICSEFFECT - void invalidateGraphicsEffectsRecursively(); + enum InvalidateReason { + OpacityChanged + }; + void invalidateParentGraphicsEffectsRecursively(); + void invalidateChildGraphicsEffectsRecursively(InvalidateReason reason); #endif //QT_NO_GRAPHICSEFFECT void invalidateDepthRecursively(); void resolveDepth(); void addChild(QGraphicsItem *child); void removeChild(QGraphicsItem *child); - void setParentItemHelper(QGraphicsItem *parent); + void setParentItemHelper(QGraphicsItem *parent, const QVariant *newParentVariant, + const QVariant *thisPointerVariant); void childrenBoundingRectHelper(QTransform *x, QRectF *rect); void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform, const QRegion &exposedRegion, bool allItems = false) const; @@ -397,6 +406,8 @@ public: return !visible || (childrenCombineOpacity() && isFullyTransparent()); } + inline void markParentDirty(bool updateBoundingRect = false); + void setFocusHelper(Qt::FocusReason focusReason, bool climb); void setSubFocus(QGraphicsItem *rootItem = 0); void clearSubFocus(QGraphicsItem *rootItem = 0); @@ -484,6 +495,8 @@ public: quint32 sequentialOrdering : 1; quint32 updateDueToGraphicsEffect : 1; quint32 scenePosDescendants : 1; + quint32 pendingPolish : 1; + quint32 mayHaveChildWithGraphicsEffect : 1; // Optional stacking order int globalStackingOrder; @@ -721,11 +734,13 @@ inline QTransform QGraphicsItemPrivate::transformToParent() const inline void QGraphicsItemPrivate::ensureSortedChildren() { if (needSortChildren) { - qSort(children.begin(), children.end(), qt_notclosestLeaf); needSortChildren = 0; sequentialOrdering = 1; + if (children.isEmpty()) + return; + qSort(children.begin(), children.end(), qt_notclosestLeaf); for (int i = 0; i < children.size(); ++i) { - if (children[i]->d_ptr->siblingIndex != i) { + if (children.at(i)->d_ptr->siblingIndex != i) { sequentialOrdering = 0; break; } @@ -741,6 +756,37 @@ inline bool QGraphicsItemPrivate::insertionOrder(QGraphicsItem *a, QGraphicsItem return a->d_ptr->siblingIndex < b->d_ptr->siblingIndex; } +/*! + \internal +*/ +inline void QGraphicsItemPrivate::markParentDirty(bool updateBoundingRect) +{ + QGraphicsItemPrivate *parentp = this; + while (parentp->parent) { + parentp = parentp->parent->d_ptr.data(); + parentp->dirtyChildren = 1; + + if (updateBoundingRect) { + parentp->dirtyChildrenBoundingRect = 1; + // ### Only do this if the parent's effect applies to the entire subtree. + parentp->notifyBoundingRectChanged = 1; + } +#ifndef QT_NO_GRAPHICSEFFECT + if (parentp->graphicsEffect) { + if (updateBoundingRect) { + parentp->notifyInvalidated = 1; + static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func() + ->source->d_func())->invalidateCache(); + } + if (parentp->graphicsEffect->isEnabled()) { + parentp->dirty = 1; + parentp->fullUpdatePending = 1; + } + } +#endif + } +} + QT_END_NAMESPACE #endif // QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index cea723c..9219773 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -292,7 +292,6 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() processDirtyItemsEmitted(false), selectionChanging(0), needSortTopLevelItems(true), - unpolishedItemsModified(true), holesInTopLevelSiblingIndex(false), topLevelSequentialOrdering(true), scenePosDescendantsUpdatePending(false), @@ -429,22 +428,38 @@ void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item) */ void QGraphicsScenePrivate::_q_polishItems() { - QSet<QGraphicsItem *>::Iterator it = unpolishedItems.begin(); + if (unpolishedItems.isEmpty()) + return; + const QVariant booleanTrueVariant(true); - while (!unpolishedItems.isEmpty()) { - QGraphicsItem *item = *it; - it = unpolishedItems.erase(it); - unpolishedItemsModified = false; - if (!item->d_ptr->explicitlyHidden) { + QGraphicsItem *item = 0; + QGraphicsItemPrivate *itemd = 0; + const int oldUnpolishedCount = unpolishedItems.count(); + + for (int i = 0; i < oldUnpolishedCount; ++i) { + item = unpolishedItems.at(i); + if (!item) + continue; + itemd = item->d_ptr.data(); + itemd->pendingPolish = false; + if (!itemd->explicitlyHidden) { item->itemChange(QGraphicsItem::ItemVisibleChange, booleanTrueVariant); item->itemChange(QGraphicsItem::ItemVisibleHasChanged, booleanTrueVariant); } - if (item->isWidget()) { + if (itemd->isWidget) { QEvent event(QEvent::Polish); QApplication::sendEvent((QGraphicsWidget *)item, &event); } - if (unpolishedItemsModified) - it = unpolishedItems.begin(); + } + + if (unpolishedItems.count() == oldUnpolishedCount) { + // No new items were added to the vector. + unpolishedItems.clear(); + } else { + // New items were appended; keep them and remove the old ones. + unpolishedItems.remove(0, oldUnpolishedCount); + unpolishedItems.squeeze(); + QMetaObject::invokeMethod(q_ptr, "_q_polishItems", Qt::QueuedConnection); } } @@ -599,7 +614,7 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) if (parentItem->scene()) { Q_ASSERT_X(parentItem->scene() == q, "QGraphicsScene::removeItem", "Parent item's scene is different from this item's scene"); - item->d_ptr->setParentItemHelper(0); + item->setParentItem(0); } } else { unregisterTopLevelItem(item); @@ -638,8 +653,12 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) selectedItems.remove(item); hoverItems.removeAll(item); cachedItemsUnderMouse.removeAll(item); - unpolishedItems.remove(item); - unpolishedItemsModified = true; + if (item->d_ptr->pendingPolish) { + const int unpolishedIndex = unpolishedItems.indexOf(item); + if (unpolishedIndex != -1) + unpolishedItems[unpolishedIndex] = 0; + item->d_ptr->pendingPolish = false; + } resetDirtyItem(item); //We remove all references of item from the sceneEventFilter arrays @@ -1936,7 +1955,7 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rectangle, Qt::ItemSe \since 4.3 This convenience function is equivalent to calling items(QRectF(\a x, \a y, \a w, \a h), \a mode). - + This function is deprecated and returns incorrect results if the scene contains items that ignore transformations. Use the overload that takes a QTransform instead. @@ -2482,12 +2501,12 @@ void QGraphicsScene::addItem(QGraphicsItem *item) qWarning("QGraphicsScene::addItem: cannot add null item"); return; } - if (item->scene() == this) { + if (item->d_ptr->scene == this) { qWarning("QGraphicsScene::addItem: item has already been added to this scene"); return; } // Remove this item from its existing scene - if (QGraphicsScene *oldScene = item->scene()) + if (QGraphicsScene *oldScene = item->d_ptr->scene) oldScene->removeItem(item); // Notify the item that its scene is changing, and allow the item to @@ -2496,15 +2515,20 @@ void QGraphicsScene::addItem(QGraphicsItem *item) qVariantFromValue<QGraphicsScene *>(this))); QGraphicsScene *targetScene = qVariantValue<QGraphicsScene *>(newSceneVariant); if (targetScene != this) { - if (targetScene && item->scene() != targetScene) + if (targetScene && item->d_ptr->scene != targetScene) targetScene->addItem(item); return; } + if (d->unpolishedItems.isEmpty()) + QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection); + d->unpolishedItems.append(item); + item->d_ptr->pendingPolish = true; + // Detach this item from its parent if the parent's scene is different // from this scene. - if (QGraphicsItem *itemParent = item->parentItem()) { - if (itemParent->scene() != this) + if (QGraphicsItem *itemParent = item->d_ptr->parent) { + if (itemParent->d_ptr->scene != this) item->setParentItem(0); } @@ -2534,7 +2558,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item) d->enableMouseTrackingOnViews(); } #ifndef QT_NO_CURSOR - if (d->allItemsUseDefaultCursor && item->hasCursor()) { + if (d->allItemsUseDefaultCursor && item->d_ptr->hasCursor) { d->allItemsUseDefaultCursor = false; if (d->allItemsIgnoreHoverEvents) // already enabled otherwise d->enableMouseTrackingOnViews(); @@ -2542,7 +2566,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item) #endif //QT_NO_CURSOR // Enable touch events if the item accepts touch events. - if (d->allItemsIgnoreTouchEvents && item->acceptTouchEvents()) { + if (d->allItemsIgnoreTouchEvents && item->d_ptr->acceptTouchEvents) { d->allItemsIgnoreTouchEvents = false; d->enableTouchEventsOnViews(); } @@ -2575,17 +2599,14 @@ void QGraphicsScene::addItem(QGraphicsItem *item) } // Add all children recursively - foreach (QGraphicsItem *child, item->children()) - addItem(child); + item->d_ptr->ensureSortedChildren(); + for (int i = 0; i < item->d_ptr->children.size(); ++i) + addItem(item->d_ptr->children.at(i)); // Resolve font and palette. item->d_ptr->resolveFont(d->font.resolve()); item->d_ptr->resolvePalette(d->palette.resolve()); - if (d->unpolishedItems.isEmpty()) - QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection); - d->unpolishedItems.insert(item); - d->unpolishedItemsModified = true; // Reenable selectionChanged() for individual items --d->selectionChanging; @@ -2619,7 +2640,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item) } } - if (item->flags() & QGraphicsItem::ItemSendsScenePositionChanges) + if (item->d_ptr->flags & QGraphicsItem::ItemSendsScenePositionChanges) d->registerScenePosItem(item); // Ensure that newly added items that have subfocus set, gain @@ -3766,10 +3787,10 @@ void QGraphicsScene::helpEvent(QGraphicsSceneHelpEvent *helpEvent) bool QGraphicsScenePrivate::itemAcceptsHoverEvents_helper(const QGraphicsItem *item) const { - return (!item->isBlockedByModalPanel() && - (item->acceptHoverEvents() - || (item->isWidget() - && static_cast<const QGraphicsWidget *>(item)->d_func()->hasDecoration()))); + return (item->d_ptr->acceptsHover + || (item->d_ptr->isWidget + && static_cast<const QGraphicsWidget *>(item)->d_func()->hasDecoration())) + && !item->isBlockedByModalPanel(); } /*! @@ -4882,17 +4903,7 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b if (ignoreOpacity) item->d_ptr->ignoreOpacity = 1; - QGraphicsItem *p = item->d_ptr->parent; - while (p) { - p->d_ptr->dirtyChildren = 1; -#ifndef QT_NO_GRAPHICSEFFECT - if (p->d_ptr->graphicsEffect && p->d_ptr->graphicsEffect->isEnabled()) { - p->d_ptr->dirty = 1; - p->d_ptr->fullUpdatePending = 1; - } -#endif //QT_NO_GRAPHICSEFFECT - p = p->d_ptr->parent; - } + item->d_ptr->markParentDirty(); } static inline bool updateHelper(QGraphicsViewPrivate *view, QGraphicsItemPrivate *item, diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index d10811c..54d8130 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -108,10 +108,9 @@ public: QPainterPath selectionArea; int selectionChanging; QSet<QGraphicsItem *> selectedItems; - QSet<QGraphicsItem *> unpolishedItems; + QVector<QGraphicsItem *> unpolishedItems; QList<QGraphicsItem *> topLevelItems; bool needSortTopLevelItems; - bool unpolishedItemsModified; bool holesInTopLevelSiblingIndex; bool topLevelSequentialOrdering; diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 2e92b87..2a91348 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -635,16 +635,17 @@ void QGraphicsSceneBspTreeIndex::updateSceneRect(const QRectF &rect) This method react to the \a change of the \a item and use the \a value to update the BSP tree if necessary. */ -void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) +void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const void *const value) { Q_D(QGraphicsSceneBspTreeIndex); switch (change) { case QGraphicsItem::ItemFlagsChange: { // Handle ItemIgnoresTransformations + QGraphicsItem::GraphicsItemFlags newFlags = *static_cast<const QGraphicsItem::GraphicsItemFlags *>(value); bool ignoredTransform = item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations; - bool willIgnoreTransform = value.toUInt() & QGraphicsItem::ItemIgnoresTransformations; + bool willIgnoreTransform = newFlags & QGraphicsItem::ItemIgnoresTransformations; bool clipsChildren = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape; - bool willClipChildren = value.toUInt() & QGraphicsItem::ItemClipsChildrenToShape; + bool willClipChildren = newFlags & QGraphicsItem::ItemClipsChildrenToShape; if ((ignoredTransform != willIgnoreTransform) || (clipsChildren != willClipChildren)) { QGraphicsItem *thatItem = const_cast<QGraphicsItem *>(item); // Remove item and its descendants from the index and append @@ -661,7 +662,7 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics case QGraphicsItem::ItemParentChange: { d->invalidateSortCache(); // Handle ItemIgnoresTransformations - QGraphicsItem *newParent = qVariantValue<QGraphicsItem *>(value); + const QGraphicsItem *newParent = static_cast<const QGraphicsItem *>(value); bool ignoredTransform = item->d_ptr->itemIsUntransformable(); bool willIgnoreTransform = (item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations) || (newParent && newParent->d_ptr->itemIsUntransformable()); @@ -682,7 +683,6 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics default: break; } - return QGraphicsSceneIndex::itemChange(item, change, value); } /*! \reimp diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 119571b..f671fd9 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -97,7 +97,7 @@ protected: void removeItem(QGraphicsItem *item); void prepareBoundingRectChange(const QGraphicsItem *item); - void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); + void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const void *const value); private : Q_DECLARE_PRIVATE(QGraphicsSceneBspTreeIndex) diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index bc8a7dc..043c4eb 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -624,7 +624,7 @@ void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item) \sa QGraphicsItem::GraphicsItemChange */ -void QGraphicsSceneIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) +void QGraphicsSceneIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const void *const value) { Q_UNUSED(item); Q_UNUSED(change); diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index def58f0..597a229 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -110,7 +110,7 @@ protected: virtual void removeItem(QGraphicsItem *item) = 0; virtual void deleteItem(QGraphicsItem *item); - virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value); + virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const void *const value); virtual void prepareBoundingRectChange(const QGraphicsItem *item); QGraphicsSceneIndex(QGraphicsSceneIndexPrivate &dd, QGraphicsScene *scene); diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp index 854be2e..42e19b8 100644 --- a/src/gui/image/qbmphandler.cpp +++ b/src/gui/image/qbmphandler.cpp @@ -144,7 +144,7 @@ static QDataStream &operator<<(QDataStream &s, const BMP_INFOHDR &bi) static int calc_shift(int mask) { int result = 0; - while (!(mask & 1)) { + while (mask && !(mask & 1)) { result++; mask >>= 1; } diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 674d5da..f823fdc 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -833,14 +833,21 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers if (QPixmapCache::find(key, *this)) return true; - QPixmapData *tmp = QPixmapData::create(0, 0, QPixmapData::PixmapType); - if (tmp->fromFile(fileName, format, flags)) { - data = tmp; - QPixmapCache::insert(key, *this); - return true; + bool ok; + + if (data) { + ok = data->fromFile(fileName, format, flags); + } else { + QScopedPointer<QPixmapData> tmp(QPixmapData::create(0, 0, QPixmapData::PixmapType)); + ok = tmp->fromFile(fileName, format, flags); + if (ok) + data = tmp.take(); } - delete tmp; - return false; + + if (ok) + QPixmapCache::insert(key, *this); + + return ok; } /*! diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h index 0b84e2f..f5034fc 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_p.h +++ b/src/gui/inputmethod/qcoefepinputcontext_p.h @@ -57,6 +57,7 @@ #include "qinputcontext.h" #include <qhash.h> +#include <qtimer.h> #include <private/qcore_symbian_p.h> #include <private/qt_s60_p.h> @@ -91,6 +92,9 @@ public: TCoeInputCapabilities inputCapabilities(); +protected: + void timerEvent(QTimerEvent *timerEvent); + private: void commitCurrentString(bool triggeredBySymbian); void updateHints(bool mustUpdateInputCapabilities); @@ -98,6 +102,7 @@ private: void applyFormat(QList<QInputMethodEvent::Attribute> *attributes); void queueInputCapabilitiesChanged(); bool needsInputPanel(); + void commitTemporaryPreeditString(); private Q_SLOTS: void ensureInputCapabilitiesChanged(); @@ -148,6 +153,8 @@ private: MFepPointerEventHandlerDuringInlineEdit *m_pointerHandler; int m_longPress; int m_cursorPos; + QBasicTimer m_tempPreeditStringTimeout; + bool m_hasTempPreeditString; }; QT_END_NAMESPACE diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index d2f207a..793bcde 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -72,7 +72,8 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent) m_formatRetriever(0), m_pointerHandler(0), m_longPress(0), - m_cursorPos(0) + m_cursorPos(0), + m_hasTempPreeditString(false) { m_fepState->SetObjectProvider(this); m_fepState->SetFlags(EAknEditorFlagDefault); @@ -100,6 +101,8 @@ QCoeFepInputContext::~QCoeFepInputContext() void QCoeFepInputContext::reset() { + commitTemporaryPreeditString(); + CCoeFep* fep = CCoeEnv::Static()->Fep(); if (fep) fep->CancelTransaction(); @@ -200,7 +203,11 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event) if (!focusWidget()) return false; - if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) { + switch (event->type()) { + case QEvent::KeyPress: + commitTemporaryPreeditString(); + // fall through intended + case QEvent::KeyRelease: const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event); switch (keyEvent->key()) { case Qt::Key_F20: @@ -223,6 +230,21 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event) default: break; } + + if (keyEvent->type() == QEvent::KeyPress + && focusWidget()->inputMethodHints() & Qt::ImhHiddenText + && !keyEvent->text().isEmpty()) { + // Send some temporary preedit text in order to make text visible for a moment. + m_preeditString = keyEvent->text(); + QList<QInputMethodEvent::Attribute> attributes; + QInputMethodEvent imEvent(m_preeditString, attributes); + QApplication::sendEvent(focusWidget(), &imEvent); + m_tempPreeditStringTimeout.start(1000, this); + m_hasTempPreeditString = true; + update(); + return true; + } + break; } if (!needsInputPanel()) @@ -253,6 +275,24 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event) return false; } +void QCoeFepInputContext::timerEvent(QTimerEvent *timerEvent) +{ + if (timerEvent->timerId() == m_tempPreeditStringTimeout.timerId()) + commitTemporaryPreeditString(); +} + +void QCoeFepInputContext::commitTemporaryPreeditString() +{ + if (m_tempPreeditStringTimeout.isActive()) + m_tempPreeditStringTimeout.stop(); + + if (!m_hasTempPreeditString) + return; + + commitCurrentString(false); + m_hasTempPreeditString = false; +} + void QCoeFepInputContext::mouseHandler( int x, QMouseEvent *event) { Q_ASSERT(focusWidget()); @@ -310,6 +350,8 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints) { using namespace Qt; + commitTemporaryPreeditString(); + bool numbersOnly = hints & ImhDigitsOnly || hints & ImhFormattedNumbersOnly || hints & ImhDialableCharactersOnly; bool noOnlys = !(numbersOnly || hints & ImhUppercaseOnly @@ -501,6 +543,8 @@ void QCoeFepInputContext::StartFepInlineEditL(const TDesC& aInitialInlineText, if (!w) return; + commitTemporaryPreeditString(); + m_cursorPos = w->inputMethodQuery(Qt::ImCursorPosition).toInt(); QList<QInputMethodEvent::Attribute> attributes; @@ -600,6 +644,8 @@ void QCoeFepInputContext::SetCursorSelectionForFepL(const TCursorSelection& aCur if (!w) return; + commitTemporaryPreeditString(); + int pos = aCursorSelection.iAnchorPos; int length = aCursorSelection.iCursorPos - pos; diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp index 7eefb0b..3111896 100644 --- a/src/gui/itemviews/qtableview.cpp +++ b/src/gui/itemviews/qtableview.cpp @@ -114,7 +114,9 @@ void QSpanCollection::updateSpan(QSpanCollection::Span *span, int old_height) } } else if (old_height > span->height()) { //remove the span from all the subspans lists that intersect the columns not covered anymore - Index::iterator it_y = index.lowerBound(qMin(-span->bottom(), 0)); + Index::iterator it_y = index.lowerBound(-span->bottom()); + if (it_y == index.end()) + it_y = index.find(-span->top()); // This is the only span remaining and we are deleting it. Q_ASSERT(it_y != index.end()); //it_y must exist since the span is in the list while (-it_y.key() <= span->top() + old_height -1) { if (-it_y.key() > span->bottom()) { diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 12fe797..4fe3900 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -121,8 +121,10 @@ extern bool qt_wince_is_pocket_pc(); //qguifunctions_wince.cpp static void initResources() { -#ifdef Q_WS_WINCE +#if defined(Q_WS_WINCE) Q_INIT_RESOURCE(qstyle_wince); +#elif defined(Q_OS_SYMBIAN) + Q_INIT_RESOURCE(qstyle_s60); #else Q_INIT_RESOURCE(qstyle); #endif diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index 6aebef5..e8b821af 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -227,8 +227,29 @@ void onApplicationChangedActivation( bool activated ); static void qt_mac_read_fontsmoothing_settings() { - NSInteger appleFontSmoothing = [[NSUserDefaults standardUserDefaults] integerForKey:@"AppleFontSmoothing"]; - qt_applefontsmoothing_enabled = (appleFontSmoothing > 0); + qt_applefontsmoothing_enabled = true; + int w = 10, h = 10; + QImage image(w, h, QImage::Format_RGB32); + image.fill(0xffffffff); + QPainter p(&image); + p.drawText(0, h, "X\\"); + p.end(); + + const int *bits = (const int *) ((const QImage &) image).bits(); + int bpl = image.bytesPerLine() / 4; + for (int y=0; y<w; ++y) { + for (int x=0; x<h; ++x) { + int r = qRed(bits[x]); + int g = qGreen(bits[x]); + int b = qBlue(bits[x]); + if (r != g || r != b) { + qt_applefontsmoothing_enabled = true; + return; + } + } + bits += bpl; + } + qt_applefontsmoothing_enabled = false; } Q_GUI_EXPORT bool qt_mac_execute_apple_script(const char *script, long script_len, AEDesc *ret) { @@ -772,11 +793,11 @@ static void qt_mac_update_intersected_gl_widgets(QWidget *widget) qt_post_window_change_event(glWidget); it->lastUpdateWidget = widget; } else if (it->lastUpdateWidget == widget) { - // Update the gl wigets that the widget intersected the last time around, - // and that we are not intersecting now. This prevents paint errors when the + // Update the gl wigets that the widget intersected the last time around, + // and that we are not intersecting now. This prevents paint errors when the // intersecting widget leaves a gl widget. qt_post_window_change_event(glWidget); - it->lastUpdateWidget = 0; + it->lastUpdateWidget = 0; } } #else @@ -808,8 +829,8 @@ Q_GUI_EXPORT void qt_event_request_window_change(QWidget *widget) // Post a kEventQtRequestWindowChange event. This event is semi-public, // don't remove this line! qt_event_request_window_change(); - - // Post update request on gl widgets unconditionally. + + // Post update request on gl widgets unconditionally. if (qt_widget_private(widget)->isGLWidget == true) { qt_post_window_change_event(widget); return; @@ -1214,8 +1235,6 @@ void qt_init(QApplicationPrivate *priv, int) if (QApplication::desktopSettingsAware()) QApplicationPrivate::qt_mac_apply_settings(); - qt_mac_read_fontsmoothing_settings(); - // Cocoa application delegate #ifdef QT_MAC_USE_COCOA NSApplication *cocoaApp = [NSApplication sharedApplication]; @@ -1253,6 +1272,7 @@ void qt_init(QApplicationPrivate *priv, int) } priv->native_modal_dialog_active = false; + qt_mac_read_fontsmoothing_settings(); } void qt_release_apple_event_handler() @@ -1705,7 +1725,7 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event // kEventMouseWheelMoved events if we dont eat this event // (actually two events; one for horizontal and one for vertical). // As a results of this, and to make sure we dont't receive duplicate events, - // we try to detect when this happend by checking the 'compatibilityEvent'. + // we try to detect when this happend by checking the 'compatibilityEvent'. SInt32 mdelt = 0; GetEventParameter(event, kEventParamMouseWheelSmoothHorizontalDelta, typeSInt32, 0, sizeof(mdelt), 0, &mdelt); @@ -2576,7 +2596,7 @@ void QApplicationPrivate::closePopup(QWidget *popup) if (QApplicationPrivate::popupWidgets->isEmpty()) { // this was the last popup delete QApplicationPrivate::popupWidgets; QApplicationPrivate::popupWidgets = 0; - + // Special case for Tool windows: since they are activated and deactived together // with a normal window they never become the QApplicationPrivate::active_window. QWidget *appFocusWidget = QApplication::focusWidget(); diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index f8943a8..9c001ab 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -501,9 +501,9 @@ public: static TUint resolveS60ScanCode(TInt scanCode, TUint keysym); QSet<WId> nativeWindows; - int symbianProcessWsEvent(const TWsEvent *event); - int symbianHandleCommand(int command); - int symbianResourceChange(int type); + int symbianProcessWsEvent(const QSymbianEvent *symbianEvent); + int symbianHandleCommand(const QSymbianEvent *symbianEvent); + int symbianResourceChange(const QSymbianEvent *symbianEvent); #endif #if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 8c77728..6caac9f 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -71,6 +71,7 @@ # include <private/qcoefepinputcontext_p.h> # endif # include <private/qs60mainapplication_p.h> +# include <centralrepository.h> #endif #include "private/qstylesheetstyle_p.h" @@ -1204,6 +1205,24 @@ void qt_init(QApplicationPrivate * /* priv */, int) S60->virtualMouseRequired = false; } + S60->avkonComponentsSupportTransparency = false; + +#ifdef Q_WS_S60 + TUid KCRUidAvkon = { 0x101F876E }; + TUint32 KAknAvkonTransparencyEnabled = 0x0000000D; + + CRepository* repository = 0; + TRAP(err, repository = CRepository::NewL(KCRUidAvkon)); + + if(err == KErrNone) { + TInt value = 0; + err = repository->Get(KAknAvkonTransparencyEnabled, value); + if(err == KErrNone) { + S60->avkonComponentsSupportTransparency = (value==1) ? true : false; + } + } +#endif + if (touch) { QApplicationPrivate::navigationMode = Qt::NavigationModeNone; } else { @@ -1528,6 +1547,12 @@ void QApplication::beep() qt_S60Beep->Play(); } +static inline bool callSymbianEventFilters(const QSymbianEvent *event) +{ + long unused; + return qApp->filterEvent(const_cast<QSymbianEvent *>(event), &unused); +} + /*! \warning This function is only available on Symbian. \since 4.6 @@ -1544,6 +1569,9 @@ int QApplication::symbianProcessEvent(const QSymbianEvent *event) QScopedLoopLevelCounter counter(d->threadData); + if (d->eventDispatcher->filterEvent(const_cast<QSymbianEvent *>(event))) + return 1; + QWidget *w = qApp ? qApp->focusWidget() : 0; if (w) { QInputContext *ic = w->inputContext(); @@ -1556,29 +1584,34 @@ int QApplication::symbianProcessEvent(const QSymbianEvent *event) switch (event->type()) { case QSymbianEvent::WindowServerEvent: - return d->symbianProcessWsEvent(event->windowServerEvent()); + return d->symbianProcessWsEvent(event); case QSymbianEvent::CommandEvent: - return d->symbianHandleCommand(event->command()); + return d->symbianHandleCommand(event); case QSymbianEvent::ResourceChangeEvent: - return d->symbianResourceChange(event->resourceChangeType()); + return d->symbianResourceChange(event); default: return -1; } } -int QApplicationPrivate::symbianProcessWsEvent(const TWsEvent *event) +int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent) { // Qt event handling. Handle some events regardless of if the handle is in our // widget map or not. + const TWsEvent *event = symbianEvent->windowServerEvent(); CCoeControl* control = reinterpret_cast<CCoeControl*>(event->Handle()); const bool controlInMap = QWidgetPrivate::mapper && QWidgetPrivate::mapper->contains(control); switch (event->Type()) { case EEventPointerEnter: - if (controlInMap) + if (controlInMap) { + callSymbianEventFilters(symbianEvent); return 1; // Qt::Enter will be generated in HandlePointerL + } break; case EEventPointerExit: if (controlInMap) { + if (callSymbianEventFilters(symbianEvent)) + return 1; if (S60) { // mouseEvent outside our window, send leave event to last focused widget QMouseEvent mEvent(QEvent::Leave, S60->lastPointerEventPos, S60->lastCursorPos, @@ -1591,6 +1624,8 @@ int QApplicationPrivate::symbianProcessWsEvent(const TWsEvent *event) } break; case EEventScreenDeviceChanged: + if (callSymbianEventFilters(symbianEvent)) + return 1; if (S60) S60->updateScreenSize(); if (qt_desktopWidget) { @@ -1603,6 +1638,8 @@ int QApplicationPrivate::symbianProcessWsEvent(const TWsEvent *event) return 0; // Propagate to CONE case EEventWindowVisibilityChanged: if (controlInMap) { + if (callSymbianEventFilters(symbianEvent)) + return 1; const TWsVisibilityChangedEvent *visChangedEvent = event->VisibilityChanged(); QWidget *w = QWidgetPrivate::mapper->value(control); if (!w->d_func()->maybeTopData()) @@ -1620,6 +1657,8 @@ int QApplicationPrivate::symbianProcessWsEvent(const TWsEvent *event) } break; case EEventFocusGained: + if (callSymbianEventFilters(symbianEvent)) + return 1; #ifndef QT_NO_CURSOR //re-enable mouse interaction if (S60->mouseInteractionEnabled) { @@ -1633,6 +1672,8 @@ int QApplicationPrivate::symbianProcessWsEvent(const TWsEvent *event) #endif break; case EEventFocusLost: + if (callSymbianEventFilters(symbianEvent)) + return 1; #ifndef QT_NO_CURSOR //disable mouse as may be moving to application that does not support it if (S60->mouseInteractionEnabled) { @@ -1684,11 +1725,16 @@ bool QApplication::symbianEventFilter(const QSymbianEvent *event) \sa s60EventFilter(), s60ProcessEvent() */ -int QApplicationPrivate::symbianHandleCommand(int command) +int QApplicationPrivate::symbianHandleCommand(const QSymbianEvent *symbianEvent) { Q_Q(QApplication); int ret = 0; + if (callSymbianEventFilters(symbianEvent)) + return 1; + + int command = symbianEvent->command(); + switch (command) { #ifdef Q_WS_S60 case EAknSoftkeyExit: { @@ -1728,14 +1774,18 @@ int QApplicationPrivate::symbianHandleCommand(int command) Currently, KEikDynamicLayoutVariantSwitch and KAknsMessageSkinChange are handled. */ -int QApplicationPrivate::symbianResourceChange(int type) +int QApplicationPrivate::symbianResourceChange(const QSymbianEvent *symbianEvent) { int ret = 0; + int type = symbianEvent->resourceChangeType(); + switch (type) { #ifdef Q_WS_S60 case KEikDynamicLayoutVariantSwitch: { + if (callSymbianEventFilters(symbianEvent)) + return 1; if (S60) S60->updateScreenSize(); @@ -1760,6 +1810,8 @@ int QApplicationPrivate::symbianResourceChange(int type) #ifndef QT_NO_STYLE_S60 case KAknsMessageSkinChange: + if (callSymbianEventFilters(symbianEvent)) + return 1; if (QS60Style *s60Style = qobject_cast<QS60Style*>(QApplication::style())) { s60Style->d_func()->handleSkinChange(); ret = 1; diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index c14798a..f61d2fe 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -510,7 +510,7 @@ extern "C" { } // Make sure the opengl context is updated on resize. - if (0 && qwidgetprivate->isGLWidget) { + if (qwidgetprivate->isGLWidget) { qwidgetprivate->needWindowChange = true; QEvent event(QEvent::MacGLWindowChange); qApp->sendEvent(qwidget, &event); diff --git a/src/gui/kernel/qformlayout.cpp b/src/gui/kernel/qformlayout.cpp index b44cd50..aebc3a5 100644 --- a/src/gui/kernel/qformlayout.cpp +++ b/src/gui/kernel/qformlayout.cpp @@ -1925,11 +1925,11 @@ void QFormLayoutPrivate::arrangeWidgets(const QVector<QLayoutStruct>& layouts, Q /* If the field on the right-hand side is tall, we want the label to be top-aligned, but not too - much. So we introduce a 5 / 4 factor so that it - gets a few extra pixels at the top. + much. So we introduce a 7 / 4 factor so that it + gets some extra pixels at the top. */ height = qMin(height, - qMin(label->sizeHint.height() * 5 / 4, + qMin(label->sizeHint.height() * 7 / 4, label->maxSize.height())); } diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index b417065..1163055 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -121,6 +121,7 @@ public: int virtualMouseRequired : 1; int qtOwnsS60Environment : 1; int supportsPremultipliedAlpha : 1; + int avkonComponentsSupportTransparency : 1; QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type static inline void updateScreenSize(); static inline RWsSession& wsSession(); diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 81a9a80..ede87de 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -2026,6 +2026,14 @@ void QWidgetPrivate::updateIsOpaque() } #endif +#ifdef Q_WS_S60 + if (q->windowType() == Qt::Dialog && q->testAttribute(Qt::WA_TranslucentBackground) + && S60->avkonComponentsSupportTransparency) { + setOpaque(false); + return; + } +#endif + if (q->testAttribute(Qt::WA_OpaquePaintEvent) || q->testAttribute(Qt::WA_PaintOnScreen)) { setOpaque(true); return; diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index b18830f..3dbc843 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -3414,6 +3414,38 @@ void QWidgetPrivate::hide_sys() ShowHide(window, false); #else [window orderOut:window]; + // Unfortunately it is not as easy as just hiding the window, we need + // to find out if we were in full screen mode. If we were and this is + // the last window in full screen mode then we need to unset the full screen + // mode. If this is not the last visible window in full screen mode then we + // don't change the full screen mode. + if(q->isFullScreen()) + { + bool keepFullScreen = false; + QWidgetList windowList = qApp->topLevelWidgets(); + int windowCount = windowList.count(); + for(int i = 0; i < windowCount; i++) + { + QWidget *w = windowList[i]; + // If it is the same window, we don't need to check :-) + if(q == w) + continue; + // If they are not visible or if they are minimized then + // we just ignore them. + if(!w->isVisible() || w->isMinimized()) + continue; + // Is it full screen? + // Notice that if there is one window in full screen mode then we + // cannot switch the full screen mode off, therefore we just abort. + if(w->isFullScreen()) { + keepFullScreen = true; + break; + } + } + // No windows in full screen mode, so let just unset that flag. + if(!keepFullScreen) + qt_mac_set_fullscreen_mode(false); + } #endif toggleDrawers(false); #ifndef QT_MAC_USE_COCOA diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index f51dc36..d6d288e 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -934,8 +934,7 @@ void QColor::setRgb(int r, int g, int b, int a) /*! \fn QRgb QColor::rgba() const - Returns the RGB value of the color. Unlike rgb(), the alpha is not - stripped. + Returns the RGB value of the color, including its alpha. For an invalid color, the alpha value of the returned color is unspecified. @@ -950,8 +949,7 @@ QRgb QColor::rgba() const } /*! - Sets the RGBA value to \a rgba. Unlike setRgb(QRgb rgb), this function does - not ignore the alpha. + Sets the RGB value to \a rgba, including its alpha. \sa rgba(), rgb() */ @@ -968,8 +966,7 @@ void QColor::setRgba(QRgb rgba) /*! \fn QRgb QColor::rgb() const - Returns the RGB value of the color. The alpha is stripped for - compatibility. + Returns the RGB value of the color. The alpha value is opaque. \sa getRgb(), rgba() */ @@ -983,7 +980,7 @@ QRgb QColor::rgb() const /*! \overload - Sets the RGB value to \a rgb, ignoring the alpha. + Sets the RGB value to \a rgb. The alpha value is set to opaque. */ void QColor::setRgb(QRgb rgb) { diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index b937f66..a1c73cc 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -264,13 +264,13 @@ private: #endif // Q_OS_SYMBIAN && QT_NO_FREETYPE inline void ensureBrush(const QBrush &brush) { - if (!qbrush_fast_equals(state()->lastBrush, brush) || state()->fillFlags) + if (!qbrush_fast_equals(state()->lastBrush, brush) || (brush.style() != Qt::NoBrush && state()->fillFlags)) updateBrush(brush); } inline void ensureBrush() { ensureBrush(state()->brush); } inline void ensurePen(const QPen &pen) { - if (!qpen_fast_equals(state()->lastPen, pen) || state()->strokeFlags) + if (!qpen_fast_equals(state()->lastPen, pen) || (pen.style() != Qt::NoPen && state()->strokeFlags)) updatePen(pen); } inline void ensurePen() { ensurePen(state()->pen); } diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index a9dcea0..cde6a2d 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -1374,9 +1374,6 @@ void QPainterPrivate::updateState(QPainterState *newState) opacity with non-smooth transformation mode (\c QPainter::SmoothPixmapTransform not enabled as a render hint). - \o Text drawing with regular font sizes with simple - transformations with solid colors using no or 8-bit antialiasing. - \o Rectangle fills with solid color, two-color linear gradients and simple transforms. @@ -7385,10 +7382,15 @@ struct QPaintDeviceRedirection typedef QList<QPaintDeviceRedirection> QPaintDeviceRedirectionList; Q_GLOBAL_STATIC(QPaintDeviceRedirectionList, globalRedirections) Q_GLOBAL_STATIC(QMutex, globalRedirectionsMutex) +Q_GLOBAL_STATIC(QAtomicInt, globalRedirectionAtomic) /*! \threadsafe + \obsolete + + Please use QWidget::render() instead. + Redirects all paint commands for the given paint \a device, to the \a replacement device. The optional point \a offset defines an offset within the source device. @@ -7398,9 +7400,10 @@ Q_GLOBAL_STATIC(QMutex, globalRedirectionsMutex) device's painter (if any) before redirecting. Call restoreRedirected() to restore the previous redirection. - In general, you'll probably find that calling - QPixmap::grabWidget() or QPixmap::grabWindow() is an easier - solution. + \warning Making use of redirections in the QPainter API implies + that QPainter::begin() and QPaintDevice destructors need to hold + a mutex for a short period. This can impact performance. Use of + QWidget::render is strongly encouraged. \sa redirected(), restoreRedirected() */ @@ -7432,14 +7435,24 @@ void QPainter::setRedirected(const QPaintDevice *device, Q_ASSERT(redirections != 0); *redirections += QPaintDeviceRedirection(device, rdev ? rdev : replacement, offset + roffset, hadInternalWidgetRedirection ? redirections->size() - 1 : -1); + globalRedirectionAtomic()->ref(); } /*! \threadsafe + \obsolete + + Using QWidget::render() obsoletes the use of this function. + Restores the previous redirection for the given \a device after a call to setRedirected(). + \warning Making use of redirections in the QPainter API implies + that QPainter::begin() and QPaintDevice destructors need to hold + a mutex for a short period. This can impact performance. Use of + QWidget::render is strongly encouraged. + \sa redirected() */ void QPainter::restoreRedirected(const QPaintDevice *device) @@ -7450,6 +7463,7 @@ void QPainter::restoreRedirected(const QPaintDevice *device) Q_ASSERT(redirections != 0); for (int i = redirections->size()-1; i >= 0; --i) { if (redirections->at(i) == device) { + globalRedirectionAtomic()->deref(); const int internalWidgetRedirectionIndex = redirections->at(i).internalWidgetRedirectionIndex; redirections->removeAt(i); // Restore the internal widget redirection, i.e. remove it from the global @@ -7471,9 +7485,18 @@ void QPainter::restoreRedirected(const QPaintDevice *device) /*! \threadsafe + \obsolete + + Using QWidget::render() obsoletes the use of this function. + Returns the replacement for given \a device. The optional out parameter \a offset returns the offset within the replaced device. + \warning Making use of redirections in the QPainter API implies + that QPainter::begin() and QPaintDevice destructors need to hold + a mutex for a short period. This can impact performance. Use of + QWidget::render is strongly encouraged. + \sa setRedirected(), restoreRedirected() */ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset) @@ -7486,6 +7509,9 @@ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset) return widgetPrivate->redirected(offset); } + if (*globalRedirectionAtomic() == 0) + return 0; + QMutexLocker locker(globalRedirectionsMutex()); QPaintDeviceRedirectionList *redirections = globalRedirections(); Q_ASSERT(redirections != 0); @@ -7503,6 +7529,9 @@ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset) void qt_painter_removePaintDevice(QPaintDevice *dev) { + if (*globalRedirectionAtomic() == 0) + return; + QMutex *mutex = 0; QT_TRY { mutex = globalRedirectionsMutex(); diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 211f4ce..b5f052b 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -1106,8 +1106,14 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, // ### Note: Ubuntulooks breaks when the proper widget is passed // Murrine engine requires a widget not to get RGBA check - warnings GtkWidget *gtkCheckButton = d->gtkWidget(QLS("GtkCheckButton")); - gtkPainter.paintOption(gtkCheckButton , buttonRect, state, shadow, gtkRadioButton->style, QLS("radiobutton")); - + QString key(QLS("radiobutton")); + if (option->state & State_HasFocus) { // Themes such as Nodoka check this flag + key += QLatin1Char('f'); + GTK_WIDGET_SET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS); + } + gtkPainter.paintOption(gtkCheckButton , buttonRect, state, shadow, gtkRadioButton->style, key); + if (option->state & State_HasFocus) + GTK_WIDGET_UNSET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS); } break; @@ -1128,6 +1134,11 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, int spacing; GtkWidget *gtkCheckButton = d->gtkWidget(QLS("GtkCheckButton")); + QString key(QLS("checkbutton")); + if (option->state & State_HasFocus) { // Themes such as Nodoka checks this flag + key += QLatin1Char('f'); + GTK_WIDGET_SET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS); + } // Some styles such as aero-clone assume they can paint in the spacing area gtkPainter.setClipRect(option->rect); @@ -1137,7 +1148,10 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, QRect checkRect = option->rect.adjusted(spacing, spacing, -spacing, -spacing); gtkPainter.paintCheckbox(gtkCheckButton, checkRect, state, shadow, gtkCheckButton->style, - QLS("checkbutton")); + key); + if (option->state & State_HasFocus) + GTK_WIDGET_UNSET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS); + } break; diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index ca0b8c7..ecb3242 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -68,6 +68,10 @@ #include "qtoolbutton.h" #include "qfocusframe.h" #include "qformlayout.h" +#include "qradiobutton.h" +#include "qcheckbox.h" +#include "qdesktopwidget.h" +#include "qprogressbar.h" #include "private/qtoolbarextension_p.h" #include "private/qcombobox_p.h" @@ -564,9 +568,11 @@ QPixmap QS60StylePrivate::cachedPart(QS60StyleEnums::SkinParts part, const QSize &size, QPainter *painter, SkinElementFlags flags) { QPixmap result; + const int animationFrame = (flags & SF_Animation) ? currentAnimationFrame(part) : 0; + const QString cacheKey = - QString::fromLatin1("S60Style: SkinParts=%1 QSize=%2|%3 SkinPartFlags=%4") - .arg((int)part).arg(size.width()).arg(size.height()).arg((int)flags); + QString::fromLatin1("S60Style: SkinParts=%1 QSize=%2|%3 SkinPartFlags=%4 AnimationFrame=%5") + .arg((int)part).arg(size.width()).arg(size.height()).arg((int)flags).arg(animationFrame); if (!QPixmapCache::find(cacheKey, result)) { result = QS60StylePrivate::part(part, size, painter, flags); QPixmapCache::insert(cacheKey, result); @@ -672,8 +678,7 @@ void QS60StylePrivate::setThemePalette(QPalette *palette) const s60Color(QS60StyleEnums::CL_QsnHighlightColors, 2, 0)); // set background image as a texture brush palette->setBrush(QPalette::Window, backgroundTexture()); - // set these as transparent so that styled full screen theme background is visible - palette->setColor(QPalette::AlternateBase, Qt::transparent); + // set as transparent so that styled full screen theme background is visible palette->setBrush(QPalette::Base, Qt::transparent); // set button and tooltipbase based on pixel colors const QColor buttonColor = colorFromFrameGraphics(SF_ButtonNormal); @@ -685,6 +690,9 @@ void QS60StylePrivate::setThemePalette(QPalette *palette) const palette->setColor(QPalette::Midlight, palette->color(QPalette::Button).lighter(125)); palette->setColor(QPalette::Mid, palette->color(QPalette::Button).darker(150)); palette->setColor(QPalette::Shadow, Qt::black); + QColor alternateBase = palette->light().color(); + alternateBase.setAlphaF(0.8); + palette->setColor(QPalette::AlternateBase, alternateBase); QApplication::setPalette(*palette); //calling QApplication::setPalette clears palette hash setThemePaletteHash(palette); @@ -775,6 +783,11 @@ void QS60StylePrivate::setThemePaletteHash(QPalette *palette) const QApplication::setPalette(widgetPalette, "QComboBox"); widgetPalette = *palette; + widgetPalette.setColor(QPalette::WindowText, s60Color(QS60StyleEnums::CL_QsnTextColors, 7, 0)); + QApplication::setPalette(widgetPalette, "QRadioButton"); + QApplication::setPalette(widgetPalette, "QCheckBox"); + widgetPalette = *palette; + widgetPalette.setColor(QPalette::WindowText, mainAreaTextColor); widgetPalette.setColor(QPalette::Button, QApplication::palette().color(QPalette::Button)); widgetPalette.setColor(QPalette::Dark, mainAreaTextColor.darker()); @@ -813,13 +826,13 @@ 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_QgnGrafNsliderEndLeft: case QS60StyleEnums::SP_QgnGrafNsliderEndRight: case QS60StyleEnums::SP_QgnGrafNsliderMiddle: result.setWidth(result.height() >> 1); break; - + case QS60StyleEnums::SP_QgnGrafNsliderMarker: case QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected: result.scale(pixelMetric(QStyle::PM_SliderLength), @@ -922,10 +935,10 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom horizontal ? QS60StylePrivate::SE_ScrollBarGrooveHorizontal : QS60StylePrivate::SE_ScrollBarGrooveVertical; QS60StylePrivate::drawSkinElement(grooveElement, painter, grooveRect, flags); - const QStyle::SubControls subControls = optionSlider->subControls; + const SubControls subControls = optionSlider->subControls; // select correct slider (horizontal/vertical/pressed) - const bool sliderPressed = ((optionSlider->state & QStyle::State_Sunken) && (subControls & SC_ScrollBarSlider)); + const bool sliderPressed = ((optionSlider->state & State_Sunken) && (subControls & SC_ScrollBarSlider)); const QS60StylePrivate::SkinElements handleElement = horizontal ? ( sliderPressed ? @@ -946,13 +959,13 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom const bool horizontal = optionSlider->orientation == Qt::Horizontal; //Highlight -/* if (optionSlider->state & QStyle::State_HasFocus) +/* if (optionSlider->state & State_HasFocus) drawPrimitive(PE_FrameFocusRect, optionSlider, painter, widget);*/ - + //Groove graphics if (QS60StylePrivate::hasSliderGrooveGraphic()) { - const QS60StylePrivate::SkinElements grooveElement = horizontal ? - QS60StylePrivate::SE_SliderGrooveHorizontal : + const QS60StylePrivate::SkinElements grooveElement = horizontal ? + QS60StylePrivate::SE_SliderGrooveHorizontal : QS60StylePrivate::SE_SliderGrooveVertical; QS60StylePrivate::drawSkinElement(grooveElement, painter, sliderGroove, flags); } else { @@ -975,7 +988,7 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom if (optionSlider->state & QStyle::State_Sunken) handleElement = horizontal ? QS60StylePrivate::SE_SliderHandleSelectedHorizontal : QS60StylePrivate::SE_SliderHandleSelectedVertical; - else + else handleElement = horizontal ? QS60StylePrivate::SE_SliderHandleHorizontal : QS60StylePrivate::SE_SliderHandleVertical; QS60StylePrivate::drawSkinElement(handleElement, painter, sliderHandle, flags); @@ -994,7 +1007,7 @@ 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 ? + const int topLeftPoint = direction ? (cmbxEditField.right() + 1) : (cmbxEditField.left() + 1 - maxWidth); const QRect buttonRect(topLeftPoint, cmbxEditField.top(), maxWidth, maxHeight); buttonOption.rect = buttonRect; @@ -1020,102 +1033,62 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom #ifndef QT_NO_TOOLBUTTON case CC_ToolButton: if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(option)) { - const State bflags = toolBtn->state; + State bflags = toolBtn->state & ~State_Sunken; + + if (bflags & State_AutoRaise) { + if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) { + bflags &= ~State_Raised; + } + } + State mflags = bflags; + if (toolBtn->state & State_Sunken) { + if (toolBtn->activeSubControls & SC_ToolButton) + bflags |= State_Sunken; + mflags |= State_Sunken; + } + const QRect button(subControlRect(control, toolBtn, SC_ToolButton, widget)); QRect menuRect = QRect(); if (toolBtn->subControls & SC_ToolButtonMenu) menuRect = subControlRect(control, toolBtn, SC_ToolButtonMenu, widget); - QStyleOptionToolButton toolButton = *toolBtn; - - if (sub&SC_ToolButton) { + if (toolBtn->subControls & SC_ToolButton) { QStyleOption tool(0); tool.palette = toolBtn->palette; - // Check if toolbutton is in toolbar. - QToolBar *toolBar = 0; - if (widget) - toolBar = qobject_cast<QToolBar *>(widget->parentWidget()); - - if (bflags & (State_Sunken | State_On | State_Raised)) { + if (bflags & (State_Sunken | State_On | State_Raised | State_Enabled)) { tool.rect = button.unite(menuRect); tool.state = bflags; - - // todo: I'd like to move extension button next to where last button is - // however, the painter seems to want to clip the button rect even if I turn of the clipping. - if (toolBar && (qobject_cast<const QToolBarExtension *>(widget))){ - /*QList<QAction *> actionList = toolBar->actions(); - const int actionCount = actionList.count(); - const int toolbarWidth = toolBar->width(); - const int extButtonWidth = pixelMetric(PM_ToolBarExtensionExtent, option, widget); - const int toolBarButtonWidth = pixelMetric(PM_ToolBarIconSize, option, widget); - const int frame = pixelMetric(PM_ToolBarFrameWidth, option, widget); - const int margin = pixelMetric(PM_ToolBarItemMargin, option, widget); - const int border = frame + margin; - const int spacing = pixelMetric(PM_ToolBarItemSpacing, option, widget); - const int toolBarButtonArea = toolbarWidth - extButtonWidth - spacing - 2*border; - const int numberOfVisibleButtons = toolBarButtonArea / toolBarButtonWidth; - // new extension button place is after border and all the other visible buttons (with spacings) - const int newXForExtensionButton = numberOfVisibleButtons * toolBarButtonWidth + (numberOfVisibleButtons-1)*spacing + border; - painter->save(); - painter->setClipping(false); - tool.rect.translate(-newXForExtensionButton,0); - painter->restore();*/ - } - - if (toolBar){ - /*if (toolBar->orientation() == Qt::Vertical){ - // todo: I'd like to make all vertical buttons the same size, but again the painter - // prefers to use clipping for button rects, even though clipping has been set off. - painter->save(); - painter->setClipping(false); - - const int origWidth = tool.rect.width(); - const int newWidth = toolBar->width()-2*pixelMetric(PM_ToolBarFrameWidth, option, widget); - painter->translate(origWidth-newWidth,0); - tool.rect.translate(origWidth-tool.rect.width(),0); - tool.rect.setWidth(newWidth); - - if (option->state & QStyle::State_Sunken) - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButtonPressed, painter, tool.rect, flags); - else - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButton, painter, tool.rect, flags); - - }*/ - if (option->state & QStyle::State_Sunken) - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButtonPressed, painter, tool.rect, flags); - else - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButton, painter, tool.rect, flags); - /* - if (toolBar->orientation() == Qt::Vertical) - painter->restore(); - */ - } else { - drawPrimitive(PE_PanelButtonTool, &tool, painter, widget); - } - - if (toolButton.subControls & SC_ToolButtonMenu) { - tool.rect = menuRect; - tool.state = bflags; - drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget); - } + const QToolButton *toolButtonWidget = qobject_cast<const QToolButton *>(widget); + QS60StylePrivate::SkinElements element; + if (toolButtonWidget) + element = (toolButtonWidget->isDown()) ? QS60StylePrivate::SE_ToolBarButtonPressed : QS60StylePrivate::SE_ToolBarButton; + else + element = (option->state & State_Sunken) ? QS60StylePrivate::SE_ToolBarButtonPressed : QS60StylePrivate::SE_ToolBarButton; + QS60StylePrivate::drawSkinElement(element, painter, tool.rect, flags); + drawPrimitive(PE_PanelButtonTool, &tool, painter, widget); + } + if (toolBtn->subControls & SC_ToolButtonMenu) { + tool.rect = menuRect; + tool.state = mflags; + drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget); } } - + QStyleOptionToolButton toolButton = *toolBtn; if (toolBtn->features & QStyleOptionToolButton::Arrow) { - QStyle::PrimitiveElement pe; + PrimitiveElement pe; switch (toolBtn->arrowType) { case Qt::LeftArrow: - pe = QStyle::PE_IndicatorArrowLeft; + pe = PE_IndicatorArrowLeft; break; case Qt::RightArrow: - pe = QStyle::PE_IndicatorArrowRight; + pe = PE_IndicatorArrowRight; break; case Qt::UpArrow: - pe = QStyle::PE_IndicatorArrowUp; + pe = PE_IndicatorArrowUp; break; case Qt::DownArrow: - pe = QStyle::PE_IndicatorArrowDown; + pe = PE_IndicatorArrowDown; break; default: break; } @@ -1199,7 +1172,7 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom // Draw frame const QRect textRect = subControlRect(CC_GroupBox, option, SC_GroupBoxLabel, widget); const QRect checkBoxRect = subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget); - if (groupBox->subControls & QStyle::SC_GroupBoxFrame) { + if (groupBox->subControls & SC_GroupBoxFrame) { QStyleOptionFrameV2 frame; frame.QStyleOption::operator=(*groupBox); frame.features = groupBox->features; @@ -1210,14 +1183,14 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom } // Draw title - if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) { + if ((groupBox->subControls & SC_GroupBoxLabel) && !groupBox->text.isEmpty()) { const QColor textColor = groupBox->textColor; painter->save(); if (textColor.isValid()) painter->setPen(textColor); int alignment = int(groupBox->textAlignment); - if (!styleHint(QStyle::SH_UnderlineShortcut, option, widget)) + if (!styleHint(SH_UnderlineShortcut, option, widget)) alignment |= Qt::TextHideMnemonic; drawItemText(painter, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | Qt::AlignVCenter | alignment, @@ -1249,6 +1222,31 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, Q_D(const QS60Style); const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ? QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled; switch (element) { + case CE_CheckBox: + case CE_RadioButton: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { + bool isRadio = (element == CE_RadioButton); + // Highlight needs to be drawn first, as it goes "underneath" the text and indicator. + if (btn->state & State_HasFocus) { + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*btn); + fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect + : SE_CheckBoxFocusRect, btn, widget); + drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); + } + QStyleOptionButton subopt = *btn; + + subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator + : SE_CheckBoxIndicator, btn, widget); + drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox, + &subopt, painter, widget); + subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents + : SE_CheckBoxContents, btn, widget); + + drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, painter, widget); + } + break; + case CE_PushButton: if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { @@ -1261,13 +1259,13 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, break; case CE_PushButtonBevel: if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) { - const bool isDisabled = !(option->state & QStyle::State_Enabled); + const bool isDisabled = !(option->state & State_Enabled); const bool isFlat = button->features & QStyleOptionButton::Flat; QS60StyleEnums::SkinParts skinPart; QS60StylePrivate::SkinElements skinElement; if (!isDisabled) { - const bool isPressed = (option->state & QStyle::State_Sunken) || - (option->state & QStyle::State_On); + const bool isPressed = (option->state & State_Sunken) || + (option->state & State_On); if (isFlat) { skinPart = isPressed ? QS60StyleEnums::SP_QsnFrButtonTbCenterPressed : QS60StyleEnums::SP_QsnFrButtonTbCenter; @@ -1292,7 +1290,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(option)) { QStyleOptionToolButton optionToolButton = *toolBtn; - if (!optionToolButton.icon.isNull() && (optionToolButton.state & QStyle::State_Sunken) + if (!optionToolButton.icon.isNull() && (optionToolButton.state & State_Sunken) && (optionToolButton.state & State_Enabled)) { const QIcon::State state = optionToolButton.state & State_On ? QIcon::On : QIcon::Off; @@ -1351,8 +1349,8 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, painter->save(); painter->setClipRect(voptAdj.rect); - const bool isSelected = (vopt->state & QStyle::State_Selected); - const bool hasFocus = (vopt->state & QStyle::State_HasFocus); + const bool isSelected = (vopt->state & State_Selected); + const bool hasFocus = (vopt->state & State_HasFocus); bool isScrollBarVisible = false; int scrollBarWidth = 0; @@ -1426,8 +1424,8 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, } // draw the icon - const QIcon::Mode mode = (voptAdj.state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled; - const QIcon::State state = voptAdj.state & QStyle::State_Open ? QIcon::On : QIcon::Off; + const QIcon::Mode mode = (voptAdj.state & State_Enabled) ? QIcon::Normal : QIcon::Disabled; + const QIcon::State state = voptAdj.state & State_Open ? QIcon::On : QIcon::Off; voptAdj.icon.paint(painter, iconRect, voptAdj.decorationAlignment, mode, state); // Draw selection check mark. Show check mark only in multi selection modes. @@ -1439,29 +1437,29 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, QStyleOptionViewItemV4 checkMarkOption(voptAdj); // Draw selection mark. - if (voptAdj.state & QStyle::State_Selected && !singleSelection) { + if (voptAdj.state & State_Selected && !singleSelection) { checkMarkOption.rect = selectionRect; - drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget); + drawPrimitive(PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget); if ( textRect.right() > selectionRect.left() ) textRect.setRight(selectionRect.left()); } else if (singleSelection && voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator && selectionRect.isValid()) { checkMarkOption.rect = selectionRect; - checkMarkOption.state = checkMarkOption.state & ~QStyle::State_HasFocus; + checkMarkOption.state = checkMarkOption.state & ~State_HasFocus; switch (vopt->checkState) { case Qt::Unchecked: - checkMarkOption.state |= QStyle::State_Off; + checkMarkOption.state |= State_Off; break; case Qt::PartiallyChecked: - checkMarkOption.state |= QStyle::State_NoChange; + checkMarkOption.state |= State_NoChange; break; case Qt::Checked: - checkMarkOption.state |= QStyle::State_On; + checkMarkOption.state |= State_On; break; } - drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget); + drawPrimitive(PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget); } } @@ -1486,7 +1484,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, case CE_TabBarTabShape: if (const QStyleOptionTabV3 *optionTab = qstyleoption_cast<const QStyleOptionTabV3 *>(option)) { QStyleOptionTabV3 optionTabAdj = *optionTab; - const bool isSelected = optionTab->state & QStyle::State_Selected; + const bool isSelected = optionTab->state & State_Selected; const bool directionMirrored = (optionTab->direction == Qt::RightToLeft); QS60StylePrivate::SkinElements skinElement; switch (optionTab->shape) { @@ -1521,9 +1519,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, skinElement==QS60StylePrivate::SE_TabBarTabSouthActive|| skinElement==QS60StylePrivate::SE_TabBarTabWestActive) { const int borderThickness = - QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth); + QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); const int tabOverlap = - QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap) - borderThickness; + QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap) - borderThickness; //todo: draw navi wipe behind tabbar - must be drawn with first draw if (skinElement==QS60StylePrivate::SE_TabBarTabEastInactive|| @@ -1546,9 +1544,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, QStyleOptionTabV3 optionTab = *tab; QRect tr = optionTab.rect; const bool directionMirrored = (optionTab.direction == Qt::RightToLeft); - const int borderThickness = QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth); + const int borderThickness = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); const int tabOverlap = - QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap) - borderThickness; + QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap) - borderThickness; const QRect windowRect = painter->window(); switch (tab->shape) { @@ -1602,12 +1600,12 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, m.rotate(newRotation); painter->setTransform(m, true); } - tr.adjust(0, 0, pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget), - pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget)); + tr.adjust(0, 0, pixelMetric(PM_TabBarTabShiftHorizontal, tab, widget), + pixelMetric(PM_TabBarTabShiftVertical, tab, widget)); if (selected) { - tr.setBottom(tr.bottom() - pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget)); - tr.setRight(tr.right() - pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget)); + tr.setBottom(tr.bottom() - pixelMetric(PM_TabBarTabShiftVertical, tab, widget)); + tr.setRight(tr.right() - pixelMetric(PM_TabBarTabShiftHorizontal, tab, widget)); } int alignment = Qt::AlignCenter | Qt::TextShowMnemonic; @@ -1648,17 +1646,20 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, // busy indicator const QS60StylePrivate::SkinElementFlag orientationFlag = optionProgressBar->orientation == Qt::Horizontal ? QS60StylePrivate::SF_PointNorth : QS60StylePrivate::SF_PointWest; - QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnGrafBarWait, painter, progressRect, flags | orientationFlag); + + QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnGrafBarWaitAnim, + painter, progressRect, flags | orientationFlag | QS60StylePrivate::SF_Animation ); } else { const qreal progressFactor = (optionProgressBar->minimum == optionProgressBar->maximum) ? 1.0 : (qreal)optionProgressBar->progress / optionProgressBar->maximum; + const int frameWidth = pixelMetric(PM_DefaultFrameWidth, option, widget); 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.adjust(1, 0, -1, 0); + progressRect.translate(optionProgressBar->rect.width() - progressRect.width(), 0); + progressRect.adjust(frameWidth, 0, -frameWidth, 0); } else { - progressRect.adjust(0, 1, 0, -1); + progressRect.adjust(0, frameWidth, 0, -frameWidth); progressRect.setTop(progressRect.bottom() - int(progressRect.height() * progressFactor)); } @@ -1714,9 +1715,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, QRect textRect = subElementRect(SE_ItemViewItemText, &optionMenuItem, widget); //todo: move the vertical spacing stuff into subElementRect - const int vSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing); + const int vSpacing = QS60StylePrivate::pixelMetric(PM_LayoutVerticalSpacing); if (checkable){ - const int hSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing); + const int hSpacing = QS60StylePrivate::pixelMetric(PM_LayoutHorizontalSpacing); QStyleOptionMenuItem optionCheckBox; optionCheckBox.QStyleOptionMenuItem::operator=(*menuItem); optionCheckBox.rect.setWidth(pixelMetric(PM_IndicatorWidth)); @@ -1754,7 +1755,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, QStyleOptionMenuItem arrowOptions; arrowOptions.QStyleOption::operator=(*menuItem); const int indicatorWidth = (pixelMetric(PM_ListViewIconSize, option, widget) >> 1) + - pixelMetric(QStyle::PM_LayoutVerticalSpacing, option, widget); + pixelMetric(PM_LayoutVerticalSpacing, option, widget); if (optionMenuItem.direction == Qt::LeftToRight) arrowOptions.rect.setLeft(textRect.right()); arrowOptions.rect.setWidth(indicatorWidth); @@ -1925,8 +1926,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, break; case CE_MenuScroller: break; - case CE_FocusFrame: - { + case CE_FocusFrame: { // The pen width should nearly fill the layoutspacings around the widget const int penWidth = qMin(pixelMetric(QS60Style::PM_LayoutVerticalSpacing), pixelMetric(QS60Style::PM_LayoutHorizontalSpacing)) @@ -1985,11 +1985,21 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, */ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const { - Q_D(const QS60Style); const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ? QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled; bool commonStyleDraws = false; switch (element) { + case PE_FrameFocusRect: { + //Draw themed highlight to radiobuttons and checkboxes. + //For other widgets skip, unless palette has been modified. In that case, draw with commonstyle. + if (option->palette.highlight().color() == QS60StylePrivate::themePalette()->highlight().color()) + if ((qstyleoption_cast<const QStyleOptionFocusRect *>(option) && + (qobject_cast<const QRadioButton *>(widget) || qobject_cast<const QCheckBox *>(widget)))) + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, option->rect, flags); + else + commonStyleDraws = true; + } + break; #ifndef QT_NO_LINEEDIT case PE_PanelLineEdit: if (const QStyleOptionFrame *lineEdit = qstyleoption_cast<const QStyleOptionFrame *>(option)) { @@ -2004,15 +2014,14 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti } break; #endif // QT_NO_LINEEDIT - case PE_IndicatorCheckBox: - { + case PE_IndicatorCheckBox: { // Draw checkbox indicator as color skinned graphics. - const QS60StyleEnums::SkinParts skinPart = (option->state & QStyle::State_On) ? + const QS60StyleEnums::SkinParts skinPart = (option->state & State_On) ? QS60StyleEnums::SP_QgnIndiCheckboxOn : QS60StyleEnums::SP_QgnIndiCheckboxOff; painter->save(); - QColor themeColor = QS60StylePrivate::themePalette()->windowText().color(); - QColor windowTextColor = option->palette.windowText().color(); + const QColor themeColor = QS60StylePrivate::themePalette()->windowText().color(); + const QColor windowTextColor = option->palette.windowText().color(); if (themeColor != windowTextColor) painter->setPen(windowTextColor); @@ -2032,7 +2041,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti if (checkBoxVisible && singleSelection) { drawPrimitive(PE_IndicatorCheckBox, option, painter, widget); // ... or normal "tick" selection at the end. - } else if (option->state & QStyle::State_Selected) { + } else if (option->state & State_Selected) { QRect tickRect = option->rect; const int frameBorderWidth = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth); // adjust tickmark rect to exclude frame border @@ -2059,15 +2068,15 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti buttonRect.adjust(0, -newY, -1, -newY); painter->save(); - QColor themeColor = d->s60Color(QS60StyleEnums::CL_QsnTextColors, 6, option); - QColor buttonTextColor = option->palette.buttonText().color(); + const QColor themeColor = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, option); + const QColor buttonTextColor = option->palette.buttonText().color(); if (themeColor != buttonTextColor) painter->setPen(buttonTextColor); else painter->setPen(themeColor); // Draw radiobutton indicator as color skinned graphics. - QS60StyleEnums::SkinParts skinPart = (option->state & QStyle::State_On) ? + QS60StyleEnums::SkinParts skinPart = (option->state & State_On) ? QS60StyleEnums::SP_QgnIndiRadiobuttOn : QS60StyleEnums::SP_QgnIndiRadiobuttOff; QS60StylePrivate::drawSkinPart(skinPart, painter, buttonRect, (flags | QS60StylePrivate::SF_ColorSkinned)); @@ -2077,15 +2086,14 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti case PE_PanelButtonCommand: case PE_PanelButtonTool: case PE_PanelButtonBevel: - case PE_FrameButtonBevel: { + case PE_FrameButtonBevel: if (QS60StylePrivate::canDrawThemeBackground(option->palette.base())) { - const bool isPressed = option->state & QStyle::State_Sunken; + const bool isPressed = option->state & State_Sunken; const QS60StylePrivate::SkinElements skinElement = isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal; QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags); } else { commonStyleDraws = true; - } } break; #ifndef QT_NO_TOOLBUTTON @@ -2207,7 +2215,6 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti break; #ifndef QT_NO_ITEMVIEWS case PE_PanelItemViewItem: - case PE_PanelItemViewRow: // ### Qt 5: remove break; #endif //QT_NO_ITEMVIEWS @@ -2276,7 +2283,23 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti } } break; - + case PE_PanelItemViewRow: // ### Qt 5: remove +#ifndef QT_NO_ITEMVIEWS + if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) { + if (vopt->palette.base().texture().cacheKey() != QS60StylePrivate::m_themePalette->base().texture().cacheKey()) { + //QPalette::Base has been changed, let commonstyle draw the item + commonStyleDraws = true; + } else { + QPalette::ColorGroup cg = vopt->state & State_Enabled ? QPalette::Normal : QPalette::Disabled; + if (cg == QPalette::Normal && !(vopt->state & State_Active)) + cg = QPalette::Inactive; + if (vopt->features & QStyleOptionViewItemV2::Alternate) + painter->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::AlternateBase)); + //apart from alternate base, no background for list item is drawn for S60Style + } + } +#endif + break; case PE_PanelScrollAreaCorner: break; @@ -2361,8 +2384,7 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) sz += QSize(2 * f->lineWidth, 4 * f->lineWidth); break; - case CT_TabBarTab: - { + case CT_TabBarTab: { const QSize naviPaneSize = QS60StylePrivate::naviPaneSize(); sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget); if (naviPaneSize.height() > sz.height()) @@ -2374,8 +2396,26 @@ 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(PM_FocusFrameVMargin)); break; +#ifndef QT_NO_COMBOBOX + case CT_ComboBox: + if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { + const int frameWidth = cmb->frame ? pixelMetric(PM_ComboBoxFrameWidth, opt, widget) * 2 : 0; + const int textMargins = 2*(pixelMetric(PM_FocusFrameHMargin) + 1); + const int smallestExtraWidth = 23; + // QItemDelegate::sizeHint expands the textMargins two times, thus the 2*textMargins... + const int extra = + qMax(smallestExtraWidth, 2*textMargins + pixelMetric(PM_ScrollBarExtent, opt, widget)); + sz = QSize(sz.width() + frameWidth + extra, sz.height() + frameWidth); + int maxScreenWidth = QApplication::desktop()->availableGeometry().size().width(); + if (sz.width() > maxScreenWidth) { + maxScreenWidth = maxScreenWidth - (extra + frameWidth); + sz.setWidth(maxScreenWidth); + } + } + break; +#endif default: sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); break; @@ -2414,7 +2454,7 @@ int QS60Style::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w retValue = QPalette::Base; break; case SH_ItemView_ActivateItemOnSingleClick: - retValue = true; + retValue = QS60StylePrivate::isSingleClickUi(); break; case SH_ProgressDialog_TextLabelAlignment: retValue = (QApplication::layoutDirection() == Qt::LeftToRight) ? @@ -2526,7 +2566,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(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(PM_ButtonIconSize) + 2 * buttonMargin; QSize buttonSize; buttonSize.setHeight(qMax(8, spinbox->rect.height() - frameThickness)); //width should at least be equal to height @@ -2575,7 +2615,7 @@ 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 buttonIconSize = QS60StylePrivate::pixelMetric(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; @@ -2613,7 +2653,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple case SC_GroupBoxLabel: { //slightly indent text and boxes, so that dialog border does not mess with them. const int horizontalSpacing = - QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing); + QS60StylePrivate::pixelMetric(PM_LayoutHorizontalSpacing); ret.adjust(2, horizontalSpacing - 3, 0, 0); } break; @@ -2668,6 +2708,9 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con { QRect ret; switch (element) { + case SE_RadioButtonFocusRect: + ret = opt->rect; + break; case SE_LineEditContents: { // in S60 the input text box doesn't start from line Edit's TL, but // a bit indented. @@ -2686,9 +2729,9 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) { const int tabOverlapNoBorder = - QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap); + QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap); const int tabOverlap = - tabOverlapNoBorder-QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth); + tabOverlapNoBorder-QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); const QTabWidget *tab = qobject_cast<const QTabWidget *>(widget); int gain = (tab) ? tabOverlap * tab->count() : 0; switch (twf->shape) { @@ -2737,8 +2780,8 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con multiSelection && (vopt->features & QStyleOptionViewItemV2::HasCheckIndicator)) { const int verticalSpacing = - QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing); - //const int horizontalSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing); + QS60StylePrivate::pixelMetric(PM_LayoutVerticalSpacing); + //const int horizontalSpacing = QS60StylePrivate::pixelMetric(PM_LayoutHorizontalSpacing); const int checkBoxRectWidth = subElementRect(SE_ItemViewItemCheckIndicator, opt, widget).width(); ret.adjust(-checkBoxRectWidth - verticalSpacing, 0, -checkBoxRectWidth - verticalSpacing, 0); } @@ -2784,9 +2827,9 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con singleSelection; // Selection check mark rect. - const int indicatorWidth = QS60StylePrivate::pixelMetric(QStyle::PM_IndicatorWidth); - const int indicatorHeight = QS60StylePrivate::pixelMetric(QStyle::PM_IndicatorHeight); - const int spacing = QS60StylePrivate::pixelMetric(QStyle::PM_CheckBoxLabelSpacing); + const int indicatorWidth = QS60StylePrivate::pixelMetric(PM_IndicatorWidth); + const int indicatorHeight = QS60StylePrivate::pixelMetric(PM_IndicatorHeight); + const int spacing = QS60StylePrivate::pixelMetric(PM_CheckBoxLabelSpacing); const int itemHeight = opt->rect.height(); int heightOffset = 0; @@ -2818,6 +2861,25 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con } ret = visualRect(opt->direction, opt->rect, ret); break; + case SE_RadioButtonIndicator: { + const int height = pixelMetric(PM_ExclusiveIndicatorHeight, opt, widget); + ret.setRect(opt->rect.x(), opt->rect.y() + ((opt->rect.height() - height) >> 1), + pixelMetric(PM_ExclusiveIndicatorWidth, opt, widget), height); + ret.translate(2, 0); //move indicator slightly to avoid highlight crossing over it + ret = visualRect(opt->direction, opt->rect, ret); + } + break; + case SE_CheckBoxIndicator: { + const int height = pixelMetric(PM_IndicatorHeight, opt, widget); + ret.setRect(opt->rect.x(), opt->rect.y() + ((opt->rect.height() - height) >> 1), + pixelMetric(PM_IndicatorWidth, opt, widget), height); + ret.translate(2, 0); //move indicator slightly to avoid highlight crossing over it + ret = visualRect(opt->direction, opt->rect, ret); + } + break; + case SE_CheckBoxFocusRect: + ret = opt->rect; + break; default: ret = QCommonStyle::subElementRect(element, opt, widget); } @@ -2835,6 +2897,12 @@ void QS60Style::polish(QWidget *widget) if (!widget) return; + //Currently we only support animations in QProgressBar. +#ifndef QT_NO_PROGRESSBAR + if (qobject_cast<QProgressBar *>(widget)) + widget->installEventFilter(this); +#endif + if (false #ifndef QT_NO_SCROLLBAR || qobject_cast<QScrollBar *>(widget) @@ -2867,6 +2935,8 @@ void QS60Style::polish(QWidget *widget) */ void QS60Style::unpolish(QWidget *widget) { + Q_D(QS60Style); + if (false #ifndef QT_NO_SCROLLBAR || qobject_cast<QScrollBar *>(widget) @@ -2893,6 +2963,14 @@ void QS60Style::unpolish(QWidget *widget) if (widget) widget->setPalette(QPalette()); +#if defined(Q_WS_S60) && !defined(QT_NO_PROGRESSBAR) + if (QProgressBar *bar = qobject_cast<QProgressBar *>(widget)) { + widget->removeEventFilter(this); + d->m_bars.removeAll(bar); + } +#else + Q_UNUSED(d) +#endif QCommonStyle::unpolish(widget); } @@ -2924,10 +3002,23 @@ void QS60Style::unpolish(QApplication *application) bool QS60Style::event(QEvent *e) { #ifdef QT_KEYPAD_NAVIGATION - if (QS60StylePrivate::isTouchSupported()) - return false; Q_D(QS60Style); + const QEvent::Type eventType = e->type(); + if ((eventType == QEvent::FocusIn || + eventType == QEvent::FocusOut || + eventType == QEvent::EnterEditFocus || + eventType == QEvent::LeaveEditFocus) && + QS60StylePrivate::isTouchSupported()) + return false; +#endif + switch (e->type()) { + case QEvent::Timer: { + QTimerEvent *te = static_cast<QTimerEvent*>(e); + timerEvent(te); + } + break; +#ifdef QT_KEYPAD_NAVIGATION case QEvent::FocusIn: if (QWidget *focusWidget = QApplication::focusWidget()) { if (!d->m_focusFrame) @@ -2946,12 +3037,10 @@ bool QS60Style::event(QEvent *e) if (d->m_focusFrame) d->m_focusFrame->update(); break; +#endif default: break; } -#else - Q_UNUSED(e) -#endif return false; } @@ -2961,7 +3050,7 @@ bool QS60Style::event(QEvent *e) QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const { - const int iconDimension = QS60StylePrivate::pixelMetric(QStyle::PM_ToolBarIconSize); + const int iconDimension = QS60StylePrivate::pixelMetric(PM_ToolBarIconSize); const QRect iconSize = (!option) ? QRect(0, 0, iconDimension, iconDimension) : option->rect; QS60StyleEnums::SkinParts part; QS60StylePrivate::SkinElementFlags adjustedFlags; @@ -2971,67 +3060,67 @@ QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon, QS60StylePrivate::SF_StateDisabled; switch(standardIcon) { - case QStyle::SP_MessageBoxWarning: + case SP_MessageBoxWarning: part = QS60StyleEnums::SP_QgnNoteWarning; break; - case QStyle::SP_MessageBoxInformation: + case SP_MessageBoxInformation: part = QS60StyleEnums::SP_QgnNoteInfo; break; - case QStyle::SP_MessageBoxCritical: + case SP_MessageBoxCritical: part = QS60StyleEnums::SP_QgnNoteError; break; - case QStyle::SP_MessageBoxQuestion: + case SP_MessageBoxQuestion: part = QS60StyleEnums::SP_QgnNoteQuery; break; - case QStyle::SP_ArrowRight: + case SP_ArrowRight: part = QS60StyleEnums::SP_QgnIndiNaviArrowRight; break; - case QStyle::SP_ArrowLeft: + case SP_ArrowLeft: part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft; break; - case QStyle::SP_ArrowUp: + case SP_ArrowUp: part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft; adjustedFlags |= QS60StylePrivate::SF_PointEast; break; - case QStyle::SP_ArrowDown: + case SP_ArrowDown: part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft; adjustedFlags |= QS60StylePrivate::SF_PointWest; break; - case QStyle::SP_ArrowBack: + case SP_ArrowBack: if (QApplication::layoutDirection() == Qt::RightToLeft) return QS60Style::standardIcon(SP_ArrowRight, option, widget); return QS60Style::standardIcon(SP_ArrowLeft, option, widget); - case QStyle::SP_ArrowForward: + case SP_ArrowForward: if (QApplication::layoutDirection() == Qt::RightToLeft) return QS60Style::standardIcon(SP_ArrowLeft, option, widget); return QS60Style::standardIcon(SP_ArrowRight, option, widget); - case QStyle::SP_ComputerIcon: + case SP_ComputerIcon: part = QS60StyleEnums::SP_QgnPropPhoneMemcLarge; break; - case QStyle::SP_DirClosedIcon: + case SP_DirClosedIcon: part = QS60StyleEnums::SP_QgnPropFolderSmall; break; - case QStyle::SP_DirOpenIcon: + case SP_DirOpenIcon: part = QS60StyleEnums::SP_QgnPropFolderCurrent; break; - case QStyle::SP_DirIcon: + case SP_DirIcon: part = QS60StyleEnums::SP_QgnPropFolderSmall; break; - case QStyle::SP_FileDialogNewFolder: + case SP_FileDialogNewFolder: part = QS60StyleEnums::SP_QgnPropFolderSmallNew; break; - case QStyle::SP_FileIcon: + case SP_FileIcon: part = QS60StyleEnums::SP_QgnPropFileSmall; break; - case QStyle::SP_TrashIcon: + case SP_TrashIcon: part = QS60StyleEnums::SP_QgnNoteErased; break; - case QStyle::SP_ToolBarHorizontalExtensionButton: + case SP_ToolBarHorizontalExtensionButton: part = QS60StyleEnums::SP_QgnIndiSubMenu; if (QApplication::layoutDirection() == Qt::RightToLeft) adjustedFlags |= QS60StylePrivate::SF_PointSouth; break; - case QStyle::SP_ToolBarVerticalExtensionButton: + case SP_ToolBarVerticalExtensionButton: adjustedFlags |= QS60StylePrivate::SF_PointEast; part = QS60StyleEnums::SP_QgnIndiSubMenu; break; @@ -3045,6 +3134,68 @@ QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon, QCommonStyle::standardIconImplementation(standardIcon, option, widget) : QIcon(cachedPixMap); } +/*! + \internal + Animate indeterminate progress bars only when visible +*/ +bool QS60Style::eventFilter(QObject *object, QEvent *event) +{ +#ifdef Q_WS_S60 +#ifndef QT_NO_PROGRESSBAR + Q_D(QS60Style); + switch(event->type()) { + case QEvent::StyleChange: + case QEvent::Show: + if (QProgressBar *bar = qobject_cast<QProgressBar *>(object)) { + if (!d->m_bars.contains(bar)) + d->m_bars << bar; + if (d->m_bars.size() == 1) //only start with first animated progressbar + d->startAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); + } + break; + case QEvent::Destroy: + case QEvent::Hide: + d->stopAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); + d->m_bars.removeAll(reinterpret_cast<QProgressBar *>(object)); + break; + default: + break; + } +#endif // QT_NO_PROGRESSBAR +#endif // Q_WS_S60 + return QStyle::eventFilter(object, event); +} + +void QS60Style::timerEvent(QTimerEvent *event) +{ +#ifdef Q_WS_S60 +#ifndef QT_NO_PROGRESSBAR + Q_D(QS60Style); + + QS60StyleAnimation *progressBarAnimation = + QS60StylePrivate::animationDefinition(QS60StyleEnums::SP_QgnGrafBarWaitAnim); + + if (event->timerId() == progressBarAnimation->timerId()) { + + Q_ASSERT(progressBarAnimation->interval() > 0); + + if (progressBarAnimation->currentFrame() == progressBarAnimation->frameCount() ) + if (progressBarAnimation->playMode() == QS60StyleEnums::AM_Looping) + progressBarAnimation->setCurrentFrame(0); + else + d->stopAnimation(progressBarAnimation->animationId()); + + foreach (QProgressBar *bar, d->m_bars) { + if ((bar->minimum() == 0 && bar->maximum() == 0)) + bar->update(); + } + progressBarAnimation->setCurrentFrame(progressBarAnimation->currentFrame() + 1); + } +#endif // QT_NO_PROGRESSBAR +#endif // Q_WS_S60 + event->ignore(); +} + extern QPoint qt_s60_fill_background_offset(const QWidget *targetWidget); bool qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush) @@ -3056,11 +3207,13 @@ bool qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QBrush const QPaintDevice *target = painter->device(); if (target->devType() == QInternal::Widget) { const QWidget *widget = static_cast<const QWidget *>(target); - const QVector<QRect> &rects = rgn.rects(); - for (int i = 0; i < rects.size(); ++i) { - const QRect rect(rects.at(i)); - painter->drawPixmap(rect.topLeft(), backgroundTexture, - rect.translated(qt_s60_fill_background_offset(widget))); + if (!widget->testAttribute(Qt::WA_TranslucentBackground)) { + const QVector<QRect> &rects = rgn.rects(); + for (int i = 0; i < rects.size(); ++i) { + const QRect rect(rects.at(i)); + painter->drawPixmap(rect.topLeft(), backgroundTexture, + rect.translated(qt_s60_fill_background_offset(widget))); + } } } return true; diff --git a/src/gui/styles/qs60style.h b/src/gui/styles/qs60style.h index adcb313..82cc21c 100644 --- a/src/gui/styles/qs60style.h +++ b/src/gui/styles/qs60style.h @@ -94,6 +94,9 @@ protected Q_SLOTS: QIcon standardIconImplementation( StandardPixmap standardIcon, const QStyleOption * option = 0, const QWidget * widget = 0 ) const; +protected: + void timerEvent(QTimerEvent *event); + bool eventFilter(QObject *o, QEvent *e); private: Q_DISABLE_COPY(QS60Style) friend class QStyleFactory; diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index 1417552..2cd238f 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -93,6 +93,29 @@ class QS60StyleEnums #endif // !Q_WS_S60 public: + + // S60 definitions within theme + enum ThemeDefinitions { + TD_AnimationData, + }; + + //Defines which values are contained within animation data (retrieved using TD_AnimationData). + //Additionally defines the order in which the items are given out in QList<QVariant>. + enum AnimationData { + AD_Interval = 0, + AD_NumberOfFrames, + AD_AnimationPlayMode, //currently not used as themes seem to contain invalid data + }; + + // Animation modes + enum AnimationMode { + AM_PlayOnce = 0, //animation is played exactly once + AM_Looping, //animation is repeated until stopped + AM_Bounce //animation is played repeatedly until stopped, + //but frames are played in reverse order every second time + //(no support yet) + }; + // S60 look-and-feel font categories enum FontCategories { FC_Undefined, @@ -104,7 +127,7 @@ public: }; enum SkinParts { - SP_QgnGrafBarWait, + SP_QgnGrafBarWaitAnim, SP_QgnGrafBarFrameCenter, SP_QgnGrafBarFrameSideL, SP_QgnGrafBarFrameSideR, @@ -287,7 +310,70 @@ public: }; }; +#ifdef Q_WS_S60 +class CAknBitmapAnimation; +NONSHARABLE_CLASS (AnimationData) : public QObject +{ +public: + AnimationData(const QS60StyleEnums::SkinParts part, int frames, int interval); + + const QS60StyleEnums::SkinParts m_id; + int m_frames; + int m_interval; + QS60StyleEnums::AnimationMode m_mode; +}; + + +NONSHARABLE_CLASS (AnimationDataV2) : public AnimationData +{ +public: + AnimationDataV2(const AnimationData &data); + ~AnimationDataV2(); + + CAknBitmapAnimation *m_animation; + int m_currentFrame; + bool m_resourceBased; + int m_timerId; +}; + + +class QS60StyleAnimation : public QObject +{ +public: + QS60StyleAnimation(const QS60StyleEnums::SkinParts part, int frames, int interval); + ~QS60StyleAnimation(); + +public: + QS60StyleEnums::SkinParts animationId() const {return m_currentData->m_id;} + int frameCount() const { return m_currentData->m_frames;} + int interval() const {return m_currentData->m_interval;} + QS60StyleEnums::AnimationMode playMode() const {return m_currentData->m_mode;} + CAknBitmapAnimation* animationObject() const {return m_currentData->m_animation;} + bool isResourceBased() const {return m_currentData->m_resourceBased;} + int timerId() const {return m_currentData->m_timerId;} + int currentFrame() const {return m_currentData->m_currentFrame;} + + void setFrameCount(const int &frameCount) {m_currentData->m_frames = frameCount;} + void setInterval(const int &interval) {m_currentData->m_interval = interval;} + void setAnimationObject(CAknBitmapAnimation* animation); + void setResourceBased(bool resourceBased) {m_currentData->m_resourceBased = resourceBased;} + void setTimerId(const int &timerId) {m_currentData->m_timerId = timerId;} + void setCurrentFrame(const int ¤tFrame) {m_currentData->m_currentFrame = currentFrame;} + + void resetToDefaults(); + +private: //data members + //TODO: consider changing these to non-pointers as the classes are rather small anyway + AnimationData *m_defaultData; + AnimationDataV2 *m_currentData; +}; + +#endif //Q_WS_S60 + + class QFocusFrame; +class QProgressBar; +class QS60StyleAnimation; // Private class #ifdef Q_OS_SYMBIAN @@ -371,6 +457,7 @@ public: SF_StateEnabled = 0x0010, // Enabled = the default SF_StateDisabled = 0x0020, SF_ColorSkinned = 0x0040, // pixmap is colored with foreground pen color + SF_Animation = 0x0080, }; enum CacheClearReason { @@ -412,6 +499,7 @@ public: static bool isTouchSupported(); static bool isToolBarBackground(); static bool hasSliderGrooveGraphic(); + static bool isSingleClickUi(); // calculates average color based on button skin graphics (minus borders). QColor colorFromFrameGraphics(SkinFrameElements frame) const; @@ -455,6 +543,16 @@ public: //so that theme graphic background can be drawn. static bool canDrawThemeBackground(const QBrush &backgroundBrush); + static int currentAnimationFrame(QS60StyleEnums::SkinParts part); +#ifdef Q_WS_S60 + + //No support for animations on emulated style + void startAnimation(QS60StyleEnums::SkinParts animation); + void stopAnimation(QS60StyleEnums::SkinParts animation); + static QS60StyleAnimation* animationDefinition(QS60StyleEnums::SkinParts part); + +#endif + private: static void drawPart(QS60StyleEnums::SkinParts part, QPainter *painter, const QRect &rect, SkinElementFlags flags = KDefaultSkinElementFlags); @@ -497,6 +595,12 @@ private: QPalette m_originalPalette; QPointer<QFocusFrame> m_focusFrame; + +#ifdef Q_WS_S60 + //list of progress bars having animation running + QList<QProgressBar *> m_bars; +#endif + }; QT_END_NAMESPACE diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index be61073..a3bb169 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -63,6 +63,7 @@ #include <aknutils.h> #include <aknnavi.h> #include <gulicon.h> +#include <AknBitmapAnimation.h> #if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN) @@ -72,6 +73,7 @@ enum TDrawType { EDrawIcon, EDrawGulIcon, EDrawBackground, + EDrawAnimation, ENoDraw }; @@ -97,6 +99,47 @@ typedef struct { int newMinorSkinId; } partMapEntry; +AnimationData::AnimationData(const QS60StyleEnums::SkinParts part, int frames, int interval) : m_id(part), + m_frames(frames), m_interval(interval), m_mode(QS60StyleEnums::AM_Looping) +{ +} + +AnimationDataV2::AnimationDataV2(const AnimationData &data) : AnimationData(data.m_id, data.m_frames, data.m_interval), + m_resourceBased(false), m_animation(0), m_timerId(0) +{ +} +AnimationDataV2::~AnimationDataV2() +{ + delete m_animation; +} + +QS60StyleAnimation::QS60StyleAnimation(const QS60StyleEnums::SkinParts part, int frames, int interval) +{ + QT_TRAP_THROWING(m_defaultData = new (ELeave) AnimationData(part, frames, interval)); + QT_TRAP_THROWING(m_currentData = new (ELeave) AnimationDataV2(*m_defaultData)); +} + +QS60StyleAnimation::~QS60StyleAnimation() +{ + delete m_currentData; + delete m_defaultData; +} + +void QS60StyleAnimation::setAnimationObject(CAknBitmapAnimation* animation) +{ + Q_ASSERT(animation); + if (m_currentData->m_animation) + delete m_currentData->m_animation; + m_currentData->m_animation = animation; +} + +void QS60StyleAnimation::resetToDefaults() +{ + delete m_currentData; + m_currentData = 0; + QT_TRAP_THROWING(m_currentData = new (ELeave) AnimationDataV2(*m_defaultData)); +} + class QS60StyleModeSpecifics { public: @@ -113,6 +156,8 @@ public: static QSize naviPaneSize(); static TAknsItemID partSpecificThemeId(int part); + static QVariant themeDefinition(QS60StyleEnums::ThemeDefinitions definition, QS60StyleEnums::SkinParts part); + private: static QPixmap createSkinnedGraphicsLX(QS60StyleEnums::SkinParts part, const QSize &size, QS60StylePrivate::SkinElementFlags flags); @@ -128,7 +173,7 @@ private: }; const partMapEntry QS60StyleModeSpecifics::m_partMap[] = { - /* SP_QgnGrafBarWait */ {KAknsIIDQgnGrafBarWaitAnim, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnGrafBarWaitAnim */ {KAknsIIDQgnGrafBarWaitAnim, EDrawAnimation, 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}, @@ -371,7 +416,7 @@ QPixmap QS60StyleModeSpecifics::colorSkinnedGraphics( void QS60StyleModeSpecifics::fallbackInfo(const QS60StyleEnums::SkinParts &stylePart, TInt &fallbackIndex) { switch(stylePart) { - case QS60StyleEnums::SP_QgnGrafBarWait: + case QS60StyleEnums::SP_QgnGrafBarWaitAnim: fallbackIndex = EMbmAvkonQgn_graf_bar_wait_1; break; case QS60StyleEnums::SP_QgnGrafBarFrameCenter: @@ -604,6 +649,11 @@ bool QS60StylePrivate::hasSliderGrooveGraphic() return QSysInfo::s60Version() != QSysInfo::SV_S60_3_1; } +bool QS60StylePrivate::isSingleClickUi() +{ + return (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0); +} + QPoint qt_s60_fill_background_offset(const QWidget *targetWidget) { CCoeControl *control = targetWidget->effectiveWinId(); @@ -709,6 +759,69 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX( // QS60WindowSurface::lockBitmapHeap(); break; } + case EDrawAnimation: { + CFbsBitmap* animationFrame; + CFbsBitmap* frameMask; + CAknBitmapAnimation* aknAnimation = 0; + TBool constructedFromTheme = ETrue; + + QS60StyleAnimation* animation = QS60StylePrivate::animationDefinition(part); //ownership is not passed + if (animation) { + if (!animation->animationObject() && !animation->isResourceBased()) {// no pre-made item exists, create new animation + CAknBitmapAnimation* newAnimation = CAknBitmapAnimation::NewL(); + CleanupStack::PushL(newAnimation); + if (newAnimation) + constructedFromTheme = newAnimation->ConstructFromSkinL(skinId); + if (constructedFromTheme && newAnimation->BitmapAnimData()->FrameArray().Count() > 0) { + animation->setResourceBased(false); + animation->setAnimationObject(newAnimation); //animation takes ownership + } + CleanupStack::Pop(newAnimation); + } + //fill-in stored information + aknAnimation = animation->animationObject(); + constructedFromTheme = !animation->isResourceBased(); + } + + const int currentFrame = QS60StylePrivate::currentAnimationFrame(part); + if (constructedFromTheme && aknAnimation && aknAnimation->BitmapAnimData()->FrameArray().Count() > 0) { + //Animation was created succesfully and contains frames, just fetch current frame + if(currentFrame >= aknAnimation->BitmapAnimData()->FrameArray().Count()) + User::Leave(KErrOverflow); + const CBitmapFrameData* frameData = aknAnimation->BitmapAnimData()->FrameArray().At(currentFrame); + if (frameData) { + animationFrame = frameData->Bitmap(); + frameMask = frameData->Mask(); + } + } else { + //Theme does not contain animation theming, create frames from resource file + TInt fallbackGraphicID = -1; + fallbackInfo(part, fallbackGraphicID); + fallbackGraphicID = fallbackGraphicID + (currentFrame * 2); //skip masks + TInt fallbackGraphicsMaskID = + (fallbackGraphicID == KErrNotFound) ? KErrNotFound : fallbackGraphicID + 1; //masks are auto-generated as next in mif files + if (fallbackGraphicsMaskID != KErrNotFound) + fallbackGraphicsMaskID = fallbackGraphicsMaskID + (currentFrame * 2); //skip actual graphics + + //Then draw animation frame + AknsUtils::CreateIconL( + skinInstance, + KAknsIIDDefault, //animation is not themed, lets force fallback graphics + animationFrame, + frameMask, + AknIconUtils::AvkonIconFileName(), + fallbackGraphicID , + fallbackGraphicsMaskID); + } + result = fromFbsBitmap(animationFrame, frameMask, flags, targetSize); + if (!constructedFromTheme) { + delete animationFrame; + animationFrame = 0; + delete frameMask; + frameMask = 0; + } + break; + } } if (!result) result = QPixmap(); @@ -731,7 +844,6 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(QS60StylePrivate::SkinFr MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); QPixmap result; -// QS60WindowSurface::unlockBitmapHeap(); static const TDisplayMode displayMode = S60->supportsPremultipliedAlpha ? Q_SYMBIAN_ECOLOR16MAP : EColor16MA; static const TInt drawParam = S60->supportsPremultipliedAlpha ? KAknsDrawParamDefault : KAknsDrawParamNoClearUnderImage|KAknsDrawParamRGBOnly; @@ -985,8 +1097,13 @@ void QS60StylePrivate::setActiveLayout() m_pmPointer = data[activeLayoutIndex]; } +Q_GLOBAL_STATIC(QList<QS60StyleAnimation *>, m_animations) + QS60StylePrivate::QS60StylePrivate() { + //Animation defaults need to be created when style is instantiated + QS60StyleAnimation* progressBarAnimation = new QS60StyleAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim, 7, 100); + m_animations()->append(progressBarAnimation); // No need to set active layout, if dynamic metrics API is available setActiveLayout(); } @@ -1187,6 +1304,11 @@ void QS60StylePrivate::handleSkinChange() setThemePalette(topLevelWidget); topLevelWidget->ensurePolished(); } +#ifndef QT_NO_PROGRESSBAR + //re-start animation timer + stopAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); //todo: once we have more animations, we could say "stop all running ones" + startAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); //and "re-start all previously running ones" +#endif } QSize QS60StylePrivate::naviPaneSize() @@ -1206,6 +1328,121 @@ QSize QS60StyleModeSpecifics::naviPaneSize() return QSize(0,0); } +int QS60StylePrivate::currentAnimationFrame(QS60StyleEnums::SkinParts part) +{ + QS60StyleAnimation *animation = animationDefinition(part); + // todo: looping could be done in QS60Style::timerEvent + if (animation->frameCount() == animation->currentFrame()) + animation->setCurrentFrame(0); + return animation->currentFrame(); +} + +QS60StyleAnimation* QS60StylePrivate::animationDefinition(QS60StyleEnums::SkinParts part) +{ + int i = 0; + const int animationsCount = m_animations()->isEmpty() ? 0 : m_animations()->count(); + for(; i < animationsCount; i++) { + if (part == m_animations()->at(i)->animationId()) + break; + } + return m_animations()->at(i); +} + +void QS60StylePrivate::startAnimation(QS60StyleEnums::SkinParts animationPart) +{ + Q_Q(QS60Style); + + //Query animation data from theme and store values to local struct. + QVariant themeAnimationDataVariant = QS60StyleModeSpecifics::themeDefinition( + QS60StyleEnums::TD_AnimationData, animationPart); + QList<QVariant> themeAnimationData = themeAnimationDataVariant.toList(); + + QS60StyleAnimation *animation = QS60StylePrivate::animationDefinition(animationPart); + if (animation) { + if (themeAnimationData.at(QS60StyleEnums::AD_Interval).toInt() != 0) + animation->setInterval(themeAnimationData.at(QS60StyleEnums::AD_Interval).toInt()); + + if (themeAnimationData.at(QS60StyleEnums::AD_NumberOfFrames).toInt() != 0) + animation->setFrameCount(themeAnimationData.at(QS60StyleEnums::AD_NumberOfFrames).toInt()); + + //todo: playmode is ignored for now, since it seems to return invalid data on some themes + //lets use the table values for play mode + + animation->setCurrentFrame(0); //always initialize + const int timerId = q->startTimer(animation->interval()); + animation->setTimerId(timerId); + } +} + +void QS60StylePrivate::stopAnimation(QS60StyleEnums::SkinParts animationPart) +{ + Q_Q(QS60Style); + + QS60StyleAnimation *animation = QS60StylePrivate::animationDefinition(animationPart); + if (animation) { + animation->setCurrentFrame(0); + if (animation->timerId() != 0) { + q->killTimer(animation->timerId()); + animation->setTimerId(0); + } + animation->resetToDefaults(); + } +} + +QVariant QS60StyleModeSpecifics::themeDefinition( + QS60StyleEnums::ThemeDefinitions definition, QS60StyleEnums::SkinParts part) +{ + MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); + + Q_ASSERT(skinInstance); + + switch(definition) { + //Animation definitions + case QS60StyleEnums::TD_AnimationData: + { + CAknsBmpAnimItemData *animationData; + TAknsItemID animationSkinId = partSpecificThemeId(part); + QList<QVariant> list; + + TRAPD( error, QT_TRYCATCH_LEAVING( + animationData = static_cast<CAknsBmpAnimItemData*>(skinInstance->CreateUncachedItemDataL( + animationSkinId, EAknsITBmpAnim)))); + if (error) + return list; + + if (animationData) { + list.append((int)animationData->FrameInterval()); + list.append((int)animationData->NumberOfImages()); + + QS60StyleEnums::AnimationMode playMode; + switch(animationData->PlayMode()) { + case CBitmapAnimClientData::EPlay: + playMode = QS60StyleEnums::AM_PlayOnce; + break; + case CBitmapAnimClientData::ECycle: + playMode = QS60StyleEnums::AM_Looping; + break; + case CBitmapAnimClientData::EBounce: + playMode = QS60StyleEnums::AM_Bounce; + break; + default: + break; + } + list.append(QVariant((int)playMode)); + delete animationData; + } else { + list.append(0); + list.append(0); + } + return list; + } + break; + default: + break; + } + return QVariant(); +} + #endif // Q_WS_S60 QT_END_NAMESPACE diff --git a/src/gui/styles/qs60style_simulated.cpp b/src/gui/styles/qs60style_simulated.cpp index bd43eb7..f87cf28 100644 --- a/src/gui/styles/qs60style_simulated.cpp +++ b/src/gui/styles/qs60style_simulated.cpp @@ -342,6 +342,11 @@ bool QS60StylePrivate::hasSliderGrooveGraphic() return false; } +bool QS60StylePrivate::isSingleClickUi() +{ + return false; +} + QFont QS60StylePrivate::s60Font_specific( QS60StyleEnums::FontCategories fontCategory, int pointSize, bool resolveFontSize) @@ -364,6 +369,11 @@ QFont QS60StylePrivate::s60Font_specific( return result; } +int QS60StylePrivate::currentAnimationFrame(QS60StyleEnums::SkinParts part) +{ + return 0; +} + /*! Constructs a QS60Style object. */ diff --git a/src/gui/styles/qstyle_s60.qrc b/src/gui/styles/qstyle_s60.qrc new file mode 100644 index 0000000..dbee38b --- /dev/null +++ b/src/gui/styles/qstyle_s60.qrc @@ -0,0 +1,137 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="/trolltech/styles/commonstyle"> +<!-- <file>images/filelink-16.png</file> --> +<file>images/filelink-32.png</file> +<!-- <file>images/filelink-128.png</file> --> +<!-- <file>images/file-16.png</file> --> +<file>images/file-32.png</file> +<!-- <file>images/file-128.png</file> --> +<!-- <file>images/newdirectory-16.png</file> --> +<file>images/newdirectory-32.png</file> +<!-- <file>images/newdirectory-128.png</file> --> +<!-- <file>images/parentdir-16.png</file> --> +<file>images/parentdir-32.png</file> +<!-- <file>images/parentdir-128.png</file> --> +<!-- <file>images/dvd-16.png</file> --> +<!-- <file>images/dvd-32.png</file> --> +<!-- <file>images/dvd-128.png</file> --> +<!-- <file>images/cdr-16.png</file> --> +<!-- <file>images/cdr-32.png</file> --> +<!-- <file>images/cdr-128.png</file> --> +<!-- <file>images/floppy-16.png</file> --> +<!-- <file>images/floppy-32.png</file> --> +<!-- <file>images/floppy-128.png</file> --> +<!-- <file>images/harddrive-16.png</file> --> +<file>images/harddrive-32.png</file> +<!-- <file>images/harddrive-128.png</file> --> +<!-- <file>images/trash-16.png</file> --> +<!-- <file>images/trash-32.png</file> --> +<!-- <file>images/trash-128.png</file> --> +<!-- <file>images/networkdrive-16.png</file> --> +<!-- <file>images/networkdrive-32.png</file> --> +<!-- <file>images/networkdrive-128.png</file> --> +<!-- <file>images/computer-16.png</file> --> +<!-- <file>images/computer-32.png</file> --> +<!-- <file>images/desktop-16.png</file> --> +<file>images/desktop-32.png</file> +<!-- <file>images/dirclosed-16.png</file> --> +<file>images/dirclosed-32.png</file> +<!-- <file>images/dirclosed-128.png</file> --> +<!-- <file>images/dirlink-16.png</file> --> +<file>images/dirlink-32.png</file> +<!-- <file>images/dirlink-128.png</file> --> +<!-- <file>images/diropen-16.png</file> --> +<file>images/diropen-32.png</file> +<!-- <file>images/diropen-128.png</file> --> +<!-- <file>images/left-16.png</file> --> +<file>images/left-32.png</file> +<!-- <file>images/left-128.png</file> --> +<!-- <file>images/right-16.png</file> --> +<file>images/right-32.png</file> +<!-- <file>images/right-128.png</file> --> +<!-- <file>images/up-16.png</file> --> +<file>images/up-32.png</file> +<!-- <file>images/up-128.png</file> --> +<!-- <file>images/down-16.png</file> --> +<file>images/down-32.png</file> +<!-- <file>images/down-128.png</file> --> +<!-- <file>images/filecontents-16.png</file> --> +<file>images/filecontents-32.png</file> +<!-- <file>images/filecontents-128.png</file> --> +<!-- <file>images/fileinfo-16.png</file> --> +<file>images/fileinfo-32.png</file> +<!-- <file>images/fileinfo-128.png</file> --> +<!-- <file>images/viewdetailed-16.png</file> --> +<file>images/viewdetailed-32.png</file> +<!-- <file>images/viewdetailed-128.png</file> --> +<!-- <file>images/viewlist-16.png</file> --> +<file>images/viewlist-32.png</file> +<!-- <file>images/viewlist-128.png</file> --> +<file>images/fontbitmap-16.png</file> +<file>images/fonttruetype-16.png</file> +<!-- <file>images/standardbutton-apply-128.png</file> --> +<!-- <file>images/standardbutton-apply-16.png</file> --> +<file>images/standardbutton-apply-32.png</file> +<!-- <file>images/standardbutton-cancel-128.png</file> --> +<!-- <file>images/standardbutton-cancel-16.png</file> --> +<file>images/standardbutton-cancel-32.png</file> +<!-- <file>images/standardbutton-clear-128.png</file> --> +<!-- <file>images/standardbutton-clear-16.png</file> --> +<file>images/standardbutton-clear-32.png</file> +<!-- <file>images/standardbutton-close-128.png</file> --> +<!-- <file>images/standardbutton-close-16.png</file> --> +<file>images/standardbutton-close-32.png</file> +<!-- <file>images/standardbutton-delete-128.png</file> --> +<!-- <file>images/standardbutton-delete-16.png</file> --> +<file>images/standardbutton-delete-32.png</file> +<!-- <file>images/standardbutton-help-128.png</file> --> +<!-- <file>images/standardbutton-help-16.png</file> --> +<file>images/standardbutton-help-32.png</file> +<!-- <file>images/standardbutton-no-128.png</file> --> +<!-- <file>images/standardbutton-no-16.png</file> --> +<file>images/standardbutton-no-32.png</file> +<!-- <file>images/standardbutton-ok-128.png</file> --> +<!-- <file>images/standardbutton-ok-16.png</file> --> +<file>images/standardbutton-ok-32.png</file> +<!-- <file>images/standardbutton-open-128.png</file> --> +<!-- <file>images/standardbutton-open-16.png</file> --> +<file>images/standardbutton-open-32.png</file> +<!-- <file>images/standardbutton-save-128.png</file> --> +<!-- <file>images/standardbutton-save-16.png</file> --> +<file>images/standardbutton-save-32.png</file> +<!-- <file>images/standardbutton-yes-128.png</file> --> +<!-- <file>images/standardbutton-yes-16.png</file> --> +<file>images/standardbutton-yes-32.png</file> +<file>images/standardbutton-closetab-16.png</file> +<file>images/standardbutton-closetab-down-16.png</file> +<file>images/standardbutton-closetab-hover-16.png</file> +<!-- <file>images/refresh-24.png</file> --> +<file>images/refresh-32.png</file> +<!-- <file>images/stop-24.png</file> --> +<file>images/stop-32.png</file> +<!-- <file>images/media-stop-16.png</file> --> +<file>images/media-stop-32.png</file> +<!-- <file>images/media-play-16.png</file> --> +<file>images/media-play-32.png</file> +<!-- <file>images/media-pause-16.png</file> --> +<file>images/media-pause-32.png</file> +<!-- <file>images/media-seek-forward-16.png</file> --> +<file>images/media-seek-forward-32.png</file> +<!-- <file>images/media-seek-backward-16.png</file> --> +<file>images/media-seek-backward-32.png</file> +<!-- <file>images/media-skip-forward-16.png</file> --> +<file>images/media-skip-forward-32.png</file> +<!-- <file>images/media-skip-backward-16.png</file> --> +<file>images/media-skip-backward-32.png</file> +<file>images/media-volume-16.png</file> +<file>images/media-volume-muted-16.png</file> +</qresource> +<!-- +<qresource prefix="/trolltech/styles/macstyle"> +<file>images/closedock-16.png</file> +<file>images/closedock-down-16.png</file> +<file>images/dockdock-16.png</file> +<file>images/dockdock-down-16.png</file> +</qresource> +--> +</RCC> diff --git a/src/gui/styles/styles.pri b/src/gui/styles/styles.pri index 7e5c55a..676f59e 100644 --- a/src/gui/styles/styles.pri +++ b/src/gui/styles/styles.pri @@ -23,10 +23,12 @@ SOURCES += \ styles/qstylesheetstyle.cpp \ styles/qstylesheetstyle_default.cpp -!wince* { - RESOURCES += styles/qstyle.qrc +wince* { + RESOURCES += styles/qstyle_wince.qrc +} else:symbian { + RESOURCES += styles/qstyle_s60.qrc } else { - RESOURCES += styles/qstyle_wince.qrc + RESOURCES += styles/qstyle.qrc } contains( styles, all ) { @@ -168,7 +170,7 @@ contains( styles, s60 ):contains(QT_CONFIG, s60) { SOURCES += styles/qs60style.cpp symbian { SOURCES += styles/qs60style_s60.cpp - LIBS += -laknicon -laknskins -laknskinsrv -lfontutils -legul + LIBS += -laknicon -laknskins -laknskinsrv -lfontutils -legul -lbmpanim } else { SOURCES += styles/qs60style_simulated.cpp RESOURCES += styles/qstyle_s60_simulated.qrc diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index 414c2ed..b0a64ea 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -524,8 +524,11 @@ void QLineControl::draw(QPainter *painter, const QPoint &offset, const QRect &cl m_textLayout.draw(painter, offset, selections, clip); if (flags & DrawCursor){ + int cursor = m_cursor; + if (m_preeditCursor != -1) + cursor += m_preeditCursor; if(!m_blinkPeriod || m_blinkStatus) - m_textLayout.drawCursor(painter, offset, m_cursor, m_cursorWidth); + m_textLayout.drawCursor(painter, offset, cursor, m_cursorWidth); } } diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h index 301ff72..d6f2705 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -549,7 +549,10 @@ inline qreal QLineControl::cursorToX(int cursor) const inline qreal QLineControl::cursorToX() const { - return cursorToX(m_cursor); + int cursor = m_cursor; + if (m_preeditCursor != -1) + cursor += m_preeditCursor; + return cursorToX(cursor); } inline bool QLineControl::isReadOnly() const diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 20baac8..fff7097 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -564,7 +564,8 @@ bool QHttpNetworkConnectionPrivate::fillPipeline(QList<HttpMessagePair> &queue, } -QString QHttpNetworkConnectionPrivate::errorDetail(QNetworkReply::NetworkError errorCode, QAbstractSocket* socket) +QString QHttpNetworkConnectionPrivate::errorDetail(QNetworkReply::NetworkError errorCode, QAbstractSocket* socket, + const QString &extraDetail) { Q_ASSERT(socket); @@ -581,7 +582,7 @@ QString QHttpNetworkConnectionPrivate::errorDetail(QNetworkReply::NetworkError e errorString = QLatin1String(QT_TRANSLATE_NOOP("QHttp", "Connection closed")); break; case QNetworkReply::TimeoutError: - errorString = QLatin1String(QT_TRANSLATE_NOOP("QHttp", "HTTP request failed")); + errorString = QLatin1String(QT_TRANSLATE_NOOP("QAbstractSocket", "Socket operation timed out")); break; case QNetworkReply::ProxyAuthenticationRequiredError: errorString = QLatin1String(QT_TRANSLATE_NOOP("QHttp", "Proxy requires authentication")); @@ -600,7 +601,7 @@ QString QHttpNetworkConnectionPrivate::errorDetail(QNetworkReply::NetworkError e break; default: // all other errors are treated as QNetworkReply::UnknownNetworkError - errorString = QLatin1String(QT_TRANSLATE_NOOP("QHttp", "HTTP request failed")); + errorString = extraDetail; break; } return errorString; diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index 76da883..03cf09c 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -185,7 +185,8 @@ public: void createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request); - QString errorDetail(QNetworkReply::NetworkError errorCode, QAbstractSocket *socket); + QString errorDetail(QNetworkReply::NetworkError errorCode, QAbstractSocket *socket, + const QString &extraDetail = QString()); #ifndef QT_NO_COMPRESS bool expand(QAbstractSocket *socket, QHttpNetworkReply *reply, bool dataComplete); diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 1955dba..b80ae9a 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -872,7 +872,7 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket break; } QPointer<QObject> that = connection; - QString errorString = connection->d_func()->errorDetail(errorCode, socket); + QString errorString = connection->d_func()->errorDetail(errorCode, socket, socket->errorString()); if (send2Reply) { if (reply) { reply->d_func()->errorString = errorString; diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 8257545..7088a57 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -1007,21 +1007,21 @@ qint64 QNativeSocketEnginePrivate::nativeWrite(const char *data, qint64 len) ret += qint64(bytesWritten); + int err; if (socketRet != SOCKET_ERROR) { if (ret == len) break; else continue; - } else if (WSAGetLastError() == WSAEWOULDBLOCK) { + } else if ((err = WSAGetLastError()) == WSAEWOULDBLOCK) { break; - } else if (WSAGetLastError() == WSAENOBUFS) { + } else if (err == WSAENOBUFS) { // this function used to not send more than 49152 per call to WSASendTo // to avoid getting a WSAENOBUFS. However this is a performance regression // and we think it only appears with old windows versions. We now handle the // WSAENOBUFS and hope it never appears anyway. // just go on, the next loop run we will try a smaller number } else { - int err = WSAGetLastError(); WS_ERROR_DEBUG(err); switch (err) { case WSAECONNRESET: diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index 8993e72..9a9b1b5 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -696,11 +696,11 @@ QSslCertificate QSslCertificatePrivate::QSslCertificate_from_X509(X509 *x509) static bool matchLineFeed(const QByteArray &pem, int *offset) { - char ch = pem.at(*offset); + char ch; // ignore extra whitespace at the end of the line - while (ch == ' ' && *offset < pem.size()) - ch = pem.at(++*offset); + while (*offset < pem.size() && (ch = pem.at(*offset)) == ' ') + ++*offset; if (ch == '\n') { *offset += 1; @@ -732,7 +732,7 @@ QList<QSslCertificate> QSslCertificatePrivate::certificatesFromPem(const QByteAr break; offset = endPos + sizeof(ENDCERTSTRING) - 1; - if (!matchLineFeed(pem, &offset)) + if (offset < pem.size() && !matchLineFeed(pem, &offset)) break; QByteArray decoded = QByteArray::fromBase64( diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index de1583e..892d330 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -553,6 +553,12 @@ void QSslSocketBackendPrivate::transmit() #endif writeBuffer.free(writtenBytes); totalBytesWritten += writtenBytes; + + if (writtenBytes < nextDataBlockSize) { + // break out of the writing loop and try again after we had read + transmitting = true; + break; + } } if (totalBytesWritten > 0) { @@ -586,12 +592,26 @@ void QSslSocketBackendPrivate::transmit() while ((pendingBytes = plainSocket->bytesAvailable()) > 0) { // Read encrypted data from the socket into a buffer. data.resize(pendingBytes); - int decryptedBytesRead = plainSocket->read(data.data(), pendingBytes); + // just peek() here because q_BIO_write could write less data than expected + int encryptedBytesRead = plainSocket->peek(data.data(), pendingBytes); #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocketBackendPrivate::transmit: read" << decryptedBytesRead << "encrypted bytes from the socket"; + qDebug() << "QSslSocketBackendPrivate::transmit: read" << encryptedBytesRead << "encrypted bytes from the socket"; #endif // Write encrypted data from the buffer into the read BIO. - q_BIO_write(readBio, data.constData(), decryptedBytesRead); + int writtenToBio = q_BIO_write(readBio, data.constData(), encryptedBytesRead); + + // do the actual read() here and throw away the results. + if (writtenToBio > 0) { + // ### TODO: make this cheaper by not making it memcpy. E.g. make it work with data=0x0 or make it work with seek + plainSocket->read(data.data(), writtenToBio); + } else { + // ### Better error handling. + q->setErrorString(QSslSocket::tr("Unable to decrypt data: %1").arg(SSL_ERRORSTR())); + q->setSocketError(QAbstractSocket::UnknownSocketError); + emit q->error(QAbstractSocket::UnknownSocketError); + return; + } + transmitting = true; } diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 556b888..8183f08 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -184,6 +184,9 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context) simpleShaderProg->addShader(vertexShader); simpleShaderProg->addShader(fragShader); simpleShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); + simpleShaderProg->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR); + simpleShaderProg->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR); + simpleShaderProg->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR); simpleShaderProg->link(); if (!simpleShaderProg->isLinked()) { qCritical() << "Errors linking simple shader:" @@ -324,6 +327,11 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS newProg->program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); if (newProg->useOpacityAttribute) newProg->program->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR); + if (newProg->usePmvMatrix) { + newProg->program->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR); + newProg->program->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR); + newProg->program->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR); + } newProg->program->link(); if (!newProg->program->isLinked()) { @@ -424,7 +432,6 @@ GLuint QGLEngineShaderManager::getUniformLocation(Uniform id) "patternColor", "globalOpacity", "depth", - "pmvMatrix", "maskTexture", "fragmentColor", "linearData", @@ -743,6 +750,7 @@ bool QGLEngineShaderManager::useCorrectShaderProg() } requiredProgram.useTextureCoords = texCoords; requiredProgram.useOpacityAttribute = (opacityMode == AttributeOpacity); + requiredProgram.usePmvMatrix = true; // At this point, requiredProgram is fully populated so try to find the program in the cache currentShaderProg = sharedShaders->findProgramInCache(requiredProgram); diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index c52e5c0..3ab4ebe 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -253,6 +253,9 @@ struct QGLEngineCachedShaderProg static const GLuint QT_VERTEX_COORDS_ATTR = 0; static const GLuint QT_TEXTURE_COORDS_ATTR = 1; static const GLuint QT_OPACITY_ATTR = 2; +static const GLuint QT_PMV_MATRIX_1_ATTR = 3; +static const GLuint QT_PMV_MATRIX_2_ATTR = 4; +static const GLuint QT_PMV_MATRIX_3_ATTR = 5; class QGLEngineShaderProg; @@ -397,6 +400,7 @@ public: bool useTextureCoords; bool useOpacityAttribute; + bool usePmvMatrix; bool operator==(const QGLEngineShaderProg& other) { // We don't care about the program @@ -431,7 +435,6 @@ public: PatternColor, GlobalOpacity, Depth, - PmvMatrix, MaskTexture, FragmentColor, LinearData, diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index d9a61e9..ee04166 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -63,210 +63,229 @@ QT_BEGIN_NAMESPACE QT_MODULE(OpenGL) -static const char* const qglslMainVertexShader = "\ - uniform highp float depth;\ - void setPosition();\ - void main(void)\ - {\ - setPosition();\ - gl_Position.z = depth * gl_Position.w;\ - }"; - -static const char* const qglslMainWithTexCoordsVertexShader = "\ - attribute highp vec2 textureCoordArray; \ - varying highp vec2 textureCoords; \ - uniform highp float depth;\ - void setPosition();\ - void main(void) \ - {\ - setPosition();\ - gl_Position.z = depth * gl_Position.w;\ - textureCoords = textureCoordArray; \ - }"; - -static const char* const qglslMainWithTexCoordsAndOpacityVertexShader = "\ - attribute highp vec2 textureCoordArray; \ - attribute lowp float opacityArray; \ - varying highp vec2 textureCoords; \ - varying lowp float opacity; \ - uniform highp float depth; \ - void setPosition(); \ - void main(void) \ - { \ - setPosition(); \ - gl_Position.z = depth * gl_Position.w; \ - textureCoords = textureCoordArray; \ - opacity = opacityArray; \ - }"; +static const char* const qglslMainVertexShader = "\n\ + void setPosition(); \n\ + void main(void) \n\ + { \n\ + setPosition(); \n\ + }\n"; + +static const char* const qglslMainWithTexCoordsVertexShader = "\n\ + attribute highp vec2 textureCoordArray; \n\ + varying highp vec2 textureCoords; \n\ + void setPosition(); \n\ + void main(void) \n\ + { \n\ + setPosition(); \n\ + textureCoords = textureCoordArray; \n\ + }\n"; + +static const char* const qglslMainWithTexCoordsAndOpacityVertexShader = "\n\ + attribute highp vec2 textureCoordArray; \n\ + attribute lowp float opacityArray; \n\ + varying highp vec2 textureCoords; \n\ + varying lowp float opacity; \n\ + void setPosition(); \n\ + void main(void) \n\ + { \n\ + setPosition(); \n\ + textureCoords = textureCoordArray; \n\ + opacity = opacityArray; \n\ + }\n"; // 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 vec2 vertexCoordsArray;\ - uniform highp mat3 pmvMatrix;\ - void setPosition(void)\ - {\ - vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \ - gl_Position = vec4(transformedPos.xy, 0.0, transformedPos.z); \ - }"; - -static const char* const qglslUntransformedPositionVertexShader = "\ - attribute highp vec4 vertexCoordsArray;\ - void setPosition(void)\ - {\ - gl_Position = vertexCoordsArray;\ - }"; +static const char* const qglslPositionOnlyVertexShader = "\n\ + attribute highp vec2 vertexCoordsArray; \n\ + attribute highp vec3 pmvMatrix1; \n\ + attribute highp vec3 pmvMatrix2; \n\ + attribute highp vec3 pmvMatrix3; \n\ + void setPosition(void) \n\ + { \n\ + highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ + gl_Position = vec4(transformedPos.xy, 0.0, transformedPos.z); \n\ + }\n"; + +static const char* const qglslUntransformedPositionVertexShader = "\n\ + attribute highp vec4 vertexCoordsArray; \n\ + void setPosition(void) \n\ + { \n\ + gl_Position = vertexCoordsArray; \n\ + }\n"; // Pattern Brush - This assumes the texture size is 8x8 and thus, the inverted size is 0.125 -static const char* const qglslPositionWithPatternBrushVertexShader = "\ - 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) { \ - 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.0); \ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \ - patternTexCoords.xy = (hTexCoords.xy * 0.125) * invertedHTexCoordsZ; \ - }"; +static const char* const qglslPositionWithPatternBrushVertexShader = "\n\ + attribute highp vec2 vertexCoordsArray; \n\ + attribute highp vec3 pmvMatrix1; \n\ + attribute highp vec3 pmvMatrix2; \n\ + attribute highp vec3 pmvMatrix3; \n\ + uniform mediump vec2 halfViewportSize; \n\ + uniform highp vec2 invertedTextureSize; \n\ + uniform highp mat3 brushTransform; \n\ + varying highp vec2 patternTexCoords; \n\ + void setPosition(void) \n\ + { \n\ + highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ + gl_Position.xy = transformedPos.xy / transformedPos.z; \n\ + mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1.0); \n\ + mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ + gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ + patternTexCoords.xy = (hTexCoords.xy * 0.125) * invertedHTexCoordsZ; \n\ + }\n"; static const char* const qglslAffinePositionWithPatternBrushVertexShader = qglslPositionWithPatternBrushVertexShader; -static const char* const qglslPatternBrushSrcFragmentShader = "\ - uniform lowp sampler2D brushTexture;\ - uniform lowp vec4 patternColor; \ - varying highp vec2 patternTexCoords;\ - lowp vec4 srcPixel() { \ - return patternColor * (1.0 - texture2D(brushTexture, patternTexCoords).r); \ +static const char* const qglslPatternBrushSrcFragmentShader = "\n\ + uniform lowp sampler2D brushTexture; \n\ + uniform lowp vec4 patternColor; \n\ + varying highp vec2 patternTexCoords;\n\ + lowp vec4 srcPixel() \n\ + { \n\ + return patternColor * (1.0 - texture2D(brushTexture, patternTexCoords).r); \n\ }\n"; // Linear Gradient Brush -static const char* const qglslPositionWithLinearGradientBrushVertexShader = "\ - 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() { \ - 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 = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \ - index = (dot(linearData.xy, hTexCoords.xy) * linearData.z) * invertedHTexCoordsZ; \ - }"; +static const char* const qglslPositionWithLinearGradientBrushVertexShader = "\n\ + attribute highp vec2 vertexCoordsArray; \n\ + attribute highp vec3 pmvMatrix1; \n\ + attribute highp vec3 pmvMatrix2; \n\ + attribute highp vec3 pmvMatrix3; \n\ + uniform mediump vec2 halfViewportSize; \n\ + uniform highp vec3 linearData; \n\ + uniform highp mat3 brushTransform; \n\ + varying mediump float index; \n\ + void setPosition() \n\ + { \n\ + highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ + gl_Position.xy = transformedPos.xy / transformedPos.z; \n\ + mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\ + mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ + gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ + index = (dot(linearData.xy, hTexCoords.xy) * linearData.z) * invertedHTexCoordsZ; \n\ + }\n"; static const char* const qglslAffinePositionWithLinearGradientBrushVertexShader = qglslPositionWithLinearGradientBrushVertexShader; -static const char* const qglslLinearGradientBrushSrcFragmentShader = "\ - uniform lowp sampler2D brushTexture; \ - varying mediump float index; \ - lowp vec4 srcPixel() { \ - mediump vec2 val = vec2(index, 0.5); \ - return texture2D(brushTexture, val); \ +static const char* const qglslLinearGradientBrushSrcFragmentShader = "\n\ + uniform lowp sampler2D brushTexture; \n\ + varying mediump float index; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + mediump vec2 val = vec2(index, 0.5); \n\ + return texture2D(brushTexture, val); \n\ }\n"; // Conical Gradient Brush -static const char* const qglslPositionWithConicalGradientBrushVertexShader = "\ - attribute highp vec2 vertexCoordsArray;\ - uniform highp mat3 pmvMatrix;\ - uniform mediump vec2 halfViewportSize; \ - uniform highp mat3 brushTransform; \ - varying highp vec2 A; \ - void setPosition(void)\ - {\ - 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 = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \ - A = hTexCoords.xy * invertedHTexCoordsZ; \ - }"; +static const char* const qglslPositionWithConicalGradientBrushVertexShader = "\n\ + attribute highp vec2 vertexCoordsArray; \n\ + attribute highp vec3 pmvMatrix1; \n\ + attribute highp vec3 pmvMatrix2; \n\ + attribute highp vec3 pmvMatrix3; \n\ + uniform mediump vec2 halfViewportSize; \n\ + uniform highp mat3 brushTransform; \n\ + varying highp vec2 A; \n\ + void setPosition(void) \n\ + { \n\ + highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ + gl_Position.xy = transformedPos.xy / transformedPos.z; \n\ + mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\ + mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ + gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ + A = hTexCoords.xy * invertedHTexCoordsZ; \n\ + }\n"; static const char* const qglslAffinePositionWithConicalGradientBrushVertexShader = qglslPositionWithConicalGradientBrushVertexShader; static const char* const qglslConicalGradientBrushSrcFragmentShader = "\n\ #define INVERSE_2PI 0.1591549430918953358 \n\ - uniform lowp sampler2D brushTexture; \n\ - uniform mediump float angle; \ - varying highp vec2 A; \ - lowp vec4 srcPixel() { \ - highp float t; \ - if (abs(A.y) == abs(A.x)) \ - t = (atan(-A.y + 0.002, A.x) + angle) * INVERSE_2PI; \ - else \ - t = (atan(-A.y, A.x) + angle) * INVERSE_2PI; \ - return texture2D(brushTexture, vec2(t - floor(t), 0.5)); \ - }"; + uniform lowp sampler2D brushTexture; \n\ + uniform mediump float angle; \n\ + varying highp vec2 A; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + highp float t; \n\ + if (abs(A.y) == abs(A.x)) \n\ + t = (atan(-A.y + 0.002, A.x) + angle) * INVERSE_2PI; \n\ + else \n\ + t = (atan(-A.y, A.x) + angle) * INVERSE_2PI; \n\ + return texture2D(brushTexture, vec2(t - floor(t), 0.5)); \n\ + }\n"; // Radial Gradient Brush -static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\ - attribute highp vec2 vertexCoordsArray;\ - uniform highp mat3 pmvMatrix;\ - uniform mediump vec2 halfViewportSize; \ - uniform highp mat3 brushTransform; \ - uniform highp vec2 fmp; \ - varying highp float b; \ - varying highp vec2 A; \ - void setPosition(void) \ - {\ - 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 = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \ - A = hTexCoords.xy * invertedHTexCoordsZ; \ - b = 2.0 * dot(A, fmp); \ - }"; +static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\n\ + attribute highp vec2 vertexCoordsArray;\n\ + attribute highp vec3 pmvMatrix1; \n\ + attribute highp vec3 pmvMatrix2; \n\ + attribute highp vec3 pmvMatrix3; \n\ + uniform mediump vec2 halfViewportSize; \n\ + uniform highp mat3 brushTransform; \n\ + uniform highp vec2 fmp; \n\ + varying highp float b; \n\ + varying highp vec2 A; \n\ + void setPosition(void) \n\ + {\n\ + highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ + gl_Position.xy = transformedPos.xy / transformedPos.z; \n\ + mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\ + mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ + gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ + A = hTexCoords.xy * invertedHTexCoordsZ; \n\ + b = 2.0 * dot(A, fmp); \n\ + }\n"; static const char* const qglslAffinePositionWithRadialGradientBrushVertexShader = qglslPositionWithRadialGradientBrushVertexShader; -static const char* const qglslRadialGradientBrushSrcFragmentShader = "\ - uniform lowp sampler2D brushTexture; \ - uniform highp float fmp2_m_radius2; \ - uniform highp float inverse_2_fmp2_m_radius2; \ - varying highp float b; \ - varying highp vec2 A; \ - lowp vec4 srcPixel() { \ - highp float c = -dot(A, A); \ - highp vec2 val = vec2((-b + sqrt(b*b - 4.0*fmp2_m_radius2*c)) * inverse_2_fmp2_m_radius2, 0.5); \ - return texture2D(brushTexture, val); \ - }"; +static const char* const qglslRadialGradientBrushSrcFragmentShader = "\n\ + uniform lowp sampler2D brushTexture; \n\ + uniform highp float fmp2_m_radius2; \n\ + uniform highp float inverse_2_fmp2_m_radius2; \n\ + varying highp float b; \n\ + varying highp vec2 A; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + highp float c = -dot(A, A); \n\ + highp vec2 val = vec2((-b + sqrt(b*b - 4.0*fmp2_m_radius2*c)) * inverse_2_fmp2_m_radius2, 0.5); \n\ + return texture2D(brushTexture, val); \n\ + }\n"; // Texture Brush -static const char* const qglslPositionWithTextureBrushVertexShader = "\ - 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) { \ - 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 = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \ - textureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \ - }"; +static const char* const qglslPositionWithTextureBrushVertexShader = "\n\ + attribute highp vec2 vertexCoordsArray; \n\ + attribute highp vec3 pmvMatrix1; \n\ + attribute highp vec3 pmvMatrix2; \n\ + attribute highp vec3 pmvMatrix3; \n\ + uniform mediump vec2 halfViewportSize; \n\ + uniform highp vec2 invertedTextureSize; \n\ + uniform highp mat3 brushTransform; \n\ + varying highp vec2 textureCoords; \n\ + void setPosition(void) \n\ + { \n\ + highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ + gl_Position.xy = transformedPos.xy / transformedPos.z; \n\ + mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\ + mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ + gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ + textureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \n\ + }\n"; static const char* const qglslAffinePositionWithTextureBrushVertexShader = qglslPositionWithTextureBrushVertexShader; @@ -275,148 +294,165 @@ static const char* const qglslAffinePositionWithTextureBrushVertexShader // OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead, // we emulate GL_REPEAT by only taking the fractional part of the texture coords. // TODO: Special case POT textures which don't need this emulation -static const char* const qglslTextureBrushSrcFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp sampler2D brushTexture; \ - lowp vec4 srcPixel() { \ - return texture2D(brushTexture, fract(textureCoords)); \ - }"; +static const char* const qglslTextureBrushSrcFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp sampler2D brushTexture; \n\ + lowp vec4 srcPixel() { \n\ + return texture2D(brushTexture, fract(textureCoords)); \n\ + }\n"; #else -static const char* const qglslTextureBrushSrcFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp sampler2D brushTexture; \ - lowp vec4 srcPixel() { \ - return texture2D(brushTexture, textureCoords); \ - }"; +static const char* const qglslTextureBrushSrcFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp sampler2D brushTexture; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + return texture2D(brushTexture, textureCoords); \n\ + }\n"; #endif -static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp vec4 patternColor; \ - uniform lowp sampler2D brushTexture; \ - lowp vec4 srcPixel() { \ - return patternColor * (1.0 - texture2D(brushTexture, textureCoords).r); \ - }"; +static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp vec4 patternColor; \n\ + uniform lowp sampler2D brushTexture; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + return patternColor * (1.0 - texture2D(brushTexture, textureCoords).r); \n\ + }\n"; // Solid Fill Brush -static const char* const qglslSolidBrushSrcFragmentShader = "\ - uniform lowp vec4 fragmentColor; \ - lowp vec4 srcPixel() { \ - return fragmentColor; \ - }"; - -static const char* const qglslImageSrcFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp sampler2D imageTexture; \ - lowp vec4 srcPixel() { \ - return texture2D(imageTexture, textureCoords); \ - }"; - -static const char* const qglslCustomSrcFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp sampler2D imageTexture; \ - lowp vec4 customShader(lowp sampler2D texture, highp vec2 coords); \ - lowp vec4 srcPixel() { \ - return customShader(imageTexture, textureCoords); \ - }"; - -static const char* const qglslImageSrcWithPatternFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp vec4 patternColor; \ - uniform lowp sampler2D imageTexture; \ - lowp vec4 srcPixel() { \ - return patternColor * (1.0 - texture2D(imageTexture, textureCoords).r); \ - }\n"; - -static const char* const qglslNonPremultipliedImageSrcFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp sampler2D imageTexture; \ - lowp vec4 srcPixel() { \ - lowp vec4 sample = texture2D(imageTexture, textureCoords); \ - sample.rgb = sample.rgb * sample.a; \ - return sample; \ - }"; - -static const char* const qglslShockingPinkSrcFragmentShader = "\ - lowp vec4 srcPixel() { \ - return vec4(0.98, 0.06, 0.75, 1.0); \ - }"; - -static const char* const qglslMainFragmentShader_ImageArrays = "\ - varying lowp float opacity; \ - lowp vec4 srcPixel(); \ - void main() { \ - gl_FragColor = srcPixel() * opacity; \ - }"; - -static const char* const qglslMainFragmentShader_CMO = "\ - uniform lowp float globalOpacity; \ - lowp vec4 srcPixel(); \ - lowp vec4 applyMask(lowp vec4); \ - lowp vec4 compose(lowp vec4); \ - void main() { \ - gl_FragColor = applyMask(compose(srcPixel()*globalOpacity))); \ - }"; - -static const char* const qglslMainFragmentShader_CM = "\ - lowp vec4 srcPixel(); \ - lowp vec4 applyMask(lowp vec4); \ - lowp vec4 compose(lowp vec4); \ - void main() { \ - gl_FragColor = applyMask(compose(srcPixel())); \ - }"; - -static const char* const qglslMainFragmentShader_MO = "\ - uniform lowp float globalOpacity; \ - lowp vec4 srcPixel(); \ - lowp vec4 applyMask(lowp vec4); \ - void main() { \ - gl_FragColor = applyMask(srcPixel()*globalOpacity); \ - }"; - -static const char* const qglslMainFragmentShader_M = "\ - lowp vec4 srcPixel(); \ - lowp vec4 applyMask(lowp vec4); \ - void main() { \ - gl_FragColor = applyMask(srcPixel()); \ - }"; - -static const char* const qglslMainFragmentShader_CO = "\ - uniform lowp float globalOpacity; \ - lowp vec4 srcPixel(); \ - lowp vec4 compose(lowp vec4); \ - void main() { \ - gl_FragColor = compose(srcPixel()*globalOpacity); \ - }"; - -static const char* const qglslMainFragmentShader_C = "\ - lowp vec4 srcPixel(); \ - lowp vec4 compose(lowp vec4); \ - void main() { \ - gl_FragColor = compose(srcPixel()); \ - }"; - -static const char* const qglslMainFragmentShader_O = "\ - uniform lowp float globalOpacity; \ - lowp vec4 srcPixel(); \ - void main() { \ - gl_FragColor = srcPixel()*globalOpacity; \ - }"; - -static const char* const qglslMainFragmentShader = "\ - lowp vec4 srcPixel(); \ - void main() { \ - gl_FragColor = srcPixel(); \ - }"; - -static const char* const qglslMaskFragmentShader = "\ - varying highp vec2 textureCoords;\ - uniform lowp sampler2D maskTexture;\ - lowp vec4 applyMask(lowp vec4 src) \ - {\ - lowp vec4 mask = texture2D(maskTexture, textureCoords); \ - return src * mask.a; \ - }"; +static const char* const qglslSolidBrushSrcFragmentShader = "\n\ + uniform lowp vec4 fragmentColor; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + return fragmentColor; \n\ + }\n"; + +static const char* const qglslImageSrcFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp sampler2D imageTexture; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + return texture2D(imageTexture, textureCoords); \n\ + }\n"; + +static const char* const qglslCustomSrcFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp sampler2D imageTexture; \n\ + lowp vec4 customShader(lowp sampler2D texture, highp vec2 coords); \n\ + lowp vec4 srcPixel() \n\ + { \n\ + return customShader(imageTexture, textureCoords); \n\ + }\n"; + +static const char* const qglslImageSrcWithPatternFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp vec4 patternColor; \n\ + uniform lowp sampler2D imageTexture; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + return patternColor * (1.0 - texture2D(imageTexture, textureCoords).r); \n\ + }\n"; + +static const char* const qglslNonPremultipliedImageSrcFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp sampler2D imageTexture; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + lowp vec4 sample = texture2D(imageTexture, textureCoords); \n\ + sample.rgb = sample.rgb * sample.a; \n\ + return sample; \n\ + }\n"; + +static const char* const qglslShockingPinkSrcFragmentShader = "\n\ + lowp vec4 srcPixel() \n\ + { \n\ + return vec4(0.98, 0.06, 0.75, 1.0); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_ImageArrays = "\n\ + varying lowp float opacity; \n\ + lowp vec4 srcPixel(); \n\ + void main() \n\ + { \n\ + gl_FragColor = srcPixel() * opacity; \n\ + }\n"; + +static const char* const qglslMainFragmentShader_CMO = "\n\ + uniform lowp float globalOpacity; \n\ + lowp vec4 srcPixel(); \n\ + lowp vec4 applyMask(lowp vec4); \n\ + lowp vec4 compose(lowp vec4); \n\ + void main() \n\ + { \n\ + gl_FragColor = applyMask(compose(srcPixel()*globalOpacity))); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_CM = "\n\ + lowp vec4 srcPixel(); \n\ + lowp vec4 applyMask(lowp vec4); \n\ + lowp vec4 compose(lowp vec4); \n\ + void main() \n\ + { \n\ + gl_FragColor = applyMask(compose(srcPixel())); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_MO = "\n\ + uniform lowp float globalOpacity; \n\ + lowp vec4 srcPixel(); \n\ + lowp vec4 applyMask(lowp vec4); \n\ + void main() \n\ + { \n\ + gl_FragColor = applyMask(srcPixel()*globalOpacity); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_M = "\n\ + lowp vec4 srcPixel(); \n\ + lowp vec4 applyMask(lowp vec4); \n\ + void main() \n\ + { \n\ + gl_FragColor = applyMask(srcPixel()); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_CO = "\n\ + uniform lowp float globalOpacity; \n\ + lowp vec4 srcPixel(); \n\ + lowp vec4 compose(lowp vec4); \n\ + void main() \n\ + { \n\ + gl_FragColor = compose(srcPixel()*globalOpacity); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_C = "\n\ + lowp vec4 srcPixel(); \n\ + lowp vec4 compose(lowp vec4); \n\ + void main() \n\ + { \n\ + gl_FragColor = compose(srcPixel()); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_O = "\n\ + uniform lowp float globalOpacity; \n\ + lowp vec4 srcPixel(); \n\ + void main() \n\ + { \n\ + gl_FragColor = srcPixel()*globalOpacity; \n\ + }\n"; + +static const char* const qglslMainFragmentShader = "\n\ + lowp vec4 srcPixel(); \n\ + void main() \n\ + { \n\ + gl_FragColor = srcPixel(); \n\ + }\n"; + +static const char* const qglslMaskFragmentShader = "\n\ + varying highp vec2 textureCoords;\n\ + uniform lowp sampler2D maskTexture;\n\ + lowp vec4 applyMask(lowp vec4 src) \n\ + {\n\ + lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\ + return src * mask.a; \n\ + }\n"; // For source over with subpixel antialiasing, the final color is calculated per component as follows // (.a is alpha component, .c is red, green or blue component): @@ -433,23 +469,23 @@ static const char* const qglslMaskFragmentShader = "\ // dest.c = dest.c * (1 - mask.c) + src.c * alpha // -static const char* const qglslRgbMaskFragmentShaderPass1 = "\ - varying highp vec2 textureCoords;\ - uniform lowp sampler2D maskTexture;\ - lowp vec4 applyMask(lowp vec4 src) \ - {\ - lowp vec4 mask = texture2D(maskTexture, textureCoords); \ - return src.a * mask; \ - }"; - -static const char* const qglslRgbMaskFragmentShaderPass2 = "\ - varying highp vec2 textureCoords;\ - uniform lowp sampler2D maskTexture;\ - lowp vec4 applyMask(lowp vec4 src) \ - {\ - lowp vec4 mask = texture2D(maskTexture, textureCoords); \ - return src * mask; \ - }"; +static const char* const qglslRgbMaskFragmentShaderPass1 = "\n\ + varying highp vec2 textureCoords;\n\ + uniform lowp sampler2D maskTexture;\n\ + lowp vec4 applyMask(lowp vec4 src) \n\ + { \n\ + lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\ + return src.a * mask; \n\ + }\n"; + +static const char* const qglslRgbMaskFragmentShaderPass2 = "\n\ + varying highp vec2 textureCoords;\n\ + uniform lowp sampler2D maskTexture;\n\ + lowp vec4 applyMask(lowp vec4 src) \n\ + { \n\ + lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\ + return src * mask; \n\ + }\n"; /* Left to implement: diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index caa679b..b282676 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -168,12 +168,6 @@ void QGL2PaintEngineExPrivate::useSimpleShader() if (matrixDirty) updateMatrix(); - - if (simpleShaderMatrixUniformDirty) { - const GLuint location = shaderManager->simpleProgram()->uniformLocation("pmvMatrix"); - glUniformMatrix3fv(location, 1, GL_FALSE, (GLfloat*)pmvMatrix); - simpleShaderMatrixUniformDirty = false; - } } void QGL2PaintEngineExPrivate::updateBrushTexture() @@ -392,9 +386,11 @@ void QGL2PaintEngineExPrivate::updateMatrix() matrixDirty = false; - // The actual data has been updated so both shader program's uniforms need updating - simpleShaderMatrixUniformDirty = true; - shaderMatrixUniformDirty = true; + // Set the PMV matrix attribute. As we use an attributes rather than uniforms, we only + // need to do this once for every matrix change and persists across all shader programs. + glVertexAttrib3fv(QT_PMV_MATRIX_1_ATTR, pmvMatrix[0]); + glVertexAttrib3fv(QT_PMV_MATRIX_2_ATTR, pmvMatrix[1]); + glVertexAttrib3fv(QT_PMV_MATRIX_3_ATTR, pmvMatrix[2]); dasher.setInvScale(inverseScale); stroker.setInvScale(inverseScale); @@ -932,18 +928,12 @@ bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) if (changed) { // The shader program has changed so mark all uniforms as dirty: brushUniformsDirty = true; - shaderMatrixUniformDirty = true; opacityUniformDirty = true; } if (brushUniformsDirty && mode != ImageDrawingMode && mode != ImageArrayDrawingMode) updateBrushUniforms(); - if (shaderMatrixUniformDirty) { - glUniformMatrix3fv(location(QGLEngineShaderManager::PmvMatrix), 1, GL_FALSE, (GLfloat*)pmvMatrix); - shaderMatrixUniformDirty = false; - } - if (opacityMode == QGLEngineShaderManager::UniformOpacity && opacityUniformDirty) { shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::GlobalOpacity), (GLfloat)q->state()->opacity); opacityUniformDirty = false; @@ -1955,11 +1945,8 @@ void QGL2PaintEngineEx::setState(QPainterState *new_state) if (old_state == s || old_state->renderHintsChanged) renderHintsChanged(); - if (old_state == s || old_state->matrixChanged) { + if (old_state == s || old_state->matrixChanged) d->matrixDirty = true; - d->simpleShaderMatrixUniformDirty = true; - d->shaderMatrixUniformDirty = true; - } if (old_state == s || old_state->compositionModeChanged) d->compositionModeDirty = true; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index ce1b538..8fa0eff 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -252,8 +252,6 @@ public: bool compositionModeDirty; bool brushTextureDirty; bool brushUniformsDirty; - bool simpleShaderMatrixUniformDirty; - bool shaderMatrixUniformDirty; bool opacityUniformDirty; bool stencilClean; // Has the stencil not been used for clipping so far? diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 3f32cf3..48e43b2 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -4393,6 +4393,13 @@ static void qt_gl_draw_text(QPainter *p, int x, int y, const QString &str, \note This function temporarily disables depth-testing when the text is drawn. + \note This function can only be used inside a + QPainter::beginNativePainting()/QPainter::endNativePainting() block + if the default OpenGL paint engine is QPaintEngine::OpenGL. To make + QPaintEngine::OpenGL the default GL engine, call + QGL::setPreferredPaintEngine(QPaintEngine::OpenGL) before the + QApplication constructor. + \l{Overpainting Example}{Overpaint} with QPainter::drawText() instead. */ diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index f4cc7c7..61a16be 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -1651,8 +1651,12 @@ static bool qt_resolveTextureFromPixmap(QPaintDevice *paintDevice) { return false; // Can't use TFP without NPOT } + const QX11Info *xinfo = qt_x11Info(paintDevice); - QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen())); + Display *display = xinfo ? xinfo->display() : X11->display; + int screen = xinfo ? xinfo->screen() : X11->defaultScreen; + + QGLExtensionMatcher extensions(glXQueryExtensionsString(display, screen)); if (extensions.match("GLX_EXT_texture_from_pixmap")) { glXBindTexImageEXT = (qt_glXBindTexImageEXT) qglx_getProcAddress("glXBindTexImageEXT"); glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) qglx_getProcAddress("glXReleaseTexImageEXT"); diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index 6d47687..aa80664 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -252,10 +252,6 @@ QGLPixmapData::QGLPixmapData(PixelType type) { setSerialNumber(++qt_gl_pixmap_serial); m_glDevice.setPixmapData(this); - - // Set InteralBindOptions minus the memory managed, since this - // QGLTexture is not managed as part of the internal texture cache - m_texture.options = QGLContext::PremultipliedAlphaBindOption; } QGLPixmapData::~QGLPixmapData() @@ -344,18 +340,18 @@ void QGLPixmapData::ensureCreated() const } if (!m_source.isNull()) { - glBindTexture(target, m_texture.id); if (external_format == GL_RGB) { - const QImage tx = m_source.convertToFormat(QImage::Format_RGB888); + const QImage tx = m_source.convertToFormat(QImage::Format_RGB888).mirrored(false, true); + + glBindTexture(target, m_texture.id); glTexSubImage2D(target, 0, 0, 0, w, h, external_format, GL_UNSIGNED_BYTE, tx.bits()); } else { const QImage tx = ctx->d_func()->convertToGLFormat(m_source, true, external_format); + + glBindTexture(target, m_texture.id); glTexSubImage2D(target, 0, 0, 0, w, h, external_format, GL_UNSIGNED_BYTE, tx.bits()); - // convertToGLFormat will flip the Y axis, so it needs to - // be drawn upside down - m_texture.options |= QGLContext::InvertedYBindOption; } if (useFramebufferObjects()) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index 1cbfdaf..f27440e 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -552,6 +552,34 @@ QImage *QDirectFBPixmapData::buffer() return &lockedImage; } + +bool QDirectFBPixmapData::scroll(int dx, int dy, const QRect &rect) +{ + if (!dfbSurface) { + return false; + } + unlockSurface(); + DFBResult result = dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); + if (result != DFB_OK) { + DirectFBError("QDirectFBPixmapData::scroll", result); + return false; + } + result = dfbSurface->SetPorterDuff(dfbSurface, DSPD_NONE); + if (result != DFB_OK) { + DirectFBError("QDirectFBPixmapData::scroll", result); + return false; + } + + const DFBRectangle source = { rect.x(), rect.y(), rect.width(), rect.height() }; + result = dfbSurface->Blit(dfbSurface, dfbSurface, &source, source.x + dx, source.y + dy); + if (result != DFB_OK) { + DirectFBError("QDirectFBPixmapData::scroll", result); + return false; + } + + return true; +} + void QDirectFBPixmapData::invalidate() { if (dfbSurface) { @@ -568,6 +596,3 @@ void QDirectFBPixmapData::invalidate() QT_END_NAMESPACE #endif // QT_NO_QWS_DIRECTFB - - - diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h index f9b14a9..da6edc6 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h @@ -81,6 +81,7 @@ public: virtual QImage toImage() const; virtual QPaintEngine *paintEngine() const; virtual QImage *buffer(); + virtual bool scroll(int dx, int dy, const QRect &rect); // Pure virtual in QPixmapData, so re-implement here and delegate to QDirectFBPaintDevice virtual int metric(QPaintDevice::PaintDeviceMetric m) const { return QDirectFBPaintDevice::metric(m); } diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp index cb9c921..6764e75 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp @@ -378,9 +378,6 @@ void QDirectFBWindowSurface::flush(QWidget *widget, const QRegion ®ion, return; } screen->flipSurface(dfbSurface, flipFlags, region, offset); - if (noSystemBackground) { - dfbSurface->Clear(dfbSurface, 0, 0, 0, 0); - } #else setOpaque(windowOpacity != 0xff); if (mode == Offscreen) { diff --git a/src/qbase.pri b/src/qbase.pri index d9832a1..710a2b6 100644 --- a/src/qbase.pri +++ b/src/qbase.pri @@ -94,31 +94,17 @@ symbian { DEFINES+=QT_MAKEDLL TARGET.CAPABILITY = All -Tcb - defBlock = \ - "$${LITERAL_HASH}ifdef WINSCW" \ - "DEFFILE ../s60installs/bwins/$${TARGET}.def" \ - "$${LITERAL_HASH}elif defined EABI" \ - "DEFFILE ../s60installs/eabi/$${TARGET}.def" \ - "$${LITERAL_HASH}endif" - - contains(QT_CONFIG, private_tests) { - #When building autotest configuration, there are extra exports from - #the Qt DLLs, which we don't want in the frozen DEF files. - MMP_RULES += EXPORTUNFROZEN - } else { - #When building without autotests, DEF files are used by default. - #This is to maintain binary compatibility with previous releases. - - #with defBlock enabled, removed exported symbols are treated as errors - #and there is binary compatibility between successive builds. - #with defBlock disabled, binary compatibility is broken every time you build - MMP_RULES += defBlock - - #with EXPORTUNFROZEN enabled, new exports are included in the dll without - #needing to run abld freeze, however binary compatibility is only maintained - #for symbols that are frozen (and only if defBlock is also enabled) - #the downside of EXPORTUNFROZEN is that the linker gets run twice - #MMP_RULES += EXPORTUNFROZEN + # When building without autotests, DEF files are used by default. + # This is to maintain binary compatibility with previous releases. + # To explicitly disable DEF files usage, eg. when lots of code churn is + # going on, and functions may be added and removed before shipping, + # configure with -no-usedeffiles + # WARNING - disabling DEF files *will* break BC with previous released versions + # of Qt, and the only compatibility will be between this build of Qt and anything + # built in this exact environment. *Never* use this when building a version + # for release. + contains(CONFIG, def_files) { + defFilePath=../s60installs } } load(armcc_warnings) diff --git a/src/s60installs/backup_registration.xml b/src/s60installs/backup_registration.xml new file mode 100644 index 0000000..e026140 --- /dev/null +++ b/src/s60installs/backup_registration.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" standalone="yes"?> +<backup_registration> + <system_backup/> + <restore requires_reboot = "no"/> +</backup_registration> diff --git a/src/s60installs/bwins/QtCoreu.def b/src/s60installs/bwins/QtCoreu.def index fe752c8..e7e890c 100644 --- a/src/s60installs/bwins/QtCoreu.def +++ b/src/s60installs/bwins/QtCoreu.def @@ -4398,4 +4398,5 @@ EXPORTS ?object@WrappedEvent@QStateMachine@@QBEPAVQObject@@XZ @ 4397 NONAME ; class QObject * QStateMachine::WrappedEvent::object(void) const ?sender@SignalEvent@QStateMachine@@QBEPAVQObject@@XZ @ 4398 NONAME ; class QObject * QStateMachine::SignalEvent::sender(void) const ?signalIndex@SignalEvent@QStateMachine@@QBEHXZ @ 4399 NONAME ; int QStateMachine::SignalEvent::signalIndex(void) const + ?disconnectOne@QMetaObject@@SA_NPBVQObject@@H0H@Z @ 4400 NONAME ; bool QMetaObject::disconnectOne(class QObject const *, int, class QObject const *, int) diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index 7a629d7..da65230 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -10694,10 +10694,10 @@ EXPORTS ?swipeAngle@QSwipeGesture@@QBEMXZ @ 10693 NONAME ; float QSwipeGesture::swipeAngle(void) const ?symbianEventFilter@QApplication@@UAE_NPBVQSymbianEvent@@@Z @ 10694 NONAME ; bool QApplication::symbianEventFilter(class QSymbianEvent const *) ?symbianFilterEvent@QInputContext@@UAE_NPAVQWidget@@PBVQSymbianEvent@@@Z @ 10695 NONAME ; bool QInputContext::symbianFilterEvent(class QWidget *, class QSymbianEvent const *) - ?symbianHandleCommand@QApplicationPrivate@@QAEHH@Z @ 10696 NONAME ; int QApplicationPrivate::symbianHandleCommand(int) + ?symbianHandleCommand@QApplicationPrivate@@QAEHH@Z @ 10696 NONAME ABSENT ; int QApplicationPrivate::symbianHandleCommand(int) ?symbianProcessEvent@QApplication@@QAEHPBVQSymbianEvent@@@Z @ 10697 NONAME ; int QApplication::symbianProcessEvent(class QSymbianEvent const *) - ?symbianProcessWsEvent@QApplicationPrivate@@QAEHPBVTWsEvent@@@Z @ 10698 NONAME ; int QApplicationPrivate::symbianProcessWsEvent(class TWsEvent const *) - ?symbianResourceChange@QApplicationPrivate@@QAEHH@Z @ 10699 NONAME ; int QApplicationPrivate::symbianResourceChange(int) + ?symbianProcessWsEvent@QApplicationPrivate@@QAEHPBVTWsEvent@@@Z @ 10698 NONAME ABSENT ; int QApplicationPrivate::symbianProcessWsEvent(class TWsEvent const *) + ?symbianResourceChange@QApplicationPrivate@@QAEHH@Z @ 10699 NONAME ABSENT ; int QApplicationPrivate::symbianResourceChange(int) ?symbol@Parser@QCss@@QBEABUSymbol@2@XZ @ 10700 NONAME ; struct QCss::Symbol const & QCss::Parser::symbol(void) const ?sync@QPaintEngineEx@@UAEXXZ @ 10701 NONAME ; void QPaintEngineEx::sync(void) ?syncBackingStore@QWidgetPrivate@@QAEXABVQRegion@@@Z @ 10702 NONAME ; void QWidgetPrivate::syncBackingStore(class QRegion const &) @@ -12525,4 +12525,12 @@ EXPORTS ??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 + ?qt_blurImage@@YAXAAVQImage@@M_NH@Z @ 12527 NONAME ; void qt_blurImage(class QImage &, float, bool, int) + ?qt_blurImage@@YAXPAVQPainter@@AAVQImage@@M_N2H@Z @ 12528 NONAME ; void qt_blurImage(class QPainter *, class QImage &, float, bool, bool, int) + ?qt_halfScaled@@YA?AVQImage@@ABV1@@Z @ 12529 NONAME ; class QImage qt_halfScaled(class QImage const &) + ?qt_memrotate90@@YAXPBIHHHPAIH@Z @ 12530 NONAME ; void qt_memrotate90(unsigned int const *, int, int, int, unsigned int *, int) + ?qt_memrotate90_gl@@YAXPBIHHHPAIH@Z @ 12531 NONAME ; void qt_memrotate90_gl(unsigned int const *, int, int, int, unsigned int *, int) + ?symbianHandleCommand@QApplicationPrivate@@QAEHPBVQSymbianEvent@@@Z @ 12532 NONAME ; int QApplicationPrivate::symbianHandleCommand(class QSymbianEvent const *) + ?symbianProcessWsEvent@QApplicationPrivate@@QAEHPBVQSymbianEvent@@@Z @ 12533 NONAME ; int QApplicationPrivate::symbianProcessWsEvent(class QSymbianEvent const *) + ?symbianResourceChange@QApplicationPrivate@@QAEHPBVQSymbianEvent@@@Z @ 12534 NONAME ; int QApplicationPrivate::symbianResourceChange(class QSymbianEvent const *) diff --git a/src/s60installs/bwins/QtScriptu.def b/src/s60installs/bwins/QtScriptu.def index 8b53524..19f7037 100644 --- a/src/s60installs/bwins/QtScriptu.def +++ b/src/s60installs/bwins/QtScriptu.def @@ -369,4 +369,5 @@ EXPORTS ?willExecuteProgram@QScriptEngineAgentPrivate@@UAEXABVDebuggerCallFrame@QTJSC@@HH@Z @ 368 NONAME ; void QScriptEngineAgentPrivate::willExecuteProgram(class QTJSC::DebuggerCallFrame const &, int, int) ?staticMetaObject@QScriptExtensionPlugin@@2UQMetaObject@@B @ 369 NONAME ; struct QMetaObject const QScriptExtensionPlugin::staticMetaObject ?staticMetaObject@QScriptEngine@@2UQMetaObject@@B @ 370 NONAME ; struct QMetaObject const QScriptEngine::staticMetaObject + ?isQObject@QScriptDeclarativeClass@@UBE_NXZ @ 371 NONAME ; bool QScriptDeclarativeClass::isQObject(void) const diff --git a/src/s60installs/eabi/QtCoreu.def b/src/s60installs/eabi/QtCoreu.def index 89fa76f..a427ff9 100644 --- a/src/s60installs/eabi/QtCoreu.def +++ b/src/s60installs/eabi/QtCoreu.def @@ -3633,4 +3633,5 @@ EXPORTS _ZTIN13QStateMachine12WrappedEventE @ 3632 NONAME _ZTVN13QStateMachine11SignalEventE @ 3633 NONAME _ZTVN13QStateMachine12WrappedEventE @ 3634 NONAME + _ZN11QMetaObject13disconnectOneEPK7QObjectiS2_i @ 3635 NONAME diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index b6862e5..05f620c 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -11629,9 +11629,9 @@ EXPORTS _ZN18QTapAndHoldGestureC1EP7QObject @ 11628 NONAME _ZN18QTapAndHoldGestureC2EP7QObject @ 11629 NONAME _ZN19QAbstractScrollArea18setViewportMarginsERK8QMargins @ 11630 NONAME - _ZN19QApplicationPrivate20symbianHandleCommandEi @ 11631 NONAME - _ZN19QApplicationPrivate21symbianProcessWsEventEPK8TWsEvent @ 11632 NONAME - _ZN19QApplicationPrivate21symbianResourceChangeEi @ 11633 NONAME + _ZN19QApplicationPrivate20symbianHandleCommandEi @ 11631 NONAME ABSENT + _ZN19QApplicationPrivate21symbianProcessWsEventEPK8TWsEvent @ 11632 NONAME ABSENT + _ZN19QApplicationPrivate21symbianResourceChangeEi @ 11633 NONAME ABSENT _ZN19QGraphicsBlurEffect12setBlurHintsE6QFlagsINS_8BlurHintEE @ 11634 NONAME _ZN19QGraphicsBlurEffect13setBlurRadiusEf @ 11635 NONAME _ZN19QGraphicsBlurEffect16blurHintsChangedE6QFlagsINS_8BlurHintEE @ 11636 NONAME @@ -11784,4 +11784,12 @@ EXPORTS _ZNK14QEglProperties8toStringEv @ 11783 NONAME ABSENT _ZNK11QFontEngine10glyphCacheEPvN21QFontEngineGlyphCache4TypeERK10QTransform @ 11784 NONAME _ZNK20QGraphicsItemPrivate21effectiveBoundingRectERK6QRectF @ 11785 NONAME + _Z12qt_blurImageP8QPainterR6QImagefbbi @ 11786 NONAME + _Z12qt_blurImageR6QImagefbi @ 11787 NONAME + _Z13qt_halfScaledRK6QImage @ 11788 NONAME + _Z14qt_memrotate90PKjiiiPji @ 11789 NONAME + _Z17qt_memrotate90_glPKjiiiPji @ 11790 NONAME + _ZN19QApplicationPrivate20symbianHandleCommandEPK13QSymbianEvent @ 11791 NONAME + _ZN19QApplicationPrivate21symbianProcessWsEventEPK13QSymbianEvent @ 11792 NONAME + _ZN19QApplicationPrivate21symbianResourceChangeEPK13QSymbianEvent @ 11793 NONAME diff --git a/src/s60installs/eabi/QtScriptu.def b/src/s60installs/eabi/QtScriptu.def index 8df03c2..8a4be2c 100644 --- a/src/s60installs/eabi/QtScriptu.def +++ b/src/s60installs/eabi/QtScriptu.def @@ -393,4 +393,5 @@ EXPORTS _ZNK23QScriptDeclarativeClass7contextEv @ 392 NONAME _ZTI23QScriptDeclarativeClass @ 393 NONAME _ZTV23QScriptDeclarativeClass @ 394 NONAME + _ZNK23QScriptDeclarativeClass9isQObjectEv @ 395 NONAME diff --git a/src/s60installs/qt.iby b/src/s60installs/qt.iby index f24ac4b..bdd668c 100644 --- a/src/s60installs/qt.iby +++ b/src/s60installs/qt.iby @@ -90,27 +90,27 @@ file=ABI_DIR\BUILD_DIR\qts60plugin_5_0.dll SHARED_LIB_DIR\qts60plugin_5_0.dll S60_APP_RESOURCE(s60main) // imageformats stubs -data=\epoc32\data\qt\qtlibspluginstubs\qgif.qtplugin resource\qt\plugins\imageformats\qgif.qtplugin -data=\epoc32\data\qt\qtlibspluginstubs\qico.qtplugin resource\qt\plugins\imageformats\qico.qtplugin -data=\epoc32\data\qt\qtlibspluginstubs\qjpeg.qtplugin resource\qt\plugins\imageformats\qjpeg.qtplugin -data=\epoc32\data\qt\qtlibspluginstubs\qmng.qtplugin resource\qt\plugins\imageformats\qmng.qtplugin -data=\epoc32\data\qt\qtlibspluginstubs\qsvg.qtplugin resource\qt\plugins\imageformats\qsvg.qtplugin -data=\epoc32\data\qt\qtlibspluginstubs\qtiff.qtplugin resource\qt\plugins\imageformats\qtiff.qtplugin +data=\epoc32\data\z\resource\qt\plugins\imageformats\qgif.qtplugin resource\qt\plugins\imageformats\qgif.qtplugin +data=\epoc32\data\z\resource\qt\plugins\imageformats\qico.qtplugin resource\qt\plugins\imageformats\qico.qtplugin +data=\epoc32\data\z\resource\qt\plugins\imageformats\qjpeg.qtplugin resource\qt\plugins\imageformats\qjpeg.qtplugin +data=\epoc32\data\z\resource\qt\plugins\imageformats\qmng.qtplugin resource\qt\plugins\imageformats\qmng.qtplugin +data=\epoc32\data\z\resource\qt\plugins\imageformats\qsvg.qtplugin resource\qt\plugins\imageformats\qsvg.qtplugin +data=\epoc32\data\z\resource\qt\plugins\imageformats\qtiff.qtplugin resource\qt\plugins\imageformats\qtiff.qtplugin // codecs stubs -data=\epoc32\data\qt\qtlibspluginstubs\qcncodecs.qtplugin resource\qt\plugins\codecs\qcncodecs.qtplugin -data=\epoc32\data\qt\qtlibspluginstubs\qjpcodecs.qtplugin resource\qt\plugins\codecs\qjpcodecs.qtplugin -data=\epoc32\data\qt\qtlibspluginstubs\qkrcodecs.qtplugin resource\qt\plugins\codecs\qkrcodecs.qtplugin -data=\epoc32\data\qt\qtlibspluginstubs\qtwcodecs.qtplugin resource\qt\plugins\codecs\qtwcodecs.qtplugin +data=\epoc32\data\z\resource\qt\plugins\codecs\qcncodecs.qtplugin resource\qt\plugins\codecs\qcncodecs.qtplugin +data=\epoc32\data\z\resource\qt\plugins\codecs\qjpcodecs.qtplugin resource\qt\plugins\codecs\qjpcodecs.qtplugin +data=\epoc32\data\z\resource\qt\plugins\codecs\qkrcodecs.qtplugin resource\qt\plugins\codecs\qkrcodecs.qtplugin +data=\epoc32\data\z\resource\qt\plugins\codecs\qtwcodecs.qtplugin resource\qt\plugins\codecs\qtwcodecs.qtplugin // iconengines stubs -data=\epoc32\data\qt\qtlibspluginstubs\qsvgicon.qtplugin resource\qt\plugins\iconengines\qsvgicon.qtplugin +data=\epoc32\data\z\resource\qt\plugins\iconengines\qsvgicon.qtplugin resource\qt\plugins\iconengines\qsvgicon.qtplugin // Phonon MMF backend -data=\epoc32\data\qt\qtlibspluginstubs\phonon_mmf.qtplugin resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin +data=\epoc32\data\z\resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin // graphicssystems -data=\epoc32\data\qt\qtlibspluginstubs\qvggraphicssystem.qtplugin resource\qt\plugins\graphicssystems\qvggraphicssystem.qtplugin +data=\epoc32\data\z\resource\qt\plugins\graphicssystems\qvggraphicssystem.qtplugin resource\qt\plugins\graphicssystems\qvggraphicssystem.qtplugin // Stub sis file data=ZSYSTEM\install\qt.sis System\Install\qt.sis diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index bbc758b..aaecf6c 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -78,7 +78,11 @@ symbian: { DEPLOYMENT += phonon_backend_plugins } - DEPLOYMENT += qtresources qtlibraries imageformats_plugins codecs_plugins graphicssystems_plugins + # Support backup & restore for Qt libraries + qtbackup.sources = backup_registration.xml + qtbackup.path = c:/private/10202D56/import/packages/$$replace(TARGET.UID3, 0x,) + + DEPLOYMENT += qtresources qtlibraries qtbackup imageformats_plugins codecs_plugins graphicssystems_plugins contains(QT_CONFIG, svg): { qtlibraries.sources += QtSvg.dll @@ -112,9 +116,4 @@ symbian: { BLD_INF_RULES.prj_exports += "qt.iby $$CORE_MW_LAYER_IBY_EXPORT_PATH(qt.iby)" BLD_INF_RULES.prj_exports += "qtdemoapps.iby $$CORE_APP_LAYER_IBY_EXPORT_PATH(qtdemoapps.iby)" - PLUGIN_STUBS = $$files(qmakepluginstubs/*) - for(STUB, PLUGIN_STUBS) { - STUB_FILENAME = $$basename(STUB) - BLD_INF_RULES.prj_exports += "qmakepluginstubs/$${STUB_FILENAME} /epoc32/data/qt/qtlibspluginstubs/$${STUB_FILENAME}" - } } diff --git a/src/tools/uic3/converter.cpp b/src/tools/uic3/converter.cpp index 8fe2a24..2bf293d 100644 --- a/src/tools/uic3/converter.cpp +++ b/src/tools/uic3/converter.cpp @@ -121,7 +121,7 @@ static inline bool isKDEClass(const QString &className) return className.at(1) .isUpper() && className.at(2).isLower(); } -DomUI *Ui3Reader::generateUi4(const QDomElement &widget, bool implicitIncludes) +DomUI *Ui3Reader::generateUi4(const QDomElement &widget) { QDomNodeList nl; candidateCustomWidgets.clear(); @@ -474,7 +474,7 @@ DomUI *Ui3Reader::generateUi4(const QDomElement &widget, bool implicitIncludes) // Magic header generation feature for legacy KDE forms // (for example, filesharing/advanced/kcm_sambaconf/share.ui) - if (implicitIncludes && isKDEClass(customClass)) { + if ((m_options & ImplicitIncludes) && isKDEClass(customClass)) { QString header = customClass.toLower(); header += QLatin1String(".h"); DomHeader *domHeader = new DomHeader; @@ -710,10 +710,13 @@ DomWidget *Ui3Reader::createWidget(const QDomElement &w, const QString &widgetCl ui_action_list.append(a); } else if (t == QLatin1String("property")) { // skip the property it is already handled by createProperties - - QString name = e.attribute(QLatin1String("name")); // change the varname this widget - if (name == QLatin1String("name")) - ui_widget->setAttributeName(DomTool::readProperty(w, QLatin1String("name"), QVariant()).toString()); + const QString name = e.attribute(QLatin1String("name")); // change the varname this widget + if (name == QLatin1String("name")) { + // Do not name QLayoutWidget if layout names are to be used. + const bool applyName = !(m_options & PreserveLayoutNames) || className != QLatin1String("QLayoutWidget"); + if (applyName) + ui_widget->setAttributeName(DomTool::readProperty(w, QLatin1String("name"), QVariant()).toString()); + } } else if (t == QLatin1String("row")) { DomRow *row = new DomRow(); row->read(e); @@ -797,6 +800,11 @@ DomLayout *Ui3Reader::createLayout(const QDomElement &w) createProperties(w, &ui_property_list, className); createAttributes(w, &ui_attribute_list, className); + if (m_options & PreserveLayoutNames) { + const QString layoutName = getLayoutName(w); + if (!layoutName.isEmpty()) + lay->setAttributeName(layoutName); + } QDomElement e = w.firstChild().toElement(); while (!e.isNull()) { diff --git a/src/tools/uic3/form.cpp b/src/tools/uic3/form.cpp index ac2668b..df1314f 100644 --- a/src/tools/uic3/form.cpp +++ b/src/tools/uic3/form.cpp @@ -100,7 +100,7 @@ QByteArray combinePath(const char *infile, const char *outfile) \sa createFormImpl() */ -void Ui3Reader::createFormDecl(const QDomElement &e, bool implicitIncludes) +void Ui3Reader::createFormDecl(const QDomElement &e) { QDomElement body = e; @@ -138,7 +138,7 @@ void Ui3Reader::createFormDecl(const QDomElement &e, bool implicitIncludes) QString tagName = n3.tagName().toLower(); if (tagName == QLatin1String("class")) { cl = n3.firstChild().toText().data(); - if (!nofwd) + if (m_options & CustomWidgetForwardDeclarations) forwardDecl << cl; customWidgets.insert(cl, 0); } else if (tagName == QLatin1String("header")) { @@ -257,10 +257,10 @@ void Ui3Reader::createFormDecl(const QDomElement &e, bool implicitIncludes) d.option().copyrightHeader = false; d.option().extractImages = m_extractImages; d.option().qrcOutputFile = m_qrcOutputFile; - d.option().implicitIncludes = implicitIncludes; + d.option().implicitIncludes = (m_options & ImplicitIncludes) ? 1 : 0; if (trmacro.size()) d.option().translateFunction = trmacro; - DomUI *ui = generateUi4(e, implicitIncludes); + DomUI *ui = generateUi4(e); d.uic(fileName, ui, &out); delete ui; diff --git a/src/tools/uic3/main.cpp b/src/tools/uic3/main.cpp index ecc345e..6acc94f 100644 --- a/src/tools/uic3/main.cpp +++ b/src/tools/uic3/main.cpp @@ -78,13 +78,11 @@ int runUic3(int argc, char * argv[]) QByteArray image_tmpfile; const char* projectName = 0; const char* trmacro = 0; - bool nofwd = false; bool fix = false; bool deps = false; - bool implicitIncludes = true; + unsigned readerOptions = Ui3Reader::ImplicitIncludes|Ui3Reader::CustomWidgetForwardDeclarations; QByteArray pchFile; - QApplication app(argc, argv, false); for (int n = 1; n < argc && error == 0; n++) { @@ -146,9 +144,11 @@ int runUic3(int argc, char * argv[]) } else if (opt == "d") { deps = true; } else if (opt == "no-implicit-includes") { - implicitIncludes = false; + readerOptions &= ~Ui3Reader::ImplicitIncludes; } else if (opt == "nofwd") { - nofwd = true; + readerOptions &= ~Ui3Reader::CustomWidgetForwardDeclarations; + } else if (opt == "layout-names") { + readerOptions |= Ui3Reader::PreserveLayoutNames; } else if (opt == "nounload") { // skip } else if (opt == "convert") { @@ -253,6 +253,7 @@ int runUic3(int argc, char * argv[]) "\t-extract qrcFile Create resource file and extract embedded images into \"image\" dir\n" "\t-pch file Add #include \"file\" as the first statement in implementation\n" "\t-nofwd Omit forward declarations of custom classes\n" + "\t-layout-names Preserve layout names of Qt Designer 3\n" "\t-no-implicit-includes Do not generate #include-directives for custom classes\n" "\t-nounload Do not unload plugins after processing\n" "\t-tr func Use func() instead of tr() for i18n\n" @@ -289,9 +290,8 @@ int runUic3(int argc, char * argv[]) QTextStream out(&fileOut); - Ui3Reader ui3(out); + Ui3Reader ui3(out, readerOptions); ui3.setExtractImages(extract, qrcOutputFile); - if (projectName && imagecollection) { out.setEncoding(QTextStream::Latin1); ui3.embed(projectName, images); @@ -349,7 +349,7 @@ int runUic3(int argc, char * argv[]) return 0; } else if (convert) { - ui3.generateUi4(QFile::decodeName(fileName), QFile::decodeName(outputFile), doc, implicitIncludes); + ui3.generateUi4(QFile::decodeName(fileName), QFile::decodeName(outputFile), doc); return 0; } @@ -388,8 +388,6 @@ int runUic3(int argc, char * argv[]) subcl, QString::fromUtf8(trmacro), QString::fromUtf8(className), - nofwd, - implicitIncludes, convertedUi); if (!protector.isEmpty()) { diff --git a/src/tools/uic3/ui3reader.cpp b/src/tools/uic3/ui3reader.cpp index 6c5bda3..fd50a19 100644 --- a/src/tools/uic3/ui3reader.cpp +++ b/src/tools/uic3/ui3reader.cpp @@ -176,7 +176,6 @@ void Ui3Reader::init() { outputFileName.clear(); trmacro.clear(); - nofwd = false; fileName.clear(); writeFunctImpl = true; @@ -241,11 +240,10 @@ QDomElement Ui3Reader::parse(const QDomDocument &doc) return widget; } -Ui3Reader::Ui3Reader(QTextStream &outStream) - : out(outStream), trout(&languageChangeBody) +Ui3Reader::Ui3Reader(QTextStream &outStream, unsigned options) : + m_options(options), out(outStream), trout(&languageChangeBody), + m_porting(new Porting), m_extractImages(false) { - m_porting = new Porting(); - m_extractImages = false; } Ui3Reader::~Ui3Reader() @@ -255,14 +253,13 @@ Ui3Reader::~Ui3Reader() void Ui3Reader::generate(const QString &fn, const QString &outputFn, QDomDocument doc, bool decl, bool subcl, const QString &trm, - const QString& subClass, bool omitForwardDecls, bool implicitIncludes, const QString &convertedUiFile) + const QString& subClass, const QString &convertedUiFile) { init(); fileName = fn; outputFileName = outputFn; trmacro = trm; - nofwd = omitForwardDecls; QDomElement e = parse(doc); @@ -281,21 +278,21 @@ void Ui3Reader::generate(const QString &fn, const QString &outputFn, createSubImpl(e, subClass); } else { if (decl) - createFormDecl(e, implicitIncludes); + createFormDecl(e); else createFormImpl(e); } } -void Ui3Reader::generateUi4(const QString &fn, const QString &outputFn, QDomDocument doc, bool implicitIncludes) +void Ui3Reader::generateUi4(const QString &fn, const QString &outputFn, QDomDocument doc) { init(); fileName = fn; outputFileName = outputFn; - DomUI *ui = generateUi4(parse(doc), implicitIncludes); + DomUI *ui = generateUi4(parse(doc)); if (!ui) return; @@ -317,11 +314,6 @@ void Ui3Reader::setTrMacro(const QString &trmacro) this->trmacro = trmacro; } -void Ui3Reader::setForwardDeclarationsEnabled(bool b) -{ - nofwd = !b; -} - void Ui3Reader::setOutputFileName(const QString &fileName) { outputFileName = fileName; diff --git a/src/tools/uic3/ui3reader.h b/src/tools/uic3/ui3reader.h index cd17835..144ef05 100644 --- a/src/tools/uic3/ui3reader.h +++ b/src/tools/uic3/ui3reader.h @@ -68,23 +68,24 @@ typedef QList<QPair<int, Color> > ColorGroup; class Ui3Reader { public: - Ui3Reader(QTextStream &stream); + enum Options { CustomWidgetForwardDeclarations = 0x1, ImplicitIncludes = 0x2, PreserveLayoutNames = 0x4 }; + + explicit Ui3Reader(QTextStream &stream, unsigned options); ~Ui3Reader(); void computeDeps(const QDomElement &e, QStringList &globalIncludes, QStringList &localIncludes, bool impl = false); - void generateUi4(const QString &fn, const QString &outputFn, QDomDocument doc, bool implicitIncludes); + void generateUi4(const QString &fn, const QString &outputFn, QDomDocument doc); void generate(const QString &fn, const QString &outputFn, QDomDocument doc, bool decl, bool subcl, const QString &trm, - const QString& subclname, bool omitForwardDecls, bool implicitIncludes, const QString &convertedUiFile); + const QString& subclname, const QString &convertedUiFile); void embed(const char *project, const QStringList &images); void setTrMacro(const QString &trmacro); - void setForwardDeclarationsEnabled(bool b); void setOutputFileName(const QString &fileName); - void createFormDecl(const QDomElement &e, bool implicitIncludes); + void createFormDecl(const QDomElement &e); void createFormImpl(const QDomElement &e); void createWrapperDecl(const QDomElement &e, const QString &convertedUiFile); @@ -125,7 +126,7 @@ private: void errorInvalidSlot(const QString &slot, const QString &widgetName, const QString &widgetClass, int line, int col); - DomUI *generateUi4(const QDomElement &e, bool implicitIncludes); + DomUI *generateUi4(const QDomElement &e); DomWidget *createWidget(const QDomElement &w, const QString &widgetClass = QString()); void createProperties(const QDomElement &e, QList<DomProperty*> *properties, const QString &className); void createAttributes(const QDomElement &e, QList<DomProperty*> *properties, const QString &className); @@ -145,6 +146,8 @@ private: void fixLayoutMargin(DomLayout *ui_layout); + const unsigned m_options; + QTextStream &out; QTextOStream trout; QString languageChangeBody; @@ -157,7 +160,6 @@ private: QString formName; QString lastItem; QString trmacro; - bool nofwd; struct Buddy { diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index 657c79a..cae959b 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -2596,11 +2596,15 @@ QDomNode QDomNode::removeChild(const QDomNode& oldChild) already has an element node as a child, \a newChild is not added as a child and a null node is returned. - Calling this function on a null node(created, for example, with the - default constructor) does nothing. + Returns a new reference to \a newChild on success or a \link + isNull() null node\endlink on failure. - The DOM specification disallow inserting attribute nodes, but due - to historical reasons QDom accept them nevertheless. + Calling this function on a null node(created, for example, with + the default constructor) does nothing and returns a \link isNull() + null node\endlink. + + The DOM specification disallow inserting attribute nodes, but for + historical reasons, QDom accepts them anyway. \sa insertBefore() insertAfter() replaceChild() removeChild() */ diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 9b91c7d..3198a65 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -569,3 +569,21 @@ contains(QT_CONFIG, webkit): SUBDIRS += \ qwebhistory contains(QT_CONFIG, declarative): SUBDIRS += declarative + +# Following tests depends on private API +!contains(QT_CONFIG, private_tests): SUBDIRS -= \ + qcssparser \ + qgraphicssceneindex \ + qhttpnetworkconnection \ + qhttpnetworkreply \ + qnativesocketengine \ + qnetworkreply \ + qpathclipper \ + qsocketnotifier \ + qsocks5socketengine \ + qstylesheetstyle \ + qtextpiecetable \ + xmlpatternsdiagnosticsts \ + xmlpatternsview \ + xmlpatternsxqts \ + xmlpatternsxslts diff --git a/tests/auto/declarative/qmlecmascript/data/assignBasicTypes.2.qml b/tests/auto/declarative/qmlecmascript/data/assignBasicTypes.2.qml new file mode 100644 index 0000000..db7f2b5 --- /dev/null +++ b/tests/auto/declarative/qmlecmascript/data/assignBasicTypes.2.qml @@ -0,0 +1,26 @@ +import Qt.test 1.0 + +MyTypeObject { + flagProperty: if(1) "FlagVal1 | FlagVal3" + enumProperty: if(1) "EnumVal2" + stringProperty: if(1) "Hello World!" + uintProperty: if(1) 10 + intProperty: if(1) -19 + realProperty: if(1) 23.2 + doubleProperty: if(1) -19.7 + floatProperty: if(1) 8.5 + colorProperty: if(1) "red" + dateProperty: if(1) "1982-11-25" + timeProperty: if(1) "11:11:32" + dateTimeProperty: if(1) "2009-05-12T13:22:01" + pointProperty: if(1) "99,13" + pointFProperty: if(1) "-10.1,12.3" + sizeProperty: if(1) "99x13" + sizeFProperty: if(1) "0.1x0.2" + rectProperty: if(1) "9,7,100x200" + rectFProperty: if(1) "1000.1,-10.9,400x90.99" + boolProperty: if(1) true + variantProperty: if(1) "Hello World!" + vectorProperty: if(1) "10,1,2.2" + urlProperty: if(1) "main.qml" +} diff --git a/tests/auto/declarative/qmlecmascript/data/undefinedResetsProperty.qml b/tests/auto/declarative/qmlecmascript/data/undefinedResetsProperty.qml new file mode 100644 index 0000000..eceff60 --- /dev/null +++ b/tests/auto/declarative/qmlecmascript/data/undefinedResetsProperty.qml @@ -0,0 +1,7 @@ +import Qt.test 1.0 + +MyQmlObject { + property bool setUndefined: false + + resettableProperty: setUndefined?undefined:92 +} diff --git a/tests/auto/declarative/qmlecmascript/testtypes.h b/tests/auto/declarative/qmlecmascript/testtypes.h index fff9246..09c850d 100644 --- a/tests/auto/declarative/qmlecmascript/testtypes.h +++ b/tests/auto/declarative/qmlecmascript/testtypes.h @@ -48,7 +48,13 @@ #include <QtCore/qsize.h> #include <QtDeclarative/qmllist.h> #include <QtCore/qrect.h> +#include <QtGui/qmatrix.h> +#include <QtGui/qcolor.h> +#include <QtGui/qvector3d.h> +#include <QtCore/qdatetime.h> #include <QtScript/qscriptvalue.h> +#include <QtDeclarative/qmlscriptstring.h> +#include <QtDeclarative/qmlcomponent.h> class MyQmlAttachedObject : public QObject { @@ -73,9 +79,10 @@ class MyQmlObject : public QObject Q_PROPERTY(QObject *objectProperty READ objectProperty WRITE setObjectProperty NOTIFY objectChanged) Q_PROPERTY(QmlList<QObject *> *objectQmlListProperty READ objectQmlListProperty CONSTANT) Q_PROPERTY(QList<QObject *> *objectListProperty READ objectListProperty CONSTANT) + Q_PROPERTY(int resettableProperty READ resettableProperty WRITE setResettableProperty RESET resetProperty) public: - MyQmlObject(): m_methodCalled(false), m_methodIntCalled(false), m_object(0), m_value(0) {} + MyQmlObject(): m_methodCalled(false), m_methodIntCalled(false), m_object(0), m_value(0), m_resetProperty(13) {} enum MyEnum { EnumValue1 = 0, EnumValue2 = 1 }; enum MyEnum2 { EnumValue3 = 2, EnumValue4 = 3 }; @@ -117,6 +124,11 @@ public: int value() const { return m_value; } void setValue(int v) { m_value = v; } + + int resettableProperty() const { return m_resetProperty; } + void setResettableProperty(int v) { m_resetProperty = v; } + void resetProperty() { m_resetProperty = 13; } + signals: void basicSignal(); void argumentSignal(int a, QString b, qreal c); @@ -141,6 +153,7 @@ private: QmlConcreteList<QObject *> m_objectQmlList; QList<QObject *> m_objectQList; int m_value; + int m_resetProperty; }; QML_DECLARE_TYPEINFO(MyQmlObject, QML_HAS_ATTACHED_PROPERTIES) @@ -149,7 +162,7 @@ QML_DECLARE_TYPE(MyQmlObject); class MyQmlContainer : public QObject { Q_OBJECT - Q_PROPERTY(QList<MyQmlObject*>* children READ children) + Q_PROPERTY(QList<MyQmlObject*>* children READ children CONSTANT) public: MyQmlContainer() {} @@ -271,15 +284,164 @@ QML_DECLARE_TYPE(MyExtendedObject); class MyTypeObject : public QObject { Q_OBJECT + Q_ENUMS(MyEnum) + Q_FLAGS(MyFlags) + + Q_PROPERTY(QString id READ id WRITE setId); + Q_PROPERTY(QObject *objectProperty READ objectProperty WRITE setObjectProperty); + Q_PROPERTY(QmlComponent *componentProperty READ componentProperty WRITE setComponentProperty); + Q_PROPERTY(MyFlags flagProperty READ flagProperty WRITE setFlagProperty); + Q_PROPERTY(MyEnum enumProperty READ enumProperty WRITE setEnumProperty); + Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty); + Q_PROPERTY(uint uintProperty READ uintProperty WRITE setUintProperty); + Q_PROPERTY(int intProperty READ intProperty WRITE setIntProperty); + Q_PROPERTY(qreal realProperty READ realProperty WRITE setRealProperty); + Q_PROPERTY(double doubleProperty READ doubleProperty WRITE setDoubleProperty); + Q_PROPERTY(float floatProperty READ floatProperty WRITE setFloatProperty); + Q_PROPERTY(QColor colorProperty READ colorProperty WRITE setColorProperty); + Q_PROPERTY(QDate dateProperty READ dateProperty WRITE setDateProperty); + Q_PROPERTY(QTime timeProperty READ timeProperty WRITE setTimeProperty); + Q_PROPERTY(QDateTime dateTimeProperty READ dateTimeProperty WRITE setDateTimeProperty); Q_PROPERTY(QPoint pointProperty READ pointProperty WRITE setPointProperty); Q_PROPERTY(QPointF pointFProperty READ pointFProperty WRITE setPointFProperty); Q_PROPERTY(QSize sizeProperty READ sizeProperty WRITE setSizeProperty); Q_PROPERTY(QSizeF sizeFProperty READ sizeFProperty WRITE setSizeFProperty); Q_PROPERTY(QRect rectProperty READ rectProperty WRITE setRectProperty NOTIFY rectPropertyChanged); + Q_PROPERTY(QRect rectProperty2 READ rectProperty2 WRITE setRectProperty2); Q_PROPERTY(QRectF rectFProperty READ rectFProperty WRITE setRectFProperty); - + Q_PROPERTY(bool boolProperty READ boolProperty WRITE setBoolProperty); + Q_PROPERTY(QVariant variantProperty READ variantProperty WRITE setVariantProperty); + Q_PROPERTY(QVector3D vectorProperty READ vectorProperty WRITE setVectorProperty); + Q_PROPERTY(QUrl urlProperty READ urlProperty WRITE setUrlProperty); + + Q_PROPERTY(QmlScriptString scriptProperty READ scriptProperty WRITE setScriptProperty); + public: - MyTypeObject() {} + MyTypeObject() + : objectPropertyValue(0), componentPropertyValue(0) {} + + QString idValue; + QString id() const { + return idValue; + } + void setId(const QString &v) { + idValue = v; + } + + QObject *objectPropertyValue; + QObject *objectProperty() const { + return objectPropertyValue; + } + void setObjectProperty(QObject *v) { + objectPropertyValue = v; + } + + QmlComponent *componentPropertyValue; + QmlComponent *componentProperty() const { + return componentPropertyValue; + } + void setComponentProperty(QmlComponent *v) { + componentPropertyValue = v; + } + + enum MyFlag { FlagVal1 = 0x01, FlagVal2 = 0x02, FlagVal3 = 0x04 }; + Q_DECLARE_FLAGS(MyFlags, MyFlag) + MyFlags flagPropertyValue; + MyFlags flagProperty() const { + return flagPropertyValue; + } + void setFlagProperty(MyFlags v) { + flagPropertyValue = v; + } + + enum MyEnum { EnumVal1, EnumVal2 }; + MyEnum enumPropertyValue; + MyEnum enumProperty() const { + return enumPropertyValue; + } + void setEnumProperty(MyEnum v) { + enumPropertyValue = v; + } + + QString stringPropertyValue; + QString stringProperty() const { + return stringPropertyValue; + } + void setStringProperty(const QString &v) { + stringPropertyValue = v; + } + + uint uintPropertyValue; + uint uintProperty() const { + return uintPropertyValue; + } + void setUintProperty(const uint &v) { + uintPropertyValue = v; + } + + int intPropertyValue; + int intProperty() const { + return intPropertyValue; + } + void setIntProperty(const int &v) { + intPropertyValue = v; + } + + qreal realPropertyValue; + qreal realProperty() const { + return realPropertyValue; + } + void setRealProperty(const qreal &v) { + realPropertyValue = v; + } + + double doublePropertyValue; + double doubleProperty() const { + return doublePropertyValue; + } + void setDoubleProperty(const double &v) { + doublePropertyValue = v; + } + + float floatPropertyValue; + float floatProperty() const { + return floatPropertyValue; + } + void setFloatProperty(const float &v) { + floatPropertyValue = v; + } + + QColor colorPropertyValue; + QColor colorProperty() const { + return colorPropertyValue; + } + void setColorProperty(const QColor &v) { + colorPropertyValue = v; + } + + QDate datePropertyValue; + QDate dateProperty() const { + return datePropertyValue; + } + void setDateProperty(const QDate &v) { + datePropertyValue = v; + } + + QTime timePropertyValue; + QTime timeProperty() const { + return timePropertyValue; + } + void setTimeProperty(const QTime &v) { + timePropertyValue = v; + } + + QDateTime dateTimePropertyValue; + QDateTime dateTimeProperty() const { + return dateTimePropertyValue; + } + void setDateTimeProperty(const QDateTime &v) { + dateTimePropertyValue = v; + } QPoint pointPropertyValue; QPoint pointProperty() const { @@ -319,6 +481,15 @@ public: } void setRectProperty(const QRect &v) { rectPropertyValue = v; + emit rectPropertyChanged(); + } + + QRect rectPropertyValue2; + QRect rectProperty2() const { + return rectPropertyValue2; + } + void setRectProperty2(const QRect &v) { + rectPropertyValue2 = v; } QRectF rectFPropertyValue; @@ -329,7 +500,52 @@ public: rectFPropertyValue = v; } + bool boolPropertyValue; + bool boolProperty() const { + return boolPropertyValue; + } + void setBoolProperty(const bool &v) { + boolPropertyValue = v; + } + + QVariant variantPropertyValue; + QVariant variantProperty() const { + return variantPropertyValue; + } + void setVariantProperty(const QVariant &v) { + variantPropertyValue = v; + } + + QVector3D vectorPropertyValue; + QVector3D vectorProperty() const { + return vectorPropertyValue; + } + void setVectorProperty(const QVector3D &v) { + vectorPropertyValue = v; + } + + QUrl urlPropertyValue; + QUrl urlProperty() const { + return urlPropertyValue; + } + void setUrlProperty(const QUrl &v) { + urlPropertyValue = v; + } + + QmlScriptString scriptPropertyValue; + QmlScriptString scriptProperty() const { + return scriptPropertyValue; + } + void setScriptProperty(const QmlScriptString &v) { + scriptPropertyValue = v; + } + + void doAction() { emit action(); } +signals: + void action(); + void rectPropertyChanged(); }; +Q_DECLARE_OPERATORS_FOR_FLAGS(MyTypeObject::MyFlags) QML_DECLARE_TYPE(MyTypeObject); Q_DECLARE_METATYPE(QScriptValue); diff --git a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp index 4c9721a..c41e248 100644 --- a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp +++ b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp @@ -76,6 +76,7 @@ public: tst_qmlecmascript() {} private slots: + void assignBasicTypes(); void idShortcutInvalidates(); void boolPropertiesEvaluateAsBool(); void methods(); @@ -116,6 +117,8 @@ private slots: void externalScript(); void compositePropertyType(); void jsObject(); + void undefinedResetsProperty(); + void listToVariant(); void bug1(); @@ -124,6 +127,66 @@ private: QmlEngine engine; }; +void tst_qmlecmascript::assignBasicTypes() +{ + { + QmlComponent component(&engine, TEST_FILE("assignBasicTypes.qml")); + MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->flagProperty(), MyTypeObject::FlagVal1 | MyTypeObject::FlagVal3); + QCOMPARE(object->enumProperty(), MyTypeObject::EnumVal2); + QCOMPARE(object->stringProperty(), QString("Hello World!")); + QCOMPARE(object->uintProperty(), uint(10)); + QCOMPARE(object->intProperty(), -19); + QCOMPARE((float)object->realProperty(), float(23.2)); + QCOMPARE((float)object->doubleProperty(), float(-19.7)); + QCOMPARE((float)object->floatProperty(), float(8.5)); + QCOMPARE(object->colorProperty(), QColor("red")); + QCOMPARE(object->dateProperty(), QDate(1982, 11, 25)); + QCOMPARE(object->timeProperty(), QTime(11, 11, 32)); + QCOMPARE(object->dateTimeProperty(), QDateTime(QDate(2009, 5, 12), QTime(13, 22, 1))); + QCOMPARE(object->pointProperty(), QPoint(99,13)); + QCOMPARE(object->pointFProperty(), QPointF(-10.1, 12.3)); + QCOMPARE(object->sizeProperty(), QSize(99, 13)); + QCOMPARE(object->sizeFProperty(), QSizeF(0.1, 0.2)); + QCOMPARE(object->rectProperty(), QRect(9, 7, 100, 200)); + QCOMPARE(object->rectFProperty(), QRectF(1000.1, -10.9, 400, 90.99)); + QCOMPARE(object->boolProperty(), true); + QCOMPARE(object->variantProperty(), QVariant("Hello World!")); + QCOMPARE(object->vectorProperty(), QVector3D(10, 1, 2.2)); + QCOMPARE(object->urlProperty(), component.url().resolved(QUrl("main.qml"))); + delete object; + } + { + QmlComponent component(&engine, TEST_FILE("assignBasicTypes.2.qml")); + MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->flagProperty(), MyTypeObject::FlagVal1 | MyTypeObject::FlagVal3); + QCOMPARE(object->enumProperty(), MyTypeObject::EnumVal2); + QCOMPARE(object->stringProperty(), QString("Hello World!")); + QCOMPARE(object->uintProperty(), uint(10)); + QCOMPARE(object->intProperty(), -19); + QCOMPARE((float)object->realProperty(), float(23.2)); + QCOMPARE((float)object->doubleProperty(), float(-19.7)); + QCOMPARE((float)object->floatProperty(), float(8.5)); + QCOMPARE(object->colorProperty(), QColor("red")); + QCOMPARE(object->dateProperty(), QDate(1982, 11, 25)); + QCOMPARE(object->timeProperty(), QTime(11, 11, 32)); + QCOMPARE(object->dateTimeProperty(), QDateTime(QDate(2009, 5, 12), QTime(13, 22, 1))); + QCOMPARE(object->pointProperty(), QPoint(99,13)); + QCOMPARE(object->pointFProperty(), QPointF(-10.1, 12.3)); + QCOMPARE(object->sizeProperty(), QSize(99, 13)); + QCOMPARE(object->sizeFProperty(), QSizeF(0.1, 0.2)); + QCOMPARE(object->rectProperty(), QRect(9, 7, 100, 200)); + QCOMPARE(object->rectFProperty(), QRectF(1000.1, -10.9, 400, 90.99)); + QCOMPARE(object->boolProperty(), true); + QCOMPARE(object->variantProperty(), QVariant("Hello World!")); + QCOMPARE(object->vectorProperty(), QVector3D(10, 1, 2.2)); + QCOMPARE(object->urlProperty(), component.url().resolved(QUrl("main.qml"))); + delete object; + } +} + void tst_qmlecmascript::idShortcutInvalidates() { { @@ -1075,6 +1138,40 @@ void tst_qmlecmascript::jsObject() delete object; } +void tst_qmlecmascript::undefinedResetsProperty() +{ + { + QmlComponent component(&engine, TEST_FILE("undefinedResetsProperty.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("resettableProperty").toInt(), 92); + + object->setProperty("setUndefined", true); + + QCOMPARE(object->property("resettableProperty").toInt(), 13); + + object->setProperty("setUndefined", false); + + QCOMPARE(object->property("resettableProperty").toInt(), 92); + + delete object; + } + { + QmlComponent component(&engine, TEST_FILE("undefinedResetsProperty.2.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("resettableProperty").toInt(), 19); + + QMetaObject::invokeMethod(object, "doReset"); + + QCOMPARE(object->property("resettableProperty").toInt(), 13); + + delete object; + } +} + // QTBUG-6781 void tst_qmlecmascript::bug1() { @@ -1497,6 +1594,25 @@ void tst_qmlecmascript::callQtInvokables() QCOMPARE(o.actuals().at(1), QVariant(11)); } +// QTBUG-5675 +void tst_qmlecmascript::listToVariant() +{ + QmlComponent component(&engine, TEST_FILE("listToVariant.qml")); + + MyQmlContainer container; + + QmlContext context(engine.rootContext()); + context.addDefaultObject(&container); + + QObject *object = component.create(&context); + QVERIFY(object != 0); + + QCOMPARE(object->property("test"), QVariant::fromValue(container.children())); + + delete object; + +} + QTEST_MAIN(tst_qmlecmascript) #include "tst_qmlecmascript.moc" diff --git a/tests/auto/declarative/qmlmetaproperty/tst_qmlmetaproperty.cpp b/tests/auto/declarative/qmlmetaproperty/tst_qmlmetaproperty.cpp index a44ea6e..ec6b87f 100644 --- a/tests/auto/declarative/qmlmetaproperty/tst_qmlmetaproperty.cpp +++ b/tests/auto/declarative/qmlmetaproperty/tst_qmlmetaproperty.cpp @@ -113,6 +113,7 @@ private slots: void name(); void read(); void write(); + void reset(); // Functionality void writeObjectToList(); @@ -153,6 +154,7 @@ void tst_qmlmetaproperty::qmlmetaproperty() QCOMPARE(prop.isDefault(), false); QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), false); + QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), false); QCOMPARE(prop.object(), (QObject *)0); QCOMPARE(prop.propertyCategory(), QmlMetaProperty::InvalidProperty); @@ -178,9 +180,12 @@ class PropertyObject : public QObject Q_PROPERTY(QRect rectProperty READ rectProperty); Q_PROPERTY(QRect wrectProperty READ wrectProperty WRITE setWRectProperty); Q_PROPERTY(QUrl url READ url WRITE setUrl); + Q_PROPERTY(int resettableProperty READ resettableProperty WRITE setResettableProperty RESET resetProperty); Q_CLASSINFO("DefaultProperty", "defaultProperty"); public: + PropertyObject() : m_resetProperty(9) {} + int defaultProperty() { return 10; } QRect rectProperty() { return QRect(10, 10, 1, 209); } @@ -190,10 +195,15 @@ public: QUrl url() { return m_url; } void setUrl(const QUrl &u) { m_url = u; } + int resettableProperty() const { return m_resetProperty; } + void setResettableProperty(int r) { m_resetProperty = r; } + void resetProperty() { m_resetProperty = 9; } + signals: void clicked(); private: + int m_resetProperty; QRect m_rect; QUrl m_url; }; @@ -230,6 +240,7 @@ void tst_qmlmetaproperty::qmlmetaproperty_object() QCOMPARE(prop.isDefault(), false); QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), false); + QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), false); QCOMPARE(prop.object(), (QObject *)0); QCOMPARE(prop.propertyCategory(), QmlMetaProperty::InvalidProperty); @@ -276,6 +287,7 @@ void tst_qmlmetaproperty::qmlmetaproperty_object() QCOMPARE(prop.isDefault(), true); QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), true); + QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); QCOMPARE(prop.object(), &dobject); QCOMPARE(prop.propertyCategory(), QmlMetaProperty::Normal); @@ -329,6 +341,7 @@ void tst_qmlmetaproperty::qmlmetaproperty_object_string() QCOMPARE(prop.isDefault(), false); QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), false); + QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), false); QCOMPARE(prop.object(), (QObject *)0); QCOMPARE(prop.propertyCategory(), QmlMetaProperty::InvalidProperty); @@ -375,6 +388,7 @@ void tst_qmlmetaproperty::qmlmetaproperty_object_string() QCOMPARE(prop.isDefault(), false); QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), true); + QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); QCOMPARE(prop.object(), &dobject); QCOMPARE(prop.propertyCategory(), QmlMetaProperty::Normal); @@ -423,6 +437,7 @@ void tst_qmlmetaproperty::qmlmetaproperty_object_string() QCOMPARE(prop.isDefault(), false); QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), false); + QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); QCOMPARE(prop.object(), &dobject); QCOMPARE(prop.propertyCategory(), QmlMetaProperty::InvalidProperty); @@ -475,6 +490,7 @@ void tst_qmlmetaproperty::qmlmetaproperty_object_context() QCOMPARE(prop.isDefault(), false); QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), false); + QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), false); QCOMPARE(prop.object(), (QObject *)0); QCOMPARE(prop.propertyCategory(), QmlMetaProperty::InvalidProperty); @@ -521,6 +537,7 @@ void tst_qmlmetaproperty::qmlmetaproperty_object_context() QCOMPARE(prop.isDefault(), true); QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), true); + QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); QCOMPARE(prop.object(), &dobject); QCOMPARE(prop.propertyCategory(), QmlMetaProperty::Normal); @@ -574,6 +591,7 @@ void tst_qmlmetaproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.isDefault(), false); QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), false); + QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), false); QCOMPARE(prop.object(), (QObject *)0); QCOMPARE(prop.propertyCategory(), QmlMetaProperty::InvalidProperty); @@ -620,6 +638,7 @@ void tst_qmlmetaproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.isDefault(), false); QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), true); + QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); QCOMPARE(prop.object(), &dobject); QCOMPARE(prop.propertyCategory(), QmlMetaProperty::Normal); @@ -668,6 +687,7 @@ void tst_qmlmetaproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.isDefault(), false); QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), false); + QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); QCOMPARE(prop.object(), &dobject); QCOMPARE(prop.propertyCategory(), QmlMetaProperty::InvalidProperty); @@ -973,6 +993,79 @@ void tst_qmlmetaproperty::write() } } +void tst_qmlmetaproperty::reset() +{ + // Invalid + { + QmlMetaProperty p; + QCOMPARE(p.isResettable(), false); + QCOMPARE(p.reset(), false); + } + + // Read-only default prop + { + PropertyObject o; + QmlMetaProperty p(&o); + QCOMPARE(p.isResettable(), false); + QCOMPARE(p.reset(), false); + } + + // Invalid default prop + { + QObject o; + QmlMetaProperty p(&o); + QCOMPARE(p.isResettable(), false); + QCOMPARE(p.reset(), false); + } + + // Non-resettable-only prop by name + { + PropertyObject o; + QmlMetaProperty p(&o, QString("defaultProperty")); + QCOMPARE(p.isResettable(), false); + QCOMPARE(p.reset(), false); + } + + // Resettable prop by name + { + PropertyObject o; + QmlMetaProperty p(&o, QString("resettableProperty")); + + QCOMPARE(p.read(), QVariant(9)); + QCOMPARE(p.write(QVariant(11)), true); + QCOMPARE(p.read(), QVariant(11)); + + QCOMPARE(p.isResettable(), true); + QCOMPARE(p.reset(), true); + + QCOMPARE(p.read(), QVariant(9)); + } + + // Deleted object + { + PropertyObject *o = new PropertyObject; + + QmlMetaProperty p(o, QString("resettableProperty")); + + QCOMPARE(p.isResettable(), true); + QCOMPARE(p.reset(), true); + + delete o; + + QCOMPARE(p.isResettable(), false); + QCOMPARE(p.reset(), false); + } + + // Signal property + { + PropertyObject o; + QmlMetaProperty p(&o, "onClicked"); + + QCOMPARE(p.isResettable(), false); + QCOMPARE(p.reset(), false); + } +} + void tst_qmlmetaproperty::writeObjectToList() { QmlComponent containerComponent(&engine); diff --git a/tests/auto/qbytearray/tst_qbytearray.cpp b/tests/auto/qbytearray/tst_qbytearray.cpp index 35e4463..5c72c7a 100644 --- a/tests/auto/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/qbytearray/tst_qbytearray.cpp @@ -76,6 +76,7 @@ private slots: void qCompress(); void qUncompress_data(); void qUncompress(); + void qCompressionZeroTermination(); #endif void constByteArray(); void leftJustified(); @@ -261,6 +262,14 @@ void tst_QByteArray::qUncompress() } QCOMPARE(res, out); } + +void tst_QByteArray::qCompressionZeroTermination() +{ + QString s = "Hello, I'm a string."; + QByteArray ba = ::qUncompress(::qCompress(s.toLocal8Bit())); + QVERIFY((int) *(ba.data() + ba.size()) == 0); +} + #endif void tst_QByteArray::constByteArray() diff --git a/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp b/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp index 51e2a57..795431b 100644 --- a/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp +++ b/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp @@ -71,6 +71,7 @@ private slots: void colorize(); void drawPixmapItem(); void deviceCoordinateTranslateCaching(); + void inheritOpacity(); }; void tst_QGraphicsEffect::initTestCase() @@ -79,8 +80,8 @@ void tst_QGraphicsEffect::initTestCase() class CustomItem : public QGraphicsRectItem { public: - CustomItem(qreal x, qreal y, qreal width, qreal height) - : QGraphicsRectItem(x, y, width, height), numRepaints(0), + CustomItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent = 0) + : QGraphicsRectItem(x, y, width, height, parent), numRepaints(0), m_painter(0), m_styleOption(0) {} @@ -560,6 +561,35 @@ void tst_QGraphicsEffect::deviceCoordinateTranslateCaching() QVERIFY(item->numRepaints == numRepaints); } +void tst_QGraphicsEffect::inheritOpacity() +{ + QGraphicsScene scene; + QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 10, 10); + CustomItem *item = new CustomItem(0, 0, 10, 10, rectItem); + + scene.addItem(rectItem); + + item->setGraphicsEffect(new DeviceEffect); + item->setPen(Qt::NoPen); + item->setBrush(Qt::red); + + rectItem->setOpacity(0.5); + + QGraphicsView view(&scene); + view.show(); + QTest::qWaitForWindowShown(&view); + + QTRY_VERIFY(item->numRepaints >= 1); + + int numRepaints = item->numRepaints; + + rectItem->setOpacity(1); + QTest::qWait(50); + + // item should have been rerendered due to opacity changing + QTRY_VERIFY(item->numRepaints > numRepaints); +} + QTEST_MAIN(tst_QGraphicsEffect) #include "tst_qgraphicseffect.moc" diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 8e43bce..14b9ef0 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -316,6 +316,7 @@ private slots: void childrenBoundingRectTransformed(); void childrenBoundingRect2(); void childrenBoundingRect3(); + void childrenBoundingRect4(); void group(); void setGroup(); void setGroup2(); @@ -417,6 +418,7 @@ private slots: void task197802_childrenVisibility(); void QTBUG_4233_updateCachedWithSceneRect(); void QTBUG_5418_textItemSetDefaultColor(); + void QTBUG_6738_missingUpdateWithSetParent(); private: QList<QGraphicsItem *> paintedItems; @@ -3257,6 +3259,32 @@ void tst_QGraphicsItem::childrenBoundingRect3() QCOMPARE(subTreeRect.height(), qreal(251.7766952966369)); } +void tst_QGraphicsItem::childrenBoundingRect4() +{ + QGraphicsScene scene; + + QGraphicsRectItem *rect = scene.addRect(QRectF(0, 0, 10, 10)); + QGraphicsRectItem *rect2 = scene.addRect(QRectF(0, 0, 20, 20)); + QGraphicsRectItem *rect3 = scene.addRect(QRectF(0, 0, 30, 30)); + rect2->setParentItem(rect); + rect3->setParentItem(rect); + + QGraphicsView view(&scene); + view.show(); + + QTest::qWaitForWindowShown(&view); + + // Try to mess up the cached bounding rect. + rect->childrenBoundingRect(); + rect2->childrenBoundingRect(); + + rect3->setOpacity(0.0); + rect3->setParentItem(rect2); + + QCOMPARE(rect->childrenBoundingRect(), rect3->boundingRect()); + QCOMPARE(rect2->childrenBoundingRect(), rect3->boundingRect()); +} + void tst_QGraphicsItem::group() { QGraphicsScene scene; @@ -9869,5 +9897,63 @@ void tst_QGraphicsItem::QTBUG_5418_textItemSetDefaultColor() QCOMPARE(i->painted, 0); //same color as before should not trigger an update (QTBUG-6242) } +void tst_QGraphicsItem::QTBUG_6738_missingUpdateWithSetParent() +{ + // In all 3 test cases below the reparented item should disappear + EventTester *parent = new EventTester; + EventTester *child = new EventTester(parent); + EventTester *child2 = new EventTester(parent); + EventTester *child3 = new EventTester(parent); + EventTester *child4 = new EventTester(parent); + + child->setPos(10, 10); + child2->setPos(20, 20); + child3->setPos(30, 30); + child4->setPos(40, 40); + + QGraphicsScene scene; + scene.addItem(parent); + + class MyGraphicsView : public QGraphicsView + { public: + int repaints; + QRegion paintedRegion; + MyGraphicsView(QGraphicsScene *scene) : QGraphicsView(scene), repaints(0) {} + void paintEvent(QPaintEvent *e) + { + ++repaints; + paintedRegion += e->region(); + QGraphicsView::paintEvent(e); + } + void reset() { repaints = 0; paintedRegion = QRegion(); } + }; + + MyGraphicsView view(&scene); + view.show(); + QTest::qWaitForWindowShown(&view); + QTRY_VERIFY(view.repaints > 0); + + // test case #1 + view.reset(); + child2->setVisible(false); + child2->setParentItem(child); + + QTRY_VERIFY(view.repaints == 1); + + // test case #2 + view.reset(); + child3->setOpacity(0.0); + child3->setParentItem(child); + + QTRY_VERIFY(view.repaints == 1); + + // test case #3 + view.reset(); + child4->setParentItem(child); + child4->setVisible(false); + + QTRY_VERIFY(view.repaints == 1); +} + QTEST_MAIN(tst_QGraphicsItem) #include "tst_qgraphicsitem.moc" diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index c08a628e..6743fbe 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -270,6 +270,7 @@ private slots: void initialFocus_data(); void initialFocus(); void polishItems(); + void polishItems2(); void isActive(); void siblingIndexAlwaysValid(); @@ -3942,14 +3943,23 @@ void tst_QGraphicsScene::initialFocus() class PolishItem : public QGraphicsTextItem { public: - PolishItem(QGraphicsItem *parent = 0) : QGraphicsTextItem(parent) { } + PolishItem(QGraphicsItem *parent = 0) + : QGraphicsTextItem(parent), polished(false), deleteChildrenInPolish(true), addChildrenInPolish(false) { } + bool polished; + bool deleteChildrenInPolish; + bool addChildrenInPolish; protected: QVariant itemChange(GraphicsItemChange change, const QVariant& value) { if (change == ItemVisibleChange) { - if (value.toBool()) + polished = true; + if (deleteChildrenInPolish) qDeleteAll(childItems()); + if (addChildrenInPolish) { + for (int i = 0; i < 10; ++i) + new PolishItem(this); + } } return QGraphicsItem::itemChange(change, value); } @@ -3966,6 +3976,35 @@ void tst_QGraphicsScene::polishItems() QMetaObject::invokeMethod(&scene,"_q_polishItems"); } +void tst_QGraphicsScene::polishItems2() +{ + QGraphicsScene scene; + PolishItem *item = new PolishItem; + item->addChildrenInPolish = true; + item->deleteChildrenInPolish = true; + // These children should be deleted in the polish. + for (int i = 0; i < 20; ++i) + new PolishItem(item); + scene.addItem(item); + + // Wait for the polish event to be delivered. + QVERIFY(!item->polished); + QApplication::sendPostedEvents(&scene, QEvent::MetaCall); + QVERIFY(item->polished); + + // We deleted the children we added above, but we also + // added 10 new children. These should be polished in the next + // event loop iteration. + QList<QGraphicsItem *> children = item->childItems(); + QCOMPARE(children.count(), 10); + foreach (QGraphicsItem *child, children) + QVERIFY(!static_cast<PolishItem *>(child)->polished); + + QApplication::sendPostedEvents(&scene, QEvent::MetaCall); + foreach (QGraphicsItem *child, children) + QVERIFY(static_cast<PolishItem *>(child)->polished); +} + void tst_QGraphicsScene::isActive() { QGraphicsScene scene1; diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index 909ea54..d3132fe 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -163,6 +163,7 @@ private slots: void addChildInpolishEvent(); void polishEvent(); void polishEvent2(); + void initialShow(); // Task fixes void task236127_bspTreeIndexFails(); @@ -2856,6 +2857,30 @@ void tst_QGraphicsWidget::polishEvent2() QVERIFY(widget->events.contains(QEvent::Polish)); } +void tst_QGraphicsWidget::initialShow() +{ + class MyGraphicsWidget : public QGraphicsWidget + { public: + MyGraphicsWidget() : repaints(0) {} + int repaints; + void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget*) { ++repaints; } + void polishEvent() { update(); } + }; + + QGraphicsScene scene; + MyGraphicsWidget *widget = new MyGraphicsWidget; + + QGraphicsView view(&scene); + view.show(); + QTest::qWaitForWindowShown(&view); + + QTest::qWait(100); + scene.addItem(widget); + QTest::qWait(100); + + QCOMPARE(widget->repaints, 1); +} + void tst_QGraphicsWidget::QT_BUG_6544_tabFocusFirstUnsetWhenRemovingItems() { QGraphicsScene scene; diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index 2340ef5..8bcd5e8 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -171,6 +171,8 @@ private slots: void preserveDepth(); void splash_crash(); + + void loadAsBitmapOrPixmap(); }; static bool lenientCompare(const QPixmap &actual, const QPixmap &expected) @@ -1510,5 +1512,41 @@ void tst_QPixmap::preserveDepth() QCOMPARE(depth, source.depth()); } +void tst_QPixmap::loadAsBitmapOrPixmap() +{ + QImage tmp(10, 10, QImage::Format_RGB32); + tmp.save("tmp.png"); + + bool ok; + + // Check that we can load the pixmap as a pixmap and that it then turns into a pixmap + QPixmap pixmap("tmp.png"); + QVERIFY(!pixmap.isNull()); + QVERIFY(pixmap.depth() > 1); + QVERIFY(!pixmap.isQBitmap()); + + pixmap = QPixmap(); + ok = pixmap.load("tmp.png"); + QVERIFY(ok); + QVERIFY(!pixmap.isNull()); + QVERIFY(pixmap.depth() > 1); + QVERIFY(!pixmap.isQBitmap()); + + // The do the same check for bitmaps.. + QBitmap bitmap("tmp.png"); + QVERIFY(!bitmap.isNull()); + QVERIFY(bitmap.depth() == 1); + QVERIFY(bitmap.isQBitmap()); + + bitmap = QBitmap(); + ok = bitmap.load("tmp.png"); + QVERIFY(ok); + QVERIFY(!bitmap.isNull()); + QVERIFY(bitmap.depth() == 1); + QVERIFY(bitmap.isQBitmap()); +} + + + QTEST_MAIN(tst_QPixmap) #include "tst_qpixmap.moc" diff --git a/tests/auto/qsslcertificate/more-certificates/malformed-just-begin-no-newline.pem b/tests/auto/qsslcertificate/more-certificates/malformed-just-begin-no-newline.pem new file mode 100644 index 0000000..75f3c32 --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/malformed-just-begin-no-newline.pem @@ -0,0 +1 @@ +-----BEGIN CERTIFICATE-----
\ No newline at end of file diff --git a/tests/auto/qsslcertificate/more-certificates/malformed-just-begin.pem b/tests/auto/qsslcertificate/more-certificates/malformed-just-begin.pem new file mode 100644 index 0000000..a71aecf --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/malformed-just-begin.pem @@ -0,0 +1 @@ +-----BEGIN CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/more-certificates/no-ending-newline.pem b/tests/auto/qsslcertificate/more-certificates/no-ending-newline.pem new file mode 100644 index 0000000..f8056c7 --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/no-ending-newline.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB8zCCAVwCAREwDQYJKoZIhvcNAQEFBQAwWzELMAkGA1UEBhMCQVUxEzARBgNV +BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYD +VQQDExJUZXN0IENBICgxMDI0IGJpdCkwHhcNMDcwNDE3MDc0MDI2WhcNMDcwNTE3 +MDc0MDI2WjApMRowGAYDVQQDExFuYW1lL3dpdGgvc2xhc2hlczELMAkGA1UEBhMC +Tk8wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOud6QOsME+pWANExxgmL0iT +1ayg++hTxHsqAYnm/FoMxfUh+NdKkgJn2/GfNppinfPOSI667VqonU+7JBZDTLV5 +CPbZIo9fFQpDJQN6naev4yaxU1VeYFfI7S8c8zYKeGSR+RenNNeLvfH80YxPpZZ1 +snv8IfDH2V8MVxiyr7lLAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAleaU4pgzV6KY ++q9QuXapUYMsC2GiNtDmkG3k+MTHUO8XlE4hqPrIM6rRf7zKQdZ950R2wL9FSnYl +Qm1Tdv38dCka6ivMBqvRuOt9axH3m0G7nzHL7U3zaCbtEx3yVln+b3yYtiVpTuq0 +3MLrt7tQGAW6ra8ISf6YY1W65/uVXZE= +-----END CERTIFICATE-----
\ No newline at end of file diff --git a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp index 44f8522..c76c11f 100644 --- a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp +++ b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp @@ -543,6 +543,9 @@ void tst_QSslCertificate::fromPath_data() QTest::newRow("\"d.*/c.*.pem\" wildcard der") << QString("d.*/c.*.pem") << int(QRegExp::Wildcard) << false << 0; QTest::newRow("trailing-whitespace") << QString("more-certificates/trailing-whitespace.pem") << int(QRegExp::FixedString) << true << 1; + QTest::newRow("no-ending-newline") << QString("more-certificates/no-ending-newline.pem") << int(QRegExp::FixedString) << true << 1; + QTest::newRow("malformed-just-begin") << QString("more-certificates/malformed-just-begin.pem") << int(QRegExp::FixedString) << true << 0; + QTest::newRow("malformed-just-begin-no-newline") << QString("more-certificates/malformed-just-begin-no-newline.pem") << int(QRegExp::FixedString) << true << 0; } void tst_QSslCertificate::fromPath() diff --git a/tests/auto/qtableview/tst_qtableview.cpp b/tests/auto/qtableview/tst_qtableview.cpp index 7a5e68f..430712c 100644 --- a/tests/auto/qtableview/tst_qtableview.cpp +++ b/tests/auto/qtableview/tst_qtableview.cpp @@ -3024,6 +3024,14 @@ void tst_QTableView::spans_data() << QPoint(0, 0) << 1 << 1; + + QTest::newRow("QTBUG-6004 (follow-up): No failing Q_ASSERT, then it passes.") + << 10 << 10 + << (SpanList() << QRect(2, 2, 1, 3) << QRect(2, 2, 1, 1)) + << false + << QPoint(0, 0) + << 1 + << 1; } void tst_QTableView::spans() diff --git a/tests/auto/qurl/tst_qurl.cpp b/tests/auto/qurl/tst_qurl.cpp index ecd6f09..33812fe 100644 --- a/tests/auto/qurl/tst_qurl.cpp +++ b/tests/auto/qurl/tst_qurl.cpp @@ -90,7 +90,6 @@ public slots: private slots: void getSetCheck(); void constructing(); - void isDetached(); void assignment(); void comparison(); void copying(); @@ -319,25 +318,6 @@ void tst_QUrl::constructing() QVERIFY(!buildUNC.isEmpty()); } -void tst_QUrl::isDetached() -{ - QUrl url; - QVERIFY(!url.isDetached()); - - url = "http://qt.nokia.com/"; - QVERIFY(url.isDetached()); - - url.clear(); - QVERIFY(!url.isDetached()); - - url.setHost("qt.nokia.com"); - QVERIFY(url.isDetached()); - - QUrl url2 = url; - QVERIFY(!url.isDetached()); - QVERIFY(!url2.isDetached()); -} - void tst_QUrl::assignment() { QUrl url("http://qt.nokia.com/"); diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index ee4e726..ea90ae3 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -5439,26 +5439,24 @@ public: QRegion r; }; -template<typename R, typename C> -void verifyColor(R const& region, C const& color) -{ - const QRegion r = QRegion(region); - for (int i = 0; i < r.rects().size(); ++i) { - const QRect rect = r.rects().at(i); - for (int t = 0; t < 5; t++) { - const QPixmap pixmap = QPixmap::grabWindow(QDesktopWidget().winId(), - rect.left(), rect.top(), - rect.width(), rect.height()); - QCOMPARE(pixmap.size(), rect.size()); - QPixmap expectedPixmap(pixmap); /* ensure equal formats */ - expectedPixmap.fill(color); - if (pixmap.toImage().pixel(0,0) != QColor(color).rgb() && t < 4 ) - { QTest::qWait(200); continue; } - QCOMPARE(pixmap.toImage().pixel(0,0), QColor(color).rgb()); - QCOMPARE(pixmap, expectedPixmap); - break; - } - } +#define VERIFY_COLOR(region, color) { \ + const QRegion r = QRegion(region); \ + for (int i = 0; i < r.rects().size(); ++i) { \ + const QRect rect = r.rects().at(i); \ + for (int t = 0; t < 5; t++) { \ + const QPixmap pixmap = QPixmap::grabWindow(QDesktopWidget().winId(), \ + rect.left(), rect.top(), \ + rect.width(), rect.height()); \ + QCOMPARE(pixmap.size(), rect.size()); \ + QPixmap expectedPixmap(pixmap); /* ensure equal formats */ \ + expectedPixmap.fill(color); \ + if (pixmap.toImage().pixel(0,0) != QColor(color).rgb() && t < 4 ) \ + { QTest::qWait(200); continue; } \ + QCOMPARE(pixmap.toImage().pixel(0,0), QColor(color).rgb()); \ + QCOMPARE(pixmap, expectedPixmap); \ + break; \ + } \ + } \ } void tst_QWidget::moveChild_data() @@ -5499,9 +5497,9 @@ void tst_QWidget::moveChild() #endif QTRY_COMPARE(parent.r, QRegion(parent.rect()) - child.geometry()); QTRY_COMPARE(child.r, QRegion(child.rect())); - verifyColor(child.geometry().translated(tlwOffset), + VERIFY_COLOR(child.geometry().translated(tlwOffset), child.color); - verifyColor(QRegion(parent.geometry()) - child.geometry().translated(tlwOffset), + VERIFY_COLOR(QRegion(parent.geometry()) - child.geometry().translated(tlwOffset), parent.color); parent.reset(); child.reset(); @@ -5520,9 +5518,9 @@ void tst_QWidget::moveChild() // should be scrolled in backingstore QCOMPARE(child.r, QRegion()); #endif - verifyColor(child.geometry().translated(tlwOffset), + VERIFY_COLOR(child.geometry().translated(tlwOffset), child.color); - verifyColor(QRegion(parent.geometry()) - child.geometry().translated(tlwOffset), + VERIFY_COLOR(QRegion(parent.geometry()) - child.geometry().translated(tlwOffset), parent.color); } @@ -5553,8 +5551,8 @@ void tst_QWidget::showAndMoveChild() child.move(desktopDimensions.width()/2, desktopDimensions.height()/2); qApp->processEvents(); - verifyColor(child.geometry().translated(tlwOffset), Qt::blue); - verifyColor(QRegion(parent.geometry()) - child.geometry().translated(tlwOffset), Qt::red); + VERIFY_COLOR(child.geometry().translated(tlwOffset), Qt::blue); + VERIFY_COLOR(QRegion(parent.geometry()) - child.geometry().translated(tlwOffset), Qt::red); } void tst_QWidget::subtractOpaqueSiblings() diff --git a/tests/benchmarks/declarative/declarative.pro b/tests/benchmarks/declarative/declarative.pro index 2f85265..8433de5 100644 --- a/tests/benchmarks/declarative/declarative.pro +++ b/tests/benchmarks/declarative/declarative.pro @@ -6,7 +6,5 @@ SUBDIRS += \ qmlcomponent \ qmlgraphicsimage \ qmlmetaproperty \ - qmlpainting \ script \ - text # qmltime diff --git a/tests/benchmarks/declarative/qmlpainting/qmlpainting.pro b/tests/benchmarks/declarative/qmlpainting/qmlpainting.pro deleted file mode 100644 index 971e18d..0000000 --- a/tests/benchmarks/declarative/qmlpainting/qmlpainting.pro +++ /dev/null @@ -1,6 +0,0 @@ -load(qttest_p4) -TEMPLATE = app -TARGET = tst_qmlpainting -macx:CONFIG -= app_bundle - -SOURCES += tst_qmlpainting.cpp diff --git a/tests/benchmarks/declarative/qmlpainting/tst_qmlpainting.cpp b/tests/benchmarks/declarative/qmlpainting/tst_qmlpainting.cpp deleted file mode 100644 index e14531f..0000000 --- a/tests/benchmarks/declarative/qmlpainting/tst_qmlpainting.cpp +++ /dev/null @@ -1,574 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qtest.h> -#include <QPainter> -#include <QImage> - -#include <math.h> -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -class tst_QmlPainting : public QObject -{ - Q_OBJECT - - public: - tst_QmlPainting() {} - -private slots: - void drawRoundedRect(); - void drawScaledRoundedRect(); - void drawTransformedRoundedRect(); - - void drawAntialiasedRoundedRect(); - void drawScaledAntialiasedRoundedRect_data(); - void drawScaledAntialiasedRoundedRect(); - void drawTransformedAntialiasedRoundedRect_data(); - void drawTransformedAntialiasedRoundedRect(); - - void drawImageRoundedRect(); - void drawScaledImageRoundedRect_data(); - void drawScaledImageRoundedRect(); - void drawTransformedImageRoundedRect_data(); - void drawTransformedImageRoundedRect(); - - void drawScaleGridRoundedRect(); - void drawScaledScaleGridRoundedRect_data(); - void drawScaledScaleGridRoundedRect(); - void drawTransformedScaleGridRoundedRect_data(); - void drawTransformedScaleGridRoundedRect(); - - void drawTransformedTransparentImage_data(); - void drawTransformedTransparentImage(); - void drawTransformedSemiTransparentImage_data(); - void drawTransformedSemiTransparentImage(); - void drawTransformedFilledImage_data(); - void drawTransformedFilledImage(); -}; - -const qreal inv_dist_to_plane = 1. / 1024.; -QTransform transformForAngle(qreal angle) -{ - QTransform transform; - - QTransform rotTrans; - rotTrans.translate(-40, 0); - QTransform rotTrans2; - rotTrans2.translate(40, 0); - - qreal rad = angle * 2. * M_PI / 360.; - qreal c = ::cos(rad); - qreal s = ::sin(rad); - - qreal x = 0; - qreal y = 80; - qreal z = 0; - - qreal len = x * x + y * y + z * z; - if (len != 1.) { - len = ::sqrt(len); - x /= len; - y /= len; - z /= len; - } - - QTransform rot(x*x*(1-c)+c, x*y*(1-c)-z*s, x*z*(1-c)+y*s*inv_dist_to_plane, - y*x*(1-c)+z*s, y*y*(1-c)+c, y*z*(1-c)-x*s*inv_dist_to_plane, - 0, 0, 1); - - transform *= rotTrans; - transform *= rot; - transform *= rotTrans2; - - return transform; -} - -void tst_QmlPainting::drawRoundedRect() -{ - QImage surface(100, 100, QImage::Format_RGB16); - surface.fill(QColor(255,255,255).rgb()); - QPainter p(&surface); - - p.setPen(QPen(Qt::black, 1)); - p.setBrush(Qt::red); - - QBENCHMARK { - p.drawRoundedRect(QRectF(.5, .5, 80, 80), 10, 10); - } - //surface.save("regular.png"); -} - -void tst_QmlPainting::drawScaledRoundedRect() -{ - QImage surface(400, 400, QImage::Format_RGB16); - surface.fill(QColor(255,255,255).rgb()); - QPainter p(&surface); - - p.setPen(QPen(Qt::black, 1)); - p.setBrush(Qt::red); - p.scale(3, 3); - - QBENCHMARK { - p.drawRoundedRect(10, 10, 80, 80, 10, 10); - } - //surface.save("scaled.png"); -} - -void tst_QmlPainting::drawTransformedRoundedRect() -{ - QImage surface(400, 400, QImage::Format_RGB16); - surface.fill(QColor(255,255,255).rgb()); - QPainter p(&surface); - - p.setPen(QPen(Qt::black, 1)); - p.setBrush(Qt::red); - - QBENCHMARK { - p.setWorldTransform(QTransform(0.956957, 0, 0.000704124, 0, 1, 0, 16.141, 0, 0.735953)); - p.drawRoundedRect(100, 100, 80, 80, 10, 10); - } - //surface.save("transformed.png"); -} - -void tst_QmlPainting::drawAntialiasedRoundedRect() -{ - QImage surface(100, 100, QImage::Format_RGB16); - surface.fill(QColor(255,255,255).rgb()); - QPainter p(&surface); - - p.setRenderHint(QPainter::Antialiasing, true); - p.setPen(QPen(Qt::black, 1)); - p.setBrush(Qt::red); - - QBENCHMARK { - p.drawRoundedRect(QRectF(.5, .5, 80, 80), 10, 10); - } - //surface.save("aar.png"); -} - -void tst_QmlPainting::drawScaledAntialiasedRoundedRect_data() -{ - QTest::addColumn<float>("scale"); - - for (float i = 0; i < 3; i += .1) - QTest::newRow(QString(QLatin1String("scale=%1")).arg(i).toLatin1()) << i; -} - -void tst_QmlPainting::drawScaledAntialiasedRoundedRect() -{ - QFETCH(float, scale); - - QImage surface(400, 400, QImage::Format_RGB16); - surface.fill(QColor(255,255,255).rgb()); - QPainter p(&surface); - - p.setRenderHint(QPainter::Antialiasing, true); - p.setPen(QPen(Qt::black, 1)); - p.setBrush(Qt::red); - p.scale(scale, scale); - - QBENCHMARK { - p.drawRoundedRect(10, 10, 80, 80, 10, 10); - } - //surface.save("aas.png"); -} - -void tst_QmlPainting::drawTransformedAntialiasedRoundedRect_data() -{ - QTest::addColumn<QTransform>("transform"); - - for (float angle = 0; angle < 360; angle += 10) - QTest::newRow(QString(QLatin1String("angle=%1")).arg(angle).toLatin1()) << transformForAngle(angle); -} - -void tst_QmlPainting::drawTransformedAntialiasedRoundedRect() -{ - QFETCH(QTransform, transform); - - QImage surface(400, 400, QImage::Format_RGB16); - surface.fill(QColor(255,255,255).rgb()); - QPainter p(&surface); - - p.setRenderHint(QPainter::Antialiasing, true); - p.setPen(QPen(Qt::black, 1)); - p.setBrush(Qt::red); - - QBENCHMARK { - p.setWorldTransform(transform); - p.drawRoundedRect(100, 100, 80, 80, 10, 10); - } - //surface.save("aat.png"); -} - -void tst_QmlPainting::drawImageRoundedRect() -{ - //setup image - const int radius = 10; - QImage rectImage(81, 81, QImage::Format_ARGB32_Premultiplied); - rectImage.fill(0); - QPainter rp(&rectImage); - rp.setRenderHint(QPainter::Antialiasing); - rp.setPen(Qt::black); - rp.setBrush(Qt::red); - rp.drawRoundedRect(QRectF(.5, .5, 80, 80), radius, radius); - - //setup surface - QImage surface(100, 100, QImage::Format_RGB16); - surface.fill(QColor(255,255,255).rgb()); - QPainter p(&surface); - - QBENCHMARK { - p.drawImage(0,0, rectImage); - } - //surface.save("ri.png"); -} - -void tst_QmlPainting::drawScaledImageRoundedRect_data() -{ - QTest::addColumn<int>("imageType"); - - QTest::newRow("imagetype=ARGB32_Pre") << (int)QImage::Format_ARGB32_Premultiplied; - QTest::newRow("imagetype=ARGB8565_Pre") << (int)QImage::Format_ARGB8565_Premultiplied; -} - -void tst_QmlPainting::drawScaledImageRoundedRect() -{ - QFETCH(int, imageType); - - //setup image - const int radius = 10; - QImage rectImage(81, 81, (QImage::Format)imageType); - rectImage.fill(0); - QPainter rp(&rectImage); - rp.setRenderHint(QPainter::Antialiasing); - rp.setPen(Qt::black); - rp.setBrush(Qt::red); - rp.drawRoundedRect(QRectF(.5, .5, 80, 80), radius, radius); - - //setup surface - QImage surface(400, 400, QImage::Format_RGB16); - surface.fill(QColor(255,255,255).rgb()); - QPainter p(&surface); - p.scale(3, 3); - - QBENCHMARK { - p.drawImage(0,0, rectImage); - } - //surface.save("si.png"); -} - -void tst_QmlPainting::drawTransformedImageRoundedRect_data() -{ - QTest::addColumn<int>("imageType"); - - QTest::newRow("imagetype=ARGB32_Pre") << (int)QImage::Format_ARGB32_Premultiplied; - QTest::newRow("imagetype=ARGB8565_Pre") << (int)QImage::Format_ARGB8565_Premultiplied; -} - -void tst_QmlPainting::drawTransformedImageRoundedRect() -{ - QFETCH(int, imageType); - - //setup image - const int radius = 10; - QImage rectImage(81, 81, (QImage::Format)imageType); - rectImage.fill(0); - QPainter rp(&rectImage); - rp.setRenderHint(QPainter::Antialiasing); - rp.setPen(Qt::black); - rp.setBrush(Qt::red); - rp.drawRoundedRect(QRectF(.5, .5, 80, 80), radius, radius); - - //setup surface - QImage surface(400, 400, QImage::Format_RGB16); - surface.fill(QColor(255,255,255).rgb()); - QPainter p(&surface); - - QBENCHMARK { - p.setWorldTransform(QTransform(0.956957, 0, 0.000704124, 0, 1, 0, 16.141, 0, 0.735953)); - p.drawImage(100,100, rectImage); - } - //surface.save("ti.png"); -} - -//code from QmlGraphicsRectangle for drawing rounded rects -void tst_QmlPainting::drawScaleGridRoundedRect() -{ - //setup image - const int pw = 1; - const int radius = 10; - QImage rectImage(radius*2 + 3 + pw*2, radius*2 + 3 + pw*2, QImage::Format_ARGB32_Premultiplied); - rectImage.fill(0); - QPainter rp(&rectImage); - rp.setRenderHint(QPainter::Antialiasing); - rp.setPen(Qt::black); - rp.setBrush(Qt::red); - if (pw%2) - rp.drawRoundedRect(QRectF(qreal(pw)/2+1, qreal(pw)/2+1, rectImage.width()-(pw+1), rectImage.height()-(pw+1)), radius, radius); - else - rp.drawRoundedRect(QRectF(qreal(pw)/2, qreal(pw)/2, rectImage.width()-pw, rectImage.height()-pw), radius, radius); - QPixmap rectPixmap = QPixmap::fromImage(rectImage); - - //setup surface - QImage surface(100, 100, QImage::Format_RGB16); - surface.fill(QColor(255,255,255).rgb()); - QPainter p(&surface); - - QBENCHMARK { - const int pw = 2; - int width = 80; - int height = 80; - - int xOffset = (rectPixmap.width()-1)/2; - int yOffset = (rectPixmap.height()-1)/2; - Q_ASSERT(rectPixmap.width() == 2*xOffset + 1); - Q_ASSERT(rectPixmap.height() == 2*yOffset + 1); - - QMargins margins(xOffset, yOffset, xOffset, yOffset); - QTileRules rules(Qt::StretchTile, Qt::StretchTile); - //NOTE: even though our item may have qreal-based width and height, qDrawBorderPixmap only supports QRects - qDrawBorderPixmap(&p, QRect(-pw/2, -pw/2, width+pw, height+pw), margins, rectPixmap, rectPixmap.rect(), margins, rules); - } - //surface.save("rsg.png"); -} - -void tst_QmlPainting::drawScaledScaleGridRoundedRect_data() -{ - QTest::addColumn<float>("scale"); - QTest::addColumn<int>("imageType"); - - for (float i = 0; i < 3; i += .1) - QTest::newRow(QString(QLatin1String("scale=%1; imagetype=ARGB32_Pre")).arg(i).toLatin1()) << i << (int)QImage::Format_ARGB32_Premultiplied; - //for (float i = 0; i < 3; i += .1) - // QTest::newRow(QString(QLatin1String("scale=%1; imagetype=ARGB8565_Pre")).arg(i).toLatin1()) << i << (int)QImage::Format_ARGB8565_Premultiplied; -} - -//code from QmlGraphicsRectangle for drawing rounded rects -void tst_QmlPainting::drawScaledScaleGridRoundedRect() -{ - QFETCH(float, scale); - QFETCH(int, imageType); - - //setup image - const int pw = 1; - const int radius = 10; - QImage rectImage(radius*2 + 3 + pw*2, radius*2 + 3 + pw*2, (QImage::Format)imageType); - rectImage.fill(0); - QPainter rp(&rectImage); - rp.setRenderHint(QPainter::Antialiasing); - rp.setPen(Qt::black); - rp.setBrush(Qt::red); - if (pw%2) - rp.drawRoundedRect(QRectF(qreal(pw)/2+1, qreal(pw)/2+1, rectImage.width()-(pw+1), rectImage.height()-(pw+1)), radius, radius); - else - rp.drawRoundedRect(QRectF(qreal(pw)/2, qreal(pw)/2, rectImage.width()-pw, rectImage.height()-pw), radius, radius); - - QPixmap rectPixmap = QPixmap::fromImage(rectImage); - - //setup surface - QImage surface(400, 400, QImage::Format_RGB16); - surface.fill(QColor(255,255,255).rgb()); - QPainter p(&surface); - p.scale(scale, scale); - - QBENCHMARK { - const int pw = 2; - int width = 80; - int height = 80; - - int xOffset = (rectPixmap.width()-1)/2; - int yOffset = (rectPixmap.height()-1)/2; - Q_ASSERT(rectPixmap.width() == 2*xOffset + 1); - Q_ASSERT(rectPixmap.height() == 2*yOffset + 1); - - QMargins margins(xOffset, yOffset, xOffset, yOffset); - QTileRules rules(Qt::StretchTile, Qt::StretchTile); - //NOTE: even though our item may have qreal-based width and height, qDrawBorderPixmap only supports QRects - qDrawBorderPixmap(&p, QRect(-pw/2, -pw/2, width+pw, height+pw), margins, rectPixmap, rectPixmap.rect(), margins, rules); - } - //surface.save("ssg.png"); -} - -void tst_QmlPainting::drawTransformedScaleGridRoundedRect_data() -{ - QTest::addColumn<QTransform>("transform"); - QTest::addColumn<int>("imageType"); - - for (float angle = 0; angle < 360; angle += 10) - QTest::newRow(QString(QLatin1String("angle=%1; imagetype=ARGB32_Pre")).arg(angle).toLatin1()) << transformForAngle(angle) << (int)QImage::Format_ARGB32_Premultiplied; - //for (float angle = 0; angle < 360; angle += 10) - // QTest::newRow(QString(QLatin1String("angle=%1; imagetype=ARGB8565_Pre")).arg(angle).toLatin1()) << transformForAngle(angle) << (int)QImage::Format_ARGB8565_Premultiplied; - -} - -//code from QmlGraphicsRectangle for drawing rounded rects -void tst_QmlPainting::drawTransformedScaleGridRoundedRect() -{ - QFETCH(QTransform, transform); - QFETCH(int, imageType); - - //setup image - const int pw = 1; - const int radius = 10; - QImage rectImage(radius*2 + 3 + pw*2, radius*2 + 3 + pw*2, (QImage::Format)imageType); - rectImage.fill(0); - QPainter rp(&rectImage); - rp.setRenderHint(QPainter::Antialiasing); - rp.setPen(Qt::black); - rp.setBrush(Qt::red); - if (pw%2) - rp.drawRoundedRect(QRectF(qreal(pw)/2+1, qreal(pw)/2+1, rectImage.width()-(pw+1), rectImage.height()-(pw+1)), radius, radius); - else - rp.drawRoundedRect(QRectF(qreal(pw)/2, qreal(pw)/2, rectImage.width()-pw, rectImage.height()-pw), radius, radius); - - QPixmap rectPixmap = QPixmap::fromImage(rectImage); - - //setup surface - QImage surface(400, 400, QImage::Format_RGB16); - surface.fill(QColor(255,255,255).rgb()); - QPainter p(&surface); - - QBENCHMARK { - p.setWorldTransform(transform); - const int pw = 2; - //int offset = int(radius+1.5+pw); - int width = 80; - int height = 80; - - int xOffset = (rectPixmap.width()-1)/2; - int yOffset = (rectPixmap.height()-1)/2; - Q_ASSERT(rectPixmap.width() == 2*xOffset + 1); - Q_ASSERT(rectPixmap.height() == 2*yOffset + 1); - - QMargins margins(xOffset, yOffset, xOffset, yOffset); - QTileRules rules(Qt::StretchTile, Qt::StretchTile); - //NOTE: even though our item may have qreal-based width and height, qDrawBorderPixmap only supports QRects - qDrawBorderPixmap(&p, QRect(-pw/2, -pw/2, width+pw, height+pw), margins, rectPixmap, rectPixmap.rect(), margins, rules); - } - //surface.save("tsg.png"); -} - -void tst_QmlPainting::drawTransformedTransparentImage_data() -{ - QTest::addColumn<int>("imageType"); - - QTest::newRow("imagetype=ARGB32_Pre") << (int)QImage::Format_ARGB32_Premultiplied; - QTest::newRow("imagetype=ARGB8565_Pre") << (int)QImage::Format_ARGB8565_Premultiplied; -} - -void tst_QmlPainting::drawTransformedTransparentImage() -{ - QFETCH(int, imageType); - - //setup image - QImage transImage(200, 200, (QImage::Format)imageType); - transImage.fill(0); - - //setup surface - QImage surface(200, 200, QImage::Format_RGB16); - surface.fill(QColor(255,255,255).rgb()); - QPainter p(&surface); - - QBENCHMARK { - p.setWorldTransform(QTransform(0.956957, 0, 0.000704124, 0, 1, 0, 16.141, 0, 0.735953)); - p.drawImage(0,0, transImage); - } -} - -void tst_QmlPainting::drawTransformedSemiTransparentImage_data() -{ - QTest::addColumn<int>("imageType"); - - QTest::newRow("imagetype=ARGB32_Pre") << (int)QImage::Format_ARGB32_Premultiplied; - QTest::newRow("imagetype=ARGB8565_Pre") << (int)QImage::Format_ARGB8565_Premultiplied; -} - -void tst_QmlPainting::drawTransformedSemiTransparentImage() -{ - QFETCH(int, imageType); - - //setup image - QImage transImage(200, 200, (QImage::Format)imageType); - transImage.fill(QColor(0,0,0, 128).rgba()); - - //setup surface - QImage surface(200, 200, QImage::Format_RGB16); - surface.fill(QColor(255,255,255).rgb()); - QPainter p(&surface); - - QBENCHMARK { - p.setWorldTransform(QTransform(0.956957, 0, 0.000704124, 0, 1, 0, 16.141, 0, 0.735953)); - p.drawImage(0,0, transImage); - } -} - -void tst_QmlPainting::drawTransformedFilledImage_data() -{ - QTest::addColumn<int>("imageType"); - - QTest::newRow("imagetype=ARGB32_Pre") << (int)QImage::Format_ARGB32_Premultiplied; - QTest::newRow("imagetype=ARGB8565_Pre") << (int)QImage::Format_ARGB8565_Premultiplied; -} - -void tst_QmlPainting::drawTransformedFilledImage() -{ - QFETCH(int, imageType); - - //setup image - QImage filledImage(200, 200, (QImage::Format)imageType); - filledImage.fill(QColor(0,0,0).rgb()); - - //setup surface - QImage surface(200, 200, QImage::Format_RGB16); - surface.fill(QColor(255,255,255).rgb()); - QPainter p(&surface); - - QBENCHMARK { - p.setWorldTransform(QTransform(0.956957, 0, 0.000704124, 0, 1, 0, 16.141, 0, 0.735953)); - p.drawImage(0,0, filledImage); - } -} - -QTEST_MAIN(tst_QmlPainting) - -#include "tst_qmlpainting.moc" diff --git a/tests/benchmarks/declarative/signalemission/signalemission.pro b/tests/benchmarks/declarative/signalemission/signalemission.pro deleted file mode 100644 index 0119aff..0000000 --- a/tests/benchmarks/declarative/signalemission/signalemission.pro +++ /dev/null @@ -1,7 +0,0 @@ -load(qttest_p4) -TEMPLATE = app -TARGET = tst_signalemission -macx:CONFIG -= app_bundle - -SOURCES += tst_signalemission.cpp - diff --git a/tests/benchmarks/declarative/signalemission/tst_signalemission.cpp b/tests/benchmarks/declarative/signalemission/tst_signalemission.cpp deleted file mode 100644 index 8327638..0000000 --- a/tests/benchmarks/declarative/signalemission/tst_signalemission.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qtest.h> -#include <QObject> -#include <QDebug> - -class LotsOfSignals : public QObject -{ - Q_OBJECT -public: - LotsOfSignals() {} - -signals: - void extraSignal1(); - void extraSignal2(); - void extraSignal3(); - void extraSignal4(); - void extraSignal5(); - void extraSignal6(); - void extraSignal7(); - void extraSignal8(); - void extraSignal9(); - void extraSignal10(); - void extraSignal12(); - void extraSignal13(); - void extraSignal14(); - void extraSignal15(); - void extraSignal16(); - void extraSignal17(); - void extraSignal18(); - void extraSignal19(); - void extraSignal20(); - void extraSignal21(); - void extraSignal22(); - void extraSignal23(); - void extraSignal24(); - void extraSignal25(); - void extraSignal26(); - void extraSignal27(); - void extraSignal28(); - void extraSignal29(); - void extraSignal30(); - void extraSignal31(); - void extraSignal32(); - void extraSignal33(); - void extraSignal34(); - void extraSignal35(); - void extraSignal36(); - void extraSignal37(); - void extraSignal38(); - void extraSignal39(); - void extraSignal40(); - void extraSignal41(); - void extraSignal42(); - void extraSignal43(); - void extraSignal44(); - void extraSignal45(); - void extraSignal46(); - void extraSignal47(); - void extraSignal48(); - void extraSignal49(); - void extraSignal50(); - void extraSignal51(); - void extraSignal52(); - void extraSignal53(); - void extraSignal54(); - void extraSignal55(); - void extraSignal56(); - void extraSignal57(); - void extraSignal58(); - void extraSignal59(); - void extraSignal60(); - void extraSignal61(); - void extraSignal62(); - void extraSignal63(); - void extraSignal64(); - void extraSignal65(); - void extraSignal66(); - void extraSignal67(); - void extraSignal68(); - void extraSignal69(); - void extraSignal70(); -}; - -class tst_signalemission : public QObject -{ - Q_OBJECT -public: - tst_signalemission() {} - -private slots: - void unconnected_data(); - void unconnected(); -}; - -void tst_signalemission::unconnected_data() -{ - QTest::addColumn<int>("signal_index"); - QTest::newRow("9") << 9; - QTest::newRow("32") << 32; - QTest::newRow("33") << 33; - QTest::newRow("64") << 64; - QTest::newRow("65") << 65; - QTest::newRow("70") << 70; -} - -void tst_signalemission::unconnected() -{ - LotsOfSignals *obj = new LotsOfSignals; - QFETCH(int, signal_index); - QVERIFY(obj->metaObject()->methodCount() == 73); - void *v; - QBENCHMARK { - //+1 because QObject has one slot - QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, signal_index+1, &v); - } - delete obj; -} - -QTEST_MAIN(tst_signalemission) -#include "tst_signalemission.moc" diff --git a/tests/benchmarks/declarative/text/text.pro b/tests/benchmarks/declarative/text/text.pro deleted file mode 100644 index 3320f53..0000000 --- a/tests/benchmarks/declarative/text/text.pro +++ /dev/null @@ -1,7 +0,0 @@ -load(qttest_p4) -TEMPLATE = app -TARGET = tst_text -macx:CONFIG -= app_bundle - -SOURCES += tst_text.cpp - diff --git a/tests/benchmarks/declarative/text/tst_text.cpp b/tests/benchmarks/declarative/text/tst_text.cpp deleted file mode 100644 index 33ee237..0000000 --- a/tests/benchmarks/declarative/text/tst_text.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qtest.h> -#include <QTextLayout> -#include <QPainter> -#include <QSize> -#include <qmath.h> -#include <private/qtextcontrol_p.h> - -class tst_text : public QObject -{ - Q_OBJECT -public: - tst_text() - { - m_text = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."; - } - -private slots: - void layout(); - void paintLayoutToPixmap(); - void paintLayoutToPixmap_painterFill(); - void document(); - void paintDocToPixmap(); - void paintDocToPixmap_painterFill(); - void control(); - void paintControlToPixmap(); - void paintControlToPixmap_painterFill(); - void constructControl(); - void constructDocument(); - -private: - QString m_text; -}; - -QSize setupTextLayout(QTextLayout *layout) -{ - bool wrap = true; - int wrapWidth = 300; - layout->setCacheEnabled(true); - - int height = 0; - qreal widthUsed = 0; - qreal lineWidth = 0; - - //set manual width - if (wrap) - lineWidth = wrapWidth; - - layout->beginLayout(); - - while (1) { - QTextLine line = layout->createLine(); - if (!line.isValid()) - break; - - if (wrap) - line.setLineWidth(lineWidth); - } - layout->endLayout(); - - for (int i = 0; i < layout->lineCount(); ++i) { - QTextLine line = layout->lineAt(i); - widthUsed = qMax(widthUsed, line.naturalTextWidth()); - line.setPosition(QPointF(0, height)); - height += int(line.height()); - } - return QSize(qCeil(widthUsed), height); -} - -void tst_text::layout() -{ - //get rid of initialization effects - QTextLayout layout(m_text); - setupTextLayout(&layout); - - QBENCHMARK { - QTextLayout layout(m_text); - setupTextLayout(&layout); - } -} - -void tst_text::paintLayoutToPixmap() -{ - QTextLayout layout(m_text); - QSize size = setupTextLayout(&layout); - - QBENCHMARK { - QPixmap img(size); - img.fill(Qt::transparent); - QPainter p(&img); - layout.draw(&p, QPointF(0, 0)); - } -} - -void tst_text::paintLayoutToPixmap_painterFill() -{ - QTextLayout layout(m_text); - QSize size = setupTextLayout(&layout); - - QBENCHMARK { - QPixmap img(size); - QPainter p(&img); - p.setCompositionMode(QPainter::CompositionMode_Source); - p.fillRect(0, 0, img.width(), img.height(), Qt::transparent); - p.setCompositionMode(QPainter::CompositionMode_SourceOver); - layout.draw(&p, QPointF(0, 0)); - } -} - -void tst_text::document() -{ - QTextDocument *doc = new QTextDocument; - - QBENCHMARK { - QTextDocument *doc = new QTextDocument; - doc->setHtml(m_text); - } -} - -void tst_text::paintDocToPixmap() -{ - QTextDocument *doc = new QTextDocument; - doc->setHtml(m_text); - doc->setTextWidth(300); - QSize size = doc->size().toSize(); - - QBENCHMARK { - QPixmap img(size); - img.fill(Qt::transparent); - QPainter p(&img); - doc->drawContents(&p); - } -} - -void tst_text::paintDocToPixmap_painterFill() -{ - QTextDocument *doc = new QTextDocument; - doc->setHtml(m_text); - doc->setTextWidth(300); - QSize size = doc->size().toSize(); - - QBENCHMARK { - QPixmap img(size); - QPainter p(&img); - p.setCompositionMode(QPainter::CompositionMode_Source); - p.fillRect(0, 0, img.width(), img.height(), Qt::transparent); - p.setCompositionMode(QPainter::CompositionMode_SourceOver); - doc->drawContents(&p); - } -} - -void tst_text::control() -{ - QTextControl *control = new QTextControl(m_text); - - QBENCHMARK { - QTextControl *control = new QTextControl; - QTextDocument *doc = control->document(); - doc->setHtml(m_text); - } -} - -void tst_text::paintControlToPixmap() -{ - QTextControl *control = new QTextControl; - QTextDocument *doc = control->document(); - doc->setHtml(m_text); - doc->setTextWidth(300); - QSize size = doc->size().toSize(); - - QBENCHMARK { - QPixmap img(size); - img.fill(Qt::transparent); - QPainter p(&img); - control->drawContents(&p, QRectF(QPointF(0, 0), QSizeF(size))); - } -} - -void tst_text::paintControlToPixmap_painterFill() -{ - QTextControl *control = new QTextControl; - QTextDocument *doc = control->document(); - doc->setHtml(m_text); - doc->setTextWidth(300); - QSize size = doc->size().toSize(); - - QBENCHMARK { - QPixmap img(size); - QPainter p(&img); - p.setCompositionMode(QPainter::CompositionMode_Source); - p.fillRect(0, 0, img.width(), img.height(), Qt::transparent); - p.setCompositionMode(QPainter::CompositionMode_SourceOver); - control->drawContents(&p, QRectF(QPointF(0, 0), QSizeF(size))); - } -} - -void tst_text::constructControl() -{ - QTextControl *control = new QTextControl; - delete control; - - QBENCHMARK { - QTextControl *control = new QTextControl; - delete control; - } -} - -void tst_text::constructDocument() -{ - QTextDocument *doc = new QTextDocument; - delete doc; - - QBENCHMARK { - QTextDocument *doc = new QTextDocument; - delete doc; - } -} - -QTEST_MAIN(tst_text) -#include "tst_text.moc" diff --git a/tools/assistant/lib/qhelpsearchquerywidget.cpp b/tools/assistant/lib/qhelpsearchquerywidget.cpp index a2b3ca2..b614cb4 100644 --- a/tools/assistant/lib/qhelpsearchquerywidget.cpp +++ b/tools/assistant/lib/qhelpsearchquerywidget.cpp @@ -120,6 +120,22 @@ private: // nothing todo } + void retranslate() + { + simpleSearchLabel->setText(tr("Search for:")); + prevQueryButton->setToolTip(tr("Previous search")); + nextQueryButton->setToolTip(tr("Next search")); + searchButton->setText(tr("Search")); +#ifdef QT_CLUCENE_SUPPORT + advancedSearchLabel->setText(tr("Advanced search")); + similarLabel->setText(tr("words <B>similar</B> to:")); + withoutLabel->setText(tr("<B>without</B> the words:")); + exactLabel->setText(tr("with <B>exact phrase</B>:")); + allLabel->setText(tr("with <B>all</B> of the words:")); + atLeastLabel->setText(tr("with <B>at least one</B> of the words:")); +#endif + } + QString escapeString(const QString &text) { QString retValue = text; @@ -360,6 +376,13 @@ private: friend class QHelpSearchQueryWidget; bool simpleSearch; + QLabel *simpleSearchLabel; + QLabel *advancedSearchLabel; + QLabel *similarLabel; + QLabel *withoutLabel; + QLabel *exactLabel; + QLabel *allLabel; + QLabel *atLeastLabel; QPushButton *searchButton; QWidget* advancedSearchWidget; QToolButton *showHideAdvancedSearchButton; @@ -408,19 +431,17 @@ QHelpSearchQueryWidget::QHelpSearchQueryWidget(QWidget *parent) vLayout->setMargin(0); QHBoxLayout* hBoxLayout = new QHBoxLayout(); - QLabel *label = new QLabel(tr("Search for:"), this); + d->simpleSearchLabel = new QLabel(this); d->defaultQuery = new QLineEdit(this); d->defaultQuery->setCompleter(&d->searchCompleter); d->prevQueryButton = new QToolButton(this); d->prevQueryButton->setArrowType(Qt::LeftArrow); - d->prevQueryButton->setToolTip(tr("Previous search")); d->prevQueryButton->setEnabled(false); d->nextQueryButton = new QToolButton(this); d->nextQueryButton->setArrowType(Qt::RightArrow); - d->nextQueryButton->setToolTip(tr("Next search")); d->nextQueryButton->setEnabled(false); - d->searchButton = new QPushButton(tr("Search"), this); - hBoxLayout->addWidget(label); + d->searchButton = new QPushButton(this); + hBoxLayout->addWidget(d->simpleSearchLabel); hBoxLayout->addWidget(d->defaultQuery); hBoxLayout->addWidget(d->prevQueryButton); hBoxLayout->addWidget(d->nextQueryButton); @@ -439,15 +460,15 @@ QHelpSearchQueryWidget::QHelpSearchQueryWidget(QWidget *parent) d->showHideAdvancedSearchButton->setText(QLatin1String("+")); d->showHideAdvancedSearchButton->setMinimumSize(25, 20); - label = new QLabel(tr("Advanced search"), this); + d->advancedSearchLabel = new QLabel(this); QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); - sizePolicy.setHeightForWidth(label->sizePolicy().hasHeightForWidth()); - label->setSizePolicy(sizePolicy); + sizePolicy.setHeightForWidth(d->advancedSearchLabel->sizePolicy().hasHeightForWidth()); + d->advancedSearchLabel->setSizePolicy(sizePolicy); QFrame* hLine = new QFrame(this); hLine->setFrameStyle(QFrame::HLine); hBoxLayout->addWidget(d->showHideAdvancedSearchButton); - hBoxLayout->addWidget(label); + hBoxLayout->addWidget(d->advancedSearchLabel); hBoxLayout->addWidget(hLine); vLayout->addLayout(hBoxLayout); @@ -457,32 +478,32 @@ QHelpSearchQueryWidget::QHelpSearchQueryWidget(QWidget *parent) QGridLayout *gLayout = new QGridLayout(d->advancedSearchWidget); gLayout->setMargin(0); - label = new QLabel(tr("words <B>similar</B> to:"), this); - gLayout->addWidget(label, 0, 0); + d->similarLabel = new QLabel(this); + gLayout->addWidget(d->similarLabel, 0, 0); d->similarQuery = new QLineEdit(this); d->similarQuery->setCompleter(&d->searchCompleter); gLayout->addWidget(d->similarQuery, 0, 1); - label = new QLabel(tr("<B>without</B> the words:"), this); - gLayout->addWidget(label, 1, 0); + d->withoutLabel = new QLabel(this); + gLayout->addWidget(d->withoutLabel, 1, 0); d->withoutQuery = new QLineEdit(this); d->withoutQuery->setCompleter(&d->searchCompleter); gLayout->addWidget(d->withoutQuery, 1, 1); - label = new QLabel(tr("with <B>exact phrase</B>:"), this); - gLayout->addWidget(label, 2, 0); + d->exactLabel = new QLabel(this); + gLayout->addWidget(d->exactLabel, 2, 0); d->exactQuery = new QLineEdit(this); d->exactQuery->setCompleter(&d->searchCompleter); gLayout->addWidget(d->exactQuery, 2, 1); - label = new QLabel(tr("with <B>all</B> of the words:"), this); - gLayout->addWidget(label, 3, 0); + d->allLabel = new QLabel(this); + gLayout->addWidget(d->allLabel, 3, 0); d->allQuery = new QLineEdit(this); d->allQuery->setCompleter(&d->searchCompleter); gLayout->addWidget(d->allQuery, 3, 1); - label = new QLabel(tr("with <B>at least one</B> of the words:"), this); - gLayout->addWidget(label, 4, 0); + d->atLeastLabel = new QLabel(this); + gLayout->addWidget(d->atLeastLabel, 4, 0); d->atLeastQuery = new QLineEdit(this); d->atLeastQuery->setCompleter(&d->searchCompleter); gLayout->addWidget(d->atLeastQuery, 4, 1); @@ -490,6 +511,8 @@ QHelpSearchQueryWidget::QHelpSearchQueryWidget(QWidget *parent) vLayout->addWidget(d->advancedSearchWidget); d->advancedSearchWidget->hide(); + d->retranslate(); + connect(d->exactQuery, SIGNAL(returnPressed()), this, SIGNAL(search())); connect(d->similarQuery, SIGNAL(returnPressed()), this, SIGNAL(search())); connect(d->withoutQuery, SIGNAL(returnPressed()), this, SIGNAL(search())); @@ -531,4 +554,14 @@ void QHelpSearchQueryWidget::focusInEvent(QFocusEvent *focusEvent) } } +/*! \reimp +*/ +void QHelpSearchQueryWidget::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + d->retranslate(); + else + QWidget::changeEvent(event); +} + QT_END_NAMESPACE diff --git a/tools/assistant/lib/qhelpsearchquerywidget.h b/tools/assistant/lib/qhelpsearchquerywidget.h index a99bae0..2afc4b4 100644 --- a/tools/assistant/lib/qhelpsearchquerywidget.h +++ b/tools/assistant/lib/qhelpsearchquerywidget.h @@ -74,7 +74,8 @@ Q_SIGNALS: void search(); private: - void focusInEvent(QFocusEvent *focusEvent); + virtual void focusInEvent(QFocusEvent *focusEvent); + virtual void changeEvent(QEvent *event); private: QHelpSearchQueryWidgetPrivate *d; diff --git a/tools/assistant/lib/qhelpsearchresultwidget.cpp b/tools/assistant/lib/qhelpsearchresultwidget.cpp index 3cac880..a3f5aed 100644 --- a/tools/assistant/lib/qhelpsearchresultwidget.cpp +++ b/tools/assistant/lib/qhelpsearchresultwidget.cpp @@ -408,6 +408,14 @@ QHelpSearchResultWidget::QHelpSearchResultWidget(QHelpSearchEngine *engine) connect(engine, SIGNAL(searchingFinished(int)), d, SLOT(setResults(int))); } +/*! \reimp +*/ +void QHelpSearchResultWidget::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + d->setResults(d->searchEngine->hitCount()); +} + /*! Destroys the search result widget. */ diff --git a/tools/assistant/lib/qhelpsearchresultwidget.h b/tools/assistant/lib/qhelpsearchresultwidget.h index d078079..ff29adc 100644 --- a/tools/assistant/lib/qhelpsearchresultwidget.h +++ b/tools/assistant/lib/qhelpsearchresultwidget.h @@ -75,6 +75,7 @@ private: QHelpSearchResultWidgetPrivate *d; QHelpSearchResultWidget(QHelpSearchEngine *engine); + virtual void changeEvent(QEvent *event); }; QT_END_NAMESPACE diff --git a/tools/assistant/tools/assistant/centralwidget.cpp b/tools/assistant/tools/assistant/centralwidget.cpp index 0b177ae..055fa1c 100644 --- a/tools/assistant/tools/assistant/centralwidget.cpp +++ b/tools/assistant/tools/assistant/centralwidget.cpp @@ -358,7 +358,7 @@ void CentralWidget::zoomOut() void CentralWidget::findNext() { - find(findWidget->editFind->text(), true, false); + find(findWidget->editFind->text(), true); } void CentralWidget::nextPage() @@ -389,7 +389,7 @@ void CentralWidget::previousPage() void CentralWidget::findPrevious() { - find(findWidget->editFind->text(), false, true); + find(findWidget->editFind->text(), false); } void CentralWidget::closeTab() @@ -697,7 +697,7 @@ HelpViewer *CentralWidget::newEmptyTab() void CentralWidget::findCurrentText(const QString &text) { - find(text, false, false); + find(text, true); } void CentralWidget::connectSignals() @@ -896,19 +896,35 @@ void CentralWidget::keyPressEvent(QKeyEvent *e) QWidget::keyPressEvent(e); } -void CentralWidget::find(const QString &ttf, bool forward, bool backward) +void CentralWidget::find(const QString &ttf, bool forward) { QPalette p = findWidget->editFind->palette(); p.setColor(QPalette::Active, QPalette::Base, Qt::white); - if (!ttf.isEmpty()) { - HelpViewer *viewer = currentHelpViewer(); + bool found = false; - bool found = false; +#if defined(QT_NO_WEBKIT) + found = findInTextBrowser(ttf, forward); +#else + found = findInWebPage(ttf, forward); +#endif + + if (!found && !ttf.isEmpty()) + p.setColor(QPalette::Active, QPalette::Base, QColor(255, 102, 102)); + + if (!findWidget->isVisible()) + findWidget->show(); + findWidget->editFind->setPalette(p); +} + +bool CentralWidget::findInWebPage(const QString &ttf, bool forward) +{ #if !defined(QT_NO_WEBKIT) - if (viewer) { - QWebPage::FindFlags options; - if (backward) + if (HelpViewer *viewer = currentHelpViewer()) { + bool found = false; + QWebPage::FindFlags options; + if (!ttf.isEmpty()) { + if (!forward) options |= QWebPage::FindBackward; if (findWidget->checkCase->isChecked()) @@ -923,30 +939,27 @@ void CentralWidget::find(const QString &ttf, bool forward, bool backward) if (found) findWidget->labelWrapped->show(); } - } else if (tabWidget->currentWidget() == m_searchWidget) { - QTextBrowser *browser = qFindChild<QTextBrowser*>(m_searchWidget); - found = findInTextBrowser(browser, ttf, forward, backward); } -#else - QTextBrowser *browser = qobject_cast<QTextBrowser*>(viewer); - if (tabWidget->currentWidget() == m_searchWidget) - browser = qFindChild<QTextBrowser*>(m_searchWidget); - found = findInTextBrowser(browser, ttf, forward, backward); -#endif - - if (!found) - p.setColor(QPalette::Active, QPalette::Base, QColor(255, 102, 102)); + // force highlighting of all other matches, also when empty (clear) + options = QWebPage::HighlightAllOccurrences; + viewer->findText(QLatin1String(""), options); + viewer->findText(ttf, options); + return found; } - if (!findWidget->isVisible()) - findWidget->show(); - findWidget->editFind->setPalette(p); + // this needs to stay, case for active search results page + return findInTextBrowser(ttf, forward); +#endif + return false; } -bool CentralWidget::findInTextBrowser(QTextBrowser* browser, const QString &ttf, - bool forward, bool backward) +bool CentralWidget::findInTextBrowser(const QString &ttf, bool forward) { - if (!browser) + QTextBrowser *browser = qobject_cast<QTextBrowser*>(currentHelpViewer()); + if (tabWidget->currentWidget() == m_searchWidget) + browser = qFindChild<QTextBrowser*>(m_searchWidget); + + if (!browser || ttf.isEmpty()) return false; QTextDocument *doc = browser->document(); @@ -962,7 +975,7 @@ bool CentralWidget::findInTextBrowser(QTextBrowser* browser, const QString &ttf, QTextCursor::MoveAnchor); } - if (backward) + if (!forward) options |= QTextDocument::FindBackward; if (findWidget->checkCase->isChecked()) @@ -1074,20 +1087,29 @@ void CentralWidget::setSourceFromSearch(const QUrl &url) { setSource(url); +#if defined(QT_NO_WEBKIT) highlightSearchTerms(); +#else + connect(currentHelpViewer(), SIGNAL(loadFinished(bool)), this, + SLOT(highlightSearchTerms())); +#endif } void CentralWidget::setSourceFromSearchInNewTab(const QUrl &url) { setSourceInNewTab(url); +#if defined(QT_NO_WEBKIT) highlightSearchTerms(); +#else + connect(currentHelpViewer(), SIGNAL(loadFinished(bool)), this, + SLOT(highlightSearchTerms())); +#endif } void CentralWidget::highlightSearchTerms() { -#if defined(QT_NO_WEBKIT) HelpViewer *viewer = currentHelpViewer(); if (!viewer) return; @@ -1109,6 +1131,7 @@ CentralWidget::highlightSearchTerms() } } +#if defined(QT_NO_WEBKIT) viewer->viewport()->setUpdatesEnabled(false); QTextCharFormat marker; @@ -1140,6 +1163,14 @@ CentralWidget::highlightSearchTerms() viewer->setTextCursor(firstHit); viewer->viewport()->setUpdatesEnabled(true); +#else + viewer->findText("", QWebPage::HighlightAllOccurrences); + // clears existing selections + foreach (const QString& term, terms) + viewer->findText(term, QWebPage::HighlightAllOccurrences); + + disconnect(viewer, SIGNAL(loadFinished(bool)), this, + SLOT(highlightSearchTerms())); #endif } diff --git a/tools/assistant/tools/assistant/centralwidget.h b/tools/assistant/tools/assistant/centralwidget.h index 6c23190..9e32985 100644 --- a/tools/assistant/tools/assistant/centralwidget.h +++ b/tools/assistant/tools/assistant/centralwidget.h @@ -182,16 +182,16 @@ private slots: void printPreview(QPrinter *printer); void setSourceFromSearch(const QUrl &url); void setSourceFromSearchInNewTab(const QUrl &url); + void highlightSearchTerms(); private: void connectSignals(); bool eventFilter(QObject *object, QEvent *e); - void find(const QString &ttf, bool forward, bool backward); - bool findInTextBrowser(QTextBrowser* browser, const QString &ttf, - bool forward, bool backward); + void find(const QString &ttf, bool forward); + bool findInWebPage(const QString &ttf, bool forward); + bool findInTextBrowser(const QString &ttf, bool forward); void initPrinter(); QString quoteTabTitle(const QString &title) const; - void highlightSearchTerms(); void setLastShownPages(); void getBrowserFontFor(QWidget* viewer, QFont *font); diff --git a/tools/assistant/tools/assistant/helpviewer.cpp b/tools/assistant/tools/assistant/helpviewer.cpp index 1900c7e..be6245a 100644 --- a/tools/assistant/tools/assistant/helpviewer.cpp +++ b/tools/assistant/tools/assistant/helpviewer.cpp @@ -141,12 +141,12 @@ QNetworkReply *HelpNetworkAccessManager::createRequest(Operation /*op*/, if (mimeType.endsWith(QLatin1String(".svg")) || mimeType.endsWith(QLatin1String(".svgz"))) { mimeType = QLatin1String("image/svg+xml"); - } - else if (mimeType.endsWith(QLatin1String(".css"))) { + } else if (mimeType.endsWith(QLatin1String(".css"))) { mimeType = QLatin1String("text/css"); - } - else if (mimeType.endsWith(QLatin1String(".js"))) { + } else if (mimeType.endsWith(QLatin1String(".js"))) { mimeType = QLatin1String("text/javascript"); + } else if (mimeType.endsWith(QLatin1String(".txt"))) { + mimeType = QLatin1String("text/plain"); } else { mimeType = QLatin1String("text/html"); } diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 919e68f..7751143 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -317,6 +317,7 @@ Configure::Configure( int& argc, char** argv ) dictionary[ "OPENSSL" ] = "auto"; dictionary[ "DBUS" ] = "auto"; dictionary[ "S60" ] = "yes"; + dictionary[ "SYMBIAN_DEFFILES" ] = "yes"; dictionary[ "STYLE_WINDOWS" ] = "yes"; dictionary[ "STYLE_WINDOWSXP" ] = "auto"; @@ -482,6 +483,7 @@ void Configure::parseCmdLine() dictionary[ "BUILDNOKIA" ] = "yes"; dictionary[ "BUILDDEV" ] = "yes"; dictionary["LICENSE_CONFIRMED"] = "yes"; + dictionary[ "SYMBIAN_DEFFILES" ] = "no"; } else if( configCmdLine.at(i) == "-opensource" ) { dictionary[ "BUILDTYPE" ] = "opensource"; @@ -803,7 +805,7 @@ void Configure::parseCmdLine() else if( configCmdLine.at(i) == "-no-native-gestures" ) dictionary[ "NATIVE_GESTURES" ] = "no"; #if !defined(EVAL) - // Others --------------------------------------------------- + // Symbian Support ------------------------------------------- else if (configCmdLine.at(i) == "-fpu" ) { ++i; @@ -812,12 +814,17 @@ void Configure::parseCmdLine() dictionary[ "ARM_FPU_TYPE" ] = configCmdLine.at(i); } - // S60 Support ------------------------------------------- else if( configCmdLine.at(i) == "-s60" ) dictionary[ "S60" ] = "yes"; else if( configCmdLine.at(i) == "-no-s60" ) dictionary[ "S60" ] = "no"; + else if( configCmdLine.at(i) == "-usedeffiles" ) + dictionary[ "SYMBIAN_DEFFILES" ] = "yes"; + else if( configCmdLine.at(i) == "-no-usedeffiles" ) + dictionary[ "SYMBIAN_DEFFILES" ] = "no"; + + // Others --------------------------------------------------- else if (configCmdLine.at(i) == "-fast" ) dictionary[ "FAST" ] = "yes"; else if (configCmdLine.at(i) == "-no-fast" ) @@ -1822,7 +1829,9 @@ bool Configure::displayHelp() desc("FREETYPE", "yes", "-qt-freetype", "Use the libfreetype bundled with Qt."); desc( "-fpu <flags>", "VFP type on ARM, supported options: softvfp(default) | vfpv2 | softvfp+vfpv2"); desc("S60", "no", "-no-s60", "Do not compile in S60 support."); - desc("S60", "yes", "-s60", "Compile with support for the S60 UI Framework\n"); + desc("S60", "yes", "-s60", "Compile with support for the S60 UI Framework"); + desc("SYMBIAN_DEFFILES", "no", "-no-usedeffiles", "Disable the usage of DEF files."); + desc("SYMBIAN_DEFFILES", "yes", "-usedeffiles", "Enable the usage of DEF files.\n"); return true; } return false; @@ -2744,6 +2753,13 @@ void Configure::generateCachefile() if ( dictionary["PLUGIN_MANIFESTS"] == "no" ) configStream << " no_plugin_manifest"; + if ( dictionary.contains("SYMBIAN_DEFFILES") ) { + if(dictionary["SYMBIAN_DEFFILES"] == "yes" ) { + configStream << " def_files"; + } else if ( dictionary["SYMBIAN_DEFFILES"] == "no" ) { + configStream << " def_files_disabled"; + } + } configStream << endl; configStream << "QT_ARCH = " << dictionary[ "ARCHITECTURE" ] << endl; if (dictionary["QT_EDITION"].contains("OPENSOURCE")) @@ -3268,6 +3284,14 @@ void Configure::displayConfig() cout << "Support for S60............." << dictionary[ "S60" ] << endl; } + if (dictionary.contains("SYMBIAN_DEFFILES")) { + cout << "Symbian DEF files enabled..." << dictionary[ "SYMBIAN_DEFFILES" ] << endl; + if(dictionary["SYMBIAN_DEFFILES"] == "no") { + cout << "WARNING: Disabling DEF files will mean that Qt is NOT binary compatible with previous versions." << endl; + cout << " This feature is only intended for use during development, NEVER for release builds." << endl; + } + } + if(dictionary["ASSISTANT_WEBKIT"] == "yes") cout << "Using WebKit as html rendering engine in Qt Assistant." << endl; diff --git a/tools/designer/src/lib/shared/widgetfactory.cpp b/tools/designer/src/lib/shared/widgetfactory.cpp index eda551d..c7b13a1 100644 --- a/tools/designer/src/lib/shared/widgetfactory.cpp +++ b/tools/designer/src/lib/shared/widgetfactory.cpp @@ -774,6 +774,8 @@ void WidgetFactory::applyStyleTopLevel(const QString &styleName, QWidget *w) void WidgetFactory::applyStyleToTopLevel(QStyle *style, QWidget *widget) { + if (!style) + return; const QPalette standardPalette = style->standardPalette(); if (widget->style() == style && widget->palette() == standardPalette) return; diff --git a/tools/qttracereplay/main.cpp b/tools/qttracereplay/main.cpp index 85e9b12..a932d72 100644 --- a/tools/qttracereplay/main.cpp +++ b/tools/qttracereplay/main.cpp @@ -52,6 +52,7 @@ public: ReplayWidget(const QString &filename); void paintEvent(QPaintEvent *event); + void resizeEvent(QResizeEvent *event); public slots: void updateRect(); @@ -64,14 +65,15 @@ public: int currentIteration; QTime timer; + QList<uint> visibleUpdates; QList<uint> iterationTimes; QString filename; }; void ReplayWidget::updateRect() { - if (!updates.isEmpty()) - update(updates.at(currentFrame)); + if (!visibleUpdates.isEmpty()) + update(updates.at(visibleUpdates.at(currentFrame))); } void ReplayWidget::paintEvent(QPaintEvent *) @@ -80,10 +82,10 @@ void ReplayWidget::paintEvent(QPaintEvent *) // p.setClipRegion(frames.at(currentFrame).updateRegion); - buffer.draw(&p, currentFrame); + buffer.draw(&p, visibleUpdates.at(currentFrame)); ++currentFrame; - if (currentFrame >= buffer.numFrames()) { + if (currentFrame >= visibleUpdates.size()) { currentFrame = 0; ++currentIteration; @@ -119,7 +121,7 @@ void ReplayWidget::paintEvent(QPaintEvent *) if (iterationTimes.size() >= 10 || stddev < 4) { printf("%s, iterations: %d, frames: %d, min(ms): %d, median(ms): %d, stddev: %f %%, max(fps): %f\n", qPrintable(filename), - iterationTimes.size(), updates.size(), min, median, stddev, 1000. * updates.size() / min); + iterationTimes.size(), visibleUpdates.size(), min, median, stddev, 1000. * visibleUpdates.size() / min); deleteLater(); return; } @@ -130,6 +132,21 @@ void ReplayWidget::paintEvent(QPaintEvent *) QTimer::singleShot(0, this, SLOT(updateRect())); } +void ReplayWidget::resizeEvent(QResizeEvent *event) +{ + visibleUpdates.clear(); + + QRect bounds = rect(); + for (int i = 0; i < updates.size(); ++i) { + if (updates.at(i).intersects(bounds)) + visibleUpdates << i; + } + + if (visibleUpdates.size() != updates.size()) + printf("Warning: skipped %d frames due to limited resolution\n", updates.size() - visibleUpdates.size()); + +} + ReplayWidget::ReplayWidget(const QString &filename_) : currentFrame(0) , currentIteration(0) @@ -138,7 +155,6 @@ ReplayWidget::ReplayWidget(const QString &filename_) setWindowTitle(filename); QFile file(filename); - QRect bounds; if (!file.open(QIODevice::ReadOnly)) { printf("Failed to load input file '%s'\n", qPrintable(filename_)); return; diff --git a/tools/runonphone/main.cpp b/tools/runonphone/main.cpp index d8c306f..a77e713 100644 --- a/tools/runonphone/main.cpp +++ b/tools/runonphone/main.cpp @@ -72,7 +72,7 @@ int main(int argc, char *argv[]) QString serialPortFriendlyName; QString sisFile; QString exeFile; - QString cmdLine; + QStringList cmdLine; QStringList args = QCoreApplication::arguments(); QTextStream outstream(stdout); QTextStream errstream(stderr); @@ -124,7 +124,6 @@ int main(int argc, char *argv[]) i++; for(;i<args.size();i++) { cmdLine.append(args.at(i)); - if(i + 1 < args.size()) cmdLine.append(' '); } } } @@ -175,7 +174,11 @@ int main(int argc, char *argv[]) } if(loglevel > 0) outstream << "Connecting to target via " << serialPortName << endl; +#ifdef Q_OS_WIN launcher->setTrkServerName(QString("\\\\.\\") + serialPortName); +#else + launcher->setTrkServerName(serialPortName); +#endif launcher->setFileName(QString("c:\\sys\\bin\\") + exeFile); launcher->setCommandLineArgs(cmdLine); @@ -200,8 +203,8 @@ int main(int argc, char *argv[]) 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(stopped(uint,uint,uint,QString)), &handler, SLOT(stopped(uint,uint,uint,QString))); - QObject::connect(&handler, SIGNAL(resume(uint,uint)), launcher.data(), SLOT(resume(uint,uint))); + QObject::connect(launcher.data(), SIGNAL(processStopped(uint,uint,uint,QString)), &handler, SLOT(stopped(uint,uint,uint,QString))); + QObject::connect(&handler, SIGNAL(resume(uint,uint)), launcher.data(), SLOT(resumeProcess(uint,uint))); QObject::connect(&handler, SIGNAL(terminate()), launcher.data(), SLOT(terminate())); QObject::connect(launcher.data(), SIGNAL(finished()), &handler, SLOT(finished())); diff --git a/tools/runonphone/runonphone.pro b/tools/runonphone/runonphone.pro index cf0c055..2c1be98 100644 --- a/tools/runonphone/runonphone.pro +++ b/tools/runonphone/runonphone.pro @@ -18,3 +18,9 @@ windows { -luuid \ -ladvapi32 } +else:unix:!symbian { + SOURCES += serenum_unix.cpp +} +else { + SOURCES += serenum_stub.cpp +} diff --git a/tools/runonphone/serenum_stub.cpp b/tools/runonphone/serenum_stub.cpp new file mode 100644 index 0000000..f39765e --- /dev/null +++ b/tools/runonphone/serenum_stub.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 "serenum.h" +#include <QByteArray> +#include <QString> +#include <QDebug> + +QList<SerialPortId> enumerateSerialPorts() +{ + QList<SerialPortId> list; + qWarning() << "enumerateSerialPorts not implemented" << endl; + return list; +} + diff --git a/tools/runonphone/serenum_unix.cpp b/tools/runonphone/serenum_unix.cpp new file mode 100644 index 0000000..ca6c437 --- /dev/null +++ b/tools/runonphone/serenum_unix.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 "serenum.h" +#include <QByteArray> +#include <QString> +#include <QDebug> +#include <QFileInfo> +#include <QDir> + +QList<SerialPortId> enumerateSerialPorts() +{ + QList<SerialPortId> list; + QDir dir("/dev/serial/by-id/"); + QFileInfoList ports(dir.entryInfoList()); + foreach(QFileInfo info, ports) { + if (!info.isDir()) { + SerialPortId id; + id.friendlyName = info.fileName(); + id.portName = info.canonicalFilePath(); + list << id; + } + } + return list; +} + diff --git a/tools/runonphone/trk/launcher.cpp b/tools/runonphone/trk/launcher.cpp index 8f150c6..1796fc5 100644 --- a/tools/runonphone/trk/launcher.cpp +++ b/tools/runonphone/trk/launcher.cpp @@ -76,7 +76,7 @@ struct LauncherPrivate { CopyState m_copyState; QString m_fileName; - QString m_commandLineArgs; + QStringList m_commandLineArgs; QString m_installFileName; int m_verbose; Launcher::Actions m_startupActions; @@ -159,7 +159,7 @@ void Launcher::setInstallFileName(const QString &name) d->m_installFileName = name; } -void Launcher::setCommandLineArgs(const QString &args) +void Launcher::setCommandLineArgs(const QStringList &args) { d->m_commandLineArgs = args; } @@ -189,8 +189,10 @@ 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); + const QString msg = QString::fromLatin1("Port=%1 Executable=%2 Arguments=%3 Package=%4 Remote Package=%5 Install file=%6") + .arg(d->m_trkServerName, d->m_fileName, + d->m_commandLineArgs.join(QString(QLatin1Char(' '))), + d->m_copyState.sourceFileName, d->m_copyState.destinationFileName, d->m_installFileName); logMessage(msg); } if (d->m_startupActions & ActionCopy) { @@ -296,6 +298,34 @@ void Launcher::handleRemoteProcessKilled(const TrkResult &result) disconnectTrk(); } +QString Launcher::msgStopped(uint pid, uint tid, uint address, const QString &why) +{ + return QString::fromLatin1("Process %1, thread %2 stopped at 0x%3: %4"). + arg(pid).arg(tid).arg(address, 0, 16). + arg(why.isEmpty() ? QString::fromLatin1("<Unknown reason>") : why); +} + +bool Launcher::parseNotifyStopped(const QByteArray &dataBA, + uint *pid, uint *tid, uint *address, + QString *why /* = 0 */) +{ + if (why) + why->clear(); + *address = *pid = *tid = 0; + if (dataBA.size() < 12) + return false; + const char *data = dataBA.data(); + *address = extractInt(data); + *pid = extractInt(data + 4); + *tid = extractInt(data + 8); + if (why && dataBA.size() >= 14) { + const unsigned short len = extractShort(data + 12); + if (len > 0) + *why = QString::fromLatin1(data + 14, len); + } + return true; +} + void Launcher::handleResult(const TrkResult &result) { QByteArray prefix = "READ BUF: "; @@ -315,25 +345,13 @@ void Launcher::handleResult(const TrkResult &result) 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 QString reason; - if (result.data.size() >= 14) { - uint pc = extractInt(result.data.mid(0,4).constData()); - uint pid = extractInt(result.data.mid(4,4).constData()); - uint tid = extractInt(result.data.mid(8,4).constData()); - ushort len = extractShort(result.data.mid(12,2).constData()); - if(len > 0) - reason = result.data.mid(14, len); - emit(stopped(pc, pid, tid, reason)); - } else { - emit(stopped(0, 0, 0, reason)); - } - //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); + uint pc; + uint pid; + uint tid; + parseNotifyStopped(result.data, &pid, &tid, &pc, &reason); + logMessage(prefix + msgStopped(pid, tid, pc, reason)); + emit(processStopped(pc, pid, tid, reason)); d->m_device->sendTrkAck(result.token); break; } @@ -681,31 +699,38 @@ void Launcher::handleInstallPackageFinished(const TrkResult &result) } } -void Launcher::startInferiorIfNeeded() +QByteArray Launcher::startProcessMessage(const QString &executable, + const QStringList &arguments) { - 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(arguments.isEmpty()) { + appendString(&ba, executable.toLocal8Bit(), TargetByteOrder); + return ba; + } + // Append full command line as one string (leading length information). + QByteArray commandLineBa; + commandLineBa.append(executable.toLocal8Bit()); + commandLineBa.append('\0'); + commandLineBa.append(arguments.join(QString(QLatin1Char(' '))).toLocal8Bit()); + appendString(&ba, commandLineBa, TargetByteOrder); + return ba; +} - 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); +void Launcher::startInferiorIfNeeded() +{ + emit startingApplication(); + if (d->m_session.pid != 0) { + logMessage("Process already 'started'"); + return; } - d->m_device->sendTrkMessage(TrkCreateItem, TrkCallback(this, &Launcher::handleCreateProcess), ba); // Create Item + d->m_device->sendTrkMessage(TrkCreateItem, TrkCallback(this, &Launcher::handleCreateProcess), + startProcessMessage(d->m_fileName, d->m_commandLineArgs)); // Create Item } -void Launcher::resume(uint pid, uint tid) +void Launcher::resumeProcess(uint pid, uint tid) { QByteArray ba; appendInt(&ba, pid, BigEndian); diff --git a/tools/runonphone/trk/launcher.h b/tools/runonphone/trk/launcher.h index 5dded53..8dc6ebe 100644 --- a/tools/runonphone/trk/launcher.h +++ b/tools/runonphone/trk/launcher.h @@ -95,7 +95,7 @@ public: void setFileName(const QString &name); void setCopyFileName(const QString &srcName, const QString &dstName); void setInstallFileName(const QString &name); - void setCommandLineArgs(const QString &args); + void setCommandLineArgs(const QStringList &args); bool startServer(QString *errorMessage); void setVerbose(int v); void setSerialFrame(bool b); @@ -109,6 +109,15 @@ public: // becomes valid after successful execution of ActionPingOnly QString deviceDescription(unsigned verbose = 0u) const; + static QByteArray startProcessMessage(const QString &executable, + const QStringList &arguments); + // Parse a TrkNotifyStopped message + static bool parseNotifyStopped(const QByteArray &a, + uint *pid, uint *tid, uint *address, + QString *why = 0); + // Helper message + static QString msgStopped(uint pid, uint tid, uint address, const QString &why); + signals: void copyingStarted(); void canNotConnect(const QString &errorMessage); @@ -125,11 +134,11 @@ signals: void applicationOutputReceived(const QString &output); void copyProgress(int percent); void stateChanged(int); - void stopped(uint pc, uint pid, uint tid, const QString& reason); + void processStopped(uint pc, uint pid, uint tid, const QString& reason); public slots: void terminate(); - void resume(uint pid, uint tid); + void resumeProcess(uint pid, uint tid); private slots: void handleResult(const trk::TrkResult &data); diff --git a/tools/runonphone/trk/trkdevice.cpp b/tools/runonphone/trk/trkdevice.cpp index 53f4490..fe3261b 100644 --- a/tools/runonphone/trk/trkdevice.cpp +++ b/tools/runonphone/trk/trkdevice.cpp @@ -99,6 +99,8 @@ QString winErrorMessage(unsigned long error) #endif +enum { verboseTrk = 0 }; + namespace trk { /////////////////////////////////////////////////////////////////////// @@ -128,6 +130,12 @@ TrkMessage::TrkMessage(byte c, byte t, TrkCallback cb) : { } +QDebug operator<<(QDebug d, const TrkMessage &msg) +{ + return d << "Message: Code: " << msg.code + << " Token: " << msg.token << " " << msg.data.toHex(); +} + } // namespace trk Q_DECLARE_METATYPE(trk::TrkMessage) @@ -204,6 +212,8 @@ byte TrkWriteQueue::nextTrkWriteToken() ++m_trkWriteToken; if (m_trkWriteToken == 0) ++m_trkWriteToken; + if (verboseTrk) + qDebug() << "Write token: " << m_trkWriteToken; return m_trkWriteToken; } @@ -334,7 +344,8 @@ DeviceContext::DeviceContext() : /////////////////////////////////////////////////////////////////////// -class WriterThread : public QThread { +class WriterThread : public QThread +{ Q_OBJECT Q_DISABLE_COPY(WriterThread) public: @@ -400,15 +411,18 @@ int WriterThread::writePendingMessage() 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: { + //qDebug() << "Write pending message " << message; // Untested: try to re-send a few times bool success = false; for (int r = 0; !success && (r < MaxAttempts); r++) { @@ -428,6 +442,8 @@ int WriterThread::writePendingMessage() break; case TrkWriteQueue::NoopMessageDequeued: // Sync with thread that owns us via a blocking signal + if (verboseTrk) + qDebug() << "Noop message dequeued" << message; emit internalNoopMessageDequeued(message); break; } // switch @@ -499,6 +515,8 @@ static inline bool overlappedSyncWrite(HANDLE file, bool WriterThread::write(const QByteArray &data, QString *errorMessage) { + if (verboseTrk) + qDebug() << "Write raw data: " << data.toHex(); QMutexLocker locker(&m_context->mutex); #ifdef Q_OS_WIN DWORD charsWritten; @@ -557,6 +575,7 @@ void WriterThread::slotHandleResult(const TrkResult &result) tryWrite(); // Have messages been enqueued in-between? } + /////////////////////////////////////////////////////////////////////// // // ReaderThreadBase: Base class for a thread that reads data from @@ -566,7 +585,8 @@ void WriterThread::slotHandleResult(const TrkResult &result) // /////////////////////////////////////////////////////////////////////// -class ReaderThreadBase : public QThread { +class ReaderThreadBase : public QThread +{ Q_OBJECT Q_DISABLE_COPY(ReaderThreadBase) public: @@ -625,7 +645,8 @@ void ReaderThreadBase::readMessages() // /////////////////////////////////////////////////////////////////////// -class WinReaderThread : public ReaderThreadBase { +class WinReaderThread : public ReaderThreadBase +{ Q_OBJECT Q_DISABLE_COPY(WinReaderThread) public: @@ -835,7 +856,8 @@ void UnixReaderThread::terminate() { // Trigger select() by writing to the pipe char c = 0; - write(m_terminatePipeFileDescriptors[1], &c, 1); + int written = write(m_terminatePipeFileDescriptors[1], &c, 1); + // FIXME: Use result. wait(); } @@ -1021,6 +1043,8 @@ void TrkDevice::setVerbose(int b) void TrkDevice::slotMessageReceived(const trk::TrkResult &result, const QByteArray &rawData) { d->writerThread->slotHandleResult(result); + if (d->verbose > 1) + qDebug() << "Received: " << result.toString(); emit messageReceived(result); if (!rawData.isEmpty()) emit rawDataReceived(rawData); @@ -1057,6 +1081,8 @@ bool TrkDevice::sendTrkAck(byte token) TrkMessage msg(0x80, token); msg.token = token; msg.data.append('\0'); + if (verboseTrk) + qDebug() << "Write synchroneous message: " << msg; return d->writerThread->trkWriteRawMessage(msg); // 01 90 00 07 7e 80 01 00 7d 5e 7e } diff --git a/tools/runonphone/trk/trkutils.h b/tools/runonphone/trk/trkutils.h index c636ac0..328dd2b 100644 --- a/tools/runonphone/trk/trkutils.h +++ b/tools/runonphone/trk/trkutils.h @@ -119,7 +119,8 @@ struct Library uint dataseg; }; -struct TrkAppVersion { +struct TrkAppVersion +{ TrkAppVersion(); void reset(); @@ -153,6 +154,10 @@ struct Session typedef QList<Library> Libraries; Libraries libraries; + typedef uint Thread; + typedef QList<Thread> Threads; + Threads threads; + // Gdb request uint currentThread; QStringList modules; |