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

Merge branch 'mhd'

This commit is contained in:
Leo Franchi 2012-04-27 19:05:05 -04:00
commit 0677db0419
32 changed files with 627 additions and 246 deletions

@ -27,6 +27,8 @@
#include "utils/TomahawkUtils.h" #include "utils/TomahawkUtils.h"
#include "utils/Logger.h" #include "utils/Logger.h"
#include "utils/AnimatedSpinner.h"
#include "utils/Closure.h"
#define CHILD_ACCOUNT_HEIGHT 24 #define CHILD_ACCOUNT_HEIGHT 24
@ -134,9 +136,9 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option,
QFont authorFont = opt.font; QFont authorFont = opt.font;
authorFont.setItalic( true ); authorFont.setItalic( true );
authorFont.setPointSize( authorFont.pointSize() - 1 ); authorFont.setPointSize( authorFont.pointSize() - 1 );
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
authorFont.setPointSize( authorFont.pointSize() - 1 ); authorFont.setPointSize( authorFont.pointSize() - 1 );
#endif #endif
const QFontMetrics authorMetrics( authorFont ); const QFontMetrics authorMetrics( authorFont );
QFont descFont = authorFont; QFont descFont = authorFont;
@ -158,7 +160,22 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option,
QRect checkRect = QRect( leftEdge, checkboxYPos, WRENCH_SIZE, WRENCH_SIZE ); QRect checkRect = QRect( leftEdge, checkboxYPos, WRENCH_SIZE, WRENCH_SIZE );
QStyleOptionViewItemV4 opt2 = opt; QStyleOptionViewItemV4 opt2 = opt;
opt2.rect = checkRect; opt2.rect = checkRect;
drawCheckBox( opt2, painter, opt.widget );
if ( !m_loadingSpinners.contains( index ) )
{
drawCheckBox( opt2, painter, opt.widget );
}
else
{
Q_ASSERT( m_loadingSpinners[ index ] );
if ( m_loadingSpinners[ index ] )
{
const QPixmap pm = m_loadingSpinners[index]->pixmap();
painter->drawPixmap( checkRect, pm );
}
}
leftEdge += WRENCH_SIZE + PADDING / 2; leftEdge += WRENCH_SIZE + PADDING / 2;
// Pixmap // Pixmap
@ -183,6 +200,7 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option,
topt.pos = confRect.topLeft(); topt.pos = confRect.topLeft();
drawConfigWrench( painter, opt, topt ); drawConfigWrench( painter, opt, topt );
m_cachedConfigRects[ index ] = confRect; m_cachedConfigRects[ index ] = confRect;
rightEdge = confRect.left(); rightEdge = confRect.left();
@ -658,4 +676,40 @@ AccountDelegate::checkRectForIndex( const QStyleOptionViewItem& option, const QM
} }
void
AccountDelegate::startInstalling( const QPersistentModelIndex& idx )
{
qDebug() << "START INSTALLING:" << idx.data( Qt::DisplayRole ).toString();
QStyleOptionViewItemV4 opt;
initStyleOption( &opt, idx );
AnimatedSpinner* anim = new AnimatedSpinner( checkRectForIndex( opt, idx ).size(), true );
_detail::Closure* closure = NewClosure( anim, SIGNAL( requestUpdate() ), this, SLOT( doUpdateIndex( const QPersistentModelIndex& ) ), idx );
closure->setAutoDelete( false );
m_loadingSpinners[ idx ] = anim;
update( idx );
}
void
AccountDelegate::doneInstalling ( const QPersistentModelIndex& idx )
{
qDebug() << "STOP INSTALLING:" << idx.data( Qt::DisplayRole ).toString();
Q_ASSERT( m_loadingSpinners.contains( idx ) );
if ( !m_loadingSpinners.contains( idx ) )
return;
delete m_loadingSpinners.take( idx );
update( idx );
}
void
AccountDelegate::doUpdateIndex( const QPersistentModelIndex& idx )
{
emit update( idx );
}

@ -22,6 +22,8 @@
#include <QStyledItemDelegate> #include <QStyledItemDelegate>
#include "accounts/AccountModel.h" #include "accounts/AccountModel.h"
class AnimatedSpinner;
namespace Tomahawk namespace Tomahawk
{ {
namespace Accounts namespace Accounts
@ -38,6 +40,12 @@ public:
virtual void paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; virtual void paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
virtual QSize sizeHint ( const QStyleOptionViewItem& option, const QModelIndex& index ) const; virtual QSize sizeHint ( const QStyleOptionViewItem& option, const QModelIndex& index ) const;
public slots:
void startInstalling( const QPersistentModelIndex& idx );
void doneInstalling ( const QPersistentModelIndex& idx );
void doUpdateIndex( const QPersistentModelIndex& idx );
protected: protected:
virtual bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ); virtual bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index );
@ -64,6 +72,7 @@ private:
mutable QHash< QPersistentModelIndex, QRect > m_cachedStarRects; mutable QHash< QPersistentModelIndex, QRect > m_cachedStarRects;
mutable QHash< QPersistentModelIndex, QRect > m_cachedConfigRects; mutable QHash< QPersistentModelIndex, QRect > m_cachedConfigRects;
mutable QHash< QPersistentModelIndex, QSize > m_sizeHints; mutable QHash< QPersistentModelIndex, QSize > m_sizeHints;
mutable QHash< QPersistentModelIndex, AnimatedSpinner* > m_loadingSpinners;
mutable int m_accountRowHeight; mutable int m_accountRowHeight;
}; };

