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
60
61 static GList *
62 file_history_list_read (void)
63 {
64 char *fn;
65 FILE *f;
66 char buf[MC_MAXPATHLEN + 100];
67 GList *file_list = NULL;
68
69
70 fn = mc_config_get_full_path (MC_FILEPOS_FILE);
71 if (fn == NULL)
72 return NULL;
73
74 f = fopen (fn, "r");
75 g_free (fn);
76 if (f == NULL)
77 return NULL;
78
79 while (fgets (buf, sizeof (buf), f) != NULL)
80 {
81 char *s;
82 file_history_data_t *fhd;
83 size_t len;
84
85 s = strrchr (buf, ' ');
86
87 fhd = g_new (file_history_data_t, 1);
88 fhd->file_name = g_strndup (buf, s - buf);
89 len = strlen (s + 1);
90 fhd->file_pos = g_strndup (s + 1, len - 1);
91 file_list = g_list_prepend (file_list, fhd);
92 }
93
94 fclose (f);
95
96 return file_list;
97 }
98
99
100
101 static void
102 file_history_list_write (const GList *file_list)
103 {
104 char *fn;
105 FILE *f;
106 gboolean write_error = FALSE;
107
108 fn = mc_config_get_full_path (MC_FILEPOS_FILE);
109 if (fn == NULL)
110 return;
111
112 mc_util_make_backup_if_possible (fn, TMP_SUFFIX);
113
114 f = fopen (fn, "w");
115 if (f != NULL)
116 {
117 GString *s;
118
119 s = g_string_sized_new (128);
120
121 for (; file_list != NULL && !write_error; file_list = g_list_next (file_list))
122 {
123 file_history_data_t *fhd = (file_history_data_t *) file_list->data;
124
125 g_string_append (s, fhd->file_name);
126 if (fhd->file_pos != NULL)
127 {
128 g_string_append_c (s, ' ');
129 g_string_append (s, fhd->file_pos);
130 }
131
132 write_error = (fprintf (f, "%s\n", s->str) < 0);
133 g_string_truncate (s, 0);
134 }
135
136 g_string_free (s, TRUE);
137
138 fclose (f);
139 }
140
141 if (write_error)
142 mc_util_restore_from_backup_if_possible (fn, TMP_SUFFIX);
143 else
144 mc_util_unlink_backup_if_possible (fn, TMP_SUFFIX);
145
146 g_free (fn);
147 }
148
149
150
151 static void
152 file_history_create_item (history_descriptor_t *hd, void *data)
153 {
154 file_history_data_t *fhd = (file_history_data_t *) data;
155 size_t width;
156
157 width = str_term_width1 (fhd->file_name);
158 hd->max_width = MAX (width, hd->max_width);
159
160 listbox_add_item (hd->listbox, LISTBOX_APPEND_AT_END, 0, fhd->file_name, fhd->file_pos, TRUE);
161
162 fhd->file_pos = NULL;
163 }
164
165
166
167 static void *
168 file_history_release_item (history_descriptor_t *hd, WLEntry *le)
169 {
170 file_history_data_t *fhd;
171
172 (void) hd;
173
174 fhd = g_new (file_history_data_t, 1);
175 fhd->file_name = le->text;
176 le->text = NULL;
177 fhd->file_pos = (char *) le->data;
178 le->data = NULL;
179
180 return fhd;
181 }
182
183
184
185 static void
186 file_history_free_item (void *data)
187 {
188 file_history_data_t *fhd = (file_history_data_t *) data;
189
190 g_free (fhd->file_name);
191 g_free (fhd->file_pos);
192 g_free (fhd);
193 }
194
195
196
197
198
199
200
201
202
203
204
205
206
207 char *
208 show_file_history (const Widget *w, int *action)
209 {
210 GList *file_list;
211 size_t len;
212 history_descriptor_t hd;
213
214 file_list = file_history_list_read ();
215 if (file_list == NULL)
216 return NULL;
217
218 len = g_list_length (file_list);
219
220 file_list = g_list_last (file_list);
221
222 history_descriptor_init (&hd, w->rect.y, w->rect.x, file_list, 0);
223
224 hd.create = file_history_create_item;
225 hd.release = file_history_release_item;
226 hd.free = file_history_free_item;
227
228 history_show (&hd);
229
230 hd.list = g_list_first (hd.list);
231
232
233 if (len != g_list_length (hd.list))
234 {
235 hd.list = g_list_reverse (hd.list);
236 file_history_list_write (hd.list);
237 }
238
239 g_list_free_full (hd.list, (GDestroyNotify) file_history_free_item);
240
241 *action = hd.action;
242
243 return hd.text;
244 }
245
246