summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarkku Luukkainen <markku.luukkainen@digia.com>2009-06-10 10:57:54 (GMT)
committerMarkku Luukkainen <markku.luukkainen@digia.com>2009-06-10 10:57:54 (GMT)
commit1c97ec260bd398912d64b0328299d50207962ad4 (patch)
tree138228023b086a943828b0ef6b16a1c1cde8d8fb /src
parent47746f46920e4d09d4524fc2466b25626b2454bf (diff)
parent9009dce133b015cd2c7060d1f4747f3733dcf546 (diff)
downloadQt-1c97ec260bd398912d64b0328299d50207962ad4.zip
Qt-1c97ec260bd398912d64b0328299d50207962ad4.tar.gz
Qt-1c97ec260bd398912d64b0328299d50207962ad4.tar.bz2
Merge branch 'softkeys_without_stack'
Diffstat (limited to 'src')
-rw-r--r--src/gui/itemviews/qabstractitemview.cpp9
-rw-r--r--src/gui/kernel/qaction.cpp26
-rw-r--r--src/gui/kernel/qaction.h10
-rw-r--r--src/gui/kernel/qaction_p.h1
-rw-r--r--src/gui/kernel/qapplication_s60.cpp14
-rw-r--r--src/gui/kernel/qwidget.cpp66
-rw-r--r--src/gui/kernel/qwidget.h3
-rw-r--r--src/gui/kernel/qwidget_p.h5
-rw-r--r--src/gui/kernel/qwidget_s60.cpp53
-rw-r--r--src/gui/widgets/qactiontokeyeventmapper.cpp103
-rw-r--r--src/gui/widgets/qactiontokeyeventmapper_p.h70
-rw-r--r--src/gui/widgets/qcombobox.cpp8
-rw-r--r--src/gui/widgets/qmainwindow.cpp5
-rw-r--r--src/gui/widgets/qmenu.cpp14
-rw-r--r--src/gui/widgets/qmenu_symbian.cpp79
-rw-r--r--src/gui/widgets/qmenubar_p.h1
-rw-r--r--src/gui/widgets/widgets.pri8
-rw-r--r--src/s60main/qts60mainappui.cpp3
18 files changed, 433 insertions, 45 deletions
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp
index 159a997..af84ea6 100644
--- a/src/gui/itemviews/qabstractitemview.cpp
+++ b/src/gui/itemviews/qabstractitemview.cpp
@@ -61,6 +61,7 @@
#ifndef QT_NO_ACCESSIBILITY
#include <qaccessible.h>
#endif
+#include <qactiontokeyeventmapper_p.h>
QT_BEGIN_NAMESPACE
@@ -2003,16 +2004,18 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event)
if (QApplication::keypadNavigationEnabled()) {
if (!hasEditFocus()) {
setEditFocus(true);
+ QActionToKeyEventMapper::addSoftKey(QAction::BackSoftKey, Qt::Key_Back, this);
return;
}
}
break;
case Qt::Key_Back:
- case Qt::Key_Context2: // TODO: aportale, remove KEYPAD_NAVIGATION_HACK when softkey support is there
- if (QApplication::keypadNavigationEnabled() && hasEditFocus())
+ if (QApplication::keypadNavigationEnabled() && hasEditFocus()) {
+ QActionToKeyEventMapper::removeSoftkey(this);
setEditFocus(false);
- else
+ } else {
event->ignore();
+ }
return;
default:
if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {
diff --git a/src/gui/kernel/qaction.cpp b/src/gui/kernel/qaction.cpp
index abb17d7..8263cbc 100644
--- a/src/gui/kernel/qaction.cpp
+++ b/src/gui/kernel/qaction.cpp
@@ -1348,6 +1348,32 @@ QAction::MenuRole QAction::menuRole() const
}
/*!
+ \property QAction::softKeyRole
+ \brief the action's softkey role
+ \since 4.6
+
+ This indicates what softkey action this action is. Usually used on mobile
+ platforms to map QActions to hardware keys.
+
+ The softkey role can be changed any time.
+*/
+void QAction::setSoftKeyRole(SoftKeyRole softKeyRole)
+{
+ Q_D(QAction);
+ if (d->softKeyRole == softKeyRole)
+ return;
+
+ d->softKeyRole = softKeyRole;
+ d->sendDataChanged();
+}
+
+QAction::SoftKeyRole QAction::softKeyRole() const
+{
+ Q_D(const QAction);
+ return d->softKeyRole;
+}
+
+/*!
\property QAction::iconVisibleInMenu
\brief Whether or not an action should show an icon in a menu
\since 4.4
diff --git a/src/gui/kernel/qaction.h b/src/gui/kernel/qaction.h
index d7bf8c3..8791a5c 100644
--- a/src/gui/kernel/qaction.h
+++ b/src/gui/kernel/qaction.h
@@ -67,6 +67,7 @@ class Q_GUI_EXPORT QAction : public QObject
Q_DECLARE_PRIVATE(QAction)
Q_ENUMS(MenuRole)
+ Q_ENUMS(SoftKeyRole)
Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable)
Q_PROPERTY(bool checked READ isChecked WRITE setChecked DESIGNABLE isCheckable NOTIFY toggled)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
@@ -84,11 +85,17 @@ class Q_GUI_EXPORT QAction : public QObject
#endif
Q_PROPERTY(bool visible READ isVisible WRITE setVisible)
Q_PROPERTY(MenuRole menuRole READ menuRole WRITE setMenuRole)
+ Q_PROPERTY(SoftKeyRole softKeyRole READ softKeyRole WRITE setSoftKeyRole)
Q_PROPERTY(bool iconVisibleInMenu READ isIconVisibleInMenu WRITE setIconVisibleInMenu)
public:
enum MenuRole { NoRole, TextHeuristicRole, ApplicationSpecificRole, AboutQtRole,
AboutRole, PreferencesRole, QuitRole };
+ enum SoftKeyRole { OptionsSoftKey, SelectSoftKey, BackSoftKey, NextSoftKey, PreviousSoftKey,
+ OkSoftKey, CancelSoftKey, EditSoftKey, ViewSoftKey, BackSpaceSoftKey,
+ EndEditSoftKey, RevertEditSoftKey, DeselectSoftKey, FinishSoftKey,
+ MenuSoftKey, ContextMenuSoftKey, Key1SoftKey, Key2SoftKey,
+ Key3SoftKey, Key4SoftKey, CustomSoftKey };
explicit QAction(QObject* parent);
QAction(const QString &text, QObject* parent);
QAction(const QIcon &icon, const QString &text, QObject* parent);
@@ -168,6 +175,9 @@ public:
void setMenuRole(MenuRole menuRole);
MenuRole menuRole() const;
+ void setSoftKeyRole(SoftKeyRole softKeyRole);
+ SoftKeyRole softKeyRole() const;
+
void setIconVisibleInMenu(bool visible);
bool isIconVisibleInMenu() const;
diff --git a/src/gui/kernel/qaction_p.h b/src/gui/kernel/qaction_p.h
index 0617ef5..6051d9a 100644
--- a/src/gui/kernel/qaction_p.h
+++ b/src/gui/kernel/qaction_p.h
@@ -102,6 +102,7 @@ public:
uint separator : 1;
uint fontSet : 1;
QAction::MenuRole menuRole;
+ QAction::SoftKeyRole softKeyRole;
int iconVisibleInMenu : 3; // Only has values -1, 0, and 1
QList<QWidget *> widgets;
#ifndef QT_NO_GRAPHICSVIEW
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 2f7bdcf..0ae4c00 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -1059,13 +1059,19 @@ void QApplication::symbianHandleCommand(int command)
{
switch (command) {
case EEikCmdExit:
- case EAknSoftkeyBack:
case EAknSoftkeyExit:
- qApp->exit();
+ exit();
break;
default:
- // For now assume all unknown menu items are Qt menu items
- QMenuBarPrivate::symbianCommands(command);
+ if (command >= SOFTKEYSTART && command <= SOFTKEYEND) {
+ int index= command-SOFTKEYSTART;
+ QWidget* focused = QApplication::focusWidget();
+ const QList<QAction*>& softKeys = focused->softKeys();
+ Q_ASSERT(index<softKeys.count());
+ softKeys.at(index)->activate(QAction::Trigger);
+ }
+ else
+ QMenuBarPrivate::symbianCommands(command);
break;
}
}
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index b376f20..eaa9491 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -4880,6 +4880,13 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
d->extra->inRenderWithPainter = false;
}
+#if !defined(Q_WS_S60)
+void QWidgetPrivate::setSoftKeys_sys(const QList<QAction*> &softkeys)
+{
+ Q_UNUSED(softkeys)
+}
+#endif // !defined(Q_WS_S60)
+
bool QWidgetPrivate::isAboutToShow() const
{
if (data.in_show)
@@ -5715,9 +5722,12 @@ bool QWidget::hasFocus() const
void QWidget::setFocus(Qt::FocusReason reason)
{
+ Q_D(QWidget);
+ d->setSoftKeys_sys(softKeys());
+
if (!isEnabled())
return;
-
+
QWidget *f = this;
while (f->d_func()->extra && f->d_func()->extra->focus_proxy)
f = f->d_func()->extra->focus_proxy;
@@ -11510,6 +11520,60 @@ void QWidget::clearMask()
setMask(QRegion());
}
+/*!
+ Returns the (possibly empty) list of this widget's softkeys.
+ Returned list cannot be changed. Softkeys should be added
+ and removed via method called setSoftKeys
+
+ \sa setSoftKey(), setSoftKeys()
+*/
+const QList<QAction*>& QWidget::softKeys() const
+{
+ Q_D(const QWidget);
+ if( d->softKeys.count() > 0)
+ return d->softKeys;
+ if (isWindow() || !parentWidget())
+ return d->softKeys;
+
+ return parentWidget()->softKeys();
+}
+
+/*!
+ Sets the softkey \a softkey to this widget's list of softkeys,
+ Setting 0 as softkey will clear all the existing softkeys set
+ to the widget
+ A QWidget can have 0 or more softkeys
+
+ \sa softKeys(), setSoftKeys()
+*/
+void QWidget::setSoftKey(QAction *softKey)
+{
+ Q_D(QWidget);
+ qDeleteAll(d->softKeys);
+ d->softKeys.clear();
+ if (softKey)
+ d->softKeys.append(softKey);
+ if (QApplication::focusWidget() == this)
+ d->setSoftKeys_sys(this->softKeys());
+}
+
+/*!
+ Sets the list of softkeys \a softkeys to this widget's list of softkeys,
+ A QWidget can have 0 or more softkeys
+
+ \sa softKeys(), setSoftKey()
+*/
+void QWidget::setSoftKeys(const QList<QAction*> &softKeys)
+{
+ Q_D(QWidget);
+ qDeleteAll(d->softKeys);
+ d->softKeys.clear();
+ d->softKeys = softKeys;
+
+ if ((QApplication::focusWidget() == this) || (QApplication::focusWidget()==0))
+ d->setSoftKeys_sys(this->softKeys());
+}
+
/*! \fn const QX11Info &QWidget::x11Info() const
Returns information about the configuration of the X display used to display
the widget.
diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h
index 0dd470d..3f9caee 100644
--- a/src/gui/kernel/qwidget.h
+++ b/src/gui/kernel/qwidget.h
@@ -554,6 +554,9 @@ public:
void removeAction(QAction *action);
QList<QAction*> actions() const;
#endif
+ const QList<QAction*>& softKeys() const;
+ void setSoftKey(QAction *softKey);
+ void setSoftKeys(const QList<QAction*> &softKeys);
QWidget *parentWidget() const;
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index d5f1b98..084439c 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -84,6 +84,9 @@ class RDrawableWindow;
class CCoeControl;
class CAknTitlePane;
class CAknContextPane;
+// The following 2 defines may only be needed for s60. To be seen.
+const int SOFTKEYSTART=5000;
+const int SOFTKEYEND=5004;
#endif
QT_BEGIN_NAMESPACE
@@ -224,6 +227,7 @@ public:
explicit QWidgetPrivate(int version = QObjectPrivateVersion);
~QWidgetPrivate();
+ void setSoftKeys_sys(const QList<QAction*> &softkeys);
QWExtra *extraData() const;
QTLWExtra *topData() const;
QTLWExtra *maybeTopData() const;
@@ -511,6 +515,7 @@ public:
#ifndef QT_NO_ACTION
QList<QAction*> actions;
#endif
+ QList<QAction*> softKeys;
QLayout *layout;
QWidgetItemV2 *widgetItem;
#if !defined(QT_NO_IM)
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index e32e272..eb3180f 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -52,6 +52,8 @@
#include <qinputcontext.h>
+#include <aknappui.h>
+
QT_BEGIN_NAMESPACE
extern bool qt_nograb();
@@ -59,6 +61,56 @@ extern bool qt_nograb();
QWidget *QWidgetPrivate::mouseGrabber = 0;
QWidget *QWidgetPrivate::keyboardGrabber = 0;
+static bool isEqual(const QList<QAction*>& a, const QList<QAction*>& b)
+{
+ if ( a.count() != b.count())
+ return false;
+ int index=0;
+ while (index<a.count()) {
+ if (a.at(index)->softKeyRole() != b.at(index)->softKeyRole())
+ return false;
+ if (a.at(index)->text().compare(b.at(index)->text())!=0)
+ return false;
+ index++;
+ }
+ return true;
+}
+
+
+void QWidgetPrivate::setSoftKeys_sys(const QList<QAction*> &softkeys)
+{
+ Q_Q(QWidget);
+ if (QApplication::focusWidget() && q!=QApplication::focusWidget()) {
+ QList<QAction *> old = QApplication::focusWidget()->softKeys();
+ if (isEqual(old, softkeys ))
+ return;
+ }
+ CCoeAppUi* appui = CEikonEnv::Static()->AppUi();
+ CAknAppUi* aknAppUi = static_cast <CAknAppUi*>(appui);
+ CEikButtonGroupContainer* nativeContainer = aknAppUi->Cba();
+ nativeContainer->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS);
+
+ int placeInScreen=0;
+ for (int index = 0; index < softkeys.count(); index++) {
+ const QAction* softKeyAction = softkeys.at(index);
+ if (softKeyAction->softKeyRole() != QAction::ContextMenuSoftKey) {
+
+ HBufC* text = qt_QString2HBufCNewL(softKeyAction->text());
+ CleanupStack::PushL(text);
+ if (softKeyAction->softKeyRole() == QAction::MenuSoftKey) {
+ nativeContainer->SetCommandL(placeInScreen, EAknSoftkeyOptions, *text);
+ } else {
+ nativeContainer->SetCommandL(placeInScreen, SOFTKEYSTART + index, *text);
+ }
+ CleanupStack::PopAndDestroy();
+ placeInScreen++;
+ }
+ if (placeInScreen==1)
+ placeInScreen=2;
+ }
+ nativeContainer->DrawDeferred(); // 3.1 needs an extra invitation
+}
+
void QWidgetPrivate::setWSGeometry(bool dontShow)
{
@@ -1006,5 +1058,4 @@ void QWidget::activateWindow()
rw->SetOrdinalPosition(0);
}
}
-
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qactiontokeyeventmapper.cpp b/src/gui/widgets/qactiontokeyeventmapper.cpp
new file mode 100644
index 0000000..5cce415
--- /dev/null
+++ b/src/gui/widgets/qactiontokeyeventmapper.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qapplication.h"
+#include "qevent.h"
+#include "QActionToKeyEventMapper_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QActionToKeyEventMapper::QActionToKeyEventMapper(QAction *softKeyAction, Qt::Key key, QObject *parent)
+ : QObject(parent)
+ , m_softKeyAction(softKeyAction)
+ , m_key(key)
+{
+
+}
+
+QString QActionToKeyEventMapper::roleText(QAction::SoftKeyRole role)
+{
+ switch (role) {
+ case QAction::OptionsSoftKey:
+ return QAction::tr("Options");
+ case QAction::SelectSoftKey:
+ return QAction::tr("Select");
+ case QAction::BackSoftKey:
+ return QAction::tr("Back");
+ case QAction::NextSoftKey:
+ return QAction::tr("Next");
+ case QAction::PreviousSoftKey:
+ return QAction::tr("Previous");
+ case QAction::OkSoftKey:
+ return QAction::tr("Ok");
+ case QAction::CancelSoftKey:
+ return QAction::tr("Cancel");
+ case QAction::EditSoftKey:
+ return QAction::tr("Edit");
+ case QAction::ViewSoftKey:
+ return QAction::tr("View");
+ default:
+ return QString();
+ };
+}
+void QActionToKeyEventMapper::addSoftKey(QAction::SoftKeyRole standardRole, Qt::Key key, QWidget *actionWidget)
+{
+ QAction *action = new QAction(actionWidget);
+ action->setSoftKeyRole(standardRole);
+ action->setText(roleText(standardRole));
+ QActionToKeyEventMapper *softKey = new QActionToKeyEventMapper(action, key, actionWidget);
+ connect(action, SIGNAL(triggered()), softKey, SLOT(sendKeyEvent()));
+ connect(action, SIGNAL(destroyed()), softKey, SLOT(deleteLater()));
+ actionWidget->setSoftKey(action);
+}
+
+void QActionToKeyEventMapper::removeSoftkey(QWidget *focussedWidget)
+{
+ focussedWidget->setSoftKey(0);
+}
+
+void QActionToKeyEventMapper::sendKeyEvent()
+{
+ QApplication::postEvent(parent(), new QKeyEvent(QEvent::KeyPress, m_key, Qt::NoModifier));
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/gui/widgets/qactiontokeyeventmapper_p.h b/src/gui/widgets/qactiontokeyeventmapper_p.h
new file mode 100644
index 0000000..da336e8
--- /dev/null
+++ b/src/gui/widgets/qactiontokeyeventmapper_p.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QACTIONTOKEYEVENTMAPPER_P_H
+#define QACTIONTOKEYEVENTMAPPER_P_H
+
+#include <QtCore/qobject.h>
+#include "QtGui/qaction.h"
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QActionToKeyEventMapper : public QObject
+{
+ Q_OBJECT
+public:
+ QActionToKeyEventMapper(QAction *softKeyAction, Qt::Key key, QObject *parent);
+ static QString roleText(QAction::SoftKeyRole role);
+ static void addSoftKey(QAction::SoftKeyRole standardRole, Qt::Key key, QWidget *actionWidget);
+ static void removeSoftkey(QWidget *focussedWidget);
+private:
+ QAction *m_softKeyAction;
+ Qt::Key m_key;
+private Q_SLOTS:
+ void sendKeyEvent();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif //QACTIONTOKEYEVENTMAPPER_H
diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp
index 16e2f39..2da5cd0 100644
--- a/src/gui/widgets/qcombobox.cpp
+++ b/src/gui/widgets/qcombobox.cpp
@@ -63,7 +63,7 @@
#include <private/qabstractitemmodel_p.h>
#include <private/qabstractscrollarea_p.h>
#include <qdebug.h>
-
+#include <qactiontokeyeventmapper_p.h>
#ifdef Q_WS_X11
#include <private/qt_x11_p.h>
#endif
@@ -628,6 +628,9 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e)
case Qt::Key_Select:
#endif
if (view->currentIndex().isValid() && (view->currentIndex().flags() & Qt::ItemIsEnabled) ) {
+#ifdef QT_KEYPAD_NAVIGATION
+ QActionToKeyEventMapper::removeSoftkey(this);
+#endif
combo->hidePopup();
emit itemSelected(view->currentIndex());
}
@@ -640,7 +643,7 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e)
case Qt::Key_Escape:
#ifdef QT_KEYPAD_NAVIGATION
case Qt::Key_Back:
- case Qt::Key_Context2: // TODO: aportale, KEYPAD_NAVIGATION_HACK when softkey support is there
+ QActionToKeyEventMapper::removeSoftkey(this);
#endif
combo->hidePopup();
return true;
@@ -2435,6 +2438,7 @@ void QComboBox::showPopup()
#ifdef QT_KEYPAD_NAVIGATION
if (QApplication::keypadNavigationEnabled())
view()->setEditFocus(true);
+ QActionToKeyEventMapper::addSoftKey(QAction::CancelSoftKey, Qt::Key_Back, view());
#endif
}
diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp
index 558ba42..2f3b412 100644
--- a/src/gui/widgets/qmainwindow.cpp
+++ b/src/gui/widgets/qmainwindow.cpp
@@ -481,6 +481,11 @@ void QMainWindow::setMenuBar(QMenuBar *menuBar)
oldMenuBar->deleteLater();
}
d->layout->setMenuBar(menuBar);
+ if (menuBar) {
+ QAction* menu = new QAction(QString::fromLatin1("Menu"), this);
+ menu->setSoftKeyRole(QAction::MenuSoftKey);
+ setSoftKey(menu);
+ }
}
/*!
diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp
index 6be0f19..3486574 100644
--- a/src/gui/widgets/qmenu.cpp
+++ b/src/gui/widgets/qmenu.cpp
@@ -60,6 +60,7 @@
#ifndef QT_NO_WHATSTHIS
# include <qwhatsthis.h>
#endif
+#include <qactiontokeyeventmapper_p.h>
#include "qmenu_p.h"
#include "qmenubar_p.h"
@@ -578,8 +579,14 @@ void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason
//when the action has no QWidget, the QMenu itself should
// get the focus
// Since the menu is a pop-up, it uses the popup reason.
- if (!q->hasFocus())
+ if (!q->hasFocus()) {
q->setFocus(Qt::PopupFocusReason);
+#ifdef QT_KEYPAD_NAVIGATION
+ // TODO: aportale, remove KEYPAD_NAVIGATION_HACK when softkey stack
+ // handles focus related and user related actions separately...
+ QActionToKeyEventMapper::addSoftKey(QAction::CancelSoftKey, Qt::Key_Back, q);
+#endif
+ }
}
}
} else { //action is a separator
@@ -1937,6 +1944,9 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
#ifndef QT_NO_ACCESSIBILITY
QAccessible::updateAccessibility(this, 0, QAccessible::PopupMenuStart);
#endif
+#ifdef QT_KEYPAD_NAVIGATION
+ QActionToKeyEventMapper::addSoftKey(QAction::CancelSoftKey, Qt::Key_Back, this);
+#endif
}
/*!
@@ -2587,7 +2597,7 @@ void QMenu::keyPressEvent(QKeyEvent *e)
case Qt::Key_Escape:
#ifdef QT_KEYPAD_NAVIGATION
case Qt::Key_Back:
- case Qt::Key_Context2: // TODO: aportale, remove KEYPAD_NAVIGATION_HACK when softkey support is there
+ QActionToKeyEventMapper::removeSoftkey(this);
#endif
key_consumed = true;
if (d->tornoff) {
diff --git a/src/gui/widgets/qmenu_symbian.cpp b/src/gui/widgets/qmenu_symbian.cpp
index 48c2cf6..49bcc21 100644
--- a/src/gui/widgets/qmenu_symbian.cpp
+++ b/src/gui/widgets/qmenu_symbian.cpp
@@ -40,8 +40,6 @@
#include "qmenu.h"
#include "qapplication.h"
-#include "qmainwindow.h"
-#include "qtoolbar.h"
#include "qevent.h"
#include "qstyle.h"
#include "qdebug.h"
@@ -56,12 +54,10 @@
#include <eikbtgpc.h>
#include <QtCore/qlibrary.h>
#include <avkon.rsg>
-
#ifndef QT_NO_MENUBAR
QT_BEGIN_NAMESPACE
-// ### FIX/Document this, we need some safe range of menu id's for Qt that don't clash with AIW ones
typedef QMultiHash<QWidget *, QMenuBarPrivate *> MenuBarHash;
Q_GLOBAL_STATIC(MenuBarHash, menubars)
@@ -78,6 +74,10 @@ struct SymbianMenuItem
static QList<SymbianMenuItem*> symbianMenus;
static QList<QMenuBar*> nativeMenuBars;
static uint qt_symbian_menu_static_cmd_id = QT_FIRST_MENU_ITEM;
+static QWidget* widgetWithContextMenu=0;
+static QList<QAction*> contextMenuActionList;
+static QAction contextAction(0);
+static int contexMenuCommand=0;
bool menuExists()
{
@@ -88,6 +88,16 @@ bool menuExists()
return true;
}
+static bool hasContextMenu(QWidget* widget)
+{
+ if (!widget)
+ return false;
+ const Qt::ContextMenuPolicy policy = widget->contextMenuPolicy();
+ if (policy != Qt::NoContextMenu && policy != Qt::PreventContextMenu ) {
+ return true;
+ }
+ return false;
+}
// ### FIX THIS, copy/paste of original (faulty) stripped text implementation.
// Implementation should be removed from QAction implementation to some generic place
static QString qt_strippedText_copy_from_qaction(QString s)
@@ -204,24 +214,18 @@ void deleteAll(QList<SymbianMenuItem*> *items)
}
}
-static void setSoftkeys()
-{
- CEikButtonGroupContainer* cba = CEikonEnv::Static()->AppUiFactory()->Cba();
- if (cba){
- if (menuExists())
- cba->SetCommandSetL(R_AVKON_SOFTKEYS_OPTIONS_EXIT);
- else
- cba->SetCommandSetL(R_AVKON_SOFTKEYS_EXIT);
- }
-}
-
static void rebuildMenu()
{
+ widgetWithContextMenu = 0;
QMenuBarPrivate *mb = 0;
- setSoftkeys();
QWidget *w = qApp->activeWindow();
- if (w)
- {
+ QWidget* focusWidget = QApplication::focusWidget();
+ if (focusWidget) {
+ if (hasContextMenu(focusWidget))
+ widgetWithContextMenu = focusWidget;
+ }
+
+ if (w) {
mb = menubars()->value(w);
qt_symbian_menu_static_cmd_id = QT_FIRST_MENU_ITEM;
deleteAll( &symbianMenus );
@@ -229,7 +233,7 @@ static void rebuildMenu()
return;
mb->symbian_menubar->rebuild();
}
- }
+}
Q_GUI_EXPORT void qt_symbian_show_toplevel( CEikMenuPane* menuPane)
{
@@ -251,6 +255,11 @@ Q_GUI_EXPORT void qt_symbian_show_submenu( CEikMenuPane* menuPane, int id)
void QMenuBarPrivate::symbianCommands(int command)
{
+ if (command == contexMenuCommand) {
+ QContextMenuEvent* event = new QContextMenuEvent(QContextMenuEvent::Keyboard, QPoint(0,0));
+ QCoreApplication::postEvent(widgetWithContextMenu, event);
+ }
+
int size = nativeMenuBars.size();
for (int i = 0; i < nativeMenuBars.size(); ++i) {
SymbianMenuItem* menu = qt_symbian_find_menu_item(command, symbianMenus);
@@ -377,22 +386,36 @@ void QMenuBarPrivate::QSymbianMenuBarPrivate::removeAction(QSymbianMenuAction *a
rebuild();
}
-void QMenuBarPrivate::QSymbianMenuBarPrivate::rebuild()
+void QMenuBarPrivate::QSymbianMenuBarPrivate::insertNativeMenuItems(const QList<QAction*> &actions)
{
- setSoftkeys();
- qt_symbian_menu_static_cmd_id = QT_FIRST_MENU_ITEM;
- deleteAll( &symbianMenus );
- if (!d)
- return;
- for (int i = 0; i < d->actions.size(); ++i) {
+ for (int i = 0; i <actions.size(); ++i) {
QSymbianMenuAction *symbianActionTopLevel = new QSymbianMenuAction;
- symbianActionTopLevel->action = d->actions.at(i);
+ symbianActionTopLevel->action = actions.at(i);
symbianActionTopLevel->parent = 0;
symbianActionTopLevel->command = qt_symbian_menu_static_cmd_id++;
qt_symbian_insert_action(symbianActionTopLevel, &symbianMenus);
- }
+ }
}
+
+
+void QMenuBarPrivate::QSymbianMenuBarPrivate::rebuild()
+{
+ contexMenuCommand = 0;
+ qt_symbian_menu_static_cmd_id = QT_FIRST_MENU_ITEM;
+ deleteAll( &symbianMenus );
+ if (d)
+ insertNativeMenuItems(d->actions);
+
+ contextMenuActionList.clear();
+ if (widgetWithContextMenu) {
+ contexMenuCommand = qt_symbian_menu_static_cmd_id;
+ contextAction.setText(QString("Actions"));
+ contextMenuActionList.append(&contextAction);
+ insertNativeMenuItems(contextMenuActionList);
+ }
+
+}
QT_END_NAMESPACE
#endif //QT_NO_MENUBAR
diff --git a/src/gui/widgets/qmenubar_p.h b/src/gui/widgets/qmenubar_p.h
index 7993acd..9e7d511 100644
--- a/src/gui/widgets/qmenubar_p.h
+++ b/src/gui/widgets/qmenubar_p.h
@@ -257,6 +257,7 @@ public:
}
return 0;
}
+ void insertNativeMenuItems(const QList<QAction*> &actions);
} *symbian_menubar;
static void symbianCommands(int command);
diff --git a/src/gui/widgets/widgets.pri b/src/gui/widgets/widgets.pri
index fc57944..9e226e2 100644
--- a/src/gui/widgets/widgets.pri
+++ b/src/gui/widgets/widgets.pri
@@ -78,8 +78,8 @@ HEADERS += \
widgets/qtoolbararealayout_p.h \
widgets/qplaintextedit.h \
widgets/qplaintextedit_p.h \
- widgets/qprintpreviewwidget.h
-
+ widgets/qprintpreviewwidget.h \
+ widgets/qactiontokeyeventmapper_p.h
SOURCES += \
widgets/qabstractbutton.cpp \
widgets/qabstractslider.cpp \
@@ -138,8 +138,8 @@ SOURCES += \
widgets/qwidgetanimator.cpp \
widgets/qtoolbararealayout.cpp \
widgets/qplaintextedit.cpp \
- widgets/qprintpreviewwidget.cpp
-
+ widgets/qprintpreviewwidget.cpp \
+ widgets/qactiontokeyeventmapper.cpp
!embedded:mac {
HEADERS += widgets/qmacnativewidget_mac.h \
diff --git a/src/s60main/qts60mainappui.cpp b/src/s60main/qts60mainappui.cpp
index 47312af..7d38f33 100644
--- a/src/s60main/qts60mainappui.cpp
+++ b/src/s60main/qts60mainappui.cpp
@@ -68,6 +68,9 @@ void CQtS60MainAppUi::ConstructL()
// even these flags are defined
BaseConstructL(CAknAppUi::EAknEnableSkin);
+ CEikButtonGroupContainer* nativeContainer = Cba();
+ nativeContainer->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS);
+
// Create async callback to call Qt main,
// this is required to give S60 app FW to finish starting correctly
TCallBack callBack( OpenCMainStaticCallBack, this );