mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-07 08:36:02 -10:00
Merge of manual and autoscan
Scanning options are unified for a single operation, which can be customized to cover previous autoscan, manual scan, DAT scan, and a lot of combinations in-between. More details in the pull request.
This commit is contained in:
1 parent
fe27d9d7b0
commit
2fdf736d51
15 files changed
+1356
-733
No files matched your search
+1
-1
@@ -432,6 +432,7 @@ OBJ += \
|
||||
$(LIBRETRO_COMM_DIR)/playlists/label_sanitization.o \
|
||||
$(LIBRETRO_COMM_DIR)/time/rtime.o \
|
||||
manual_content_scan.o \
|
||||
tasks/task_database.o \
|
||||
disk_control_interface.o
|
||||
|
||||
ifeq ($(HAVE_CONFIGFILE), 1)
|
||||
@@ -581,7 +582,6 @@ ifeq ($(HAVE_LIBRETRODB), 1)
|
||||
libretro-db/rmsgpack.o \
|
||||
libretro-db/rmsgpack_dom.o \
|
||||
database_info.o \
|
||||
tasks/task_database.o \
|
||||
tasks/task_database_cue.o
|
||||
|
||||
ifeq ($(HAVE_MENU), 1)
|
||||
|
||||
+15
-12
@@ -23,11 +23,13 @@
|
||||
#include <file/file_path.h>
|
||||
#include <lists/string_list.h>
|
||||
#include <lists/dir_list.h>
|
||||
#include <string/stdstring.h>
|
||||
|
||||
#include "libretro-db/libretrodb.h"
|
||||
|
||||
#include "core_info.h"
|
||||
#include "database_info.h"
|
||||
#include "manual_content_scan.h"
|
||||
|
||||
int database_info_build_query_enum(char *s, size_t len,
|
||||
enum database_query_type type,
|
||||
@@ -860,8 +862,9 @@ static int dir_entry_compare(const void *left, const void *right)
|
||||
}
|
||||
|
||||
database_info_handle_t *database_info_dir_init(const char *dir,
|
||||
enum database_type type, retro_task_t *task,
|
||||
bool show_hidden_files)
|
||||
enum database_type type, char *file_exts,
|
||||
bool show_hidden_files, bool recursive, bool include_archive,
|
||||
struct string_list **content_list)
|
||||
{
|
||||
core_info_list_t *core_info_list = NULL;
|
||||
struct string_list *list = NULL;
|
||||
@@ -871,11 +874,13 @@ database_info_handle_t *database_info_dir_init(const char *dir,
|
||||
if (!db)
|
||||
return NULL;
|
||||
|
||||
core_info_get_list(&core_info_list);
|
||||
/* File list will include all supported files, unless extension list is given */
|
||||
if (string_is_empty(file_exts))
|
||||
core_info_get_list(&core_info_list);
|
||||
|
||||
if (!(list = dir_list_new(dir, core_info_list ? core_info_list->all_ext : NULL,
|
||||
if (!(list = dir_list_new(dir, core_info_list ? core_info_list->all_ext : file_exts,
|
||||
false, show_hidden_files,
|
||||
false, true)))
|
||||
include_archive, recursive)))
|
||||
{
|
||||
free(db);
|
||||
return NULL;
|
||||
@@ -886,14 +891,13 @@ database_info_handle_t *database_info_dir_init(const char *dir,
|
||||
|
||||
db->status = DATABASE_STATUS_ITERATE;
|
||||
db->type = type;
|
||||
db->list_ptr = 0;
|
||||
db->list = list;
|
||||
*content_list = list;
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
database_info_handle_t *database_info_file_init(const char *path,
|
||||
enum database_type type, retro_task_t *task)
|
||||
enum database_type type, retro_task_t *task, struct string_list **content_list)
|
||||
{
|
||||
union string_list_elem_attr attr;
|
||||
struct string_list *list = NULL;
|
||||
@@ -914,16 +918,15 @@ database_info_handle_t *database_info_file_init(const char *path,
|
||||
|
||||
db->status = DATABASE_STATUS_ITERATE;
|
||||
db->type = type;
|
||||
db->list_ptr = 0;
|
||||
db->list = list;
|
||||
*content_list = list;
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
void database_info_free(database_info_handle_t *db)
|
||||
{
|
||||
if (db)
|
||||
string_list_free(db->list);
|
||||
/* if (db)
|
||||
string_list_free(db->list);*/
|
||||
}
|
||||
|
||||
database_info_list_t *database_info_list_new(
|
||||
|
||||
+4
-5
@@ -75,8 +75,6 @@ enum database_query_type
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct string_list *list;
|
||||
size_t list_ptr;
|
||||
enum database_status status;
|
||||
enum database_type type;
|
||||
} database_info_handle_t;
|
||||
@@ -145,11 +143,12 @@ database_info_list_t *database_info_list_new(const char *rdb_path,
|
||||
void database_info_list_free(database_info_list_t *list);
|
||||
|
||||
database_info_handle_t *database_info_dir_init(const char *dir,
|
||||
enum database_type type, retro_task_t *task,
|
||||
bool show_hidden_files);
|
||||
enum database_type type, char* file_exts,
|
||||
bool show_hidden_files, bool recursive, bool include_archive,
|
||||
struct string_list **content_list);
|
||||
|
||||
database_info_handle_t *database_info_file_init(const char *path,
|
||||
enum database_type type, retro_task_t *task);
|
||||
enum database_type type, retro_task_t *task, struct string_list **content_list);
|
||||
|
||||
void database_info_free(database_info_handle_t *handle);
|
||||
|
||||
|
||||
+10
-10
@@ -8073,7 +8073,7 @@ MSG_HASH(
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_PLAYLIST_MANAGER_REFRESH_PLAYLIST,
|
||||
"Add new content and remove invalid entries by repeating the 'Manual Scan' operation last used to create or edit the playlist."
|
||||
"Add new content and remove invalid entries by repeating the content scan operation last used to create or edit the playlist."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_DELETE_PLAYLIST,
|
||||
@@ -8670,11 +8670,11 @@ MSG_HASH(
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_LIST,
|
||||
"Manual Scan"
|
||||
"Content Scan"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_LIST,
|
||||
"Configurable scan based on content file names. Does not require content to match the database."
|
||||
"Configurable scan based on content file names and/or database match."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_SCAN_ENTRY,
|
||||
@@ -8740,31 +8740,31 @@ MSG_HASH(
|
||||
"Add to Mixer and Play"
|
||||
)
|
||||
|
||||
/* Import Content > Manual Scan */
|
||||
/* Import Content > Content Scan */
|
||||
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_DIR,
|
||||
"Content Directory"
|
||||
"Content Location"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_DIR,
|
||||
"Select a directory to scan for content."
|
||||
"Select a directory (or file) to scan for content."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME,
|
||||
"System Name"
|
||||
"Target Playlist"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME,
|
||||
"Specify a 'system name' with which to associate scanned content. Used to name to the generated playlist file and to identify playlist thumbnails."
|
||||
"Name of the generated playlist file, also used to identify playlist thumbnails. Automatic setting will use the same name as the matching database or content directory."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM,
|
||||
"Custom System Name"
|
||||
"Custom Playlist Name"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM,
|
||||
"Manually specify a 'system name' for scanned content. Only used when 'System Name' is set to '<Custom>'."
|
||||
"Custom playlist name for scanned content."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_CORE_NAME,
|
||||
|
||||
+296
-101
@@ -39,8 +39,11 @@
|
||||
* with a manual content scan */
|
||||
typedef struct
|
||||
{
|
||||
enum manual_content_scan_method scan_method;
|
||||
enum manual_content_scan_system_name_type system_name_type;
|
||||
enum manual_content_scan_core_type core_type;
|
||||
enum manual_content_scan_db_usage db_usage;
|
||||
enum manual_content_scan_db_selection db_selection;
|
||||
|
||||
char core_path[PATH_MAX_LENGTH];
|
||||
char file_exts_core[PATH_MAX_LENGTH];
|
||||
@@ -54,6 +57,8 @@ typedef struct
|
||||
|
||||
bool search_recursively;
|
||||
bool search_archives;
|
||||
bool scan_single_file;
|
||||
bool omit_db_ref;
|
||||
bool filter_dat_content;
|
||||
bool overwrite_playlist;
|
||||
bool validate_entries;
|
||||
@@ -70,19 +75,24 @@ typedef struct
|
||||
* are not thread safe, but we only access them when pushing a
|
||||
* task, not in the task thread itself, so all is well) */
|
||||
static scan_settings_t scan_settings = {
|
||||
MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR, /* system_name_type */
|
||||
MANUAL_CONTENT_SCAN_METHOD_AUTOMATIC, /* scan method */
|
||||
MANUAL_CONTENT_SCAN_SYSTEM_NAME_AUTO, /* system_name_type */
|
||||
MANUAL_CONTENT_SCAN_CORE_DETECT, /* core_type */
|
||||
MANUAL_CONTENT_SCAN_USE_DB_STRICT,
|
||||
MANUAL_CONTENT_SCAN_SELECT_DB_AUTO,
|
||||
"", /* core_path */
|
||||
"", /* file_exts_core */
|
||||
"", /* file_exts_custom */
|
||||
"", /* dat_file_path */
|
||||
"", /* content_dir */
|
||||
"", /* system_name_content_dir */
|
||||
"", /* system_name_database */
|
||||
"", /* system_name_custom */
|
||||
"", /* core_name */
|
||||
"", /* core_path */
|
||||
"", /* file_exts_core */
|
||||
"", /* file_exts_custom */
|
||||
"", /* dat_file_path */
|
||||
true, /* search_recursively */
|
||||
false, /* search_archives */
|
||||
true, /* search_archives */
|
||||
false,
|
||||
false,
|
||||
false, /* filter_dat_content */
|
||||
false, /* overwrite_playlist */
|
||||
false /* validate_entries */
|
||||
@@ -103,12 +113,12 @@ char *manual_content_scan_get_content_dir_ptr(void)
|
||||
|
||||
unsigned manual_content_scan_get_scan_method_enum(void)
|
||||
{
|
||||
return 0;
|
||||
return scan_settings.scan_method;
|
||||
}
|
||||
|
||||
unsigned manual_content_scan_get_scan_use_db_enum(void)
|
||||
{
|
||||
return 0;
|
||||
return scan_settings.db_usage;
|
||||
}
|
||||
|
||||
/* Returns a pointer to the internal
|
||||
@@ -169,12 +179,12 @@ bool *manual_content_scan_get_search_archives_ptr(void)
|
||||
|
||||
bool *manual_content_scan_get_scan_single_file_ptr(void)
|
||||
{
|
||||
return NULL;
|
||||
return &scan_settings.scan_single_file;
|
||||
}
|
||||
|
||||
bool *manual_content_scan_get_omit_db_ref_ptr(void)
|
||||
{
|
||||
return NULL;
|
||||
return &scan_settings.omit_db_ref;
|
||||
}
|
||||
|
||||
/* Returns a pointer to the internal
|
||||
@@ -312,9 +322,6 @@ bool manual_content_scan_set_menu_content_dir(const char *content_dir)
|
||||
if (string_is_empty(content_dir))
|
||||
goto error;
|
||||
|
||||
if (!path_is_directory(content_dir))
|
||||
goto error;
|
||||
|
||||
/* Copy directory path to settings struct.
|
||||
* Remove trailing slash, if required */
|
||||
if ((_len = strlcpy(
|
||||
@@ -357,19 +364,55 @@ error:
|
||||
bool manual_content_scan_set_menu_scan_method(
|
||||
enum manual_content_scan_method method)
|
||||
{
|
||||
scan_settings.scan_method = method;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool manual_content_scan_set_menu_scan_use_db(
|
||||
enum manual_content_scan_db_usage usage)
|
||||
{
|
||||
return true;
|
||||
if (usage <= MANUAL_CONTENT_SCAN_USE_DB_NONE)
|
||||
{
|
||||
scan_settings.db_usage = usage;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
scan_settings.db_usage = MANUAL_CONTENT_SCAN_USE_DB_NONE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool manual_content_scan_set_menu_scan_db_select(
|
||||
enum manual_content_scan_db_selection select,
|
||||
const char *db_name)
|
||||
{
|
||||
if (select == MANUAL_CONTENT_SCAN_SELECT_DB_AUTO ||
|
||||
select == MANUAL_CONTENT_SCAN_SELECT_DB_AUTO_FIRST_MATCH)
|
||||
{
|
||||
scan_settings.db_selection = select;
|
||||
/*scan_settings.system_name_database[0] = '\0';*/
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We are using a database name... */
|
||||
if (string_is_empty(db_name))
|
||||
goto error;
|
||||
|
||||
scan_settings.db_selection = MANUAL_CONTENT_SCAN_SELECT_DB_SPECIFIC;
|
||||
/* Copy database name to settings struct */
|
||||
strlcpy(
|
||||
scan_settings.system_name_database,
|
||||
db_name,
|
||||
sizeof(scan_settings.system_name_database));
|
||||
}
|
||||
return true;
|
||||
|
||||
error:
|
||||
/* Input parameters are invalid - reset internal
|
||||
* 'system_name_type' and 'system_name_database' */
|
||||
scan_settings.db_selection = MANUAL_CONTENT_SCAN_SELECT_DB_AUTO;
|
||||
scan_settings.system_name_database[0] = '\0';
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -396,8 +439,10 @@ bool manual_content_scan_set_menu_system_name(
|
||||
|
||||
/* Check if we are using a non-database name */
|
||||
if ((scan_settings.system_name_type == MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR) ||
|
||||
(scan_settings.system_name_type == MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM))
|
||||
scan_settings.system_name_database[0] = '\0';
|
||||
(scan_settings.system_name_type == MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM) ||
|
||||
(scan_settings.system_name_type == MANUAL_CONTENT_SCAN_SYSTEM_NAME_AUTO))
|
||||
/* No-op. Keep the existing system_name_database. */
|
||||
;
|
||||
else
|
||||
{
|
||||
/* We are using a database name... */
|
||||
@@ -416,7 +461,7 @@ bool manual_content_scan_set_menu_system_name(
|
||||
error:
|
||||
/* Input parameters are invalid - reset internal
|
||||
* 'system_name_type' and 'system_name_database' */
|
||||
scan_settings.system_name_type = MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR;
|
||||
scan_settings.system_name_type = MANUAL_CONTENT_SCAN_SYSTEM_NAME_AUTO;
|
||||
scan_settings.system_name_database[0] = '\0';
|
||||
return false;
|
||||
}
|
||||
@@ -547,10 +592,13 @@ enum manual_content_scan_playlist_refresh_status
|
||||
const char *core_name = NULL;
|
||||
const char *file_exts = NULL;
|
||||
const char *dat_file_path = NULL;
|
||||
const char *database_name_lpl = NULL;
|
||||
bool search_recursively = false;
|
||||
bool search_archives = false;
|
||||
bool filter_dat_content = false;
|
||||
bool overwrite_playlist = false;
|
||||
bool omit_db_ref = false;
|
||||
int db_usage = MANUAL_CONTENT_SCAN_USE_DB_NONE;
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
struct string_list *rdb_list = NULL;
|
||||
#endif
|
||||
@@ -559,6 +607,7 @@ enum manual_content_scan_playlist_refresh_status
|
||||
enum manual_content_scan_core_type
|
||||
core_type = MANUAL_CONTENT_SCAN_CORE_DETECT;
|
||||
char system_name[NAME_MAX_LENGTH];
|
||||
char database_name[NAME_MAX_LENGTH];
|
||||
|
||||
if (!playlist_scan_refresh_enabled(playlist))
|
||||
return MANUAL_CONTENT_SCAN_PLAYLIST_REFRESH_MISSING_CONFIG;
|
||||
@@ -569,11 +618,14 @@ enum manual_content_scan_playlist_refresh_status
|
||||
core_name = playlist_get_default_core_name(playlist);
|
||||
file_exts = playlist_get_scan_file_exts(playlist);
|
||||
dat_file_path = playlist_get_scan_dat_file_path(playlist);
|
||||
database_name_lpl = playlist_get_scan_database_name(playlist);
|
||||
|
||||
search_recursively = playlist_get_scan_search_recursively(playlist);
|
||||
search_archives = playlist_get_scan_search_archives(playlist);
|
||||
filter_dat_content = playlist_get_scan_filter_dat_content(playlist);
|
||||
overwrite_playlist = playlist_get_scan_overwrite_playlist(playlist);
|
||||
omit_db_ref = playlist_get_scan_omit_db_ref(playlist);
|
||||
db_usage = playlist_get_scan_db_usage(playlist);
|
||||
|
||||
/* Determine system name (playlist basename
|
||||
* without extension) */
|
||||
@@ -585,6 +637,8 @@ enum manual_content_scan_playlist_refresh_status
|
||||
fill_pathname(system_name, path_basename(playlist_path),
|
||||
"", sizeof(system_name));
|
||||
|
||||
if (database_name_lpl && !string_is_empty(database_name_lpl))
|
||||
fill_pathname(database_name,database_name_lpl,"",sizeof(database_name));
|
||||
/* Cannot happen, but would constitute a
|
||||
* 'system name' error */
|
||||
if (string_is_empty(system_name))
|
||||
@@ -594,6 +648,11 @@ enum manual_content_scan_playlist_refresh_status
|
||||
if (!manual_content_scan_set_menu_content_dir(content_dir))
|
||||
return MANUAL_CONTENT_SCAN_PLAYLIST_REFRESH_INVALID_CONTENT_DIR;
|
||||
|
||||
if (!manual_content_scan_set_menu_scan_use_db(db_usage))
|
||||
return MANUAL_CONTENT_SCAN_PLAYLIST_REFRESH_MISSING_CONFIG;
|
||||
|
||||
scan_settings.db_selection = MANUAL_CONTENT_SCAN_SELECT_DB_AUTO;
|
||||
|
||||
/* Set system name */
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
/* > If platform has database support, get names
|
||||
@@ -623,8 +682,17 @@ enum manual_content_scan_playlist_refresh_status
|
||||
if (string_is_equal(system_name, rdb_name))
|
||||
{
|
||||
system_name_type = MANUAL_CONTENT_SCAN_SYSTEM_NAME_DATABASE;
|
||||
strlcpy(scan_settings.system_name_database, system_name,
|
||||
sizeof(scan_settings.system_name_database));
|
||||
scan_settings.db_selection = MANUAL_CONTENT_SCAN_SELECT_DB_SPECIFIC;
|
||||
break;
|
||||
}
|
||||
if (string_is_equal(database_name, rdb_name))
|
||||
{
|
||||
strlcpy(scan_settings.system_name_database, database_name,
|
||||
sizeof(scan_settings.system_name_database));
|
||||
scan_settings.db_selection = MANUAL_CONTENT_SCAN_SELECT_DB_SPECIFIC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -712,6 +780,8 @@ enum manual_content_scan_playlist_refresh_status
|
||||
scan_settings.search_archives = search_archives;
|
||||
scan_settings.filter_dat_content = filter_dat_content;
|
||||
scan_settings.overwrite_playlist = overwrite_playlist;
|
||||
scan_settings.omit_db_ref = omit_db_ref;
|
||||
scan_settings.scan_method = MANUAL_CONTENT_SCAN_METHOD_CUSTOM;
|
||||
/* When refreshing a playlist:
|
||||
* > We always validate entries in the
|
||||
* existing file */
|
||||
@@ -737,21 +807,88 @@ bool manual_content_scan_get_menu_content_dir(const char **content_dir)
|
||||
|
||||
bool manual_content_scan_get_menu_scan_method(const char **scan_method)
|
||||
{
|
||||
if (scan_method)
|
||||
{
|
||||
switch (scan_settings.scan_method)
|
||||
{
|
||||
case MANUAL_CONTENT_SCAN_METHOD_AUTOMATIC:
|
||||
*scan_method = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_SCAN_METHOD_AUTO);
|
||||
return true;
|
||||
case MANUAL_CONTENT_SCAN_METHOD_CUSTOM:
|
||||
*scan_method = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_SCAN_METHOD_CUSTOM);
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool manual_content_scan_get_menu_scan_use_db(const char **scan_use_db)
|
||||
{
|
||||
if (scan_use_db)
|
||||
{
|
||||
switch (scan_settings.db_usage)
|
||||
{
|
||||
case MANUAL_CONTENT_SCAN_USE_DB_STRICT:
|
||||
*scan_use_db = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_SCAN_USE_DB_STRICT);
|
||||
return true;
|
||||
case MANUAL_CONTENT_SCAN_USE_DB_LOOSE:
|
||||
*scan_use_db = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_SCAN_USE_DB_LOOSE);
|
||||
return true;
|
||||
case MANUAL_CONTENT_SCAN_USE_DB_DAT_STRICT:
|
||||
*scan_use_db = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_SCAN_USE_DB_CUSTOM_DAT);
|
||||
return true;
|
||||
case MANUAL_CONTENT_SCAN_USE_DB_DAT_LOOSE:
|
||||
*scan_use_db = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_SCAN_USE_DB_CUSTOM_DAT_LOOSE);
|
||||
return true;
|
||||
case MANUAL_CONTENT_SCAN_USE_DB_NONE:
|
||||
*scan_use_db = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_SCAN_USE_DB_NONE);
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned manual_content_scan_get_scan_db_select_enum(void)
|
||||
{
|
||||
return 0;
|
||||
return scan_settings.db_selection;
|
||||
}
|
||||
|
||||
bool manual_content_scan_get_menu_scan_db_select(const char **scan_db_select)
|
||||
{
|
||||
if (scan_db_select)
|
||||
{
|
||||
switch (scan_settings.db_selection)
|
||||
{
|
||||
case MANUAL_CONTENT_SCAN_SELECT_DB_AUTO:
|
||||
*scan_db_select = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_SCAN_DB_SELECT_AUTO_ANY);
|
||||
return true;
|
||||
case MANUAL_CONTENT_SCAN_SELECT_DB_AUTO_FIRST_MATCH:
|
||||
*scan_db_select = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_SCAN_DB_SELECT_AUTO_FIRST);
|
||||
return true;
|
||||
case MANUAL_CONTENT_SCAN_SELECT_DB_SPECIFIC:
|
||||
if (!string_is_empty(scan_settings.system_name_database))
|
||||
{
|
||||
*scan_db_select = scan_settings.system_name_database;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -774,6 +911,11 @@ bool manual_content_scan_get_menu_system_name(const char **system_name)
|
||||
*system_name = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME_USE_CUSTOM);
|
||||
return true;
|
||||
case MANUAL_CONTENT_SCAN_SYSTEM_NAME_AUTO:
|
||||
*system_name = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME_USE_AUTO);
|
||||
return true;
|
||||
|
||||
case MANUAL_CONTENT_SCAN_SYSTEM_NAME_DATABASE:
|
||||
if (!string_is_empty(scan_settings.system_name_database))
|
||||
{
|
||||
@@ -791,7 +933,7 @@ bool manual_content_scan_get_menu_system_name(const char **system_name)
|
||||
|
||||
unsigned manual_content_scan_get_menu_system_name_type(void)
|
||||
{
|
||||
return 0;
|
||||
return scan_settings.system_name_type;
|
||||
}
|
||||
/* Fetches core name for the next manual scan operation.
|
||||
* Returns true if core name is valid. */
|
||||
@@ -825,6 +967,28 @@ bool manual_content_scan_get_menu_core_name(const char **core_name)
|
||||
|
||||
struct string_list *manual_content_scan_get_menu_scan_method_list(void)
|
||||
{
|
||||
union string_list_elem_attr attr;
|
||||
struct string_list *name_list = string_list_new();
|
||||
|
||||
/* Sanity check */
|
||||
if (!name_list)
|
||||
return NULL;
|
||||
|
||||
attr.i = 0;
|
||||
|
||||
if (!string_list_append(name_list, msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_SCAN_METHOD_AUTO), attr))
|
||||
goto error;
|
||||
|
||||
if (!string_list_append(name_list, msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_SCAN_METHOD_CUSTOM), attr))
|
||||
goto error;
|
||||
|
||||
return name_list;
|
||||
|
||||
error:
|
||||
if (name_list)
|
||||
string_list_free(name_list);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
@@ -971,6 +1135,11 @@ struct string_list *manual_content_scan_get_menu_system_name_list(
|
||||
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME_USE_CUSTOM), attr))
|
||||
goto error;
|
||||
|
||||
/* Add 'use custom' entry */
|
||||
if (!string_list_append(name_list, msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME_USE_AUTO), attr))
|
||||
goto error;
|
||||
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
/* If platform has database support, get names
|
||||
* of all installed database files */
|
||||
@@ -1103,19 +1272,44 @@ bool manual_content_scan_get_task_config(
|
||||
task_config->file_exts[0] = '\0';
|
||||
task_config->dat_file_path[0] = '\0';
|
||||
|
||||
/* Ensure defaults for "fully automatic" method. */
|
||||
if (scan_settings.scan_method == MANUAL_CONTENT_SCAN_METHOD_AUTOMATIC)
|
||||
{
|
||||
/* Not all settings are zeroed, but the list below should ensure a consistent task setup */
|
||||
scan_settings.system_name_type = MANUAL_CONTENT_SCAN_SYSTEM_NAME_AUTO;
|
||||
scan_settings.core_type = MANUAL_CONTENT_SCAN_CORE_DETECT;
|
||||
scan_settings.db_usage = MANUAL_CONTENT_SCAN_USE_DB_STRICT;
|
||||
scan_settings.db_selection = MANUAL_CONTENT_SCAN_SELECT_DB_AUTO;
|
||||
scan_settings.file_exts_custom[0] = '\0';
|
||||
scan_settings.search_recursively = true;
|
||||
scan_settings.search_archives = true;
|
||||
scan_settings.scan_single_file = false;
|
||||
}
|
||||
/* Get content directory */
|
||||
if (string_is_empty(scan_settings.content_dir))
|
||||
return false;
|
||||
|
||||
if (!path_is_directory(scan_settings.content_dir))
|
||||
return false;
|
||||
scan_settings.scan_single_file = true;
|
||||
else
|
||||
scan_settings.scan_single_file = false;
|
||||
|
||||
strlcpy(
|
||||
task_config->content_dir,
|
||||
scan_settings.content_dir,
|
||||
sizeof(task_config->content_dir));
|
||||
|
||||
/* Get system name */
|
||||
/* If name is set as automatic, but is predictable, fill it now. */
|
||||
if (scan_settings.system_name_type == MANUAL_CONTENT_SCAN_SYSTEM_NAME_AUTO)
|
||||
{
|
||||
if (scan_settings.db_usage == MANUAL_CONTENT_SCAN_USE_DB_DAT_STRICT ||
|
||||
scan_settings.db_usage == MANUAL_CONTENT_SCAN_USE_DB_DAT_LOOSE ||
|
||||
scan_settings.db_usage == MANUAL_CONTENT_SCAN_USE_DB_NONE)
|
||||
scan_settings.system_name_type = MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR;
|
||||
else if (scan_settings.db_selection == MANUAL_CONTENT_SCAN_SELECT_DB_SPECIFIC)
|
||||
scan_settings.system_name_type = MANUAL_CONTENT_SCAN_SYSTEM_NAME_DATABASE;
|
||||
}
|
||||
/* Get target playlist ("system name") */
|
||||
switch (scan_settings.system_name_type)
|
||||
{
|
||||
case MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR:
|
||||
@@ -1125,6 +1319,7 @@ bool manual_content_scan_get_task_config(
|
||||
task_config->system_name,
|
||||
scan_settings.system_name_content_dir,
|
||||
sizeof(task_config->system_name));
|
||||
task_config->target_is_single_determined_playlist = true;
|
||||
break;
|
||||
case MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM:
|
||||
if (string_is_empty(scan_settings.system_name_custom))
|
||||
@@ -1133,6 +1328,7 @@ bool manual_content_scan_get_task_config(
|
||||
task_config->system_name,
|
||||
scan_settings.system_name_custom,
|
||||
sizeof(task_config->system_name));
|
||||
task_config->target_is_single_determined_playlist = true;
|
||||
break;
|
||||
case MANUAL_CONTENT_SCAN_SYSTEM_NAME_DATABASE:
|
||||
if (string_is_empty(scan_settings.system_name_database))
|
||||
@@ -1141,13 +1337,19 @@ bool manual_content_scan_get_task_config(
|
||||
task_config->system_name,
|
||||
scan_settings.system_name_database,
|
||||
sizeof(task_config->system_name));
|
||||
task_config->target_is_single_determined_playlist = true;
|
||||
break;
|
||||
case MANUAL_CONTENT_SCAN_SYSTEM_NAME_AUTO:
|
||||
/* Leave it as empty intentionally. */
|
||||
task_config->target_is_single_determined_playlist = false;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Now we have a valid system name, can generate
|
||||
* a 'database' name... */
|
||||
/* Store database name and playlist path, depending on scan settings */
|
||||
/* Old manual scan method: db name == target playlist */
|
||||
|
||||
fill_pathname(
|
||||
task_config->database_name,
|
||||
task_config->system_name,
|
||||
@@ -1168,6 +1370,34 @@ bool manual_content_scan_get_task_config(
|
||||
if (string_is_empty(task_config->playlist_file))
|
||||
return false;
|
||||
|
||||
if (scan_settings.db_usage == MANUAL_CONTENT_SCAN_USE_DB_STRICT ||
|
||||
scan_settings.db_usage == MANUAL_CONTENT_SCAN_USE_DB_LOOSE)
|
||||
{
|
||||
|
||||
/* Pass the selected DB name to the task if there is one */
|
||||
if (scan_settings.db_selection == MANUAL_CONTENT_SCAN_SELECT_DB_SPECIFIC)
|
||||
{
|
||||
fill_pathname(
|
||||
task_config->database_name,
|
||||
scan_settings.system_name_database,
|
||||
".lpl",
|
||||
sizeof(task_config->database_name));
|
||||
}
|
||||
/* Or make it empty (auto DB select case). The omit_db_ref is handled elsewhere. */
|
||||
else
|
||||
{
|
||||
task_config->database_name[0] = '\0';
|
||||
if (scan_settings.system_name_type == MANUAL_CONTENT_SCAN_SYSTEM_NAME_AUTO)
|
||||
task_config->playlist_file[0] = '\0';
|
||||
/* Abuse dat_file_path for a convenient placeholder value */
|
||||
fill_pathname(
|
||||
task_config->dat_file_path,
|
||||
scan_settings.system_name_content_dir,
|
||||
".lpl",
|
||||
sizeof(task_config->dat_file_path));
|
||||
}
|
||||
}
|
||||
|
||||
/* Get core name and path */
|
||||
switch (scan_settings.core_type)
|
||||
{
|
||||
@@ -1198,6 +1428,7 @@ bool manual_content_scan_get_task_config(
|
||||
}
|
||||
|
||||
/* Get file extensions list */
|
||||
/* Possible improvement: if DB is set (but not core), some filtering may be applied */
|
||||
task_config->file_exts_custom_set = false;
|
||||
if (!string_is_empty(scan_settings.file_exts_custom))
|
||||
{
|
||||
@@ -1221,7 +1452,9 @@ bool manual_content_scan_get_task_config(
|
||||
string_replace_all_chars(task_config->file_exts, ' ', '|');
|
||||
|
||||
/* Get DAT file path */
|
||||
if (!string_is_empty(scan_settings.dat_file_path))
|
||||
if ((scan_settings.db_usage == MANUAL_CONTENT_SCAN_USE_DB_DAT_STRICT ||
|
||||
scan_settings.db_usage == MANUAL_CONTENT_SCAN_USE_DB_DAT_LOOSE) &&
|
||||
!string_is_empty(scan_settings.dat_file_path))
|
||||
{
|
||||
if (!logiqx_dat_path_is_valid(scan_settings.dat_file_path, NULL))
|
||||
return false;
|
||||
@@ -1235,12 +1468,17 @@ bool manual_content_scan_get_task_config(
|
||||
task_config->search_recursively = scan_settings.search_recursively;
|
||||
/* Copy 'search inside archives' setting */
|
||||
task_config->search_archives = scan_settings.search_archives;
|
||||
/* Copy 'DAT file filter' setting */
|
||||
task_config->filter_dat_content = scan_settings.filter_dat_content;
|
||||
/* Set up filter if DB usage requires */
|
||||
task_config->filter_dat_content =
|
||||
(scan_settings.db_usage == MANUAL_CONTENT_SCAN_USE_DB_DAT_STRICT) ? true : false;
|
||||
/* Copy 'overwrite playlist' setting */
|
||||
task_config->overwrite_playlist = scan_settings.overwrite_playlist;
|
||||
/* Copy 'validate_entries' setting */
|
||||
task_config->validate_entries = scan_settings.validate_entries;
|
||||
|
||||
task_config->omit_db_reference = scan_settings.omit_db_ref;
|
||||
task_config->db_usage = scan_settings.db_usage;
|
||||
task_config->db_selection = scan_settings.db_selection;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1277,16 +1515,28 @@ struct string_list *manual_content_scan_get_content_list(
|
||||
* then compressed files must of course be included */
|
||||
include_compressed = (!filter_exts || task_config->search_archives);
|
||||
|
||||
/* Get directory listing
|
||||
* > Exclude directories and hidden files */
|
||||
dir_list = dir_list_new(
|
||||
task_config->content_dir,
|
||||
filter_exts ? task_config->file_exts : NULL,
|
||||
false, /* include_dirs */
|
||||
false, /* include_hidden */
|
||||
include_compressed,
|
||||
task_config->search_recursively
|
||||
);
|
||||
if (path_is_directory(task_config->content_dir))
|
||||
{
|
||||
/* Get directory listing
|
||||
* > Exclude directories and hidden files */
|
||||
dir_list = dir_list_new(
|
||||
task_config->content_dir,
|
||||
filter_exts ? task_config->file_exts : NULL,
|
||||
false, /* include_dirs */
|
||||
false, /* include_hidden */ /* todo: obey global settings? */
|
||||
include_compressed,
|
||||
task_config->search_recursively
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((dir_list = string_list_new()))
|
||||
{
|
||||
union string_list_elem_attr attr;
|
||||
attr.i = 0;
|
||||
string_list_append(dir_list, task_config->content_dir, attr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Sanity check */
|
||||
if (!dir_list || dir_list->size < 1)
|
||||
@@ -1315,79 +1565,24 @@ bool manual_content_scan_get_playlist_content_path(
|
||||
const char *content_path, int content_type,
|
||||
char *s, size_t len)
|
||||
{
|
||||
size_t _len;
|
||||
struct string_list *archive_list = NULL;
|
||||
/* Sanity check */
|
||||
if (!task_config || string_is_empty(content_path))
|
||||
return false;
|
||||
/* Allow paths inside archives, but do not add directories in or outside of archives. */
|
||||
if (!path_is_valid(content_path))
|
||||
{
|
||||
if(!(string_index_last_occurance(content_path,'#') > 0) ||
|
||||
(string_index_last_occurance(content_path,'/') + 1 == (int)strlen(content_path)))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (path_is_directory(content_path))
|
||||
return false;
|
||||
/* In all cases, base content path must be
|
||||
* copied to @s */
|
||||
_len = strlcpy(s, content_path, len);
|
||||
/* Check whether this is an archive file
|
||||
* requiring special attention... */
|
||||
if ( (content_type == RARCH_COMPRESSED_ARCHIVE)
|
||||
&& task_config->search_archives)
|
||||
{
|
||||
bool filter_exts = !string_is_empty(task_config->file_exts);
|
||||
const char *archive_file = NULL;
|
||||
|
||||
/* Important note:
|
||||
* > If an archive file of a particular type is
|
||||
* included in the task_config->file_exts list,
|
||||
* dir_list_new() will assign it a file type of
|
||||
* RARCH_PLAIN_FILE
|
||||
* > Thus we will only reach this point if
|
||||
* (a) We are not filtering by extension
|
||||
* (b) This is an archive file type *not*
|
||||
* already included in the supported
|
||||
* extensions list
|
||||
* > These guarantees substantially reduce the
|
||||
* complexity of the following code... */
|
||||
|
||||
/* Get archive file contents */
|
||||
if (!(archive_list = file_archive_get_file_list(
|
||||
content_path, filter_exts ? task_config->file_exts : NULL)))
|
||||
return false;
|
||||
|
||||
if (archive_list->size < 1)
|
||||
goto error;
|
||||
|
||||
/* Get first file contained in archive */
|
||||
dir_list_sort(archive_list, true);
|
||||
archive_file = archive_list->elems[0].data;
|
||||
if (string_is_empty(archive_file))
|
||||
goto error;
|
||||
|
||||
/* Have to take care to ensure that we don't make
|
||||
* a mess of arcade content...
|
||||
* > If we are filtering by extension, then the
|
||||
* archive file itself is *not* valid content,
|
||||
* so link to the first file inside the archive
|
||||
* > If we are not filtering by extension, then:
|
||||
* - If archive contains one valid file, assume
|
||||
* it is a compressed ROM
|
||||
* - If archive contains multiple files, have to
|
||||
* assume it is MAME/FBA-style content, where
|
||||
* only the archive itself is valid */
|
||||
if (filter_exts || (archive_list->size == 1))
|
||||
{
|
||||
/* Build path to file inside archive */
|
||||
s[ _len] = '#';
|
||||
s[++_len] = '\0';
|
||||
strlcpy(s + _len, archive_file, len - _len);
|
||||
}
|
||||
|
||||
string_list_free(archive_list);
|
||||
}
|
||||
|
||||
strlcpy(s, content_path, len);
|
||||
return true;
|
||||
|
||||
error:
|
||||
if (archive_list)
|
||||
string_list_free(archive_list);
|
||||
return false;
|
||||
/* no need to do all the other magic here any more */
|
||||
}
|
||||
|
||||
/* Extracts content 'label' (name) from content path
|
||||
|
||||
@@ -49,6 +49,7 @@ enum manual_content_scan_system_name_type
|
||||
{
|
||||
MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR = 0,
|
||||
MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM,
|
||||
MANUAL_CONTENT_SCAN_SYSTEM_NAME_AUTO,
|
||||
MANUAL_CONTENT_SCAN_SYSTEM_NAME_DATABASE
|
||||
};
|
||||
|
||||
@@ -121,6 +122,10 @@ typedef struct
|
||||
bool filter_dat_content;
|
||||
bool overwrite_playlist;
|
||||
bool validate_entries;
|
||||
bool omit_db_reference;
|
||||
bool target_is_single_determined_playlist;
|
||||
enum manual_content_scan_db_usage db_usage;
|
||||
enum manual_content_scan_db_selection db_selection;
|
||||
} manual_content_scan_task_config_t;
|
||||
|
||||
/*****************/
|
||||
|
||||
@@ -714,6 +714,7 @@ static int manual_content_scan_system_name_left(
|
||||
unsigned current_index = 0;
|
||||
unsigned next_index = 0;
|
||||
unsigned i;
|
||||
struct menu_state *menu_st = menu_state_get_ptr();
|
||||
|
||||
if (!system_name_list)
|
||||
return -1;
|
||||
@@ -745,12 +746,15 @@ static int manual_content_scan_system_name_left(
|
||||
next_system_name_type = MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR;
|
||||
else if (next_index == (unsigned)MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM)
|
||||
next_system_name_type = MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM;
|
||||
else if (next_index == (unsigned)MANUAL_CONTENT_SCAN_SYSTEM_NAME_AUTO)
|
||||
next_system_name_type = MANUAL_CONTENT_SCAN_SYSTEM_NAME_AUTO;
|
||||
|
||||
next_system_name = system_name_list->elems[next_index].data;
|
||||
|
||||
/* Set system name */
|
||||
manual_content_scan_set_menu_system_name(
|
||||
next_system_name_type, next_system_name);
|
||||
menu_st->flags |= MENU_ST_FLAG_ENTRIES_NEED_REFRESH;
|
||||
|
||||
/* Clean up */
|
||||
string_list_free(system_name_list);
|
||||
|
||||
+38
-15
@@ -1297,11 +1297,20 @@ int generic_action_ok_displaylist_push(
|
||||
dl_type = DISPLAYLIST_FILE_BROWSER_SCAN_DIR;
|
||||
break;
|
||||
case ACTION_OK_DL_MANUAL_SCAN_DIR_LIST:
|
||||
filebrowser_set_type(FILEBROWSER_MANUAL_SCAN_DIR);
|
||||
info.type = FILE_TYPE_DIRECTORY;
|
||||
if (*(manual_content_scan_get_scan_single_file_ptr()) == true)
|
||||
{
|
||||
filebrowser_set_type(FILEBROWSER_SCAN_FILE);
|
||||
info.type = FILE_TYPE_PLAIN;
|
||||
dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE;
|
||||
}
|
||||
else
|
||||
{
|
||||
filebrowser_set_type(FILEBROWSER_MANUAL_SCAN_DIR);
|
||||
info.type = FILE_TYPE_DIRECTORY;
|
||||
dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_DIR;
|
||||
}
|
||||
info.directory_ptr = idx;
|
||||
info_label = label;
|
||||
dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_DIR;
|
||||
|
||||
action_ok_get_file_browser_start_path(
|
||||
manual_content_scan_get_content_dir_ptr(),
|
||||
@@ -4239,21 +4248,38 @@ static int action_ok_path_scan_directory(const char *path,
|
||||
static int action_ok_path_manual_scan_directory(const char *path,
|
||||
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||
{
|
||||
#if IOS
|
||||
char dir_path[DIR_MAX_LENGTH];
|
||||
#endif
|
||||
char content_dir[DIR_MAX_LENGTH];
|
||||
unsigned flush_type = 0;
|
||||
const char *menu_path = NULL;
|
||||
|
||||
content_dir[0] = '\0';
|
||||
|
||||
if (filebrowser_get_type() == FILEBROWSER_SCAN_FILE)
|
||||
{
|
||||
menu_entries_get_last_stack(&menu_path, NULL, NULL, NULL, NULL);
|
||||
|
||||
#if IOS
|
||||
fill_pathname_expand_special(dir_path, menu_path, sizeof(dir_path));
|
||||
menu_path = dir_path;
|
||||
#endif
|
||||
|
||||
fill_pathname_join_special(content_dir, menu_path, path, sizeof(content_dir));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get user-selected scan directory */
|
||||
menu_entries_get_last_stack(&menu_path,
|
||||
NULL, NULL, NULL, NULL);
|
||||
|
||||
if (!string_is_empty(menu_path))
|
||||
strlcpy(content_dir, menu_path, sizeof(content_dir));
|
||||
}
|
||||
/* 'Reset' file browser */
|
||||
filebrowser_clear_type();
|
||||
|
||||
/* Get user-selected scan directory */
|
||||
menu_entries_get_last_stack(&menu_path,
|
||||
NULL, NULL, NULL, NULL);
|
||||
|
||||
if (!string_is_empty(menu_path))
|
||||
strlcpy(content_dir, menu_path, sizeof(content_dir));
|
||||
|
||||
#ifdef HAVE_COCOATOUCH
|
||||
{
|
||||
@@ -7580,6 +7606,7 @@ static int action_ok_push_dropdown_item_manual_content_scan_system_name(
|
||||
{
|
||||
case MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR:
|
||||
case MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM:
|
||||
case MANUAL_CONTENT_SCAN_SYSTEM_NAME_AUTO:
|
||||
system_name_type = (enum manual_content_scan_system_name_type)idx;
|
||||
break;
|
||||
default:
|
||||
@@ -9915,9 +9942,7 @@ static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs,
|
||||
case FILE_TYPE_CARCHIVE:
|
||||
if (filebrowser_get_type() == FILEBROWSER_SCAN_FILE)
|
||||
{
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
BIND_ACTION_OK(cbs, action_ok_scan_file);
|
||||
#endif
|
||||
BIND_ACTION_OK(cbs, action_ok_path_manual_scan_directory);
|
||||
}
|
||||
#ifdef HAVE_COMPRESSION
|
||||
else if (filebrowser_get_type() == FILEBROWSER_SELECT_OVERLAY)
|
||||
@@ -10079,9 +10104,7 @@ static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs,
|
||||
case FILE_TYPE_PLAIN:
|
||||
if (filebrowser_get_type() == FILEBROWSER_SCAN_FILE)
|
||||
{
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
BIND_ACTION_OK(cbs, action_ok_scan_file);
|
||||
#endif
|
||||
BIND_ACTION_OK(cbs, action_ok_path_manual_scan_directory);
|
||||
}
|
||||
else if (cbs->enum_idx != MSG_UNKNOWN)
|
||||
{
|
||||
|
||||
@@ -851,6 +851,7 @@ static int manual_content_scan_system_name_right(unsigned type, const char *labe
|
||||
unsigned current_index = 0;
|
||||
unsigned next_index = 0;
|
||||
unsigned i;
|
||||
struct menu_state *menu_st = menu_state_get_ptr();
|
||||
|
||||
if (!system_name_list)
|
||||
return -1;
|
||||
@@ -885,12 +886,15 @@ static int manual_content_scan_system_name_right(unsigned type, const char *labe
|
||||
next_system_name_type = MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR;
|
||||
else if (next_index == (unsigned)MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM)
|
||||
next_system_name_type = MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM;
|
||||
else if (next_index == (unsigned)MANUAL_CONTENT_SCAN_SYSTEM_NAME_AUTO)
|
||||
next_system_name_type = MANUAL_CONTENT_SCAN_SYSTEM_NAME_AUTO;
|
||||
|
||||
next_system_name = system_name_list->elems[next_index].data;
|
||||
|
||||
/* Set system name */
|
||||
manual_content_scan_set_menu_system_name(
|
||||
next_system_name_type, next_system_name);
|
||||
menu_st->flags |= MENU_ST_FLAG_ENTRIES_NEED_REFRESH;
|
||||
|
||||
/* Clean up */
|
||||
string_list_free(system_name_list);
|
||||
|
||||
@@ -568,9 +568,11 @@ static int action_start_manual_content_scan_system_name(
|
||||
const char *path, const char *label,
|
||||
unsigned type, size_t idx, size_t entry_idx)
|
||||
{
|
||||
struct menu_state *menu_st = menu_state_get_ptr();
|
||||
/* Reset system name */
|
||||
manual_content_scan_set_menu_system_name(
|
||||
MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR, "");
|
||||
MANUAL_CONTENT_SCAN_SYSTEM_NAME_AUTO, "");
|
||||
menu_st->flags |= MENU_ST_FLAG_ENTRIES_NEED_REFRESH;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+135
-54
@@ -6532,70 +6532,151 @@ static unsigned menu_displaylist_parse_manual_content_scan_list(
|
||||
MENU_SETTING_MANUAL_CONTENT_SCAN_DIR, 0, 0, NULL))
|
||||
count++;
|
||||
|
||||
/* System name */
|
||||
/* Scan method - automatic or custom (more entries) */
|
||||
if (menu_entries_append(info_list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME),
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME_STR,
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME,
|
||||
MENU_SETTING_MANUAL_CONTENT_SCAN_SYSTEM_NAME, 0, 0, NULL))
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_METHOD),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_SCAN_METHOD),
|
||||
MENU_ENUM_LABEL_SCAN_METHOD,
|
||||
MENU_SETTING_SCAN_METHOD, 0, 0, NULL))
|
||||
count++;
|
||||
|
||||
/* Custom system name */
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info_list,
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM, PARSE_ONLY_STRING,
|
||||
false) == 0)
|
||||
count++;
|
||||
if (manual_content_scan_get_scan_method_enum() == MANUAL_CONTENT_SCAN_METHOD_CUSTOM)
|
||||
{
|
||||
/* DB usage - matching strategy */
|
||||
if (menu_entries_append(info_list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_USE_DB),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_SCAN_USE_DB),
|
||||
MENU_ENUM_LABEL_SCAN_USE_DB,
|
||||
MENU_SETTING_SCAN_USE_DB, 0, 0, NULL))
|
||||
count++;
|
||||
|
||||
/* Core name */
|
||||
if (menu_entries_append(info_list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_CORE_NAME),
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_CORE_NAME_STR,
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_CORE_NAME,
|
||||
MENU_SETTING_MANUAL_CONTENT_SCAN_CORE_NAME, 0, 0, NULL))
|
||||
count++;
|
||||
if (manual_content_scan_get_scan_use_db_enum() == MANUAL_CONTENT_SCAN_USE_DB_DAT_LOOSE ||
|
||||
manual_content_scan_get_scan_use_db_enum() == MANUAL_CONTENT_SCAN_USE_DB_DAT_STRICT)
|
||||
{
|
||||
/* Arcade DAT file - only if DAT file is used*/
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info_list,
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_DAT_FILE, PARSE_ONLY_PATH,
|
||||
false) == 0)
|
||||
count++;
|
||||
}
|
||||
else if (manual_content_scan_get_scan_use_db_enum() != MANUAL_CONTENT_SCAN_USE_DB_NONE)
|
||||
{
|
||||
/* Database selection */
|
||||
if (menu_entries_append(info_list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DB_SELECT),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_SCAN_DB_SELECT),
|
||||
MENU_ENUM_LABEL_SCAN_DB_SELECT,
|
||||
MENU_SETTING_SCAN_DB_SELECT, 0, 0, NULL))
|
||||
count++;
|
||||
}
|
||||
|
||||
/* File extensions */
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info_list,
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_FILE_EXTS, PARSE_ONLY_STRING,
|
||||
false) == 0)
|
||||
count++;
|
||||
/* Target playlist (system name in old terminology) */
|
||||
if (menu_entries_append(info_list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME),
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME,
|
||||
MENU_SETTING_MANUAL_CONTENT_SCAN_SYSTEM_NAME, 0, 0, NULL))
|
||||
count++;
|
||||
|
||||
/* Search recursively */
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info_list,
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SEARCH_RECURSIVELY, PARSE_ONLY_BOOL,
|
||||
false) == 0)
|
||||
count++;
|
||||
if (manual_content_scan_get_menu_system_name_type() == MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM)
|
||||
{
|
||||
/* Custom target playlist */
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info_list,
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM, PARSE_ONLY_STRING,
|
||||
false) == 0)
|
||||
count++;
|
||||
}
|
||||
if (manual_content_scan_get_menu_system_name_type() == MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM ||
|
||||
manual_content_scan_get_menu_system_name_type() == MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR)
|
||||
{
|
||||
/* DB reference skipping only makes sense if there is a DB used */
|
||||
if (manual_content_scan_get_scan_use_db_enum() == MANUAL_CONTENT_SCAN_USE_DB_STRICT ||
|
||||
manual_content_scan_get_scan_use_db_enum() == MANUAL_CONTENT_SCAN_USE_DB_LOOSE)
|
||||
{
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info_list,
|
||||
MENU_ENUM_LABEL_SCAN_OMIT_DB_REF, PARSE_ONLY_BOOL,
|
||||
false) == 0)
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Search inside archive files */
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info_list,
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SEARCH_ARCHIVES, PARSE_ONLY_BOOL,
|
||||
false) == 0)
|
||||
count++;
|
||||
/* Core name */
|
||||
if (menu_entries_append(info_list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_CORE_NAME),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_CORE_NAME),
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_CORE_NAME,
|
||||
MENU_SETTING_MANUAL_CONTENT_SCAN_CORE_NAME, 0, 0, NULL))
|
||||
count++;
|
||||
|
||||
/* Arcade DAT file */
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info_list,
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_DAT_FILE, PARSE_ONLY_PATH,
|
||||
false) == 0)
|
||||
count++;
|
||||
/* File extensions */
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info_list,
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_FILE_EXTS, PARSE_ONLY_STRING,
|
||||
false) == 0)
|
||||
count++;
|
||||
|
||||
/* Arcade DAT filter */
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info_list,
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_DAT_FILE_FILTER, PARSE_ONLY_BOOL,
|
||||
false) == 0)
|
||||
count++;
|
||||
/* Search recursively */
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info_list,
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SEARCH_RECURSIVELY, PARSE_ONLY_BOOL,
|
||||
false) == 0)
|
||||
count++;
|
||||
|
||||
/* Overwrite playlist */
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info_list,
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_OVERWRITE, PARSE_ONLY_BOOL,
|
||||
false) == 0)
|
||||
count++;
|
||||
if (*(manual_content_scan_get_search_recursively_ptr()) == false)
|
||||
{
|
||||
/* Scan only one file */
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info_list,
|
||||
MENU_ENUM_LABEL_SCAN_SINGLE_FILE, PARSE_ONLY_BOOL,
|
||||
false) == 0)
|
||||
count++;
|
||||
}
|
||||
|
||||
/* Validate existing entries */
|
||||
if (!(*manual_content_scan_get_overwrite_playlist_ptr())
|
||||
&& MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info_list,
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_VALIDATE_ENTRIES, PARSE_ONLY_BOOL,
|
||||
false) == 0)
|
||||
count++;
|
||||
/* Search inside archive files */
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info_list,
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SEARCH_ARCHIVES, PARSE_ONLY_BOOL,
|
||||
false) == 0)
|
||||
count++;
|
||||
|
||||
/* Arcade DAT filter is merged with DB usage setting */
|
||||
|
||||
/* Hiding validate / overwrite in cases when target playlist can not be determined in advance */
|
||||
if ((manual_content_scan_get_scan_use_db_enum() == MANUAL_CONTENT_SCAN_USE_DB_STRICT ||
|
||||
manual_content_scan_get_scan_use_db_enum() == MANUAL_CONTENT_SCAN_USE_DB_LOOSE) &&
|
||||
(manual_content_scan_get_scan_db_select_enum() == MANUAL_CONTENT_SCAN_SELECT_DB_AUTO ||
|
||||
manual_content_scan_get_scan_db_select_enum() == MANUAL_CONTENT_SCAN_SELECT_DB_AUTO_FIRST_MATCH ) &&
|
||||
manual_content_scan_get_menu_system_name_type() == MANUAL_CONTENT_SCAN_SYSTEM_NAME_AUTO)
|
||||
{
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Overwrite playlist */
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info_list,
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_OVERWRITE, PARSE_ONLY_BOOL,
|
||||
false) == 0)
|
||||
count++;
|
||||
|
||||
/* Validate existing entries */
|
||||
if (!(*manual_content_scan_get_overwrite_playlist_ptr())
|
||||
&& MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info_list,
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_VALIDATE_ENTRIES, PARSE_ONLY_BOOL,
|
||||
false) == 0)
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Scan without core match and CRC duplicate check only makes sense if there is a DB used */
|
||||
if (manual_content_scan_get_scan_use_db_enum() == MANUAL_CONTENT_SCAN_USE_DB_STRICT ||
|
||||
manual_content_scan_get_scan_use_db_enum() == MANUAL_CONTENT_SCAN_USE_DB_LOOSE)
|
||||
{
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info_list,
|
||||
MENU_ENUM_LABEL_SCAN_WITHOUT_CORE_MATCH, PARSE_ONLY_BOOL,
|
||||
false) == 0)
|
||||
count++;
|
||||
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info_list,
|
||||
MENU_ENUM_LABEL_SCAN_SERIAL_AND_CRC, PARSE_ONLY_BOOL,
|
||||
false) == 0)
|
||||
count++;
|
||||
}
|
||||
|
||||
/* Start scan */
|
||||
if (menu_entries_append(info_list,
|
||||
@@ -7674,7 +7755,7 @@ unsigned menu_displaylist_build_list(
|
||||
#endif
|
||||
break;
|
||||
case DISPLAYLIST_SCAN_DIRECTORY_LIST:
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
#if 0
|
||||
if (menu_entries_append(list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY),
|
||||
MENU_ENUM_LABEL_SCAN_DIRECTORY_STR,
|
||||
|
||||
@@ -25234,6 +25234,21 @@ static bool setting_append_list(
|
||||
(*list)[list_info->index - 1].ui_type = ST_UI_TYPE_STRING_LINE_EDIT;
|
||||
(*list)[list_info->index - 1].action_start = setting_generic_action_start_default;
|
||||
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
manual_content_scan_get_omit_db_ref_ptr(),
|
||||
MENU_ENUM_LABEL_SCAN_OMIT_DB_REF,
|
||||
MENU_ENUM_LABEL_VALUE_SCAN_OMIT_DB_REF,
|
||||
false,
|
||||
MENU_ENUM_LABEL_VALUE_OFF,
|
||||
MENU_ENUM_LABEL_VALUE_ON,
|
||||
&group_info,
|
||||
&subgroup_info,
|
||||
parent_group,
|
||||
general_write_handler,
|
||||
general_read_handler,
|
||||
SD_FLAG_NONE);
|
||||
|
||||
CONFIG_STRING(
|
||||
list, list_info,
|
||||
manual_content_scan_get_file_exts_custom_ptr(),
|
||||
@@ -25264,12 +25279,30 @@ static bool setting_append_list(
|
||||
general_write_handler,
|
||||
general_read_handler,
|
||||
SD_FLAG_NONE);
|
||||
(*list)[list_info->index - 1].action_ok = setting_bool_action_left_with_refresh;
|
||||
(*list)[list_info->index - 1].action_left = setting_bool_action_left_with_refresh;
|
||||
(*list)[list_info->index - 1].action_right = setting_bool_action_right_with_refresh;
|
||||
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
manual_content_scan_get_search_archives_ptr(),
|
||||
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SEARCH_ARCHIVES,
|
||||
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SEARCH_ARCHIVES,
|
||||
true,
|
||||
MENU_ENUM_LABEL_VALUE_OFF,
|
||||
MENU_ENUM_LABEL_VALUE_ON,
|
||||
&group_info,
|
||||
&subgroup_info,
|
||||
parent_group,
|
||||
general_write_handler,
|
||||
general_read_handler,
|
||||
SD_FLAG_NONE);
|
||||
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
manual_content_scan_get_scan_single_file_ptr(),
|
||||
MENU_ENUM_LABEL_SCAN_SINGLE_FILE,
|
||||
MENU_ENUM_LABEL_VALUE_SCAN_SINGLE_FILE,
|
||||
false,
|
||||
MENU_ENUM_LABEL_VALUE_OFF,
|
||||
MENU_ENUM_LABEL_VALUE_ON,
|
||||
|
||||
+119
-1
@@ -55,10 +55,13 @@ typedef struct
|
||||
char *content_dir;
|
||||
char *file_exts;
|
||||
char *dat_file_path;
|
||||
char *database_name;
|
||||
bool search_recursively;
|
||||
bool search_archives;
|
||||
bool filter_dat_content;
|
||||
bool overwrite_playlist;
|
||||
bool omit_db_ref;
|
||||
int db_usage;
|
||||
} playlist_manual_scan_record_t;
|
||||
|
||||
enum content_playlist_flags
|
||||
@@ -106,6 +109,7 @@ typedef struct
|
||||
enum playlist_thumbnail_mode *current_meta_thumbnail_mode_val;
|
||||
enum playlist_thumbnail_match_mode *current_meta_thumbnail_match_mode_val;
|
||||
enum playlist_sort_mode *current_meta_sort_mode_val;
|
||||
unsigned *current_meta_db_usage_val;
|
||||
bool *current_meta_bool_val;
|
||||
playlist_t *playlist;
|
||||
|
||||
@@ -1686,7 +1690,7 @@ void playlist_write_runtime_file(playlist_t *playlist)
|
||||
| CNT_PLAYLIST_FLG_OLD_FMT
|
||||
| CNT_PLAYLIST_FLG_COMPRESSED);
|
||||
|
||||
RARCH_LOG("[Playlist] Written to file: \"%s\".\n", playlist->config.path);
|
||||
RARCH_DBG("[Playlist] Runtime written to file: \"%s\".\n", playlist->config.path);
|
||||
end:
|
||||
intfstream_close(file);
|
||||
free(file);
|
||||
@@ -1863,6 +1867,14 @@ void playlist_write_file(playlist_t *playlist)
|
||||
rjsonwriter_add_string(writer, playlist->scan_record.dat_file_path);
|
||||
rjsonwriter_raw(writer, ",\n", 2);
|
||||
|
||||
rjsonwriter_add_spaces(writer, 2);
|
||||
rjsonwriter_add_string(writer, "scan_database_name");
|
||||
rjsonwriter_raw(writer, ":", 1);
|
||||
rjsonwriter_raw(writer, " ", 1);
|
||||
rjsonwriter_add_string(writer, playlist->scan_record.database_name);
|
||||
rjsonwriter_raw(writer, ",", 1);
|
||||
rjsonwriter_raw(writer, "\n", 1);
|
||||
|
||||
rjsonwriter_add_spaces(writer, 2);
|
||||
rjsonwriter_add_string(writer, "scan_search_recursively");
|
||||
rjsonwriter_raw(writer, ": ", 2);
|
||||
@@ -1890,6 +1902,17 @@ void playlist_write_file(playlist_t *playlist)
|
||||
}
|
||||
rjsonwriter_raw(writer, ",\n", 2);
|
||||
|
||||
rjsonwriter_add_spaces(writer, 2);
|
||||
rjsonwriter_add_string(writer, "scan_omit_db_ref");
|
||||
rjsonwriter_raw(writer, ":", 1);
|
||||
rjsonwriter_raw(writer, " ", 1);
|
||||
{
|
||||
bool value = playlist->scan_record.omit_db_ref;
|
||||
rjsonwriter_raw(writer, (value ? "true" : "false"), (value ? 4 : 5));
|
||||
}
|
||||
rjsonwriter_raw(writer, ",", 1);
|
||||
rjsonwriter_raw(writer, "\n", 1);
|
||||
|
||||
rjsonwriter_add_spaces(writer, 2);
|
||||
rjsonwriter_add_string(writer, "scan_overwrite_playlist");
|
||||
rjsonwriter_raw(writer, ": ", 2);
|
||||
@@ -1898,6 +1921,14 @@ void playlist_write_file(playlist_t *playlist)
|
||||
rjsonwriter_raw(writer, (value ? "true" : "false"), (value ? 4 : 5));
|
||||
}
|
||||
rjsonwriter_raw(writer, ",\n", 2);
|
||||
|
||||
rjsonwriter_add_spaces(writer, 2);
|
||||
rjsonwriter_add_string(writer, "scan_db_usage");
|
||||
rjsonwriter_raw(writer, ":", 1);
|
||||
rjsonwriter_raw(writer, " ", 1);
|
||||
rjsonwriter_rawf(writer, "%d", (int)playlist->scan_record.db_usage);
|
||||
rjsonwriter_raw(writer, ",", 1);
|
||||
rjsonwriter_raw(writer, "\n", 1);
|
||||
}
|
||||
|
||||
rjsonwriter_add_spaces(writer, 2);
|
||||
@@ -2095,6 +2126,10 @@ void playlist_free(playlist_t *playlist)
|
||||
free(playlist->scan_record.dat_file_path);
|
||||
playlist->scan_record.dat_file_path = NULL;
|
||||
|
||||
if (playlist->scan_record.database_name)
|
||||
free(playlist->scan_record.database_name);
|
||||
playlist->scan_record.database_name = NULL;
|
||||
|
||||
if (playlist->entries)
|
||||
{
|
||||
for (i = 0, _len = RBUF_LEN(playlist->entries); i < _len; i++)
|
||||
@@ -2337,6 +2372,8 @@ static bool JSONNumberHandler(void *context, const char *pValue, size_t len)
|
||||
*pCtx->current_meta_thumbnail_match_mode_val = (enum playlist_thumbnail_match_mode)strtoul(pValue, NULL, 10);
|
||||
else if (pCtx->current_meta_sort_mode_val)
|
||||
*pCtx->current_meta_sort_mode_val = (enum playlist_sort_mode)strtoul(pValue, NULL, 10);
|
||||
else if (pCtx->current_meta_db_usage_val)
|
||||
*pCtx->current_meta_db_usage_val = (enum playlist_sort_mode)strtoul(pValue, NULL, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2346,6 +2383,7 @@ static bool JSONNumberHandler(void *context, const char *pValue, size_t len)
|
||||
pCtx->current_meta_thumbnail_mode_val = NULL;
|
||||
pCtx->current_meta_thumbnail_match_mode_val = NULL;
|
||||
pCtx->current_meta_sort_mode_val = NULL;
|
||||
pCtx->current_meta_db_usage_val = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2450,6 +2488,7 @@ static bool JSONObjectMemberHandler(void *context, const char *pValue, size_t le
|
||||
pCtx->current_meta_thumbnail_mode_val = NULL;
|
||||
pCtx->current_meta_thumbnail_match_mode_val = NULL;
|
||||
pCtx->current_meta_sort_mode_val = NULL;
|
||||
pCtx->current_meta_db_usage_val = NULL;
|
||||
pCtx->current_meta_bool_val = NULL;
|
||||
pCtx->flags &= ~(JSON_CTX_FLG_IN_ITEMS);
|
||||
|
||||
@@ -2486,12 +2525,18 @@ static bool JSONObjectMemberHandler(void *context, const char *pValue, size_t le
|
||||
pCtx->current_string_val = &pCtx->playlist->scan_record.file_exts;
|
||||
else if (memcmp(pValue, "scan_dat_file_path", sizeof("scan_dat_file_path")) == 0)
|
||||
pCtx->current_string_val = &pCtx->playlist->scan_record.dat_file_path;
|
||||
else if (string_is_equal(pValue, "scan_database_name"))
|
||||
pCtx->current_string_val = &pCtx->playlist->scan_record.database_name;
|
||||
else if (memcmp(pValue, "scan_search_recursively", sizeof("scan_search_recursively")) == 0)
|
||||
pCtx->current_meta_bool_val = &pCtx->playlist->scan_record.search_recursively;
|
||||
else if (memcmp(pValue, "scan_search_archives", sizeof("scan_search_archives")) == 0)
|
||||
pCtx->current_meta_bool_val = &pCtx->playlist->scan_record.search_archives;
|
||||
else if (memcmp(pValue, "scan_filter_dat_content", sizeof("scan_filter_dat_content")) == 0)
|
||||
pCtx->current_meta_bool_val = &pCtx->playlist->scan_record.filter_dat_content;
|
||||
else if (string_is_equal(pValue, "scan_omit_db_ref"))
|
||||
pCtx->current_meta_bool_val = &pCtx->playlist->scan_record.omit_db_ref;
|
||||
else if (string_is_equal(pValue, "scan_db_usage"))
|
||||
pCtx->current_meta_db_usage_val = (unsigned int*)&pCtx->playlist->scan_record.db_usage;
|
||||
else if (memcmp(pValue, "scan_overwrite_playlist", sizeof("scan_overwrite_playlist")) == 0)
|
||||
pCtx->current_meta_bool_val = &pCtx->playlist->scan_record.overwrite_playlist;
|
||||
else if (memcmp(pValue, "sort_mode", sizeof("sort_mode")) == 0)
|
||||
@@ -2872,9 +2917,12 @@ playlist_t *playlist_init(const playlist_config_t *config)
|
||||
playlist->scan_record.search_recursively = false;
|
||||
playlist->scan_record.search_archives = false;
|
||||
playlist->scan_record.filter_dat_content = false;
|
||||
playlist->scan_record.omit_db_ref = false;
|
||||
playlist->scan_record.content_dir = NULL;
|
||||
playlist->scan_record.file_exts = NULL;
|
||||
playlist->scan_record.dat_file_path = NULL;
|
||||
playlist->scan_record.database_name = NULL;
|
||||
playlist->scan_record.db_usage = 4; /*MANUAL_CONTENT_SCAN_USE_DB_NONE*/
|
||||
|
||||
/* Cache configuration parameters */
|
||||
if (!playlist_config_copy(config, &playlist->config))
|
||||
@@ -3310,6 +3358,13 @@ const char *playlist_get_scan_dat_file_path(playlist_t *playlist)
|
||||
return playlist->scan_record.dat_file_path;
|
||||
}
|
||||
|
||||
const char *playlist_get_scan_database_name(playlist_t *playlist)
|
||||
{
|
||||
if (!playlist)
|
||||
return NULL;
|
||||
return playlist->scan_record.database_name;
|
||||
}
|
||||
|
||||
bool playlist_get_scan_search_recursively(playlist_t *playlist)
|
||||
{
|
||||
if (!playlist)
|
||||
@@ -3331,6 +3386,13 @@ bool playlist_get_scan_filter_dat_content(playlist_t *playlist)
|
||||
return playlist->scan_record.filter_dat_content;
|
||||
}
|
||||
|
||||
bool playlist_get_scan_omit_db_ref(playlist_t *playlist)
|
||||
{
|
||||
if (!playlist)
|
||||
return false;
|
||||
return playlist->scan_record.omit_db_ref;
|
||||
}
|
||||
|
||||
bool playlist_get_scan_overwrite_playlist(playlist_t *playlist)
|
||||
{
|
||||
if (!playlist)
|
||||
@@ -3338,6 +3400,13 @@ bool playlist_get_scan_overwrite_playlist(playlist_t *playlist)
|
||||
return playlist->scan_record.overwrite_playlist;
|
||||
}
|
||||
|
||||
int playlist_get_scan_db_usage(playlist_t *playlist)
|
||||
{
|
||||
if (!playlist)
|
||||
return 4;
|
||||
return playlist->scan_record.db_usage;
|
||||
}
|
||||
|
||||
bool playlist_scan_refresh_enabled(playlist_t *playlist)
|
||||
{
|
||||
if (!playlist)
|
||||
@@ -3534,6 +3603,37 @@ void playlist_set_scan_dat_file_path(playlist_t *playlist, const char *dat_file_
|
||||
playlist->scan_record.dat_file_path = strdup(dat_file_path);
|
||||
}
|
||||
|
||||
void playlist_set_scan_database_name(playlist_t *playlist, const char *database_name)
|
||||
{
|
||||
bool current_string_empty;
|
||||
bool new_string_empty;
|
||||
|
||||
if (!playlist)
|
||||
return;
|
||||
|
||||
current_string_empty = string_is_empty(playlist->scan_record.database_name);
|
||||
new_string_empty = string_is_empty(database_name);
|
||||
|
||||
/* Check whether string value has changed
|
||||
* (note that a NULL or empty argument will
|
||||
* unset the playlist value) */
|
||||
if ( ( current_string_empty && !new_string_empty)
|
||||
|| (!current_string_empty && new_string_empty)
|
||||
|| !string_is_equal(playlist->scan_record.database_name, database_name))
|
||||
playlist->flags |= CNT_PLAYLIST_FLG_MOD;
|
||||
else
|
||||
return; /* Strings are identical; do nothing */
|
||||
|
||||
if (playlist->scan_record.database_name)
|
||||
{
|
||||
free(playlist->scan_record.database_name);
|
||||
playlist->scan_record.database_name = NULL;
|
||||
}
|
||||
|
||||
if (!new_string_empty)
|
||||
playlist->scan_record.database_name = strdup(database_name);
|
||||
}
|
||||
|
||||
void playlist_set_scan_search_recursively(playlist_t *playlist, bool search_recursively)
|
||||
{
|
||||
if (playlist && playlist->scan_record.search_recursively != search_recursively)
|
||||
@@ -3561,6 +3661,24 @@ void playlist_set_scan_filter_dat_content(playlist_t *playlist, bool filter_dat_
|
||||
}
|
||||
}
|
||||
|
||||
void playlist_set_scan_omit_db_ref(playlist_t *playlist, bool omit_db_ref)
|
||||
{
|
||||
if (playlist && playlist->scan_record.omit_db_ref != omit_db_ref)
|
||||
{
|
||||
playlist->scan_record.omit_db_ref = omit_db_ref;
|
||||
playlist->flags |= CNT_PLAYLIST_FLG_MOD;
|
||||
}
|
||||
}
|
||||
|
||||
void playlist_set_scan_db_usage(playlist_t *playlist, int db_usage)
|
||||
{
|
||||
if (playlist && playlist->scan_record.db_usage != db_usage)
|
||||
{
|
||||
playlist->scan_record.db_usage = db_usage;
|
||||
playlist->flags |= CNT_PLAYLIST_FLG_MOD;
|
||||
}
|
||||
}
|
||||
|
||||
void playlist_set_scan_overwrite_playlist(playlist_t *playlist, bool overwrite_playlist)
|
||||
{
|
||||
if (playlist && playlist->scan_record.overwrite_playlist != overwrite_playlist)
|
||||
|
||||
@@ -385,10 +385,13 @@ enum playlist_sort_mode playlist_get_sort_mode(playlist_t *playlist);
|
||||
const char *playlist_get_scan_content_dir(playlist_t *playlist);
|
||||
const char *playlist_get_scan_file_exts(playlist_t *playlist);
|
||||
const char *playlist_get_scan_dat_file_path(playlist_t *playlist);
|
||||
const char *playlist_get_scan_database_name(playlist_t *playlist);
|
||||
bool playlist_get_scan_search_recursively(playlist_t *playlist);
|
||||
bool playlist_get_scan_search_archives(playlist_t *playlist);
|
||||
bool playlist_get_scan_filter_dat_content(playlist_t *playlist);
|
||||
bool playlist_get_scan_omit_db_ref(playlist_t *playlist);
|
||||
bool playlist_get_scan_overwrite_playlist(playlist_t *playlist);
|
||||
int playlist_get_scan_db_usage(playlist_t *playlist);
|
||||
bool playlist_scan_refresh_enabled(playlist_t *playlist);
|
||||
|
||||
void playlist_set_default_core_path(playlist_t *playlist, const char *core_path);
|
||||
@@ -400,10 +403,13 @@ void playlist_set_sort_mode(playlist_t *playlist, enum playlist_sort_mode sort_m
|
||||
void playlist_set_scan_content_dir(playlist_t *playlist, const char *content_dir);
|
||||
void playlist_set_scan_file_exts(playlist_t *playlist, const char *file_exts);
|
||||
void playlist_set_scan_dat_file_path(playlist_t *playlist, const char *dat_file_path);
|
||||
void playlist_set_scan_database_name(playlist_t *playlist, const char *database_name);
|
||||
void playlist_set_scan_search_recursively(playlist_t *playlist, bool search_recursively);
|
||||
void playlist_set_scan_search_archives(playlist_t *playlist, bool search_archives);
|
||||
void playlist_set_scan_filter_dat_content(playlist_t *playlist, bool filter_dat_content);
|
||||
void playlist_set_scan_omit_db_ref(playlist_t *playlist, bool omit_db_ref);
|
||||
void playlist_set_scan_overwrite_playlist(playlist_t *playlist, bool overwrite_playlist);
|
||||
void playlist_set_scan_db_usage(playlist_t *playlist, int db_usage);
|
||||
|
||||
/* Returns true if specified entry has a valid
|
||||
* core association (i.e. a non-empty string
|
||||
|
||||
+683
-533
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user