Revision 3089

src/filesel.c (revision 3089)
60 60
					 gpointer		 data);
61 61
#endif
62 62
#ifdef G_OS_WIN32
63
static gboolean is_ext_lnk		(const gchar		*filename);
63 64
static gchar *filesel_get_link		(const gchar		*link_file);
65
static GSList *filesel_resolve_link	(GtkFileChooser		*chooser,
66
					 GSList			*list,
67
					 gboolean		*dir_selected);
64 68
#endif
65 69

  
66 70

  
......
199 203
again:
200 204
	if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
201 205
		list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
206
#ifdef G_OS_WIN32
202 207
		if (list) {
203
#ifdef G_OS_WIN32
204
			/* follow Windows shortcut */
205
			if (g_slist_length(list) == 1) {
206
				gchar *selected = (gchar *)list->data;
207
				gchar *target;
208
				const gchar *ext;
209

  
210
				if ((ext = strrchr(selected, '.')) &&
211
				    g_ascii_strcasecmp(ext, ".lnk") == 0) {
212
					target = filesel_get_link(selected);
213
					if (is_dir_exist(target)) {
214
						gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), target);
215
						g_free(target);
216
						slist_free_strings(list);
217
						g_slist_free(list);
218
						list = NULL;
219
					    	goto again;
220
					} else if (is_file_exist(target)) {
221
						slist_free_strings(list);
222
						g_slist_free(list);
223
						list = g_slist_append(NULL, target);
224
					} else {
225
					    	g_free(target);
226
					}
227
				}
208
			/* resolve Windows shortcut */
209
			gboolean dir_selected = FALSE;
210
			list = filesel_resolve_link(GTK_FILE_CHOOSER(dialog),
211
						    list, &dir_selected);
212
			if (!list) {
213
				if (!dir_selected)
214
					alertpanel_error(_("The link target not found."));
215
				goto again;
228 216
			}
217
		}
229 218
#endif
219
		if (list) {
230 220
			cwd = gtk_file_chooser_get_current_folder
231 221
				(GTK_FILE_CHOOSER(dialog));
232 222
			if (cwd) {
......
373 363
	if (filename && is_file_exist(filename)) {
374 364
		AlertValue aval;
375 365

  
366
#ifdef G_OS_WIN32
367
		gchar *target = NULL;
368

  
369
		if (is_ext_lnk(filename) &&
370
		    (target = filesel_get_link(filename)) != NULL &&
371
		    is_dir_exist(target)) {
372
			gtk_file_chooser_set_current_folder(chooser, target);
373
		    	g_free(target);
374
		    	g_free(filename);
375
		    	return GTK_FILE_CHOOSER_CONFIRMATION_SELECT_AGAIN;
376
		}
377
		g_free(target);
378
#endif
379

  
376 380
		aval = alertpanel(_("Overwrite existing file"),
377 381
				  _("The file already exists. Do you want to replace it?"),
378 382
				  GTK_STOCK_YES, GTK_STOCK_NO, NULL);
......
389 393
#endif
390 394

  
391 395
#ifdef G_OS_WIN32
396
static gboolean is_ext_lnk(const gchar *filename)
397
{
398
	const gchar *ext;
399

  
400
	if (filename && (ext = strrchr(filename, '.')) &&
401
	    g_ascii_strcasecmp(ext, ".lnk") == 0)
402
		return TRUE;
403

  
404
	return FALSE;
405
}
406

  
392 407
static gchar *filesel_get_link(const gchar *link_file)
393 408
{
394 409
	WIN32_FIND_DATAW wfd;
......
407 422
	if (S_OK == CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkW, (void **)&psl)) {
408 423
		if (S_OK == IShellLinkW_QueryInterface(psl, &IID_IPersistFile, (void **)&ppf)) {
409 424
			wlink_file = g_utf8_to_utf16(link_file, -1, NULL, NULL, NULL);
410
			hr = IPersistFile_Load(ppf, wlink_file, STGM_READ);
411
			if (S_OK == hr) {
412
				IShellLinkW_GetPath(psl, wtarget, MAX_PATH, &wfd, SLGP_UNCPRIORITY);
413
				target = g_utf16_to_utf8(wtarget, -1, NULL, NULL, NULL);
425
			if (S_OK == IPersistFile_Load(ppf, wlink_file, STGM_READ)) {
426
				if (S_OK == IShellLinkW_GetPath(psl, wtarget, MAX_PATH, &wfd, SLGP_UNCPRIORITY)) {
427
					target = g_utf16_to_utf8(wtarget, -1, NULL, NULL, NULL);
428
				}
414 429
			}
415 430
			IPersistFile_Release(ppf);
416 431
			g_free(wlink_file);
......
426 441

  
427 442
	return target;
428 443
}
444

  
445
static GSList *filesel_resolve_link(GtkFileChooser *chooser, GSList *list, gboolean *dir_selected)
446
{
447
	GSList *cur;
448
	GSList *new_list = NULL;
449
	gchar *target;
450

  
451
	for (cur = list; cur != NULL; cur = cur->next) {
452
		gchar *selected = (gchar *)cur->data;
453

  
454
		if (is_ext_lnk(selected)) {
455
			target = filesel_get_link(selected);
456

  
457
		    	if (is_dir_exist(target)) {
458
				gtk_file_chooser_set_current_folder(chooser, target);
459
				g_free(target);
460
				slist_free_strings(new_list);
461
				g_slist_free(new_list);
462
		    		new_list = NULL;
463
				*dir_selected = TRUE;
464
		    		break;
465
			} else if (is_file_exist(target)) {
466
				new_list = g_slist_append(new_list, target);
467
			} else {
468
			    	g_free(target);
469
			}
470
		} else {
471
			new_list = g_slist_append(new_list, g_strdup(selected));
472
		}
473
	}
474

  
475
	slist_free_strings(list);
476
	g_slist_free(list);
477

  
478
	return new_list;
479
}
429 480
#endif
ChangeLog (revision 3089)
1
2012-06-12
2

  
3
	* src/filesel.c: win32: handle multiple file selection with shortcuts.
4
	  Follow folder link on save mode.
5

  
1 6
2012-06-11
2 7

  
3 8
	* src/filesel.c: win32: follow Windows shortcut (.lnk).

Also available in: Unified diff