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 * The filelist argument does not need to be freed; it will automatically be
* freed when the callback returns. * freed when the callback returns.
* *
* The filter argument is the index of the filter that was selected, or one * The filter argument is the index of the filter that was selected, or -1 if
* more than the size of the list (therefore the index of the terminating NULL * no filter was selected or if the platform or method doesn't support fetching
* entry) if no filter was selected, or -1 if the platform or method doesn't * the selected filter.
* support fetching the selected filter.
* *
* \param userdata An app-provided pointer, for the callback's use. * \param userdata An app-provided pointer, for the callback's use.
* \param filelist The file(s) chosen by the user. * \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. * it will be invoked.
* \param window The window that the dialog should be modal for. May be NULL. * \param window The window that the dialog should be modal for. May be NULL.
* Not all platforms support this option. * Not all platforms support this option.
* \param filters A null-terminated list of SDL_DialogFileFilter's. May be * \param filters A list of SDL_DialogFileFilter's. May be NULL. Not all
* NULL. Not all platforms support this option, and platforms * platforms support this option, and platforms that do support
* that do support it may allow the user to ignore the filters. * 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. * \param default_location The default folder or file to start the dialog at.
* May be NULL. Not all platforms support this option. * May be NULL. Not all platforms support this option.
* \param allow_many If non-zero, the user will be allowed to select multiple * \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_ShowSaveFileDialog
* \sa SDL_ShowOpenFolderDialog * \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 * 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. * it will be invoked.
* \param window The window that the dialog should be modal for. May be NULL. * \param window The window that the dialog should be modal for. May be NULL.
* Not all platforms support this option. * Not all platforms support this option.
* \param filters A null-terminated list of SDL_DialogFileFilter's. May be * \param filters A list of SDL_DialogFileFilter's. May be NULL. Not all
* NULL. Not all platforms support this option, and platforms * platforms support this option, and platforms that do support
* that do support it may allow the user to ignore the filters. * 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. * \param default_location The default folder or file to start the dialog at.
* May be NULL. Not all platforms support this option. * 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_ShowOpenFileDialog
* \sa SDL_ShowOpenFolderDialog * \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. * 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_bool Android_JNI_OpenFileDialog(
SDL_DialogFileCallback callback, void* userdata, 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) { if (mAndroidFileDialogData.callback != NULL) {
SDL_SetError("Only one file dialog can be run at a time."); SDL_SetError("Only one file dialog can be run at a time.");
@ -2926,17 +2927,11 @@ SDL_bool Android_JNI_OpenFileDialog(
/* Setup filters */ /* Setup filters */
jobjectArray filtersArray = NULL; jobjectArray filtersArray = NULL;
if (filters) { 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"); 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 */ /* 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); jstring str = (*env)->NewStringUTF(env, filters[i].pattern);
(*env)->SetObjectArrayElement(env, filtersArray, i, str); (*env)->SetObjectArrayElement(env, filtersArray, i, str);
(*env)->DeleteLocalRef(env, str); (*env)->DeleteLocalRef(env, str);

View file

@ -144,7 +144,8 @@ void Android_ActivityMutex_Lock_Running(void);
/* File Dialogs */ /* File Dialogs */
SDL_bool Android_JNI_OpenFileDialog(SDL_DialogFileCallback callback, void* userdata, 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++ */ /* Ends C function definitions when using C++ */
#ifdef __cplusplus #ifdef __cplusplus

View file

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

View file

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

View file

@ -22,17 +22,17 @@
#include "SDL_internal.h" #include "SDL_internal.h"
#include "../../core/android/SDL_android.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 */ /* SDL_SetError is already called when it fails */
callback(userdata, NULL, -1); 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 */ /* SDL_SetError is already called when it fails */
callback(userdata, NULL, -1); callback(userdata, NULL, -1);
} }

View file

@ -31,14 +31,14 @@ typedef enum
FDT_OPENFOLDER FDT_OPENFOLDER
} cocoa_FileDialogType; } 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) #if defined(SDL_PLATFORM_TVOS) || defined(SDL_PLATFORM_IOS)
SDL_SetError("tvOS and iOS don't support path-based file dialogs"); SDL_SetError("tvOS and iOS don't support path-based file dialogs");
callback(userdata, NULL, -1); callback(userdata, NULL, -1);
#else #else
if (filters) { if (filters) {
const char *msg = validate_filters(filters); const char *msg = validate_filters(filters, nfilters);
if (msg) { if (msg) {
SDL_SetError("%s", msg); SDL_SetError("%s", msg);
@ -76,13 +76,11 @@ void show_file_dialog(cocoa_FileDialogType type, SDL_DialogFileCallback callback
}; };
if (filters) { 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 // 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; 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 = SDL_strdup(filters[i].pattern);
char *pattern_ptr = 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) #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) 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" #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(); SDL_Unsupported();
callback(userdata, NULL, -1); 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(); SDL_Unsupported();
callback(userdata, NULL, -1); 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 class SDLBRefFilter : public BRefFilter
{ {
public: public:
SDLBRefFilter(const SDL_DialogFileFilter *filters) : SDLBRefFilter(const SDL_DialogFileFilter *filters, int nfilters) :
BRefFilter(), BRefFilter(),
m_filters(filters) m_filters(filters),
m_nfilters(nfilters)
{ {
} }
@ -81,14 +82,12 @@ public:
if (S_ISDIR(info.st_mode)) if (S_ISDIR(info.st_mode))
return true; return true;
const auto *filter = m_filters; for (int i = 0; i < m_nfilters; i++) {
while (filter->name && filter->pattern) { for (const auto& suffix : StringSplit(m_filters[i].pattern, ";")) {
for (const auto& suffix : StringSplit(filter->pattern, ";")) {
if (StringEndsWith(result, std::string(".") + suffix)) { if (StringEndsWith(result, std::string(".") + suffix)) {
return true; return true;
} }
} }
filter++;
} }
return false; return false;
@ -96,6 +95,7 @@ public:
private: private:
const SDL_DialogFileFilter * const m_filters; const SDL_DialogFileFilter * const m_filters;
int m_nfilters;
}; };
class CallbackLooper : public BLooper class CallbackLooper : public BLooper
@ -190,7 +190,7 @@ private:
SDLBRefFilter *m_filter; 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()) { if (SDL_InitBeApp()) {
char* err = SDL_strdup(SDL_GetError()); char* err = SDL_strdup(SDL_GetError());
@ -200,12 +200,14 @@ void ShowDialog(bool save, SDL_DialogFileCallback callback, void *userdata, bool
return; return;
} }
const char *msg = validate_filters(filters); if (filters) {
const char *msg = validate_filters(filters, nfilters);
if (msg) { if (msg) {
SDL_SetError("%s", msg); SDL_SetError("%s", msg);
callback(userdata, NULL, -1); callback(userdata, NULL, -1);
return; return;
}
} }
if (SDL_GetHint(SDL_HINT_FILE_DIALOG_DRIVER) != NULL) { 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 // No unique_ptr's because they need to survive the end of the function
CallbackLooper *looper = new(std::nothrow) CallbackLooper(callback, userdata); CallbackLooper *looper = new(std::nothrow) CallbackLooper(callback, userdata);
BMessenger *messenger = new(std::nothrow) BMessenger(NULL, looper); 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) { if (looper == NULL || messenger == NULL || filter == NULL) {
SDL_free(looper); SDL_free(looper);
@ -241,19 +243,17 @@ void ShowDialog(bool save, SDL_DialogFileCallback callback, void *userdata, bool
panel->Show(); 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) 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 ShowDialog(false, callback, userdata, allow_many == SDL_TRUE, !!window, NULL, 0, true, default_location);
SDL_DialogFileFilter filter[] = {{}};
ShowDialog(false, callback, userdata, allow_many == SDL_TRUE, !!window, filter, 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); 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; DBusMessageIter filter_entry, filter_array, filter_array_entry;
char *state = NULL, *patterns, *pattern, *glob_pattern; char *state = NULL, *patterns, *pattern, *glob_pattern;
int zero = 0; int zero = 0;
dbus->message_iter_open_container(parent, DBUS_TYPE_STRUCT, NULL, &filter_entry); 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); 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) { if (!patterns) {
goto cleanup; goto cleanup;
} }
@ -120,7 +120,7 @@ cleanup:
dbus->message_iter_close_container(parent, &filter_entry); 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; DBusMessageIter options_pair, options_value, options_value_array;
static const char *filters_name = "filters"; 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_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_pair, DBUS_TYPE_VARIANT, "a(sa(us))", &options_value);
dbus->message_iter_open_container(&options_value, DBUS_TYPE_ARRAY, "(sa(us))", &options_value_array); 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) { for (int i = 0; i < nfilters; i++) {
DBus_AppendFilter(dbus, &options_value_array, filter); DBus_AppendFilter(dbus, &options_value_array, filters[i]);
} }
dbus->message_iter_close_container(&options_value, &options_value_array); dbus->message_iter_close_container(&options_value, &options_value_array);
dbus->message_iter_close_container(&options_pair, &options_value); dbus->message_iter_close_container(&options_pair, &options_value);
@ -269,7 +269,7 @@ not_our_signal:
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 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(); SDL_DBusContext *dbus = SDL_DBus_GetContext();
DBusMessage *msg; DBusMessage *msg;
@ -281,7 +281,7 @@ static void DBus_OpenDialog(const char *method, const char *method_title, SDL_Di
static char *default_parent_window = ""; static char *default_parent_window = "";
SDL_PropertiesID props = SDL_GetWindowProperties(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) { if (err_msg) {
SDL_SetError("%s", 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); DBus_AppendBoolOption(dbus, &options, "directory", 1);
} }
if (filters) { if (filters) {
DBus_AppendFilters(dbus, &options, filters); DBus_AppendFilters(dbus, &options, filters, nfilters);
} }
if (default_location) { if (default_location) {
DBus_AppendByteArray(dbus, &options, "current_folder", default_location); DBus_AppendByteArray(dbus, &options, "current_folder", default_location);
@ -419,19 +419,19 @@ incorrect_type:
dbus->message_unref(reply); 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) 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) int SDL_Portal_detect(void)
@ -494,13 +494,13 @@ done:
/* Dummy implementation to avoid compilation problems */ /* 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(); SDL_Unsupported();
callback(userdata, NULL, -1); 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(); SDL_Unsupported();
callback(userdata, NULL, -1); callback(userdata, NULL, -1);

View file

@ -21,8 +21,8 @@
#include "SDL_internal.h" #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_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, 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);
void SDL_Portal_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many); 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 */ /** @returns non-zero if available, zero if unavailable */

View file

@ -23,8 +23,8 @@
#include "./SDL_portaldialog.h" #include "./SDL_portaldialog.h"
#include "./SDL_zenitydialog.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_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, const char* default_location) = 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 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); static int detect_available_methods(const char *value);
@ -73,7 +73,7 @@ static int detect_available_methods(const char *value)
return 0; 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 */ /* Call detect_available_methods() again each time in case the situation changed */
if (!detected_open && !detect_available_methods(NULL)) { if (!detected_open && !detect_available_methods(NULL)) {
@ -82,10 +82,10 @@ void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL
return; 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 */ /* Call detect_available_methods() again each time in case the situation changed */
if (!detected_save && !detect_available_methods(NULL)) { if (!detected_save && !detect_available_methods(NULL)) {
@ -94,7 +94,7 @@ void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL
return; 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) 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; void* userdata;
const char* filename; const char* filename;
const SDL_DialogFileFilter *filters; const SDL_DialogFileFilter *filters;
int nfilters;
Uint32 flags; Uint32 flags;
} zenityArgs; } zenityArgs;
@ -110,12 +111,7 @@ static char** generate_args(const zenityArgs* info)
} }
if (info->filters) { if (info->filters) {
const SDL_DialogFileFilter *filter_ptr = info->filters; argc += info->nfilters;
while (filter_ptr->name && filter_ptr->pattern) {
argc++;
filter_ptr++;
}
} }
argv = SDL_malloc(sizeof(char *) * argc + 1); argv = SDL_malloc(sizeof(char *) * argc + 1);
@ -157,10 +153,9 @@ static char** generate_args(const zenityArgs* info)
} }
if (info->filters) { if (info->filters) {
const SDL_DialogFileFilter *filter_ptr = info->filters; for (int i = 0; i < info->nfilters; i++) {
char *filter_str = convert_filter(info->filters[i],
while (filter_ptr->name && filter_ptr->pattern) { zenity_clean_name,
char *filter_str = convert_filter(*filter_ptr, zenity_clean_name,
"--file-filter=", " | ", "", "--file-filter=", " | ", "",
"*.", " *.", ""); "*.", " *.", "");
@ -170,8 +165,6 @@ static char** generate_args(const zenityArgs* info)
argv[nextarg++] = filter_str; argv[nextarg++] = filter_str;
CHECK_OOM() CHECK_OOM()
filter_ptr++;
} }
} }
@ -330,7 +323,7 @@ static int run_zenity_thread(void* ptr)
return 0; 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; zenityArgs *args;
SDL_Thread *thread; SDL_Thread *thread;
@ -345,6 +338,7 @@ void SDL_Zenity_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userda
args->userdata = userdata; args->userdata = userdata;
args->filename = default_location; args->filename = default_location;
args->filters = filters; args->filters = filters;
args->nfilters = nfilters;
args->flags = (allow_many == SDL_TRUE) ? ZENITY_MULTIPLE : 0; args->flags = (allow_many == SDL_TRUE) ? ZENITY_MULTIPLE : 0;
thread = SDL_CreateThread(run_zenity_thread, "SDL_ShowOpenFileDialog", (void *) args); 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); 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; zenityArgs *args;
SDL_Thread *thread; SDL_Thread *thread;
@ -372,6 +366,7 @@ void SDL_Zenity_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userda
args->userdata = userdata; args->userdata = userdata;
args->filename = default_location; args->filename = default_location;
args->filters = filters; args->filters = filters;
args->nfilters = nfilters;
args->flags = ZENITY_SAVE; args->flags = ZENITY_SAVE;
thread = SDL_CreateThread(run_zenity_thread, "SDL_ShowSaveFileDialog", (void *) args); 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->userdata = userdata;
args->filename = default_location; args->filename = default_location;
args->filters = NULL; args->filters = NULL;
args->nfilters = 0;
args->flags = ((allow_many == SDL_TRUE) ? ZENITY_MULTIPLE : 0) | ZENITY_DIRECTORY; args->flags = ((allow_many == SDL_TRUE) ? ZENITY_MULTIPLE : 0) | ZENITY_DIRECTORY;
thread = SDL_CreateThread(run_zenity_thread, "SDL_ShowOpenFolderDialog", (void *) args); thread = SDL_CreateThread(run_zenity_thread, "SDL_ShowOpenFolderDialog", (void *) args);

