FS#11808 - Major playlist handling changes (on disk playlists)

* Playlists are treated similar to directories in the browser, they now open in the viewer when selected instead of automatically starting the playlist.
* Make the "Playlists" main menu item useful, it now displays the playlist catalog (and has been renamed accordingly)
* Default to storing playlists in the catalog
* Add a UI to move the catalog directory

(other minor stuff too)

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30177 a1c6a512-1295-4272-9138-f99709370657
diff --git a/apps/filetree.c b/apps/filetree.c
index b7f3c9e..654d33d 100644
--- a/apps/filetree.c
+++ b/apps/filetree.c
@@ -1,4 +1,4 @@
-/***************************************************************************
+ /***************************************************************************
  *             __________               __   ___.
  *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
  *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
@@ -43,6 +43,7 @@
 #include "filetree.h"
 #include "misc.h"
 #include "strnatcmp.h"
+#include "playlist_viewer.h"
 #ifdef HAVE_LCD_BITMAP
 #include "keyboard.h"
 #endif
@@ -445,13 +446,8 @@
 
         switch ( file->attr & FILE_ATTR_MASK ) {
             case FILE_ATTR_M3U:
-                play = ft_play_playlist(buf, c->currdir, file->name);
-                
-                if (play)
-                {
-                    start_index = 0;
-                }
-
+                if (!bookmark_autoload(buf))
+                    playlist_viewer_ex(buf);
                 break;
 
             case FILE_ATTR_AUDIO:
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index e0811fa..e9d1dba 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -502,7 +502,7 @@
 </phrase>
 <phrase>
   id: LANG_PLAYLISTS
-  desc: in the main menu and file view setting
+  desc: in the file view setting
   user: core
   <source>
     *: "Playlists"
@@ -6544,7 +6544,7 @@
 </phrase>
 <phrase>
   id: LANG_CATALOG
-  desc: in onplay menu
+  desc: in main menu and onplay menu
   user: core
   <source>
     *: "Playlist Catalog"
@@ -12757,3 +12757,45 @@
     *: "Rewind on Pause"
   </voice>
 </phrase>
+<phrase>
+  id: LANG_SET_AS_PLAYLISTCAT_DIR
+  desc: used in the onplay menu to set a playlist catalog dir
+  user: core
+  <source>
+    *: "Set As Playlist Catalog Directory"
+  </source>
+  <dest>
+    *: "Set As Playlist Catalog Directory"
+  </dest>
+  <voice>
+    *: "Set As Playlist Catalog Directory"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_RESET_PLAYLISTCAT_DIR
+  desc:
+  user: core
+  <source>
+    *: "Reset Playlist Catalog Directory"
+  </source>
+  <dest>
+    *: "Reset Playlist Catalog Directory"
+  </dest>
+  <voice>
+    *: "Reset Playlist Catalog Directory"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_CURRENT_PLAYLIST
+  desc: Used when you need to say playlist, also voiced
+  user: core
+  <source>
+    *: "Current Playlist"
+  </source>
+  <dest>
+    *: "Current Playlist"
+  </dest>
+  <voice>
+    *: "Current Playlist"
+  </voice>
+</phrase>
diff --git a/apps/menus/playlist_menu.c b/apps/menus/playlist_menu.c
index a47c3b1..be3ad30 100644
--- a/apps/menus/playlist_menu.c
+++ b/apps/menus/playlist_menu.c
@@ -21,6 +21,7 @@
 
 #include <stdbool.h>
 #include <string.h>
+#include <stdio.h>
 #include "config.h"
 #include "lang.h"
 #include "action.h"
@@ -35,20 +36,28 @@
 #include "playlist_viewer.h"
 #include "talk.h"
 #include "playlist_catalog.h"
+#include "splash.h"
 
 int save_playlist_screen(struct playlist_info* playlist)
 {
-    char temp[MAX_PATH+1];
+    char temp[MAX_PATH+1], *dot;
     int len;
-
+    
     playlist_get_name(playlist, temp, sizeof(temp)-1);
     len = strlen(temp);
 
-    if (len > 4 && !strcasecmp(&temp[len-4], ".m3u"))
+    dot = strrchr(temp, '.');
+    if (!dot)
+    {
+        /* folder of some type */
+        if (temp[1] != '\0')
+            strcpy(&temp[len-1], ".m3u8");
+        else
+            snprintf(temp, sizeof(temp), "%s%s",
+                    catalog_get_directory(), DEFAULT_DYNAMIC_PLAYLIST_NAME);
+    }
+    else if (len > 4 && !strcasecmp(dot, ".m3u"))
         strcat(temp, "8");
