1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-03-20 07:49:42 +01:00

Create copyable artist and album page links

This commit is contained in:
Leo Franchi 2012-06-17 00:09:03 +02:00
parent b1b9ee46db
commit 89ab3344d4
11 changed files with 187 additions and 30 deletions

View File

@ -97,6 +97,48 @@ GlobalActionManager::openLinkFromQuery( const query_ptr& query ) const
}
QUrl
GlobalActionManager::copyOpenLink( const query_ptr& query ) const
{
const QUrl link = openLinkFromQuery( query );
QClipboard* cb = QApplication::clipboard();
QByteArray data = link.toEncoded();
data.replace( "'", "%27" ); // QUrl doesn't encode ', which it doesn't have to. Some apps don't like ' though, and want %27. Both are valid.
cb->setText( data );
return link;
}
QUrl
GlobalActionManager::copyOpenLink( const artist_ptr& artist ) const
{
const QUrl link( QString( "%1/artist/%2" ).arg( hostname() ).arg( artist->name() ) );
QClipboard* cb = QApplication::clipboard();
QByteArray data = link.toEncoded();
data.replace( "'", "%27" ); // QUrl doesn't encode ', which it doesn't have to. Some apps don't like ' though, and want %27. Both are valid.
cb->setText( data );
return link;
}
QUrl
GlobalActionManager::copyOpenLink( const album_ptr& album ) const
{
const QUrl link( QString( "%1/album/%2/%3" ).arg( hostname() ).arg( album->artist().isNull() ? QString() : album->artist()->name() ).arg( album->name()) );
QClipboard* cb = QApplication::clipboard();
QByteArray data = link.toEncoded();
data.replace( "'", "%27" ); // QUrl doesn't encode ', which it doesn't have to. Some apps don't like ' though, and want %27. Both are valid.
cb->setText( data );
return link;
}
QUrl
GlobalActionManager::openLink( const QString& title, const QString& artist, const QString& album ) const
{

View File

@ -43,6 +43,11 @@ public:
virtual ~GlobalActionManager();
QUrl openLinkFromQuery( const Tomahawk::query_ptr& query ) const;
QUrl copyOpenLink( const Tomahawk::artist_ptr& artist ) const;
QUrl copyOpenLink( const Tomahawk::album_ptr& album ) const;
QUrl copyOpenLink( const Tomahawk::query_ptr& query ) const;
QUrl openLink( const QString& title, const QString& artist, const QString& album ) const;
public slots:

View File

@ -55,6 +55,8 @@ public:
AlbumInfoWidget( const Tomahawk::album_ptr& album, QWidget* parent = 0 );
~AlbumInfoWidget();
Tomahawk::album_ptr album() const { return m_album; }
virtual QWidget* widget() { return this; }
virtual Tomahawk::playlistinterface_ptr playlistInterface() const;

View File

@ -66,6 +66,8 @@ public:
*/
void load( const Tomahawk::artist_ptr& artist );
Tomahawk::artist_ptr artist() const { return m_artist; }
virtual QWidget* widget() { return this; }
virtual Tomahawk::playlistinterface_ptr playlistInterface() const;

View File

@ -54,6 +54,8 @@ public:
TrackInfoWidget( const Tomahawk::query_ptr& query, QWidget* parent = 0 );
~TrackInfoWidget();
Tomahawk::query_ptr query() const { return m_query; }
virtual QWidget* widget() { return this; }
virtual Tomahawk::playlistinterface_ptr playlistInterface() const;

View File

@ -568,6 +568,8 @@ SourceTreeView::onCustomContextMenu( const QPoint& pos )
setupMenus();
const QList< QAction* > customActions = model()->data( m_contextMenuIndex, SourcesModel::CustomActionRole ).value< QList< QAction* > >();
if ( model()->data( m_contextMenuIndex, SourcesModel::SourceTreeItemTypeRole ) == SourcesModel::StaticPlaylist ||
model()->data( m_contextMenuIndex, SourcesModel::SourceTreeItemTypeRole ) == SourcesModel::AutomaticPlaylist ||
model()->data( m_contextMenuIndex, SourcesModel::SourceTreeItemTypeRole ) == SourcesModel::Station )
@ -586,6 +588,12 @@ SourceTreeView::onCustomContextMenu( const QPoint& pos )
else if ( !item->source().isNull() )
m_privacyMenu.exec( mapToGlobal( pos ) );
}
else if ( !customActions.isEmpty() )
{
QMenu customMenu;
customMenu.addActions( customActions );
customMenu.exec( mapToGlobal( pos ) );
}
}