@ -44,7 +44,7 @@
#include "AccountDelegate.h" #include "AccountDelegate.h"
#include "database/Database.h" #include "database/Database.h"
#include "network/Servent.h" #include "network/Servent.h"
#include "playlist/dynamic/widgets/LoadingSpinner.h" #include "utils/AnimatedSpinner.h"
#include "accounts/AccountModel.h" #include "accounts/AccountModel.h"
#include "accounts/Account.h" #include "accounts/Account.h"
#include "accounts/AccountManager.h" #include "accounts/AccountManager.h"
@ -114,6 +114,8 @@ SettingsDialog::SettingsDialog( QWidget *parent )
m_accountProxy = new AccountModelFilterProxy( m_accountModel ); m_accountProxy = new AccountModelFilterProxy( m_accountModel );
m_accountProxy->setSourceModel( m_accountModel ); m_accountProxy->setSourceModel( m_accountModel );
connect( m_accountProxy, SIGNAL( startInstalling( QPersistentModelIndex ) ), accountDelegate, SLOT( startInstalling(QPersistentModelIndex) ) );
connect( m_accountProxy, SIGNAL( doneInstalling( QPersistentModelIndex ) ), accountDelegate, SLOT( doneInstalling(QPersistentModelIndex) ) );
connect( m_accountProxy, SIGNAL( scrollTo( QModelIndex ) ), this, SLOT( scrollTo( QModelIndex ) ) ); connect( m_accountProxy, SIGNAL( scrollTo( QModelIndex ) ), this, SLOT( scrollTo( QModelIndex ) ) );
ui->accountsView->setModel( m_accountProxy ); ui->accountsView->setModel( m_accountProxy );
@ -130,7 +132,7 @@ SettingsDialog::SettingsDialog( QWidget *parent )
if ( !Servent::instance()->isReady() ) if ( !Servent::instance()->isReady() )
{ {
m_sipSpinner = new LoadingSpinner( ui->accountsView ); m_sipSpinner = new AnimatedSpinner( ui->accountsView );
m_sipSpinner->fadeIn(); m_sipSpinner->fadeIn();
connect( Servent::instance(), SIGNAL( ready() ), this, SLOT( serventReady() ) ); connect( Servent::instance(), SIGNAL( ready() ), this, SLOT( serventReady() ) );

@ -26,7 +26,7 @@
#include "config.h" #include "config.h"
class LoadingSpinner; class AnimatedSpinner;
class QListWidgetItem; class QListWidgetItem;
class Ui_StackedSettingsDialog; class Ui_StackedSettingsDialog;
class SipPlugin; class SipPlugin;
@ -112,7 +112,7 @@ private:
bool m_rejected; bool m_rejected;
Tomahawk::Accounts::AccountModel* m_accountModel; Tomahawk::Accounts::AccountModel* m_accountModel;
Tomahawk::Accounts::AccountModelFilterProxy* m_accountProxy; Tomahawk::Accounts::AccountModelFilterProxy* m_accountProxy;
LoadingSpinner* m_sipSpinner; AnimatedSpinner* m_sipSpinner;
}; };
#endif // SETTINGSDIALOG_H #endif // SETTINGSDIALOG_H

@ -19,7 +19,7 @@
#include "SpotifyAccountConfig.h" #include "SpotifyAccountConfig.h"
#include "SpotifyAccount.h" #include "SpotifyAccount.h"
#include <playlist/dynamic/widgets/LoadingSpinner.h> #include "utils/AnimatedSpinner.h"
#include "ui_SpotifyAccountConfig.h" #include "ui_SpotifyAccountConfig.h"
#include <QListWidget> #include <QListWidget>
@ -44,7 +44,7 @@ SpotifyAccountConfig::SpotifyAccountConfig( SpotifyAccount *account )
connect( m_ui->passwordEdit, SIGNAL( textChanged( QString ) ), this, SLOT( resetLoginButton() ) ); connect( m_ui->passwordEdit, SIGNAL( textChanged( QString ) ), this, SLOT( resetLoginButton() ) );
loadFromConfig(); loadFromConfig();
m_playlistsLoading = new LoadingSpinner( m_ui->playlistList ); m_playlistsLoading = new AnimatedSpinner( m_ui->playlistList );
} }

@ -23,7 +23,7 @@
#include <QVariantMap> #include <QVariantMap>
#include <QTimer> #include <QTimer>
class LoadingSpinner; class AnimatedSpinner;
class QShowEvent; class QShowEvent;
namespace Ui namespace Ui
@ -74,7 +74,7 @@ private slots:
private: private:
Ui::SpotifyConfig* m_ui; Ui::SpotifyConfig* m_ui;
SpotifyAccount* m_account; SpotifyAccount* m_account;
LoadingSpinner* m_playlistsLoading; AnimatedSpinner* m_playlistsLoading;
bool m_loggedInManually; bool m_loggedInManually;
}; };

