history.c 9 KB
Newer Older
Michael Meeks's avatar
Michael Meeks committed
1 2 3 4 5 6 7
/*
 * History.c: Implements file menu file history
 *
 * Author:
 *  Mike Kestner (mkestner@ameritech.net)
 *
 */
8 9 10
#include <gnumeric-config.h>
#include "gnumeric.h"
#include "history.h"
Michael Meeks's avatar
Michael Meeks committed
11 12

#include "application.h"
13 14
#include "workbook-control-gui-priv.h"
#include "workbook-view.h"
Michael Meeks's avatar
Michael Meeks committed
15
#include "workbook.h"
16

Jody Goldberg's avatar
Jody Goldberg committed
17
#include <gtk/gtkmenuitem.h>
Jody Goldberg's avatar
fix.  
Jody Goldberg committed
18
#include <libgnome/gnome-i18n.h>
Jody Goldberg's avatar
Jody Goldberg committed
19
#include <libgnomeui/gnome-app-helper.h>
20
#ifdef WITH_BONOBO
21 22
#include <bonobo.h>
#endif
Michael Meeks's avatar
Michael Meeks committed
23 24

/* Command callback called on activation of a file history menu item. */
25
#ifndef WITH_BONOBO
Michael Meeks's avatar
Michael Meeks committed
26 27 28 29

#define UGLY_GNOME_UI_KEY "HistoryFilename"

static void
30
file_history_cmd (GtkWidget *widget, WorkbookControlGUI *wbcg)
Michael Meeks's avatar
Michael Meeks committed
31
{
32
	gchar *filename = gtk_object_get_data (GTK_OBJECT (widget), UGLY_GNOME_UI_KEY);
33
	(void) wb_view_open (wb_control_view (WORKBOOK_CONTROL (wbcg)),
34
	                     WORKBOOK_CONTROL (wbcg), filename, TRUE);
Michael Meeks's avatar
Michael Meeks committed
35 36 37 38
}

#else
static void
39
file_history_cmd (BonoboUIComponent *uic, WorkbookControlGUI *wbcg, const char *path)
Michael Meeks's avatar
Michael Meeks committed
40
{
41 42 43
	char *fullpath = g_strconcat ("/menu/File/FileHistory/", path, NULL);
	char *filename = bonobo_ui_component_get_prop (wbcg->uic, fullpath,
						       "tip", NULL);
Michael Meeks's avatar
Michael Meeks committed
44

45
	g_free (fullpath);
46
	(void) wb_view_open (wb_control_view (WORKBOOK_CONTROL (wbcg)),
47
	                     WORKBOOK_CONTROL (wbcg), filename, TRUE);
Morten Welinder's avatar
Morten Welinder committed
48
	g_free (filename);
Michael Meeks's avatar
Michael Meeks committed
49 50 51
}
#endif

52
/*
53
 * Returns a newly allocated string containing the base name of the file
54
 * with any .gnumeric extension stripped off.
55
 */
Michael Meeks's avatar
Michael Meeks committed
56
static gchar*
57
history_item_label (const gchar *name, const gint accel_number)
Michael Meeks's avatar
Michael Meeks committed
58 59
{
	int   i;
60 61 62 63 64 65 66 67 68
	char *label, *menuname, *tmp;

	/* Translate '_' to '-' so menu will not show underline.  */
	menuname = g_strdup (g_basename (name));
	for (tmp = menuname; *tmp; tmp++)
		if (*tmp == '_')
			*tmp = '-';
	label = g_strdup_printf ("_%d %s", accel_number, menuname);
	g_free (menuname);
Michael Meeks's avatar
Michael Meeks committed
69

70 71
	for (i = strlen (label) - 1; i >= 0; i--)
		if (label [i] == '.') {
Jon K Hellan's avatar
Jon K Hellan committed
72 73
			if (strcmp (label + i, ".gnumeric") == 0)
				label [i] = '\0';
Michael Meeks's avatar
Michael Meeks committed
74 75 76
			break;
		}

77
	return label;
Michael Meeks's avatar
Michael Meeks committed
78 79
}

