diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 31b5f4152..3762cb59b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -121,6 +121,7 @@ set(SOURCES globalsearch/globalsearch.cpp globalsearch/globalsearchitemdelegate.cpp globalsearch/globalsearchpopup.cpp + globalsearch/globalsearchsettingspage.cpp globalsearch/globalsearchsortmodel.cpp globalsearch/globalsearchtooltip.cpp globalsearch/globalsearchwidget.cpp @@ -371,6 +372,7 @@ set(HEADERS globalsearch/librarysearchprovider.h globalsearch/globalsearch.h globalsearch/globalsearchpopup.h + globalsearch/globalsearchsettingspage.h globalsearch/globalsearchtooltip.h globalsearch/globalsearchwidget.h globalsearch/groovesharksearchprovider.h @@ -545,6 +547,7 @@ set(UI devices/deviceproperties.ui globalsearch/globalsearchpopup.ui + globalsearch/globalsearchsettingspage.ui globalsearch/globalsearchwidget.ui internet/digitallyimportedsettingspage.ui diff --git a/src/globalsearch/globalsearchsettingspage.cpp b/src/globalsearch/globalsearchsettingspage.cpp new file mode 100644 index 000000000..1fa27e779 --- /dev/null +++ b/src/globalsearch/globalsearchsettingspage.cpp @@ -0,0 +1,168 @@ +/* This file is part of Clementine. + Copyright 2011, David Sansome + + Clementine is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Clementine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Clementine. If not, see . +*/ + +#include "globalsearch.h" +#include "globalsearchsettingspage.h" +#include "core/logging.h" +#include "ui/iconloader.h" +#include "ui/settingsdialog.h" +#include "ui_globalsearchsettingspage.h" + +#include + +GlobalSearchSettingsPage::GlobalSearchSettingsPage(SettingsDialog* dialog) + : SettingsPage(dialog), + ui_(new Ui::GlobalSearchSettingsPage) +{ + ui_->setupUi(this); + setWindowIcon(IconLoader::Load("edit-find")); + + ui_->sources->header()->setResizeMode(0, QHeaderView::Stretch); + ui_->sources->header()->setResizeMode(1, QHeaderView::ResizeToContents); + + warning_icon_ = IconLoader::Load("dialog-warning"); + + connect(ui_->up, SIGNAL(clicked()), SLOT(MoveUp())); + connect(ui_->down, SIGNAL(clicked()), SLOT(MoveDown())); + connect(ui_->configure, SIGNAL(clicked()), SLOT(ConfigureProvider())); + connect(ui_->sources, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), + SLOT(CurrentProviderChanged(QTreeWidgetItem*))); +} + +GlobalSearchSettingsPage::~GlobalSearchSettingsPage() { +} + +static bool CompareProviderId(SearchProvider* left, SearchProvider* right) { + return left->id() < right->id(); +} + +void GlobalSearchSettingsPage::Load() { + QSettings s; + s.beginGroup(GlobalSearch::kSettingsGroup); + + GlobalSearch* engine = dialog()->global_search(); + QList providers = engine->providers(); + + // Sort the list of providers alphabetically (by id) initially, so any that + // aren't in the provider_order list will take this order. + qSort(providers.begin(), providers.end(), CompareProviderId); + + // Add the ones in the configured list first + ui_->sources->clear(); + foreach (const QString& id, s.value("provider_order", QStringList() << "library").toStringList()) { + // Find a matching provider for this id + for (QList::iterator it = providers.begin(); + it != providers.end() ; ++it) { + if ((*it)->id() == id) { + AddProviderItem(engine, *it); + providers.erase(it); + break; + } + } + } + + // Now add any others that are remaining + foreach (SearchProvider* provider, providers) { + AddProviderItem(engine, provider); + } + + ui_->show_globalsearch->setChecked(s.value("show_globalsearch", true).toBool()); + ui_->hide_others->setChecked(s.value("hide_others", false).toBool()); + ui_->combine->setChecked(s.value("combine_identical_results", true).toBool()); + ui_->tooltip->setChecked(s.value("tooltip", true).toBool()); + ui_->tooltip_help->setChecked(s.value("tooltip_help", true).toBool()); +} + +void GlobalSearchSettingsPage::AddProviderItem(GlobalSearch* engine, + SearchProvider* provider) { + QTreeWidgetItem* item = new QTreeWidgetItem; + item->setText(0, provider->name()); + item->setIcon(0, provider->icon()); + + const bool enabled = engine->is_provider_enabled(provider); + const bool logged_in = provider->IsLoggedIn(); + + if (!logged_in) { + item->setData(0, Qt::CheckStateRole, Qt::Unchecked); + item->setIcon(1, warning_icon_); + item->setText(1, tr("Not logged in")); + item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); + } else if (enabled) { + item->setData(0, Qt::CheckStateRole, Qt::Checked); + item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable); + } else { + item->setData(0, Qt::CheckStateRole, Qt::Unchecked); + item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable); + } + + item->setData(0, Qt::UserRole, QVariant::fromValue(provider)); + + ui_->sources->invisibleRootItem()->addChild(item); +} + +void GlobalSearchSettingsPage::Save() { + +} + +void GlobalSearchSettingsPage::MoveUp() { + MoveCurrentItem(-1); +} + +void GlobalSearchSettingsPage::MoveDown() { + MoveCurrentItem(+1); +} + +void GlobalSearchSettingsPage::MoveCurrentItem(int d) { + QTreeWidgetItem* item = ui_->sources->currentItem(); + if (!item) + return; + + QTreeWidgetItem* root = ui_->sources->invisibleRootItem(); + + const int row = root->indexOfChild(item); + const int new_row = qBound(0, row + d, root->childCount()); + + if (row == new_row) + return; + + root->removeChild(item); + root->insertChild(new_row, item); + + ui_->sources->setCurrentItem(item); +} + +void GlobalSearchSettingsPage::ConfigureProvider() { + QTreeWidgetItem* item = ui_->sources->currentItem(); + if (!item) + return; + + SearchProvider* provider = item->data(0, Qt::UserRole).value(); + provider->ShowConfig(); +} + +void GlobalSearchSettingsPage::CurrentProviderChanged(QTreeWidgetItem* item) { + if (!item) + return; + + QTreeWidgetItem* root = ui_->sources->invisibleRootItem(); + SearchProvider* provider = item->data(0, Qt::UserRole).value(); + const int row = root->indexOfChild(item); + + ui_->up->setEnabled(row != 0); + ui_->down->setEnabled(row != root->childCount() - 1); + ui_->configure->setEnabled(provider->CanShowConfig()); +} diff --git a/src/globalsearch/globalsearchsettingspage.h b/src/globalsearch/globalsearchsettingspage.h new file mode 100644 index 000000000..48e69afd1 --- /dev/null +++ b/src/globalsearch/globalsearchsettingspage.h @@ -0,0 +1,59 @@ +/* This file is part of Clementine. + Copyright 2011, David Sansome + + Clementine is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Clementine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Clementine. If not, see . +*/ + +#ifndef GLOBALSEARCHSETTINGSPAGE_H +#define GLOBALSEARCHSETTINGSPAGE_H + +#include "ui/settingspage.h" + +#include +#include + +class GlobalSearch; +class SearchProvider; +class Ui_GlobalSearchSettingsPage; + +class QTreeWidgetItem; + +class GlobalSearchSettingsPage : public SettingsPage { + Q_OBJECT + +public: + GlobalSearchSettingsPage(SettingsDialog* dialog); + ~GlobalSearchSettingsPage(); + + void Load(); + void Save(); + +private slots: + void MoveUp(); + void MoveDown(); + void ConfigureProvider(); + + void CurrentProviderChanged(QTreeWidgetItem* item); + +private: + void AddProviderItem(GlobalSearch* engine, SearchProvider* provider); + void MoveCurrentItem(int d); + +private: + QScopedPointer ui_; + + QIcon warning_icon_; +}; + +#endif // GLOBALSEARCHSETTINGSPAGE_H diff --git a/src/globalsearch/globalsearchsettingspage.ui b/src/globalsearch/globalsearchsettingspage.ui new file mode 100644 index 000000000..803fdf5c1 --- /dev/null +++ b/src/globalsearch/globalsearchsettingspage.ui @@ -0,0 +1,220 @@ + + + GlobalSearchSettingsPage + + + + 0 + 0 + 654 + 506 + + + + Global Search + + + + + + Show the Global Search box above the sidebar + + + + + + + Hide all other search boxes + + + + + + + Sources + + + + + + Combine identical results from different sources + + + + + + + Enable sources below to include them in Global Search results. When identical results are available from more than one source, ones at the top will take priority. + + + true + + + + + + + + + Qt::ScrollBarAlwaysOff + + + false + + + 2 + + + false + + + false + + + + 1 + + + + + 2 + + + + + + + + + + Move up + + + + + + + Move down + + + + + + + Configure... + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + Results + + + + + + Show a tooltip with more information about each result + + + + + + + Include keyboard shortcut help in the tooltip + + + + + + + + + + + + show_globalsearch + toggled(bool) + hide_others + setEnabled(bool) + + + 86 + 23 + + + 88 + 53 + + + + + show_globalsearch + toggled(bool) + sources_group + setEnabled(bool) + + + 171 + 25 + + + 165 + 77 + + + + + show_globalsearch + toggled(bool) + results_group + setEnabled(bool) + + + 201 + 18 + + + 240 + 416 + + + + + tooltip + toggled(bool) + tooltip_help + setEnabled(bool) + + + 121 + 447 + + + 123 + 469 + + + + + diff --git a/src/globalsearch/groovesharksearchprovider.h b/src/globalsearch/groovesharksearchprovider.h index b0a12df4b..3c936469f 100644 --- a/src/globalsearch/groovesharksearchprovider.h +++ b/src/globalsearch/groovesharksearchprovider.h @@ -36,6 +36,7 @@ class GroovesharkSearchProvider : public SearchProvider { void LoadArtAsync(int id, const Result& result); void LoadTracksAsync(int id, const Result& result); bool IsLoggedIn(); + bool CanShowConfig() const { return true; } void ShowConfig(); private slots: diff --git a/src/globalsearch/searchprovider.h b/src/globalsearch/searchprovider.h index a7ad94a6f..150c8ad42 100644 --- a/src/globalsearch/searchprovider.h +++ b/src/globalsearch/searchprovider.h @@ -103,6 +103,7 @@ public: // If provider needs user login to search and play songs, this method should // be reimplemented virtual bool IsLoggedIn() { return true; } + virtual bool CanShowConfig() const { return false; } virtual void ShowConfig() { } static QImage ScaleAndPad(const QImage& image); @@ -154,4 +155,6 @@ private slots: void BlockingSearchFinished(); }; +Q_DECLARE_METATYPE(SearchProvider*) + #endif // SEARCHPROVIDER_H diff --git a/src/globalsearch/spotifysearchprovider.h b/src/globalsearch/spotifysearchprovider.h index b6850edda..ec049796f 100644 --- a/src/globalsearch/spotifysearchprovider.h +++ b/src/globalsearch/spotifysearchprovider.h @@ -36,6 +36,7 @@ public: void LoadTracksAsync(int id, const Result& result); bool IsLoggedIn(); + bool CanShowConfig() const { return true; } void ShowConfig(); private slots: diff --git a/src/translations/translations.pot b/src/translations/translations.pot index 2d1bbdea4..799107755 100644 --- a/src/translations/translations.pot +++ b/src/translations/translations.pot @@ -684,6 +684,9 @@ msgstr "" msgid "Color" msgstr "" +msgid "Combine identical results from different sources" +msgstr "" + msgid "Comma separated list of class:level, level is 0-3" msgstr "" @@ -1091,6 +1094,12 @@ msgstr "" msgid "Enable shortcuts only when Clementine is focused" msgstr "" +msgid "" +"Enable sources below to include them in Global Search results. When " +"identical results are available from more than one source, ones at the top " +"will take priority." +msgstr "" + msgid "Enable/disable Last.fm scrobbling" msgstr "" @@ -1333,6 +1342,9 @@ msgstr "" msgid "Give it a name:" msgstr "" +msgid "Global Search" +msgstr "" + msgid "Global search" msgstr "" @@ -1394,6 +1406,9 @@ msgstr "" msgid "Hardware information is only available while the device is connected." msgstr "" +msgid "Hide all other search boxes" +msgstr "" + msgid "High" msgstr "" @@ -1458,6 +1473,9 @@ msgstr "" msgid "Include all songs" msgstr "" +msgid "Include keyboard shortcut help in the tooltip" +msgstr "" + msgid "Increase the volume by 4%" msgstr "" @@ -1942,6 +1960,9 @@ msgstr "" msgid "Not installed" msgstr "" +msgid "Not logged in" +msgstr "" + msgid "Not mounted - double click to mount" msgstr "" @@ -2340,6 +2361,9 @@ msgstr "" msgid "Restrict to ASCII characters" msgstr "" +msgid "Results" +msgstr "" + msgid "Rock" msgstr "" @@ -2517,6 +2541,9 @@ msgstr "" msgid "Show a pretty OSD" msgstr "" +msgid "Show a tooltip with more information about each result" +msgstr "" + msgid "Show above status bar" msgstr "" @@ -2554,6 +2581,9 @@ msgstr "" msgid "Show the \"love\" and \"ban\" buttons" msgstr "" +msgid "Show the Global Search box above the sidebar" +msgstr "" + msgid "Show the scrobble button in the main window" msgstr "" @@ -2644,6 +2674,9 @@ msgstr "" msgid "Sorting" msgstr "" +msgid "Sources" +msgstr "" + msgid "Speex" msgstr "" diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index 69c766d2f..f03cb0110 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -1940,10 +1940,9 @@ void MainWindow::EnsureSettingsDialogCreated() { settings_dialog_.reset(new SettingsDialog(background_streams_)); settings_dialog_->SetLibraryDirectoryModel(library_->model()->directory_model()); - settings_dialog_->SetGstEngine(qobject_cast(player_->engine())); - settings_dialog_->SetGlobalShortcutManager(global_shortcuts_); + settings_dialog_->SetGlobalSearch(global_search_); settings_dialog_->SetSongInfoView(song_info_view_); // Settings diff --git a/src/ui/settingsdialog.cpp b/src/ui/settingsdialog.cpp index 72cc7c5f8..a2efe6101 100644 --- a/src/ui/settingsdialog.cpp +++ b/src/ui/settingsdialog.cpp @@ -30,6 +30,7 @@ #include "core/networkproxyfactory.h" #include "engines/enginebase.h" #include "engines/gstengine.h" +#include "globalsearch/globalsearchsettingspage.h" #include "internet/digitallyimportedsettingspage.h" #include "internet/groovesharksettingspage.h" #include "internet/magnatunesettingspage.h" @@ -100,6 +101,7 @@ SettingsDialog::SettingsDialog(BackgroundStreams* streams, QWidget* parent) gst_engine_(NULL), song_info_view_(NULL), streams_(streams), + global_search_(NULL), ui_(new Ui_SettingsDialog), loading_settings_(false) { @@ -125,6 +127,7 @@ SettingsDialog::SettingsDialog(BackgroundStreams* streams, QWidget* parent) // User interface QTreeWidgetItem* interface = AddCategory(tr("User interface")); AddPage(Page_GlobalShortcuts, new GlobalShortcutsSettingsPage(this), interface); + AddPage(Page_GlobalSearch, new GlobalSearchSettingsPage(this), interface); AddPage(Page_SongInformation, new SongInfoSettingsPage(this), interface); AddPage(Page_Notifications, new NotificationsSettingsPage(this), interface); diff --git a/src/ui/settingsdialog.h b/src/ui/settingsdialog.h index d09039c14..d11a96e57 100644 --- a/src/ui/settingsdialog.h +++ b/src/ui/settingsdialog.h @@ -28,6 +28,7 @@ class QScrollArea; class QTreeWidgetItem; class BackgroundStreams; +class GlobalSearch; class GlobalShortcuts; class LibraryDirectoryModel; class SettingsPage; @@ -59,6 +60,7 @@ public: Page_Behaviour, Page_SongInformation, Page_GlobalShortcuts, + Page_GlobalSearch, Page_Notifications, Page_Library, Page_Lastfm, @@ -81,6 +83,7 @@ public: void SetGlobalShortcutManager(GlobalShortcuts* manager) { manager_ = manager; } void SetGstEngine(const GstEngine* engine) { gst_engine_ = engine; } void SetSongInfoView(SongInfoView* view) { song_info_view_ = view; } + void SetGlobalSearch(GlobalSearch* global_search) { global_search_ = global_search; } bool is_loading_settings() const { return loading_settings_; } @@ -89,6 +92,7 @@ public: const GstEngine* gst_engine() const { return gst_engine_; } SongInfoView* song_info_view() const { return song_info_view_; } BackgroundStreams* background_streams() const { return streams_; } + GlobalSearch* global_search() const { return global_search_; } void OpenAtPage(Page page); @@ -121,6 +125,7 @@ private: const GstEngine* gst_engine_; SongInfoView* song_info_view_; BackgroundStreams* streams_; + GlobalSearch* global_search_; Ui_SettingsDialog* ui_; bool loading_settings_;