summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/widgets/stylesheet/mainwindow.cpp3
-rw-r--r--src/gui/kernel/qapplication_s60.cpp16
-rw-r--r--src/gui/softkeys/main.cpp125
-rw-r--r--src/gui/softkeys/softkeys.pro2
-rw-r--r--src/gui/styles/qs60style.cpp3
-rw-r--r--src/gui/widgets/qmainwindow.cpp47
-rw-r--r--src/gui/widgets/qmainwindow.h11
-rw-r--r--src/gui/widgets/qmenu_symbian.cpp79
-rw-r--r--src/gui/widgets/qmenubar_p.h1
-rw-r--r--src/gui/widgets/qsoftkeyaction.cpp205
-rw-r--r--src/gui/widgets/qsoftkeyaction.h106
-rw-r--r--src/gui/widgets/qsoftkeystack.cpp166
-rw-r--r--src/gui/widgets/qsoftkeystack.h84
-rw-r--r--src/gui/widgets/qsoftkeystack_p.h93
-rw-r--r--src/gui/widgets/qsoftkeystack_s60.cpp111
-rw-r--r--src/gui/widgets/widgets.pri11
16 files changed, 1029 insertions, 34 deletions
diff --git a/examples/widgets/stylesheet/mainwindow.cpp b/examples/widgets/stylesheet/mainwindow.cpp
index a1307a8..a0a38ad 100644
--- a/examples/widgets/stylesheet/mainwindow.cpp
+++ b/examples/widgets/stylesheet/mainwindow.cpp
@@ -46,6 +46,9 @@
MainWindow::MainWindow()
{
+ QSoftKeyStack* stack = new QSoftKeyStack(this);
+ setSoftKeyStack(stack);
+
ui.setupUi(this);
ui.nameLabel->setProperty("class", "mandatory QLabel");
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index dd51fcd..db67fd8 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -28,6 +28,9 @@
#include "private/qwindowsurface_s60_p.h"
#include "qpaintengine.h"
#include "qmenubar.h"
+#include "qmainwindow.h"
+#include "qsoftkeystack.h"
+#include "private/qsoftkeystack_p.h"
#include "apgwgnam.h" // For CApaWindowGroupName
#include <MdaAudioTonePlayer.h> // For CMdaAudioToneUtility
@@ -1024,13 +1027,18 @@ void QApplication::s60HandleCommandL(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
- QMenuBar::symbianCommands(command);
+ if (command >= SOFTKEYSTART && command <= SOFTKEYEND) {
+ const QMainWindow *activeMainWindow =
+ qobject_cast<const QMainWindow*>(QApplication::activeWindow());
+ if (activeMainWindow)
+ activeMainWindow->softKeyStack()->handleSoftKeyPress(command);
+ } else {
+ QMenuBar::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/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp
index c082125..7ed53f2 100644
--- a/src/gui/styles/qs60style.cpp
+++ b/src/gui/styles/qs60style.cpp
@@ -2460,12 +2460,13 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple
ret = QCommonStyle::subControlRect(control, option, scontrol, widget);
switch (scontrol) {
case SC_GroupBoxCheckBox: //fallthrough
- case SC_GroupBoxLabel:
+ case SC_GroupBoxLabel: {
//slightly indent text and boxes, so that dialog border does not mess with them.
const int horizontalSpacing =
QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
const int bottomMargin = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutBottomMargin);
ret.adjust(2,horizontalSpacing-3,0,0);
+ }
break;
case SC_GroupBoxFrame: {
const QRect textBox = subControlRect(control, option, SC_GroupBoxLabel, widget);
diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp
index 558ba42..e12b879 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()
@@ -514,6 +525,42 @@ 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 stackfor 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;
+}
+#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..e2dcd5e 100644
--- a/src/gui/widgets/qmainwindow.h
+++ b/src/gui/widgets/qmainwindow.h
@@ -59,7 +59,9 @@ class QMenuBar;
class QStatusBar;
class QToolBar;
class QMenu;
-
+#ifndef QT_NO_SOFTKEYSTACK
+class QSoftKeyStack;
+#endif
class Q_GUI_EXPORT QMainWindow : public QWidget
{
Q_OBJECT
@@ -129,7 +131,12 @@ public:
QWidget *menuWidget() const;
void setMenuWidget(QWidget *menubar);
#endif
-
+
+#ifndef QT_NO_SOFTKEYSTACK
+ QSoftKeyStack *softKeyStack() const;
+ void setSoftKeyStack(QSoftKeyStack *softKeyStack);
+#endif
+
#ifndef QT_NO_STATUSBAR
QStatusBar *statusBar() const;
void setStatusBar(QStatusBar *statusbar);
diff --git a/src/gui/widgets/qmenu_symbian.cpp b/src/gui/widgets/qmenu_symbian.cpp
index 86affe3..1cff1bf 100644
--- a/src/gui/widgets/qmenu_symbian.cpp
+++ b/src/gui/widgets/qmenu_symbian.cpp
@@ -26,12 +26,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)
@@ -48,6 +48,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()
{
@@ -174,24 +178,28 @@ 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);
+ QSoftKeyStack* softKeyStack = mainWindow->softKeyStack();
+ 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 );
@@ -199,7 +207,7 @@ static void rebuildMenu()
return;
mb->symbian_menubar->rebuild();
}
- }
+}
Q_GUI_EXPORT void qt_symbian_show_toplevel( CEikMenuPane* menuPane)
{
@@ -227,6 +235,11 @@ void QMenu::symbianCommands(int command)
void QMenuBar::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) {
bool result = nativeMenuBars.at(i)->d_func()->symbianCommands(command);
@@ -371,22 +384,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 d562cd9..1b9bac7 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;
bool symbianCommands(int command);
diff --git a/src/gui/widgets/qsoftkeyaction.cpp b/src/gui/widgets/qsoftkeyaction.cpp
new file mode 100644
index 0000000..583cf65
--- /dev/null
+++ b/src/gui/widgets/qsoftkeyaction.cpp
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** 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;
+ }
+
+ QSoftKeyAction::StandardRole role;
+ QString roleName;
+ int nativePosition;
+ int qtContextKey;
+};
+
+/*!
+ \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;
+}
+
+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..cd17171
--- /dev/null
+++ b/src/gui/widgets/qsoftkeystack.cpp
@@ -0,0 +1,166 @@
+/****************************************************************************
+**
+** 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"
+
+QSoftKeyStackPrivate::QSoftKeyStackPrivate()
+{
+
+}
+
+QSoftKeyStackPrivate::~QSoftKeyStackPrivate()
+{
+
+}
+
+void QSoftKeyStackPrivate::push(QSoftKeyAction *softKey)
+{
+ QSoftkeySet softKeySet;
+ softKeySet.append(softKey);
+ softKeyStack.push(softKeySet);
+ setNativeSoftKeys();
+
+}
+void QSoftKeyStackPrivate::push(const QList<QSoftKeyAction*> &softkeys)
+{
+ QSoftkeySet softKeySet(softkeys);
+ softKeyStack.push(softKeySet);
+ setNativeSoftKeys();
+}
+
+void QSoftKeyStackPrivate::pop()
+{
+ softKeyStack.pop();
+ setNativeSoftKeys();
+}
+
+const QSoftkeySet& QSoftKeyStackPrivate::top()
+{
+ return softKeyStack.top();
+}
+
+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();
+}
+
+const QSoftkeySet& QSoftKeyStack::top()
+{
+ Q_D(QSoftKeyStack);
+ return d->top();
+}
+
+void QSoftKeyStack::handleFocusChanged(QWidget *old, QWidget *now)
+{
+ if (!now)
+ return;
+ QWidget *w = qApp->activeWindow();
+ QMainWindow *mainWindow = qobject_cast<QMainWindow*>(w);
+ if( !mainWindow)
+ return;
+ QSoftKeyStack* softKeyStack = mainWindow->softKeyStack();
+ if (old)
+ softKeyStack->pop();
+
+ Qt::ContextMenuPolicy policy = now->contextMenuPolicy();
+ if (policy != Qt::NoContextMenu && policy != Qt::PreventContextMenu ) {
+ QList<QSoftKeyAction*> actionList;
+ QSoftKeyAction* menu = new QSoftKeyAction(QSoftKeyAction::Menu, QString("Menu"), now);
+ QSoftKeyAction* contextMenu = new QSoftKeyAction(QSoftKeyAction::ContextMenu, QString("ContextMenu"), now);
+ actionList.append(menu);
+ actionList.append(contextMenu);
+ softKeyStack->push(actionList);
+ }
+
+/* if (!now)
+ return;
+ bool nowInOurMainWindow = false;
+ const QMainWindow *ourMainWindow = qobject_cast<const QMainWindow*>(parent());
+ Q_ASSERT(ourMainWindow);
+
+ // "ourMainWindow" in parent chain of "now"? Isn't there a helper in Qt for this?
+ QWidget *nowParent = now;
+ while (nowParent = nowParent->parentWidget()) {
+ if (nowParent == ourMainWindow) {
+ nowInOurMainWindow = true;
+ break;
+ }
+ }
+
+ if (!nowInOurMainWindow)
+ return;
+
+ QList<QAction*> actions = now->actions();
+ // Do something with these actions.
+*/
+}
+
+void QSoftKeyStack::handleSoftKeyPress(int command)
+{
+ Q_D(QSoftKeyStack);
+ d->handleSoftKeyPress(command);
+}
diff --git a/src/gui/widgets/qsoftkeystack.h b/src/gui/widgets/qsoftkeystack.h
new file mode 100644
index 0000000..c9a05c3
--- /dev/null
+++ b/src/gui/widgets/qsoftkeystack.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** 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 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();
+ const QSoftkeySet& top();
+
+ void handleSoftKeyPress(int command);
+
+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..2469648
--- /dev/null
+++ b/src/gui/widgets/qsoftkeystack_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** 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
+{
+public:
+ QSoftKeyStackPrivate();
+ ~QSoftKeyStackPrivate();
+
+ void push(QSoftKeyAction *softKey);
+ void push(const QList<QSoftKeyAction*> &softKeys);
+ void pop();
+ const QSoftkeySet& top();
+ void handleSoftKeyPress(int command);
+
+private:
+ void mapSoftKeys(const QSoftkeySet &top);
+ void setNativeSoftKeys();
+
+private:
+ QStack <QSoftkeySet> softKeyStack;
+};
+
+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..a6b885e
--- /dev/null
+++ b/src/gui/widgets/qsoftkeystack_s60.cpp
@@ -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$
+**
+****************************************************************************/
+
+#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"
+
+void QSoftKeyStackPrivate::mapSoftKeys(const QSoftkeySet &top)
+{
+ if (top.count() == 1) {
+ top.at(0)->setNativePosition(2);
+ top.at(0)->setQtContextKey(Qt::Key_Context2);
+ }
+ 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 QSoftkeySet top = 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..c9e68a1 100644
--- a/src/gui/widgets/widgets.pri
+++ b/src/gui/widgets/widgets.pri
@@ -162,5 +162,14 @@ wince*: {
}
symbian*: {
- SOURCES += widgets/qmenu_symbian.cpp
+ HEADERS += \
+ widgets/qsoftkeyaction.h \
+ widgets/qsoftkeystack.h \
+ widgets/qsoftkeystack_p.h
+
+ SOURCES += \
+ widgets/qmenu_symbian.cpp \
+ widgets/qsoftkeyaction.cpp \
+ widgets/qsoftkeystack.cpp \
+ widgets/qsoftkeystack_s60.cpp
}