ITaskHandler: Harden against vanishing ITaskHandlers

Harden against vanishing ITaskHandlers and avoid qobject_casts.

Task-number: QTCREATORBUG-19994
Change-Id: I72bccb944cb6fa6ec92a8c0293617931a2eb2732
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Tobias Hunger
2018-03-07 13:47:45 +01:00
parent c0f98299df
commit 144bba95e9

View File

@@ -210,11 +210,18 @@ void TaskView::resizeEvent(QResizeEvent *e)
class TaskWindowPrivate class TaskWindowPrivate
{ {
public: public:
ITaskHandler *handler(const QAction *action)
{
ITaskHandler *handler = m_actionToHandlerMap.value(action, nullptr);
return g_taskHandlers.contains(handler) ? handler : nullptr;
}
Internal::TaskModel *m_model; Internal::TaskModel *m_model;
Internal::TaskFilterModel *m_filter; Internal::TaskFilterModel *m_filter;
Internal::TaskView *m_listview; Internal::TaskView *m_listview;
Internal::TaskWindowContext *m_taskWindowContext; Internal::TaskWindowContext *m_taskWindowContext;
QMenu *m_contextMenu; QMenu *m_contextMenu;
QMap<const QAction *, ITaskHandler *> m_actionToHandlerMap;
ITaskHandler *m_defaultHandler = nullptr; ITaskHandler *m_defaultHandler = nullptr;
QToolButton *m_filterWarningsButton; QToolButton *m_filterWarningsButton;
QToolButton *m_categoriesButton; QToolButton *m_categoriesButton;
@@ -318,14 +325,6 @@ TaskWindow::~TaskWindow()
delete d; delete d;
} }
static ITaskHandler *handler(QAction *action)
{
QVariant prop = action->property("ITaskHandler");
ITaskHandler *handler = qobject_cast<ITaskHandler *>(prop.value<QObject *>());
QTC_CHECK(handler);
return handler;
}
void TaskWindow::delayedInitialization() void TaskWindow::delayedInitialization()
{ {
static bool alreadyDone = false; static bool alreadyDone = false;
@@ -340,7 +339,7 @@ void TaskWindow::delayedInitialization()
QAction *action = h->createAction(this); QAction *action = h->createAction(this);
QTC_ASSERT(action, continue); QTC_ASSERT(action, continue);
action->setProperty("ITaskHandler", qVariantFromValue(qobject_cast<QObject*>(h))); d->m_actionToHandlerMap.insert(action, h);
connect(action, &QAction::triggered, this, &TaskWindow::actionTriggered); connect(action, &QAction::triggered, this, &TaskWindow::actionTriggered);
d->m_actions << action; d->m_actions << action;
@@ -395,7 +394,7 @@ void TaskWindow::currentChanged(const QModelIndex &index)
{ {
const Task task = index.isValid() ? d->m_filter->task(index) : Task(); const Task task = index.isValid() ? d->m_filter->task(index) : Task();
foreach (QAction *action, d->m_actions) { foreach (QAction *action, d->m_actions) {
ITaskHandler *h = handler(action); ITaskHandler *h = d->handler(action);
action->setEnabled((task.isNull() || !h) ? false : h->canHandle(task)); action->setEnabled((task.isNull() || !h) ? false : h->canHandle(task));
} }
} }
@@ -511,7 +510,7 @@ void TaskWindow::actionTriggered()
auto action = qobject_cast<QAction *>(sender()); auto action = qobject_cast<QAction *>(sender());
if (!action || !action->isEnabled()) if (!action || !action->isEnabled())
return; return;
ITaskHandler *h = handler(action); ITaskHandler *h = d->handler(action);
if (!h) if (!h)
return; return;