Implement the presistent menu of recently closed docks, still somewhat

2008-05-16  Michael Natterer  <mitch@gimp.org>

	Implement the presistent menu of recently closed docks, still
	somewhat hackish but fully functional. Fixes bug #132744.

	* app/actions/dialogs-actions.c
	* app/actions/dialogs-commands.[ch]
	* menus/image-menu.xml.in: remove the menu items that were
	creating the hardcoded preconfigured docks.

	* app/dialogs/dialogs.[ch]: add GimpContainer of recently closed
	docks and API to load and save it.

	* app/gui/session.c: call the recent dock load and save functions.

	* app/widgets/gimpsessioninfo.[ch]: implement the GimpConfig interface
	and (de)serialize via proper interface methods.

	* app/gui/session.c
	* app/widgets/gimpdialogfactory.c: use the GimpConfig API
	to (de)serialize session infos and added the code that was
	formerly in the info's (de)serialize functions but didn't belong
	there.

	* app/widgets/gimpaction.[ch]: add "max-width-chars" property and
	set it on proxy menu item labels.

	* app/actions/windows-actions.[ch]
	* app/actions/windows-commands.[ch]
	* app/menus/windows-menu.c: add actions and menu of recently
	closed docks and code to restore the dock when the menu items are
	selected. Use above new action property to ensure a minimum
	width of the menu.

	* app/widgets/gimpmenudock.c: use '-' instead of '|' for
	separating notebooks in the window title. Menu items don't like	'|'.

	* app/widgets/gimpdock.c: removed the confirmation dialog when
	closing docks and simply add them to the recent docks container.
	This code is totally misplaced and will move to another file soon.


svn path=/trunk/; revision=25671
This commit is contained in:
Michael Natterer 2008-05-16 16:06:42 +00:00 committed by Michael Natterer
parent b236aa58ea
commit ff5310a4ea
19 changed files with 495 additions and 307 deletions

View File

@ -1,3 +1,44 @@
2008-05-16 Michael Natterer <mitch@gimp.org>
Implement the presistent menu of recently closed docks, still
somewhat hackish but fully functional. Fixes bug #132744.
* app/actions/dialogs-actions.c
* app/actions/dialogs-commands.[ch]
* menus/image-menu.xml.in: remove the menu items that were
creating the hardcoded preconfigured docks.
* app/dialogs/dialogs.[ch]: add GimpContainer of recently closed
docks and API to load and save it.
* app/gui/session.c: call the recent dock load and save functions.
* app/widgets/gimpsessioninfo.[ch]: implement the GimpConfig interface
and (de)serialize via proper interface methods.
* app/gui/session.c
* app/widgets/gimpdialogfactory.c: use the GimpConfig API
to (de)serialize session infos and added the code that was
formerly in the info's (de)serialize functions but didn't belong
there.
* app/widgets/gimpaction.[ch]: add "max-width-chars" property and
set it on proxy menu item labels.
* app/actions/windows-actions.[ch]
* app/actions/windows-commands.[ch]
* app/menus/windows-menu.c: add actions and menu of recently
closed docks and code to restore the dock when the menu items are
selected. Use above new action property to ensure a minimum
width of the menu.
* app/widgets/gimpmenudock.c: use '-' instead of '|' for
separating notebooks in the window title. Menu items don't like '|'.
* app/widgets/gimpdock.c: removed the confirmation dialog when
closing docks and simply add them to the recent docks container.
This code is totally misplaced and will move to another file soon.
2008-05-14 Sven Neumann <sven@gimp.org>
* app/core/gimpcurve.c (gimp_curve_plot): don't write over the end

View File

@ -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 dialogs_toplevel_actions[] =
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),

View File

@ -18,20 +18,13 @@
#include "config.h"
#include <string.h>
#include <gtk/gtk.h>
#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 (GtkAction *action,
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);
}

View File

