Commit 247639d9 authored by Eike Ziller's avatar Eike Ziller
Browse files

Remove 1-1 dependency between locator and locator input widget



Add possibility for filters to set a new search text when accepting
an entry.
Move placeholder text update from locator manager to widget.
Propagate filter update through signal-slot connection instead of directly.
LocatorManager::show is the only place left that directly references the locator widget.

Change-Id: Id61354d9f166c2af8c9d5528ad8998c7c6b8e1ab
Reviewed-by: David Schulz's avatarDavid Schulz <david.schulz@qt.io>
parent 19a47fed
......@@ -83,8 +83,12 @@ QList<Core::LocatorFilterEntry> CMakeLocatorFilter::matchesFor(QFutureInterface<
return m_result;
}
void CMakeLocatorFilter::accept(Core::LocatorFilterEntry selection) const
void CMakeLocatorFilter::accept(Core::LocatorFilterEntry selection,
QString *newText, int *selectionStart, int *selectionLength) const
{
Q_UNUSED(newText)
Q_UNUSED(selectionStart)
Q_UNUSED(selectionLength)
// Get the project containing the target selected
const auto cmakeProject = qobject_cast<CMakeProject *>(
Utils::findOrDefault(SessionManager::projects(), [selection](Project *p) {
......
......@@ -40,7 +40,8 @@ public:
void prepareSearch(const QString &entry) override;
QList<Core::LocatorFilterEntry> matchesFor(QFutureInterface<Core::LocatorFilterEntry> &future,
const QString &entry) override;
void accept(Core::LocatorFilterEntry selection) const override;
void accept(Core::LocatorFilterEntry selection,
QString *newText, int *selectionStart, int *selectionLength) const override;
void refresh(QFutureInterface<void> &future) override;
private:
......
......@@ -180,8 +180,12 @@ QList<LocatorFilterEntry> BaseFileFilter::matchesFor(QFutureInterface<LocatorFil
return betterEntries;
}
void BaseFileFilter::accept(LocatorFilterEntry selection) const
void BaseFileFilter::accept(LocatorFilterEntry selection,
QString *newText, int *selectionStart, int *selectionLength) const
{
Q_UNUSED(newText)
Q_UNUSED(selectionStart)
Q_UNUSED(selectionLength)
EditorManager::openEditor(selection.internalData.toString(), Id(),
EditorManager::CanContainLineAndColumnNumber);
}
......
......@@ -72,7 +72,8 @@ public:
void prepareSearch(const QString &entry) override;
QList<LocatorFilterEntry> matchesFor(QFutureInterface<LocatorFilterEntry> &future,
const QString &entry) override;
void accept(LocatorFilterEntry selection) const override;
void accept(LocatorFilterEntry selection,
QString *newText, int *selectionStart, int *selectionLength) const override;
protected:
void setFileIterator(Iterator *iterator);
......
......@@ -95,8 +95,12 @@ QList<LocatorFilterEntry> CommandLocator::matchesFor(QFutureInterface<LocatorFil
return betterEntries;
}
void CommandLocator::accept(LocatorFilterEntry entry) const
void CommandLocator::accept(LocatorFilterEntry entry,
QString *newText, int *selectionStart, int *selectionLength) const
{
Q_UNUSED(newText)
Q_UNUSED(selectionStart)
Q_UNUSED(selectionLength)
// Retrieve action via index.
const int index = entry.internalData.toInt();
QTC_ASSERT(index >= 0 && index < d->commands.size(), return);
......
......@@ -47,7 +47,8 @@ public:
QList<LocatorFilterEntry> matchesFor(QFutureInterface<LocatorFilterEntry> &future,
const QString &entry) override;
void accept(LocatorFilterEntry selection) const override;
void accept(LocatorFilterEntry selection,
QString *newText, int *selectionStart, int *selectionLength) const override;
void refresh(QFutureInterface<void> &future) override;
private:
......
......@@ -79,8 +79,12 @@ QList<LocatorFilterEntry> ExecuteFilter::matchesFor(QFutureInterface<LocatorFilt
return value;
}
void ExecuteFilter::accept(LocatorFilterEntry selection) const
void ExecuteFilter::accept(LocatorFilterEntry selection,
QString *newText, int *selectionStart, int *selectionLength) const
{
Q_UNUSED(newText)
Q_UNUSED(selectionStart)
Q_UNUSED(selectionLength)
ExecuteFilter *p = const_cast<ExecuteFilter *>(this);
const QString value = selection.displayName.trimmed();
......
......@@ -51,7 +51,8 @@ public:
ExecuteFilter();
QList<LocatorFilterEntry> matchesFor(QFutureInterface<LocatorFilterEntry> &future,
const QString &entry) override;
void accept(LocatorFilterEntry selection) const override;
void accept(LocatorFilterEntry selection,
QString *newText, int *selectionStart, int *selectionLength) const override;
void refresh(QFutureInterface<void> &) override {}
private:
......
......@@ -47,8 +47,12 @@ QList<LocatorFilterEntry> ExternalToolsFilter::matchesFor(QFutureInterface<Locat
return m_results;
}
void ExternalToolsFilter::accept(LocatorFilterEntry selection) const
void ExternalToolsFilter::accept(LocatorFilterEntry selection,
QString *newText, int *selectionStart, int *selectionLength) const
{
Q_UNUSED(newText)
Q_UNUSED(selectionStart)
Q_UNUSED(selectionLength)
auto tool = selection.internalData.value<ExternalTool *>();
QTC_ASSERT(tool, return);
......
......@@ -38,7 +38,8 @@ public:
QList<LocatorFilterEntry> matchesFor(QFutureInterface<LocatorFilterEntry> &future,
const QString &entry) override;
void accept(LocatorFilterEntry selection) const 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;
......
......@@ -57,8 +57,7 @@ QList<LocatorFilterEntry> *categorize(const QString &entry, const QString &candi
} // anynoumous namespace
FileSystemFilter::FileSystemFilter(LocatorWidget *locatorWidget)
: m_locatorWidget(locatorWidget)
FileSystemFilter::FileSystemFilter()
{
setId("Files in file system");
setDisplayName(tr("Files in File System"));
......@@ -148,15 +147,18 @@ QList<LocatorFilterEntry> FileSystemFilter::matchesFor(QFutureInterface<LocatorF
return betterEntries;
}
void FileSystemFilter::accept(LocatorFilterEntry selection) const
void FileSystemFilter::accept(LocatorFilterEntry selection,
QString *newText, int *selectionStart, int *selectionLength) const
{
Q_UNUSED(selectionLength)
QString fileName = selection.fileName;
QFileInfo info(fileName);
if (info.isDir()) {
QString value = shortcutString();
value += QLatin1Char(' ');
value += QDir::toNativeSeparators(info.absoluteFilePath() + QLatin1Char('/'));
m_locatorWidget->show(value, value.length());
*newText = value;
*selectionStart = value.length();
return;
} else if (!info.exists()) {
QFile file(selection.internalData.toString());
......
......@@ -36,25 +36,23 @@
namespace Core {
namespace Internal {
class LocatorWidget;
class FileSystemFilter : public ILocatorFilter
{
Q_OBJECT
public:
explicit FileSystemFilter(LocatorWidget *locatorWidget);
explicit FileSystemFilter();
void prepareSearch(const QString &entry) override;
QList<LocatorFilterEntry> matchesFor(QFutureInterface<LocatorFilterEntry> &future,
const QString &entry) override;
void accept(LocatorFilterEntry selection) const override;
void accept(LocatorFilterEntry selection,
QString *newText, int *selectionStart, int *selectionLength) const override;
QByteArray saveState() const override;
void restoreState(const QByteArray &state) override;
bool openConfigDialog(QWidget *parent, bool &needsRefresh) override;
void refresh(QFutureInterface<void> &) override {}
private:
LocatorWidget *m_locatorWidget;
bool m_includeHidden = true;
QString m_currentDocumentDirectory;
};
......
......@@ -419,10 +419,12 @@ void ILocatorFilter::setConfigurable(bool configurable)
*/
/*!
\fn void ILocatorFilter::accept(LocatorFilterEntry selection) const
\fn void ILocatorFilter::accept(LocatorFilterEntry selection, QString *newText, int *selectionStart, int *selectionLength) const
Called with the entry specified by \a selection when the user activates it
in the result list.
Implementations can return a new search term \a newText, which has \a selectionLength characters
starting from \a selectionStart preselected, and the cursor set to the end of the selection.
*/
/*!
......
......@@ -117,7 +117,8 @@ public:
virtual QList<LocatorFilterEntry> matchesFor(QFutureInterface<LocatorFilterEntry> &future, const QString &entry) = 0;
virtual void accept(LocatorFilterEntry selection) const = 0;
virtual void accept(LocatorFilterEntry selection,
QString *newText, int *selectionStart, int *selectionLength) const = 0;
virtual void refresh(QFutureInterface<void> &future) = 0;
......
......@@ -48,6 +48,7 @@
#include <utils/algorithm.h>
#include <utils/mapreduce.h>
#include <utils/qtcassert.h>
#include <utils/utilsicons.h>
#include <QSettings>
#include <QtPlugin>
......@@ -89,31 +90,29 @@ void Locator::initialize(CorePlugin *corePlugin, const QStringList &, QString *)
m_settingsPage = new LocatorSettingsPage(this);
m_corePlugin->addObject(m_settingsPage);
m_locatorWidget = new LocatorWidget(this);
m_locatorWidget->setEnabled(false);
StatusBarWidget *view = new StatusBarWidget;
view->setWidget(m_locatorWidget);
view->setContext(Context("LocatorWidget"));
view->setPosition(StatusBarWidget::First);
m_corePlugin->addAutoReleasedObject(view);
QAction *action = new QAction(m_locatorWidget->windowIcon(), m_locatorWidget->windowTitle(), this);
QAction *action = new QAction(Utils::Icons::ZOOM.icon(), tr("Locate..."), this);
Command *cmd = ActionManager::registerAction(action, Constants::LOCATE);
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+K")));
connect(action, &QAction::triggered, this, &Locator::openLocator);
connect(cmd, &Command::keySequenceChanged,
this, [this, cmd]() { updatePlaceholderText(cmd); });
updatePlaceholderText(cmd);
connect(action, &QAction::triggered, this, [] {
LocatorManager::show(QString());
});
ActionContainer *mtools = ActionManager::actionContainer(Constants::M_TOOLS);
mtools->addAction(cmd);
m_corePlugin->addObject(new LocatorManager(m_locatorWidget));
auto locatorWidget = new LocatorWidget(this);
StatusBarWidget *view = new StatusBarWidget;
view->setWidget(locatorWidget);
view->setContext(Context("LocatorWidget"));
view->setPosition(StatusBarWidget::First);
m_corePlugin->addAutoReleasedObject(view);
m_corePlugin->addObject(new LocatorManager(locatorWidget));
m_openDocumentsFilter = new OpenDocumentsFilter;
m_corePlugin->addObject(m_openDocumentsFilter);
m_fileSystemFilter = new FileSystemFilter(m_locatorWidget);
m_fileSystemFilter = new FileSystemFilter();
m_corePlugin->addObject(m_fileSystemFilter);
m_executeFilter = new ExecuteFilter();
......@@ -122,7 +121,7 @@ void Locator::initialize(CorePlugin *corePlugin, const QStringList &, QString *)
m_externalToolsFilter = new ExternalToolsFilter;
m_corePlugin->addObject(m_externalToolsFilter);
m_corePlugin->addAutoReleasedObject(new LocatorFiltersFilter(this, m_locatorWidget));
m_corePlugin->addAutoReleasedObject(new LocatorFiltersFilter(this));
#ifdef Q_OS_OSX
m_corePlugin->addAutoReleasedObject(new SpotlightLocatorFilter);
#endif
......@@ -130,21 +129,6 @@ void Locator::initialize(CorePlugin *corePlugin, const QStringList &, QString *)
connect(ICore::instance(), &ICore::saveSettingsRequested, this, &Locator::saveSettings);
}
void Locator::updatePlaceholderText(Command *command)
{
QTC_ASSERT(command, return);
if (command->keySequence().isEmpty())
m_locatorWidget->setPlaceholderText(tr("Type to locate"));
else
m_locatorWidget->setPlaceholderText(tr("Type to locate (%1)").arg(
command->keySequence().toString(QKeySequence::NativeText)));
}
void Locator::openLocator()
{
m_locatorWidget->show(QString());
}
void Locator::extensionsInitialized()
{
m_filters = ExtensionSystem::PluginManager::getObjects<ILocatorFilter>();
......@@ -198,11 +182,10 @@ void Locator::loadSettings()
settings->endGroup();
settings->endGroup();
m_locatorWidget->updateFilterList();
m_locatorWidget->setEnabled(true);
if (m_refreshTimer.interval() > 0)
m_refreshTimer.start();
m_settingsInitialized = true;
emit filtersChanged();
}
void Locator::updateEditorManagerPlaceholderText()
......@@ -296,7 +279,7 @@ void Locator::setFilters(QList<ILocatorFilter *> f)
{
m_filters = f;
updateEditorManagerPlaceholderText(); // possibly some shortcut changed
m_locatorWidget->updateFilterList();
emit filtersChanged();
}
void Locator::setCustomFilters(QList<ILocatorFilter *> filters)
......
......@@ -40,7 +40,6 @@ namespace Core {
namespace Internal {
class CorePlugin;
class LocatorWidget;
class OpenDocumentsFilter;
class FileSystemFilter;
class LocatorSettingsPage;
......@@ -65,17 +64,17 @@ public:
int refreshInterval();
void setRefreshInterval(int interval);
signals:
void filtersChanged();
public slots:
void refresh(QList<ILocatorFilter *> filters = QList<ILocatorFilter *>());
void saveSettings();
void openLocator();
private:
void updatePlaceholderText(Core::Command *command);
void loadSettings();
void updateEditorManagerPlaceholderText();
LocatorWidget *m_locatorWidget;
LocatorSettingsPage *m_settingsPage;
bool m_settingsInitialized = false;
......
......@@ -35,10 +35,8 @@ using namespace Core::Internal;
Q_DECLARE_METATYPE(ILocatorFilter*)
LocatorFiltersFilter::LocatorFiltersFilter(Locator *plugin,
LocatorWidget *locatorWidget):
LocatorFiltersFilter::LocatorFiltersFilter(Locator *plugin):
m_plugin(plugin),
m_locatorWidget(locatorWidget),
m_icon(Utils::Icons::NEXT.icon())
{
setId("FiltersFilter");
......@@ -87,15 +85,18 @@ QList<LocatorFilterEntry> LocatorFiltersFilter::matchesFor(QFutureInterface<Loca
return entries;
}
void LocatorFiltersFilter::accept(LocatorFilterEntry selection) const
void LocatorFiltersFilter::accept(LocatorFilterEntry selection,
QString *newText, int *selectionStart, int *selectionLength) const
{
Q_UNUSED(selectionLength)
bool ok;
int index = selection.internalData.toInt(&ok);
QTC_ASSERT(ok && index >= 0 && index < m_filterShortcutStrings.size(), return);
const QString shortcutString = m_filterShortcutStrings.at(index);
if (!shortcutString.isEmpty())
m_locatorWidget->show(shortcutString + QLatin1Char(' '),
shortcutString.length() + 1);
if (!shortcutString.isEmpty()) {
*newText = shortcutString + QLatin1Char(' ');
*selectionStart = shortcutString.length() + 1;
}
}
void LocatorFiltersFilter::refresh(QFutureInterface<void> &future)
......
......@@ -33,7 +33,6 @@ namespace Core {
namespace Internal {
class Locator;
class LocatorWidget;
/*!
This filter provides the user with the list of available Locator filters.
......@@ -44,19 +43,18 @@ class LocatorFiltersFilter : public ILocatorFilter
Q_OBJECT
public:
LocatorFiltersFilter(Locator *plugin,
LocatorWidget *locatorWidget);
LocatorFiltersFilter(Locator *plugin);
// ILocatorFilter
void prepareSearch(const QString &entry) override;
QList<LocatorFilterEntry> matchesFor(QFutureInterface<LocatorFilterEntry> &future,
const QString &entry) override;
void accept(LocatorFilterEntry selection) const override;
void accept(LocatorFilterEntry selection,
QString *newText, int *selectionStart, int *selectionLength) const override;
void refresh(QFutureInterface<void> &future) override;
private:
Locator *m_plugin;
LocatorWidget *m_locatorWidget;
QStringList m_filterShortcutStrings;
QStringList m_filterDisplayNames;
QIcon m_icon;
......
......@@ -283,7 +283,6 @@ LocatorWidget::LocatorWidget(Locator *qop) :
setAttribute(Qt::WA_Hover);
setFocusProxy(m_fileLineEdit);
setWindowTitle(tr("Locate..."));
resize(200, 90);
QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
sizePolicy.setHorizontalStretch(0);
......@@ -296,7 +295,6 @@ LocatorWidget::LocatorWidget(Locator *qop) :
layout->setMargin(0);
layout->addWidget(m_fileLineEdit);
setWindowIcon(Utils::Icons::ZOOM.icon());
const QPixmap pixmap = Utils::Icons::MAGNIFIER.pixmap();
m_fileLineEdit->setFiltering(true);
m_fileLineEdit->setButtonPixmap(Utils::FancyLineEdit::Left, pixmap);
......@@ -345,11 +343,27 @@ LocatorWidget::LocatorWidget(Locator *qop) :
m_showProgressTimer.setSingleShot(true);
m_showProgressTimer.setInterval(50); // don't show progress for < 50ms tasks
connect(&m_showProgressTimer, &QTimer::timeout, [this]() { setProgressIndicatorVisible(true);});
Command *locateCmd = ActionManager::command(Constants::LOCATE);
if (QTC_GUARD(locateCmd)) {
connect(locateCmd, &Command::keySequenceChanged, this, [this,locateCmd] {
updatePlaceholderText(locateCmd);
});
updatePlaceholderText(locateCmd);
}
connect(m_locatorPlugin, &Locator::filtersChanged, this, &LocatorWidget::updateFilterList);
updateFilterList();
}
void LocatorWidget::setPlaceholderText(const QString &text)
void LocatorWidget::updatePlaceholderText(Command *command)
{
m_fileLineEdit->setPlaceholderText(text);
QTC_ASSERT(command, return);
if (command->keySequence().isEmpty())
m_fileLineEdit->setPlaceholderText(tr("Type to locate"));
else
m_fileLineEdit->setPlaceholderText(tr("Type to locate (%1)").arg(
command->keySequence().toString(QKeySequence::NativeText)));
}
void LocatorWidget::updateFilterList()
......@@ -658,10 +672,17 @@ void LocatorWidget::acceptCurrentEntry()
if (!index.isValid())
return;
const LocatorFilterEntry entry = m_locatorModel->data(index, ItemDataRoles::ResultItemRole).value<LocatorFilterEntry>();
m_completionList->hide();
m_fileLineEdit->clearFocus();
Q_ASSERT(entry.filter != nullptr);
entry.filter->accept(entry);
QString newText;
int selectionStart = -1;
int selectionLength = 0;
entry.filter->accept(entry, &newText, &selectionStart, &selectionLength);
if (newText.isEmpty()) {
m_completionList->hide();
m_fileLineEdit->clearFocus();
} else {
show(newText, selectionStart, selectionLength);
}
}
void LocatorWidget::show(const QString &text, int selectionStart, int selectionLength)
......
......@@ -58,7 +58,7 @@ public:
void show(const QString &text, int selectionStart = -1, int selectionLength = 0);
void setPlaceholderText(const QString &text);
void updatePlaceholderText(Command *command);
private:
void showPopup();
......
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