Dialog: Add filter number, remove NULL termination

This commit is contained in:
Semphris 2024-05-22 19:20:40 -04:00 committed by Sam Lantinga
parent 3e70964ae2
commit 8c8ee2174d
17 changed files with 144 additions and 147 deletions

View File

@ -78,10 +78,9 @@ typedef struct SDL_DialogFileFilter
* The filelist argument does not need to be freed; it will automatically be
* freed when the callback returns.
*
* The filter argument is the index of the filter that was selected, or one
* more than the size of the list (therefore the index of the terminating NULL
* entry) if no filter was selected, or -1 if the platform or method doesn't
* support fetching the selected filter.
* The filter argument is the index of the filter that was selected, or -1 if
* no filter was selected or if the platform or method doesn't support fetching
* the selected filter.
*
* \param userdata An app-provided pointer, for the callback's use.
* \param filelist The file(s) chosen by the user.
@ -135,9 +134,10 @@ typedef void(SDLCALL *SDL_DialogFileCallback)(void *userdata, const char * const
* it will be invoked.
* \param window The window that the dialog should be modal for. May be NULL.
* Not all platforms support this option.
* \param filters A null-terminated list of SDL_DialogFileFilter's. May be
* NULL. Not all platforms support this option, and platforms
* that do support it may allow the user to ignore the filters.
* \param filters A list of SDL_DialogFileFilter's. May be NULL. Not all
* platforms support this option, and platforms that do support
* it may allow the user to ignore the filters.
* \param nfilters The number of filters. Ignored if filters is NULL.
* \param default_location The default folder or file to start the dialog at.
* May be NULL. Not all platforms support this option.
* \param allow_many If non-zero, the user will be allowed to select multiple
@ -150,7 +150,7 @@ typedef void(SDLCALL *SDL_DialogFileCallback)(void *userdata, const char * const
* \sa SDL_ShowSaveFileDialog
* \sa SDL_ShowOpenFolderDialog
*/
extern SDL_DECLSPEC void SDLCALL SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, const char *default_location, SDL_bool allow_many);
extern SDL_DECLSPEC void SDLCALL SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, int nfilters, const char *default_location, SDL_bool allow_many);
/**
* Displays a dialog that lets the user choose a new or existing file on their
@ -191,9 +191,10 @@ extern SDL_DECLSPEC void SDLCALL SDL_ShowOpenFileDialog(SDL_DialogFileCallback c
* it will be invoked.
* \param window The window that the dialog should be modal for. May be NULL.
* Not all platforms support this option.
* \param filters A null-terminated list of SDL_DialogFileFilter's. May be
* NULL. Not all platforms support this option, and platforms
* that do support it may allow the user to ignore the filters.
* \param filters A list of SDL_DialogFileFilter's. May be NULL. Not all
* platforms support this option, and platforms that do support
* it may allow the user to ignore the filters.
* \param nfilters The number of filters. Ignored if filters is NULL.
* \param default_location The default folder or file to start the dialog at.
* May be NULL. Not all platforms support this option.
*
@ -204,7 +205,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_ShowOpenFileDialog(SDL_DialogFileCallback c
* \sa SDL_ShowOpenFileDialog
* \sa SDL_ShowOpenFolderDialog
*/
extern SDL_DECLSPEC void SDLCALL SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, const char *default_location);
extern SDL_DECLSPEC void SDLCALL SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, int nfilters, const char *default_location);
/**
* Displays a dialog that lets the user select a folder on their filesystem.

View File

@ -2910,7 +2910,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeFileDialog)(
SDL_bool Android_JNI_OpenFileDialog(
SDL_DialogFileCallback callback, void* userdata,
const SDL_DialogFileFilter *filters, SDL_bool forwrite, SDL_bool multiple)
const SDL_DialogFileFilter *filters, int nfilters, SDL_bool forwrite,
SDL_bool multiple)
{
if (mAndroidFileDialogData.callback != NULL) {
SDL_SetError("Only one file dialog can be run at a time.");
@ -2926,17 +2927,11 @@ SDL_bool Android_JNI_OpenFileDialog(
/* Setup filters */
jobjectArray filtersArray = NULL;
if (filters) {
/* Count how many filters */
int count = 0;
for (const SDL_DialogFileFilter *f = filters; f->name != NULL && f->pattern != NULL; f++) {
count++;
}
jclass stringClass = (*env)->FindClass(env, "java/lang/String");
filtersArray = (*env)->NewObjectArray(env, count, stringClass, NULL);
filtersArray = (*env)->NewObjectArray(env, nfilters, stringClass, NULL);
/* Convert to string */
for (int i = 0; i < count; i++) {
for (int i = 0; i < nfilters; i++) {
jstring str = (*env)->NewStringUTF(env, filters[i].pattern);
(*env)->SetObjectArrayElement(env, filtersArray, i, str);
(*env)->DeleteLocalRef(env, str);

View File

@ -144,7 +144,8 @@ void Android_ActivityMutex_Lock_Running(void);
/* File Dialogs */
SDL_bool Android_JNI_OpenFileDialog(SDL_DialogFileCallback callback, void* userdata,
const SDL_DialogFileFilter *filters, SDL_bool forwrite, SDL_bool multiple);
const SDL_DialogFileFilter *filters, int nfilters, SDL_bool forwrite,
SDL_bool multiple);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus

View File

@ -22,18 +22,24 @@
#include "SDL_dialog_utils.h"
char *convert_filters(const SDL_DialogFileFilter *filters, NameTransform ntf,
const char *prefix, const char *separator,
const char *suffix, const char *filt_prefix,
const char *filt_separator, const char *filt_suffix,
const char *ext_prefix, const char *ext_separator,
const char *ext_suffix)
char *convert_filters(const SDL_DialogFileFilter *filters, int nfilters,
NameTransform ntf, const char *prefix,
const char *separator, const char *suffix,
const char *filt_prefix, const char *filt_separator,
const char *filt_suffix, const char *ext_prefix,
const char *ext_separator, const char *ext_suffix)
{
char *combined;
char *new_combined;
char *converted;
const char *terminator;
size_t new_length;
int i;
if (!filters) {
SDL_SetError("Called convert_filters() with NULL filters (SDL bug)");
return NULL;
}
combined = SDL_strdup(prefix);
@ -41,7 +47,9 @@ char *convert_filters(const SDL_DialogFileFilter *filters, NameTransform ntf,
return NULL;
}
for (const SDL_DialogFileFilter *f = filters; f->name && f->pattern; f++) {
for (i = 0; i < nfilters; i++) {
const SDL_DialogFileFilter *f = &filters[i];
converted = convert_filter(*f, ntf, filt_prefix, filt_separator,
filt_suffix, ext_prefix, ext_separator,
ext_suffix);
@ -90,9 +98,9 @@ char *convert_filters(const SDL_DialogFileFilter *filters, NameTransform ntf,
}
char *convert_filter(const SDL_DialogFileFilter filter, NameTransform ntf,
const char *prefix, const char *separator,
const char *suffix, const char *ext_prefix,
const char *ext_separator, const char *ext_suffix)
const char *prefix, const char *separator,
const char *suffix, const char *ext_prefix,
const char *ext_separator, const char *ext_suffix)
{
char *converted;
char *name_filtered;
@ -208,11 +216,11 @@ char *convert_ext_list(const char *list, const char *prefix,
return converted;
}
const char *validate_filters(const SDL_DialogFileFilter *filters)
const char *validate_filters(const SDL_DialogFileFilter *filters, int nfilters)
{
if (filters) {
for (const SDL_DialogFileFilter *f = filters; f->name && f->pattern; f++) {
const char *msg = validate_list(f->pattern);
for (int i = 0; i < nfilters; i++) {
const char *msg = validate_list(filters[i].pattern);
if (msg) {
return msg;

View File

@ -32,19 +32,19 @@ typedef char *(NameTransform)(const char * name);
/* Converts all the filters into a single string. */
/* <prefix>[filter]{<separator>[filter]...}<suffix> */
char *convert_filters(const SDL_DialogFileFilter *filters, NameTransform ntf,
const char *prefix, const char *separator,
const char *suffix, const char *filt_prefix,
const char *filt_separator, const char *filt_suffix,
const char *ext_prefix, const char *ext_separator,
const char *ext_suffix);
char *convert_filters(const SDL_DialogFileFilter *filters, int nfilters,
NameTransform ntf, const char *prefix,
const char *separator, const char *suffix,
const char *filt_prefix, const char *filt_separator,
const char *filt_suffix, const char *ext_prefix,
const char *ext_separator, const char *ext_suffix);
/* Converts one filter into a single string. */
/* <prefix>[filter name]<separator>[filter extension list]<suffix> */
char *convert_filter(const SDL_DialogFileFilter filter, NameTransform ntf,
const char *prefix, const char *separator,
const char *suffix, const char *ext_prefix,
const char *ext_separator, const char *ext_suffix);
const char *prefix, const char *separator,
const char *suffix, const char *ext_prefix,
const char *ext_separator, const char *ext_suffix);
/* Converts the extenstion list of a filter into a single string. */
/* <prefix>[extension]{<separator>[extension]...}<suffix> */
@ -53,5 +53,7 @@ char *convert_ext_list(const char *list, const char *prefix,
/* Must be used if convert_* functions aren't used */
/* Returns an error message if there's a problem, NULL otherwise */
const char *validate_filters(const SDL_DialogFileFilter *filters);
const char *validate_filters(const SDL_DialogFileFilter *filters,
int nfilters);
const char *validate_list(const char *list);

View File

@ -22,17 +22,17 @@
#include "SDL_internal.h"
#include "../../core/android/SDL_android.h"
void SDLCALL SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, const char *default_location, SDL_bool allow_many)
void SDLCALL SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, int nfilters, const char *default_location, SDL_bool allow_many)
{
if (!Android_JNI_OpenFileDialog(callback, userdata, filters, SDL_FALSE, allow_many)) {
if (!Android_JNI_OpenFileDialog(callback, userdata, filters, nfilters, SDL_FALSE, allow_many)) {
/* SDL_SetError is already called when it fails */
callback(userdata, NULL, -1);
}
}
void SDLCALL SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, const char *default_location)
void SDLCALL SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, int nfilters, const char *default_location)
{
if (!Android_JNI_OpenFileDialog(callback, userdata, filters, SDL_TRUE, SDL_FALSE)) {
if (!Android_JNI_OpenFileDialog(callback, userdata, filters, nfilters, SDL_TRUE, SDL_FALSE)) {
/* SDL_SetError is already called when it fails */
callback(userdata, NULL, -1);
}

View File

@ -31,14 +31,14 @@ typedef enum
FDT_OPENFOLDER
} cocoa_FileDialogType;
void show_file_dialog(cocoa_FileDialogType type, SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many)
void show_file_dialog(cocoa_FileDialogType type, SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many)
{
#if defined(SDL_PLATFORM_TVOS) || defined(SDL_PLATFORM_IOS)
SDL_SetError("tvOS and iOS don't support path-based file dialogs");
callback(userdata, NULL, -1);
#else
if (filters) {
const char *msg = validate_filters(filters);
const char *msg = validate_filters(filters, nfilters);
if (msg) {
SDL_SetError("%s", msg);
@ -76,13 +76,11 @@ void show_file_dialog(cocoa_FileDialogType type, SDL_DialogFileCallback callback
};
if (filters) {
int n = -1;
while (filters[++n].name && filters[n].pattern);
// On macOS 11.0 and up, this is an array of UTType. Prior to that, it's an array of NSString
NSMutableArray *types = [[NSMutableArray alloc] initWithCapacity:n ];
NSMutableArray *types = [[NSMutableArray alloc] initWithCapacity:nfilters ];
int has_all_files = 0;
for (int i = 0; i < n; i++) {
for (int i = 0; i < nfilters; i++) {
char *pattern = SDL_strdup(filters[i].pattern);
char *pattern_ptr = pattern;
@ -180,17 +178,17 @@ void show_file_dialog(cocoa_FileDialogType type, SDL_DialogFileCallback callback
#endif // defined(SDL_PLATFORM_TVOS) || defined(SDL_PLATFORM_IOS)
}
void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many)
void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many)
{
show_file_dialog(FDT_OPEN, callback, userdata, window, filters, default_location, allow_many);
show_file_dialog(FDT_OPEN, callback, userdata, window, filters, nfilters, default_location, allow_many);
}
void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location)
void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location)
{
show_file_dialog(FDT_SAVE, callback, userdata, window, filters, default_location, 0);
show_file_dialog(FDT_SAVE, callback, userdata, window, filters, nfilters, default_location, 0);
}
void SDL_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many)
{
show_file_dialog(FDT_OPENFOLDER, callback, userdata, window, NULL, default_location, allow_many);
show_file_dialog(FDT_OPENFOLDER, callback, userdata, window, NULL, 0, default_location, allow_many);
}

View File

@ -20,13 +20,13 @@
*/
#include "SDL_internal.h"
void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many)
void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many)
{
SDL_Unsupported();
callback(userdata, NULL, -1);
}
void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location)
void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location)
{
SDL_Unsupported();
callback(userdata, NULL, -1);

View File

@ -60,9 +60,10 @@ std::vector<std::string> StringSplit(const std::string& str, const std::string&
class SDLBRefFilter : public BRefFilter
{
public:
SDLBRefFilter(const SDL_DialogFileFilter *filters) :
SDLBRefFilter(const SDL_DialogFileFilter *filters, int nfilters) :
BRefFilter(),
m_filters(filters)
m_filters(filters),
m_nfilters(nfilters)
{
}
@ -81,14 +82,12 @@ public:
if (S_ISDIR(info.st_mode))
return true;
const auto *filter = m_filters;
while (filter->name && filter->pattern) {
for (const auto& suffix : StringSplit(filter->pattern, ";")) {
for (int i = 0; i < m_nfilters; i++) {
for (const auto& suffix : StringSplit(m_filters[i].pattern, ";")) {
if (StringEndsWith(result, std::string(".") + suffix)) {
return true;
}
}
filter++;
}
return false;
@ -96,6 +95,7 @@ public:
private:
const SDL_DialogFileFilter * const m_filters;
int m_nfilters;
};
class CallbackLooper : public BLooper
@ -190,7 +190,7 @@ private:
SDLBRefFilter *m_filter;
};
void ShowDialog(bool save, SDL_DialogFileCallback callback, void *userdata, bool many, bool modal, const SDL_DialogFileFilter *filters, bool folder, const char *location)
void ShowDialog(bool save, SDL_DialogFileCallback callback, void *userdata, bool many, bool modal, const SDL_DialogFileFilter *filters, int nfilters, bool folder, const char *location)
{
if (SDL_InitBeApp()) {
char* err = SDL_strdup(SDL_GetError());
@ -200,12 +200,14 @@ void ShowDialog(bool save, SDL_DialogFileCallback callback, void *userdata, bool
return;
}
const char *msg = validate_filters(filters);
if (filters) {
const char *msg = validate_filters(filters, nfilters);
if (msg) {
SDL_SetError("%s", msg);
callback(userdata, NULL, -1);
return;
if (msg) {
SDL_SetError("%s", msg);
callback(userdata, NULL, -1);
return;
}
}
if (SDL_GetHint(SDL_HINT_FILE_DIALOG_DRIVER) != NULL) {
@ -217,7 +219,7 @@ void ShowDialog(bool save, SDL_DialogFileCallback callback, void *userdata, bool
// No unique_ptr's because they need to survive the end of the function
CallbackLooper *looper = new(std::nothrow) CallbackLooper(callback, userdata);
BMessenger *messenger = new(std::nothrow) BMessenger(NULL, looper);
SDLBRefFilter *filter = new(std::nothrow) SDLBRefFilter(filters);
SDLBRefFilter *filter = new(std::nothrow) SDLBRefFilter(filters, nfilters);
if (looper == NULL || messenger == NULL || filter == NULL) {
SDL_free(looper);
@ -241,19 +243,17 @@ void ShowDialog(bool save, SDL_DialogFileCallback callback, void *userdata, bool
panel->Show();
}
void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, const char *default_location, SDL_bool allow_many)
void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, int nfilters, const char *default_location, SDL_bool allow_many)
{
ShowDialog(false, callback, userdata, allow_many == SDL_TRUE, !!window, filters, false, default_location);
ShowDialog(false, callback, userdata, allow_many == SDL_TRUE, !!window, filters, nfilters, false, default_location);
}
void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, const char *default_location)
void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, int nfilters, const char *default_location)
{
ShowDialog(true, callback, userdata, false, !!window, filters, false, default_location);
ShowDialog(true, callback, userdata, false, !!window, filters, nfilters, false, default_location);
}
void SDL_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const char* default_location, SDL_bool allow_many)
{
// Use a dummy filter to avoid showing files in the dialog
SDL_DialogFileFilter filter[] = {{}};
ShowDialog(false, callback, userdata, allow_many == SDL_TRUE, !!window, filter, true, default_location);
ShowDialog(false, callback, userdata, allow_many == SDL_TRUE, !!window, NULL, 0, true, default_location);
}

View File

@ -74,17 +74,17 @@ static void DBus_AppendBoolOption(SDL_DBusContext *dbus, DBusMessageIter *option
dbus->message_iter_close_container(options, &options_pair);
}
static void DBus_AppendFilter(SDL_DBusContext *dbus, DBusMessageIter *parent, const SDL_DialogFileFilter *filter)
static void DBus_AppendFilter(SDL_DBusContext *dbus, DBusMessageIter *parent, const SDL_DialogFileFilter filter)
{
DBusMessageIter filter_entry, filter_array, filter_array_entry;
char *state = NULL, *patterns, *pattern, *glob_pattern;
int zero = 0;
dbus->message_iter_open_container(parent, DBUS_TYPE_STRUCT, NULL, &filter_entry);
dbus->message_iter_append_basic(&filter_entry, DBUS_TYPE_STRING, &filter->name);
dbus->message_iter_append_basic(&filter_entry, DBUS_TYPE_STRING, &filter.name);
dbus->message_iter_open_container(&filter_entry, DBUS_TYPE_ARRAY, "(us)", &filter_array);
patterns = SDL_strdup(filter->pattern);
patterns = SDL_strdup(filter.pattern);
if (!patterns) {
goto cleanup;
}
@ -120,7 +120,7 @@ cleanup:
dbus->message_iter_close_container(parent, &filter_entry);
}
static void DBus_AppendFilters(SDL_DBusContext *dbus, DBusMessageIter *options, const SDL_DialogFileFilter *filters)
static void DBus_AppendFilters(SDL_DBusContext *dbus, DBusMessageIter *options, const SDL_DialogFileFilter *filters, int nfilters)
{
DBusMessageIter options_pair, options_value, options_value_array;
static const char *filters_name = "filters";
@ -129,8 +129,8 @@ static void DBus_AppendFilters(SDL_DBusContext *dbus, DBusMessageIter *options,
dbus->message_iter_append_basic(&options_pair, DBUS_TYPE_STRING, &filters_name);
dbus->message_iter_open_container(&options_pair, DBUS_TYPE_VARIANT, "a(sa(us))", &options_value);
dbus->message_iter_open_container(&options_value, DBUS_TYPE_ARRAY, "(sa(us))", &options_value_array);
for (const SDL_DialogFileFilter *filter = filters; filter && filter->name && filter->pattern; ++filter) {
DBus_AppendFilter(dbus, &options_value_array, filter);
for (int i = 0; i < nfilters; i++) {
DBus_AppendFilter(dbus, &options_value_array, filters[i]);
}
dbus->message_iter_close_container(&options_value, &options_value_array);
dbus->message_iter_close_container(&options_pair, &options_value);
@ -269,7 +269,7 @@ not_our_signal:
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
static void DBus_OpenDialog(const char *method, const char *method_title, SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many, int open_folders)
static void DBus_OpenDialog(const char *method, const char *method_title, SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many, int open_folders)
{
SDL_DBusContext *dbus = SDL_DBus_GetContext();
DBusMessage *msg;
@ -281,7 +281,7 @@ static void DBus_OpenDialog(const char *method, const char *method_title, SDL_Di
static char *default_parent_window = "";
SDL_PropertiesID props = SDL_GetWindowProperties(window);
const char *err_msg = validate_filters(filters);
const char *err_msg = validate_filters(filters, nfilters);
if (err_msg) {
SDL_SetError("%s", err_msg);
@ -358,7 +358,7 @@ static void DBus_OpenDialog(const char *method, const char *method_title, SDL_Di
DBus_AppendBoolOption(dbus, &options, "directory", 1);
}
if (filters) {
DBus_AppendFilters(dbus, &options, filters);
DBus_AppendFilters(dbus, &options, filters, nfilters);
}
if (default_location) {
DBus_AppendByteArray(dbus, &options, "current_folder", default_location);
@ -419,19 +419,19 @@ incorrect_type:
dbus->message_unref(reply);
}
void SDL_Portal_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many)
void SDL_Portal_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many)
{
DBus_OpenDialog("OpenFile", "Open File", callback, userdata, window, filters, default_location, allow_many, 0);
DBus_OpenDialog("OpenFile", "Open File", callback, userdata, window, filters, nfilters, default_location, allow_many, 0);
}
void SDL_Portal_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location)
void SDL_Portal_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location)
{
DBus_OpenDialog("SaveFile", "Save File", callback, userdata, window, filters, default_location, 0, 0);
DBus_OpenDialog("SaveFile", "Save File", callback, userdata, window, filters, nfilters, default_location, 0, 0);
}
void SDL_Portal_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many)
{
DBus_OpenDialog("OpenFile", "Open Folder", callback, userdata, window, NULL, default_location, allow_many, 1);
DBus_OpenDialog("OpenFile", "Open Folder", callback, userdata, window, NULL, 0, default_location, allow_many, 1);
}
int SDL_Portal_detect(void)
@ -494,13 +494,13 @@ done:
/* Dummy implementation to avoid compilation problems */
void SDL_Portal_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many)
void SDL_Portal_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many)
{
SDL_Unsupported();
callback(userdata, NULL, -1);
}
void SDL_Portal_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location)
void SDL_Portal_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location)
{
SDL_Unsupported();
callback(userdata, NULL, -1);

View File

@ -21,8 +21,8 @@
#include "SDL_internal.h"
void SDL_Portal_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many);
void SDL_Portal_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location);
void SDL_Portal_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many);
void SDL_Portal_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location);
void SDL_Portal_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many);
/** @returns non-zero if available, zero if unavailable */

View File

@ -23,8 +23,8 @@
#include "./SDL_portaldialog.h"
#include "./SDL_zenitydialog.h"
static void (*detected_open)(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many) = NULL;
static void (*detected_save)(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location) = NULL;
static void (*detected_open)(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many) = NULL;
static void (*detected_save)(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location) = NULL;
static void (*detected_folder)(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many) = NULL;
static int detect_available_methods(const char *value);
@ -73,7 +73,7 @@ static int detect_available_methods(const char *value)
return 0;
}
void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many)
void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many)
{
/* Call detect_available_methods() again each time in case the situation changed */
if (!detected_open && !detect_available_methods(NULL)) {
@ -82,10 +82,10 @@ void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL
return;
}
detected_open(callback, userdata, window, filters, default_location, allow_many);
detected_open(callback, userdata, window, filters, nfilters, default_location, allow_many);
}
void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location)
void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location)
{
/* Call detect_available_methods() again each time in case the situation changed */
if (!detected_save && !detect_available_methods(NULL)) {
@ -94,7 +94,7 @@ void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL
return;
}
detected_save(callback, userdata, window, filters, default_location);
detected_save(callback, userdata, window, filters, nfilters, default_location);
}
void SDL_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many)

