SF.net SVN: geany: [951] trunk

ntrel at users.sourceforge.net ntrel at xxxxx
Wed Nov 1 15:26:49 UTC 2006


Revision: 951
          http://svn.sourceforge.net/geany/?rev=951&view=rev
Author:   ntrel
Date:     2006-11-01 07:26:41 -0800 (Wed, 01 Nov 2006)

Log Message:
-----------
Add Find Previous, Find All in File/Session buttons to the Find
dialog.
Move Find Usage code from on_find_usage1_activate to search.c.
Add ui_button_new_with_image(), ui_hbutton_box_copy_layout().

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/src/callbacks.c
    trunk/src/search.c
    trunk/src/search.h
    trunk/src/ui_utils.c
    trunk/src/ui_utils.h

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2006-11-01 10:58:47 UTC (rev 950)
+++ trunk/ChangeLog	2006-11-01 15:26:41 UTC (rev 951)
@@ -1,6 +1,12 @@
 2006-11-01  Nick Treleaven  <nick.treleaven at btinternet.com>
 
  * src/document.c: Prevent possible invalid memory read.
+ * src/ui_utils.h, src/search.c, src/search.h, src/ui_utils.c,
+   src/callbacks.c:
+   Add Find Previous, Find All in File/Session buttons to the Find
+   dialog.
+   Move Find Usage code from on_find_usage1_activate to search.c.
+   Add ui_button_new_with_image(), ui_hbutton_box_copy_layout().
 
 
 2006-10-30  Enrico Tröger  <enrico.troeger at uvena.de>

Modified: trunk/src/callbacks.c
===================================================================
--- trunk/src/callbacks.c	2006-11-01 10:58:47 UTC (rev 950)
+++ trunk/src/callbacks.c	2006-11-01 15:26:41 UTC (rev 951)
@@ -1159,15 +1159,12 @@
 on_find_usage1_activate                (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	guint i;
-	gint pos, line = -1, flags, idx;
-	struct TextToFind ttf;
-	gchar *buffer, *short_file_name, *string, *search_text;
+	gint flags, idx;
+	gchar *search_text;
 
-	gtk_notebook_set_current_page(GTK_NOTEBOOK(msgwindow.notebook), MSG_MESSAGE);
-	gtk_list_store_clear(msgwindow.store_msg);
-
 	idx = document_get_cur_idx();
+	if (! DOC_IDX_VALID(idx)) return;
+
 	if (sci_can_copy(doc_list[idx].sci))
 	{	// take selected text if there is a selection
 		search_text = g_malloc(sci_get_selected_text_length(doc_list[idx].sci) + 1);
@@ -1180,43 +1177,7 @@
 		flags = SCFIND_MATCHCASE | SCFIND_WHOLEWORD;
 	}
 
-	for(i = 0; i < doc_array->len; i++)
-	{
-		if (doc_list[i].is_valid)
-		{
-			ttf.chrg.cpMin = 0;
-			ttf.chrg.cpMax = sci_get_length(doc_list[i].sci);
-			ttf.lpstrText = search_text;
-			while (1)
-			{
-				pos = sci_find_text(doc_list[i].sci, flags, &ttf);
-				if (pos == -1) break;
-
-				line = sci_get_line_from_position(doc_list[i].sci, pos);
-				buffer = sci_get_line(doc_list[i].sci, line);
-
-				if (doc_list[i].file_name == NULL)
-					short_file_name = g_strdup(GEANY_STRING_UNTITLED);
-				else
-					short_file_name = g_path_get_basename(doc_list[i].file_name);
-				string = g_strdup_printf("%s:%d : %s", short_file_name, line + 1, g_strstrip(buffer));
-				msgwin_msg_add(line + 1, i, string);
-
-				g_free(buffer);
-				g_free(short_file_name);
-				g_free(string);
-				ttf.chrg.cpMin = ttf.chrgText.cpMax + 1;
-			}
-		}
-	}
-	if (line == -1) // no matches were found (searching from unnamed file)
-	{
-		gchar *text = g_strdup_printf(_("No matches found for '%s'."), search_text);
-		msgwin_status_add(text);
-		msgwin_msg_add(-1, -1, text);
-		g_free(text);
-	}
-
+	search_find_usage(search_text, flags, TRUE);
 	g_free(search_text);
 }
 

