Make it possible to specify shortcuts for Locator filters.

Task-number: QTCREATORBUG-1147
This commit is contained in:
con
2010-12-06 17:21:03 +01:00
parent bada915c35
commit 90ecb036a2
12 changed files with 136 additions and 11 deletions

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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();

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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)

View File

@@ -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

View File

@@ -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()

View File

@@ -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);

View File

@@ -91,6 +91,7 @@ private:
Utils::FilterLineEdit *m_fileLineEdit;
QTimer *m_showPopupTimer;
QFutureWatcher<FilterEntry> *m_entriesWatcher;
QMap<QString, QAction *> m_filterActionMap;
};
} // namespace Internal