This source file includes following definitions.
- file_history_list_read
- file_history_list_write
- file_history_create_item
- file_history_release_item
- file_history_free_item
- show_file_history
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #include <config.h>
27
28 #include <stdio.h>
29
30 #include "lib/global.h"
31
32 #include "lib/fileloc.h"
33 #include "lib/mcconfig.h"
34 #include "lib/strutil.h"
35 #include "lib/util.h"
36
37 #include "file_history.h"
38
39
40
41
42
43 #define TMP_SUFFIX ".tmp"
44
45
46
47 typedef struct file_history_data_t
48 {
49 char *file_name;
50 char *file_pos;
51 } file_history_data_t;
52
53
54
55
56
57
58
59 static GList *
60 file_history_list_read (void)
61 {
62 char *fn;
63 FILE *f;
64 char buf[MC_MAXPATHLEN + 100];
65 GList *file_list = NULL;
66
67
68 fn = mc_config_get_full_path (MC_FILEPOS_FILE);
69 if (fn == NULL)
70 return NULL;
71
72 f = fopen (fn, "r");
73 g_free (fn);
74 if (f == NULL)
75 return NULL;
76
77 while (fgets (buf, sizeof (buf), f) != NULL)
78 {
79 char *s;
80 file_history_data_t *fhd;
81 size_t len;
82
83 s = strrchr (buf, ' ');
84
85 fhd = g_new (file_history_data_t, 1);
86 fhd->file_name = g_strndup (buf, s - buf);
87 len = strlen (s + 1);
88 fhd->file_pos = g_strndup (s + 1, len - 1);
89 file_list = g_list_prepend (file_list, fhd);
90 }
91
92 fclose (f);
93
94 return file_list;
95 }
96
97
98
99 static void
100 file_history_list_write (const GList * file_list)
101 {
102 char *fn;
103 FILE *f;
104 gboolean write_error = FALSE;
105
106 fn = mc_config_get_full_path (MC_FILEPOS_FILE);
107 if (fn == NULL)
108 return;
109
110 mc_util_make_backup_if_possible (fn, TMP_SUFFIX);
111
112 f = fopen (fn, "w");
113 if (f != NULL)
114 {
115 GString *s;
116
117 s = g_string_sized_new (128);
118
119 for (; file_list != NULL && !write_error; file_list = g_list_next (file_list))
120 {
121 file_history_data_t *fhd = (file_history_data_t *) file_list->data;
122
123 g_string_append (s, fhd->file_name);
124 if (fhd->file_pos != NULL)
125 {
126 g_string_append_c (s, ' ');
127 g_string_append (s, fhd->file_pos);
128 }
129
130 write_error = (fprintf (f, "%s\n", s->str) < 0);
131 g_string_truncate (s, 0);
132 }
133
134 g_string_free (s, TRUE);
135
136 fclose (f);
137 }
138
139 if (write_error)
140 mc_util_restore_from_backup_if_possible (fn, TMP_SUFFIX);
141 else
142 mc_util_unlink_backup_if_possible (fn, TMP_SUFFIX);
143
144 g_free (fn);
145 }
146
147
148
149 static void
150 file_history_create_item (history_descriptor_t * hd, void *data)
151 {
152 file_history_data_t *fhd = (file_history_data_t *) data;
153 size_t width;
154
155 width = str_term_width1 (fhd->file_name);
156 hd->max_width = MAX (width, hd->max_width);
157
158 listbox_add_item (hd->listbox, LISTBOX_APPEND_AT_END, 0, fhd->file_name, fhd->file_pos, TRUE);
159
160 fhd->file_pos = NULL;
161 }
162
163
164
165 static void *
166 file_history_release_item (history_descriptor_t * hd, WLEntry * le)
167 {
168 file_history_data_t *fhd;
169
170 (void) hd;
171
172 fhd = g_new (file_history_data_t, 1);
173 fhd->file_name = le->text;
174 le->text = NULL;
175 fhd->file_pos = (char *) le->data;
176 le->data = NULL;
177
178 return fhd;
179 }
180
181
182
183 static void
184 file_history_free_item (void *data)
185 {
186 file_history_data_t *fhd = (file_history_data_t *) data;
187
188 g_free (fhd->file_name);
189 g_free (fhd->file_pos);
190 g_free (fhd);
191 }
192
193
194
195
196
197
198
199
200
201
202
203
204
205 char *
206 show_file_history (const Widget * w, int *action)
207 {
208 GList *file_list;
209 size_t len;
210 history_descriptor_t hd;
211
212 file_list = file_history_list_read ();
213 if (file_list == NULL)
214 return NULL;
215
216 len = g_list_length (file_list);
217
218 file_list = g_list_last (file_list);
219
220 history_descriptor_init (&hd, w->rect.y, w->rect.x, file_list, 0);
221
222 hd.create = file_history_create_item;
223 hd.release = file_history_release_item;
224 hd.free = file_history_free_item;
225
226 history_show (&hd);
227
228 hd.list = g_list_first (hd.list);
229
230
231 if (len != g_list_length (hd.list))
232 {
233 hd.list = g_list_reverse (hd.list);
234 file_history_list_write (hd.list);
235 }
236
237 g_list_free_full (hd.list, (GDestroyNotify) file_history_free_item);
238
239 *action = hd.action;
240
241 return hd.text;
242 }
243
244