mirror of
https://github.com/libretro/RetroArch
synced 2024-12-29 12:31:05 +00:00
ff63852a7c
When browsing compressed archives 'Parent Directory' will not work and will endlessly recurse into non-existent empty directories where the user will have to press the back button to get out of every instance. This will now hide 'Parent Directory' in compressed archives to avoid this issue. The user will still be able to press the back button to exit. Fixes https://github.com/libretro/RetroArch/issues/2604
315 lines
10 KiB
C
315 lines
10 KiB
C
/* RetroArch - A frontend for libretro.
|
|
* Copyright (C) 2011-2017 - Daniel De Matteis
|
|
*
|
|
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
|
* of the GNU General Public License as published by the Free Software Found-
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
|
*
|
|
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with RetroArch.
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <compat/strl.h>
|
|
#include <lists/string_list.h>
|
|
#include <string/stdstring.h>
|
|
#include <file/file_path.h>
|
|
#include <file/archive_file.h>
|
|
|
|
#include <lists/dir_list.h>
|
|
|
|
#include <boolean.h>
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "../../config.h"
|
|
#endif
|
|
|
|
#include "menu_filebrowser.h"
|
|
|
|
#include "../menu_driver.h"
|
|
#include "../menu_displaylist.h"
|
|
|
|
#include "../../configuration.h"
|
|
#include "../../paths.h"
|
|
|
|
#include "../../retroarch.h"
|
|
#include "../../core.h"
|
|
#include "../../content.h"
|
|
#include "../../verbosity.h"
|
|
#include "../../dynamic.h"
|
|
|
|
static enum filebrowser_enums filebrowser_types = FILEBROWSER_NONE;
|
|
|
|
enum filebrowser_enums filebrowser_get_type(void)
|
|
{
|
|
return filebrowser_types;
|
|
}
|
|
|
|
void filebrowser_clear_type(void)
|
|
{
|
|
filebrowser_types = FILEBROWSER_NONE;
|
|
}
|
|
|
|
void filebrowser_set_type(enum filebrowser_enums type)
|
|
{
|
|
filebrowser_types = type;
|
|
}
|
|
|
|
void filebrowser_parse(menu_displaylist_info_t *info, unsigned type_data)
|
|
{
|
|
size_t i, list_size;
|
|
struct string_list *str_list = NULL;
|
|
unsigned items_found = 0;
|
|
unsigned files_count = 0;
|
|
unsigned dirs_count = 0;
|
|
settings_t *settings = config_get_ptr();
|
|
enum menu_displaylist_ctl_state type = (enum menu_displaylist_ctl_state)
|
|
type_data;
|
|
const char *path = info ? info->path : NULL;
|
|
bool path_is_compressed = !string_is_empty(path)
|
|
? path_is_compressed_file(path) : false;
|
|
bool filter_ext =
|
|
settings->bools.menu_navigation_browser_filter_supported_extensions_enable;
|
|
|
|
rarch_system_info_t *system = runloop_get_system_info();
|
|
const struct retro_subsystem_info *subsystem;
|
|
|
|
/* Core fully loaded, use the subsystem data */
|
|
if (system->subsystem.data)
|
|
subsystem = system->subsystem.data + content_get_subsystem();
|
|
/* Core not loaded completely, use the data we peeked on load core */
|
|
else
|
|
subsystem = subsystem_data + content_get_subsystem();
|
|
|
|
if (info && string_is_equal(info->label,
|
|
msg_hash_to_str(MENU_ENUM_LABEL_SCAN_FILE)))
|
|
filter_ext = false;
|
|
|
|
if (info && path_is_compressed)
|
|
{
|
|
if (filebrowser_types != FILEBROWSER_SELECT_FILE_SUBSYSTEM)
|
|
str_list = file_archive_get_file_list(path, info->exts);
|
|
else if (subsystem && subsystem_current_count > 0)
|
|
str_list = file_archive_get_file_list(path, subsystem->roms[content_get_subsystem_rom_id()].valid_extensions);
|
|
}
|
|
else if (!string_is_empty(path))
|
|
{
|
|
if (filebrowser_types == FILEBROWSER_SELECT_FILE_SUBSYSTEM)
|
|
{
|
|
if (subsystem && subsystem_current_count > 0 && content_get_subsystem_rom_id() < subsystem->num_roms)
|
|
str_list = dir_list_new(path,
|
|
(filter_ext && info) ? subsystem->roms[content_get_subsystem_rom_id()].valid_extensions : NULL,
|
|
true, settings->bools.show_hidden_files, true, false);
|
|
}
|
|
else
|
|
str_list = dir_list_new(path,
|
|
(filter_ext && info) ? info->exts : NULL,
|
|
true, settings->bools.show_hidden_files, true, false);
|
|
}
|
|
|
|
|
|
switch (filebrowser_types)
|
|
{
|
|
case FILEBROWSER_SCAN_DIR:
|
|
#ifdef HAVE_LIBRETRODB
|
|
if (info)
|
|
menu_entries_prepend(info->list,
|
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_THIS_DIRECTORY),
|
|
msg_hash_to_str(MENU_ENUM_LABEL_SCAN_THIS_DIRECTORY),
|
|
MENU_ENUM_LABEL_SCAN_THIS_DIRECTORY,
|
|
FILE_TYPE_SCAN_DIRECTORY, 0 ,0);
|
|
#endif
|
|
break;
|
|
case FILEBROWSER_SELECT_DIR:
|
|
if (info)
|
|
menu_entries_prepend(info->list,
|
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_USE_THIS_DIRECTORY),
|
|
msg_hash_to_str(MENU_ENUM_LABEL_USE_THIS_DIRECTORY),
|
|
MENU_ENUM_LABEL_USE_THIS_DIRECTORY,
|
|
FILE_TYPE_USE_DIRECTORY, 0 ,0);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (!str_list)
|
|
{
|
|
const char *str = path_is_compressed
|
|
? msg_hash_to_str(MENU_ENUM_LABEL_VALUE_UNABLE_TO_READ_COMPRESSED_FILE)
|
|
: msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DIRECTORY_NOT_FOUND);
|
|
|
|
if (info)
|
|
menu_entries_append_enum(info->list, str, "",
|
|
MENU_ENUM_LABEL_VALUE_DIRECTORY_NOT_FOUND, 0, 0, 0);
|
|
goto end;
|
|
}
|
|
|
|
dir_list_sort(str_list, true);
|
|
|
|
list_size = str_list->size;
|
|
|
|
if (list_size == 0)
|
|
{
|
|
string_list_free(str_list);
|
|
str_list = NULL;
|
|
}
|
|
else
|
|
{
|
|
for (i = 0; i < list_size; i++)
|
|
{
|
|
char label[64];
|
|
bool is_dir = false;
|
|
enum msg_hash_enums enum_idx = MSG_UNKNOWN;
|
|
enum msg_file_type file_type = FILE_TYPE_NONE;
|
|
const char *path = str_list->elems[i].data;
|
|
|
|
label[0] = '\0';
|
|
|
|
switch (str_list->elems[i].attr.i)
|
|
{
|
|
case RARCH_DIRECTORY:
|
|
file_type = FILE_TYPE_DIRECTORY;
|
|
break;
|
|
case RARCH_COMPRESSED_ARCHIVE:
|
|
file_type = FILE_TYPE_CARCHIVE;
|
|
break;
|
|
case RARCH_COMPRESSED_FILE_IN_ARCHIVE:
|
|
file_type = FILE_TYPE_IN_CARCHIVE;
|
|
break;
|
|
case RARCH_PLAIN_FILE:
|
|
default:
|
|
if (filebrowser_types == FILEBROWSER_SELECT_FONT)
|
|
file_type = FILE_TYPE_FONT;
|
|
else
|
|
file_type = (enum msg_file_type)info->type_default;
|
|
switch (type)
|
|
{
|
|
/* in case of deferred_core_list we have to interpret
|
|
* every archive as an archive to disallow instant loading
|
|
*/
|
|
case DISPLAYLIST_CORES_DETECTED:
|
|
if (path_is_compressed_file(path))
|
|
file_type = FILE_TYPE_CARCHIVE;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
is_dir = (file_type == FILE_TYPE_DIRECTORY);
|
|
|
|
if (!is_dir)
|
|
{
|
|
if (filebrowser_types == FILEBROWSER_SELECT_DIR)
|
|
continue;
|
|
if (filebrowser_types == FILEBROWSER_SCAN_DIR)
|
|
continue;
|
|
}
|
|
|
|
/* Need to preserve slash first time. */
|
|
|
|
if (!string_is_empty(path) && !path_is_compressed)
|
|
path = path_basename(path);
|
|
|
|
if (filebrowser_types == FILEBROWSER_SELECT_COLLECTION)
|
|
{
|
|
if (is_dir)
|
|
file_type = FILE_TYPE_DIRECTORY;
|
|
else
|
|
file_type = FILE_TYPE_PLAYLIST_COLLECTION;
|
|
}
|
|
|
|
if (!is_dir && path_is_media_type(path) == RARCH_CONTENT_MUSIC)
|
|
file_type = FILE_TYPE_MUSIC;
|
|
else if (!is_dir &&
|
|
(settings->bools.multimedia_builtin_mediaplayer_enable ||
|
|
settings->bools.multimedia_builtin_imageviewer_enable))
|
|
{
|
|
switch (path_is_media_type(path))
|
|
{
|
|
case RARCH_CONTENT_MOVIE:
|
|
#if defined(HAVE_FFMPEG) || defined(HAVE_MPV)
|
|
if (settings->bools.multimedia_builtin_mediaplayer_enable)
|
|
file_type = FILE_TYPE_MOVIE;
|
|
#endif
|
|
break;
|
|
case RARCH_CONTENT_IMAGE:
|
|
#ifdef HAVE_IMAGEVIEWER
|
|
if (settings->bools.multimedia_builtin_imageviewer_enable
|
|
&& type != DISPLAYLIST_IMAGES)
|
|
file_type = FILE_TYPE_IMAGEVIEWER;
|
|
else
|
|
file_type = FILE_TYPE_IMAGE;
|
|
#endif
|
|
if (filebrowser_types == FILEBROWSER_SELECT_IMAGE)
|
|
file_type = FILE_TYPE_IMAGE;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch (file_type)
|
|
{
|
|
case FILE_TYPE_PLAIN:
|
|
#if 0
|
|
enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_PLAIN_FILE;
|
|
#endif
|
|
files_count++;
|
|
break;
|
|
case FILE_TYPE_MOVIE:
|
|
enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_MOVIE_OPEN;
|
|
files_count++;
|
|
break;
|
|
case FILE_TYPE_MUSIC:
|
|
enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_MUSIC_OPEN;
|
|
files_count++;
|
|
break;
|
|
case FILE_TYPE_IMAGE:
|
|
enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_IMAGE;
|
|
files_count++;
|
|
break;
|
|
case FILE_TYPE_IMAGEVIEWER:
|
|
enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_IMAGE_OPEN_WITH_VIEWER;
|
|
files_count++;
|
|
break;
|
|
case FILE_TYPE_DIRECTORY:
|
|
enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY;
|
|
dirs_count++;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
items_found++;
|
|
menu_entries_append_enum(info->list, path, label,
|
|
enum_idx,
|
|
file_type, 0, 0);
|
|
}
|
|
}
|
|
|
|
if (str_list && str_list->size > 0)
|
|
string_list_free(str_list);
|
|
|
|
if (items_found == 0)
|
|
{
|
|
menu_entries_append_enum(info->list,
|
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ITEMS),
|
|
msg_hash_to_str(MENU_ENUM_LABEL_NO_ITEMS),
|
|
MENU_ENUM_LABEL_NO_ITEMS,
|
|
MENU_SETTING_NO_ITEM, 0, 0);
|
|
}
|
|
|
|
end:
|
|
if (info && !path_is_compressed)
|
|
menu_entries_prepend(info->list,
|
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PARENT_DIRECTORY),
|
|
path,
|
|
MENU_ENUM_LABEL_PARENT_DIRECTORY,
|
|
FILE_TYPE_PARENT_DIRECTORY, 0, 0);
|
|
}
|