[banshee] [PlayQueue] Add 'Add after' feature for adding songs to queue
- From: Alex Launi <alexlauni src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [banshee] [PlayQueue] Add 'Add after' feature for adding songs to queue
- Date: Fri, 22 Oct 2010 02:09:37 +0000 (UTC)
commit e51ceb17babb47baab57d30a052c15d95b337364
Author: Alex Launi <alex launi gmail com>
Date: Thu Oct 21 22:06:31 2010 -0400
[PlayQueue] Add 'Add after' feature for adding songs to queue
Allows adding tracks to the play queue after the currently playing song, artist, or album.
https://bugzilla.gnome.org/show_bug.cgi?id=632845
.../Banshee.PlayQueue/Banshee.PlayQueue.csproj | 1 +
.../Banshee.PlayQueue/PlayQueueActions.cs | 51 ++++++++-
.../Banshee.PlayQueue/PlayQueueSource.cs | 117 +++++++++++++++++---
.../Banshee.PlayQueue/QueueMode.cs | 38 +++++++
src/Extensions/Banshee.PlayQueue/Makefile.am | 3 +-
.../Banshee.PlayQueue/Resources/GlobalUI.xml | 5 +
6 files changed, 194 insertions(+), 21 deletions(-)
---
diff --git a/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue.csproj b/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue.csproj
index 41a0b34..afed885 100644
--- a/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue.csproj
+++ b/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue.csproj
@@ -105,6 +105,7 @@
<Compile Include="Banshee.PlayQueue\PlayQueueTrackListModel.cs" />
<Compile Include="Banshee.PlayQueue\QueueableSourceComboBox.cs" />
<Compile Include="Banshee.PlayQueue\HeaderWidget.cs" />
+ <Compile Include="Banshee.PlayQueue\QueueMode.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\ActiveSourceUI.xml">
diff --git a/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueActions.cs b/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueActions.cs
index fd24691..8a97fdf 100644
--- a/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueActions.cs
+++ b/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueActions.cs
@@ -33,6 +33,7 @@ using Gtk;
using Hyena;
+using Banshee.MediaEngine;
using Banshee.ServiceStack;
using Banshee.Sources;
@@ -49,7 +50,27 @@ namespace Banshee.PlayQueue
new ActionEntry ("AddToPlayQueueAction", Stock.Add,
Catalog.GetString ("Add to Play Queue"), "q",
Catalog.GetString ("Append selected songs to the play queue"),
- OnAddToPlayQueue)
+ OnAddToPlayQueue),
+
+ new ActionEntry ("AddToPlayQueueAfterAction", null,
+ Catalog.GetString ("Add after"), null,
+ Catalog.GetString ("Add selected songs after the currently playing track, album, or artist"),
+ null),
+
+ new ActionEntry ("AddToPlayQueueAfterCurrentTrackAction", null,
+ Catalog.GetString ("Current track"), null,
+ Catalog.GetString ("Add selected songs to the play queue after the currently playing song"),
+ OnAddToPlayQueueAfterCurrentTrack),
+
+ new ActionEntry ("AddToPlayQueueAfterCurrentTrackAlbum", null,
+ Catalog.GetString ("Current album"), null,
+ Catalog.GetString ("Add selected songs to the play queue after the currently playing album"),
+ OnAddToPlayQueueAfterCurrentAlbum),
+
+ new ActionEntry ("AddToPlayQueueAfterCurrentTrackArtist", null,
+ Catalog.GetString ("Current artist"), null,
+ Catalog.GetString ("Add selected songs to the play queue after the currently playing artist"),
+ OnAddToPlayQueueAfterCurrentArtist)
});
AddImportant (
@@ -87,6 +108,7 @@ namespace Banshee.PlayQueue
playqueue.Updated += OnUpdated;
ServiceManager.SourceManager.ActiveSourceChanged += OnSourceUpdated;
+ ServiceManager.PlayerEngine.ConnectEvent (OnPlayerEvent, PlayerEvent.StateChange);
OnUpdated (null, null);
@@ -102,9 +124,34 @@ namespace Banshee.PlayQueue
#region Action Handlers
+ private void OnPlayerEvent (PlayerEventArgs args)
+ {
+ this["AddToPlayQueueAfterAction"].Sensitive = ServiceManager.PlayerEngine.IsPlaying ();
+ }
+
private void OnAddToPlayQueue (object o, EventArgs args)
{
- playqueue.AddSelectedTracks (ServiceManager.SourceManager.ActiveSource);
+ AddSelectedToPlayQueue (QueueMode.Normal);
+ }
+
+ private void OnAddToPlayQueueAfterCurrentTrack (object sender, EventArgs e)
+ {
+ AddSelectedToPlayQueue (QueueMode.AfterCurrentTrack);
+ }
+
+ private void OnAddToPlayQueueAfterCurrentAlbum (object sender, EventArgs e)
+ {
+ AddSelectedToPlayQueue (QueueMode.AfterCurrentAlbum);
+ }
+
+ private void OnAddToPlayQueueAfterCurrentArtist (object sender, EventArgs e)
+ {
+ AddSelectedToPlayQueue (QueueMode.AfterCurrentArtist);
+ }
+
+ private void AddSelectedToPlayQueue (QueueMode mode)
+ {
+ playqueue.AddSelectedTracks (ServiceManager.SourceManager.ActiveSource, mode);
}
private void OnClearPlayQueue (object o, EventArgs args)
diff --git a/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueSource.cs b/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueSource.cs
index ea85d49..f17facc 100644
--- a/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueSource.cs
+++ b/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueSource.cs
@@ -320,7 +320,12 @@ namespace Banshee.PlayQueue
#endregion
- public override bool AddSelectedTracks (Source source)
+ public override bool AddSelectedTracks (Source souce)
+ {
+ return AddSelectedTracks (souce, QueueMode.Normal);
+ }
+
+ public bool AddSelectedTracks (Source source, QueueMode mode)
{
if ((Parent == null || source == Parent || source.Parent == Parent) && AcceptsInputFromSource (source)) {
DatabaseTrackListModel model = (source as ITrackModelSource).TrackModel as DatabaseTrackListModel;
@@ -328,8 +333,10 @@ namespace Banshee.PlayQueue
return false;
}
+ long view_order = CalculateViewOrder (mode);
+ long max_view_order = MaxViewOrder;
long current_view_order = CurrentTrackViewOrder;
-
+
// If the current_track is not playing, insert before it.
int index = -1;
if (current_track != null && !ServiceManager.PlayerEngine.IsPlaying (current_track)) {
@@ -337,27 +344,16 @@ namespace Banshee.PlayQueue
index = TrackModel.IndexOf (current_track);
}
- // view_order will point to the last pending non-generated track in the queue
- // or to the current_track if all tracks are generated. We want to insert tracks after it.
- long view_order = Math.Max(current_view_order, ServiceManager.DbConnection.Query<long> (@"
- SELECT MAX(ViewOrder)
- FROM CorePlaylistEntries
- WHERE PlaylistID = ? AND ViewOrder > ? AND Generated = 0",
- DbId, current_view_order
- ));
-
WithTrackSelection (model, shuffler.RecordInsertions);
// Add the tracks to the end of the queue.
WithTrackSelection (model, AddTrackRange);
- // Shift generated tracks to the end of the queue.
- ServiceManager.DbConnection.Execute (@"
- UPDATE CorePlaylistEntries
- SET ViewOrder = ViewOrder - ? + ?
- WHERE PlaylistID = ? AND ViewOrder > ? AND Generated = 1",
- view_order, MaxViewOrder, DbId, view_order
- );
+ if (mode != QueueMode.Normal) {
+ ShiftForAddedAfter (view_order, max_view_order);
+ }
+
+ ShiftGeneratedTracks (view_order);
OnTracksAdded ();
OnUserNotifyUpdated ();
@@ -373,6 +369,91 @@ namespace Banshee.PlayQueue
return false;
}
+ private long CalculateViewOrder (QueueMode mode)
+ {
+ long view_order = 0;
+ long current_view_order = CurrentTrackViewOrder;
+
+ switch (mode) {
+ case QueueMode.AfterCurrentTrack:
+ // view_order will point to the currently playing track.
+ // We want to insert tracks after this one.
+ view_order = current_view_order;
+ break;
+ case QueueMode.AfterCurrentAlbum:
+ // view order will point to the last track of the currently
+ // playing album.
+ IterateTrackModelUntilEndMatch (out view_order, true);
+ break;
+ case QueueMode.AfterCurrentArtist:
+ // view order will point to the last track of the currently
+ // playing artist.
+ IterateTrackModelUntilEndMatch (out view_order, false);
+ break;
+ case QueueMode.Normal:
+ // view_order will point to the last pending non-generated track in the queue
+ // or to the current_track if all tracks are generated. We want to insert tracks after it.
+ view_order = Math.Max(current_view_order, ServiceManager.DbConnection.Query<long> (@"
+ SELECT MAX(ViewOrder)
+ FROM CorePlaylistEntries
+ WHERE PlaylistID = ? AND ViewOrder > ? AND Generated = 0",
+ DbId, current_view_order
+ ));
+ break;
+ default:
+ throw new ArgumentException ("Handling for that QueueMode has not been defined");
+ }
+
+ return view_order;
+ }
+
+ private void IterateTrackModelUntilEndMatch (out long viewOrder, bool checkAlbum)
+ {
+ var t = TrackModel;
+ bool in_match = false;
+ long current_view_order = CurrentTrackViewOrder;
+
+ string current_album = ServiceManager.PlayerEngine.CurrentTrack.AlbumTitle;
+ string current_artist = ServiceManager.PlayerEngine.CurrentTrack.AlbumArtist;
+
+ // view order will point to the last track that has the same album and artist of the
+ // currently playing track.
+ viewOrder = current_view_order;
+ for (int i = 0; i < t.Count; i++) {
+ var track = t[i];
+ if (current_artist == track.AlbumArtist && (!checkAlbum || current_album == track.AlbumTitle)) {
+ in_match = true;
+ viewOrder++;
+ } else if (!in_match) {
+ continue;
+ } else {
+ viewOrder--;
+ break;
+ }
+ }
+ }
+
+ private void ShiftForAddedAfter (long viewOrder, long maxViewOrder)
+ {
+ ServiceManager.DbConnection.Execute (@"
+ UPDATE CorePlaylistEntries
+ SET ViewOrder = ViewOrder - ? + ?
+ WHERE PlaylistID = ? AND ViewOrder > ? AND ViewOrder < ?",
+ viewOrder, MaxViewOrder, DbId, viewOrder, maxViewOrder
+ );
+ }
+
+ private void ShiftGeneratedTracks (long viewOrder)
+ {
+ // Shift generated tracks to the end of the queue.
+ ServiceManager.DbConnection.Execute (@"
+ UPDATE CorePlaylistEntries
+ SET ViewOrder = ViewOrder - ? + ?
+ WHERE PlaylistID = ? AND ViewOrder > ? AND Generated = 1",
+ viewOrder, MaxViewOrder, DbId, viewOrder
+ );
+ }
+
private void SetAsPlaybackSourceUnlessPlaying ()
{
if (current_track != null && ServiceManager.PlaybackController.Source != this) {
diff --git a/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/QueueMode.cs b/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/QueueMode.cs
new file mode 100644
index 0000000..6d17ddd
--- /dev/null
+++ b/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/QueueMode.cs
@@ -0,0 +1,38 @@
+//
+// QueueMode.cs
+//
+// Author:
+// Alex Launi <alex launi gmail com>
+//
+// Copyright (c) 2010 Alex Launi
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+
+namespace Banshee.PlayQueue
+{
+ public enum QueueMode {
+ Normal,
+ AfterCurrentTrack,
+ AfterCurrentArtist,
+ AfterCurrentAlbum
+ }
+}
+
diff --git a/src/Extensions/Banshee.PlayQueue/Makefile.am b/src/Extensions/Banshee.PlayQueue/Makefile.am
index fd5b24b..a4c9440 100644
--- a/src/Extensions/Banshee.PlayQueue/Makefile.am
+++ b/src/Extensions/Banshee.PlayQueue/Makefile.am
@@ -9,7 +9,8 @@ SOURCES = \
Banshee.PlayQueue/PlayQueueActions.cs \
Banshee.PlayQueue/PlayQueueSource.cs \
Banshee.PlayQueue/PlayQueueTrackListModel.cs \
- Banshee.PlayQueue/QueueableSourceComboBox.cs
+ Banshee.PlayQueue/QueueableSourceComboBox.cs \
+ Banshee.PlayQueue/QueueMode.cs
RESOURCES = \
Banshee.PlayQueue.addin.xml \
diff --git a/src/Extensions/Banshee.PlayQueue/Resources/GlobalUI.xml b/src/Extensions/Banshee.PlayQueue/Resources/GlobalUI.xml
index 565604b..cabea01 100644
--- a/src/Extensions/Banshee.PlayQueue/Resources/GlobalUI.xml
+++ b/src/Extensions/Banshee.PlayQueue/Resources/GlobalUI.xml
@@ -10,6 +10,11 @@
<popup name="TrackContextMenu" action="TrackContextMenuAction">
<placeholder name="AboveAddToPlaylist">
<menuitem name="AddToPlayQueue" action="AddToPlayQueueAction"></menuitem>
+ <menu name="AddToPlayQueueAfterMenu" action="AddToPlayQueueAfterAction">
+ <menuitem name="AddToPlayQueueAfterCurrentTrack" action="AddToPlayQueueAfterCurrentTrackAction"></menuitem>
+ <menuitem name="AddToPlayQueueAfterCurrentAlbum" action="AddToPlayQueueAfterCurrentTrackAlbum"></menuitem>
+ <menuitem name="AddToPlayQueueAfterCurrentArtist" action="AddToPlayQueueAfterCurrentTrackArtist"></menuitem>
+ </menu>
</placeholder>
</popup>
</ui>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]