-    
-    if (len <= 5 || strcasecmp(&temp[len-5], ".m3u8"))
-        strcpy(temp, DEFAULT_DYNAMIC_PLAYLIST_NAME);
 
     if (!kbd_input(temp, sizeof(temp)))
     {
@@ -63,27 +72,45 @@
 
 static int playlist_view_(void)
 {
-    return GO_TO_PLAYLIST_VIEWER;
+    playlist_viewer_ex(NULL);
+    return 0;
 }
 
 MENUITEM_FUNCTION(create_playlist_item, 0, ID2P(LANG_CREATE_PLAYLIST), 
                   (int(*)(void))create_playlist, NULL, NULL, Icon_NOICON);
-MENUITEM_FUNCTION(view_cur_playlist, MENU_FUNC_CHECK_RETVAL,
+MENUITEM_FUNCTION(view_cur_playlist, 0,
                   ID2P(LANG_VIEW_DYNAMIC_PLAYLIST), 
                   (int(*)(void))playlist_view_, NULL, NULL, Icon_NOICON);
 MENUITEM_FUNCTION(save_playlist, MENU_FUNC_USEPARAM, ID2P(LANG_SAVE_DYNAMIC_PLAYLIST), 
                          (int(*)(void*))save_playlist_screen, 
                         NULL, NULL, Icon_NOICON);
-MENUITEM_FUNCTION(catalog, 0, ID2P(LANG_CATALOG_VIEW), 
-                  (int(*)(void))catalog_view_playlists,
-                   NULL, NULL, Icon_NOICON);
 MENUITEM_SETTING(recursive_dir_insert, &global_settings.recursive_dir_insert, NULL);
 MENUITEM_SETTING(warn_on_erase, &global_settings.warnon_erase_dynplaylist, NULL);
+static int clear_catalog_directory(void)
+{
+    catalog_set_directory(NULL);
+    settings_save();
+    splash(HZ, ID2P(LANG_RESET_DONE_CLEAR));
+    return false;
+}
+MENUITEM_FUNCTION(clear_catalog_directory_item, 0, ID2P(LANG_RESET_PLAYLISTCAT_DIR), 
+                  clear_catalog_directory, NULL, NULL, Icon_file_view_menu);
+
+/* Playlist viewer settings submenu */
+MENUITEM_SETTING(show_icons, &global_settings.playlist_viewer_icons, NULL);
+MENUITEM_SETTING(show_indices, &global_settings.playlist_viewer_indices, NULL);
+MENUITEM_SETTING(track_display, 
+                 &global_settings.playlist_viewer_track_display, NULL);
+MAKE_MENU(viewer_settings_menu, ID2P(LANG_PLAYLISTVIEWER_SETTINGS), 
+          NULL, Icon_Playlist,
+          &show_icons, &show_indices, &track_display);
+
 
 MAKE_MENU(playlist_settings, ID2P(LANG_PLAYLISTS), NULL,
           Icon_Playlist,
-          &recursive_dir_insert, &warn_on_erase);
+          &viewer_settings_menu, &recursive_dir_insert, &warn_on_erase);
 MAKE_MENU(playlist_options, ID2P(LANG_PLAYLISTS), NULL,
           Icon_Playlist,
-          &create_playlist_item, &view_cur_playlist, &save_playlist, &catalog);
+          &create_playlist_item, &view_cur_playlist,
+          &save_playlist, &clear_catalog_directory_item);
 
diff --git a/apps/misc.h b/apps/misc.h
index 7ea5360..1e151f0 100644
--- a/apps/misc.h
+++ b/apps/misc.h
@@ -113,7 +113,8 @@
     ACTIVITY_PLUGINBROWSER,
     ACTIVITY_QUICKSCREEN,
     ACTIVITY_PITCHSCREEN,
-    ACTIVITY_OPTIONSELECT
+    ACTIVITY_OPTIONSELECT,
+    ACTIVITY_PLAYLISTBROWSER
 };
 
 #if CONFIG_CODEC == SWCODEC
diff --git a/apps/onplay.c b/apps/onplay.c
index a2a3671..da06f93 100644
--- a/apps/onplay.c
+++ b/apps/onplay.c
@@ -315,7 +315,7 @@
                   view_playlist, NULL,
                   treeplaylist_callback, Icon_Playlist);
 
