Code

Convert the directory name in file_get_header() from utf-8.
[ncmpc.git] / screen_file.c
1 /* 
2  * $Id: screen_file.c,v 1.9 2004/03/18 09:33:07 kalle Exp $ 
3  *
4  */
6 #include <stdlib.h>
7 #include <string.h>
8 #include <glib.h>
9 #include <ncurses.h>
11 #include "config.h"
12 #include "support.h"
13 #include "libmpdclient.h"
14 #include "mpc.h"
15 #include "command.h"
16 #include "screen.h"
17 #include "screen_file.h"
19 #define BUFSIZE 1024
21 static char *
22 list_callback(int index, int *highlight, void *data)
23 {
24   static char buf[BUFSIZE];
25   mpd_client_t *c = (mpd_client_t *) data;
26   filelist_entry_t *entry;
27   mpd_InfoEntity *entity;
29   *highlight = 0;
30   if( (entry=(filelist_entry_t *) g_list_nth_data(c->filelist, index))==NULL )
31     return NULL;
33   entity = entry->entity;
34   *highlight = entry->selected;
36   if( entity == NULL )
37     {
38       return "[Back]";
39     }
40   if( entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY ) 
41     {
42       mpd_Directory *dir = entity->info.directory;
43       char *dirname = utf8_to_locale(basename(dir->path));
45       strncpy(buf, dirname, BUFSIZE);
46       free(dirname);
47       return buf;
48     }
49   else if( entity->type==MPD_INFO_ENTITY_TYPE_SONG )
50     {
51       mpd_Song *song = entity->info.song;
52       return mpc_get_song_name(song);
53     }
55   return NULL;
56 }
58 static void
59 change_directory(screen_t *screen, mpd_client_t *c)
60 {
61   list_window_t *w = screen->filelist;
62   filelist_entry_t *entry;
63   mpd_InfoEntity *entity;
65   entry = ( filelist_entry_t *) g_list_nth_data(c->filelist, w->selected);
66   if( entry==NULL )
67     return;
69   entity = entry->entity;
70   if( entity==NULL )
71     {
72       char *parent = g_path_get_dirname(c->cwd);
74       if( strcmp(parent,".") == 0 )
75         {
76           parent[0] = '\0';
77         }
78       if( c->cwd )
79         free(c->cwd);
80       c->cwd = parent;
81     }
82   else
83     if( entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY)
84       {
85         mpd_Directory *dir = entity->info.directory;
86         if( c->cwd )
87           free(c->cwd);
88         c->cwd = strdup(dir->path);      
89       }
90     else
91       return;
92   
93   mpc_update_filelist(c);
94   list_window_reset(w);
95 }
98 static int
99 add_directory(mpd_client_t *c, char *dir)
101   mpd_InfoEntity *entity;
102   GList *subdir_list = NULL;
103   GList *list = NULL;
104   char buf[80];
106   snprintf(buf, 80, "Adding directory %s...\n", dir);
107   screen_status_message(c, buf);
109   mpd_sendLsInfoCommand(c->connection, dir);
110   mpd_sendCommandListBegin(c->connection);
111   while( (entity=mpd_getNextInfoEntity(c->connection)) )
112     {
113       if( entity->type==MPD_INFO_ENTITY_TYPE_SONG )
114         {
115           mpd_Song *song = entity->info.song;
116           mpd_sendAddCommand(c->connection, song->file);
117           mpd_freeInfoEntity(entity);
118         }
119       else if( entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY )
120         {
121           subdir_list = g_list_append(subdir_list, (gpointer) entity); 
122         }
123       else
124         mpd_freeInfoEntity(entity);
125     }
126   mpd_sendCommandListEnd(c->connection);
127   mpd_finishCommand(c->connection);
128   
129   list = g_list_first(subdir_list);
130   while( list!=NULL )
131     {
132       mpd_Directory *dir;
134       entity = list->data;
135       dir = entity->info.directory;
136       add_directory(c, dir->path);
137       mpd_freeInfoEntity(entity);
138       list->data=NULL;
139       list=list->next;
140     }
141   g_list_free(subdir_list);
142   return 0;
145 static void
146 select_entry(screen_t *screen, mpd_client_t *c)
148   list_window_t *w = screen->filelist;
149   filelist_entry_t *entry;
151   entry = ( filelist_entry_t *) g_list_nth_data(c->filelist, w->selected);
152   if( entry==NULL || entry->entity==NULL)
153     return;
155   if( entry->entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY )
156     {
157       mpd_Directory *dir = entry->entity->info.directory;
158       add_directory(c, dir->path);
159       return;
160     }
162   if( entry->entity->type!=MPD_INFO_ENTITY_TYPE_SONG )
163     return; /* No support for adding dirs... :( */
165   entry->selected = !entry->selected;
167   if( entry->selected )
168     {
169       if( entry->entity->type==MPD_INFO_ENTITY_TYPE_SONG )
170         {
171           char buf[80];
172           mpd_Song *song = entry->entity->info.song;
174           mpd_sendAddCommand(c->connection, song->file);
175           mpd_finishCommand(c->connection);
177           snprintf(buf, 80, 
178                    "Adding \'%s\' to playlist\n", 
179                    mpc_get_song_name(song));
180           screen_status_message(c, buf);
181         }
182     }
183   else
184     {
185       if( entry->entity->type==MPD_INFO_ENTITY_TYPE_SONG )
186         {
187           int i;
188           char buf[80];
189           mpd_Song *song = entry->entity->info.song;
190           
191           i = mpc_playlist_get_song_index(c, song->file);
192           if( i>=0 )
193             {
194               mpd_sendDeleteCommand(c->connection, i);
195               mpd_finishCommand(c->connection);
196               snprintf(buf, 80, 
197                        "Removed \'%s\' from playlist\n", 
198                        mpc_get_song_name(song));
199               screen_status_message(c, buf);
200             }
201         }
202     }
203   
206 void
207 file_clear_highlights(mpd_client_t *c)
209   GList *list = g_list_first(c->filelist);
210   
211   while( list )
212     {
213       filelist_entry_t *entry = list->data;
215       entry->selected = 0;
216       list = list->next;
217     }
220 void
221 file_clear_highlight(mpd_client_t *c, mpd_Song *song)
223   GList *list = g_list_first(c->filelist);
225   if( !song )
226     return;
228   while( list )
229     {
230       filelist_entry_t *entry = list->data;
231       mpd_InfoEntity *entity  = entry->entity;
233       if( entity && entity->type==MPD_INFO_ENTITY_TYPE_SONG )
234         {
235           mpd_Song *song2 = entity->info.song;
237           if( strcmp(song->file, song2->file) == 0 )
238             {
239               entry->selected = 0;
240             }
241         }
242       list = list->next;
243     }
246 char *
247 file_get_header(mpd_client_t *c)
249   static char buf[64];
250   char *tmp;
252   tmp = utf8_to_locale(basename(c->cwd));
253   snprintf(buf, 64, 
254            TOP_HEADER_FILE ": %s                          ",
255            tmp
256            );
257   free(tmp);
259   return buf;
262 void 
263 file_open(screen_t *screen, mpd_client_t *c)
265   if( c->filelist == NULL )
266     {
267       mpc_update_filelist(c);
268     }
271 void 
272 file_close(screen_t *screen, mpd_client_t *c)
276 void 
277 file_paint(screen_t *screen, mpd_client_t *c)
279   list_window_t *w = screen->filelist;
280  
281   w->clear = 1;
282   
283   list_window_paint(screen->filelist, list_callback, (void *) c);
284   wrefresh(screen->filelist->w);
287 void 
288 file_update(screen_t *screen, mpd_client_t *c)
290   if( c->filelist_updated )
291     {
292       file_paint(screen, c);
293       c->filelist_updated = 0;
294       return;
295     }
296   list_window_paint(screen->filelist, list_callback, (void *) c);
297   wrefresh(screen->filelist->w);
301 int 
302 file_cmd(screen_t *screen, mpd_client_t *c, command_t cmd)
304   switch(cmd)
305     {
306     case CMD_PLAY:
307       change_directory(screen, c);
308       break;
309     case CMD_LIST_PREVIOUS:
310       list_window_previous(screen->filelist);
311       screen->filelist->repaint=1;
312       break;
313     case CMD_SELECT:
314       select_entry(screen, c);
315       /* continue and select next item... */
316     case CMD_LIST_NEXT:
317       list_window_next(screen->filelist, c->filelist_length);
318       screen->filelist->repaint=1;
319       break;
320     case CMD_LIST_FIRST:
321       list_window_first(screen->filelist);
322       screen->filelist->repaint  = 1;
323       break;
324     case CMD_LIST_LAST:
325       list_window_last(screen->filelist, c->filelist_length);
326       screen->filelist->repaint  = 1;
327       break;
328     case CMD_LIST_NEXT_PAGE:
329       list_window_next_page(screen->filelist, c->filelist_length);
330       screen->filelist->repaint  = 1;
331       break;
332     case CMD_LIST_PREVIOUS_PAGE:
333       list_window_previous_page(screen->filelist);
334       screen->filelist->repaint  = 1;
335       break;
336     default:
337       return 0;
338     }
339   return 1;