Fix #2988985: Doesn't update location when using address bar and terminal.
[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>
34#include <sys/socket.h>
35#include <sys/un.h>
36#include <signal.h>
37#include <unistd.h> /* for getcwd */
b6e3c554 38
20c0bc9a 39#include <libfm/fm-gtk.h>
4d55886c 40#include "app-config.h"
b6e3c554 41#include "main-win.h"
8505a8ef 42#include "desktop.h"
71f82759 43#include "volume-manager.h"
c5fccf1d 44#include "pref.h"
df6826e0 45#include "pcmanfm.h"
8505a8ef 46
f8f2bfad
HJYP
47static int sock;
48GIOChannel* io_channel = NULL;
49
50gboolean daemon_mode = FALSE;
51
f8f2bfad 52static char** files_to_open = NULL;
f970e846
HJYP
53static char* profile = NULL;
54static char* config_name = NULL;
f8f2bfad
HJYP
55static gboolean no_desktop = FALSE;
56static gboolean show_desktop = FALSE;
57static gboolean desktop_off = FALSE;
58static gboolean desktop_running = FALSE;
59static gboolean new_tab = FALSE;
60static int show_pref = 0;
61static gboolean desktop_pref = FALSE;
62static char* set_wallpaper = NULL;
63static gboolean find_files = FALSE;
5b890032 64static char* ipc_cwd = NULL;
f8f2bfad
HJYP
65
66static int n_pcmanfm_ref = 0;
67
68static GOptionEntry opt_entries[] =
8505a8ef 69{
f970e846 70 { "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 71 { "profile", 'p', 0, G_OPTION_ARG_STRING, &profile, N_("Name of configuration profile"), "<profile name>" },
f8f2bfad
HJYP
72 { "desktop", '\0', 0, G_OPTION_ARG_NONE, &show_desktop, N_("Launch desktop manager"), NULL },
73 { "desktop-off", '\0', 0, G_OPTION_ARG_NONE, &desktop_off, N_("Turn off desktop manager if it's running"), NULL },
f8f2bfad 74 { "daemon-mode", 'd', 0, G_OPTION_ARG_NONE, &daemon_mode, N_("Run PCManFM as a daemon"), NULL },
f8f2bfad 75 { "desktop-pref", '\0', 0, G_OPTION_ARG_NONE, &desktop_pref, N_("Open desktop preference dialog"), NULL },
f970e846 76 { "set-wallpaper", 'w', 0, G_OPTION_ARG_FILENAME, &set_wallpaper, N_("Set desktop wallpaper"), N_("<image file>") },
a48f9fc8 77 { "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" },
f8f2bfad 78 { "find-files", 'f', 0, G_OPTION_ARG_NONE, &find_files, N_("Open Find Files utility"), NULL },
f970e846 79 { "no-desktop", '\0', 0, G_OPTION_ARG_NONE, &no_desktop, N_("No function. Just to be compatible with nautilus"), NULL },
f8f2bfad
HJYP
80 {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &files_to_open, NULL, N_("[FILE1, FILE2,...]")},
81 { NULL }
82};
83
84static gboolean single_instance_check();
85static void single_instance_finalize();
86static void get_socket_name(char* buf, int len);
87static gboolean pcmanfm_run();
88static gboolean on_socket_event(GIOChannel* ioc, GIOCondition cond, gpointer data);
b6e3c554
HJYP
89
90int main(int argc, char** argv)
91{
4d55886c 92 FmConfig* config;
f8f2bfad
HJYP
93 GError* err = NULL;
94
95#ifdef ENABLE_NLS
96 bindtextdomain ( GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR );
97 bind_textdomain_codeset ( GETTEXT_PACKAGE, "UTF-8" );
98 textdomain ( GETTEXT_PACKAGE );
99#endif
100
101 /* initialize GTK+ and parse the command line arguments */
102 if(G_UNLIKELY(!gtk_init_with_args(&argc, &argv, "", opt_entries, GETTEXT_PACKAGE, &err)))
103 {
104 g_printf("%s\n", err->message);
c5fccf1d 105 g_error_free(err);
f8f2bfad
HJYP
106 return 1;
107 }
108
109 /* ensure that there is only one instance of pcmanfm.
110 if there is an existing instance, command line arguments
111 will be passed to the existing instance, and exit() will be called here. */
112 single_instance_check();
113
114 /* intercept signals */
115 signal( SIGPIPE, SIG_IGN );
116 /* signal( SIGHUP, gtk_main_quit ); */
117 signal( SIGINT, gtk_main_quit );
118 signal( SIGTERM, gtk_main_quit );
b6e3c554 119
f970e846
HJYP
120 config = fm_app_config_new(); /* this automatically load libfm config file. */
121 /* load pcmanfm-specific config file */
122 if(profile)
123 config_name = g_strconcat("pcmanfm/", profile, ".conf", NULL);
4b3e1fe9 124 fm_app_config_load_from_file(FM_APP_CONFIG(config), config_name);
f970e846 125
4d55886c 126 fm_gtk_init(config);
b6e3c554 127
f8f2bfad
HJYP
128 /* the main part */
129 if(pcmanfm_run())
130 {
71f82759 131 fm_volume_manager_init();
f8f2bfad
HJYP
132 gtk_main();
133 if(desktop_running)
134 fm_desktop_manager_finalize();
f8f2bfad 135 fm_config_save(config, NULL); /* save libfm config */
f970e846 136 fm_app_config_save((FmAppConfig*)config, config_name); /* save pcmanfm config */
71f82759 137 fm_volume_manager_finalize();
f8f2bfad
HJYP
138 }
139 single_instance_finalize();
8505a8ef 140
f8f2bfad
HJYP
141 fm_gtk_finalize();
142 g_object_unref(config);
f8f2bfad
HJYP
143 return 0;
144}
145
7b7d923f 146inline static void buf_append_str(GByteArray* buf, const char* str)
f8f2bfad 147{
7b7d923f
HJYP
148 int len;
149 if(G_LIKELY(str))
150 {
151 len = strlen(str) + 1;
152 g_byte_array_append(buf, (guint8*)&len, sizeof(len));
153 g_byte_array_append(buf, (guint8*)str, len);
154 }
155 else
156 {
157 len = 0;
158 g_byte_array_append(buf, (guint8*)&len, sizeof(len));
159 }
160}
161
162inline static GByteArray* args_to_ipc_buf()
163{
164 int i, len;
165 GByteArray* buf = g_byte_array_sized_new(4096);
5b890032
HJYP
166 /* send our current working dir to existing instance via IPC. */
167 ipc_cwd = g_get_current_dir();
7b7d923f 168 buf_append_str(buf, ipc_cwd);
5b890032 169 g_free(ipc_cwd);
7b7d923f
HJYP
170
171 g_byte_array_append(buf, (guint8*)&new_tab, sizeof(new_tab));
172 g_byte_array_append(buf, (guint8*)&show_desktop, sizeof(show_desktop));
173 g_byte_array_append(buf, (guint8*)&desktop_off, sizeof(desktop_off));
174 g_byte_array_append(buf, (guint8*)&desktop_pref, sizeof(desktop_pref));
175 buf_append_str(buf, set_wallpaper);
176 g_byte_array_append(buf, (guint8*)&show_pref, sizeof(show_pref));
177 g_byte_array_append(buf, (guint8*)&find_files, sizeof(find_files));
178 g_byte_array_append(buf, (guint8*)&no_desktop, sizeof(no_desktop));
179
a1a528d2 180 len = files_to_open ? g_strv_length(files_to_open) : 0;
2b46b521
HJYP
181 g_byte_array_append(buf, (guint8*)&len, sizeof(len));
182 for(i = 0; i < len; ++i)
183 buf_append_str(buf, files_to_open[i]);
7b7d923f 184
f8f2bfad
HJYP
185 return buf;
186}
187
7b7d923f
HJYP
188inline static gboolean buf_read_bool(const char**p)
189{
190 gboolean ret;
191 memcpy(&ret, *p, sizeof(ret));
192 *p += sizeof(ret);
193 return ret;
194}
195
196inline static int buf_read_int(const char**p)
197{
198 int ret;
199 memcpy(&ret, *p, sizeof(ret));
200 *p += sizeof(ret);
201 return ret;
202}
203
204inline static char* buf_read_str(const char**p)
205{
206 char* ret;
207 int len = buf_read_int(p);
208 if(len > 0)
209 {
210 ret = g_malloc(len);
211 memcpy(ret, *p, len);
212 *p += len;
213 }
214 else
215 ret = NULL;
216 return ret;
217}
218
219inline static void ipc_buf_to_args(GByteArray* buf)
f8f2bfad 220{
7b7d923f
HJYP
221 int i, len;
222 char* p = buf->data;
223 char* cwd = buf_read_str(&p);
224 new_tab = buf_read_bool(&p);
225 show_desktop = buf_read_bool(&p);
226 desktop_off = buf_read_bool(&p);
227 desktop_pref = buf_read_bool(&p);
228 g_free(set_wallpaper);
229 set_wallpaper = buf_read_str(&p);
230 show_pref = buf_read_int(&p);
231 find_files = buf_read_bool(&p);
232 no_desktop = buf_read_bool(&p);
233
234 len = buf_read_int(&p);
2b46b521 235 g_debug("len = %d", len);
7b7d923f 236 if(len > 0)
b6e3c554 237 {
7b7d923f
HJYP
238 files_to_open = g_new(char*, len + 1);
239 for(i = 0; i < len; ++i)
f8f2bfad 240 {
7b7d923f
HJYP
241 char* file = buf_read_str(&p);
242 files_to_open[i] = fm_canonicalize_filename(file, cwd);
243 g_free(file);
f8f2bfad 244 }
7b7d923f 245 files_to_open[i] = NULL;
b6e3c554 246 }
7b7d923f
HJYP
247 else
248 files_to_open = NULL;
249 g_free(cwd);
f8f2bfad 250}
8505a8ef 251
f8f2bfad
HJYP
252gboolean on_socket_event( GIOChannel* ioc, GIOCondition cond, gpointer data )
253{
254 int client, r;
255 socklen_t addr_len = 0;
256 struct sockaddr_un client_addr ={ 0 };
257 static char buf[ 1024 ];
7b7d923f 258 GByteArray* args;
b6e3c554 259
f8f2bfad
HJYP
260 if ( cond & G_IO_IN )
261 {
262 client = accept( g_io_channel_unix_get_fd( ioc ), (struct sockaddr *)&client_addr, &addr_len );
263 if ( client != -1 )
264 {
7b7d923f 265 args = g_byte_array_sized_new(4096);
f8f2bfad 266 while( (r = read( client, buf, sizeof(buf) )) > 0 )
7b7d923f 267 g_byte_array_append( args, (guint8*)buf, r);
f8f2bfad
HJYP
268 shutdown( client, 2 );
269 close( client );
44409230 270 ipc_buf_to_args(args);
7b7d923f 271 g_byte_array_free( args, TRUE );
f8f2bfad
HJYP
272 pcmanfm_run();
273 }
274 }
275 return TRUE;
276}
19fbd668 277
f8f2bfad
HJYP
278void get_socket_name( char* buf, int len )
279{
280 char* dpy = gdk_get_display();
281 g_snprintf( buf, len, "/tmp/.pcmanfm2-socket%s-%s", dpy, g_get_user_name() );
282 g_free( dpy );
283}
8505a8ef 284
f8f2bfad
HJYP
285gboolean single_instance_check()
286{
287 struct sockaddr_un addr;
288 int addr_len;
289 int ret;
290 int reuse;
b6e3c554 291
f8f2bfad
HJYP
292 if((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
293 {
294 ret = 1;
295 goto _exit;
296 }
297
298 /* FIXME: use abstract socket */
299 addr.sun_family = AF_UNIX;
300 get_socket_name(addr.sun_path, sizeof( addr.sun_path ));
301#ifdef SUN_LEN
302 addr_len = SUN_LEN(&addr);
303#else
304 addr_len = strlen( addr.sun_path ) + sizeof( addr.sun_family );
305#endif
306
307 /* try to connect to existing instance */
308 if(connect(sock, (struct sockaddr*)&addr, addr_len) == 0)
309 {
310 /* connected successfully */
7b7d923f
HJYP
311 GByteArray* buf = args_to_ipc_buf();
312 write(sock, buf->data, buf->len);
313 g_byte_array_free(buf, TRUE);
f8f2bfad
HJYP
314
315 shutdown( sock, 2 );
316 close( sock );
317 ret = 0;
318 goto _exit;
319 }
320
321 /* There is no existing server, and we are in the first instance. */
322 unlink( addr.sun_path ); /* delete old socket file if it exists. */
323 reuse = 1;
324 ret = setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse) );
325 if(bind(sock, (struct sockaddr*)&addr, addr_len) == -1)
326 {
327 ret = 1;
328 goto _exit;
329 }
330
331 io_channel = g_io_channel_unix_new(sock);
332 g_io_channel_set_encoding(io_channel, NULL, NULL);
333 g_io_channel_set_buffered(io_channel, FALSE);
334 g_io_add_watch(io_channel, G_IO_IN,
335 (GIOFunc)on_socket_event, NULL);
336 if(listen(sock, 5) == -1)
337 {
338 ret = 1;
339 goto _exit;
340 }
d3451adb 341 return TRUE;
f8f2bfad
HJYP
342
343_exit:
344
345 gdk_notify_startup_complete();
346 exit( ret );
347}
348
349void single_instance_finalize()
350{
351 char lock_file[256];
352 shutdown(sock, 2);
353 g_io_channel_unref(io_channel);
354 close(sock);
355 get_socket_name(lock_file, sizeof( lock_file ));
356 unlink(lock_file);
357}
358
359
360gboolean pcmanfm_run()
361{
362 gboolean ret = TRUE;
f8f2bfad 363
f8f2bfad
HJYP
364 if(!files_to_open)
365 {
366 /* Launch desktop manager */
367 if(show_desktop)
368 {
369 if(!desktop_running)
370 {
371 fm_desktop_manager_init();
372 desktop_running = TRUE;
373 }
19abb8bf 374 show_desktop = FALSE;
f8f2bfad
HJYP
375 return TRUE;
376 }
377 else if(desktop_off)
378 {
379 if(desktop_running)
380 {
381 desktop_running = FALSE;
382 fm_desktop_manager_finalize();
383 }
19abb8bf 384 desktop_off = FALSE;
f8f2bfad
HJYP
385 return FALSE;
386 }
387 else if(show_pref > 0)
388 {
c5fccf1d
HJYP
389 fm_edit_preference(NULL, show_pref - 1);
390 show_pref = 0;
f8f2bfad
HJYP
391 return TRUE;
392 }
393 else if(desktop_pref)
394 {
c5fccf1d 395 fm_desktop_preference();
19abb8bf 396 desktop_pref = FALSE;
f8f2bfad
HJYP
397 return TRUE;
398 }
399 else if(set_wallpaper)
400 {
f970e846 401 /* g_debug("\'%s\'", set_wallpaper); */
f8f2bfad 402 /* Make sure this is a support image file. */
f970e846 403 if(gdk_pixbuf_get_file_info(set_wallpaper, NULL, NULL))
f8f2bfad 404 {
f970e846
HJYP
405 if(app_config->wallpaper)
406 g_free(app_config->wallpaper);
407 app_config->wallpaper = set_wallpaper;
f8f2bfad 408 set_wallpaper = NULL;
f970e846 409 if(app_config->wallpaper_mode == FM_WP_COLOR)
c5fccf1d 410 app_config->wallpaper_mode = FM_WP_FIT;
4b3e1fe9 411 fm_config_emit_changed(FM_CONFIG(app_config), "wallpaper");
dcecce78 412 fm_app_config_save(app_config, config_name);
f8f2bfad
HJYP
413 }
414 return FALSE;
415 }
416 }
417
418 if(G_UNLIKELY(find_files))
419 {
420 /* FIXME: find files */
421 }
422 else
423 {
df6826e0
HJYP
424 if(files_to_open)
425 {
426 char** filename;
0a053694 427 FmJob* job = fm_file_info_job_new(NULL, 0);
cacf261a 428 FmPath* cwd = NULL;
d951adb8 429 GList* infos;
df6826e0
HJYP
430 for(filename=files_to_open; *filename; ++filename)
431 {
cacf261a
HJYP
432 FmPath* path;
433 if( **filename == '/' || strstr(*filename, ":/") ) /* absolute path or URI */
434 path = fm_path_new(*filename);
0d8dce1a
HJYP
435 else if( strcmp(*filename, "~") == 0 ) /* special case for home dir */
436 {
437 path = fm_path_get_home();
438 fm_main_win_add_win(NULL, path);
439 continue;
440 }
cacf261a
HJYP
441 else /* basename */
442 {
443 if(G_UNLIKELY(!cwd))
444 {
445 /* FIXME: This won't work if those filenames are passed via IPC since the receiving process has different cwd. */
446 char* cwd_str = g_get_current_dir();
447 cwd = fm_path_new(cwd_str);
448 g_free(cwd_str);
449 }
450 path = fm_path_new_relative(cwd, *filename);
451 }
4b3e1fe9 452 fm_file_info_job_add(FM_FILE_INFO_JOB(job), path);
df6826e0
HJYP
453 fm_path_unref(path);
454 }
cacf261a
HJYP
455 if(cwd)
456 fm_path_unref(cwd);
a48f9fc8 457 fm_job_run_sync_with_mainloop(job);
d951adb8
HJYP
458 infos = fm_list_peek_head_link(FM_FILE_INFO_JOB(job)->file_infos);
459 fm_launch_files_simple(NULL, NULL, infos, pcmanfm_open_folder, NULL);
df6826e0 460 g_object_unref(job);
cacf261a 461 ret = (n_pcmanfm_ref >= 1); /* if there is opened window, return true to run the main loop. */
2b46b521
HJYP
462
463 g_strfreev(files_to_open);
464 files_to_open = NULL;
df6826e0
HJYP
465 }
466 else
f8f2bfad
HJYP
467 {
468 FmPath* path;
5b890032 469 char* cwd = ipc_cwd ? ipc_cwd : g_get_current_dir();
0d8dce1a
HJYP
470 path = fm_path_new(cwd);
471 fm_main_win_add_win(NULL, path);
472 fm_path_unref(path);
473 g_free(cwd);
5b890032 474 ipc_cwd = NULL;
f8f2bfad
HJYP
475 }
476 }
477 return ret;
478}
479
480/* After opening any window/dialog/tool, this should be called. */
481void pcmanfm_ref()
482{
483 ++n_pcmanfm_ref;
484 /* g_debug("ref: %d", n_pcmanfm_ref); */
485}
486
487/* After closing any window/dialog/tool, this should be called.
488 * If the last window is closed and we are not a deamon, pcmanfm will quit.
489 */
490void pcmanfm_unref()
491{
492 --n_pcmanfm_ref;
493 /* g_debug("unref: %d, daemon_mode=%d, desktop_running=%d", n_pcmanfm_ref, daemon_mode, desktop_running); */
494 if( 0 == n_pcmanfm_ref && !daemon_mode && !desktop_running )
495 gtk_main_quit();
b6e3c554 496}
df6826e0
HJYP
497
498gboolean pcmanfm_open_folder(GAppLaunchContext* ctx, GList* folder_infos, gpointer user_data, GError** err)
499{
df6826e0
HJYP
500 GList* l = folder_infos;
501 for(; l; l=l->next)
502 {
503 FmFileInfo* fi = (FmFileInfo*)l->data;
504 fm_main_win_open_in_last_active(fi->path);
505 }
506 return TRUE;
507}
dcecce78
HJYP
508
509void pcmanfm_save_config()
510{
511 fm_config_save(fm_config, NULL);
512 fm_app_config_save(app_config, config_name);
513}
c56a211a
HJYP
514
515void pcmanfm_open_folder_in_terminal(GtkWindow* parent, FmPath* dir)
516{
517 GAppInfo* app;
c56a211a
HJYP
518 char** argv;
519 int argc;
520 if(!fm_config->terminal)
521 {
522 fm_show_error(parent, _("Terminal emulator is not set."));
523 fm_edit_preference(parent, PREF_ADVANCED);
524 return;
525 }
526 if(!g_shell_parse_argv(fm_config->terminal, &argc, &argv, NULL))
527 return;
528 app = g_app_info_create_from_commandline(argv[0], NULL, 0, NULL);
529 g_strfreev(argv);
530 if(app)
531 {
532 GError* err = NULL;
533 GAppLaunchContext* ctx = gdk_app_launch_context_new();
534 char* cwd_str;
535
536 if(fm_path_is_native(dir))
537 cwd_str = fm_path_to_str(dir);
538 else
539 {
540 GFile* gf = fm_path_to_gfile(dir);
541 cwd_str = g_file_get_path(gf);
542 g_object_unref(gf);
543 }
99476ede 544 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
545 gdk_app_launch_context_set_timestamp(GDK_APP_LAUNCH_CONTEXT(ctx), gtk_get_current_event_time());
546 g_chdir(cwd_str); /* FIXME: currently we don't have better way for this. maybe a wrapper script? */
547 g_free(cwd_str);
548 if(!g_app_info_launch(app, NULL, ctx, &err))
549 {
550 fm_show_error(parent, err->message);
551 g_error_free(err);
552 }
553 g_object_unref(ctx);
554 g_object_unref(app);
555 }
556}
7cb06c27
HJYP
557
558/* FIXME: Need to load content of ~/Templates and list available templates in popup menus. */
559void pcmanfm_create_new(GtkWindow* parent, FmPath* cwd, const char* templ)
560{
561 GError* err = NULL;
562 FmPath* dest;
563 char* basename;
564_retry:
565 basename = fm_get_user_input(parent, _("Create New..."), _("Enter a name for the newly created file:"), _("New"));
566 if(!basename)
567 return;
568
569 dest = fm_path_new_child(cwd, basename);
570 g_free(basename);
571
572 if( templ == TEMPL_NAME_FOLDER )
573 {
574 GFile* gf = fm_path_to_gfile(dest);
575 if(!g_file_make_directory(gf, NULL, &err))
576 {
98daf506 577 if(err->domain == G_IO_ERROR && err->code == G_IO_ERROR_EXISTS)
7cb06c27
HJYP
578 {
579 fm_path_unref(dest);
580 g_error_free(err);
581 g_object_unref(gf);
582 err = NULL;
583 goto _retry;
584 }
585 fm_show_error(parent, err->message);
586 g_error_free(err);
587 }
588
589 if(!err) /* select the newly created file */
590 {
591 /*FIXME: this doesn't work since the newly created file will
592 * only be shown after file-created event was fired on its
593 * folder's monitor and after FmFolder handles it in idle
594 * handler. So, we cannot select it since it's not yet in
595 * the folder model now. */
596 /* fm_folder_view_select_file_path(fv, dest); */
597 }
598 g_object_unref(gf);
599 }
600 else if( templ == TEMPL_NAME_BLANK )
601 {
602 GFile* gf = fm_path_to_gfile(dest);
603 GFileOutputStream* f = g_file_create(gf, G_FILE_CREATE_NONE, NULL, &err);
604 if(f)
605 {
606 g_output_stream_close(G_OUTPUT_STREAM(f), NULL, NULL);
607 g_object_unref(f);
608 }
609 else
610 {
98daf506 611 if(err->domain == G_IO_ERROR && err->code == G_IO_ERROR_EXISTS)
7cb06c27
HJYP
612 {
613 fm_path_unref(dest);
614 g_error_free(err);
615 g_object_unref(gf);
616 err = NULL;
617 goto _retry;
618 }
619 fm_show_error(parent, err->message);
620 g_error_free(err);
621 }
622
623 if(!err) /* select the newly created file */
624 {
625 /*FIXME: this doesn't work since the newly created file will
626 * only be shown after file-created event was fired on its
627 * folder's monitor and after FmFolder handles it in idle
628 * handler. So, we cannot select it since it's not yet in
629 * the folder model now. */
630 /* fm_folder_view_select_file_path(fv, dest); */
631 }
632 g_object_unref(gf);
633 }
634 else /* templates in ~/Templates */
635 {
636 FmPath* dir = fm_path_new(g_get_user_special_dir(G_USER_DIRECTORY_TEMPLATES));
637 FmPath* template = fm_path_new_child(dir, templ);
638 fm_copy_file(template, cwd);
639 fm_path_unref(template);
640 }
641 fm_path_unref(dest);
642}