Modified: trunk/src/search.c
===================================================================
--- trunk/src/search.c	2006-11-01 10:58:47 UTC (rev 950)
+++ trunk/src/search.c	2006-11-01 15:26:41 UTC (rev 951)
@@ -43,9 +43,13 @@
 
 
 enum {
-	GEANY_RESPONSE_REPLACE = 1,
+	GEANY_RESPONSE_FIND = 1,
+	GEANY_RESPONSE_FIND_PREVIOUS,
+	GEANY_RESPONSE_FIND_IN_FILE,
+	GEANY_RESPONSE_FIND_IN_SESSION,
+	GEANY_RESPONSE_MARK,
+	GEANY_RESPONSE_REPLACE,
 	GEANY_RESPONSE_REPLACE_AND_FIND,
-	GEANY_RESPONSE_FIND,
 	GEANY_RESPONSE_REPLACE_IN_SESSION,
 	GEANY_RESPONSE_REPLACE_IN_FILE,
 	GEANY_RESPONSE_REPLACE_IN_SEL
@@ -139,7 +143,7 @@
 
 static GtkWidget *add_find_checkboxes(GtkDialog *dialog)
 {
-	GtkWidget *checkbox1, *checkbox2, *check_regexp, *checkbox4, *checkbox5,
+	GtkWidget *checkbox1, *checkbox2, *check_regexp, *check_back, *checkbox5,
 			  *checkbox7, *hbox, *fbox, *mbox;
 	GtkTooltips *tooltips = GTK_TOOLTIPS(lookup_widget(app->window, "tooltips"));
 
@@ -152,11 +156,22 @@
 	g_signal_connect(G_OBJECT(check_regexp), "toggled",
 		G_CALLBACK(on_find_replace_checkbutton_toggled), GTK_WIDGET(dialog));
 
-	checkbox4 = gtk_check_button_new_with_mnemonic(_("_Search backwards"));
-	g_object_set_data_full(G_OBJECT(dialog), "check_back",
-					gtk_widget_ref(checkbox4), (GDestroyNotify)gtk_widget_unref);
-	gtk_button_set_focus_on_click(GTK_BUTTON(checkbox4), FALSE);
-
+	if (dialog != GTK_DIALOG(widgets.find_dialog))
+	{
+		check_back = gtk_check_button_new_with_mnemonic(_("_Search backwards"));
+		g_object_set_data_full(G_OBJECT(dialog), "check_back",
+						gtk_widget_ref(check_back), (GDestroyNotify)gtk_widget_unref);
+		gtk_button_set_focus_on_click(GTK_BUTTON(check_back), FALSE);
+	}
+	else
+	{	// align the two checkboxes at the top of the hbox
+		GtkSizeGroup *label_size;
+		check_back = gtk_label_new(NULL);
+		label_size = gtk_size_group_new(GTK_SIZE_GROUP_VERTICAL);
+		gtk_size_group_add_widget(GTK_SIZE_GROUP(label_size), check_back);
+		gtk_size_group_add_widget(GTK_SIZE_GROUP(label_size), check_regexp);
+		g_object_unref(label_size);
+	}
 	checkbox7 = gtk_check_button_new_with_mnemonic(_("Use _escape sequences"));
 	g_object_set_data_full(G_OBJECT(dialog), "check_escape",
 					gtk_widget_ref(checkbox7), (GDestroyNotify)gtk_widget_unref);
@@ -169,7 +184,7 @@
 	fbox = gtk_vbox_new(FALSE, 0);
 	gtk_container_add(GTK_CONTAINER(fbox), check_regexp);
 	gtk_container_add(GTK_CONTAINER(fbox), checkbox7);
-	gtk_container_add(GTK_CONTAINER(fbox), checkbox4);
+	gtk_container_add(GTK_CONTAINER(fbox), check_back);
 
 	checkbox1 = gtk_check_button_new_with_mnemonic(_("_Case sensitive"));
 	g_object_set_data_full(G_OBJECT(dialog), "check_case",
@@ -199,12 +214,10 @@
 }
 
 
-#if 0
 static void send_find_dialog_response(GtkButton *button, gpointer user_data)
 {
 	gtk_dialog_response(GTK_DIALOG(widgets.find_dialog), GPOINTER_TO_INT(user_data));
 }
-#endif
 
 
 static gchar *get_default_text(gint idx)
@@ -239,14 +252,25 @@
 	if (widgets.find_dialog == NULL)
 	{
 		GtkWidget *label, *entry, *sbox, *vbox;
+		GtkWidget *exp, *bbox, *button, *check_close;
+		GtkTooltips *tooltips = GTK_TOOLTIPS(lookup_widget(app->window, "tooltips"));
 
 		widgets.find_dialog = gtk_dialog_new_with_buttons(_("Find"),
 			GTK_WINDOW(app->window), GTK_DIALOG_DESTROY_WITH_PARENT,
-			GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL,
-			GTK_STOCK_FIND, GTK_RESPONSE_ACCEPT, NULL);
+			GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL, NULL);
 		vbox = ui_dialog_vbox_new(GTK_DIALOG(widgets.find_dialog));
 		gtk_box_set_spacing(GTK_BOX(vbox), 9);
 
+		button = gtk_button_new_with_mnemonic(_("Find _Previous"));
+		gtk_dialog_add_action_widget(GTK_DIALOG(widgets.find_dialog), button,
+			GEANY_RESPONSE_FIND_PREVIOUS);
+		g_object_set_data_full(G_OBJECT(widgets.find_dialog), "btn_previous",
+						gtk_widget_ref(button), (GDestroyNotify)gtk_widget_unref);
+
+		button = ui_button_new_with_image(GTK_STOCK_FIND, _("Find _Next"));
+		gtk_dialog_add_action_widget(GTK_DIALOG(widgets.find_dialog), button,
+			GEANY_RESPONSE_FIND);
+
 		label = gtk_label_new(_("Search for:"));
 		gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 
@@ -267,11 +291,49 @@
 		sbox = gtk_hbox_new(FALSE, 6);
 		gtk_box_pack_start(GTK_BOX(sbox), label, FALSE, FALSE, 0);
 		gtk_box_pack_start(GTK_BOX(sbox), entry, TRUE, TRUE, 0);
-		gtk_container_add(GTK_CONTAINER(vbox), sbox);
+		gtk_box_pack_start(GTK_BOX(vbox), sbox, TRUE, FALSE, 0);
 
 		gtk_container_add(GTK_CONTAINER(vbox),
 			add_find_checkboxes(GTK_DIALOG(widgets.find_dialog)));
 
+		// Now add the multiple match options
+		exp = gtk_expander_new(_("Find All"));
+		bbox = gtk_hbutton_box_new();
+
+#if 0
+		button = gtk_button_new_with_mnemonic(_("_Mark"));
+		gtk_container_add(GTK_CONTAINER(bbox), button);
+		g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(send_find_dialog_response),
+			GINT_TO_POINTER(GEANY_RESPONSE_MARK));
+#endif	// not implemented yet
+
+		button = gtk_button_new_with_mnemonic(_("In Sessi_on"));
+		gtk_container_add(GTK_CONTAINER(bbox), button);
+		g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(send_find_dialog_response),
+			GINT_TO_POINTER(GEANY_RESPONSE_FIND_IN_SESSION));
+
+		button = gtk_button_new_with_mnemonic(_("In F_ile"));
+		gtk_container_add(GTK_CONTAINER(bbox), button);
+		g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(send_find_dialog_response),
+			GINT_TO_POINTER(GEANY_RESPONSE_FIND_IN_FILE));
+
+		// close window checkbox
+		check_close = gtk_check_button_new_with_mnemonic(_("Close _dialog"));
+		g_object_set_data_full(G_OBJECT(widgets.find_dialog), "check_close",
+						gtk_widget_ref(check_close), (GDestroyNotify) gtk_widget_unref);
+		gtk_button_set_focus_on_click(GTK_BUTTON(check_close), FALSE);
+		gtk_tooltips_set_tip(tooltips, check_close,
+				_("The dialog window won't be closed when you start the operation."), NULL);
+		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_close), TRUE);
+		gtk_container_add(GTK_CONTAINER(bbox), check_close);
+		gtk_button_box_set_child_secondary(GTK_BUTTON_BOX(bbox), check_close, TRUE);
+
+		ui_hbutton_box_copy_layout(
+			GTK_BUTTON_BOX(GTK_DIALOG(widgets.find_dialog)->action_area),
+			GTK_BUTTON_BOX(bbox));
+		gtk_container_add(GTK_CONTAINER(exp), bbox);
+		gtk_container_add(GTK_CONTAINER(vbox), exp);
+
 		gtk_widget_show_all(widgets.find_dialog);
 	}
 	else
