Rework GtkBuilder code to behave more like old Glade 2 code

* Put back ui_hookup_widget and ui_lookup_widget functions
* Put back lookup_widget code in stash.c
* Emulate old create_*() functions from interface.[ch].
* Hookup all the GtkBuilder widget's to their top widgets like Glade 2
  generated code would've done.
* Misc changes to accomodate the above.
This commit is contained in:
Matthew Brush 2011-10-19 00:35:24 -07:00
parent a670edfbe5
commit 72e856947e
10 changed files with 166 additions and 116 deletions

View File

@ -302,10 +302,6 @@
geany_functions->p_ui->ui_combo_box_add_to_history
#define ui_menu_add_document_items_sorted \
geany_functions->p_ui->ui_menu_add_document_items_sorted
#define ui_hookup_object \
geany_functions->p_ui->ui_hookup_object
#define ui_lookup_object \
geany_functions->p_ui->ui_lookup_object
#define dialogs_show_question \
geany_functions->p_dialogs->dialogs_show_question
#define dialogs_show_msgbox \

View File

@ -241,7 +241,7 @@ static void main_init(void)
ui_init_stock_items();
main_widgets.window = ui_lookup_widget(NULL, "window1");
main_widgets.window = create_window1();
/* add recent projects to the Project menu */
ui_widgets.recent_projects_menuitem = ui_lookup_widget(main_widgets.window, "recent_projects1");
@ -253,12 +253,12 @@ static void main_init(void)
main_widgets.toolbar = toolbar_init();
main_widgets.sidebar_notebook = ui_lookup_widget(main_widgets.window, "notebook3");
main_widgets.notebook = ui_lookup_widget(main_widgets.window, "notebook1");
main_widgets.editor_menu = ui_lookup_widget(NULL, "edit_menu1");
main_widgets.editor_menu = create_edit_menu1();
main_widgets.tools_menu = ui_lookup_widget(main_widgets.window, "tools1_menu");
main_widgets.message_window_notebook = ui_lookup_widget(main_widgets.window, "notebook_info");
main_widgets.project_menu = ui_lookup_widget(main_widgets.window, "menu_project1_menu");
ui_widgets.toolbar_menu = ui_lookup_widget(NULL, "toolbar_popup_menu1");
ui_widgets.toolbar_menu = create_toolbar_popup_menu1();
ui_init();
/* set widget names for matching with .gtkrc-2.0 */
@ -1237,7 +1237,7 @@ void main_quit()
g_free(app);
ui_finalize_builder(); /* After all widgets are cleaned up */
ui_finalize_builder();
gtk_main_quit();
}

View File

@ -477,8 +477,6 @@ typedef struct UIUtilsFuncs
const gchar *text, gint history_len);
void (*ui_menu_add_document_items_sorted) (GtkMenu *menu, struct GeanyDocument *active,
GCallback callback, GCompareFunc compare_func);
void (*ui_hookup_object) (GObject *obj, const gchar *object_name);
GObject* (*ui_lookup_object) (const gchar *object_name);
}
UIUtilsFuncs;

View File

