aboutsummaryrefslogtreecommitdiffstats
path: root/lib/egg/egg-editable-toolbar.c
diff options
context:
space:
mode:
authorMarco Pesenti Gritti <marco@it.gnome.org>2003-04-02 02:48:50 +0800
committerMarco Pesenti Gritti <mpeseng@src.gnome.org>2003-04-02 02:48:50 +0800
commit1bf392262548cf4c6779e1bc6c550b3605aba733 (patch)
treecf7ef737a899cb44d44d4270a788b5a7ebdcc964 /lib/egg/egg-editable-toolbar.c
parenta040bc3b4be4f80ae661b7f2a88c78d29c480e65 (diff)
downloadgsoc2013-epiphany-1bf392262548cf4c6779e1bc6c550b3605aba733.tar
gsoc2013-epiphany-1bf392262548cf4c6779e1bc6c550b3605aba733.tar.gz
gsoc2013-epiphany-1bf392262548cf4c6779e1bc6c550b3605aba733.tar.bz2
gsoc2013-epiphany-1bf392262548cf4c6779e1bc6c550b3605aba733.tar.lz
gsoc2013-epiphany-1bf392262548cf4c6779e1bc6c550b3605aba733.tar.xz
gsoc2013-epiphany-1bf392262548cf4c6779e1bc6c550b3605aba733.tar.zst
gsoc2013-epiphany-1bf392262548cf4c6779e1bc6c550b3605aba733.zip
Use EggEditableToolbar. Update to latest versions (not EggMenuMerge, we
2003-04-01 Marco Pesenti Gritti <marco@it.gnome.org> * lib/egg/Makefile.am: * lib/egg/egg-accel-dialog.c: * lib/egg/egg-action-group.c: * lib/egg/egg-action.c: * lib/egg/egg-editable-toolbar.c: * lib/egg/egg-editable-toolbar.h: * lib/egg/egg-radio-action.c: * lib/egg/egg-toggle-action.c: * lib/egg/egg-toolbars-group.c: * lib/egg/egg-toolbars-group.h: * lib/egg/eggintl.h: * lib/egg/eggtoolbar.c: * lib/egg/eggtoolbutton.c: * lib/egg/update-from-egg.sh: Use EggEditableToolbar. Update to latest versions (not EggMenuMerge, we still need patches). WARNING: it's no more possible to drag bookmarks in the toolbar, if you depend on that feature please wait the weekend to update cvs. * lib/egg/egg-markup.c: * lib/egg/egg-markup.h: Remove, not used. * lib/widgets/Makefile.am: * lib/widgets/ephy-editable-toolbar.c: * lib/widgets/ephy-editable-toolbar.h: * lib/widgets/ephy-toolbars-group.c: * lib/widgets/ephy-toolbars-group.h: Remove. * src/prefs-dialog.c: (prefs_dialog_show_help), (prefs_dialog_response_cb): Fix a warning. * src/toolbar.c: (toolbar_get_type), (toolbar_get_action_name), (toolbar_get_action), (toolbar_class_init), (toolbar_init): * src/toolbar.h: * src/window-commands.c: (window_cmd_edit_toolbar): Update to use the egg api.
Diffstat (limited to 'lib/egg/egg-editable-toolbar.c')
-rwxr-xr-xlib/egg/egg-editable-toolbar.c1149
1 files changed, 1149 insertions, 0 deletions
diff --git a/lib/egg/egg-editable-toolbar.c b/lib/egg/egg-editable-toolbar.c
new file mode 100755
index 000000000..4d1ce4875
--- /dev/null
+++ b/lib/egg/egg-editable-toolbar.c
@@ -0,0 +1,1149 @@
+/*
+ * Copyright (C) 2003 Marco Pesenti Gritti
+ *
+ * This program 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; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "egg-editable-toolbar.h"
+#include "egg-toolbars-group.h"
+#include "eggtoolitem.h"
+#include "eggtoolbar.h"
+#include "eggseparatortoolitem.h"
+
+#include <string.h>
+
+#ifndef _
+# define _(s) (s)
+#endif
+
+#ifndef N_
+# define N_(s) (s)
+#endif
+
+enum
+{
+ X_TOOLBAR_ITEM
+};
+
+static GtkTargetEntry dest_drag_types[] = {
+ {"application/x-toolbar-item", 0, X_TOOLBAR_ITEM},
+};
+static int n_dest_drag_types = G_N_ELEMENTS (dest_drag_types);
+
+static GtkTargetEntry source_drag_types[] = {
+ {"application/x-toolbar-item", 0, X_TOOLBAR_ITEM},
+};
+
+static int n_source_drag_types = G_N_ELEMENTS (source_drag_types);
+
+enum
+{
+ RESPONSE_ADD_TOOLBAR
+};
+
+static void egg_editable_toolbar_class_init (EggEditableToolbarClass *klass);
+static void egg_editable_toolbar_init (EggEditableToolbar *t);
+static void egg_editable_toolbar_finalize (GObject *object);
+static void do_merge (EggEditableToolbar *t);
+static void setup_editor (EggEditableToolbar *etoolbar,
+ GtkWidget *window);
+static void update_editor_sheet (EggEditableToolbar *etoolbar);
+static void egg_editable_toolbar_remove_cb (EggAction *action,
+ EggEditableToolbar *etoolbar);
+static void egg_editable_toolbar_edit_cb (EggAction *action,
+ EggEditableToolbar *etoolbar);
+
+static EggActionGroupEntry egg_toolbar_popups[] = {
+ /* Toplevel */
+ {"FakeToplevel", (""), NULL, NULL, NULL, NULL, NULL},
+
+ /* Popups */
+ {"RemoveToolbarPopup", N_("_Remove Toolbar"), GTK_STOCK_REMOVE, NULL,
+ NULL, G_CALLBACK (egg_editable_toolbar_remove_cb), NULL},
+ {"EditToolbarPopup", N_("_Edit Toolbars..."), GTK_STOCK_PREFERENCES, NULL,
+ NULL, G_CALLBACK (egg_editable_toolbar_edit_cb), NULL},
+};
+
+static guint egg_toolbar_popups_n_entries = G_N_ELEMENTS (egg_toolbar_popups);
+
+enum
+{
+ PROP_0,
+ PROP_TOOLBARS_GROUP,
+ PROP_MENU_MERGE
+};
+
+static GObjectClass *parent_class = NULL;
+
+struct EggEditableToolbarPrivate
+{
+ EggMenuMerge *merge;
+
+ GtkWidget *editor;
+ GtkWidget *table;
+ GtkWidget *scrolled_window;
+
+ GtkWidget *last_toolbar;
+
+ guint ui_id;
+
+ gboolean toolbars_dirty;
+ gboolean editor_sheet_dirty;
+ gboolean edit_mode;
+
+ EggToolbarsGroup *group;
+
+ EggMenuMerge *popup_merge;
+ EggActionGroup *popup_action_group;
+
+ GList *actions_list;
+};
+
+typedef struct
+{
+ EggEditableToolbar *etoolbar;
+ EggToolbarsToolbar *t;
+} ContextMenuData;
+
+GType
+egg_editable_toolbar_get_type (void)
+{
+ static GType egg_editable_toolbar_type = 0;
+
+ if (egg_editable_toolbar_type == 0)
+ {
+ static const GTypeInfo our_info = {
+ sizeof (EggEditableToolbarClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) egg_editable_toolbar_class_init,
+ NULL,
+ NULL, /* class_data */
+ sizeof (EggEditableToolbar),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) egg_editable_toolbar_init
+ };
+
+ egg_editable_toolbar_type = g_type_register_static (G_TYPE_OBJECT,
+ "EggEditableToolbar",
+ &our_info, 0);
+ }
+
+ return egg_editable_toolbar_type;
+}
+
+static void
+update_popup_menu (EggEditableToolbar *t)
+{
+ EggAction *action;
+
+ action = egg_action_group_get_action (t->priv->popup_action_group,
+ "EditToolbarPopup");
+ g_object_set (G_OBJECT (action), "visible", !t->priv->edit_mode, NULL);
+
+ action = egg_action_group_get_action (t->priv->popup_action_group,
+ "RemoveToolbarPopup");
+ g_object_set (G_OBJECT (action), "visible", t->priv->edit_mode, NULL);
+}
+
+static EggAction *
+find_action (EggEditableToolbar *t,
+ const char *name)
+{
+ GList *l = t->priv->merge->action_groups;
+ EggAction *action = NULL;
+
+ g_return_val_if_fail (IS_EGG_EDITABLE_TOOLBAR (t), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ for (; l != NULL; l = l->next)
+ {
+ EggAction *tmp;
+
+ tmp = egg_action_group_get_action (EGG_ACTION_GROUP (l->data), name);
+ if (tmp)
+ action = tmp;
+ }
+
+ return action;
+}
+
+static char *
+impl_get_action_name (EggEditableToolbar *etoolbar,
+ const char *drag_type,
+ const char *data)
+{
+ return NULL;
+}
+
+static EggAction *
+impl_get_action (EggEditableToolbar *etoolbar,
+ const char *name)
+{
+ EggAction *action;
+
+ g_return_val_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar), NULL);
+
+ action = find_action (etoolbar, name);
+
+ return action;
+}
+
+static gboolean
+ui_update (gpointer data)
+{
+ EggEditableToolbar *etoolbar = EGG_EDITABLE_TOOLBAR (data);
+
+ g_return_val_if_fail (etoolbar != NULL, FALSE);
+
+ if (etoolbar->priv->toolbars_dirty)
+ {
+ do_merge (etoolbar);
+ etoolbar->priv->toolbars_dirty = FALSE;
+ }
+
+ if (etoolbar->priv->editor_sheet_dirty)
+ {
+ update_editor_sheet (etoolbar);
+ etoolbar->priv->editor_sheet_dirty = FALSE;
+ }
+
+ return FALSE;
+}
+
+static void
+queue_ui_update (EggEditableToolbar *etoolbar)
+{
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+
+ g_idle_add (ui_update, etoolbar);
+}
+
+static void
+drag_data_received_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time_,
+ EggEditableToolbar *etoolbar)
+{
+ EggToolbarsToolbar *toolbar;
+ const char *type = NULL;
+ EggAction *action = NULL;
+ int pos;
+
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+
+ toolbar =
+ (EggToolbarsToolbar *) g_object_get_data (G_OBJECT (widget),
+ "toolbar_data");
+ pos = egg_toolbar_get_drop_index (EGG_TOOLBAR (widget), x, y);
+
+ /* HACK placeholder are implemented as separators */
+ pos = pos / 3 + 1;
+
+ /* FIXME custom dnd types */
+
+ if (type)
+ {
+ char *name;
+
+ name = egg_editable_toolbar_get_action_name
+ (etoolbar, type, selection_data->data);
+ if (name != NULL)
+ {
+ action = egg_editable_toolbar_get_action (etoolbar, name);
+ g_free (name);
+ }
+ }
+ else
+ {
+ action =
+ egg_editable_toolbar_get_action (etoolbar, selection_data->data);
+ }
+
+ if (action)
+ {
+ egg_toolbars_group_add_item (etoolbar->priv->group, toolbar, pos,
+ action->name);
+ etoolbar->priv->toolbars_dirty = TRUE;
+ }
+ else if (strcmp (selection_data->data, "separator") == 0)
+ {
+ egg_toolbars_group_add_item (etoolbar->priv->group, toolbar, pos,
+ "separator");
+ etoolbar->priv->toolbars_dirty = TRUE;
+ }
+
+ queue_ui_update (etoolbar);
+}
+
+static void
+drag_data_delete_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ EggEditableToolbar *etoolbar)
+{
+ EggToolbarsItem *node;
+
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+
+ node =
+ (EggToolbarsItem *) g_object_get_data (G_OBJECT (widget), "item_data");
+ g_return_if_fail (node != NULL);
+ egg_toolbars_group_remove_item (etoolbar->priv->group, node);
+
+ etoolbar->priv->toolbars_dirty = TRUE;
+ queue_ui_update (etoolbar);
+}
+
+static void
+drag_data_get_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint32 time,
+ EggEditableToolbar *etoolbar)
+{
+ EggAction *action;
+ const char *target;
+
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+
+ action = EGG_ACTION (g_object_get_data (G_OBJECT (widget), "egg-action"));
+
+ if (action)
+ {
+ target = action->name;
+ }
+ else
+ {
+ target = "separator";
+ }
+
+ gtk_selection_data_set (selection_data,
+ selection_data->target, 8, target, strlen (target));
+}
+
+static void
+toolbar_drag_data_delete_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ EggEditableToolbar *etoolbar)
+{
+ EggToolbarsToolbar *t;
+
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+
+ t = (EggToolbarsToolbar *) g_object_get_data (G_OBJECT (widget),
+ "toolbar_drag_data");
+ g_return_if_fail (t != NULL);
+
+ egg_toolbars_group_remove_toolbar (etoolbar->priv->group, t);
+
+ etoolbar->priv->toolbars_dirty = TRUE;
+ queue_ui_update (etoolbar);
+}
+
+static void
+toolbar_drag_data_get_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint32 time,
+ EggEditableToolbar *etoolbar)
+{
+ EggToolbarsToolbar *t;
+ char *target;
+
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+
+ t = (EggToolbarsToolbar *) g_object_get_data (G_OBJECT (widget),
+ "toolbar_drag_data");
+
+ target = t->id;
+
+ gtk_selection_data_set (selection_data,
+ selection_data->target, 8, target, strlen (target));
+}
+
+static void
+egg_editable_toolbar_remove_cb (EggAction *action,
+ EggEditableToolbar *etoolbar)
+{
+ EggToolbarsToolbar *t;
+
+ t = g_object_get_data (G_OBJECT (etoolbar), "popup_toolbar");
+
+ egg_toolbars_group_remove_toolbar (etoolbar->priv->group, t);
+}
+
+static void
+egg_editable_toolbar_edit_cb (EggAction *action,
+ EggEditableToolbar *etoolbar)
+{
+ egg_editable_toolbar_edit (etoolbar, NULL);
+}
+
+static GtkWidget *
+get_item_widget (EggEditableToolbar *t,
+ gpointer data)
+{
+ GtkWidget *widget;
+ char *path;
+
+ path = egg_toolbars_group_get_path (t->priv->group, data);
+ g_return_val_if_fail (path != NULL, NULL);
+
+ widget = egg_menu_merge_get_widget (t->priv->merge, path);
+ g_free (path);
+
+ return widget;
+}
+
+static void
+connect_item_drag_source (EggToolbarsItem *item,
+ EggEditableToolbar *etoolbar)
+{
+ GtkWidget *toolitem;
+
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+ g_return_if_fail (item != NULL);
+
+ toolitem = get_item_widget (etoolbar, item);
+
+ if (!g_object_get_data (G_OBJECT (toolitem), "drag_source_set"))
+ {
+ g_object_set_data (G_OBJECT (toolitem), "drag_source_set",
+ GINT_TO_POINTER (TRUE));
+
+ egg_tool_item_set_use_drag_window (EGG_TOOL_ITEM (toolitem), TRUE);
+
+ g_object_set_data (G_OBJECT (toolitem), "item_data", item);
+
+ gtk_drag_source_set (toolitem, GDK_BUTTON1_MASK,
+ source_drag_types, n_source_drag_types,
+ GDK_ACTION_MOVE);
+ g_signal_connect (toolitem, "drag_data_get",
+ G_CALLBACK (drag_data_get_cb), etoolbar);
+ g_signal_connect (toolitem, "drag_data_delete",
+ G_CALLBACK (drag_data_delete_cb), etoolbar);
+ }
+}
+
+static void
+disconnect_item_drag_source (EggToolbarsItem *item,
+ EggEditableToolbar *etoolbar)
+{
+ GtkWidget *toolitem;
+
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+ g_return_if_fail (item != NULL);
+
+ toolitem = get_item_widget (etoolbar, item);
+
+ if (g_object_get_data (G_OBJECT (toolitem), "drag_source_set"))
+ {
+ g_object_set_data (G_OBJECT (toolitem), "drag_source_set",
+ GINT_TO_POINTER (FALSE));
+
+ egg_tool_item_set_use_drag_window (EGG_TOOL_ITEM (toolitem), FALSE);
+
+ g_signal_handlers_disconnect_by_func (toolitem,
+ G_CALLBACK (drag_data_get_cb),
+ etoolbar);
+ g_signal_handlers_disconnect_by_func (toolitem,
+ G_CALLBACK (drag_data_delete_cb),
+ etoolbar);
+ }
+}
+
+static void
+connect_toolbar_drag_source (EggToolbarsToolbar *t,
+ EggEditableToolbar *etoolbar)
+{
+ GtkWidget *tb;
+
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+ g_return_if_fail (t != NULL);
+
+ tb = get_item_widget (etoolbar, t);
+
+ g_return_if_fail (tb != NULL);
+
+ if (!g_object_get_data (G_OBJECT (tb), "drag_source_set"))
+ {
+ g_object_set_data (G_OBJECT (tb), "drag_source_set",
+ GINT_TO_POINTER (TRUE));
+
+ g_object_set_data (G_OBJECT (tb), "toolbar_drag_data", t);
+
+ g_signal_connect (tb, "drag_data_get",
+ G_CALLBACK (toolbar_drag_data_get_cb), etoolbar);
+ g_signal_connect (tb, "drag_data_delete",
+ G_CALLBACK (toolbar_drag_data_delete_cb), etoolbar);
+ }
+}
+
+static void
+disconnect_toolbar_drag_source (EggToolbarsToolbar *t,
+ EggEditableToolbar *etoolbar)
+{
+ GtkWidget *tb;
+
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+ g_return_if_fail (t != NULL);
+
+ tb = get_item_widget (etoolbar, t);
+
+ g_return_if_fail (tb != NULL);
+
+ if (g_object_get_data (G_OBJECT (tb), "drag_source_set"))
+ {
+ g_object_set_data (G_OBJECT (tb), "drag_source_set",
+ GINT_TO_POINTER (FALSE));
+
+ g_signal_handlers_disconnect_by_func (tb,
+ G_CALLBACK
+ (toolbar_drag_data_get_cb),
+ etoolbar);
+ g_signal_handlers_disconnect_by_func (tb,
+ G_CALLBACK
+ (toolbar_drag_data_delete_cb),
+ etoolbar);
+ }
+}
+
+static void
+popup_toolbar_context_menu (EggToolbar *toolbar,
+ ContextMenuData *data)
+{
+ GtkWidget *widget;
+
+ widget = egg_menu_merge_get_widget (data->etoolbar->priv->popup_merge,
+ "/popups/EggToolbarPopup");
+
+ g_object_set_data (G_OBJECT (data->etoolbar), "popup_toolbar", data->t);
+
+ g_return_if_fail (widget != NULL);
+
+ gtk_menu_popup (GTK_MENU (widget), NULL, NULL, NULL, NULL, 2,
+ gtk_get_current_event_time ());
+}
+
+static void
+setup_toolbar (EggToolbarsToolbar *toolbar,
+ EggEditableToolbar *etoolbar)
+{
+ GtkWidget *widget;
+ ContextMenuData *data;
+ int signal_id;
+
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+ g_return_if_fail (toolbar != NULL);
+
+ widget = get_item_widget (etoolbar, toolbar);
+ g_object_set_data (G_OBJECT (widget), "toolbar_data", toolbar);
+
+ if (!g_object_get_data (G_OBJECT (widget), "drag_dest_set"))
+ {
+ g_object_set_data (G_OBJECT (widget), "drag_dest_set",
+ GINT_TO_POINTER (TRUE));
+ gtk_drag_dest_set (widget, GTK_DEST_DEFAULT_ALL,
+ dest_drag_types, n_dest_drag_types,
+ GDK_ACTION_MOVE | GDK_ACTION_COPY);
+ g_signal_connect (widget, "drag_data_received",
+ G_CALLBACK (drag_data_received_cb), etoolbar);
+ }
+
+ if (!g_object_get_data (G_OBJECT (widget), "popup_signal_id"))
+ {
+ data = g_new0 (ContextMenuData, 1);
+ data->etoolbar = etoolbar;
+ data->t = toolbar;
+
+ signal_id = g_signal_connect_data (widget,
+ "popup_context_menu",
+ G_CALLBACK
+ (popup_toolbar_context_menu), data,
+ (GClosureNotify) g_free, 0);
+
+ g_object_set_data (G_OBJECT (widget), "popup_signal_id",
+ GINT_TO_POINTER (signal_id));
+ }
+
+ etoolbar->priv->last_toolbar = widget;
+}
+
+static void
+ensure_toolbar_min_size (EggToolbarsToolbar *toolbar,
+ EggEditableToolbar *t)
+{
+ GtkWidget *widget;
+
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (t));
+ g_return_if_fail (toolbar != NULL);
+
+ widget = get_item_widget (t, toolbar);
+
+ if (EGG_TOOLBAR (widget)->num_children == 0)
+ {
+ gtk_widget_set_size_request (widget, -1, 20);
+ }
+ else
+ {
+ gtk_widget_set_size_request (widget, -1, -1);
+ }
+}
+
+static void
+do_merge (EggEditableToolbar *t)
+{
+ char *str;
+ guint ui_id;
+
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (t));
+
+ str = egg_toolbars_group_to_string (t->priv->group);
+ g_return_if_fail (str != NULL);
+
+ ui_id = egg_menu_merge_add_ui_from_string (t->priv->merge, str, -1, NULL);
+
+ if (t->priv->ui_id != 0)
+ {
+ egg_menu_merge_remove_ui (t->priv->merge, t->priv->ui_id);
+ }
+
+ t->priv->ui_id = ui_id;
+
+ egg_menu_merge_ensure_update (t->priv->merge);
+
+ egg_toolbars_group_foreach_toolbar (t->priv->group,
+ (EggToolbarsGroupForeachToolbarFunc)
+ setup_toolbar, t);
+
+ if (t->priv->edit_mode)
+ {
+ egg_toolbars_group_foreach_item (t->priv->group,
+ (EggToolbarsGroupForeachItemFunc)
+ connect_item_drag_source, t);
+
+ egg_toolbars_group_foreach_toolbar (t->priv->group,
+ (EggToolbarsGroupForeachToolbarFunc)
+ connect_toolbar_drag_source, t);
+ }
+
+ egg_toolbars_group_foreach_toolbar (t->priv->group,
+ (EggToolbarsGroupForeachToolbarFunc)
+ ensure_toolbar_min_size, t);
+
+ g_free (str);
+}
+
+static void
+ensure_action (EggToolbarsItem *item,
+ EggEditableToolbar *t)
+{
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (t));
+ g_return_if_fail (item != NULL);
+
+ egg_editable_toolbar_get_action (t, item->action);
+}
+
+static void
+group_changed_cb (EggToolbarsGroup *group,
+ EggEditableToolbar *t)
+{
+ g_return_if_fail (IS_EGG_TOOLBARS_GROUP (group));
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (t));
+
+ t->priv->toolbars_dirty = TRUE;
+
+ egg_toolbars_group_foreach_item (t->priv->group,
+ (EggToolbarsGroupForeachItemFunc)
+ ensure_action, t);
+
+ queue_ui_update (t);
+}
+
+static void
+egg_editable_toolbar_set_group (EggEditableToolbar *t,
+ EggToolbarsGroup *group)
+{
+ g_return_if_fail (IS_EGG_TOOLBARS_GROUP (group));
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (t));
+
+ t->priv->group = group;
+
+ g_signal_connect_object (group, "changed",
+ G_CALLBACK (group_changed_cb), t, 0);
+}
+
+static void
+egg_editable_toolbar_set_merge (EggEditableToolbar *t,
+ EggMenuMerge *merge)
+{
+ g_return_if_fail (EGG_IS_MENU_MERGE (merge));
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (t));
+
+ t->priv->merge = merge;
+
+ egg_toolbars_group_foreach_item (t->priv->group,
+ (EggToolbarsGroupForeachItemFunc)
+ ensure_action, t);
+
+ do_merge (t);
+}
+
+static void
+egg_editable_toolbar_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EggEditableToolbar *t = EGG_EDITABLE_TOOLBAR (object);
+
+ switch (prop_id)
+ {
+ case PROP_MENU_MERGE:
+ egg_editable_toolbar_set_merge (t, g_value_get_object (value));
+ break;
+ case PROP_TOOLBARS_GROUP:
+ egg_editable_toolbar_set_group (t, g_value_get_object (value));
+ break;
+ }
+}
+
+static void
+egg_editable_toolbar_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EggEditableToolbar *t = EGG_EDITABLE_TOOLBAR (object);
+
+ switch (prop_id)
+ {
+ case PROP_MENU_MERGE:
+ g_value_set_object (value, t->priv->merge);
+ break;
+ case PROP_TOOLBARS_GROUP:
+ g_value_set_object (value, t->priv->group);
+ break;
+ }
+}
+
+static void
+egg_editable_toolbar_class_init (EggEditableToolbarClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->finalize = egg_editable_toolbar_finalize;
+ object_class->set_property = egg_editable_toolbar_set_property;
+ object_class->get_property = egg_editable_toolbar_get_property;
+
+ klass->get_action = impl_get_action;
+ klass->get_action_name = impl_get_action_name;
+
+ g_object_class_install_property (object_class,
+ PROP_MENU_MERGE,
+ g_param_spec_object ("MenuMerge",
+ "MenuMerge",
+ "Menu merge",
+ EGG_TYPE_MENU_MERGE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_TOOLBARS_GROUP,
+ g_param_spec_object ("ToolbarsGroup",
+ "ToolbarsGroup",
+ "Toolbars Group",
+ EGG_TOOLBARS_GROUP_TYPE,
+ G_PARAM_READWRITE));
+}
+
+static void
+egg_editable_toolbar_init (EggEditableToolbar *t)
+{
+ int i;
+
+ t->priv = g_new0 (EggEditableToolbarPrivate, 1);
+
+ t->priv->merge = NULL;
+ t->priv->editor = NULL;
+ t->priv->ui_id = 0;
+ t->priv->toolbars_dirty = FALSE;
+ t->priv->editor_sheet_dirty = FALSE;
+ t->priv->edit_mode = FALSE;
+ t->priv->actions_list = NULL;
+
+ for (i = 0; i < egg_toolbar_popups_n_entries; i++)
+ {
+ egg_toolbar_popups[i].user_data = t;
+ }
+
+ t->priv->popup_merge = egg_menu_merge_new ();
+
+ t->priv->popup_action_group = egg_action_group_new ("ToolbarPopupActions");
+ egg_action_group_add_actions (t->priv->popup_action_group,
+ egg_toolbar_popups,
+ egg_toolbar_popups_n_entries);
+ egg_menu_merge_insert_action_group (t->priv->popup_merge,
+ t->priv->popup_action_group, 0);
+/* FIXME
+ egg_menu_merge_add_ui_from_file (t->priv->popup_merge,
+ egg_file ("epiphany-toolbar-popup-ui.xml"),
+ NULL);
+*/
+ update_popup_menu (t);
+}
+
+static void
+egg_editable_toolbar_finalize (GObject *object)
+{
+ EggEditableToolbar *t = EGG_EDITABLE_TOOLBAR (object);
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (object));
+
+ if (t->priv->editor)
+ {
+ gtk_widget_destroy (t->priv->editor);
+ }
+
+ g_object_unref (t->priv->popup_action_group);
+ egg_menu_merge_remove_action_group (t->priv->popup_merge,
+ t->priv->popup_action_group);
+ g_object_unref (t->priv->popup_merge);
+
+ g_free (t->priv);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+EggEditableToolbar *
+egg_editable_toolbar_new (EggMenuMerge *merge,
+ EggToolbarsGroup *group)
+{
+ EggEditableToolbar *t;
+
+ t = EGG_EDITABLE_TOOLBAR (g_object_new (EGG_EDITABLE_TOOLBAR_TYPE,
+ "ToolbarsGroup", group,
+ "MenuMerge", merge, NULL));
+
+ g_return_val_if_fail (t->priv != NULL, NULL);
+
+ return t;
+}
+
+static void
+hide_editor (EggEditableToolbar *etoolbar)
+{
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+
+ gtk_widget_hide (GTK_WIDGET (etoolbar->priv->editor));
+}
+
+static void
+editor_drag_data_received_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time_,
+ EggEditableToolbar *etoolbar)
+{
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+
+ etoolbar->priv->editor_sheet_dirty = TRUE;
+ queue_ui_update (etoolbar);
+}
+
+static void
+editor_drag_data_delete_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ EggEditableToolbar *etoolbar)
+{
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+
+ etoolbar->priv->editor_sheet_dirty = TRUE;
+ queue_ui_update (etoolbar);
+}
+
+static void
+editor_close (EggEditableToolbar * etoolbar)
+{
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+
+ etoolbar->priv->edit_mode = FALSE;
+ egg_toolbars_group_foreach_item (etoolbar->priv->group,
+ (EggToolbarsGroupForeachItemFunc)
+ disconnect_item_drag_source, etoolbar);
+ egg_toolbars_group_foreach_toolbar (etoolbar->priv->group,
+ (EggToolbarsGroupForeachToolbarFunc)
+ disconnect_toolbar_drag_source,
+ etoolbar);
+
+ update_popup_menu (etoolbar);
+ hide_editor (etoolbar);
+}
+
+static void
+editor_add_toolbar (EggEditableToolbar *etoolbar)
+{
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+
+ egg_toolbars_group_add_toolbar (etoolbar->priv->group);
+
+ etoolbar->priv->toolbars_dirty = TRUE;
+ queue_ui_update (etoolbar);
+}
+
+static void
+dialog_response_cb (GtkDialog *dialog,
+ gint response_id,
+ EggEditableToolbar *etoolbar)
+{
+ switch (response_id)
+ {
+ case RESPONSE_ADD_TOOLBAR:
+ editor_add_toolbar (etoolbar);
+ break;
+ case GTK_RESPONSE_CLOSE:
+ editor_close (etoolbar);
+ break;
+ }
+}
+
+static void
+setup_editor (EggEditableToolbar *etoolbar,
+ GtkWidget *window)
+{
+ GtkWidget *editor;
+ GtkWidget *scrolled_window;
+ GtkWidget *vbox;
+ GtkWidget *label_hbox;
+ GtkWidget *image;
+ GtkWidget *label;
+
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+
+ editor = gtk_dialog_new (),
+ gtk_dialog_set_has_separator (GTK_DIALOG (editor), FALSE);
+ gtk_widget_set_size_request (GTK_WIDGET (editor), 500, 330);
+ gtk_window_set_transient_for (GTK_WINDOW (editor), GTK_WINDOW (window));
+ gtk_window_set_title (GTK_WINDOW (editor), "Toolbar editor");
+ etoolbar->priv->editor = editor;
+
+ vbox = gtk_vbox_new (FALSE, 12);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
+ gtk_widget_show (vbox);
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (editor)->vbox), vbox);
+ scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ etoolbar->priv->scrolled_window = scrolled_window;
+ gtk_widget_show (scrolled_window);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 0);
+ label_hbox = gtk_hbox_new (FALSE, 6);
+ gtk_widget_show (label_hbox);
+ gtk_box_pack_start (GTK_BOX (vbox), label_hbox, FALSE, FALSE, 0);
+ image =
+ gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
+ gtk_widget_show (image);
+ gtk_box_pack_start (GTK_BOX (label_hbox), image, FALSE, FALSE, 0);
+ label = gtk_label_new (_("Drag an item onto the toolbars above to add it, "
+ "from the toolbars in the items table to remove it."));
+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+ gtk_widget_show (label);
+ gtk_box_pack_start (GTK_BOX (label_hbox), label, FALSE, TRUE, 0);
+
+ gtk_dialog_add_button (GTK_DIALOG (editor),
+ _("Add Toolbar"), RESPONSE_ADD_TOOLBAR);
+ gtk_dialog_add_button (GTK_DIALOG (editor),
+ GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
+
+ g_signal_connect (editor, "response",
+ G_CALLBACK (dialog_response_cb), etoolbar);
+
+ update_editor_sheet (etoolbar);
+}
+
+static void
+add_to_list (EggToolbarsItem *item,
+ GList **l)
+{
+ g_return_if_fail (item != NULL);
+
+ *l = g_list_append (*l, item);
+}
+
+static void
+update_editor_sheet (EggEditableToolbar *etoolbar)
+{
+ GList *l;
+ GList *to_drag = NULL;
+ int x, y, height, width;
+ GtkWidget *table;
+ GtkWidget *viewport;
+
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+
+ viewport = GTK_BIN (etoolbar->priv->scrolled_window)->child;
+ if (viewport)
+ {
+ table = GTK_BIN (viewport)->child;
+ gtk_container_remove (GTK_CONTAINER (viewport), table);
+ }
+ table = gtk_table_new (0, 0, TRUE);
+ etoolbar->priv->table = table;
+ gtk_container_set_border_width (GTK_CONTAINER (table), 12);
+ gtk_widget_show (table);
+ gtk_scrolled_window_add_with_viewport
+ (GTK_SCROLLED_WINDOW (etoolbar->priv->scrolled_window), table);
+ gtk_drag_dest_set (table, GTK_DEST_DEFAULT_ALL,
+ dest_drag_types, n_dest_drag_types, GDK_ACTION_MOVE);
+ g_signal_connect (table, "drag_data_received",
+ G_CALLBACK (editor_drag_data_received_cb), etoolbar);
+
+ egg_toolbars_group_foreach_available (etoolbar->priv->group,
+ (EggToolbarsGroupForeachItemFunc)
+ add_to_list, &to_drag);
+
+ x = y = 0;
+ width = 4;
+ height = (g_list_length (to_drag) - 1) / width + 1;
+ gtk_table_resize (GTK_TABLE (etoolbar->priv->table), height, width);
+
+ for (l = to_drag; l != NULL; l = l->next)
+ {
+ GtkWidget *event_box;
+ GtkWidget *vbox;
+ GtkWidget *icon;
+ GtkWidget *label;
+ EggToolbarsItem *node = (EggToolbarsItem *) (l->data);
+ EggAction *action;
+
+ action = egg_editable_toolbar_get_action (etoolbar, node->action);
+ g_return_if_fail (action != NULL);
+
+ event_box = gtk_event_box_new ();
+ gtk_widget_show (event_box);
+ gtk_drag_source_set (event_box,
+ GDK_BUTTON1_MASK,
+ source_drag_types, 1, GDK_ACTION_MOVE);
+ g_signal_connect (event_box, "drag_data_get",
+ G_CALLBACK (drag_data_get_cb), etoolbar);
+ g_signal_connect (event_box, "drag_data_delete",
+ G_CALLBACK (editor_drag_data_delete_cb), etoolbar);
+
+ g_object_set_data (G_OBJECT (event_box), "egg-action", action);
+
+ vbox = gtk_vbox_new (0, FALSE);
+ gtk_widget_show (vbox);
+ gtk_container_add (GTK_CONTAINER (event_box), vbox);
+
+ icon = gtk_image_new_from_stock
+ (action->stock_id ? action->stock_id : GTK_STOCK_DND,
+ GTK_ICON_SIZE_LARGE_TOOLBAR);
+ gtk_widget_show (icon);
+ gtk_box_pack_start (GTK_BOX (vbox), icon, FALSE, TRUE, 0);
+
+ label = gtk_label_new_with_mnemonic (action->label);
+ gtk_widget_show (label);
+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
+
+ gtk_table_attach_defaults (GTK_TABLE (etoolbar->priv->table),
+ event_box, x, x + 1, y, y + 1);
+
+ x++;
+ if (x >= width)
+ {
+ x = 0;
+ y++;
+ }
+ }
+
+ g_list_free (to_drag);
+}
+
+static void
+show_editor (EggEditableToolbar *etoolbar)
+{
+ GtkWidget *editor = etoolbar->priv->editor;
+
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+ g_return_if_fail (editor != NULL);
+
+ gtk_widget_show (GTK_WIDGET (editor));
+}
+
+static void
+set_action_sensitive (EggToolbarsItem *item,
+ EggEditableToolbar *etoolbar)
+{
+ EggAction *action;
+
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+ g_return_if_fail (item != NULL);
+
+ if (!item->separator)
+ {
+ action = find_action (etoolbar, item->action);
+ g_object_set (action, "sensitive", TRUE, NULL);
+ }
+}
+
+void
+egg_editable_toolbar_edit (EggEditableToolbar *etoolbar,
+ GtkWidget *window)
+{
+ g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar));
+
+ etoolbar->priv->edit_mode = TRUE;
+ egg_toolbars_group_foreach_item (etoolbar->priv->group,
+ (EggToolbarsGroupForeachItemFunc)
+ connect_item_drag_source, etoolbar);
+ egg_toolbars_group_foreach_item (etoolbar->priv->group,
+ (EggToolbarsGroupForeachItemFunc)
+ set_action_sensitive, etoolbar);
+ egg_toolbars_group_foreach_toolbar (etoolbar->priv->group,
+ (EggToolbarsGroupForeachToolbarFunc)
+ connect_toolbar_drag_source, etoolbar);
+
+ update_popup_menu (etoolbar);
+
+ setup_editor (etoolbar, window);
+ show_editor (etoolbar);
+}
+
+char *
+egg_editable_toolbar_get_action_name (EggEditableToolbar *etoolbar,
+ const char *drag_type,
+ const char *data)
+{
+ EggEditableToolbarClass *klass = EGG_EDITABLE_TOOLBAR_GET_CLASS (etoolbar);
+ return klass->get_action_name (etoolbar, drag_type, data);
+}
+
+EggAction *
+egg_editable_toolbar_get_action (EggEditableToolbar *etoolbar,
+ const char *name)
+{
+ EggEditableToolbarClass *klass = EGG_EDITABLE_TOOLBAR_GET_CLASS (etoolbar);
+ return klass->get_action (etoolbar, name);
+}