diff options
author | Janne Anttila <janne.anttila@digia.com> | 2010-03-23 08:36:22 (GMT) |
---|---|---|
committer | Janne Anttila <janne.anttila@digia.com> | 2010-03-23 08:37:38 (GMT) |
commit | 262e98f9a29385f99cd6f768632264e0b621dc01 (patch) | |
tree | 3c8d0745912d25d9ce0fcc5e72a4bf33a298c626 /src/gui/kernel | |
parent | ae3d95f872c8bd2e192c58d7c7c830a3d2e4bc43 (diff) | |
download | Qt-262e98f9a29385f99cd6f768632264e0b621dc01.zip Qt-262e98f9a29385f99cd6f768632264e0b621dc01.tar.gz Qt-262e98f9a29385f99cd6f768632264e0b621dc01.tar.bz2 |
Fixed S60 softkey implementation to use popup/modal dialog softkeys.
Previously softkey implementation assumed that source for softkey
actions is focused widget or activewindow if there is no focused
widget. Since for example pop-up menu does not take focus immediately
in touch enabled devices, the underlying widget softkeys were visible
and usable when menu was open. This lead to problem that underlying
widget could be interacted via softkeys when popup menu was open.
For example as reported in QTBUG-8688, it was possible to close the
underlying filedialog from which the currently active context menu was
launched. It was also possible to open "Options" menu of underlying
widget when context menu was open, leading to situation where several
context menus could be launched via "Actions" item of "Options" menu.
This was reported as an issue: QTBUG-6167
In addition when user started navigating in context menu via keypad,
the menu got focus and softkeys changed to partially correct. Only
partially correct, since context menu "Select" action and "Options"
action had same priority and both associated to LSK. In addition the
context menu action "Cancel" associated to RSK was set to invisible,
meaning that it was also disabled and appeared in sofkeys as dimmed.
All of these issues were fixed by making making the popup and modal
dialogs highest priority softkey source. In case the focused widget
is inside popup or modal dialog it is being used as an initial softkey
source. In addition the softkeys created with
QSoftKeyManager::createAction or QSoftKeyManager::createKeyedAction are
now by default invisible i.e. not visible in context menu and have
special property set to make them still normally enabled in softkeys.
Task-number: QTBUG-6167
Task-number: QTBUG-8688
Task-number: QTBUG-9144
Reviewed-by: Sami Merila
Diffstat (limited to 'src/gui/kernel')
-rw-r--r-- | src/gui/kernel/qsoftkeymanager.cpp | 60 | ||||
-rw-r--r-- | src/gui/kernel/qsoftkeymanager_p.h | 5 | ||||
-rw-r--r-- | src/gui/kernel/qsoftkeymanager_s60.cpp | 7 |
3 files changed, 59 insertions, 13 deletions
diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp index c9a94ee..d324c76 100644 --- a/src/gui/kernel/qsoftkeymanager.cpp +++ b/src/gui/kernel/qsoftkeymanager.cpp @@ -115,6 +115,8 @@ QAction *QSoftKeyManager::createAction(StandardSoftKey standardKey, QWidget *act break; } action->setSoftKeyRole(softKeyRole); + action->setVisible(false); + setForceEnabledInSoftkeys(action); return action; } @@ -168,25 +170,55 @@ bool QSoftKeyManager::appendSoftkeys(const QWidget &source, int level) { Q_D(QSoftKeyManager); bool ret = false; - QList<QAction*> actions = source.actions(); - for (int i = 0; i < actions.count(); ++i) { - if (actions.at(i)->softKeyRole() != QAction::NoSoftKey) { - d->requestedSoftKeyActions.insert(level, actions.at(i)); + foreach(QAction *action, source.actions()) { + if (action->softKeyRole() != QAction::NoSoftKey + && (action->isVisible() || isForceEnabledInSofkeys(action))) { + d->requestedSoftKeyActions.insert(level, action); ret = true; } } return ret; } + +static bool isChildOf(const QWidget *c, const QWidget *p) +{ + while (c) { + if (c == p) + return true; + c = c->parentWidget(); + } + return false; +} + QWidget *QSoftKeyManager::softkeySource(QWidget *previousSource, bool& recursiveMerging) { Q_D(QSoftKeyManager); QWidget *source = NULL; if (!previousSource) { // Initial source is primarily focuswidget and secondarily activeWindow - source = QApplication::focusWidget(); - if (!source) - source = QApplication::activeWindow(); + const QWidget *focus = QApplication::focusWidget(); + const QWidget *popup = QApplication::activePopupWidget(); + if (popup) { + if (isChildOf(focus, popup)) + source = focus; + else + source = popup; + } + if (!source) { + const QWidget *modal = QApplication::activeModalWidget(); + if (modal) { + if (isChildOf(focus, modal)) + source = focus; + else + source = modal; + } + } + if (!source) { + source = focus; + if (!source) + source = QApplication::activeWindow(); + } } else { // Softkey merging is based on four criterias // 1. Implicit merging is used whenever focus widget does not specify any softkeys @@ -220,6 +252,20 @@ bool QSoftKeyManager::handleUpdateSoftKeys() return true; } +void QSoftKeyManager::setForceEnabledInSoftkeys(QAction *action) +{ + action->setProperty(FORCE_ENABLED_PROPERTY, QVariant(true)); +} + +bool QSoftKeyManager::isForceEnabledInSofkeys(QAction *action) +{ + bool ret = false; + QVariant property = action->property(FORCE_ENABLED_PROPERTY); + if (property.isValid() && property.toBool()) + ret = true; + return ret; +} + bool QSoftKeyManager::event(QEvent *e) { #ifndef QT_NO_ACTION diff --git a/src/gui/kernel/qsoftkeymanager_p.h b/src/gui/kernel/qsoftkeymanager_p.h index a6fe17e..a5b258b 100644 --- a/src/gui/kernel/qsoftkeymanager_p.h +++ b/src/gui/kernel/qsoftkeymanager_p.h @@ -63,7 +63,8 @@ QT_BEGIN_NAMESPACE class QSoftKeyManagerPrivate; -const char MENU_ACTION_PROPERTY[] = "_q_menuaction"; +const char MENU_ACTION_PROPERTY[] = "_q_menuAction"; +const char FORCE_ENABLED_PROPERTY[] = "_q_forceEnabledInSoftkeys"; class Q_AUTOTEST_EXPORT QSoftKeyManager : public QObject { @@ -88,6 +89,8 @@ public: static QAction *createAction(StandardSoftKey standardKey, QWidget *actionWidget); static QAction *createKeyedAction(StandardSoftKey standardKey, Qt::Key key, QWidget *actionWidget); static QString standardSoftKeyText(StandardSoftKey standardKey); + static void setForceEnabledInSoftkeys(QAction *action); + static bool isForceEnabledInSofkeys(QAction *action); protected: bool event(QEvent *e); diff --git a/src/gui/kernel/qsoftkeymanager_s60.cpp b/src/gui/kernel/qsoftkeymanager_s60.cpp index 3a0304c..9812d72 100644 --- a/src/gui/kernel/qsoftkeymanager_s60.cpp +++ b/src/gui/kernel/qsoftkeymanager_s60.cpp @@ -288,11 +288,7 @@ bool QSoftKeyManagerPrivateS60::setSoftkey(CEikButtonGroupContainer &cba, TPtrC nativeText = qt_QString2TPtrC(text); int command = S60_COMMAND_START + position; setNativeSoftkey(cba, position, command, nativeText); - // QMainWindow "Options" action is set to invisible in order it does not appear in context menu - // and all invisible actions are by default disabled. - // However we never want to dim options softkey, even it is set to invisible - QVariant property = action->property(MENU_ACTION_PROPERTY); - const bool dimmed = (property.isValid() && property.toBool()) ? false : !action->isEnabled(); + const bool dimmed = !action->isEnabled() && !QSoftKeyManager::isForceEnabledInSofkeys(action); cba.DimCommand(command, dimmed); realSoftKeyActions.insert(command, action); return true; @@ -335,6 +331,7 @@ bool QSoftKeyManagerPrivateS60::setRightSoftkey(CEikButtonGroupContainer &cba) cbaHasImage[RSK_POSITION] = false; } setNativeSoftkey(cba, RSK_POSITION, EAknSoftkeyExit, nativeText); + cba.DimCommand(EAknSoftkeyExit, false); return true; } } |