@ -96,7 +96,6 @@ set( libGuiSources
playlist/dynamic/widgets/MiscControlWidgets.cpp playlist/dynamic/widgets/MiscControlWidgets.cpp
playlist/dynamic/widgets/CollapsibleControls.cpp playlist/dynamic/widgets/CollapsibleControls.cpp
playlist/dynamic/widgets/DynamicSetupWidget.cpp playlist/dynamic/widgets/DynamicSetupWidget.cpp
playlist/dynamic/widgets/LoadingSpinner.cpp
playlist/topbar/TopBar.cpp playlist/topbar/TopBar.cpp
playlist/topbar/ClearButton.cpp playlist/topbar/ClearButton.cpp
@ -123,6 +122,7 @@ set( libGuiSources
utils/Closure.cpp utils/Closure.cpp
utils/PixmapDelegateFader.cpp utils/PixmapDelegateFader.cpp
utils/SmartPointerList.h utils/SmartPointerList.h
utils/AnimatedSpinner.cpp
widgets/AnimatedCounterLabel.cpp widgets/AnimatedCounterLabel.cpp
widgets/CheckDirTree.cpp widgets/CheckDirTree.cpp

@ -2,7 +2,7 @@
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org> Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org> Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
Copyright (C) 2011-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org> Copyright (C) 2011-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
@ -144,6 +144,51 @@ GlobalActionManager::shortenLink( const QUrl& url, const QVariant& callbackObj )
} }
void
GlobalActionManager::getShortLink( const playlist_ptr& pl )
{
QVariantMap m;
m[ "title" ] = pl->title();
m[ "creator" ] = pl->author().isNull() ? "" : pl->author()->friendlyName();
QVariantList tracks;
foreach( const plentry_ptr& pl, pl->entries() )
{
if ( pl->query().isNull() )
continue;
QVariantMap track;
track[ "title" ] = pl->query()->track();
track[ "creator" ] = pl->query()->artist();
track[ "album" ] = pl->query()->album();
tracks << track;
}
m[ "track" ] = tracks;
QVariantMap jspf;
jspf["playlist"] = m;
QJson::Serializer s;
QByteArray msg = s.serialize( jspf );
// No built-in Qt facilities for doing a FORM POST. So we build the payload ourselves...
const QByteArray boundary = "----------------------------2434992cccab";
QByteArray data(QByteArray("--" + boundary + "\r\n"));
data += "Content-Disposition: form-data; name=\"data\"; filename=\"playlist.jspf\"\r\n";
data += "Content-Type: application/octet-stream\r\n\r\n";
data += msg;
data += "\r\n\r\n";
data += "--" + boundary + "--\r\n\r\n";
const QUrl url( QString( "%1/p/").arg( hostname() ) );
QNetworkRequest req( url );
req.setHeader( QNetworkRequest::ContentTypeHeader, QString( "multipart/form-data; boundary=%1" ).arg( QString::fromLatin1( boundary ) ) );
QNetworkReply *reply = TomahawkUtils::nam()->post( req, data );
connect( reply, SIGNAL( finished() ), SLOT( postShortenFinished() ) );
connect( reply, SIGNAL( error( QNetworkReply::NetworkError ) ), SLOT( shortenLinkRequestError( QNetworkReply::NetworkError ) ) );
}
QString QString
GlobalActionManager::copyPlaylistToClipboard( const dynplaylist_ptr& playlist ) GlobalActionManager::copyPlaylistToClipboard( const dynplaylist_ptr& playlist )
{ {
@ -341,18 +386,29 @@ GlobalActionManager::handlePlaylistCommand( const QUrl& url )
if ( parts[ 0 ] == "import" ) if ( parts[ 0 ] == "import" )
{ {
if ( !url.hasQueryItem( "xspf" ) ) if ( !url.hasQueryItem( "xspf" ) && !url.hasQueryItem( "jspf") )
{ {
tDebug() << "No xspf to load..."; tDebug() << "No xspf or jspf to load...";
return false; return false;
} }
QUrl xspf = QUrl::fromUserInput( url.queryItemValue( "xspf" ) ); if ( url.hasQueryItem( "xspf") )
QString title = url.hasQueryItem( "title" ) ? url.queryItemValue( "title" ) : QString(); {
XSPFLoader* l= new XSPFLoader( true, this ); QUrl xspf = QUrl::fromUserInput( url.queryItemValue( "xspf" ) );
l->setOverrideTitle( title ); QString title = url.hasQueryItem( "title" ) ? url.queryItemValue( "title" ) : QString();
l->load( xspf ); XSPFLoader* l= new XSPFLoader( true, this );
connect( l, SIGNAL( ok( Tomahawk::playlist_ptr ) ), this, SLOT( playlistCreatedToShow( Tomahawk::playlist_ptr) ) ); l->setOverrideTitle( title );
l->load( xspf );
connect( l, SIGNAL( ok( Tomahawk::playlist_ptr ) ), this, SLOT( playlistCreatedToShow( Tomahawk::playlist_ptr) ) );
}
else if ( url.hasQueryItem( "jspf" ) )
{
QUrl jspf = QUrl::fromUserInput( url.queryItemValue( "jspf" ) );
QString title = url.hasQueryItem( "title" ) ? url.queryItemValue( "title" ) : QString();
JSPFLoader* l= new JSPFLoader( true, this );
l->setOverrideTitle( title );
l->load( jspf );
connect( l, SIGNAL( ok( Tomahawk::playlist_ptr ) ), this, SLOT( playlistCreatedToShow( Tomahawk::playlist_ptr) ) );
}
} }
else if ( parts [ 0 ] == "new" ) else if ( parts [ 0 ] == "new" )
{ {
@ -1016,7 +1072,7 @@ GlobalActionManager::shortenLinkRequestFinished()
QVariant callbackObj; QVariant callbackObj;
if ( reply->property( "callbackobj" ).isValid() ) if ( reply->property( "callbackobj" ).isValid() )
callbackObj = reply->property( "callbackobj" ); callbackObj = reply->property( "callbackobj" );
// Check for the redirect attribute, as this should be the shortened link // Check for the redirect attribute, as this should be the shortened link
QVariant urlVariant = reply->attribute( QNetworkRequest::RedirectionTargetAttribute ); QVariant urlVariant = reply->attribute( QNetworkRequest::RedirectionTargetAttribute );
@ -1054,6 +1110,25 @@ GlobalActionManager::shortenLinkRequestFinished()
} }
void
GlobalActionManager::postShortenFinished()
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
Q_ASSERT( reply );
const QByteArray raw = reply->readAll();
qDebug() << "GOT REPLYL" << raw;
const QUrl url = QUrl::fromUserInput( raw );
qDebug() << "GOT POSTED SHORT URL:" << url.toString();
QClipboard* cb = QApplication::clipboard();
QByteArray data = url.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 );
reply->deleteLater();
}
void void
GlobalActionManager::shortenLinkRequestError( QNetworkReply::NetworkError error ) GlobalActionManager::shortenLinkRequestError( QNetworkReply::NetworkError error )
{ {

@ -57,6 +57,7 @@ public:
public slots: public slots:
void shortenLink( const QUrl& url, const QVariant &callbackObj = QVariant() ); void shortenLink( const QUrl& url, const QVariant &callbackObj = QVariant() );
void getShortLink( const Tomahawk::playlist_ptr& playlist );
bool parseTomahawkLink( const QString& link ); bool parseTomahawkLink( const QString& link );
void waitingForResolved( bool ); void waitingForResolved( bool );
@ -71,6 +72,7 @@ signals:
private slots: private slots:
void shortenLinkRequestFinished(); void shortenLinkRequestFinished();
void postShortenFinished();
void shortenLinkRequestError( QNetworkReply::NetworkError ); void shortenLinkRequestError( QNetworkReply::NetworkError );
void bookmarkPlaylistCreated( const Tomahawk::playlist_ptr& pl ); void bookmarkPlaylistCreated( const Tomahawk::playlist_ptr& pl );

@ -408,6 +408,42 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion )
setValue( "allaccounts", allAccounts ); setValue( "allaccounts", allAccounts );
endGroup(); endGroup();
} }
else if ( oldVersion == 8 )
{
// Some users got duplicate accounts for some reason, so make them unique if we can
QSet< QString > uniqueFriendlyNames;
beginGroup("accounts");
const QStringList accounts = childGroups();
QStringList allAccounts = value( "allaccounts" ).toStringList();
// qDebug() << "Got accounts to migrate:" << accounts;
foreach ( const QString& account, accounts )
{
if ( !allAccounts.contains( account ) ) // orphan
{
qDebug() << "Found account not in allaccounts list!" << account << "is a dup!";
remove( account );
continue;
}
const QString friendlyName = value( QString( "%1/accountfriendlyname" ).arg( account ) ).toString();
if ( !uniqueFriendlyNames.contains( friendlyName ) )
{
uniqueFriendlyNames.insert( friendlyName );
continue;
}
else
{
// Duplicate..?
qDebug() << "Found duplicate account friendly name:" << account << friendlyName << "is a dup!";
remove( account );
allAccounts.removeAll( account );
}
}
qDebug() << "Ended up with all accounts list:" << allAccounts << "and all accounts:" << childGroups();
setValue( "allaccounts", allAccounts );
endGroup();
}
} }

