Code

Added reversed and wrapped list search (find).
authorKalle Wallin <kaw@linux.se>
Fri, 26 Mar 2004 12:31:40 +0000 (12:31 +0000)
committerKalle Wallin <kaw@linux.se>
Fri, 26 Mar 2004 12:31:40 +0000 (12:31 +0000)
git-svn-id: https://svn.musicpd.org/ncmpc/trunk@497 09075e82-0dd4-0310-85a5-a0d7c8717e4f

command.c
command.h
list_window.c
list_window.h
options.c
options.h
screen_file.c
screen_help.c
screen_play.c
screen_utils.c
screen_utils.h

index 67e1a6975034d362d149f57cf960349392e96ee5..73623b95534840c46b11e51f9fb498b4a3f59a1a 100644 (file)
--- a/command.c
+++ b/command.c
@@ -43,7 +43,7 @@
 static command_definition_t cmds[] =
 {
   { {  13,   0,   0 }, CMD_PLAY, "Play/Enter directory" },
-  { { 'p',   0,   0 }, CMD_PAUSE, "Pause" },
+  { { 'P',   0,   0 }, CMD_PAUSE, "Pause" },
   { {  BS, ESC,   0 }, CMD_STOP, "Stop" },
   { { '>',   0,   0 }, CMD_TRACK_NEXT, "Next song" },
   { { '<',   0,   0 }, CMD_TRACK_PREVIOUS, "Previous song" },
@@ -51,12 +51,16 @@ static command_definition_t cmds[] =
   { { '+', RGHT,  0 }, CMD_VOLUME_UP, "Increase volume" },
   { { '-', LEFT,  0 }, CMD_VOLUME_DOWN, "Decrease volume" },
 
-  { { ' ',   0,  0 }, CMD_SELECT, "Select/deselect song in playlist" },
+  { { 'w',   0,   0 }, CMD_TOGGLE_FIND_WRAP, "Toggle find mode" },
+
+  { { ' ',   0,   0 }, CMD_SELECT, "Select/deselect song in playlist" },
   { { DEL,   0,   0 }, CMD_DELETE, "Delete song from playlist" },
   { { 's',   0,   0 }, CMD_SHUFFLE, "Shuffle playlist" },
   { { 'c',   0,   0 }, CMD_CLEAR, "Clear playlist" },
   { { 'r',   0,   0 }, CMD_REPEAT, "Toggle repeat mode" },
   { { 'z',   0,   0 }, CMD_RANDOM, "Toggle random mode" },
+  { { 'S',   0,   0 }, CMD_SAVE_PLAYLIST, "Save playlist" },
+  { { 'D',   0,   0 }, CMD_DELETE_PLAYLIST, "Delete playlist" },
 
   { {  UP,   0,   0 }, CMD_LIST_PREVIOUS,      "Move: Up" },
   { { DWN,   0,   0 }, CMD_LIST_NEXT,          "Move: Down" },
@@ -64,8 +68,10 @@ static command_definition_t cmds[] =
   { { END,   0,   0 }, CMD_LIST_LAST,          "Move: End" },
   { { PGUP,  0,   0 }, CMD_LIST_PREVIOUS_PAGE, "Move: Page Up" },
   { { PGDN,  0,   0 }, CMD_LIST_NEXT_PAGE,     "Move: Page Down" },
-  { { '/',   0,   0 }, CMD_LIST_FIND,          "Find" },
-  { { 'n',   0,   0 }, CMD_LIST_FIND_NEXT,     "Find Next" },
+  { { '/',   0,   0 }, CMD_LIST_FIND,          "Forward Find" },
+  { { 'n',   0,   0 }, CMD_LIST_FIND_NEXT,     "Forward Find Next" },
+  { { '?',   0,   0 }, CMD_LIST_RFIND,         "Backward Find" },
+  { { 'p',   0,   0 }, CMD_LIST_RFIND_NEXT,    "Backward Find Previous" },
 
   { { TAB,   0,   0 }, CMD_SCREEN_NEXT,   "Next screen" },
   { { STAB,  0,   0 }, CMD_SCREEN_PREVIOUS, "Previous screen" },
@@ -204,8 +210,8 @@ get_keyboard_command(void)
 
   DK(fprintf(stderr, "key = 0x%02X\t", key));
 
-  if( isalpha(key) )
-    key=tolower(key);
+  //  if( isalpha(key) )
+  //    key=tolower(key);
 
   i=0;
   while( cmds[i].description )
index 1ad7b1dfe23b8cc01ce52b8dc2285e653bc41317..1672316f7f2d353abb5cd217f2a70aa16c955684 100644 (file)
--- a/command.h
+++ b/command.h
@@ -15,6 +15,9 @@ typedef enum
   CMD_REPEAT,
   CMD_VOLUME_UP,
   CMD_VOLUME_DOWN,
+  CMD_SAVE_PLAYLIST,
+  CMD_DELETE_PLAYLIST,
+  CMD_TOGGLE_FIND_WRAP,
   CMD_LIST_PREVIOUS,
   CMD_LIST_NEXT,
   CMD_LIST_FIRST,
@@ -23,6 +26,8 @@ typedef enum
   CMD_LIST_PREVIOUS_PAGE,
   CMD_LIST_FIND,
   CMD_LIST_FIND_NEXT,
+  CMD_LIST_RFIND,
+  CMD_LIST_RFIND_NEXT,
   CMD_SCREEN_PREVIOUS,
   CMD_SCREEN_NEXT,
   CMD_SCREEN_PLAY,
index 21ee9119fc3f5b95fdf5c2a0c2bdd9acadeb23ce..ee08a8b8134d2582a840594905511d7955669065 100644 (file)
@@ -150,20 +150,58 @@ int
 list_window_find(list_window_t *lw, 
                 list_window_callback_fn_t callback,
                 void *callback_data,
-                char *str)
+                char *str,
+                int wrap)
 {
   int h;
   int i = lw->selected+1;
   char *label;
+  
+  while( wrap || i==lw->selected+1 )
+    {
+      while( (label=(callback) (i,&h,callback_data)) )
+       {
+         if( str && label && strcasestr(label, str) )
+           {
+             lw->selected = i;
+             return 0;
+           }
+         i++;
+         if( wrap && i==lw->selected )
+           return 1;
+       }
+      i=0; /* first item */
+    }
+  return 1;
+}
 
