Mercurial > geeqie.yaz
annotate src/rcfile.c @ 276:4f526d436873
Implement secure rc file saving.
First data is written to a temporary file, then if nothing
was wrong, this file is renamed to the final name.
This way the risk of corrupted rc file is greatly reduced.
The code is borrowed from ELinks (http://elinks.cz).
author | zas_ |
---|---|
date | Tue, 08 Apr 2008 21:55:58 +0000 |
parents | a9adf9e1a746 |
children | 9995c5fb202a |
rev | line source |
---|---|
1 | 1 /* |
196 | 2 * Geeqie |
113
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
3 * (C) 2006 John Ellis |
1 | 4 * |
5 * Author: John Ellis | |
6 * | |
9 | 7 * This software is released under the GNU General Public License (GNU GPL). |
8 * Please read the included file COPYING for more information. | |
9 * This software comes with no warranty of any kind, use at your own risk! | |
1 | 10 */ |
11 | |
276 | 12 #include <glib/gstdio.h> |
13 #include <errno.h> | |
9 | 14 |
1 | 15 #include "gqview.h" |
9 | 16 #include "rcfile.h" |
1 | 17 |
9 | 18 #include "filelist.h" |
19 #include "slideshow.h" | |
20 #include "ui_fileops.h" | |
222
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
218
diff
changeset
|
21 #include "bar_exif.h" |
9 | 22 |
276 | 23 /* ABOUT SECURE SAVE */ |
24 /* This code was borrowed from the ELinks project (http://elinks.cz) | |
25 * It was originally written by me (Laurent Monin aka Zas) and heavily | |
26 * modified and improved by all ELinks contributors. | |
27 * This code was released under the GPLv2 licence. | |
28 * It was modified to be included in geeqie on 2008/04/05 */ | |
29 | |
30 /* If ssi->secure_save is TRUE: | |
31 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
32 * | |
33 * A call to secure_open("/home/me/.geeqie/filename", mask) will open a file | |
34 * named "filename.tmp_XXXXXX" in /home/me/.geeqie/ and return a pointer to a | |
35 * structure SecureSaveInfo on success or NULL on error. | |
36 * | |
37 * filename.tmp_XXXXXX can't conflict with any file since it's created using | |
38 * mkstemp(). XXXXXX is a random string. | |
39 * | |
40 * Subsequent write operations are done using returned SecureSaveInfo FILE * | |
41 * field named fp. | |
42 * | |
43 * If an error is encountered, SecureSaveInfo int field named err is set | |
44 * (automatically if using secure_fp*() functions or by programmer) | |
45 * | |
46 * When secure_close() is called, "filename.tmp_XXXXXX" is flushed and closed, | |
47 * and if SecureSaveInfo err field has a value of zero, "filename.tmp_XXXXXX" | |
48 * is renamed to "filename". If this succeeded, then secure_close() returns 0. | |
49 * | |
50 * WARNING: since rename() is used, any symlink called "filename" may be | |
51 * replaced by a regular file. If destination file isn't a regular file, | |
52 * then secsave is disabled for that file. | |
53 * | |
54 * If ssi->secure_save is FALSE: | |
55 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
56 * | |
57 * No temporary file is created, "filename" is truncated, all operations are | |
58 * done on it, no rename nor flush occur, symlinks are preserved. | |
59 * | |
60 * In both cases: | |
61 * ~~~~~~~~~~~~~ | |
62 * | |
63 * Access rights are affected by secure_open() mask parameter. | |
64 */ | |
65 | |
66 /* FIXME: locking system on files about to be rewritten ? */ | |
67 /* FIXME: Low risk race conditions about ssi->file_name. */ | |
68 | |
69 SecureSaveErrno secsave_errno = SS_ERR_NONE; | |
70 | |
71 | |
72 /** Open a file for writing in a secure way. @returns a pointer to a | |
73 * structure secure_save_info on success, or NULL on failure. */ | |
74 static SecureSaveInfo * | |
75 secure_open_umask(gchar *file_name) | |
76 { | |
77 struct stat st; | |
78 SecureSaveInfo *ssi; | |
79 | |
80 secsave_errno = SS_ERR_NONE; | |
81 | |
82 ssi = g_new0(SecureSaveInfo, 1); | |
83 if (!ssi) { | |
84 secsave_errno = SS_ERR_OUT_OF_MEM; | |
85 goto end; | |
86 } | |
87 | |
88 ssi->secure_save = TRUE; | |
89 | |
90 ssi->file_name = g_strdup(file_name); | |
91 if (!ssi->file_name) { | |
92 secsave_errno = SS_ERR_OUT_OF_MEM; | |
93 goto free_f; | |
94 } | |
95 | |
96 /* Check properties of final file. */ | |
97 #ifndef NO_UNIX_SOFTLINKS | |
98 if (g_lstat(ssi->file_name, &st)) { | |
99 #else | |
100 if (g_stat(ssi->file_name, &st)) { | |
101 #endif | |
102 /* We ignore error caused by file inexistence. */ | |
103 if (errno != ENOENT) { | |
104 /* lstat() error. */ | |
105 ssi->err = errno; | |
106 secsave_errno = SS_ERR_STAT; | |
107 goto free_file_name; | |
108 } | |
109 } else { | |
110 if (!S_ISREG(st.st_mode)) { | |
111 /* Not a regular file, secure_save is disabled. */ | |
112 ssi->secure_save = 0; | |
113 } else { | |
114 #ifdef HAVE_ACCESS | |
115 /* XXX: access() do not work with setuid programs. */ | |
116 if (g_access(ssi->file_name, R_OK | W_OK) < 0) { | |
117 ssi->err = errno; | |
118 secsave_errno = SS_ERR_ACCESS; | |
119 goto free_file_name; | |
120 } | |
121 #else | |
122 FILE *f1; | |
123 | |
124 /* We still have a race condition here between | |
125 * [l]stat() and fopen() */ | |
126 | |
127 f1 = g_fopen(ssi->file_name, "rb+"); | |
128 if (f1) { | |
129 fclose(f1); | |
130 } else { | |
131 ssi->err = errno; | |
132 secsave_errno = SS_ERR_OPEN_READ; | |
133 goto free_file_name; | |
134 } | |
135 #endif | |
136 } | |
137 } | |
138 | |
139 if (ssi->secure_save) { | |
140 /* We use a random name for temporary file, mkstemp() opens | |
141 * the file and return a file descriptor named fd, which is | |
142 * then converted to FILE * using fdopen(). | |
143 */ | |
144 gint fd; | |
145 gchar *randname = g_strconcat(ssi->file_name, ".tmp_XXXXXX", NULL); | |
146 | |
147 if (!randname) { | |
148 secsave_errno = SS_ERR_OUT_OF_MEM; | |
149 goto free_file_name; | |
150 } | |
151 | |
152 /* No need to use safe_mkstemp() here. --Zas */ | |
153 fd = g_mkstemp(randname); | |
154 if (fd == -1) { | |
155 secsave_errno = SS_ERR_MKSTEMP; | |
156 g_free(randname); | |
157 goto free_file_name; | |
158 } | |
159 | |
160 ssi->fp = fdopen(fd, "wb"); | |
161 if (!ssi->fp) { | |
162 secsave_errno = SS_ERR_OPEN_WRITE; | |
163 ssi->err = errno; | |
164 g_free(randname); | |
165 goto free_file_name; | |
166 } | |
167 | |
168 ssi->tmp_file_name = randname; | |
169 } else { | |
170 /* No need to create a temporary file here. */ | |
171 ssi->fp = g_fopen(ssi->file_name, "wb"); | |
172 if (!ssi->fp) { | |
173 secsave_errno = SS_ERR_OPEN_WRITE; | |
174 ssi->err = errno; | |
175 goto free_file_name; | |
176 } | |
177 } | |
178 | |
179 return ssi; | |
180 | |
181 free_file_name: | |
182 g_free(ssi->file_name); | |
183 ssi->file_name = NULL; | |
184 | |
185 free_f: | |
186 g_free(ssi); | |
187 ssi = NULL; | |
188 | |
189 end: | |
190 return NULL; | |
191 } | |
192 | |
193 SecureSaveInfo * | |
194 secure_open(gchar *file_name) | |
195 { | |
196 SecureSaveInfo *ssi; | |
197 mode_t saved_mask; | |
198 #ifdef CONFIG_OS_WIN32 | |
199 /* There is neither S_IRWXG nor S_IRWXO under crossmingw32-gcc */ | |
200 const mode_t mask = 0177; | |
201 #else | |
202 const mode_t mask = S_IXUSR | S_IRWXG | S_IRWXO; | |
203 #endif | |
204 | |
205 saved_mask = umask(mask); | |
206 ssi = secure_open_umask(file_name); | |
207 umask(saved_mask); | |
208 | |
209 return ssi; | |
210 } | |
211 | |
212 /** Close a file opened with secure_open(). Rreturns 0 on success, | |
213 * errno or -1 on failure. | |
214 */ | |
215 gint | |
216 secure_close(SecureSaveInfo *ssi) | |
217 { | |
218 gint ret = -1; | |
219 | |
220 if (!ssi) return ret; | |
221 if (!ssi->fp) goto free; | |
222 | |
223 if (ssi->err) { /* Keep previous errno. */ | |
224 ret = ssi->err; | |
225 fclose(ssi->fp); /* Close file */ | |
226 goto free; | |
227 } | |
228 | |
229 /* Ensure data is effectively written to disk, we first flush libc buffers | |
230 * using fflush(), then fsync() to flush kernel buffers, and finally call | |
231 * fclose() (which call fflush() again, but the first one is needed since | |
232 * it doesn't make much sense to flush kernel buffers and then libc buffers, | |
233 * while closing file releases file descriptor we need to call fsync(). */ | |
234 #if defined(HAVE_FFLUSH) || defined(HAVE_FSYNC) | |
235 if (ssi->secure_save) { | |
236 int fail = 0; | |
237 | |
238 #ifdef HAVE_FFLUSH | |
239 fail = (fflush(ssi->fp) == EOF); | |
240 #endif | |
241 | |
242 #ifdef HAVE_FSYNC | |
243 if (!fail) fail = fsync(fileno(ssi->fp)); | |
244 #endif | |
245 | |
246 if (fail) { | |
247 ret = errno; | |
248 secsave_errno = SS_ERR_OTHER; | |
249 | |
250 fclose(ssi->fp); /* Close file, ignore errors. */ | |
251 goto free; | |
252 } | |
253 } | |
254 #endif | |
255 | |
256 /* Close file. */ | |
257 if (fclose(ssi->fp) == EOF) { | |
258 ret = errno; | |
259 secsave_errno = SS_ERR_OTHER; | |
260 goto free; | |
261 } | |
262 | |
263 if (ssi->secure_save && ssi->file_name && ssi->tmp_file_name) { | |
264 /* FIXME: Race condition on ssi->file_name. The file | |
265 * named ssi->file_name may have changed since | |
266 * secure_open() call (where we stat() file and | |
267 * more..). */ | |
268 if (debug > 2) g_printf("rename %s -> %s", ssi->tmp_file_name, ssi->file_name); | |
269 if (g_rename(ssi->tmp_file_name, ssi->file_name) == -1) { | |
270 ret = errno; | |
271 secsave_errno = SS_ERR_RENAME; | |
272 goto free; | |
273 } | |
274 } | |
275 | |
276 ret = 0; /* Success. */ | |
277 | |
278 free: | |
279 if (ssi->tmp_file_name) g_free(ssi->tmp_file_name); | |
280 if (ssi->file_name) g_free(ssi->file_name); | |
281 if (ssi) g_free(ssi); | |
282 | |
283 return ret; | |
284 } | |
285 | |
286 | |
287 /** fputs() wrapper, set ssi->err to errno on error. If ssi->err is set when | |
288 * called, it immediatly returns EOF. | |
289 */ | |
290 gint | |
291 secure_fputs(SecureSaveInfo *ssi, const gchar *s) | |
292 { | |
293 gint ret; | |
294 | |
295 if (!ssi || !ssi->fp || ssi->err) return EOF; | |
296 | |
297 ret = fputs(s, ssi->fp); | |
298 if (ret == EOF) { | |
299 secsave_errno = SS_ERR_OTHER; | |
300 ssi->err = errno; | |
301 } | |
302 | |
303 return ret; | |
304 } | |
305 | |
306 | |
307 /** fputc() wrapper, set ssi->err to errno on error. If ssi->err is set when | |
308 * called, it immediatly returns EOF. | |
309 */ | |
310 gint | |
311 secure_fputc(SecureSaveInfo *ssi, gint c) | |
312 { | |
313 gint ret; | |
314 | |
315 if (!ssi || !ssi->fp || ssi->err) return EOF; | |
316 | |
317 ret = fputc(c, ssi->fp); | |
318 if (ret == EOF) { | |
319 ssi->err = errno; | |
320 secsave_errno = SS_ERR_OTHER; | |
321 } | |
322 | |
323 return ret; | |
324 } | |
325 | |
326 /** fprintf() wrapper, set ssi->err to errno on error and return a negative | |
327 * value. If ssi->err is set when called, it immediatly returns -1. | |
328 */ | |
329 gint | |
330 secure_fprintf(SecureSaveInfo *ssi, const gchar *format, ...) | |
331 { | |
332 va_list ap; | |
333 gint ret; | |
334 | |
335 if (!ssi || !ssi->fp || ssi->err) return -1; | |
336 | |
337 va_start(ap, format); | |
338 ret = vfprintf(ssi->fp, format, ap); | |
339 if (ret < 0) ssi->err = errno; | |
340 va_end(ap); | |
341 | |
342 return ret; | |
343 } | |
344 | |
345 gchar * | |
346 secsave_strerror(SecureSaveErrno secsave_error) | |
347 { | |
348 switch (secsave_error) { | |
349 case SS_ERR_OPEN_READ: | |
350 return _("Cannot read the file"); | |
351 case SS_ERR_STAT: | |
352 return _("Cannot get file status"); | |
353 case SS_ERR_ACCESS: | |
354 return _("Cannot access the file"); | |
355 case SS_ERR_MKSTEMP: | |
356 return _("Cannot create temp file"); | |
357 case SS_ERR_RENAME: | |
358 return _("Cannot rename the file"); | |
359 case SS_ERR_DISABLED: | |
360 return _("File saving disabled by option"); | |
361 case SS_ERR_OUT_OF_MEM: | |
362 return _("Out of memory"); | |
363 case SS_ERR_OPEN_WRITE: | |
364 return _("Cannot write the file"); | |
365 case SS_ERR_NONE: /* Impossible. */ | |
366 case SS_ERR_OTHER: | |
367 default: | |
368 return _("Secure file saving error"); | |
369 } | |
370 } | |
1 | 371 |
372 /* | |
373 *----------------------------------------------------------------------------- | |
374 * line write/parse routines (private) | |
375 *----------------------------------------------------------------------------- | |
376 */ | |
217 | 377 |
378 /* | |
379 returns text without quotes or NULL for empty or broken string | |
380 any text up to first '"' is skipped | |
381 tail is set to point at the char after the second '"' | |
382 or at the ending \0 | |
383 | |
384 */ | |
1 | 385 |
217 | 386 gchar *quoted_value(const gchar *text, const gchar **tail) |
1 | 387 { |
9 | 388 const gchar *ptr; |
1 | 389 gint c = 0; |
390 gint l = strlen(text); | |
210
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
391 gchar *retval = NULL; |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
392 |
217 | 393 if (tail) *tail = text; |
394 | |
210
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
395 if (l == 0) return retval; |
1 | 396 |
397 while (c < l && text[c] !='"') c++; | |
398 if (text[c] == '"') | |
399 { | |
9 | 400 gint e; |
1 | 401 c++; |
402 ptr = text + c; | |
9 | 403 e = c; |
210
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
404 while (e < l) |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
405 { |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
406 if (text[e-1] != '\\' && text[e] == '"') break; |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
407 e++; |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
408 } |
9 | 409 if (text[e] == '"') |
1 | 410 { |
9 | 411 if (e - c > 0) |
1 | 412 { |
210
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
413 gchar *substring = g_strndup(ptr, e - c); |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
414 |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
415 if (substring) |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
416 { |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
417 retval = g_strcompress(substring); |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
418 g_free(substring); |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
419 } |
1 | 420 } |
421 } | |
217 | 422 if (tail) *tail = text + e + 1; |
1 | 423 } |
424 else | |
425 /* for compatibility with older formats (<0.3.7) | |
426 * read a line without quotes too */ | |
427 { | |
428 c = 0; | |
429 while (c < l && text[c] !=' ' && text[c] !=8 && text[c] != '\n') c++; | |
430 if (c != 0) | |
431 { | |
210
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
432 retval = g_strndup(text, c); |
1 | 433 } |
217 | 434 if (tail) *tail = text + c; |
1 | 435 } |
436 | |
210
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
437 return retval; |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
438 } |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
439 |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
440 gchar *escquote_value(const gchar *text) |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
441 { |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
442 gchar *e; |
250 | 443 |
217 | 444 if (!text) return g_strdup("\"\""); |
210
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
445 |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
446 e = g_strescape(text, ""); |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
447 if (e) |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
448 { |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
449 gchar *retval = g_strdup_printf("\"%s\"", e); |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
450 g_free(e); |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
451 return retval; |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
452 } |
217 | 453 return g_strdup("\"\""); |
1 | 454 } |
455 | |
276 | 456 static void write_char_option(SecureSaveInfo *ssi, gchar *label, gchar *text) |
1 | 457 { |
210
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
458 gchar *escval = escquote_value(text); |
3fa93ab9b119
Improve escaping and quoting of strings saved in rc files.
zas_
parents:
209
diff
changeset
|
459 |
276 | 460 secure_fprintf(ssi, "%s: %s\n", label, escval); |
217 | 461 g_free(escval); |
1 | 462 } |
463 | |
464 static gchar *read_char_option(FILE *f, gchar *option, gchar *label, gchar *value, gchar *text) | |
465 { | |
9 | 466 if (strcasecmp(option, label) == 0) |
1 | 467 { |
468 g_free(text); | |
217 | 469 text = quoted_value(value, NULL); |
1 | 470 } |
471 return text; | |
472 } | |
473 | |
267
a9adf9e1a746
Remove dependency on GTK 2.12, reported by John Vodden and Vladimir
zas_
parents:
250
diff
changeset
|
474 /* Since gdk_color_to_string() is only available since gtk 2.12 |
a9adf9e1a746
Remove dependency on GTK 2.12, reported by John Vodden and Vladimir
zas_
parents:
250
diff
changeset
|
475 * here is an equivalent stub function. */ |
a9adf9e1a746
Remove dependency on GTK 2.12, reported by John Vodden and Vladimir
zas_
parents:
250
diff
changeset
|
476 static gchar *color_to_string(GdkColor *color) |
a9adf9e1a746
Remove dependency on GTK 2.12, reported by John Vodden and Vladimir
zas_
parents:
250
diff
changeset
|
477 { |
a9adf9e1a746
Remove dependency on GTK 2.12, reported by John Vodden and Vladimir
zas_
parents:
250
diff
changeset
|
478 return g_strdup_printf("#%04X%04X%04X", color->red, color->green, color->blue); |
a9adf9e1a746
Remove dependency on GTK 2.12, reported by John Vodden and Vladimir
zas_
parents:
250
diff
changeset
|
479 } |
a9adf9e1a746
Remove dependency on GTK 2.12, reported by John Vodden and Vladimir
zas_
parents:
250
diff
changeset
|
480 |
276 | 481 static void write_color_option(SecureSaveInfo *ssi, gchar *label, GdkColor *color) |
208
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
482 { |
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
483 if (color) |
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
484 { |
267
a9adf9e1a746
Remove dependency on GTK 2.12, reported by John Vodden and Vladimir
zas_
parents:
250
diff
changeset
|
485 gchar *colorstring = color_to_string(color); |
208
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
486 |
276 | 487 write_char_option(ssi, label, colorstring); |
208
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
488 g_free(colorstring); |
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
489 } |
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
490 else |
276 | 491 secure_fprintf(ssi, "%s: \n", label); |
208
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
492 } |
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
493 |
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
494 static GdkColor *read_color_option(FILE *f, gchar *option, gchar *label, gchar *value, GdkColor *color) |
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
495 { |
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
496 if (strcasecmp(option, label) == 0) |
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
497 { |
217 | 498 gchar *colorstr = quoted_value(value, NULL); |
499 if (colorstr) gdk_color_parse(colorstr, color); | |
500 g_free(colorstr); | |
208
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
501 } |
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
502 return color; |
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
503 } |
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
504 |
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
505 |
276 | 506 static void write_int_option(SecureSaveInfo *ssi, gchar *label, gint n) |
1 | 507 { |
276 | 508 secure_fprintf(ssi, "%s: %d\n", label, n); |
1 | 509 } |
510 | |
511 static gint read_int_option(FILE *f, gchar *option, gchar *label, gchar *value, gint n) | |
512 { | |
9 | 513 if (strcasecmp(option, label) == 0) |
514 { | |
515 n = strtol(value, NULL, 10); | |
516 } | |
517 return n; | |
518 } | |
519 | |
276 | 520 static void write_int_unit_option(SecureSaveInfo *ssi, gchar *label, gint n, gint subunits) |
9 | 521 { |
522 gint l, r; | |
523 | |
524 if (subunits > 0) | |
525 { | |
526 l = n / subunits; | |
527 r = n % subunits; | |
528 } | |
529 else | |
1 | 530 { |
9 | 531 l = n; |
532 r = 0; | |
533 } | |
534 | |
276 | 535 secure_fprintf(ssi, "%s: %d.%d\n", label, l, r); |
9 | 536 } |
537 | |
538 static gint read_int_unit_option(FILE *f, gchar *option, gchar *label, gchar *value, gint n, gint subunits) | |
539 { | |
540 if (strcasecmp(option, label) == 0) | |
541 { | |
542 gint l, r; | |
543 gchar *ptr; | |
544 | |
545 ptr = value; | |
546 while (*ptr != '\0' && *ptr != '.') ptr++; | |
547 if (*ptr == '.') | |
548 { | |
549 *ptr = '\0'; | |
550 l = strtol(value, NULL, 10); | |
551 *ptr = '.'; | |
552 ptr++; | |
553 r = strtol(ptr, NULL, 10); | |
554 } | |
555 else | |
556 { | |
557 l = strtol(value, NULL, 10); | |
558 r = 0; | |
559 } | |
560 | |
561 n = l * subunits + r; | |
1 | 562 } |
563 return n; | |
564 } | |
565 | |
276 | 566 static void write_bool_option(SecureSaveInfo *ssi, gchar *label, gint n) |
1 | 567 { |
276 | 568 secure_fprintf(ssi, "%s: ", label); |
569 if (n) secure_fprintf(ssi, "true\n"); else secure_fprintf(ssi, "false\n"); | |
1 | 570 } |
571 | |
572 static gint read_bool_option(FILE *f, gchar *option, gchar *label, gchar *value, gint n) | |
573 { | |
9 | 574 if (strcasecmp(option, label) == 0) |
1 | 575 { |
9 | 576 if (strcasecmp(value, "true") == 0) |
1 | 577 n = TRUE; |
578 else | |
579 n = FALSE; | |
580 } | |
581 return n; | |
582 } | |
583 | |
584 /* | |
585 *----------------------------------------------------------------------------- | |
586 * save configuration (public) | |
587 *----------------------------------------------------------------------------- | |
588 */ | |
589 | |
9 | 590 void save_options(void) |
1 | 591 { |
276 | 592 SecureSaveInfo *ssi; |
1 | 593 gchar *rc_path; |
9 | 594 gchar *rc_pathl; |
1 | 595 gint i; |
596 | |
9 | 597 rc_path = g_strconcat(homedir(), "/", GQVIEW_RC_DIR, "/", RC_FILE_NAME, NULL); |
1 | 598 |
9 | 599 rc_pathl = path_from_utf8(rc_path); |
276 | 600 ssi = secure_open(rc_pathl); |
9 | 601 g_free(rc_pathl); |
276 | 602 if (!ssi) |
1 | 603 { |
9 | 604 gchar *buf; |
605 | |
606 buf = g_strdup_printf(_("error saving config file: %s\n"), rc_path); | |
607 print_term(buf); | |
608 g_free(buf); | |
609 | |
1 | 610 g_free(rc_path); |
611 return; | |
612 } | |
276 | 613 |
614 secure_fprintf(ssi, "######################################################################\n"); | |
615 secure_fprintf(ssi, "# Geeqie config file version %7s #\n", VERSION); | |
616 secure_fprintf(ssi, "######################################################################\n"); | |
617 secure_fputc(ssi, '\n'); | |
1 | 618 |
276 | 619 secure_fprintf(ssi, "# Note: This file is autogenerated. Options can be changed here,\n"); |
620 secure_fprintf(ssi, "# but user comments and formatting will be lost.\n"); | |
621 secure_fputc(ssi, '\n'); | |
622 | |
623 secure_fprintf(ssi, "##### General Options #####\n\n"); | |
1 | 624 |
276 | 625 write_int_option(ssi, "layout_style", layout_style); |
626 write_char_option(ssi, "layout_order", layout_order); | |
627 secure_fputc(ssi, '\n'); | |
9 | 628 |
276 | 629 write_bool_option(ssi, "layout_view_as_icons", layout_view_icons); |
630 write_bool_option(ssi, "layout_view_as_tree", layout_view_tree); | |
631 write_bool_option(ssi, "show_icon_names", show_icon_names); | |
632 secure_fputc(ssi, '\n'); | |
9 | 633 |
276 | 634 write_bool_option(ssi, "tree_descend_folders", tree_descend_subdirs); |
635 write_bool_option(ssi, "lazy_image_sync", lazy_image_sync); | |
636 write_bool_option(ssi, "update_on_time_change", update_on_time_change); | |
637 write_bool_option(ssi, "exif_auto_rotate", exif_rotate_enable); | |
638 secure_fputc(ssi, '\n'); | |
1 | 639 |
276 | 640 write_bool_option(ssi, "enable_startup_path", startup_path_enable); |
641 write_char_option(ssi, "startup_path", startup_path); | |
642 secure_fputc(ssi, '\n'); | |
9 | 643 |
276 | 644 secure_fprintf(ssi, "zoom_mode: "); |
645 if (zoom_mode == ZOOM_RESET_ORIGINAL) secure_fprintf(ssi, "original\n"); | |
646 if (zoom_mode == ZOOM_RESET_FIT_WINDOW) secure_fprintf(ssi, "fit\n"); | |
647 if (zoom_mode == ZOOM_RESET_NONE) secure_fprintf(ssi, "dont_change\n"); | |
648 write_bool_option(ssi, "two_pass_scaling", two_pass_zoom); | |
649 write_bool_option(ssi, "zoom_to_fit_allow_expand", zoom_to_fit_expands); | |
650 secure_fputc(ssi, '\n'); | |
1 | 651 |
276 | 652 write_bool_option(ssi, "fit_window_to_image", fit_window); |
653 write_bool_option(ssi, "limit_window_size", limit_window_size); | |
654 write_int_option(ssi, "max_window_size", max_window_size); | |
655 write_bool_option(ssi, "limit_autofit_size", limit_autofit_size); | |
656 write_int_option(ssi, "max_autofit_size", max_autofit_size); | |
657 secure_fputc(ssi, '\n'); | |
1 | 658 |
276 | 659 write_bool_option(ssi, "progressive_keyboard_scrolling", progressive_key_scrolling); |
660 write_int_option(ssi, "scroll_reset_method", scroll_reset_method); | |
661 secure_fputc(ssi, '\n'); | |
9 | 662 |
276 | 663 write_bool_option(ssi, "enable_thumbnails", thumbnails_enabled); |
664 write_int_option(ssi, "thumbnail_width", thumb_max_width); | |
665 write_int_option(ssi, "thumbnail_height", thumb_max_height); | |
666 write_bool_option(ssi, "cache_thumbnails", enable_thumb_caching); | |
667 write_bool_option(ssi, "cache_thumbnails_into_dirs", enable_thumb_dirs); | |
668 write_bool_option(ssi, "thumbnail_fast", thumbnail_fast); | |
669 write_bool_option(ssi, "use_xvpics_thumbnails", use_xvpics_thumbnails); | |
670 write_bool_option(ssi, "thumbnail_spec_standard", thumbnail_spec_standard); | |
671 secure_fputc(ssi, '\n'); | |
9 | 672 |
276 | 673 write_bool_option(ssi, "local_metadata", enable_metadata_dirs); |
674 secure_fputc(ssi, '\n'); | |
1 | 675 |
276 | 676 write_int_option(ssi, "sort_method", (gint)file_sort_method); |
677 write_bool_option(ssi, "sort_ascending", file_sort_ascending); | |
678 write_bool_option(ssi, "sort_case_sensitive", file_sort_case_sensitive); | |
679 secure_fputc(ssi, '\n'); | |
1 | 680 |
276 | 681 write_bool_option(ssi, "confirm_delete", confirm_delete); |
682 write_bool_option(ssi, "enable_delete_key", enable_delete_key); | |
683 write_bool_option(ssi, "safe_delete", safe_delete_enable); | |
684 write_char_option(ssi, "safe_delete_path", safe_delete_path); | |
685 write_int_option(ssi, "safe_delete_size", safe_delete_size); | |
686 secure_fputc(ssi, '\n'); | |
9 | 687 |
276 | 688 write_bool_option(ssi, "tools_float", tools_float); |
689 write_bool_option(ssi, "tools_hidden", tools_hidden); | |
690 write_bool_option(ssi, "restore_tool_state", restore_tool); | |
691 write_bool_option(ssi, "toolbar_hidden", toolbar_hidden); | |
692 secure_fputc(ssi, '\n'); | |
9 | 693 |
276 | 694 write_bool_option(ssi, "mouse_wheel_scrolls", mousewheel_scrolls); |
695 write_bool_option(ssi, "in_place_rename", enable_in_place_rename); | |
696 write_int_option(ssi, "open_recent_max", recent_list_max); | |
697 write_int_option(ssi, "image_cache_size_max", tile_cache_max); | |
698 write_int_option(ssi, "thumbnail_quality", thumbnail_quality); | |
699 write_int_option(ssi, "zoom_quality", zoom_quality); | |
700 write_int_option(ssi, "dither_quality", dither_quality); | |
701 write_int_option(ssi, "zoom_increment", zoom_increment); | |
702 write_bool_option(ssi, "enable_read_ahead", enable_read_ahead); | |
703 write_bool_option(ssi, "display_dialogs_under_mouse", place_dialogs_under_mouse); | |
704 secure_fputc(ssi, '\n'); | |
9 | 705 |
276 | 706 write_bool_option(ssi, "user_specified_window_background", user_specified_window_background); |
707 write_color_option(ssi, "window_background_color", &window_background_color); | |
708 secure_fputc(ssi, '\n'); | |
4 | 709 |
276 | 710 write_int_option(ssi, "fullscreen_screen", fullscreen_screen); |
711 write_bool_option(ssi, "fullscreen_clean_flip", fullscreen_clean_flip); | |
712 write_bool_option(ssi, "fullscreen_disable_saver", fullscreen_disable_saver); | |
713 write_bool_option(ssi, "fullscreen_above", fullscreen_above); | |
714 write_bool_option(ssi, "show_fullscreen_info", show_fullscreen_info); | |
715 write_char_option(ssi, "fullscreen_info", fullscreen_info); | |
716 secure_fputc(ssi, '\n'); | |
1 | 717 |
276 | 718 write_int_option(ssi, "custom_similarity_threshold", dupe_custom_threshold); |
1 | 719 |
276 | 720 secure_fprintf(ssi, "\n##### Slideshow Options #####\n\n"); |
721 | |
722 write_int_unit_option(ssi, "slideshow_delay", slideshow_delay, SLIDESHOW_SUBSECOND_PRECISION); | |
1 | 723 |
276 | 724 write_bool_option(ssi, "slideshow_random", slideshow_random); |
725 write_bool_option(ssi, "slideshow_repeat", slideshow_repeat); | |
726 | |
727 secure_fprintf(ssi, "\n##### Filtering Options #####\n\n"); | |
1 | 728 |
276 | 729 write_bool_option(ssi, "show_dotfiles", show_dot_files); |
730 write_bool_option(ssi, "disable_filtering", file_filter_disable); | |
145
8be2cc687304
fixed grouping sidecar files and made it configurable via config file
nadvornik
parents:
113
diff
changeset
|
731 |
276 | 732 filter_write_list(ssi); |
733 | |
734 sidecar_ext_write(ssi); | |
1 | 735 |
276 | 736 secure_fprintf(ssi, "\n##### Color Profiles #####\n\n"); |
113
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
737 |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
738 #ifndef HAVE_LCMS |
276 | 739 secure_fprintf(ssi, "# NOTICE: Geeqie was not built with support for color profiles,\n" |
740 "# color profile options will have no effect.\n\n"); | |
113
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
741 #endif |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
742 |
276 | 743 write_bool_option(ssi, "color_profile_enabled", color_profile_enabled); |
744 write_bool_option(ssi, "color_profile_use_image", color_profile_use_image); | |
745 write_int_option(ssi, "color_profile_input_type", color_profile_input_type); | |
113
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
746 for (i = 0; i < COLOR_PROFILE_INPUTS; i++) |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
747 { |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
748 gchar *buf; |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
749 |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
750 buf = g_strdup_printf("color_profile_input_file_%d", i + 1); |
276 | 751 write_char_option(ssi, buf, color_profile_input_file[i]); |
113
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
752 g_free(buf); |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
753 |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
754 buf = g_strdup_printf("color_profile_input_name_%d", i + 1); |
276 | 755 write_char_option(ssi, buf, color_profile_input_name[i]); |
113
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
756 g_free(buf); |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
757 } |
276 | 758 secure_fputc(ssi, '\n'); |
759 write_int_option(ssi, "color_profile_screen_type", color_profile_screen_type); | |
760 write_char_option(ssi, "color_profile_screen_file_1", color_profile_screen_file); | |
113
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
761 |
276 | 762 secure_fprintf(ssi, "\n##### External Programs #####\n"); |
763 secure_fprintf(ssi, "# Maximum of 10 programs (external_1 through external_10)\n"); | |
764 secure_fprintf(ssi, "# format: external_n: \"menu name\" \"command line\"\n\n"); | |
1 | 765 |
9 | 766 for (i = 0; i < GQVIEW_EDITOR_SLOTS; i++) |
1 | 767 { |
276 | 768 gchar *qname = escquote_value(editor_name[i]); |
769 gchar *qcommand = escquote_value(editor_command[i]); | |
770 secure_fprintf(ssi, "external_%d: %s %s\n", i+1, qname, qcommand); | |
217 | 771 g_free(qname); |
772 g_free(qcommand); | |
1 | 773 } |
774 | |
276 | 775 secure_fprintf(ssi, "\n##### Collection Options #####\n\n"); |
9 | 776 |
276 | 777 write_bool_option(ssi, "rectangular_selections", collection_rectangular_selection); |
9 | 778 |
276 | 779 secure_fprintf(ssi, "\n##### Window Positions #####\n\n"); |
1 | 780 |
276 | 781 write_bool_option(ssi, "restore_window_positions", save_window_positions); |
782 secure_fputc(ssi, '\n'); | |
783 write_int_option(ssi, "main_window_x", main_window_x); | |
784 write_int_option(ssi, "main_window_y", main_window_y); | |
785 write_int_option(ssi, "main_window_width", main_window_w); | |
786 write_int_option(ssi, "main_window_height", main_window_h); | |
787 write_bool_option(ssi, "main_window_maximized", main_window_maximized); | |
788 write_int_option(ssi, "float_window_x", float_window_x); | |
789 write_int_option(ssi, "float_window_y", float_window_y); | |
790 write_int_option(ssi, "float_window_width", float_window_w); | |
791 write_int_option(ssi, "float_window_height", float_window_h); | |
792 write_int_option(ssi, "float_window_divider", float_window_divider); | |
793 write_int_option(ssi, "divider_position_h", window_hdivider_pos); | |
794 write_int_option(ssi, "divider_position_v", window_vdivider_pos); | |
1 | 795 |
276 | 796 secure_fprintf(ssi, "\n##### Exif #####\n# 0: never\n# 1: if set\n# 2: always\n\n"); |
222
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
218
diff
changeset
|
797 for (i = 0; ExifUIList[i].key; i++) |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
218
diff
changeset
|
798 { |
276 | 799 secure_fprintf(ssi, "exif_"); |
800 write_int_option(ssi, (gchar *)ExifUIList[i].key, ExifUIList[i].current); | |
222
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
218
diff
changeset
|
801 } |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
218
diff
changeset
|
802 |
276 | 803 secure_fputc(ssi, '\n'); |
804 secure_fprintf(ssi, "######################################################################\n"); | |
805 secure_fprintf(ssi, "# end of Geeqie config file #\n"); | |
806 secure_fprintf(ssi, "######################################################################\n"); | |
1 | 807 |
276 | 808 |
809 if (secure_close(ssi)) | |
810 { | |
811 gchar *buf; | |
812 | |
813 buf = g_strdup_printf(_("error saving config file: %s\nerror: %s\n"), rc_path, | |
814 secsave_strerror(secsave_errno)); | |
815 print_term(buf); | |
816 g_free(buf); | |
817 | |
818 g_free(rc_path); | |
819 return; | |
820 } | |
1 | 821 |
822 g_free(rc_path); | |
823 } | |
824 | |
825 /* | |
826 *----------------------------------------------------------------------------- | |
827 * load configuration (public) | |
828 *----------------------------------------------------------------------------- | |
829 */ | |
830 | |
9 | 831 void load_options(void) |
1 | 832 { |
833 FILE *f; | |
834 gchar *rc_path; | |
9 | 835 gchar *rc_pathl; |
1 | 836 gchar s_buf[1024]; |
837 gchar *s_buf_ptr; | |
838 gchar option[1024]; | |
839 gchar value[1024]; | |
840 gchar value_all[1024]; | |
841 gint c,l,i; | |
9 | 842 |
222
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
218
diff
changeset
|
843 for (i = 0; ExifUIList[i].key; i++) |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
218
diff
changeset
|
844 ExifUIList[i].current = ExifUIList[i].default_value; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
218
diff
changeset
|
845 |
9 | 846 rc_path = g_strconcat(homedir(), "/", GQVIEW_RC_DIR, "/", RC_FILE_NAME, NULL); |
1 | 847 |
9 | 848 rc_pathl = path_from_utf8(rc_path); |
849 f = fopen(rc_pathl,"r"); | |
850 g_free(rc_pathl); | |
1 | 851 if (!f) |
852 { | |
853 g_free(rc_path); | |
854 return; | |
855 } | |
856 | |
857 while (fgets(s_buf,1024,f)) | |
858 { | |
859 if (s_buf[0]=='#') continue; | |
860 if (s_buf[0]=='\n') continue; | |
861 c = 0; | |
862 l = strlen(s_buf); | |
863 while (s_buf[c] != ':' && c < l) c++; | |
864 if (c >= l) continue; | |
865 s_buf[c] = '\0'; | |
866 c++; | |
9 | 867 while ((s_buf[c] == ' ' || s_buf[c] == 8) && c < l) c++; |
1 | 868 s_buf_ptr = s_buf + c; |
9 | 869 strncpy(value_all, s_buf_ptr, sizeof(value_all)); |
1 | 870 while (s_buf[c] != 8 && s_buf[c] != ' ' && s_buf[c] != '\n' && c < l) c++; |
871 s_buf[c] = '\0'; | |
9 | 872 strncpy(option, s_buf, sizeof(option)); |
873 strncpy(value, s_buf_ptr, sizeof(value)); | |
1 | 874 |
875 /* general options */ | |
876 | |
9 | 877 layout_style = read_int_option(f, option, |
878 "layout_style", value, layout_style); | |
879 layout_order = read_char_option(f, option, | |
880 "layout_order", value, layout_order); | |
881 layout_view_icons = read_bool_option(f, option, | |
882 "layout_view_as_icons", value, layout_view_icons); | |
883 layout_view_tree = read_bool_option(f, option, | |
884 "layout_view_as_tree", value, layout_view_tree); | |
885 show_icon_names = read_bool_option(f, option, | |
886 "show_icon_names", value, show_icon_names); | |
887 | |
888 tree_descend_subdirs = read_bool_option(f, option, | |
889 "tree_descend_folders", value, tree_descend_subdirs); | |
890 lazy_image_sync = read_bool_option(f, option, | |
891 "lazy_image_sync", value, lazy_image_sync); | |
892 update_on_time_change = read_bool_option(f, option, | |
893 "update_on_time_change", value, update_on_time_change); | |
894 exif_rotate_enable = read_bool_option(f, option, | |
895 "exif_auto_rotate", value, exif_rotate_enable); | |
896 | |
1 | 897 startup_path_enable = read_bool_option(f, option, |
898 "enable_startup_path", value, startup_path_enable); | |
899 startup_path = read_char_option(f, option, | |
900 "startup_path", value_all, startup_path); | |
901 | |
9 | 902 if (strcasecmp(option,"zoom_mode") == 0) |
1 | 903 { |
9 | 904 if (strcasecmp(value, "original") == 0) zoom_mode = ZOOM_RESET_ORIGINAL; |
905 if (strcasecmp(value, "fit") == 0) zoom_mode = ZOOM_RESET_FIT_WINDOW; | |
906 if (strcasecmp(value, "dont_change") == 0) zoom_mode = ZOOM_RESET_NONE; | |
1 | 907 } |
9 | 908 two_pass_zoom = read_bool_option(f, option, |
909 "two_pass_scaling", value, two_pass_zoom); | |
910 zoom_to_fit_expands = read_bool_option(f, option, | |
911 "zoom_to_fit_allow_expand", value, zoom_to_fit_expands); | |
1 | 912 |
913 fit_window = read_bool_option(f, option, | |
914 "fit_window_to_image", value, fit_window); | |
915 limit_window_size = read_bool_option(f, option, | |
916 "limit_window_size", value, limit_window_size); | |
917 max_window_size = read_int_option(f, option, | |
918 "max_window_size", value, max_window_size); | |
209
ad78ad18523a
configurable frame around image - geeqie_autofit_maxsize.patch by Laurent MONIN
nadvornik
parents:
208
diff
changeset
|
919 limit_autofit_size = read_bool_option(f, option, |
ad78ad18523a
configurable frame around image - geeqie_autofit_maxsize.patch by Laurent MONIN
nadvornik
parents:
208
diff
changeset
|
920 "limit_autofit_size", value, limit_autofit_size); |
ad78ad18523a
configurable frame around image - geeqie_autofit_maxsize.patch by Laurent MONIN
nadvornik
parents:
208
diff
changeset
|
921 max_autofit_size = read_int_option(f, option, |
ad78ad18523a
configurable frame around image - geeqie_autofit_maxsize.patch by Laurent MONIN
nadvornik
parents:
208
diff
changeset
|
922 "max_autofit_size", value, max_autofit_size); |
1 | 923 progressive_key_scrolling = read_bool_option(f, option, |
924 "progressive_keyboard_scrolling", value, progressive_key_scrolling); | |
9 | 925 scroll_reset_method = read_int_option(f, option, |
926 "scroll_reset_method", value, scroll_reset_method); | |
1 | 927 |
3 | 928 thumbnails_enabled = read_bool_option(f, option, |
929 "enable_thumbnails", value, thumbnails_enabled); | |
1 | 930 thumb_max_width = read_int_option(f, option, |
931 "thumbnail_width", value, thumb_max_width); | |
226
3c89da4aef95
Fix and simplify thumbnails size combo box related code.
zas_
parents:
222
diff
changeset
|
932 if (thumb_max_width < 16) thumb_max_width = 16; |
1 | 933 thumb_max_height = read_int_option(f, option, |
934 "thumbnail_height", value, thumb_max_height); | |
226
3c89da4aef95
Fix and simplify thumbnails size combo box related code.
zas_
parents:
222
diff
changeset
|
935 if (thumb_max_height < 16) thumb_max_height = 16; |
1 | 936 enable_thumb_caching = read_bool_option(f, option, |
937 "cache_thumbnails", value, enable_thumb_caching); | |
9 | 938 enable_thumb_dirs = read_bool_option(f, option, |
939 "cache_thumbnails_into_dirs", value, enable_thumb_dirs); | |
14
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
940 thumbnail_fast = read_bool_option(f, option, |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
941 "thumbnail_fast", value, thumbnail_fast); |
1 | 942 use_xvpics_thumbnails = read_bool_option(f, option, |
943 "use_xvpics_thumbnails", value, use_xvpics_thumbnails); | |
9 | 944 thumbnail_spec_standard = read_bool_option(f, option, |
945 "thumbnail_spec_standard", value, thumbnail_spec_standard); | |
946 | |
947 enable_metadata_dirs = read_bool_option(f, option, | |
948 "local_metadata", value, enable_metadata_dirs); | |
949 | |
950 file_sort_method = (SortType)read_int_option(f, option, | |
951 "sort_method", value, (gint)file_sort_method); | |
952 file_sort_ascending = read_bool_option(f, option, | |
953 "sort_ascending", value, file_sort_ascending); | |
954 file_sort_case_sensitive = read_bool_option(f, option, | |
955 "sort_case_sensitive", value, file_sort_case_sensitive); | |
1 | 956 |
957 confirm_delete = read_bool_option(f, option, | |
958 "confirm_delete", value, confirm_delete); | |
9 | 959 enable_delete_key = read_bool_option(f, option, |
960 "enable_delete_key", value, enable_delete_key); | |
961 safe_delete_enable = read_bool_option(f, option, | |
962 "safe_delete", value, safe_delete_enable); | |
963 safe_delete_path = read_char_option(f, option, | |
964 "safe_delete_path", value, safe_delete_path); | |
965 safe_delete_size = read_int_option(f, option, | |
966 "safe_delete_size", value, safe_delete_size); | |
1 | 967 |
968 tools_float = read_bool_option(f, option, | |
969 "tools_float", value, tools_float); | |
970 tools_hidden = read_bool_option(f, option, | |
971 "tools_hidden", value, tools_hidden); | |
972 restore_tool = read_bool_option(f, option, | |
973 "restore_tool_state", value, restore_tool); | |
974 | |
9 | 975 toolbar_hidden = read_bool_option(f, option, |
976 "toolbar_hidden", value, toolbar_hidden); | |
977 | |
4 | 978 mousewheel_scrolls = read_bool_option(f, option, |
979 "mouse_wheel_scrolls", value, mousewheel_scrolls); | |
9 | 980 enable_in_place_rename = read_bool_option(f, option, |
981 "in_place_rename", value, enable_in_place_rename); | |
4 | 982 |
9 | 983 recent_list_max = read_int_option(f, option, |
984 "open_recent_max", value, recent_list_max); | |
985 | |
986 tile_cache_max = read_int_option(f, option, | |
987 "image_cache_size_max", value, tile_cache_max); | |
988 | |
989 thumbnail_quality = CLAMP(read_int_option(f, option, | |
990 "thumbnail_quality", value, thumbnail_quality), GDK_INTERP_NEAREST, GDK_INTERP_HYPER); | |
991 zoom_quality = CLAMP(read_int_option(f, option, | |
992 "zoom_quality", value, zoom_quality), GDK_INTERP_NEAREST, GDK_INTERP_HYPER); | |
993 dither_quality = CLAMP(read_int_option(f, option, | |
994 "dither_quality", value, dither_quality), GDK_RGB_DITHER_NONE, GDK_RGB_DITHER_MAX); | |
995 | |
996 zoom_increment = read_int_option(f, option, | |
997 "zoom_increment", value, zoom_increment); | |
998 | |
999 enable_read_ahead = read_bool_option(f, option, | |
1000 "enable_read_ahead", value, enable_read_ahead); | |
4 | 1001 |
9 | 1002 place_dialogs_under_mouse = read_bool_option(f, option, |
1003 "display_dialogs_under_mouse", value, place_dialogs_under_mouse); | |
1004 | |
208
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
1005 user_specified_window_background = read_bool_option(f, option, |
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
1006 "user_specified_window_background", value, user_specified_window_background); |
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
1007 read_color_option(f, option, |
fa0e05f985c3
set user-defined color as image background - patch by Laurent MONIN
nadvornik
parents:
196
diff
changeset
|
1008 "window_background_color", value, &window_background_color); |
1 | 1009 |
9 | 1010 fullscreen_screen = read_int_option(f, option, |
1011 "fullscreen_screen", value, fullscreen_screen); | |
1012 fullscreen_clean_flip = read_bool_option(f, option, | |
1013 "fullscreen_clean_flip", value, fullscreen_clean_flip); | |
1014 fullscreen_disable_saver = read_bool_option(f, option, | |
1015 "fullscreen_disable_saver", value, fullscreen_disable_saver); | |
1016 fullscreen_above = read_bool_option(f, option, | |
1017 "fullscreen_above", value, fullscreen_above); | |
218
f4a0555794a9
Customizable info overlay in fullscreen, based on the patch posted to gqview-devel list by Timo on 2007-09-10.
zas_
parents:
217
diff
changeset
|
1018 show_fullscreen_info = read_bool_option(f, option, |
f4a0555794a9
Customizable info overlay in fullscreen, based on the patch posted to gqview-devel list by Timo on 2007-09-10.
zas_
parents:
217
diff
changeset
|
1019 "show_fullscreen_info", value, show_fullscreen_info); |
f4a0555794a9
Customizable info overlay in fullscreen, based on the patch posted to gqview-devel list by Timo on 2007-09-10.
zas_
parents:
217
diff
changeset
|
1020 fullscreen_info = read_char_option(f, option, |
f4a0555794a9
Customizable info overlay in fullscreen, based on the patch posted to gqview-devel list by Timo on 2007-09-10.
zas_
parents:
217
diff
changeset
|
1021 "fullscreen_info", value_all, fullscreen_info); |
9 | 1022 |
1023 dupe_custom_threshold = read_int_option(f, option, | |
1024 "custom_similarity_threshold", value, dupe_custom_threshold); | |
1025 | |
1026 /* slideshow options */ | |
1027 | |
1028 slideshow_delay = read_int_unit_option(f, option, | |
1029 "slideshow_delay", value, slideshow_delay, SLIDESHOW_SUBSECOND_PRECISION); | |
1 | 1030 slideshow_random = read_bool_option(f, option, |
1031 "slideshow_random", value, slideshow_random); | |
1032 slideshow_repeat = read_bool_option(f, option, | |
1033 "slideshow_repeat", value, slideshow_repeat); | |
1034 | |
1035 /* filtering options */ | |
1036 | |
1037 show_dot_files = read_bool_option(f, option, | |
1038 "show_dotfiles", value, show_dot_files); | |
1039 file_filter_disable = read_bool_option(f, option, | |
1040 "disable_filtering", value, file_filter_disable); | |
1041 | |
9 | 1042 if (strcasecmp(option, "filter_ext") == 0) |
1043 { | |
1044 filter_parse(value_all); | |
1045 } | |
1 | 1046 |
145
8be2cc687304
fixed grouping sidecar files and made it configurable via config file
nadvornik
parents:
113
diff
changeset
|
1047 if (strcasecmp(option, "sidecar_ext") == 0) |
8be2cc687304
fixed grouping sidecar files and made it configurable via config file
nadvornik
parents:
113
diff
changeset
|
1048 { |
170
9a56e3d13e67
basic sidecar files configuration via preferences dialog
nadvornik
parents:
145
diff
changeset
|
1049 sidecar_ext_parse(value_all, TRUE); |
145
8be2cc687304
fixed grouping sidecar files and made it configurable via config file
nadvornik
parents:
113
diff
changeset
|
1050 } |
8be2cc687304
fixed grouping sidecar files and made it configurable via config file
nadvornik
parents:
113
diff
changeset
|
1051 |
113
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1052 /* Color Profiles */ |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1053 |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1054 color_profile_enabled = read_bool_option(f, option, |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1055 "color_profile_enabled", value, color_profile_enabled); |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1056 color_profile_use_image = read_bool_option(f, option, |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1057 "color_profile_use_image", value, color_profile_use_image); |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1058 color_profile_input_type = read_int_option(f, option, |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1059 "color_profile_input_type", value, color_profile_input_type); |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1060 |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1061 if (strncasecmp(option, "color_profile_input_file_", 25) == 0) |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1062 { |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1063 i = strtol(option + 25, NULL, 0) - 1; |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1064 if (i >= 0 && i < COLOR_PROFILE_INPUTS) |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1065 { |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1066 color_profile_input_file[i] = read_char_option(f, option, |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1067 option, value, color_profile_input_file[i]); |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1068 } |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1069 } |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1070 if (strncasecmp(option, "color_profile_input_name_", 25) == 0) |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1071 { |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1072 i = strtol(option + 25, NULL, 0) - 1; |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1073 if (i >= 0 && i < COLOR_PROFILE_INPUTS) |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1074 { |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1075 color_profile_input_name[i] = read_char_option(f, option, |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1076 option, value, color_profile_input_name[i]); |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1077 } |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1078 } |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1079 |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1080 color_profile_screen_type = read_int_option(f, option, |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1081 "color_profile_screen_type", value, color_profile_screen_type); |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1082 color_profile_screen_file = read_char_option(f, option, |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1083 "color_profile_screen_file_1", value, color_profile_screen_file); |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
41
diff
changeset
|
1084 |
1 | 1085 /* External Programs */ |
1086 | |
9 | 1087 if (strncasecmp(option, "external_", 9) == 0) |
1 | 1088 { |
1089 i = strtol(option + 9, NULL, 0); | |
9 | 1090 if (i > 0 && i <= GQVIEW_EDITOR_SLOTS) |
1 | 1091 { |
217 | 1092 const gchar *ptr; |
1 | 1093 i--; |
1094 g_free(editor_name[i]); | |
1095 g_free(editor_command[i]); | |
217 | 1096 |
1097 editor_name[i] = quoted_value(value_all, &ptr); | |
1098 editor_command[i] = quoted_value(ptr, NULL); | |
1 | 1099 } |
1100 } | |
1101 | |
9 | 1102 /* colection options */ |
1103 | |
1104 collection_rectangular_selection = read_bool_option(f, option, | |
1105 "rectangular_selections", value, collection_rectangular_selection); | |
1106 | |
1 | 1107 /* window positions */ |
1108 | |
1109 save_window_positions = read_bool_option(f, option, | |
1110 "restore_window_positions", value, save_window_positions); | |
1111 | |
1112 main_window_x = read_int_option(f, option, | |
1113 "main_window_x", value, main_window_x); | |
1114 main_window_y = read_int_option(f, option, | |
1115 "main_window_y", value, main_window_y); | |
1116 main_window_w = read_int_option(f, option, | |
1117 "main_window_width", value, main_window_w); | |
1118 main_window_h = read_int_option(f, option, | |
1119 "main_window_height", value, main_window_h); | |
9 | 1120 main_window_maximized = read_bool_option(f, option, |
1121 "main_window_maximized", value, main_window_maximized); | |
1 | 1122 float_window_x = read_int_option(f, option, |
1123 "float_window_x", value, float_window_x); | |
1124 float_window_y = read_int_option(f, option, | |
1125 "float_window_y", value, float_window_y); | |
1126 float_window_w = read_int_option(f, option, | |
1127 "float_window_width", value, float_window_w); | |
1128 float_window_h = read_int_option(f, option, | |
1129 "float_window_height", value, float_window_h); | |
9 | 1130 float_window_divider = read_int_option(f, option, |
1131 "float_window_divider", value, float_window_divider); | |
1132 window_hdivider_pos = read_int_option(f, option, | |
1133 "divider_position_h", value, window_hdivider_pos); | |
1134 window_vdivider_pos = read_int_option(f, option, | |
1135 "divider_position_v", value, window_vdivider_pos); | |
1136 | |
222
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
218
diff
changeset
|
1137 if (0 == strncasecmp(option, "exif_", 5)) |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
218
diff
changeset
|
1138 { |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
218
diff
changeset
|
1139 for (i = 0; ExifUIList[i].key; i++) |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
218
diff
changeset
|
1140 if (0 == strcasecmp(option+5, ExifUIList[i].key)) |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
218
diff
changeset
|
1141 ExifUIList[i].current = strtol(value, NULL, 10); |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
218
diff
changeset
|
1142 } |
1 | 1143 } |
1144 | |
1145 fclose(f); | |
1146 g_free(rc_path); | |
1147 } | |
1148 |