diff options
Diffstat (limited to 'lib/egg/egg-editable-toolbar.c')
-rwxr-xr-x | lib/egg/egg-editable-toolbar.c | 1169 |
1 files changed, 244 insertions, 925 deletions
diff --git a/lib/egg/egg-editable-toolbar.c b/lib/egg/egg-editable-toolbar.c index 73528b96d..5220629a5 100755 --- a/lib/egg/egg-editable-toolbar.c +++ b/lib/egg/egg-editable-toolbar.c @@ -17,54 +17,32 @@ */ #include "egg-editable-toolbar.h" -#include "egg-toolbars-group.h" -#include "eggtoolitem.h" +#include "egg-toolbars-model.h" #include "eggtoolbar.h" +#include "eggtoolitem.h" #include "eggseparatortoolitem.h" #include "eggintl.h" #include <string.h> -#define EGG_TOOLBAR_ITEM_TYPE "application/x-toolbar-item" - -enum -{ - X_TOOLBAR_ITEM -}; - -static GtkTargetEntry dest_drag_types[] = { - {EGG_TOOLBAR_ITEM_TYPE, 0, X_TOOLBAR_ITEM}, -}; - -static int n_dest_drag_types = G_N_ELEMENTS (dest_drag_types); +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 GtkTargetEntry source_drag_types[] = { - {EGG_TOOLBAR_ITEM_TYPE, 0, X_TOOLBAR_ITEM}, + {EGG_TOOLBAR_ITEM_TYPE, 0, 0}, }; - static int n_source_drag_types = G_N_ELEMENTS (source_drag_types); -enum -{ - RESPONSE_ADD_TOOLBAR +static GtkTargetEntry dest_drag_types[] = { + {EGG_TOOLBAR_ITEM_TYPE, 0, 0}, }; - -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 int n_dest_drag_types = G_N_ELEMENTS (dest_drag_types); enum { PROP_0, - PROP_TOOLBARS_GROUP, + PROP_TOOLBARS_MODEL, PROP_MENU_MERGE }; @@ -73,32 +51,10 @@ 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; + EggToolbarsModel *model; gboolean edit_mode; - - EggToolbarsGroup *group; - - GList *actions_list; - - GList *drag_types; }; -typedef struct -{ - EggEditableToolbar *etoolbar; - EggToolbarsToolbar *t; -} ContextMenuData; - GType egg_editable_toolbar_get_type (void) { @@ -118,7 +74,7 @@ egg_editable_toolbar_get_type (void) (GInstanceInitFunc) egg_editable_toolbar_init }; - egg_editable_toolbar_type = g_type_register_static (G_TYPE_OBJECT, + egg_editable_toolbar_type = g_type_register_static (GTK_TYPE_VBOX, "EggEditableToolbar", &our_info, 0); } @@ -126,77 +82,66 @@ egg_editable_toolbar_get_type (void) return egg_editable_toolbar_type; } -static EggAction * -find_action (EggEditableToolbar *t, - const char *name) +static int +get_toolbar_position (EggEditableToolbar *etoolbar, GtkWidget *toolbar) { - 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; + GList *l; + int result; - tmp = egg_action_group_get_action (EGG_ACTION_GROUP (l->data), name); - if (tmp) - action = tmp; - } + l = gtk_container_get_children (GTK_CONTAINER (etoolbar)); + result = g_list_index (l, toolbar); + g_list_free (l); - return action; + return result; } -static char * -impl_get_action_name (EggEditableToolbar *etoolbar, - const char *drag_type, - const char *data) +static int +get_n_toolbars (EggEditableToolbar *etoolbar) { - return NULL; + GList *l; + int result; + + l = gtk_container_get_children (GTK_CONTAINER (etoolbar)); + result = g_list_length (l); + g_list_free (l); + + return result; } -static EggAction * -impl_get_action (EggEditableToolbar *etoolbar, - const char *name) +static GtkWidget * +get_toolbar_nth (EggEditableToolbar *etoolbar, + int position) { - EggAction *action; - - g_return_val_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar), NULL); + GList *l; + GtkWidget *result; - action = find_action (etoolbar, name); + l = gtk_container_get_children (GTK_CONTAINER (etoolbar)); + result = g_list_nth_data (l, position); + g_list_free (l); - return action; + return result; } -static gboolean -ui_update (gpointer data) +static EggAction * +find_action (EggEditableToolbar *t, + const char *name) { - EggEditableToolbar *etoolbar = EGG_EDITABLE_TOOLBAR (data); + GList *l = t->priv->merge->action_groups; + EggAction *action = NULL; - g_return_val_if_fail (etoolbar != NULL, FALSE); + g_return_val_if_fail (IS_EGG_EDITABLE_TOOLBAR (t), NULL); + g_return_val_if_fail (name != NULL, NULL); - if (etoolbar->priv->toolbars_dirty) + for (; l != NULL; l = l->next) { - do_merge (etoolbar); - etoolbar->priv->toolbars_dirty = FALSE; - } + EggAction *tmp; - if (etoolbar->priv->editor_sheet_dirty) - { - update_editor_sheet (etoolbar); - etoolbar->priv->editor_sheet_dirty = FALSE; + tmp = egg_action_group_get_action (EGG_ACTION_GROUP (l->data), name); + if (tmp) + action = tmp; } - return FALSE; -} - -static void -queue_ui_update (EggEditableToolbar *etoolbar) -{ - g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar)); - - g_idle_add (ui_update, etoolbar); + return action; } static void @@ -209,67 +154,27 @@ drag_data_received_cb (GtkWidget *widget, guint time_, EggEditableToolbar *etoolbar) { - EggToolbarsToolbar *toolbar; - const char *type = NULL; - EggAction *action = NULL; - int pos; - GdkAtom target; - GList *l; + int pos, toolbar_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); + toolbar_pos = get_toolbar_position (etoolbar, widget); - /* HACK placeholder are implemented as separators */ - pos = pos / 3 + 1; - - target = gtk_drag_dest_find_target (widget, context, NULL); - - for (l = etoolbar->priv->drag_types; l != NULL; l = l->next) - { - char *drag_type = (char *)l->data; - - if (gdk_atom_intern (drag_type, FALSE) == target) - { - type = drag_type; - } - } - - if (strcmp (type, EGG_TOOLBAR_ITEM_TYPE) != 0) + if (strcmp (selection_data->data, "separator") == 0) { - 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); - } + egg_toolbars_model_add_separator (etoolbar->priv->model, + toolbar_pos, pos); } else { - action = - egg_editable_toolbar_get_action (etoolbar, selection_data->data); - } + GdkAtom target; - if (action) - { - egg_toolbars_group_add_item (etoolbar->priv->group, toolbar, pos, - action->name); - etoolbar->priv->toolbars_dirty = TRUE; + target = gtk_drag_dest_find_target (widget, context, NULL); + egg_toolbars_model_add_item (etoolbar->priv->model, + toolbar_pos, pos, target, + selection_data->data); } - 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 @@ -277,17 +182,16 @@ drag_data_delete_cb (GtkWidget *widget, GdkDragContext *context, EggEditableToolbar *etoolbar) { - EggToolbarsItem *node; + int pos, toolbar_pos; 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); + pos = egg_toolbar_get_item_index (EGG_TOOLBAR (widget->parent), + EGG_TOOL_ITEM (widget)); + toolbar_pos = get_toolbar_position (etoolbar, widget->parent); - etoolbar->priv->toolbars_dirty = TRUE; - queue_ui_update (etoolbar); + egg_toolbars_model_remove_item (etoolbar->priv->model, + toolbar_pos, pos); } static void @@ -319,412 +223,206 @@ drag_data_get_cb (GtkWidget *widget, } 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) +remove_toolbar_cb (GtkWidget *toolbar, + 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; + int pos; - gtk_selection_data_set (selection_data, - selection_data->target, 8, target, strlen (target)); + pos = get_toolbar_position (etoolbar, toolbar); + egg_toolbars_model_remove_toolbar (etoolbar->priv->model, pos); } static void -egg_editable_toolbar_remove_cb (EggAction *action, - EggEditableToolbar *etoolbar) +popup_toolbar_context_menu_cb (GtkWidget *toolbar, + EggEditableToolbar *t) { - EggToolbarsToolbar *t; + GtkWidget *menu; + GtkWidget *item; + GtkWidget *image; - t = g_object_get_data (G_OBJECT (etoolbar), "popup_toolbar"); + menu = gtk_menu_new (); - egg_toolbars_group_remove_toolbar (etoolbar->priv->group, t); -} + item = gtk_image_menu_item_new_with_mnemonic (_("_Remove Toolbar")); + gtk_widget_show (item); + image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU); + gtk_widget_show (image); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + g_signal_connect (item, "activate", + G_CALLBACK (remove_toolbar_cb), + t); -static void -egg_editable_toolbar_edit_cb (EggAction *action, - EggEditableToolbar *etoolbar) -{ - egg_editable_toolbar_edit (etoolbar, NULL); + gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 2, + gtk_get_current_event_time ()); } static GtkWidget * -get_item_widget (EggEditableToolbar *t, - gpointer data) +create_toolbar (EggEditableToolbar *t) { - GtkWidget *widget; - char *path; - - path = egg_toolbars_group_get_path (t->priv->group, data); - g_return_val_if_fail (path != NULL, NULL); + GtkWidget *toolbar; - widget = egg_menu_merge_get_widget (t->priv->merge, path); - g_free (path); + toolbar = egg_toolbar_new (); + gtk_widget_show (toolbar); + gtk_drag_dest_set (toolbar, GTK_DEST_DEFAULT_DROP, + dest_drag_types, n_dest_drag_types, + GDK_ACTION_MOVE | GDK_ACTION_COPY); + g_signal_connect (toolbar, "drag_data_received", + G_CALLBACK (drag_data_received_cb), t); + g_signal_connect (toolbar, "popup_context_menu", + G_CALLBACK (popup_toolbar_context_menu_cb), t); - return widget; + return toolbar; } -static void -connect_item_drag_source (EggToolbarsItem *item, - EggEditableToolbar *etoolbar) +static GtkWidget * +create_item (EggEditableToolbar *t, + EggToolbarsModel *model, + int toolbar_position, + int position) { - GtkWidget *toolitem; - - g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar)); - g_return_if_fail (item != NULL); + GtkWidget *item; + EggAction *action; + const char *action_name; + gboolean is_separator; - toolitem = get_item_widget (etoolbar, item); + action_name = egg_toolbars_model_item_nth + (model, toolbar_position, position, + &is_separator); - if (!g_object_get_data (G_OBJECT (toolitem), "drag_source_set")) + if (is_separator) { - 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); + item = GTK_WIDGET (egg_separator_tool_item_new ()); } -} - -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")) + else { - 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); - - gtk_drag_source_unset (toolitem); - - 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); + action = find_action (t, action_name); + item = egg_action_create_tool_item (action); } -} - -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); + gtk_widget_show (item); + gtk_drag_source_set (item, GDK_BUTTON1_MASK, + source_drag_types, n_source_drag_types, + GDK_ACTION_MOVE); + g_signal_connect (item, "drag_data_get", + G_CALLBACK (drag_data_get_cb), t); + g_signal_connect (item, "drag_data_delete", + G_CALLBACK (drag_data_delete_cb), t); - tb = get_item_widget (etoolbar, t); - - g_return_if_fail (tb != NULL); - - if (!g_object_get_data (G_OBJECT (tb), "drag_source_set")) + if (t->priv->edit_mode) { - 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); - - gtk_drag_source_set (tb, GDK_BUTTON1_MASK, - source_drag_types, n_source_drag_types, - GDK_ACTION_MOVE); - - 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); + egg_tool_item_set_use_drag_window (EGG_TOOL_ITEM (item), TRUE); } + + return item; } static void -disconnect_toolbar_drag_source (EggToolbarsToolbar *t, - EggEditableToolbar *etoolbar) +toolbar_added_cb (EggToolbarsModel *model, + int position, + EggEditableToolbar *t) { - GtkWidget *tb; - - g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar)); - g_return_if_fail (t != NULL); + GtkWidget *toolbar; - tb = get_item_widget (etoolbar, t); + toolbar = create_toolbar (t); + gtk_widget_set_size_request (toolbar, -1, 20); + gtk_box_pack_start (GTK_BOX (t), toolbar, FALSE, FALSE, 0); - 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)); - - gtk_drag_source_unset (tb); - - 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); - } + /* FIXME reorder to match position */ } static void -popup_toolbar_context_menu (EggToolbar *toolbar, - ContextMenuData *data) +toolbar_removed_cb (EggToolbarsModel *model, + int position, + EggEditableToolbar *t) { - GtkWidget *menu; - GtkWidget *item; - GtkWidget *image; - EggEditableToolbar *etoolbar = EGG_EDITABLE_TOOLBAR (data->etoolbar); - - menu = gtk_menu_new (); - - if (etoolbar->priv->edit_mode) - { - item = gtk_image_menu_item_new_with_mnemonic (_("_Remove Toolbar")); - gtk_widget_show (item); - image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU); - gtk_widget_show (image); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_object_set_data (G_OBJECT (etoolbar), "popup_toolbar", data->t); - g_signal_connect (item, "activate", - G_CALLBACK (egg_editable_toolbar_remove_cb), - etoolbar); - } - else - { - item = gtk_image_menu_item_new_with_mnemonic (_("_Edit Toolbars...")); - gtk_widget_show (item); - image = gtk_image_new_from_stock (GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU); - gtk_widget_show (image); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_signal_connect (item, "activate", - G_CALLBACK (egg_editable_toolbar_edit_cb), - etoolbar); - } + GtkWidget *toolbar; - gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 2, - gtk_get_current_event_time ()); + toolbar = get_toolbar_nth (t, position); + gtk_widget_destroy (toolbar); } -static GtkTargetList * -get_dest_targets (EggEditableToolbar *etoolbar) +static void +item_added_cb (EggToolbarsModel *model, + int toolbar_position, + int position, + EggEditableToolbar *t) { - GList *l; - GtkTargetList *targets; - int i = 0; - - targets = gtk_target_list_new (NULL, 0); - - for (l = etoolbar->priv->drag_types; l != NULL; l = l->next) - { - char *type = (char *)l->data; - gtk_target_list_add (targets, gdk_atom_intern (type, FALSE), 0, i); - i++; - } + GtkWidget *toolbar; + GtkWidget *item; - return targets; + toolbar = get_toolbar_nth (t, toolbar_position); + gtk_widget_set_size_request (toolbar, -1, -1); + item = create_item (t, model, toolbar_position, position); + egg_toolbar_insert (EGG_TOOLBAR (toolbar), + EGG_TOOL_ITEM (item), position); } static void -setup_toolbar (EggToolbarsToolbar *toolbar, - EggEditableToolbar *etoolbar) +item_removed_cb (EggToolbarsModel *model, + int toolbar_position, + int position, + EggEditableToolbar *t) { - 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")) - { - GtkTargetList *targets; - - g_object_set_data (G_OBJECT (widget), "drag_dest_set", - GINT_TO_POINTER (TRUE)); - gtk_drag_dest_set (widget, GTK_DEST_DEFAULT_ALL, - NULL, 0, - GDK_ACTION_MOVE | GDK_ACTION_COPY); - targets = get_dest_targets (etoolbar); - gtk_drag_dest_set_target_list (widget, targets); - gtk_target_list_unref (targets); - g_signal_connect (widget, "drag_data_received", - G_CALLBACK (drag_data_received_cb), etoolbar); - } + GtkWidget *toolbar; + GtkWidget *item; - 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)); - } + toolbar = get_toolbar_nth (t, toolbar_position); + item = GTK_WIDGET (egg_toolbar_get_nth_item + (EGG_TOOLBAR (toolbar), position)); + gtk_container_remove (GTK_CONTAINER (toolbar), item); - etoolbar->priv->last_toolbar = widget; + if (egg_toolbars_model_n_items (model, toolbar_position) == 0) + { + egg_toolbars_model_remove_toolbar (model, toolbar_position); + } } static void -ensure_toolbar_min_size (EggToolbarsToolbar *toolbar, - EggEditableToolbar *t) +egg_editable_toolbar_set_model (EggEditableToolbar *t, + EggToolbarsModel *model) { - GtkWidget *widget; - + g_return_if_fail (IS_EGG_TOOLBARS_MODEL (model)); g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (t)); - g_return_if_fail (toolbar != NULL); - widget = get_item_widget (t, toolbar); + t->priv->model = model; - if (EGG_TOOLBAR (widget)->num_children == 0) - { - gtk_widget_set_size_request (widget, -1, 20); - } - else - { - gtk_widget_set_size_request (widget, -1, -1); - } + g_signal_connect_object (model, "item_added", + G_CALLBACK (item_added_cb), t, 0); + g_signal_connect_object (model, "item_removed", + G_CALLBACK (item_removed_cb), t, 0); + g_signal_connect_object (model, "toolbar_added", + G_CALLBACK (toolbar_added_cb), t, 0); + g_signal_connect_object (model, "toolbar_removed", + G_CALLBACK (toolbar_removed_cb), t, 0); } static void -do_merge (EggEditableToolbar *t) +egg_editable_toolbar_construct (EggEditableToolbar *t) { - char *str; - guint ui_id; - - g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (t)); + int i, l, n_items, n_toolbars; + EggToolbarsModel *model = t->priv->model; - str = egg_toolbars_group_to_string (t->priv->group); - g_return_if_fail (str != NULL); + g_return_if_fail (model != NULL); - ui_id = egg_menu_merge_add_ui_from_string (t->priv->merge, str, -1, NULL); + n_toolbars = egg_toolbars_model_n_toolbars (model); - if (t->priv->ui_id != 0) + for (i = 0; i < n_toolbars; i++) { - 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); + GtkWidget *toolbar; - egg_toolbars_group_foreach_toolbar (t->priv->group, - (EggToolbarsGroupForeachToolbarFunc) - setup_toolbar, t); + toolbar = create_toolbar (t); + gtk_box_pack_start (GTK_BOX (t), toolbar, FALSE, FALSE, 0); - if (t->priv->edit_mode) - { - egg_toolbars_group_foreach_item (t->priv->group, - (EggToolbarsGroupForeachItemFunc) - connect_item_drag_source, t); + n_items = egg_toolbars_model_n_items (model, i); + for (l = 0; l < n_items; l++) + { + GtkWidget *item; - egg_toolbars_group_foreach_toolbar (t->priv->group, - (EggToolbarsGroupForeachToolbarFunc) - connect_toolbar_drag_source, t); + item = create_item (t, model, i, l); + egg_toolbar_insert (EGG_TOOLBAR (toolbar), + EGG_TOOL_ITEM (item), l); + } } - - 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 @@ -736,11 +434,7 @@ egg_editable_toolbar_set_merge (EggEditableToolbar *t, t->priv->merge = merge; - egg_toolbars_group_foreach_item (t->priv->group, - (EggToolbarsGroupForeachItemFunc) - ensure_action, t); - - do_merge (t); + egg_editable_toolbar_construct (t); } static void @@ -756,8 +450,8 @@ egg_editable_toolbar_set_property (GObject *object, 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)); + case PROP_TOOLBARS_MODEL: + egg_editable_toolbar_set_model (t, g_value_get_object (value)); break; } } @@ -775,8 +469,8 @@ egg_editable_toolbar_get_property (GObject *object, 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); + case PROP_TOOLBARS_MODEL: + g_value_set_object (value, t->priv->model); break; } } @@ -792,9 +486,6 @@ egg_editable_toolbar_class_init (EggEditableToolbarClass *klass) 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", @@ -803,11 +494,11 @@ egg_editable_toolbar_class_init (EggEditableToolbarClass *klass) 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, + PROP_TOOLBARS_MODEL, + g_param_spec_object ("ToolbarsModel", + "ToolbarsModel", + "Toolbars Model", + EGG_TOOLBARS_MODEL_TYPE, G_PARAM_READWRITE)); } @@ -817,15 +508,7 @@ egg_editable_toolbar_init (EggEditableToolbar *t) 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; - t->priv->drag_types = NULL; - - egg_editable_toolbar_add_drag_type (t, EGG_TOOLBAR_ITEM_TYPE); } static void @@ -836,433 +519,69 @@ egg_editable_toolbar_finalize (GObject *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); - } - - if (t->priv->drag_types) - { - g_list_foreach (t->priv->drag_types, (GFunc)g_free, NULL); - g_list_free (t->priv->drag_types); - } - g_free (t->priv); G_OBJECT_CLASS (parent_class)->finalize (object); } -EggEditableToolbar * +GtkWidget * egg_editable_toolbar_new (EggMenuMerge *merge, - EggToolbarsGroup *group) + EggToolbarsModel *model) { EggEditableToolbar *t; t = EGG_EDITABLE_TOOLBAR (g_object_new (EGG_EDITABLE_TOOLBAR_TYPE, - "ToolbarsGroup", group, + "ToolbarsModel", model, "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); + return GTK_WIDGET (t); } -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); - hide_editor (etoolbar); -} - -static void -editor_add_toolbar (EggEditableToolbar *etoolbar) +void +egg_editable_toolbar_set_edit_mode (EggEditableToolbar *etoolbar, + gboolean mode) { - g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar)); + int i, l, n_toolbars, n_items; - egg_toolbars_group_add_toolbar (etoolbar->priv->group); + etoolbar->priv->edit_mode = mode; - etoolbar->priv->toolbars_dirty = TRUE; - queue_ui_update (etoolbar); -} - -static void -dialog_response_cb (GtkDialog *dialog, - gint response_id, - EggEditableToolbar *etoolbar) -{ - switch (response_id) + n_toolbars = get_n_toolbars (etoolbar); + for (i = 0; i < n_toolbars; i++) { - case RESPONSE_ADD_TOOLBAR: - editor_add_toolbar (etoolbar); - break; - case GTK_RESPONSE_CLOSE: - editor_close (etoolbar); - break; - } -} + GtkWidget *toolbar; -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 a New 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); -} + toolbar = get_toolbar_nth (etoolbar, i); + n_items = egg_toolbar_get_n_items (EGG_TOOLBAR (toolbar)); + for (l = 0; l < n_items; l++) + { + EggToolItem *item; -static gchar * -elide_underscores (const gchar *original) -{ - gchar *q, *result; - const gchar *p; - gboolean last_underscore; - - q = result = g_malloc (strlen (original) + 1); - last_underscore = FALSE; - - for (p = original; *p; p++) - { - if (!last_underscore && *p == '_') - last_underscore = TRUE; - else - { - last_underscore = FALSE; - *q++ = *p; - } + item = egg_toolbar_get_nth_item (EGG_TOOLBAR (toolbar), l); + egg_tool_item_set_use_drag_window (item, mode); + } } - - *q = '\0'; - - return result; } -static GtkWidget * -editor_create_item (EggEditableToolbar *etoolbar, - const char *stock_id, - const char *label_text, - GdkDragAction action) +void +egg_editable_toolbar_show (EggEditableToolbar *etoolbar, + const char *name) { - GtkWidget *event_box; - GtkWidget *vbox; - GtkWidget *icon; - GtkWidget *label; - gchar *label_no_mnemonic = 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, action); - 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); - - vbox = gtk_vbox_new (0, FALSE); - gtk_widget_show (vbox); - gtk_container_add (GTK_CONTAINER (event_box), vbox); - - icon = gtk_image_new_from_stock - (stock_id ? 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_no_mnemonic = elide_underscores (label_text); - label = gtk_label_new (label_no_mnemonic); - g_free (label_no_mnemonic); - gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0); - - return event_box; -} + int i, n_toolbars; + EggToolbarsModel *model = etoolbar->priv->model; -static void -update_editor_sheet (EggEditableToolbar *etoolbar) -{ - GList *l; - GList *to_drag = NULL; - int x, y, height, width; - GtkWidget *table; - GtkWidget *viewport; - GtkWidget *item; - - g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar)); + g_return_if_fail (model != NULL); - viewport = GTK_BIN (etoolbar->priv->scrolled_window)->child; - if (viewport) + n_toolbars = egg_toolbars_model_n_toolbars (model); + for (i = 0; i < n_toolbars; i++) { - 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) - { - EggToolbarsItem *node = (EggToolbarsItem *) (l->data); - EggAction *action; - - action = egg_editable_toolbar_get_action (etoolbar, node->action); - g_return_if_fail (action != NULL); - - item = editor_create_item (etoolbar, action->stock_id, - action->short_label, GDK_ACTION_MOVE); - g_object_set_data (G_OBJECT (item), "egg-action", action); - gtk_table_attach_defaults (GTK_TABLE (etoolbar->priv->table), - item, x, x + 1, y, y + 1); - - x++; - if (x >= width) - { - x = 0; - y++; - } - } - - item = editor_create_item (etoolbar, NULL, _("Separator"), - GDK_ACTION_COPY); - gtk_table_attach_defaults (GTK_TABLE (etoolbar->priv->table), - item, x, x + 1, y, y + 1); - - g_list_free (to_drag); -} - -static void -show_editor (EggEditableToolbar *etoolbar) -{ - GtkWidget *editor = etoolbar->priv->editor; + const char *toolbar_name; - 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); + toolbar_name = egg_toolbars_model_toolbar_nth (model, i); + if (strcmp (toolbar_name, name) == 0) + { + gtk_widget_show (get_toolbar_nth (etoolbar, i)); + } } } - -static void -hide_toolbar (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); - - gtk_widget_hide (tb); -} - -static void -show_toolbar (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); - - gtk_widget_show (tb); -} - -void -egg_editable_toolbar_show (EggEditableToolbar *etoolbar) -{ - g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar)); - - egg_toolbars_group_foreach_toolbar (etoolbar->priv->group, - (EggToolbarsGroupForeachToolbarFunc) - show_toolbar, etoolbar); -} - -void -egg_editable_toolbar_hide (EggEditableToolbar *etoolbar) -{ - g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar)); - - egg_toolbars_group_foreach_toolbar (etoolbar->priv->group, - (EggToolbarsGroupForeachToolbarFunc) - hide_toolbar, etoolbar); -} - -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); - - setup_editor (etoolbar, window); - show_editor (etoolbar); -} - -void -egg_editable_toolbar_add_drag_type (EggEditableToolbar *etoolbar, - const char *drag_type) -{ - etoolbar->priv->drag_types = g_list_append - (etoolbar->priv->drag_types, g_strdup (drag_type)); -} - -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); -} |