1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-03-21 08:19:42 +01:00

Support copying and parsing station and automatic playlist tomahawk:// links

This commit is contained in:
Leo Franchi 2011-05-22 18:43:06 -04:00
parent 6b877e3364
commit d1ee642c12
5 changed files with 172 additions and 8 deletions

View File

@ -84,6 +84,48 @@ GlobalActionManager::openLinkFromQuery( const Tomahawk::query_ptr& query ) const
return link;
}
void
GlobalActionManager::copyPlaylistToClipboard( const Tomahawk::dynplaylist_ptr& playlist )
{
QUrl link( "tomahawk://station/create/" );
if( playlist->generator()->type() != "echonest" ) {
qDebug() << "Only echonest generators are supported";
return;
}
link.addEncodedQueryItem( "type", "echonest" );
link.addQueryItem( "title", playlist->title() );
link.addQueryItem( "plmode", QString::number( static_cast<int>( playlist->mode() ) ) );
QList< Tomahawk::dyncontrol_ptr > controls = playlist->generator()->controls();
foreach( const Tomahawk::dyncontrol_ptr& c, controls ) {
if( c->selectedType() == "Artist" ) {
if( c->match().toInt() == Echonest::DynamicPlaylist::ArtistType )
link.addQueryItem( "artist_limit", c->input() );
else
link.addQueryItem( "artist", c->input() );
} else if( c->selectedType() == "Artist Description" ) {
link.addQueryItem( "description", c->input() );
} else {
QString name = c->selectedType().toLower().replace( " ", "_" );
Echonest::DynamicPlaylist::PlaylistParam p = static_cast< Echonest::DynamicPlaylist::PlaylistParam >( c->match().toInt() );
// if it is a max, set that too
if( p == Echonest::DynamicPlaylist::MaxTempo || p == Echonest::DynamicPlaylist::MaxDuration || p == Echonest::DynamicPlaylist::MaxLoudness
|| p == Echonest::DynamicPlaylist::MaxDanceability || p == Echonest::DynamicPlaylist::MaxEnergy || p == Echonest::DynamicPlaylist::ArtistMaxFamiliarity
|| p == Echonest::DynamicPlaylist::ArtistMaxHotttnesss || p == Echonest::DynamicPlaylist::SongMaxHotttnesss || p == Echonest::DynamicPlaylist::ArtistMaxLatitude
|| p == Echonest::DynamicPlaylist::ArtistMaxLongitude )
name += "_max";
link.addQueryItem( name, c->input() );
}
}
QClipboard* cb = QApplication::clipboard();
cb->setText( link.toEncoded() );
}
void
GlobalActionManager::copyToClipboard( const Tomahawk::query_ptr& query ) const
{
@ -323,7 +365,12 @@ GlobalActionManager::handleStationCommand( const QUrl& url )
}
QString title = url.queryItemValue( "title" );
QString type = url.queryItemValue( "type" );
Tomahawk::dynplaylist_ptr pl = Tomahawk::DynamicPlaylist::create( SourceList::instance()->getLocal(), uuid(), title, QString(), QString(), Tomahawk::OnDemand, false, type );
Tomahawk::GeneratorMode m = Tomahawk::OnDemand;
if( url.hasQueryItem( "plmode" ) && url.queryItemValue( "plmode" ).toInt() == 1 )
m = Tomahawk::Static;
Tomahawk::dynplaylist_ptr pl = Tomahawk::DynamicPlaylist::create( SourceList::instance()->getLocal(), uuid(), title, QString(), QString(), m, false, type );
pl->setMode( m );
QList< Tomahawk::dyncontrol_ptr > controls;
QPair< QString, QString > param;
foreach( param, url.queryItems() ) {
@ -332,14 +379,98 @@ GlobalActionManager::handleStationCommand( const QUrl& url )
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistRadioType ) );
controls << c;
} /*else if( param.first == "hotttnesss" ) { TODO
} else if( param.first == "artist_limit" ) {
Tomahawk::dyncontrol_ptr c = pl->generator()->createControl( "Artist" );
c->setInput( param.second );
c->setMatch( 0 );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistType ) );
controls << c;
} */
} else if( param.first == "description" ) {
Tomahawk::dyncontrol_ptr c = pl->generator()->createControl( "Artist Description" );
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistDescriptionType ) );
controls << c;
} else if( param.first == "variety" ) {
Tomahawk::dyncontrol_ptr c = pl->generator()->createControl( "Variety" );
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Variety ) );
controls << c;
} else if( param.first.startsWith( "tempo" ) ) {
Tomahawk::dyncontrol_ptr c = pl->generator()->createControl( "Tempo" );
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinTempo + extra ) );
controls << c;
} else if( param.first.startsWith( "duration" ) ) {
Tomahawk::dyncontrol_ptr c = pl->generator()->createControl( "Duration" );
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinDuration + extra ) );
controls << c;
} else if( param.first.startsWith( "loudness" ) ) {
Tomahawk::dyncontrol_ptr c = pl->generator()->createControl( "Loudness" );
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinLoudness + extra ) );
controls << c;
} else if( param.first.startsWith( "danceability" ) ) {
Tomahawk::dyncontrol_ptr c = pl->generator()->createControl( "Danceability" );
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinDanceability + extra ) );
controls << c;
} else if( param.first.startsWith( "energy" ) ) {
Tomahawk::dyncontrol_ptr c = pl->generator()->createControl( "Energy" );
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinEnergy + extra ) );
controls << c;
} else if( param.first.startsWith( "artist_familiarity" ) ) {
Tomahawk::dyncontrol_ptr c = pl->generator()->createControl( "Artist Familiarity" );
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinFamiliarity + extra ) );
controls << c;
} else if( param.first.startsWith( "artist_hotttnesss" ) ) {
Tomahawk::dyncontrol_ptr c = pl->generator()->createControl( "Artist Hotttnesss" );
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinFamiliarity + extra ) );
controls << c;
} else if( param.first.startsWith( "song_hotttnesss" ) ) {
Tomahawk::dyncontrol_ptr c = pl->generator()->createControl( "Song Hotttnesss" );
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::SongMinHotttnesss + extra ) );
controls << c;
} else if( param.first.startsWith( "longitude" ) ) {
Tomahawk::dyncontrol_ptr c = pl->generator()->createControl( "Longitude" );
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinLongitude + extra ) );
controls << c;
} else if( param.first.startsWith( "latitude" ) ) {
Tomahawk::dyncontrol_ptr c = pl->generator()->createControl( "Latitude" );
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinLatitude + extra ) );
controls << c;
} else if( param.first == "key" ) {
Tomahawk::dyncontrol_ptr c = pl->generator()->createControl( "Key" );
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Key ) );
controls << c;
} else if( param.first == "mode" ) {
Tomahawk::dyncontrol_ptr c = pl->generator()->createControl( "Mode" );
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Mode ) );
controls << c;
}
}
pl->createNewRevision( uuid(), pl->currentrevision(), type, controls );
if( m == Tomahawk::OnDemand )
pl->createNewRevision( uuid(), pl->currentrevision(), type, controls );
else
pl->createNewRevision( uuid(), pl->currentrevision(), type, controls, pl->entries() );
return true;
}