@@ -304,7 +366,7 @@
 	{
 		GtkWidget *label_find, *label_replace, *entry_find, *entry_replace,
 			*check_close, *button, *rbox, *fbox, *vbox, *exp, *bbox;
-		GtkSizeGroup *label_size, *button_size;
+		GtkSizeGroup *label_size;
 		GtkTooltips *tooltips = GTK_TOOLTIPS(lookup_widget(app->window, "tooltips"));
 
 		widgets.replace_dialog = gtk_dialog_new_with_buttons(_("Replace"),
@@ -323,10 +385,6 @@
 		gtk_dialog_add_action_widget(GTK_DIALOG(widgets.replace_dialog), button,
 			GEANY_RESPONSE_REPLACE_AND_FIND);
 
-		button_size = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
-		gtk_size_group_add_widget(GTK_SIZE_GROUP(button_size), button);
-		g_object_unref(G_OBJECT(button_size));
-
 		label_find = gtk_label_new(_("Search for:"));
 		gtk_misc_set_alignment(GTK_MISC(label_find), 0, 0.5);
 
@@ -376,8 +434,6 @@
 		// Now add the multiple replace options
 		exp = gtk_expander_new(_("Replace All"));
 		bbox = gtk_hbutton_box_new();
-		gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
-		gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 10);
 
 		button = gtk_button_new_with_mnemonic(_("In Se_lection"));
 		gtk_tooltips_set_tip(tooltips, button,
@@ -396,9 +452,7 @@
 		g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(send_replace_dialog_response),
 			GINT_TO_POINTER(GEANY_RESPONSE_REPLACE_IN_FILE));
 
-		gtk_size_group_add_widget(GTK_SIZE_GROUP(button_size), button);
-
-		// Don't close window checkbox
+		// close window checkbox
 		check_close = gtk_check_button_new_with_mnemonic(_("Close _dialog"));
 		g_object_set_data_full(G_OBJECT(widgets.replace_dialog), "check_close",
 						gtk_widget_ref(check_close), (GDestroyNotify) gtk_widget_unref);
@@ -409,6 +463,9 @@
 		gtk_container_add(GTK_CONTAINER(bbox), check_close);
 		gtk_button_box_set_child_secondary(GTK_BUTTON_BOX(bbox), check_close, TRUE);
 
+		ui_hbutton_box_copy_layout(
+			GTK_BUTTON_BOX(GTK_DIALOG(widgets.replace_dialog)->action_area),
+			GTK_BUTTON_BOX(bbox));
 		gtk_container_add(GTK_CONTAINER(exp), bbox);
 		gtk_container_add(GTK_CONTAINER(vbox), exp);
 
@@ -618,7 +675,6 @@
 	if (togglebutton == chk_regexp)
 	{
 		gboolean regex_set = gtk_toggle_button_get_active(chk_regexp);
-		GtkWidget *check_back = lookup_widget(dialog, "check_back");
 		GtkWidget *check_word = lookup_widget(dialog, "check_word");
 		GtkWidget *check_wordstart = lookup_widget(dialog, "check_wordstart");
 		GtkToggleButton *check_case = GTK_TOGGLE_BUTTON(
@@ -626,7 +682,11 @@
 		static gboolean case_state = FALSE; // state before regex enabled
 
 		// hide options that don't apply to regex searches
-		gtk_widget_set_sensitive(check_back, ! regex_set);
+		if (dialog == widgets.find_dialog)
+			gtk_widget_set_sensitive(lookup_widget(dialog, "btn_previous"), ! regex_set);
+		else
+			gtk_widget_set_sensitive(lookup_widget(dialog, "check_back"), ! regex_set);
+
 		gtk_widget_set_sensitive(check_word, ! regex_set);
 		gtk_widget_set_sensitive(check_wordstart, ! regex_set);
 
@@ -649,7 +709,9 @@
 static void
 on_find_dialog_response(GtkDialog *dialog, gint response, gpointer user_data)
 {
-	if (response == GTK_RESPONSE_ACCEPT)
+	if (response == GTK_RESPONSE_CANCEL)
+		gtk_widget_hide(widgets.find_dialog);
+	else
 	{
 		gint idx = document_get_cur_idx();
 		gboolean search_replace_escape;
@@ -661,12 +723,15 @@
 			fl3 = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
 						lookup_widget(GTK_WIDGET(widgets.find_dialog), "check_regexp"))),
 			fl4 = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
-						lookup_widget(GTK_WIDGET(widgets.find_dialog), "check_wordstart")));
+						lookup_widget(GTK_WIDGET(widgets.find_dialog), "check_wordstart"))),
+			check_close = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
+						lookup_widget(GTK_WIDGET(widgets.find_dialog), "check_close")));
 		search_replace_escape = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
 						lookup_widget(GTK_WIDGET(widgets.find_dialog), "check_escape")));
