18
18
#include "albumcoversearcher.h"
19
19
#include "ui_albumcoversearcher.h"
20
#include "core/albumcoverfetcher.h"
21
#include "core/albumcoverloader.h"
20
#include "core/logging.h"
21
#include "core/utilities.h"
22
#include "covers/albumcoverfetcher.h"
23
#include "covers/albumcoverloader.h"
24
#include "widgets/forcescrollperpixel.h"
25
#include "widgets/groupediconview.h"
23
27
#include <QKeyEvent>
24
28
#include <QListWidgetItem>
30
#include <QStandardItemModel>
32
const int SizeOverlayDelegate::kMargin = 4;
33
const int SizeOverlayDelegate::kPaddingX = 3;
34
const int SizeOverlayDelegate::kPaddingY = 1;
35
const qreal SizeOverlayDelegate::kBorder = 5.0;
36
const qreal SizeOverlayDelegate::kFontPointSize = 7.5;
37
const int SizeOverlayDelegate::kBorderAlpha = 200;
38
const int SizeOverlayDelegate::kBackgroundAlpha = 175;
41
SizeOverlayDelegate::SizeOverlayDelegate(QObject* parent)
42
: QStyledItemDelegate(parent)
46
void SizeOverlayDelegate::paint(QPainter* painter,
47
const QStyleOptionViewItem& option,
48
const QModelIndex& index) const {
49
QStyledItemDelegate::paint(painter, option, index);
51
if (!index.data(AlbumCoverSearcher::Role_ImageFetchFinished).toBool()) {
55
const QSize size = index.data(AlbumCoverSearcher::Role_ImageSize).toSize();
56
const QString text = Utilities::PrettySize(size);
58
QFont font(option.font);
59
font.setPointSizeF(kFontPointSize);
62
const QFontMetrics metrics(font);
64
const int text_width = metrics.width(text);
66
const QRect icon_rect(
67
option.rect.left(), option.rect.top(),
68
option.rect.width(), option.rect.width());
70
const QRect background_rect(
71
icon_rect.right() - kMargin - text_width - kPaddingX*2,
72
icon_rect.bottom() - kMargin - metrics.height() - kPaddingY*2,
73
text_width + kPaddingX*2, metrics.height() + kPaddingY*2);
74
const QRect text_rect(
75
background_rect.left() + kPaddingX, background_rect.top() + kPaddingY,
76
text_width, metrics.height());
79
painter->setRenderHint(QPainter::Antialiasing);
80
painter->setPen(QColor(0, 0, 0, kBorderAlpha));
81
painter->setBrush(QColor(0, 0, 0, kBackgroundAlpha));
82
painter->drawRoundedRect(background_rect, kBorder, kBorder);
84
painter->setPen(Qt::white);
85
painter->setFont(font);
86
painter->drawText(text_rect, text);
26
91
AlbumCoverSearcher::AlbumCoverSearcher(const QIcon& no_cover_icon, QWidget* parent)
28
93
ui_(new Ui_AlbumCoverSearcher),
94
model_(new QStandardItemModel(this)),
29
95
no_cover_icon_(no_cover_icon),
30
96
loader_(new BackgroundThreadImplementation<AlbumCoverLoader, AlbumCoverLoader>(this)),
100
setWindowModality(Qt::WindowModal);
34
101
ui_->setupUi(this);
35
102
ui_->busy->hide();
104
ui_->covers->set_header_text(tr("Covers from %1"));
105
ui_->covers->AddSortSpec(Role_ImageDimensions, Qt::DescendingOrder);
106
ui_->covers->setItemDelegate(new SizeOverlayDelegate(this));
107
ui_->covers->setModel(model_);
37
109
loader_->Start(true);
38
loader_->Worker()->SetDefaultOutputImage(QImage(":nocover.png"));
39
110
loader_->Worker()->SetScaleOutputImage(false);
40
111
loader_->Worker()->SetPadOutputImage(false);
41
112
connect(loader_->Worker().get(), SIGNAL(ImageLoaded(quint64,QImage)),
52
127
void AlbumCoverSearcher::Init(AlbumCoverFetcher* fetcher) {
53
128
fetcher_ = fetcher;
55
connect(fetcher_, SIGNAL(SearchFinished(quint64,AlbumCoverFetcher::SearchResults)), SLOT(SearchFinished(quint64,AlbumCoverFetcher::SearchResults)));
130
connect(fetcher_, SIGNAL(SearchFinished(quint64,CoverSearchResults,CoverSearchStatistics)),
131
SLOT(SearchFinished(quint64,CoverSearchResults)));
58
QImage AlbumCoverSearcher::Exec(const QString &query) {
59
ui_->query->setText(query);
60
ui_->query->setFocus();
134
QImage AlbumCoverSearcher::Exec(const QString& artist, const QString& album) {
135
ui_->artist->setText(artist);
136
ui_->album->setText(album);
137
ui_->artist->setFocus();
62
if(!query.isEmpty()) {
139
if(!artist.isEmpty() || !album.isEmpty()) {
66
143
if (exec() == QDialog::Rejected)
68
if (!ui_->covers->currentItem())
146
QModelIndex selected = ui_->covers->currentIndex();
147
if (!selected.isValid() || !selected.data(Role_ImageFetchFinished).toBool())
71
QIcon icon = ui_->covers->currentItem()->icon();
150
QIcon icon = selected.data(Qt::DecorationRole).value<QIcon>();
72
151
if (icon.cacheKey() == no_cover_icon_.cacheKey())
78
157
void AlbumCoverSearcher::Search() {
79
158
ui_->busy->show();
80
159
ui_->search->setEnabled(false);
81
ui_->query->setEnabled(false);
160
ui_->artist->setEnabled(false);
161
ui_->album->setEnabled(false);
82
162
ui_->covers->setEnabled(false);
84
id_ = fetcher_->SearchForCovers(ui_->query->text());
165
cover_loading_tasks_.clear();
167
id_ = fetcher_->SearchForCovers(ui_->artist->text(), ui_->album->text());
87
void AlbumCoverSearcher::SearchFinished(quint64 id, const AlbumCoverFetcher::SearchResults &results) {
170
void AlbumCoverSearcher::SearchFinished(quint64 id, const CoverSearchResults& results) {
91
174
ui_->search->setEnabled(true);
92
ui_->query->setEnabled(true);
175
ui_->artist->setEnabled(true);
176
ui_->album->setEnabled(true);
93
177
ui_->covers->setEnabled(true);
97
cover_loading_tasks_.clear();
98
foreach (const AlbumCoverFetcher::SearchResult& result, results) {
180
foreach (const CoverSearchResult& result, results) {
99
181
if (result.image_url.isEmpty())
102
184
quint64 id = loader_->Worker()->LoadImageAsync(result.image_url, QString());
104
QListWidgetItem* item = new QListWidgetItem(ui_->covers);
186
QStandardItem* item = new QStandardItem;
105
187
item->setIcon(no_cover_icon_);
106
item->setText(result.artist + " - " + result.album);
107
item->setData(Role_ImageURL, result.image_url);
108
item->setData(Role_ImageRequestId, id);
109
item->setData(Qt::TextAlignmentRole, QVariant(Qt::AlignTop | Qt::AlignHCenter));
188
item->setText(result.description);
189
item->setData(result.image_url, Role_ImageURL);
190
item->setData(id, Role_ImageRequestId);
191
item->setData(false, Role_ImageFetchFinished);
192
item->setData(QVariant(Qt::AlignTop | Qt::AlignHCenter), Qt::TextAlignmentRole);
193
item->setData(result.provider, GroupedIconView::Role_Group);
195
model_->appendRow(item);
111
197
cover_loading_tasks_[id] = item;
118
204
void AlbumCoverSearcher::ImageLoaded(quint64 id, const QImage& image) {
119
205
if (!cover_loading_tasks_.contains(id))
207
QStandardItem* item = cover_loading_tasks_.take(id);
209
if (cover_loading_tasks_.isEmpty())
212
if (image.isNull()) {
213
model_->removeRow(item->row());
122
217
QIcon icon(QPixmap::fromImage(image));
124
// Add an icon that's the right size for the view
125
icon.addPixmap(QPixmap::fromImage(image.scaled(ui_->covers->iconSize(),
126
Qt::KeepAspectRatio, Qt::SmoothTransformation)));
128
QListWidgetItem* item = cover_loading_tasks_.take(id);
219
// Create a pixmap that's padded and exactly the right size for the icon.
220
QImage scaled_image(image.scaled(ui_->covers->iconSize(),
222
Qt::SmoothTransformation));
224
QImage padded_image(ui_->covers->iconSize(), QImage::Format_ARGB32_Premultiplied);
225
padded_image.fill(0);
227
QPainter p(&padded_image);
228
p.drawImage((padded_image.width() - scaled_image.width()) / 2,
229
(padded_image.height() - scaled_image.height()) / 2,
233
icon.addPixmap(QPixmap::fromImage(padded_image));
235
item->setData(true, Role_ImageFetchFinished);
236
item->setData(image.width() * image.height(), Role_ImageDimensions);
237
item->setData(image.size(), Role_ImageSize);
129
238
item->setIcon(icon);
131
if (cover_loading_tasks_.isEmpty())
135
241
void AlbumCoverSearcher::keyPressEvent(QKeyEvent* e) {