Bug Summary

File:libbaul-private/baul-mime-actions.c
Warning:line 1608, column 9
Value stored to 'show_install_mime' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name baul-mime-actions.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/libbaul-private -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -I .. -I .. -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/cafe-desktop-2.0 -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/startup-notification-1.0 -I /usr/include/dconf -I /usr/include/cail-3.0 -I /usr/include/libxml2 -D G_DISABLE_DEPRECATED -D GDK_PIXBUF_DISABLE_DEPRECATED -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -D BAUL_DATADIR="/usr/local/share/baul" -D BAUL_EXTENSIONDIR="/usr/local/lib/baul/extensions-2.0" -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/libbaul-private -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-01-10-171457-28394-1 -x c baul-mime-actions.c
1/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2
3/* baul-mime-actions.c - uri-specific versions of mime action functions
4
5 Copyright (C) 2000, 2001 Eazel, Inc.
6
7 The Cafe Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11
12 The Cafe Library 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 GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public
18 License along with the Cafe Library; see the file COPYING.LIB. If not,
19 write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20 Boston, MA 02110-1301, USA.
21
22 Authors: Maciej Stachowiak <mjs@eazel.com>
23*/
24
25#include <config.h>
26#include <string.h>
27
28#include <glib/gi18n.h>
29#include <glib/gstdio.h>
30#include <cdk/cdkx.h>
31
32#include <eel/eel-glib-extensions.h>
33#include <eel/eel-stock-dialogs.h>
34#include <eel/eel-string.h>
35
36#include "baul-mime-actions.h"
37#include "baul-file-attributes.h"
38#include "baul-file.h"
39#include "baul-autorun.h"
40#include "baul-file-operations.h"
41#include "baul-metadata.h"
42#include "baul-program-choosing.h"
43#include "baul-desktop-icon-file.h"
44#include "baul-global-preferences.h"
45#include "baul-debug-log.h"
46#include "baul-open-with-dialog.h"
47
48typedef enum
49{
50 ACTIVATION_ACTION_LAUNCH_DESKTOP_FILE,
51 ACTIVATION_ACTION_ASK,
52 ACTIVATION_ACTION_LAUNCH,
53 ACTIVATION_ACTION_LAUNCH_IN_TERMINAL,
54 ACTIVATION_ACTION_OPEN_IN_VIEW,
55 ACTIVATION_ACTION_OPEN_IN_APPLICATION,
56 ACTIVATION_ACTION_DO_NOTHING,
57} ActivationAction;
58
59typedef struct
60{
61 BaulFile *file;
62 char *uri;
63} LaunchLocation;
64
65typedef struct
66{
67 GAppInfo *application;
68 GList *uris;
69} ApplicationLaunchParameters;
70
71typedef struct
72{
73 BaulWindowSlotInfo *slot_info;
74 gpointer window_info;
75 CtkWindow *parent_window;
76 GCancellable *cancellable;
77 GList *locations;
78 GList *mountables;
79 GList *start_mountables;
80 GList *not_mounted;
81 BaulWindowOpenMode mode;
82 BaulWindowOpenFlags flags;
83 char *timed_wait_prompt;
84 gboolean timed_wait_active;
85 BaulFileListHandle *files_handle;
86 gboolean tried_mounting;
87 char *activation_directory;
88 gboolean user_confirmation;
89} ActivateParameters;
90
91/* Number of seconds until cancel dialog shows up */
92#define DELAY_UNTIL_CANCEL_MSECS5000 5000
93
94#define RESPONSE_RUN1000 1000
95#define RESPONSE_DISPLAY1001 1001
96#define RESPONSE_RUN_IN_TERMINAL1002 1002
97#define RESPONSE_MARK_TRUSTED1003 1003
98
99#define SILENT_WINDOW_OPEN_LIMIT5 5
100
101/* This number controls a maximum character count for a URL that is
102 * displayed as part of a dialog. It's fairly arbitrary -- big enough
103 * to allow most "normal" URIs to display in full, but small enough to
104 * prevent the dialog from getting insanely wide.
105 */
106#define MAX_URI_IN_DIALOG_LENGTH60 60
107
108static void cancel_activate_callback (gpointer callback_data);
109static void activate_activation_uris_ready_callback (GList *files,
110 gpointer callback_data);
111static void activation_mount_mountables (ActivateParameters *parameters);
112static void activation_start_mountables (ActivateParameters *parameters);
113static void activate_callback (GList *files,
114 gpointer callback_data);
115static void activation_mount_not_mounted (ActivateParameters *parameters);
116
117
118static void
119launch_location_free (LaunchLocation *location)
120{
121 baul_file_unref (location->file);
122 g_free (location->uri);
123 g_free (location);
124}
125
126static void
127launch_location_list_free (GList *list)
128{
129 g_list_foreach (list, (GFunc)launch_location_free, NULL((void*)0));
130 g_list_free (list);
131}
132
133static GList *
134get_file_list_for_launch_locations (GList *locations)
135{
136 GList *files, *l;
137 LaunchLocation *location = NULL((void*)0);
138
139 files = NULL((void*)0);
140 for (l = locations; l != NULL((void*)0); l = l->next)
141 {
142 location = l->data;
143
144 files = g_list_prepend (files,
145 baul_file_ref (location->file));
146 }
147 return g_list_reverse (files);
148}
149
150
151static LaunchLocation *
152launch_location_from_file (BaulFile *file)
153{
154 LaunchLocation *location;
155 location = g_new (LaunchLocation, 1)((LaunchLocation *) g_malloc_n ((1), sizeof (LaunchLocation))
)
;
156 location->file = baul_file_ref (file);
157 location->uri = baul_file_get_uri (file);
158
159 return location;
160}
161
162static void
163launch_location_update_from_file (LaunchLocation *location,
164 BaulFile *file)
165{
166 baul_file_unref (location->file);
167 g_free (location->uri);
168 location->file = baul_file_ref (file);
169 location->uri = baul_file_get_uri (file);
170}
171
172static void
173launch_location_update_from_uri (LaunchLocation *location,
174 const char *uri)
175{
176 baul_file_unref (location->file);
177 g_free (location->uri);
178 location->file = baul_file_get_by_uri (uri);
179 location->uri = g_strdup (uri)g_strdup_inline (uri);
180}
181
182static LaunchLocation *
183find_launch_location_for_file (GList *list,
184 BaulFile *file)
185{
186 GList *l;
187 LaunchLocation *location = NULL((void*)0);
188
189 for (l = list; l != NULL((void*)0); l = l->next)
190 {
191 location = l->data;
192
193 if (location->file == file)
194 {
195 return location;
196 }
197 }
198 return NULL((void*)0);
199}
200
201static GList *
202launch_locations_from_file_list (GList *list)
203{
204 GList *new;
205
206 new = NULL((void*)0);
207 while (list)
208 {
209 new = g_list_prepend (new,
210 launch_location_from_file (list->data));
211 list = list->next;
212 }
213 new = g_list_reverse (new);
214 return new;
215}
216
217static ApplicationLaunchParameters *
218application_launch_parameters_new (GAppInfo *application,
219 GList *uris)
220{
221 ApplicationLaunchParameters *result;
222
223 result = g_new0 (ApplicationLaunchParameters, 1)((ApplicationLaunchParameters *) g_malloc0_n ((1), sizeof (ApplicationLaunchParameters
)))
;
224 result->application = g_object_ref (application)((__typeof__ (application)) (g_object_ref) (application));
225 result->uris = g_list_copy_deep (uris, (GCopyFunc) g_strdup, NULL((void*)0));
226
227 return result;
228}
229
230static void
231application_launch_parameters_free (ApplicationLaunchParameters *parameters)
232{
233 g_object_unref (parameters->application);
234 g_list_free_full (parameters->uris, g_free);
235
236 g_free (parameters);
237}
238
239static GList*
240filter_baul_handler (GList *apps)
241{
242 GList *l, *next;
243 GAppInfo *application = NULL((void*)0);
244
245 l = apps;
246 while (l != NULL((void*)0))
247 {
248 const char *id;
249
250 application = (GAppInfo *) l->data;
251 next = l->next;
252
253 id = g_app_info_get_id (application);
254 if (id != NULL((void*)0) &&
255 strcmp (id,
256 "baul-folder-handler.desktop") == 0)
257 {
258 g_object_unref (application);
259 apps = g_list_delete_link (apps, l);
260 }
261
262 l = next;
263 }
264
265 return apps;
266}
267
268static GList*
269filter_non_uri_apps (GList *apps)
270{
271 GList *l, *next;
272 GAppInfo *app = NULL((void*)0);
273
274 for (l = apps; l != NULL((void*)0); l = next)
275 {
276 app = l->data;
277 next = l->next;
278
279 if (!g_app_info_supports_uris (app))
280 {
281 apps = g_list_delete_link (apps, l);
282 g_object_unref (app);
283 }
284 }
285 return apps;
286}
287
288
289static gboolean
290baul_mime_actions_check_if_required_attributes_ready (BaulFile *file)
291{
292 BaulFileAttributes attributes;
293 gboolean ready;
294
295 attributes = baul_mime_actions_get_required_file_attributes ();
296 ready = baul_file_check_if_ready (file, attributes);
297
298 return ready;
299}
300
301BaulFileAttributes
302baul_mime_actions_get_required_file_attributes (void)
303{
304 return BAUL_FILE_ATTRIBUTE_INFO |
305 BAUL_FILE_ATTRIBUTE_LINK_INFO;
306}
307
308static gboolean
309file_has_local_path (BaulFile *file)
310{
311 GFile *location;
312 char *path;
313 gboolean res;
314
315
316 /* Don't only check _is_native, because we want to support
317 using the fuse path */
318 location = baul_file_get_location (file);
319 if (g_file_is_native (location))
320 {
321 res = TRUE(!(0));
322 }
323 else
324 {
325 path = g_file_get_path (location);
326
327 res = path != NULL((void*)0);
328
329 g_free (path);
330 }
331 g_object_unref (location);
332
333 return res;
334}
335
336GAppInfo *
337baul_mime_get_default_application_for_file (BaulFile *file)
338{
339 GAppInfo *app;
340 char *mime_type;
341
342 if (!baul_mime_actions_check_if_required_attributes_ready (file))
343 {
344 return NULL((void*)0);
345 }
346
347 mime_type = baul_file_get_mime_type (file);
348 app = g_app_info_get_default_for_type (mime_type, !file_has_local_path (file));
349 g_free (mime_type);
350
351 if (app == NULL((void*)0))
352 {
353 char *uri_scheme;
354
355 uri_scheme = baul_file_get_uri_scheme (file);
356 if (uri_scheme != NULL((void*)0))
357 {
358 app = g_app_info_get_default_for_uri_scheme (uri_scheme);
359 g_free (uri_scheme);
360 }
361 }
362
363 return app;
364}
365
366static int
367file_compare_by_mime_type (BaulFile *file_a,
368 BaulFile *file_b)
369{
370 char *mime_type_a, *mime_type_b;
371 int ret;
372
373 mime_type_a = baul_file_get_mime_type (file_a);
374 mime_type_b = baul_file_get_mime_type (file_b);
375
376 ret = strcmp (mime_type_a, mime_type_b);
377
378 g_free (mime_type_a);
379 g_free (mime_type_b);
380
381 return ret;
382}
383
384static int
385file_compare_by_parent_uri (BaulFile *file_a,
386 BaulFile *file_b)
387{
388 char *parent_uri_a, *parent_uri_b;
389 int ret;
390
391 parent_uri_a = baul_file_get_parent_uri (file_a);
392 parent_uri_b = baul_file_get_parent_uri (file_b);
393
394 ret = strcmp (parent_uri_a, parent_uri_b);
395
396 g_free (parent_uri_a);
397 g_free (parent_uri_b);
398
399 return ret;
400}
401
402static int
403application_compare_by_name (const GAppInfo *app_a,
404 const GAppInfo *app_b)
405{
406 return g_utf8_collate (g_app_info_get_display_name ((GAppInfo *)app_a),
407 g_app_info_get_display_name ((GAppInfo *)app_b));
408}
409
410static int
411application_compare_by_id (const GAppInfo *app_a,
412 const GAppInfo *app_b)
413{
414 const char *id_a, *id_b;
415
416 id_a = g_app_info_get_id ((GAppInfo *)app_a);
417 id_b = g_app_info_get_id ((GAppInfo *)app_b);
418
419 if (id_a == NULL((void*)0) && id_b == NULL((void*)0))
420 {
421 if (g_app_info_equal ((GAppInfo *)app_a, (GAppInfo *)app_b))
422 {
423 return 0;
424 }
425 if ((gsize)app_a < (gsize) app_b)
426 {
427 return -1;
428 }
429 return 1;
430 }
431
432 if (id_a == NULL((void*)0))
433 {
434 return -1;
435 }
436
437 if (id_b == NULL((void*)0))
438 {
439 return 1;
440 }
441
442
443 return strcmp (id_a, id_b);
444}
445
446GList *
447baul_mime_get_applications_for_file (BaulFile *file)
448{
449 char *mime_type;
450 char *uri_scheme;
451 GList *result;
452
453 if (!baul_mime_actions_check_if_required_attributes_ready (file))
454 {
455 return NULL((void*)0);
456 }
457 mime_type = baul_file_get_mime_type (file);
458 result = g_app_info_get_all_for_type (mime_type);
459
460 uri_scheme = baul_file_get_uri_scheme (file);
461 if (uri_scheme != NULL((void*)0))
462 {
463 GAppInfo *uri_handler;
464
465 uri_handler = g_app_info_get_default_for_uri_scheme (uri_scheme);
466 if (uri_handler)
467 {
468 result = g_list_prepend (result, uri_handler);
469 }
470 g_free (uri_scheme);
471 }
472
473 if (!file_has_local_path (file))
474 {
475 /* Filter out non-uri supporting apps */
476 result = filter_non_uri_apps (result);
477 }
478
479 result = g_list_sort (result, (GCompareFunc) application_compare_by_name);
480 g_free (mime_type);
481
482 return filter_baul_handler (result);
483}
484
485gboolean
486baul_mime_has_any_applications_for_file (BaulFile *file)
487{
488 GList *apps;
489 char *mime_type;
490 gboolean result;
491 char *uri_scheme;
492
493 mime_type = baul_file_get_mime_type (file);
494
495 apps = g_app_info_get_all_for_type (mime_type);
496
497 uri_scheme = baul_file_get_uri_scheme (file);
498 if (uri_scheme != NULL((void*)0))
499 {
500 GAppInfo *uri_handler;
501
502 uri_handler = g_app_info_get_default_for_uri_scheme (uri_scheme);
503 if (uri_handler)
504 {
505 apps = g_list_prepend (apps, uri_handler);
506 }
507 g_free (uri_scheme);
508 }
509
510 if (!file_has_local_path (file))
511 {
512 /* Filter out non-uri supporting apps */
513 apps = filter_non_uri_apps (apps);
514 }
515 apps = filter_baul_handler (apps);
516
517 if (apps)
518 {
519 result = TRUE(!(0));
520 g_list_free_full (apps, g_object_unref);
521 }
522 else
523 {
524 result = FALSE(0);
525 }
526
527 g_free (mime_type);
528
529 return result;
530}
531
532GAppInfo *
533baul_mime_get_default_application_for_files (GList *files)
534{
535 GList *l, *sorted_files;
536 GAppInfo *app, *one_app;
537 BaulFile *file = NULL((void*)0);
538
539 g_assert (files != NULL)do { if (files != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-mime-actions.c", 539, ((const char*) (__func__
)), "files != NULL"); } while (0)
;
540
541 sorted_files = g_list_sort (g_list_copy (files), (GCompareFunc) file_compare_by_mime_type);
542
543 app = NULL((void*)0);
544 for (l = sorted_files; l != NULL((void*)0); l = l->next)
545 {
546 file = l->data;
547
548 if (l->prev &&
549 file_compare_by_mime_type (file, l->prev->data) == 0 &&
550 file_compare_by_parent_uri (file, l->prev->data) == 0)
551 {
552 continue;
553 }
554
555 one_app = baul_mime_get_default_application_for_file (file);
556 if (one_app == NULL((void*)0) || (app != NULL((void*)0) && !g_app_info_equal (app, one_app)))
557 {
558 if (app)
559 {
560 g_object_unref (app);
561 }
562 if (one_app)
563 {
564 g_object_unref (one_app);
565 }
566 app = NULL((void*)0);
567 break;
568 }
569
570 if (app == NULL((void*)0))
571 {
572 app = one_app;
573 }
574 else
575 {
576 g_object_unref (one_app);
577 }
578 }
579
580 g_list_free (sorted_files);
581
582 return app;
583}
584
585/* returns an intersection of two mime application lists,
586 * and returns a new list, freeing a, b and all applications
587 * that are not in the intersection set.
588 * The lists are assumed to be pre-sorted by their IDs */
589static GList *
590intersect_application_lists (GList *a,
591 GList *b)
592{
593 GList *l, *m;
594 GList *ret;
595 GAppInfo *a_app = NULL((void*)0);
596 GAppInfo *b_app = NULL((void*)0);
597
598 ret = NULL((void*)0);
599
600 l = a;
601 m = b;
602
603 while (l != NULL((void*)0) && m != NULL((void*)0))
604 {
605 int cmp;
606
607 a_app = (GAppInfo *) l->data;
608 b_app = (GAppInfo *) m->data;
609
610 cmp = application_compare_by_id (a_app, b_app);
611 if (cmp > 0)
612 {
613 g_object_unref (b_app);
614 m = m->next;
615 }
616 else if (cmp < 0)
617 {
618 g_object_unref (a_app);
619 l = l->next;
620 }
621 else
622 {
623 g_object_unref (b_app);
624 ret = g_list_prepend (ret, a_app);
625 l = l->next;
626 m = m->next;
627 }
628 }
629
630 g_list_foreach (l, (GFunc) g_object_unref, NULL((void*)0));
631 g_list_foreach (m, (GFunc) g_object_unref, NULL((void*)0));
632
633 g_list_free (a);
634 g_list_free (b);
635
636 return g_list_reverse (ret);
637}
638
639GList *
640baul_mime_get_applications_for_files (GList *files)
641{
642 GList *l, *sorted_files;
643 GList *one_ret, *ret;
644 BaulFile *file = NULL((void*)0);
645
646 g_assert (files != NULL)do { if (files != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-mime-actions.c", 646, ((const char*) (__func__
)), "files != NULL"); } while (0)
;
647
648 sorted_files = g_list_sort (g_list_copy (files), (GCompareFunc) file_compare_by_mime_type);
649
650 ret = NULL((void*)0);
651 for (l = sorted_files; l != NULL((void*)0); l = l->next)
652 {
653 file = l->data;
654
655 if (l->prev &&
656 file_compare_by_mime_type (file, l->prev->data) == 0 &&
657 file_compare_by_parent_uri (file, l->prev->data) == 0)
658 {
659 continue;
660 }
661
662 one_ret = baul_mime_get_applications_for_file (file);
663 one_ret = g_list_sort (one_ret, (GCompareFunc) application_compare_by_id);
664 if (ret != NULL((void*)0))
665 {
666 ret = intersect_application_lists (ret, one_ret);
667 }
668 else
669 {
670 ret = one_ret;
671 }
672
673 if (ret == NULL((void*)0))
674 {
675 break;
676 }
677 }
678
679 g_list_free (sorted_files);
680
681 ret = g_list_sort (ret, (GCompareFunc) application_compare_by_name);
682
683 return ret;
684}
685
686static void
687trash_or_delete_files (CtkWindow *parent_window,
688 const GList *files,
689 gboolean delete_if_all_already_in_trash)
690{
691 GList *locations;
692 const GList *node;
693
694 locations = NULL((void*)0);
695 for (node = files; node != NULL((void*)0); node = node->next)
696 {
697 locations = g_list_prepend (locations,
698 baul_file_get_location ((BaulFile *) node->data));
699 }
700
701 locations = g_list_reverse (locations);
702
703 baul_file_operations_trash_or_delete (locations,
704 parent_window,
705 NULL((void*)0), NULL((void*)0));
706 g_list_free_full (locations, g_object_unref);
707}
708
709static void
710report_broken_symbolic_link (CtkWindow *parent_window, BaulFile *file)
711{
712 char *target_path;
713 char *display_name;
714 char *prompt;
715 char *detail;
716 CtkDialog *dialog;
717 GList file_as_list;
718 int response;
719
720 g_assert (baul_file_is_broken_symbolic_link (file))do { if (baul_file_is_broken_symbolic_link (file)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-mime-actions.c", 720, ((const char*) (__func__
)), "baul_file_is_broken_symbolic_link (file)"); } while (0)
;
721
722 display_name = baul_file_get_display_name (file);
723 if (baul_file_is_in_trash (file))
724 {
725 prompt = g_strdup_printf (_("The Link \"%s\" is Broken.")gettext ("The Link \"%s\" is Broken."), display_name);
726 }
727 else
728 {
729 prompt = g_strdup_printf (_("The Link \"%s\" is Broken. Move it to Trash?")gettext ("The Link \"%s\" is Broken. Move it to Trash?"), display_name);
730 }
731 g_free (display_name);
732
733 target_path = baul_file_get_symbolic_link_target_path (file);
734 if (target_path == NULL((void*)0))
735 {
736 detail = g_strdup (_("This link cannot be used, because it has no target."))g_strdup_inline (gettext ("This link cannot be used, because it has no target."
))
;
737 }
738 else
739 {
740 detail = g_strdup_printf (_("This link cannot be used, because its target "gettext ("This link cannot be used, because its target " "\"%s\" doesn't exist."
)
741 "\"%s\" doesn't exist.")gettext ("This link cannot be used, because its target " "\"%s\" doesn't exist."
)
, target_path);
742 }
743
744 if (baul_file_is_in_trash (file))
745 {
746 eel_run_simple_dialog (CTK_WIDGET (parent_window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parent_window)), ((ctk_widget_get_type ()))))))
, FALSE(0), CTK_MESSAGE_WARNING,
747 prompt, detail, "process-stop", NULL((void*)0));
748 goto out;
749 }
750
751 dialog = eel_show_yes_no_dialog (prompt, detail, _("Mo_ve to Trash")gettext ("Mo_ve to Trash"), "process-stop",
752 parent_window);
753
754 ctk_dialog_set_default_response (dialog, CTK_RESPONSE_CANCEL);
755
756 /* Make this modal to avoid problems with reffing the view & file
757 * to keep them around in case the view changes, which would then
758 * cause the old view not to be destroyed, which would cause its
759 * merged CafeComponent items not to be un-merged. Maybe we need to unmerge
760 * explicitly when disconnecting views instead of relying on the
761 * unmerge in Destroy. But since CafeComponentUIHandler is probably going
762 * to change wildly, I don't want to mess with this now.
763 */
764
765 response = ctk_dialog_run (dialog);
766 ctk_widget_destroy (CTK_WIDGET (dialog)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_widget_get_type ()))))))
);
767
768 if (response == CTK_RESPONSE_YES)
769 {
770 file_as_list.data = file;
771 file_as_list.next = NULL((void*)0);
772 file_as_list.prev = NULL((void*)0);
773 trash_or_delete_files (parent_window, &file_as_list, TRUE(!(0)));
774 }
775
776out:
777 g_free (prompt);
778 g_free (target_path);
779 g_free (detail);
780}
781
782static ActivationAction
783get_executable_text_file_action (CtkWindow *parent_window, BaulFile *file)
784{
785 CtkDialog *dialog;
786 char *file_name;
787 char *prompt;
788 char *detail;
789 int preferences_value;
790 int response;
791
792 g_assert (baul_file_contains_text (file))do { if (baul_file_contains_text (file)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-mime-actions.c", 792, ((const char*) (__func__
)), "baul_file_contains_text (file)"); } while (0)
;
793
794 preferences_value = g_settings_get_enum (baul_preferences,
795 BAUL_PREFERENCES_EXECUTABLE_TEXT_ACTIVATION"executable-text-activation");
796 switch (preferences_value)
797 {
798 case BAUL_EXECUTABLE_TEXT_LAUNCH:
799 return ACTIVATION_ACTION_LAUNCH;
800 case BAUL_EXECUTABLE_TEXT_DISPLAY:
801 return ACTIVATION_ACTION_OPEN_IN_APPLICATION;
802 case BAUL_EXECUTABLE_TEXT_ASK:
803 break;
804 default:
805 /* Complain non-fatally, since preference data can't be trusted */
806 g_warning ("Unknown value %d for BAUL_PREFERENCES_EXECUTABLE_TEXT_ACTIVATION",
807 preferences_value);
808
809 }
810
811
812 file_name = baul_file_get_display_name (file);
813 prompt = g_strdup_printf (_("Do you want to run \"%s\", or display its contents?")gettext ("Do you want to run \"%s\", or display its contents?"
)
,
814 file_name);
815 detail = g_strdup_printf (_("\"%s\" is an executable text file.")gettext ("\"%s\" is an executable text file."),
816 file_name);
817 g_free (file_name);
818
819 dialog = eel_create_question_dialog (prompt,
820 detail,
821 _("Run in _Terminal")gettext ("Run in _Terminal"), RESPONSE_RUN_IN_TERMINAL1002,
822 _("_Display")gettext ("_Display"), RESPONSE_DISPLAY1001,
823 parent_window);
824
825 eel_dialog_add_button (dialog,
826 _("_Cancel")gettext ("_Cancel"),
827 "process-stop",
828 CTK_RESPONSE_CANCEL);
829
830 ctk_dialog_add_button (dialog, _("_Run")gettext ("_Run"), RESPONSE_RUN1000);
831 ctk_dialog_set_default_response (dialog, CTK_RESPONSE_CANCEL);
832 ctk_widget_show (CTK_WIDGET (dialog)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_widget_get_type ()))))))
);
833
834 g_free (prompt);
835 g_free (detail);
836
837 response = ctk_dialog_run (dialog);
838 ctk_widget_destroy (CTK_WIDGET (dialog)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_widget_get_type ()))))))
);
839
840 switch (response)
841 {
842 case RESPONSE_RUN1000:
843 return ACTIVATION_ACTION_LAUNCH;
844 case RESPONSE_RUN_IN_TERMINAL1002:
845 return ACTIVATION_ACTION_LAUNCH_IN_TERMINAL;
846 case RESPONSE_DISPLAY1001:
847 return ACTIVATION_ACTION_OPEN_IN_APPLICATION;
848 default:
849 return ACTIVATION_ACTION_DO_NOTHING;
850 }
851}
852
853static ActivationAction
854get_default_executable_text_file_action (void)
855{
856 int preferences_value;
857
858 preferences_value = g_settings_get_enum (baul_preferences,
859 BAUL_PREFERENCES_EXECUTABLE_TEXT_ACTIVATION"executable-text-activation");
860 switch (preferences_value)
861 {
862 case BAUL_EXECUTABLE_TEXT_LAUNCH:
863 return ACTIVATION_ACTION_LAUNCH;
864 case BAUL_EXECUTABLE_TEXT_DISPLAY:
865 return ACTIVATION_ACTION_OPEN_IN_APPLICATION;
866 case BAUL_EXECUTABLE_TEXT_ASK:
867 default:
868 return ACTIVATION_ACTION_ASK;
869 }
870}
871
872gboolean
873baul_mime_file_opens_in_view (BaulFile *file)
874{
875 return (baul_file_is_directory (file));
876}
877
878static ActivationAction
879get_activation_action (BaulFile *file)
880{
881 ActivationAction action;
882 char *activation_uri;
883
884 if (baul_file_is_baul_link (file))
885 {
886 return ACTIVATION_ACTION_LAUNCH_DESKTOP_FILE;
887 }
888
889 activation_uri = baul_file_get_activation_uri (file);
890 if (activation_uri == NULL((void*)0))
891 {
892 activation_uri = baul_file_get_uri (file);
893 }
894
895 action = ACTIVATION_ACTION_DO_NOTHING;
896 if (baul_file_is_launchable (file))
897 {
898 char *executable_path;
899
900 action = ACTIVATION_ACTION_LAUNCH;
901
902 executable_path = g_filename_from_uri (activation_uri, NULL((void*)0), NULL((void*)0));
903 if (!executable_path)
904 {
905 action = ACTIVATION_ACTION_DO_NOTHING;
906 }
907 else if (baul_file_contains_text (file))
908 {
909 action = get_default_executable_text_file_action ();
910 }
911 g_free (executable_path);
912 }
913
914 if (action == ACTIVATION_ACTION_DO_NOTHING)
915 {
916 if (baul_mime_file_opens_in_view (file))
917 {
918 action = ACTIVATION_ACTION_OPEN_IN_VIEW;
919 }
920 else
921 {
922 action = ACTIVATION_ACTION_OPEN_IN_APPLICATION;
923 }
924 }
925 g_free (activation_uri);
926
927 return action;
928}
929
930gboolean
931baul_mime_file_opens_in_external_app (BaulFile *file)
932{
933 ActivationAction activation_action;
934
935 activation_action = get_activation_action (file);
936
937 return (activation_action == ACTIVATION_ACTION_OPEN_IN_APPLICATION);
938}
939
940
941static unsigned int
942mime_application_hash (GAppInfo *app)
943{
944 const char *id;
945
946 id = g_app_info_get_id (app);
947
948 if (id == NULL((void*)0))
949 {
950 return GPOINTER_TO_UINT(app)((guint) (gulong) (app));
951 }
952
953 return g_str_hash (id);
954}
955
956static void
957list_to_parameters_foreach (GAppInfo *application,
958 GList *uris,
959 GList **ret)
960{
961 ApplicationLaunchParameters *parameters;
962
963 uris = g_list_reverse (uris);
964
965 parameters = application_launch_parameters_new
966 (application, uris);
967 *ret = g_list_prepend (*ret, parameters);
968}
969
970
971/**
972 * make_activation_parameters
973 *
974 * Construct a list of ApplicationLaunchParameters from a list of BaulFiles,
975 * where files that have the same default application are put into the same
976 * launch parameter, and others are put into the unhandled_files list.
977 *
978 * @files: Files to use for construction.
979 * @unhandled_files: Files without any default application will be put here.
980 *
981 * Return value: Newly allocated list of ApplicationLaunchParameters.
982 **/
983static GList *
984make_activation_parameters (GList *uris,
985 GList **unhandled_uris)
986{
987 GList *ret, *l, *app_uris;
988 GHashTable *app_table;
989 GAppInfo *old_app;
990 GAppInfo *app = NULL((void*)0);
991 BaulFile *file = NULL((void*)0);
992
993 ret = NULL((void*)0);
994 *unhandled_uris = NULL((void*)0);
995
996 app_table = g_hash_table_new_full
997 ((GHashFunc) mime_application_hash,
998 (GEqualFunc) g_app_info_equal,
999 (GDestroyNotify) g_object_unref,
1000 (GDestroyNotify) g_list_free);
1001
1002 for (l = uris; l != NULL((void*)0); l = l->next)
1003 {
1004 char *uri;
1005
1006 uri = l->data;
1007 file = baul_file_get_by_uri (uri);
1008
1009 /* Double-check if a file's MIME type has changed before we commit to a
1010 choice of application for it. This can happen if, for instance, file
1011 was originally created with 0 bytes and then content was added to it
1012 later-- it will change from plaintext to something else. */
1013 baul_file_refresh_info (file);
1014
1015 app = baul_mime_get_default_application_for_file (file);
1016 if (app != NULL((void*)0))
1017 {
1018 app_uris = NULL((void*)0);
1019
1020 if (g_hash_table_lookup_extended (app_table, app,
1021 (gpointer *) &old_app,
1022 (gpointer *) &app_uris))
1023 {
1024 g_hash_table_steal (app_table, old_app);
1025
1026 app_uris = g_list_prepend (app_uris, uri);
1027
1028 g_object_unref (app);
1029 app = old_app;
1030 }
1031 else
1032 {
1033 app_uris = g_list_prepend (NULL((void*)0), uri);
1034 }
1035
1036 g_hash_table_insert (app_table, app, app_uris);
1037 }
1038 else
1039 {
1040 *unhandled_uris = g_list_prepend (*unhandled_uris, uri);
1041 }
1042 baul_file_unref (file);
1043 }
1044
1045 g_hash_table_foreach (app_table,
1046 (GHFunc) list_to_parameters_foreach,
1047 &ret);
1048
1049 g_hash_table_destroy (app_table);
1050
1051 *unhandled_uris = g_list_reverse (*unhandled_uris);
1052
1053 return g_list_reverse (ret);
1054}
1055
1056static gboolean
1057file_was_cancelled (BaulFile *file)
1058{
1059 GError *error;
1060
1061 error = baul_file_get_file_info_error (file);
1062 return
1063 error != NULL((void*)0) &&
1064 error->domain == G_IO_ERRORg_io_error_quark() &&
1065 error->code == G_IO_ERROR_CANCELLED;
1066}
1067
1068static gboolean
1069file_was_not_mounted (BaulFile *file)
1070{
1071 GError *error;
1072
1073 error = baul_file_get_file_info_error (file);
1074 return
1075 error != NULL((void*)0) &&
1076 error->domain == G_IO_ERRORg_io_error_quark() &&
1077 error->code == G_IO_ERROR_NOT_MOUNTED;
1078}
1079
1080static void
1081activation_parameters_free (ActivateParameters *parameters)
1082{
1083 if (parameters->timed_wait_active)
1084 {
1085 eel_timed_wait_stop (cancel_activate_callback, parameters);
1086 }
1087
1088 if (parameters->slot_info)
1089 {
1090 g_object_remove_weak_pointer (G_OBJECT (parameters->slot_info)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parameters->slot_info)), (((GType) ((20) << (2)
)))))))
, (gpointer *)&parameters->slot_info);
1091 }
1092 if (parameters->parent_window)
1093 {
1094 g_object_remove_weak_pointer (G_OBJECT (parameters->parent_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parameters->parent_window)), (((GType) ((20) <<
(2))))))))
, (gpointer *)&parameters->parent_window);
1095 }
1096 g_object_unref (parameters->cancellable);
1097 launch_location_list_free (parameters->locations);
1098 baul_file_list_free (parameters->mountables);
1099 baul_file_list_free (parameters->start_mountables);
1100 baul_file_list_free (parameters->not_mounted);
1101 g_free (parameters->activation_directory);
1102 g_free (parameters->timed_wait_prompt);
1103 g_assert (parameters->files_handle == NULL)do { if (parameters->files_handle == ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-mime-actions.c", 1103, ((const char*) (
__func__)), "parameters->files_handle == NULL"); } while (
0)
;
1104 g_free (parameters);
1105}
1106
1107static void
1108cancel_activate_callback (gpointer callback_data)
1109{
1110 ActivateParameters *parameters = callback_data;
1111
1112 parameters->timed_wait_active = FALSE(0);
1113
1114 g_cancellable_cancel (parameters->cancellable);
1115
1116 if (parameters->files_handle)
1117 {
1118 baul_file_list_cancel_call_when_ready (parameters->files_handle);
1119 parameters->files_handle = NULL((void*)0);
1120 activation_parameters_free (parameters);
1121 }
1122}
1123
1124static void
1125activation_start_timed_cancel (ActivateParameters *parameters)
1126{
1127 parameters->timed_wait_active = TRUE(!(0));
1128 eel_timed_wait_start_with_duration
1129 (DELAY_UNTIL_CANCEL_MSECS5000,
1130 cancel_activate_callback,
1131 parameters,
1132 parameters->timed_wait_prompt,
1133 parameters->parent_window);
1134}
1135
1136static void
1137pause_activation_timed_cancel (ActivateParameters *parameters)
1138{
1139 if (parameters->timed_wait_active)
1140 {
1141 eel_timed_wait_stop (cancel_activate_callback, parameters);
1142 parameters->timed_wait_active = FALSE(0);
1143 }
1144}
1145
1146static void
1147unpause_activation_timed_cancel (ActivateParameters *parameters)
1148{
1149 if (!parameters->timed_wait_active)
1150 {
1151 activation_start_timed_cancel (parameters);
1152 }
1153}
1154
1155
1156static void
1157activate_mount_op_active (CtkMountOperation *operation,
1158 GParamSpec *pspec,
1159 ActivateParameters *parameters)
1160{
1161 gboolean is_active;
1162
1163 g_object_get (operation, "is-showing", &is_active, NULL((void*)0));
1164
1165 if (is_active)
1166 {
1167 pause_activation_timed_cancel (parameters);
1168 }
1169 else
1170 {
1171 unpause_activation_timed_cancel (parameters);
1172 }
1173}
1174
1175static gboolean
1176confirm_multiple_windows (CtkWindow *parent_window,
1177 int count,
1178 gboolean use_tabs)
1179{
1180 CtkDialog *dialog;
1181 char *prompt;
1182 char *detail;
1183 int response;
1184
1185 if (count <= SILENT_WINDOW_OPEN_LIMIT5)
1186 {
1187 return TRUE(!(0));
1188 }
1189
1190 prompt = _("Are you sure you want to open all files?")gettext ("Are you sure you want to open all files?");
1191 if (use_tabs)
1192 {
1193 detail = g_strdup_printf (ngettext("This will open %d separate tab.",
1194 "This will open %d separate tabs.", count), count);
1195 }
1196 else
1197 {
1198 detail = g_strdup_printf (ngettext("This will open %d separate window.",
1199 "This will open %d separate windows.", count), count);
1200 }
1201 dialog = eel_show_yes_no_dialog (prompt, detail,
1202 "ctk-ok", "process-stop",
1203 parent_window);
1204 g_free (detail);
1205
1206 response = ctk_dialog_run (dialog);
1207 ctk_widget_destroy (CTK_WIDGET (dialog)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_widget_get_type ()))))))
);
1208
1209 return response == CTK_RESPONSE_YES;
1210}
1211
1212typedef struct
1213{
1214 BaulWindowSlotInfo *slot_info;
1215 CtkWindow *parent_window;
1216 BaulFile *file;
1217 GList *files;
1218 BaulWindowOpenMode mode;
1219 BaulWindowOpenFlags flags;
1220 char *activation_directory;
1221 gboolean user_confirmation;
1222 char *uri;
1223 GDBusProxy *proxy;
1224 CtkWidget *dialog;
1225} ActivateParametersInstall;
1226
1227static void
1228activate_parameters_install_free (ActivateParametersInstall *parameters_install)
1229{
1230 if (parameters_install->slot_info)
1231 {
1232 g_object_remove_weak_pointer (G_OBJECT (parameters_install->slot_info)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parameters_install->slot_info)), (((GType) ((20) <<
(2))))))))
, (gpointer *)&parameters_install->slot_info);
1233 }
1234 if (parameters_install->parent_window)
1235 {
1236 g_object_remove_weak_pointer (G_OBJECT (parameters_install->parent_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parameters_install->parent_window)), (((GType) ((20) <<
(2))))))))
, (gpointer *)&parameters_install->parent_window);
1237 }
1238
1239 if (parameters_install->proxy != NULL((void*)0))
1240 {
1241 g_object_unref (parameters_install->proxy);
1242 }
1243
1244 baul_file_unref (parameters_install->file);
1245 baul_file_list_free (parameters_install->files);
1246 g_free (parameters_install->activation_directory);
1247 g_free (parameters_install->uri);
1248 g_free (parameters_install);
1249}
1250
1251static char *
1252get_application_no_mime_type_handler_message (BaulFile *file, char *uri)
1253{
1254 char *uri_for_display;
1255 char *nice_uri;
1256 char *error_message;
1257
1258 /* For local files, we want to use filename if possible */
1259 if (baul_file_is_local (file))
1260 {
1261 GFile *location;
1262
1263 location = baul_file_get_location (file);
1264 nice_uri = g_file_get_parse_name (location);
1265 g_object_unref (location);
1266 }
1267 else
1268 {
1269 nice_uri = g_strdup (uri)g_strdup_inline (uri);
1270 }
1271
1272 /* Truncate the URI so it doesn't get insanely wide. Note that even
1273 * though the dialog uses wrapped text, if the URI doesn't contain
1274 * white space then the text-wrapping code is too stupid to wrap it.
1275 */
1276 uri_for_display = eel_str_middle_truncate (nice_uri, MAX_URI_IN_DIALOG_LENGTH60);
1277 error_message = g_strdup_printf (_("Could not display \"%s\".")gettext ("Could not display \"%s\"."), uri_for_display);
1278 g_free (nice_uri);
1279 g_free (uri_for_display);
1280 return error_message;
1281}
1282
1283static void
1284application_selected_cb (BaulOpenWithDialog *dialog,
1285 GAppInfo *app,
1286 gpointer user_data)
1287{
1288 CtkWindow *parent_window;
1289 BaulFile *file;
1290 GList files;
1291
1292 parent_window = CTK_WINDOW (user_data)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), ((ctk_window_get_type ()))))))
;
1293
1294 file = g_object_get_data (G_OBJECT (dialog)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), (((GType) ((20) << (2))))))))
, "mime-action:file");
1295
1296 files.next = NULL((void*)0);
1297 files.prev = NULL((void*)0);
1298 files.data = file;
1299 baul_launch_application (app, &files, parent_window);
1300}
1301
1302static void
1303choose_program (CtkDialog *message_dialog, int response, gpointer callback_data)
1304{
1305 CtkWidget *dialog;
1306 char *uri;
1307 char *mime_type;
1308 BaulFile *file;
1309
1310 if (response != CTK_RESPONSE_ACCEPT)
1311 {
1312 ctk_widget_destroy (CTK_WIDGET (message_dialog)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((message_dialog)), ((ctk_widget_get_type ()))))))
);
1313 return;
1314 }
1315
1316 file = g_object_get_data (G_OBJECT (message_dialog)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((message_dialog)), (((GType) ((20) << (2))))))))
, "mime-action:file");
1317
1318 g_assert (BAUL_IS_FILE (file))do { if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((file)); GType __t = (baul_file_get_type()); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) ; else
g_assertion_message_expr (((gchar*) 0), "baul-mime-actions.c"
, 1318, ((const char*) (__func__)), "BAUL_IS_FILE (file)"); }
while (0)
;
1319
1320 baul_file_ref (file);
1321 uri = baul_file_get_uri (file);
1322 mime_type = baul_file_get_mime_type (file);
1323
1324 dialog = baul_open_with_dialog_new (uri, mime_type, NULL((void*)0));
1325 g_object_set_data_full (G_OBJECT (dialog)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), (((GType) ((20) << (2))))))))
,
1326 "mime-action:file",
1327 baul_file_ref (file),
1328 (GDestroyNotify)baul_file_unref);
1329
1330 ctk_window_set_screen (CTK_WINDOW (dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
,
1331 ctk_widget_get_screen (CTK_WIDGET (callback_data)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((callback_data)), ((ctk_widget_get_type ()))))))
));
1332
1333 /* Destroy the message dialog after ref:ing the file */
1334 ctk_widget_destroy (CTK_WIDGET (message_dialog)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((message_dialog)), ((ctk_widget_get_type ()))))))
);
1335
1336 ctk_widget_show (dialog);
1337
1338 g_signal_connect_object (dialog,
1339 "application_selected",
1340 G_CALLBACK (application_selected_cb)((GCallback) (application_selected_cb)),
1341 callback_data,
1342 0);
1343
1344 g_free (uri);
1345 g_free (mime_type);
1346 baul_file_unref (file);
1347}
1348
1349static void
1350show_unhandled_type_error (ActivateParametersInstall *parameters)
1351{
1352 CtkWidget *dialog;
1353
1354 char *mime_type = baul_file_get_mime_type (parameters->file);
1355 char *error_message = get_application_no_mime_type_handler_message (parameters->file, parameters->uri);
1356 if (g_content_type_is_unknown (mime_type)) {
1357 dialog = ctk_message_dialog_new (parameters->parent_window,
1358 CTK_DIALOG_DESTROY_WITH_PARENT,
1359 CTK_MESSAGE_ERROR,
1360 0,
1361 NULL((void*)0));
1362 g_object_set (dialog,
1363 "text", error_message,
1364 "secondary-text", _("The file is of an unknown type")gettext ("The file is of an unknown type"),
1365 NULL((void*)0));
1366 } else {
1367 char *text;
1368 text = g_strdup_printf (_("There is no application installed for %s files")gettext ("There is no application installed for %s files"), g_content_type_get_description (mime_type));
1369
1370 dialog = ctk_message_dialog_new (parameters->parent_window,
1371 CTK_DIALOG_DESTROY_WITH_PARENT,
1372 CTK_MESSAGE_ERROR,
1373 0,
1374 NULL((void*)0));
1375 g_object_set (dialog,
1376 "text", error_message,
1377 "secondary-text", text,
1378 NULL((void*)0));
1379
1380 g_free (text);
1381 }
1382
1383 ctk_dialog_add_button (CTK_DIALOG (dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_dialog_get_type ()))))))
, _("_Select Application")gettext ("_Select Application"), CTK_RESPONSE_ACCEPT);
1384
1385 eel_dialog_add_button (CTK_DIALOG (dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_dialog_get_type ()))))))
,
1386 _("_OK")gettext ("_OK"),
1387 "ctk-ok",
1388 CTK_RESPONSE_OK);
1389
1390 ctk_dialog_set_default_response (CTK_DIALOG (dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_dialog_get_type ()))))))
, CTK_RESPONSE_OK);
1391
1392 g_object_set_data_full (G_OBJECT (dialog)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), (((GType) ((20) << (2))))))))
,
1393 "mime-action:file",
1394 baul_file_ref (parameters->file),
1395 (GDestroyNotify)baul_file_unref);
1396
1397 ctk_widget_show (CTK_WIDGET (dialog)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_widget_get_type ()))))))
);
1398
1399 g_signal_connect (dialog, "response",g_signal_connect_data ((dialog), ("response"), (((GCallback) (
choose_program))), (parameters->parent_window), ((void*)0)
, (GConnectFlags) 0)
1400 G_CALLBACK (choose_program), parameters->parent_window)g_signal_connect_data ((dialog), ("response"), (((GCallback) (
choose_program))), (parameters->parent_window), ((void*)0)
, (GConnectFlags) 0)
;
1401
1402 g_free (error_message);
1403 g_free (mime_type);
1404}
1405
1406static void
1407search_for_application_dbus_call_notify_cb (GDBusProxy *proxy,
1408 GAsyncResult *result,
1409 gpointer user_data)
1410{
1411 ActivateParametersInstall *parameters_install = user_data;
1412 GVariant *variant;
1413 GError *error = NULL((void*)0);
1414
1415 variant = g_dbus_proxy_call_finish (proxy, result, &error);
1416 if (variant == NULL((void*)0))
1417 {
1418 if (!g_dbus_error_is_remote_error (error) ||
1419 g_strcmp0 (g_dbus_error_get_remote_error (error), "org.freedesktop.PackageKit.Modify.Failed") == 0)
1420 {
1421 char *message;
1422
1423 message = g_strdup_printf ("%s\n%s",
1424 _("There was an internal error trying to search for applications:")gettext ("There was an internal error trying to search for applications:"
)
,
1425 error->message);
1426 eel_show_error_dialog (_("Unable to search for application")gettext ("Unable to search for application"), message,
1427 parameters_install->parent_window);
1428 g_free (message);
1429 }
1430
1431 g_error_free (error);
1432 activate_parameters_install_free (parameters_install);
1433 return;
1434 }
1435
1436 g_variant_unref (variant);
1437
1438 /* activate the file again */
1439 baul_mime_activate_files (parameters_install->parent_window,
1440 parameters_install->slot_info,
1441 parameters_install->files,
1442 parameters_install->activation_directory,
1443 parameters_install->mode,
1444 parameters_install->flags,
1445 parameters_install->user_confirmation);
1446
1447 activate_parameters_install_free (parameters_install);
1448}
1449
1450static void
1451search_for_application_mime_type (ActivateParametersInstall *parameters_install, const gchar *mime_type)
1452{
1453 CdkWindow *window;
1454 guint xid = 0;
1455 const char *mime_types[2];
1456
1457 g_assert (parameters_install->proxy != NULL)do { if (parameters_install->proxy != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-mime-actions.c", 1457, ((const char*) (
__func__)), "parameters_install->proxy != NULL"); } while (
0)
;
1458
1459 /* get XID from parent window */
1460 window = ctk_widget_get_window (CTK_WIDGET (parameters_install->parent_window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parameters_install->parent_window)), ((ctk_widget_get_type
()))))))
);
1461 if (window != NULL((void*)0))
1462 {
1463 xid = CDK_WINDOW_XID (window)(cdk_x11_window_get_xid (window));
1464 }
1465
1466 mime_types[0] = mime_type;
1467 mime_types[1] = NULL((void*)0);
1468
1469 g_dbus_proxy_call (parameters_install->proxy,
1470 "InstallMimeTypes",
1471 g_variant_new ("(u^ass)",
1472 xid,
1473 mime_types,
1474 "hide-confirm-search"),
1475 G_DBUS_CALL_FLAGS_NONE,
1476 G_MAXINT2147483647 /* no timeout */,
1477 NULL((void*)0) /* cancellable */,
1478 (GAsyncReadyCallback) search_for_application_dbus_call_notify_cb,
1479 parameters_install);
1480
1481 baul_debug_log (FALSE(0), BAUL_DEBUG_LOG_DOMAIN_USER"USER",
1482 "InstallMimeType method invoked for %s", mime_type);
1483}
1484
1485static void
1486application_unhandled_file_install (CtkDialog *dialog,
1487 gint response_id,
1488 ActivateParametersInstall *parameters_install)
1489{
1490 ctk_widget_destroy (CTK_WIDGET (dialog)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_widget_get_type ()))))))
);
1491 parameters_install->dialog = NULL((void*)0);
1492
1493 if (response_id == CTK_RESPONSE_YES)
1494 {
1495 char *mime_type;
1496
1497 mime_type = baul_file_get_mime_type (parameters_install->file);
1498 search_for_application_mime_type (parameters_install, mime_type);
1499 g_free (mime_type);
1500 }
1501 else
1502 {
1503 /* free as we're not going to get the async dbus callback */
1504 activate_parameters_install_free (parameters_install);
1505 }
1506}
1507
1508static gboolean
1509delete_cb (CtkDialog *dialog)
1510{
1511 ctk_dialog_response (dialog, CTK_RESPONSE_DELETE_EVENT);
1512 return TRUE(!(0));
1513}
1514
1515static void
1516pk_proxy_appeared_cb (GObject *source,
1517 GAsyncResult *res,
1518 gpointer user_data)
1519{
1520 ActivateParametersInstall *parameters_install = user_data;
1521 char *mime_type;
1522 char *error_message;
1523 CtkWidget *dialog;
1524 GDBusProxy *proxy;
1525 GError *error = NULL((void*)0);
1526
1527 proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
1528
1529 if (error != NULL((void*)0))
1530 {
1531 g_warning ("Couldn't call Modify on the PackageKit interface: %s",
1532 error->message);
1533 g_error_free (error);
1534
1535 /* show an unhelpful dialog */
1536 show_unhandled_type_error (parameters_install);
1537 /* The callback wasn't started, so we have to free the parameters */
1538 activate_parameters_install_free (parameters_install);
1539
1540 return;
1541 }
1542
1543 mime_type = baul_file_get_mime_type (parameters_install->file);
1544 error_message = get_application_no_mime_type_handler_message (parameters_install->file,
1545 parameters_install->uri);
1546 /* use a custom dialog to prompt the user to install new software */
1547 dialog = ctk_message_dialog_new (parameters_install->parent_window, 0,
1548 CTK_MESSAGE_ERROR,
1549 CTK_BUTTONS_YES_NO,
1550 "%s", error_message);
1551 ctk_message_dialog_format_secondary_text (CTK_MESSAGE_DIALOG (dialog)((((CtkMessageDialog*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((dialog)), ((ctk_message_dialog_get_type ())
)))))
,
1552 _("There is no application installed for %s files.\n"gettext ("There is no application installed for %s files.\n" "Do you want to search for an application to open this file?"
)
1553 "Do you want to search for an application to open this file?")gettext ("There is no application installed for %s files.\n" "Do you want to search for an application to open this file?"
)
,
1554 g_content_type_get_description (mime_type));
1555 ctk_window_set_resizable (CTK_WINDOW (dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
, FALSE(0));
1556
1557 parameters_install->dialog = dialog;
1558 parameters_install->proxy = proxy;
1559
1560 g_signal_connect (dialog, "response",g_signal_connect_data ((dialog), ("response"), (((GCallback) (
application_unhandled_file_install))), (parameters_install), (
(void*)0), (GConnectFlags) 0)
1561 G_CALLBACK (application_unhandled_file_install),g_signal_connect_data ((dialog), ("response"), (((GCallback) (
application_unhandled_file_install))), (parameters_install), (
(void*)0), (GConnectFlags) 0)
1562 parameters_install)g_signal_connect_data ((dialog), ("response"), (((GCallback) (
application_unhandled_file_install))), (parameters_install), (
(void*)0), (GConnectFlags) 0)
;
1563 g_signal_connect (dialog, "delete-event",g_signal_connect_data ((dialog), ("delete-event"), (((GCallback
) (delete_cb))), (((void*)0)), ((void*)0), (GConnectFlags) 0)
1564 G_CALLBACK (delete_cb), NULL)g_signal_connect_data ((dialog), ("delete-event"), (((GCallback
) (delete_cb))), (((void*)0)), ((void*)0), (GConnectFlags) 0)
;
1565 ctk_widget_show_all (dialog);
1566 g_free (mime_type);
1567}
1568
1569static void
1570application_unhandled_uri (ActivateParameters *parameters, char *uri)
1571{
1572 gboolean show_install_mime;
1573 char *mime_type;
1574 BaulFile *file;
1575 ActivateParametersInstall *parameters_install;
1576
1577 file = baul_file_get_by_uri (uri);
1578
1579 mime_type = baul_file_get_mime_type (file);
1580
1581 /* copy the parts of parameters we are interested in as the orignal will be unref'd */
1582 parameters_install = g_new0 (ActivateParametersInstall, 1)((ActivateParametersInstall *) g_malloc0_n ((1), sizeof (ActivateParametersInstall
)))
;
1583 parameters_install->slot_info = parameters->slot_info;
1584 g_object_add_weak_pointer (G_OBJECT (parameters_install->slot_info)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parameters_install->slot_info)), (((GType) ((20) <<
(2))))))))
, (gpointer *)&parameters_install->slot_info);
1585 if (parameters->parent_window)
1586 {
1587 parameters_install->parent_window = parameters->parent_window;
1588 g_object_add_weak_pointer (G_OBJECT (parameters_install->parent_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parameters_install->parent_window)), (((GType) ((20) <<
(2))))))))
, (gpointer *)&parameters_install->parent_window);
1589 }
1590 parameters_install->activation_directory = g_strdup (parameters->activation_directory)g_strdup_inline (parameters->activation_directory);
1591 parameters_install->file = file;
1592 parameters_install->files = get_file_list_for_launch_locations (parameters->locations);
1593 parameters_install->mode = parameters->mode;
1594 parameters_install->flags = parameters->flags;
1595 parameters_install->user_confirmation = parameters->user_confirmation;
1596 parameters_install->uri = g_strdup(uri)g_strdup_inline (uri);
1597
1598#ifdef ENABLE_PACKAGEKIT1
1599 /* allow an admin to disable the PackageKit search functionality */
1600 show_install_mime = g_settings_get_boolean (baul_preferences, BAUL_PREFERENCES_INSTALL_MIME_ACTIVATION"install-mime-activation");
1601#else
1602 /* we have no install functionality */
1603 show_install_mime = FALSE(0);
1604#endif
1605 /* There is no use trying to look for handlers of application/octet-stream */
1606 if (g_content_type_is_unknown (mime_type))
1607 {
1608 show_install_mime = FALSE(0);
Value stored to 'show_install_mime' is never read
1609 goto out;
1610 }
1611
1612 if (!show_install_mime)
1613 {
1614 goto out;
1615 }
1616
1617 g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
1618 G_DBUS_PROXY_FLAGS_NONE,
1619 NULL((void*)0),
1620 "org.freedesktop.PackageKit",
1621 "/org/freedesktop/PackageKit",
1622 "org.freedesktop.PackageKit.Modify",
1623 NULL((void*)0),
1624 pk_proxy_appeared_cb,
1625 parameters_install);
1626
1627 return;
1628
1629out:
1630 /* show an unhelpful dialog */
1631 show_unhandled_type_error (parameters_install);
1632 /* The callback wasn't started, so we have to free the parameters */
1633 activate_parameters_install_free (parameters_install);
1634
1635 g_free (mime_type);
1636}
1637
1638typedef struct
1639{
1640 CtkWindow *parent_window;
1641 BaulFile *file;
1642} ActivateParametersDesktop;
1643
1644static void
1645activate_parameters_desktop_free (ActivateParametersDesktop *parameters_desktop)
1646{
1647 if (parameters_desktop->parent_window)
1648 {
1649 g_object_remove_weak_pointer (G_OBJECT (parameters_desktop->parent_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parameters_desktop->parent_window)), (((GType) ((20) <<
(2))))))))
, (gpointer *)&parameters_desktop->parent_window);
1650 }
1651 baul_file_unref (parameters_desktop->file);
1652 g_free (parameters_desktop);
1653}
1654
1655static void
1656untrusted_launcher_response_callback (CtkDialog *dialog,
1657 int response_id,
1658 ActivateParametersDesktop *parameters)
1659{
1660 CdkScreen *screen;
1661 char *uri;
1662 GFile *file;
1663
1664 switch (response_id)
1665 {
1666 case RESPONSE_RUN1000:
1667 screen = ctk_widget_get_screen (CTK_WIDGET (parameters->parent_window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parameters->parent_window)), ((ctk_widget_get_type ()
))))))
);
1668 uri = baul_file_get_uri (parameters->file);
1669 baul_debug_log (FALSE(0), BAUL_DEBUG_LOG_DOMAIN_USER"USER",
1670 "directory view activate_callback launch_desktop_file window=%p: %s",
1671 parameters->parent_window, uri);
1672 baul_launch_desktop_file (screen, uri, NULL((void*)0),
1673 parameters->parent_window);
1674 g_free (uri);
1675 break;
1676 case RESPONSE_MARK_TRUSTED1003:
1677 file = baul_file_get_location (parameters->file);
1678 baul_file_mark_desktop_file_trusted (file,
1679 parameters->parent_window,
1680 TRUE(!(0)),
1681 NULL((void*)0), NULL((void*)0));
1682 g_object_unref (file);
1683 break;
1684 default:
1685 /* Just destroy dialog */
1686 break;
1687 }
1688
1689 ctk_widget_destroy (CTK_WIDGET (dialog)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_widget_get_type ()))))))
);
1690 activate_parameters_desktop_free (parameters);
1691}
1692
1693static void
1694activate_desktop_file (ActivateParameters *parameters,
1695 BaulFile *file)
1696{
1697 ActivateParametersDesktop *parameters_desktop;
1698 CdkScreen *screen;
1699 char *uri;
1700
1701 screen = ctk_widget_get_screen (CTK_WIDGET (parameters->parent_window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parameters->parent_window)), ((ctk_widget_get_type ()
))))))
);
1702
1703 if (!baul_file_is_trusted_link (file))
1704 {
1705 char *primary, *secondary, *display_name;
1706 CtkWidget *dialog;
1707
1708 /* copy the parts of parameters we are interested in as the orignal will be freed */
1709 parameters_desktop = g_new0 (ActivateParametersDesktop, 1)((ActivateParametersDesktop *) g_malloc0_n ((1), sizeof (ActivateParametersDesktop
)))
;
1710 if (parameters->parent_window)
1711 {
1712 parameters_desktop->parent_window = parameters->parent_window;
1713 g_object_add_weak_pointer (G_OBJECT (parameters_desktop->parent_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parameters_desktop->parent_window)), (((GType) ((20) <<
(2))))))))
, (gpointer *)&parameters_desktop->parent_window);
1714 }
1715 parameters_desktop->file = baul_file_ref (file);
1716
1717 primary = _("Untrusted application launcher")gettext ("Untrusted application launcher");
1718 display_name = baul_file_get_display_name (file);
1719 secondary =
1720 g_strdup_printf (_("The application launcher \"%s\" has not been marked as trusted. "gettext ("The application launcher \"%s\" has not been marked as trusted. "
"If you do not know the source of this file, launching it may be unsafe."
)
1721 "If you do not know the source of this file, launching it may be unsafe."gettext ("The application launcher \"%s\" has not been marked as trusted. "
"If you do not know the source of this file, launching it may be unsafe."
)
1722 )gettext ("The application launcher \"%s\" has not been marked as trusted. "
"If you do not know the source of this file, launching it may be unsafe."
)
,
1723 display_name);
1724
1725 dialog = ctk_message_dialog_new (parameters->parent_window,
1726 0,
1727 CTK_MESSAGE_WARNING,
1728 CTK_BUTTONS_NONE,
1729 NULL((void*)0));
1730 g_object_set (dialog,
1731 "text", primary,
1732 "secondary-text", secondary,
1733 NULL((void*)0));
1734 ctk_dialog_add_button (CTK_DIALOG (dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_dialog_get_type ()))))))
,
1735 _("_Launch Anyway")gettext ("_Launch Anyway"), RESPONSE_RUN1000);
1736 if (baul_file_can_set_permissions (file))
1737 {
1738 ctk_dialog_add_button (CTK_DIALOG (dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_dialog_get_type ()))))))
,
1739 _("Mark as _Trusted")gettext ("Mark as _Trusted"), RESPONSE_MARK_TRUSTED1003);
1740 }
1741
1742 eel_dialog_add_button (CTK_DIALOG (dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_dialog_get_type ()))))))
,
1743 _("_Cancel")gettext ("_Cancel"),
1744 "process-stop",
1745 CTK_RESPONSE_CANCEL);
1746
1747 ctk_dialog_set_default_response (CTK_DIALOG (dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_dialog_get_type ()))))))
, CTK_RESPONSE_CANCEL);
1748
1749 g_signal_connect (dialog, "response",g_signal_connect_data ((dialog), ("response"), (((GCallback) (
untrusted_launcher_response_callback))), (parameters_desktop)
, ((void*)0), (GConnectFlags) 0)
1750 G_CALLBACK (untrusted_launcher_response_callback),g_signal_connect_data ((dialog), ("response"), (((GCallback) (
untrusted_launcher_response_callback))), (parameters_desktop)
, ((void*)0), (GConnectFlags) 0)
1751 parameters_desktop)g_signal_connect_data ((dialog), ("response"), (((GCallback) (
untrusted_launcher_response_callback))), (parameters_desktop)
, ((void*)0), (GConnectFlags) 0)
;
1752 ctk_widget_show (dialog);
1753
1754 g_free (display_name);
1755 g_free (secondary);
1756 return;
1757 }
1758
1759 uri = baul_file_get_uri (file);
1760 baul_debug_log (FALSE(0), BAUL_DEBUG_LOG_DOMAIN_USER"USER",
1761 "directory view activate_callback launch_desktop_file window=%p: %s",
1762 parameters->parent_window, uri);
1763 baul_launch_desktop_file (screen, uri, NULL((void*)0),
1764 parameters->parent_window);
1765 g_free (uri);
1766}
1767
1768static void
1769activate_files (ActivateParameters *parameters)
1770{
1771 BaulWindowInfo *window_info;
1772 BaulWindowOpenFlags flags;
1773 BaulFile *file;
1774 GList *launch_desktop_files;
1775 GList *launch_files;
1776 GList *launch_in_terminal_files;
1777 GList *open_in_app_uris;
1778 GList *open_in_app_parameters;
1779 GList *unhandled_open_in_app_uris;
1780 GList *open_in_view_files;
1781 GList *l;
1782 int count;
1783 char *uri;
1784 char *executable_path, *quoted_path, *name;
1785 char *old_working_dir;
1786 ActivationAction action;
1787 CdkScreen *screen;
1788 LaunchLocation *location;
1789 ApplicationLaunchParameters *one_parameters = NULL((void*)0);
1790
1791 screen = ctk_widget_get_screen (CTK_WIDGET (parameters->parent_window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parameters->parent_window)), ((ctk_widget_get_type ()
))))))
);
1792
1793 launch_desktop_files = NULL((void*)0);
1794 launch_files = NULL((void*)0);
1795 launch_in_terminal_files = NULL((void*)0);
1796 open_in_app_uris = NULL((void*)0);
1797 open_in_view_files = NULL((void*)0);
1798
1799 for (l = parameters->locations; l != NULL((void*)0); l = l->next)
1800 {
1801 location = l->data;
1802 file = location->file;
1803
1804 if (file_was_cancelled (file))
1805 {
1806 continue;
1807 }
1808
1809 action = get_activation_action (file);
1810 if (action == ACTIVATION_ACTION_ASK)
1811 {
1812 /* Special case for executable text files, since it might be
1813 * dangerous & unexpected to launch these.
1814 */
1815 pause_activation_timed_cancel (parameters);
1816 action = get_executable_text_file_action (parameters->parent_window, file);
1817 unpause_activation_timed_cancel (parameters);
1818 }
1819
1820 switch (action)
1821 {
1822 case ACTIVATION_ACTION_LAUNCH_DESKTOP_FILE :
1823 launch_desktop_files = g_list_prepend (launch_desktop_files, file);
1824 break;
1825 case ACTIVATION_ACTION_LAUNCH :
1826 launch_files = g_list_prepend (launch_files, file);
1827 break;
1828 case ACTIVATION_ACTION_LAUNCH_IN_TERMINAL :
1829 launch_in_terminal_files = g_list_prepend (launch_in_terminal_files, file);
1830 break;
1831 case ACTIVATION_ACTION_OPEN_IN_VIEW :
1832 open_in_view_files = g_list_prepend (open_in_view_files, file);
1833 break;
1834 case ACTIVATION_ACTION_OPEN_IN_APPLICATION :
1835 open_in_app_uris = g_list_prepend (open_in_app_uris, location->uri);
1836 break;
1837 case ACTIVATION_ACTION_DO_NOTHING :
1838 break;
1839 case ACTIVATION_ACTION_ASK :
1840 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "baul-mime-actions.c"
, 1840, ((const char*) (__func__)), ((void*)0)); } while (0)
;
1841 break;
1842 }
1843 }
1844
1845 launch_desktop_files = g_list_reverse (launch_desktop_files);
1846 for (l = launch_desktop_files; l != NULL((void*)0); l = l->next)
1847 {
1848 file = BAUL_FILE (l->data)((((BaulFile*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((l->data)), (baul_file_get_type())))))
;
1849
1850 activate_desktop_file (parameters, file);
1851 }
1852
1853 old_working_dir = NULL((void*)0);
1854 if (parameters->activation_directory &&
1855 (launch_files != NULL((void*)0) || launch_in_terminal_files != NULL((void*)0)))
1856 {
1857 old_working_dir = g_get_current_dir ();
1858 g_chdir (parameters->activation_directory);
1859
1860 }
1861
1862 launch_files = g_list_reverse (launch_files);
1863 for (l = launch_files; l != NULL((void*)0); l = l->next)
1864 {
1865 file = BAUL_FILE (l->data)((((BaulFile*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((l->data)), (baul_file_get_type())))))
;
1866
1867 uri = baul_file_get_activation_uri (file);
1868 executable_path = g_filename_from_uri (uri, NULL((void*)0), NULL((void*)0));
1869 quoted_path = g_shell_quote (executable_path);
1870 name = baul_file_get_name (file);
1871
1872 baul_debug_log (FALSE(0), BAUL_DEBUG_LOG_DOMAIN_USER"USER",
1873 "directory view activate_callback launch_file window=%p: %s",
1874 parameters->parent_window, quoted_path);
1875
1876 baul_launch_application_from_command (screen, name, quoted_path, FALSE(0), NULL((void*)0));
1877 g_free (name);
1878 g_free (quoted_path);
1879 g_free (executable_path);
1880 g_free (uri);
1881
1882 }
1883
1884 launch_in_terminal_files = g_list_reverse (launch_in_terminal_files);
1885 for (l = launch_in_terminal_files; l != NULL((void*)0); l = l->next)
1886 {
1887 file = BAUL_FILE (l->data)((((BaulFile*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((l->data)), (baul_file_get_type())))))
;
1888
1889 uri = baul_file_get_activation_uri (file);
1890 executable_path = g_filename_from_uri (uri, NULL((void*)0), NULL((void*)0));
1891 quoted_path = g_shell_quote (executable_path);
1892 name = baul_file_get_name (file);
1893
1894 baul_debug_log (FALSE(0), BAUL_DEBUG_LOG_DOMAIN_USER"USER",
1895 "directory view activate_callback launch_in_terminal window=%p: %s",
1896 parameters->parent_window, quoted_path);
1897
1898 baul_launch_application_from_command (screen, name, quoted_path, TRUE(!(0)), NULL((void*)0));
1899 g_free (name);
1900 g_free (quoted_path);
1901 g_free (executable_path);
1902 g_free (uri);
1903 }
1904
1905 if (old_working_dir != NULL((void*)0))
1906 {
1907 g_chdir (old_working_dir);
1908 g_free (old_working_dir);
1909 }
1910
1911 open_in_view_files = g_list_reverse (open_in_view_files);
1912 count = g_list_length (open_in_view_files);
1913
1914 flags = parameters->flags;
1915 if (count > 1)
1916 {
1917 if ((parameters->flags & BAUL_WINDOW_OPEN_FLAG_NEW_WINDOW) == 0)
1918 {
1919 flags |= BAUL_WINDOW_OPEN_FLAG_NEW_TAB;
1920 }
1921 else
1922 {
1923 flags |= BAUL_WINDOW_OPEN_FLAG_NEW_WINDOW;
1924 }
1925 }
1926
1927 if (parameters->slot_info != NULL((void*)0) &&
1928 (!parameters->user_confirmation ||
1929 confirm_multiple_windows (parameters->parent_window, count,
1930 (flags & BAUL_WINDOW_OPEN_FLAG_NEW_TAB) != 0)))
1931 {
1932
1933 if ((flags & BAUL_WINDOW_OPEN_FLAG_NEW_TAB) != 0 &&
1934 g_settings_get_enum (baul_preferences, BAUL_PREFERENCES_NEW_TAB_POSITION"tabs-open-position") ==
1935 BAUL_NEW_TAB_POSITION_AFTER_CURRENT_TAB)
1936 {
1937 /* When inserting N tabs after the current one,
1938 * we first open tab N, then tab N-1, ..., then tab 0.
1939 * Each of them is appended to the current tab, i.e.
1940 * prepended to the list of tabs to open.
1941 */
1942 open_in_view_files = g_list_reverse (open_in_view_files);
1943 }
1944
1945
1946 for (l = open_in_view_files; l != NULL((void*)0); l = l->next)
1947 {
1948 GFile *f;
1949 /* The ui should ask for navigation or object windows
1950 * depending on what the current one is */
1951 file = BAUL_FILE (l->data)((((BaulFile*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((l->data)), (baul_file_get_type())))))
;
1952
1953 uri = baul_file_get_activation_uri (file);
1954 f = g_file_new_for_uri (uri);
1955 baul_window_slot_info_open_location (parameters->slot_info,baul_window_slot_info_open_location_full(parameters->slot_info
, f, parameters->mode, flags, ((void*)0), ((void*)0), ((void
*)0))
1956 f, parameters->mode, flags, NULL)baul_window_slot_info_open_location_full(parameters->slot_info
, f, parameters->mode, flags, ((void*)0), ((void*)0), ((void
*)0))
;
1957 g_object_unref (f);
1958 g_free (uri);
1959 }
1960 }
1961
1962 open_in_app_parameters = NULL((void*)0);
1963 unhandled_open_in_app_uris = NULL((void*)0);
1964
1965 if (open_in_app_uris != NULL((void*)0))
1966 {
1967 open_in_app_uris = g_list_reverse (open_in_app_uris);
1968
1969 open_in_app_parameters = make_activation_parameters
1970 (open_in_app_uris, &unhandled_open_in_app_uris);
1971 }
1972
1973 for (l = open_in_app_parameters; l != NULL((void*)0); l = l->next)
1974 {
1975 one_parameters = l->data;
1976
1977 baul_launch_application_by_uri (one_parameters->application,
1978 one_parameters->uris,
1979 parameters->parent_window);
1980 application_launch_parameters_free (one_parameters);
1981 }
1982
1983 for (l = unhandled_open_in_app_uris; l != NULL((void*)0); l = l->next)
1984 {
1985 uri = l->data;
1986
1987 /* this does not block */
1988 application_unhandled_uri (parameters, uri);
1989 }
1990
1991 window_info = NULL((void*)0);
1992 if (parameters->slot_info != NULL((void*)0))
1993 {
1994 window_info = baul_window_slot_info_get_window (parameters->slot_info);
1995 }
1996
1997 if (open_in_app_parameters != NULL((void*)0) ||
1998 unhandled_open_in_app_uris != NULL((void*)0))
1999 {
2000 if ((parameters->flags & BAUL_WINDOW_OPEN_FLAG_CLOSE_BEHIND) != 0 &&
2001 window_info != NULL((void*)0) &&
2002 baul_window_info_get_window_type (window_info) == BAUL_WINDOW_SPATIAL)
2003 {
2004 baul_window_info_close (window_info);
2005 }
2006 }
2007
2008 g_list_free (launch_desktop_files);
2009 g_list_free (launch_files);
2010 g_list_free (launch_in_terminal_files);
2011 g_list_free (open_in_view_files);
2012 g_list_free (open_in_app_uris);
2013 g_list_free (open_in_app_parameters);
2014 g_list_free (unhandled_open_in_app_uris);
2015
2016 activation_parameters_free (parameters);
2017}
2018
2019static void
2020activation_mount_not_mounted_callback (GObject *source_object,
2021 GAsyncResult *res,
2022 gpointer user_data)
2023{
2024 ActivateParameters *parameters = user_data;
2025 GError *error;
2026 BaulFile *file;
2027
2028 file = parameters->not_mounted->data;
2029
2030 error = NULL((void*)0);
2031 if (!g_file_mount_enclosing_volume_finish (G_FILE (source_object)((((GFile*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((source_object)), ((g_file_get_type ()))))))
, res, &error))
2032 {
2033 if (error->domain != G_IO_ERRORg_io_error_quark() ||
2034 (error->code != G_IO_ERROR_CANCELLED &&
2035 error->code != G_IO_ERROR_FAILED_HANDLED &&
2036 error->code != G_IO_ERROR_ALREADY_MOUNTED))
2037 {
2038 eel_show_error_dialog (_("Unable to mount location")gettext ("Unable to mount location"),
2039 error->message, parameters->parent_window);
2040 }
2041
2042 if (error->domain != G_IO_ERRORg_io_error_quark() ||
2043 error->code != G_IO_ERROR_ALREADY_MOUNTED)
2044 {
2045 LaunchLocation *loc;
2046
2047 loc = find_launch_location_for_file (parameters->locations,
2048 file);
2049 if (loc)
2050 {
2051 parameters->locations =
2052 g_list_remove (parameters->locations, loc);
2053 launch_location_free (loc);
2054 }
2055 }
2056
2057 g_error_free (error);
2058 }
2059
2060 parameters->not_mounted = g_list_delete_link (parameters->not_mounted,
2061 parameters->not_mounted);
2062 baul_file_unref (file);
2063
2064 activation_mount_not_mounted (parameters);
2065}
2066
2067static void
2068activation_mount_not_mounted (ActivateParameters *parameters)
2069{
2070 LaunchLocation *loc = NULL((void*)0);
2071 GList *l, *next, *files;
2072
2073 if (parameters->not_mounted != NULL((void*)0))
2074 {
2075 BaulFile *file;
2076 GFile *location;
2077 GMountOperation *mount_op;
2078
2079 file = parameters->not_mounted->data;
2080 mount_op = ctk_mount_operation_new (parameters->parent_window);
2081 g_mount_operation_set_password_save (mount_op, G_PASSWORD_SAVE_FOR_SESSION);
2082 g_signal_connect (mount_op, "notify::is-showing",g_signal_connect_data ((mount_op), ("notify::is-showing"), ((
(GCallback) (activate_mount_op_active))), (parameters), ((void
*)0), (GConnectFlags) 0)
2083 G_CALLBACK (activate_mount_op_active), parameters)g_signal_connect_data ((mount_op), ("notify::is-showing"), ((
(GCallback) (activate_mount_op_active))), (parameters), ((void
*)0), (GConnectFlags) 0)
;
2084 location = baul_file_get_location (file);
2085 g_file_mount_enclosing_volume (location, 0, mount_op, parameters->cancellable,
2086 activation_mount_not_mounted_callback, parameters);
2087 g_object_unref (location);
2088 /* unref mount_op here - g_file_mount_enclosing_volume() does ref for itself */
2089 g_object_unref (mount_op);
2090 return;
2091 }
2092
2093 parameters->tried_mounting = TRUE(!(0));
2094
2095 if (parameters->locations == NULL((void*)0))
2096 {
2097 activation_parameters_free (parameters);
2098 return;
2099 }
2100
2101 /* once the mount is finished, refresh all attributes */
2102 /* - fixes new windows not appearing after successful mount */
2103 for (l = parameters->locations; l != NULL((void*)0); l = next)
2104 {
2105 loc = l->data;
2106 next = l->next;
2107 baul_file_invalidate_all_attributes (loc->file);
2108 }
2109
2110 files = get_file_list_for_launch_locations (parameters->locations);
2111 baul_file_list_call_when_ready
2112 (files,
2113 baul_mime_actions_get_required_file_attributes () | BAUL_FILE_ATTRIBUTE_LINK_INFO,
2114 &parameters->files_handle,
2115 activate_callback, parameters);
2116 baul_file_list_free (files);
2117}
2118
2119
2120static void
2121activate_callback (GList *files, gpointer callback_data)
2122{
2123 ActivateParameters *parameters = callback_data;
2124 GList *l, *next;
2125 LaunchLocation *location;
2126 BaulFile *file = NULL((void*)0);
2127
2128 parameters->files_handle = NULL((void*)0);
2129
2130 for (l = parameters->locations; l != NULL((void*)0); l = next)
2131 {
2132 location = l->data;
2133 file = location->file;
2134 next = l->next;
2135
2136 if (file_was_cancelled (file))
2137 {
2138 launch_location_free (location);
2139 parameters->locations = g_list_delete_link (parameters->locations, l);
2140 continue;
2141 }
2142
2143 if (file_was_not_mounted (file))
2144 {
2145 if (parameters->tried_mounting)
2146 {
2147 launch_location_free (location);
2148 parameters->locations = g_list_delete_link (parameters->locations, l);
2149 }
2150 else
2151 {
2152 parameters->not_mounted = g_list_prepend (parameters->not_mounted,
2153 baul_file_ref (file));
2154 }
2155 continue;
2156 }
2157 }
2158
2159
2160 if (parameters->not_mounted != NULL((void*)0))
2161 {
2162 activation_mount_not_mounted (parameters);
2163 }
2164 else
2165 {
2166 activate_files (parameters);
2167 }
2168}
2169
2170static void
2171activate_activation_uris_ready_callback (GList *files_ignore,
2172 gpointer callback_data)
2173{
2174 ActivateParameters *parameters = callback_data;
2175 GList *l, *next, *files;
2176 LaunchLocation *location;
2177 BaulFile *file = NULL((void*)0);
2178
2179 parameters->files_handle = NULL((void*)0);
2180
2181 for (l = parameters->locations; l != NULL((void*)0); l = next)
2182 {
2183 location = l->data;
2184 file = location->file;
2185 next = l->next;
2186
2187 if (file_was_cancelled (file))
2188 {
2189 launch_location_free (location);
2190 parameters->locations = g_list_delete_link (parameters->locations, l);
2191 continue;
2192 }
2193
2194 if (baul_file_is_broken_symbolic_link (file))
2195 {
2196 launch_location_free (location);
2197 parameters->locations = g_list_delete_link (parameters->locations, l);
2198 pause_activation_timed_cancel (parameters);
2199 report_broken_symbolic_link (parameters->parent_window, file);
2200 unpause_activation_timed_cancel (parameters);
2201 continue;
2202 }
2203
2204 if (baul_file_get_file_type (file) == G_FILE_TYPE_MOUNTABLE &&
2205 !baul_file_has_activation_uri (file))
2206 {
2207 /* Don't launch these... There is nothing we
2208 can do */
2209 launch_location_free (location);
2210 parameters->locations = g_list_delete_link (parameters->locations, l);
2211 continue;
2212 }
2213
2214 }
2215
2216 if (parameters->locations == NULL((void*)0))
2217 {
2218 activation_parameters_free (parameters);
2219 return;
2220 }
2221
2222 /* Convert the files to the actual activation uri files */
2223 for (l = parameters->locations; l != NULL((void*)0); l = l->next)
2224 {
2225 char *uri;
2226 location = l->data;
2227
2228 /* We want the file for the activation URI since we care
2229 * about the attributes for that, not for the original file.
2230 */
2231 uri = baul_file_get_activation_uri (location->file);
2232 if (uri != NULL((void*)0))
2233 {
2234 launch_location_update_from_uri (location, uri);
2235 }
2236 g_free (uri);
2237 }
2238
2239
2240 /* get the parameters for the actual files */
2241 files = get_file_list_for_launch_locations (parameters->locations);
2242 baul_file_list_call_when_ready
2243 (files,
2244 baul_mime_actions_get_required_file_attributes () | BAUL_FILE_ATTRIBUTE_LINK_INFO,
2245 &parameters->files_handle,
2246 activate_callback, parameters);
2247 baul_file_list_free (files);
2248}
2249
2250static void
2251activation_get_activation_uris (ActivateParameters *parameters)
2252{
2253 GList *l, *files;
2254 LaunchLocation *location;
2255 BaulFile *file = NULL((void*)0);
2256
2257 /* link target info might be stale, re-read it */
2258 for (l = parameters->locations; l != NULL((void*)0); l = l->next)
2259 {
2260 location = l->data;
2261 file = location->file;
2262
2263 if (file_was_cancelled (file))
2264 {
2265 launch_location_free (location);
2266 parameters->locations = g_list_delete_link (parameters->locations, l);
2267 continue;
2268 }
2269
2270 if (baul_file_is_symbolic_link (file))
2271 {
2272 baul_file_invalidate_attributes
2273 (file,
2274 BAUL_FILE_ATTRIBUTE_INFO |
2275 BAUL_FILE_ATTRIBUTE_LINK_INFO);
2276 }
2277 }
2278
2279 if (parameters->locations == NULL((void*)0))
2280 {
2281 activation_parameters_free (parameters);
2282 return;
2283 }
2284
2285 files = get_file_list_for_launch_locations (parameters->locations);
2286 baul_file_list_call_when_ready
2287 (files,
2288 BAUL_FILE_ATTRIBUTE_INFO |
2289 BAUL_FILE_ATTRIBUTE_LINK_INFO,
2290 &parameters->files_handle,
2291 activate_activation_uris_ready_callback, parameters);
2292 baul_file_list_free (files);
2293}
2294
2295static void
2296activation_mountable_mounted (BaulFile *file,
2297 GFile *result_location,
2298 GError *error,
2299 gpointer callback_data)
2300{
2301 ActivateParameters *parameters = callback_data;
2302 LaunchLocation *location;
2303
2304 /* Remove from list of files that have to be mounted */
2305 parameters->mountables = g_list_remove (parameters->mountables, file);
2306 baul_file_unref (file);
2307
2308
2309 if (error == NULL((void*)0))
2310 {
2311 BaulFile *target_file;
2312
2313 /* Replace file with the result of the mount */
2314 target_file = baul_file_get (result_location);
2315
2316 location = find_launch_location_for_file (parameters->locations,
2317 file);
2318 if (location)
2319 {
2320 launch_location_update_from_file (location, target_file);
2321 }
2322 baul_file_unref (target_file);
2323 }
2324 else
2325 {
2326 /* Remove failed file */
2327
2328 if (error->domain != G_IO_ERRORg_io_error_quark() ||
2329 (error->code != G_IO_ERROR_FAILED_HANDLED &&
2330 error->code != G_IO_ERROR_ALREADY_MOUNTED))
2331 {
2332 location = find_launch_location_for_file (parameters->locations,
2333 file);
2334 if (location)
2335 {
2336 parameters->locations =
2337 g_list_remove (parameters->locations,
2338 location);
2339 launch_location_free (location);
2340 }
2341 }
2342
2343 if (error->domain != G_IO_ERRORg_io_error_quark() ||
2344 (error->code != G_IO_ERROR_CANCELLED &&
2345 error->code != G_IO_ERROR_FAILED_HANDLED &&
2346 error->code != G_IO_ERROR_ALREADY_MOUNTED))
2347 {
2348 eel_show_error_dialog (_("Unable to mount location")gettext ("Unable to mount location"),
2349 error->message, parameters->parent_window);
2350 }
2351
2352 if (error->code == G_IO_ERROR_CANCELLED)
2353 {
2354 activation_parameters_free (parameters);
2355 return;
2356 }
2357 }
2358
2359 /* Mount more mountables */
2360 activation_mount_mountables (parameters);
2361}
2362
2363
2364static void
2365activation_mount_mountables (ActivateParameters *parameters)
2366{
2367 if (parameters->mountables != NULL((void*)0))
2368 {
2369 BaulFile *file;
2370 GMountOperation *mount_op;
2371
2372 file = parameters->mountables->data;
2373 mount_op = ctk_mount_operation_new (parameters->parent_window);
2374 g_mount_operation_set_password_save (mount_op, G_PASSWORD_SAVE_FOR_SESSION);
2375 g_signal_connect (mount_op, "notify::is-showing",g_signal_connect_data ((mount_op), ("notify::is-showing"), ((
(GCallback) (activate_mount_op_active))), (parameters), ((void
*)0), (GConnectFlags) 0)
2376 G_CALLBACK (activate_mount_op_active), parameters)g_signal_connect_data ((mount_op), ("notify::is-showing"), ((
(GCallback) (activate_mount_op_active))), (parameters), ((void
*)0), (GConnectFlags) 0)
;
2377 baul_file_mount (file,
2378 mount_op,
2379 parameters->cancellable,
2380 activation_mountable_mounted,
2381 parameters);
2382 g_object_unref (mount_op);
2383 return;
2384 }
2385
2386 if (parameters->mountables == NULL((void*)0) && parameters->start_mountables == NULL((void*)0))
2387 activation_get_activation_uris (parameters);
2388}
2389
2390
2391static void
2392activation_mountable_started (BaulFile *file,
2393 GFile *gfile_of_file,
2394 GError *error,
2395 gpointer callback_data)
2396{
2397 ActivateParameters *parameters = callback_data;
2398 LaunchLocation *location;
2399
2400 /* Remove from list of files that have to be mounted */
2401 parameters->start_mountables = g_list_remove (parameters->start_mountables, file);
2402 baul_file_unref (file);
2403
2404 if (error == NULL((void*)0))
2405 {
2406 /* Remove file */
2407 location = find_launch_location_for_file (parameters->locations, file);
2408 if (location != NULL((void*)0))
2409 {
2410 parameters->locations = g_list_remove (parameters->locations, location);
2411 launch_location_free (location);
2412 }
2413
2414 }
2415 else
2416 {
2417 /* Remove failed file */
2418 if (error->domain != G_IO_ERRORg_io_error_quark() ||
2419 (error->code != G_IO_ERROR_FAILED_HANDLED))
2420 {
2421 location = find_launch_location_for_file (parameters->locations,
2422 file);
2423 if (location)
2424 {
2425 parameters->locations =
2426 g_list_remove (parameters->locations,
2427 location);
2428 launch_location_free (location);
2429 }
2430 }
2431
2432 if (error->domain != G_IO_ERRORg_io_error_quark() ||
2433 (error->code != G_IO_ERROR_CANCELLED &&
2434 error->code != G_IO_ERROR_FAILED_HANDLED))
2435 {
2436 eel_show_error_dialog (_("Unable to start location")gettext ("Unable to start location"),
2437 error->message, NULL((void*)0));
2438 }
2439
2440 if (error->code == G_IO_ERROR_CANCELLED)
2441 {
2442 activation_parameters_free (parameters);
2443 return;
2444 }
2445 }
2446
2447 /* Start more mountables */
2448 activation_start_mountables (parameters);
2449}
2450
2451static void
2452activation_start_mountables (ActivateParameters *parameters)
2453{
2454 if (parameters->start_mountables != NULL((void*)0))
2455 {
2456 BaulFile *file;
2457 GMountOperation *start_op;
2458
2459 file = parameters->start_mountables->data;
2460 start_op = ctk_mount_operation_new (parameters->parent_window);
2461 g_signal_connect (start_op, "notify::is-showing",g_signal_connect_data ((start_op), ("notify::is-showing"), ((
(GCallback) (activate_mount_op_active))), (parameters), ((void
*)0), (GConnectFlags) 0)
2462 G_CALLBACK (activate_mount_op_active), parameters)g_signal_connect_data ((start_op), ("notify::is-showing"), ((
(GCallback) (activate_mount_op_active))), (parameters), ((void
*)0), (GConnectFlags) 0)
;
2463 baul_file_start (file,
2464 start_op,
2465 parameters->cancellable,
2466 activation_mountable_started,
2467 parameters);
2468 g_object_unref (start_op);
2469 return;
2470 }
2471
2472 if (parameters->mountables == NULL((void*)0) && parameters->start_mountables == NULL((void*)0))
2473 activation_get_activation_uris (parameters);
2474}
2475
2476/**
2477 * baul_mime_activate_files:
2478 *
2479 * Activate a list of files. Each one might launch with an application or
2480 * with a component. This is normally called only by subclasses.
2481 * @view: FMDirectoryView in question.
2482 * @files: A GList of BaulFiles to activate.
2483 *
2484 **/
2485void
2486baul_mime_activate_files (CtkWindow *parent_window,
2487 BaulWindowSlotInfo *slot_info,
2488 GList *files,
2489 const char *launch_directory,
2490 BaulWindowOpenMode mode,
2491 BaulWindowOpenFlags flags,
2492 gboolean user_confirmation)
2493{
2494 ActivateParameters *parameters;
2495 int file_count;
2496 GList *l, *next;
2497 LaunchLocation *location;
2498 BaulFile *file = NULL((void*)0);
2499
2500 if (files == NULL((void*)0))
2501 {
2502 return;
2503 }
2504
2505 baul_debug_log_with_file_list (FALSE(0), BAUL_DEBUG_LOG_DOMAIN_USER"USER", files,
2506 "baul_mime_activate_files window=%p",
2507 parent_window);
2508
2509 parameters = g_new0 (ActivateParameters, 1)((ActivateParameters *) g_malloc0_n ((1), sizeof (ActivateParameters
)))
;
2510 parameters->slot_info = slot_info;
2511 g_object_add_weak_pointer (G_OBJECT (parameters->slot_info)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parameters->slot_info)), (((GType) ((20) << (2)
)))))))
, (gpointer *)&parameters->slot_info);
2512 if (parent_window)
2513 {
2514 parameters->parent_window = parent_window;
2515 g_object_add_weak_pointer (G_OBJECT (parameters->parent_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parameters->parent_window)), (((GType) ((20) <<
(2))))))))
, (gpointer *)&parameters->parent_window);
2516 }
2517 parameters->cancellable = g_cancellable_new ();
2518 parameters->activation_directory = g_strdup (launch_directory)g_strdup_inline (launch_directory);
2519 parameters->locations = launch_locations_from_file_list (files);
2520 parameters->mode = mode;
2521 parameters->flags = flags;
2522 parameters->user_confirmation = user_confirmation;
2523
2524 file_count = g_list_length (files);
2525 if (file_count == 1)
2526 {
2527 char *file_name;
2528
2529 file_name = baul_file_get_display_name (files->data);
2530 parameters->timed_wait_prompt = g_strdup_printf (_("Opening \"%s\".")gettext ("Opening \"%s\"."), file_name);
2531 g_free (file_name);
2532 }
2533 else
2534 {
2535 parameters->timed_wait_prompt = g_strdup_printf (ngettext ("Opening %d item.",
2536 "Opening %d items.",
2537 file_count),
2538 file_count);
2539 }
2540
2541
2542 for (l = parameters->locations; l != NULL((void*)0); l = next)
2543 {
2544 location = l->data;
2545 file = location->file;
2546 next = l->next;
2547
2548 if (baul_file_can_mount (file))
2549 {
2550 parameters->mountables = g_list_prepend (parameters->mountables,
2551 baul_file_ref (file));
2552 }
2553
2554 if (baul_file_can_start (file))
2555 {
2556 parameters->start_mountables = g_list_prepend (parameters->start_mountables,
2557 baul_file_ref (file));
2558 }
2559 }
2560
2561 activation_start_timed_cancel (parameters);
2562 if (parameters->mountables != NULL((void*)0))
2563 activation_mount_mountables (parameters);
2564 if (parameters->start_mountables != NULL((void*)0))
2565 activation_start_mountables (parameters);
2566 if (parameters->mountables == NULL((void*)0) && parameters->start_mountables == NULL((void*)0))
2567 activation_get_activation_uris (parameters);
2568}
2569
2570/**
2571 * baul_mime_activate_file:
2572 *
2573 * Activate a file in this view. This might involve switching the displayed
2574 * location for the current window, or launching an application.
2575 * @view: FMDirectoryView in question.
2576 * @file: A BaulFile representing the file in this view to activate.
2577 * @use_new_window: Should this item be opened in a new window?
2578 *
2579 **/
2580
2581void
2582baul_mime_activate_file (CtkWindow *parent_window,
2583 BaulWindowSlotInfo *slot_info,
2584 BaulFile *file,
2585 const char *launch_directory,
2586 BaulWindowOpenMode mode,
2587 BaulWindowOpenFlags flags)
2588{
2589 GList *files;
2590
2591 g_return_if_fail (BAUL_IS_FILE (file))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((file)); GType __t = (baul_file_get_type()); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "BAUL_IS_FILE (file)"); return; } } while (0)
;
2592
2593 files = g_list_prepend (NULL((void*)0), file);
2594 baul_mime_activate_files (parent_window, slot_info, files, launch_directory, mode, flags, FALSE(0));
2595 g_list_free (files);
2596}