80 81 82
/*
 * Create a history menu item in a menu at a given position.
 */
83
#ifndef WITH_BONOBO
Michael Meeks's avatar
Michael Meeks committed
84
static void
85
history_menu_item_create (WorkbookControlGUI *wbcg, gchar *name, gint accel_number,
86
			  GtkWidget *menu, gint pos)
Michael Meeks's avatar
Michael Meeks committed
87
{
Jody Goldberg's avatar
Jody Goldberg committed
88
	char *label;
Michael Meeks's avatar
Michael Meeks committed
89
	GnomeUIInfo info[] = {
90
		{ GNOME_APP_UI_ITEM, NULL, NULL, file_history_cmd, NULL },
Michael Meeks's avatar
Michael Meeks committed
91 92 93
		GNOMEUIINFO_END
	};

94
	info [0].hint = name;
Jody Goldberg's avatar
Jody Goldberg committed
95
	info [0].label = label = history_item_label (name, accel_number);
96
	info [0].user_data = wbcg;
Michael Meeks's avatar
Michael Meeks committed
97

98
	gnome_app_fill_menu (GTK_MENU_SHELL (menu), info,
99
			     GNOME_APP (wbcg->toplevel)->accel_group, TRUE,
100
			     pos);
Jody Goldberg's avatar
Jody Goldberg committed
101
	gtk_object_set_data (GTK_OBJECT (info [0].widget), UGLY_GNOME_UI_KEY, name);
102
	gnome_app_install_menu_hints (GNOME_APP (wbcg->toplevel), info);
Michael Meeks's avatar
Michael Meeks committed
103

Jody Goldberg's avatar
Jody Goldberg committed
104
	g_free (label);
Michael Meeks's avatar
Michael Meeks committed
105
}
106
#endif
Michael Meeks's avatar
Michael Meeks committed
107

108
#ifndef WITH_BONOBO
109 110 111 112
typedef struct {
	GtkWidget *menu;
	gint      pos;
} MenuPos;
Michael Meeks's avatar
Michael Meeks committed
113

114 115 116 117 118 119 120
/*
 * Locate the menu and position of history separator. They may not yet exist.
 *
 * NOTE:
 * gnome_app_find_menu_pos returns the position *after* the menu item given.
 * bonobo_ui_handler_menu_get_pos returns the position *of* the menu item.
 */
Jody Goldberg's avatar
Jody Goldberg committed
121 122
static void
history_menu_locate_separator (WorkbookControlGUI *wbcg, MenuPos *res)
123
{
124 125 126
/*
 * xgettext:
 * This string must translate to exactly the same strings as the
127
 * 'Print Preview...' item in the
128 129
 * 'File' menu
 */
Jody Goldberg's avatar
Jody Goldberg committed
130 131 132 133 134 135 136
	char const *menu_name = _("_File/Print Pre_view...");
	res->menu = gnome_app_find_menu_pos (GNOME_APP (wbcg->toplevel)->menubar,
					    menu_name, &res->pos);
	if (res->menu == NULL)
		g_warning ("Probable mis-translation. '%s' : was not found. "
			   "Does this match the '_File/Print Pre_view...' menu exactly ?",
			   menu_name);
137
}
Michael Meeks's avatar
Michael Meeks committed
138

139
/* Insert the history separator. Return its position.  */
Jody Goldberg's avatar
Jody Goldberg committed
140 141
static void
history_menu_insert_separator (WorkbookControlGUI *wbcg, MenuPos *res)
142 143 144
{
	GtkWidget *item;

Jody Goldberg's avatar
Jody Goldberg committed
145 146
	history_menu_locate_separator (wbcg, res);
	if (res->menu != NULL) {
Jody Goldberg's avatar
Jody Goldberg committed
147 148
		item = gtk_menu_item_new ();
		gtk_widget_show (item);
Jody Goldberg's avatar
Jody Goldberg committed
149
		gtk_menu_shell_insert (GTK_MENU_SHELL (res->menu), item, res->pos);
150
		gtk_widget_set_sensitive(item, FALSE);
Jody Goldberg's avatar
Jody Goldberg committed
151
	}
152 153 154 155 156 157
}

