1 /*
2  * Strawberry Music Player
3  * This file was part of Clementine.
4  * Copyright 2012, David Sansome <me@davidsansome.com>
5  *
6  * Strawberry is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Strawberry is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Strawberry.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #include "config.h"
22 
23 #include <QtGlobal>
24 #include <QObject>
25 #include <QAbstractItemModel>
26 #include <QStandardItem>
27 #include <QMap>
28 #include <QSet>
29 #include <QImage>
30 #include <QPixmap>
31 #include <QIcon>
32 
33 #include "covermanager/albumcoverloader.h"
34 #include "standarditemiconloader.h"
35 
StandardItemIconLoader(AlbumCoverLoader * cover_loader,QObject * parent)36 StandardItemIconLoader::StandardItemIconLoader(AlbumCoverLoader *cover_loader, QObject *parent)
37     : QObject(parent),
38       cover_loader_(cover_loader),
39       model_(nullptr) {
40 
41   cover_options_.desired_height_ = 16;
42 
43   QObject::connect(cover_loader_, &AlbumCoverLoader::AlbumCoverLoaded, this, &StandardItemIconLoader::AlbumCoverLoaded);
44 
45 }
46 
SetModel(QAbstractItemModel * model)47 void StandardItemIconLoader::SetModel(QAbstractItemModel *model) {
48 
49   if (model_) {
50     QObject::disconnect(model_, &QAbstractItemModel::rowsAboutToBeRemoved, this, &StandardItemIconLoader::RowsAboutToBeRemoved);
51   }
52 
53   model_ = model;
54 
55   QObject::connect(model_, &QAbstractItemModel::rowsAboutToBeRemoved, this, &StandardItemIconLoader::RowsAboutToBeRemoved);
56   QObject::connect(model_, &QAbstractItemModel::modelAboutToBeReset, this, &StandardItemIconLoader::ModelReset);
57 
58 }
59 
LoadIcon(const QUrl & art_automatic,const QUrl & art_manual,QStandardItem * for_item)60 void StandardItemIconLoader::LoadIcon(const QUrl &art_automatic, const QUrl &art_manual, QStandardItem *for_item) {
61 
62   const quint64 id = cover_loader_->LoadImageAsync(cover_options_, art_automatic, art_manual);
63   pending_covers_[id] = for_item;
64 
65 }
66 
LoadIcon(const Song & song,QStandardItem * for_item)67 void StandardItemIconLoader::LoadIcon(const Song &song, QStandardItem *for_item) {
68   const quint64 id = cover_loader_->LoadImageAsync(cover_options_, song);
69   pending_covers_[id] = for_item;
70 }
71 
RowsAboutToBeRemoved(const QModelIndex & parent,int begin,int end)72 void StandardItemIconLoader::RowsAboutToBeRemoved(const QModelIndex &parent, int begin, int end) {
73 
74   for (QMap<quint64, QStandardItem*>::iterator it = pending_covers_.begin(); it != pending_covers_.end();) {
75     const QStandardItem *item = it.value();
76     const QStandardItem *item_parent = item->parent();
77 
78     if (item_parent && item_parent->index() == parent && item->index().row() >= begin && item->index().row() <= end) {
79       cover_loader_->CancelTask(it.key());
80       it = pending_covers_.erase(it);  // clazy:exclude=strict-iterators
81     }
82     else {
83       ++it;
84     }
85   }
86 
87 }
88 
ModelReset()89 void StandardItemIconLoader::ModelReset() {
90 
91 #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
92   cover_loader_->CancelTasks(QSet<quint64>(pending_covers_.keyBegin(), pending_covers_.keyEnd()));
93 #else
94   cover_loader_->CancelTasks(QSet<quint64>::fromList(pending_covers_.keys()));
95 #endif
96   pending_covers_.clear();
97 
98 }
99 
AlbumCoverLoaded(const quint64 id,const AlbumCoverLoaderResult & result)100 void StandardItemIconLoader::AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderResult &result) {
101 
102   QStandardItem *item = pending_covers_.take(id);
103   if (!item) return;
104 
105   if (result.success && !result.image_scaled.isNull() && result.type != AlbumCoverLoaderResult::Type_ManuallyUnset) {
106     item->setIcon(QIcon(QPixmap::fromImage(result.image_scaled)));
107   }
108 
109 }
110