@ -28,7 +28,7 @@
#include "DllMacro.h" #include "DllMacro.h"
#define TOMAHAWK_SETTINGS_VERSION 8 #define TOMAHAWK_SETTINGS_VERSION 9
/** /**
* Convenience wrapper around QSettings for tomahawk-specific config * Convenience wrapper around QSettings for tomahawk-specific config

@ -266,7 +266,7 @@ void
AccountManager::loadFromConfig() AccountManager::loadFromConfig()
{ {
QStringList accountIds = TomahawkSettings::instance()->accounts(); QStringList accountIds = TomahawkSettings::instance()->accounts();
qDebug() << "LOADING ALL ACCOUNTS" << accountIds;
foreach( const QString& accountId, accountIds ) foreach( const QString& accountId, accountIds )
{ {
QString pluginFactory = factoryFromId( accountId ); QString pluginFactory = factoryFromId( accountId );

@ -29,7 +29,7 @@
using namespace Tomahawk; using namespace Tomahawk;
using namespace Accounts; using namespace Accounts;
#define ACCOUNTMODEL_DEBUG 0 #define ACCOUNTMODEL_DEBUG 1
AccountModel::AccountModel( QObject* parent ) AccountModel::AccountModel( QObject* parent )
: QAbstractListModel( parent ) : QAbstractListModel( parent )
@ -451,6 +451,7 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role
qDebug() << "Kicked off fetch+install, now waiting"; qDebug() << "Kicked off fetch+install, now waiting";
m_waitingForAtticaInstall.insert( resolver.id() ); m_waitingForAtticaInstall.insert( resolver.id() );
emit startInstalling( index );
AtticaManager::instance()->installResolver( resolver ); AtticaManager::instance()->installResolver( resolver );
return true; return true;
} }
@ -571,6 +572,10 @@ AccountModel::accountAdded( Account* account )
AccountManager::instance()->enableAccount( account ); AccountManager::instance()->enableAccount( account );
m_waitingForAtticaInstall.remove( attica->atticaId() ); m_waitingForAtticaInstall.remove( attica->atticaId() );
// find index to emit doneInstalling for
const QModelIndex idx = index( i, 0, QModelIndex() );
emit doneInstalling( idx );
} }
if ( thisIsTheOne ) if ( thisIsTheOne )

@ -94,6 +94,8 @@ signals:
void createAccount( Tomahawk::Accounts::AccountFactory* factory ); void createAccount( Tomahawk::Accounts::AccountFactory* factory );
void scrollTo( const QModelIndex& idx ); void scrollTo( const QModelIndex& idx );
void startInstalling( const QPersistentModelIndex& idx );
void doneInstalling( const QPersistentModelIndex& idx );
private slots: private slots:
void loadData(); void loadData();

@ -36,6 +36,8 @@ void
AccountModelFilterProxy::setSourceModel( QAbstractItemModel* sourceModel ) AccountModelFilterProxy::setSourceModel( QAbstractItemModel* sourceModel )
{ {
connect( sourceModel, SIGNAL( scrollTo( QModelIndex ) ), this, SLOT( onScrollTo( QModelIndex ) ) ); connect( sourceModel, SIGNAL( scrollTo( QModelIndex ) ), this, SLOT( onScrollTo( QModelIndex ) ) );
connect( sourceModel, SIGNAL( startInstalling( QPersistentModelIndex ) ), this, SLOT( onStartInstalling( QPersistentModelIndex ) ) );
connect( sourceModel, SIGNAL( doneInstalling( QPersistentModelIndex ) ), this, SLOT( onDoneInstalling( QPersistentModelIndex ) ) );
QSortFilterProxyModel::setSourceModel( sourceModel ); QSortFilterProxyModel::setSourceModel( sourceModel );
} }
@ -70,3 +72,17 @@ AccountModelFilterProxy::onScrollTo( const QModelIndex& idx )
{ {
emit scrollTo( mapFromSource( idx ) ); emit scrollTo( mapFromSource( idx ) );
} }
void
AccountModelFilterProxy::onDoneInstalling( const QPersistentModelIndex& idx )
{
emit doneInstalling( mapFromSource( idx ) );
}
void
AccountModelFilterProxy::onStartInstalling( const QPersistentModelIndex& idx )
{
emit startInstalling( mapFromSource( idx ) );
}

@ -40,12 +40,18 @@ public:
signals: signals:
void scrollTo( const QModelIndex& idx ); void scrollTo( const QModelIndex& idx );
void startInstalling( const QPersistentModelIndex& idx );
void doneInstalling( const QPersistentModelIndex& idx );
protected: protected:
virtual bool filterAcceptsRow ( int sourceRow, const QModelIndex& sourceParent ) const; virtual bool filterAcceptsRow ( int sourceRow, const QModelIndex& sourceParent ) const;
private slots: private slots:
void onScrollTo( const QModelIndex& idx ); void onScrollTo( const QModelIndex& idx );
void onStartInstalling( const QPersistentModelIndex& idx );
void onDoneInstalling( const QPersistentModelIndex& idx );
private: private:
Tomahawk::Accounts::AccountType m_filterType; Tomahawk::Accounts::AccountType m_filterType;
}; };

@ -26,7 +26,7 @@
#include <attica/content.h> #include <attica/content.h>
#define ACCOUNTMODELNODE_DEBUG 0 #define ACCOUNTMODELNODE_DEBUG 1
namespace Tomahawk { namespace Tomahawk {

@ -34,7 +34,7 @@
#include "AlbumModel.h" #include "AlbumModel.h"
#include "ViewManager.h" #include "ViewManager.h"
#include "utils/Logger.h" #include "utils/Logger.h"
#include "dynamic/widgets/LoadingSpinner.h" #include "utils/AnimatedSpinner.h"
#define SCROLL_TIMEOUT 280 #define SCROLL_TIMEOUT 280
@ -46,7 +46,7 @@ AlbumView::AlbumView( QWidget* parent )
, m_model( 0 ) , m_model( 0 )
, m_proxyModel( 0 ) , m_proxyModel( 0 )
, m_delegate( 0 ) , m_delegate( 0 )
, m_loadingSpinner( new LoadingSpinner( this ) ) , m_loadingSpinner( new AnimatedSpinner( this ) )
, m_overlay( new OverlayWidget( this ) ) , m_overlay( new OverlayWidget( this ) )
, m_inited( false ) , m_inited( false )
{ {

@ -30,7 +30,7 @@
#include "DllMacro.h" #include "DllMacro.h"
class AlbumModel; class AlbumModel;
class LoadingSpinner; class AnimatedSpinner;
class AlbumItemDelegate; class AlbumItemDelegate;
class DLLEXPORT AlbumView : public QListView, public Tomahawk::ViewPage class DLLEXPORT AlbumView : public QListView, public Tomahawk::ViewPage
@ -87,7 +87,7 @@ private:
AlbumModel* m_model; AlbumModel* m_model;
AlbumProxyModel* m_proxyModel; AlbumProxyModel* m_proxyModel;
AlbumItemDelegate* m_delegate; AlbumItemDelegate* m_delegate;
LoadingSpinner* m_loadingSpinner; AnimatedSpinner* m_loadingSpinner;
OverlayWidget* m_overlay; OverlayWidget* m_overlay;
bool m_inited; bool m_inited;

@ -26,7 +26,7 @@
#include "audio/AudioEngine.h" #include "audio/AudioEngine.h"
#include "context/ContextWidget.h" #include "context/ContextWidget.h"
#include "dynamic/widgets/LoadingSpinner.h" #include "utils/AnimatedSpinner.h"
#include "widgets/OverlayWidget.h" #include "widgets/OverlayWidget.h"
#include "ContextMenu.h" #include "ContextMenu.h"
@ -49,7 +49,7 @@ ArtistView::ArtistView( QWidget* parent )
, m_model( 0 ) , m_model( 0 )
, m_proxyModel( 0 ) , m_proxyModel( 0 )
// , m_delegate( 0 ) // , m_delegate( 0 )
, m_loadingSpinner( new LoadingSpinner( this ) ) , m_loadingSpinner( new AnimatedSpinner( this ) )
, m_updateContextView( true ) , m_updateContextView( true )
, m_contextMenu( new ContextMenu( this ) ) , m_contextMenu( new ContextMenu( this ) )
, m_showModes( true ) , m_showModes( true )

@ -37,7 +37,7 @@ namespace Tomahawk
}; };
class TreeHeader; class TreeHeader;
class LoadingSpinner; class AnimatedSpinner;
class OverlayWidget; class OverlayWidget;
class TreeModel; class TreeModel;
@ -108,7 +108,7 @@ private:
TreeModel* m_model; TreeModel* m_model;
TreeProxyModel* m_proxyModel; TreeProxyModel* m_proxyModel;
// PlaylistItemDelegate* m_delegate; // PlaylistItemDelegate* m_delegate;
LoadingSpinner* m_loadingSpinner; AnimatedSpinner* m_loadingSpinner;
bool m_updateContextView; bool m_updateContextView;

@ -30,13 +30,13 @@
#include "audio/AudioEngine.h" #include "audio/AudioEngine.h"
#include "context/ContextWidget.h" #include "context/ContextWidget.h"
#include "widgets/OverlayWidget.h" #include "widgets/OverlayWidget.h"
#include "dynamic/widgets/LoadingSpinner.h"
#include "utils/TomahawkUtils.h" #include "utils/TomahawkUtils.h"
#include "utils/Logger.h" #include "utils/Logger.h"
#include "utils/Closure.h" #include "utils/Closure.h"
#include "DropJob.h" #include "DropJob.h"
#include "Artist.h" #include "Artist.h"
#include "Album.h" #include "Album.h"
#include "utils/AnimatedSpinner.h"
#define SCROLL_TIMEOUT 280 #define SCROLL_TIMEOUT 280
@ -50,7 +50,7 @@ TrackView::TrackView( QWidget* parent )
, m_delegate( 0 ) , m_delegate( 0 )
, m_header( new TrackHeader( this ) ) , m_header( new TrackHeader( this ) )
, m_overlay( new OverlayWidget( this ) ) , m_overlay( new OverlayWidget( this ) )
, m_loadingSpinner( new LoadingSpinner( this ) ) , m_loadingSpinner( new AnimatedSpinner( this ) )
, m_resizing( false ) , m_resizing( false )
, m_dragging( false ) , m_dragging( false )
, m_updateContextView( true ) , m_updateContextView( true )
@ -157,7 +157,7 @@ TrackView::setTrackModel( TrackModel* model )
setHeaderHidden( true ); setHeaderHidden( true );
setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
break; break;
default: default:
setHeaderHidden( false ); setHeaderHidden( false );
setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded ); setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded );

@ -30,7 +30,7 @@
#include "DllMacro.h" #include "DllMacro.h"
class QAction; class QAction;
class LoadingSpinner; class AnimatedSpinner;
class TrackHeader; class TrackHeader;
class TrackModel; class TrackModel;
class TrackProxyModel; class TrackProxyModel;
@ -57,7 +57,7 @@ public:
TrackHeader* header() const { return m_header; } TrackHeader* header() const { return m_header; }
OverlayWidget* overlay() const { return m_overlay; } OverlayWidget* overlay() const { return m_overlay; }
Tomahawk::ContextMenu* contextMenu() const { return m_contextMenu; } Tomahawk::ContextMenu* contextMenu() const { return m_contextMenu; }
LoadingSpinner* loadingSpinner() const { return m_loadingSpinner; } AnimatedSpinner* loadingSpinner() const { return m_loadingSpinner; }
QModelIndex hoveredIndex() const { return m_hoveredIndex; } QModelIndex hoveredIndex() const { return m_hoveredIndex; }
QModelIndex contextMenuIndex() const { return m_contextMenuIndex; } QModelIndex contextMenuIndex() const { return m_contextMenuIndex; }
@ -119,7 +119,7 @@ private:
PlaylistItemDelegate* m_delegate; PlaylistItemDelegate* m_delegate;
TrackHeader* m_header; TrackHeader* m_header;
OverlayWidget* m_overlay; OverlayWidget* m_overlay;
LoadingSpinner* m_loadingSpinner; AnimatedSpinner* m_loadingSpinner;
bool m_resizing; bool m_resizing;
bool m_dragging; bool m_dragging;
@ -133,7 +133,7 @@ private:
Tomahawk::query_ptr m_autoPlaying; Tomahawk::query_ptr m_autoPlaying;
Tomahawk::ContextMenu* m_contextMenu; Tomahawk::ContextMenu* m_contextMenu;
QTimer m_timer; QTimer m_timer;
}; };

@ -41,7 +41,7 @@
#include "ViewManager.h" #include "ViewManager.h"
#include "dynamic/DynamicView.h" #include "dynamic/DynamicView.h"
#include "DynamicSetupWidget.h" #include "DynamicSetupWidget.h"
#include "LoadingSpinner.h" #include "utils/AnimatedSpinner.h"
#include "utils/Logger.h" #include "utils/Logger.h"
using namespace Tomahawk; using namespace Tomahawk;
@ -74,7 +74,7 @@ DynamicWidget::DynamicWidget( const Tomahawk::dynplaylist_ptr& playlist, QWidget
connect( m_model, SIGNAL( collapseFromTo( int, int ) ), m_view, SLOT( collapseEntries( int, int ) ) ); connect( m_model, SIGNAL( collapseFromTo( int, int ) ), m_view, SLOT( collapseEntries( int, int ) ) );
connect( m_model, SIGNAL( trackGenerationFailure( QString ) ), this, SLOT( stationFailed( QString ) ) ); connect( m_model, SIGNAL( trackGenerationFailure( QString ) ), this, SLOT( stationFailed( QString ) ) );
m_loading = new LoadingSpinner( m_view ); m_loading = new AnimatedSpinner( m_view );
connect( m_model, SIGNAL( tracksAdded() ), m_loading, SLOT( fadeOut() ) ); connect( m_model, SIGNAL( tracksAdded() ), m_loading, SLOT( fadeOut() ) );
m_setup = new DynamicSetupWidget( playlist, this ); m_setup = new DynamicSetupWidget( playlist, this );

@ -26,7 +26,7 @@
#include "ViewPage.h" #include "ViewPage.h"
#include "playlist/dynamic/DynamicPlaylistRevision.h" #include "playlist/dynamic/DynamicPlaylistRevision.h"
class LoadingSpinner; class AnimatedSpinner;
class QShowEvent; class QShowEvent;
class QHideEvent; class QHideEvent;
class QSpinBox; class QSpinBox;
@ -119,7 +119,7 @@ private:
bool m_activePlaylist; bool m_activePlaylist;
// loading animation // loading animation
LoadingSpinner* m_loading; AnimatedSpinner* m_loading;
// setup controls // setup controls
DynamicSetupWidget* m_setup; DynamicSetupWidget* m_setup;

@ -1,128 +0,0 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010 Leo Franchi <lfranchi@kde.org>
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include "LoadingSpinner.h"
#include <QTimeLine>
#include <QPaintEvent>
#include <QPainter>
#include <QMovie>
#include <QLabel>
#include "utils/TomahawkUtils.h"
#include "utils/Logger.h"
#define ANIM_LENGTH 300
LoadingSpinner::LoadingSpinner( QWidget* parent )
: QWidget( parent )
, m_showHide( new QTimeLine )
{
m_showHide->setDuration( 300 );
m_showHide->setStartFrame( 0 );
m_showHide->setEndFrame( 100 );
m_showHide->setUpdateInterval( 20 );
connect( m_showHide, SIGNAL( frameChanged( int ) ), this, SLOT( update() ) );
connect( m_showHide, SIGNAL( finished() ), this, SLOT( hideFinished() ) );
m_anim = new QMovie( RESPATH "/images/loading-animation.gif" );
m_anim->jumpToNextFrame();
connect( m_anim, SIGNAL( frameChanged( int ) ), this, SLOT( update() ) );
resize( m_anim->currentPixmap().size() );
setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
hide();
}
LoadingSpinner::~LoadingSpinner()
{
}
void
LoadingSpinner::fadeIn()
{
if ( isVisible() )
return;
show();
m_anim->start();
m_showHide->setDirection( QTimeLine::Forward );
if ( m_showHide->state() != QTimeLine::Running )
m_showHide->start();
}
void
LoadingSpinner::fadeOut()
{
m_showHide->setDirection( QTimeLine::Backward );
if ( m_showHide->state() != QTimeLine::Running )
m_showHide->start();
}
void
LoadingSpinner::hideFinished()
{
if ( m_showHide->direction() == QTimeLine::Backward )
{
hide();
m_anim->stop();
}
}
QSize
LoadingSpinner::sizeHint() const
{
return m_anim->currentPixmap().size();
}
void
LoadingSpinner::paintEvent( QPaintEvent* ev )
{
Q_UNUSED( ev );
if ( !parentWidget() )
return;
QPoint center( ( parentWidget()->width() / 2 ) - ( width() / 2 ), ( parentWidget()->height() / 2 ) - ( height() / 2 ) );
if ( center != pos() )
{
move( center );
return;
}
QPainter p( this );
if ( m_showHide->state() == QTimeLine::Running )
{ // showing or hiding
p.setOpacity( (qreal)m_showHide->currentValue() );
}
p.drawPixmap( rect(), m_anim->currentPixmap() );
}

@ -1,56 +0,0 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010 Leo Franchi <lfranchi@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LOADING_SPINNER_H
#define LOADING_SPINNER_H
#include <QWidget>
#include "DllMacro.h"
class QMovie;
class QTimeLine;
/**
* A small widget that displays an animated loading spinner
*/
class DLLEXPORT LoadingSpinner : public QWidget {
Q_OBJECT
public:
LoadingSpinner( QWidget* parent );
virtual ~LoadingSpinner();
virtual QSize sizeHint() const;
virtual void paintEvent( QPaintEvent* );
public slots:
void fadeIn();
void fadeOut();
private slots:
void hideFinished();
private:
void reposition();
QTimeLine* m_showHide;
QMovie* m_anim;
};
#endif
class QPaintEvent;

