8a8f4f0568fbe3792dfa9f933d4cb3ca8c08454a
[lxde/pcmanfm.git] / src / app-config.c
1 /*
2 * app-config.c
3 *
4 * Copyright 2010 PCMan <pcman.tw@gmail.com>
5 * Copyright 2012-2014 Andriy Grytsenko (LStranger) <andrej@rep.kiev.ua>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 * MA 02110-1301, USA.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include "app-config.h"
28
29 #include <libfm/fm-gtk.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <stdlib.h>
33
34 #include "tab-page.h"
35
36 #if !FM_CHECK_VERSION(1, 2, 0)
37 typedef struct
38 {
39 GKeyFile *kf;
40 char *group; /* allocated if not in cache */
41 char *filepath; /* NULL if in cache */
42 gboolean changed;
43 } FmFolderConfig;
44
45 static GKeyFile *fc_cache = NULL;
46
47 static gboolean dir_cache_changed = FALSE;
48
49 static FmFolderConfig *fm_folder_config_open(FmPath *path)
50 {
51 FmFolderConfig *fc = g_slice_new(FmFolderConfig);
52 FmPath *sub_path;
53
54 fc->changed = FALSE;
55 /* clear .directory file first */
56 sub_path = fm_path_new_child(path, ".directory");
57 fc->filepath = fm_path_to_str(sub_path);
58 fm_path_unref(sub_path);
59 if (g_file_test(fc->filepath, G_FILE_TEST_EXISTS))
60 {
61 fc->kf = g_key_file_new();
62 if (g_key_file_load_from_file(fc->kf, fc->filepath,
63 G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
64 NULL) &&
65 g_key_file_has_group(fc->kf, "File Manager"))
66 {
67 fc->group = "File Manager";
68 return fc;
69 }
70 g_key_file_free(fc->kf);
71 }
72 g_free(fc->filepath);
73 fc->filepath = NULL;
74 fc->group = fm_path_to_str(path);
75 fc->kf = fc_cache;
76 return fc;
77 }
78
79 static gboolean fm_folder_config_close(FmFolderConfig *fc, GError **error)
80 {
81 gboolean ret = TRUE;
82
83 if (fc->filepath)
84 {
85 if (fc->changed)
86 {
87 char *out;
88 gsize len;
89
90 out = g_key_file_to_data(fc->kf, &len, error);
91 if (!out || !g_file_set_contents(fc->filepath, out, len, error))
92 ret = FALSE;
93 g_free(out);
94 }
95 g_free(fc->filepath);
96 g_key_file_free(fc->kf);
97 }
98 else
99 {
100 if (fc->changed)
101 {
102 /* raise 'changed' flag and schedule config save */
103 dir_cache_changed = TRUE;
104 pcmanfm_save_config(FALSE);
105 }
106 g_free(fc->group);
107 }
108
109 g_slice_free(FmFolderConfig, fc);
110 return ret;
111 }
112
113 static gboolean fm_folder_config_is_empty(FmFolderConfig *fc)
114 {
115 return !g_key_file_has_group(fc->kf, fc->group);
116 }
117
118 static gboolean fm_folder_config_get_integer(FmFolderConfig *fc, const char *key,
119 gint *val)
120 {
121 return fm_key_file_get_int(fc->kf, fc->group, key, val);
122 }
123
124 static gboolean fm_folder_config_get_boolean(FmFolderConfig *fc, const char *key,
125 gboolean *val)
126 {
127 return fm_key_file_get_bool(fc->kf, fc->group, key, val);
128 }
129
130 static char *fm_folder_config_get_string(FmFolderConfig *fc, const char *key)
131 {
132 return g_key_file_get_string(fc->kf, fc->group, key, NULL);
133 }
134
135 static char **fm_folder_config_get_string_list(FmFolderConfig *fc,
136 const char *key, gsize *length)
137 {
138 return g_key_file_get_string_list(fc->kf, fc->group, key, length, NULL);
139 }
140
141 #if !FM_CHECK_VERSION(1, 0, 2)
142 static void fm_folder_config_set_integer(FmFolderConfig *fc, const char *key,
143 gint val)
144 {
145 fc->changed = TRUE;
146 g_key_file_set_integer(fc->kf, fc->group, key, val);
147 }
148 #endif
149
150 static void fm_folder_config_set_boolean(FmFolderConfig *fc, const char *key,
151 gboolean val)
152 {
153 fc->changed = TRUE;
154 g_key_file_set_boolean(fc->kf, fc->group, key, val);
155 }
156
157 static void fm_folder_config_set_string(FmFolderConfig *fc, const char *key,
158 const char *string)
159 {
160 fc->changed = TRUE;
161 g_key_file_set_string(fc->kf, fc->group, key, string);
162 }
163
164 static void fm_folder_config_set_string_list(FmFolderConfig *fc, const char *key,
165 const gchar * const list[],
166 gsize length)
167 {
168 fc->changed = TRUE;
169 g_key_file_set_string_list(fc->kf, fc->group, key, list, length);
170 }
171
172 static void fm_folder_config_remove_key(FmFolderConfig *fc, const char *key)
173 {
174 fc->changed = TRUE;
175 g_key_file_remove_key(fc->kf, fc->group, key, NULL);
176 }
177
178 static void fm_folder_config_purge(FmFolderConfig *fc)
179 {
180 fc->changed = TRUE;
181 g_key_file_remove_group(fc->kf, fc->group, NULL);
182 }
183
184 static void fm_folder_config_save_cache(const char *dir_path)
185 {
186 char *path, *path2, *path3;
187 char *out;
188 gsize len;
189
190 /* if per-directory cache was changed since last invocation then save it */
191 if (dir_cache_changed)
192 {
193 out = g_key_file_to_data(fc_cache, &len, NULL);
194 if (out)
195 {
196 /* create temp file with settings */
197 path = g_build_filename(dir_path, "dir-settings.conf", NULL);
198 path2 = g_build_filename(dir_path, "dir-settings.tmp", NULL);
199 path3 = g_build_filename(dir_path, "dir-settings.backup", NULL);
200 /* do safe replace now, the file is important enough to be lost */
201 if (g_file_set_contents(path2, out, len, NULL))
202 {
203 /* backup old cache file */
204 g_unlink(path3);
205 if (!g_file_test(path, G_FILE_TEST_EXISTS) ||
206 g_rename(path, path3) == 0)
207 {
208 /* rename temp file */
209 if (g_rename(path2, path) == 0)
210 {
211 /* success! remove the old cache file */
212 g_unlink(path3);
213 /* reset the 'changed' flag */
214 dir_cache_changed = FALSE;
215 }
216 else
217 g_warning("cannot rename %s to %s", path2, path);
218 }
219 else
220 g_warning("cannot rename %s to %s", path, path3);
221 }
222 else
223 g_warning("cannot save %s", path2);
224 g_free(path);
225 g_free(path2);
226 g_free(path3);
227 g_free(out);
228 }
229 }
230 }
231 #endif /* LibFM < 1.2.0 */
232
233 #if FM_CHECK_VERSION(1, 0, 2)
234 static void _parse_sort(GKeyFile *kf, const char *group, FmSortMode *mode,
235 FmFolderModelCol *col)
236 {
237 int tmp_int;
238 char **sort;
239
240 /* parse "sort" strings list first */
241 sort = g_key_file_get_string_list(kf, group, "sort", NULL, NULL);
242 if (sort)
243 {
244 FmSortMode tmp_mode = 0;
245 FmFolderModelCol tmp_col = FM_FOLDER_MODEL_COL_DEFAULT;
246
247 for (tmp_int = 0; sort[tmp_int]; tmp_int++)
248 {
249 if (tmp_int == 0) /* column should be first! */
250 tmp_col = fm_folder_model_get_col_by_name(sort[tmp_int]);
251 else if (strcmp(sort[tmp_int], "ascending") == 0)
252 tmp_mode = (tmp_mode & ~FM_SORT_ORDER_MASK) | FM_SORT_ASCENDING;
253 else if (strcmp(sort[tmp_int], "descending") == 0)
254 tmp_mode = (tmp_mode & ~FM_SORT_ORDER_MASK) | FM_SORT_DESCENDING;
255 else if (strcmp(sort[tmp_int], "case") == 0)
256 tmp_mode |= FM_SORT_CASE_SENSITIVE;
257 #if FM_CHECK_VERSION(1, 2, 0)
258 else if (strcmp(sort[tmp_int], "mingle") == 0)
259 tmp_mode |= FM_SORT_NO_FOLDER_FIRST;
260 #endif
261 }
262 *mode = tmp_mode;
263 if (tmp_col != FM_FOLDER_MODEL_COL_DEFAULT)
264 *col = tmp_col;
265 g_strfreev(sort);
266 return;
267 }
268 /* parse fallback old style sort config */
269 if(fm_key_file_get_int(kf, group, "sort_type", &tmp_int) &&
270 tmp_int == GTK_SORT_DESCENDING)
271 *mode = FM_SORT_DESCENDING;
272 else
273 *mode = FM_SORT_ASCENDING;
274 if(fm_key_file_get_int(kf, group, "sort_by", &tmp_int) &&
275 #if FM_CHECK_VERSION(1, 2, 0)
276 fm_folder_model_col_is_valid((guint)tmp_int))
277 #else
278 FM_FOLDER_MODEL_COL_IS_VALID((guint)tmp_int))
279 #endif
280 *col = tmp_int;
281 }
282 #else /* < 1.0.2 */
283 static void _parse_sort(GKeyFile *kf, const char *group, GtkSortType *mode,
284 int *col)
285 {
286 int tmp_int;
287
288 if(fm_key_file_get_int(kf, group, "sort_type", &tmp_int) &&
289 tmp_int == GTK_SORT_DESCENDING)
290 *mode = GTK_SORT_DESCENDING;
291 else
292 *mode = GTK_SORT_ASCENDING;
293 if(fm_key_file_get_int(kf, group, "sort_by", &tmp_int) &&
294 FM_FOLDER_MODEL_COL_IS_VALID((guint)tmp_int))
295 *col = tmp_int;
296 }
297 #endif
298
299 #if FM_CHECK_VERSION(1, 0, 2)
300 static void _save_sort(GString *buf, FmSortMode mode, FmFolderModelCol col)
301 {
302 const char *name = fm_folder_model_col_get_name(col);
303
304 if (name == NULL) /* FM_FOLDER_MODEL_COL_NAME is always valid */
305 name = fm_folder_model_col_get_name(FM_FOLDER_MODEL_COL_NAME);
306 g_string_append_printf(buf, "sort=%s;%s;", name,
307 FM_SORT_IS_ASCENDING(mode) ? "ascending" : "descending");
308 if (mode & FM_SORT_CASE_SENSITIVE)
309 g_string_append(buf, "case;");
310 #if FM_CHECK_VERSION(1, 2, 0)
311 if (mode & FM_SORT_NO_FOLDER_FIRST)
312 g_string_append(buf, "mingle;");
313 #endif
314 g_string_append_c(buf, '\n');
315 }
316 #else
317 static void _save_sort(GString *buf, GtkSortType type, int col)
318 {
319 g_string_append_printf(buf, "sort_type=%d\n", sort_type);
320 g_string_append_printf(buf, "sort_by=%d\n", col);
321 }
322 #endif
323
324 /* we use capitalized keys here because it is de-facto standard for
325 desktop entry files and we use those keys in '.directory' as well */
326 #if FM_CHECK_VERSION(1, 0, 2)
327 static gboolean _parse_config_for_path(FmFolderConfig *fc,
328 FmSortMode *mode, FmFolderModelCol *by,
329 #else
330 static gboolean _parse_config_for_path(FmFolderConfig *fc,
331 GtkSortType *mode, gint *by,
332 #endif
333 FmStandardViewMode *view_mode,
334 gboolean *show_hidden, char ***columns)
335 {
336 char *tmp;
337 int tmp_int;
338 /* we cannot use _parse_sort() here because we have no access to GKeyFile */
339 #if FM_CHECK_VERSION(1, 0, 2)
340 char **sort;
341
342 /* parse "sort" strings list first */
343 sort = fm_folder_config_get_string_list(fc, "Sort", NULL);
344 if (sort)
345 {
346 FmSortMode tmp_mode = 0;
347 FmFolderModelCol tmp_col = FM_FOLDER_MODEL_COL_DEFAULT;
348
349 for (tmp_int = 0; sort[tmp_int]; tmp_int++)
350 {
351 if (tmp_int == 0) /* column should be first! */
352 tmp_col = fm_folder_model_get_col_by_name(sort[tmp_int]);
353 else if (strcmp(sort[tmp_int], "ascending") == 0)
354 tmp_mode = (tmp_mode & ~FM_SORT_ORDER_MASK) | FM_SORT_ASCENDING;
355 else if (strcmp(sort[tmp_int], "descending") == 0)
356 tmp_mode = (tmp_mode & ~FM_SORT_ORDER_MASK) | FM_SORT_DESCENDING;
357 else if (strcmp(sort[tmp_int], "case") == 0)
358 tmp_mode |= FM_SORT_CASE_SENSITIVE;
359 #if FM_CHECK_VERSION(1, 2, 0)
360 else if (strcmp(sort[tmp_int], "mingle") == 0)
361 tmp_mode |= FM_SORT_NO_FOLDER_FIRST;
362 #endif
363 }
364 *mode = tmp_mode;
365 if (tmp_col != FM_FOLDER_MODEL_COL_DEFAULT)
366 *by = tmp_col;
367 g_strfreev(sort);
368 }
369 else
370 {
371 /* parse fallback old style sort config */
372 if(fm_folder_config_get_integer(fc, "sort_type", &tmp_int) &&
373 tmp_int == GTK_SORT_DESCENDING)
374 *mode = FM_SORT_DESCENDING;
375 else
376 *mode = FM_SORT_ASCENDING;
377 if(fm_folder_config_get_integer(fc, "sort_by", &tmp_int) &&
378 #if FM_CHECK_VERSION(1, 2, 0)
379 fm_folder_model_col_is_valid((guint)tmp_int))
380 #else
381 FM_FOLDER_MODEL_COL_IS_VALID((guint)tmp_int))
382 #endif
383 *by = tmp_int;
384 }
385 #else /* < 1.0.2 */
386 if(fm_folder_config_get_integer(fc, "sort_type", &tmp_int) &&
387 tmp_int == GTK_SORT_DESCENDING)
388 *mode = GTK_SORT_DESCENDING;
389 else
390 *mode = GTK_SORT_ASCENDING;
391 if(fm_folder_config_get_integer(fc, "sort_by", &tmp_int) &&
392 FM_FOLDER_MODEL_COL_IS_VALID((guint)tmp_int))
393 *by = tmp_int;
394 #endif
395 if (view_mode && (tmp = fm_folder_config_get_string(fc, "ViewMode")))
396 {
397 *view_mode = fm_standard_view_mode_from_str(tmp);
398 g_free(tmp);
399 }
400 if (show_hidden)
401 fm_folder_config_get_boolean(fc, "ShowHidden", show_hidden);
402 #if FM_CHECK_VERSION(1, 0, 2)
403 if (columns)
404 *columns = fm_folder_config_get_string_list(fc, "Columns", NULL);
405 #endif
406 return TRUE;
407 }
408
409
410 static void fm_app_config_finalize (GObject *object);
411
412 G_DEFINE_TYPE(FmAppConfig, fm_app_config, FM_CONFIG_TYPE);
413
414
415 static void fm_app_config_class_init(FmAppConfigClass *klass)
416 {
417 GObjectClass *g_object_class;
418 g_object_class = G_OBJECT_CLASS(klass);
419 g_object_class->finalize = fm_app_config_finalize;
420 }
421
422
423 static void fm_app_config_finalize(GObject *object)
424 {
425 FmAppConfig *cfg;
426
427 g_return_if_fail(object != NULL);
428 g_return_if_fail(IS_FM_APP_CONFIG(object));
429
430 cfg = (FmAppConfig*)object;
431 #if FM_CHECK_VERSION(1, 0, 2)
432 g_strfreev(cfg->columns);
433 #endif
434 if (cfg->desktop_section.configured)
435 {
436 if(cfg->desktop_section.wallpapers_configured > 0)
437 {
438 int i;
439
440 for(i = 0; i < cfg->desktop_section.wallpapers_configured; i++)
441 g_free(cfg->desktop_section.wallpapers[i]);
442 g_free(cfg->desktop_section.wallpapers);
443 }
444 g_free(cfg->desktop_section.wallpaper);
445 g_free(cfg->desktop_section.desktop_font);
446 g_free(cfg->desktop_section.folder);
447 }
448 /*g_free(cfg->su_cmd);*/
449 g_hash_table_unref(cfg->autorun_choices);
450
451 #if !FM_CHECK_VERSION(1, 2, 0)
452 g_key_file_free(fc_cache);
453 fc_cache = NULL;
454 #endif
455
456 #if FM_CHECK_VERSION(1, 2, 0)
457 g_free(cfg->home_path);
458 #endif
459
460 G_OBJECT_CLASS(fm_app_config_parent_class)->finalize(object);
461 }
462
463 static void _free_archoice(gpointer data)
464 {
465 FmAutorunChoice *choice = data;
466
467 g_free(choice->last_used);
468 g_slice_free(FmAutorunChoice, choice);
469 }
470
471 static void fm_app_config_init(FmAppConfig *cfg)
472 {
473 /* load libfm config file */
474 fm_config_load_from_file((FmConfig*)cfg, NULL);
475
476 cfg->bm_open_method = FM_OPEN_IN_CURRENT_TAB;
477
478 cfg->mount_on_startup = TRUE;
479 cfg->mount_removable = TRUE;
480 cfg->autorun = TRUE;
481
482 cfg->desktop_section.desktop_fg.red = cfg->desktop_section.desktop_fg.green = cfg->desktop_section.desktop_fg.blue = 65535;
483 cfg->win_width = 640;
484 cfg->win_height = 480;
485 cfg->splitter_pos = 150;
486 cfg->max_tab_chars = 32;
487 cfg->media_in_new_tab = FALSE;
488 cfg->desktop_folder_new_win = FALSE;
489
490 cfg->side_pane_mode = FM_SP_PLACES;
491
492 cfg->view_mode = FM_FV_ICON_VIEW;
493 cfg->show_hidden = FALSE;
494 #if FM_CHECK_VERSION(1, 0, 2)
495 cfg->sort_type = FM_SORT_ASCENDING;
496 cfg->sort_by = FM_FOLDER_MODEL_COL_NAME;
497 #if FM_CHECK_VERSION(1, 2, 0)
498 cfg->desktop_section.desktop_sort_type = FM_SORT_ASCENDING | FM_SORT_NO_FOLDER_FIRST;
499 #else
500 cfg->desktop_section.desktop_sort_type = FM_SORT_ASCENDING;
501 #endif
502 cfg->desktop_section.desktop_sort_by = FM_FOLDER_MODEL_COL_MTIME;
503 #else
504 cfg->sort_type = GTK_SORT_ASCENDING;
505 cfg->sort_by = COL_FILE_NAME;
506 cfg->desktop_section.desktop_sort_type = GTK_SORT_ASCENDING;
507 cfg->desktop_section.desktop_sort_by = COL_FILE_MTIME;
508 #endif
509 cfg->desktop_section.wallpaper_common = TRUE;
510 #if FM_CHECK_VERSION(1, 2, 0)
511 cfg->desktop_section.show_documents = FALSE;
512 cfg->desktop_section.show_trash = TRUE;
513 cfg->desktop_section.show_mounts = FALSE;
514 #endif
515 cfg->desktop_section.folder = NULL;
516 cfg->tb.visible = cfg->tb.new_tab = cfg->tb.nav = cfg->tb.home = TRUE;
517 cfg->tb.new_win = FALSE;
518 cfg->autorun_choices = g_hash_table_new_full(g_str_hash, g_str_equal,
519 g_free, _free_archoice);
520 cfg->show_statusbar = TRUE;
521 #if FM_CHECK_VERSION(1, 2, 0)
522 cfg->home_path = NULL;
523 cfg->focus_previous = FALSE;
524 #endif
525 cfg->change_tab_on_drop = TRUE;
526 cfg->close_on_unmount = TRUE;
527 cfg->maximized = FALSE;
528 cfg->pathbar_mode_buttons = FALSE;
529 }
530
531
532 FmConfig *fm_app_config_new(void)
533 {
534 return (FmConfig*)g_object_new(FM_APP_CONFIG_TYPE, NULL);
535 }
536
537 void fm_app_config_load_desktop_config(GKeyFile *kf, const char *group, FmDesktopConfig *cfg)
538 {
539 char* tmp;
540
541 if (!g_key_file_has_group(kf, group))
542 return;
543
544 /* set some defaults, assuming config is zeroed now */
545 cfg->desktop_fg.red = cfg->desktop_fg.green = cfg->desktop_fg.blue = 65535;
546 #if FM_CHECK_VERSION(1, 0, 2)
547 #if FM_CHECK_VERSION(1, 2, 0)
548 cfg->desktop_sort_type = FM_SORT_ASCENDING | FM_SORT_NO_FOLDER_FIRST;
549 #else
550 cfg->desktop_sort_type = FM_SORT_ASCENDING;
551 #endif
552 cfg->desktop_sort_by = FM_FOLDER_MODEL_COL_MTIME;
553 #else
554 cfg->desktop_sort_type = GTK_SORT_ASCENDING;
555 cfg->desktop_sort_by = COL_FILE_MTIME;
556 #endif
557 cfg->wallpaper_common = TRUE;
558 #if FM_CHECK_VERSION(1, 2, 0)
559 cfg->show_trash = TRUE;
560 #endif
561 cfg->configured = TRUE;
562 tmp = g_key_file_get_string(kf, group, "wallpaper_mode", NULL);
563 if (tmp)
564 {
565 if (tmp[0] >= '0' && tmp[0] <= '4') /* backward compatibility */
566 cfg->wallpaper_mode = tmp[0] - '0';
567 else
568 cfg->wallpaper_mode = fm_app_wallpaper_get_mode_by_name(tmp);
569 if (cfg->wallpaper_mode == (FmWallpaperMode)-1)
570 cfg->wallpaper_mode = FM_WP_COLOR; /* fallback */
571 g_free(tmp);
572 }
573
574 if(cfg->wallpapers_configured > 0)
575 {
576 int i;
577
578 for(i = 0; i < cfg->wallpapers_configured; i++)
579 g_free(cfg->wallpapers[i]);
580 g_free(cfg->wallpapers);
581 }
582 g_free(cfg->wallpaper);
583 cfg->wallpaper = NULL;
584 fm_key_file_get_int(kf, group, "wallpapers_configured", &cfg->wallpapers_configured);
585 if(cfg->wallpapers_configured > 0)
586 {
587 char wpn_buf[32];
588 int i;
589
590 cfg->wallpapers = g_malloc(cfg->wallpapers_configured * sizeof(char *));
591 for(i = 0; i < cfg->wallpapers_configured; i++)
592 {
593 snprintf(wpn_buf, sizeof(wpn_buf), "wallpaper%d", i);
594 tmp = g_key_file_get_string(kf, group, wpn_buf, NULL);
595 cfg->wallpapers[i] = tmp;
596 }
597 }
598 fm_key_file_get_bool(kf, group, "wallpaper_common", &cfg->wallpaper_common);
599 if (cfg->wallpaper_common)
600 {
601 tmp = g_key_file_get_string(kf, group, "wallpaper", NULL);
602 if (tmp && tmp[0] == '\0') /* ignore empty string */
603 {
604 g_free(tmp);
605 tmp = NULL;
606 }
607 g_free(cfg->wallpaper);
608 cfg->wallpaper = tmp;
609 }
610
611 tmp = g_key_file_get_string(kf, group, "desktop_bg", NULL);
612 if(tmp)
613 {
614 gdk_color_parse(tmp, &cfg->desktop_bg);
615 g_free(tmp);
616 }
617 tmp = g_key_file_get_string(kf, group, "desktop_fg", NULL);
618 if(tmp)
619 {
620 gdk_color_parse(tmp, &cfg->desktop_fg);
621 g_free(tmp);
622 }
623 tmp = g_key_file_get_string(kf, group, "desktop_shadow", NULL);
624 if(tmp)
625 {
626 gdk_color_parse(tmp, &cfg->desktop_shadow);
627 g_free(tmp);
628 }
629
630 tmp = g_key_file_get_string(kf, group, "desktop_font", NULL);
631 g_free(cfg->desktop_font);
632 cfg->desktop_font = tmp;
633
634 g_free(cfg->folder);
635 cfg->folder = g_key_file_get_string(kf, group, "folder", NULL);
636
637 fm_key_file_get_bool(kf, group, "show_wm_menu", &cfg->show_wm_menu);
638 _parse_sort(kf, group, &cfg->desktop_sort_type, &cfg->desktop_sort_by);
639 #if FM_CHECK_VERSION(1, 2, 0)
640 fm_key_file_get_bool(kf, group, "show_documents", &cfg->show_documents);
641 fm_key_file_get_bool(kf, group, "show_trash", &cfg->show_trash);
642 fm_key_file_get_bool(kf, group, "show_mounts", &cfg->show_mounts);
643 #endif
644 }
645
646 void fm_app_config_load_from_key_file(FmAppConfig* cfg, GKeyFile* kf)
647 {
648 #if FM_CHECK_VERSION(1, 0, 2)
649 char *tmp;
650 char **tmpv;
651 #endif
652 int tmp_int, i;
653
654 /* behavior */
655 fm_key_file_get_int(kf, "config", "bm_open_method", &cfg->bm_open_method);
656 /*tmp = g_key_file_get_string(kf, "config", "su_cmd", NULL);
657 g_free(cfg->su_cmd);
658 cfg->su_cmd = tmp;*/
659 #if FM_CHECK_VERSION(1, 2, 0)
660 g_free(cfg->home_path);
661 cfg->home_path = g_key_file_get_string(kf, "config", "home_path", NULL);
662 #endif
663
664 /* volume management */
665 fm_key_file_get_bool(kf, "volume", "mount_on_startup", &cfg->mount_on_startup);
666 fm_key_file_get_bool(kf, "volume", "mount_removable", &cfg->mount_removable);
667 fm_key_file_get_bool(kf, "volume", "autorun", &cfg->autorun);
668
669 /* [desktop] section */
670 fm_app_config_load_desktop_config(kf, "desktop", &cfg->desktop_section);
671
672 /* ui */
673 fm_key_file_get_bool(kf, "ui", "always_show_tabs", &cfg->always_show_tabs);
674 fm_key_file_get_int(kf, "ui", "hide_close_btn", &cfg->hide_close_btn);
675 fm_key_file_get_int(kf, "ui", "max_tab_chars", &cfg->max_tab_chars);
676
677 fm_key_file_get_int(kf, "ui", "win_width", &cfg->win_width);
678 fm_key_file_get_int(kf, "ui", "win_height", &cfg->win_height);
679 fm_key_file_get_bool(kf, "ui", "maximized", &cfg->maximized);
680
681 fm_key_file_get_int(kf, "ui", "splitter_pos", &cfg->splitter_pos);
682
683 fm_key_file_get_bool(kf, "ui", "media_in_new_tab", &cfg->media_in_new_tab);
684 fm_key_file_get_bool(kf, "ui", "desktop_folder_new_win", &cfg->desktop_folder_new_win);
685 fm_key_file_get_bool(kf, "ui", "change_tab_on_drop", &cfg->change_tab_on_drop);
686 fm_key_file_get_bool(kf, "ui", "close_on_unmount", &cfg->close_on_unmount);
687
688 #if FM_CHECK_VERSION(1, 2, 0)
689 fm_key_file_get_bool(kf, "ui", "focus_previous", &cfg->focus_previous);
690 tmp_int = FM_SP_NONE;
691 tmpv = g_key_file_get_string_list(kf, "ui", "side_pane_mode", NULL, NULL);
692 if (tmpv)
693 {
694 for (i = 0; tmpv[i]; i++)
695 {
696 tmp = tmpv[i];
697 if (strcmp(tmp, "hidden") == 0)
698 tmp_int |= FM_SP_HIDE;
699 else
700 {
701 tmp_int &= ~FM_SP_MODE_MASK;
702 if (tmp[0] >= '0' && tmp[0] <= '9') /* backward compatibility */
703 tmp_int |= atoi(tmp);
704 else /* portable way */
705 tmp_int |= fm_side_pane_get_mode_by_name(tmp);
706 }
707 }
708 g_strfreev(tmpv);
709 }
710 if ((tmp_int & FM_SP_MODE_MASK) != FM_SP_NONE)
711 #else
712 if(fm_key_file_get_int(kf, "ui", "side_pane_mode", &tmp_int))
713 #endif
714 cfg->side_pane_mode = (FmSidePaneMode)tmp_int;
715
716 /* default values for folder views */
717 #if FM_CHECK_VERSION(1, 0, 2)
718 tmp = g_key_file_get_string(kf, "ui", "view_mode", NULL);
719 if (tmp)
720 {
721 if (tmp[0] >= '0' && tmp[0] <= '9') /* backward compatibility */
722 tmp_int = atoi(tmp);
723 else /* portable way */
724 tmp_int = fm_standard_view_mode_from_str(tmp);
725 g_free(tmp);
726 }
727 if (tmp &&
728 #else
729 if(fm_key_file_get_int(kf, "ui", "view_mode", &tmp_int) &&
730 #endif
731 FM_STANDARD_VIEW_MODE_IS_VALID(tmp_int))
732 cfg->view_mode = tmp_int;
733 fm_key_file_get_bool(kf, "ui", "show_hidden", &cfg->show_hidden);
734 _parse_sort(kf, "ui", &cfg->sort_type, &cfg->sort_by);
735 #if FM_CHECK_VERSION(1, 0, 2)
736 tmpv = g_key_file_get_string_list(kf, "ui", "columns", NULL, NULL);
737 if (tmpv)
738 {
739 g_strfreev(cfg->columns);
740 cfg->columns = tmpv;
741 }
742 #endif
743 tmpv = g_key_file_get_string_list(kf, "ui", "toolbar", NULL, NULL);
744 if (tmpv)
745 {
746 /* reset defaults */
747 cfg->tb.visible = TRUE;
748 cfg->tb.new_win = cfg->tb.new_tab = cfg->tb.nav = cfg->tb.home = FALSE;
749 /* parse the array */
750 for (i = 0; tmpv[i]; i++)
751 {
752 tmp = tmpv[i];
753 if (cfg->tb.visible && strcmp(tmp, "hidden") == 0)
754 cfg->tb.visible = FALSE;
755 else if (!cfg->tb.new_win && strcmp(tmp, "newwin") == 0)
756 cfg->tb.new_win = TRUE;
757 else if (!cfg->tb.new_tab && strcmp(tmp, "newtab") == 0)
758 cfg->tb.new_tab = TRUE;
759 else if (!cfg->tb.nav && strcmp(tmp, "navigation") == 0)
760 cfg->tb.nav = TRUE;
761 else if (!cfg->tb.home && strcmp(tmp, "home") == 0)
762 cfg->tb.home = TRUE;
763 }
764 g_strfreev(tmpv);
765 }
766 fm_key_file_get_bool(kf, "ui", "show_statusbar", &cfg->show_statusbar);
767 if (g_key_file_has_group(kf, "autorun"))
768 {
769 tmpv = g_key_file_get_keys(kf, "autorun", NULL, NULL);
770 for (i = 0; tmpv[i]; i++)
771 {
772 tmp = g_key_file_get_string(kf, "autorun", tmpv[i], NULL);
773 if (tmp && tmp[0])
774 {
775 if (tmp[0] == '*')
776 fm_app_config_set_autorun_choice(cfg, tmpv[i],
777 tmp[1] ? &tmp[1] : NULL,
778 TRUE);
779 else
780 fm_app_config_set_autorun_choice(cfg, tmpv[i], tmp, FALSE);
781 }
782 g_free(tmp);
783 }
784 g_strfreev(tmpv);
785 }
786 fm_key_file_get_bool(kf, "ui", "pathbar_mode_buttons", &cfg->pathbar_mode_buttons);
787 }
788
789 void fm_app_config_load_from_profile(FmAppConfig* cfg, const char* name)
790 {
791 const gchar * const *dirs, * const *dir;
792 char *path;
793 GKeyFile* kf = g_key_file_new();
794 const char* old_name = name;
795
796 if(!name || !*name) /* if profile name is not provided, use 'default' */
797 {
798 name = "default";
799 old_name = "pcmanfm"; /* for compatibility with old versions. */
800 }
801
802 /* load system-wide settings */
803 dirs = g_get_system_config_dirs();
804 for(dir=dirs;*dir;++dir)
805 {
806 path = g_build_filename(*dir, "pcmanfm", name, "pcmanfm.conf", NULL);
807 if(g_key_file_load_from_file(kf, path, 0, NULL))
808 fm_app_config_load_from_key_file(cfg, kf);
809 g_free(path);
810 }
811
812 /* override system-wide settings with user-specific configuration */
813
814 /* For backward compatibility, try to load old config file and
815 * then migrate to new location */
816 path = g_strconcat(g_get_user_config_dir(), "/pcmanfm/", old_name, ".conf", NULL);
817 if(G_UNLIKELY(g_key_file_load_from_file(kf, path, 0, NULL)))
818 {
819 char* new_dir;
820 /* old config file is found, migrate to new profile format */
821 fm_app_config_load_from_key_file(cfg, kf);
822
823 /* create the profile dir */
824 new_dir = g_build_filename(g_get_user_config_dir(), "pcmanfm", name, NULL);
825 if(g_mkdir_with_parents(new_dir, 0700) == 0)
826 {
827 /* move the old config file to new location */
828 char* new_path = g_build_filename(new_dir, "pcmanfm.conf", NULL);
829 rename(path, new_path);
830 g_free(new_path);
831 }
832 g_free(new_dir);
833 }
834 else
835 {
836 g_free(path);
837 path = g_build_filename(g_get_user_config_dir(), "pcmanfm", name, "pcmanfm.conf", NULL);
838 if(g_key_file_load_from_file(kf, path, 0, NULL))
839 fm_app_config_load_from_key_file(cfg, kf);
840 }
841 g_free(path);
842 g_key_file_free(kf);
843
844 #if !FM_CHECK_VERSION(1, 2, 0)
845 fc_cache = g_key_file_new();
846 path = g_build_filename(g_get_user_config_dir(), "pcmanfm", name,
847 "dir-settings.conf", NULL);
848 g_key_file_load_from_file(fc_cache, path, 0, NULL);
849 g_free(path);
850 #endif
851 }
852
853 /**
854 * fm_app_config_get_config_for_path
855 * @path: path to get config
856 * @mode: (allow-none) (out): location to save sort mode
857 * @by: (allow-none) (out): location to save sort columns
858 * @view_mode: (allow-none) (out): location to save view mode
859 * @show_hidden: (allow-none) (out): location to save show hidden flag
860 * @columns: (allow-none) (out) (transfer none): location to save columns list
861 *
862 * Returns: %TRUE if @path has individual configuration.
863 */
864 #if FM_CHECK_VERSION(1, 0, 2)
865 gboolean fm_app_config_get_config_for_path(FmPath *path, FmSortMode *mode,
866 FmFolderModelCol *by,
867 #else
868 gboolean fm_app_config_get_config_for_path(FmPath *path, GtkSortType *mode,
869 gint *by,
870 #endif
871 FmStandardViewMode *view_mode,
872 gboolean *show_hidden,
873 char ***columns)
874 {
875 FmPath *sub_path;
876 FmFolderConfig *fc;
877 gboolean ret = TRUE;
878
879 /* preload defaults */
880 if (mode)
881 *mode = app_config->sort_type;
882 if (by)
883 *by = app_config->sort_by;
884 if (view_mode)
885 *view_mode = app_config->view_mode;
886 if (show_hidden)
887 *show_hidden = app_config->show_hidden;
888 #if FM_CHECK_VERSION(1, 0, 2)
889 if (columns)
890 *columns = app_config->columns;
891 #endif
892 fc = fm_folder_config_open(path);
893 if (!fm_folder_config_is_empty(fc))
894 _parse_config_for_path(fc, mode, by, view_mode, show_hidden, columns);
895 else if (!fm_path_is_native(path))
896 {
897 /* if path is non-native then try the scheme */
898 #if FM_CHECK_VERSION(1, 2, 0)
899 sub_path = fm_path_get_scheme_path(path);
900 #else
901 for (sub_path = path; fm_path_get_parent(sub_path) != NULL; )
902 sub_path = fm_path_get_parent(sub_path);
903 #endif
904 fm_folder_config_close(fc, NULL);
905 fc = fm_folder_config_open(sub_path);
906 if (!fm_folder_config_is_empty(fc))
907 _parse_config_for_path(fc, mode, by, view_mode, show_hidden, columns);
908 /* if path is search://... then use predefined values */
909 else if (strncmp(fm_path_get_basename(sub_path), "search:", 7) == 0)
910 {
911 if (view_mode)
912 *view_mode = FM_FV_LIST_VIEW;
913 if (show_hidden)
914 *show_hidden = TRUE;
915 #if FM_CHECK_VERSION(1, 0, 2)
916 if (columns)
917 {
918 static char *def[] = {"name", "desc", "dirname", "size", "mtime", NULL};
919 *columns = def;
920 }
921 #endif
922 }
923 else
924 ret = FALSE;
925 }
926 else
927 ret = FALSE;
928 fm_folder_config_close(fc, NULL);
929 return ret;
930 }
931
932 /**
933 * @path, @mode, @by, @show_hidden are mandatory
934 * @view_mode may be -1 to not change
935 * @columns may be %NULL to not change
936 */
937 #if FM_CHECK_VERSION(1, 0, 2)
938 void fm_app_config_save_config_for_path(FmPath *path, FmSortMode mode,
939 FmFolderModelCol by,
940 #else
941 void fm_app_config_save_config_for_path(FmPath *path, GtkSortType mode, gint by,
942 #endif
943 FmStandardViewMode view_mode,
944 gboolean show_hidden, char **columns)
945 {
946 FmPath *sub_path;
947 FmFolderConfig *fc;
948 #if FM_CHECK_VERSION(1, 0, 2)
949 char const *list[5];
950 int n = 2;
951 #endif
952
953 /* if path is search://... then use search: instead */
954 #if FM_CHECK_VERSION(1, 2, 0)
955 sub_path = fm_path_get_scheme_path(path);
956 #else
957 for (sub_path = path; fm_path_get_parent(sub_path) != NULL; )
958 sub_path = fm_path_get_parent(sub_path);
959 #endif
960 if (strncmp(fm_path_get_basename(sub_path), "search:", 7) == 0)
961 {
962 path = fm_path_new_for_uri("search:///");
963 fc = fm_folder_config_open(path);
964 fm_path_unref(path);
965 /* allow to create new entry only if we got valid columns */
966 if (fm_folder_config_is_empty(fc) && (columns != NULL && columns[0] != NULL))
967 {
968 fm_folder_config_close(fc, NULL);
969 /* save columns is mandatory for search view */
970 return;
971 }
972 view_mode = FM_FV_LIST_VIEW; /* search view mode should be immutable */
973 }
974 else
975 fc = fm_folder_config_open(path);
976 #if FM_CHECK_VERSION(1, 0, 2)
977 list[0] = fm_folder_model_col_get_name(by);
978 if (list[0] == NULL) /* FM_FOLDER_MODEL_COL_NAME is always valid */
979 list[0] = fm_folder_model_col_get_name(FM_FOLDER_MODEL_COL_NAME);
980 list[1] = FM_SORT_IS_ASCENDING(mode) ? "ascending" : "descending";
981 if (mode & FM_SORT_CASE_SENSITIVE)
982 list[n++] = "case";
983 #if FM_CHECK_VERSION(1, 2, 0)
984 if (mode & FM_SORT_NO_FOLDER_FIRST)
985 list[n++] = "mingle";
986 #endif
987 list[n] = NULL;
988 fm_folder_config_set_string_list(fc, "Sort", list, n);
989 if (FM_STANDARD_VIEW_MODE_IS_VALID(view_mode))
990 fm_folder_config_set_string(fc, "ViewMode",
991 fm_standard_view_mode_to_str(view_mode));
992 if (columns && columns[0])
993 fm_folder_config_set_string_list(fc, "Columns",
994 (const char *const *)columns,
995 g_strv_length(columns));
996 else if (columns) /* empty list means we should reset columns */
997 fm_folder_config_remove_key(fc, "Columns");
998 #else /* pre-1.0.2 */
999 if (FM_FOLDER_VIEW_MODE_IS_VALID(view_mode))
1000 fm_folder_config_set_integer(fc, "ViewMode", view_mode);
1001 fm_folder_config_set_integer(fc, "sort_type", mode);
1002 fm_folder_config_set_integer(fc, "sort_by", by);
1003 #endif
1004 fm_folder_config_set_boolean(fc, "ShowHidden", show_hidden);
1005 fm_folder_config_close(fc, NULL);
1006 #if FM_CHECK_VERSION(1, 2, 0)
1007 /* raise 'changed' flag and schedule config save */
1008 pcmanfm_save_config(FALSE);
1009 #endif
1010 }
1011
1012 void fm_app_config_clear_config_for_path(FmPath *path)
1013 {
1014 FmFolderConfig *fc = fm_folder_config_open(path);
1015
1016 fm_folder_config_purge(fc);
1017 fm_folder_config_close(fc, NULL);
1018 #if FM_CHECK_VERSION(1, 2, 0)
1019 /* raise 'changed' flag and schedule config save */
1020 pcmanfm_save_config(FALSE);
1021 #endif
1022 }
1023
1024 void fm_app_config_save_desktop_config(GString *buf, const char *group, FmDesktopConfig *cfg)
1025 {
1026 g_string_append_printf(buf, "[%s]\n"
1027 "wallpaper_mode=%s\n", group,
1028 fm_app_wallpaper_get_mode_name(cfg->wallpaper_mode));
1029 g_string_append_printf(buf, "wallpaper_common=%d\n", cfg->wallpaper_common);
1030 if (cfg->wallpapers && cfg->wallpapers_configured > 0)
1031 {
1032 int i;
1033
1034 g_string_append_printf(buf, "wallpapers_configured=%d\n", cfg->wallpapers_configured);
1035 for (i = 0; i < cfg->wallpapers_configured; i++)
1036 if (cfg->wallpapers[i])
1037 g_string_append_printf(buf, "wallpaper%d=%s\n", i, cfg->wallpapers[i]);
1038 }
1039 if (cfg->wallpaper_common && cfg->wallpaper)
1040 g_string_append_printf(buf, "wallpaper=%s\n", cfg->wallpaper);
1041 g_string_append_printf(buf, "desktop_bg=#%02x%02x%02x\n",
1042 cfg->desktop_bg.red/257,
1043 cfg->desktop_bg.green/257,
1044 cfg->desktop_bg.blue/257);
1045 g_string_append_printf(buf, "desktop_fg=#%02x%02x%02x\n",
1046 cfg->desktop_fg.red/257,
1047 cfg->desktop_fg.green/257,
1048 cfg->desktop_fg.blue/257);
1049 g_string_append_printf(buf, "desktop_shadow=#%02x%02x%02x\n",
1050 cfg->desktop_shadow.red/257,
1051 cfg->desktop_shadow.green/257,
1052 cfg->desktop_shadow.blue/257);
1053 if(cfg->desktop_font && *cfg->desktop_font)
1054 g_string_append_printf(buf, "desktop_font=%s\n", cfg->desktop_font);
1055 if(cfg->folder)
1056 g_string_append_printf(buf, "folder=%s\n", cfg->folder);
1057 g_string_append_printf(buf, "show_wm_menu=%d\n", cfg->show_wm_menu);
1058 _save_sort(buf, cfg->desktop_sort_type, cfg->desktop_sort_by);
1059 #if FM_CHECK_VERSION(1, 2, 0)
1060 g_string_append_printf(buf, "show_documents=%d\n", cfg->show_documents);
1061 g_string_append_printf(buf, "show_trash=%d\n", cfg->show_trash);
1062 g_string_append_printf(buf, "show_mounts=%d\n", cfg->show_mounts);
1063 #endif
1064 }
1065
1066 static void _save_choice(gpointer key, gpointer val, gpointer buf)
1067 {
1068 FmAutorunChoice *choice = val;
1069
1070 if (!choice->dont_ask && !choice->last_used)
1071 return;
1072 g_string_append_printf(buf, "%s=%s%s\n", (char*)key,
1073 choice->dont_ask ? "*" : "",
1074 choice->last_used ? choice->last_used : "");
1075 }
1076
1077 void fm_app_config_save_profile(FmAppConfig* cfg, const char* name)
1078 {
1079 char* path = NULL;;
1080 char* dir_path;
1081
1082 if(!name || !*name)
1083 name = "default";
1084
1085 dir_path = g_build_filename(g_get_user_config_dir(), "pcmanfm", name, NULL);
1086 if(g_mkdir_with_parents(dir_path, 0700) != -1)
1087 {
1088 GString* buf = g_string_sized_new(1024);
1089
1090 g_string_append(buf, "[config]\n");
1091 g_string_append_printf(buf, "bm_open_method=%d\n", cfg->bm_open_method);
1092 /*if(cfg->su_cmd && *cfg->su_cmd)
1093 g_string_append_printf(buf, "su_cmd=%s\n", cfg->su_cmd);*/
1094 #if FM_CHECK_VERSION(1, 2, 0)
1095 if (cfg->home_path && cfg->home_path[0]
1096 && strcmp(cfg->home_path, fm_get_home_dir()) != 0)
1097 g_string_append_printf(buf, "home_path=%s\n", cfg->home_path);
1098 #endif
1099
1100 g_string_append(buf, "\n[volume]\n");
1101 g_string_append_printf(buf, "mount_on_startup=%d\n", cfg->mount_on_startup);
1102 g_string_append_printf(buf, "mount_removable=%d\n", cfg->mount_removable);
1103 g_string_append_printf(buf, "autorun=%d\n", cfg->autorun);
1104
1105 if (g_hash_table_size(cfg->autorun_choices) > 0)
1106 {
1107 g_string_append(buf, "\n[autorun]\n");
1108 g_hash_table_foreach(cfg->autorun_choices, _save_choice, buf);
1109 }
1110
1111 g_string_append(buf, "\n[ui]\n");
1112 g_string_append_printf(buf, "always_show_tabs=%d\n", cfg->always_show_tabs);
1113 g_string_append_printf(buf, "max_tab_chars=%d\n", cfg->max_tab_chars);
1114 /* g_string_append_printf(buf, "hide_close_btn=%d\n", cfg->hide_close_btn); */
1115 g_string_append_printf(buf, "win_width=%d\n", cfg->win_width);
1116 g_string_append_printf(buf, "win_height=%d\n", cfg->win_height);
1117 if (cfg->maximized)
1118 g_string_append(buf, "maximized=1\n");
1119 g_string_append_printf(buf, "splitter_pos=%d\n", cfg->splitter_pos);
1120 g_string_append_printf(buf, "media_in_new_tab=%d\n", cfg->media_in_new_tab);
1121 g_string_append_printf(buf, "desktop_folder_new_win=%d\n", cfg->desktop_folder_new_win);
1122 g_string_append_printf(buf, "change_tab_on_drop=%d\n", cfg->change_tab_on_drop);
1123 g_string_append_printf(buf, "close_on_unmount=%d\n", cfg->close_on_unmount);
1124 #if FM_CHECK_VERSION(1, 2, 0)
1125 g_string_append_printf(buf, "focus_previous=%d\n", cfg->focus_previous);
1126 g_string_append(buf, "side_pane_mode=");
1127 if (cfg->side_pane_mode & FM_SP_HIDE)
1128 g_string_append(buf, "hidden;");
1129 g_string_append_printf(buf, "%s\n",
1130 fm_side_pane_get_mode_name(cfg->side_pane_mode & FM_SP_MODE_MASK));
1131 #else
1132 g_string_append_printf(buf, "side_pane_mode=%d\n", cfg->side_pane_mode);
1133 #endif
1134 #if FM_CHECK_VERSION(1, 0, 2)
1135 g_string_append_printf(buf, "view_mode=%s\n", fm_standard_view_mode_to_str(cfg->view_mode));
1136 #else
1137 g_string_append_printf(buf, "view_mode=%d\n", cfg->view_mode);
1138 #endif
1139 g_string_append_printf(buf, "show_hidden=%d\n", cfg->show_hidden);
1140 _save_sort(buf, cfg->sort_type, cfg->sort_by);
1141 #if FM_CHECK_VERSION(1, 0, 2)
1142 if (cfg->columns && cfg->columns[0])
1143 {
1144 char **colptr;
1145
1146 g_string_append(buf, "columns=");
1147 for (colptr = cfg->columns; *colptr; colptr++)
1148 g_string_append_printf(buf, "%s;", *colptr);
1149 g_string_append_c(buf, '\n');
1150 }
1151 #endif
1152 g_string_append(buf, "toolbar=");
1153 if (!cfg->tb.visible)
1154 g_string_append(buf, "hidden;");
1155 if (cfg->tb.new_win)
1156 g_string_append(buf, "newwin;");
1157 if (cfg->tb.new_tab)
1158 g_string_append(buf, "newtab;");
1159 if (cfg->tb.nav)
1160 g_string_append(buf, "navigation;");
1161 if (cfg->tb.home)
1162 g_string_append(buf, "home;");
1163 g_string_append_c(buf, '\n');
1164 g_string_append_printf(buf, "show_statusbar=%d\n", cfg->show_statusbar);
1165 g_string_append_printf(buf, "pathbar_mode_buttons=%d\n", cfg->pathbar_mode_buttons);
1166
1167 path = g_build_filename(dir_path, "pcmanfm.conf", NULL);
1168 g_file_set_contents(path, buf->str, buf->len, NULL);
1169 g_free(path);
1170 g_string_free(buf, TRUE);
1171
1172 #if FM_CHECK_VERSION(1, 2, 0)
1173 /* libfm does not have any profile things */
1174 fm_folder_config_save_cache();
1175 #else
1176 fm_folder_config_save_cache(dir_path);
1177 #endif
1178 }
1179 g_free(dir_path);
1180 }
1181
1182 void fm_app_config_set_autorun_choice(FmAppConfig *cfg,
1183 const char *content_type,
1184 const char *app, gboolean dont_ask)
1185 {
1186 FmAutorunChoice *choice;
1187
1188 if (content_type == NULL)
1189 return;
1190 choice = g_hash_table_lookup(cfg->autorun_choices, content_type);
1191 if (choice)
1192 g_free(choice->last_used);
1193 else
1194 {
1195 choice = g_slice_new(FmAutorunChoice);
1196 g_hash_table_insert(cfg->autorun_choices, g_strdup(content_type), choice);
1197 }
1198 choice->last_used = g_strdup(app);
1199 choice->dont_ask = dont_ask;
1200 }
1201
1202 typedef struct
1203 {
1204 const char *name;
1205 FmWallpaperMode mode;
1206 } _WPModeDesc;
1207
1208 static const _WPModeDesc _wp_modes[] = {
1209 { "color", FM_WP_COLOR },
1210 { "stretch", FM_WP_STRETCH },
1211 { "fit", FM_WP_FIT },
1212 { "center", FM_WP_CENTER },
1213 { "tile", FM_WP_TILE },
1214 { "crop", FM_WP_CROP },
1215 { "screen", FM_WP_SCREEN }
1216 };
1217
1218 FmWallpaperMode fm_app_wallpaper_get_mode_by_name(const char *name)
1219 {
1220 guint i;
1221 if (name) for (i = 0; i < G_N_ELEMENTS(_wp_modes); i++)
1222 if (strcmp(_wp_modes[i].name, name) == 0)
1223 return _wp_modes[i].mode;
1224 return (FmWallpaperMode)-1;
1225 }
1226
1227 const char *fm_app_wallpaper_get_mode_name(FmWallpaperMode mode)
1228 {
1229 guint i;
1230 for (i = 0; i < G_N_ELEMENTS(_wp_modes); i++)
1231 if (_wp_modes[i].mode == mode)
1232 return _wp_modes[i].name;
1233 return NULL;
1234 }