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