@ -0,0 +1,267 @@
/*
Copyright (C) 2012 Leo Franchi <leo.franchi@kdab.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AnimatedSpinner.h"
#include <QtCore/QPoint>
#include <QTimeLine>
#include <QDebug>
#include <QDateTime>
#include <QtGui/QApplication>
#include <QtGui/QHideEvent>
#include <QtGui/QPainter>
#include <QtGui/QPaintEvent>
#include <QtGui/QShowEvent>
AnimatedSpinner::AnimatedSpinner( QWidget *parent )
: QWidget( parent )
, m_showHide( new QTimeLine )
, m_animation( new QTimeLine )
, m_currentIndex( -1 )
{
init();
m_radius = 10;
m_armLength = sizeHint().width()/2 - m_radius;
m_armWidth = 5;
m_border = 3;
m_armRect = QRect( m_radius, 0, m_armLength, m_armWidth );
}
AnimatedSpinner::AnimatedSpinner( const QSize size, bool autoStart )
: QWidget()
, m_showHide( new QTimeLine )
, m_animation( new QTimeLine )
, m_currentIndex( -1 )
{
m_pixmap = QPixmap( size );
m_pixmap.fill( Qt::transparent );
init();
if ( size.width() < 30 )
{
m_radius = 4;
m_armLength = size.width()/2 - m_radius;
m_armWidth = 2;
m_border = 2;
m_armRect = QRect( m_radius, 0, m_armLength, m_armWidth );
}
else
{
m_radius = 10;
m_armLength = size.width()/2 - m_radius;
m_armWidth = 5;
m_border = 3;
m_armRect = QRect( m_radius, 0, m_armLength, m_armWidth );
}
if ( autoStart )
fadeIn();
}
void
AnimatedSpinner::init()
{
m_showHide->setDuration( 300 );
m_showHide->setStartFrame( 0 );
m_showHide->setEndFrame( 100 );
m_showHide->setUpdateInterval( 20 );
if( parentWidget() )
connect( m_showHide, SIGNAL( frameChanged( int ) ), this, SLOT( update() ) );
else
connect( m_showHide, SIGNAL( frameChanged( int ) ), this, SLOT( updatePixmap() ) );
connect( m_showHide, SIGNAL( finished() ), this, SLOT( hideFinished() ) );
m_animation->setDuration( 1000 );
m_animation->setStartFrame( 0 );
m_animation->setEndFrame( segmentCount() );
m_animation->setUpdateInterval( 20 );
m_animation->setLoopCount( 0 );
m_animation->setDirection( QTimeLine::Forward );
m_animation->setCurveShape( QTimeLine::LinearCurve );
connect( m_animation, SIGNAL( frameChanged( int ) ), this, SLOT( frameChanged( int ) ) );
m_colors.resize( segmentCount() );
hide();
}
void
AnimatedSpinner::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
if ( parentWidget() )
{
QPoint center( ( parentWidget()->width() / 2 ) - ( width() / 2 ), ( parentWidget()->height() / 2 ) - ( height() / 2 ) );
if ( center != pos() )
{
move( center );
return;
}
}
QPainter p(this);
drawFrame( &p, rect() );
}
void
AnimatedSpinner::updatePixmap()
{
Q_ASSERT( !m_pixmap.isNull() );
QPainter p( &m_pixmap );
m_pixmap.fill( Qt::transparent );
drawFrame( &p, m_pixmap.rect() );
p.end();
emit requestUpdate();
}
void
AnimatedSpinner::drawFrame( QPainter* p, const QRect& rect )
{
if ( m_showHide->state() == QTimeLine::Running )
{
// showing or hiding
p->setOpacity( (qreal)m_showHide->currentValue() );
}
p->setRenderHint(QPainter::Antialiasing, true);
p->translate( rect.center() ); // center
const qreal stepRadius = (360 + 2*m_armWidth) / segmentCount();
p->rotate( stepRadius );
for (int segment = 0; segment < segmentCount(); ++segment) {
p->rotate(stepRadius);
QPainterPath arm;
arm.addRoundedRect( m_armRect.adjusted( 0, -m_armWidth/2., 0, -m_armWidth/2 ), m_border, m_border );
p->fillPath( arm, colorForSegment( segment ) );
}
}
void
AnimatedSpinner::fadeIn()
{
if ( parentWidget() && isVisible() )
return;
m_animation->start();
m_showHide->setDirection( QTimeLine::Forward );
if ( m_showHide->state() != QTimeLine::Running )
m_showHide->start();
if ( parentWidget() )
show();
else
updatePixmap();
}
void
AnimatedSpinner::fadeOut()
{
m_showHide->setDirection( QTimeLine::Backward );
if ( m_showHide->state() != QTimeLine::Running )
m_showHide->start();
}
void
AnimatedSpinner::hideFinished()
{
if ( m_showHide->direction() == QTimeLine::Backward )
{
m_animation->stop();
if ( parentWidget() )
hide();
else
updatePixmap();
}
}
QSize
AnimatedSpinner::sizeHint() const
{
return QSize(48, 48);
}
void
AnimatedSpinner::frameChanged( int frame )
{
if ( m_currentIndex == frame || frame > segmentCount()-1 )
return;
m_currentIndex = frame;
Q_ASSERT( frame >= 0 && frame < m_colors.size() );
// calculate colors, save a factor from 1 to 0 behind the current item
m_colors.fill( -1 );
int cur = m_currentIndex, running = 0, tailLength = 5;
while ( m_colors[cur] == -1 )
{
if ( running > tailLength )
m_colors[cur] = 0.; // beyond the tail, draw at base color
else
m_colors[cur] = 1. - ((qreal)running/tailLength); // scale from 1 to 0 along tail
++running;
cur = --cur < 0 ? m_colors.size() - 1 : cur;
}
if ( parentWidget() )
update();
else
updatePixmap();
}
QColor
AnimatedSpinner::colorForSegment( int seg ) const
{
// Highlight color is 227, 227, 227
// Base color is 101, 101, 101
Q_ASSERT( seg < m_colors.size() );
const int comp = 101 + m_colors[seg] * ( 126 );
return QColor(comp, comp, comp, 255);
}
int
AnimatedSpinner::segmentCount() const
{
return 11;
}

@ -0,0 +1,87 @@
/*
Copyright (C) 2012 Leo Franchi <leo.franchi@kdab.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ANIMATED_SPINNER_H
#define ANIMATED_SPINNER_H
#include "DllMacro.h"
#include <QtGui/QWidget>
#include <QtCore/QSize>
#include <QtGui/QColor>
#include <QtGui/QPixmap>
#include <QPainter>
class QTimeLine;
class QHideEvent;
class QShowEvent;
class QPaintEvent;
class QTimerEvent;
/**
If you don't pass a parent QWidget, this spinner will
draw into the pixmap instead. If you do, the pixmap will
be invalid.
*/
class DLLEXPORT AnimatedSpinner : public QWidget
{
Q_OBJECT
public:
explicit AnimatedSpinner( QWidget *parent = 0 ); // widget mode
AnimatedSpinner( const QSize size, bool autoStart ); // pixmap mode
QSize sizeHint() const;
QPixmap pixmap() const { return m_pixmap; }
public slots:
void fadeIn();
void fadeOut();
signals:
void requestUpdate();
protected:
void paintEvent(QPaintEvent *event);
private slots:
void updatePixmap();
void hideFinished();
void frameChanged( int );
private:
void init();
void drawFrame( QPainter* p, const QRect& rect );
int segmentCount() const;
QColor colorForSegment( int segment ) const;
QTimeLine* m_showHide;
QTimeLine* m_animation;
// to tweak
int m_radius, m_armLength, m_armWidth, m_border;
QRect m_armRect;
int m_currentIndex;
QVector<qreal> m_colors;
QPixmap m_pixmap;
};
#endif

