Remove most usages of QFutureWatcher

This commit is contained in:
John Maguire 2015-11-27 14:22:59 +00:00
parent 2d61fe6c87
commit f300946c81
29 changed files with 184 additions and 271 deletions

View File

@ -200,6 +200,15 @@ _detail::ClosureBase* NewClosure(QFuture<T> future, QObject* receiver,
return NewClosure(watcher, SIGNAL(finished()), receiver, slot, args...);
}
template <typename T, typename F, typename... Args>
_detail::ClosureBase* NewClosure(QFuture<T> future, const F& callback,
const Args&... args) {
QFutureWatcher<T>* watcher = new QFutureWatcher<T>;
watcher->setFuture(future);
QObject::connect(watcher, SIGNAL(finished()), watcher, SLOT(deleteLater()));
return NewClosure(watcher, SIGNAL(finished()), callback, args...);
}
void DoAfter(QObject* receiver, const char* slot, int msec);
void DoAfter(std::function<void()> callback, std::chrono::milliseconds msec);
void DoInAMinuteOrSo(QObject* receiver, const char* slot);

View File

@ -29,7 +29,6 @@
#ifndef CORE_SONG_H_
#define CORE_SONG_H_
#include <QFuture>
#include <QImage>
#include <QMetaType>
#include <QSharedDataPointer>

View File

