Committing FS#10717 by Tomasz Kowalyczyk: add PLAYLIST_INSERT_LAST_SHUFFLED (appends the inserted folder into shuffled order to end of playlist)

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23385 a1c6a512-1295-4272-9138-f99709370657
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index d7dba2f..e7e3acd 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -13182,3 +13182,31 @@
     usb_hid: "USB Human Interface Device"
   </voice>
 </phrase>
+<phrase>
+  id: LANG_INSERT_LAST_SHUFFLED
+  desc: in onplay menu.  insert a playlist randomly at end of dynamic playlist
+  user: core
+  <source>
+    *: "Insert Last Shuffled"
+  </source>
+  <dest>
+    *: "Insert Last Shuffled"
+  </dest>
+  <voice>
+    *: "Insert Last Shuffled"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_QUEUE_LAST_SHUFFLED
+  desc: in onplay menu.  queue a playlist randomly at and of dynamic playlist
+  user: core
+  <source>
+    *: "Queue Last Shuffled"
+  </source>
+  <dest>
+    *: "Queue Last Shuffled"
+  </dest>
+  <voice>
+    *: "Queue Last Shuffled"
+  </voice>
+</phrase>
diff --git a/apps/onplay.c b/apps/onplay.c
index 28bf7de..7ad22d5 100644
--- a/apps/onplay.c
+++ b/apps/onplay.c
@@ -173,8 +173,12 @@
         playlist_create(NULL, NULL);
 
     /* always set seed before inserting shuffled */
-    if (position == PLAYLIST_INSERT_SHUFFLED)
+    if (position == PLAYLIST_INSERT_SHUFFLED || position == PLAYLIST_INSERT_LAST_SHUFFLED)
+    {
         srand(current_tick);
+	if (position == PLAYLIST_INSERT_LAST_SHUFFLED)
+	    playlist_set_last_shuffled_start();
+    }
 
 #ifdef HAVE_TAGCACHE
     if (context == CONTEXT_ID3DB)
@@ -355,6 +359,10 @@
                   ID2P(LANG_INSERT_SHUFFLED), playlist_insert_func,
                   (intptr_t*)PLAYLIST_INSERT_SHUFFLED, treeplaylist_callback,
                   Icon_Playlist);
+MENUITEM_FUNCTION(i_last_shuf_pl_item, MENU_FUNC_USEPARAM,
+                  ID2P(LANG_INSERT_LAST_SHUFFLED), playlist_insert_func,
+                  (intptr_t*)PLAYLIST_INSERT_LAST_SHUFFLED, treeplaylist_callback,
+                  Icon_Playlist);
 /* queue items */
 MENUITEM_FUNCTION(q_pl_item, MENU_FUNC_USEPARAM, ID2P(LANG_QUEUE),
                   playlist_queue_func, (intptr_t*)PLAYLIST_INSERT,
@@ -369,6 +377,10 @@
                   ID2P(LANG_QUEUE_SHUFFLED), playlist_queue_func,
                   (intptr_t*)PLAYLIST_INSERT_SHUFFLED,
                   treeplaylist_wplayback_callback, Icon_Playlist);
+MENUITEM_FUNCTION(q_last_shuf_pl_item, MENU_FUNC_USEPARAM,
+                  ID2P(LANG_QUEUE_LAST_SHUFFLED), playlist_queue_func,
+                  (intptr_t*)PLAYLIST_INSERT_LAST_SHUFFLED,
+                  treeplaylist_callback, Icon_Playlist);
 /* replace playlist */
 MENUITEM_FUNCTION(replace_pl_item, MENU_FUNC_USEPARAM, ID2P(LANG_REPLACE),
                   playlist_insert_func, (intptr_t*)PLAYLIST_REPLACE,
@@ -388,10 +400,12 @@
                  /* insert */
                  &i_pl_item, &i_first_pl_item,
                  &i_last_pl_item, &i_shuf_pl_item,
+                 &i_last_shuf_pl_item,
                  
                  /* queue */
                  &q_pl_item, &q_first_pl_item, &q_last_pl_item,
                  &q_shuf_pl_item,
+                 &q_last_shuf_pl_item,
                  
                  /* replace */
                  &replace_pl_item
@@ -439,6 +453,15 @@
                 }
                 return ACTION_EXIT_MENUITEM;
             }
+            else if (this_item == &i_last_shuf_pl_item || this_item == &q_last_shuf_pl_item)
+            {
+        	if ((playlist_amount() > 0) && (audio_status() & AUDIO_STATUS_PLAY) && (selected_file_attr & ATTR_DIRECTORY))
+        	{
+        	    return action;
+        	}
+        	else
+        	    return ACTION_EXIT_MENUITEM;
+            }
             break;
     }
     return action;