@ -246,9 +246,7 @@ static UIUtilsFuncs uiutils_funcs = {
&ui_is_keyval_enter_or_return,
&ui_get_gtk_settings_integer,
&ui_combo_box_add_to_history,
&ui_menu_add_document_items_sorted,
&ui_hookup_object,
&ui_lookup_object
&ui_menu_add_document_items_sorted
};
static DialogFuncs dialog_funcs = {

View File

@ -1629,7 +1629,7 @@ void prefs_show_dialog(void)
gchar *encoding_string;
GdkPixbuf *pb;
ui_widgets.prefs_dialog = ui_lookup_widget(NULL, "prefs_dialog");
ui_widgets.prefs_dialog = create_prefs_dialog();
gtk_widget_set_name(ui_widgets.prefs_dialog, "GeanyPrefsDialog");
gtk_window_set_transient_for(GTK_WINDOW(ui_widgets.prefs_dialog), GTK_WINDOW(main_widgets.window));
pb = ui_new_pixbuf_from_inline(GEANY_IMAGE_LOGO);

View File

@ -402,7 +402,7 @@ static void create_properties_dialog(PropertyDialogElements *e)
GeanyDocument *doc = document_get_current();
GeanyFiletype *ft = NULL;
e->dialog = ui_lookup_widget(NULL, "project_dialog");
e->dialog = create_project_dialog();
gtk_window_set_transient_for(GTK_WINDOW(e->dialog), GTK_WINDOW(main_widgets.window));
gtk_window_set_destroy_with_parent(GTK_WINDOW(e->dialog), TRUE);
gtk_widget_set_name(e->dialog, "GeanyDialogProject");

View File

@ -86,7 +86,6 @@
#include <string.h> /* only for strcmp() */
#include "support.h" /* only for _("text") */
#include "utils.h" /* only for foreach_*, utils_get_setting_*(). Stash should not depend on Geany. */
#include "ui_utils.h" /* only for ui_lookup_object(). Stash should not depend on Geany. */
#include "stash.h"
@ -526,18 +525,31 @@ static void handle_combo_box_entry(GtkWidget *widget, StashPref *entry,
}
/* FIXME */
/* taken from Glade 2.x generated support.c */
static GtkWidget*
lookup_widget(GtkWidget *widget, const gchar *widget_name)
{
GtkWidget *found_widget;
GtkWidget *parent, *found_widget;
(void) widget; /* not used anymore */
g_return_val_if_fail(widget != NULL, NULL);
g_return_val_if_fail(widget_name != NULL, NULL);
found_widget = GTK_WIDGET(ui_lookup_object(widget_name));
if (!found_widget)
g_warning ("Widget not found: %s", widget_name);
for (;;)
{
if (GTK_IS_MENU(widget))
parent = gtk_menu_get_attach_widget(GTK_MENU(widget));
else
parent = widget->parent;
if (parent == NULL)
parent = (GtkWidget*) g_object_get_data(G_OBJECT(widget), "GladeParentKey");
if (parent == NULL)
break;
widget = parent;
}
found_widget = (GtkWidget*) g_object_get_data(G_OBJECT(widget), widget_name);
if (G_UNLIKELY(found_widget == NULL))
g_warning("Widget not found: %s", widget_name);
return found_widget;
}

View File

@ -63,7 +63,12 @@ GeanyMainWidgets main_widgets;
UIPrefs ui_prefs;
UIWidgets ui_widgets;
static GHashTable *objects_table = NULL;
static GtkBuilder *builder = NULL;
static GtkWidget* window1 = NULL;
static GtkWidget* toolbar_popup_menu1 = NULL;
static GtkWidget* edit_menu1 = NULL;
static GtkWidget* prefs_dialog = NULL;
static GtkWidget* project_dialog = NULL;
static struct
{
@ -2113,14 +2118,72 @@ static const gchar *ui_guess_object_name(GObject *obj)
}
/* Compatibility functions */
GtkWidget *create_edit_menu1(void)
{
return edit_menu1;
}
GtkWidget *create_prefs_dialog(void)
{
return prefs_dialog;
}
GtkWidget *create_project_dialog(void)
{
return project_dialog;
}
GtkWidget *create_toolbar_popup_menu1(void)
{
return toolbar_popup_menu1;
}
GtkWidget *create_window1(void)
{
return window1;
}
static GtkWidget *ui_get_top_parent(GtkWidget *widget)
{
GtkWidget *parent, *found_widget;
g_return_val_if_fail(GTK_IS_WIDGET(widget), NULL);
for (;;)
{
if (GTK_IS_MENU(widget))
parent = gtk_menu_get_attach_widget(GTK_MENU(widget));
else
parent = gtk_widget_get_parent(widget);
if (parent == NULL)
parent = (GtkWidget*) g_object_get_data(G_OBJECT(widget), "GladeParentKey");
if (parent == NULL)
break;
widget = parent;
}
return widget;
}
void ui_init_builder(void)
{
gchar *interface_file;
const gchar *name;
const gchar *name, *toplevel_name;
GError *error;
GSList *iter, *all_objects;
GtkBuilder *builder;
GtkCellRenderer *renderer;
GtkWidget *widget, *toplevel;
/* prevent function from being called twice */
if (GTK_IS_BUILDER(builder))
return;
builder = gtk_builder_new();
if (! builder)
@ -2143,33 +2206,52 @@ void ui_init_builder(void)
gtk_builder_connect_signals(builder, NULL);
objects_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref);
edit_menu1 = GTK_WIDGET(gtk_builder_get_object(builder, "edit_menu1"));
prefs_dialog = GTK_WIDGET(gtk_builder_get_object(builder, "prefs_dialog"));
project_dialog = GTK_WIDGET(gtk_builder_get_object(builder, "project_dialog"));
toolbar_popup_menu1 = GTK_WIDGET(gtk_builder_get_object(builder, "toolbar_popup_menu1"));
window1 = GTK_WIDGET(gtk_builder_get_object(builder, "window1"));
g_object_set_data(G_OBJECT(edit_menu1), "edit_menu1", edit_menu1);
g_object_set_data(G_OBJECT(prefs_dialog), "prefs_dialog", prefs_dialog);
g_object_set_data(G_OBJECT(project_dialog), "project_dialog", project_dialog);
g_object_set_data(G_OBJECT(toolbar_popup_menu1), "toolbar_popup_menu1", toolbar_popup_menu1);
g_object_set_data(G_OBJECT(window1), "window1", window1);
all_objects = gtk_builder_get_objects(builder);
for (iter = all_objects; iter != NULL; iter = g_slist_next(iter))
{
name = ui_guess_object_name(iter->data);
if (! GTK_IS_WIDGET(iter->data))
continue;
widget = GTK_WIDGET(iter->data);
name = ui_guess_object_name(G_OBJECT(widget));
if (! name)
{
g_warning("Unable to get name from GtkBuilder object");
continue;
}
ui_hookup_object(iter->data, name);
toplevel = ui_get_top_parent(widget);
if (toplevel)
ui_hookup_widget(toplevel, widget, name);
/* Glade doesn't seem to add cell renderers for the combo boxes,
* so they are added here. */
if (GTK_IS_COMBO_BOX(iter->data))
if (GTK_IS_COMBO_BOX(widget))
{
renderer = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(iter->data), renderer, TRUE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(iter->data),
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), renderer, TRUE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(widget),
renderer, "text", 0, NULL);
}
}
g_slist_free(all_objects);
g_object_unref(builder);
/* FIXME: we don't want to loose all the unpacked GObjects which
* gets destroyed here, so we'll free the builder at the end */
//g_object_unref(builder);
}
@ -2226,8 +2308,20 @@ void ui_init(void)
void ui_finalize_builder(void)
{
if (objects_table != NULL)
g_hash_table_destroy(objects_table);
if (GTK_IS_BUILDER(builder))
g_object_unref(builder);
/* cleanup refs lingering even after GtkBuilder is destroyed */
if (GTK_IS_WIDGET(edit_menu1))
gtk_widget_destroy(edit_menu1);
if (GTK_IS_WIDGET(prefs_dialog))
gtk_widget_destroy(prefs_dialog);
if (GTK_IS_WIDGET(project_dialog))
gtk_widget_destroy(project_dialog);
if (GTK_IS_WIDGET(toolbar_popup_menu1))
gtk_widget_destroy(toolbar_popup_menu1);
if (GTK_IS_WIDGET(window1))
gtk_widget_destroy(window1);
}
@ -2311,86 +2405,40 @@ void ui_widget_set_tooltip_text(GtkWidget *widget, const gchar *text)
* Call it with the toplevel widget in the component (i.e. a window/dialog),
* or alternatively any widget in the component, and the name of the widget
* you want returned.
*
* @note Since 0.21 the @a widget parameter is not used and can be set
* to NULL if you like.
*
* @param widget Widget with the @a widget_name property set.
* @param widget_name Name to lookup.
* @return The widget found.
* @see ui_hookup_object().
* @see ui_lookup_object().
* @deprecated Use ui_lookup_object instead.
* @see ui_hookup_widget().
*
* @since 0.16
*/
GtkWidget *ui_lookup_widget(GtkWidget *widget, const gchar *widget_name)
{
GtkWidget *found_widget;
(void) widget; /* not used anymore */
GtkWidget *parent, *found_widget;
g_return_val_if_fail(widget != NULL, NULL);
g_return_val_if_fail(widget_name != NULL, NULL);
found_widget = GTK_WIDGET(ui_lookup_object(widget_name));
for (;;)
{
if (GTK_IS_MENU(widget))
parent = gtk_menu_get_attach_widget(GTK_MENU(widget));
else
parent = widget->parent;
if (parent == NULL)
parent = (GtkWidget*) g_object_get_data(G_OBJECT(widget), "GladeParentKey");
if (parent == NULL)
break;
widget = parent;
}
found_widget = (GtkWidget*) g_object_get_data(G_OBJECT(widget), widget_name);
if (G_UNLIKELY(found_widget == NULL))
g_warning("Widget not found: %s", widget_name);
return found_widget;
}
/** Returns a widget from a name.
*
* Call it with the name of the GObject you want returned.
*
* @note The GObject must either be in the GtkBuilder/Glade file or
* have been added with the function @a ui_hookup_object.
*
* @param widget Widget with the @a widget_name property set.
* @param widget_name Name to lookup.
* @return The widget found.
*
* @see ui_hookup_object()
* @since 0.21
*/
GObject *ui_lookup_object(const gchar *object_name)
{
gpointer *found;
g_return_val_if_fail(object_name != NULL, NULL);
g_return_val_if_fail(objects_table != NULL, NULL);
found = g_hash_table_lookup(objects_table, (gconstpointer) object_name);
if (found == NULL)
return NULL;
return G_OBJECT(found);
}
/** Sets a name to lookup GObject @a obj.
*
* The GObject can later be looked-up by the @a name using the
* @a ui_lookup_object() function.
*
* @param obj GObject.
* @param name Name.
*
* @see ui_lookup_object()
* @since 0.21
**/
void ui_hookup_object(GObject *obj, const gchar *object_name)
{
g_return_if_fail(G_IS_OBJECT(obj));
g_return_if_fail(object_name != NULL);
g_return_if_fail(objects_table != NULL);
g_hash_table_insert(objects_table, g_strdup(object_name), g_object_ref(obj));
}
/* Progress Bar */
static guint progress_bar_timer_id = (guint) -1;

