Commit ff5310a4 authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer

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
parent b236aa58
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
......
......@@ -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),
......
......@@ -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);
}
......@@ -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__ */
......@@ -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);
}
......@@ -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)
{
......
......@@ -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);
......
......@@ -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 *
......
......@@ -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__ */
......@@ -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;
}
......
......@@ -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;