diff options
-rw-r--r-- | examples/widgets/stylesheet/mainwindow.cpp | 3 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_s60.cpp | 16 | ||||
-rw-r--r-- | src/gui/softkeys/main.cpp | 125 | ||||
-rw-r--r-- | src/gui/softkeys/softkeys.pro | 2 | ||||
-rw-r--r-- | src/gui/styles/qs60style.cpp | 3 | ||||
-rw-r--r-- | src/gui/widgets/qmainwindow.cpp | 47 | ||||
-rw-r--r-- | src/gui/widgets/qmainwindow.h | 11 | ||||
-rw-r--r-- | src/gui/widgets/qmenu_symbian.cpp | 79 | ||||
-rw-r--r-- | src/gui/widgets/qmenubar_p.h | 1 | ||||
-rw-r--r-- | src/gui/widgets/qsoftkeyaction.cpp | 205 | ||||
-rw-r--r-- | src/gui/widgets/qsoftkeyaction.h | 106 | ||||
-rw-r--r-- | src/gui/widgets/qsoftkeystack.cpp | 166 | ||||
-rw-r--r-- | src/gui/widgets/qsoftkeystack.h | 84 | ||||
-rw-r--r-- | src/gui/widgets/qsoftkeystack_p.h | 93 | ||||
-rw-r--r-- | src/gui/widgets/qsoftkeystack_s60.cpp | 111 | ||||
-rw-r--r-- | src/gui/widgets/widgets.pri | 11 |
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 } |