@ -25,10 +25,10 @@
#include "SourceList.h" #include "SourceList.h"
#include "ViewManager.h" #include "ViewManager.h"
#include "dynamic/widgets/LoadingSpinner.h"
#include "playlist/AlbumModel.h" #include "playlist/AlbumModel.h"
#include "playlist/PlaylistModel.h" #include "playlist/PlaylistModel.h"
#include "widgets/OverlayWidget.h" #include "widgets/OverlayWidget.h"
#include "utils/AnimatedSpinner.h"
#include "utils/TomahawkUtils.h" #include "utils/TomahawkUtils.h"
#include "utils/Logger.h" #include "utils/Logger.h"
@ -146,7 +146,7 @@ SearchWidget::onResultsFound( const QList<Tomahawk::result_ptr>& results )
q->addResults( rl ); q->addResults( rl );
m_resultsModel->append( q ); m_resultsModel->append( q );
artists << result->artist(); artists << result->artist();
albums << result->album(); albums << result->album();
} }

@ -127,7 +127,7 @@ main( int argc, char *argv[] )
#ifndef ENABLE_HEADLESSs #ifndef ENABLE_HEADLESSs
#ifdef WITH_BREAKPAD #ifdef WITH_BREAKPAD
new BreakPad( QDir::tempPath(), TomahawkSettings::instance()->crashReporterEnabled() ); //new BreakPad( QDir::tempPath(), TomahawkSettings::instance()->crashReporterEnabled() );
#endif #endif
#endif #endif

