Remove commented out code.
[geeqie.git] / src / history_list.c
1 /*
2  * Geeqie
3  * Copyright (C) 2008 - 2012 The Geeqie Team
4  *
5  * Authors: John Ellis, Vladimir Nadvornik, Laurent Monin
6  *
7  *
8  * This software is released under the GNU General Public License (GNU GPL).
9  * Please read the included file COPYING for more information.
10  * This software comes with no warranty of any kind, use at your own risk!
11  */
12
13 #include "main.h"
14 #include "history_list.h"
15
16 #include "secure_save.h"
17 #include "ui_fileops.h"
18
19 /*
20  *-----------------------------------------------------------------------------
21  * history lists
22  *-----------------------------------------------------------------------------
23  */
24
25 #define HISTORY_DEFAULT_KEY_COUNT 16
26
27
28 typedef struct _HistoryData HistoryData;
29 struct _HistoryData
30 {
31         gchar *key;
32         GList *list;
33 };
34
35 static GList *history_list = NULL;
36
37
38 static gchar *quoted_from_text(const gchar *text)
39 {
40         const gchar *ptr;
41         gint c = 0;
42         gint l = strlen(text);
43
44         if (l == 0) return NULL;
45
46         while (c < l && text[c] !='"') c++;
47         if (text[c] == '"')
48                 {
49                 gint e;
50                 c++;
51                 ptr = text + c;
52                 e = c;
53                 while (e < l && text[e] !='"') e++;
54                 if (text[e] == '"')
55                         {
56                         if (e - c > 0)
57                                 {
58                                 return g_strndup(ptr, e - c);
59                                 }
60                         }
61                 }
62         return NULL;
63 }
64
65 gboolean history_list_load(const gchar *path)
66 {
67         FILE *f;
68         gchar *key = NULL;
69         gchar s_buf[1024];
70         gchar *pathl;
71
72         pathl = path_from_utf8(path);
73         f = fopen(pathl, "r");
74         g_free(pathl);
75         if (!f) return FALSE;
76
77         /* first line must start with History comment */
78         if (!fgets(s_buf, sizeof(s_buf), f) ||
79             strncmp(s_buf, "#History", 8) != 0)
80                 {
81                 fclose(f);
82                 return FALSE;
83                 }
84
85         while (fgets(s_buf, sizeof(s_buf), f))
86                 {
87                 if (s_buf[0]=='#') continue;
88                 if (s_buf[0]=='[')
89                         {
90                         gint c;
91                         gchar *ptr;
92
93                         ptr = s_buf + 1;
94                         c = 0;
95                         while (ptr[c] != ']' && ptr[c] != '\n' && ptr[c] != '\0') c++;
96
97                         g_free(key);
98                         key = g_strndup(ptr, c);
99                         }
100                 else
101                         {
102                         gchar *value;
103
104                         value = quoted_from_text(s_buf);
105                         if (value && key)
106                                 {
107                                 history_list_add_to_key(key, value, 0);
108                                 }
109                         g_free(value);
110                         }
111                 }
112
113         fclose(f);
114
115         g_free(key);
116
117         return TRUE;
118 }
119
120 gboolean history_list_save(const gchar *path)
121 {
122         SecureSaveInfo *ssi;
123         GList *list;
124         gchar *pathl;
125
126         pathl = path_from_utf8(path);
127         ssi = secure_open(pathl);
128         g_free(pathl);
129         if (!ssi)
130                 {
131                 log_printf(_("Unable to write history lists to: %s\n"), path);
132                 return FALSE;
133                 }
134
135         secure_fprintf(ssi, "#History lists\n\n");
136
137         list = g_list_last(history_list);
138         while (list && secsave_errno == SS_ERR_NONE)
139                 {
140                 HistoryData *hd;
141                 GList *work;
142
143                 hd = list->data;
144                 list = list->prev;
145
146                 secure_fprintf(ssi, "[%s]\n", hd->key);
147
148                 /* save them inverted (oldest to newest)
149                  * so that when reading they are added correctly
150                  */
151                 work = g_list_last(hd->list);
152                 while (work && secsave_errno == SS_ERR_NONE)
153                         {
154                         secure_fprintf(ssi, "\"%s\"\n", (gchar *)work->data);
155                         work = work->prev;
156                         }
157                 secure_fputc(ssi, '\n');
158                 }
159
160         secure_fprintf(ssi, "#end\n");
161
162         return (secure_close(ssi) == 0);
163 }
164
165 static void history_list_free(HistoryData *hd)
166 {
167         GList *work;
168
169         if (!hd) return;
170
171         work = hd->list;
172         while (work)
173                 {
174                 g_free(work->data);
175                 work = work->next;
176                 }
177
178         g_free(hd->key);
179         g_free(hd);
180 }
181
182 static HistoryData *history_list_find_by_key(const gchar *key)
183 {
184         GList *work = history_list;
185
186         if (!key) return NULL;
187
188         while (work)
189                 {
190                 HistoryData *hd = work->data;
191                 if (strcmp(hd->key, key) == 0) return hd;
192                 work = work->next;
193                 }
194         return NULL;
195 }
196
197 const gchar *history_list_find_last_path_by_key(const gchar *key)
198 {
199         HistoryData *hd;
200
201         hd = history_list_find_by_key(key);
202         if (!hd || !hd->list) return NULL;
203
204         return hd->list->data;
205 }
206
207 void history_list_free_key(const gchar *key)
208 {
209         HistoryData *hd;
210         hd = history_list_find_by_key(key);
211         if (!hd) return;
212
213         history_list = g_list_remove(history_list, hd);
214         history_list_free(hd);
215 }
216
217 void history_list_add_to_key(const gchar *key, const gchar *path, gint max)
218 {
219         HistoryData *hd;
220         GList *work;
221
222         if (!key || !path) return;
223
224         hd = history_list_find_by_key(key);
225         if (!hd)
226                 {
227                 hd = g_new(HistoryData, 1);
228                 hd->key = g_strdup(key);
229                 hd->list = NULL;
230                 history_list = g_list_prepend(history_list, hd);
231                 }
232
233         /* if already in the list, simply move it to the top */
234         work = hd->list;
235         while (work)
236                 {
237                 gchar *buf = work->data;
238
239                 if (strcmp(buf, path) == 0)
240                         {
241                         /* if not first, move it */
242                         if (work != hd->list)
243                                 {
244                                 hd->list = g_list_remove(hd->list, buf);
245                                 hd->list = g_list_prepend(hd->list, buf);
246                                 }
247                         return;
248                         }
249                 work = work->next;
250                 }
251
252         hd->list = g_list_prepend(hd->list, g_strdup(path));
253
254         if (max == -1) max = HISTORY_DEFAULT_KEY_COUNT;
255         if (max > 0)
256                 {
257                 gint len = 0;
258                 GList *work = hd->list;
259                 GList *last = NULL;
260
261                 while (work)
262                         {
263                         len++;
264                         last = work;
265                         work = work->next;
266                         }
267
268                 work = last;
269                 while (work && len > max)
270                         {
271                         GList *node = work;
272                         work = work->prev;
273
274                         g_free(node->data);
275                         hd->list = g_list_delete_link(hd->list, node);
276                         len--;
277                         }
278                 }
279 }
280
281 void history_list_item_change(const gchar *key, const gchar *oldpath, const gchar *newpath)
282 {
283         HistoryData *hd;
284         GList *work;
285
286         if (!oldpath) return;
287         hd = history_list_find_by_key(key);
288         if (!hd) return;
289
290         work = hd->list;
291         while (work)
292                 {
293                 gchar *buf = work->data;
294                 if (strcmp(buf, oldpath) == 0)
295                         {
296                         if (newpath)
297                                 {
298                                 work->data = g_strdup(newpath);
299                                 }
300                         else
301                                 {
302                                 hd->list = g_list_remove(hd->list, buf);
303                                 }
304                         g_free(buf);
305                         return;
306                         }
307                 work = work->next;
308                 }
309 }
310
311 void history_list_item_move(const gchar *key, const gchar *path, gint direction)
312 {
313         HistoryData *hd;
314         GList *work;
315         gint p = 0;
316
317         if (!path) return;
318         hd = history_list_find_by_key(key);
319         if (!hd) return;
320
321         work = hd->list;
322         while (work)
323                 {
324                 gchar *buf = work->data;
325                 if (strcmp(buf, path) == 0)
326                         {
327                         p += direction;
328                         if (p < 0) return;
329                         hd->list = g_list_remove(hd->list, buf);
330                         hd->list = g_list_insert(hd->list, buf, p);
331                         return;
332                         }
333                 work = work->next;
334                 p++;
335                 }
336 }
337
338 void history_list_item_remove(const gchar *key, const gchar *path)
339 {
340         history_list_item_change(key, path, NULL);
341 }
342
343 GList *history_list_get_by_key(const gchar *key)
344 {
345         HistoryData *hd;
346
347         hd = history_list_find_by_key(key);
348         if (!hd) return NULL;
349
350         return hd->list;
351 }
352 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */