1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* gnome-vfs-mime-handlers.c - Mime type handlers for the GNOME Virtual
5 Copyright (C) 2000 Eazel, Inc.
7 The Gnome 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.
12 The Gnome 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.
17 You should have received a copy of the GNU Library General Public
18 License along with the Gnome Library; see the file COPYING.LIB. If not,
19 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
22 Author: Maciej Stachowiak <mjs@eazel.com> */
25 #include "gnome-vfs-mime-handlers.h"
27 #include "gnome-vfs-application-registry.h"
28 #include "gnome-vfs-mime-info.h"
29 #include "gnome-vfs-mime.h"
30 #include "gnome-vfs-result.h"
31 #include "gnome-vfs-private-utils.h"
32 #include "gnome-vfs-utils.h"
33 #include <bonobo-activation/bonobo-activation-activate.h>
34 #include <gconf/gconf-client.h>
38 #define GCONF_DEFAULT_VIEWER_EXEC_PATH "/desktop/gnome/applications/component_viewer/exec"
41 static GnomeVFSResult expand_parameters (gpointer action,
42 GnomeVFSMimeActionType type,
46 static GList * Bonobo_ServerInfoList_to_ServerInfo_g_list (Bonobo_ServerInfoList *info_list);
47 static GList * copy_str_list (GList *string_list);
48 static GList * comma_separated_str_to_str_list (const char *str);
49 static GList * str_list_difference (GList *a,
51 static char * str_list_to_comma_separated_str (GList *list);
52 static void g_list_free_deep (GList *list);
53 static GList * prune_ids_for_nonexistent_applications (GList *list);
54 static GnomeVFSResult gnome_vfs_mime_edit_user_file (const char *mime_type,
57 static gboolean application_known_to_be_nonexistent (const char *application_id);
58 static const char *gnome_vfs_mime_maybe_get_user_level_value (const char *mime_type,
63 * gnome_vfs_mime_get_description:
64 * @mime_type: the mime type
66 * Query the MIME database for a description of the specified MIME type.
68 * Return value: A description of MIME type @mime_type
71 gnome_vfs_mime_get_description (const char *mime_type)
73 return gnome_vfs_mime_get_value (mime_type, "description");
77 * gnome_vfs_mime_set_description:
78 * @mime_type: A const char * containing a mime type
79 * @description: A description of this MIME type
81 * Set the description of this MIME type in the MIME database. The description
82 * should be something like "Gnumeric spreadsheet".
84 * Return value: GnomeVFSResult indicating the success of the operation or any
85 * errors that may have occurred.
88 gnome_vfs_mime_set_description (const char *mime_type, const char *description)
90 return gnome_vfs_mime_edit_user_file
91 (mime_type, "description", description);
95 * gnome_vfs_mime_get_default_action_type:
96 * @mime_type: A const char * containing a mime type, e.g. "application/x-php"
98 * Query the MIME database for the type of action to be performed on a particular MIME type by default.
100 * Return value: The type of action to be performed on a file of
101 * MIME type, @mime_type by default.
103 GnomeVFSMimeActionType
104 gnome_vfs_mime_get_default_action_type (const char *mime_type)
106 const char *action_type_string;
108 action_type_string = gnome_vfs_mime_get_value (mime_type, "default_action_type");
110 if (action_type_string != NULL && g_ascii_strcasecmp (action_type_string, "application") == 0) {
111 return GNOME_VFS_MIME_ACTION_TYPE_APPLICATION;
112 } else if (action_type_string != NULL && g_ascii_strcasecmp (action_type_string, "component") == 0) {
113 return GNOME_VFS_MIME_ACTION_TYPE_COMPONENT;
115 return GNOME_VFS_MIME_ACTION_TYPE_NONE;
121 * gnome_vfs_mime_get_default_action:
122 * @mime_type: A const char * containing a mime type, e.g. "application/x-php"
124 * Query the MIME database for default action associated with a particular MIME type @mime_type.
126 * Return value: A GnomeVFSMimeAction representing the default action to perform upon
127 * file of type @mime_type.
130 gnome_vfs_mime_get_default_action (const char *mime_type)
132 GnomeVFSMimeAction *action;
134 action = g_new0 (GnomeVFSMimeAction, 1);
136 action->action_type = gnome_vfs_mime_get_default_action_type (mime_type);
138 switch (action->action_type) {
139 case GNOME_VFS_MIME_ACTION_TYPE_APPLICATION:
140 action->action.application =
141 gnome_vfs_mime_get_default_application (mime_type);
142 if (action->action.application == NULL) {
147 case GNOME_VFS_MIME_ACTION_TYPE_COMPONENT:
148 action->action.component =
149 gnome_vfs_mime_get_default_component (mime_type);
150 if (action->action.component == NULL) {
155 case GNOME_VFS_MIME_ACTION_TYPE_NONE:
160 g_assert_not_reached ();
167 * gnome_vfs_mime_get_default_application:
168 * @mime_type: A const char * containing a mime type, e.g. "image/png"
170 * Query the MIME database for the application to be executed on files of MIME type
171 * @mime_type by default.
173 * Return value: A GnomeVFSMimeApplication representing the default handler of @mime_type
175 GnomeVFSMimeApplication *
176 gnome_vfs_mime_get_default_application (const char *mime_type)
178 const char *default_application_id;
179 GnomeVFSMimeApplication *default_application;
182 default_application = NULL;
184 /* First, try the default for the mime type */
185 default_application_id = gnome_vfs_mime_get_value
186 (mime_type, "default_application_id");
188 if (default_application_id != NULL
189 && default_application_id[0] != '\0'
190 && !application_known_to_be_nonexistent (default_application_id)) {
191 default_application =
192 gnome_vfs_application_registry_get_mime_application (default_application_id);
195 if (default_application == NULL) {
196 /* Failing that, try something from the short list */
198 short_list = gnome_vfs_mime_get_short_list_applications (mime_type);
200 if (short_list != NULL) {
201 default_application = gnome_vfs_mime_application_copy
202 ((GnomeVFSMimeApplication *) (short_list->data));
203 gnome_vfs_mime_application_list_free (short_list);
208 return default_application;
212 * gnome_vfs_mime_get_icon:
213 * @mime_type: A const char * containing a MIME type
215 * Query the MIME database for an icon representing the specified MIME type.
217 * Return value: The filename of the icon as listed in the MIME database. This is
218 * usually a filename without path information, e.g. "i-chardev.png", and sometimes
219 * does not have an extension, e.g. "i-regular" if the icon is supposed to be image
220 * type agnostic between icon themes. Icons are generic, and not theme specific. These
221 * will not necessarily match with the icons a user sees in Nautilus, you have been warned.
224 gnome_vfs_mime_get_icon (const char *mime_type)
226 return gnome_vfs_mime_get_value (mime_type, "icon_filename");
230 * gnome_vfs_mime_set_icon:
231 * @mime_type: A const char * containing a MIME type
232 * @filename: a const char * containing an image filename
234 * Set the icon entry for a particular MIME type in the MIME database. Note that
235 * icon entries need not necessarily contain the full path, and do not necessarily need to
236 * specify an extension. So "i-regular", "my-special-icon.png", and "some-icon"
237 * are all valid icon filenames.
239 * Return value: A GnomeVFSResult indicating the success of the operation
240 * or any errors that may have occurred.
243 gnome_vfs_mime_set_icon (const char *mime_type, const char *filename)
245 return gnome_vfs_mime_edit_user_file
246 (mime_type, "icon_filename", filename);
251 * gnome_vfs_mime_can_be_executable:
252 * @mime_type: A const char * containing a mime type
254 * Check whether files of this MIME type might conceivably be executable.
255 * Default for known types if FALSE. Default for unknown types is TRUE.
257 * Return value: gboolean containing TRUE if some files of this MIME type
258 * are registered as being executable, and false otherwise.
261 gnome_vfs_mime_can_be_executable (const char *mime_type)
263 const char *result_as_string;
266 result_as_string = gnome_vfs_mime_get_value (mime_type, "can_be_executable");
267 if (result_as_string != NULL) {
268 result = strcmp (result_as_string, "TRUE") == 0;
270 /* If type is not known, we treat it as potentially executable.
271 * If type is known, we use default value of not executable.
273 result = !gnome_vfs_mime_type_is_known (mime_type);
280 * gnome_vfs_mime_set_can_be_executable:
281 * @mime_type: A const char * containing a mime type
282 * @new_value: A boolean value indicating whether @mime_type could be executable.
284 * Set whether files of this MIME type might conceivably be executable.
286 * Return value: GnomeVFSResult indicating the success of the operation or any
287 * errors that may have occurred.
290 gnome_vfs_mime_set_can_be_executable (const char *mime_type, gboolean new_value)
292 return gnome_vfs_mime_edit_user_file
293 (mime_type, "can_be_executable", new_value ? "TRUE" : "FALSE");
297 * gnome_vfs_mime_get_default_component:
298 * @mime_type: A const char * containing a mime type, e.g. "image/png"
300 * Query the MIME database for the default Bonobo component to be activated to
301 * view files of MIME type @mime_type.
303 * Return value: An Bonobo_ServerInfo * representing the OAF server to be activated
304 * to get a reference to the proper component.
307 gnome_vfs_mime_get_default_component (const char *mime_type)
309 const char *default_component_iid;
310 Bonobo_ServerInfoList *info_list;
311 Bonobo_ServerInfo *default_component;
312 CORBA_Environment ev;
320 if (mime_type == NULL) {
324 CORBA_exception_init (&ev);
326 supertype = gnome_vfs_get_supertype_from_mime_type (mime_type);
328 /* Find a component that supports either the exact mime type,
329 the supertype, or all mime types. */
331 /* First try the component specified in the mime database, if available.
332 gnome_vfs_mime_get_value looks up the value for the mime type and the supertype. */
333 default_component_iid = gnome_vfs_mime_get_value
334 (mime_type, "default_component_iid");
336 query = g_strconcat ("bonobo:supported_mime_types.has_one (['", mime_type,
341 if (default_component_iid != NULL) {
342 sort[0] = g_strconcat ("iid == '", default_component_iid, "'", NULL);
344 sort[0] = g_strdup ("true");
347 short_list = gnome_vfs_mime_get_short_list_components (mime_type);
348 short_list = g_list_concat (short_list,
349 gnome_vfs_mime_get_short_list_components (supertype));
350 if (short_list != NULL) {
351 sort[1] = g_strdup ("prefer_by_list_order(iid, ['");
353 for (p = short_list; p != NULL; p = p->next) {
356 if (p->next != NULL) {
357 sort[1] = g_strconcat (prev, ((Bonobo_ServerInfo *) (p->data))->iid,
360 sort[1] = g_strconcat (prev, ((Bonobo_ServerInfo *) (p->data))->iid,
365 gnome_vfs_mime_component_list_free (short_list);
367 sort[1] = g_strdup ("true");
371 /* Prefer something that matches the exact type to something
372 that matches the supertype */
373 sort[2] = g_strconcat ("bonobo:supported_mime_types.has ('", mime_type, "')", NULL);
375 /* Prefer something that matches the supertype to something that matches `*' */
376 sort[3] = g_strconcat ("bonobo:supported_mime_types.has ('", supertype, "')", NULL);
378 sort[4] = g_strdup ("name");
381 info_list = bonobo_activation_query (query, sort, &ev);
383 default_component = NULL;
384 if (ev._major == CORBA_NO_EXCEPTION) {
385 if (info_list != NULL && info_list->_length > 0) {
386 default_component = Bonobo_ServerInfo_duplicate (&info_list->_buffer[0]);
388 CORBA_free (info_list);
399 CORBA_exception_free (&ev);
401 return default_component;
405 gnome_vfs_mime_str_list_merge (GList *a,
412 pruned_b = str_list_difference (b, a);
414 a_copy = g_list_copy (a);
415 extended_a = g_list_concat (a_copy, pruned_b);
417 /* No need to free a_copy or
418 * pruned_b since they were concat()ed into
427 gnome_vfs_mime_str_list_apply_delta (GList *list_to_process,
431 GList *extended_original_list;
432 GList *processed_list;
434 extended_original_list = gnome_vfs_mime_str_list_merge (list_to_process, additions);
436 processed_list = str_list_difference (extended_original_list, removals);
438 g_list_free (extended_original_list);
440 return processed_list;
444 gnome_vfs_mime_do_short_list_processing (GList *short_list,
447 GList *supertype_short_list,
448 GList *supertype_additions,
449 GList *supertype_removals)
451 GList *processed_supertype_list;
452 GList *merged_system_and_supertype;
455 processed_supertype_list = gnome_vfs_mime_str_list_apply_delta (supertype_short_list,
459 merged_system_and_supertype = gnome_vfs_mime_str_list_merge (short_list,
460 processed_supertype_list);
462 final_list = gnome_vfs_mime_str_list_apply_delta (merged_system_and_supertype,
466 g_list_free (processed_supertype_list);
467 g_list_free (merged_system_and_supertype);
473 /* sort_application_list
475 * Sort list alphabetically
479 sort_application_list (gconstpointer a, gconstpointer b)
481 GnomeVFSMimeApplication *application1, *application2;
483 application1 = (GnomeVFSMimeApplication *) a;
484 application2 = (GnomeVFSMimeApplication *) b;
486 return g_ascii_strcasecmp (application1->name, application2->name);
490 * gnome_vfs_mime_get_short_list_applications:
491 * @mime_type: A const char * containing a mime type, e.g. "image/png"
493 * Return an alphabetically sorted list of GnomeVFSMimeApplication
494 * data structures for the requested mime type. The short list contains
495 * "select" applications recommended for handling this MIME type, appropriate for
496 * display to the user.
498 * Return value: A GList * where the elements are GnomeVFSMimeApplication *
499 * representing various applications to display in the short list for @mime_type.
502 gnome_vfs_mime_get_short_list_applications (const char *mime_type)
504 GList *system_short_list;
505 GList *short_list_additions;
506 GList *short_list_removals;
508 GList *supertype_short_list;
509 GList *supertype_additions;
510 GList *supertype_removals;
513 GnomeVFSMimeApplication *application;
514 GList *preferred_applications;
516 if (mime_type == NULL) {
521 system_short_list = comma_separated_str_to_str_list (gnome_vfs_mime_maybe_get_user_level_value
523 "short_list_application_ids"));
524 system_short_list = prune_ids_for_nonexistent_applications
527 /* get user short list delta (add list and remove list) */
529 short_list_additions = comma_separated_str_to_str_list (gnome_vfs_mime_get_value
531 "short_list_application_user_additions"));
532 short_list_additions = prune_ids_for_nonexistent_applications (short_list_additions);
533 short_list_removals = comma_separated_str_to_str_list (gnome_vfs_mime_get_value
535 "short_list_application_user_removals"));
537 /* Only include the supertype in the short list if we came up empty with
538 the specific types */
539 supertype = gnome_vfs_get_supertype_from_mime_type (mime_type);
541 if (!gnome_vfs_mime_type_is_supertype (mime_type) && system_short_list == NULL) {
542 supertype_short_list = comma_separated_str_to_str_list
543 (gnome_vfs_mime_maybe_get_user_level_value
545 "short_list_application_ids"));
546 supertype_short_list = prune_ids_for_nonexistent_applications
547 (supertype_short_list);
549 /* get supertype short list delta (add list and remove list) */
551 supertype_additions = comma_separated_str_to_str_list
552 (gnome_vfs_mime_get_value
554 "short_list_application_user_additions"));
555 supertype_removals = comma_separated_str_to_str_list
556 (gnome_vfs_mime_get_value
558 "short_list_application_user_removals"));
560 supertype_short_list = NULL;
561 supertype_additions = NULL;
562 supertype_removals = NULL;
567 /* compute list modified by delta */
569 id_list = gnome_vfs_mime_do_short_list_processing (system_short_list,
570 short_list_additions,
572 supertype_short_list,
576 preferred_applications = NULL;
578 for (p = id_list; p != NULL; p = p->next) {
579 application = gnome_vfs_application_registry_get_mime_application (p->data);
580 if (application != NULL) {
581 preferred_applications = g_list_prepend
582 (preferred_applications, application);
587 preferred_applications = g_list_reverse (preferred_applications);
589 g_list_free_deep (system_short_list);
590 g_list_free_deep (short_list_additions);
591 g_list_free_deep (short_list_removals);
592 g_list_free_deep (supertype_short_list);
593 g_list_free_deep (supertype_additions);
594 g_list_free_deep (supertype_removals);
595 g_list_free (id_list);
597 /* Sort list alphabetically by application name */
598 preferred_applications = g_list_sort (preferred_applications, sort_application_list);
600 return preferred_applications;
606 join_str_list (const char *separator, GList *list)
613 /* Convert to a strv so we can use g_strjoinv.
614 * Saves code but could be made faster if we want.
616 strv = g_new0 (char *, g_list_length (list) + 1);
617 for (p = list, i = 0; p != NULL; p = p->next, i++) {
618 strv[i] = (char *) p->data;
622 retval = g_strjoinv (separator, strv);
631 * gnome_vfs_mime_get_short_list_components:
632 * @mime_type: A const char * containing a mime type, e.g. "image/png"
634 * Return an unsorted sorted list of Bonobo_ServerInfo *
635 * data structures for the requested mime type. The short list contains
636 * "select" components recommended for handling this MIME type, appropriate for
637 * display to the user.
639 * Return value: A GList * where the elements are Bonobo_ServerInfo *
640 * representing various components to display in the short list for @mime_type.
643 gnome_vfs_mime_get_short_list_components (const char *mime_type)
645 GList *system_short_list;
646 GList *short_list_additions;
647 GList *short_list_removals;
649 GList *supertype_short_list;
650 GList *supertype_additions;
651 GList *supertype_removals;
655 char *iids_delimited;
656 CORBA_Environment ev;
657 Bonobo_ServerInfoList *info_list;
658 GList *preferred_components;
660 if (mime_type == NULL) {
665 /* get short list IIDs for that user level */
666 system_short_list = comma_separated_str_to_str_list (gnome_vfs_mime_get_value
668 "short_list_component_iids"));
670 /* get user short list delta (add list and remove list) */
672 short_list_additions = comma_separated_str_to_str_list (gnome_vfs_mime_get_value
674 "short_list_component_user_additions"));
676 short_list_removals = comma_separated_str_to_str_list (gnome_vfs_mime_get_value
678 "short_list_component_user_removals"));
681 supertype = gnome_vfs_get_supertype_from_mime_type (mime_type);
683 if (strcmp (supertype, mime_type) != 0) {
684 supertype_short_list = comma_separated_str_to_str_list
685 (gnome_vfs_mime_get_value
687 "short_list_component_iids"));
689 /* get supertype short list delta (add list and remove list) */
691 supertype_additions = comma_separated_str_to_str_list
692 (gnome_vfs_mime_get_value
694 "short_list_component_user_additions"));
695 supertype_removals = comma_separated_str_to_str_list
696 (gnome_vfs_mime_get_value
698 "short_list_component_user_removals"));
700 supertype_short_list = NULL;
701 supertype_additions = NULL;
702 supertype_removals = NULL;
705 /* compute list modified by delta */
707 iid_list = gnome_vfs_mime_do_short_list_processing (system_short_list,
708 short_list_additions,
710 supertype_short_list,
716 /* Do usual query but requiring that IIDs be one of the ones
717 in the short list IID list. */
719 preferred_components = NULL;
720 if (iid_list != NULL) {
721 CORBA_exception_init (&ev);
723 iids_delimited = join_str_list ("','", iid_list);
725 query = g_strconcat ("bonobo:supported_mime_types.has_one (['", mime_type,
728 " AND has(['", iids_delimited, "'], iid)", NULL);
730 sort[0] = g_strconcat ("prefer_by_list_order(iid, ['", iids_delimited, "'])", NULL);
733 info_list = bonobo_activation_query (query, sort, &ev);
735 if (ev._major == CORBA_NO_EXCEPTION) {
736 preferred_components = Bonobo_ServerInfoList_to_ServerInfo_g_list (info_list);
737 CORBA_free (info_list);
740 g_free (iids_delimited);
744 CORBA_exception_free (&ev);
748 g_list_free_deep (system_short_list);
749 g_list_free_deep (short_list_additions);
750 g_list_free_deep (short_list_removals);
751 g_list_free_deep (supertype_short_list);
752 g_list_free_deep (supertype_additions);
753 g_list_free_deep (supertype_removals);
754 g_list_free (iid_list);
756 return preferred_components;
761 * gnome_vfs_mime_get_all_applications:
762 * @mime_type: A const char * containing a mime type, e.g. "image/png"
764 * Return an alphabetically sorted list of GnomeVFSMimeApplication
765 * data structures representing all applications in the MIME database registered
766 * to handle files of MIME type @mime_type (and supertypes).
768 * Return value: A GList * where the elements are GnomeVFSMimeApplication *
769 * representing applications that handle MIME type @mime_type.
772 gnome_vfs_mime_get_all_applications (const char *mime_type)
774 GList *applications, *node, *next;
775 char *application_id;
776 GnomeVFSMimeApplication *application;
778 g_return_val_if_fail (mime_type != NULL, NULL);
780 applications = gnome_vfs_application_registry_get_applications (mime_type);
782 /* We get back a list of const char *, but the prune function
783 * wants a list of strings that we own.
785 for (node = applications; node != NULL; node = node->next) {
786 node->data = g_strdup (node->data);
789 /* Remove application ids representing nonexistent (not in path) applications */
790 applications = prune_ids_for_nonexistent_applications (applications);
792 /* Convert to GnomeVFSMimeApplication's (leaving out NULLs) */
793 for (node = applications; node != NULL; node = next) {
796 application_id = node->data;
797 application = gnome_vfs_application_registry_get_mime_application (application_id);
799 /* Replace the application ID with the application */
800 if (application == NULL) {
801 applications = g_list_remove_link (applications, node);
802 g_list_free_1 (node);
804 node->data = application;
807 g_free (application_id);
814 * gnome_vfs_mime_get_all_components:
815 * @mime_type: A const char * containing a mime type, e.g. "image/png"
817 * Return an alphabetically sorted list of Bonobo_ServerInfo
818 * data structures representing all Bonobo components registered
819 * to handle files of MIME type @mime_type (and supertypes).
821 * Return value: A GList * where the elements are Bonobo_ServerInfo *
822 * representing components that can handle MIME type @mime_type.
825 gnome_vfs_mime_get_all_components (const char *mime_type)
827 Bonobo_ServerInfoList *info_list;
828 GList *components_list;
829 CORBA_Environment ev;
834 if (mime_type == NULL) {
838 CORBA_exception_init (&ev);
840 /* Find a component that supports either the exact mime type,
841 the supertype, or all mime types. */
843 /* FIXME bugzilla.eazel.com 1142: should probably check for
844 the right interfaces too. Also slightly semantically
845 different from nautilus in other tiny ways.
847 supertype = gnome_vfs_get_supertype_from_mime_type (mime_type);
848 query = g_strconcat ("bonobo:supported_mime_types.has_one (['", mime_type,
853 /* Alphebetize by name, for the sake of consistency */
854 sort[0] = g_strdup ("name");
857 info_list = bonobo_activation_query (query, sort, &ev);
859 if (ev._major == CORBA_NO_EXCEPTION) {
860 components_list = Bonobo_ServerInfoList_to_ServerInfo_g_list (info_list);
861 CORBA_free (info_list);
863 components_list = NULL;
869 CORBA_exception_free (&ev);
871 return components_list;
874 static GnomeVFSResult
875 gnome_vfs_mime_edit_user_file_full (const char *mime_type, GList *keys, GList *values)
877 GnomeVFSResult result;
879 const char *key, *value;
881 if (mime_type == NULL) {
885 result = GNOME_VFS_OK;
887 gnome_vfs_mime_freeze ();
888 for (p = keys, q = values; p != NULL && q != NULL; p = p->next, q = q->next) {
894 gnome_vfs_mime_set_value (mime_type, key, value);
896 gnome_vfs_mime_thaw ();
901 static GnomeVFSResult
902 gnome_vfs_mime_edit_user_file_args (const char *mime_type, va_list args)
904 GList *keys, *values;
906 GnomeVFSResult result;
911 key = va_arg (args, char *);
915 value = va_arg (args, char *);
916 keys = g_list_prepend (keys, key);
917 values = g_list_prepend (values, value);
920 result = gnome_vfs_mime_edit_user_file_full (mime_type, keys, values);
923 g_list_free (values);
928 static GnomeVFSResult
929 gnome_vfs_mime_edit_user_file_multiple (const char *mime_type, ...)
932 GnomeVFSResult result;
934 va_start (args, mime_type);
935 result = gnome_vfs_mime_edit_user_file_args (mime_type, args);
941 static GnomeVFSResult
942 gnome_vfs_mime_edit_user_file (const char *mime_type, const char *key, const char *value)
944 g_return_val_if_fail (key != NULL, GNOME_VFS_OK);
945 return gnome_vfs_mime_edit_user_file_multiple (mime_type, key, value, NULL);
949 * gnome_vfs_mime_set_default_action_type:
950 * @mime_type: A const char * containing a mime type, e.g. "image/png"
951 * @action_type: A GnomeVFSMimeActionType containing the action to perform by default
953 * Sets the default action type to be performed on files of MIME type @mime_type.
955 * Return value: A GnomeVFSResult indicating the success of the operation or reporting
956 * any errors encountered.
959 gnome_vfs_mime_set_default_action_type (const char *mime_type,
960 GnomeVFSMimeActionType action_type)
962 const char *action_string;
964 switch (action_type) {
965 case GNOME_VFS_MIME_ACTION_TYPE_APPLICATION:
966 action_string = "application";
968 case GNOME_VFS_MIME_ACTION_TYPE_COMPONENT:
969 action_string = "component";
971 case GNOME_VFS_MIME_ACTION_TYPE_NONE:
973 action_string = "none";
976 return gnome_vfs_mime_edit_user_file
977 (mime_type, "default_action_type", action_string);
981 * gnome_vfs_mime_set_default_application:
982 * @mime_type: A const char * containing a mime type, e.g. "application/x-php"
983 * @application_id: A key representing an application in the MIME database
984 * (GnomeVFSMimeApplication->id, for example)
986 * Sets the default application to be run on files of MIME type @mime_type.
988 * Return value: A GnomeVFSResult indicating the success of the operation or reporting
989 * any errors encountered.
992 gnome_vfs_mime_set_default_application (const char *mime_type,
993 const char *application_id)
995 GnomeVFSResult result;
997 result = gnome_vfs_mime_edit_user_file
998 (mime_type, "default_application_id", application_id);
1000 /* If there's no default action type, set it to match this. */
1001 if (result == GNOME_VFS_OK
1002 && application_id != NULL
1003 && gnome_vfs_mime_get_default_action_type (mime_type) == GNOME_VFS_MIME_ACTION_TYPE_NONE) {
1004 result = gnome_vfs_mime_set_default_action_type (mime_type, GNOME_VFS_MIME_ACTION_TYPE_APPLICATION);
1011 * gnome_vfs_mime_set_default_component:
1012 * @mime_type: A const char * containing a mime type, e.g. "application/x-php"
1013 * @component_iid: The OAFIID of a component
1015 * Sets the default component to be activated for files of MIME type @mime_type.
1017 * Return value: A GnomeVFSResult indicating the success of the operation or reporting
1018 * any errors encountered.
1021 gnome_vfs_mime_set_default_component (const char *mime_type,
1022 const char *component_iid)
1024 GnomeVFSResult result;
1026 result = gnome_vfs_mime_edit_user_file
1027 (mime_type, "default_component_iid", component_iid);
1029 /* If there's no default action type, set it to match this. */
1030 if (result == GNOME_VFS_OK
1031 && component_iid != NULL
1032 && gnome_vfs_mime_get_default_action_type (mime_type) == GNOME_VFS_MIME_ACTION_TYPE_NONE) {
1033 gnome_vfs_mime_set_default_action_type (mime_type, GNOME_VFS_MIME_ACTION_TYPE_COMPONENT);
1040 * gnome_vfs_mime_set_short_list_applications:
1041 * @mime_type: A const char * containing a mime type, e.g. "application/x-php"
1042 * @application_ids: GList of const char * application ids
1044 * Set the short list of applications for the specified MIME type. The short list
1045 * contains applications recommended for possible selection by the user.
1047 * Return value: A GnomeVFSResult indicating the success of the operation or reporting
1048 * any errors encountered.
1051 gnome_vfs_mime_set_short_list_applications (const char *mime_type,
1052 GList *application_ids)
1054 char *addition_string, *removal_string;
1055 GList *short_list_id_list;
1056 GList *short_list_addition_list;
1057 GList *short_list_removal_list;
1058 GnomeVFSResult result;
1061 /* Get base list. */
1062 short_list_id_list = comma_separated_str_to_str_list
1063 (gnome_vfs_mime_maybe_get_user_level_value (mime_type, "short_list_application_ids"));
1065 /* Compute delta. */
1066 short_list_addition_list = str_list_difference (application_ids, short_list_id_list);
1067 short_list_removal_list = str_list_difference (short_list_id_list, application_ids);
1068 addition_string = str_list_to_comma_separated_str (short_list_addition_list);
1069 removal_string = str_list_to_comma_separated_str (short_list_removal_list);
1071 /* Make sure the newly added app_ids are already associated to this
1072 * mime type in the application registry
1074 for (it = short_list_addition_list; it != NULL; it = it->next) {
1075 /* add_mime_type won't do anything if mime_type is already
1076 * associated with it->data
1078 gnome_vfs_application_registry_add_mime_type (it->data, mime_type);
1080 gnome_vfs_application_registry_sync ();
1082 g_list_free_deep (short_list_id_list);
1083 g_list_free (short_list_addition_list);
1084 g_list_free (short_list_removal_list);
1087 result = gnome_vfs_mime_edit_user_file_multiple
1089 "short_list_application_user_additions", addition_string,
1090 "short_list_application_user_removals", removal_string,
1093 g_free (addition_string);
1094 g_free (removal_string);
1100 * gnome_vfs_mime_set_short_list_components:
1101 * @mime_type: A const char * containing a mime type, e.g. "application/x-php"
1102 * @component_iids: GList of const char * OAF IIDs
1104 * Set the short list of components for the specified MIME type. The short list
1105 * contains companents recommended for possible selection by the user. *
1107 * Return value: A GnomeVFSResult indicating the success of the operation or reporting
1108 * any errors encountered.
1111 gnome_vfs_mime_set_short_list_components (const char *mime_type,
1112 GList *component_iids)
1114 char *addition_string, *removal_string;
1115 GList *short_list_id_list;
1116 GList *short_list_addition_list;
1117 GList *short_list_removal_list;
1118 GnomeVFSResult result;
1120 short_list_id_list = comma_separated_str_to_str_list
1121 (gnome_vfs_mime_get_value (mime_type, "short_list_component_iids"));
1123 /* Compute delta. */
1124 short_list_addition_list = str_list_difference (component_iids, short_list_id_list);
1125 short_list_removal_list = str_list_difference (short_list_id_list, component_iids);
1126 addition_string = str_list_to_comma_separated_str (short_list_addition_list);
1127 removal_string = str_list_to_comma_separated_str (short_list_removal_list);
1128 g_list_free (short_list_addition_list);
1129 g_list_free (short_list_removal_list);
1132 result = gnome_vfs_mime_edit_user_file_multiple
1134 "short_list_component_user_additions", addition_string,
1135 "short_list_component_user_removals", removal_string,
1138 g_free (addition_string);
1139 g_free (removal_string);
1144 /* FIXME bugzilla.eazel.com 1148:
1145 * The next set of helper functions are all replicated in nautilus-mime-actions.c.
1146 * Need to refactor so they can share code.
1149 gnome_vfs_mime_application_has_id (GnomeVFSMimeApplication *application, const char *id)
1151 return strcmp (application->id, id);
1155 gnome_vfs_mime_id_matches_application (const char *id, GnomeVFSMimeApplication *application)
1157 return gnome_vfs_mime_application_has_id (application, id);
1161 gnome_vfs_mime_id_matches_component (const char *iid, Bonobo_ServerInfo *component)
1163 return strcmp (component->iid, iid);
1167 gnome_vfs_mime_application_matches_id (GnomeVFSMimeApplication *application, const char *id)
1169 return gnome_vfs_mime_id_matches_application (id, application);
1173 gnome_vfs_mime_component_matches_id (Bonobo_ServerInfo *component, const char *iid)
1175 return gnome_vfs_mime_id_matches_component (iid, component);
1179 * gnome_vfs_mime_id_in_application_list:
1180 * @id: An application id.
1181 * @applications: A GList * whose nodes are GnomeVFSMimeApplications, such as the
1182 * result of gnome_vfs_mime_get_short_list_applications().
1184 * Check whether an application id is in a list of GnomeVFSMimeApplications.
1186 * Return value: TRUE if an application whose id matches @id is in @applications.
1189 gnome_vfs_mime_id_in_application_list (const char *id, GList *applications)
1191 return g_list_find_custom
1192 (applications, (gpointer) id,
1193 (GCompareFunc) gnome_vfs_mime_application_matches_id) != NULL;
1197 * gnome_vfs_mime_id_in_component_list:
1198 * @iid: A component iid.
1199 * @components: A GList * whose nodes are Bonobo_ServerInfos, such as the
1200 * result of gnome_vfs_mime_get_short_list_components().
1202 * Check whether a component iid is in a list of Bonobo_ServerInfos.
1204 * Return value: TRUE if a component whose iid matches @iid is in @components.
1207 gnome_vfs_mime_id_in_component_list (const char *iid, GList *components)
1209 return g_list_find_custom
1210 (components, (gpointer) iid,
1211 (GCompareFunc) gnome_vfs_mime_component_matches_id) != NULL;
1216 * gnome_vfs_mime_id_list_from_application_list:
1217 * @applications: A GList * whose nodes are GnomeVFSMimeApplications, such as the
1218 * result of gnome_vfs_mime_get_short_list_applications().
1220 * Create a list of application ids from a list of GnomeVFSMimeApplications.
1222 * Return value: A new list where each GnomeVFSMimeApplication in the original
1223 * list is replaced by a char * with the application's id. The original list is
1227 gnome_vfs_mime_id_list_from_application_list (GList *applications)
1234 for (node = applications; node != NULL; node = node->next) {
1235 result = g_list_append
1236 (result, g_strdup (((GnomeVFSMimeApplication *)node->data)->id));
1243 * gnome_vfs_mime_id_list_from_component_list:
1244 * @components: A GList * whose nodes are Bonobo_ServerInfos, such as the
1245 * result of gnome_vfs_mime_get_short_list_components().
1247 * Create a list of component iids from a list of Bonobo_ServerInfos.
1249 * Return value: A new list where each Bonobo_ServerInfo in the original
1250 * list is replaced by a char * with the component's iid. The original list is
1254 gnome_vfs_mime_id_list_from_component_list (GList *components)
1259 for (node = components; node != NULL; node = node->next) {
1260 list = g_list_prepend
1261 (list, g_strdup (((Bonobo_ServerInfo *)node->data)->iid));
1263 return g_list_reverse (list);
1267 g_list_free_deep (GList *list)
1269 g_list_foreach (list, (GFunc) g_free, NULL);
1274 * gnome_vfs_mime_add_application_to_short_list:
1275 * @mime_type: A const char * containing a mime type, e.g. "application/x-php"
1276 * @application_id: const char * containing the application's id in the MIME database
1278 * Add an application to the short list for MIME type @mime_type. The short list contains
1279 * applications recommended for display as choices to the user for a particular MIME type.
1281 * Return value: A GnomeVFSResult indicating the success of the operation or reporting
1282 * any errors encountered.
1285 gnome_vfs_mime_add_application_to_short_list (const char *mime_type,
1286 const char *application_id)
1288 GList *old_list, *new_list;
1289 GnomeVFSResult result;
1291 old_list = gnome_vfs_mime_get_short_list_applications (mime_type);
1293 if (gnome_vfs_mime_id_in_application_list (application_id, old_list)) {
1294 result = GNOME_VFS_OK;
1296 new_list = g_list_append (gnome_vfs_mime_id_list_from_application_list (old_list),
1297 g_strdup (application_id));
1298 result = gnome_vfs_mime_set_short_list_applications (mime_type, new_list);
1299 g_list_free_deep (new_list);
1302 gnome_vfs_mime_application_list_free (old_list);
1308 * gnome_vfs_mime_remove_application_from_list:
1309 * @applications: A GList * whose nodes are GnomeVFSMimeApplications, such as the
1310 * result of gnome_vfs_mime_get_short_list_applications().
1311 * @application_id: The id of an application to remove from @applications.
1312 * @did_remove: If non-NULL, this is filled in with TRUE if the application
1313 * was found in the list, FALSE otherwise.
1315 * Remove an application specified by id from a list of GnomeVFSMimeApplications.
1317 * Return value: The modified list. If the application is not found, the list will
1321 gnome_vfs_mime_remove_application_from_list (GList *applications,
1322 const char *application_id,
1323 gboolean *did_remove)
1325 GList *matching_node;
1327 matching_node = g_list_find_custom
1328 (applications, (gpointer)application_id,
1329 (GCompareFunc) gnome_vfs_mime_application_matches_id);
1330 if (matching_node != NULL) {
1331 applications = g_list_remove_link (applications, matching_node);
1332 gnome_vfs_mime_application_list_free (matching_node);
1335 if (did_remove != NULL) {
1336 *did_remove = matching_node != NULL;
1339 return applications;
1343 * gnome_vfs_mime_remove_application_from_short_list:
1344 * @mime_type: A const char * containing a mime type, e.g. "application/x-php"
1345 * @application_id: const char * containing the application's id in the MIME database
1347 * Remove an application from the short list for MIME type @mime_type. The short list contains
1348 * applications recommended for display as choices to the user for a particular MIME type.
1350 * Return value: A GnomeVFSResult indicating the success of the operation or reporting
1351 * any errors encountered.
1354 gnome_vfs_mime_remove_application_from_short_list (const char *mime_type,
1355 const char *application_id)
1357 GnomeVFSResult result;
1358 GList *old_list, *new_list;
1359 gboolean was_in_list;
1361 old_list = gnome_vfs_mime_get_short_list_applications (mime_type);
1362 old_list = gnome_vfs_mime_remove_application_from_list
1363 (old_list, application_id, &was_in_list);
1366 result = GNOME_VFS_OK;
1368 new_list = gnome_vfs_mime_id_list_from_application_list (old_list);
1369 result = gnome_vfs_mime_set_short_list_applications (mime_type, new_list);
1370 g_list_free_deep (new_list);
1373 gnome_vfs_mime_application_list_free (old_list);
1379 * gnome_vfs_mime_add_component_to_short_list:
1380 * @mime_type: A const char * containing a mime type, e.g. "application/x-php"
1381 * @iid: const char * containing the component's OAF IID
1383 * Add a component to the short list for MIME type @mime_type. The short list contains
1384 * components recommended for display as choices to the user for a particular MIME type.
1386 * Return value: A GnomeVFSResult indicating the success of the operation or reporting
1387 * any errors encountered.
1390 gnome_vfs_mime_add_component_to_short_list (const char *mime_type,
1393 GnomeVFSResult result;
1394 GList *old_list, *new_list;
1396 old_list = gnome_vfs_mime_get_short_list_components (mime_type);
1398 if (gnome_vfs_mime_id_in_component_list (iid, old_list)) {
1399 result = GNOME_VFS_OK;
1401 new_list = g_list_append (gnome_vfs_mime_id_list_from_component_list (old_list),
1403 result = gnome_vfs_mime_set_short_list_components (mime_type, new_list);
1404 g_list_free_deep (new_list);
1407 gnome_vfs_mime_component_list_free (old_list);
1413 * gnome_vfs_mime_remove_component_from_list:
1414 * @components: A GList * whose nodes are Bonobo_ServerInfos, such as the
1415 * result of gnome_vfs_mime_get_short_list_components().
1416 * @iid: The iid of a component to remove from @components.
1417 * @did_remove: If non-NULL, this is filled in with TRUE if the component
1418 * was found in the list, FALSE otherwise.
1420 * Remove a component specified by iid from a list of Bonobo_ServerInfos.
1422 * Return value: The modified list. If the component is not found, the list will
1426 gnome_vfs_mime_remove_component_from_list (GList *components,
1428 gboolean *did_remove)
1430 GList *matching_node;
1432 matching_node = g_list_find_custom
1433 (components, (gpointer)iid,
1434 (GCompareFunc) gnome_vfs_mime_component_matches_id);
1435 if (matching_node != NULL) {
1436 components = g_list_remove_link (components, matching_node);
1437 gnome_vfs_mime_component_list_free (matching_node);
1440 if (did_remove != NULL) {
1441 *did_remove = matching_node != NULL;
1447 * gnome_vfs_mime_remove_component_from_short_list:
1448 * @mime_type: A const char * containing a mime type, e.g. "application/x-php"
1449 * @iid: const char * containing the component's OAF IID
1451 * Remove a component from the short list for MIME type @mime_type. The short list contains
1452 * components recommended for display as choices to the user for a particular MIME type.
1454 * Return value: A GnomeVFSResult indicating the success of the operation or reporting
1455 * any errors encountered.
1458 gnome_vfs_mime_remove_component_from_short_list (const char *mime_type,
1461 GnomeVFSResult result;
1462 GList *old_list, *new_list;
1463 gboolean was_in_list;
1465 old_list = gnome_vfs_mime_get_short_list_components (mime_type);
1466 old_list = gnome_vfs_mime_remove_component_from_list
1467 (old_list, iid, &was_in_list);
1470 result = GNOME_VFS_OK;
1472 new_list = gnome_vfs_mime_id_list_from_component_list (old_list);
1473 result = gnome_vfs_mime_set_short_list_components (mime_type, new_list);
1474 g_list_free_deep (new_list);
1477 gnome_vfs_mime_component_list_free (old_list);
1483 * gnome_vfs_mime_add_extension:
1484 * @extension: The extension to add (e.g. "txt")
1485 * @mime_type: The mime type to add the mapping to.
1487 * Add a file extension to the specificed MIME type in the MIME database.
1489 * Return value: GnomeVFSResult indicating the success of the operation or any
1490 * errors that may have occurred.
1493 gnome_vfs_mime_add_extension (const char *mime_type, const char *extension)
1495 GnomeVFSResult result;
1496 GList *list, *element;
1497 gchar *extensions, *old_extensions;
1500 old_extensions = NULL;
1502 result = GNOME_VFS_OK;
1504 list = gnome_vfs_mime_get_extensions_list (mime_type);
1506 /* List is NULL. This means there are no current registered extensions.
1507 * Add the new extension and it will cause the list to be created next time.
1509 result = gnome_vfs_mime_set_registered_type_key (mime_type, "ext", extension);
1513 /* Check for duplicates */
1514 for (element = list; element != NULL; element = element->next) {
1515 if (strcmp (extension, (char *)element->data) == 0) {
1516 gnome_vfs_mime_extensions_list_free (list);
1521 /* Add new extension to list */
1522 for (element = list; element != NULL; element = element->next) {
1523 if (extensions != NULL) {
1524 old_extensions = extensions;
1525 extensions = g_strdup_printf ("%s %s", old_extensions, (char *)element->data);
1526 g_free (old_extensions);
1528 extensions = g_strdup_printf ("%s", (char *)element->data);
1532 if (extensions != NULL) {
1533 old_extensions = extensions;
1534 extensions = g_strdup_printf ("%s %s", old_extensions, extension);
1535 g_free (old_extensions);
1537 /* Add extensions to hash table and flush into the file. */
1538 gnome_vfs_mime_set_registered_type_key (mime_type, "ext", extensions);
1541 gnome_vfs_mime_extensions_list_free (list);
1547 * gnome_vfs_mime_remove_extension:
1548 * @extension: The extension to remove
1549 * @mime_type: The mime type to remove the extension from
1551 * Removes a file extension from the specificed MIME type in the MIME database.
1553 * Return value: GnomeVFSResult indicating the success of the operation or any
1554 * errors that may have occurred.
1557 gnome_vfs_mime_remove_extension (const char *mime_type, const char *extension)
1559 GList *list, *element;
1560 gchar *extensions, *old_extensions;
1562 GnomeVFSResult result;
1564 result = GNOME_VFS_OK;
1566 old_extensions = NULL;
1569 list = gnome_vfs_mime_get_extensions_list (mime_type);
1574 /* See if extension is in list */
1575 for (element = list; element != NULL; element = element->next) {
1576 if (strcmp (extension, (char *)element->data) == 0) {
1577 /* Remove extension from list */
1579 list = g_list_remove (list, element->data);
1580 g_free (element->data);
1589 /* Exit if we found no match */
1591 gnome_vfs_mime_extensions_list_free (list);
1595 /* Create new extension list */
1596 for (element = list; element != NULL; element = element->next) {
1597 if (extensions != NULL) {
1598 old_extensions = extensions;
1599 extensions = g_strdup_printf ("%s %s", old_extensions, (char *)element->data);
1600 g_free (old_extensions);
1602 extensions = g_strdup_printf ("%s", (char *)element->data);
1606 if (extensions != NULL) {
1607 /* Add extensions to hash table and flush into the file */
1608 gnome_vfs_mime_set_registered_type_key (mime_type, "ext", extensions);
1610 gnome_vfs_mime_set_registered_type_key (mime_type, "ext", "");
1613 gnome_vfs_mime_extensions_list_free (list);
1619 * gnome_vfs_mime_extend_all_applications:
1620 * @mime_type: A const char * containing a mime type, e.g. "application/x-php"
1621 * @application_ids: a GList of const char * containing application ids
1623 * Register @mime_type as being handled by all applications list in @application_ids.
1625 * Return value: A GnomeVFSResult indicating the success of the operation or reporting
1626 * any errors encountered.
1629 gnome_vfs_mime_extend_all_applications (const char *mime_type,
1630 GList *application_ids)
1634 g_return_val_if_fail (mime_type != NULL, GNOME_VFS_ERROR_INTERNAL);
1636 for (li = application_ids; li != NULL; li = li->next) {
1637 const char *application_id = li->data;
1638 gnome_vfs_application_registry_add_mime_type (application_id,
1642 return gnome_vfs_application_registry_sync ();
1646 * gnome_vfs_mime_remove_from_all_applications:
1647 * @mime_type: A const char * containing a mime type, e.g. "application/x-php"
1648 * @application_ids: a GList of const char * containing application ids
1650 * Remove @mime_type as a handled type from every application in @application_ids
1652 * Return value: A GnomeVFSResult indicating the success of the operation or reporting
1653 * any errors encountered.
1656 gnome_vfs_mime_remove_from_all_applications (const char *mime_type,
1657 GList *application_ids)
1661 g_return_val_if_fail (mime_type != NULL, GNOME_VFS_ERROR_INTERNAL);
1663 for (li = application_ids; li != NULL; li = li->next) {
1664 const char *application_id = li->data;
1665 gnome_vfs_application_registry_remove_mime_type (application_id,
1669 return gnome_vfs_application_registry_sync ();
1674 * gnome_vfs_mime_application_copy:
1675 * @application: The GnomeVFSMimeApplication to be duplicated.
1677 * Creates a newly referenced copy of a GnomeVFSMimeApplication object.
1679 * Return value: A copy of @application
1681 GnomeVFSMimeApplication *
1682 gnome_vfs_mime_application_copy (GnomeVFSMimeApplication *application)
1684 GnomeVFSMimeApplication *result;
1686 if (application == NULL) {
1690 result = g_new0 (GnomeVFSMimeApplication, 1);
1691 result->id = g_strdup (application->id);
1692 result->name = g_strdup (application->name);
1693 result->command = g_strdup (application->command);
1694 result->can_open_multiple_files = application->can_open_multiple_files;
1695 result->expects_uris = application->expects_uris;
1696 result->supported_uri_schemes = copy_str_list (application->supported_uri_schemes);
1697 result->requires_terminal = application->requires_terminal;
1703 * gnome_vfs_mime_application_free:
1704 * @application: The GnomeVFSMimeApplication to be freed
1706 * Frees a GnomeVFSMimeApplication *.
1710 gnome_vfs_mime_application_free (GnomeVFSMimeApplication *application)
1712 if (application != NULL) {
1713 g_free (application->name);
1714 g_free (application->command);
1715 g_list_foreach (application->supported_uri_schemes,
1718 g_list_free (application->supported_uri_schemes);
1719 g_free (application->id);
1720 g_free (application);
1725 * gnome_vfs_mime_action_free:
1726 * @action: The GnomeVFSMimeAction to be freed
1728 * Frees a GnomeVFSMimeAction *.
1732 gnome_vfs_mime_action_free (GnomeVFSMimeAction *action)
1734 switch (action->action_type) {
1735 case GNOME_VFS_MIME_ACTION_TYPE_APPLICATION:
1736 gnome_vfs_mime_application_free (action->action.application);
1738 case GNOME_VFS_MIME_ACTION_TYPE_COMPONENT:
1739 CORBA_free (action->action.component);
1742 g_assert_not_reached ();
1749 * gnome_vfs_mime_application_list_free:
1750 * @list: a GList of GnomeVFSApplication * to be freed
1752 * Frees lists of GnomeVFSApplications, as returned from functions such
1753 * as gnome_vfs_get_all_applications().
1757 gnome_vfs_mime_application_list_free (GList *list)
1759 g_list_foreach (list, (GFunc) gnome_vfs_mime_application_free, NULL);
1764 * gnome_vfs_mime_component_list_free:
1765 * @list: a GList of Bonobo_ServerInfo * to be freed
1767 * Frees lists of Bonobo_ServerInfo * (as returned from functions such
1768 * as @gnome_vfs_get_all_components)
1772 gnome_vfs_mime_component_list_free (GList *list)
1774 g_list_foreach (list, (GFunc) CORBA_free, NULL);
1779 * gnome_vfs_mime_application_new_from_id:
1780 * @id: A const char * containing an application id
1782 * Fetches the GnomeVFSMimeApplication associated with the specified
1783 * application ID from the MIME database.
1785 * Return value: GnomeVFSMimeApplication * corresponding to @id
1787 GnomeVFSMimeApplication *
1788 gnome_vfs_mime_application_new_from_id (const char *id)
1790 return gnome_vfs_application_registry_get_mime_application (id);
1794 * gnome_vfs_mime_action_launch:
1795 * @action: the GnomeVFSMimeAction to launch
1796 * @uris: parameters for the GnomeVFSMimeAction
1798 * Launches the given mime action with the given parameters. If
1799 * the action is an application the command line parameters will
1800 * be expanded as required by the application. The application
1801 * will also be launched in a terminal if that is required. If the
1802 * application only supports one argument per instance then multile
1803 * instances of the application will be launched.
1805 * If the default action is a component it will be launched with
1806 * the component viewer application defined using the gconf value:
1807 * /desktop/gnome/application/component_viewer/exec. The parameters
1808 * %s and %c in the command line will be replaced with the list of
1809 * parameters and the default component IID respectively.
1811 * Return value: GNOME_VFS_OK if the action was launched,
1812 * GNOME_VFS_ERROR_BAD_PARAMETERS for an invalid action.
1813 * GNOME_VFS_ERROR_NOT_SUPPORTED if the uri protocol is
1814 * not supported by the action.
1815 * GNOME_VFS_ERROR_PARSE if the action command can not be parsed.
1816 * GNOME_VFS_ERROR_LAUNCH if the action command can not be launched.
1817 * GNOME_VFS_ERROR_INTERNAL for other internal and GConf errors.
1822 gnome_vfs_mime_action_launch (GnomeVFSMimeAction *action,
1825 return gnome_vfs_mime_action_launch_with_env (action, uris, NULL);
1829 * gnome_vfs_mime_action_launch_with_env:
1831 * Same as gnome_vfs_mime_action_launch except that the
1832 * application or component viewer will be launched with
1833 * the given environment.
1835 * Return value: same as gnome_vfs_mime_action_launch
1840 gnome_vfs_mime_action_launch_with_env (GnomeVFSMimeAction *action,
1844 GnomeVFSResult result;
1848 g_return_val_if_fail (action != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
1849 g_return_val_if_fail (uris != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
1851 switch (action->action_type) {
1852 case GNOME_VFS_MIME_ACTION_TYPE_APPLICATION:
1854 return gnome_vfs_mime_application_launch_with_env
1855 (action->action.application,
1858 case GNOME_VFS_MIME_ACTION_TYPE_COMPONENT:
1860 result = expand_parameters (action->action.component, action->action_type,
1861 uris, &argc, &argv);
1863 if (result != GNOME_VFS_OK) {
1867 if (!g_spawn_async (NULL /* working directory */,
1870 G_SPAWN_SEARCH_PATH /* flags */,
1871 NULL /* child_setup */,
1873 NULL /* child_pid */,
1874 NULL /* error */)) {
1876 return GNOME_VFS_ERROR_LAUNCH;
1880 return GNOME_VFS_OK;
1883 g_assert_not_reached ();
1886 return GNOME_VFS_ERROR_BAD_PARAMETERS;
1890 * gnome_vfs_mime_application_launch:
1891 * @app: the GnomeVFSMimeApplication to launch
1892 * @uris: parameters for the GnomeVFSMimeApplication
1894 * Launches the given mime application with the given parameters.
1895 * Command line parameters will be expanded as required by the
1896 * application. The application will also be launched in a terminal
1897 * if that is required. If the application only supports one argument
1898 * per instance then multiple instances of the application will be
1902 * GNOME_VFS_OK if the application was launched.
1903 * GNOME_VFS_ERROR_NOT_SUPPORTED if the uri protocol is not
1904 * supported by the application.
1905 * GNOME_VFS_ERROR_PARSE if the application command can not
1907 * GNOME_VFS_ERROR_LAUNCH if the application command can not
1909 * GNOME_VFS_ERROR_INTERNAL for other internal and GConf errors.
1914 gnome_vfs_mime_application_launch (GnomeVFSMimeApplication *app,
1917 return gnome_vfs_mime_application_launch_with_env (app, uris, NULL);
1921 * gnome_vfs_mime_application_launch_with_env:
1923 * Same as gnome_vfs_mime_application_launch except that
1924 * the application will be launched with the given environment.
1926 * Return value: same as gnome_vfs_mime_application_launch
1931 gnome_vfs_mime_application_launch_with_env (GnomeVFSMimeApplication *app,
1935 GnomeVFSResult result;
1941 g_return_val_if_fail (app != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
1942 g_return_val_if_fail (uris != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
1944 /* check that all uri schemes are supported */
1945 if (app->supported_uri_schemes != NULL) {
1946 for (u = uris; u != NULL; u = u->next) {
1948 scheme = gnome_vfs_get_uri_scheme (u->data);
1950 if (!g_list_find_custom (app->supported_uri_schemes,
1951 scheme, (GCompareFunc) strcmp)) {
1953 return GNOME_VFS_ERROR_NOT_SUPPORTED;
1960 while (uris != NULL) {
1962 result = expand_parameters (app, GNOME_VFS_MIME_ACTION_TYPE_APPLICATION,
1963 uris, &argc, &argv);
1965 if (result != GNOME_VFS_OK) {
1969 if (app->requires_terminal) {
1970 if (!_gnome_vfs_prepend_terminal_to_vector (&argc, &argv)) {
1972 return GNOME_VFS_ERROR_INTERNAL;
1976 if (!g_spawn_async (NULL /* working directory */,
1979 G_SPAWN_SEARCH_PATH /* flags */,
1980 NULL /* child_setup */,
1982 NULL /* child_pid */,
1983 NULL /* error */)) {
1985 return GNOME_VFS_ERROR_LAUNCH;
1991 if (app->can_open_multiple_files) {
1996 return GNOME_VFS_OK;
1999 static GnomeVFSResult
2000 expand_parameters (gpointer action,
2001 GnomeVFSMimeActionType type,
2006 GnomeVFSMimeApplication *app = NULL;
2007 Bonobo_ServerInfo *server = NULL;
2008 GConfClient *client;
2010 char *command = NULL;
2011 char **c_argv, **r_argv;
2012 int c_argc, max_r_argc;
2016 /* figure out what command to parse */
2018 case GNOME_VFS_MIME_ACTION_TYPE_APPLICATION:
2019 app = (GnomeVFSMimeApplication *) action;
2020 command = app->command;
2023 case GNOME_VFS_MIME_ACTION_TYPE_COMPONENT:
2024 if (!gconf_is_initialized ()) {
2025 if (!gconf_init (0, NULL, NULL)) {
2026 return GNOME_VFS_ERROR_INTERNAL;
2030 client = gconf_client_get_default ();
2031 g_return_val_if_fail (client != NULL, GNOME_VFS_ERROR_INTERNAL);
2033 command = gconf_client_get_string (client, GCONF_DEFAULT_VIEWER_EXEC_PATH, NULL);
2034 g_object_unref (client);
2036 if (command != NULL) {
2037 g_warning ("No default component viewer set\n");
2038 return GNOME_VFS_ERROR_INTERNAL;
2041 server = (Bonobo_ServerInfo *) action;
2046 g_assert_not_reached ();
2049 if (!g_shell_parse_argv (command,
2053 return GNOME_VFS_ERROR_PARSE;
2056 /* figure out how many parameters we can max have */
2057 max_r_argc = g_list_length (uris) + c_argc + 1;
2058 r_argv = g_new0 (char *, max_r_argc + 1);
2062 for (c = 0; c < c_argc; c++) {
2063 /* replace %s with the uri parameters */
2064 if (strcmp (c_argv[c], "%s") == 0) {
2065 while (uris != NULL) {
2067 switch (app->expects_uris) {
2068 case GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS:
2069 r_argv[i] = g_strdup (uris->data);
2072 case GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_PATHS:
2073 r_argv[i] = gnome_vfs_get_local_path_from_uri (uris->data);
2074 if (r_argv[i] == NULL) {
2075 g_strfreev (c_argv);
2076 g_strfreev (r_argv);
2077 return GNOME_VFS_ERROR_NOT_SUPPORTED;
2081 case GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS_FOR_NON_FILES:
2082 /* this really means use URIs for non local files */
2083 path = gnome_vfs_get_local_path_from_uri (uris->data);
2088 r_argv[i] = g_strdup (uris->data);
2094 g_assert_not_reached ();
2097 r_argv[i] = g_strdup (uris->data);
2102 if (app != NULL && !app->can_open_multiple_files) {
2108 /* replace %c with the component iid */
2109 } else if (server != NULL && strcmp (c_argv[c], "%c") == 0) {
2110 r_argv[i++] = g_strdup (server->iid);
2113 /* otherwise take arg from command */
2115 r_argv[i++] = g_strdup (c_argv[c]);
2118 g_strfreev (c_argv);
2120 /* if there is no %s or %c, append the parameters to the end */
2122 while (uris != NULL) {
2124 switch (app->expects_uris) {
2125 case GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS:
2126 r_argv[i] = g_strdup (uris->data);
2129 case GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_PATHS:
2130 r_argv[i] = gnome_vfs_get_local_path_from_uri (uris->data);
2131 if (r_argv[i] == NULL) {
2132 g_strfreev (r_argv);
2133 return GNOME_VFS_ERROR_NOT_SUPPORTED;
2137 case GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS_FOR_NON_FILES:
2138 /* this really means use URIs for non local files */
2139 path = gnome_vfs_get_local_path_from_uri (uris->data);
2144 r_argv[i] = g_strdup (uris->data);
2150 g_assert_not_reached ();
2153 r_argv[i] = g_strdup (uris->data);
2158 if (app != NULL && !app->can_open_multiple_files) {
2167 return GNOME_VFS_OK;
2171 application_known_to_be_nonexistent (const char *application_id)
2173 const char *command;
2175 g_return_val_if_fail (application_id != NULL, FALSE);
2177 command = gnome_vfs_application_registry_peek_value
2179 GNOME_VFS_APPLICATION_REGISTRY_COMMAND);
2181 if (command == NULL) {
2185 return !gnome_vfs_is_executable_command_string (command);
2189 prune_ids_for_nonexistent_applications (GList *list)
2193 for (p = list; p != NULL; p = next) {
2196 if (application_known_to_be_nonexistent (p->data)) {
2197 list = g_list_remove_link (list, p);
2207 Bonobo_ServerInfoList_to_ServerInfo_g_list (Bonobo_ServerInfoList *info_list)
2213 if (info_list != NULL && info_list->_length > 0) {
2214 for (i = 0; i < info_list->_length; i++) {
2215 retval = g_list_prepend (retval, Bonobo_ServerInfo_duplicate (&info_list->_buffer[i]));
2217 retval = g_list_reverse (retval);
2224 strsplit_handle_null (const char *str, const char *delim, int max)
2226 return g_strsplit ((str == NULL ? "" : str), delim, max);
2230 strsplit_to_list (const char *str, const char *delim, int max)
2236 strv = strsplit_handle_null (str, delim, max);
2240 for (i = 0; strv[i] != NULL; i++) {
2241 retval = g_list_prepend (retval, strv[i]);
2244 retval = g_list_reverse (retval);
2246 /* Don't strfreev, since we didn't copy the individual strings. */
2253 strjoin_from_list (const char *separator, GList *list)
2260 strv = g_new0 (char *, (g_list_length (list) + 1));
2262 for (p = list, i = 0; p != NULL; p = p->next, i++) {
2266 retval = g_strjoinv (separator, strv);
2274 comma_separated_str_to_str_list (const char *str)
2276 return strsplit_to_list (str, ",", 0);
2280 str_list_to_comma_separated_str (GList *list)
2282 return strjoin_from_list (",", list);
2286 str_list_difference (GList *a, GList *b)
2288 GList *node, *result;
2290 /* Uses an N^2 algorithm rather than a more efficient one
2291 * that sorts or creates a hash table.
2296 for (node = a; node != NULL; node = node->next) {
2297 if (g_list_find_custom (b, node->data, (GCompareFunc) strcmp) == NULL) {
2298 result = g_list_prepend (result, node->data);
2302 return g_list_reverse (result);
2306 copy_str_list (GList *string_list)
2311 for (node = string_list; node != NULL; node = node->next) {
2312 copy = g_list_prepend (copy,
2313 g_strdup ((char *) node->data));
2315 return g_list_reverse (copy);
2319 gnome_vfs_mime_maybe_get_user_level_value (const char *mime_type, const char *key)
2321 const char *return_value;
2324 /* This function checks for a key and falls back
2325 * to the "advanced" user level preference if the key
2329 return_value = gnome_vfs_mime_get_value (mime_type, key);
2331 if (return_value != NULL) {
2332 return return_value;
2335 new_key = g_strconcat (key, "_for_advanced_user_level", NULL);
2336 return_value = gnome_vfs_mime_get_value (mime_type, new_key);
2339 return return_value;