View File

@ -39,6 +39,7 @@ typedef struct
void* userdata;
const char* filename;
const SDL_DialogFileFilter *filters;
int nfilters;
Uint32 flags;
} zenityArgs;
@ -110,12 +111,7 @@ static char** generate_args(const zenityArgs* info)
}
if (info->filters) {
const SDL_DialogFileFilter *filter_ptr = info->filters;
while (filter_ptr->name && filter_ptr->pattern) {
argc++;
filter_ptr++;
}
argc += info->nfilters;
}
argv = SDL_malloc(sizeof(char *) * argc + 1);
@ -157,10 +153,9 @@ static char** generate_args(const zenityArgs* info)
}
if (info->filters) {
const SDL_DialogFileFilter *filter_ptr = info->filters;
while (filter_ptr->name && filter_ptr->pattern) {
char *filter_str = convert_filter(*filter_ptr, zenity_clean_name,
for (int i = 0; i < info->nfilters; i++) {
char *filter_str = convert_filter(info->filters[i],
zenity_clean_name,
"--file-filter=", " | ", "",
"*.", " *.", "");
@ -170,8 +165,6 @@ static char** generate_args(const zenityArgs* info)
argv[nextarg++] = filter_str;
CHECK_OOM()
filter_ptr++;
}
}
@ -330,7 +323,7 @@ static int run_zenity_thread(void* ptr)
return 0;
}
void SDL_Zenity_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many)
void SDL_Zenity_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many)
{
zenityArgs *args;
SDL_Thread *thread;
@ -345,6 +338,7 @@ void SDL_Zenity_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userda
args->userdata = userdata;
args->filename = default_location;
args->filters = filters;
args->nfilters = nfilters;
args->flags = (allow_many == SDL_TRUE) ? ZENITY_MULTIPLE : 0;
thread = SDL_CreateThread(run_zenity_thread, "SDL_ShowOpenFileDialog", (void *) args);
@ -357,7 +351,7 @@ void SDL_Zenity_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userda
SDL_DetachThread(thread);
}
void SDL_Zenity_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location)
void SDL_Zenity_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location)
{
zenityArgs *args;
SDL_Thread *thread;
@ -372,6 +366,7 @@ void SDL_Zenity_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userda
args->userdata = userdata;
args->filename = default_location;
args->filters = filters;
args->nfilters = nfilters;
args->flags = ZENITY_SAVE;
thread = SDL_CreateThread(run_zenity_thread, "SDL_ShowSaveFileDialog", (void *) args);
@ -399,6 +394,7 @@ void SDL_Zenity_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* user
args->userdata = userdata;
args->filename = default_location;
args->filters = NULL;
args->nfilters = 0;
args->flags = ((allow_many == SDL_TRUE) ? ZENITY_MULTIPLE : 0) | ZENITY_DIRECTORY;
thread = SDL_CreateThread(run_zenity_thread, "SDL_ShowOpenFolderDialog", (void *) args);

View File

@ -21,8 +21,8 @@
#include "SDL_internal.h"
void SDL_Zenity_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many);
void SDL_Zenity_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location);
void SDL_Zenity_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many);
void SDL_Zenity_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location);
void SDL_Zenity_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many);
/** @returns non-zero if available, zero if unavailable */