-  while( (label=(callback) (i,&h,callback_data)) )
+
+int
+list_window_rfind(list_window_t *lw, 
+                 list_window_callback_fn_t callback,
+                 void *callback_data,
+                 char *str,
+                 int wrap,
+                 int rows)
+{
+  int h;
+  int i = lw->selected-1;
+  char *label;
+
+  while( wrap || i==lw->selected-1 )
     {
-      if( str && label && strcasestr(label, str) )
+      while( i>=0 && (label=(callback) (i,&h,callback_data)) )
        {
-         lw->selected = i;
-         return 0;
+         if( str && label && strcasestr(label, str) )
+           {
+             lw->selected = i;
+             return 0;
+           }
+         i--;
+         if( wrap && i==lw->selected )
+           return 1;
        }
-      i++;
+      i=rows-1; /* last item */
     }
   return 1;
 }
@@ -204,3 +242,5 @@ list_window_cmd(list_window_t *lw, int rows, command_t cmd)
     }
   return 1;
 }
+
+
index 87bbf826daff30579db2b7046623523d81b8c4dd..ce799c1bdd6794a62fd985aa9675e3158f696dc6 100644 (file)
@@ -49,6 +49,16 @@ void list_window_next_page(list_window_t *lw, int length);
 int  list_window_find(list_window_t *lw, 
                      list_window_callback_fn_t callback,
                      void *callback_data,
-                     char *str);
+                     char *str,
+                     int wrap);
+
+/* find a string in a list window (reversed) */
+int
+list_window_rfind(list_window_t *lw, 
+                 list_window_callback_fn_t callback,
+                 void *callback_data,
+                 char *str,
+                 int wrap,
+                 int rows);
 
 #endif
