Code

go to root/parent dir key added
[ncmpc.git] / src / screen_file.c
index aff58a526e01a0f0ffe66db216d763d053dd9232..4a4bdf70c1bcb0b65b5842cf5ba1c2d13a71bbbd 100644 (file)
@@ -34,7 +34,7 @@
 #include "screen.h"
 #include "screen_utils.h"
 #include "screen_browse.h"
-
+#include "screen_play.h"
 
 #define USE_OLD_LAYOUT
 #undef  USE_OLD_ADD
@@ -45,7 +45,7 @@
 
 
 static list_window_t *lw = NULL;
-static GList *lw_state_list = NULL;
+static list_window_state_t *lw_state = NULL;
 static mpdclient_filelist_t *filelist = NULL;
 
 
@@ -153,31 +153,6 @@ playlist_changed_callback(mpdclient_t *c, int event, gpointer data)
     }
 }
 
-/* store current state when entering a subdirectory */
-static void
-push_lw_state(void)
-{
-  list_window_t *tmp = g_malloc(sizeof(list_window_t));
-
-  memcpy(tmp, lw, sizeof(list_window_t));
-  lw_state_list = g_list_prepend(lw_state_list, (gpointer) tmp);
-}
-
-/* get previous state when leaving a directory */
-static void
-pop_lw_state(void)
-{
-  if( lw_state_list )
-    {
-      list_window_t *tmp = lw_state_list->data;
-
-      memcpy(lw, tmp, sizeof(list_window_t));
-      g_free(tmp);
-      lw_state_list->data = NULL;
-      lw_state_list = g_list_delete_link(lw_state_list, lw_state_list);
-    }
-}
-
 /* list_window callback */
 char *
 browse_lw_callback(int index, int *highlight, void *data)
@@ -227,28 +202,41 @@ browse_lw_callback(int index, int *highlight, void *data)
       g_free(filename);
       return buf;
     }
-  return "Error: Unknow entry!";
+  return "Error: Unknown entry!";
 }
 
 /* chdir */
 static int
-change_directory(screen_t *screen, mpdclient_t *c, filelist_entry_t *entry)
+change_directory(screen_t *screen, mpdclient_t *c, filelist_entry_t *entry, char *new_path)
 {
-  mpd_InfoEntity *entity = entry->entity;
+  mpd_InfoEntity *entity = NULL;
   gchar *path = NULL;
 
+  if( entry!=NULL )
+    entity = entry->entity;
+  else if( new_path==NULL )
+    return -1;
+
   if( entity==NULL )
     {
-      /* return to parent */
-      char *parent = g_path_get_dirname(filelist->path);
-      if( strcmp(parent, ".") == 0 )
+      if( entry || 0==strcmp(new_path, "..") )
        {
-         parent[0] = '\0';
+         /* return to parent */
+         char *parent = g_path_get_dirname(filelist->path);
+         if( strcmp(parent, ".") == 0 )
+           {
+             parent[0] = '\0';
+           }
+         path = g_strdup(parent);
+       }
+      else
+       {
+         /* entry==NULL, then new_path ("" is root) */
+         path = g_strdup(new_path);
        }
-      path = g_strdup(parent);
       list_window_reset(lw);
       /* restore previous list window state */
-      pop_lw_state(); 
+      list_window_pop_state(lw_state,lw); 
     }
   else
     if( entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY)
@@ -257,8 +245,7 @@ change_directory(screen_t *screen, mpdclient_t *c, filelist_entry_t *entry)
        mpd_Directory *dir = entity->info.directory;
        path = utf8_to_locale(dir->path);      
        /* save current list window state */
-       push_lw_state(); 
-       list_window_reset(lw);
+       list_window_push_state(lw_state,lw); 
       }
     else
       return -1;
@@ -284,6 +271,26 @@ load_playlist(screen_t *screen, mpdclient_t *c, filelist_entry_t *entry)
   return 0;
 }
 