@ -226,8 +226,8 @@ SourceTreeView::setupMenus()
} }
if ( type == SourcesModel::StaticPlaylist ) if ( type == SourcesModel::StaticPlaylist )
copyPlaylistAction->setText( tr( "&Export Playlist" ) ); copyPlaylistAction->setText( tr( "&Export Playlist" ) );
connect( loadPlaylistAction, SIGNAL( triggered() ), SLOT( loadPlaylist() ) ); connect( loadPlaylistAction, SIGNAL( triggered() ), SLOT( loadPlaylist() ) );
connect( renamePlaylistAction, SIGNAL( triggered() ), SLOT( renamePlaylist() ) ); connect( renamePlaylistAction, SIGNAL( triggered() ), SLOT( renamePlaylist() ) );
@ -357,18 +357,22 @@ SourceTreeView::copyPlaylistLink()
} }
else if ( type == SourcesModel::StaticPlaylist ) else if ( type == SourcesModel::StaticPlaylist )
{ {
PlaylistItem* item = itemFromIndex< PlaylistItem >( m_contextMenuIndex );
playlist_ptr playlist = item->playlist();
QString suggestedFilename = TomahawkSettings::instance()->playlistDefaultPath() + "/" + playlist->title(); // Disable toma.hk playlist mode until ready
QString filename = QFileDialog::getSaveFileName( TomahawkUtils::tomahawkWindow(), tr( "Save XSPF" ), // GlobalActionManager::instance()->getShortLink( playlist );
suggestedFilename, tr( "Playlists (*.xspf)" ) );
if ( !filename.isEmpty() ) PlaylistItem* item = itemFromIndex< PlaylistItem >( m_contextMenuIndex );
{ playlist_ptr playlist = item->playlist();
QFileInfo playlistAbsoluteFilePath = filename;
TomahawkSettings::instance()->setPlaylistDefaultPath( playlistAbsoluteFilePath.absolutePath() ); QString suggestedFilename = TomahawkSettings::instance()->playlistDefaultPath() + "/" + playlist->title();
GlobalActionManager::instance()->savePlaylistToFile( playlist, filename ); QString filename = QFileDialog::getSaveFileName( TomahawkUtils::tomahawkWindow(), tr( "Save XSPF" ),
} suggestedFilename, tr( "Playlists (*.xspf)" ) );
if ( !filename.isEmpty() )
{
QFileInfo playlistAbsoluteFilePath = filename;
TomahawkSettings::instance()->setPlaylistDefaultPath( playlistAbsoluteFilePath.absolutePath() );
GlobalActionManager::instance()->savePlaylistToFile( playlist, filename );
}
} }
} }