index 8f684a10845b87f899ee451fa0db5c8d3d56a004..f1840325b56440baddcf08c6d70804a68dd52db6 100644 (file)
--- a/options.c
+++ b/options.c
@@ -105,7 +105,9 @@ options_init( void )
     options.port = atoi(value);
   else
     options.port = DEFAULT_PORT;
+
   options.reconnect = 1;
+  options.find_wrap = 1;
 
   options.bg_color       = COLOR_BLACK;
   options.title_color    = COLOR_BLUE;
index a8ac179817ae6d348340b36be30ffd5f964834a4..cb346374dffff402736bb239a645e2198f23bec7 100644 (file)
--- a/options.h
+++ b/options.h
@@ -11,6 +11,7 @@ typedef struct
   int   port;
   int   reconnect;
   int   debug;
+  int   find_wrap;
 
   int   enable_colors;
   int   bg_color;
index 9d2dffbc8dfe6dca9eb6660a0a40e8f2bb91a32b..e3de2d051aa8853114b13e010fee5621fe1cda58 100644 (file)
@@ -31,7 +31,7 @@ list_callback(int index, int *highlight, void *data)
 
   if( entity == NULL )
     {
-      return "[Back]";
+      return "[..]";
     }
   if( entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY ) 
     {
@@ -52,7 +52,7 @@ list_callback(int index, int *highlight, void *data)
       mpd_PlaylistFile *plf = entity->info.playlistFile;
       char *filename = utf8_to_locale(basename(plf->path));
       
-      snprintf(buf, BUFSIZE, "%s*", filename);
+      snprintf(buf, BUFSIZE, "*%s*", filename);
       free(filename);
       return buf;
     }
@@ -342,29 +342,17 @@ file_cmd(screen_t *screen, mpd_client_t *c, command_t cmd)
          cmd = CMD_LIST_NEXT;
        }
       break;
+    case CMD_DELETE_PLAYLIST:
+      screen_status_printf("Sorry, command not implemented yet!");
+      return 1;
+      break;
     case CMD_LIST_FIND:
-      if( screen->findbuf )
-       {
-         free(screen->findbuf);
-         screen->findbuf=NULL;
-       }
-      /* continue... */
+    case CMD_LIST_RFIND:
     case CMD_LIST_FIND_NEXT:
-      if( !screen->findbuf )
-       screen->findbuf=screen_readln(screen->status_window.w, "/");
-      if( list_window_find(screen->filelist,
-                          list_callback,
-                          c,
-                          screen->findbuf) == 0 )
-       {
-         screen->filelist->repaint  = 1;
-       }
-      else
-       {
-         screen_status_printf("Unable to find \'%s\'", screen->findbuf);
-         beep();
-       }
-      return 1;
+    case CMD_LIST_RFIND_NEXT:
+      return screen_find(screen, c, 
+                        screen->filelist, c->filelist_length,
+                        cmd, list_callback);
     default:
       break;
     }
index 5320647be47712913f75dedb72aba36ceab974cd..34a007c0af1a53dbce9c36f7238d1e11ae90b53b 100644 (file)
@@ -32,7 +32,10 @@ static help_text_row_t help_text[] =
   { 0, CMD_LIST_NEXT,      "Move cursor up" },
   { 0, CMD_LIST_PREVIOUS,  "Move cursor down" },
   { 0, CMD_LIST_FIND,      "Find" },
-  { 0, CMD_LIST_FIND_NEXT, "Find again" },
+  { 0, CMD_LIST_RFIND,     "find backward" },
+  { 0, CMD_LIST_FIND_NEXT, "Find next" },
+  { 0, CMD_LIST_RFIND_NEXT,"Find previuos" },
+  { 0, CMD_TOGGLE_FIND_WRAP, "Toggle find mode" },
   { 0, CMD_NONE, " " },
   { 0, CMD_SCREEN_NEXT,   "Change screen" },
   { 0, CMD_SCREEN_HELP,   "Help screen" },
