diff options
Diffstat (limited to 'lib/egg')
-rw-r--r-- | lib/egg/Makefile.am | 28 | ||||
-rw-r--r-- | lib/egg/egg-accel-dialog.c | 2 | ||||
-rw-r--r-- | lib/egg/egg-action-group.c | 3 | ||||
-rw-r--r-- | lib/egg/egg-action.c | 17 | ||||
-rwxr-xr-x | lib/egg/egg-editable-toolbar.c | 1149 | ||||
-rwxr-xr-x | lib/egg/egg-editable-toolbar.h | 73 | ||||
-rw-r--r-- | lib/egg/egg-markup.c | 438 | ||||
-rw-r--r-- | lib/egg/egg-markup.h | 30 | ||||
-rw-r--r-- | lib/egg/egg-radio-action.c | 2 | ||||
-rw-r--r-- | lib/egg/egg-toggle-action.c | 2 | ||||
-rwxr-xr-x | lib/egg/egg-toolbars-group.c | 643 | ||||
-rwxr-xr-x | lib/egg/egg-toolbars-group.h | 99 | ||||
-rw-r--r-- | lib/egg/eggintl.h | 6 | ||||
-rw-r--r-- | lib/egg/eggtoolbar.c | 1 | ||||
-rw-r--r-- | lib/egg/eggtoolbutton.c | 2 | ||||
-rwxr-xr-x | lib/egg/update-from-egg.sh | 40 |
16 files changed, 2044 insertions, 491 deletions
diff --git a/lib/egg/Makefile.am b/lib/egg/Makefile.am index b903ca315..4a1448a11 100644 --- a/lib/egg/Makefile.am +++ b/lib/egg/Makefile.am @@ -6,12 +6,11 @@ INCLUDES = \ noinst_LTLIBRARIES = libegg.la -libegg_la_SOURCES = \ +EGGSOURCES = \ egg-action.c \ egg-action-group.c \ egg-toggle-action.c \ egg-radio-action.c \ - egg-markup.c \ egg-menu-merge.c \ egg-accel-dialog.c \ eggradiotoolbutton.c \ @@ -20,15 +19,19 @@ libegg_la_SOURCES = \ eggseparatortoolitem.c \ eggtoolbar.c \ eggtoolbutton.c \ - eggmarshalers.c + eggmarshalers.c \ + egg-editable-toolbar.c \ + egg-toolbars-group.c -noinst_HEADERS = \ +libegg_la_SOURCES = \ + $(EGGSOURCES) + +EGGHEADERS = \ egg-menu.h \ egg-action.h \ egg-action-group.h \ egg-toggle-action.h \ egg-radio-action.h \ - egg-markup.h \ egg-menu-merge.h \ egg-accel-dialog.h \ eggradiotoolbutton.h \ @@ -37,7 +40,13 @@ noinst_HEADERS = \ eggseparatortoolitem.h \ eggtoolbar.h \ eggtoolbutton.h \ - eggmarshalers.h + eggmarshalers.h \ + egg-editable-toolbar.h \ + egg-toolbars-group.h + +noinst_HEADERS = \ + $(EGGHEADERS) \ + eggintl.h eggmarshalers.h: cd $(srcdir) \ @@ -55,3 +64,10 @@ egg-marshal.c: eggmarshalers.h eggmarshalers.c EXTRA_DIST= \ eggmarshalers.list + +EGGFILES=$(EGGSOURCES) $(EGGHEADERS) +EGGDIR=$(srcdir)/../../../libegg/libegg + +regenerate-built-sources: + EGGFILES="$(EGGFILES)" EGGDIR="$(EGGDIR)" $(srcdir)/update-from-egg.sh + diff --git a/lib/egg/egg-accel-dialog.c b/lib/egg/egg-accel-dialog.c index 7435044e8..4173cbf02 100644 --- a/lib/egg/egg-accel-dialog.c +++ b/lib/egg/egg-accel-dialog.c @@ -6,7 +6,7 @@ static void egg_accel_dialog_class_init (EggAccelDialogClass *class); GType egg_accel_dialog_get_type (void) { - static GType type = 0; + static GtkType type = 0; if (!type) { diff --git a/lib/egg/egg-action-group.c b/lib/egg/egg-action-group.c index 43cb7f9d4..42d95aabb 100644 --- a/lib/egg/egg-action-group.c +++ b/lib/egg/egg-action-group.c @@ -1,8 +1,7 @@ #include "egg-action-group.h" #include "egg-toggle-action.h" #include "egg-radio-action.h" - -#define _(String) gettext (String) +#include "eggintl.h" static void egg_action_group_init (EggActionGroup *self); static void egg_action_group_class_init (EggActionGroupClass *class); diff --git a/lib/egg/egg-action.c b/lib/egg/egg-action.c index 6d1889e65..8cb099048 100644 --- a/lib/egg/egg-action.c +++ b/lib/egg/egg-action.c @@ -1,9 +1,7 @@ #include "egg-action.h" #include "eggtoolbutton.h" +#include "eggintl.h" -#ifndef _ -# define _(s) (s) -#endif /* some code for making arbitrary GtkButtons that act like toolbar * buttons */ @@ -38,7 +36,7 @@ static const gchar *accel_path_key = "EggAction::accel_path"; GType egg_action_get_type (void) { - static GType type = 0; + static GtkType type = 0; if (!type) { @@ -560,14 +558,11 @@ disconnect_proxy (EggAction *action, GtkWidget *proxy) G_CALLBACK (egg_action_sync_stock_id), proxy); /* menu item specific synchronisers ... */ - if (GTK_IS_MENU_ITEM (proxy)) - { - g_signal_handlers_disconnect_by_func (action, - G_CALLBACK (egg_action_sync_label), - proxy); + g_signal_handlers_disconnect_by_func (action, + G_CALLBACK (egg_action_sync_label), + proxy); - gtk_menu_item_set_accel_path (GTK_MENU_ITEM (proxy), NULL); - } + gtk_menu_item_set_accel_path (GTK_MENU_ITEM (proxy), NULL); /* toolbar button specific synchronisers ... */ g_signal_handlers_disconnect_by_func (action, 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); +} diff --git a/lib/egg/egg-editable-toolbar.h b/lib/egg/egg-editable-toolbar.h new file mode 100755 index 000000000..36d65cd35 --- /dev/null +++ b/lib/egg/egg-editable-toolbar.h @@ -0,0 +1,73 @@ +/* + * 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. + */ + +#ifndef EGG_EDITABLE_TOOLBAR_H +#define EGG_EDITABLE_TOOLBAR_H + +#include <glib-object.h> +#include <glib.h> + +#include "egg-menu-merge.h" +#include "egg-toolbars-group.h" + +G_BEGIN_DECLS + +typedef struct EggEditableToolbarClass EggEditableToolbarClass; + +#define EGG_EDITABLE_TOOLBAR_TYPE (egg_editable_toolbar_get_type ()) +#define EGG_EDITABLE_TOOLBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_EDITABLE_TOOLBAR_TYPE, EggEditableToolbar)) +#define EGG_EDITABLE_TOOLBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_EDITABLE_TOOLBAR_TYPE, EggEditableToolbarClass)) +#define IS_EGG_EDITABLE_TOOLBAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_EDITABLE_TOOLBAR_TYPE)) +#define IS_EGG_EDITABLE_TOOLBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_EDITABLE_TOOLBAR_TYPE)) +#define EGG_EDITABLE_TOOLBAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_EDITABLE_TOOLBAR_TYPE, EggEditableToolbarClass)) + + +typedef struct EggEditableToolbar EggEditableToolbar; +typedef struct EggEditableToolbarPrivate EggEditableToolbarPrivate; + +struct EggEditableToolbar +{ + GObject parent_object; + EggEditableToolbarPrivate *priv; +}; + +struct EggEditableToolbarClass +{ + GObjectClass parent_class; + + char *(* get_action_name) (EggEditableToolbar *etoolbar, + const char *drag_type, + const char *data); + EggAction *( *get_action) (EggEditableToolbar *etoolbar, + const char *name); +}; + +GType egg_editable_toolbar_get_type (void); +EggEditableToolbar *egg_editable_toolbar_new (EggMenuMerge *merge, + EggToolbarsGroup *group); +void egg_editable_toolbar_edit (EggEditableToolbar *etoolbar, + GtkWidget *window); +char *egg_editable_toolbar_get_action_name (EggEditableToolbar *etoolbar, + const char *drag_type, + const char *data); +EggAction *egg_editable_toolbar_get_action (EggEditableToolbar *etoolbar, + const char *name); + +G_END_DECLS + +#endif diff --git a/lib/egg/egg-markup.c b/lib/egg/egg-markup.c deleted file mode 100644 index feae85a00..000000000 --- a/lib/egg/egg-markup.c +++ /dev/null @@ -1,438 +0,0 @@ -#include <string.h> -#include "egg-markup.h" -#include "eggtoolbar.h" - -#ifndef _ -# define _(String) (String) -# define N_(String) (String) -#endif - -typedef enum { - STATE_START, - STATE_ROOT, - STATE_MENU, - STATE_TOOLBAR, - STATE_POPUPS, - STATE_ITEM, - STATE_END -} ParseState; - -typedef struct _ParseContext ParseContext; -struct _ParseContext -{ - /* parser state information */ - ParseState state; - ParseState prev_state; - - /* function to call when we finish off a toplevel widget */ - EggWidgetFunc widget_func; - gpointer user_data; - - /* GdkAccelGroup to use for menus */ - GtkAccelGroup *accel_group; - - /* info about the widget we are constructing at the moment */ - GtkWidget *top; - gchar *type; - gchar *name; - - /* the current container we are working on */ - GtkWidget *current; - - /* the ActionGroup used to create menu items */ - EggActionGroup *action_group; -}; - -static void -start_element_handler (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - gpointer user_data, - GError **error) -{ - ParseContext *ctx = user_data; - gboolean raise_error = TRUE; - gchar *error_attr = NULL; - - switch (element_name[0]) - { - case 'R': - if (ctx->state == STATE_START && !strcmp(element_name, "Root")) - { - ctx->state = STATE_ROOT; - raise_error = FALSE; - } - break; - case 'm': - if (ctx->state == STATE_ROOT && !strcmp(element_name, "menu")) - { - ctx->state = STATE_MENU; - - ctx->top = ctx->current = gtk_menu_bar_new(); - ctx->type = "menu"; - ctx->name = NULL; - - raise_error = FALSE; - } - else if (ctx->state == STATE_MENU && !strcmp(element_name, "menuitem")) - { - gint i; - const gchar *action_name = NULL; - EggAction *action = NULL; - - ctx->state = STATE_ITEM; - - for (i = 0; attribute_names[i] != NULL; i++) - { - if (!strcmp(attribute_names[i], "verb")) - { - action_name = attribute_values[i]; - action = egg_action_group_get_action(ctx->action_group, - action_name); - } - } - - if (action) - { - GtkWidget *widget = egg_action_create_menu_item(action); - - gtk_container_add(GTK_CONTAINER(ctx->current), widget); - gtk_widget_show(widget); - } - else - { - g_warning("could not find action '%s'", - action_name ? action_name : "(null)"); - } - - raise_error = FALSE; - } - break; - case 'd': - if (ctx->state == STATE_ROOT && !strcmp(element_name, "dockitem")) - { - gint i; - - ctx->state = STATE_TOOLBAR; - - ctx->top = ctx->current = egg_toolbar_new(); - ctx->type = "toolbar"; - for (i = 0; attribute_names[i] != NULL; i++) - { - if (!strcmp(attribute_names[i], "name")) - ctx->name = g_strdup(attribute_values[i]); - } - - raise_error = FALSE; - } - break; - case 'p': - if (ctx->state == STATE_ROOT && !strcmp(element_name, "popups")) - { - ctx->state = STATE_POPUPS; - raise_error = FALSE; - } - else if (ctx->state == STATE_POPUPS &&!strcmp(element_name, "popup")) - { - gint i; - - ctx->state = STATE_MENU; - - ctx->top = ctx->current = gtk_menu_new(); - gtk_menu_set_accel_group(GTK_MENU(ctx->current), ctx->accel_group); - ctx->type = "popup"; - for (i = 0; attribute_names[i] != NULL; i++) - { - if (!strcmp(attribute_names[i], "name")) - { - ctx->name = g_strdup(attribute_values[i]); - gtk_menu_set_title(GTK_MENU(ctx->current), ctx->name); - } - else if (!strcmp(attribute_names[i], "tearoff")) - { - GtkWidget *tearoff = gtk_tearoff_menu_item_new(); - - gtk_container_add(GTK_CONTAINER(ctx->current), tearoff); - gtk_widget_show(tearoff); - } - } - - raise_error = FALSE; - } - break; - case 's': - if (ctx->state == STATE_MENU && !strcmp(element_name, "submenu")) - { - gint i; - const gchar *label = NULL; - gboolean tearoff = FALSE; - GtkWidget *widget; - - ctx->state = STATE_MENU; - for (i = 0; attribute_names[i] != NULL; i++) - { - if (!strcmp(attribute_names[i], "label")) - label = g_strdup(attribute_values[i]); - else if (!strcmp(attribute_names[i], "tearoff")) - tearoff = TRUE; - } - widget = gtk_menu_item_new_with_label(label); - gtk_label_set_use_underline(GTK_LABEL(GTK_BIN(widget)->child), TRUE); - gtk_container_add(GTK_CONTAINER(ctx->current), widget); - gtk_widget_show(widget); - - ctx->current = gtk_menu_new(); - gtk_menu_set_accel_group(GTK_MENU(ctx->current), ctx->accel_group); - gtk_menu_set_title(GTK_MENU(ctx->current), label); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(widget), ctx->current); - - if (tearoff) - { - GtkWidget *tearoff = gtk_tearoff_menu_item_new(); - - gtk_container_add(GTK_CONTAINER(ctx->current), tearoff); - gtk_widget_show(tearoff); - } - - raise_error = FALSE; - } - else if ((ctx->state == STATE_MENU || ctx->state == STATE_TOOLBAR) && - !strcmp(element_name, "separator")) - { - ctx->state = STATE_ITEM; - - if (GTK_IS_MENU_SHELL(ctx->current)) - { - GtkWidget *widget = gtk_separator_menu_item_new(); - gtk_container_add(GTK_CONTAINER(ctx->current), widget); - gtk_widget_show(widget); - } - else /* toolbar */ - { - EggToolItem *item = egg_tool_item_new (); - egg_toolbar_insert_tool_item (EGG_TOOLBAR(ctx->current), item, -1); - gtk_widget_show (GTK_WIDGET (item)); - } - - raise_error = FALSE; - } - break; - case 't': - if (ctx->state == STATE_TOOLBAR && !strcmp(element_name, "toolitem")) - { - gint i; - const gchar *action_name = NULL; - EggAction *action = NULL; - - ctx->state = STATE_ITEM; - - for (i = 0; attribute_names[i] != NULL; i++) - { - if (!strcmp(attribute_names[i], "verb")) - { - action_name = attribute_values[i]; - action = egg_action_group_get_action(ctx->action_group, - action_name); - } - } - - if (action) - { - GtkWidget *widget = egg_action_create_tool_item (action); - - gtk_container_add (GTK_CONTAINER (ctx->current), widget); - } - else - { - g_warning("could not find action '%s'", - action_name ? action_name : "(null)"); - } - - raise_error = FALSE; - } - break; - }; - - if (raise_error) - { - gint line_number, char_number; - - g_markup_parse_context_get_position (context, - &line_number, &char_number); - - if (error_attr) - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, - _("Unknown attribute '%s' on line %d char %d"), - error_attr, - line_number, char_number); - else - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_UNKNOWN_ELEMENT, - _("Unknown tag '%s' on line %d char %d"), - element_name, - line_number, char_number); - } -} - -static void -end_element_handler (GMarkupParseContext *context, - const gchar *element_name, - gpointer user_data, - GError **error) -{ - ParseContext *ctx = user_data; - GtkWidget *widget; - - switch (ctx->state) - { - case STATE_START: - g_warning("shouldn't get any end tags at this point"); - /* should do a GError here */ - break; - case STATE_ROOT: - ctx->state = STATE_END; - break; - case STATE_MENU: - widget = GTK_IS_MENU(ctx->current) ? - gtk_menu_get_attach_widget(GTK_MENU(ctx->current)) : NULL; - if (widget) /* not back to the toplevel ... */ - { - ctx->current = widget->parent; - ctx->state = STATE_MENU; - } - else - { - if (GTK_IS_MENU(ctx->current)) /* must be a popup */ - ctx->state = STATE_POPUPS; - else - ctx->state = STATE_ROOT; - - /* notify */ - (* ctx->widget_func)(ctx->top, ctx->type, ctx->name, ctx->user_data); - ctx->top = NULL; - ctx->type = NULL; - g_free(ctx->name); - ctx->name = NULL; - ctx->current = NULL; - } - break; - case STATE_TOOLBAR: - ctx->state = STATE_ROOT; - - /* notify */ - (* ctx->widget_func)(ctx->top, ctx->type, ctx->name, ctx->user_data); - ctx->top = NULL; - ctx->type = NULL; - g_free(ctx->name); - ctx->name = NULL; - ctx->current = NULL; - break; - case STATE_POPUPS: - ctx->state = STATE_ROOT; - break; - case STATE_ITEM: - if (GTK_IS_MENU_SHELL(ctx->current)) - ctx->state = STATE_MENU; - else - ctx->state = STATE_TOOLBAR; - break; - case STATE_END: - g_warning("shouldn't get any end tags at this point"); - /* should do a GError here */ - break; - } -} - -static void -cleanup (GMarkupParseContext *context, - GError *error, - gpointer user_data) -{ - ParseContext *ctx = user_data; - - gtk_widget_destroy(ctx->top); - ctx->top = NULL; - ctx->type = NULL; - g_free(ctx->name); - ctx->name = NULL; - ctx->current = NULL; -} - - -static GMarkupParser ui_parser = { - start_element_handler, - end_element_handler, - NULL, - NULL, - cleanup -}; - - -gboolean -egg_create_from_string (EggActionGroup *action_group, - EggWidgetFunc widget_func, gpointer user_data, - GtkAccelGroup *accel_group, - const gchar *buffer, guint length, - GError **error) -{ - ParseContext ctx = { 0 }; - GMarkupParseContext *context; - gboolean res = TRUE; - - g_return_val_if_fail(EGG_IS_ACTION_GROUP(action_group), FALSE); - g_return_val_if_fail(widget_func != NULL, FALSE); - g_return_val_if_fail(GTK_IS_ACCEL_GROUP(accel_group), FALSE); - g_return_val_if_fail(buffer != NULL, FALSE); - - ctx.state = STATE_START; - ctx.widget_func = widget_func; - ctx.user_data = user_data; - ctx.accel_group = accel_group; - ctx.top = NULL; - ctx.type = NULL; - ctx.name = NULL; - ctx.current = NULL; - ctx.action_group = action_group; - - context = g_markup_parse_context_new(&ui_parser, 0, &ctx, NULL); - if (length < 0) - length = strlen(buffer); - - if (g_markup_parse_context_parse(context, buffer, length, error)) - { - if (!g_markup_parse_context_end_parse(context, error)) - res = FALSE; - } - else - res = FALSE; - - g_markup_parse_context_free (context); - - return res; -} - -gboolean -egg_create_from_file (EggActionGroup *action_group, - EggWidgetFunc widget_func, - gpointer user_data, - GtkAccelGroup *accel_group, - const gchar *filename, - GError **error) -{ - gchar *buffer; - gint length; - gboolean res; - - if (!g_file_get_contents (filename, &buffer, &length, error)) - return FALSE; - - res = egg_create_from_string(action_group, widget_func, user_data, - accel_group, buffer, length, error); - g_free(buffer); - - return res; -} diff --git a/lib/egg/egg-markup.h b/lib/egg/egg-markup.h deleted file mode 100644 index 15524189f..000000000 --- a/lib/egg/egg-markup.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef EGG_MARKUP_H -#define EGG_MARKUP_H - -#include <gtk/gtk.h> -#include <egg-action.h> -#include <egg-action-group.h> - - -/* this stuff can go away once I am finished with the merge code */ - -typedef void (*EggWidgetFunc) (GtkWidget *widget, - const gchar *type, - const gchar *name, - gpointer user_data); - -gboolean egg_create_from_string (EggActionGroup *action_group, - EggWidgetFunc widget_func, - gpointer user_data, - GtkAccelGroup *accel_group, - const gchar *buffer, guint length, - GError **error); - -gboolean egg_create_from_file (EggActionGroup *action_group, - EggWidgetFunc widget_func, - gpointer user_data, - GtkAccelGroup *accel_group, - const gchar *filename, - GError **error); - -#endif diff --git a/lib/egg/egg-radio-action.c b/lib/egg/egg-radio-action.c index 6a4a13314..888448c50 100644 --- a/lib/egg/egg-radio-action.c +++ b/lib/egg/egg-radio-action.c @@ -6,7 +6,7 @@ static void egg_radio_action_class_init (EggRadioActionClass *class); GType egg_radio_action_get_type (void) { - static GType type = 0; + static GtkType type = 0; if (!type) { diff --git a/lib/egg/egg-toggle-action.c b/lib/egg/egg-toggle-action.c index 0c5dfe121..6c0c0b442 100644 --- a/lib/egg/egg-toggle-action.c +++ b/lib/egg/egg-toggle-action.c @@ -12,7 +12,7 @@ static void egg_toggle_action_class_init (EggToggleActionClass *class); GType egg_toggle_action_get_type (void) { - static GType type = 0; + static GtkType type = 0; if (!type) { diff --git a/lib/egg/egg-toolbars-group.c b/lib/egg/egg-toolbars-group.c new file mode 100755 index 000000000..c99f0cd06 --- /dev/null +++ b/lib/egg/egg-toolbars-group.c @@ -0,0 +1,643 @@ +/* + * Copyright (C) 2002 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-toolbars-group.h" + +#include <string.h> + +static void egg_toolbars_group_class_init (EggToolbarsGroupClass *klass); +static void egg_toolbars_group_init (EggToolbarsGroup *t); +static void egg_toolbars_group_finalize (GObject *object); + +enum +{ + CHANGED, + LAST_SIGNAL +}; + +static guint egg_toolbars_group_signals[LAST_SIGNAL] = { 0 }; + +static GObjectClass *parent_class = NULL; + +struct EggToolbarsGroupPrivate +{ + GNode *available_actions; + GNode *toolbars; + char *defaults; + char *user; +}; + +GType +egg_toolbars_group_get_type (void) +{ + static GType egg_toolbars_group_type = 0; + + if (egg_toolbars_group_type == 0) + { + static const GTypeInfo our_info = { + sizeof (EggToolbarsGroupClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) egg_toolbars_group_class_init, + NULL, + NULL, /* class_data */ + sizeof (EggToolbarsGroup), + 0, /* n_preallocs */ + (GInstanceInitFunc) egg_toolbars_group_init + }; + + egg_toolbars_group_type = g_type_register_static (G_TYPE_OBJECT, + "EggToolbarsGroup", + &our_info, 0); + } + + return egg_toolbars_group_type; + +} + +static xmlDocPtr +egg_toolbars_group_to_xml (EggToolbarsGroup *t) +{ + GNode *l1, *l2, *tl; + xmlDocPtr doc; + + g_return_val_if_fail (IS_EGG_TOOLBARS_GROUP (t), NULL); + + tl = t->priv->toolbars; + + xmlIndentTreeOutput = TRUE; + doc = xmlNewDoc ("1.0"); + doc->children = xmlNewDocNode (doc, NULL, "toolbars", NULL); + + for (l1 = tl->children; l1 != NULL; l1 = l1->next) + { + xmlNodePtr tnode; + + tnode = xmlNewChild (doc->children, NULL, "toolbar", NULL); + + for (l2 = l1->children; l2 != NULL; l2 = l2->next) + { + xmlNodePtr node; + EggToolbarsItem *item = l2->data; + + if (item->separator) + { + node = xmlNewChild (tnode, NULL, "separator", NULL); + } + else + { + node = xmlNewChild (tnode, NULL, "toolitem", NULL); + xmlSetProp (node, "verb", item->action); + } + } + } + + return doc; +} + +static void +toolbars_group_save (EggToolbarsGroup *t) +{ + xmlDocPtr doc; + + g_return_if_fail (IS_EGG_TOOLBARS_GROUP (t)); + + doc = egg_toolbars_group_to_xml (t); + xmlSaveFormatFile (t->priv->user, doc, 1); + xmlFreeDoc (doc); +} + +static EggToolbarsToolbar * +toolbars_toolbar_new (void) +{ + EggToolbarsToolbar *toolbar; + static int id = 0; + + toolbar = g_new0 (EggToolbarsToolbar, 1); + toolbar->id = g_strdup_printf ("Toolbar%d", id); + + id++; + + return toolbar; +} + +static EggToolbarsItem * +toolbars_item_new (const char *action, + gboolean separator) +{ + EggToolbarsItem *item; + static int id = 0; + + g_return_val_if_fail (action != NULL, NULL); + + item = g_new0 (EggToolbarsItem, 1); + item->action = g_strdup (action); + item->separator = separator; + item->id = g_strdup_printf ("TI%d", id); + + id++; + + return item; +} + +static void +free_toolbar_node (EggToolbarsToolbar *toolbar) +{ + g_return_if_fail (toolbar != NULL); + + g_free (toolbar->id); + g_free (toolbar); +} + +static void +free_item_node (EggToolbarsItem *item) +{ + g_return_if_fail (item != NULL); + + g_free (item->action); + g_free (item->id); + g_free (item); +} + +static void +add_action (EggToolbarsGroup *t, + GNode *parent, + int pos, + const char *name) +{ + EggToolbarsItem *item; + GNode *node; + gboolean separator; + + separator = (strcmp (name, "separator") == 0); + item = toolbars_item_new (name, separator); + item->parent = parent->data; + node = g_node_new (item); + + g_node_insert (parent, pos, node); +} + +void +egg_toolbars_group_add_item (EggToolbarsGroup *t, + EggToolbarsToolbar *parent, + int pos, + const char *name) +{ + GNode *parent_node; + + g_return_if_fail (IS_EGG_TOOLBARS_GROUP (t)); + g_return_if_fail (parent != NULL); + g_return_if_fail (name != NULL); + + parent_node = + g_node_find (t->priv->toolbars, G_IN_ORDER, G_TRAVERSE_ALL, parent); + + add_action (t, parent_node, pos, name); + + toolbars_group_save (t); + + g_signal_emit (G_OBJECT (t), egg_toolbars_group_signals[CHANGED], 0); +} + +static void +parse_item_list (EggToolbarsGroup *t, + xmlNodePtr child, + GNode *parent) +{ + while (child) + { + if (xmlStrEqual (child->name, "toolitem")) + { + xmlChar *verb; + + verb = xmlGetProp (child, "verb"); + add_action (t, parent, -1, verb); + + xmlFree (verb); + } + else if (xmlStrEqual (child->name, "separator")) + { + add_action (t, parent, -1, "separator"); + } + + child = child->next; + } +} + +static GNode * +add_toolbar (EggToolbarsGroup *t) +{ + EggToolbarsToolbar *toolbar; + GNode *node; + + toolbar = toolbars_toolbar_new (); + node = g_node_new (toolbar); + g_node_append (t->priv->toolbars, node); + + return node; +} + +EggToolbarsToolbar * +egg_toolbars_group_add_toolbar (EggToolbarsGroup *t) +{ + GNode *node; + + g_return_val_if_fail (IS_EGG_TOOLBARS_GROUP (t), NULL); + + node = add_toolbar (t); + g_return_val_if_fail (node != NULL, NULL); + + toolbars_group_save (t); + + g_signal_emit (G_OBJECT (t), egg_toolbars_group_signals[CHANGED], 0); + + return node->data; +} + +static void +parse_toolbars (EggToolbarsGroup *t, + xmlNodePtr child) +{ + while (child) + { + if (xmlStrEqual (child->name, "toolbar")) + { + GNode *node; + + node = add_toolbar (t); + parse_item_list (t, child->children, node); + } + + child = child->next; + } +} + +static void +load_defaults (EggToolbarsGroup *t) +{ + xmlDocPtr doc; + xmlNodePtr child; + xmlNodePtr root; + const char *xml_filepath; + + g_return_if_fail (IS_EGG_TOOLBARS_GROUP (t)); + + xml_filepath = t->priv->defaults; + + doc = xmlParseFile (xml_filepath); + root = xmlDocGetRootElement (doc); + + child = root->children; + while (child) + { + if (xmlStrEqual (child->name, "available")) + { + t->priv->available_actions = g_node_new (NULL); + parse_item_list (t, child->children, t->priv->available_actions); + } + else if (xmlStrEqual (child->name, "default") && + t->priv->toolbars == NULL) + { + t->priv->toolbars = g_node_new (NULL); + parse_toolbars (t, child->children); + } + + child = child->next; + } + + xmlFreeDoc (doc); +} + +static void +load_toolbar (EggToolbarsGroup *t) +{ + xmlDocPtr doc; + xmlNodePtr root; + const char *xml_filepath = t->priv->user; + + g_return_if_fail (IS_EGG_TOOLBARS_GROUP (t)); + + if (!g_file_test (xml_filepath, G_FILE_TEST_EXISTS)) + return; + + doc = xmlParseFile (xml_filepath); + root = xmlDocGetRootElement (doc); + + t->priv->toolbars = g_node_new (NULL); + parse_toolbars (t, root->children); + + xmlFreeDoc (doc); +} + +char * +egg_toolbars_group_to_string (EggToolbarsGroup *t) +{ + GString *s; + GNode *l1, *l2, *tl; + char *result; + int k = 0; + + g_return_val_if_fail (IS_EGG_TOOLBARS_GROUP (t), NULL); + + tl = t->priv->toolbars; + + g_return_val_if_fail (tl != NULL, NULL); + + s = g_string_new (NULL); + g_string_append (s, "<Root>"); + for (l1 = tl->children; l1 != NULL; l1 = l1->next) + { + int i = 0; + EggToolbarsToolbar *toolbar = l1->data; + + g_string_append_printf (s, "<dockitem name=\"%s\">\n", toolbar->id); + + for (l2 = l1->children; l2 != NULL; l2 = l2->next) + { + EggToolbarsItem *item = l2->data; + + if (item->separator) + { + g_string_append_printf + (s, "<placeholder name=\"PlaceHolder%d-%d\">" + "<separator name=\"%s\"/>" + "</placeholder>\n", i, k, item->id); + } + else + { + g_string_append_printf + (s, "<placeholder name=\"PlaceHolder%d-%d\">" + "<toolitem name=\"%s\" verb=\"%s\"/>" + "</placeholder>\n", i, k, item->id, item->action); + } + i++; + } + + g_string_append (s, "</dockitem>\n"); + + k++; + } + g_string_append (s, "</Root>"); + + result = g_string_free (s, FALSE); + + return result; +} + +static void +egg_toolbars_group_class_init (EggToolbarsGroupClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = egg_toolbars_group_finalize; + + egg_toolbars_group_signals[CHANGED] = + g_signal_new ("changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EggToolbarsGroupClass, changed), + NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + +} + +static void +egg_toolbars_group_init (EggToolbarsGroup *t) +{ + t->priv = g_new0 (EggToolbarsGroupPrivate, 1); + + t->priv->available_actions = NULL; + t->priv->toolbars = NULL; + t->priv->user = NULL; + t->priv->defaults = NULL; +} + +static void +egg_toolbars_group_finalize (GObject *object) +{ + EggToolbarsGroup *t = EGG_TOOLBARS_GROUP (object); + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_EGG_TOOLBARS_GROUP (object)); + + g_node_children_foreach (t->priv->available_actions, G_IN_ORDER, + (GNodeForeachFunc) free_item_node, NULL); + egg_toolbars_group_foreach_toolbar + (t, (EggToolbarsGroupForeachToolbarFunc) free_toolbar_node, NULL); + egg_toolbars_group_foreach_item + (t, (EggToolbarsGroupForeachItemFunc) free_item_node, NULL); + g_node_destroy (t->priv->available_actions); + g_node_destroy (t->priv->toolbars); + + g_free (t->priv->user); + g_free (t->priv->defaults); + + g_free (t->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +EggToolbarsGroup * +egg_toolbars_group_new (void) +{ + EggToolbarsGroup *t; + + t = EGG_TOOLBARS_GROUP (g_object_new (EGG_TOOLBARS_GROUP_TYPE, NULL)); + + g_return_val_if_fail (t->priv != NULL, NULL); + + return t; +} + +void +egg_toolbars_group_remove_toolbar (EggToolbarsGroup *t, + EggToolbarsToolbar *toolbar) +{ + GNode *node; + + g_return_if_fail (IS_EGG_TOOLBARS_GROUP (t)); + g_return_if_fail (toolbar != NULL); + + node = g_node_find (t->priv->toolbars, G_IN_ORDER, G_TRAVERSE_ALL, toolbar); + g_return_if_fail (node != NULL); + free_toolbar_node (node->data); + g_node_destroy (node); + + toolbars_group_save (t); + + g_signal_emit (G_OBJECT (t), egg_toolbars_group_signals[CHANGED], 0); +} + +void +egg_toolbars_group_remove_item (EggToolbarsGroup *t, + EggToolbarsItem *item) +{ + GNode *node; + GNode *toolbar; + + g_return_if_fail (IS_EGG_TOOLBARS_GROUP (t)); + g_return_if_fail (item != NULL); + + node = g_node_find (t->priv->toolbars, G_IN_ORDER, G_TRAVERSE_ALL, item); + g_return_if_fail (node != NULL); + toolbar = node->parent; + free_item_node (node->data); + g_node_destroy (node); + + if (g_node_n_children (toolbar) == 0) + { + free_toolbar_node (toolbar->data); + g_node_destroy (toolbar); + } + + toolbars_group_save (t); + + g_signal_emit (G_OBJECT (t), egg_toolbars_group_signals[CHANGED], 0); +} + +void +egg_toolbars_group_set_source (EggToolbarsGroup *group, + const char *defaults, + const char *user) +{ + g_return_if_fail (IS_EGG_TOOLBARS_GROUP (group)); + g_return_if_fail (defaults != NULL); + + group->priv->defaults = g_strdup (defaults); + group->priv->user = g_strdup (user); + + load_toolbar (group); + load_defaults (group); +} + +static gboolean +is_item_in_toolbars (EggToolbarsGroup *group, + const char *action) +{ + GNode *l1, *l2; + + g_return_val_if_fail (IS_EGG_TOOLBARS_GROUP (group), FALSE); + g_return_val_if_fail (action != NULL, FALSE); + + for (l1 = group->priv->toolbars->children; l1 != NULL; l1 = l1->next) + { + for (l2 = l1->children; l2 != NULL; l2 = l2->next) + { + EggToolbarsItem *item; + + item = (EggToolbarsItem *) l2->data; + if (strcmp (action, item->action) == 0) + return TRUE; + } + } + + return FALSE; +} + +void +egg_toolbars_group_foreach_available (EggToolbarsGroup *group, + EggToolbarsGroupForeachItemFunc func, + gpointer data) +{ + GNode *l1; + + g_return_if_fail (IS_EGG_TOOLBARS_GROUP (group)); + + for (l1 = group->priv->available_actions->children; l1 != NULL; + l1 = l1->next) + { + EggToolbarsItem *item; + + item = (EggToolbarsItem *) l1->data; + + if (!is_item_in_toolbars (group, item->action)) + { + func (item, data); + } + } +} + +void +egg_toolbars_group_foreach_toolbar (EggToolbarsGroup *group, + EggToolbarsGroupForeachToolbarFunc func, + gpointer data) +{ + GNode *l1; + + g_return_if_fail (IS_EGG_TOOLBARS_GROUP (group)); + + for (l1 = group->priv->toolbars->children; l1 != NULL; l1 = l1->next) + { + func (l1->data, data); + } +} + +void +egg_toolbars_group_foreach_item (EggToolbarsGroup *group, + EggToolbarsGroupForeachItemFunc func, + gpointer data) +{ + GNode *l1, *l2; + + g_return_if_fail (IS_EGG_TOOLBARS_GROUP (group)); + + for (l1 = group->priv->toolbars->children; l1 != NULL; l1 = l1->next) + { + for (l2 = l1->children; l2 != NULL; l2 = l2->next) + { + func (l2->data, data); + } + } +} + +char * +egg_toolbars_group_get_path (EggToolbarsGroup *t, + gpointer item) +{ + GNode *node; + char *path = NULL; + EggToolbarsItem *titem; + EggToolbarsToolbar *toolbar; + + g_return_val_if_fail (IS_EGG_TOOLBARS_GROUP (t), NULL); + + node = g_node_find (t->priv->toolbars, G_IN_ORDER, G_TRAVERSE_ALL, item); + g_return_val_if_fail (node != NULL, NULL); + titem = (EggToolbarsItem *) node->data; + toolbar = (EggToolbarsToolbar *) node->data; + + switch (g_node_depth (node)) + { + case 2: + path = g_strdup_printf ("/%s", toolbar->id); + break; + case 3: + path = g_strdup_printf + ("/Toolbar%d/PlaceHolder%d-%d/%s", + g_node_child_position (node->parent->parent, node->parent), + g_node_child_position (node->parent, node), + g_node_child_position (node->parent->parent, node->parent), + titem->id); + break; + default: + g_assert_not_reached (); + } + + return path; +} diff --git a/lib/egg/egg-toolbars-group.h b/lib/egg/egg-toolbars-group.h new file mode 100755 index 000000000..7e278dcf3 --- /dev/null +++ b/lib/egg/egg-toolbars-group.h @@ -0,0 +1,99 @@ +/* + * 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. + */ + +#ifndef EGG_TOOLBARS_GROUP_H +#define EGG_TOOLBARS_GROUP_H + +#include <gtk/gtkwidget.h> +#include <libxml/parser.h> + +G_BEGIN_DECLS + +typedef struct EggToolbarsGroupClass EggToolbarsGroupClass; + +#define EGG_TOOLBARS_GROUP_TYPE (egg_toolbars_group_get_type ()) +#define EGG_TOOLBARS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TOOLBARS_GROUP_TYPE, EggToolbarsGroup)) +#define EGG_TOOLBARS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TOOLBARS_GROUP_TYPE, EggToolbarsGroupClass)) +#define IS_EGG_TOOLBARS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TOOLBARS_GROUP_TYPE)) +#define IS_EGG_TOOLBARS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TOOLBARS_GROUP_TYPE)) +#define EGG_TOOLBARS_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TOOLBARS_GROUP_TYPE, EggToolbarsGroupClass)) + + +typedef struct EggToolbarsGroup EggToolbarsGroup; +typedef struct EggToolbarsGroupPrivate EggToolbarsGroupPrivate; + +typedef struct +{ + char *id; +} EggToolbarsToolbar; + +typedef struct +{ + char *id; + gboolean separator; + char *action; + EggToolbarsToolbar *parent; +} EggToolbarsItem; + +typedef void (*EggToolbarsGroupForeachToolbarFunc) (EggToolbarsToolbar *toolbar, + gpointer data); +typedef void (*EggToolbarsGroupForeachItemFunc) (EggToolbarsItem *item, + gpointer data); + +struct EggToolbarsGroup +{ + GObject parent_object; + EggToolbarsGroupPrivate *priv; +}; + +struct EggToolbarsGroupClass +{ + GObjectClass parent_class; + + void (*changed) (EggToolbarsGroup * group); +}; + +GType egg_toolbars_group_get_type (void); +EggToolbarsGroup *egg_toolbars_group_new (void); +void egg_toolbars_group_set_source (EggToolbarsGroup *group, + const char *defaults, + const char *user); +EggToolbarsToolbar *egg_toolbars_group_add_toolbar (EggToolbarsGroup *t); +void egg_toolbars_group_add_item (EggToolbarsGroup *t, + EggToolbarsToolbar *parent, + int position, + const char *name); +void egg_toolbars_group_remove_toolbar (EggToolbarsGroup *t, + EggToolbarsToolbar *toolbar); +void egg_toolbars_group_remove_item (EggToolbarsGroup *t, + EggToolbarsItem *item); +void egg_toolbars_group_foreach_available (EggToolbarsGroup *group, + EggToolbarsGroupForeachItemFunc func, + gpointer data); +void egg_toolbars_group_foreach_toolbar (EggToolbarsGroup * group, + EggToolbarsGroupForeachToolbarFunc func, + gpointer data); +void egg_toolbars_group_foreach_item (EggToolbarsGroup *group, + EggToolbarsGroupForeachItemFunc func, + gpointer data); +char *egg_toolbars_group_to_string (EggToolbarsGroup *t); +char *egg_toolbars_group_get_path (EggToolbarsGroup *t, + gpointer item); + +G_END_DECLS +#endif diff --git a/lib/egg/eggintl.h b/lib/egg/eggintl.h new file mode 100644 index 000000000..e71ef1ad7 --- /dev/null +++ b/lib/egg/eggintl.h @@ -0,0 +1,6 @@ +#ifndef __EGG_INTL_H__ +#define __EGG_INTL_H__ + +#include <libgnome/gnome-i18n.h> + +#endif /* __EGG_INTL_H__ */ diff --git a/lib/egg/eggtoolbar.c b/lib/egg/eggtoolbar.c index 8d3f058c3..7c1d8c1b5 100644 --- a/lib/egg/eggtoolbar.c +++ b/lib/egg/eggtoolbar.c @@ -1311,6 +1311,7 @@ egg_toolbar_drag_motion (GtkWidget *widget, EggToolbar *toolbar = EGG_TOOLBAR (widget); EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); gint new_index, new_pos; + find_drop_pos(toolbar, x, y, &new_index, &new_pos); if (!priv->drag_highlight) diff --git a/lib/egg/eggtoolbutton.c b/lib/egg/eggtoolbutton.c index ad3c5b5db..4ff471729 100644 --- a/lib/egg/eggtoolbutton.c +++ b/lib/egg/eggtoolbutton.c @@ -82,7 +82,7 @@ static GObjectClass *parent_class = NULL; GType egg_tool_button_get_type (void) { - static GType type = 0; + static GtkType type = 0; if (!type) { diff --git a/lib/egg/update-from-egg.sh b/lib/egg/update-from-egg.sh new file mode 100755 index 000000000..b2e74bb7a --- /dev/null +++ b/lib/egg/update-from-egg.sh @@ -0,0 +1,40 @@ +#!/bin/sh + +function die() { + echo $* + exit 1 +} + +if test -z "$EGGDIR"; then + echo "Must set EGGDIR" + exit 1 +fi + +if test -z "$EGGFILES"; then + echo "Must set EGGFILES" + exit 1 +fi + +for FILE in $EGGFILES; do + SRCFILE=$EGGDIR/$FILE + if ! test -e $SRCFILE ; then + if test -e $EGGDIR/toolbar/$FILE ; then + SRCFILE=$EGGDIR/toolbar/$FILE + fi + if test -e $EGGDIR/menu/$FILE ; then + SRCFILE=$EGGDIR/menu/$FILE + fi + if test -e $EGGDIR/toolbareditor/$FILE ; then + SRCFILE=$EGGDIR/toolbareditor/$FILE + fi + if test -e $EGGDIR/util/$FILE ; then + SRCFILE=$EGGDIR/util/$FILE + fi + fi + if cmp -s $SRCFILE $FILE; then + echo "File $FILE is unchanged" + else + cp $SRCFILE $FILE || die "Could not move $SRCFILE to $FILE" + echo "Updated $FILE" + fi +done |