summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorKurt Korbatits <kurt.korbatits@nokia.com>2010-02-07 23:53:17 (GMT)
committerKurt Korbatits <kurt.korbatits@nokia.com>2010-02-07 23:53:17 (GMT)
commitac33de5bf257eb215a09c232d950be265d57d22f (patch)
tree3947891872c1a41deaa32e8995e2e233548b3352 /src/gui
parent3108f02f35685bd57486e198277c600e09d98b13 (diff)
parent8ca95cbc98a97a8208120e4aa76bfd5c16b01df9 (diff)
downloadQt-ac33de5bf257eb215a09c232d950be265d57d22f.zip
Qt-ac33de5bf257eb215a09c232d950be265d57d22f.tar.gz
Qt-ac33de5bf257eb215a09c232d950be265d57d22f.tar.bz2
Merge branch '4.6' of scm.dev.nokia.troll.no:qt/qt-multimedia-team into 4.6
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/gui.pro3
-rw-r--r--src/gui/itemviews/qitemdelegate.cpp2
-rw-r--r--src/gui/kernel/kernel.pri53
-rw-r--r--src/gui/kernel/qapplication_s60.cpp3
-rw-r--r--src/gui/kernel/qclipboard_s60.cpp3
-rw-r--r--src/gui/kernel/qdesktopwidget_s60.cpp18
-rw-r--r--src/gui/kernel/qdnd_x11.cpp2
-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.cpp407
-rw-r--r--src/gui/kernel/qsoftkeymanager_s60_p.h111
-rw-r--r--src/gui/kernel/qt_s60_p.h6
-rw-r--r--src/gui/kernel/qwidget_s60.cpp4
-rw-r--r--src/gui/styles/qcommonstyle.cpp2
-rw-r--r--src/gui/styles/qmacstyle_mac.mm21
-rw-r--r--src/gui/styles/qs60style.cpp15
-rw-r--r--src/gui/widgets/qmainwindow.cpp2
-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
23 files changed, 805 insertions, 213 deletions
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/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/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/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 6caac9f..6e03d7c 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -1647,6 +1647,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/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/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/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..a72d16c
--- /dev/null
+++ b/src/gui/kernel/qsoftkeymanager_s60.cpp
@@ -0,0 +1,407 @@
+/****************************************************************************
+**
+** 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);
+ QBitmap softkeyMask = softkeyPixmap.mask();
+ if (softkeyMask.isNull()) {
+ softkeyMask = QBitmap(softkeyPixmap.size());
+ softkeyMask.fill(Qt::color1);
+ }
+
+ // Softkey mask in > SV_S60_5_1 has to be inverted
+ if(QSysInfo::s60Version() > QSysInfo::SV_S60_5_1) {
+ QImage maskImage = softkeyMask.toImage();
+ maskImage.invertPixels();
+ softkeyMask = QPixmap::fromImage(maskImage);
+ }
+
+ CFbsBitmap* nBitmap = softkeyPixmap.toSymbianCFbsBitmap();
+ CFbsBitmap* nMask = softkeyMask.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_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_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index 00f2213..0ce7534 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -1195,6 +1195,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/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp
index 739a70b..74d3ec3 100644
--- a/src/gui/styles/qcommonstyle.cpp
+++ b/src/gui/styles/qcommonstyle.cpp
@@ -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 7a680f2..aab16cb 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);
@@ -5715,12 +5720,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 fc435e8..9025e5b 100644
--- a/src/gui/styles/qs60style.cpp
+++ b/src/gui/styles/qs60style.cpp
@@ -2399,13 +2399,14 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
sz.setHeight(sz.height() + 2 * pixelMetric(PM_FocusFrameVMargin));
break;
#ifndef QT_NO_COMBOBOX
- 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);
+ 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:
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/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();