/*
 * Add the history items list to the file menu for the workbook specified.
 */
static void
158
history_menu_insert_items (WorkbookControlGUI *wbcg, GList *name_list, MenuPos *mp)
159 160 161 162 163
{
	gint  accel_number;
	GList *l;

	g_return_if_fail (name_list != NULL);
Michael Meeks's avatar
Michael Meeks committed
164 165

	/* Add a new menu item for each item in the history list */
166
	accel_number = 1;
Michael Meeks's avatar
Michael Meeks committed
167
	for (l = name_list; l; l = l->next)
168
		history_menu_item_create (wbcg, (gchar *)l->data, accel_number++,
169
					  mp->menu, (mp->pos)++);
170
}
171
#else
172
static void
173
history_menu_insert_items (WorkbookControlGUI *wbcg, GList *name_list)
174 175 176 177 178 179
{
	CORBA_Environment ev;
	gint  accel_number;
	GList *l;

	g_return_if_fail (name_list != NULL);
180

181
	CORBA_exception_init (&ev);
182

183 184
	/* Add a new menu item for each item in the history list */
	accel_number = 1;
185
	bonobo_ui_component_freeze (wbcg->uic, &ev);
186
	for (l = name_list; l; l = l->next) {
187
		char *id, *str, *label, *filename;
188

189
		id = g_strdup_printf ("FileHistory%d", accel_number);
190 191 192 193
		str = history_item_label (l->data, accel_number);
		label = bonobo_ui_util_encode_str (str);
		g_free (str);
		filename = bonobo_ui_util_encode_str ((char *) l->data);
194 195 196
		str = g_strdup_printf ("<menuitem name=\"%s\" "
				       "verb=\"%s\" "
				       "label=\"%s\" "
197
				       "tip=\"%s\"/>\n",
198
				       id, id, label, filename);
199
		bonobo_ui_component_set (wbcg->uic,
200 201
					 "/menu/File/FileHistory", str, &ev);
		bonobo_ui_component_add_verb (
202
			wbcg->uic, id, (BonoboUIVerbFn) file_history_cmd, wbcg);
203
		g_free (id);
204
		g_free (str);
205
		g_free (filename);
206
		g_free (label);
207
		accel_number++;
208
	}
209
	bonobo_ui_component_thaw (wbcg->uic, &ev);
210
	CORBA_exception_free (&ev);
Michael Meeks's avatar
Michael Meeks committed
211
}
212
#endif
Michael Meeks's avatar
Michael Meeks committed
213

214
#ifndef WITH_BONOBO
215 216 217 218 219
/*
 * Remove the history list items from the file menu of the workbook
 * specified.
 */
static void
220
history_menu_remove_items (WorkbookControlGUI *wbcg, GList *name_list)
221 222
{
	gint  accel_number = 1;
Michael Meeks's avatar
Michael Meeks committed
223

224
	if (name_list) {
225 226
		char *label, *path;

227 228
		label = history_item_label ((gchar *)name_list->data, accel_number);
		path = g_strconcat (_("File/"), label, NULL);
229
		gnome_app_remove_menus (GNOME_APP (wbcg->toplevel), path,
230
					g_list_length (name_list));
Morten Welinder's avatar
Leaks.  
Morten Welinder committed
231 232
		g_free (label);
		g_free (path);
233
	}
234 235
}

Michael Meeks's avatar
Michael Meeks committed
236
#else
237 238 239 240 241
/*
 * Remove the history list items from the file menu of the workbook
 * specified.
 */
