1 /* Dia -- an diagram creation/manipulation program
2  * Copyright (C) 1998 Alexander Larsson
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18 
19 /* Autosave */
20 
21 /* Automatically save a copy with the .autosave extension after idle time.
22  * Don't autosave unmodified diagrams, and remove the autosave file when
23  * the diagram is saved successfully.  Also remove autosave file when the
24  * diagram is closed, even if it was modified.
25  * If (auto)saving crashes you, this will really fuck you over!
26  *
27  */
28 
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32 
33 #include <stdio.h>
34 #include <sys/types.h>
35 #ifdef HAVE_UNISTD_H
36 #include <unistd.h>
37 #endif
38 
39 #include "intl.h"
40 #include "dia_dirs.h"
41 #include "diagram.h"
42 #include "load_save.h"
43 #include "dialogs.h"
44 #include <gtk/gtk.h>
45 
46 gboolean autosave_check_autosave(gpointer data);
47 
48 static void
autosave_save_diagram(gpointer data)49 autosave_save_diagram(gpointer data)
50 {
51   Diagram *dia = (Diagram *)data;
52 
53   g_idle_remove_by_data(data);
54 
55   diagram_autosave(dia);
56 }
57 
58 /** Makes autosave copies of the diagrams in the appropriate directory
59  * This function will be called after a diagram is modified, and will
60  * only save documents that are modified and not already autosaved,
61  * and only at the next idle period.
62  */
63 gboolean
autosave_check_autosave(gpointer data)64 autosave_check_autosave(gpointer data)
65 {
66   GList *diagrams = dia_open_diagrams();
67   Diagram *diagram;
68 
69   while (diagrams != NULL) {
70     diagram = (Diagram *)diagrams->data;
71     if (diagram_is_modified(diagram) &&
72 	!diagram->autosaved) {
73       /* Diagram has been modified.  At next idleness, save it */
74       g_idle_add ((GSourceFunc)autosave_save_diagram, diagram);
75     }
76     diagrams = g_list_next(diagrams);
77   }
78   return TRUE;
79 }
80 
81 /* This is old stuff for a restore dialog */
82 #if 0
83 /* Doesn't work with autosave files stored in the files dir */
84 
85 /** Create a dialog that asks for files to be restore */
86 static void
87 autosave_make_restore_dialog(GList *files)
88 {
89   GtkWidget *ok, *cancel;
90   GtkWidget *dialog = dialog_make(_("Recovering autosaved diagrams"),
91 				  NULL, NULL, &ok, &cancel);
92   GtkWidget *vbox = GTK_DIALOG(dialog)->vbox;
93   GtkWidget *selectarea = gtk_clist_new(1);
94   GList *iter;
95   gchar **filearray = (gchar**)g_new(gchar *, g_list_length(files)+1);
96   int i;
97 
98   gtk_box_pack_start_defaults(GTK_BOX(vbox), gtk_label_new(_("Autosaved files exist.\nPlease select those you wish to recover.")));
99 
100   for (i = 0, iter = files; iter != NULL; i++, iter = g_list_next(iter)) {
101     filearray[i] = (gchar *)iter->data;
102   }
103   filearray[i] = 0;
104   gtk_clist_append(GTK_CLIST(selectarea), filearray);
105 
106   gtk_box_pack_start_defaults(GTK_BOX(vbox), selectarea);
107   gtk_widget_show_all(dialog);
108 }
109 
110 /** If autosave files exist, ask the user if they should be restored
111  */
112 void
113 autosave_restore_documents(void)
114 {
115   gchar *savedir = dia_config_filename("autosave" G_DIR_SEPARATOR_S);
116   GDir *dir = g_dir_open(savedir, 0, NULL);
117   const char *ent;
118   GList *files = NULL;
119 
120   if (dir == NULL) return;
121   while ((ent = g_dir_read_name(dir)) != NULL) {
122     printf("Found autosave file %s\n", ent);
123     files = g_list_prepend(files, g_strdup(ent));
124   }
125 
126   if (files != NULL) {
127     autosave_make_restore_dialog(files);
128   }
129   g_dir_close(dir);
130   g_free(savedir);
131   g_list_free(files);
132 }
133 #endif
134