Code

spelling fixes by avuton
[ncmpc.git] / src / screen_search.c
index 03ce11ad6370e7d8b83f01cacf31f1886862b966..3f07d47682056d1b6016b6ffbd6e85d7d3711231 100644 (file)
 #include "strfsong.h"
 #include "command.h"
 #include "screen.h"
+#include "utils.h"
 #include "screen_utils.h"
 #include "screen_browse.h"
 
-#define SEARCH_TITLE  0
-#define SEARCH_ARTIST 1
-#define SEARCH_ALBUM  2
-#define SEARCH_FILE   3
+/* new search stuff with qball's libmpdclient */
+#define FUTURE
+
+
+#ifdef FUTURE
+
+extern gint mpdclient_finish_command(mpdclient_t *c);
+
+typedef struct
+{
+  int id;
+  char *name;
+  char *localname;
+} search_tag_t;
+
+static search_tag_t search_tag[] = {
+  { MPD_TAG_ITEM_ARTIST,   "artist",    N_("artist") },
+  { MPD_TAG_ITEM_ALBUM,    "album",     N_("album") },
+  { MPD_TAG_ITEM_TITLE,    "title",     N_("title") },
+  { MPD_TAG_ITEM_TRACK,    "track",     N_("track") },
+  { MPD_TAG_ITEM_NAME,     "name",      N_("name") },
+  { MPD_TAG_ITEM_GENRE,    "genre",     N_("genre") },
+  { MPD_TAG_ITEM_DATE,     "date",      N_("date") },
+  { MPD_TAG_ITEM_COMPOSER, "composer",  N_("composer") },
+  { MPD_TAG_ITEM_PERFORMER,"performer", N_("performer") },
+  { MPD_TAG_ITEM_COMMENT,  "comment",   N_("comment") },
+  { MPD_TAG_ITEM_FILENAME, "filename",  N_("file") },
+  { -1,                    NULL,        NULL }
+};
+
+static int
+search_get_tag_id(char *name)
+{
+  int i;
+
+  i=0;
+  while( search_tag[i].name )
+    {
+      if( strcasecmp(search_tag[i].name, name)==0 || 
+         strcasecmp(search_tag[i].localname, name)==0 )
+       return search_tag[i].id;
+      i++;
+    }
+  return -1;
+}
+
+#endif
+
+
+#define SEARCH_TITLE    0
+#define SEARCH_ARTIST   1
+#define SEARCH_ALBUM    2
+#define SEARCH_FILE     3
 
 typedef struct {
   int table;
@@ -56,7 +106,44 @@ static search_type_t mode[] = {
 
 static list_window_t *lw = NULL;
 static mpdclient_filelist_t *filelist = NULL;
+static GList *search_history = NULL;
 static gchar *pattern = NULL;
+static gboolean advanced_search_mode = FALSE;
+
+
+/* search info */
+static char *
+lw_search_help_callback(int index, int *highlight, void *data)
+{
+  int text_rows;
+  static char *text[] = {
+    "Welcome to ncmpc's search screen - SVN version.",
+    "",
+    "Quick search - just enter a string and ncmpc will search according",
+    "               to the current search mode (displayed above).",
+    "",
+    "Advanced - bla bla bla.... syntax below",
+    ""
+    " <tag>:<search term> [<tag>:<search term>...]",
+    "",
+    "Example: artist:radiohead album:pablo honey",
+    "",
+    "##### SOMEONE - Write a proper help text, please! #####",
+    "",
+    "avalible tags: artist, album, title, track, name, genre, date",
+    "               composer, performer, comment, file",
+    "",
+    NULL
+  };
+
+  text_rows=0;
+  while( text[text_rows] )
+    text_rows++;
+  
+  if( index < text_rows )
+    return text[index];
+  return NULL;
+}
 
 /* the playlist have been updated -> fix highlights */
 static void 
@@ -105,6 +192,128 @@ search_clear(screen_t *screen, mpdclient_t *c, gboolean clear_pattern)
     }
 }
 
