comparison src/ui_bookmark.c @ 902:c414002a1f27

Move history_list_*() functions to separate files: history_list.c and history_list.h.
author zas_
date Sun, 20 Jul 2008 14:56:32 +0000
parents 518c05cf63ba
children 1698baa37871
comparison
equal deleted inserted replaced
901:ae75cd2b4d76 902:c414002a1f27
22 #include <gtk/gtk.h> 22 #include <gtk/gtk.h>
23 23
24 #include <gdk/gdkkeysyms.h> /* for key values */ 24 #include <gdk/gdkkeysyms.h> /* for key values */
25 25
26 #include "main.h" 26 #include "main.h"
27
27 #include "filedata.h" 28 #include "filedata.h"
29 #include "history_list.h"
28 30
29 #include "secure_save.h" 31 #include "secure_save.h"
30 #include "ui_bookmark.h" 32 #include "ui_bookmark.h"
31 #include "ui_fileops.h" 33 #include "ui_fileops.h"
32 #include "ui_menu.h" 34 #include "ui_menu.h"
33 #include "ui_misc.h" 35 #include "ui_misc.h"
34 #include "ui_utildlg.h" 36 #include "ui_utildlg.h"
35 #include "ui_tabcomp.h" 37 #include "ui_tabcomp.h"
36 38
37 39
38 /*
39 *-----------------------------------------------------------------------------
40 * history lists
41 *-----------------------------------------------------------------------------
42 */
43
44 #define HISTORY_DEFAULT_KEY_COUNT 16
45
46
47 typedef struct _HistoryData HistoryData;
48 struct _HistoryData
49 {
50 gchar *key;
51 GList *list;
52 };
53
54 static GList *history_list = NULL;
55
56
57 static gchar *quoted_from_text(const gchar *text)
58 {
59 const gchar *ptr;
60 gint c = 0;
61 gint l = strlen(text);
62
63 if (l == 0) return NULL;
64
65 while (c < l && text[c] !='"') c++;
66 if (text[c] == '"')
67 {
68 gint e;
69 c++;
70 ptr = text + c;
71 e = c;
72 while (e < l && text[e] !='"') e++;
73 if (text[e] == '"')
74 {
75 if (e - c > 0)
76 {
77 return g_strndup(ptr, e - c);
78 }
79 }
80 }
81 return NULL;
82 }
83
84 gint history_list_load(const gchar *path)
85 {
86 FILE *f;
87 gchar *key = NULL;
88 gchar s_buf[1024];
89 gchar *pathl;
90
91 pathl = path_from_utf8(path);
92 f = fopen(pathl, "r");
93 g_free(pathl);
94 if (!f) return FALSE;
95
96 /* first line must start with History comment */
97 if (!fgets(s_buf, sizeof(s_buf), f) ||
98 strncmp(s_buf, "#History", 8) != 0)
99 {
100 fclose(f);
101 return FALSE;
102 }
103
104 while (fgets(s_buf, sizeof(s_buf), f))
105 {
106 if (s_buf[0]=='#') continue;
107 if (s_buf[0]=='[')
108 {
109 gint c;
110 gchar *ptr;
111
112 ptr = s_buf + 1;
113 c = 0;
114 while (ptr[c] != ']' && ptr[c] != '\n' && ptr[c] != '\0') c++;
115
116 g_free(key);
117 key = g_strndup(ptr, c);
118 }
119 else
120 {
121 gchar *value;
122
123 value = quoted_from_text(s_buf);
124 if (value && key)
125 {
126 history_list_add_to_key(key, value, 0);
127 }
128 g_free(value);
129 }
130 }
131
132 fclose(f);
133
134 g_free(key);
135
136 return TRUE;
137 }
138
139 gint history_list_save(const gchar *path)
140 {
141 SecureSaveInfo *ssi;
142 GList *list;
143 gchar *pathl;
144
145 pathl = path_from_utf8(path);
146 ssi = secure_open(pathl);
147 g_free(pathl);
148 if (!ssi)
149 {
150 log_printf(_("Unable to write history lists to: %s\n"), path);
151 return FALSE;
152 }
153
154 secure_fprintf(ssi, "#History lists\n\n");
155
156 list = g_list_last(history_list);
157 while (list && secsave_errno == SS_ERR_NONE)
158 {
159 HistoryData *hd;
160 GList *work;
161
162 hd = list->data;
163 list = list->prev;
164
165 secure_fprintf(ssi, "[%s]\n", hd->key);
166
167 /* save them inverted (oldest to newest)
168 * so that when reading they are added correctly
169 */
170 work = g_list_last(hd->list);
171 while (work && secsave_errno == SS_ERR_NONE)
172 {
173 secure_fprintf(ssi, "\"%s\"\n", (gchar *)work->data);
174 work = work->prev;
175 }
176 secure_fputc(ssi, '\n');
177 }
178
179 secure_fprintf(ssi, "#end\n");
180
181 return (secure_close(ssi) == 0);
182 }
183
184 static void history_list_free(HistoryData *hd)
185 {
186 GList *work;
187
188 if (!hd) return;
189
190 work = hd->list;
191 while (work)
192 {
193 g_free(work->data);
194 work = work->next;
195 }
196
197 g_free(hd->key);
198 g_free(hd);
199 }
200
201 static HistoryData *history_list_find_by_key(const gchar* key)
202 {
203 GList *work = history_list;
204
205 if (!key) return NULL;
206
207 while (work)
208 {
209 HistoryData *hd = work->data;
210 if (strcmp(hd->key, key) == 0) return hd;
211 work = work->next;
212 }
213 return NULL;
214 }
215
216 const gchar *history_list_find_last_path_by_key(const gchar* key)
217 {
218 HistoryData *hd;
219
220 hd = history_list_find_by_key(key);
221 if (!hd || !hd->list) return NULL;
222
223 return hd->list->data;
224 }
225
226 void history_list_free_key(const gchar *key)
227 {
228 HistoryData *hd;
229 hd = history_list_find_by_key(key);
230 if (!hd) return;
231
232 history_list = g_list_remove(history_list, hd);
233 history_list_free(hd);
234 }
235
236 void history_list_add_to_key(const gchar *key, const gchar *path, gint max)
237 {
238 HistoryData *hd;
239 GList *work;
240
241 if (!key || !path) return;
242
243 hd = history_list_find_by_key(key);
244 if (!hd)
245 {
246 hd = g_new(HistoryData, 1);
247 hd->key = g_strdup(key);
248 hd->list = NULL;
249 history_list = g_list_prepend(history_list, hd);
250 }
251
252 /* if already in the list, simply move it to the top */
253 work = hd->list;
254 while (work)
255 {
256 gchar *buf = work->data;
257
258 if (strcmp(buf, path) == 0)
259 {
260 /* if not first, move it */
261 if (work != hd->list)
262 {
263 hd->list = g_list_remove(hd->list, buf);
264 hd->list = g_list_prepend(hd->list, buf);
265 }
266 return;
267 }
268 work = work->next;
269 }
270
271 hd->list = g_list_prepend(hd->list, g_strdup(path));
272
273 if (max == -1) max = HISTORY_DEFAULT_KEY_COUNT;
274 if (max > 0)
275 {
276 gint len = 0;
277 GList *work = hd->list;
278 GList *last = NULL;
279
280 while (work)
281 {
282 len++;
283 last = work;
284 work = work->next;
285 }
286
287 work = last;
288 while (work && len > max)
289 {
290 GList *node = work;
291 work = work->prev;
292
293 g_free(node->data);
294 hd->list = g_list_delete_link(hd->list, node);
295 len--;
296 }
297 }
298 }
299
300 void history_list_item_change(const gchar *key, const gchar *oldpath, const gchar *newpath)
301 {
302 HistoryData *hd;
303 GList *work;
304
305 if (!oldpath) return;
306 hd = history_list_find_by_key(key);
307 if (!hd) return;
308
309 work = hd->list;
310 while (work)
311 {
312 gchar *buf = work->data;
313 if (strcmp(buf, oldpath) == 0)
314 {
315 if (newpath)
316 {
317 work->data = g_strdup(newpath);
318 }
319 else
320 {
321 hd->list = g_list_remove(hd->list, buf);
322 }
323 g_free(buf);
324 return;
325 }
326 work = work->next;
327 }
328 }
329
330 void history_list_item_move(const gchar *key, const gchar *path, gint direction)
331 {
332 HistoryData *hd;
333 GList *work;
334 gint p = 0;
335
336 if (!path) return;
337 hd = history_list_find_by_key(key);
338 if (!hd) return;
339
340 work = hd->list;
341 while (work)
342 {
343 gchar *buf = work->data;
344 if (strcmp(buf, path) == 0)
345 {
346 p += direction;
347 if (p < 0) return;
348 hd->list = g_list_remove(hd->list, buf);
349 hd->list = g_list_insert(hd->list, buf, p);
350 return;
351 }
352 work = work->next;
353 p++;
354 }
355 }
356
357 void history_list_item_remove(const gchar *key, const gchar *path)
358 {
359 history_list_item_change(key, path, NULL);
360 }
361
362 GList *history_list_get_by_key(const gchar *key)
363 {
364 HistoryData *hd;
365
366 hd = history_list_find_by_key(key);
367 if (!hd) return NULL;
368
369 return hd->list;
370 }
371 40
372 /* 41 /*
373 *----------------------------------------------------------------------------- 42 *-----------------------------------------------------------------------------
374 * bookmarks 43 * bookmarks
375 *----------------------------------------------------------------------------- 44 *-----------------------------------------------------------------------------