-MAKE_ONPLAYMENU( tree_playlist_menu, ID2P(LANG_PLAYLIST),
+MAKE_ONPLAYMENU( tree_playlist_menu, ID2P(LANG_CURRENT_PLAYLIST),
                  treeplaylist_callback, Icon_Playlist,
                  
                  /* view */
@@ -382,6 +382,12 @@
     return action;
 }
 
+void onplay_show_playlist_menu(char* track_name)
+{
+    selected_file = track_name;
+    selected_file_attr = FILE_ATTR_AUDIO;
+    do_menu(&tree_playlist_menu, NULL, NULL, false);
+}
 
 /* playlist catalog options */
 static bool cat_add_to_a_playlist(void)
@@ -395,23 +401,37 @@
     return catalog_add_to_a_playlist(selected_file, selected_file_attr,
                                      true, NULL);
 }
+static int clipboard_callback(int action,const struct menu_item_ex *this_item);
+static bool set_catalogdir(void)
+{
+    catalog_set_directory(selected_file);
+    settings_save();
+    return false;
+}
+MENUITEM_FUNCTION(set_catalogdir_item, 0, ID2P(LANG_SET_AS_PLAYLISTCAT_DIR),
+                  set_catalogdir, NULL, clipboard_callback, Icon_Playlist);
 
 static int cat_playlist_callback(int action,
                                  const struct menu_item_ex *this_item);
