Index: app/tools/gimpselectiontool.c =================================================================== --- app/tools/gimpselectiontool.c (revision 25670) +++ app/tools/gimpselectiontool.c (working copy) @@ -233,7 +233,7 @@ gimp_selection_tool_oper_update (GimpToo if (proximity) { - gchar *status = NULL; + const gchar *status = NULL; gboolean free_status = FALSE; GdkModifierType modifiers = (GDK_SHIFT_MASK | GDK_CONTROL_MASK); @@ -316,7 +316,7 @@ gimp_selection_tool_oper_update (GimpToo gimp_tool_push_status (tool, display, status); if (free_status) - g_free (status); + g_free ((gchar *) status); } } Index: app/tools/gimpvectortool.c =================================================================== --- app/tools/gimpvectortool.c (revision 25670) +++ app/tools/gimpvectortool.c (working copy) @@ -1137,20 +1137,23 @@ gimp_vector_tool_status_update (GimpTool if (proximity) { - gchar *status = NULL; - gboolean free_status = FALSE; + const gchar *status = NULL; + gboolean free_status = FALSE; switch (vector_tool->function) { case VECTORS_SELECT_VECTOR: status = _("Click to pick path to edit"); break; + case VECTORS_CREATE_VECTOR: status = _("Click to create a new path"); break; + case VECTORS_CREATE_STROKE: status = _("Click to create a new component of the path"); break; + case VECTORS_ADD_ANCHOR: status = gimp_suggest_modifiers (_("Click or Click-Drag to create " "a new anchor"), @@ -1158,6 +1161,7 @@ gimp_vector_tool_status_update (GimpTool NULL, NULL, NULL); free_status = TRUE; break; + case VECTORS_MOVE_ANCHOR: if (options->edit_mode != GIMP_VECTOR_MODE_EDIT) { @@ -1170,9 +1174,11 @@ gimp_vector_tool_status_update (GimpTool else status = _("Click-Drag to move the anchor around"); break; + case VECTORS_MOVE_ANCHORSET: status = _("Click-Drag to move the anchors around"); break; + case VECTORS_MOVE_HANDLE: status = gimp_suggest_modifiers (_("Click-Drag to move the handle " "around"), @@ -1180,6 +1186,7 @@ gimp_vector_tool_status_update (GimpTool NULL, NULL, NULL); free_status = TRUE; break; + case VECTORS_MOVE_CURVE: if (GIMP_VECTOR_TOOL_GET_OPTIONS (tool)->polygonal) status = gimp_suggest_modifiers (_("Click-Drag to move the " @@ -1193,6 +1200,7 @@ gimp_vector_tool_status_update (GimpTool _("%s: symmetrical"), NULL, NULL); free_status = TRUE; break; + case VECTORS_MOVE_STROKE: status = gimp_suggest_modifiers (_("Click-Drag to move the " "component around"), @@ -1200,9 +1208,11 @@ gimp_vector_tool_status_update (GimpTool NULL, NULL, NULL); free_status = TRUE; break; + case VECTORS_MOVE_VECTORS: status = _("Click-Drag to move the path around"); break; + case VECTORS_INSERT_ANCHOR: status = gimp_suggest_modifiers (_("Click-Drag to insert an anchor " "on the path"), @@ -1210,19 +1220,24 @@ gimp_vector_tool_status_update (GimpTool NULL, NULL, NULL); free_status = TRUE; break; + case VECTORS_DELETE_ANCHOR: status = _("Click to delete this anchor"); break; + case VECTORS_CONNECT_STROKES: status = _("Click to connect this anchor " "with the selected endpoint"); break; + case VECTORS_DELETE_SEGMENT: status = _("Click to open up the path"); break; + case VECTORS_CONVERT_EDGE: status = _("Click to make this node angular"); break; + case VECTORS_FINISHED: status = NULL; break; @@ -1232,7 +1247,7 @@ gimp_vector_tool_status_update (GimpTool gimp_tool_push_status (tool, display, status); if (free_status) - g_free (status); + g_free ((gchar *) status); } } Index: app/dialogs/dialogs.c =================================================================== --- app/dialogs/dialogs.c (revision 25670) +++ app/dialogs/dialogs.c (working copy) @@ -26,10 +26,12 @@ #include "core/gimp.h" #include "core/gimpcontext.h" +#include "core/gimplist.h" #include "widgets/gimpdialogfactory.h" #include "widgets/gimphelp-ids.h" #include "widgets/gimpmenufactory.h" +#include "widgets/gimpsessioninfo.h" #include "dialogs.h" #include "dialogs-constructors.h" @@ -42,6 +44,8 @@ GimpDialogFactory *global_dock_factory GimpDialogFactory *global_toolbox_factory = NULL; GimpDialogFactory *global_display_factory = NULL; +GimpContainer *global_recent_docks = NULL; + #define FOREIGN(id,singleton,remember_size) \ { id, NULL, NULL, NULL, NULL, \ @@ -301,6 +305,8 @@ dialogs_init (Gimp *gimp, TRUE, TRUE, FALSE); + + global_recent_docks = gimp_list_new (GIMP_TYPE_SESSION_INFO, FALSE); } void @@ -337,6 +343,12 @@ dialogs_exit (Gimp *gimp) g_object_unref (global_display_factory); global_display_factory = NULL; } + + if (global_recent_docks) + { + g_object_unref (global_recent_docks); + global_recent_docks = NULL; + } } GtkWidget * Index: app/dialogs/dialogs.h =================================================================== --- app/dialogs/dialogs.h (revision 25670) +++ app/dialogs/dialogs.h (working copy) @@ -25,6 +25,8 @@ extern GimpDialogFactory *global_dock_fa extern GimpDialogFactory *global_toolbox_factory; extern GimpDialogFactory *global_display_factory; +extern GimpContainer *global_recent_docks; + void dialogs_init (Gimp *gimp, GimpMenuFactory *menu_factory); Index: app/gui/session.c =================================================================== --- app/gui/session.c (revision 25670) +++ app/gui/session.c (working copy) @@ -124,13 +124,55 @@ session_init (Gimp *gimp) case G_TOKEN_SYMBOL: if (scanner->value.v_symbol == GINT_TO_POINTER (SESSION_INFO)) { - g_scanner_set_scope (scanner, SESSION_INFO); - token = gimp_session_info_deserialize (scanner, SESSION_INFO); + GimpDialogFactory *factory; + GimpSessionInfo *info; + gchar *factory_name; + gchar *entry_name; + gboolean skip = FALSE; - if (token == G_TOKEN_RIGHT_PAREN) - g_scanner_set_scope (scanner, 0); - else + token = G_TOKEN_STRING; + + if (! gimp_scanner_parse_string (scanner, &factory_name)) + break; + + factory = gimp_dialog_factory_from_name (factory_name); + g_free (factory_name); + + if (! factory) break; + + if (! gimp_scanner_parse_string (scanner, &entry_name)) + break; + + info = gimp_session_info_new (); + + if (strcmp (entry_name, "dock")) + { + info->toplevel_entry = gimp_dialog_factory_find_entry (factory, + entry_name); + skip = (info->toplevel_entry == NULL); + } + + if (GIMP_CONFIG_GET_INTERFACE (info)->deserialize (GIMP_CONFIG (info), + scanner, + 1, + NULL)) + { + if (! skip) + { + factory->session_infos = + g_list_append (factory->session_infos, info); + } + else + { + g_object_unref (info); + } + } + else + { + g_object_unref (info); + break; + } } else if (scanner->value.v_symbol == GINT_TO_POINTER (LAST_TIP_SHOWN)) { Index: app/menus/windows-menu.c =================================================================== --- app/menus/windows-menu.c (revision 25670) +++ app/menus/windows-menu.c (working copy) @@ -59,6 +59,13 @@ static void windows_menu_dock_removed GimpDock *dock, GimpUIManager *manager); +static void windows_menu_recent_add (GimpContainer *container, + GimpSessionInfo *info, + GimpUIManager *manager); +static void windows_menu_recent_remove (GimpContainer *container, + GimpSessionInfo *info, + GimpUIManager *manager); + void windows_menu_setup (GimpUIManager *manager, @@ -104,6 +111,22 @@ windows_menu_setup (GimpUIManager *manag if (GIMP_IS_DOCK (dock)) windows_menu_dock_added (global_dock_factory, dock, manager); } + + g_signal_connect_object (global_recent_docks, "add", + G_CALLBACK (windows_menu_recent_add), + manager, 0); + g_signal_connect_object (global_recent_docks, "remove", + G_CALLBACK (windows_menu_recent_remove), + manager, 0); + + for (list = GIMP_LIST (global_recent_docks)->list; + list; + list = g_list_next (list)) + { + GimpSessionInfo *info = list->data; + + windows_menu_recent_add (global_recent_docks, info, manager); + } } @@ -240,3 +263,64 @@ windows_menu_dock_removed (GimpDialogFac g_free (merge_key); } + +static void +windows_menu_recent_add (GimpContainer *container, + GimpSessionInfo *info, + GimpUIManager *manager) +{ + const gchar *ui_path; + gchar *action_name; + gchar *action_path; + gint info_id; + gchar *merge_key; + guint merge_id; + + ui_path = g_object_get_data (G_OBJECT (manager), "image-menu-ui-path"); + + info_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (info), + "recent-action-id")); + + action_name = g_strdup_printf ("windows-recent-%04d", info_id); + action_path = g_strdup_printf ("%s/Windows/Recently Closed Docks", ui_path); + + merge_key = g_strdup_printf ("windows-recent-%04d-merge-id", info_id); + merge_id = gtk_ui_manager_new_merge_id (GTK_UI_MANAGER (manager)); + + g_object_set_data (G_OBJECT (manager), merge_key, + GUINT_TO_POINTER (merge_id)); + + gtk_ui_manager_add_ui (GTK_UI_MANAGER (manager), merge_id, + action_path, action_name, action_name, + GTK_UI_MANAGER_MENUITEM, + FALSE); + + g_free (merge_key); + g_free (action_path); + g_free (action_name); +} + +static void +windows_menu_recent_remove (GimpContainer *container, + GimpSessionInfo *info, + GimpUIManager *manager) +{ + gint info_id; + gchar *merge_key; + guint merge_id; + + info_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (info), + "recent-action-id")); + + merge_key = g_strdup_printf ("windows-recent-%04d-merge-id", info_id); + + merge_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (manager), + merge_key)); + + if (merge_id) + gtk_ui_manager_remove_ui (GTK_UI_MANAGER (manager), merge_id); + + g_object_set_data (G_OBJECT (manager), merge_key, NULL); + + g_free (merge_key); +} Index: app/actions/windows-actions.c =================================================================== --- app/actions/windows-actions.c (revision 25670) +++ app/actions/windows-actions.c (working copy) @@ -66,6 +66,13 @@ static void windows_actions_dock_notif const GParamSpec *pspec, GimpActionGroup *group); +static void windows_actions_recent_add (GimpContainer *container, + GimpSessionInfo *info, + GimpActionGroup *group); +static void windows_actions_recent_remove (GimpContainer *container, + GimpSessionInfo *info, + GimpActionGroup *group); + static const GimpActionEntry windows_actions[] = { @@ -84,12 +91,15 @@ static const GimpActionEntry windows_act void windows_actions_setup (GimpActionGroup *group) { - GList *list; + GtkAction *action; + GList *list; gimp_action_group_add_actions (group, windows_actions, G_N_ELEMENTS (windows_actions)); + gimp_action_group_set_action_hide_empty (group, "windows-docks-menu", FALSE); + g_signal_connect_object (group->gimp->displays, "add", G_CALLBACK (windows_actions_display_add), group, 0); @@ -122,6 +132,22 @@ windows_actions_setup (GimpActionGroup * if (GIMP_IS_DOCK (dock)) windows_actions_dock_added (global_dock_factory, dock, group); } + + g_signal_connect_object (global_recent_docks, "add", + G_CALLBACK (windows_actions_recent_add), + group, 0); + g_signal_connect_object (global_recent_docks, "remove", + G_CALLBACK (windows_actions_recent_remove), + group, 0); + + for (list = GIMP_LIST (global_recent_docks)->list; + list; + list = g_list_next (list)) + { + GimpSessionInfo *info = list->data; + + windows_actions_recent_add (global_recent_docks, info, group); + } } void @@ -305,3 +331,73 @@ windows_actions_dock_notify (GimpDock "label", gtk_window_get_title (GTK_WINDOW (dock)), NULL); } + +static void +windows_actions_recent_add (GimpContainer *container, + GimpSessionInfo *info, + GimpActionGroup *group) +{ + GtkAction *action; + GimpActionEntry entry; + gint info_id; + static gint info_id_counter = 1; + gchar *action_name; + gchar *title; + + info_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (info), + "recent-action-id")); + + if (! info_id) + { + info_id = info_id_counter++; + + g_object_set_data (G_OBJECT (info), "recent-action-id", + GINT_TO_POINTER (info_id)); + } + + action_name = g_strdup_printf ("windows-recent-%04d", info_id); + + entry.name = action_name; + entry.stock_id = NULL; + entry.label = gimp_object_get_name (GIMP_OBJECT (info)); + entry.accelerator = NULL; + entry.tooltip = NULL; + entry.callback = G_CALLBACK (windows_open_recent_cmd_callback); + entry.help_id = NULL; + + gimp_action_group_add_actions (group, &entry, 1); + + action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), + action_name); + + g_object_set (action, + "ellipsize", PANGO_ELLIPSIZE_END, + "width-chars", 30, + NULL); + + g_object_set_data (G_OBJECT (action), "info", info); + + g_free (action_name); +} + +static void +windows_actions_recent_remove (GimpContainer *container, + GimpSessionInfo *info, + GimpActionGroup *group) +{ + GtkAction *action; + gint info_id; + gchar *action_name; + + info_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (info), + "recent-action-id")); + + action_name = g_strdup_printf ("windows-recent-%04d", info_id); + + action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name); + + if (action) + gtk_action_group_remove_action (GTK_ACTION_GROUP (group), action); + + g_free (action_name); +} Index: app/actions/windows-commands.c =================================================================== --- app/actions/windows-commands.c (revision 25670) +++ app/actions/windows-commands.c (working copy) @@ -24,7 +24,10 @@ #include "actions-types.h" +#include "core/gimpcontainer.h" + #include "widgets/gimpdialogfactory.h" +#include "widgets/gimpsessioninfo.h" #include "display/gimpdisplay.h" @@ -61,6 +64,22 @@ windows_show_dock_cmd_callback (GtkActio } void +windows_open_recent_cmd_callback (GtkAction *action, + gpointer data) +{ + GimpSessionInfo *info = g_object_get_data (G_OBJECT (action), "info"); + + g_object_ref (info); + gimp_container_remove (global_recent_docks, GIMP_OBJECT (info)); + + global_dock_factory->session_infos = + g_list_append (global_dock_factory->session_infos, info); + + gimp_session_info_restore (info, global_dock_factory); + gimp_session_info_clear_info (info); +} + +void windows_show_toolbox (void) { if (! global_toolbox_factory->open_dialogs) Index: app/actions/windows-commands.h =================================================================== --- app/actions/windows-commands.h (revision 25670) +++ app/actions/windows-commands.h (working copy) @@ -26,6 +26,8 @@ void windows_show_display_cmd_callback gpointer data); void windows_show_dock_cmd_callback (GtkAction *action, gpointer data); +void windows_open_recent_cmd_callback (GtkAction *action, + gpointer data); void windows_show_toolbox (void); Index: app/actions/dialogs-actions.c =================================================================== --- app/actions/dialogs-actions.c (revision 25670) +++ app/actions/dialogs-actions.c (working copy) @@ -33,27 +33,6 @@ #include "gimp-intl.h" -static const GimpActionEntry dialogs_actions[] = -{ - { "dialogs-new-dock-lcp", NULL, - N_("_Layers, Channels & Paths"), NULL, - N_("Open a Layers, Channels & Paths dock"), - G_CALLBACK (dialogs_create_lc_cmd_callback), - GIMP_HELP_DOCK }, - - { "dialogs-new-dock-data", NULL, - N_("_Brushes, Patterns & Gradients"), NULL, - N_("Open a Brushes, Patterns & Gradients dock"), - G_CALLBACK (dialogs_create_data_cmd_callback), - GIMP_HELP_DOCK }, - - { "dialogs-new-dock-stuff", NULL, - N_("_Misc. Stuff"), NULL, - N_("Open a dock containing miscellaneous dialogs"), - G_CALLBACK (dialogs_create_stuff_cmd_callback), - GIMP_HELP_DOCK } -}; - const GimpStringActionEntry dialogs_dockable_actions[] = { { "dialogs-tool-options", GIMP_STOCK_TOOL_OPTIONS, @@ -240,10 +219,6 @@ static const GimpStringActionEntry dialo void dialogs_actions_setup (GimpActionGroup *group) { - gimp_action_group_add_actions (group, - dialogs_actions, - G_N_ELEMENTS (dialogs_actions)); - gimp_action_group_add_string_actions (group, dialogs_dockable_actions, G_N_ELEMENTS (dialogs_dockable_actions), Index: app/actions/dialogs-commands.c =================================================================== --- app/actions/dialogs-commands.c (revision 25670) +++ app/actions/dialogs-commands.c (working copy) @@ -18,20 +18,13 @@ #include "config.h" -#include - #include #include "libgimpwidgets/gimpwidgets.h" #include "actions-types.h" -#include "core/gimp.h" - #include "widgets/gimpdialogfactory.h" -#include "widgets/gimpdockable.h" -#include "widgets/gimpdockbook.h" -#include "widgets/gimpmenudock.h" #include "dialogs/dialogs.h" @@ -39,14 +32,6 @@ #include "dialogs-commands.h" -/* local function prototypes */ - -static void dialogs_create_dock (GdkScreen *screen, - gboolean show_image_menu, - const gchar * const tabs[], - gint n_tabs); - - /* public functions */ void @@ -76,96 +61,3 @@ dialogs_create_dockable_cmd_callback (Gt gtk_widget_get_screen (widget), value, -1); } - -void -dialogs_create_lc_cmd_callback (GtkAction *action, - gpointer data) -{ - static const gchar * const tabs[] = - { - "gimp-layer-list", - "gimp-channel-list", - "gimp-vectors-list", - "gimp-undo-history" - }; - - GtkWidget *widget; - return_if_no_widget (widget, data); - - dialogs_create_dock (gtk_widget_get_screen (widget), TRUE, - tabs, G_N_ELEMENTS (tabs)); -} - -void -dialogs_create_data_cmd_callback (GtkAction *action, - gpointer data) -{ - static const gchar * const tabs[] = - { - "gimp-brush-grid", - "gimp-pattern-grid", - "gimp-gradient-list", - "gimp-palette-list", - "gimp-font-list" - }; - - GtkWidget *widget; - return_if_no_widget (widget, data); - - dialogs_create_dock (gtk_widget_get_screen (widget), FALSE, - tabs, G_N_ELEMENTS (tabs)); -} - -void -dialogs_create_stuff_cmd_callback (GtkAction *action, - gpointer data) -{ - static const gchar * const tabs[] = - { - "gimp-buffer-list", - "gimp-image-list", - "gimp-document-list", - "gimp-template-list" - }; - - GtkWidget *widget; - return_if_no_widget (widget, data); - - dialogs_create_dock (gtk_widget_get_screen (widget), FALSE, - tabs, G_N_ELEMENTS (tabs)); -} - - -/* private functions */ - -static void -dialogs_create_dock (GdkScreen *screen, - gboolean show_image_menu, - const gchar * const tabs[], - gint n_tabs) -{ - GtkWidget *dock; - GtkWidget *dockbook; - GtkWidget *dockable; - gint i; - - dock = gimp_dialog_factory_dock_new (global_dock_factory, screen); - - gimp_menu_dock_set_show_image_menu (GIMP_MENU_DOCK (dock), show_image_menu); - - dockbook = gimp_dockbook_new (global_dock_factory->menu_factory); - - gimp_dock_add_book (GIMP_DOCK (dock), GIMP_DOCKBOOK (dockbook), 0); - - for (i = 0; i < n_tabs; i++) - { - dockable = gimp_dialog_factory_dialog_new (global_dock_factory, - screen, - tabs[i], -1, TRUE); - - if (dockable && ! GIMP_DOCKABLE (dockable)->dockbook) - gimp_dock_add (GIMP_DOCK (dock), GIMP_DOCKABLE (dockable), -1, -1); - } - - gtk_widget_show (dock); -} Index: app/actions/dialogs-commands.h =================================================================== --- app/actions/dialogs-commands.h (revision 25670) +++ app/actions/dialogs-commands.h (working copy) @@ -27,12 +27,5 @@ void dialogs_create_dockable_cmd_callb const gchar *value, gpointer data); -void dialogs_create_lc_cmd_callback (GtkAction *action, - gpointer data); -void dialogs_create_data_cmd_callback (GtkAction *action, - gpointer data); -void dialogs_create_stuff_cmd_callback (GtkAction *action, - gpointer data); - #endif /* __DIALOGS_COMMANDS_H__ */ Index: app/widgets/gimpsessioninfo.c =================================================================== --- app/widgets/gimpsessioninfo.c (revision 25670) +++ app/widgets/gimpsessioninfo.c (working copy) @@ -2,7 +2,7 @@ * Copyright (C) 1995 Spencer Kimball and Peter Mattis * * gimpsessioninfo.c - * Copyright (C) 2001-2007 Michael Natterer + * Copyright (C) 2001-2008 Michael Natterer * * 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 @@ -49,13 +49,25 @@ enum #define DEFAULT_SCREEN -1 -static void gimp_session_info_finalize (GObject *object); +static void gimp_session_info_config_iface_init (GimpConfigInterface *iface); -static gint64 gimp_session_info_get_memsize (GimpObject *object, - gint64 *gui_size); +static void gimp_session_info_finalize (GObject *object); +static gint64 gimp_session_info_get_memsize (GimpObject *object, + gint64 *gui_size); -G_DEFINE_TYPE (GimpSessionInfo, gimp_session_info, GIMP_TYPE_OBJECT) +static gboolean gimp_session_info_serialize (GimpConfig *config, + GimpConfigWriter *writer, + gpointer data); +static gboolean gimp_session_info_deserialize (GimpConfig *config, + GScanner *scanner, + gint nest_level, + gpointer data); + + +G_DEFINE_TYPE_WITH_CODE (GimpSessionInfo, gimp_session_info, GIMP_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG, + gimp_session_info_config_iface_init)) #define parent_class gimp_session_info_parent_class @@ -74,6 +86,14 @@ gimp_session_info_class_init (GimpSessio static void gimp_session_info_init (GimpSessionInfo *info) { + info->screen = DEFAULT_SCREEN; +} + +static void +gimp_session_info_config_iface_init (GimpConfigInterface *iface) +{ + iface->serialize = gimp_session_info_serialize; + iface->deserialize = gimp_session_info_deserialize; } static void @@ -99,34 +119,12 @@ gimp_session_info_get_memsize (GimpObjec gui_size); } - -/* public functions */ - -GimpSessionInfo * -gimp_session_info_new (void) -{ - return g_object_new (GIMP_TYPE_SESSION_INFO, NULL); -} - -void -gimp_session_info_serialize (GimpConfigWriter *writer, - GimpSessionInfo *info, - const gchar *factory_name) +static gboolean +gimp_session_info_serialize (GimpConfig *config, + GimpConfigWriter *writer, + gpointer data) { - const gchar *dialog_name; - - g_return_if_fail (GIMP_IS_SESSION_INFO (info)); - g_return_if_fail (factory_name != NULL); - g_return_if_fail (writer != NULL); - - if (info->toplevel_entry) - dialog_name = info->toplevel_entry->identifier; - else - dialog_name = "dock"; - - gimp_config_writer_open (writer, "session-info"); - gimp_config_writer_string (writer, factory_name); - gimp_config_writer_string (writer, dialog_name); + GimpSessionInfo *info = GIMP_SESSION_INFO (config); gimp_config_writer_open (writer, "position"); gimp_config_writer_printf (writer, "%d %d", info->x, info->y); @@ -158,7 +156,7 @@ gimp_session_info_serialize (GimpConfigW gimp_session_info_dock_serialize (writer, info->books); } - gimp_config_writer_close (writer); /* session-info */ + return TRUE; } /* @@ -193,57 +191,31 @@ gimp_session_info_parse_offset (GScanner return TRUE; } -GTokenType -gimp_session_info_deserialize (GScanner *scanner, - gint scope) -{ - GimpDialogFactory *factory; - GimpSessionInfo *info = NULL; - GTokenType token; - gboolean skip = FALSE; - gchar *factory_name; - gchar *entry_name; +static gboolean +gimp_session_info_deserialize (GimpConfig *config, + GScanner *scanner, + gint nest_level, + gpointer data) +{ + GimpSessionInfo *info = GIMP_SESSION_INFO (config); + GTokenType token; + guint scope_id; + guint old_scope_id; - g_return_val_if_fail (scanner != NULL, G_TOKEN_LEFT_PAREN); + scope_id = g_type_qname (G_TYPE_FROM_INSTANCE (config)); + old_scope_id = g_scanner_set_scope (scanner, scope_id); - g_scanner_scope_add_symbol (scanner, scope, "position", + g_scanner_scope_add_symbol (scanner, scope_id, "position", GINT_TO_POINTER (SESSION_INFO_POSITION)); - g_scanner_scope_add_symbol (scanner, scope, "size", + g_scanner_scope_add_symbol (scanner, scope_id, "size", GINT_TO_POINTER (SESSION_INFO_SIZE)); - g_scanner_scope_add_symbol (scanner, scope, "open-on-exit", + g_scanner_scope_add_symbol (scanner, scope_id, "open-on-exit", GINT_TO_POINTER (SESSION_INFO_OPEN)); - g_scanner_scope_add_symbol (scanner, scope, "aux-info", + g_scanner_scope_add_symbol (scanner, scope_id, "aux-info", GINT_TO_POINTER (SESSION_INFO_AUX)); - g_scanner_scope_add_symbol (scanner, scope, "dock", + g_scanner_scope_add_symbol (scanner, scope_id, "dock", GINT_TO_POINTER (SESSION_INFO_DOCK)); - token = G_TOKEN_STRING; - - if (! gimp_scanner_parse_string (scanner, &factory_name)) - goto error; - - factory = gimp_dialog_factory_from_name (factory_name); - g_free (factory_name); - - if (! factory) - goto error; - - if (! gimp_scanner_parse_string (scanner, &entry_name)) - goto error; - - info = gimp_session_info_new (); - - info->screen = DEFAULT_SCREEN; - - if (strcmp (entry_name, "dock")) - { - info->toplevel_entry = gimp_dialog_factory_find_entry (factory, - entry_name); - skip = (info->toplevel_entry == NULL); - } - - g_free (entry_name); - token = G_TOKEN_LEFT_PAREN; while (g_scanner_peek_next_token (scanner) == token) @@ -302,12 +274,12 @@ gimp_session_info_deserialize (GScanner if (info->toplevel_entry) goto error; - g_scanner_set_scope (scanner, scope + 1); - token = gimp_session_info_dock_deserialize (scanner, scope + 1, + g_scanner_set_scope (scanner, scope_id + 1); + token = gimp_session_info_dock_deserialize (scanner, scope_id + 1, info); if (token == G_TOKEN_LEFT_PAREN) - g_scanner_set_scope (scanner, scope); + g_scanner_set_scope (scanner, scope_id); else goto error; @@ -328,29 +300,26 @@ gimp_session_info_deserialize (GScanner } } - if (token == G_TOKEN_LEFT_PAREN) - { - token = G_TOKEN_RIGHT_PAREN; + error: - if (!skip && g_scanner_peek_next_token (scanner) == token) - factory->session_infos = g_list_append (factory->session_infos, info); - else - g_object_unref (info); - } - else - { - error: - if (info) - g_object_unref (info); - } + g_scanner_scope_remove_symbol (scanner, scope_id, "position"); + g_scanner_scope_remove_symbol (scanner, scope_id, "size"); + g_scanner_scope_remove_symbol (scanner, scope_id, "open-on-exit"); + g_scanner_scope_remove_symbol (scanner, scope_id, "aux-info"); + g_scanner_scope_remove_symbol (scanner, scope_id, "dock"); + + g_scanner_set_scope (scanner, old_scope_id); + + return gimp_config_deserialize_return (scanner, token, nest_level); +} - g_scanner_scope_remove_symbol (scanner, scope, "position"); - g_scanner_scope_remove_symbol (scanner, scope, "size"); - g_scanner_scope_remove_symbol (scanner, scope, "open-on-exit"); - g_scanner_scope_remove_symbol (scanner, scope, "aux-info"); - g_scanner_scope_remove_symbol (scanner, scope, "dock"); - return token; +/* public functions */ + +GimpSessionInfo * +gimp_session_info_new (void) +{ + return g_object_new (GIMP_TYPE_SESSION_INFO, NULL); } void Index: app/widgets/gimpsessioninfo.h =================================================================== --- app/widgets/gimpsessioninfo.h (revision 25670) +++ app/widgets/gimpsessioninfo.h (working copy) @@ -74,12 +74,6 @@ GType gimp_session_info_get_ GimpSessionInfo * gimp_session_info_new (void); -void gimp_session_info_serialize (GimpConfigWriter *writer, - GimpSessionInfo *info, - const gchar *factory_name); -GTokenType gimp_session_info_deserialize (GScanner *scanner, - gint scope); - void gimp_session_info_restore (GimpSessionInfo *info, GimpDialogFactory *factory); Index: app/widgets/gimpdialogfactory.c =================================================================== --- app/widgets/gimpdialogfactory.c (revision 25670) +++ app/widgets/gimpdialogfactory.c (working copy) @@ -2,7 +2,7 @@ * Copyright (C) 1995 Spencer Kimball and Peter Mattis * * gimpdialogfactory.c - * Copyright (C) 2001 Michael Natterer + * Copyright (C) 2001-2008 Michael Natterer * * 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 @@ -26,6 +26,7 @@ #include +#include "libgimpconfig/gimpconfig.h" #include "libgimpwidgets/gimpwidgets.h" #include "widgets-types.h" @@ -913,7 +914,7 @@ gimp_dialog_factory_add_dialog (GimpDial factory, G_CONNECT_SWAPPED); - if (entry && entry->session_managed && toplevel) + if ((entry && entry->session_managed && toplevel) || GIMP_IS_DOCK (dialog)) g_signal_connect_object (dialog, "configure-event", G_CALLBACK (gimp_dialog_factory_dialog_configure), factory, @@ -1281,7 +1282,7 @@ gimp_dialog_factory_dialog_configure (Gt dialog_factory = gimp_dialog_factory_from_widget (dialog, &entry); - if (! dialog_factory || ! entry) + if (! dialog_factory || (! entry && ! GIMP_IS_DOCK (dialog))) { g_warning ("%s: dialog was not created by a GimpDialogFactory", G_STRFUNC); @@ -1306,7 +1307,7 @@ gimp_dialog_factory_dialog_configure (Gt GIMP_LOG (DIALOG_FACTORY, "updated session info for \"%s\" from window geometry " "(x=%d y=%d %dx%d)", - entry->identifier, + entry ? entry->identifier : "dock", session_info->x, session_info->y, session_info->width, session_info->height); @@ -1339,7 +1340,19 @@ gimp_dialog_factories_save_foreach (gcon if (info->widget) gimp_session_info_get_info (info); - gimp_session_info_serialize (writer, info, GIMP_OBJECT (factory)->name); + gimp_config_writer_open (writer, "session-info"); + gimp_config_writer_string (writer, + gimp_object_get_name (GIMP_OBJECT (factory))); + gimp_config_writer_string (writer, + info->toplevel_entry ? + info->toplevel_entry->identifier : + "dock"); + + GIMP_CONFIG_GET_INTERFACE (info)->serialize (GIMP_CONFIG (info), + writer, + NULL); + + gimp_config_writer_close (writer); if (info->widget) gimp_session_info_clear_info (info); Index: app/widgets/gimpaction.c =================================================================== --- app/widgets/gimpaction.c (revision 25670) +++ app/widgets/gimpaction.c (working copy) @@ -47,7 +47,8 @@ enum PROP_CONTEXT, PROP_COLOR, PROP_VIEWABLE, - PROP_ELLIPSIZE + PROP_ELLIPSIZE, + PROP_WIDTH_CHARS }; @@ -110,6 +111,12 @@ gimp_action_class_init (GimpActionClass PANGO_TYPE_ELLIPSIZE_MODE, PANGO_ELLIPSIZE_NONE, GIMP_PARAM_READWRITE)); + + g_object_class_install_property (object_class, PROP_WIDTH_CHARS, + g_param_spec_int ("width-chars", + NULL, NULL, + -1, G_MAXINT, -1, + GIMP_PARAM_READWRITE)); } static void @@ -168,6 +175,9 @@ gimp_action_get_property (GObject *ob case PROP_ELLIPSIZE: g_value_set_enum (value, action->ellipsize); break; + case PROP_WIDTH_CHARS: + g_value_set_int (value, action->width_chars); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -207,6 +217,10 @@ gimp_action_set_property (GObject * action->ellipsize = g_value_get_enum (value); set_proxy = TRUE; break; + case PROP_WIDTH_CHARS: + action->width_chars = g_value_get_int (value); + set_proxy = TRUE; + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -392,11 +406,23 @@ gimp_action_set_proxy (GimpAction *actio } { - GtkWidget *label = gtk_bin_get_child (GTK_BIN (proxy)); + GtkWidget *child = gtk_bin_get_child (GTK_BIN (proxy)); - if (GTK_IS_LABEL (label)) + if (GTK_IS_LABEL (child)) { - gtk_label_set_ellipsize (GTK_LABEL (label), action->ellipsize); + GtkLabel *label = GTK_LABEL (child); + gint len = g_utf8_strlen (gtk_label_get_text (label), -1); + + gtk_label_set_ellipsize (label, action->ellipsize); + + if (action->width_chars == -1 || action->width_chars > len) + { + gtk_label_set_width_chars (label, -1); + } + else + { + gtk_label_set_width_chars (label, action->width_chars); + } } } } Index: app/widgets/gimpaction.h =================================================================== --- app/widgets/gimpaction.h (revision 25670) +++ app/widgets/gimpaction.h (working copy) @@ -45,6 +45,7 @@ struct _GimpAction GimpRGB *color; GimpViewable *viewable; PangoEllipsizeMode ellipsize; + gint width_chars; }; struct _GimpActionClass Index: app/widgets/gimpmenudock.c =================================================================== --- app/widgets/gimpmenudock.c (revision 25670) +++ app/widgets/gimpmenudock.c (working copy) @@ -501,7 +501,7 @@ gimp_menu_dock_update_title_idle (GimpMe g_list_free (children); if (g_list_next (list)) - g_string_append (title, " | "); + g_string_append (title, " - "); } gtk_window_set_title (GTK_WINDOW (menu_dock), title->str); Index: app/widgets/gimpdock.c =================================================================== --- app/widgets/gimpdock.c (revision 25670) +++ app/widgets/gimpdock.c (working copy) @@ -38,10 +38,12 @@ #include "gimpdockable.h" #include "gimpdockbook.h" #include "gimpdockseparator.h" -#include "gimpmessagebox.h" -#include "gimpmessagedialog.h" #include "gimpwidgets-utils.h" +#include "gimpsessioninfo.h" /* FIXME */ +#include "core/gimpcontainer.h" /* FIXME */ +#include "dialogs/dialogs.h" /* FIXME */ + #include "gimp-intl.h" @@ -277,8 +279,7 @@ static gboolean gimp_dock_delete_event (GtkWidget *widget, GdkEventAny *event) { - GimpDock *dock = GIMP_DOCK (widget); - gboolean retval = FALSE; + GimpDock *dock = GIMP_DOCK (widget); GList *list; gint n; @@ -287,39 +288,20 @@ gimp_dock_delete_event (GtkWidget *wid if (n > 1) { - GtkWidget *dialog = - gimp_message_dialog_new (_("Close all Tabs?"), - GIMP_STOCK_WARNING, - widget, GTK_DIALOG_MODAL, - NULL, NULL, - - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - _("Close all Tabs"), GTK_RESPONSE_OK, - - NULL); - - gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), - GTK_RESPONSE_OK, - GTK_RESPONSE_CANCEL, - -1); - - gimp_message_box_set_primary_text (GIMP_MESSAGE_DIALOG (dialog)->box, - _("Close all tabs?")); - - gimp_message_box_set_text (GIMP_MESSAGE_DIALOG (dialog)->box, - ngettext ("This window has %d tab open. " - "Closing the window will also close " - "all its tabs.", - "This window has %d tabs open. " - "Closing the window will also close " - "all its tabs.", n), n); + GimpSessionInfo *info = gimp_session_info_new (); + + gimp_object_set_name (GIMP_OBJECT (info), + gtk_window_get_title (GTK_WINDOW (widget))); - retval = (gimp_dialog_run (GIMP_DIALOG (dialog)) != GTK_RESPONSE_OK); + info->widget = widget; + gimp_session_info_get_info (info); + info->widget = NULL; - gtk_widget_destroy (dialog); + gimp_container_add (global_recent_docks, GIMP_OBJECT (info)); + g_object_unref (info); } - return retval; + return FALSE; } static void Index: menus/image-menu.xml.in =================================================================== --- menus/image-menu.xml.in (revision 25670) +++ menus/image-menu.xml.in (working copy) @@ -559,11 +559,7 @@ - - - - - +