-		search_data.backwards = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
-						lookup_widget(GTK_WIDGET(widgets.find_dialog), "check_back")));
+		search_data.backwards = FALSE;
 
+		if (! DOC_IDX_VALID(idx)) return;
+
 		g_free(search_data.text);
 		search_data.text = g_strdup(gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(user_data)))));
 		if (strlen(search_data.text) == 0 ||
@@ -682,9 +747,31 @@
 				(fl2 ? SCFIND_WHOLEWORD : 0) |
 				(fl3 ? SCFIND_REGEXP | SCFIND_POSIX: 0) |
 				(fl4 ? SCFIND_WORDSTART : 0);
-		document_find_text(idx, search_data.text, search_data.flags, search_data.backwards);
+		
+		switch (response)
+		{
+			case GEANY_RESPONSE_FIND:
+			case GEANY_RESPONSE_FIND_PREVIOUS:
+			document_find_text(idx, search_data.text, search_data.flags,
+				(response == GEANY_RESPONSE_FIND_PREVIOUS));
+			check_close = FALSE;
+			break;
+
+			case GEANY_RESPONSE_FIND_IN_FILE:
+			search_find_usage(search_data.text, search_data.flags, FALSE);
+			break;
+
+			case GEANY_RESPONSE_FIND_IN_SESSION:
+			search_find_usage(search_data.text, search_data.flags, TRUE);
+			break;
+
+			case GEANY_RESPONSE_MARK:
+			// TODO
+			break;
+		}
+		if (check_close)
+			gtk_widget_hide(widgets.find_dialog);
 	}
