1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 
3 /*
4    caja-mime-application-chooser.c: an mime-application chooser
5 
6    Copyright (C) 2004 Novell, Inc.
7    Copyright (C) 2007 Red Hat, Inc.
8 
9    The Mate Library is free software; you can redistribute it and/or
10    modify it under the terms of the GNU Library General Public License as
11    published by the Free Software Foundation; either version 2 of the
12    License, or (at your option) any later version.
13 
14    The Mate Library is distributed in the hope that it will be useful,
15    but APPLICATIONOUT ANY WARRANTY; applicationout even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    Library General Public License for more details.
18 
19    You should have received a copy of the GNU Library General Public
20    License along application the Mate Library; see the file COPYING.LIB.  If not,
21    write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22    Boston, MA 02110-1301, USA.
23 
24    Authors: Dave Camp <dave@novell.com>
25             Alexander Larsson <alexl@redhat.com>
26 */
27 
28 #include <config.h>
29 #include <string.h>
30 
31 #include <glib/gi18n-lib.h>
32 #include <gdk-pixbuf/gdk-pixbuf.h>
33 #include <gtk/gtk.h>
34 #include <gio/gio.h>
35 
36 #include <eel/eel-stock-dialogs.h>
37 
38 #include "caja-mime-application-chooser.h"
39 #include "caja-open-with-dialog.h"
40 #include "caja-signaller.h"
41 #include "caja-file.h"
42 
43 struct _CajaMimeApplicationChooserDetails
44 {
45     char *uri;
46 
47     char *content_type;
48     char *extension;
49     char *type_description;
50     char *orig_mime_type;
51 
52     guint refresh_timeout;
53 
54     GtkWidget *label;
55     GtkWidget *entry;
56     GtkWidget *treeview;
57     GtkWidget *remove_button;
58 
59     gboolean for_multiple_files;
60 
61     GtkListStore *model;
62     GtkCellRenderer *toggle_renderer;
63 };
64 
65 enum
66 {
67     COLUMN_APPINFO,
68     COLUMN_DEFAULT,
69     COLUMN_ICON,
70     COLUMN_NAME,
71     NUM_COLUMNS
72 };
73 
74 G_DEFINE_TYPE (CajaMimeApplicationChooser, caja_mime_application_chooser, GTK_TYPE_BOX);
75 
76 static void refresh_model             (CajaMimeApplicationChooser *chooser);
77 static void refresh_model_soon        (CajaMimeApplicationChooser *chooser);
78 static void mime_type_data_changed_cb (GObject                        *signaller,
79                                        gpointer                        user_data);
80 
81 static void
caja_mime_application_chooser_finalize(GObject * object)82 caja_mime_application_chooser_finalize (GObject *object)
83 {
84     CajaMimeApplicationChooser *chooser;
85 
86     chooser = CAJA_MIME_APPLICATION_CHOOSER (object);
87 
88     if (chooser->details->refresh_timeout)
89     {
90         g_source_remove (chooser->details->refresh_timeout);
91     }
92 
93     g_signal_handlers_disconnect_by_func (caja_signaller_get_current (),
94                                           G_CALLBACK (mime_type_data_changed_cb),
95                                           chooser);
96 
97 
98     g_free (chooser->details->uri);
99     g_free (chooser->details->content_type);
100     g_free (chooser->details->extension);
101     g_free (chooser->details->type_description);
102     g_free (chooser->details->orig_mime_type);
103 
104     g_free (chooser->details);
105 
106     G_OBJECT_CLASS (caja_mime_application_chooser_parent_class)->finalize (object);
107 }
108 
109 static void
caja_mime_application_chooser_class_init(CajaMimeApplicationChooserClass * class)110 caja_mime_application_chooser_class_init (CajaMimeApplicationChooserClass *class)
111 {
112     GObjectClass *gobject_class;
113 
114     gobject_class = G_OBJECT_CLASS (class);
115     gobject_class->finalize = caja_mime_application_chooser_finalize;
116 }
117 
118 static void
default_toggled_cb(GtkCellRendererToggle * renderer,const char * path_str,gpointer user_data)119 default_toggled_cb (GtkCellRendererToggle *renderer,
120                     const char *path_str,
121                     gpointer user_data)
122 {
123     CajaMimeApplicationChooser *chooser;
124     GtkTreeIter iter;
125     GtkTreePath *path;
126     GError *error;
127 
128     chooser = CAJA_MIME_APPLICATION_CHOOSER (user_data);
129 
130     path = gtk_tree_path_new_from_string (path_str);
131     if (gtk_tree_model_get_iter (GTK_TREE_MODEL (chooser->details->model),
132                                  &iter, path))
133     {
134         gboolean is_default;
135         gboolean success;
136         GAppInfo *info;
137 
138         gtk_tree_model_get (GTK_TREE_MODEL (chooser->details->model),
139                             &iter,
140                             COLUMN_DEFAULT, &is_default,
141                             COLUMN_APPINFO, &info,
142                             -1);
143 
144         if (!is_default && info != NULL)
145         {
146             error = NULL;
147             if (chooser->details->extension)
148             {
149                 success = g_app_info_set_as_default_for_extension (info,
150                           chooser->details->extension,
151                           &error);
152             }
153             else
154             {
155                 success = g_app_info_set_as_default_for_type (info,
156                           chooser->details->content_type,
157                           &error);
158             }
159 
160             if (!success)
161             {
162                 char *message;
163 
164                 message = g_strdup_printf (_("Could not set application as the default: %s"), error->message);
165                 eel_show_error_dialog (_("Could not set as default application"),
166                                        message,
167                                        GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (chooser))));
168                 g_free (message);
169                 g_error_free (error);
170             }
171 
172             g_signal_emit_by_name (caja_signaller_get_current (),
173                                    "mime_data_changed");
174         }
175         g_object_unref (info);
176     }
177     gtk_tree_path_free (path);
178 }
179 
180 static GAppInfo *
get_selected_application(CajaMimeApplicationChooser * chooser)181 get_selected_application (CajaMimeApplicationChooser *chooser)
182 {
183     GtkTreeIter iter;
184     GtkTreeSelection *selection;
185     GAppInfo *info;
186 
187     selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (chooser->details->treeview));
188 
189     info = NULL;
190     if (gtk_tree_selection_get_selected (selection,
191                                          NULL,
192                                          &iter))
193     {
194         gtk_tree_model_get (GTK_TREE_MODEL (chooser->details->model),
195                             &iter,
196                             COLUMN_APPINFO, &info,
197                             -1);
198     }
199 
200     return info;
201 }
202 
203 static void
selection_changed_cb(GtkTreeSelection * selection,gpointer user_data)204 selection_changed_cb (GtkTreeSelection *selection,
205                       gpointer user_data)
206 {
207     CajaMimeApplicationChooser *chooser;
208     GAppInfo *info;
209 
210     chooser = CAJA_MIME_APPLICATION_CHOOSER (user_data);
211 
212     info = get_selected_application (chooser);
213     if (info)
214     {
215         gtk_widget_set_sensitive (chooser->details->remove_button,
216                                   g_app_info_can_remove_supports_type (info));
217 
218         g_object_unref (info);
219     }
220     else
221     {
222         gtk_widget_set_sensitive (chooser->details->remove_button,
223                                   FALSE);
224     }
225 }
226 
227 static GtkWidget *
create_tree_view(CajaMimeApplicationChooser * chooser)228 create_tree_view (CajaMimeApplicationChooser *chooser)
229 {
230     GtkWidget *treeview;
231     GtkListStore *store;
232     GtkTreeViewColumn *column;
233     GtkCellRenderer *renderer;
234     GtkTreeSelection *selection;
235 
236     treeview = gtk_tree_view_new ();
237     gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
238 
239     store = gtk_list_store_new (NUM_COLUMNS,
240                                 G_TYPE_APP_INFO,
241                                 G_TYPE_BOOLEAN,
242                                 G_TYPE_ICON,
243                                 G_TYPE_STRING);
244     gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
245                                           COLUMN_NAME,
246                                           GTK_SORT_ASCENDING);
247     gtk_tree_view_set_model (GTK_TREE_VIEW (treeview),
248                              GTK_TREE_MODEL (store));
249     chooser->details->model = store;
250 
251     renderer = gtk_cell_renderer_toggle_new ();
252     g_signal_connect (renderer, "toggled",
253                       G_CALLBACK (default_toggled_cb),
254                       chooser);
255     gtk_cell_renderer_toggle_set_radio (GTK_CELL_RENDERER_TOGGLE (renderer),
256                                         TRUE);
257 
258     column = gtk_tree_view_column_new_with_attributes (_("Default"),
259              renderer,
260              "active",
261              COLUMN_DEFAULT,
262              NULL);
263     gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
264     chooser->details->toggle_renderer = renderer;
265 
266     renderer = gtk_cell_renderer_pixbuf_new ();
267     g_object_set (renderer, "stock-size", GTK_ICON_SIZE_LARGE_TOOLBAR, NULL);
268     column = gtk_tree_view_column_new_with_attributes (_("Icon"),
269              renderer,
270              "gicon",
271              COLUMN_ICON,
272              NULL);
273     gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
274 
275     renderer = gtk_cell_renderer_text_new ();
276     column = gtk_tree_view_column_new_with_attributes (_("Name"),
277              renderer,
278              "markup",
279              COLUMN_NAME,
280              NULL);
281     gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
282 
283     selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
284     g_signal_connect (selection, "changed",
285                       G_CALLBACK (selection_changed_cb),
286                       chooser);
287 
288     return treeview;
289 }
290 
291 static void
add_clicked_cb(GtkButton * button,gpointer user_data)292 add_clicked_cb (GtkButton *button,
293                 gpointer user_data)
294 {
295     CajaMimeApplicationChooser *chooser;
296     GtkWidget *dialog;
297 
298     chooser = CAJA_MIME_APPLICATION_CHOOSER (user_data);
299 
300     if (chooser->details->for_multiple_files)
301     {
302         dialog = caja_add_application_dialog_new_for_multiple_files (chooser->details->extension,
303                  chooser->details->orig_mime_type);
304     }
305     else
306     {
307         dialog = caja_add_application_dialog_new (chooser->details->uri,
308                  chooser->details->orig_mime_type);
309     }
310     gtk_window_set_screen (GTK_WINDOW (dialog),
311                            gtk_widget_get_screen (GTK_WIDGET (chooser)));
312     gtk_widget_show (dialog);
313 }
314 
315 static void
remove_clicked_cb(GtkButton * button,gpointer user_data)316 remove_clicked_cb (GtkButton *button,
317                    gpointer user_data)
318 {
319     CajaMimeApplicationChooser *chooser;
320     GError *error;
321     GAppInfo *info;
322 
323     chooser = CAJA_MIME_APPLICATION_CHOOSER (user_data);
324 
325     info = get_selected_application (chooser);
326 
327     if (info)
328     {
329         error = NULL;
330         if (!g_app_info_remove_supports_type (info,
331                                               chooser->details->content_type,
332                                               &error))
333         {
334             eel_show_error_dialog (_("Could not remove application"),
335                                    error->message,
336                                    GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (chooser))));
337             g_error_free (error);
338 
339         }
340         g_signal_emit_by_name (caja_signaller_get_current (),
341                                "mime_data_changed");
342         g_object_unref (info);
343     }
344 }
345 
346 static void
reset_clicked_cb(GtkButton * button,gpointer user_data)347 reset_clicked_cb (GtkButton *button,
348                   gpointer   user_data)
349 {
350     CajaMimeApplicationChooser *chooser;
351 
352     chooser = CAJA_MIME_APPLICATION_CHOOSER (user_data);
353 
354     g_app_info_reset_type_associations (chooser->details->content_type);
355 
356     g_signal_emit_by_name (caja_signaller_get_current (),
357                            "mime_data_changed");
358 }
359 
360 static void
mime_type_data_changed_cb(GObject * signaller,gpointer user_data)361 mime_type_data_changed_cb (GObject *signaller,
362                            gpointer user_data)
363 {
364     CajaMimeApplicationChooser *chooser;
365 
366     chooser = CAJA_MIME_APPLICATION_CHOOSER (user_data);
367 
368     refresh_model_soon (chooser);
369 }
370 
371 static void
caja_mime_application_chooser_init(CajaMimeApplicationChooser * chooser)372 caja_mime_application_chooser_init (CajaMimeApplicationChooser *chooser)
373 {
374     GtkWidget *box;
375     GtkWidget *scrolled;
376     GtkWidget *button;
377 
378     chooser->details = g_new0 (CajaMimeApplicationChooserDetails, 1);
379 
380     chooser->details->for_multiple_files = FALSE;
381 
382     gtk_orientable_set_orientation (GTK_ORIENTABLE (chooser), GTK_ORIENTATION_VERTICAL);
383 
384     gtk_container_set_border_width (GTK_CONTAINER (chooser), 8);
385     gtk_box_set_spacing (GTK_BOX (chooser), 0);
386     gtk_box_set_homogeneous (GTK_BOX (chooser), FALSE);
387 
388     chooser->details->label = gtk_label_new ("");
389     gtk_label_set_xalign (GTK_LABEL (chooser->details->label), 0);
390     gtk_label_set_line_wrap (GTK_LABEL (chooser->details->label), TRUE);
391     gtk_label_set_line_wrap_mode (GTK_LABEL (chooser->details->label),
392                                   PANGO_WRAP_WORD_CHAR);
393     gtk_box_pack_start (GTK_BOX (chooser), chooser->details->label,
394                         FALSE, FALSE, 0);
395 
396     gtk_widget_show (chooser->details->label);
397 
398     scrolled = gtk_scrolled_window_new (NULL, NULL);
399 
400     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
401                                     GTK_POLICY_AUTOMATIC,
402                                     GTK_POLICY_AUTOMATIC);
403     gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled),
404                                          GTK_SHADOW_IN);
405     gtk_scrolled_window_set_overlay_scrolling (GTK_SCROLLED_WINDOW (scrolled), FALSE);
406 
407     gtk_widget_show (scrolled);
408     gtk_box_pack_start (GTK_BOX (chooser), scrolled, TRUE, TRUE, 6);
409 
410     chooser->details->treeview = create_tree_view (chooser);
411     gtk_widget_show (chooser->details->treeview);
412 
413     gtk_container_add (GTK_CONTAINER (scrolled),
414                        chooser->details->treeview);
415 
416     box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
417     gtk_box_set_spacing (GTK_BOX (box), 6);
418     gtk_button_box_set_layout (GTK_BUTTON_BOX (box), GTK_BUTTONBOX_END);
419     gtk_box_pack_start (GTK_BOX (chooser), box, FALSE, FALSE, 6);
420     gtk_widget_show (box);
421 
422     button = gtk_button_new_with_mnemonic (_("_Add"));
423     gtk_button_set_image (GTK_BUTTON (button), gtk_image_new_from_icon_name ("list-add", GTK_ICON_SIZE_BUTTON));
424 
425     g_signal_connect (button, "clicked",
426                       G_CALLBACK (add_clicked_cb),
427                       chooser);
428 
429     gtk_widget_show (button);
430     gtk_container_add (GTK_CONTAINER (box), button);
431 
432     button = gtk_button_new_with_mnemonic (_("_Remove"));
433     gtk_button_set_image (GTK_BUTTON (button), gtk_image_new_from_icon_name ("list-remove", GTK_ICON_SIZE_BUTTON));
434 
435     g_signal_connect (button, "clicked",
436                       G_CALLBACK (remove_clicked_cb),
437                       chooser);
438 
439     gtk_widget_show (button);
440     gtk_container_add (GTK_CONTAINER (box), button);
441 
442     chooser->details->remove_button = button;
443 
444     button = gtk_button_new_with_label (_("Reset"));
445     g_signal_connect (button, "clicked",
446                       G_CALLBACK (reset_clicked_cb),
447                       chooser);
448 
449     gtk_widget_show (button);
450     gtk_container_add (GTK_CONTAINER (box), button);
451 
452     g_signal_connect (caja_signaller_get_current (),
453                       "mime_data_changed",
454                       G_CALLBACK (mime_type_data_changed_cb),
455                       chooser);
456 }
457 
458 static char *
get_extension(const char * basename)459 get_extension (const char *basename)
460 {
461     char *p;
462 
463     p = strrchr (basename, '.');
464 
465     if (p && *(p + 1) != '\0')
466     {
467         return g_strdup (p + 1);
468     }
469     else
470     {
471         return NULL;
472     }
473 }
474 
475 static gboolean
refresh_model_timeout(gpointer data)476 refresh_model_timeout (gpointer data)
477 {
478     CajaMimeApplicationChooser *chooser = data;
479 
480     chooser->details->refresh_timeout = 0;
481 
482     refresh_model (chooser);
483 
484     return FALSE;
485 }
486 
487 /* This adds a slight delay so that we're sure the mime data is
488    done writing */
489 static void
refresh_model_soon(CajaMimeApplicationChooser * chooser)490 refresh_model_soon (CajaMimeApplicationChooser *chooser)
491 {
492     if (chooser->details->refresh_timeout != 0)
493         return;
494 
495     chooser->details->refresh_timeout =
496         g_timeout_add (300,
497                        refresh_model_timeout,
498                        chooser);
499 }
500 
501 static void
refresh_model(CajaMimeApplicationChooser * chooser)502 refresh_model (CajaMimeApplicationChooser *chooser)
503 {
504     GList *applications;
505     GAppInfo *default_app;
506     GList *l;
507     GtkTreeSelection *selection;
508     GtkTreeViewColumn *column;
509 
510     column = gtk_tree_view_get_column (GTK_TREE_VIEW (chooser->details->treeview), 0);
511     gtk_tree_view_column_set_visible (column, TRUE);
512 
513     gtk_list_store_clear (chooser->details->model);
514 
515     applications = g_app_info_get_all_for_type (chooser->details->content_type);
516     default_app = g_app_info_get_default_for_type (chooser->details->content_type, FALSE);
517 
518     for (l = applications; l != NULL; l = l->next)
519     {
520         GtkTreeIter iter;
521         gboolean is_default;
522         GAppInfo *application;
523         char *escaped;
524         GIcon *icon;
525 
526         application = l->data;
527 
528         is_default = default_app && g_app_info_equal (default_app, application);
529 
530         escaped = g_markup_escape_text (g_app_info_get_display_name (application), -1);
531 
532         icon = g_app_info_get_icon (application);
533 
534         gtk_list_store_append (chooser->details->model, &iter);
535         gtk_list_store_set (chooser->details->model, &iter,
536                             COLUMN_APPINFO, application,
537                             COLUMN_DEFAULT, is_default,
538                             COLUMN_ICON, icon,
539                             COLUMN_NAME, escaped,
540                             -1);
541 
542         g_free (escaped);
543     }
544 
545     selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (chooser->details->treeview));
546 
547     if (applications)
548     {
549         g_object_set (chooser->details->toggle_renderer,
550                       "visible", TRUE,
551                       NULL);
552         gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
553     }
554     else
555     {
556         GtkTreeIter iter;
557         char *name;
558 
559         gtk_tree_view_column_set_visible (column, FALSE);
560         gtk_list_store_append (chooser->details->model, &iter);
561         name = g_strdup_printf ("<i>%s</i>", _("No applications selected"));
562         gtk_list_store_set (chooser->details->model, &iter,
563                             COLUMN_NAME, name,
564                             COLUMN_APPINFO, NULL,
565                             -1);
566         g_free (name);
567 
568         gtk_tree_selection_set_mode (selection, GTK_SELECTION_NONE);
569     }
570 
571     if (default_app)
572     {
573         g_object_unref (default_app);
574     }
575 
576     g_list_free_full (applications, g_object_unref);
577 }
578 
579 static void
set_extension_and_description(CajaMimeApplicationChooser * chooser,const char * extension,const char * mime_type)580 set_extension_and_description (CajaMimeApplicationChooser *chooser,
581                                const char *extension,
582                                const char *mime_type)
583 {
584     if (extension != NULL &&
585             g_content_type_is_unknown (mime_type))
586     {
587         chooser->details->extension = g_strdup (extension);
588         chooser->details->content_type = g_strdup_printf ("application/x-extension-%s", extension);
589         /* the %s here is a file extension */
590         chooser->details->type_description =
591             g_strdup_printf (_("%s document"), extension);
592     }
593     else
594     {
595         char *description;
596 
597         chooser->details->content_type = g_strdup (mime_type);
598         description = g_content_type_get_description (mime_type);
599         if (description == NULL)
600         {
601             description = g_strdup (_("Unknown"));
602         }
603 
604         chooser->details->type_description = description;
605     }
606 }
607 
608 static gboolean
set_uri_and_type(CajaMimeApplicationChooser * chooser,const char * uri,const char * mime_type)609 set_uri_and_type (CajaMimeApplicationChooser *chooser,
610                   const char *uri,
611                   const char *mime_type)
612 {
613     char *label;
614     char *name;
615     char *emname;
616     char *extension;
617     GFile *file;
618 
619     chooser->details->uri = g_strdup (uri);
620 
621     file = g_file_new_for_uri (uri);
622     name = g_file_get_basename (file);
623     g_object_unref (file);
624 
625     chooser->details->orig_mime_type = g_strdup (mime_type);
626 
627     extension = get_extension (name);
628     set_extension_and_description (CAJA_MIME_APPLICATION_CHOOSER (chooser),
629                                    extension, mime_type);
630     g_free (extension);
631 
632     /* first %s is filename, second %s is mime-type description */
633     emname = g_strdup_printf ("<i>%s</i>", name);
634     label = g_strdup_printf (_("Select an application to open %s and other files of type \"%s\""),
635                              emname, chooser->details->type_description);
636     g_free (emname);
637 
638     gtk_label_set_markup (GTK_LABEL (chooser->details->label), label);
639 
640     g_free (label);
641     g_free (name);
642 
643     refresh_model (chooser);
644 
645     return TRUE;
646 }
647 
648 static char *
get_extension_from_file(CajaFile * nfile)649 get_extension_from_file (CajaFile *nfile)
650 {
651     char *name;
652     char *extension;
653 
654     name = caja_file_get_name (nfile);
655     extension = get_extension (name);
656 
657     g_free (name);
658 
659     return extension;
660 }
661 
662 static gboolean
set_uri_and_type_for_multiple_files(CajaMimeApplicationChooser * chooser,GList * uris,const char * mime_type)663 set_uri_and_type_for_multiple_files (CajaMimeApplicationChooser *chooser,
664                                      GList *uris,
665                                      const char *mime_type)
666 {
667     char *label;
668     char *first_extension;
669     gboolean same_extension;
670     GList *iter;
671 
672     chooser->details->for_multiple_files = TRUE;
673     chooser->details->uri = NULL;
674     chooser->details->orig_mime_type = g_strdup (mime_type);
675     same_extension = TRUE;
676     first_extension = get_extension_from_file (CAJA_FILE (uris->data));
677     iter = uris->next;
678 
679     while (iter != NULL)
680     {
681         char *extension_current;
682 
683         extension_current = get_extension_from_file (CAJA_FILE (iter->data));
684         if (g_strcmp0 (first_extension, extension_current)) {
685             same_extension = FALSE;
686             g_free (extension_current);
687             break;
688         }
689         iter = iter->next;
690 
691         g_free (extension_current);
692     }
693     if (!same_extension)
694     {
695         set_extension_and_description (CAJA_MIME_APPLICATION_CHOOSER (chooser),
696                                        NULL, mime_type);
697     }
698     else
699     {
700         set_extension_and_description (CAJA_MIME_APPLICATION_CHOOSER (chooser),
701                                        first_extension, mime_type);
702     }
703 
704     g_free (first_extension);
705 
706     label = g_strdup_printf (_("Open all files of type \"%s\" with:"),
707                              chooser->details->type_description);
708     gtk_label_set_markup (GTK_LABEL (chooser->details->label), label);
709 
710     g_free (label);
711 
712     refresh_model (chooser);
713 
714     return TRUE;
715 }
716 
717 GtkWidget *
caja_mime_application_chooser_new(const char * uri,const char * mime_type)718 caja_mime_application_chooser_new (const char *uri,
719                                    const char *mime_type)
720 {
721     GtkWidget *chooser;
722 
723     chooser = gtk_widget_new (CAJA_TYPE_MIME_APPLICATION_CHOOSER, NULL);
724 
725     set_uri_and_type (CAJA_MIME_APPLICATION_CHOOSER (chooser), uri, mime_type);
726 
727     return chooser;
728 }
729 
730 GtkWidget *
caja_mime_application_chooser_new_for_multiple_files(GList * uris,const char * mime_type)731 caja_mime_application_chooser_new_for_multiple_files (GList *uris,
732         const char *mime_type)
733 {
734     GtkWidget *chooser;
735 
736     chooser = gtk_widget_new (CAJA_TYPE_MIME_APPLICATION_CHOOSER, NULL);
737 
738     set_uri_and_type_for_multiple_files (CAJA_MIME_APPLICATION_CHOOSER (chooser),
739                                          uris, mime_type);
740 
741     return chooser;
742 }
743 
744