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(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;
93 mpc_update_filelist(c);
94 list_window_reset(w);
95 }
98 static int
99 add_directory(mpd_client_t *c, char *dir)
100 {
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);
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;
143 }
145 static void
146 select_entry(screen_t *screen, mpd_client_t *c)
147 {
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;
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 }
204 }
206 void
207 file_clear_highlights(mpd_client_t *c)
208 {
209 GList *list = g_list_first(c->filelist);
211 while( list )
212 {
213 filelist_entry_t *entry = list->data;
215 entry->selected = 0;
216 list = list->next;
217 }
218 }
220 void
221 file_clear_highlight(mpd_client_t *c, mpd_Song *song)
222 {
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 }
244 }
246 char *
247 file_get_header(mpd_client_t *c)
248 {
249 static char buf[64];
251 snprintf(buf, 64,
252 TOP_HEADER_FILE ": %s ",
253 basename(c->cwd)
254 );
256 return buf;
257 }
259 void
260 file_open(screen_t *screen, mpd_client_t *c)
261 {
262 if( c->filelist == NULL )
263 {
264 mpc_update_filelist(c);
265 }
266 }
268 void
269 file_close(screen_t *screen, mpd_client_t *c)
270 {
271 }
273 void
274 file_paint(screen_t *screen, mpd_client_t *c)
275 {
276 list_window_t *w = screen->filelist;
278 w->clear = 1;
280 list_window_paint(screen->filelist, list_callback, (void *) c);
281 wrefresh(screen->filelist->w);
282 }
284 void
285 file_update(screen_t *screen, mpd_client_t *c)
286 {
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);
295 }
298 int
299 file_cmd(screen_t *screen, mpd_client_t *c, command_t cmd)
300 {
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 default:
334 return 0;
335 }
336 return 1;
337 }