summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorAaron McCarthy <aaron.mccarthy@nokia.com>2010-02-11 06:09:18 (GMT)
committerAaron McCarthy <aaron.mccarthy@nokia.com>2010-02-11 06:09:18 (GMT)
commit9a76a90b1944db52bd4180d27c01781fbb3499d4 (patch)
tree46ac1557761e30127330520d2fa6412305e07443 /src/gui
parentb5fe99c0105a9791e34a8b959822430497a4aeb9 (diff)
parentb9907e309885b4b8ce280c721231a56a583b51d0 (diff)
downloadQt-9a76a90b1944db52bd4180d27c01781fbb3499d4.zip
Qt-9a76a90b1944db52bd4180d27c01781fbb3499d4.tar.gz
Qt-9a76a90b1944db52bd4180d27c01781fbb3499d4.tar.bz2
Merge remote branch 'origin/4.6' into bearermanagement/integration
Conflicts: src/s60installs/s60installs.pro
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/dialogs/qfiledialog.cpp3
-rw-r--r--src/gui/dialogs/qprintdialog.h6
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp8
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h10
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp32
-rw-r--r--src/gui/graphicsview/qgraphicssceneindex.cpp4
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp1
-rw-r--r--src/gui/gui.pro3
-rw-r--r--src/gui/image/qicon.cpp17
-rw-r--r--src/gui/image/qimagepixmapcleanuphooks.cpp20
-rw-r--r--src/gui/image/qimagepixmapcleanuphooks_p.h23
-rw-r--r--src/gui/image/qimagereader.cpp28
-rw-r--r--src/gui/image/qpixmap.cpp12
-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/image/qpixmapfilter.cpp17
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_p.h5
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp34
-rw-r--r--src/gui/itemviews/qfileiconprovider.cpp5
-rw-r--r--src/gui/itemviews/qitemdelegate.cpp2
-rw-r--r--src/gui/itemviews/qlistview.cpp2
-rw-r--r--src/gui/kernel/kernel.pri53
-rw-r--r--src/gui/kernel/qaction.cpp4
-rw-r--r--src/gui/kernel/qapplication_mac.mm6
-rw-r--r--src/gui/kernel/qapplication_p.h2
-rw-r--r--src/gui/kernel/qapplication_s60.cpp31
-rw-r--r--src/gui/kernel/qapplication_win.cpp28
-rw-r--r--src/gui/kernel/qapplication_x11.cpp8
-rw-r--r--src/gui/kernel/qclipboard_mac.cpp12
-rw-r--r--src/gui/kernel/qclipboard_s60.cpp3
-rw-r--r--src/gui/kernel/qcocoapanel_mac.mm3
-rw-r--r--src/gui/kernel/qcocoasharedwindowmethods_mac_p.h20
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm16
-rw-r--r--src/gui/kernel/qcocoawindow_mac_p.h3
-rw-r--r--src/gui/kernel/qdesktopwidget_s60.cpp18
-rw-r--r--src/gui/kernel/qdnd_x11.cpp2
-rw-r--r--src/gui/kernel/qkeymapper_x11.cpp14
-rw-r--r--src/gui/kernel/qmime_mac.cpp4
-rw-r--r--src/gui/kernel/qsoftkeymanager.cpp209
-rw-r--r--src/gui/kernel/qsoftkeymanager_common_p.h82
-rw-r--r--src/gui/kernel/qsoftkeymanager_p.h22
-rw-r--r--src/gui/kernel/qsoftkeymanager_s60.cpp404
-rw-r--r--src/gui/kernel/qsoftkeymanager_s60_p.h111
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm2
-rw-r--r--src/gui/kernel/qt_s60_p.h6
-rw-r--r--src/gui/kernel/qwidget.cpp31
-rw-r--r--src/gui/kernel/qwidget_mac.mm21
-rw-r--r--src/gui/kernel/qwidget_p.h5
-rw-r--r--src/gui/kernel/qwidget_s60.cpp114
-rw-r--r--src/gui/kernel/qwidget_x11.cpp77
-rw-r--r--src/gui/painting/qdrawhelper.cpp40
-rw-r--r--src/gui/painting/qdrawhelper_mmx_p.h45
-rw-r--r--src/gui/painting/qdrawhelper_p.h3
-rw-r--r--src/gui/painting/qmath_p.h6
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp9
-rw-r--r--src/gui/painting/qpaintengine_x11.cpp3
-rw-r--r--src/gui/painting/qpainter.cpp27
-rw-r--r--src/gui/painting/qpathclipper.cpp6
-rw-r--r--src/gui/painting/qpathclipper_p.h2
-rw-r--r--src/gui/painting/qwindowsurface_raster.cpp4
-rw-r--r--src/gui/painting/qwindowsurface_s60.cpp11
-rw-r--r--src/gui/styles/qcommonstyle.cpp6
-rw-r--r--src/gui/styles/qmacstyle_mac.mm33
-rw-r--r--src/gui/styles/qs60style.cpp41
-rw-r--r--src/gui/styles/qstylesheetstyle.cpp2
-rw-r--r--src/gui/text/qfont.cpp5
-rw-r--r--src/gui/text/qfontdatabase_s60.cpp11
-rw-r--r--src/gui/text/qfontengine_s60.cpp70
-rw-r--r--src/gui/text/qfontengine_s60_p.h13
-rw-r--r--src/gui/text/qtextlayout.cpp6
-rw-r--r--src/gui/text/qzip.cpp9
-rw-r--r--src/gui/text/qzipreader_p.h2
-rw-r--r--src/gui/text/qzipwriter_p.h2
-rw-r--r--src/gui/util/qsystemtrayicon_p.h2
-rw-r--r--src/gui/util/qsystemtrayicon_x11.cpp2
-rw-r--r--src/gui/widgets/qabstractscrollarea.cpp11
-rw-r--r--src/gui/widgets/qabstractslider.cpp73
-rw-r--r--src/gui/widgets/qabstractslider_p.h1
-rw-r--r--src/gui/widgets/qabstractspinbox.h2
-rw-r--r--src/gui/widgets/qcombobox.h2
-rw-r--r--src/gui/widgets/qdialogbuttonbox.cpp2
-rw-r--r--src/gui/widgets/qlinecontrol.cpp2
-rw-r--r--src/gui/widgets/qmainwindow.cpp2
-rw-r--r--src/gui/widgets/qmainwindowlayout.cpp14
-rw-r--r--src/gui/widgets/qmenu.h2
-rw-r--r--src/gui/widgets/qmenu_p.h7
-rw-r--r--src/gui/widgets/qmenu_symbian.cpp34
-rw-r--r--src/gui/widgets/qmenubar.cpp2
-rw-r--r--src/gui/widgets/qprintpreviewwidget.cpp6
-rw-r--r--src/gui/widgets/qscrollbar.cpp18
-rw-r--r--src/gui/widgets/qtoolbar.cpp3
92 files changed, 1509 insertions, 608 deletions
diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp
index 21650bb..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.
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/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index ed36f87..39c41c4 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -1392,7 +1392,8 @@ QGraphicsItem::~QGraphicsItem()
}
delete d_ptr->transformData;
- qt_dataStore()->data.remove(this);
+ if (QGraphicsItemCustomDataStore *dataStore = qt_dataStore())
+ dataStore->data.remove(this);
}
/*!
@@ -2569,6 +2570,7 @@ void QGraphicsItem::setOpacity(qreal opacity)
if (newOpacity == d_ptr->opacity)
return;
+ bool wasFullyTransparent = d_ptr->isOpacityNull();
d_ptr->opacity = newOpacity;
// Notify change.
@@ -2584,7 +2586,9 @@ void QGraphicsItem::setOpacity(qreal opacity)
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)
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 5ad6cd5..b3ca3b5 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -358,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 {
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 54d47fa..66707fc 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -251,6 +251,7 @@
#endif
#include <private/qgraphicseffect_p.h>
#include <private/qgesturemanager_p.h>
+#include <private/qpathclipper_p.h>
// #define GESTURE_DEBUG
#ifndef GESTURE_DEBUG
@@ -372,7 +373,10 @@ void QGraphicsScenePrivate::_q_emitUpdated()
}
}
} else {
- updateAll = false;
+ if (views.isEmpty()) {
+ updateAll = false;
+ return;
+ }
for (int i = 0; i < views.size(); ++i)
views.at(i)->d_func()->processPendingUpdates();
// It's important that we update all views before we dispatch, hence two for-loops.
@@ -4603,6 +4607,7 @@ void QGraphicsScenePrivate::drawItems(QPainter *painter, const QTransform *const
if (!unpolishedItems.isEmpty())
_q_polishItems();
+ updateAll = false;
QRectF exposedSceneRect;
if (exposedRegion && indexMethod != QGraphicsScene::NoIndex) {
exposedSceneRect = exposedRegion->boundingRect().adjusted(-1, -1, 1, 1);
@@ -4630,7 +4635,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;
@@ -4750,7 +4755,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();
@@ -4765,7 +4770,12 @@ void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const Q
painter->setWorldTransform(*transformPtr * *effectTransform);
else
painter->setWorldTransform(*transformPtr);
- painter->setClipPath(item->shape(), Qt::IntersectClip);
+ QRectF clipRect;
+ const QPainterPath clipPath(item->shape());
+ if (QPathClipper::pathToRect(clipPath, &clipRect))
+ painter->setClipRect(clipRect, Qt::IntersectClip);
+ else
+ painter->setClipPath(clipPath, Qt::IntersectClip);
}
// Draw children behind
@@ -4801,8 +4811,14 @@ void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const Q
painter->setWorldTransform(*transformPtr);
}
- if (itemClipsToShape)
- painter->setClipPath(item->shape(), Qt::IntersectClip);
+ if (itemClipsToShape) {
+ QRectF clipRect;
+ const QPainterPath clipPath(item->shape());
+ if (QPathClipper::pathToRect(clipPath, &clipRect))
+ painter->setClipRect(clipRect, Qt::IntersectClip);
+ else
+ painter->setClipPath(clipPath, Qt::IntersectClip);
+ }
painter->setOpacity(opacity);
if (!item->d_ptr->cacheMode && !item->d_ptr->isWidget)
@@ -4980,7 +4996,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;
@@ -5153,6 +5170,7 @@ void QGraphicsScene::drawItems(QPainter *painter,
if (!d->unpolishedItems.isEmpty())
d->_q_polishItems();
+ d->updateAll = false;
QTransform viewTransform = painter->worldTransform();
Q_UNUSED(options);
diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp
index 043c4eb..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.
*/
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index 451f183..96b9373 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -2748,7 +2748,6 @@ bool QGraphicsView::viewportEvent(QEvent *event)
}
}
}
- d->scene->d_func()->updateAll = false;
}
break;
case QEvent::TouchBegin:
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index 4215f97..8ad3bac 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -54,4 +54,5 @@ DEFINES += Q_INTERNAL_QAPP_SRC
symbian:TARGET.UID3=0x2001B2DD
# ro-section in gui can exceed default allocated space, so more rw-section little further
-symbian-sbsv2: QMAKE_LFLAGS.ARMCC += --rw-base 0x800000"
+symbian-sbsv2: QMAKE_LFLAGS.ARMCC += --rw-base 0x800000
+symbian: QMAKE_LFLAGS.GCCE += -Tdata 0xC00000
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index ac1d303..bf6eb8d 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -104,6 +104,15 @@ QT_BEGIN_NAMESPACE
static QBasicAtomicInt serialNumCounter = Q_BASIC_ATOMIC_INITIALIZER(1);
+static void qt_cleanup_icon_cache();
+typedef QCache<QString, QIcon> IconCache;
+Q_GLOBAL_STATIC_WITH_INITIALIZER(IconCache, qtIconCache, qAddPostRoutine(qt_cleanup_icon_cache))
+
+static void qt_cleanup_icon_cache()
+{
+ qtIconCache()->clear();
+}
+
QIconPrivate::QIconPrivate()
: engine(0), ref(1),
serialNum(serialNumCounter.fetchAndAddRelaxed(1)),
@@ -963,15 +972,13 @@ QString QIcon::themeName()
*/
QIcon QIcon::fromTheme(const QString &name, const QIcon &fallback)
{
- static QCache <QString, QIcon> iconCache;
-
QIcon icon;
- if (iconCache.contains(name)) {
- icon = *iconCache.object(name);
+ if (qtIconCache()->contains(name)) {
+ icon = *qtIconCache()->object(name);
} else {
QIcon *cachedIcon = new QIcon(new QIconLoaderEngine(name));
- iconCache.insert(name, cachedIcon);
+ qtIconCache()->insert(name, cachedIcon);
icon = *cachedIcon;
}
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/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index c9e015c..9320cfc 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -263,25 +263,37 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
device->seek(pos);
}
- if (!handler && !testFormat.isEmpty() && autoDetectImageFormat && !ignoresFormatAndExtension) {
+ if (!handler && !testFormat.isEmpty() && !ignoresFormatAndExtension) {
// check if any plugin supports the format (they are not allowed to
// read from the device yet).
const qint64 pos = device ? device->pos() : 0;
- for (int i = 0; i < keys.size(); ++i) {
- if (i != suffixPluginIndex) {
- QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(keys.at(i)));
- if (plugin && plugin->capabilities(device, testFormat) & QImageIOPlugin::CanRead) {
+
+ if (autoDetectImageFormat) {
+ for (int i = 0; i < keys.size(); ++i) {
+ if (i != suffixPluginIndex) {
+ QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(keys.at(i)));
+ if (plugin && plugin->capabilities(device, testFormat) & QImageIOPlugin::CanRead) {
#ifdef QIMAGEREADER_DEBUG
- qDebug() << "QImageReader::createReadHandler: the" << keys.at(i) << "plugin can read this format";
+ qDebug() << "QImageReader::createReadHandler: the" << keys.at(i) << "plugin can read this format";
#endif
- handler = plugin->create(device, testFormat);
- break;
+ handler = plugin->create(device, testFormat);
+ break;
+ }
}
}
+ } else {
+ QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(QLatin1String(testFormat)));
+ if (plugin && plugin->capabilities(device, testFormat) & QImageIOPlugin::CanRead) {
+#ifdef QIMAGEREADER_DEBUG
+ qDebug() << "QImageReader::createReadHandler: the" << testFormat << "plugin can read this format";
+#endif
+ handler = plugin->create(device, testFormat);
+ }
}
if (device && !device->isSequential())
device->seek(pos);
}
+
#endif // QT_NO_LIBRARY
// if we don't have a handler yet, check if we have built-in support for
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index f823fdc..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);
}
/*!
@@ -1025,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)
@@ -1943,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/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp
index 37a6a18..2792e45 100644
--- a/src/gui/image/qpixmapfilter.cpp
+++ b/src/gui/image/qpixmapfilter.cpp
@@ -422,6 +422,9 @@ void QPixmapConvolutionFilter::draw(QPainter *painter, const QPointF &p, const Q
if(d->kernelWidth<=0 || d->kernelHeight <= 0)
return;
+ if (src.isNull())
+ return;
+
QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ?
static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0;
QPixmapConvolutionFilter *convolutionFilter = static_cast<QPixmapConvolutionFilter*>(filter);
@@ -710,7 +713,8 @@ void expblur(QImage &img, qreal radius, bool improvedQuality = false, int transp
radius *= qreal(0.5);
Q_ASSERT(img.format() == QImage::Format_ARGB32_Premultiplied
- || img.format() == QImage::Format_RGB32);
+ || img.format() == QImage::Format_RGB32
+ || img.format() == QImage::Format_Indexed8);
// choose the alpha such that pixels at radius distance from a fully
// saturated pixel will have an alpha component of no greater than
@@ -902,6 +906,9 @@ void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap
if (!painter->isActive())
return;
+ if (src.isNull())
+ return;
+
QRectF srcRect = rect;
if (srcRect.isNull())
srcRect = src.rect();
@@ -1082,6 +1089,10 @@ void QPixmapColorizeFilter::setStrength(qreal strength)
void QPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
{
Q_D(const QPixmapColorizeFilter);
+
+ if (src.isNull())
+ return;
+
QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ?
static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0;
QPixmapColorizeFilter *colorizeFilter = static_cast<QPixmapColorizeFilter*>(filter);
@@ -1312,6 +1323,10 @@ void QPixmapDropShadowFilter::draw(QPainter *p,
const QRectF &src) const
{
Q_D(const QPixmapDropShadowFilter);
+
+ if (px.isNull())
+ return;
+
QPixmapFilter *filter = p->paintEngine() && p->paintEngine()->isExtended() ?
static_cast<QPaintEngineEx *>(p->paintEngine())->pixmapFilter(type(), this) : 0;
QPixmapDropShadowFilter *dropShadowFilter = static_cast<QPixmapDropShadowFilter*>(filter);
diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h
index f5034fc..d5243c3 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_p.h
+++ b/src/gui/inputmethod/qcoefepinputcontext_p.h
@@ -96,7 +96,7 @@ protected:
void timerEvent(QTimerEvent *timerEvent);
private:
- void commitCurrentString(bool triggeredBySymbian);
+ void commitCurrentString(bool cancelFepTransaction);
void updateHints(bool mustUpdateInputCapabilities);
void applyHints(Qt::InputMethodHints hints);
void applyFormat(QList<QInputMethodEvent::Attribute> *attributes);
@@ -127,7 +127,7 @@ public:
private:
void DoCommitFepInlineEditL();
MCoeFepAwareTextEditor_Extension1* Extension1(TBool& aSetToTrue);
- void ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateEvent aEventType);
+ void ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateEvent aEventType);
// From MCoeFepAwareTextEditor_Extension1
public:
@@ -151,7 +151,6 @@ private:
int m_inlinePosition;
MFepInlineTextFormatRetriever *m_formatRetriever;
MFepPointerEventHandlerDuringInlineEdit *m_pointerHandler;
- int m_longPress;
int m_cursorPos;
QBasicTimer m_tempPreeditStringTimeout;
bool m_hasTempPreeditString;
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index 793bcde..2b91711 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -71,7 +71,6 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
m_inlinePosition(0),
m_formatRetriever(0),
m_pointerHandler(0),
- m_longPress(0),
m_cursorPos(0),
m_hasTempPreeditString(false)
{
@@ -101,11 +100,7 @@ QCoeFepInputContext::~QCoeFepInputContext()
void QCoeFepInputContext::reset()
{
- commitTemporaryPreeditString();
-
- CCoeFep* fep = CCoeEnv::Static()->Fep();
- if (fep)
- fep->CancelTransaction();
+ commitCurrentString(true);
}
void QCoeFepInputContext::ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateEvent aEventType)
@@ -130,7 +125,7 @@ void QCoeFepInputContext::update()
void QCoeFepInputContext::setFocusWidget(QWidget *w)
{
- commitCurrentString(false);
+ commitCurrentString(true);
QInputContext::setFocusWidget(w);
@@ -223,7 +218,7 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
break;
case Qt::Key_Select:
if (!m_preeditString.isEmpty()) {
- commitCurrentString(false);
+ commitCurrentString(true);
return true;
}
break;
@@ -235,10 +230,11 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
&& focusWidget()->inputMethodHints() & Qt::ImhHiddenText
&& !keyEvent->text().isEmpty()) {
// Send some temporary preedit text in order to make text visible for a moment.
+ m_cursorPos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt();
m_preeditString = keyEvent->text();
QList<QInputMethodEvent::Attribute> attributes;
QInputMethodEvent imEvent(m_preeditString, attributes);
- QApplication::sendEvent(focusWidget(), &imEvent);
+ sendEvent(imEvent);
m_tempPreeditStringTimeout.start(1000, this);
m_hasTempPreeditString = true;
update();
@@ -290,7 +286,6 @@ void QCoeFepInputContext::commitTemporaryPreeditString()
return;
commitCurrentString(false);
- m_hasTempPreeditString = false;
}
void QCoeFepInputContext::mouseHandler( int x, QMouseEvent *event)
@@ -298,7 +293,7 @@ void QCoeFepInputContext::mouseHandler( int x, QMouseEvent *event)
Q_ASSERT(focusWidget());
if (event->type() == QEvent::MouseButtonPress && event->button() == Qt::LeftButton) {
- commitCurrentString(false);
+ commitCurrentString(true);
int pos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt();
QList<QInputMethodEvent::Attribute> attributes;
@@ -744,30 +739,33 @@ void QCoeFepInputContext::GetScreenCoordinatesForFepL(TPoint& aLeftSideOfBaseLin
void QCoeFepInputContext::DoCommitFepInlineEditL()
{
- commitCurrentString(true);
+ commitCurrentString(false);
}
-void QCoeFepInputContext::commitCurrentString(bool triggeredBySymbian)
+void QCoeFepInputContext::commitCurrentString(bool cancelFepTransaction)
{
+ int longPress = 0;
+
if (m_preeditString.size() == 0) {
QWidget *w = focusWidget();
- if (triggeredBySymbian && w) {
+ if (!cancelFepTransaction && w) {
// We must replace the last character only if the input box has already accepted one
if (w->inputMethodQuery(Qt::ImCursorPosition).toInt() != m_cursorPos)
- m_longPress = 1;
+ longPress = 1;
}
return;
}
QList<QInputMethodEvent::Attribute> attributes;
QInputMethodEvent event(QLatin1String(""), attributes);
- event.setCommitString(m_preeditString, 0-m_longPress, m_longPress);
+ event.setCommitString(m_preeditString, 0-longPress, longPress);
m_preeditString.clear();
sendEvent(event);
- m_longPress = 0;
+ m_hasTempPreeditString = false;
+ longPress = 0;
- if (!triggeredBySymbian) {
+ if (cancelFepTransaction) {
CCoeFep* fep = CCoeEnv::Static()->Fep();
if (fep)
fep->CancelTransaction();
diff --git a/src/gui/itemviews/qfileiconprovider.cpp b/src/gui/itemviews/qfileiconprovider.cpp
index 360ed14..fcc61e5 100644
--- a/src/gui/itemviews/qfileiconprovider.cpp
+++ b/src/gui/itemviews/qfileiconprovider.cpp
@@ -65,6 +65,7 @@
#ifndef SHGFI_ADDOVERLAYS
# define SHGFI_ADDOVERLAYS 0x000000020
+# define SHGFI_OVERLAYINDEX 0x000000040
#endif
QT_BEGIN_NAMESPACE
@@ -248,7 +249,7 @@ QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const
//Get the small icon
#ifndef Q_OS_WINCE
val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
- sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_SMALLICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS);
+ sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_SMALLICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS|SHGFI_OVERLAYINDEX);
#else
val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_SYSICONINDEX);
@@ -287,7 +288,7 @@ QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const
//Get the big icon
#ifndef Q_OS_WINCE
val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
- sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_LARGEICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS);
+ sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_LARGEICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS|SHGFI_OVERLAYINDEX);
#else
val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
sizeof(SHFILEINFO), SHGFI_LARGEICON|SHGFI_SYSICONINDEX);
diff --git a/src/gui/itemviews/qitemdelegate.cpp b/src/gui/itemviews/qitemdelegate.cpp
index 6fd26a7..9069ce4 100644
--- a/src/gui/itemviews/qitemdelegate.cpp
+++ b/src/gui/itemviews/qitemdelegate.cpp
@@ -1033,7 +1033,7 @@ static QString qPixmapSerial(quint64 i, bool enabled)
i >>= 4;
}
- return QString::fromUtf16(ptr, int(&arr[sizeof(arr) / sizeof(ushort)] - ptr));
+ return QString((const QChar *)ptr, int(&arr[sizeof(arr) / sizeof(ushort)] - ptr));
}
/*!
diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp
index 19b1e8c..b2def39 100644
--- a/src/gui/itemviews/qlistview.cpp
+++ b/src/gui/itemviews/qlistview.cpp
@@ -2160,7 +2160,7 @@ void QListModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand)
} else {
if (flowPositions.isEmpty())
return;
- const int max = flowPositions.count() - 1;
+ const int max = scrollValueMap.count() - 1;
if (vertical && flow() == QListView::TopToBottom && dy != 0) {
int currentValue = qBound(0, verticalValue, max);
int previousValue = qBound(0, currentValue + dy, max);
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index f2bd288..0993b86 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -7,7 +7,7 @@ PRECOMPILED_HEADER = kernel/qt_gui_pch.h
KERNEL_P= kernel
HEADERS += \
kernel/qaction.h \
- kernel/qaction_p.h \
+ kernel/qaction_p.h \
kernel/qactiongroup.h \
kernel/qapplication.h \
kernel/qapplication_p.h \
@@ -37,8 +37,8 @@ HEADERS += \
kernel/qstackedlayout.h \
kernel/qtooltip.h \
kernel/qwhatsthis.h \
- kernel/qwidget.h \
- kernel/qwidget_p.h \
+ kernel/qwidget.h \
+ kernel/qwidget_p.h \
kernel/qwidgetaction.h \
kernel/qwidgetaction_p.h \
kernel/qwindowdefs.h \
@@ -49,6 +49,7 @@ HEADERS += \
kernel/qgesturerecognizer.h \
kernel/qgesturemanager_p.h \
kernel/qsoftkeymanager_p.h \
+ kernel/qsoftkeymanager_common_p.h \
kernel/qguiplatformplugin_p.h
SOURCES += \
@@ -84,14 +85,14 @@ SOURCES += \
kernel/qgesturerecognizer.cpp \
kernel/qgesturemanager.cpp \
kernel/qsoftkeymanager.cpp \
- kernel/qdesktopwidget.cpp \
+ kernel/qdesktopwidget.cpp \
kernel/qguiplatformplugin.cpp
win32 {
DEFINES += QT_NO_DIRECTDRAW
- HEADERS += \
- kernel/qwinnativepangesturerecognizer_win_p.h
+ HEADERS += \
+ kernel/qwinnativepangesturerecognizer_win_p.h
SOURCES += \
kernel/qapplication_win.cpp \
@@ -103,30 +104,34 @@ win32 {
kernel/qsound_win.cpp \
kernel/qwidget_win.cpp \
kernel/qole_win.cpp \
- kernel/qkeymapper_win.cpp \
- kernel/qwinnativepangesturerecognizer_win.cpp
+ kernel/qkeymapper_win.cpp \
+ kernel/qwinnativepangesturerecognizer_win.cpp
- !contains(DEFINES, QT_NO_DIRECTDRAW):LIBS += ddraw.lib
+ !contains(DEFINES, QT_NO_DIRECTDRAW):LIBS += ddraw.lib
}
symbian {
- SOURCES += \
- kernel/qapplication_s60.cpp \
- kernel/qeventdispatcher_s60.cpp \
- kernel/qwidget_s60.cpp \
- kernel/qcursor_s60.cpp \
- kernel/qdesktopwidget_s60.cpp \
- kernel/qkeymapper_s60.cpp\
- kernel/qclipboard_s60.cpp\
- kernel/qdnd_s60.cpp \
- kernel/qsound_s60.cpp
+ SOURCES += \
+ kernel/qapplication_s60.cpp \
+ kernel/qeventdispatcher_s60.cpp \
+ kernel/qwidget_s60.cpp \
+ kernel/qcursor_s60.cpp \
+ kernel/qdesktopwidget_s60.cpp \
+ kernel/qkeymapper_s60.cpp\
+ kernel/qclipboard_s60.cpp\
+ kernel/qdnd_s60.cpp \
+ kernel/qsound_s60.cpp \
+ kernel/qsoftkeymanager_s60.cpp
- HEADERS += \
- kernel/qt_s60_p.h \
- kernel/qeventdispatcher_s60_p.h
- LIBS += -lbafl -lestor
+ HEADERS += \
+ kernel/qt_s60_p.h \
+ kernel/qeventdispatcher_s60_p.h \
+ kernel/qsoftkeymanager_s60_p.h
+
+ LIBS += -lbafl -lestor
- INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE
+ INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE
+ INCLUDEPATH += ../3rdparty/s60
}
diff --git a/src/gui/kernel/qaction.cpp b/src/gui/kernel/qaction.cpp
index 4b7d949..8ddd051 100644
--- a/src/gui/kernel/qaction.cpp
+++ b/src/gui/kernel/qaction.cpp
@@ -715,6 +715,10 @@ QActionGroup *QAction::actionGroup() const
it is displayed to the left of the menu text. There is no default
icon.
+ On Symbian the icons which are passed to softkeys, i.e. to actions with
+ softkey role, need to have pixmap alpha channel correctly set otherwise
+ drawing artifacts will appear when softkey is pressed down.
+
If a null icon (QIcon::isNull() is passed into this function,
the icon of the action is cleared.
*/
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
index e8b821af..54a4901 100644
--- a/src/gui/kernel/qapplication_mac.mm
+++ b/src/gui/kernel/qapplication_mac.mm
@@ -2143,6 +2143,7 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event
}
if (wheel_deltaX || wheel_deltaY) {
+#ifndef QT_NO_WHEELEVENT
if (wheel_deltaX) {
QWheelEvent qwe(plocal, p, wheel_deltaX, buttons, modifiers, Qt::Horizontal);
QApplication::sendSpontaneousEvent(widget, &qwe);
@@ -2165,6 +2166,7 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event
handled_event = false;
}
}
+#endif // QT_NO_WHEELEVENT
} else {
#ifdef QMAC_SPEAK_TO_ME
const int speak_keys = Qt::AltModifier | Qt::ShiftModifier;
@@ -2717,6 +2719,7 @@ int QApplication::keyboardInputInterval()
return QApplicationPrivate::keyboard_input_time;
}
+#ifndef QT_NO_WHEELEVENT
void QApplication::setWheelScrollLines(int n)
{
QApplicationPrivate::wheel_scroll_lines = n;
@@ -2726,6 +2729,7 @@ int QApplication::wheelScrollLines()
{
return QApplicationPrivate::wheel_scroll_lines;
}
+#endif
void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
{
@@ -2888,9 +2892,11 @@ bool QApplicationPrivate::qt_mac_apply_settings()
QApplication::cursorFlashTime()).toInt();
QApplication::setCursorFlashTime(num);
+#ifndef QT_NO_WHEELEVENT
num = settings.value(QLatin1String("wheelScrollLines"),
QApplication::wheelScrollLines()).toInt();
QApplication::setWheelScrollLines(num);
+#endif
QString colorspec = settings.value(QLatin1String("colorSpec"),
QVariant(QLatin1String("default"))).toString();
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h
index 9c001ab..b3ec732 100644
--- a/src/gui/kernel/qapplication_p.h
+++ b/src/gui/kernel/qapplication_p.h
@@ -427,7 +427,9 @@ public:
static int cursor_flash_time;
static int mouse_double_click_time;
static int keyboard_input_time;
+#ifndef QT_NO_WHEELEVENT
static int wheel_scroll_lines;
+#endif
static bool animate_ui;
static bool animate_menu;
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 6caac9f..bf3ad71 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -809,12 +809,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;
+ QWidget *window = qwidget->window();
+ Q_ASSERT(window);
+ QTLWExtra *topExtra = window->d_func()->maybeTopData();
+ Q_ASSERT(topExtra);
+ if (!topExtra->inExpose) {
+ topExtra->inExpose = true;
QRect exposeRect = qt_TRect2QRect(controlRect);
qwidget->d_func()->syncBackingStore(exposeRect);
- extra->inExpose = false;
+ topExtra->inExpose = false;
}
QWindowSurface *surface = qwidget->windowSurface();
@@ -924,8 +927,8 @@ void QSymbianControl::PositionChanged()
cr.moveTopLeft(newPos);
qwidget->data->crect = cr;
QTLWExtra *top = qwidget->d_func()->maybeTopData();
- if (top)
- top->normalGeometry = cr;
+ if (top && (qwidget->windowState() & (~Qt::WindowActive)) == Qt::WindowNoState)
+ top->normalGeometry.moveTopLeft(newPos);
if (qwidget->isVisible()) {
QMoveEvent e(newPos, oldPos);
qt_sendSpontaneousEvent(qwidget, &e);
@@ -960,15 +963,14 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
qwidget->d_func()->setWindowIcon_sys(true);
qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle());
#ifdef Q_WS_S60
- // If widget is fullscreen, hide status pane and button container
- // otherwise show them.
+ // If widget is fullscreen/minimized, hide status pane and button container otherwise show them.
CEikStatusPane* statusPane = S60->statusPane();
CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer();
- bool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
- if (statusPane && (bool)statusPane->IsVisible() == isFullscreen)
- statusPane->MakeVisible(!isFullscreen);
- if (buttonGroup && (bool)buttonGroup->IsVisible() == isFullscreen)
- buttonGroup->MakeVisible(!isFullscreen);
+ TBool visible = !(qwidget->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized));
+ if (statusPane)
+ statusPane->MakeVisible(visible);
+ if (buttonGroup)
+ buttonGroup->MakeVisible(visible);
#endif
} else if (QApplication::activeWindow() == qwidget->window()) {
if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog()) {
@@ -1647,6 +1649,9 @@ int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent
if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible) {
delete w->d_func()->topData()->backingStore;
w->d_func()->topData()->backingStore = 0;
+ // In order to ensure that any resources used by the window surface
+ // are immediately freed, we flush the WSERV command buffer.
+ S60->wsSession().Flush();
} else if ((visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible)
&& !w->d_func()->maybeBackingStore()) {
w->d_func()->topData()->backingStore = new QWidgetBackingStore(w);
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
index 3355272..0a4869b 100644
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
@@ -928,7 +928,11 @@ const QString qt_reg_winclass(QWidget *w) // register window class
uint style;
bool icon;
QString cname;
- if (flags & Qt::MSWindowsOwnDC) {
+ if (qt_widget_private(w)->isGLWidget) {
+ cname = QLatin1String("QGLWidget");
+ style = CS_DBLCLKS;
+ icon = true;
+ } else if (flags & Qt::MSWindowsOwnDC) {
cname = QLatin1String("QWidgetOwnDC");
style = CS_DBLCLKS;
#ifndef Q_WS_WINCE
@@ -1021,7 +1025,7 @@ const QString qt_reg_winclass(QWidget *w) // register window class
}
wc.hCursor = 0;
#ifndef Q_WS_WINCE
- wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_WINDOW);
+ wc.hbrBackground = qt_widget_private(w)->isGLWidget ? 0 : (HBRUSH)GetSysColorBrush(COLOR_WINDOW);
#else
wc.hbrBackground = 0;
#endif
@@ -3616,13 +3620,19 @@ bool QETWidget::translatePaintEvent(const MSG &msg)
return true;
setAttribute(Qt::WA_PendingUpdate, false);
- const QRegion dirtyInBackingStore(qt_dirtyRegion(this));
- // Make sure the invalidated region contains the region we're about to repaint.
- // BeginPaint will set the clip to the invalidated region and it is impossible
- // to enlarge it afterwards (only shrink it). Using GetDCEx is not suffient
- // as it may return an invalid context (especially on Windows Vista).
- if (!dirtyInBackingStore.isEmpty())
- InvalidateRgn(internalWinId(), dirtyInBackingStore.handle(), false);
+
+ if (d_func()->isGLWidget) {
+ if (d_func()->usesDoubleBufferedGLContext)
+ InvalidateRect(internalWinId(), 0, false);
+ } else {
+ const QRegion dirtyInBackingStore(qt_dirtyRegion(this));
+ // Make sure the invalidated region contains the region we're about to repaint.
+ // BeginPaint will set the clip to the invalidated region and it is impossible
+ // to enlarge it afterwards (only shrink it). Using GetDCEx is not suffient
+ // as it may return an invalid context (especially on Windows Vista).
+ if (!dirtyInBackingStore.isEmpty())
+ InvalidateRgn(internalWinId(), dirtyInBackingStore.handle(), false);
+ }
PAINTSTRUCT ps;
d_func()->hd = BeginPaint(internalWinId(), &ps);
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index 2a1f655..afd927b 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -944,10 +944,12 @@ bool QApplicationPrivate::x11_apply_settings()
QApplication::cursorFlashTime()).toInt();
QApplication::setCursorFlashTime(num);
+#ifndef QT_NO_WHEELEVENT
num =
settings.value(QLatin1String("wheelScrollLines"),
QApplication::wheelScrollLines()).toInt();
QApplication::setWheelScrollLines(num);
+#endif
QString colorspec = settings.value(QLatin1String("colorSpec"),
QVariant(QLatin1String("default"))).toString();
@@ -4401,8 +4403,10 @@ bool QETWidget::translateWheelEvent(int global_x, int global_y, int delta,
QWidget* popup = qApp->activePopupWidget();
if (popup && window() != popup)
popup->close();
+#ifndef QT_NO_WHEELEVENT
QWheelEvent e(pos, globalPos, delta, buttons, modifiers, orient);
if (QApplication::sendSpontaneousEvent(widget, &e))
+#endif
return true;
}
@@ -4413,8 +4417,10 @@ bool QETWidget::translateWheelEvent(int global_x, int global_y, int delta,
QWidget* popup = qApp->activePopupWidget();
if (popup && widget != popup)
popup->hide();
+#ifndef QT_NO_WHEELEVENT
QWheelEvent e(pos, globalPos, delta, buttons, modifiers, orient);
if (QApplication::sendSpontaneousEvent(widget, &e))
+#endif
return true;
}
return false;
@@ -5313,6 +5319,7 @@ int QApplication::keyboardInputInterval()
return QApplicationPrivate::keyboard_input_time;
}
+#ifndef QT_NO_WHEELEVENT
void QApplication::setWheelScrollLines(int n)
{
QApplicationPrivate::wheel_scroll_lines = n;
@@ -5322,6 +5329,7 @@ int QApplication::wheelScrollLines()
{
return QApplicationPrivate::wheel_scroll_lines;
}
+#endif
void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
{
diff --git a/src/gui/kernel/qclipboard_mac.cpp b/src/gui/kernel/qclipboard_mac.cpp
index f3a971d..49a6cc8 100644
--- a/src/gui/kernel/qclipboard_mac.cpp
+++ b/src/gui/kernel/qclipboard_mac.cpp
@@ -388,6 +388,18 @@ QMacPasteboard::setMimeData(QMimeData *mime_src)
clear_helper();
QStringList formats = mime_src->formats();
+#ifdef QT_MAC_USE_COCOA
+ // QMimeData sub classes reimplementing the formats() might not expose the
+ // temporary "application/x-qt-mime-type-name" mimetype. So check the existence
+ // of this mime type while doing drag and drop.
+ QString dummyMimeType(QLatin1String("application/x-qt-mime-type-name"));
+ if (!formats.contains(dummyMimeType)) {
+ QByteArray dummyType = mime_src->data(dummyMimeType);
+ if (!dummyType.isEmpty()) {
+ formats.append(dummyMimeType);
+ }
+ }
+#endif
for(int f = 0; f < formats.size(); ++f) {
QString mimeType = formats.at(f);
for (QList<QMacPasteboardMime *>::Iterator it = availableConverters.begin(); it != availableConverters.end(); ++it) {
diff --git a/src/gui/kernel/qclipboard_s60.cpp b/src/gui/kernel/qclipboard_s60.cpp
index 71c355b..f07e066 100644
--- a/src/gui/kernel/qclipboard_s60.cpp
+++ b/src/gui/kernel/qclipboard_s60.cpp
@@ -164,7 +164,8 @@ void readFromStreamLX(QMimeData* aData,RReadStream& aStream)
TCardinality mimeTypeSize;
aStream >> mimeTypeSize;
HBufC* mimeTypeBuf = HBufC::NewLC(aStream,mimeTypeSize);
- QString mimeType = QString::fromUtf16(mimeTypeBuf->Des().Ptr(),mimeTypeBuf->Length());
+ QString mimeType = QString(reinterpret_cast<const QChar *>(mimeTypeBuf->Des().Ptr()),
+ mimeTypeBuf->Length());
CleanupStack::PopAndDestroy(mimeTypeBuf);
// mime data
TCardinality dataSize;
diff --git a/src/gui/kernel/qcocoapanel_mac.mm b/src/gui/kernel/qcocoapanel_mac.mm
index e535aac..5e24c84 100644
--- a/src/gui/kernel/qcocoapanel_mac.mm
+++ b/src/gui/kernel/qcocoapanel_mac.mm
@@ -46,6 +46,9 @@
#import <private/qcocoawindowdelegate_mac_p.h>
#import <private/qcocoaview_mac_p.h>
#import <private/qcocoawindowcustomthemeframe_mac_p.h>
+#include <private/qapplication_p.h>
+#include <private/qbackingstore_p.h>
+
#include <QtGui/QWidget>
diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
index 1a265d0..d2b74d7 100644
--- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
+++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
@@ -51,6 +51,9 @@
NSPanel, while QCocoaWindow needs to inherit NSWindow rather than NSPanel).
****************************************************************************/
+// WARNING: Don't include any header files from within this file. Put them
+// directly into qcocoawindow_mac_p.h and qcocoapanel_mac_p.h
+
QT_BEGIN_NAMESPACE
extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm
extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
@@ -185,3 +188,20 @@ QT_END_NAMESPACE
return [super frameViewClassForStyleMask:styleMask];
}
+- (void)displayIfNeeded
+{
+
+ QWidget *qwidget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self];
+ if (qwidget == 0) {
+ [super displayIfNeeded];
+ return;
+ }
+
+ if (QApplicationPrivate::graphicsSystem() != 0) {
+ if (QWidgetBackingStore *bs = qt_widget_private(qwidget)->maybeBackingStore())
+ bs->sync(qwidget, qwidget->rect());
+ }
+ [super displayIfNeeded];
+}
+
+
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index f61d2fe..ad64a91 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -520,10 +520,11 @@ extern "C" {
- (void)drawRect:(NSRect)aRect
{
if (QApplicationPrivate::graphicsSystem() != 0) {
- if (QWidgetBackingStore *bs = qwidgetprivate->maybeBackingStore())
- bs->markDirty(qwidget->rect(), qwidget);
- qwidgetprivate->syncBackingStore(qwidget->rect());
- return;
+ if (QWidgetBackingStore *bs = qwidgetprivate->maybeBackingStore()) {
+ // Drawing is handled on the window level
+ // See qcocoasharedwindowmethods_mac_p.
+ return;
+ }
}
CGContextRef cg = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
qwidgetprivate->hd = cg;
@@ -644,6 +645,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];
@@ -825,6 +828,7 @@ extern "C" {
deltaZ = qBound(-120, int([theEvent deltaZ] * 10000), 120);
}
+#ifndef QT_NO_WHEELEVENT
if (deltaX != 0) {
QWheelEvent qwe(qlocal, qglobal, deltaX, buttons, keyMods, Qt::Horizontal);
qt_sendSpontaneousEvent(widgetToGetMouse, &qwe);
@@ -865,6 +869,8 @@ extern "C" {
wheelOK = qwe2.isAccepted();
}
}
+#endif //QT_NO_WHEELEVENT
+
if (!wheelOK) {
return [super scrollWheel:theEvent];
}
@@ -1401,7 +1407,7 @@ Qt::DropAction QDragManager::drag(QDrag *o)
// setup the data
QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacPasteboardMime::MIME_DND);
- dragPrivate()->data->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray());
+ dragPrivate()->data->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray("dummy"));
dragBoard.setMimeData(dragPrivate()->data);
// create the image
diff --git a/src/gui/kernel/qcocoawindow_mac_p.h b/src/gui/kernel/qcocoawindow_mac_p.h
index c0d8252..0474882 100644
--- a/src/gui/kernel/qcocoawindow_mac_p.h
+++ b/src/gui/kernel/qcocoawindow_mac_p.h
@@ -53,6 +53,9 @@
#ifdef QT_MAC_USE_COCOA
#include "qmacdefines_mac.h"
#import <Cocoa/Cocoa.h>
+#include <private/qapplication_p.h>
+#include <private/qbackingstore_p.h>
+
enum { QtMacCustomizeWindow = 1 << 21 }; // This will one day be run over by
diff --git a/src/gui/kernel/qdesktopwidget_s60.cpp b/src/gui/kernel/qdesktopwidget_s60.cpp
index 77745ea..84e3c5d 100644
--- a/src/gui/kernel/qdesktopwidget_s60.cpp
+++ b/src/gui/kernel/qdesktopwidget_s60.cpp
@@ -88,24 +88,20 @@ QDesktopWidgetPrivate::~QDesktopWidgetPrivate()
void QDesktopWidgetPrivate::init(QDesktopWidget *that)
{
- int screenCount=0;
+// int screenCount=0;
- if (HAL::Get(0, HALData::EDisplayNumberOfScreens, screenCount) == KErrNone)
- QDesktopWidgetPrivate::screenCount = screenCount;
- else
- QDesktopWidgetPrivate::screenCount = 0;
+ // ### TODO: Implement proper multi-display support
+ QDesktopWidgetPrivate::screenCount = 1;
+// if (HAL::Get(0, HALData::EDisplayNumberOfScreens, screenCount) == KErrNone)
+// QDesktopWidgetPrivate::screenCount = screenCount;
+// else
+// QDesktopWidgetPrivate::screenCount = 0;
rects = new QVector<QRect>();
workrects = new QVector<QRect>();
rects->resize(QDesktopWidgetPrivate::screenCount);
workrects->resize(QDesktopWidgetPrivate::screenCount);
-
- // ### TODO: Implement proper multi-display support
- rects->resize(1);
- rects->replace(0, that->rect());
- workrects->resize(1);
- workrects->replace(0, that->rect());
}
void QDesktopWidgetPrivate::cleanup()
diff --git a/src/gui/kernel/qdnd_x11.cpp b/src/gui/kernel/qdnd_x11.cpp
index edab6a0..33968bd 100644
--- a/src/gui/kernel/qdnd_x11.cpp
+++ b/src/gui/kernel/qdnd_x11.cpp
@@ -617,7 +617,7 @@ QVariant QX11Data::xdndMimeConvertToFormat(Atom a, const QByteArray &data, const
// so it should be safe to check that the second char is 0
// to verify that it is utf16
if (data.size() > 1 && data.at(1) == 0)
- return QString::fromUtf16(reinterpret_cast<const ushort *>(data.constData()),
+ return QString::fromRawData((const QChar *)data.constData(),
data.size() / 2).split(QLatin1Char('\n')).first().toLatin1();
}
}
diff --git a/src/gui/kernel/qkeymapper_x11.cpp b/src/gui/kernel/qkeymapper_x11.cpp
index 70574e7..4e6c847 100644
--- a/src/gui/kernel/qkeymapper_x11.cpp
+++ b/src/gui/kernel/qkeymapper_x11.cpp
@@ -360,6 +360,13 @@ QList<int> QKeyMapperPrivate::possibleKeysXKB(QKeyEvent *event)
if (code && code < 0xfffe)
code = QChar(code).toUpper().unicode();
+
+ if (code == Qt::Key_Tab && (baseModifiers & Qt::ShiftModifier)) {
+ // map shift+tab to shift+backtab
+ code = Qt::Key_Backtab;
+ text = QString();
+ }
+
if (code == baseCode)
continue;
@@ -448,6 +455,13 @@ QList<int> QKeyMapperPrivate::possibleKeysCore(QKeyEvent *event)
if (code && code < 0xfffe)
code = QChar(code).toUpper().unicode();
+
+ if (code == Qt::Key_Tab && (baseModifiers & Qt::ShiftModifier)) {
+ // map shift+tab to shift+backtab
+ code = Qt::Key_Backtab;
+ text = QString();
+ }
+
if (code == baseCode)
continue;
diff --git a/src/gui/kernel/qmime_mac.cpp b/src/gui/kernel/qmime_mac.cpp
index 0431f2f..071f80d 100644
--- a/src/gui/kernel/qmime_mac.cpp
+++ b/src/gui/kernel/qmime_mac.cpp
@@ -431,8 +431,8 @@ QVariant QMacPasteboardMimeUnicodeText::convertToMime(const QString &mimetype, Q
firstData.size(), CFStringGetSystemEncoding(), false));
ret = QString(str);
} else if (flavor == QLatin1String("public.utf16-plain-text")) {
- ret = QString::fromUtf16(reinterpret_cast<const ushort *>(firstData.constData()),
- firstData.size() / sizeof(ushort));
+ ret = QString(reinterpret_cast<const QChar *>(firstData.constData()),
+ firstData.size() / sizeof(QChar));
} else {
qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype));
}
diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp
index 354f90b..6d108b0 100644
--- a/src/gui/kernel/qsoftkeymanager.cpp
+++ b/src/gui/kernel/qsoftkeymanager.cpp
@@ -41,34 +41,18 @@
#include "qapplication.h"
#include "qevent.h"
-#ifdef Q_WS_S60
-#include "qstyle.h"
-#include "private/qt_s60_p.h"
-#endif
+#include "qbitmap.h"
#include "private/qsoftkeymanager_p.h"
#include "private/qobject_p.h"
-
-#ifndef QT_NO_SOFTKEYMANAGER
-QT_BEGIN_NAMESPACE
+#include "private/qsoftkeymanager_common_p.h"
#ifdef Q_WS_S60
-static const int s60CommandStart = 6000;
+#include "private/qsoftkeymanager_s60_p.h"
#endif
-class QSoftKeyManagerPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QSoftKeyManager)
-
-public:
- static void updateSoftKeys_sys(const QList<QAction*> &softKeys);
-
-private:
- QHash<QAction*, Qt::Key> keyedActions;
- static QSoftKeyManager *self;
- static QWidget *softKeySource;
-};
+#ifndef QT_NO_SOFTKEYMANAGER
+QT_BEGIN_NAMESPACE
-QWidget *QSoftKeyManagerPrivate::softKeySource = 0;
QSoftKeyManager *QSoftKeyManagerPrivate::self = 0;
const char *QSoftKeyManager::standardSoftKeyText(StandardSoftKey standardKey)
@@ -105,7 +89,12 @@ QSoftKeyManager *QSoftKeyManager::instance()
return QSoftKeyManagerPrivate::self;
}
-QSoftKeyManager::QSoftKeyManager() : QObject(*(new QSoftKeyManagerPrivate), 0)
+QSoftKeyManager::QSoftKeyManager() :
+#ifdef Q_WS_S60
+ QObject(*(new QSoftKeyManagerPrivateS60), 0)
+#else
+ QObject(*(new QSoftKeyManagerPrivate), 0)
+#endif
{
}
@@ -115,10 +104,11 @@ QAction *QSoftKeyManager::createAction(StandardSoftKey standardKey, QWidget *act
QAction *action = new QAction(QSoftKeyManager::tr(text), actionWidget);
QAction::SoftKeyRole softKeyRole = QAction::NoSoftKey;
switch (standardKey) {
+ case MenuSoftKey: // FALL-THROUGH
+ action->setProperty(MENU_ACTION_PROPERTY, QVariant(true)); // TODO: can be refactored away to use _q_action_menubar
case OkSoftKey:
case SelectSoftKey:
case DoneSoftKey:
- case MenuSoftKey:
softKeyRole = QAction::PositiveSoftKey;
break;
case CancelSoftKey:
@@ -147,7 +137,7 @@ QAction *QSoftKeyManager::createKeyedAction(StandardSoftKey standardKey, Qt::Key
#endif //QT_NO_ACTION
}
-void QSoftKeyManager::cleanupHash(QObject* obj)
+void QSoftKeyManager::cleanupHash(QObject *obj)
{
Q_D(QSoftKeyManager);
QAction *action = qobject_cast<QAction*>(obj);
@@ -175,137 +165,78 @@ void QSoftKeyManager::updateSoftKeys()
QApplication::postEvent(QSoftKeyManager::instance(), event);
}
-bool QSoftKeyManager::event(QEvent *e)
+bool QSoftKeyManager::appendSoftkeys(const QWidget &source, int level)
{
-#ifndef QT_NO_ACTION
- if (e->type() == QEvent::UpdateSoftKeys) {
- QList<QAction*> softKeys;
- QWidget *source = QApplication::focusWidget();
- do {
- if (source) {
- QList<QAction*> actions = source->actions();
- for (int i = 0; i < actions.count(); ++i) {
- if (actions.at(i)->softKeyRole() != QAction::NoSoftKey)
- softKeys.append(actions.at(i));
- }
-
- QWidget *parent = source->parentWidget();
- if (parent && softKeys.isEmpty() && !source->isWindow())
- source = parent;
- else
- break;
- } else {
- source = QApplication::activeWindow();
- }
- } while (source);
-
- QSoftKeyManagerPrivate::softKeySource = source;
- QSoftKeyManagerPrivate::updateSoftKeys_sys(softKeys);
- return true;
+ Q_D(QSoftKeyManager);
+ bool ret = false;
+ QList<QAction*> actions = source.actions();
+ for (int i = 0; i < actions.count(); ++i) {
+ if (actions.at(i)->softKeyRole() != QAction::NoSoftKey) {
+ d->requestedSoftKeyActions.insert(level, actions.at(i));
+ ret = true;
+ }
}
-#endif //QT_NO_ACTION
- return false;
+ return ret;
}
-#ifdef Q_WS_S60
-void QSoftKeyManagerPrivate::updateSoftKeys_sys(const QList<QAction*> &softkeys)
+QWidget *QSoftKeyManager::softkeySource(QWidget *previousSource, bool& recursiveMerging)
{
- // lets not update softkeys if s60 native dialog or menu is shown
- if (QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes)
- || CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog())
- return;
-
- CEikButtonGroupContainer* nativeContainer = S60->buttonGroupContainer();
- nativeContainer->DrawableWindow()->SetOrdinalPosition(0);
- nativeContainer->DrawableWindow()->SetPointerCapturePriority(1); //keep softkeys available in modal dialog
- nativeContainer->DrawableWindow()->SetFaded(EFalse, RWindowTreeNode::EFadeIncludeChildren);
-
- int position = -1;
- bool needsExitButton = true;
- QT_TRAP_THROWING(
- //Using -1 instead of EAknSoftkeyEmpty to avoid flickering.
- nativeContainer->SetCommandL(0, -1, KNullDesC);
- nativeContainer->SetCommandL(2, -1, KNullDesC);
- );
-
- for (int index = 0; index < softkeys.count(); index++) {
- const QAction* softKeyAction = softkeys.at(index);
- switch (softKeyAction->softKeyRole()) {
- // Positive Actions on the LSK
- case QAction::PositiveSoftKey:
- position = 0;
- break;
- case QAction::SelectSoftKey:
- position = 0;
- break;
- // Negative Actions on the RSK
- case QAction::NegativeSoftKey:
- needsExitButton = false;
- position = 2;
- break;
- default:
- break;
- }
-
- int command = (softKeyAction->objectName().contains(QLatin1String("_q_menuSoftKeyAction")))
- ? EAknSoftkeyOptions
- : s60CommandStart + index;
-
- // _q_menuSoftKeyAction action is set to "invisible" and all invisible actions are by default
- // disabled. However we never want to dim options softkey, even it is set to "invisible"
- bool dimmed = (command == EAknSoftkeyOptions) ? false : !softKeyAction->isEnabled();
-
- if (position != -1) {
- const int underlineShortCut = QApplication::style()->styleHint(QStyle::SH_UnderlineShortcut);
- QString iconText = softKeyAction->iconText();
- TPtrC text = qt_QString2TPtrC( underlineShortCut ? softKeyAction->text() : iconText);
- QT_TRAP_THROWING(
- nativeContainer->SetCommandL(position, command, text);
- nativeContainer->DimCommand(command, dimmed);
- );
- }
+ Q_D(QSoftKeyManager);
+ QWidget *source = NULL;
+ if (!previousSource) {
+ // Initial source is primarily focuswidget and secondarily activeWindow
+ source = QApplication::focusWidget();
+ if (!source)
+ source = QApplication::activeWindow();
+ } else {
+ // Softkey merging is based on four criterias
+ // 1. Implicit merging is used whenever focus widget does not specify any softkeys
+ bool implicitMerging = d->requestedSoftKeyActions.isEmpty();
+ // 2. Explicit merging with parent is used whenever WA_MergeSoftkeys widget attribute is set
+ bool explicitMerging = previousSource->testAttribute(Qt::WA_MergeSoftkeys);
+ // 3. Explicit merging with all parents
+ recursiveMerging |= previousSource->testAttribute(Qt::WA_MergeSoftkeysRecursively);
+ // 4. Implicit and explicit merging always stops at window boundary
+ bool merging = (implicitMerging || explicitMerging || recursiveMerging) && !previousSource->isWindow();
+
+ source = merging ? previousSource->parentWidget() : NULL;
}
-
- const Qt::WindowType sourceWindowType = QSoftKeyManagerPrivate::softKeySource
- ? QSoftKeyManagerPrivate::softKeySource->window()->windowType()
- : Qt::Widget;
-
- if (needsExitButton && sourceWindowType != Qt::Dialog && sourceWindowType != Qt::Popup)
- QT_TRAP_THROWING(
- nativeContainer->SetCommandL(2, EAknSoftkeyExit, qt_QString2TPtrC(QSoftKeyManager::tr("Exit"))));
-
- nativeContainer->DrawDeferred(); // 3.1 needs an extra invitation
+ return source;
}
-bool QSoftKeyManager::handleCommand(int command)
+bool QSoftKeyManager::handleUpdateSoftKeys()
{
- if (command >= s60CommandStart && QSoftKeyManagerPrivate::softKeySource) {
- int index = command - s60CommandStart;
- const QList<QAction*>& softKeys = QSoftKeyManagerPrivate::softKeySource->actions();
- for (int i = 0, j = 0; i < softKeys.count(); ++i) {
- QAction *action = softKeys.at(i);
- if (action->softKeyRole() != QAction::NoSoftKey) {
- if (j == index) {
- QWidget *parent = action->parentWidget();
- if (parent && parent->isEnabled()) {
- action->activate(QAction::Trigger);
- return true;
- }
- }
- j++;
- }
+ Q_D(QSoftKeyManager);
+ int level = 0;
+ d->requestedSoftKeyActions.clear();
+ bool recursiveMerging = false;
+ QWidget *source = softkeySource(NULL, recursiveMerging);
+ do {
+ if (source) {
+ bool added = appendSoftkeys(*source, level);
+ source = softkeySource(source, recursiveMerging);
+ level = added ? ++level : level;
}
- }
+ } while (source);
- return false;
+ d->updateSoftKeys_sys();
+ return true;
}
-#else
-
-void QSoftKeyManagerPrivate::updateSoftKeys_sys(const QList<QAction*> &)
+bool QSoftKeyManager::event(QEvent *e)
{
+#ifndef QT_NO_ACTION
+ if (e->type() == QEvent::UpdateSoftKeys)
+ return handleUpdateSoftKeys();
+#endif //QT_NO_ACTION
+ return false;
}
+#ifdef Q_WS_S60
+bool QSoftKeyManager::handleCommand(int command)
+{
+ return static_cast<QSoftKeyManagerPrivateS60*>(QSoftKeyManager::instance()->d_func())->handleCommand(command);
+}
#endif
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qsoftkeymanager_common_p.h b/src/gui/kernel/qsoftkeymanager_common_p.h
new file mode 100644
index 0000000..460d0dc
--- /dev/null
+++ b/src/gui/kernel/qsoftkeymanager_common_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSOFTKEYMANAGER_COMMON_P_H
+#define QSOFTKEYMANAGER_COMMON_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_HEADER
+
+#ifndef QT_NO_SOFTKEYMANAGER
+
+QT_BEGIN_NAMESPACE
+
+class QSoftKeyManagerPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QSoftKeyManager)
+
+public:
+ virtual void updateSoftKeys_sys() {};
+
+protected:
+ static QSoftKeyManager *self;
+ QHash<QAction*, Qt::Key> keyedActions;
+ QMultiHash<int, QAction*> requestedSoftKeyActions;
+
+};
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_SOFTKEYMANAGER
+
+QT_END_HEADER
+
+#endif // QSOFTKEYMANAGER_COMMON_P_H \ No newline at end of file
diff --git a/src/gui/kernel/qsoftkeymanager_p.h b/src/gui/kernel/qsoftkeymanager_p.h
index c901a29..ce902fe 100644
--- a/src/gui/kernel/qsoftkeymanager_p.h
+++ b/src/gui/kernel/qsoftkeymanager_p.h
@@ -63,6 +63,8 @@ QT_BEGIN_NAMESPACE
class QSoftKeyManagerPrivate;
+const char MENU_ACTION_PROPERTY[] = "_q_menuaction";
+
class Q_AUTOTEST_EXPORT QSoftKeyManager : public QObject
{
Q_OBJECT
@@ -79,26 +81,30 @@ public:
};
static void updateSoftKeys();
- static QAction *createAction(StandardSoftKey standardKey, QWidget *actionWidget);
- static QAction *createKeyedAction(StandardSoftKey standardKey, Qt::Key key, QWidget *actionWidget);
-
#ifdef Q_WS_S60
static bool handleCommand(int);
#endif
-private:
- QSoftKeyManager();
- static QSoftKeyManager *instance();
- static const char *standardSoftKeyText(StandardSoftKey standardKey);
+ static QAction *createAction(StandardSoftKey standardKey, QWidget *actionWidget);
+ static QAction *createKeyedAction(StandardSoftKey standardKey, Qt::Key key, QWidget *actionWidget);
protected:
bool event(QEvent *e);
- Q_DISABLE_COPY(QSoftKeyManager)
+private:
+ QSoftKeyManager();
+ static QSoftKeyManager *instance();
+ static const char *standardSoftKeyText(StandardSoftKey standardKey);
+ bool appendSoftkeys(const QWidget &source, int level);
+ QWidget *softkeySource(QWidget *previousSource, bool& recursiveMerging);
+ bool handleUpdateSoftKeys();
private Q_SLOTS:
void cleanupHash(QObject* obj);
void sendKeyEvent();
+
+private:
+ Q_DISABLE_COPY(QSoftKeyManager)
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qsoftkeymanager_s60.cpp b/src/gui/kernel/qsoftkeymanager_s60.cpp
new file mode 100644
index 0000000..af84a8f
--- /dev/null
+++ b/src/gui/kernel/qsoftkeymanager_s60.cpp
@@ -0,0 +1,404 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qapplication.h"
+#include "qevent.h"
+#include "qbitmap.h"
+#include "qstyle.h"
+#include "qmenubar.h"
+#include "private/qt_s60_p.h"
+#include "private/qmenu_p.h"
+#include "private/qsoftkeymanager_p.h"
+#include "private/qsoftkeymanager_s60_p.h"
+#include "private/qobject_p.h"
+#include <eiksoftkeyimage.h>
+#include <eikcmbut.h>
+
+#ifndef QT_NO_SOFTKEYMANAGER
+QT_BEGIN_NAMESPACE
+
+const int S60_COMMAND_START = 6000;
+const int LSK_POSITION = 0;
+const int MSK_POSITION = 3;
+const int RSK_POSITION = 2;
+
+QSoftKeyManagerPrivateS60::QSoftKeyManagerPrivateS60()
+{
+ cachedCbaIconSize[0] = QSize(0,0);
+ cachedCbaIconSize[1] = QSize(0,0);
+ cachedCbaIconSize[2] = QSize(0,0);
+ cachedCbaIconSize[3] = QSize(0,0);
+ skipNextUpdate = false;
+}
+
+bool QSoftKeyManagerPrivateS60::skipCbaUpdate()
+{
+ // lets not update softkeys if
+ // 1. We don't have application panes, i.e. cba
+ // 2. S60 native dialog or menu is shown
+ if (QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes) ||
+ CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog() || skipNextUpdate) {
+ skipNextUpdate = false;
+ return true;
+ }
+ return false;
+}
+
+void QSoftKeyManagerPrivateS60::ensureCbaVisibilityAndResponsiviness(CEikButtonGroupContainer &cba)
+{
+ RDrawableWindow *cbaWindow = cba.DrawableWindow();
+ Q_ASSERT_X(cbaWindow, Q_FUNC_INFO, "Native CBA does not have window!");
+ // Make sure CBA is visible, i.e. CBA window is on top
+ cbaWindow->SetOrdinalPosition(0);
+ // Qt shares same CBA instance between top-level widgets,
+ // make sure we are not faded by underlying window.
+ cbaWindow->SetFaded(EFalse, RWindowTreeNode::EFadeIncludeChildren);
+ // Modal dialogs capture pointer events, but shared cba instance
+ // shall stay responsive. Raise pointer capture priority to keep
+ // softkeys responsive in modal dialogs
+ cbaWindow->SetPointerCapturePriority(1);
+}
+
+void QSoftKeyManagerPrivateS60::clearSoftkeys(CEikButtonGroupContainer &cba)
+{
+ QT_TRAP_THROWING(
+ //Using -1 instead of EAknSoftkeyEmpty to avoid flickering.
+ cba.SetCommandL(0, -1, KNullDesC);
+ // TODO: Should we clear also middle SK?
+ cba.SetCommandL(2, -1, KNullDesC);
+ );
+ realSoftKeyActions.clear();
+}
+
+QString QSoftKeyManagerPrivateS60::softkeyText(QAction &softkeyAction)
+{
+ // In S60 softkeys and menu items do not support key accelerators (i.e.
+ // CTRL+X). Therefore, removing the accelerator characters from both softkey
+ // and menu item texts.
+ const int underlineShortCut = QApplication::style()->styleHint(QStyle::SH_UnderlineShortcut);
+ QString iconText = softkeyAction.iconText();
+ return underlineShortCut ? softkeyAction.text() : iconText;
+}
+
+QAction *QSoftKeyManagerPrivateS60::highestPrioritySoftkey(QAction::SoftKeyRole role)
+{
+ QAction *ret = NULL;
+ // Priority look up is two level
+ // 1. First widget with softkeys always has highest priority
+ for (int level = 0; !ret; level++) {
+ // 2. Highest priority action within widget
+ QList<QAction*> actions = requestedSoftKeyActions.values(level);
+ if (actions.isEmpty())
+ break;
+ qSort(actions.begin(), actions.end(), QSoftKeyManagerPrivateS60::actionPriorityMoreThan);
+ foreach (QAction *action, actions) {
+ if (action->softKeyRole() == role) {
+ ret = action;
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
+bool QSoftKeyManagerPrivateS60::actionPriorityMoreThan(const QAction *firstItem, const QAction *secondItem)
+{
+ return firstItem->priority() > secondItem->priority();
+}
+
+void QSoftKeyManagerPrivateS60::setNativeSoftkey(CEikButtonGroupContainer &cba,
+ TInt position, TInt command, const TDesC &text)
+{
+ // Calling SetCommandL causes CBA redraw
+ QT_TRAP_THROWING(cba.SetCommandL(position, command, text));
+}
+
+QPoint QSoftKeyManagerPrivateS60::softkeyIconPosition(int position, QSize sourceSize, QSize targetSize)
+{
+ QPoint iconPosition(0,0);
+ switch( AknLayoutUtils::CbaLocation() )
+ {
+ case AknLayoutUtils::EAknCbaLocationBottom:
+ // RSK must be moved to right, LSK in on correct position by default
+ if (position == RSK_POSITION)
+ iconPosition.setX(targetSize.width() - sourceSize.width());
+ break;
+ case AknLayoutUtils::EAknCbaLocationRight:
+ case AknLayoutUtils::EAknCbaLocationLeft:
+ // Already in correct position
+ default:
+ break;
+ }
+
+ // Align horizontally to center
+ iconPosition.setY((targetSize.height() - sourceSize.height()) >> 1);
+ return iconPosition;
+}
+
+QPixmap QSoftKeyManagerPrivateS60::prepareSoftkeyPixmap(QPixmap src, int position, QSize targetSize)
+{
+ QPixmap target(targetSize);
+ target.fill(Qt::transparent);
+ QPainter p;
+ p.begin(&target);
+ p.drawPixmap(softkeyIconPosition(position, src.size(), targetSize), src);
+ p.end();
+ return target;
+}
+
+bool QSoftKeyManagerPrivateS60::isOrientationLandscape()
+{
+ // Hard to believe that there is no public API in S60 to
+ // get current orientation. This workaround works with currently supported resolutions
+ return S60->screenHeightInPixels < S60->screenWidthInPixels;
+}
+
+QSize QSoftKeyManagerPrivateS60::cbaIconSize(CEikButtonGroupContainer *cba, int position)
+{
+
+ int index = position;
+ index += isOrientationLandscape() ? 0 : 1;
+ if(cachedCbaIconSize[index].isNull()) {
+ // Only way I figured out to get CBA icon size without RnD SDK, was
+ // to set some dummy icon to CBA first and then ask CBA button CCoeControl::Size()
+ // The returned value is cached to avoid unnecessary icon setting every time.
+ const bool left = (position == LSK_POSITION);
+ if(position == LSK_POSITION || position == RSK_POSITION) {
+ CEikImage* tmpImage = NULL;
+ QT_TRAP_THROWING(tmpImage = new (ELeave) CEikImage);
+ EikSoftkeyImage::SetImage(cba, *tmpImage, left); // Takes myimage ownership
+ int command = S60_COMMAND_START + position;
+ setNativeSoftkey(*cba, position, command, KNullDesC());
+ cachedCbaIconSize[index] = qt_TSize2QSize(cba->ControlOrNull(command)->Size());
+ EikSoftkeyImage::SetLabel(cba, left);
+
+ if(cachedCbaIconSize[index] == QSize(138,72)) {
+ // Hack for S60 5.0 (5800) landscape orientation, which return wrong icon size
+ cachedCbaIconSize[index] = QSize(60,60);
+ }
+ }
+ }
+
+ return cachedCbaIconSize[index];
+}
+
+bool QSoftKeyManagerPrivateS60::setSoftkeyImage(CEikButtonGroupContainer *cba,
+ QAction &action, int position)
+{
+ bool ret = false;
+
+ const bool left = (position == LSK_POSITION);
+ if(position == LSK_POSITION || position == RSK_POSITION) {
+ QIcon icon = action.icon();
+ if (!icon.isNull()) {
+ // Get size of CBA icon area based on button position and orientation
+ QSize requiredIconSize = cbaIconSize(cba, position);
+ // Get pixmap out of icon based on preferred size, the aspect ratio is kept
+ QPixmap pmWihtAspectRatio = icon.pixmap(requiredIconSize);
+ // Native softkeys require that pixmap size is exactly the same as requiredIconSize
+ // prepareSoftkeyPixmap creates a new pixmap with requiredIconSize and blits the 'pmWihtAspectRatio'
+ // to correct location of it
+ QPixmap softkeyPixmap = prepareSoftkeyPixmap(pmWihtAspectRatio, position, requiredIconSize);
+
+ QPixmap softkeyAlpha = softkeyPixmap.alphaChannel();
+ // Alpha channel in 5.1 and older devices need to be inverted
+ // TODO: Switch to use toSymbianCFbsBitmap with invert when available
+ if(QSysInfo::s60Version() <= QSysInfo::SV_S60_5_1) {
+ QImage alphaImage = softkeyAlpha.toImage();
+ alphaImage.invertPixels();
+ softkeyAlpha = QPixmap::fromImage(alphaImage);
+ }
+
+ CFbsBitmap* nBitmap = softkeyPixmap.toSymbianCFbsBitmap();
+ CFbsBitmap* nMask = softkeyAlpha.toSymbianCFbsBitmap();
+
+ CEikImage* myimage = new (ELeave) CEikImage;
+ myimage->SetPicture( nBitmap, nMask ); // nBitmap and nMask ownership transfered
+
+ EikSoftkeyImage::SetImage(cba, *myimage, left); // Takes myimage ownership
+ ret = true;
+ } else {
+ // Restore softkey to text based
+ EikSoftkeyImage::SetLabel(cba, left);
+ }
+ }
+ return ret;
+}
+
+bool QSoftKeyManagerPrivateS60::setSoftkey(CEikButtonGroupContainer &cba,
+ QAction::SoftKeyRole role, int position)
+{
+ QAction *action = highestPrioritySoftkey(role);
+ if (action) {
+ setSoftkeyImage(&cba, *action, position);
+ QString text = softkeyText(*action);
+ TPtrC nativeText = qt_QString2TPtrC(text);
+ int command = S60_COMMAND_START + position;
+ setNativeSoftkey(cba, position, command, nativeText);
+ cba.DimCommand(command, !action->isEnabled());
+ realSoftKeyActions.insert(command, action);
+ return true;
+ }
+ return false;
+}
+
+bool QSoftKeyManagerPrivateS60::setLeftSoftkey(CEikButtonGroupContainer &cba)
+{
+ return setSoftkey(cba, QAction::PositiveSoftKey, LSK_POSITION);
+}
+
+bool QSoftKeyManagerPrivateS60::setMiddleSoftkey(CEikButtonGroupContainer &cba)
+{
+ // Note: In order to get MSK working, application has to have EAknEnableMSK flag set
+ // Currently it is not possible very easily)
+ // For more information see: http://wiki.forum.nokia.com/index.php/Middle_softkey_usage
+ return setSoftkey(cba, QAction::SelectSoftKey, MSK_POSITION);
+}
+
+bool QSoftKeyManagerPrivateS60::setRightSoftkey(CEikButtonGroupContainer &cba)
+{
+ if (!setSoftkey(cba, QAction::NegativeSoftKey, RSK_POSITION)) {
+ Qt::WindowType windowType = Qt::Window;
+ QAction *action = requestedSoftKeyActions.value(0);
+ if (action) {
+ QWidget *actionParent = action->parentWidget();
+ Q_ASSERT_X(actionParent, Q_FUNC_INFO, "No parent set for softkey action!");
+
+ QWidget *actionWindow = actionParent->window();
+ Q_ASSERT_X(actionWindow, Q_FUNC_INFO, "Softkey action does not have window!");
+ windowType = actionWindow->windowType();
+ }
+
+ if (windowType != Qt::Dialog && windowType != Qt::Popup) {
+ QString text(QSoftKeyManager::tr("Exit"));
+ TPtrC nativeText = qt_QString2TPtrC(text);
+ EikSoftkeyImage::SetLabel(&cba, false);
+ setNativeSoftkey(cba, RSK_POSITION, EAknSoftkeyExit, nativeText);
+ return true;
+ }
+ }
+ return false;
+}
+
+void QSoftKeyManagerPrivateS60::setSoftkeys(CEikButtonGroupContainer &cba)
+{
+ int requestedSoftkeyCount = requestedSoftKeyActions.count();
+ const int maxSoftkeyCount = 2; // TODO: differs based on orientation ans S60 versions (some have MSK)
+ if (requestedSoftkeyCount > maxSoftkeyCount) {
+ // We have more softkeys than available slots
+ // Put highest priority negative action to RSK and Options menu with rest of softkey actions to LSK
+ // TODO: Build menu
+ setLeftSoftkey(cba);
+ if(AknLayoutUtils::MSKEnabled())
+ setMiddleSoftkey(cba);
+ setRightSoftkey(cba);
+ } else {
+ // We have less softkeys than available slots
+ // Put softkeys to request slots based on role
+ setLeftSoftkey(cba);
+ if(AknLayoutUtils::MSKEnabled())
+ setMiddleSoftkey(cba);
+ setRightSoftkey(cba);
+ }
+}
+
+void QSoftKeyManagerPrivateS60::updateSoftKeys_sys()
+{
+ if (skipCbaUpdate())
+ return;
+
+ CEikButtonGroupContainer *nativeContainer = S60->buttonGroupContainer();
+ Q_ASSERT_X(nativeContainer, Q_FUNC_INFO, "Native CBA does not exist!");
+ ensureCbaVisibilityAndResponsiviness(*nativeContainer);
+ clearSoftkeys(*nativeContainer);
+ setSoftkeys(*nativeContainer);
+
+ nativeContainer->DrawDeferred(); // 3.1 needs an extra invitation
+}
+
+bool QSoftKeyManagerPrivateS60::handleCommand(int command)
+{
+ QAction *action = realSoftKeyActions.value(command);
+ if (action) {
+ QVariant property = action->property(MENU_ACTION_PROPERTY);
+ if (property.isValid() && property.toBool()) {
+ QT_TRAP_THROWING(S60->menuBar()->TryDisplayMenuBarL());
+ } else if (action->menu()) {
+ // TODO: This is hack, in order to use exising QMenuBar implementation for Symbian
+ // menubar needs to have widget to which it is associated. Since we want to associate
+ // menubar to action (which is inherited from QObejct), we create and associate QWidget
+ // to action and pass that for QMenuBar. This associates the menubar to action, and we
+ // can have own menubar for each action.
+ QWidget *actionContainer = action->property("_q_action_widget").value<QWidget*>();
+ if(!actionContainer) {
+ actionContainer = new QWidget(action->parentWidget());
+ QMenuBar *menuBar = new QMenuBar(actionContainer);
+ foreach(QAction *menuAction, action->menu()->actions()) {
+ QMenu *menu = menuAction->menu();
+ if(menu)
+ menuBar->addMenu(action->menu());
+ else
+ menuBar->addAction(menuAction);
+ }
+ QVariant v;
+ v.setValue(actionContainer);
+ action->setProperty("_q_action_widget", v);
+ }
+ qt_symbian_next_menu_from_action(actionContainer);
+ QT_TRAP_THROWING(S60->menuBar()->TryDisplayMenuBarL());
+ // TODO: hack remove, it can happen that IsDisplayingMenuOrDialog return false
+ // in updateSoftKeys_sys, and we will override menu CBA with our own
+ skipNextUpdate = true;
+ } else {
+ Q_ASSERT(action->softKeyRole() != QAction::NoSoftKey);
+ QWidget *actionParent = action->parentWidget();
+ Q_ASSERT_X(actionParent, Q_FUNC_INFO, "No parent set for softkey action!");
+ if (actionParent->isEnabled()) {
+ action->activate(QAction::Trigger);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+QT_END_NAMESPACE
+#endif //QT_NO_SOFTKEYMANAGER
diff --git a/src/gui/kernel/qsoftkeymanager_s60_p.h b/src/gui/kernel/qsoftkeymanager_s60_p.h
new file mode 100644
index 0000000..f8bd6d9
--- /dev/null
+++ b/src/gui/kernel/qsoftkeymanager_s60_p.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSOFTKEYMANAGER_S60_P_H
+#define QSOFTKEYMANAGER_S60_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qobject_p.h"
+#include "private/qsoftkeymanager_common_p.h"
+
+QT_BEGIN_HEADER
+
+#ifndef QT_NO_SOFTKEYMANAGER
+
+QT_BEGIN_NAMESPACE
+
+class CEikButtonGroupContainer;
+class QAction;
+
+class QSoftKeyManagerPrivateS60 : public QSoftKeyManagerPrivate
+{
+ Q_DECLARE_PUBLIC(QSoftKeyManager)
+
+public:
+ QSoftKeyManagerPrivateS60();
+
+public:
+ void updateSoftKeys_sys();
+ bool handleCommand(int command);
+
+private:
+ bool skipCbaUpdate();
+ void ensureCbaVisibilityAndResponsiviness(CEikButtonGroupContainer &cba);
+ void clearSoftkeys(CEikButtonGroupContainer &cba);
+ QString softkeyText(QAction &softkeyAction);
+ QAction *highestPrioritySoftkey(QAction::SoftKeyRole role);
+ static bool actionPriorityMoreThan(const QAction* item1, const QAction* item2);
+ void setNativeSoftkey(CEikButtonGroupContainer &cba, TInt position, TInt command, const TDesC& text);
+ QPoint softkeyIconPosition(int position, QSize sourceSize, QSize targetSize);
+ QPixmap prepareSoftkeyPixmap(QPixmap src, int position, QSize targetSize);
+ bool isOrientationLandscape();
+ QSize cbaIconSize(CEikButtonGroupContainer *cba, int position);
+ bool setSoftkeyImage(CEikButtonGroupContainer *cba, QAction &action, int position);
+ bool setSoftkey(CEikButtonGroupContainer &cba, QAction::SoftKeyRole role, int position);
+ bool setLeftSoftkey(CEikButtonGroupContainer &cba);
+ bool setMiddleSoftkey(CEikButtonGroupContainer &cba);
+ bool setRightSoftkey(CEikButtonGroupContainer &cba);
+ void setSoftkeys(CEikButtonGroupContainer &cba);
+
+private:
+ QHash<int, QAction*> realSoftKeyActions;
+ QSize cachedCbaIconSize[4];
+ bool skipNextUpdate;
+};
+
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_SOFTKEYMANAGER
+
+QT_END_HEADER
+
+#endif // QSOFTKEYMANAGER_S60_P_H
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index e06a810..65c04e5 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -1162,7 +1162,7 @@ CGContextRef qt_mac_graphicsContextFor(QWidget *widget)
CGrafPtr port = GetWindowPort(qt_mac_window_for(widget));
QDBeginCGContext(port, &context);
#else
- CGContextRef context = (CGContextRef)[[NSGraphicsContext graphicsContextWithWindow:qt_mac_window_for(widget)] graphicsPort];
+ CGContextRef context = reinterpret_cast<CGContextRef>([[qt_mac_window_for(widget) graphicsContext] graphicsPort]);
#endif
return context;
}
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index 1163055..735ca7a 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -128,6 +128,7 @@ public:
static inline RWindowGroup& windowGroup();
static inline CWsScreenDevice* screenDevice();
static inline CCoeAppUi* appUi();
+ static inline CEikMenuBar* menuBar();
#ifdef Q_WS_S60
static inline CEikStatusPane* statusPane();
static inline CCoeControl* statusPaneSubPane(TInt aPaneId);
@@ -270,6 +271,11 @@ inline CCoeAppUi* QS60Data::appUi()
return CCoeEnv::Static()-> AppUi();
}
+inline CEikMenuBar* QS60Data::menuBar()
+{
+ return CEikonEnv::Static()->AppUiFactory()->MenuBar();
+}
+
#ifdef Q_WS_S60
inline CEikStatusPane* QS60Data::statusPane()
{
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index ffad38b..2a19d23 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -192,6 +192,7 @@ QWidgetPrivate::QWidgetPrivate(int version)
, inDirtyList(0)
, isScrolled(0)
, isMoved(0)
+ , isGLWidget(0)
, usesDoubleBufferedGLContext(0)
#if defined(Q_WS_X11)
, picture(0)
@@ -200,7 +201,6 @@ QWidgetPrivate::QWidgetPrivate(int version)
, nativeGesturePanEnabled(0)
#elif defined(Q_WS_MAC)
, needWindowChange(0)
- , isGLWidget(0)
, window_event(0)
, qd_hd(0)
#endif
@@ -1439,6 +1439,18 @@ QWidget::~QWidget()
}
#endif
+#ifdef Q_OS_SYMBIAN
+ if (d->extra && d->extra->topextra && d->extra->topextra->backingStore) {
+ // Okay, we are about to destroy the top-level window that owns
+ // the backing store. Make sure we delete the backing store right away
+ // before the window handle is invalid. This is important because
+ // the backing store will delete its window surface, which may or may
+ // not have a reference to this widget that will be used later to
+ // notify the window it no longer has a surface.
+ delete d->extra->topextra->backingStore;
+ d->extra->topextra->backingStore = 0;
+ }
+#endif
if (QWidgetBackingStore *bs = d->maybeBackingStore()) {
bs->removeDirtyWidget(this);
if (testAttribute(Qt::WA_StaticContents))
@@ -1660,7 +1672,13 @@ void QWidgetPrivate::syncBackingStore()
repaint_sys(dirty);
dirty = QRegion();
} else if (QWidgetBackingStore *bs = maybeBackingStore()) {
+#ifdef QT_MAC_USE_COCOA
+ Q_UNUSED(bs);
+ void qt_mac_set_needs_display(QWidget *, QRegion);
+ qt_mac_set_needs_display(q_func(), QRegion());
+#else
bs->sync();
+#endif
}
}
@@ -1668,8 +1686,15 @@ void QWidgetPrivate::syncBackingStore(const QRegion &region)
{
if (paintOnScreen())
repaint_sys(region);
- else if (QWidgetBackingStore *bs = maybeBackingStore())
+ else if (QWidgetBackingStore *bs = maybeBackingStore()) {
+#ifdef QT_MAC_USE_COCOA
+ Q_UNUSED(bs);
+ void qt_mac_set_needs_display(QWidget *, QRegion);
+ qt_mac_set_needs_display(q_func(), region);
+#else
bs->sync(q_func(), region);
+#endif
+ }
}
void QWidgetPrivate::setUpdatesEnabled_helper(bool enable)
@@ -6414,6 +6439,8 @@ void QWidget::setTabOrder(QWidget* first, QWidget *second)
first = fp;
}
+ if (fp == second)
+ return;
if (QWidget *sp = second->focusProxy())
second = sp;
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index ebfab21..9e7517f 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -565,6 +565,25 @@ inline static void qt_mac_set_window_group_to_popup(OSWindowRef window)
}
#endif
+#ifdef QT_MAC_USE_COCOA
+void qt_mac_set_needs_display(QWidget *widget, QRegion region)
+{
+ NSView *theNSView = qt_mac_nativeview_for(widget);
+ if (region.isEmpty()) {
+ [theNSView setNeedsDisplay:YES];
+ return;
+ }
+
+ QVector<QRect> rects = region.rects();
+ for (int i = 0; i<rects.count(); ++i) {
+ const QRect &rect = rects.at(i);
+ NSRect nsrect = NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height());
+ [theNSView setNeedsDisplayInRect:nsrect];
+ }
+
+}
+#endif
+
inline static bool updateRedirectedToGraphicsProxyWidget(QWidget *widget, const QRect &rect)
{
if (!widget)
@@ -3510,6 +3529,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 b1eb3c3..b421d30 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -173,6 +173,8 @@ struct QTLWExtra {
#ifndef QT_NO_QWS_MANAGER
QWSManager *qwsManager;
#endif
+#elif defined(Q_OS_SYMBIAN)
+ uint inExpose : 1; // Prevents drawing recursion
#endif
};
@@ -229,7 +231,6 @@ 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.
@@ -682,6 +683,7 @@ public:
uint inDirtyList : 1;
uint isScrolled : 1;
uint isMoved : 1;
+ uint isGLWidget : 1;
uint usesDoubleBufferedGLContext : 1;
// *************************** Platform specific ************************************
@@ -713,7 +715,6 @@ public:
#elif defined(Q_WS_MAC) // <--------------------------------------------------------- MAC
// This is new stuff
uint needWindowChange : 1;
- uint isGLWidget : 1;
// Each wiget keeps a list of all its child and grandchild OpenGL widgets.
// This list is used to update the gl context whenever a parent and a granparent
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index 00f2213..ebd289c 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -878,6 +878,7 @@ void QWidgetPrivate::registerDropSite(bool /* on */)
void QWidgetPrivate::createTLSysExtra()
{
extra->topextra->backingStore = 0;
+ extra->topextra->inExpose = 0;
}
void QWidgetPrivate::deleteTLSysExtra()
@@ -891,7 +892,6 @@ void QWidgetPrivate::createSysExtra()
extra->activated = 0;
extra->nativePaintMode = QWExtra::Default;
extra->receiveNativePaintEvents = 0;
- extra->inExpose = 0;
}
void QWidgetPrivate::deleteSysExtra()
@@ -1046,96 +1046,48 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
return;
if (isWindow()) {
-#ifdef Q_WS_S60
- // Change window decoration visibility if switching to or from fullsccreen
- // In addition decoration visibility is changed when the initial has been
- // WindowNoState.
- // The window decoration visibility has to be changed before doing actual
- // window state change since in that order the availableGeometry will return
- // directly the right size and we will avoid unnecessarty redraws
- if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen) ||
- oldstate == Qt::WindowNoState) {
- CEikStatusPane* statusPane = S60->statusPane();
- CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer();
- if (newstate & Qt::WindowFullScreen) {
- if (statusPane)
- statusPane->MakeVisible(false);
- if (buttonGroup)
- buttonGroup->MakeVisible(false);
- } else {
- if (statusPane)
- statusPane->MakeVisible(true);
- if (buttonGroup)
- buttonGroup->MakeVisible(true);
- }
+ QSymbianControl *window = static_cast<QSymbianControl *>(effectiveWinId());
+ if (window && newstate & Qt::WindowMinimized) {
+ window->setFocusSafely(false);
+ window->MakeVisible(false);
+ } else if (window && oldstate & Qt::WindowMinimized) {
+ window->setFocusSafely(true);
+ window->MakeVisible(true);
}
+
+#ifdef Q_WS_S60
+ // Hide window decoration when switching to fullsccreen / minimized otherwise show decoration.
+ // The window decoration visibility has to be changed before doing actual window state
+ // change since in that order the availableGeometry will return directly the right size and
+ // we will avoid unnecessarty redraws
+ CEikStatusPane* statusPane = S60->statusPane();
+ CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer();
+ TBool visible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized));
+ if (statusPane)
+ statusPane->MakeVisible(visible);
+ if (buttonGroup)
+ buttonGroup->MakeVisible(visible);
#endif // Q_WS_S60
createWinId();
Q_ASSERT(testAttribute(Qt::WA_WState_Created));
- QTLWExtra *top = d->topData();
-
// Ensure the initial size is valid, since we store it as normalGeometry below.
if (!testAttribute(Qt::WA_Resized) && !isVisible())
adjustSize();
- if ((oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized)) {
- if ((newstate & Qt::WindowMaximized)) {
- const QRect normalGeometry = geometry();
+ QTLWExtra *top = d->topData();
+ const QRect normalGeometry = (top->normalGeometry.width() < 0) ? geometry() : top->normalGeometry;
- const QRect r = top->normalGeometry;
- setGeometry(qApp->desktop()->availableGeometry(this));
- top->normalGeometry = r;
+ if (newstate & Qt::WindowFullScreen)
+ setGeometry(qApp->desktop()->screenGeometry(this));
+ else if (newstate & Qt::WindowMaximized)
+ setGeometry(qApp->desktop()->availableGeometry(this));
+ else
+ setGeometry(normalGeometry);
- if (top->normalGeometry.width() < 0)
- top->normalGeometry = normalGeometry;
- } else {
- // restore original geometry
- setGeometry(top->normalGeometry);
- }
- }
- if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen)) {
- if (newstate & Qt::WindowFullScreen) {
- const QRect normalGeometry = geometry();
- const QRect r = top->normalGeometry;
- setGeometry(qApp->desktop()->screenGeometry(this));
-
- top->normalGeometry = r;
- if (top->normalGeometry.width() < 0)
- top->normalGeometry = normalGeometry;
- } else {
- if (newstate & Qt::WindowMaximized) {
- const QRect r = top->normalGeometry;
- setGeometry(qApp->desktop()->availableGeometry(this));
- top->normalGeometry = r;
- } else {
- setGeometry(top->normalGeometry);
- }
- }
- }
- if ((oldstate & Qt::WindowMinimized) != (newstate & Qt::WindowMinimized)) {
- if (newstate & Qt::WindowMinimized) {
- if (isVisible()) {
- QSymbianControl *id = static_cast<QSymbianControl *>(effectiveWinId());
- if (id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
- id->setFocusSafely(false);
- id->MakeVisible(false);
- }
- } else {
- if (isVisible()) {
- QSymbianControl *id = static_cast<QSymbianControl *>(effectiveWinId());
- id->MakeVisible(true);
- if (!id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
- id->setFocusSafely(true);
- }
- const QRect normalGeometry = geometry();
- const QRect r = top->normalGeometry;
- top->normalGeometry = r;
- if (top->normalGeometry.width() < 0)
- top->normalGeometry = normalGeometry;
- }
- }
+ //restore normal geometry
+ top->normalGeometry = normalGeometry;
}
data->window_state = newstate;
@@ -1195,6 +1147,10 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
if (destroyWindow) {
delete id;
+ // At this point the backing store should already be destroyed
+ // so we flush the command buffer to ensure that the freeing of
+ // those resources and deleting the window can happen "atomically"
+ S60->wsSession().Flush();
}
}
diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp
index 4684bc1..10fb009 100644
--- a/src/gui/kernel/qwidget_x11.cpp
+++ b/src/gui/kernel/qwidget_x11.cpp
@@ -346,11 +346,6 @@ Q_GUI_EXPORT void qt_x11_enforce_cursor(QWidget * w)
qt_x11_enforce_cursor(w, false);
}
-static Bool checkForConfigureAndExpose(Display *, XEvent *e, XPointer)
-{
- return e->type == ConfigureNotify || e->type == Expose;
-}
-
Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w)
{
if (!w || (!w->isWindow() && !w->internalWinId()))
@@ -363,38 +358,60 @@ Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w)
if (!w->testAttribute(Qt::WA_WState_Created))
return;
- if (!(w->windowFlags() & Qt::X11BypassWindowManagerHint)) {
- // if the window is not override-redirect, then the window manager
- // will reparent us to the frame decoration window.
- while (!XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), ReparentNotify, &ev)) {
- if (t.elapsed() > maximumWaitTime)
- return;
- qApp->syncX(); // non-busy wait
- }
- }
+ WId winid = w->internalWinId();
- while (!XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), MapNotify, &ev)) {
- if (t.elapsed() > maximumWaitTime)
- return;
- qApp->syncX(); // non-busy wait
- }
+ // first deliver events that are already in the local queue
+ QApplication::sendPostedEvents();
- qApp->x11ProcessEvent(&ev);
+ // the normal sequence is:
+ // ... ConfigureNotify ... ReparentNotify ... MapNotify ... Expose
+ // with X11BypassWindowManagerHint:
+ // ConfigureNotify ... MapNotify ... Expose
- // ok, seems like the window manager successfully reparented us, we'll wait
- // for the first paint event to arrive, while handling ConfigureNotify in
- // the arrival order
- while(1)
- {
- if (XCheckIfEvent(X11->display, &ev, checkForConfigureAndExpose, 0)) {
+ enum State {
+ Initial, Reparented, Mapped
+ } state = Initial;
+
+ do {
+ if (XEventsQueued(X11->display, QueuedAlready)) {
+ XNextEvent(X11->display, &ev);
qApp->x11ProcessEvent(&ev);
- if (ev.type == Expose)
- return;
+
+ if (w->windowFlags() & Qt::X11BypassWindowManagerHint) {
+ switch (state) {
+ case Initial:
+ case Reparented:
+ if (ev.type == MapNotify && ev.xany.window == winid)
+ state = Mapped;
+ break;
+ case Mapped:
+ if (ev.type == Expose && ev.xany.window == winid)
+ return;
+ break;
+ }
+ } else {
+ switch (state) {
+ case Initial:
+ if (ev.type == ReparentNotify && ev.xany.window == winid)
+ state = Reparented;
+ break;
+ case Reparented:
+ if (ev.type == MapNotify && ev.xany.window == winid)
+ state = Mapped;
+ break;
+ case Mapped:
+ if (ev.type == Expose && ev.xany.window == winid)
+ return;
+ break;
+ }
+ }
+ } else {
+ if (!XEventsQueued(X11->display, QueuedAfterFlush))
+ qApp->syncX(); // non-busy wait
}
if (t.elapsed() > maximumWaitTime)
return;
- qApp->syncX(); // non-busy wait
- }
+ } while(1);
}
void qt_change_net_wm_state(const QWidget* w, bool set, Atom one, Atom two = 0)
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 194dda3..7a3da20 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -1267,32 +1267,28 @@ static const uint L2CacheLineLengthInInts = L2CacheLineLength/sizeof(uint);
result = 0
d = d * cia
*/
+#define comp_func_Clear_impl(dest, length, const_alpha)\
+{\
+ if (const_alpha == 255) {\
+ QT_MEMFILL_UINT(dest, length, 0);\
+ } else {\
+ int ialpha = 255 - const_alpha;\
+ PRELOAD_INIT(dest)\
+ for (int i = 0; i < length; ++i) {\
+ PRELOAD_COND(dest)\
+ dest[i] = BYTE_MUL(dest[i], ialpha);\
+ }\
+ }\
+}
+
static void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha)
{
- if (const_alpha == 255) {
- QT_MEMFILL_UINT(dest, length, 0);
- } else {
- int ialpha = 255 - const_alpha;
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- dest[i] = BYTE_MUL(dest[i], ialpha);
- }
- }
+ comp_func_Clear_impl(dest, length, const_alpha);
}
static void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha)
{
- if (const_alpha == 255) {
- QT_MEMFILL_UINT(dest, length, 0);
- } else {
- int ialpha = 255 - const_alpha;
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- dest[i] = BYTE_MUL(dest[i], ialpha);
- }
- }
+ comp_func_Clear_impl(dest, length, const_alpha);
}
/*
@@ -2408,7 +2404,11 @@ static inline int soft_light_op(int dst, int src, int da, int sa)
else if (4 * dst <= da)
return (dst * sa * 255 + da * (src2 - sa) * ((((16 * dst_np - 12 * 255) * dst_np + 3 * 65025) * dst_np) / 65025) + temp) / 65025;
else {
+# ifdef Q_CC_RVCT // needed to avoid compiler crash in RVCT 2.2
+ return (dst * sa * 255 + da * (src2 - sa) * (qIntSqrtInt(dst_np * 255) - dst_np) + temp) / 65025;
+# else
return (dst * sa * 255 + da * (src2 - sa) * (int(sqrt(qreal(dst_np * 255))) - dst_np) + temp) / 65025;
+# endif
}
}
diff --git a/src/gui/painting/qdrawhelper_mmx_p.h b/src/gui/painting/qdrawhelper_mmx_p.h
index 8482262..59b3804 100644
--- a/src/gui/painting/qdrawhelper_mmx_p.h
+++ b/src/gui/painting/qdrawhelper_mmx_p.h
@@ -146,36 +146,30 @@ struct QMMXCommonIntrinsics
result = 0
d = d * cia
*/
+#define comp_func_Clear_impl(dest, length, const_alpha)\
+{\
+ if (const_alpha == 255) {\
+ qt_memfill(static_cast<quint32*>(dest), quint32(0), length);\
+ } else {\
+ C_FF; C_80; C_00;\
+ m64 ia = MM::negate(MM::load_alpha(const_alpha));\
+ for (int i = 0; i < length; ++i) {\
+ dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), ia));\
+ }\
+ MM::end();\
+ }\
+}
+
template <class MM>
static void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha)
{
- if (!length)
- return;
-
- if (const_alpha == 255) {
- qt_memfill(static_cast<quint32*>(dest), quint32(0), length);
- } else {
- C_FF; C_80; C_00;
- m64 ia = MM::negate(MM::load_alpha(const_alpha));
- for (int i = 0; i < length; ++i) {
- dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), ia));
- }
- }
- MM::end();
+ comp_func_Clear_impl(dest, length, const_alpha);
}
template <class MM>
static void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha)
{
- if (const_alpha == 255) {
- qt_memfill(static_cast<quint32*>(dest), quint32(0), length);
- } else {
- C_FF; C_80; C_00;
- m64 ia = MM::negate(MM::load_alpha(const_alpha));
- for (int i = 0; i < length; ++i)
- dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), ia));
- }
- MM::end();
+ comp_func_Clear_impl(dest, length, const_alpha);
}
/*
@@ -246,7 +240,10 @@ static void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int le
C_FF; C_80; C_00;
if (const_alpha == 255) {
for (int i = 0; i < length; ++i) {
- if ((0xff000000 & src[i]) == 0xff000000) {
+ const uint alphaMaskedSource = 0xff000000 & src[i];
+ if (alphaMaskedSource == 0)
+ continue;
+ if (alphaMaskedSource == 0xff000000) {
dest[i] = src[i];
} else {
m64 s = MM::load(src[i]);
@@ -257,6 +254,8 @@ static void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int le
} else {
m64 ca = MM::load_alpha(const_alpha);
for (int i = 0; i < length; ++i) {
+ if ((0xff000000 & src[i]) == 0)
+ continue;
m64 s = MM::byte_mul(MM::load(src[i]), ca);
m64 ia = MM::negate(MM::alpha(s));
dest[i] = MM::store(MM::add(s, MM::byte_mul(MM::load(dest[i]), ia)));
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index 6c47aac..cb0db4f 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -1549,6 +1549,9 @@ template<> inline void qt_memfill(quint8 *dest, quint8 color, int count)
template <class T>
inline void qt_memfill(T *dest, T value, int count)
{
+ if (!count)
+ return;
+
int n = (count + 7) / 8;
switch (count & 0x07)
{
diff --git a/src/gui/painting/qmath_p.h b/src/gui/painting/qmath_p.h
index cd9f5ea..8a5f5ab 100644
--- a/src/gui/painting/qmath_p.h
+++ b/src/gui/painting/qmath_p.h
@@ -54,6 +54,7 @@
//
#include <math.h>
+#include <qmath.h>
QT_BEGIN_NAMESPACE
@@ -61,6 +62,11 @@ static const qreal Q_PI = qreal(3.14159265358979323846); // pi
static const qreal Q_2PI = qreal(6.28318530717958647693); // 2*pi
static const qreal Q_PI2 = qreal(1.57079632679489661923); // pi/2
+inline int qIntSqrtInt(int v)
+{
+ return static_cast<int>(qSqrt(static_cast<qreal>(v)));
+}
+
QT_END_NAMESPACE
#endif // QMATH_P_H
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 3f2322e..bc56ed0 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -3081,6 +3081,8 @@ void QRasterPaintEngine::drawGlyphsS60(const QPointF &p, const QTextItemInt &ti)
QVarLengthArray<glyph_t> glyphs;
QTransform matrix = s->matrix;
matrix.translate(p.x(), p.y());
+ if (matrix.type() == QTransform::TxScale)
+ fe->setFontScale(matrix.m11());
ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
const QFixed aliasDelta = QFixed::fromReal(aliasedCoordinateDelta);
@@ -3097,6 +3099,9 @@ void QRasterPaintEngine::drawGlyphsS60(const QPointF &p, const QTextItemInt &ti)
alphaPenBlt(glyphBitmapBytes, glyphBitmapSize.iWidth, 8, x, y, glyphBitmapSize.iWidth, glyphBitmapSize.iHeight);
}
+ if (matrix.type() == QTransform::TxScale)
+ fe->setFontScale(1.0);
+
return;
}
#endif // Q_OS_SYMBIAN && QT_NO_FREETYPE
@@ -3269,7 +3274,9 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte
}
#elif defined (Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE) // Q_WS_WIN || Q_WS_MAC
- if (s->matrix.type() <= QTransform::TxTranslate) {
+ if (s->matrix.type() <= QTransform::TxTranslate
+ || (s->matrix.type() == QTransform::TxScale
+ && (qFuzzyCompare(s->matrix.m11(), s->matrix.m22())))) {
drawGlyphsS60(p, ti);
return;
}
diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp
index 147491e..da48fcb 100644
--- a/src/gui/painting/qpaintengine_x11.cpp
+++ b/src/gui/painting/qpaintengine_x11.cpp
@@ -1989,6 +1989,9 @@ void QX11PaintEngine::drawPixmap(const QRectF &r, const QPixmap &px, const QRect
}
XFillRectangle(d->dpy, d->hd, d->gc, x, y, sw, sh);
restore_clip = true;
+ } else if (mono_dst && !mono_src) {
+ QBitmap bitmap(pixmap);
+ XCopyArea(d->dpy, bitmap.handle(), d->hd, d->gc, sx, sy, sw, sh, x, y);
} else {
XCopyArea(d->dpy, pixmap.handle(), d->hd, d->gc, sx, sy, sw, sh, x, y);
}
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 2502cc0..270144b 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -1987,12 +1987,25 @@ QPaintEngine *QPainter::paintEngine() const
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().
+ to their respective default states. The states we reset may change from
+ release to release. The following states are currently reset in the OpenGL
+ 2 engine:
- Here is an example that shows intermixing of painter commands
- and raw OpenGL commands:
+ \list
+ \i blending is disabled
+ \i the depth, stencil and scissor tests are disabled
+ \i the active texture unit is reset to 0
+ \i the depth mask, depth function and the clear depth are reset to their
+ default values
+ \i the stencil mask, stencil operation and stencil function are reset to
+ their default values
+ \i the current color is reset to solid white
+ \endlist
+
+ 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:
\snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 21
@@ -7510,7 +7523,7 @@ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
return widgetPrivate->redirected(offset);
}
- if (*globalRedirectionAtomic() == 0)
+ if (!globalRedirectionAtomic() || *globalRedirectionAtomic() == 0)
return 0;
QMutexLocker locker(globalRedirectionsMutex());
@@ -7530,7 +7543,7 @@ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
void qt_painter_removePaintDevice(QPaintDevice *dev)
{
- if (*globalRedirectionAtomic() == 0)
+ if (!globalRedirectionAtomic() || *globalRedirectionAtomic() == 0)
return;
QMutex *mutex = 0;
diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp
index 7997e77..bc81514 100644
--- a/src/gui/painting/qpathclipper.cpp
+++ b/src/gui/painting/qpathclipper.cpp
@@ -90,8 +90,6 @@ static QPointF normalize(const QPointF &p)
return p / qSqrt(p.x() * p.x() + p.y() * p.y());
}
-static bool pathToRect(const QPainterPath &path, QRectF *rect = 0);
-
struct QIntersection
{
qreal alphaA;
@@ -1660,7 +1658,7 @@ static bool fuzzyCompare(qreal a, qreal b)
return qFuzzyCompare(a, b);
}
-static bool pathToRect(const QPainterPath &path, QRectF *rect)
+bool QPathClipper::pathToRect(const QPainterPath &path, QRectF *rect)
{
if (path.elementCount() != 5)
return false;
@@ -1693,7 +1691,7 @@ static bool pathToRect(const QPainterPath &path, QRectF *rect)
return false;
if (rect)
- *rect = QRectF(QPointF(x1, y1), QPointF(x2, y2));
+ rect->setCoords(x1, y1, x2, y2);
return true;
}
diff --git a/src/gui/painting/qpathclipper_p.h b/src/gui/painting/qpathclipper_p.h
index 0d2c049..b900862 100644
--- a/src/gui/painting/qpathclipper_p.h
+++ b/src/gui/painting/qpathclipper_p.h
@@ -86,6 +86,8 @@ public:
bool intersect();
bool contains();
+ static bool pathToRect(const QPainterPath &path, QRectF *rect = 0);
+
private:
Q_DISABLE_COPY(QPathClipper)
diff --git a/src/gui/painting/qwindowsurface_raster.cpp b/src/gui/painting/qwindowsurface_raster.cpp
index a0d2b9b..eee6bef 100644
--- a/src/gui/painting/qwindowsurface_raster.cpp
+++ b/src/gui/painting/qwindowsurface_raster.cpp
@@ -295,10 +295,8 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi
CGContextRestoreGState(context);
#ifndef QT_MAC_USE_COCOA
QDEndCGContext(port, &context);
-#else
- CGContextFlush(context);
-#endif
#endif
+#endif // Q_WS_MAC
#ifdef Q_OS_SYMBIAN
Q_UNUSED(widget);
diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp
index b41dc2c..6cbf3d9 100644
--- a/src/gui/painting/qwindowsurface_s60.cpp
+++ b/src/gui/painting/qwindowsurface_s60.cpp
@@ -145,12 +145,15 @@ QImage* QS60WindowSurface::buffer(const QWidget *widget)
void QS60WindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &)
{
- QWExtra *extra = widget->d_func()->extraData();
- if (extra && !extra->inExpose) {
- extra->inExpose = true; // Prevent DrawNow() from calling syncBackingStore() again
+ QWidget *window = widget->window();
+ Q_ASSERT(window);
+ QTLWExtra *topExtra = window->d_func()->maybeTopData();
+ Q_ASSERT(topExtra);
+ if (!topExtra->inExpose) {
+ topExtra->inExpose = true; // Prevent DrawNow() from calling syncBackingStore() again
TRect tr = qt_QRect2TRect(region.boundingRect());
widget->winId()->DrawNow(tr);
- extra->inExpose = false;
+ topExtra->inExpose = false;
}
}
diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp
index 739a70b..b1924e7 100644
--- a/src/gui/styles/qcommonstyle.cpp
+++ b/src/gui/styles/qcommonstyle.cpp
@@ -1149,10 +1149,10 @@ void QCommonStylePrivate::tabLayout(const QStyleOptionTabV3 *opt, const QWidget
int vpadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabVSpace, opt, widget) / 2;
if (opt->shape == QTabBar::RoundedSouth || opt->shape == QTabBar::TriangularSouth)
verticalShift = -verticalShift;
- tr.adjust(hpadding, vpadding, horizontalShift - hpadding, verticalShift - vpadding);
+ tr.adjust(hpadding, verticalShift - vpadding, horizontalShift - hpadding, vpadding);
bool selected = opt->state & QStyle::State_Selected;
if (selected) {
- tr.setBottom(tr.bottom() - verticalShift);
+ tr.setTop(tr.top() - verticalShift);
tr.setRight(tr.right() - horizontalShift);
}
@@ -1608,7 +1608,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
if (toolbutton->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
pr.setHeight(pmSize.height() + 6);
- tr.adjust(0, pr.height() - 1, 0, -3);
+ tr.adjust(0, pr.height() - 1, 0, -2);
pr.translate(shiftX, shiftY);
if (!hasArrow) {
proxy()->drawItemPixmap(p, pr, Qt::AlignCenter, pm);
diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm
index f4af579..78074c7 100644
--- a/src/gui/styles/qmacstyle_mac.mm
+++ b/src/gui/styles/qmacstyle_mac.mm
@@ -2411,7 +2411,12 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW
ret = 0;
break;
case PM_ToolBarFrameWidth:
- ret = 0;
+ ret = 1;
+ if (widget) {
+ if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(widget->parent()))
+ if (mainWindow->unifiedTitleAndToolBarOnMac())
+ ret = 0;
+ }
break;
default:
ret = QWindowsStyle::pixelMetric(metric, opt, widget);
@@ -3375,8 +3380,14 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
if (tb->toolButtonStyle != Qt::ToolButtonIconOnly) {
needText = true;
if (tb->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
- pr.setHeight(pixmap.size().height());
- cr.adjust(0, pr.bottom() + 1, 0, 1);
+ QMainWindow *mw = qobject_cast<QMainWindow *>(w->window());
+ if (mw && mw->unifiedTitleAndToolBarOnMac()) {
+ pr.setHeight(pixmap.size().height());
+ cr.adjust(0, pr.bottom() + 1, 0, 1);
+ } else {
+ pr.setHeight(pixmap.size().height() + 6);
+ cr.adjust(0, pr.bottom(), 0, -3);
+ }
alignment |= Qt::AlignCenter;
} else {
pr.setWidth(pixmap.width() + 8);
@@ -4341,8 +4352,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:
@@ -5717,12 +5726,16 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
break;
case CT_ToolButton:
if (widget && qobject_cast<const QToolBar *>(widget->parentWidget())) {
- sz.rwidth() += 4;
- if (sz.height() <= 32) {
- // Workaround strange HIToolBar bug when getting constraints.
- sz.rheight() += 1;
+ if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(widget->parent())) {
+ if (mainWindow->unifiedTitleAndToolBarOnMac()) {
+ sz.rwidth() += 4;
+ if (sz.height() <= 32) {
+ // Workaround strange HIToolBar bug when getting constraints.
+ sz.rheight() += 1;
+ }
+ return sz;
+ }
}
- return sz;
}
sz.rwidth() += 10;
sz.rheight() += 10;
diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp
index 9b99161..9025e5b 100644
--- a/src/gui/styles/qs60style.cpp
+++ b/src/gui/styles/qs60style.cpp
@@ -92,10 +92,10 @@ static const qreal goldenRatio = 1.618;
const layoutHeader QS60StylePrivate::m_layoutHeaders[] = {
// *** generated layout data ***
-{240,320,1,15,"QVGA Landscape"},
-{320,240,1,15,"QVGA Portrait"},
-{360,640,1,15,"NHD Landscape"},
-{640,360,1,15,"NHD Portrait"},
+{240,320,1,16,"QVGA Landscape"},
+{320,240,1,16,"QVGA Portrait"},
+{360,640,1,16,"NHD Landscape"},
+{640,360,1,16,"NHD Portrait"},
{352,800,1,12,"E90 Landscape"}
// *** End of generated data ***
};
@@ -104,10 +104,10 @@ const int QS60StylePrivate::m_numberOfLayouts =
const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = {
// *** generated pixel metrics ***
-{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,-909,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,3,3,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1},
-{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1},
-{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1},
-{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,5,5,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1},
+{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,-909,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,4,4,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1},
+{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,3,3,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1},
+{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,13,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1},
+{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,12,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1},
{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1}
// *** End of generated data ***
};
@@ -2399,22 +2399,15 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
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;
+ case CT_ComboBox: {
+ // Fixing Ui design issues with too wide QComboBoxes and greedy SizeHints
+ // Make sure, that the combobox says within the screen.
+ const QSize desktopContentSize = QApplication::desktop()->availableGeometry().size()
+ -QSize(pixelMetric(PM_LayoutLeftMargin) + pixelMetric(PM_LayoutRightMargin), 0);
+ sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget).
+ boundedTo(desktopContentSize);
+ }
+ break;
#endif
default:
sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp
index 498313b..b36294a 100644
--- a/src/gui/styles/qstylesheetstyle.cpp
+++ b/src/gui/styles/qstylesheetstyle.cpp
@@ -1125,6 +1125,7 @@ void QRenderRule::fixupBorder(int nativeWidth)
void QRenderRule::drawBorderImage(QPainter *p, const QRect& rect)
{
+ setClip(p, rect);
static const Qt::TileRule tileMode2TileRule[] = {
Qt::StretchTile, Qt::RoundTile, Qt::StretchTile, Qt::RepeatTile, Qt::StretchTile };
@@ -1142,6 +1143,7 @@ void QRenderRule::drawBorderImage(QPainter *p, const QRect& rect)
QRect(QPoint(), borderImageData->pixmap.size()), sourceMargins,
QTileRules(tileMode2TileRule[borderImageData->horizStretch], tileMode2TileRule[borderImageData->vertStretch]));
p->setRenderHint(QPainter::SmoothPixmapTransform, wasSmoothPixmapTransform);
+ unsetClip(p);
}
QRect QRenderRule::originRect(const QRect &rect, Origin origin) const
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index bbd35f1..dd9e69e 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -629,8 +629,9 @@ QFontEngineData::~QFontEngineData()
Returns the name of the font within the underlying window system.
- Only on X11 when Qt was built without FontConfig support the XLFD (X Logical Font Description)
- is returned; otherwise an empty string.
+ On X11, this function will return an empty string if Qt is built with
+ FontConfig support; otherwise the XLFD (X Logical Font Description) is
+ returned.
Using the return value of this function is usually \e not \e
portable.
diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp
index f8de08f..7e5397d 100644
--- a/src/gui/text/qfontdatabase_s60.cpp
+++ b/src/gui/text/qfontdatabase_s60.cpp
@@ -246,8 +246,8 @@ static void initializeDb()
QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
const int numTypeFaces = QS60Data::screenDevice()->NumTypefaces();
- const QFontDatabaseS60StoreImplementation *store = dynamic_cast<const QFontDatabaseS60StoreImplementation*>(db->s60Store);
- Q_ASSERT(store);
+ const QFontDatabaseS60StoreImplementation *store =
+ static_cast<const QFontDatabaseS60StoreImplementation*>(db->s60Store);
bool fontAdded = false;
for (int i = 0; i < numTypeFaces; i++) {
TTypefaceSupport typefaceSupport;
@@ -258,8 +258,7 @@ static void initializeDb()
continue;
if (font->TypeUid() == KCFbsFontUid) {
TOpenFontFaceAttrib faceAttrib;
- const CFbsFont *cfbsFont = dynamic_cast<const CFbsFont *>(font);
- Q_ASSERT(cfbsFont);
+ const CFbsFont *cfbsFont = static_cast<const CFbsFont *>(font);
cfbsFont->GetFaceAttrib(faceAttrib);
QtFontStyle::Key styleKey;
@@ -390,8 +389,8 @@ QFontEngine *QFontDatabase::findFont(int script, const QFontPrivate *, const QFo
QFontDef request = req;
request.family = fontFamily;
#if defined(QT_NO_FREETYPE)
- const QFontDatabaseS60StoreImplementation *store = dynamic_cast<const QFontDatabaseS60StoreImplementation*>(db->s60Store);
- Q_ASSERT(store);
+ const QFontDatabaseS60StoreImplementation *store =
+ static_cast<const QFontDatabaseS60StoreImplementation*>(db->s60Store);
const QFontEngineS60Extensions *extension = store->extension(fontFamily);
fe = new QFontEngineS60(request, extension);
#else
diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp
index 4625667..3ea084b 100644
--- a/src/gui/text/qfontengine_s60.cpp
+++ b/src/gui/text/qfontengine_s60.cpp
@@ -44,7 +44,7 @@
#include "qglobal.h"
#include <private/qapplication_p.h>
#include "qimage.h"
-#include "qt_s60_p.h"
+#include <private/qt_s60_p.h>
#include <e32base.h>
#include <e32std.h>
@@ -129,26 +129,62 @@ static inline unsigned int getChar(const QChar *str, int &i, const int len)
return uc;
}
+CFont *QFontEngineS60::fontWithSize(qreal size) const
+{
+ CFont *result = 0;
+ TFontSpec fontSpec(qt_QString2TPtrC(QFontEngine::fontDef.family), TInt(size));
+ fontSpec.iFontStyle.SetBitmapType(EAntiAliasedGlyphBitmap);
+ fontSpec.iFontStyle.SetPosture(QFontEngine::fontDef.style == QFont::StyleNormal?EPostureUpright:EPostureItalic);
+ fontSpec.iFontStyle.SetStrokeWeight(QFontEngine::fontDef.weight > QFont::Normal?EStrokeWeightBold:EStrokeWeightNormal);
+ const TInt errorCode = S60->screenDevice()->GetNearestFontToDesignHeightInPixels(result, fontSpec);
+ Q_ASSERT(result && (errorCode == 0));
+ return result;
+}
+
+void QFontEngineS60::setFontScale(qreal scale)
+{
+ if (qFuzzyCompare(scale, qreal(1))) {
+ if (!m_originalFont)
+ m_originalFont = fontWithSize(m_originalFontSizeInPixels);
+ m_activeFont = m_originalFont;
+ } else {
+ const qreal scaledFontSizeInPixels = m_originalFontSizeInPixels * scale;
+ if (!m_scaledFont ||
+ (TInt(scaledFontSizeInPixels) != TInt(m_scaledFontSizeInPixels))) {
+ releaseFont(m_scaledFont);
+ m_scaledFontSizeInPixels = scaledFontSizeInPixels;
+ m_scaledFont = fontWithSize(m_scaledFontSizeInPixels);
+ }
+ m_activeFont = m_scaledFont;
+ }
+}
+
+void QFontEngineS60::releaseFont(CFont *&font)
+{
+ if (font) {
+ S60->screenDevice()->ReleaseFont(font);
+ font = 0;
+ }
+}
+
QFontEngineS60::QFontEngineS60(const QFontDef &request, const QFontEngineS60Extensions *extensions)
: m_extensions(extensions)
+ , m_originalFont(0)
+ , m_originalFontSizeInPixels((request.pixelSize >= 0)?
+ request.pixelSize:pointsToPixels(request.pointSize))
+ , m_scaledFont(0)
+ , m_scaledFontSizeInPixels(0)
+ , m_activeFont(0)
{
QFontEngine::fontDef = request;
- m_fontSizeInPixels = (request.pixelSize >= 0)?
- request.pixelSize:pointsToPixels(request.pointSize);
-
- TFontSpec fontSpec(qt_QString2TPtrC(request.family), m_fontSizeInPixels);
- fontSpec.iFontStyle.SetBitmapType(EAntiAliasedGlyphBitmap);
- fontSpec.iFontStyle.SetPosture(request.style == QFont::StyleNormal?EPostureUpright:EPostureItalic);
- fontSpec.iFontStyle.SetStrokeWeight(request.weight > QFont::Normal?EStrokeWeightBold:EStrokeWeightNormal);
- const TInt errorCode = S60->screenDevice()->GetNearestFontToDesignHeightInPixels(m_font, fontSpec);
- Q_ASSERT(errorCode == 0);
-
+ setFontScale(1.0);
cache_cost = sizeof(QFontEngineS60);
}
QFontEngineS60::~QFontEngineS60()
{
- S60->screenDevice()->ReleaseFont(m_font);
+ releaseFont(m_originalFont);
+ releaseFont(m_scaledFont);
}
bool QFontEngineS60::stringToCMap(const QChar *characters, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
@@ -251,12 +287,12 @@ glyph_metrics_t QFontEngineS60::boundingBox(glyph_t glyph)
QFixed QFontEngineS60::ascent() const
{
- return m_font->FontMaxAscent();
+ return m_originalFont->FontMaxAscent();
}
QFixed QFontEngineS60::descent() const
{
- return m_font->FontMaxDescent();
+ return m_originalFont->FontMaxDescent();
}
QFixed QFontEngineS60::leading() const
@@ -266,7 +302,7 @@ QFixed QFontEngineS60::leading() const
qreal QFontEngineS60::maxCharWidth() const
{
- return m_font->MaxCharWidthInPixels();
+ return m_originalFont->MaxCharWidthInPixels();
}
const char *QFontEngineS60::name() const
@@ -302,11 +338,11 @@ void QFontEngineS60::getCharacterData(glyph_t glyph, TOpenFontCharMetrics& metri
const TUint specialCode = (TUint)glyph | 0x80000000;
const CFont::TCharacterDataAvailability availability =
- m_font->GetCharacterData(specialCode, metrics, bitmap, bitmapSize);
+ m_activeFont->GetCharacterData(specialCode, metrics, bitmap, bitmapSize);
const glyph_t fallbackGlyph = '?';
if (availability != CFont::EAllCharacterData) {
const CFont::TCharacterDataAvailability fallbackAvailability =
- m_font->GetCharacterData(fallbackGlyph, metrics, bitmap, bitmapSize);
+ m_activeFont->GetCharacterData(fallbackGlyph, metrics, bitmap, bitmapSize);
Q_ASSERT(fallbackAvailability == CFont::EAllCharacterData);
}
}
diff --git a/src/gui/text/qfontengine_s60_p.h b/src/gui/text/qfontengine_s60_p.h
index ff819e2..78f8a9a 100644
--- a/src/gui/text/qfontengine_s60_p.h
+++ b/src/gui/text/qfontengine_s60_p.h
@@ -58,9 +58,6 @@
#include "qsize.h"
#include <OPENFONT.H>
-class CFbsBitmap;
-class CFbsBitmapDevice;
-class CFbsBitGc;
class CFont;
QT_BEGIN_NAMESPACE
@@ -120,15 +117,21 @@ public:
Type type() const;
void getCharacterData(glyph_t glyph, TOpenFontCharMetrics& metrics, const TUint8*& bitmap, TSize& bitmapSize) const;
+ void setFontScale(qreal scale);
private:
friend class QFontPrivate;
QFixed glyphAdvance(HB_Glyph glyph) const;
+ CFont *fontWithSize(qreal size) const;
+ static void releaseFont(CFont *&font);
- CFont* m_font;
const QFontEngineS60Extensions *m_extensions;
- qreal m_fontSizeInPixels;
+ CFont* m_originalFont;
+ const qreal m_originalFontSizeInPixels;
+ CFont* m_scaledFont;
+ qreal m_scaledFontSizeInPixels;
+ CFont* m_activeFont;
};
class QFontEngineMultiS60 : public QFontEngineMulti
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 26c7c1e..af91603 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -1331,7 +1331,7 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition
QTextLine l(line, d);
const QScriptLine &sl = d->lines[line];
- const qreal x = position.x() + l.cursorToX(cursorPosition);
+ qreal x = position.x() + l.cursorToX(cursorPosition);
int itm = d->findItem(cursorPosition - 1);
QFixed base = sl.base();
@@ -1350,6 +1350,10 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition
&& (p->transform().type() > QTransform::TxTranslate);
if (toggleAntialiasing)
p->setRenderHint(QPainter::Antialiasing);
+#if defined(QT_MAC_USE_COCOA)
+ // Always draw the cursor aligned to pixel boundary.
+ x = qRound(x);
+#endif
p->fillRect(QRectF(x, y, qreal(width), (base + descent + 1).toReal()), p->pen().brush());
if (toggleAntialiasing)
p->setRenderHint(QPainter::Antialiasing, false);
diff --git a/src/gui/text/qzip.cpp b/src/gui/text/qzip.cpp
index 2fc1940..d30c996 100644
--- a/src/gui/text/qzip.cpp
+++ b/src/gui/text/qzip.cpp
@@ -54,10 +54,13 @@
#include <zlib.h>
#if defined(Q_OS_WIN)
-#undef S_IFREG
-#define S_IFREG 0100000
+# undef S_IFREG
+# define S_IFREG 0100000
+# ifndef S_IFDIR
+# define S_IFDIR 0040000
+# endif
# ifndef S_ISDIR
-# define S_ISDIR(x) ((x) & 0040000) > 0
+# define S_ISDIR(x) ((x) & S_IFDIR) > 0
# endif
# ifndef S_ISREG
# define S_ISREG(x) ((x) & 0170000) == S_IFREG
diff --git a/src/gui/text/qzipreader_p.h b/src/gui/text/qzipreader_p.h
index 1086464..67a2ace 100644
--- a/src/gui/text/qzipreader_p.h
+++ b/src/gui/text/qzipreader_p.h
@@ -49,7 +49,7 @@
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
-// of the QLibrary class. This header file may change from
+// of the QZipReader class. This header file may change from
// version to version without notice, or even be removed.
//
// We mean it.
diff --git a/src/gui/text/qzipwriter_p.h b/src/gui/text/qzipwriter_p.h
index 7b97937..9322f4a 100644
--- a/src/gui/text/qzipwriter_p.h
+++ b/src/gui/text/qzipwriter_p.h
@@ -47,7 +47,7 @@
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
-// of the QLibrary class. This header file may change from
+// of the QZipWriter class. This header file may change from
// version to version without notice, or even be removed.
//
// We mean it.
diff --git a/src/gui/util/qsystemtrayicon_p.h b/src/gui/util/qsystemtrayicon_p.h
index b881f68..e8bf197 100644
--- a/src/gui/util/qsystemtrayicon_p.h
+++ b/src/gui/util/qsystemtrayicon_p.h
@@ -164,7 +164,9 @@ protected:
bool x11Event(XEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
+#ifndef QT_NO_WHEELEVENT
void wheelEvent(QWheelEvent *event);
+#endif
bool event(QEvent *e);
private:
diff --git a/src/gui/util/qsystemtrayicon_x11.cpp b/src/gui/util/qsystemtrayicon_x11.cpp
index a645050..82b4325 100644
--- a/src/gui/util/qsystemtrayicon_x11.cpp
+++ b/src/gui/util/qsystemtrayicon_x11.cpp
@@ -308,10 +308,12 @@ void QSystemTrayIconSys::mouseDoubleClickEvent(QMouseEvent *ev)
emit q->activated(QSystemTrayIcon::DoubleClick);
}
+#ifndef QT_NO_WHEELEVENT
void QSystemTrayIconSys::wheelEvent(QWheelEvent *e)
{
QApplication::sendEvent(q, e);
}
+#endif
bool QSystemTrayIconSys::event(QEvent *e)
{
diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp
index 87f6c83..1d496d5 100644
--- a/src/gui/widgets/qabstractscrollarea.cpp
+++ b/src/gui/widgets/qabstractscrollarea.cpp
@@ -1134,13 +1134,10 @@ void QAbstractScrollArea::mouseMoveEvent(QMouseEvent *e)
void QAbstractScrollArea::wheelEvent(QWheelEvent *e)
{
Q_D(QAbstractScrollArea);
- QScrollBar *const bars[2] = { d->hbar, d->vbar };
- int idx = (e->orientation() == Qt::Vertical) ? 1 : 0;
- int other = (idx + 1) % 2;
- if (!bars[idx]->isVisible() && bars[other]->isVisible())
- idx = other; // If the scrollbar of the event orientation is hidden, fallback to the other.
-
- QApplication::sendEvent(bars[idx], e);
+ if (static_cast<QWheelEvent*>(e)->orientation() == Qt::Horizontal)
+ QApplication::sendEvent(d->hbar, e);
+ else
+ QApplication::sendEvent(d->vbar, e);
}
#endif
diff --git a/src/gui/widgets/qabstractslider.cpp b/src/gui/widgets/qabstractslider.cpp
index 2874647..4bd7b5a 100644
--- a/src/gui/widgets/qabstractslider.cpp
+++ b/src/gui/widgets/qabstractslider.cpp
@@ -214,8 +214,8 @@ QT_BEGIN_NAMESPACE
*/
QAbstractSliderPrivate::QAbstractSliderPrivate()
- : minimum(0), maximum(99), singleStep(1), pageStep(10),
- value(0), position(0), pressValue(-1), offset_accumulated(0), tracking(true),
+ : minimum(0), maximum(99), pageStep(10), value(0), position(0), pressValue(-1),
+ singleStep(1), offset_accumulated(0), tracking(true),
blocktracking(false), pressed(false),
invertedAppearance(false), invertedControls(false),
orientation(Qt::Horizontal), repeatAction(QAbstractSlider::SliderNoAction)
@@ -688,51 +688,66 @@ void QAbstractSlider::sliderChange(SliderChange)
update();
}
-
-/*!
- \reimp
-*/
-#ifndef QT_NO_WHEELEVENT
-void QAbstractSlider::wheelEvent(QWheelEvent * e)
+bool QAbstractSliderPrivate::scrollByDelta(Qt::Orientation orientation, Qt::KeyboardModifiers modifiers, int delta)
{
- Q_D(QAbstractSlider);
- e->ignore();
-
+ Q_Q(QAbstractSlider);
int stepsToScroll = 0;
- qreal offset = qreal(e->delta()) / 120;
+ // in Qt scrolling to the right gives negative values.
+ if (orientation == Qt::Horizontal)
+ delta = -delta;
+ qreal offset = qreal(delta) / 120;
- if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier)) {
+ if ((modifiers & Qt::ControlModifier) || (modifiers & Qt::ShiftModifier)) {
// Scroll one page regardless of delta:
- stepsToScroll = qBound(-d->pageStep, int(offset * d->pageStep), d->pageStep);
- d->offset_accumulated = 0;
+ stepsToScroll = qBound(-pageStep, int(offset * pageStep), pageStep);
+ offset_accumulated = 0;
} else {
// Calculate how many lines to scroll. Depending on what delta is (and
// offset), we might end up with a fraction (e.g. scroll 1.3 lines). We can
// only scroll whole lines, so we keep the reminder until next event.
- qreal stepsToScrollF = offset * QApplication::wheelScrollLines() * d->effectiveSingleStep();
+ qreal stepsToScrollF =
+#ifndef QT_NO_WHEELEVENT
+ QApplication::wheelScrollLines() *
+#endif
+ offset * effectiveSingleStep();
// Check if wheel changed direction since last event:
- if (d->offset_accumulated != 0 && (offset / d->offset_accumulated) < 0)
- d->offset_accumulated = 0;
+ if (offset_accumulated != 0 && (offset / offset_accumulated) < 0)
+ offset_accumulated = 0;
- d->offset_accumulated += stepsToScrollF;
- stepsToScroll = qBound(-d->pageStep, int(d->offset_accumulated), d->pageStep);
- d->offset_accumulated -= int(d->offset_accumulated);
+ offset_accumulated += stepsToScrollF;
+ stepsToScroll = qBound(-pageStep, int(offset_accumulated), pageStep);
+ offset_accumulated -= int(offset_accumulated);
if (stepsToScroll == 0)
- return;
+ return false;
}
- if (d->invertedControls)
+ if (invertedControls)
stepsToScroll = -stepsToScroll;
- int prevValue = d->value;
- d->position = d->overflowSafeAdd(stepsToScroll); // value will be updated by triggerAction()
- triggerAction(SliderMove);
+ int prevValue = value;
+ position = overflowSafeAdd(stepsToScroll); // value will be updated by triggerAction()
+ q->triggerAction(QAbstractSlider::SliderMove);
- if (prevValue == d->value)
- d->offset_accumulated = 0;
- else
+ if (prevValue == value) {
+ offset_accumulated = 0;
+ return false;
+ }
+ return true;
+}
+
+/*!
+ \reimp
+*/
+#ifndef QT_NO_WHEELEVENT
+void QAbstractSlider::wheelEvent(QWheelEvent * e)
+{
+ Q_D(QAbstractSlider);
+ e->ignore();
+ int delta = e->delta();
+ if (d->scrollByDelta(e->orientation(), e->modifiers(), delta))
e->accept();
}
+
#endif
#ifdef QT_KEYPAD_NAVIGATION
/*!
diff --git a/src/gui/widgets/qabstractslider_p.h b/src/gui/widgets/qabstractslider_p.h
index 6cde468..6e6ff6e 100644
--- a/src/gui/widgets/qabstractslider_p.h
+++ b/src/gui/widgets/qabstractslider_p.h
@@ -138,6 +138,7 @@ public:
}
q->triggerAction(repeatAction);
}
+ bool scrollByDelta(Qt::Orientation orientation, Qt::KeyboardModifiers modifiers, int delta);
};
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qabstractspinbox.h b/src/gui/widgets/qabstractspinbox.h
index 059943a..6c062c0 100644
--- a/src/gui/widgets/qabstractspinbox.h
+++ b/src/gui/widgets/qabstractspinbox.h
@@ -137,7 +137,9 @@ protected:
void resizeEvent(QResizeEvent *event);
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
+#ifndef QT_NO_WHEELEVENT
void wheelEvent(QWheelEvent *event);
+#endif
void focusInEvent(QFocusEvent *event);
void focusOutEvent(QFocusEvent *event);
void contextMenuEvent(QContextMenuEvent *event);
diff --git a/src/gui/widgets/qcombobox.h b/src/gui/widgets/qcombobox.h
index f332d31..9b19a66 100644
--- a/src/gui/widgets/qcombobox.h
+++ b/src/gui/widgets/qcombobox.h
@@ -245,7 +245,9 @@ protected:
void mouseReleaseEvent(QMouseEvent *e);
void keyPressEvent(QKeyEvent *e);
void keyReleaseEvent(QKeyEvent *e);
+#ifndef QT_NO_WHEELEVENT
void wheelEvent(QWheelEvent *e);
+#endif
void contextMenuEvent(QContextMenuEvent *e);
void inputMethodEvent(QInputMethodEvent *);
QVariant inputMethodQuery(Qt::InputMethodQuery) const;
diff --git a/src/gui/widgets/qdialogbuttonbox.cpp b/src/gui/widgets/qdialogbuttonbox.cpp
index 48d7022..6a0e363 100644
--- a/src/gui/widgets/qdialogbuttonbox.cpp
+++ b/src/gui/widgets/qdialogbuttonbox.cpp
@@ -1017,6 +1017,8 @@ void QDialogButtonBox::removeButton(QAbstractButton *button)
If the button has already been added, it is removed and added again with the
new role.
+ \note The button box takes ownership of the button.
+
\sa removeButton(), clear()
*/
void QDialogButtonBox::addButton(QAbstractButton *button, ButtonRole role)
diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp
index b0a64ea..db099e8 100644
--- a/src/gui/widgets/qlinecontrol.cpp
+++ b/src/gui/widgets/qlinecontrol.cpp
@@ -1371,6 +1371,8 @@ bool QLineControl::processEvent(QEvent* ev)
processInputMethodEvent(static_cast<QInputMethodEvent*>(ev)); break;
#ifndef QT_NO_SHORTCUT
case QEvent::ShortcutOverride:{
+ if (isReadOnly())
+ return false;
QKeyEvent* ke = static_cast<QKeyEvent*>(ev);
if (ke == QKeySequence::Copy
|| ke == QKeySequence::Paste
diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp
index 1622191..269cd12 100644
--- a/src/gui/widgets/qmainwindow.cpp
+++ b/src/gui/widgets/qmainwindow.cpp
@@ -119,8 +119,6 @@ void QMainWindowPrivate::init()
q->setAttribute(Qt::WA_Hover);
#ifdef QT_SOFTKEYS_ENABLED
menuBarAction = QSoftKeyManager::createAction(QSoftKeyManager::MenuSoftKey, q);
- menuBarAction->setObjectName(QLatin1String("_q_menuSoftKeyAction"));
- menuBarAction->setVisible(false);
#endif
}
diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp
index d1e7285..fc75c92 100644
--- a/src/gui/widgets/qmainwindowlayout.cpp
+++ b/src/gui/widgets/qmainwindowlayout.cpp
@@ -1627,6 +1627,13 @@ void QMainWindowLayout::animationFinished(QWidget *widget)
tb->d_func()->plug(currentGapRect);
#endif
+ savedState.clear();
+ currentGapPos.clear();
+ pluggingWidget = 0;
+ //applying the state will make sure that the currentGap is updated correctly
+ //and all the geometries (especially the one from the central widget) is correct
+ layoutState.apply(false);
+
#ifndef QT_NO_DOCKWIDGET
#ifndef QT_NO_TABBAR
if (qobject_cast<QDockWidget*>(widget) != 0) {
@@ -1637,13 +1644,6 @@ void QMainWindowLayout::animationFinished(QWidget *widget)
}
#endif
#endif
-
- savedState.clear();
- currentGapPos.clear();
- pluggingWidget = 0;
- //applying the state will make sure that the currentGap is updated correctly
- //and all the geometries (especially the one from the central widget) is correct
- layoutState.apply(false);
}
if (!widgetAnimator.animating()) {
diff --git a/src/gui/widgets/qmenu.h b/src/gui/widgets/qmenu.h
index 5a6a5c7..47dff2b 100644
--- a/src/gui/widgets/qmenu.h
+++ b/src/gui/widgets/qmenu.h
@@ -162,7 +162,9 @@ protected:
void mouseReleaseEvent(QMouseEvent *);
void mousePressEvent(QMouseEvent *);
void mouseMoveEvent(QMouseEvent *);
+#ifndef QT_NO_WHEELEVENT
void wheelEvent(QWheelEvent *);
+#endif
void enterEvent(QEvent *);
void leaveEvent(QEvent *);
void hideEvent(QHideEvent *);
diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h
index b7272f7..aaed6b1 100644
--- a/src/gui/widgets/qmenu_p.h
+++ b/src/gui/widgets/qmenu_p.h
@@ -71,6 +71,7 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_MENU
#ifdef Q_WS_S60
+void qt_symbian_next_menu_from_action(QWidget* actionContainer);
void qt_symbian_show_toplevel(CEikMenuPane* menuPane);
void qt_symbian_show_submenu(CEikMenuPane* menuPane, int id);
#endif // Q_WS_S60
@@ -87,7 +88,7 @@ QT_BEGIN_NAMESPACE
typedef void NSMenuItem;
# endif //__OBJC__
struct QMacMenuAction {
- QMacMenuAction()
+ QMacMenuAction()
#ifndef QT_MAC_USE_COCOA
: command(0)
#else
@@ -124,7 +125,7 @@ typedef QList<QMenuMergeItem> QMenuMergeList;
#ifdef Q_WS_WINCE
struct QWceMenuAction {
- uint command;
+ uint command;
QPointer<QAction> action;
HMENU menuHandle;
QWceMenuAction() : menuHandle(0), command(0) {}
@@ -340,7 +341,7 @@ public:
QList<QWceMenuAction*> actionItems;
HMENU menuHandle;
QWceMenuPrivate();
- ~QWceMenuPrivate();
+ ~QWceMenuPrivate();
void addAction(QAction *, QWceMenuAction* =0);
void addAction(QWceMenuAction *, QWceMenuAction* =0);
void syncAction(QWceMenuAction *);
diff --git a/src/gui/widgets/qmenu_symbian.cpp b/src/gui/widgets/qmenu_symbian.cpp
index 28b27d4..eae97a6 100644
--- a/src/gui/widgets/qmenu_symbian.cpp
+++ b/src/gui/widgets/qmenu_symbian.cpp
@@ -81,6 +81,7 @@ static QList<QMenuBar*> nativeMenuBars;
static uint qt_symbian_menu_static_cmd_id = QT_SYMBIAN_FIRST_MENU_ITEM;
static QPointer<QWidget> widgetWithContextMenu;
static QList<QAction*> contextMenuActionList;
+static QWidget* actionMenu = NULL;
static int contexMenuCommand=0;
bool menuExists()
@@ -224,8 +225,26 @@ static void rebuildMenu()
}
#ifdef Q_WS_S60
+void qt_symbian_next_menu_from_action(QWidget *actionContainer)
+{
+ actionMenu = actionContainer;
+}
+
void qt_symbian_show_toplevel( CEikMenuPane* menuPane)
{
+ if (actionMenu) {
+ QMenuBarPrivate *mb = 0;
+ mb = menubars()->value(actionMenu);
+ qt_symbian_menu_static_cmd_id = QT_SYMBIAN_FIRST_MENU_ITEM;
+ deleteAll( &symbianMenus );
+ Q_ASSERT(mb);
+ mb->symbian_menubar->rebuild();
+ for (int i = 0; i < symbianMenus.count(); ++i)
+ QT_TRAP_THROWING(menuPane->AddMenuItemL(symbianMenus.at(i)->menuItemData));
+ actionMenu = NULL;
+ return;
+ }
+
if (!menuExists())
return;
rebuildMenu();
@@ -271,10 +290,16 @@ int QMenuBarPrivate::symbianCommands(int command)
void QMenuBarPrivate::symbianCreateMenuBar(QWidget *parent)
{
Q_Q(QMenuBar);
- if (parent && parent->isWindow()){
- menubars()->insert(q->window(), this);
- symbian_menubar = new QSymbianMenuBarPrivate(this);
- nativeMenuBars.append(q);
+ if (parent) {
+ if(parent->isWindow()) {
+ menubars()->insert(q->window(), this);
+ symbian_menubar = new QSymbianMenuBarPrivate(this);
+ nativeMenuBars.append(q);
+ } else {
+ menubars()->insert(q->parentWidget(), this);
+ symbian_menubar = new QSymbianMenuBarPrivate(this);
+ nativeMenuBars.append(q);
+ }
}
}
@@ -284,6 +309,7 @@ void QMenuBarPrivate::symbianDestroyMenuBar()
int index = nativeMenuBars.indexOf(q);
nativeMenuBars.removeAt(index);
menubars()->remove(q->window(), this);
+ menubars()->remove(q->parentWidget(), this);
rebuildMenu();
if (symbian_menubar)
delete symbian_menubar;
diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp
index 0e14385..9caadb7 100644
--- a/src/gui/widgets/qmenubar.cpp
+++ b/src/gui/widgets/qmenubar.cpp
@@ -667,7 +667,7 @@ void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *acti
\i Application Menu | About <application name>
\i The application name is fetched from the \c {Info.plist} file
(see note below). If this entry is not found no About item
- will appear in the Application Menu.
+ will appear in the Application Menu.
\row \i config, options, setup, settings or preferences
\i Application Menu | Preferences
\i If this entry is not found the Settings item will be disabled
diff --git a/src/gui/widgets/qprintpreviewwidget.cpp b/src/gui/widgets/qprintpreviewwidget.cpp
index 747a227..45b15ef 100644
--- a/src/gui/widgets/qprintpreviewwidget.cpp
+++ b/src/gui/widgets/qprintpreviewwidget.cpp
@@ -151,7 +151,11 @@ class GraphicsView : public QGraphicsView
public:
GraphicsView(QWidget* parent = 0)
: QGraphicsView(parent)
- {}
+ {
+#ifdef Q_WS_MAC
+ setFrameStyle(QFrame::NoFrame);
+#endif
+ }
signals:
void resized();
diff --git a/src/gui/widgets/qscrollbar.cpp b/src/gui/widgets/qscrollbar.cpp
index 73ce122..4eff260 100644
--- a/src/gui/widgets/qscrollbar.cpp
+++ b/src/gui/widgets/qscrollbar.cpp
@@ -521,6 +521,24 @@ bool QScrollBar::event(QEvent *event)
if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event))
d_func()->updateHoverControl(he->pos());
break;
+#ifndef QT_NO_WHEELEVENT
+ case QEvent::Wheel: {
+ // override wheel event without adding virtual function override
+ QWheelEvent *ev = static_cast<QWheelEvent *>(event);
+ int delta = ev->delta();
+ // scrollbar is a special case - in vertical mode it reaches minimum
+ // value in the upper position, however QSlider's minimum value is on
+ // the bottom. So we need to invert a value, but since the scrollbar is
+ // inverted by default, we need to inverse the delta value for the
+ // horizontal orientation.
+ if (ev->orientation() == Qt::Horizontal)
+ delta = -delta;
+ Q_D(QScrollBar);
+ if (d->scrollByDelta(ev->orientation(), ev->modifiers(), delta))
+ event->accept();
+ return true;
+ }
+#endif
default:
break;
}
diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp
index 53050ac..8beda55 100644
--- a/src/gui/widgets/qtoolbar.cpp
+++ b/src/gui/widgets/qtoolbar.cpp
@@ -441,8 +441,7 @@ void QToolBarPrivate::plug(const QRect &r)
When a QToolBar is not a child of a QMainWindow, it looses the ability
to populate the extension pop up with widgets added to the toolbar using
addWidget(). Please use widget actions created by inheriting QWidgetAction
- and implementing QWidgetAction::createWidget() instead. This is a known
- issue which will be fixed in a future release.
+ and implementing QWidgetAction::createWidget() instead.
\sa QToolButton, QMenu, QAction, {Application Example}
*/