View File

@ -24,21 +24,16 @@
/** Sets a name to lookup @a widget from @a owner.
*
* @note Since 0.21 the @a owner parameter is not used and can be set
* to NULL if you like.
*
* @param owner Usually a window, dialog or popup menu.
* @param widget Widget.
* @param widget_name Name.
* @see ui_hookup_object().
* @see ui_lookup_object().
* @deprecated Use ui_hookup_object() instead.
* @see ui_lookup_widget().
*
* @since 0.16
**/
#define ui_hookup_widget(owner, widget, widget_name) \
ui_hookup_object(G_OBJECT(widget), widget_name)
g_object_set_data_full(G_OBJECT(owner), widget_name, \
g_object_ref(widget), (GDestroyNotify)g_object_unref);
/** Interface preferences */
@ -214,9 +209,12 @@ void ui_widget_set_tooltip_text(GtkWidget *widget, const gchar *text);
GtkWidget *ui_lookup_widget(GtkWidget *widget, const gchar *widget_name);
GObject *ui_lookup_object(const gchar *object_name);
void ui_hookup_object(GObject *obj, const gchar *object_name);
/* Compatibility functions */
GtkWidget *create_edit_menu1(void);
GtkWidget *create_prefs_dialog(void);
GtkWidget *create_project_dialog(void);
GtkWidget *create_toolbar_popup_menu1(void);
GtkWidget *create_window1(void);
void ui_widget_set_sensitive(GtkWidget *widget, gboolean set);