-MENUITEM_FUNCTION(cat_view_lists, 0, ID2P(LANG_CATALOG_VIEW),
-                  catalog_view_playlists, 0,
-                  cat_playlist_callback, Icon_Playlist);
 MENUITEM_FUNCTION(cat_add_to_list, 0, ID2P(LANG_CATALOG_ADD_TO),
                   cat_add_to_a_playlist, 0, NULL, Icon_Playlist);
 MENUITEM_FUNCTION(cat_add_to_new, 0, ID2P(LANG_CATALOG_ADD_TO_NEW),
                   cat_add_to_a_new_playlist, 0, NULL, Icon_Playlist);
 MAKE_ONPLAYMENU(cat_playlist_menu, ID2P(LANG_CATALOG),
                 cat_playlist_callback, Icon_Playlist,
-                &cat_view_lists, &cat_add_to_list, &cat_add_to_new);
+                &cat_add_to_list, &cat_add_to_new, &set_catalogdir_item);
+
+void onplay_show_playlist_cat_menu(char* track_name)
+{
+    selected_file = track_name;
+    selected_file_attr = FILE_ATTR_AUDIO;
+    do_menu(&cat_playlist_menu, NULL, NULL, false);
+}
 
 static int cat_playlist_callback(int action,
                                  const struct menu_item_ex *this_item)
 {
+    (void)this_item;
     if (!selected_file ||
         (((selected_file_attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO) &&
          ((selected_file_attr & FILE_ATTR_MASK) != FILE_ATTR_M3U) &&
@@ -430,12 +450,7 @@
     switch (action)
     {
         case ACTION_REQUEST_MENUITEM:
-            if (this_item == &cat_view_lists)
-            {
-                return action;
-            }
-            else if ((audio_status() & AUDIO_STATUS_PLAY) ||
-                     context != CONTEXT_WPS)
+            if ((audio_status() & AUDIO_STATUS_PLAY) || context != CONTEXT_WPS)
             {
                 return action;
             }
@@ -1100,7 +1115,8 @@
                 {
                     /* only for directories */
                     if (this_item == &delete_dir_item ||
-                        this_item == &set_startdir_item
+                        this_item == &set_startdir_item ||
+                        this_item == &set_catalogdir_item
 #ifdef HAVE_RECORDING
                      || this_item == &set_recdir_item
 #endif
diff --git a/apps/onplay.h b/apps/onplay.h
index b129296..921303c 100644
--- a/apps/onplay.h
+++ b/apps/onplay.h
@@ -48,4 +48,8 @@
 };
 #endif
 
+/* needed for the playlist viewer.. eventually clean this up */
+void onplay_show_playlist_cat_menu(char* track_name);
+void onplay_show_playlist_menu(char* track_name);
+
 #endif
diff --git a/apps/playlist_catalog.c b/apps/playlist_catalog.c
index 9d4d707..3687681 100644
--- a/apps/playlist_catalog.c
+++ b/apps/playlist_catalog.c
@@ -43,6 +43,8 @@
 #include "debug.h"
 #include "playlist_catalog.h"
 #include "talk.h"
+#include "playlist_viewer.h"
+#include "bookmark.h"
 
 /* Use for recursive directory search */
 struct add_track_context {
@@ -59,9 +61,9 @@
 static bool playlist_dir_exists = false;
 
 /* Retrieve playlist directory from config file and verify it exists */
+static bool initialized = false;
 static int initialize_catalog(void)
 {
-    static bool initialized = false;
 
     if (!initialized)
     {
@@ -110,6 +112,27 @@
     return 0;
 }
 
+void catalog_set_directory(const char* directory)
+{
+    if (directory == NULL)
+    {
+        global_settings.playlist_catalog_dir[0] = '\0';
+    }
+    else
+    {
+        strcpy(global_settings.playlist_catalog_dir, directory);
+    }
+    initialized = false;
+    initialize_catalog();
+}
+
+const char* catalog_get_directory(void)
+{
+    if (initialize_catalog() == -1)
+        return "";
+    return playlist_dir;
+}
+
 /* Display all playlists in catalog.  Selected "playlist" is returned.
    If "view" mode is set then we're not adding anything into playlist. */
 static int display_playlists(char* playlist, bool view)
@@ -126,6 +149,8 @@
     browse.buf = selected_playlist;
     browse.bufsize = sizeof(selected_playlist);
 
+restart:
+    browse.flags &= ~BROWSE_SELECTED;
     rockbox_browse(&browse);
 
     if (browse.flags & BROWSE_SELECTED)
@@ -135,9 +160,12 @@
 
         if (view)
         {
-            char *filename = strrchr(selected_playlist, '/')+1;
-            /* In view mode, selecting a playlist starts playback */
-            ft_play_playlist(selected_playlist, playlist_dir, filename);
+            
+            if (!bookmark_autoload(selected_playlist))
+            {
+                if (playlist_viewer_ex(selected_playlist) == PLAYLIST_VIEWER_CANCEL)
+                    goto restart;
+            }
             result = 0;
         }
         else
@@ -311,8 +339,6 @@
             snprintf(playlist, MAX_PATH, "%s/%s.m3u8",
                      playlist_dir,
                      (name!=NULL && (sel_attr & ATTR_DIRECTORY))?name+1:"");
-            if (kbd_input(playlist, MAX_PATH))
-                return false;
         }
         else
             strcpy(playlist, m3u8name);
@@ -323,6 +349,9 @@
             strcat(playlist, "8");
         else if(len <= 5 || strcasecmp(&playlist[len-5], ".m3u8"))
             strcat(playlist, ".m3u8");
+        
+        if (kbd_input(playlist, MAX_PATH))
+            return false;
     }
     else
     {
diff --git a/apps/playlist_catalog.h b/apps/playlist_catalog.h
index 2c2a2d4..2e31712 100644
--- a/apps/playlist_catalog.h
+++ b/apps/playlist_catalog.h
@@ -21,6 +21,12 @@
 #ifndef _PLAYLIST_CATALOG_H_
 #define _PLAYLIST_CATALOG_H_
 
+/* Gets the configured playlist catalog dir */
+const char* catalog_get_directory(void);
+
+/* Set the playlist catalog dir */
+void catalog_set_directory(const char* directory);
+
 /* 
  * View list of playlists in catalog.
  *  ret : true if no error
diff --git a/apps/playlist_viewer.c b/apps/playlist_viewer.c
index aaa4559..17b9cf5 100644
--- a/apps/playlist_viewer.c
+++ b/apps/playlist_viewer.c
@@ -125,7 +125,6 @@
 
 static bool update_playlist(bool force);
 static int  onplay_menu(int index);
-static bool viewer_menu(void);
 static int save_playlist_func(void);
 
 static void playlist_buffer_init(struct playlist_buffer *pb, char *names_buffer,
@@ -437,6 +436,9 @@
     return true;
 }
 
+MENUITEM_FUNCTION(save_playlist_item, 0, ID2P(LANG_SAVE_DYNAMIC_PLAYLIST),
+                  save_playlist_func, 0, NULL, Icon_NOICON);
+
 /* Menu of playlist commands.  Invoked via ON+PLAY on main viewer screen.
    Returns -1 if USB attached, 0 if no playlist change, and 1 if playlist
    changed. */
@@ -446,9 +448,9 @@
     struct playlist_entry * current_track =
         playlist_buffer_get_track(&viewer.buffer, index);
     MENUITEM_STRINGLIST(menu_items, ID2P(LANG_PLAYLIST), NULL, 
+                        ID2P(LANG_PLAYLIST), ID2P(LANG_CATALOG),
                         ID2P(LANG_REMOVE), ID2P(LANG_MOVE),
-                        ID2P(LANG_CATALOG_ADD_TO), ID2P(LANG_CATALOG_ADD_TO_NEW),
-                        ID2P(LANG_PLAYLISTVIEWER_SETTINGS));
+                        ID2P(LANG_SAVE_DYNAMIC_PLAYLIST));
     bool current = (current_track->index == viewer.current_playing_track);
 
     result = do_menu(&menu_items, NULL, NULL, false);
@@ -465,6 +467,16 @@
         switch (result)
         {
             case 0:
+                /* playlist */
+                onplay_show_playlist_menu(current_track->name);
+                ret = 0;
+                break;
+            case 1:
+                /* add to catalog */
+                onplay_show_playlist_cat_menu(current_track->name);
+                ret = 0;
+                break;
+            case 2:
                 /* delete track */
                 playlist_delete(viewer.playlist, current_track->index);
                 if (current)
@@ -490,43 +502,22 @@
                 }
                 ret = 1;
                 break;
-            case 1:
+            case 3:
                 /* move track */
                 viewer.moving_track = index;
                 viewer.moving_playlist_index = current_track->index;
                 ret = 0;
                 break;
-            case 2: /* add to catalog */
-            case 3: /* add to a new one */
-                catalog_add_to_a_playlist(current_track->name,
-                                          FILE_ATTR_AUDIO,
-                                          result == 3, NULL);
+            case 4:
+                /* save playlist */
+                save_playlist_screen(viewer.playlist);
                 ret = 0;
                 break;
-            case 4: /* playlist viewer settings */
-                /* true on usb connect */
-                ret = viewer_menu() ? -1 : 0;
-                break;
         }
     }
     return ret;
 }
 
-/* Menu of viewer options.  Invoked via F1(r) or Menu(p). */
-MENUITEM_SETTING(show_icons, &global_settings.playlist_viewer_icons, NULL);
-MENUITEM_SETTING(show_indices, &global_settings.playlist_viewer_indices, NULL);
-MENUITEM_SETTING(track_display, 
-                 &global_settings.playlist_viewer_track_display, NULL);
-MENUITEM_FUNCTION(save_playlist_item, 0, ID2P(LANG_SAVE_DYNAMIC_PLAYLIST),
-                  save_playlist_func, 0, NULL, Icon_NOICON);
-MAKE_MENU(viewer_settings_menu, ID2P(LANG_PLAYLISTVIEWER_SETTINGS), 
-          NULL, Icon_Playlist,
-          &show_icons, &show_indices, &track_display, &save_playlist_item);
-static bool viewer_menu(void)
-{
-    return do_menu(&viewer_settings_menu, NULL, NULL, false) == MENU_ATTACHED_USB;
-}
-
 /* Save playlist to disk */
 static int save_playlist_func(void)
 {
@@ -712,7 +703,10 @@
                     gui_synclist_draw(&playlist_lists);
                 }
                 else
+                {
                     exit = true;
+                    ret = PLAYLIST_VIEWER_CANCEL;
+                }
                 break;
             }
             case ACTION_STD_OK:
@@ -739,20 +733,31 @@
                 else if (!viewer.playlist)
                 {
                     /* play new track */
-                    playlist_start(current_track->index, 0);
-                    update_playlist(false);
+                    if (!global_settings.party_mode)
+                    {
+                        playlist_start(current_track->index, 0);
+                        update_playlist(false);
+                    }
                 }
-                else
+                else if (!global_settings.party_mode)
                 {
+                    int start_index = current_track->index;
+                    if (!warn_on_pl_erase())
+                    {
+                        gui_synclist_draw(&playlist_lists);
+                        break;
+                    }
                     /* New playlist */
                     if (playlist_set_current(viewer.playlist) < 0)
                         goto exit;
-
-                    playlist_start(current_track->index, 0);
+                    if (global_settings.playlist_shuffle)
+                        start_index = playlist_shuffle(current_tick, start_index);
+                    playlist_start(start_index, 0);
 
                     /* Our playlist is now the current list */
                     if (!playlist_viewer_init(&viewer, NULL, true))
                         goto exit;
+                    exit = true;
                 }
                 gui_synclist_draw(&playlist_lists);
 
diff --git a/apps/playlist_viewer.h b/apps/playlist_viewer.h
index 97f5b0b..0a54c1b 100644
--- a/apps/playlist_viewer.h
+++ b/apps/playlist_viewer.h
@@ -29,6 +29,7 @@
 
 enum playlist_viewer_result {
     PLAYLIST_VIEWER_OK,
+    PLAYLIST_VIEWER_CANCEL,
     PLAYLIST_VIEWER_USB,
     PLAYLIST_VIEWER_MAINMENU,
 };
diff --git a/apps/root_menu.c b/apps/root_menu.c
index 3e53bd9..573ea94 100644
--- a/apps/root_menu.c
+++ b/apps/root_menu.c
@@ -60,6 +60,7 @@
 #include "bookmark.h"
 #include "playlist.h"
 #include "playlist_viewer.h"
+#include "playlist_catalog.h"
 #include "menus/exported_menus.h"
 #ifdef HAVE_RTC_ALARM
 #include "rtc.h"
@@ -335,7 +336,21 @@
             return GO_TO_ROOT;
     }
 }