@ -27,12 +27,5 @@ void dialogs_create_dockable_cmd_callback (GtkAction *action,
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__ */

View File

@ -66,6 +66,13 @@ static void windows_actions_dock_notify (GimpDock *dock,
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[] =
{
@ -90,6 +97,8 @@ windows_actions_setup (GimpActionGroup *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 +131,22 @@ windows_actions_setup (GimpActionGroup *group)
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 +330,72 @@ windows_actions_dock_notify (GimpDock *dock,
"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;
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,
"max-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);
}

View File

@ -24,7 +24,10 @@
#include "actions-types.h"
#include "core/gimpcontainer.h"
#include "widgets/gimpdialogfactory.h"
#include "widgets/gimpsessioninfo.h"
#include "display/gimpdisplay.h"
@ -60,6 +63,22 @@ windows_show_dock_cmd_callback (GtkAction *action,
gtk_window_present (dock);
}
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)
{

View File

@ -26,6 +26,8 @@ void windows_show_display_cmd_callback (GtkAction *action,
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);

View File

@ -20,16 +20,20 @@
#include <gtk/gtk.h>
#include "libgimpbase/gimpbase.h"
#include "libgimpconfig/gimpconfig.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "dialogs-types.h"
#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 +46,8 @@ GimpDialogFactory *global_dock_factory = NULL;
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 +307,8 @@ dialogs_init (Gimp *gimp,
TRUE,
TRUE,
FALSE);
global_recent_docks = gimp_list_new (GIMP_TYPE_SESSION_INFO, FALSE);
}
void
@ -337,6 +345,64 @@ 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;
}
}
void
dialogs_load_recent_docks (Gimp *gimp)
{
gchar *filename;
GError *error = NULL;
g_return_if_fail (GIMP_IS_GIMP (gimp));
filename = gimp_personal_rc_file ("dockrc");
if (gimp->be_verbose)
g_print ("Parsing '%s'\n", gimp_filename_to_utf8 (filename));
if (! gimp_config_deserialize_file (GIMP_CONFIG (global_recent_docks),
filename,
NULL, &error))
{
if (error->code != GIMP_CONFIG_ERROR_OPEN_ENOENT)
gimp_message (gimp, NULL, GIMP_MESSAGE_ERROR, "%s", error->message);
g_clear_error (&error);
}
g_free (filename);
}
void
dialogs_save_recent_docks (Gimp *gimp)
{
gchar *filename;
GError *error = NULL;
g_return_if_fail (GIMP_IS_GIMP (gimp));
filename = gimp_personal_rc_file ("dockrc");
if (gimp->be_verbose)
g_print ("Writing '%s'\n", gimp_filename_to_utf8 (filename));
if (! gimp_config_serialize_to_file (GIMP_CONFIG (global_recent_docks),
filename,
"recently closed docks",
"end of recently closed docks",
NULL, &error))
{
gimp_message (gimp, NULL, GIMP_MESSAGE_ERROR, "%s", error->message);
g_clear_error (&error);
}
g_free (filename);
}
GtkWidget *

View File

@ -25,12 +25,17 @@ extern GimpDialogFactory *global_dock_factory;
extern GimpDialogFactory *global_toolbox_factory;
extern GimpDialogFactory *global_display_factory;
extern GimpContainer *global_recent_docks;
void dialogs_init (Gimp *gimp,
GimpMenuFactory *menu_factory);
void dialogs_exit (Gimp *gimp);
GtkWidget * dialogs_get_toolbox (void);
void dialogs_init (Gimp *gimp,
GimpMenuFactory *menu_factory);
void dialogs_exit (Gimp *gimp);
void dialogs_load_recent_docks (Gimp *gimp);
void dialogs_save_recent_docks (Gimp *gimp);
GtkWidget * dialogs_get_toolbox (void);
#endif /* __DIALOGS_H__ */

View File

@ -48,6 +48,8 @@
#include "widgets/gimpdialogfactory.h"
#include "widgets/gimpsessioninfo.h"
#include "dialogs/dialogs.h"
#include "session.h"
#include "gimp-intl.h"
@ -124,13 +126,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))
{
@ -170,6 +214,8 @@ session_init (Gimp *gimp)
gimp_scanner_destroy (scanner);
g_free (filename);
dialogs_load_recent_docks (gimp);
}
void
@ -237,6 +283,8 @@ session_save (Gimp *gimp,
g_clear_error (&error);
}
dialogs_save_recent_docks (gimp);
sessionrc_deleted = FALSE;
}

View File

@ -59,6 +59,13 @@ static void windows_menu_dock_removed (GimpDialogFactory *factory,
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 *manager,
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 (GimpDialogFactory *factory,
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);
}

View File

@ -47,7 +47,8 @@ enum
PROP_CONTEXT,
PROP_COLOR,
PROP_VIEWABLE,
PROP_ELLIPSIZE
PROP_ELLIPSIZE,
PROP_MAX_WIDTH_CHARS
};
@ -110,6 +111,12 @@ gimp_action_class_init (GimpActionClass *klass)
PANGO_TYPE_ELLIPSIZE_MODE,
PANGO_ELLIPSIZE_NONE,
GIMP_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_MAX_WIDTH_CHARS,
g_param_spec_int ("max-width-chars",
NULL, NULL,
-1, G_MAXINT, -1,
GIMP_PARAM_READWRITE));
}
static void
@ -168,6 +175,9 @@ gimp_action_get_property (GObject *object,
case PROP_ELLIPSIZE:
g_value_set_enum (value, action->ellipsize);
break;
case PROP_MAX_WIDTH_CHARS:
g_value_set_int (value, action->max_width_chars);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -207,6 +217,10 @@ gimp_action_set_property (GObject *object,
action->ellipsize = g_value_get_enum (value);
set_proxy = TRUE;
break;
case PROP_MAX_WIDTH_CHARS:
action->max_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,14 @@ gimp_action_set_proxy (GimpAction *action,
}
{
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);
gtk_label_set_ellipsize (label, action->ellipsize);
gtk_label_set_max_width_chars (label, action->max_width_chars);
}
}
}

View File

