Fix from korzhpavel@sourceforge for GTK criticals on desktop destroy.
[lxde/pcmanfm.git] / src / pcmanfm.c
CommitLineData
b6e3c554
HJYP
1/*
2 * pcmanfm.c
d3451adb 3 *
7b7d923f 4 * Copyright 2009 - 2010 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
d3451adb 5 *
b6e3c554
HJYP
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
d3451adb 10 *
b6e3c554
HJYP
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
d3451adb 15 *
b6e3c554
HJYP
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 */
21
08e70fea 22#ifdef HAVE_CONFIG_H
b6e3c554 23#include <config.h>
08e70fea
HJYP
24#endif
25
b6e3c554 26#include <gtk/gtk.h>
1098cfe7 27#include <gdk/gdkx.h>
b6e3c554 28#include <stdio.h>
f8f2bfad
HJYP
29#include <glib/gi18n.h>
30
31#include <stdlib.h>
32#include <string.h>
33/* socket is used to keep single instance */
34#include <sys/types.h>
f8f2bfad
HJYP
35#include <signal.h>
36#include <unistd.h> /* for getcwd */
b6e3c554 37
20c0bc9a 38#include <libfm/fm-gtk.h>
4d55886c 39#include "app-config.h"
b6e3c554 40#include "main-win.h"
8505a8ef 41#include "desktop.h"
71f82759 42#include "volume-manager.h"
c5fccf1d 43#include "pref.h"
df6826e0 44#include "pcmanfm.h"
cc448d7f 45#include "single-inst.h"
f8f2bfad 46
94435bc3 47static int signal_pipe[2] = {-1, -1};
f8f2bfad 48gboolean daemon_mode = FALSE;
3d141640 49static guint save_config_idle = 0;
f8f2bfad 50
f8f2bfad 51static char** files_to_open = NULL;
cc448d7f 52static int n_files_to_open = 0;
f970e846 53static char* profile = NULL;
f8f2bfad
HJYP
54static gboolean no_desktop = FALSE;
55static gboolean show_desktop = FALSE;
56static gboolean desktop_off = FALSE;
57static gboolean desktop_running = FALSE;
107cdb22 58/* static gboolean new_tab = FALSE; */
f8f2bfad
HJYP
59static int show_pref = 0;
60static gboolean desktop_pref = FALSE;
61static char* set_wallpaper = NULL;
107cdb22 62static char* wallpaper_mode = NULL;
9197e75e 63/* static gboolean new_win = FALSE; */
f8f2bfad 64static gboolean find_files = FALSE;
5b890032 65static char* ipc_cwd = NULL;
f8f2bfad
HJYP
66
67static int n_pcmanfm_ref = 0;
68
69static GOptionEntry opt_entries[] =
8505a8ef 70{
cda6259f 71 /* options only acceptable by first pcmanfm instance. These options are not passed through IPC */
a48f9fc8 72 { "profile", 'p', 0, G_OPTION_ARG_STRING, &profile, N_("Name of configuration profile"), "<profile name>" },
cda6259f
HJYP
73 { "daemon-mode", 'd', 0, G_OPTION_ARG_NONE, &daemon_mode, N_("Run PCManFM as a daemon"), NULL },
74 { "no-desktop", '\0', 0, G_OPTION_ARG_NONE, &no_desktop, N_("No function. Just to be compatible with nautilus"), NULL },
75
76 /* options that are acceptable for every instance of pcmanfm and will be passed through IPC. */
f8f2bfad
HJYP
77 { "desktop", '\0', 0, G_OPTION_ARG_NONE, &show_desktop, N_("Launch desktop manager"), NULL },
78 { "desktop-off", '\0', 0, G_OPTION_ARG_NONE, &desktop_off, N_("Turn off desktop manager if it's running"), NULL },
f8f2bfad 79 { "desktop-pref", '\0', 0, G_OPTION_ARG_NONE, &desktop_pref, N_("Open desktop preference dialog"), NULL },
f970e846 80 { "set-wallpaper", 'w', 0, G_OPTION_ARG_FILENAME, &set_wallpaper, N_("Set desktop wallpaper"), N_("<image file>") },
107cdb22 81 { "wallpaper-mode", '\0', 0, G_OPTION_ARG_STRING, &wallpaper_mode, N_("Set mode of desktop wallpaper. <mode>=(color|stretch|fit|center|tile)"), N_("<mode>") },
a48f9fc8 82 { "show-pref", '\0', 0, G_OPTION_ARG_INT, &show_pref, N_("Open preference dialog. 'n' is number of the page you want to show (1, 2, 3...)."), "n" },
9197e75e 83 /* { "new-win", '\0', 'n', G_OPTION_ARG_NONE, &new_win, N_("Open new window"), NULL }, */
1d071341 84 /* { "find-files", 'f', 0, G_OPTION_ARG_NONE, &find_files, N_("Open Find Files utility"), NULL }, */
f8f2bfad
HJYP
85 {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &files_to_open, NULL, N_("[FILE1, FILE2,...]")},
86 { NULL }
87};
88
107cdb22
HJYP
89static const char* valid_wallpaper_modes[] = {"color", "stretch", "fit", "center", "tile"};
90
f8f2bfad 91static gboolean pcmanfm_run();
b6e3c554 92
94435bc3
HJYP
93/* it's not safe to call gtk+ functions in unix signal handler
94 * since the process is interrupted here and the state of gtk+ is unpredictable. */
95static void unix_signal_handler(int sig_num)
96{
97 /* postpond the signal handling by using a pipe */
3aebc679
AG
98 if (write(signal_pipe[1], &sig_num, sizeof(sig_num)) != sizeof(sig_num)) {
99 g_critical("cannot bounce the signal, stop");
100 exit(2);
101 }
94435bc3
HJYP
102}
103
104static gboolean on_unix_signal(GIOChannel* ch, GIOCondition cond, gpointer user_data)
105{
106 int sig_num;
3aebc679 107 g_io_channel_read_chars(ch, (gchar*)&sig_num, 1, NULL, NULL);
94435bc3
HJYP
108 switch(sig_num)
109 {
110 case SIGTERM:
111 default:
112 gtk_main_quit();
113 }
114 return TRUE;
115}
116
1098cfe7 117static void single_inst_cb(const char* cwd, int screen_num)
cc448d7f 118{
cda6259f
HJYP
119 g_free(ipc_cwd);
120 ipc_cwd = g_strdup(cwd);
121
122 if(files_to_open)
cc448d7f 123 {
cda6259f 124 int i;
6033d802 125 n_files_to_open = g_strv_length(files_to_open);
cda6259f
HJYP
126 /* canonicalize filename if needed. */
127 for(i = 0; i < n_files_to_open; ++i)
cc448d7f 128 {
cda6259f
HJYP
129 char* file = files_to_open[i];
130 char* scheme = g_uri_parse_scheme(file);
6033d802 131 g_debug("file: %s", file);
cda6259f 132 if(scheme) /* a valid URI */
cc448d7f 133 {
cda6259f
HJYP
134 /* FIXME: should we canonicalize URIs? and how about file:///? */
135 g_free(scheme);
136 }
137 else /* a file path */
138 {
139 files_to_open[i] = fm_canonicalize_filename(file, cwd);
140 g_free(file);
cc448d7f 141 }
cc448d7f 142 }
cc448d7f 143 }
cda6259f 144 pcmanfm_run();
cc448d7f
HJYP
145}
146
b6e3c554
HJYP
147int main(int argc, char** argv)
148{
4d55886c 149 FmConfig* config;
f8f2bfad 150 GError* err = NULL;
21df32aa 151 SingleInstData inst;
cda6259f 152
f8f2bfad
HJYP
153#ifdef ENABLE_NLS
154 bindtextdomain ( GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR );
155 bind_textdomain_codeset ( GETTEXT_PACKAGE, "UTF-8" );
156 textdomain ( GETTEXT_PACKAGE );
157#endif
158
159 /* initialize GTK+ and parse the command line arguments */
160 if(G_UNLIKELY(!gtk_init_with_args(&argc, &argv, "", opt_entries, GETTEXT_PACKAGE, &err)))
161 {
162 g_printf("%s\n", err->message);
c5fccf1d 163 g_error_free(err);
f8f2bfad
HJYP
164 return 1;
165 }
166
cc448d7f 167 /* ensure that there is only one instance of pcmanfm. */
21df32aa
AG
168 inst.prog_name = "pcmanfm";
169 inst.cb = single_inst_cb;
170 inst.opt_entries = opt_entries + 3;
171 inst.screen_num = gdk_x11_get_default_screen();
172 switch(single_inst_init(&inst))
cc448d7f
HJYP
173 {
174 case SINGLE_INST_CLIENT: /* we're not the first instance. */
21df32aa 175 single_inst_finalize(&inst);
cc448d7f
HJYP
176 gdk_notify_startup_complete();
177 return 0;
178 case SINGLE_INST_ERROR: /* error happened. */
21df32aa 179 single_inst_finalize(&inst);
cc448d7f 180 return 1;
3aebc679 181 case SINGLE_INST_SERVER: ; /* FIXME */
cc448d7f 182 }
f8f2bfad 183
94435bc3
HJYP
184 if(pipe(signal_pipe) == 0)
185 {
186 GIOChannel* ch = g_io_channel_unix_new(signal_pipe[0]);
187 g_io_add_watch(ch, G_IO_IN|G_IO_PRI, (GIOFunc)on_unix_signal, NULL);
188 g_io_channel_unref(ch);
189
190 /* intercept signals */
ae2947d9
HJYP
191 // signal( SIGPIPE, SIG_IGN );
192 signal( SIGHUP, unix_signal_handler );
94435bc3 193 signal( SIGTERM, unix_signal_handler );
e2f270e5 194#ifdef SIGPOLL /* bug #3528311 */
ae2947d9 195 signal( SIGPOLL, unix_signal_handler );
e2f270e5 196#endif
ae2947d9 197 signal( SIGHUP, unix_signal_handler );
94435bc3 198 }
b6e3c554 199
f970e846 200 config = fm_app_config_new(); /* this automatically load libfm config file. */
17d12cc9 201
f970e846 202 /* load pcmanfm-specific config file */
17d12cc9 203 fm_app_config_load_from_profile(FM_APP_CONFIG(config), profile);
f970e846 204
94435bc3 205 fm_gtk_init(config);
f8f2bfad
HJYP
206 /* the main part */
207 if(pcmanfm_run())
208 {
71f82759 209 fm_volume_manager_init();
94435bc3 210 gtk_main();
f8f2bfad
HJYP
211 if(desktop_running)
212 fm_desktop_manager_finalize();
3d141640
HJYP
213
214 pcmanfm_save_config(TRUE);
215 if(save_config_idle)
216 {
217 g_source_remove(save_config_idle);
218 save_config_idle = 0;
219 }
71f82759 220 fm_volume_manager_finalize();
f8f2bfad 221 }
cc448d7f 222
21df32aa 223 single_inst_finalize(&inst);
f8f2bfad 224 fm_gtk_finalize();
ae2947d9 225
f8f2bfad 226 g_object_unref(config);
94435bc3 227 return 0;
f8f2bfad
HJYP
228}
229
ee12f37e
HJYP
230static FmJobErrorAction on_file_info_job_error(FmFileInfoJob* job, GError* err, FmJobErrorSeverity severity, gpointer user_data)
231{
16a17d6b 232 if(err->domain == G_IO_ERROR)
ee12f37e 233 {
16a17d6b
HJYP
234 if(err->code == G_IO_ERROR_NOT_MOUNTED)
235 {
236 if(fm_mount_path(NULL, fm_file_info_job_get_current(job), TRUE))
237 return FM_JOB_RETRY;
238 }
239 else if(err->code == G_IO_ERROR_FAILED_HANDLED)
240 return FM_JOB_CONTINUE;
ee12f37e 241 }
5089e13a 242 fm_show_error(NULL, NULL, err->message);
ee12f37e
HJYP
243 return FM_JOB_CONTINUE;
244}
f8f2bfad
HJYP
245
246gboolean pcmanfm_run()
247{
248 gboolean ret = TRUE;
f8f2bfad 249
f8f2bfad
HJYP
250 if(!files_to_open)
251 {
252 /* Launch desktop manager */
253 if(show_desktop)
254 {
255 if(!desktop_running)
256 {
257 fm_desktop_manager_init();
258 desktop_running = TRUE;
259 }
19abb8bf 260 show_desktop = FALSE;
f8f2bfad
HJYP
261 return TRUE;
262 }
263 else if(desktop_off)
264 {
265 if(desktop_running)
266 {
267 desktop_running = FALSE;
268 fm_desktop_manager_finalize();
269 }
19abb8bf 270 desktop_off = FALSE;
f8f2bfad
HJYP
271 return FALSE;
272 }
273 else if(show_pref > 0)
274 {
c5fccf1d
HJYP
275 fm_edit_preference(NULL, show_pref - 1);
276 show_pref = 0;
f8f2bfad
HJYP
277 return TRUE;
278 }
279 else if(desktop_pref)
280 {
c5fccf1d 281 fm_desktop_preference();
19abb8bf 282 desktop_pref = FALSE;
f8f2bfad
HJYP
283 return TRUE;
284 }
107cdb22 285 else
f8f2bfad 286 {
107cdb22
HJYP
287 gboolean need_to_exit = (wallpaper_mode || set_wallpaper);
288 gboolean wallpaper_changed = FALSE;
289 if(set_wallpaper) /* a new wallpaper is assigned */
290 {
291 /* g_debug("\'%s\'", set_wallpaper); */
292 /* Make sure this is a support image file. */
293 if(gdk_pixbuf_get_file_info(set_wallpaper, NULL, NULL))
294 {
295 if(app_config->wallpaper)
296 g_free(app_config->wallpaper);
297 app_config->wallpaper = set_wallpaper;
298 set_wallpaper = NULL;
299 if(! wallpaper_mode) /* if wallpaper mode is not specified */
300 {
301 /* do not use solid color mode; otherwise wallpaper won't be shown. */
302 if(app_config->wallpaper_mode == FM_WP_COLOR)
303 app_config->wallpaper_mode = FM_WP_FIT;
304 }
305 wallpaper_changed = TRUE;
306 }
307 }
308
309 if(wallpaper_mode)
310 {
6f0f1950 311 guint i = 0;
107cdb22
HJYP
312 for(i = 0; i < G_N_ELEMENTS(valid_wallpaper_modes); ++i)
313 {
314 if(strcmp(valid_wallpaper_modes[i], wallpaper_mode) == 0)
315 {
316 if(i != app_config->wallpaper_mode)
317 {
318 app_config->wallpaper_mode = i;
319 wallpaper_changed = TRUE;
320 }
321 break;
322 }
323 }
324 g_free(wallpaper_mode);
325 wallpaper_mode = NULL;
326 }
327
328 if(wallpaper_changed)
f8f2bfad 329 {
4b3e1fe9 330 fm_config_emit_changed(FM_CONFIG(app_config), "wallpaper");
17d12cc9 331 fm_app_config_save_profile(app_config, profile);
f8f2bfad 332 }
107cdb22
HJYP
333
334 if(need_to_exit)
335 return FALSE;
f8f2bfad
HJYP
336 }
337 }
338
339 if(G_UNLIKELY(find_files))
340 {
341 /* FIXME: find files */
342 }
343 else
344 {
df6826e0
HJYP
345 if(files_to_open)
346 {
347 char** filename;
3aebc679 348 FmFileInfoJob* job = fm_file_info_job_new(NULL, 0);
cacf261a 349 FmPath* cwd = NULL;
d951adb8 350 GList* infos;
df6826e0
HJYP
351 for(filename=files_to_open; *filename; ++filename)
352 {
cacf261a 353 FmPath* path;
9197e75e
HJYP
354 if( **filename == '/') /* absolute path */
355 path = fm_path_new_for_path(*filename);
356 else if(strstr(*filename, ":/") ) /* URI */
357 path = fm_path_new_for_uri(*filename);
0d8dce1a
HJYP
358 else if( strcmp(*filename, "~") == 0 ) /* special case for home dir */
359 {
360 path = fm_path_get_home();
361 fm_main_win_add_win(NULL, path);
362 continue;
363 }
cacf261a
HJYP
364 else /* basename */
365 {
366 if(G_UNLIKELY(!cwd))
367 {
368 /* FIXME: This won't work if those filenames are passed via IPC since the receiving process has different cwd. */
9197e75e 369 /* FIXME: should we use ipc_cwd here? */
cacf261a 370 char* cwd_str = g_get_current_dir();
653af525 371 cwd = fm_path_new_for_str(cwd_str);
cacf261a
HJYP
372 g_free(cwd_str);
373 }
374 path = fm_path_new_relative(cwd, *filename);
375 }
3aebc679 376 fm_file_info_job_add(job, path);
df6826e0
HJYP
377 fm_path_unref(path);
378 }
cacf261a
HJYP
379 if(cwd)
380 fm_path_unref(cwd);
ee12f37e 381 g_signal_connect(job, "error", G_CALLBACK(on_file_info_job_error), NULL);
3aebc679 382 fm_job_run_sync_with_mainloop(FM_JOB(job));
5a89e062 383 infos = fm_file_info_list_peek_head_link(job->file_infos);
d951adb8 384 fm_launch_files_simple(NULL, NULL, infos, pcmanfm_open_folder, NULL);
df6826e0 385 g_object_unref(job);
cacf261a 386 ret = (n_pcmanfm_ref >= 1); /* if there is opened window, return true to run the main loop. */
2b46b521
HJYP
387
388 g_strfreev(files_to_open);
389 files_to_open = NULL;
df6826e0
HJYP
390 }
391 else
f8f2bfad 392 {
bc88a8dc
HJYP
393 static gboolean first_run = TRUE;
394 if(first_run && daemon_mode)
3d141640 395 {
bc88a8dc
HJYP
396 /* If the function is called the first time and we're in daemon mode,
397 * don't open any folder.
398 * Checking if pcmanfm_run() is called the first time is needed to fix
399 * #3397444 - pcmanfm dont show window in daemon mode if i call 'pcmanfm' */
400 }
401 else
402 {
403 /* If we're not in daemon mode, or pcmanfm_run() is called because another
404 * instance send signal to us, open cwd by default. */
3d141640
HJYP
405 FmPath* path;
406 char* cwd = ipc_cwd ? ipc_cwd : g_get_current_dir();
407 path = fm_path_new_for_path(cwd);
408 fm_main_win_add_win(NULL, path);
409 fm_path_unref(path);
410 g_free(cwd);
411 ipc_cwd = NULL;
412 }
bc88a8dc 413 first_run = FALSE;
f8f2bfad
HJYP
414 }
415 }
416 return ret;
417}
418
419/* After opening any window/dialog/tool, this should be called. */
420void pcmanfm_ref()
421{
422 ++n_pcmanfm_ref;
423 /* g_debug("ref: %d", n_pcmanfm_ref); */
424}
425
426/* After closing any window/dialog/tool, this should be called.
427 * If the last window is closed and we are not a deamon, pcmanfm will quit.
428 */
429void pcmanfm_unref()
430{
431 --n_pcmanfm_ref;
432 /* g_debug("unref: %d, daemon_mode=%d, desktop_running=%d", n_pcmanfm_ref, daemon_mode, desktop_running); */
433 if( 0 == n_pcmanfm_ref && !daemon_mode && !desktop_running )
434 gtk_main_quit();
b6e3c554 435}
df6826e0
HJYP
436
437gboolean pcmanfm_open_folder(GAppLaunchContext* ctx, GList* folder_infos, gpointer user_data, GError** err)
438{
df6826e0
HJYP
439 GList* l = folder_infos;
440 for(; l; l=l->next)
441 {
442 FmFileInfo* fi = (FmFileInfo*)l->data;
0b951729 443 fm_main_win_open_in_last_active(fm_file_info_get_path(fi));
df6826e0
HJYP
444 }
445 return TRUE;
446}
dcecce78 447
3d141640 448static gboolean on_save_config_idle(gpointer user_data)
dcecce78 449{
3d141640
HJYP
450 pcmanfm_save_config(TRUE);
451 save_config_idle = 0;
452 return FALSE;
453}
454
455void pcmanfm_save_config(gboolean immediate)
456{
457 if(immediate)
458 {
459 fm_config_save(fm_config, NULL);
460 fm_app_config_save_profile(app_config, profile);
461 }
462 else
463 {
464 /* install an idle handler to save the config file. */
465 if( 0 == save_config_idle)
466 save_config_idle = g_idle_add_full(G_PRIORITY_LOW, (GSourceFunc)on_save_config_idle, NULL, NULL);
467 }
dcecce78 468}
c56a211a
HJYP
469
470void pcmanfm_open_folder_in_terminal(GtkWindow* parent, FmPath* dir)
471{
472 GAppInfo* app;
c56a211a
HJYP
473 char** argv;
474 int argc;
475 if(!fm_config->terminal)
476 {
5089e13a 477 fm_show_error(parent, NULL, _("Terminal emulator is not set."));
c56a211a
HJYP
478 fm_edit_preference(parent, PREF_ADVANCED);
479 return;
480 }
481 if(!g_shell_parse_argv(fm_config->terminal, &argc, &argv, NULL))
482 return;
483 app = g_app_info_create_from_commandline(argv[0], NULL, 0, NULL);
484 g_strfreev(argv);
485 if(app)
486 {
487 GError* err = NULL;
3aebc679 488 GdkAppLaunchContext* ctx = gdk_app_launch_context_new();
c56a211a 489 char* cwd_str;
1dfc8e4c 490 char* old_cwd = g_get_current_dir();
c56a211a
HJYP
491
492 if(fm_path_is_native(dir))
493 cwd_str = fm_path_to_str(dir);
494 else
495 {
496 GFile* gf = fm_path_to_gfile(dir);
497 cwd_str = g_file_get_path(gf);
498 g_object_unref(gf);
499 }
3aebc679
AG
500 gdk_app_launch_context_set_screen(ctx, parent ? gtk_widget_get_screen(GTK_WIDGET(parent)) : gdk_screen_get_default());
501 gdk_app_launch_context_set_timestamp(ctx, gtk_get_current_event_time());
c56a211a
HJYP
502 g_chdir(cwd_str); /* FIXME: currently we don't have better way for this. maybe a wrapper script? */
503 g_free(cwd_str);
1dfc8e4c 504
3aebc679 505 if(!g_app_info_launch(app, NULL, G_APP_LAUNCH_CONTEXT(ctx), &err))
c56a211a 506 {
5089e13a 507 fm_show_error(parent, NULL, err->message);
c56a211a
HJYP
508 g_error_free(err);
509 }
510 g_object_unref(ctx);
511 g_object_unref(app);
1dfc8e4c
HJYP
512
513 /* switch back to old cwd and fix #3114626 - PCManFM 0.9.9 Umount partitions problem */
514 g_chdir(old_cwd); /* This is really dirty, but we don't have better solution now. */
515 g_free(old_cwd);
c56a211a
HJYP
516 }
517}
7cb06c27
HJYP
518
519/* FIXME: Need to load content of ~/Templates and list available templates in popup menus. */
520void pcmanfm_create_new(GtkWindow* parent, FmPath* cwd, const char* templ)
521{
522 GError* err = NULL;
523 FmPath* dest;
524 char* basename;
cac3de08 525 const char* msg;
3aebc679 526 //FmMainWin* win = FM_MAIN_WIN(parent);
7cb06c27 527_retry:
cac3de08
HJYP
528 if(templ == TEMPL_NAME_FOLDER)
529 msg = N_("Enter a name for the newly created folder:");
530 else
531 msg = N_("Enter a name for the newly created file:");
532 basename = fm_get_user_input(parent, _("Create New..."), _(msg), _("New"));
7cb06c27
HJYP
533 if(!basename)
534 return;
535
536 dest = fm_path_new_child(cwd, basename);
537 g_free(basename);
538
539 if( templ == TEMPL_NAME_FOLDER )
540 {
541 GFile* gf = fm_path_to_gfile(dest);
542 if(!g_file_make_directory(gf, NULL, &err))
543 {
98daf506 544 if(err->domain == G_IO_ERROR && err->code == G_IO_ERROR_EXISTS)
7cb06c27
HJYP
545 {
546 fm_path_unref(dest);
547 g_error_free(err);
548 g_object_unref(gf);
549 err = NULL;
550 goto _retry;
551 }
5089e13a 552 fm_show_error(parent, NULL, err->message);
7cb06c27
HJYP
553 g_error_free(err);
554 }
555
556 if(!err) /* select the newly created file */
557 {
558 /*FIXME: this doesn't work since the newly created file will
559 * only be shown after file-created event was fired on its
560 * folder's monitor and after FmFolder handles it in idle
561 * handler. So, we cannot select it since it's not yet in
562 * the folder model now. */
563 /* fm_folder_view_select_file_path(fv, dest); */
564 }
565 g_object_unref(gf);
566 }
567 else if( templ == TEMPL_NAME_BLANK )
568 {
569 GFile* gf = fm_path_to_gfile(dest);
570 GFileOutputStream* f = g_file_create(gf, G_FILE_CREATE_NONE, NULL, &err);
571 if(f)
572 {
573 g_output_stream_close(G_OUTPUT_STREAM(f), NULL, NULL);
574 g_object_unref(f);
575 }
576 else
577 {
98daf506 578 if(err->domain == G_IO_ERROR && err->code == G_IO_ERROR_EXISTS)
7cb06c27
HJYP
579 {
580 fm_path_unref(dest);
581 g_error_free(err);
582 g_object_unref(gf);
583 err = NULL;
584 goto _retry;
585 }
5089e13a 586 fm_show_error(parent, NULL, err->message);
7cb06c27
HJYP
587 g_error_free(err);
588 }
589
590 if(!err) /* select the newly created file */
591 {
592 /*FIXME: this doesn't work since the newly created file will
593 * only be shown after file-created event was fired on its
594 * folder's monitor and after FmFolder handles it in idle
595 * handler. So, we cannot select it since it's not yet in
596 * the folder model now. */
597 /* fm_folder_view_select_file_path(fv, dest); */
598 }
599 g_object_unref(gf);
600 }
601 else /* templates in ~/Templates */
602 {
b2fd837c 603 /* FIXME: need an extended processing with desktop entries support */
653af525 604 FmPath* dir = fm_path_new_for_str(g_get_user_special_dir(G_USER_DIRECTORY_TEMPLATES));
7cb06c27 605 FmPath* template = fm_path_new_child(dir, templ);
9afd9e19 606 fm_copy_file(parent, template, cwd);
7cb06c27 607 fm_path_unref(template);
b2fd837c 608 fm_path_unref(dir);
7cb06c27
HJYP
609 }
610 fm_path_unref(dest);
611}
92f8ca49
HJYP
612
613char* pcmanfm_get_profile_dir(gboolean create)
614{
615 char* dir = g_build_filename(g_get_user_config_dir(), "pcmanfm", profile ? profile : "default", NULL);
616 if(create)
617 g_mkdir_with_parents(dir, 0700);
618 return dir;
619}