summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gui/itemviews/qabstractitemview.cpp11
-rw-r--r--src/gui/kernel/qapplication_s60.cpp12
-rw-r--r--src/gui/softkeys/main.cpp125
-rw-r--r--src/gui/softkeys/softkeys.pro2
-rw-r--r--src/gui/widgets/qcombobox.cpp9
-rw-r--r--src/gui/widgets/qmainwindow.cpp61
-rw-r--r--src/gui/widgets/qmainwindow.h9
-rw-r--r--src/gui/widgets/qmenu.cpp16
-rw-r--r--src/gui/widgets/qmenu_symbian.cpp82
-rw-r--r--src/gui/widgets/qmenubar_p.h1
-rw-r--r--src/gui/widgets/qsoftkeyaction.cpp234
-rw-r--r--src/gui/widgets/qsoftkeyaction.h106
-rw-r--r--src/gui/widgets/qsoftkeystack.cpp304
-rw-r--r--src/gui/widgets/qsoftkeystack.h89
-rw-r--r--src/gui/widgets/qsoftkeystack_p.h111
-rw-r--r--src/gui/widgets/qsoftkeystack_s60.cpp119
-rw-r--r--src/gui/widgets/widgets.pri15
17 files changed, 1263 insertions, 43 deletions
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp
index 159a997..565bc28 100644
--- a/src/gui/itemviews/qabstractitemview.cpp
+++ b/src/gui/itemviews/qabstractitemview.cpp
@@ -61,6 +61,9 @@
#ifndef QT_NO_ACCESSIBILITY
#include <qaccessible.h>
#endif
+#ifdef QT_KEYPAD_NAVIGATION
+#include <private/qsoftkeystack_p.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -2003,16 +2006,18 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event)
if (QApplication::keypadNavigationEnabled()) {
if (!hasEditFocus()) {
setEditFocus(true);
+ QKeyEventSoftKey::addSoftKey(QSoftKeyAction::Back, 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()) {
+ QKeyEventSoftKey::removeSoftkey(this);
setEditFocus(false);
- else
+ } else {
event->ignore();
+ }
return;
default:
if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 2f7bdcf..94e59b3 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -1,5 +1,5 @@
/****************************************************************************
-**
+1**
** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
@@ -58,6 +58,7 @@
#endif
#include "private/qwindowsurface_s60_p.h"
#include "qpaintengine.h"
+#include "private/qsoftkeystack_p.h"
#include "private/qmenubar_p.h"
#include "apgwgnam.h" // For CApaWindowGroupName
@@ -1059,13 +1060,14 @@ 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)
+ QSoftKeyStackPrivate::handleSoftKeyPress(command);
+ else
+ QMenuBarPrivate::symbianCommands(command);
break;
}
}
diff --git a/src/gui/softkeys/main.cpp b/src/gui/softkeys/main.cpp
new file mode 100644
index 0000000..a92e2c2
--- /dev/null
+++ b/src/gui/softkeys/main.cpp
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+public:
+
+private slots:
+ void context1Slot();
+ void context3Slot();
+ void softKeySlot();
+public:
+
+ MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+ QMenu *contextMenu;
+ QAction* context1;
+ QAction* context2;
+ QAction* context3;
+ QSoftKeyAction *action1;
+ QSoftKeyAction *action2;
+ QSoftKeyAction *action3;
+ QSoftKeyAction *action4;
+ QSoftKeyAction *action5;
+};
+
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent),
+ contextMenu(0),
+ context1(0), context2(0), context3(0),
+ action1(0),action2(0),action3(0),action4(0),action5(0)
+
+{
+ QWidget *central = new QWidget(this);
+ contextMenu = new QMenu();
+
+ central->setLayout(new QVBoxLayout);
+ central->layout()->addWidget(new QPushButton);
+ central->layout()->addWidget(new QPushButton);
+ central->layout()->addWidget(new QPushButton);
+ context1 = new QAction(QString("Context1"), central);
+ context2 = new QAction(QString("Context2"), central);
+
+ context3 = new QAction(QString("Context3"), contextMenu);
+ central->addAction(context1);
+ central->addAction(context2);
+ QMenuBar* menuBar = new QMenuBar(this);
+ menuBar->addAction("MyMenuItem1");
+ this->setMenuBar(menuBar);
+ context2->setMenu(contextMenu);
+ contextMenu->addAction(context3);
+
+ connect(context1, SIGNAL(triggered()), this, SLOT(context1Slot()));
+ connect(context3, SIGNAL(triggered()), this, SLOT(context3Slot()));
+ action1 = new QSoftKeyAction(QSoftKeyAction::Ok, QString("Ok"), central);
+ action2 = new QSoftKeyAction(QSoftKeyAction::Back, QString("Back"), central);
+ action3 = new QSoftKeyAction(QSoftKeyAction::Cancel, QString("Cancel"), central);
+ action4 = new QSoftKeyAction(QSoftKeyAction::Menu, QString("Menu"), central);
+ action5 = new QSoftKeyAction(QSoftKeyAction::ContextMenu,QString("ContextMenu"), central);
+
+ connect(action2, SIGNAL(triggered()), this, SLOT(softKeySlot()));
+
+ QList<QSoftKeyAction*> myActionList;
+ myActionList.append(action1);
+ myActionList.append(action2);
+ myActionList.append(action3);
+ softKeyStack()->push(myActionList);
+ softKeyStack()->pop();
+ softKeyStack()->push(action1);
+ softKeyStack()->pop();
+
+ QList<QSoftKeyAction*> myActionList2;
+ myActionList2.append(action4);
+ myActionList2.append(action2);
+ myActionList2.append(action5);
+ softKeyStack()->push(myActionList2);
+
+
+ setCentralWidget(central);
+}
+MainWindow::~MainWindow()
+{
+ delete context1;
+ delete context2;
+ delete context3;
+ delete action1;
+ delete action2;
+ delete action3;
+ delete action4;
+ delete action5;
+ delete contextMenu;
+}
+
+void MainWindow::context1Slot()
+ {
+ }
+void MainWindow::context3Slot()
+ {
+ }
+
+void MainWindow::softKeySlot()
+{
+
+}
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ MainWindow mw;
+ mw.show();
+ return app.exec();
+}
+
+#include "main.moc"
diff --git a/src/gui/softkeys/softkeys.pro b/src/gui/softkeys/softkeys.pro
new file mode 100644
index 0000000..a16103e
--- /dev/null
+++ b/src/gui/softkeys/softkeys.pro
@@ -0,0 +1,2 @@
+SOURCES += \
+ main.cpp
diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp
index 16e2f39..59b740f 100644
--- a/src/gui/widgets/qcombobox.cpp
+++ b/src/gui/widgets/qcombobox.cpp
@@ -75,6 +75,9 @@
#ifndef QT_NO_EFFECTS
# include <private/qeffects_p.h>
#endif
+#ifdef QT_KEYPAD_NAVIGATION
+# include <private/qsoftkeystack_p.h>
+#endif
QT_BEGIN_NAMESPACE
extern QHash<QByteArray, QFont> *qt_app_fonts_hash();
@@ -628,6 +631,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
+ QKeyEventSoftKey::removeSoftkey(this);
+#endif
combo->hidePopup();
emit itemSelected(view->currentIndex());
}
@@ -640,7 +646,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
+ QKeyEventSoftKey::removeSoftkey(this);
#endif
combo->hidePopup();
return true;
@@ -2435,6 +2441,7 @@ void QComboBox::showPopup()
#ifdef QT_KEYPAD_NAVIGATION
if (QApplication::keypadNavigationEnabled())
view()->setEditFocus(true);
+ QKeyEventSoftKey::addSoftKey(QSoftKeyAction::Cancel, Qt::Key_Back, this);
#endif
}
diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp
index 558ba42..37b1398 100644
--- a/src/gui/widgets/qmainwindow.cpp
+++ b/src/gui/widgets/qmainwindow.cpp
@@ -66,6 +66,10 @@ extern OSWindowRef qt_mac_window_for(const QWidget *); // qwidget_mac.cpp
QT_END_NAMESPACE
#endif
+#ifndef QT_NO_SOFTKEYSTACK
+#include <qsoftkeystack.h>
+#endif
+
QT_BEGIN_NAMESPACE
class QMainWindowPrivate : public QWidgetPrivate
@@ -80,6 +84,9 @@ public:
#if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR)
, hasOldCursor(false) , cursorAdjusted(false)
#endif
+#ifndef QT_NO_SOFTKEYSTACK
+ , softKeyStack(0)
+#endif
{ }
QMainWindowLayout *layout;
QSize iconSize;
@@ -99,6 +106,10 @@ public:
uint hasOldCursor : 1;
uint cursorAdjusted : 1;
#endif
+
+#ifndef QT_NO_SOFTKEYSTACK
+ QSoftKeyStack *softKeyStack;
+#endif
};
void QMainWindowPrivate::init()
@@ -110,6 +121,9 @@ void QMainWindowPrivate::init()
explicitIconSize = false;
q->setAttribute(Qt::WA_Hover);
+#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SOFTKEYSTACK)
+ softKeyStack = new QSoftKeyStack(q);
+#endif
}
/*
@@ -514,6 +528,53 @@ void QMainWindow::setMenuWidget(QWidget *menuBar)
}
#endif // QT_NO_MENUBAR
+#ifndef QT_NO_SOFTKEYSTACK
+/*!
+ Returns the softkey stack for the main window. This function creates
+ and returns an empty soft key stack if the stack does not exist.
+
+ \sa softKeyStack()
+*/
+QSoftKeyStack *QMainWindow::softKeyStack() const
+{
+ if (!d_func()->softKeyStack) {
+ QMainWindow *self = const_cast<QMainWindow *>(this);
+ QSoftKeyStack* softKeyStack = new QSoftKeyStack(self);
+ self->setSoftKeyStack(softKeyStack);
+ }
+ return d_func()->softKeyStack;
+}
+
+/*!
+ Sets the softkey stack for the main window to \a softKeyStack.
+
+ Note: QMainWindow takes ownership of the \a softKeyStack pointer and
+ deletes it at the appropriate time.
+
+ \sa softKeyStack()
+*/
+void QMainWindow::setSoftKeyStack(QSoftKeyStack *softKeyStack)
+{
+ Q_D(QMainWindow);
+ if (d->softKeyStack && d->softKeyStack != softKeyStack) {
+ QSoftKeyStack *oldSoftKeyStack = d->softKeyStack;
+ delete oldSoftKeyStack;
+ }
+ d->softKeyStack = softKeyStack;
+}
+
+/*!
+ Returns true if QMainWindow has a softkeystack and false otherwise
+
+ \sa softKeyStack()
+*/
+bool QMainWindow::hasSoftKeyStack() const
+{
+ Q_D(const QMainWindow);
+ return d->softKeyStack != 0;
+}
+#endif // QT_NO_SOFTKEYSTACK
+
#ifndef QT_NO_STATUSBAR
/*!
Returns the status bar for the main window. This function creates
diff --git a/src/gui/widgets/qmainwindow.h b/src/gui/widgets/qmainwindow.h
index 9983c7a..81457d6 100644
--- a/src/gui/widgets/qmainwindow.h
+++ b/src/gui/widgets/qmainwindow.h
@@ -59,6 +59,7 @@ class QMenuBar;
class QStatusBar;
class QToolBar;
class QMenu;
+class QSoftKeyStack;
class Q_GUI_EXPORT QMainWindow : public QWidget
{
@@ -129,7 +130,13 @@ public:
QWidget *menuWidget() const;
void setMenuWidget(QWidget *menubar);
#endif
-
+
+#ifndef QT_NO_SOFTKEYSTACK
+ QSoftKeyStack *softKeyStack() const;
+ void setSoftKeyStack(QSoftKeyStack *softKeyStack);
+ bool hasSoftKeyStack() const;
+#endif
+
#ifndef QT_NO_STATUSBAR
QStatusBar *statusBar() const;
void setStatusBar(QStatusBar *statusbar);
diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp
index 6be0f19..c4db539 100644
--- a/src/gui/widgets/qmenu.cpp
+++ b/src/gui/widgets/qmenu.cpp
@@ -60,6 +60,9 @@
#ifndef QT_NO_WHATSTHIS
# include <qwhatsthis.h>
#endif
+#ifdef QT_KEYPAD_NAVIGATION
+# include <private/qsoftkeystack_p.h>
+#endif
#include "qmenu_p.h"
#include "qmenubar_p.h"
@@ -578,8 +581,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...
+ QKeyEventSoftKey::addSoftKey(QSoftKeyAction::Cancel, Qt::Key_Back, q);
+#endif
+ }
}
}
} else { //action is a separator
@@ -1937,6 +1946,9 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
#ifndef QT_NO_ACCESSIBILITY
QAccessible::updateAccessibility(this, 0, QAccessible::PopupMenuStart);
#endif
+#ifdef QT_KEYPAD_NAVIGATION
+ QKeyEventSoftKey::addSoftKey(QSoftKeyAction::Cancel, Qt::Key_Back, this);
+#endif
}
/*!
@@ -2587,7 +2599,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
+ QKeyEventSoftKey::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..f27e580 100644
--- a/src/gui/widgets/qmenu_symbian.cpp
+++ b/src/gui/widgets/qmenu_symbian.cpp
@@ -56,12 +56,12 @@
#include <eikbtgpc.h>
#include <QtCore/qlibrary.h>
#include <avkon.rsg>
-
+#include <qsoftkeystack.h>
+#include <qsoftkeyaction.h>
#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 +78,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()
{
@@ -204,24 +208,31 @@ 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)
- {
+ QMainWindow *mainWindow = qobject_cast<QMainWindow*>(w);
+ if ((mainWindow) && mainWindow->hasSoftKeyStack()) {
+ QSoftKeyStack* softKeyStack = mainWindow->softKeyStack();
+ if (!softKeyStack->isEmpty()) {
+ const QSoftkeySet& softKeyTop = softKeyStack->top();
+ int index=0;
+ bool found=false;
+ while( index<softKeyTop.count() && !found) {
+ QSoftKeyAction* softAction = softKeyTop.at(index);
+ QSoftKeyAction::StandardRole role = softAction->role();
+ if(softAction->role() == QSoftKeyAction::ContextMenu) {
+ widgetWithContextMenu = softAction->parentWidget();
+ found=true;
+ }
+ index++;
+ }
+ }
+ }
+
+ if (w) {
mb = menubars()->value(w);
qt_symbian_menu_static_cmd_id = QT_FIRST_MENU_ITEM;
deleteAll( &symbianMenus );
@@ -229,7 +240,7 @@ static void rebuildMenu()
return;
mb->symbian_menubar->rebuild();
}
- }
+}
Q_GUI_EXPORT void qt_symbian_show_toplevel( CEikMenuPane* menuPane)
{
@@ -251,6 +262,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 +393,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..429605a 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/qsoftkeyaction.cpp b/src/gui/widgets/qsoftkeyaction.cpp
new file mode 100644
index 0000000..302850c
--- /dev/null
+++ b/src/gui/widgets/qsoftkeyaction.cpp
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** 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 "qsoftkeyaction.h"
+#include <QtGui/private/qaction_p.h>
+
+/*!
+ \class QSoftKeyAction
+ \brief The QSoftKeyAction class defines a special kind of QAction that may also be displayed in a QSoftKeyBar.
+*/
+
+class QSoftKeyActionPrivate : public QActionPrivate
+{
+public:
+ QSoftKeyActionPrivate(QSoftKeyAction::StandardRole role = QSoftKeyAction::Custom)
+ {
+ this->role = role;
+ }
+
+ static QString roleText(QSoftKeyAction::StandardRole role);
+
+ QSoftKeyAction::StandardRole role;
+ QString roleName;
+ int nativePosition;
+ int qtContextKey;
+};
+
+QString QSoftKeyActionPrivate::roleText(QSoftKeyAction::StandardRole role)
+{
+ switch (role) {
+ case QSoftKeyAction::Options:
+ return QSoftKeyAction::tr("Options");
+ case QSoftKeyAction::Select:
+ return QSoftKeyAction::tr("Select");
+ case QSoftKeyAction::Back:
+ return QSoftKeyAction::tr("Back");
+ case QSoftKeyAction::Next:
+ return QSoftKeyAction::tr("Next");
+ case QSoftKeyAction::Previous:
+ return QSoftKeyAction::tr("Previous");
+ case QSoftKeyAction::Ok:
+ return QSoftKeyAction::tr("Ok");
+ case QSoftKeyAction::Cancel:
+ return QSoftKeyAction::tr("Cancel");
+ case QSoftKeyAction::Edit:
+ return QSoftKeyAction::tr("Edit");
+ case QSoftKeyAction::View:
+ return QSoftKeyAction::tr("View");
+ default:
+ return QString();
+ };
+}
+
+/*!
+ \enum QSoftKeyAction::StandardRole
+ This enum defines the standard role for a QSoftKeyAction.
+
+ \value Options
+ \value Select
+ \value Back
+ \value Next
+ \value Previous
+ \value Ok
+ \value Cancel
+ \value Edit
+ \value View
+ \value BackSpace
+ \value EndEdit
+ \value RevertEdit
+ \value Deselect
+ \value Finish
+ \value Custom
+*/
+
+QSoftKeyAction::QSoftKeyAction(QObject *parent)
+ : QAction(*new QSoftKeyActionPrivate(), parent)
+{
+}
+
+QSoftKeyAction::QSoftKeyAction(StandardRole role, QObject *parent)
+ : QAction(*new QSoftKeyActionPrivate(), parent)
+{
+ Q_D(QSoftKeyAction);
+ d->role = role;
+ setText(QSoftKeyActionPrivate::roleText(role));
+}
+
+QSoftKeyAction::QSoftKeyAction(const QString &text, QObject* parent)
+ : QAction(*new QSoftKeyActionPrivate(), parent)
+{
+ setText(text);
+}
+
+QSoftKeyAction::QSoftKeyAction(StandardRole role, const QString &text, QObject* parent)
+ : QAction(*new QSoftKeyActionPrivate(), parent)
+{
+ setText(text);
+ Q_D(QSoftKeyAction);
+ d->role = role;
+}
+
+QSoftKeyAction::QSoftKeyAction(const QIcon &icon, const QString &text, QObject* parent)
+ : QAction(*new QSoftKeyActionPrivate(), parent)
+{
+ setIcon(icon);
+ setText(text);
+}
+
+QSoftKeyAction::QSoftKeyAction(StandardRole role, const QIcon &icon, const QString &text, QObject* parent)
+ : QAction(*new QSoftKeyActionPrivate(), parent)
+{
+ setIcon(icon);
+ setText(text);
+ Q_D(QSoftKeyAction);
+ d->role = role;
+}
+
+QSoftKeyAction::~QSoftKeyAction()
+{
+}
+
+/*!
+ Returns the standard role associated with this action, or Custom
+ if the role is defined by roleName().
+
+ \sa setRole(), roleName()
+*/
+QSoftKeyAction::StandardRole QSoftKeyAction::role() const
+{
+ Q_D(const QSoftKeyAction);
+ return d->role;
+}
+
+/*!
+ Returns the custom role name if role() is Custom, or an empty
+ string otherwise.
+
+ \sa role(), setRole()
+*/
+QString QSoftKeyAction::roleName() const
+{
+ Q_D(const QSoftKeyAction);
+ return d->roleName;
+}
+
+/*!
+ Sets the standard role associated with this action to \a role,
+ and also sets roleName() to the empty string.
+
+ \sa role(), roleName()
+*/
+void QSoftKeyAction::setRole(StandardRole role)
+{
+ Q_D(QSoftKeyAction);
+ d->role = role;
+ d->roleName = QString();
+ emit changed();
+}
+
+/*!
+ Sets the custom roleName() associated with this action to \a role,
+ and also sets role() to Custom.
+
+ \sa role(), roleName()
+*/
+void QSoftKeyAction::setRole(const QString& role)
+{
+ Q_D(QSoftKeyAction);
+ d->role = Custom;
+ d->roleName = role;
+ emit changed();
+}
+
+int QSoftKeyAction::nativePosition() const
+{
+ Q_D(const QSoftKeyAction);
+ return d->nativePosition;
+}
+
+void QSoftKeyAction::setNativePosition(int position)
+{
+ Q_D(QSoftKeyAction);
+ d->nativePosition = position;
+}
+
+int QSoftKeyAction::qtContextKey() const
+{
+ Q_D(const QSoftKeyAction);
+ return d->qtContextKey;
+}
+
+void QSoftKeyAction::setQtContextKey(int key)
+{
+ Q_D(QSoftKeyAction);
+ d->qtContextKey = key;
+}
diff --git a/src/gui/widgets/qsoftkeyaction.h b/src/gui/widgets/qsoftkeyaction.h
new file mode 100644
index 0000000..77aeac0
--- /dev/null
+++ b/src/gui/widgets/qsoftkeyaction.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** 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 QSOFTKEYACTION_H
+#define QSOFTKEYACTION_H
+
+#include <QtGui/qaction.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QSoftKeyActionPrivate;
+
+class Q_GUI_EXPORT QSoftKeyAction : public QAction
+{
+ Q_OBJECT
+public:
+ enum StandardRole {
+ Options=0,
+ Select,
+ Back,
+ Next,
+ Previous,
+ Ok,
+ Cancel,
+ Edit,
+ View,
+ BackSpace,
+ EndEdit,
+ RevertEdit,
+ Deselect,
+ Finish,
+ Menu,
+ ContextMenu,
+ Custom
+ };
+
+ QSoftKeyAction(QObject *parent);
+ QSoftKeyAction(StandardRole role, QObject *parent);
+ QSoftKeyAction(const QString &text, QObject *parent);
+ QSoftKeyAction(StandardRole role, const QString &text, QObject *parent);
+ QSoftKeyAction(const QIcon &icon, const QString &text, QObject *parent);
+ QSoftKeyAction(StandardRole role, const QIcon &icon, const QString &text, QObject *parent);
+ ~QSoftKeyAction();
+
+ StandardRole role() const;
+ QString roleName() const;
+
+ void setRole(StandardRole role);
+ void setRole(const QString &role);
+ int nativePosition() const;
+ void setNativePosition(int position);
+ int qtContextKey() const;
+ void setQtContextKey(int position);
+
+private:
+ Q_DECLARE_PRIVATE(QSoftKeyAction)
+ Q_DISABLE_COPY(QSoftKeyAction)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSOFTKEYACTION_H
diff --git a/src/gui/widgets/qsoftkeystack.cpp b/src/gui/widgets/qsoftkeystack.cpp
new file mode 100644
index 0000000..9a5a66c
--- /dev/null
+++ b/src/gui/widgets/qsoftkeystack.cpp
@@ -0,0 +1,304 @@
+/****************************************************************************
+**
+** 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 "qsoftkeystack.h"
+#include "qsoftkeystack_p.h"
+#include "qapplication.h"
+#include "qmainwindow.h"
+#include "qevent.h"
+
+#if !defined(Q_WS_S60)
+#include "qtoolbar.h"
+#endif
+
+static bool isSame(const QSoftkeySet& a, const QSoftkeySet& b)
+{
+ bool isSame=true;
+ if ( a.count() != b.count())
+ return false;
+ int index=0;
+ while (index<a.count()) {
+ if (a.at(index)->role() != b.at(index)->role())
+ return false;
+ if (a.at(index)->text().compare(b.at(index)->text())!=0)
+ return false;
+ index++;
+ }
+ return true;
+}
+
+QSoftKeyStackPrivate::QSoftKeyStackPrivate()
+{
+
+}
+
+QSoftKeyStackPrivate::~QSoftKeyStackPrivate()
+{
+
+}
+
+void QSoftKeyStackPrivate::push(QSoftKeyAction *softKey)
+{
+ QSoftkeySet softKeySet;
+ softKeySet.append(softKey);
+ push(softKeySet);
+}
+
+void QSoftKeyStackPrivate::push(const QList<QSoftKeyAction*> &softkeys)
+{
+ QSoftkeySet softKeySet(softkeys);
+ softKeyStack.push(softKeySet);
+ setNativeSoftKeys();
+}
+
+void QSoftKeyStackPrivate::pop()
+{
+ qDeleteAll(softKeyStack.pop());
+ setNativeSoftKeys();
+}
+
+void QSoftKeyStackPrivate::popandPush(QSoftKeyAction *softKey)
+{
+ QSoftkeySet newSoftKeySet;
+ newSoftKeySet.append(softKey);
+ popandPush(newSoftKeySet);
+}
+
+void QSoftKeyStackPrivate::popandPush(const QList<QSoftKeyAction*> &softkeys)
+{
+ QSoftkeySet oldSoftKeySet = softKeyStack.pop();
+ QSoftkeySet newSoftKeySet(softkeys);
+ softKeyStack.push(newSoftKeySet);
+#ifdef Q_WS_S60
+ // Don't flicker on Symbian.
+ // Platforms that use QActions as native SoftKeys must always call setNativeSoftKeys
+ // Otherwise the following deletion of oldSoftKeySet would remove the softkeys
+ if (!isSame(oldSoftKeySet, newSoftKeySet))
+#endif
+ setNativeSoftKeys();
+ qDeleteAll(oldSoftKeySet);
+}
+
+const QSoftkeySet& QSoftKeyStackPrivate::top()
+{
+ return softKeyStack.top();
+}
+
+bool QSoftKeyStackPrivate::isEmpty()
+{
+ return softKeyStack.isEmpty();
+}
+
+QSoftKeyStack::QSoftKeyStack(QWidget *parent)
+ : QObject(*new QSoftKeyStackPrivate, parent)
+{
+ connect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), SLOT(handleFocusChanged(QWidget*, QWidget*)));
+}
+
+QSoftKeyStack::~QSoftKeyStack()
+{
+}
+
+void QSoftKeyStack::push(QSoftKeyAction *softKey)
+{
+ Q_D(QSoftKeyStack);
+ d->push(softKey);
+}
+
+void QSoftKeyStack::push(const QList<QSoftKeyAction*> &softKeys)
+{
+ Q_D(QSoftKeyStack);
+ d->push(softKeys);
+}
+
+void QSoftKeyStack::pop()
+{
+ Q_D(QSoftKeyStack);
+ d->pop();
+}
+
+void QSoftKeyStack::popandPush(QSoftKeyAction *softKey)
+{
+ Q_D(QSoftKeyStack);
+ d->popandPush(softKey);
+}
+
+void QSoftKeyStack::popandPush(const QList<QSoftKeyAction*> &softkeys)
+{
+ Q_D(QSoftKeyStack);
+ d->popandPush(softkeys);
+}
+
+const QSoftkeySet& QSoftKeyStack::top()
+{
+ Q_D(QSoftKeyStack);
+ return d->top();
+}
+
+bool QSoftKeyStack::isEmpty()
+{
+ Q_D(QSoftKeyStack);
+ return d->isEmpty();
+}
+
+QList<QSoftKeyAction*> menuActionList(QWidget *widget)
+{
+ QList<QSoftKeyAction*> result;
+
+ QSoftKeyAction* menu = new QSoftKeyAction(QSoftKeyAction::Menu, QString::fromLatin1("Menu"), widget);
+ result.append(menu);
+ const Qt::ContextMenuPolicy policy = widget->contextMenuPolicy();
+ if (policy != Qt::NoContextMenu && policy != Qt::PreventContextMenu ) {
+ QSoftKeyAction* contextMenu = new QSoftKeyAction(QSoftKeyAction::ContextMenu, QString::fromLatin1("ContextMenu"), widget);
+ result.append(contextMenu);
+ }
+
+ return result;
+}
+
+void QSoftKeyStack::handleFocusChanged(QWidget *old, QWidget *now)
+{
+ if (!now)
+ return;
+ QWidget *w = qApp->activeWindow();
+ QMainWindow *mainWindow = qobject_cast<QMainWindow*>(w);
+ if( !mainWindow)
+ return;
+ if (!mainWindow->hasSoftKeyStack())
+ return;
+ QSoftKeyStack* softKeyStack = mainWindow->softKeyStack();
+ if (mainWindow->menuWidget()) {
+ QList<QSoftKeyAction*> actionList = menuActionList(now);
+ if (old)
+ softKeyStack->popandPush(actionList);
+ else
+ softKeyStack->push(actionList);
+ }
+}
+
+QMainWindow *QSoftKeyStack::mainWindowOfWidget(QWidget *widget)
+{
+ for (QWidget *widgetParent = widget; widgetParent; widgetParent = widgetParent->parentWidget())
+ if (QMainWindow *mainWindow = qobject_cast<QMainWindow*>(widgetParent))
+ return mainWindow;
+
+ return 0;
+}
+
+QSoftKeyStack *QSoftKeyStack::softKeyStackOfWidget(QWidget *widget)
+{
+ QMainWindow *mainWindow = mainWindowOfWidget(widget);
+ return (mainWindow && mainWindow->hasSoftKeyStack()) ? mainWindow->softKeyStack() : 0;
+}
+
+#if !defined(Q_WS_S60)
+void QSoftKeyStackPrivate::handleSoftKeyPress(int command)
+{
+ Q_UNUSED(command)
+}
+
+QToolBar* softKeyToolBar(QMainWindow *mainWindow)
+{
+ Q_ASSERT(mainWindow);
+ const QString toolBarName = QString::fromLatin1("SoftKeyToolBarForDebugging");
+ QToolBar *result = 0;
+ foreach (QObject *child, mainWindow->children()) {
+ result = qobject_cast<QToolBar*>(child);
+ if (result && result->objectName() == toolBarName)
+ return result;
+ }
+ result = mainWindow->addToolBar(toolBarName);
+ result->setObjectName(toolBarName);
+ return result;
+}
+
+void QSoftKeyStackPrivate::setNativeSoftKeys()
+{
+ Q_Q(QSoftKeyStack);
+ QMainWindow *parent = qobject_cast<QMainWindow*>(q->parent());
+ if (!parent)
+ return;
+ QToolBar* toolbar = softKeyToolBar(parent);
+ toolbar->clear();
+ foreach (const QSoftkeySet &set, softKeyStack) {
+ foreach (QSoftKeyAction *skAction, set)
+ toolbar->addAction(skAction);
+ toolbar->addSeparator();
+ }
+ if (toolbar->actions().isEmpty()) {
+ parent->removeToolBar(toolbar);
+ delete toolbar;
+ }
+}
+#endif // !defined(Q_WS_S60)
+
+QKeyEventSoftKey::QKeyEventSoftKey(QSoftKeyAction *softKeyAction, Qt::Key key, QObject *parent)
+ : QObject(parent)
+ , m_softKeyAction(softKeyAction)
+ , m_key(key)
+{
+}
+
+void QKeyEventSoftKey::addSoftKey(QSoftKeyAction::StandardRole standardRole, Qt::Key key, QWidget *actionWidget)
+{
+ QSoftKeyStack *stack = QSoftKeyStack::softKeyStackOfWidget(actionWidget);
+ if (!stack)
+ return;
+ QSoftKeyAction *action = new QSoftKeyAction(standardRole, actionWidget);
+ QKeyEventSoftKey *softKey = new QKeyEventSoftKey(action, key, actionWidget);
+ connect(action, SIGNAL(triggered()), softKey, SLOT(sendKeyEvent()));
+ connect(action, SIGNAL(destroyed()), softKey, SLOT(deleteLater()));
+ stack->popandPush(action);
+}
+
+void QKeyEventSoftKey::removeSoftkey(QWidget *focussedWidget)
+{
+ QSoftKeyStack *stack = QSoftKeyStack::softKeyStackOfWidget(focussedWidget);
+ if (!stack)
+ return;
+ QList<QSoftKeyAction*> actionList = menuActionList(focussedWidget);
+ stack->popandPush(actionList);
+}
+
+void QKeyEventSoftKey::sendKeyEvent()
+{
+ QApplication::postEvent(parent(), new QKeyEvent(QEvent::KeyPress, m_key, Qt::NoModifier));
+}
diff --git a/src/gui/widgets/qsoftkeystack.h b/src/gui/widgets/qsoftkeystack.h
new file mode 100644
index 0000000..423da66
--- /dev/null
+++ b/src/gui/widgets/qsoftkeystack.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** 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 QSOFTKEYSTACK_H
+#define QSOFTKEYSTACK_H
+
+#include <QtGui/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#define QSoftkeySet QList <QSoftKeyAction*>
+
+class QSoftKeyStackPrivate;
+class QSoftKeyAction;
+class QMainWindow;
+
+class Q_GUI_EXPORT QSoftKeyStack : public QObject
+{
+ Q_OBJECT
+public:
+ QSoftKeyStack(QWidget *parent);
+ ~QSoftKeyStack();
+
+ void push(QSoftKeyAction *softKey);
+ void push(const QList<QSoftKeyAction*> &softkeys);
+ void pop();
+ void popandPush(QSoftKeyAction *softKey);
+ void popandPush(const QList<QSoftKeyAction*> &softkeys);
+ const QSoftkeySet& top();
+ bool isEmpty();
+
+ static QMainWindow *mainWindowOfWidget(QWidget *widget);
+ static QSoftKeyStack *softKeyStackOfWidget(QWidget *widget);
+
+private Q_SLOTS:
+ void handleFocusChanged(QWidget *old, QWidget *now);
+
+private:
+ Q_DECLARE_PRIVATE(QSoftKeyStack)
+ Q_DISABLE_COPY(QSoftKeyStack)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSOFTKEYSTACK_H
diff --git a/src/gui/widgets/qsoftkeystack_p.h b/src/gui/widgets/qsoftkeystack_p.h
new file mode 100644
index 0000000..4532515
--- /dev/null
+++ b/src/gui/widgets/qsoftkeystack_p.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** 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 QSOFTKEYSTACK_P_H
+#define QSOFTKEYSTACK_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 "qstack.h"
+#include <QtCore/private/qobject_p.h>
+
+#include "qsoftkeyaction.h"
+#include "qsoftkeystack.h"
+
+QT_BEGIN_NAMESPACE
+
+// The following 2 defines may only be needed for s60. To be seen.
+#define SOFTKEYSTART 5000
+#define SOFTKEYEND (5000 + Qt::Key_Context4-Qt::Key_Context1)
+
+#define QSoftkeySet QList <QSoftKeyAction*>
+
+class QSoftKeyStackPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QSoftKeyStack)
+public:
+ QSoftKeyStackPrivate();
+ ~QSoftKeyStackPrivate();
+
+ void push(QSoftKeyAction *softKey);
+ void push(const QList<QSoftKeyAction*> &softKeys);
+ void pop();
+ void popandPush(QSoftKeyAction *softKey);
+ void popandPush(const QList<QSoftKeyAction*> &softkeys);
+ const QSoftkeySet& top();
+ bool isEmpty();
+ static void handleSoftKeyPress(int command);
+
+private:
+ void mapSoftKeys(const QSoftkeySet &top);
+ void setNativeSoftKeys();
+
+private:
+ QStack <QSoftkeySet> softKeyStack;
+};
+
+class QKeyEventSoftKey : QObject
+{
+ Q_OBJECT
+public:
+ QKeyEventSoftKey(QSoftKeyAction *softKeyAction, Qt::Key key, QObject *parent);
+ static void addSoftKey(QSoftKeyAction::StandardRole standardRole, Qt::Key key, QWidget *actionWidget);
+ static void removeSoftkey(QWidget *focussedWidget);
+private:
+ QSoftKeyAction *m_softKeyAction;
+ Qt::Key m_key;
+private Q_SLOTS:
+ void sendKeyEvent();
+};
+
+QT_END_NAMESPACE
+
+#endif // QSOFTKEYSTACK_P_H
diff --git a/src/gui/widgets/qsoftkeystack_s60.cpp b/src/gui/widgets/qsoftkeystack_s60.cpp
new file mode 100644
index 0000000..8dfd5dd
--- /dev/null
+++ b/src/gui/widgets/qsoftkeystack_s60.cpp
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** 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 <eikenv.h>
+#include <eikbtgpc.h>
+#include <eikappui.h>
+#include <aknappui.h>
+#include <avkon.rsg>
+
+#include "private/qcore_symbian_p.h"
+
+#include "qsoftkeystack_p.h"
+#include "qapplication.h"
+#include "qmainwindow.h"
+
+void QSoftKeyStackPrivate::mapSoftKeys(const QSoftkeySet &top)
+{
+ if (top.count() == 1) {
+ top.at(0)->setNativePosition(2);
+ top.at(0)->setQtContextKey(Qt::Key_Context1);
+ }
+ else {
+ // FIX THIS
+ // veryWeirdMagic is needes as s60 5th edition sdk always panics if cba is set with index 1, this hops over it
+ // This needs further investigation why so that the hack can be removed
+ int veryWeirdMagic = 0;
+ for (int index = 0; index < top.count(); index++) {
+ top.at(index)->setNativePosition(index + veryWeirdMagic);
+ top.at(index)->setQtContextKey(Qt::Key_Context1 + index);
+ if (veryWeirdMagic == 0)
+ veryWeirdMagic = 1;
+ }
+ }
+}
+
+void QSoftKeyStackPrivate::setNativeSoftKeys()
+{
+ CCoeAppUi* appui = CEikonEnv::Static()->AppUi();
+ CAknAppUi* aknAppUi = static_cast <CAknAppUi*>(appui);
+ CEikButtonGroupContainer* nativeContainer = aknAppUi->Cba();
+ nativeContainer->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS);
+ if (softKeyStack.isEmpty())
+ return;
+
+ const QSoftkeySet top = softKeyStack.top();
+ mapSoftKeys(top);
+
+ for (int index = 0; index < top.count(); index++) {
+ const QSoftKeyAction* softKeyAction = top.at(index);
+ if (softKeyAction->role() != QSoftKeyAction::ContextMenu) {
+
+ HBufC* text = qt_QString2HBufCNewL(softKeyAction->text());
+ CleanupStack::PushL(text);
+ if (softKeyAction->role() == QSoftKeyAction::Menu) {
+ nativeContainer->SetCommandL(softKeyAction->nativePosition(), EAknSoftkeyOptions, *text);
+ } else {
+ nativeContainer->SetCommandL(softKeyAction->nativePosition(), SOFTKEYSTART + softKeyAction->qtContextKey()-Qt::Key_Context1, *text);
+ }
+ CleanupStack::PopAndDestroy();
+ }
+ }
+}
+
+void QSoftKeyStackPrivate::handleSoftKeyPress(int command)
+{
+ const QMainWindow *activeMainWindow =
+ qobject_cast<const QMainWindow*>(QApplication::activeWindow());
+ if (!activeMainWindow)
+ return;
+ QSoftKeyStackPrivate *d_ptr = activeMainWindow->softKeyStack()->d_func();
+
+ const QSoftkeySet top = d_ptr->softKeyStack.top();
+ int index = command-SOFTKEYSTART;
+ if (index < 0 || index >= top.count()) {
+ // ### FIX THIS, add proper error handling, now fail quietly
+ return;
+ }
+
+ top.at(index)->activate(QAction::Trigger);
+}
+
diff --git a/src/gui/widgets/widgets.pri b/src/gui/widgets/widgets.pri
index fc57944..0c0641a 100644
--- a/src/gui/widgets/widgets.pri
+++ b/src/gui/widgets/widgets.pri
@@ -78,8 +78,10 @@ HEADERS += \
widgets/qtoolbararealayout_p.h \
widgets/qplaintextedit.h \
widgets/qplaintextedit_p.h \
- widgets/qprintpreviewwidget.h
-
+ widgets/qprintpreviewwidget.h \
+ widgets/qsoftkeyaction.h \
+ widgets/qsoftkeystack.h \
+ widgets/qsoftkeystack_p.h
SOURCES += \
widgets/qabstractbutton.cpp \
widgets/qabstractslider.cpp \
@@ -138,8 +140,9 @@ SOURCES += \
widgets/qwidgetanimator.cpp \
widgets/qtoolbararealayout.cpp \
widgets/qplaintextedit.cpp \
- widgets/qprintpreviewwidget.cpp
-
+ widgets/qprintpreviewwidget.cpp \
+ widgets/qsoftkeyaction.cpp \
+ widgets/qsoftkeystack.cpp
!embedded:mac {
HEADERS += widgets/qmacnativewidget_mac.h \
@@ -162,5 +165,7 @@ wince*: {
}
symbian*: {
- SOURCES += widgets/qmenu_symbian.cpp
+ SOURCES += \
+ widgets/qmenu_symbian.cpp \
+ widgets/qsoftkeystack_s60.cpp
}