diff --git a/src/plugins/coreplugin/locator/locator.cpp b/src/plugins/coreplugin/locator/locator.cpp index d8509cf8260..a37e87bf185 100644 --- a/src/plugins/coreplugin/locator/locator.cpp +++ b/src/plugins/coreplugin/locator/locator.cpp @@ -70,6 +70,7 @@ static Locator *m_instance = nullptr; const char kDirectoryFilterPrefix[] = "directory"; const char kUrlFilterPrefix[] = "url"; +const char kUseCenteredPopup[] = "UseCenteredPopupForShortcut"; class LocatorData { @@ -189,8 +190,10 @@ void Locator::loadSettings() // TOOD remove a few versions after 4.15 const QString settingsGroup = settings->contains("Locator") ? QString("Locator") : QString("QuickOpen"); + const Settings def; settings->beginGroup(settingsGroup); m_refreshTimer.setInterval(settings->value("RefreshInterval", 60).toInt() * 60000); + m_settings.useCenteredPopup = settings->value(kUseCenteredPopup, def.useCenteredPopup).toBool(); for (ILocatorFilter *filter : qAsConst(m_filters)) { if (settings->contains(filter->id().toString())) { @@ -313,11 +316,13 @@ void Locator::saveSettings() const if (!m_settingsInitialized) return; + const Settings def; SettingsDatabase *s = ICore::settingsDatabase(); s->beginTransaction(); s->beginGroup("Locator"); s->remove(QString()); s->setValue("RefreshInterval", refreshInterval()); + s->setValueWithDefault(kUseCenteredPopup, m_settings.useCenteredPopup, def.useCenteredPopup); for (ILocatorFilter *filter : m_filters) { if (!m_customFilters.contains(filter) && filter->id().isValid()) { const QByteArray state = filter->saveState(); @@ -386,6 +391,16 @@ void Locator::setRefreshInterval(int interval) 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 filters) { if (m_shuttingDown) @@ -410,5 +425,27 @@ void Locator::refresh(QList filters) }); } +void Locator::showFilter(ILocatorFilter *filter, LocatorWidget *widget) +{ + QTC_ASSERT(filter, return ); + QTC_ASSERT(widget, return ); + QString searchText = LocatorManager::tr(""); + const QString currentText = widget->currentText().trimmed(); + // add shortcut string at front or replace existing shortcut string + if (!currentText.isEmpty()) { + searchText = currentText; + const QList 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 Core diff --git a/src/plugins/coreplugin/locator/locator.h b/src/plugins/coreplugin/locator/locator.h index 95a6b63687b..04425f202ba 100644 --- a/src/plugins/coreplugin/locator/locator.h +++ b/src/plugins/coreplugin/locator/locator.h @@ -26,7 +26,6 @@ #pragma once #include "ilocatorfilter.h" -#include "locatorconstants.h" #include #include @@ -41,6 +40,7 @@ namespace Core { namespace Internal { class LocatorData; +class LocatorWidget; class Locator : public QObject { @@ -65,6 +65,11 @@ public: int refreshInterval() const; void setRefreshInterval(int interval); + static bool useCenteredPopupForShortcut(); + static void setUseCenteredPopupForShortcut(bool center); + + static void showFilter(ILocatorFilter *filter, LocatorWidget *widget); + signals: void filtersChanged(); @@ -79,8 +84,14 @@ private: LocatorData *m_locatorData = nullptr; + struct Settings + { + bool useCenteredPopup = false; + }; + bool m_shuttingDown = false; bool m_settingsInitialized = false; + Settings m_settings; QList m_filters; QList m_customFilters; QMap m_filterActionMap; diff --git a/src/plugins/coreplugin/locator/locatormanager.cpp b/src/plugins/coreplugin/locator/locatormanager.cpp index 5c1bb0a0b54..262af92b990 100644 --- a/src/plugins/coreplugin/locator/locatormanager.cpp +++ b/src/plugins/coreplugin/locator/locatormanager.cpp @@ -57,10 +57,12 @@ static LocatorWidget *locatorWidget() // if that is a popup, try to find a better one if (window->windowFlags() & Qt::Popup && window->parentWidget()) window = window->parentWidget()->window(); - if (auto *widget = Aggregation::query(window)) { - if (popup) - popup->close(); - return widget; + if (!Locator::useCenteredPopupForShortcut()) { + if (auto *widget = Aggregation::query(window)) { + if (popup) + popup->close(); + return widget; + } } if (!popup) { popup = createLocatorPopup(Locator::instance(), window); @@ -71,23 +73,7 @@ static LocatorWidget *locatorWidget() void LocatorManager::showFilter(ILocatorFilter *filter) { - QTC_ASSERT(filter, return); - QString searchText = tr(""); - const QString currentText = locatorWidget()->currentText().trimmed(); - // add shortcut string at front or replace existing shortcut string - if (!currentText.isEmpty()) { - searchText = currentText; - const QList 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()); + Locator::showFilter(filter, locatorWidget()); } void LocatorManager::show(const QString &text, diff --git a/src/plugins/coreplugin/locator/locatorwidget.cpp b/src/plugins/coreplugin/locator/locatorwidget.cpp index 2b05025bc39..a2da50e2681 100644 --- a/src/plugins/coreplugin/locator/locatorwidget.cpp +++ b/src/plugins/coreplugin/locator/locatorwidget.cpp @@ -28,6 +28,7 @@ #include "ilocatorfilter.h" #include "locator.h" #include "locatorconstants.h" +#include "locatormanager.h" #include "locatorsearchutils.h" #include @@ -328,7 +329,7 @@ void CenteredLocatorPopup::doUpdateGeometry() const QSize size = preferredSize(); const QSize parentSize = parentWidget()->size(); const QPoint local((parentSize.width() - size.width()) / 2, - parentSize.height() / 2 - size.height()); + (parentSize.height() - size.height()) / 2); const QPoint pos = parentWidget()->mapToGlobal(local); QRect rect(pos, size); // 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(Locator *locator) : - m_locatorModel(new LocatorModel(this)), - m_filterMenu(new QMenu(this)), - m_refreshAction(new QAction(tr("Refresh"), this)), - m_configureAction(new QAction(ICore::msgShowOptionsDialog(), this)), - m_fileLineEdit(new Utils::FancyLineEdit) +LocatorWidget::LocatorWidget(Locator *locator) + : m_locatorModel(new LocatorModel(this)) + , m_filterMenu(new QMenu(this)) + , m_centeredPopupAction(new QAction(tr("Open as Centered Popup"))) + , m_refreshAction(new QAction(tr("Refresh"), this)) + , m_configureAction(new QAction(ICore::msgShowOptionsDialog(), this)) + , m_fileLineEdit(new Utils::FancyLineEdit) { setAttribute(Qt::WA_Hover); setFocusProxy(m_fileLineEdit); @@ -602,6 +604,19 @@ LocatorWidget::LocatorWidget(Locator *locator) : m_fileLineEdit->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_configureAction); @@ -669,11 +684,16 @@ void LocatorWidget::updateFilterList() m_filterMenu->clear(); const QList filters = Locator::filters(); for (ILocatorFilter *filter : filters) { - Command *cmd = ActionManager::command(filter->actionId()); - if (cmd) - m_filterMenu->addAction(cmd->action()); + if (filter->shortcutString().isEmpty() || filter->isHidden()) + continue; + 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->addAction(m_centeredPopupAction); m_filterMenu->addAction(m_refreshAction); m_filterMenu->addAction(m_configureAction); } @@ -1038,7 +1058,11 @@ LocatorPopup *createLocatorPopup(Locator *locator, QWidget *parent) { auto widget = new LocatorWidget(locator); auto popup = new CenteredLocatorPopup(widget, parent); - popup->layout()->addWidget(widget); + auto layout = qobject_cast(popup->layout()); + if (QTC_GUARD(layout)) + layout->insertWidget(0, widget); + else + popup->layout()->addWidget(widget); popup->setWindowFlags(Qt::Popup); popup->setAttribute(Qt::WA_DeleteOnClose); return popup; diff --git a/src/plugins/coreplugin/locator/locatorwidget.h b/src/plugins/coreplugin/locator/locatorwidget.h index 9371b5aac98..8d608089a8d 100644 --- a/src/plugins/coreplugin/locator/locatorwidget.h +++ b/src/plugins/coreplugin/locator/locatorwidget.h @@ -103,6 +103,7 @@ private: static LocatorWidget *m_sharedFutureOrigin; QMenu *m_filterMenu = nullptr; + QAction *m_centeredPopupAction = nullptr; QAction *m_refreshAction = nullptr; QAction *m_configureAction = nullptr; Utils::FancyLineEdit *m_fileLineEdit = nullptr;