summaryrefslogtreecommitdiff
path: root/apps/tree.c
diff options
context:
space:
mode:
authorJörg Hohensohn <hohensoh@rockbox.org>2004-10-21 18:34:48 +0000
committerJörg Hohensohn <hohensoh@rockbox.org>2004-10-21 18:34:48 +0000
commit40ae63b4fcf57da3f70e342230ef81cb3b903d4f (patch)
tree40133e9083584c0c24ea3cb0a54aedfac22a096a /apps/tree.c
parenta24bf1caef474d52687558244e93710b39b86a1e (diff)
downloadrockbox-40ae63b4fcf57da3f70e342230ef81cb3b903d4f.zip
rockbox-40ae63b4fcf57da3f70e342230ef81cb3b903d4f.tar.gz
rockbox-40ae63b4fcf57da3f70e342230ef81cb3b903d4f.tar.bz2
rockbox-40ae63b4fcf57da3f70e342230ef81cb3b903d4f.tar.xz
Improvement for talking filenames: While loading the directory, already cache for which files are clips available. This avoids unsuccessful spinups while browsing.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5317 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/tree.c')
-rw-r--r--apps/tree.c165
1 files changed, 128 insertions, 37 deletions
diff --git a/apps/tree.c b/apps/tree.c
index 1025306..89864f5 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -269,29 +269,19 @@ static int play_dirname(int start_index)
return 1;
}
-static int play_filename(char *dir, char *file)
+static void play_filename(char *dir, char *file)
{
- int fd;
char name_mp3_filename[MAX_PATH+1];
if (mpeg_status() & MPEG_STATUS_PLAY)
- return 0;
+ return;
- if (strcasecmp(&file[strlen(file) - strlen(TALK_EXT)], TALK_EXT))
+ if (strcasecmp(&file[strlen(file) - strlen(file_thumbnail_ext)],
+ file_thumbnail_ext))
{ /* file has no .talk extension */
snprintf(name_mp3_filename, sizeof(name_mp3_filename),
- "%s/%s" TALK_EXT, dir, file);
+ "%s/%s%s", dir, file, file_thumbnail_ext);
- /* check if a corresponding .talk file exists */
- DEBUGF("Checking for Filename Thumb %s\n", name_mp3_filename);
- fd = open(name_mp3_filename, O_RDONLY);
- if (fd < 0)
- {
- DEBUGF("Failed to find: %s\n", name_mp3_filename);
- return -1;
- }
- DEBUGF("Found: %s\n", name_mp3_filename);
- close(fd);
talk_file(name_mp3_filename, false);
}
else
@@ -301,8 +291,6 @@ static int play_filename(char *dir, char *file)
talk_id(LANG_VOICE_DIR_HOVER, false); /* prefix it */
talk_file(name_mp3_filename, true);
}
-
- return 1;
}
static int compare(const void* p1, const void* p2)
@@ -388,6 +376,94 @@ static void showfileline(int line, int direntry, bool scroll, const int *dirfilt
*dotpos = '.';
}
+/* walk a directory and check all dircache entries if a .talk file exists */
+void check_file_thumbnails(const char *dirname, int num_files)
+{
+ int i;
+ struct dirent *entry;
+ DIR *dir;
+
+ dir = opendir(dirname);
+ if(!dir)
+ return;
+
+ for (i=0; i<num_files; i++) /* mark all files as non talking, except the .talk ones */
+ {
+ if (dircache[i].attr & ATTR_DIRECTORY)
+ continue; /* we're not touching directories */
+
+ if (strcasecmp(file_thumbnail_ext,
+ &dircache[i].name[strlen(dircache[i].name)
+ - strlen(file_thumbnail_ext)]))
+ { /* no .talk file */
+ dircache[i].attr &= ~TREE_ATTR_THUMBNAIL; /* clear */
+ }
+ else
+ { /* .talk file, we later let them speak themselves */
+ dircache[i].attr |= TREE_ATTR_THUMBNAIL; /* set */
+ }
+ }
+
+ while((entry = readdir(dir)) != 0) /* walk directory */
+ {
+ int ext_pos;
+
+ ext_pos = strlen(entry->d_name) - strlen(file_thumbnail_ext);
+ if (ext_pos <= 0 /* too short to carry ".talk" */
+ || (entry->attribute & ATTR_DIRECTORY) /* no file */
+ || strcasecmp(&entry->d_name[ext_pos], file_thumbnail_ext))
+ { /* or doesn't end with ".talk", no candidate */
+ continue;
+ }
+
+ /* terminate the (disposable) name in dir buffer,
+ this truncates off the ".talk" without needing an extra buffer */
+ entry->d_name[ext_pos] = '\0';
+
+ /* search corresponding file in dir cache */
+ for (i=0; i<num_files; i++)
+ {
+ if (!strcasecmp(dircache[i].name, entry->d_name))
+ { /* match */
+ dircache[i].attr |= TREE_ATTR_THUMBNAIL; /* set the flag */
+ break; /* exit search loop, because we found it */
+ }
+ }
+ }
+ closedir(dir);
+}
+
+/* check all dircache directories if they contain a "_dirname.talk" file */
+#if 0 /* not practical, this is too slow */
+void check_dir_thumbnails(const char *dirname, int num_files)
+{
+ int i;
+ int fd;
+ char clipfile[MAX_PATH];
+
+ for (i=0; i<num_files; i++)
+ {
+ if (!(dircache[i].attr & ATTR_DIRECTORY))
+ continue; /* only directories are interesting */
+
+ /* compose pathname of directory name clip file */
+ snprintf(clipfile, sizeof(clipfile), "%s%s/%s",
+ dirname, dircache[i].name, dir_thumbnail_name);
+
+ fd = open(clipfile, O_RDONLY); /* check if exists */
+ if (fd >= 0)
+ { /* there is one */
+ dircache[i].attr |= TREE_ATTR_THUMBNAIL; /* set the flag */
+ close(fd);
+ }
+ else
+ { /* none found, clear the flag */
+ dircache[i].attr &= ~TREE_ATTR_THUMBNAIL;
+ }
+ }
+}
+#endif /* #if 0 */
+
/* load sorted directory into dircache. returns NULL on failure. */
struct entry* load_and_sort_directory(const char *dirname, const int *dirfilter,
int *num_files, bool *buffer_full)
@@ -490,6 +566,14 @@ struct entry* load_and_sort_directory(const char *dirname, const int *dirfilter,
lastdir[sizeof(lastdir)-1] = 0;
qsort(dircache,i,sizeof(struct entry),compare);
+ /* If thumbnail talking is enabled, make an extra run to mark files with
+ associated thumbnails, so we don't do unsuccessful spinups later. */
+ if (global_settings.talk_file == 3)
+ check_file_thumbnails(dirname, i); /* map .talk to ours */
+#if 0 /* not practical, this is too slow */
+ if (global_settings.talk_dir == 3)
+ check_dir_thumbnails(dirname, i); /* try in the directories */
+#endif /* #if 0 */
return dircache;
}
@@ -1373,15 +1457,12 @@ static bool dirbrowse(const char *root, const int *dirfilter)
}
}
else
- {
+ {
DEBUGF("Playing file thumbnail: %s/%s%s\n",
- currdir, dircache[lasti].name, TALK_EXT);
- res = play_filename(currdir, dircache[lasti].name);
- if (res < 0) /* failed, not existing */
- { /* say the number instead, as a fallback */
- play_filenumber(lasti-dirsindir+1,
- dircache[lasti].attr);
- }
+ currdir, dircache[lasti].name, file_thumbnail_ext);
+ /* no fallback necessary, we knew in advance
+ that the file exists */
+ play_filename(currdir, dircache[lasti].name);
}
thumbnail_time = -1; /* job done */
}
@@ -1501,20 +1582,30 @@ static bool dirbrowse(const char *root, const int *dirfilter)
talk_spell(dircache[i].name, false);
}
}
- else if (global_settings.talk_file == 1) /* files as numbers */
- {
- play_filenumber(i-dirsindir+1,
- dircache[i].attr & TREE_ATTR_MASK);
- }
- else if (global_settings.talk_file == 2) /* files spelled */
+ else /* file */
{
- talk_spell(dircache[i].name, false);
- }
- else if (global_settings.talk_file == 3) /* hover */
- { /* "schedule" a thumbnail, to have a little dalay */
- thumbnail_time = current_tick + HOVER_DELAY;
+ int voicemethod = global_settings.talk_file;
+ if (voicemethod == 3) /* thumbnail clip */
+ { /* "schedule" a thumbnail, to have a little delay */
+ if (dircache[i].attr & TREE_ATTR_THUMBNAIL)
+ {
+ thumbnail_time = current_tick + HOVER_DELAY;
+ }
+ else
+ { /* say the number as fallback */
+ voicemethod = 1;
+ }
+ }
+ if (voicemethod == 1) /* files as numbers */
+ {
+ play_filenumber(i-dirsindir+1,
+ dircache[i].attr & TREE_ATTR_MASK);
+ }
+ else if (voicemethod == 2) /* files spelled */
+ {
+ talk_spell(dircache[i].name, false);
+ }
}
-
}
}