diff --git a/capplets/file-types/ChangeLog b/capplets/file-types/ChangeLog index 624010cbd..e295e3c4a 100644 --- a/capplets/file-types/ChangeLog +++ b/capplets/file-types/ChangeLog @@ -1,3 +1,7 @@ +2002-01-04 Bradford Hovinen + + * Makefile.am: Clean up + 2001-12-09 Havoc Pennington * file-types-capplet.c: remove no-longer-existing header diff --git a/capplets/file-types/Makefile.am b/capplets/file-types/Makefile.am index 2c412b2de..92f5289bb 100644 --- a/capplets/file-types/Makefile.am +++ b/capplets/file-types/Makefile.am @@ -1,34 +1,25 @@ SUBDIRS = libuuid -cappletname = file-types -cappletgroup = "Advanced/" -bin_PROGRAMS = file-types-capplet +bin_PROGRAMS = gnome-file-types-properties -file_types_capplet_LDADD = $(VFS_CAPPLET_LIBS) libuuid/libuuid.a +gnome_file_types_properties_LDADD = $(GNOMECC_CAPPLETS_LIBS) $(VFS_CAPPLET_LIBS) libuuid/libuuid.a -file_types_capplet_SOURCES = \ - file-types-capplet.h \ - file-types-capplet-dialogs.h \ - file-types-icon-entry.h \ - file-types-capplet.c \ - file-types-capplet-dialogs.c \ - file-types-icon-entry.c +gnome_file_types_properties_SOURCES = \ + file-types-capplet.c \ + mime-types-model.c mime-types-model.h \ + mime-type-info.c mime-type-info.h \ + mime-edit-dialog.c mime-edit-dialog.h \ + service-info.c service-info.h \ + service-edit-dialog.c service-edit-dialog.h -pixmap_DATA = - -## -## You should not need to modify anything below this line -## @INTLTOOL_DESKTOP_RULE@ -@GNOMECC_CAPPLETS_DESKTOP_IN_RULE@ + +Gladedir = $(GNOMECC_DATA_DIR)/interfaces +Glade_DATA = file-types-properties.glade + +desktopdir = $(GNOMECC_DATA_DIR)/capplets/Advanced +desktop_DATA = file-types.desktop INCLUDES = $(GNOMECC_CAPPLETS_CFLAGS) $(VFS_CAPPLET_CFLAGS) CLEANFILES = $(GNOMECC_CAPPLETS_CLEANFILES) -EXTRA_DIST = $(GNOMECC_CAPPLETS_EXTRA_DIST) -iconsdir = $(GNOMECC_ICONS_DIR) -Gladedir = $(GNOMECC_GLADE_DIR) -pixmapdir = $(GNOMECC_PIXMAPS_DIR) -Glade_DATA = $(cappletname)-properties.glade -icons_DATA = $(cappletname)-capplet.png -desktop = $(cappletname).desktop -all-local: $(desktop) +EXTRA_DIST = $(Glade_DATA) $(desktop_DATA) diff --git a/capplets/file-types/TODO_NOTES b/capplets/file-types/TODO_NOTES new file mode 100644 index 000000000..f80a62546 --- /dev/null +++ b/capplets/file-types/TODO_NOTES @@ -0,0 +1,9 @@ + - Get icon name (esp. use of stock icons) working correctly + - Add categories to many types in MIME database + - Do dialog for Internet service + - Validation + - Talk to gnome-vfs people about categories, edit and print lines, custom line, gnome-vfs-mime-info.h install + - Do something better about custom-line (i.e. create a dummy app in the app register) + - Make MIME types tree accept double clicks + - Implement tree cascading + - Fix gnome_url_show diff --git a/capplets/file-types/file-types-capplet.c b/capplets/file-types/file-types-capplet.c index 46a4a93a3..a466b1ca2 100644 --- a/capplets/file-types/file-types-capplet.c +++ b/capplets/file-types/file-types-capplet.c @@ -1,10 +1,11 @@ /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* nautilus-mime-type-capplet.h +/* file-types-capplet.h * * Copyright (C) 1998 Redhat Software Inc. * Copyright (C) 2000 Free Software Foundaton * Copyright (C) 2000 Eazel, Inc. + * Copyright (C) 2002 Ximian, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -21,2014 +22,165 @@ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * - * Authors: Jonathan Blandford - * Gene Z. Ragan + * Authors: Jonathan Blandford , + * Gene Z. Ragan , + * Bradford Hovinen */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "file-types-capplet-dialogs.h" -#include "file-types-icon-entry.h" - -#include "file-types-capplet.h" - -#define DEFAULT_REGULAR_ICON "nautilus/i-regular-24.png" -#define DEFAULT_ACTION_ICON "nautilus/i-executable.png" - -#define MAX_ICON_WIDTH_IN_LIST 18 -#define MAX_ICON_HEIGHT_IN_LIST 18 - -enum { - COLUMN_DESCRIPTION = 0, - COLUMN_MIME_TYPE, - COLUMN_EXTENSION, - COLUMN_ACTION, - TOTAL_COLUMNS -}; - -/* Local Prototypes */ -static void init_mime_capplet (const char *scroll_to_mime_type); -static void populate_application_menu (GtkWidget *menu, - const char *mime_string); -static void populate_viewer_menu (GtkWidget *menu, - const char *mime_string); -static void revert_mime_clicked (GtkWidget *widget, - gpointer data); -static void delete_mime_clicked (GtkWidget *widget, - gpointer data); -static void add_mime_clicked (GtkWidget *widget, - gpointer data); -static void edit_default_clicked (GtkWidget *widget, - gpointer data); -static GtkWidget *create_mime_list_and_scroller (void); -static void response_cb (GtkDialog *dialog, - GtkResponseType r, - gpointer data); -static void gtk_widget_make_bold (GtkWidget *widget); -static GdkFont *gdk_font_get_bold (const GdkFont *plain_font); -static void gtk_widget_set_font (GtkWidget *widget, - GdkFont *font); -static GdkPixbuf *capplet_gdk_pixbuf_scale_to_fit (GdkPixbuf *pixbuf, - int max_width, - int max_height); -static void update_mime_list_action (const char *mime_string); -static void populate_mime_list (GList *type_list, - GtkCList *clist); -static GdkPixbuf *capplet_get_icon_pixbuf (const char *mime_string, - gboolean is_executable); - - -/* FIXME: Using global variables here is yucky */ -GtkWidget *capplet; -GtkWidget *delete_button; -GtkWidget *remove_button; -GtkWidget *add_button; -GtkWidget *icon_entry, *extension_list, *mime_list; -GtkWidget *default_menu; -GtkWidget *application_button, *viewer_button; -GtkLabel *mime_label; -GtkWidget *description_entry; -gboolean description_has_changed; -gboolean sort_column_clicked [TOTAL_COLUMNS]; - -/* - * main - * - * Display capplet - */ - -#define MATHIEU_DEBUG - -#ifdef MATHIEU_DEBUG -#include - -static void -nautilus_stop_in_debugger (void) -{ - void (* saved_handler) (int); - - saved_handler = signal (SIGINT, SIG_IGN); - raise (SIGINT); - signal (SIGINT, saved_handler); -} - -static void -nautilus_stop_after_default_log_handler (const char *domain, - GLogLevelFlags level, - const char *message, - gpointer data) -{ - g_log_default_handler (domain, level, message, data); - nautilus_stop_in_debugger (); -} - -static void -nautilus_set_stop_after_default_log_handler (const char *domain) -{ - g_log_set_handler (domain, G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING, - nautilus_stop_after_default_log_handler, NULL); -} - -static void -nautilus_make_warnings_and_criticals_stop_in_debugger (const char *first_domain, ...) -{ - va_list domains; - const char *domain; - - nautilus_set_stop_after_default_log_handler (first_domain); - - va_start (domains, first_domain); - - for (;;) { - domain = va_arg (domains, const char *); - if (domain == NULL) { - break; - } - nautilus_set_stop_after_default_log_handler (domain); - } - - va_end (domains); -} -#endif /* MATHIEU_DEBUG */ - -int -main (int argc, char **argv) -{ - int init_results; - char *mime_type; - - mime_type = NULL; - - /* */ - if (argc >= 1) { - mime_type = g_strdup (argv[1]); - } - - bindtextdomain (PACKAGE, GNOMELOCALEDIR); - bind_textdomain_codeset (PACKAGE, "UTF-8"); - textdomain (PACKAGE); - - - gnome_program_init ("file-types-capplet", VERSION, - LIBGNOMEUI_MODULE, argc, argv, NULL); - - gnome_vfs_init (); - - init_mime_capplet (mime_type); - gtk_main (); - - return 0; -} - -static void -response_cb (GtkDialog *dialog, GtkResponseType response, gpointer data) -{ - switch (response) - { - case GTK_RESPONSE_NONE: - case GTK_RESPONSE_CLOSE: - gtk_main_quit (); - break; - } -} - -static void -populate_extension_list (const char *mime_type, GtkCList *list) -{ - GList *extensions, *element; - gchar *extension[1]; - gint row; - - if (mime_type == NULL || list == NULL) { - return; - } - - /* Clear out old items */ - gtk_clist_clear (list); - - extensions = gnome_vfs_mime_get_extensions_list (mime_type); - if (extensions == NULL) { - return; - } - - for (element = extensions; element != NULL; element = element->next) { - extension[0] = (char *)element->data; - if (strlen (element->data) > 0) { - row = gtk_clist_append (list, extension); - - /* Set to deletable */ - gtk_clist_set_row_data (list, row, GINT_TO_POINTER (FALSE)); - } - } - - gnome_vfs_mime_extensions_list_free (extensions); - - /* Select first item in extension list */ - gtk_clist_select_row (list, 0, 0); -} - -void -nautilus_mime_type_capplet_add_extension (const char *extension) -{ - gchar *title[1]; - gchar *token, *search_string; - gint rownumber; - const char *mime_type; - - /* Check for empty string */ - if (strlen (extension) <= 0) { - return; - } - - /* Copy only contiguous part of string. No spaces allowed. */ - search_string = g_strdup (extension); - token = strtok (search_string, " "); - - if (token == NULL) { - title[0] = g_strdup (extension); - } else if (strlen (token) <= 0) { - return; - } else { - title[0] = g_strdup (token); - } - g_free (search_string); - - rownumber = gtk_clist_append (GTK_CLIST (extension_list), title); - gtk_clist_set_row_data (GTK_CLIST (extension_list), rownumber, - GINT_TO_POINTER (TRUE)); - - mime_type = nautilus_mime_type_capplet_get_selected_item_mime_type (); - g_assert (mime_type != NULL); - gnome_vfs_mime_add_extension (mime_type, extension); - - /* Select new item in list */ - gtk_clist_select_row (GTK_CLIST (extension_list), rownumber, 0); - -} - - -static void -mime_list_selected_row_callback (GtkWidget *widget, gint row, gint column, GdkEvent *event, gpointer data) -{ - const char *mime_type; - - mime_type = (const char *) gtk_clist_get_row_data (GTK_CLIST (widget),row); - - /* Update info on selection */ - nautilus_mime_type_capplet_update_info (mime_type); -} - -static void -application_button_toggled (GtkToggleButton *button, gpointer user_data) -{ - const char *mime_type; - - if (gtk_toggle_button_get_active (button)) { - - mime_type = nautilus_mime_type_capplet_get_selected_item_mime_type (); - - gnome_vfs_mime_set_default_action_type (mime_type, GNOME_VFS_MIME_ACTION_TYPE_APPLICATION); - - /* Populate menu with application items */ - populate_application_menu (default_menu, mime_type); - - /* Update mime list */ - update_mime_list_action (mime_type); - } -} - -static void -viewer_button_toggled (GtkToggleButton *button, gpointer user_data) -{ - const char *mime_type; - - if (gtk_toggle_button_get_active (button)) { - mime_type = nautilus_mime_type_capplet_get_selected_item_mime_type (); - - gnome_vfs_mime_set_default_action_type (mime_type, GNOME_VFS_MIME_ACTION_TYPE_COMPONENT); - - /* Populate menu with viewer items */ - populate_viewer_menu (default_menu, mime_type); - - /* Update mime list */ - update_mime_list_action (mime_type); - } -} - -static int -get_selected_row_number (void) -{ - gint row; - - if (GTK_CLIST (mime_list)->selection == NULL) { - return -1; - } - - row = GPOINTER_TO_INT ((GTK_CLIST (mime_list)->selection)->data); - return row; -} -static const char * -get_selected_mime_type (void) -{ - gint row = 0; - const char *mime_type; - - - if (GTK_CLIST (mime_list)->selection == NULL) { - return NULL; - } - - row = get_selected_row_number (); - if (row == -1) { - return NULL; - } - - mime_type = (const char *) gtk_clist_get_row_data (GTK_CLIST (mime_list), row); - - return mime_type; -} - -static void -really_change_icon (gpointer user_data) -{ - NautilusMimeIconEntry *icon_entry; - char *filename; - const char *mime_type; - - g_assert (NAUTILUS_MIME_IS_ICON_ENTRY (user_data)); - - mime_type = get_selected_mime_type (); - if (mime_type == NULL) { - return; - } - - icon_entry = NAUTILUS_MIME_ICON_ENTRY (user_data); - - filename = nautilus_mime_type_icon_entry_get_relative_filename (icon_entry); - if (filename == NULL) { - filename = nautilus_mime_type_icon_entry_get_full_filename (icon_entry); - } - - gnome_vfs_mime_set_icon (mime_type, filename); - - nautilus_mime_type_capplet_update_mime_list_icon_and_description (mime_type); - nautilus_mime_type_capplet_update_info (mime_type); - - g_free (filename); -} - -static void -icon_chosen_callback (GnomeIconList *gil, gint num, GdkEvent *event, gpointer user_data) -{ - NautilusMimeIconEntry *icon_entry; - const gchar * icon; - GnomeIconSelection * gis; - GtkWidget *gtk_entry; - - g_return_if_fail (user_data != NULL); - g_return_if_fail (NAUTILUS_MIME_IS_ICON_ENTRY (user_data)); - - icon_entry = NAUTILUS_MIME_ICON_ENTRY (user_data); - - gis = gtk_object_get_user_data (GTK_OBJECT(icon_entry)); - icon = gnome_icon_selection_get_icon(gis, TRUE); - - if (icon != NULL) { - gtk_entry = nautilus_mime_type_icon_entry_gtk_entry(icon_entry); - gtk_entry_set_text(GTK_ENTRY(gtk_entry),icon); - - } - - if(event && event->type == GDK_2BUTTON_PRESS && ((GdkEventButton *)event)->button == 1) { - gnome_icon_selection_stop_loading(gis); - really_change_icon (user_data); - gtk_widget_hide(icon_entry->pick_dialog); - } - - -} - -static void -change_icon_clicked_cb_real (GnomeDialog *dialog, gint button_number, gpointer user_data) -{ - if (button_number == GNOME_OK) { - really_change_icon (user_data); - } -} - -static void -change_icon_clicked (GtkWidget *entry, gpointer user_data) -{ - GnomeDialog *dialog; - GnomeIconSelection * gis; - - nautilus_mime_type_show_icon_selection (NAUTILUS_MIME_ICON_ENTRY (user_data)); - - dialog = GNOME_DIALOG (NAUTILUS_MIME_ICON_ENTRY (user_data)->pick_dialog); - - gtk_signal_connect (GTK_OBJECT (dialog), "clicked", change_icon_clicked_cb_real, user_data); - - gis = gtk_object_get_user_data(GTK_OBJECT(user_data)); - gtk_signal_connect_after (GTK_OBJECT(gnome_icon_selection_get_gil(GNOME_ICON_SELECTION(gis))), - "select_icon", icon_chosen_callback, user_data); - -} - -static void -update_extensions_list (const char *mime_type) -{ - int row; - char *pretty_string; - - row = get_selected_row_number (); - - pretty_string = gnome_vfs_mime_get_extensions_pretty_string (mime_type); - if (pretty_string == NULL) { - pretty_string = g_strdup (" "); - } - gtk_clist_set_text (GTK_CLIST (mime_list), - row, 2, pretty_string); - - g_free (pretty_string); - -} - -static void -change_file_extensions_clicked (GtkWidget *widget, gpointer user_data) -{ - const char *mime_type; - char *new_extensions; - gboolean use_new_list; - - mime_type = get_selected_mime_type (); - if (mime_type == NULL) { - return; - } - - new_extensions = nautilus_mime_type_capplet_show_change_extension_window (mime_type, &use_new_list); - if (use_new_list) { - gnome_vfs_mime_set_extensions_list (mime_type, new_extensions); - } - - update_extensions_list (mime_type); -} - -/* The following are copied from gtkclist.c and nautilusclist.c */ -#define CELL_SPACING 1 - -/* gives the top pixel of the given row in context of - * the clist's voffset */ -#define ROW_TOP_YPIXEL(clist, row) (((clist)->row_height * (row)) + \ - (((row) + 1) * CELL_SPACING) + \ - (clist)->voffset) -static void -list_move_vertical (GtkCList *clist, gint row, gfloat align) -{ - gfloat value; - - g_return_if_fail (clist != NULL); - - if (!clist->vadjustment) { - return; - } - - value = (ROW_TOP_YPIXEL (clist, row) - clist->voffset - - align * (clist->clist_window_height - clist->row_height) + - (2 * align - 1) * CELL_SPACING); - - if (value + clist->vadjustment->page_size > clist->vadjustment->upper) { - value = clist->vadjustment->upper - clist->vadjustment->page_size; - } - - gtk_adjustment_set_value (clist->vadjustment, value); -} - -static void -list_moveto (GtkCList *clist, gint row, gint column, gfloat row_align, gfloat col_align) -{ - g_return_if_fail (clist != NULL); - - if (row < -1 || row >= clist->rows) { - return; - } - - if (column < -1 || column >= clist->columns) { - return; - } - - row_align = CLAMP (row_align, 0, 1); - col_align = CLAMP (col_align, 0, 1); - - /* adjust vertical scrollbar */ - if (clist->vadjustment && row >= 0) { - list_move_vertical (clist, row, row_align); - } -} - -static void -list_reveal_row (GtkCList *clist, int row_index) -{ - g_return_if_fail (row_index >= 0 && row_index < clist->rows); - - if (ROW_TOP_YPIXEL (clist, row_index) + clist->row_height > clist->clist_window_height) { - list_moveto (clist, row_index, -1, 1, 0); - } else if (ROW_TOP_YPIXEL (clist, row_index) < 0) { - list_moveto (clist, row_index, -1, 0, 0); - } -} - - - -static int -find_row_for_mime_type (const char *mime_type, GtkCList *mime_list) -{ - gboolean found_one; - int index; - const char *row_data; - - if (mime_type == NULL) { - return -1; - } - - found_one = FALSE; - - for (index = 0; index < mime_list->rows; index++) { - row_data = gtk_clist_get_row_data (mime_list, index); - if (row_data != NULL && strcmp (row_data, mime_type) == 0) { - found_one = TRUE; - break; - } - } - - if (found_one) { - return index; - } - - return -1; -} - - -static void -update_description_from_input (GtkEntry *entry) -{ - char *new_description; - const char *mime_type; - - g_assert (GTK_IS_ENTRY (entry)); - g_assert ((gpointer)entry == (gpointer)description_entry); - - description_has_changed = FALSE; - - mime_type = get_selected_mime_type (); - if (mime_type == NULL) { - return; - } - - new_description = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1); - gnome_vfs_mime_set_description (mime_type, new_description); - nautilus_mime_type_capplet_update_mime_list_icon_and_description (mime_type); - g_free (new_description); -} - -static void -description_entry_activate (GtkEntry *entry, gpointer user_data) -{ - g_assert (GTK_IS_ENTRY (entry)); - g_assert ((gpointer)entry == (gpointer)description_entry); - g_assert (user_data == NULL); - - if (description_has_changed) { - update_description_from_input (entry); - } -} - -static void -description_entry_changed (GtkEntry *entry, gpointer user_data) -{ - g_assert (GTK_IS_ENTRY (entry)); - g_assert ((gpointer)entry == (gpointer)description_entry); - g_assert (user_data == NULL); - - description_has_changed = TRUE; -} - -static gboolean -description_entry_lost_focus (GtkEntry *entry, - GdkEventFocus *event, - gpointer user_data) -{ - g_assert (GTK_IS_ENTRY (entry)); - g_assert ((gpointer)entry == (gpointer)description_entry); - g_assert (user_data == NULL); - - if (description_has_changed) { - update_description_from_input (entry); - } - - return FALSE; -} - -static void -init_mime_capplet (const char *scroll_to_mime_type) -{ - GtkWidget *main_vbox; - GtkWidget *vbox, *hbox, *left_vbox; - GtkWidget *button; - GtkWidget *mime_list_container; - GtkWidget *frame; - GtkWidget *table; - int index, list_width, column_width, found_index; - - capplet = - gtk_dialog_new_with_buttons (_("URL Handlers"), NULL, - -1, - GTK_STOCK_HELP, GTK_RESPONSE_HELP, - GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, - NULL); - - /* Main vertical box */ - main_vbox = gtk_vbox_new (FALSE, GNOME_PAD); - gtk_container_set_border_width (GTK_CONTAINER (main_vbox), GNOME_PAD_SMALL); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (capplet)->vbox), main_vbox, - TRUE, TRUE, 0); - - /* Main horizontal box and mime list */ - hbox = gtk_hbox_new (FALSE, GNOME_PAD); - gtk_box_pack_start (GTK_BOX (main_vbox), hbox, TRUE, TRUE, 0); - mime_list_container = create_mime_list_and_scroller (); - gtk_box_pack_start (GTK_BOX (hbox), mime_list_container, TRUE, TRUE, 0); - - vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL); - gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0); - - /* Create table */ - table = gtk_table_new (2, 2, FALSE); - gtk_box_pack_start (GTK_BOX (main_vbox), table, FALSE, FALSE, 0); - gtk_table_set_row_spacings (GTK_TABLE (table), GNOME_PAD_SMALL); - gtk_table_set_col_spacings (GTK_TABLE (table), GNOME_PAD_SMALL); - - - left_vbox = gtk_vbox_new (FALSE, 0); - /* Set up top left area. */ - { - GtkWidget *small_table; - - small_table = gtk_table_new (1, 2, FALSE); - gtk_table_set_col_spacings (GTK_TABLE (small_table), 7); - - gtk_table_attach ( GTK_TABLE (table), small_table, 0, 1, 0, 1, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - - icon_entry = nautilus_mime_type_icon_entry_new ("mime_icon_entry", NULL); - gtk_table_attach (GTK_TABLE (small_table), icon_entry, 0, 1, 0, 1, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - - vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL); - gtk_table_attach (GTK_TABLE (small_table), vbox, 1, 2, 0, 1, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (GTK_FILL), 0, 0); - - description_entry = gtk_entry_new (); - description_has_changed = FALSE; - gtk_box_pack_start (GTK_BOX (vbox), description_entry, FALSE, FALSE, 0); - gtk_widget_make_bold (GTK_WIDGET (description_entry)); - - gtk_signal_connect (GTK_OBJECT (description_entry), "activate", - GTK_SIGNAL_FUNC (description_entry_activate), - NULL); - - gtk_signal_connect (GTK_OBJECT (description_entry), "changed", - GTK_SIGNAL_FUNC (description_entry_changed), - NULL); - - gtk_signal_connect (GTK_OBJECT (description_entry), "focus_out_event", - GTK_SIGNAL_FUNC (description_entry_lost_focus), - NULL); - - hbox = gtk_hbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (hbox), FALSE, FALSE, 0); - - mime_label = GTK_LABEL (gtk_label_new (_("MIME Type"))); - gtk_label_set_justify (GTK_LABEL (mime_label), GTK_JUSTIFY_LEFT); - gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (mime_label), FALSE, FALSE, 0); - - hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - - button = gtk_button_new_with_label (_("Change Icon")); - gtk_signal_connect (GTK_OBJECT (button), "clicked", change_icon_clicked, icon_entry); - gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); - - /* spacer */ - gtk_box_pack_start (GTK_BOX (hbox), gtk_vbox_new (FALSE, 0), FALSE, FALSE, 10); - - button = gtk_button_new_with_label (_("Change File Extensions")); - gtk_signal_connect (GTK_OBJECT (button), "clicked", change_file_extensions_clicked, NULL); - gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); - - } - - /* Set up bottom left area. */ - { - frame = gtk_frame_new (_("Default Action:")); - gtk_table_attach ( GTK_TABLE (table), frame, 0, 1, 1, 2, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - - vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL); - gtk_container_add (GTK_CONTAINER (frame), vbox); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 5); - - hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - - viewer_button = gtk_radio_button_new_with_label (NULL, _("Use Viewer")); - gtk_box_pack_start (GTK_BOX (hbox), viewer_button, FALSE, FALSE, 0); - gtk_signal_connect (GTK_OBJECT (viewer_button), "toggled", - GTK_SIGNAL_FUNC (viewer_button_toggled), NULL); - - application_button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (viewer_button), - _("Open With Application")); - gtk_box_pack_start (GTK_BOX (hbox), application_button, FALSE, FALSE, 0); - gtk_signal_connect (GTK_OBJECT (application_button), "toggled", - GTK_SIGNAL_FUNC (application_button_toggled), NULL); - - hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - - default_menu = gtk_option_menu_new(); - gtk_box_pack_start (GTK_BOX (hbox), default_menu, TRUE, TRUE, 0); - - button = gtk_button_new_with_label (_("Edit List")); - gtk_misc_set_padding (GTK_MISC (GTK_BIN(button)->child), 2, 1); - gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); - gtk_signal_connect (GTK_OBJECT (button), "clicked", edit_default_clicked, mime_list); - } - - /* Set up top right area. */ - { - GtkWidget *separator; - GtkWidget *small_table; - - hbox = gtk_hbox_new (FALSE, 0); - gtk_table_attach_defaults ( GTK_TABLE (table), hbox, 1, 2, 0, 1); - - small_table = gtk_table_new (5, 1, FALSE); - gtk_table_set_row_spacings (GTK_TABLE (small_table), 7); - gtk_box_pack_end (GTK_BOX (hbox), small_table, FALSE, FALSE, 0); - - /* Placed to space top button with top of left table */ - hbox = gtk_hbox_new (FALSE, 0); - gtk_table_attach (GTK_TABLE (small_table), hbox, 0, 1, 0, 1, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_widget_set_usize (hbox, 1, 11); - - button = gtk_button_new_with_label (_("Add New MIME Type...")); - gtk_signal_connect (GTK_OBJECT (button), "clicked", add_mime_clicked, NULL); - gtk_table_attach (GTK_TABLE (small_table), button, 0, 1, 1, 2, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - - button = gtk_button_new_with_label (_("Delete This MIME Type")); - gtk_signal_connect (GTK_OBJECT (button), "clicked", delete_mime_clicked, NULL); - gtk_table_attach (GTK_TABLE (small_table), button, 0, 1, 2, 3, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - - separator = gtk_hseparator_new (); - gtk_table_attach (GTK_TABLE (small_table), separator, 0, 1, 3, 4, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (GTK_FILL), 0, 0); - - button = gtk_button_new_with_label (_("Revert to System Defaults")); - gtk_signal_connect (GTK_OBJECT (button), "clicked", revert_mime_clicked, NULL); - gtk_table_attach (GTK_TABLE (small_table), button, 0, 1, 4, 5, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - - } - - /* Yes, show all widgets */ - gtk_widget_show_all (capplet); - - /* Make columns all fit within capplet list view bounds */ - list_width = GTK_WIDGET (mime_list)->allocation.width; - column_width = list_width / TOTAL_COLUMNS; - for (index = 0; index < TOTAL_COLUMNS; index++) - gtk_clist_set_column_auto_resize (GTK_CLIST (mime_list), index, TRUE); -#if 0 - /* This is not working */ - for (index = 0; index < TOTAL_COLUMNS; index++) { - g_print ("Setting column %i with to %d\n", index, column_width); - gtk_clist_set_column_width (GTK_CLIST (mime_list), index, column_width); - } +#ifdef HAVE_CONFIG_H +# include "config.h" #endif - /* Setup capplet signals */ - gtk_signal_connect (GTK_OBJECT(capplet), "response", - GTK_SIGNAL_FUNC (response_cb), NULL); +#include +#include - gtk_signal_connect (GTK_OBJECT (mime_list),"select_row", - GTK_SIGNAL_FUNC (mime_list_selected_row_callback), NULL); +#include "mime-types-model.h" +#include "mime-edit-dialog.h" +#include "mime-type-info.h" +#include "service-edit-dialog.h" +#include "service-info.h" - /* Sort by description. The description is the first column in the list. */ - gtk_clist_set_sort_column (GTK_CLIST (mime_list), COLUMN_DESCRIPTION); - gtk_clist_sort (GTK_CLIST (mime_list)); - GTK_CLIST (mime_list)->sort_type = GTK_SORT_ASCENDING; +#define WID(x) (glade_xml_get_widget (dialog, x)) - /* Set up initial column click tracking state. We do this so the initial clicks on - * columns will allow us to set the proper sort state for the user. - */ - sort_column_clicked[0] = TRUE; /* First sort column has been click by us in setup code */ - for (index = 1; index < TOTAL_COLUMNS; index++) { - sort_column_clicked[index] = FALSE; - } - - /* Attempt to select specified mime type in list */ - if (scroll_to_mime_type != NULL) { - found_index = find_row_for_mime_type (scroll_to_mime_type, GTK_CLIST (mime_list)); - if (found_index != -1) { - gtk_clist_select_row (GTK_CLIST (mime_list), found_index, 1); - list_reveal_row (GTK_CLIST (mime_list), found_index); - } else { - gtk_clist_select_row (GTK_CLIST (mime_list), 0, 1); - list_reveal_row (GTK_CLIST (mime_list), 0); - } - } else { - gtk_clist_select_row (GTK_CLIST (mime_list), 0, 0); - list_reveal_row (GTK_CLIST (mime_list), 0); - } -} +static GList *remove_list = NULL; -static gboolean -is_full_path (const char *path_or_name) +static void +add_cb (GtkButton *button, GladeXML *dialog) { - return path_or_name[0] == '/'; -} + GObject *add_dialog; -static char * -capplet_get_icon_path (const char *path_or_name) -{ - char *result; - char *alternate_relative_filename; - - if (is_full_path (path_or_name) && g_file_exists (path_or_name)) { - return g_strdup (path_or_name); - } - - result = gnome_vfs_icon_path_from_filename (path_or_name); - if (result != NULL) { - return result; - } - - /* FIXME bugzilla.eazel.com 639: - * It is somewhat evil to special-case the nautilus directory here. - * We should clean this up if/when we come up with a way to handle - * Nautilus themes here. - */ - alternate_relative_filename = g_strconcat ("nautilus/", path_or_name, NULL); - result = gnome_vfs_icon_path_from_filename (alternate_relative_filename); - g_free (alternate_relative_filename); - if (result != NULL) { - return result; - } - - /* FIXME bugzilla.eazel.com 639: - * To work correctly with Nautilus themed icons, if there's no - * suffix we will also try looking in the nautilus dir for a ".png" name. - * This will return the icon for the default theme; there is no - * mechanism for getting a themed icon in the capplet. - */ - alternate_relative_filename = g_strconcat ("nautilus/", path_or_name, ".png", NULL); - result = gnome_vfs_icon_path_from_filename (alternate_relative_filename); - g_free (alternate_relative_filename); - - return result; -} - -/* - * nautilus_mime_type_capplet_update_info - * - * Update controls with info based on mime type - */ - -void -nautilus_mime_type_capplet_update_info (const char *mime_type) { - - GnomeVFSMimeAction *action; - const char *icon_name, *description; - char *path; - - /* Update text items */ - gtk_label_set_text (GTK_LABEL (mime_label), mime_type); - - description = gnome_vfs_mime_get_description (mime_type); - gtk_entry_set_text (GTK_ENTRY (description_entry), description != NULL ? description : ""); - description_has_changed = FALSE; - - /* Update menus */ - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (application_button))) { - populate_application_menu (default_menu, mime_type); - } else { - populate_viewer_menu (default_menu, mime_type); - } - - /* Update extensions list */ - if (extension_list != NULL) { - populate_extension_list (mime_type, GTK_CLIST (extension_list)); - } - - /* Set icon for mime type */ - icon_name = gnome_vfs_mime_get_icon (mime_type); - path = NULL; - if (icon_name != NULL) { - path = capplet_get_icon_path (icon_name); - } - if (path == NULL) { - /* No custom icon specified, or custom icon not found, use default */ - path = capplet_get_icon_path (DEFAULT_REGULAR_ICON); - } - nautilus_mime_type_icon_entry_set_icon (NAUTILUS_MIME_ICON_ENTRY (icon_entry), path); - g_free (path); - - /* Indicate default action */ - action = gnome_vfs_mime_get_default_action (mime_type); - if (action != NULL) { - switch (action->action_type) { - case GNOME_VFS_MIME_ACTION_TYPE_APPLICATION: - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (application_button), TRUE); - break; - - case GNOME_VFS_MIME_ACTION_TYPE_COMPONENT: - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (viewer_button), TRUE); - break; - - default: - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (application_button), TRUE); - break; - } - } else { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (application_button), TRUE); - } - -} - -static void -application_menu_activated (GtkWidget *menu_item, gpointer data) -{ - const char *id; - const char *mime_type; - - /* Get our stashed data */ - id = gtk_object_get_data (GTK_OBJECT (menu_item), "id"); - mime_type = gtk_object_get_data (GTK_OBJECT (menu_item), "mime_type"); - - if (id == NULL || mime_type == NULL) { - return; - } - gnome_vfs_mime_set_default_application (mime_type, id); - update_mime_list_action (mime_type); + add_dialog = mime_add_dialog_new (); } static void -populate_application_menu (GtkWidget *application_menu, const char *mime_type) +edit_cb (GtkButton *button, GladeXML *dialog) { - GtkWidget *new_menu, *menu_item; - GList *app_list, *copy_list; - GnomeVFSMimeApplication *default_app, *application; - gboolean has_none, found_match; - char *mime_copy; - const char *id; - GList *children; - int index; + GtkTreeView *treeview; + GtkTreeModel *model; + GtkTreeSelection *selection; + GtkTreeIter iter; + GValue mime_type; - has_none = TRUE; - found_match = FALSE; + GObject *edit_dialog; - mime_copy = g_strdup (mime_type); - - new_menu = gtk_menu_new (); - - /* Get the default application */ - default_app = gnome_vfs_mime_get_default_application (mime_type); + treeview = GTK_TREE_VIEW (WID ("mime_types_tree")); + selection = gtk_tree_view_get_selection (treeview); + gtk_tree_selection_get_selected (selection, &model, &iter); - /* Get the application short list */ - app_list = gnome_vfs_mime_get_short_list_applications (mime_type); - if (app_list != NULL) { - for (copy_list = app_list; copy_list != NULL; copy_list = copy_list->next) { - has_none = FALSE; + mime_type.g_type = G_TYPE_INVALID; + gtk_tree_model_get_value (model, &iter, MIME_TYPE_COLUMN, &mime_type); - application = copy_list->data; - menu_item = gtk_menu_item_new_with_label (application->name); + if (model_entry_is_protocol (model, &iter)) + edit_dialog = service_edit_dialog_new (service_info_load (g_value_get_string (&mime_type), NULL)); + else + edit_dialog = mime_edit_dialog_new (mime_type_info_load (g_value_get_string (&mime_type))); - /* Store copy of application name and mime type in item; free when item destroyed. */ - gtk_object_set_data_full (GTK_OBJECT (menu_item), - "id", - g_strdup (application->id), - g_free); - - gtk_object_set_data_full (GTK_OBJECT (menu_item), - "mime_type", - g_strdup (mime_type), - g_free); - - gtk_menu_append (GTK_MENU (new_menu), menu_item); - gtk_widget_show (menu_item); - - gtk_signal_connect (GTK_OBJECT (menu_item), "activate", - application_menu_activated, NULL); - } - - gnome_vfs_mime_application_list_free (app_list); - } - - /* Find all applications or add a "None" item */ - if (has_none && default_app == NULL) { - menu_item = gtk_menu_item_new_with_label (_("None")); - gtk_menu_append (GTK_MENU (new_menu), menu_item); - gtk_widget_show (menu_item); - } else { - /* Check and see if default is in the short list */ - if (default_app != NULL) { - /* Iterate */ - children = gtk_container_children (GTK_CONTAINER (new_menu)); - for (index = 0; children != NULL; children = children->next, ++index) { - id = (const char *)(gtk_object_get_data (GTK_OBJECT (children->data), "id")); - if (id != NULL) { - if (strcmp (default_app->id, id) == 0) { - found_match = TRUE; - break; - } - } - } - g_list_free (children); - - /* See if we have a match */ - if (found_match) { - /* Have menu appear with default application selected */ - gtk_menu_set_active (GTK_MENU (new_menu), index); - } else { - /* No match found. We need to insert a menu item - * and add the application to the default list */ - menu_item = gtk_menu_item_new_with_label (default_app->name); - - /* Store copy of application name and mime type in item; free when item destroyed. */ - gtk_object_set_data_full (GTK_OBJECT (menu_item), - "id", - g_strdup (default_app->id), - g_free); - - gtk_object_set_data_full (GTK_OBJECT (menu_item), - "mime_type", - g_strdup (mime_type), - g_free); - - gtk_menu_append (GTK_MENU (new_menu), menu_item); - gtk_widget_show (menu_item); - - gtk_signal_connect (GTK_OBJECT (menu_item), "activate", - application_menu_activated, NULL); - - - /* Iterate */ - children = gtk_container_children (GTK_CONTAINER (new_menu)); - for (index = 0; children != NULL; children = children->next, ++index) { - id = (const char *)(gtk_object_get_data (GTK_OBJECT (children->data), "id")); - if (id != NULL) { - if (strcmp (default_app->id, id) == 0) { - found_match = TRUE; - break; - } - } - } - g_list_free (children); - - /* Set it as active */ - gtk_menu_set_active (GTK_MENU (new_menu), index); - } - gnome_vfs_mime_application_free (default_app); - } - } - - gtk_option_menu_set_menu (GTK_OPTION_MENU (default_menu), new_menu); -} - -static void -component_menu_activated (GtkWidget *menu_item, gpointer data) -{ - const char *iid; - const char *mime_type; - - /* Get our stashed data */ - iid = gtk_object_get_data (GTK_OBJECT (menu_item), "iid"); - mime_type = gtk_object_get_data (GTK_OBJECT (menu_item), "mime_type"); - - if (iid == NULL || mime_type == NULL) { - return; - } - - gnome_vfs_mime_set_default_component (mime_type, iid); - update_mime_list_action (mime_type); + g_value_unset (&mime_type); } static void -populate_viewer_menu (GtkWidget *component_menu, const char *mime_type) +remove_cb (GtkButton *button, GladeXML *dialog) { - GtkWidget *new_menu, *menu_item; - GList *component_list, *copy_list; - Bonobo_ServerInfo *default_component; - Bonobo_ServerInfo *info; - gboolean has_none, found_match; - char *mime_copy, *component_name; - const char *iid; - GList *children; - int index; + GtkTreeView *treeview; + GtkTreeModel *model; + GtkTreeSelection *selection; + GtkTreeIter iter; + GValue mime_type; - has_none = TRUE; - found_match = FALSE; + treeview = GTK_TREE_VIEW (WID ("mime_types_tree")); + selection = gtk_tree_view_get_selection (treeview); + gtk_tree_selection_get_selected (selection, &model, &iter); - mime_copy = g_strdup (mime_type); - - new_menu = gtk_menu_new (); - - /* Get the default component */ - default_component = gnome_vfs_mime_get_default_component (mime_type); - - /* Get the component short list */ - component_list = gnome_vfs_mime_get_short_list_components (mime_type); - if (component_list != NULL) { - for (copy_list = component_list; copy_list != NULL; copy_list = copy_list->next) { - has_none = FALSE; - - component_name = name_from_oaf_server_info (copy_list->data); - menu_item = gtk_menu_item_new_with_label (component_name); - g_free (component_name); - - /* Store copy of component name and mime type in item; free when item destroyed. */ - info = copy_list->data; - gtk_object_set_data_full (GTK_OBJECT (menu_item), - "iid", - g_strdup (info->iid), - g_free); - - gtk_object_set_data_full (GTK_OBJECT (menu_item), - "mime_type", - g_strdup (mime_type), - g_free); - - gtk_menu_append (GTK_MENU (new_menu), menu_item); - gtk_widget_show (menu_item); - - gtk_signal_connect (GTK_OBJECT (menu_item), "activate", - component_menu_activated, NULL); - } - - gnome_vfs_mime_component_list_free (component_list); - } - - /* Find all components or add a "None" item */ - if (has_none && default_component == NULL) { - menu_item = gtk_menu_item_new_with_label (_("None")); - gtk_menu_append (GTK_MENU (new_menu), menu_item); - gtk_widget_show (menu_item); - } else { - /* Check and see if default is in the short list */ - if (default_component != NULL) { - /* Iterate */ - children = gtk_container_children (GTK_CONTAINER (new_menu)); - for (index = 0; children != NULL; children = children->next, ++index) { - iid = (const char *)(gtk_object_get_data (GTK_OBJECT (children->data), "iid")); - if (iid != NULL) { - if (strcmp (default_component->iid, iid) == 0) { - found_match = TRUE; - break; - } - } - } - g_list_free (children); - - /* See if we have a match */ - if (found_match) { - /* Have menu appear with default component selected */ - gtk_menu_set_active (GTK_MENU (new_menu), index); - } else { - /* No match found. We need to insert a menu item - * and add the component to the default list */ - component_name = name_from_oaf_server_info (default_component); - menu_item = gtk_menu_item_new_with_label (component_name); - g_free (component_name); - - /* Store copy of component name and mime type in item; free when item destroyed. */ - gtk_object_set_data_full (GTK_OBJECT (menu_item), - "iid", - g_strdup (default_component->iid), - g_free); - - gtk_object_set_data_full (GTK_OBJECT (menu_item), - "mime_type", - g_strdup (mime_type), - g_free); - - gtk_menu_append (GTK_MENU (new_menu), menu_item); - gtk_widget_show (menu_item); - - gtk_signal_connect (GTK_OBJECT (menu_item), "activate", - component_menu_activated, NULL); - - - /* Iterate */ - children = gtk_container_children (GTK_CONTAINER (new_menu)); - for (index = 0; children != NULL; children = children->next, ++index) { - iid = (const char *)(gtk_object_get_data (GTK_OBJECT (children->data), "iid")); - if (iid != NULL) { - if (strcmp (default_component->iid, iid) == 0) { - found_match = TRUE; - break; - } - } - } - g_list_free (children); - - /* Set it as active */ - gtk_menu_set_active (GTK_MENU (new_menu), index); - } - CORBA_free (default_component); - } - } - - gtk_option_menu_set_menu (GTK_OPTION_MENU (default_menu), new_menu); + mime_type.g_type = G_TYPE_INVALID; + gtk_tree_model_get_value (model, &iter, MIME_TYPE_COLUMN, &mime_type); + remove_list = g_list_prepend (remove_list, g_value_dup_string (&mime_type)); + mime_type_remove_from_dirty_list (g_value_get_string (&mime_type)); + gtk_tree_store_remove (GTK_TREE_STORE (model), &iter); + g_value_unset (&mime_type); } +static GladeXML * +create_dialog (void) +{ + GladeXML *dialog; + + GtkTreeModel *model; + + GtkWidget *treeview; + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + + gint col_offset; + + dialog = glade_xml_new (GNOMECC_DATA_DIR "/interfaces/file-types-properties.glade", "main_dialog", NULL); + + model = mime_types_model_new (); + treeview = WID ("mime_types_tree"); + + gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), model); + + /* Icon column */ + renderer = gtk_cell_renderer_pixbuf_new (); + gtk_tree_view_insert_column_with_attributes + (GTK_TREE_VIEW (treeview), -1, NULL, renderer, + "pixbuf", ICON_COLUMN, + NULL); + + /* Description column */ + renderer = gtk_cell_renderer_text_new (); + col_offset = gtk_tree_view_insert_column_with_attributes + (GTK_TREE_VIEW (treeview), -1, _("Description"), renderer, + "text", DESCRIPTION_COLUMN, + NULL); + + /* Extensions column */ + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_insert_column_with_attributes + (GTK_TREE_VIEW (treeview), -1, _("Extensions"), renderer, + "text", EXTENSIONS_COLUMN, + NULL); + + column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), col_offset - 1); + gtk_tree_view_set_expander_column (GTK_TREE_VIEW (treeview), column); + + g_signal_connect (G_OBJECT (WID ("add_button")), "clicked", (GCallback) add_cb, dialog); + g_signal_connect (G_OBJECT (WID ("edit_button")), "clicked", (GCallback) edit_cb, dialog); + g_signal_connect (G_OBJECT (WID ("remove_button")), "clicked", (GCallback) remove_cb, dialog); + + return dialog; +} + +/* Stupid gnome-vfs install bug */ +void gnome_vfs_mime_registered_mime_type_delete (const gchar *mime_type); + static void -revert_real_cb (gint reply, gpointer data) +apply_cb (void) { - if (reply == 0) { - /* YES */ - GList *mime_types_list; - gnome_vfs_mime_reset (); - - gnome_vfs_mime_info_reload (); - - mime_types_list = gnome_vfs_get_registered_mime_types (); - - gtk_clist_freeze (GTK_CLIST (mime_list)); - gtk_clist_clear (GTK_CLIST (mime_list)); - populate_mime_list (mime_types_list, GTK_CLIST (mime_list)); - - /* Sort list using current sort type and select the first item. */ - gtk_clist_sort (GTK_CLIST (mime_list)); - gtk_clist_select_row (GTK_CLIST (mime_list), 0, 0); - list_reveal_row (GTK_CLIST (mime_list), 0); - - gtk_clist_thaw (GTK_CLIST (mime_list)); - - } else { - /* NO */ - } + mime_type_commit_dirty_list (); + g_list_foreach (remove_list, (GFunc) gnome_vfs_mime_registered_mime_type_delete, NULL); + g_list_foreach (remove_list, (GFunc) g_free, NULL); + g_list_free (remove_list); } -static void -revert_mime_clicked (GtkWidget *widget, gpointer data) +int +main (int argc, char **argv) { - GtkWidget *dialog; - - dialog = gnome_question_dialog_modal (_("Reverting to system settings will lose any changes\n" - "you have ever made to File Types and Programs.\n" - "Revert anyway?"), - revert_real_cb, NULL); + GladeXML *dialog; -} -/* - * delete_mime_clicked - * - * Delete mime type if it is a user defined type. - */ - -static void -delete_mime_clicked (GtkWidget *widget, gpointer data) -{ - const char *mime_type; - gint row = 0; - - if (GTK_CLIST (mime_list)->selection) - row = GPOINTER_TO_INT ((GTK_CLIST (mime_list)->selection)->data); - else - return; - mime_type = (const char *) gtk_clist_get_row_data (GTK_CLIST (mime_list), row); - - gtk_clist_remove (GTK_CLIST (mime_list), row); - - gnome_vfs_mime_registered_mime_type_delete (mime_type); -} - -static void -add_mime_clicked (GtkWidget *widget, gpointer data) -{ - char *text[4], *tmp_text; - const char *description; - char *extensions, *mime_string, *filename; - gint row; - GdkPixbuf *pixbuf; - GdkPixmap *pixmap; - GdkBitmap *bitmap; - GnomeVFSMimeAction *action; - GnomeVFSMimeApplication *default_app; - Bonobo_ServerInfo *default_component; - int found_index; - - mime_string = nautilus_mime_type_capplet_show_new_mime_window (); - if (mime_string != NULL && mime_string[0] != '\0') { - /* Add new type to mime list */ - pixbuf = NULL; - - /* Add description to first column */ - description = gnome_vfs_mime_get_description (mime_string); - if (description != NULL && strlen (description) > 0) { - text[0] = g_strdup (description); - } else { - text[0] = g_strdup (""); - } - - /* Add mime type to second column */ - text[1] = g_strdup (mime_string); - - /* Add extension to third columns */ - extensions = gnome_vfs_mime_get_extensions_pretty_string (mime_string); - if (extensions != NULL) { - text[2] = g_strdup (extensions); - } else { - text[2] = g_strdup (""); - } - - /* Add default action to fourth column */ - text[3] = g_strdup(_("none")); - - /* Insert item into list */ - row = gtk_clist_insert (GTK_CLIST (mime_list), 1, text); - gtk_clist_set_row_data (GTK_CLIST (mime_list), row, g_strdup (mime_string)); - - /* Set description column icon */ - pixbuf = capplet_get_icon_pixbuf (mime_string, FALSE); - - if (pixbuf != NULL) { - pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, MAX_ICON_WIDTH_IN_LIST, MAX_ICON_HEIGHT_IN_LIST); - gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &bitmap, 100); - gtk_clist_set_pixtext (GTK_CLIST (mime_list), row, 0, text[0], 5, pixmap, bitmap); - gdk_pixbuf_unref (pixbuf); - } - - /* Set up action column */ - pixbuf = NULL; - action = gnome_vfs_mime_get_default_action (mime_string); - if (action != NULL) { - switch (action->action_type) { - case GNOME_VFS_MIME_ACTION_TYPE_APPLICATION: - /* Get the default application */ - default_app = gnome_vfs_mime_get_default_application (mime_string); - g_free (text[3]); - text[3] = g_strdup (default_app->name); - - filename = capplet_get_icon_path (DEFAULT_ACTION_ICON); - if (filename != NULL) { - pixbuf = gdk_pixbuf_new_from_file (filename, NULL); - g_free (filename); - } - - gnome_vfs_mime_application_free (default_app); - break; - - case GNOME_VFS_MIME_ACTION_TYPE_COMPONENT: - /* Get the default component */ - default_component = gnome_vfs_mime_get_default_component (mime_string); - g_free (text[3]); - tmp_text = name_from_oaf_server_info (default_component); - text[3] = g_strdup_printf (_("View as %s"), tmp_text); - g_free (tmp_text); - filename = capplet_get_icon_path ("nautilus/gnome-library.png"); - if (filename != NULL) { - pixbuf = gdk_pixbuf_new_from_file (filename, NULL); - g_free (filename); - } - CORBA_free (default_component); - break; - - default: - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (application_button), TRUE); - break; - } - } - - /* Set column icon */ - if (pixbuf != NULL) { - pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, MAX_ICON_WIDTH_IN_LIST, MAX_ICON_HEIGHT_IN_LIST); - gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &bitmap, 100); - gtk_clist_set_pixtext (GTK_CLIST (mime_list), row, 3, text[3], 5, pixmap, bitmap); - gdk_pixbuf_unref (pixbuf); - } - - /* Sort, select and scroll to new mime type */ - gtk_clist_sort (GTK_CLIST (mime_list)); - found_index = find_row_for_mime_type (mime_string, GTK_CLIST (mime_list)); - if (found_index != -1) { - gtk_clist_select_row (GTK_CLIST (mime_list), found_index, 1); - list_reveal_row (GTK_CLIST (mime_list), found_index); - } - - g_free (text[0]); - g_free (text[1]); - g_free (text[2]); - g_free (text[3]); - g_free (extensions); - g_free (mime_string); - } - -} - -static void -edit_default_clicked (GtkWidget *widget, gpointer data) -{ - GtkWidget *list; - const char *mime_type; - GList *p; - GtkCListRow *row; - - g_return_if_fail (GTK_IS_CLIST (data)); - - list = data; - row = NULL; - - /* Get first selected row. This will be the only selection for this list */ - for (p = GTK_CLIST (list)->row_list; p != NULL; p = p->next) { - row = p->data; - if (row->state == GTK_STATE_SELECTED) { - break; - } - } - - if (row == NULL) { - return; - } - - /* Show dialog */ - mime_type = (const char *) row->data; - - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (application_button))) { - show_edit_applications_dialog (mime_type); - } else { - show_edit_components_dialog (mime_type); - } -} - - -void -nautilus_mime_type_capplet_update_mime_list_icon_and_description (const char *mime_string) -{ - char *text; - const char *description; - gint row; - GdkPixbuf *pixbuf; - GdkPixmap *pixmap; - GdkBitmap *bitmap; - GtkCList *clist; - - clist = GTK_CLIST (mime_list); - - pixbuf = NULL; - - row = GPOINTER_TO_INT (clist->selection->data); - - gnome_vfs_mime_info_reload (); - - /* Get description text */ - description = gnome_vfs_mime_get_description (mime_string); - if (description != NULL && strlen (description) > 0) { - text = g_strdup (description); - } else { - text = g_strdup (""); - } - - /* Set description column icon */ - pixbuf = capplet_get_icon_pixbuf (mime_string, FALSE); - - if (pixbuf != NULL) { - pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, MAX_ICON_WIDTH_IN_LIST, MAX_ICON_HEIGHT_IN_LIST); - gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &bitmap, 100); - gtk_clist_set_pixtext (clist, row, 0, text, 5, pixmap, bitmap); - gdk_pixbuf_unref (pixbuf); - } - - g_free (text); -} - -/* - * nautilus_mime_type_capplet_update_application_info - * - * Update state of the applications menu. This function is called - * when the Edit Applications dialog is closed with an OK. - */ - -void -nautilus_mime_type_capplet_update_application_info (const char *mime_type) -{ - populate_application_menu (default_menu, mime_type); -} - -/* - * nautilus_mime_type_capplet_update_component_info - * - * Update state of the components menu. This function is called - * when the Edit Componests dialog is closed with an OK. - */ - -void -nautilus_mime_type_capplet_update_viewer_info (const char *mime_type) -{ - populate_viewer_menu (default_menu, mime_type); -} - -static void -update_mime_list_action (const char *mime_string) -{ - GdkPixbuf *pixbuf; - GdkPixmap *pixmap; - GdkBitmap *bitmap; - GnomeVFSMimeAction *action; - GnomeVFSMimeApplication *default_app; - Bonobo_ServerInfo *default_component; - char *text, *tmp_text, *icon_path; - int row; - - pixbuf = NULL; - row = GPOINTER_TO_INT (GTK_CLIST (mime_list)->selection->data); - - text = g_strdup(_("none")); - - action = gnome_vfs_mime_get_default_action (mime_string); - if (action != NULL) { - switch (action->action_type) { - /* FIXME: Big hunks of this code are copied/pasted in several - * places in this file. Need to use common routines. One way - * to find them is to search for "nautilus/gnome-library.png" - */ - case GNOME_VFS_MIME_ACTION_TYPE_APPLICATION: - /* Get the default application */ - default_app = gnome_vfs_mime_get_default_application (mime_string); - g_free (text); - text = g_strdup (default_app->name); - icon_path = capplet_get_icon_path (DEFAULT_ACTION_ICON); - if (icon_path != NULL) { - pixbuf = gdk_pixbuf_new_from_file (icon_path, NULL); - g_free (icon_path); - } - gnome_vfs_mime_application_free (default_app); - break; - - case GNOME_VFS_MIME_ACTION_TYPE_COMPONENT: - /* Get the default component */ - default_component = gnome_vfs_mime_get_default_component (mime_string); - g_free (text); - tmp_text = name_from_oaf_server_info (default_component); - text = g_strdup_printf (_("View as %s"), tmp_text); - g_free (tmp_text); - icon_path = capplet_get_icon_path ("nautilus/gnome-library.png"); - if (icon_path != NULL) { - pixbuf = gdk_pixbuf_new_from_file (icon_path, NULL); - g_free (icon_path); - } - CORBA_free (default_component); - break; - - default: - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (application_button), TRUE); - break; - } - } - - /* Set column icon */ - if (pixbuf != NULL) { - pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, MAX_ICON_WIDTH_IN_LIST, MAX_ICON_HEIGHT_IN_LIST); - gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &bitmap, 100); - gtk_clist_set_pixtext (GTK_CLIST (mime_list), row, 3, text, 5, pixmap, bitmap); - gdk_pixbuf_unref (pixbuf); - } else { - /* Just set text with no icon */ - gtk_clist_set_text (GTK_CLIST (mime_list), row, 3, text); - } - g_free (text); -} - -/* FIXME: - * This routine is never called with is_executable TRUE anymore. It - * could be simplified, possibly out of existence. - */ -static GdkPixbuf * -capplet_get_icon_pixbuf (const char *mime_string, gboolean is_executable) -{ - const char *icon_name; - char *icon_path; - GdkPixbuf *pixbuf; - - pixbuf = NULL; - - icon_name = gnome_vfs_mime_get_icon (mime_string); - if (icon_name == NULL) { - icon_name = is_executable - ? DEFAULT_ACTION_ICON - : DEFAULT_REGULAR_ICON; - } - - icon_path = capplet_get_icon_path (icon_name); - if (icon_path != NULL) { - pixbuf = gdk_pixbuf_new_from_file (icon_path, NULL); - g_free (icon_path); - } - - return pixbuf; -} - -static void -populate_mime_list (GList *type_list, GtkCList *clist) -{ - char *text[4], *tmp_text; - const char *description; - char *icon_path; - char *extensions, *mime_string; - gint row; - GList *element; - GdkPixbuf *pixbuf; - GdkPixmap *pixmap; - GdkBitmap *bitmap; - GnomeVFSMimeAction *action; - GnomeVFSMimeApplication *default_app; - Bonobo_ServerInfo *default_component; - - for (element = type_list; element != NULL; element= element->next) { - mime_string = (char *)element->data; - - pixbuf = NULL; - - /* Add description to first column */ - description = gnome_vfs_mime_get_description (mime_string); - if (description != NULL && strlen (description) > 0) { - text[0] = g_strdup (description); - } else { - text[0] = g_strdup (""); - } - - /* Add mime type to second column */ - text[1] = mime_string; - - /* Add extension to third columns */ - extensions = gnome_vfs_mime_get_extensions_pretty_string (mime_string); - if (extensions != NULL) { - text[2] = extensions; - } else { - text[2] = ""; - } - - /* Add default action to fourth column */ - text[3] = g_strdup(_("none")); - - /* Insert item into list */ - row = gtk_clist_insert (GTK_CLIST (clist), 1, text); - gtk_clist_set_row_data (GTK_CLIST (clist), row, g_strdup (mime_string)); - - /* Set description column icon */ - pixbuf = capplet_get_icon_pixbuf (mime_string, FALSE); - - if (pixbuf != NULL) { - /* FIXME: Big hunks of this code are copied/pasted in several - * places in this file. Need to use common routines. One way - * to find them is to search for MAX_ICON_WIDTH_IN_LIST - */ - pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, MAX_ICON_WIDTH_IN_LIST, MAX_ICON_HEIGHT_IN_LIST); - gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &bitmap, 100); - gtk_clist_set_pixtext (clist, row, 0, text[0], 5, pixmap, bitmap); - gdk_pixbuf_unref (pixbuf); - } - - /* Set up action column */ - pixbuf = NULL; - action = gnome_vfs_mime_get_default_action (mime_string); - if (action != NULL) { - switch (action->action_type) { - case GNOME_VFS_MIME_ACTION_TYPE_APPLICATION: - /* Get the default application */ - default_app = gnome_vfs_mime_get_default_application (mime_string); - g_free (text[3]); - text[3] = g_strdup (default_app->name); - - icon_path = capplet_get_icon_path (DEFAULT_ACTION_ICON); - if (icon_path != NULL) { - pixbuf = gdk_pixbuf_new_from_file (icon_path, NULL); - g_free (icon_path); - } - gnome_vfs_mime_application_free (default_app); - break; - - case GNOME_VFS_MIME_ACTION_TYPE_COMPONENT: - /* Get the default component */ - default_component = gnome_vfs_mime_get_default_component (mime_string); - g_free (text[3]); - tmp_text = name_from_oaf_server_info (default_component); - text[3] = g_strdup_printf (_("View as %s"), tmp_text); - g_free (tmp_text); - icon_path = capplet_get_icon_path ("nautilus/gnome-library.png"); - if (icon_path != NULL) { - pixbuf = gdk_pixbuf_new_from_file (icon_path, NULL); - g_free (icon_path); - } - CORBA_free (default_component); - break; - - default: - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (application_button), TRUE); - break; - } - } - - /* Set column icon */ - if (pixbuf != NULL) { - pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, MAX_ICON_WIDTH_IN_LIST, MAX_ICON_HEIGHT_IN_LIST); - gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &bitmap, 100); - gtk_clist_set_pixtext (clist, row, 3, text[3], 5, pixmap, bitmap); - gdk_pixbuf_unref (pixbuf); - } - - g_free (text[0]); - g_free (text[3]); - g_free (extensions); - } -} - -static gint -sort_case_insensitive (GtkCList *clist, gpointer ptr1, gpointer ptr2) -{ - const char *text1 = NULL; - const char *text2 = NULL; - - GtkCListRow *row1 = (GtkCListRow *) ptr1; - GtkCListRow *row2 = (GtkCListRow *) ptr2; - - switch (row1->cell[clist->sort_column].type) { - case GTK_CELL_TEXT: - text1 = GTK_CELL_TEXT (row1->cell[clist->sort_column])->text; - break; - - case GTK_CELL_PIXTEXT: - text1 = GTK_CELL_PIXTEXT (row1->cell[clist->sort_column])->text; - break; - - default: - break; - } - - switch (row2->cell[clist->sort_column].type) { - case GTK_CELL_TEXT: - text2 = GTK_CELL_TEXT (row2->cell[clist->sort_column])->text; - break; - - case GTK_CELL_PIXTEXT: - text2 = GTK_CELL_PIXTEXT (row2->cell[clist->sort_column])->text; - break; - - default: - break; - } - - if (text2 == NULL) { - return (text1 != NULL); - } - - if (text1 == NULL) { - return -1; - } - - return strcasecmp (text1, text2); -} - -static void -column_clicked (GtkCList *clist, gint column, gpointer user_data) -{ - gtk_clist_set_sort_column (clist, column); - - /* If the user has not clicked the column yet, make sure - * that the sort type is descending the first time. - */ - if (!sort_column_clicked [column]) { - clist->sort_type = GTK_SORT_DESCENDING; - sort_column_clicked [column] = TRUE; - } - - /* Toggle sort type */ - if (clist->sort_type == GTK_SORT_ASCENDING) { - gtk_clist_set_sort_type (clist, GTK_SORT_DESCENDING); - } else { - gtk_clist_set_sort_type (clist, GTK_SORT_ASCENDING); - } - - gtk_clist_sort (clist); -} - -static void -mime_list_reset_row_height (GtkCList *list) -{ - guint height_for_icon; - guint height_for_text; - - height_for_icon = MAX_ICON_HEIGHT_IN_LIST + 1; - height_for_text = gtk_style_get_font (GTK_WIDGET (list)->style)->ascent + - gtk_style_get_font (GTK_WIDGET (list)->style)->descent + 1; - gtk_clist_set_row_height (list, MAX (height_for_icon, height_for_text)); -} - -static GtkWidget * -create_mime_list_and_scroller (void) -{ - GtkWidget *window; - gchar *titles[TOTAL_COLUMNS]; - GList *type_list; - int index; - - titles[0] = _("Description"); - titles[1] = _("MIME Type"); - titles[2] = _("Extension"); - titles[3] = _("Default Action"); - - window = gtk_scrolled_window_new (NULL, NULL); - gtk_widget_set_usize (window, 500, 200); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (window), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - mime_list = gtk_clist_new_with_titles (TOTAL_COLUMNS, titles); - gtk_clist_set_selection_mode (GTK_CLIST (mime_list), GTK_SELECTION_BROWSE); - gtk_clist_set_compare_func (GTK_CLIST (mime_list), (GtkCListCompareFunc) sort_case_insensitive); - - type_list = gnome_vfs_get_registered_mime_types (); - populate_mime_list (type_list, GTK_CLIST (mime_list)); - gnome_vfs_mime_registered_mime_type_list_free (type_list); - - gtk_clist_columns_autosize (GTK_CLIST (mime_list)); - gtk_clist_select_row (GTK_CLIST (mime_list), 0, 0); - gtk_container_add (GTK_CONTAINER (window), mime_list); - - /* Enable all titles */ - gtk_clist_column_titles_active (GTK_CLIST (mime_list)); - gtk_signal_connect (GTK_OBJECT (mime_list), "click_column", - column_clicked, NULL); - - /* Turn off autoresizing of columns */ - for (index = 0; index < TOTAL_COLUMNS; index++) { - gtk_clist_set_column_auto_resize (GTK_CLIST (mime_list), index, FALSE); - } - - /* Make height tall enough for icons to look good. - * This must be done after the list widget is realized, due to - * a bug/design flaw in nautilus_clist_set_row_height. Connecting to - * the "realize" signal is slightly too early, so we connect to - * "map". - */ - gtk_signal_connect (GTK_OBJECT (mime_list), - "map", - mime_list_reset_row_height, - NULL); - - return window; -} - -const char * -nautilus_mime_type_capplet_get_selected_item_mime_type (void) -{ - const char *mime_type; - int row; - GtkCList *clist; - - clist = GTK_CLIST (mime_list); - - if (clist->selection == NULL) { - return NULL; - } - - /* This is a single selection list, so we just use the first item in - * the list to retrieve the data */ - row = GPOINTER_TO_INT (clist->selection->data); - - mime_type = (const char *) gtk_clist_get_row_data (clist, row); - - return mime_type; -} - -/** - * gtk_label_make_bold. - * - * Switches the font of label to a bold equivalent. - * @label: The label. - **/ - -static void -gtk_widget_make_bold (GtkWidget *widget) -{ - GtkStyle *style; - GdkFont *bold_font; - - g_return_if_fail (GTK_IS_WIDGET (widget)); - style = gtk_widget_get_style (widget); - - bold_font = gdk_font_get_bold (gtk_style_get_font (style)); - - if (bold_font == NULL) { - return; - } - - gtk_widget_set_font (widget, bold_font); - gdk_font_unref (bold_font); -} - -/** - * gtk_widget_set_font - * - * Sets the font for a widget's style, managing the style objects. - * @widget: The widget. - * @font: The font. - **/ -static void -gtk_widget_set_font (GtkWidget *widget, GdkFont *font) -{ - GtkStyle *new_style; - - g_return_if_fail (GTK_IS_WIDGET (widget)); - g_return_if_fail (font != NULL); - - new_style = gtk_style_copy (gtk_widget_get_style (widget)); - - gtk_style_set_font (new_style, font); - - gtk_widget_set_style (widget, new_style); - gtk_style_unref (new_style); -} - -/** - * gdk_font_get_bold - * @plain_font: A font. - * Returns: A bold variant of @plain_font or NULL. - * - * Tries to find a bold flavor of a given font. Returns NULL if none is available. - */ -static GdkFont * -gdk_font_get_bold (const GdkFont *plain_font) -{ - return gdk_font_ref (plain_font); -} - - -/* scale the passed in pixbuf to conform to the passed-in maximum width and height */ -/* utility routine to scale the passed-in pixbuf to be smaller than the maximum allowed size, if necessary */ -static GdkPixbuf * -capplet_gdk_pixbuf_scale_to_fit (GdkPixbuf *pixbuf, int max_width, int max_height) -{ - double scale_factor; - double h_scale = 1.0; - double v_scale = 1.0; - - int width = gdk_pixbuf_get_width(pixbuf); - int height = gdk_pixbuf_get_height(pixbuf); - - if (width > max_width) { - h_scale = max_width / (double) width; - } - if (height > max_height) { - v_scale = max_height / (double) height; - } - scale_factor = MIN (h_scale, v_scale); - - if (scale_factor < 1.0) { - GdkPixbuf *scaled_pixbuf; - /* the width and scale factor are always > 0, so it's OK to round by adding here */ - int scaled_width = floor(width * scale_factor + .5); - int scaled_height = floor(height * scale_factor + .5); - - scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf, scaled_width, scaled_height, GDK_INTERP_BILINEAR); - gdk_pixbuf_unref (pixbuf); - pixbuf = scaled_pixbuf; - } - - return pixbuf; + bindtextdomain (PACKAGE, GNOMELOCALEDIR); + bind_textdomain_codeset (PACKAGE, "UTF-8"); + textdomain (PACKAGE); + + gnome_program_init ("gnome-file-types-properties", VERSION, LIBGNOMEUI_MODULE, argc, argv, NULL); + + dialog = create_dialog (); + + g_signal_connect (G_OBJECT (WID ("main_apply_button")), "clicked", (GCallback) apply_cb, NULL); + g_signal_connect (G_OBJECT (WID ("main_close_button")), "clicked", (GCallback) gtk_main_quit, NULL); + gtk_widget_show_all (WID ("main_dialog")); + + gtk_main (); + + return 0; } diff --git a/capplets/file-types/file-types-properties.glade b/capplets/file-types/file-types-properties.glade index e69de29bb..e18a0062a 100644 --- a/capplets/file-types/file-types-properties.glade +++ b/capplets/file-types/file-types-properties.glade @@ -0,0 +1,1093 @@ + + + + + + + + File types and Internet Services + GTK_WINDOW_TOPLEVEL + no + 400 + 300 + no + yes + no + GTK_WIN_POS_NONE + + + + no + 8 + yes + + + + GTK_BUTTONBOX_END + 8 + yes + + + + yes + yes + yes + gtk-apply + yes + yes + + + + + + yes + yes + yes + gtk-close + yes + yes + + + + + 0 + no + yes + GTK_PACK_END + + + + + + no + 4 + yes + + + + GTK_POLICY_AUTOMATIC + GTK_POLICY_ALWAYS + GTK_SHADOW_IN + yes + + + + yes + yes + yes + + + + CTree:title + yes + + + + + + CTree:title + yes + + + + + + CTree:title + yes + + + + + + + + GTK_UPDATE_CONTINUOUS + yes + + + + + + GTK_UPDATE_CONTINUOUS + yes + + + + + 0 + yes + yes + + + + + + GTK_BUTTONBOX_START + 10 + yes + + + + yes + yes + Add... + GTK_RELIEF_NORMAL + yes + + + + + + yes + yes + Edit... + GTK_RELIEF_NORMAL + yes + + + + + + yes + yes + Remove + GTK_RELIEF_NORMAL + yes + + + + + 0 + no + yes + + + + + 0 + yes + yes + + + + + 4 + yes + yes + + + + + Edit file type + GTK_WINDOW_TOPLEVEL + no + no + yes + no + GTK_WIN_POS_NONE + + + + no + 8 + yes + + + + GTK_BUTTONBOX_END + 8 + yes + + + + yes + yes + yes + gtk-apply + yes + yes + + + + + + yes + yes + yes + gtk-close + yes + yes + + + + + 0 + no + yes + GTK_PACK_END + + + + + + 4 + no + 4 + yes + + + + yes + + + 0 + yes + yes + + + + + + Icon + GTK_JUSTIFY_CENTER + no + 0.5 + 0.5 + 0 + 0 + yes + + + 0 + no + no + + + + + + no + 4 + yes + + + + Description + GTK_JUSTIFY_CENTER + no + 0.5 + 0.5 + 0 + 0 + yes + + + 0 + no + no + + + + + + yes + yes + + 0 + yes + yes + + + 0 + yes + yes + + + + + 0 + no + yes + + + + + + no + 4 + yes + + + + MIME Type + GTK_JUSTIFY_CENTER + no + 0.5 + 0.5 + 0 + 0 + yes + + + 0 + no + no + + + + + + yes + yes + + 0 + yes + yes + + + 0 + yes + yes + + + + + 0 + no + yes + + + + + + Filename extensions + 0 + GTK_SHADOW_ETCHED_IN + yes + + + + 4 + no + 4 + yes + + + + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + yes + + + + yes + no + yes + + + + CList:title + label8 + GTK_JUSTIFY_CENTER + no + 0.5 + 0.5 + 0 + 0 + yes + + + + + + + + GTK_UPDATE_CONTINUOUS + yes + + + + + + GTK_UPDATE_CONTINUOUS + yes + + + + + 0 + yes + yes + + + + + + GTK_BUTTONBOX_START + 10 + yes + + + + yes + yes + Add... + GTK_RELIEF_NORMAL + yes + + + + + + yes + yes + Remove + GTK_RELIEF_NORMAL + yes + + + + + 0 + no + yes + + + + + + + 0 + yes + yes + + + + + + Actions + 0 + GTK_SHADOW_ETCHED_IN + yes + + + + 4 + no + 4 + yes + + + + no + 4 + yes + + + + Viewing component + GTK_JUSTIFY_CENTER + no + 0 + 0.5 + 0 + 0 + yes + + + 0 + no + yes + + + + + + yes + 0 + yes + + + + yes + + + + + 0 + yes + yes + + + + + 0 + no + yes + + + + + + no + 4 + yes + + + + Default action + GTK_JUSTIFY_CENTER + no + 0 + 0.5 + 0 + 0 + yes + + + 0 + no + yes + + + + + + yes + 0 + yes + + + + yes + + + + + 0 + yes + yes + + + + + 0 + no + yes + + + + + + no + 4 + yes + + + + Program to execute + GTK_JUSTIFY_CENTER + no + 0 + 0.5 + 0 + 0 + yes + + + 0 + no + yes + + + + + + no + no + yes + + + + yes + yes + + 0 + yes + yes + + + + + 0 + yes + yes + + + + + 0 + yes + yes + + + + + + + 0 + no + yes + + + + + 0 + yes + yes + + + + + 4 + yes + yes + + + + + GTK_WINDOW_TOPLEVEL + no + no + no + no + GTK_WIN_POS_NONE + + + + no + 8 + yes + + + + GTK_BUTTONBOX_END + 8 + yes + + + + yes + yes + yes + gtk-ok + yes + yes + + + + + + yes + yes + yes + gtk-apply + yes + yes + + + + + + yes + yes + yes + gtk-cancel + yes + yes + + + + + 0 + no + yes + GTK_PACK_END + + + + + + no + 4 + yes + + + + New filename extension + GTK_JUSTIFY_CENTER + no + 0 + 0.5 + 0 + 0 + yes + + + 0 + no + no + + + + + + yes + yes + + 0 + yes + yes + + + 0 + no + no + + + + + 0 + yes + yes + + + + + 4 + yes + yes + + + + + GTK_WINDOW_TOPLEVEL + no + no + no + no + GTK_WIN_POS_NONE + + + + no + 8 + yes + + + + GTK_BUTTONBOX_END + 8 + yes + + + + yes + yes + yes + gtk-ok + yes + yes + + + + + + yes + yes + yes + gtk-apply + yes + yes + + + + + + yes + yes + yes + gtk-cancel + yes + yes + + + + + 0 + no + yes + GTK_PACK_END + + + + + + 4 + no + 4 + yes + + + + no + 4 + yes + + + + Description + GTK_JUSTIFY_CENTER + no + 0.5 + 0.5 + 0 + 0 + yes + + + 0 + no + no + + + + + + yes + yes + + 0 + yes + yes + + + 0 + yes + yes + + + + + 0 + yes + yes + + + + + + no + 4 + yes + + + + Protocol name + GTK_JUSTIFY_CENTER + no + 0.5 + 0.5 + 0 + 0 + yes + + + 0 + no + no + + + + + + yes + yes + + 0 + yes + yes + + + 0 + yes + yes + + + + + 0 + yes + yes + + + + + + yes + Look at content + no + yes + yes + + + 0 + no + no + + + + + + yes + Run a program + no + yes + yes + look_at_content_toggle + + + 0 + no + no + + + + + + Program to run + 0 + GTK_SHADOW_ETCHED_IN + yes + + + + 4 + no + 4 + yes + + + + yes + 0 + yes + + + + yes + + + + + 0 + no + no + + + + + + no + 4 + yes + + + + Program + GTK_JUSTIFY_CENTER + no + 0.5 + 0.5 + 0 + 0 + yes + + + 0 + no + no + + + + + + no + no + yes + + + + yes + yes + + 0 + yes + yes + + + + + 0 + yes + yes + + + + + 0 + yes + yes + + + + + + yes + Needs terminal + no + yes + yes + + + 0 + no + no + + + + + + + 0 + yes + yes + + + + + 0 + yes + yes + + + + + 4 + yes + yes + + + + diff --git a/capplets/file-types/file-types-properties.glade1 b/capplets/file-types/file-types-properties.glade1 new file mode 100644 index 000000000..84c8f06c5 --- /dev/null +++ b/capplets/file-types/file-types-properties.glade1 @@ -0,0 +1,1026 @@ + + + + + File-types-properties + file-types-properties + + src + pixmaps + C + True + True + + + + GnomeDialog + main_dialog + File types and Internet Services + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + 400 + 300 + False + True + False + False + False + + + GtkVBox + GnomeDialog:vbox + dialog-vbox1 + False + 8 + + 4 + True + True + + + + GtkHButtonBox + GnomeDialog:action_area + dialog-action_area1 + GTK_BUTTONBOX_END + 8 + 85 + 27 + 7 + 0 + + 0 + False + True + GTK_PACK_END + + + + GtkButton + main_apply_button + True + True + GNOME_STOCK_BUTTON_APPLY + + + + GtkButton + main_close_button + True + True + GNOME_STOCK_BUTTON_CLOSE + + + + + GtkHBox + prefs_widget + False + 4 + + 0 + True + True + + + + GtkScrolledWindow + scrolledwindow1 + GTK_POLICY_AUTOMATIC + GTK_POLICY_ALWAYS + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + 0 + True + True + + + + GtkCTree + mime_types_tree + True + 3 + 80,80,80 + GTK_SELECTION_SINGLE + True + GTK_SHADOW_IN + + + Placeholder + CTree:title + + + + Placeholder + CTree:title + + + + Placeholder + CTree:title + + + + + + GtkVButtonBox + vbuttonbox1 + GTK_BUTTONBOX_START + 10 + 85 + 27 + 7 + 0 + + 0 + False + True + + + + GtkButton + add_button + True + True + + GTK_RELIEF_NORMAL + + + + GtkButton + edit_button + True + True + + GTK_RELIEF_NORMAL + + + + GtkButton + remove_button + True + True + + GTK_RELIEF_NORMAL + + + + + + + + GnomeDialog + edit_dialog + Edit file type + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + False + True + False + False + False + + + GtkVBox + GnomeDialog:vbox + dialog-vbox2 + False + 8 + + 4 + True + True + + + + GtkHButtonBox + GnomeDialog:action_area + dialog-action_area2 + GTK_BUTTONBOX_END + 8 + 85 + 27 + 7 + 0 + + 0 + False + True + GTK_PACK_END + + + + GtkButton + edit_apply_button + True + True + GNOME_STOCK_BUTTON_APPLY + + + + GtkButton + edit_close_button + True + True + GNOME_STOCK_BUTTON_CLOSE + + + + + GtkVBox + edit_widget + 4 + False + 4 + + 0 + True + True + + + + GnomeIconEntry + icon_entry + 10 + + 0 + True + True + + + + + GtkLabel + label13 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkHBox + hbox3 + False + 4 + + 0 + False + True + + + + GtkLabel + description_label + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkEntry + description_entry + True + True + True + 0 + + + 0 + True + True + + + + + + GtkHBox + hbox4 + False + 4 + + 0 + False + True + + + + GtkLabel + mime_type_label + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkEntry + mime_type_entry + True + True + True + 0 + + + 0 + True + True + + + + + + GtkFrame + frame2 + + 0 + GTK_SHADOW_ETCHED_IN + + 0 + True + True + + + + GtkHBox + hbox5 + 4 + False + 4 + + + GtkScrolledWindow + scrolledwindow2 + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + 0 + True + True + + + + GtkCList + ext_list + True + 1 + 80 + GTK_SELECTION_SINGLE + False + GTK_SHADOW_IN + + + GtkLabel + CList:title + label8 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + + + GtkVButtonBox + vbuttonbox3 + GTK_BUTTONBOX_START + 10 + 85 + 27 + 7 + 0 + + 0 + False + True + + + + GtkButton + add_ext_button + True + True + + GTK_RELIEF_NORMAL + + + + GtkButton + remove_ext_button + True + True + + GTK_RELIEF_NORMAL + + + + + + + GtkFrame + frame3 + + 0 + GTK_SHADOW_ETCHED_IN + + 0 + False + True + + + + GtkVBox + vbox2 + 4 + False + 4 + + + GtkHBox + hbox6 + False + 4 + + 0 + False + True + + + + GtkLabel + component_label + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + + 0 + False + True + + + + + GtkOptionMenu + component_select + True + + 0 + + 0 + True + True + + + + + + GtkHBox + hbox7 + False + 4 + + 0 + False + True + + + + GtkLabel + default_action_label + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + + 0 + False + True + + + + + GtkOptionMenu + default_action_select + True + + 0 + + 0 + True + True + + + + + + GtkHBox + program_entry_box + False + 4 + + 0 + True + True + + + + GtkLabel + program_label + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + + 0 + False + True + + + + + GnomeFileEntry + program_entry + 10 + False + False + + 0 + True + True + + + + GtkEntry + GnomeEntry:entry + combo-entry1 + True + True + True + 0 + + + + + + + + + + + + GnomeDialog + add_ext_dialog + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + False + False + False + False + False + + + GtkVBox + GnomeDialog:vbox + dialog-vbox3 + False + 8 + + 4 + True + True + + + + GtkHButtonBox + GnomeDialog:action_area + dialog-action_area3 + GTK_BUTTONBOX_END + 8 + 85 + 27 + 7 + 0 + + 0 + False + True + GTK_PACK_END + + + + GtkButton + button7 + True + True + GNOME_STOCK_BUTTON_OK + + + + GtkButton + button8 + True + True + GNOME_STOCK_BUTTON_APPLY + + + + GtkButton + button9 + True + True + GNOME_STOCK_BUTTON_CANCEL + + + + + GtkVBox + add_ext_widget + False + 4 + + 0 + True + True + + + + GtkLabel + label14 + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkEntry + add_ext_entry + True + True + True + 0 + + + 0 + False + False + + + + + + + + GnomeDialog + internet_service_dialog + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + False + False + False + False + False + + + GtkVBox + GnomeDialog:vbox + dialog-vbox4 + False + 8 + + 4 + True + True + + + + GtkHButtonBox + GnomeDialog:action_area + dialog-action_area4 + GTK_BUTTONBOX_END + 8 + 85 + 27 + 7 + 0 + + 0 + False + True + GTK_PACK_END + + + + GtkButton + button10 + True + True + GNOME_STOCK_BUTTON_OK + + + + GtkButton + button11 + True + True + GNOME_STOCK_BUTTON_APPLY + + + + GtkButton + button12 + True + True + GNOME_STOCK_BUTTON_CANCEL + + + + + GtkVBox + service_edit_widget + 4 + False + 4 + + 0 + True + True + + + + GtkHBox + hbox10 + False + 4 + + 0 + True + True + + + + GtkLabel + description_label + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkEntry + description_entry + True + True + True + 0 + + + 0 + True + True + + + + + + GtkHBox + hbox11 + False + 4 + + 0 + True + True + + + + GtkLabel + protocol_label + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkEntry + protocol_entry + True + True + True + 0 + + + 0 + True + True + + + + + + GtkRadioButton + look_at_content_toggle + True + + False + True + action_type + + 0 + False + False + + + + + GtkRadioButton + run_program_toggle + True + + False + True + action_type + + 0 + False + False + + + + + GtkFrame + program_frame + + 0 + GTK_SHADOW_ETCHED_IN + + 0 + True + True + + + + GtkVBox + vbox5 + 4 + False + 4 + + + GtkOptionMenu + program_select + True + + 0 + + 0 + False + False + + + + + GtkHBox + hbox12 + False + 4 + + 0 + True + True + + + + GtkLabel + custom_program_label + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GnomeFileEntry + custom_program_entry + 10 + False + False + + 0 + True + True + + + + GtkEntry + GnomeEntry:entry + combo-entry2 + True + True + True + 0 + + + + + + + GtkCheckButton + needs_terminal_toggle + True + + False + True + + 0 + False + False + + + + + + + + + diff --git a/capplets/file-types/mime-edit-dialog.c b/capplets/file-types/mime-edit-dialog.c new file mode 100644 index 000000000..44d7a644b --- /dev/null +++ b/capplets/file-types/mime-edit-dialog.c @@ -0,0 +1,561 @@ +/* -*- mode: c; style: linux -*- */ + +/* mime-edit-dialog.c + * Copyright (C) 2001 Ximian, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "mime-edit-dialog.h" + +#define WID(x) (glade_xml_get_widget (dialog->p->dialog_xml, x)) + +enum { + PROP_0, + PROP_MIME_TYPE_INFO +}; + +struct _MimeEditDialogPrivate +{ + MimeTypeInfo *info; + GladeXML *dialog_xml; + GtkWidget *dialog_win; + GtkTreeStore *ext_store; +}; + +static GObjectClass *parent_class; + +static void mime_edit_dialog_init (MimeEditDialog *mime_edit_dialog, + MimeEditDialogClass *class); +static void mime_edit_dialog_class_init (MimeEditDialogClass *class); +static void mime_edit_dialog_base_init (MimeEditDialogClass *class); + +static void mime_edit_dialog_set_prop (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void mime_edit_dialog_get_prop (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static void mime_edit_dialog_dispose (GObject *object); +static void mime_edit_dialog_finalize (GObject *object); + +static void fill_dialog (MimeEditDialog *dialog); + +static void populate_component_list (MimeEditDialog *dialog); +static void populate_application_list (MimeEditDialog *dialog); +static void populate_extensions_list (MimeEditDialog *dialog); + +static void add_ext_cb (MimeEditDialog *dialog); +static void remove_ext_cb (MimeEditDialog *dialog); +static void default_action_changed_cb (MimeEditDialog *dialog); +static void response_cb (MimeEditDialog *dialog, + gint response_id); + +GType +mime_edit_dialog_get_type (void) +{ + static GType mime_edit_dialog_type = 0; + + if (!mime_edit_dialog_type) { + GTypeInfo mime_edit_dialog_info = { + sizeof (MimeEditDialogClass), + (GBaseInitFunc) mime_edit_dialog_base_init, + NULL, /* GBaseFinalizeFunc */ + (GClassInitFunc) mime_edit_dialog_class_init, + NULL, /* GClassFinalizeFunc */ + NULL, /* user-supplied data */ + sizeof (MimeEditDialog), + 0, /* n_preallocs */ + (GInstanceInitFunc) mime_edit_dialog_init, + NULL + }; + + mime_edit_dialog_type = + g_type_register_static (G_TYPE_OBJECT, + "MimeEditDialog", + &mime_edit_dialog_info, 0); + } + + return mime_edit_dialog_type; +} + +static void +mime_edit_dialog_init (MimeEditDialog *dialog, MimeEditDialogClass *class) +{ + GtkSizeGroup *size_group; + GtkTreeView *view; + GtkCellRenderer *renderer; + + dialog->p = g_new0 (MimeEditDialogPrivate, 1); + dialog->p->dialog_xml = glade_xml_new + (GNOMECC_DATA_DIR "/interfaces/file-types-properties.glade", "edit_widget", NULL); + + size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + gtk_size_group_add_widget (size_group, WID ("description_label")); + gtk_size_group_add_widget (size_group, WID ("mime_type_label")); + + size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + gtk_size_group_add_widget (size_group, WID ("component_label")); + gtk_size_group_add_widget (size_group, WID ("default_action_label")); + gtk_size_group_add_widget (size_group, WID ("program_label")); + + dialog->p->ext_store = gtk_tree_store_new (1, G_TYPE_STRING); + + view = GTK_TREE_VIEW (WID ("ext_list")); + gtk_tree_view_set_model (view, GTK_TREE_MODEL (dialog->p->ext_store)); + + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_insert_column_with_attributes (view, -1, _("Extension"), renderer, "text", 0, NULL); + + dialog->p->dialog_win = gtk_dialog_new_with_buttons + (_("Edit file type"), NULL, -1, + GTK_STOCK_OK, GTK_RESPONSE_OK, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + NULL); + + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog->p->dialog_win)->vbox), WID ("edit_widget"), TRUE, TRUE, 0); + + g_signal_connect_swapped (G_OBJECT (WID ("add_ext_button")), "clicked", (GCallback) add_ext_cb, dialog); + g_signal_connect_swapped (G_OBJECT (WID ("remove_ext_button")), "clicked", (GCallback) remove_ext_cb, dialog); + g_signal_connect_swapped (G_OBJECT (WID ("default_action_select")), "changed", (GCallback) default_action_changed_cb, dialog); + + g_signal_connect_swapped (G_OBJECT (dialog->p->dialog_win), "response", (GCallback) response_cb, dialog); +} + +static void +mime_edit_dialog_base_init (MimeEditDialogClass *class) +{ +} + +static void +mime_edit_dialog_class_init (MimeEditDialogClass *class) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (class); + + object_class->dispose = mime_edit_dialog_dispose; + object_class->finalize = mime_edit_dialog_finalize; + object_class->set_property = mime_edit_dialog_set_prop; + object_class->get_property = mime_edit_dialog_get_prop; + + g_object_class_install_property + (object_class, PROP_MIME_TYPE_INFO, + g_param_spec_pointer ("mime-type-info", + _("MIME type info"), + _("Information on MIME type to edit"), + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + parent_class = G_OBJECT_CLASS + (g_type_class_ref (G_TYPE_OBJECT)); +} + +static void +mime_edit_dialog_set_prop (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + MimeEditDialog *mime_edit_dialog; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_MIME_EDIT_DIALOG (object)); + + mime_edit_dialog = MIME_EDIT_DIALOG (object); + + switch (prop_id) { + case PROP_MIME_TYPE_INFO: + mime_edit_dialog->p->info = g_value_get_pointer (value); + fill_dialog (mime_edit_dialog); + break; + + default: + g_warning ("Bad property set"); + break; + } +} + +static void +mime_edit_dialog_get_prop (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + MimeEditDialog *mime_edit_dialog; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_MIME_EDIT_DIALOG (object)); + + mime_edit_dialog = MIME_EDIT_DIALOG (object); + + switch (prop_id) { + case PROP_MIME_TYPE_INFO: + g_value_set_pointer (value, mime_edit_dialog->p->info); + break; + + default: + g_warning ("Bad property get"); + break; + } +} + +static void +mime_edit_dialog_dispose (GObject *object) +{ + MimeEditDialog *dialog; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_MIME_EDIT_DIALOG (object)); + + dialog = MIME_EDIT_DIALOG (object); + + if (dialog->p->dialog_xml != NULL) { + g_object_unref (G_OBJECT (dialog->p->dialog_xml)); + dialog->p->dialog_xml = NULL; + } + + if (dialog->p->dialog_win != NULL) { + gtk_widget_destroy (GTK_WIDGET (dialog->p->dialog_win)); + dialog->p->dialog_win = NULL; + } + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +mime_edit_dialog_finalize (GObject *object) +{ + MimeEditDialog *mime_edit_dialog; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_MIME_EDIT_DIALOG (object)); + + mime_edit_dialog = MIME_EDIT_DIALOG (object); + + g_free (mime_edit_dialog->p); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +GObject * +mime_edit_dialog_new (MimeTypeInfo *info) +{ + return g_object_new (mime_edit_dialog_get_type (), + "mime-type-info", info, + NULL); +} + +GObject * +mime_add_dialog_new (void) +{ + return g_object_new (mime_edit_dialog_get_type (), + "mime-type-info", g_new0 (MimeTypeInfo, 1), + NULL); +} + +static void +fill_dialog (MimeEditDialog *dialog) +{ + gtk_entry_set_text (GTK_ENTRY (WID ("description_entry")), dialog->p->info->description); + gtk_entry_set_text (GTK_ENTRY (WID ("mime_type_entry")), dialog->p->info->mime_type); + + if (dialog->p->info->custom_line != NULL) + gnome_file_entry_set_filename (GNOME_FILE_ENTRY (WID ("program_entry")), dialog->p->info->custom_line); + + if (dialog->p->info->mime_type != NULL && *dialog->p->info->mime_type != '\0') + gtk_widget_set_sensitive (WID ("mime_type_entry"), FALSE); + + if (dialog->p->info->icon_name == NULL) + gnome_icon_entry_set_filename (GNOME_ICON_ENTRY (WID ("icon_entry")), "nautilus/i-regular-24.png"); + else + gnome_icon_entry_set_filename (GNOME_ICON_ENTRY (WID ("icon_entry")), dialog->p->info->icon_name); + + populate_component_list (dialog); + populate_application_list (dialog); + populate_extensions_list (dialog); + + gtk_widget_show_all (dialog->p->dialog_win); +} + +static void +populate_component_list (MimeEditDialog *dialog) +{ + GList *component_list, *tmp; + GtkMenu *menu; + GtkWidget *menu_item; + GtkOptionMenu *component_select; + gchar *component_name; + Bonobo_ServerInfo *info; + int found_idx = -1, i; + + menu = GTK_MENU (gtk_menu_new ()); + + component_list = gnome_vfs_mime_get_short_list_components (dialog->p->info->mime_type); + + for (tmp = component_list, i = 0; tmp != NULL; tmp = tmp->next, i++) { + info = tmp->data; + + if (!strcmp (info->iid, dialog->p->info->default_component_id)) + found_idx = i; + + component_name = mime_type_get_pretty_name_for_server (info); + menu_item = gtk_menu_item_new_with_label (component_name); + g_free (component_name); + + /* Store copy of component name in item; free when item destroyed. */ + g_object_set_data_full (G_OBJECT (menu_item), + "iid", + g_strdup (info->iid), + (GDestroyNotify) g_free); + + gtk_menu_append (menu, menu_item); + gtk_widget_show (menu_item); + } + + gtk_menu_append (menu, gtk_menu_item_new_with_label (_("None"))); + + if (found_idx < 0) + found_idx = i; + + component_select = GTK_OPTION_MENU (WID ("component_select")); + gtk_option_menu_set_menu (component_select, GTK_WIDGET (menu)); + gtk_option_menu_set_history (component_select, found_idx); + + gnome_vfs_mime_component_list_free (component_list); +} + +static void +populate_application_list (MimeEditDialog *dialog) +{ + GList *app_list, *tmp; + GtkMenu *menu; + GtkWidget *menu_item; + GtkOptionMenu *app_select; + GnomeVFSMimeApplication *app; + int found_idx = -1, i; + + menu = GTK_MENU (gtk_menu_new ()); + + app_list = gnome_vfs_mime_get_short_list_applications (dialog->p->info->mime_type); + + for (tmp = app_list, i = 0; tmp != NULL; tmp = tmp->next, i++) { + app = tmp->data; + + if (!strcmp (app->id, dialog->p->info->default_action->id)) + found_idx = i; + + menu_item = gtk_menu_item_new_with_label (app->name); + + /* Store copy of application in item; free when item destroyed. */ + g_object_set_data_full (G_OBJECT (menu_item), + "app", app, + (GDestroyNotify) gnome_vfs_mime_application_free); + + gtk_menu_append (menu, menu_item); + gtk_widget_show (menu_item); + } + + gtk_menu_append (menu, gtk_menu_item_new_with_label (_("Custom"))); + + if (found_idx < 0) { + found_idx = i; + gnome_file_entry_set_filename (GNOME_FILE_ENTRY (WID ("program_entry")), + dialog->p->info->default_action->command); + } else { + gtk_widget_set_sensitive (WID ("program_entry_box"), FALSE); + } + + app_select = GTK_OPTION_MENU (WID ("default_action_select")); + gtk_option_menu_set_menu (app_select, GTK_WIDGET (menu)); + gtk_option_menu_set_history (app_select, found_idx); + + g_list_free (app_list); +} + +static void +populate_extensions_list (MimeEditDialog *dialog) +{ + GList *tmp; + GtkTreeIter iter; + + for (tmp = dialog->p->info->file_extensions; tmp != NULL; tmp = tmp->next) { + gtk_tree_store_append (dialog->p->ext_store, &iter, NULL); + gtk_tree_store_set (dialog->p->ext_store, &iter, 0, tmp->data, -1); + } +} + +static GList * +collect_filename_extensions (MimeEditDialog *dialog) +{ + GtkTreeIter iter; + GValue value; + GList *ret = NULL; + + gtk_tree_model_get_iter_root (GTK_TREE_MODEL (dialog->p->ext_store), &iter); + + value.g_type = G_TYPE_INVALID; + + do { + gtk_tree_model_get_value (GTK_TREE_MODEL (dialog->p->ext_store), &iter, 0, &value); + ret = g_list_prepend (ret, g_value_dup_string (&value)); + g_value_unset (&value); + } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (dialog->p->ext_store), &iter)); + + return ret; +} + +static GList * +merge_ext_lists (GList *list1, GList *list2) +{ + GList *tmp, *tmp1; + + for (tmp = list2; tmp != NULL; tmp = tmp->next) { + for (tmp1 = list1; tmp1 != NULL && strcmp (tmp->data, tmp1->data); tmp1 = tmp1->next); + + if (tmp1 == NULL) + list1 = g_list_prepend (list1, g_strdup (tmp->data)); + } + + return list1; +} + +static void +store_data (MimeEditDialog *dialog) +{ + GtkOptionMenu *option_menu; + GtkMenuShell *menu_shell; + GObject *menu_item; + gint idx; + + GList *ext_list; + + g_free (dialog->p->info->description); + dialog->p->info->description = g_strdup (gtk_entry_get_text (GTK_ENTRY (WID ("description_entry")))); + + g_free (dialog->p->info->mime_type); + dialog->p->info->mime_type = g_strdup (gtk_entry_get_text (GTK_ENTRY (WID ("mime_type_entry")))); + + g_free (dialog->p->info->icon_name); + dialog->p->info->icon_name = g_strdup (gnome_icon_entry_get_filename (GNOME_ICON_ENTRY (WID ("icon_entry")))); + + option_menu = GTK_OPTION_MENU (WID ("component_select")); + menu_shell = GTK_MENU_SHELL (gtk_option_menu_get_menu (option_menu)); + idx = gtk_option_menu_get_history (option_menu); + menu_item = (g_list_nth (menu_shell->children, idx))->data; + + g_free (dialog->p->info->default_component_id); + dialog->p->info->default_component_id = g_strdup (g_object_get_data (menu_item, "iid")); + + option_menu = GTK_OPTION_MENU (WID ("default_action_select")); + menu_shell = GTK_MENU_SHELL (gtk_option_menu_get_menu (option_menu)); + idx = gtk_option_menu_get_history (option_menu); + menu_item = (g_list_nth (menu_shell->children, idx))->data; + + gnome_vfs_mime_application_free (dialog->p->info->default_action); + dialog->p->info->default_action = gnome_vfs_mime_application_copy (g_object_get_data (menu_item, "app")); + + g_free (dialog->p->info->custom_line); + dialog->p->info->custom_line = g_strdup (gnome_file_entry_get_full_path (GNOME_FILE_ENTRY (WID ("program_entry")), FALSE)); + + ext_list = collect_filename_extensions (dialog); + dialog->p->info->file_extensions = merge_ext_lists (dialog->p->info->file_extensions, ext_list); + g_list_foreach (ext_list, (GFunc) g_free, NULL); + g_list_free (ext_list); + + mime_type_append_to_dirty_list (dialog->p->info); +} + +static void +add_ext_cb (MimeEditDialog *dialog) +{ + GladeXML *add_dialog_xml; + GtkWidget *add_dialog; + GtkWidget *add_widget; + GtkWidget *ext_entry; + gint response_id; + GtkTreeIter iter; + + add_dialog_xml = glade_xml_new (GNOMECC_DATA_DIR "/interfaces/file-types-properties.glade", "add_ext_widget", NULL); + + add_dialog = gtk_dialog_new_with_buttons + (_("Add filename extension"), NULL, -1, + GTK_STOCK_OK, GTK_RESPONSE_OK, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + NULL); + + add_widget = glade_xml_get_widget (add_dialog_xml, "add_ext_widget"); + ext_entry = glade_xml_get_widget (add_dialog_xml, "add_ext_entry"); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (add_dialog)->vbox), add_widget, TRUE, TRUE, 0); + + gtk_widget_show_all (add_dialog); + + response_id = gtk_dialog_run (GTK_DIALOG (add_dialog)); + + if (response_id == GTK_RESPONSE_OK) { + gtk_tree_store_append (dialog->p->ext_store, &iter, NULL); + gtk_tree_store_set (dialog->p->ext_store, &iter, 0, + gtk_entry_get_text (GTK_ENTRY (ext_entry))); + } + + gtk_widget_destroy (GTK_WIDGET (add_dialog)); + g_object_unref (G_OBJECT (add_dialog_xml)); +} + +static void +remove_ext_foreach_cb (GtkTreeModel *model, GtkTreePath *path, + GtkTreeIter *iter) +{ + gtk_tree_store_remove (GTK_TREE_STORE (model), iter); +} + +static void +remove_ext_cb (MimeEditDialog *dialog) +{ + gtk_tree_selection_selected_foreach (gtk_tree_view_get_selection (GTK_TREE_VIEW (WID ("ext_list"))), + (GtkTreeSelectionForeachFunc) remove_ext_foreach_cb, NULL); +} + +static void +default_action_changed_cb (MimeEditDialog *dialog) +{ + int id; + GtkOptionMenu *option_menu; + GtkMenuShell *menu; + + option_menu = GTK_OPTION_MENU (WID ("default_action_select")); + menu = GTK_MENU_SHELL (gtk_option_menu_get_menu (option_menu)); + id = gtk_option_menu_get_history (option_menu); + + if (id == g_list_length (menu->children) - 1) + gtk_widget_set_sensitive (WID ("program_entry_box"), TRUE); + else + gtk_widget_set_sensitive (WID ("program_entry_box"), FALSE); +} + +static void +response_cb (MimeEditDialog *dialog, gint response_id) +{ + if (response_id == GTK_RESPONSE_OK) + store_data (dialog); + + g_object_unref (G_OBJECT (dialog)); +} diff --git a/capplets/file-types/mime-edit-dialog.h b/capplets/file-types/mime-edit-dialog.h new file mode 100644 index 000000000..c1e1f37e7 --- /dev/null +++ b/capplets/file-types/mime-edit-dialog.h @@ -0,0 +1,60 @@ +/* -*- mode: c; style: linux -*- */ + +/* mime-edit-dialog.h + * Copyright (C) 2001 Ximian, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef __MIME_EDIT_DIALOG_H +#define __MIME_EDIT_DIALOG_H + +#include + +#include "mime-type-info.h" + +G_BEGIN_DECLS + +#define MIME_EDIT_DIALOG(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, mime_edit_dialog_get_type (), MimeEditDialog) +#define MIME_EDIT_DIALOG_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, mime_edit_dialog_get_type (), MimeEditDialogClass) +#define IS_MIME_EDIT_DIALOG(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, mime_edit_dialog_get_type ()) + +typedef struct _MimeEditDialog MimeEditDialog; +typedef struct _MimeEditDialogClass MimeEditDialogClass; +typedef struct _MimeEditDialogPrivate MimeEditDialogPrivate; + +struct _MimeEditDialog +{ + GObject parent; + + MimeEditDialogPrivate *p; +}; + +struct _MimeEditDialogClass +{ + GObjectClass g_object_class; +}; + +GType mime_edit_dialog_get_type (void); + +GObject *mime_edit_dialog_new (MimeTypeInfo *info); +GObject *mime_add_dialog_new (void); + +G_END_DECLS + +#endif /* __MIME_EDIT_DIALOG_H */ diff --git a/capplets/file-types/mime-type-info.c b/capplets/file-types/mime-type-info.c new file mode 100644 index 000000000..aaccb8ff8 --- /dev/null +++ b/capplets/file-types/mime-type-info.c @@ -0,0 +1,193 @@ +/* -*- mode: c; style: linux -*- */ + +/* mime-type-info.c + * + * Copyright (C) 2000 Eazel, Inc. + * Copyright (C) 2002 Ximian, Inc. + * + * Written by Bradford Hovinen , + * Jonathan Blandford , + * Gene Z. Ragan + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "mime-type-info.h" + +static GList *dirty_list = NULL; + +static GSList * +get_lang_list (void) +{ + GSList *retval; + const char *lang; + char *equal_char; + + retval = NULL; + + lang = g_getenv ("LANGUAGE"); + + if (lang == NULL) + lang = g_getenv ("LANG"); + + + if (lang != NULL) { + equal_char = strchr (lang, '='); + if (equal_char != NULL) + lang = equal_char + 1; + + retval = g_slist_prepend (retval, g_strdup (lang)); + } + + return retval; +} + +MimeTypeInfo * +mime_type_info_load (const gchar *mime_type) +{ + MimeTypeInfo *info; + Bonobo_ServerInfo *component_info; + + info = g_new0 (MimeTypeInfo, 1); + info->mime_type = g_strdup (mime_type); + info->description = g_strdup (gnome_vfs_mime_get_description (mime_type)); + info->icon_name = g_strdup (gnome_vfs_mime_get_icon (mime_type)); + info->file_extensions = gnome_vfs_mime_get_extensions_list (mime_type); + info->edit_line = g_strdup (gnome_vfs_mime_get_value (mime_type, "edit-line")); + info->print_line = g_strdup (gnome_vfs_mime_get_value (mime_type, "print-line")); + info->default_action = gnome_vfs_mime_get_default_application (mime_type); + info->custom_line = g_strdup (gnome_vfs_mime_get_value (mime_type, "custom-line")); + + component_info = gnome_vfs_mime_get_default_component (mime_type); + + if (component_info != NULL) { + info->default_component_id = component_info->iid; + CORBA_free (component_info); + } + + return info; +} + +void +mime_type_info_save (const MimeTypeInfo *info) +{ + gchar *tmp; + gchar **array; + GList *l; + gint i = 0; + + gnome_vfs_mime_set_description (info->mime_type, info->description); + gnome_vfs_mime_set_icon (info->mime_type, info->icon_name); + gnome_vfs_mime_set_default_application (info->mime_type, info->default_action->id); + gnome_vfs_mime_set_value (info->mime_type, "custom-line", info->custom_line); + gnome_vfs_mime_set_value (info->mime_type, "print-line", info->print_line); + gnome_vfs_mime_set_value (info->mime_type, "edit-line", info->edit_line); + + array = g_new0 (gchar *, g_list_length (info->file_extensions) + 1); + for (l = info->file_extensions; l != NULL; l = l->next) + array[i++] = l->data; + tmp = g_strjoinv (" ", array); + g_free (array); + + gnome_vfs_mime_set_extensions_list (info->mime_type, tmp); + g_free (tmp); +} + +void +mime_type_info_free (MimeTypeInfo *info) +{ + g_free (info->mime_type); + g_free (info->description); + g_free (info->icon_name); + gnome_vfs_mime_extensions_list_free (info->file_extensions); + g_free (info->default_component_id); + gnome_vfs_mime_application_free (info->default_action); + g_free (info->custom_line); + g_free (info->edit_line); + g_free (info->print_line); + g_free (info); +} + +char * +mime_type_get_pretty_name_for_server (Bonobo_ServerInfo *server) +{ + const char *view_as_name; + char *display_name; + GSList *langs; + + display_name = NULL; + + langs = get_lang_list (); + view_as_name = bonobo_server_info_prop_lookup (server, "nautilus:view_as_name", langs); + + if (view_as_name == NULL) + view_as_name = bonobo_server_info_prop_lookup (server, "name", langs); + + if (view_as_name == NULL) + view_as_name = server->iid; + + g_slist_foreach (langs, (GFunc) g_free, NULL); + g_slist_free (langs); + + /* if the name is an OAFIID, clean it up for display */ + if (!strncmp (view_as_name, "OAFIID:", strlen ("OAFIID:"))) { + char *display_name, *colon_ptr; + + display_name = g_strdup (view_as_name + strlen ("OAFIID:")); + colon_ptr = strchr (display_name, ':'); + if (colon_ptr) + *colon_ptr = '\0'; + + return display_name; + } + + return g_strdup_printf ("View as %s", view_as_name); +} + +void +mime_type_append_to_dirty_list (MimeTypeInfo *info) +{ + if (g_list_find (dirty_list, info) == NULL) + dirty_list = g_list_prepend (dirty_list, info); +} + +void +mime_type_remove_from_dirty_list (const gchar *mime_type) +{ + GList *tmp = dirty_list, *tmp1; + + while (tmp != NULL) { + tmp1 = tmp->next; + if (!strcmp (mime_type, ((MimeTypeInfo *) tmp->data)->mime_type)) + dirty_list = g_list_remove_link (dirty_list, tmp); + tmp = tmp1; + } +} + +void +mime_type_commit_dirty_list (void) +{ + gnome_vfs_mime_freeze (); + g_list_foreach (dirty_list, (GFunc) mime_type_info_save, NULL); + gnome_vfs_mime_thaw (); +} + diff --git a/capplets/file-types/mime-type-info.h b/capplets/file-types/mime-type-info.h new file mode 100644 index 000000000..e3ba48506 --- /dev/null +++ b/capplets/file-types/mime-type-info.h @@ -0,0 +1,62 @@ +/* -*- mode: c; style: linux -*- */ + +/* mime-type-info.h + * + * Copyright (C) 2002 Ximian, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __MIME_TYPE_INFO_H +#define __MIME_TYPE_INFO_H + +#include +#include +#include + +G_BEGIN_DECLS + +typedef struct _MimeTypeInfo MimeTypeInfo; + +struct _MimeTypeInfo +{ + gchar *mime_type; + gchar *description; + gchar *icon_name; + GList *file_extensions; + + gchar *default_component_id; + GnomeVFSMimeApplication *default_action; + gchar *custom_line; + gchar *edit_line; + gchar *print_line; +}; + +MimeTypeInfo *mime_type_info_load (const gchar *mime_type); +void mime_type_info_save (const MimeTypeInfo *info); +void mime_type_info_free (MimeTypeInfo *info); + +char *mime_type_get_pretty_name_for_server (Bonobo_ServerInfo *server); + +void mime_type_append_to_dirty_list (MimeTypeInfo *info); +void mime_type_remove_from_dirty_list (const gchar *mime_type); +void mime_type_commit_dirty_list (void); + +G_END_DECLS + +#endif /* __MIME_TYPE_INFO_H */ diff --git a/capplets/file-types/mime-types-model.c b/capplets/file-types/mime-types-model.c new file mode 100644 index 000000000..97a1985ec --- /dev/null +++ b/capplets/file-types/mime-types-model.c @@ -0,0 +1,308 @@ +/* -*- mode: c; style: linux -*- */ + +/* mime-types-model.c + * + * Copyright (C) 2002 Ximian, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include +#include + +#include "mime-types-model.h" + +const gchar *categories[] = { + "Documents", "Images", "Audio", "Video", "Internet Services", NULL +}; + +const gchar *url_descriptions[][2] = { + { "unknown", N_("Unknown service types") }, + { "http", N_("World wide web") }, + { "ftp", N_("File transfer protocol") }, + { "info", N_("Detailed documentation") }, + { "man", N_("Manual pages") }, + { "mailto", N_("Electronic mail transmission") }, + { NULL, NULL } +}; + +static GdkPixbuf * +get_icon_pixbuf (const gchar *short_icon_name) +{ + gchar *icon_name; + GdkPixbuf *pixbuf, *pixbuf1; + + static GHashTable *pixbuf_table; + + if (pixbuf_table == NULL) + pixbuf_table = g_hash_table_new (g_str_hash, g_str_equal); + + if (short_icon_name == NULL) + short_icon_name = "nautilus/i-regular-24.png"; + + icon_name = gnome_program_locate_file + (gnome_program_get (), GNOME_FILE_DOMAIN_PIXMAP, + short_icon_name, TRUE, NULL); + + if (icon_name != NULL) { + pixbuf1 = g_hash_table_lookup (pixbuf_table, icon_name); + + if (pixbuf1 != NULL) { + g_object_ref (G_OBJECT (pixbuf1)); + } else { + pixbuf = gdk_pixbuf_new_from_file (icon_name, NULL); + + if (pixbuf == NULL) + pixbuf = get_icon_pixbuf (NULL); + + pixbuf1 = gdk_pixbuf_scale_simple (pixbuf, 16, 16, GDK_INTERP_BILINEAR); + g_object_unref (G_OBJECT (pixbuf)); + } + + g_free (icon_name); + } else { + pixbuf1 = get_icon_pixbuf (NULL); + } + + return pixbuf1; +} + +static gchar * +get_category_path_for_mime_type (const gchar *mime_type) +{ + gchar *path; + + path = gnome_vfs_mime_get_value (mime_type, "category"); + + if (path != NULL) + return path; + else if (!strncmp (mime_type, "image", strlen ("image"))) + return "Images"; + else if (!strncmp (mime_type, "video", strlen ("video"))) + return "Video"; + else if (!strncmp (mime_type, "audio", strlen ("audio"))) + return "Audio"; + else + return NULL; +} + +static void +get_path_num_from_str (GtkTreeStore *model, GtkTreeIter *iter, const gchar *path_str, GString *path_num) +{ + gchar *first_component; + gchar *rest_components; + GValue value; + GtkTreeIter child_iter; + int i, n; + + if (path_str == NULL || *path_str == '\0') + return; + + rest_components = strchr (path_str, '/'); + + if (rest_components != NULL) { + first_component = g_strndup (path_str, rest_components - path_str); + rest_components++; + } else { + first_component = g_strdup (path_str); + } + + gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &child_iter, iter); + n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), iter); + + value.g_type = G_TYPE_INVALID; + + for (i = 0; i < n; i++) { + gtk_tree_model_get_value (GTK_TREE_MODEL (model), &child_iter, DESCRIPTION_COLUMN, &value); + + if (!strcmp (first_component, g_value_get_string (&value))) { + g_string_append_printf (path_num, ":%d", i); + get_path_num_from_str (model, &child_iter, rest_components, path_num); + g_free (first_component); + return; + } + + gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &child_iter); + g_value_unset (&value); + } + + gtk_tree_store_append (model, &child_iter, iter); + gtk_tree_store_set (model, &child_iter, DESCRIPTION_COLUMN, first_component, -1); + g_string_append_printf (path_num, ":%d", n); + g_free (first_component); +} + +static void +get_insertion_point (GtkTreeStore *model, const gchar *path_str, GtkTreeIter *iter) +{ + GString *path_num; + + path_num = g_string_new (""); + get_path_num_from_str (model, NULL, path_str, path_num); + gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (model), iter, path_num->str + 1); + g_string_free (path_num, TRUE); +} + +static const gchar * +get_protocol_name (const gchar *key) +{ + gchar *protocol_name; + + protocol_name = strrchr (key, '/'); + + if (protocol_name != NULL) + return protocol_name + 1; + else + return NULL; +} + +static gchar * +get_description_for_protocol (const gchar *protocol_name) +{ + gchar *description; + gchar *key; + int i; + + key = g_strconcat ("/desktop/gnome/url-handlers/", protocol_name, "/description", NULL); + description = gconf_client_get_string (gconf_client_get_default (), key, NULL); + g_free (key); + + if (description != NULL) + return description; + + for (i = 0; url_descriptions[i][0] != NULL; i++) + if (!strcmp (url_descriptions[i][0], protocol_name)) + return g_strdup (url_descriptions[i][1]); + + return NULL; +} + +GtkTreeModel * +mime_types_model_new (void) +{ + GtkTreeStore *model; + GList *type_list; + GList *tmp; + GtkTreeIter iter; + GtkTreeIter child_iter; + gchar *mime_type; + gchar *path_str; + const gchar *description; + const gchar *extensions; + GdkPixbuf *pixbuf; + + GSList *url_list; + GSList *tmps; + const gchar *protocol_name; + gchar *protocol_desc; + + gint i; + + model = gtk_tree_store_new (4, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); + + tmp = type_list = gnome_vfs_get_registered_mime_types (); + + for (i = 0; categories[i] != NULL; i++) { + gtk_tree_store_append (model, &iter, NULL); + gtk_tree_store_set (model, &iter, DESCRIPTION_COLUMN, categories[i], -1); + } + + for (; tmp != NULL; tmp = tmp->next) { + mime_type = tmp->data; + path_str = get_category_path_for_mime_type (mime_type); + + if (path_str != NULL) { + description = gnome_vfs_mime_get_description (mime_type); + extensions = gnome_vfs_mime_get_extensions_pretty_string (mime_type); + + if (extensions == NULL || *extensions == '\0') + continue; + + pixbuf = get_icon_pixbuf (gnome_vfs_mime_get_icon (mime_type)); + + get_insertion_point (model, path_str, &iter); + + gtk_tree_store_append (model, &child_iter, &iter); + gtk_tree_store_set (model, &child_iter, + ICON_COLUMN, pixbuf, + DESCRIPTION_COLUMN, description, + MIME_TYPE_COLUMN, mime_type, + EXTENSIONS_COLUMN, extensions, + -1); + } + } + + g_list_free (type_list); + + tmps = url_list = gconf_client_all_dirs + (gconf_client_get_default (), "/desktop/gnome/url-handlers", NULL); + + get_insertion_point (model, "Internet Services", &iter); + + for (; tmps != NULL; tmps = tmps->next) { + protocol_name = get_protocol_name (tmps->data); + + if (protocol_name == NULL) + continue; + + protocol_desc = get_description_for_protocol (protocol_name); + + gtk_tree_store_append (model, &child_iter, &iter); + gtk_tree_store_set (model, &child_iter, + DESCRIPTION_COLUMN, protocol_desc, + MIME_TYPE_COLUMN, protocol_name, + -1); + + if (strcmp (protocol_name, "unknown")) + gtk_tree_store_set (model, &child_iter, EXTENSIONS_COLUMN, protocol_name, -1); + + g_free (protocol_desc); + g_free (tmps->data); + } + + g_slist_free (url_list); + + return GTK_TREE_MODEL (model); +} + +gboolean +model_entry_is_protocol (GtkTreeModel *model, GtkTreeIter *iter) +{ + GtkTreeIter parent_iter; + GtkTreePath *parent_path, *child_path; + gboolean ret; + + get_insertion_point (GTK_TREE_STORE (model), "Internet Services", &parent_iter); + + parent_path = gtk_tree_model_get_path (model, &parent_iter); + child_path = gtk_tree_model_get_path (model, iter); + ret = gtk_tree_path_is_ancestor (parent_path, child_path); + gtk_tree_path_free (parent_path); + gtk_tree_path_free (child_path); + + return ret; +} + diff --git a/capplets/file-types/mime-types-model.h b/capplets/file-types/mime-types-model.h new file mode 100644 index 000000000..c2344e0cc --- /dev/null +++ b/capplets/file-types/mime-types-model.h @@ -0,0 +1,45 @@ +/* -*- mode: c; style: linux -*- */ + +/* mime-types-model.h + * + * Copyright (C) 2002 Ximian, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __MIME_TYPES_MODEL_H +#define __MIME_TYPES_MODEL_H + +#include + +G_BEGIN_DECLS + +enum { + ICON_COLUMN, + DESCRIPTION_COLUMN, + MIME_TYPE_COLUMN, + EXTENSIONS_COLUMN +}; + +GtkTreeModel *mime_types_model_new (void); + +gboolean model_entry_is_protocol (GtkTreeModel *model, GtkTreeIter *iter); + +G_END_DECLS + +#endif /* __MIME_TYPES_MODEL_H */ diff --git a/capplets/file-types/service-edit-dialog.c b/capplets/file-types/service-edit-dialog.c new file mode 100644 index 000000000..b2d0089c5 --- /dev/null +++ b/capplets/file-types/service-edit-dialog.c @@ -0,0 +1,270 @@ +/* -*- mode: c; style: linux -*- */ + +/* service-edit-dialog.c + * Copyright (C) 2001 Ximian, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "service-edit-dialog.h" + +#define WID(x) (glade_xml_get_widget (dialog->p->dialog_xml, x)) + +enum { + PROP_0, + PROP_SERVICE_INFO +}; + +struct _ServiceEditDialogPrivate +{ + ServiceInfo *info; + GladeXML *dialog_xml; + GtkWidget *dialog_win; +}; + +static GObjectClass *parent_class; + +static void service_edit_dialog_init (ServiceEditDialog *dialog, + ServiceEditDialogClass *class); +static void service_edit_dialog_class_init (ServiceEditDialogClass *class); +static void service_edit_dialog_base_init (ServiceEditDialogClass *class); + +static void service_edit_dialog_set_prop (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void service_edit_dialog_get_prop (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static void service_edit_dialog_dispose (GObject *object); +static void service_edit_dialog_finalize (GObject *object); + +static void fill_dialog (ServiceEditDialog *dialog); +static void populate_app_list (ServiceEditDialog *dialog); + +static void response_cb (ServiceEditDialog *dialog); + +GType +service_edit_dialog_get_type (void) +{ + static GType service_edit_dialog_type = 0; + + if (!service_edit_dialog_type) { + GTypeInfo service_edit_dialog_info = { + sizeof (ServiceEditDialogClass), + (GBaseInitFunc) service_edit_dialog_base_init, + NULL, /* GBaseFinalizeFunc */ + (GClassInitFunc) service_edit_dialog_class_init, + NULL, /* GClassFinalizeFunc */ + NULL, /* user-supplied data */ + sizeof (ServiceEditDialog), + 0, /* n_preallocs */ + (GInstanceInitFunc) service_edit_dialog_init, + NULL + }; + + service_edit_dialog_type = + g_type_register_static (G_TYPE_OBJECT, + "ServiceEditDialog", + &service_edit_dialog_info, 0); + } + + return service_edit_dialog_type; +} + +static void +service_edit_dialog_init (ServiceEditDialog *dialog, ServiceEditDialogClass *class) +{ + GtkSizeGroup *size_group; + + dialog->p = g_new0 (ServiceEditDialogPrivate, 1); + dialog->p->dialog_xml = glade_xml_new + (GNOMECC_DATA_DIR "/interfaces/file-types-properties.glade", "service_edit_widget", NULL); + + size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + gtk_size_group_add_widget (size_group, WID ("description_label")); + gtk_size_group_add_widget (size_group, WID ("protocol_label")); + + dialog->p->dialog_win = gtk_dialog_new_with_buttons + (_("Edit file type"), NULL, -1, + GTK_STOCK_OK, GTK_RESPONSE_OK, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + NULL); + + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog->p->dialog_win)->vbox), WID ("service_edit_widget"), TRUE, TRUE, 0); + + g_signal_connect_swapped (G_OBJECT (dialog->p->dialog_win), "response", (GCallback) response_cb, dialog); +} + +static void +service_edit_dialog_base_init (ServiceEditDialogClass *class) +{ +} + +static void +service_edit_dialog_class_init (ServiceEditDialogClass *class) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (class); + + object_class->dispose = service_edit_dialog_dispose; + object_class->finalize = service_edit_dialog_finalize; + object_class->set_property = service_edit_dialog_set_prop; + object_class->get_property = service_edit_dialog_get_prop; + + g_object_class_install_property + (object_class, PROP_SERVICE_INFO, + g_param_spec_pointer ("service-info", + _("Servie information"), + _("Data structure containing service information"), + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + parent_class = G_OBJECT_CLASS + (g_type_class_ref (G_TYPE_OBJECT)); +} + +static void +service_edit_dialog_set_prop (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + ServiceEditDialog *dialog; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_SERVICE_EDIT_DIALOG (object)); + + dialog = SERVICE_EDIT_DIALOG (object); + + switch (prop_id) { + case PROP_SERVICE_INFO: + dialog->p->info = g_value_get_pointer (value); + fill_dialog (dialog); + break; + + default: + g_warning ("Bad property set"); + break; + } +} + +static void +service_edit_dialog_get_prop (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + ServiceEditDialog *dialog; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_SERVICE_EDIT_DIALOG (object)); + + dialog = SERVICE_EDIT_DIALOG (object); + + switch (prop_id) { + case PROP_SERVICE_INFO: + g_value_set_pointer (value, dialog->p->info); + break; + + default: + g_warning ("Bad property get"); + break; + } +} + +static void +service_edit_dialog_dispose (GObject *object) +{ + ServiceEditDialog *dialog; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_SERVICE_EDIT_DIALOG (object)); + + dialog = SERVICE_EDIT_DIALOG (object); + + if (dialog->p->dialog_win != NULL) { + gtk_widget_destroy (dialog->p->dialog_win); + dialog->p->dialog_win = NULL; + } + + if (dialog->p->dialog_xml != NULL) { + g_object_unref (G_OBJECT (dialog->p->dialog_xml)); + dialog->p->dialog_xml = NULL; + } + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +service_edit_dialog_finalize (GObject *object) +{ + ServiceEditDialog *service_edit_dialog; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_SERVICE_EDIT_DIALOG (object)); + + service_edit_dialog = SERVICE_EDIT_DIALOG (object); + + g_free (service_edit_dialog->p); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +GObject * +service_edit_dialog_new (ServiceInfo *info) +{ + return g_object_new (service_edit_dialog_get_type (), + "service-info", info, + NULL); +} + +static void +fill_dialog (ServiceEditDialog *dialog) +{ + if (dialog->p->info->description != NULL) + gtk_entry_set_text (GTK_ENTRY (WID ("description_entry")), dialog->p->info->description); + + if (dialog->p->info->protocol != NULL) + gtk_entry_set_text (GTK_ENTRY (WID ("protocol_entry")), dialog->p->info->protocol); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("look_at_content_toggle")), dialog->p->info->use_content); + + if (dialog->p->info->use_content && strcmp (dialog->p->info->protocol, "ftp")) + gtk_widget_set_sensitive (WID ("program_frame"), FALSE); + + if (dialog->p->info->custom_line != NULL) + gnome_file_entry_set_filename (GNOME_FILE_ENTRY (WID ("custom_program_entry")), dialog->p->info->custom_line); + + populate_app_list (dialog); + + gtk_widget_show_all (dialog->p->dialog_win); +} + +static void +populate_app_list (ServiceEditDialog *dialog) +{ +} + +static void +response_cb (ServiceEditDialog *dialog) +{ + g_object_unref (G_OBJECT (dialog)); +} diff --git a/capplets/file-types/service-edit-dialog.h b/capplets/file-types/service-edit-dialog.h new file mode 100644 index 000000000..299c4f379 --- /dev/null +++ b/capplets/file-types/service-edit-dialog.h @@ -0,0 +1,59 @@ +/* -*- mode: c; style: linux -*- */ + +/* service-edit-dialog.h + * Copyright (C) 2001 Ximian, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef __SERVICE_EDIT_DIALOG_H +#define __SERVICE_EDIT_DIALOG_H + +#include + +#include "service-info.h" + +G_BEGIN_DECLS + +#define SERVICE_EDIT_DIALOG(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, service_edit_dialog_get_type (), ServiceEditDialog) +#define SERVICE_EDIT_DIALOG_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, service_edit_dialog_get_type (), ServiceEditDialogClass) +#define IS_SERVICE_EDIT_DIALOG(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, service_edit_dialog_get_type ()) + +typedef struct _ServiceEditDialog ServiceEditDialog; +typedef struct _ServiceEditDialogClass ServiceEditDialogClass; +typedef struct _ServiceEditDialogPrivate ServiceEditDialogPrivate; + +struct _ServiceEditDialog +{ + GObject parent; + + ServiceEditDialogPrivate *p; +}; + +struct _ServiceEditDialogClass +{ + GObjectClass g_object_class; +}; + +GType service_edit_dialog_get_type (void); + +GObject *service_edit_dialog_new (ServiceInfo *info); + +G_END_DECLS + +#endif /* __SERVICE_EDIT_DIALOG_H */ diff --git a/capplets/file-types/service-info.c b/capplets/file-types/service-info.c new file mode 100644 index 000000000..7df647701 --- /dev/null +++ b/capplets/file-types/service-info.c @@ -0,0 +1,163 @@ +/* -*- mode: c; style: linux -*- */ + +/* service-info.c + * + * Copyright (C) 2002 Ximian, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "service-info.h" + +static gchar * +get_key_name (const ServiceInfo *info, gchar *end) +{ + return g_strconcat ("/desktop/gnome/url-handlers/", info->protocol, "/", end, NULL); +} + +static void +set_string (const ServiceInfo *info, gchar *end, gchar *value, GConfChangeSet *changeset) +{ + gchar *key; + + key = get_key_name (info, end); + + if (changeset != NULL) + gconf_change_set_set_string (changeset, key, value); + else + gconf_client_set_string (gconf_client_get_default (), key, value, NULL); + + g_free (key); +} + +static void +set_bool (const ServiceInfo *info, gchar *end, gboolean value, GConfChangeSet *changeset) +{ + gchar *key; + + key = get_key_name (info, end); + + if (changeset != NULL) + gconf_change_set_set_bool (changeset, key, value); + else + gconf_client_set_bool (gconf_client_get_default (), key, value, NULL); + + g_free (key); +} + +static gchar * +get_string (const ServiceInfo *info, gchar *end, GConfChangeSet *changeset) +{ + gchar *key, *ret; + GConfValue *value; + gboolean found; + + key = get_key_name (info, end); + + if (changeset != NULL) + found = gconf_change_set_check_value (changeset, key, &value); + + if (!found || changeset == NULL) { + ret = gconf_client_get_string (gconf_client_get_default (), key, NULL); + } else { + ret = g_strdup (gconf_value_get_string (value)); + gconf_value_free (value); + } + + g_free (key); + + return ret; +} + +static gboolean +get_bool (const ServiceInfo *info, gchar *end, GConfChangeSet *changeset) +{ + gchar *key; + gboolean ret; + GConfValue *value; + gboolean found; + + key = get_key_name (info, end); + + if (changeset != NULL) + found = gconf_change_set_check_value (changeset, key, &value); + + if (!found || changeset == NULL) { + ret = gconf_client_get_bool (gconf_client_get_default (), key, NULL); + } else { + ret = gconf_value_get_bool (value); + gconf_value_free (value); + } + + g_free (key); + + return ret; +} + +ServiceInfo * +service_info_load (const gchar *protocol, GConfChangeSet *changeset) +{ + ServiceInfo *info; + gchar *id; + + info = g_new0 (ServiceInfo, 1); + info->protocol = g_strdup (protocol); + info->description = get_string (info, "description", changeset); + info->use_content = get_bool (info, "use-content", changeset); + info->custom_line = get_string (info, "command", changeset); + info->need_terminal = get_bool (info, "need-terminal", changeset); + + id = get_string (info, "command-id", changeset); + if (id != NULL) + info->app = gnome_vfs_mime_application_new_from_id (id); + g_free (id); + + return info; +} + +void +service_info_save (const ServiceInfo *info, GConfChangeSet *changeset) +{ + set_string (info, "description", info->description, changeset); + + if (info->app == NULL) { + set_string (info, "command", info->custom_line, changeset); + set_string (info, "command-id", "", changeset); + } else { + set_string (info, "command", info->app->command, changeset); + set_string (info, "command-id", info->app->id, changeset); + } + + set_bool (info, "use-content", info->use_content, changeset); + set_bool (info, "need-terminal", info->need_terminal, changeset); +} + +void +service_info_free (ServiceInfo *info) +{ + g_free (info->protocol); + g_free (info->description); + gnome_vfs_mime_application_free (info->app); + g_free (info->custom_line); +} diff --git a/capplets/file-types/service-info.h b/capplets/file-types/service-info.h new file mode 100644 index 000000000..d8740cc14 --- /dev/null +++ b/capplets/file-types/service-info.h @@ -0,0 +1,55 @@ +/* -*- mode: c; style: linux -*- */ + +/* service-info.h + * + * Copyright (C) 2002 Ximian, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __SERVICE_INFO_H +#define __SERVICE_INFO_H + +#include +#include +#include +#include + +G_BEGIN_DECLS + +typedef struct _ServiceInfo ServiceInfo; + +struct _ServiceInfo { + gchar *protocol; + gchar *description; + gboolean use_content; + + GnomeVFSMimeApplication *app; + gchar *custom_line; + gboolean need_terminal; +}; + +ServiceInfo *service_info_load (const gchar *protocol, + GConfChangeSet *changeset); +void service_info_save (const ServiceInfo *info, + GConfChangeSet *changeset); +void service_info_free (ServiceInfo *info); + +G_END_DECLS + +#endif /* __SERVICE_INFO_H */