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)