-	else gtk_widget_hide(widgets.find_dialog);
 }
 
 
@@ -1075,3 +1162,72 @@
 }
 
 
+static gint find_document_usage(gint idx, const gchar *search_text, gint flags)
+{
+	gchar *buffer, *short_file_name, *string;
+	gint pos, line, count = 0;
+	struct TextToFind ttf;
+
+	g_return_val_if_fail(DOC_IDX_VALID(idx), 0);
+
+	ttf.chrg.cpMin = 0;
+	ttf.chrg.cpMax = sci_get_length(doc_list[idx].sci);
+	ttf.lpstrText = (gchar *)search_text;
+	while (1)
+	{
+		pos = sci_find_text(doc_list[idx].sci, flags, &ttf);
+		if (pos == -1) break;
+
+		line = sci_get_line_from_position(doc_list[idx].sci, pos);
+		buffer = sci_get_line(doc_list[idx].sci, line);
+
+		if (doc_list[idx].file_name == NULL)
+			short_file_name = g_strdup(GEANY_STRING_UNTITLED);
+		else
+			short_file_name = g_path_get_basename(doc_list[idx].file_name);
+		string = g_strdup_printf("%s:%d : %s", short_file_name, line + 1, g_strstrip(buffer));
+		msgwin_msg_add(line + 1, idx, string);
+
+		g_free(buffer);
+		g_free(short_file_name);
+		g_free(string);
+		ttf.chrg.cpMin = ttf.chrgText.cpMax + 1;
+		count++;
+	}
+	return count;
+}
+
+
+void search_find_usage(const gchar *search_text, gint flags, gboolean in_session)
+{
+	gint idx;
+	gboolean found = FALSE;
+
+	idx = document_get_cur_idx();
+	g_return_if_fail(DOC_IDX_VALID(idx));
+
+	gtk_notebook_set_current_page(GTK_NOTEBOOK(msgwindow.notebook), MSG_MESSAGE);
+	gtk_list_store_clear(msgwindow.store_msg);
+
+	if (! in_session)
+	{	// use current document
+		found = (find_document_usage(idx, search_text, flags) > 0);
+	}
+	else
+	{
+		guint i;
+		for(i = 0; i < doc_array->len; i++)
+		{
+			if (doc_list[i].is_valid)
+				if (find_document_usage(i, search_text, flags) > 0) found = TRUE;
+		}
+	}
+
+	if (! found) // no matches were found
+	{
+		gchar *text = g_strdup_printf(_("No matches found for '%s'."), search_text);
+		ui_set_statusbar(text, FALSE);
+		msgwin_msg_add(-1, -1, text);
+		g_free(text);
+	}
+}

