mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-01 11:50:37 +02:00
Add album and tracks view to script collections
This commit is contained in:
@@ -624,6 +624,14 @@ Tomahawk.PluginManager = {
|
||||
|
||||
resolve: [],
|
||||
invokeSync: function (requestId, objectId, methodName, params) {
|
||||
if (!Tomahawk.resolver.instance.apiVersion || Tomahawk.resolver.instance.apiVersion < 0.9) {
|
||||
if (methodName === 'artistAlbums') {
|
||||
methodName = 'albums';
|
||||
} else if ( methodName === 'albumTracks' ) {
|
||||
methodName = 'tracks';
|
||||
}
|
||||
}
|
||||
|
||||
var pluginManager = this;
|
||||
if (!this.objects[objectId]) {
|
||||
Tomahawk.log("Object not found! objectId: " + objectId + " methodName: " + methodName);
|
||||
@@ -694,6 +702,15 @@ Tomahawk.ConfigTestResultType = {
|
||||
};
|
||||
|
||||
|
||||
Tomahawk.Collection = {
|
||||
BrowseCapability: {
|
||||
Artists: 1,
|
||||
Albums: 2,
|
||||
Tracks: 4
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Legacy compability for 0.8 and before
|
||||
Tomahawk.reportCapabilities = function (capabilities) {
|
||||
if (capabilities & TomahawkResolverCapability.Browsable) {
|
||||
|
@@ -67,6 +67,13 @@ Collection::weakRef() const
|
||||
}
|
||||
|
||||
|
||||
QSet< Collection::BrowseCapability >
|
||||
Collection::browseCapabilities() const
|
||||
{
|
||||
return m_browseCapabilities;
|
||||
}
|
||||
|
||||
|
||||
const QString
|
||||
Collection::name() const
|
||||
{
|
||||
|
@@ -27,10 +27,6 @@
|
||||
#ifndef TOMAHAWK_COLLECTION_H
|
||||
#define TOMAHAWK_COLLECTION_H
|
||||
|
||||
#include <QHash>
|
||||
#include <QList>
|
||||
#include <QSharedPointer>
|
||||
|
||||
#include "Typedefs.h"
|
||||
#include "Playlist.h"
|
||||
#include "playlist/dynamic/DynamicPlaylist.h"
|
||||
@@ -41,6 +37,12 @@
|
||||
|
||||
#include "DllMacro.h"
|
||||
|
||||
#include <QHash>
|
||||
#include <QList>
|
||||
#include <QSharedPointer>
|
||||
#include <QSet>
|
||||
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
@@ -55,6 +57,16 @@ public:
|
||||
void setWeakRef( const collection_wptr& weakRef );
|
||||
const collection_wptr weakRef() const;
|
||||
|
||||
enum BrowseCapability
|
||||
{
|
||||
CapabilityBrowseNull = 0x0,
|
||||
CapabilityBrowseArtists = 0x1,
|
||||
CapabilityBrowseAlbums = 0x2,
|
||||
CapabilityBrowseTracks = 0x4
|
||||
};
|
||||
|
||||
QSet< BrowseCapability > browseCapabilities() const;
|
||||
|
||||
enum BackendType
|
||||
{
|
||||
NullCollectionType = 0,
|
||||
@@ -127,6 +139,7 @@ public slots:
|
||||
protected:
|
||||
QString m_name;
|
||||
unsigned int m_lastmodified; // unix time of last change to collection
|
||||
QSet< BrowseCapability > m_browseCapabilities;
|
||||
|
||||
private slots:
|
||||
void onSynced();
|
||||
|
@@ -229,6 +229,27 @@ ScriptCollection::parseMetaData( const QVariantMap& metadata )
|
||||
|
||||
fetchIcon( metadata.value( "iconurl" ).toString() );
|
||||
}
|
||||
|
||||
if ( metadata.contains( "capabilities" ) )
|
||||
{
|
||||
QVariantList list = metadata[ "capabilities" ].toList();
|
||||
|
||||
foreach( const QVariant& type, list )
|
||||
{
|
||||
bool ok;
|
||||
int intType = type.toInt( &ok );
|
||||
if ( ok )
|
||||
{
|
||||
tLog() << intType;
|
||||
m_browseCapabilities << static_cast< BrowseCapability >( intType );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_browseCapabilities << CapabilityBrowseArtists;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include "PlaylistEntry.h"
|
||||
#include "ScriptCollection.h"
|
||||
#include "ScriptJob.h"
|
||||
#include "ScriptCommand_AllArtists.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
@@ -70,16 +71,18 @@ ScriptCommand_AllAlbums::exec()
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !m_artist )
|
||||
ScriptJob* job;
|
||||
if ( m_artist )
|
||||
{
|
||||
reportFailure();
|
||||
return;
|
||||
QVariantMap arguments;
|
||||
arguments[ "artist" ] = m_artist->name();
|
||||
job = collection->scriptObject()->invoke( "artistAlbums", arguments );
|
||||
}
|
||||
else
|
||||
{
|
||||
job = collection->scriptObject()->invoke( "albums" );
|
||||
}
|
||||
|
||||
QVariantMap arguments;
|
||||
arguments[ "artist" ] = m_artist->name();
|
||||
|
||||
ScriptJob* job = collection->scriptObject()->invoke( "albums", arguments );
|
||||
connect( job, SIGNAL( done( QVariantMap ) ), SLOT( onAlbumsJobDone( QVariantMap ) ), Qt::QueuedConnection );
|
||||
job->start();
|
||||
}
|
||||
@@ -108,8 +111,17 @@ ScriptCommand_AllAlbums::onAlbumsJobDone(const QVariantMap& result)
|
||||
return;
|
||||
}
|
||||
|
||||
QList< Tomahawk::album_ptr > a = parseAlbumVariantList( m_artist, result[ "albums" ].toList() );
|
||||
QList< Tomahawk::artist_ptr > resultArtists;
|
||||
if ( result["artists"].toList().length() > 0 )
|
||||
{
|
||||
resultArtists = ScriptCommand_AllArtists::parseArtistVariantList( result[ "artists" ].toList() );
|
||||
}
|
||||
else
|
||||
{
|
||||
resultArtists << m_artist;
|
||||
}
|
||||
|
||||
QList< Tomahawk::album_ptr > a = parseAlbumVariantList( resultArtists, result[ "albums" ].toList() );
|
||||
if ( m_filter.isEmpty() )
|
||||
emit albums( a );
|
||||
else
|
||||
@@ -130,19 +142,34 @@ ScriptCommand_AllAlbums::onAlbumsJobDone(const QVariantMap& result)
|
||||
|
||||
|
||||
QList< Tomahawk::album_ptr >
|
||||
ScriptCommand_AllAlbums::parseAlbumVariantList( const Tomahawk::artist_ptr& artist, const QVariantList& reslist )
|
||||
ScriptCommand_AllAlbums::parseAlbumVariantList( const QList< Tomahawk::artist_ptr >& artists, const QVariantList& reslist )
|
||||
{
|
||||
QList< Tomahawk::album_ptr > results;
|
||||
|
||||
foreach( const QVariant& rv, reslist )
|
||||
if (artists.length() != 1 && reslist.length() != artists.length())
|
||||
{
|
||||
const QString val = rv.toString();
|
||||
tLog() << "artists" << artists.length();
|
||||
tLog() << "albums" << reslist.length();
|
||||
Q_ASSERT(false);
|
||||
tLog() << "Got invalid collection albums response where artists and albums don't match";
|
||||
return results;
|
||||
}
|
||||
|
||||
bool useArtistList = ( artists.length() > 1 );
|
||||
for( int i=0; i<reslist.length(); i++ )
|
||||
{
|
||||
const QString val = reslist[ i ].toString();
|
||||
if ( val.trimmed().isEmpty() )
|
||||
continue;
|
||||
|
||||
Tomahawk::album_ptr ap = Tomahawk::Album::get( artist, val, false );
|
||||
|
||||
results << ap;
|
||||
if ( useArtistList )
|
||||
{
|
||||
results << Tomahawk::Album::get( artists[ i ], val, false );
|
||||
}
|
||||
else
|
||||
{
|
||||
results << Tomahawk::Album::get( artists[ 0 ], val, false );
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
|
@@ -52,7 +52,7 @@ private slots:
|
||||
void onAlbumsJobDone( const QVariantMap& result );
|
||||
|
||||
private:
|
||||
static QList< Tomahawk::album_ptr > parseAlbumVariantList( const Tomahawk::artist_ptr& artist,
|
||||
static QList< Tomahawk::album_ptr > parseAlbumVariantList( const QList< Tomahawk::artist_ptr >& artists,
|
||||
const QVariantList& reslist );
|
||||
Tomahawk::collection_ptr m_collection;
|
||||
Tomahawk::artist_ptr m_artist;
|
||||
|
@@ -29,7 +29,9 @@ namespace Tomahawk
|
||||
|
||||
class ScriptCommand_AllArtists : public ScriptCommand, public Tomahawk::ArtistsRequest
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
friend class ScriptCommand_AllAlbums;
|
||||
|
||||
public:
|
||||
explicit ScriptCommand_AllArtists( const Tomahawk::collection_ptr& collection,
|
||||
QObject* parent = nullptr );
|
||||
|
@@ -64,17 +64,21 @@ ScriptCommand_AllTracks::exec()
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_album.isNull() )
|
||||
ScriptJob* job;
|
||||
if( m_album )
|
||||
{
|
||||
reportFailure();
|
||||
return;
|
||||
QVariantMap arguments;
|
||||
arguments[ "artist" ] = m_album->artist()->name();
|
||||
arguments[ "album" ] = m_album->name();
|
||||
|
||||
job = collection->scriptObject()->invoke( "albumTracks", arguments );
|
||||
}
|
||||
else
|
||||
{
|
||||
job = collection->scriptObject()->invoke( "tracks" );
|
||||
}
|
||||
|
||||
QVariantMap arguments;
|
||||
arguments[ "artist" ] = m_album->artist()->name();
|
||||
arguments[ "album" ] = m_album->name();
|
||||
|
||||
ScriptJob* job = collection->scriptObject()->invoke( "tracks", arguments );
|
||||
connect( job, SIGNAL( done( QVariantMap ) ), SLOT( onTracksJobDone( QVariantMap ) ), Qt::QueuedConnection );
|
||||
job->start();
|
||||
}
|
||||
|
@@ -88,9 +88,15 @@ CollectionViewPage::CollectionViewPage( const Tomahawk::collection_ptr& collecti
|
||||
m_header->ui->anchor1Label->setText( tr( "Artists" ) );
|
||||
m_header->ui->anchor2Label->setText( tr( "Albums" ) );
|
||||
m_header->ui->anchor3Label->setText( tr( "Songs" ) );
|
||||
m_header->ui->anchor1Label->show();
|
||||
m_header->ui->anchor2Label->show();
|
||||
m_header->ui->anchor3Label->show();
|
||||
|
||||
if( collection->browseCapabilities().contains( Collection::CapabilityBrowseArtists ) )
|
||||
m_header->ui->anchor1Label->show();
|
||||
|
||||
if( collection->browseCapabilities().contains( Collection::CapabilityBrowseAlbums ) )
|
||||
m_header->ui->anchor2Label->show();
|
||||
|
||||
if( collection->browseCapabilities().contains( Collection::CapabilityBrowseTracks ) )
|
||||
m_header->ui->anchor3Label->show();
|
||||
|
||||
const float lowOpacity = 0.8;
|
||||
m_header->ui->anchor1Label->setOpacity( 1 );
|
||||
@@ -335,7 +341,33 @@ CollectionViewPage::restoreViewMode()
|
||||
m_mode = static_cast< CollectionViewPageMode >( modeNumber );
|
||||
TomahawkSettings::instance()->endGroup();
|
||||
|
||||
setCurrentMode( (CollectionViewPageMode)modeNumber );
|
||||
// try to set a supported mode otherwise fall back to artists view
|
||||
CollectionViewPageMode mode = (CollectionViewPageMode) modeNumber;
|
||||
if ( mode == CollectionViewPage::Columns && !m_collection->browseCapabilities().contains( Collection::CapabilityBrowseArtists ) )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << 0;
|
||||
if ( m_collection->browseCapabilities().contains( Collection::CapabilityBrowseAlbums ) )
|
||||
setCurrentMode( CollectionViewPage::Albums );
|
||||
else if ( m_collection->browseCapabilities().contains( Collection::CapabilityBrowseTracks ) )
|
||||
setCurrentMode( CollectionViewPage::Columns );
|
||||
}
|
||||
else if ( mode == CollectionViewPage::Albums && !m_collection->browseCapabilities().contains( Collection::CapabilityBrowseAlbums ) )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << 1;
|
||||
if ( m_collection->browseCapabilities().contains( Collection::CapabilityBrowseTracks ) )
|
||||
setCurrentMode( CollectionViewPage::Flat );
|
||||
else
|
||||
setCurrentMode( CollectionViewPage::Columns );
|
||||
} else if ( mode == CollectionViewPage::Flat && !m_collection->browseCapabilities().contains( Collection::CapabilityBrowseTracks ) )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << 2;
|
||||
if ( m_collection->browseCapabilities().contains( Collection::CapabilityBrowseArtists ) )
|
||||
setCurrentMode( CollectionViewPage::Columns );
|
||||
else if ( m_collection->browseCapabilities().contains( Collection::CapabilityBrowseAlbums ) )
|
||||
setCurrentMode( CollectionViewPage::Albums );
|
||||
} else {
|
||||
setCurrentMode( mode );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -386,9 +418,6 @@ CollectionViewPage::onCollectionChanged()
|
||||
}
|
||||
else
|
||||
setEmptyTip( tr( "This collection is empty." ) );
|
||||
|
||||
if ( m_collection.objectCast<ScriptCollection>() )
|
||||
m_trackView->setEmptyTip( tr( "Cloud collections aren't supported in the flat view yet. We will have them covered soon. Switch to another view to navigate them." ) );
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user