View File

@ -107,39 +107,43 @@ SourcesModel::data( const QModelIndex& index, int role ) const
switch ( role )
{
case Qt::SizeHintRole:
return QSize( 0, 18 );
case SourceTreeItemRole:
return QVariant::fromValue< SourceTreeItem* >( item );
case SourceTreeItemTypeRole:
return item->type();
case Qt::DisplayRole:
case Qt::EditRole:
return item->text();
case Qt::DecorationRole:
return item->icon();
case SourcesModel::SortRole:
return item->peerSortValue();
case SourcesModel::IDRole:
return item->IDValue();
case SourcesModel::LatchedOnRole:
case Qt::SizeHintRole:
return QSize( 0, 18 );
case SourceTreeItemRole:
return QVariant::fromValue< SourceTreeItem* >( item );
case SourceTreeItemTypeRole:
return item->type();
case Qt::DisplayRole:
case Qt::EditRole:
return item->text();
case Qt::DecorationRole:
return item->icon();
case SourcesModel::SortRole:
return item->peerSortValue();
case SourcesModel::IDRole:
return item->IDValue();
case SourcesModel::LatchedOnRole:
{
if ( item->type() == Collection )
{
if ( item->type() == Collection )
{
SourceItem* cItem = qobject_cast< SourceItem* >( item );
return cItem->localLatchedOn();
}
return false;
SourceItem* cItem = qobject_cast< SourceItem* >( item );
return cItem->localLatchedOn();
}
case SourcesModel::LatchedRealtimeRole:
return false;
}
case SourcesModel::LatchedRealtimeRole:
{
if ( item->type() == Collection )
{
if ( item->type() == Collection )
{
SourceItem* cItem = qobject_cast< SourceItem* >( item );
return cItem->localLatchMode() == Tomahawk::PlaylistModes::RealTime;
}
return false;
SourceItem* cItem = qobject_cast< SourceItem* >( item );
return cItem->localLatchMode() == Tomahawk::PlaylistModes::RealTime;
}
return false;
}
case SourcesModel::CustomActionRole:
{
return QVariant::fromValue< QList< QAction* > >( item->customActions() );
}
case Qt::ToolTipRole:
if ( !item->tooltip().isEmpty() )
return item->tooltip();

View File

@ -28,6 +28,9 @@
#include "Typedefs.h"
#include "Source.h"
#include <QList>
#include <QAction>
class QMimeData;
class SourceTreeItem;
@ -72,7 +75,8 @@ public:
SortRole = Qt::UserRole + 12,
IDRole = Qt::UserRole + 13,
LatchedOnRole = Qt::UserRole + 14,
LatchedRealtimeRole = Qt::UserRole + 15
LatchedRealtimeRole = Qt::UserRole + 15,
CustomActionRole = Qt::UserRole + 16 // QList< QAction* >
};
SourcesModel( QObject* parent = 0 );
@ -149,4 +153,6 @@ private:
Tomahawk::ViewPage* m_viewPageDelayedCacheItem;
};
Q_DECLARE_METATYPE( QList< QAction* > )
#endif // SOURCESMODEL_H

View File

@ -70,6 +70,7 @@ public:
virtual void setDropType( DropType type ) { m_dropType = type; }
virtual DropType dropType() const { return m_dropType; }
virtual bool isBeingPlayed() const { return false; }
virtual QList< QAction* > customActions() const { return QList< QAction* >(); }
/// don't call me unless you are a sourcetreeitem. i prefer this to making everyone a friend
void beginRowsAdded( int from, int to ) { emit beginChildRowsAdded( from, to ); }

View File