@ -45,6 +45,7 @@ struct _GimpAction
GimpRGB *color;
GimpViewable *viewable;
PangoEllipsizeMode ellipsize;
gint max_width_chars;
};
struct _GimpActionClass

View File

@ -2,7 +2,7 @@
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpdialogfactory.c
* Copyright (C) 2001 Michael Natterer <mitch@gimp.org>
* Copyright (C) 2001-2008 Michael Natterer <mitch@gimp.org>
*
* 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 <gtk/gtk.h>
#include "libgimpconfig/gimpconfig.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "widgets-types.h"
@ -913,7 +914,7 @@ gimp_dialog_factory_add_dialog (GimpDialogFactory *factory,
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 (GtkWidget *dialog,
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 (GtkWidget *dialog,
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 (gconstpointer key,
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);

View File

@ -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 *widget,
if (n > 1)
{
GtkWidget *dialog =
gimp_message_dialog_new (_("Close all Tabs?"),
GIMP_STOCK_WARNING,
widget, GTK_DIALOG_MODAL,
NULL, NULL,
GimpSessionInfo *info = gimp_session_info_new ();
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
_("Close all Tabs"), GTK_RESPONSE_OK,
gimp_object_set_name (GIMP_OBJECT (info),
gtk_window_get_title (GTK_WINDOW (widget)));
NULL);
info->widget = widget;
gimp_session_info_get_info (info);
info->widget = 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);
retval = (gimp_dialog_run (GIMP_DIALOG (dialog)) != GTK_RESPONSE_OK);
gtk_widget_destroy (dialog);
gimp_container_add (global_recent_docks, GIMP_OBJECT (info));
g_object_unref (info);
}
return retval;
return FALSE;
}
static void

View File

@ -501,7 +501,7 @@ gimp_menu_dock_update_title_idle (GimpMenuDock *menu_dock)
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);

View File

@ -2,7 +2,7 @@
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpsessioninfo.c
* Copyright (C) 2001-2007 Michael Natterer <mitch@gimp.org>
* Copyright (C) 2001-2008 Michael Natterer <mitch@gimp.org>
*
* 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);
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 (GimpSessionInfo, gimp_session_info, GIMP_TYPE_OBJECT)
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 (GimpSessionInfoClass *klass)
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 (GimpObject *object,
gui_size);
}
/* public functions */
GimpSessionInfo *
gimp_session_info_new (void)
static gboolean
gimp_session_info_serialize (GimpConfig *config,
GimpConfigWriter *writer,
gpointer data)
{
return g_object_new (GIMP_TYPE_SESSION_INFO, NULL);
}
void
gimp_session_info_serialize (GimpConfigWriter *writer,
GimpSessionInfo *info,
const gchar *factory_name)
{
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);
@ -149,16 +147,13 @@ gimp_session_info_serialize (GimpConfigWriter *writer,
gimp_config_writer_close (writer);
}
if (info->widget)
{
if (info->aux_info)
gimp_session_info_aux_serialize (writer, info->aux_info);
if (info->aux_info)
gimp_session_info_aux_serialize (writer, info->aux_info);
if (info->books)
gimp_session_info_dock_serialize (writer, info->books);
}
if (info->books)
gimp_session_info_dock_serialize (writer, info->books);
gimp_config_writer_close (writer); /* session-info */
return TRUE;
}
/*
@ -193,57 +188,31 @@ gimp_session_info_parse_offset (GScanner *scanner,
return TRUE;
}
GTokenType
gimp_session_info_deserialize (GScanner *scanner,
gint scope)
static gboolean
gimp_session_info_deserialize (GimpConfig *config,
GScanner *scanner,
gint nest_level,
gpointer data)
{
GimpDialogFactory *factory;
GimpSessionInfo *info = NULL;
GTokenType token;
gboolean skip = FALSE;
gchar *factory_name;
gchar *entry_name;
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 +271,12 @@ gimp_session_info_deserialize (GScanner *scanner,
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 +297,26 @@ gimp_session_info_deserialize (GScanner *scanner,
}
}
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_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");
g_scanner_set_scope (scanner, old_scope_id);
return token;
return gimp_config_deserialize_return (scanner, token, nest_level);
}
/* public functions */
GimpSessionInfo *
gimp_session_info_new (void)
{
return g_object_new (GIMP_TYPE_SESSION_INFO, NULL);
}
void

View File

@ -74,12 +74,6 @@ GType gimp_session_info_get_type (void) G_GNUC_CONST;
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);

View File

@ -559,11 +559,7 @@
</menu>
<menu action="windows-menu" name="Windows">
<menu action="windows-docks-menu" name="Recent Docks">
<menuitem action="dialogs-new-dock-lcp" />
<menuitem action="dialogs-new-dock-data" />
<menuitem action="dialogs-new-dock-stuff" />
</menu>
<menu action="windows-docks-menu" name="Recently Closed Docks" />
<menu action="windows-dialogs-menu" name="Dockable Dialogs">
<xi:include href="dialogs-menuitems.xml" />
</menu>