-    
+
+
+static int playlist_view_catalog(void * param)
+{
+    /* kludge untill catalog_view_playlists() returns something useful */
+    int old_playstatus = audio_status();
+    (void)param;
+    push_current_activity(ACTIVITY_PLAYLISTBROWSER);
+    catalog_view_playlists();
+    pop_current_activity();
+    if (!old_playstatus && audio_status())
+        return GO_TO_WPS;
+    return GO_TO_PREVIOUS;
+}
+
 static int playlist_view(void * param)
 {
     (void)param;
@@ -397,9 +412,9 @@
     
     [GO_TO_RECENTBMARKS] =  { load_bmarks, NULL, &bookmark_settings_menu }, 
     [GO_TO_BROWSEPLUGINS] = { miscscrn, &plugin_menu, NULL },
-    [GO_TO_PLAYLISTS_SCREEN] = { miscscrn, &playlist_options,
-                                                        &playlist_settings },
-    [GO_TO_PLAYLIST_VIEWER] = { playlist_view, NULL, NULL },
+    [GO_TO_PLAYLISTS_SCREEN] = { playlist_view_catalog, NULL,
+                                                        &playlist_options },
+    [GO_TO_PLAYLIST_VIEWER] = { playlist_view, NULL, &playlist_options },
     [GO_TO_SYSTEM_SCREEN] = { miscscrn, &info_menu, &system_menu },
     
 };
