Code

Imported ncmpc (mpc-ncures).
[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"
20 static char *
21 list_callback(int index, int *highlight, void *data)
22 {
23   mpd_client_t *c = (mpd_client_t *) data;
24   filelist_entry_t *entry;
25   mpd_InfoEntity *entity;
27   *highlight = 0;
28   if( (entry=(filelist_entry_t *) g_list_nth_data(c->filelist, index))==NULL )
29     return NULL;
31   entity = entry->entity;
32   *highlight = entry->selected;
34   if( entity == NULL )
35     {
36       return "[Back]";
37     }
38   if( entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY ) 
39     {
41       mpd_Directory *dir = entity->info.directory;
43       return utf8(basename(dir->path));
44     }
45   else if( entity->type==MPD_INFO_ENTITY_TYPE_SONG )
46     {
47       mpd_Song *song = entity->info.song;
48       return mpc_get_song_name(song);
49     }
51   return NULL;
52 }
54 static void
55 change_directory(screen_t *screen, mpd_client_t *c)
56 {
57   list_window_t *w = screen->filelist;
58   filelist_entry_t *entry;
59   mpd_InfoEntity *entity;
61   entry = ( filelist_entry_t *) g_list_nth_data(c->filelist, w->selected);
62   if( entry==NULL )
63     return;
65   entity = entry->entity;
66   if( entity==NULL )
67     {
68       char *parent = g_path_get_dirname(c->cwd);
70       if( strcmp(parent,".") == 0 )
71         {
72           parent[0] = '\0';
73         }
74       if( c->cwd )
75         free(c->cwd);
76       c->cwd = parent;
77     }
78   else
79     if( entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY)
80       {
81         mpd_Directory *dir = entity->info.directory;
82         if( c->cwd )
83           free(c->cwd);
84         c->cwd = strdup(dir->path);      
85       }
86     else
87       return;
88   
89   mpc_update_filelist(c);
90   list_window_reset(w);
91 }
94 static int
95 add_directory(mpd_client_t *c, char *dir)
96 {
97   mpd_InfoEntity *entity;
98   GList *subdir_list = NULL;
99   GList *list = NULL;
100   char buf[80];
102   snprintf(buf, 80, "Adding directory %s...\n", dir);
103   screen_status_message(c, buf);
105   mpd_sendLsInfoCommand(c->connection, dir);
106   mpd_sendCommandListBegin(c->connection);
107   while( (entity=mpd_getNextInfoEntity(c->connection)) )
108     {
109       if( entity->type==MPD_INFO_ENTITY_TYPE_SONG )
110         {
111           mpd_Song *song = entity->info.song;
112           mpd_sendAddCommand(c->connection, song->file);
113           mpd_freeInfoEntity(entity);
114         }
115       else if( entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY )
116         {
117           subdir_list = g_list_append(subdir_list, (gpointer) entity); 
118         }
119       else
120         mpd_freeInfoEntity(entity);
121     }
122   mpd_sendCommandListEnd(c->connection);
123   mpd_finishCommand(c->connection);
124   
125   list = g_list_first(subdir_list);
126   while( list!=NULL )
127     {
128       mpd_Directory *dir;
130       entity = list->data;
131       dir = entity->info.directory;
132       add_directory(c, dir->path);
133       mpd_freeInfoEntity(entity);
134       list->data=NULL;
135       list=list->next;
136     }
137   g_list_free(subdir_list);
138   return 0;
141 static void
142 select_entry(screen_t *screen, mpd_client_t *c)
144   list_window_t *w = screen->filelist;
145   filelist_entry_t *entry;
147   entry = ( filelist_entry_t *) g_list_nth_data(c->filelist, w->selected);
148   if( entry==NULL || entry->entity==NULL)
149     return;
151   if( entry->entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY )
152     {
153       mpd_Directory *dir = entry->entity->info.directory;
154       add_directory(c, dir->path);
155       return;
156     }
158   if( entry->entity->type!=MPD_INFO_ENTITY_TYPE_SONG )
159     return; /* No support for adding dirs... :( */
161   entry->selected = !entry->selected;
163   if( entry->selected )
164     {
165       if( entry->entity->type==MPD_INFO_ENTITY_TYPE_SONG )
166         {
167           char buf[80];
168           mpd_Song *song = entry->entity->info.song;
170           mpd_sendAddCommand(c->connection, song->file);
171           mpd_finishCommand(c->connection);
173           snprintf(buf, 80, 
174                    "Adding \'%s\' to playlist\n", 
175                    mpc_get_song_name(song));
176           screen_status_message(c, buf);
177         }
178     }
179   else
180     {
181       if( entry->entity->type==MPD_INFO_ENTITY_TYPE_SONG )
182         {
183           int i;
184           char buf[80];
185           mpd_Song *song = entry->entity->info.song;
186           
187           i = mpc_playlist_get_song_index(c, song->file);
188           if( i>=0 )
189             {
190               mpd_sendDeleteCommand(c->connection, i);
191               mpd_finishCommand(c->connection);
192               snprintf(buf, 80, 
193                        "Removed \'%s\' from playlist\n", 
194                        mpc_get_song_name(song));
195               screen_status_message(c, buf);
196             }
197         }
198     }
199   
202 void
203 file_clear_highlights(mpd_client_t *c)
205   GList *list = g_list_first(c->filelist);
206   
207   while( list )
208     {
209       filelist_entry_t *entry = list->data;
211       entry->selected = 0;
212       list = list->next;
213     }
216 void
217 file_clear_highlight(mpd_client_t *c, mpd_Song *song)
219   GList *list = g_list_first(c->filelist);
221   if( !song )
222     return;
224   while( list )
225     {
226       filelist_entry_t *entry = list->data;
227       mpd_InfoEntity *entity  = entry->entity;
229       if( entity && entity->type==MPD_INFO_ENTITY_TYPE_SONG )
230         {
231           mpd_Song *song2 = entity->info.song;
233           if( strcmp(song->file, song2->file) == 0 )
234             {
235               entry->selected = 0;
236             }
237         }
238       list = list->next;
239     }
242 char *
243 file_get_header(mpd_client_t *c)
245   static char buf[64];
247   snprintf(buf, 64, 
248            TOP_HEADER_FILE ": %s                          ",
249            basename(c->cwd)
250            );
252   return buf;
255 void 
256 file_open(screen_t *screen, mpd_client_t *c)
258   if( c->filelist == NULL )
259     {
260       mpc_update_filelist(c);
261     }
264 void 
265 file_close(screen_t *screen, mpd_client_t *c)
269 void 
270 file_paint(screen_t *screen, mpd_client_t *c)
272   list_window_t *w = screen->filelist;
273  
274   w->clear = 1;
275   
276   list_window_paint(screen->filelist, list_callback, (void *) c);
277   wrefresh(screen->filelist->w);
280 void 
281 file_update(screen_t *screen, mpd_client_t *c)
283   if( c->filelist_updated )
284     {
285       file_paint(screen, c);
286       c->filelist_updated = 0;
287       return;
288     }
289   list_window_paint(screen->filelist, list_callback, (void *) c);
290   wrefresh(screen->filelist->w);
294 int 
295 file_cmd(screen_t *screen, mpd_client_t *c, command_t cmd)
297   switch(cmd)
298     {
299     case CMD_PLAY:
300       change_directory(screen, c);
301       break;
302     case CMD_LIST_PREVIOUS:
303       list_window_previous(screen->filelist);
304       screen->filelist->repaint=1;
305       break;
306     case CMD_SELECT:
307       select_entry(screen, c);
308       /* continue and select next item... */
309     case CMD_LIST_NEXT:
310       list_window_next(screen->filelist, c->filelist_length);
311       screen->filelist->repaint=1;
312       break;
313     case CMD_LIST_FIRST:
314       list_window_first(screen->filelist);
315       screen->filelist->repaint  = 1;
316       break;
317     case CMD_LIST_LAST:
318       list_window_last(screen->filelist, c->filelist_length);
319       screen->filelist->repaint  = 1;
320       break;
321     case CMD_LIST_NEXT_PAGE:
322       list_window_next_page(screen->filelist, c->filelist_length);
323       screen->filelist->repaint  = 1;
324       break;
325     case CMD_LIST_PREVIOUS_PAGE:
326       list_window_previous_page(screen->filelist);
327       screen->filelist->repaint  = 1;
328       break;
329     default:
330       return 0;
331     }
332   return 1;