/* This file is part of Clementine. Copyright 2010, 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 "searchpreview.h" #include "ui_searchpreview.h" #include #include #include #include "querygenerator.h" #include "playlist/playlist.h" namespace smart_playlists { typedef QFuture Future; typedef QFutureWatcher FutureWatcher; SearchPreview::SearchPreview(QWidget* parent) : QWidget(parent), ui_(new Ui_SmartPlaylistSearchPreview), 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(); } SearchPreview::~SearchPreview() { delete ui_; } void SearchPreview::set_application(Application* app) { ui_->tree->SetApplication(app); } void SearchPreview::set_library(LibraryBackend* backend) { backend_ = backend; model_ = new Playlist(nullptr, nullptr, backend_, -1, QString(), false, this); ui_->tree->setModel(model_); ui_->tree->SetPlaylist(model_); ui_->tree->SetItemDelegates(backend_); } void SearchPreview::Update(const Search& 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 SearchPreview::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_ = Search(); } QWidget::showEvent(e); } PlaylistItemList DoRunSearch(GeneratorPtr gen) { return gen->Generate(); } void SearchPreview::RunSearch(const Search& search) { generator_.reset(new QueryGenerator); generator_->set_library(backend_); std::dynamic_pointer_cast(generator_)->Load(search); ui_->busy_container->show(); ui_->count_label->hide(); Future future = QtConcurrent::run(DoRunSearch, generator_); FutureWatcher* watcher = new FutureWatcher(this); watcher->setFuture(future); connect(watcher, SIGNAL(finished()), SLOT(SearchFinished())); } void SearchPreview::SearchFinished() { FutureWatcher* watcher = static_cast(sender()); 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_ = Search(); return; } PlaylistItemList all_items = watcher->result(); PlaylistItemList displayed_items = all_items.mid(0, Generator::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(); } } // namespace