View File

@ -489,12 +489,12 @@ static void vte_popup_menu_clicked(GtkMenuItem *menuitem, gpointer user_data)
}
case POPUP_PREFERENCES:
{
GObject *notebook, *tab_page;
GtkWidget *notebook, *tab_page;
prefs_show_dialog();
notebook = ui_lookup_object("notebook2");
tab_page = ui_lookup_object("frame_term");
notebook = ui_lookup_widget(ui_widgets.prefs_dialog, "notebook2");
tab_page = ui_lookup_widget(ui_widgets.prefs_dialog, "frame_term");
gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook),
gtk_notebook_page_num(GTK_NOTEBOOK(notebook), GTK_WIDGET(tab_page)));
@ -737,7 +737,7 @@ void vte_append_preferences_tab(void)
{
GtkWidget *frame_term, *button_shell, *entry_shell;
GtkWidget *check_run_in_vte, *check_skip_script;
GObject *font_button, *fg_color_button, *bg_color_button;
GtkWidget *font_button, *fg_color_button, *bg_color_button;
button_shell = GTK_WIDGET(ui_lookup_widget(ui_widgets.prefs_dialog, "button_term_shell"));
entry_shell = GTK_WIDGET(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_shell"));
@ -751,16 +751,16 @@ void vte_append_preferences_tab(void)
g_signal_connect(G_OBJECT(check_run_in_vte), "toggled",
G_CALLBACK(on_check_run_in_vte_toggled), check_skip_script);
font_button = ui_lookup_object("font_term");
font_button = ui_lookup_widget(ui_widgets.prefs_dialog, "font_term");
g_signal_connect(font_button, "font-set", G_CALLBACK(on_term_font_set), NULL);
fg_color_button = ui_lookup_object("color_fore");
fg_color_button = ui_lookup_widget(ui_widgets.prefs_dialog, "color_fore");
g_signal_connect(fg_color_button, "color-set", G_CALLBACK(on_term_fg_color_set), NULL);
bg_color_button = ui_lookup_object("color_back");
bg_color_button = ui_lookup_widget(ui_widgets.prefs_dialog, "color_back");
g_signal_connect(bg_color_button, "color-set", G_CALLBACK(on_term_bg_color_set), NULL);
frame_term = GTK_WIDGET(ui_lookup_widget(ui_widgets.prefs_dialog, "frame_term"));
frame_term = ui_lookup_widget(ui_widgets.prefs_dialog, "frame_term");
gtk_widget_show_all(frame_term);
}
}