View File

@ -34,6 +34,7 @@ typedef struct
{
int is_save;
const SDL_DialogFileFilter *filters;
int nfilters;
const char* default_file;
SDL_Window* parent;
DWORD flags;
@ -50,18 +51,9 @@ typedef struct
} winFArgs;
/** Converts dialog.nFilterIndex to SDL-compatible value */
int getFilterIndex(int as_reported_by_windows, const SDL_DialogFileFilter *filters)
int getFilterIndex(int as_reported_by_windows)
{
int filter_index = as_reported_by_windows - 1;
if (filter_index < 0) {
filter_index = 0;
for (const SDL_DialogFileFilter *filter = filters; filter && filter->name && filter->pattern; filter++) {
filter_index++;
}
}
return filter_index;
return as_reported_by_windows - 1;
}
/* TODO: The new version of file dialogs */
@ -70,6 +62,7 @@ void windows_ShowFileDialog(void *ptr)
winArgs *args = (winArgs *) ptr;
int is_save = args->is_save;
const SDL_DialogFileFilter *filters = args->filters;
int nfilters = args->nfilters;
const char* default_file = args->default_file;
SDL_Window* parent = args->parent;
DWORD flags = args->flags;
@ -160,8 +153,9 @@ void windows_ShowFileDialog(void *ptr)
if (filters) {
/* '\x01' is used in place of a null byte */
/* suffix needs two null bytes in case the filter list is empty */
char *filterlist = convert_filters(filters, NULL, "", "", "\x01\x01", "",
"\x01", "\x01", "*.", ";*.", "");
char *filterlist = convert_filters(filters, nfilters, NULL, "", "",
"\x01\x01", "", "\x01", "\x01",
"*.", ";*.", "");
if (!filterlist) {
callback(userdata, NULL, -1);
@ -224,7 +218,7 @@ void windows_ShowFileDialog(void *ptr)
/* File is a C string stored in dialog.lpstrFile */
char *chosen_file = WIN_StringToUTF8W(dialog.lpstrFile);
const char* opts[2] = { chosen_file, NULL };
callback(userdata, opts, getFilterIndex(dialog.nFilterIndex, filters));
callback(userdata, opts, getFilterIndex(dialog.nFilterIndex));
SDL_free(chosen_file);
} else {
/* File is either a C string if the user chose a single file, else
@ -336,7 +330,7 @@ void windows_ShowFileDialog(void *ptr)
}
}
callback(userdata, (const char * const*) chosen_files_list, getFilterIndex(dialog.nFilterIndex, filters));
callback(userdata, (const char * const*) chosen_files_list, getFilterIndex(dialog.nFilterIndex));
for (size_t i = 0; i < nfiles; i++) {
SDL_free(chosen_files_list[i]);
@ -353,7 +347,7 @@ void windows_ShowFileDialog(void *ptr)
function before set a different error code, so it's safe to
check for success. */
const char* opts[1] = { NULL };
callback(userdata, opts, getFilterIndex(dialog.nFilterIndex, filters));
callback(userdata, opts, getFilterIndex(dialog.nFilterIndex));
} else {
SDL_SetError("Windows error, CommDlgExtendedError: %ld", pCommDlgExtendedError());
callback(userdata, NULL, -1);
@ -433,7 +427,7 @@ int windows_folder_dialog_thread(void* ptr)
return 0;
}
void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many)
void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many)
{
winArgs *args;
SDL_Thread *thread;
@ -453,6 +447,7 @@ void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL
args->is_save = 0;
args->filters = filters;
args->nfilters = nfilters;
args->default_file = default_location;
args->parent = window;
args->flags = (allow_many == SDL_TRUE) ? OFN_ALLOWMULTISELECT : 0;
@ -470,7 +465,7 @@ void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL
SDL_DetachThread(thread);
}
void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location)
void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location)
{
winArgs *args;
SDL_Thread *thread;
@ -489,6 +484,7 @@ void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL
args->is_save = 1;
args->filters = filters;
args->nfilters = nfilters;
args->default_file = default_location;
args->parent = window;
args->flags = 0;

View File

@ -810,9 +810,9 @@ SDL_DYNAPI_PROC(void,SDL_SetWindowsMessageHook,(SDL_WindowsMessageHook a, void *
SDL_DYNAPI_PROC(void,SDL_SetX11EventHook,(SDL_X11EventHook a, void *b),(a,b),)
SDL_DYNAPI_PROC(int,SDL_ShowCursor,(void),(),return)
SDL_DYNAPI_PROC(int,SDL_ShowMessageBox,(const SDL_MessageBoxData *a, int *b),(a,b),return)
SDL_DYNAPI_PROC(void,SDL_ShowOpenFileDialog,(SDL_DialogFileCallback a, void *b, SDL_Window *c, const SDL_DialogFileFilter *d, const char *e, SDL_bool f),(a,b,c,d,e,f),)
SDL_DYNAPI_PROC(void,SDL_ShowOpenFileDialog,(SDL_DialogFileCallback a, void *b, SDL_Window *c, const SDL_DialogFileFilter *d, int e, const char *f, SDL_bool g),(a,b,c,d,e,f,g),)
SDL_DYNAPI_PROC(void,SDL_ShowOpenFolderDialog,(SDL_DialogFileCallback a, void *b, SDL_Window *c, const char *d, SDL_bool e),(a,b,c,d,e),)
SDL_DYNAPI_PROC(void,SDL_ShowSaveFileDialog,(SDL_DialogFileCallback a, void *b, SDL_Window *c, const SDL_DialogFileFilter *d, const char *e),(a,b,c,d,e),)
SDL_DYNAPI_PROC(void,SDL_ShowSaveFileDialog,(SDL_DialogFileCallback a, void *b, SDL_Window *c, const SDL_DialogFileFilter *d, int e, const char *f),(a,b,c,d,e,f),)
SDL_DYNAPI_PROC(int,SDL_ShowSimpleMessageBox,(SDL_MessageBoxFlags a, const char *b, const char *c, SDL_Window *d),(a,b,c,d),return)
SDL_DYNAPI_PROC(int,SDL_ShowWindow,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_ShowWindowSystemMenu,(SDL_Window *a, int b, int c),(a,b,c),return)

View File

@ -15,11 +15,10 @@
#include <SDL3/SDL_main.h>
#include <SDL3/SDL_test.h>
const SDL_DialogFileFilter filters[4] = {
const SDL_DialogFileFilter filters[3] = {
{ "All files", "*" },
{ "JPG images", "jpg;jpeg" },
{ "PNG images", "png" },
{ NULL, NULL }
{ "PNG images", "png" }
};
static void SDLCALL callback(void* userdata, const char* const* files, int filter) {
@ -54,6 +53,7 @@ int main(int argc, char *argv[]) {
const SDL_FRect open_folder_rect = { 370, 50, 220, 140 };
int i;
char *initial_path = NULL;
const int nfilters = sizeof(filters) / sizeof(*filters);
/* Initialize test framework */
state = SDLTest_CommonCreateState(argv, 0);
@ -114,11 +114,11 @@ int main(int argc, char *argv[]) {
* - Nonzero if the user is allowed to choose multiple entries (not for SDL_ShowSaveFileDialog)
*/
if (SDL_PointInRectFloat(&p, &open_file_rect)) {
SDL_ShowOpenFileDialog(callback, NULL, w, filters, initial_path, 1);
SDL_ShowOpenFileDialog(callback, NULL, w, filters, nfilters, initial_path, 1);
} else if (SDL_PointInRectFloat(&p, &open_folder_rect)) {
SDL_ShowOpenFolderDialog(callback, NULL, w, initial_path, 1);
} else if (SDL_PointInRectFloat(&p, &save_file_rect)) {
SDL_ShowSaveFileDialog(callback, NULL, w, filters, initial_path);
SDL_ShowSaveFileDialog(callback, NULL, w, filters, nfilters, initial_path);
}
}
}