diff --git a/src/library/libraryfilterwidget.cpp b/src/library/libraryfilterwidget.cpp index b80449ad7..302e57be7 100644 --- a/src/library/libraryfilterwidget.cpp +++ b/src/library/libraryfilterwidget.cpp @@ -23,20 +23,26 @@ #include "ui/settingsdialog.h" #include "widgets/maclineedit.h" +#include #include #include -#include -#include #include +#include +#include LibraryFilterWidget::LibraryFilterWidget(QWidget *parent) : QWidget(parent), ui_(new Ui_LibraryFilterWidget), model_(NULL), - group_by_dialog_(new GroupByDialog) + group_by_dialog_(new GroupByDialog), + filter_delay_(new QTimer(this)) { ui_->setupUi(this); connect(ui_->filter, SIGNAL(returnPressed()), SIGNAL(ReturnPressed())); + connect(filter_delay_, SIGNAL(timeout()), SLOT(FilterDelayTimeout())); + + filter_delay_->setInterval(kFilterDelay); + filter_delay_->setSingleShot(true); // Icons ui_->clear->setIcon(IconLoader::Load("edit-clear-locationbar-ltr")); @@ -114,6 +120,8 @@ LibraryFilterWidget::LibraryFilterWidget(QWidget *parent) #else filter_ = ui_->filter; #endif + + connect(filter_->object(), SIGNAL(textChanged(QString)), SLOT(FilterTextChanged(QString))); } LibraryFilterWidget::~LibraryFilterWidget() { @@ -125,7 +133,6 @@ void LibraryFilterWidget::SetLibraryModel(LibraryModel *model) { disconnect(model_, 0, this, 0); disconnect(model_, 0, group_by_dialog_.get(), 0); disconnect(group_by_dialog_.get(), 0, model_, 0); - disconnect(filter_->object(), 0, model_, 0); disconnect(filter_age_mapper_, 0, model_, 0); } @@ -138,7 +145,6 @@ void LibraryFilterWidget::SetLibraryModel(LibraryModel *model) { SLOT(GroupingChanged(LibraryModel::Grouping))); connect(group_by_dialog_.get(), SIGNAL(Accepted(LibraryModel::Grouping)), model_, SLOT(SetGroupBy(LibraryModel::Grouping))); - connect(filter_->object(), SIGNAL(textChanged(QString)), model_, SLOT(SetFilterText(QString))); connect(filter_age_mapper_, SIGNAL(mapped(int)), model_, SLOT(SetFilterAge(int))); // Load settings @@ -226,3 +232,20 @@ void LibraryFilterWidget::keyReleaseEvent(QKeyEvent* e) { QWidget::keyReleaseEvent(e); } + +void LibraryFilterWidget::FilterTextChanged(const QString& text) { + // Searching with one or two characters can be very expensive on the database + // even with FTS, so if there are a large number of songs in the database + // introduce a small delay before actually filtering the model, so if the + // user is typing the first few characters of something it will be quicker. + if (!text.isEmpty() && text.length() < 3 && model_->total_song_count() >= 100000) { + filter_delay_->start(); + } else { + filter_delay_->stop(); + model_->SetFilterText(text); + } +} + +void LibraryFilterWidget::FilterDelayTimeout() { + model_->SetFilterText(filter_->text()); +} diff --git a/src/library/libraryfilterwidget.h b/src/library/libraryfilterwidget.h index 5969b1996..ec9b9544d 100644 --- a/src/library/libraryfilterwidget.h +++ b/src/library/libraryfilterwidget.h @@ -40,6 +40,8 @@ class LibraryFilterWidget : public QWidget { LibraryFilterWidget(QWidget* parent = 0); ~LibraryFilterWidget(); + static const int kFilterDelay = 500; // msec + void SetFilterHint(const QString& hint); void SetAgeFilterEnabled(bool enabled); void SetGroupByEnabled(bool enabled); @@ -64,6 +66,9 @@ class LibraryFilterWidget : public QWidget { void GroupByClicked(QAction* action); void ClearFilter(); + void FilterTextChanged(const QString& text); + void FilterDelayTimeout(); + private: Ui_LibraryFilterWidget* ui_; LibraryModel* model_; @@ -77,6 +82,8 @@ class LibraryFilterWidget : public QWidget { QActionGroup* group_by_group_; QSignalMapper* filter_age_mapper_; + QTimer* filter_delay_; + QString settings_group_; LineEditInterface* filter_; diff --git a/src/library/librarymodel.cpp b/src/library/librarymodel.cpp index 9555e7837..517e5f2c8 100644 --- a/src/library/librarymodel.cpp +++ b/src/library/librarymodel.cpp @@ -55,6 +55,7 @@ LibraryModel::LibraryModel(LibraryBackend* backend, QObject* parent) dir_model_(new LibraryDirectoryModel(backend, this)), show_smart_playlists_(false), show_various_artists_(true), + total_song_count_(0), artist_icon_(":/icons/22x22/x-clementine-artist.png"), album_icon_(":/icons/22x22/x-clementine-album.png"), no_cover_icon_(":nocover.png"), @@ -77,7 +78,7 @@ void LibraryModel::Init() { connect(backend_, SIGNAL(SongsDeleted(SongList)), SLOT(SongsDeleted(SongList))); connect(backend_, SIGNAL(SongsStatisticsChanged(SongList)), SLOT(SongsStatisticsChanged(SongList))); connect(backend_, SIGNAL(DatabaseReset()), SLOT(Reset())); - connect(backend_, SIGNAL(TotalSongCountUpdated(int)), SIGNAL(TotalSongCountUpdated(int))); + connect(backend_, SIGNAL(TotalSongCountUpdated(int)), SLOT(TotalSongCountUpdatedSlot(int))); backend_->UpdateTotalSongCountAsync(); @@ -1107,3 +1108,8 @@ GeneratorPtr LibraryModel::CreateGenerator(const QModelIndex& index) const { ret->Load(item->smart_playlist_data); return ret; } + +void LibraryModel::TotalSongCountUpdatedSlot(int count) { + total_song_count_ = count; + emit TotalSongCountUpdated(count); +} diff --git a/src/library/librarymodel.h b/src/library/librarymodel.h index c65e8da8e..0d26a37eb 100644 --- a/src/library/librarymodel.h +++ b/src/library/librarymodel.h @@ -112,6 +112,9 @@ class LibraryModel : public SimpleTreeModel { SongList GetChildSongs(const QModelIndex& index) const; SongList GetChildSongs(const QModelIndexList& indexes) const; + // Might be accurate + int total_song_count() const { return total_song_count_; } + // Smart playlists smart_playlists::GeneratorPtr CreateGenerator(const QModelIndex& index) const; void AddGenerator(smart_playlists::GeneratorPtr gen); @@ -146,6 +149,7 @@ class LibraryModel : public SimpleTreeModel { void SongsDiscovered(const SongList& songs); void SongsDeleted(const SongList& songs); void SongsStatisticsChanged(const SongList& songs); + void TotalSongCountUpdatedSlot(int count); // Called after ResetAsync void ResetAsyncQueryFinished(); @@ -215,6 +219,8 @@ class LibraryModel : public SimpleTreeModel { DefaultGenerators default_smart_playlists_; bool show_various_artists_; + int total_song_count_; + QueryOptions query_options_; Grouping group_by_;