diff --git a/apps/playlist.c b/apps/playlist.c
index 1e96ebf..0c4fe97 100644
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -664,19 +664,21 @@
 
 
 /*
- * Add track to playlist at specified position.  There are five special
+ * Add track to playlist at specified position. There are seven special
  * positions that can be specified:
- *     PLAYLIST_PREPEND         - Add track at beginning of playlist
- *     PLAYLIST_INSERT          - Add track after current song.  NOTE: If
- *                                there are already inserted tracks then track
- *                                is added to the end of the insertion list
- *     PLAYLIST_INSERT_FIRST    - Add track immediately after current song, no
- *                                matter what other tracks have been inserted
- *     PLAYLIST_INSERT_LAST     - Add track to end of playlist
- *     PLAYLIST_INSERT_SHUFFLED - Add track at some random point between the
- *                                current playing track and end of playlist
- *     PLAYLIST_REPLACE         - Erase current playlist, Cue the current track
- *                                and inster this track at the end.
+ *  PLAYLIST_PREPEND              - Add track at beginning of playlist
+ *  PLAYLIST_INSERT               - Add track after current song.  NOTE: If
+ *                                  there are already inserted tracks then track
+ *                                  is added to the end of the insertion list
+ *  PLAYLIST_INSERT_FIRST         - Add track immediately after current song, no
+ *                                  matter what other tracks have been inserted
+ *  PLAYLIST_INSERT_LAST          - Add track to end of playlist
+ *  PLAYLIST_INSERT_SHUFFLED      - Add track at some random point between the
+ *                                  current playing track and end of playlist
+ *  PLAYLIST_INSERT_LAST_SHUFFLED - Add tracks in random order to the end of
+ *                                  the playlist.
+ *  PLAYLIST_REPLACE              - Erase current playlist, Cue the current track
+ *                                  and inster this track at the end.
  */
 static int add_track_to_playlist(struct playlist_info* playlist,
                                  const char *filename, int position,
@@ -753,6 +755,12 @@
                 position = insert_position = (rand() % (playlist->amount+1));
             break;
         }
+        case PLAYLIST_INSERT_LAST_SHUFFLED:
+        {
+            position = insert_position = playlist->last_shuffled_start +
+                          rand() % (playlist->amount - playlist->last_shuffled_start + 1);
+            break;
+        }
         case PLAYLIST_REPLACE:
             if (playlist_remove_all_tracks(playlist) < 0)
                 return -1;
@@ -2639,7 +2647,13 @@
 {
     return playlist_amount_ex(NULL);
 }
-
+/* set playlist->last_shuffle_start to playlist->amount for
+   PLAYLIST_INSERT_LAST_SHUFFLED command purposes*/
+void playlist_set_last_shuffled_start(void)
+{
+    struct playlist_info* playlist = &current_playlist;
+    playlist->last_shuffled_start = playlist->amount;
+}
 /*
  * Create a new playlist  If playlist is not NULL then we're loading a
  * playlist off disk for viewing/editing.  The index_buffer is used to store
diff --git a/apps/playlist.h b/apps/playlist.h
index 4f7b9cf..fa234f6 100644
--- a/apps/playlist.h
+++ b/apps/playlist.h
@@ -53,7 +53,8 @@
     PLAYLIST_INSERT_LAST = -3,
     PLAYLIST_INSERT_FIRST = -4,
     PLAYLIST_INSERT_SHUFFLED = -5,
-    PLAYLIST_REPLACE = -6
+    PLAYLIST_REPLACE = -6,
+    PLAYLIST_INSERT_LAST_SHUFFLED = -7
 };
 
 enum {
@@ -105,6 +106,8 @@
     bool pending_control_sync; /* control file needs to be synced   */
 
     struct mutex control_mutex; /* mutex for control file access    */
+    int last_shuffled_start; /* number of tracks when insert last
+                                    shuffled command start */
 };
 
 struct playlist_track_info
@@ -131,6 +134,7 @@
 int playlist_update_resume_info(const struct mp3entry* id3);
 int playlist_get_display_index(void);
 int playlist_amount(void);
+void playlist_set_last_shuffled_start(void);
 
 /* Exported functions for all playlists.  Pass NULL for playlist_info
    structure to work with current playlist. */
diff --git a/manual/working_with_playlists/main.tex b/manual/working_with_playlists/main.tex
index 96781e0..311aa86 100644
--- a/manual/working_with_playlists/main.tex
+++ b/manual/working_with_playlists/main.tex
@@ -100,7 +100,9 @@
 \item [Insert Last.] Add track(s) to end of playlist.
 
 \item [Insert Shuffled.] Add track(s) to the playlist in a random order.
-  
+
+\item [Insert Last Shuffled.] Add tracks in a random order to the end of the playlist.
+
 \item [Queue.] Queue is the same as Insert except queued tracks are
   deleted immediately from the playlist after they have been played. Also,
   queued tracks are not saved to the playlist file (see
@@ -112,6 +114,8 @@
 
 \item [Queue Shuffled.] Queue track(s) in a random order.
 
+\item [Queue Last Shuffled.] Queue tracks in a random order at the end of the playlist.
+
 \item [Play Next.] Replaces all but the current playing track with track(s).
     Current playing track is queued.
 \end{description}