809ae3faf81f16f67319d0a6f243c66052180d26
1 #include <stdlib.h>
2 #include <string.h>
3 #include <glib.h>
4 #include <ncurses.h>
6 #include "config.h"
7 #include "support.h"
8 #include "libmpdclient.h"
9 #include "mpc.h"
10 #include "command.h"
11 #include "screen.h"
12 #include "screen_utils.h"
13 #include "screen_file.h"
15 #define BUFSIZE 1024
17 static char *
18 list_callback(int index, int *highlight, void *data)
19 {
20 static char buf[BUFSIZE];
21 mpd_client_t *c = (mpd_client_t *) data;
22 filelist_entry_t *entry;
23 mpd_InfoEntity *entity;
25 *highlight = 0;
26 if( (entry=(filelist_entry_t *) g_list_nth_data(c->filelist, index))==NULL )
27 return NULL;
29 entity = entry->entity;
30 *highlight = entry->selected;
32 if( entity == NULL )
33 {
34 return "[Back]";
35 }
36 if( entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY )
37 {
38 mpd_Directory *dir = entity->info.directory;
39 char *dirname = utf8_to_locale(basename(dir->path));
41 snprintf(buf, BUFSIZE, "[%s]", dirname);
42 free(dirname);
43 return buf;
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 *dirname;
102 dirname = utf8_to_locale(dir);
103 screen_status_printf("Adding directory %s...\n", dirname);
104 free(dirname);
105 dirname = NULL;
107 mpd_sendLsInfoCommand(c->connection, dir);
108 mpd_sendCommandListBegin(c->connection);
109 while( (entity=mpd_getNextInfoEntity(c->connection)) )
110 {
111 if( entity->type==MPD_INFO_ENTITY_TYPE_SONG )
112 {
113 mpd_Song *song = entity->info.song;
114 mpd_sendAddCommand(c->connection, song->file);
115 mpd_freeInfoEntity(entity);
116 }
117 else if( entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY )
118 {
119 subdir_list = g_list_append(subdir_list, (gpointer) entity);
120 }
121 else
122 mpd_freeInfoEntity(entity);
123 }
124 mpd_sendCommandListEnd(c->connection);
125 mpd_finishCommand(c->connection);
127 list = g_list_first(subdir_list);
128 while( list!=NULL )
129 {
130 mpd_Directory *dir;
132 entity = list->data;
133 dir = entity->info.directory;
134 add_directory(c, dir->path);
135 mpd_freeInfoEntity(entity);
136 list->data=NULL;
137 list=list->next;
138 }
139 g_list_free(subdir_list);
140 return 0;
141 }
143 static void
144 select_entry(screen_t *screen, mpd_client_t *c)
145 {
146 list_window_t *w = screen->filelist;
147 filelist_entry_t *entry;
149 entry = ( filelist_entry_t *) g_list_nth_data(c->filelist, w->selected);
150 if( entry==NULL || entry->entity==NULL)
151 return;
153 if( entry->entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY )
154 {
155 mpd_Directory *dir = entry->entity->info.directory;
156 add_directory(c, dir->path);
157 return;
158 }
160 if( entry->entity->type!=MPD_INFO_ENTITY_TYPE_SONG )
161 return; /* No support for adding dirs... :( */
163 entry->selected = !entry->selected;
165 if( entry->selected )
166 {
167 if( entry->entity->type==MPD_INFO_ENTITY_TYPE_SONG )
168 {
169 mpd_Song *song = entry->entity->info.song;
171 mpd_sendAddCommand(c->connection, song->file);
172 mpd_finishCommand(c->connection);
174 screen_status_printf("Adding \'%s\' to playlist\n",
175 mpc_get_song_name(song));
176 }
177 }
178 else
179 {
180 if( entry->entity->type==MPD_INFO_ENTITY_TYPE_SONG )
181 {
182 int i;
183 mpd_Song *song = entry->entity->info.song;
185 i = mpc_playlist_get_song_index(c, song->file);
186 if( i>=0 )
187 {
188 mpd_sendDeleteCommand(c->connection, i);
189 mpd_finishCommand(c->connection);
190 screen_status_printf("Removed \'%s\' from playlist\n",
191 mpc_get_song_name(song));
193 }
194 }
195 }
197 }
199 void
200 file_clear_highlights(mpd_client_t *c)
201 {
202 GList *list = g_list_first(c->filelist);
204 while( list )
205 {
206 filelist_entry_t *entry = list->data;
208 entry->selected = 0;
209 list = list->next;
210 }
211 }
213 void
214 file_clear_highlight(mpd_client_t *c, mpd_Song *song)
215 {
216 GList *list = g_list_first(c->filelist);
218 if( !song )
219 return;
221 while( list )
222 {
223 filelist_entry_t *entry = list->data;
224 mpd_InfoEntity *entity = entry->entity;
226 if( entity && entity->type==MPD_INFO_ENTITY_TYPE_SONG )
227 {
228 mpd_Song *song2 = entity->info.song;
230 if( strcmp(song->file, song2->file) == 0 )
231 {
232 entry->selected = 0;
233 }
234 }
235 list = list->next;
236 }
237 }
239 char *
240 file_get_header(mpd_client_t *c)
241 {
242 static char buf[64];
243 char *tmp;
245 tmp = utf8_to_locale(basename(c->cwd));
246 snprintf(buf, 64,
247 TOP_HEADER_FILE ": %s ",
248 tmp
249 );
250 free(tmp);
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 return 1;
302 case CMD_SELECT:
303 select_entry(screen, c);
304 /* continue and select next item... */
305 cmd = CMD_LIST_NEXT;
306 break;
307 case CMD_LIST_FIND:
308 if( screen->findbuf )
309 {
310 free(screen->findbuf);
311 screen->findbuf=NULL;
312 }
313 /* continue... */
314 case CMD_LIST_FIND_NEXT:
315 if( !screen->findbuf )
316 screen->findbuf=screen_readln(screen->status_window.w, "/");
317 if( list_window_find(screen->filelist,
318 list_callback,
319 c,
320 screen->findbuf) == 0 )
321 {
322 screen->filelist->repaint = 1;
323 }
324 else
325 {
326 screen_status_printf("Unable to find \'%s\'", screen->findbuf);
327 beep();
328 }
329 return 1;
330 default:
331 break;
332 }
333 return list_window_cmd(screen->filelist, c->filelist_length, cmd);
334 }