mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 02:27:39 -04:00
[Bug_Fix] shortcut to directory in .link files caused crash
since the plugin browser is now closed when running plugins rb->set_current_file() had no valid browser context and used 'random' memory instead also adds a way to discard levels so we can load the desired directory instead of returning to the previous https://forums.rockbox.org/index.php/topic,54694.0.html Change-Id: I624246e56d42972bf6a1ce566a209b745de6f30b
This commit is contained in:
parent
6e90bfe029
commit
72c539d35e
5 changed files with 83 additions and 13 deletions
|
@ -287,12 +287,18 @@ static int compare(const void* p1, const void* p2)
|
||||||
/* load and sort directory into the tree's cache. returns NULL on failure. */
|
/* load and sort directory into the tree's cache. returns NULL on failure. */
|
||||||
int ft_load(struct tree_context* c, const char* tempdir)
|
int ft_load(struct tree_context* c, const char* tempdir)
|
||||||
{
|
{
|
||||||
|
if (c->out_of_tree > 0) /* something else is loaded */
|
||||||
|
return 0;
|
||||||
|
|
||||||
int files_in_dir = 0;
|
int files_in_dir = 0;
|
||||||
int name_buffer_used = 0;
|
int name_buffer_used = 0;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
bool (*callback_show_item)(char *, int, struct tree_context *) = NULL;
|
bool (*callback_show_item)(char *, int, struct tree_context *) = NULL;
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
|
|
||||||
|
if (!c->is_browsing)
|
||||||
|
c->browse = NULL;
|
||||||
|
|
||||||
if (tempdir)
|
if (tempdir)
|
||||||
dir = opendir(tempdir);
|
dir = opendir(tempdir);
|
||||||
else
|
else
|
||||||
|
@ -760,6 +766,7 @@ int ft_enter(struct tree_context* c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -802,5 +809,7 @@ int ft_exit(struct tree_context* c)
|
||||||
if (exit_func)
|
if (exit_func)
|
||||||
rc = 3;
|
rc = 3;
|
||||||
|
|
||||||
|
c->out_of_tree = 0;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -353,7 +353,7 @@ static bool callback_show_item(char *name, int attr, struct tree_context *tc)
|
||||||
{
|
{
|
||||||
if (strstr(tc->currdir, PLUGIN_DIR) != NULL)
|
if (strstr(tc->currdir, PLUGIN_DIR) != NULL)
|
||||||
return true;
|
return true;
|
||||||
tc->browse = NULL; /* exit immediately */
|
tc->is_browsing = false; /* exit immediately */
|
||||||
}
|
}
|
||||||
else if(attr & FILE_ATTR_ROCK)
|
else if(attr & FILE_ATTR_ROCK)
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,7 +32,7 @@ enum sc_list_action_type
|
||||||
SCLA_USB,
|
SCLA_USB,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static size_t root_len;
|
||||||
static char *link_filename;
|
static char *link_filename;
|
||||||
static bool user_file;
|
static bool user_file;
|
||||||
|
|
||||||
|
@ -175,6 +175,42 @@ bool goto_entry(char *file_or_dir)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static bool callback_show_item(char *name, int attr, struct tree_context *tc)
|
||||||
|
{
|
||||||
|
(void)name;
|
||||||
|
if(attr & ATTR_DIRECTORY)
|
||||||
|
{
|
||||||
|
if ((tc->browse->flags & BROWSE_SELECTED) == 0 &&
|
||||||
|
rb->strlen(tc->currdir) < root_len)
|
||||||
|
{
|
||||||
|
tc->is_browsing = false; /* exit immediately */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool open_browse(char *path, char *buf, size_t bufsz)
|
||||||
|
{
|
||||||
|
struct browse_context browse = {
|
||||||
|
.dirfilter = rb->global_settings->dirfilter,
|
||||||
|
.flags = BROWSE_DIRFILTER| BROWSE_SELECTONLY | BROWSE_NO_CONTEXT_MENU,
|
||||||
|
.title = path,
|
||||||
|
.icon = Icon_Plugin,
|
||||||
|
.root = path,
|
||||||
|
.buf = buf,
|
||||||
|
.bufsize = bufsz,
|
||||||
|
.callback_show_item = callback_show_item,
|
||||||
|
};
|
||||||
|
root_len = 0;
|
||||||
|
char *name = rb->strrchr(path, '/');
|
||||||
|
if (name)
|
||||||
|
root_len = name - path;
|
||||||
|
rb->rockbox_browse(&browse);
|
||||||
|
|
||||||
|
return (browse.flags & BROWSE_SELECTED);
|
||||||
|
}
|
||||||
|
|
||||||
int goto_entry(char *file_or_dir)
|
int goto_entry(char *file_or_dir)
|
||||||
{
|
{
|
||||||
DEBUGF("Trying to go to '%s'...\n", file_or_dir);
|
DEBUGF("Trying to go to '%s'...\n", file_or_dir);
|
||||||
|
@ -202,14 +238,18 @@ int goto_entry(char *file_or_dir)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Set the browsers dirfilter to the global setting
|
if (!is_dir)
|
||||||
* This is required in case the plugin was launched
|
{
|
||||||
* from the plugins browser, in which case the
|
|
||||||
* dirfilter is set to only display .rock files */
|
|
||||||
rb->set_dirfilter(rb->global_settings->dirfilter);
|
|
||||||
|
|
||||||
/* Change directory to the entry selected by the user */
|
|
||||||
rb->set_current_file(file_or_dir);
|
rb->set_current_file(file_or_dir);
|
||||||
|
return LOOP_EXIT;
|
||||||
|
}
|
||||||
|
char tmp_buf[MAX_PATH];
|
||||||
|
if (open_browse(file_or_dir, tmp_buf, sizeof(tmp_buf)))
|
||||||
|
{
|
||||||
|
DEBUGF("Trying to load '%s'...\n", tmp_buf);
|
||||||
|
rb->set_current_file(tmp_buf);
|
||||||
|
return LOOP_EXIT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return PLUGIN_OK;
|
return PLUGIN_OK;
|
||||||
}
|
}
|
||||||
|
|
22
apps/tree.c
22
apps/tree.c
|
@ -608,6 +608,13 @@ void set_current_file(const char *path)
|
||||||
{
|
{
|
||||||
tc.selected_item = tree_get_file_position(lastfile);
|
tc.selected_item = tree_get_file_position(lastfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!tc.is_browsing && tc.out_of_tree == 0)
|
||||||
|
{
|
||||||
|
/* the browser is closed */
|
||||||
|
/* don't allow the previous items to overwrite what we just loaded */
|
||||||
|
tc.out_of_tree = tc.selected_item + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -652,7 +659,7 @@ static int dirbrowse(void)
|
||||||
return GO_TO_PREVIOUS; /* No files found for rockbox_browse() */
|
return GO_TO_PREVIOUS; /* No files found for rockbox_browse() */
|
||||||
}
|
}
|
||||||
|
|
||||||
while(tc.browse) {
|
while(tc.browse && tc.is_browsing) {
|
||||||
bool restore = false;
|
bool restore = false;
|
||||||
if (tc.dirlevel < 0)
|
if (tc.dirlevel < 0)
|
||||||
tc.dirlevel = 0; /* shouldnt be needed.. this code needs work! */
|
tc.dirlevel = 0; /* shouldnt be needed.. this code needs work! */
|
||||||
|
@ -973,10 +980,18 @@ static struct tree_context backups[NUM_TC_BACKUP];
|
||||||
static int backup_count = -1;
|
static int backup_count = -1;
|
||||||
int rockbox_browse(struct browse_context *browse)
|
int rockbox_browse(struct browse_context *browse)
|
||||||
{
|
{
|
||||||
|
tc.is_browsing = (browse != NULL);
|
||||||
static char current[MAX_PATH];
|
static char current[MAX_PATH];
|
||||||
int ret_val = 0;
|
int ret_val = 0;
|
||||||
int dirfilter = browse->dirfilter;
|
int dirfilter = browse->dirfilter;
|
||||||
|
|
||||||
|
if (tc.out_of_tree > 0)
|
||||||
|
{
|
||||||
|
tc.selected_item = tc.out_of_tree - 1;
|
||||||
|
tc.out_of_tree = 0;
|
||||||
|
return ft_enter(&tc);
|
||||||
|
}
|
||||||
|
|
||||||
if (backup_count >= NUM_TC_BACKUP)
|
if (backup_count >= NUM_TC_BACKUP)
|
||||||
return GO_TO_PREVIOUS;
|
return GO_TO_PREVIOUS;
|
||||||
if (backup_count >= 0)
|
if (backup_count >= 0)
|
||||||
|
@ -1031,6 +1046,9 @@ int rockbox_browse(struct browse_context *browse)
|
||||||
backup_count--;
|
backup_count--;
|
||||||
if (backup_count >= 0)
|
if (backup_count >= 0)
|
||||||
tc = backups[backup_count];
|
tc = backups[backup_count];
|
||||||
|
|
||||||
|
tc.is_browsing = false;
|
||||||
|
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1198,7 +1216,7 @@ static int ft_play_filename(char *dir, char *file, int attr)
|
||||||
/* These two functions are called by the USB and shutdown handlers */
|
/* These two functions are called by the USB and shutdown handlers */
|
||||||
void tree_flush(void)
|
void tree_flush(void)
|
||||||
{
|
{
|
||||||
tc.browse = NULL; /* clear browse to prevent reentry to a possibly missing file */
|
tc.is_browsing = false;/* clear browse to prevent reentry to a possibly missing file */
|
||||||
#ifdef HAVE_TAGCACHE
|
#ifdef HAVE_TAGCACHE
|
||||||
tagcache_shutdown();
|
tagcache_shutdown();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -90,9 +90,12 @@ struct tree_context {
|
||||||
int currtable; /* db use */
|
int currtable; /* db use */
|
||||||
int currextra; /* db use */
|
int currextra; /* db use */
|
||||||
#endif
|
#endif
|
||||||
|
int sort_dir; /* directory sort order */
|
||||||
|
int out_of_tree; /* shortcut from elsewhere */
|
||||||
struct tree_cache cache;
|
struct tree_cache cache;
|
||||||
bool dirfull;
|
bool dirfull;
|
||||||
int sort_dir; /* directory sort order */
|
bool is_browsing; /* valid browse context? */
|
||||||
|
|
||||||
struct browse_context *browse;
|
struct browse_context *browse;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue