Branch: refs/heads/master Author: Jiří Techet techet@gmail.com Committer: GitHub noreply@github.com Date: Wed, 12 Jun 2024 12:01:33 UTC Commit: 05286579a253e2806192e863475b28b47843b2aa https://github.com/geany/geany/commit/05286579a253e2806192e863475b28b47843b2...
Log Message: ----------- Merge pull request #3861 from techee/native_dialogs
Use GtkFileChooserNative for opening files on Windows and macOS
Modified Paths: -------------- data/geany.glade plugins/saveactions.c src/dialogs.c src/dialogs.h src/filetypes.c src/keyfile.c src/prefs.c src/project.c src/symbols.c src/ui_utils.c src/ui_utils.h src/win32.c src/win32.h
Modified: data/geany.glade 16 lines changed, 16 insertions(+), 0 deletions(-) =================================================================== @@ -1311,6 +1311,22 @@ <property name="position">3</property> </packing> </child> + <child> + <object class="GtkCheckButton" id="check_native_dialogs"> + <property name="label" translatable="yes">Use platform-native file dialogs</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="tooltip-text" translatable="yes">Defines whether to use the platform-native file dialogs or the GTK default dialogs</property> + <property name="use-underline">True</property> + <property name="draw-indicator">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">4</property> + </packing> + </child> </object> </child> </object>
Modified: plugins/saveactions.c 41 lines changed, 32 insertions(+), 9 deletions(-) =================================================================== @@ -445,27 +445,50 @@ void plugin_init(GeanyData *data) }
+static gint file_chooser_run(GtkFileChooser *dialog) +{ + if (GTK_IS_NATIVE_DIALOG(dialog)) + return gtk_native_dialog_run(GTK_NATIVE_DIALOG(dialog)); + else + return gtk_dialog_run(GTK_DIALOG(dialog)); +} + + +static void file_chooser_destroy(GtkFileChooser *dialog) +{ + if (GTK_IS_NATIVE_DIALOG(dialog)) + g_object_unref(dialog); + else + gtk_widget_destroy(GTK_WIDGET(dialog)); +} + + static void target_directory_button_clicked_cb(GtkButton *button, gpointer item) { - GtkWidget *dialog; + GtkFileChooser *dialog; gchar *text;
/* initialize the dialog */ - dialog = gtk_file_chooser_dialog_new(_("Select Directory"), NULL, - GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); + if (geany_data->interface_prefs->use_native_windows_dialogs) + dialog = GTK_FILE_CHOOSER(gtk_file_chooser_native_new(_("Select Directory"), + GTK_WINDOW(geany_data->main_widgets->window), + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, NULL, NULL)); + else + dialog = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new(_("Select Directory"), + NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL));
text = utils_get_locale_from_utf8(gtk_entry_get_text(GTK_ENTRY(item))); if (!EMPTY(text)) - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), text); + gtk_file_chooser_set_current_folder(dialog, text);
/* run it */ - if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) + if (file_chooser_run(dialog) == GTK_RESPONSE_ACCEPT) { gchar *utf8_filename, *tmp;
- tmp = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + tmp = gtk_file_chooser_get_filename(dialog); utf8_filename = utils_get_utf8_from_locale(tmp);
gtk_entry_set_text(GTK_ENTRY(item), utf8_filename); @@ -474,7 +497,7 @@ static void target_directory_button_clicked_cb(GtkButton *button, gpointer item) g_free(tmp); }
- gtk_widget_destroy(dialog); + file_chooser_destroy(dialog); }
Modified: src/dialogs.c 227 lines changed, 135 insertions(+), 92 deletions(-) =================================================================== @@ -122,7 +122,7 @@ static void file_chooser_set_filter_idx(GtkFileChooser *chooser, guint idx) }
-static gboolean open_file_dialog_handle_response(GtkWidget *dialog, gint response) +static gboolean open_file_dialog_handle_response(GtkFileChooser *dialog, gint response) { gboolean ret = TRUE;
@@ -131,24 +131,28 @@ static gboolean open_file_dialog_handle_response(GtkWidget *dialog, gint respons GSList *filelist; GeanyFiletype *ft = NULL; const gchar *charset = NULL; - GtkWidget *expander = ui_lookup_widget(dialog, "more_options_expander"); - GtkWidget *filetype_combo = ui_lookup_widget(dialog, "filetype_combo"); - GtkWidget *encoding_combo = ui_lookup_widget(dialog, "encoding_combo"); gboolean ro = (response == GEANY_RESPONSE_VIEW); /* View clicked */
- filesel_state.open.more_options_visible = gtk_expander_get_expanded(GTK_EXPANDER(expander)); - filesel_state.open.filter_idx = file_chooser_get_filter_idx(GTK_FILE_CHOOSER(dialog)); - filesel_state.open.filetype_idx = filetype_combo_box_get_active_filetype(GTK_COMBO_BOX(filetype_combo)); + if (!GTK_IS_NATIVE_DIALOG(dialog)) + { + GtkWidget *expander = ui_lookup_widget(GTK_WIDGET(dialog), "more_options_expander"); + GtkWidget *filetype_combo = ui_lookup_widget(GTK_WIDGET(dialog), "filetype_combo"); + GtkWidget *encoding_combo = ui_lookup_widget(GTK_WIDGET(dialog), "encoding_combo"); + + filesel_state.open.more_options_visible = gtk_expander_get_expanded(GTK_EXPANDER(expander)); + filesel_state.open.filetype_idx = filetype_combo_box_get_active_filetype(GTK_COMBO_BOX(filetype_combo)); + filesel_state.open.encoding_idx = ui_encodings_combo_box_get_active_encoding(GTK_COMBO_BOX(encoding_combo)); + } + filesel_state.open.filter_idx = file_chooser_get_filter_idx(dialog);
/* ignore detect from file item */ if (filesel_state.open.filetype_idx >= 0) ft = filetypes_index(filesel_state.open.filetype_idx);
- filesel_state.open.encoding_idx = ui_encodings_combo_box_get_active_encoding(GTK_COMBO_BOX(encoding_combo)); if (filesel_state.open.encoding_idx >= 0 && filesel_state.open.encoding_idx < GEANY_ENCODINGS_MAX) charset = encodings[filesel_state.open.encoding_idx].charset;
- filelist = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)); + filelist = gtk_file_chooser_get_filenames(dialog); if (filelist != NULL) { const gchar *first = filelist->data; @@ -167,7 +171,7 @@ static gboolean open_file_dialog_handle_response(GtkWidget *dialog, gint respons } } if (app->project && !EMPTY(app->project->base_path)) - gtk_file_chooser_remove_shortcut_folder(GTK_FILE_CHOOSER(dialog), + gtk_file_chooser_remove_shortcut_folder(dialog, app->project->base_path, NULL); return ret; } @@ -365,90 +369,122 @@ static GtkWidget *add_file_open_extra_widget(GtkWidget *dialog) }
-static GtkWidget *create_open_file_dialog(void) +static GtkFileChooser *create_open_file_dialog(void) { - GtkWidget *dialog; + GtkFileChooser *dialog; + GtkFileFilter *filter; GtkWidget *viewbtn; GSList *node;
- dialog = gtk_file_chooser_dialog_new(_("Open File"), GTK_WINDOW(main_widgets.window), - GTK_FILE_CHOOSER_ACTION_OPEN, NULL, NULL); - gtk_widget_set_name(dialog, "GeanyDialog"); - - viewbtn = gtk_dialog_add_button(GTK_DIALOG(dialog), C_("Open dialog action", "_View"), GEANY_RESPONSE_VIEW); - gtk_widget_set_tooltip_text(viewbtn, - _("Opens the file in read-only mode. If you choose more than one file to open, all files will be opened read-only.")); - - gtk_dialog_add_buttons(GTK_DIALOG(dialog), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); - gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); - - gtk_widget_set_size_request(dialog, -1, 460); - gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); - gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); - gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), FALSE); - gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG); - gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(main_widgets.window)); - gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE); - gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dialog), FALSE); - - /* add checkboxes and filename entry */ - gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(dialog), add_file_open_extra_widget(dialog)); + if (interface_prefs.use_native_windows_dialogs) + dialog = GTK_FILE_CHOOSER(gtk_file_chooser_native_new(_("Open File"), + GTK_WINDOW(main_widgets.window), GTK_FILE_CHOOSER_ACTION_OPEN, NULL, NULL)); + else + { + dialog = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new(_("Open File"), GTK_WINDOW(main_widgets.window), + GTK_FILE_CHOOSER_ACTION_OPEN, NULL, NULL)); + gtk_widget_set_name(GTK_WIDGET(dialog), "GeanyDialog"); + + viewbtn = gtk_dialog_add_button(GTK_DIALOG(dialog), C_("Open dialog action", "_View"), GEANY_RESPONSE_VIEW); + gtk_widget_set_tooltip_text(viewbtn, + _("Opens the file in read-only mode. If you choose more than one file to open, all files will be opened read-only.")); + + gtk_dialog_add_buttons(GTK_DIALOG(dialog), + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); + gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); + + gtk_widget_set_size_request(GTK_WIDGET(dialog), -1, 460); + gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); + gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); + gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), FALSE); + gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG); + gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(main_widgets.window)); + + /* add checkboxes and filename entry */ + gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(dialog), add_file_open_extra_widget(GTK_WIDGET(dialog))); + + g_signal_connect(dialog, "notify::show-hidden", + G_CALLBACK(on_file_open_show_hidden_notify), NULL); + }
/* add FileFilters(start with "All Files") */ - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), - filetypes_create_file_filter(filetypes[GEANY_FILETYPES_NONE])); + if ((filter = filetypes_create_file_filter(filetypes[GEANY_FILETYPES_NONE]))) + gtk_file_chooser_add_filter(dialog, filter); /* now create meta filter "All Source" */ - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), - filetypes_create_file_filter_all_source()); + if ((filter = filetypes_create_file_filter_all_source())) + gtk_file_chooser_add_filter(dialog, filter); foreach_slist(node, filetypes_by_title) { GeanyFiletype *ft = node->data;
if (G_UNLIKELY(ft->id == GEANY_FILETYPES_NONE)) continue; - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filetypes_create_file_filter(ft)); + if ((filter = filetypes_create_file_filter(ft))) + gtk_file_chooser_add_filter(dialog, filter); }
- g_signal_connect(dialog, "notify::show-hidden", - G_CALLBACK(on_file_open_show_hidden_notify), NULL); + gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE); + gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dialog), FALSE);
return dialog; }
-static void open_file_dialog_apply_settings(GtkWidget *dialog) +static void open_file_dialog_apply_settings(GtkFileChooser *dialog) { static gboolean initialized = FALSE; - GtkWidget *check_hidden = ui_lookup_widget(dialog, "check_hidden"); - GtkWidget *filetype_combo = ui_lookup_widget(dialog, "filetype_combo"); - GtkWidget *encoding_combo = ui_lookup_widget(dialog, "encoding_combo"); - GtkWidget *expander = ui_lookup_widget(dialog, "more_options_expander");
/* we can't know the initial position of combo boxes, so retrieve it the first time */ if (! initialized) { - filesel_state.open.filter_idx = file_chooser_get_filter_idx(GTK_FILE_CHOOSER(dialog)); + filesel_state.open.filter_idx = file_chooser_get_filter_idx(dialog);
initialized = TRUE; } else { - file_chooser_set_filter_idx(GTK_FILE_CHOOSER(dialog), filesel_state.open.filter_idx); + file_chooser_set_filter_idx(dialog, filesel_state.open.filter_idx); + } + + if (!GTK_IS_NATIVE_DIALOG(dialog)) + { + GtkWidget *check_hidden = ui_lookup_widget(GTK_WIDGET(dialog), "check_hidden"); + GtkWidget *filetype_combo = ui_lookup_widget(GTK_WIDGET(dialog), "filetype_combo"); + GtkWidget *encoding_combo = ui_lookup_widget(GTK_WIDGET(dialog), "encoding_combo"); + GtkWidget *expander = ui_lookup_widget(GTK_WIDGET(dialog), "more_options_expander"); + + gtk_expander_set_expanded(GTK_EXPANDER(expander), filesel_state.open.more_options_visible); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_hidden), filesel_state.open.show_hidden); + ui_encodings_combo_box_set_active_encoding(GTK_COMBO_BOX(encoding_combo), filesel_state.open.encoding_idx); + filetype_combo_box_set_active_filetype(GTK_COMBO_BOX(filetype_combo), filesel_state.open.filetype_idx); } - gtk_expander_set_expanded(GTK_EXPANDER(expander), filesel_state.open.more_options_visible); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_hidden), filesel_state.open.show_hidden); - ui_encodings_combo_box_set_active_encoding(GTK_COMBO_BOX(encoding_combo), filesel_state.open.encoding_idx); - filetype_combo_box_set_active_filetype(GTK_COMBO_BOX(filetype_combo), filesel_state.open.filetype_idx); +} + + +gint dialogs_file_chooser_run(GtkFileChooser *dialog) +{ + if (GTK_IS_NATIVE_DIALOG(dialog)) + return gtk_native_dialog_run(GTK_NATIVE_DIALOG(dialog)); + else + return gtk_dialog_run(GTK_DIALOG(dialog)); +} + + +void dialogs_file_chooser_destroy(GtkFileChooser *dialog) +{ + if (GTK_IS_NATIVE_DIALOG(dialog)) + g_object_unref(dialog); + else + gtk_widget_destroy(GTK_WIDGET(dialog)); }
/* This shows the file selection dialog to open a file. */ void dialogs_show_open_file(void) { gchar *initdir; - GtkWidget *dialog; + GtkFileChooser *dialog;
/* set dialog directory to the current file's directory, if present */ initdir = utils_get_current_file_dir_utf8(); @@ -464,15 +500,15 @@ void dialogs_show_open_file(void) open_file_dialog_apply_settings(dialog);
if (initdir != NULL && g_path_is_absolute(initdir)) - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), initdir); + gtk_file_chooser_set_current_folder(dialog, initdir);
if (app->project && !EMPTY(app->project->base_path)) - gtk_file_chooser_add_shortcut_folder(GTK_FILE_CHOOSER(dialog), + gtk_file_chooser_add_shortcut_folder(dialog, app->project->base_path, NULL);
while (!open_file_dialog_handle_response(dialog, - gtk_dialog_run(GTK_DIALOG(dialog)))); - gtk_widget_destroy(dialog); + dialogs_file_chooser_run(dialog))); + dialogs_file_chooser_destroy(dialog);
g_free(initdir); } @@ -507,11 +543,11 @@ static gboolean handle_save_as(GeanyDocument *doc,
static gboolean save_as_dialog_handle_response(GeanyDocument *doc, - GtkWidget *dialog, gint response) + GtkFileChooser *dialog, gint response) { gboolean rename_file = FALSE; gboolean success = FALSE; - gchar *new_filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + gchar *new_filename = gtk_file_chooser_get_filename(dialog);
switch (response) { @@ -549,39 +585,46 @@ static gboolean save_as_dialog_handle_response(GeanyDocument *doc, }
-static GtkWidget *create_save_file_dialog(GeanyDocument *doc) +static GtkFileChooser *create_save_file_dialog(GeanyDocument *doc) { - GtkWidget *dialog, *rename_btn; + GtkFileChooser *dialog; + GtkWidget *rename_btn; const gchar *initdir;
- dialog = gtk_file_chooser_dialog_new(_("Save File"), GTK_WINDOW(main_widgets.window), - GTK_FILE_CHOOSER_ACTION_SAVE, NULL, NULL); - gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); - gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); - gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), FALSE); - gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG); - gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(main_widgets.window)); - gtk_widget_set_name(dialog, "GeanyDialog"); - - rename_btn = gtk_dialog_add_button(GTK_DIALOG(dialog), _("R_ename"), GEANY_RESPONSE_RENAME); - gtk_widget_set_tooltip_text(rename_btn, _("Save the file and rename it")); - /* disable rename unless file exists on disk */ - gtk_widget_set_sensitive(rename_btn, doc->real_path != NULL); - - gtk_dialog_add_buttons(GTK_DIALOG(dialog), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); - gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); + if (interface_prefs.use_native_windows_dialogs) + dialog = GTK_FILE_CHOOSER(gtk_file_chooser_native_new(_("Save File"), + GTK_WINDOW(main_widgets.window), GTK_FILE_CHOOSER_ACTION_SAVE, NULL, NULL)); + else + { + dialog = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new(_("Save File"), GTK_WINDOW(main_widgets.window), + GTK_FILE_CHOOSER_ACTION_SAVE, NULL, NULL)); + gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); + gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); + gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), FALSE); + gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG); + gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(main_widgets.window)); + gtk_widget_set_name(GTK_WIDGET(dialog), "GeanyDialog"); + + rename_btn = gtk_dialog_add_button(GTK_DIALOG(dialog), _("R_ename"), GEANY_RESPONSE_RENAME); + gtk_widget_set_tooltip_text(rename_btn, _("Save the file and rename it")); + /* disable rename unless file exists on disk */ + gtk_widget_set_sensitive(rename_btn, doc->real_path != NULL); + + gtk_dialog_add_buttons(GTK_DIALOG(dialog), + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); + gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); + }
- gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE); - gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dialog), FALSE); + gtk_file_chooser_set_do_overwrite_confirmation(dialog, TRUE); + gtk_file_chooser_set_local_only(dialog, FALSE);
/* set the folder by default to the project base dir or the global pref for opening files */ initdir = utils_get_default_dir_utf8(); if (initdir) { gchar *linitdir = utils_get_locale_from_utf8(initdir); - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), linitdir); + gtk_file_chooser_set_current_folder(dialog, linitdir); g_free(linitdir); } return dialog; @@ -590,7 +633,7 @@ static GtkWidget *create_save_file_dialog(GeanyDocument *doc)
static gboolean show_save_as_gtk(GeanyDocument *doc) { - GtkWidget *dialog; + GtkFileChooser *dialog; gint resp;
g_return_val_if_fail(DOC_VALID(doc), FALSE); @@ -605,15 +648,15 @@ static gboolean show_save_as_gtk(GeanyDocument *doc) gchar *locale_basename = g_path_get_basename(locale_filename); gchar *locale_dirname = g_path_get_dirname(locale_filename);
- gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), locale_dirname); - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), locale_basename); + gtk_file_chooser_set_current_folder(dialog, locale_dirname); + gtk_file_chooser_set_current_name(dialog, locale_basename);
g_free(locale_filename); g_free(locale_basename); g_free(locale_dirname); } else - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), doc->file_name); + gtk_file_chooser_set_current_name(dialog, doc->file_name); } else { @@ -625,7 +668,7 @@ static gboolean show_save_as_gtk(GeanyDocument *doc) else fname = g_strdup(GEANY_STRING_UNTITLED);
- gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), fname); + gtk_file_chooser_set_current_name(dialog, fname);
g_free(fname); } @@ -637,15 +680,15 @@ static gboolean show_save_as_gtk(GeanyDocument *doc) /* Run the dialog synchronously, pausing this function call */ do { - resp = gtk_dialog_run(GTK_DIALOG(dialog)); + resp = dialogs_file_chooser_run(dialog); } while (! save_as_dialog_handle_response(doc, dialog, resp));
if (app->project && !EMPTY(app->project->base_path)) - gtk_file_chooser_remove_shortcut_folder(GTK_FILE_CHOOSER(dialog), + gtk_file_chooser_remove_shortcut_folder(dialog, app->project->base_path, NULL);
- gtk_widget_destroy(dialog); + dialogs_file_chooser_destroy(dialog);
return (resp == GTK_RESPONSE_ACCEPT); }
Modified: src/dialogs.h 3 lines changed, 3 insertions(+), 0 deletions(-) =================================================================== @@ -80,6 +80,9 @@ gint dialogs_show_prompt(GtkWidget *parent,
void dialogs_show_msgbox_with_secondary(GtkMessageType type, const gchar *text, const gchar *secondary);
+gint dialogs_file_chooser_run(GtkFileChooser *dialog); +void dialogs_file_chooser_destroy(GtkFileChooser *dialog); + #endif /* GEANY_PRIVATE */
G_END_DECLS
Modified: src/filetypes.c 17 lines changed, 17 insertions(+), 0 deletions(-) =================================================================== @@ -1187,6 +1187,7 @@ GtkFileFilter *filetypes_create_file_filter_all_source(void) { GtkFileFilter *new_filter; guint i, j; + guint n_patterns = 0;
new_filter = gtk_file_filter_new(); gtk_file_filter_set_name(new_filter, _("All Source")); @@ -1200,7 +1201,16 @@ GtkFileFilter *filetypes_create_file_filter_all_source(void) { gtk_file_filter_add_pattern(new_filter, filetypes[i]->pattern[j]); } + n_patterns += j; } + + /* very unlikely case where there is *no* patterns at all */ + if (n_patterns == 0) + { + g_object_unref(new_filter); + new_filter = NULL; + } + return new_filter; }
@@ -1213,6 +1223,13 @@ GtkFileFilter *filetypes_create_file_filter(const GeanyFiletype *ft)
g_return_val_if_fail(ft != NULL, NULL);
+ /* unlikely case where the ft has no patterns */ + if (! ft->pattern[0]) + { + g_debug("Not creating filter for filetype %s that has no pattern", ft->name); + return NULL; + } + new_filter = gtk_file_filter_new(); title = ft->id == GEANY_FILETYPES_NONE ? _("All files") : ft->title; gtk_file_filter_set_name(new_filter, title);
Modified: src/keyfile.c 11 lines changed, 8 insertions(+), 3 deletions(-) =================================================================== @@ -79,11 +79,14 @@ #define GEANY_DISK_CHECK_TIMEOUT 30 #define GEANY_DEFAULT_TOOLS_MAKE "make" #ifdef G_OS_WIN32 -#define GEANY_DEFAULT_TOOLS_TERMINAL "cmd.exe /Q /C %c" +# define GEANY_DEFAULT_TOOLS_TERMINAL "cmd.exe /Q /C %c" +# define GEANY_DEFAULT_USE_NATIVE_DLGS TRUE #elif defined(__APPLE__) -#define GEANY_DEFAULT_TOOLS_TERMINAL "open -a terminal %c" +# define GEANY_DEFAULT_TOOLS_TERMINAL "open -a terminal %c" +# define GEANY_DEFAULT_USE_NATIVE_DLGS TRUE #else -#define GEANY_DEFAULT_TOOLS_TERMINAL "xterm -e "/bin/sh %c"" +# define GEANY_DEFAULT_TOOLS_TERMINAL "xterm -e "/bin/sh %c"" +# define GEANY_DEFAULT_USE_NATIVE_DLGS FALSE #endif #ifdef __APPLE__ #define GEANY_DEFAULT_TOOLS_BROWSER "open -a safari" @@ -547,6 +550,7 @@ static void save_dialog_prefs(GKeyFile *config) g_key_file_set_integer(config, PACKAGE, "tab_pos_editor", interface_prefs.tab_pos_editor); g_key_file_set_integer(config, PACKAGE, "tab_pos_msgwin", interface_prefs.tab_pos_msgwin); g_key_file_set_integer(config, PACKAGE, "tab_label_length", interface_prefs.tab_label_len); + g_key_file_set_boolean(config, PACKAGE, "use_native_dialogs", interface_prefs.use_native_windows_dialogs);
/* display */ g_key_file_set_boolean(config, PACKAGE, "show_indent_guide", editor_prefs.show_indent_guide); @@ -897,6 +901,7 @@ static void load_dialog_prefs(GKeyFile *config) interface_prefs.editor_font = utils_get_setting_string(config, PACKAGE, "editor_font", GEANY_DEFAULT_FONT_EDITOR); interface_prefs.tagbar_font = utils_get_setting_string(config, PACKAGE, "tagbar_font", GEANY_DEFAULT_FONT_SYMBOL_LIST); interface_prefs.msgwin_font = utils_get_setting_string(config, PACKAGE, "msgwin_font", GEANY_DEFAULT_FONT_MSG_WINDOW); + interface_prefs.use_native_windows_dialogs = utils_get_setting_boolean(config, PACKAGE, "use_native_dialogs", GEANY_DEFAULT_USE_NATIVE_DLGS);
/* display, editor */ editor_prefs.long_line_enabled = utils_get_setting_boolean(config, PACKAGE, "long_line_enabled", TRUE);
Modified: src/prefs.c 8 lines changed, 8 insertions(+), 0 deletions(-) =================================================================== @@ -424,6 +424,10 @@ static void prefs_init_dialog(void) widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_contextaction"); gtk_entry_set_text(GTK_ENTRY(widget), tool_prefs.context_action_cmd);
+ widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_native_dialogs"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), + interface_prefs.use_native_windows_dialogs); + project_setup_prefs(); /* project files path */
@@ -900,6 +904,10 @@ on_prefs_dialog_response(GtkDialog *dialog, gint response, gpointer user_data) g_free(tool_prefs.context_action_cmd); tool_prefs.context_action_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
+ widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_native_dialogs"); + interface_prefs.use_native_windows_dialogs = + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); + project_apply_prefs(); /* project file path */
Modified: src/project.c 118 lines changed, 68 insertions(+), 50 deletions(-) =================================================================== @@ -313,11 +313,11 @@ gboolean project_load_file_with_session(const gchar *locale_file_name) }
-static void run_open_dialog(GtkDialog *dialog) +static void run_open_dialog(GtkFileChooser *dialog) { - while (gtk_dialog_run(dialog) == GTK_RESPONSE_ACCEPT) + while (dialogs_file_chooser_run(dialog) == GTK_RESPONSE_ACCEPT) { - gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + gchar *filename = gtk_file_chooser_get_filename(dialog);
if (app->project && !project_close(FALSE)) {} /* try to load the config */ @@ -326,7 +326,8 @@ static void run_open_dialog(GtkDialog *dialog) gchar *utf8_filename = utils_get_utf8_from_locale(filename);
SHOW_ERR1(_("Project file "%s" could not be loaded."), utf8_filename); - gtk_widget_grab_focus(GTK_WIDGET(dialog)); + if (GTK_IS_WIDGET(dialog)) + gtk_widget_grab_focus(GTK_WIDGET(dialog)); g_free(utf8_filename); g_free(filename); continue; @@ -341,45 +342,52 @@ void project_open(void) { const gchar *dir = local_prefs.project_file_path; gchar *locale_path; - GtkWidget *dialog; + GtkFileChooser *dialog; GtkFileFilter *filter;
- dialog = gtk_file_chooser_dialog_new(_("Open Project"), GTK_WINDOW(main_widgets.window), - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); - gtk_widget_set_name(dialog, "GeanyDialogProject"); + if (interface_prefs.use_native_windows_dialogs) + dialog = GTK_FILE_CHOOSER(gtk_file_chooser_native_new(_("Open Project"), + GTK_WINDOW(main_widgets.window), GTK_FILE_CHOOSER_ACTION_OPEN, NULL, NULL)); + else + { + dialog = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new(_("Open Project"), GTK_WINDOW(main_widgets.window), + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL)); + gtk_widget_set_name(GTK_WIDGET(dialog), "GeanyDialogProject"); + + /* set default Open, so pressing enter can open multiple files */ + gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); + gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); + gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), TRUE); + gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG); + gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(main_widgets.window)); + gtk_widget_show_all(GTK_WIDGET(dialog)); + }
- /* set default Open, so pressing enter can open multiple files */ - gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); - gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); - gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), TRUE); - gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG); - gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(main_widgets.window)); - gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE); + gtk_file_chooser_set_select_multiple(dialog, TRUE);
/* add FileFilters */ filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("All files")); gtk_file_filter_add_pattern(filter, "*"); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); + gtk_file_chooser_add_filter(dialog, filter); filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("Project files")); gtk_file_filter_add_pattern(filter, "*." GEANY_PROJECT_EXT); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); - gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter); + gtk_file_chooser_add_filter(dialog, filter); + gtk_file_chooser_set_filter(dialog, filter);
locale_path = utils_get_locale_from_utf8(dir); if (g_file_test(locale_path, G_FILE_TEST_EXISTS) && g_file_test(locale_path, G_FILE_TEST_IS_DIR)) { - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), locale_path); + gtk_file_chooser_set_current_folder(dialog, locale_path); } g_free(locale_path);
- gtk_widget_show_all(dialog); - run_open_dialog(GTK_DIALOG(dialog)); - gtk_widget_destroy(GTK_WIDGET(dialog)); + run_open_dialog(dialog); + dialogs_file_chooser_destroy(dialog); }
@@ -485,24 +493,28 @@ static void destroy_project(gboolean open_default) static void on_project_properties_base_path_button_clicked(GtkWidget *button, GtkWidget *base_path_entry) { - GtkWidget *dialog; + GtkFileChooser *dialog;
g_return_if_fail(base_path_entry != NULL); g_return_if_fail(GTK_IS_WIDGET(base_path_entry));
- dialog = gtk_file_chooser_dialog_new(_("Choose Project Base Path"), - NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - NULL); + if (interface_prefs.use_native_windows_dialogs) + dialog = GTK_FILE_CHOOSER(gtk_file_chooser_native_new(_("Choose Project Base Path"), + NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, NULL, NULL)); + else + dialog = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new(_("Choose Project Base Path"), + NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL));
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { gtk_entry_set_text(GTK_ENTRY(base_path_entry), gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog))); }
- gtk_widget_destroy(dialog); + dialogs_file_chooser_destroy(dialog); }
@@ -875,7 +887,7 @@ static gboolean update_config(const PropertyDialogElements *e, gboolean new_proj }
-static void run_dialog(GtkWidget *dialog, GtkWidget *entry) +static void run_dialog(GtkFileChooser *dialog, GtkWidget *entry) { /* set filename in the file chooser dialog */ const gchar *utf8_filename = gtk_entry_get_text(GTK_ENTRY(entry)); @@ -889,31 +901,31 @@ static void run_dialog(GtkWidget *dialog, GtkWidget *entry) * gtk_file_chooser_set_current_folder(which expects a locale filename) otherwise * we end up in the parent directory */ if (g_file_test(locale_filename, G_FILE_TEST_IS_DIR)) - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), locale_filename); + gtk_file_chooser_set_current_folder(dialog, locale_filename); else - gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), utf8_filename); + gtk_file_chooser_set_filename(dialog, utf8_filename); } else /* if the file doesn't yet exist, use at least the current directory */ { gchar *locale_dir = g_path_get_dirname(locale_filename); gchar *name = g_path_get_basename(utf8_filename);
if (g_file_test(locale_dir, G_FILE_TEST_EXISTS)) - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), locale_dir); - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), name); + gtk_file_chooser_set_current_folder(dialog, locale_dir); + gtk_file_chooser_set_current_name(dialog, name);
g_free(name); g_free(locale_dir); } } - else if (gtk_file_chooser_get_action(GTK_FILE_CHOOSER(dialog)) != GTK_FILE_CHOOSER_ACTION_OPEN) + else if (gtk_file_chooser_get_action(dialog) != GTK_FILE_CHOOSER_ACTION_OPEN) { - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), utf8_filename); + gtk_file_chooser_set_current_name(dialog, utf8_filename); } g_free(locale_filename);
/* run it */ - if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) + if (dialogs_file_chooser_run(dialog) == GTK_RESPONSE_ACCEPT) { gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gchar *tmp_utf8_filename = utils_get_utf8_from_locale(filename); @@ -923,24 +935,30 @@ static void run_dialog(GtkWidget *dialog, GtkWidget *entry) g_free(tmp_utf8_filename); g_free(filename); } - gtk_widget_destroy(dialog); + dialogs_file_chooser_destroy(dialog); }
static void on_file_save_button_clicked(GtkButton *button, PropertyDialogElements *e) { - GtkWidget *dialog; + GtkFileChooser *dialog;
/* initialise the dialog */ - dialog = gtk_file_chooser_dialog_new(_("Choose Project Filename"), NULL, - GTK_FILE_CHOOSER_ACTION_SAVE, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); - gtk_widget_set_name(dialog, "GeanyDialogProject"); - gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); - gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), TRUE); - gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG); - gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); + if (interface_prefs.use_native_windows_dialogs) + dialog = GTK_FILE_CHOOSER(gtk_file_chooser_native_new(_("Choose Project Filename"), + NULL, GTK_FILE_CHOOSER_ACTION_SAVE, NULL, NULL)); + else + { + dialog = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new(_("Choose Project Filename"), NULL, + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL)); + gtk_widget_set_name(GTK_WIDGET(dialog), "GeanyDialogProject"); + gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); + gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), TRUE); + gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG); + gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); + }
run_dialog(dialog, e->file_name); }
Modified: src/symbols.c 29 lines changed, 18 insertions(+), 11 deletions(-) =================================================================== @@ -38,6 +38,7 @@
#include "app.h" #include "callbacks.h" /* FIXME: for ignore_callback */ +#include "dialogs.h" #include "documentprivate.h" #include "editor.h" #include "encodings.h" @@ -1263,23 +1264,29 @@ int symbols_generate_global_tags(int argc, char **argv, gboolean want_preprocess
void symbols_show_load_tags_dialog(void) { - GtkWidget *dialog; + GtkFileChooser *dialog; GtkFileFilter *filter;
- dialog = gtk_file_chooser_dialog_new(_("Load Tags File"), GTK_WINDOW(main_widgets.window), - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_OK, - NULL); - gtk_widget_set_name(dialog, "GeanyDialog"); + if (interface_prefs.use_native_windows_dialogs) + dialog = GTK_FILE_CHOOSER(gtk_file_chooser_native_new(_("Load Tags File"), + GTK_WINDOW(main_widgets.window), GTK_FILE_CHOOSER_ACTION_OPEN, NULL, NULL)); + else + { + dialog = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new(_("Load Tags File"), GTK_WINDOW(main_widgets.window), + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL)); + gtk_widget_set_name(GTK_WIDGET(dialog), "GeanyDialog"); + } filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("Geany tags file (*.*.tags)")); gtk_file_filter_add_pattern(filter, "*.*.tags"); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); + gtk_file_chooser_add_filter(dialog, filter);
- if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) + if (dialogs_file_chooser_run(dialog) == GTK_RESPONSE_ACCEPT) { - GSList *flist = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)); + GSList *flist = gtk_file_chooser_get_filenames(dialog); GSList *item;
for (item = flist; item != NULL; item = g_slist_next(item)) @@ -1303,7 +1310,7 @@ void symbols_show_load_tags_dialog(void) } g_slist_free(flist); } - gtk_widget_destroy(dialog); + dialogs_file_chooser_destroy(dialog); }
Modified: src/ui_utils.c 44 lines changed, 18 insertions(+), 26 deletions(-) =================================================================== @@ -1964,55 +1964,57 @@ void ui_setup_open_button_callback(GtkWidget *open_btn, const gchar *title, }
-#ifndef G_OS_WIN32 static gchar *run_file_chooser(const gchar *title, GtkFileChooserAction action, const gchar *utf8_path) { - GtkWidget *dialog = gtk_file_chooser_dialog_new(title, - GTK_WINDOW(main_widgets.window), action, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL); + GtkFileChooser *dialog; gchar *locale_path; gchar *ret_path = NULL;
- gtk_widget_set_name(dialog, "GeanyDialog"); + if (interface_prefs.use_native_windows_dialogs) + dialog = GTK_FILE_CHOOSER(gtk_file_chooser_native_new(title, + GTK_WINDOW(main_widgets.window), action, NULL, NULL)); + else + { + dialog = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new(title, + GTK_WINDOW(main_widgets.window), action, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL)); + gtk_widget_set_name(GTK_WIDGET(dialog), "GeanyDialog"); + } + locale_path = utils_get_locale_from_utf8(utf8_path); if (action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) { if (g_path_is_absolute(locale_path) && g_file_test(locale_path, G_FILE_TEST_IS_DIR)) - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), locale_path); + gtk_file_chooser_set_current_folder(dialog, locale_path); } else if (action == GTK_FILE_CHOOSER_ACTION_OPEN) { if (g_path_is_absolute(locale_path)) - gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), locale_path); + gtk_file_chooser_set_filename(dialog, locale_path); } g_free(locale_path);
- if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) + if (dialogs_file_chooser_run(dialog) == GTK_RESPONSE_ACCEPT) { gchar *dir_locale;
- dir_locale = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + dir_locale = gtk_file_chooser_get_filename(dialog); ret_path = utils_get_utf8_from_locale(dir_locale); g_free(dir_locale); } - gtk_widget_destroy(dialog); + dialogs_file_chooser_destroy(dialog); return ret_path; } -#endif
gchar *ui_get_project_directory(const gchar *path) { gchar *utf8_path; const gchar *title = _("Select Project Base Path");
-#ifdef G_OS_WIN32 - utf8_path = win32_show_folder_dialog(ui_widgets.prefs_dialog, title, path); -#else utf8_path = run_file_chooser(title, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, path); -#endif
return utf8_path; } @@ -2035,22 +2037,12 @@ static void ui_path_box_open_clicked(GtkButton *button, gpointer user_data)
if (action == GTK_FILE_CHOOSER_ACTION_OPEN) { -#ifdef G_OS_WIN32 - utf8_path = win32_show_file_dialog(GTK_WINDOW(ui_widgets.prefs_dialog), title, - gtk_entry_get_text(GTK_ENTRY(entry))); -#else utf8_path = run_file_chooser(title, action, gtk_entry_get_text(GTK_ENTRY(entry))); -#endif } else if (action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) { gchar *path = g_path_get_dirname(gtk_entry_get_text(GTK_ENTRY(entry))); -#ifdef G_OS_WIN32 - utf8_path = win32_show_folder_dialog(ui_widgets.prefs_dialog, title, - gtk_entry_get_text(GTK_ENTRY(entry))); -#else utf8_path = run_file_chooser(title, action, path); -#endif g_free(path); }
Modified: src/ui_utils.h 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -63,7 +63,7 @@ typedef struct GeanyInterfacePrefs gboolean msgwin_compiler_visible; /**< whether message window's compiler tab is visible */ gboolean msgwin_messages_visible; /**< whether message window's messages tab is visible */ gboolean msgwin_scribble_visible; /**< whether message window's scribble tab is visible */ - /** whether to use native Windows' dialogs - ignored and not used anymore */ + /** whether to use platform-native file dialogs */ gboolean use_native_windows_dialogs; /** whether compiler messages window is automatically scrolled to show new messages */ gboolean compiler_tab_autoscroll;
Modified: src/win32.c 210 lines changed, 0 insertions(+), 210 deletions(-) =================================================================== @@ -60,216 +60,6 @@ #include <gdk/gdkwin32.h>
-/* The timer handle used to refresh windows below modal native dialogs. If - * ever more than one dialog can be shown at a time, this needs to be changed - * to be for specific dialogs. */ -static UINT_PTR dialog_timer = 0; - - -G_INLINE_FUNC void win32_dialog_reset_timer(HWND hwnd) -{ - if (G_UNLIKELY(dialog_timer != 0)) - { - KillTimer(hwnd, dialog_timer); - dialog_timer = 0; - } -} - - -static VOID CALLBACK -win32_dialog_update_main_window(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) -{ - gint i; - - /* Pump the main window loop a bit, but not enough to lock-up. - * The typical `while(gtk_events_pending()) gtk_main_iteration();` - * loop causes the entire operating system to lock-up. */ - for (i = 0; i < 4 && gtk_events_pending(); i++) - gtk_main_iteration(); - - /* Cancel any pending timers since we just did an update */ - win32_dialog_reset_timer(hwnd); -} - - -G_INLINE_FUNC UINT_PTR win32_dialog_queue_main_window_redraw(HWND dlg, UINT msg, - WPARAM wParam, LPARAM lParam, gboolean postpone) -{ - switch (msg) - { - /* Messages that likely mean the window below a dialog needs to be re-drawn. */ - case WM_WINDOWPOSCHANGED: - case WM_MOVE: - case WM_SIZE: - case WM_THEMECHANGED: - if (postpone) - { - win32_dialog_reset_timer(dlg); - dialog_timer = SetTimer(dlg, 0, 33 /* around 30fps */, win32_dialog_update_main_window); - } - else - win32_dialog_update_main_window(dlg, msg, wParam, lParam); - break; - } - return 0; /* always let the default proc handle it */ -} - - -/* This function is called for OPENFILENAME lpfnHook function and it establishes - * a timer that is reset each time which will update the main window loop eventually. */ -static UINT_PTR CALLBACK win32_dialog_explorer_hook_proc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - return win32_dialog_queue_main_window_redraw(dlg, msg, wParam, lParam, TRUE); -} - - -/* This function is called for old-school win32 dialogs that accept a proper - * lpfnHook function for all messages, it doesn't use a timer. */ -static UINT_PTR CALLBACK win32_dialog_hook_proc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - return win32_dialog_queue_main_window_redraw(dlg, msg, wParam, lParam, FALSE); -} - - -/* Converts the given UTF-8 filename or directory name into something usable for Windows and - * returns the directory part of the given filename. */ -static wchar_t *get_dir_for_path(const gchar *utf8_filename) -{ - static wchar_t w_dir[MAX_PATH]; - gchar *result; - - if (g_file_test(utf8_filename, G_FILE_TEST_IS_DIR)) - result = (gchar*) utf8_filename; - else - result = g_path_get_dirname(utf8_filename); - - MultiByteToWideChar(CP_UTF8, 0, result, -1, w_dir, G_N_ELEMENTS(w_dir)); - - if (result != utf8_filename) - g_free(result); - - return w_dir; -} - - -/* Callback function for setting the initial directory of the folder open dialog. This could also - * be done with BROWSEINFO.pidlRoot and SHParseDisplayName but SHParseDisplayName is not available - * on systems below Windows XP. So, we go the hard way by creating a callback which will set up the - * folder when the dialog is initialised. Yeah, I like Windows. */ -static INT CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lp, LPARAM pData) -{ - win32_dialog_hook_proc(hwnd, uMsg, lp, pData); - switch (uMsg) - { - case BFFM_INITIALIZED: - { - SendMessageW(hwnd, BFFM_SETSELECTIONW, TRUE, pData); - break; - } - case BFFM_SELCHANGED: - { - /* set the status window to the currently selected path. */ - static wchar_t szDir[MAX_PATH]; - if (SHGetPathFromIDListW((LPITEMIDLIST) lp, szDir)) - { - SendMessageW(hwnd, BFFM_SETSTATUSTEXTW, 0, (LPARAM) szDir); - } - break; - } - } - return 0; -} - - -/* Shows a folder selection dialog. - * initial_dir is expected in UTF-8 - * The selected folder name is returned. */ -gchar *win32_show_folder_dialog(GtkWidget *parent, const gchar *title, const gchar *initial_dir) -{ - BROWSEINFOW bi; - LPITEMIDLIST pidl; - gchar *result = NULL; - wchar_t fname[MAX_PATH]; - wchar_t w_title[512]; - - MultiByteToWideChar(CP_UTF8, 0, title, -1, w_title, G_N_ELEMENTS(w_title)); - - if (parent == NULL) - parent = main_widgets.window; - - memset(&bi, 0, sizeof bi); - bi.hwndOwner = GDK_WINDOW_HWND(gtk_widget_get_window(parent)); - bi.pidlRoot = NULL; - bi.lpszTitle = w_title; - bi.lpfn = BrowseCallbackProc; - bi.lParam = (LPARAM) get_dir_for_path(initial_dir); - bi.ulFlags = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_USENEWUI; - - pidl = SHBrowseForFolderW(&bi); - - /* convert the strange Windows folder list item something into an usual path string ;-) */ - if (pidl != NULL) - { - if (SHGetPathFromIDListW(pidl, fname)) - { - result = g_malloc0(MAX_PATH * 2); - WideCharToMultiByte(CP_UTF8, 0, fname, -1, result, MAX_PATH * 2, NULL, NULL); - } - CoTaskMemFree(pidl); - } - return result; -} - - -/* initial_dir can be NULL to use the current working directory. - * Returns: the selected filename */ -gchar *win32_show_file_dialog(GtkWindow *parent, const gchar *title, const gchar *initial_file) -{ - OPENFILENAMEW of; - gint retval; - gchar tmp[MAX_PATH]; - wchar_t w_file[MAX_PATH]; - wchar_t w_title[512]; - - w_file[0] = '\0'; - - if (initial_file != NULL) - MultiByteToWideChar(CP_UTF8, 0, initial_file, -1, w_file, G_N_ELEMENTS(w_file)); - - MultiByteToWideChar(CP_UTF8, 0, title, -1, w_title, G_N_ELEMENTS(w_title)); - - /* initialise file dialog info struct */ - memset(&of, 0, sizeof of); - of.lStructSize = sizeof of; - of.hwndOwner = GDK_WINDOW_HWND(gtk_widget_get_window(GTK_WIDGET(parent))); - - of.lpstrFile = w_file; - of.nMaxFile = 2048; - of.lpstrFileTitle = NULL; - of.lpstrTitle = w_title; - of.lpstrDefExt = L""; - of.Flags = OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_ENABLEHOOK | OFN_ENABLESIZING; - of.lpfnHook = win32_dialog_explorer_hook_proc; - retval = GetOpenFileNameW(&of); - - if (! retval) - { - if (CommDlgExtendedError()) - { - gchar *error = g_strdup_printf( - "File dialog box error (%x)", (gint) CommDlgExtendedError()); - win32_message_dialog(NULL, GTK_MESSAGE_ERROR, error); - g_free(error); - } - return NULL; - } - - WideCharToMultiByte(CP_UTF8, 0, w_file, -1, tmp, sizeof(tmp), NULL, NULL); - - return g_strdup(tmp); -} - - /* Creates a native Windows message box of the given type and returns always TRUE * or FALSE representing th pressed Yes or No button. * If type is not GTK_MESSAGE_QUESTION, it returns always TRUE. */
Modified: src/win32.h 4 lines changed, 0 insertions(+), 4 deletions(-) =================================================================== @@ -30,15 +30,11 @@
G_BEGIN_DECLS
-gchar *win32_show_file_dialog(GtkWindow *parent, const gchar *title, const gchar *initial_dir); - gboolean win32_message_dialog(GtkWidget *parent, GtkMessageType type, const gchar *msg);
void win32_open_browser(const gchar *uri);
-gchar *win32_show_folder_dialog(GtkWidget *parent, const gchar *title, const gchar *initial_dir); - gint win32_check_write_permission(const gchar *dir);
void win32_init_debug_code(void);
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).