forked from qt-creator/qt-creator
Taskwindow: Allow for Keyboard shortcuts in actions
Allow to trigger TaskHandler actions by keyboard shortcut. Simplify the code while doing so. As a side effect the default handler is now listed in the context menu, which makes it more discoverable. Change-Id: I41183e5a5ef77be57360f29f289e327cadfaa7d1 Reviewed-by: Daniel Teske <daniel.teske@digia.com> Reviewed-by: Eike Ziller <eike.ziller@digia.com>
This commit is contained in:
committed by
Eike Ziller
parent
a28f48366c
commit
432de3a198
@@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
#include "projectexplorer_export.h"
|
#include "projectexplorer_export.h"
|
||||||
|
|
||||||
|
#include <coreplugin/id.h>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
@@ -52,6 +54,7 @@ public:
|
|||||||
virtual bool isDefaultHandler() const { return false; }
|
virtual bool isDefaultHandler() const { return false; }
|
||||||
virtual bool canHandle(const Task &) const = 0;
|
virtual bool canHandle(const Task &) const = 0;
|
||||||
virtual void handle(const Task &) = 0;
|
virtual void handle(const Task &) = 0;
|
||||||
|
virtual Core::Id actionManagerId() const { return Core::Id(); }
|
||||||
virtual QAction *createAction(QObject *parent) const = 0;
|
virtual QAction *createAction(QObject *parent) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ public:
|
|||||||
TaskView(QWidget *parent = 0);
|
TaskView(QWidget *parent = 0);
|
||||||
~TaskView();
|
~TaskView();
|
||||||
void resizeEvent(QResizeEvent *e);
|
void resizeEvent(QResizeEvent *e);
|
||||||
void keyPressEvent(QKeyEvent *e);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TaskWindowContext : public Core::IContext
|
class TaskWindowContext : public Core::IContext
|
||||||
@@ -189,16 +188,6 @@ void TaskView::resizeEvent(QResizeEvent *e)
|
|||||||
static_cast<TaskDelegate *>(itemDelegate())->emitSizeHintChanged(selectionModel()->currentIndex());
|
static_cast<TaskDelegate *>(itemDelegate())->emitSizeHintChanged(selectionModel()->currentIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskView::keyPressEvent(QKeyEvent *e)
|
|
||||||
{
|
|
||||||
if (!e->modifiers() && e->key() == Qt::Key_Return) {
|
|
||||||
emit activated(currentIndex());
|
|
||||||
e->accept();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QListView::keyPressEvent(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////
|
/////
|
||||||
// TaskWindow
|
// TaskWindow
|
||||||
/////
|
/////
|
||||||
@@ -211,13 +200,13 @@ public:
|
|||||||
Internal::TaskView *m_listview;
|
Internal::TaskView *m_listview;
|
||||||
Internal::TaskWindowContext *m_taskWindowContext;
|
Internal::TaskWindowContext *m_taskWindowContext;
|
||||||
QMenu *m_contextMenu;
|
QMenu *m_contextMenu;
|
||||||
QModelIndex m_contextMenuIndex;
|
|
||||||
ITaskHandler *m_defaultHandler;
|
ITaskHandler *m_defaultHandler;
|
||||||
QToolButton *m_filterWarningsButton;
|
QToolButton *m_filterWarningsButton;
|
||||||
QToolButton *m_categoriesButton;
|
QToolButton *m_categoriesButton;
|
||||||
QMenu *m_categoriesMenu;
|
QMenu *m_categoriesMenu;
|
||||||
TaskHub *m_taskHub;
|
TaskHub *m_taskHub;
|
||||||
int m_badgeCount;
|
int m_badgeCount;
|
||||||
|
QList<QAction *> m_actions;
|
||||||
};
|
};
|
||||||
|
|
||||||
static QToolButton *createFilterButton(QIcon icon, const QString &toolTip,
|
static QToolButton *createFilterButton(QIcon icon, const QString &toolTip,
|
||||||
@@ -261,17 +250,14 @@ TaskWindow::TaskWindow(TaskHub *taskhub) : d(new TaskWindowPrivate)
|
|||||||
connect(d->m_listview->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
|
connect(d->m_listview->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
|
||||||
tld, SLOT(currentChanged(QModelIndex,QModelIndex)));
|
tld, SLOT(currentChanged(QModelIndex,QModelIndex)));
|
||||||
|
|
||||||
|
connect(d->m_listview->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
|
||||||
|
this, SLOT(currentChanged(QModelIndex)));
|
||||||
connect(d->m_listview, SIGNAL(activated(QModelIndex)),
|
connect(d->m_listview, SIGNAL(activated(QModelIndex)),
|
||||||
this, SLOT(triggerDefaultHandler(QModelIndex)));
|
this, SLOT(triggerDefaultHandler(QModelIndex)));
|
||||||
|
|
||||||
d->m_contextMenu = new QMenu(d->m_listview);
|
d->m_contextMenu = new QMenu(d->m_listview);
|
||||||
connect(d->m_contextMenu, SIGNAL(triggered(QAction*)),
|
|
||||||
this, SLOT(contextMenuEntryTriggered(QAction*)));
|
|
||||||
|
|
||||||
d->m_listview->setContextMenuPolicy(Qt::CustomContextMenu);
|
d->m_listview->setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||||
|
|
||||||
connect(d->m_listview, SIGNAL(customContextMenuRequested(QPoint)),
|
|
||||||
this, SLOT(showContextMenu(QPoint)));
|
|
||||||
|
|
||||||
d->m_filterWarningsButton = createFilterButton(d->m_model->taskTypeIcon(Task::Warning),
|
d->m_filterWarningsButton = createFilterButton(d->m_model->taskTypeIcon(Task::Warning),
|
||||||
tr("Show Warnings"),
|
tr("Show Warnings"),
|
||||||
@@ -315,7 +301,6 @@ TaskWindow::TaskWindow(TaskHub *taskhub) : d(new TaskWindowPrivate)
|
|||||||
TaskWindow::~TaskWindow()
|
TaskWindow::~TaskWindow()
|
||||||
{
|
{
|
||||||
Core::ICore::removeContextObject(d->m_taskWindowContext);
|
Core::ICore::removeContextObject(d->m_taskWindowContext);
|
||||||
cleanContextMenu();
|
|
||||||
delete d->m_filterWarningsButton;
|
delete d->m_filterWarningsButton;
|
||||||
delete d->m_listview;
|
delete d->m_listview;
|
||||||
delete d->m_filter;
|
delete d->m_filter;
|
||||||
@@ -323,6 +308,43 @@ TaskWindow::~TaskWindow()
|
|||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ITaskHandler *handler(QAction *action)
|
||||||
|
{
|
||||||
|
return qobject_cast<ITaskHandler *>(action->data().value<QObject *>());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskWindow::delayedInitialization()
|
||||||
|
{
|
||||||
|
static bool alreadyDone = false;
|
||||||
|
if (alreadyDone)
|
||||||
|
return;
|
||||||
|
|
||||||
|
alreadyDone = true;
|
||||||
|
|
||||||
|
QList<ITaskHandler *> handlers = ExtensionSystem::PluginManager::getObjects<ITaskHandler>();
|
||||||
|
foreach (ITaskHandler *h, handlers) {
|
||||||
|
if (h->isDefaultHandler() && !d->m_defaultHandler)
|
||||||
|
d->m_defaultHandler = h;
|
||||||
|
|
||||||
|
QAction *action = h->createAction(this);
|
||||||
|
QTC_ASSERT(action, continue);
|
||||||
|
action->setData(qVariantFromValue(qobject_cast<QObject*>(h)));
|
||||||
|
connect(action, SIGNAL(triggered()), this, SLOT(actionTriggered()));
|
||||||
|
d->m_actions << action;
|
||||||
|
|
||||||
|
Core::Id id = h->actionManagerId();
|
||||||
|
if (id.isValid()) {
|
||||||
|
Core::Command *cmd = Core::ActionManager::instance()
|
||||||
|
->registerAction(action, id, d->m_taskWindowContext->context(), true);
|
||||||
|
action = cmd->action();
|
||||||
|
}
|
||||||
|
d->m_listview->addAction(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable everything for now:
|
||||||
|
currentChanged(QModelIndex());
|
||||||
|
}
|
||||||
|
|
||||||
QList<QWidget*> TaskWindow::toolBarWidgets() const
|
QList<QWidget*> TaskWindow::toolBarWidgets() const
|
||||||
{
|
{
|
||||||
return QList<QWidget*>() << d->m_filterWarningsButton << d->m_categoriesButton;
|
return QList<QWidget*>() << d->m_filterWarningsButton << d->m_categoriesButton;
|
||||||
@@ -382,8 +404,19 @@ void TaskWindow::setCategoryVisibility(const Core::Id &categoryId, bool visible)
|
|||||||
setBadgeNumber(d->m_badgeCount);
|
setBadgeNumber(d->m_badgeCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskWindow::visibilityChanged(bool /* b */)
|
void TaskWindow::currentChanged(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
|
const Task task = index.isValid() ? d->m_filter->task(index) : Task();
|
||||||
|
foreach (QAction *action, d->m_actions) {
|
||||||
|
ITaskHandler *h = handler(action);
|
||||||
|
action->setEnabled((task.isNull() || !h) ? false : h->canHandle(task));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskWindow::visibilityChanged(bool visible)
|
||||||
|
{
|
||||||
|
if (visible)
|
||||||
|
delayedInitialization();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskWindow::addCategory(const Core::Id &categoryId, const QString &displayName, bool visible)
|
void TaskWindow::addCategory(const Core::Id &categoryId, const QString &displayName, bool visible)
|
||||||
@@ -470,20 +503,9 @@ void TaskWindow::openTask(unsigned int id)
|
|||||||
|
|
||||||
void TaskWindow::triggerDefaultHandler(const QModelIndex &index)
|
void TaskWindow::triggerDefaultHandler(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
if (!index.isValid())
|
if (!index.isValid() || !d->m_defaultHandler)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Find a default handler to use:
|
|
||||||
if (!d->m_defaultHandler) {
|
|
||||||
QList<ITaskHandler *> handlers = ExtensionSystem::PluginManager::getObjects<ITaskHandler>();
|
|
||||||
foreach(ITaskHandler *handler, handlers) {
|
|
||||||
if (handler->isDefaultHandler()) {
|
|
||||||
d->m_defaultHandler = handler;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Q_ASSERT(d->m_defaultHandler);
|
|
||||||
Task task(d->m_filter->task(index));
|
Task task(d->m_filter->task(index));
|
||||||
if (task.isNull())
|
if (task.isNull())
|
||||||
return;
|
return;
|
||||||
@@ -496,49 +518,21 @@ void TaskWindow::triggerDefaultHandler(const QModelIndex &index)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskWindow::showContextMenu(const QPoint &position)
|
void TaskWindow::actionTriggered()
|
||||||
{
|
{
|
||||||
QModelIndex index = d->m_listview->indexAt(position);
|
QAction *action = qobject_cast<QAction *>(sender());
|
||||||
if (!index.isValid())
|
if (!action || !action->isEnabled())
|
||||||
|
return;
|
||||||
|
ITaskHandler *h = handler(action);
|
||||||
|
if (!h)
|
||||||
return;
|
return;
|
||||||
d->m_contextMenuIndex = index;
|
|
||||||
cleanContextMenu();
|
|
||||||
|
|
||||||
|
QModelIndex index = d->m_listview->selectionModel()->currentIndex();
|
||||||
Task task = d->m_filter->task(index);
|
Task task = d->m_filter->task(index);
|
||||||
if (task.isNull())
|
if (task.isNull())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QList<ITaskHandler *> handlers = ExtensionSystem::PluginManager::getObjects<ITaskHandler>();
|
h->handle(task);
|
||||||
foreach(ITaskHandler *handler, handlers) {
|
|
||||||
if (handler == d->m_defaultHandler)
|
|
||||||
continue;
|
|
||||||
QAction * action = handler->createAction(d->m_contextMenu);
|
|
||||||
action->setEnabled(handler->canHandle(task));
|
|
||||||
action->setData(qVariantFromValue(qobject_cast<QObject*>(handler)));
|
|
||||||
d->m_contextMenu->addAction(action);
|
|
||||||
}
|
|
||||||
d->m_contextMenu->popup(d->m_listview->mapToGlobal(position));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TaskWindow::contextMenuEntryTriggered(QAction *action)
|
|
||||||
{
|
|
||||||
if (action->isEnabled()) {
|
|
||||||
Task task = d->m_filter->task(d->m_contextMenuIndex);
|
|
||||||
if (task.isNull())
|
|
||||||
return;
|
|
||||||
|
|
||||||
ITaskHandler *handler = qobject_cast<ITaskHandler*>(action->data().value<QObject*>());
|
|
||||||
if (!handler)
|
|
||||||
return;
|
|
||||||
handler->handle(task);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TaskWindow::cleanContextMenu()
|
|
||||||
{
|
|
||||||
QList<QAction *> actions = d->m_contextMenu->actions();
|
|
||||||
qDeleteAll(actions);
|
|
||||||
d->m_contextMenu->clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskWindow::setShowWarnings(bool show)
|
void TaskWindow::setShowWarnings(bool show)
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ public:
|
|||||||
TaskWindow(ProjectExplorer::TaskHub *taskHub);
|
TaskWindow(ProjectExplorer::TaskHub *taskHub);
|
||||||
virtual ~TaskWindow();
|
virtual ~TaskWindow();
|
||||||
|
|
||||||
|
void delayedInitialization();
|
||||||
|
|
||||||
int taskCount(const Core::Id &category = Core::Id()) const;
|
int taskCount(const Core::Id &category = Core::Id()) const;
|
||||||
int warningTaskCount(const Core::Id &category = Core::Id()) const;
|
int warningTaskCount(const Core::Id &category = Core::Id()) const;
|
||||||
int errorTaskCount(const Core::Id &category = Core::Id()) const;
|
int errorTaskCount(const Core::Id &category = Core::Id()) const;
|
||||||
@@ -92,16 +94,15 @@ private slots:
|
|||||||
void openTask(unsigned int id);
|
void openTask(unsigned int id);
|
||||||
void clearTasks(const Core::Id &categoryId);
|
void clearTasks(const Core::Id &categoryId);
|
||||||
void setCategoryVisibility(const Core::Id &categoryId, bool visible);
|
void setCategoryVisibility(const Core::Id &categoryId, bool visible);
|
||||||
|
void currentChanged(const QModelIndex &index);
|
||||||
|
|
||||||
void triggerDefaultHandler(const QModelIndex &index);
|
void triggerDefaultHandler(const QModelIndex &index);
|
||||||
void showContextMenu(const QPoint &position);
|
void actionTriggered();
|
||||||
void contextMenuEntryTriggered(QAction *);
|
|
||||||
void setShowWarnings(bool);
|
void setShowWarnings(bool);
|
||||||
void updateCategoriesMenu();
|
void updateCategoriesMenu();
|
||||||
void filterCategoryTriggered(QAction *action);
|
void filterCategoryTriggered(QAction *action);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void cleanContextMenu();
|
|
||||||
int sizeHintForColumn(int column) const;
|
int sizeHintForColumn(int column) const;
|
||||||
|
|
||||||
TaskWindowPrivate *d;
|
TaskWindowPrivate *d;
|
||||||
|
|||||||
Reference in New Issue
Block a user