@@ -43,18 +46,20 @@ static help_text_row_t help_text[] =
   { 0, CMD_NONE, " " },
   { 1, CMD_NONE, "    Keys - Playlist screen " },
   { 0, CMD_NONE, "  --------------------------" },
-  { 0, CMD_PLAY,    "Play selected entry" },
-  { 0, CMD_DELETE,  "Delete selected entry from platlist" },
-  { 0, CMD_SHUFFLE, "Shuffle playlist" },
-  { 0, CMD_CLEAR,   "Clear playlist" },
-  { 0, CMD_REPEAT,  "Toggle repeat mode" },
-  { 0, CMD_RANDOM,  "Toggle random mode" },
+  { 0, CMD_PLAY,           "Play selected entry" },
+  { 0, CMD_DELETE,         "Delete selected entry from playlist" },
+  { 0, CMD_SHUFFLE,        "Shuffle playlist" },
+  { 0, CMD_CLEAR,          "Clear playlist" },
+  { 0, CMD_SAVE_PLAYLIST,  "Save playlist" },
+  { 0, CMD_REPEAT,         "Toggle repeat mode" },
+  { 0, CMD_RANDOM,         "Toggle random mode" },
   { 0, CMD_NONE, " " },
   { 0, CMD_NONE, " " },
   { 1, CMD_NONE, "    Keys - Browse screen " },
   { 0, CMD_NONE, "  ------------------------" },
-  { 0, CMD_PLAY,   "Change to selected directory" },
-  { 0, CMD_SELECT, "Add/Remove selected file" },
+  { 0, CMD_PLAY,            "Enter directory/Load playlist" },
+  { 0, CMD_SELECT,          "Add/remove song from playlist" },
+  { 0, CMD_DELETE_PLAYLIST, "Delete playlist" },
   { 0, CMD_NONE, " " },
   { 0, CMD_NONE, " " },
   { 1, CMD_NONE, " " PACKAGE " version " VERSION },
@@ -131,33 +136,13 @@ help_update(screen_t *screen, mpd_client_t *c)
 int 
 help_cmd(screen_t *screen, mpd_client_t *c, command_t cmd)
 {
- switch(cmd)
-    {
-    case CMD_LIST_FIND:
-      if( screen->findbuf )
-       {
-         free(screen->findbuf);
-         screen->findbuf=NULL;
-       }
-      /* continue... */
-    case CMD_LIST_FIND_NEXT:
-      if( !screen->findbuf )
-       screen->findbuf=screen_readln(screen->status_window.w, "/");
-      if( list_window_find(screen->helplist,
-                          list_callback,
-                          c,
-                          screen->findbuf) == 0 )
-       {
-         screen->helplist->repaint  = 1;
-       }
-      else
-       {
-         screen_status_printf("Unable to find \'%s\'", screen->findbuf);
-         beep();
-       }
-      return 1;
-    default:
-      break;
-    }
-  return list_window_cmd(screen->helplist, help_text_rows, cmd);
+  int retval;
+
+  retval = list_window_cmd(screen->helplist, help_text_rows, cmd);
+  if( !retval )
+    return screen_find(screen, c, 
+                      screen->helplist, help_text_rows,
+                      cmd, list_callback);
+
+  return retval;
 }
index 48dc86961130fd940a3f0dab24869a6bb28d501f..c52c2d1651a8b0463493ae0a0e6f028df00f8a15 100644 (file)
@@ -92,29 +92,16 @@ play_cmd(screen_t *screen, mpd_client_t *c, command_t cmd)
       screen_status_printf("Removed \'%s\' from playlist!",
                           mpc_get_song_name(song));
       return 1;
+    case CMD_SAVE_PLAYLIST:
+      screen_status_printf("Sorry, playlist saving not implemented yet!");
+      return 1;
     case CMD_LIST_FIND:
-      if( screen->findbuf )
-       {
-         free(screen->findbuf);
-         screen->findbuf=NULL;
-       }
-      /* continue... */
+    case CMD_LIST_RFIND:
     case CMD_LIST_FIND_NEXT:
