aboutsummaryrefslogblamecommitdiffstats
path: root/screen_file.c
blob: ba0dbd3e1c948b280d70cbe2bd9b000085b05a1d (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

















                                                            
                    



                                                    
                           
















                                                                              
                                                  
                                                          
 
                                              

                    























































                                                                          
                
 



                                                            






























































                                                                          




                                                        

                                                              






                                                          






                                                         


                                                                     

















































                                                             
            
 
                                         

                                                            
              
             
            













































































                                                                  





                                
                       











                                                                    
                                                                         


                 




               
/* 
 * $Id: screen_file.c,v 1.9 2004/03/18 09:33:07 kalle Exp $ 
 *
 */

#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <ncurses.h>

#include "config.h"
#include "support.h"
#include "libmpdclient.h"
#include "mpc.h"
#include "command.h"
#include "screen.h"
#include "screen_file.h"

#define BUFSIZE 1024

static char *
list_callback(int index, int *highlight, void *data)
{
  static char buf[BUFSIZE];
  mpd_client_t *c = (mpd_client_t *) data;
  filelist_entry_t *entry;
  mpd_InfoEntity *entity;

  *highlight = 0;
  if( (entry=(filelist_entry_t *) g_list_nth_data(c->filelist, index))==NULL )
    return NULL;

  entity = entry->entity;
  *highlight = entry->selected;

  if( entity == NULL )
    {
      return "[Back]";
    }
  if( entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY ) 
    {
      mpd_Directory *dir = entity->info.directory;
      char *dirname = utf8_to_locale(basename(dir->path));

      snprintf(buf, BUFSIZE, "[%s]", dirname);
      free(dirname);
      return buf;
    }
  else if( entity->type==MPD_INFO_ENTITY_TYPE_SONG )
    {
      mpd_Song *song = entity->info.song;
      return mpc_get_song_name(song);
    }

  return NULL;
}

static void
change_directory(screen_t *screen, mpd_client_t *c)
{
  list_window_t *w = screen->filelist;
  filelist_entry_t *entry;
  mpd_InfoEntity *entity;

  entry = ( filelist_entry_t *) g_list_nth_data(c->filelist, w->selected);
  if( entry==NULL )
    return;

  entity = entry->entity;
  if( entity==NULL )
    {
      char *parent = g_path_get_dirname(c->cwd);

      if( strcmp(parent,".") == 0 )
	{
	  parent[0] = '\0';
	}
      if( c->cwd )
	free(c->cwd);
      c->cwd = parent;
    }
  else
    if( entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY)
      {
	mpd_Directory *dir = entity->info.directory;
	if( c->cwd )
	  free(c->cwd);
	c->cwd = strdup(dir->path);      
      }
    else
      return;
  
  mpc_update_filelist(c);
  list_window_reset(w);
}


static int
add_directory(mpd_client_t *c, char *dir)
{
  mpd_InfoEntity *entity;
  GList *subdir_list = NULL;
  GList *list = NULL;
  char *dirname;

  dirname = utf8_to_locale(dir);
  screen_status_printf("Adding directory %s...\n", dirname);
  free(dirname);
  dirname = NULL;

  mpd_sendLsInfoCommand(c->connection, dir);
  mpd_sendCommandListBegin(c->connection);
  while( (entity=mpd_getNextInfoEntity(c->connection)) )
    {
      if( entity->type==MPD_INFO_ENTITY_TYPE_SONG )
	{
	  mpd_Song *song = entity->info.song;
	  mpd_sendAddCommand(c->connection, song->file);
	  mpd_freeInfoEntity(entity);
	}
      else if( entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY )
	{
	  subdir_list = g_list_append(subdir_list, (gpointer) entity); 
	}
      else
	mpd_freeInfoEntity(entity);
    }
  mpd_sendCommandListEnd(c->connection);
  mpd_finishCommand(c->connection);
  
  list = g_list_first(subdir_list);
  while( list!=NULL )
    {
      mpd_Directory *dir;

      entity = list->data;
      dir = entity->info.directory;
      add_directory(c, dir->path);
      mpd_freeInfoEntity(entity);
      list->data=NULL;
      list=list->next;
    }
  g_list_free(subdir_list);
  return 0;
}

static void
select_entry(screen_t *screen, mpd_client_t *c)
{
  list_window_t *w = screen->filelist;
  filelist_entry_t *entry;

  entry = ( filelist_entry_t *) g_list_nth_data(c->filelist, w->selected);
  if( entry==NULL || entry->entity==NULL)
    return;

  if( entry->entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY )
    {
      mpd_Directory *dir = entry->entity->info.directory;
      add_directory(c, dir->path);
      return;
    }

  if( entry->entity->type!=MPD_INFO_ENTITY_TYPE_SONG )
    return; /* No support for adding dirs... :( */

  entry->selected = !entry->selected;

  if( entry->selected )
    {
      if( entry->entity->type==MPD_INFO_ENTITY_TYPE_SONG )
	{
	  mpd_Song *song = entry->entity->info.song;

	  mpd_sendAddCommand(c->connection, song->file);
	  mpd_finishCommand(c->connection);

	  screen_status_printf("Adding \'%s\' to playlist\n", 
			       mpc_get_song_name(song));
	}
    }
  else
    {
      if( entry->entity->type==MPD_INFO_ENTITY_TYPE_SONG )
	{
	  int i;
	  mpd_Song *song = entry->entity->info.song;
	  
	  i = mpc_playlist_get_song_index(c, song->file);
	  if( i>=0 )
	    {
	      mpd_sendDeleteCommand(c->connection, i);
	      mpd_finishCommand(c->connection);
	      screen_status_printf("Removed \'%s\' from playlist\n", 
				   mpc_get_song_name(song));

	    }
	}
    }
  
}

void
file_clear_highlights(mpd_client_t *c)
{
  GList *list = g_list_first(c->filelist);
  
  while( list )
    {
      filelist_entry_t *entry = list->data;

      entry->selected = 0;
      list = list->next;
    }
}

void
file_clear_highlight(mpd_client_t *c, mpd_Song *song)
{
  GList *list = g_list_first(c->filelist);

  if( !song )
    return;

  while( list )
    {
      filelist_entry_t *entry = list->data;
      mpd_InfoEntity *entity  = entry->entity;

      if( entity && entity->type==MPD_INFO_ENTITY_TYPE_SONG )
	{
	  mpd_Song *song2 = entity->info.song;

	  if( strcmp(song->file, song2->file) == 0 )
	    {
	      entry->selected = 0;
	    }
	}
      list = list->next;
    }
}

char *
file_get_header(mpd_client_t *c)
{
  static char buf[64];
  char *tmp;

  tmp = utf8_to_locale(basename(c->cwd));
  snprintf(buf, 64, 
	   TOP_HEADER_FILE ": %s                          ",
	   tmp
	   );
  free(tmp);

  return buf;
}

void 
file_open(screen_t *screen, mpd_client_t *c)
{
  if( c->filelist == NULL )
    {
      mpc_update_filelist(c);
    }
}

void 
file_close(screen_t *screen, mpd_client_t *c)
{
}

void 
file_paint(screen_t *screen, mpd_client_t *c)
{
  list_window_t *w = screen->filelist;
 
  w->clear = 1;
  
  list_window_paint(screen->filelist, list_callback, (void *) c);
  wrefresh(screen->filelist->w);
}

void 
file_update(screen_t *screen, mpd_client_t *c)
{
  if( c->filelist_updated )
    {
      file_paint(screen, c);
      c->filelist_updated = 0;
      return;
    }
  list_window_paint(screen->filelist, list_callback, (void *) c);
  wrefresh(screen->filelist->w);
}


int 
file_cmd(screen_t *screen, mpd_client_t *c, command_t cmd)
{
  switch(cmd)
    {
    case CMD_PLAY:
      change_directory(screen, c);
      break;
    case CMD_LIST_PREVIOUS:
      list_window_previous(screen->filelist);
      screen->filelist->repaint=1;
      break;
    case CMD_SELECT:
      select_entry(screen, c);
      /* continue and select next item... */
    case CMD_LIST_NEXT:
      list_window_next(screen->filelist, c->filelist_length);
      screen->filelist->repaint=1;
      break;
    case CMD_LIST_FIRST:
      list_window_first(screen->filelist);
      screen->filelist->repaint  = 1;
      break;
    case CMD_LIST_LAST:
      list_window_last(screen->filelist, c->filelist_length);
      screen->filelist->repaint  = 1;
      break;
    case CMD_LIST_NEXT_PAGE:
      list_window_next_page(screen->filelist, c->filelist_length);
      screen->filelist->repaint  = 1;
      break;
    case CMD_LIST_PREVIOUS_PAGE:
      list_window_previous_page(screen->filelist);
      screen->filelist->repaint  = 1;
      break;
    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->filelist,
			   list_callback,
			   c,
			   screen->findbuf) == 0 )
	{
	  screen->filelist->repaint  = 1;
	}
      else
	{
	  screen_status_printf("Unable to find \'%s\'", screen->findbuf);
	  beep();
	}
      break;
    default:
      return 0;
    }
  return 1;
}