diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2011-08-12 12:29:20 (GMT) |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2011-08-12 13:17:58 (GMT) |
commit | 1dc0a2ccd645abd26b13fd67313a03bbc722a74d (patch) | |
tree | 3d67cf3b6fa877a6baf6796257e3b8d7e22e17f1 | |
parent | 15b44c1ea04c3beebe4d7f6d9f45b81127c3c8f9 (diff) | |
download | Qt-1dc0a2ccd645abd26b13fd67313a03bbc722a74d.zip Qt-1dc0a2ccd645abd26b13fd67313a03bbc722a74d.tar.gz Qt-1dc0a2ccd645abd26b13fd67313a03bbc722a74d.tar.bz2 |
Fix softkeys cleanup
QSoftKeyManager's keyedActions and softKeyCommandActions hashes were
not properly cleaned up, resulting in randomly incorrect softkeys
as already deleted cached actions were assigned to softkeys if the
new action happened to be in the same address as the previously deleted
action.
Two bugs related to this were fixed:
1) qobject_cast can't be used in "destroyed" signal handler, as the
cast will return NULL pointer in this case. Changed the cast to
static_cast, which is safe here as the pointer is only used as a
hash key.
2) If softkey action was created with QSoftKeyManager::createAction
instead of QSoftKeyManager::createKeyedAction, the "destroyed"
signal was not connected to cleanupHash slot, leaving such
actions in softKeyCommandActions hash after deletion. Ensured
the signal was connected properly in both cases.
Task-number: QTTH-1442, QTBUG-20214
Reviewed-by: Gareth Stockwell
-rw-r--r-- | src/gui/kernel/qsoftkeymanager.cpp | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp index 2700bbb..80e6ec6 100644 --- a/src/gui/kernel/qsoftkeymanager.cpp +++ b/src/gui/kernel/qsoftkeymanager.cpp @@ -126,8 +126,10 @@ QAction *QSoftKeyManager::createAction(StandardSoftKey standardKey, QWidget *act default: break; }; - if (key != 0) + if (key != 0) { QSoftKeyManager::instance()->d_func()->softKeyCommandActions.insert(action, key); + connect(action, SIGNAL(destroyed(QObject*)), QSoftKeyManager::instance(), SLOT(cleanupHash(QObject*))); + } #endif QAction::SoftKeyRole softKeyRole = QAction::NoSoftKey; switch (standardKey) { @@ -160,7 +162,13 @@ QAction *QSoftKeyManager::createKeyedAction(StandardSoftKey standardKey, Qt::Key QScopedPointer<QAction> action(createAction(standardKey, actionWidget)); connect(action.data(), SIGNAL(triggered()), QSoftKeyManager::instance(), SLOT(sendKeyEvent())); + +#if defined(Q_WS_S60) && !defined(SYMBIAN_VERSION_9_4) && !defined(SYMBIAN_VERSION_9_3) && !defined(SYMBIAN_VERSION_9_2) + // Don't connect destroyed slot if is was already connected in createAction + if (!(QSoftKeyManager::instance()->d_func()->softKeyCommandActions.contains(action.data()))) +#endif connect(action.data(), SIGNAL(destroyed(QObject*)), QSoftKeyManager::instance(), SLOT(cleanupHash(QObject*))); + QSoftKeyManager::instance()->d_func()->keyedActions.insert(action.data(), key); return action.take(); #endif //QT_NO_ACTION @@ -169,7 +177,9 @@ QAction *QSoftKeyManager::createKeyedAction(StandardSoftKey standardKey, Qt::Key void QSoftKeyManager::cleanupHash(QObject *obj) { Q_D(QSoftKeyManager); - QAction *action = qobject_cast<QAction*>(obj); + // Can't use qobject_cast in destroyed() signal handler as that'll return NULL, + // so use static_cast instead. Since the pointer is only used as a hash key, it is safe. + QAction *action = static_cast<QAction *>(obj); d->keyedActions.remove(action); #if defined(Q_WS_S60) && !defined(SYMBIAN_VERSION_9_4) && !defined(SYMBIAN_VERSION_9_3) && !defined(SYMBIAN_VERSION_9_2) d->softKeyCommandActions.remove(action); |