-      if( !screen->findbuf )
-       screen->findbuf=screen_readln(screen->status_window.w, "/");
-      if( list_window_find(screen->playlist,
-                          list_callback,
-                          c,
-                          screen->findbuf) == 0 )
-       {
-         screen->playlist->repaint  = 1;
-       }
-      else
-       {
-         screen_status_printf("Unable to find \'%s\'", screen->findbuf);
-         beep();
-       }
-      return 1;
+    case CMD_LIST_RFIND_NEXT:
+      return screen_find(screen, c, 
+                        screen->playlist, c->playlist_length,
+                        cmd, list_callback);
     default:
       break;
     }
index 648291f03af4be47f49098edb5edda76dc0b7266..9feda742abafe63344da2807c76f24a6a2a05ccd 100644 (file)
@@ -9,8 +9,12 @@
 #include "support.h"
 #include "command.h"
 #include "options.h"
+#include "list_window.h"
 #include "screen.h"
 
+#define FIND_PROMPT  "Find: "
+#define RFIND_PROMPT "Find backward: "
+
 char *
 screen_readln(WINDOW *w, char *prompt)
 {
@@ -34,6 +38,70 @@ screen_readln(WINDOW *w, char *prompt)
   return line;
 }
 
+
+/* query user for a string and find it in a list window */
+int 
+screen_find(screen_t *screen,
+           mpd_client_t *c,
+           list_window_t *lw, 
+           int rows,
+           command_t findcmd,
+           list_window_callback_fn_t callback_fn)
+{
+  int reversed = 0;
+  int retval   = 0;
+  char *prompt = FIND_PROMPT;
+
+  if( findcmd==CMD_LIST_RFIND ||findcmd==CMD_LIST_RFIND_NEXT ) 
+    {
+      prompt = RFIND_PROMPT;
+      reversed = 1;
+    }
+
+  switch(findcmd)
+    {
+    case CMD_LIST_FIND:
+    case CMD_LIST_RFIND:
+      if( screen->findbuf )
+       {
+         free(screen->findbuf);
+         screen->findbuf=NULL;
+       }
+      /* continue... */
+    case CMD_LIST_FIND_NEXT:
+    case CMD_LIST_RFIND_NEXT:
+      if( !screen->findbuf )
+       screen->findbuf=screen_readln(screen->status_window.w, prompt);
+      if( reversed )
+       retval = list_window_rfind(lw, 
+                                  callback_fn,
+                                  c, 
+                                  screen->findbuf,
+                                  options.find_wrap,
+                                  rows);
+      else
+       retval = list_window_find(lw,
+                                 callback_fn,
+                                 c,
+                                 screen->findbuf,
+                                 options.find_wrap);
+      if( retval == 0 )
+       {
+         lw->repaint  = 1;
+       }
+      else
+       {
+         screen_status_printf("Unable to find \'%s\'", screen->findbuf);
+         beep();
+       }
+      return 1;
+    default:
+      break;
+    }
+  return 0;
+}
+
+
 int
 my_waddstr(WINDOW *w, const char *text, int color)
 {
@@ -61,3 +129,4 @@ my_mvwaddstr(WINDOW *w, int x, int y, const char *text, int color)
 
   return ret;
 }
+
index a03c36d477a2fd1e9f84febecd5c3a22c961d621..87cb6e04cf4c6501ba8f92835a7141af85d1dd39 100644 (file)
@@ -1,5 +1,15 @@
 
+/* read a string from the status window */
 char *screen_readln(WINDOW *w, char *prompt);
 
+/* query user for a string and find it in a list window */
+int screen_find(screen_t *screen,
+               mpd_client_t *c,
+               list_window_t *lw, 
+               int rows,
+               command_t findcmd,
+               list_window_callback_fn_t callback_fn);
+
+
 int my_waddstr(WINDOW *, const char *, int);
 int my_mvwaddstr(WINDOW *, int, int, const char *, int);