diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/itemviews/qabstractitemview.cpp | 11 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_s60.cpp | 12 | ||||
-rw-r--r-- | src/gui/softkeys/main.cpp | 125 | ||||
-rw-r--r-- | src/gui/softkeys/softkeys.pro | 2 | ||||
-rw-r--r-- | src/gui/widgets/qcombobox.cpp | 9 | ||||
-rw-r--r-- | src/gui/widgets/qmainwindow.cpp | 61 | ||||
-rw-r--r-- | src/gui/widgets/qmainwindow.h | 9 | ||||
-rw-r--r-- | src/gui/widgets/qmenu.cpp | 16 | ||||
-rw-r--r-- | src/gui/widgets/qmenu_symbian.cpp | 82 | ||||
-rw-r--r-- | src/gui/widgets/qmenubar_p.h | 1 | ||||
-rw-r--r-- | src/gui/widgets/qsoftkeyaction.cpp | 234 | ||||
-rw-r--r-- | src/gui/widgets/qsoftkeyaction.h | 106 | ||||
-rw-r--r-- | src/gui/widgets/qsoftkeystack.cpp | 304 | ||||
-rw-r--r-- | src/gui/widgets/qsoftkeystack.h | 89 | ||||
-rw-r--r-- | src/gui/widgets/qsoftkeystack_p.h | 111 | ||||
-rw-r--r-- | src/gui/widgets/qsoftkeystack_s60.cpp | 119 | ||||
-rw-r--r-- | src/gui/widgets/widgets.pri | 15 |
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 } |