diff --git a/apps/filetree.c b/apps/filetree.c
index b7f3c9e..011d509 100644
--- a/apps/filetree.c
+++ b/apps/filetree.c
@@ -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,7 @@ int ft_enter(struct tree_context* c)
 
         switch ( file->attr & FILE_ATTR_MASK ) {
             case FILE_ATTR_M3U:
-                play = ft_play_playlist(buf, c->currdir, file->name);
-                
-                if (play)
-                {
-                    start_index = 0;
-                }
-
+                playlist_viewer_ex(buf);
                 break;
 
             case FILE_ATTR_AUDIO:
diff --git a/apps/menus/playlist_menu.c b/apps/menus/playlist_menu.c
index a47c3b1..fbafdb1 100644
--- a/apps/menus/playlist_menu.c
+++ b/apps/menus/playlist_menu.c
@@ -63,27 +63,35 @@ int save_playlist_screen(struct playlist_info* playlist)
 
 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);
 
+/* 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);
 
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 @@ enum current_activity {
     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..985a2fb 100644
--- a/apps/onplay.c
+++ b/apps/onplay.c
@@ -382,6 +382,12 @@ static int treeplaylist_callback(int action,
     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)
@@ -398,20 +404,25 @@ static bool cat_add_to_a_new_playlist(void)
 
 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);
+
+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 +441,7 @@ static int cat_playlist_callback(int action,
     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;
             }
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 @@ enum hotkey_action {
 };
 #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..a281f26 100644
--- a/apps/playlist_catalog.c
+++ b/apps/playlist_catalog.c
@@ -43,6 +43,7 @@
 #include "debug.h"
 #include "playlist_catalog.h"
 #include "talk.h"
+#include "playlist_viewer.h"
 
 /* Use for recursive directory search */
 struct add_track_context {
@@ -120,12 +121,14 @@ static int display_playlists(char* playlist, bool view)
 
     browse_context_init(&browse, SHOW_M3U,
                         BROWSE_SELECTONLY|(view? 0: BROWSE_NO_CONTEXT_MENU),
-                        str(LANG_CATALOG), NOICON,
+                        str(LANG_PLAYLISTS), NOICON,
                         playlist_dir, most_recent_playlist);
 
     browse.buf = selected_playlist;
     browse.bufsize = sizeof(selected_playlist);
 
+restart:
+    browse.flags &= ~BROWSE_SELECTED;
     rockbox_browse(&browse);
 
     if (browse.flags & BROWSE_SELECTED)
@@ -135,9 +138,8 @@ static int display_playlists(char* playlist, bool view)
 
         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 (playlist_viewer_ex(selected_playlist) == PLAYLIST_VIEWER_CANCEL)
+                goto restart;
             result = 0;
         }
         else
diff --git a/apps/playlist_viewer.c b/apps/playlist_viewer.c
index aaa4559..e9089a7 100644
--- a/apps/playlist_viewer.c
+++ b/apps/playlist_viewer.c
@@ -125,7 +125,6 @@ static void format_line(const struct playlist_entry* track, char* str,
 
 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 @@ static bool update_playlist(bool force)
     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 @@ static int onplay_menu(int index)
     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 @@ static int onplay_menu(int index)
         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 @@ static int onplay_menu(int index)
                 }
                 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 @@ enum playlist_viewer_result playlist_viewer_ex(const char* filename)
                     gui_synclist_draw(&playlist_lists);
                 }
                 else
+                {
                     exit = true;
+                    ret = PLAYLIST_VIEWER_CANCEL;
+                }
                 break;
             }
             case ACTION_STD_OK:
@@ -744,15 +738,18 @@ enum playlist_viewer_result playlist_viewer_ex(const char* filename)
                 }
                 else
                 {
+                    int start_index = current_track->index;
                     /* 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 @@ bool search_playlist(void);
 
 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..e9a1f33 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 @@ static int miscscrn(void * param)
             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 @@ static const struct root_items items[] = {
     
     [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 @@ MENUITEM_RETURNVALUE(db_browser, ID2P(LANG_TAGCACHE), GO_TO_DBBROWSER,
 #endif
 MENUITEM_RETURNVALUE(rocks_browser, ID2P(LANG_PLUGINS), GO_TO_BROWSEPLUGINS, 
                         NULL, Icon_Plugin);
+
+MENUITEM_RETURNVALUE(playlist_browser, ID2P(LANG_PLAYLISTS), 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;