@@ -415,6 +430,10 @@
 #endif
 MENUITEM_RETURNVALUE(rocks_browser, ID2P(LANG_PLUGINS), GO_TO_BROWSEPLUGINS, 
                         NULL, Icon_Plugin);
+
+MENUITEM_RETURNVALUE(playlist_browser, ID2P(LANG_CATALOG), GO_TO_PLAYLIST_VIEWER, 
+                        NULL, Icon_Playlist);
+
 static char *get_wps_item_name(int selected_item, void * data, char *buffer)
 {
     (void)selected_item; (void)data; (void)buffer;
@@ -437,7 +456,7 @@
 MENUITEM_RETURNVALUE(bookmarks, ID2P(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS),
                         GO_TO_RECENTBMARKS,  item_callback, 
                         Icon_Bookmark);
-MENUITEM_RETURNVALUE(playlists, ID2P(LANG_PLAYLISTS), GO_TO_PLAYLISTS_SCREEN,
+MENUITEM_RETURNVALUE(playlists, ID2P(LANG_CATALOG), GO_TO_PLAYLISTS_SCREEN,
                      NULL, Icon_Playlist);
 MENUITEM_RETURNVALUE(system_menu_, ID2P(LANG_SYSTEM), GO_TO_SYSTEM_SCREEN,
                      NULL, Icon_System_menu);
diff --git a/apps/tree.c b/apps/tree.c
index a9e6a6e..f38edb2 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -917,8 +917,15 @@
 {
     char filename[MAX_PATH];
 
-    snprintf(filename, sizeof filename, "%s.m3u8",
-             tc.currdir[1] ? tc.currdir : "/root");
+    if (tc.currdir[1])
+        snprintf(filename, sizeof filename, "%s.m3u8", tc.currdir);
+    else
+        snprintf(filename, sizeof filename, "%s/all.m3u8",
+                catalog_get_directory());
+        
+    
+    if (kbd_input(filename, MAX_PATH))
+        return false;
     splashf(0, "%s %s", str(LANG_CREATING), filename);
 
     trigger_cpu_boost();