> 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


Reply via email to