UML class fix bigtime.
[dia.git] / app / recent_files.c
blob1e9e765d3b2d578d2accceb5166e1b987aefb317
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.
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
26 #ifdef GNOME
27 #include <gnome.h>
28 #else
29 #include <gdk/gdkkeysyms.h>
30 #endif
32 #include <glib.h>
33 #include <gtk/gtk.h>
34 #include <stdio.h>
35 #include <string.h>
37 #include "dia_dirs.h"
38 #include "recent_files.h"
39 #include "menus.h"
40 #include "diagram.h"
41 #include "display.h"
42 #include "interface.h"
43 #include "layer_dialog.h"
44 #include "preferences.h"
45 #include "../lib/filter.h"
46 #include "../lib/intl.h"
47 #include "message.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);
55 static GtkWidget *
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..."),
62 NULL))->parent;
65 static void
66 recent_file_history_clear_menu()
68 GtkWidget *file_menu = recent_file_filemenu_get();
69 GList *menu_items = GTK_MENU_SHELL(file_menu)->children;
70 GList *next_item;
72 for (;menu_items != NULL; menu_items = next_item) {
73 GtkMenuItem *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,
80 menu_items);
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.
88 * Pos starts from 0.
90 static void
91 recent_file_menuitem_create(GtkWidget *menu, gchar *filename,
92 guint pos, guint offset)
94 gchar *basename, *label;
95 GtkWidget *item;
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,
103 pos + offset);
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,
109 filename, NULL);
111 if (pos < 9)
113 accel_group = gtk_accel_group_new();
114 gtk_window_add_accel_group(GTK_WINDOW(interface_get_toolbox_shell()),
115 accel_group);
116 gtk_widget_add_accelerator(item, "activate", accel_group,
117 GDK_1 + pos,
118 GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
121 gtk_widget_show(item);
123 g_free(basename);
124 /* gtk_label_set_text() g_strdup's our label, so... */
125 g_free(label);
128 /** Build and insert the recent files menu */
129 static void
130 recent_file_history_make_menu()
132 guint i;
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
156 * moving them.
158 void
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);
165 g_free(absname);
166 g_free(filename);
168 recent_file_history_make_menu();
171 /* load the recent file history */
172 void
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 */
187 void
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);
195 g_free(absname);
196 g_free(filename);
198 recent_file_history_make_menu();
201 static void
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);
215 } else
216 recent_file_history_remove (filename);
217 g_free(filename);