Revision: 3874 http://geany.svn.sourceforge.net/geany/?rev=3874&view=rev Author: eht16 Date: 2009-06-20 16:51:32 +0000 (Sat, 20 Jun 2009)
Log Message: ----------- Instantly reload (i.e. rebuild) the toolbar when ui_toolbar.xml is saved within Geany. Refactor some related code.
Modified Paths: -------------- trunk/ChangeLog trunk/data/ui_toolbar.xml trunk/doc/geany.txt trunk/src/build.c trunk/src/geanymenubuttonaction.c trunk/src/geanymenubuttonaction.h trunk/src/main.c trunk/src/plugins.c trunk/src/templates.c trunk/src/toolbar.c trunk/src/toolbar.h trunk/src/ui_utils.c trunk/src/ui_utils.h
Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-06-18 14:20:07 UTC (rev 3873) +++ trunk/ChangeLog 2009-06-20 16:51:32 UTC (rev 3874) @@ -1,3 +1,14 @@ +2009-06-20 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de> + + * data/ui_toolbar.xml, doc/geany.txt, src/build.c, + src/geanymenubuttonaction.c, src/geanymenubuttonaction.h, src/main.c, + src/plugins.c, src/templates.c, src/toolbar.c, src/toolbar.h, + src/ui_utils.c, src/ui_utils.h: + Instantly reload (i.e. rebuild) the toolbar when ui_toolbar.xml is + saved within Geany. + Refactor some related code. + + 2009-06-18 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
* src/highlighting.c, README.Packagers, HACKING:
Modified: trunk/data/ui_toolbar.xml =================================================================== --- trunk/data/ui_toolbar.xml 2009-06-18 14:20:07 UTC (rev 3873) +++ trunk/data/ui_toolbar.xml 2009-06-20 16:51:32 UTC (rev 3874) @@ -3,10 +3,10 @@ The DTD can be found at http://library.gnome.org/devel/gtk/stable/GtkUIManager.html#GtkUIManager.des....
You can re-order all items and freely add and remove available actions. -You cannot add new actions which are not listed below. +You cannot add new actions which are not listed in the documentation. Everything you add or change must be inside the /ui/toolbar/ path.
-For changes to take effect, you need to restart Geany. +For changes to take effect, simply save this file within Geany or restart Geany.
A list of available actions can be found in the documentation included with Geany or at http://www.geany.org/manual/current/index.html#customizing-the-toolbar.
Modified: trunk/doc/geany.txt =================================================================== --- trunk/doc/geany.txt 2009-06-18 14:20:07 UTC (rev 3873) +++ trunk/doc/geany.txt 2009-06-20 16:51:32 UTC (rev 3874) @@ -3534,11 +3534,11 @@ This file must be valid XML, otherwise the global toolbar UI definition will be used instead.
+Your changes are applied once you save the file. + .. note:: (1) You cannot add new actions which are not listed below. (2) Everything you add or change must be inside the /ui/toolbar/ path. - (3) After you finish editing the file, you need to restart Geany - for changes to take effect.
Available toolbar elements
Modified: trunk/src/build.c =================================================================== --- trunk/src/build.c 2009-06-18 14:20:07 UTC (rev 3873) +++ trunk/src/build.c 2009-06-20 16:51:32 UTC (rev 3874) @@ -94,10 +94,10 @@
static struct { - GtkWidget *run_button; - GtkWidget *compile_button; - GtkWidget *build_button; + GtkAction *run_action; + GtkAction *compile_action; GtkAction *build_action; + GtkWidget *toolmenu;
GtkWidget *toolitem_build; GtkWidget *toolitem_make_all; @@ -130,7 +130,7 @@ static void process_build_output_line(const gchar *line, gint color);
-void build_finalize() +void build_finalize(void) { g_free(build_info.dir); g_free(build_info.custom_target); @@ -139,6 +139,8 @@ gtk_widget_destroy(default_menu_items.menu); if (latex_menu_items.menu != NULL && GTK_IS_WIDGET(latex_menu_items.menu)) gtk_widget_destroy(latex_menu_items.menu); + + g_object_unref(widgets.toolmenu); }
@@ -1627,9 +1629,9 @@ { gtk_widget_set_sensitive(menubar_build_menu, FALSE); gtk_menu_item_remove_submenu(GTK_MENU_ITEM(menubar_build_menu)); - ui_widget_set_sensitive(widgets.compile_button, FALSE); - ui_widget_set_sensitive(widgets.build_button, FALSE); - ui_widget_set_sensitive(widgets.run_button, FALSE); + gtk_action_set_sensitive(widgets.compile_action, FALSE); + gtk_action_set_sensitive(widgets.build_action, FALSE); + gtk_action_set_sensitive(widgets.run_action, FALSE); return; } else @@ -1703,10 +1705,10 @@ if (widgets.toolitem_set_args != NULL) gtk_widget_set_sensitive(widgets.toolitem_set_args, can_set_args);
- ui_widget_set_sensitive(widgets.compile_button, + gtk_action_set_sensitive(widgets.compile_action, can_build && ft->actions->can_compile && NZV(ft->programs->compiler)); - ui_widget_set_sensitive(widgets.build_button, can_make); - ui_widget_set_sensitive(widgets.run_button, can_run || can_stop); + gtk_action_set_sensitive(widgets.build_action, can_make); + gtk_action_set_sensitive(widgets.run_action, can_run || can_stop);
/* show the stop command if a program is running, otherwise show run command */ set_stop_button(can_stop); @@ -1725,21 +1727,20 @@ static void set_stop_button(gboolean stop) { GtkStockItem sitem; + GtkToolButton *run_button; GtkWidget *menuitem = build_get_menu_items(run_info.file_type_id)->item_exec;
- if (widgets.run_button == NULL) + run_button = GTK_TOOL_BUTTON(toolbar_get_widget_by_name("Run")); + if (stop && utils_str_equal(gtk_tool_button_get_stock_id(run_button), "gtk-stop")) return; + if (! stop && utils_str_equal(gtk_tool_button_get_stock_id(run_button), "gtk-execute")) + return;
- if (stop && utils_str_equal( - gtk_tool_button_get_stock_id(GTK_TOOL_BUTTON(widgets.run_button)), "gtk-stop")) return; - if (! stop && utils_str_equal( - gtk_tool_button_get_stock_id(GTK_TOOL_BUTTON(widgets.run_button)), "gtk-execute")) return; - /* use the run button also as stop button */ if (stop) { - gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(widgets.run_button), "gtk-stop"); + gtk_tool_button_set_stock_id(run_button, "gtk-stop");
if (menuitem != NULL) { @@ -1752,7 +1753,7 @@ } else { - gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(widgets.run_button), "gtk-execute"); + gtk_tool_button_set_stock_id(run_button, "gtk-execute");
if (menuitem != NULL) { @@ -2095,66 +2096,69 @@ }
-void build_init() +void build_init(void) { GtkWidget *item; GtkWidget *toolmenu;
- widgets.build_action = toolbar_get_action_by_name("Build"); - toolmenu = geany_menu_button_action_get_menu(GEANY_MENU_BUTTON_ACTION(widgets.build_action)); + /* create the toolbar Build item sub menu */ + toolmenu = gtk_menu_new(); + g_object_ref(toolmenu);
- if (toolmenu != NULL) - { - /* build the code */ - item = ui_image_menu_item_new(GEANY_STOCK_BUILD, _("_Build")); - gtk_widget_show(item); - gtk_container_add(GTK_CONTAINER(toolmenu), item); - g_signal_connect(item, "activate", G_CALLBACK(on_toolbutton_build_activate), NULL); - widgets.toolitem_build = item; + /* build the code */ + item = ui_image_menu_item_new(GEANY_STOCK_BUILD, _("_Build")); + gtk_widget_show(item); + gtk_container_add(GTK_CONTAINER(toolmenu), item); + g_signal_connect(item, "activate", G_CALLBACK(on_toolbutton_build_activate), NULL); + widgets.toolitem_build = item;
- item = gtk_separator_menu_item_new(); - gtk_widget_show(item); - gtk_container_add(GTK_CONTAINER(toolmenu), item); + item = gtk_separator_menu_item_new(); + gtk_widget_show(item); + gtk_container_add(GTK_CONTAINER(toolmenu), item);
- /* build the code with make all */ - item = gtk_image_menu_item_new_with_mnemonic(_("_Make All")); - gtk_widget_show(item); - gtk_container_add(GTK_CONTAINER(toolmenu), item); - g_signal_connect(item, "activate", G_CALLBACK(on_toolbutton_make_activate), - GINT_TO_POINTER(GBO_MAKE_ALL)); - widgets.toolitem_make_all = item; + /* build the code with make all */ + item = gtk_image_menu_item_new_with_mnemonic(_("_Make All")); + gtk_widget_show(item); + gtk_container_add(GTK_CONTAINER(toolmenu), item); + g_signal_connect(item, "activate", G_CALLBACK(on_toolbutton_make_activate), + GINT_TO_POINTER(GBO_MAKE_ALL)); + widgets.toolitem_make_all = item;
- /* build the code with make custom */ - item = gtk_image_menu_item_new_with_mnemonic(_("Make Custom _Target")); - gtk_widget_show(item); - gtk_container_add(GTK_CONTAINER(toolmenu), item); - g_signal_connect(item, "activate", G_CALLBACK(on_toolbutton_make_activate), - GINT_TO_POINTER(GBO_MAKE_CUSTOM)); - widgets.toolitem_make_custom = item; + /* build the code with make custom */ + item = gtk_image_menu_item_new_with_mnemonic(_("Make Custom _Target")); + gtk_widget_show(item); + gtk_container_add(GTK_CONTAINER(toolmenu), item); + g_signal_connect(item, "activate", G_CALLBACK(on_toolbutton_make_activate), + GINT_TO_POINTER(GBO_MAKE_CUSTOM)); + widgets.toolitem_make_custom = item;
- /* build the code with make object */ - item = gtk_image_menu_item_new_with_mnemonic(_("Make _Object")); - gtk_widget_show(item); - gtk_container_add(GTK_CONTAINER(toolmenu), item); - g_signal_connect(item, "activate", G_CALLBACK(on_toolbutton_make_activate), - GINT_TO_POINTER(GBO_MAKE_OBJECT)); - widgets.toolitem_make_object = item; + /* build the code with make object */ + item = gtk_image_menu_item_new_with_mnemonic(_("Make _Object")); + gtk_widget_show(item); + gtk_container_add(GTK_CONTAINER(toolmenu), item); + g_signal_connect(item, "activate", G_CALLBACK(on_toolbutton_make_activate), + GINT_TO_POINTER(GBO_MAKE_OBJECT)); + widgets.toolitem_make_object = item;
- item = gtk_separator_menu_item_new(); - gtk_widget_show(item); - gtk_container_add(GTK_CONTAINER(toolmenu), item); + item = gtk_separator_menu_item_new(); + gtk_widget_show(item); + gtk_container_add(GTK_CONTAINER(toolmenu), item);
- /* arguments */ - item = ui_image_menu_item_new(GTK_STOCK_PREFERENCES, _("_Set Includes and Arguments")); - gtk_widget_show(item); - gtk_container_add(GTK_CONTAINER(toolmenu), item); - g_signal_connect(item, "activate", G_CALLBACK(on_build_arguments_activate), NULL); - widgets.toolitem_set_args = item; - } + /* arguments */ + item = ui_image_menu_item_new(GTK_STOCK_PREFERENCES, _("_Set Includes and Arguments")); + gtk_widget_show(item); + gtk_container_add(GTK_CONTAINER(toolmenu), item); + g_signal_connect(item, "activate", G_CALLBACK(on_build_arguments_activate), NULL); + widgets.toolitem_set_args = item;
- widgets.compile_button = toolbar_get_widget_by_name("Compile"); - widgets.run_button = toolbar_get_widget_by_name("Run"); - widgets.build_button = toolbar_get_widget_by_name("Build"); + + /* get toolbar action pointers */ + widgets.build_action = toolbar_get_action_by_name("Build"); + widgets.compile_action = toolbar_get_action_by_name("Compile"); + widgets.run_action = toolbar_get_action_by_name("Run"); + widgets.toolmenu = toolmenu; + /* set the submenu to the toolbar item */ + geany_menu_button_action_set_menu(GEANY_MENU_BUTTON_ACTION(widgets.build_action), toolmenu); }
Modified: trunk/src/geanymenubuttonaction.c =================================================================== --- trunk/src/geanymenubuttonaction.c 2009-06-18 14:20:07 UTC (rev 3873) +++ trunk/src/geanymenubuttonaction.c 2009-06-20 16:51:32 UTC (rev 3874) @@ -26,6 +26,7 @@
#include "geany.h" #include "support.h" +#include "utils.h" #include "geanymenubuttonaction.h"
@@ -37,9 +38,7 @@
struct _GeanyMenubuttonActionPrivate { - GtkWidget *button; GtkWidget *menu; - gboolean menu_added; };
enum @@ -64,48 +63,12 @@ }
-static void menu_filled_cb(GtkContainer *container, GtkWidget *widget, gpointer data) -{ - GeanyMenubuttonActionPrivate *priv = GEANY_MENU_BUTTON_ACTION_GET_PRIVATE(data); - - if (! priv->menu_added) - { - gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(priv->button), priv->menu); - priv->menu_added = TRUE; - } -} - - -static void geany_menu_button_action_connect_proxy(GtkAction *action, GtkWidget *widget) -{ - GeanyMenubuttonActionPrivate *priv = GEANY_MENU_BUTTON_ACTION_GET_PRIVATE(action); - /* add the menu to the menu button once it got items ("add" from GtkContainer) */ - g_signal_connect(priv->menu, "add", G_CALLBACK(menu_filled_cb), action); - - GTK_ACTION_CLASS(geany_menu_button_action_parent_class)->connect_proxy(action, widget); -} - - static void delegate_button_activated(GtkAction *action) { g_signal_emit(action, signals[BUTTON_CLICKED], 0); }
-static GtkWidget *geany_menu_button_action_create_tool_item(GtkAction *action) -{ - GeanyMenubuttonActionPrivate *priv = GEANY_MENU_BUTTON_ACTION_GET_PRIVATE(action); - - priv->menu = gtk_menu_new(); - g_object_ref(priv->menu); - gtk_widget_show(priv->menu); - - priv->button = g_object_new(GTK_TYPE_MENU_TOOL_BUTTON, NULL); - - return priv->button; -} - - static void geany_menu_button_action_class_init(GeanyMenubuttonActionClass *klass) { GtkActionClass *action_class = GTK_ACTION_CLASS(klass); @@ -114,8 +77,6 @@ g_object_class->finalize = geany_menu_button_action_finalize;
action_class->activate = delegate_button_activated; - action_class->connect_proxy = geany_menu_button_action_connect_proxy; - action_class->create_tool_item = geany_menu_button_action_create_tool_item; action_class->toolbar_item_type = GTK_TYPE_MENU_TOOL_BUTTON;
g_type_class_add_private(klass, sizeof(GeanyMenubuttonActionPrivate)); @@ -133,11 +94,7 @@
static void geany_menu_button_action_init(GeanyMenubuttonAction *action) { - GeanyMenubuttonActionPrivate *priv = GEANY_MENU_BUTTON_ACTION_GET_PRIVATE(action); - - priv->menu = NULL; - priv->button = NULL; - priv->menu_added = FALSE; + /* nothing to do */ }
@@ -167,3 +124,22 @@
return priv->menu; } + + +void geany_menu_button_action_set_menu(GeanyMenubuttonAction *action, GtkWidget *menu) +{ + GeanyMenubuttonActionPrivate *priv; + GSList *l; + + g_return_if_fail(action != NULL); + g_return_if_fail(menu != NULL); + + priv = GEANY_MENU_BUTTON_ACTION_GET_PRIVATE(action); + + priv->menu = menu; + + foreach_slist(l, gtk_action_get_proxies(GTK_ACTION(action))) + { + gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(l->data), priv->menu); + } +}
Modified: trunk/src/geanymenubuttonaction.h =================================================================== --- trunk/src/geanymenubuttonaction.h 2009-06-18 14:20:07 UTC (rev 3873) +++ trunk/src/geanymenubuttonaction.h 2009-06-20 16:51:32 UTC (rev 3874) @@ -55,6 +55,8 @@ const gchar *stock_id); GtkWidget* geany_menu_button_action_get_menu (GeanyMenubuttonAction *action);
+void geany_menu_button_action_set_menu (GeanyMenubuttonAction *action, GtkWidget *menu); + G_END_DECLS
#endif /* __GEANY_MENU_BUTTON_ACTION_H__ */
Modified: trunk/src/main.c =================================================================== --- trunk/src/main.c 2009-06-18 14:20:07 UTC (rev 3873) +++ trunk/src/main.c 2009-06-20 16:51:32 UTC (rev 3874) @@ -192,37 +192,7 @@ } ui_sidebar_show_hide();
- /* sets the icon style of the toolbar */ - switch (toolbar_prefs.icon_style) - { - case GTK_TOOLBAR_BOTH: - { - /*gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ui_lookup_widget(main_widgets.window, "images_and_text1")), TRUE);*/ - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ui_lookup_widget(ui_widgets.toolbar_menu, "images_and_text2")), TRUE); - break; - } - case GTK_TOOLBAR_ICONS: - { - /*gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ui_lookup_widget(main_widgets.window, "images_only1")), TRUE);*/ - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ui_lookup_widget(ui_widgets.toolbar_menu, "images_only2")), TRUE); - break; - } - case GTK_TOOLBAR_TEXT: - { - /*gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ui_lookup_widget(main_widgets.window, "text_only1")), TRUE);*/ - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ui_lookup_widget(ui_widgets.toolbar_menu, "text_only2")), TRUE); - break; - } - } - gtk_toolbar_set_style(GTK_TOOLBAR(main_widgets.toolbar), toolbar_prefs.icon_style); - - /* sets the icon size of the toolbar, use user preferences (.gtkrc) if not set */ - if (toolbar_prefs.icon_size == GTK_ICON_SIZE_SMALL_TOOLBAR || - toolbar_prefs.icon_size == GTK_ICON_SIZE_LARGE_TOOLBAR || - toolbar_prefs.icon_size == GTK_ICON_SIZE_MENU) - { - gtk_toolbar_set_icon_size(GTK_TOOLBAR(main_widgets.toolbar), toolbar_prefs.icon_size); - } + toolbar_apply_settings(); toolbar_update_ui();
ui_update_view_editor_menu_items(); @@ -275,11 +245,6 @@ main_status.opening_session_files = FALSE;
main_widgets.window = create_window1(); - /* add recent files to the File menu */ - ui_widgets.recent_files_menuitem = ui_lookup_widget(main_widgets.window, "recent_files1"); - ui_widgets.recent_files_menu_menubar = gtk_menu_new(); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(ui_widgets.recent_files_menuitem), - ui_widgets.recent_files_menu_menubar);
/* add recent projects to the Project menu */ ui_widgets.recent_projects_menuitem = ui_lookup_widget(main_widgets.window, "recent_projects1"); @@ -1018,22 +983,12 @@ }
/* registering some basic events */ - { - GtkWidget *entry; + g_signal_connect(main_widgets.window, "delete-event", G_CALLBACK(on_exit_clicked), NULL); + g_signal_connect(main_widgets.window, "window-state-event", G_CALLBACK(on_window_state_event), NULL);
- g_signal_connect(main_widgets.window, "delete-event", G_CALLBACK(on_exit_clicked), NULL); - g_signal_connect(main_widgets.window, "window-state-event", G_CALLBACK(on_window_state_event), NULL); - g_signal_connect(main_widgets.toolbar, "button-press-event", G_CALLBACK(toolbar_popup_menu), NULL); + g_signal_connect(ui_lookup_widget(main_widgets.window, "textview_scribble"), + "motion-notify-event", G_CALLBACK(on_motion_event), NULL);
- g_signal_connect(ui_lookup_widget(main_widgets.window, "textview_scribble"), - "motion-notify-event", G_CALLBACK(on_motion_event), NULL); - entry = toolbar_get_widget_child_by_name("SearchEntry"); - if (entry != NULL) - g_signal_connect(entry, "motion-notify-event", G_CALLBACK(on_motion_event), NULL); - entry = toolbar_get_widget_child_by_name("GotoEntry"); - if (entry != NULL) - g_signal_connect(entry, "motion-notify-event", G_CALLBACK(on_motion_event), NULL); - } #ifdef HAVE_VTE vte_init(); #endif
Modified: trunk/src/plugins.c =================================================================== --- trunk/src/plugins.c 2009-06-18 14:20:07 UTC (rev 3873) +++ trunk/src/plugins.c 2009-06-20 16:51:32 UTC (rev 3874) @@ -1325,12 +1325,16 @@ autosep->widget = GTK_WIDGET(sep);
gtk_toolbar_insert(toolbar, item, pos + 1); + + toolbar_item_ref(sep); + toolbar_item_ref(item); } else { pos = gtk_toolbar_get_item_index(toolbar, GTK_TOOL_ITEM(autosep->widget)); g_return_if_fail(pos >= 0); gtk_toolbar_insert(toolbar, item, pos); + toolbar_item_ref(item); } /* hide the separator widget if there are no toolbar items showing for the plugin */ ui_auto_separator_add_ref(autosep, GTK_WIDGET(item));
Modified: trunk/src/templates.c =================================================================== --- trunk/src/templates.c 2009-06-18 14:20:07 UTC (rev 3873) +++ trunk/src/templates.c 2009-06-20 16:51:32 UTC (rev 3874) @@ -37,6 +37,8 @@ #include "document.h" #include "filetypes.h" #include "ui_utils.h" +#include "toolbar.h" +#include "geanymenubuttonaction.h"
GeanyTemplatePrefs template_prefs; @@ -360,7 +362,7 @@
/* template items for the new file menu */ -static void create_new_menu_items(void) +static void create_new_menu_items(GtkWidget *toolbar_new_file_menu) { GSList *node;
@@ -378,13 +380,10 @@ gtk_container_add(GTK_CONTAINER(new_with_template_menu), tmp_menu); g_signal_connect(tmp_menu, "activate", G_CALLBACK(on_new_with_template), ft);
- if (ui_widgets.new_file_menu != NULL) - { - tmp_button = gtk_menu_item_new_with_label(label); - gtk_widget_show(tmp_button); - gtk_container_add(GTK_CONTAINER(ui_widgets.new_file_menu), tmp_button); - g_signal_connect(tmp_button, "activate", G_CALLBACK(on_new_with_template), ft); - } + tmp_button = gtk_menu_item_new_with_label(label); + gtk_widget_show(tmp_button); + gtk_container_add(GTK_CONTAINER(toolbar_new_file_menu), tmp_button); + g_signal_connect(tmp_button, "activate", G_CALLBACK(on_new_with_template), ft); } }
@@ -443,6 +442,7 @@ static void add_file_item(gpointer data, gpointer user_data) { GtkWidget *tmp_menu, *tmp_button; + GtkWidget *toolbar_new_file_menu = user_data; gchar *label;
g_return_if_fail(data); @@ -454,13 +454,11 @@ gtk_container_add(GTK_CONTAINER(new_with_template_menu), tmp_menu); g_signal_connect(tmp_menu, "activate", G_CALLBACK(on_new_with_file_template), NULL);
- if (ui_widgets.new_file_menu != NULL) - { - tmp_button = gtk_menu_item_new_with_label(label); - gtk_widget_show(tmp_button); - gtk_container_add(GTK_CONTAINER(ui_widgets.new_file_menu), tmp_button); - g_signal_connect(tmp_button, "activate", G_CALLBACK(on_new_with_file_template), NULL); - } + tmp_button = gtk_menu_item_new_with_label(label); + gtk_widget_show(tmp_button); + gtk_container_add(GTK_CONTAINER(toolbar_new_file_menu), tmp_button); + g_signal_connect(tmp_button, "activate", G_CALLBACK(on_new_with_file_template), NULL); + g_free(label); }
@@ -485,7 +483,7 @@ }
-static gboolean add_custom_template_items(void) +static gboolean add_custom_template_items(GtkWidget *toolbar_new_file_menu) { gchar *path = g_build_path(G_DIR_SEPARATOR_S, app->configdir, GEANY_TEMPLATES_SUBDIR, "files", NULL); @@ -497,7 +495,7 @@ return FALSE; } list = g_slist_sort(list, compare_filenames_by_filetype); - g_slist_foreach(list, add_file_item, NULL); + g_slist_foreach(list, add_file_item, toolbar_new_file_menu); g_slist_foreach(list, (GFunc) g_free, NULL); g_slist_free(list); g_free(path); @@ -508,23 +506,28 @@ static void create_file_template_menus(void) { GtkWidget *sep1, *sep2 = NULL; + GtkWidget *toolbar_new_file_menu = NULL;
new_with_template_menu = ui_lookup_widget(main_widgets.window, "menu_new_with_template1_menu"); - create_new_menu_items(); + toolbar_new_file_menu = gtk_menu_new(); + /* we hold our own ref on the menu in case it is not used in the toolbar */ + g_object_ref(toolbar_new_file_menu);
+ create_new_menu_items(toolbar_new_file_menu); + sep1 = gtk_separator_menu_item_new(); gtk_container_add(GTK_CONTAINER(new_with_template_menu), sep1); - if (ui_widgets.new_file_menu != NULL) + sep2 = gtk_separator_menu_item_new(); + gtk_container_add(GTK_CONTAINER(toolbar_new_file_menu), sep2); + + if (add_custom_template_items(toolbar_new_file_menu)) { - sep2 = gtk_separator_menu_item_new(); - gtk_container_add(GTK_CONTAINER(ui_widgets.new_file_menu), sep2); - } - if (add_custom_template_items()) - { gtk_widget_show(sep1); - if (sep2 != NULL) - gtk_widget_show(sep2); + gtk_widget_show(sep2); } + + geany_menu_button_action_set_menu(GEANY_MENU_BUTTON_ACTION( + toolbar_get_action_by_name("New")), toolbar_new_file_menu); }
@@ -806,6 +809,8 @@ { gint i; GList *children, *item; + GtkWidget *toolbar_new_file_menu = geany_menu_button_action_get_menu( + GEANY_MENU_BUTTON_ACTION(toolbar_get_action_by_name("New")));
for (i = 0; i < GEANY_MAX_TEMPLATES; i++) { @@ -816,16 +821,14 @@ g_free(ft_templates[i]); } /* destroy "New with template" sub menu items (in case we want to reload the templates) */ - if (ui_widgets.new_file_menu != NULL) + children = gtk_container_get_children(GTK_CONTAINER(toolbar_new_file_menu)); + foreach_list(item, children) { - children = gtk_container_get_children(GTK_CONTAINER(ui_widgets.new_file_menu)); - for (item = children; item != NULL; item = g_list_next(item)) - { - gtk_widget_destroy(GTK_WIDGET(item->data)); - } + gtk_widget_destroy(GTK_WIDGET(item->data)); } + g_object_unref(toolbar_new_file_menu); children = gtk_container_get_children(GTK_CONTAINER(new_with_template_menu)); - for (item = children; item != NULL; item = g_list_next(item)) + foreach_list(item, children) { gtk_widget_destroy(GTK_WIDGET(item->data)); }
Modified: trunk/src/toolbar.c =================================================================== --- trunk/src/toolbar.c 2009-06-18 14:20:07 UTC (rev 3873) +++ trunk/src/toolbar.c 2009-06-20 16:51:32 UTC (rev 3874) @@ -35,6 +35,7 @@ #include "dialogs.h" #include "document.h" #include "build.h" +#include "main.h" #include "geanymenubuttonaction.h" #include "geanyentryaction.h"
@@ -43,11 +44,12 @@ GeanyToolbarPrefs toolbar_prefs; static GtkUIManager *uim; static GtkActionGroup *group; +static GSList *plugin_items = NULL;
- /* Available toolbar actions * Fields: name, stock_id, label, accelerator, tooltip, callback */ const GtkActionEntry ui_entries[] = { + /* custom actions defined in toolbar_init(): "New", "Open", "SearchEntry", "GotoEntry", "Build" */ { "Save", GTK_STOCK_SAVE, NULL, NULL, N_("Save the current file"), G_CALLBACK(on_toolbutton_save_clicked) }, { "SaveAll", GEANY_STOCK_SAVE_ALL, N_("Save All"), NULL, N_("Save all open files"), G_CALLBACK(on_save_all1_activate) }, { "Reload", GTK_STOCK_REVERT_TO_SAVED, NULL, NULL, N_("Reload the current file from disk"), G_CALLBACK(on_toolbutton_reload_clicked) }, @@ -109,6 +111,10 @@ "</ui>";
+/* Note: The returned widget pointer is only valid until the toolbar is reloaded. So, either + * update the widget pointer in this case (i.e. request it again) or better use + * toolbar_get_action_by_name() instead. The action objects will remain the same even when the + * toolbar is reloaded. */ GtkWidget *toolbar_get_widget_by_name(const gchar *name) { GtkWidget *widget; @@ -124,6 +130,8 @@ }
+/* Note: The returned widget pointer is only valid until the toolbar is reloaded. See + * toolbar_get_widget_by_name for details(). */ GtkWidget *toolbar_get_widget_child_by_name(const gchar *name) { GtkWidget *widget = toolbar_get_widget_by_name(name); @@ -143,15 +151,171 @@ }
-static void on_document_save(G_GNUC_UNUSED GObject *object, GeanyDocument *doc, +static void toolbar_item_destroy_cb(GtkWidget *widget, G_GNUC_UNUSED gpointer data) +{ + plugin_items = g_slist_remove(plugin_items, widget); +} + + +void toolbar_item_ref(GtkToolItem *item) +{ + g_return_if_fail(item != NULL); + + plugin_items = g_slist_append(plugin_items, item); + g_signal_connect(item, "destroy", G_CALLBACK(toolbar_item_destroy_cb), NULL); +} + + +static GtkWidget *toolbar_reload(void) +{ + gint i; + GSList *l; + GtkWidget *entry; + GError *error = NULL; + const gchar *filename; + static guint merge_id = 0; + GtkWidget *toolbar_new_file_menu = NULL; + GtkWidget *toolbar_recent_files_menu = NULL; + GtkWidget *toolbar_build_menu = NULL; + + /* Cleanup old toolbar */ + if (merge_id > 0) + { + /* ref plugins toolbar items to keep them after we destroyed the toolbar */ + foreach_slist(l, plugin_items) + { + g_object_ref(l->data); + gtk_container_remove(GTK_CONTAINER(main_widgets.toolbar), GTK_WIDGET(l->data)); + } + /* ref and hold the submenus of the New, Open and Build toolbar items */ + toolbar_new_file_menu = geany_menu_button_action_get_menu( + GEANY_MENU_BUTTON_ACTION(gtk_action_group_get_action(group, "New"))); + g_object_ref(toolbar_new_file_menu); + toolbar_recent_files_menu = geany_menu_button_action_get_menu( + GEANY_MENU_BUTTON_ACTION(gtk_action_group_get_action(group, "Open"))); + g_object_ref(toolbar_recent_files_menu); + toolbar_build_menu = geany_menu_button_action_get_menu( + GEANY_MENU_BUTTON_ACTION(gtk_action_group_get_action(group, "Build"))); + g_object_ref(toolbar_build_menu); + + /* Get rid of it! */ + gtk_widget_destroy(main_widgets.toolbar); + + gtk_ui_manager_remove_ui(uim, merge_id); + gtk_ui_manager_ensure_update(uim); + } + + /* Load the toolbar UI XML file from disk (first from config dir, then try data dir) */ + filename = utils_build_path(app->configdir, "ui_toolbar.xml", NULL); + merge_id = gtk_ui_manager_add_ui_from_file(uim, filename, &error); + if (merge_id == 0) + { + if (error->code != G_FILE_ERROR_NOENT) + geany_debug("Loading user toolbar UI definition failed (%s).", error->message); + g_error_free(error); + error = NULL; + + filename = utils_build_path(app->datadir, "ui_toolbar.xml", NULL); + merge_id = gtk_ui_manager_add_ui_from_file(uim, filename, &error); + if (merge_id == 0) + { + geany_debug( + "UI creation failed, using internal fallback definition. Error message: %s", + error->message); + g_error_free(error); + /* finally load the internally defined markup as fallback */ + merge_id = gtk_ui_manager_add_ui_from_string(uim, toolbar_markup, -1, NULL); + } + } + + main_widgets.toolbar = gtk_ui_manager_get_widget(uim, "/ui/GeanyToolbar"); + ui_init_toolbar_widgets(); + + /* add the toolbar again to the main window */ + if (toolbar_prefs.append_to_menu) + { + GtkWidget *hbox_menubar = ui_lookup_widget(main_widgets.window, "hbox_menubar"); + gtk_box_pack_start(GTK_BOX(hbox_menubar), main_widgets.toolbar, TRUE, TRUE, 0); + gtk_box_reorder_child(GTK_BOX(hbox_menubar), main_widgets.toolbar, 1); + } + else + { + GtkWidget *box = ui_lookup_widget(main_widgets.window, "vbox1"); + + gtk_box_pack_start(GTK_BOX(box), main_widgets.toolbar, FALSE, FALSE, 0); + gtk_box_reorder_child(GTK_BOX(box), main_widgets.toolbar, 1); + } + gtk_widget_show(main_widgets.toolbar); + + /* re-add und unref the plugin toolbar items */ + i = toolbar_get_insert_position(); + foreach_slist(l, plugin_items) + { + gtk_toolbar_insert(GTK_TOOLBAR(main_widgets.toolbar), l->data, i); + g_object_unref(l->data); + i++; + } + /* re-add und unref the submenus of menu toolbar items */ + if (toolbar_new_file_menu != NULL) + { + geany_menu_button_action_set_menu(GEANY_MENU_BUTTON_ACTION( + gtk_action_group_get_action(group, "New")), toolbar_new_file_menu); + g_object_unref(toolbar_new_file_menu); + } + if (toolbar_recent_files_menu != NULL) + { + geany_menu_button_action_set_menu(GEANY_MENU_BUTTON_ACTION( + gtk_action_group_get_action(group, "Open")), toolbar_recent_files_menu); + g_object_unref(toolbar_recent_files_menu); + } + if (toolbar_build_menu != NULL) + { + geany_menu_button_action_set_menu(GEANY_MENU_BUTTON_ACTION( + gtk_action_group_get_action(group, "Build")), toolbar_build_menu); + g_object_unref(toolbar_build_menu); + } + + /* update button states */ + if (main_status.main_window_realized) + { + GeanyDocument *doc = document_get_current(); + + ui_document_buttons_update(); + ui_save_buttons_toggle(doc->changed); /* update save all */ + ui_update_popup_reundo_items(doc); + + toolbar_apply_settings(); + } + + /* Signals */ + g_signal_connect(main_widgets.toolbar, "button-press-event", + G_CALLBACK(toolbar_popup_menu), NULL); + g_signal_connect(main_widgets.toolbar, "key-press-event", + G_CALLBACK(on_escape_key_press_event), NULL); + + /* We don't need to disconnect those signals as this is done automatically when the entry + * widgets are destroyed, happens when the toolbar itself is destroyed. */ + entry = toolbar_get_widget_child_by_name("SearchEntry"); + if (entry != NULL) + g_signal_connect(entry, "motion-notify-event", G_CALLBACK(on_motion_event), NULL); + entry = toolbar_get_widget_child_by_name("GotoEntry"); + if (entry != NULL) + g_signal_connect(entry, "motion-notify-event", G_CALLBACK(on_motion_event), NULL); + + + return main_widgets.toolbar; +} + + +static void document_save_cb(G_GNUC_UNUSED GObject *object, GeanyDocument *doc, G_GNUC_UNUSED gpointer data) { g_return_if_fail(NZV(doc->real_path));
if (utils_str_equal(doc->real_path, utils_build_path(app->configdir, "ui_toolbar.xml", NULL))) { - ui_set_statusbar(FALSE, "%s", - _("For all changes you make in this file to take effect, you need to restart Geany.")); + main_widgets.toolbar = toolbar_reload(); + ui_set_statusbar(FALSE, _("Toolbar reloaded.")); } }
@@ -160,7 +324,7 @@ { ui_add_config_file_menu_item( utils_build_path(app->configdir, "ui_toolbar.xml", NULL), NULL, NULL); - g_signal_connect(geany_object, "document-save", G_CALLBACK(on_document_save), NULL); + g_signal_connect(geany_object, "document-save", G_CALLBACK(document_save_cb), NULL); }
@@ -172,8 +336,6 @@ GtkAction *action_build; GtkAction *action_searchentry; GtkAction *action_gotoentry; - GError *error = NULL; - const gchar *filename;
uim = gtk_ui_manager_new(); group = gtk_action_group_new("GeanyToolbar"); @@ -213,36 +375,8 @@
gtk_ui_manager_insert_action_group(uim, group, 0);
- /* Load the toolbar UI XML file from disk (first from config dir, then try data dir) */ - filename = utils_build_path(app->configdir, "ui_toolbar.xml", NULL); - if (! gtk_ui_manager_add_ui_from_file(uim, filename, &error)) - { - if (error->code != G_FILE_ERROR_NOENT) - geany_debug("Loading user toolbar UI definition failed (%s).", error->message); - g_error_free(error); - error = NULL; + toolbar = toolbar_reload();
- filename = utils_build_path(app->datadir, "ui_toolbar.xml", NULL); - if (! gtk_ui_manager_add_ui_from_file(uim, filename, &error)) - { - geany_debug( - "UI creation failed, using internal fallback definition. Error message: %s", - error->message); - g_error_free(error); - /* finally load the internally defined markup as fallback */ - gtk_ui_manager_add_ui_from_string(uim, toolbar_markup, -1, NULL); - } - } - - /* Set some pointers */ - toolbar = gtk_ui_manager_get_widget(uim, "/ui/GeanyToolbar"); - ui_widgets.new_file_menu = geany_menu_button_action_get_menu( - GEANY_MENU_BUTTON_ACTION(action_new)); - ui_widgets.recent_files_menu_toolbar = geany_menu_button_action_get_menu( - GEANY_MENU_BUTTON_ACTION(action_open)); - - g_signal_connect(toolbar, "key-press-event", G_CALLBACK(on_escape_key_press_event), NULL); - return toolbar; }
@@ -352,7 +486,48 @@
void toolbar_finalize(void) { - /* unref'ing the GtkUIManager object will destroy all its widgets unless they were ref'ed */ + g_object_unref(geany_menu_button_action_get_menu( + GEANY_MENU_BUTTON_ACTION(toolbar_get_action_by_name("Open")))); + + /* unref'ing the GtkUIManager object will destroy all its widgets unless they were ref'ed */ g_object_unref(uim); - g_object_unref(group); + g_object_unref(group); + + g_slist_free(plugin_items); } + + +void toolbar_apply_settings(void) +{ + /* sets the icon style of the toolbar */ + switch (toolbar_prefs.icon_style) + { + case GTK_TOOLBAR_BOTH: + { + /*gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ui_lookup_widget(main_widgets.window, "images_and_text1")), TRUE);*/ + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ui_lookup_widget(ui_widgets.toolbar_menu, "images_and_text2")), TRUE); + break; + } + case GTK_TOOLBAR_ICONS: + { + /*gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ui_lookup_widget(main_widgets.window, "images_only1")), TRUE);*/ + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ui_lookup_widget(ui_widgets.toolbar_menu, "images_only2")), TRUE); + break; + } + case GTK_TOOLBAR_TEXT: + { + /*gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ui_lookup_widget(main_widgets.window, "text_only1")), TRUE);*/ + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ui_lookup_widget(ui_widgets.toolbar_menu, "text_only2")), TRUE); + break; + } + } + gtk_toolbar_set_style(GTK_TOOLBAR(main_widgets.toolbar), toolbar_prefs.icon_style); + + /* sets the icon size of the toolbar, use user preferences (.gtkrc) if not set */ + if (toolbar_prefs.icon_size == GTK_ICON_SIZE_SMALL_TOOLBAR || + toolbar_prefs.icon_size == GTK_ICON_SIZE_LARGE_TOOLBAR || + toolbar_prefs.icon_size == GTK_ICON_SIZE_MENU) + { + gtk_toolbar_set_icon_size(GTK_TOOLBAR(main_widgets.toolbar), toolbar_prefs.icon_size); + } +}
Modified: trunk/src/toolbar.h =================================================================== --- trunk/src/toolbar.h 2009-06-18 14:20:07 UTC (rev 3873) +++ trunk/src/toolbar.h 2009-06-20 16:51:32 UTC (rev 3874) @@ -49,6 +49,10 @@
void toolbar_update_ui(void);
+void toolbar_apply_settings(void); + +void toolbar_item_ref(GtkToolItem *item); + GtkWidget *toolbar_init(void);
void toolbar_finalize(void);
Modified: trunk/src/ui_utils.c =================================================================== --- trunk/src/ui_utils.c 2009-06-18 14:20:07 UTC (rev 3873) +++ trunk/src/ui_utils.c 2009-06-20 16:51:32 UTC (rev 3874) @@ -48,6 +48,7 @@ #include "plugins.h" #include "symbols.h" #include "toolbar.h" +#include "geanymenubuttonaction.h"
GeanyInterfacePrefs interface_prefs; @@ -58,7 +59,8 @@
static struct { - /* pointers to widgets only sensitive when there is at least one document */ + /* pointers to widgets only sensitive when there is at least one document, the pointers can + * also be GtkAction objects, so check each pointer before using it */ GPtrArray *document_buttons; GtkWidget *menu_insert_include_items[2]; GtkWidget *popup_goto_items[4]; @@ -610,7 +612,7 @@ g_ptr_array_add(widgets.document_buttons, ui_lookup_widget(main_widgets.window, widget_name))
#define add_doc_toolitem(widget_name) \ - g_ptr_array_add(widgets.document_buttons, toolbar_get_widget_by_name(widget_name)) + g_ptr_array_add(widgets.document_buttons, toolbar_get_action_by_name(widget_name))
static void init_document_widgets(void) { @@ -686,7 +688,10 @@ for (i = 0; i < widgets.document_buttons->len; i++) { GtkWidget *widget = g_ptr_array_index(widgets.document_buttons, i); - ui_widget_set_sensitive(widget, enable); + if (GTK_IS_ACTION(widget)) + gtk_action_set_sensitive(GTK_ACTION(widget), enable); + else + ui_widget_set_sensitive(widget, enable); } }
@@ -956,7 +961,8 @@ { grf.recent_queue = ui_prefs.recent_queue; grf.menubar = ui_widgets.recent_files_menu_menubar; - grf.toolbar = ui_widgets.recent_files_menu_toolbar; + grf.toolbar = geany_menu_button_action_get_menu(GEANY_MENU_BUTTON_ACTION( + toolbar_get_action_by_name("Open"))); grf.activate_cb = recent_file_activate_cb; } return &grf; @@ -1798,10 +1804,39 @@ }
+void ui_init_toolbar_widgets(void) +{ + widgets.save_buttons[1] = toolbar_get_widget_by_name("Save"); + widgets.save_buttons[3] = toolbar_get_widget_by_name("SaveAll"); + widgets.redo_items[2] = toolbar_get_widget_by_name("Redo"); + widgets.undo_items[2] = toolbar_get_widget_by_name("Undo"); +} + + +static void init_recent_files(void) +{ + GtkWidget *toolbar_recent_files_menu; + + /* add recent files to the File menu */ + ui_widgets.recent_files_menuitem = ui_lookup_widget(main_widgets.window, "recent_files1"); + ui_widgets.recent_files_menu_menubar = gtk_menu_new(); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(ui_widgets.recent_files_menuitem), + ui_widgets.recent_files_menu_menubar); + + /* add recent files to the toolbar Open button */ + toolbar_recent_files_menu = gtk_menu_new(); + g_object_ref(toolbar_recent_files_menu); + geany_menu_button_action_set_menu(GEANY_MENU_BUTTON_ACTION( + toolbar_get_action_by_name("Open")), toolbar_recent_files_menu); +} + + void ui_init(void) { add_stock_items();
+ init_recent_files(); + ui_widgets.statusbar = ui_lookup_widget(main_widgets.window, "statusbar"); ui_widgets.print_page_setup = ui_lookup_widget(main_widgets.window, "page_setup1");
@@ -1820,16 +1855,13 @@ widgets.menu_insert_include_items[0] = ui_lookup_widget(main_widgets.editor_menu, "insert_include1"); widgets.menu_insert_include_items[1] = ui_lookup_widget(main_widgets.window, "insert_include2"); widgets.save_buttons[0] = ui_lookup_widget(main_widgets.window, "menu_save1"); - widgets.save_buttons[1] = toolbar_get_widget_by_name("Save"); widgets.save_buttons[2] = ui_lookup_widget(main_widgets.window, "menu_save_all1"); - widgets.save_buttons[3] = toolbar_get_widget_by_name("SaveAll"); widgets.redo_items[0] = ui_lookup_widget(main_widgets.editor_menu, "redo1"); widgets.redo_items[1] = ui_lookup_widget(main_widgets.window, "menu_redo2"); - widgets.redo_items[2] = toolbar_get_widget_by_name("Redo"); widgets.undo_items[0] = ui_lookup_widget(main_widgets.editor_menu, "undo1"); widgets.undo_items[1] = ui_lookup_widget(main_widgets.window, "menu_undo2"); - widgets.undo_items[2] = toolbar_get_widget_by_name("Undo");
+ ui_init_toolbar_widgets(); init_document_widgets(); create_config_files_menu(); toolbar_add_config_file_menu_item(); @@ -1853,7 +1885,6 @@ autosep->ref_count++; else autosep->ref_count--; - auto_separator_update(autosep); }
Modified: trunk/src/ui_utils.h =================================================================== --- trunk/src/ui_utils.h 2009-06-18 14:20:07 UTC (rev 3873) +++ trunk/src/ui_utils.h 2009-06-20 16:51:32 UTC (rev 3874) @@ -103,10 +103,8 @@ { /* menu widgets */ GtkWidget *toolbar_menu; - GtkWidget *new_file_menu; GtkWidget *recent_files_menuitem; GtkWidget *recent_files_menu_menubar; - GtkWidget *recent_files_menu_toolbar; GtkWidget *print_page_setup; GtkWidget *recent_projects_menuitem; GtkWidget *recent_projects_menu_menubar; @@ -205,6 +203,8 @@
void ui_init(void);
+void ui_init_toolbar_widgets(void); + void ui_add_config_file_menu_item(const gchar *real_path, const gchar *label, GtkContainer *parent);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.