Qt 4.8
qsoftkeymanager.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qapplication.h"
43 #include "qevent.h"
44 #include "qbitmap.h"
45 #include "private/qsoftkeymanager_p.h"
46 #include "private/qaction_p.h"
47 #include "private/qsoftkeymanager_common_p.h"
48 
49 #ifdef Q_WS_S60
50 #include "private/qsoftkeymanager_s60_p.h"
51 #include "private/qt_s60_p.h"
52 #endif
53 
54 #ifndef QT_NO_SOFTKEYMANAGER
56 
58 
60 {
61  QString softKeyText;
62  switch (standardKey) {
63  case OkSoftKey:
64  softKeyText = QSoftKeyManager::tr("OK");
65  break;
66  case SelectSoftKey:
67  softKeyText = QSoftKeyManager::tr("Select");
68  break;
69  case DoneSoftKey:
70  softKeyText = QSoftKeyManager::tr("Done");
71  break;
72  case MenuSoftKey:
73  softKeyText = QSoftKeyManager::tr("Options");
74  break;
75  case CancelSoftKey:
76  softKeyText = QSoftKeyManager::tr("Cancel");
77  break;
78  default:
79  break;
80  };
81 
82  return softKeyText;
83 }
84 
86 {
89 
91 }
92 
94 #ifdef Q_WS_S60
95  QObject(*(new QSoftKeyManagerPrivateS60), 0)
96 #else
98 #endif
99 {
100 }
101 
103 {
104  QAction *action = new QAction(standardSoftKeyText(standardKey), actionWidget);
105 #if defined(Q_WS_S60) && !defined(SYMBIAN_VERSION_9_4) && !defined(SYMBIAN_VERSION_9_3) && !defined(SYMBIAN_VERSION_9_2)
106  int key = 0;
107  switch (standardKey) {
108  case OkSoftKey:
109  key = EAknSoftkeyOk;
110  break;
111  case SelectSoftKey:
112  key = EAknSoftkeySelect;
113  break;
114  case DoneSoftKey:
115  key = EAknSoftkeyDone;
116  break;
117  case MenuSoftKey:
118  key = EAknSoftkeyOptions;
119  break;
120  case CancelSoftKey:
121  key = EAknSoftkeyCancel;
122  break;
123  default:
124  break;
125  };
126  if (key != 0) {
127  QSoftKeyManager::instance()->d_func()->softKeyCommandActions.insert(action, key);
129  }
130 #endif
132  switch (standardKey) {
133  case MenuSoftKey: // FALL-THROUGH
134  QActionPrivate::get(action)->menuActionSoftkeys = true;
135  case OkSoftKey:
136  case SelectSoftKey:
137  case DoneSoftKey:
138  softKeyRole = QAction::PositiveSoftKey;
139  break;
140  case CancelSoftKey:
141  softKeyRole = QAction::NegativeSoftKey;
142  break;
143  }
144  action->setSoftKeyRole(softKeyRole);
145  action->setVisible(false);
147  return action;
148 }
149 
160 {
161 #ifndef QT_NO_ACTION
162  QScopedPointer<QAction> action(createAction(standardKey, actionWidget));
163 
164  connect(action.data(), SIGNAL(triggered()), QSoftKeyManager::instance(), SLOT(sendKeyEvent()));
165 
166 #if defined(Q_WS_S60) && !defined(SYMBIAN_VERSION_9_4) && !defined(SYMBIAN_VERSION_9_3) && !defined(SYMBIAN_VERSION_9_2)
167  // Don't connect destroyed slot if is was already connected in createAction
168  if (!(QSoftKeyManager::instance()->d_func()->softKeyCommandActions.contains(action.data())))
169 #endif
171 
172  QSoftKeyManager::instance()->d_func()->keyedActions.insert(action.data(), key);
173  return action.take();
174 #endif //QT_NO_ACTION
175 }
176 
178 {
180  // Can't use qobject_cast in destroyed() signal handler as that'll return NULL,
181  // so use static_cast instead. Since the pointer is only used as a hash key, it is safe.
182  QAction *action = static_cast<QAction *>(obj);
183  d->keyedActions.remove(action);
184 #if defined(Q_WS_S60) && !defined(SYMBIAN_VERSION_9_4) && !defined(SYMBIAN_VERSION_9_3) && !defined(SYMBIAN_VERSION_9_2)
185  d->softKeyCommandActions.remove(action);
186 #endif
187 }
188 
190 {
192  QAction *action = qobject_cast<QAction*>(sender());
193 
194  if (!action)
195  return;
196 
197  Qt::Key keyToSend = d->keyedActions.value(action, Qt::Key_unknown);
198 
199  if (keyToSend != Qt::Key_unknown)
201  new QKeyEvent(QEvent::KeyPress, keyToSend, Qt::NoModifier));
202 }
203 
205 {
206 #ifdef Q_WS_S60
207  // Do not adjust softkeys if application is not the topmost one
208  if (S60->wsSession().GetFocusWindowGroup() != S60->windowGroup().WindowGroupId())
209  return;
210 #endif
211  QSoftKeyManager::instance()->d_func()->pendingUpdate = true;
212  QEvent *event = new QEvent(QEvent::UpdateSoftKeys);
214 }
215 
216 bool QSoftKeyManager::appendSoftkeys(const QWidget &source, int level)
217 {
219  bool ret = false;
220  foreach(QAction *action, source.actions()) {
221  if (action->softKeyRole() != QAction::NoSoftKey
222  && (action->isVisible() || isForceEnabledInSofkeys(action))) {
223  d->requestedSoftKeyActions.insert(level, action);
224  ret = true;
225  }
226  }
227  return ret;
228 }
229 
230 
231 static bool isChildOf(const QWidget *c, const QWidget *p)
232 {
233  while (c) {
234  if (c == p)
235  return true;
236  c = c->parentWidget();
237  }
238  return false;
239 }
240 
241 QWidget *QSoftKeyManager::softkeySource(QWidget *previousSource, bool& recursiveMerging)
242 {
244  QWidget *source = NULL;
245  if (!previousSource) {
246  // Initial source is primarily focuswidget and secondarily activeWindow
249  if (popup) {
250  if (isChildOf(focus, popup))
251  source = focus;
252  else
253  source = popup;
254  }
255  if (!source) {
257  if (modal) {
258  if (isChildOf(focus, modal))
259  source = focus;
260  else
261  source = modal;
262  }
263  }
264  if (!source) {
265  source = focus;
266  if (!source)
267  source = QApplication::activeWindow();
268  }
269  } else {
270  // Softkey merging is based on four criterias
271  // 1. Implicit merging is used whenever focus widget does not specify any softkeys
272  bool implicitMerging = d->requestedSoftKeyActions.isEmpty();
273  // 2. Explicit merging with parent is used whenever WA_MergeSoftkeys widget attribute is set
274  bool explicitMerging = previousSource->testAttribute(Qt::WA_MergeSoftkeys);
275  // 3. Explicit merging with all parents
276  recursiveMerging |= previousSource->testAttribute(Qt::WA_MergeSoftkeysRecursively);
277  // 4. Implicit and explicit merging always stops at window boundary
278  bool merging = (implicitMerging || explicitMerging || recursiveMerging) && !previousSource->isWindow();
279 
280  source = merging ? previousSource->parentWidget() : NULL;
281  }
282  return source;
283 }
284 
286 {
288  int level = 0;
289  d->requestedSoftKeyActions.clear();
290  bool recursiveMerging = false;
291  QWidget *source = softkeySource(NULL, recursiveMerging);
292  d->initialSoftKeySource = source;
293  while (source) {
294  if (appendSoftkeys(*source, level))
295  ++level;
296  source = softkeySource(source, recursiveMerging);
297  }
298 
299  d->updateSoftKeys_sys();
300  d->pendingUpdate = false;
301  return true;
302 }
303 
305 {
307 }
308 
310 {
312 }
313 
315 {
316 #ifndef QT_NO_ACTION
317  if (e->type() == QEvent::UpdateSoftKeys)
318  return handleUpdateSoftKeys();
319 #endif //QT_NO_ACTION
320  return false;
321 }
322 
323 #ifdef Q_WS_S60
324 bool QSoftKeyManager::handleCommand(int command)
325 {
326  if (QSoftKeyManager::instance()->d_func()->pendingUpdate)
328 
329  return static_cast<QSoftKeyManagerPrivateS60*>(QSoftKeyManager::instance()->d_func())->handleCommand(command);
330 }
331 #endif
332 
334 #endif //QT_NO_SOFTKEYMANAGER
QWidget * softkeySource(QWidget *previousSource, bool &recursiveMerging)
double d
Definition: qnumeric_p.h:62
QWidget * parentWidget() const
Returns the parent of this widget, or 0 if it does not have any parent widget.
Definition: qwidget.h:1035
The QKeyEvent class describes a key event.
Definition: qevent.h:224
static QString standardSoftKeyText(StandardSoftKey standardKey)
unsigned char c[8]
Definition: qnumeric_p.h:62
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
T * data() const
Returns the value of the pointer referenced by this object.
bool isWindow() const
Returns true if the widget is an independent window, otherwise returns false.
Definition: qwidget.h:945
static void postEvent(QObject *receiver, QEvent *event)
Adds the event event, with the object receiver as the receiver of the event, to an event queue and re...
uint forceEnabledInSoftkeys
Definition: qaction_p.h:113
static QWidget * activeWindow()
Returns the application top-level window that has the keyboard input focus, or 0 if no application wi...
#define SLOT(a)
Definition: qobjectdefs.h:226
T * take()
Returns the value of the pointer referenced by this object.
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
static QString tr(const char *sourceText, const char *comment=0, int n=-1)
void cleanupHash(QObject *obj)
The QString class provides a Unicode character string.
Definition: qstring.h:83
T * qobject_cast(QObject *object)
Definition: qobject.h:375
bool appendSoftkeys(const QWidget &source, int level)
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
#define Q_D(Class)
Definition: qglobal.h:2482
bool event(QEvent *e)
This virtual function receives events to an object and should return true if the event e was recogniz...
uint menuActionSoftkeys
Definition: qaction_p.h:114
QObject * sender() const
Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; othe...
Definition: qobject.cpp:2327
bool isVisible() const
Definition: qaction.cpp:1246
#define SIGNAL(a)
Definition: qobjectdefs.h:227
QWidget * parentWidget() const
Returns the parent widget.
Definition: qaction.cpp:399
static QAction * createKeyedAction(StandardSoftKey standardKey, Qt::Key key, QWidget *actionWidget)
Creates a QAction and registers the &#39;triggered&#39; signal to send the given key event to actionWidget as...
static QWidget * activeModalWidget()
Returns the active modal widget.
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
static bool isChildOf(const QWidget *c, const QWidget *p)
void destroyed(QObject *=0)
This signal is emitted immediately before the object obj is destroyed, and can not be blocked...
static QSoftKeyManager * instance()
bool testAttribute(Qt::WidgetAttribute) const
Returns true if attribute attribute is set on this widget; otherwise returns false.
Definition: qwidget.h:1041
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
void setSoftKeyRole(SoftKeyRole softKeyRole)
Definition: qaction.cpp:1599
static QActionPrivate * get(QAction *q)
Definition: qaction_p.h:78
SoftKeyRole
This enum describes how an action should be placed in the softkey bar.
Definition: qaction.h:96
static void setForceEnabledInSoftkeys(QAction *action)
void reset(T *other=0)
Deletes the existing object it is pointing to if any, and sets its pointer to other.
SoftKeyRole softKeyRole
the action&#39;s softkey role
Definition: qaction.h:89
static QScopedPointer< QSoftKeyManager > self
static QAction * createAction(StandardSoftKey standardKey, QWidget *actionWidget)
static void updateSoftKeys()
void setVisible(bool)
Definition: qaction.cpp:1230
static QWidget * activePopupWidget()
Returns the active popup widget.
int key
QList< QAction * > actions() const
Returns the (possibly empty) list of this widget&#39;s actions.
Definition: qwidget.cpp:3407
bool modal
Definition: qmenu_mac.mm:99
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
static QWidget * focusWidget()
Returns the application widget that has the keyboard input focus, or 0 if no widget in this applicati...
static bool isForceEnabledInSofkeys(QAction *action)
The QAction class provides an abstract user interface action that can be inserted into widgets...
Definition: qaction.h:64