Make searching more responsive on large libraries (Jamendo)

This commit is contained in:
David Sansome 2010-11-27 20:20:26 +00:00
parent af234763f2
commit dd937fb06d
4 changed files with 48 additions and 6 deletions

View File

@ -23,20 +23,26 @@
#include "ui/settingsdialog.h"
#include "widgets/maclineedit.h"
#include <QActionGroup>
#include <QKeyEvent>
#include <QMenu>
#include <QActionGroup>
#include <QSignalMapper>
#include <QSettings>
#include <QSignalMapper>
#include <QTimer>
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());
}

View File

@ -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_;

View File

@ -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);
}

View File

@ -112,6 +112,9 @@ class LibraryModel : public SimpleTreeModel<LibraryItem> {
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<LibraryItem> {
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<LibraryItem> {
DefaultGenerators default_smart_playlists_;
bool show_various_artists_;
int total_song_count_;
QueryOptions query_options_;
Grouping group_by_;