+static int
+handle_save(screen_t *screen, mpdclient_t *c)
+{
+  filelist_entry_t *entry;
+  char *defaultname = NULL;
+
+
+  entry=( filelist_entry_t *) g_list_nth_data(filelist->list,lw->selected);
+  if( entry && entry->entity )
+    { 
+      mpd_InfoEntity *entity = entry->entity;
+      if( entity->type==MPD_INFO_ENTITY_TYPE_PLAYLISTFILE )
+       {
+         mpd_PlaylistFile *plf = entity->info.playlistFile;
+         defaultname = plf->path;
+       }
+    }
+  return playlist_save(screen, c, NULL, defaultname);
+}
+
 static int 
 handle_delete(screen_t *screen, mpdclient_t *c)
 {
@@ -331,6 +338,7 @@ handle_delete(screen_t *screen, mpdclient_t *c)
 static int
 enqueue_and_play(screen_t *screen, mpdclient_t *c, filelist_entry_t *entry)
 {
+  int index;
   mpd_InfoEntity *entity = entry->entity;
   mpd_Song *song = entity->info.song;
   
@@ -349,7 +357,7 @@ enqueue_and_play(screen_t *screen, mpdclient_t *c, filelist_entry_t *entry)
        return -1;
     }
   
-  int index = playlist_get_index_from_file(c, song->file);
+  index = playlist_get_index_from_file(c, song->file);
   mpdclient_cmd_play(c, index);
   return 0;
 }
@@ -371,7 +379,7 @@ browse_handle_enter(screen_t *screen,
 
   entity = entry->entity;
   if( entity==NULL || entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY )
-    return change_directory(screen, c, entry);
+    return change_directory(screen, c, entry, NULL);
   else if( entity->type==MPD_INFO_ENTITY_TYPE_PLAYLISTFILE )
     return load_playlist(screen, c, entry);
   else if( entity->type==MPD_INFO_ENTITY_TYPE_SONG )
@@ -516,6 +524,7 @@ static void
 browse_init(WINDOW *w, int cols, int rows)
 {
   lw = list_window_init(w, cols, rows);
+  lw_state = list_window_init_state();
 }
 
 static void
@@ -528,22 +537,10 @@ browse_resize(int cols, int rows)
 static void
 browse_exit(void)
 {
-  if( lw_state_list )
-    {
-      GList *list = lw_state_list;
-      while( list )
-       {
-         g_free(list->data);
-         list->data = NULL;
-         list = list->next;
-       }
-      g_list_free(lw_state_list);
-      lw_state_list = NULL;
-
-    }
   if( filelist )
     filelist = mpdclient_filelist_free(filelist);
-  list_window_free(lw);
+  lw = list_window_free(lw);
+  lw_state = list_window_free_state(lw_state);
 }
 
 static void 
@@ -565,7 +562,20 @@ browse_close(void)
 static char *
 browse_title(char *str, size_t size)
 {
-  g_snprintf(str, size, _("Browse: %s"), basename(filelist->path));
+  char *pathcopy;
+  char *parentdir;
+  pathcopy = strdup(filelist->path);
+  parentdir = dirname(pathcopy);
+  parentdir = basename(parentdir);
+  if( parentdir[0] == '.' && strlen(parentdir) == 1 )
+    {
+      parentdir = NULL;
+    }
+  g_snprintf(str, size, _("Browse: %s%s%s"),
+            parentdir ? parentdir : "",
+            parentdir ? "/" : "",
+            basename(filelist->path));
+  free(pathcopy);
   return str;
 }
 
@@ -638,6 +648,12 @@ browse_cmd(screen_t *screen, mpdclient_t *c, command_t cmd)
     case CMD_PLAY:
       browse_handle_enter(screen, c, lw, filelist);
       return 1;
+    case CMD_GO_ROOT_DIRECTORY:
+      return change_directory(screen, c, NULL, "");
+      break;
+    case CMD_GO_PARENT_DIRECTORY:
+      return change_directory(screen, c, NULL, "..");
+      break;
     case CMD_SELECT:
       if( browse_handle_select(screen, c, lw, filelist) == 0 )
        {
@@ -648,6 +664,9 @@ browse_cmd(screen_t *screen, mpdclient_t *c, command_t cmd)
     case CMD_DELETE:
       handle_delete(screen, c);
       break;
+    case CMD_SAVE_PLAYLIST:
+      handle_save(screen, c);
+      break;
     case CMD_SCREEN_UPDATE:
       screen->painted = 0;
       lw->clear = 1;
@@ -661,8 +680,12 @@ browse_cmd(screen_t *screen, mpdclient_t *c, command_t cmd)
        {
          if( mpdclient_cmd_db_update_utf8(c,filelist->path)==0 )
            {
-             screen_status_printf(_("Database update of %s started!"),
+             if(strcmp(filelist->path,"")) {
+                screen_status_printf(_("Database update of %s started!"),
                                   filelist->path);
+             } else {
+               screen_status_printf(_("Database update started!"));
+             }
              /* set updatingDb to make shure the browse callback gets called
               * even if the updated has finished before status is updated */
              c->status->updatingDb = 1;