diff options
Diffstat (limited to 'src')
89 files changed, 2143 insertions, 977 deletions
diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 6fe71d6..221c020 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - 8f5ca3ba5da63a47d4f90bbd867d3e8453443dd3 + a54fd11a3abcd6d9c858e8162e85fd1f3aa21db1 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index 8e1c965..fd5606b 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,24 @@ +2010-01-25 Janne Koskinen <janne.p.koskinen@digia.com> + + Reviewed by Simon Hausmann. + + [Qt] Phone backup support for QtWebkit for Symbian devices. + https://bugs.webkit.org/show_bug.cgi?id=34077 + + * WebCore.pro: + +2010-01-21 Thiago Macieira <thiago.macieira@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix incorrect dependency to QtXmlPatterns in generated include/QtWebKit/QtWebKit header + + The generated file includes QtXmlPatterns/QtXmlPatterns, which is neither used/required by + the public QtWebKit API nor will it be available if Qt is configured with -no-xmlpatterns. + + * WebCore.pro: Trick syncqt to believe that xmlpatterns is not a dependency, so that it's not + included in the generated file. It'll still be used and linked to with this trick. + 2010-01-17 Srinidhi Shreedhara <srinidhi.shreedhara@nokia.com> Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro index 04aba62..bf4d6f9 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pro +++ b/src/3rdparty/webkit/WebCore/WebCore.pro @@ -18,7 +18,10 @@ symbian: { " " webkitlibs.pkg_prerules = vendorinfo - DEPLOYMENT += webkitlibs + webkitbackup.sources = ../WebKit/qt/symbian/backup_registration.xml + webkitbackup.path = /private/10202D56/import/packages/$$replace(TARGET.UID3, 0x,) + + DEPLOYMENT += webkitlibs webkitbackup TARGET.UID3 = 0x200267C2 # RO text (code) section in qtwebkit.dll exceeds allocated space for gcce udeb target. @@ -2780,7 +2783,7 @@ unix:!mac:CONFIG += link_pkgconfig contains(DEFINES, ENABLE_XSLT=1) { FEATURE_DEFINES_JAVASCRIPT += ENABLE_XSLT=1 - QT += xmlpatterns + tobe|!tobe: QT += xmlpatterns SOURCES += \ bindings/js/JSXSLTProcessorConstructor.cpp \ @@ -3415,14 +3418,8 @@ CONFIG(QTDIR_build):isEqual(QT_MAJOR_VERSION, 4):greaterThan(QT_MINOR_VERSION, 4 symbian { shared { - contains(MMP_RULES, defBlock) { - MMP_RULES -= defBlock - - MMP_RULES += "$${LITERAL_HASH}ifdef WINSCW" \ - "DEFFILE ../WebKit/qt/symbian/bwins/$${TARGET}.def" \ - "$${LITERAL_HASH}elif defined EABI" \ - "DEFFILE ../WebKit/qt/symbian/eabi/$${TARGET}.def" \ - "$${LITERAL_HASH}endif" + contains(CONFIG, def_files) { + defFilePath=../WebKit/qt/symbian } } } diff --git a/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp index 989b34c..714cac9 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp @@ -39,6 +39,7 @@ #include <QGraphicsProxyWidget> #include <QGraphicsScene> #include <QGraphicsView> +#include <QGraphicsWebView> #include <QListWidget> #include <QListWidgetItem> #include <QMenu> @@ -57,8 +58,10 @@ PopupMenu::PopupMenu(PopupMenuClient* client) PopupMenu::~PopupMenu() { - delete m_popup; - delete m_proxy; + // If we create a proxy, then the deletion of the proxy and the + // combo will be done by the proxy's parent (QGraphicsWebView) + if (!m_proxy) + delete m_popup; } void PopupMenu::clear() @@ -100,9 +103,8 @@ void PopupMenu::show(const IntRect& r, FrameView* v, int index) if (QGraphicsView* view = qobject_cast<QGraphicsView*>(client->ownerWidget())) { if (!m_proxy) { - m_proxy = new QGraphicsProxyWidget; + m_proxy = new QGraphicsProxyWidget(qobject_cast<QGraphicsWebView*>(client->pluginParent())); m_proxy->setWidget(m_popup); - view->scene()->addItem(m_proxy); } else m_proxy->setVisible(true); m_proxy->setGeometry(rect); diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp index 29bde0d..e4c2afc 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp @@ -1369,6 +1369,11 @@ void QWebFrame::print(QPrinter *printer) const // paranoia check fromPage = qMax(1, fromPage); toPage = qMin(printContext.pageCount(), toPage); + if (toPage < fromPage) { + // if the user entered a page range outside the actual number + // of printable pages, just return + return; + } if (printer->pageOrder() == QPrinter::LastPageFirst) { int tmp = fromPage; diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index ee555f3..09acd47 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,12 @@ +2010-01-25 Janne Koskinen <janne.p.koskinen@digia.com> + + Reviewed by Simon Hausmann. + + [Qt] Phone backup support for QtWebkit for Symbian devices. + https://bugs.webkit.org/show_bug.cgi?id=34077 + + * symbian/backup_registration.xml: Added. + 2009-11-19 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> Reviewed by Kenneth Rohde Christiansen. diff --git a/src/3rdparty/webkit/WebKit/qt/symbian/backup_registration.xml b/src/3rdparty/webkit/WebKit/qt/symbian/backup_registration.xml new file mode 100644 index 0000000..e026140 --- /dev/null +++ b/src/3rdparty/webkit/WebKit/qt/symbian/backup_registration.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" standalone="yes"?> +<backup_registration> + <system_backup/> + <restore requires_reboot = "no"/> +</backup_registration> diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index f5a9d16..f834a80 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -306,8 +306,6 @@ void QUnifiedTimer::registerRunningAnimation(QAbstractAnimation *animation) return; if (QAbstractAnimationPrivate::get(animation)->isPause) { - if (animation->duration() == -1) - qDebug() << "toto"; runningPauseAnimations << animation; } else runningLeafAnimations++; diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 722d6d3..9179485 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -98,7 +98,7 @@ static inline QByteArray openModeToFopenMode(QIODevice::OpenMode flags, const QS if (!fileName.isEmpty() && QT_STAT(QFile::encodeName(fileName), &statBuf) == 0 && (statBuf.st_mode & S_IFMT) == S_IFREG) { - mode += "+"; + mode += '+'; } else { mode = "wb+"; } diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 2c31509..64015ce 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -1091,30 +1091,23 @@ static inline int pathHashKey(QSettings::Format format, QSettings::Scope scope) return int((uint(format) << 1) | uint(scope == QSettings::SystemScope)); } -static QString getPath(QSettings::Format format, QSettings::Scope scope) +static void initDefaultPaths(QMutexLocker *locker) { - Q_ASSERT((int)QSettings::NativeFormat == 0); - Q_ASSERT((int)QSettings::IniFormat == 1); - + PathHash *pathHash = pathHashFunc(); QString homePath = QDir::homePath(); QString systemPath; - QMutexLocker locker(globalMutex()); - PathHash *pathHash = pathHashFunc(); - bool loadSystemPath = pathHash->isEmpty(); - locker.unlock(); - - if (loadSystemPath) { - /* - QLibraryInfo::location() uses QSettings, so in order to - avoid a dead-lock, we can't hold the global mutex while - calling it. - */ - systemPath = QLibraryInfo::location(QLibraryInfo::SettingsPath); - systemPath += QLatin1Char('/'); - } + locker->unlock(); + + /* + QLibraryInfo::location() uses QSettings, so in order to + avoid a dead-lock, we can't hold the global mutex while + calling it. + */ + systemPath = QLibraryInfo::location(QLibraryInfo::SettingsPath); + systemPath += QLatin1Char('/'); - locker.relock(); + locker->relock(); if (pathHash->isEmpty()) { /* Lazy initialization of pathHash. We initialize the @@ -1155,6 +1148,17 @@ static QString getPath(QSettings::Format format, QSettings::Scope scope) #endif #endif } +} + +static QString getPath(QSettings::Format format, QSettings::Scope scope) +{ + Q_ASSERT((int)QSettings::NativeFormat == 0); + Q_ASSERT((int)QSettings::IniFormat == 1); + + QMutexLocker locker(globalMutex()); + PathHash *pathHash = pathHashFunc(); + if (pathHash->isEmpty()) + initDefaultPaths(&locker); QString result = pathHash->value(pathHashKey(format, scope)); if (!result.isEmpty()) @@ -3455,6 +3459,8 @@ void QSettings::setPath(Format format, Scope scope, const QString &path) { QMutexLocker locker(globalMutex()); PathHash *pathHash = pathHashFunc(); + if (pathHash->isEmpty()) + initDefaultPaths(&locker); pathHash->insert(pathHashKey(format, scope), path + QDir::separator()); } diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index a131d6c..076cc33 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -3241,8 +3241,11 @@ static QString qt_ACE_do(const QString &domain, AceOperation op) while (1) { int idx = nextDotDelimiter(domain, lastIdx); int labelLength = idx - lastIdx; - if (labelLength == 0) + if (labelLength == 0) { + if (idx == domain.length()) + break; return QString(); // two delimiters in a row -- empty label not allowed + } // RFC 3490 says, about the ToASCII operation: // 3. If the UseSTD3ASCIIRules flag is set, then perform these checks: diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp index 0ef92d9..b6a2df4 100644 --- a/src/corelib/tools/qeasingcurve.cpp +++ b/src/corelib/tools/qeasingcurve.cpp @@ -125,7 +125,7 @@ \value OutCubic \inlineimage qeasingcurve-outcubic.png \br Easing curve for a cubic (t^3) function: - decelerating from zero velocity. + decelerating to zero velocity. \value InOutCubic \inlineimage qeasingcurve-inoutcubic.png \br Easing curve for a cubic (t^3) function: @@ -141,7 +141,7 @@ \value OutQuart \inlineimage qeasingcurve-outquart.png \br Easing curve for a cubic (t^4) function: - decelerating from zero velocity. + decelerating to zero velocity. \value InOutQuart \inlineimage qeasingcurve-inoutquart.png \br Easing curve for a cubic (t^4) function: @@ -157,7 +157,7 @@ \value OutQuint \inlineimage qeasingcurve-outquint.png \br Easing curve for a cubic (t^5) function: - decelerating from zero velocity. + decelerating to zero velocity. \value InOutQuint \inlineimage qeasingcurve-inoutquint.png \br Easing curve for a cubic (t^5) function: diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 21816b9..1b4b356 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -130,7 +130,7 @@ multiple- or virtual-inheritance (that is, in cases where two different pointer addresses can refer to the same object). In that case, if a pointer is cast to a different type and its value changes, - QSharedPointer's pointer tracking mechanism mail fail to detect that the + QSharedPointer's pointer tracking mechanism may fail to detect that the object being tracked is the same. \omit diff --git a/src/dbus/qdbusargument.cpp b/src/dbus/qdbusargument.cpp index 3466d90..7defc9a 100644 --- a/src/dbus/qdbusargument.cpp +++ b/src/dbus/qdbusargument.cpp @@ -535,7 +535,6 @@ QDBusArgument &QDBusArgument::operator<<(const QByteArray &arg) /*! \internal - Returns the type signature of the D-Bus type this QDBusArgument \since 4.5 Appends the variant \a v. diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 30fa0b6..44abf7b 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1660,9 +1660,6 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError } QString busService = QLatin1String(DBUS_SERVICE_DBUS); - WatchedServicesHash::mapped_type &bus = watchedServices[busService]; - bus.refcount = 1; - bus.owner = getNameOwnerNoCache(busService); connectSignal(busService, QString(), QString(), QLatin1String("NameAcquired"), QStringList(), QString(), this, SLOT(registerService(QString))); connectSignal(busService, QString(), QString(), QLatin1String("NameLost"), QStringList(), QString(), @@ -2004,7 +2001,8 @@ bool QDBusConnectionPrivate::connectSignal(const QString &service, entry.path == hook.path && entry.signature == hook.signature && entry.obj == hook.obj && - entry.midx == hook.midx) { + entry.midx == hook.midx && + entry.argumentMatch == hook.argumentMatch) { // no need to compare the parameters if it's the same slot return true; // already there } @@ -2046,10 +2044,7 @@ void QDBusConnectionPrivate::connectSignal(const QString &key, const SignalHook // Do we need to watch for this name? if (shouldWatchService(hook.service)) { WatchedServicesHash::mapped_type &data = watchedServices[hook.service]; - if (data.refcount) { - // already watching - ++data.refcount; - } else { + if (++data.refcount == 1) { // we need to watch for this service changing QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS); connectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS), @@ -2089,7 +2084,8 @@ bool QDBusConnectionPrivate::disconnectSignal(const QString &service, entry.path == hook.path && entry.signature == hook.signature && entry.obj == hook.obj && - entry.midx == hook.midx) { + entry.midx == hook.midx && + entry.argumentMatch == hook.argumentMatch) { // no need to compare the parameters if it's the same slot disconnectSignal(it); return true; // it was there @@ -2105,19 +2101,6 @@ QDBusConnectionPrivate::disconnectSignal(SignalHookHash::Iterator &it) { const SignalHook &hook = it.value(); - WatchedServicesHash::Iterator sit = watchedServices.find(hook.service); - if (sit != watchedServices.end()) { - if (sit.value().refcount == 1) { - watchedServices.erase(sit); - QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS); - disconnectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS), - QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(), - this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); - } else { - --sit.value().refcount; - } - } - bool erase = false; MatchRefCountHash::iterator i = matchRefCounts.find(hook.matchRule); if (i == matchRefCounts.end()) { @@ -2136,6 +2119,20 @@ QDBusConnectionPrivate::disconnectSignal(SignalHookHash::Iterator &it) if (connection && erase) { qDBusDebug("Removing rule: %s", hook.matchRule.constData()); q_dbus_bus_remove_match(connection, hook.matchRule, NULL); + + // Successfully disconnected the signal + // Were we watching for this name? + WatchedServicesHash::Iterator sit = watchedServices.find(hook.service); + if (sit != watchedServices.end()) { + if (--sit.value().refcount == 0) { + watchedServices.erase(sit); + QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS); + disconnectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS), + QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(), + this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); + } + } + } return signalHooks.erase(it); diff --git a/src/dbus/qdbusmarshaller.cpp b/src/dbus/qdbusmarshaller.cpp index f156e04..8ec328e 100644 --- a/src/dbus/qdbusmarshaller.cpp +++ b/src/dbus/qdbusmarshaller.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qdbusargument_p.h" +#include "qdbusmetatype_p.h" #include "qdbusutil_p.h" QT_BEGIN_NAMESPACE @@ -167,7 +168,7 @@ inline bool QDBusMarshaller::append(const QDBusVariant &arg) QByteArray tmpSignature; const char *signature = 0; - if (int(id) == qMetaTypeId<QDBusArgument>()) { + if (int(id) == QDBusMetaTypeId::argument) { // take the signature from the QDBusArgument object we're marshalling tmpSignature = qvariant_cast<QDBusArgument>(value).currentSignature().toLatin1(); @@ -353,7 +354,7 @@ bool QDBusMarshaller::appendVariantInternal(const QVariant &arg) } // intercept QDBusArgument parameters here - if (id == qMetaTypeId<QDBusArgument>()) { + if (id == QDBusMetaTypeId::argument) { QDBusArgument dbusargument = qvariant_cast<QDBusArgument>(arg); QDBusArgumentPrivate *d = QDBusArgumentPrivate::d(dbusargument); if (!d->message) diff --git a/src/gui/dialogs/qprintpreviewdialog.cpp b/src/gui/dialogs/qprintpreviewdialog.cpp index 42be780..6723b53 100644 --- a/src/gui/dialogs/qprintpreviewdialog.cpp +++ b/src/gui/dialogs/qprintpreviewdialog.cpp @@ -207,6 +207,9 @@ public: QActionGroup *printerGroup; QAction *printAction; QAction *pageSetupAction; +#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA) + QAction *closeAction; +#endif QPointer<QObject> receiverToDisconnectOnClose; QByteArray memberToDisconnectOnClose; @@ -287,6 +290,9 @@ void QPrintPreviewDialogPrivate::init(QPrinter *_printer) toolbar->addSeparator(); toolbar->addAction(pageSetupAction); toolbar->addAction(printAction); +#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA) + toolbar->addAction(closeAction); +#endif // Cannot use the actions' triggered signal here, since it doesn't autorepeat QToolButton *zoomInButton = static_cast<QToolButton *>(toolbar->widgetForAction(zoomInAction)); @@ -406,6 +412,10 @@ void QPrintPreviewDialogPrivate::setupActions() qt_setupActionIcon(pageSetupAction, QLatin1String("page-setup")); QObject::connect(printAction, SIGNAL(triggered(bool)), q, SLOT(_q_print())); QObject::connect(pageSetupAction, SIGNAL(triggered(bool)), q, SLOT(_q_pageSetup())); +#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA) + closeAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Close")); + QObject::connect(closeAction, SIGNAL(triggered(bool)), q, SLOT(reject())); +#endif // Initial state: fitPageAction->setChecked(true); diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp index ad23df3..10ef5ea 100644 --- a/src/gui/effects/qgraphicseffect.cpp +++ b/src/gui/effects/qgraphicseffect.cpp @@ -383,9 +383,9 @@ void QGraphicsEffectSourcePrivate::invalidateCache(InvalidateReason reason) cons { if (m_cachedMode != QGraphicsEffect::PadToEffectiveBoundingRect && (reason == EffectRectChanged - || reason == TransformChanged - && m_cachedSystem == Qt::LogicalCoordinates)) + || (reason == TransformChanged && m_cachedSystem == Qt::LogicalCoordinates))) { return; + } QPixmapCache::remove(m_cacheKey); } diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 1361a89..ed36f87 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -268,6 +268,17 @@ */ /*! + \variable QGraphicsItem::Type + + The type value returned by the virtual type() function in standard + graphics item classes in Qt. All such standard graphics item + classes in Qt are associated with a unique value for Type, + e.g. the value returned by QGraphicsPathItem::type() is 2. + + \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 18 +*/ + +/*! \variable QGraphicsItem::UserType The lowest permitted type value for custom items (subclasses @@ -276,6 +287,8 @@ and declaring a Type enum value. Example: \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 1 + + \note UserType = 65536 */ /*! @@ -798,8 +811,36 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch return; } - foreach (QGraphicsItem *child, children) - child->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false); + for (int i = 0; i < children.size(); ++i) + children.at(i)->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false); +} + +void QGraphicsItemPrivate::updateAncestorFlags() +{ + int flags = 0; + if (parent) { + // Inherit the parent's ancestor flags. + QGraphicsItemPrivate *pd = parent->d_ptr.data(); + flags = pd->ancestorFlags; + + // Add in flags from the parent. + if (pd->filtersDescendantEvents) + flags |= AncestorFiltersChildEvents; + if (pd->handlesChildEvents) + flags |= AncestorHandlesChildEvents; + if (pd->flags & QGraphicsItem::ItemClipsChildrenToShape) + flags |= AncestorClipsChildren; + if (pd->flags & QGraphicsItem::ItemIgnoresTransformations) + flags |= AncestorIgnoresTransformations; + } + + if (ancestorFlags == flags) + return; // No change; stop propagation. + ancestorFlags = flags; + + // Propagate to children recursively. + for (int i = 0; i < children.size(); ++i) + children.at(i)->d_ptr->updateAncestorFlags(); } /*! @@ -984,25 +1025,17 @@ QVariant QGraphicsItemPrivate::inputMethodQueryHelper(Qt::InputMethodQuery query prepareGeometryChange) if the item is in its destructor, i.e. inDestructor is 1. */ -void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) +void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const QVariant *newParentVariant, + const QVariant *thisPointerVariant) { Q_Q(QGraphicsItem); - if (newParent == q) { - qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this); - return; - } - if (newParent == parent) - return; - - const QVariant newParentVariant(q->itemChange(QGraphicsItem::ItemParentChange, - qVariantFromValue<QGraphicsItem *>(newParent))); - newParent = qVariantValue<QGraphicsItem *>(newParentVariant); if (newParent == parent) return; if (scene) { // Deliver the change to the index - scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParentVariant); + if (scene->d_func()->indexMethod != QGraphicsScene::NoIndex) + scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParent); // Disable scene pos notifications for old ancestors if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges)) @@ -1020,11 +1053,11 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) if (!inDestructor) q_ptr->prepareGeometryChange(); - const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(q)); if (parent) { // Remove from current parent parent->d_ptr->removeChild(q); - parent->itemChange(QGraphicsItem::ItemChildRemovedChange, thisPointerVariant); + if (thisPointerVariant) + parent->itemChange(QGraphicsItem::ItemChildRemovedChange, *thisPointerVariant); } // Update toplevelitem list. If this item is being deleted, its parent @@ -1042,7 +1075,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) QGraphicsItem *p = parent; QGraphicsItem *parentFocusScopeItem = 0; while (p) { - if (p->flags() & QGraphicsItem::ItemIsFocusScope) { + if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) { // If this item's focus scope's focus scope item points // to this item or a descendent, then clear it. QGraphicsItem *fsi = p->d_ptr->focusScopeItem; @@ -1055,6 +1088,10 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) p = p->d_ptr->parent; } + // Update graphics effect optimization flag + if (newParent && (graphicsEffect || mayHaveChildWithGraphicsEffect)) + newParent->d_ptr->updateChildWithGraphicsEffectFlagRecursively(); + // Update focus scope item ptr in new scope. QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem; if (newFocusScopeItem && newParent) { @@ -1063,11 +1100,11 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) QGraphicsItem *ancestorScope = 0; QGraphicsItem *p = subFocusItem->d_ptr->parent; while (p) { - if (p->flags() & QGraphicsItem::ItemIsFocusScope) + if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) ancestorScope = p; - if (p->isPanel()) + if (p->d_ptr->flags & QGraphicsItem::ItemIsPanel) break; - p = p->parentItem(); + p = p->d_ptr->parent; } if (ancestorScope) newFocusScopeItem = ancestorScope; @@ -1075,7 +1112,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) QGraphicsItem *p = newParent; while (p) { - if (p->flags() & QGraphicsItem::ItemIsFocusScope) { + if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) { p->d_ptr->focusScopeItem = newFocusScopeItem; // Ensure the new item is no longer the subFocusItem. The // only way to set focus on a child of a focus scope is @@ -1089,52 +1126,45 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) } if ((parent = newParent)) { - bool implicitUpdate = false; if (parent->d_func()->scene && parent->d_func()->scene != scene) { // Move this item to its new parent's scene parent->d_func()->scene->addItem(q); - implicitUpdate = true; } else if (!parent->d_func()->scene && scene) { // Remove this item from its former scene scene->removeItem(q); } parent->d_ptr->addChild(q); - parent->itemChange(QGraphicsItem::ItemChildAddedChange, thisPointerVariant); + if (thisPointerVariant) + parent->itemChange(QGraphicsItem::ItemChildAddedChange, *thisPointerVariant); if (scene) { - if (!implicitUpdate) - scene->d_func()->markDirty(q_ptr); - // Re-enable scene pos notifications for new ancestors if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges)) scene->d_func()->setScenePosItemEnabled(q, true); } + // Propagate dirty flags to the new parent + markParentDirty(/*updateBoundingRect=*/true); + // Inherit ancestor flags from the new parent. - updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2)); - updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1)); - updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape); - updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations); + updateAncestorFlags(); // Update item visible / enabled. - if (parent->isVisible() != visible) { - if (!parent->isVisible() || !explicitlyHidden) - setVisibleHelper(parent->isVisible(), /* explicit = */ false, /* update = */ !implicitUpdate); + if (parent->d_ptr->visible != visible) { + if (!parent->d_ptr->visible || !explicitlyHidden) + setVisibleHelper(parent->d_ptr->visible, /* explicit = */ false, /* update = */ false); } if (parent->isEnabled() != enabled) { - if (!parent->isEnabled() || !explicitlyDisabled) - setEnabledHelper(parent->isEnabled(), /* explicit = */ false, /* update = */ !implicitUpdate); + if (!parent->d_ptr->enabled || !explicitlyDisabled) + setEnabledHelper(parent->d_ptr->enabled, /* explicit = */ false, /* update = */ false); } // Auto-activate if visible and the parent is active. - if (q->isVisible() && parent->isActive()) + if (visible && parent->isActive()) q->setActive(true); } else { // Inherit ancestor flags from the new parent. - updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2)); - updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1)); - updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape); - updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations); + updateAncestorFlags(); if (!inDestructor) { // Update item visible / enabled. @@ -1142,10 +1172,6 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) setVisibleHelper(true, /* explicit = */ false); if (!enabled && !explicitlyDisabled) setEnabledHelper(true, /* explicit = */ false); - - // If the item is being deleted, the whole scene will be updated. - if (scene) - scene->d_func()->markDirty(q_ptr); } } @@ -1161,7 +1187,8 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) } // Deliver post-change notification - q->itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant); + if (newParentVariant) + q->itemChange(QGraphicsItem::ItemParentHasChanged, *newParentVariant); if (isObject) emit static_cast<QGraphicsObject *>(q)->parentChanged(); @@ -1350,7 +1377,7 @@ QGraphicsItem::~QGraphicsItem() d_ptr->scene->d_func()->removeItemHelper(this); } else { d_ptr->resetFocusProxy(); - d_ptr->setParentItemHelper(0); + setParentItem(0); } #ifndef QT_NO_GRAPHICSEFFECT @@ -1543,21 +1570,36 @@ const QGraphicsObject *QGraphicsItem::toGraphicsObject() const } /*! - Sets this item's parent item to \a parent. If this item already has a - parent, it is first removed from the previous parent. If \a parent is 0, - this item will become a top-level item. + Sets this item's parent item to \a newParent. If this item already + has a parent, it is first removed from the previous parent. If \a + newParent is 0, this item will become a top-level item. - Note that this implicitly adds this graphics item to the scene of - the parent. You should not \l{QGraphicsScene::addItem()}{add} the - item to the scene yourself. + Note that this implicitly adds this graphics item to the scene of + the parent. You should not \l{QGraphicsScene::addItem()}{add} the + item to the scene yourself. - Calling this function on an item that is an ancestor of \a parent have undefined behaviour. + Calling this function on an item that is an ancestor of \a newParent + have undefined behaviour. - \sa parentItem(), childItems() + \sa parentItem(), childItems() */ -void QGraphicsItem::setParentItem(QGraphicsItem *parent) +void QGraphicsItem::setParentItem(QGraphicsItem *newParent) { - d_ptr->setParentItemHelper(parent); + if (newParent == this) { + qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this); + return; + } + if (newParent == d_ptr->parent) + return; + + const QVariant newParentVariant(itemChange(QGraphicsItem::ItemParentChange, + qVariantFromValue<QGraphicsItem *>(newParent))); + newParent = qVariantValue<QGraphicsItem *>(newParentVariant); + if (newParent == d_ptr->parent) + return; + + const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(this)); + d_ptr->setParentItemHelper(newParent, &newParentVariant, &thisPointerVariant); } /*! @@ -1607,7 +1649,7 @@ bool QGraphicsItem::isWidget() const */ bool QGraphicsItem::isWindow() const { - return isWidget() && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window); + return d_ptr->isWidget && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window); } /*! @@ -1644,9 +1686,9 @@ QGraphicsItem::GraphicsItemFlags QGraphicsItem::flags() const void QGraphicsItem::setFlag(GraphicsItemFlag flag, bool enabled) { if (enabled) - setFlags(flags() | flag); + setFlags(GraphicsItemFlags(d_ptr->flags) | flag); else - setFlags(flags() & ~flag); + setFlags(GraphicsItemFlags(d_ptr->flags) & ~flag); } /*! @@ -1693,8 +1735,8 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt()); if (quint32(d_ptr->flags) == quint32(flags)) return; - if (d_ptr->scene) - d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, quint32(flags)); + if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) + d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, &flags); // Flags that alter the geometry of the item (or its children). const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable); @@ -1703,7 +1745,7 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) d_ptr->paintedViewBoundingRectsNeedRepaint = 1; // Keep the old flags to compare the diff. - GraphicsItemFlags oldFlags = this->flags(); + GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags); // Update flags. d_ptr->flags = flags; @@ -1732,7 +1774,23 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) d_ptr->updateAncestorFlag(ItemIgnoresTransformations); } + if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) { + // NB! We change the flags directly here, so we must also update d_ptr->flags. + // Note that this has do be done before the ItemStacksBehindParent check + // below; otherwise we will loose the change. + + // Update stack-behind. + if (d_ptr->z < qreal(0.0)) + flags |= ItemStacksBehindParent; + else + flags &= ~ItemStacksBehindParent; + d_ptr->flags = flags; + } + if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) { + // NB! This check has to come after the ItemNegativeZStacksBehindParent + // check above. Be careful. + // Ensure child item sorting is up to date when toggling this flag. if (d_ptr->parent) d_ptr->parent->d_ptr->needSortChildren = 1; @@ -1746,10 +1804,6 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) d_ptr->scene->d_func()->updateInputMethodSensitivityInViews(); } - if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) { - // Update stack-behind. - setFlag(ItemStacksBehindParent, d_ptr->z < qreal(0.0)); - } if ((d_ptr->panelModality != NonModal) && d_ptr->scene @@ -2523,7 +2577,9 @@ void QGraphicsItem::setOpacity(qreal opacity) // Update. if (d_ptr->scene) { #ifndef QT_NO_GRAPHICSEFFECT - d_ptr->invalidateGraphicsEffectsRecursively(); + d_ptr->invalidateParentGraphicsEffectsRecursively(); + if (!(d_ptr->flags & ItemDoesntPropagateOpacityToChildren)) + d_ptr->invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::OpacityChanged); #endif //QT_NO_GRAPHICSEFFECT d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true, @@ -2568,6 +2624,8 @@ void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect) if (d_ptr->graphicsEffect) { delete d_ptr->graphicsEffect; d_ptr->graphicsEffect = 0; + } else if (d_ptr->parent) { + d_ptr->parent->d_ptr->updateChildWithGraphicsEffectFlagRecursively(); } if (effect) { @@ -2581,6 +2639,19 @@ void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect) } #endif //QT_NO_GRAPHICSEFFECT +void QGraphicsItemPrivate::updateChildWithGraphicsEffectFlagRecursively() +{ +#ifndef QT_NO_GRAPHICSEFFECT + QGraphicsItemPrivate *itemPrivate = this; + do { + // parent chain already notified? + if (itemPrivate->mayHaveChildWithGraphicsEffect) + return; + itemPrivate->mayHaveChildWithGraphicsEffect = 1; + } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0)); +#endif +} + /*! \internal \since 4.6 @@ -4264,9 +4335,9 @@ void QGraphicsItem::setZValue(qreal z) if (newZ == d_ptr->z) return; - if (d_ptr->scene) { + if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) { // Z Value has changed, we have to notify the index. - d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, newZVariant); + d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, &newZ); } d_ptr->z = newZ; @@ -5033,7 +5104,7 @@ int QGraphicsItemPrivate::depth() const \internal */ #ifndef QT_NO_GRAPHICSEFFECT -void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively() +void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively() { QGraphicsItemPrivate *itemPrivate = this; do { @@ -5045,6 +5116,24 @@ void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively() } } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0)); } + +void QGraphicsItemPrivate::invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::InvalidateReason reason) +{ + if (!mayHaveChildWithGraphicsEffect) + return; + + for (int i = 0; i < children.size(); ++i) { + QGraphicsItemPrivate *childPrivate = children.at(i)->d_ptr.data(); + if (reason == OpacityChanged && (childPrivate->flags & QGraphicsItem::ItemIgnoresParentOpacity)) + continue; + if (childPrivate->graphicsEffect) { + childPrivate->notifyInvalidated = 1; + static_cast<QGraphicsItemEffectSourcePrivate *>(childPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache(); + } + + childPrivate->invalidateChildGraphicsEffectsRecursively(reason); + } +} #endif //QT_NO_GRAPHICSEFFECT /*! @@ -5289,7 +5378,7 @@ void QGraphicsItem::update(const QRectF &rect) // Make sure we notify effects about invalidated source. #ifndef QT_NO_GRAPHICSEFFECT - d_ptr->invalidateGraphicsEffectsRecursively(); + d_ptr->invalidateParentGraphicsEffectsRecursively(); #endif //QT_NO_GRAPHICSEFFECT if (CacheMode(d_ptr->cacheMode) != NoCache) { @@ -7165,7 +7254,9 @@ void QGraphicsItem::prepareGeometryChange() QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); scenePrivate->index->prepareBoundingRectChange(this); - scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true); + scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true, /*force=*/false, + /*ignoreOpacity=*/ false, /*removingItemFromScene=*/ false, + /*updateBoundingRect=*/true); // For compatibility reasons, we have to update the item's old geometry // if someone is connected to the changed signal or the scene has no views. @@ -7182,19 +7273,7 @@ void QGraphicsItem::prepareGeometryChange() } } - QGraphicsItem *parent = this; - while ((parent = parent->d_ptr->parent)) { - QGraphicsItemPrivate *parentp = parent->d_ptr.data(); - parentp->dirtyChildrenBoundingRect = 1; - // ### Only do this if the parent's effect applies to the entire subtree. - parentp->notifyBoundingRectChanged = 1; -#ifndef QT_NO_GRAPHICSEFFECT - if (parentp->scene && parentp->graphicsEffect) { - parentp->notifyInvalidated = 1; - static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()->source->d_func())->invalidateCache(); - } -#endif - } + d_ptr->markParentDirty(/*updateBoundingRect=*/true); } /*! diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 2d34b80..5ad6cd5 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -153,7 +153,7 @@ public: dirtyChildren(0), localCollisionHack(0), inSetPosHelper(0), - needSortChildren(1), // ### can be 0 by default? + needSortChildren(0), allChildrenDirty(0), fullUpdatePending(0), flags(0), @@ -178,6 +178,8 @@ public: sequentialOrdering(1), updateDueToGraphicsEffect(0), scenePosDescendants(0), + pendingPolish(0), + mayHaveChildWithGraphicsEffect(0), globalStackingOrder(-1), q_ptr(0) { @@ -195,8 +197,10 @@ public: return item->d_ptr.data(); } + void updateChildWithGraphicsEffectFlagRecursively(); void updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag, AncestorFlag flag = NoFlag, bool enabled = false, bool root = true); + void updateAncestorFlags(); void setIsMemberOfGroup(bool enabled); void remapItemPos(QEvent *event, QGraphicsItem *item); QPointF genericMapFromScene(const QPointF &pos, const QWidget *viewport) const; @@ -223,13 +227,18 @@ public: bool ignoreDirtyBit = false, bool ignoreOpacity = false) const; int depth() const; #ifndef QT_NO_GRAPHICSEFFECT - void invalidateGraphicsEffectsRecursively(); + enum InvalidateReason { + OpacityChanged + }; + void invalidateParentGraphicsEffectsRecursively(); + void invalidateChildGraphicsEffectsRecursively(InvalidateReason reason); #endif //QT_NO_GRAPHICSEFFECT void invalidateDepthRecursively(); void resolveDepth(); void addChild(QGraphicsItem *child); void removeChild(QGraphicsItem *child); - void setParentItemHelper(QGraphicsItem *parent); + void setParentItemHelper(QGraphicsItem *parent, const QVariant *newParentVariant, + const QVariant *thisPointerVariant); void childrenBoundingRectHelper(QTransform *x, QRectF *rect); void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform, const QRegion &exposedRegion, bool allItems = false) const; @@ -397,6 +406,8 @@ public: return !visible || (childrenCombineOpacity() && isFullyTransparent()); } + inline void markParentDirty(bool updateBoundingRect = false); + void setFocusHelper(Qt::FocusReason focusReason, bool climb); void setSubFocus(QGraphicsItem *rootItem = 0); void clearSubFocus(QGraphicsItem *rootItem = 0); @@ -484,6 +495,8 @@ public: quint32 sequentialOrdering : 1; quint32 updateDueToGraphicsEffect : 1; quint32 scenePosDescendants : 1; + quint32 pendingPolish : 1; + quint32 mayHaveChildWithGraphicsEffect : 1; // Optional stacking order int globalStackingOrder; @@ -721,11 +734,13 @@ inline QTransform QGraphicsItemPrivate::transformToParent() const inline void QGraphicsItemPrivate::ensureSortedChildren() { if (needSortChildren) { - qSort(children.begin(), children.end(), qt_notclosestLeaf); needSortChildren = 0; sequentialOrdering = 1; + if (children.isEmpty()) + return; + qSort(children.begin(), children.end(), qt_notclosestLeaf); for (int i = 0; i < children.size(); ++i) { - if (children[i]->d_ptr->siblingIndex != i) { + if (children.at(i)->d_ptr->siblingIndex != i) { sequentialOrdering = 0; break; } @@ -741,6 +756,37 @@ inline bool QGraphicsItemPrivate::insertionOrder(QGraphicsItem *a, QGraphicsItem return a->d_ptr->siblingIndex < b->d_ptr->siblingIndex; } +/*! + \internal +*/ +inline void QGraphicsItemPrivate::markParentDirty(bool updateBoundingRect) +{ + QGraphicsItemPrivate *parentp = this; + while (parentp->parent) { + parentp = parentp->parent->d_ptr.data(); + parentp->dirtyChildren = 1; + + if (updateBoundingRect) { + parentp->dirtyChildrenBoundingRect = 1; + // ### Only do this if the parent's effect applies to the entire subtree. + parentp->notifyBoundingRectChanged = 1; + } +#ifndef QT_NO_GRAPHICSEFFECT + if (parentp->graphicsEffect) { + if (updateBoundingRect) { + parentp->notifyInvalidated = 1; + static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func() + ->source->d_func())->invalidateCache(); + } + if (parentp->graphicsEffect->isEnabled()) { + parentp->dirty = 1; + parentp->fullUpdatePending = 1; + } + } +#endif + } +} + QT_END_NAMESPACE #endif // QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 83a6b9c..478669e 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -292,7 +292,6 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() processDirtyItemsEmitted(false), selectionChanging(0), needSortTopLevelItems(true), - unpolishedItemsModified(true), holesInTopLevelSiblingIndex(false), topLevelSequentialOrdering(true), scenePosDescendantsUpdatePending(false), @@ -429,22 +428,38 @@ void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item) */ void QGraphicsScenePrivate::_q_polishItems() { - QSet<QGraphicsItem *>::Iterator it = unpolishedItems.begin(); + if (unpolishedItems.isEmpty()) + return; + const QVariant booleanTrueVariant(true); - while (!unpolishedItems.isEmpty()) { - QGraphicsItem *item = *it; - it = unpolishedItems.erase(it); - unpolishedItemsModified = false; - if (!item->d_ptr->explicitlyHidden) { + QGraphicsItem *item = 0; + QGraphicsItemPrivate *itemd = 0; + const int oldUnpolishedCount = unpolishedItems.count(); + + for (int i = 0; i < oldUnpolishedCount; ++i) { + item = unpolishedItems.at(i); + if (!item) + continue; + itemd = item->d_ptr.data(); + itemd->pendingPolish = false; + if (!itemd->explicitlyHidden) { item->itemChange(QGraphicsItem::ItemVisibleChange, booleanTrueVariant); item->itemChange(QGraphicsItem::ItemVisibleHasChanged, booleanTrueVariant); } - if (item->isWidget()) { + if (itemd->isWidget) { QEvent event(QEvent::Polish); QApplication::sendEvent((QGraphicsWidget *)item, &event); } - if (unpolishedItemsModified) - it = unpolishedItems.begin(); + } + + if (unpolishedItems.count() == oldUnpolishedCount) { + // No new items were added to the vector. + unpolishedItems.clear(); + } else { + // New items were appended; keep them and remove the old ones. + unpolishedItems.remove(0, oldUnpolishedCount); + unpolishedItems.squeeze(); + QMetaObject::invokeMethod(q_ptr, "_q_polishItems", Qt::QueuedConnection); } } @@ -599,7 +614,7 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) if (parentItem->scene()) { Q_ASSERT_X(parentItem->scene() == q, "QGraphicsScene::removeItem", "Parent item's scene is different from this item's scene"); - item->d_ptr->setParentItemHelper(0); + item->setParentItem(0); } } else { unregisterTopLevelItem(item); @@ -638,8 +653,12 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) selectedItems.remove(item); hoverItems.removeAll(item); cachedItemsUnderMouse.removeAll(item); - unpolishedItems.remove(item); - unpolishedItemsModified = true; + if (item->d_ptr->pendingPolish) { + const int unpolishedIndex = unpolishedItems.indexOf(item); + if (unpolishedIndex != -1) + unpolishedItems[unpolishedIndex] = 0; + item->d_ptr->pendingPolish = false; + } resetDirtyItem(item); //We remove all references of item from the sceneEventFilter arrays @@ -1936,7 +1955,7 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rectangle, Qt::ItemSe \since 4.3 This convenience function is equivalent to calling items(QRectF(\a x, \a y, \a w, \a h), \a mode). - + This function is deprecated and returns incorrect results if the scene contains items that ignore transformations. Use the overload that takes a QTransform instead. @@ -2482,12 +2501,12 @@ void QGraphicsScene::addItem(QGraphicsItem *item) qWarning("QGraphicsScene::addItem: cannot add null item"); return; } - if (item->scene() == this) { + if (item->d_ptr->scene == this) { qWarning("QGraphicsScene::addItem: item has already been added to this scene"); return; } // Remove this item from its existing scene - if (QGraphicsScene *oldScene = item->scene()) + if (QGraphicsScene *oldScene = item->d_ptr->scene) oldScene->removeItem(item); // Notify the item that its scene is changing, and allow the item to @@ -2496,15 +2515,20 @@ void QGraphicsScene::addItem(QGraphicsItem *item) qVariantFromValue<QGraphicsScene *>(this))); QGraphicsScene *targetScene = qVariantValue<QGraphicsScene *>(newSceneVariant); if (targetScene != this) { - if (targetScene && item->scene() != targetScene) + if (targetScene && item->d_ptr->scene != targetScene) targetScene->addItem(item); return; } + if (d->unpolishedItems.isEmpty()) + QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection); + d->unpolishedItems.append(item); + item->d_ptr->pendingPolish = true; + // Detach this item from its parent if the parent's scene is different // from this scene. - if (QGraphicsItem *itemParent = item->parentItem()) { - if (itemParent->scene() != this) + if (QGraphicsItem *itemParent = item->d_ptr->parent) { + if (itemParent->d_ptr->scene != this) item->setParentItem(0); } @@ -2534,7 +2558,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item) d->enableMouseTrackingOnViews(); } #ifndef QT_NO_CURSOR - if (d->allItemsUseDefaultCursor && item->hasCursor()) { + if (d->allItemsUseDefaultCursor && item->d_ptr->hasCursor) { d->allItemsUseDefaultCursor = false; if (d->allItemsIgnoreHoverEvents) // already enabled otherwise d->enableMouseTrackingOnViews(); @@ -2542,7 +2566,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item) #endif //QT_NO_CURSOR // Enable touch events if the item accepts touch events. - if (d->allItemsIgnoreTouchEvents && item->acceptTouchEvents()) { + if (d->allItemsIgnoreTouchEvents && item->d_ptr->acceptTouchEvents) { d->allItemsIgnoreTouchEvents = false; d->enableTouchEventsOnViews(); } @@ -2575,17 +2599,14 @@ void QGraphicsScene::addItem(QGraphicsItem *item) } // Add all children recursively - foreach (QGraphicsItem *child, item->children()) - addItem(child); + item->d_ptr->ensureSortedChildren(); + for (int i = 0; i < item->d_ptr->children.size(); ++i) + addItem(item->d_ptr->children.at(i)); // Resolve font and palette. item->d_ptr->resolveFont(d->font.resolve()); item->d_ptr->resolvePalette(d->palette.resolve()); - if (d->unpolishedItems.isEmpty()) - QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection); - d->unpolishedItems.insert(item); - d->unpolishedItemsModified = true; // Reenable selectionChanged() for individual items --d->selectionChanging; @@ -2619,7 +2640,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item) } } - if (item->flags() & QGraphicsItem::ItemSendsScenePositionChanges) + if (item->d_ptr->flags & QGraphicsItem::ItemSendsScenePositionChanges) d->registerScenePosItem(item); // Ensure that newly added items that have subfocus set, gain @@ -3766,10 +3787,10 @@ void QGraphicsScene::helpEvent(QGraphicsSceneHelpEvent *helpEvent) bool QGraphicsScenePrivate::itemAcceptsHoverEvents_helper(const QGraphicsItem *item) const { - return (!item->isBlockedByModalPanel() && - (item->acceptHoverEvents() - || (item->isWidget() - && static_cast<const QGraphicsWidget *>(item)->d_func()->hasDecoration()))); + return (item->d_ptr->acceptsHover + || (item->d_ptr->isWidget + && static_cast<const QGraphicsWidget *>(item)->d_func()->hasDecoration())) + && !item->isBlockedByModalPanel(); } /*! @@ -4813,7 +4834,8 @@ void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const Q } void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, bool invalidateChildren, - bool force, bool ignoreOpacity, bool removingItemFromScene) + bool force, bool ignoreOpacity, bool removingItemFromScene, + bool updateBoundingRect) { Q_ASSERT(item); if (updateAll) @@ -4884,17 +4906,8 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b if (ignoreOpacity) item->d_ptr->ignoreOpacity = 1; - QGraphicsItem *p = item->d_ptr->parent; - while (p) { - p->d_ptr->dirtyChildren = 1; -#ifndef QT_NO_GRAPHICSEFFECT - if (p->d_ptr->graphicsEffect && p->d_ptr->graphicsEffect->isEnabled()) { - p->d_ptr->dirty = 1; - p->d_ptr->fullUpdatePending = 1; - } -#endif //QT_NO_GRAPHICSEFFECT - p = p->d_ptr->parent; - } + if (!updateBoundingRect) + item->d_ptr->markParentDirty(); } static inline bool updateHelper(QGraphicsViewPrivate *view, QGraphicsItemPrivate *item, diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index d10811c..04ffe0f 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -108,10 +108,9 @@ public: QPainterPath selectionArea; int selectionChanging; QSet<QGraphicsItem *> selectedItems; - QSet<QGraphicsItem *> unpolishedItems; + QVector<QGraphicsItem *> unpolishedItems; QList<QGraphicsItem *> topLevelItems; bool needSortTopLevelItems; - bool unpolishedItemsModified; bool holesInTopLevelSiblingIndex; bool topLevelSequentialOrdering; @@ -223,7 +222,8 @@ public: QRegion *, QWidget *, qreal, const QTransform *const, bool, bool); void markDirty(QGraphicsItem *item, const QRectF &rect = QRectF(), bool invalidateChildren = false, - bool force = false, bool ignoreOpacity = false, bool removingItemFromScene = false); + bool force = false, bool ignoreOpacity = false, bool removingItemFromScene = false, + bool updateBoundingRect = false); void processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren = false, qreal parentOpacity = qreal(1.0)); diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 2e92b87..2a91348 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -635,16 +635,17 @@ void QGraphicsSceneBspTreeIndex::updateSceneRect(const QRectF &rect) This method react to the \a change of the \a item and use the \a value to update the BSP tree if necessary. */ -void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) +void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const void *const value) { Q_D(QGraphicsSceneBspTreeIndex); switch (change) { case QGraphicsItem::ItemFlagsChange: { // Handle ItemIgnoresTransformations + QGraphicsItem::GraphicsItemFlags newFlags = *static_cast<const QGraphicsItem::GraphicsItemFlags *>(value); bool ignoredTransform = item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations; - bool willIgnoreTransform = value.toUInt() & QGraphicsItem::ItemIgnoresTransformations; + bool willIgnoreTransform = newFlags & QGraphicsItem::ItemIgnoresTransformations; bool clipsChildren = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape; - bool willClipChildren = value.toUInt() & QGraphicsItem::ItemClipsChildrenToShape; + bool willClipChildren = newFlags & QGraphicsItem::ItemClipsChildrenToShape; if ((ignoredTransform != willIgnoreTransform) || (clipsChildren != willClipChildren)) { QGraphicsItem *thatItem = const_cast<QGraphicsItem *>(item); // Remove item and its descendants from the index and append @@ -661,7 +662,7 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics case QGraphicsItem::ItemParentChange: { d->invalidateSortCache(); // Handle ItemIgnoresTransformations - QGraphicsItem *newParent = qVariantValue<QGraphicsItem *>(value); + const QGraphicsItem *newParent = static_cast<const QGraphicsItem *>(value); bool ignoredTransform = item->d_ptr->itemIsUntransformable(); bool willIgnoreTransform = (item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations) || (newParent && newParent->d_ptr->itemIsUntransformable()); @@ -682,7 +683,6 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics default: break; } - return QGraphicsSceneIndex::itemChange(item, change, value); } /*! \reimp diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 119571b..f671fd9 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -97,7 +97,7 @@ protected: void removeItem(QGraphicsItem *item); void prepareBoundingRectChange(const QGraphicsItem *item); - void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); + void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const void *const value); private : Q_DECLARE_PRIVATE(QGraphicsSceneBspTreeIndex) diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index bc8a7dc..043c4eb 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -624,7 +624,7 @@ void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item) \sa QGraphicsItem::GraphicsItemChange */ -void QGraphicsSceneIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) +void QGraphicsSceneIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const void *const value) { Q_UNUSED(item); Q_UNUSED(change); diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index def58f0..597a229 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -110,7 +110,7 @@ protected: virtual void removeItem(QGraphicsItem *item) = 0; virtual void deleteItem(QGraphicsItem *item); - virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value); + virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const void *const value); virtual void prepareBoundingRectChange(const QGraphicsItem *item); QGraphicsSceneIndex(QGraphicsSceneIndexPrivate &dd, QGraphicsScene *scene); diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp index 854be2e..42e19b8 100644 --- a/src/gui/image/qbmphandler.cpp +++ b/src/gui/image/qbmphandler.cpp @@ -144,7 +144,7 @@ static QDataStream &operator<<(QDataStream &s, const BMP_INFOHDR &bi) static int calc_shift(int mask) { int result = 0; - while (!(mask & 1)) { + while (mask && !(mask & 1)) { result++; mask >>= 1; } diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h index 0b84e2f..f5034fc 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_p.h +++ b/src/gui/inputmethod/qcoefepinputcontext_p.h @@ -57,6 +57,7 @@ #include "qinputcontext.h" #include <qhash.h> +#include <qtimer.h> #include <private/qcore_symbian_p.h> #include <private/qt_s60_p.h> @@ -91,6 +92,9 @@ public: TCoeInputCapabilities inputCapabilities(); +protected: + void timerEvent(QTimerEvent *timerEvent); + private: void commitCurrentString(bool triggeredBySymbian); void updateHints(bool mustUpdateInputCapabilities); @@ -98,6 +102,7 @@ private: void applyFormat(QList<QInputMethodEvent::Attribute> *attributes); void queueInputCapabilitiesChanged(); bool needsInputPanel(); + void commitTemporaryPreeditString(); private Q_SLOTS: void ensureInputCapabilitiesChanged(); @@ -148,6 +153,8 @@ private: MFepPointerEventHandlerDuringInlineEdit *m_pointerHandler; int m_longPress; int m_cursorPos; + QBasicTimer m_tempPreeditStringTimeout; + bool m_hasTempPreeditString; }; QT_END_NAMESPACE diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index d2f207a..793bcde 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -72,7 +72,8 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent) m_formatRetriever(0), m_pointerHandler(0), m_longPress(0), - m_cursorPos(0) + m_cursorPos(0), + m_hasTempPreeditString(false) { m_fepState->SetObjectProvider(this); m_fepState->SetFlags(EAknEditorFlagDefault); @@ -100,6 +101,8 @@ QCoeFepInputContext::~QCoeFepInputContext() void QCoeFepInputContext::reset() { + commitTemporaryPreeditString(); + CCoeFep* fep = CCoeEnv::Static()->Fep(); if (fep) fep->CancelTransaction(); @@ -200,7 +203,11 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event) if (!focusWidget()) return false; - if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) { + switch (event->type()) { + case QEvent::KeyPress: + commitTemporaryPreeditString(); + // fall through intended + case QEvent::KeyRelease: const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event); switch (keyEvent->key()) { case Qt::Key_F20: @@ -223,6 +230,21 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event) default: break; } + + if (keyEvent->type() == QEvent::KeyPress + && focusWidget()->inputMethodHints() & Qt::ImhHiddenText + && !keyEvent->text().isEmpty()) { + // Send some temporary preedit text in order to make text visible for a moment. + m_preeditString = keyEvent->text(); + QList<QInputMethodEvent::Attribute> attributes; + QInputMethodEvent imEvent(m_preeditString, attributes); + QApplication::sendEvent(focusWidget(), &imEvent); + m_tempPreeditStringTimeout.start(1000, this); + m_hasTempPreeditString = true; + update(); + return true; + } + break; } if (!needsInputPanel()) @@ -253,6 +275,24 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event) return false; } +void QCoeFepInputContext::timerEvent(QTimerEvent *timerEvent) +{ + if (timerEvent->timerId() == m_tempPreeditStringTimeout.timerId()) + commitTemporaryPreeditString(); +} + +void QCoeFepInputContext::commitTemporaryPreeditString() +{ + if (m_tempPreeditStringTimeout.isActive()) + m_tempPreeditStringTimeout.stop(); + + if (!m_hasTempPreeditString) + return; + + commitCurrentString(false); + m_hasTempPreeditString = false; +} + void QCoeFepInputContext::mouseHandler( int x, QMouseEvent *event) { Q_ASSERT(focusWidget()); @@ -310,6 +350,8 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints) { using namespace Qt; + commitTemporaryPreeditString(); + bool numbersOnly = hints & ImhDigitsOnly || hints & ImhFormattedNumbersOnly || hints & ImhDialableCharactersOnly; bool noOnlys = !(numbersOnly || hints & ImhUppercaseOnly @@ -501,6 +543,8 @@ void QCoeFepInputContext::StartFepInlineEditL(const TDesC& aInitialInlineText, if (!w) return; + commitTemporaryPreeditString(); + m_cursorPos = w->inputMethodQuery(Qt::ImCursorPosition).toInt(); QList<QInputMethodEvent::Attribute> attributes; @@ -600,6 +644,8 @@ void QCoeFepInputContext::SetCursorSelectionForFepL(const TCursorSelection& aCur if (!w) return; + commitTemporaryPreeditString(); + int pos = aCursorSelection.iAnchorPos; int length = aCursorSelection.iCursorPos - pos; diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp index 7eefb0b..3111896 100644 --- a/src/gui/itemviews/qtableview.cpp +++ b/src/gui/itemviews/qtableview.cpp @@ -114,7 +114,9 @@ void QSpanCollection::updateSpan(QSpanCollection::Span *span, int old_height) } } else if (old_height > span->height()) { //remove the span from all the subspans lists that intersect the columns not covered anymore - Index::iterator it_y = index.lowerBound(qMin(-span->bottom(), 0)); + Index::iterator it_y = index.lowerBound(-span->bottom()); + if (it_y == index.end()) + it_y = index.find(-span->top()); // This is the only span remaining and we are deleting it. Q_ASSERT(it_y != index.end()); //it_y must exist since the span is in the list while (-it_y.key() <= span->top() + old_height -1) { if (-it_y.key() > span->bottom()) { diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 65840c8..b9ea540 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -121,8 +121,10 @@ extern bool qt_wince_is_pocket_pc(); //qguifunctions_wince.cpp static void initResources() { -#ifdef Q_WS_WINCE +#if defined(Q_WS_WINCE) Q_INIT_RESOURCE(qstyle_wince); +#elif defined(Q_OS_SYMBIAN) + Q_INIT_RESOURCE(qstyle_s60); #else Q_INIT_RESOURCE(qstyle); #endif diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index 961a3f6..3fba833 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -227,8 +227,29 @@ void onApplicationChangedActivation( bool activated ); static void qt_mac_read_fontsmoothing_settings() { - NSInteger appleFontSmoothing = [[NSUserDefaults standardUserDefaults] integerForKey:@"AppleFontSmoothing"]; - qt_applefontsmoothing_enabled = (appleFontSmoothing > 0); + qt_applefontsmoothing_enabled = true; + int w = 10, h = 10; + QImage image(w, h, QImage::Format_RGB32); + image.fill(0xffffffff); + QPainter p(&image); + p.drawText(0, h, "X\\"); + p.end(); + + const int *bits = (const int *) ((const QImage &) image).bits(); + int bpl = image.bytesPerLine() / 4; + for (int y=0; y<w; ++y) { + for (int x=0; x<h; ++x) { + int r = qRed(bits[x]); + int g = qGreen(bits[x]); + int b = qBlue(bits[x]); + if (r != g || r != b) { + qt_applefontsmoothing_enabled = true; + return; + } + } + bits += bpl; + } + qt_applefontsmoothing_enabled = false; } Q_GUI_EXPORT bool qt_mac_execute_apple_script(const char *script, long script_len, AEDesc *ret) { @@ -772,11 +793,11 @@ static void qt_mac_update_intersected_gl_widgets(QWidget *widget) qt_post_window_change_event(glWidget); it->lastUpdateWidget = widget; } else if (it->lastUpdateWidget == widget) { - // Update the gl wigets that the widget intersected the last time around, - // and that we are not intersecting now. This prevents paint errors when the + // Update the gl wigets that the widget intersected the last time around, + // and that we are not intersecting now. This prevents paint errors when the // intersecting widget leaves a gl widget. qt_post_window_change_event(glWidget); - it->lastUpdateWidget = 0; + it->lastUpdateWidget = 0; } } #else @@ -808,8 +829,8 @@ Q_GUI_EXPORT void qt_event_request_window_change(QWidget *widget) // Post a kEventQtRequestWindowChange event. This event is semi-public, // don't remove this line! qt_event_request_window_change(); - - // Post update request on gl widgets unconditionally. + + // Post update request on gl widgets unconditionally. if (qt_widget_private(widget)->isGLWidget == true) { qt_post_window_change_event(widget); return; @@ -1214,8 +1235,6 @@ void qt_init(QApplicationPrivate *priv, int) if (QApplication::desktopSettingsAware()) QApplicationPrivate::qt_mac_apply_settings(); - qt_mac_read_fontsmoothing_settings(); - // Cocoa application delegate #ifdef QT_MAC_USE_COCOA NSApplication *cocoaApp = [NSApplication sharedApplication]; @@ -1249,6 +1268,7 @@ void qt_init(QApplicationPrivate *priv, int) } priv->native_modal_dialog_active = false; + qt_mac_read_fontsmoothing_settings(); } void qt_release_apple_event_handler() @@ -1730,7 +1750,7 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event // kEventMouseWheelMoved events if we dont eat this event // (actually two events; one for horizontal and one for vertical). // As a results of this, and to make sure we dont't receive duplicate events, - // we try to detect when this happend by checking the 'compatibilityEvent'. + // we try to detect when this happend by checking the 'compatibilityEvent'. SInt32 mdelt = 0; GetEventParameter(event, kEventParamMouseWheelSmoothHorizontalDelta, typeSInt32, 0, sizeof(mdelt), 0, &mdelt); @@ -2623,7 +2643,7 @@ void QApplicationPrivate::closePopup(QWidget *popup) if (QApplicationPrivate::popupWidgets->isEmpty()) { // this was the last popup delete QApplicationPrivate::popupWidgets; QApplicationPrivate::popupWidgets = 0; - + // Special case for Tool windows: since they are activated and deactived together // with a normal window they never become the QApplicationPrivate::active_window. QWidget *appFocusWidget = QApplication::focusWidget(); diff --git a/src/gui/kernel/qcocoamenuloader_mac.mm b/src/gui/kernel/qcocoamenuloader_mac.mm index 9f90cec..18b3772 100644 --- a/src/gui/kernel/qcocoamenuloader_mac.mm +++ b/src/gui/kernel/qcocoamenuloader_mac.mm @@ -110,6 +110,12 @@ QT_USE_NAMESPACE } } +- (void)removeActionsFromAppMenu +{ + for (NSMenuItem *item in [appMenu itemArray]) + [item setTag:nil]; +} + - (void)dealloc { [lastAppSpecificItem release]; diff --git a/src/gui/kernel/qcocoamenuloader_mac_p.h b/src/gui/kernel/qcocoamenuloader_mac_p.h index 432a7a6..81c136e 100644 --- a/src/gui/kernel/qcocoamenuloader_mac_p.h +++ b/src/gui/kernel/qcocoamenuloader_mac_p.h @@ -70,6 +70,7 @@ } - (void)ensureAppMenuInMenu:(NSMenu *)menu; +- (void)removeActionsFromAppMenu; - (NSMenu *)applicationMenu; - (NSMenu *)menu; - (NSMenuItem *)quitMenuItem; diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index 13c25fd..377e5a0 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -1296,4 +1296,17 @@ void qt_cocoaChangeOverrideCursor(const QCursor &cursor) } @end +QMacCocoaAutoReleasePool::QMacCocoaAutoReleasePool() +{ +#ifndef QT_MAC_USE_COCOA + NSApplicationLoad(); +#endif + pool = (void*)[[NSAutoreleasePool alloc] init]; +} + +QMacCocoaAutoReleasePool::~QMacCocoaAutoReleasePool() +{ + [(NSAutoreleasePool*)pool release]; +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index eed76e5..e678220 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -3352,7 +3352,7 @@ QPoint QWidget::pos() const \note Setting the size to \c{QSize(0, 0)} will cause the widget to not appear on screen. This also applies to windows. - \sa pos, geometry, minimumSize, maximumSize, resizeEvent() + \sa pos, geometry, minimumSize, maximumSize, resizeEvent(), adjustSize() */ /*! diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 3ff46f5..43b945e 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -404,7 +404,7 @@ inline static void qt_mac_set_fullscreen_mode(bool b) return; qt_mac_app_fullscreen = b; if (b) { - SetSystemUIMode(kUIModeAllSuppressed, 0); + SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); } else { SetSystemUIMode(kUIModeNormal, 0); } diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index f51dc36..d6d288e 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -934,8 +934,7 @@ void QColor::setRgb(int r, int g, int b, int a) /*! \fn QRgb QColor::rgba() const - Returns the RGB value of the color. Unlike rgb(), the alpha is not - stripped. + Returns the RGB value of the color, including its alpha. For an invalid color, the alpha value of the returned color is unspecified. @@ -950,8 +949,7 @@ QRgb QColor::rgba() const } /*! - Sets the RGBA value to \a rgba. Unlike setRgb(QRgb rgb), this function does - not ignore the alpha. + Sets the RGB value to \a rgba, including its alpha. \sa rgba(), rgb() */ @@ -968,8 +966,7 @@ void QColor::setRgba(QRgb rgba) /*! \fn QRgb QColor::rgb() const - Returns the RGB value of the color. The alpha is stripped for - compatibility. + Returns the RGB value of the color. The alpha value is opaque. \sa getRgb(), rgba() */ @@ -983,7 +980,7 @@ QRgb QColor::rgb() const /*! \overload - Sets the RGB value to \a rgb, ignoring the alpha. + Sets the RGB value to \a rgb. The alpha value is set to opaque. */ void QColor::setRgb(QRgb rgb) { diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index b937f66..a1c73cc 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -264,13 +264,13 @@ private: #endif // Q_OS_SYMBIAN && QT_NO_FREETYPE inline void ensureBrush(const QBrush &brush) { - if (!qbrush_fast_equals(state()->lastBrush, brush) || state()->fillFlags) + if (!qbrush_fast_equals(state()->lastBrush, brush) || (brush.style() != Qt::NoBrush && state()->fillFlags)) updateBrush(brush); } inline void ensureBrush() { ensureBrush(state()->brush); } inline void ensurePen(const QPen &pen) { - if (!qpen_fast_equals(state()->lastPen, pen) || state()->strokeFlags) + if (!qpen_fast_equals(state()->lastPen, pen) || (pen.style() != Qt::NoPen && state()->strokeFlags)) updatePen(pen); } inline void ensurePen() { ensurePen(state()->pen); } diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 31132d9..cde6a2d 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -7382,10 +7382,15 @@ struct QPaintDeviceRedirection typedef QList<QPaintDeviceRedirection> QPaintDeviceRedirectionList; Q_GLOBAL_STATIC(QPaintDeviceRedirectionList, globalRedirections) Q_GLOBAL_STATIC(QMutex, globalRedirectionsMutex) +Q_GLOBAL_STATIC(QAtomicInt, globalRedirectionAtomic) /*! \threadsafe + \obsolete + + Please use QWidget::render() instead. + Redirects all paint commands for the given paint \a device, to the \a replacement device. The optional point \a offset defines an offset within the source device. @@ -7395,9 +7400,10 @@ Q_GLOBAL_STATIC(QMutex, globalRedirectionsMutex) device's painter (if any) before redirecting. Call restoreRedirected() to restore the previous redirection. - In general, you'll probably find that calling - QPixmap::grabWidget() or QPixmap::grabWindow() is an easier - solution. + \warning Making use of redirections in the QPainter API implies + that QPainter::begin() and QPaintDevice destructors need to hold + a mutex for a short period. This can impact performance. Use of + QWidget::render is strongly encouraged. \sa redirected(), restoreRedirected() */ @@ -7429,14 +7435,24 @@ void QPainter::setRedirected(const QPaintDevice *device, Q_ASSERT(redirections != 0); *redirections += QPaintDeviceRedirection(device, rdev ? rdev : replacement, offset + roffset, hadInternalWidgetRedirection ? redirections->size() - 1 : -1); + globalRedirectionAtomic()->ref(); } /*! \threadsafe + \obsolete + + Using QWidget::render() obsoletes the use of this function. + Restores the previous redirection for the given \a device after a call to setRedirected(). + \warning Making use of redirections in the QPainter API implies + that QPainter::begin() and QPaintDevice destructors need to hold + a mutex for a short period. This can impact performance. Use of + QWidget::render is strongly encouraged. + \sa redirected() */ void QPainter::restoreRedirected(const QPaintDevice *device) @@ -7447,6 +7463,7 @@ void QPainter::restoreRedirected(const QPaintDevice *device) Q_ASSERT(redirections != 0); for (int i = redirections->size()-1; i >= 0; --i) { if (redirections->at(i) == device) { + globalRedirectionAtomic()->deref(); const int internalWidgetRedirectionIndex = redirections->at(i).internalWidgetRedirectionIndex; redirections->removeAt(i); // Restore the internal widget redirection, i.e. remove it from the global @@ -7468,9 +7485,18 @@ void QPainter::restoreRedirected(const QPaintDevice *device) /*! \threadsafe + \obsolete + + Using QWidget::render() obsoletes the use of this function. + Returns the replacement for given \a device. The optional out parameter \a offset returns the offset within the replaced device. + \warning Making use of redirections in the QPainter API implies + that QPainter::begin() and QPaintDevice destructors need to hold + a mutex for a short period. This can impact performance. Use of + QWidget::render is strongly encouraged. + \sa setRedirected(), restoreRedirected() */ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset) @@ -7483,6 +7509,9 @@ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset) return widgetPrivate->redirected(offset); } + if (*globalRedirectionAtomic() == 0) + return 0; + QMutexLocker locker(globalRedirectionsMutex()); QPaintDeviceRedirectionList *redirections = globalRedirections(); Q_ASSERT(redirections != 0); @@ -7500,6 +7529,9 @@ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset) void qt_painter_removePaintDevice(QPaintDevice *dev) { + if (*globalRedirectionAtomic() == 0) + return; + QMutex *mutex = 0; QT_TRY { mutex = globalRedirectionsMutex(); diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm index 2313ac5..e8298cf 100644 --- a/src/gui/styles/qmacstyle_mac.mm +++ b/src/gui/styles/qmacstyle_mac.mm @@ -667,32 +667,47 @@ static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg switch (ct) { case QStyle::CT_PushButton: { - const QPushButton *psh = static_cast<const QPushButton *>(widg); - QString buttonText = qt_mac_removeMnemonics(psh->text()); - if (buttonText.contains(QLatin1Char('\n'))) - ret = QSize(-1, -1); - else if (sz == QAquaSizeLarge) - ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight)); - else if (sz == QAquaSizeSmall) - ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight)); - else if (sz == QAquaSizeMini) - ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight)); - - if (!psh->icon().isNull()){ - // If the button got an icon, and the icon is larger than the - // button, we can't decide on a default size - ret.setWidth(-1); - if (ret.height() < psh->iconSize().height()) - ret.setHeight(-1); - } - else if (buttonText == QLatin1String("OK") || buttonText == QLatin1String("Cancel")){ - // Aqua Style guidelines restrict the size of OK and Cancel buttons to 68 pixels. - // However, this doesn't work for German, therefore only do it for English, - // I suppose it would be better to do some sort of lookups for languages - // that like to have really long words. - ret.setWidth(77 - 8); - } - + const QPushButton *psh = qobject_cast<const QPushButton *>(widg); + // If this comparison is false, then the widget was not a push button. + // This is bad and there's very little we can do since we were requested to find a + // sensible size for a widget that pretends to be a QPushButton but is not. + if(psh) { + QString buttonText = qt_mac_removeMnemonics(psh->text()); + if (buttonText.contains(QLatin1Char('\n'))) + ret = QSize(-1, -1); + else if (sz == QAquaSizeLarge) + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight)); + else if (sz == QAquaSizeSmall) + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight)); + else if (sz == QAquaSizeMini) + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight)); + + if (!psh->icon().isNull()){ + // If the button got an icon, and the icon is larger than the + // button, we can't decide on a default size + ret.setWidth(-1); + if (ret.height() < psh->iconSize().height()) + ret.setHeight(-1); + } + else if (buttonText == QLatin1String("OK") || buttonText == QLatin1String("Cancel")){ + // Aqua Style guidelines restrict the size of OK and Cancel buttons to 68 pixels. + // However, this doesn't work for German, therefore only do it for English, + // I suppose it would be better to do some sort of lookups for languages + // that like to have really long words. + ret.setWidth(77 - 8); + } + } else { + // The only sensible thing to do is to return whatever the style suggests... + if (sz == QAquaSizeLarge) + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight)); + else if (sz == QAquaSizeSmall) + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight)); + else if (sz == QAquaSizeMini) + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight)); + else + // Since there's no default size we return the large size... + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight)); + } #if 0 //Not sure we are applying the rules correctly for RadioButtons/CheckBoxes --Sam } else if (ct == QStyle::CT_RadioButton) { QRadioButton *rdo = static_cast<QRadioButton *>(widg); @@ -749,23 +764,30 @@ static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg if (sz == QAquaSizeSmall) { int width = 0, height = 0; if (szHint == QSize(-1, -1)) { //just 'guess'.. - const QToolButton *bt = static_cast<const QToolButton *>(widg); - if (!bt->icon().isNull()) { - QSize iconSize = bt->iconSize(); - QSize pmSize = bt->icon().actualSize(QSize(32, 32), QIcon::Normal); - width = qMax(width, qMax(iconSize.width(), pmSize.width())); - height = qMax(height, qMax(iconSize.height(), pmSize.height())); - } - if (!bt->text().isNull() && bt->toolButtonStyle() != Qt::ToolButtonIconOnly) { - int text_width = bt->fontMetrics().width(bt->text()), - text_height = bt->fontMetrics().height(); - if (bt->toolButtonStyle() == Qt::ToolButtonTextUnderIcon) { - width = qMax(width, text_width); - height += text_height; - } else { - width += text_width; - width = qMax(height, text_height); + const QToolButton *bt = qobject_cast<const QToolButton *>(widg); + // If this conversion fails then the widget was not what it claimed to be. + if(bt) { + if (!bt->icon().isNull()) { + QSize iconSize = bt->iconSize(); + QSize pmSize = bt->icon().actualSize(QSize(32, 32), QIcon::Normal); + width = qMax(width, qMax(iconSize.width(), pmSize.width())); + height = qMax(height, qMax(iconSize.height(), pmSize.height())); + } + if (!bt->text().isNull() && bt->toolButtonStyle() != Qt::ToolButtonIconOnly) { + int text_width = bt->fontMetrics().width(bt->text()), + text_height = bt->fontMetrics().height(); + if (bt->toolButtonStyle() == Qt::ToolButtonTextUnderIcon) { + width = qMax(width, text_width); + height += text_height; + } else { + width += text_width; + width = qMax(height, text_height); + } } + } else { + // Let's return the size hint... + width = szHint.width(); + height = szHint.height(); } } else { width = szHint.width(); @@ -778,37 +800,47 @@ static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg break; case QStyle::CT_Slider: { int w = -1; - const QSlider *sld = static_cast<const QSlider *>(widg); - if (sz == QAquaSizeLarge) { - if (sld->orientation() == Qt::Horizontal) { - w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight); - if (sld->tickPosition() != QSlider::NoTicks) - w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight); - } else { - w = qt_mac_aqua_get_metric(kThemeMetricVSliderWidth); - if (sld->tickPosition() != QSlider::NoTicks) - w += qt_mac_aqua_get_metric(kThemeMetricVSliderTickWidth); - } - } else if (sz == QAquaSizeSmall) { - if (sld->orientation() == Qt::Horizontal) { - w = qt_mac_aqua_get_metric(kThemeMetricSmallHSliderHeight); - if (sld->tickPosition() != QSlider::NoTicks) - w += qt_mac_aqua_get_metric(kThemeMetricSmallHSliderTickHeight); - } else { - w = qt_mac_aqua_get_metric(kThemeMetricSmallVSliderWidth); - if (sld->tickPosition() != QSlider::NoTicks) - w += qt_mac_aqua_get_metric(kThemeMetricSmallVSliderTickWidth); - } - } else if (sz == QAquaSizeMini) { - if (sld->orientation() == Qt::Horizontal) { - w = qt_mac_aqua_get_metric(kThemeMetricMiniHSliderHeight); - if (sld->tickPosition() != QSlider::NoTicks) - w += qt_mac_aqua_get_metric(kThemeMetricMiniHSliderTickHeight); - } else { - w = qt_mac_aqua_get_metric(kThemeMetricMiniVSliderWidth); - if (sld->tickPosition() != QSlider::NoTicks) - w += qt_mac_aqua_get_metric(kThemeMetricMiniVSliderTickWidth); + const QSlider *sld = qobject_cast<const QSlider *>(widg); + // If this conversion fails then the widget was not what it claimed to be. + if(sld) { + if (sz == QAquaSizeLarge) { + if (sld->orientation() == Qt::Horizontal) { + w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight); + if (sld->tickPosition() != QSlider::NoTicks) + w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight); + } else { + w = qt_mac_aqua_get_metric(kThemeMetricVSliderWidth); + if (sld->tickPosition() != QSlider::NoTicks) + w += qt_mac_aqua_get_metric(kThemeMetricVSliderTickWidth); + } + } else if (sz == QAquaSizeSmall) { + if (sld->orientation() == Qt::Horizontal) { + w = qt_mac_aqua_get_metric(kThemeMetricSmallHSliderHeight); + if (sld->tickPosition() != QSlider::NoTicks) + w += qt_mac_aqua_get_metric(kThemeMetricSmallHSliderTickHeight); + } else { + w = qt_mac_aqua_get_metric(kThemeMetricSmallVSliderWidth); + if (sld->tickPosition() != QSlider::NoTicks) + w += qt_mac_aqua_get_metric(kThemeMetricSmallVSliderTickWidth); + } + } else if (sz == QAquaSizeMini) { + if (sld->orientation() == Qt::Horizontal) { + w = qt_mac_aqua_get_metric(kThemeMetricMiniHSliderHeight); + if (sld->tickPosition() != QSlider::NoTicks) + w += qt_mac_aqua_get_metric(kThemeMetricMiniHSliderTickHeight); + } else { + w = qt_mac_aqua_get_metric(kThemeMetricMiniVSliderWidth); + if (sld->tickPosition() != QSlider::NoTicks) + w += qt_mac_aqua_get_metric(kThemeMetricMiniVSliderTickWidth); + } } + } else { + // This is tricky, we were requested to find a size for a slider which is not + // a slider. We don't know if this is vertical or horizontal or if we need to + // have tick marks or not. + // For this case we will return an horizontal slider without tick marks. + w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight); + w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight); } if (sld->orientation() == Qt::Horizontal) ret.setHeight(w); diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 100303e..9b99161 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -68,6 +68,10 @@ #include "qtoolbutton.h" #include "qfocusframe.h" #include "qformlayout.h" +#include "qradiobutton.h" +#include "qcheckbox.h" +#include "qdesktopwidget.h" +#include "qprogressbar.h" #include "private/qtoolbarextension_p.h" #include "private/qcombobox_p.h" @@ -564,9 +568,11 @@ QPixmap QS60StylePrivate::cachedPart(QS60StyleEnums::SkinParts part, const QSize &size, QPainter *painter, SkinElementFlags flags) { QPixmap result; + const int animationFrame = (flags & SF_Animation) ? currentAnimationFrame(part) : 0; + const QString cacheKey = - QString::fromLatin1("S60Style: SkinParts=%1 QSize=%2|%3 SkinPartFlags=%4") - .arg((int)part).arg(size.width()).arg(size.height()).arg((int)flags); + QString::fromLatin1("S60Style: SkinParts=%1 QSize=%2|%3 SkinPartFlags=%4 AnimationFrame=%5") + .arg((int)part).arg(size.width()).arg(size.height()).arg((int)flags).arg(animationFrame); if (!QPixmapCache::find(cacheKey, result)) { result = QS60StylePrivate::part(part, size, painter, flags); QPixmapCache::insert(cacheKey, result); @@ -672,8 +678,7 @@ void QS60StylePrivate::setThemePalette(QPalette *palette) const s60Color(QS60StyleEnums::CL_QsnHighlightColors, 2, 0)); // set background image as a texture brush palette->setBrush(QPalette::Window, backgroundTexture()); - // set these as transparent so that styled full screen theme background is visible - palette->setColor(QPalette::AlternateBase, Qt::transparent); + // set as transparent so that styled full screen theme background is visible palette->setBrush(QPalette::Base, Qt::transparent); // set button and tooltipbase based on pixel colors const QColor buttonColor = colorFromFrameGraphics(SF_ButtonNormal); @@ -685,6 +690,9 @@ void QS60StylePrivate::setThemePalette(QPalette *palette) const palette->setColor(QPalette::Midlight, palette->color(QPalette::Button).lighter(125)); palette->setColor(QPalette::Mid, palette->color(QPalette::Button).darker(150)); palette->setColor(QPalette::Shadow, Qt::black); + QColor alternateBase = palette->light().color(); + alternateBase.setAlphaF(0.8); + palette->setColor(QPalette::AlternateBase, alternateBase); QApplication::setPalette(*palette); //calling QApplication::setPalette clears palette hash setThemePaletteHash(palette); @@ -775,6 +783,11 @@ void QS60StylePrivate::setThemePaletteHash(QPalette *palette) const QApplication::setPalette(widgetPalette, "QComboBox"); widgetPalette = *palette; + widgetPalette.setColor(QPalette::WindowText, s60Color(QS60StyleEnums::CL_QsnTextColors, 7, 0)); + QApplication::setPalette(widgetPalette, "QRadioButton"); + QApplication::setPalette(widgetPalette, "QCheckBox"); + widgetPalette = *palette; + widgetPalette.setColor(QPalette::WindowText, mainAreaTextColor); widgetPalette.setColor(QPalette::Button, QApplication::palette().color(QPalette::Button)); widgetPalette.setColor(QPalette::Dark, mainAreaTextColor.darker()); @@ -813,13 +826,13 @@ QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlag //ratio of 1:2 for horizontal tab bars (and 2:1 for vertical ones). result.setWidth(result.height() >> 1); break; - + case QS60StyleEnums::SP_QgnGrafNsliderEndLeft: case QS60StyleEnums::SP_QgnGrafNsliderEndRight: case QS60StyleEnums::SP_QgnGrafNsliderMiddle: result.setWidth(result.height() >> 1); break; - + case QS60StyleEnums::SP_QgnGrafNsliderMarker: case QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected: result.scale(pixelMetric(QStyle::PM_SliderLength), @@ -922,10 +935,10 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom horizontal ? QS60StylePrivate::SE_ScrollBarGrooveHorizontal : QS60StylePrivate::SE_ScrollBarGrooveVertical; QS60StylePrivate::drawSkinElement(grooveElement, painter, grooveRect, flags); - const QStyle::SubControls subControls = optionSlider->subControls; + const SubControls subControls = optionSlider->subControls; // select correct slider (horizontal/vertical/pressed) - const bool sliderPressed = ((optionSlider->state & QStyle::State_Sunken) && (subControls & SC_ScrollBarSlider)); + const bool sliderPressed = ((optionSlider->state & State_Sunken) && (subControls & SC_ScrollBarSlider)); const QS60StylePrivate::SkinElements handleElement = horizontal ? ( sliderPressed ? @@ -946,13 +959,13 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom const bool horizontal = optionSlider->orientation == Qt::Horizontal; //Highlight -/* if (optionSlider->state & QStyle::State_HasFocus) +/* if (optionSlider->state & State_HasFocus) drawPrimitive(PE_FrameFocusRect, optionSlider, painter, widget);*/ - + //Groove graphics if (QS60StylePrivate::hasSliderGrooveGraphic()) { - const QS60StylePrivate::SkinElements grooveElement = horizontal ? - QS60StylePrivate::SE_SliderGrooveHorizontal : + const QS60StylePrivate::SkinElements grooveElement = horizontal ? + QS60StylePrivate::SE_SliderGrooveHorizontal : QS60StylePrivate::SE_SliderGrooveVertical; QS60StylePrivate::drawSkinElement(grooveElement, painter, sliderGroove, flags); } else { @@ -972,10 +985,10 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom //Handle graphics const QRect sliderHandle = subControlRect(control, optionSlider, SC_SliderHandle, widget); QS60StylePrivate::SkinElements handleElement; - if (optionSlider->state & QStyle::State_Sunken) + if (optionSlider->state & State_Sunken) handleElement = horizontal ? QS60StylePrivate::SE_SliderHandleSelectedHorizontal : QS60StylePrivate::SE_SliderHandleSelectedVertical; - else + else handleElement = horizontal ? QS60StylePrivate::SE_SliderHandleHorizontal : QS60StylePrivate::SE_SliderHandleVertical; QS60StylePrivate::drawSkinElement(handleElement, painter, sliderHandle, flags); @@ -994,7 +1007,7 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom buttonOption.QStyleOption::operator=(*cmb); const int maxHeight = cmbxFrame.height(); const int maxWidth = cmbxFrame.width() - cmbxEditField.width(); - const int topLeftPoint = direction ? + const int topLeftPoint = direction ? (cmbxEditField.right() + 1) : (cmbxEditField.left() + 1 - maxWidth); const QRect buttonRect(topLeftPoint, cmbxEditField.top(), maxWidth, maxHeight); buttonOption.rect = buttonRect; @@ -1020,102 +1033,62 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom #ifndef QT_NO_TOOLBUTTON case CC_ToolButton: if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(option)) { - const State bflags = toolBtn->state; + State bflags = toolBtn->state & ~State_Sunken; + + if (bflags & State_AutoRaise) { + if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) { + bflags &= ~State_Raised; + } + } + State mflags = bflags; + if (toolBtn->state & State_Sunken) { + if (toolBtn->activeSubControls & SC_ToolButton) + bflags |= State_Sunken; + mflags |= State_Sunken; + } + const QRect button(subControlRect(control, toolBtn, SC_ToolButton, widget)); QRect menuRect = QRect(); if (toolBtn->subControls & SC_ToolButtonMenu) menuRect = subControlRect(control, toolBtn, SC_ToolButtonMenu, widget); - QStyleOptionToolButton toolButton = *toolBtn; - - if (sub&SC_ToolButton) { + if (toolBtn->subControls & SC_ToolButton) { QStyleOption tool(0); tool.palette = toolBtn->palette; - // Check if toolbutton is in toolbar. - QToolBar *toolBar = 0; - if (widget) - toolBar = qobject_cast<QToolBar *>(widget->parentWidget()); - - if (bflags & (State_Sunken | State_On | State_Raised)) { + if (bflags & (State_Sunken | State_On | State_Raised | State_Enabled)) { tool.rect = button.unite(menuRect); tool.state = bflags; - - // todo: I'd like to move extension button next to where last button is - // however, the painter seems to want to clip the button rect even if I turn of the clipping. - if (toolBar && (qobject_cast<const QToolBarExtension *>(widget))){ - /*QList<QAction *> actionList = toolBar->actions(); - const int actionCount = actionList.count(); - const int toolbarWidth = toolBar->width(); - const int extButtonWidth = pixelMetric(PM_ToolBarExtensionExtent, option, widget); - const int toolBarButtonWidth = pixelMetric(PM_ToolBarIconSize, option, widget); - const int frame = pixelMetric(PM_ToolBarFrameWidth, option, widget); - const int margin = pixelMetric(PM_ToolBarItemMargin, option, widget); - const int border = frame + margin; - const int spacing = pixelMetric(PM_ToolBarItemSpacing, option, widget); - const int toolBarButtonArea = toolbarWidth - extButtonWidth - spacing - 2*border; - const int numberOfVisibleButtons = toolBarButtonArea / toolBarButtonWidth; - // new extension button place is after border and all the other visible buttons (with spacings) - const int newXForExtensionButton = numberOfVisibleButtons * toolBarButtonWidth + (numberOfVisibleButtons-1)*spacing + border; - painter->save(); - painter->setClipping(false); - tool.rect.translate(-newXForExtensionButton,0); - painter->restore();*/ - } - - if (toolBar){ - /*if (toolBar->orientation() == Qt::Vertical){ - // todo: I'd like to make all vertical buttons the same size, but again the painter - // prefers to use clipping for button rects, even though clipping has been set off. - painter->save(); - painter->setClipping(false); - - const int origWidth = tool.rect.width(); - const int newWidth = toolBar->width()-2*pixelMetric(PM_ToolBarFrameWidth, option, widget); - painter->translate(origWidth-newWidth,0); - tool.rect.translate(origWidth-tool.rect.width(),0); - tool.rect.setWidth(newWidth); - - if (option->state & QStyle::State_Sunken) - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButtonPressed, painter, tool.rect, flags); - else - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButton, painter, tool.rect, flags); - - }*/ - if (option->state & QStyle::State_Sunken) - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButtonPressed, painter, tool.rect, flags); - else - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButton, painter, tool.rect, flags); - /* - if (toolBar->orientation() == Qt::Vertical) - painter->restore(); - */ - } else { - drawPrimitive(PE_PanelButtonTool, &tool, painter, widget); - } - - if (toolButton.subControls & SC_ToolButtonMenu) { - tool.rect = menuRect; - tool.state = bflags; - drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget); - } + const QToolButton *toolButtonWidget = qobject_cast<const QToolButton *>(widget); + QS60StylePrivate::SkinElements element; + if (toolButtonWidget) + element = (toolButtonWidget->isDown()) ? QS60StylePrivate::SE_ToolBarButtonPressed : QS60StylePrivate::SE_ToolBarButton; + else + element = (option->state & State_Sunken) ? QS60StylePrivate::SE_ToolBarButtonPressed : QS60StylePrivate::SE_ToolBarButton; + QS60StylePrivate::drawSkinElement(element, painter, tool.rect, flags); + drawPrimitive(PE_PanelButtonTool, &tool, painter, widget); + } + if (toolBtn->subControls & SC_ToolButtonMenu) { + tool.rect = menuRect; + tool.state = mflags; + drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget); } } - + QStyleOptionToolButton toolButton = *toolBtn; if (toolBtn->features & QStyleOptionToolButton::Arrow) { - QStyle::PrimitiveElement pe; + PrimitiveElement pe; switch (toolBtn->arrowType) { case Qt::LeftArrow: - pe = QStyle::PE_IndicatorArrowLeft; + pe = PE_IndicatorArrowLeft; break; case Qt::RightArrow: - pe = QStyle::PE_IndicatorArrowRight; + pe = PE_IndicatorArrowRight; break; case Qt::UpArrow: - pe = QStyle::PE_IndicatorArrowUp; + pe = PE_IndicatorArrowUp; break; case Qt::DownArrow: - pe = QStyle::PE_IndicatorArrowDown; + pe = PE_IndicatorArrowDown; break; default: break; } @@ -1199,7 +1172,7 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom // Draw frame const QRect textRect = subControlRect(CC_GroupBox, option, SC_GroupBoxLabel, widget); const QRect checkBoxRect = subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget); - if (groupBox->subControls & QStyle::SC_GroupBoxFrame) { + if (groupBox->subControls & SC_GroupBoxFrame) { QStyleOptionFrameV2 frame; frame.QStyleOption::operator=(*groupBox); frame.features = groupBox->features; @@ -1210,14 +1183,14 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom } // Draw title - if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) { + if ((groupBox->subControls & SC_GroupBoxLabel) && !groupBox->text.isEmpty()) { const QColor textColor = groupBox->textColor; painter->save(); if (textColor.isValid()) painter->setPen(textColor); int alignment = int(groupBox->textAlignment); - if (!styleHint(QStyle::SH_UnderlineShortcut, option, widget)) + if (!styleHint(SH_UnderlineShortcut, option, widget)) alignment |= Qt::TextHideMnemonic; drawItemText(painter, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | Qt::AlignVCenter | alignment, @@ -1249,6 +1222,31 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, Q_D(const QS60Style); const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ? QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled; switch (element) { + case CE_CheckBox: + case CE_RadioButton: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { + bool isRadio = (element == CE_RadioButton); + // Highlight needs to be drawn first, as it goes "underneath" the text and indicator. + if (btn->state & State_HasFocus) { + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*btn); + fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect + : SE_CheckBoxFocusRect, btn, widget); + drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); + } + QStyleOptionButton subopt = *btn; + + subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator + : SE_CheckBoxIndicator, btn, widget); + drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox, + &subopt, painter, widget); + subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents + : SE_CheckBoxContents, btn, widget); + + drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, painter, widget); + } + break; + case CE_PushButton: if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { @@ -1261,13 +1259,13 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, break; case CE_PushButtonBevel: if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) { - const bool isDisabled = !(option->state & QStyle::State_Enabled); + const bool isDisabled = !(option->state & State_Enabled); const bool isFlat = button->features & QStyleOptionButton::Flat; QS60StyleEnums::SkinParts skinPart; QS60StylePrivate::SkinElements skinElement; if (!isDisabled) { - const bool isPressed = (option->state & QStyle::State_Sunken) || - (option->state & QStyle::State_On); + const bool isPressed = (option->state & State_Sunken) || + (option->state & State_On); if (isFlat) { skinPart = isPressed ? QS60StyleEnums::SP_QsnFrButtonTbCenterPressed : QS60StyleEnums::SP_QsnFrButtonTbCenter; @@ -1292,7 +1290,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(option)) { QStyleOptionToolButton optionToolButton = *toolBtn; - if (!optionToolButton.icon.isNull() && (optionToolButton.state & QStyle::State_Sunken) + if (!optionToolButton.icon.isNull() && (optionToolButton.state & State_Sunken) && (optionToolButton.state & State_Enabled)) { const QIcon::State state = optionToolButton.state & State_On ? QIcon::On : QIcon::Off; @@ -1351,8 +1349,8 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, painter->save(); painter->setClipRect(voptAdj.rect); - const bool isSelected = (vopt->state & QStyle::State_Selected); - const bool hasFocus = (vopt->state & QStyle::State_HasFocus); + const bool isSelected = (vopt->state & State_Selected); + const bool hasFocus = (vopt->state & State_HasFocus); bool isScrollBarVisible = false; int scrollBarWidth = 0; @@ -1426,8 +1424,8 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, } // draw the icon - const QIcon::Mode mode = (voptAdj.state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled; - const QIcon::State state = voptAdj.state & QStyle::State_Open ? QIcon::On : QIcon::Off; + const QIcon::Mode mode = (voptAdj.state & State_Enabled) ? QIcon::Normal : QIcon::Disabled; + const QIcon::State state = voptAdj.state & State_Open ? QIcon::On : QIcon::Off; voptAdj.icon.paint(painter, iconRect, voptAdj.decorationAlignment, mode, state); // Draw selection check mark. Show check mark only in multi selection modes. @@ -1439,29 +1437,29 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, QStyleOptionViewItemV4 checkMarkOption(voptAdj); // Draw selection mark. - if (voptAdj.state & QStyle::State_Selected && !singleSelection) { + if (voptAdj.state & State_Selected && !singleSelection) { checkMarkOption.rect = selectionRect; - drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget); + drawPrimitive(PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget); if ( textRect.right() > selectionRect.left() ) textRect.setRight(selectionRect.left()); } else if (singleSelection && voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator && selectionRect.isValid()) { checkMarkOption.rect = selectionRect; - checkMarkOption.state = checkMarkOption.state & ~QStyle::State_HasFocus; + checkMarkOption.state = checkMarkOption.state & ~State_HasFocus; switch (vopt->checkState) { case Qt::Unchecked: - checkMarkOption.state |= QStyle::State_Off; + checkMarkOption.state |= State_Off; break; case Qt::PartiallyChecked: - checkMarkOption.state |= QStyle::State_NoChange; + checkMarkOption.state |= State_NoChange; break; case Qt::Checked: - checkMarkOption.state |= QStyle::State_On; + checkMarkOption.state |= State_On; break; } - drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget); + drawPrimitive(PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget); } } @@ -1486,7 +1484,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, case CE_TabBarTabShape: if (const QStyleOptionTabV3 *optionTab = qstyleoption_cast<const QStyleOptionTabV3 *>(option)) { QStyleOptionTabV3 optionTabAdj = *optionTab; - const bool isSelected = optionTab->state & QStyle::State_Selected; + const bool isSelected = optionTab->state & State_Selected; const bool directionMirrored = (optionTab->direction == Qt::RightToLeft); QS60StylePrivate::SkinElements skinElement; switch (optionTab->shape) { @@ -1521,9 +1519,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, skinElement==QS60StylePrivate::SE_TabBarTabSouthActive|| skinElement==QS60StylePrivate::SE_TabBarTabWestActive) { const int borderThickness = - QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth); + QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); const int tabOverlap = - QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap) - borderThickness; + QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap) - borderThickness; //todo: draw navi wipe behind tabbar - must be drawn with first draw if (skinElement==QS60StylePrivate::SE_TabBarTabEastInactive|| @@ -1546,9 +1544,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, QStyleOptionTabV3 optionTab = *tab; QRect tr = optionTab.rect; const bool directionMirrored = (optionTab.direction == Qt::RightToLeft); - const int borderThickness = QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth); + const int borderThickness = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); const int tabOverlap = - QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap) - borderThickness; + QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap) - borderThickness; const QRect windowRect = painter->window(); switch (tab->shape) { @@ -1602,12 +1600,12 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, m.rotate(newRotation); painter->setTransform(m, true); } - tr.adjust(0, 0, pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget), - pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget)); + tr.adjust(0, 0, pixelMetric(PM_TabBarTabShiftHorizontal, tab, widget), + pixelMetric(PM_TabBarTabShiftVertical, tab, widget)); if (selected) { - tr.setBottom(tr.bottom() - pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget)); - tr.setRight(tr.right() - pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget)); + tr.setBottom(tr.bottom() - pixelMetric(PM_TabBarTabShiftVertical, tab, widget)); + tr.setRight(tr.right() - pixelMetric(PM_TabBarTabShiftHorizontal, tab, widget)); } int alignment = Qt::AlignCenter | Qt::TextShowMnemonic; @@ -1648,17 +1646,20 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, // busy indicator const QS60StylePrivate::SkinElementFlag orientationFlag = optionProgressBar->orientation == Qt::Horizontal ? QS60StylePrivate::SF_PointNorth : QS60StylePrivate::SF_PointWest; - QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnGrafBarWait, painter, progressRect, flags | orientationFlag); + + QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnGrafBarWaitAnim, + painter, progressRect, flags | orientationFlag | QS60StylePrivate::SF_Animation ); } else { const qreal progressFactor = (optionProgressBar->minimum == optionProgressBar->maximum) ? 1.0 : (qreal)optionProgressBar->progress / optionProgressBar->maximum; + const int frameWidth = pixelMetric(PM_DefaultFrameWidth, option, widget); if (optionProgressBar->orientation == Qt::Horizontal) { progressRect.setWidth(int(progressRect.width() * progressFactor)); if(optionProgressBar->direction == Qt::RightToLeft) - progressRect.translate(optionProgressBar->rect.width()-progressRect.width(), 0); - progressRect.adjust(1, 0, -1, 0); + progressRect.translate(optionProgressBar->rect.width() - progressRect.width(), 0); + progressRect.adjust(frameWidth, 0, -frameWidth, 0); } else { - progressRect.adjust(0, 1, 0, -1); + progressRect.adjust(0, frameWidth, 0, -frameWidth); progressRect.setTop(progressRect.bottom() - int(progressRect.height() * progressFactor)); } @@ -1714,9 +1715,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, QRect textRect = subElementRect(SE_ItemViewItemText, &optionMenuItem, widget); //todo: move the vertical spacing stuff into subElementRect - const int vSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing); + const int vSpacing = QS60StylePrivate::pixelMetric(PM_LayoutVerticalSpacing); if (checkable){ - const int hSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing); + const int hSpacing = QS60StylePrivate::pixelMetric(PM_LayoutHorizontalSpacing); QStyleOptionMenuItem optionCheckBox; optionCheckBox.QStyleOptionMenuItem::operator=(*menuItem); optionCheckBox.rect.setWidth(pixelMetric(PM_IndicatorWidth)); @@ -1754,7 +1755,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, QStyleOptionMenuItem arrowOptions; arrowOptions.QStyleOption::operator=(*menuItem); const int indicatorWidth = (pixelMetric(PM_ListViewIconSize, option, widget) >> 1) + - pixelMetric(QStyle::PM_LayoutVerticalSpacing, option, widget); + pixelMetric(PM_LayoutVerticalSpacing, option, widget); if (optionMenuItem.direction == Qt::LeftToRight) arrowOptions.rect.setLeft(textRect.right()); arrowOptions.rect.setWidth(indicatorWidth); @@ -1925,8 +1926,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, break; case CE_MenuScroller: break; - case CE_FocusFrame: - { + case CE_FocusFrame: { // The pen width should nearly fill the layoutspacings around the widget const int penWidth = qMin(pixelMetric(QS60Style::PM_LayoutVerticalSpacing), pixelMetric(QS60Style::PM_LayoutHorizontalSpacing)) @@ -1985,11 +1985,21 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, */ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const { - Q_D(const QS60Style); const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ? QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled; bool commonStyleDraws = false; switch (element) { + case PE_FrameFocusRect: { + //Draw themed highlight to radiobuttons and checkboxes. + //For other widgets skip, unless palette has been modified. In that case, draw with commonstyle. + if (option->palette.highlight().color() == QS60StylePrivate::themePalette()->highlight().color()) + if ((qstyleoption_cast<const QStyleOptionFocusRect *>(option) && + (qobject_cast<const QRadioButton *>(widget) || qobject_cast<const QCheckBox *>(widget)))) + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, option->rect, flags); + else + commonStyleDraws = true; + } + break; #ifndef QT_NO_LINEEDIT case PE_PanelLineEdit: if (const QStyleOptionFrame *lineEdit = qstyleoption_cast<const QStyleOptionFrame *>(option)) { @@ -2004,15 +2014,14 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti } break; #endif // QT_NO_LINEEDIT - case PE_IndicatorCheckBox: - { + case PE_IndicatorCheckBox: { // Draw checkbox indicator as color skinned graphics. - const QS60StyleEnums::SkinParts skinPart = (option->state & QStyle::State_On) ? + const QS60StyleEnums::SkinParts skinPart = (option->state & State_On) ? QS60StyleEnums::SP_QgnIndiCheckboxOn : QS60StyleEnums::SP_QgnIndiCheckboxOff; painter->save(); - QColor themeColor = QS60StylePrivate::themePalette()->windowText().color(); - QColor windowTextColor = option->palette.windowText().color(); + const QColor themeColor = QS60StylePrivate::themePalette()->windowText().color(); + const QColor windowTextColor = option->palette.windowText().color(); if (themeColor != windowTextColor) painter->setPen(windowTextColor); @@ -2032,7 +2041,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti if (checkBoxVisible && singleSelection) { drawPrimitive(PE_IndicatorCheckBox, option, painter, widget); // ... or normal "tick" selection at the end. - } else if (option->state & QStyle::State_Selected) { + } else if (option->state & State_Selected) { QRect tickRect = option->rect; const int frameBorderWidth = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth); // adjust tickmark rect to exclude frame border @@ -2059,15 +2068,15 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti buttonRect.adjust(0, -newY, -1, -newY); painter->save(); - QColor themeColor = d->s60Color(QS60StyleEnums::CL_QsnTextColors, 6, option); - QColor buttonTextColor = option->palette.buttonText().color(); + const QColor themeColor = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, option); + const QColor buttonTextColor = option->palette.buttonText().color(); if (themeColor != buttonTextColor) painter->setPen(buttonTextColor); else painter->setPen(themeColor); // Draw radiobutton indicator as color skinned graphics. - QS60StyleEnums::SkinParts skinPart = (option->state & QStyle::State_On) ? + QS60StyleEnums::SkinParts skinPart = (option->state & State_On) ? QS60StyleEnums::SP_QgnIndiRadiobuttOn : QS60StyleEnums::SP_QgnIndiRadiobuttOff; QS60StylePrivate::drawSkinPart(skinPart, painter, buttonRect, (flags | QS60StylePrivate::SF_ColorSkinned)); @@ -2077,15 +2086,14 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti case PE_PanelButtonCommand: case PE_PanelButtonTool: case PE_PanelButtonBevel: - case PE_FrameButtonBevel: { + case PE_FrameButtonBevel: if (QS60StylePrivate::canDrawThemeBackground(option->palette.base())) { - const bool isPressed = option->state & QStyle::State_Sunken; + const bool isPressed = option->state & State_Sunken; const QS60StylePrivate::SkinElements skinElement = isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal; QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags); } else { commonStyleDraws = true; - } } break; #ifndef QT_NO_TOOLBUTTON @@ -2207,7 +2215,6 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti break; #ifndef QT_NO_ITEMVIEWS case PE_PanelItemViewItem: - case PE_PanelItemViewRow: // ### Qt 5: remove break; #endif //QT_NO_ITEMVIEWS @@ -2276,7 +2283,23 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti } } break; - + case PE_PanelItemViewRow: // ### Qt 5: remove +#ifndef QT_NO_ITEMVIEWS + if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) { + if (vopt->palette.base().texture().cacheKey() != QS60StylePrivate::m_themePalette->base().texture().cacheKey()) { + //QPalette::Base has been changed, let commonstyle draw the item + commonStyleDraws = true; + } else { + QPalette::ColorGroup cg = vopt->state & State_Enabled ? QPalette::Normal : QPalette::Disabled; + if (cg == QPalette::Normal && !(vopt->state & State_Active)) + cg = QPalette::Inactive; + if (vopt->features & QStyleOptionViewItemV2::Alternate) + painter->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::AlternateBase)); + //apart from alternate base, no background for list item is drawn for S60Style + } + } +#endif + break; case PE_PanelScrollAreaCorner: break; @@ -2361,8 +2384,7 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) sz += QSize(2 * f->lineWidth, 4 * f->lineWidth); break; - case CT_TabBarTab: - { + case CT_TabBarTab: { const QSize naviPaneSize = QS60StylePrivate::naviPaneSize(); sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget); if (naviPaneSize.height() > sz.height()) @@ -2374,8 +2396,26 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, if (QS60StylePrivate::isTouchSupported()) //Make itemview easier to use in touch devices //QCommonStyle does not adjust height with horizontal margin, it only adjusts width - sz.setHeight(sz.height() + 2 * pixelMetric(QStyle::PM_FocusFrameVMargin)); + sz.setHeight(sz.height() + 2 * pixelMetric(PM_FocusFrameVMargin)); break; +#ifndef QT_NO_COMBOBOX + case CT_ComboBox: + if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { + const int frameWidth = cmb->frame ? pixelMetric(PM_ComboBoxFrameWidth, opt, widget) * 2 : 0; + const int textMargins = 2*(pixelMetric(PM_FocusFrameHMargin) + 1); + const int smallestExtraWidth = 23; + // QItemDelegate::sizeHint expands the textMargins two times, thus the 2*textMargins... + const int extra = + qMax(smallestExtraWidth, 2*textMargins + pixelMetric(PM_ScrollBarExtent, opt, widget)); + sz = QSize(sz.width() + frameWidth + extra, sz.height() + frameWidth); + int maxScreenWidth = QApplication::desktop()->availableGeometry().size().width(); + if (sz.width() > maxScreenWidth) { + maxScreenWidth = maxScreenWidth - (extra + frameWidth); + sz.setWidth(maxScreenWidth); + } + } + break; +#endif default: sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); break; @@ -2414,7 +2454,7 @@ int QS60Style::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w retValue = QPalette::Base; break; case SH_ItemView_ActivateItemOnSingleClick: - retValue = true; + retValue = QS60StylePrivate::isSingleClickUi(); break; case SH_ProgressDialog_TextLabelAlignment: retValue = (QApplication::layoutDirection() == Qt::LeftToRight) ? @@ -2526,7 +2566,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { const int frameThickness = spinbox->frame ? pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0; const int buttonMargin = spinbox->frame ? 2 : 0; - const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize) + 2 * buttonMargin; + const int buttonWidth = QS60StylePrivate::pixelMetric(PM_ButtonIconSize) + 2 * buttonMargin; QSize buttonSize; buttonSize.setHeight(qMax(8, spinbox->rect.height() - frameThickness)); //width should at least be equal to height @@ -2575,34 +2615,36 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple ret = cmb->rect; const int width = cmb->rect.width(); const int height = cmb->rect.height(); - const int buttonIconSize = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize); + const int buttonIconSize = QS60StylePrivate::pixelMetric(PM_ButtonIconSize); const int buttonMargin = cmb->frame ? 2 : 0; // lets use spinbox frame here as well, as no combobox specific value available. const int frameThickness = cmb->frame ? pixelMetric(PM_SpinBoxFrameWidth, cmb, widget) : 0; const int buttonWidth = qMax(cmb->rect.height(), buttonIconSize); - const int xposMod = (cmb->rect.x()) + width - buttonMargin - buttonWidth; - const int ypos = cmb->rect.y(); QSize buttonSize; buttonSize.setWidth(buttonWidth + 2 * buttonMargin); buttonSize.setHeight(qMax(8, (cmb->rect.height() >> 1) - frameThickness)); //buttons should be squares buttonSize = buttonSize.expandedTo(QApplication::globalStrut()); switch (scontrol) { - case SC_ComboBoxArrow: + case SC_ComboBoxArrow: { + const int xposMod = cmb->rect.x() + width - buttonMargin - buttonWidth; + const int ypos = cmb->rect.y(); ret.setRect(xposMod, ypos + buttonMargin, buttonWidth, height - 2 * buttonMargin); + } break; case SC_ComboBoxEditField: { - const int withFrameX = cmb->rect.x() + cmb->rect.width() - frameThickness - buttonSize.width(); + const int withFrameX = cmb->rect.x() + width - frameThickness - buttonSize.width(); ret = QRect( frameThickness, frameThickness, withFrameX - frameThickness, - cmb->rect.height() - 2 * frameThickness); + height - 2 * frameThickness); } break; default: break; } + ret = visualRect(cmb->direction, cmb->rect, ret); } break; case CC_GroupBox: @@ -2613,7 +2655,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple case SC_GroupBoxLabel: { //slightly indent text and boxes, so that dialog border does not mess with them. const int horizontalSpacing = - QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing); + QS60StylePrivate::pixelMetric(PM_LayoutHorizontalSpacing); ret.adjust(2, horizontalSpacing - 3, 0, 0); } break; @@ -2668,6 +2710,9 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con { QRect ret; switch (element) { + case SE_RadioButtonFocusRect: + ret = opt->rect; + break; case SE_LineEditContents: { // in S60 the input text box doesn't start from line Edit's TL, but // a bit indented. @@ -2686,9 +2731,9 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) { const int tabOverlapNoBorder = - QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap); + QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap); const int tabOverlap = - tabOverlapNoBorder-QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth); + tabOverlapNoBorder-QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); const QTabWidget *tab = qobject_cast<const QTabWidget *>(widget); int gain = (tab) ? tabOverlap * tab->count() : 0; switch (twf->shape) { @@ -2737,8 +2782,8 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con multiSelection && (vopt->features & QStyleOptionViewItemV2::HasCheckIndicator)) { const int verticalSpacing = - QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing); - //const int horizontalSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing); + QS60StylePrivate::pixelMetric(PM_LayoutVerticalSpacing); + //const int horizontalSpacing = QS60StylePrivate::pixelMetric(PM_LayoutHorizontalSpacing); const int checkBoxRectWidth = subElementRect(SE_ItemViewItemCheckIndicator, opt, widget).width(); ret.adjust(-checkBoxRectWidth - verticalSpacing, 0, -checkBoxRectWidth - verticalSpacing, 0); } @@ -2784,9 +2829,9 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con singleSelection; // Selection check mark rect. - const int indicatorWidth = QS60StylePrivate::pixelMetric(QStyle::PM_IndicatorWidth); - const int indicatorHeight = QS60StylePrivate::pixelMetric(QStyle::PM_IndicatorHeight); - const int spacing = QS60StylePrivate::pixelMetric(QStyle::PM_CheckBoxLabelSpacing); + const int indicatorWidth = QS60StylePrivate::pixelMetric(PM_IndicatorWidth); + const int indicatorHeight = QS60StylePrivate::pixelMetric(PM_IndicatorHeight); + const int spacing = QS60StylePrivate::pixelMetric(PM_CheckBoxLabelSpacing); const int itemHeight = opt->rect.height(); int heightOffset = 0; @@ -2818,6 +2863,25 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con } ret = visualRect(opt->direction, opt->rect, ret); break; + case SE_RadioButtonIndicator: { + const int height = pixelMetric(PM_ExclusiveIndicatorHeight, opt, widget); + ret.setRect(opt->rect.x(), opt->rect.y() + ((opt->rect.height() - height) >> 1), + pixelMetric(PM_ExclusiveIndicatorWidth, opt, widget), height); + ret.translate(2, 0); //move indicator slightly to avoid highlight crossing over it + ret = visualRect(opt->direction, opt->rect, ret); + } + break; + case SE_CheckBoxIndicator: { + const int height = pixelMetric(PM_IndicatorHeight, opt, widget); + ret.setRect(opt->rect.x(), opt->rect.y() + ((opt->rect.height() - height) >> 1), + pixelMetric(PM_IndicatorWidth, opt, widget), height); + ret.translate(2, 0); //move indicator slightly to avoid highlight crossing over it + ret = visualRect(opt->direction, opt->rect, ret); + } + break; + case SE_CheckBoxFocusRect: + ret = opt->rect; + break; default: ret = QCommonStyle::subElementRect(element, opt, widget); } @@ -2835,6 +2899,12 @@ void QS60Style::polish(QWidget *widget) if (!widget) return; + //Currently we only support animations in QProgressBar. +#ifndef QT_NO_PROGRESSBAR + if (qobject_cast<QProgressBar *>(widget)) + widget->installEventFilter(this); +#endif + if (false #ifndef QT_NO_SCROLLBAR || qobject_cast<QScrollBar *>(widget) @@ -2867,6 +2937,8 @@ void QS60Style::polish(QWidget *widget) */ void QS60Style::unpolish(QWidget *widget) { + Q_D(QS60Style); + if (false #ifndef QT_NO_SCROLLBAR || qobject_cast<QScrollBar *>(widget) @@ -2893,6 +2965,14 @@ void QS60Style::unpolish(QWidget *widget) if (widget) widget->setPalette(QPalette()); +#if defined(Q_WS_S60) && !defined(QT_NO_PROGRESSBAR) + if (QProgressBar *bar = qobject_cast<QProgressBar *>(widget)) { + widget->removeEventFilter(this); + d->m_bars.removeAll(bar); + } +#else + Q_UNUSED(d) +#endif QCommonStyle::unpolish(widget); } @@ -2924,10 +3004,23 @@ void QS60Style::unpolish(QApplication *application) bool QS60Style::event(QEvent *e) { #ifdef QT_KEYPAD_NAVIGATION - if (QS60StylePrivate::isTouchSupported()) - return false; Q_D(QS60Style); + const QEvent::Type eventType = e->type(); + if ((eventType == QEvent::FocusIn || + eventType == QEvent::FocusOut || + eventType == QEvent::EnterEditFocus || + eventType == QEvent::LeaveEditFocus) && + QS60StylePrivate::isTouchSupported()) + return false; +#endif + switch (e->type()) { + case QEvent::Timer: { + QTimerEvent *te = static_cast<QTimerEvent*>(e); + timerEvent(te); + } + break; +#ifdef QT_KEYPAD_NAVIGATION case QEvent::FocusIn: if (QWidget *focusWidget = QApplication::focusWidget()) { if (!d->m_focusFrame) @@ -2946,12 +3039,10 @@ bool QS60Style::event(QEvent *e) if (d->m_focusFrame) d->m_focusFrame->update(); break; +#endif default: break; } -#else - Q_UNUSED(e) -#endif return false; } @@ -2961,7 +3052,7 @@ bool QS60Style::event(QEvent *e) QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const { - const int iconDimension = QS60StylePrivate::pixelMetric(QStyle::PM_ToolBarIconSize); + const int iconDimension = QS60StylePrivate::pixelMetric(PM_ToolBarIconSize); const QRect iconSize = (!option) ? QRect(0, 0, iconDimension, iconDimension) : option->rect; QS60StyleEnums::SkinParts part; QS60StylePrivate::SkinElementFlags adjustedFlags; @@ -2971,67 +3062,67 @@ QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon, QS60StylePrivate::SF_StateDisabled; switch(standardIcon) { - case QStyle::SP_MessageBoxWarning: + case SP_MessageBoxWarning: part = QS60StyleEnums::SP_QgnNoteWarning; break; - case QStyle::SP_MessageBoxInformation: + case SP_MessageBoxInformation: part = QS60StyleEnums::SP_QgnNoteInfo; break; - case QStyle::SP_MessageBoxCritical: + case SP_MessageBoxCritical: part = QS60StyleEnums::SP_QgnNoteError; break; - case QStyle::SP_MessageBoxQuestion: + case SP_MessageBoxQuestion: part = QS60StyleEnums::SP_QgnNoteQuery; break; - case QStyle::SP_ArrowRight: + case SP_ArrowRight: part = QS60StyleEnums::SP_QgnIndiNaviArrowRight; break; - case QStyle::SP_ArrowLeft: + case SP_ArrowLeft: part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft; break; - case QStyle::SP_ArrowUp: + case SP_ArrowUp: part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft; adjustedFlags |= QS60StylePrivate::SF_PointEast; break; - case QStyle::SP_ArrowDown: + case SP_ArrowDown: part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft; adjustedFlags |= QS60StylePrivate::SF_PointWest; break; - case QStyle::SP_ArrowBack: + case SP_ArrowBack: if (QApplication::layoutDirection() == Qt::RightToLeft) return QS60Style::standardIcon(SP_ArrowRight, option, widget); return QS60Style::standardIcon(SP_ArrowLeft, option, widget); - case QStyle::SP_ArrowForward: + case SP_ArrowForward: if (QApplication::layoutDirection() == Qt::RightToLeft) return QS60Style::standardIcon(SP_ArrowLeft, option, widget); return QS60Style::standardIcon(SP_ArrowRight, option, widget); - case QStyle::SP_ComputerIcon: + case SP_ComputerIcon: part = QS60StyleEnums::SP_QgnPropPhoneMemcLarge; break; - case QStyle::SP_DirClosedIcon: + case SP_DirClosedIcon: part = QS60StyleEnums::SP_QgnPropFolderSmall; break; - case QStyle::SP_DirOpenIcon: + case SP_DirOpenIcon: part = QS60StyleEnums::SP_QgnPropFolderCurrent; break; - case QStyle::SP_DirIcon: + case SP_DirIcon: part = QS60StyleEnums::SP_QgnPropFolderSmall; break; - case QStyle::SP_FileDialogNewFolder: + case SP_FileDialogNewFolder: part = QS60StyleEnums::SP_QgnPropFolderSmallNew; break; - case QStyle::SP_FileIcon: + case SP_FileIcon: part = QS60StyleEnums::SP_QgnPropFileSmall; break; - case QStyle::SP_TrashIcon: + case SP_TrashIcon: part = QS60StyleEnums::SP_QgnNoteErased; break; - case QStyle::SP_ToolBarHorizontalExtensionButton: + case SP_ToolBarHorizontalExtensionButton: part = QS60StyleEnums::SP_QgnIndiSubMenu; if (QApplication::layoutDirection() == Qt::RightToLeft) adjustedFlags |= QS60StylePrivate::SF_PointSouth; break; - case QStyle::SP_ToolBarVerticalExtensionButton: + case SP_ToolBarVerticalExtensionButton: adjustedFlags |= QS60StylePrivate::SF_PointEast; part = QS60StyleEnums::SP_QgnIndiSubMenu; break; @@ -3045,6 +3136,72 @@ QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon, QCommonStyle::standardIconImplementation(standardIcon, option, widget) : QIcon(cachedPixMap); } +/*! + \internal + Animate indeterminate progress bars only when visible +*/ +bool QS60Style::eventFilter(QObject *object, QEvent *event) +{ +#ifdef Q_WS_S60 +#ifndef QT_NO_PROGRESSBAR + Q_D(QS60Style); + switch(event->type()) { + case QEvent::StyleChange: + case QEvent::Show: + if (QProgressBar *bar = qobject_cast<QProgressBar *>(object)) { + if (!d->m_bars.contains(bar)) + d->m_bars << bar; + if (d->m_bars.size() == 1) //only start with first animated progressbar + d->startAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); + } + break; + case QEvent::Destroy: + case QEvent::Hide: + d->stopAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); + d->m_bars.removeAll(reinterpret_cast<QProgressBar *>(object)); + break; + default: + break; + } +#endif // QT_NO_PROGRESSBAR +#endif // Q_WS_S60 + return QStyle::eventFilter(object, event); +} + +/*! + \internal + Handle the timer \a event. +*/ +void QS60Style::timerEvent(QTimerEvent *event) +{ +#ifdef Q_WS_S60 +#ifndef QT_NO_PROGRESSBAR + Q_D(QS60Style); + + QS60StyleAnimation *progressBarAnimation = + QS60StylePrivate::animationDefinition(QS60StyleEnums::SP_QgnGrafBarWaitAnim); + + if (event->timerId() == progressBarAnimation->timerId()) { + + Q_ASSERT(progressBarAnimation->interval() > 0); + + if (progressBarAnimation->currentFrame() == progressBarAnimation->frameCount() ) + if (progressBarAnimation->playMode() == QS60StyleEnums::AM_Looping) + progressBarAnimation->setCurrentFrame(0); + else + d->stopAnimation(progressBarAnimation->animationId()); + + foreach (QProgressBar *bar, d->m_bars) { + if ((bar->minimum() == 0 && bar->maximum() == 0)) + bar->update(); + } + progressBarAnimation->setCurrentFrame(progressBarAnimation->currentFrame() + 1); + } +#endif // QT_NO_PROGRESSBAR +#endif // Q_WS_S60 + event->ignore(); +} + extern QPoint qt_s60_fill_background_offset(const QWidget *targetWidget); bool qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush) diff --git a/src/gui/styles/qs60style.h b/src/gui/styles/qs60style.h index adcb313..82cc21c 100644 --- a/src/gui/styles/qs60style.h +++ b/src/gui/styles/qs60style.h @@ -94,6 +94,9 @@ protected Q_SLOTS: QIcon standardIconImplementation( StandardPixmap standardIcon, const QStyleOption * option = 0, const QWidget * widget = 0 ) const; +protected: + void timerEvent(QTimerEvent *event); + bool eventFilter(QObject *o, QEvent *e); private: Q_DISABLE_COPY(QS60Style) friend class QStyleFactory; diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index 1417552..eae2291 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -74,7 +74,6 @@ typedef struct { unsigned short width; int major_version; int minor_version; - bool mirroring; // TODO: (nice to have) Use Qt::LayoutDirection const char* layoutName; } layoutHeader; @@ -93,6 +92,29 @@ class QS60StyleEnums #endif // !Q_WS_S60 public: + + // S60 definitions within theme + enum ThemeDefinitions { + TD_AnimationData, + }; + + //Defines which values are contained within animation data (retrieved using TD_AnimationData). + //Additionally defines the order in which the items are given out in QList<QVariant>. + enum AnimationData { + AD_Interval = 0, + AD_NumberOfFrames, + AD_AnimationPlayMode, //currently not used as themes seem to contain invalid data + }; + + // Animation modes + enum AnimationMode { + AM_PlayOnce = 0, //animation is played exactly once + AM_Looping, //animation is repeated until stopped + AM_Bounce //animation is played repeatedly until stopped, + //but frames are played in reverse order every second time + //(no support yet) + }; + // S60 look-and-feel font categories enum FontCategories { FC_Undefined, @@ -104,7 +126,7 @@ public: }; enum SkinParts { - SP_QgnGrafBarWait, + SP_QgnGrafBarWaitAnim, SP_QgnGrafBarFrameCenter, SP_QgnGrafBarFrameSideL, SP_QgnGrafBarFrameSideR, @@ -287,7 +309,70 @@ public: }; }; +#ifdef Q_WS_S60 +class CAknBitmapAnimation; +NONSHARABLE_CLASS (AnimationData) : public QObject +{ +public: + AnimationData(const QS60StyleEnums::SkinParts part, int frames, int interval); + + const QS60StyleEnums::SkinParts m_id; + int m_frames; + int m_interval; + QS60StyleEnums::AnimationMode m_mode; +}; + + +NONSHARABLE_CLASS (AnimationDataV2) : public AnimationData +{ +public: + AnimationDataV2(const AnimationData &data); + ~AnimationDataV2(); + + CAknBitmapAnimation *m_animation; + int m_currentFrame; + bool m_resourceBased; + int m_timerId; +}; + + +class QS60StyleAnimation : public QObject +{ +public: + QS60StyleAnimation(const QS60StyleEnums::SkinParts part, int frames, int interval); + ~QS60StyleAnimation(); + +public: + QS60StyleEnums::SkinParts animationId() const {return m_currentData->m_id;} + int frameCount() const { return m_currentData->m_frames;} + int interval() const {return m_currentData->m_interval;} + QS60StyleEnums::AnimationMode playMode() const {return m_currentData->m_mode;} + CAknBitmapAnimation* animationObject() const {return m_currentData->m_animation;} + bool isResourceBased() const {return m_currentData->m_resourceBased;} + int timerId() const {return m_currentData->m_timerId;} + int currentFrame() const {return m_currentData->m_currentFrame;} + + void setFrameCount(int frameCount) {m_currentData->m_frames = frameCount;} + void setInterval(int interval) {m_currentData->m_interval = interval;} + void setAnimationObject(CAknBitmapAnimation* animation); + void setResourceBased(bool resourceBased) {m_currentData->m_resourceBased = resourceBased;} + void setTimerId(int timerId) {m_currentData->m_timerId = timerId;} + void setCurrentFrame(int currentFrame) {m_currentData->m_currentFrame = currentFrame;} + + void resetToDefaults(); + +private: //data members + //TODO: consider changing these to non-pointers as the classes are rather small anyway + AnimationData *m_defaultData; + AnimationDataV2 *m_currentData; +}; + +#endif //Q_WS_S60 + + class QFocusFrame; +class QProgressBar; +class QS60StyleAnimation; // Private class #ifdef Q_OS_SYMBIAN @@ -371,6 +456,7 @@ public: SF_StateEnabled = 0x0010, // Enabled = the default SF_StateDisabled = 0x0020, SF_ColorSkinned = 0x0040, // pixmap is colored with foreground pen color + SF_Animation = 0x0080, }; enum CacheClearReason { @@ -412,6 +498,7 @@ public: static bool isTouchSupported(); static bool isToolBarBackground(); static bool hasSliderGrooveGraphic(); + static bool isSingleClickUi(); // calculates average color based on button skin graphics (minus borders). QColor colorFromFrameGraphics(SkinFrameElements frame) const; @@ -455,6 +542,16 @@ public: //so that theme graphic background can be drawn. static bool canDrawThemeBackground(const QBrush &backgroundBrush); + static int currentAnimationFrame(QS60StyleEnums::SkinParts part); +#ifdef Q_WS_S60 + + //No support for animations on emulated style + void startAnimation(QS60StyleEnums::SkinParts animation); + void stopAnimation(QS60StyleEnums::SkinParts animation); + static QS60StyleAnimation* animationDefinition(QS60StyleEnums::SkinParts part); + +#endif + private: static void drawPart(QS60StyleEnums::SkinParts part, QPainter *painter, const QRect &rect, SkinElementFlags flags = KDefaultSkinElementFlags); @@ -497,6 +594,12 @@ private: QPalette m_originalPalette; QPointer<QFocusFrame> m_focusFrame; + +#ifdef Q_WS_S60 + //list of progress bars having animation running + QList<QProgressBar *> m_bars; +#endif + }; QT_END_NAMESPACE diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index 9d2dc66..6d9ba05 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -63,6 +63,7 @@ #include <aknutils.h> #include <aknnavi.h> #include <gulicon.h> +#include <AknBitmapAnimation.h> #if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN) @@ -72,6 +73,7 @@ enum TDrawType { EDrawIcon, EDrawGulIcon, EDrawBackground, + EDrawAnimation, ENoDraw }; @@ -97,6 +99,47 @@ typedef struct { int newMinorSkinId; } partMapEntry; +AnimationData::AnimationData(const QS60StyleEnums::SkinParts part, int frames, int interval) : m_id(part), + m_frames(frames), m_interval(interval), m_mode(QS60StyleEnums::AM_Looping) +{ +} + +AnimationDataV2::AnimationDataV2(const AnimationData &data) : AnimationData(data.m_id, data.m_frames, data.m_interval), + m_animation(0), m_currentFrame(0), m_resourceBased(false), m_timerId(0) +{ +} +AnimationDataV2::~AnimationDataV2() +{ + delete m_animation; +} + +QS60StyleAnimation::QS60StyleAnimation(const QS60StyleEnums::SkinParts part, int frames, int interval) +{ + QT_TRAP_THROWING(m_defaultData = new (ELeave) AnimationData(part, frames, interval)); + QT_TRAP_THROWING(m_currentData = new (ELeave) AnimationDataV2(*m_defaultData)); +} + +QS60StyleAnimation::~QS60StyleAnimation() +{ + delete m_currentData; + delete m_defaultData; +} + +void QS60StyleAnimation::setAnimationObject(CAknBitmapAnimation* animation) +{ + Q_ASSERT(animation); + if (m_currentData->m_animation) + delete m_currentData->m_animation; + m_currentData->m_animation = animation; +} + +void QS60StyleAnimation::resetToDefaults() +{ + delete m_currentData; + m_currentData = 0; + QT_TRAP_THROWING(m_currentData = new (ELeave) AnimationDataV2(*m_defaultData)); +} + class QS60StyleModeSpecifics { public: @@ -113,6 +156,8 @@ public: static QSize naviPaneSize(); static TAknsItemID partSpecificThemeId(int part); + static QVariant themeDefinition(QS60StyleEnums::ThemeDefinitions definition, QS60StyleEnums::SkinParts part); + private: static QPixmap createSkinnedGraphicsLX(QS60StyleEnums::SkinParts part, const QSize &size, QS60StylePrivate::SkinElementFlags flags); @@ -128,7 +173,7 @@ private: }; const partMapEntry QS60StyleModeSpecifics::m_partMap[] = { - /* SP_QgnGrafBarWait */ {KAknsIIDQgnGrafBarWaitAnim, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnGrafBarWaitAnim */ {KAknsIIDQgnGrafBarWaitAnim, EDrawAnimation, ES60_All, -1,-1}, /* SP_QgnGrafBarFrameCenter */ {KAknsIIDQgnGrafBarFrameCenter, EDrawIcon, ES60_All, -1,-1}, /* SP_QgnGrafBarFrameSideL */ {KAknsIIDQgnGrafBarFrameSideL, EDrawIcon, ES60_All, -1,-1}, /* SP_QgnGrafBarFrameSideR */ {KAknsIIDQgnGrafBarFrameSideR, EDrawIcon, ES60_All, -1,-1}, @@ -371,7 +416,7 @@ QPixmap QS60StyleModeSpecifics::colorSkinnedGraphics( void QS60StyleModeSpecifics::fallbackInfo(const QS60StyleEnums::SkinParts &stylePart, TInt &fallbackIndex) { switch(stylePart) { - case QS60StyleEnums::SP_QgnGrafBarWait: + case QS60StyleEnums::SP_QgnGrafBarWaitAnim: fallbackIndex = EMbmAvkonQgn_graf_bar_wait_1; break; case QS60StyleEnums::SP_QgnGrafBarFrameCenter: @@ -604,6 +649,11 @@ bool QS60StylePrivate::hasSliderGrooveGraphic() return QSysInfo::s60Version() != QSysInfo::SV_S60_3_1; } +bool QS60StylePrivate::isSingleClickUi() +{ + return (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0); +} + QPoint qt_s60_fill_background_offset(const QWidget *targetWidget) { CCoeControl *control = targetWidget->effectiveWinId(); @@ -709,6 +759,69 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX( // QS60WindowSurface::lockBitmapHeap(); break; } + case EDrawAnimation: { + CFbsBitmap* animationFrame; + CFbsBitmap* frameMask; + CAknBitmapAnimation* aknAnimation = 0; + TBool constructedFromTheme = ETrue; + + QS60StyleAnimation* animation = QS60StylePrivate::animationDefinition(part); //ownership is not passed + if (animation) { + if (!animation->animationObject() && !animation->isResourceBased()) {// no pre-made item exists, create new animation + CAknBitmapAnimation* newAnimation = CAknBitmapAnimation::NewL(); + CleanupStack::PushL(newAnimation); + if (newAnimation) + constructedFromTheme = newAnimation->ConstructFromSkinL(skinId); + if (constructedFromTheme && newAnimation->BitmapAnimData()->FrameArray().Count() > 0) { + animation->setResourceBased(false); + animation->setAnimationObject(newAnimation); //animation takes ownership + } + CleanupStack::Pop(newAnimation); + } + //fill-in stored information + aknAnimation = animation->animationObject(); + constructedFromTheme = !animation->isResourceBased(); + } + + const int currentFrame = QS60StylePrivate::currentAnimationFrame(part); + if (constructedFromTheme && aknAnimation && aknAnimation->BitmapAnimData()->FrameArray().Count() > 0) { + //Animation was created succesfully and contains frames, just fetch current frame + if(currentFrame >= aknAnimation->BitmapAnimData()->FrameArray().Count()) + User::Leave(KErrOverflow); + const CBitmapFrameData* frameData = aknAnimation->BitmapAnimData()->FrameArray().At(currentFrame); + if (frameData) { + animationFrame = frameData->Bitmap(); + frameMask = frameData->Mask(); + } + } else { + //Theme does not contain animation theming, create frames from resource file + TInt fallbackGraphicID = -1; + fallbackInfo(part, fallbackGraphicID); + fallbackGraphicID = fallbackGraphicID + (currentFrame * 2); //skip masks + TInt fallbackGraphicsMaskID = + (fallbackGraphicID == KErrNotFound) ? KErrNotFound : fallbackGraphicID + 1; //masks are auto-generated as next in mif files + if (fallbackGraphicsMaskID != KErrNotFound) + fallbackGraphicsMaskID = fallbackGraphicsMaskID + (currentFrame * 2); //skip actual graphics + + //Then draw animation frame + AknsUtils::CreateIconL( + skinInstance, + KAknsIIDDefault, //animation is not themed, lets force fallback graphics + animationFrame, + frameMask, + AknIconUtils::AvkonIconFileName(), + fallbackGraphicID , + fallbackGraphicsMaskID); + } + result = fromFbsBitmap(animationFrame, frameMask, flags, targetSize); + if (!constructedFromTheme) { + delete animationFrame; + animationFrame = 0; + delete frameMask; + frameMask = 0; + } + break; + } } if (!result) result = QPixmap(); @@ -984,8 +1097,13 @@ void QS60StylePrivate::setActiveLayout() m_pmPointer = data[activeLayoutIndex]; } +Q_GLOBAL_STATIC(QList<QS60StyleAnimation *>, m_animations) + QS60StylePrivate::QS60StylePrivate() { + //Animation defaults need to be created when style is instantiated + QS60StyleAnimation* progressBarAnimation = new QS60StyleAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim, 7, 100); + m_animations()->append(progressBarAnimation); // No need to set active layout, if dynamic metrics API is available setActiveLayout(); } @@ -1186,6 +1304,11 @@ void QS60StylePrivate::handleSkinChange() setThemePalette(topLevelWidget); topLevelWidget->ensurePolished(); } +#ifndef QT_NO_PROGRESSBAR + //re-start animation timer + stopAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); //todo: once we have more animations, we could say "stop all running ones" + startAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); //and "re-start all previously running ones" +#endif } QSize QS60StylePrivate::naviPaneSize() @@ -1205,6 +1328,121 @@ QSize QS60StyleModeSpecifics::naviPaneSize() return QSize(0,0); } +int QS60StylePrivate::currentAnimationFrame(QS60StyleEnums::SkinParts part) +{ + QS60StyleAnimation *animation = animationDefinition(part); + // todo: looping could be done in QS60Style::timerEvent + if (animation->frameCount() == animation->currentFrame()) + animation->setCurrentFrame(0); + return animation->currentFrame(); +} + +QS60StyleAnimation* QS60StylePrivate::animationDefinition(QS60StyleEnums::SkinParts part) +{ + int i = 0; + const int animationsCount = m_animations()->isEmpty() ? 0 : m_animations()->count(); + for(; i < animationsCount; i++) { + if (part == m_animations()->at(i)->animationId()) + break; + } + return m_animations()->at(i); +} + +void QS60StylePrivate::startAnimation(QS60StyleEnums::SkinParts animationPart) +{ + Q_Q(QS60Style); + + //Query animation data from theme and store values to local struct. + QVariant themeAnimationDataVariant = QS60StyleModeSpecifics::themeDefinition( + QS60StyleEnums::TD_AnimationData, animationPart); + QList<QVariant> themeAnimationData = themeAnimationDataVariant.toList(); + + QS60StyleAnimation *animation = QS60StylePrivate::animationDefinition(animationPart); + if (animation) { + if (themeAnimationData.at(QS60StyleEnums::AD_Interval).toInt() != 0) + animation->setInterval(themeAnimationData.at(QS60StyleEnums::AD_Interval).toInt()); + + if (themeAnimationData.at(QS60StyleEnums::AD_NumberOfFrames).toInt() != 0) + animation->setFrameCount(themeAnimationData.at(QS60StyleEnums::AD_NumberOfFrames).toInt()); + + //todo: playmode is ignored for now, since it seems to return invalid data on some themes + //lets use the table values for play mode + + animation->setCurrentFrame(0); //always initialize + const int timerId = q->startTimer(animation->interval()); + animation->setTimerId(timerId); + } +} + +void QS60StylePrivate::stopAnimation(QS60StyleEnums::SkinParts animationPart) +{ + Q_Q(QS60Style); + + QS60StyleAnimation *animation = QS60StylePrivate::animationDefinition(animationPart); + if (animation) { + animation->setCurrentFrame(0); + if (animation->timerId() != 0) { + q->killTimer(animation->timerId()); + animation->setTimerId(0); + } + animation->resetToDefaults(); + } +} + +QVariant QS60StyleModeSpecifics::themeDefinition( + QS60StyleEnums::ThemeDefinitions definition, QS60StyleEnums::SkinParts part) +{ + MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); + + Q_ASSERT(skinInstance); + + switch(definition) { + //Animation definitions + case QS60StyleEnums::TD_AnimationData: + { + CAknsBmpAnimItemData *animationData; + TAknsItemID animationSkinId = partSpecificThemeId(part); + QList<QVariant> list; + + TRAPD( error, QT_TRYCATCH_LEAVING( + animationData = static_cast<CAknsBmpAnimItemData*>(skinInstance->CreateUncachedItemDataL( + animationSkinId, EAknsITBmpAnim)))); + if (error) + return list; + + if (animationData) { + list.append((int)animationData->FrameInterval()); + list.append((int)animationData->NumberOfImages()); + + QS60StyleEnums::AnimationMode playMode; + switch(animationData->PlayMode()) { + case CBitmapAnimClientData::EPlay: + playMode = QS60StyleEnums::AM_PlayOnce; + break; + case CBitmapAnimClientData::ECycle: + playMode = QS60StyleEnums::AM_Looping; + break; + case CBitmapAnimClientData::EBounce: + playMode = QS60StyleEnums::AM_Bounce; + break; + default: + break; + } + list.append(QVariant((int)playMode)); + delete animationData; + } else { + list.append(0); + list.append(0); + } + return list; + } + break; + default: + break; + } + return QVariant(); +} + #endif // Q_WS_S60 QT_END_NAMESPACE diff --git a/src/gui/styles/qs60style_simulated.cpp b/src/gui/styles/qs60style_simulated.cpp index bd43eb7..f87cf28 100644 --- a/src/gui/styles/qs60style_simulated.cpp +++ b/src/gui/styles/qs60style_simulated.cpp @@ -342,6 +342,11 @@ bool QS60StylePrivate::hasSliderGrooveGraphic() return false; } +bool QS60StylePrivate::isSingleClickUi() +{ + return false; +} + QFont QS60StylePrivate::s60Font_specific( QS60StyleEnums::FontCategories fontCategory, int pointSize, bool resolveFontSize) @@ -364,6 +369,11 @@ QFont QS60StylePrivate::s60Font_specific( return result; } +int QS60StylePrivate::currentAnimationFrame(QS60StyleEnums::SkinParts part) +{ + return 0; +} + /*! Constructs a QS60Style object. */ diff --git a/src/gui/styles/qstyle_s60.qrc b/src/gui/styles/qstyle_s60.qrc new file mode 100644 index 0000000..dbee38b --- /dev/null +++ b/src/gui/styles/qstyle_s60.qrc @@ -0,0 +1,137 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="/trolltech/styles/commonstyle"> +<!-- <file>images/filelink-16.png</file> --> +<file>images/filelink-32.png</file> +<!-- <file>images/filelink-128.png</file> --> +<!-- <file>images/file-16.png</file> --> +<file>images/file-32.png</file> +<!-- <file>images/file-128.png</file> --> +<!-- <file>images/newdirectory-16.png</file> --> +<file>images/newdirectory-32.png</file> +<!-- <file>images/newdirectory-128.png</file> --> +<!-- <file>images/parentdir-16.png</file> --> +<file>images/parentdir-32.png</file> +<!-- <file>images/parentdir-128.png</file> --> +<!-- <file>images/dvd-16.png</file> --> +<!-- <file>images/dvd-32.png</file> --> +<!-- <file>images/dvd-128.png</file> --> +<!-- <file>images/cdr-16.png</file> --> +<!-- <file>images/cdr-32.png</file> --> +<!-- <file>images/cdr-128.png</file> --> +<!-- <file>images/floppy-16.png</file> --> +<!-- <file>images/floppy-32.png</file> --> +<!-- <file>images/floppy-128.png</file> --> +<!-- <file>images/harddrive-16.png</file> --> +<file>images/harddrive-32.png</file> +<!-- <file>images/harddrive-128.png</file> --> +<!-- <file>images/trash-16.png</file> --> +<!-- <file>images/trash-32.png</file> --> +<!-- <file>images/trash-128.png</file> --> +<!-- <file>images/networkdrive-16.png</file> --> +<!-- <file>images/networkdrive-32.png</file> --> +<!-- <file>images/networkdrive-128.png</file> --> +<!-- <file>images/computer-16.png</file> --> +<!-- <file>images/computer-32.png</file> --> +<!-- <file>images/desktop-16.png</file> --> +<file>images/desktop-32.png</file> +<!-- <file>images/dirclosed-16.png</file> --> +<file>images/dirclosed-32.png</file> +<!-- <file>images/dirclosed-128.png</file> --> +<!-- <file>images/dirlink-16.png</file> --> +<file>images/dirlink-32.png</file> +<!-- <file>images/dirlink-128.png</file> --> +<!-- <file>images/diropen-16.png</file> --> +<file>images/diropen-32.png</file> +<!-- <file>images/diropen-128.png</file> --> +<!-- <file>images/left-16.png</file> --> +<file>images/left-32.png</file> +<!-- <file>images/left-128.png</file> --> +<!-- <file>images/right-16.png</file> --> +<file>images/right-32.png</file> +<!-- <file>images/right-128.png</file> --> +<!-- <file>images/up-16.png</file> --> +<file>images/up-32.png</file> +<!-- <file>images/up-128.png</file> --> +<!-- <file>images/down-16.png</file> --> +<file>images/down-32.png</file> +<!-- <file>images/down-128.png</file> --> +<!-- <file>images/filecontents-16.png</file> --> +<file>images/filecontents-32.png</file> +<!-- <file>images/filecontents-128.png</file> --> +<!-- <file>images/fileinfo-16.png</file> --> +<file>images/fileinfo-32.png</file> +<!-- <file>images/fileinfo-128.png</file> --> +<!-- <file>images/viewdetailed-16.png</file> --> +<file>images/viewdetailed-32.png</file> +<!-- <file>images/viewdetailed-128.png</file> --> +<!-- <file>images/viewlist-16.png</file> --> +<file>images/viewlist-32.png</file> +<!-- <file>images/viewlist-128.png</file> --> +<file>images/fontbitmap-16.png</file> +<file>images/fonttruetype-16.png</file> +<!-- <file>images/standardbutton-apply-128.png</file> --> +<!-- <file>images/standardbutton-apply-16.png</file> --> +<file>images/standardbutton-apply-32.png</file> +<!-- <file>images/standardbutton-cancel-128.png</file> --> +<!-- <file>images/standardbutton-cancel-16.png</file> --> +<file>images/standardbutton-cancel-32.png</file> +<!-- <file>images/standardbutton-clear-128.png</file> --> +<!-- <file>images/standardbutton-clear-16.png</file> --> +<file>images/standardbutton-clear-32.png</file> +<!-- <file>images/standardbutton-close-128.png</file> --> +<!-- <file>images/standardbutton-close-16.png</file> --> +<file>images/standardbutton-close-32.png</file> +<!-- <file>images/standardbutton-delete-128.png</file> --> +<!-- <file>images/standardbutton-delete-16.png</file> --> +<file>images/standardbutton-delete-32.png</file> +<!-- <file>images/standardbutton-help-128.png</file> --> +<!-- <file>images/standardbutton-help-16.png</file> --> +<file>images/standardbutton-help-32.png</file> +<!-- <file>images/standardbutton-no-128.png</file> --> +<!-- <file>images/standardbutton-no-16.png</file> --> +<file>images/standardbutton-no-32.png</file> +<!-- <file>images/standardbutton-ok-128.png</file> --> +<!-- <file>images/standardbutton-ok-16.png</file> --> +<file>images/standardbutton-ok-32.png</file> +<!-- <file>images/standardbutton-open-128.png</file> --> +<!-- <file>images/standardbutton-open-16.png</file> --> +<file>images/standardbutton-open-32.png</file> +<!-- <file>images/standardbutton-save-128.png</file> --> +<!-- <file>images/standardbutton-save-16.png</file> --> +<file>images/standardbutton-save-32.png</file> +<!-- <file>images/standardbutton-yes-128.png</file> --> +<!-- <file>images/standardbutton-yes-16.png</file> --> +<file>images/standardbutton-yes-32.png</file> +<file>images/standardbutton-closetab-16.png</file> +<file>images/standardbutton-closetab-down-16.png</file> +<file>images/standardbutton-closetab-hover-16.png</file> +<!-- <file>images/refresh-24.png</file> --> +<file>images/refresh-32.png</file> +<!-- <file>images/stop-24.png</file> --> +<file>images/stop-32.png</file> +<!-- <file>images/media-stop-16.png</file> --> +<file>images/media-stop-32.png</file> +<!-- <file>images/media-play-16.png</file> --> +<file>images/media-play-32.png</file> +<!-- <file>images/media-pause-16.png</file> --> +<file>images/media-pause-32.png</file> +<!-- <file>images/media-seek-forward-16.png</file> --> +<file>images/media-seek-forward-32.png</file> +<!-- <file>images/media-seek-backward-16.png</file> --> +<file>images/media-seek-backward-32.png</file> +<!-- <file>images/media-skip-forward-16.png</file> --> +<file>images/media-skip-forward-32.png</file> +<!-- <file>images/media-skip-backward-16.png</file> --> +<file>images/media-skip-backward-32.png</file> +<file>images/media-volume-16.png</file> +<file>images/media-volume-muted-16.png</file> +</qresource> +<!-- +<qresource prefix="/trolltech/styles/macstyle"> +<file>images/closedock-16.png</file> +<file>images/closedock-down-16.png</file> +<file>images/dockdock-16.png</file> +<file>images/dockdock-down-16.png</file> +</qresource> +--> +</RCC> diff --git a/src/gui/styles/styles.pri b/src/gui/styles/styles.pri index 7e5c55a..676f59e 100644 --- a/src/gui/styles/styles.pri +++ b/src/gui/styles/styles.pri @@ -23,10 +23,12 @@ SOURCES += \ styles/qstylesheetstyle.cpp \ styles/qstylesheetstyle_default.cpp -!wince* { - RESOURCES += styles/qstyle.qrc +wince* { + RESOURCES += styles/qstyle_wince.qrc +} else:symbian { + RESOURCES += styles/qstyle_s60.qrc } else { - RESOURCES += styles/qstyle_wince.qrc + RESOURCES += styles/qstyle.qrc } contains( styles, all ) { @@ -168,7 +170,7 @@ contains( styles, s60 ):contains(QT_CONFIG, s60) { SOURCES += styles/qs60style.cpp symbian { SOURCES += styles/qs60style_s60.cpp - LIBS += -laknicon -laknskins -laknskinsrv -lfontutils -legul + LIBS += -laknicon -laknskins -laknskinsrv -lfontutils -legul -lbmpanim } else { SOURCES += styles/qs60style_simulated.cpp RESOURCES += styles/qstyle_s60_simulated.qrc diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 9343cb7..c000457 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -357,9 +357,6 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform ++i; } } else { - positions.resize(glyphs.numGlyphs); - glyphs_out.resize(glyphs.numGlyphs); - int i = 0; while (i < glyphs.numGlyphs) { if (!glyphs.attributes[i].dontPrint) { QFixed gpos_x = xpos + glyphs.offsets[i].x; diff --git a/src/gui/text/qtextoption.cpp b/src/gui/text/qtextoption.cpp index 0c8aeec..c1e254c 100644 --- a/src/gui/text/qtextoption.cpp +++ b/src/gui/text/qtextoption.cpp @@ -52,6 +52,9 @@ struct QTextOptionPrivate /*! Constructs a text option with default properties for text. + The text alignment property is set to Qt::AlignLeft. The + word wrap property is set to QTextOption::WordWrap. The + using of design metrics flag is set to false. */ QTextOption::QTextOption() : align(Qt::AlignLeft), @@ -67,6 +70,8 @@ QTextOption::QTextOption() /*! Constructs a text option with the given \a alignment for text. + The word wrap property is set to QTextOption::WordWrap. The using + of design metrics flag is set to false. */ QTextOption::QTextOption(Qt::Alignment alignment) : align(alignment), diff --git a/src/gui/util/qsystemtrayicon_mac.mm b/src/gui/util/qsystemtrayicon_mac.mm index ae805f6..0265a83 100644 --- a/src/gui/util/qsystemtrayicon_mac.mm +++ b/src/gui/util/qsystemtrayicon_mac.mm @@ -569,16 +569,3 @@ private: } @end - -/* Done here because this is the only .mm for now! -Sam */ -QMacCocoaAutoReleasePool::QMacCocoaAutoReleasePool() -{ - NSApplicationLoad(); - pool = (void*)[[NSAutoreleasePool alloc] init]; -} - -QMacCocoaAutoReleasePool::~QMacCocoaAutoReleasePool() -{ - [(NSAutoreleasePool*)pool release]; -} - diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index 414c2ed..b0a64ea 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -524,8 +524,11 @@ void QLineControl::draw(QPainter *painter, const QPoint &offset, const QRect &cl m_textLayout.draw(painter, offset, selections, clip); if (flags & DrawCursor){ + int cursor = m_cursor; + if (m_preeditCursor != -1) + cursor += m_preeditCursor; if(!m_blinkPeriod || m_blinkStatus) - m_textLayout.drawCursor(painter, offset, m_cursor, m_cursorWidth); + m_textLayout.drawCursor(painter, offset, cursor, m_cursorWidth); } } diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h index 301ff72..d6f2705 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -549,7 +549,10 @@ inline qreal QLineControl::cursorToX(int cursor) const inline qreal QLineControl::cursorToX() const { - return cursorToX(m_cursor); + int cursor = m_cursor; + if (m_preeditCursor != -1) + cursor += m_preeditCursor; + return cursorToX(cursor); } inline bool QLineControl::isReadOnly() const diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm index ee79f5a..d92168a 100644 --- a/src/gui/widgets/qmainwindowlayout_mac.mm +++ b/src/gui/widgets/qmainwindowlayout_mac.mm @@ -472,14 +472,20 @@ void QMainWindowLayout::removeFromMacToolbar(QToolBar *toolbar) void QMainWindowLayout::cleanUpMacToolbarItems() { - for (int i = 0; i < toolbarItemsCopy.size(); ++i) +#ifdef QT_MAC_USE_COCOA + QMacCocoaAutoReleasePool pool; +#endif + for (int i = 0; i < toolbarItemsCopy.size(); ++i) { +#ifdef QT_MAC_USE_COCOA + NSToolbarItem *item = static_cast<NSToolbarItem *>(toolbarItemsCopy.at(i)); + [item setView:0]; +#endif CFRelease(toolbarItemsCopy.at(i)); + } toolbarItemsCopy.clear(); unifiedToolbarHash.clear(); #ifdef QT_MAC_USE_COCOA - QMacCocoaAutoReleasePool pool; - OSWindowRef window = qt_mac_window_for(layoutState.mainWindow); NSToolbar *macToolbar = [window toolbar]; if (macToolbar) { diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 5031d88..8ce7cc0 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -1588,10 +1588,9 @@ QAction *QMenu::insertSeparator(QAction *before) } /*! - This will set the default action to \a act. The default action may - have a visual queue depending on the current QStyle. A default - action is usually meant to indicate what will defaultly happen on a - drop, as shown in a context menu. + This sets the default action to \a act. The default action may have + a visual cue, depending on the current QStyle. A default action + usually indicates what will happen by default when a drop occurs. \sa defaultAction() */ diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm index 32968ee..e335884 100644 --- a/src/gui/widgets/qmenu_mac.mm +++ b/src/gui/widgets/qmenu_mac.mm @@ -175,6 +175,22 @@ static quint32 constructModifierMask(quint32 accel_key) return ret; } +static void cancelAllMenuTracking() +{ +#ifdef QT_MAC_USE_COCOA + QMacCocoaAutoReleasePool pool; + NSMenu *mainMenu = [NSApp mainMenu]; + [mainMenu cancelTracking]; + for (NSMenuItem *item in [mainMenu itemArray]) { + if ([item submenu]) { + [[item submenu] cancelTracking]; + } + } +#else + CancelMenuTracking(AcquireRootMenu(), true, 0); +#endif +} + static bool actualMenuItemVisibility(const QMenuBarPrivate::QMacMenuBarPrivate *mbp, const QMacMenuAction *action) { @@ -1796,6 +1812,12 @@ void QMenuBarPrivate::macDestroyMenuBar() mac_menubar = 0; if (qt_mac_current_menubar.qmenubar == q) { +#ifdef QT_MAC_USE_COCOA + QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader(); + [loader removeActionsFromAppMenu]; +#else + cancelAllMenuTracking(); +#endif extern void qt_event_request_menubarupdate(); //qapplication_mac.cpp qt_event_request_menubarupdate(); } diff --git a/src/network/access/qfilenetworkreply.cpp b/src/network/access/qfilenetworkreply.cpp index 8c5065c..4ac9a8c 100644 --- a/src/network/access/qfilenetworkreply.cpp +++ b/src/network/access/qfilenetworkreply.cpp @@ -49,10 +49,15 @@ QT_BEGIN_NAMESPACE QFileNetworkReplyPrivate::QFileNetworkReplyPrivate() - : QNetworkReplyPrivate(), realFileSize(0) + : QNetworkReplyPrivate(), fileEngine(0), fileSize(0), filePos(0) { } +QFileNetworkReplyPrivate::~QFileNetworkReplyPrivate() +{ + delete fileEngine; +} + QFileNetworkReply::~QFileNetworkReply() { } @@ -94,9 +99,8 @@ QFileNetworkReply::QFileNetworkReply(QObject *parent, const QNetworkRequest &req if (fileName.isEmpty()) { fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery); } - d->realFile.setFileName(fileName); - QFileInfo fi(d->realFile); + QFileInfo fi(fileName); if (fi.isDir()) { QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Cannot open %1: Path is a directory").arg(url.toString()); setError(QNetworkReply::ContentOperationNotPermittedError, msg); @@ -106,14 +110,15 @@ QFileNetworkReply::QFileNetworkReply(QObject *parent, const QNetworkRequest &req return; } - bool opened = d->realFile.open(QIODevice::ReadOnly | QIODevice::Unbuffered); + d->fileEngine = QAbstractFileEngine::create(fileName); + bool opened = d->fileEngine->open(QIODevice::ReadOnly | QIODevice::Unbuffered); // could we open the file? if (!opened) { QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Error opening %1: %2") - .arg(d->realFile.fileName(), d->realFile.errorString()); + .arg(fileName, d->fileEngine->errorString()); - if (d->realFile.exists()) { + if (fi.exists()) { setError(QNetworkReply::ContentAccessDenied, msg); QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ContentAccessDenied)); @@ -126,13 +131,13 @@ QFileNetworkReply::QFileNetworkReply(QObject *parent, const QNetworkRequest &req return; } - d->realFileSize = fi.size(); + d->fileSize = fi.size(); setHeader(QNetworkRequest::LastModifiedHeader, fi.lastModified()); - setHeader(QNetworkRequest::ContentLengthHeader, d->realFileSize); + setHeader(QNetworkRequest::ContentLengthHeader, d->fileSize); QMetaObject::invokeMethod(this, "metaDataChanged", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "downloadProgress", Qt::QueuedConnection, - Q_ARG(qint64, d->realFileSize), Q_ARG(qint64, d->realFileSize)); + Q_ARG(qint64, d->fileSize), Q_ARG(qint64, d->fileSize)); QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); } @@ -146,20 +151,25 @@ void QFileNetworkReply::close() { Q_D(QFileNetworkReply); QNetworkReply::close(); - d->realFile.close(); + if (d->fileEngine) + d->fileEngine->close(); } void QFileNetworkReply::abort() { Q_D(QFileNetworkReply); QNetworkReply::close(); - d->realFile.close(); + if (d->fileEngine) + d->fileEngine->close(); } qint64 QFileNetworkReply::bytesAvailable() const { Q_D(const QFileNetworkReply); - return QNetworkReply::bytesAvailable() + d->realFile.bytesAvailable(); + if (!d->fileEngine) + return 0; + + return QNetworkReply::bytesAvailable() + d->fileSize - d->filePos; } bool QFileNetworkReply::isSequential () const @@ -170,7 +180,7 @@ bool QFileNetworkReply::isSequential () const qint64 QFileNetworkReply::size() const { Q_D(const QFileNetworkReply); - return d->realFileSize; + return d->fileSize; } /*! @@ -179,11 +189,17 @@ qint64 QFileNetworkReply::size() const qint64 QFileNetworkReply::readData(char *data, qint64 maxlen) { Q_D(QFileNetworkReply); - qint64 ret = d->realFile.read(data, maxlen); - if (ret == 0 && bytesAvailable() == 0) + if (!d->fileEngine) + return -1; + + qint64 ret = d->fileEngine->read(data, maxlen); + if (ret == 0 && bytesAvailable() == 0) { return -1; // everything had been read - else - return ret; + } else if (ret > 0) { + d->filePos += ret; + } + + return ret; } diff --git a/src/network/access/qfilenetworkreply_p.h b/src/network/access/qfilenetworkreply_p.h index 125fa2e..710ec9f 100644 --- a/src/network/access/qfilenetworkreply_p.h +++ b/src/network/access/qfilenetworkreply_p.h @@ -57,6 +57,7 @@ #include "qnetworkreply_p.h" #include "qnetworkaccessmanager.h" #include <QFile> +#include <QAbstractFileEngine> QT_BEGIN_NAMESPACE @@ -85,9 +86,11 @@ class QFileNetworkReplyPrivate: public QNetworkReplyPrivate { public: QFileNetworkReplyPrivate(); + ~QFileNetworkReplyPrivate(); - QFile realFile; - qint64 realFileSize; + QAbstractFileEngine *fileEngine; + qint64 fileSize; + qint64 filePos; virtual bool isFinished() const; diff --git a/src/network/access/qhttpnetworkheader.cpp b/src/network/access/qhttpnetworkheader.cpp index c2cc69c..669f9cf 100644 --- a/src/network/access/qhttpnetworkheader.cpp +++ b/src/network/access/qhttpnetworkheader.cpp @@ -80,7 +80,7 @@ QByteArray QHttpNetworkHeaderPrivate::headerField(const QByteArray &name, const QByteArray result; bool first = true; - foreach (QByteArray value, allValues) { + foreach (const QByteArray &value, allValues) { if (!first) result += ", "; first = false; diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index 519bc95..8e02723 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -767,7 +767,7 @@ void QNetworkAccessHttpBackend::replyHeaderChanged() QByteArray value = rawHeader(it->first); if (!value.isEmpty()) { if (qstricmp(it->first.constData(), "set-cookie") == 0) - value += "\n"; + value += '\n'; else value += ", "; } diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index 07ff7b4..52b88a3 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -681,7 +681,7 @@ static QVariant parseCookieHeader(const QByteArray &raw) { QList<QNetworkCookie> result; QList<QByteArray> cookieList = raw.split(';'); - foreach (QByteArray cookie, cookieList) { + foreach (const QByteArray &cookie, cookieList) { QList<QNetworkCookie> parsed = QNetworkCookie::parseCookies(cookie.trimmed()); if (parsed.count() != 1) return QVariant(); // invalid Cookie: header diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp index 193a043..e4023c8 100644 --- a/src/network/kernel/qauthenticator.cpp +++ b/src/network/kernel/qauthenticator.cpp @@ -270,7 +270,7 @@ void QAuthenticatorPrivate::parseHttpResponse(const QHttpResponseHeader &header, break; case Ntlm: // #### extract from header - realm = QString(); + realm.clear(); break; case DigestMd5: { realm = QString::fromLatin1(options.value("realm")); @@ -281,7 +281,7 @@ void QAuthenticatorPrivate::parseHttpResponse(const QHttpResponseHeader &header, break; } default: - realm = QString(); + realm.clear(); challenge = QByteArray(); phase = Invalid; } diff --git a/src/network/kernel/qnetworkinterface.cpp b/src/network/kernel/qnetworkinterface.cpp index 367e3c4..1115c63 100644 --- a/src/network/kernel/qnetworkinterface.cpp +++ b/src/network/kernel/qnetworkinterface.cpp @@ -541,7 +541,7 @@ QList<QNetworkInterface> QNetworkInterface::allInterfaces() { QList<QSharedDataPointer<QNetworkInterfacePrivate> > privs = manager()->allInterfaces(); QList<QNetworkInterface> result; - foreach (QSharedDataPointer<QNetworkInterfacePrivate> p, privs) { + foreach (const QSharedDataPointer<QNetworkInterfacePrivate> &p, privs) { QNetworkInterface item; item.d = p; result << item; @@ -560,7 +560,7 @@ QList<QHostAddress> QNetworkInterface::allAddresses() { QList<QSharedDataPointer<QNetworkInterfacePrivate> > privs = manager()->allInterfaces(); QList<QHostAddress> result; - foreach (const QSharedDataPointer<QNetworkInterfacePrivate> p, privs) { + foreach (const QSharedDataPointer<QNetworkInterfacePrivate> &p, privs) { foreach (const QNetworkAddressEntry &entry, p->addressEntries) result += entry.ip(); } diff --git a/src/network/socket/qlocalserver.cpp b/src/network/socket/qlocalserver.cpp index ede3c89..ef7fc02 100644 --- a/src/network/socket/qlocalserver.cpp +++ b/src/network/socket/qlocalserver.cpp @@ -122,9 +122,9 @@ void QLocalServer::close() qDeleteAll(d->pendingConnections); d->pendingConnections.clear(); d->closeServer(); - d->serverName = QString(); - d->fullServerName = QString(); - d->errorString = QString(); + d->serverName.clear(); + d->fullServerName.clear(); + d->errorString.clear(); d->error = QAbstractSocket::UnknownSocketError; } @@ -226,8 +226,8 @@ bool QLocalServer::listen(const QString &name) } if (!d->listen(name)) { - d->serverName = QString(); - d->fullServerName = QString(); + d->serverName.clear(); + d->fullServerName.clear(); return false; } diff --git a/src/network/socket/qlocalsocket_tcp.cpp b/src/network/socket/qlocalsocket_tcp.cpp index 9f574d4..5b5e84f 100644 --- a/src/network/socket/qlocalsocket_tcp.cpp +++ b/src/network/socket/qlocalsocket_tcp.cpp @@ -102,8 +102,8 @@ void QLocalSocketPrivate::_q_stateChanged(QAbstractSocket::SocketState newState) switch(newState) { case QAbstractSocket::UnconnectedState: state = QLocalSocket::UnconnectedState; - serverName = QString(); - fullServerName = QString(); + serverName.clear(); + fullServerName.clear(); break; case QAbstractSocket::ConnectingState: state = QLocalSocket::ConnectingState; @@ -218,7 +218,7 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode) || state() == ConnectingState) return; - d->errorString = QString(); + d->errorString.clear(); d->state = ConnectingState; emit stateChanged(d->state); @@ -333,8 +333,8 @@ void QLocalSocket::close() { Q_D(QLocalSocket); d->tcpSocket->close(); - d->serverName = QString(); - d->fullServerName = QString(); + d->serverName.clear(); + d->fullServerName.clear(); QIODevice::close(); } diff --git a/src/network/socket/qlocalsocket_unix.cpp b/src/network/socket/qlocalsocket_unix.cpp index 73c2465..1ca11d8 100644 --- a/src/network/socket/qlocalsocket_unix.cpp +++ b/src/network/socket/qlocalsocket_unix.cpp @@ -109,8 +109,8 @@ void QLocalSocketPrivate::_q_stateChanged(QAbstractSocket::SocketState newState) switch(newState) { case QAbstractSocket::UnconnectedState: state = QLocalSocket::UnconnectedState; - serverName = QString(); - fullServerName = QString(); + serverName.clear(); + fullServerName.clear(); break; case QAbstractSocket::ConnectingState: state = QLocalSocket::ConnectingState; @@ -225,7 +225,7 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode) || state() == ConnectingState) return; - d->errorString = QString(); + d->errorString.clear(); d->unixSocket.setSocketState(QAbstractSocket::ConnectingState); d->state = ConnectingState; emit stateChanged(d->state); @@ -341,7 +341,7 @@ void QLocalSocketPrivate::_q_connectToSocket() errorOccurred(QLocalSocket::UnknownSocketError, function); } connectingSocket = -1; - connectingName = QString(); + connectingName.clear(); connectingOpenMode = 0; } @@ -438,10 +438,10 @@ void QLocalSocket::close() if (d->connectingSocket != -1) ::close(d->connectingSocket); d->connectingSocket = -1; - d->connectingName = QString(); + d->connectingName.clear(); d->connectingOpenMode = 0; - d->serverName = QString(); - d->fullServerName = QString(); + d->serverName.clear(); + d->fullServerName.clear(); QIODevice::close(); } diff --git a/src/network/socket/qnativesocketengine.cpp b/src/network/socket/qnativesocketengine.cpp index 6e1df93..a890b3b 100644 --- a/src/network/socket/qnativesocketengine.cpp +++ b/src/network/socket/qnativesocketengine.cpp @@ -778,6 +778,14 @@ qint64 QNativeSocketEngine::read(char *data, qint64 maxSize) QNativeSocketEnginePrivate::RemoteHostClosedErrorString); close(); return -1; + } else if (readBytes == -1) { + if (!d->hasSetSocketError) { + d->hasSetSocketError = true; + d->socketError = QAbstractSocket::NetworkError; + d->socketErrorString = qt_error_string(); + } + close(); + return -1; } return readBytes; } diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index d3b0fe5..9a2c349 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -903,7 +903,7 @@ qint64 QNativeSocketEnginePrivate::nativeRead(char *data, qint64 maxSize) case EBADF: case EINVAL: case EIO: - setError(QAbstractSocket::NetworkError, ReadErrorString); + //error string is now set in read(), not here in nativeRead() break; #ifdef Q_OS_SYMBIAN case EPIPE: diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 7088a57..8177b4f 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -1068,7 +1068,7 @@ qint64 QNativeSocketEnginePrivate::nativeRead(char *data, qint64 maxLength) break; case WSAEBADF: case WSAEINVAL: - setError(QAbstractSocket::NetworkError, ReadErrorString); + //error string is now set in read(), not here in nativeRead() break; case WSAECONNRESET: case WSAECONNABORTED: @@ -1199,8 +1199,10 @@ void QNativeSocketEnginePrivate::nativeClose() #if defined (QTCPSOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::nativeClose()"); #endif - linger l = {1, 0}; - ::setsockopt(socketDescriptor, SOL_SOCKET, SO_DONTLINGER, (char*)&l, sizeof(l)); + // We were doing a setsockopt here before with SO_DONTLINGER. (However with kind of wrong + // usage of parameters, it wants a BOOL but we used a struct and pretended it to be bool). + // We don't think setting this option should be done here, if a user wants it she/he can + // do it manually with socketDescriptor()/setSocketDescriptor(); ::closesocket(socketDescriptor); } diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index 9a9b1b5..fd647e2 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -634,11 +634,11 @@ QByteArray QSslCertificatePrivate::QByteArray_from_X509(X509 *x509, QSsl::Encodi QByteArray tmp; for (int i = 0; i <= array.size() - 64; i += 64) { tmp += QByteArray::fromRawData(array.data() + i, 64); - tmp += "\n"; + tmp += '\n'; } if (int remainder = array.size() % 64) { tmp += QByteArray::fromRawData(array.data() + array.size() - remainder, remainder); - tmp += "\n"; + tmp += '\n'; } return BEGINCERTSTRING "\n" + tmp + ENDCERTSTRING "\n"; diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 6947aa7..9623570 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -1109,7 +1109,7 @@ void QSslSocket::setCiphers(const QString &ciphers) { Q_D(QSslSocket); d->configuration.ciphers.clear(); - foreach (QString cipherName, ciphers.split(QLatin1String(":"),QString::SkipEmptyParts)) { + foreach (const QString &cipherName, ciphers.split(QLatin1String(":"),QString::SkipEmptyParts)) { for (int i = 0; i < 3; ++i) { // ### Crude QSslCipher cipher(cipherName, QSsl::SslProtocol(i)); diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 892d330..ce2aee1 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -818,7 +818,7 @@ bool QSslSocketBackendPrivate::startHandshake() QRegExp regexp(commonName, Qt::CaseInsensitive, QRegExp::Wildcard); if (!regexp.exactMatch(peerName)) { bool matched = false; - foreach (QString altName, configuration.peerCertificate + foreach (const QString &altName, configuration.peerCertificate .alternateSubjectNames().values(QSsl::DnsEntry)) { regexp.setPattern(altName); if (regexp.exactMatch(peerName)) { diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 556b888..8183f08 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -184,6 +184,9 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context) simpleShaderProg->addShader(vertexShader); simpleShaderProg->addShader(fragShader); simpleShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); + simpleShaderProg->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR); + simpleShaderProg->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR); + simpleShaderProg->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR); simpleShaderProg->link(); if (!simpleShaderProg->isLinked()) { qCritical() << "Errors linking simple shader:" @@ -324,6 +327,11 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS newProg->program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); if (newProg->useOpacityAttribute) newProg->program->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR); + if (newProg->usePmvMatrix) { + newProg->program->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR); + newProg->program->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR); + newProg->program->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR); + } newProg->program->link(); if (!newProg->program->isLinked()) { @@ -424,7 +432,6 @@ GLuint QGLEngineShaderManager::getUniformLocation(Uniform id) "patternColor", "globalOpacity", "depth", - "pmvMatrix", "maskTexture", "fragmentColor", "linearData", @@ -743,6 +750,7 @@ bool QGLEngineShaderManager::useCorrectShaderProg() } requiredProgram.useTextureCoords = texCoords; requiredProgram.useOpacityAttribute = (opacityMode == AttributeOpacity); + requiredProgram.usePmvMatrix = true; // At this point, requiredProgram is fully populated so try to find the program in the cache currentShaderProg = sharedShaders->findProgramInCache(requiredProgram); diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index c52e5c0..3ab4ebe 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -253,6 +253,9 @@ struct QGLEngineCachedShaderProg static const GLuint QT_VERTEX_COORDS_ATTR = 0; static const GLuint QT_TEXTURE_COORDS_ATTR = 1; static const GLuint QT_OPACITY_ATTR = 2; +static const GLuint QT_PMV_MATRIX_1_ATTR = 3; +static const GLuint QT_PMV_MATRIX_2_ATTR = 4; +static const GLuint QT_PMV_MATRIX_3_ATTR = 5; class QGLEngineShaderProg; @@ -397,6 +400,7 @@ public: bool useTextureCoords; bool useOpacityAttribute; + bool usePmvMatrix; bool operator==(const QGLEngineShaderProg& other) { // We don't care about the program @@ -431,7 +435,6 @@ public: PatternColor, GlobalOpacity, Depth, - PmvMatrix, MaskTexture, FragmentColor, LinearData, diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index d9a61e9..ee04166 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -63,210 +63,229 @@ QT_BEGIN_NAMESPACE QT_MODULE(OpenGL) -static const char* const qglslMainVertexShader = "\ - uniform highp float depth;\ - void setPosition();\ - void main(void)\ - {\ - setPosition();\ - gl_Position.z = depth * gl_Position.w;\ - }"; - -static const char* const qglslMainWithTexCoordsVertexShader = "\ - attribute highp vec2 textureCoordArray; \ - varying highp vec2 textureCoords; \ - uniform highp float depth;\ - void setPosition();\ - void main(void) \ - {\ - setPosition();\ - gl_Position.z = depth * gl_Position.w;\ - textureCoords = textureCoordArray; \ - }"; - -static const char* const qglslMainWithTexCoordsAndOpacityVertexShader = "\ - attribute highp vec2 textureCoordArray; \ - attribute lowp float opacityArray; \ - varying highp vec2 textureCoords; \ - varying lowp float opacity; \ - uniform highp float depth; \ - void setPosition(); \ - void main(void) \ - { \ - setPosition(); \ - gl_Position.z = depth * gl_Position.w; \ - textureCoords = textureCoordArray; \ - opacity = opacityArray; \ - }"; +static const char* const qglslMainVertexShader = "\n\ + void setPosition(); \n\ + void main(void) \n\ + { \n\ + setPosition(); \n\ + }\n"; + +static const char* const qglslMainWithTexCoordsVertexShader = "\n\ + attribute highp vec2 textureCoordArray; \n\ + varying highp vec2 textureCoords; \n\ + void setPosition(); \n\ + void main(void) \n\ + { \n\ + setPosition(); \n\ + textureCoords = textureCoordArray; \n\ + }\n"; + +static const char* const qglslMainWithTexCoordsAndOpacityVertexShader = "\n\ + attribute highp vec2 textureCoordArray; \n\ + attribute lowp float opacityArray; \n\ + varying highp vec2 textureCoords; \n\ + varying lowp float opacity; \n\ + void setPosition(); \n\ + void main(void) \n\ + { \n\ + setPosition(); \n\ + textureCoords = textureCoordArray; \n\ + opacity = opacityArray; \n\ + }\n"; // NOTE: We let GL do the perspective correction so texture lookups in the fragment // shader are also perspective corrected. -static const char* const qglslPositionOnlyVertexShader = "\ - attribute highp vec2 vertexCoordsArray;\ - uniform highp mat3 pmvMatrix;\ - void setPosition(void)\ - {\ - vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \ - gl_Position = vec4(transformedPos.xy, 0.0, transformedPos.z); \ - }"; - -static const char* const qglslUntransformedPositionVertexShader = "\ - attribute highp vec4 vertexCoordsArray;\ - void setPosition(void)\ - {\ - gl_Position = vertexCoordsArray;\ - }"; +static const char* const qglslPositionOnlyVertexShader = "\n\ + attribute highp vec2 vertexCoordsArray; \n\ + attribute highp vec3 pmvMatrix1; \n\ + attribute highp vec3 pmvMatrix2; \n\ + attribute highp vec3 pmvMatrix3; \n\ + void setPosition(void) \n\ + { \n\ + highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ + gl_Position = vec4(transformedPos.xy, 0.0, transformedPos.z); \n\ + }\n"; + +static const char* const qglslUntransformedPositionVertexShader = "\n\ + attribute highp vec4 vertexCoordsArray; \n\ + void setPosition(void) \n\ + { \n\ + gl_Position = vertexCoordsArray; \n\ + }\n"; // Pattern Brush - This assumes the texture size is 8x8 and thus, the inverted size is 0.125 -static const char* const qglslPositionWithPatternBrushVertexShader = "\ - attribute highp vec2 vertexCoordsArray; \ - uniform highp mat3 pmvMatrix; \ - uniform mediump vec2 halfViewportSize; \ - uniform highp vec2 invertedTextureSize; \ - uniform highp mat3 brushTransform; \ - varying highp vec2 patternTexCoords; \ - void setPosition(void) { \ - vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \ - gl_Position.xy = transformedPos.xy / transformedPos.z; \ - mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1.0); \ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \ - patternTexCoords.xy = (hTexCoords.xy * 0.125) * invertedHTexCoordsZ; \ - }"; +static const char* const qglslPositionWithPatternBrushVertexShader = "\n\ + attribute highp vec2 vertexCoordsArray; \n\ + attribute highp vec3 pmvMatrix1; \n\ + attribute highp vec3 pmvMatrix2; \n\ + attribute highp vec3 pmvMatrix3; \n\ + uniform mediump vec2 halfViewportSize; \n\ + uniform highp vec2 invertedTextureSize; \n\ + uniform highp mat3 brushTransform; \n\ + varying highp vec2 patternTexCoords; \n\ + void setPosition(void) \n\ + { \n\ + highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ + gl_Position.xy = transformedPos.xy / transformedPos.z; \n\ + mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1.0); \n\ + mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ + gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ + patternTexCoords.xy = (hTexCoords.xy * 0.125) * invertedHTexCoordsZ; \n\ + }\n"; static const char* const qglslAffinePositionWithPatternBrushVertexShader = qglslPositionWithPatternBrushVertexShader; -static const char* const qglslPatternBrushSrcFragmentShader = "\ - uniform lowp sampler2D brushTexture;\ - uniform lowp vec4 patternColor; \ - varying highp vec2 patternTexCoords;\ - lowp vec4 srcPixel() { \ - return patternColor * (1.0 - texture2D(brushTexture, patternTexCoords).r); \ +static const char* const qglslPatternBrushSrcFragmentShader = "\n\ + uniform lowp sampler2D brushTexture; \n\ + uniform lowp vec4 patternColor; \n\ + varying highp vec2 patternTexCoords;\n\ + lowp vec4 srcPixel() \n\ + { \n\ + return patternColor * (1.0 - texture2D(brushTexture, patternTexCoords).r); \n\ }\n"; // Linear Gradient Brush -static const char* const qglslPositionWithLinearGradientBrushVertexShader = "\ - attribute highp vec2 vertexCoordsArray; \ - uniform highp mat3 pmvMatrix; \ - uniform mediump vec2 halfViewportSize; \ - uniform highp vec3 linearData; \ - uniform highp mat3 brushTransform; \ - varying mediump float index; \ - void setPosition() { \ - vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \ - gl_Position.xy = transformedPos.xy / transformedPos.z; \ - mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \ - index = (dot(linearData.xy, hTexCoords.xy) * linearData.z) * invertedHTexCoordsZ; \ - }"; +static const char* const qglslPositionWithLinearGradientBrushVertexShader = "\n\ + attribute highp vec2 vertexCoordsArray; \n\ + attribute highp vec3 pmvMatrix1; \n\ + attribute highp vec3 pmvMatrix2; \n\ + attribute highp vec3 pmvMatrix3; \n\ + uniform mediump vec2 halfViewportSize; \n\ + uniform highp vec3 linearData; \n\ + uniform highp mat3 brushTransform; \n\ + varying mediump float index; \n\ + void setPosition() \n\ + { \n\ + highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ + gl_Position.xy = transformedPos.xy / transformedPos.z; \n\ + mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\ + mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ + gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ + index = (dot(linearData.xy, hTexCoords.xy) * linearData.z) * invertedHTexCoordsZ; \n\ + }\n"; static const char* const qglslAffinePositionWithLinearGradientBrushVertexShader = qglslPositionWithLinearGradientBrushVertexShader; -static const char* const qglslLinearGradientBrushSrcFragmentShader = "\ - uniform lowp sampler2D brushTexture; \ - varying mediump float index; \ - lowp vec4 srcPixel() { \ - mediump vec2 val = vec2(index, 0.5); \ - return texture2D(brushTexture, val); \ +static const char* const qglslLinearGradientBrushSrcFragmentShader = "\n\ + uniform lowp sampler2D brushTexture; \n\ + varying mediump float index; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + mediump vec2 val = vec2(index, 0.5); \n\ + return texture2D(brushTexture, val); \n\ }\n"; // Conical Gradient Brush -static const char* const qglslPositionWithConicalGradientBrushVertexShader = "\ - attribute highp vec2 vertexCoordsArray;\ - uniform highp mat3 pmvMatrix;\ - uniform mediump vec2 halfViewportSize; \ - uniform highp mat3 brushTransform; \ - varying highp vec2 A; \ - void setPosition(void)\ - {\ - vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \ - gl_Position.xy = transformedPos.xy / transformedPos.z; \ - mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \ - A = hTexCoords.xy * invertedHTexCoordsZ; \ - }"; +static const char* const qglslPositionWithConicalGradientBrushVertexShader = "\n\ + attribute highp vec2 vertexCoordsArray; \n\ + attribute highp vec3 pmvMatrix1; \n\ + attribute highp vec3 pmvMatrix2; \n\ + attribute highp vec3 pmvMatrix3; \n\ + uniform mediump vec2 halfViewportSize; \n\ + uniform highp mat3 brushTransform; \n\ + varying highp vec2 A; \n\ + void setPosition(void) \n\ + { \n\ + highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ + gl_Position.xy = transformedPos.xy / transformedPos.z; \n\ + mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\ + mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ + gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ + A = hTexCoords.xy * invertedHTexCoordsZ; \n\ + }\n"; static const char* const qglslAffinePositionWithConicalGradientBrushVertexShader = qglslPositionWithConicalGradientBrushVertexShader; static const char* const qglslConicalGradientBrushSrcFragmentShader = "\n\ #define INVERSE_2PI 0.1591549430918953358 \n\ - uniform lowp sampler2D brushTexture; \n\ - uniform mediump float angle; \ - varying highp vec2 A; \ - lowp vec4 srcPixel() { \ - highp float t; \ - if (abs(A.y) == abs(A.x)) \ - t = (atan(-A.y + 0.002, A.x) + angle) * INVERSE_2PI; \ - else \ - t = (atan(-A.y, A.x) + angle) * INVERSE_2PI; \ - return texture2D(brushTexture, vec2(t - floor(t), 0.5)); \ - }"; + uniform lowp sampler2D brushTexture; \n\ + uniform mediump float angle; \n\ + varying highp vec2 A; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + highp float t; \n\ + if (abs(A.y) == abs(A.x)) \n\ + t = (atan(-A.y + 0.002, A.x) + angle) * INVERSE_2PI; \n\ + else \n\ + t = (atan(-A.y, A.x) + angle) * INVERSE_2PI; \n\ + return texture2D(brushTexture, vec2(t - floor(t), 0.5)); \n\ + }\n"; // Radial Gradient Brush -static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\ - attribute highp vec2 vertexCoordsArray;\ - uniform highp mat3 pmvMatrix;\ - uniform mediump vec2 halfViewportSize; \ - uniform highp mat3 brushTransform; \ - uniform highp vec2 fmp; \ - varying highp float b; \ - varying highp vec2 A; \ - void setPosition(void) \ - {\ - vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \ - gl_Position.xy = transformedPos.xy / transformedPos.z; \ - mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \ - A = hTexCoords.xy * invertedHTexCoordsZ; \ - b = 2.0 * dot(A, fmp); \ - }"; +static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\n\ + attribute highp vec2 vertexCoordsArray;\n\ + attribute highp vec3 pmvMatrix1; \n\ + attribute highp vec3 pmvMatrix2; \n\ + attribute highp vec3 pmvMatrix3; \n\ + uniform mediump vec2 halfViewportSize; \n\ + uniform highp mat3 brushTransform; \n\ + uniform highp vec2 fmp; \n\ + varying highp float b; \n\ + varying highp vec2 A; \n\ + void setPosition(void) \n\ + {\n\ + highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ + gl_Position.xy = transformedPos.xy / transformedPos.z; \n\ + mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\ + mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ + gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ + A = hTexCoords.xy * invertedHTexCoordsZ; \n\ + b = 2.0 * dot(A, fmp); \n\ + }\n"; static const char* const qglslAffinePositionWithRadialGradientBrushVertexShader = qglslPositionWithRadialGradientBrushVertexShader; -static const char* const qglslRadialGradientBrushSrcFragmentShader = "\ - uniform lowp sampler2D brushTexture; \ - uniform highp float fmp2_m_radius2; \ - uniform highp float inverse_2_fmp2_m_radius2; \ - varying highp float b; \ - varying highp vec2 A; \ - lowp vec4 srcPixel() { \ - highp float c = -dot(A, A); \ - highp vec2 val = vec2((-b + sqrt(b*b - 4.0*fmp2_m_radius2*c)) * inverse_2_fmp2_m_radius2, 0.5); \ - return texture2D(brushTexture, val); \ - }"; +static const char* const qglslRadialGradientBrushSrcFragmentShader = "\n\ + uniform lowp sampler2D brushTexture; \n\ + uniform highp float fmp2_m_radius2; \n\ + uniform highp float inverse_2_fmp2_m_radius2; \n\ + varying highp float b; \n\ + varying highp vec2 A; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + highp float c = -dot(A, A); \n\ + highp vec2 val = vec2((-b + sqrt(b*b - 4.0*fmp2_m_radius2*c)) * inverse_2_fmp2_m_radius2, 0.5); \n\ + return texture2D(brushTexture, val); \n\ + }\n"; // Texture Brush -static const char* const qglslPositionWithTextureBrushVertexShader = "\ - attribute highp vec2 vertexCoordsArray; \ - uniform highp mat3 pmvMatrix; \ - uniform mediump vec2 halfViewportSize; \ - uniform highp vec2 invertedTextureSize; \ - uniform highp mat3 brushTransform; \ - varying highp vec2 textureCoords; \ - void setPosition(void) { \ - vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \ - gl_Position.xy = transformedPos.xy / transformedPos.z; \ - mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \ - textureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \ - }"; +static const char* const qglslPositionWithTextureBrushVertexShader = "\n\ + attribute highp vec2 vertexCoordsArray; \n\ + attribute highp vec3 pmvMatrix1; \n\ + attribute highp vec3 pmvMatrix2; \n\ + attribute highp vec3 pmvMatrix3; \n\ + uniform mediump vec2 halfViewportSize; \n\ + uniform highp vec2 invertedTextureSize; \n\ + uniform highp mat3 brushTransform; \n\ + varying highp vec2 textureCoords; \n\ + void setPosition(void) \n\ + { \n\ + highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ + gl_Position.xy = transformedPos.xy / transformedPos.z; \n\ + mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\ + mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ + gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ + textureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \n\ + }\n"; static const char* const qglslAffinePositionWithTextureBrushVertexShader = qglslPositionWithTextureBrushVertexShader; @@ -275,148 +294,165 @@ static const char* const qglslAffinePositionWithTextureBrushVertexShader // OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead, // we emulate GL_REPEAT by only taking the fractional part of the texture coords. // TODO: Special case POT textures which don't need this emulation -static const char* const qglslTextureBrushSrcFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp sampler2D brushTexture; \ - lowp vec4 srcPixel() { \ - return texture2D(brushTexture, fract(textureCoords)); \ - }"; +static const char* const qglslTextureBrushSrcFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp sampler2D brushTexture; \n\ + lowp vec4 srcPixel() { \n\ + return texture2D(brushTexture, fract(textureCoords)); \n\ + }\n"; #else -static const char* const qglslTextureBrushSrcFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp sampler2D brushTexture; \ - lowp vec4 srcPixel() { \ - return texture2D(brushTexture, textureCoords); \ - }"; +static const char* const qglslTextureBrushSrcFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp sampler2D brushTexture; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + return texture2D(brushTexture, textureCoords); \n\ + }\n"; #endif -static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp vec4 patternColor; \ - uniform lowp sampler2D brushTexture; \ - lowp vec4 srcPixel() { \ - return patternColor * (1.0 - texture2D(brushTexture, textureCoords).r); \ - }"; +static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp vec4 patternColor; \n\ + uniform lowp sampler2D brushTexture; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + return patternColor * (1.0 - texture2D(brushTexture, textureCoords).r); \n\ + }\n"; // Solid Fill Brush -static const char* const qglslSolidBrushSrcFragmentShader = "\ - uniform lowp vec4 fragmentColor; \ - lowp vec4 srcPixel() { \ - return fragmentColor; \ - }"; - -static const char* const qglslImageSrcFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp sampler2D imageTexture; \ - lowp vec4 srcPixel() { \ - return texture2D(imageTexture, textureCoords); \ - }"; - -static const char* const qglslCustomSrcFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp sampler2D imageTexture; \ - lowp vec4 customShader(lowp sampler2D texture, highp vec2 coords); \ - lowp vec4 srcPixel() { \ - return customShader(imageTexture, textureCoords); \ - }"; - -static const char* const qglslImageSrcWithPatternFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp vec4 patternColor; \ - uniform lowp sampler2D imageTexture; \ - lowp vec4 srcPixel() { \ - return patternColor * (1.0 - texture2D(imageTexture, textureCoords).r); \ - }\n"; - -static const char* const qglslNonPremultipliedImageSrcFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp sampler2D imageTexture; \ - lowp vec4 srcPixel() { \ - lowp vec4 sample = texture2D(imageTexture, textureCoords); \ - sample.rgb = sample.rgb * sample.a; \ - return sample; \ - }"; - -static const char* const qglslShockingPinkSrcFragmentShader = "\ - lowp vec4 srcPixel() { \ - return vec4(0.98, 0.06, 0.75, 1.0); \ - }"; - -static const char* const qglslMainFragmentShader_ImageArrays = "\ - varying lowp float opacity; \ - lowp vec4 srcPixel(); \ - void main() { \ - gl_FragColor = srcPixel() * opacity; \ - }"; - -static const char* const qglslMainFragmentShader_CMO = "\ - uniform lowp float globalOpacity; \ - lowp vec4 srcPixel(); \ - lowp vec4 applyMask(lowp vec4); \ - lowp vec4 compose(lowp vec4); \ - void main() { \ - gl_FragColor = applyMask(compose(srcPixel()*globalOpacity))); \ - }"; - -static const char* const qglslMainFragmentShader_CM = "\ - lowp vec4 srcPixel(); \ - lowp vec4 applyMask(lowp vec4); \ - lowp vec4 compose(lowp vec4); \ - void main() { \ - gl_FragColor = applyMask(compose(srcPixel())); \ - }"; - -static const char* const qglslMainFragmentShader_MO = "\ - uniform lowp float globalOpacity; \ - lowp vec4 srcPixel(); \ - lowp vec4 applyMask(lowp vec4); \ - void main() { \ - gl_FragColor = applyMask(srcPixel()*globalOpacity); \ - }"; - -static const char* const qglslMainFragmentShader_M = "\ - lowp vec4 srcPixel(); \ - lowp vec4 applyMask(lowp vec4); \ - void main() { \ - gl_FragColor = applyMask(srcPixel()); \ - }"; - -static const char* const qglslMainFragmentShader_CO = "\ - uniform lowp float globalOpacity; \ - lowp vec4 srcPixel(); \ - lowp vec4 compose(lowp vec4); \ - void main() { \ - gl_FragColor = compose(srcPixel()*globalOpacity); \ - }"; - -static const char* const qglslMainFragmentShader_C = "\ - lowp vec4 srcPixel(); \ - lowp vec4 compose(lowp vec4); \ - void main() { \ - gl_FragColor = compose(srcPixel()); \ - }"; - -static const char* const qglslMainFragmentShader_O = "\ - uniform lowp float globalOpacity; \ - lowp vec4 srcPixel(); \ - void main() { \ - gl_FragColor = srcPixel()*globalOpacity; \ - }"; - -static const char* const qglslMainFragmentShader = "\ - lowp vec4 srcPixel(); \ - void main() { \ - gl_FragColor = srcPixel(); \ - }"; - -static const char* const qglslMaskFragmentShader = "\ - varying highp vec2 textureCoords;\ - uniform lowp sampler2D maskTexture;\ - lowp vec4 applyMask(lowp vec4 src) \ - {\ - lowp vec4 mask = texture2D(maskTexture, textureCoords); \ - return src * mask.a; \ - }"; +static const char* const qglslSolidBrushSrcFragmentShader = "\n\ + uniform lowp vec4 fragmentColor; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + return fragmentColor; \n\ + }\n"; + +static const char* const qglslImageSrcFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp sampler2D imageTexture; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + return texture2D(imageTexture, textureCoords); \n\ + }\n"; + +static const char* const qglslCustomSrcFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp sampler2D imageTexture; \n\ + lowp vec4 customShader(lowp sampler2D texture, highp vec2 coords); \n\ + lowp vec4 srcPixel() \n\ + { \n\ + return customShader(imageTexture, textureCoords); \n\ + }\n"; + +static const char* const qglslImageSrcWithPatternFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp vec4 patternColor; \n\ + uniform lowp sampler2D imageTexture; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + return patternColor * (1.0 - texture2D(imageTexture, textureCoords).r); \n\ + }\n"; + +static const char* const qglslNonPremultipliedImageSrcFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp sampler2D imageTexture; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + lowp vec4 sample = texture2D(imageTexture, textureCoords); \n\ + sample.rgb = sample.rgb * sample.a; \n\ + return sample; \n\ + }\n"; + +static const char* const qglslShockingPinkSrcFragmentShader = "\n\ + lowp vec4 srcPixel() \n\ + { \n\ + return vec4(0.98, 0.06, 0.75, 1.0); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_ImageArrays = "\n\ + varying lowp float opacity; \n\ + lowp vec4 srcPixel(); \n\ + void main() \n\ + { \n\ + gl_FragColor = srcPixel() * opacity; \n\ + }\n"; + +static const char* const qglslMainFragmentShader_CMO = "\n\ + uniform lowp float globalOpacity; \n\ + lowp vec4 srcPixel(); \n\ + lowp vec4 applyMask(lowp vec4); \n\ + lowp vec4 compose(lowp vec4); \n\ + void main() \n\ + { \n\ + gl_FragColor = applyMask(compose(srcPixel()*globalOpacity))); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_CM = "\n\ + lowp vec4 srcPixel(); \n\ + lowp vec4 applyMask(lowp vec4); \n\ + lowp vec4 compose(lowp vec4); \n\ + void main() \n\ + { \n\ + gl_FragColor = applyMask(compose(srcPixel())); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_MO = "\n\ + uniform lowp float globalOpacity; \n\ + lowp vec4 srcPixel(); \n\ + lowp vec4 applyMask(lowp vec4); \n\ + void main() \n\ + { \n\ + gl_FragColor = applyMask(srcPixel()*globalOpacity); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_M = "\n\ + lowp vec4 srcPixel(); \n\ + lowp vec4 applyMask(lowp vec4); \n\ + void main() \n\ + { \n\ + gl_FragColor = applyMask(srcPixel()); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_CO = "\n\ + uniform lowp float globalOpacity; \n\ + lowp vec4 srcPixel(); \n\ + lowp vec4 compose(lowp vec4); \n\ + void main() \n\ + { \n\ + gl_FragColor = compose(srcPixel()*globalOpacity); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_C = "\n\ + lowp vec4 srcPixel(); \n\ + lowp vec4 compose(lowp vec4); \n\ + void main() \n\ + { \n\ + gl_FragColor = compose(srcPixel()); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_O = "\n\ + uniform lowp float globalOpacity; \n\ + lowp vec4 srcPixel(); \n\ + void main() \n\ + { \n\ + gl_FragColor = srcPixel()*globalOpacity; \n\ + }\n"; + +static const char* const qglslMainFragmentShader = "\n\ + lowp vec4 srcPixel(); \n\ + void main() \n\ + { \n\ + gl_FragColor = srcPixel(); \n\ + }\n"; + +static const char* const qglslMaskFragmentShader = "\n\ + varying highp vec2 textureCoords;\n\ + uniform lowp sampler2D maskTexture;\n\ + lowp vec4 applyMask(lowp vec4 src) \n\ + {\n\ + lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\ + return src * mask.a; \n\ + }\n"; // For source over with subpixel antialiasing, the final color is calculated per component as follows // (.a is alpha component, .c is red, green or blue component): @@ -433,23 +469,23 @@ static const char* const qglslMaskFragmentShader = "\ // dest.c = dest.c * (1 - mask.c) + src.c * alpha // -static const char* const qglslRgbMaskFragmentShaderPass1 = "\ - varying highp vec2 textureCoords;\ - uniform lowp sampler2D maskTexture;\ - lowp vec4 applyMask(lowp vec4 src) \ - {\ - lowp vec4 mask = texture2D(maskTexture, textureCoords); \ - return src.a * mask; \ - }"; - -static const char* const qglslRgbMaskFragmentShaderPass2 = "\ - varying highp vec2 textureCoords;\ - uniform lowp sampler2D maskTexture;\ - lowp vec4 applyMask(lowp vec4 src) \ - {\ - lowp vec4 mask = texture2D(maskTexture, textureCoords); \ - return src * mask; \ - }"; +static const char* const qglslRgbMaskFragmentShaderPass1 = "\n\ + varying highp vec2 textureCoords;\n\ + uniform lowp sampler2D maskTexture;\n\ + lowp vec4 applyMask(lowp vec4 src) \n\ + { \n\ + lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\ + return src.a * mask; \n\ + }\n"; + +static const char* const qglslRgbMaskFragmentShaderPass2 = "\n\ + varying highp vec2 textureCoords;\n\ + uniform lowp sampler2D maskTexture;\n\ + lowp vec4 applyMask(lowp vec4 src) \n\ + { \n\ + lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\ + return src * mask; \n\ + }\n"; /* Left to implement: diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 5e41cc1..24560d1 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -169,12 +169,6 @@ void QGL2PaintEngineExPrivate::useSimpleShader() if (matrixDirty) updateMatrix(); - - if (simpleShaderMatrixUniformDirty) { - const GLuint location = shaderManager->simpleProgram()->uniformLocation("pmvMatrix"); - glUniformMatrix3fv(location, 1, GL_FALSE, (GLfloat*)pmvMatrix); - simpleShaderMatrixUniformDirty = false; - } } void QGL2PaintEngineExPrivate::updateBrushTexture() @@ -393,9 +387,11 @@ void QGL2PaintEngineExPrivate::updateMatrix() matrixDirty = false; - // The actual data has been updated so both shader program's uniforms need updating - simpleShaderMatrixUniformDirty = true; - shaderMatrixUniformDirty = true; + // Set the PMV matrix attribute. As we use an attributes rather than uniforms, we only + // need to do this once for every matrix change and persists across all shader programs. + glVertexAttrib3fv(QT_PMV_MATRIX_1_ATTR, pmvMatrix[0]); + glVertexAttrib3fv(QT_PMV_MATRIX_2_ATTR, pmvMatrix[1]); + glVertexAttrib3fv(QT_PMV_MATRIX_3_ATTR, pmvMatrix[2]); dasher.setInvScale(inverseScale); stroker.setInvScale(inverseScale); @@ -1033,18 +1029,12 @@ bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) if (changed) { // The shader program has changed so mark all uniforms as dirty: brushUniformsDirty = true; - shaderMatrixUniformDirty = true; opacityUniformDirty = true; } if (brushUniformsDirty && mode != ImageDrawingMode && mode != ImageArrayDrawingMode) updateBrushUniforms(); - if (shaderMatrixUniformDirty) { - glUniformMatrix3fv(location(QGLEngineShaderManager::PmvMatrix), 1, GL_FALSE, (GLfloat*)pmvMatrix); - shaderMatrixUniformDirty = false; - } - if (opacityMode == QGLEngineShaderManager::UniformOpacity && opacityUniformDirty) { shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::GlobalOpacity), (GLfloat)q->state()->opacity); opacityUniformDirty = false; @@ -2060,11 +2050,8 @@ void QGL2PaintEngineEx::setState(QPainterState *new_state) if (old_state == s || old_state->renderHintsChanged) renderHintsChanged(); - if (old_state == s || old_state->matrixChanged) { + if (old_state == s || old_state->matrixChanged) d->matrixDirty = true; - d->simpleShaderMatrixUniformDirty = true; - d->shaderMatrixUniformDirty = true; - } if (old_state == s || old_state->compositionModeChanged) d->compositionModeDirty = true; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index e3d0bfc..35c88f4 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -252,8 +252,6 @@ public: bool compositionModeDirty; bool brushTextureDirty; bool brushUniformsDirty; - bool simpleShaderMatrixUniformDirty; - bool shaderMatrixUniformDirty; bool opacityUniformDirty; bool stencilClean; // Has the stencil not been used for clipping so far? diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index b7139a2..bb76f1a 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -4494,6 +4494,13 @@ static void qt_gl_draw_text(QPainter *p, int x, int y, const QString &str, \note This function temporarily disables depth-testing when the text is drawn. + \note This function can only be used inside a + QPainter::beginNativePainting()/QPainter::endNativePainting() block + if the default OpenGL paint engine is QPaintEngine::OpenGL. To make + QPaintEngine::OpenGL the default GL engine, call + QGL::setPreferredPaintEngine(QPaintEngine::OpenGL) before the + QApplication constructor. + \l{Overpainting Example}{Overpaint} with QPainter::drawText() instead. */ @@ -4513,8 +4520,17 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font, bool auto_swap = autoBufferSwap(); QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine(); - qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL); + QPaintEngine *engine = paintEngine(); + if (engine && (oldEngineType == QPaintEngine::OpenGL2) && engine->isActive()) { + qWarning("QGLWidget::renderText(): Calling renderText() while a GL 2 paint engine is" + " active on the same device is not allowed."); + return; + } + + // this changes what paintEngine() returns + qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL); + engine = paintEngine(); QPainter *p; bool reuse_painter = false; if (engine->isActive()) { @@ -4607,8 +4623,17 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con win_y = height - win_y; // y is inverted QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine(); - qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL); QPaintEngine *engine = paintEngine(); + + if (engine && (oldEngineType == QPaintEngine::OpenGL2) && engine->isActive()) { + qWarning("QGLWidget::renderText(): Calling renderText() while a GL 2 paint engine is" + " active on the same device is not allowed."); + return; + } + + // this changes what paintEngine() returns + qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL); + engine = paintEngine(); QPainter *p; bool reuse_painter = false; bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST); diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index 5e2f1f5..79484fa 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -106,6 +106,19 @@ QT_BEGIN_NAMESPACE \snippet doc/src/snippets/code/src_opengl_qglshaderprogram.cpp 2 + \section1 Binary shaders and programs + + Binary shaders may be specified using \c{glShaderBinary()} on + the return value from QGLShader::shaderId(). The QGLShader instance + containing the binary can then be added to the shader program with + addShader() and linked in the usual fashion with link(). + + Binary programs may be specified using \c{glProgramBinaryOES()} + on the return value from programId(). Then the application should + call link(), which will notice that the program has already been + specified and linked, allowing other operations to be performed + on the shader program. + \sa QGLShader */ @@ -632,8 +645,6 @@ bool QGLShaderProgram::addShader(QGLShader *shader) qWarning("QGLShaderProgram::addShader: Program and shader are not associated with same context."); return false; } - if (!shader->d_func()->compiled) - return false; if (!shader->d_func()->shaderGuard.id()) return false; glAttachShader(d->programGuard.id(), shader->d_func()->shaderGuard.id()); @@ -820,8 +831,20 @@ bool QGLShaderProgram::link() GLuint program = d->programGuard.id(); if (!program) return false; + GLint value; + if (d->shaders.isEmpty()) { + // If there are no explicit shaders, then it is possible that the + // application added a program binary with glProgramBinaryOES(), + // or otherwise populated the shaders itself. Check to see if the + // program is already linked and bail out if so. + value = 0; + glGetProgramiv(program, GL_LINK_STATUS, &value); + d->linked = (value != 0); + if (d->linked) + return true; + } glLinkProgram(program); - GLint value = 0; + value = 0; glGetProgramiv(program, GL_LINK_STATUS, &value); d->linked = (value != 0); value = 0; @@ -928,6 +951,15 @@ void QGLShaderProgram::release() GLuint QGLShaderProgram::programId() const { Q_D(const QGLShaderProgram); + GLuint id = d->programGuard.id(); + if (id) + return id; + + // Create the identifier if we don't have one yet. This is for + // applications that want to create the attached shader configuration + // themselves, particularly those using program binaries. + if (!const_cast<QGLShaderProgram *>(this)->init()) + return 0; return d->programGuard.id(); } diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index 6d47687..aa80664 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -252,10 +252,6 @@ QGLPixmapData::QGLPixmapData(PixelType type) { setSerialNumber(++qt_gl_pixmap_serial); m_glDevice.setPixmapData(this); - - // Set InteralBindOptions minus the memory managed, since this - // QGLTexture is not managed as part of the internal texture cache - m_texture.options = QGLContext::PremultipliedAlphaBindOption; } QGLPixmapData::~QGLPixmapData() @@ -344,18 +340,18 @@ void QGLPixmapData::ensureCreated() const } if (!m_source.isNull()) { - glBindTexture(target, m_texture.id); if (external_format == GL_RGB) { - const QImage tx = m_source.convertToFormat(QImage::Format_RGB888); + const QImage tx = m_source.convertToFormat(QImage::Format_RGB888).mirrored(false, true); + + glBindTexture(target, m_texture.id); glTexSubImage2D(target, 0, 0, 0, w, h, external_format, GL_UNSIGNED_BYTE, tx.bits()); } else { const QImage tx = ctx->d_func()->convertToGLFormat(m_source, true, external_format); + + glBindTexture(target, m_texture.id); glTexSubImage2D(target, 0, 0, 0, w, h, external_format, GL_UNSIGNED_BYTE, tx.bits()); - // convertToGLFormat will flip the Y axis, so it needs to - // be drawn upside down - m_texture.options |= QGLContext::InvertedYBindOption; } if (useFramebufferObjects()) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index 1cbfdaf..f27440e 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -552,6 +552,34 @@ QImage *QDirectFBPixmapData::buffer() return &lockedImage; } + +bool QDirectFBPixmapData::scroll(int dx, int dy, const QRect &rect) +{ + if (!dfbSurface) { + return false; + } + unlockSurface(); + DFBResult result = dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); + if (result != DFB_OK) { + DirectFBError("QDirectFBPixmapData::scroll", result); + return false; + } + result = dfbSurface->SetPorterDuff(dfbSurface, DSPD_NONE); + if (result != DFB_OK) { + DirectFBError("QDirectFBPixmapData::scroll", result); + return false; + } + + const DFBRectangle source = { rect.x(), rect.y(), rect.width(), rect.height() }; + result = dfbSurface->Blit(dfbSurface, dfbSurface, &source, source.x + dx, source.y + dy); + if (result != DFB_OK) { + DirectFBError("QDirectFBPixmapData::scroll", result); + return false; + } + + return true; +} + void QDirectFBPixmapData::invalidate() { if (dfbSurface) { @@ -568,6 +596,3 @@ void QDirectFBPixmapData::invalidate() QT_END_NAMESPACE #endif // QT_NO_QWS_DIRECTFB - - - diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h index f9b14a9..da6edc6 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h @@ -81,6 +81,7 @@ public: virtual QImage toImage() const; virtual QPaintEngine *paintEngine() const; virtual QImage *buffer(); + virtual bool scroll(int dx, int dy, const QRect &rect); // Pure virtual in QPixmapData, so re-implement here and delegate to QDirectFBPaintDevice virtual int metric(QPaintDevice::PaintDeviceMetric m) const { return QDirectFBPaintDevice::metric(m); } diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp index 4f49476..b2351fa 100644 --- a/src/plugins/imageformats/ico/qicohandler.cpp +++ b/src/plugins/imageformats/ico/qicohandler.cpp @@ -556,7 +556,11 @@ QImage ICOReader::iconAt(int index) else // # colors used icoAttrib.ncolors = header.biClrUsed ? header.biClrUsed : 1 << icoAttrib.nbits; icoAttrib.w = iconEntry.bWidth; + if (icoAttrib.w == 0) + icoAttrib.w = header.biWidth; icoAttrib.h = iconEntry.bHeight; + if (icoAttrib.h == 0) + icoAttrib.h = header.biHeight/2; QImage::Format format = QImage::Format_ARGB32; if (icoAttrib.nbits == 24) diff --git a/src/qbase.pri b/src/qbase.pri index 22a57db..58bb6d4 100644 --- a/src/qbase.pri +++ b/src/qbase.pri @@ -94,31 +94,17 @@ symbian { DEFINES+=QT_MAKEDLL TARGET.CAPABILITY = All -Tcb - defBlock = \ - "$${LITERAL_HASH}ifdef WINSCW" \ - "DEFFILE ../s60installs/bwins/$${TARGET}.def" \ - "$${LITERAL_HASH}elif defined EABI" \ - "DEFFILE ../s60installs/eabi/$${TARGET}.def" \ - "$${LITERAL_HASH}endif" - - contains(QT_CONFIG, private_tests) { - #When building autotest configuration, there are extra exports from - #the Qt DLLs, which we don't want in the frozen DEF files. - MMP_RULES += EXPORTUNFROZEN - } else { - #When building without autotests, DEF files are used by default. - #This is to maintain binary compatibility with previous releases. - - #with defBlock enabled, removed exported symbols are treated as errors - #and there is binary compatibility between successive builds. - #with defBlock disabled, binary compatibility is broken every time you build - MMP_RULES += defBlock - - #with EXPORTUNFROZEN enabled, new exports are included in the dll without - #needing to run abld freeze, however binary compatibility is only maintained - #for symbols that are frozen (and only if defBlock is also enabled) - #the downside of EXPORTUNFROZEN is that the linker gets run twice - #MMP_RULES += EXPORTUNFROZEN + # When building without autotests, DEF files are used by default. + # This is to maintain binary compatibility with previous releases. + # To explicitly disable DEF files usage, eg. when lots of code churn is + # going on, and functions may be added and removed before shipping, + # configure with -no-usedeffiles + # WARNING - disabling DEF files *will* break BC with previous released versions + # of Qt, and the only compatibility will be between this build of Qt and anything + # built in this exact environment. *Never* use this when building a version + # for release. + contains(CONFIG, def_files) { + defFilePath=../s60installs } } load(armcc_warnings) diff --git a/src/s60installs/backup_registration.xml b/src/s60installs/backup_registration.xml new file mode 100644 index 0000000..e026140 --- /dev/null +++ b/src/s60installs/backup_registration.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" standalone="yes"?> +<backup_registration> + <system_backup/> + <restore requires_reboot = "no"/> +</backup_registration> diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index 55eaee1..aaecf6c 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -78,7 +78,11 @@ symbian: { DEPLOYMENT += phonon_backend_plugins } - DEPLOYMENT += qtresources qtlibraries imageformats_plugins codecs_plugins graphicssystems_plugins + # Support backup & restore for Qt libraries + qtbackup.sources = backup_registration.xml + qtbackup.path = c:/private/10202D56/import/packages/$$replace(TARGET.UID3, 0x,) + + DEPLOYMENT += qtresources qtlibraries qtbackup imageformats_plugins codecs_plugins graphicssystems_plugins contains(QT_CONFIG, svg): { qtlibraries.sources += QtSvg.dll diff --git a/src/s60installs/sqlite3_selfsigned.sis b/src/s60installs/sqlite3_selfsigned.sis Binary files differnew file mode 100644 index 0000000..a025ac5 --- /dev/null +++ b/src/s60installs/sqlite3_selfsigned.sis diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index 1db2e1b..5bfe46a 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -1148,10 +1148,15 @@ bool QScriptValue::strictlyEquals(const QScriptValue &other) const } if (d->type != other.d_ptr->type) { - if (d->type == QScriptValuePrivate::JavaScriptCore) - return JSC::JSValue::strictEqual(d->jscValue, d->engine->scriptValueToJSCValue(other)); - else if (other.d_ptr->type == QScriptValuePrivate::JavaScriptCore) - return JSC::JSValue::strictEqual(other.d_ptr->engine->scriptValueToJSCValue(*this), other.d_ptr->jscValue); + if (d->type == QScriptValuePrivate::JavaScriptCore) { + QScriptEnginePrivate *eng_p = d->engine ? d->engine : other.d_ptr->engine; + if (eng_p) + return JSC::JSValue::strictEqual(d->jscValue, eng_p->scriptValueToJSCValue(other)); + } else if (other.d_ptr->type == QScriptValuePrivate::JavaScriptCore) { + QScriptEnginePrivate *eng_p = other.d_ptr->engine ? other.d_ptr->engine : d->engine; + if (eng_p) + return JSC::JSValue::strictEqual(eng_p->scriptValueToJSCValue(*this), other.d_ptr->jscValue); + } return false; } diff --git a/src/src.pro b/src/src.pro index 8dec49b..f2070ae 100644 --- a/src/src.pro +++ b/src/src.pro @@ -106,6 +106,7 @@ src_declarative.target = sub-declarative contains(QT_CONFIG, webkit) { src_webkit.depends = src_gui src_sql src_network src_xml contains(QT_CONFIG, phonon):src_webkit.depends += src_phonon + contains(QT_CONFIG, xmlpatterns): src_webkit.depends += src_xmlpatterns contains(QT_CONFIG, declarative):src_declarative.depends += src_webkit #exists($$QT_SOURCE_TREE/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pro): src_webkit.depends += src_javascriptcore } |