From 91917644913db6beca718301d502d2b8c1cfd790 Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Fri, 12 Mar 2010 13:06:34 +0000 Subject: [PATCH] Make Build Commands dialog show menu item labels as a button (to help show that menu labels don't normally need to be edited & display the mnemonic correctly). Clicking shows an input dialog to set a new menu item label. Split dialogs_show_input() into 2 functions: one simple, one for a persistent dialog. Fix possible double-destroy of input dialog when closed by user. git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@4754 ea778897-0a13-0410-b9d1-a72fbfd435f5 --- ChangeLog | 8 ++++++ src/build.c | 50 ++++++++++++++++++++++++++++++----- src/callbacks.c | 15 ++++------- src/dialogs.c | 70 +++++++++++++++++++++++++++++++++++-------------- src/dialogs.h | 9 ++++--- 5 files changed, 112 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index ff97eec0..eaaa4d0c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,14 @@ * src/ui_utils.c: Fix ui_button_new_with_image() to call gtk_button_set_image() so that gtk_button_[sg]et_label() work as expected. + * src/build.c, src/dialogs.c, src/dialogs.h, src/callbacks.c: + Make Build Commands dialog show menu item labels as a button (to + help show that menu labels don't normally need to be edited & + display the mnemonic correctly). Clicking shows an input dialog to + set a new menu item label. + Split dialogs_show_input() into 2 functions: one simple, one for + a persistent dialog. + Fix possible double-destroy of input dialog when closed by user. 2010-03-10 Nick Treleaven diff --git a/src/build.c b/src/build.c index f58eaeae..63f216fc 100644 --- a/src/build.c +++ b/src/build.c @@ -1239,9 +1239,9 @@ static void on_build_menu_item(GtkWidget *w, gpointer user_data) if (! dialog) { - dialog = dialogs_show_input(_("Custom Text"), + dialog = dialogs_show_input_persistent(_("Custom Text"), _("Enter custom text here, all entered text is appended to the command."), - build_info.custom_target, TRUE, &on_make_custom_input_response); + build_info.custom_target, &on_make_custom_input_response); } else { @@ -1716,6 +1716,15 @@ typedef struct RowWidgets } RowWidgets; +static void set_build_command_entry_text(GtkWidget *wid, const gchar *text) +{ + if (GTK_IS_BUTTON(wid)) + gtk_button_set_label(GTK_BUTTON(wid), text); + else + gtk_entry_set_text(GTK_ENTRY(wid), text); +} + + static void on_clear_dialog_row(GtkWidget *unused, gpointer user_data) { RowWidgets *r = (RowWidgets*)user_data; @@ -1729,7 +1738,7 @@ static void on_clear_dialog_row(GtkWidget *unused, gpointer user_data) r->src = src; for (i = 0; i < GEANY_BC_CMDENTRIES_COUNT; i++) { - gtk_entry_set_text(GTK_ENTRY(r->entries[i]), + set_build_command_entry_text(r->entries[i], id_to_str(bc,i) != NULL ? id_to_str(bc,i) : ""); } } @@ -1738,7 +1747,7 @@ static void on_clear_dialog_row(GtkWidget *unused, gpointer user_data) r->cmdsrc = NULL; for (i = 0; i < GEANY_BC_CMDENTRIES_COUNT; i++) { - gtk_entry_set_text(GTK_ENTRY(r->entries[i]), ""); + set_build_command_entry_text(r->entries[i], ""); } } r->cleared = TRUE; @@ -1751,6 +1760,16 @@ static void on_clear_dialog_regex_row(GtkEntry *regex, gpointer unused) } +static void on_label_button_clicked(GtkWidget *wid) +{ + const gchar *old = gtk_button_get_label(GTK_BUTTON(wid)); + gchar *str = dialogs_show_input(_("Set menu item label"), NULL, old); + + gtk_button_set_label(GTK_BUTTON(wid), str); + g_free(str); +} + + /* Column headings, array NULL-terminated */ static gchar *colheads[] = { @@ -1793,7 +1812,15 @@ static RowWidgets *build_add_dialog_row(GeanyDocument *doc, GtkTable *table, gin gint xflags = (i == GEANY_BC_COMMAND) ? GTK_FILL | GTK_EXPAND : GTK_FILL; column += 1; - roww->entries[i] = gtk_entry_new(); + if (i == GEANY_BC_LABEL) + { + GtkWidget *wid = roww->entries[i] = gtk_button_new(); + gtk_button_set_use_underline(GTK_BUTTON(wid), TRUE); + ui_widget_set_tooltip_text(wid, _("Click to set menu item label")); + g_signal_connect(wid, "clicked", G_CALLBACK(on_label_button_clicked), NULL); + } + else + roww->entries[i] = gtk_entry_new(); gtk_table_attach(table, roww->entries[i], column, column + 1, row, row + 1, xflags, GTK_FILL | GTK_EXPAND, entry_x_padding, entry_y_padding); } @@ -1813,7 +1840,7 @@ static RowWidgets *build_add_dialog_row(GeanyDocument *doc, GtkTable *table, gin gchar *str = ""; if (bc != NULL && (str = bc->entries[i]) == NULL) str = ""; - gtk_entry_set_text(GTK_ENTRY(roww->entries[i]), str); + set_build_command_entry_text(roww->entries[i], str); } if (src > (gint)dst || (grp == GEANY_GBG_FT && (doc == NULL || doc->file_type == NULL))) { @@ -1982,6 +2009,15 @@ static int stcmp(const gchar *a, const gchar *b) } +static const gchar *get_build_command_entry_text(GtkWidget *wid) +{ + if (GTK_IS_BUTTON(wid)) + return gtk_button_get_label(GTK_BUTTON(wid)); + else + return gtk_entry_get_text(GTK_ENTRY(wid)); +} + + static gboolean read_row(BuildDestination *dst, TableData table_data, gint drow, gint grp, gint cmd) { gchar *entries[GEANY_BC_CMDENTRIES_COUNT]; @@ -1993,7 +2029,7 @@ static gboolean read_row(BuildDestination *dst, TableData table_data, gint drow, for (i = 0; i < GEANY_BC_CMDENTRIES_COUNT; i++) { - entries[i] = g_strdup(gtk_entry_get_text(GTK_ENTRY(table_data->rows[drow]->entries[i]))); + entries[i] = g_strdup(get_build_command_entry_text(table_data->rows[drow]->entries[i])); } if (table_data->rows[drow]->cleared) { diff --git a/src/callbacks.c b/src/callbacks.c index f4d82405..2173b6fd 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -1480,13 +1480,6 @@ on_comments_fileheader_activate (GtkMenuItem *menuitem, } -static void -on_custom_date_input_response(const gchar *input) -{ - setptr(ui_prefs.custom_date_format, g_strdup(input)); -} - - void on_insert_date_activate (GtkMenuItem *menuitem, gpointer user_data) @@ -1520,9 +1513,11 @@ on_insert_date_activate (GtkMenuItem *menuitem, format = ui_prefs.custom_date_format; else { - dialogs_show_input(_("Custom Date Format"), - _("Enter here a custom date and time format. You can use any conversion specifiers which can be used with the ANSI C strftime function."), - ui_prefs.custom_date_format, FALSE, &on_custom_date_input_response); + setptr(ui_prefs.custom_date_format, + dialogs_show_input(_("Custom Date Format"), + _("Enter here a custom date and time format. " + "You can use any conversion specifiers which can be used with the ANSI C strftime function."), + ui_prefs.custom_date_format)); return; } diff --git a/src/dialogs.c b/src/dialogs.c index d247004c..a4c5e188 100644 --- a/src/dialogs.c +++ b/src/dialogs.c @@ -822,8 +822,8 @@ on_input_dialog_response(GtkDialog *dialog, if (response == GTK_RESPONSE_ACCEPT) { const gchar *str = gtk_entry_get_text(GTK_ENTRY(entry)); - InputCallback input_cb = - (InputCallback) g_object_get_data(G_OBJECT(dialog), "input_cb"); + GeanyInputCallback input_cb = + (GeanyInputCallback) g_object_get_data(G_OBJECT(dialog), "input_cb"); if (persistent) { @@ -832,23 +832,22 @@ on_input_dialog_response(GtkDialog *dialog, } input_cb(str); } - - if (persistent) - gtk_widget_hide(GTK_WIDGET(dialog)); - else - gtk_widget_destroy(GTK_WIDGET(dialog)); + gtk_widget_hide(GTK_WIDGET(dialog)); } static void add_input_widgets(GtkWidget *dialog, GtkWidget *vbox, const gchar *label_text, const gchar *default_text, gboolean persistent) { - GtkWidget *label, *entry; + GtkWidget *entry; - label = gtk_label_new(label_text); - gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - gtk_container_add(GTK_CONTAINER(vbox), label); + if (label_text) + { + GtkWidget *label = gtk_label_new(label_text); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + gtk_container_add(GTK_CONTAINER(vbox), label); + } if (persistent) /* remember previous entry text in a combo box */ { @@ -884,9 +883,9 @@ static void add_input_widgets(GtkWidget *dialog, GtkWidget *vbox, * in this case the dialog returned is not destroyed on a response, * and can be reshown. * Returns: the dialog widget. */ -GtkWidget * -dialogs_show_input(const gchar *title, const gchar *label_text, const gchar *default_text, - gboolean persistent, InputCallback input_cb) +static GtkWidget * +dialogs_show_input_full(const gchar *title, const gchar *label_text, const gchar *default_text, + gboolean persistent, GeanyInputCallback input_cb) { GtkWidget *dialog, *vbox; @@ -903,12 +902,43 @@ dialogs_show_input(const gchar *title, const gchar *label_text, const gchar *def add_input_widgets(dialog, vbox, label_text, default_text, persistent); if (persistent) - g_signal_connect(dialog, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); - else - g_signal_connect(dialog, "delete-event", G_CALLBACK(gtk_widget_destroy), NULL); - + { + gtk_widget_show_all(dialog); + return dialog; + } gtk_widget_show_all(dialog); - return dialog; + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + return NULL; +} + + +/* Remember previous entry text in a combo box. + * Returns: the dialog widget. */ +GtkWidget * +dialogs_show_input_persistent(const gchar *title, const gchar *label_text, const gchar *default_text, + GeanyInputCallback input_cb) +{ + return dialogs_show_input_full(title, label_text, default_text, TRUE, input_cb); +} + + +/* ugly hack - user_data not supported for callback */ +gchar *dialog_input = NULL; + +static void on_dialog_input(const gchar *str) +{ + dialog_input = g_strdup(str); +} + + +/* Returns: newly allocated string - a copy of either the entry text or default_text. */ +gchar *dialogs_show_input(const gchar *title, const gchar *label_text, + const gchar *default_text) +{ + dialog_input = NULL; + dialogs_show_input_full(title, label_text, default_text, FALSE, on_dialog_input); + return NVL(dialog_input, g_strdup(default_text)); } diff --git a/src/dialogs.h b/src/dialogs.h index 413d7678..3a63def2 100644 --- a/src/dialogs.h +++ b/src/dialogs.h @@ -30,7 +30,7 @@ #ifndef GEANY_DIALOGS_H #define GEANY_DIALOGS_H 1 -typedef void (*InputCallback)(const gchar *); +typedef void (*GeanyInputCallback)(const gchar *text); void dialogs_show_open_file(void); @@ -45,8 +45,11 @@ void dialogs_show_word_count(void); void dialogs_show_color(gchar *colour); -GtkWidget *dialogs_show_input(const gchar *title, const gchar *label_text, - const gchar *default_text, gboolean persistent, InputCallback input_cb); +gchar *dialogs_show_input(const gchar *title, const gchar *label_text, + const gchar *default_text); + +GtkWidget *dialogs_show_input_persistent(const gchar *title, const gchar *label_text, + const gchar *default_text, GeanyInputCallback input_cb); gboolean dialogs_show_input_numeric(const gchar *title, const gchar *label_text, gdouble *value, gdouble min, gdouble max, gdouble step);