SF.net SVN: geany:[5837] trunk

colombanw at users.sourceforge.net colombanw at xxxxx
Fri Jun 10 22:13:30 UTC 2011


Revision: 5837
          http://geany.svn.sourceforge.net/geany/?rev=5837&view=rev
Author:   colombanw
Date:     2011-06-10 22:13:29 +0000 (Fri, 10 Jun 2011)

Log Message:
-----------
Always destroy open and save dialog after use

Create and destroy the file open/save dialogs on each call rather than
keeping the same dialog around.  This avoids letting GTK monitor the
displayed directory for changes, thus probably reducing overhead and
works around GTK monitoring bugs.

This refactors the code a bit now it works a little differently.

Also fixes a bug that made dialogs_show_save_as() wrongly return the
first user response rather than the one that is actually used to make
the decision.  It happened for example when the user first selected an
non-writable location, or was asked whether to override a file and
answered "no".

Closes/references:
https://sourceforge.net/tracker/?func=detail&aid=3311687&group_id=153444&atid=787793
https://sourceforge.net/tracker/?func=detail&aid=3311258&group_id=153444&atid=787791
https://sourceforge.net/tracker/?func=detail&aid=3304273&group_id=153444&atid=787791
https://sourceforge.net/tracker/?func=detail&aid=3201050&group_id=153444&atid=787791
https://sourceforge.net/tracker/?func=detail&aid=3163742&group_id=153444&atid=787791
https://sourceforge.net/tracker/?func=detail&aid=3153120&group_id=153444&atid=787791
https://sourceforge.net/tracker/?func=detail&aid=2985896&group_id=153444&atid=787791
https://bugs.launchpad.net/ubuntu/+source/geany/+bug/754577

Dialog state restoration based on a patch by Matthew Brush, thanks.

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/src/dialogs.c
    trunk/src/main.c
    trunk/src/ui_utils.h

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2011-06-10 10:26:01 UTC (rev 5836)
+++ trunk/ChangeLog	2011-06-10 22:13:29 UTC (rev 5837)
@@ -1,3 +1,11 @@
+2011-06-11  Colomban Wendling  <colomban(at)geany(dot)org>
+
+ * src/dialogs.c, src/main.c, src/ui_utils.h:
+   Always destroy open and save dialog after use. This also helps
+   working around a long-living GTK+ bug, hopefully closing #3311258,
+   #3304273, #3201050, #3163742, #3153120 and #2985896.
+
+
 2011-06-03  Colomban Wendling  <colomban(at)geany(dot)org>
 
  * src/callbacks.c, src/document.c, src/document.h, src/editor.c,

Modified: trunk/src/dialogs.c
===================================================================
--- trunk/src/dialogs.c	2011-06-10 10:26:01 UTC (rev 5836)
+++ trunk/src/dialogs.c	2011-06-10 22:13:29 UTC (rev 5837)
@@ -66,45 +66,91 @@
 };
 
 
-static gboolean handle_save_as(const gchar *utf8_filename, gboolean open_new_tab,
-	gboolean rename_file);
+static struct FileSelState
+{
+	struct
+	{
+		guint filter_idx;
+		gint encoding_idx;
+		gint filetype_idx;
+		gboolean show_hidden;
+		gboolean more_options_visible;
+	} open;
+	struct
+	{
+		gboolean open_in_new_tab;
+	} save;
+}
+filesel_state = {
+	{ 0, 0, 0, FALSE, FALSE },
+	{ FALSE }
+};
 
 
-static GtkWidget *add_file_open_extra_widget(void);
+/* gets the ID of the current file filter */
+static guint file_chooser_get_filter_idx(GtkFileChooser *chooser)
+{
+	guint idx = 0;
+	GtkFileFilter *current;
+	GSList *filters, *item;
 
+	current = gtk_file_chooser_get_filter(chooser);
+	filters = gtk_file_chooser_list_filters(chooser);
+	foreach_slist(item, filters)
+	{
+		if (item->data == current)
+			break;
+		idx ++;
+	}
+	g_slist_free(filters);
+	return idx;
+}
 
-static void
-on_file_open_dialog_response           (GtkDialog *dialog,
-                                        gint response,
-                                        gpointer user_data)
+
+/* sets the current file filter from its ID */
+static void file_chooser_set_filter_idx(GtkFileChooser *chooser, guint idx)
 {
-	gtk_widget_hide(ui_widgets.open_filesel);
+	GtkFileFilter *current;
+	GSList *filters;
 
+	filters = gtk_file_chooser_list_filters(chooser);
+	current = g_slist_nth_data(filters, idx);
+	g_slist_free(filters);
+	gtk_file_chooser_set_filter(chooser, current);
+}
+
+
+static void open_file_dialog_handle_response(GtkWidget *dialog, gint response)
+{
 	if (response == GTK_RESPONSE_ACCEPT || response == GEANY_RESPONSE_VIEW)
 	{
 		GSList *filelist;
-		gint filetype_idx = gtk_combo_box_get_active(GTK_COMBO_BOX(
-						ui_lookup_widget(GTK_WIDGET(dialog), "filetype_combo")));
 		gint encoding_idx;
 		GtkTreeModel *encoding_model;
 		GtkTreeIter encoding_iter;
 		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 = gtk_combo_box_get_active(GTK_COMBO_BOX(filetype_combo));
+		filesel_state.open.encoding_idx = gtk_combo_box_get_active(GTK_COMBO_BOX(encoding_combo));
+
 		/* ignore detect from file item */
-		if (filetype_idx > 0)
-			ft = g_slist_nth_data(filetypes_by_title, filetype_idx);
+		if (filesel_state.open.filetype_idx > 0)
+			ft = g_slist_nth_data(filetypes_by_title, filesel_state.open.filetype_idx);
 
-		encoding_model = gtk_combo_box_get_model(GTK_COMBO_BOX(
-			ui_lookup_widget(GTK_WIDGET(dialog), "encoding_combo")));
-		gtk_combo_box_get_active_iter(GTK_COMBO_BOX(
-			ui_lookup_widget(GTK_WIDGET(dialog), "encoding_combo")), &encoding_iter);
+		encoding_model = gtk_combo_box_get_model(GTK_COMBO_BOX(encoding_combo));
+		gtk_combo_box_get_active_iter(GTK_COMBO_BOX(encoding_combo), &encoding_iter);
 		gtk_tree_model_get(encoding_model, &encoding_iter, 0, &encoding_idx, -1);
 		if (encoding_idx >= 0 && encoding_idx < GEANY_ENCODINGS_MAX)
 			charset = encodings[encoding_idx].charset;
 
-		filelist = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(ui_widgets.open_filesel));
+		filelist = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
 		if (filelist != NULL)
 		{
 			document_open_files(filelist, ro, ft, charset);
@@ -113,7 +159,7 @@
 		g_slist_free(filelist);
 	}
 	if (app->project && NZV(app->project->base_path))
-		gtk_file_chooser_remove_shortcut_folder(GTK_FILE_CHOOSER(ui_widgets.open_filesel),
+		gtk_file_chooser_remove_shortcut_folder(GTK_FILE_CHOOSER(dialog),
 			app->project->base_path, NULL);
 }
 
@@ -132,11 +178,10 @@
 
 
 static void
-on_file_open_check_hidden_toggled(GtkToggleButton *togglebutton, gpointer user_data)
+on_file_open_check_hidden_toggled(GtkToggleButton *togglebutton, GtkWidget *dialog)
 {
-	gboolean is_on = gtk_toggle_button_get_active(togglebutton);
-
-	gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(ui_widgets.open_filesel), is_on);
+	filesel_state.open.show_hidden = gtk_toggle_button_get_active(togglebutton);
+	gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(dialog), filesel_state.open.show_hidden);
 }
 
 
@@ -228,49 +273,118 @@
 }
 
 
-static void create_open_file_dialog(void)
+static GtkWidget *add_file_open_extra_widget(GtkWidget *dialog)
 {
+	GtkWidget *expander, *vbox, *table, *check_hidden;
+	GtkWidget *filetype_ebox, *filetype_label, *filetype_combo;
+	GtkWidget *encoding_ebox, *encoding_label, *encoding_combo;
+
+	expander = gtk_expander_new_with_mnemonic(_("_More Options"));
+	vbox = gtk_vbox_new(FALSE, 6);
+	gtk_container_add(GTK_CONTAINER(expander), vbox);
+
+	table = gtk_table_new(2, 4, FALSE);
+
+	/* line 1 with checkbox and encoding combo */
+	check_hidden = gtk_check_button_new_with_mnemonic(_("Show _hidden files"));
+	gtk_widget_show(check_hidden);
+	gtk_table_attach(GTK_TABLE(table), check_hidden, 0, 1, 0, 1,
+					(GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
+					(GtkAttachOptions) (0), 0, 5);
+
+	/* spacing */
+	gtk_table_attach(GTK_TABLE(table), gtk_label_new(""), 1, 2, 0, 1,
+					(GtkAttachOptions) (GTK_FILL),
+					(GtkAttachOptions) (0), 5, 5);
+
+	encoding_label = gtk_label_new(_("Set encoding:"));
+	gtk_misc_set_alignment(GTK_MISC(encoding_label), 1, 0);
+	gtk_table_attach(GTK_TABLE(table), encoding_label, 2, 3, 0, 1,
+					(GtkAttachOptions) (GTK_FILL),
+					(GtkAttachOptions) (0), 4, 5);
+	/* the ebox is for the tooltip, because gtk_combo_box can't show tooltips */
+	encoding_ebox = gtk_event_box_new();
+	encoding_combo = gtk_combo_box_new();
+	ui_widget_set_tooltip_text(encoding_ebox,
+		_("Explicitly defines an encoding for the file, if it would not be detected. This is useful when you know that the encoding of a file cannot be detected correctly by Geany.\nNote if you choose multiple files, they will all be opened with the chosen encoding."));
+	gtk_container_add(GTK_CONTAINER(encoding_ebox), encoding_combo);
+	gtk_table_attach(GTK_TABLE(table), encoding_ebox, 3, 4, 0, 1,
+					(GtkAttachOptions) (GTK_FILL),
+					(GtkAttachOptions) (0), 0, 5);
+
+	/* line 2 with filetype combo */
+	filetype_label = gtk_label_new(_("Set filetype:"));
+	gtk_misc_set_alignment(GTK_MISC(filetype_label), 1, 0);
+	gtk_table_attach(GTK_TABLE(table), filetype_label, 2, 3, 1, 2,
+					(GtkAttachOptions) (GTK_FILL),
+					(GtkAttachOptions) (0), 4, 5);
+	/* the ebox is for the tooltip, because gtk_combo_box can't show tooltips */
+	filetype_ebox = gtk_event_box_new();
+	filetype_combo = gtk_combo_box_new_text();
+	gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(filetype_combo), 2);
+	ui_widget_set_tooltip_text(filetype_ebox,
+		_("Explicitly defines a filetype for the file, if it would not be detected by filename extension.\nNote if you choose multiple files, they will all be opened with the chosen filetype."));
+	gtk_container_add(GTK_CONTAINER(filetype_ebox), filetype_combo);
+	gtk_table_attach(GTK_TABLE(table), filetype_ebox, 3, 4, 1, 2,
+					(GtkAttachOptions) (GTK_FILL),
+					(GtkAttachOptions) (0), 0, 5);
+
+	gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
+	gtk_widget_show_all(vbox);
+
+	g_signal_connect(check_hidden, "toggled", G_CALLBACK(on_file_open_check_hidden_toggled), dialog);
+
+	ui_hookup_widget(dialog, expander, "more_options_expander");
+	ui_hookup_widget(dialog, check_hidden, "check_hidden");
+	ui_hookup_widget(dialog, filetype_combo, "filetype_combo");
+	ui_hookup_widget(dialog, encoding_combo, "encoding_combo");
+
+	return expander;
+}
+
+
+static GtkWidget *create_open_file_dialog(void)
+{
+	GtkWidget *dialog;
 	GtkWidget *filetype_combo, *encoding_combo;
 	GtkWidget *viewbtn;
 	GtkCellRenderer *encoding_renderer;
 	GtkTreeIter encoding_iter;
 	GSList *node;
 
-	ui_widgets.open_filesel = gtk_file_chooser_dialog_new(_("Open File"), GTK_WINDOW(main_widgets.window),
+	dialog = gtk_file_chooser_dialog_new(_("Open File"), GTK_WINDOW(main_widgets.window),
 			GTK_FILE_CHOOSER_ACTION_OPEN, NULL, NULL);
-	gtk_widget_set_name(ui_widgets.open_filesel, "GeanyDialog");
+	gtk_widget_set_name(dialog, "GeanyDialog");
 
-	viewbtn = gtk_dialog_add_button(GTK_DIALOG(ui_widgets.open_filesel), _("_View"),
-				GEANY_RESPONSE_VIEW);
+	viewbtn = gtk_dialog_add_button(GTK_DIALOG(dialog), _("_View"), GEANY_RESPONSE_VIEW);
 	ui_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(ui_widgets.open_filesel),
+	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(ui_widgets.open_filesel), GTK_RESPONSE_ACCEPT);
+	gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
 
-	gtk_widget_set_size_request(ui_widgets.open_filesel, -1, 460);
-	gtk_window_set_modal(GTK_WINDOW(ui_widgets.open_filesel), TRUE);
-	gtk_window_set_destroy_with_parent(GTK_WINDOW(ui_widgets.open_filesel), TRUE);
-	gtk_window_set_skip_taskbar_hint(GTK_WINDOW(ui_widgets.open_filesel), FALSE);
-	gtk_window_set_type_hint(GTK_WINDOW(ui_widgets.open_filesel), GDK_WINDOW_TYPE_HINT_DIALOG);
-	gtk_window_set_transient_for(GTK_WINDOW(ui_widgets.open_filesel), GTK_WINDOW(main_widgets.window));
-	gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(ui_widgets.open_filesel), TRUE);
+	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);
 	if (gtk_check_version(2, 14, 0) == NULL)
-		gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(ui_widgets.open_filesel), FALSE);
+		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(ui_widgets.open_filesel),
-		add_file_open_extra_widget());
-	filetype_combo = ui_lookup_widget(ui_widgets.open_filesel, "filetype_combo");
+	gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(dialog), add_file_open_extra_widget(dialog));
+	filetype_combo = ui_lookup_widget(dialog, "filetype_combo");
 
 	gtk_combo_box_append_text(GTK_COMBO_BOX(filetype_combo), _("Detect by file extension"));
 	/* add FileFilters(start with "All Files") */
-	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(ui_widgets.open_filesel),
+	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog),
 				filetypes_create_file_filter(filetypes[GEANY_FILETYPES_NONE]));
 	/* now create meta filter "All Source" */
-	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(ui_widgets.open_filesel),
+	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog),
 				filetypes_create_file_filter_all_source());
 	foreach_slist(node, filetypes_by_title)
 	{
@@ -279,33 +393,57 @@
 		if (G_UNLIKELY(ft->id == GEANY_FILETYPES_NONE))
 			continue;
 		gtk_combo_box_append_text(GTK_COMBO_BOX(filetype_combo), ft->title);
-		gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(ui_widgets.open_filesel),
-				filetypes_create_file_filter(ft));
+		gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filetypes_create_file_filter(ft));
 	}
 	gtk_combo_box_set_active(GTK_COMBO_BOX(filetype_combo), 0);
 
 	/* fill encoding combo box */
-	encoding_combo = ui_lookup_widget(ui_widgets.open_filesel, "encoding_combo");
+	encoding_combo = ui_lookup_widget(dialog, "encoding_combo");
 	gtk_combo_box_set_model(GTK_COMBO_BOX(encoding_combo), GTK_TREE_MODEL(
-		create_encoding_combo_store(&encoding_iter)));
+			create_encoding_combo_store(&encoding_iter)));
 	gtk_combo_box_set_active_iter(GTK_COMBO_BOX(encoding_combo), &encoding_iter);
 	encoding_renderer = gtk_cell_renderer_text_new();
 	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(encoding_combo), encoding_renderer, TRUE);
 	gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(encoding_combo), encoding_renderer, "text", 1);
 	gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(encoding_combo), encoding_renderer,
-		encoding_combo_cell_data_func, NULL, NULL);
+			encoding_combo_cell_data_func, NULL, NULL);
 
-	g_signal_connect(ui_widgets.open_filesel, "notify::show-hidden",
-				G_CALLBACK(on_file_open_notify), NULL);
-	g_signal_connect(ui_widgets.open_filesel, "delete-event",
-				G_CALLBACK(gtk_widget_hide_on_delete), NULL);
-	g_signal_connect(ui_widgets.open_filesel, "response",
-				G_CALLBACK(on_file_open_dialog_response), NULL);
+	g_signal_connect(dialog, "notify::show-hidden", G_CALLBACK(on_file_open_notify), NULL);
+
+	return dialog;
 }
 
 
+static void open_file_dialog_apply_settings(GtkWidget *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 retreive it the first time */
+	if (! initialized)
+	{
+		filesel_state.open.filter_idx = file_chooser_get_filter_idx(GTK_FILE_CHOOSER(dialog));
+		filesel_state.open.filetype_idx = gtk_combo_box_get_active(GTK_COMBO_BOX(filetype_combo));
+		filesel_state.open.encoding_idx = gtk_combo_box_get_active(GTK_COMBO_BOX(encoding_combo));
+
+		initialized = TRUE;
+	}
+	else
+	{
+		file_chooser_set_filter_idx(GTK_FILE_CHOOSER(dialog), filesel_state.open.filter_idx);
+		gtk_combo_box_set_active(GTK_COMBO_BOX(filetype_combo), filesel_state.open.filetype_idx);
+		gtk_combo_box_set_active(GTK_COMBO_BOX(encoding_combo), filesel_state.open.encoding_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);
+}
+
+
 /* This shows the file selection dialog to open a file. */
-void dialogs_show_open_file()
+void dialogs_show_open_file(void)
 {
 	gchar *initdir;
 
@@ -325,103 +463,29 @@
 	else
 #endif
 	{
-		/* We use the same file selection widget each time, so first of all we create it
-		 * if it hasn't already been created. */
-		if (ui_widgets.open_filesel == NULL)
-			create_open_file_dialog();
+		GtkWidget *dialog = create_open_file_dialog();
+		gint response;
 
-		if (initdir != NULL)
-		{
-			if (g_path_is_absolute(initdir))
-				gtk_file_chooser_set_current_folder(
-					GTK_FILE_CHOOSER(ui_widgets.open_filesel), initdir);
-		}
+		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);
+
 		if (app->project && NZV(app->project->base_path))
-			gtk_file_chooser_add_shortcut_folder(GTK_FILE_CHOOSER(ui_widgets.open_filesel),
-				app->project->base_path, NULL);
+			gtk_file_chooser_add_shortcut_folder(GTK_FILE_CHOOSER(dialog),
+					app->project->base_path, NULL);
 
-		gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(ui_widgets.open_filesel));
-		gtk_window_present(GTK_WINDOW(ui_widgets.open_filesel));
+		response = gtk_dialog_run(GTK_DIALOG(dialog));
+		open_file_dialog_handle_response(dialog, response);
+		gtk_widget_destroy(dialog);
 	}
 	g_free(initdir);
 }
 
 
-static GtkWidget *add_file_open_extra_widget()
-{
-	GtkWidget *expander, *vbox, *table, *check_hidden;
-	GtkWidget *filetype_ebox, *filetype_label, *filetype_combo;
-	GtkWidget *encoding_ebox, *encoding_label, *encoding_combo;
-
-	expander = gtk_expander_new_with_mnemonic(_("_More Options"));
-	vbox = gtk_vbox_new(FALSE, 6);
-	gtk_container_add(GTK_CONTAINER(expander), vbox);
-
-	table = gtk_table_new(2, 4, FALSE);
-
-	/* line 1 with checkbox and encoding combo */
-	check_hidden = gtk_check_button_new_with_mnemonic(_("Show _hidden files"));
-	gtk_widget_show(check_hidden);
-	gtk_table_attach(GTK_TABLE(table), check_hidden, 0, 1, 0, 1,
-					(GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
-					(GtkAttachOptions) (0), 0, 5);
-
-	/* spacing */
-	gtk_table_attach(GTK_TABLE(table), gtk_label_new(""), 1, 2, 0, 1,
-					(GtkAttachOptions) (GTK_FILL),
-					(GtkAttachOptions) (0), 5, 5);
-
-	encoding_label = gtk_label_new(_("Set encoding:"));
-	gtk_misc_set_alignment(GTK_MISC(encoding_label), 1, 0);
-	gtk_table_attach(GTK_TABLE(table), encoding_label, 2, 3, 0, 1,
-					(GtkAttachOptions) (GTK_FILL),
-					(GtkAttachOptions) (0), 4, 5);
-	/* the ebox is for the tooltip, because gtk_combo_box can't show tooltips */
-	encoding_ebox = gtk_event_box_new();
-	encoding_combo = gtk_combo_box_new();
-	ui_widget_set_tooltip_text(encoding_ebox,
-		_("Explicitly defines an encoding for the file, if it would not be detected. This is useful when you know that the encoding of a file cannot be detected correctly by Geany.\nNote if you choose multiple files, they will all be opened with the chosen encoding."));
-	gtk_container_add(GTK_CONTAINER(encoding_ebox), encoding_combo);
-	gtk_table_attach(GTK_TABLE(table), encoding_ebox, 3, 4, 0, 1,
-					(GtkAttachOptions) (GTK_FILL),
-					(GtkAttachOptions) (0), 0, 5);
-
-	/* line 2 with filetype combo */
-	filetype_label = gtk_label_new(_("Set filetype:"));
-	gtk_misc_set_alignment(GTK_MISC(filetype_label), 1, 0);
-	gtk_table_attach(GTK_TABLE(table), filetype_label, 2, 3, 1, 2,
-					(GtkAttachOptions) (GTK_FILL),
-					(GtkAttachOptions) (0), 4, 5);
-	/* the ebox is for the tooltip, because gtk_combo_box can't show tooltips */
-	filetype_ebox = gtk_event_box_new();
-	filetype_combo = gtk_combo_box_new_text();
-	gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(filetype_combo), 2);
-	ui_widget_set_tooltip_text(filetype_ebox,
-		_("Explicitly defines a filetype for the file, if it would not be detected by filename extension.\nNote if you choose multiple files, they will all be opened with the chosen filetype."));
-	gtk_container_add(GTK_CONTAINER(filetype_ebox), filetype_combo);
-	gtk_table_attach(GTK_TABLE(table), filetype_ebox, 3, 4, 1, 2,
-					(GtkAttachOptions) (GTK_FILL),
-					(GtkAttachOptions) (0), 0, 5);
-
-	gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
-	gtk_widget_show_all(vbox);
-
-	g_signal_connect(check_hidden, "toggled",
-				G_CALLBACK(on_file_open_check_hidden_toggled), NULL);
-
-	ui_hookup_widget(ui_widgets.open_filesel, check_hidden, "check_hidden");
-	ui_hookup_widget(ui_widgets.open_filesel, filetype_combo, "filetype_combo");
-	ui_hookup_widget(ui_widgets.open_filesel, encoding_combo, "encoding_combo");
-
-	return expander;
-}
-
-
 static void on_save_as_new_tab_toggled(GtkToggleButton *togglebutton, gpointer user_data)
 {
-	gtk_widget_set_sensitive(GTK_WIDGET(user_data),
-		! gtk_toggle_button_get_active(togglebutton));
+	gtk_widget_set_sensitive(GTK_WIDGET(user_data), ! gtk_toggle_button_get_active(togglebutton));
 }
 
 
@@ -457,14 +521,11 @@
 }
 
 
-static void
-on_file_save_dialog_response           (GtkDialog *dialog,
-                                        gint response,
-                                        gpointer user_data)
+static gboolean save_as_dialog_handle_response(GtkWidget *dialog, gint response)
 {
 	gboolean rename_file = FALSE;
 	gboolean success = FALSE;
-	gchar *new_filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(ui_widgets.save_filesel));
+	gchar *new_filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
 
 	switch (response)
 	{
@@ -485,95 +546,92 @@
 		case GTK_RESPONSE_ACCEPT:
 		{
 			gboolean open_new_tab = gtk_toggle_button_get_active(
-					GTK_TOGGLE_BUTTON(ui_lookup_widget(ui_widgets.save_filesel, "check_open_new_tab")));
+					GTK_TOGGLE_BUTTON(ui_lookup_widget(dialog, "check_open_new_tab")));
 			gchar *utf8_filename;
 
 			utf8_filename = utils_get_utf8_from_locale(new_filename);
 			success = handle_save_as(utf8_filename, open_new_tab, rename_file);
 
+			if (success)
+				filesel_state.save.open_in_new_tab = open_new_tab;
+
 			g_free(utf8_filename);
 			break;
 		}
+		case GTK_RESPONSE_DELETE_EVENT:
 		case GTK_RESPONSE_CANCEL:
 			success = TRUE;
 			break;
 	}
 	g_free(new_filename);
 
-	if (success)
-		gtk_widget_hide(ui_widgets.save_filesel);
+	return success;
 }
 
 
-static void create_save_file_dialog(void)
+static GtkWidget *create_save_file_dialog(void)
 {
-	GtkWidget *vbox, *check_open_new_tab, *rename_btn;
+	GtkWidget *dialog, *vbox, *check_open_new_tab, *rename_btn;
 	const gchar *initdir;
 
-	ui_widgets.save_filesel = gtk_file_chooser_dialog_new(_("Save File"), GTK_WINDOW(main_widgets.window),
+	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(ui_widgets.save_filesel), TRUE);
-	gtk_window_set_destroy_with_parent(GTK_WINDOW(ui_widgets.save_filesel), TRUE);
-	gtk_window_set_skip_taskbar_hint(GTK_WINDOW(ui_widgets.save_filesel), FALSE);
-	gtk_window_set_type_hint(GTK_WINDOW(ui_widgets.save_filesel), GDK_WINDOW_TYPE_HINT_DIALOG);
-	gtk_widget_set_name(ui_widgets.save_filesel, "GeanyDialog");
+	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(ui_widgets.save_filesel), _("R_ename"),
-					GEANY_RESPONSE_RENAME);
+	rename_btn = gtk_dialog_add_button(GTK_DIALOG(dialog), _("R_ename"), GEANY_RESPONSE_RENAME);
 	ui_widget_set_tooltip_text(rename_btn, _("Save the file and rename it"));
 
-	gtk_dialog_add_buttons(GTK_DIALOG(ui_widgets.save_filesel),
+	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(ui_widgets.save_filesel), GTK_RESPONSE_ACCEPT);
+	gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
 
 	vbox = gtk_vbox_new(FALSE, 0);
 	check_open_new_tab = gtk_check_button_new_with_mnemonic(_("_Open file in a new tab"));
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_open_new_tab), filesel_state.save.open_in_new_tab);
 	ui_widget_set_tooltip_text(check_open_new_tab,
 		_("Keep the current unsaved document open"
 		" and open the newly saved file in a new tab"));
 	gtk_box_pack_start(GTK_BOX(vbox), check_open_new_tab, FALSE, FALSE, 0);
 	gtk_widget_show_all(vbox);
-	gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(ui_widgets.save_filesel), vbox);
-	gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(ui_widgets.save_filesel), TRUE);
+	gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(dialog), vbox);
+	gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
 	if (gtk_check_version(2, 14, 0) == NULL)
-		gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(ui_widgets.save_filesel), FALSE);
+		gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(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(ui_widgets.save_filesel), linitdir);
+		gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), linitdir);
 		g_free(linitdir);
 	}
 
 	g_signal_connect(check_open_new_tab, "toggled",
 				G_CALLBACK(on_save_as_new_tab_toggled), rename_btn);
 
-	ui_hookup_widget(ui_widgets.save_filesel, check_open_new_tab, "check_open_new_tab");
+	ui_hookup_widget(dialog, check_open_new_tab, "check_open_new_tab");
 
-	g_signal_connect(ui_widgets.save_filesel, "delete-event",
-		G_CALLBACK(gtk_widget_hide_on_delete), NULL);
-	g_signal_connect(ui_widgets.save_filesel, "response",
-		G_CALLBACK(on_file_save_dialog_response), NULL);
-
-	gtk_window_set_transient_for(GTK_WINDOW(ui_widgets.save_filesel), GTK_WINDOW(main_widgets.window));
+	return dialog;
 }
 
 
