mirror of
https://github.com/clementine-player/Clementine
synced 2025-01-31 11:35:24 +01:00
Early Caturday!
This commit is contained in:
parent
6b35eea469
commit
5f6dcbe4b7
@ -52,6 +52,7 @@ set(SOURCES
|
||||
core/globalshortcutbackend.cpp
|
||||
core/globalshortcuts.cpp
|
||||
core/gnomeglobalshortcutbackend.cpp
|
||||
core/kittenloader.cpp
|
||||
core/mergedproxymodel.cpp
|
||||
core/mpris_common.cpp
|
||||
core/musicstorage.cpp
|
||||
@ -239,6 +240,7 @@ set(HEADERS
|
||||
core/deletefiles.h
|
||||
core/globalshortcuts.h
|
||||
core/gnomeglobalshortcutbackend.h
|
||||
core/kittenloader.h
|
||||
core/mergedproxymodel.h
|
||||
core/mpris_common.h
|
||||
core/network.h
|
||||
|
@ -35,7 +35,6 @@ class AlbumCoverLoader : public QObject {
|
||||
public:
|
||||
AlbumCoverLoader(QObject* parent = 0);
|
||||
|
||||
|
||||
void Stop() { stop_requested_ = true; }
|
||||
|
||||
static QString ImageCacheDir();
|
||||
@ -46,10 +45,11 @@ class AlbumCoverLoader : public QObject {
|
||||
|
||||
|
||||
quint64 LoadImageAsync(const Song& song);
|
||||
quint64 LoadImageAsync(const QString& art_automatic,
|
||||
const QString& art_manual,
|
||||
const QString& song_filename = QString(),
|
||||
const QImage& embedded_image = QImage());
|
||||
virtual quint64 LoadImageAsync(
|
||||
const QString& art_automatic,
|
||||
const QString& art_manual,
|
||||
const QString& song_filename = QString(),
|
||||
const QImage& embedded_image = QImage());
|
||||
|
||||
void Clear();
|
||||
|
||||
@ -61,11 +61,11 @@ class AlbumCoverLoader : public QObject {
|
||||
signals:
|
||||
void ImageLoaded(quint64 id, const QImage& image);
|
||||
|
||||
private slots:
|
||||
protected slots:
|
||||
void ProcessTasks();
|
||||
void RemoteFetchFinished();
|
||||
|
||||
private:
|
||||
protected:
|
||||
enum State {
|
||||
State_TryingManual,
|
||||
State_TryingAuto,
|
||||
|
98
src/core/kittenloader.cpp
Normal file
98
src/core/kittenloader.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
#include "kittenloader.h"
|
||||
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
#include "core/network.h"
|
||||
|
||||
const char* KittenLoader::kFlickrKittenUrl =
|
||||
"http://api.flickr.com/services/rest/"
|
||||
"?method=flickr.photos.search"
|
||||
"&api_key=d4dbb3e0fcb0cc0331da7d6a40df9d26"
|
||||
"&tags=cat"
|
||||
"&sort=random"
|
||||
"&safe_search=1"
|
||||
"&content_type=1"
|
||||
"&auth_token=72157625568449786-b84430cc6d3a8665"
|
||||
"&api_sig=66b58c9c4aa61a48d62409bc6d7b1326";
|
||||
|
||||
const char* KittenLoader::kFlickrPhotoUrl =
|
||||
"http://farm%1.static.flickr.com/%2/%3_%4_m.jpg";
|
||||
|
||||
KittenLoader::KittenLoader(QObject* parent)
|
||||
: AlbumCoverLoader(parent) {
|
||||
}
|
||||
|
||||
quint64 KittenLoader::LoadImageAsync(
|
||||
const QString& art_automatic,
|
||||
const QString& art_manual,
|
||||
const QString& song_filename,
|
||||
const QImage& embedded_image) {
|
||||
if (!kitten_urls_.isEmpty()) {
|
||||
QUrl url = kitten_urls_.dequeue();
|
||||
return AlbumCoverLoader::LoadImageAsync(
|
||||
QString::null,
|
||||
url.toString(),
|
||||
QString::null,
|
||||
QImage());
|
||||
}
|
||||
|
||||
Task task;
|
||||
{
|
||||
QMutexLocker l(&mutex_);
|
||||
task.id = next_id_++;
|
||||
pending_kittens_.enqueue(task);
|
||||
}
|
||||
|
||||
metaObject()->invokeMethod(this, "FetchMoreKittens", Qt::QueuedConnection);
|
||||
|
||||
return task.id;
|
||||
}
|
||||
|
||||
void KittenLoader::FetchMoreKittens() {
|
||||
QNetworkRequest req = QNetworkRequest(QUrl(kFlickrKittenUrl));
|
||||
QNetworkReply* reply = network_->get(req);
|
||||
connect(reply, SIGNAL(finished()), SLOT(KittensRetrieved()));
|
||||
}
|
||||
|
||||
void KittenLoader::KittensRetrieved() {
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
|
||||
Q_ASSERT(reply);
|
||||
reply->deleteLater();
|
||||
|
||||
QXmlStreamReader reader(reply);
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNext();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == "photo") {
|
||||
QXmlStreamAttributes attrs = reader.attributes();
|
||||
QStringRef farm_id = attrs.value("farm");
|
||||
QStringRef photo_id = attrs.value("id");
|
||||
QStringRef secret = attrs.value("secret");
|
||||
QStringRef server = attrs.value("server");
|
||||
QString photo_url = QString(kFlickrPhotoUrl)
|
||||
.arg(farm_id.toString())
|
||||
.arg(server.toString())
|
||||
.arg(photo_id.toString())
|
||||
.arg(secret.toString());
|
||||
kitten_urls_ << QUrl(photo_url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QMutexLocker l(&mutex_);
|
||||
while (!kitten_urls_.isEmpty() && !pending_kittens_.isEmpty()) {
|
||||
Task task = pending_kittens_.dequeue();
|
||||
QUrl kitten_url = kitten_urls_.dequeue();
|
||||
task.art_manual = kitten_url.toString();
|
||||
task.state = State_TryingManual;
|
||||
tasks_.enqueue(task);
|
||||
}
|
||||
|
||||
if (kitten_urls_.isEmpty()) {
|
||||
FetchMoreKittens();
|
||||
}
|
||||
|
||||
metaObject()->invokeMethod(this, "ProcessTasks", Qt::QueuedConnection);
|
||||
}
|
32
src/core/kittenloader.h
Normal file
32
src/core/kittenloader.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef KITTENLOADER_H
|
||||
#define KITTENLOADER_H
|
||||
|
||||
#include "albumcoverloader.h"
|
||||
|
||||
#include <QQueue>
|
||||
#include <QUrl>
|
||||
|
||||
class KittenLoader : public AlbumCoverLoader {
|
||||
Q_OBJECT
|
||||
public:
|
||||
KittenLoader(QObject* parent = 0);
|
||||
|
||||
virtual quint64 LoadImageAsync(
|
||||
const QString& art_automatic,
|
||||
const QString& art_manual,
|
||||
const QString& song_filename,
|
||||
const QImage& embedded_image);
|
||||
|
||||
private slots:
|
||||
void KittensRetrieved();
|
||||
void FetchMoreKittens();
|
||||
|
||||
private:
|
||||
static const char* kFlickrKittenUrl;
|
||||
static const char* kFlickrPhotoUrl;
|
||||
|
||||
QQueue<Task> pending_kittens_;
|
||||
QQueue<QUrl> kitten_urls_;
|
||||
};
|
||||
|
||||
#endif
|
@ -1121,6 +1121,9 @@ msgstr ""
|
||||
msgid "Keep the original files"
|
||||
msgstr ""
|
||||
|
||||
msgid "Kittens"
|
||||
msgstr ""
|
||||
|
||||
msgid "Language"
|
||||
msgstr ""
|
||||
|
||||
|
@ -546,6 +546,7 @@ MainWindow::MainWindow(Engine::Type engine, QWidget *parent)
|
||||
connect(ui_->now_playing, SIGNAL(ShowAboveStatusBarChanged(bool)),
|
||||
SLOT(NowPlayingWidgetPositionChanged(bool)));
|
||||
connect(ui_->action_hypnotoad, SIGNAL(toggled(bool)), ui_->now_playing, SLOT(AllHail(bool)));
|
||||
connect(ui_->action_kittens, SIGNAL(toggled(bool)), ui_->now_playing, SLOT(EnableKittens(bool)));
|
||||
NowPlayingWidgetPositionChanged(ui_->now_playing->show_above_status_bar());
|
||||
|
||||
// Load theme
|
||||
|
@ -443,6 +443,7 @@
|
||||
</property>
|
||||
<addaction name="action_rain"/>
|
||||
<addaction name="action_hypnotoad"/>
|
||||
<addaction name="action_kittens" />
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuTools">
|
||||
<property name="title">
|
||||
@ -648,6 +649,14 @@
|
||||
<string comment="Label for button to enable/disable Hypnotoad background sound.">All Glory to the Hypnotoad!</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_kittens">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string comment="Label for buton to enable/disable kittens in the now playing widget">Kittens</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_shuffle_mode">
|
||||
<property name="text">
|
||||
<string>Shuffle mode</string>
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "nowplayingwidget.h"
|
||||
#include "core/albumcoverloader.h"
|
||||
#include "core/kittenloader.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QMovie>
|
||||
@ -52,6 +53,7 @@ const int NowPlayingWidget::kTopBorder = 4;
|
||||
NowPlayingWidget::NowPlayingWidget(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
cover_loader_(new BackgroundThreadImplementation<AlbumCoverLoader, AlbumCoverLoader>(this)),
|
||||
kitten_loader_(NULL),
|
||||
mode_(SmallSongDetails),
|
||||
menu_(new QMenu(this)),
|
||||
above_statusbar_action_(NULL),
|
||||
@ -63,7 +65,8 @@ NowPlayingWidget::NowPlayingWidget(QWidget *parent)
|
||||
load_cover_id_(0),
|
||||
details_(new QTextDocument(this)),
|
||||
previous_track_opacity_(0.0),
|
||||
hypnotoad_(NULL)
|
||||
hypnotoad_(NULL),
|
||||
aww_(false)
|
||||
{
|
||||
// Load settings
|
||||
QSettings s;
|
||||
@ -108,7 +111,9 @@ void NowPlayingWidget::CreateModeAction(Mode mode, const QString &text, QActionG
|
||||
|
||||
void NowPlayingWidget::set_ideal_height(int height) {
|
||||
small_ideal_height_ = height;
|
||||
UpdateHeight();
|
||||
UpdateHeight(aww_
|
||||
? kitten_loader_->Worker().get()
|
||||
: cover_loader_->Worker().get());
|
||||
}
|
||||
|
||||
QSize NowPlayingWidget::sizeHint() const {
|
||||
@ -116,13 +121,15 @@ QSize NowPlayingWidget::sizeHint() const {
|
||||
}
|
||||
|
||||
void NowPlayingWidget::CoverLoaderInitialised() {
|
||||
UpdateHeight();
|
||||
cover_loader_->Worker()->SetPadOutputImage(true);
|
||||
connect(cover_loader_->Worker().get(), SIGNAL(ImageLoaded(quint64,QImage)),
|
||||
BackgroundThread<AlbumCoverLoader>* loader =
|
||||
static_cast<BackgroundThread<AlbumCoverLoader>*>(sender());
|
||||
UpdateHeight(loader->Worker().get());
|
||||
loader->Worker()->SetPadOutputImage(true);
|
||||
connect(loader->Worker().get(), SIGNAL(ImageLoaded(quint64,QImage)),
|
||||
SLOT(AlbumArtLoaded(quint64,QImage)));
|
||||
}
|
||||
|
||||
void NowPlayingWidget::UpdateHeight() {
|
||||
void NowPlayingWidget::UpdateHeight(AlbumCoverLoader* loader) {
|
||||
switch (mode_) {
|
||||
case SmallSongDetails:
|
||||
cover_height_ = small_ideal_height_;
|
||||
@ -141,11 +148,11 @@ void NowPlayingWidget::UpdateHeight() {
|
||||
setMaximumHeight(total_height_);
|
||||
|
||||
// Tell the cover loader what size we want the images in
|
||||
cover_loader_->Worker()->SetDesiredHeight(cover_height_);
|
||||
cover_loader_->Worker()->SetDefaultOutputImage(QImage(":nocover.png"));
|
||||
loader->SetDesiredHeight(cover_height_);
|
||||
loader->SetDefaultOutputImage(QImage(":nocover.png"));
|
||||
|
||||
// Re-fetch the current image
|
||||
load_cover_id_ = cover_loader_->Worker()->LoadImageAsync(metadata_);
|
||||
load_cover_id_ = loader->LoadImageAsync(metadata_);
|
||||
|
||||
// Tell Qt we've changed size
|
||||
updateGeometry();
|
||||
@ -165,7 +172,10 @@ void NowPlayingWidget::NowPlaying(const Song& metadata) {
|
||||
metadata_ = metadata;
|
||||
cover_ = QPixmap();
|
||||
|
||||
UpdateHeight(); // Loads the cover too
|
||||
// Loads the cover too.
|
||||
UpdateHeight(aww_
|
||||
? kitten_loader_->Worker().get()
|
||||
: cover_loader_->Worker().get());
|
||||
UpdateDetailsText();
|
||||
|
||||
SetVisible(true);
|
||||
@ -305,7 +315,9 @@ void NowPlayingWidget::FadePreviousTrack(qreal value) {
|
||||
|
||||
void NowPlayingWidget::SetMode(int mode) {
|
||||
mode_ = Mode(mode);
|
||||
UpdateHeight();
|
||||
UpdateHeight(aww_
|
||||
? kitten_loader_->Worker().get()
|
||||
: cover_loader_->Worker().get());
|
||||
UpdateDetailsText();
|
||||
update();
|
||||
|
||||
@ -316,7 +328,9 @@ void NowPlayingWidget::SetMode(int mode) {
|
||||
|
||||
void NowPlayingWidget::resizeEvent(QResizeEvent* e) {
|
||||
if (visible_ && mode_ == LargeSongDetails && e->oldSize().width() != e->size().width()) {
|
||||
UpdateHeight();
|
||||
UpdateHeight(aww_
|
||||
? kitten_loader_->Worker().get()
|
||||
: cover_loader_->Worker().get());
|
||||
UpdateDetailsText();
|
||||
}
|
||||
}
|
||||
@ -349,3 +363,15 @@ void NowPlayingWidget::AllHail(bool hypnotoad) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void NowPlayingWidget::EnableKittens(bool aww) {
|
||||
if (!kitten_loader_ && aww) {
|
||||
kitten_loader_ = new BackgroundThreadImplementation<AlbumCoverLoader, KittenLoader>(this);
|
||||
kitten_loader_->Start();
|
||||
connect(kitten_loader_, SIGNAL(Initialised()), SLOT(CoverLoaderInitialised()));
|
||||
} else if (aww) {
|
||||
NowPlaying(metadata_);
|
||||
}
|
||||
|
||||
aww_ = aww;
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ public slots:
|
||||
void NowPlaying(const Song& metadata);
|
||||
void Stopped();
|
||||
void AllHail(bool hypnotoad);
|
||||
void EnableKittens(bool aww);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* e);
|
||||
@ -87,11 +88,12 @@ private:
|
||||
void CreateModeAction(Mode mode, const QString& text, QActionGroup* group,
|
||||
QSignalMapper* mapper);
|
||||
void UpdateDetailsText();
|
||||
void UpdateHeight();
|
||||
void UpdateHeight(AlbumCoverLoader* loader);
|
||||
void DrawContents(QPainter* p);
|
||||
|
||||
private:
|
||||
BackgroundThread<AlbumCoverLoader>* cover_loader_;
|
||||
BackgroundThread<AlbumCoverLoader>* kitten_loader_;
|
||||
|
||||
Mode mode_;
|
||||
|
||||
@ -117,6 +119,8 @@ private:
|
||||
|
||||
static const char* kHypnotoadPath;
|
||||
QMovie* hypnotoad_;
|
||||
|
||||
bool aww_;
|
||||
};
|
||||
|
||||
#endif // NOWPLAYINGWIDGET_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user