View file

@ -21,8 +21,8 @@
#include "SDL_internal.h" #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_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, 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);
void SDL_Zenity_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many); 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 */ /** @returns non-zero if available, zero if unavailable */

View file

@ -34,6 +34,7 @@ typedef struct
{ {
int is_save; int is_save;
const SDL_DialogFileFilter *filters; const SDL_DialogFileFilter *filters;
int nfilters;
const char* default_file; const char* default_file;
SDL_Window* parent; SDL_Window* parent;
DWORD flags; DWORD flags;
@ -50,18 +51,9 @@ typedef struct
} winFArgs; } winFArgs;
/** Converts dialog.nFilterIndex to SDL-compatible value */ /** 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; return 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;
} }
/* TODO: The new version of file dialogs */ /* TODO: The new version of file dialogs */
@ -70,6 +62,7 @@ void windows_ShowFileDialog(void *ptr)
winArgs *args = (winArgs *) ptr; winArgs *args = (winArgs *) ptr;
int is_save = args->is_save; int is_save = args->is_save;
const SDL_DialogFileFilter *filters = args->filters; const SDL_DialogFileFilter *filters = args->filters;
int nfilters = args->nfilters;
const char* default_file = args->default_file; const char* default_file = args->default_file;
SDL_Window* parent = args->parent; SDL_Window* parent = args->parent;
DWORD flags = args->flags; DWORD flags = args->flags;
@ -160,8 +153,9 @@ void windows_ShowFileDialog(void *ptr)
if (filters) { if (filters) {
/* '\x01' is used in place of a null byte */ /* '\x01' is used in place of a null byte */
/* suffix needs two null bytes in case the filter list is empty */ /* suffix needs two null bytes in case the filter list is empty */
char *filterlist = convert_filters(filters, NULL, "", "", "\x01\x01", "", char *filterlist = convert_filters(filters, nfilters, NULL, "", "",
"\x01", "\x01", "*.", ";*.", ""); "\x01\x01", "", "\x01", "\x01",
"*.", ";*.", "");
if (!filterlist) { if (!filterlist) {
callback(userdata, NULL, -1); callback(userdata, NULL, -1);
@ -224,7 +218,7 @@ void windows_ShowFileDialog(void *ptr)
/* File is a C string stored in dialog.lpstrFile */ /* File is a C string stored in dialog.lpstrFile */
char *chosen_file = WIN_StringToUTF8W(dialog.lpstrFile); char *chosen_file = WIN_StringToUTF8W(dialog.lpstrFile);
const char* opts[2] = { chosen_file, NULL }; const char* opts[2] = { chosen_file, NULL };
callback(userdata, opts, getFilterIndex(dialog.nFilterIndex, filters)); callback(userdata, opts, getFilterIndex(dialog.nFilterIndex));
SDL_free(chosen_file); SDL_free(chosen_file);
} else { } else {
/* File is either a C string if the user chose a single 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++) { for (size_t i = 0; i < nfiles; i++) {
SDL_free(chosen_files_list[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 function before set a different error code, so it's safe to
check for success. */ check for success. */
const char* opts[1] = { NULL }; const char* opts[1] = { NULL };
callback(userdata, opts, getFilterIndex(dialog.nFilterIndex, filters)); callback(userdata, opts, getFilterIndex(dialog.nFilterIndex));
} else { } else {
SDL_SetError("Windows error, CommDlgExtendedError: %ld", pCommDlgExtendedError()); SDL_SetError("Windows error, CommDlgExtendedError: %ld", pCommDlgExtendedError());
callback(userdata, NULL, -1); callback(userdata, NULL, -1);
@ -433,7 +427,7 @@ int windows_folder_dialog_thread(void* ptr)
return 0; 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; winArgs *args;
SDL_Thread *thread; SDL_Thread *thread;
@ -453,6 +447,7 @@ void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL
args->is_save = 0; args->is_save = 0;
args->filters = filters; args->filters = filters;
args->nfilters = nfilters;
args->default_file = default_location; args->default_file = default_location;
args->parent = window; args->parent = window;
args->flags = (allow_many == SDL_TRUE) ? OFN_ALLOWMULTISELECT : 0; 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); 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; winArgs *args;
SDL_Thread *thread; SDL_Thread *thread;
@ -489,6 +484,7 @@ void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL
args->is_save = 1; args->is_save = 1;
args->filters = filters; args->filters = filters;
args->nfilters = nfilters;
args->default_file = default_location; args->default_file = default_location;
args->parent = window; args->parent = window;
args->flags = 0; 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(void,SDL_SetX11EventHook,(SDL_X11EventHook a, void *b),(a,b),)
SDL_DYNAPI_PROC(int,SDL_ShowCursor,(void),(),return) 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(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_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_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_ShowWindow,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_ShowWindowSystemMenu,(SDL_Window *a, int b, int c),(a,b,c),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_main.h>
#include <SDL3/SDL_test.h> #include <SDL3/SDL_test.h>
const SDL_DialogFileFilter filters[4] = { const SDL_DialogFileFilter filters[3] = {
{ "All files", "*" }, { "All files", "*" },
{ "JPG images", "jpg;jpeg" }, { "JPG images", "jpg;jpeg" },
{ "PNG images", "png" }, { "PNG images", "png" }
{ NULL, NULL }
}; };
static void SDLCALL callback(void* userdata, const char* const* files, int filter) { 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 }; const SDL_FRect open_folder_rect = { 370, 50, 220, 140 };
int i; int i;
char *initial_path = NULL; char *initial_path = NULL;
const int nfilters = sizeof(filters) / sizeof(*filters);
/* Initialize test framework */ /* Initialize test framework */
state = SDLTest_CommonCreateState(argv, 0); 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) * - Nonzero if the user is allowed to choose multiple entries (not for SDL_ShowSaveFileDialog)
*/ */
if (SDL_PointInRectFloat(&p, &open_file_rect)) { 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)) { } else if (SDL_PointInRectFloat(&p, &open_folder_rect)) {
SDL_ShowOpenFolderDialog(callback, NULL, w, initial_path, 1); SDL_ShowOpenFolderDialog(callback, NULL, w, initial_path, 1);
} else if (SDL_PointInRectFloat(&p, &save_file_rect)) { } 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);
} }
} }
} }