/* * Strawberry Music Player * This file was part of Clementine. * Copyright 2010, David Sansome * * Strawberry 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. * * Strawberry 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 Strawberry. If not, see . * */ #include "config.h" #include #include #include #include #include #include #include #include "smartplaylistsearchpreview.h" #include "ui_smartplaylistsearchpreview.h" #include "playlist/playlist.h" #include "playlistquerygenerator.h" SmartPlaylistSearchPreview::SmartPlaylistSearchPreview(QWidget *parent) : QWidget(parent), ui_(new Ui_SmartPlaylistSearchPreview), backend_(nullptr), model_(nullptr) { ui_->setupUi(this); // Prevent editing songs and saving settings (like header columns and geometry) ui_->tree->setEditTriggers(QAbstractItemView::NoEditTriggers); ui_->tree->SetReadOnlySettings(true); QFont bold_font; bold_font.setBold(true); ui_->preview_label->setFont(bold_font); ui_->busy_container->hide(); } SmartPlaylistSearchPreview::~SmartPlaylistSearchPreview() { delete ui_; } void SmartPlaylistSearchPreview::set_application(Application *app) { ui_->tree->Init(app); } void SmartPlaylistSearchPreview::set_collection(CollectionBackend *backend) { backend_ = backend; model_ = new Playlist(nullptr, nullptr, backend_, -1, QString(), false, this); ui_->tree->setModel(model_); ui_->tree->SetPlaylist(model_); ui_->tree->SetItemDelegates(); } void SmartPlaylistSearchPreview::Update(const SmartPlaylistSearch &search) { if (search == last_search_) { // This search was the same as the last one we did return; } if (generator_ || isHidden()) { // It's busy generating something already, or the widget isn't visible pending_search_ = search; return; } RunSearch(search); } void SmartPlaylistSearchPreview::showEvent(QShowEvent *e) { if (pending_search_.is_valid() && !generator_) { // There was a search waiting while we were hidden, so run it now RunSearch(pending_search_); pending_search_ = SmartPlaylistSearch(); } QWidget::showEvent(e); } namespace { PlaylistItemList DoRunSearch(PlaylistGeneratorPtr gen) { return gen->Generate(); } } // namespace void SmartPlaylistSearchPreview::RunSearch(const SmartPlaylistSearch &search) { generator_.reset(new PlaylistQueryGenerator); generator_->set_collection(backend_); std::dynamic_pointer_cast(generator_)->Load(search); ui_->busy_container->show(); ui_->count_label->hide(); QFuture future = QtConcurrent::run(DoRunSearch, generator_); QFutureWatcher *watcher = new QFutureWatcher(); QObject::connect(watcher, &QFutureWatcher::finished, this, &SmartPlaylistSearchPreview::SearchFinished); watcher->setFuture(future); } void SmartPlaylistSearchPreview::SearchFinished() { QFutureWatcher *watcher = static_cast*>(sender()); PlaylistItemList all_items = watcher->result(); watcher->deleteLater(); last_search_ = std::dynamic_pointer_cast(generator_)->search(); generator_.reset(); if (pending_search_.is_valid() && pending_search_ != last_search_) { // There was another search done while we were running // throw away these results and do that one now instead RunSearch(pending_search_); pending_search_ = SmartPlaylistSearch(); return; } PlaylistItemList displayed_items = all_items.mid(0, PlaylistGenerator::kDefaultLimit); model_->Clear(); model_->InsertItems(displayed_items); if (displayed_items.count() < all_items.count()) { ui_->count_label->setText(tr("%1 songs found (showing %2)").arg(all_items.count()).arg(displayed_items.count())); } else { ui_->count_label->setText(tr("%1 songs found").arg(all_items.count())); } ui_->busy_container->hide(); ui_->count_label->show(); }