diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/lang/english.lang | 28 | ||||
-rw-r--r-- | apps/menus/settings_menu.c | 86 | ||||
-rw-r--r-- | apps/metadata.c | 47 | ||||
-rw-r--r-- | apps/metadata.h | 7 | ||||
-rw-r--r-- | apps/playback.c | 9 | ||||
-rw-r--r-- | apps/settings.h | 7 | ||||
-rw-r--r-- | apps/settings_list.c | 9 |
7 files changed, 165 insertions, 28 deletions
diff --git a/apps/lang/english.lang b/apps/lang/english.lang index dd8ed84caf..7da2cc2959 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang | |||
@@ -12716,3 +12716,31 @@ | |||
12716 | *: "Automatic resume" | 12716 | *: "Automatic resume" |
12717 | </voice> | 12717 | </voice> |
12718 | </phrase> | 12718 | </phrase> |
12719 | <phrase> | ||
12720 | id: LANG_AUTORESUME_AUTOMATIC | ||
12721 | desc: resume on automatic track change | ||
12722 | user: core | ||
12723 | <source> | ||
12724 | *: "Resume on automatic track change" | ||
12725 | </source> | ||
12726 | <dest> | ||
12727 | *: "Resume on automatic track change" | ||
12728 | </dest> | ||
12729 | <voice> | ||
12730 | *: "Resume on automatic track change" | ||
12731 | </voice> | ||
12732 | </phrase> | ||
12733 | <phrase> | ||
12734 | id: LANG_AUTORESUME_CUSTOM | ||
12735 | desc: enable customization of resume on automatic track change | ||
12736 | user: core | ||
12737 | <source> | ||
12738 | *: "Custom path/genre substrings (comma-separated)" | ||
12739 | </source> | ||
12740 | <dest> | ||
12741 | *: "Custom path/genre substrings (comma-separated)" | ||
12742 | </dest> | ||
12743 | <voice> | ||
12744 | *: "Custom path/genre substrings (comma-separated)" | ||
12745 | </voice> | ||
12746 | </phrase> | ||
diff --git a/apps/menus/settings_menu.c b/apps/menus/settings_menu.c index ce03e1a646..363792870d 100644 --- a/apps/menus/settings_menu.c +++ b/apps/menus/settings_menu.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "action.h" | 28 | #include "action.h" |
29 | #include "settings.h" | 29 | #include "settings.h" |
30 | #include "menu.h" | 30 | #include "menu.h" |
31 | #include "keyboard.h" | ||
31 | #include "sound_menu.h" | 32 | #include "sound_menu.h" |
32 | #include "exported_menus.h" | 33 | #include "exported_menus.h" |
33 | #include "tree.h" | 34 | #include "tree.h" |
@@ -368,6 +369,64 @@ MAKE_MENU(bookmark_settings_menu, ID2P(LANG_BOOKMARK_SETTINGS), 0, | |||
368 | /***********************************/ | 369 | /***********************************/ |
369 | 370 | ||
370 | /***********************************/ | 371 | /***********************************/ |
372 | /* AUTORESUME MENU */ | ||
373 | #ifdef HAVE_TAGCACHE | ||
374 | #if CONFIG_CODEC == SWCODEC | ||
375 | |||
376 | static int autoresume_callback(int action, const struct menu_item_ex *this_item) | ||
377 | { | ||
378 | (void)this_item; | ||
379 | |||
380 | if (action == ACTION_EXIT_MENUITEM /* on exit */ | ||
381 | && global_settings.autoresume_enable | ||
382 | && !tagcache_is_usable()) | ||
383 | { | ||
384 | static const char *lines[] = {ID2P(LANG_TAGCACHE_BUSY), | ||
385 | ID2P(LANG_TAGCACHE_FORCE_UPDATE)}; | ||
386 | static const struct text_message message = {lines, 2}; | ||
387 | |||
388 | if (gui_syncyesno_run(&message, NULL, NULL) == YESNO_YES) | ||
389 | tagcache_rebuild_with_splash(); | ||
390 | } | ||
391 | return action; | ||
392 | } | ||
393 | |||
394 | static int autoresume_nexttrack_callback(int action, | ||
395 | const struct menu_item_ex *this_item) | ||
396 | { | ||
397 | (void)this_item; | ||
398 | static int oldval = 0; | ||
399 | switch (action) | ||
400 | { | ||
401 | case ACTION_ENTER_MENUITEM: | ||
402 | oldval = global_settings.autoresume_automatic; | ||
403 | break; | ||
404 | case ACTION_EXIT_MENUITEM: | ||
405 | if (global_settings.autoresume_automatic == AUTORESUME_NEXTTRACK_CUSTOM | ||
406 | && kbd_input ((char*) &global_settings.autoresume_strpat, | ||
407 | MAX_PATHNAME+1) < 0) | ||
408 | { | ||
409 | global_settings.autoresume_automatic = oldval; | ||
410 | } | ||
411 | } | ||
412 | return action; | ||
413 | } | ||
414 | |||
415 | MENUITEM_SETTING(autoresume_enable, &global_settings.autoresume_enable, | ||
416 | autoresume_callback); | ||
417 | MENUITEM_SETTING(autoresume_automatic, &global_settings.autoresume_automatic, | ||
418 | autoresume_nexttrack_callback); | ||
419 | |||
420 | MAKE_MENU(autoresume_menu, ID2P(LANG_AUTORESUME), | ||
421 | 0, Icon_NOICON, | ||
422 | &autoresume_enable, &autoresume_automatic); | ||
423 | |||
424 | #endif /* CONFIG_CODEC == SWCODEC */ | ||
425 | #endif /* HAVE_TAGCACHE */ | ||
426 | /* AUTORESUME MENU */ | ||
427 | /***********************************/ | ||
428 | |||
429 | /***********************************/ | ||
371 | /* VOICE MENU */ | 430 | /* VOICE MENU */ |
372 | static int talk_callback(int action,const struct menu_item_ex *this_item); | 431 | static int talk_callback(int action,const struct menu_item_ex *this_item); |
373 | MENUITEM_SETTING(talk_menu_item, &global_settings.talk_menu, NULL); | 432 | MENUITEM_SETTING(talk_menu_item, &global_settings.talk_menu, NULL); |
@@ -425,31 +484,6 @@ MAKE_MENU(hotkey_menu, ID2P(LANG_HOTKEY), 0, Icon_NOICON, | |||
425 | /***********************************/ | 484 | /***********************************/ |
426 | /* SETTINGS MENU */ | 485 | /* SETTINGS MENU */ |
427 | 486 | ||
428 | #ifdef HAVE_TAGCACHE | ||
429 | #if CONFIG_CODEC == SWCODEC | ||
430 | static int autoresume_callback(int action, const struct menu_item_ex *this_item) | ||
431 | { | ||
432 | (void)this_item; | ||
433 | |||
434 | if (action == ACTION_EXIT_MENUITEM /* on exit */ | ||
435 | && global_settings.autoresume_enable | ||
436 | && !tagcache_is_usable()) | ||
437 | { | ||
438 | static const char *lines[] = {ID2P(LANG_TAGCACHE_BUSY), | ||
439 | ID2P(LANG_TAGCACHE_FORCE_UPDATE)}; | ||
440 | static const struct text_message message = {lines, 2}; | ||
441 | |||
442 | if (gui_syncyesno_run(&message, NULL, NULL) == YESNO_YES) | ||
443 | tagcache_rebuild_with_splash(); | ||
444 | } | ||
445 | return action; | ||
446 | } | ||
447 | |||
448 | MENUITEM_SETTING(autoresume_enable, &global_settings.autoresume_enable, | ||
449 | autoresume_callback); | ||
450 | #endif | ||
451 | #endif | ||
452 | |||
453 | static struct browse_folder_info langs = { LANG_DIR, SHOW_LNG }; | 487 | static struct browse_folder_info langs = { LANG_DIR, SHOW_LNG }; |
454 | 488 | ||
455 | MENUITEM_FUNCTION(browse_langs, MENU_FUNC_USEPARAM, ID2P(LANG_LANGUAGE), | 489 | MENUITEM_FUNCTION(browse_langs, MENU_FUNC_USEPARAM, ID2P(LANG_LANGUAGE), |
@@ -465,7 +499,7 @@ MAKE_MENU(settings_menu_item, ID2P(LANG_GENERAL_SETTINGS), 0, | |||
465 | &bookmark_settings_menu, | 499 | &bookmark_settings_menu, |
466 | #ifdef HAVE_TAGCACHE | 500 | #ifdef HAVE_TAGCACHE |
467 | #if CONFIG_CODEC == SWCODEC | 501 | #if CONFIG_CODEC == SWCODEC |
468 | &autoresume_enable, | 502 | &autoresume_menu, |
469 | #endif | 503 | #endif |
470 | #endif | 504 | #endif |
471 | &browse_langs, &voice_settings_menu, | 505 | &browse_langs, &voice_settings_menu, |
diff --git a/apps/metadata.c b/apps/metadata.c index 47c0e7449b..da20a0df2b 100644 --- a/apps/metadata.c +++ b/apps/metadata.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include "debug.h" | 26 | #include "debug.h" |
27 | #include "logf.h" | 27 | #include "logf.h" |
28 | #include "settings.h" | ||
28 | #include "cuesheet.h" | 29 | #include "cuesheet.h" |
29 | #include "metadata.h" | 30 | #include "metadata.h" |
30 | 31 | ||
@@ -425,3 +426,49 @@ void copy_mp3entry(struct mp3entry *dest, const struct mp3entry *orig) | |||
425 | memcpy(dest, orig, sizeof(struct mp3entry)); | 426 | memcpy(dest, orig, sizeof(struct mp3entry)); |
426 | adjust_mp3entry(dest, dest, orig); | 427 | adjust_mp3entry(dest, dest, orig); |
427 | } | 428 | } |
429 | |||
430 | #ifdef HAVE_TAGCACHE | ||
431 | #if CONFIG_CODEC == SWCODEC | ||
432 | |||
433 | enum { AUTORESUMABLE_UNKNOWN = 0, AUTORESUMABLE_TRUE, AUTORESUMABLE_FALSE }; | ||
434 | |||
435 | bool autoresumable(struct mp3entry *id3) | ||
436 | { | ||
437 | unsigned char search[MAX_PATHNAME+1]; | ||
438 | char *saveptr, *substr; | ||
439 | bool is_resumable; | ||
440 | |||
441 | if (id3->autoresumable) /* result cached? */ | ||
442 | return id3->autoresumable == AUTORESUMABLE_TRUE; | ||
443 | |||
444 | is_resumable = true; | ||
445 | |||
446 | strcpy(search, global_settings.autoresume_strpat); | ||
447 | |||
448 | for (substr = strtok_r(search, ",", &saveptr); | ||
449 | substr; | ||
450 | substr = strtok_r(NULL, ",", &saveptr)) | ||
451 | { | ||
452 | if (id3->path && strcasestr(id3->path, substr)) | ||
453 | goto out; | ||
454 | if (id3->genre_string && strcasestr(id3->genre_string, substr)) | ||
455 | goto out; | ||
456 | } | ||
457 | |||
458 | is_resumable = false; | ||
459 | |||
460 | out: | ||
461 | /* cache result */ | ||
462 | id3->autoresumable = | ||
463 | is_resumable ? AUTORESUMABLE_TRUE : AUTORESUMABLE_FALSE; | ||
464 | |||
465 | logf("autoresumable: %s with genre %s is%s resumable", | ||
466 | id3->path, | ||
467 | id3->genre_string ? id3->genre_string : "(NULL)", | ||
468 | is_resumable ? "" : " not"); | ||
469 | |||
470 | return is_resumable; | ||
471 | } | ||
472 | |||
473 | #endif /* SWCODEC */ | ||
474 | #endif /* HAVE_TAGCACHE */ | ||
diff --git a/apps/metadata.h b/apps/metadata.h index 3831062418..b99d4d09d6 100644 --- a/apps/metadata.h +++ b/apps/metadata.h | |||
@@ -255,6 +255,8 @@ struct mp3entry { | |||
255 | int index; /* playlist index */ | 255 | int index; /* playlist index */ |
256 | 256 | ||
257 | #ifdef HAVE_TAGCACHE | 257 | #ifdef HAVE_TAGCACHE |
258 | unsigned char autoresumable; /* caches result of autoresumable() */ | ||
259 | |||
258 | /* runtime database fields */ | 260 | /* runtime database fields */ |
259 | long tagcache_idx; /* 0=invalid, otherwise idx+1 */ | 261 | long tagcache_idx; /* 0=invalid, otherwise idx+1 */ |
260 | int rating; | 262 | int rating; |
@@ -287,10 +289,15 @@ bool get_metadata(struct mp3entry* id3, int fd, const char* trackname); | |||
287 | bool mp3info(struct mp3entry *entry, const char *filename); | 289 | bool mp3info(struct mp3entry *entry, const char *filename); |
288 | void adjust_mp3entry(struct mp3entry *entry, void *dest, const void *orig); | 290 | void adjust_mp3entry(struct mp3entry *entry, void *dest, const void *orig); |
289 | void copy_mp3entry(struct mp3entry *dest, const struct mp3entry *orig); | 291 | void copy_mp3entry(struct mp3entry *dest, const struct mp3entry *orig); |
292 | |||
290 | #if CONFIG_CODEC == SWCODEC | 293 | #if CONFIG_CODEC == SWCODEC |
291 | void strip_tags(int handle_id); | 294 | void strip_tags(int handle_id); |
292 | #endif | 295 | #endif |
293 | 296 | ||
297 | #ifdef HAVE_TAGCACHE | ||
298 | bool autoresumable(struct mp3entry *id3); | ||
299 | #endif | ||
300 | |||
294 | #endif | 301 | #endif |
295 | 302 | ||
296 | 303 | ||
diff --git a/apps/playback.c b/apps/playback.c index e33a4ac507..fe7b74893a 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -1002,8 +1002,13 @@ static void audio_update_trackinfo(void) | |||
1002 | thistrack_id3->elapsed = 0; | 1002 | thistrack_id3->elapsed = 0; |
1003 | 1003 | ||
1004 | #ifdef HAVE_TAGCACHE | 1004 | #ifdef HAVE_TAGCACHE |
1005 | /* Resume all manually selected tracks if so configured */ | 1005 | /* Ignoring resume position for automatic track change if so configured */ |
1006 | resume = global_settings.autoresume_enable && !automatic_skip; | 1006 | resume = global_settings.autoresume_enable && |
1007 | (!automatic_skip /* Resume all manually selected tracks */ | ||
1008 | || global_settings.autoresume_automatic == AUTORESUME_NEXTTRACK_ALWAYS | ||
1009 | || (global_settings.autoresume_automatic != AUTORESUME_NEXTTRACK_NEVER | ||
1010 | /* Not never resume? */ | ||
1011 | && autoresumable(thistrack_id3))); /* Pass Resume filter? */ | ||
1007 | #endif | 1012 | #endif |
1008 | 1013 | ||
1009 | if (!resume) | 1014 | if (!resume) |
diff --git a/apps/settings.h b/apps/settings.h index 131ff181dd..ae32a65bc6 100644 --- a/apps/settings.h +++ b/apps/settings.h | |||
@@ -125,6 +125,10 @@ enum { SHOW_PATH_OFF = 0, SHOW_PATH_CURRENT, SHOW_PATH_FULL }; | |||
125 | /* scrollbar visibility/position */ | 125 | /* scrollbar visibility/position */ |
126 | enum { SCROLLBAR_OFF = 0, SCROLLBAR_LEFT, SCROLLBAR_RIGHT }; | 126 | enum { SCROLLBAR_OFF = 0, SCROLLBAR_LEFT, SCROLLBAR_RIGHT }; |
127 | 127 | ||
128 | /* autoresume settings */ | ||
129 | enum { AUTORESUME_NEXTTRACK_NEVER = 0, AUTORESUME_NEXTTRACK_ALWAYS, | ||
130 | AUTORESUME_NEXTTRACK_CUSTOM}; | ||
131 | |||
128 | /* Alarm settings */ | 132 | /* Alarm settings */ |
129 | #ifdef HAVE_RTC_ALARM | 133 | #ifdef HAVE_RTC_ALARM |
130 | enum { ALARM_START_WPS = 0, | 134 | enum { ALARM_START_WPS = 0, |
@@ -577,6 +581,9 @@ struct user_settings | |||
577 | #endif | 581 | #endif |
578 | bool tagcache_autoupdate; /* automatically keep tagcache in sync? */ | 582 | bool tagcache_autoupdate; /* automatically keep tagcache in sync? */ |
579 | bool autoresume_enable; /* enable auto-resume feature? */ | 583 | bool autoresume_enable; /* enable auto-resume feature? */ |
584 | int autoresume_automatic; /* resume next track? 0=never, 1=always, | ||
585 | 2=custom */ | ||
586 | unsigned char autoresume_strpat[MAX_PATHNAME+1]; /* comma-separated list */ | ||
580 | bool runtimedb; /* runtime database active? */ | 587 | bool runtimedb; /* runtime database active? */ |
581 | #endif /* HAVE_TAGCACHE */ | 588 | #endif /* HAVE_TAGCACHE */ |
582 | 589 | ||
diff --git a/apps/settings_list.c b/apps/settings_list.c index 0521d4fb90..75e989eb10 100644 --- a/apps/settings_list.c +++ b/apps/settings_list.c | |||
@@ -1261,6 +1261,15 @@ const struct settings_list settings[] = { | |||
1261 | BOOL_SETTING(0, autoresume_enable, LANG_AUTORESUME, false, | 1261 | BOOL_SETTING(0, autoresume_enable, LANG_AUTORESUME, false, |
1262 | "autoresume enable", off_on, | 1262 | "autoresume enable", off_on, |
1263 | LANG_SET_BOOL_YES, LANG_SET_BOOL_NO, NULL), | 1263 | LANG_SET_BOOL_YES, LANG_SET_BOOL_NO, NULL), |
1264 | CHOICE_SETTING(0, autoresume_automatic, LANG_AUTORESUME_AUTOMATIC, | ||
1265 | AUTORESUME_NEXTTRACK_NEVER, | ||
1266 | "autoresume next track", "never,all,custom", | ||
1267 | NULL, 3, | ||
1268 | ID2P(LANG_SET_BOOL_NO), | ||
1269 | ID2P(LANG_ALWAYS), | ||
1270 | ID2P(LANG_AUTORESUME_CUSTOM)), | ||
1271 | TEXT_SETTING(0, autoresume_strpat, "autoresume next track patterns", | ||
1272 | "podcast", NULL, NULL), | ||
1264 | #endif | 1273 | #endif |
1265 | 1274 | ||
1266 | OFFON_SETTING(0, runtimedb, LANG_RUNTIMEDB_ACTIVE, false, | 1275 | OFFON_SETTING(0, runtimedb, LANG_RUNTIMEDB_ACTIVE, false, |