- Show podcast coves in toolbar, queue, and info view.
- Show podcast description in info view. - Only show cover in toolbar cover tooltip. Issue #1556
This commit is contained in:
committed by
Craig Drummond
parent
e10350842d
commit
2d8566d743
@@ -54,10 +54,13 @@
|
||||
40. Categorized view is reported to crash (#1530), so disable by default. Pass
|
||||
-DENABLE_CATEGORIZED_VIEW=ON to cmake to re-enable.
|
||||
41. Add 'aac' and 'libfdk_aac' as supported encoders.
|
||||
42. Custom playqueue background is not workig with Qt 5.12 onwards, so
|
||||
disabled for now.
|
||||
42. Custom playqueue background is not working with Qt 5.12 onwards, so
|
||||
disabled for now. (#1554)
|
||||
43. Convert podcast descriptions to plain text, trim whitespace, and limit to
|
||||
1000 characters.
|
||||
44. Show podcast coves in toolbar, queue, and info view.
|
||||
45. Show podcast description in info view.
|
||||
46. Only show cover in toolbar cover tooltip.
|
||||
|
||||
2.3.3
|
||||
-----
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "onlineview.h"
|
||||
#include "gui/covers.h"
|
||||
#include "online/podcastservice.h"
|
||||
|
||||
OnlineView::OnlineView(QWidget *p)
|
||||
: View(p)
|
||||
@@ -40,12 +41,13 @@ void OnlineView::update(const Song &song, bool force)
|
||||
needToUpdate=true;
|
||||
return;
|
||||
}
|
||||
setHeader(song.describe());
|
||||
Covers::Image cImg=Covers::self()->requestImage(song, true);
|
||||
setHeader(currentSong.describe().replace("<b>", "").replace("</b>", ""));
|
||||
QString descr = PodcastService::self()->episodeDescr(song);
|
||||
Covers::Image cImg = Covers::self()->requestImage(song, true);
|
||||
if (!cImg.img.isNull()) {
|
||||
setHtml(createPicTag(cImg.img, cImg.fileName));
|
||||
setHtml(createPicTag(cImg.img, cImg.fileName)+(descr.isEmpty() ? QString() : ("<br>"+descr)));
|
||||
} else {
|
||||
setHtml(QString());
|
||||
setHtml(descr.isEmpty() ? QString() : descr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "song.h"
|
||||
#if !defined CANTATA_NO_UI_FUNCTIONS
|
||||
#include "online/onlineservice.h"
|
||||
#include "online/podcastservice.h"
|
||||
#endif
|
||||
#include <QStringList>
|
||||
#include <QSet>
|
||||
@@ -825,6 +826,12 @@ QString Song::filePath(const QString &base) const
|
||||
|
||||
QString Song::describe() const
|
||||
{
|
||||
#if !defined CANTATA_NO_UI_FUNCTIONS
|
||||
if (OnlineSvrTrack==type && PodcastService::constName==onlineService()) {
|
||||
return title;
|
||||
}
|
||||
#endif
|
||||
|
||||
QString albumText=album.isEmpty() ? name() : displayAlbum(album, Song::albumYear(*this));
|
||||
|
||||
if (title.isEmpty()) {
|
||||
|
||||
@@ -57,6 +57,8 @@ Song & OnlineService::encode(Song &song)
|
||||
add(json, "track", song.track);
|
||||
add(json, "disc", song.disc);
|
||||
add(json, "service", song.onlineService());
|
||||
add(json, "imgcache", song.extraField(Song::OnlineImageCacheName));
|
||||
add(json, "imgurl", song.extraField(Song::OnlineImageUrl));
|
||||
song.file=Utils::addHashParam(QUrl(song.file).toEncoded(), constSongDetails, QJsonDocument(json).toJson(QJsonDocument::Compact));
|
||||
return song;
|
||||
}
|
||||
@@ -84,6 +86,8 @@ bool OnlineService::decode(Song &song)
|
||||
if (obj.contains("track")) song.track=obj["track"].toInt();
|
||||
if (obj.contains("disc")) song.track=obj["disc"].toInt();
|
||||
song.setIsFromOnlineService(obj["service"].toString());
|
||||
if (obj.contains("imgcache")) song.setExtraField(Song::OnlineImageCacheName, obj["imgcache"].toString());
|
||||
if (obj.contains("imgurl")) song.setExtraField(Song::OnlineImageUrl, obj["imgurl"].toString());
|
||||
song.type=Song::OnlineSvrTrack;
|
||||
song.file=Utils::removeHash(song.file);
|
||||
return true;
|
||||
|
||||
@@ -49,9 +49,8 @@ OnlineServicesPage::OnlineServicesPage(QWidget *p)
|
||||
SoundCloudService *soundcloud=new SoundCloudService(this);
|
||||
addPage(soundcloud->name(), soundcloud->icon(), soundcloud->title(), soundcloud->descr(), new OnlineSearchWidget(soundcloud, this));
|
||||
|
||||
podcast=new PodcastService(this);
|
||||
addPage(podcast->name(), podcast->icon(), podcast->title(), podcast->descr(), new PodcastWidget(podcast, this));
|
||||
connect(podcast, SIGNAL(error(QString)), this, SIGNAL(error(QString)));
|
||||
addPage(PodcastService::self()->name(), PodcastService::self()->icon(), PodcastService::self()->title(), PodcastService::self()->descr(), new PodcastWidget(PodcastService::self(), this));
|
||||
connect(PodcastService::self(), SIGNAL(error(QString)), this, SIGNAL(error(QString)));
|
||||
|
||||
Configuration config(metaObject()->className());
|
||||
load(config);
|
||||
@@ -65,12 +64,12 @@ OnlineServicesPage::~OnlineServicesPage()
|
||||
|
||||
bool OnlineServicesPage::isDownloading()
|
||||
{
|
||||
return podcast->isDownloading();
|
||||
return PodcastService::self()->isDownloading();
|
||||
}
|
||||
|
||||
void OnlineServicesPage::cancelAll()
|
||||
{
|
||||
podcast->cancelAll();
|
||||
PodcastService::self()->cancelAll();
|
||||
}
|
||||
|
||||
#include "moc_onlineservicespage.cpp"
|
||||
|
||||
@@ -27,8 +27,6 @@
|
||||
#include "onlineservice.h"
|
||||
#include "widgets/multipagewidget.h"
|
||||
|
||||
class PodcastService;
|
||||
|
||||
class OnlineServicesPage : public MultiPageWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -44,9 +42,6 @@ public:
|
||||
|
||||
Q_SIGNALS:
|
||||
void error(const QString &msg);
|
||||
|
||||
private:
|
||||
PodcastService *podcast;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "podcastservice.h"
|
||||
#include "podcastsettingsdialog.h"
|
||||
#include "rssparser.h"
|
||||
#include "support/globalstatic.h"
|
||||
#include "support/utils.h"
|
||||
#include "support/monoicon.h"
|
||||
#include "gui/settings.h"
|
||||
@@ -48,6 +49,8 @@
|
||||
#include <QTextDocument>
|
||||
#include <stdio.h>
|
||||
|
||||
GLOBAL_STATIC(PodcastService, instance)
|
||||
|
||||
static QString encodeName(const QString &name)
|
||||
{
|
||||
QString n=name;
|
||||
@@ -214,8 +217,10 @@ Song PodcastService::Episode::toSong() const
|
||||
Song song;
|
||||
song.title=name;
|
||||
song.file=url.toString();
|
||||
song.artist=parent->name;
|
||||
song.album=parent->name;
|
||||
song.time=duration;
|
||||
song.setExtraField(Song::OnlineImageUrl, parent->imageUrl.toString());
|
||||
song.setExtraField(Song::OnlineImageCacheName, parent->imageFile);
|
||||
if (!localFile.isEmpty()) {
|
||||
song.setLocalPath(localFile);
|
||||
}
|
||||
@@ -411,8 +416,8 @@ const Song & PodcastService::Podcast::coverSong()
|
||||
return song;
|
||||
}
|
||||
|
||||
PodcastService::PodcastService(QObject *p)
|
||||
: ActionModel(p)
|
||||
PodcastService::PodcastService()
|
||||
: ActionModel(nullptr)
|
||||
, downloadJob(nullptr)
|
||||
, rssUpdateTimer(nullptr)
|
||||
{
|
||||
@@ -438,6 +443,44 @@ QString PodcastService::descr() const
|
||||
return tr("Subscribe to RSS feeds");
|
||||
}
|
||||
|
||||
bool PodcastService::episodeCover(const Song &s, QImage &img, QString &imgFilename) const
|
||||
{
|
||||
if ((s.isFromOnlineService() && s.onlineService()==constName) || isPodcastFile(s.file)) {
|
||||
QString path=s.decodedPath();
|
||||
if (path.isEmpty()) {
|
||||
path=s.file;
|
||||
}
|
||||
for (Podcast *podcast: podcasts) {
|
||||
for (Episode *episode: podcast->episodes) {
|
||||
if (episode->url==path || episode->localFile==path) {
|
||||
imgFilename = podcast->imageFile;
|
||||
img = QImage(imgFilename);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString PodcastService::episodeDescr(const Song &s) const
|
||||
{
|
||||
if ((s.isFromOnlineService() && s.onlineService()==constName) || isPodcastFile(s.file)) {
|
||||
QString path=s.decodedPath();
|
||||
if (path.isEmpty()) {
|
||||
path=s.file;
|
||||
}
|
||||
for (Podcast *podcast: podcasts) {
|
||||
for (Episode *episode: podcast->episodes) {
|
||||
if (episode->url==path || episode->localFile==path) {
|
||||
return episode->descr.replace("<p><br></p>", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
int PodcastService::rowCount(const QModelIndex &index) const
|
||||
{
|
||||
if (index.column()>0) {
|
||||
@@ -1343,6 +1386,7 @@ void PodcastService::currentMpdSong(const Song &s)
|
||||
idx=createIndex(podcasts.indexOf(podcast), 0, (void *)podcast);
|
||||
emit dataChanged(idx, idx);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,13 +113,17 @@ public:
|
||||
|
||||
static const QLatin1String constName;
|
||||
|
||||
PodcastService(QObject *p);
|
||||
static PodcastService * self();
|
||||
|
||||
PodcastService();
|
||||
~PodcastService() override { cancelAll(); }
|
||||
|
||||
Song & fixPath(Song &song) const;
|
||||
QString name() const override;
|
||||
QString title() const override;
|
||||
QString descr() const override;
|
||||
bool episodeCover(const Song &s, QImage &img, QString &imgFilename) const;
|
||||
QString episodeDescr(const Song &s) const;
|
||||
int rowCount(const QModelIndex &index = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent) return 1; }
|
||||
bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
@@ -71,30 +71,19 @@ void CoverLabel::updateToolTip(bool isEvent)
|
||||
setToolTip(QString());
|
||||
return;
|
||||
}
|
||||
QString toolTip=QLatin1String("<table>");
|
||||
const QImage &img=CurrentCover::self()->image();
|
||||
|
||||
toolTip+=tr("<tr><td align=\"right\"><b>Artist:</b></td><td>%1</td></tr>").arg(current.artist);
|
||||
if (current.artist!=current.albumArtist()) {
|
||||
toolTip+=tr("<tr><td align=\"right\"><b>Album artist:</b></td><td>%1</td></tr>").arg(current.albumArtist());
|
||||
const QImage &img=CurrentCover::self()->image();
|
||||
if (img.isNull()) {
|
||||
return;
|
||||
}
|
||||
if (!current.composer().isEmpty()) {
|
||||
toolTip+=tr("<tr><td align=\"right\"><b>Composer:</b></td><td>%1</td></tr>").arg(current.composer());
|
||||
}
|
||||
if (!current.performer().isEmpty() && current.performer()!=current.albumArtist()) {
|
||||
toolTip+=tr("<tr><td align=\"right\"><b>Performer:</b></td><td>%1</td></tr>").arg(current.performer());
|
||||
}
|
||||
toolTip+=tr("<tr><td align=\"right\"><b>Album:</b></td><td>%1</td></tr>").arg(current.albumName());
|
||||
toolTip+=tr("<tr><td align=\"right\"><b>Year:</b></td><td>%3</td></tr>").arg(QString::number(current.year));
|
||||
toolTip+="</table>";
|
||||
if (!img.isNull()) {
|
||||
if (img.size().width()>Covers::constMaxSize.width() || img.size().height()>Covers::constMaxSize.height()) {
|
||||
toolTip+=QString("<br/>%1").arg(View::encode(img.scaled(Covers::constMaxSize, Qt::KeepAspectRatio, Qt::SmoothTransformation)));
|
||||
} else if (CurrentCover::self()->fileName().isEmpty() || !QFile::exists(CurrentCover::self()->fileName())) {
|
||||
toolTip+=QString("<br/>%1").arg(View::encode(img));
|
||||
} else {
|
||||
toolTip+=QString("<br/><img src=\"%1\"/>").arg(CurrentCover::self()->fileName());
|
||||
}
|
||||
|
||||
QString toolTip;
|
||||
if (img.size().width()>Covers::constMaxSize.width() || img.size().height()>Covers::constMaxSize.height()) {
|
||||
toolTip=QString("<br/>%1").arg(View::encode(img.scaled(Covers::constMaxSize, Qt::KeepAspectRatio, Qt::SmoothTransformation)));
|
||||
} else if (CurrentCover::self()->fileName().isEmpty() || !QFile::exists(CurrentCover::self()->fileName())) {
|
||||
toolTip=QString("<br/>%1").arg(View::encode(img));
|
||||
} else {
|
||||
toolTip=QString("<br/><img src=\"%1\"/>").arg(CurrentCover::self()->fileName());
|
||||
}
|
||||
setToolTip(toolTip);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user