mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-03-10 07:50:19 +00:00
Refactored file-selection completion logic so it can operate on any GtkFileChooser object, not only GtkFileChooserDialog, by introducing gtkutil_file_req_done_chooser() and reusing it from the existing dialog path. This keeps validation/callback behavior identical between chooser implementations.
Updated gtkutil_file_req() to resolve an effective_parent (fallback to global parent_window when no parent is passed), which ensures consistent transient parenting and modal assertions in this code path. Added a Windows GTK3-specific path that uses GtkFileChooserNative (instead of the GTK file chooser dialog widget path implicated by your stack trace), while preserving existing behavior for initial folder/name, filters, multi-select, and overwrite confirmation before invoking the same file-check callback flow. Left the existing non-Windows / non-GTK3 dialog flow in place unchanged in behavior, so platforms outside the crash scenario continue using the prior implementation.
This commit is contained in:
@@ -431,10 +431,9 @@ gtkutil_check_file (char *filename, struct file_req *freq)
|
||||
}
|
||||
|
||||
static void
|
||||
gtkutil_file_req_done (GtkWidget * wid, struct file_req *freq)
|
||||
gtkutil_file_req_done_chooser (GtkFileChooser *fs, struct file_req *freq)
|
||||
{
|
||||
GSList *files, *cur;
|
||||
GtkFileChooser *fs = GTK_FILE_CHOOSER (freq->dialog);
|
||||
|
||||
if (freq->flags & FRF_MULTIPLE)
|
||||
{
|
||||
@@ -467,6 +466,13 @@ gtkutil_file_req_done (GtkWidget * wid, struct file_req *freq)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gtkutil_file_req_done (GtkWidget * wid, struct file_req *freq)
|
||||
{
|
||||
gtkutil_file_req_done_chooser (GTK_FILE_CHOOSER (freq->dialog), freq);
|
||||
|
||||
/* this should call the "destroy" cb, where we free(freq) */
|
||||
gtk_widget_destroy (freq->dialog);
|
||||
}
|
||||
@@ -496,6 +502,91 @@ gtkutil_file_req (GtkWindow *parent, const char *title, void *callback, void *us
|
||||
char *token;
|
||||
char *tokenbuffer;
|
||||
const char *xdir;
|
||||
GtkWindow *effective_parent = parent;
|
||||
|
||||
extern GtkWidget *parent_window;
|
||||
if (effective_parent == NULL && parent_window != NULL)
|
||||
effective_parent = GTK_WINDOW (parent_window);
|
||||
|
||||
xdir = get_xdir ();
|
||||
|
||||
#if defined (WIN32) && HAVE_GTK3
|
||||
{
|
||||
GtkFileChooserNative *native = gtk_file_chooser_native_new (
|
||||
title,
|
||||
effective_parent,
|
||||
(flags & FRF_CHOOSEFOLDER) ? GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER :
|
||||
((flags & FRF_WRITE) ? GTK_FILE_CHOOSER_ACTION_SAVE : GTK_FILE_CHOOSER_ACTION_OPEN),
|
||||
(flags & FRF_WRITE) ? _("_Save") : _("_Open"),
|
||||
_("_Cancel"));
|
||||
GtkFileChooser *native_chooser = GTK_FILE_CHOOSER (native);
|
||||
int response;
|
||||
|
||||
if (flags & FRF_MULTIPLE)
|
||||
gtk_file_chooser_set_select_multiple (native_chooser, TRUE);
|
||||
if (flags & FRF_WRITE && !(flags & FRF_NOASKOVERWRITE))
|
||||
gtk_file_chooser_set_do_overwrite_confirmation (native_chooser, TRUE);
|
||||
|
||||
if ((flags & FRF_EXTENSIONS || flags & FRF_MIMETYPES) && extensions != NULL)
|
||||
{
|
||||
GtkFileFilter *native_filter = gtk_file_filter_new ();
|
||||
char *native_tokenbuffer = g_strdup (extensions);
|
||||
char *native_token = strtok (native_tokenbuffer, ";");
|
||||
|
||||
while (native_token != NULL)
|
||||
{
|
||||
if (flags & FRF_EXTENSIONS)
|
||||
gtk_file_filter_add_pattern (native_filter, native_token);
|
||||
else
|
||||
gtk_file_filter_add_mime_type (native_filter, native_token);
|
||||
native_token = strtok (NULL, ";");
|
||||
}
|
||||
|
||||
g_free (native_tokenbuffer);
|
||||
gtk_file_chooser_set_filter (native_chooser, native_filter);
|
||||
}
|
||||
|
||||
if (filter && filter[0] && (flags & FRF_FILTERISINITIAL))
|
||||
{
|
||||
if (flags & FRF_WRITE)
|
||||
{
|
||||
char temp[1024];
|
||||
path_part (filter, temp, sizeof (temp));
|
||||
if (temp[0] && g_file_test (temp, G_FILE_TEST_IS_DIR))
|
||||
gtk_file_chooser_set_current_folder (native_chooser, temp);
|
||||
else if (xdir && xdir[0] && g_file_test (xdir, G_FILE_TEST_IS_DIR))
|
||||
gtk_file_chooser_set_current_folder (native_chooser, xdir);
|
||||
gtk_file_chooser_set_current_name (native_chooser, file_part (filter));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_file_test (filter, G_FILE_TEST_IS_DIR))
|
||||
gtk_file_chooser_set_current_folder (native_chooser, filter);
|
||||
else if (xdir && xdir[0] && g_file_test (xdir, G_FILE_TEST_IS_DIR))
|
||||
gtk_file_chooser_set_current_folder (native_chooser, xdir);
|
||||
}
|
||||
}
|
||||
else if (!(flags & FRF_RECENTLYUSED))
|
||||
{
|
||||
if (xdir && xdir[0] && g_file_test (xdir, G_FILE_TEST_IS_DIR))
|
||||
gtk_file_chooser_set_current_folder (native_chooser, xdir);
|
||||
}
|
||||
|
||||
freq = g_new (struct file_req, 1);
|
||||
freq->dialog = NULL;
|
||||
freq->flags = flags;
|
||||
freq->callback = callback;
|
||||
freq->userdata = userdata;
|
||||
|
||||
response = gtk_native_dialog_run (GTK_NATIVE_DIALOG (native));
|
||||
if (response == GTK_RESPONSE_ACCEPT)
|
||||
gtkutil_file_req_done_chooser (native_chooser, freq);
|
||||
|
||||
g_object_unref (native);
|
||||
g_free (freq);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (flags & FRF_WRITE)
|
||||
{
|
||||
@@ -531,8 +622,6 @@ gtkutil_file_req (GtkWindow *parent, const char *title, void *callback, void *us
|
||||
NULL);
|
||||
#endif
|
||||
|
||||
xdir = get_xdir ();
|
||||
|
||||
if (filter && filter[0] && (flags & FRF_FILTERISINITIAL))
|
||||
{
|
||||
if (flags & FRF_WRITE)
|
||||
@@ -591,7 +680,6 @@ gtkutil_file_req (GtkWindow *parent, const char *title, void *callback, void *us
|
||||
if (shortcut_error)
|
||||
g_error_free (shortcut_error);
|
||||
}
|
||||
|
||||
freq = g_new (struct file_req, 1);
|
||||
freq->dialog = dialog;
|
||||
freq->flags = flags;
|
||||
@@ -603,12 +691,12 @@ gtkutil_file_req (GtkWindow *parent, const char *title, void *callback, void *us
|
||||
g_signal_connect (G_OBJECT (dialog), "destroy",
|
||||
G_CALLBACK (gtkutil_file_req_destroy), (gpointer) freq);
|
||||
|
||||
if (parent)
|
||||
gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
|
||||
if (effective_parent)
|
||||
gtk_window_set_transient_for (GTK_WINDOW (dialog), effective_parent);
|
||||
|
||||
if (flags & FRF_MODAL)
|
||||
{
|
||||
g_assert (parent);
|
||||
g_assert (effective_parent);
|
||||
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user