diff --git a/ChangeLog b/ChangeLog index b99d14ba81..934a390365 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2008-05-19 Sven Neumann + + * app/widgets/gimpdockable.[ch] + * app/widgets/gimpdockbook.[ch]: added a "locked" propery to + GimpDockable. A locked dockable cannot be moved by drag-n-drop. + Allows users to protect their dockables from accidental changes, + mainly when working with a tablet. + + * app/widgets/gimpsessioninfo-dockable.[ch]: store the "locked" + property in the session info. + + * app/actions/dockable-actions.c + * app/actions/dockable-commands.[ch]: added an action for toggling + the "locked" state. + + * app/widgets/gimphelp-ids.h: new help-id "gimp-dock-tab-lock". + + * menus/dockable-menu.xml.in: show the new menu item. + + * app/actions/plug-in-actions.c: formatting. + 2008-05-19 Michael Natterer Unabstract image map tool settings load/save a bit before it's diff --git a/app/actions/dockable-actions.c b/app/actions/dockable-actions.c index 6d84e036ab..8d5aed47d1 100644 --- a/app/actions/dockable-actions.c +++ b/app/actions/dockable-actions.c @@ -104,6 +104,12 @@ static const GimpRadioActionEntry dockable_tab_style_actions[] = static const GimpToggleActionEntry dockable_toggle_actions[] = { + { "dockable-lock-tab", NULL, + N_("Loc_k Tab to Dock"), NULL, NULL, + G_CALLBACK (dockable_lock_tab_cmd_callback), + FALSE, + GIMP_HELP_DOCK_TAB_LOCK }, + { "dockable-show-button-bar", NULL, N_("Show _Button Bar"), NULL, NULL, G_CALLBACK (dockable_show_button_bar_cmd_callback), @@ -175,6 +181,7 @@ dockable_actions_update (GimpActionGroup *group, GimpViewType view_type = -1; gboolean list_view_available = FALSE; gboolean grid_view_available = FALSE; + gboolean locked = FALSE; GimpViewSize view_size = -1; GimpTabStyle tab_style = -1; gint n_pages = 0; @@ -250,7 +257,13 @@ dockable_actions_update (GimpActionGroup *group, #define SET_SENSITIVE(action,sensitive) \ gimp_action_group_set_action_sensitive (group, action, (sensitive) != 0) - SET_SENSITIVE ("dockable-detach-tab", n_pages > 1 || n_books > 1); + + locked = gimp_dockable_is_locked (dockable); + + SET_SENSITIVE ("dockable-detach-tab", (! locked && + (n_pages > 1 || n_books > 1))); + + SET_ACTIVE ("dockable-lock-tab", locked); SET_VISIBLE ("dockable-preview-size-menu", view_size != -1); diff --git a/app/actions/dockable-commands.c b/app/actions/dockable-commands.c index 2b891eb5e7..0e919225a2 100644 --- a/app/actions/dockable-commands.c +++ b/app/actions/dockable-commands.c @@ -40,6 +40,9 @@ #include "dockable-commands.h" +static GimpDockable * dockable_get_current (GimpDockbook *dockbook); + + /* public functions */ void @@ -83,13 +86,7 @@ dockable_close_tab_cmd_callback (GtkAction *action, gpointer data) { GimpDockbook *dockbook = GIMP_DOCKBOOK (data); - GimpDockable *dockable; - gint page_num; - - page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (dockbook)); - - dockable = (GimpDockable *) - gtk_notebook_get_nth_page (GTK_NOTEBOOK (dockbook), page_num); + GimpDockable *dockable = dockable_get_current (dockbook); if (dockable) gimp_dockbook_remove (dockbook, dockable); @@ -100,18 +97,27 @@ dockable_detach_tab_cmd_callback (GtkAction *action, gpointer data) { GimpDockbook *dockbook = GIMP_DOCKBOOK (data); - GimpDockable *dockable; - gint page_num; - - page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (dockbook)); - - dockable = (GimpDockable *) - gtk_notebook_get_nth_page (GTK_NOTEBOOK (dockbook), page_num); + GimpDockable *dockable = dockable_get_current (dockbook); if (dockable) gimp_dockable_detach (dockable); } +void +dockable_lock_tab_cmd_callback (GtkAction *action, + gpointer data) +{ + GimpDockbook *dockbook = GIMP_DOCKBOOK (data); + GimpDockable *dockable = dockable_get_current (dockbook); + + if (dockable) + { + gboolean lock = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + + gimp_dockable_set_locked (dockable, lock); + } +} + void dockable_toggle_view_cmd_callback (GtkAction *action, GtkAction *current, @@ -219,17 +225,11 @@ dockable_view_size_cmd_callback (GtkAction *action, gpointer data) { GimpDockbook *dockbook = GIMP_DOCKBOOK (data); - GimpDockable *dockable; + GimpDockable *dockable = dockable_get_current (dockbook); gint view_size; - gint page_num; view_size = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action)); - page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (dockbook)); - - dockable = (GimpDockable *) - gtk_notebook_get_nth_page (GTK_NOTEBOOK (dockbook), page_num); - if (dockable) { GimpContainerView *view = gimp_container_view_get_by_dockable (dockable); @@ -253,25 +253,19 @@ dockable_tab_style_cmd_callback (GtkAction *action, gpointer data) { GimpDockbook *dockbook = GIMP_DOCKBOOK (data); - GimpDockable *dockable; + GimpDockable *dockable = dockable_get_current (dockbook); GimpTabStyle tab_style; - gint page_num; tab_style = (GimpTabStyle) gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action)); - page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (dockbook)); - - dockable = (GimpDockable *) - gtk_notebook_get_nth_page (GTK_NOTEBOOK (dockbook), page_num); - if (dockable && dockable->tab_style != tab_style) { GtkWidget *tab_widget; gimp_dockable_set_tab_style (dockable, tab_style); - tab_widget = gimp_dockbook_get_tab_widget (dockbook, dockable); + tab_widget = gimp_dockbook_create_tab_widget (dockbook, dockable); gtk_notebook_set_tab_label (GTK_NOTEBOOK (dockbook), GTK_WIDGET (dockable), @@ -284,13 +278,7 @@ dockable_show_button_bar_cmd_callback (GtkAction *action, gpointer data) { GimpDockbook *dockbook = GIMP_DOCKBOOK (data); - GimpDockable *dockable; - gint page_num; - - page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (dockbook)); - - dockable = (GimpDockable *) - gtk_notebook_get_nth_page (GTK_NOTEBOOK (dockbook), page_num); + GimpDockable *dockable = dockable_get_current (dockbook); if (dockable) { @@ -303,3 +291,12 @@ dockable_show_button_bar_cmd_callback (GtkAction *action, gimp_docked_set_show_button_bar (docked, show); } } + +static GimpDockable * +dockable_get_current (GimpDockbook *dockbook) +{ + gint page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (dockbook)); + + return (GimpDockable *) gtk_notebook_get_nth_page (GTK_NOTEBOOK (dockbook), + page_num); +} diff --git a/app/actions/dockable-commands.h b/app/actions/dockable-commands.h index 14ee796491..3e19d0515f 100644 --- a/app/actions/dockable-commands.h +++ b/app/actions/dockable-commands.h @@ -27,6 +27,8 @@ void dockable_close_tab_cmd_callback (GtkAction *action, gpointer data); void dockable_detach_tab_cmd_callback (GtkAction *action, gpointer data); +void dockable_lock_tab_cmd_callback (GtkAction *action, + gpointer data); void dockable_toggle_view_cmd_callback (GtkAction *action, GtkAction *current, diff --git a/app/actions/plug-in-actions.c b/app/actions/plug-in-actions.c index 726d022afe..bae6a8cacd 100644 --- a/app/actions/plug-in-actions.c +++ b/app/actions/plug-in-actions.c @@ -506,8 +506,10 @@ plug_in_actions_history_changed (GimpPlugInManager *manager, gimp_action_group_set_action_label (group, "plug-in-repeat", repeat); gimp_action_group_set_action_label (group, "plug-in-reshow", reshow); - gimp_action_group_set_action_sensitive (group, "plug-in-repeat", sensitive); - gimp_action_group_set_action_sensitive (group, "plug-in-reshow", sensitive); + gimp_action_group_set_action_sensitive (group, + "plug-in-repeat", sensitive); + gimp_action_group_set_action_sensitive (group, + "plug-in-reshow", sensitive); g_free (repeat); g_free (reshow); diff --git a/app/widgets/gimpdockable.c b/app/widgets/gimpdockable.c index 9ebe0de45d..7fc9e21513 100644 --- a/app/widgets/gimpdockable.c +++ b/app/widgets/gimpdockable.c @@ -21,6 +21,8 @@ #include "config.h" +#include + #include #include "libgimpwidgets/gimpwidgets.h" @@ -36,12 +38,27 @@ #include "gimpdockbook.h" #include "gimpdocked.h" #include "gimphelp-ids.h" +#include "gimpsessioninfo-aux.h" #include "gimpuimanager.h" #include "gimpwidgets-utils.h" #include "gimp-intl.h" +enum +{ + PROP_0, + PROP_LOCKED +}; + +static void gimp_dockable_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void gimp_dockable_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); static void gimp_dockable_destroy (GtkObject *object); static void gimp_dockable_size_request (GtkWidget *widget, GtkRequisition *requisition); @@ -76,6 +93,8 @@ static void gimp_dockable_forall (GtkContainer *container, GtkCallback callback, gpointer callback_data); +static void gimp_dockable_cursor_setup (GimpDockable *dockable); + static void gimp_dockable_get_title_area (GimpDockable *dockable, GdkRectangle *area); static void gimp_dockable_clear_title_area (GimpDockable *dockable); @@ -100,11 +119,15 @@ static const GtkTargetEntry dialog_target_table[] = { GIMP_TARGET_DIALOG }; static void gimp_dockable_class_init (GimpDockableClass *klass) { - GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); - object_class->destroy = gimp_dockable_destroy; + object_class->set_property = gimp_dockable_set_property; + object_class->get_property = gimp_dockable_get_property; + + gtk_object_class->destroy = gimp_dockable_destroy; widget_class->size_request = gimp_dockable_size_request; widget_class->size_allocate = gimp_dockable_size_allocate; @@ -122,6 +145,11 @@ gimp_dockable_class_init (GimpDockableClass *klass) container_class->child_type = gimp_dockable_child_type; container_class->forall = gimp_dockable_forall; + g_object_class_install_property (object_class, PROP_LOCKED, + g_param_spec_boolean ("locked", NULL, NULL, + FALSE, + GIMP_PARAM_READWRITE)); + gtk_widget_class_install_style_property (widget_class, g_param_spec_int ("content-border", NULL, NULL, @@ -175,7 +203,7 @@ gimp_dockable_init (GimpDockable *dockable) dialog_target_table, G_N_ELEMENTS (dialog_target_table), GDK_ACTION_MOVE); - /* Filter out all button_press events not coming from the event window + /* Filter out all button-press events not coming from the event window over the title area. This keeps events that originate from widgets in the dockable to start a drag. */ @@ -187,6 +215,44 @@ gimp_dockable_init (GimpDockable *dockable) NULL); } +static void +gimp_dockable_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GimpDockable *dockable = GIMP_DOCKABLE (object); + + switch (property_id) + { + case PROP_LOCKED: + gimp_dockable_set_locked (dockable, g_value_get_boolean (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gimp_dockable_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GimpDockable *dockable = GIMP_DOCKABLE (object); + + switch (property_id) + { + case PROP_LOCKED: + g_value_set_boolean (value, dockable->locked); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + static void gimp_dockable_destroy (GtkObject *object) { @@ -344,7 +410,6 @@ gimp_dockable_realize (GtkWidget *widget) { GdkWindowAttr attributes; GdkRectangle area; - GdkCursor *cursor; gimp_dockable_get_title_area (dockable, &area); @@ -367,12 +432,9 @@ gimp_dockable_realize (GtkWidget *widget) GDK_WA_NOREDIR)); gdk_window_set_user_data (dockable->title_window, widget); - - cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), - GDK_HAND2); - gdk_window_set_cursor (dockable->title_window, cursor); - gdk_cursor_unref (cursor); } + + gimp_dockable_cursor_setup (dockable); } static void @@ -742,6 +804,7 @@ gimp_dockable_new (const gchar *name, return GTK_WIDGET (dockable); } + void gimp_dockable_set_aux_info (GimpDockable *dockable, GList *aux_info) @@ -771,6 +834,32 @@ gimp_dockable_get_aux_info (GimpDockable *dockable) return NULL; } + +void +gimp_dockable_set_locked (GimpDockable *dockable, + gboolean lock) +{ + g_return_if_fail (GIMP_IS_DOCKABLE (dockable)); + + if (dockable->locked != lock) + { + dockable->locked = lock ? TRUE : FALSE; + + gimp_dockable_cursor_setup (dockable); + + g_object_notify (G_OBJECT (dockable), "locked"); + } +} + +gboolean +gimp_dockable_is_locked (GimpDockable *dockable) +{ + g_return_val_if_fail (GIMP_IS_DOCKABLE (dockable), FALSE); + + return dockable->locked; +} + + void gimp_dockable_set_tab_style (GimpDockable *dockable, GimpTabStyle tab_style) @@ -939,8 +1028,35 @@ gimp_dockable_blink_cancel (GimpDockable *dockable) } } + /* private functions */ +static void +gimp_dockable_cursor_setup (GimpDockable *dockable) +{ + if (! GTK_WIDGET_REALIZED (dockable)) + return; + + if (! dockable->title_window) + return; + + /* only show a hand cursor for unlocked dockables */ + + if (gimp_dockable_is_locked (dockable)) + { + gdk_window_set_cursor (dockable->title_window, NULL); + } + else + { + GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (dockable)); + GdkCursor *cursor; + + cursor = gdk_cursor_new_for_display (display, GDK_HAND2); + gdk_window_set_cursor (dockable->title_window, cursor); + gdk_cursor_unref (cursor); + } +} + static void gimp_dockable_get_title_area (GimpDockable *dockable, GdkRectangle *area) diff --git a/app/widgets/gimpdockable.h b/app/widgets/gimpdockable.h index bdf52855f9..d3dbcaa133 100644 --- a/app/widgets/gimpdockable.h +++ b/app/widgets/gimpdockable.h @@ -48,6 +48,7 @@ struct _GimpDockable gchar *stock_id; gchar *help_id; GimpTabStyle tab_style; + gboolean locked; GimpDockbook *dockbook; @@ -82,6 +83,10 @@ void gimp_dockable_set_aux_info (GimpDockable *dockable, GList *aux_info); GList * gimp_dockable_get_aux_info (GimpDockable *dockable); +void gimp_dockable_set_locked (GimpDockable *dockable, + gboolean lock); +gboolean gimp_dockable_is_locked (GimpDockable *dockable); + void gimp_dockable_set_tab_style (GimpDockable *dockable, GimpTabStyle tab_style); GtkWidget * gimp_dockable_get_tab_widget (GimpDockable *dockable, diff --git a/app/widgets/gimpdockbook.c b/app/widgets/gimpdockbook.c index edd22082a6..0969bc2f2e 100644 --- a/app/widgets/gimpdockbook.c +++ b/app/widgets/gimpdockbook.c @@ -35,6 +35,7 @@ #include "gimpdnd.h" #include "gimpdockable.h" #include "gimpdockbook.h" +#include "gimpdocked.h" #include "gimphelp-ids.h" #include "gimpimagedock.h" #include "gimpmenufactory.h" @@ -79,6 +80,8 @@ static void gimp_dockbook_dockable_removed (GimpDockbook *dockbook, static void gimp_dockbook_update_tabs (GimpDockbook *dockbook, gboolean added); +static void gimp_dockbook_tab_drag_source_setup (GtkWidget *widget, + GimpDockable *dockable); static void gimp_dockbook_tab_drag_begin (GtkWidget *widget, GdkDragContext *context, GimpDockable *dockable); @@ -106,6 +109,9 @@ static void gimp_dockbook_add_tab_timeout (GimpDockbook *dockbook, GimpDockable *dockable); static void gimp_dockbook_remove_tab_timeout (GimpDockbook *dockbook); static gboolean gimp_dockbook_tab_timeout (GimpDockbook *dockbook); +static void gimp_dockbook_tab_locked_notify (GimpDockable *dockable, + GParamSpec *pspec, + GimpDockbook *dockbook); static void gimp_dockbook_help_func (const gchar *help_id, gpointer help_data); @@ -244,8 +250,8 @@ gimp_dockbook_style_set (GtkWidget *widget, { GtkWidget *tab_widget; - tab_widget = gimp_dockbook_get_tab_widget (GIMP_DOCKBOOK (widget), - GIMP_DOCKABLE (list->data)); + tab_widget = gimp_dockbook_create_tab_widget (GIMP_DOCKBOOK (widget), + GIMP_DOCKABLE (list->data)); gtk_notebook_set_tab_label (GTK_NOTEBOOK (widget), GTK_WIDGET (list->data), @@ -337,7 +343,7 @@ gimp_dockbook_add (GimpDockbook *dockbook, g_return_if_fail (GIMP_IS_DOCKABLE (dockable)); g_return_if_fail (dockable->dockbook == NULL); - tab_widget = gimp_dockbook_get_tab_widget (dockbook, dockable); + tab_widget = gimp_dockbook_create_tab_widget (dockbook, dockable); g_return_if_fail (GTK_IS_WIDGET (tab_widget)); @@ -370,6 +376,10 @@ gimp_dockbook_add (GimpDockbook *dockbook, gimp_dockable_set_context (dockable, dockbook->dock->context); + g_signal_connect (dockable, "notify::locked", + G_CALLBACK (gimp_dockbook_tab_locked_notify), + dockbook); + g_signal_emit (dockbook, dockbook_signals[DOCKABLE_ADDED], 0, dockable); } @@ -385,6 +395,10 @@ gimp_dockbook_remove (GimpDockbook *dockbook, g_object_ref (dockable); + g_signal_handlers_disconnect_by_func (dockable, + G_CALLBACK (gimp_dockbook_tab_locked_notify), + dockbook); + if (dockbook->tab_hover_dockable == dockable) gimp_dockbook_remove_tab_timeout (dockbook); @@ -407,8 +421,8 @@ gimp_dockbook_remove (GimpDockbook *dockbook, } GtkWidget * -gimp_dockbook_get_tab_widget (GimpDockbook *dockbook, - GimpDockable *dockable) +gimp_dockbook_create_tab_widget (GimpDockbook *dockbook, + GimpDockable *dockable) { GtkWidget *tab_widget; GtkIconSize tab_size = DEFAULT_TAB_ICON_SIZE; @@ -482,13 +496,8 @@ gimp_dockbook_get_tab_widget (GimpDockbook *dockbook, g_object_set_data (G_OBJECT (tab_widget), "gimp-dockable", dockable); - /* set the drag source *before* connecting button_press because we - * stop button_press emission by returning TRUE from the callback - */ - gtk_drag_source_set (GTK_WIDGET (tab_widget), - GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, - dialog_target_table, G_N_ELEMENTS (dialog_target_table), - GDK_ACTION_MOVE); + gimp_dockbook_tab_drag_source_setup (tab_widget, dockable); + g_signal_connect (tab_widget, "drag-begin", G_CALLBACK (gimp_dockbook_tab_drag_begin), dockable); @@ -496,10 +505,6 @@ gimp_dockbook_get_tab_widget (GimpDockbook *dockbook, G_CALLBACK (gimp_dockbook_tab_drag_end), dockable); - gtk_drag_source_set (GTK_WIDGET (dockable), - GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, - dialog_target_table, G_N_ELEMENTS (dialog_target_table), - GDK_ACTION_MOVE); g_signal_connect (dockable, "drag-begin", G_CALLBACK (gimp_dockbook_tab_drag_begin), dockable); @@ -507,7 +512,7 @@ gimp_dockbook_get_tab_widget (GimpDockbook *dockbook, G_CALLBACK (gimp_dockbook_tab_drag_end), dockable); - gtk_drag_dest_set (GTK_WIDGET (tab_widget), + gtk_drag_dest_set (tab_widget, GTK_DEST_DEFAULT_DROP, dialog_target_table, G_N_ELEMENTS (dialog_target_table), GDK_ACTION_MOVE); @@ -570,6 +575,34 @@ gimp_dockbook_drop_dockable (GimpDockbook *dockbook, /* tab DND source side */ +static void +gimp_dockbook_tab_drag_source_setup (GtkWidget *widget, + GimpDockable *dockable) +{ + if (gimp_dockable_is_locked (dockable)) + { + if (widget) + gtk_drag_source_unset (widget); + + gtk_drag_source_unset (GTK_WIDGET (dockable)); + } + else + { + if (widget) + gtk_drag_source_set (widget, + GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, + dialog_target_table, + G_N_ELEMENTS (dialog_target_table), + GDK_ACTION_MOVE); + + gtk_drag_source_set (GTK_WIDGET (dockable), + GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, + dialog_target_table, + G_N_ELEMENTS (dialog_target_table), + GDK_ACTION_MOVE); + } +} + static void gimp_dockbook_tab_drag_begin (GtkWidget *widget, GdkDragContext *context, @@ -796,16 +829,27 @@ gimp_dockbook_tab_timeout (GimpDockbook *dockbook) return FALSE; } +static void +gimp_dockbook_tab_locked_notify (GimpDockable *dockable, + GParamSpec *pspec, + GimpDockbook *dockbook) +{ + GtkWidget *tab_widget; + + tab_widget = gtk_notebook_get_tab_label (GTK_NOTEBOOK (dockbook), + GTK_WIDGET (dockable)); + + gimp_dockbook_tab_drag_source_setup (tab_widget, dockable); +} + static void gimp_dockbook_help_func (const gchar *help_id, gpointer help_data) { - GimpDockbook *dockbook; + GimpDockbook *dockbook = GIMP_DOCKBOOK (help_data); GtkWidget *dockable; gint page_num; - dockbook = GIMP_DOCKBOOK (help_data); - page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (dockbook)); dockable = gtk_notebook_get_nth_page (GTK_NOTEBOOK (dockbook), page_num); diff --git a/app/widgets/gimpdockbook.h b/app/widgets/gimpdockbook.h index 4a94eea9ef..70428a4aef 100644 --- a/app/widgets/gimpdockbook.h +++ b/app/widgets/gimpdockbook.h @@ -60,20 +60,20 @@ struct _GimpDockbookClass }; -GType gimp_dockbook_get_type (void) G_GNUC_CONST; +GType gimp_dockbook_get_type (void) G_GNUC_CONST; -GtkWidget * gimp_dockbook_new (GimpMenuFactory *menu_factory); +GtkWidget * gimp_dockbook_new (GimpMenuFactory *menu_factory); -void gimp_dockbook_add (GimpDockbook *dockbook, - GimpDockable *dockable, - gint position); -void gimp_dockbook_remove (GimpDockbook *dockbook, - GimpDockable *dockable); +void gimp_dockbook_add (GimpDockbook *dockbook, + GimpDockable *dockable, + gint position); +void gimp_dockbook_remove (GimpDockbook *dockbook, + GimpDockable *dockable); -GtkWidget * gimp_dockbook_get_tab_widget (GimpDockbook *dockbook, - GimpDockable *dockable); -gboolean gimp_dockbook_drop_dockable (GimpDockbook *dockbook, - GtkWidget *drag_source); +GtkWidget * gimp_dockbook_create_tab_widget (GimpDockbook *dockbook, + GimpDockable *dockable); +gboolean gimp_dockbook_drop_dockable (GimpDockbook *dockbook, + GtkWidget *drag_source); #endif /* __GIMP_DOCKBOOK_H__ */ diff --git a/app/widgets/gimphelp-ids.h b/app/widgets/gimphelp-ids.h index f0aeb786f3..d40fdc484a 100644 --- a/app/widgets/gimphelp-ids.h +++ b/app/widgets/gimphelp-ids.h @@ -452,6 +452,7 @@ #define GIMP_HELP_DOCK_TAB_ADD "gimp-dock-tab-add" #define GIMP_HELP_DOCK_TAB_CLOSE "gimp-dock-tab-close" +#define GIMP_HELP_DOCK_TAB_LOCK "gimp-dock-tab-lock" #define GIMP_HELP_DOCK_TAB_MENU "gimp-dock-tab-menu" #define GIMP_HELP_DOCK_TAB_DETACH "gimp-dock-tab-detach" #define GIMP_HELP_DOCK_PREVIEW_SIZE "gimp-dock-preview-size" diff --git a/app/widgets/gimpsessioninfo-dockable.c b/app/widgets/gimpsessioninfo-dockable.c index 755049ce2d..08b0cb8db1 100644 --- a/app/widgets/gimpsessioninfo-dockable.c +++ b/app/widgets/gimpsessioninfo-dockable.c @@ -38,6 +38,7 @@ enum { + SESSION_INFO_DOCKABLE_LOCKED, SESSION_INFO_DOCKABLE_TAB_STYLE, SESSION_INFO_DOCKABLE_VIEW_SIZE, SESSION_INFO_DOCKABLE_AUX @@ -89,6 +90,12 @@ gimp_session_info_dockable_serialize (GimpConfigWriter *writer, gimp_config_writer_open (writer, "dockable"); gimp_config_writer_string (writer, info->identifier); + if (info->locked) + { + gimp_config_writer_open (writer, "locked"); + gimp_config_writer_close (writer); + } + enum_value = g_enum_get_value (enum_class, info->tab_style); if (enum_value) @@ -126,6 +133,8 @@ gimp_session_info_dockable_deserialize (GScanner *scanner, g_return_val_if_fail (scanner != NULL, G_TOKEN_LEFT_PAREN); g_return_val_if_fail (dockable != NULL, G_TOKEN_LEFT_PAREN); + g_scanner_scope_add_symbol (scanner, scope, "locked", + GINT_TO_POINTER (SESSION_INFO_DOCKABLE_LOCKED)); g_scanner_scope_add_symbol (scanner, scope, "tab-style", GINT_TO_POINTER (SESSION_INFO_DOCKABLE_TAB_STYLE)); g_scanner_scope_add_symbol (scanner, scope, "preview-size", @@ -156,6 +165,10 @@ gimp_session_info_dockable_deserialize (GScanner *scanner, case G_TOKEN_SYMBOL: switch (GPOINTER_TO_INT (scanner->value.v_symbol)) { + case SESSION_INFO_DOCKABLE_LOCKED: + info->locked = TRUE; + break; + case SESSION_INFO_DOCKABLE_TAB_STYLE: token = G_TOKEN_IDENTIFIER; if (g_scanner_peek_next_token (scanner) != token) @@ -206,6 +219,7 @@ gimp_session_info_dockable_deserialize (GScanner *scanner, g_type_class_unref (enum_class); + g_scanner_scope_remove_symbol (scanner, scope, "locked"); g_scanner_scope_remove_symbol (scanner, scope, "tab-style"); g_scanner_scope_remove_symbol (scanner, scope, "preview-size"); g_scanner_scope_remove_symbol (scanner, scope, "aux-info"); @@ -237,6 +251,7 @@ gimp_session_info_dockable_from_widget (GimpDockable *dockable) info = gimp_session_info_dockable_new (); + info->locked = dockable->locked; info->identifier = g_strdup (entry->identifier); info->tab_style = dockable->tab_style; info->view_size = -1; @@ -278,6 +293,7 @@ gimp_session_info_dockable_restore (GimpSessionInfoDockable *info, if (dockable) { + gimp_dockable_set_locked (GIMP_DOCKABLE (dockable), info->locked); gimp_dockable_set_tab_style (GIMP_DOCKABLE (dockable), info->tab_style); if (info->aux_info) diff --git a/app/widgets/gimpsessioninfo-dockable.h b/app/widgets/gimpsessioninfo-dockable.h index a0b1e8b3e3..96f8956f40 100644 --- a/app/widgets/gimpsessioninfo-dockable.h +++ b/app/widgets/gimpsessioninfo-dockable.h @@ -26,6 +26,7 @@ struct _GimpSessionInfoDockable { gchar *identifier; + gboolean locked; GimpTabStyle tab_style; gint view_size; diff --git a/menus/dockable-menu.xml.in b/menus/dockable-menu.xml.in index e1946e358a..29301d1fc6 100644 --- a/menus/dockable-menu.xml.in +++ b/menus/dockable-menu.xml.in @@ -9,6 +9,7 @@ +