1 /* -*- Mode: C; c-basic-offset: 4 -*- */
2 /* Dia -- an diagram creation/manipulation program
3 * Copyright (C) 1998-2000 Alexander Larsson
5 * recent_files.c: recent files menu dia
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 #include <gdk/gdkkeysyms.h>
38 #include "recent_files.h"
42 #include "interface.h"
43 #include "layer_dialog.h"
44 #include "preferences.h"
45 #include "../lib/filter.h"
46 #include "../lib/intl.h"
48 #include "persistence.h"
50 static GtkTooltips
*tooltips
= 0;
52 static void open_recent_file_callback (GtkWidget
*widget
, gpointer data
);
53 void recent_file_history_remove (const char *fname
);
56 recent_file_filemenu_get(void)
58 /* Use the Plugins menu item to get a pointer to the File menu,
59 but any item on the File menu will do */
61 return GTK_WIDGET(menus_get_item_from_path(N_("<Toolbox>/File/Plugins..."),
66 recent_file_history_clear_menu()
68 GtkWidget
*file_menu
= recent_file_filemenu_get();
69 GList
*menu_items
= GTK_MENU_SHELL(file_menu
)->children
;
72 for (;menu_items
!= NULL
; menu_items
= next_item
) {
74 next_item
= g_list_next(menu_items
);
75 item
= GTK_MENU_ITEM(menu_items
->data
);
76 if (g_signal_handler_find(G_OBJECT(item
), G_SIGNAL_MATCH_FUNC
,
77 0, 0, NULL
, open_recent_file_callback
, NULL
)) {
78 /* Unlink first, then destroy */
79 g_list_remove_link(GTK_MENU_SHELL(file_menu
)->children
,
81 gtk_widget_destroy(GTK_WIDGET(item
));
82 g_list_free_1(menu_items
);
87 /** Create a single menu item at position pos in the recent files list.
91 recent_file_menuitem_create(GtkWidget
*menu
, gchar
*filename
,
92 guint pos
, guint offset
)
94 gchar
*basename
, *label
;
96 GtkAccelGroup
*accel_group
;
97 /* FIXME: filename encoding, but we need utf-8 here */
98 basename
= g_path_get_basename(filename
);
100 label
= g_strdup_printf("%d. %s", pos
+1, basename
);
101 item
= gtk_menu_item_new_with_label(label
);
102 gtk_menu_insert(GTK_MENU(menu
), item
,
105 g_signal_connect(GTK_OBJECT(item
), "activate",
106 G_CALLBACK(open_recent_file_callback
), filename
);
108 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips
), item
,
113 accel_group
= gtk_accel_group_new();
114 gtk_window_add_accel_group(GTK_WINDOW(interface_get_toolbox_shell()),
116 gtk_widget_add_accelerator(item
, "activate", accel_group
,
118 GDK_CONTROL_MASK
, GTK_ACCEL_VISIBLE
);
121 gtk_widget_show(item
);
124 /* gtk_label_set_text() g_strdup's our label, so... */
128 /** Build and insert the recent files menu */
130 recent_file_history_make_menu()
134 GList
*items
= persistent_list_get_glist("recent-files");
136 GtkWidget
*file_menu
= recent_file_filemenu_get();
138 GtkMenuItem
*menu_item
=
139 menus_get_item_from_path(N_("<Toolbox>/File/Quit"), NULL
);
141 GList
*list_item
= g_list_find(GTK_MENU_SHELL(file_menu
)->children
,
142 (gpointer
)menu_item
);
144 int offset
= g_list_position(GTK_MENU_SHELL(file_menu
)->children
,
145 list_item
) - 1; /* fudge factor */
147 for (i
= 0; items
!= NULL
&& i
< prefs
.recent_documents_list_size
;
148 items
= g_list_next(items
), i
++) {
149 recent_file_menuitem_create(file_menu
, (gchar
*)items
->data
, i
, offset
);
153 /** Add a new item to the file history list.
154 * Since this only happens when a new files is opened, we can afford the
155 * time it takes to rebuild the menus, rather than messing around with
159 recent_file_history_add(const char *fname
)
161 gchar
*absname
= dia_get_absolute_filename(fname
);
162 gchar
*filename
= g_filename_to_utf8(absname
, -1, NULL
, NULL
, NULL
);
163 recent_file_history_clear_menu();
164 persistent_list_add("recent-files", filename
);
168 recent_file_history_make_menu();
171 /* load the recent file history */
173 recent_file_history_init()
175 prefs
.recent_documents_list_size
=
176 CLAMP(prefs
.recent_documents_list_size
, 0, 16);
178 tooltips
= gtk_tooltips_new();
180 persistence_register_list("recent-files");
182 recent_file_history_make_menu();
185 /* remove a broken file from the history and update menu accordingly
186 * Xing Wang, 2002.06 */
188 recent_file_history_remove (const char *fname
)
190 gchar
*absname
= dia_get_absolute_filename(fname
);
191 gchar
*filename
= g_filename_to_utf8(absname
, -1, NULL
, NULL
, NULL
);
192 recent_file_history_clear_menu();
194 persistent_list_remove("recent-files", filename
);
198 recent_file_history_make_menu();
202 open_recent_file_callback(GtkWidget
*widget
, gpointer data
)
204 DiaImportFilter
*ifilter
= NULL
;
205 Diagram
*diagram
= NULL
;
206 gchar
*filename
= g_filename_from_utf8((gchar
*)data
, -1, NULL
, NULL
, NULL
);
208 ifilter
= filter_guess_import_filter(filename
);
210 diagram
= diagram_load(filename
, ifilter
);
211 if (diagram
!= NULL
) {
212 diagram_update_extents(diagram
);
213 layer_dialog_set_diagram(diagram
);
214 new_display(diagram
);
216 recent_file_history_remove (filename
);