Optionally show locator popup centered

when using the menu item or shortcut.
Turn on with "Open as Centered Popup" in the "filter" menu in
the locator input field. Default is off.

Change-Id: Ic1e0d2188aba924d25fe5b6f0048ae8c3adf1aa8
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Eike Ziller
2022-07-05 12:07:27 +02:00
parent 60f5275edf
commit d3354d1999
5 changed files with 92 additions and 33 deletions

View File

@@ -70,6 +70,7 @@ static Locator *m_instance = nullptr;
const char kDirectoryFilterPrefix[] = "directory"; const char kDirectoryFilterPrefix[] = "directory";
const char kUrlFilterPrefix[] = "url"; const char kUrlFilterPrefix[] = "url";
const char kUseCenteredPopup[] = "UseCenteredPopupForShortcut";
class LocatorData class LocatorData
{ {
@@ -189,8 +190,10 @@ void Locator::loadSettings()
// TOOD remove a few versions after 4.15 // TOOD remove a few versions after 4.15
const QString settingsGroup = settings->contains("Locator") ? QString("Locator") const QString settingsGroup = settings->contains("Locator") ? QString("Locator")
: QString("QuickOpen"); : QString("QuickOpen");
const Settings def;
settings->beginGroup(settingsGroup); settings->beginGroup(settingsGroup);
m_refreshTimer.setInterval(settings->value("RefreshInterval", 60).toInt() * 60000); m_refreshTimer.setInterval(settings->value("RefreshInterval", 60).toInt() * 60000);
m_settings.useCenteredPopup = settings->value(kUseCenteredPopup, def.useCenteredPopup).toBool();
for (ILocatorFilter *filter : qAsConst(m_filters)) { for (ILocatorFilter *filter : qAsConst(m_filters)) {
if (settings->contains(filter->id().toString())) { if (settings->contains(filter->id().toString())) {
@@ -313,11 +316,13 @@ void Locator::saveSettings() const
if (!m_settingsInitialized) if (!m_settingsInitialized)
return; return;
const Settings def;
SettingsDatabase *s = ICore::settingsDatabase(); SettingsDatabase *s = ICore::settingsDatabase();
s->beginTransaction(); s->beginTransaction();
s->beginGroup("Locator"); s->beginGroup("Locator");
s->remove(QString()); s->remove(QString());
s->setValue("RefreshInterval", refreshInterval()); s->setValue("RefreshInterval", refreshInterval());
s->setValueWithDefault(kUseCenteredPopup, m_settings.useCenteredPopup, def.useCenteredPopup);
for (ILocatorFilter *filter : m_filters) { for (ILocatorFilter *filter : m_filters) {
if (!m_customFilters.contains(filter) && filter->id().isValid()) { if (!m_customFilters.contains(filter) && filter->id().isValid()) {
const QByteArray state = filter->saveState(); const QByteArray state = filter->saveState();
@@ -386,6 +391,16 @@ void Locator::setRefreshInterval(int interval)
m_refreshTimer.start(); m_refreshTimer.start();
} }
bool Locator::useCenteredPopupForShortcut()
{
return m_instance->m_settings.useCenteredPopup;
}
void Locator::setUseCenteredPopupForShortcut(bool center)
{
m_instance->m_settings.useCenteredPopup = center;
}
void Locator::refresh(QList<ILocatorFilter *> filters) void Locator::refresh(QList<ILocatorFilter *> filters)
{ {
if (m_shuttingDown) if (m_shuttingDown)
@@ -410,5 +425,27 @@ void Locator::refresh(QList<ILocatorFilter *> filters)
}); });
} }
void Locator::showFilter(ILocatorFilter *filter, LocatorWidget *widget)
{
QTC_ASSERT(filter, return );
QTC_ASSERT(widget, return );
QString searchText = LocatorManager::tr("<type here>");
const QString currentText = widget->currentText().trimmed();
// add shortcut string at front or replace existing shortcut string
if (!currentText.isEmpty()) {
searchText = currentText;
const QList<ILocatorFilter *> allFilters = Locator::filters();
for (ILocatorFilter *otherfilter : allFilters) {
if (currentText.startsWith(otherfilter->shortcutString() + ' ')) {
searchText = currentText.mid(otherfilter->shortcutString().length() + 1);
break;
}
}
}
widget->showText(filter->shortcutString() + ' ' + searchText,
filter->shortcutString().length() + 1,
searchText.length());
}
} // namespace Internal } // namespace Internal
} // namespace Core } // namespace Core

View File

@@ -26,7 +26,6 @@
#pragma once #pragma once
#include "ilocatorfilter.h" #include "ilocatorfilter.h"
#include "locatorconstants.h"
#include <coreplugin/actionmanager/command.h> #include <coreplugin/actionmanager/command.h>
#include <extensionsystem/iplugin.h> #include <extensionsystem/iplugin.h>
@@ -41,6 +40,7 @@ namespace Core {
namespace Internal { namespace Internal {
class LocatorData; class LocatorData;
class LocatorWidget;
class Locator : public QObject class Locator : public QObject
{ {
@@ -65,6 +65,11 @@ public:
int refreshInterval() const; int refreshInterval() const;
void setRefreshInterval(int interval); void setRefreshInterval(int interval);
static bool useCenteredPopupForShortcut();
static void setUseCenteredPopupForShortcut(bool center);
static void showFilter(ILocatorFilter *filter, LocatorWidget *widget);
signals: signals:
void filtersChanged(); void filtersChanged();
@@ -79,8 +84,14 @@ private:
LocatorData *m_locatorData = nullptr; LocatorData *m_locatorData = nullptr;
struct Settings
{
bool useCenteredPopup = false;
};
bool m_shuttingDown = false; bool m_shuttingDown = false;
bool m_settingsInitialized = false; bool m_settingsInitialized = false;
Settings m_settings;
QList<ILocatorFilter *> m_filters; QList<ILocatorFilter *> m_filters;
QList<ILocatorFilter *> m_customFilters; QList<ILocatorFilter *> m_customFilters;
QMap<Utils::Id, QAction *> m_filterActionMap; QMap<Utils::Id, QAction *> m_filterActionMap;

View File

@@ -57,11 +57,13 @@ static LocatorWidget *locatorWidget()
// if that is a popup, try to find a better one // if that is a popup, try to find a better one
if (window->windowFlags() & Qt::Popup && window->parentWidget()) if (window->windowFlags() & Qt::Popup && window->parentWidget())
window = window->parentWidget()->window(); window = window->parentWidget()->window();
if (!Locator::useCenteredPopupForShortcut()) {
if (auto *widget = Aggregation::query<LocatorWidget>(window)) { if (auto *widget = Aggregation::query<LocatorWidget>(window)) {
if (popup) if (popup)
popup->close(); popup->close();
return widget; return widget;
} }
}
if (!popup) { if (!popup) {
popup = createLocatorPopup(Locator::instance(), window); popup = createLocatorPopup(Locator::instance(), window);
popup->show(); popup->show();
@@ -71,23 +73,7 @@ static LocatorWidget *locatorWidget()
void LocatorManager::showFilter(ILocatorFilter *filter) void LocatorManager::showFilter(ILocatorFilter *filter)
{ {
QTC_ASSERT(filter, return); Locator::showFilter(filter, locatorWidget());
QString searchText = tr("<type here>");
const QString currentText = locatorWidget()->currentText().trimmed();
// add shortcut string at front or replace existing shortcut string
if (!currentText.isEmpty()) {
searchText = currentText;
const QList<ILocatorFilter *> allFilters = Locator::filters();
for (ILocatorFilter *otherfilter : allFilters) {
if (currentText.startsWith(otherfilter->shortcutString() + ' ')) {
searchText = currentText.mid(otherfilter->shortcutString().length() + 1);
break;
}
}
}
show(filter->shortcutString() + ' ' + searchText,
filter->shortcutString().length() + 1,
searchText.length());
} }
void LocatorManager::show(const QString &text, void LocatorManager::show(const QString &text,

View File

@@ -28,6 +28,7 @@
#include "ilocatorfilter.h" #include "ilocatorfilter.h"
#include "locator.h" #include "locator.h"
#include "locatorconstants.h" #include "locatorconstants.h"
#include "locatormanager.h"
#include "locatorsearchutils.h" #include "locatorsearchutils.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
@@ -328,7 +329,7 @@ void CenteredLocatorPopup::doUpdateGeometry()
const QSize size = preferredSize(); const QSize size = preferredSize();
const QSize parentSize = parentWidget()->size(); const QSize parentSize = parentWidget()->size();
const QPoint local((parentSize.width() - size.width()) / 2, const QPoint local((parentSize.width() - size.width()) / 2,
parentSize.height() / 2 - size.height()); (parentSize.height() - size.height()) / 2);
const QPoint pos = parentWidget()->mapToGlobal(local); const QPoint pos = parentWidget()->mapToGlobal(local);
QRect rect(pos, size); QRect rect(pos, size);
// invisible widget doesn't have the right screen set yet, so use the parent widget to // invisible widget doesn't have the right screen set yet, so use the parent widget to
@@ -568,12 +569,13 @@ bool CompletionList::eventFilter(QObject *watched, QEvent *event)
// =========== LocatorWidget =========== // =========== LocatorWidget ===========
LocatorWidget::LocatorWidget(Locator *locator) : LocatorWidget::LocatorWidget(Locator *locator)
m_locatorModel(new LocatorModel(this)), : m_locatorModel(new LocatorModel(this))
m_filterMenu(new QMenu(this)), , m_filterMenu(new QMenu(this))
m_refreshAction(new QAction(tr("Refresh"), this)), , m_centeredPopupAction(new QAction(tr("Open as Centered Popup")))
m_configureAction(new QAction(ICore::msgShowOptionsDialog(), this)), , m_refreshAction(new QAction(tr("Refresh"), this))
m_fileLineEdit(new Utils::FancyLineEdit) , m_configureAction(new QAction(ICore::msgShowOptionsDialog(), this))
, m_fileLineEdit(new Utils::FancyLineEdit)
{ {
setAttribute(Qt::WA_Hover); setAttribute(Qt::WA_Hover);
setFocusProxy(m_fileLineEdit); setFocusProxy(m_fileLineEdit);
@@ -602,6 +604,19 @@ LocatorWidget::LocatorWidget(Locator *locator) :
m_fileLineEdit->installEventFilter(this); m_fileLineEdit->installEventFilter(this);
this->installEventFilter(this); this->installEventFilter(this);
m_centeredPopupAction->setCheckable(true);
m_centeredPopupAction->setChecked(Locator::useCenteredPopupForShortcut());
connect(m_filterMenu, &QMenu::aboutToShow, this, [this] {
m_centeredPopupAction->setChecked(Locator::useCenteredPopupForShortcut());
});
connect(m_centeredPopupAction, &QAction::toggled, locator, [locator](bool toggled) {
if (toggled != Locator::useCenteredPopupForShortcut()) {
Locator::setUseCenteredPopupForShortcut(toggled);
QMetaObject::invokeMethod(locator, [] { LocatorManager::show({}); });
}
});
m_filterMenu->addAction(m_centeredPopupAction);
m_filterMenu->addAction(m_refreshAction); m_filterMenu->addAction(m_refreshAction);
m_filterMenu->addAction(m_configureAction); m_filterMenu->addAction(m_configureAction);
@@ -669,11 +684,16 @@ void LocatorWidget::updateFilterList()
m_filterMenu->clear(); m_filterMenu->clear();
const QList<ILocatorFilter *> filters = Locator::filters(); const QList<ILocatorFilter *> filters = Locator::filters();
for (ILocatorFilter *filter : filters) { for (ILocatorFilter *filter : filters) {
Command *cmd = ActionManager::command(filter->actionId()); if (filter->shortcutString().isEmpty() || filter->isHidden())
if (cmd) continue;
m_filterMenu->addAction(cmd->action()); QAction *action = m_filterMenu->addAction(filter->displayName());
action->setToolTip(filter->description());
connect(action, &QAction::triggered, this, [this, filter] {
Locator::showFilter(filter, this);
});
} }
m_filterMenu->addSeparator(); m_filterMenu->addSeparator();
m_filterMenu->addAction(m_centeredPopupAction);
m_filterMenu->addAction(m_refreshAction); m_filterMenu->addAction(m_refreshAction);
m_filterMenu->addAction(m_configureAction); m_filterMenu->addAction(m_configureAction);
} }
@@ -1038,6 +1058,10 @@ LocatorPopup *createLocatorPopup(Locator *locator, QWidget *parent)
{ {
auto widget = new LocatorWidget(locator); auto widget = new LocatorWidget(locator);
auto popup = new CenteredLocatorPopup(widget, parent); auto popup = new CenteredLocatorPopup(widget, parent);
auto layout = qobject_cast<QVBoxLayout *>(popup->layout());
if (QTC_GUARD(layout))
layout->insertWidget(0, widget);
else
popup->layout()->addWidget(widget); popup->layout()->addWidget(widget);
popup->setWindowFlags(Qt::Popup); popup->setWindowFlags(Qt::Popup);
popup->setAttribute(Qt::WA_DeleteOnClose); popup->setAttribute(Qt::WA_DeleteOnClose);

View File

@@ -103,6 +103,7 @@ private:
static LocatorWidget *m_sharedFutureOrigin; static LocatorWidget *m_sharedFutureOrigin;
QMenu *m_filterMenu = nullptr; QMenu *m_filterMenu = nullptr;
QAction *m_centeredPopupAction = nullptr;
QAction *m_refreshAction = nullptr; QAction *m_refreshAction = nullptr;
QAction *m_configureAction = nullptr; QAction *m_configureAction = nullptr;
Utils::FancyLineEdit *m_fileLineEdit = nullptr; Utils::FancyLineEdit *m_fileLineEdit = nullptr;