summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qsoftkeymanager.cpp
diff options
context:
space:
mode:
authorJanne Anttila <janne.anttila@digia.com>2010-03-23 10:36:22 +0200
committerJanne Anttila <janne.anttila@digia.com>2010-03-23 10:37:38 +0200
commit262e98f9a29385f99cd6f768632264e0b621dc01 (patch)
tree3c8d0745912d25d9ce0fcc5e72a4bf33a298c626 /src/gui/kernel/qsoftkeymanager.cpp
parentae3d95f872c8bd2e192c58d7c7c830a3d2e4bc43 (diff)
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/qsoftkeymanager.cpp')
-rw-r--r--src/gui/kernel/qsoftkeymanager.cpp60
1 files changed, 53 insertions, 7 deletions
diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp
index c9a94ee7b7..d324c769f8 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