summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2011-08-12 12:29:20 (GMT)
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2011-08-12 13:17:58 (GMT)
commit1dc0a2ccd645abd26b13fd67313a03bbc722a74d (patch)
tree3d67cf3b6fa877a6baf6796257e3b8d7e22e17f1
parent15b44c1ea04c3beebe4d7f6d9f45b81127c3c8f9 (diff)
downloadQt-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.cpp14
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);