File: | libbaul-private/baul-mime-actions.c |
Warning: | line 1608, column 9 Value stored to 'show_install_mime' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | |
48 | typedef 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 | |
59 | typedef struct |
60 | { |
61 | BaulFile *file; |
62 | char *uri; |
63 | } LaunchLocation; |
64 | |
65 | typedef struct |
66 | { |
67 | GAppInfo *application; |
68 | GList *uris; |
69 | } ApplicationLaunchParameters; |
70 | |
71 | typedef 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 | |
108 | static void cancel_activate_callback (gpointer callback_data); |
109 | static void activate_activation_uris_ready_callback (GList *files, |
110 | gpointer callback_data); |
111 | static void activation_mount_mountables (ActivateParameters *parameters); |
112 | static void activation_start_mountables (ActivateParameters *parameters); |
113 | static void activate_callback (GList *files, |
114 | gpointer callback_data); |
115 | static void activation_mount_not_mounted (ActivateParameters *parameters); |
116 | |
117 | |
118 | static void |
119 | launch_location_free (LaunchLocation *location) |
120 | { |
121 | baul_file_unref (location->file); |
122 | g_free (location->uri); |
123 | g_free (location); |
124 | } |
125 | |
126 | static void |
127 | launch_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 | |
133 | static GList * |
134 | get_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 | |
151 | static LaunchLocation * |
152 | launch_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 | |
162 | static void |
163 | launch_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 | |
172 | static void |
173 | launch_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 | |
182 | static LaunchLocation * |
183 | find_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 | |
201 | static GList * |
202 | launch_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 | |
217 | static ApplicationLaunchParameters * |
218 | application_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 | |
230 | static void |
231 | application_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 | |
239 | static GList* |
240 | filter_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 | |
268 | static GList* |
269 | filter_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 | |
289 | static gboolean |
290 | baul_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 | |
301 | BaulFileAttributes |
302 | baul_mime_actions_get_required_file_attributes (void) |
303 | { |
304 | return BAUL_FILE_ATTRIBUTE_INFO | |
305 | BAUL_FILE_ATTRIBUTE_LINK_INFO; |
306 | } |
307 | |
308 | static gboolean |
309 | file_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 | |
336 | GAppInfo * |
337 | baul_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 | |
366 | static int |
367 | file_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 | |
384 | static int |
385 | file_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 | |
402 | static int |
403 | application_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 | |
410 | static int |
411 | application_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 | |
446 | GList * |
447 | baul_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 | |
485 | gboolean |
486 | baul_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 | |
532 | GAppInfo * |
533 | baul_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 */ |
589 | static GList * |
590 | intersect_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 | |
639 | GList * |
640 | baul_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 | |
686 | static void |
687 | trash_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 | |
709 | static void |
710 | report_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 | |
776 | out: |
777 | g_free (prompt); |
778 | g_free (target_path); |
779 | g_free (detail); |
780 | } |
781 | |
782 | static ActivationAction |
783 | get_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 | |
853 | static ActivationAction |
854 | get_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 | |
872 | gboolean |
873 | baul_mime_file_opens_in_view (BaulFile *file) |
874 | { |
875 | return (baul_file_is_directory (file)); |
876 | } |
877 | |
878 | static ActivationAction |
879 | get_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 | |
930 | gboolean |
931 | baul_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 | |
941 | static unsigned int |
942 | mime_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 | |
956 | static void |
957 | list_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 | **/ |
983 | static GList * |
984 | make_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 | |
1056 | static gboolean |
1057 | file_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 | |
1068 | static gboolean |
1069 | file_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 | |
1080 | static void |
1081 | activation_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 *)¶meters->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 *)¶meters->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 | |
1107 | static void |
1108 | cancel_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 | |
1124 | static void |
1125 | activation_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 | |
1136 | static void |
1137 | pause_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 | |
1146 | static void |
1147 | unpause_activation_timed_cancel (ActivateParameters *parameters) |
1148 | { |
1149 | if (!parameters->timed_wait_active) |
1150 | { |
1151 | activation_start_timed_cancel (parameters); |
1152 | } |
1153 | } |
1154 | |
1155 | |
1156 | static void |
1157 | activate_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 | |
1175 | static gboolean |
1176 | confirm_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 | |
1212 | typedef 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 | |
1227 | static void |
1228 | activate_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 *)¶meters_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 *)¶meters_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 | |
1251 | static char * |
1252 | get_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 | |
1283 | static void |
1284 | application_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 | |
1302 | static void |
1303 | choose_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 | |
1349 | static void |
1350 | show_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 | |
1406 | static void |
1407 | search_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 | |
1450 | static void |
1451 | search_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 | |
1485 | static void |
1486 | application_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 | |
1508 | static gboolean |
1509 | delete_cb (CtkDialog *dialog) |
1510 | { |
1511 | ctk_dialog_response (dialog, CTK_RESPONSE_DELETE_EVENT); |
1512 | return TRUE(!(0)); |
1513 | } |
1514 | |
1515 | static void |
1516 | pk_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 | |
1569 | static void |
1570 | application_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 *)¶meters_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 *)¶meters_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 | |
1629 | out: |
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 | |
1638 | typedef struct |
1639 | { |
1640 | CtkWindow *parent_window; |
1641 | BaulFile *file; |
1642 | } ActivateParametersDesktop; |
1643 | |
1644 | static void |
1645 | activate_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 *)¶meters_desktop->parent_window); |
1650 | } |
1651 | baul_file_unref (parameters_desktop->file); |
1652 | g_free (parameters_desktop); |
1653 | } |
1654 | |
1655 | static void |
1656 | untrusted_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 | |
1693 | static void |
1694 | activate_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 *)¶meters_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 | |
1768 | static void |
1769 | activate_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 | |
2019 | static void |
2020 | activation_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 | |
2067 | static void |
2068 | activation_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 | ¶meters->files_handle, |
2115 | activate_callback, parameters); |
2116 | baul_file_list_free (files); |
2117 | } |
2118 | |
2119 | |
2120 | static void |
2121 | activate_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 | |
2170 | static void |
2171 | activate_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 | ¶meters->files_handle, |
2246 | activate_callback, parameters); |
2247 | baul_file_list_free (files); |
2248 | } |
2249 | |
2250 | static void |
2251 | activation_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 | ¶meters->files_handle, |
2291 | activate_activation_uris_ready_callback, parameters); |
2292 | baul_file_list_free (files); |
2293 | } |
2294 | |
2295 | static void |
2296 | activation_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 | |
2364 | static void |
2365 | activation_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 | |
2391 | static void |
2392 | activation_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 | |
2451 | static void |
2452 | activation_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 | **/ |
2485 | void |
2486 | baul_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 *)¶meters->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 *)¶meters->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 | |
2581 | void |
2582 | baul_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 | } |