Code

Use screen_status_printf() instead of screen_status_message().
[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 *dirname;
106   dirname = utf8_to_locale(dir);
107   screen_status_printf("Adding directory %s...\n", dirname);
108   free(dirname);
109   dirname = NULL;
111   mpd_sendLsInfoCommand(c->connection, dir);
112   mpd_sendCommandListBegin(c->connection);
113   while( (entity=mpd_getNextInfoEntity(c->connection)) )
114     {
115       if( entity->type==MPD_INFO_ENTITY_TYPE_SONG )
116         {
117           mpd_Song *song = entity->info.song;
118           mpd_sendAddCommand(c->connection, song->file);
119           mpd_freeInfoEntity(entity);
120         }
121       else if( entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY )
122         {
123           subdir_list = g_list_append(subdir_list, (gpointer) entity); 
124         }
125       else
126         mpd_freeInfoEntity(entity);
127     }
128   mpd_sendCommandListEnd(c->connection);
129   mpd_finishCommand(c->connection);
130   
131   list = g_list_first(subdir_list);
132   while( list!=NULL )
133     {
134       mpd_Directory *dir;
136       entity = list->data;
137       dir = entity->info.directory;
138       add_directory(c, dir->path);
139       mpd_freeInfoEntity(entity);
140       list->data=NULL;
141       list=list->next;
142     }
143   g_list_free(subdir_list);
144   return 0;
147 static void
148 select_entry(screen_t *screen, mpd_client_t *c)
150   list_window_t *w = screen->filelist;
151   filelist_entry_t *entry;
153   entry = ( filelist_entry_t *) g_list_nth_data(c->filelist, w->selected);
154   if( entry==NULL || entry->entity==NULL)
155     return;
157   if( entry->entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY )
158     {
159       mpd_Directory *dir = entry->entity->info.directory;
160       add_directory(c, dir->path);
161       return;
162     }
164   if( entry->entity->type!=MPD_INFO_ENTITY_TYPE_SONG )
165     return; /* No support for adding dirs... :( */
167   entry->selected = !entry->selected;
169   if( entry->selected )
170     {
171       if( entry->entity->type==MPD_INFO_ENTITY_TYPE_SONG )
172         {
173           mpd_Song *song = entry->entity->info.song;
175           mpd_sendAddCommand(c->connection, song->file);
176           mpd_finishCommand(c->connection);
178           screen_status_printf("Adding \'%s\' to playlist\n", 
179                                mpc_get_song_name(song));
180         }
181     }
182   else
183     {
184       if( entry->entity->type==MPD_INFO_ENTITY_TYPE_SONG )
185         {
186           int i;
187           mpd_Song *song = entry->entity->info.song;
188           
189           i = mpc_playlist_get_song_index(c, song->file);
190           if( i>=0 )
191             {
192               mpd_sendDeleteCommand(c->connection, i);
193               mpd_finishCommand(c->connection);
194               screen_status_printf("Removed \'%s\' from playlist\n", 
195                                    mpc_get_song_name(song));
197             }
198         }
199     }
200   
203 void
204 file_clear_highlights(mpd_client_t *c)
206   GList *list = g_list_first(c->filelist);
207   
208   while( list )
209     {
210       filelist_entry_t *entry = list->data;
212       entry->selected = 0;
213       list = list->next;
214     }
217 void
218 file_clear_highlight(mpd_client_t *c, mpd_Song *song)
220   GList *list = g_list_first(c->filelist);
222   if( !song )
223     return;
225   while( list )
226     {
227       filelist_entry_t *entry = list->data;
228       mpd_InfoEntity *entity  = entry->entity;
230       if( entity && entity->type==MPD_INFO_ENTITY_TYPE_SONG )
231         {
232           mpd_Song *song2 = entity->info.song;
234           if( strcmp(song->file, song2->file) == 0 )
235             {
236               entry->selected = 0;
237             }
238         }
239       list = list->next;
240     }
243 char *
244 file_get_header(mpd_client_t *c)
246   static char buf[64];
247   char *tmp;
249   tmp = utf8_to_locale(basename(c->cwd));
250   snprintf(buf, 64, 
251            TOP_HEADER_FILE ": %s                          ",
252            tmp
253            );
254   free(tmp);
256   return buf;
259 void 
260 file_open(screen_t *screen, mpd_client_t *c)
262   if( c->filelist == NULL )
263     {
264       mpc_update_filelist(c);
265     }
268 void 
269 file_close(screen_t *screen, mpd_client_t *c)
273 void 
274 file_paint(screen_t *screen, mpd_client_t *c)
276   list_window_t *w = screen->filelist;
277  
278   w->clear = 1;
279   
280   list_window_paint(screen->filelist, list_callback, (void *) c);
281   wrefresh(screen->filelist->w);
284 void 
285 file_update(screen_t *screen, mpd_client_t *c)
287   if( c->filelist_updated )
288     {
289       file_paint(screen, c);
290       c->filelist_updated = 0;
291       return;
292     }
293   list_window_paint(screen->filelist, list_callback, (void *) c);
294   wrefresh(screen->filelist->w);
298 int 
299 file_cmd(screen_t *screen, mpd_client_t *c, command_t cmd)
301   switch(cmd)
302     {
303     case CMD_PLAY:
304       change_directory(screen, c);
305       break;
306     case CMD_LIST_PREVIOUS:
307       list_window_previous(screen->filelist);
308       screen->filelist->repaint=1;
309       break;
310     case CMD_SELECT:
311       select_entry(screen, c);
312       /* continue and select next item... */
313     case CMD_LIST_NEXT:
314       list_window_next(screen->filelist, c->filelist_length);
315       screen->filelist->repaint=1;
316       break;
317     case CMD_LIST_FIRST:
318       list_window_first(screen->filelist);
319       screen->filelist->repaint  = 1;
320       break;
321     case CMD_LIST_LAST:
322       list_window_last(screen->filelist, c->filelist_length);
323       screen->filelist->repaint  = 1;
324       break;
325     case CMD_LIST_NEXT_PAGE:
326       list_window_next_page(screen->filelist, c->filelist_length);
327       screen->filelist->repaint  = 1;
328       break;
329     case CMD_LIST_PREVIOUS_PAGE:
330       list_window_previous_page(screen->filelist);
331       screen->filelist->repaint  = 1;
332       break;
333     case CMD_LIST_FIND:
334       if( screen->findbuf )
335         {
336           free(screen->findbuf);
337           screen->findbuf=NULL;
338         }
339       /* fall throw... */
340     case CMD_LIST_FIND_NEXT:
341       if( !screen->findbuf )
342         screen->findbuf=screen_readln(screen->status_window.w, "/");
343       if( list_window_find(screen->filelist,
344                            list_callback,
345                            c,
346                            screen->findbuf) == 0 )
347         {
348           screen->filelist->repaint  = 1;
349         }
350       else
351         {
352           screen_status_printf("Unable to find \'%s\'", screen->findbuf);
353           beep();
354         }
355       break;
356     default:
357       return 0;
358     }
359   return 1;