diff options
-rwxr-xr-x | lib/egg/egg-editable-toolbar.c | 378 |
1 files changed, 124 insertions, 254 deletions
diff --git a/lib/egg/egg-editable-toolbar.c b/lib/egg/egg-editable-toolbar.c index f2aeb983f..d52da9915 100755 --- a/lib/egg/egg-editable-toolbar.c +++ b/lib/egg/egg-editable-toolbar.c @@ -52,7 +52,6 @@ static void egg_editable_toolbar_finalize (GObject *object); #define MIN_TOOLBAR_HEIGHT 20 #define EGG_ITEM_NAME "egg-item-name" -#define EGG_TOOLITEM "egg-toolitem" static const GtkTargetEntry dest_drag_types[] = { {EGG_TOOLBAR_ITEM_TYPE, GTK_TARGET_SAME_APP, 0}, @@ -62,7 +61,8 @@ enum { PROP_0, PROP_TOOLBARS_MODEL, - PROP_UI_MANAGER + PROP_UI_MANAGER, + PROP_SELECTED }; enum @@ -84,6 +84,9 @@ struct _EggEditableToolbarPrivate guint edit_mode; gboolean save_hidden; GtkWidget *fixed_toolbar; + + GtkWidget *selected; + guint popup; guint dnd_pending; GtkToolbar *dnd_toolbar; @@ -228,8 +231,6 @@ drag_begin_cb (GtkWidget *widget, GdkDragContext *context, EggEditableToolbar *etoolbar) { - widget = gtk_widget_get_ancestor (widget, GTK_TYPE_TOOL_ITEM); - g_return_if_fail (widget != NULL); gtk_widget_hide (widget); } @@ -238,8 +239,6 @@ drag_end_cb (GtkWidget *widget, GdkDragContext *context, EggEditableToolbar *etoolbar) { - widget = gtk_widget_get_ancestor (widget, GTK_TYPE_TOOL_ITEM); - g_return_if_fail (widget != NULL); gtk_widget_show (widget); } @@ -255,9 +254,6 @@ drag_data_get_cb (GtkWidget *widget, const char *name; char *data; - widget = gtk_widget_get_ancestor (widget, GTK_TYPE_TOOL_ITEM); - g_return_if_fail (widget != NULL); - g_return_if_fail (EGG_IS_EDITABLE_TOOLBAR (etoolbar)); model = egg_editable_toolbar_get_model (etoolbar); @@ -277,16 +273,6 @@ drag_data_get_cb (GtkWidget *widget, } static void -move_item_cb (GtkWidget *menuitem, - EggEditableToolbar *etoolbar) -{ - GtkWidget *toolitem = g_object_get_data (G_OBJECT (menuitem), EGG_TOOLITEM); - GtkTargetList *list = gtk_target_list_new (dest_drag_types, G_N_ELEMENTS (dest_drag_types)); - gtk_drag_begin (toolitem, list, GDK_ACTION_MOVE, 1, NULL); - gtk_target_list_unref (list); -} - -static void set_dock_visible (EggEditableToolbar *etoolbar, GtkWidget *dock, gboolean visible) @@ -320,15 +306,37 @@ set_dock_visible (EggEditableToolbar *etoolbar, } static void -remove_item_cb (GtkWidget *menuitem, +move_item_cb (GtkAction *action, + EggEditableToolbar *etoolbar) +{ + GtkWidget *toolitem = gtk_widget_get_ancestor (egg_editable_toolbar_get_selected (etoolbar), GTK_TYPE_TOOL_ITEM); + GtkTargetList *list = gtk_target_list_new (dest_drag_types, G_N_ELEMENTS (dest_drag_types)); + + GdkEvent *realevent = gtk_get_current_event(); + GdkEventMotion event; + event.type = GDK_MOTION_NOTIFY; + event.window = realevent->any.window; + event.send_event = FALSE; + event.axes = NULL; + event.time = gdk_event_get_time (realevent); + gdk_event_get_state (realevent, &event.state); + gdk_event_get_coords (realevent, &event.x, &event.y); + gdk_event_get_root_coords (realevent, &event.x_root, &event.y_root); + + gtk_drag_begin (toolitem, list, GDK_ACTION_MOVE, 1, (GdkEvent *)&event); + gtk_target_list_unref (list); +} + +static void +remove_item_cb (GtkAction *action, EggEditableToolbar *etoolbar) { - GtkWidget *toolitem = g_object_get_data (G_OBJECT (menuitem), EGG_TOOLITEM); + GtkWidget *toolitem = gtk_widget_get_ancestor (egg_editable_toolbar_get_selected (etoolbar), GTK_TYPE_TOOL_ITEM); int pos, toolbar_pos; toolbar_pos = get_toolbar_position (etoolbar, toolitem->parent); - pos = gtk_toolbar_get_item_index (GTK_TOOLBAR (toolitem->parent), - GTK_TOOL_ITEM (toolitem)); + pos = gtk_toolbar_get_item_index (GTK_TOOLBAR (toolitem->parent), + GTK_TOOL_ITEM (toolitem)); egg_toolbars_model_remove_item (etoolbar->priv->model, toolbar_pos, pos); @@ -340,10 +348,11 @@ remove_item_cb (GtkWidget *menuitem, } static void -remove_toolbar_cb (GtkWidget *menuitem, +remove_toolbar_cb (GtkAction *action, EggEditableToolbar *etoolbar) { - GtkWidget *toolbar = g_object_get_data (G_OBJECT (menuitem), "egg-toolbar"); + GtkWidget *selected = egg_editable_toolbar_get_selected (etoolbar); + GtkWidget *toolbar = gtk_widget_get_ancestor (selected, GTK_TYPE_TOOLBAR); int toolbar_pos; toolbar_pos = get_toolbar_position (etoolbar, toolbar); @@ -351,205 +360,20 @@ remove_toolbar_cb (GtkWidget *menuitem, } static void -toggle_visibility_cb (GtkWidget *menuitem, - EggEditableToolbar *etoolbar) -{ - GtkWidget *dock = g_object_get_data (G_OBJECT (menuitem), "egg-dock"); - set_dock_visible (etoolbar, dock, !GTK_WIDGET_VISIBLE (dock)); -} - -static void -egg_editable_toolbar_add_visibility_items (EggEditableToolbar *etoolbar, - GtkMenu *popup) -{ - EggToolbarsModel *model = etoolbar->priv->model; - GtkCheckMenuItem *item; - GtkWidget *dock; - int n_toolbars, n_items, n_visible = 0; - int i, j, k, l; - - g_return_if_fail (model != NULL); - g_return_if_fail (etoolbar->priv->manager != NULL); - - n_toolbars = egg_toolbars_model_n_toolbars (model); - - for (i = 0; i < n_toolbars; i++) - { - dock = get_dock_nth (etoolbar, i); - if (GTK_WIDGET_VISIBLE (dock)) - n_visible++; - } - - if (GTK_MENU_SHELL(popup)->children != NULL) - { - GtkWidget *separator = gtk_separator_menu_item_new (); - gtk_widget_show (separator); - gtk_menu_shell_append (GTK_MENU_SHELL (popup), separator); - } - - for (i = 0; i < n_toolbars; i++) - { - char buffer[40] = "Empty"; - - n_items = egg_toolbars_model_n_items (model, i); - for (k = 0, j = 0; j < n_items && k < sizeof(buffer)-1; j++) - { - GValue value = { 0, }; - GtkAction *action; - const char *name; - - name = egg_toolbars_model_item_nth (model, i, j); - if (name == NULL) continue; - action = find_action (etoolbar, name); - if (action == NULL) continue; - - g_value_init (&value, G_TYPE_STRING); - g_object_get_property (G_OBJECT (action), "label", &value); - name = g_value_get_string (&value); - if (name == NULL) continue; - - if (j > 0) - { - if(k<sizeof(buffer)-1) buffer[k++] = ','; - if(k<sizeof(buffer)-1) buffer[k++] = ' '; - } - - for (l = 0; name[l] && k<sizeof(buffer)-1; l++) - { - switch(name[l]) - { - case '_': - case '.': - case ',': - break; - default: - buffer[k++] = name[l]; - } - } - - if (name[l]) - { - l = k-5; - while(l>0 && buffer[l] != ',') l--; - if(buffer[l] == ',') k = l + 2; - else k = k-3; - - buffer[k++] = '.'; - buffer[k++] = '.'; - buffer[k++] = '.'; - buffer[k] = 0; - break; - } - - buffer[k] = 0; - - g_value_unset (&value); - } - - - dock = get_dock_nth (etoolbar, i); - item = GTK_CHECK_MENU_ITEM (gtk_check_menu_item_new_with_label (buffer)); - gtk_check_menu_item_set_active (item, GTK_WIDGET_VISIBLE (dock)); - gtk_widget_set_sensitive (GTK_WIDGET (item), (n_visible > 1 || !GTK_WIDGET_VISIBLE (dock))); - gtk_widget_show (GTK_WIDGET (item)); - gtk_menu_shell_append (GTK_MENU_SHELL (popup), GTK_WIDGET (item)); - - g_object_set_data (G_OBJECT (item), "egg-dock", dock); - g_signal_connect (item, "toggled", - G_CALLBACK (toggle_visibility_cb), - etoolbar); - } -} - -void -egg_editable_toolbar_add_popup_items (GtkWidget *widget, - GtkMenu *popup) -{ - EggEditableToolbar *etoolbar = EGG_EDITABLE_TOOLBAR - (gtk_widget_get_ancestor (widget, EGG_TYPE_EDITABLE_TOOLBAR)); - GtkWidget *toolbar = gtk_widget_get_ancestor (widget, GTK_TYPE_TOOLBAR); - GtkWidget *toolitem = gtk_widget_get_ancestor (widget, GTK_TYPE_TOOL_ITEM); - GtkWidget *item, *image; - int separated; - - separated = (GTK_MENU_SHELL(popup)->children == NULL); - - if (etoolbar != NULL && toolitem != NULL) - { - if (!separated) - { - item = gtk_separator_menu_item_new (); - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (popup), item); - separated = 1; - } - - item = gtk_menu_item_new_with_mnemonic (_("_Move on Toolbar")); - g_object_set_data (G_OBJECT (item), EGG_TOOLITEM, toolitem); - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (popup), item); - g_signal_connect (item, "activate", - G_CALLBACK (move_item_cb), - etoolbar); - - item = gtk_image_menu_item_new_with_mnemonic (_("_Remove from Toolbar")); - g_object_set_data (G_OBJECT (item), EGG_TOOLITEM, toolitem); - gtk_widget_show (item); - image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); - gtk_menu_shell_append (GTK_MENU_SHELL (popup), item); - g_signal_connect (item, "activate", - G_CALLBACK (remove_item_cb), - etoolbar); - } - - if (etoolbar != NULL && toolbar != NULL) - { - int position; - EggTbModelFlags flags; - - position = get_toolbar_position (etoolbar, toolbar); - flags = egg_toolbars_model_get_flags (etoolbar->priv->model, position); - - if (etoolbar->priv->edit_mode > 0 && (flags & EGG_TB_MODEL_NOT_REMOVABLE)==0) - { - if (!separated) - { - item = gtk_separator_menu_item_new (); - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (popup), item); - separated = 1; - } - - item = gtk_image_menu_item_new_with_mnemonic (_("_Remove Toolbar")); - g_object_set_data (G_OBJECT (item), "egg-toolbar", toolbar); - gtk_widget_show (item); - image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); - gtk_menu_shell_append (GTK_MENU_SHELL (popup), item); - g_signal_connect (item, "activate", - G_CALLBACK (remove_toolbar_cb), - etoolbar); - } - - if (egg_toolbars_model_n_toolbars (etoolbar->priv->model) > 1) - { - egg_editable_toolbar_add_visibility_items (etoolbar, popup); - } - } -} - -static void popup_context_menu_cb (GtkWidget *toolbar, gint x, gint y, gint button_number, EggEditableToolbar *etoolbar) { - GtkMenu *menu = GTK_MENU (gtk_menu_new ()); - egg_editable_toolbar_add_popup_items (toolbar, menu); - gtk_menu_popup (menu, NULL, NULL, NULL, NULL, button_number, - gtk_get_current_event_time ()); + if (etoolbar->priv->popup != 0) + { + egg_editable_toolbar_set_selected (etoolbar, toolbar); + g_object_notify (G_OBJECT (etoolbar), "selected"); + + GtkMenu *menu = GTK_MENU (gtk_ui_manager_get_widget (etoolbar->priv->manager, "/ToolbarPopup")); + gtk_menu_popup (menu, NULL, NULL, NULL, NULL, button_number, gtk_get_current_event_time ()); + } } static gboolean @@ -557,12 +381,14 @@ button_press_event_cb (GtkWidget *widget, GdkEventButton *event, EggEditableToolbar *etoolbar) { - if (event->button == 3) + if (event->button == 3 && etoolbar->priv->popup != 0) { - GtkMenu *menu = GTK_MENU (gtk_menu_new ()); - egg_editable_toolbar_add_popup_items (widget, menu); - gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event->button, - event->time); + egg_editable_toolbar_set_selected (etoolbar, widget); + g_object_notify (G_OBJECT (etoolbar), "selected"); + + GtkMenu *menu = GTK_MENU (gtk_ui_manager_get_widget (etoolbar->priv->manager, "/ToolbarPopup")); + gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event->button, event->time); + return TRUE; } @@ -575,31 +401,18 @@ configure_item_sensitivity (GtkToolItem *item, EggEditableToolbar *etoolbar) GtkAction *action; char *name; - g_return_if_fail (etoolbar != NULL); - - if (etoolbar->priv->edit_mode > 0) - { - GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (item), GTK_SENSITIVE); - gtk_tool_item_set_use_drag_window (item, TRUE); - gtk_widget_set_sensitive (GTK_WIDGET (item), TRUE); - return; - } - name = g_object_get_data (G_OBJECT (item), EGG_ITEM_NAME); action = name ? find_action (etoolbar, name) : NULL; - - if (action != NULL && gtk_action_is_sensitive (action)) - { - GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (item), GTK_SENSITIVE); - gtk_tool_item_set_use_drag_window (item, FALSE); - gtk_widget_set_sensitive (GTK_WIDGET (item), TRUE); - } - else + + if (action) { - gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE); - gtk_tool_item_set_use_drag_window (item, TRUE); - GTK_WIDGET_SET_FLAGS (GTK_WIDGET (item), GTK_SENSITIVE); + g_object_notify (G_OBJECT (action), "sensitive"); } + + gtk_tool_item_set_use_drag_window (item, + (etoolbar->priv->edit_mode > 0) || + GTK_IS_SEPARATOR_TOOL_ITEM (item)); + } static void @@ -622,9 +435,6 @@ configure_item_cursor (GtkToolItem *item, EggEditableToolbar *etoolbar) else { gdk_window_set_cursor (GTK_WIDGET(item)->window, NULL); - - gtk_drag_source_set (GTK_WIDGET (item), GDK_BUTTON2_MASK, dest_drag_types, - G_N_ELEMENTS (dest_drag_types), GDK_ACTION_MOVE); } } @@ -638,7 +448,7 @@ connect_widget_signals (GtkWidget *proxy, EggEditableToolbar *etoolbar) (gpointer) etoolbar); } - if (GTK_IS_BUTTON (proxy) || GTK_IS_TOOL_ITEM (proxy)) + if (GTK_IS_TOOL_ITEM (proxy)) { g_signal_connect (proxy, "drag_begin", G_CALLBACK (drag_begin_cb), etoolbar); @@ -648,12 +458,12 @@ connect_widget_signals (GtkWidget *proxy, EggEditableToolbar *etoolbar) G_CALLBACK (drag_data_get_cb), etoolbar); g_signal_connect (proxy, "drag_data_delete", G_CALLBACK (drag_data_delete_cb), etoolbar); - g_signal_connect (proxy, "drag_data_get", - G_CALLBACK (drag_data_get_cb), etoolbar); + } + + if (GTK_IS_BUTTON (proxy) || GTK_IS_TOOL_ITEM (proxy)) + { g_signal_connect (proxy, "button-press-event", G_CALLBACK (button_press_event_cb), etoolbar); - gtk_drag_source_set (proxy, GDK_BUTTON2_MASK, dest_drag_types, - G_N_ELEMENTS (dest_drag_types), GDK_ACTION_MOVE); } } @@ -664,7 +474,11 @@ action_sensitive_cb (GtkAction *action, { EggEditableToolbar *etoolbar = EGG_EDITABLE_TOOLBAR (gtk_widget_get_ancestor (GTK_WIDGET (item), EGG_TYPE_EDITABLE_TOOLBAR)); - configure_item_sensitivity (item, etoolbar); + + if (etoolbar->priv->edit_mode > 0) + { + gtk_widget_set_sensitive (GTK_WIDGET (item), TRUE); + } } static GtkToolItem * @@ -678,7 +492,6 @@ create_item_from_action (EggEditableToolbar *etoolbar, if (strcmp (name, "_separator") == 0) { item = gtk_separator_tool_item_new (); - gtk_tool_item_set_use_drag_window (item, TRUE); } else { @@ -1242,7 +1055,45 @@ egg_editable_toolbar_set_ui_manager (EggEditableToolbar *etoolbar, { g_return_if_fail (GTK_IS_UI_MANAGER (manager)); + GtkActionGroup *group = gtk_action_group_new ("ToolbarActions"); + GtkActionEntry actions[] = { + { "MoveToolItem", NULL, _("_Move on Toolbar"), NULL, + _("Move the selected item on the toolbar"), G_CALLBACK (move_item_cb) }, + { "RemoveToolItem", GTK_STOCK_REMOVE, _("_Remove from Toolbar"), NULL, + _("Remove the selected item from the toolbar"), G_CALLBACK (remove_item_cb) }, + { "RemoveToolbar", GTK_STOCK_REMOVE, _("_Remove Toolbar"), NULL, + _("Remove the selected toolbar"), G_CALLBACK (remove_toolbar_cb) }, + }; + gtk_action_group_add_actions (group, actions, 3, etoolbar); + + gtk_ui_manager_insert_action_group (manager, group, 0); + etoolbar->priv->manager = g_object_ref (manager); + etoolbar->priv->popup = gtk_ui_manager_add_ui_from_string (manager, + "<popup name=\"ToolbarPopup\">" + "<menuitem action=\"MoveToolItem\"/>" + "<menuitem action=\"RemoveToolItem\"/>" + "<menuitem action=\"RemoveToolbar\"/>" + "</popup>", -1, NULL); +} + +GtkWidget * egg_editable_toolbar_get_selected (EggEditableToolbar *etoolbar) +{ + return etoolbar->priv->selected; +} + +void +egg_editable_toolbar_set_selected (EggEditableToolbar *etoolbar, + GtkWidget *widget) +{ + etoolbar->priv->selected = widget; + + gboolean toolitem = (gtk_widget_get_ancestor (widget, GTK_TYPE_TOOL_ITEM) != 0); + gboolean toolbar = (gtk_widget_get_ancestor (widget, GTK_TYPE_TOOLBAR) != 0); + + gtk_action_set_visible (find_action (etoolbar, "RemoveToolbar"), toolbar && (etoolbar->priv->edit_mode > 0)); + gtk_action_set_visible (find_action (etoolbar, "RemoveToolItem"), toolitem); + gtk_action_set_visible (find_action (etoolbar, "MoveToolItem"), toolitem); } static void @@ -1261,6 +1112,9 @@ egg_editable_toolbar_set_property (GObject *object, case PROP_TOOLBARS_MODEL: egg_editable_toolbar_set_model (etoolbar, g_value_get_object (value)); break; + case PROP_SELECTED: + egg_editable_toolbar_set_selected (etoolbar, g_value_get_object (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1283,6 +1137,9 @@ egg_editable_toolbar_get_property (GObject *object, case PROP_TOOLBARS_MODEL: g_value_set_object (value, etoolbar->priv->model); break; + case PROP_SELECTED: + g_value_set_object (value, etoolbar->priv->selected); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1322,6 +1179,13 @@ egg_editable_toolbar_class_init (EggEditableToolbarClass *klass) "Toolbars Model", EGG_TYPE_TOOLBARS_MODEL, G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + g_object_class_install_property (object_class, + PROP_SELECTED, + g_param_spec_object ("selected", + "Selected", + "Selected toolitem", + GTK_TYPE_TOOL_ITEM, + G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); g_type_class_add_private (object_class, sizeof (EggEditableToolbarPrivate)); } @@ -1345,6 +1209,12 @@ egg_editable_toolbar_finalize (GObject *object) if (etoolbar->priv->manager) { + if (etoolbar->priv->popup) + { + gtk_ui_manager_remove_ui (etoolbar->priv->manager, + etoolbar->priv->popup); + } + g_object_unref (etoolbar->priv->manager); } |