Early Caturday!

This commit is contained in:
John Maguire 2010-12-10 14:26:29 +00:00
parent 6b35eea469
commit 5f6dcbe4b7
9 changed files with 195 additions and 20 deletions

View File

@ -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

View File

@ -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
View 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
View 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

View File

@ -1121,6 +1121,9 @@ msgstr ""
msgid "Keep the original files"
msgstr ""
msgid "Kittens"
msgstr ""
msgid "Language"
msgstr ""

View File

@ -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

View File

@ -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>

View File

@ -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;
}

View File

@ -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