bd60872e60e438a0060800dc93eb1c9b8adfab10
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;
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);
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;
139 }
141 static void
142 select_entry(screen_t *screen, mpd_client_t *c)
143 {
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;
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 }
200 }
202 void
203 file_clear_highlights(mpd_client_t *c)
204 {
205 GList *list = g_list_first(c->filelist);
207 while( list )
208 {
209 filelist_entry_t *entry = list->data;
211 entry->selected = 0;
212 list = list->next;
213 }
214 }
216 void
217 file_clear_highlight(mpd_client_t *c, mpd_Song *song)
218 {
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 }
240 }
242 char *
243 file_get_header(mpd_client_t *c)
244 {
245 static char buf[64];
247 snprintf(buf, 64,
248 TOP_HEADER_FILE ": %s ",
249 basename(c->cwd)
250 );
252 return buf;
253 }
255 void
256 file_open(screen_t *screen, mpd_client_t *c)
257 {
258 if( c->filelist == NULL )
259 {
260 mpc_update_filelist(c);
261 }
262 }
264 void
265 file_close(screen_t *screen, mpd_client_t *c)
266 {
267 }
269 void
270 file_paint(screen_t *screen, mpd_client_t *c)
271 {
272 list_window_t *w = screen->filelist;
274 w->clear = 1;
276 list_window_paint(screen->filelist, list_callback, (void *) c);
277 wrefresh(screen->filelist->w);
278 }
280 void
281 file_update(screen_t *screen, mpd_client_t *c)
282 {
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);
291 }
294 int
295 file_cmd(screen_t *screen, mpd_client_t *c, command_t cmd)
296 {
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;
333 }