forked from qt-creator/qt-creator
Core: add menu bar locator filter
Adding the possibility to trigger menu actions from the locator Change-Id: I70d595c167f5b43b02f8125eafbb83e5b45012c9 Reviewed-by: André Hartmann <aha_1980@gmx.de> Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -26,12 +26,13 @@
|
||||
#include "coreplugin.h"
|
||||
#include "designmode.h"
|
||||
#include "editmode.h"
|
||||
#include "idocument.h"
|
||||
#include "helpmanager.h"
|
||||
#include "mainwindow.h"
|
||||
#include "modemanager.h"
|
||||
#include "idocument.h"
|
||||
#include "infobar.h"
|
||||
#include "iwizardfactory.h"
|
||||
#include "mainwindow.h"
|
||||
#include "menubarfilter.h"
|
||||
#include "modemanager.h"
|
||||
#include "reaper_p.h"
|
||||
#include "themechooser.h"
|
||||
|
||||
@@ -162,6 +163,8 @@ bool CorePlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
InfoBar::initialize(ICore::settings(), creatorTheme());
|
||||
}
|
||||
|
||||
addAutoReleasedObject(new MenuBarFilter);
|
||||
|
||||
IWizardFactory::initialize();
|
||||
|
||||
// Make sure we respect the process's umask when creating new files
|
||||
|
@@ -111,7 +111,8 @@ SOURCES += corejsextensions.cpp \
|
||||
externaltoolmanager.cpp \
|
||||
systemsettings.cpp \
|
||||
coreicons.cpp \
|
||||
diffservice.cpp
|
||||
diffservice.cpp \
|
||||
menubarfilter.cpp
|
||||
|
||||
HEADERS += corejsextensions.h \
|
||||
mainwindow.h \
|
||||
@@ -222,7 +223,8 @@ HEADERS += corejsextensions.h \
|
||||
systemsettings.h \
|
||||
coreicons.h \
|
||||
editormanager/documentmodel_p.h \
|
||||
diffservice.h
|
||||
diffservice.h \
|
||||
menubarfilter.h
|
||||
|
||||
FORMS += dialogs/newdialog.ui \
|
||||
dialogs/saveitemsdialog.ui \
|
||||
|
@@ -32,79 +32,154 @@ Project {
|
||||
Group {
|
||||
name: "General"
|
||||
files: [
|
||||
"basefilewizard.cpp", "basefilewizard.h",
|
||||
"basefilewizardfactory.cpp", "basefilewizardfactory.h",
|
||||
"basefilewizard.cpp",
|
||||
"basefilewizard.h",
|
||||
"basefilewizardfactory.cpp",
|
||||
"basefilewizardfactory.h",
|
||||
"core.qrc",
|
||||
"core_global.h",
|
||||
"coreconstants.h",
|
||||
"coreicons.cpp", "coreicons.h",
|
||||
"corejsextensions.cpp", "corejsextensions.h",
|
||||
"coreplugin.cpp", "coreplugin.h",
|
||||
"designmode.cpp", "designmode.h",
|
||||
"diffservice.cpp", "diffservice.h",
|
||||
"documentmanager.cpp", "documentmanager.h",
|
||||
"editmode.cpp", "editmode.h",
|
||||
"editortoolbar.cpp", "editortoolbar.h",
|
||||
"externaltool.cpp", "externaltool.h",
|
||||
"externaltoolmanager.cpp", "externaltoolmanager.h",
|
||||
"fancyactionbar.cpp", "fancyactionbar.h", "fancyactionbar.qrc",
|
||||
"fancytabwidget.cpp", "fancytabwidget.h",
|
||||
"featureprovider.cpp", "featureprovider.h",
|
||||
"fileiconprovider.cpp", "fileiconprovider.h",
|
||||
"fileutils.cpp", "fileutils.h",
|
||||
"findplaceholder.cpp", "findplaceholder.h",
|
||||
"generalsettings.cpp", "generalsettings.h", "generalsettings.ui",
|
||||
"generatedfile.cpp", "generatedfile.h",
|
||||
"helpmanager.cpp", "helpmanager.h",
|
||||
"icontext.cpp", "icontext.h",
|
||||
"icore.cpp", "icore.h",
|
||||
"id.cpp", "id.h",
|
||||
"idocument.cpp", "idocument.h",
|
||||
"idocumentfactory.cpp", "idocumentfactory.h",
|
||||
"coreicons.cpp",
|
||||
"coreicons.h",
|
||||
"corejsextensions.cpp",
|
||||
"corejsextensions.h",
|
||||
"coreplugin.cpp",
|
||||
"coreplugin.h",
|
||||
"designmode.cpp",
|
||||
"designmode.h",
|
||||
"diffservice.cpp",
|
||||
"diffservice.h",
|
||||
"documentmanager.cpp",
|
||||
"documentmanager.h",
|
||||
"editmode.cpp",
|
||||
"editmode.h",
|
||||
"editortoolbar.cpp",
|
||||
"editortoolbar.h",
|
||||
"externaltool.cpp",
|
||||
"externaltool.h",
|
||||
"externaltoolmanager.cpp",
|
||||
"externaltoolmanager.h",
|
||||
"fancyactionbar.cpp",
|
||||
"fancyactionbar.h",
|
||||
"fancyactionbar.qrc",
|
||||
"fancytabwidget.cpp",
|
||||
"fancytabwidget.h",
|
||||
"featureprovider.cpp",
|
||||
"featureprovider.h",
|
||||
"fileiconprovider.cpp",
|
||||
"fileiconprovider.h",
|
||||
"fileutils.cpp",
|
||||
"fileutils.h",
|
||||
"findplaceholder.cpp",
|
||||
"findplaceholder.h",
|
||||
"generalsettings.cpp",
|
||||
"generalsettings.h",
|
||||
"generalsettings.ui",
|
||||
"generatedfile.cpp",
|
||||
"generatedfile.h",
|
||||
"helpmanager.cpp",
|
||||
"helpmanager.h",
|
||||
"icontext.cpp",
|
||||
"icontext.h",
|
||||
"icore.cpp",
|
||||
"icore.h",
|
||||
"id.cpp",
|
||||
"id.h",
|
||||
"idocument.cpp",
|
||||
"idocument.h",
|
||||
"idocumentfactory.cpp",
|
||||
"idocumentfactory.h",
|
||||
"ifilewizardextension.h",
|
||||
"imode.cpp", "imode.h",
|
||||
"inavigationwidgetfactory.cpp", "inavigationwidgetfactory.h",
|
||||
"infobar.cpp", "infobar.h",
|
||||
"ioutputpane.cpp", "ioutputpane.h",
|
||||
"iversioncontrol.cpp", "iversioncontrol.h",
|
||||
"iwelcomepage.cpp", "iwelcomepage.h",
|
||||
"iwizardfactory.cpp", "iwizardfactory.h",
|
||||
"jsexpander.cpp", "jsexpander.h",
|
||||
"mainwindow.cpp", "mainwindow.h",
|
||||
"manhattanstyle.cpp", "manhattanstyle.h",
|
||||
"messagebox.cpp", "messagebox.h",
|
||||
"messagemanager.cpp", "messagemanager.h",
|
||||
"messageoutputwindow.cpp", "messageoutputwindow.h",
|
||||
"mimetypemagicdialog.cpp", "mimetypemagicdialog.h", "mimetypemagicdialog.ui",
|
||||
"mimetypesettings.cpp", "mimetypesettings.h",
|
||||
"imode.cpp",
|
||||
"imode.h",
|
||||
"inavigationwidgetfactory.cpp",
|
||||
"inavigationwidgetfactory.h",
|
||||
"infobar.cpp",
|
||||
"infobar.h",
|
||||
"ioutputpane.cpp",
|
||||
"ioutputpane.h",
|
||||
"iversioncontrol.cpp",
|
||||
"iversioncontrol.h",
|
||||
"iwelcomepage.cpp",
|
||||
"iwelcomepage.h",
|
||||
"iwizardfactory.cpp",
|
||||
"iwizardfactory.h",
|
||||
"jsexpander.cpp",
|
||||
"jsexpander.h",
|
||||
"mainwindow.cpp",
|
||||
"mainwindow.h",
|
||||
"manhattanstyle.cpp",
|
||||
"manhattanstyle.h",
|
||||
"menubarfilter.cpp",
|
||||
"menubarfilter.h",
|
||||
"messagebox.cpp",
|
||||
"messagebox.h",
|
||||
"messagemanager.cpp",
|
||||
"messagemanager.h",
|
||||
"messageoutputwindow.cpp",
|
||||
"messageoutputwindow.h",
|
||||
"mimetypemagicdialog.cpp",
|
||||
"mimetypemagicdialog.h",
|
||||
"mimetypemagicdialog.ui",
|
||||
"mimetypesettings.cpp",
|
||||
"mimetypesettings.h",
|
||||
"mimetypesettingspage.ui",
|
||||
"minisplitter.cpp", "minisplitter.h",
|
||||
"modemanager.cpp", "modemanager.h",
|
||||
"navigationsubwidget.cpp", "navigationsubwidget.h",
|
||||
"navigationwidget.cpp", "navigationwidget.h",
|
||||
"opendocumentstreeview.cpp", "opendocumentstreeview.h",
|
||||
"outputpane.cpp", "outputpane.h",
|
||||
"outputpanemanager.cpp", "outputpanemanager.h",
|
||||
"outputwindow.cpp", "outputwindow.h",
|
||||
"patchtool.cpp", "patchtool.h",
|
||||
"plugindialog.cpp", "plugindialog.h",
|
||||
"reaper.cpp", "reaper.h", "reaper_p.h",
|
||||
"rightpane.cpp", "rightpane.h",
|
||||
"settingsdatabase.cpp", "settingsdatabase.h",
|
||||
"shellcommand.cpp", "shellcommand.h",
|
||||
"sidebar.cpp", "sidebar.h",
|
||||
"sidebarwidget.cpp", "sidebarwidget.h",
|
||||
"statusbarmanager.cpp", "statusbarmanager.h",
|
||||
"statusbarwidget.cpp", "statusbarwidget.h",
|
||||
"styleanimator.cpp", "styleanimator.h",
|
||||
"systemsettings.cpp", "systemsettings.h", "systemsettings.ui",
|
||||
"textdocument.cpp", "textdocument.h",
|
||||
"themechooser.cpp", "themechooser.h",
|
||||
"toolsettings.cpp", "toolsettings.h",
|
||||
"variablechooser.cpp", "variablechooser.h",
|
||||
"vcsmanager.cpp", "vcsmanager.h",
|
||||
"versiondialog.cpp", "versiondialog.h",
|
||||
"windowsupport.cpp", "windowsupport.h"
|
||||
"minisplitter.cpp",
|
||||
"minisplitter.h",
|
||||
"modemanager.cpp",
|
||||
"modemanager.h",
|
||||
"navigationsubwidget.cpp",
|
||||
"navigationsubwidget.h",
|
||||
"navigationwidget.cpp",
|
||||
"navigationwidget.h",
|
||||
"opendocumentstreeview.cpp",
|
||||
"opendocumentstreeview.h",
|
||||
"outputpane.cpp",
|
||||
"outputpane.h",
|
||||
"outputpanemanager.cpp",
|
||||
"outputpanemanager.h",
|
||||
"outputwindow.cpp",
|
||||
"outputwindow.h",
|
||||
"patchtool.cpp",
|
||||
"patchtool.h",
|
||||
"plugindialog.cpp",
|
||||
"plugindialog.h",
|
||||
"reaper.cpp",
|
||||
"reaper.h",
|
||||
"reaper_p.h",
|
||||
"rightpane.cpp",
|
||||
"rightpane.h",
|
||||
"settingsdatabase.cpp",
|
||||
"settingsdatabase.h",
|
||||
"shellcommand.cpp",
|
||||
"shellcommand.h",
|
||||
"sidebar.cpp",
|
||||
"sidebar.h",
|
||||
"sidebarwidget.cpp",
|
||||
"sidebarwidget.h",
|
||||
"statusbarmanager.cpp",
|
||||
"statusbarmanager.h",
|
||||
"statusbarwidget.cpp",
|
||||
"statusbarwidget.h",
|
||||
"styleanimator.cpp",
|
||||
"styleanimator.h",
|
||||
"systemsettings.cpp",
|
||||
"systemsettings.h",
|
||||
"systemsettings.ui",
|
||||
"textdocument.cpp",
|
||||
"textdocument.h",
|
||||
"themechooser.cpp",
|
||||
"themechooser.h",
|
||||
"toolsettings.cpp",
|
||||
"toolsettings.h",
|
||||
"variablechooser.cpp",
|
||||
"variablechooser.h",
|
||||
"vcsmanager.cpp",
|
||||
"vcsmanager.h",
|
||||
"versiondialog.cpp",
|
||||
"versiondialog.h",
|
||||
"windowsupport.cpp",
|
||||
"windowsupport.h",
|
||||
]
|
||||
}
|
||||
|
||||
|
162
src/plugins/coreplugin/menubarfilter.cpp
Normal file
162
src/plugins/coreplugin/menubarfilter.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "menubarfilter.h"
|
||||
|
||||
#include "actionmanager/actioncontainer.h"
|
||||
#include "actionmanager/actionmanager.h"
|
||||
#include "coreconstants.h"
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/asconst.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/stringutils.h>
|
||||
|
||||
#include <QMenuBar>
|
||||
#include <QPointer>
|
||||
#include <QRegularExpression>
|
||||
|
||||
using namespace Core::Internal;
|
||||
using namespace Core;
|
||||
|
||||
MenuBarFilter::MenuBarFilter()
|
||||
{
|
||||
setId("Actions from the menu");
|
||||
setDisplayName(tr("Actions from the Menu"));
|
||||
setShortcutString("t");
|
||||
}
|
||||
|
||||
static const QList<QAction *> menuBarActions()
|
||||
{
|
||||
QMenuBar *menuBar = Core::ActionManager::actionContainer(Constants::MENU_BAR)->menuBar();
|
||||
QTC_ASSERT(menuBar, return {});
|
||||
return menuBar->actions();
|
||||
}
|
||||
|
||||
QList<LocatorFilterEntry> MenuBarFilter::matchesFor(QFutureInterface<LocatorFilterEntry> &future,
|
||||
const QString &entry)
|
||||
{
|
||||
Q_UNUSED(future);
|
||||
static const QString separators = ". >/";
|
||||
static const QRegularExpression seperatorRegExp(QString("[%1]").arg(separators));
|
||||
QList<LocatorFilterEntry> entries;
|
||||
QString normalized = entry;
|
||||
normalized.replace(seperatorRegExp, separators.at(0));
|
||||
const QStringList entryPath = normalized.split(separators.at(0), QString::SkipEmptyParts);
|
||||
QVector<const QMenu *> processedMenus;
|
||||
for (QAction* action : menuBarActions())
|
||||
entries << matchesForAction(action, entryPath, QStringList(), processedMenus);
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
void MenuBarFilter::accept(LocatorFilterEntry selection, QString *newText,
|
||||
int *selectionStart, int *selectionLength) const
|
||||
{
|
||||
Q_UNUSED(newText);
|
||||
Q_UNUSED(selectionStart);
|
||||
Q_UNUSED(selectionLength);
|
||||
if (auto action = selection.internalData.value<QPointer<QAction>>())
|
||||
action->trigger();
|
||||
}
|
||||
|
||||
void MenuBarFilter::refresh(QFutureInterface<void> &future)
|
||||
{
|
||||
Q_UNUSED(future);
|
||||
}
|
||||
|
||||
QList<LocatorFilterEntry> MenuBarFilter::matchesForAction(QAction *action,
|
||||
const QStringList &entryPath,
|
||||
const QStringList &path,
|
||||
QVector<const QMenu *> &processedMenus)
|
||||
{
|
||||
QList<LocatorFilterEntry> entries;
|
||||
if (!action->isEnabled())
|
||||
return entries;
|
||||
const QString text = Utils::stripAccelerator(action->text());
|
||||
if (QMenu *menu = action->menu()) {
|
||||
if (processedMenus.contains(menu))
|
||||
return entries;
|
||||
processedMenus.append(menu);
|
||||
if (menu->isEnabled()) {
|
||||
const QList<QAction *> &actions = menu->actions();
|
||||
QStringList menuPath(path);
|
||||
menuPath << text;
|
||||
for (QAction *menuAction : actions)
|
||||
entries << matchesForAction(menuAction, entryPath, menuPath, processedMenus);
|
||||
}
|
||||
} else if (!text.isEmpty()) {
|
||||
int entryIndex = 0;
|
||||
int entryLength = 0;
|
||||
int pathIndex = 0;
|
||||
LocatorFilterEntry::HighlightInfo::DataType highlightType =
|
||||
LocatorFilterEntry::HighlightInfo::DisplayName;
|
||||
const QString pathText = path.join(" > ");
|
||||
QStringList actionPath(path);
|
||||
if (!entryPath.isEmpty()) {
|
||||
actionPath << text;
|
||||
for (const QString &entry : entryPath) {
|
||||
const QRegularExpression re(".*" + entry + ".*",
|
||||
QRegularExpression::CaseInsensitiveOption);
|
||||
pathIndex = actionPath.indexOf(re, pathIndex);
|
||||
if (pathIndex < 0)
|
||||
return entries;
|
||||
}
|
||||
const QString &lastEntry(entryPath.last());
|
||||
entryLength = lastEntry.length();
|
||||
entryIndex = text.indexOf(lastEntry, 0, Qt::CaseInsensitive);
|
||||
if (entryIndex >= 0) {
|
||||
highlightType = LocatorFilterEntry::HighlightInfo::DisplayName;
|
||||
} else {
|
||||
entryIndex = pathText.indexOf(lastEntry, 0, Qt::CaseInsensitive);
|
||||
QTC_ASSERT(entryIndex >= 0, return entries);
|
||||
highlightType = LocatorFilterEntry::HighlightInfo::ExtraInfo;
|
||||
}
|
||||
}
|
||||
LocatorFilterEntry filterEntry(this, text, QVariant(), action->icon());
|
||||
filterEntry.internalData.setValue(QPointer<QAction>(action));
|
||||
filterEntry.extraInfo = pathText;
|
||||
filterEntry.highlightInfo = {entryIndex, entryLength, highlightType};
|
||||
entries << filterEntry;
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
static void requestMenuUpdate(const QAction* action)
|
||||
{
|
||||
if (QMenu *menu = action->menu()) {
|
||||
emit menu->aboutToShow();
|
||||
const QList<QAction *> &actions = menu->actions();
|
||||
for (const QAction *menuActions : actions)
|
||||
requestMenuUpdate(menuActions);
|
||||
}
|
||||
}
|
||||
|
||||
void Core::Internal::MenuBarFilter::prepareSearch(const QString &entry)
|
||||
{
|
||||
Q_UNUSED(entry);
|
||||
for (const QAction *action : menuBarActions())
|
||||
requestMenuUpdate(action);
|
||||
}
|
58
src/plugins/coreplugin/menubarfilter.h
Normal file
58
src/plugins/coreplugin/menubarfilter.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <coreplugin/locator/ilocatorfilter.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAction;
|
||||
class QMenu;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core {
|
||||
namespace Internal {
|
||||
|
||||
class MenuBarFilter : public ILocatorFilter
|
||||
{
|
||||
public:
|
||||
MenuBarFilter();
|
||||
|
||||
QList<LocatorFilterEntry> matchesFor(QFutureInterface<LocatorFilterEntry> &future,
|
||||
const QString &entry) override;
|
||||
void accept(LocatorFilterEntry selection, QString *newText,
|
||||
int *selectionStart, int *selectionLength) const override;
|
||||
void refresh(QFutureInterface<void> &future) override;
|
||||
void prepareSearch(const QString &entry) override;
|
||||
private:
|
||||
QList<LocatorFilterEntry> matchesForAction(QAction *action,
|
||||
const QStringList &entryPath,
|
||||
const QStringList &path,
|
||||
QVector<const QMenu *> &processedMenus);
|
||||
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Core
|
Reference in New Issue
Block a user