Modified: trunk/src/search.h
===================================================================
--- trunk/src/search.h	2006-11-01 10:58:47 UTC (rev 950)
+++ trunk/src/search.h	2006-11-01 15:26:41 UTC (rev 951)
@@ -46,4 +46,6 @@
 
 void search_show_find_in_files_dialog();
 
+void search_find_usage(const gchar *search_text, gint flags, gboolean in_session);
+
 #endif

Modified: trunk/src/ui_utils.c
===================================================================
--- trunk/src/ui_utils.c	2006-11-01 10:58:47 UTC (rev 950)
+++ trunk/src/ui_utils.c	2006-11-01 15:26:41 UTC (rev 951)
@@ -1038,4 +1038,52 @@
 }
 
 
+/* Create a GtkButton with custom text and a stock image, aligned like
+ * gtk_button_new_from_stock */
+GtkWidget *ui_button_new_with_image(const gchar *stock_id, const gchar *text)
+{
+	GtkWidget *image, *label, *align, *hbox, *button;
 
+	hbox = gtk_hbox_new(FALSE, 2);
+	image = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_BUTTON);
+	label = gtk_label_new_with_mnemonic(text);
+	gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
+	gtk_box_pack_end(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+	button = gtk_button_new();
+	align = gtk_alignment_new(0.5, 0.5, 0.0, 0.0);
+	gtk_container_add(GTK_CONTAINER(align), hbox);
+	gtk_container_add(GTK_CONTAINER(button), align);
+	return button;
+}
+
+
+static void add_to_size_group(GtkWidget *widget, gpointer size_group)
+{
+	g_return_if_fail(GTK_IS_SIZE_GROUP(size_group));
+	gtk_size_group_add_widget(GTK_SIZE_GROUP(size_group), widget);
+}
+
+
+/* Copies the spacing and layout of the master GtkHButtonBox and synchronises
+ * the width of each button box's children.
+ * Should be called after all child widgets have been packed. */
+void ui_hbutton_box_copy_layout(GtkButtonBox *master, GtkButtonBox *copy)
+{
+	GtkSizeGroup *size_group;
+
+	/* set_spacing is deprecated but there seems to be no alternative,
+	* GTK 2.6 defaults to no spacing, unlike dialog button box */
+	gtk_button_box_set_spacing(copy, 10);
+	gtk_button_box_set_layout(copy, gtk_button_box_get_layout(master));
+
+	/* now we need to put the widest widget from each button box in a size group,
+	* but we don't know the width before they are drawn, and for different label
+	* translations the widest widget can vary, so we just add all widgets. */
+	size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+	gtk_container_foreach(GTK_CONTAINER(master), add_to_size_group, size_group);
+	gtk_container_foreach(GTK_CONTAINER(copy), add_to_size_group, size_group);
+	g_object_unref(size_group);
+}
+
+

Modified: trunk/src/ui_utils.h
===================================================================
--- trunk/src/ui_utils.h	2006-11-01 10:58:47 UTC (rev 950)
+++ trunk/src/ui_utils.h	2006-11-01 15:26:41 UTC (rev 951)
@@ -97,4 +97,8 @@
 
 GtkWidget *ui_dialog_vbox_new(GtkDialog *dialog);
 
+GtkWidget *ui_button_new_with_image(const gchar *stock_id, const gchar *text);
+
+void ui_hbutton_box_copy_layout(GtkButtonBox *master, GtkButtonBox *copy);
+
 #endif


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