blob: aea81a71d474154fc47084d4a206071a0086ca33 [file] [log] [blame]
Björn Stenberg8a5de5f2005-01-17 11:39:46 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
Björn Stenberg5a2f0482005-01-17 16:06:07 +000010 * Copyright (C) 2005 by Björn Stenberg
Björn Stenberg8a5de5f2005-01-17 11:39:46 +000011 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <stdlib.h>
20#include <file.h>
21#include <dir.h>
22#include <string.h>
23#include <kernel.h>
24#include <lcd.h>
25#include <debug.h>
26#include <font.h>
Jean-Philippe Bernardy00cf0da2005-02-15 15:30:19 +000027#include <limits.h>
Björn Stenberg8a5de5f2005-01-17 11:39:46 +000028#include "bookmark.h"
29#include "tree.h"
30#include "settings.h"
31#include "filetypes.h"
32#include "talk.h"
33#include "playlist.h"
Christi Scarborough4c0b83f2005-11-17 20:14:59 +000034#include "gwps.h"
Björn Stenberg8a5de5f2005-01-17 11:39:46 +000035#include "lang.h"
36#include "language.h"
37#include "screens.h"
38#include "plugin.h"
39#include "rolo.h"
Björn Stenberga50cc0b2005-01-17 12:56:00 +000040#include "sprintf.h"
Miika Pekkarinenab78b042005-10-07 17:38:05 +000041#include "dircache.h"
Kevin Ferraree991bee2005-11-16 15:12:15 +000042#include "splash.h"
Hardeep Sidhu941de852006-02-05 19:35:03 +000043#include "yesno.h"
Nicolas Pennequin9f4bd872007-02-14 14:40:24 +000044#include "cuesheet.h"
Frank Dischner75c3d0b2006-03-29 16:21:42 +000045#ifdef HAVE_LCD_BITMAP
46#include "keyboard.h"
47#endif
Björn Stenberg8a5de5f2005-01-17 11:39:46 +000048
Jonathan Gordon8ff3a652007-02-18 02:04:47 +000049#if CONFIG_TUNER
Hristo Kovachev009853f2006-04-02 12:23:08 +000050#include "radio.h"
51#endif
52
Nicolas Pennequin1cf2ec32007-04-25 22:08:00 +000053#if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1))
Peter D'Hoye93b899d2006-05-21 11:00:02 +000054#include "backdrop.h"
55#endif
56
Björn Stenberg8a5de5f2005-01-17 11:39:46 +000057int ft_build_playlist(struct tree_context* c, int start_index)
58{
59 int i;
60 int start=start_index;
61
62 struct entry *dircache = c->dircache;
63
64 for(i = 0;i < c->filesindir;i++)
65 {
Jonathan Gordon36a2e302007-04-18 13:03:01 +000066 if((dircache[i].attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO)
Björn Stenberg8a5de5f2005-01-17 11:39:46 +000067 {
68 DEBUGF("Adding %s\n", dircache[i].name);
69 if (playlist_add(dircache[i].name) < 0)
70 break;
71 }
72 else
73 {
74 /* Adjust the start index when se skip non-MP3 entries */
75 if(i < start)
76 start_index--;
77 }
78 }
79
80 return start_index;
81}
82
83/* walk a directory and check all dircache entries if a .talk file exists */
84static void check_file_thumbnails(struct tree_context* c)
85{
86 int i;
Miika Pekkarinenab78b042005-10-07 17:38:05 +000087 struct dircache_entry *entry;
Björn Stenberg8a5de5f2005-01-17 11:39:46 +000088 struct entry* dircache = c->dircache;
Miika Pekkarinenab78b042005-10-07 17:38:05 +000089 DIRCACHED *dir;
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +000090
Miika Pekkarinenab78b042005-10-07 17:38:05 +000091 dir = opendir_cached(c->currdir);
Björn Stenberg8a5de5f2005-01-17 11:39:46 +000092 if(!dir)
93 return;
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +000094 /* mark all files as non talking, except the .talk ones */
95 for (i=0; i < c->filesindir; i++)
Björn Stenberg8a5de5f2005-01-17 11:39:46 +000096 {
97 if (dircache[i].attr & ATTR_DIRECTORY)
98 continue; /* we're not touching directories */
99
100 if (strcasecmp(file_thumbnail_ext,
101 &dircache[i].name[strlen(dircache[i].name)
102 - strlen(file_thumbnail_ext)]))
103 { /* no .talk file */
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000104 dircache[i].attr &= ~FILE_ATTR_THUMBNAIL; /* clear */
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000105 }
106 else
107 { /* .talk file, we later let them speak themselves */
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000108 dircache[i].attr |= FILE_ATTR_THUMBNAIL; /* set */
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000109 }
110 }
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +0000111
Miika Pekkarinenab78b042005-10-07 17:38:05 +0000112 while((entry = readdir_cached(dir)) != 0) /* walk directory */
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000113 {
114 int ext_pos;
115
Daniel Stenbergf981ea92005-12-05 22:44:42 +0000116 ext_pos = strlen((char *)entry->d_name) - strlen(file_thumbnail_ext);
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000117 if (ext_pos <= 0 /* too short to carry ".talk" */
118 || (entry->attribute & ATTR_DIRECTORY) /* no file */
Daniel Stenbergf981ea92005-12-05 22:44:42 +0000119 || strcasecmp((char *)&entry->d_name[ext_pos], file_thumbnail_ext))
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000120 { /* or doesn't end with ".talk", no candidate */
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +0000121 continue;
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000122 }
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +0000123
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000124 /* terminate the (disposable) name in dir buffer,
125 this truncates off the ".talk" without needing an extra buffer */
126 entry->d_name[ext_pos] = '\0';
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +0000127
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000128 /* search corresponding file in dir cache */
129 for (i=0; i < c->filesindir; i++)
130 {
Daniel Stenbergf981ea92005-12-05 22:44:42 +0000131 if (!strcasecmp(dircache[i].name, (char *)entry->d_name))
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000132 { /* match */
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000133 dircache[i].attr |= FILE_ATTR_THUMBNAIL; /* set the flag */
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000134 break; /* exit search loop, because we found it */
135 }
136 }
137 }
Miika Pekkarinenab78b042005-10-07 17:38:05 +0000138 closedir_cached(dir);
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000139}
140
141/* support function for qsort() */
142static int compare(const void* p1, const void* p2)
143{
144 struct entry* e1 = (struct entry*)p1;
145 struct entry* e2 = (struct entry*)p2;
146 int criteria;
147
148 if (e1->attr & ATTR_DIRECTORY && e2->attr & ATTR_DIRECTORY)
149 { /* two directories */
150 criteria = global_settings.sort_dir;
Björn Stenbergb2d84b12005-01-17 12:29:27 +0000151
Nils Wallménius685f6bb2007-03-17 00:55:23 +0000152#ifdef HAVE_MULTIVOLUME
Björn Stenbergb2d84b12005-01-17 12:29:27 +0000153 if (e1->attr & ATTR_VOLUME || e2->attr & ATTR_VOLUME)
154 { /* a volume identifier is involved */
155 if (e1->attr & ATTR_VOLUME && e2->attr & ATTR_VOLUME)
156 criteria = 0; /* two volumes: sort alphabetically */
157 else /* only one is a volume: volume first */
158 return (e2->attr & ATTR_VOLUME) - (e1->attr & ATTR_VOLUME);
159 }
Nils Wallménius685f6bb2007-03-17 00:55:23 +0000160#endif
161
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000162 }
163 else if (!(e1->attr & ATTR_DIRECTORY) && !(e2->attr & ATTR_DIRECTORY))
164 { /* two files */
165 criteria = global_settings.sort_file;
166 }
167 else /* dir and file, dir goes first */
168 return ( e2->attr & ATTR_DIRECTORY ) - ( e1->attr & ATTR_DIRECTORY );
169
170 switch(criteria)
171 {
172 case 3: /* sort type */
173 {
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000174 int t1 = e1->attr & FILE_ATTR_MASK;
175 int t2 = e2->attr & FILE_ATTR_MASK;
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000176
177 if (!t1) /* unknown type */
Jean-Philippe Bernardy87587132005-02-12 12:29:41 +0000178 t1 = INT_MAX; /* gets a high number, to sort after known */
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000179 if (!t2) /* unknown type */
Jean-Philippe Bernardy87587132005-02-12 12:29:41 +0000180 t2 = INT_MAX; /* gets a high number, to sort after known */
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000181
182 if (t1 - t2) /* if different */
183 return t1 - t2;
184 /* else fall through to alphabetical sorting */
185 }
Anton Oleynikovd102e1f2005-11-02 22:32:04 +0000186 case 0: /* sort alphabetically asc */
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000187 if (global_settings.sort_case)
188 return strncmp(e1->name, e2->name, MAX_PATH);
189 else
190 return strncasecmp(e1->name, e2->name, MAX_PATH);
191
Anton Oleynikovd102e1f2005-11-02 22:32:04 +0000192 case 4: /* sort alphabetically desc */
193 if (global_settings.sort_case)
194 return strncmp(e2->name, e1->name, MAX_PATH);
195 else
196 return strncasecmp(e2->name, e1->name, MAX_PATH);
197
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000198 case 1: /* sort date */
199 return e1->time_write - e2->time_write;
200
201 case 2: /* sort date, newest first */
202 return e2->time_write - e1->time_write;
203 }
204 return 0; /* never reached */
205}
206
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +0000207/* load and sort directory into dircache. returns NULL on failure. */
Björn Stenbergcdd79a32005-01-18 22:50:47 +0000208int ft_load(struct tree_context* c, const char* tempdir)
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000209{
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000210 int i;
Björn Stenberga50cc0b2005-01-17 12:56:00 +0000211 int name_buffer_used = 0;
Miika Pekkarinenab78b042005-10-07 17:38:05 +0000212 DIRCACHED *dir;
Björn Stenbergcdd79a32005-01-18 22:50:47 +0000213
214 if (tempdir)
Miika Pekkarinenab78b042005-10-07 17:38:05 +0000215 dir = opendir_cached(tempdir);
Björn Stenbergcdd79a32005-01-18 22:50:47 +0000216 else
Miika Pekkarinenab78b042005-10-07 17:38:05 +0000217 dir = opendir_cached(c->currdir);
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000218 if(!dir)
219 return -1; /* not a directory */
220
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000221 c->dirsindir = 0;
Björn Stenberg84c7d8802005-01-18 22:45:00 +0000222 c->dirfull = false;
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000223
224 for ( i=0; i < global_settings.max_files_in_dir; i++ ) {
225 int len;
Miika Pekkarinenab78b042005-10-07 17:38:05 +0000226 struct dircache_entry *entry = readdir_cached(dir);
Björn Stenberg84c7d8802005-01-18 22:45:00 +0000227 struct entry* dptr =
228 (struct entry*)(c->dircache + i * sizeof(struct entry));
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000229 if (!entry)
230 break;
231
Daniel Stenbergf981ea92005-12-05 22:44:42 +0000232 len = strlen((char *)entry->d_name);
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000233
234 /* skip directories . and .. */
235 if ((entry->attribute & ATTR_DIRECTORY) &&
Daniel Stenbergf981ea92005-12-05 22:44:42 +0000236 (((len == 1) && (!strncmp((char *)entry->d_name, ".", 1))) ||
237 ((len == 2) && (!strncmp((char *)entry->d_name, "..", 2))))) {
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000238 i--;
239 continue;
240 }
241
242 /* Skip FAT volume ID */
243 if (entry->attribute & ATTR_VOLUME_ID) {
244 i--;
245 continue;
246 }
247
248 /* filter out dotfiles and hidden files */
249 if (*c->dirfilter != SHOW_ALL &&
250 ((entry->d_name[0]=='.') ||
251 (entry->attribute & ATTR_HIDDEN))) {
252 i--;
253 continue;
254 }
255
256 dptr->attr = entry->attribute;
257
258 /* check for known file types */
Henrik Backeb2473d52005-09-02 15:05:35 +0000259 if ( !(dptr->attr & ATTR_DIRECTORY) )
Daniel Stenbergf981ea92005-12-05 22:44:42 +0000260 dptr->attr |= filetype_get_attr((char *)entry->d_name);
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000261
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000262 /* filter out non-visible files */
Jonas Häggqvist280d9cc2005-08-17 17:53:54 +0000263 if ((!(dptr->attr & ATTR_DIRECTORY) && (
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000264 (*c->dirfilter == SHOW_PLAYLIST &&
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000265 (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_M3U) ||
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000266 ((*c->dirfilter == SHOW_MUSIC &&
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000267 (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO) &&
268 (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_M3U) ||
Jonas Häggqvist280d9cc2005-08-17 17:53:54 +0000269 (*c->dirfilter == SHOW_SUPPORTED && !filetype_supported(dptr->attr)))) ||
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000270 (*c->dirfilter == SHOW_WPS && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_WPS) ||
Christi Scarborough4c0b83f2005-11-17 20:14:59 +0000271#ifdef HAVE_REMOTE_LCD
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000272 (*c->dirfilter == SHOW_RWPS && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_RWPS) ||
Christi Scarborough4c0b83f2005-11-17 20:14:59 +0000273#endif
Jonathan Gordon8ff3a652007-02-18 02:04:47 +0000274#if CONFIG_TUNER
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000275 (*c->dirfilter == SHOW_FMR && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_FMR) ||
Hristo Kovachev009853f2006-04-02 12:23:08 +0000276#endif
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000277 (*c->dirfilter == SHOW_CFG && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_CFG) ||
278 (*c->dirfilter == SHOW_LNG && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_LNG) ||
279 (*c->dirfilter == SHOW_MOD && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_MOD) ||
280 (*c->dirfilter == SHOW_FONT && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_FONT) ||
281 (*c->dirfilter == SHOW_PLUGINS && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_ROCK))
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000282 {
283 i--;
284 continue;
285 }
286
287 if (len > c->name_buffer_size - name_buffer_used - 1) {
288 /* Tell the world that we ran out of buffer space */
Björn Stenberg84c7d8802005-01-18 22:45:00 +0000289 c->dirfull = true;
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000290 break;
291 }
292 dptr->name = &c->name_buffer[name_buffer_used];
Jean-Philippe Bernardy87587132005-02-12 12:29:41 +0000293 dptr->time_write =
294 (long)entry->wrtdate<<16 |
295 (long)entry->wrttime; /* in one # */
Daniel Stenbergf981ea92005-12-05 22:44:42 +0000296 strcpy(dptr->name, (char *)entry->d_name);
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000297 name_buffer_used += len + 1;
298
299 if (dptr->attr & ATTR_DIRECTORY) /* count the remaining dirs */
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +0000300 c->dirsindir++;
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000301 }
302 c->filesindir = i;
Björn Stenberg84c7d8802005-01-18 22:45:00 +0000303 c->dirlength = i;
Miika Pekkarinenab78b042005-10-07 17:38:05 +0000304 closedir_cached(dir);
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000305
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000306 qsort(c->dircache,i,sizeof(struct entry),compare);
307
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +0000308 /* If thumbnail talking is enabled, make an extra run to mark files with
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000309 associated thumbnails, so we don't do unsuccessful spinups later. */
310 if (global_settings.talk_file == 3)
311 check_file_thumbnails(c); /* map .talk to ours */
312
313 return 0;
314}
315
316int ft_enter(struct tree_context* c)
317{
318 int rc = 0;
319 char buf[MAX_PATH];
320 struct entry *dircache = c->dircache;
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +0000321 struct entry* file = &dircache[c->selected_item];
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000322 bool reload_dir = false;
323 bool start_wps = false;
324 bool exit_func = false;
325
326 if (c->currdir[1])
327 snprintf(buf,sizeof(buf),"%s/%s",c->currdir, file->name);
328 else
329 snprintf(buf,sizeof(buf),"/%s",file->name);
330
331 if (file->attr & ATTR_DIRECTORY) {
332 memcpy(c->currdir, buf, sizeof(c->currdir));
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +0000333 if ( c->dirlevel < MAX_DIR_LEVELS )
334 c->selected_item_history[c->dirlevel] = c->selected_item;
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000335 c->dirlevel++;
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +0000336 c->selected_item=0;
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000337 }
338 else {
339 int seed = current_tick;
340 bool play = false;
341 int start_index=0;
342
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000343 switch ( file->attr & FILE_ATTR_MASK ) {
344 case FILE_ATTR_M3U:
Björn Stenbergfc390af2006-03-19 08:40:31 +0000345 if (global_settings.party_mode) {
Jens Arnold4d6374c2007-03-16 21:56:08 +0000346 gui_syncsplash(HZ, str(LANG_PARTY_MODE));
Björn Stenbergfc390af2006-03-19 08:40:31 +0000347 break;
348 }
349
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000350 if (bookmark_autoload(buf))
351 break;
352
Jens Arnold4d6374c2007-03-16 21:56:08 +0000353 gui_syncsplash(0, str(LANG_WAIT));
Zakk Robertsddb36b22006-04-15 06:23:34 +0000354
Hardeep Sidhu941de852006-02-05 19:35:03 +0000355 /* about to create a new current playlist...
356 allow user to cancel the operation */
Björn Stenberg5b4307e2006-03-19 12:09:41 +0000357 if (global_settings.warnon_erase_dynplaylist &&
Hardeep Sidhu941de852006-02-05 19:35:03 +0000358 playlist_modified(NULL))
359 {
360 char *lines[]={str(LANG_WARN_ERASEDYNPLAYLIST_PROMPT)};
361 struct text_message message={lines, 1};
362
363 if(gui_syncyesno_run(&message, NULL, NULL) != YESNO_YES)
364 break;
365 }
366
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000367 if (playlist_create(c->currdir, file->name) != -1)
368 {
369 if (global_settings.playlist_shuffle)
370 playlist_shuffle(seed, -1);
371 start_index = 0;
372 playlist_start(start_index,0);
373 play = true;
374 }
375 break;
376
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000377 case FILE_ATTR_AUDIO:
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000378 if (bookmark_autoload(c->currdir))
379 break;
380
Jens Arnold4d6374c2007-03-16 21:56:08 +0000381 gui_syncsplash(0, str(LANG_WAIT));
Zakk Robertsddb36b22006-04-15 06:23:34 +0000382
Hardeep Sidhu941de852006-02-05 19:35:03 +0000383 /* about to create a new current playlist...
384 allow user to cancel the operation */
Zakk Robertsddb36b22006-04-15 06:23:34 +0000385 if (global_settings.warnon_erase_dynplaylist &&
386 !global_settings.party_mode &&
Hardeep Sidhu941de852006-02-05 19:35:03 +0000387 playlist_modified(NULL))
388 {
389 char *lines[]={str(LANG_WARN_ERASEDYNPLAYLIST_PROMPT)};
390 struct text_message message={lines, 1};
391
392 if(gui_syncyesno_run(&message, NULL, NULL) != YESNO_YES)
393 break;
394 }
395
Miika Pekkarinen887cfeb2006-08-10 09:50:45 +0000396 if (global_settings.party_mode)
397 {
Björn Stenbergfc390af2006-03-19 08:40:31 +0000398 playlist_insert_track(NULL, buf,
Miika Pekkarinen887cfeb2006-08-10 09:50:45 +0000399 PLAYLIST_INSERT_LAST, true, true);
Jens Arnold4d6374c2007-03-16 21:56:08 +0000400 gui_syncsplash(HZ, str(LANG_QUEUE_LAST));
Björn Stenbergfc390af2006-03-19 08:40:31 +0000401 }
402 else if (playlist_create(c->currdir, NULL) != -1)
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000403 {
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +0000404 start_index = ft_build_playlist(c, c->selected_item);
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000405 if (global_settings.playlist_shuffle)
406 {
407 start_index = playlist_shuffle(seed, start_index);
408
409 /* when shuffling dir.: play all files
410 even if the file selected by user is
411 not the first one */
412 if (!global_settings.play_selected)
413 start_index = 0;
414 }
415
416 playlist_start(start_index, 0);
417 play = true;
418 }
419 break;
420
Jonathan Gordon8ff3a652007-02-18 02:04:47 +0000421#if CONFIG_TUNER
Hristo Kovachev009853f2006-04-02 12:23:08 +0000422 /* fmr preset file */
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000423 case FILE_ATTR_FMR:
Zakk Robertsddb36b22006-04-15 06:23:34 +0000424
Jens Arnold4d6374c2007-03-16 21:56:08 +0000425 gui_syncsplash(0, str(LANG_WAIT));
Zakk Robertsddb36b22006-04-15 06:23:34 +0000426
Hristo Kovachev009853f2006-04-02 12:23:08 +0000427 /* Preset inside the default folder. */
428 if(!strncasecmp(FMPRESET_PATH, buf, strlen(FMPRESET_PATH)))
429 {
430 set_file(buf, global_settings.fmr_file, MAX_FILENAME);
431 radio_load_presets(global_settings.fmr_file);
Michael Sevakis0f175322007-02-08 10:36:49 +0000432 if(!in_radio_screen())
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000433 radio_screen();
Hristo Kovachev009853f2006-04-02 12:23:08 +0000434 }
Zakk Robertsddb36b22006-04-15 06:23:34 +0000435 /*
Hristo Kovachev009853f2006-04-02 12:23:08 +0000436 * Preset outside default folder, we can choose such only
Zakk Robertsddb36b22006-04-15 06:23:34 +0000437 * if we are out of the radio screen, so the check for the
438 * radio status isn't neccessary
Hristo Kovachev009853f2006-04-02 12:23:08 +0000439 */
440 else
441 {
442 radio_load_presets(buf);
443 radio_screen();
444 }
Zakk Robertsddb36b22006-04-15 06:23:34 +0000445
Hristo Kovachev009853f2006-04-02 12:23:08 +0000446 break;
447#endif
448
449
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000450 /* wps config file */
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000451 case FILE_ATTR_WPS:
Jens Arnold4d6374c2007-03-16 21:56:08 +0000452 gui_syncsplash(0, str(LANG_WAIT));
Jens Arnold02978732006-11-13 00:45:21 +0000453#if LCD_DEPTH > 1
Peter D'Hoye93b899d2006-05-21 11:00:02 +0000454 unload_wps_backdrop();
455#endif
Marcoen Hirschberg53a56c12005-12-09 01:11:14 +0000456 wps_data_load(gui_wps[0].data, buf, true);
Daniel Stenbergf981ea92005-12-05 22:44:42 +0000457 set_file(buf, (char *)global_settings.wps_file,
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000458 MAX_FILENAME);
459 break;
460
Magnus Holmgrenf9fa33f2005-12-04 12:11:08 +0000461#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
Christi Scarborough4c0b83f2005-11-17 20:14:59 +0000462 /* remote-wps config file */
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000463 case FILE_ATTR_RWPS:
Jens Arnold4d6374c2007-03-16 21:56:08 +0000464 gui_syncsplash(0, str(LANG_WAIT));
Nicolas Pennequinb8a79b82007-04-26 20:32:05 +0000465#if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
466 unload_remote_wps_backdrop();
467#endif
Marcoen Hirschberg53a56c12005-12-09 01:11:14 +0000468 wps_data_load(gui_wps[1].data, buf, true);
Daniel Stenbergf981ea92005-12-05 22:44:42 +0000469 set_file(buf, (char *)global_settings.rwps_file,
Christi Scarborough4c0b83f2005-11-17 20:14:59 +0000470 MAX_FILENAME);
471 break;
472#endif
473
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000474 case FILE_ATTR_CFG:
Jens Arnold4d6374c2007-03-16 21:56:08 +0000475 gui_syncsplash(0, str(LANG_WAIT));
Jonathan Gordonb2e50902007-01-23 13:40:44 +0000476 if (!settings_load_config(buf,true))
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000477 break;
Jens Arnold4d6374c2007-03-16 21:56:08 +0000478 gui_syncsplash(HZ, str(LANG_SETTINGS_LOADED));
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000479 break;
480
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000481 case FILE_ATTR_BMARK:
Jens Arnold4d6374c2007-03-16 21:56:08 +0000482 gui_syncsplash(0, str(LANG_WAIT));
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000483 bookmark_load(buf, false);
484 reload_dir = true;
485 break;
486
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000487 case FILE_ATTR_LNG:
Jens Arnold4d6374c2007-03-16 21:56:08 +0000488 gui_syncsplash(0, str(LANG_WAIT));
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000489 if(!lang_load(buf)) {
Daniel Stenbergf981ea92005-12-05 22:44:42 +0000490 set_file(buf, (char *)global_settings.lang_file,
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000491 MAX_FILENAME);
492 talk_init(); /* use voice of same language */
Jens Arnold4d6374c2007-03-16 21:56:08 +0000493 gui_syncsplash(HZ, str(LANG_LANGUAGE_LOADED));
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000494 }
495 break;
496
497#ifdef HAVE_LCD_BITMAP
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000498 case FILE_ATTR_FONT:
Jens Arnold4d6374c2007-03-16 21:56:08 +0000499 gui_syncsplash(0, str(LANG_WAIT));
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000500 font_load(buf);
Daniel Stenbergf981ea92005-12-05 22:44:42 +0000501 set_file(buf, (char *)global_settings.font_file, MAX_FILENAME);
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000502 break;
Frank Dischner75c3d0b2006-03-29 16:21:42 +0000503
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000504 case FILE_ATTR_KBD:
Jens Arnold4d6374c2007-03-16 21:56:08 +0000505 gui_syncsplash(0, str(LANG_WAIT));
Frank Dischner75c3d0b2006-03-29 16:21:42 +0000506 if (!load_kbd(buf))
Jens Arnold4d6374c2007-03-16 21:56:08 +0000507 gui_syncsplash(HZ, str(LANG_KEYBOARD_LOADED));
Frank Dischner75c3d0b2006-03-29 16:21:42 +0000508 set_file(buf, (char *)global_settings.kbd_file, MAX_FILENAME);
509 break;
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000510#endif
511
512#ifndef SIMULATOR
513 /* firmware file */
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000514 case FILE_ATTR_MOD:
Jens Arnold4d6374c2007-03-16 21:56:08 +0000515 gui_syncsplash(0, str(LANG_WAIT));
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000516 rolo_load(buf);
517 break;
518#endif
519
520 /* plugin file */
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000521 case FILE_ATTR_ROCK:
Björn Stenbergfc390af2006-03-19 08:40:31 +0000522 if (global_settings.party_mode) {
Jens Arnold4d6374c2007-03-16 21:56:08 +0000523 gui_syncsplash(HZ, str(LANG_PARTY_MODE));
Björn Stenbergfc390af2006-03-19 08:40:31 +0000524 break;
525 }
526
Jens Arnold4d6374c2007-03-16 21:56:08 +0000527 gui_syncsplash(0, str(LANG_WAIT));
Zakk Robertsddb36b22006-04-15 06:23:34 +0000528
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000529 if (plugin_load(buf,NULL) == PLUGIN_USB_CONNECTED)
530 {
531 if(*c->dirfilter > NUM_FILTER_MODES)
532 /* leave sub-browsers after usb, doing
533 otherwise might be confusing to the user */
534 exit_func = true;
535 else
Jens Arnold32be5902005-05-17 18:28:32 +0000536 reload_dir = true;
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000537 }
538 break;
539
Jonathan Gordon36a2e302007-04-18 13:03:01 +0000540 case FILE_ATTR_CUE:
Nicolas Pennequin9f4bd872007-02-14 14:40:24 +0000541 display_cuesheet_content(buf);
542 break;
543
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000544 default:
545 {
Björn Stenbergfc390af2006-03-19 08:40:31 +0000546 char* plugin;
547
548 if (global_settings.party_mode) {
Jens Arnold4d6374c2007-03-16 21:56:08 +0000549 gui_syncsplash(HZ, str(LANG_PARTY_MODE));
Björn Stenbergfc390af2006-03-19 08:40:31 +0000550 break;
551 }
Zakk Robertsddb36b22006-04-15 06:23:34 +0000552
Björn Stenbergfc390af2006-03-19 08:40:31 +0000553 plugin = filetype_get_plugin(file);
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000554 if (plugin)
555 {
556 if (plugin_load(plugin,buf) == PLUGIN_USB_CONNECTED)
Jens Arnold32be5902005-05-17 18:28:32 +0000557 reload_dir = true;
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000558 }
559 break;
560 }
561 }
562
563 if ( play ) {
Christi Scarborough9e8918b2005-06-29 12:23:09 +0000564 /* the resume_index must always be the index in the
565 shuffled list in case shuffle is enabled */
Jonathan Gordon228d62d2007-01-24 02:19:22 +0000566 global_status.resume_index = start_index;
567 global_status.resume_offset = 0;
568 status_save();
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000569
570 start_wps = true;
571 }
572 else {
573 if (*c->dirfilter > NUM_FILTER_MODES &&
574 *c->dirfilter != SHOW_FONT &&
575 *c->dirfilter != SHOW_PLUGINS)
576 {
577 exit_func = true;
578 }
579 }
580 }
581
582 if (reload_dir)
583 rc = 1;
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000584 if (start_wps)
Jens Arnold32be5902005-05-17 18:28:32 +0000585 rc = 2;
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000586 if (exit_func)
Jens Arnold32be5902005-05-17 18:28:32 +0000587 rc = 3;
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000588
589 return rc;
590}
591
592int ft_exit(struct tree_context* c)
593{
594 extern char lastfile[]; /* from tree.c */
595 char buf[MAX_PATH];
596 int rc = 0;
597 bool exit_func = false;
598
599 int i = strlen(c->currdir);
600 if (i>1) {
601 while (c->currdir[i-1]!='/')
602 i--;
603 strcpy(buf,&c->currdir[i]);
604 if (i==1)
605 c->currdir[i]=0;
606 else
607 c->currdir[i-1]=0;
608
609 if (*c->dirfilter > NUM_FILTER_MODES && c->dirlevel < 1)
610 exit_func = true;
611
612 c->dirlevel--;
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +0000613 if ( c->dirlevel < MAX_DIR_LEVELS )
614 c->selected_item=c->selected_item_history[c->dirlevel];
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000615 else
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +0000616 c->selected_item=0;
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000617
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +0000618 /* if undefined position */
619 if (c->selected_item == -1)
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000620 strcpy(lastfile, buf);
621 }
622 else
623 {
624 if (*c->dirfilter > NUM_FILTER_MODES && c->dirlevel < 1)
625 exit_func = true;
626 }
627
628 if (exit_func)
Jens Arnold32be5902005-05-17 18:28:32 +0000629 rc = 3;
Björn Stenberg8a5de5f2005-01-17 11:39:46 +0000630
631 return rc;
632}