-static gboolean gtk_show_save_as(void)
+static gboolean show_save_as_gtk(void)
 {
+	GtkWidget *dialog;
 	GeanyDocument *doc = document_get_current();
 	gint resp;
 
 	g_return_val_if_fail(doc != NULL, FALSE);
 
-	if (G_UNLIKELY(ui_widgets.save_filesel == NULL))
-		create_save_file_dialog();
+	dialog = create_save_file_dialog();
 
-	gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(ui_widgets.save_filesel));
-
 	if (doc->file_name != NULL)
 	{
 		if (g_path_is_absolute(doc->file_name))
@@ -582,18 +640,15 @@
 			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(ui_widgets.save_filesel),
-				locale_dirname);
-			gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(ui_widgets.save_filesel),
-				locale_basename);
+			gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), locale_dirname);
+			gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(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(ui_widgets.save_filesel),
-				doc->file_name);
+			gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), doc->file_name);
 	}
 	else
 	{
@@ -605,22 +660,28 @@
 		else
 			fname = g_strdup(GEANY_STRING_UNTITLED);
 
-		gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(ui_widgets.save_filesel), fname);
+		gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), fname);
 
 		g_free(fname);
 	}
 
 	if (app->project && NZV(app->project->base_path))
-		gtk_file_chooser_add_shortcut_folder(GTK_FILE_CHOOSER(ui_widgets.save_filesel),
+		gtk_file_chooser_add_shortcut_folder(GTK_FILE_CHOOSER(dialog),
 			app->project->base_path, NULL);
 
 	/* Run the dialog synchronously, pausing this function call */
-	resp = gtk_dialog_run(GTK_DIALOG(ui_widgets.save_filesel));
+	do
+	{
+		resp = gtk_dialog_run(GTK_DIALOG(dialog));
+	}
+	while (! save_as_dialog_handle_response(dialog, resp));
 
 	if (app->project && NZV(app->project->base_path))
-		gtk_file_chooser_remove_shortcut_folder(GTK_FILE_CHOOSER(ui_widgets.save_filesel),
+		gtk_file_chooser_remove_shortcut_folder(GTK_FILE_CHOOSER(dialog),
 			app->project->base_path, NULL);
 
+	gtk_widget_destroy(dialog);
+
 	return (resp == GTK_RESPONSE_ACCEPT);
 }
 
@@ -645,7 +706,7 @@
 	}
 	else
 #endif
-	result = gtk_show_save_as();
+	result = show_save_as_gtk();
 	return result;
 }
 

Modified: trunk/src/main.c
===================================================================
--- trunk/src/main.c	2011-06-10 10:26:01 UTC (rev 5836)
+++ trunk/src/main.c	2011-06-10 22:13:29 UTC (rev 5837)
@@ -232,8 +232,6 @@
 	app->project			= NULL;
 	ui_widgets.open_fontsel		= NULL;
 	ui_widgets.open_colorsel	= NULL;
-	ui_widgets.open_filesel		= NULL;
-	ui_widgets.save_filesel		= NULL;
 	ui_widgets.prefs_dialog		= NULL;
 	main_status.main_window_realized = FALSE;
 	file_prefs.tab_order_ltr		= FALSE;
@@ -1219,8 +1217,6 @@
 	queue_free(ui_prefs.recent_projects_queue);
 
 	if (ui_widgets.prefs_dialog && GTK_IS_WIDGET(ui_widgets.prefs_dialog)) gtk_widget_destroy(ui_widgets.prefs_dialog);
-	if (ui_widgets.save_filesel && GTK_IS_WIDGET(ui_widgets.save_filesel)) gtk_widget_destroy(ui_widgets.save_filesel);
-	if (ui_widgets.open_filesel && GTK_IS_WIDGET(ui_widgets.open_filesel)) gtk_widget_destroy(ui_widgets.open_filesel);
 	if (ui_widgets.open_fontsel && GTK_IS_WIDGET(ui_widgets.open_fontsel)) gtk_widget_destroy(ui_widgets.open_fontsel);
 	if (ui_widgets.open_colorsel && GTK_IS_WIDGET(ui_widgets.open_colorsel)) gtk_widget_destroy(ui_widgets.open_colorsel);
 #ifdef HAVE_VTE

Modified: trunk/src/ui_utils.h
===================================================================
--- trunk/src/ui_utils.h	2011-06-10 10:26:01 UTC (rev 5836)
+++ trunk/src/ui_utils.h	2011-06-10 22:13:29 UTC (rev 5837)
@@ -124,8 +124,6 @@
 	/* dialogs */
 	GtkWidget	*open_colorsel;
 	GtkWidget	*open_fontsel;
-	GtkWidget	*open_filesel;
-	GtkWidget	*save_filesel;
 	GtkWidget	*prefs_dialog;
 
 	/* other widgets not needed in GeanyMainWidgets */


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list