From 2dbed2f03dbca475d0fbd9010c5f28ecb18a745f Mon Sep 17 00:00:00 2001 From: leafyzito <34610295+leafyzito@users.noreply.github.com> Date: Sat, 24 Jan 2026 15:31:39 -0100 Subject: [PATCH] feat: add search engine selection and context menu search functionality (#6743) Reviewed-by: pajlada --- CHANGELOG.md | 1 + src/singletons/Settings.hpp | 16 ++++++ src/widgets/helper/ChannelView.cpp | 20 +++++++ src/widgets/settingspages/GeneralPage.cpp | 70 +++++++++++++++++++++++ 4 files changed, 107 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f861f18a..613ca40b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unversioned +- Minor: Add search engine selection for context menu search action. (#6743) - Minor: Add a separate highlight option for watchstreak notifications. (#6571, #6581) - Minor: Badges now link to their home page like emotes in the context menu. (#6437) - Minor: Fixed usercard resizing improperly without recent messages. (#6496) diff --git a/src/singletons/Settings.hpp b/src/singletons/Settings.hpp index 7ea15869..013506cb 100644 --- a/src/singletons/Settings.hpp +++ b/src/singletons/Settings.hpp @@ -310,6 +310,22 @@ public: BoolSetting autoCloseThreadPopup = {"/behaviour/autoCloseThreadPopup", false}; + /// Specifies whether the search functionality should be enabled + BoolSetting searchEnabled = { + "/behaviour/search/enabled", + false, + }; + /// The URL of the search engine + QStringSetting searchEngineUrl = { + "/behaviour/search/engineUrl", + "", + }; + /// The name of the search engine + QStringSetting searchEngineName = { + "/behaviour/search/engineName", + "", + }; + EnumSetting usernameRightClickBehavior = { "/behaviour/usernameRightClickBehavior", UsernameRightClickBehavior::Mention, diff --git a/src/widgets/helper/ChannelView.cpp b/src/widgets/helper/ChannelView.cpp index 961a3985..791cbd05 100644 --- a/src/widgets/helper/ChannelView.cpp +++ b/src/widgets/helper/ChannelView.cpp @@ -66,6 +66,7 @@ #include #include #include +#include #include #include @@ -2710,6 +2711,25 @@ void ChannelView::addMessageContextMenuItems(QMenu *menu, } } + // Add search action when text is selected and search feature is enabled + if (!this->selection_.isEmpty() && getSettings()->searchEnabled.getValue()) + { + QString searchURL = getSettings()->searchEngineUrl.getValue(); + QString searchName = getSettings()->searchEngineName.getValue(); + + if (!searchURL.isEmpty()) + { + QString actionText = + searchName.isEmpty() ? "&Search" : "&Search with " + searchName; + + menu->addAction(actionText, [this, searchURL] { + QString query = this->getSelectedText().trimmed(); + QString encodedQuery = QUrl::toPercentEncoding(query); + QDesktopServices::openUrl(QUrl(searchURL + encodedQuery)); + }); + } + } + auto *twitchChannel = dynamic_cast(this->underlyingChannel_.get()); if (!layout->getMessage()->id.isEmpty() && twitchChannel && diff --git a/src/widgets/settingspages/GeneralPage.cpp b/src/widgets/settingspages/GeneralPage.cpp index 79bd0c33..23da0900 100644 --- a/src/widgets/settingspages/GeneralPage.cpp +++ b/src/widgets/settingspages/GeneralPage.cpp @@ -31,6 +31,8 @@ #include #include #include +#include +#include namespace { @@ -1214,6 +1216,74 @@ void GeneralPage::initLayout(GeneralPageView &layout) "the top and a positive to the bottom.") ->addTo(layout); + { + layout.addSubtitle("Search"); + layout.addDescription( + "Search engine which appears when you select text and right-click " + "a message. Select a search engine preset from the dropdown below, " + "or fill in your custom search engine URL and name."); + SettingWidget::checkbox("Enable search in right-click context menu", + s.searchEnabled) + ->setTooltip( + "Allow searching selected text using a search engine from " + "the right-click context menu.") + ->addTo(layout); + + // Preset dropdown + QStringList presetList = {"DuckDuckGo", "Bing", "Google"}; + auto *presetCombo = + layout.addDropdown("Search engine preset", presetList, + "Select a search engine preset"); + presetCombo->setPlaceholderText("Select..."); + presetCombo->setCurrentIndex(-1); + // Make placeholder text more visible + QPalette palette = presetCombo->palette(); + palette.setColor(QPalette::PlaceholderText, + QColor(255, 255, 255)); // white + presetCombo->setPalette(palette); + s.searchEnabled.connect([presetCombo](bool value) { + presetCombo->setEnabled(value); + }); + + // Connect preset dropdown to update URL and name settings + QObject::connect( + presetCombo, QOverload::of(&QComboBox::currentIndexChanged), + [&s, presetCombo](int index) { + if (index < 0) + return; + + QString preset = presetCombo->itemText(index); + if (preset == "DuckDuckGo") + { + s.searchEngineUrl = "https://duckduckgo.com/?q="; + s.searchEngineName = "DuckDuckGo"; + } + else if (preset == "Bing") + { + s.searchEngineUrl = "https://www.bing.com/search?q="; + s.searchEngineName = "Bing"; + } + else if (preset == "Google") + { + s.searchEngineUrl = "https://www.google.com/search?q="; + s.searchEngineName = "Google"; + } + // Reset to -1 after selection + { + QSignalBlocker blocker(presetCombo); + presetCombo->setCurrentIndex(-1); + } + }); + + // URL and Name text inputs + SettingWidget::lineEdit("Search engine URL", s.searchEngineUrl) + ->conditionallyEnabledBy(s.searchEnabled) + ->addTo(layout); + + SettingWidget::lineEdit("Search engine name", s.searchEngineName) + ->conditionallyEnabledBy(s.searchEnabled) + ->addTo(layout); + } layout.addSubtitle("Miscellaneous"); if (supportsIncognitoLinks())