@ -17,11 +17,24 @@
*/
#include "TemporaryPageItem.h"
#include "GlobalActionManager.h"
#include "ViewManager.h"
#include "widgets/infowidgets/AlbumInfoWidget.h"
#include "widgets/infowidgets/ArtistInfoWidget.h"
#include "widgets/infowidgets/TrackInfoWidget.h"
#include "widgets/SearchWidget.h"
#include "utils/Closure.h"
#include <QAction>
namespace {
enum LinkType {
ArtistLink,
AlbumLink,
TrackLink
};
}
using namespace Tomahawk;
@ -31,14 +44,39 @@ TemporaryPageItem::TemporaryPageItem ( SourcesModel* mdl, SourceTreeItem* parent
, m_icon( QIcon( RESPATH "images/playlist-icon.png" ) )
, m_sortValue( sortValue )
{
QAction* action = 0;
if ( dynamic_cast< ArtistInfoWidget* >( page ) )
{
action = new QAction( tr( "Copy Artist Link" ), this );
action->setProperty( "linkType", (int)ArtistLink );
m_icon = QIcon( RESPATH "images/artist-icon.png" );
}
else if ( dynamic_cast< AlbumInfoWidget* >( page ) )
{
action = new QAction( tr( "Copy Album Link" ), this );
action->setProperty( "linkType", (int)AlbumLink );
m_icon = QIcon( RESPATH "images/album-icon.png" );
}
else if ( dynamic_cast< TrackInfoWidget* >( page ) )
{
action = new QAction( tr( "Copy Track Link" ), this );
action->setProperty( "linkType", (int)TrackLink );
m_icon = QIcon( RESPATH "images/track-icon-sidebar.png" );
}
else if ( dynamic_cast< SearchWidget* >( page ) )
{
m_icon = QIcon( RESPATH "images/search-icon.png" );
}
if ( action )
{
m_customActions << action;
NewClosure( action, SIGNAL( triggered() ), this, SLOT( linkActionTriggered( QAction* ) ), action );
}
model()->linkSourceItemToPage( this, page );
}
@ -95,3 +133,41 @@ TemporaryPageItem::removeFromList()
deleteLater();
}
void
TemporaryPageItem::linkActionTriggered( QAction* action )
{
Q_ASSERT( action );
if ( !action )
return;
const LinkType type = (LinkType)action->property( "linkType" ).toInt();
switch( type )
{
case ArtistLink:
{
ArtistInfoWidget* aPage = dynamic_cast< ArtistInfoWidget* >( m_page );
Q_ASSERT( aPage );
GlobalActionManager::instance()->copyOpenLink( aPage->artist() );
break;
}
case AlbumLink:
{
AlbumInfoWidget* aPage = dynamic_cast< AlbumInfoWidget* >( m_page );
Q_ASSERT( aPage );
GlobalActionManager::instance()->copyOpenLink( aPage->album() );
break;
}
case TrackLink:
{
TrackInfoWidget* tPage = dynamic_cast< TrackInfoWidget* >( m_page );
Q_ASSERT( tPage );
GlobalActionManager::instance()->copyOpenLink( tPage->query() );
break;
}
}
}

View File

@ -22,6 +22,8 @@
#include "items/SourceTreeItem.h"
#include "ViewPage.h"
class QAction;
class TemporaryPageItem : public SourceTreeItem
{
Q_OBJECT
@ -34,6 +36,7 @@ public:
virtual QIcon icon() const;
virtual int peerSortValue() const;
virtual int IDValue() const;
virtual QList< QAction* > customActions() const { return m_customActions; }
Tomahawk::ViewPage* page() const { return m_page; }
virtual bool isBeingPlayed() const { return m_page->isBeingPlayed(); }
@ -44,10 +47,16 @@ public slots:
signals:
bool removed();
private slots:
void linkActionTriggered( QAction* );
private:
Tomahawk::ViewPage* m_page;
QIcon m_icon;
int m_sortValue;
QList< QAction* > m_customActions;
};
Q_DECLARE_METATYPE( QAction* )
#endif // TEMPORARYPAGEITEM_H