diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index ddff13f7a..a7cd9f8c1 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -27,6 +27,8 @@ #include "utils/TomahawkUtils.h" #include "utils/Logger.h" +#include "utils/AnimatedSpinner.h" +#include "utils/Closure.h" #define CHILD_ACCOUNT_HEIGHT 24 @@ -134,9 +136,9 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, QFont authorFont = opt.font; authorFont.setItalic( true ); authorFont.setPointSize( authorFont.pointSize() - 1 ); - #ifdef Q_OS_MAC +#ifdef Q_OS_MAC authorFont.setPointSize( authorFont.pointSize() - 1 ); - #endif +#endif const QFontMetrics authorMetrics( authorFont ); QFont descFont = authorFont; @@ -158,7 +160,22 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, QRect checkRect = QRect( leftEdge, checkboxYPos, WRENCH_SIZE, WRENCH_SIZE ); QStyleOptionViewItemV4 opt2 = opt; 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; // Pixmap @@ -183,6 +200,7 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, topt.pos = confRect.topLeft(); drawConfigWrench( painter, opt, topt ); + m_cachedConfigRects[ index ] = confRect; 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 ); +} diff --git a/src/AccountDelegate.h b/src/AccountDelegate.h index 01c7f6a9c..e0d4112bc 100644 --- a/src/AccountDelegate.h +++ b/src/AccountDelegate.h @@ -22,6 +22,8 @@ #include #include "accounts/AccountModel.h" +class AnimatedSpinner; + namespace Tomahawk { namespace Accounts @@ -38,6 +40,12 @@ public: virtual void paint ( QPainter* painter, 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: 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_cachedConfigRects; mutable QHash< QPersistentModelIndex, QSize > m_sizeHints; + mutable QHash< QPersistentModelIndex, AnimatedSpinner* > m_loadingSpinners; mutable int m_accountRowHeight; }; diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index 862abb4ef..1795035b5 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -44,7 +44,7 @@ #include "AccountDelegate.h" #include "database/Database.h" #include "network/Servent.h" -#include "playlist/dynamic/widgets/LoadingSpinner.h" +#include "utils/AnimatedSpinner.h" #include "accounts/AccountModel.h" #include "accounts/Account.h" #include "accounts/AccountManager.h" @@ -114,6 +114,8 @@ SettingsDialog::SettingsDialog( QWidget *parent ) m_accountProxy = new AccountModelFilterProxy( 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 ) ) ); ui->accountsView->setModel( m_accountProxy ); @@ -130,7 +132,7 @@ SettingsDialog::SettingsDialog( QWidget *parent ) if ( !Servent::instance()->isReady() ) { - m_sipSpinner = new LoadingSpinner( ui->accountsView ); + m_sipSpinner = new AnimatedSpinner( ui->accountsView ); m_sipSpinner->fadeIn(); connect( Servent::instance(), SIGNAL( ready() ), this, SLOT( serventReady() ) ); diff --git a/src/SettingsDialog.h b/src/SettingsDialog.h index 991723423..7d1ab0d1b 100644 --- a/src/SettingsDialog.h +++ b/src/SettingsDialog.h @@ -26,7 +26,7 @@ #include "config.h" -class LoadingSpinner; +class AnimatedSpinner; class QListWidgetItem; class Ui_StackedSettingsDialog; class SipPlugin; @@ -112,7 +112,7 @@ private: bool m_rejected; Tomahawk::Accounts::AccountModel* m_accountModel; Tomahawk::Accounts::AccountModelFilterProxy* m_accountProxy; - LoadingSpinner* m_sipSpinner; + AnimatedSpinner* m_sipSpinner; }; #endif // SETTINGSDIALOG_H diff --git a/src/accounts/spotify/SpotifyAccountConfig.cpp b/src/accounts/spotify/SpotifyAccountConfig.cpp index 2d475bad2..b3fa5f629 100644 --- a/src/accounts/spotify/SpotifyAccountConfig.cpp +++ b/src/accounts/spotify/SpotifyAccountConfig.cpp @@ -19,7 +19,7 @@ #include "SpotifyAccountConfig.h" #include "SpotifyAccount.h" -#include +#include "utils/AnimatedSpinner.h" #include "ui_SpotifyAccountConfig.h" #include @@ -44,7 +44,7 @@ SpotifyAccountConfig::SpotifyAccountConfig( SpotifyAccount *account ) connect( m_ui->passwordEdit, SIGNAL( textChanged( QString ) ), this, SLOT( resetLoginButton() ) ); loadFromConfig(); - m_playlistsLoading = new LoadingSpinner( m_ui->playlistList ); + m_playlistsLoading = new AnimatedSpinner( m_ui->playlistList ); } diff --git a/src/accounts/spotify/SpotifyAccountConfig.h b/src/accounts/spotify/SpotifyAccountConfig.h index 56d3ff748..79c398e04 100644 --- a/src/accounts/spotify/SpotifyAccountConfig.h +++ b/src/accounts/spotify/SpotifyAccountConfig.h @@ -23,7 +23,7 @@ #include #include -class LoadingSpinner; +class AnimatedSpinner; class QShowEvent; namespace Ui @@ -74,7 +74,7 @@ private slots: private: Ui::SpotifyConfig* m_ui; SpotifyAccount* m_account; - LoadingSpinner* m_playlistsLoading; + AnimatedSpinner* m_playlistsLoading; bool m_loggedInManually; }; diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index d93a06ed9..c77b302e5 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -96,7 +96,6 @@ set( libGuiSources playlist/dynamic/widgets/MiscControlWidgets.cpp playlist/dynamic/widgets/CollapsibleControls.cpp playlist/dynamic/widgets/DynamicSetupWidget.cpp - playlist/dynamic/widgets/LoadingSpinner.cpp playlist/topbar/TopBar.cpp playlist/topbar/ClearButton.cpp @@ -123,6 +122,7 @@ set( libGuiSources utils/Closure.cpp utils/PixmapDelegateFader.cpp utils/SmartPointerList.h + utils/AnimatedSpinner.cpp widgets/AnimatedCounterLabel.cpp widgets/CheckDirTree.cpp diff --git a/src/libtomahawk/GlobalActionManager.cpp b/src/libtomahawk/GlobalActionManager.cpp index d3c052b34..d7c6cfbe2 100644 --- a/src/libtomahawk/GlobalActionManager.cpp +++ b/src/libtomahawk/GlobalActionManager.cpp @@ -2,7 +2,7 @@ Copyright (C) 2011 Leo Franchi Copyright (C) 2011, Jeff Mitchell Copyright (C) 2011-2012, Christian Muehlhaeuser - + 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 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 GlobalActionManager::copyPlaylistToClipboard( const dynplaylist_ptr& playlist ) { @@ -341,18 +386,29 @@ GlobalActionManager::handlePlaylistCommand( const QUrl& url ) 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; } - QUrl xspf = QUrl::fromUserInput( url.queryItemValue( "xspf" ) ); - QString title = url.hasQueryItem( "title" ) ? url.queryItemValue( "title" ) : QString(); - XSPFLoader* l= new XSPFLoader( true, this ); - l->setOverrideTitle( title ); - l->load( xspf ); - connect( l, SIGNAL( ok( Tomahawk::playlist_ptr ) ), this, SLOT( playlistCreatedToShow( Tomahawk::playlist_ptr) ) ); - + if ( url.hasQueryItem( "xspf") ) + { + QUrl xspf = QUrl::fromUserInput( url.queryItemValue( "xspf" ) ); + QString title = url.hasQueryItem( "title" ) ? url.queryItemValue( "title" ) : QString(); + XSPFLoader* l= new XSPFLoader( true, this ); + 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" ) { @@ -1016,7 +1072,7 @@ GlobalActionManager::shortenLinkRequestFinished() QVariant callbackObj; if ( reply->property( "callbackobj" ).isValid() ) callbackObj = reply->property( "callbackobj" ); - + // Check for the redirect attribute, as this should be the shortened link QVariant urlVariant = reply->attribute( QNetworkRequest::RedirectionTargetAttribute ); @@ -1054,6 +1110,25 @@ GlobalActionManager::shortenLinkRequestFinished() } +void +GlobalActionManager::postShortenFinished() +{ + QNetworkReply* reply = qobject_cast( 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 GlobalActionManager::shortenLinkRequestError( QNetworkReply::NetworkError error ) { diff --git a/src/libtomahawk/GlobalActionManager.h b/src/libtomahawk/GlobalActionManager.h index 5137f6f8c..e9a96f3d6 100644 --- a/src/libtomahawk/GlobalActionManager.h +++ b/src/libtomahawk/GlobalActionManager.h @@ -57,6 +57,7 @@ public: public slots: void shortenLink( const QUrl& url, const QVariant &callbackObj = QVariant() ); + void getShortLink( const Tomahawk::playlist_ptr& playlist ); bool parseTomahawkLink( const QString& link ); void waitingForResolved( bool ); @@ -71,6 +72,7 @@ signals: private slots: void shortenLinkRequestFinished(); + void postShortenFinished(); void shortenLinkRequestError( QNetworkReply::NetworkError ); void bookmarkPlaylistCreated( const Tomahawk::playlist_ptr& pl ); diff --git a/src/libtomahawk/TomahawkSettings.cpp b/src/libtomahawk/TomahawkSettings.cpp index 66bea27b5..1c79b0493 100644 --- a/src/libtomahawk/TomahawkSettings.cpp +++ b/src/libtomahawk/TomahawkSettings.cpp @@ -408,6 +408,42 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion ) setValue( "allaccounts", allAccounts ); 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(); + } } diff --git a/src/libtomahawk/TomahawkSettings.h b/src/libtomahawk/TomahawkSettings.h index 60a2eccd9..65e6d84ea 100644 --- a/src/libtomahawk/TomahawkSettings.h +++ b/src/libtomahawk/TomahawkSettings.h @@ -28,7 +28,7 @@ #include "DllMacro.h" -#define TOMAHAWK_SETTINGS_VERSION 8 +#define TOMAHAWK_SETTINGS_VERSION 9 /** * Convenience wrapper around QSettings for tomahawk-specific config diff --git a/src/libtomahawk/accounts/AccountManager.cpp b/src/libtomahawk/accounts/AccountManager.cpp index 564d520d7..66da9ce39 100644 --- a/src/libtomahawk/accounts/AccountManager.cpp +++ b/src/libtomahawk/accounts/AccountManager.cpp @@ -266,7 +266,7 @@ void AccountManager::loadFromConfig() { QStringList accountIds = TomahawkSettings::instance()->accounts(); - + qDebug() << "LOADING ALL ACCOUNTS" << accountIds; foreach( const QString& accountId, accountIds ) { QString pluginFactory = factoryFromId( accountId ); diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 450ecf506..f4614c322 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -29,7 +29,7 @@ using namespace Tomahawk; using namespace Accounts; -#define ACCOUNTMODEL_DEBUG 0 +#define ACCOUNTMODEL_DEBUG 1 AccountModel::AccountModel( QObject* parent ) : QAbstractListModel( parent ) @@ -451,6 +451,7 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role qDebug() << "Kicked off fetch+install, now waiting"; m_waitingForAtticaInstall.insert( resolver.id() ); + emit startInstalling( index ); AtticaManager::instance()->installResolver( resolver ); return true; } @@ -571,6 +572,10 @@ AccountModel::accountAdded( Account* account ) AccountManager::instance()->enableAccount( account ); m_waitingForAtticaInstall.remove( attica->atticaId() ); + + // find index to emit doneInstalling for + const QModelIndex idx = index( i, 0, QModelIndex() ); + emit doneInstalling( idx ); } if ( thisIsTheOne ) diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index 53594f76c..68fcb89f6 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -94,6 +94,8 @@ signals: void createAccount( Tomahawk::Accounts::AccountFactory* factory ); void scrollTo( const QModelIndex& idx ); + void startInstalling( const QPersistentModelIndex& idx ); + void doneInstalling( const QPersistentModelIndex& idx ); private slots: void loadData(); diff --git a/src/libtomahawk/accounts/AccountModelFilterProxy.cpp b/src/libtomahawk/accounts/AccountModelFilterProxy.cpp index 23dca5dfc..1a559faed 100644 --- a/src/libtomahawk/accounts/AccountModelFilterProxy.cpp +++ b/src/libtomahawk/accounts/AccountModelFilterProxy.cpp @@ -36,6 +36,8 @@ void AccountModelFilterProxy::setSourceModel( QAbstractItemModel* sourceModel ) { 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 ); } @@ -70,3 +72,17 @@ AccountModelFilterProxy::onScrollTo( const QModelIndex& 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 ) ); +} diff --git a/src/libtomahawk/accounts/AccountModelFilterProxy.h b/src/libtomahawk/accounts/AccountModelFilterProxy.h index e34c3a6a3..75021c6b1 100644 --- a/src/libtomahawk/accounts/AccountModelFilterProxy.h +++ b/src/libtomahawk/accounts/AccountModelFilterProxy.h @@ -40,12 +40,18 @@ public: signals: void scrollTo( const QModelIndex& idx ); + void startInstalling( const QPersistentModelIndex& idx ); + void doneInstalling( const QPersistentModelIndex& idx ); + protected: virtual bool filterAcceptsRow ( int sourceRow, const QModelIndex& sourceParent ) const; private slots: void onScrollTo( const QModelIndex& idx ); + void onStartInstalling( const QPersistentModelIndex& idx ); + void onDoneInstalling( const QPersistentModelIndex& idx ); + private: Tomahawk::Accounts::AccountType m_filterType; }; diff --git a/src/libtomahawk/accounts/AccountModelNode.h b/src/libtomahawk/accounts/AccountModelNode.h index 857d57402..a1754a8d2 100644 --- a/src/libtomahawk/accounts/AccountModelNode.h +++ b/src/libtomahawk/accounts/AccountModelNode.h @@ -26,7 +26,7 @@ #include -#define ACCOUNTMODELNODE_DEBUG 0 +#define ACCOUNTMODELNODE_DEBUG 1 namespace Tomahawk { diff --git a/src/libtomahawk/playlist/AlbumView.cpp b/src/libtomahawk/playlist/AlbumView.cpp index a3b2c6080..881a566b8 100644 --- a/src/libtomahawk/playlist/AlbumView.cpp +++ b/src/libtomahawk/playlist/AlbumView.cpp @@ -34,7 +34,7 @@ #include "AlbumModel.h" #include "ViewManager.h" #include "utils/Logger.h" -#include "dynamic/widgets/LoadingSpinner.h" +#include "utils/AnimatedSpinner.h" #define SCROLL_TIMEOUT 280 @@ -46,7 +46,7 @@ AlbumView::AlbumView( QWidget* parent ) , m_model( 0 ) , m_proxyModel( 0 ) , m_delegate( 0 ) - , m_loadingSpinner( new LoadingSpinner( this ) ) + , m_loadingSpinner( new AnimatedSpinner( this ) ) , m_overlay( new OverlayWidget( this ) ) , m_inited( false ) { diff --git a/src/libtomahawk/playlist/AlbumView.h b/src/libtomahawk/playlist/AlbumView.h index 6e5cd73f9..c7d3918b5 100644 --- a/src/libtomahawk/playlist/AlbumView.h +++ b/src/libtomahawk/playlist/AlbumView.h @@ -30,7 +30,7 @@ #include "DllMacro.h" class AlbumModel; -class LoadingSpinner; +class AnimatedSpinner; class AlbumItemDelegate; class DLLEXPORT AlbumView : public QListView, public Tomahawk::ViewPage @@ -87,7 +87,7 @@ private: AlbumModel* m_model; AlbumProxyModel* m_proxyModel; AlbumItemDelegate* m_delegate; - LoadingSpinner* m_loadingSpinner; + AnimatedSpinner* m_loadingSpinner; OverlayWidget* m_overlay; bool m_inited; diff --git a/src/libtomahawk/playlist/ArtistView.cpp b/src/libtomahawk/playlist/ArtistView.cpp index ce22cccd8..fec374771 100644 --- a/src/libtomahawk/playlist/ArtistView.cpp +++ b/src/libtomahawk/playlist/ArtistView.cpp @@ -26,7 +26,7 @@ #include "audio/AudioEngine.h" #include "context/ContextWidget.h" -#include "dynamic/widgets/LoadingSpinner.h" +#include "utils/AnimatedSpinner.h" #include "widgets/OverlayWidget.h" #include "ContextMenu.h" @@ -49,7 +49,7 @@ ArtistView::ArtistView( QWidget* parent ) , m_model( 0 ) , m_proxyModel( 0 ) // , m_delegate( 0 ) - , m_loadingSpinner( new LoadingSpinner( this ) ) + , m_loadingSpinner( new AnimatedSpinner( this ) ) , m_updateContextView( true ) , m_contextMenu( new ContextMenu( this ) ) , m_showModes( true ) diff --git a/src/libtomahawk/playlist/ArtistView.h b/src/libtomahawk/playlist/ArtistView.h index 1926acd4e..90c76e66f 100644 --- a/src/libtomahawk/playlist/ArtistView.h +++ b/src/libtomahawk/playlist/ArtistView.h @@ -37,7 +37,7 @@ namespace Tomahawk }; class TreeHeader; -class LoadingSpinner; +class AnimatedSpinner; class OverlayWidget; class TreeModel; @@ -108,7 +108,7 @@ private: TreeModel* m_model; TreeProxyModel* m_proxyModel; // PlaylistItemDelegate* m_delegate; - LoadingSpinner* m_loadingSpinner; + AnimatedSpinner* m_loadingSpinner; bool m_updateContextView; diff --git a/src/libtomahawk/playlist/TrackView.cpp b/src/libtomahawk/playlist/TrackView.cpp index 2f7a38ea1..74651b917 100644 --- a/src/libtomahawk/playlist/TrackView.cpp +++ b/src/libtomahawk/playlist/TrackView.cpp @@ -30,13 +30,13 @@ #include "audio/AudioEngine.h" #include "context/ContextWidget.h" #include "widgets/OverlayWidget.h" -#include "dynamic/widgets/LoadingSpinner.h" #include "utils/TomahawkUtils.h" #include "utils/Logger.h" #include "utils/Closure.h" #include "DropJob.h" #include "Artist.h" #include "Album.h" +#include "utils/AnimatedSpinner.h" #define SCROLL_TIMEOUT 280 @@ -50,7 +50,7 @@ TrackView::TrackView( QWidget* parent ) , m_delegate( 0 ) , m_header( new TrackHeader( this ) ) , m_overlay( new OverlayWidget( this ) ) - , m_loadingSpinner( new LoadingSpinner( this ) ) + , m_loadingSpinner( new AnimatedSpinner( this ) ) , m_resizing( false ) , m_dragging( false ) , m_updateContextView( true ) @@ -157,7 +157,7 @@ TrackView::setTrackModel( TrackModel* model ) setHeaderHidden( true ); setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); break; - + default: setHeaderHidden( false ); setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded ); diff --git a/src/libtomahawk/playlist/TrackView.h b/src/libtomahawk/playlist/TrackView.h index 7a69e5053..1a27ccfed 100644 --- a/src/libtomahawk/playlist/TrackView.h +++ b/src/libtomahawk/playlist/TrackView.h @@ -30,7 +30,7 @@ #include "DllMacro.h" class QAction; -class LoadingSpinner; +class AnimatedSpinner; class TrackHeader; class TrackModel; class TrackProxyModel; @@ -57,7 +57,7 @@ public: TrackHeader* header() const { return m_header; } OverlayWidget* overlay() const { return m_overlay; } 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 contextMenuIndex() const { return m_contextMenuIndex; } @@ -119,7 +119,7 @@ private: PlaylistItemDelegate* m_delegate; TrackHeader* m_header; OverlayWidget* m_overlay; - LoadingSpinner* m_loadingSpinner; + AnimatedSpinner* m_loadingSpinner; bool m_resizing; bool m_dragging; @@ -133,7 +133,7 @@ private: Tomahawk::query_ptr m_autoPlaying; Tomahawk::ContextMenu* m_contextMenu; - + QTimer m_timer; }; diff --git a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp index d5eb6cd77..eabad53e9 100644 --- a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp +++ b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp @@ -41,7 +41,7 @@ #include "ViewManager.h" #include "dynamic/DynamicView.h" #include "DynamicSetupWidget.h" -#include "LoadingSpinner.h" +#include "utils/AnimatedSpinner.h" #include "utils/Logger.h" 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( 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() ) ); m_setup = new DynamicSetupWidget( playlist, this ); diff --git a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.h b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.h index 2a8d33e81..7773f2269 100644 --- a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.h +++ b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.h @@ -26,7 +26,7 @@ #include "ViewPage.h" #include "playlist/dynamic/DynamicPlaylistRevision.h" -class LoadingSpinner; +class AnimatedSpinner; class QShowEvent; class QHideEvent; class QSpinBox; @@ -119,7 +119,7 @@ private: bool m_activePlaylist; // loading animation - LoadingSpinner* m_loading; + AnimatedSpinner* m_loading; // setup controls DynamicSetupWidget* m_setup; diff --git a/src/libtomahawk/playlist/dynamic/widgets/LoadingSpinner.cpp b/src/libtomahawk/playlist/dynamic/widgets/LoadingSpinner.cpp deleted file mode 100644 index 9b0ff0524..000000000 --- a/src/libtomahawk/playlist/dynamic/widgets/LoadingSpinner.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2010 Leo Franchi - * Copyright 2010-2011, Jeff Mitchell - * - * 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 . - */ - -#include "LoadingSpinner.h" - -#include -#include -#include -#include -#include - -#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() ); -} diff --git a/src/libtomahawk/playlist/dynamic/widgets/LoadingSpinner.h b/src/libtomahawk/playlist/dynamic/widgets/LoadingSpinner.h deleted file mode 100644 index fe51bb4fc..000000000 --- a/src/libtomahawk/playlist/dynamic/widgets/LoadingSpinner.h +++ /dev/null @@ -1,56 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2010 Leo Franchi - * - * 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 . - */ - -#ifndef LOADING_SPINNER_H -#define LOADING_SPINNER_H - -#include - -#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; diff --git a/src/libtomahawk/utils/AnimatedSpinner.cpp b/src/libtomahawk/utils/AnimatedSpinner.cpp new file mode 100644 index 000000000..25b0dc497 --- /dev/null +++ b/src/libtomahawk/utils/AnimatedSpinner.cpp @@ -0,0 +1,267 @@ +/* + Copyright (C) 2012 Leo Franchi + + 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 . +*/ + +#include "AnimatedSpinner.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +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; +} diff --git a/src/libtomahawk/utils/AnimatedSpinner.h b/src/libtomahawk/utils/AnimatedSpinner.h new file mode 100644 index 000000000..e738d9bb0 --- /dev/null +++ b/src/libtomahawk/utils/AnimatedSpinner.h @@ -0,0 +1,87 @@ +/* + Copyright (C) 2012 Leo Franchi + + 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 . +*/ + +#ifndef ANIMATED_SPINNER_H +#define ANIMATED_SPINNER_H + +#include "DllMacro.h" + +#include + +#include +#include +#include +#include + +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 m_colors; + QPixmap m_pixmap; +}; + +#endif diff --git a/src/libtomahawk/widgets/SearchWidget.cpp b/src/libtomahawk/widgets/SearchWidget.cpp index a0b30d3ad..30a9a84c5 100644 --- a/src/libtomahawk/widgets/SearchWidget.cpp +++ b/src/libtomahawk/widgets/SearchWidget.cpp @@ -25,10 +25,10 @@ #include "SourceList.h" #include "ViewManager.h" -#include "dynamic/widgets/LoadingSpinner.h" #include "playlist/AlbumModel.h" #include "playlist/PlaylistModel.h" #include "widgets/OverlayWidget.h" +#include "utils/AnimatedSpinner.h" #include "utils/TomahawkUtils.h" #include "utils/Logger.h" @@ -146,7 +146,7 @@ SearchWidget::onResultsFound( const QList& results ) q->addResults( rl ); m_resultsModel->append( q ); - + artists << result->artist(); albums << result->album(); } diff --git a/src/main.cpp b/src/main.cpp index f0db949a9..5ce835528 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -127,7 +127,7 @@ main( int argc, char *argv[] ) #ifndef ENABLE_HEADLESSs #ifdef WITH_BREAKPAD - new BreakPad( QDir::tempPath(), TomahawkSettings::instance()->crashReporterEnabled() ); + //new BreakPad( QDir::tempPath(), TomahawkSettings::instance()->crashReporterEnabled() ); #endif #endif diff --git a/src/sourcetree/SourceTreeView.cpp b/src/sourcetree/SourceTreeView.cpp index a7ea33e44..3e43c36b6 100644 --- a/src/sourcetree/SourceTreeView.cpp +++ b/src/sourcetree/SourceTreeView.cpp @@ -226,8 +226,8 @@ SourceTreeView::setupMenus() } - if ( type == SourcesModel::StaticPlaylist ) - copyPlaylistAction->setText( tr( "&Export Playlist" ) ); + if ( type == SourcesModel::StaticPlaylist ) + copyPlaylistAction->setText( tr( "&Export Playlist" ) ); connect( loadPlaylistAction, SIGNAL( triggered() ), SLOT( loadPlaylist() ) ); connect( renamePlaylistAction, SIGNAL( triggered() ), SLOT( renamePlaylist() ) ); @@ -357,18 +357,22 @@ SourceTreeView::copyPlaylistLink() } else if ( type == SourcesModel::StaticPlaylist ) { - PlaylistItem* item = itemFromIndex< PlaylistItem >( m_contextMenuIndex ); - playlist_ptr playlist = item->playlist(); - QString suggestedFilename = TomahawkSettings::instance()->playlistDefaultPath() + "/" + playlist->title(); - 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 ); - } + // Disable toma.hk playlist mode until ready + // GlobalActionManager::instance()->getShortLink( playlist ); + + PlaylistItem* item = itemFromIndex< PlaylistItem >( m_contextMenuIndex ); + playlist_ptr playlist = item->playlist(); + + QString suggestedFilename = TomahawkSettings::instance()->playlistDefaultPath() + "/" + playlist->title(); + 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 ); + } } }