> Index: gtk/gtk_toolbar.c > this file is the toolbar customization code, from customization branch; it handles opening a new window - the toolbar customization 'store' containing potential buttons to add to the toolbar [one for every menu item, the throbber, as well as the websearch bar item]; toolbar_customization_init changes the behaviour of the gtk window that called 'customize', setting its buttons as movable rather than working buttons, memorizing its button locations; desensitizing the normal mouse clicks; then toolbar_window_open creates the 'store' window, setting its buttons as movable, arranging the data handlers for moving buttons between windows; toolbar_delete / toolbar_cancel_clicked clear up the windows, resetting normal behaviour; toolbar_persist saves settings to file, transfers them to all gtk windows; toolbar_reset reloads default settings; toolbar_set_physical sets the visible toolbar for a window according to its memory-stored logical toolbar button locations; toolbar_close handles tidy-up code; toolbar_clear is a callback to iterate every item, clearing the whole toolbar; toolbar_add_item_to_toolbar adds items in order of location; toolbar_add_store_widget adds items neatly to the store window; the datahandlers handle hovering / dropping items, the only noteworthy feature is that gtk's data handling should have sent the id of the button being moved; it seems to have omitted to do so; as a result there is a global variable to contain that reference; toolbar_make_widget is a factory to create the widgets as originally designed in glade; there are a set of basic assistance functions; toolbar_customization_load loads custom toolbutton locations from the settings file; save does the opposite; > =================================================================== > --- /dev/null 2009-04-16 19:17:07.000000000 +0100 > +++ gtk/gtk_toolbar.c 2009-07-10 12:49:36.000000000 +0100 > @@ -0,0 +1,957 @@ > +/* > + * Copyright 2009 Mark Benjamin <[email protected]> > + * > + * This file is part of NetSurf, http://www.netsurf-browser.org/ > + * > + * NetSurf is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; version 2 of the License. > + * > + * NetSurf is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program. If not, see <http://www.gnu.org/licenses/>. > + */ > + > +#include <gtk/gtk.h> > +#include "gtk/gtk_toolbar.h" > +#include "gtk/gtk_gui.h" > +#include "gtk/gtk_scaffolding.h" > +#include "gtk/gtk_search.h" > +#include "gtk/gtk_theme.h" > +#include "gtk/gtk_throbber.h" > +#include "gtk/gtk_window.h" > +#include "utils/log.h" > +#include "utils/messages.h" > +#include "utils/utils.h" > + > +static GtkTargetEntry entry = {(char *)"nsgtk_button_data", > + GTK_TARGET_SAME_APP, 0}; > + > +static bool edit_mode = false; > + > +struct nsgtk_toolbar_custom_store { > + GtkWidget *window; > +/* currently includes all menu items that have stock images that could be > + * added to buttons; once theming is added, could allow all menu items; > + * until then, need to consider adding images to important menu items such > + * as savetext, savepdf, find, downloads, debugrendering, localhistory, > + * globalhistory, addbookmarks, editbookmarks */ > + GtkWidget *store_buttons[PLACEHOLDER_BUTTON]; > + GtkWidget *widgetvbox; > + GtkWidget *currentbar; > + char numberh; > + GladeXML *glade; > + int buttonlocations[PLACEHOLDER_BUTTON]; > + int currentbutton; > + bool fromstore; > +}; > + > +static struct nsgtk_toolbar_custom_store store; > +static struct nsgtk_toolbar_custom_store *window = &store; > + > +static void nsgtk_toolbar_close(struct gtk_scaffolding *g); > +static void nsgtk_toolbar_window_open(struct gtk_scaffolding *g); > +static void nsgtk_toolbar_customization_save(struct gtk_scaffolding *g); > +static void nsgtk_toolbar_add_item_to_toolbar(struct gtk_scaffolding *g, int > i, > + struct nsgtk_theme *theme); > +static bool nsgtk_toolbar_add_store_widget(GtkWidget *widget); > +static gboolean nsgtk_toolbar_data(GtkWidget *widget, GdkDragContext > *context, > + gint x, gint y, guint time, gpointer data); > +static gboolean nsgtk_toolbar_store_return(GtkWidget *widget, GdkDragContext > *gdc, gint x, gint y, guint time, gpointer data); > +static gboolean nsgtk_toolbar_action(GtkWidget *widget, GdkDragContext > + *drag_context, gint x, gint y, guint time, gpointer data); > +gboolean nsgtk_toolbar_store_action(GtkWidget *widget, GdkDragContext *gdc, > + gint x, gint y, guint time, gpointer data); > +static gboolean nsgtk_toolbar_move_complete(GtkWidget *widget, GdkDragContext > + *gdc, gint x, gint y, GtkSelectionData *selection, guint info, > + guint time, gpointer data); > +static void nsgtk_toolbar_clear(GtkWidget *widget, GdkDragContext *gdc, guint > + time, gpointer data); > +static gboolean nsgtk_toolbar_delete(GtkWidget *widget, GdkEvent *event, > + gpointer data); > +static gboolean nsgtk_toolbar_cancel_clicked(GtkWidget *widget, gpointer > data); > +static gboolean nsgtk_toolbar_reset(GtkWidget *widget, gpointer data); > +static gboolean nsgtk_toolbar_persist(GtkWidget *widget, gpointer data); > +static void nsgtk_toolbar_cast(struct gtk_scaffolding *g); > +static GtkWidget *nsgtk_toolbar_make_widget(struct gtk_scaffolding *g, int i, > + struct nsgtk_theme *theme); > +static void nsgtk_toolbar_set_handler(struct gtk_scaffolding *g, int i); > +static void nsgtk_toolbar_temp_connect(struct gtk_scaffolding *g, int i); > +static void nsgtk_toolbar_clear_toolbar(GtkWidget *widget, gpointer data); > +static int nsgtk_toolbar_get_id_at_location(struct gtk_scaffolding *g, int > i); > + > +/** > + * change behaviour of scaffoldings while editing toolbar > + */ > +void nsgtk_toolbar_customization_init(struct gtk_scaffolding *g) > +{ > + int i; > + nsgtk_scaffolding *list = scaf_list;; > + edit_mode = true; > + > + while (list) { > + g_signal_handler_block(GTK_WIDGET( > + nsgtk_window_get_drawing_area( > + nsgtk_scaffolding_top_level(list))), > + nsgtk_window_get_signalhandler( > + nsgtk_scaffolding_top_level(list), 0)); > + g_signal_handler_block(GTK_WIDGET( > + nsgtk_window_get_drawing_area( > + nsgtk_scaffolding_top_level(list))), > + nsgtk_window_get_signalhandler( > + nsgtk_scaffolding_top_level(list), 1)); > + gtk_widget_modify_bg(GTK_WIDGET(nsgtk_window_get_drawing_area( > + nsgtk_scaffolding_top_level(list))), > + GTK_STATE_NORMAL, &((GdkColor) > + {0, 0xEEEE, 0xEEEE, 0xEEEE})); > + > + if (list == g) { > + list = nsgtk_scaffolding_iterate(list); > + continue; > + } > + /* set sensitive for all gui_windows save g */ > + gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_scaffolding_window( > + list)), FALSE); > + list = nsgtk_scaffolding_iterate(list); > + } > + /* set sensitive for all of g save toolbar */ > + gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_scaffolding_menu_bar(g)), > + FALSE); > + gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_scaffolding_notebook(g)), > + FALSE); > + > + /* set editable aspect for toolbar */ > + gtk_container_foreach(GTK_CONTAINER(nsgtk_scaffolding_toolbar(g)), > + nsgtk_toolbar_clear_toolbar, g); > + nsgtk_toolbar_set_physical(g); > + /* memorize button locations, set editable */ > + for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { > + window->buttonlocations[i] = nsgtk_scaffolding_button(g, i) > + ->location; > + if ((window->buttonlocations[i] == -1) || (i == URL_BAR_ITEM)) > + continue; > + gtk_tool_item_set_use_drag_window(GTK_TOOL_ITEM( > + nsgtk_scaffolding_button(g, i)->button), TRUE); > + gtk_drag_source_set(GTK_WIDGET(nsgtk_scaffolding_button( > + g, i)->button), GDK_BUTTON1_MASK, &entry, 1, > + GDK_ACTION_COPY); > + nsgtk_toolbar_temp_connect(g, i); > + } > + > + /* add move button listeners */ > + g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_toolbar(g)), > + "drag-drop", G_CALLBACK(nsgtk_toolbar_data), g); > + g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_toolbar(g)), > + "drag-data-received", G_CALLBACK( > + nsgtk_toolbar_move_complete), g); > + g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_toolbar(g)), > + "drag-motion", G_CALLBACK(nsgtk_toolbar_action), g); > + g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_toolbar(g)), > + "drag-leave", G_CALLBACK( > + nsgtk_toolbar_clear), g); > + > + /* set data types */ > + gtk_drag_dest_set(GTK_WIDGET(nsgtk_scaffolding_toolbar(g)), > + GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, > + &entry, 1, GDK_ACTION_COPY); > + > + /* open toolbar window */ > + nsgtk_toolbar_window_open(g); > +} > + > +/** > + * create store window > + */ > +void nsgtk_toolbar_window_open(struct gtk_scaffolding *g) > +{ > + int x,y; > + struct nsgtk_theme *theme = > + nsgtk_theme_load(GTK_ICON_SIZE_LARGE_TOOLBAR); > + window->glade = glade_xml_new(glade_toolbar_file_location, > + "toolbarwindow", NULL); > + glade_xml_signal_autoconnect(window->glade); > + > +#define GET_TOOLWIDGET(p, q) window->p = glade_xml_get_widget(window->glade,\ > + #q) > + GET_TOOLWIDGET(window, toolbarwindow); > + GET_TOOLWIDGET(widgetvbox, widgetvbox); > +#undef GET_TOOLWIDGET > + > + window->numberh = 6; > + window->currentbutton = -1; > + /* load toolbuttons */ > + /* add toolbuttons to window */ > + /* set event handlers */ > + for (int i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { > + if (i == URL_BAR_ITEM) > + continue; > + window->store_buttons[i] = > + nsgtk_toolbar_make_widget(g, i, theme); > + nsgtk_toolbar_add_store_widget(window->store_buttons[i]); > + g_signal_connect(window->store_buttons[i], "drag-data-get", > + G_CALLBACK( > + nsgtk_scaffolding_button(g, i)->dataplus), g); > + } > + free(theme); > + gtk_window_set_transient_for(GTK_WINDOW(window->window), > + nsgtk_scaffolding_window(g)); > + gtk_window_set_title(GTK_WINDOW(window->window), messages_get( > + "gtkToolBarTitle")); > + gtk_window_set_accept_focus(GTK_WINDOW(window->window), FALSE); > + gtk_drag_dest_set(GTK_WIDGET(window->window), GTK_DEST_DEFAULT_MOTION | > + GTK_DEST_DEFAULT_DROP, &entry, 1, GDK_ACTION_COPY); > + gtk_widget_show_all(window->window); > + gtk_window_set_position(GTK_WINDOW(window->window), > + GTK_WIN_POS_CENTER_ON_PARENT); > + gtk_window_get_position(nsgtk_scaffolding_window(g), &x, &y); > + gtk_window_move(GTK_WINDOW(window->window), x, y + 100); > + g_signal_connect(glade_xml_get_widget(window->glade, "cancelbutton"), > + "clicked", G_CALLBACK( > + nsgtk_toolbar_cancel_clicked), g); > + g_signal_connect(glade_xml_get_widget(window->glade, "okbutton"), > + "clicked", G_CALLBACK(nsgtk_toolbar_persist), g); > + g_signal_connect(glade_xml_get_widget(window->glade, "resetbutton"), > + "clicked", G_CALLBACK(nsgtk_toolbar_reset), g); > + g_signal_connect(window->window, "delete-event", > + G_CALLBACK(nsgtk_toolbar_delete), g); > + g_signal_connect(window->window, "drag-drop", > + G_CALLBACK(nsgtk_toolbar_store_return), g); > + g_signal_connect(window->window, "drag-motion", > + G_CALLBACK(nsgtk_toolbar_store_action), g); > +} > + > +/** > + * when titlebar / alt-F4 window close event happens > + */ > +gboolean nsgtk_toolbar_delete(GtkWidget *widget, GdkEvent *event, gpointer > data) > +{ > + edit_mode = false; > + struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; > + /* reset g->buttons->location */ > + for (int i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { > + nsgtk_scaffolding_button(g, i)->location = > + window->buttonlocations[i]; > + } > + nsgtk_toolbar_set_physical(g); > + nsgtk_toolbar_connect_all(g); > + nsgtk_toolbar_close(g); > + nsgtk_scaffolding_set_sensitivity(g); > + gtk_widget_destroy(window->window); > + return TRUE; > +} > + > +/** > + * when cancel button is clicked > + */ > +gboolean nsgtk_toolbar_cancel_clicked(GtkWidget *widget, gpointer data) > +{ > + edit_mode = false; > + struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; > + /* reset g->buttons->location */ > + for (int i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { > + nsgtk_scaffolding_button(g, i)->location = > + window->buttonlocations[i]; > + } > + nsgtk_toolbar_set_physical(g); > + nsgtk_toolbar_connect_all(g); > + nsgtk_toolbar_close(g); > + nsgtk_scaffolding_set_sensitivity(g); > + gtk_widget_destroy(window->window); > + return TRUE; > +} > + > +/** > + * when 'save settings' button is clicked > + */ > +gboolean nsgtk_toolbar_persist(GtkWidget *widget, gpointer data) > +{ > + edit_mode = false; > + struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; > + /* save state to file, update toolbars for all windows */ > + nsgtk_toolbar_customization_save(g); > + nsgtk_toolbar_cast(g); > + nsgtk_toolbar_set_physical(g); > + nsgtk_toolbar_close(g); > + gtk_widget_destroy(window->window); > + return TRUE; > +} > + > +/** > + * when 'reload defaults' button is clicked > + */ > +gboolean nsgtk_toolbar_reset(GtkWidget *widget, gpointer data) > +{ > + struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; > + int i; > + for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) > + nsgtk_scaffolding_button(g, i)->location = > + (i <= WEBSEARCH_ITEM) ? i : -1; > + nsgtk_toolbar_set_physical(g); > + for (i = BACK_BUTTON; i <= WEBSEARCH_ITEM; i++) { > + if (i == URL_BAR_ITEM) > + continue; > + gtk_tool_item_set_use_drag_window(GTK_TOOL_ITEM( > + nsgtk_scaffolding_button(g, i)->button), TRUE); > + gtk_drag_source_set(GTK_WIDGET( > + nsgtk_scaffolding_button(g, i)->button), > + GDK_BUTTON1_MASK, &entry, 1, GDK_ACTION_COPY); > + nsgtk_toolbar_temp_connect(g, i); > + } > + return TRUE; > +} > + > +/** > + * set toolbar logical -> physical > + */ > +void nsgtk_toolbar_set_physical(struct gtk_scaffolding *g) > +{ > + int i; > + struct nsgtk_theme *theme = > + nsgtk_theme_load(GTK_ICON_SIZE_LARGE_TOOLBAR); > + /* simplest is to clear the toolbar then reload it from memory */ > + gtk_container_foreach(GTK_CONTAINER(nsgtk_scaffolding_toolbar(g)), > + nsgtk_toolbar_clear_toolbar, g); > + for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) > + nsgtk_toolbar_add_item_to_toolbar(g, i, theme); > + gtk_widget_show_all(GTK_WIDGET(nsgtk_scaffolding_toolbar(g))); > + free(theme); > +} > + > +/** > + * physical update of all toolbars; resensitize > + * \param g the 'front' scaffolding that called customize > + */ > +void nsgtk_toolbar_close(struct gtk_scaffolding *g) > +{ > + int i; > + nsgtk_scaffolding *list = scaf_list; > + while (list) { > + struct nsgtk_theme *theme = > + nsgtk_theme_load(GTK_ICON_SIZE_LARGE_TOOLBAR); > + /* clear toolbar */ > + gtk_container_foreach(GTK_CONTAINER(nsgtk_scaffolding_toolbar( > + list)), nsgtk_toolbar_clear_toolbar, list); > + /* then add items */ > + for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { > + nsgtk_toolbar_add_item_to_toolbar(list, i, theme); > + } > + nsgtk_toolbar_connect_all(list); > + gtk_widget_show_all(GTK_WIDGET(nsgtk_scaffolding_toolbar( > + list))); > + nsgtk_scaffolding_set_sensitivity(list); > + gtk_widget_modify_bg(GTK_WIDGET(nsgtk_window_get_drawing_area( > + nsgtk_scaffolding_top_level(list))), > + GTK_STATE_NORMAL, &((GdkColor) > + {0, 0xFFFF, 0xFFFF, 0xFFFF})); > + g_signal_handler_unblock(GTK_WIDGET( > + nsgtk_window_get_drawing_area( > + nsgtk_scaffolding_top_level(list))), > + nsgtk_window_get_signalhandler( > + nsgtk_scaffolding_top_level(list), 0)); > + g_signal_handler_unblock(GTK_WIDGET( > + nsgtk_window_get_drawing_area( > + nsgtk_scaffolding_top_level(list))), > + nsgtk_window_get_signalhandler( > + nsgtk_scaffolding_top_level(list), 1)); > + if ((gui_window_get_browser_window(nsgtk_scaffolding_top_level( > + list))->current_content != NULL) && > + (gui_window_get_browser_window( > + nsgtk_scaffolding_top_level(list))-> > + current_content->url != NULL)) > + browser_window_refresh_url_bar( > + gui_window_get_browser_window( > + nsgtk_scaffolding_top_level(list)), > + gui_window_get_browser_window( > + nsgtk_scaffolding_top_level(list))-> > + current_content->url, > + gui_window_get_browser_window( > + nsgtk_scaffolding_top_level(list))-> > + frag_id); > + > + if (list != g) > + gtk_widget_set_sensitive(GTK_WIDGET( > + nsgtk_scaffolding_window(list)), TRUE); > + free(theme); > + list = nsgtk_scaffolding_iterate(list); > + } > + gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_scaffolding_notebook(g)), > + TRUE); > + gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_scaffolding_menu_bar(g)), > + TRUE); > + gui_window_set_search_ico(); > +} > + > +/** > + * callback function to iterate toolbar's widgets > + */ > +void nsgtk_toolbar_clear_toolbar(GtkWidget *widget, gpointer data) > +{ > + struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; > + gtk_container_remove(GTK_CONTAINER(nsgtk_scaffolding_toolbar(g)), > widget); > +} > + > +/** > + * add item to toolbar > + * \param g the scaffolding whose toolbar an item is added to > + * \param i the location in the toolbar > + * the function should be called, when multiple items are being added, > + * in ascending order > + */ > +void nsgtk_toolbar_add_item_to_toolbar(struct gtk_scaffolding *g, int i, > + struct nsgtk_theme *theme) > +{ > + int q; > + for (q = BACK_BUTTON; q < PLACEHOLDER_BUTTON; q++) > + if (nsgtk_scaffolding_button(g, q)->location == i) { > + nsgtk_scaffolding_button(g, q)->button = GTK_TOOL_ITEM( > + nsgtk_toolbar_make_widget(g, q, > + theme)); > + gtk_toolbar_insert(nsgtk_scaffolding_toolbar(g), > + nsgtk_scaffolding_button(g, q)->button, > + i); > + break; > + } > +} > + > +/** > + * physically add widgets to store window > + */ > +bool nsgtk_toolbar_add_store_widget(GtkWidget *widget) > +{ > + if (window->numberh >= 6) { > + window->currentbar = gtk_toolbar_new(); > + gtk_toolbar_set_style(GTK_TOOLBAR(window->currentbar), > + GTK_TOOLBAR_BOTH); > + gtk_toolbar_set_icon_size(GTK_TOOLBAR(window->currentbar), > + GTK_ICON_SIZE_LARGE_TOOLBAR); > + gtk_box_pack_start(GTK_BOX(window->widgetvbox), > + window->currentbar, FALSE, FALSE, 0); > + window->numberh = 0; > + } > + gtk_widget_set_size_request(widget, 111, 70); > + gtk_toolbar_insert(GTK_TOOLBAR(window->currentbar), GTK_TOOL_ITEM( > + widget), window->numberh++); > + gtk_tool_item_set_use_drag_window(GTK_TOOL_ITEM(widget), TRUE); > + gtk_drag_source_set(widget, GDK_BUTTON1_MASK, &entry, 1, > + GDK_ACTION_COPY); > + gtk_widget_show_all(window->window); > + return true; > +} > + > +/** > + * called when a widget is dropped onto the toolbar > + */ > +gboolean nsgtk_toolbar_data(GtkWidget *widget, GdkDragContext *gdc, gint x, > + gint y, guint time, gpointer data) > +{ > + struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; > + int ind = gtk_toolbar_get_drop_index(nsgtk_scaffolding_toolbar(g), > + x, y); > + int q, i; > + if (window->currentbutton == -1) > + return TRUE; > + struct nsgtk_theme *theme = > + nsgtk_theme_load(GTK_ICON_SIZE_LARGE_TOOLBAR); > + if (nsgtk_scaffolding_button(g, window->currentbutton)->location > + != -1) { > + if (nsgtk_scaffolding_button(g, window->currentbutton)-> > + location < ind) > + ind--; > + gtk_container_remove(GTK_CONTAINER( > + nsgtk_scaffolding_toolbar(g)), GTK_WIDGET( > + nsgtk_scaffolding_button(g, > + window->currentbutton)->button)); > + for (i = nsgtk_scaffolding_button(g, window->currentbutton)-> > + location + 1; i < PLACEHOLDER_BUTTON; i++) { > + q = nsgtk_toolbar_get_id_at_location(g, i); > + if (q == -1) > + continue; > + nsgtk_scaffolding_button(g, q)->location--; > + } > + nsgtk_scaffolding_button(g, window->currentbutton)-> > + location = -1; > + } > + nsgtk_scaffolding_button(g, window->currentbutton)->button = > + GTK_TOOL_ITEM(nsgtk_toolbar_make_widget(g, > + window->currentbutton, theme)); > + free(theme); > + /* update logical schema */ > + nsgtk_scaffolding_reset_offset(g); > + for (i = PLACEHOLDER_BUTTON - 1; i >= ind; i--) { > + q = nsgtk_toolbar_get_id_at_location(g, i); > + if (q == -1) > + continue; > + nsgtk_scaffolding_button(g, q)->location++; > + } > + nsgtk_scaffolding_button(g, window->currentbutton)->location = ind; > + > + /* complete action */ > + gtk_toolbar_insert(nsgtk_scaffolding_toolbar(g), > + nsgtk_scaffolding_button(g, > + window->currentbutton)->button, ind); > + gtk_tool_item_set_use_drag_window(GTK_TOOL_ITEM( > + nsgtk_scaffolding_button(g, > + window->currentbutton)->button), TRUE); > + gtk_drag_source_set(GTK_WIDGET( > + nsgtk_scaffolding_button(g, > + window->currentbutton)->button), > + GDK_BUTTON1_MASK, &entry, 1, GDK_ACTION_COPY); > + nsgtk_toolbar_temp_connect(g, window->currentbutton); > + gtk_widget_show_all(GTK_WIDGET( > + nsgtk_scaffolding_button(g, > + window->currentbutton)->button)); > + window->currentbutton = -1; > + return TRUE; > +} > + > +gboolean nsgtk_toolbar_move_complete(GtkWidget *widget, GdkDragContext > *gdc, > + gint x, gint y, GtkSelectionData *selection, guint info, guint > + time, gpointer data) > +{ > + return FALSE; > +} > +/** > + * called when a widget is dropped onto the store window > + */ > +gboolean nsgtk_toolbar_store_return(GtkWidget *widget, GdkDragContext *gdc, > + gint x, gint y, guint time, gpointer data) > +{ > + struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; > + int q, i; > + > + if ((window->fromstore) || (window->currentbutton == -1)) { > + window->currentbutton = -1; > + return FALSE; > + } > + if (nsgtk_scaffolding_button(g, window->currentbutton)->location > + != -1) { > + for (i = nsgtk_scaffolding_button(g, window->currentbutton)-> > + location + 1; i < PLACEHOLDER_BUTTON; i++) { > + q = nsgtk_toolbar_get_id_at_location(g, i); > + if (q == -1) > + continue; > + nsgtk_scaffolding_button(g, q)->location--; > + } > + gtk_container_remove(GTK_CONTAINER( > + nsgtk_scaffolding_toolbar(g)), GTK_WIDGET( > + nsgtk_scaffolding_button(g, > + window->currentbutton)->button)); > + nsgtk_scaffolding_button(g, window->currentbutton)->location > + = -1; > + } > + window->currentbutton = -1; > + gtk_drag_finish(gdc, TRUE, TRUE, time); > + return FALSE; > +} > +/** > + * called when hovering an item above the toolbar > + */ > +gboolean nsgtk_toolbar_action(GtkWidget *widget, GdkDragContext *gdc, > gint x, > + gint y, guint time, gpointer data) > +{ > + struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; > + GtkToolItem *item = gtk_tool_button_new(NULL, NULL); > + gtk_toolbar_set_drop_highlight_item(nsgtk_scaffolding_toolbar(g), > + GTK_TOOL_ITEM(item), gtk_toolbar_get_drop_index( > + nsgtk_scaffolding_toolbar(g), x, y)); > + return FALSE; > +} > + > +/** > + * called when hovering above the store > + */ > +gboolean nsgtk_toolbar_store_action(GtkWidget *widget, GdkDragContext *gdc, > + gint x, gint y, guint time, gpointer data) > +{ > + return FALSE; > +} > +/** > + * called when hovering stops > + */ > +void nsgtk_toolbar_clear(GtkWidget *widget, GdkDragContext *gdc, guint time, > + gpointer data) > +{ > + gtk_toolbar_set_drop_highlight_item(GTK_TOOLBAR(widget), NULL, 0); > +} > + > +/** > + * widget factory for creation of toolbar item widgets > + * \param g the reference scaffolding > + * \param i the id of the widget > + * \param theme the theme to make the widgets from > + */ > +GtkWidget *nsgtk_toolbar_make_widget(struct gtk_scaffolding *g, int i, > + struct nsgtk_theme *theme) > +{ > + GtkWidget *w = NULL, *image = NULL, *hbox = NULL, *entry = NULL; > + char *label; > + GtkStockItem item; > + switch(i){ > +#define MAKE_STOCKBUTTON(p, q) case p##_BUTTON:\ > + gtk_stock_lookup(#q, &item);\ > + label = remove_underscores(item.label, false);\ > + w = GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET(\ > + theme->image[p##_BUTTON]),label));\ > + free(label);\ > + break > + MAKE_STOCKBUTTON(HOME, gtk-home); > + MAKE_STOCKBUTTON(BACK, gtk-go-back); > + MAKE_STOCKBUTTON(FORWARD, gtk-go-forward); > + MAKE_STOCKBUTTON(STOP, gtk-stop); > + MAKE_STOCKBUTTON(RELOAD, gtk-refresh); > +#undef MAKE_STOCKBUTTON > + case HISTORY_BUTTON: > + w = GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET( > + theme->image[HISTORY_BUTTON]), NULL)); > + break; > + case URL_BAR_ITEM: > + label = g_strconcat(res_dir_location, "netsurf-16x16.xpm", > NULL); > + hbox = gtk_hbox_new(FALSE, 0); > + image = GTK_WIDGET(gtk_image_new_from_file(label)); > + g_free(label); > + entry = GTK_WIDGET(gtk_entry_new()); > + gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); > + gtk_box_pack_end(GTK_BOX(hbox), entry, TRUE, TRUE, 0); > + w = GTK_WIDGET(gtk_tool_item_new()); > + gtk_container_add(GTK_CONTAINER(w), hbox); > + gtk_tool_item_set_expand(GTK_TOOL_ITEM(w), TRUE); > + break; > + case THROBBER_ITEM: > + if (edit_mode) > + return GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET( > + gtk_image_new_from_pixbuf( > + nsgtk_throbber->framedata[0])), > + "[throbber]")); > + image = GTK_WIDGET(gtk_image_new_from_pixbuf( > + nsgtk_throbber->framedata[0])); > + w = GTK_WIDGET(gtk_tool_item_new()); > + gtk_container_add(GTK_CONTAINER(w), image); > + break; > + case WEBSEARCH_ITEM: > + if (edit_mode) > + return GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET( > + gtk_image_new_from_stock("gtk-find", > + GTK_ICON_SIZE_LARGE_TOOLBAR)), > + "[websearch]")); > + hbox = gtk_hbox_new(FALSE, 0); > + image = GTK_WIDGET(gtk_image_new_from_stock("gtk-info", > + GTK_ICON_SIZE_LARGE_TOOLBAR)); > + entry = GTK_WIDGET(gtk_entry_new()); > + gtk_widget_set_size_request(entry, 77, -1); > + gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); > + gtk_box_pack_end(GTK_BOX(hbox), entry, TRUE, TRUE, 0); > + w = GTK_WIDGET(gtk_tool_item_new()); > + gtk_container_add(GTK_CONTAINER(w), hbox); > + break; > +#define MAKE_MENUBUTTON(p, q) case p##_BUTTON:\ > + label = remove_underscores(messages_get(#q), false);\ > + w = GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET(\ > + theme->image[p##_BUTTON]), label));\ > + free(label);\ > + break > + MAKE_MENUBUTTON(NEWWINDOW, gtkNewWindow); > + MAKE_MENUBUTTON(NEWTAB, gtkNewTab); > + MAKE_MENUBUTTON(OPENFILE, gtkOpenFile); > + MAKE_MENUBUTTON(CLOSETAB, gtkCloseTab); > + MAKE_MENUBUTTON(CLOSEWINDOW, gtkCloseWindow); > + MAKE_MENUBUTTON(SAVEPAGE, gtkSavePage); > + MAKE_MENUBUTTON(PRINTPREVIEW, gtkPrintPreview); > + MAKE_MENUBUTTON(PRINT, gtkPrint); > + MAKE_MENUBUTTON(QUIT, gtkQuit); > + MAKE_MENUBUTTON(CUT, gtkCut); > + MAKE_MENUBUTTON(COPY, gtkCopy); > + MAKE_MENUBUTTON(PASTE, gtkPaste); > + MAKE_MENUBUTTON(DELETE, gtkDelete); > + MAKE_MENUBUTTON(SELECTALL, gtkSelectAll); > + MAKE_MENUBUTTON(PREFERENCES, gtkPreferences); > + MAKE_MENUBUTTON(ZOOMPLUS, gtkZoomPlus); > + MAKE_MENUBUTTON(ZOOMMINUS, gtkZoomMinus); > + MAKE_MENUBUTTON(ZOOMNORMAL, gtkZoomNormal); > + MAKE_MENUBUTTON(FULLSCREEN, gtkFullScreen); > + MAKE_MENUBUTTON(VIEWSOURCE, gtkViewSource); > + MAKE_MENUBUTTON(CONTENTS, gtkContents); > + MAKE_MENUBUTTON(ABOUT, gtkAbout); > + MAKE_MENUBUTTON(PDF, gtkPDF); > + MAKE_MENUBUTTON(PLAINTEXT, gtkPlainText); > + MAKE_MENUBUTTON(DRAWFILE, gtkDrawFile); > + MAKE_MENUBUTTON(POSTSCRIPT, gtkPostScript); > + MAKE_MENUBUTTON(FIND, gtkFind); > + MAKE_MENUBUTTON(DOWNLOADS, gtkDownloads); > + MAKE_MENUBUTTON(SAVEWINDOWSIZE, gtkSaveWindowSize); > + MAKE_MENUBUTTON(TOGGLEDEBUGGING, gtkToggleDebugging); > + MAKE_MENUBUTTON(SAVEBOXTREE, gtkSaveBoxTree); > + MAKE_MENUBUTTON(SAVEDOMTREE, gtkSaveDomTree); > + MAKE_MENUBUTTON(LOCALHISTORY, gtkLocalHistory); > + MAKE_MENUBUTTON(GLOBALHISTORY, gtkGlobalHistory); > + MAKE_MENUBUTTON(ADDBOOKMARKS, gtkAddBookMarks); > + MAKE_MENUBUTTON(SHOWBOOKMARKS, gtkShowBookMarks); > + MAKE_MENUBUTTON(OPENLOCATION, gtkOpenLocation); > + MAKE_MENUBUTTON(NEXTTAB, gtkNextTab); > + MAKE_MENUBUTTON(PREVTAB, gtkPrevTab); > + MAKE_MENUBUTTON(GUIDE, gtkGuide); > + MAKE_MENUBUTTON(INFO, gtkUserInformation); > + default: > + break; > +#undef MAKE_MENUBUTTON > + } > + return w; > +} > + > +/** > + * \return toolbar item id when a widget is an element of the scaffolding > + * else -1 > + */ > +int nsgtk_toolbar_get_id_from_widget(GtkWidget *widget, struct > gtk_scaffolding > + *g) > +{ > + int i; > + for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { > + if ((nsgtk_scaffolding_button(g, i)->location != -1) > + && (widget == GTK_WIDGET( > + nsgtk_scaffolding_button(g, i)->button))) { > + return i; > + } > + } > + return -1; > +} > + > +/** > + * \return toolbar item id from location when there is an item at that > logical > + * location; else -1 > + */ > +int nsgtk_toolbar_get_id_at_location(struct gtk_scaffolding *g, int i) > +{ > + int q; > + for (q = BACK_BUTTON; q < PLACEHOLDER_BUTTON; q++) > + if (nsgtk_scaffolding_button(g, q)->location == i) > + return q; > + return -1; > +} > + > +void nsgtk_toolbar_connect_all(struct gtk_scaffolding *g) > +{ > + int q, i; > + for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { > + q = nsgtk_toolbar_get_id_at_location(g, i); > + if (q == -1) > + continue; > + g_signal_connect(nsgtk_scaffolding_button(g, q)->button, > + "size-allocate", G_CALLBACK( > + nsgtk_scaffolding_toolbar_size_allocate), g); > + nsgtk_toolbar_set_handler(g, q); > + } > +} > + > +/** > + * add handlers to factory widgets > + * \param g the scaffolding to attach handlers to > + * \param i the toolbar item id > + */ > +void nsgtk_toolbar_set_handler(struct gtk_scaffolding *g, int i) > +{ > + switch(i){ > + case URL_BAR_ITEM: > + nsgtk_scaffolding_update_url_bar_ref(g); > + g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_urlbar(g)), > + "activate", G_CALLBACK( > + nsgtk_window_url_activate_event), g); > + g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_urlbar(g)), > + "changed", G_CALLBACK( > + nsgtk_window_url_changed), g); > + break; > + case THROBBER_ITEM: > + nsgtk_scaffolding_update_throbber_ref(g); > + break; > + case WEBSEARCH_ITEM: > + nsgtk_scaffolding_update_websearch_ref(g); > + g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_websearch(g)), > + "activate", G_CALLBACK( > + nsgtk_websearch_activate), g); > + g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_websearch(g)), > + "focus-in-event", G_CALLBACK( > + nsgtk_websearch_clear), g); > + break; > + default: > + if (nsgtk_scaffolding_button(g, i)->bhandler != NULL) > + g_signal_connect(nsgtk_scaffolding_button(g, i)-> > + button, "clicked", > + G_CALLBACK(nsgtk_scaffolding_button(g, > + i)->bhandler), g); > + break; > + } > +} > + > +#define DATAHANDLER(p, q)\ > +gboolean nsgtk_toolbar_##p##_button_data(GtkWidget *widget, GdkDragContext\ > + *cont, GtkSelectionData *selection, guint info, guint time,\ > + gpointer data)\ > +{\ > + window->currentbutton = q##_BUTTON;\ > + window->fromstore = true;\ > + return TRUE;\ > +}\ > +gboolean nsgtk_toolbar_##p##_toolbar_button_data(GtkWidget *widget,\ > + GdkDragContext *cont, GtkSelectionData *selection, guint info,\ > + guint time, gpointer data)\ > +{\ > + window->currentbutton = q##_BUTTON;\ > + window->fromstore = false;\ > + return TRUE;\ > +} > + > +DATAHANDLER(home, HOME) > +DATAHANDLER(forward, FORWARD) > +DATAHANDLER(back, BACK) > +DATAHANDLER(stop, STOP) > +DATAHANDLER(reload, RELOAD) > +DATAHANDLER(history, HISTORY) > +DATAHANDLER(newwindow, NEWWINDOW); > +DATAHANDLER(newtab, NEWTAB); > +DATAHANDLER(openfile, OPENFILE); > +DATAHANDLER(closetab, CLOSETAB); > +DATAHANDLER(closewindow, CLOSEWINDOW); > +DATAHANDLER(savepage, SAVEPAGE); > +DATAHANDLER(printpreview, PRINTPREVIEW); > +DATAHANDLER(print, PRINT); > +DATAHANDLER(quit, QUIT); > +DATAHANDLER(cut, CUT); > +DATAHANDLER(copy, COPY); > +DATAHANDLER(paste, PASTE); > +DATAHANDLER(delete, DELETE); > +DATAHANDLER(selectall, SELECTALL); > +DATAHANDLER(preferences, PREFERENCES); > +DATAHANDLER(zoomplus, ZOOMPLUS); > +DATAHANDLER(zoomminus, ZOOMMINUS); > +DATAHANDLER(zoomnormal, ZOOMNORMAL); > +DATAHANDLER(fullscreen, FULLSCREEN); > +DATAHANDLER(viewsource, VIEWSOURCE); > +DATAHANDLER(contents, CONTENTS); > +DATAHANDLER(about, ABOUT); > +DATAHANDLER(pdf, PDF); > +DATAHANDLER(plaintext, PLAINTEXT); > +DATAHANDLER(drawfile, DRAWFILE); > +DATAHANDLER(postscript, POSTSCRIPT); > +DATAHANDLER(find, FIND); > +DATAHANDLER(downloads, DOWNLOADS); > +DATAHANDLER(savewindowsize, SAVEWINDOWSIZE); > +DATAHANDLER(toggledebugging, TOGGLEDEBUGGING); > +DATAHANDLER(saveboxtree, SAVEBOXTREE); > +DATAHANDLER(savedomtree, SAVEDOMTREE); > +DATAHANDLER(localhistory, LOCALHISTORY); > +DATAHANDLER(globalhistory, GLOBALHISTORY); > +DATAHANDLER(addbookmarks, ADDBOOKMARKS); > +DATAHANDLER(showbookmarks, SHOWBOOKMARKS); > +DATAHANDLER(openlocation, OPENLOCATION); > +DATAHANDLER(nexttab, NEXTTAB); > +DATAHANDLER(prevtab, PREVTAB); > +DATAHANDLER(guide, GUIDE); > +DATAHANDLER(info, INFO); > +#undef DATAHANDLER > +#define DATAHANDLER(p, q)\ > +gboolean nsgtk_toolbar_##p##_button_data(GtkWidget *widget, GdkDragContext\ > + *cont, GtkSelectionData *selection, guint info, guint time,\ > + gpointer data)\ > +{\ > + window->currentbutton = q##_ITEM;\ > + window->fromstore = true;\ > + return TRUE;\ > +}\ > +gboolean nsgtk_toolbar_##p##_toolbar_button_data(GtkWidget *widget,\ > + GdkDragContext *cont, GtkSelectionData *selection, guint info,\ > + guint time, gpointer data)\ > +{\ > + window->currentbutton = q##_ITEM;\ > + window->fromstore = false;\ > + return TRUE;\ > +} > +DATAHANDLER(throbber, THROBBER); > +DATAHANDLER(websearch, WEBSEARCH); > +#undef DATAHANDLER > + > +/** > + * connect temporary handler for toolbar edit events > + */ > +void nsgtk_toolbar_temp_connect(struct gtk_scaffolding *g, int i) > +{ > + if (i == URL_BAR_ITEM) > + return; > + g_signal_connect(nsgtk_scaffolding_button(g, i)->button, > + "drag-data-get", G_CALLBACK(nsgtk_scaffolding_button( > + g, i)->dataminus), g); > +} > + > +/** > + * load toolbar settings from file > + */ > +void nsgtk_toolbar_customization_load(struct gtk_scaffolding *g) > +{ > + int i, ii; > + char *val; > + char buffer[SLEN("11;|") * 2 * PLACEHOLDER_BUTTON]; /* numbers 0-99 */ > + buffer[0] = '\0'; > + char *buffer1, *subbuffer, *ptr, *pter; > + FILE *f = fopen(toolbar_indices_file_location, "r"); > + val = fgets(buffer, sizeof buffer, f); > + if (val == NULL) > + LOG(("empty read toolbar settings")); > + fclose(f); > + for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) > + nsgtk_scaffolding_button(g, i)->location = > + (i <= WEBSEARCH_ITEM) ? i : -1; > + i = BACK_BUTTON; > + ii = BACK_BUTTON; > + buffer1 = strtok_r(buffer, "|", &ptr); > + while (buffer1 != NULL) { > + subbuffer = strtok_r(buffer1, ";", &pter); > + i = atoi(subbuffer); > + subbuffer = strtok_r(NULL, ";", &pter); > + ii = atoi(subbuffer); > + if ((i >= BACK_BUTTON) && (i < PLACEHOLDER_BUTTON) && > + (ii >= -1) && (ii < PLACEHOLDER_BUTTON)) { > + nsgtk_scaffolding_button(g, i)->location = ii; > + } > + buffer1 = strtok_r(NULL, "|", &ptr); > + } > +} > + > +/** > + * cast toolbar settings to all scaffoldings referenced from the global > linked > + * list of gui_windows > + */ > +void nsgtk_toolbar_cast(struct gtk_scaffolding *g) > +{ > + int i; > + nsgtk_scaffolding *list = scaf_list; > + for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) > + window->buttonlocations[i] = nsgtk_scaffolding_button(g, i)-> > + location; > + while (list) { > + if (list != g) > + for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) > + nsgtk_scaffolding_button(list, i)->location = > + window->buttonlocations[i]; > + list = nsgtk_scaffolding_iterate(list); > + } > +} > + > +/** > + * save toolbar settings to file > + */ > +void nsgtk_toolbar_customization_save(struct gtk_scaffolding *g) > +{ > + int i; > + FILE *f = fopen(toolbar_indices_file_location, "w"); > + if (f == NULL){ > + warn_user("gtkFileError", toolbar_indices_file_location); > + return; > + } > + for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { > + fprintf(f, "%d;%d|", i, nsgtk_scaffolding_button(g, > i)->location); > + } > + fclose(f); > +} > +
> Index: gtk/gtk_toolbar.h > =================================================================== > --- /dev/null 2009-04-16 19:17:07.000000000 +0100 > +++ gtk/gtk_toolbar.h 2009-07-10 12:49:37.000000000 +0100 > @@ -0,0 +1,90 @@ > +/* > + * Copyright 2009 Mark Benjamin <[email protected]> > + * > + * This file is part of NetSurf, http://www.netsurf-browser.org/ > + * > + * NetSurf is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; version 2 of the License. > + * > + * NetSurf is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program. If not, see <http://www.gnu.org/licenses/>. > + */ > + > +#ifndef _NETSURF_GTK_TOOLBAR_H_ > +#define _NETSURF_GTK_TOOLBAR_H_ > + > +#include <gtk/gtk.h> > +#include "gtk/gtk_scaffolding.h" > + > +void nsgtk_toolbar_customization_init(nsgtk_scaffolding *g); > +void nsgtk_toolbar_init(nsgtk_scaffolding *g); > +void nsgtk_toolbar_customization_load(nsgtk_scaffolding *g); > +void nsgtk_toolbar_set_physical(nsgtk_scaffolding *g); > +void nsgtk_toolbar_connect_all(nsgtk_scaffolding *g); > +int nsgtk_toolbar_get_id_from_widget(GtkWidget *widget, nsgtk_scaffolding > + *g); > + > +#define TOOLPROTO(q) gboolean nsgtk_toolbar_##q##_button_data(\ > + GtkWidget *widget, GdkDragContext *cont, GtkSelectionData\ > + *selection, guint info, guint time, gpointer data);\ > +gboolean nsgtk_toolbar_##q##_toolbar_button_data(GtkWidget *widget,\ > + GdkDragContext *cont, GtkSelectionData *selection, guint info,\ > + guint time, gpointer data) > +TOOLPROTO(home); > +TOOLPROTO(back); > +TOOLPROTO(forward); > +TOOLPROTO(reload); > +TOOLPROTO(stop); > +TOOLPROTO(throbber); > +TOOLPROTO(websearch); > +TOOLPROTO(history); > +TOOLPROTO(newwindow); > +TOOLPROTO(newtab); > +TOOLPROTO(openfile); > +TOOLPROTO(closetab); > +TOOLPROTO(closewindow); > +TOOLPROTO(savepage); > +TOOLPROTO(pdf); > +TOOLPROTO(plaintext); > +TOOLPROTO(drawfile); > +TOOLPROTO(postscript); > +TOOLPROTO(printpreview); > +TOOLPROTO(print); > +TOOLPROTO(quit); > +TOOLPROTO(cut); > +TOOLPROTO(copy); > +TOOLPROTO(paste); > +TOOLPROTO(delete); > +TOOLPROTO(selectall); > +TOOLPROTO(find); > +TOOLPROTO(preferences); > +TOOLPROTO(zoomplus); > +TOOLPROTO(zoomminus); > +TOOLPROTO(zoomnormal); > +TOOLPROTO(fullscreen); > +TOOLPROTO(viewsource); > +TOOLPROTO(downloads); > +TOOLPROTO(localhistory); > +TOOLPROTO(globalhistory); > +TOOLPROTO(addbookmarks); > +TOOLPROTO(showbookmarks); > +TOOLPROTO(openlocation); > +TOOLPROTO(nexttab); > +TOOLPROTO(prevtab); > +TOOLPROTO(savewindowsize); > +TOOLPROTO(toggledebugging); > +TOOLPROTO(saveboxtree); > +TOOLPROTO(savedomtree); > +TOOLPROTO(contents); > +TOOLPROTO(guide); > +TOOLPROTO(info); > +TOOLPROTO(about); > +#undef TOOLPROTO > + > +#endif > Index: gtk/res/toolbarIndices > =================================================================== > Index: gtk/res/toolbar.glade > =================================================================== > --- /dev/null 2009-04-16 19:17:07.000000000 +0100 > +++ gtk/res/toolbar.glade 2009-07-10 12:49:52.000000000 +0100 > @@ -0,0 +1,126 @@ > +<?xml version="1.0" encoding="UTF-8" standalone="no"?> > +<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> > +<!--Generated with glade3 3.4.5 on Tue Jun 9 08:21:40 2009 --> > +<glade-interface> > + <widget class="GtkWindow" id="toolbarwindow"> > + <property name="width_request">700</property> > + <property name="height_request">450</property> > + <child> > + <widget class="GtkVBox" id="windowvbox"> > + <property name="visible">True</property> > + <child> > + <widget class="GtkLabel" id="toolbarlabel"> > + <property name="visible">True</property> > + <property name="label" translatable="yes">move items from store > to toolbar rearrange items in toolbar move items from toolbar to > store</property> > + </widget> > + <packing> > + <property name="expand">False</property> > + </packing> > + </child> > + <child> > + <widget class="GtkScrolledWindow" id="scrolledwindow1"> > + <property name="visible">True</property> > + <property name="can_focus">False</property> > + <property > name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> > + <property > name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> > + <child> > + <widget class="GtkViewport" id="viewport1"> > + <property name="visible">True</property> > + <property name="resize_mode">GTK_RESIZE_QUEUE</property> > + <child> > + <widget class="GtkVBox" id="widgetvbox"> > + <property name="visible">True</property> > + <child> > + <placeholder/> > + </child> > + </widget> > + </child> > + </widget> > + </child> > + </widget> > + <packing> > + <property name="position">1</property> > + </packing> > + </child> > + <child> > + <widget class="GtkHBox" id="buttonhbox"> > + <property name="visible">True</property> > + <property name="can_focus">True</property> > + <child> > + <widget class="GtkButton" id="resetbutton"> > + <property name="visible">True</property> > + <property name="can_focus">True</property> > + <property name="receives_default">True</property> > + <property name="response_id">0</property> > + <child> > + <widget class="GtkHBox" id="button1hbox"> > + <property name="visible">True</property> > + <child> > + <widget class="GtkImage" id="image1"> > + <property name="visible">True</property> > + <property name="stock">gtk-refresh</property> > + </widget> > + <packing> > + <property name="expand">False</property> > + </packing> > + </child> > + <child> > + <widget class="GtkLabel" id="refreshbuttonlabel"> > + <property name="visible">True</property> > + <property name="label" translatable="yes">reset > default</property> > + </widget> > + <packing> > + <property name="position">1</property> > + </packing> > + </child> > + </widget> > + </child> > + </widget> > + <packing> > + <property name="expand">False</property> > + <property name="padding">10</property> > + </packing> > + </child> > + <child> > + <placeholder/> > + </child> > + <child> > + <widget class="GtkButton" id="okbutton"> > + <property name="visible">True</property> > + <property name="can_focus">True</property> > + <property name="has_focus">True</property> > + <property name="receives_default">True</property> > + <property name="label" > translatable="yes">gtk-apply</property> > + <property name="use_stock">True</property> > + <property name="response_id">0</property> > + </widget> > + <packing> > + <property name="expand">False</property> > + <property name="padding">10</property> > + <property name="position">2</property> > + </packing> > + </child> > + <child> > + <widget class="GtkButton" id="cancelbutton"> > + <property name="visible">True</property> > + <property name="can_focus">True</property> > + <property name="receives_default">True</property> > + <property name="label" > translatable="yes">gtk-cancel</property> > + <property name="use_stock">True</property> > + <property name="response_id">0</property> > + </widget> > + <packing> > + <property name="expand">False</property> > + <property name="position">3</property> > + </packing> > + </child> > + </widget> > + <packing> > + <property name="expand">False</property> > + <property name="position">2</property> > + </packing> > + </child> > + </widget> > + </child> > + </widget> > +</glade-interface> > Index: utils/utils.c > =================================================================== > --- utils/utils.c (revision 8438) > +++ utils/utils.c (working copy) > @@ -61,6 +61,23 @@ > return 1; > } > > +char *remove_underscores(const char *s, bool replacespace) > +{ > + size_t i, len, offset = 0; > + char *ret; > + len = strlen(s); > + ret = malloc(len + 1); > + for (i = 0; i < len; i++) > + if (s[i] != '_') > + ret[i - offset] = s[i]; > + else if (replacespace) > + ret[i - offset] = ' '; > + else > + offset++; > + ret[i - offset] = '\0'; > + return ret; > +} > + > /** > * Replace consecutive whitespace with a single space. > * > Index: utils/utils.h > new function to create button labels from menu labels in gtk that contain underscores; could clearly be of more general utility > =================================================================== > --- utils/utils.h (revision 8438) > +++ utils/utils.h (working copy) > @@ -76,6 +76,7 @@ > char * strip(char * const s); > int whitespace(const char * str); > char * squash_whitespace(const char * s); > +char *remove_underscores(const char *s, bool replacespace); > char *cnv_space2nbsp(const char *s); > bool is_dir(const char *path); > void regcomp_wrapper(regex_t *preg, const char *regex, int cflags); -- Mark http://www.halloit.com Key ID 046B65CF