static void
242
history_menu_remove_items (WorkbookControlGUI *wbcg, GList *name_list)
243 244 245 246 247
{
	gint  accel_number = 1;
	GList *l;
	CORBA_Environment ev;

248
	CORBA_exception_init (&ev);
249
	bonobo_ui_component_freeze (wbcg->uic, &ev);
250
	for (l = name_list; l; l = l->next) {
251 252
		char *path;

253 254
		path = g_strdup_printf ("/menu/File/FileHistory/FileHistory%d",
					accel_number++);
255
		bonobo_ui_component_rm (wbcg->uic,
256
					path, &ev);
257
		g_free (path);
Michael Meeks's avatar
Michael Meeks committed
258
	}
259
	bonobo_ui_component_thaw (wbcg->uic, &ev);
260
	CORBA_exception_free (&ev);
Michael Meeks's avatar
Michael Meeks committed
261
}
262
#endif
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278

/*
 * Remove the history list items from the file menus of all workbooks.
 *
 * All changes require that the list is removed and a new one built, because we
 * add a digit in front of the file name.
 */
void
history_menu_flush (GList *wl, GList *name_list)
{
	GList *l;

	/* Update the menus in all open workbooks */
	for (l = wl; l; l = g_list_next (l)) {
		Workbook  *wb = WORKBOOK (l->data);

279 280 281 282
		WORKBOOK_FOREACH_CONTROL (wb, view, control,
		{
			/* ICK : Should this be virtual ?
			 * seems too specific to do that.
283
			 * kludge for now
284 285 286 287
			 */
			if (IS_WORKBOOK_CONTROL_GUI (control))
				history_menu_remove_items (WORKBOOK_CONTROL_GUI (control), name_list);
		});
288 289
	}
}
290 291 292 293
/*
 * Add the items contained in name list to the file menu for the app
 * specified.
 */
Michael Meeks's avatar
Michael Meeks committed
294
void
295
history_menu_setup (WorkbookControlGUI *wbcg, GList *name_list)
Michael Meeks's avatar
Michael Meeks committed
296
{
297
	g_return_if_fail (name_list != NULL);
Michael Meeks's avatar
Michael Meeks committed
298

299
#ifdef WITH_BONOBO
300
	/* Insert the items */
301
	history_menu_insert_items (wbcg, name_list);
302 303 304 305
#else
	{
	MenuPos   mp;

306
	/* Insert separator and get its position */
Jody Goldberg's avatar
Jody Goldberg committed
307
	history_menu_insert_separator (wbcg, &mp);
308 309
	(mp.pos)++;
	/* Insert the items */
310
	history_menu_insert_items (wbcg, name_list, &mp);
311 312
	}
#endif
313
}
Michael Meeks's avatar
Michael Meeks committed
314

315 316 317 318 319 320 321 322 323 324 325 326
/*
 * A quick utility routine.  This could be a virtual in wb-control.
 * but the code is too messy to both with just now.
 */
static void
history_control_fill (WorkbookControl *control, GList *name_list, gboolean need_sep)
{
	if (IS_WORKBOOK_CONTROL_GUI (control)) {
		WorkbookControlGUI *wbcg = WORKBOOK_CONTROL_GUI (control);
		if (need_sep)
			history_menu_setup (wbcg, name_list);
		else {
327
#ifndef WITH_BONOBO
328
			MenuPos mp;
Jody Goldberg's avatar
Jody Goldberg committed
329
			history_menu_locate_separator (wbcg, &mp);
330 331 332 333 334 335 336 337 338
			(mp.pos)++;
			/* Insert the items */
			history_menu_insert_items (wbcg, name_list, &mp);
#else
			history_menu_insert_items (wbcg, name_list);
#endif
		}
	}
}
339 340 341 342 343 344 345 346 347
/*
 * Make the menus for the workbooks in wl show the new history list. If this is
 * the first history item, need_sep should be set to cause a separator to be
 * added as well.
 *
 * Precondition - the old entries have been removed with history_menu_flush.
 */
void
history_menu_fill (GList *wl, GList *name_list,  gboolean need_sep)
348
{
349
	GList *l;
350

351 352
	/* Update the menus in all open workbooks */
	for (l = wl; l; l = g_list_next (l)) {
353 354 355
		Workbook *wb = WORKBOOK (l->data);
		WORKBOOK_FOREACH_CONTROL (wb, view, control,
			history_control_fill (control, name_list, need_sep););
Michael Meeks's avatar
Michael Meeks committed
356 357
	}
}