summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>2010-02-01 15:36:05 (GMT)
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>2010-02-01 15:36:05 (GMT)
commit7e8d20de90af2e5ea199b6a92830cc223cea777b (patch)
tree89364f787fad44c2fdea1de6358140c568a82e7a /src/gui
parentf3cf5dd98e321980984288a1768f3375a8349800 (diff)
parentafe0f17eb5974adbedd1bc1f2fcd98459d92df47 (diff)
downloadQt-7e8d20de90af2e5ea199b6a92830cc223cea777b.zip
Qt-7e8d20de90af2e5ea199b6a92830cc223cea777b.tar.gz
Qt-7e8d20de90af2e5ea199b6a92830cc223cea777b.tar.bz2
Merge branch '4.6' into qstatictext-4.6
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/dialogs/qcolordialog.cpp45
-rw-r--r--src/gui/dialogs/qdialog.cpp16
-rw-r--r--src/gui/dialogs/qfiledialog.cpp18
-rw-r--r--src/gui/dialogs/qfiledialog_mac.mm7
-rw-r--r--src/gui/dialogs/qprintdialog.h6
-rw-r--r--src/gui/dialogs/qprintpreviewdialog.cpp10
-rw-r--r--src/gui/effects/qgraphicseffect.cpp4
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp265
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h66
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp108
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h6
-rw-r--r--src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp10
-rw-r--r--src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h2
-rw-r--r--src/gui/graphicsview/qgraphicssceneindex.cpp6
-rw-r--r--src/gui/graphicsview/qgraphicssceneindex_p.h2
-rw-r--r--src/gui/image/qbmphandler.cpp2
-rw-r--r--src/gui/image/qimage.cpp2
-rw-r--r--src/gui/image/qimagepixmapcleanuphooks.cpp20
-rw-r--r--src/gui/image/qimagepixmapcleanuphooks_p.h23
-rw-r--r--src/gui/image/qpixmap.cpp33
-rw-r--r--src/gui/image/qpixmap_x11.cpp14
-rw-r--r--src/gui/image/qpixmapdata.cpp11
-rw-r--r--src/gui/image/qpixmapdata_p.h8
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_p.h7
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp50
-rw-r--r--src/gui/itemviews/qlistview.cpp7
-rw-r--r--src/gui/itemviews/qtableview.cpp4
-rw-r--r--src/gui/kernel/qapplication.cpp4
-rw-r--r--src/gui/kernel/qapplication_mac.mm42
-rw-r--r--src/gui/kernel/qapplication_p.h6
-rw-r--r--src/gui/kernel/qapplication_s60.cpp77
-rw-r--r--src/gui/kernel/qcocoamenuloader_mac.mm6
-rw-r--r--src/gui/kernel/qcocoamenuloader_mac_p.h1
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm4
-rw-r--r--src/gui/kernel/qdesktopwidget.cpp10
-rw-r--r--src/gui/kernel/qeventdispatcher_mac.mm2
-rw-r--r--src/gui/kernel/qformlayout.cpp6
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm16
-rw-r--r--src/gui/kernel/qt_s60_p.h1
-rw-r--r--src/gui/kernel/qwidget.cpp10
-rw-r--r--src/gui/kernel/qwidget_mac.mm49
-rw-r--r--src/gui/kernel/qwidget_p.h1
-rw-r--r--src/gui/kernel/qwidget_s60.cpp9
-rw-r--r--src/gui/painting/qcolor.cpp11
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h4
-rw-r--r--src/gui/painting/qpaintengineex.cpp16
-rw-r--r--src/gui/painting/qpainter.cpp58
-rw-r--r--src/gui/painting/qprintengine_pdf.cpp26
-rw-r--r--src/gui/painting/qwindowsurface_s60.cpp8
-rw-r--r--src/gui/styles/qgtkstyle.cpp22
-rw-r--r--src/gui/styles/qmacstyle_mac.mm178
-rw-r--r--src/gui/styles/qs60style.cpp539
-rw-r--r--src/gui/styles/qs60style.h3
-rw-r--r--src/gui/styles/qs60style_p.h107
-rw-r--r--src/gui/styles/qs60style_s60.cpp243
-rw-r--r--src/gui/styles/qs60style_simulated.cpp10
-rw-r--r--src/gui/styles/qstyle_s60.qrc137
-rw-r--r--src/gui/styles/styles.pri10
-rw-r--r--src/gui/text/qfont.cpp10
-rw-r--r--src/gui/text/qfontengine.cpp3
-rw-r--r--src/gui/text/qtextoption.cpp5
-rw-r--r--src/gui/util/qsystemtrayicon_mac.mm13
-rw-r--r--src/gui/widgets/qlinecontrol.cpp5
-rw-r--r--src/gui/widgets/qlinecontrol_p.h5
-rw-r--r--src/gui/widgets/qmainwindowlayout_mac.mm19
-rw-r--r--src/gui/widgets/qmenu.cpp7
-rw-r--r--src/gui/widgets/qmenu_mac.mm36
67 files changed, 1858 insertions, 613 deletions
diff --git a/src/gui/dialogs/qcolordialog.cpp b/src/gui/dialogs/qcolordialog.cpp
index e9031ac..83ecc30 100644
--- a/src/gui/dialogs/qcolordialog.cpp
+++ b/src/gui/dialogs/qcolordialog.cpp
@@ -68,6 +68,10 @@
#include "private/qt_s60_p.h"
#endif
+#if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
+# define QT_SMALL_COLORDIALOG
+#endif
+
QT_BEGIN_NAMESPACE
//////////// QWellArray BEGIN
@@ -1072,14 +1076,17 @@ QColorShower::QColorShower(QColorDialog *parent)
gl->setMargin(gl->spacing());
lab = new QColorShowLabel(this);
-#ifdef Q_WS_S60
+#ifdef QT_SMALL_COLORDIALOG
+# ifdef Q_WS_S60
QS60Data s60Data = QS60Data();
const bool nonTouchUI = !s60Data.hasTouchscreen;
+# elif defined Q_WS_MAEMO_5
+ const bool nonTouchUI = false;
+# endif
#endif
-
#ifndef Q_WS_WINCE
-#ifdef Q_WS_S60
+#ifdef QT_SMALL_COLORDIALOG
lab->setMinimumHeight(60);
#endif
lab->setMinimumWidth(60);
@@ -1090,7 +1097,7 @@ QColorShower::QColorShower(QColorDialog *parent)
// In S60, due to small screen and different screen layouts need to re-arrange the widgets.
// For QVGA screens only the comboboxes and color label are visible.
// For nHD screens only color and luminence pickers and color label are visible.
-#ifndef Q_WS_S60
+#if !defined(QT_SMALL_COLORDIALOG)
gl->addWidget(lab, 0, 0, -1, 1);
#else
if (nonTouchUI)
@@ -1108,7 +1115,7 @@ QColorShower::QColorShower(QColorDialog *parent)
lblHue->setBuddy(hEd);
#endif
lblHue->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
-#ifndef Q_WS_S60
+#if !defined(QT_SMALL_COLORDIALOG)
gl->addWidget(lblHue, 0, 1);
gl->addWidget(hEd, 0, 2);
#else
@@ -1127,7 +1134,7 @@ QColorShower::QColorShower(QColorDialog *parent)
lblSat->setBuddy(sEd);
#endif
lblSat->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
-#ifndef Q_WS_S60
+#if !defined(QT_SMALL_COLORDIALOG)
gl->addWidget(lblSat, 1, 1);
gl->addWidget(sEd, 1, 2);
#else
@@ -1146,7 +1153,7 @@ QColorShower::QColorShower(QColorDialog *parent)
lblVal->setBuddy(vEd);
#endif
lblVal->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
-#ifndef Q_WS_S60
+#if !defined(QT_SMALL_COLORDIALOG)
gl->addWidget(lblVal, 2, 1);
gl->addWidget(vEd, 2, 2);
#else
@@ -1165,7 +1172,7 @@ QColorShower::QColorShower(QColorDialog *parent)
lblRed->setBuddy(rEd);
#endif
lblRed->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
-#ifndef Q_WS_S60
+#if !defined(QT_SMALL_COLORDIALOG)
gl->addWidget(lblRed, 0, 3);
gl->addWidget(rEd, 0, 4);
#else
@@ -1184,7 +1191,7 @@ QColorShower::QColorShower(QColorDialog *parent)
lblGreen->setBuddy(gEd);
#endif
lblGreen->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
-#ifndef Q_WS_S60
+#if !defined(QT_SMALL_COLORDIALOG)
gl->addWidget(lblGreen, 1, 3);
gl->addWidget(gEd, 1, 4);
#else
@@ -1203,7 +1210,7 @@ QColorShower::QColorShower(QColorDialog *parent)
lblBlue->setBuddy(bEd);
#endif
lblBlue->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
-#ifndef Q_WS_S60
+#if !defined(QT_SMALL_COLORDIALOG)
gl->addWidget(lblBlue, 2, 3);
gl->addWidget(bEd, 2, 4);
#else
@@ -1222,7 +1229,7 @@ QColorShower::QColorShower(QColorDialog *parent)
alphaLab->setBuddy(alphaEd);
#endif
alphaLab->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
-#ifndef Q_WS_S60
+#if !defined(QT_SMALL_COLORDIALOG)
gl->addWidget(alphaLab, 3, 1, 1, 3);
gl->addWidget(alphaEd, 3, 4);
#else
@@ -1467,7 +1474,7 @@ void QColorDialogPrivate::init(const QColor &initial)
leftLay = 0;
-#if (defined(Q_WS_WINCE) || defined(Q_WS_S60))
+#if defined(Q_WS_WINCE) || defined(QT_SMALL_COLORDIALOG)
smallDisplay = true;
const int lumSpace = 20;
#else
@@ -1497,9 +1504,13 @@ void QColorDialogPrivate::init(const QColor &initial)
}
#endif
-#if defined(Q_WS_S60)
+#if defined(QT_SMALL_COLORDIALOG)
+# if defined(Q_WS_S60)
QS60Data s60Data = QS60Data();
const bool nonTouchUI = !s60Data.hasTouchscreen;
+# elif defined(Q_WS_MAEMO_5)
+ const bool nonTouchUI = false;
+# endif
#endif
if (!smallDisplay) {
@@ -1532,7 +1543,7 @@ void QColorDialogPrivate::init(const QColor &initial)
leftLay->addWidget(addCusBt);
} else {
// better color picker size for small displays
-#ifdef Q_WS_S60
+#if defined(QT_SMALL_COLORDIALOG)
QSize screenSize = QApplication::desktop()->availableGeometry(QCursor::pos()).size();
pWidth = pHeight = qMin(screenSize.width(), screenSize.height());
pHeight -= 20;
@@ -1558,7 +1569,7 @@ void QColorDialogPrivate::init(const QColor &initial)
cp->setFrameStyle(QFrame::Panel + QFrame::Sunken);
-#if defined(Q_WS_S60)
+#if defined(QT_SMALL_COLORDIALOG)
if (!nonTouchUI) {
pickLay->addWidget(cp);
cLay->addSpacing(lumSpace);
@@ -1572,7 +1583,7 @@ void QColorDialogPrivate::init(const QColor &initial)
cLay->addSpacing(lumSpace);
lp = new QColorLuminancePicker(q);
-#if defined(Q_WS_S60)
+#if defined(QT_SMALL_COLORDIALOG)
QSize screenSize = QApplication::desktop()->availableGeometry(QCursor::pos()).size();
const int minDimension = qMin(screenSize.height(), screenSize.width());
//set picker to be finger-usable
@@ -1596,7 +1607,7 @@ void QColorDialogPrivate::init(const QColor &initial)
QObject::connect(cs, SIGNAL(newCol(QRgb)), q, SLOT(_q_newColorTypedIn(QRgb)));
QObject::connect(cs, SIGNAL(currentColorChanged(QColor)),
q, SIGNAL(currentColorChanged(QColor)));
-#if defined(Q_WS_S60)
+#if defined(QT_SMALL_COLORDIALOG)
if (!nonTouchUI)
pWidth -= cp->size().width();
topLay->addWidget(cs);
diff --git a/src/gui/dialogs/qdialog.cpp b/src/gui/dialogs/qdialog.cpp
index 3650051..9ff2ad8 100644
--- a/src/gui/dialogs/qdialog.cpp
+++ b/src/gui/dialogs/qdialog.cpp
@@ -265,6 +265,14 @@ QDialog::QDialog(QWidget *parent, Qt::WindowFlags f)
if (!qt_wince_is_smartphone())
setWindowFlags(windowFlags() | Qt::WindowOkButtonHint | QFlag(qt_wince_is_mobile() ? 0 : Qt::WindowCancelButtonHint));
#endif
+
+#ifdef Q_WS_S60
+ if (S60->avkonComponentsSupportTransparency) {
+ bool noSystemBackground = testAttribute(Qt::WA_NoSystemBackground);
+ setAttribute(Qt::WA_TranslucentBackground); // also sets WA_NoSystemBackground
+ setAttribute(Qt::WA_NoSystemBackground, noSystemBackground); // restore system background attribute
+ }
+#endif
}
#ifdef QT3_SUPPORT
@@ -294,6 +302,14 @@ QDialog::QDialog(QDialogPrivate &dd, QWidget *parent, Qt::WindowFlags f)
if (!qt_wince_is_smartphone())
setWindowFlags(windowFlags() | Qt::WindowOkButtonHint | QFlag(qt_wince_is_mobile() ? 0 : Qt::WindowCancelButtonHint));
#endif
+
+#ifdef Q_WS_S60
+ if (S60->avkonComponentsSupportTransparency) {
+ bool noSystemBackground = testAttribute(Qt::WA_NoSystemBackground);
+ setAttribute(Qt::WA_TranslucentBackground); // also sets WA_NoSystemBackground
+ setAttribute(Qt::WA_NoSystemBackground, noSystemBackground); // restore system background attribute
+ }
+#endif
}
/*!
diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp
index 3d59463..089e04a 100644
--- a/src/gui/dialogs/qfiledialog.cpp
+++ b/src/gui/dialogs/qfiledialog.cpp
@@ -229,11 +229,10 @@ Q_GUI_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook
\value ReadOnly Indicates that the model is readonly.
\value HideNameFilterDetails Indicates if the is hidden or not.
- This value is obsolete and does nothing since Qt 4.5:
\value DontUseSheet In previous versions of Qt, the static
functions would create a sheet by default if the static function
- was given a parent. This is no longer supported in Qt 4.5, The
+ was given a parent. This is no longer supported and does nothing in Qt 4.5, The
static functions will always be an application modal dialog. If
you want to use sheets, use QFileDialog::open() instead.
@@ -1222,12 +1221,6 @@ QFileDialog::ViewMode QFileDialog::viewMode() const
void QFileDialog::setFileMode(QFileDialog::FileMode mode)
{
Q_D(QFileDialog);
- if (d->nativeDialogInUse){
- d->model->setFilter(d->filterForMode(filter()));
- d->setFilter_sys();
- return;
- }
-
d->fileMode = mode;
d->retranslateWindowTitle();
@@ -1263,6 +1256,11 @@ void QFileDialog::setFileMode(QFileDialog::FileMode mode)
}
}
setLabelText(Accept, buttonText);
+ if (d->nativeDialogInUse){
+ d->setFilter_sys();
+ return;
+ }
+
d->qFileDialogUi->fileTypeCombo->setEnabled(!testOption(ShowDirsOnly));
d->_q_updateOkButton();
}
@@ -1300,6 +1298,10 @@ void QFileDialog::setAcceptMode(QFileDialog::AcceptMode mode)
d->qFileDialogUi->lookInCombo->setEditable(false);
}
d->retranslateWindowTitle();
+#if defined(Q_WS_MAC)
+ d->deleteNativeDialog_sys();
+ setAttribute(Qt::WA_DontShowOnScreen, false);
+#endif
}
/*
diff --git a/src/gui/dialogs/qfiledialog_mac.mm b/src/gui/dialogs/qfiledialog_mac.mm
index db5c356..67daced 100644
--- a/src/gui/dialogs/qfiledialog_mac.mm
+++ b/src/gui/dialogs/qfiledialog_mac.mm
@@ -639,9 +639,16 @@ void QFileDialogPrivate::setFilter_sys()
{
#ifndef QT_MAC_USE_COCOA
#else
+ Q_Q(QFileDialog);
QMacCocoaAutoReleasePool pool;
QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
*(delegate->mQDirFilter) = model->filter();
+ delegate->mFileMode = fileMode;
+ [delegate->mSavePanel setTitle:qt_mac_QStringToNSString(q->windowTitle())];
+ [delegate->mSavePanel setPrompt:[delegate strip:acceptLabel]];
+ if (fileNameLabelExplicitlySat)
+ [delegate->mSavePanel setNameFieldLabel:[delegate strip:qFileDialogUi->fileNameLabel->text()]];
+
[delegate updateProperties];
#endif
}
diff --git a/src/gui/dialogs/qprintdialog.h b/src/gui/dialogs/qprintdialog.h
index 390a4a0..ecd50c1 100644
--- a/src/gui/dialogs/qprintdialog.h
+++ b/src/gui/dialogs/qprintdialog.h
@@ -97,9 +97,9 @@ public:
void done(int result);
#if defined (Q_OS_UNIX) && defined (QT3_SUPPORT)
- void setPrinter(QPrinter *, bool = false);
- QPrinter *printer() const;
- void addButton(QPushButton *button);
+ QT3_SUPPORT void setPrinter(QPrinter *, bool = false);
+ QT3_SUPPORT QPrinter *printer() const;
+ QT3_SUPPORT void addButton(QPushButton *button);
#endif
void setOption(PrintDialogOption option, bool on = true);
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 cae9660..b4e19d1 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
@@ -2515,6 +2569,7 @@ void QGraphicsItem::setOpacity(qreal opacity)
if (newOpacity == d_ptr->opacity)
return;
+ bool wasFullyTransparent = d_ptr->isOpacityNull();
d_ptr->opacity = newOpacity;
// Notify change.
@@ -2523,12 +2578,16 @@ 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,
/*force=*/false,
- /*ignoreOpacity=*/true);
+ /*ignoreOpacity=*/d_ptr->isOpacityNull());
+ if (wasFullyTransparent)
+ d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
}
if (d_ptr->isObject)
@@ -2568,6 +2627,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 +2642,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
@@ -2997,9 +3071,16 @@ void QGraphicsItem::setActive(bool active)
*/
bool QGraphicsItem::hasFocus() const
{
+ if (!d_ptr->scene || !d_ptr->scene->isActive())
+ return false;
+
if (d_ptr->focusProxy)
return d_ptr->focusProxy->hasFocus();
- return isActive() && (d_ptr->scene && d_ptr->scene->focusItem() == this);
+
+ if (d_ptr->scene->d_func()->focusItem != this)
+ return false;
+
+ return panel() == d_ptr->scene->d_func()->activePanel;
}
/*!
@@ -4257,9 +4338,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;
@@ -5026,7 +5107,7 @@ int QGraphicsItemPrivate::depth() const
\internal
*/
#ifndef QT_NO_GRAPHICSEFFECT
-void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively()
+void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively()
{
QGraphicsItemPrivate *itemPrivate = this;
do {
@@ -5038,6 +5119,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
/*!
@@ -5282,7 +5381,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) {
@@ -7158,7 +7257,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.
@@ -7175,19 +7276,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..b3ca3b5 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;
@@ -349,14 +358,20 @@ public:
return o;
}
+ inline bool isOpacityNull() const
+ { return (opacity < qreal(0.001)); }
+
+ static inline bool isOpacityNull(qreal opacity)
+ { return (opacity < qreal(0.001)); }
+
inline bool isFullyTransparent() const
{
- if (opacity < 0.001)
+ if (isOpacityNull())
return true;
if (!parent)
return false;
- return calcEffectiveOpacity() < 0.001;
+ return isOpacityNull(calcEffectiveOpacity());
}
inline qreal effectiveOpacity() const {
@@ -397,6 +412,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 +501,8 @@ public:
quint32 sequentialOrdering : 1;
quint32 updateDueToGraphicsEffect : 1;
quint32 scenePosDescendants : 1;
+ quint32 pendingPolish : 1;
+ quint32 mayHaveChildWithGraphicsEffect : 1;
// Optional stacking order
int globalStackingOrder;
@@ -721,11 +740,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 +762,37 @@ inline bool QGraphicsItemPrivate::insertionOrder(QGraphicsItem *a, QGraphicsItem
return a->d_ptr->siblingIndex < b->d_ptr->siblingIndex;
}
+/*!
+ \internal
+*/
+inline void QGraphicsItemPrivate::markParentDirty(bool updateBoundingRect)
+{
+ QGraphicsItemPrivate *parentp = this;
+ while (parentp->parent) {
+ parentp = parentp->parent->d_ptr.data();
+ parentp->dirtyChildren = 1;
+
+ if (updateBoundingRect) {
+ parentp->dirtyChildrenBoundingRect = 1;
+ // ### Only do this if the parent's effect applies to the entire subtree.
+ parentp->notifyBoundingRectChanged = 1;
+ }
+#ifndef QT_NO_GRAPHICSEFFECT
+ if (parentp->graphicsEffect) {
+ if (updateBoundingRect) {
+ parentp->notifyInvalidated = 1;
+ static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()
+ ->source->d_func())->invalidateCache();
+ }
+ if (parentp->graphicsEffect->isEnabled()) {
+ parentp->dirty = 1;
+ parentp->fullUpdatePending = 1;
+ }
+ }
+#endif
+ }
+}
+
QT_END_NAMESPACE
#endif // QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index cea723c..842d368 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();
}
/*!
@@ -4609,7 +4630,7 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
return; // Item has neither contents nor children!(?)
const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
- const bool itemIsFullyTransparent = (opacity < 0.0001);
+ const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity);
if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity()))
return;
@@ -4729,7 +4750,7 @@ void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const Q
qreal opacity, const QTransform *effectTransform,
bool wasDirtyParentSceneTransform, bool drawItem)
{
- const bool itemIsFullyTransparent = (opacity < 0.0001);
+ const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity);
const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
const bool itemHasChildren = !item->d_ptr->children.isEmpty();
@@ -4811,7 +4832,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)
@@ -4882,17 +4904,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,
@@ -4967,7 +4980,8 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool
}
const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
- const bool itemIsFullyTransparent = !item->d_ptr->ignoreOpacity && opacity < 0.0001;
+ const bool itemIsFullyTransparent = !item->d_ptr->ignoreOpacity
+ && QGraphicsItemPrivate::isOpacityNull(opacity);
if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity())) {
resetDirtyItem(item, /*recursive=*/itemHasChildren);
return;
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..707c71f 100644
--- a/src/gui/graphicsview/qgraphicssceneindex.cpp
+++ b/src/gui/graphicsview/qgraphicssceneindex.cpp
@@ -279,7 +279,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe
return;
const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
- const bool itemIsFullyTransparent = (opacity < 0.0001);
+ const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity);
const bool itemHasChildren = !item->d_ptr->children.isEmpty();
if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity()))
return;
@@ -554,7 +554,7 @@ QList<QGraphicsItem *> QGraphicsSceneIndex::estimateTopLevelItems(const QRectF &
/*!
\fn QList<QGraphicsItem *> QGraphicsSceneIndex::items(Qt::SortOrder order = Qt::DescendingOrder) const
-
+
This pure virtual function all items in the index and sort them using
\a order.
*/
@@ -624,7 +624,7 @@ void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item)
\sa QGraphicsItem::GraphicsItemChange
*/
-void QGraphicsSceneIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value)
+void QGraphicsSceneIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const void *const value)
{
Q_UNUSED(item);
Q_UNUSED(change);
diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h
index def58f0..597a229 100644
--- a/src/gui/graphicsview/qgraphicssceneindex_p.h
+++ b/src/gui/graphicsview/qgraphicssceneindex_p.h
@@ -110,7 +110,7 @@ protected:
virtual void removeItem(QGraphicsItem *item) = 0;
virtual void deleteItem(QGraphicsItem *item);
- virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value);
+ virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const void *const value);
virtual void prepareBoundingRectChange(const QGraphicsItem *item);
QGraphicsSceneIndex(QGraphicsSceneIndexPrivate &dd, QGraphicsScene *scene);
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
index 854be2e..42e19b8 100644
--- a/src/gui/image/qbmphandler.cpp
+++ b/src/gui/image/qbmphandler.cpp
@@ -144,7 +144,7 @@ static QDataStream &operator<<(QDataStream &s, const BMP_INFOHDR &bi)
static int calc_shift(int mask)
{
int result = 0;
- while (!(mask & 1)) {
+ while (mask && !(mask & 1)) {
result++;
mask >>= 1;
}
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 4e10b5b..4f5efa1 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -3992,7 +3992,7 @@ QImage QImage::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::Transf
QSize newSize = size();
newSize.scale(s, aspectMode);
if (newSize == size())
- return copy();
+ return *this;
QTransform wm = QTransform::fromScale((qreal)newSize.width() / width(), (qreal)newSize.height() / height());
QImage img = transformed(wm, mode);
diff --git a/src/gui/image/qimagepixmapcleanuphooks.cpp b/src/gui/image/qimagepixmapcleanuphooks.cpp
index 61d538f..ace4bb6 100644
--- a/src/gui/image/qimagepixmapcleanuphooks.cpp
+++ b/src/gui/image/qimagepixmapcleanuphooks.cpp
@@ -62,12 +62,12 @@ QImagePixmapCleanupHooks *QImagePixmapCleanupHooks::instance()
return qt_image_and_pixmap_cleanup_hooks();
}
-void QImagePixmapCleanupHooks::addPixmapModificationHook(_qt_pixmap_cleanup_hook_pm hook)
+void QImagePixmapCleanupHooks::addPixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd hook)
{
pixmapModificationHooks.append(hook);
}
-void QImagePixmapCleanupHooks::addPixmapDestructionHook(_qt_pixmap_cleanup_hook_pm hook)
+void QImagePixmapCleanupHooks::addPixmapDataDestructionHook(_qt_pixmap_cleanup_hook_pmd hook)
{
pixmapDestructionHooks.append(hook);
}
@@ -78,12 +78,12 @@ void QImagePixmapCleanupHooks::addImageHook(_qt_image_cleanup_hook_64 hook)
imageHooks.append(hook);
}
-void QImagePixmapCleanupHooks::removePixmapModificationHook(_qt_pixmap_cleanup_hook_pm hook)
+void QImagePixmapCleanupHooks::removePixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd hook)
{
pixmapModificationHooks.removeAll(hook);
}
-void QImagePixmapCleanupHooks::removePixmapDestructionHook(_qt_pixmap_cleanup_hook_pm hook)
+void QImagePixmapCleanupHooks::removePixmapDataDestructionHook(_qt_pixmap_cleanup_hook_pmd hook)
{
pixmapDestructionHooks.removeAll(hook);
}
@@ -93,24 +93,24 @@ void QImagePixmapCleanupHooks::removeImageHook(_qt_image_cleanup_hook_64 hook)
imageHooks.removeAll(hook);
}
-void QImagePixmapCleanupHooks::executePixmapModificationHooks(QPixmap* pm)
+void QImagePixmapCleanupHooks::executePixmapDataModificationHooks(QPixmapData* pmd)
{
QImagePixmapCleanupHooks *h = qt_image_and_pixmap_cleanup_hooks();
for (int i = 0; i < h->pixmapModificationHooks.count(); ++i)
- h->pixmapModificationHooks[i](pm);
+ h->pixmapModificationHooks[i](pmd);
if (qt_pixmap_cleanup_hook_64)
- qt_pixmap_cleanup_hook_64(pm->cacheKey());
+ qt_pixmap_cleanup_hook_64(pmd->cacheKey());
}
-void QImagePixmapCleanupHooks::executePixmapDestructionHooks(QPixmap* pm)
+void QImagePixmapCleanupHooks::executePixmapDataDestructionHooks(QPixmapData* pmd)
{
QImagePixmapCleanupHooks *h = qt_image_and_pixmap_cleanup_hooks();
for (int i = 0; i < h->pixmapDestructionHooks.count(); ++i)
- h->pixmapDestructionHooks[i](pm);
+ h->pixmapDestructionHooks[i](pmd);
if (qt_pixmap_cleanup_hook_64)
- qt_pixmap_cleanup_hook_64(pm->cacheKey());
+ qt_pixmap_cleanup_hook_64(pmd->cacheKey());
}
void QImagePixmapCleanupHooks::executeImageHooks(qint64 key)
diff --git a/src/gui/image/qimagepixmapcleanuphooks_p.h b/src/gui/image/qimagepixmapcleanuphooks_p.h
index 7176044..88dd3a6 100644
--- a/src/gui/image/qimagepixmapcleanuphooks_p.h
+++ b/src/gui/image/qimagepixmapcleanuphooks_p.h
@@ -58,7 +58,8 @@
QT_BEGIN_NAMESPACE
typedef void (*_qt_image_cleanup_hook_64)(qint64);
-typedef void (*_qt_pixmap_cleanup_hook_pm)(QPixmap*);
+typedef void (*_qt_pixmap_cleanup_hook_pmd)(QPixmapData*);
+
class QImagePixmapCleanupHooks;
@@ -71,27 +72,27 @@ public:
static void enableCleanupHooks(const QPixmap &pixmap);
static void enableCleanupHooks(QPixmapData *pixmapData);
- // Gets called when a pixmap is about to be modified:
- void addPixmapModificationHook(_qt_pixmap_cleanup_hook_pm);
+ // Gets called when a pixmap data is about to be modified:
+ void addPixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd);
- // Gets called when a pixmap is about to be destroyed:
- void addPixmapDestructionHook(_qt_pixmap_cleanup_hook_pm);
+ // Gets called when a pixmap data is about to be destroyed:
+ void addPixmapDataDestructionHook(_qt_pixmap_cleanup_hook_pmd);
// Gets called when an image is about to be modified or destroyed:
void addImageHook(_qt_image_cleanup_hook_64);
- void removePixmapModificationHook(_qt_pixmap_cleanup_hook_pm);
- void removePixmapDestructionHook(_qt_pixmap_cleanup_hook_pm);
+ void removePixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd);
+ void removePixmapDataDestructionHook(_qt_pixmap_cleanup_hook_pmd);
void removeImageHook(_qt_image_cleanup_hook_64);
- static void executePixmapModificationHooks(QPixmap*);
- static void executePixmapDestructionHooks(QPixmap*);
+ static void executePixmapDataModificationHooks(QPixmapData*);
+ static void executePixmapDataDestructionHooks(QPixmapData*);
static void executeImageHooks(qint64 key);
private:
QList<_qt_image_cleanup_hook_64> imageHooks;
- QList<_qt_pixmap_cleanup_hook_pm> pixmapModificationHooks;
- QList<_qt_pixmap_cleanup_hook_pm> pixmapDestructionHooks;
+ QList<_qt_pixmap_cleanup_hook_pmd> pixmapModificationHooks;
+ QList<_qt_pixmap_cleanup_hook_pmd> pixmapDestructionHooks;
};
QT_END_NAMESPACE
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 674d5da..d1e5c40 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -320,8 +320,6 @@ QPixmap::QPixmap(const char * const xpm[])
QPixmap::~QPixmap()
{
Q_ASSERT(!data || data->ref >= 1); // Catch if ref-counting changes again
- if (data && data->is_cached && data->ref == 1) // ref will be decrememnted after destructor returns
- QImagePixmapCleanupHooks::executePixmapDestructionHooks(this);
}
/*!
@@ -833,14 +831,21 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers
if (QPixmapCache::find(key, *this))
return true;
- QPixmapData *tmp = QPixmapData::create(0, 0, QPixmapData::PixmapType);
- if (tmp->fromFile(fileName, format, flags)) {
- data = tmp;
- QPixmapCache::insert(key, *this);
- return true;
+ bool ok;
+
+ if (data) {
+ ok = data->fromFile(fileName, format, flags);
+ } else {
+ QScopedPointer<QPixmapData> tmp(QPixmapData::create(0, 0, QPixmapData::PixmapType));
+ ok = tmp->fromFile(fileName, format, flags);
+ if (ok)
+ data = tmp.take();
}
- delete tmp;
- return false;
+
+ if (ok)
+ QPixmapCache::insert(key, *this);
+
+ return ok;
}
/*!
@@ -1018,12 +1023,8 @@ qint64 QPixmap::cacheKey() const
if (isNull())
return 0;
- int classKey = data->classId();
- if (classKey >= 1024)
- classKey = -(classKey >> 10);
- return ((((qint64) classKey) << 56)
- | (((qint64) data->serialNumber()) << 32)
- | ((qint64) (data->detach_no)));
+ Q_ASSERT(data);
+ return data->cacheKey();
}
static void sendResizeEvents(QWidget *target)
@@ -1936,7 +1937,7 @@ void QPixmap::detach()
}
if (data->is_cached && data->ref == 1)
- QImagePixmapCleanupHooks::executePixmapModificationHooks(this);
+ QImagePixmapCleanupHooks::executePixmapDataModificationHooks(data.data());
#if defined(Q_WS_MAC)
QMacPixmapData *macData = id == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(data.data()) : 0;
diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp
index 0e66e09..e1e8a0d 100644
--- a/src/gui/image/qpixmap_x11.cpp
+++ b/src/gui/image/qpixmap_x11.cpp
@@ -68,6 +68,7 @@
#include "qx11info_x11.h"
#include <private/qdrawhelper_p.h>
#include <private/qimage_p.h>
+#include <private/qimagepixmapcleanuphooks_p.h>
#include <stdlib.h>
@@ -1228,6 +1229,12 @@ void QX11PixmapData::fill(const QColor &fillColor)
QX11PixmapData::~QX11PixmapData()
{
+ // Cleanup hooks have to be called before the handles are freed
+ if (is_cached) {
+ QImagePixmapCleanupHooks::executePixmapDataDestructionHooks(this);
+ is_cached = false;
+ }
+
release();
}
@@ -1236,8 +1243,13 @@ void QX11PixmapData::release()
delete pengine;
pengine = 0;
- if (!X11)
+ if (!X11) {
+#ifndef QT_NO_DEBUG
+ qWarning("~QX11PixmapData(): QPixmap objects must be destroyed before the QApplication"
+ " object, otherwise the native pixmap object will be leaked.");
+#endif
return;
+ }
if (x11_mask) {
#ifndef QT_NO_XRENDER
diff --git a/src/gui/image/qpixmapdata.cpp b/src/gui/image/qpixmapdata.cpp
index 65032da..ea4fe6b 100644
--- a/src/gui/image/qpixmapdata.cpp
+++ b/src/gui/image/qpixmapdata.cpp
@@ -45,6 +45,7 @@
#include <QtGui/qimagereader.h>
#include <private/qgraphicssystem_p.h>
#include <private/qapplication_p.h>
+#include <private/qimagepixmapcleanuphooks_p.h>
QT_BEGIN_NAMESPACE
@@ -80,6 +81,16 @@ QPixmapData::QPixmapData(PixelType pixelType, int objectId)
QPixmapData::~QPixmapData()
{
+ // Sometimes the pixmap cleanup hooks will be called from derrived classes, which will
+ // then set is_cached to false. For example, on X11 QtOpenGL needs to delete the GLXPixmap
+ // or EGL Pixmap Surface for a given pixmap _before_ the native X11 pixmap is deleted,
+ // otherwise some drivers will leak the GL surface. In this case, QX11PixmapData will
+ // call the cleanup hooks itself before deleting the native pixmap and set is_cached to
+ // false.
+ if (is_cached) {
+ QImagePixmapCleanupHooks::executePixmapDataDestructionHooks(this);
+ is_cached = false;
+ }
}
QPixmapData *QPixmapData::createCompatiblePixmapData() const
diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h
index 1125515..827fa18 100644
--- a/src/gui/image/qpixmapdata_p.h
+++ b/src/gui/image/qpixmapdata_p.h
@@ -117,6 +117,14 @@ public:
inline int colorCount() const { return metric(QPaintDevice::PdmNumColors); }
inline int depth() const { return d; }
inline bool isNull() const { return is_null; }
+ inline qint64 cacheKey() const {
+ int classKey = id;
+ if (classKey >= 1024)
+ classKey = -(classKey >> 10);
+ return ((((qint64) classKey) << 56)
+ | (((qint64) ser_no) << 32)
+ | ((qint64) detach_no));
+ }
#if defined(Q_OS_SYMBIAN)
virtual void* toNativeType(NativeType type);
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/qlistview.cpp b/src/gui/itemviews/qlistview.cpp
index f289c7d..19b1e8c 100644
--- a/src/gui/itemviews/qlistview.cpp
+++ b/src/gui/itemviews/qlistview.cpp
@@ -2621,6 +2621,13 @@ bool QIconModeViewBase::filterDropEvent(QDropEvent *e)
const QSize contents = contentsSize;
QPoint offset(horizontalOffset(), verticalOffset());
QPoint end = e->pos() + offset;
+ if (qq->acceptDrops()) {
+ const Qt::ItemFlags dropableFlags = Qt::ItemIsDropEnabled|Qt::ItemIsEnabled;
+ const QVector<QModelIndex> &dropIndices = intersectingSet(QRect(end, QSize(1, 1)));
+ foreach (const QModelIndex &index, dropIndices)
+ if ((index.flags() & dropableFlags) == dropableFlags)
+ return false;
+ }
QPoint start = dd->pressedPosition;
QPoint delta = (dd->movement == QListView::Snap ? snapToGrid(end) - snapToGrid(start) : end - start);
QList<QModelIndex> indexes = dd->selectionModel->selectedIndexes();
diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp
index 7eefb0b..3111896 100644
--- a/src/gui/itemviews/qtableview.cpp
+++ b/src/gui/itemviews/qtableview.cpp
@@ -114,7 +114,9 @@ void QSpanCollection::updateSpan(QSpanCollection::Span *span, int old_height)
}
} else if (old_height > span->height()) {
//remove the span from all the subspans lists that intersect the columns not covered anymore
- Index::iterator it_y = index.lowerBound(qMin(-span->bottom(), 0));
+ Index::iterator it_y = index.lowerBound(-span->bottom());
+ if (it_y == index.end())
+ it_y = index.find(-span->top()); // This is the only span remaining and we are deleting it.
Q_ASSERT(it_y != index.end()); //it_y must exist since the span is in the list
while (-it_y.key() <= span->top() + old_height -1) {
if (-it_y.key() > span->bottom()) {
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 12fe797..4fe3900 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -121,8 +121,10 @@ extern bool qt_wince_is_pocket_pc(); //qguifunctions_wince.cpp
static void initResources()
{
-#ifdef Q_WS_WINCE
+#if defined(Q_WS_WINCE)
Q_INIT_RESOURCE(qstyle_wince);
+#elif defined(Q_OS_SYMBIAN)
+ Q_INIT_RESOURCE(qstyle_s60);
#else
Q_INIT_RESOURCE(qstyle);
#endif
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
index 6aebef5..e8b821af 100644
--- a/src/gui/kernel/qapplication_mac.mm
+++ b/src/gui/kernel/qapplication_mac.mm
@@ -227,8 +227,29 @@ void onApplicationChangedActivation( bool activated );
static void qt_mac_read_fontsmoothing_settings()
{
- NSInteger appleFontSmoothing = [[NSUserDefaults standardUserDefaults] integerForKey:@"AppleFontSmoothing"];
- qt_applefontsmoothing_enabled = (appleFontSmoothing > 0);
+ qt_applefontsmoothing_enabled = true;
+ int w = 10, h = 10;
+ QImage image(w, h, QImage::Format_RGB32);
+ image.fill(0xffffffff);
+ QPainter p(&image);
+ p.drawText(0, h, "X\\");
+ p.end();
+
+ const int *bits = (const int *) ((const QImage &) image).bits();
+ int bpl = image.bytesPerLine() / 4;
+ for (int y=0; y<w; ++y) {
+ for (int x=0; x<h; ++x) {
+ int r = qRed(bits[x]);
+ int g = qGreen(bits[x]);
+ int b = qBlue(bits[x]);
+ if (r != g || r != b) {
+ qt_applefontsmoothing_enabled = true;
+ return;
+ }
+ }
+ bits += bpl;
+ }
+ qt_applefontsmoothing_enabled = false;
}
Q_GUI_EXPORT bool qt_mac_execute_apple_script(const char *script, long script_len, AEDesc *ret) {
@@ -772,11 +793,11 @@ static void qt_mac_update_intersected_gl_widgets(QWidget *widget)
qt_post_window_change_event(glWidget);
it->lastUpdateWidget = widget;
} else if (it->lastUpdateWidget == widget) {
- // Update the gl wigets that the widget intersected the last time around,
- // and that we are not intersecting now. This prevents paint errors when the
+ // Update the gl wigets that the widget intersected the last time around,
+ // and that we are not intersecting now. This prevents paint errors when the
// intersecting widget leaves a gl widget.
qt_post_window_change_event(glWidget);
- it->lastUpdateWidget = 0;
+ it->lastUpdateWidget = 0;
}
}
#else
@@ -808,8 +829,8 @@ Q_GUI_EXPORT void qt_event_request_window_change(QWidget *widget)
// Post a kEventQtRequestWindowChange event. This event is semi-public,
// don't remove this line!
qt_event_request_window_change();
-
- // Post update request on gl widgets unconditionally.
+
+ // Post update request on gl widgets unconditionally.
if (qt_widget_private(widget)->isGLWidget == true) {
qt_post_window_change_event(widget);
return;
@@ -1214,8 +1235,6 @@ void qt_init(QApplicationPrivate *priv, int)
if (QApplication::desktopSettingsAware())
QApplicationPrivate::qt_mac_apply_settings();
- qt_mac_read_fontsmoothing_settings();
-
// Cocoa application delegate
#ifdef QT_MAC_USE_COCOA
NSApplication *cocoaApp = [NSApplication sharedApplication];
@@ -1253,6 +1272,7 @@ void qt_init(QApplicationPrivate *priv, int)
}
priv->native_modal_dialog_active = false;
+ qt_mac_read_fontsmoothing_settings();
}
void qt_release_apple_event_handler()
@@ -1705,7 +1725,7 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event
// kEventMouseWheelMoved events if we dont eat this event
// (actually two events; one for horizontal and one for vertical).
// As a results of this, and to make sure we dont't receive duplicate events,
- // we try to detect when this happend by checking the 'compatibilityEvent'.
+ // we try to detect when this happend by checking the 'compatibilityEvent'.
SInt32 mdelt = 0;
GetEventParameter(event, kEventParamMouseWheelSmoothHorizontalDelta, typeSInt32, 0,
sizeof(mdelt), 0, &mdelt);
@@ -2576,7 +2596,7 @@ void QApplicationPrivate::closePopup(QWidget *popup)
if (QApplicationPrivate::popupWidgets->isEmpty()) { // this was the last popup
delete QApplicationPrivate::popupWidgets;
QApplicationPrivate::popupWidgets = 0;
-
+
// Special case for Tool windows: since they are activated and deactived together
// with a normal window they never become the QApplicationPrivate::active_window.
QWidget *appFocusWidget = QApplication::focusWidget();
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h
index f8943a8..9c001ab 100644
--- a/src/gui/kernel/qapplication_p.h
+++ b/src/gui/kernel/qapplication_p.h
@@ -501,9 +501,9 @@ public:
static TUint resolveS60ScanCode(TInt scanCode, TUint keysym);
QSet<WId> nativeWindows;
- int symbianProcessWsEvent(const TWsEvent *event);
- int symbianHandleCommand(int command);
- int symbianResourceChange(int type);
+ int symbianProcessWsEvent(const QSymbianEvent *symbianEvent);
+ int symbianHandleCommand(const QSymbianEvent *symbianEvent);
+ int symbianResourceChange(const QSymbianEvent *symbianEvent);
#endif
#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS)
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 3ee0a71..6caac9f 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -71,6 +71,7 @@
# include <private/qcoefepinputcontext_p.h>
# endif
# include <private/qs60mainapplication_p.h>
+# include <centralrepository.h>
#endif
#include "private/qstylesheetstyle_p.h"
@@ -807,6 +808,15 @@ TCoeInputCapabilities QSymbianControl::InputCapabilities() const
void QSymbianControl::Draw(const TRect& controlRect) const
{
+ // Set flag to avoid calling DrawNow in window surface
+ QWExtra *extra = qwidget->d_func()->extraData();
+ if (extra && !extra->inExpose) {
+ extra->inExpose = true;
+ QRect exposeRect = qt_TRect2QRect(controlRect);
+ qwidget->d_func()->syncBackingStore(exposeRect);
+ extra->inExpose = false;
+ }
+
QWindowSurface *surface = qwidget->windowSurface();
QPaintEngine *engine = surface ? surface->paintDevice()->paintEngine() : NULL;
@@ -855,8 +865,6 @@ void QSymbianControl::Draw(const TRect& controlRect) const
default:
Q_ASSERT(false);
}
- } else {
- surface->flush(qwidget, QRegion(qt_TRect2QRect(backingStoreRect)), QPoint());
}
if (sendNativePaintEvents) {
@@ -1197,6 +1205,24 @@ void qt_init(QApplicationPrivate * /* priv */, int)
S60->virtualMouseRequired = false;
}
+ S60->avkonComponentsSupportTransparency = false;
+
+#ifdef Q_WS_S60
+ TUid KCRUidAvkon = { 0x101F876E };
+ TUint32 KAknAvkonTransparencyEnabled = 0x0000000D;
+
+ CRepository* repository = 0;
+ TRAP(err, repository = CRepository::NewL(KCRUidAvkon));
+
+ if(err == KErrNone) {
+ TInt value = 0;
+ err = repository->Get(KAknAvkonTransparencyEnabled, value);
+ if(err == KErrNone) {
+ S60->avkonComponentsSupportTransparency = (value==1) ? true : false;
+ }
+ }
+#endif
+
if (touch) {
QApplicationPrivate::navigationMode = Qt::NavigationModeNone;
} else {
@@ -1521,6 +1547,12 @@ void QApplication::beep()
qt_S60Beep->Play();
}
+static inline bool callSymbianEventFilters(const QSymbianEvent *event)
+{
+ long unused;
+ return qApp->filterEvent(const_cast<QSymbianEvent *>(event), &unused);
+}
+
/*!
\warning This function is only available on Symbian.
\since 4.6
@@ -1537,6 +1569,9 @@ int QApplication::symbianProcessEvent(const QSymbianEvent *event)
QScopedLoopLevelCounter counter(d->threadData);
+ if (d->eventDispatcher->filterEvent(const_cast<QSymbianEvent *>(event)))
+ return 1;
+
QWidget *w = qApp ? qApp->focusWidget() : 0;
if (w) {
QInputContext *ic = w->inputContext();
@@ -1549,29 +1584,34 @@ int QApplication::symbianProcessEvent(const QSymbianEvent *event)
switch (event->type()) {
case QSymbianEvent::WindowServerEvent:
- return d->symbianProcessWsEvent(event->windowServerEvent());
+ return d->symbianProcessWsEvent(event);
case QSymbianEvent::CommandEvent:
- return d->symbianHandleCommand(event->command());
+ return d->symbianHandleCommand(event);
case QSymbianEvent::ResourceChangeEvent:
- return d->symbianResourceChange(event->resourceChangeType());
+ return d->symbianResourceChange(event);
default:
return -1;
}
}
-int QApplicationPrivate::symbianProcessWsEvent(const TWsEvent *event)
+int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent)
{
// Qt event handling. Handle some events regardless of if the handle is in our
// widget map or not.
+ const TWsEvent *event = symbianEvent->windowServerEvent();
CCoeControl* control = reinterpret_cast<CCoeControl*>(event->Handle());
const bool controlInMap = QWidgetPrivate::mapper && QWidgetPrivate::mapper->contains(control);
switch (event->Type()) {
case EEventPointerEnter:
- if (controlInMap)
+ if (controlInMap) {
+ callSymbianEventFilters(symbianEvent);
return 1; // Qt::Enter will be generated in HandlePointerL
+ }
break;
case EEventPointerExit:
if (controlInMap) {
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
if (S60) {
// mouseEvent outside our window, send leave event to last focused widget
QMouseEvent mEvent(QEvent::Leave, S60->lastPointerEventPos, S60->lastCursorPos,
@@ -1584,6 +1624,8 @@ int QApplicationPrivate::symbianProcessWsEvent(const TWsEvent *event)
}
break;
case EEventScreenDeviceChanged:
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
if (S60)
S60->updateScreenSize();
if (qt_desktopWidget) {
@@ -1596,6 +1638,8 @@ int QApplicationPrivate::symbianProcessWsEvent(const TWsEvent *event)
return 0; // Propagate to CONE
case EEventWindowVisibilityChanged:
if (controlInMap) {
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
const TWsVisibilityChangedEvent *visChangedEvent = event->VisibilityChanged();
QWidget *w = QWidgetPrivate::mapper->value(control);
if (!w->d_func()->maybeTopData())
@@ -1613,6 +1657,8 @@ int QApplicationPrivate::symbianProcessWsEvent(const TWsEvent *event)
}
break;
case EEventFocusGained:
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
#ifndef QT_NO_CURSOR
//re-enable mouse interaction
if (S60->mouseInteractionEnabled) {
@@ -1626,6 +1672,8 @@ int QApplicationPrivate::symbianProcessWsEvent(const TWsEvent *event)
#endif
break;
case EEventFocusLost:
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
#ifndef QT_NO_CURSOR
//disable mouse as may be moving to application that does not support it
if (S60->mouseInteractionEnabled) {
@@ -1677,11 +1725,16 @@ bool QApplication::symbianEventFilter(const QSymbianEvent *event)
\sa s60EventFilter(), s60ProcessEvent()
*/
-int QApplicationPrivate::symbianHandleCommand(int command)
+int QApplicationPrivate::symbianHandleCommand(const QSymbianEvent *symbianEvent)
{
Q_Q(QApplication);
int ret = 0;
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
+
+ int command = symbianEvent->command();
+
switch (command) {
#ifdef Q_WS_S60
case EAknSoftkeyExit: {
@@ -1721,14 +1774,18 @@ int QApplicationPrivate::symbianHandleCommand(int command)
Currently, KEikDynamicLayoutVariantSwitch and
KAknsMessageSkinChange are handled.
*/
-int QApplicationPrivate::symbianResourceChange(int type)
+int QApplicationPrivate::symbianResourceChange(const QSymbianEvent *symbianEvent)
{
int ret = 0;
+ int type = symbianEvent->resourceChangeType();
+
switch (type) {
#ifdef Q_WS_S60
case KEikDynamicLayoutVariantSwitch:
{
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
if (S60)
S60->updateScreenSize();
@@ -1753,6 +1810,8 @@ int QApplicationPrivate::symbianResourceChange(int type)
#ifndef QT_NO_STYLE_S60
case KAknsMessageSkinChange:
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
if (QS60Style *s60Style = qobject_cast<QS60Style*>(QApplication::style())) {
s60Style->d_func()->handleSkinChange();
ret = 1;
diff --git a/src/gui/kernel/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/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index c14798a..d255604 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -510,7 +510,7 @@ extern "C" {
}
// Make sure the opengl context is updated on resize.
- if (0 && qwidgetprivate->isGLWidget) {
+ if (qwidgetprivate->isGLWidget) {
qwidgetprivate->needWindowChange = true;
QEvent event(QEvent::MacGLWindowChange);
qApp->sendEvent(qwidget, &event);
@@ -644,6 +644,8 @@ extern "C" {
- (void)mouseEntered:(NSEvent *)event
{
+ if (qwidgetprivate->data.in_destructor)
+ return;
QEvent enterEvent(QEvent::Enter);
NSPoint windowPoint = [event locationInWindow];
NSPoint globalPoint = [[event window] convertBaseToScreen:windowPoint];
diff --git a/src/gui/kernel/qdesktopwidget.cpp b/src/gui/kernel/qdesktopwidget.cpp
index c8a4373..24b4e57 100644
--- a/src/gui/kernel/qdesktopwidget.cpp
+++ b/src/gui/kernel/qdesktopwidget.cpp
@@ -47,6 +47,11 @@ QT_BEGIN_NAMESPACE
const QRect QDesktopWidget::screenGeometry(const QWidget *widget) const
{
+ if (!widget) {
+ qWarning("QDesktopWidget::screenGeometry(): Attempt "
+ "to get the screen geometry of a null widget");
+ return QRect();
+ }
QRect rect = QWidgetPrivate::screenGeometry(widget);
if (rect.isNull())
return screenGeometry(screenNumber(widget));
@@ -55,6 +60,11 @@ const QRect QDesktopWidget::screenGeometry(const QWidget *widget) const
const QRect QDesktopWidget::availableGeometry(const QWidget *widget) const
{
+ if (!widget) {
+ qWarning("QDesktopWidget::availableGeometry(): Attempt "
+ "to get the available geometry of a null widget");
+ return QRect();
+ }
QRect rect = QWidgetPrivate::screenGeometry(widget);
if (rect.isNull())
return availableGeometry(screenNumber(widget));
diff --git a/src/gui/kernel/qeventdispatcher_mac.mm b/src/gui/kernel/qeventdispatcher_mac.mm
index eda75db..c7c7caf 100644
--- a/src/gui/kernel/qeventdispatcher_mac.mm
+++ b/src/gui/kernel/qeventdispatcher_mac.mm
@@ -569,7 +569,7 @@ bool QEventDispatcherMac::processEvents(QEventLoop::ProcessEventsFlags flags)
// in cocoa. [NSApp run] should be called at least once for any cocoa app.
if (NSModalSession session = d->currentModalSession()) {
QBoolBlocker execGuard(d->currentExecIsNSAppRun, false);
- while (!d->interrupt && [NSApp runModalSession:session] == NSRunContinuesResponse)
+ while ([NSApp runModalSession:session] == NSRunContinuesResponse && !d->interrupt)
qt_mac_waitForMoreModalSessionEvents();
if (!d->interrupt && session == d->currentModalSessionCached) {
// INVARIANT: Someone called e.g. [NSApp stopModal:] from outside the event
diff --git a/src/gui/kernel/qformlayout.cpp b/src/gui/kernel/qformlayout.cpp
index b44cd50..aebc3a5 100644
--- a/src/gui/kernel/qformlayout.cpp
+++ b/src/gui/kernel/qformlayout.cpp
@@ -1925,11 +1925,11 @@ void QFormLayoutPrivate::arrangeWidgets(const QVector<QLayoutStruct>& layouts, Q
/*
If the field on the right-hand side is tall,
we want the label to be top-aligned, but not too
- much. So we introduce a 5 / 4 factor so that it
- gets a few extra pixels at the top.
+ much. So we introduce a 7 / 4 factor so that it
+ gets some extra pixels at the top.
*/
height = qMin(height,
- qMin(label->sizeHint.height() * 5 / 4,
+ qMin(label->sizeHint.height() * 7 / 4,
label->maxSize.height()));
}
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index e36ab9b..e06a810 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -143,6 +143,9 @@ extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds)
{
+#ifdef QT_MAC_USE_COCOA
+ QMacCocoaAutoReleasePool pool;
+#endif
OSWindowRef wnd = static_cast<OSWindowRef>(window);
if (wnd) {
QWidget *widget;
@@ -1278,4 +1281,17 @@ void qt_cocoaChangeOverrideCursor(const QCursor &cursor)
}
#endif
+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/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index b417065..1163055 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -121,6 +121,7 @@ public:
int virtualMouseRequired : 1;
int qtOwnsS60Environment : 1;
int supportsPremultipliedAlpha : 1;
+ int avkonComponentsSupportTransparency : 1;
QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type
static inline void updateScreenSize();
static inline RWsSession& wsSession();
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 81a9a80..ffad38b 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -2026,6 +2026,14 @@ void QWidgetPrivate::updateIsOpaque()
}
#endif
+#ifdef Q_WS_S60
+ if (q->windowType() == Qt::Dialog && q->testAttribute(Qt::WA_TranslucentBackground)
+ && S60->avkonComponentsSupportTransparency) {
+ setOpaque(false);
+ return;
+ }
+#endif
+
if (q->testAttribute(Qt::WA_OpaquePaintEvent) || q->testAttribute(Qt::WA_PaintOnScreen)) {
setOpaque(true);
return;
@@ -3344,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 354a666..78c1562 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -110,6 +110,7 @@
#include "qevent_p.h"
#include "qdnd_p.h"
#include <QtGui/qgraphicsproxywidget.h>
+#include "qmainwindow.h"
QT_BEGIN_NAMESPACE
@@ -403,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);
}
@@ -1721,6 +1722,15 @@ bool QWidgetPrivate::qt_widget_rgn(QWidget *widget, short wcode, RgnHandle rgn,
void QWidgetPrivate::determineWindowClass()
{
Q_Q(QWidget);
+#if !defined(QT_NO_MAINWINDOW) && !defined(QT_NO_TOOLBAR)
+ // Make sure that QMainWindow has the MacWindowToolBarButtonHint when the
+ // unifiedTitleAndToolBarOnMac property is ON. This is to avoid reentry of
+ // setParent() triggered by the QToolBar::event(QEvent::ParentChange).
+ QMainWindow *mainWindow = qobject_cast<QMainWindow *>(q);
+ if (mainWindow && mainWindow->unifiedTitleAndToolBarOnMac()) {
+ data.window_flags |= Qt::MacWindowToolBarButtonHint;
+ }
+#endif
#ifndef QT_MAC_USE_COCOA
// ### COCOA:Interleave these better!
@@ -2743,7 +2753,9 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
}
if (wasWindow) {
oldToolbar = [oldWindow toolbar];
+ [oldToolbar retain];
oldToolbarVisible = [oldToolbar isVisible];
+ [oldWindow setToolbar:nil];
}
#endif
}
@@ -2787,6 +2799,7 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
if (oldToolbar && !(f & Qt::FramelessWindowHint)) {
OSWindowRef newWindow = qt_mac_window_for(q);
[newWindow setToolbar:oldToolbar];
+ [oldToolbar release];
[oldToolbar setVisible:oldToolbarVisible];
}
#endif
@@ -3401,6 +3414,38 @@ void QWidgetPrivate::hide_sys()
ShowHide(window, false);
#else
[window orderOut:window];
+ // Unfortunately it is not as easy as just hiding the window, we need
+ // to find out if we were in full screen mode. If we were and this is
+ // the last window in full screen mode then we need to unset the full screen
+ // mode. If this is not the last visible window in full screen mode then we
+ // don't change the full screen mode.
+ if(q->isFullScreen())
+ {
+ bool keepFullScreen = false;
+ QWidgetList windowList = qApp->topLevelWidgets();
+ int windowCount = windowList.count();
+ for(int i = 0; i < windowCount; i++)
+ {
+ QWidget *w = windowList[i];
+ // If it is the same window, we don't need to check :-)
+ if(q == w)
+ continue;
+ // If they are not visible or if they are minimized then
+ // we just ignore them.
+ if(!w->isVisible() || w->isMinimized())
+ continue;
+ // Is it full screen?
+ // Notice that if there is one window in full screen mode then we
+ // cannot switch the full screen mode off, therefore we just abort.
+ if(w->isFullScreen()) {
+ keepFullScreen = true;
+ break;
+ }
+ }
+ // No windows in full screen mode, so let just unset that flag.
+ if(!keepFullScreen)
+ qt_mac_set_fullscreen_mode(false);
+ }
#endif
toggleDrawers(false);
#ifndef QT_MAC_USE_COCOA
@@ -3465,6 +3510,8 @@ void QWidgetPrivate::hide_sys()
if (!QWidget::mouseGrabber()){
QWidget *enterWidget = QApplication::widgetAt(QCursor::pos());
+ if (enterWidget && enterWidget->data->in_destructor)
+ enterWidget = 0;
QApplicationPrivate::dispatchEnterLeave(enterWidget, qt_mouseover);
qt_mouseover = enterWidget;
}
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index ec8d20f..b1eb3c3 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -229,6 +229,7 @@ struct QWExtra {
#endif
#elif defined(Q_OS_SYMBIAN) // <----------------------------------------------------- Symbian
uint activated : 1; // RWindowBase::Activated has been called
+ uint inExpose : 1; // Prevents drawing recursion
/**
* Defines the behaviour of QSymbianControl::Draw.
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index c65a162..00f2213 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -389,9 +389,13 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
if (!isOpaque) {
RWindow *const window = static_cast<RWindow *>(drawableWindow);
+#ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
+ window->SetSurfaceTransparency(true);
+#else
const TDisplayMode displayMode = static_cast<TDisplayMode>(window->SetRequiredDisplayMode(EColor16MA));
if (window->SetTransparencyAlphaChannel() == KErrNone)
window->SetBackgroundColor(TRgb(255, 255, 255, 0));
+#endif
}
}
@@ -707,12 +711,16 @@ void QWidgetPrivate::s60UpdateIsOpaque()
RWindow *const window = static_cast<RWindow *>(q->effectiveWinId()->DrawableWindow());
+#ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
+ window->SetSurfaceTransparency(!isOpaque);
+#else
if (!isOpaque) {
const TDisplayMode displayMode = static_cast<TDisplayMode>(window->SetRequiredDisplayMode(EColor16MA));
if (window->SetTransparencyAlphaChannel() == KErrNone)
window->SetBackgroundColor(TRgb(255, 255, 255, 0));
} else
window->SetTransparentRegion(TRegionFix<1>());
+#endif
}
void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
@@ -883,6 +891,7 @@ void QWidgetPrivate::createSysExtra()
extra->activated = 0;
extra->nativePaintMode = QWExtra::Default;
extra->receiveNativePaintEvents = 0;
+ extra->inExpose = 0;
}
void QWidgetPrivate::deleteSysExtra()
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 e441a6b..5e5d9b8 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -267,13 +267,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/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index b61821d..faf5a37 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -418,13 +418,6 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
} else if (style == Qt::NoPen) {
d->activeStroker = 0;
} else {
- // ### re-enable...
- if (pen.isCosmetic()) {
- d->dasher.setClipRect(d->exDeviceRect);
- } else {
- QRectF clipRect = state()->matrix.inverted().mapRect(QRectF(d->exDeviceRect));
- d->dasher.setClipRect(clipRect);
- }
d->dasher.setDashPattern(pen.dashPattern());
d->dasher.setDashOffset(pen.dashOffset());
d->activeStroker = &d->dasher;
@@ -435,6 +428,15 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
return;
}
+ if (pen.style() > Qt::SolidLine) {
+ if (pen.isCosmetic()) {
+ d->activeStroker->setClipRect(d->exDeviceRect);
+ } else {
+ QRectF clipRect = state()->matrix.inverted().mapRect(QRectF(d->exDeviceRect));
+ d->activeStroker->setClipRect(clipRect);
+ }
+ }
+
const QPainterPath::ElementType *types = path.elements();
const qreal *points = path.points();
int pointCount = path.elementCount();
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 4f675ae..4338a5f 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -1376,9 +1376,6 @@ void QPainterPrivate::updateState(QPainterState *newState)
opacity with non-smooth transformation mode
(\c QPainter::SmoothPixmapTransform not enabled as a render hint).
- \o Text drawing with regular font sizes with simple
- transformations with solid colors using no or 8-bit antialiasing.
-
\o Rectangle fills with solid color, two-color linear gradients
and simple transforms.
@@ -1986,9 +1983,14 @@ QPaintEngine *QPainter::paintEngine() const
/*!
\since 4.6
- Flushes the painting pipeline and prepares for the user issuing
- commands directly to the underlying graphics context. Must be
- followed by a call to endNativePainting().
+ Flushes the painting pipeline and prepares for the user issuing commands
+ directly to the underlying graphics context. Must be followed by a call to
+ endNativePainting().
+
+ Note that only the states the underlying paint engine changes will be reset
+ to their respective default states. If, for example, the OpenGL polygon
+ mode is changed by the user inside a beginNativePaint()/endNativePainting()
+ block, it will not be reset to the default state by endNativePainting().
Here is an example that shows intermixing of painter commands
and raw OpenGL commands:
@@ -2012,9 +2014,9 @@ void QPainter::beginNativePainting()
/*!
\since 4.6
- Restores the painter after manually issuing native painting commands.
- Lets the painter restore any native state that it relies on before
- calling any other painter commands.
+ Restores the painter after manually issuing native painting commands. Lets
+ the painter restore any native state that it relies on before calling any
+ other painter commands.
\sa beginNativePainting()
*/
@@ -7502,10 +7504,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.
@@ -7515,9 +7522,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()
*/
@@ -7549,14 +7557,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)
@@ -7567,6 +7585,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
@@ -7588,9 +7607,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)
@@ -7603,6 +7631,9 @@ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
return widgetPrivate->redirected(offset);
}
+ if (!globalRedirectionAtomic() || *globalRedirectionAtomic() == 0)
+ return 0;
+
QMutexLocker locker(globalRedirectionsMutex());
QPaintDeviceRedirectionList *redirections = globalRedirections();
Q_ASSERT(redirections != 0);
@@ -7620,6 +7651,9 @@ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
void qt_painter_removePaintDevice(QPaintDevice *dev)
{
+ if (!globalRedirectionAtomic() || *globalRedirectionAtomic() == 0)
+ return;
+
QMutex *mutex = 0;
QT_TRY {
mutex = globalRedirectionsMutex();
diff --git a/src/gui/painting/qprintengine_pdf.cpp b/src/gui/painting/qprintengine_pdf.cpp
index e3a2461..b8bf15e 100644
--- a/src/gui/painting/qprintengine_pdf.cpp
+++ b/src/gui/painting/qprintengine_pdf.cpp
@@ -931,14 +931,24 @@ void QPdfEnginePrivate::writeHeader()
void QPdfEnginePrivate::writeInfo()
{
info = addXrefEntry(-1);
- xprintf("<<\n"
- "/Title (%s)\n"
-// "/Author (%s)\n"
- "/Creator (%s)\n"
- "/Producer (Qt " QT_VERSION_STR " (C) 2009 Nokia Corporation and/or its subsidiary(-ies))\n",
- title.toUtf8().constData(),
-// author.toUtf8().constData(),
- creator.toUtf8().constData());
+
+ // The 'text string' type in PDF is encoded either as PDFDocEncoding, or
+ // Unicode UTF-16 with a Unicode byte order mark as the first character
+ // (0xfeff), with the high-order byte first.
+ QByteArray array("<<\n/Title (\xfe\xff");
+ const ushort *utf16Title = title.utf16();
+ for (int i=0; i < title.size(); ++i) {
+ array.append((*(utf16Title + i)) >> 8);
+ array.append((*(utf16Title + i)) & 0xff);
+ }
+ array.append(")\n/Creator (\xfe\xff");
+ const ushort *utf16Creator = creator.utf16();
+ for (int i=0; i < creator.size(); ++i) {
+ array.append((*(utf16Creator + i)) >> 8);
+ array.append((*(utf16Creator + i)) & 0xff);
+ }
+ array.append(")\n/Producer (Qt " QT_VERSION_STR " (C) 2010 Nokia Corporation and/or its subsidiary(-ies))\n");
+ write(array);
QDateTime now = QDateTime::currentDateTime().toUTC();
QTime t = now.time();
diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp
index b8eaead..b41dc2c 100644
--- a/src/gui/painting/qwindowsurface_s60.cpp
+++ b/src/gui/painting/qwindowsurface_s60.cpp
@@ -145,10 +145,12 @@ QImage* QS60WindowSurface::buffer(const QWidget *widget)
void QS60WindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &)
{
- const QVector<QRect> subRects = region.rects();
- for (int i = 0; i < subRects.count(); ++i) {
- TRect tr = qt_QRect2TRect(subRects[i]);
+ QWExtra *extra = widget->d_func()->extraData();
+ if (extra && !extra->inExpose) {
+ extra->inExpose = true; // Prevent DrawNow() from calling syncBackingStore() again
+ TRect tr = qt_QRect2TRect(region.boundingRect());
widget->winId()->DrawNow(tr);
+ extra->inExpose = false;
}
}
diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp
index abb9e1e..b5f052b 100644
--- a/src/gui/styles/qgtkstyle.cpp
+++ b/src/gui/styles/qgtkstyle.cpp
@@ -1106,8 +1106,14 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
// ### Note: Ubuntulooks breaks when the proper widget is passed
// Murrine engine requires a widget not to get RGBA check - warnings
GtkWidget *gtkCheckButton = d->gtkWidget(QLS("GtkCheckButton"));
- gtkPainter.paintOption(gtkCheckButton , buttonRect, state, shadow, gtkRadioButton->style, QLS("radiobutton"));
-
+ QString key(QLS("radiobutton"));
+ if (option->state & State_HasFocus) { // Themes such as Nodoka check this flag
+ key += QLatin1Char('f');
+ GTK_WIDGET_SET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS);
+ }
+ gtkPainter.paintOption(gtkCheckButton , buttonRect, state, shadow, gtkRadioButton->style, key);
+ if (option->state & State_HasFocus)
+ GTK_WIDGET_UNSET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS);
}
break;
@@ -1128,6 +1134,11 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
int spacing;
GtkWidget *gtkCheckButton = d->gtkWidget(QLS("GtkCheckButton"));
+ QString key(QLS("checkbutton"));
+ if (option->state & State_HasFocus) { // Themes such as Nodoka checks this flag
+ key += QLatin1Char('f');
+ GTK_WIDGET_SET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS);
+ }
// Some styles such as aero-clone assume they can paint in the spacing area
gtkPainter.setClipRect(option->rect);
@@ -1137,7 +1148,10 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
QRect checkRect = option->rect.adjusted(spacing, spacing, -spacing, -spacing);
gtkPainter.paintCheckbox(gtkCheckButton, checkRect, state, shadow, gtkCheckButton->style,
- QLS("checkbutton"));
+ key);
+ if (option->state & State_HasFocus)
+ GTK_WIDGET_UNSET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS);
+
}
break;
@@ -1377,7 +1391,7 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom
else {
gtkCachedPainter.paintFlatBox(gtkEntry, "entry_bg", contentRect,
option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE,
- GTK_SHADOW_NONE, gtkCombo->style, entryPath + QString::number(focus));
+ GTK_SHADOW_NONE, gtkEntry->style, entryPath + QString::number(focus));
}
gtkCachedPainter.paintShadow(gtkEntry, comboBox->editable ? "entry" : "frame", frameRect, frameState,
diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm
index 97d69b2..7a680f2 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);
@@ -4309,8 +4341,6 @@ QRect QMacStyle::subElementRect(SubElement sr, const QStyleOption *opt,
rect.setY(0);
rect.setHeight(widget->height());
}
- if (opt->direction == Qt::RightToLeft)
- rect.adjust(15, 0, -20, 0);
}
break;
case SE_ProgressBarGroove:
diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp
index ca0b8c7..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)
@@ -3056,11 +3213,13 @@ bool qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QBrush
const QPaintDevice *target = painter->device();
if (target->devType() == QInternal::Widget) {
const QWidget *widget = static_cast<const QWidget *>(target);
- const QVector<QRect> &rects = rgn.rects();
- for (int i = 0; i < rects.size(); ++i) {
- const QRect rect(rects.at(i));
- painter->drawPixmap(rect.topLeft(), backgroundTexture,
- rect.translated(qt_s60_fill_background_offset(widget)));
+ if (!widget->testAttribute(Qt::WA_TranslucentBackground)) {
+ const QVector<QRect> &rects = rgn.rects();
+ for (int i = 0; i < rects.size(); ++i) {
+ const QRect rect(rects.at(i));
+ painter->drawPixmap(rect.topLeft(), backgroundTexture,
+ rect.translated(qt_s60_fill_background_offset(widget)));
+ }
}
}
return true;
diff --git a/src/gui/styles/qs60style.h b/src/gui/styles/qs60style.h
index adcb313..82cc21c 100644
--- a/src/gui/styles/qs60style.h
+++ b/src/gui/styles/qs60style.h
@@ -94,6 +94,9 @@ protected Q_SLOTS:
QIcon standardIconImplementation(
StandardPixmap standardIcon, const QStyleOption * option = 0, const QWidget * widget = 0 ) const;
+protected:
+ void timerEvent(QTimerEvent *event);
+ bool eventFilter(QObject *o, QEvent *e);
private:
Q_DISABLE_COPY(QS60Style)
friend class QStyleFactory;
diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h
index 1417552..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 be61073..872bc2b 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();
@@ -731,7 +844,6 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(QS60StylePrivate::SkinFr
MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
QPixmap result;
-// QS60WindowSurface::unlockBitmapHeap();
static const TDisplayMode displayMode = S60->supportsPremultipliedAlpha ? Q_SYMBIAN_ECOLOR16MAP : EColor16MA;
static const TInt drawParam = S60->supportsPremultipliedAlpha ? KAknsDrawParamDefault : KAknsDrawParamNoClearUnderImage|KAknsDrawParamRGBOnly;
@@ -985,8 +1097,13 @@ void QS60StylePrivate::setActiveLayout()
m_pmPointer = data[activeLayoutIndex];
}
+Q_GLOBAL_STATIC(QList<QS60StyleAnimation *>, m_animations)
+
QS60StylePrivate::QS60StylePrivate()
{
+ //Animation defaults need to be created when style is instantiated
+ QS60StyleAnimation* progressBarAnimation = new QS60StyleAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim, 7, 100);
+ m_animations()->append(progressBarAnimation);
// No need to set active layout, if dynamic metrics API is available
setActiveLayout();
}
@@ -1187,6 +1304,11 @@ void QS60StylePrivate::handleSkinChange()
setThemePalette(topLevelWidget);
topLevelWidget->ensurePolished();
}
+#ifndef QT_NO_PROGRESSBAR
+ //re-start animation timer
+ stopAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); //todo: once we have more animations, we could say "stop all running ones"
+ startAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); //and "re-start all previously running ones"
+#endif
}
QSize QS60StylePrivate::naviPaneSize()
@@ -1206,6 +1328,121 @@ QSize QS60StyleModeSpecifics::naviPaneSize()
return QSize(0,0);
}
+int QS60StylePrivate::currentAnimationFrame(QS60StyleEnums::SkinParts part)
+{
+ QS60StyleAnimation *animation = animationDefinition(part);
+ // todo: looping could be done in QS60Style::timerEvent
+ if (animation->frameCount() == animation->currentFrame())
+ animation->setCurrentFrame(0);
+ return animation->currentFrame();
+}
+
+QS60StyleAnimation* QS60StylePrivate::animationDefinition(QS60StyleEnums::SkinParts part)
+{
+ int i = 0;
+ const int animationsCount = m_animations()->isEmpty() ? 0 : m_animations()->count();
+ for(; i < animationsCount; i++) {
+ if (part == m_animations()->at(i)->animationId())
+ break;
+ }
+ return m_animations()->at(i);
+}
+
+void QS60StylePrivate::startAnimation(QS60StyleEnums::SkinParts animationPart)
+{
+ Q_Q(QS60Style);
+
+ //Query animation data from theme and store values to local struct.
+ QVariant themeAnimationDataVariant = QS60StyleModeSpecifics::themeDefinition(
+ QS60StyleEnums::TD_AnimationData, animationPart);
+ QList<QVariant> themeAnimationData = themeAnimationDataVariant.toList();
+
+ QS60StyleAnimation *animation = QS60StylePrivate::animationDefinition(animationPart);
+ if (animation) {
+ if (themeAnimationData.at(QS60StyleEnums::AD_Interval).toInt() != 0)
+ animation->setInterval(themeAnimationData.at(QS60StyleEnums::AD_Interval).toInt());
+
+ if (themeAnimationData.at(QS60StyleEnums::AD_NumberOfFrames).toInt() != 0)
+ animation->setFrameCount(themeAnimationData.at(QS60StyleEnums::AD_NumberOfFrames).toInt());
+
+ //todo: playmode is ignored for now, since it seems to return invalid data on some themes
+ //lets use the table values for play mode
+
+ animation->setCurrentFrame(0); //always initialize
+ const int timerId = q->startTimer(animation->interval());
+ animation->setTimerId(timerId);
+ }
+}
+
+void QS60StylePrivate::stopAnimation(QS60StyleEnums::SkinParts animationPart)
+{
+ Q_Q(QS60Style);
+
+ QS60StyleAnimation *animation = QS60StylePrivate::animationDefinition(animationPart);
+ if (animation) {
+ animation->setCurrentFrame(0);
+ if (animation->timerId() != 0) {
+ q->killTimer(animation->timerId());
+ animation->setTimerId(0);
+ }
+ animation->resetToDefaults();
+ }
+}
+
+QVariant QS60StyleModeSpecifics::themeDefinition(
+ QS60StyleEnums::ThemeDefinitions definition, QS60StyleEnums::SkinParts part)
+{
+ MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
+
+ Q_ASSERT(skinInstance);
+
+ switch(definition) {
+ //Animation definitions
+ case QS60StyleEnums::TD_AnimationData:
+ {
+ CAknsBmpAnimItemData *animationData;
+ TAknsItemID animationSkinId = partSpecificThemeId(part);
+ QList<QVariant> list;
+
+ TRAPD( error, QT_TRYCATCH_LEAVING(
+ animationData = static_cast<CAknsBmpAnimItemData*>(skinInstance->CreateUncachedItemDataL(
+ animationSkinId, EAknsITBmpAnim))));
+ if (error)
+ return list;
+
+ if (animationData) {
+ list.append((int)animationData->FrameInterval());
+ list.append((int)animationData->NumberOfImages());
+
+ QS60StyleEnums::AnimationMode playMode;
+ switch(animationData->PlayMode()) {
+ case CBitmapAnimClientData::EPlay:
+ playMode = QS60StyleEnums::AM_PlayOnce;
+ break;
+ case CBitmapAnimClientData::ECycle:
+ playMode = QS60StyleEnums::AM_Looping;
+ break;
+ case CBitmapAnimClientData::EBounce:
+ playMode = QS60StyleEnums::AM_Bounce;
+ break;
+ default:
+ break;
+ }
+ list.append(QVariant((int)playMode));
+ delete animationData;
+ } else {
+ list.append(0);
+ list.append(0);
+ }
+ return list;
+ }
+ break;
+ default:
+ break;
+ }
+ return QVariant();
+}
+
#endif // Q_WS_S60
QT_END_NAMESPACE
diff --git a/src/gui/styles/qs60style_simulated.cpp b/src/gui/styles/qs60style_simulated.cpp
index bd43eb7..f87cf28 100644
--- a/src/gui/styles/qs60style_simulated.cpp
+++ b/src/gui/styles/qs60style_simulated.cpp
@@ -342,6 +342,11 @@ bool QS60StylePrivate::hasSliderGrooveGraphic()
return false;
}
+bool QS60StylePrivate::isSingleClickUi()
+{
+ return false;
+}
+
QFont QS60StylePrivate::s60Font_specific(
QS60StyleEnums::FontCategories fontCategory,
int pointSize, bool resolveFontSize)
@@ -364,6 +369,11 @@ QFont QS60StylePrivate::s60Font_specific(
return result;
}
+int QS60StylePrivate::currentAnimationFrame(QS60StyleEnums::SkinParts part)
+{
+ return 0;
+}
+
/*!
Constructs a QS60Style object.
*/
diff --git a/src/gui/styles/qstyle_s60.qrc b/src/gui/styles/qstyle_s60.qrc
new file mode 100644
index 0000000..dbee38b
--- /dev/null
+++ b/src/gui/styles/qstyle_s60.qrc
@@ -0,0 +1,137 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/trolltech/styles/commonstyle">
+<!-- <file>images/filelink-16.png</file> -->
+<file>images/filelink-32.png</file>
+<!-- <file>images/filelink-128.png</file> -->
+<!-- <file>images/file-16.png</file> -->
+<file>images/file-32.png</file>
+<!-- <file>images/file-128.png</file> -->
+<!-- <file>images/newdirectory-16.png</file> -->
+<file>images/newdirectory-32.png</file>
+<!-- <file>images/newdirectory-128.png</file> -->
+<!-- <file>images/parentdir-16.png</file> -->
+<file>images/parentdir-32.png</file>
+<!-- <file>images/parentdir-128.png</file> -->
+<!-- <file>images/dvd-16.png</file> -->
+<!-- <file>images/dvd-32.png</file> -->
+<!-- <file>images/dvd-128.png</file> -->
+<!-- <file>images/cdr-16.png</file> -->
+<!-- <file>images/cdr-32.png</file> -->
+<!-- <file>images/cdr-128.png</file> -->
+<!-- <file>images/floppy-16.png</file> -->
+<!-- <file>images/floppy-32.png</file> -->
+<!-- <file>images/floppy-128.png</file> -->
+<!-- <file>images/harddrive-16.png</file> -->
+<file>images/harddrive-32.png</file>
+<!-- <file>images/harddrive-128.png</file> -->
+<!-- <file>images/trash-16.png</file> -->
+<!-- <file>images/trash-32.png</file> -->
+<!-- <file>images/trash-128.png</file> -->
+<!-- <file>images/networkdrive-16.png</file> -->
+<!-- <file>images/networkdrive-32.png</file> -->
+<!-- <file>images/networkdrive-128.png</file> -->
+<!-- <file>images/computer-16.png</file> -->
+<!-- <file>images/computer-32.png</file> -->
+<!-- <file>images/desktop-16.png</file> -->
+<file>images/desktop-32.png</file>
+<!-- <file>images/dirclosed-16.png</file> -->
+<file>images/dirclosed-32.png</file>
+<!-- <file>images/dirclosed-128.png</file> -->
+<!-- <file>images/dirlink-16.png</file> -->
+<file>images/dirlink-32.png</file>
+<!-- <file>images/dirlink-128.png</file> -->
+<!-- <file>images/diropen-16.png</file> -->
+<file>images/diropen-32.png</file>
+<!-- <file>images/diropen-128.png</file> -->
+<!-- <file>images/left-16.png</file> -->
+<file>images/left-32.png</file>
+<!-- <file>images/left-128.png</file> -->
+<!-- <file>images/right-16.png</file> -->
+<file>images/right-32.png</file>
+<!-- <file>images/right-128.png</file> -->
+<!-- <file>images/up-16.png</file> -->
+<file>images/up-32.png</file>
+<!-- <file>images/up-128.png</file> -->
+<!-- <file>images/down-16.png</file> -->
+<file>images/down-32.png</file>
+<!-- <file>images/down-128.png</file> -->
+<!-- <file>images/filecontents-16.png</file> -->
+<file>images/filecontents-32.png</file>
+<!-- <file>images/filecontents-128.png</file> -->
+<!-- <file>images/fileinfo-16.png</file> -->
+<file>images/fileinfo-32.png</file>
+<!-- <file>images/fileinfo-128.png</file> -->
+<!-- <file>images/viewdetailed-16.png</file> -->
+<file>images/viewdetailed-32.png</file>
+<!-- <file>images/viewdetailed-128.png</file> -->
+<!-- <file>images/viewlist-16.png</file> -->
+<file>images/viewlist-32.png</file>
+<!-- <file>images/viewlist-128.png</file> -->
+<file>images/fontbitmap-16.png</file>
+<file>images/fonttruetype-16.png</file>
+<!-- <file>images/standardbutton-apply-128.png</file> -->
+<!-- <file>images/standardbutton-apply-16.png</file> -->
+<file>images/standardbutton-apply-32.png</file>
+<!-- <file>images/standardbutton-cancel-128.png</file> -->
+<!-- <file>images/standardbutton-cancel-16.png</file> -->
+<file>images/standardbutton-cancel-32.png</file>
+<!-- <file>images/standardbutton-clear-128.png</file> -->
+<!-- <file>images/standardbutton-clear-16.png</file> -->
+<file>images/standardbutton-clear-32.png</file>
+<!-- <file>images/standardbutton-close-128.png</file> -->
+<!-- <file>images/standardbutton-close-16.png</file> -->
+<file>images/standardbutton-close-32.png</file>
+<!-- <file>images/standardbutton-delete-128.png</file> -->
+<!-- <file>images/standardbutton-delete-16.png</file> -->
+<file>images/standardbutton-delete-32.png</file>
+<!-- <file>images/standardbutton-help-128.png</file> -->
+<!-- <file>images/standardbutton-help-16.png</file> -->
+<file>images/standardbutton-help-32.png</file>
+<!-- <file>images/standardbutton-no-128.png</file> -->
+<!-- <file>images/standardbutton-no-16.png</file> -->
+<file>images/standardbutton-no-32.png</file>
+<!-- <file>images/standardbutton-ok-128.png</file> -->
+<!-- <file>images/standardbutton-ok-16.png</file> -->
+<file>images/standardbutton-ok-32.png</file>
+<!-- <file>images/standardbutton-open-128.png</file> -->
+<!-- <file>images/standardbutton-open-16.png</file> -->
+<file>images/standardbutton-open-32.png</file>
+<!-- <file>images/standardbutton-save-128.png</file> -->
+<!-- <file>images/standardbutton-save-16.png</file> -->
+<file>images/standardbutton-save-32.png</file>
+<!-- <file>images/standardbutton-yes-128.png</file> -->
+<!-- <file>images/standardbutton-yes-16.png</file> -->
+<file>images/standardbutton-yes-32.png</file>
+<file>images/standardbutton-closetab-16.png</file>
+<file>images/standardbutton-closetab-down-16.png</file>
+<file>images/standardbutton-closetab-hover-16.png</file>
+<!-- <file>images/refresh-24.png</file> -->
+<file>images/refresh-32.png</file>
+<!-- <file>images/stop-24.png</file> -->
+<file>images/stop-32.png</file>
+<!-- <file>images/media-stop-16.png</file> -->
+<file>images/media-stop-32.png</file>
+<!-- <file>images/media-play-16.png</file> -->
+<file>images/media-play-32.png</file>
+<!-- <file>images/media-pause-16.png</file> -->
+<file>images/media-pause-32.png</file>
+<!-- <file>images/media-seek-forward-16.png</file> -->
+<file>images/media-seek-forward-32.png</file>
+<!-- <file>images/media-seek-backward-16.png</file> -->
+<file>images/media-seek-backward-32.png</file>
+<!-- <file>images/media-skip-forward-16.png</file> -->
+<file>images/media-skip-forward-32.png</file>
+<!-- <file>images/media-skip-backward-16.png</file> -->
+<file>images/media-skip-backward-32.png</file>
+<file>images/media-volume-16.png</file>
+<file>images/media-volume-muted-16.png</file>
+</qresource>
+<!--
+<qresource prefix="/trolltech/styles/macstyle">
+<file>images/closedock-16.png</file>
+<file>images/closedock-down-16.png</file>
+<file>images/dockdock-16.png</file>
+<file>images/dockdock-down-16.png</file>
+</qresource>
+-->
+</RCC>
diff --git a/src/gui/styles/styles.pri b/src/gui/styles/styles.pri
index 7e5c55a..676f59e 100644
--- a/src/gui/styles/styles.pri
+++ b/src/gui/styles/styles.pri
@@ -23,10 +23,12 @@ SOURCES += \
styles/qstylesheetstyle.cpp \
styles/qstylesheetstyle_default.cpp
-!wince* {
- RESOURCES += styles/qstyle.qrc
+wince* {
+ RESOURCES += styles/qstyle_wince.qrc
+} else:symbian {
+ RESOURCES += styles/qstyle_s60.qrc
} else {
- RESOURCES += styles/qstyle_wince.qrc
+ RESOURCES += styles/qstyle.qrc
}
contains( styles, all ) {
@@ -168,7 +170,7 @@ contains( styles, s60 ):contains(QT_CONFIG, s60) {
SOURCES += styles/qs60style.cpp
symbian {
SOURCES += styles/qs60style_s60.cpp
- LIBS += -laknicon -laknskins -laknskinsrv -lfontutils -legul
+ LIBS += -laknicon -laknskins -laknskinsrv -lfontutils -legul -lbmpanim
} else {
SOURCES += styles/qs60style_simulated.cpp
RESOURCES += styles/qstyle_s60_simulated.qrc
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 4c57dff..bbd35f1 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -1614,7 +1614,11 @@ bool QFont::operator==(const QFont &f) const
&& f.d->overline == d->overline
&& f.d->strikeOut == d->strikeOut
&& f.d->kerning == d->kerning
- && f.d->capital == d->capital));
+ && f.d->capital == d->capital
+ && f.d->letterSpacingIsAbsolute == d->letterSpacingIsAbsolute
+ && f.d->letterSpacing == d->letterSpacing
+ && f.d->wordSpacing == d->wordSpacing
+ ));
}
@@ -1648,6 +1652,10 @@ bool QFont::operator<(const QFont &f) const
#endif // Q_WS_X11
if (f.d->capital != d->capital) return f.d->capital < d->capital;
+ if (f.d->letterSpacingIsAbsolute != d->letterSpacingIsAbsolute) return f.d->letterSpacingIsAbsolute < d->letterSpacingIsAbsolute;
+ if (f.d->letterSpacing != d->letterSpacing) return f.d->letterSpacing < d->letterSpacing;
+ if (f.d->wordSpacing != d->wordSpacing) return f.d->wordSpacing < d->wordSpacing;
+
int f1attrs = (f.d->underline << 3) + (f.d->overline << 2) + (f.d->strikeOut<<1) + f.d->kerning;
int f2attrs = (d->underline << 3) + (d->overline << 2) + (d->strikeOut<<1) + d->kerning;
return f1attrs < f2attrs;
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 e41c2be..d92168a 100644
--- a/src/gui/widgets/qmainwindowlayout_mac.mm
+++ b/src/gui/widgets/qmainwindowlayout_mac.mm
@@ -472,10 +472,27 @@ 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
+ OSWindowRef window = qt_mac_window_for(layoutState.mainWindow);
+ NSToolbar *macToolbar = [window toolbar];
+ if (macToolbar) {
+ [[macToolbar delegate] release];
+ [macToolbar setDelegate:nil];
+ }
+#endif
}
void QMainWindowLayout::fixSizeInUnifiedToolbar(QToolBar *tb) const
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 cd7f9bd..7e4bbb5 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)
{
@@ -1830,6 +1846,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();
}
@@ -1933,20 +1955,6 @@ static bool qt_mac_should_disable_menu(QMenuBar *menuBar, QWidget *modalWidget)
return qt_mac_is_ancestor(menuBar->parentWidget(), modalWidget);
}
-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];
- }
- }
-#endif
-}
-
/*!
\internal