diff --git a/data/images/playlist-subscribed.png b/data/images/playlist-subscribed.png new file mode 100755 index 000000000..09234c070 Binary files /dev/null and b/data/images/playlist-subscribed.png differ diff --git a/resources.qrc b/resources.qrc index ca9e2d340..b853e65a3 100644 --- a/resources.qrc +++ b/resources.qrc @@ -148,5 +148,6 @@ data/images/jump-link.png data/images/scrollbar-vertical-handle.png data/images/scrollbar-horizontal-handle.png + data/images/playlist-subscribed.png diff --git a/src/libtomahawk/playlist/PlaylistUpdaterInterface.h b/src/libtomahawk/playlist/PlaylistUpdaterInterface.h index 0776451bd..79c582d89 100644 --- a/src/libtomahawk/playlist/PlaylistUpdaterInterface.h +++ b/src/libtomahawk/playlist/PlaylistUpdaterInterface.h @@ -35,6 +35,12 @@ namespace Tomahawk /** * PlaylistUpdaters are attached to playlists. They usually manipulate the playlist in some way * due to external input (spotify syncing) or timers (xspf updating) + * + * Updaters have 2 modes of operation: syncing and subscribing. Syncing implies two-way sync, that is, this + * playlist is reproduced on some other service (e.g. spotify or rdio). + * + * Subscribing implies the playlist is being updated periodically with changes from some source, and the user + * is working with a copy: e.g. an xspf updater or a spotify subscribed playlist. */ class PlaylistUpdaterFactory; @@ -71,7 +77,8 @@ public: static void registerUpdaterFactory( PlaylistUpdaterFactory* f ); - virtual bool sync() const { return true; } + virtual bool sync() const { return false; } + virtual bool subscribed() const { return false; } signals: void changed(); diff --git a/src/libtomahawk/playlist/XspfUpdater.h b/src/libtomahawk/playlist/XspfUpdater.h index cbe875119..c83efd18b 100644 --- a/src/libtomahawk/playlist/XspfUpdater.h +++ b/src/libtomahawk/playlist/XspfUpdater.h @@ -48,6 +48,8 @@ public: void setInterval( int intervalMsecs ) ; int intervalMsecs() const { return m_timer->interval(); } + bool subscribed() const { return true; } + public slots: void updateNow(); void setAutoUpdate( bool autoUpdate ); diff --git a/src/sourcetree/SourceDelegate.cpp b/src/sourcetree/SourceDelegate.cpp index 5a0571a0b..0548b2870 100644 --- a/src/sourcetree/SourceDelegate.cpp +++ b/src/sourcetree/SourceDelegate.cpp @@ -1,7 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser - * Copyright 2011, Leo Franchi + * Copyright 2011-2012, Leo Franchi * Copyright 2011, Michael Zanetti * Copyright 2010-2012, Jeff Mitchell * @@ -143,7 +143,7 @@ SourceDelegate::paintDecorations( QPainter* painter, const QStyleOptionViewItem& iconW = ah->originalSize().height() - 4; } } - + QRect iconRect = QRect( 4, option.rect.y() + 2, iconW, iconW ); QPixmap speaker = option.state & QStyle::State_Selected ? m_nowPlayingSpeaker : m_nowPlayingSpeakerDark; speaker = speaker.scaledToHeight( iconW, Qt::SmoothTransformation ); @@ -549,6 +549,22 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co else QStyledItemDelegate::paint( painter, o, index ); } + else if ( type == SourcesModel::StaticPlaylist ) + { + QStyledItemDelegate::paint( painter, o, index ); + + PlaylistItem* plItem = qobject_cast< PlaylistItem* >( item ); + if ( plItem->subscribed() && !plItem->subscribedIcon().isNull() ) + { + const int padding = 2; + const int imgWidth = o.rect.height() - 2*padding; + + const QPixmap icon = plItem->subscribedIcon().scaled( imgWidth, imgWidth, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + + const QRect subRect( o.rect.right() - padding - imgWidth, o.rect.top() + padding, imgWidth, imgWidth ); + painter->drawPixmap( subRect, icon ); + } + } else QStyledItemDelegate::paint( painter, o, index ); } diff --git a/src/sourcetree/items/PlaylistItems.cpp b/src/sourcetree/items/PlaylistItems.cpp index 8fb322915..5925bdcda 100644 --- a/src/sourcetree/items/PlaylistItems.cpp +++ b/src/sourcetree/items/PlaylistItems.cpp @@ -1,6 +1,6 @@ /* * - * Copyright 2010-2011, Leo Franchi + * Copyright 2010-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 @@ -280,6 +280,7 @@ PlaylistItem::onUpdated() if ( !newOverlay && !m_overlaidIcon.isNull() ) m_overlaidIcon = QIcon(); + emit updated(); } @@ -292,6 +293,19 @@ PlaylistItem::createOverlay() if ( m_playlist->updaters().isEmpty() ) return false; + m_showSubscribed = false; + foreach ( PlaylistUpdaterInterface* updater, m_playlist->updaters() ) + { + if ( updater->subscribed() ) + { + m_showSubscribed = true; + break; + } + } + + if ( m_showSubscribed && m_subscribedIcon.isNull() ) + m_subscribedIcon = QPixmap( RESPATH "images/playlist-subscribed.png" ); + QList< QPixmap > icons; foreach ( PlaylistUpdaterInterface* updater, m_playlist->updaters() ) { diff --git a/src/sourcetree/items/PlaylistItems.h b/src/sourcetree/items/PlaylistItems.h index 31198e778..f5d1b34c3 100644 --- a/src/sourcetree/items/PlaylistItems.h +++ b/src/sourcetree/items/PlaylistItems.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011, Leo Franchi + * Copyright 2010-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 @@ -42,6 +42,10 @@ public: virtual SourceTreeItem* activateCurrent(); + bool subscribed() const { return m_showSubscribed; } + QPixmap subscribedIcon() const { return m_subscribedIcon; } + QList< QAction* > subscribedActions() const; + public slots: virtual void activate(); virtual void doubleClicked(); @@ -58,9 +62,10 @@ private slots: private: bool createOverlay(); - bool m_loaded; + bool m_loaded, m_showSubscribed; Tomahawk::playlist_ptr m_playlist; QIcon m_icon, m_overlaidIcon; + QPixmap m_subscribedIcon; QList m_overlaidUpdaters; }; Q_DECLARE_OPERATORS_FOR_FLAGS(PlaylistItem::DropTypes)