diff --git a/apps/bookmark.c b/apps/bookmark.c index f76edd256e..6ff7e4e52c 100644 --- a/apps/bookmark.c +++ b/apps/bookmark.c @@ -50,6 +50,14 @@ #define MAX_BOOKMARKS 10 #define MAX_BOOKMARK_SIZE 350 #define RECENT_BOOKMARK_FILE ROCKBOX_DIR "/most-recent.bmark" +#define BOOKMARK_IGNORE "/bookmark.ignore" +#define BOOKMARK_UNIGNORE "/bookmark.unignore" + +/* flags for write_bookmark() */ +#define BMARK_WRITE 0x0 +#define BMARK_ASK_USER 0x1 +#define BMARK_CREATE_FILE 0x2 +#define BMARK_CHECK_IGNORE 0x4 /* Used to buffer bookmarks while displaying the bookmark list. */ struct bookmark_list @@ -539,6 +547,41 @@ static void get_track_resume_info(struct resume_info *resume_info) #endif } +/* ----------------------------------------------------------------------- */ +/* This function checks for bookmark ignore and unignore files to allow */ +/* directories to be ignored or included in bookmarks */ +/* ----------------------------------------------------------------------- */ +static bool bookmark_has_ignore(struct resume_info *resume_info) +{ + if (!resume_info->id3) + return false; + + char *buf = global_temp_buffer; + size_t bufsz = sizeof(global_temp_buffer); + + strmemccpy(buf, resume_info->id3->path, bufsz); + + char *slash; + while ((slash = strrchr(buf, '/'))) + { + size_t rem = bufsz - (slash - buf); + if (strmemccpy(slash, BOOKMARK_UNIGNORE, rem) != NULL && file_exists(buf)) + { + /* unignore exists we want bookmarks */ + logf("unignore bookmark found %s\n", buf); + return false; + } + if (strmemccpy(slash, BOOKMARK_IGNORE, rem) != NULL && file_exists(buf)) + { + /* ignore exists we do not want bookmarks */ + logf("ignore bookmark found %s\n", buf); + return true; + } + *slash = '\0'; + } + return false; +} + /* ----------------------------------------------------------------------- */ /* This function takes the current current resume information and writes */ /* that to the beginning of the bookmark file. */ @@ -550,12 +593,17 @@ static void get_track_resume_info(struct resume_info *resume_info) /* possible that a bookmark is successfully added to the most recent */ /* bookmark list but fails to be added to the bookmark file or vice versa. */ /* ------------------------------------------------------------------------*/ -static bool write_bookmark(bool create_bookmark_file) +static bool write_bookmark(unsigned int flags) { - logf("%s", __func__); + logf("%s flags: %d", __func__, flags); char bm_filename[MAX_PATH]; bool ret=true; + bool create_bookmark_file = flags & BMARK_CREATE_FILE; + bool check_ignore = flags & BMARK_CHECK_IGNORE; + bool ask_user = flags & BMARK_ASK_USER; + bool usemrb = global_settings.usemrb; + char *name = NULL; size_t namelen = 0; char* bm; @@ -564,8 +612,27 @@ static bool write_bookmark(bool create_bookmark_file) if (bookmark_is_bookmarkable_state()) { get_track_resume_info(&resume_info); + + if (check_ignore + && (create_bookmark_file || ask_user || usemrb)) + { + if (bookmark_has_ignore(&resume_info)) + return false; + } + + if (ask_user) + { + if (yesno_pop(ID2P(LANG_AUTO_BOOKMARK_QUERY))) + { + if (global_settings.autocreatebookmark != BOOKMARK_RECENT_ONLY_ASK) + create_bookmark_file = true; + } + else + return false; + } + /* writing the most recent bookmark */ - if (global_settings.usemrb) + if (usemrb) { /* since we use the same buffer bookmark needs created each time */ bm = create_bookmark(&name, &namelen, &resume_info); @@ -1103,7 +1170,7 @@ bool bookmark_create_menu(void) if (!bookmark_is_bookmarkable_state()) save_playlist_screen(NULL); - return write_bookmark(true); + return write_bookmark(BMARK_CREATE_FILE); } /* ----------------------------------------------------------------------- */ /* This function acts as the load interface from the context menu. */ @@ -1175,29 +1242,23 @@ bool bookmark_autobookmark(bool prompt_ok) update = (global_settings.autoupdatebookmark && bookmark_exists()); if (update) - return write_bookmark(true); + return write_bookmark(BMARK_CREATE_FILE | BMARK_CHECK_IGNORE); switch (global_settings.autocreatebookmark) { case BOOKMARK_YES: - return write_bookmark(true); + return write_bookmark(BMARK_CREATE_FILE | BMARK_CHECK_IGNORE); case BOOKMARK_NO: return false; case BOOKMARK_RECENT_ONLY_YES: - return write_bookmark(false); + return write_bookmark(BMARK_CHECK_IGNORE); } - const char *lines[]={ID2P(LANG_AUTO_BOOKMARK_QUERY)}; - const struct text_message message={lines, 1}; - if(prompt_ok && gui_syncyesno_run(&message, NULL, NULL)==YESNO_YES) - { - if (global_settings.autocreatebookmark == BOOKMARK_RECENT_ONLY_ASK) - return write_bookmark(false); - else - return write_bookmark(true); - } + if(prompt_ok) + return write_bookmark(BMARK_ASK_USER | BMARK_CHECK_IGNORE); + return false; } diff --git a/manual/configure_rockbox/bookmarking.tex b/manual/configure_rockbox/bookmarking.tex index a0a047e190..398257e552 100644 --- a/manual/configure_rockbox/bookmarking.tex +++ b/manual/configure_rockbox/bookmarking.tex @@ -14,6 +14,20 @@ the bookmark to load. There are other ways to load a bookmarks mentioned below. + You can also configure what directories will save bookmarks by creating a file + named 'bookmark.ignore' in a directory if you would like to never create a bookmark + when files are played from it. + + \note{You can still manually create a bookmark but ignored directories will + not update existing bookmarks nor auto create them for files located + in ignored directories. } + + The file 'bookmark.unignore' provides the opposite functionality. + For instance in the root of the drive you could create '/bookmark.ignore' + and no files played from this drive would get bookmarks. + If you then created '/podcasts/bookmark.unignore' tracks played from the podcast + directory would get bookmarks. + \note{If the current playlist has been modified or is unsaved, such as when playing tracks from the \setting{Database}, Rockbox will automatically offer to save the playlist to a file when you attempt to create a bookmark. diff --git a/tools/buildzip.pl b/tools/buildzip.pl index 12ca9de1d9..5a4f0d0d80 100755 --- a/tools/buildzip.pl +++ b/tools/buildzip.pl @@ -395,6 +395,9 @@ sub buildzip { # create the file so the talkclip generation skips this folder open(IGNORE, ">$temp_dir/talkclips.ignore") || die "can't open talkclips.ignore"; close(IGNORE); + # create the file so bookmark generation skips this folder + open(IGNORE, ">$temp_dir/bookmark.ignore") || die "can't open bookmark.ignore"; + close(IGNORE); # the samsung ypr0 has a loader script that's needed in the zip if ($modelname =~ /samsungypr[01]/) {