@ -20,7 +20,6 @@
#include <functional>
#include <memory>
#include <QFutureWatcher>
#include <QScrollBar>
#include <QtConcurrentRun>
@ -86,9 +85,8 @@ void DeviceProperties::ShowDevice(int row) {
<< "phone-palm-pre";
for (const QString& icon_name : icon_names) {
QListWidgetItem* item = new QListWidgetItem(IconLoader::Load(icon_name,
IconLoader::Base),
QString(), ui_->icon);
QListWidgetItem* item = new QListWidgetItem(
IconLoader::Load(icon_name, IconLoader::Base), QString(), ui_->icon);
item->setData(Qt::UserRole, icon_name);
}
@ -226,10 +224,8 @@ void DeviceProperties::UpdateFormats() {
QFuture<bool> future = QtConcurrent::run(std::bind(
&ConnectedDevice::GetSupportedFiletypes, device, &supported_formats_));
QFutureWatcher<bool>* watcher = new QFutureWatcher<bool>(this);
watcher->setFuture(future);
connect(watcher, SIGNAL(finished()), SLOT(UpdateFormatsFinished()));
NewClosure(future, this, SLOT(UpdateFormatsFinished(QFuture<bool>)),
future);
ui_->formats_stack->setCurrentWidget(ui_->formats_page_loading);
updating_formats_ = true;
@ -265,12 +261,10 @@ void DeviceProperties::accept() {
void DeviceProperties::OpenDevice() { manager_->Connect(index_.row()); }
void DeviceProperties::UpdateFormatsFinished() {
QFutureWatcher<bool>* watcher = static_cast<QFutureWatcher<bool>*>(sender());
watcher->deleteLater();
void DeviceProperties::UpdateFormatsFinished(QFuture<bool> future) {
updating_formats_ = false;
if (!watcher->future().result()) {
if (!future.result()) {
supported_formats_.clear();
}

View File

@ -19,6 +19,7 @@
#define DEVICEPROPERTIES_H
#include <QDialog>
#include <QFuture>
#include <QPersistentModelIndex>
#include "core/song.h"
@ -47,7 +48,7 @@ class DeviceProperties : public QDialog {
private slots:
void ModelChanged();
void OpenDevice();
void UpdateFormatsFinished();
void UpdateFormatsFinished(QFuture<bool> future);
private:
Ui_DeviceProperties* ui_;

View File

@ -18,6 +18,7 @@
#ifndef SEARCHPROVIDER_H
#define SEARCHPROVIDER_H
#include <QFuture>
#include <QIcon>
#include <QMetaType>
#include <QObject>

View File

@ -24,7 +24,6 @@
#include <algorithm>
#include <QDesktopServices>
#include <QFutureWatcher>
#include <QMenu>
#include <QMultiHash>
#include <QNetworkReply>
@ -75,8 +74,8 @@ IcecastService::IcecastService(Application* app, InternetModel* parent)
IcecastService::~IcecastService() {}
QStandardItem* IcecastService::CreateRootItem() {
root_ = new QStandardItem(IconLoader::Load("icon_radio",
IconLoader::Lastfm), kServiceName);
root_ = new QStandardItem(IconLoader::Load("icon_radio", IconLoader::Lastfm),
kServiceName);
root_->setData(true, InternetModel::Role_CanLazyLoad);
return root_;
}
@ -128,13 +127,9 @@ void IcecastService::DownloadDirectoryFinished(QNetworkReply* reply,
QFuture<IcecastBackend::StationList> future =
QtConcurrent::run(this, &IcecastService::ParseDirectory, reply);
QFutureWatcher<void>* watcher = new QFutureWatcher<void>(this);
watcher->setFuture(future);
NewClosure(
watcher, SIGNAL(finished()), this,
SLOT(ParseDirectoryFinished(QFuture<IcecastBackend::StationList>, int)),
future, task_id);
connect(watcher, SIGNAL(finished()), watcher, SLOT(deleteLater()));
NewClosure(future, this, SLOT(ParseDirectoryFinished(
QFuture<IcecastBackend::StationList>, int)),
future, task_id);
}
namespace {

View File

@ -24,7 +24,6 @@
#include "jamendoservice.h"
#include <QDesktopServices>
#include <QFutureWatcher>
#include <QMenu>
#include <QMessageBox>
#include <QNetworkReply>
@ -146,9 +145,8 @@ JamendoService::JamendoService(Application* app, InternetModel* parent)
JamendoService::~JamendoService() {}
QStandardItem* JamendoService::CreateRootItem() {
QStandardItem* item =
new QStandardItem(IconLoader::Load("jamendo", IconLoader::Provider),
kServiceName);
QStandardItem* item = new QStandardItem(
IconLoader::Load("jamendo", IconLoader::Provider), kServiceName);
item->setData(true, InternetModel::Role_CanLazyLoad);
return item;
}
@ -205,8 +203,7 @@ void JamendoService::DownloadDirectory() {
void JamendoService::DownloadDirectoryProgress(qint64 received, qint64 total) {
float progress = static_cast<float>(received) / total;
app_->task_manager()->SetTaskProgress(load_database_task_id_,
static_cast<int>(progress * 100),
100);
static_cast<int>(progress * 100), 100);
}
void JamendoService::DownloadDirectoryFinished() {
@ -230,9 +227,7 @@ void JamendoService::DownloadDirectoryFinished() {
QFuture<void> future =
QtConcurrent::run(this, &JamendoService::ParseDirectory, gzip);
QFutureWatcher<void>* watcher = new QFutureWatcher<void>();
watcher->setFuture(future);
connect(watcher, SIGNAL(finished()), SLOT(ParseDirectoryFinished()));
NewClosure(future, this, SLOT(ParseDirectoryFinished()));
}
void JamendoService::ParseDirectory(QIODevice* device) const {
@ -408,9 +403,6 @@ Song JamendoService::ReadTrack(const QString& artist, const QString& album,
}
void JamendoService::ParseDirectoryFinished() {
QFutureWatcher<void>* watcher = static_cast<QFutureWatcher<void>*>(sender());
delete watcher;
// show smart playlists
library_model_->set_show_smart_playlists(true);
library_model_->Reset();
@ -424,14 +416,12 @@ void JamendoService::EnsureMenuCreated() {
context_menu_ = new QMenu;
context_menu_->addActions(GetPlaylistActions());
album_info_ = context_menu_->addAction(IconLoader::Load("view-media-lyrics",
IconLoader::Base),
tr("Album info on jamendo.com..."),
this, SLOT(AlbumInfo()));
download_album_ = context_menu_->addAction(IconLoader::Load("download",
IconLoader::Base),
tr("Download this album..."), this,
SLOT(DownloadAlbum()));
album_info_ = context_menu_->addAction(
IconLoader::Load("view-media-lyrics", IconLoader::Base),
tr("Album info on jamendo.com..."), this, SLOT(AlbumInfo()));
download_album_ = context_menu_->addAction(
IconLoader::Load("download", IconLoader::Base),
tr("Download this album..."), this, SLOT(DownloadAlbum()));
context_menu_->addSeparator();
context_menu_->addAction(IconLoader::Load("download", IconLoader::Base),
tr("Open %1 in browser").arg("jamendo.com"), this,

View File

@ -20,7 +20,6 @@
#include <functional>
#include <QFuture>
#include <QFutureWatcher>
#include <QIODevice>
#include <QMetaEnum>
#include <QNetworkCacheMetaData>
@ -63,8 +62,6 @@ const char* LibraryModel::kSmartPlaylistsSettingsGroup =
const int LibraryModel::kSmartPlaylistsVersion = 4;
const int LibraryModel::kPrettyCoverSize = 32;
const qint64 LibraryModel::kIconCacheSize = 100000000; //~100MB
typedef QFuture<LibraryModel::QueryResult> RootQueryFuture;
typedef QFutureWatcher<LibraryModel::QueryResult> RootQueryWatcher;
static bool IsArtistGroupBy(const LibraryModel::GroupBy by) {
return by == LibraryModel::GroupBy_Artist ||
@ -228,7 +225,8 @@ void LibraryModel::SongsDiscovered(const SongList& songs) {
key = PrettyYearAlbum(qMax(0, song.year()), song.album());
break;
case GroupBy_OriginalYearAlbum:
key = PrettyYearAlbum(qMax(0, song.effective_originalyear()), song.album());
key = PrettyYearAlbum(qMax(0, song.effective_originalyear()),
song.album());
break;
case GroupBy_FileType:
key = song.filetype();
@ -732,18 +730,16 @@ void LibraryModel::LazyPopulate(LibraryItem* parent, bool signal) {
}
void LibraryModel::ResetAsync() {
RootQueryFuture future =
QFuture<LibraryModel::QueryResult> future =
QtConcurrent::run(this, &LibraryModel::RunQuery, root_);
RootQueryWatcher* watcher = new RootQueryWatcher(this);
watcher->setFuture(future);
connect(watcher, SIGNAL(finished()), SLOT(ResetAsyncQueryFinished()));
NewClosure(future, this,
SLOT(ResetAsyncQueryFinished(QFuture<LibraryModel::QueryResult>)),
future);
}
void LibraryModel::ResetAsyncQueryFinished() {
RootQueryWatcher* watcher = static_cast<RootQueryWatcher*>(sender());
const struct QueryResult result = watcher->result();
watcher->deleteLater();
void LibraryModel::ResetAsyncQueryFinished(
QFuture<LibraryModel::QueryResult> future) {
const struct QueryResult result = future.result();
BeginReset();
root_->lazy_loaded = true;
@ -960,9 +956,10 @@ LibraryItem* LibraryModel::ItemFromQuery(GroupBy type, bool signal,
item->metadata.set_album(row.value(2).toString());
item->metadata.set_grouping(row.value(3).toString());
effective_originalyear = qMax(0, item->metadata.effective_originalyear());
item->key = PrettyYearAlbum(effective_originalyear, item->metadata.album());
item->sort_text = SortTextForNumber(effective_originalyear) + item->metadata.grouping()
+ item->metadata.album();
item->key =
PrettyYearAlbum(effective_originalyear, item->metadata.album());
item->sort_text = SortTextForNumber(effective_originalyear) +
item->metadata.grouping() + item->metadata.album();
break;
case GroupBy_Year:
@ -1050,7 +1047,8 @@ LibraryItem* LibraryModel::ItemFromSong(GroupBy type, bool signal,
item->metadata.set_originalyear(originalyear);
item->metadata.set_album(s.album());
item->key = PrettyYearAlbum(effective_originalyear, s.album());
item->sort_text = SortTextForNumber(effective_originalyear) + s.grouping() + s.album();
item->sort_text =
SortTextForNumber(effective_originalyear) + s.grouping() + s.album();
break;
case GroupBy_Year:

View File

@ -195,7 +195,7 @@ signals:
void TotalSongCountUpdatedSlot(int count);
// Called after ResetAsync
void ResetAsyncQueryFinished();
void ResetAsyncQueryFinished(QFuture<LibraryModel::QueryResult> future);
void AlbumArtLoaded(quint64 id, const QImage& image);

View File

@ -182,20 +182,14 @@ void MoodbarItemDelegate::StartLoadingColors(const QUrl& url,
Data* data) {
data->state_ = Data::State_LoadingColors;
QFutureWatcher<ColorVector>* watcher = new QFutureWatcher<ColorVector>();
NewClosure(watcher, SIGNAL(finished()), this,
SLOT(ColorsLoaded(QUrl, QFutureWatcher<ColorVector>*)), url,
watcher);
QFuture<ColorVector> future = QtConcurrent::run(
MoodbarRenderer::Colors, bytes, style_, qApp->palette());
watcher->setFuture(future);
NewClosure(future, this, SLOT(ColorsLoaded(QUrl, QFuture<ColorVector>)), url,
future);
}
void MoodbarItemDelegate::ColorsLoaded(const QUrl& url,
QFutureWatcher<ColorVector>* watcher) {
watcher->deleteLater();
QFuture<ColorVector> future) {
Data* data = data_[url];
if (!data) {
return;
@ -205,7 +199,7 @@ void MoodbarItemDelegate::ColorsLoaded(const QUrl& url,
return;
}
data->colors_ = watcher->result();
data->colors_ = future.result();
// Load the image next.
StartLoadingImage(url, data);
@ -214,19 +208,13 @@ void MoodbarItemDelegate::ColorsLoaded(const QUrl& url,
void MoodbarItemDelegate::StartLoadingImage(const QUrl& url, Data* data) {
data->state_ = Data::State_LoadingImage;
QFutureWatcher<QImage>* watcher = new QFutureWatcher<QImage>();
NewClosure(watcher, SIGNAL(finished()), this,
SLOT(ImageLoaded(QUrl, QFutureWatcher<QImage>*)), url, watcher);
QFuture<QImage> future = QtConcurrent::run(
MoodbarRenderer::RenderToImage, data->colors_, data->desired_size_);
watcher->setFuture(future);
NewClosure(future, this, SLOT(ImageLoaded(QUrl, QFuture<QImage>)), url,
future);
}
void MoodbarItemDelegate::ImageLoaded(const QUrl& url,
QFutureWatcher<QImage>* watcher) {
watcher->deleteLater();
void MoodbarItemDelegate::ImageLoaded(const QUrl& url, QFuture<QImage> future) {
Data* data = data_[url];
if (!data) {
return;
@ -236,7 +224,7 @@ void MoodbarItemDelegate::ImageLoaded(const QUrl& url,
return;
}
QImage image(watcher->result());
QImage image(future.result());
// If the desired size changed then don't even bother converting the image
// to a pixmap, just reload it at the new size.

View File

@ -21,8 +21,8 @@
#include "moodbarrenderer.h"
#include <QCache>
#include <QFuture>
#include <QItemDelegate>
#include <QFutureWatcher>
#include <QUrl>
class Application;
@ -45,8 +45,8 @@ class MoodbarItemDelegate : public QItemDelegate {
void ReloadSettings();
void DataLoaded(const QUrl& url, MoodbarPipeline* pipeline);
void ColorsLoaded(const QUrl& url, QFutureWatcher<ColorVector>* watcher);
void ImageLoaded(const QUrl& url, QFutureWatcher<QImage>* watcher);
void ColorsLoaded(const QUrl& url, QFuture<ColorVector> future);
void ImageLoaded(const QUrl& url, QFuture<QImage> future);
private:
struct Data {

View File

@ -1457,10 +1457,6 @@ void Playlist::Save() const {
dynamic_playlist_);
}
namespace {
typedef QFutureWatcher<QList<PlaylistItemPtr>> PlaylistItemFutureWatcher;
}
void Playlist::Restore() {
if (!backend_) return;
@ -1470,17 +1466,12 @@ void Playlist::Restore() {
QFuture<QList<PlaylistItemPtr>> future =
QtConcurrent::run(backend_, &PlaylistBackend::GetPlaylistItems, id_);
PlaylistItemFutureWatcher* watcher = new PlaylistItemFutureWatcher(this);
watcher->setFuture(future);
connect(watcher, SIGNAL(finished()), SLOT(ItemsLoaded()));
NewClosure(future, this, SLOT(ItemsLoaded(QFuture<PlaylistItemList>)),
future);
}
void Playlist::ItemsLoaded() {
PlaylistItemFutureWatcher* watcher =
static_cast<PlaylistItemFutureWatcher*>(sender());
watcher->deleteLater();
PlaylistItemList items = watcher->future().result();
void Playlist::ItemsLoaded(QFuture<PlaylistItemList> future) {
PlaylistItemList items = future.result();
// backend returns empty elements for library items which it couldn't
// match (because they got deleted); we don't need those

View File

@ -394,7 +394,7 @@ signals:
void SongSaveComplete(TagReaderReply* reply,
const QPersistentModelIndex& index);
void ItemReloadComplete(const QPersistentModelIndex& index);
void ItemsLoaded();
void ItemsLoaded(QFuture<PlaylistItemList> future);
void SongInsertVetoListenerDestroyed();
private:

View File

@ -20,7 +20,6 @@
#include <QDateTime>
#include <QDir>
#include <QFuture>
#include <QFutureWatcher>
#include <QHeaderView>
#include <QHelpEvent>
#include <QLinearGradient>
@ -400,19 +399,12 @@ TagCompleter::TagCompleter(LibraryBackend* backend, Playlist::Column column,
: QCompleter(editor), editor_(editor) {
QFuture<TagCompletionModel*> future =
QtConcurrent::run(&InitCompletionModel, backend, column);
QFutureWatcher<TagCompletionModel*>* watcher =
new QFutureWatcher<TagCompletionModel*>(this);
watcher->setFuture(future);
connect(watcher, SIGNAL(finished()), SLOT(ModelReady()));
NewClosure(future, this, SLOT(ModelReady(QFuture<TagCompletionModel*>)),
future);
}
void TagCompleter::ModelReady() {
QFutureWatcher<TagCompletionModel*>* watcher =
dynamic_cast<QFutureWatcher<TagCompletionModel*>*>(sender());
if (!watcher) return;
TagCompletionModel* model = watcher->result();
void TagCompleter::ModelReady(QFuture<TagCompletionModel*> future) {
TagCompletionModel* model = future.result();
setModel(model);
setCaseSensitivity(Qt::CaseInsensitive);
editor_->setCompleter(this);
@ -421,7 +413,6 @@ void TagCompleter::ModelReady() {
QWidget* TagCompletionItemDelegate::createEditor(QWidget* parent,
const QStyleOptionViewItem&,
const QModelIndex&) const {
QLineEdit* editor = new QLineEdit(parent);
new TagCompleter(backend_, column_, editor);

View File

@ -159,7 +159,7 @@ class TagCompleter : public QCompleter {
QLineEdit* editor);
private slots:
void ModelReady();
void ModelReady(QFuture<TagCompletionModel*> future);
private:
QLineEdit* editor_;
@ -169,7 +169,7 @@ class TagCompletionItemDelegate : public PlaylistDelegateBase {
public:
TagCompletionItemDelegate(QObject* parent, LibraryBackend* backend,
Playlist::Column column)
: PlaylistDelegateBase(parent), backend_(backend), column_(column) {};
: PlaylistDelegateBase(parent), backend_(backend), column_(column){};
QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option,
const QModelIndex& index) const;

View File

@ -20,6 +20,7 @@
#include <memory>
#include <QFuture>
#include <QMap>
#include <QMetaType>
#include <QStandardItem>
@ -97,7 +98,10 @@ class PlaylistItem : public std::enable_shared_from_this<PlaylistItem> {
protected:
bool should_skip_;
enum DatabaseColumn { Column_LibraryId, Column_InternetService, };
enum DatabaseColumn {
Column_LibraryId,
Column_InternetService,
};
virtual QVariant DatabaseValue(DatabaseColumn) const {
return QVariant(QVariant::String);

View File

@ -33,7 +33,6 @@
#include <QFileDialog>
#include <QFileInfo>
#include <QFuture>
#include <QFutureWatcher>
#include <QMessageBox>
#include <QtConcurrentRun>
#include <QtDebug>
@ -185,21 +184,16 @@ void PlaylistManager::Save(int id, const QString& filename,
// from the left side bar and the playlist isn't loaded.
QFuture<QList<Song>> future = QtConcurrent::run(
playlist_backend_, &PlaylistBackend::GetPlaylistSongs, id);
QFutureWatcher<SongList>* watcher = new QFutureWatcher<SongList>(this);
watcher->setFuture(future);
NewClosure(watcher, SIGNAL(finished()), this,
SLOT(ItemsLoadedForSavePlaylist(QFutureWatcher<SongList>*,
QString, Playlist::Path)),
watcher, filename);
NewClosure(future, this, SLOT(ItemsLoadedForSavePlaylist(
QFuture<SongList>, QString, Playlist::Path)),
future, filename, path_type);
}
}
void PlaylistManager::ItemsLoadedForSavePlaylist(
QFutureWatcher<SongList>* watcher, const QString& filename,
Playlist::Path path_type) {
SongList song_list = watcher->future().result();
parser_->Save(song_list, filename, path_type);
void PlaylistManager::ItemsLoadedForSavePlaylist(QFuture<SongList> future,
const QString& filename,
Playlist::Path path_type) {
parser_->Save(future.result(), filename, path_type);
}
void PlaylistManager::SaveWithUI(int id, const QString& suggested_filename) {
@ -471,7 +465,7 @@ void PlaylistManager::InsertUrls(int id, const QList<QUrl>& urls, int pos,
}
void PlaylistManager::InsertSongs(int id, const SongList& songs, int pos,
bool play_now, bool enqueue) {
bool play_now, bool enqueue) {
Q_ASSERT(playlists_.contains(id));
playlists_[id].p->InsertSongs(songs, pos, play_now, enqueue);

View File

@ -221,7 +221,7 @@ class PlaylistManager : public PlaylistManagerInterface {
void InsertUrls(int id, const QList<QUrl>& urls, int pos = -1,
bool play_now = false, bool enqueue = false);
void InsertSongs(int id, const SongList& songs, int pos = -1,
bool play_now = false, bool enqueue = false);
bool play_now = false, bool enqueue = false);
// Removes items with given indices from the playlist. This operation is not
// undoable.
void RemoveItemsWithoutUndo(int id, const QList<int>& indices);
@ -234,7 +234,7 @@ class PlaylistManager : public PlaylistManagerInterface {
void OneOfPlaylistsChanged();
void UpdateSummaryText();
void SongsDiscovered(const SongList& songs);
void ItemsLoadedForSavePlaylist(QFutureWatcher<SongList>* watcher,
void ItemsLoadedForSavePlaylist(QFuture<SongList> future,
const QString& filename,
Playlist::Path path_type);

View File

@ -15,18 +15,16 @@
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/
#include "generator.h"
#include "generatorinserter.h"
#include "core/taskmanager.h"
#include "playlist/playlist.h"
#include "smartplaylists/generatorinserter.h"
#include <QFutureWatcher>
#include <QtConcurrentRun>
namespace smart_playlists {
#include "core/closure.h"
#include "core/taskmanager.h"
#include "playlist/playlist.h"
#include "smartplaylists/generator.h"
typedef QFuture<PlaylistItemList> Future;
typedef QFutureWatcher<PlaylistItemList> FutureWatcher;
namespace smart_playlists {
GeneratorInserter::GeneratorInserter(TaskManager* task_manager,
LibraryBackend* library, QObject* parent)
@ -57,18 +55,13 @@ void GeneratorInserter::Load(Playlist* destination, int row, bool play_now,
connect(generator.get(), SIGNAL(Error(QString)), SIGNAL(Error(QString)));
Future future = QtConcurrent::run(Generate, generator, dynamic_count);
FutureWatcher* watcher = new FutureWatcher(this);
watcher->setFuture(future);
connect(watcher, SIGNAL(finished()), SLOT(Finished()));
QFuture<PlaylistItemList> future =
QtConcurrent::run(Generate, generator, dynamic_count);
NewClosure(future, this, SLOT(Finished(QFuture<PlaylistItemList>)), future);
}
void GeneratorInserter::Finished() {
FutureWatcher* watcher = static_cast<FutureWatcher*>(sender());
watcher->deleteLater();
PlaylistItemList items = watcher->result();
void GeneratorInserter::Finished(QFuture<PlaylistItemList> future) {
PlaylistItemList items = future.result();
if (items.isEmpty()) {
if (is_dynamic_) {

View File

@ -20,8 +20,11 @@
#include "generator_fwd.h"
#include <QFuture>
#include <QObject>
#include "playlist/playlist.h"
class LibraryBackend;
class Playlist;
class TaskManager;
@ -45,7 +48,7 @@ signals:
void PlayRequested(const QModelIndex& index);
private slots:
void Finished();
void Finished(QFuture<PlaylistItemList> future);
private:
TaskManager* task_manager_;

View File

@ -20,7 +20,6 @@
#include <memory>
#include <QFutureWatcher>
#include <QtConcurrentRun>
#include "querygenerator.h"
@ -28,9 +27,6 @@
namespace smart_playlists {
typedef QFuture<PlaylistItemList> Future;
typedef QFutureWatcher<PlaylistItemList> FutureWatcher;
SearchPreview::SearchPreview(QWidget* parent)
: QWidget(parent), ui_(new Ui_SmartPlaylistSearchPreview), model_(nullptr) {
ui_->setupUi(this);
@ -95,17 +91,12 @@ void SearchPreview::RunSearch(const Search& 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()));
QFuture<PlaylistItemList> future = QtConcurrent::run(DoRunSearch, generator_);
NewClosure(future, this, SLOT(SearchFinished(QFuture<PlaylistItemList>)),
future);
}
void SearchPreview::SearchFinished() {
FutureWatcher* watcher = static_cast<FutureWatcher*>(sender());
watcher->deleteLater();
void SearchPreview::SearchFinished(QFuture<PlaylistItemList> future) {
last_search_ =
std::dynamic_pointer_cast<QueryGenerator>(generator_)->search();
generator_.reset();
@ -118,7 +109,7 @@ void SearchPreview::SearchFinished() {
return;
}
PlaylistItemList all_items = watcher->result();
PlaylistItemList all_items = future.result();
PlaylistItemList displayed_items = all_items.mid(0, Generator::kDefaultLimit);
model_->Clear();

View File

@ -21,6 +21,7 @@
#include "search.h"
#include "smartplaylists/generator_fwd.h"
#include <QFuture>
#include <QWidget>
class Application;
@ -49,7 +50,7 @@ class SearchPreview : public QWidget {
void RunSearch(const Search& search);
private slots:
void SearchFinished();
void SearchFinished(QFuture<PlaylistItemList> future);
private:
Ui_SmartPlaylistSearchPreview* ui_;

View File

@ -15,25 +15,24 @@
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "songinfoprovider.h"
#include "songinfoview.h"
#include "taglyricsinfoprovider.h"
#include "ultimatelyricsprovider.h"
#include "ultimatelyricsreader.h"
#ifdef HAVE_LIBLASTFM
#include "lastfmtrackinfoprovider.h"
#endif
#include "songinfo/songinfoview.h"
#include <QFuture>
#include <QFutureWatcher>
#include <QSettings>
#include <QtConcurrentRun>
const char* SongInfoView::kSettingsGroup = "SongInfo";
#include "config.h"
#include "core/closure.h"
#include "songinfo/songinfoprovider.h"
#include "songinfo/taglyricsinfoprovider.h"
#include "songinfo/ultimatelyricsprovider.h"
#include "songinfo/ultimatelyricsreader.h"
typedef QList<SongInfoProvider*> ProviderList;
#ifdef HAVE_LIBLASTFM
#include "songinfo/lastfmtrackinfoprovider.h"
#endif
const char* SongInfoView::kSettingsGroup = "SongInfo";
SongInfoView::SongInfoView(QWidget* parent)
: SongInfoBase(parent), ultimate_reader_(new UltimateLyricsReader(this)) {
@ -41,10 +40,8 @@ SongInfoView::SongInfoView(QWidget* parent)
QFuture<ProviderList> future =
QtConcurrent::run(ultimate_reader_.get(), &UltimateLyricsReader::Parse,
QString(":lyrics/ultimate_providers.xml"));
QFutureWatcher<ProviderList>* watcher =
new QFutureWatcher<ProviderList>(this);
watcher->setFuture(future);
connect(watcher, SIGNAL(finished()), SLOT(UltimateLyricsParsed()));
NewClosure(future, this, SLOT(UltimateLyricsParsed(QFuture<ProviderList>)),
future);
#ifdef HAVE_LIBLASTFM
fetcher_->AddProvider(new LastfmTrackInfoProvider);
@ -54,15 +51,11 @@ SongInfoView::SongInfoView(QWidget* parent)
SongInfoView::~SongInfoView() {}
void SongInfoView::UltimateLyricsParsed() {
QFutureWatcher<ProviderList>* watcher =
static_cast<QFutureWatcher<ProviderList>*>(sender());
for (SongInfoProvider* provider : watcher->result()) {
void SongInfoView::UltimateLyricsParsed(QFuture<ProviderList> future) {
for (SongInfoProvider* provider : future.result()) {
fetcher_->AddProvider(provider);
}
watcher->deleteLater();
ultimate_reader_.reset();
ReloadSettings();

View File

@ -49,8 +49,9 @@ class SongInfoView : public SongInfoBase {
private:
SongInfoProvider* ProviderByName(const QString& name) const;
typedef QList<SongInfoProvider*> ProviderList;
private slots:
void UltimateLyricsParsed();
void UltimateLyricsParsed(QFuture<ProviderList> future);
private:
std::unique_ptr<UltimateLyricsReader> ultimate_reader_;

View File

@ -15,26 +15,14 @@
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/
#include "albumcovermanager.h"
#include "edittagdialog.h"
#include "trackselectiondialog.h"
#include "ui/edittagdialog.h"
#include "ui_edittagdialog.h"
#include "core/application.h"
#include "core/logging.h"
#include "core/tagreaderclient.h"
#include "core/utilities.h"
#include "covers/albumcoverloader.h"
#include "covers/coverproviders.h"
#include "library/library.h"
#include "library/librarybackend.h"
#include "playlist/playlistdelegates.h"
#include "ui/albumcoverchoicecontroller.h"
#include "ui/coverfromurldialog.h"
#include <limits>
#include <QDateTime>
#include <QDir>
#include <QFuture>
#include <QFutureWatcher>
#include <QLabel>
#include <QMenu>
#include <QMessageBox>
@ -43,7 +31,19 @@
#include <QtConcurrentRun>
#include <QtDebug>
#include <limits>
#include "core/application.h"
#include "core/logging.h"
#include "core/tagreaderclient.h"
#include "core/utilities.h"
#include "covers/albumcoverloader.h"
#include "covers/coverproviders.h"
#include "library/librarybackend.h"
#include "library/library.h"
#include "playlist/playlistdelegates.h"
#include "ui/albumcoverchoicecontroller.h"
#include "ui/albumcovermanager.h"
#include "ui/coverfromurldialog.h"
#include "ui/trackselectiondialog.h"
const char* EditTagDialog::kHintText =
QT_TR_NOOP("(different across multiple songs)");
@ -158,12 +158,10 @@ EditTagDialog::EditTagDialog(Application* app, QWidget* parent)
ui_->art->setAcceptDrops(true);
// Add the next/previous buttons
previous_button_ =
new QPushButton(IconLoader::Load("go-previous", IconLoader::Base),
tr("Previous"), this);
next_button_ =
new QPushButton(IconLoader::Load("go-next", IconLoader::Base),
tr("Next"), this);
previous_button_ = new QPushButton(
IconLoader::Load("go-previous", IconLoader::Base), tr("Previous"), this);
next_button_ = new QPushButton(IconLoader::Load("go-next", IconLoader::Base),
tr("Next"), this);
ui_->button_box->addButton(previous_button_, QDialogButtonBox::ResetRole);
ui_->button_box->addButton(next_button_, QDialogButtonBox::ResetRole);
@ -251,20 +249,15 @@ void EditTagDialog::SetSongs(const SongList& s, const PlaylistItemList& items) {
// Reload tags in the background
QFuture<QList<Data>> future =
QtConcurrent::run(this, &EditTagDialog::LoadData, s);
QFutureWatcher<QList<Data>>* watcher = new QFutureWatcher<QList<Data>>(this);
watcher->setFuture(future);
connect(watcher, SIGNAL(finished()), SLOT(SetSongsFinished()));
NewClosure(future, this,
SLOT(SetSongsFinished(QFuture<QList<EditTagDialog::Data>>)),
future);
}
void EditTagDialog::SetSongsFinished() {
QFutureWatcher<QList<Data>>* watcher =
dynamic_cast<QFutureWatcher<QList<Data>>*>(sender());
if (!watcher) return;
watcher->deleteLater();
void EditTagDialog::SetSongsFinished(QFuture<QList<Data>> future) {
if (!SetLoading(QString())) return;
data_ = watcher->result();
data_ = future.result();
if (data_.count() == 0) {
// If there were no valid songs, disable everything
ui_->song_list->setEnabled(false);
@ -708,16 +701,10 @@ void EditTagDialog::accept() {
// Save tags in the background
QFuture<void> future =
QtConcurrent::run(this, &EditTagDialog::SaveData, data_);
QFutureWatcher<void>* watcher = new QFutureWatcher<void>(this);
watcher->setFuture(future);
connect(watcher, SIGNAL(finished()), SLOT(AcceptFinished()));
NewClosure(future, this, SLOT(AcceptFinished()));
}
void EditTagDialog::AcceptFinished() {
QFutureWatcher<void>* watcher = dynamic_cast<QFutureWatcher<void>*>(sender());
if (!watcher) return;
watcher->deleteLater();
if (!SetLoading(QString())) return;
QDialog::accept();

View File

@ -64,8 +64,26 @@ signals:
void showEvent(QShowEvent*);
void hideEvent(QHideEvent*);
private:
struct Data {
Data(const Song& song = Song()) : original_(song), current_(song) {}
static QVariant value(const Song& song, const QString& id);
QVariant original_value(const QString& id) const {
return value(original_, id);
}
QVariant current_value(const QString& id) const {
return value(current_, id);
}
void set_value(const QString& id, const QVariant& value);
Song original_;
Song current_;
};
private slots:
void SetSongsFinished();
void SetSongsFinished(QFuture<QList<EditTagDialog::Data>> future);
void AcceptFinished();
void SelectionChanged();
@ -90,23 +108,6 @@ signals:
void NextSong();
private:
struct Data {
Data(const Song& song = Song()) : original_(song), current_(song) {}
static QVariant value(const Song& song, const QString& id);
QVariant original_value(const QString& id) const {
return value(original_, id);
}
QVariant current_value(const QString& id) const {
return value(current_, id);
}
void set_value(const QString& id, const QVariant& value);
Song original_;
Song current_;
};
struct FieldData {
FieldData(QLabel* label = nullptr, QWidget* editor = nullptr,
const QString& id = QString())

View File

@ -22,7 +22,6 @@
#include <QDir>
#include <QFileInfo>
#include <QFutureWatcher>
#include <QHash>
#include <QMenu>
#include <QPushButton>
@ -53,7 +52,8 @@ OrganiseDialog::OrganiseDialog(TaskManager* task_manager, QWidget* parent)
connect(ui_->button_box->button(QDialogButtonBox::Reset), SIGNAL(clicked()),
SLOT(Reset()));
ui_->aftercopying->setItemIcon(1, IconLoader::Load("edit-delete", IconLoader::Base));
ui_->aftercopying->setItemIcon(
1, IconLoader::Load("edit-delete", IconLoader::Base));
// Valid tags
QMap<QString, QString> tags;
@ -155,12 +155,7 @@ bool OrganiseDialog::SetUrls(const QList<QUrl>& urls) {
bool OrganiseDialog::SetFilenames(const QStringList& filenames) {
songs_future_ =
QtConcurrent::run(this, &OrganiseDialog::LoadSongsBlocking, filenames);
QFutureWatcher<SongList>* watcher = new QFutureWatcher<SongList>(this);
watcher->setFuture(songs_future_);
NewClosure(watcher, SIGNAL(finished()), [=]() {
SetSongs(songs_future_.result());
watcher->deleteLater();
});
NewClosure(songs_future_, [=]() { SetSongs(songs_future_.result()); });
SetLoadingSongs(true);
return true;

View File

@ -21,6 +21,7 @@
#include <memory>
#include <QDialog>
#include <QFuture>
#include <QMap>
#include <QUrl>
@ -60,7 +61,7 @@ class OrganiseDialog : public QDialog {
void SetCopy(bool copy);
signals:
signals:
void FileCopied(int);
public slots:

View File

@ -15,13 +15,10 @@
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/
#include "iconloader.h"
#include "trackselectiondialog.h"
#include "ui/trackselectiondialog.h"
#include "ui_trackselectiondialog.h"
#include "core/tagreaderclient.h"
#include <QFileInfo>
#include <QFutureWatcher>
#include <QPushButton>
#include <QShortcut>
#include <QTreeWidget>
@ -29,6 +26,9 @@
#include <QtConcurrentRun>
#include <QtDebug>
#include "core/tagreaderclient.h"
#include "ui/iconloader.h"
TrackSelectionDialog::TrackSelectionDialog(QWidget* parent)
: QDialog(parent), ui_(new Ui_TrackSelectionDialog), save_on_close_(false) {
// Setup dialog window
@ -43,10 +43,9 @@ TrackSelectionDialog::TrackSelectionDialog(QWidget* parent)
SetLoading(QString());
// Add the next/previous buttons
previous_button_ =
new QPushButton(IconLoader::Load("go-previous", IconLoader::Base),
tr("Previous"), this);
next_button_ = new QPushButton(IconLoader::Load("go-next", IconLoader::Base),
previous_button_ = new QPushButton(
IconLoader::Load("go-previous", IconLoader::Base), tr("Previous"), this);
next_button_ = new QPushButton(IconLoader::Load("go-next", IconLoader::Base),
tr("Next"), this);
ui_->button_box->addButton(previous_button_, QDialogButtonBox::ResetRole);
ui_->button_box->addButton(next_button_, QDialogButtonBox::ResetRole);
@ -258,10 +257,7 @@ void TrackSelectionDialog::accept() {
// Save tags in the background
QFuture<void> future =
QtConcurrent::run(&TrackSelectionDialog::SaveData, data_);
QFutureWatcher<void>* watcher = new QFutureWatcher<void>(this);
watcher->setFuture(future);
connect(watcher, SIGNAL(finished()), SLOT(AcceptFinished()));
NewClosure(future, this, SLOT(AcceptFinished()));
return;
}
@ -278,10 +274,6 @@ void TrackSelectionDialog::accept() {
}
void TrackSelectionDialog::AcceptFinished() {
QFutureWatcher<void>* watcher = dynamic_cast<QFutureWatcher<void>*>(sender());
if (!watcher) return;
watcher->deleteLater();
SetLoading(QString());
QDialog::accept();
}