+#ifdef FUTURE
+/*-----------------------------------------------------------------------
+ * NOTE: This code exists to test a new search ui,
+ *       Its ugly and MUST be redesigned before the next release!
+ *-----------------------------------------------------------------------
+ */
+static mpdclient_filelist_t *
+search_advanced_query(char *query, mpdclient_t *c)
+{
+  int i,j;
+  char **strv;
+  int table[10];
+  char *arg[10];
+  mpdclient_filelist_t *filelist = NULL;
+
+  advanced_search_mode = FALSE;
+  if( g_strrstr(query, ":") == NULL )
+    return NULL;
+  
+  strv = g_strsplit_set(query, ": ", 0);
+
+  i=0;
+  while( strv[i] )
+    {
+      D("strv[%d] = \"%s\"\n", i, strv[i]);
+      i++;
+    }
+
+  memset(table, 0, 10*sizeof(int));
+  memset(arg,   0, 10*sizeof(char *));
+
+  i=0;
+  j=0;
+  while( strv[i] && strlen(strv[i])>0 && i<9 )
+    {
+      D("strv[%d] = \"%s\"\n", i, strv[i]);
+
+      int id = search_get_tag_id(strv[i]);
+      if( id==-1 )
+       {
+         if( table[j] )
+           {
+             char *tmp = arg[j];
+             arg[j] = g_strdup_printf("%s %s", arg[j], strv[i]);
+             g_free(tmp);
+           }
+         else
+           {
+             D("Bad search tag %s\n", strv[i]);
+             screen_status_printf(_("Bad search tag %s"), strv[i]);
+           }
+         i++;
+       }
+      else if( strv[i+1] == NULL || strlen(strv[i+1])==0 )
+       {
+         D("No argument for search tag %s\n", strv[i]);
+         screen_status_printf(_("No argument for search tag %s"), strv[i]);
+         i++;
+         //      j--;
+         //table[j] = -1;
+       }
+      else
+       {
+         table[j] = id;
+         arg[j] = locale_to_utf8(strv[i+1]); // FREE ME
+         j++;
+         table[j] = -1;
+         arg[j] = NULL;
+         i = i + 2;
+         advanced_search_mode = TRUE;
+       }     
+    }
+
+  g_strfreev(strv);
+
+
+  if( advanced_search_mode && j>0 )
+    {
+      /*-----------------------------------------------------------------------
+       * NOTE (again): This code exists to test a new search ui,
+       *               Its ugly and MUST be redesigned before the next release!
+       *             + the code below should live in mpdclient.c
+       *-----------------------------------------------------------------------
+       */
+      mpd_InfoEntity *entity;
+
+      /** stupid - but this is just a test...... (fulhack)  */
+         int iter;
+         for(iter = 0; i < 10; i++)
+         {
+                 mpd_addConstraintSearch(c->connection, table[i], arg[i]);
+         }               
+                       
+         mpd_commitSearch(c->connection);
+         
+      filelist = g_malloc0(sizeof(mpdclient_filelist_t));
+
+      while( (entity=mpd_getNextInfoEntity(c->connection)) ) 
+       {
+         filelist_entry_t *entry = g_malloc0(sizeof(filelist_entry_t));
+      
+         entry->entity = entity;
+         filelist->list = g_list_append(filelist->list, (gpointer) entry);
+         filelist->length++;
+       }
+  
+      if( mpdclient_finish_command(c) && filelist )
+       filelist = mpdclient_filelist_free(filelist);
+
+      filelist->updated = TRUE;
+    } 
+  
+  i=0;
+  while( arg[i] )
+    g_free(arg[i++]);
+
+  return filelist;
+}
+#else
+#define search_advanced_query(pattern,c) (NULL)
+#endif
+
 static void
 search_new(screen_t *screen, mpdclient_t *c)
 {
@@ -113,7 +322,7 @@ search_new(screen_t *screen, mpdclient_t *c)
   pattern = screen_readln(screen->status_window.w, 
                          _("Search: "),
                          NULL,
-                         NULL,
+                         &search_history,
                          NULL);
 
   if( pattern && strcmp(pattern,"")==0 )
@@ -128,15 +337,20 @@ search_new(screen_t *screen, mpdclient_t *c)
       return;
     }
 
-  filelist = mpdclient_filelist_search(c, 
-                                      FALSE,
-                                      mode[options.search_mode].table,
-                                      pattern);
+  if( !MPD_VERSION_LT(c, 0, 12, 0) )
+    filelist = search_advanced_query(pattern, c);
+  if( !advanced_search_mode && filelist==NULL )
+    filelist = mpdclient_filelist_search(c, 
+                                        FALSE,
+                                        mode[options.search_mode].table,
+                                        pattern);
   sync_highlights(c, filelist);
   mpdclient_install_playlist_callback(c, playlist_changed_callback);
   list_window_check_selected(lw, filelist->length);
 }
 
+
+
 static void
 init(WINDOW *w, int cols, int rows)
 {
@@ -146,6 +360,8 @@ init(WINDOW *w, int cols, int rows)
 static void
 quit(void)
 {
+  if( search_history )
+    string_list_free(search_history);
   if( filelist )
     filelist = mpdclient_filelist_free(filelist);
   list_window_free(lw);
@@ -157,10 +373,10 @@ quit(void)
 static void
 open(screen_t *screen, mpdclient_t *c)
 {
-  if( pattern==NULL )
-    search_new(screen, c);
-  else
-    screen_status_printf(_("Press %s for a new search"),
+  //  if( pattern==NULL )
+  //    search_new(screen, c);
+  // else
+  screen_status_printf(_("Press %s for a new search"),
                         get_key_names(CMD_SCREEN_SEARCH,0));
   search_check_mode();
 }
@@ -184,13 +400,18 @@ paint(screen_t *screen, mpdclient_t *c)
   
   if( filelist )
     {
+      lw->flags = 0;
       list_window_paint(lw, browse_lw_callback, (void *) filelist);
       filelist->updated = FALSE;
     }
   else
     {
-      wmove(lw->w, 0, 0);
-      wclrtobot(lw->w);
+      lw->flags = LW_HIDE_CURSOR;
+      list_window_paint(lw, lw_search_help_callback, NULL);
+      if( !MPD_VERSION_LT(c, 0, 12, 0) )
+       g_strdup_printf("Advanced search disabled (MPD version < 0.12.0"); 
+      //      wmove(lw->w, 0, 0);
+      //wclrtobot(lw->w);
     }
   wnoutrefresh(lw->w);
 }
@@ -210,7 +431,9 @@ update(screen_t *screen, mpdclient_t *c)
 static char *
 get_title(char *str, size_t size)
 {
-  if( pattern )
+  if( advanced_search_mode && pattern )
+    g_snprintf(str, size, _("Search: %s"), pattern);
+  else if( pattern )
     g_snprintf(str, size, 
               _("Search: Results for %s [%s]"), 
               pattern,