diff options
author | Olivier Goffart <ogoffart@trolltech.com> | 2009-10-30 12:42:27 (GMT) |
---|---|---|
committer | Olivier Goffart <ogoffart@trolltech.com> | 2009-10-30 12:42:27 (GMT) |
commit | dc1b1b37e1ebe055d3bd46bc43e0c3b9612560bc (patch) | |
tree | 05f9f9bc92322c9b42257c00ae2df14700fdd35f /src | |
parent | 79a7c969983eafeef67cce28724c3981cf3af1ea (diff) | |
parent | e95e69f7d1209cceacdef0f26416b93c1d83e8e0 (diff) | |
download | Qt-dc1b1b37e1ebe055d3bd46bc43e0c3b9612560bc.zip Qt-dc1b1b37e1ebe055d3bd46bc43e0c3b9612560bc.tar.gz Qt-dc1b1b37e1ebe055d3bd46bc43e0c3b9612560bc.tar.bz2 |
Merge commit 'origin/4.6' into 4.6
Diffstat (limited to 'src')
74 files changed, 1979 insertions, 1416 deletions
diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro index a835fc7..d633a7a 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pro +++ b/src/3rdparty/webkit/WebCore/WebCore.pro @@ -3376,3 +3376,18 @@ CONFIG(QTDIR_build):isEqual(QT_MAJOR_VERSION, 4):greaterThan(QT_MINOR_VERSION, 4 plugins/win/PaintHooks.asm } } + +# Temporary workaround to pick up the DEF file from the same place as all the others +symbian { + shared { + contains(MMP_RULES, defBlock) { + MMP_RULES -= defBlock + + MMP_RULES += "$${LITERAL_HASH}ifdef WINSCW" \ + "DEFFILE ../../../s60installs/bwins/$${TARGET}.def" \ + "$${LITERAL_HASH}elif defined EABI" \ + "DEFFILE ../../../s60installs/eabi/$${TARGET}.def" \ + "$${LITERAL_HASH}endif" + } + } +} diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index f835bee..9a15bf1 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -35,4 +35,4 @@ symbian: { # Workaroud for problems with paging this dll MMP_RULES -= PAGED MMP_RULES *= UNPAGED -}
\ No newline at end of file +} diff --git a/src/corelib/eval.pri b/src/corelib/eval.pri new file mode 100644 index 0000000..efda56b --- /dev/null +++ b/src/corelib/eval.pri @@ -0,0 +1,4 @@ +SOURCES += \ + $$QT_SOURCE_TREE/src/corelib/kernel/qtcore_eval.cpp +INCLUDEPATH += \ + $$QT_BUILD_TREE/src/corelib/global diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index e227403..32693e0 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -208,6 +208,18 @@ QLibraryInfo::buildKey() } /*! + \since 4.6 + Returns the installation date for this build of Qt. The install date will + usually be the last time that Qt sources were configured. +*/ +QDate +QLibraryInfo::buildDate() +{ + return QDate(); + //return QDate::fromString(QString::fromLatin1(qt_configure_installation + 12), Qt::ISODate); +} + +/*! Returns the location specified by \a loc. */ @@ -481,12 +493,20 @@ void qt_core_boilerplate() "Contact: Nokia Corporation (qt-info@nokia.com)\n" "\n" "Build key: " QT_BUILD_KEY "\n" + "Build date: %s\n" "Installation prefix: %s\n" "Library path: %s\n" "Include path: %s\n", + qt_configure_installation + 12, qt_configure_prefix_path_str + 12, qt_configure_libraries_path_str + 12, qt_configure_headers_path_str + 12); + +#ifdef QT_EVAL + extern void qt_core_eval_init(uint); + qt_core_eval_init(1); +#endif + exit(0); } diff --git a/src/corelib/global/qlibraryinfo.h b/src/corelib/global/qlibraryinfo.h index 3195777..88e8566 100644 --- a/src/corelib/global/qlibraryinfo.h +++ b/src/corelib/global/qlibraryinfo.h @@ -43,6 +43,7 @@ #define QLIBRARYINFO_H #include <QtCore/qstring.h> +#include <QtCore/QDate> QT_BEGIN_HEADER @@ -59,6 +60,7 @@ public: static QString licensedProducts(); static QString buildKey(); + static QDate buildDate(); enum LibraryLocation { diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index fb096a7..b69a5e5 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -76,6 +76,16 @@ QT_BEGIN_NAMESPACE # endif #endif +#ifdef Q_OS_SYMBIAN + // Using default 4k block in symbian is highly inefficient due to + // the fact that each file operation requires slow IPC calls, so + // use somewhat larger block size. +# define FDFH_BLOCK_SIZE 16384 +#else + // Read/write in blocks of 4k to avoid platform limitations (Windows + // commonly bails out if you read or write too large blocks at once). +# define FDFH_BLOCK_SIZE 4096 +#endif /*! \class QFSFileEngine \brief The QFSFileEngine class implements Qt's default file engine. @@ -160,11 +170,11 @@ QString QFSFileEnginePrivate::canonicalized(const QString &path) if ( #ifdef Q_OS_SYMBIAN // Symbian doesn't support directory symlinks, so do not check for link unless we - // are handling the last path element. This not only slightly improves performance, + // are handling the last path element. This not only slightly improves performance, // but also saves us from lot of unnecessary platform security check failures // when dealing with files under *:/private directories. separatorPos == -1 && -#endif +#endif !nonSymlinks.contains(prefix)) { fi.setFile(prefix); if (fi.isSymLink()) { @@ -628,14 +638,12 @@ qint64 QFSFileEnginePrivate::readFdFh(char *data, qint64 len) qint64 read = 0; int retry = 0; - // Read in blocks of 4k to avoid platform limitations (Windows - // commonly bails out if you read or write too large blocks at once). qint64 bytesToRead; do { if (retry == 1) retry = 2; - bytesToRead = qMin<qint64>(4096, len - read); + bytesToRead = qMin<qint64>(FDFH_BLOCK_SIZE, len - read); do { readBytes = fread(data + read, 1, size_t(bytesToRead), fh); } while (readBytes == 0 && !feof(fh) && errno == EINTR); @@ -666,10 +674,8 @@ qint64 QFSFileEnginePrivate::readFdFh(char *data, qint64 len) qint64 read = 0; errno = 0; - // Read in blocks of 4k to avoid platform limitations (Windows - // commonly bails out if you read or write too large blocks at once). do { - qint64 bytesToRead = qMin<qint64>(4096, len - read); + qint64 bytesToRead = qMin<qint64>(FDFH_BLOCK_SIZE, len - read); do { result = QT_READ(fd, data + read, int(bytesToRead)); } while (result == -1 && errno == EINTR); @@ -770,9 +776,7 @@ qint64 QFSFileEnginePrivate::writeFdFh(const char *data, qint64 len) qint64 written = 0; do { - // Write blocks of 4k to avoid platform limitations (Windows commonly - // bails out if you read or write too large blocks at once). - qint64 bytesToWrite = qMin<qint64>(4096, len - written); + qint64 bytesToWrite = qMin<qint64>(FDFH_BLOCK_SIZE, len - written); if (fh) { do { // Buffered stdlib mode. @@ -903,7 +907,7 @@ bool QFSFileEngine::supportsExtension(Extension extension) const /*! \fn QString QFSFileEngine::currentPath(const QString &fileName) For Unix, returns the current working directory for the file engine. - + For Windows, returns the canonicalized form of the current path used by the file engine for the drive specified by \a fileName. On Windows, each drive has its own current directory, so a different diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 6001d9d..86680a5 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -5556,79 +5556,6 @@ QUrl QUrl::fromEncoded(const QByteArray &input, ParsingMode parsingMode) } /*! - Returns a valid URL from a user supplied \a userInput string if one can be - deducted. In the case that is not possible, an invalid QUrl() is returned. - - \since 4.6 - - Most applications that can browse the web, allow the user to input a URL - in the form of a plain string. This string can be manually typed into - a location bar, obtained from the clipboard, or passed in via command - line arguments. - - When the string is not already a valid URL, a best guess is performed, - making various web related assumptions. - - In the case the string corresponds to a valid file path on the system, - a file:// URL is constructed, using QUrl::fromLocalFile(). - - If that is not the case, an attempt is made to turn the string into a - http:// or ftp:// URL. The latter in the case the string starts with - 'ftp'. The result is then passed through QUrl's tolerant parser, and - in the case or success, a valid QUrl is returned, or else a QUrl(). - - \section1 Examples: - - \list - \o qt.nokia.com becomes http://qt.nokia.com - \o ftp.qt.nokia.com becomes ftp://ftp.qt.nokia.com - \o localhost becomes http://localhost - \o /home/user/test.html becomes file:///home/user/test.html (if exists) - \endlist - - \section2 Tips to avoid erroneous character conversion when dealing with - URLs and strings: - - \list - \o When creating an URL QString from a QByteArray or a char*, always use - QString::fromUtf8(). - \o Favor the use of QUrl::fromEncoded() and QUrl::toEncoded() instead of - QUrl(string) and QUrl::toString() when converting QUrl to/from string. - \endlist -*/ -QUrl QUrl::fromUserInput(const QString &userInput) -{ - QString trimmedString = userInput.trimmed(); - - // Absolute files - if (QDir::isAbsolutePath(trimmedString)) - return QUrl::fromLocalFile(trimmedString); - - // Check the most common case of a valid url with scheme and host first - QUrl url = QUrl::fromEncoded(trimmedString.toUtf8(), QUrl::TolerantMode); - if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) - return url; - - // If the string is missing the scheme or the scheme is not valid, prepend a scheme - QString scheme = url.scheme(); - if (scheme.isEmpty() || scheme.contains(QLatin1Char('.')) || scheme == QLatin1String("localhost")) { - // Do not do anything for strings such as "foo", only "foo.com" - int dotIndex = trimmedString.indexOf(QLatin1Char('.')); - if (dotIndex != -1 || trimmedString.startsWith(QLatin1String("localhost"))) { - const QString hostscheme = trimmedString.left(dotIndex).toLower(); - QByteArray scheme = (hostscheme == QLatin1String("ftp")) ? "ftp" : "http"; - trimmedString = QLatin1String(scheme) + QLatin1String("://") + trimmedString; - } - url = QUrl::fromEncoded(trimmedString.toUtf8(), QUrl::TolerantMode); - } - - if (url.isValid()) - return url; - - return QUrl(); -} - -/*! Returns a decoded copy of \a input. \a input is first decoded from percent encoding, then converted from UTF-8 to unicode. */ @@ -6227,4 +6154,107 @@ QString QUrl::errorString() const \internal */ +// The following code has the following copyright: +/* + Copyright (C) Research In Motion Limited 2009. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Research In Motion Limited nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY Research In Motion Limited ''AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL Research In Motion Limited BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + + +/*! + Returns a valid URL from a user supplied \a userInput string if one can be + deducted. In the case that is not possible, an invalid QUrl() is returned. + + \since 4.6 + + Most applications that can browse the web, allow the user to input a URL + in the form of a plain string. This string can be manually typed into + a location bar, obtained from the clipboard, or passed in via command + line arguments. + + When the string is not already a valid URL, a best guess is performed, + making various web related assumptions. + + In the case the string corresponds to a valid file path on the system, + a file:// URL is constructed, using QUrl::fromLocalFile(). + + If that is not the case, an attempt is made to turn the string into a + http:// or ftp:// URL. The latter in the case the string starts with + 'ftp'. The result is then passed through QUrl's tolerant parser, and + in the case or success, a valid QUrl is returned, or else a QUrl(). + + \section1 Examples: + + \list + \o qt.nokia.com becomes http://qt.nokia.com + \o ftp.qt.nokia.com becomes ftp://ftp.qt.nokia.com + \o localhost becomes http://localhost + \o /home/user/test.html becomes file:///home/user/test.html (if exists) + \endlist + + \section2 Tips to avoid erroneous character conversion when dealing with + URLs and strings: + + \list + \o When creating an URL QString from a QByteArray or a char*, always use + QString::fromUtf8(). + \o Favor the use of QUrl::fromEncoded() and QUrl::toEncoded() instead of + QUrl(string) and QUrl::toString() when converting QUrl to/from string. + \endlist +*/ +QUrl QUrl::fromUserInput(const QString &userInput) +{ + QString trimmedString = userInput.trimmed(); + + // Check the most common case of a valid url with scheme and host first + QUrl url = QUrl::fromEncoded(trimmedString.toUtf8(), QUrl::TolerantMode); + if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) + return url; + + // Absolute files that exists + if (QDir::isAbsolutePath(trimmedString) && QFile::exists(trimmedString)) + return QUrl::fromLocalFile(trimmedString); + + // If the string is missing the scheme or the scheme is not valid prepend a scheme + QString scheme = url.scheme(); + if (scheme.isEmpty() || scheme.contains(QLatin1Char('.')) || scheme == QLatin1String("localhost")) { + // Do not do anything for strings such as "foo", only "foo.com" + int dotIndex = trimmedString.indexOf(QLatin1Char('.')); + if (dotIndex != -1 || trimmedString.startsWith(QLatin1String("localhost"))) { + const QString hostscheme = trimmedString.left(dotIndex).toLower(); + QByteArray scheme = (hostscheme == QLatin1String("ftp")) ? "ftp" : "http"; + trimmedString = QLatin1String(scheme) + QLatin1String("://") + trimmedString; + } + url = QUrl::fromEncoded(trimmedString.toUtf8(), QUrl::TolerantMode); + } + + if (url.isValid()) + return url; + + return QUrl(); +} +// end of BSD code + QT_END_NAMESPACE diff --git a/src/corelib/kernel/qtcore_eval.cpp b/src/corelib/kernel/qtcore_eval.cpp new file mode 100644 index 0000000..fe47a30 --- /dev/null +++ b/src/corelib/kernel/qtcore_eval.cpp @@ -0,0 +1,569 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qcoreevent.h> +#include <qdatetime.h> +#include <qlibraryinfo.h> +#include <qobject.h> +#include <qcoreapplication.h> + +#include "stdio.h" +#include "stdlib.h" + +QT_BEGIN_NAMESPACE + +#include "qconfig_eval.cpp" + +static const char boilerplate_unsuported[] = + "\nQt %1 Evaluation License\n" + "Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).\n" + "All rights reserved.\n\n" + "This trial version may only be used for evaluation purposes\n" + "and will shut down after 120 minutes.\n" + "Registered to:\n" + " Licensee: %2\n\n" + "The evaluation expires in %4 days\n\n" + "Contact http://qt.nokia.com/about/contact-us for pricing and purchasing information.\n"; + +static const char boilerplate_supported[] = + "\nQt %1 Evaluation License\n" + "Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).\n" + "All rights reserved.\n\n" + "This trial version may only be used for evaluation purposes\n" + "Registered to:\n" + " Licensee: %2\n\n" + "The evaluation expires in %4 days\n\n" + "Contact http://qt.nokia.com/about/contact-us for pricing and purchasing information.\n"; + +static const char boilerplate_expired[] = + "This software is using the trial version of the Qt GUI toolkit.\n" + "The trial period has expired. If you need more time to\n" + "evaluate Qt, or if you have any questions about Qt, contact us\n" + "at: http://qt.nokia.com/about/contact-us.\n\n"; + +static const char will_shutdown_1min[] = + "\nThe evaluation of Qt will SHUT DOWN in 1 minute.\n" + "Contact http://qt.nokia.com/about/contact-us for pricing and purchasing information.\n"; + +static const char will_shutdown_now[] = + "\nThe evaluation of Qt has now reached its automatic\n" + "timeout and will shut down.\n" + "Contact http://qt.nokia.com/about/contact-us for pricing and purchasing information.\n"; + +static int qt_eval_days_left() +{ + const char *const license_key = qt_eval_key_data + 12; + + // fast fail + if (!qt_eval_key_data[0] || !*license_key) + return -2; + + QDate today = QDate::currentDate(); + QDate build = QLibraryInfo::buildDate(); + return qMax(-1, today.daysTo(build) + 30); +} + +static int qt_eval_is_supported() +{ + const char *const license_key = qt_eval_key_data + 12; + if (!qt_eval_key_data[0] || !*license_key) + return -1; + + // is this an unsupported evaluation? + const char* typecode = license_key; + int field = 2; + for ( ; field && *typecode; ++typecode) + if (*typecode == '-') + --field; + + if (!field && typecode[1] == '4' && typecode[2] == 'M') { + if (typecode[0] == 'Q') + return 0; + else if (typecode[0] == 'R' || typecode[0] == 'Z') + return 1; + } + return -1; +} + +static QString qt_eval_string() +{ + const char *msg; + switch (qt_eval_is_supported()) { + case 0: + msg = boilerplate_unsuported; + break; + case 1: + msg = boilerplate_supported; + break; + default: + return QString(); + msg = 0; + } + + return QString::fromLatin1(msg) + .arg(QLatin1String(QT_VERSION_STR)) + .arg(QLibraryInfo::licensee()) + .arg(qt_eval_days_left()); +} + +#define WARN_TIMEOUT 60 * 1000 * 119 +#define KILL_DELAY 60 * 1000 * 1 + +class QCoreFuriCuri : public QObject +{ +public: + + int warn; + int kill; + + QCoreFuriCuri() : QObject(), warn(-1), kill(-1) + { + if (!qt_eval_is_supported()) { + warn = startTimer(WARN_TIMEOUT); + kill = 0; + } + } + + void timerEvent(QTimerEvent *e) { + if (e->timerId() == warn) { + killTimer(warn); + fprintf(stderr, "%s\n", will_shutdown_1min); + kill = startTimer(KILL_DELAY); + } else if (e->timerId() == kill) { + fprintf(stderr, "%s\n", will_shutdown_now); + QCoreApplication::instance()->quit(); + } + } +}; + +#if defined(QT_BUILD_CORE_LIB) || defined (QT_BOOTSTRAPPED) + +void qt_core_eval_init(uint type) +{ + switch (qt_eval_days_left()) { + case -2: + return; + + case -1: + fprintf(stderr, "%s\n", boilerplate_expired); + if (type == 0) { + // if we're a console app only. + exit(0); + } + + default: + fprintf(stderr, "%s\n", qPrintable(qt_eval_string())); + if (type == 0) { + Q_UNUSED(new QCoreFuriCuri()); + } + } +} +#endif + +#ifdef QT_BUILD_GUI_LIB + +QT_BEGIN_INCLUDE_NAMESPACE +#include <qdialog.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qmessagebox.h> +#include <qpushbutton.h> +#include <qtimer.h> +#include <qapplication.h> +QT_END_INCLUDE_NAMESPACE + + +static const char * const qtlogo_eval_xpm[] = { +/* columns rows colors chars-per-pixel */ +"46 55 174 2", +" c #002E02", +". c #00370D", +"X c #003A0E", +"o c #003710", +"O c #013C13", +"+ c #043E1A", +"@ c #084F0A", +"# c #0B520C", +"$ c #054413", +"% c #0C4C17", +"& c #07421D", +"* c #09451D", +"= c #0D491E", +"- c #125515", +"; c #13541A", +": c #17591B", +"> c #1B5C1D", +", c #1F611F", +"< c #20621E", +"1 c #337B1E", +"2 c #0B4521", +"3 c #0F4923", +"4 c #114B24", +"5 c #154D2A", +"6 c #175323", +"7 c #1C5924", +"8 c #1C532F", +"9 c #1E5432", +"0 c #245936", +"q c #265938", +"w c #295C3B", +"e c #246324", +"r c #266823", +"t c #2A6C24", +"y c #276628", +"u c #2D7026", +"i c #327427", +"p c #367927", +"a c #37782A", +"s c #397C2A", +"d c #2E613E", +"f c #336C37", +"g c #2F6040", +"h c #356545", +"j c #3C6B4E", +"k c #3F6C51", +"l c #406E4F", +"z c #406D52", +"x c #477457", +"c c #497557", +"v c #4B7857", +"b c #517B5E", +"n c #3C8423", +"m c #3E812C", +"M c #53A61D", +"N c #41862C", +"B c #458A2D", +"V c #498F2D", +"C c #479324", +"Z c #489226", +"A c #4D952C", +"S c #478B30", +"D c #488C30", +"F c #4D9232", +"G c #509632", +"H c #549A33", +"J c #589F35", +"K c #56A526", +"L c #57A821", +"P c #5BAA27", +"I c #57A32A", +"U c #5CA72E", +"Y c #5DAB2A", +"T c #5CA336", +"R c #60AD2E", +"E c #63B12D", +"W c #65AF35", +"Q c #62A53F", +"! c #65AE39", +"~ c #66B036", +"^ c #6AB437", +"/ c #67B138", +"( c #6AB339", +") c #6DB838", +"_ c #70BA3C", +"` c #4D8545", +"' c #4E8942", +"] c #548851", +"[ c #6FAF4A", +"{ c #6DB243", +"} c #71B546", +"| c #70B840", +" . c #73B648", +".. c #79BA4E", +"X. c #7CBB53", +"o. c #598266", +"O. c #62886D", +"+. c #6A8F75", +"@. c #6B9173", +"#. c #70937A", +"$. c #799F79", +"%. c #7BAF66", +"&. c #81BD5B", +"*. c #85BF60", +"=. c #85AC7F", +"-. c #8DBA7B", +";. c #87C061", +":. c #8AC364", +">. c #8DC46A", +",. c #90C56E", +"<. c #93C771", +"1. c #96CA73", +"2. c #9ACB7C", +"3. c #9FD07D", +"4. c #779981", +"5. c #7F9F89", +"6. c #809F88", +"7. c #82A18B", +"8. c #86A192", +"9. c #8DA994", +"0. c #8FA998", +"q. c #94AF9B", +"w. c #97B991", +"e. c #97B19E", +"r. c #9DB6A3", +"t. c #A3BCA7", +"y. c #A6BCAB", +"u. c #A9BEB1", +"i. c #9ECD81", +"p. c #A2CF85", +"a. c #A5D284", +"s. c #A6D189", +"d. c #A9D28E", +"f. c #ABD491", +"g. c #B1D797", +"h. c #B1D699", +"j. c #B5D89E", +"k. c #ADC5AC", +"l. c #B1CAAE", +"z. c #B9DAA3", +"x. c #BDDDA8", +"c. c #ADC1B4", +"v. c #B2C6B6", +"b. c #B5C6BC", +"n. c #B6C9BA", +"m. c #BCD1BA", +"M. c #C6E1B4", +"N. c #CDE5BD", +"B. c #C2D2C6", +"V. c #CADEC2", +"C. c #C6D3CC", +"Z. c #C8D7CB", +"A. c #CEDAD2", +"S. c #D2DDD4", +"D. c #D3E9C6", +"F. c #D7EBC9", +"G. c #D9EBCD", +"H. c #DEEED4", +"J. c #D6E0D9", +"K. c #DAE4DC", +"L. c #E0EFD7", +"P. c #E5F2DD", +"I. c #DFE8E0", +"U. c #E4EBE5", +"Y. c #E9EFEA", +"T. c #EDF4EB", +"R. c #F0FAE6", +"E. c #F1F8EC", +"W. c #EDF0F0", +"Q. c #F4F7F3", +"!. c #F6F9F4", +"~. c #F8FAF7", +"^. c #FEFEFE", +"/. c None", +/* pixels */ +"/././././.c h ' Q / W _ &.p././././././././././././././././././././././././././././././././.", +"/././.4 O % Z ~ ~ W ~ W R U R R ( X.>.p././././././././././././././././././././././././././.", +"/./.. * = J _ ~ ~ ~ ~ ~ / / / / W W U P P U W .;.2././././././././././././././././././././.", +"/.= = & a ) W ~ ~ ~ ~ ~ / W / ~ ~ ~ ^ ( ( ^ ~ R R U P Y ~ .;.2././././././././././././././.", +"O.O = = T ^ W ~ ~ ~ ~ ~ ~ W W / W ~ ~ ~ ~ ~ ~ ~ ( ( ( ( ~ W Y Y Y Y W { &.1././././././././.", +"0 = * 7 ~ ~ ~ ~ ~ ~ ~ ~ ~ / / W ~ ~ ~ ~ ~ ~ ~ ~ W W W ~ ~ ~ ~ ( ( ( W W R U P U W { X.1.f./.", +"= = & e ^ W ~ ~ ~ ~ ~ ~ ~ ~ / / ~ ~ ~ ~ ~ ~ ~ ~ W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ^ ( ( / ~ W R U U Y ", +"= = & e ^ W ~ ~ ~ ~ ~ ~ ~ ~ W W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ( W ~ ~ ~ ^ ^ ( ", +"= = * e ^ W ~ ~ ~ ~ ~ ~ / W / W ! ( / ~ W ^ ( ( ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ~ W W ~ ~ ~ ~ ~ ~ ", +"= = & e ^ ! ~ ~ ~ ~ ~ ~ W W ^ _ ~ K Y W W R P Y W ( ~ ~ ~ ~ ~ ~ ~ W / ~ ~ ~ ^ W ~ ~ ~ ~ ~ ~ ", +"= = & e ^ W ~ ~ ~ ~ ~ ~ W ) W 1 ` w.V.L.H.D.z.,.~ Y ^ ~ ~ ~ ~ ~ W ~ ~ ~ ( ~ W W ~ ~ ~ ~ ~ ~ ", +"= = & e ^ W ~ ~ ~ ~ ~ W ) V = 8.~.^.^.^.^.^.^.^.U.<.Y ~ ~ ~ ~ ~ W W ! ~ Y W ^ W ~ ~ ~ ~ ~ ~ ", +"= = & e ^ W ~ ~ ~ ~ W ^ B O u.^.~.^.^.^.^.~.~.^.^.^.h.Y ^ ~ ~ ^ F $ k.R.G.1.Y / ~ ~ ~ ~ ~ ~ ", +"= = & e ^ ~ ~ ~ / W ( J X 7.^.~.^.^.^.^.^.^.^.^.^.^.^.s.Y / W ) a 2 U.^.^.d.U ( ~ ~ ~ ~ ~ ~ ", +"= = & e ^ W / ~ ~ ~ ^ > w ~.^.^.^.^.^.F.%.v c.^.^.^.^.~.X.W ~ ^ > h ^.^.^.d.P ( ~ ~ ~ ~ ~ ~ ", +"= = & e ^ W ~ ~ W ^ H o e.^.^.^.^.^.G.Y E n . y.^.^.^.^.M.Y ( ! $ @.^.~.^.f.U ( / ~ ~ W ~ ~ ", +"= = & e ^ W ~ W ! ) t 4 U.^.^.^.^.^.>.U ( _ , 9 ~.^.^.^.~...^ A y.^.~.^.s.M W Y ~ ~ ~ ~ ~ ", +"= 3 & e ^ W ~ ( ^ ( $ c ^.^.^.^.^.E.) ~ ~ ^ S o n.^.^.^.^.=.- l.v.Y.^.^.^.M.:.:.X.~ ~ ~ ~ ~ ", +"= = & e ^ ! W W ( J X 7.^.^.^.^.^.F.Y ( W ^ T X 6.^.^.~.^.c.. J.^.^.^.^.^.^.^.^.P.~ ~ ~ ~ ~ ", +"= = & r ^ W / W ) B o v.^.~.^.^.^.M.U / ~ ~ ! $ o.^.^.^.^.K.* S.^.^.^.^.^.^.^.^.P.~ ~ ~ ~ ~ ", +"= = & e ^ ! ~ W ) a + S.^.^.^.^.^.z.P ( W ~ ( % z ^.^.^.^.~.f t.U.^.^.^.^.~.^.^.P.~ ~ ~ ~ ~ ", +"* = & e ^ W ~ W ) t 3 Y.^.^.^.^.^.f.P ( ~ ~ ^ ; h ^.^.^.^.^.:.@ j ^.^.^.^.h.{ X.&.~ ~ ~ ~ ~ ", +"3 = & e ^ W ~ ~ ^ e 8 Q.^.^.^.^.^.s.P ~ ~ W ^ > 0 ~.^.^.^.^.1.# z ^.^.^.^.d.L W R ~ ~ ~ ~ ~ ", +"= = & e ^ W ~ ~ ^ > q ~.^.^.^.^.^.p.U ^ ~ W ) e 9 ~.^.^.^.^.3.# k ^.^.^.^.f.Y ( / ~ ~ ~ ~ ~ ", +"= = & e ^ W / W ^ > w ~.^.^.^.^.^.i.Y / ~ W ^ e 8 Q.^.^.^.^.a.# z ^.^.^.^.f.Y / ~ ~ ~ ~ ~ ~ ", +"= = & e ^ W / W ^ > w ^.^.^.^.^.^.2.Y / ~ ~ ) e 8 Q.^.^.^.^.s.# z ^.^.^.^.d.P ( ~ ~ ~ ~ ~ ~ ", +"= = & e ^ W W W ^ > q ^.^.^.^.^.^.p.Y / ~ ~ ^ e 9 Q.^.^.^.^.a.@ z ^.^.^.^.f.U / ~ ~ ~ ~ ~ ~ ", +"= = & e ^ W / W ) 7 9 Q.^.^.^.^.^.a.P / ~ W ) , 9 Q.^.^.^.^.3.# z ^.^.~.^.f.P ^ ~ ~ ~ ~ ~ ~ ", +"= = & e ^ W / W ) r 5 T.^.^.^.^.^.d.Y / ~ W ) > q ~.^.^.^.^.1.# k ^.^.^.^.f.Y ( ~ ~ ~ ~ ~ ~ ", +"= = & e ^ / / W ) i 2 I.^.^.^.^.^.h.P ( ~ W ( > g ^.^.^.^.^.:.# z ^.^.^.^.f.P / ~ ~ ~ ~ ~ ~ ", +"= = & e ( W / W ) m O Z.^.^.^.^.^.x.P / ~ ~ ( ; j ^.^.^.^.~.&.- k ^.^.~.^.f.P / ~ ~ ~ ~ ~ ~ ", +"= = & e ( W / W ) F o y.^.~.^.^.^.N.U ( ~ ~ W $ b ^.^.^.^.R._ - k ^.^.^.^.f.Y ( ~ ~ ~ ~ ~ ~ ", +"= = & e ^ W ~ ~ ^ J X 4.^.^.^.^.^.L.~ ~ W ^ T X #.^.^.^.^.F.~ ; j ^.^.^.^.f.U ( ~ ~ ~ ~ ~ ~ ", +"= = & e ^ ~ ~ ~ / ^ % l ^.^.^.^.^.!. .R ^ ^ G . r.^.~.^.^.j.E : j ^.^.^.^.f.P ) ( ~ ~ ~ ~ ~ ", +"= = & e ^ W ~ ~ W ) u = U.^.^.^.^.^.1.Y ! ) a & K.^.^.^.^.;.~ : j ^.^.~.^.z.M I I / ~ ~ W ~ ", +"= = & e ( W ~ ~ W ( G . q.^.^.^.^.^.D.U ^ ! X o.^.^.^.^.P.~ ^ > g ^.^.^.^.E.-.$.m.X.W ~ ~ ~ ", +"= = & e ^ / ~ ~ ^ ! ( > w ~.^.^.^.^.^.h.T > j T.^.^.~.^.a.Y _ i 3 U.^.^.^.^.^.^.^.X.R ~ ~ ~ ", +"= = & e ^ / ~ ~ W W ^ H . 9.^.~.^.^.^.^.K.C.~.^.^.^.^.H.W W ^ T . q.^.~.^.^.^.^.^.X.R ~ ~ ~ ", +"= = + e ^ W / ~ W W W ) m + B.^.~.^.^.^.^.^.^.^.^.^.E.X.Y ( W ^ B 6 y.^.^.^.E.D.2.( ~ ~ ~ ~ ", +"= = * e ^ ! / ! W ^ W W ) a 4 b.^.^.^.^.^.^.^.^.^.P...Y ( ! W ! ^ W Z [ *.X.{ Y U ~ ~ ~ ~ ~ ", +"= = & e ( W ~ ~ W / W / W ) A < +.A.~.^.^.^.^.!.p.W R ~ ~ ~ ~ ~ W / ) E U W W / ^ ~ ~ ~ ~ ~ ", +"= = & e ^ W ~ ~ / W / / / W ( _ Z X 6.^.^.^.^.E.W ~ ^ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ / ~ ~ ~ ~ ~ ~ ~ ~ ", +"= = & e ^ ~ ~ ~ W W / W ~ ~ ~ ~ ) ; h ^.^.^.^.^.d.M U ~ / ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ", +"= = & e ^ W ~ ~ ^ W W / ~ ~ ~ W ) p + S.^.^.^.^.~.M.f. .W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ .", +"= = & e ^ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ( T O +.^.~.^.^.^.^.^.&.Y ( ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ( Y 2.", +"= = & e ( W ~ ~ ~ ~ ~ ~ ~ ~ ~ / W ) N + b.^.^.^.^.^.^.&.R ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W /.", +"= = & e ^ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ^ N 7 r.W.^.^.^.!.X.W ~ ~ W ~ W ~ ~ ~ ~ ~ ~ / ( ( K p./.", +"= = & e ( W ~ ~ W ~ ~ ~ ~ ~ ~ ~ ~ ~ W ( W C Q &.:.X.| ~ ~ ~ ~ W ~ / ~ ( / ( ~ W E U P 1././.", +"= = + e ^ / / / ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W / ) ^ R Y W W ~ ~ ( / ( / W R Y Y U R ( X.,././././.", +"= = * e ( / ~ / ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W ! ( ( ( W W E U P Y W ( X.,.d./././././././././.", +"= = * e ( W ~ ~ ~ ~ W ! ~ W ~ W ~ ( ( / ^ W W U Y P W ( X.,.d./././././././././././././././.", +"8 $ * e ( W ~ ~ ~ ! ( ( ( / ( W R Y Y Y R ( X.>.d./././././././././././././././././././././.", +"/.d . y ^ / / / ( W Y Y P P W ( X.>.d./././././././././././././././././././././././././././.", +"/./.h : ^ R R R W ( X.<.f./././././././././././././././././././././././././././././././././.", +"/././.] _ *.3./././././././././././././././././././././././././././././././././././././././." +}; + +class EvalMessageBox : public QDialog +{ +public: + EvalMessageBox(bool expired) + { + setWindowTitle(QLatin1String(" ")); + + QString str = qt_eval_string(); + if (expired) { + str = QLatin1String(boilerplate_expired); + } else { + str = qt_eval_string(); + } + str = str.trimmed(); + + QFrame *border = new QFrame(this); + + QLabel *pixmap_label = new QLabel(border); + pixmap_label->setPixmap(qtlogo_eval_xpm); + pixmap_label->setAlignment(Qt::AlignTop); + + QLabel *text_label = new QLabel(str, border); + + QHBoxLayout *pm_and_text_layout = new QHBoxLayout(); + pm_and_text_layout->addWidget(pixmap_label); + pm_and_text_layout->addWidget(text_label); + + QVBoxLayout *master_layout = new QVBoxLayout(border); + master_layout->addLayout(pm_and_text_layout); + + QVBoxLayout *border_layout = new QVBoxLayout(this); + border_layout->setMargin(0); + border_layout->addWidget(border); + + if (expired) { + QPushButton *cmd = new QPushButton(QLatin1String("OK"), border); + cmd->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + cmd->setDefault(true); + + QHBoxLayout *button_layout = new QHBoxLayout(); + master_layout->addLayout(button_layout); + button_layout->addWidget(cmd); + + connect(cmd, SIGNAL(clicked()), this, SLOT(close())); + } else { + border->setFrameShape(QFrame::WinPanel); + border->setFrameShadow(QFrame::Raised); + setParent(parentWidget(), Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); + QTimer::singleShot(7000, this, SLOT(close())); + setAttribute(Qt::WA_DeleteOnClose); + } + + setFixedSize(sizeHint()); + } +}; + +class QGuiFuriCuri : public QCoreFuriCuri +{ +public: + void timerEvent(QTimerEvent *e) { + if (e->timerId() == warn) { + killTimer(warn); + QMessageBox::information(0, QLatin1String("Automatic Timeout"), QLatin1String(will_shutdown_1min)); + kill = startTimer(KILL_DELAY); + } else if (e->timerId() == kill) { + killTimer(kill); + QMessageBox::information(0, QLatin1String("Automatic Timeout"), QLatin1String(will_shutdown_now)); + qApp->quit(); + } + } +}; + + +void qt_gui_eval_init(uint) +{ + switch (qt_eval_days_left()) { + case -2: + return; + + case -1: { + EvalMessageBox box(true); + box.exec(); + ::exit(0); + } + + default: { + EvalMessageBox *box = new EvalMessageBox(false); + box->show(); + Q_UNUSED(new QGuiFuriCuri()); + } + } +} + +static QString qt_eval_title_prefix() +{ + return QLatin1String("[Qt Evaluation] "); +} + +QString qt_eval_adapt_window_title(const QString &title) +{ + if (qt_eval_days_left() == -2) + return title; + return qt_eval_title_prefix() + title; +} + +void qt_eval_init_widget(QWidget *w) +{ + if (qt_eval_days_left() == -2) + return; + if (w->isTopLevel()) { + QString windowTitle = w->windowTitle(); + if (windowTitle.isEmpty()) { + w->setWindowTitle(QLatin1String(" ")); + } else if (!windowTitle.startsWith(qt_eval_title_prefix())) { + qt_eval_adapt_window_title(windowTitle); + } + } +} +#endif + +QT_END_NAMESPACE diff --git a/src/corelib/statemachine/qabstractstate.cpp b/src/corelib/statemachine/qabstractstate.cpp index 72d640b..ec5332f 100644 --- a/src/corelib/statemachine/qabstractstate.cpp +++ b/src/corelib/statemachine/qabstractstate.cpp @@ -78,7 +78,8 @@ QT_BEGIN_NAMESPACE function to perform custom processing when the state is exited. */ -QAbstractStatePrivate::QAbstractStatePrivate() +QAbstractStatePrivate::QAbstractStatePrivate(StateType type) + : stateType(type), isMachine(false), parentState(0) { } @@ -87,6 +88,11 @@ QAbstractStatePrivate *QAbstractStatePrivate::get(QAbstractState *q) return q->d_func(); } +const QAbstractStatePrivate *QAbstractStatePrivate::get(const QAbstractState *q) +{ + return q->d_func(); +} + QStateMachine *QAbstractStatePrivate::machine() const { QObject *par = parent; @@ -126,7 +132,7 @@ void QAbstractStatePrivate::emitExited() Constructs a new state with the given \a parent state. */ QAbstractState::QAbstractState(QState *parent) - : QObject(*new QAbstractStatePrivate, parent) + : QObject(*new QAbstractStatePrivate(QAbstractStatePrivate::AbstractState), parent) { } @@ -150,7 +156,10 @@ QAbstractState::~QAbstractState() */ QState *QAbstractState::parentState() const { - return qobject_cast<QState*>(parent()); + Q_D(const QAbstractState); + if (d->parentState != parent()) + d->parentState = qobject_cast<QState*>(parent()); + return d->parentState; } /*! diff --git a/src/corelib/statemachine/qabstractstate_p.h b/src/corelib/statemachine/qabstractstate_p.h index 4b1306d..faea6b6 100644 --- a/src/corelib/statemachine/qabstractstate_p.h +++ b/src/corelib/statemachine/qabstractstate_p.h @@ -65,9 +65,17 @@ class QAbstractStatePrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QAbstractState) public: - QAbstractStatePrivate(); + enum StateType { + AbstractState, + StandardState, + FinalState, + HistoryState + }; + + QAbstractStatePrivate(StateType type); static QAbstractStatePrivate *get(QAbstractState *q); + static const QAbstractStatePrivate *get(const QAbstractState *q); QStateMachine *machine() const; @@ -76,6 +84,10 @@ public: void emitEntered(); void emitExited(); + + uint stateType:31; + uint isMachine:1; + mutable QState *parentState; }; QT_END_NAMESPACE diff --git a/src/corelib/statemachine/qfinalstate.cpp b/src/corelib/statemachine/qfinalstate.cpp index 761eee4..d900ddd 100644 --- a/src/corelib/statemachine/qfinalstate.cpp +++ b/src/corelib/statemachine/qfinalstate.cpp @@ -92,6 +92,7 @@ public: }; QFinalStatePrivate::QFinalStatePrivate() + : QAbstractStatePrivate(FinalState) { } diff --git a/src/corelib/statemachine/qhistorystate.cpp b/src/corelib/statemachine/qhistorystate.cpp index 0c2b858..18436d3 100644 --- a/src/corelib/statemachine/qhistorystate.cpp +++ b/src/corelib/statemachine/qhistorystate.cpp @@ -120,7 +120,8 @@ QT_BEGIN_NAMESPACE */ QHistoryStatePrivate::QHistoryStatePrivate() - : defaultState(0), historyType(QHistoryState::ShallowHistory) + : QAbstractStatePrivate(HistoryState), + defaultState(0), historyType(QHistoryState::ShallowHistory) { } diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp index 9abf20b..5dc310b 100644 --- a/src/corelib/statemachine/qstate.cpp +++ b/src/corelib/statemachine/qstate.cpp @@ -124,8 +124,9 @@ QT_BEGIN_NAMESPACE */ QStatePrivate::QStatePrivate() - : errorState(0), initialState(0), childMode(QState::ExclusiveStates), - transitionsListNeedsRefresh(true) + : QAbstractStatePrivate(StandardState), + errorState(0), initialState(0), childMode(QState::ExclusiveStates), + childStatesListNeedsRefresh(true), transitionsListNeedsRefresh(true) { } @@ -181,15 +182,18 @@ QState::~QState() QList<QAbstractState*> QStatePrivate::childStates() const { - QList<QAbstractState*> result; - QList<QObject*>::const_iterator it; - for (it = children.constBegin(); it != children.constEnd(); ++it) { - QAbstractState *s = qobject_cast<QAbstractState*>(*it); - if (!s || qobject_cast<QHistoryState*>(s)) - continue; - result.append(s); + if (childStatesListNeedsRefresh) { + childStatesList.clear(); + QList<QObject*>::const_iterator it; + for (it = children.constBegin(); it != children.constEnd(); ++it) { + QAbstractState *s = qobject_cast<QAbstractState*>(*it); + if (!s || qobject_cast<QHistoryState*>(s)) + continue; + childStatesList.append(s); + } + childStatesListNeedsRefresh = false; } - return result; + return childStatesList; } QList<QHistoryState*> QStatePrivate::historyStates() const @@ -473,8 +477,10 @@ void QState::setChildMode(ChildMode mode) bool QState::event(QEvent *e) { Q_D(QState); - if ((e->type() == QEvent::ChildAdded) || (e->type() == QEvent::ChildRemoved)) + if ((e->type() == QEvent::ChildAdded) || (e->type() == QEvent::ChildRemoved)) { + d->childStatesListNeedsRefresh = true; d->transitionsListNeedsRefresh = true; + } return QAbstractState::event(e); } diff --git a/src/corelib/statemachine/qstate_p.h b/src/corelib/statemachine/qstate_p.h index 3b5f416..34c8838 100644 --- a/src/corelib/statemachine/qstate_p.h +++ b/src/corelib/statemachine/qstate_p.h @@ -99,6 +99,8 @@ public: QAbstractState *errorState; QAbstractState *initialState; QState::ChildMode childMode; + mutable bool childStatesListNeedsRefresh; + mutable QList<QAbstractState*> childStatesList; mutable bool transitionsListNeedsRefresh; mutable QList<QAbstractTransition*> transitionsList; diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index e182c88..ea5587e 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -178,6 +178,8 @@ QT_BEGIN_NAMESPACE QStateMachinePrivate::QStateMachinePrivate() { + QAbstractStatePrivate::isMachine = true; + state = NotRunning; _startState = 0; processing = false; @@ -336,7 +338,7 @@ QSet<QAbstractTransition*> QStateMachinePrivate::selectTransitions(QEvent *event if (isPreempted(state, enabledTransitions)) continue; QList<QState*> lst = properAncestors(state, rootState()->parentState()); - if (QState *grp = qobject_cast<QState*>(state)) + if (QState *grp = toStandardState(state)) lst.prepend(grp); bool found = false; for (int j = 0; (j < lst.size()) && !found; ++j) { @@ -414,7 +416,7 @@ QList<QAbstractState*> QStateMachinePrivate::exitStates(QEvent *event, const QLi qSort(statesToExit_sorted.begin(), statesToExit_sorted.end(), stateExitLessThan); for (int i = 0; i < statesToExit_sorted.size(); ++i) { QAbstractState *s = statesToExit_sorted.at(i); - if (QState *grp = qobject_cast<QState*>(s)) { + if (QState *grp = toStandardState(s)) { QList<QHistoryState*> hlst = QStatePrivate::get(grp)->historyStates(); for (int j = 0; j < hlst.size(); ++j) { QHistoryState *h = hlst.at(j); @@ -563,7 +565,7 @@ void QStateMachinePrivate::addStatesToEnter(QAbstractState *s, QState *root, QSet<QAbstractState*> &statesToEnter, QSet<QAbstractState*> &statesForDefaultEntry) { - if (QHistoryState *h = qobject_cast<QHistoryState*>(s)) { + if (QHistoryState *h = toHistoryState(s)) { QList<QAbstractState*> hconf = QHistoryStatePrivate::get(h)->configuration; if (!hconf.isEmpty()) { for (int k = 0; k < hconf.size(); ++k) { @@ -600,7 +602,7 @@ void QStateMachinePrivate::addStatesToEnter(QAbstractState *s, QState *root, } statesToEnter.insert(s); if (isParallel(s)) { - QState *grp = qobject_cast<QState*>(s); + QState *grp = toStandardState(s); QList<QAbstractState*> lst = QStatePrivate::get(grp)->childStates(); for (int i = 0; i < lst.size(); ++i) { QAbstractState *child = lst.at(i); @@ -608,7 +610,7 @@ void QStateMachinePrivate::addStatesToEnter(QAbstractState *s, QState *root, } } else if (isCompound(s)) { statesForDefaultEntry.insert(s); - QState *grp = qobject_cast<QState*>(s); + QState *grp = toStandardState(s); QAbstractState *initial = grp->initialState(); if (initial != 0) { Q_ASSERT(initial->machine() == q_func()); @@ -660,7 +662,7 @@ void QStateMachinePrivate::applyProperties(const QList<QAbstractTransition*> &tr QHash<QAbstractState*, QList<QPropertyAssignment> > propertyAssignmentsForState; QHash<RestorableId, QVariant> pendingRestorables = registeredRestorables; for (int i = 0; i < enteredStates.size(); ++i) { - QState *s = qobject_cast<QState*>(enteredStates.at(i)); + QState *s = toStandardState(enteredStates.at(i)); if (!s) continue; @@ -831,7 +833,7 @@ void QStateMachinePrivate::applyProperties(const QList<QAbstractTransition*> &tr // Emit polished signal for entered states that have no animated properties. for (int i = 0; i < enteredStates.size(); ++i) { - QState *s = qobject_cast<QState*>(enteredStates.at(i)); + QState *s = toStandardState(enteredStates.at(i)); if (s #ifndef QT_NO_ANIMATION && !animationsForState.contains(s) @@ -845,21 +847,21 @@ void QStateMachinePrivate::applyProperties(const QList<QAbstractTransition*> &tr bool QStateMachinePrivate::isFinal(const QAbstractState *s) { - return qobject_cast<const QFinalState*>(s) != 0; + return s && (QAbstractStatePrivate::get(s)->stateType == QAbstractStatePrivate::FinalState); } bool QStateMachinePrivate::isParallel(const QAbstractState *s) { - const QState *ss = qobject_cast<const QState*>(s); + const QState *ss = toStandardState(s); return ss && (QStatePrivate::get(ss)->childMode == QState::ParallelStates); } bool QStateMachinePrivate::isCompound(const QAbstractState *s) const { - const QState *group = qobject_cast<const QState*>(s); + const QState *group = toStandardState(s); if (!group) return false; - bool isMachine = (qobject_cast<const QStateMachine*>(group) != 0); + bool isMachine = QStatePrivate::get(group)->isMachine; // Don't treat the machine as compound if it's a sub-state of this machine if (isMachine && (group != rootState())) return false; @@ -869,11 +871,11 @@ bool QStateMachinePrivate::isCompound(const QAbstractState *s) const bool QStateMachinePrivate::isAtomic(const QAbstractState *s) const { - const QState *ss = qobject_cast<const QState*>(s); + const QState *ss = toStandardState(s); return (ss && QStatePrivate::get(ss)->childStates().isEmpty()) || isFinal(s) // Treat the machine as atomic if it's a sub-state of this machine - || (ss && (qobject_cast<const QStateMachine*>(ss) != 0) && (ss != rootState())); + || (ss && QStatePrivate::get(ss)->isMachine && (ss != rootState())); } @@ -897,10 +899,38 @@ QList<QState*> QStateMachinePrivate::properAncestors(const QAbstractState *state return result; } +QState *QStateMachinePrivate::toStandardState(QAbstractState *state) +{ + if (state && (QAbstractStatePrivate::get(state)->stateType == QAbstractStatePrivate::StandardState)) + return static_cast<QState*>(state); + return 0; +} + +const QState *QStateMachinePrivate::toStandardState(const QAbstractState *state) +{ + if (state && (QAbstractStatePrivate::get(state)->stateType == QAbstractStatePrivate::StandardState)) + return static_cast<const QState*>(state); + return 0; +} + +QFinalState *QStateMachinePrivate::toFinalState(QAbstractState *state) +{ + if (state && (QAbstractStatePrivate::get(state)->stateType == QAbstractStatePrivate::FinalState)) + return static_cast<QFinalState*>(state); + return 0; +} + +QHistoryState *QStateMachinePrivate::toHistoryState(QAbstractState *state) +{ + if (state && (QAbstractStatePrivate::get(state)->stateType == QAbstractStatePrivate::HistoryState)) + return static_cast<QHistoryState*>(state); + return 0; +} + bool QStateMachinePrivate::isInFinalState(QAbstractState* s) const { if (isCompound(s)) { - QState *grp = qobject_cast<QState*>(s); + QState *grp = toStandardState(s); QList<QAbstractState*> lst = QStatePrivate::get(grp)->childStates(); for (int i = 0; i < lst.size(); ++i) { QAbstractState *cs = lst.at(i); @@ -909,7 +939,7 @@ bool QStateMachinePrivate::isInFinalState(QAbstractState* s) const } return false; } else if (isParallel(s)) { - QState *grp = qobject_cast<QState*>(s); + QState *grp = toStandardState(s); QList<QAbstractState*> lst = QStatePrivate::get(grp)->childStates(); for (int i = 0; i < lst.size(); ++i) { QAbstractState *cs = lst.at(i); @@ -975,7 +1005,7 @@ QAbstractState *QStateMachinePrivate::findErrorState(QAbstractState *context) // Find error state recursively in parent hierarchy if not set explicitly for context state QAbstractState *errorState = 0; if (context != 0) { - QState *s = qobject_cast<QState*>(context); + QState *s = toStandardState(context); if (s != 0) errorState = s->errorState(); @@ -1100,7 +1130,7 @@ void QStateMachinePrivate::_q_animationFinished() animations.removeOne(anim); if (animations.isEmpty()) { animationsForState.erase(it); - QStatePrivate::get(qobject_cast<QState*>(state))->emitPolished(); + QStatePrivate::get(toStandardState(state))->emitPolished(); } } @@ -1216,8 +1246,7 @@ void QStateMachinePrivate::_q_process() delete e; e = 0; } - if (enabledTransitions.isEmpty() && !internalEventQueue.isEmpty()) { - e = internalEventQueue.takeFirst(); + if (enabledTransitions.isEmpty() && ((e = dequeueInternalEvent()) != 0)) { #ifdef QSTATEMACHINE_DEBUG qDebug() << q << ": dequeued internal event" << e << "of type" << e->type(); #endif @@ -1228,13 +1257,7 @@ void QStateMachinePrivate::_q_process() } } if (enabledTransitions.isEmpty()) { - if (externalEventQueue.isEmpty()) { - if (internalEventQueue.isEmpty()) { - processing = false; - stopProcessingReason = EventQueueEmpty; - } - } else { - e = externalEventQueue.takeFirst(); + if ((e = dequeueExternalEvent()) != 0) { #ifdef QSTATEMACHINE_DEBUG qDebug() << q << ": dequeued external event" << e << "of type" << e->type(); #endif @@ -1243,6 +1266,11 @@ void QStateMachinePrivate::_q_process() delete e; e = 0; } + } else { + if (isInternalEventQueueEmpty()) { + processing = false; + stopProcessingReason = EventQueueEmpty; + } } } if (!enabledTransitions.isEmpty()) { @@ -1278,17 +1306,60 @@ void QStateMachinePrivate::_q_process() } } +void QStateMachinePrivate::postInternalEvent(QEvent *e) +{ + QMutexLocker locker(&internalEventMutex); + internalEventQueue.append(e); +} + +void QStateMachinePrivate::postExternalEvent(QEvent *e) +{ + QMutexLocker locker(&externalEventMutex); + externalEventQueue.append(e); +} + +QEvent *QStateMachinePrivate::dequeueInternalEvent() +{ + QMutexLocker locker(&internalEventMutex); + if (internalEventQueue.isEmpty()) + return 0; + return internalEventQueue.takeFirst(); +} + +QEvent *QStateMachinePrivate::dequeueExternalEvent() +{ + QMutexLocker locker(&externalEventMutex); + if (externalEventQueue.isEmpty()) + return 0; + return externalEventQueue.takeFirst(); +} + +bool QStateMachinePrivate::isInternalEventQueueEmpty() +{ + QMutexLocker locker(&internalEventMutex); + return internalEventQueue.isEmpty(); +} + +bool QStateMachinePrivate::isExternalEventQueueEmpty() +{ + QMutexLocker locker(&externalEventMutex); + return externalEventQueue.isEmpty(); +} + void QStateMachinePrivate::processEvents(EventProcessingMode processingMode) { + Q_Q(QStateMachine); if ((state != Running) || processing || processingScheduled) return; switch (processingMode) { case DirectProcessing: - _q_process(); - break; + if (QThread::currentThread() == q->thread()) { + _q_process(); + break; + } // fallthrough -- processing must be done in the machine thread case QueuedProcessing: processingScheduled = true; - QMetaObject::invokeMethod(q_func(), "_q_process", Qt::QueuedConnection); + QMetaObject::invokeMethod(q, "_q_process", Qt::QueuedConnection); break; } } @@ -1296,6 +1367,7 @@ void QStateMachinePrivate::processEvents(EventProcessingMode processingMode) void QStateMachinePrivate::cancelAllDelayedEvents() { Q_Q(QStateMachine); + QMutexLocker locker(&delayedEventsMutex); QHash<int, QEvent*>::const_iterator it; for (it = delayedEvents.constBegin(); it != delayedEvents.constEnd(); ++it) { int id = it.key(); @@ -1346,7 +1418,7 @@ void QStateMachinePrivate::goToState(QAbstractState *targetState) if (state == Running) { QSet<QAbstractState*>::const_iterator it; for (it = configuration.constBegin(); it != configuration.constEnd(); ++it) { - sourceState = qobject_cast<QState*>(*it); + sourceState = toStandardState(*it); if (sourceState != 0) break; } @@ -1370,7 +1442,7 @@ void QStateMachinePrivate::goToState(QAbstractState *targetState) void QStateMachinePrivate::registerTransitions(QAbstractState *state) { - QState *group = qobject_cast<QState*>(state); + QState *group = toStandardState(state); if (!group) return; QList<QAbstractTransition*> transitions = QStatePrivate::get(group)->transitions(); @@ -1547,7 +1619,7 @@ void QStateMachinePrivate::handleFilteredEvent(QObject *watched, QEvent *event) { Q_ASSERT(qobjectEvents.contains(watched)); if (qobjectEvents[watched].contains(event->type())) { - internalEventQueue.append(new QStateMachine::WrappedEvent(watched, handler->cloneEvent(event))); + postInternalEvent(new QStateMachine::WrappedEvent(watched, handler->cloneEvent(event))); processEvents(DirectProcessing); } } @@ -1571,7 +1643,7 @@ void QStateMachinePrivate::handleTransitionSignal(QObject *sender, int signalInd qDebug() << q_func() << ": sending signal event ( sender =" << sender << ", signal =" << sender->metaObject()->method(signalIndex).signature() << ')'; #endif - internalEventQueue.append(new QStateMachine::SignalEvent(sender, signalIndex, vargs)); + postInternalEvent(new QStateMachine::SignalEvent(sender, signalIndex, vargs)); processEvents(DirectProcessing); } @@ -1825,6 +1897,8 @@ void QStateMachine::stop() } /*! + \threadsafe + Posts the given \a event of the given \a priority for processing by this state machine. @@ -1852,16 +1926,18 @@ void QStateMachine::postEvent(QEvent *event, EventPriority priority) #endif switch (priority) { case NormalPriority: - d->externalEventQueue.append(event); + d->postExternalEvent(event); break; case HighPriority: - d->internalEventQueue.append(event); + d->postInternalEvent(event); break; } d->processEvents(QStateMachinePrivate::QueuedProcessing); } /*! + \threadsafe + Posts the given \a event for processing by this state machine, with the given \a delay in milliseconds. Returns an identifier associated with the delayed event, or -1 if the event could not be posted. @@ -1893,12 +1969,15 @@ int QStateMachine::postDelayedEvent(QEvent *event, int delay) #ifdef QSTATEMACHINE_DEBUG qDebug() << this << ": posting event" << event << "with delay" << delay; #endif + QMutexLocker locker(&d->delayedEventsMutex); int tid = startTimer(delay); d->delayedEvents[tid] = event; return tid; } /*! + \threadsafe + Cancels the delayed event identified by the given \a id. The id should be a value returned by a call to postDelayedEvent(). Returns true if the event was successfully cancelled, otherwise returns false. @@ -1912,6 +1991,7 @@ bool QStateMachine::cancelDelayedEvent(int id) qWarning("QStateMachine::cancelDelayedEvent: the machine is not running"); return false; } + QMutexLocker locker(&d->delayedEventsMutex); QEvent *e = d->delayedEvents.take(id); if (!e) return false; @@ -1921,8 +2001,6 @@ bool QStateMachine::cancelDelayedEvent(int id) } /*! - \internal - Returns the maximal consistent set of states (including parallel and final states) that this state machine is currently in. If a state \c s is in the configuration, it is always the case that the parent of \c s is also in @@ -1963,18 +2041,23 @@ bool QStateMachine::event(QEvent *e) int tid = te->timerId(); if (d->state != QStateMachinePrivate::Running) { // This event has been cancelled already + QMutexLocker locker(&d->delayedEventsMutex); Q_ASSERT(!d->delayedEvents.contains(tid)); return true; } + d->delayedEventsMutex.lock(); QEvent *ee = d->delayedEvents.take(tid); if (ee != 0) { killTimer(tid); - d->externalEventQueue.append(ee); + d->delayedEventsMutex.unlock(); + d->postExternalEvent(ee); d->processEvents(QStateMachinePrivate::DirectProcessing); return true; + } else { + d->delayedEventsMutex.unlock(); } } - return QObject::event(e); + return QState::event(e); } #ifndef QT_NO_STATEMACHINE_EVENTFILTER diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index cf7a073..01c9361 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -58,6 +58,7 @@ #include <QtCore/qcoreevent.h> #include <QtCore/qhash.h> #include <QtCore/qlist.h> +#include <QtCore/qmutex.h> #include <QtCore/qpair.h> #include <QtCore/qset.h> #include <QtCore/qvector.h> @@ -72,6 +73,8 @@ class QSignalEventGenerator; class QSignalTransition; class QAbstractState; class QAbstractTransition; +class QFinalState; +class QHistoryState; class QState; #ifndef QT_NO_ANIMATION @@ -137,6 +140,11 @@ public: const QList<QAbstractState*> &exitedStates, const QList<QAbstractState*> &enteredStates); + static QState *toStandardState(QAbstractState *state); + static const QState *toStandardState(const QAbstractState *state); + static QFinalState *toFinalState(QAbstractState *state); + static QHistoryState *toHistoryState(QAbstractState *state); + bool isInFinalState(QAbstractState *s) const; static bool isFinal(const QAbstractState *s); static bool isParallel(const QAbstractState *s); @@ -159,6 +167,13 @@ public: void unregisterAllTransitions(); void handleTransitionSignal(QObject *sender, int signalIndex, void **args); + + void postInternalEvent(QEvent *e); + void postExternalEvent(QEvent *e); + QEvent *dequeueInternalEvent(); + QEvent *dequeueExternalEvent(); + bool isInternalEventQueueEmpty(); + bool isExternalEventQueueEmpty(); void processEvents(EventProcessingMode processingMode); void cancelAllDelayedEvents(); @@ -181,6 +196,8 @@ public: QSet<QAbstractState*> configuration; QList<QEvent*> internalEventQueue; QList<QEvent*> externalEventQueue; + QMutex internalEventMutex; + QMutex externalEventMutex; QStateMachine::Error error; QStateMachine::RestorePolicy globalRestorePolicy; @@ -214,6 +231,7 @@ public: QHash<QObject*, QHash<QEvent::Type, int> > qobjectEvents; #endif QHash<int, QEvent*> delayedEvents; + QMutex delayedEventsMutex; typedef QEvent* (*f_cloneEvent)(QEvent*); struct Handler { diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 54465bb..db6435e 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -1855,7 +1855,7 @@ QTime QTime::currentTime() t = localtime(<ime); #endif Q_CHECK_PTR(t); - + ct.mds = MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec + tv.tv_usec / 1000; #else @@ -3725,11 +3725,11 @@ static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time) TTimeIntervalSeconds tTimeIntervalSecsSince1Jan1970UTC(secsSince1Jan1970UTC); TTime epochTTime; TInt err = epochTTime.Set(KUnixEpoch); + tm res; if(err == KErrNone) { TTime utcTTime = epochTTime + tTimeIntervalSecsSince1Jan1970UTC; utcTTime = utcTTime + utcOffset; TDateTime utcDateTime = utcTTime.DateTime(); - tm res; res.tm_sec = utcDateTime.Second(); res.tm_min = utcDateTime.Minute(); res.tm_hour = utcDateTime.Hour(); @@ -3816,11 +3816,11 @@ static void localToUtc(QDate &date, QTime &time, int isdst) TTimeIntervalSeconds tTimeIntervalSecsSince1Jan1970UTC(secsSince1Jan1970UTC); TTime epochTTime; TInt err = epochTTime.Set(KUnixEpoch); + tm res; if(err == KErrNone) { TTime utcTTime = epochTTime + tTimeIntervalSecsSince1Jan1970UTC; utcTTime = utcTTime + utcOffset; TDateTime utcDateTime = utcTTime.DateTime(); - tm res; res.tm_sec = utcDateTime.Second(); res.tm_min = utcDateTime.Minute(); res.tm_hour = utcDateTime.Hour(); diff --git a/src/gui/dialogs/qprintdialog_win.cpp b/src/gui/dialogs/qprintdialog_win.cpp index 843c4e2..51e83ac 100644 --- a/src/gui/dialogs/qprintdialog_win.cpp +++ b/src/gui/dialogs/qprintdialog_win.cpp @@ -139,7 +139,7 @@ static void qt_win_setup_PRINTDLGEX(PRINTDLGEX *pd, QWidget *parent, if (d->ep->printToFile) pd->Flags |= PD_PRINTTOFILE; Q_ASSERT(parent != 0 && parent->testAttribute(Qt::WA_WState_Created)); - pd->hwndOwner = parent->winId(); + pd->hwndOwner = parent->window()->winId(); pd->lpPageRanges[0].nFromPage = qMax(pdlg->fromPage(), pdlg->minPage()); pd->lpPageRanges[0].nToPage = (pdlg->toPage() > 0) ? qMin(pdlg->toPage(), pdlg->maxPage()) : 1; pd->nCopies = d->ep->num_copies; diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp index 969b6b5..3815b60 100644 --- a/src/gui/effects/qgraphicseffect.cpp +++ b/src/gui/effects/qgraphicseffect.cpp @@ -65,9 +65,6 @@ \o QGraphicsDropShadowEffect - renders a dropshadow behind the item \o QGraphicsColorizeEffect - renders the item in shades of any given color \o QGraphicsOpacityEffect - renders the item with an opacity - \o QGraphicsPixelizeEffect - pixelizes the item with any pixel size - \o QGraphicsGrayscaleEffect - renders the item in shades of gray - \o QGraphicsBloomEffect - applies a blooming / glowing effect \endlist \img graphicseffect-effects.png @@ -100,9 +97,11 @@ */ #include "qgraphicseffect_p.h" +#include <QtGui/qgraphicsitem.h> #include <QtGui/qimage.h> #include <QtGui/qpainter.h> +#include <QtGui/qpaintengine.h> #include <QtCore/qrect.h> #include <QtCore/qdebug.h> #include <private/qdrawhelper_p.h> @@ -251,17 +250,24 @@ bool QGraphicsEffectSource::isPixmap() const \sa QGraphicsEffect::draw(), boundingRect(), deviceRect() */ -QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offset) const +QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offset, PixmapPadMode mode) const { Q_D(const QGraphicsEffectSource); + // Shortcut, no cache for childless pixmap items... + const QGraphicsItem *item = graphicsItem(); + if (system == Qt::LogicalCoordinates && mode == NoExpandPadMode && item && isPixmap()) { + return ((QGraphicsPixmapItem *) item)->pixmap(); + } + QPixmap pm; - if (d->m_cachedSystem == system) + if (d->m_cachedSystem == system && d->m_cachedMode == mode) QPixmapCache::find(d->m_cacheKey, &pm); if (pm.isNull()) { - pm = d->pixmap(system, &d->m_cachedOffset); + pm = d->pixmap(system, &d->m_cachedOffset, mode); d->m_cachedSystem = system; + d->m_cachedMode = mode; d->invalidateCache(); d->m_cacheKey = QPixmapCache::insert(pm); @@ -353,8 +359,10 @@ void QGraphicsEffect::setEnabled(bool enable) return; d->isEnabled = enable; - if (d->source) + if (d->source) { d->source->d_func()->effectBoundingRectChanged(); + d->source->d_func()->invalidateCache(); + } emit enabledChanged(enable); } @@ -408,8 +416,10 @@ QGraphicsEffectSource *QGraphicsEffect::source() const void QGraphicsEffect::updateBoundingRect() { Q_D(QGraphicsEffect); - if (d->source) + if (d->source) { d->source->d_func()->effectBoundingRectChanged(); + d->source->d_func()->invalidateCache(); + } } /*! @@ -458,96 +468,6 @@ void QGraphicsEffect::sourceChanged(ChangeFlags flags) } /*! - \class QGraphicsGrayscaleEffect - \brief The QGraphicsGrayscaleEffect class provides a grayscale effect. - \since 4.6 - - A grayscale effect renders the source in shades of gray. - - \img graphicseffect-grayscale.png - - \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsPixelizeEffect, - QGraphicsColorizeEffect, QGraphicsOpacityEffect -*/ - -/*! - Constructs a new QGraphicsGrayscale instance. - The \a parent parameter is passed to QGraphicsEffect's constructor. -*/ -QGraphicsGrayscaleEffect::QGraphicsGrayscaleEffect(QObject *parent) - : QGraphicsEffect(*new QGraphicsGrayscaleEffectPrivate, parent) -{ -} - -/*! - Destroys the effect. -*/ -QGraphicsGrayscaleEffect::~QGraphicsGrayscaleEffect() -{ -} - - -/*! - \property QGraphicsGrayscaleEffect::strength - \brief the strength of the effect. - - By default, the strength is 1.0. - A strength 0.0 equals to no effect, while 1.0 means full grayscale. -*/ -qreal QGraphicsGrayscaleEffect::strength() const -{ - Q_D(const QGraphicsGrayscaleEffect); - return d->filter->strength(); -} - -void QGraphicsGrayscaleEffect::setStrength(qreal strength) -{ - Q_D(QGraphicsGrayscaleEffect); - if (qFuzzyCompare(d->filter->strength(), strength)) - return; - - d->filter->setStrength(strength); - d->opaque = !qFuzzyIsNull(strength); - update(); - emit strengthChanged(strength); -} - -/*! \fn void QGraphicsGrayscaleEffect::strengthChanged(qreal strength) - This signal is emitted whenever setStrength() changes the grayscale - strength property. \a strength contains the new strength value of - the grayscale effect. - */ - -/*! - \reimp -*/ -void QGraphicsGrayscaleEffect::draw(QPainter *painter, QGraphicsEffectSource *source) -{ - Q_D(QGraphicsGrayscaleEffect); - - if (!d->opaque) { - source->draw(painter); - return; - } - - QPoint offset; - if (source->isPixmap()) { - // No point in drawing in device coordinates (pixmap will be scaled anyways). - const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset); - d->filter->draw(painter, offset, pixmap); - return; - } - - // Draw pixmap in device coordinates to avoid pixmap scaling; - const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset); - QTransform restoreTransform = painter->worldTransform(); - painter->setWorldTransform(QTransform()); - d->filter->draw(painter, offset, pixmap); - painter->setWorldTransform(restoreTransform); - -} - -/*! \class QGraphicsColorizeEffect \brief The QGraphicsColorizeEffect class provides a colorize effect. \since 4.6 @@ -559,8 +479,7 @@ void QGraphicsGrayscaleEffect::draw(QPainter *painter, QGraphicsEffectSource *so \img graphicseffect-colorize.png - \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsPixelizeEffect, - QGraphicsGrayscaleEffect, QGraphicsOpacityEffect + \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsOpacityEffect */ /*! @@ -655,7 +574,8 @@ void QGraphicsColorizeEffect::draw(QPainter *painter, QGraphicsEffectSource *sou QPoint offset; if (source->isPixmap()) { // No point in drawing in device coordinates (pixmap will be scaled anyways). - const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset); + const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset, + QGraphicsEffectSource::NoExpandPadMode); d->filter->draw(painter, offset, pixmap); return; } @@ -669,126 +589,6 @@ void QGraphicsColorizeEffect::draw(QPainter *painter, QGraphicsEffectSource *sou } /*! - \class QGraphicsPixelizeEffect - \brief The QGraphicsPixelizeEffect class provides a pixelize effect. - \since 4.6 - - A pixelize effect renders the source in lower resolution. This effect is - useful for reducing details, like censorship. The resolution can be - modified using the setPixelSize() function. - - By default, the pixel size is 3. - - \img graphicseffect-pixelize.png - - \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsGrayscaleEffect, - QGraphicsColorizeEffect, QGraphicsOpacityEffect -*/ - -/*! - Constructs a new QGraphicsPixelizeEffect instance. - The \a parent parameter is passed to QGraphicsEffect's constructor. -*/ -QGraphicsPixelizeEffect::QGraphicsPixelizeEffect(QObject *parent) - : QGraphicsEffect(*new QGraphicsPixelizeEffectPrivate, parent) -{ -} - -/*! - Destroys the effect. -*/ -QGraphicsPixelizeEffect::~QGraphicsPixelizeEffect() -{ -} - -/*! - \property QGraphicsPixelizeEffect::pixelSize - \brief the size of a pixel in the effect. - - Setting the pixel size to 2 means two pixels in the source will be used to - represent one pixel. Using a bigger size results in lower resolution. - - By default, the pixel size is 3. -*/ -int QGraphicsPixelizeEffect::pixelSize() const -{ - Q_D(const QGraphicsPixelizeEffect); - return d->pixelSize; -} - -void QGraphicsPixelizeEffect::setPixelSize(int size) -{ - Q_D(QGraphicsPixelizeEffect); - if (d->pixelSize == size) - return; - - d->pixelSize = size; - update(); - emit pixelSizeChanged(size); -} - -/*! - \fn void QGraphicsPixelizeEffect::pixelSizeChanged(int size) - - This signal is emitted whenever the effect's pixel size changes. - The \a size parameter holds the effect's new pixel size. -*/ - -static inline void pixelize(QImage *image, int pixelSize) -{ - Q_ASSERT(pixelSize > 0); - Q_ASSERT(image); - int width = image->width(); - int height = image->height(); - for (int y = 0; y < height; y += pixelSize) { - int ys = qMin(height - 1, y + pixelSize / 2); - QRgb *sbuf = reinterpret_cast<QRgb*>(image->scanLine(ys)); - for (int x = 0; x < width; x += pixelSize) { - int xs = qMin(width - 1, x + pixelSize / 2); - QRgb color = sbuf[xs]; - for (int yi = 0; yi < qMin(pixelSize, height - y); ++yi) { - QRgb *buf = reinterpret_cast<QRgb*>(image->scanLine(y + yi)); - for (int xi = 0; xi < qMin(pixelSize, width - x); ++xi) - buf[x + xi] = color; - } - } - } -} - -/*! - \reimp -*/ -void QGraphicsPixelizeEffect::draw(QPainter *painter, QGraphicsEffectSource *source) -{ - Q_D(QGraphicsPixelizeEffect); - if (d->pixelSize <= 0) { - source->draw(painter); - return; - } - - QPoint offset; - if (source->isPixmap()) { - const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset); - QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32); - pixelize(&image, d->pixelSize); - painter->drawImage(offset, image); - return; - } - - // Draw pixmap in device coordinates to avoid pixmap scaling. - const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset); - - // pixelize routine - QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32); - pixelize(&image, d->pixelSize); - - QTransform restoreTransform = painter->worldTransform(); - painter->setWorldTransform(QTransform()); - painter->drawImage(offset, image); - painter->setWorldTransform(restoreTransform); -} - -/*! \class QGraphicsBlurEffect \brief The QGraphicsBlurEffect class provides a blur effect. \since 4.6 @@ -802,8 +602,7 @@ void QGraphicsPixelizeEffect::draw(QPainter *painter, QGraphicsEffectSource *sou \img graphicseffect-blur.png - \sa QGraphicsDropShadowEffect, QGraphicsPixelizeEffect, QGraphicsGrayscaleEffect, - QGraphicsColorizeEffect, QGraphicsOpacityEffect + \sa QGraphicsDropShadowEffect, QGraphicsColorizeEffect, QGraphicsOpacityEffect */ /*! @@ -833,16 +632,16 @@ QGraphicsBlurEffect::~QGraphicsBlurEffect() By default, the blur radius is 5 pixels. */ -int QGraphicsBlurEffect::blurRadius() const +qreal QGraphicsBlurEffect::blurRadius() const { Q_D(const QGraphicsBlurEffect); return d->filter->radius(); } -void QGraphicsBlurEffect::setBlurRadius(int radius) +void QGraphicsBlurEffect::setBlurRadius(qreal radius) { Q_D(QGraphicsBlurEffect); - if (d->filter->radius() == radius) + if (qFuzzyCompare(d->filter->radius(), radius)) return; d->filter->setRadius(radius); @@ -851,7 +650,7 @@ void QGraphicsBlurEffect::setBlurRadius(int radius) } /*! - \fn void QGraphicsBlurEffect::blurRadiusChanged(int radius) + \fn void QGraphicsBlurEffect::blurRadiusChanged(qreal radius) This signal is emitted whenever the effect's blur radius changes. The \a radius parameter holds the effect's new blur radius. @@ -911,9 +710,13 @@ void QGraphicsBlurEffect::draw(QPainter *painter, QGraphicsEffectSource *source) return; } + QGraphicsEffectSource::PixmapPadMode mode = QGraphicsEffectSource::ExpandToEffectRectPadMode; + if (painter->paintEngine()->type() == QPaintEngine::OpenGL2) + mode = QGraphicsEffectSource::ExpandToTransparentBorderPadMode; + // Draw pixmap in device coordinates to avoid pixmap scaling. QPoint offset; - const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset); + const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset, mode); QTransform restoreTransform = painter->worldTransform(); painter->setWorldTransform(QTransform()); d->filter->draw(painter, offset, pixmap); @@ -937,8 +740,7 @@ void QGraphicsBlurEffect::draw(QPainter *painter, QGraphicsEffectSource *source) \img graphicseffect-drop-shadow.png - \sa QGraphicsBlurEffect, QGraphicsPixelizeEffect, QGraphicsGrayscaleEffect, - QGraphicsColorizeEffect, QGraphicsOpacityEffect + \sa QGraphicsBlurEffect, QGraphicsColorizeEffect, QGraphicsOpacityEffect */ /*! @@ -988,6 +790,8 @@ void QGraphicsDropShadowEffect::setOffset(const QPointF &offset) By default, the horizontal shadow offset is 8 pixels. + + \sa yOffset(), offset() */ @@ -1018,16 +822,16 @@ void QGraphicsDropShadowEffect::setOffset(const QPointF &offset) \sa color(), offset(). */ -int QGraphicsDropShadowEffect::blurRadius() const +qreal QGraphicsDropShadowEffect::blurRadius() const { Q_D(const QGraphicsDropShadowEffect); return d->filter->blurRadius(); } -void QGraphicsDropShadowEffect::setBlurRadius(int blurRadius) +void QGraphicsDropShadowEffect::setBlurRadius(qreal blurRadius) { Q_D(QGraphicsDropShadowEffect); - if (d->filter->blurRadius() == blurRadius) + if (qFuzzyCompare(d->filter->blurRadius(), blurRadius)) return; d->filter->setBlurRadius(blurRadius); @@ -1036,7 +840,7 @@ void QGraphicsDropShadowEffect::setBlurRadius(int blurRadius) } /*! - \fn void QGraphicsDropShadowEffect::blurRadiusChanged(int blurRadius) + \fn void QGraphicsDropShadowEffect::blurRadiusChanged(qreal blurRadius) This signal is emitted whenever the effect's blur radius changes. The \a blurRadius parameter holds the effect's new blur radius. @@ -1095,9 +899,13 @@ void QGraphicsDropShadowEffect::draw(QPainter *painter, QGraphicsEffectSource *s return; } + QGraphicsEffectSource::PixmapPadMode mode = QGraphicsEffectSource::ExpandToEffectRectPadMode; + if (painter->paintEngine()->type() == QPaintEngine::OpenGL2) + mode = QGraphicsEffectSource::ExpandToTransparentBorderPadMode; + // Draw pixmap in device coordinates to avoid pixmap scaling. QPoint offset; - const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset); + const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset, mode); QTransform restoreTransform = painter->worldTransform(); painter->setWorldTransform(QTransform()); d->filter->draw(painter, offset, pixmap); @@ -1117,8 +925,7 @@ void QGraphicsDropShadowEffect::draw(QPainter *painter, QGraphicsEffectSource *s \img graphicseffect-opacity.png - \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsPixelizeEffect, - QGraphicsGrayscaleEffect, QGraphicsColorizeEffect + \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsColorizeEffect */ /*! @@ -1238,10 +1045,11 @@ void QGraphicsOpacityEffect::draw(QPainter *painter, QGraphicsEffectSource *sour QPoint offset; Qt::CoordinateSystem system = source->isPixmap() ? Qt::LogicalCoordinates : Qt::DeviceCoordinates; - QPixmap pixmap = source->pixmap(system, &offset); + QPixmap pixmap = source->pixmap(system, &offset, QGraphicsEffectSource::NoExpandPadMode); if (pixmap.isNull()) return; + painter->save(); painter->setOpacity(d->opacity); @@ -1267,234 +1075,6 @@ void QGraphicsOpacityEffect::draw(QPainter *painter, QGraphicsEffectSource *sour painter->restore(); } -/*! - \class QGraphicsBloomEffect - \brief The QGraphicsBloomEffect class provides a bloom/glow effect. - \since 4.6 - - A bloom/glow effect adds fringes of light around bright areas in the source. - - \img graphicseffect-bloom.png - - \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsPixelizeEffect, - QGraphicsGrayscaleEffect, QGraphicsColorizeEffect -*/ - -/*! - Constructs a new QGraphicsBloomEffect instance. - The \a parent parameter is passed to QGraphicsEffect's constructor. -*/ -QGraphicsBloomEffect::QGraphicsBloomEffect(QObject *parent) - : QGraphicsEffect(*new QGraphicsBloomEffectPrivate, parent) -{ - Q_D(QGraphicsBloomEffect); - for (int i = 0; i < 256; ++i) - d->colorTable[i] = qMin(i + d->brightness, 255); -} - -/*! - Destroys the effect. -*/ -QGraphicsBloomEffect::~QGraphicsBloomEffect() -{ -} - -/*! - \reimp -*/ -QRectF QGraphicsBloomEffect::boundingRectFor(const QRectF &rect) const -{ - Q_D(const QGraphicsBloomEffect); - const qreal delta = d->blurFilter.radius() * 2; - return rect.adjusted(-delta, -delta, delta, delta); -} - -/*! - \property QGraphicsBloomEffect::blurRadius - \brief the blur radius in pixels of the effect. - - Using a smaller radius results in a sharper appearance, whereas a bigger - radius results in a more blurred appearance. - - By default, the blur radius is 5 pixels. - - \sa strength(), brightness() -*/ -int QGraphicsBloomEffect::blurRadius() const -{ - Q_D(const QGraphicsBloomEffect); - return d->blurFilter.radius(); -} - -void QGraphicsBloomEffect::setBlurRadius(int radius) -{ - Q_D(QGraphicsBloomEffect); - if (d->blurFilter.radius() == radius) - return; - - d->blurFilter.setRadius(radius); - updateBoundingRect(); - emit blurRadiusChanged(radius); -} - -/*! - \fn void QGraphicsBloomEffect::blurRadiusChanged(int blurRadius) - - This signal is emitted whenever the effect's blur radius changes. - The \a blurRadius parameter holds the effect's new blur radius. -*/ - -/*! - \property QGraphicsBloomEffect::blurHint - \brief the blur hint of the effect. - - Use the Qt::PerformanceHint hint to say that you want a faster blur, - and the Qt::QualityHint hint to say that you prefer a higher quality blur. - - When animating the blur radius it's recommended to use Qt::PerformanceHint. - - By default, the blur hint is Qt::PerformanceHint. -*/ -Qt::RenderHint QGraphicsBloomEffect::blurHint() const -{ - Q_D(const QGraphicsBloomEffect); - return d->blurFilter.blurHint(); -} - -void QGraphicsBloomEffect::setBlurHint(Qt::RenderHint hint) -{ - Q_D(QGraphicsBloomEffect); - if (d->blurFilter.blurHint() == hint) - return; - - d->blurFilter.setBlurHint(hint); - emit blurHintChanged(hint); -} - -/*! - \fn void QGraphicsBloomEffect::blurHintChanged(Qt::RenderHint hint) - - This signal is emitted whenever the effect's blur hint changes. - The \a hint parameter holds the effect's new blur hint. -*/ - -/*! - \property QGraphicsBloomEffect::brightness - \brief the brightness of the glow. - - The value should be in the range of 0 to 255, where 0 is dark - and 255 is bright. - - By default, the brightness is 70. - - \sa strength(), blurRadius() -*/ -int QGraphicsBloomEffect::brightness() const -{ - Q_D(const QGraphicsBloomEffect); - return d->brightness; -} - -void QGraphicsBloomEffect::setBrightness(int brightness) -{ - Q_D(QGraphicsBloomEffect); - brightness = qBound(0, brightness, 255); - if (d->brightness == brightness) - return; - - d->brightness = brightness; - for (int i = 0; i < 256; ++i) - d->colorTable[i] = qMin(i + brightness, 255); - - update(); - emit brightnessChanged(brightness); -} - -/*! - \fn void QGraphicsBloomEffect::brightnessChanged(int brightness) - - This signal is emitted whenever the effect's brightness changes. - The \a brightness parameter holds the effect's new brightness. -*/ - -/*! - \property QGraphicsBloomEffect::strength - \brief the strength of the effect. - - A strength 0.0 equals to no effect, while 1.0 means maximum glow. - - By default, the strength is 0.7. -*/ -qreal QGraphicsBloomEffect::strength() const -{ - Q_D(const QGraphicsBloomEffect); - return d->strength; -} - -void QGraphicsBloomEffect::setStrength(qreal strength) -{ - Q_D(QGraphicsBloomEffect); - strength = qBound(qreal(0.0), strength, qreal(1.0)); - if (qFuzzyCompare(d->strength, strength)) - return; - - d->strength = strength; - update(); - emit strengthChanged(strength); -} - -/*! - \fn void QGraphicsBloomEffect::strengthChanged(qreal strength) - - This signal is emitted whenever the effect's strength changes. - The \a strength parameter holds the effect's new strength. -*/ - -extern QPixmap qt_toRasterPixmap(const QPixmap &pixmap); - -/*! - \reimp -*/ -void QGraphicsBloomEffect::draw(QPainter *painter, QGraphicsEffectSource *source) -{ - Q_D(QGraphicsBloomEffect); - if (d->strength < 0.001) { - source->draw(painter); - return; - } - - QPoint offset; - QPixmap pixmap = qt_toRasterPixmap(source->pixmap(Qt::DeviceCoordinates, &offset)); - - // Blur. - QImage overlay(pixmap.size(), QImage::Format_ARGB32_Premultiplied); - overlay.fill(0); - - QPainter blurPainter(&overlay); - d->blurFilter.draw(&blurPainter, QPointF(), pixmap); - blurPainter.end(); - - // Brighten. - const int numBits = overlay.width() * overlay.height(); - QRgb *bits = reinterpret_cast<QRgb *>(overlay.bits()); - for (int i = 0; i < numBits; ++i) { - const QRgb pixel = INV_PREMUL(bits[i]); - bits[i] = PREMUL(qRgba(d->colorTable[qRed(pixel)], d->colorTable[qGreen(pixel)], - d->colorTable[qBlue(pixel)], qAlpha(pixel))); - } - - // Composite. - QPainter compPainter(&pixmap); - compPainter.setCompositionMode(QPainter::CompositionMode_Overlay); - compPainter.setOpacity(d->strength); - compPainter.drawImage(0, 0, overlay); - compPainter.end(); - - QTransform restoreTransform = painter->worldTransform(); - painter->setWorldTransform(QTransform()); - painter->drawPixmap(offset, pixmap); - painter->setWorldTransform(restoreTransform); -} QT_END_NAMESPACE diff --git a/src/gui/effects/qgraphicseffect.h b/src/gui/effects/qgraphicseffect.h index c89851e..bf18581 100644 --- a/src/gui/effects/qgraphicseffect.h +++ b/src/gui/effects/qgraphicseffect.h @@ -64,6 +64,12 @@ class Q_GUI_EXPORT QGraphicsEffectSource : public QObject { Q_OBJECT public: + enum PixmapPadMode { + NoExpandPadMode, + ExpandToTransparentBorderPadMode, + ExpandToEffectRectPadMode + }; + ~QGraphicsEffectSource(); const QGraphicsItem *graphicsItem() const; const QWidget *widget() const; @@ -75,7 +81,9 @@ public: QRectF boundingRect(Qt::CoordinateSystem coordinateSystem = Qt::LogicalCoordinates) const; QRect deviceRect() const; - QPixmap pixmap(Qt::CoordinateSystem system = Qt::LogicalCoordinates, QPoint *offset = 0) const; + QPixmap pixmap(Qt::CoordinateSystem system = Qt::LogicalCoordinates, + QPoint *offset = 0, + PixmapPadMode mode = ExpandToEffectRectPadMode) const; protected: QGraphicsEffectSource(QGraphicsEffectSourcePrivate &dd, QObject *parent = 0); @@ -141,31 +149,6 @@ private: }; Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsEffect::ChangeFlags) -class QGraphicsGrayscaleEffectPrivate; -class Q_GUI_EXPORT QGraphicsGrayscaleEffect: public QGraphicsEffect -{ - Q_OBJECT - Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged) -public: - QGraphicsGrayscaleEffect(QObject *parent = 0); - ~QGraphicsGrayscaleEffect(); - - qreal strength() const; - -protected: - void draw(QPainter *painter, QGraphicsEffectSource *source); - -public Q_SLOTS: - void setStrength(qreal strength); - -Q_SIGNALS: - void strengthChanged(qreal strength); - -private: - Q_DECLARE_PRIVATE(QGraphicsGrayscaleEffect) - Q_DISABLE_COPY(QGraphicsGrayscaleEffect) -}; - class QGraphicsColorizeEffectPrivate; class Q_GUI_EXPORT QGraphicsColorizeEffect: public QGraphicsEffect { @@ -195,51 +178,26 @@ private: Q_DISABLE_COPY(QGraphicsColorizeEffect) }; -class QGraphicsPixelizeEffectPrivate; -class Q_GUI_EXPORT QGraphicsPixelizeEffect: public QGraphicsEffect -{ - Q_OBJECT - Q_PROPERTY(int pixelSize READ pixelSize WRITE setPixelSize NOTIFY pixelSizeChanged) -public: - QGraphicsPixelizeEffect(QObject *parent = 0); - ~QGraphicsPixelizeEffect(); - - int pixelSize() const; - -public Q_SLOTS: - void setPixelSize(int pixelSize); - -Q_SIGNALS: - void pixelSizeChanged(int pixelSize); - -protected: - void draw(QPainter *painter, QGraphicsEffectSource *source); - -private: - Q_DECLARE_PRIVATE(QGraphicsPixelizeEffect) - Q_DISABLE_COPY(QGraphicsPixelizeEffect) -}; - class QGraphicsBlurEffectPrivate; class Q_GUI_EXPORT QGraphicsBlurEffect: public QGraphicsEffect { Q_OBJECT - Q_PROPERTY(int blurRadius READ blurRadius WRITE setBlurRadius NOTIFY blurRadiusChanged) + Q_PROPERTY(qreal blurRadius READ blurRadius WRITE setBlurRadius NOTIFY blurRadiusChanged) Q_PROPERTY(Qt::RenderHint blurHint READ blurHint WRITE setBlurHint NOTIFY blurHintChanged) public: QGraphicsBlurEffect(QObject *parent = 0); ~QGraphicsBlurEffect(); QRectF boundingRectFor(const QRectF &rect) const; - int blurRadius() const; + qreal blurRadius() const; Qt::RenderHint blurHint() const; public Q_SLOTS: - void setBlurRadius(int blurRadius); + void setBlurRadius(qreal blurRadius); void setBlurHint(Qt::RenderHint hint); Q_SIGNALS: - void blurRadiusChanged(int blurRadius); + void blurRadiusChanged(qreal blurRadius); void blurHintChanged(Qt::RenderHint hint); protected: @@ -257,7 +215,7 @@ class Q_GUI_EXPORT QGraphicsDropShadowEffect: public QGraphicsEffect Q_PROPERTY(QPointF offset READ offset WRITE setOffset NOTIFY offsetChanged) Q_PROPERTY(qreal xOffset READ xOffset WRITE setXOffset NOTIFY offsetChanged) Q_PROPERTY(qreal yOffset READ yOffset WRITE setYOffset NOTIFY offsetChanged) - Q_PROPERTY(int blurRadius READ blurRadius WRITE setBlurRadius NOTIFY blurRadiusChanged) + Q_PROPERTY(qreal blurRadius READ blurRadius WRITE setBlurRadius NOTIFY blurRadiusChanged) Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) public: QGraphicsDropShadowEffect(QObject *parent = 0); @@ -272,7 +230,7 @@ public: inline qreal yOffset() const { return offset().y(); } - int blurRadius() const; + qreal blurRadius() const; QColor color() const; public Q_SLOTS: @@ -290,12 +248,12 @@ public Q_SLOTS: inline void setYOffset(qreal dy) { setOffset(QPointF(xOffset(), dy)); } - void setBlurRadius(int blurRadius); + void setBlurRadius(qreal blurRadius); void setColor(const QColor &color); Q_SIGNALS: void offsetChanged(const QPointF &offset); - void blurRadiusChanged(int blurRadius); + void blurRadiusChanged(qreal blurRadius); void colorChanged(const QColor &color); protected: @@ -335,44 +293,6 @@ private: Q_DISABLE_COPY(QGraphicsOpacityEffect) }; -class QGraphicsBloomEffectPrivate; -class Q_GUI_EXPORT QGraphicsBloomEffect: public QGraphicsEffect -{ - Q_OBJECT - Q_PROPERTY(int blurRadius READ blurRadius WRITE setBlurRadius NOTIFY blurRadiusChanged) - Q_PROPERTY(Qt::RenderHint blurHint READ blurHint WRITE setBlurHint NOTIFY blurHintChanged) - Q_PROPERTY(int brightness READ brightness WRITE setBrightness NOTIFY brightnessChanged) - Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged) -public: - QGraphicsBloomEffect(QObject *parent = 0); - ~QGraphicsBloomEffect(); - - QRectF boundingRectFor(const QRectF &rect) const; - int blurRadius() const; - Qt::RenderHint blurHint() const; - int brightness() const; - qreal strength() const; - -public Q_SLOTS: - void setBlurRadius(int blurRadius); - void setBlurHint(Qt::RenderHint hint); - void setBrightness(int brightness); - void setStrength(qreal strength); - -Q_SIGNALS: - void blurRadiusChanged(int blurRadius); - void blurHintChanged(Qt::RenderHint hint); - void brightnessChanged(int brightness); - void strengthChanged(qreal strength); - -protected: - void draw(QPainter *painter, QGraphicsEffectSource *source); - -private: - Q_DECLARE_PRIVATE(QGraphicsBloomEffect) - Q_DISABLE_COPY(QGraphicsBloomEffect) -}; - QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/effects/qgraphicseffect_p.h b/src/gui/effects/qgraphicseffect_p.h index fc925f2..1ed7103 100644 --- a/src/gui/effects/qgraphicseffect_p.h +++ b/src/gui/effects/qgraphicseffect_p.h @@ -66,7 +66,12 @@ class QGraphicsEffectSourcePrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QGraphicsEffectSource) public: - QGraphicsEffectSourcePrivate() : QObjectPrivate() {} + QGraphicsEffectSourcePrivate() + : QObjectPrivate() + , m_cachedSystem(Qt::DeviceCoordinates) + , m_cachedMode(QGraphicsEffectSource::ExpandToTransparentBorderPadMode) + {} + virtual ~QGraphicsEffectSourcePrivate() { invalidateCache(); } virtual void detach() = 0; virtual QRectF boundingRect(Qt::CoordinateSystem system) const = 0; @@ -77,7 +82,8 @@ public: virtual void draw(QPainter *p) = 0; virtual void update() = 0; virtual bool isPixmap() const = 0; - virtual QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset = 0) const = 0; + virtual QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset = 0, + QGraphicsEffectSource::PixmapPadMode mode = QGraphicsEffectSource::ExpandToTransparentBorderPadMode) const = 0; virtual void effectBoundingRectChanged() = 0; void invalidateCache() const { QPixmapCache::remove(m_cacheKey); } @@ -87,6 +93,7 @@ public: private: mutable Qt::CoordinateSystem m_cachedSystem; + mutable QGraphicsEffectSource::PixmapPadMode m_cachedMode; mutable QPoint m_cachedOffset; mutable QPixmapCache::Key m_cacheKey; }; @@ -118,22 +125,6 @@ public: quint32 padding : 31; // feel free to use }; -class QGraphicsGrayscaleEffectPrivate : public QGraphicsEffectPrivate -{ - Q_DECLARE_PUBLIC(QGraphicsGrayscaleEffect) -public: - QGraphicsGrayscaleEffectPrivate() - : opaque(true) - { - filter = new QPixmapColorizeFilter; - filter->setColor(Qt::black); - } - ~QGraphicsGrayscaleEffectPrivate() { delete filter; } - - QPixmapColorizeFilter *filter; - quint32 opaque : 1; - quint32 padding : 31; -}; class QGraphicsColorizeEffectPrivate : public QGraphicsEffectPrivate { @@ -151,15 +142,6 @@ public: quint32 padding : 31; }; -class QGraphicsPixelizeEffectPrivate : public QGraphicsEffectPrivate -{ - Q_DECLARE_PUBLIC(QGraphicsPixelizeEffect) -public: - QGraphicsPixelizeEffectPrivate() : pixelSize(3) {} - - int pixelSize; -}; - class QGraphicsBlurEffectPrivate : public QGraphicsEffectPrivate { Q_DECLARE_PUBLIC(QGraphicsBlurEffect) @@ -195,18 +177,6 @@ public: uint hasOpacityMask : 1; }; -class QGraphicsBloomEffectPrivate : public QGraphicsEffectPrivate -{ - Q_DECLARE_PUBLIC(QGraphicsBlurEffect) -public: - QGraphicsBloomEffectPrivate() : brightness(70), strength(qreal(0.7)) {} - - QPixmapBlurFilter blurFilter; - int colorTable[256]; - int brightness; - qreal strength; -}; - QT_END_NAMESPACE #endif // QGRAPHICSEFFECT_P_H diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index ce28891..4665916 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1678,7 +1678,7 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, quint32(flags)); // Flags that alter the geometry of the item (or its children). - const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations); + const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable); bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask); if (fullUpdate) d_ptr->paintedViewBoundingRectsNeedRepaint = 1; @@ -9180,10 +9180,14 @@ void QGraphicsPixmapItem::setOffset(const QPointF &offset) QRectF QGraphicsPixmapItem::boundingRect() const { Q_D(const QGraphicsPixmapItem); - qreal pw = 1.0; if (d->pixmap.isNull()) return QRectF(); - return QRectF(d->offset, d->pixmap.size()).adjusted(-pw/2, -pw/2, pw/2, pw/2); + if (d->flags & ItemIsSelectable) { + qreal pw = 1.0; + return QRectF(d->offset, d->pixmap.size()).adjusted(-pw/2, -pw/2, pw/2, pw/2); + } else { + return QRectF(d->offset, d->pixmap.size()); + } } /*! @@ -10702,7 +10706,8 @@ void QGraphicsItemEffectSourcePrivate::draw(QPainter *painter) } } -QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset) const +QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset, + QGraphicsEffectSource::PixmapPadMode mode) const { const bool deviceCoordinates = (system == Qt::DeviceCoordinates); if (!info && deviceCoordinates) { @@ -10716,7 +10721,17 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func(); const QRectF sourceRect = boundingRect(system); - QRect effectRect = item->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect(); + QRect effectRect; + + if (mode == QGraphicsEffectSource::ExpandToEffectRectPadMode) { + effectRect = item->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect(); + } else if (mode == QGraphicsEffectSource::ExpandToTransparentBorderPadMode) { + // adjust by 1.5 to account for cosmetic pens + effectRect = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5).toAlignedRect(); + } else { + effectRect = sourceRect.toAlignedRect(); + } + if (offset) *offset = effectRect.topLeft(); @@ -10744,10 +10759,15 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP effectRect.setBottom(deviceHeight -1); } - if (effectRect.isEmpty()) return QPixmap(); + if (system == Qt::LogicalCoordinates + && effectRect.size() == sourceRect.size() + && isPixmap()) { + return static_cast<QGraphicsPixmapItem *>(item)->pixmap(); + } + QPixmap pixmap(effectRect.size()); pixmap.fill(Qt::transparent); QPainter pixmapPainter(&pixmap); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 7c3c4f0..183e95b 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -61,6 +61,7 @@ #include <private/qgraphicstransform_p.h> #include <private/qgraphicseffect_p.h> +#include <qgraphicseffect.h> #include <QtCore/qpoint.h> @@ -603,7 +604,9 @@ public: inline bool isPixmap() const { - return (item->type() == QGraphicsPixmapItem::Type); + return item->type() == QGraphicsPixmapItem::Type + && !(item->flags() & QGraphicsItem::ItemIsSelectable) + && item->d_ptr->children.size() == 0; //|| (item->d_ptr->isObject && qobject_cast<QFxImage *>(q_func())); } @@ -621,7 +624,9 @@ public: QRectF boundingRect(Qt::CoordinateSystem system) const; void draw(QPainter *); - QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset) const; + QPixmap pixmap(Qt::CoordinateSystem system, + QPoint *offset, + QGraphicsEffectSource::PixmapPadMode mode) const; QGraphicsItem *item; QGraphicsItemPaintInfo *info; diff --git a/src/gui/image/qnativeimage.cpp b/src/gui/image/qnativeimage.cpp index 88faea8..e4ea2e9 100644 --- a/src/gui/image/qnativeimage.cpp +++ b/src/gui/image/qnativeimage.cpp @@ -199,10 +199,12 @@ QNativeImage::QNativeImage(int width, int height, QImage::Format format,bool /* shmctl(xshminfo.shmid, IPC_RMID, 0); return; } - xshmpm = XShmCreatePixmap(X11->display, DefaultRootWindow(X11->display), xshmimg->data, - &xshminfo, width, height, dd); - if (!xshmpm) { - qWarning() << "QNativeImage: Unable to create shared Pixmap."; + if (X11->use_mitshm_pixmaps) { + xshmpm = XShmCreatePixmap(X11->display, DefaultRootWindow(X11->display), xshmimg->data, + &xshminfo, width, height, dd); + if (!xshmpm) { + qWarning() << "QNativeImage: Unable to create shared Pixmap."; + } } } diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp index 666d608..7086341 100644 --- a/src/gui/image/qpixmap_s60.cpp +++ b/src/gui/image/qpixmap_s60.cpp @@ -684,9 +684,10 @@ void QS60PixmapData::beginDataAccess() uchar* newBytes = (uchar*)cfbsBitmap->DataAddress(); - if (newBytes == bytes) - return; + TSize size = cfbsBitmap->SizeInPixels(); + if (newBytes == bytes && image.width() == size.iWidth && image.height() == size.iHeight) + return; bytes = newBytes; TDisplayMode mode = cfbsBitmap->DisplayMode(); @@ -695,8 +696,6 @@ void QS60PixmapData::beginDataAccess() if (format == QImage::Format_ARGB32) format = QImage::Format_ARGB32_Premultiplied; // pixel data is actually in premultiplied format - TSize size = cfbsBitmap->SizeInPixels(); - QVector<QRgb> savedColorTable; if (!image.isNull()) savedColorTable = image.colorTable(); @@ -935,18 +934,21 @@ void QS60PixmapData::fromNativeType(void* pixmap, NativeType nativeType) da.beginDataAccess(sourceBitmap); uchar *bytes = (uchar*)sourceBitmap->DataAddress(); QImage img = QImage(bytes, size.iWidth, size.iHeight, format); + img = img.copy(); da.endDataAccess(sourceBitmap); - fromImage(img, Qt::AutoColor); - - if(deleteSourceBitmap) - delete sourceBitmap; - if(displayMode == EGray2) { //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid //So invert mono bitmaps so that masks work correctly. - image.invertPixels(); + img.invertPixels(); + } else if(displayMode == EColor16M) { + img = img.rgbSwapped(); // EColor16M is BGR } + + fromImage(img, Qt::AutoColor); + + if(deleteSourceBitmap) + delete sourceBitmap; } else { CFbsBitmap* duplicate = 0; QT_TRAP_THROWING(duplicate = new (ELeave) CFbsBitmap); diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp index 9fcf776..d0de03e 100644 --- a/src/gui/image/qpixmapfilter.cpp +++ b/src/gui/image/qpixmapfilter.cpp @@ -506,7 +506,7 @@ class QPixmapBlurFilterPrivate : public QPixmapFilterPrivate public: QPixmapBlurFilterPrivate() : radius(5), hint(Qt::PerformanceHint) {} - int radius; + qreal radius; Qt::RenderHint hint; }; @@ -535,7 +535,7 @@ QPixmapBlurFilter::~QPixmapBlurFilter() \internal */ -void QPixmapBlurFilter::setRadius(int radius) +void QPixmapBlurFilter::setRadius(qreal radius) { Q_D(QPixmapBlurFilter); d->radius = radius; @@ -546,7 +546,7 @@ void QPixmapBlurFilter::setRadius(int radius) \internal */ -int QPixmapBlurFilter::radius() const +qreal QPixmapBlurFilter::radius() const { Q_D(const QPixmapBlurFilter); return d->radius; @@ -584,7 +584,7 @@ Qt::RenderHint QPixmapBlurFilter::blurHint() const QRectF QPixmapBlurFilter::boundingRectFor(const QRectF &rect) const { Q_D(const QPixmapBlurFilter); - const qreal delta = d->radius * 2; + const qreal delta = d->radius + 1; return rect.adjusted(-delta, -delta, delta, delta); } @@ -668,7 +668,7 @@ void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap if (!painter->isActive()) return; - if (d->radius == 0) { + if (d->radius <= 0) { painter->drawPixmap(srcRect.translated(p), src, srcRect); return; } @@ -688,12 +688,12 @@ void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap if (srcRect.isNull()) { srcImage = src.toImage(); - destImage = blurred(srcImage, srcImage.rect(), d->radius); + destImage = blurred(srcImage, srcImage.rect(), qRound(d->radius)); } else { QRect rect = srcRect.toAlignedRect().intersected(src.rect()); srcImage = src.copy(rect).toImage(); - destImage = blurred(srcImage, srcImage.rect(), d->radius); + destImage = blurred(srcImage, srcImage.rect(), qRound(d->radius)); } painter->drawImage(p, destImage); @@ -902,7 +902,7 @@ public: QPointF offset; QColor color; - int radius; + qreal radius; }; /*! @@ -966,7 +966,7 @@ QPixmapDropShadowFilter::~QPixmapDropShadowFilter() \internal */ -int QPixmapDropShadowFilter::blurRadius() const +qreal QPixmapDropShadowFilter::blurRadius() const { Q_D(const QPixmapDropShadowFilter); return d->radius; @@ -981,7 +981,7 @@ int QPixmapDropShadowFilter::blurRadius() const \internal */ -void QPixmapDropShadowFilter::setBlurRadius(int radius) +void QPixmapDropShadowFilter::setBlurRadius(qreal radius) { Q_D(QPixmapDropShadowFilter); d->radius = radius; @@ -1057,14 +1057,9 @@ void QPixmapDropShadowFilter::setOffset(const QPointF &offset) QRectF QPixmapDropShadowFilter::boundingRectFor(const QRectF &rect) const { Q_D(const QPixmapDropShadowFilter); - - const qreal delta = qreal(d->radius * 2); - qreal x1 = qMin(rect.left(), rect.left() + d->offset.x() - delta); - qreal y1 = qMin(rect.top(), rect.top() + d->offset.y() - delta); - qreal x2 = qMax(rect.right(), rect.right() + d->offset.x() + delta); - qreal y2 = qMax(rect.bottom(), rect.bottom() + d->offset.y() + delta); - - return QRectF(x1, y1, x2 - x1, y2 - y1); + qreal delta = d->radius + 1; + return rect.adjusted(-2, -2, 2, 2).united( + rect.translated(d->offset).adjusted(-delta, -delta, delta, delta)); } /*! @@ -1090,7 +1085,7 @@ void QPixmapDropShadowFilter::draw(QPainter *p, QImage tmp = src.isNull() ? px.toImage() : px.copy(src.toAlignedRect()).toImage(); // blur the alpha channel - tmp = blurred(tmp, tmp.rect(), d->radius, true); + tmp = blurred(tmp, tmp.rect(), qRound(d->radius), true); // blacken the image... QPainter tmpPainter(&tmp); diff --git a/src/gui/image/qpixmapfilter_p.h b/src/gui/image/qpixmapfilter_p.h index 8a2207a..fc70795 100644 --- a/src/gui/image/qpixmapfilter_p.h +++ b/src/gui/image/qpixmapfilter_p.h @@ -129,10 +129,10 @@ public: QPixmapBlurFilter(QObject *parent = 0); ~QPixmapBlurFilter(); - void setRadius(int radius); + void setRadius(qreal radius); void setBlurHint(Qt::RenderHint hint); - int radius() const; + qreal radius() const; Qt::RenderHint blurHint() const; QRectF boundingRectFor(const QRectF &rect) const; @@ -175,8 +175,8 @@ public: QRectF boundingRectFor(const QRectF &rect) const; void draw(QPainter *p, const QPointF &pos, const QPixmap &px, const QRectF &src = QRectF()) const; - int blurRadius() const; - void setBlurRadius(int radius); + qreal blurRadius() const; + void setBlurRadius(qreal radius); QColor color() const; void setColor(const QColor &color); diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index c4d17ff..3f21bc3 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -561,8 +561,28 @@ void QCoeFepInputContext::GetCursorSelectionForFep(TCursorSelection& aCursorSele int cursor = w->inputMethodQuery(Qt::ImCursorPosition).toInt() + m_preeditString.size(); int anchor = w->inputMethodQuery(Qt::ImAnchorPosition).toInt() + m_preeditString.size(); - aCursorSelection.iAnchorPos = anchor; - aCursorSelection.iCursorPos = cursor; + QString text = w->inputMethodQuery(Qt::ImSurroundingText).value<QString>(); + int combinedSize = text.size() + m_preeditString.size(); + if (combinedSize < anchor || combinedSize < cursor) { + // ### TODO! FIXME! QTBUG-5050 + // This is a hack to prevent crashing in 4.6 with QLineEdits that use input masks. + // The root problem is that cursor position is relative to displayed text instead of the + // actual text we get. + // + // To properly fix this we would need to know the displayText of QLineEdits instead + // of just the text, which on itself should be a trivial change. The difficulties start + // when we need to commit the changes back to the QLineEdit, which would have to be somehow + // able to handle displayText, too. + // + // Until properly fixed, the cursor and anchor positions will not reflect correct positions + // for masked QLineEdits, unless all the masked positions are filled in order so that + // cursor position relative to the displayed text matches position relative to actual text. + aCursorSelection.iAnchorPos = combinedSize; + aCursorSelection.iCursorPos = combinedSize; + } else { + aCursorSelection.iAnchorPos = anchor; + aCursorSelection.iCursorPos = cursor; + } } void QCoeFepInputContext::GetEditorContentForFep(TDes& aEditorContent, TInt aDocumentPosition, diff --git a/src/gui/inputmethod/qwininputcontext_win.cpp b/src/gui/inputmethod/qwininputcontext_win.cpp index e9ab870..ef2f5c0 100644 --- a/src/gui/inputmethod/qwininputcontext_win.cpp +++ b/src/gui/inputmethod/qwininputcontext_win.cpp @@ -327,28 +327,13 @@ static int getCursorPosition(HIMC himc) static QString getString(HIMC himc, DWORD dwindex, int *selStart = 0, int *selLength = 0) { - static wchar_t *buffer = 0; - static int buflen = 0; - - int len = getCompositionString(himc, dwindex, 0, 0) + 1; - if (!buffer || len > buflen) { - delete [] buffer; - buflen = qMin(len, 256); - buffer = new wchar_t[buflen]; - } - - len = getCompositionString(himc, dwindex, buffer, buflen * sizeof(wchar_t)); + const int bufferSize = 256; + wchar_t buffer[bufferSize]; + int len = getCompositionString(himc, dwindex, buffer, bufferSize * sizeof(wchar_t)); if (selStart) { - static wchar_t *attrbuffer = 0; - static int attrbuflen = 0; - int attrlen = getCompositionString(himc, dwindex, 0, 0) + 1; - if (!attrbuffer || attrlen> attrbuflen) { - delete [] attrbuffer; - attrbuflen = qMin(attrlen, 256); - attrbuffer = new wchar_t[attrbuflen]; - } - attrlen = getCompositionString(himc, GCS_COMPATTR, attrbuffer, attrbuflen * sizeof(wchar_t)); + char attrbuffer[bufferSize]; + int attrlen = getCompositionString(himc, GCS_COMPATTR, attrbuffer, bufferSize); *selStart = attrlen+1; *selLength = -1; for (int i = 0; i < attrlen; i++) { diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index bf95684..7f11faa 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -1625,6 +1625,7 @@ void qt_init(QApplicationPrivate *priv, int, // MIT-SHM X11->use_mitshm = false; + X11->use_mitshm_pixmaps = false; X11->mitshm_major = 0; X11->sip_serial = 0; @@ -1918,12 +1919,13 @@ void qt_init(QApplicationPrivate *priv, int, bool local = displayName.isEmpty() || displayName.lastIndexOf(QLatin1Char(':')) == 0; if (local && (qgetenv("QT_X11_NO_MITSHM").toInt() == 0)) { Visual *defaultVisual = DefaultVisual(X11->display, DefaultScreen(X11->display)); - X11->use_mitshm = mitshm_pixmaps && ((defaultVisual->red_mask == 0xff0000 - || defaultVisual->red_mask == 0xf800) - && (defaultVisual->green_mask == 0xff00 - || defaultVisual->green_mask == 0x7e0) - && (defaultVisual->blue_mask == 0xff - || defaultVisual->blue_mask == 0x1f)); + X11->use_mitshm = ((defaultVisual->red_mask == 0xff0000 + || defaultVisual->red_mask == 0xf800) + && (defaultVisual->green_mask == 0xff00 + || defaultVisual->green_mask == 0x7e0) + && (defaultVisual->blue_mask == 0xff + || defaultVisual->blue_mask == 0x1f)); + X11->use_mitshm_pixmaps = X11->use_mitshm && mitshm_pixmaps; } } #endif // QT_NO_MITSHM diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp index 75c321e..a5a2201 100644 --- a/src/gui/kernel/qsoftkeymanager.cpp +++ b/src/gui/kernel/qsoftkeymanager.cpp @@ -139,11 +139,18 @@ QAction *QSoftKeyManager::createKeyedAction(StandardSoftKey standardKey, Qt::Key QScopedPointer<QAction> action(createAction(standardKey, actionWidget)); connect(action.data(), SIGNAL(triggered()), QSoftKeyManager::instance(), SLOT(sendKeyEvent())); - + connect(action.data(), SIGNAL(destroyed(QObject*)), QSoftKeyManager::instance(), SLOT(cleanupHash(QObject*))); QSoftKeyManager::instance()->d_func()->keyedActions.insert(action.data(), key); return action.take(); } +void QSoftKeyManager::cleanupHash(QObject* obj) +{ + Q_D(QSoftKeyManager); + QAction *action = qobject_cast<QAction*>(obj); + d->keyedActions.remove(action); +} + void QSoftKeyManager::sendKeyEvent() { Q_D(QSoftKeyManager); @@ -200,6 +207,7 @@ bool QSoftKeyManager::event(QEvent *e) void QSoftKeyManagerPrivate::updateSoftKeys_sys(const QList<QAction*> &softkeys) { CEikButtonGroupContainer* nativeContainer = S60->buttonGroupContainer(); + nativeContainer->DrawableWindow()->SetOrdinalPosition(0); nativeContainer->DrawableWindow()->SetPointerCapturePriority(1); //keep softkeys available in modal dialog QT_TRAP_THROWING(nativeContainer->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS)); diff --git a/src/gui/kernel/qsoftkeymanager_p.h b/src/gui/kernel/qsoftkeymanager_p.h index b455445..81218cf 100644 --- a/src/gui/kernel/qsoftkeymanager_p.h +++ b/src/gui/kernel/qsoftkeymanager_p.h @@ -96,6 +96,7 @@ protected: Q_DISABLE_COPY(QSoftKeyManager) private Q_SLOTS: + void cleanupHash(QObject* obj); void sendKeyEvent(); }; diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h index 62db064..5318d31 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h +++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h @@ -116,7 +116,7 @@ typedef struct CGPoint NSPoint; QT_BEGIN_NAMESPACE Qt::MouseButtons qt_mac_get_buttons(int buttons); Qt::MouseButton qt_mac_get_button(EventMouseButton button); -void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds = 0); +void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds = 0.15); bool macWindowIsTextured(void * /*OSWindowRef*/ window); void macWindowToolbarShow(const QWidget *widget, bool show ); void macWindowToolbarSet( void * /*OSWindowRef*/ window, void* toolbarRef ); diff --git a/src/gui/kernel/qt_x11_p.h b/src/gui/kernel/qt_x11_p.h index 61acbac..9f08dc6 100644 --- a/src/gui/kernel/qt_x11_p.h +++ b/src/gui/kernel/qt_x11_p.h @@ -428,6 +428,7 @@ struct QX11Data // true if Qt is compiled w/ MIT-SHM support and MIT-SHM is supported on the connected Display bool use_mitshm; + bool use_mitshm_pixmaps; int mitshm_major; // true if Qt is compiled w/ Tablet support and we have a tablet. diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 1951ab2..75bdd73 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -5433,7 +5433,8 @@ void QWidgetEffectSourcePrivate::draw(QPainter *painter) context->sharedPainter, context->backingStore); } -QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset) const +QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset, + QGraphicsEffectSource::PixmapPadMode mode) const { const bool deviceCoordinates = (system == Qt::DeviceCoordinates); if (!context && deviceCoordinates) { @@ -5451,7 +5452,20 @@ QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint * pixmapOffset = painterTransform.map(pixmapOffset); } - QRect effectRect = m_widget->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect(); + + QRect effectRect; + + if (mode == QGraphicsEffectSource::ExpandToEffectRectPadMode) { + effectRect = m_widget->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect(); + + } else if (mode == QGraphicsEffectSource::ExpandToTransparentBorderPadMode) { + effectRect = sourceRect.adjusted(-1, -1, 1, 1).toAlignedRect(); + + } else { + effectRect = sourceRect.toAlignedRect(); + + } + if (offset) *offset = effectRect.topLeft(); diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 95c0bed..58252ca 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -2896,6 +2896,7 @@ void QWidgetPrivate::setCursor_sys(const QCursor &) #else Q_Q(QWidget); if (q->testAttribute(Qt::WA_WState_Created)) { + QMacCocoaAutoReleasePool pool; [qt_mac_window_for(q) invalidateCursorRectsForView:qt_mac_nativeview_for(q)]; } #endif @@ -2908,6 +2909,7 @@ void QWidgetPrivate::unsetCursor_sys() #else Q_Q(QWidget); if (q->testAttribute(Qt::WA_WState_Created)) { + QMacCocoaAutoReleasePool pool; [qt_mac_window_for(q) invalidateCursorRectsForView:qt_mac_nativeview_for(q)]; } #endif diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 5cea641..73a7d68 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -818,7 +818,8 @@ public: QRectF boundingRect(Qt::CoordinateSystem system) const; void draw(QPainter *p); - QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset) const; + QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset, + QGraphicsEffectSource::PixmapPadMode mode) const; QWidget *m_widget; QWidgetPaintContext *context; diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index cb615fe..a6d8ed7 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -716,62 +716,6 @@ void QWidgetPrivate::s60UpdateIsOpaque() window->SetTransparentRegion(TRegionFix<1>()); } -CFbsBitmap* qt_pixmapToNativeBitmap(QPixmap pixmap, bool invert) -{ - CFbsBitmap* fbsBitmap = q_check_ptr(new CFbsBitmap); // CBase derived object needs check on new - TSize size(pixmap.size().width(), pixmap.size().height()); - TDisplayMode mode(EColor16MU); - - bool isNull = pixmap.isNull(); - int depth = pixmap.depth(); - - // TODO: dummy assumptions from bit amounts for each color - // Will fix later on when native pixmap is implemented - switch(pixmap.depth()) { - case 1: - mode = EGray2; - break; - case 4: - mode = EColor16; - break; - case 8: - mode = EColor256; - break; - case 12: - mode = EColor4K; - break; - case 16: - mode = EColor64K; - break; - case 24: - mode = EColor16M; - break; - case 32: - case EColor16MU: - break; - default: - qFatal("Unsupported pixmap depth"); - break; - } - - qt_symbian_throwIfError(fbsBitmap->Create(size, mode)); - fbsBitmap->LockHeap(); - QImage image = pixmap.toImage(); - - if (invert) - image.invertPixels(); - - int height = pixmap.size().height(); - for(int i=0;i<height;i++ ) - { - TPtr8 scanline(image.scanLine(i), image.bytesPerLine(), image.bytesPerLine()); - fbsBitmap->SetScanLine( scanline, i ); - } - - fbsBitmap->UnlockHeap(); - return fbsBitmap; -} - void QWidgetPrivate::setWindowIcon_sys(bool forceReset) { #ifdef Q_WS_S60 @@ -800,12 +744,8 @@ void QWidgetPrivate::setWindowIcon_sys(bool forceReset) mask.fill(Qt::color1); } - // Convert to CFbsBitmp - // TODO: When QPixmap is adapted to use native CFbsBitmap, - // it could be set directly to context pane - CFbsBitmap* nBitmap = qt_pixmapToNativeBitmap(pm, false); - CFbsBitmap* nMask = qt_pixmapToNativeBitmap(mask, true); - + CFbsBitmap* nBitmap = pm.toSymbianCFbsBitmap(); + CFbsBitmap* nMask = mask.toSymbianCFbsBitmap(); contextPane->SetPicture(nBitmap,nMask); } else { // Icon set to null -> set context pane picture to default @@ -836,12 +776,8 @@ void QWidgetPrivate::setWindowIcon_sys(bool forceReset) mask.fill(Qt::color1); } - // Convert to CFbsBitmp - // TODO: When QPixmap is adapted to use native CFbsBitmap, - // it could be set directly to context pane - CFbsBitmap* nBitmap = qt_pixmapToNativeBitmap(pm, false); - CFbsBitmap* nMask = qt_pixmapToNativeBitmap(mask, true); - + CFbsBitmap* nBitmap = pm.toSymbianCFbsBitmap(); + CFbsBitmap* nMask = mask.toSymbianCFbsBitmap(); titlePane->SetSmallPicture( nBitmap, nMask, ETrue ); } else { // Icon set to null -> set context pane picture to default diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index fd0e810..8d0b961 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1686,7 +1686,7 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen) if (!s->penData.blend) return; - if (s->flags.fast_pen && path.shape() <= QVectorPath::NonCurvedShapeHint + if (s->flags.fast_pen && !path.isCurved() && s->lastPen.brush().isOpaque()) { int count = path.elementCount(); QPointF *points = (QPointF *) path.points(); @@ -1739,8 +1739,7 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen) const QLineF *lines = reinterpret_cast<const QLineF *>(path.points()); for (int i = 0; i < lineCount; ++i) { - if (path.shape() == QVectorPath::LinesHint) - dashOffset = s->lastPen.dashOffset(); + dashOffset = s->lastPen.dashOffset(); if (lines[i].p1() == lines[i].p2()) { if (s->lastPen.capStyle() != Qt::FlatCap) { QPointF p = lines[i].p1(); @@ -5120,6 +5119,9 @@ void QSpanData::adjustSpanMethods() #else unclipped_blend = qBlendTexture; #endif + if (!texture.imageData) + unclipped_blend = 0; + break; } // setup clipping diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index 59482c6..35b77f7 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -146,7 +146,7 @@ static inline int qpainterOpToXrender(QPainter::CompositionMode mode) // hack, so we don't have to make QRegion::clipRectangles() public or include // X11 headers in qregion.h -Q_AUTOTEST_EXPORT void *qt_getClipRects(const QRegion &r, int &num) +Q_GUI_EXPORT void *qt_getClipRects(const QRegion &r, int &num) { return r.clipRectangles(num); } diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 195be0a..9e21182 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -92,6 +92,24 @@ QRectF QVectorPath::controlPointRect() const return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2)); } + +QVectorPath::CacheEntry *QVectorPath::addCacheData(QPaintEngineEx *engine, void *data, + qvectorpath_cache_cleanup cleanup) { + Q_ASSERT(!lookupCacheData(engine)); + if ((m_hints & IsCachedHint) == 0) { + m_cache = 0; + m_hints |= IsCachedHint; + } + CacheEntry *e = new CacheEntry; + e->engine = engine; + e->data = data; + e->cleanup = cleanup; + e->next = m_cache; + m_cache = e; + return m_cache; +} + + const QVectorPath &qtVectorPathForPath(const QPainterPath &path) { Q_ASSERT(path.d_func()); @@ -414,7 +432,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) // Some engines might decide to optimize for the non-shape hint later on... uint flags = QVectorPath::WindingFill; if (d->stroker.capStyle() == Qt::RoundCap || d->stroker.joinStyle() == Qt::RoundJoin) - flags |= QVectorPath::CurvedShapeHint; + flags |= QVectorPath::CurvedShapeMask; // ### Perspective Xforms are currently not supported... if (!pen.isCosmetic()) { @@ -442,7 +460,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) points[4], points[5]); points += 6; types += 3; - flags |= QVectorPath::CurvedShapeHint; + flags |= QVectorPath::CurvedShapeMask; break; default: break; @@ -504,7 +522,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y()); points += 6; types += 3; - flags |= QVectorPath::CurvedShapeHint; + flags |= QVectorPath::CurvedShapeMask; break; } default: @@ -736,7 +754,7 @@ void QPaintEngineEx::drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yR x1 + xRadius, y1 }; - QVectorPath path(pts, 17, qpaintengineex_roundedrect_types); + QVectorPath path(pts, 17, qpaintengineex_roundedrect_types, QVectorPath::RoundedRectHint); draw(path); } @@ -827,7 +845,7 @@ void QPaintEngineEx::drawPoints(const QPointF *points, int pointCount) pts[++oset] = points[i].x() + 0.001; pts[++oset] = points[i].y(); } - QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::NonCurvedShapeHint); + QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::LinesHint); stroke(path, pen); pointCount -= 16; points += 16; @@ -858,7 +876,7 @@ void QPaintEngineEx::drawPoints(const QPoint *points, int pointCount) pts[++oset] = points[i].x() + 0.001; pts[++oset] = points[i].y(); } - QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::NonCurvedShapeHint); + QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::LinesHint); stroke(path, pen); pointCount -= 16; points += 16; diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h index 3ec9bd6..02d77f4 100644 --- a/src/gui/painting/qpaintengineex_p.h +++ b/src/gui/painting/qpaintengineex_p.h @@ -250,9 +250,9 @@ public: inline uint QVectorPath::polygonFlags(QPaintEngine::PolygonDrawMode mode) { switch (mode) { case QPaintEngine::ConvexMode: return ConvexPolygonHint | ImplicitClose; - case QPaintEngine::OddEvenMode: return NonCurvedShapeHint | OddEvenFill | ImplicitClose; - case QPaintEngine::WindingMode: return NonCurvedShapeHint | WindingFill | ImplicitClose; - case QPaintEngine::PolylineMode: return NonCurvedShapeHint; + case QPaintEngine::OddEvenMode: return PolygonHint | OddEvenFill | ImplicitClose; + case QPaintEngine::WindingMode: return PolygonHint | WindingFill | ImplicitClose; + case QPaintEngine::PolylineMode: return PolygonHint; default: return 0; } } diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index 69e189c..c40bcee 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -688,6 +688,8 @@ void QPainterPath::lineTo(const QPointF &p) return; Element elm = { p.x(), p.y(), LineToElement }; d->elements.append(elm); + + d->convex = d->elements.size() == 3 || (d->elements.size() == 4 && d->isClosed()); } /*! @@ -960,6 +962,8 @@ void QPainterPath::addRect(const QRectF &r) ensureData(); detach(); + bool first = d_func()->elements.size() < 2; + d_func()->elements.reserve(d_func()->elements.size() + 5); moveTo(r.x(), r.y()); @@ -970,6 +974,7 @@ void QPainterPath::addRect(const QRectF &r) d_func()->elements << l1 << l2 << l3 << l4; d_func()->require_moveTo = true; + d_func()->convex = first; } /*! @@ -1039,6 +1044,7 @@ void QPainterPath::addEllipse(const QRectF &boundingRect) detach(); Q_D(QPainterPath); + bool first = d_func()->elements.size() < 2; d->elements.reserve(d->elements.size() + 13); QPointF pts[12]; @@ -1051,6 +1057,8 @@ void QPainterPath::addEllipse(const QRectF &boundingRect) cubicTo(pts[6], pts[7], pts[8]); // 180 -> 90 cubicTo(pts[9], pts[10], pts[11]); // 90 - >0 d_func()->require_moveTo = true; + + d_func()->convex = first; } /*! @@ -3027,6 +3035,8 @@ void QPainterPath::addRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadi ensureData(); detach(); + bool first = d_func()->elements.size() < 2; + arcMoveTo(x, y, rxx2, ryy2, 90); arcTo(x, y, rxx2, ryy2, 90, 90); arcTo(x, y+h-ryy2, rxx2, ryy2, 2*90, 90); @@ -3035,6 +3045,7 @@ void QPainterPath::addRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadi closeSubpath(); d_func()->require_moveTo = true; + d_func()->convex = first; } /*! @@ -3081,6 +3092,8 @@ void QPainterPath::addRoundRect(const QRectF &r, int xRnd, int yRnd) ensureData(); detach(); + bool first = d_func()->elements.size() < 2; + arcMoveTo(x, y, rxx2, ryy2, 90); arcTo(x, y, rxx2, ryy2, 90, 90); arcTo(x, y+h-ryy2, rxx2, ryy2, 2*90, 90); @@ -3089,6 +3102,7 @@ void QPainterPath::addRoundRect(const QRectF &r, int xRnd, int yRnd) closeSubpath(); d_func()->require_moveTo = true; + d_func()->convex = first; } /*! @@ -3269,6 +3283,7 @@ void QPainterPath::setDirty(bool dirty) d_func()->dirtyControlBounds = dirty; delete d_func()->pathConverter; d_func()->pathConverter = 0; + d_func()->convex = false; } void QPainterPath::computeBoundingRect() const diff --git a/src/gui/painting/qpainterpath_p.h b/src/gui/painting/qpainterpath_p.h index 54c182d..112c2bd 100644 --- a/src/gui/painting/qpainterpath_p.h +++ b/src/gui/painting/qpainterpath_p.h @@ -81,8 +81,8 @@ class QVectorPathConverter; class QVectorPathConverter { public: - QVectorPathConverter(const QVector<QPainterPath::Element> &path, uint fillRule) - : pathData(path, fillRule), + QVectorPathConverter(const QVector<QPainterPath::Element> &path, uint fillRule, bool convex) + : pathData(path, fillRule, convex), path(pathData.points.data(), path.size(), pathData.elements.data(), pathData.flags) {} @@ -91,7 +91,7 @@ public: } struct QVectorPathData { - QVectorPathData(const QVector<QPainterPath::Element> &path, uint fillRule) + QVectorPathData(const QVector<QPainterPath::Element> &path, uint fillRule, bool convex) : elements(path.size()), points(path.size() * 2), flags(0) @@ -103,7 +103,7 @@ public: points[ptsPos++] = e.x; points[ptsPos++] = e.y; if (e.type == QPainterPath::CurveToElement) - flags |= QVectorPath::CurvedShapeHint; + flags |= QVectorPath::CurvedShapeMask; } if (fillRule == Qt::WindingFill) @@ -111,6 +111,8 @@ public: else flags |= QVectorPath::OddEvenFill; + if (!convex) + flags |= QVectorPath::NonConvexShapeMask; } QVarLengthArray<QPainterPath::ElementType> elements; QVarLengthArray<qreal> points; @@ -128,20 +130,26 @@ class QPainterPathData : public QPainterPathPrivate { public: QPainterPathData() : - cStart(0), fillRule(Qt::OddEvenFill), - dirtyBounds(false), dirtyControlBounds(false), - pathConverter(0) + cStart(0), + fillRule(Qt::OddEvenFill), + pathConverter(0), + dirtyBounds(false), + dirtyControlBounds(false) + { ref = 1; require_moveTo = false; + convex = false; } QPainterPathData(const QPainterPathData &other) : QPainterPathPrivate(), cStart(other.cStart), fillRule(other.fillRule), - dirtyBounds(other.dirtyBounds), bounds(other.bounds), - dirtyControlBounds(other.dirtyControlBounds), + bounds(other.bounds), controlBounds(other.controlBounds), - pathConverter(0) + pathConverter(0), + dirtyBounds(other.dirtyBounds), + dirtyControlBounds(other.dirtyControlBounds), + convex(other.convex) { ref = 1; require_moveTo = false; @@ -158,20 +166,21 @@ public: const QVectorPath &vectorPath() { if (!pathConverter) - pathConverter = new QVectorPathConverter(elements, fillRule); + pathConverter = new QVectorPathConverter(elements, fillRule, convex); return pathConverter->path; } int cStart; Qt::FillRule fillRule; - bool require_moveTo; - - bool dirtyBounds; QRectF bounds; - bool dirtyControlBounds; QRectF controlBounds; + uint require_moveTo : 1; + uint dirtyBounds : 1; + uint dirtyControlBounds : 1; + uint convex : 1; + QVectorPathConverter *pathConverter; }; diff --git a/src/gui/painting/qvectorpath_p.h b/src/gui/painting/qvectorpath_p.h index d023131..ec27970 100644 --- a/src/gui/painting/qvectorpath_p.h +++ b/src/gui/painting/qvectorpath_p.h @@ -66,8 +66,9 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) +class QPaintEngineEx; -#define QVECTORPATH_NO_CACHE +typedef void (*qvectorpath_cache_cleanup)(void *data); struct QRealRect { qreal x1, y1, x2, y2; @@ -77,19 +78,27 @@ class Q_GUI_EXPORT QVectorPath { public: enum Hint { - // Basic shapes... - LinesHint = 0x0001, // Just plain lines... - RectangleHint = 0x0002, - ConvexPolygonHint = 0x0003, // Convex polygon... - NonISectPolygonHint = 0x0004, // concave polygon, but not intersecting.. - NonCurvedShapeHint = 0x0005, // Generic polygon, possibly self-intersecting... - CurvedShapeHint = 0x0006, // Generic vector path.. - EllipseHint = 0x0007, - ShapeHintMask = 0x000f, + // Shape hints, in 0x000000ff, access using shape() + AreaShapeMask = 0x0001, // shape covers an area + NonConvexShapeMask = 0x0002, // shape is not convex + CurvedShapeMask = 0x0004, // shape contains curves... + LinesShapeMask = 0x0008, + RectangleShapeMask = 0x0010, + ShapeMask = 0x001f, + + // Shape hints merged into basic shapes.. + LinesHint = LinesShapeMask, + RectangleHint = AreaShapeMask | RectangleShapeMask, + EllipseHint = AreaShapeMask | CurvedShapeMask, + ConvexPolygonHint = AreaShapeMask, + PolygonHint = AreaShapeMask | NonConvexShapeMask, + RoundedRectHint = AreaShapeMask | CurvedShapeMask, + ArbitraryShapeHint = AreaShapeMask | NonConvexShapeMask | CurvedShapeMask, // Other hints - CacheHint = 0x0100, - ControlPointRect = 0x0200, // Set if the control point rect has been calculated... + IsCachedHint = 0x0100, // Set if the cache hint is set + ShouldUseCacheHint = 0x0200, // Set if the path should be cached when possible.. + ControlPointRect = 0x0400, // Set if the control point rect has been calculated... // Shape rendering specifiers... OddEvenFill = 0x1000, @@ -101,22 +110,21 @@ public: QVectorPath(const qreal *points, int count, const QPainterPath::ElementType *elements = 0, - uint hints = CurvedShapeHint) + uint hints = ArbitraryShapeHint) : m_elements(elements), m_points(points), m_count(count), m_hints(hints) -#ifndef QVECTORPATH_NO_CACHE - , m_cache(0) -#endif { } QRectF controlPointRect() const; - inline Hint shape() const { return (Hint) (m_hints & ShapeHintMask); } + inline Hint shape() const { return (Hint) (m_hints & ShapeMask); } + inline bool isConvex() const { return (m_hints & NonConvexShapeMask) == 0; } + inline bool isCurved() const { return m_hints & CurvedShapeMask; } - inline bool hasCacheHint() const { return m_hints & CacheHint; } + inline bool isCacheable() const { return m_hints & ShouldUseCacheHint; } inline bool hasImplicitClose() const { return m_hints & ImplicitClose; } inline bool hasWindingFill() const { return m_hints & WindingFill; } @@ -131,24 +139,30 @@ public: static inline uint polygonFlags(QPaintEngine::PolygonDrawMode mode); -private: - Q_DISABLE_COPY(QVectorPath) - -#ifndef QVECTORPATH_NO_CACHE struct CacheEntry { - void *engine; - int id; - void *extra; + QPaintEngineEx *engine; + void *data; + qvectorpath_cache_cleanup cleanup; CacheEntry *next; }; - void addCacheData(CacheEntry *d) { - d->next = m_cache; - m_cache = d; + CacheEntry *addCacheData(QPaintEngineEx *engine, void *data, qvectorpath_cache_cleanup cleanup); + inline CacheEntry *lookupCacheData(QPaintEngineEx *engine) const { + Q_ASSERT(m_hints & IsCachedHint); + CacheEntry *e = m_cache; + while (e) { + if (e->engine == engine) + return e; + e = e->next; + } + return 0; } + +private: + Q_DISABLE_COPY(QVectorPath) + CacheEntry *m_cache; -#endif const QPainterPath::ElementType *m_elements; const qreal *m_points; diff --git a/src/gui/painting/qwindowsurface_raster.cpp b/src/gui/painting/qwindowsurface_raster.cpp index 3a118bd..d412040 100644 --- a/src/gui/painting/qwindowsurface_raster.cpp +++ b/src/gui/painting/qwindowsurface_raster.cpp @@ -215,6 +215,12 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi XCopyArea(X11->display, d_ptr->image->xshmpm, widget->handle(), d_ptr->gc, br.x(), br.y(), br.width(), br.height(), wbr.x(), wbr.y()); XSync(X11->display, False); + } else if (d_ptr->image->xshmimg) { + const QImage &src = d->image->image; + br = br.intersected(src.rect()); + XShmPutImage(X11->display, widget->handle(), d_ptr->gc, d_ptr->image->xshmimg, + br.x(), br.y(), wbr.x(), wbr.y(), br.width(), br.height(), False); + XSync(X11->display, False); } else #endif { diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index d315c98..b8d3674 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -1933,9 +1933,6 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom QRect grooveRect = option->rect.adjusted(focusFrameMargin, outerSize + focusFrameMargin, -focusFrameMargin, -outerSize - focusFrameMargin); - gtkPainter.paintBox( scaleWidget, "trough", grooveRect, state, - GTK_SHADOW_IN, style, QString(QLS("p%0")).arg(slider->sliderPosition)); - gboolean trough_side_details = false; // Indicates if the upper or lower scale background differs if (!QGtk::gtk_check_version(2, 10, 0)) QGtk::gtk_widget_style_get((GtkWidget*)(scaleWidget), "trough-side-details", &trough_side_details, NULL); diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 8d59d14..b87f3a8 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -66,7 +66,6 @@ #include "qtextedit.h" #include "qtoolbar.h" #include "qtoolbutton.h" -#include "qtreeview.h" #include "qfocusframe.h" #include "private/qtoolbarextension_p.h" @@ -91,14 +90,14 @@ static const qreal goldenRatio = 1.618; const layoutHeader QS60StylePrivate::m_layoutHeaders[] = { // *** generated layout data *** -{240,320,1,14,true,"QVGA Landscape Mirrored"}, -{240,320,1,14,false,"QVGA Landscape"}, -{320,240,1,14,true,"QVGA Portrait Mirrored"}, -{320,240,1,14,false,"QVGA Portrait"}, -{360,640,1,14,true,"NHD Landscape Mirrored"}, -{360,640,1,14,false,"NHD Landscape"}, -{640,360,1,14,true,"NHD Portrait Mirrored"}, -{640,360,1,14,false,"NHD Portrait"}, +{240,320,1,15,true,"QVGA Landscape Mirrored"}, +{240,320,1,15,false,"QVGA Landscape"}, +{320,240,1,15,true,"QVGA Portrait Mirrored"}, +{320,240,1,15,false,"QVGA Portrait"}, +{360,640,1,15,true,"NHD Landscape Mirrored"}, +{360,640,1,15,false,"NHD Landscape"}, +{640,360,1,15,true,"NHD Portrait Mirrored"}, +{640,360,1,15,false,"NHD Portrait"}, {352,800,1,12,true,"E90 Landscape Mirrored"}, {352,800,1,12,false,"E90 Landscape"} // *** End of generated data *** @@ -108,16 +107,16 @@ const int QS60StylePrivate::m_numberOfLayouts = const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = { // *** generated pixel metrics *** -{5,0,-909,0,0,1,0,0,-1,8,15,22,15,15,7,198,-909,-909,-909,19,15,2,0,0,21,-909,21,-909,4,4,1,-909,-909,0,2,0,0,13,23,17,17,21,21,2,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,51,27,51,4,4,5,10,15,-909,5,58,12,5,0,7,4,4,9,4,4,-909,1,-909,-909,-909,-909,4,4,3,1}, -{5,0,-909,0,0,1,0,0,-1,8,15,22,15,15,7,198,-909,-909,-909,19,15,2,0,0,21,-909,21,-909,4,4,1,-909,-909,0,2,0,0,13,23,17,17,21,21,2,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,51,27,51,4,4,5,10,15,-909,5,58,12,5,0,4,4,7,9,4,4,-909,1,-909,-909,-909,-909,4,4,3,1}, -{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,-909,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,7,4,4,9,4,4,-909,1,-909,-909,-909,-909,4,4,3,1}, -{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,-909,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,1,-909,-909,-909,-909,4,4,3,1}, -{7,0,-909,0,0,2,0,0,-1,20,53,28,19,19,9,258,-909,-909,-909,29,19,26,0,0,32,-909,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,8,5,5,12,5,5,-909,2,-909,-909,-909,-909,7,7,3,1}, -{7,0,-909,0,0,2,0,0,-1,20,53,28,19,19,9,258,-909,-909,-909,29,19,26,0,0,32,-909,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,2,-909,-909,-909,-909,7,7,3,1}, -{7,0,-909,0,0,2,0,0,-1,20,52,28,19,19,9,258,-909,-909,-909,29,19,6,0,0,32,-909,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,98,35,98,5,5,6,8,19,-909,7,74,22,7,0,8,5,5,12,5,5,-909,2,-909,-909,-909,-909,7,7,3,1}, -{7,0,-909,0,0,2,0,0,-1,20,52,28,19,19,9,258,-909,-909,-909,29,19,6,0,0,32,-909,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,98,35,98,5,5,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,2,-909,-909,-909,-909,7,7,3,1}, -{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,-909,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,5,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,8,6,5,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1}, -{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,-909,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1} +{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,-909,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,3,3,4,9,13,-909,5,51,11,5,0,6,3,3,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1}, +{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,-909,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,3,3,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1}, +{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,7,4,4,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1}, +{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1}, +{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,8,5,5,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, +{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, +{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,5,5,6,8,19,-909,7,74,22,7,0,8,5,5,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, +{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,5,5,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, +{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,5,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,8,6,5,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1}, +{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1} // *** End of generated data *** }; @@ -526,7 +525,8 @@ void QS60StylePrivate::drawPart(QS60StyleEnums::SkinParts skinPart, #else true; #endif - const QPixmap skinPartPixMap((doCache ? cachedPart : part)(skinPart, rect.size(), flags)); + + const QPixmap skinPartPixMap((doCache ? cachedPart : part)(skinPart, rect.size(), painter, flags)); if (!skinPartPixMap.isNull()) painter->drawPixmap(rect.topLeft(), skinPartPixMap); } @@ -593,14 +593,14 @@ void QS60StylePrivate::drawRow(QS60StyleEnums::SkinParts start, } QPixmap QS60StylePrivate::cachedPart(QS60StyleEnums::SkinParts part, - const QSize &size, SkinElementFlags flags) + const QSize &size, QPainter *painter, SkinElementFlags flags) { QPixmap result; 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); if (!QPixmapCache::find(cacheKey, result)) { - result = QS60StylePrivate::part(part, size, flags); + result = QS60StylePrivate::part(part, size, painter, flags); QPixmapCache::insert(cacheKey, result); } return result; @@ -1315,13 +1315,13 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, painter->setClipRect(voptAdj.rect); const bool isSelected = (vopt->state & QStyle::State_Selected); - bool isVisible = false; + bool isScrollBarVisible = false; int scrollBarWidth = 0; QList<QScrollBar *> scrollBars = qFindChildren<QScrollBar *>(widget); for (int i = 0; i < scrollBars.size(); ++i) { QScrollBar *scrollBar = scrollBars.at(i); if (scrollBar && scrollBar->orientation() == Qt::Vertical) { - isVisible = scrollBar->isVisible(); + isScrollBarVisible = scrollBar->isVisible(); scrollBarWidth = scrollBar->size().width(); break; } @@ -1329,7 +1329,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, int rightValue = widget ? widget->contentsRect().right() : 0; - if (isVisible) + if (isScrollBarVisible) rightValue -= scrollBarWidth; if (voptAdj.rect.right() > rightValue) @@ -1337,40 +1337,40 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, const QRect iconRect = subElementRect(SE_ItemViewItemDecoration, &voptAdj, widget); QRect textRect = subElementRect(SE_ItemViewItemText, &voptAdj, widget); + const QAbstractItemView *itemView = qobject_cast<const QAbstractItemView *>(widget); // draw themed background for table unless background brush has been defined. if (vopt->backgroundBrush == Qt::NoBrush) { - const QStyleOptionViewItemV4 *tableOption = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option); - const QTableView *table = qobject_cast<const QTableView *>(widget); - if (table && tableOption) { - const QModelIndex index = tableOption->index; + if (itemView) { + const QModelIndex index = vopt->index; //todo: Draw cell background only once - for the first cell. QStyleOptionViewItemV4 voptAdj2 = voptAdj; - const QModelIndex indexFirst = table->model()->index(0,0); - const QModelIndex indexLast = table->model()->index( - table->model()->rowCount()-1,table->model()->columnCount()-1); - if (table->viewport()) - voptAdj2.rect = QRect( table->visualRect(indexFirst).topLeft(), - table->visualRect(indexLast).bottomRight()).intersect(table->viewport()->rect()); - drawPrimitive(PE_PanelItemViewItem, &voptAdj2, painter, widget); + const QModelIndex indexFirst = itemView->model()->index(0,0); + const QModelIndex indexLast = itemView->model()->index( + itemView->model()->rowCount()-1,itemView->model()->columnCount()-1); + if (itemView->viewport()) + voptAdj2.rect = QRect( itemView->visualRect(indexFirst).topLeft(), + itemView->visualRect(indexLast).bottomRight()).intersect(itemView->viewport()->rect()); + drawPrimitive(PE_PanelItemViewItem, &voptAdj, painter, widget); } - } else { QCommonStyle::drawPrimitive(PE_PanelItemViewItem, option, painter, widget);} + } else { QCommonStyle::drawPrimitive(PE_PanelItemViewItem, &voptAdj, painter, widget);} // draw the focus rect if (isSelected) { QRect highlightRect = option->rect.adjusted(1,1,-1,-1); - const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget); - if (view && view->selectionBehavior() != QAbstractItemView::SelectItems) { + QAbstractItemView::SelectionBehavior selectionBehavior = + itemView ? itemView->selectionBehavior() : QAbstractItemView::SelectItems; + if (selectionBehavior != QAbstractItemView::SelectItems) { // set highlight rect so that it is continuous from cell to cell, yet sligthly // smaller than cell rect int xBeginning = 0, yBeginning = 0, xEnd = 0, yEnd = 0; - if (view->selectionBehavior() == QAbstractItemView::SelectRows) { + if (selectionBehavior == QAbstractItemView::SelectRows) { yBeginning = 1; yEnd = -1; if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning) xBeginning = 1; else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End) xEnd = -1; - } else if (view->selectionBehavior() == QAbstractItemView::SelectColumns) { + } else if (selectionBehavior == QAbstractItemView::SelectColumns) { xBeginning = 1; xEnd = -1; if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning) yBeginning = 1; @@ -1379,7 +1379,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, } highlightRect = option->rect.adjusted(xBeginning, yBeginning, xEnd, yEnd); } - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, highlightRect, flags); + if (vopt->showDecorationSelected && + (vopt->palette.highlight().color() == d->themePalette()->highlight().color())) + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, highlightRect, flags); } // draw the icon @@ -1388,48 +1390,44 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, voptAdj.icon.paint(painter, iconRect, voptAdj.decorationAlignment, mode, state); // Draw selection check mark. Show check mark only in multi selection modes. - if (const QListView *listView = (qobject_cast<const QListView *>(widget))) { + if (itemView) { const bool singleSelection = - listView && - (listView->selectionMode() == QAbstractItemView::SingleSelection || - listView->selectionMode() == QAbstractItemView::NoSelection); + (itemView->selectionMode() == QAbstractItemView::SingleSelection || + itemView->selectionMode() == QAbstractItemView::NoSelection); const QRect selectionRect = subElementRect(SE_ItemViewItemCheckIndicator, &voptAdj, widget); + + QStyleOptionViewItemV4 checkMarkOption(voptAdj); + // Draw selection mark. if (voptAdj.state & QStyle::State_Selected && !singleSelection) { - QStyleOptionViewItemV4 option(voptAdj); - option.rect = selectionRect; - // Draw selection mark. - drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &option, painter, widget); + checkMarkOption.rect = selectionRect; + drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget); if ( textRect.right() > selectionRect.left() ) textRect.setRight(selectionRect.left()); } else if (singleSelection && - voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator) { - // draw the check mark - if (selectionRect.isValid()) { - QStyleOptionViewItemV4 option(*vopt); - option.rect = selectionRect; - option.state = option.state & ~QStyle::State_HasFocus; - - switch (vopt->checkState) { - case Qt::Unchecked: - option.state |= QStyle::State_Off; - break; - case Qt::PartiallyChecked: - option.state |= QStyle::State_NoChange; - break; - case Qt::Checked: - option.state |= QStyle::State_On; - break; - } - drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &option, painter, widget); + voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator && + selectionRect.isValid()) { + checkMarkOption.rect = selectionRect; + checkMarkOption.state = checkMarkOption.state & ~QStyle::State_HasFocus; + + switch (vopt->checkState) { + case Qt::Unchecked: + checkMarkOption.state |= QStyle::State_Off; + break; + case Qt::PartiallyChecked: + checkMarkOption.state |= QStyle::State_NoChange; + break; + case Qt::Checked: + checkMarkOption.state |= QStyle::State_On; + break; } + drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget); } } // draw the text if (!voptAdj.text.isEmpty()) { - const QStyleOptionViewItemV4 *tableOption = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option); if (isSelected) { - if (qobject_cast<const QTableView *>(widget) && tableOption) + if (qobject_cast<const QTableView *>(widget)) voptAdj.palette.setColor( QPalette::Text, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 11, 0)); else @@ -1722,8 +1720,11 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, // direction is set to north (and south when in RightToLeft) const QS60StylePrivate::SkinElementFlag arrowDirection = (arrowOptions.direction == Qt::LeftToRight) ? QS60StylePrivate::SF_PointNorth : QS60StylePrivate::SF_PointSouth; + painter->save(); + painter->setPen(option->palette.windowText().color()); QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnIndiSubMenu, painter, arrowOptions.rect, (flags | QS60StylePrivate::SF_ColorSkinned | arrowDirection)); + painter->restore(); } //draw text @@ -1830,8 +1831,12 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, break; #endif //QT_NO_TOOLBAR case CE_ShapedFrame: - if (qobject_cast<const QTextEdit *>(widget)) { - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_Editor, painter, option->rect, flags); + if (const QTextEdit *textEdit = qobject_cast<const QTextEdit *>(widget)) { + const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(option); + if (frame->palette.base().color()==Qt::transparent) + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_Editor, painter, option->rect, flags); + else + QCommonStyle::drawControl(element, option, painter, widget); } else if (qobject_cast<const QTableView *>(widget)) { QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_TableItem, painter, option->rect, flags); } else if (const QHeaderView *header = qobject_cast<const QHeaderView *>(widget)) { @@ -1889,6 +1894,17 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, painter->restore(); } break; + case CE_Splitter: + if (option->state & State_Sunken && option->state & State_Enabled) { + painter->save(); + painter->setOpacity(0.5); + painter->setBrush(d->themePalette()->light()); + painter->setRenderHint(QPainter::Antialiasing); + const qreal roundRectRadius = 4 * goldenRatio; + painter->drawRoundedRect(option->rect, roundRectRadius, roundRectRadius); + painter->restore(); + } + break; default: QCommonStyle::drawControl(element, option, painter, widget); } @@ -1899,6 +1915,7 @@ 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; switch (element) { #ifndef QT_NO_LINEEDIT @@ -1908,19 +1925,27 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti if (widget && qobject_cast<const QComboBox *>(widget->parentWidget())) break; #endif - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_FrameLineEdit, - painter, option->rect, flags); + QBrush editBrush = option->palette.brush(QPalette::Base); + if (editBrush.color() == Qt::transparent) + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_FrameLineEdit, + painter, option->rect, flags); + else + QCommonStyle::drawPrimitive(element, option, painter, widget); } break; #endif // QT_NO_LINEEDIT case PE_IndicatorCheckBox: { - const QRect indicatorRect = option->rect; // Draw checkbox indicator as color skinned graphics. const QS60StyleEnums::SkinParts skinPart = (option->state & QStyle::State_On) ? QS60StyleEnums::SP_QgnIndiCheckboxOn : QS60StyleEnums::SP_QgnIndiCheckboxOff; - QS60StylePrivate::drawSkinPart(skinPart, painter, indicatorRect, - (flags | QS60StylePrivate::SF_ColorSkinned)); + painter->save(); + QColor themeColor = d->s60Color(QS60StyleEnums::CL_QsnIconColors, 13, option); + QColor buttonTextColor = option->palette.buttonText().color(); + if (themeColor != buttonTextColor) + painter->setPen(buttonTextColor); + QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, flags | QS60StylePrivate::SF_ColorSkinned ); + painter->restore(); } break; case PE_IndicatorViewItemCheck: @@ -1960,21 +1985,33 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti const int newY = (buttonRect.bottomRight().y() - option->rect.bottomRight().y()) >> 1 ; buttonRect.adjust(0,-newY,0,-newY); + painter->save(); + QColor themeColor = d->s60Color(QS60StyleEnums::CL_QsnIconColors, 13, option); + QColor buttonTextColor = option->palette.buttonText().color(); + if (themeColor != buttonTextColor) + painter->setPen(buttonTextColor); + // Draw radiobutton indicator as color skinned graphics. QS60StyleEnums::SkinParts skinPart = (option->state & QStyle::State_On) ? QS60StyleEnums::SP_QgnIndiRadiobuttOn : QS60StyleEnums::SP_QgnIndiRadiobuttOff; QS60StylePrivate::drawSkinPart(skinPart, painter, buttonRect, (flags | QS60StylePrivate::SF_ColorSkinned)); + painter->restore(); } break; case PE_PanelButtonCommand: case PE_PanelButtonTool: case PE_PanelButtonBevel: case PE_FrameButtonBevel: { - const bool isPressed = option->state & QStyle::State_Sunken; - const QS60StylePrivate::SkinElements skinElement = - isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal; - QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags); + QBrush editBrush = option->palette.brush(QPalette::Base); + if (editBrush.color() == Qt::transparent) { + const bool isPressed = option->state & QStyle::State_Sunken; + const QS60StylePrivate::SkinElements skinElement = + isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal; + QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags); + } else { + QCommonStyle::drawPrimitive(element, option, painter, widget); + } } break; #ifndef QT_NO_TOOLBUTTON @@ -2001,21 +2038,29 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti case PE_IndicatorSpinUp: if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { QStyleOptionSpinBox optionSpinBox = *spinBox; - const QS60StyleEnums::SkinParts part = (element == PE_IndicatorSpinUp) ? - QS60StyleEnums::SP_QgnGrafScrollArrowUp : - QS60StyleEnums::SP_QgnGrafScrollArrowDown; - const int adjustment = qMin(optionSpinBox.rect.width(), optionSpinBox.rect.height())/6; - optionSpinBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment ); - QS60StylePrivate::drawSkinPart(part, painter, optionSpinBox.rect,flags); + if (optionSpinBox.palette.base().color()==Qt::transparent) { + const QS60StyleEnums::SkinParts part = (element == PE_IndicatorSpinUp) ? + QS60StyleEnums::SP_QgnGrafScrollArrowUp : + QS60StyleEnums::SP_QgnGrafScrollArrowDown; + const int adjustment = qMin(optionSpinBox.rect.width(), optionSpinBox.rect.height())/6; + optionSpinBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment ); + QS60StylePrivate::drawSkinPart(part, painter, optionSpinBox.rect,flags); + } else { + QCommonStyle::drawPrimitive(element, &optionSpinBox, painter, widget); + } } #ifndef QT_NO_COMBOBOX else if (const QStyleOptionFrame *cmb = qstyleoption_cast<const QStyleOptionFrame *>(option)) { - // We want to draw down arrow here for comboboxes as well. - const QS60StyleEnums::SkinParts part = QS60StyleEnums::SP_QgnGrafScrollArrowDown; - QStyleOptionFrame comboBox = *cmb; - const int adjustment = qMin(comboBox.rect.width(), comboBox.rect.height())/6; - comboBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment ); - QS60StylePrivate::drawSkinPart(part, painter, comboBox.rect,flags); + if (cmb->palette.base().color()==Qt::transparent) { + // We want to draw down arrow here for comboboxes as well. + const QS60StyleEnums::SkinParts part = QS60StyleEnums::SP_QgnGrafScrollArrowDown; + QStyleOptionFrame comboBox = *cmb; + const int adjustment = qMin(comboBox.rect.width(), comboBox.rect.height())/6; + comboBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment ); + QS60StylePrivate::drawSkinPart(part, painter, comboBox.rect,flags); + } else { + QCommonStyle::drawPrimitive(element, cmb, painter, widget); + } } #endif //QT_NO_COMBOBOX break; @@ -2045,8 +2090,12 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti || qobject_cast<const QMenu *> (widget) #endif //QT_NO_MENU ) { - QS60StylePrivate::SkinElements skinElement = QS60StylePrivate::SE_OptionsMenu; - QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags); + if (option->palette.base().color()==Qt::transparent) { + QS60StylePrivate::SkinElements skinElement = QS60StylePrivate::SE_OptionsMenu; + QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags); + } else { + QCommonStyle::drawPrimitive(element, option, painter, widget); + } } break; case PE_FrameWindow: @@ -2133,7 +2182,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti drawSkinPart = true; } - if ( drawSkinPart ) + if (drawSkinPart) QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, flags); if (option->state & State_Children) { @@ -2190,7 +2239,7 @@ int QS60Style::pixelMetric(PixelMetric metric, const QStyleOption *option, const if (metricValue == KNotFound) metricValue = QCommonStyle::pixelMetric(metric, option, widget); - if (metric == PM_SubMenuOverlap && widget){ + if (metric == PM_SubMenuOverlap && widget) { const QMenu *menu = qobject_cast<const QMenu *>(widget); if (menu && menu->activeAction() && menu->activeAction()->menu()) { const int menuWidth = menu->activeAction()->menu()->sizeHint().width(); @@ -2878,7 +2927,7 @@ QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon, return QCommonStyle::standardIconImplementation(standardIcon, option, widget); } const QS60StylePrivate::SkinElementFlags flags = adjustedFlags; - const QPixmap cachedPixMap(QS60StylePrivate::cachedPart(part, iconSize.size(), flags)); + const QPixmap cachedPixMap(QS60StylePrivate::cachedPart(part, iconSize.size(), 0, flags)); return cachedPixMap.isNull() ? QCommonStyle::standardIconImplementation(standardIcon, option, widget) : QIcon(cachedPixMap); } diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index 8e53eee..54af757 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -372,7 +372,7 @@ public: SF_StateEnabled = 0x0010, // Enabled = the default SF_StateDisabled = 0x0020, - SF_ColorSkinned = 0x0040, + SF_ColorSkinned = 0x0040, // pixmap is colored with foreground pen color }; enum CacheClearReason { @@ -472,7 +472,7 @@ private: const QRect &rect, SkinElementFlags flags = KDefaultSkinElementFlags); static QPixmap cachedPart(QS60StyleEnums::SkinParts part, const QSize &size, - SkinElementFlags flags = KDefaultSkinElementFlags); + QPainter *painter, SkinElementFlags flags = KDefaultSkinElementFlags); static QPixmap cachedFrame(SkinFrameElements frame, const QSize &size, SkinElementFlags flags = KDefaultSkinElementFlags); @@ -489,7 +489,7 @@ private: static QSize partSize(QS60StyleEnums::SkinParts part, SkinElementFlags flags = KDefaultSkinElementFlags); static QPixmap part(QS60StyleEnums::SkinParts part, const QSize &size, - SkinElementFlags flags = KDefaultSkinElementFlags); + QPainter *painter, SkinElementFlags flags = KDefaultSkinElementFlags); static QFont s60Font_specific(QS60StyleEnums::FontCategories fontCategory, int pointSize); diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index 9765066..678844c 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -99,7 +99,7 @@ public: const QSize &size, QS60StylePrivate::SkinElementFlags flags); static QPixmap skinnedGraphics(QS60StylePrivate::SkinFrameElements frameElement, const QSize &size, QS60StylePrivate::SkinElementFlags flags); static QPixmap colorSkinnedGraphics(const QS60StyleEnums::SkinParts &stylepart, - const QSize &size, QS60StylePrivate::SkinElementFlags flags); + const QSize &size, QPainter *painter, QS60StylePrivate::SkinElementFlags flags); static QColor colorValue(const TAknsItemID &colorGroup, int colorIndex); static QPixmap fromFbsBitmap(CFbsBitmap *icon, CFbsBitmap *mask, QS60StylePrivate::SkinElementFlags flags, QImage::Format format); static bool disabledPartGraphic(QS60StyleEnums::SkinParts &part); @@ -112,14 +112,12 @@ private: const QSize &size, QS60StylePrivate::SkinElementFlags flags); static QPixmap createSkinnedGraphicsLX(QS60StylePrivate::SkinFrameElements frameElement, const QSize &size, QS60StylePrivate::SkinElementFlags flags); static QPixmap colorSkinnedGraphicsLX(const QS60StyleEnums::SkinParts &stylepart, - const QSize &size, QS60StylePrivate::SkinElementFlags flags); + const QSize &size, QPainter *painter, QS60StylePrivate::SkinElementFlags flags); static void frameIdAndCenterId(QS60StylePrivate::SkinFrameElements frameElement, TAknsItemID &frameId, TAknsItemID ¢erId); static TRect innerRectFromElement(QS60StylePrivate::SkinFrameElements frameElement, const TRect &outerRect); static void checkAndUnCompressBitmapL(CFbsBitmap*& aOriginalBitmap); static void checkAndUnCompressBitmap(CFbsBitmap*& aOriginalBitmap); static void unCompressBitmapL(const TRect& aTrgRect, CFbsBitmap* aTrgBitmap, CFbsBitmap* aSrcBitmap); - static void colorGroupAndIndex(QS60StyleEnums::SkinParts skinID, - TAknsItemID &colorGroup, int &colorIndex); static void fallbackInfo(const QS60StyleEnums::SkinParts &stylepart, TDes& fallbackFileName, TInt& fallbackIndex); static bool checkSupport(const int supportedRelease); static TAknsItemID checkAndUpdateReleaseSpecificGraphics(int part); @@ -361,11 +359,11 @@ QPixmap QS60StyleModeSpecifics::skinnedGraphics( } QPixmap QS60StyleModeSpecifics::colorSkinnedGraphics( - const QS60StyleEnums::SkinParts &stylepart, - const QSize &size, QS60StylePrivate::SkinElementFlags flags) + const QS60StyleEnums::SkinParts &stylepart, const QSize &size, QPainter *painter, + QS60StylePrivate::SkinElementFlags flags) { QPixmap colorGraphics; - TRAPD(error, QT_TRYCATCH_LEAVING(colorGraphics = colorSkinnedGraphicsLX(stylepart, size, flags))); + TRAPD(error, QT_TRYCATCH_LEAVING(colorGraphics = colorSkinnedGraphicsLX(stylepart, size, painter, flags))); return error ? QPixmap() : colorGraphics; } @@ -525,7 +523,7 @@ void QS60StyleModeSpecifics::fallbackInfo(const QS60StyleEnums::SkinParts &style QPixmap QS60StyleModeSpecifics::colorSkinnedGraphicsLX( const QS60StyleEnums::SkinParts &stylepart, - const QSize &size, QS60StylePrivate::SkinElementFlags flags) + const QSize &size, QPainter *painter, QS60StylePrivate::SkinElementFlags flags) { // this function can throw both exceptions and leaves. There are no cleanup dependencies between Qt and Symbian parts. const int stylepartIndex = (int)stylepart; @@ -537,8 +535,13 @@ QPixmap QS60StyleModeSpecifics::colorSkinnedGraphicsLX( fallbackInfo(stylepart, fileNamePtr, fallbackGraphicID); TAknsItemID colorGroup = KAknsIIDQsnIconColors; - int colorIndex = 0; - colorGroupAndIndex(stylepart, colorGroup, colorIndex); + TRgb defaultColor = KRgbBlack; + int colorIndex = -1; //set a bogus value to color index to ensure that painter color is used + //to color the icon + if (painter) { + QRgb widgetColor = painter->pen().color().rgb(); + defaultColor = TRgb(qRed(widgetColor), qGreen(widgetColor), qBlue(widgetColor)); + } const bool rotatedBy90or270 = (flags & (QS60StylePrivate::SF_PointEast | QS60StylePrivate::SF_PointWest)); @@ -550,7 +553,7 @@ QPixmap QS60StyleModeSpecifics::colorSkinnedGraphicsLX( fallbackGraphicID == KErrNotFound?KErrNotFound:fallbackGraphicID+1; //masks are auto-generated as next in mif files MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); AknsUtils::CreateColorIconLC( - skinInstance, skinId, colorGroup, colorIndex, icon, iconMask, fileNamePtr, fallbackGraphicID , fallbackGraphicsMaskID, KRgbBlack); + skinInstance, skinId, colorGroup, colorIndex, icon, iconMask, fileNamePtr, fallbackGraphicID , fallbackGraphicsMaskID, defaultColor); User::LeaveIfError(AknIconUtils::SetSize(icon, targetSize, EAspectRatioNotPreserved)); User::LeaveIfError(AknIconUtils::SetSize(iconMask, targetSize, EAspectRatioNotPreserved)); QPixmap result = fromFbsBitmap(icon, iconMask, flags, qt_TDisplayMode2Format(icon->DisplayMode())); @@ -652,8 +655,8 @@ QPoint qt_s60_fill_background_offset(const QWidget *targetWidget) } QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX( - QS60StyleEnums::SkinParts part, - const QSize &size, QS60StylePrivate::SkinElementFlags flags) + QS60StyleEnums::SkinParts part, const QSize &size, + QS60StylePrivate::SkinElementFlags flags) { // this function can throw both exceptions and leaves. There are no cleanup dependencies between Qt and Symbian parts. if (!size.isValid()) @@ -700,13 +703,13 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX( CleanupStack::PushL(background); User::LeaveIfError(background->Create(targetSize, EColor16MA)); - CFbsBitmapDevice* dev = CFbsBitmapDevice::NewL(background); + CFbsBitmapDevice *dev = CFbsBitmapDevice::NewL(background); CleanupStack::PushL(dev); - CFbsBitGc* gc = NULL; + CFbsBitGc *gc = NULL; User::LeaveIfError(dev->CreateContext(gc)); CleanupStack::PushL(gc); - CAknsBasicBackgroundControlContext* bgContext = CAknsBasicBackgroundControlContext::NewL( + CAknsBasicBackgroundControlContext *bgContext = CAknsBasicBackgroundControlContext::NewL( skinId, targetSize, EFalse); @@ -1145,12 +1148,12 @@ QPixmap QS60StyleModeSpecifics::generateMissingThemeGraphic(QS60StyleEnums::Skin } QPixmap QS60StylePrivate::part(QS60StyleEnums::SkinParts part, - const QSize &size, SkinElementFlags flags) + const QSize &size, QPainter *painter, SkinElementFlags flags) { QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); QPixmap result = (flags & SF_ColorSkinned)? - QS60StyleModeSpecifics::colorSkinnedGraphics(part, size, flags) + QS60StyleModeSpecifics::colorSkinnedGraphics(part, size, painter, flags) : QS60StyleModeSpecifics::skinnedGraphics(part, size, flags); lock.relock(); @@ -1189,7 +1192,7 @@ QPixmap QS60StylePrivate::backgroundTexture() { if (!m_background) { QPixmap background = part(QS60StyleEnums::SP_QsnBgScreen, - QSize(S60->screenWidthInPixels, S60->screenHeightInPixels), SkinElementFlags()); + QSize(S60->screenWidthInPixels, S60->screenHeightInPixels), 0, SkinElementFlags()); m_background = new QPixmap(background); } return *m_background; @@ -1343,26 +1346,6 @@ QSize QS60StylePrivate::screenSize() return QSize(screenSize.iWidth, screenSize.iHeight); } -void QS60StyleModeSpecifics::colorGroupAndIndex( - QS60StyleEnums::SkinParts skinID, TAknsItemID &colorGroup, int &colorIndex) -{ - switch(skinID) { - case QS60StyleEnums::SP_QgnIndiSubMenu: - colorGroup = KAknsIIDQsnIconColors; - colorIndex = EAknsCIQsnIconColorsCG1; - break; - case QS60StyleEnums::SP_QgnIndiRadiobuttOff: - case QS60StyleEnums::SP_QgnIndiRadiobuttOn: - case QS60StyleEnums::SP_QgnIndiCheckboxOff: - case QS60StyleEnums::SP_QgnIndiCheckboxOn: - colorGroup = KAknsIIDQsnIconColors; - colorIndex = EAknsCIQsnIconColorsCG14; - break; - default: - break; - } -} - QS60Style::QS60Style() : QCommonStyle(*new QS60StylePrivate) { diff --git a/src/gui/styles/qs60style_simulated.cpp b/src/gui/styles/qs60style_simulated.cpp index 8a2616d..14f0424 100644 --- a/src/gui/styles/qs60style_simulated.cpp +++ b/src/gui/styles/qs60style_simulated.cpp @@ -189,8 +189,10 @@ QColor QS60StylePrivate::s60Color(QS60StyleEnums::ColorLists list, } QPixmap QS60StylePrivate::part(QS60StyleEnums::SkinParts part, const QSize &size, - QS60StylePrivate::SkinElementFlags flags) + QPainter *painter, QS60StylePrivate::SkinElementFlags flags) { + Q_UNUSED(painter); + const QString partKey = QS60Style::partKeys().at(part); const QPicture partPicture = QS60StyleModeSpecifics::m_partPictures.value(partKey); QSize partSize(partPicture.boundingRect().size()); diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 8ce437d..a4e7c04 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -546,7 +546,7 @@ void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *position cgMatrix = CGAffineTransformScale(cgMatrix, 1, -1); if (synthesisFlags & QFontEngine::SynthesizedItalic) - cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, tanf(14 * acosf(0) / 90), 1, 0, 0)); + cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0)); for (int i = 0; i < nGlyphs; ++i) { diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp index fd34d0f..6c367ab 100644 --- a/src/gui/text/qfontengine_win.cpp +++ b/src/gui/text/qfontengine_win.cpp @@ -208,7 +208,7 @@ void QFontEngineWin::getCMap() unitsPerEm = otm->otmEMSquare; x_height = (int)otm->otmsXHeight; loadKerningPairs(designToDevice); - _faceId.filename = (char *)otm + (int)otm->otmpFullName; + _faceId.filename = QString::fromWCharArray((wchar_t *)((char *)otm + (int)otm->otmpFullName)).toLatin1(); lineWidth = otm->otmsUnderscoreSize; fsType = otm->otmfsType; free(otm); @@ -987,8 +987,8 @@ QFontEngine::Properties QFontEngineWin::properties() const Properties p; p.emSquare = unitsPerEm; p.italicAngle = otm->otmItalicAngle; - p.postscriptName = (char *)otm + (int)otm->otmpFamilyName; - p.postscriptName += (char *)otm + (int)otm->otmpStyleName; + p.postscriptName = QString::fromWCharArray((wchar_t *)((char *)otm + (int)otm->otmpFamilyName)).toLatin1(); + p.postscriptName += QString::fromWCharArray((wchar_t *)((char *)otm + (int)otm->otmpStyleName)).toLatin1(); #ifndef QT_NO_PRINTER p.postscriptName = QPdf::stripSpecialCharacters(p.postscriptName); #endif @@ -1110,7 +1110,7 @@ QNativeImage *QFontEngineWin::drawGDIGlyph(HFONT font, glyph_t glyph, int margin ih + 2 * margin + 4, QNativeImage::systemFormat(), !qt_cleartype_enabled); - /*If cleartype is enabled we use the standard system format even on Windows CE + /*If cleartype is enabled we use the standard system format even on Windows CE and not the special textbuffer format we have to use if cleartype is disabled*/ ni->image.fill(0xffffffff); diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index e22303d..af9306f 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -476,7 +476,7 @@ bool QGLEngineShaderManager::useCorrectShaderProg() return false; bool useCustomSrc = customSrcStage != 0; - if (useCustomSrc && srcPixelType != QGLEngineShaderManager::ImageSrc) { + if (useCustomSrc && srcPixelType != QGLEngineShaderManager::ImageSrc && srcPixelType != Qt::TexturePattern) { useCustomSrc = false; qWarning("QGLEngineShaderManager - Ignoring custom shader stage for non image src"); } diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index 3eef808..2407979 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -258,7 +258,7 @@ static const char* const qglslPositionWithTextureBrushVertexShader = "\ uniform mediump vec2 halfViewportSize; \ uniform highp vec2 invertedTextureSize; \ uniform highp mat3 brushTransform; \ - varying highp vec2 brushTextureCoords; \ + varying highp vec2 textureCoords; \ void setPosition(void) { \ gl_Position = pmvMatrix * vertexCoordsArray;\ gl_Position.xy = gl_Position.xy / gl_Position.w; \ @@ -267,7 +267,7 @@ static const char* const qglslPositionWithTextureBrushVertexShader = "\ mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \ gl_Position.w = invertedHTexCoordsZ; \ - brushTextureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \ + textureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \ }"; static const char* const qglslAffinePositionWithTextureBrushVertexShader @@ -278,26 +278,26 @@ static const char* const qglslAffinePositionWithTextureBrushVertexShader // 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 brushTextureCoords; \ + varying highp vec2 textureCoords; \ uniform lowp sampler2D brushTexture; \ lowp vec4 srcPixel() { \ - return texture2D(brushTexture, fract(brushTextureCoords)); \ + return texture2D(brushTexture, fract(textureCoords)); \ }"; #else static const char* const qglslTextureBrushSrcFragmentShader = "\ - varying highp vec2 brushTextureCoords; \ + varying highp vec2 textureCoords; \ uniform lowp sampler2D brushTexture; \ lowp vec4 srcPixel() { \ - return texture2D(brushTexture, brushTextureCoords); \ + return texture2D(brushTexture, textureCoords); \ }"; #endif static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\ - varying highp vec2 brushTextureCoords; \ + varying highp vec2 textureCoords; \ uniform lowp vec4 patternColor; \ uniform lowp sampler2D brushTexture; \ lowp vec4 srcPixel() { \ - return patternColor * (1.0 - texture2D(brushTexture, brushTextureCoords).r); \ + return patternColor * (1.0 - texture2D(brushTexture, textureCoords).r); \ }"; // Solid Fill Brush diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index a0810bc..a9744b3 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -535,7 +535,7 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::PatternColor), col); } - QSizeF invertedTextureSize(1.0 / texPixmap.width(), 1.0 * textureInvertedY / texPixmap.height()); + QSizeF invertedTextureSize(1.0 / texPixmap.width(), 1.0 / texPixmap.height()); shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::InvertedTextureSize), invertedTextureSize); QVector2D halfViewportSize(width*0.5, height*0.5); @@ -550,7 +550,11 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() QTransform translate(1, 0, 0, 1, -translationPoint.x(), -translationPoint.y()); QTransform gl_to_qt(1, 0, 0, -1, 0, height); - QTransform inv_matrix = gl_to_qt * (brushQTransform * matrix).inverted() * translate; + QTransform inv_matrix; + if (style == Qt::TexturePattern && textureInvertedY == -1) + inv_matrix = gl_to_qt * (QTransform(1, 0, 0, -1, 0, currentBrush->texture().height()) * brushQTransform * matrix).inverted() * translate; + else + inv_matrix = gl_to_qt * (brushQTransform * matrix).inverted() * translate; shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::BrushTransform), inv_matrix); shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::BrushTexture), QT_BRUSH_TEXTURE_UNIT); @@ -858,9 +862,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) QGLRect rect(points[0].x(), points[0].y(), points[2].x(), points[2].y()); prepareForDraw(currentBrush->isOpaque()); composite(rect); - } else if (path.shape() == QVectorPath::EllipseHint - || path.shape() == QVectorPath::ConvexPolygonHint) - { + } else if (path.isConvex()) { vertexCoordinateArray.clear(); vertexCoordinateArray.addPath(path, inverseScale, false); prepareForDraw(currentBrush->isOpaque()); diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp index ec05020..ad18a51 100644 --- a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp +++ b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp @@ -131,8 +131,8 @@ void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen) if (m_roundness > 24) m_roundness = 24; - m_sin_theta = qSin(Q_PI / m_roundness); // ### Use qFastSin - m_cos_theta = qCos(Q_PI / m_roundness); + m_sin_theta = qFastSin(Q_PI / m_roundness); + m_cos_theta = qFastCos(Q_PI / m_roundness); const qreal *endPts = pts + (count<<1); const qreal *startPts; diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h b/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h index 483cea9..97eabef 100644 --- a/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h +++ b/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h @@ -125,7 +125,16 @@ inline void QTriangulatingStroker::normalVector(float x1, float y1, float x2, fl { float dx = x2 - x1; float dy = y2 - y1; - float pw = m_width / sqrt(dx*dx + dy*dy); + + float pw; + + if (dx == 0) + pw = m_width / dy; + else if (dy == 0) + pw = m_width / dx; + else + pw = m_width / sqrt(dx*dx + dy*dy); + *nx = -dy * pw; *ny = dx * pw; } diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 6720ae7..e80521b 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2156,6 +2156,11 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G time.start(); #endif +#ifndef QT_NO_DEBUG + // Reset the gl error stack...git + while (glGetError() != GL_NO_ERROR); +#endif + // Scale the pixmap if needed. GL textures needs to have the // dimensions 2^n+2(border) x 2^m+2(border), unless we're using GL // 2.0 or use the GL_TEXTURE_RECTANGLE texture target diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 3894ed1..7180682 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -589,7 +589,6 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, cons GLuint textureId; glGenTextures(1, &textureId); - glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, textureId); // bind the egl pixmap surface to a texture diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp index 0603369..2af69e0 100644 --- a/src/opengl/qglpixmapfilter.cpp +++ b/src/opengl/qglpixmapfilter.cpp @@ -104,7 +104,7 @@ public: void setUniforms(QGLShaderProgram *program); - static QByteArray generateGaussianShader(int radius, bool dropShadow = false); + static QByteArray generateGaussianShader(int radius, bool singlePass = false, bool dropShadow = false); protected: bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const; @@ -113,6 +113,7 @@ private: mutable QSize m_textureSize; mutable bool m_horizontalBlur; + mutable bool m_singlePass; mutable bool m_haveCached; mutable int m_cachedRadius; @@ -132,6 +133,7 @@ protected: private: mutable QSize m_textureSize; mutable bool m_horizontalBlur; + mutable bool m_singlePass; mutable bool m_haveCached; mutable int m_cachedRadius; @@ -298,123 +300,147 @@ bool QGLPixmapConvolutionFilter::processGL(QPainter *painter, const QPointF &pos return true; } -static const char *qt_gl_blur_filter_fast = - "const int samples = 9;" - "uniform mediump vec2 delta;" - "lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords) {" - " mediump vec4 color = vec4(0.0, 0.0, 0.0, 0.0);" - " mediump float offset = (float(samples) - 1.0) / 2.0;" - " for (int i = 0; i < samples; i++) {" - " mediump vec2 coord = srcCoords + delta * (offset - float(i)) / offset;" - " color += texture2D(src, coord);" - " }" - " return color * (1.0 / float(samples));" - "}"; - -static const char *qt_gl_drop_shadow_filter_fast = - "const int samples = 9;" - "uniform mediump vec2 delta;" - "uniform mediump vec4 shadowColor;" - "lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords) {" - " mediump vec4 color = vec4(0.0, 0.0, 0.0, 0.0);" - " mediump float offset = (float(samples) - 1.0) / 2.0;" - " for (int i = 0; i < samples; i++) {" - " mediump vec2 coord = srcCoords + delta * (offset - float(i)) / offset;" - " color += texture2D(src, coord).a * shadowColor;" - " }" - " return color * (1.0 / float(samples));" - "}"; +static const char *qt_gl_texture_sampling_helper = + "lowp float texture2DAlpha(lowp sampler2D src, highp vec2 srcCoords) {\n" + " return texture2D(src, srcCoords).a;\n" + "}\n"; + +static const char *qt_gl_clamped_texture_sampling_helper = + "highp vec4 texture_dimensions;\n" // x = width, y = height, z = 0.5/width, w = 0.5/height + "lowp float clampedTexture2DAlpha(lowp sampler2D src, highp vec2 srcCoords) {\n" + " highp vec2 clampedCoords = clamp(srcCoords, texture_dimensions.zw, vec2(1.0) - texture_dimensions.zw);\n" + " highp vec2 t = clamp(min(srcCoords, vec2(1.0) - srcCoords) * srcDim + 0.5, 0.0, 1.0);\n" + " return texture2D(src, clampedCoords).a * t.x * t.y;\n" + "}\n" + "lowp vec4 clampedTexture2D(lowp sampler2D src, highp vec2 srcCoords) {\n" + " highp vec2 clampedCoords = clamp(srcCoords, texture_dimensions.zw, vec2(1.0) - texture_dimensions.zw);\n" + " highp vec2 t = clamp(min(srcCoords, vec2(1.0) - srcCoords) * srcDim + 0.5, 0.0, 1.0);\n" + " return texture2D(src, clampedCoords) * t.x * t.y;\n" + "}\n"; + +static QByteArray qt_gl_convertToClamped(const QByteArray &source) +{ + QByteArray result; + result.append(qt_gl_clamped_texture_sampling_helper); + result.append(QByteArray(source).replace("texture2DAlpha", "clampedTexture2DAlpha") + .replace("texture2D", "clampedTexture2D")); + return result; +} QGLPixmapBlurFilter::QGLPixmapBlurFilter(Qt::RenderHint hint) : m_haveCached(false) - , m_cachedRadius(5) + , m_cachedRadius(0) , m_hint(hint) { - if (hint == Qt::PerformanceHint) { - QGLPixmapBlurFilter *filter = const_cast<QGLPixmapBlurFilter *>(this); - filter->setSource(qt_gl_blur_filter_fast); - m_haveCached = true; - } } bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &) const { QGLPixmapBlurFilter *filter = const_cast<QGLPixmapBlurFilter *>(this); - int radius = this->radius(); - if (!m_haveCached || (m_hint == Qt::QualityHint && radius != m_cachedRadius)) { - // Only regenerate the shader from source if parameters have changed. - m_haveCached = true; - m_cachedRadius = radius; - filter->setSource(generateGaussianShader(radius)); + int actualRadius = qRound(radius()); + int filterRadius = actualRadius; + int fastRadii[] = { 1, 2, 3, 5, 8, 15, 25 }; + if (m_hint == Qt::PerformanceHint) { + uint i = 0; + for (; i < (sizeof(fastRadii)/sizeof(*fastRadii))-1; ++i) { + if (fastRadii[i+1] > filterRadius) + break; + } + filterRadius = fastRadii[i]; } - QGLFramebufferObjectFormat format; - format.setInternalTextureFormat(GLenum(src.hasAlphaChannel() ? GL_RGBA : GL_RGB)); - QGLFramebufferObject *fbo = qgl_fbo_pool()->acquire(src.size(), format); + m_singlePass = filterRadius <= 3; - if (!fbo) - return false; - - glBindTexture(GL_TEXTURE_2D, fbo->texture()); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glBindTexture(GL_TEXTURE_2D, 0); + if (!m_haveCached || filterRadius != m_cachedRadius) { + // Only regenerate the shader from source if parameters have changed. + m_haveCached = true; + m_cachedRadius = filterRadius; + QByteArray source = generateGaussianShader(filterRadius, m_singlePass); + filter->setSource(source); + } - // prepare for updateUniforms - m_textureSize = src.size(); + QRect targetRect = QRectF(src.rect()).translated(pos).adjusted(-actualRadius, -actualRadius, actualRadius, actualRadius).toAlignedRect(); - // horizontal pass, to pixmap - m_horizontalBlur = true; + if (m_singlePass) { + // prepare for updateUniforms + m_textureSize = src.size(); - QPainter fboPainter(fbo); + // ensure GL_LINEAR filtering is used + painter->setRenderHint(QPainter::SmoothPixmapTransform); + filter->setOnPainter(painter); + QBrush pixmapBrush = src; + pixmapBrush.setTransform(QTransform::fromTranslate(pos.x(), pos.y())); + painter->fillRect(targetRect, pixmapBrush); + filter->removeFromPainter(painter); + } else { + QGLFramebufferObjectFormat format; + format.setInternalTextureFormat(GLenum(src.hasAlphaChannel() ? GL_RGBA : GL_RGB)); + QGLFramebufferObject *fbo = qgl_fbo_pool()->acquire(targetRect.size(), format); - if (src.hasAlphaChannel()) { - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); - } + if (!fbo) + return false; - // ensure GL_LINEAR filtering is used - fboPainter.setRenderHint(QPainter::SmoothPixmapTransform); - filter->setOnPainter(&fboPainter); - fboPainter.drawPixmap(0, 0, src); - filter->removeFromPainter(&fboPainter); - fboPainter.end(); + // prepare for updateUniforms + m_textureSize = src.size(); - QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(painter->paintEngine()); + // horizontal pass, to pixmap + m_horizontalBlur = true; - // vertical pass, to painter - m_horizontalBlur = false; + QPainter fboPainter(fbo); - painter->save(); - // ensure GL_LINEAR filtering is used - painter->setRenderHint(QPainter::SmoothPixmapTransform); - filter->setOnPainter(painter); - engine->drawTexture(src.rect().translated(pos.x(), pos.y()), fbo->texture(), fbo->size(), src.rect().translated(0, fbo->height() - src.height())); - filter->removeFromPainter(painter); - painter->restore(); + if (src.hasAlphaChannel()) { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + } - qgl_fbo_pool()->release(fbo); + // ensure GL_LINEAR filtering is used + fboPainter.setRenderHint(QPainter::SmoothPixmapTransform); + filter->setOnPainter(&fboPainter); + QBrush pixmapBrush = src; + pixmapBrush.setTransform(QTransform::fromTranslate(actualRadius, actualRadius)); + fboPainter.fillRect(QRect(0, 0, targetRect.width(), targetRect.height()), pixmapBrush); + filter->removeFromPainter(&fboPainter); + fboPainter.end(); + + QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(painter->paintEngine()); + + // vertical pass, to painter + m_horizontalBlur = false; + m_textureSize = fbo->size(); + + painter->save(); + // ensure GL_LINEAR filtering is used + painter->setRenderHint(QPainter::SmoothPixmapTransform); + filter->setOnPainter(painter); + engine->drawTexture(targetRect, fbo->texture(), fbo->size(), QRect(QPoint(), targetRect.size()).translated(0, fbo->height() - targetRect.height())); + filter->removeFromPainter(painter); + painter->restore(); + + qgl_fbo_pool()->release(fbo); + } return true; } void QGLPixmapBlurFilter::setUniforms(QGLShaderProgram *program) { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + if (m_hint == Qt::QualityHint) { - if (m_horizontalBlur) + if (m_singlePass) + program->setUniformValue("delta", 1.0 / m_textureSize.width(), 1.0 / m_textureSize.height()); + else if (m_horizontalBlur) program->setUniformValue("delta", 1.0 / m_textureSize.width(), 0.0); else program->setUniformValue("delta", 0.0, 1.0 / m_textureSize.height()); } else { - // 1.4 is chosen to most closely match the blurriness of the gaussian blur - // at low radii - qreal blur = radius() / 1.4f; + qreal blur = radius() / qreal(m_cachedRadius); - if (m_horizontalBlur) + if (m_singlePass) + program->setUniformValue("delta", blur / m_textureSize.width(), blur / m_textureSize.height()); + else if (m_horizontalBlur) program->setUniformValue("delta", blur / m_textureSize.width(), 0.0); else program->setUniformValue("delta", 0.0, blur / m_textureSize.height()); @@ -426,12 +452,21 @@ static inline qreal gaussian(qreal dx, qreal sigma) return exp(-dx * dx / (2 * sigma * sigma)) / (Q_2PI * sigma * sigma); } -QByteArray QGLPixmapBlurFilter::generateGaussianShader(int radius, bool dropShadow) +QByteArray QGLPixmapBlurFilter::generateGaussianShader(int radius, bool singlePass, bool dropShadow) { Q_ASSERT(radius >= 1); + radius = qMin(127, radius); + + static QCache<uint, QByteArray> shaderSourceCache; + uint key = radius | (int(singlePass) << 7) | (int(dropShadow) << 8); + QByteArray *cached = shaderSourceCache.object(key); + if (cached) + return *cached; + QByteArray source; source.reserve(1000); + source.append(qt_gl_texture_sampling_helper); source.append("uniform highp vec2 delta;\n"); if (dropShadow) @@ -446,7 +481,7 @@ QByteArray QGLPixmapBlurFilter::generateGaussianShader(int radius, bool dropShad qreal sigma = radius / 1.65; qreal sum = 0; - for (int i = -radius; i <= radius; ++i) { + for (int i = -radius; i < radius; ++i) { float value = gaussian(i, sigma); gaussianComponents << value; sum += value; @@ -464,43 +499,67 @@ QByteArray QGLPixmapBlurFilter::generateGaussianShader(int radius, bool dropShad weights << weight; } - // odd size ? - if (gaussianComponents.size() & 1) { - sampleOffsets << radius; - weights << gaussianComponents.last(); - } - - int currentVariable = 1; - source.append(" mediump vec4 sample = vec4(0.0);\n"); - source.append(" mediump vec2 coord;\n"); - - qreal weightSum = 0; - source.append(" mediump float c;\n"); - for (int i = 0; i < sampleOffsets.size(); ++i) { - qreal delta = sampleOffsets.at(i); - - ++currentVariable; + int limit = sampleOffsets.size(); + if (singlePass) + limit *= limit; + + QByteArray baseCoordinate = "srcCoords"; + + for (int i = 0; i < limit; ++i) { + QByteArray coordinate = baseCoordinate; + + qreal weight; + if (singlePass) { + const int xIndex = i % sampleOffsets.size(); + const int yIndex = i / sampleOffsets.size(); + + const qreal deltaX = sampleOffsets.at(xIndex); + const qreal deltaY = sampleOffsets.at(yIndex); + weight = weights.at(xIndex) * weights.at(yIndex); + + if (!qFuzzyCompare(deltaX, deltaY)) { + coordinate.append(" + vec2(delta.x * float("); + coordinate.append(QByteArray::number(deltaX)); + coordinate.append("), delta.y * float("); + coordinate.append(QByteArray::number(deltaY)); + coordinate.append("))"); + } else if (!qFuzzyIsNull(deltaX)) { + coordinate.append(" + delta * float("); + coordinate.append(QByteArray::number(deltaX)); + coordinate.append(")"); + } + } else { + const qreal delta = sampleOffsets.at(i); + weight = weights.at(i); + if (!qFuzzyIsNull(delta)) { + coordinate.append(" + delta * float("); + coordinate.append(QByteArray::number(delta)); + coordinate.append(")"); + } + } - QByteArray coordinate = "srcCoords"; - if (delta != qreal(0)) { - coordinate.append(" + delta * float("); - coordinate.append(QByteArray::number(delta)); - coordinate.append(")"); + if (i == 0) { + if (dropShadow) + source.append(" mediump float sample = "); + else + source.append(" mediump vec4 sample = "); + } else { + if (dropShadow) + source.append(" sample += "); + else + source.append(" sample += "); } - source.append(" coord = "); + source.append("texture2D(src, "); source.append(coordinate); - source.append(";\n"); + source.append(")"); if (dropShadow) - source.append(" sample += texture2D(src, coord).a * shadowColor"); - else - source.append(" sample += texture2D(src, coord)"); + source.append(".a"); - weightSum += weights.at(i); - if (weights.at(i) != qreal(1)) { + if (!qFuzzyCompare(weight, qreal(1))) { source.append(" * float("); - source.append(QByteArray::number(weights.at(i))); + source.append(QByteArray::number(weight)); source.append(");\n"); } else { source.append(";\n"); @@ -508,87 +567,102 @@ QByteArray QGLPixmapBlurFilter::generateGaussianShader(int radius, bool dropShad } source.append(" return "); + if (dropShadow) + source.append("shadowColor * "); source.append("sample;\n"); source.append("}\n"); + cached = new QByteArray(source); + shaderSourceCache.insert(key, cached); + return source; } QGLPixmapDropShadowFilter::QGLPixmapDropShadowFilter(Qt::RenderHint hint) : m_haveCached(false) - , m_cachedRadius(5) + , m_cachedRadius(0) , m_hint(hint) { - if (hint == Qt::PerformanceHint) { - QGLPixmapDropShadowFilter *filter = const_cast<QGLPixmapDropShadowFilter *>(this); - filter->setSource(qt_gl_drop_shadow_filter_fast); - m_haveCached = true; - } } bool QGLPixmapDropShadowFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const { QGLPixmapDropShadowFilter *filter = const_cast<QGLPixmapDropShadowFilter *>(this); - int radius = this->blurRadius(); - if (!m_haveCached || (m_hint == Qt::QualityHint && radius != m_cachedRadius)) { + int actualRadius = qRound(blurRadius()); + int filterRadius = actualRadius; + m_singlePass = filterRadius <= 3; + + if (!m_haveCached || filterRadius != m_cachedRadius) { // Only regenerate the shader from source if parameters have changed. m_haveCached = true; - m_cachedRadius = radius; - filter->setSource(QGLPixmapBlurFilter::generateGaussianShader(radius, true)); + m_cachedRadius = filterRadius; + QByteArray source = QGLPixmapBlurFilter::generateGaussianShader(filterRadius, m_singlePass, true); + filter->setSource(source); } - QGLFramebufferObjectFormat format; - format.setInternalTextureFormat(GLenum(src.hasAlphaChannel() ? GL_RGBA : GL_RGB)); - QGLFramebufferObject *fbo = qgl_fbo_pool()->acquire(src.size(), format); + QRect targetRect = QRectF(src.rect()).translated(pos + offset()).adjusted(-actualRadius, -actualRadius, actualRadius, actualRadius).toAlignedRect(); + + if (m_singlePass) { + // prepare for updateUniforms + m_textureSize = src.size(); + + painter->save(); + // ensure GL_LINEAR filtering is used + painter->setRenderHint(QPainter::SmoothPixmapTransform); + filter->setOnPainter(painter); + QBrush pixmapBrush = src; + pixmapBrush.setTransform(QTransform::fromTranslate(pos.x() + offset().x(), pos.y() + offset().y())); + painter->fillRect(targetRect, pixmapBrush); + filter->removeFromPainter(painter); + painter->restore(); + } else { + QGLFramebufferObjectFormat format; + format.setInternalTextureFormat(GLenum(src.hasAlphaChannel() ? GL_RGBA : GL_RGB)); + QGLFramebufferObject *fbo = qgl_fbo_pool()->acquire(targetRect.size(), format); - if (!fbo) - return false; + if (!fbo) + return false; - glBindTexture(GL_TEXTURE_2D, fbo->texture()); + // prepare for updateUniforms + m_textureSize = src.size(); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glBindTexture(GL_TEXTURE_2D, 0); + // horizontal pass, to pixmap + m_horizontalBlur = true; - // prepare for updateUniforms - m_textureSize = src.size(); + QPainter fboPainter(fbo); - // horizontal pass, to pixmap - m_horizontalBlur = true; - - QPainter fboPainter(fbo); + if (src.hasAlphaChannel()) { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + } - if (src.hasAlphaChannel()) { - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); + // ensure GL_LINEAR filtering is used + fboPainter.setRenderHint(QPainter::SmoothPixmapTransform); + filter->setOnPainter(&fboPainter); + QBrush pixmapBrush = src; + pixmapBrush.setTransform(QTransform::fromTranslate(actualRadius, actualRadius)); + fboPainter.fillRect(QRect(0, 0, targetRect.width(), targetRect.height()), pixmapBrush); + filter->removeFromPainter(&fboPainter); + fboPainter.end(); + + QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(painter->paintEngine()); + + // vertical pass, to painter + m_horizontalBlur = false; + m_textureSize = fbo->size(); + + painter->save(); + // ensure GL_LINEAR filtering is used + painter->setRenderHint(QPainter::SmoothPixmapTransform); + filter->setOnPainter(painter); + engine->drawTexture(targetRect, fbo->texture(), fbo->size(), src.rect().translated(0, fbo->height() - src.height())); + filter->removeFromPainter(painter); + painter->restore(); + + qgl_fbo_pool()->release(fbo); } - // ensure GL_LINEAR filtering is used - fboPainter.setRenderHint(QPainter::SmoothPixmapTransform); - filter->setOnPainter(&fboPainter); - fboPainter.drawPixmap(0, 0, src); - filter->removeFromPainter(&fboPainter); - fboPainter.end(); - - QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(painter->paintEngine()); - - // vertical pass, to painter - m_horizontalBlur = false; - - painter->save(); - // ensure GL_LINEAR filtering is used - painter->setRenderHint(QPainter::SmoothPixmapTransform); - filter->setOnPainter(painter); - QPointF ofs = offset(); - engine->drawTexture(src.rect().translated(pos.x() + ofs.x(), pos.y() + ofs.y()), fbo->texture(), fbo->size(), src.rect().translated(0, fbo->height() - src.height())); - filter->removeFromPainter(painter); - painter->restore(); - - qgl_fbo_pool()->release(fbo); - // Now draw the actual pixmap over the top. painter->drawPixmap(pos, src, srcRect); @@ -597,8 +671,11 @@ bool QGLPixmapDropShadowFilter::processGL(QPainter *painter, const QPointF &pos, void QGLPixmapDropShadowFilter::setUniforms(QGLShaderProgram *program) { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + QColor col = color(); - if (m_horizontalBlur) { + if (m_horizontalBlur && !m_singlePass) { program->setUniformValue("shadowColor", 1.0f, 1.0f, 1.0f, 1.0f); } else { qreal alpha = col.alphaF(); @@ -607,17 +684,20 @@ void QGLPixmapDropShadowFilter::setUniforms(QGLShaderProgram *program) col.blueF() * alpha, alpha); } + if (m_hint == Qt::QualityHint) { - if (m_horizontalBlur) + if (m_singlePass) + program->setUniformValue("delta", 1.0 / m_textureSize.width(), 1.0 / m_textureSize.height()); + else if (m_horizontalBlur) program->setUniformValue("delta", 1.0 / m_textureSize.width(), 0.0); else program->setUniformValue("delta", 0.0, 1.0 / m_textureSize.height()); } else { - // 1.4 is chosen to most closely match the blurriness of the gaussian blur - // at low radii - qreal blur = blurRadius() / 1.4f; + qreal blur = blurRadius() / qreal(m_cachedRadius); - if (m_horizontalBlur) + if (m_singlePass) + program->setUniformValue("delta", blur / m_textureSize.width(), blur / m_textureSize.height()); + else if (m_horizontalBlur) program->setUniformValue("delta", blur / m_textureSize.width(), 0.0); else program->setUniformValue("delta", 0.0, blur / m_textureSize.height()); diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index 83ebece..c965947 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -76,6 +76,19 @@ static inline int areaDiff(const QSize &size, const QGLFramebufferObject *fbo) return qAbs(size.width() * size.height() - fbo->width() * fbo->height()); } +extern int qt_next_power_of_two(int v); + +static inline QSize maybeRoundToNextPowerOfTwo(const QSize &sz) +{ +#ifdef QT_OPENGL_ES_2 + QSize rounded(qt_next_power_of_two(sz.width()), qt_next_power_of_two(sz.height())); + if (rounded.width() * rounded.height() < 1.20 * sz.width() * sz.height()) + return rounded; +#endif + return sz; +} + + QGLFramebufferObject *QGLFramebufferObjectPool::acquire(const QSize &requestSize, const QGLFramebufferObjectFormat &requestFormat) { QGLFramebufferObject *chosen = 0; @@ -106,7 +119,7 @@ QGLFramebufferObject *QGLFramebufferObjectPool::acquire(const QSize &requestSize if (sz != fboSize) { delete candidate; - candidate = new QGLFramebufferObject(sz, requestFormat); + candidate = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(sz), requestFormat); } chosen = candidate; @@ -114,7 +127,7 @@ QGLFramebufferObject *QGLFramebufferObjectPool::acquire(const QSize &requestSize } if (!chosen) { - chosen = new QGLFramebufferObject(requestSize, requestFormat); + chosen = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(requestSize), requestFormat); } if (!chosen->isValid()) { diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index 94e0793..8a485a0 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -3574,51 +3574,48 @@ void QVGCompositionHelper::fillBackground } } -void QVGCompositionHelper::drawCursorImage - (const QImage& image, const QPoint& offset) +void QVGCompositionHelper::drawCursorPixmap + (const QPixmap& pixmap, const QPoint& offset) { - QImage img = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); + VGImage vgImage = VG_INVALID_HANDLE; - VGImage vgImg = vgCreateImage - (VG_sARGB_8888_PRE, img.width(), img.height(), - VG_IMAGE_QUALITY_FASTER); - vgImageSubData - (vgImg, img.bits() + img.bytesPerLine() * (img.height() - 1), - -(img.bytesPerLine()), VG_sARGB_8888_PRE, 0, 0, - img.width(), img.height()); + // Fetch the VGImage from the pixmap if possible. + QPixmapData *pd = pixmap.pixmapData(); + if (pd->classId() == QPixmapData::OpenVGClass) { + QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd); + if (vgpd->isValid()) + vgImage = vgpd->toVGImage(); + } - QTransform transform; - int y = screenSize.height() - (offset.y() + img.height()); - transform.translate(offset.x() + 0.5f, y + 0.5f); + // Set the image transformation and modes. + VGfloat devh = screenSize.height() - 1; + QTransform transform(1.0f, 0.0f, 0.0f, + 0.0f, -1.0f, 0.0f, + -0.5f, devh + 0.5f, 1.0f); + transform.translate(offset.x(), offset.y()); d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform); - d->setImageMode(VG_DRAW_IMAGE_NORMAL); - vgDrawImage(vgImg); - vgDestroyImage(vgImg); -} + // Draw the VGImage. + if (vgImage != VG_INVALID_HANDLE) { + vgDrawImage(vgImage); + } else { + QImage img = pixmap.toImage().convertToFormat + (QImage::Format_ARGB32_Premultiplied); -void QVGCompositionHelper::drawCursorPixmap - (const QPixmap& pixmap, const QPoint& offset) -{ - QPixmapData *pd = pixmap.pixmapData(); - if (pd->classId() == QPixmapData::OpenVGClass) { - QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd); - if (vgpd->isValid()) { - VGfloat devh = screenSize.height() - 1; - QTransform transform(1.0f, 0.0f, 0.0f, - 0.0f, -1.0f, 0.0f, - -0.5f, devh + 0.5f, 1.0f); - transform.translate(offset.x(), offset.y()); - d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform); - - d->setImageMode(VG_DRAW_IMAGE_NORMAL); - vgDrawImage(vgpd->toVGImage()); + vgImage = vgCreateImage + (VG_sARGB_8888_PRE, img.width(), img.height(), + VG_IMAGE_QUALITY_FASTER); + if (vgImage == VG_INVALID_HANDLE) return; - } - } + vgImageSubData + (vgImage, img.bits() + img.bytesPerLine() * (img.height() - 1), + -(img.bytesPerLine()), VG_sARGB_8888_PRE, 0, 0, + img.width(), img.height()); - drawCursorImage(pixmap.toImage(), offset); + vgDrawImage(vgImage); + vgDestroyImage(vgImage); + } } void QVGCompositionHelper::setScissor(const QRegion& region) diff --git a/src/openvg/qpixmapfilter_vg_p.h b/src/openvg/qpixmapfilter_vg_p.h index efbbc7b..29dd37e 100644 --- a/src/openvg/qpixmapfilter_vg_p.h +++ b/src/openvg/qpixmapfilter_vg_p.h @@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE #if !defined(QT_SHIVAVG) -class Q_OPENVG_EXPORT QVGPixmapConvolutionFilter : public QPixmapConvolutionFilter +class QVGPixmapConvolutionFilter : public QPixmapConvolutionFilter { Q_OBJECT public: @@ -71,7 +71,7 @@ public: void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const; }; -class Q_OPENVG_EXPORT QVGPixmapColorizeFilter : public QPixmapColorizeFilter +class QVGPixmapColorizeFilter : public QPixmapColorizeFilter { Q_OBJECT public: @@ -81,7 +81,7 @@ public: void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const; }; -class Q_OPENVG_EXPORT QVGPixmapDropShadowFilter : public QPixmapDropShadowFilter +class QVGPixmapDropShadowFilter : public QPixmapDropShadowFilter { Q_OBJECT public: @@ -91,7 +91,7 @@ public: void draw(QPainter *p, const QPointF &pos, const QPixmap &px, const QRectF &src) const; }; -class Q_OPENVG_EXPORT QVGPixmapBlurFilter : public QPixmapBlurFilter +class QVGPixmapBlurFilter : public QPixmapBlurFilter { Q_OBJECT public: diff --git a/src/openvg/qvgcompositionhelper_p.h b/src/openvg/qvgcompositionhelper_p.h index 6317c3f..3afe31e 100644 --- a/src/openvg/qvgcompositionhelper_p.h +++ b/src/openvg/qvgcompositionhelper_p.h @@ -74,7 +74,6 @@ public: void blitWindow(QVGEGLWindowSurfacePrivate *surface, const QRect& rect, const QPoint& topLeft, int opacity); void fillBackground(const QRegion& region, const QBrush& brush); - void drawCursorImage(const QImage& image, const QPoint& offset); void drawCursorPixmap(const QPixmap& pixmap, const QPoint& offset); void setScissor(const QRegion& region); void clearScissor(); diff --git a/src/openvg/qwindowsurface_vgegl.cpp b/src/openvg/qwindowsurface_vgegl.cpp index 103f84d..29d82c8 100644 --- a/src/openvg/qwindowsurface_vgegl.cpp +++ b/src/openvg/qwindowsurface_vgegl.cpp @@ -193,6 +193,13 @@ static QEglContext *createContext(QPaintDevice *device) return 0; } + // Set the swap interval for the display. + QByteArray interval = qgetenv("QT_VG_SWAP_INTERVAL"); + if (!interval.isEmpty()) + eglSwapInterval(context->display(), interval.toInt()); + else + eglSwapInterval(context->display(), 1); + // Choose an appropriate configuration for rendering into the device. QEglProperties configProps; configProps.setPaintDeviceFormat(device); diff --git a/src/plugins/s60/src/qlocale_3_1.cpp b/src/plugins/s60/src/qlocale_3_1.cpp index 0afd10a..beeee7f 100644 --- a/src/plugins/s60/src/qlocale_3_1.cpp +++ b/src/plugins/s60/src/qlocale_3_1.cpp @@ -40,23 +40,109 @@ ****************************************************************************/ #include <e32std.h> +#include <e32const.h> +#include <e32debug.h> -EXPORT_C void defaultFormatL(TTime&, TDes& des, const TDesC&, const TLocale&) +_LIT(KYear, "%Y"); +_LIT(KMonth, "%M"); +_LIT(KDay, "%D"); +_LIT(KLocaleIndependent, "%F"); +static TBuf<10> dateFormat; +static TBuf<10> timeFormat; + +static void initialiseDateFormat() +{ + if(dateFormat.Length()) + return; + + TLocale locale; + + //Separator 1 is used between 1st and 2nd components of the date + //Separator 2 is used between 2nd and 3rd components of the date + //Usually they are the same, but they are allowed to be different + TChar s1 = locale.DateSeparator(1); + TChar s2 = locale.DateSeparator(2); + dateFormat=KLocaleIndependent; + switch(locale.DateFormat()) { + case EDateAmerican: + dateFormat.Append(KMonth); + dateFormat.Append(s1); + dateFormat.Append(KDay); + dateFormat.Append(s2); + dateFormat.Append(KYear); + break; + case EDateEuropean: + dateFormat.Append(KDay); + dateFormat.Append(s1); + dateFormat.Append(KMonth); + dateFormat.Append(s2); + dateFormat.Append(KYear); + break; + case EDateJapanese: + default: //it's closest to ISO format + dateFormat.Append(KYear); + dateFormat.Append(s1); + dateFormat.Append(KMonth); + dateFormat.Append(s2); + dateFormat.Append(KDay); + break; + } +#ifdef _DEBUG + RDebug::Print(_L("Date Format \"%S\""), &dateFormat); +#endif +} + +static void initialiseTimeFormat() +{ + if(timeFormat.Length()) + return; + + TLocale locale; + //Separator 1 is used between 1st and 2nd components of the time + //Separator 2 is used between 2nd and 3rd components of the time + //Usually they are the same, but they are allowed to be different + TChar s1 = locale.TimeSeparator(1); + TChar s2 = locale.TimeSeparator(2); + switch(locale.TimeFormat()) { + case ETime12: + timeFormat.Append(_L("%I")); + break; + case ETime24: + default: + timeFormat.Append(_L("%H")); + break; + } + timeFormat.Append(s1); + timeFormat.Append(_L("%T")); + timeFormat.Append(s2); + timeFormat.Append(_L("%S")); + +#ifdef _DEBUG + RDebug::Print(_L("Time Format \"%S\""), &timeFormat); +#endif +} + +EXPORT_C void defaultFormatL(TTime& time, TDes& des, const TDesC& fmt, const TLocale&) { - des.Zero(); + //S60 3.1 does not support format for a specific locale, so use default locale + time.FormatL(des, fmt); } +//S60 3.1 doesn't support extended locale date&time formats, so use default locale EXPORT_C TPtrC defaultGetTimeFormatSpec(TExtendedLocale&) { - return TPtrC(KNullDesC); + initialiseTimeFormat(); + return TPtrC(timeFormat); } EXPORT_C TPtrC defaultGetLongDateFormatSpec(TExtendedLocale&) { - return TPtrC(KNullDesC); + initialiseDateFormat(); + return TPtrC(dateFormat); } EXPORT_C TPtrC defaultGetShortDateFormatSpec(TExtendedLocale&) { - return TPtrC(KNullDesC); + initialiseDateFormat(); + return TPtrC(dateFormat); } diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index 4305346..56ba18f 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -5488,7 +5488,7 @@ EXPORTS ?currentIndex@QDataWidgetMapper@@QBEHXZ @ 5487 NONAME ; int QDataWidgetMapper::currentIndex(void) const ?setFont@QApplication@@SAXABVQFont@@PBD@Z @ 5488 NONAME ; void QApplication::setFont(class QFont const &, char const *) ?resized@QDesktopWidget@@IAEXH@Z @ 5489 NONAME ; void QDesktopWidget::resized(int) - ?fontEngine@QTextEngine@@QBEPAVQFontEngine@@ABUQScriptItem@@PAUQFixed@@1@Z @ 5490 NONAME ; class QFontEngine * QTextEngine::fontEngine(struct QScriptItem const &, struct QFixed *, struct QFixed *) const + ?fontEngine@QTextEngine@@QBEPAVQFontEngine@@ABUQScriptItem@@PAUQFixed@@1@Z @ 5490 NONAME ABSENT ; class QFontEngine * QTextEngine::fontEngine(struct QScriptItem const &, struct QFixed *, struct QFixed *) const ??BQVector2D@@QBE?AVQVariant@@XZ @ 5491 NONAME ; QVector2D::operator class QVariant(void) const ?qt_metacall@QTreeWidget@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 5492 NONAME ; int QTreeWidget::qt_metacall(enum QMetaObject::Call, int, void * *) ?setSelectable@QStandardItem@@QAEX_N@Z @ 5493 NONAME ; void QStandardItem::setSelectable(bool) @@ -12542,4 +12542,10 @@ EXPORTS ??0QSplitter@@QAE@PAVQWidget@@@Z @ 12541 NONAME ; QSplitter::QSplitter(class QWidget *) ?DocumentLengthForFep@QCoeFepInputContext@@UBEHXZ @ 12542 NONAME ; int QCoeFepInputContext::DocumentLengthForFep(void) const ??0QShowEvent@@QAE@XZ @ 12543 NONAME ; QShowEvent::QShowEvent(void) + ?fontEngine@QTextEngine@@QBEPAVQFontEngine@@ABUQScriptItem@@PAUQFixed@@11@Z @ 12544 NONAME ; class QFontEngine * QTextEngine::fontEngine(struct QScriptItem const &, struct QFixed *, struct QFixed *, struct QFixed *) const + ?leading@QTextLine@@QBEMXZ @ 12545 NONAME ; float QTextLine::leading(void) const + ?leadingIncluded@QTextLine@@QBE_NXZ @ 12546 NONAME ; bool QTextLine::leadingIncluded(void) const + ?projectedRotate@QMatrix4x4@@AAEAAV1@MMMM@Z @ 12547 NONAME ; class QMatrix4x4 & QMatrix4x4::projectedRotate(float, float, float, float) + ?setLeadingIncluded@QTextLine@@QAEX_N@Z @ 12548 NONAME ; void QTextLine::setLeadingIncluded(bool) + ?toTransform@QMatrix4x4@@QBE?AVQTransform@@XZ @ 12549 NONAME ; class QTransform QMatrix4x4::toTransform(void) const diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index ae69475..2d1c42f 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -1051,12 +1051,12 @@ EXPORTS _ZN11QPaintEventD2Ev @ 1050 NONAME _ZN11QPanGesture11qt_metacallEN11QMetaObject4CallEiPPv @ 1051 NONAME _ZN11QPanGesture11qt_metacastEPKc @ 1052 NONAME - _ZN11QPanGesture13setLastOffsetERK6QSizeF @ 1053 NONAME - _ZN11QPanGesture14setTotalOffsetERK6QSizeF @ 1054 NONAME + _ZN11QPanGesture13setLastOffsetERK6QSizeF @ 1053 NONAME ABSENT + _ZN11QPanGesture14setTotalOffsetERK6QSizeF @ 1054 NONAME ABSENT _ZN11QPanGesture15setAccelerationEf @ 1055 NONAME _ZN11QPanGesture16staticMetaObjectE @ 1056 NONAME DATA 16 _ZN11QPanGesture19getStaticMetaObjectEv @ 1057 NONAME - _ZN11QPanGesture9setOffsetERK6QSizeF @ 1058 NONAME + _ZN11QPanGesture9setOffsetERK6QSizeF @ 1058 NONAME ABSENT _ZN11QPanGestureC1EP7QObject @ 1059 NONAME _ZN11QPanGestureC2EP7QObject @ 1060 NONAME _ZN11QPixmapData12toNativeTypeENS_10NativeTypeE @ 1061 NONAME @@ -6366,7 +6366,7 @@ EXPORTS _ZN8QGesture11qt_metacallEN11QMetaObject4CallEiPPv @ 6365 NONAME _ZN8QGesture11qt_metacastEPKc @ 6366 NONAME _ZN8QGesture12unsetHotSpotEv @ 6367 NONAME - _ZN8QGesture15setTargetObjectEP7QObject @ 6368 NONAME + _ZN8QGesture15setTargetObjectEP7QObject @ 6368 NONAME ABSENT _ZN8QGesture16staticMetaObjectE @ 6369 NONAME DATA 16 _ZN8QGesture19getStaticMetaObjectEv @ 6370 NONAME _ZN8QGestureC1EN2Qt11GestureTypeEP7QObject @ 6371 NONAME ABSENT @@ -7888,7 +7888,7 @@ EXPORTS _ZNK11QTextCursorneERKS_ @ 7887 NONAME _ZNK11QTextEngine10attributesEv @ 7888 NONAME _ZNK11QTextEngine10elidedTextEN2Qt13TextElideModeERK6QFixedi @ 7889 NONAME - _ZNK11QTextEngine10fontEngineERK11QScriptItemP6QFixedS4_ @ 7890 NONAME + _ZNK11QTextEngine10fontEngineERK11QScriptItemP6QFixedS4_ @ 7890 NONAME ABSENT _ZNK11QTextEngine11boundingBoxEii @ 7891 NONAME _ZNK11QTextEngine11formatIndexEPK11QScriptItem @ 7892 NONAME _ZNK11QTextEngine11setBoundaryEi @ 7893 NONAME @@ -10163,7 +10163,7 @@ EXPORTS _ZNK8QGesture10hasHotSpotEv @ 10162 NONAME _ZNK8QGesture10metaObjectEv @ 10163 NONAME _ZNK8QGesture11gestureTypeEv @ 10164 NONAME - _ZNK8QGesture12targetObjectEv @ 10165 NONAME + _ZNK8QGesture12targetObjectEv @ 10165 NONAME ABSENT _ZNK8QGesture5stateEv @ 10166 NONAME _ZNK8QGesture7hotSpotEv @ 10167 NONAME _ZNK8QMdiArea10backgroundEv @ 10168 NONAME @@ -11615,4 +11615,24 @@ EXPORTS _Zls6QDebugRKN12QStyleOption10OptionTypeE @ 11614 NONAME _ZNK14QDesktopWidget14screenGeometryEPK7QWidget @ 11615 NONAME _ZNK14QDesktopWidget17availableGeometryEPK7QWidget @ 11616 NONAME + _ZN11QPanGesture13setLastOffsetERK7QPointF @ 11617 NONAME + _ZN11QPanGesture14setTotalOffsetERK7QPointF @ 11618 NONAME + _ZN11QPanGesture9setOffsetERK7QPointF @ 11619 NONAME + _ZN13QGestureEvent6d_funcEv @ 11620 NONAME + _ZN13QGestureEvent9setWidgetEP7QWidget @ 11621 NONAME + _ZN13QGestureEventD0Ev @ 11622 NONAME + _ZN13QGestureEventD1Ev @ 11623 NONAME + _ZN13QGestureEventD2Ev @ 11624 NONAME + _ZN14QWidgetPrivate36invalidateGraphicsEffectsRecursivelyEv @ 11625 NONAME + _ZN20QGraphicsItemPrivate36invalidateGraphicsEffectsRecursivelyEv @ 11626 NONAME + _ZNK13QGestureEvent10mapToSceneERK7QPointF @ 11627 NONAME + _ZNK13QGestureEvent6d_funcEv @ 11628 NONAME + _ZNK13QGestureEvent6widgetEv @ 11629 NONAME + _Zls6QDebugP15QGraphicsObject @ 11630 NONAME + _ZN10QMatrix4x415projectedRotateEffff @ 11631 NONAME + _ZN9QTextLine18setLeadingIncludedEb @ 11632 NONAME + _ZNK10QMatrix4x411toTransformEv @ 11633 NONAME + _ZNK11QTextEngine10fontEngineERK11QScriptItemP6QFixedS4_S4_ @ 11634 NONAME + _ZNK9QTextLine15leadingIncludedEv @ 11635 NONAME + _ZNK9QTextLine7leadingEv @ 11636 NONAME diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index 7233e8a..022a072 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -35,8 +35,8 @@ symbian: { qtlibraries.pkg_postrules += qts60plugindeployment sqlitedeployment = \ - "; EXISTS statement does not resolve !. Lets check the most common drives" \ - "IF NOT EXISTS(\"c:\\sys\\bin\\sqlite3.dll\") AND NOT EXISTS(\"e:\\sys\\bin\\sqlite3.dll\") AND NOT EXISTS(\"z:\\sys\\bin\\sqlite3.dll\")" \ + "; Deploy sqlite onto phone that does not have it (this should be replaced with embedded sis file when available)" \ + "IF NOT package(0x2002533b) " \ "\"$${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET)/sqlite3.dll\" - \"!:\\sys\\bin\\sqlite3.dll\"" \ "ENDIF" qtlibraries.pkg_postrules += sqlitedeployment @@ -97,6 +97,10 @@ symbian: { qtlibraries.sources += QtScript.dll } + contains(QT_CONFIG, xmlpatterns): { + qtlibraries.sources += QtXmlPatterns.dll + } + contains(QT_CONFIG, webkit): { qtlibraries.sources += QtWebKit.dll } diff --git a/src/xmlpatterns/api/qxmlquery.h b/src/xmlpatterns/api/qxmlquery.h index abfddc0..37e4fe1 100644 --- a/src/xmlpatterns/api/qxmlquery.h +++ b/src/xmlpatterns/api/qxmlquery.h @@ -74,7 +74,7 @@ namespace QPatternist class XsdSchemaParser; class XsdValidatingInstanceReader; class VariableLoader; -}; +} class Q_XMLPATTERNS_EXPORT QXmlQuery { diff --git a/src/xmlpatterns/schema/qxsdstatemachine.cpp b/src/xmlpatterns/schema/qxsdstatemachine.cpp index 85bc752..8a43411 100644 --- a/src/xmlpatterns/schema/qxsdstatemachine.cpp +++ b/src/xmlpatterns/schema/qxsdstatemachine.cpp @@ -335,64 +335,6 @@ typename XsdStateMachine<TransitionType>::StateId XsdStateMachine<TransitionType return dfaState; } - -template <typename TransitionType> -QSet<typename XsdStateMachine<TransitionType>::StateId> XsdStateMachine<TransitionType>::epsilonClosure(const QSet<StateId> &input) const -{ - // every state can reach itself by epsilon transition, so include the input states - // in the result as well - QSet<StateId> result = input; - - // add the input states to the list of to be processed states - QList<StateId> workStates = input.toList(); - while (!workStates.isEmpty()) { // while there are states to be processed left... - - // dequeue one state from list - const StateId state = workStates.takeFirst(); - - // get the list of states that can be reached by the epsilon transition - // from the current 'state' - const QVector<StateId> targetStates = m_epsilonTransitions.value(state); - for (int i = 0; i < targetStates.count(); ++i) { - // if we have this target state not in our result set yet... - if (!result.contains(targetStates.at(i))) { - // ... add it to the result set - result.insert(targetStates.at(i)); - - // add the target state to the list of to be processed states as well, - // as we want to have the epsilon transitions not only for the first - // level of following states - workStates.append(targetStates.at(i)); - } - } - } - - return result; -} - -template <typename TransitionType> -QSet<typename XsdStateMachine<TransitionType>::StateId> XsdStateMachine<TransitionType>::move(const QSet<StateId> &states, TransitionType input) const -{ - QSet<StateId> result; - - QSetIterator<StateId> it(states); - while (it.hasNext()) { // iterate over all given states - const StateId state = it.next(); - - // get the transition table for the current state - const QHash<TransitionType, QVector<StateId> > transitions = m_transitions.value(state); - - // get the target states for the given input - const QVector<StateId> targetStates = transitions.value(input); - - // add all target states to the result - for (int i = 0; i < targetStates.size(); ++i) - result.insert(targetStates.at(i)); - } - - return result; -} - template <typename TransitionType> XsdStateMachine<TransitionType> XsdStateMachine<TransitionType>::toDFA() const { @@ -469,9 +411,3 @@ QHash<typename XsdStateMachine<TransitionType>::StateId, typename XsdStateMachin { return m_states; } - -template <typename TransitionType> -QHash<typename XsdStateMachine<TransitionType>::StateId, QHash<TransitionType, QVector<typename XsdStateMachine<TransitionType>::StateId> > > XsdStateMachine<TransitionType>::transitions() const -{ - return m_transitions; -} diff --git a/src/xmlpatterns/schema/qxsdstatemachine_p.h b/src/xmlpatterns/schema/qxsdstatemachine_p.h index e671499..294eb50 100644 --- a/src/xmlpatterns/schema/qxsdstatemachine_p.h +++ b/src/xmlpatterns/schema/qxsdstatemachine_p.h @@ -204,8 +204,14 @@ namespace QPatternist /** * Returns the information of all transitions of the state machine. + * + * The implementation is inlined in order to workaround a compiler + * bug on Symbian/winscw. */ - QHash<StateId, QHash<TransitionType, QVector<StateId> > > transitions() const; + QHash<StateId, QHash<TransitionType, QVector<StateId> > > transitions() const + { + return m_transitions; + } private: /** @@ -217,14 +223,71 @@ namespace QPatternist /** * Returns the set of all states that can be reached from the set of @p input states * by the epsilon transition. + * + * The implementation is inlined in order to workaround a compiler + * bug on Symbian/winscw. */ - QSet<StateId> epsilonClosure(const QSet<StateId> &input) const; + QSet<StateId> epsilonClosure(const QSet<StateId> &input) const + { + // every state can reach itself by epsilon transition, so include the input states + // in the result as well + QSet<StateId> result = input; + + // add the input states to the list of to be processed states + QList<StateId> workStates = input.toList(); + while (!workStates.isEmpty()) { // while there are states to be processed left... + + // dequeue one state from list + const StateId state = workStates.takeFirst(); + + // get the list of states that can be reached by the epsilon transition + // from the current 'state' + const QVector<StateId> targetStates = m_epsilonTransitions.value(state); + for (int i = 0; i < targetStates.count(); ++i) { + // if we have this target state not in our result set yet... + if (!result.contains(targetStates.at(i))) { + // ... add it to the result set + result.insert(targetStates.at(i)); + + // add the target state to the list of to be processed states as well, + // as we want to have the epsilon transitions not only for the first + // level of following states + workStates.append(targetStates.at(i)); + } + } + } + + return result; + } /** * Returns the set of all states that can be reached from the set of given @p states * by the given @p input. + * + * The implementation is inlined in order to workaround a compiler + * bug on Symbian/winscw. */ - QSet<StateId> move(const QSet<StateId> &states, TransitionType input) const; + QSet<StateId> move(const QSet<StateId> &states, TransitionType input) const + { + QSet<StateId> result; + + QSetIterator<StateId> it(states); + while (it.hasNext()) { // iterate over all given states + const StateId state = it.next(); + + // get the transition table for the current state + const QHash<TransitionType, QVector<StateId> > transitions = m_transitions.value(state); + + // get the target states for the given input + const QVector<StateId> targetStates = transitions.value(input); + + // add all target states to the result + for (int i = 0; i < targetStates.size(); ++i) + result.insert(targetStates.at(i)); + } + + return result; + } NamePool::Ptr m_namePool; QHash<StateId, StateType> m_states; diff --git a/src/xmlpatterns/xmlpatterns.pro b/src/xmlpatterns/xmlpatterns.pro index bb8e452..1df497d 100644 --- a/src/xmlpatterns/xmlpatterns.pro +++ b/src/xmlpatterns/xmlpatterns.pro @@ -34,3 +34,5 @@ wince*: { QMAKE_CXXFLAGS_RELEASE ~= s/-O1/-Os -Oy -Ob2/ } } + +symbian:TARGET.UID3=0x2001E62B |