View File

@ -21,6 +21,8 @@
#define GLOBALACTIONMANAGER_H
#include "playlist.h"
#include "query.h"
#include "playlist/dynamic/DynamicPlaylist.h"
#include "dllmacro.h"
#include <QObject>
@ -34,7 +36,9 @@ public:
virtual ~GlobalActionManager();
QUrl openLinkFromQuery( const Tomahawk::query_ptr& query ) const;
void copyToClipboard( const Tomahawk::query_ptr& query ) const;
void copyPlaylistToClipboard( const Tomahawk::dynplaylist_ptr& playlist );
public slots:
bool parseTomahawkLink( const QString& link );

View File

@ -111,7 +111,6 @@ Tomahawk::EchonestControl::summary() const
void
Tomahawk::EchonestControl::setInput(const QString& input)
{
// TODO generate widgets
m_data.second = input;
updateWidgetsFromData();
}
@ -119,7 +118,6 @@ Tomahawk::EchonestControl::setInput(const QString& input)
void
Tomahawk::EchonestControl::setMatch(const QString& match)
{
// TODO generate widgets
m_matchData = match;
updateWidgetsFromData();
}
@ -289,7 +287,7 @@ Tomahawk::EchonestControl::updateWidgets()
m_match = QWeakPointer< QWidget >( match );
m_input = QWeakPointer< QWidget >( combo );
} else if( selectedType() == "Sorting" ) {
m_currentType = Echonest::DynamicPlaylist::Key;
m_currentType = Echonest::DynamicPlaylist::Sort;
QComboBox* match = new QComboBox();
match->addItem( tr( "Ascending" ), 0 );

View File

@ -33,6 +33,7 @@
#include <QPainter>
#include <QStyledItemDelegate>
#include <QSize>
#include <globalactionmanager.h>
using namespace Tomahawk;
@ -119,6 +120,7 @@ void
SourceTreeView::setupMenus()
{
m_playlistMenu.clear();
m_roPlaylistMenu.clear();
bool readonly = true;
SourcesModel::RowType type = ( SourcesModel::RowType )model()->data( m_contextMenuIndex, SourcesModel::SourceTreeItemTypeRole ).toInt();
@ -136,14 +138,22 @@ SourceTreeView::setupMenus()
m_loadPlaylistAction = m_playlistMenu.addAction( tr( "&Load Playlist" ) );
m_renamePlaylistAction = m_playlistMenu.addAction( tr( "&Rename Playlist" ) );
m_playlistMenu.addSeparator();
m_copyPlaylistAction = m_playlistMenu.addAction( tr( "&Copy Playlist Link" ) );
m_deletePlaylistAction = m_playlistMenu.addAction( tr( "&Delete %1" ).arg( SourcesModel::rowTypeToString( type ) ) );
m_roPlaylistMenu.addAction( m_copyPlaylistAction );
m_deletePlaylistAction->setEnabled( !readonly );
m_renamePlaylistAction->setEnabled( !readonly );
if ( type == SourcesModel::StaticPlaylist )
m_copyPlaylistAction->setText( tr( "&Export Playlist" ) );
connect( m_loadPlaylistAction, SIGNAL( triggered() ), SLOT( loadPlaylist() ) );
connect( m_renamePlaylistAction, SIGNAL( triggered() ), SLOT( renamePlaylist() ) );
connect( m_deletePlaylistAction, SIGNAL( triggered() ), SLOT( deletePlaylist() ) );
connect( m_copyPlaylistAction, SIGNAL( triggered() ), SLOT( copyPlaylistLink() ) );
}
@ -223,6 +233,22 @@ SourceTreeView::deletePlaylist()
}
}
void
SourceTreeView::copyPlaylistLink()
{
QModelIndex idx = m_contextMenuIndex;
if ( !idx.isValid() )
return;
SourcesModel::RowType type = ( SourcesModel::RowType )model()->data( m_contextMenuIndex, SourcesModel::SourceTreeItemTypeRole ).toInt();
if( type == SourcesModel::AutomaticPlaylist || type == SourcesModel::Station )
{
DynamicPlaylistItem* item = itemFromIndex< DynamicPlaylistItem >( m_contextMenuIndex );
dynplaylist_ptr playlist = item->dynPlaylist();
GlobalActionManager::instance()->copyPlaylistToClipboard( playlist );
}
}
void
SourceTreeView::renamePlaylist()
@ -252,6 +278,8 @@ SourceTreeView::onCustomContextMenu( const QPoint& pos )
PlaylistItem* item = itemFromIndex< PlaylistItem >( m_contextMenuIndex );
if( item->playlist()->author()->isLocal() )
m_playlistMenu.exec( mapToGlobal( pos ) );
else if( model()->data( m_contextMenuIndex, SourcesModel::SourceTreeItemTypeRole ) != SourcesModel::StaticPlaylist )
m_roPlaylistMenu.exec( mapToGlobal( pos ) );
}
}

View File

@ -53,6 +53,7 @@ private slots:
void loadPlaylist();
void deletePlaylist();
void copyPlaylistLink();
void onCustomContextMenu( const QPoint& pos );
protected:
@ -77,9 +78,11 @@ private:
QModelIndex m_contextMenuIndex;
QMenu m_playlistMenu;
QMenu m_roPlaylistMenu;
QAction* m_loadPlaylistAction;
QAction* m_renamePlaylistAction;
QAction* m_deletePlaylistAction;
QAction* m_copyPlaylistAction;
bool m_dragging;
QRect m_dropRect;