Commit 90ecb036 authored by con's avatar con
Browse files

Make it possible to specify shortcuts for Locator filters.

Task-number: QTCREATORBUG-1147
parent bada915c
......@@ -35,6 +35,7 @@
#include <coreplugin/coreconstants.h>
#include <coreplugin/icore.h>
#include <utils/qtcassert.h>
#include <QtCore/QDebug>
#include <QtCore/QSettings>
......@@ -198,6 +199,17 @@ namespace {
\sa ActionManager::createMenu()
\sa ActionManager::createMenuBar()
*/
/*!
\fn Command *ActionManager::unregisterAction(QAction *action, const QString &id)
\brief Removes the knowledge about an \a action under the specified string \a id.
Usually you do not need to unregister actions. The only valid use case for unregistering
actions, is for actions that represent user definable actions, like for the custom Locator
filters. If the user removes such an action, it also has to be unregistered from the action manager,
to make it disappear from shortcut settings etc.
*/
/*!
\fn ActionManager::ActionManager(QObject *parent)
\internal
......@@ -332,6 +344,7 @@ Command *ActionManagerPrivate::registerAction(QAction *action, const Id &id, con
a = static_cast<Action *>(c);
if (a)
a->addOverrideAction(action, context);
emit commandListChanged();
return a;
}
......@@ -375,10 +388,31 @@ Command *ActionManagerPrivate::registerOverridableAction(QAction *action, const
} else if (checkUnique) {
qWarning() << "registerOverridableAction: id" << id << "is already registered.";
}
return a;
}
void ActionManagerPrivate::unregisterAction(QAction *action, const Id &id)
{
Action *a = 0;
const int uid = UniqueIDManager::instance()->uniqueIdentifier(id);
CommandPrivate *c = m_idCmdMap.value(uid, 0);
QTC_ASSERT(c, return);
a = qobject_cast<Action *>(c);
if (!a) {
qWarning() << "registerAction: id" << id << "is registered with a different command type.";
return;
}
a->removeOverrideAction(action);
if (a->isEmpty()) {
// clean up
m_mainWnd->removeAction(a->action());
delete a->action();
m_idCmdMap.remove(uid);
delete a;
}
emit commandListChanged();
}
Command *ActionManagerPrivate::registerShortcut(QShortcut *shortcut, const Id &id, const Context &context)
{
Shortcut *sc = 0;
......@@ -410,6 +444,7 @@ Command *ActionManagerPrivate::registerShortcut(QShortcut *shortcut, const Id &i
else
sc->setContext(context);
emit commandListChanged();
return sc;
}
......
......@@ -32,6 +32,7 @@
#include "coreplugin/core_global.h"
#include "coreplugin/uniqueidmanager.h"
#include "coreplugin/icontext.h"
#include <QtCore/QObject>
#include <QtCore/QList>
......@@ -46,7 +47,6 @@ namespace Core {
class ActionContainer;
class Command;
class Context;
class CORE_EXPORT ActionManager : public QObject
{
......@@ -65,6 +65,11 @@ public:
virtual ActionContainer *actionContainer(const Id &id) const = 0;
virtual QList<Command *> commands() const = 0;
virtual void unregisterAction(QAction *action, const Id &id) = 0;
signals:
void commandListChanged();
};
} // namespace Core
......
......@@ -91,6 +91,7 @@ public:
Core::Command *command(const Id &id) const;
Core::ActionContainer *actionContainer(const Id &id) const;
void unregisterAction(QAction *action, const Id &id);
private:
bool hasContext(const Context &context) const;
......
......@@ -495,6 +495,20 @@ void Action::addOverrideAction(QAction *action, const Core::Context &context)
}
}
void Action::removeOverrideAction(QAction *action)
{
QMutableMapIterator<int, QPointer<QAction> > it(m_contextActionMap);
while (it.hasNext()) {
it.next();
if (it.value() == 0) {
it.remove();
} else if (it.value() == action) {
it.remove();
}
}
setCurrentContext(m_context);
}
void Action::actionChanged()
{
if (hasAttribute(CA_UpdateIcon)) {
......@@ -535,3 +549,8 @@ void Action::setActive(bool state)
}
}
bool Action::isEmpty() const
{
return m_contextActionMap.isEmpty();
}
......@@ -130,6 +130,8 @@ public:
bool setCurrentContext(const Context &context);
bool isActive() const;
void addOverrideAction(QAction *action, const Context &context);
void removeOverrideAction(QAction *action);
bool isEmpty() const;
protected:
void updateToolTipWithKeySequence();
......
......@@ -158,6 +158,8 @@ void CommandMappings::commandChanged(QTreeWidgetItem *current)
void CommandMappings::filterChanged(const QString &f)
{
if (!m_page)
return;
for (int i=0; i<m_page->commandList->topLevelItemCount(); ++i) {
QTreeWidgetItem *item = m_page->commandList->topLevelItem(i);
item->setHidden(filter(f, item));
......@@ -203,3 +205,10 @@ void CommandMappings::setModified(QTreeWidgetItem *item , bool modified)
f.setBold(modified);
item->setFont(2, f);
}
QString CommandMappings::filterText() const
{
if (!m_page)
return QString();
return m_page->filterEdit->text();
}
......@@ -80,6 +80,7 @@ protected:
void setImportExportEnabled(bool enabled);
QTreeWidget *commandList() const;
QLineEdit *targetEdit() const;
QString filterText() const;
void setPageTitle(const QString &s);
void setTargetLabelText(const QString &s);
void setTargetEditTitle(const QString &s);
......
......@@ -56,8 +56,10 @@ using namespace Core;
using namespace Core::Internal;
ShortcutSettings::ShortcutSettings(QObject *parent)
: CommandMappings(parent)
: CommandMappings(parent), m_initialized(false)
{
Core::Internal::ActionManagerPrivate *am = ActionManagerPrivate::instance();
connect(am, SIGNAL(commandListChanged()), this, SLOT(initialize()));
}
ShortcutSettings::~ShortcutSettings()
......@@ -94,6 +96,7 @@ QIcon ShortcutSettings::categoryIcon() const
QWidget *ShortcutSettings::createPage(QWidget *parent)
{
m_initialized = true;
m_keyNum = m_key[0] = m_key[1] = m_key[2] = m_key[3] = 0;
QWidget *w = CommandMappings::createPage(parent);
......@@ -128,6 +131,7 @@ void ShortcutSettings::finish()
m_scitems.clear();
CommandMappings::finish();
m_initialized = false;
}
bool ShortcutSettings::matches(const QString &s) const
......@@ -271,8 +275,21 @@ void ShortcutSettings::exportAction()
}
}
void ShortcutSettings::clear()
{
QTreeWidget *tree = commandList();
for (int i = tree->topLevelItemCount()-1; i >= 0 ; --i) {
delete tree->takeTopLevelItem(i);
}
qDeleteAll(m_scitems);
m_scitems.clear();
}
void ShortcutSettings::initialize()
{
if (!m_initialized)
return;
clear();
Core::Internal::ActionManagerPrivate *am = ActionManagerPrivate::instance();
UniqueIDManager *uidm = UniqueIDManager::instance();
......@@ -325,6 +342,7 @@ void ShortcutSettings::initialize()
markPossibleCollisions(s);
}
filterChanged(filterText());
}
void ShortcutSettings::handleKeyEvent(QKeyEvent *e)
......
......@@ -86,10 +86,11 @@ private slots:
void importAction();
void exportAction();
void defaultAction();
void initialize();
private:
void setKeySequence(const QKeySequence &key);
void initialize();
void clear();
void handleKeyEvent(QKeyEvent *e);
int translateModifiers(Qt::KeyboardModifiers state, const QString &text);
......@@ -101,6 +102,7 @@ private:
int m_key[4], m_keyNum;
QString m_searchKeywords;
bool m_initialized;
};
} // namespace Internal
......
......@@ -36,11 +36,6 @@
#include "filesystemfilter.h"
#include "settingspage.h"
#include <QtCore/QSettings>
#include <QtCore/QtPlugin>
#include <QtCore/QFuture>
#include <QtCore/QFutureWatcher>
#include <coreplugin/statusbarwidget.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/settingsdatabase.h>
......@@ -54,6 +49,12 @@
#include <extensionsystem/pluginmanager.h>
#include <qtconcurrent/QtConcurrentTools>
#include <QtCore/QSettings>
#include <QtCore/QtPlugin>
#include <QtCore/QFuture>
#include <QtCore/QFutureWatcher>
#include <QtGui/QAction>
/*!
\namespace Locator
The Locator namespace provides the hooks for Locator content.
......@@ -142,6 +143,7 @@ void LocatorPlugin::extensionsInitialized()
{
m_filters = ExtensionSystem::PluginManager::instance()->getObjects<ILocatorFilter>();
qSort(m_filters.begin(), m_filters.end(), filterLessThan);
setFilters(m_filters);
}
void LocatorPlugin::startSettingsLoad()
......
......@@ -37,6 +37,8 @@
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/fileiconprovider.h>
#include <utils/filterlineedit.h>
......@@ -321,12 +323,40 @@ LocatorWidget::LocatorWidget(LocatorPlugin *qop) :
void LocatorWidget::updateFilterList()
{
m_filterMenu->clear();
// update actions and menu
Core::ActionManager *am = Core::ICore::instance()->actionManager();
QMap<QString, QAction *> actionCopy = m_filterActionMap;
m_filterActionMap.clear();
// register new actions, update existent
foreach (ILocatorFilter *filter, m_locatorPlugin->filters()) {
if (!filter->shortcutString().isEmpty() && !filter->isHidden()) {
QAction *action = m_filterMenu->addAction(filter->displayName(), this, SLOT(filterSelected()));
if (filter->shortcutString().isEmpty() || filter->isHidden())
continue;
QAction *action = 0;
Core::Command *cmd = 0;
if (!actionCopy.contains(filter->id())) {
// register new action
action = new QAction(filter->displayName(), this);
cmd = am->registerAction(action, QLatin1String("Locator.") + filter->id(),
Core::Context(Core::Constants::C_GLOBAL));
cmd->setAttribute(Core::Command::CA_UpdateText);
connect(action, SIGNAL(triggered()), this, SLOT(filterSelected()));
action->setData(qVariantFromValue(filter));
} else {
action = actionCopy.take(filter->id());
action->setText(filter->displayName());
cmd = am->command(QLatin1String("Locator.") + filter->id());
}
m_filterActionMap.insert(filter->id(), action);
m_filterMenu->addAction(cmd->action());
}
// unregister actions that are deleted now
foreach (const QString &id, actionCopy.keys()) {
am->unregisterAction(actionCopy.value(id), QLatin1String("Locator.") + id);
}
qDeleteAll(actionCopy);
m_filterMenu->addSeparator();
m_filterMenu->addAction(m_refreshAction);
m_filterMenu->addAction(m_configureAction);
......
......@@ -91,6 +91,7 @@ private:
Utils::FilterLineEdit *m_fileLineEdit;
QTimer *m_showPopupTimer;
QFutureWatcher<FilterEntry> *m_entriesWatcher;
QMap<QString, QAction *> m_filterActionMap;
};
} // namespace Internal
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment