summaryrefslogtreecommitdiff
path: root/capplets
diff options
context:
space:
mode:
authorRamiro Estrugo <ramiro@src.gnome.org>2000-05-23 23:23:57 +0000
committerRamiro Estrugo <ramiro@src.gnome.org>2000-05-23 23:23:57 +0000
commit674dd004d828cfa7a47107de97b0248e96b949ed (patch)
treeb70c1d773a768d5c39b10037b6d12cf2ac02a0e8 /capplets
parent7b219f893b64cd9b611c5f1388d43ff17a183137 (diff)
downloadgnome-control-center-674dd004d828cfa7a47107de97b0248e96b949ed.tar.gz
mime-type-capplet/edit-window.c, mime-type-capplet/edit-window.h,
* Makefile.am: * configure.in: * mime-type-capplet/.cvsignore: * mime-type-capplet/Makefile.am: * mime-type-capplet/edit-window.c, * mime-type-capplet/edit-window.h, * mime-type-capplet/mime-data.c, * mime-type-capplet/mime-data.h, * mime-type-capplet/mime-info.c, * mime-type-capplet/mime-info.h, * mime-type-capplet/mime-type-capplet.c, * mime-type-capplet/mime-type.desktop, * mime-type-capplet/new-mime-window.c, * mime-type-capplet/new-mime-window.h: Copy mime-type capplet from the control-center so that it can be improved and made to use gnome-vfs. This has the unfortunate side-effect of introducing a dependency on libcapplet. This is temporary until the capplet can move back to the control-center. At that time, the control-center will depend on gnome-vfs and eveyone will live happily ever after.
Diffstat (limited to 'capplets')
-rw-r--r--capplets/file-types/.cvsignore5
-rw-r--r--capplets/file-types/Makefile.am29
-rw-r--r--capplets/file-types/edit-window.c577
-rw-r--r--capplets/file-types/edit-window.h15
-rw-r--r--capplets/file-types/mime-data.c656
-rw-r--r--capplets/file-types/mime-data.h34
-rw-r--r--capplets/file-types/mime-info.c492
-rw-r--r--capplets/file-types/mime-info.h17
-rw-r--r--capplets/file-types/mime-type-capplet.c142
-rw-r--r--capplets/file-types/mime-type.desktop52
-rw-r--r--capplets/file-types/new-mime-window.c116
-rw-r--r--capplets/file-types/new-mime-window.h14
12 files changed, 2149 insertions, 0 deletions
diff --git a/capplets/file-types/.cvsignore b/capplets/file-types/.cvsignore
new file mode 100644
index 000000000..695625db1
--- /dev/null
+++ b/capplets/file-types/.cvsignore
@@ -0,0 +1,5 @@
+Makefile
+Makefile.in
+.deps
+.libs
+mime-type-capplet
diff --git a/capplets/file-types/Makefile.am b/capplets/file-types/Makefile.am
new file mode 100644
index 000000000..245761ce2
--- /dev/null
+++ b/capplets/file-types/Makefile.am
@@ -0,0 +1,29 @@
+INCLUDES = -I. -I$(srcdir) \
+ -I$(top_srcdir)/intl -I$(top_builddir)/intl \
+ $(CAPPLET_INCLUDEDIR) \
+ $(GNOME_INCLUDEDIR) \
+ -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
+ -I$(includedir)
+
+bin_PROGRAMS = mime-type-capplet
+
+mime_type_capplet_SOURCES = mime-type-capplet.c\
+ mime-data.h mime-data.c edit-window.c\
+ edit-window.h mime-info.c mime-info.h \
+ new-mime-window.h new-mime-window.c
+
+mime_type_capplet_LDADD =\
+ $(CAPPLET_LIBDIR) \
+ $(CAPPLET_LIBS)
+ $(ORBIT_LIBS) \
+ $(INTLLIBS)
+
+EXTRA_DIST = \
+ mime-type.desktop
+
+
+sysdir = $(datadir)/control-center
+sys_DATA = mime-type.desktop
+
+install-data-local:
+ $(INSTALL_DATA) $(srcdir)/mime-type.desktop $(DESTDIR)$(datadir)/gnome/apps/Settings/mime-type.desktop
diff --git a/capplets/file-types/edit-window.c b/capplets/file-types/edit-window.c
new file mode 100644
index 000000000..e87c70c69
--- /dev/null
+++ b/capplets/file-types/edit-window.c
@@ -0,0 +1,577 @@
+#include "edit-window.h"
+#include "mime-data.h"
+#include "mime-info.h"
+#include "capplet-widget.h"
+
+
+extern GtkWidget *capplet;
+extern GHashTable *user_mime_types;
+
+typedef struct {
+ GtkWidget *window;
+ GtkWidget *icon_entry;
+ GtkWidget *mime_type;
+/* GtkWidget *ext_tag_label; */
+ GtkWidget *regexp1_tag_label;
+ GtkWidget *regexp2_tag_label;
+/* GtkWidget *ext_label; */
+ GtkWidget *regexp1_label;
+ GtkWidget *regexp2_label;
+ GtkWidget *open_entry;
+ GtkWidget *edit_entry;
+ GtkWidget *view_entry;
+ GtkWidget *ext_scroll;
+ GtkWidget *ext_clist;
+ GtkWidget *ext_entry;
+ GtkWidget *ext_add_button;
+ GtkWidget *ext_remove_button;
+ MimeInfo *mi;
+ MimeInfo *user_mi;
+ GList *tmp_ext[2];
+} edit_window;
+static edit_window *main_win = NULL;
+static gboolean changing = TRUE;
+static void
+destruction_handler (GtkWidget *widget, gpointer data)
+{
+ g_free (main_win);
+ main_win = NULL;
+}
+static void
+entry_changed (GtkWidget *widget, gpointer data)
+{
+ if (changing == FALSE)
+ capplet_widget_state_changed (CAPPLET_WIDGET (capplet),
+ TRUE);
+}
+static void
+ext_clist_selected (GtkWidget *clist, gint row, gint column, gpointer data)
+{
+ gboolean deletable;
+
+ deletable = GPOINTER_TO_INT (gtk_clist_get_row_data (GTK_CLIST (clist), row));
+ if (deletable)
+ gtk_widget_set_sensitive (main_win->ext_remove_button, TRUE);
+ else
+ gtk_widget_set_sensitive (main_win->ext_remove_button, FALSE);
+}
+static void
+ext_clist_deselected (GtkWidget *clist, gint row, gint column, gpointer data)
+{
+ if (g_list_length (GTK_CLIST (clist)->selection) == 0)
+ gtk_widget_set_sensitive (main_win->ext_remove_button, FALSE);
+}
+static void
+ext_entry_changed (GtkWidget *entry, gpointer data)
+{
+ gchar *text;
+ text = gtk_entry_get_text (GTK_ENTRY (entry));
+ gtk_widget_set_sensitive (main_win->ext_add_button, (strlen (text) >0));
+}
+static void
+ext_add (GtkWidget *widget, gpointer data)
+{
+ gchar *row[1];
+ gint rownumber;
+
+ row[0] = g_strdup (gtk_entry_get_text (GTK_ENTRY (main_win->ext_entry)));
+ rownumber = gtk_clist_append (GTK_CLIST (main_win->ext_clist), row);
+ gtk_clist_set_row_data (GTK_CLIST (main_win->ext_clist), rownumber,
+ GINT_TO_POINTER (TRUE));
+ gtk_entry_set_text (GTK_ENTRY (main_win->ext_entry), "");
+
+ main_win->tmp_ext[0] = g_list_prepend (main_win->tmp_ext[0], row[0]);
+ if (changing == FALSE)
+ capplet_widget_state_changed (CAPPLET_WIDGET (capplet),
+ TRUE);
+}
+static void
+ext_remove (GtkWidget *widget, gpointer data)
+{
+ gint row;
+ gchar *text;
+ gchar *store;
+ GList *tmp;
+
+ text = (gchar *)g_malloc (sizeof (gchar) * 1024);
+ gtk_clist_freeze (GTK_CLIST (main_win->ext_clist));
+ row = GPOINTER_TO_INT (GTK_CLIST (main_win->ext_clist)->selection->data);
+ gtk_clist_get_text (GTK_CLIST (main_win->ext_clist), row, 0, &text);
+ store = g_strdup (text);
+ gtk_clist_remove (GTK_CLIST (main_win->ext_clist), row);
+
+ gtk_clist_thaw (GTK_CLIST (main_win->ext_clist));
+
+ for (tmp = main_win->tmp_ext[0]; tmp; tmp = tmp->next) {
+ GList *found;
+
+ if (strcmp (tmp->data, store) == 0) {
+ found = tmp;
+
+ main_win->tmp_ext[0] = g_list_remove_link (main_win->tmp_ext[0], found);
+ g_list_free_1 (found);
+ break;
+ }
+ }
+
+ if (changing == FALSE)
+ capplet_widget_state_changed (CAPPLET_WIDGET (capplet),
+ TRUE);
+}
+static void
+apply_entry_change (GtkWidget *entry, gchar *key, MimeInfo *mi)
+{
+ const gchar *buf;
+ gchar *text;
+ /* buf is the value that existed before when we
+ * started the capplet */
+ buf = local_mime_get_value (mi->mime_type, key);
+ if (buf == NULL)
+ buf = gnome_mime_get_value (mi->mime_type, key);
+ text = gtk_entry_get_text (GTK_ENTRY (entry));
+ if (text && !*text)
+ text = NULL;
+
+ /* First we see if they've added something. */
+ if (buf == NULL && text)
+ set_mime_key_value (mi->mime_type, key, text);
+ else {
+ /* Has the value changed? */
+ if (text && strcmp (text, buf))
+ set_mime_key_value (mi->mime_type, key, text);
+ else
+ /* We _REALLY_ need a way to specify in
+ * user.keys not to use the system defaults.
+ * (ie. override the system default and
+ * query it).
+ * If we could then we'd set it here. */
+ ;
+ }
+}
+static GList*
+copy_mi_extensions (GList *orig)
+{
+ GList *tmp;
+ GList *list = NULL;
+
+ for (tmp = orig; tmp; tmp = tmp->next) {
+ list = g_list_append (list, g_strdup (tmp->data));
+ }
+ return list;
+}
+static void
+make_readable (MimeInfo *mi)
+{
+ GList *list;
+ GString *extension;
+
+ extension = g_string_new ("");
+ for (list = ((MimeInfo *) mi)->user_ext[0]; list; list = list->next) {
+ g_string_append (extension, (gchar *) list->data);
+ if (list->next != NULL)
+ g_string_append (extension, ", ");
+ }
+ mi->ext_readable[0] = extension->str;
+ g_string_free (extension, FALSE);
+
+ extension = g_string_new ("");
+ for (list = ((MimeInfo *) mi)->user_ext[1]; list; list = list->next) {
+ g_string_append (extension, (gchar *) list->data);
+ if (list->next != NULL)
+ g_string_append (extension, ", ");
+ }
+ mi->ext_readable[1] = extension->str;
+ g_string_free (extension, FALSE);
+}
+static void
+apply_changes (MimeInfo *mi)
+{
+ GList *tmp;
+ int i;
+
+ apply_entry_change (gnome_icon_entry_gtk_entry (GNOME_ICON_ENTRY (main_win->icon_entry)),
+ "icon-filename", mi);
+ apply_entry_change (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (main_win->open_entry)),
+ "open", mi);
+ apply_entry_change (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (main_win->view_entry)),
+ "view", mi);
+ apply_entry_change (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (main_win->edit_entry)),
+ "edit", mi);
+
+ if (!main_win->user_mi) {
+ add_to_key (mi->mime_type, "ext: tmp", user_mime_types, TRUE);
+ /* the tmp extension will be removed when we copy the tmp_ext
+ * stuff over the top of it.
+ */
+ main_win->user_mi = g_hash_table_lookup (user_mime_types,
+ mi->mime_type);
+ }
+
+ for (i = 0; i < 2; i++) {
+ if (main_win->tmp_ext[i]) {
+ main_win->user_mi->user_ext[i] = copy_mi_extensions (main_win->tmp_ext[i]);
+ mi->user_ext[i] = copy_mi_extensions (main_win->tmp_ext[i]);
+ } else {
+ main_win->user_mi->user_ext[i] = NULL;
+ mi->user_ext[i] = NULL;
+ }
+ }
+
+ make_readable (main_win->user_mi);
+
+ if (! (main_win->user_mi->ext[0] || main_win->user_mi->ext[1] ||
+ main_win->user_mi->user_ext[0] || main_win->user_mi->ext[1]))
+ g_hash_table_remove (user_mime_types, mi->mime_type);
+
+ /* Free the 2 tmp lists */
+ for (i = 0; i < 2; i++) {
+ if (main_win->tmp_ext[i])
+ for (tmp = main_win->tmp_ext[i]; tmp; tmp = tmp->next)
+ g_free (tmp->data);
+ }
+ if (changing == FALSE)
+ capplet_widget_state_changed (CAPPLET_WIDGET (capplet),
+ TRUE);
+}
+
+#if 0
+static void
+browse_callback (GtkWidget *widget, gpointer data)
+{
+}
+#endif
+
+static void
+initialize_main_win ()
+{
+ GtkWidget *align, *vbox, *hbox, *vbox2, *vbox3;
+ GtkWidget *frame, *table, *label;
+/* GtkWidget *button; */
+/* GString *extension; */
+ gchar *title[2] = {"Extensions"};
+
+ main_win = g_new (edit_window, 1);
+ main_win->window = gnome_dialog_new ("",
+ GNOME_STOCK_BUTTON_OK,
+ GNOME_STOCK_BUTTON_CANCEL,
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (main_win->window),
+ "destroy",
+ destruction_handler,
+ NULL);
+ vbox = GNOME_DIALOG (main_win->window)->vbox;
+
+ /* icon box */
+ main_win->icon_entry = gnome_icon_entry_new ("mime_icon_entry", _("Select an icon..."));
+ align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
+ gtk_container_add (GTK_CONTAINER (align), main_win->icon_entry);
+ gtk_signal_connect (GTK_OBJECT (gnome_icon_entry_gtk_entry (GNOME_ICON_ENTRY (main_win->icon_entry))),
+ "changed",
+ entry_changed,
+ NULL);
+ gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
+
+ hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
+ gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("Mime Type: ")), FALSE, FALSE, 0);
+ main_win->mime_type = gtk_label_new ("");
+ gtk_box_pack_start (GTK_BOX (hbox), main_win->mime_type, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+
+ /* extension/regexp */
+ vbox2 = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
+ gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0);
+
+ hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
+ main_win->ext_clist = gtk_clist_new_with_titles (1, title);
+ gtk_clist_column_titles_passive (GTK_CLIST (main_win->ext_clist));
+ gtk_clist_set_auto_sort (GTK_CLIST (main_win->ext_clist), TRUE);
+
+ gtk_signal_connect (GTK_OBJECT (main_win->ext_clist),
+ "select-row",
+ GTK_SIGNAL_FUNC (ext_clist_selected),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (main_win->ext_clist),
+ "unselect-row",
+ GTK_SIGNAL_FUNC (ext_clist_deselected),
+ NULL);
+ main_win->ext_scroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (main_win->ext_scroll),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ gtk_container_add (GTK_CONTAINER (main_win->ext_scroll),
+ main_win->ext_clist);
+
+ vbox3 = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
+ main_win->ext_add_button = gtk_button_new_with_label (_("Add"));
+ gtk_signal_connect (GTK_OBJECT (main_win->ext_add_button),
+ "clicked",
+ GTK_SIGNAL_FUNC (ext_add),
+ NULL);
+ gtk_box_pack_start (GTK_BOX (vbox3), main_win->ext_add_button, FALSE, FALSE, 0);
+ gtk_widget_set_sensitive (main_win->ext_add_button, FALSE);
+
+ main_win->ext_remove_button = gtk_button_new_with_label (_("Remove"));
+ gtk_signal_connect (GTK_OBJECT (main_win->ext_remove_button),
+ "clicked",
+ GTK_SIGNAL_FUNC (ext_remove),
+ NULL);
+ gtk_widget_set_sensitive (main_win->ext_remove_button, FALSE);
+ gtk_box_pack_start (GTK_BOX (vbox3), main_win->ext_remove_button,
+ FALSE, FALSE, 0);
+
+ gtk_box_pack_start (GTK_BOX (hbox), main_win->ext_scroll, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), vbox3, FALSE, FALSE, 0);
+
+ gtk_box_pack_start (GTK_BOX (vbox2), hbox, TRUE, TRUE, 0);
+
+ main_win->ext_entry = gtk_entry_new ();
+ gtk_signal_connect (GTK_OBJECT (main_win->ext_entry),
+ "changed",
+ ext_entry_changed,
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (main_win->ext_entry),
+ "activate",
+ ext_add,
+ NULL);
+ gtk_box_pack_start (GTK_BOX (vbox2), main_win->ext_entry, TRUE, TRUE, 0);
+
+ hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
+ main_win->regexp1_label = gtk_label_new ("");
+ main_win->regexp1_tag_label = gtk_label_new (_("First Regular Expression: "));
+ gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), main_win->regexp1_tag_label,
+ FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), main_win->regexp1_label, FALSE, FALSE, 0);
+
+ hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
+ main_win->regexp2_label = gtk_label_new ("");
+ main_win->regexp2_tag_label = gtk_label_new (_("Second Regular Expression: "));
+ gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), main_win->regexp2_tag_label,
+ FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), main_win->regexp2_label, FALSE, FALSE, 0);
+
+ /* Actions box */
+ frame = gtk_frame_new (_("Mime Type Actions"));
+ vbox2 = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
+ gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
+ table = gtk_table_new (3, 2, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), GNOME_PAD_SMALL);
+ gtk_container_set_border_width (GTK_CONTAINER (table), GNOME_PAD_SMALL);
+ gtk_container_add (GTK_CONTAINER (frame), vbox2);
+ label = gtk_label_new (_("Example: emacs %f"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_misc_set_padding (GTK_MISC (label), 2, 0);
+ gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox2), table, FALSE, FALSE, 0);
+ label = gtk_label_new (_("Open"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_misc_set_padding (GTK_MISC (label), 2, 0);
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ label,
+ 0, 1, 0, 1);
+ main_win->open_entry = gnome_file_entry_new ("MIME_CAPPLET_OPEN", _("Select a file..."));
+ gtk_signal_connect (GTK_OBJECT (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (main_win->open_entry))),
+ "changed",
+ entry_changed,
+ NULL);
+
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ main_win->open_entry,
+ 1, 2, 0, 1);
+ label = gtk_label_new (_("View"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_misc_set_padding (GTK_MISC (label), 2, 0);
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ label,
+ 0, 1, 1, 2);
+
+ main_win->view_entry = gnome_file_entry_new ("MIME_CAPPLET_VIEW", _("Select a file..."));
+ gtk_signal_connect (GTK_OBJECT (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (main_win->view_entry))),
+ "changed",
+ entry_changed,
+ NULL);
+
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ main_win->view_entry,
+ 1, 2, 1, 2);
+ label = gtk_label_new (_("Edit"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_misc_set_padding (GTK_MISC (label), 2, 0);
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ label,
+ 0, 1, 2, 3);
+ main_win->edit_entry = gnome_file_entry_new ("MIME_CAPPLET_EDIT", _("Select a file..."));
+ gtk_signal_connect (GTK_OBJECT (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (main_win->edit_entry))),
+ "changed",
+ entry_changed,
+ NULL);
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ main_win->edit_entry,
+ 1, 2, 2, 3);
+}
+static void
+setup_entry (gchar *key, GtkWidget *g_entry, MimeInfo *mi)
+{
+ const gchar *buf;
+ GtkWidget *entry = gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (g_entry));
+ buf = local_mime_get_value (mi->mime_type, key);
+ if (buf == NULL)
+ buf = gnome_mime_get_value (mi->mime_type, key);
+ if (buf)
+ gtk_entry_set_text (GTK_ENTRY (entry), buf);
+ else
+ gtk_entry_set_text (GTK_ENTRY (entry), "");
+}
+void
+initialize_main_win_vals (void)
+{
+ MimeInfo *mi;
+ gchar *title;
+ gboolean showext = FALSE;
+ if (main_win == NULL)
+ return;
+ mi = main_win->mi;
+ if (mi == NULL)
+ return;
+ /* now we fill in the fields with the mi stuff. */
+
+ changing = TRUE;
+ gtk_label_set_text (GTK_LABEL (main_win->mime_type), mi->mime_type);
+ gnome_icon_entry_set_icon (GNOME_ICON_ENTRY (main_win->icon_entry),
+ gnome_mime_get_value (mi->mime_type,
+ "icon-filename"));
+
+ gtk_widget_show_all (GNOME_DIALOG (main_win->window)->vbox);
+ /* we initialize everything */
+ title = g_strdup_printf (_("Set actions for %s"), mi->mime_type);
+ gtk_window_set_title (GTK_WINDOW (main_win->window), title);
+ g_free (title);
+
+ /* not sure why this is necessary */
+ gtk_clist_clear (GTK_CLIST (main_win->ext_clist));
+ if (mi->ext[0]) {
+ GList *tmp;
+ gchar *extension[1];
+ gint row;
+ for (tmp = mi->ext[0]; tmp; tmp = tmp->next) {
+ extension[0] = g_strdup (tmp->data);
+ row = gtk_clist_append (GTK_CLIST (main_win->ext_clist),
+ extension);
+ gtk_clist_set_row_data (GTK_CLIST (main_win->ext_clist),
+ row, GINT_TO_POINTER (FALSE));
+ }
+ showext = TRUE;
+ }
+ if (mi->ext[1]) {
+ GList *tmp;
+ gchar *extension[1];
+ gint row;
+ for (tmp = mi->ext[1]; tmp; tmp = tmp->next) {
+ extension[0] = g_strdup (tmp->data);
+ row = gtk_clist_append (GTK_CLIST (main_win->ext_clist),
+ extension);
+ gtk_clist_set_row_data (GTK_CLIST (main_win->ext_clist),
+ row, GINT_TO_POINTER (FALSE));
+ }
+ showext = TRUE;
+ }
+ if (main_win->tmp_ext[0]) {
+ GList *tmp;
+ gchar *extension[1];
+ gint row;
+ for (tmp = main_win->tmp_ext[0]; tmp; tmp = tmp->next) {
+ extension[0] = g_strdup (tmp->data);
+ row = gtk_clist_append (GTK_CLIST (main_win->ext_clist),
+ extension);
+ gtk_clist_set_row_data (GTK_CLIST (main_win->ext_clist),
+ row, GINT_TO_POINTER (TRUE));
+ }
+ showext = TRUE;
+ }
+ if (main_win->tmp_ext[1]) {
+ GList *tmp;
+ gchar *extension[1];
+ gint row;
+ for (tmp = main_win->tmp_ext[0]; tmp; tmp = tmp->next) {
+ extension[0] = g_strdup (tmp->data);
+ row = gtk_clist_append (GTK_CLIST (main_win->ext_clist),
+ extension);
+ gtk_clist_set_row_data (GTK_CLIST (main_win->ext_clist),
+ row, GINT_TO_POINTER (TRUE));
+ }
+ showext = TRUE;
+ }
+ if (!showext) {
+ gtk_widget_hide (main_win->ext_clist);
+ gtk_widget_hide (main_win->ext_entry);
+ gtk_widget_hide (main_win->ext_add_button);
+ gtk_widget_hide (main_win->ext_remove_button);
+ gtk_widget_hide (main_win->ext_scroll);
+ }
+ if (mi->regex_readable[0])
+ gtk_label_set_text (GTK_LABEL (main_win->regexp1_label),
+ mi->regex_readable[0]);
+ else {
+ gtk_widget_hide (main_win->regexp1_label);
+ gtk_widget_hide (main_win->regexp1_tag_label);
+ }
+ if (mi->regex_readable[1])
+ gtk_label_set_text (GTK_LABEL (main_win->regexp2_label),
+ mi->regex_readable[1]);
+ else {
+ gtk_widget_hide (main_win->regexp2_label);
+ gtk_widget_hide (main_win->regexp2_tag_label);
+ }
+ /* initialize the entries */
+ setup_entry ("open", main_win->open_entry, mi);
+ setup_entry ("view", main_win->view_entry, mi);
+ setup_entry ("edit", main_win->edit_entry, mi);
+ changing = FALSE;
+
+}
+void
+launch_edit_window (MimeInfo *mi)
+{
+/* gint size; */
+
+ if (main_win == NULL)
+ initialize_main_win ();
+ main_win->mi = mi;
+ main_win->user_mi = g_hash_table_lookup (user_mime_types, mi->mime_type);
+ main_win->tmp_ext[0] = NULL;
+ main_win->tmp_ext[1] = NULL;
+ if (main_win->user_mi) {
+ if (main_win->user_mi->user_ext[0])
+ main_win->tmp_ext[0] = copy_mi_extensions (main_win->user_mi->user_ext[0]);
+ if (main_win->user_mi->user_ext[1])
+ main_win->tmp_ext[1] = copy_mi_extensions (main_win->user_mi->user_ext[1]);
+ }
+ initialize_main_win_vals ();
+
+ switch(gnome_dialog_run (GNOME_DIALOG (main_win->window))) {
+ case 0:
+ apply_changes (mi);
+ case 1:
+ main_win->mi = NULL;
+ gtk_widget_hide (main_win->window);
+ break;
+ }
+}
+
+void
+hide_edit_window (void)
+{
+ if (main_win && main_win->mi && main_win->window)
+ gtk_widget_hide (main_win->window);
+}
+void
+show_edit_window (void)
+{
+ if (main_win && main_win->mi && main_win->window)
+ gtk_widget_show (main_win->window);
+}
+
+
+
+
diff --git a/capplets/file-types/edit-window.h b/capplets/file-types/edit-window.h
new file mode 100644
index 000000000..626a7c6be
--- /dev/null
+++ b/capplets/file-types/edit-window.h
@@ -0,0 +1,15 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* Copyright (C) 1998 Redhat Software Inc.
+ * Authors: Jonathan Blandford <jrb@redhat.com>
+ */
+#include "mime-data.h"
+#ifndef _EDIT_WINDOW_H_
+#define _EDIT_WINDOW_H_
+
+
+void launch_edit_window (MimeInfo *mi);
+void initialize_main_win_vals (void);
+void hide_edit_window (void);
+void show_edit_window (void);
+
+#endif
diff --git a/capplets/file-types/mime-data.c b/capplets/file-types/mime-data.c
new file mode 100644
index 000000000..f0dd56cb0
--- /dev/null
+++ b/capplets/file-types/mime-data.c
@@ -0,0 +1,656 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* Copyright (C) 1998 Redhat Software Inc.
+ * Authors: Jonathan Blandford <jrb@redhat.com>
+ */
+#include <config.h>
+#include "capplet-widget.h"
+#include "gnome.h"
+#include <string.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <regex.h>
+#include <ctype.h>
+#include "edit-window.h"
+#include "mime-data.h"
+#include "mime-info.h"
+#include "new-mime-window.h"
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+
+
+/* Prototypes */
+static void mime_fill_from_file (const char *filename, gboolean init_user);
+static void mime_load_from_dir (const char *mime_info_dir, gboolean system_dir);
+void add_to_key (char *mime_type, char *def, GHashTable *table, gboolean init_user);
+static char *get_priority (char *def, int *priority);
+
+
+/* Global variables */
+/* static char *current_lang; */
+static GHashTable *mime_types = NULL;
+static GHashTable *initial_user_mime_types = NULL;
+GHashTable *user_mime_types = NULL;
+static GtkWidget *clist = NULL;
+extern GtkWidget *delete_button;
+extern GtkWidget *capplet;
+/* Initialization functions */
+static void
+run_error (gchar *message)
+{
+ GtkWidget *error_box;
+
+ error_box = gnome_message_box_new (
+ message,
+ GNOME_MESSAGE_BOX_ERROR,
+ GNOME_STOCK_BUTTON_OK,
+ NULL);
+ gnome_dialog_run_and_close (GNOME_DIALOG (error_box));
+}
+static char *
+get_priority (char *def, int *priority)
+{
+ *priority = 0;
+
+ if (*def == ','){
+ def++;
+ if (*def == '1'){
+ *priority = 0;
+ def++;
+ } else if (*def == '2'){
+ *priority = 1;
+ def++;
+ }
+ }
+
+ while (*def && *def == ':')
+ def++;
+
+ return def;
+}
+static void
+free_mime_info (MimeInfo *mi)
+{
+
+}
+void
+add_to_key (char *mime_type, char *def, GHashTable *table, gboolean init_user)
+{
+ int priority = 1;
+ char *s, *p, *ext;
+ int used;
+ MimeInfo *info;
+
+ info = g_hash_table_lookup (table, (const void *) mime_type);
+ if (info == NULL) {
+ info = g_malloc (sizeof (MimeInfo));
+ info->mime_type = g_strdup (mime_type);
+ info->regex[0] = NULL;
+ info->regex[1] = NULL;
+ info->ext[0] = NULL;
+ info->ext[1] = NULL;
+ info->user_ext[0] = NULL;
+ info->user_ext[1] = NULL;
+ info->regex_readable[0] = NULL;
+ info->regex_readable[1] = NULL;
+ info->ext_readable[0] = NULL;
+ info->ext_readable[1] = NULL;
+ info->keys = gnome_mime_get_keys (mime_type);
+ g_hash_table_insert (table, info->mime_type, info);
+ }
+ if (strncmp (def, "ext", 3) == 0){
+ char *tokp;
+
+ def += 3;
+ def = get_priority (def, &priority);
+ s = p = g_strdup (def);
+
+ used = 0;
+
+ while ((ext = strtok_r (s, " \t\n\r,", &tokp)) != NULL){
+ /* FIXME: We really need to check for duplicates before entering this. */
+ if (!init_user) {
+ info->ext[priority] = g_list_prepend (info->ext[priority], ext);
+ } else {
+ info->user_ext[priority] = g_list_prepend (info->user_ext[priority], ext);
+ }
+ used = 1;
+ s = NULL;
+ }
+ if (!used)
+ g_free (p);
+ }
+
+ if (strncmp (def, "regex", 5) == 0){
+ regex_t *regex;
+
+ regex = g_new (regex_t, 1);
+ def += 5;
+ def = get_priority (def, &priority);
+
+ while (*def && isspace (*def))
+ def++;
+
+ if (!*def)
+ return;
+ if (regcomp (regex, def, REG_EXTENDED | REG_NOSUB))
+ g_free (regex);
+ else {
+ info->regex[priority] = regex;
+ g_free (info->regex_readable[priority]);
+ info->regex_readable[priority] = g_strdup (def);
+ }
+ }
+}
+static void
+mime_fill_from_file (const char *filename, gboolean init_user)
+{
+ FILE *f;
+ char buf [1024];
+ char *current_key;
+ gboolean used;
+
+ g_assert (filename != NULL);
+
+ f = fopen (filename, "r");
+ if (!f)
+ return;
+
+ current_key = NULL;
+ used = FALSE;
+ while (fgets (buf, sizeof (buf), f)){
+ char *p;
+
+ if (buf [0] == '#')
+ continue;
+
+ /* Trim trailing spaces */
+ for (p = buf + strlen (buf) - 1; p >= buf; p--){
+ if (isspace (*p) || *p == '\n')
+ *p = 0;
+ else
+ break;
+ }
+
+ if (!buf [0])
+ continue;
+
+ if (buf [0] == '\t' || buf [0] == ' '){
+ if (current_key){
+ char *p = buf;
+
+ while (*p && isspace (*p))
+ p++;
+
+ if (*p == 0)
+ continue;
+ add_to_key (current_key, p, mime_types, init_user);
+ if (init_user) {
+ add_to_key (current_key, p,
+ initial_user_mime_types,
+ TRUE);
+ add_to_key (current_key, p,
+ user_mime_types, TRUE);
+ }
+ used = TRUE;
+ }
+ } else {
+ if (!used && current_key)
+ g_free (current_key);
+ current_key = g_strdup (buf);
+ if (current_key [strlen (current_key)-1] == ':')
+ current_key [strlen (current_key)-1] = 0;
+
+ used = FALSE;
+ }
+ }
+ fclose (f);
+}
+
+static void
+mime_load_from_dir (const char *mime_info_dir, gboolean system_dir)
+{
+ DIR *dir;
+ struct dirent *dent;
+ const int extlen = sizeof (".mime") - 1;
+ char *filename;
+
+ dir = opendir (mime_info_dir);
+ if (!dir)
+ return;
+ if (system_dir) {
+ filename = g_concat_dir_and_file (mime_info_dir, "gnome.mime");
+ mime_fill_from_file (filename, FALSE);
+ g_free (filename);
+ }
+ while ((dent = readdir (dir)) != NULL){
+
+ int len = strlen (dent->d_name);
+
+ if (len <= extlen)
+ continue;
+
+ if (strcmp (dent->d_name + len - extlen, ".mime"))
+ continue;
+ if (system_dir && !strcmp (dent->d_name, "gnome.mime"))
+ continue;
+ if (!system_dir && !strcmp (dent->d_name, "user.mime"))
+ continue;
+
+ filename = g_concat_dir_and_file (mime_info_dir, dent->d_name);
+ mime_fill_from_file (filename, FALSE);
+ g_free (filename);
+ }
+ if (!system_dir) {
+ filename = g_concat_dir_and_file (mime_info_dir, "user.mime");
+ mime_fill_from_file (filename, TRUE);
+ g_free (filename);
+ }
+ closedir (dir);
+}
+static int
+add_mime_vals_to_clist (gchar *mime_type, gpointer mi, gpointer cl)
+{
+ /* we also finalize the MimeInfo structure here, now that we're done
+ * loading it */
+ static gchar *text[2];
+ GList *list;
+ GString *extension;
+ gint row;
+
+ extension = g_string_new ("");
+ for (list = ((MimeInfo *) mi)->ext[0];list; list=list->next) {
+ g_string_append (extension, (gchar *) list->data);
+ if (list->next != NULL)
+ g_string_append (extension, ", ");
+ }
+ if (strcmp (extension->str, "") != 0 && ((MimeInfo *)mi)->user_ext[0])
+ g_string_append (extension, ", ");
+ for (list = ((MimeInfo *) mi)->user_ext[0]; list; list=list->next) {
+ g_string_append (extension, (gchar *) list->data);
+ if (list->next != NULL)
+ g_string_append (extension, ", ");
+ }
+ ((MimeInfo *) mi)->ext_readable[0] = extension->str;
+ g_string_free (extension, FALSE);
+
+ extension = g_string_new ("");
+ for (list = ((MimeInfo *) mi)->ext[1];list; list=list->next) {
+ g_string_append (extension, (gchar *) list->data);
+ if (list->next)
+ g_string_append (extension, ", ");
+ }
+ if (strcmp (extension->str, "") != 0 && ((MimeInfo *)mi)->user_ext[1])
+ g_string_append (extension, ", ");
+ for (list = ((MimeInfo *) mi)->user_ext[1]; list; list=list->next) {
+ g_string_append (extension, (gchar *) list->data);
+ if (list->next != NULL)
+ g_string_append (extension, ", ");
+ }
+ ((MimeInfo *) mi)->ext_readable[1] = extension->str;
+ g_string_free (extension, FALSE);
+
+ if (((MimeInfo *) mi)->ext[0] || ((MimeInfo *) mi)->user_ext[0]) {
+ extension = g_string_new ((((MimeInfo *) mi)->ext_readable[0]));
+ if (((MimeInfo *) mi)->ext[1] || ((MimeInfo *) mi)->user_ext[1]) {
+ g_string_append (extension, ", ");
+ g_string_append (extension, (((MimeInfo *) mi)->ext_readable[1]));
+ }
+ } else if (((MimeInfo *) mi)->ext[1] || ((MimeInfo *) mi)->user_ext[1])
+ extension = g_string_new ((((MimeInfo *) mi)->ext_readable[1]));
+ else
+ extension = g_string_new ("");
+
+ text[0] = ((MimeInfo *) mi)->mime_type;
+ text[1] = extension->str;
+
+ row = gtk_clist_insert (GTK_CLIST (cl), 1, text);
+ gtk_clist_set_row_data (GTK_CLIST (cl), row, mi);
+ g_string_free (extension, TRUE);
+ return row;
+}
+static void
+selected_row_callback (GtkWidget *widget, gint row, gint column, GdkEvent *event, gpointer data)
+{
+ MimeInfo *mi;
+ if (column < 0)
+ return;
+
+ mi = (MimeInfo *) gtk_clist_get_row_data (GTK_CLIST (widget),row);
+
+ if (event && event->type == GDK_2BUTTON_PRESS)
+ launch_edit_window (mi);
+
+ if (g_hash_table_lookup (user_mime_types, mi->mime_type)) {
+ gtk_widget_set_sensitive (delete_button, TRUE);
+ } else
+ gtk_widget_set_sensitive (delete_button, FALSE);
+}
+
+/* public functions */
+void
+delete_clicked (GtkWidget *widget, gpointer data)
+{
+ MimeInfo *mi;
+ gint row = 0;
+
+ if (GTK_CLIST (clist)->selection)
+ row = GPOINTER_TO_INT ((GTK_CLIST (clist)->selection)->data);
+ else
+ return;
+ mi = (MimeInfo *) gtk_clist_get_row_data (GTK_CLIST (clist), row);
+
+ gtk_clist_remove (GTK_CLIST (clist), row);
+ g_hash_table_remove (user_mime_types, mi->mime_type);
+ remove_mime_info (mi->mime_type);
+ free_mime_info (mi);
+ capplet_widget_state_changed (CAPPLET_WIDGET (capplet),
+ TRUE);
+}
+
+void
+edit_clicked (GtkWidget *widget, gpointer data)
+{
+ MimeInfo *mi;
+ gint row = 0;
+
+ if (GTK_CLIST (clist)->selection)
+ row = GPOINTER_TO_INT ((GTK_CLIST (clist)->selection)->data);
+ else
+ return;
+ mi = (MimeInfo *) gtk_clist_get_row_data (GTK_CLIST (clist), row);
+ if (mi)
+ launch_edit_window (mi);
+ gtk_clist_remove (GTK_CLIST (clist), row);
+ row = add_mime_vals_to_clist (mi->mime_type, mi, clist);
+ gtk_clist_select_row (GTK_CLIST (clist), row, 0);
+}
+void
+add_clicked (GtkWidget *widget, gpointer data)
+{
+ launch_new_mime_window ();
+}
+
+GtkWidget *
+get_mime_clist (void)
+{
+ GtkWidget *retval;
+ gchar *titles[2];
+
+ titles[0] = _("Mime Type");
+ titles[1] = _("Extension");
+ retval = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (retval),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ clist = gtk_clist_new_with_titles (2, titles);
+ gtk_signal_connect (GTK_OBJECT (clist),
+ "select_row",
+ GTK_SIGNAL_FUNC (selected_row_callback),
+ NULL);
+ gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_BROWSE);
+ gtk_clist_set_auto_sort (GTK_CLIST (clist), TRUE);
+ if (clist)
+ g_hash_table_foreach (mime_types, (GHFunc) add_mime_vals_to_clist, clist);
+ gtk_clist_columns_autosize (GTK_CLIST (clist));
+ gtk_clist_select_row (GTK_CLIST (clist), 0, 0);
+ gtk_container_add (GTK_CONTAINER (retval), clist);
+ return retval;
+}
+
+static void
+finalize_mime_type_foreach (gpointer mime_type, gpointer info, gpointer data)
+{
+ MimeInfo *mi = (MimeInfo *)info;
+ GList *list;
+ GString *extension;
+
+ extension = g_string_new ("");
+ for (list = ((MimeInfo *) mi)->ext[0];list; list=list->next) {
+ g_string_append (extension, (gchar *) list->data);
+ if (list->next != NULL)
+ g_string_append (extension, ", ");
+ }
+ if (strcmp (extension->str, "") != 0 && mi->user_ext[0])
+ g_string_append (extension, ", ");
+ for (list = ((MimeInfo *) mi)->user_ext[0]; list; list=list->next) {
+ g_string_append (extension, (gchar *) list->data);
+ if (list->next != NULL)
+ g_string_append (extension, ", ");
+ }
+ ((MimeInfo *) mi)->ext_readable[0] = extension->str;
+ g_string_free (extension, FALSE);
+
+ extension = g_string_new ("");
+ for (list = ((MimeInfo *) mi)->ext[1];list; list=list->next) {
+ g_string_append (extension, (gchar *) list->data);
+ if (list->next)
+ g_string_append (extension, ", ");
+ }
+ if (strcmp (extension->str, "") != 0 && mi->user_ext[1])
+ g_string_append (extension, ", ");
+ for (list = ((MimeInfo *) mi)->user_ext[1]; list; list=list->next) {
+ g_string_append (extension, (gchar *) list->data);
+ if (list->next != NULL)
+ g_string_append (extension, ", ");
+ }
+ ((MimeInfo *) mi)->ext_readable[1] = extension->str;
+ g_string_free (extension, FALSE);
+
+ if (((MimeInfo *) mi)->ext[0] || ((MimeInfo *) mi)->user_ext[0]) {
+ extension = g_string_new ((((MimeInfo *) mi)->ext_readable[0]));
+ if (((MimeInfo *) mi)->ext[1] || ((MimeInfo *) mi)->user_ext[1]) {
+ g_string_append (extension, ", ");
+ g_string_append (extension, (((MimeInfo *) mi)->ext_readable[1]));
+ }
+ } else if (((MimeInfo *) mi)->ext[1] || ((MimeInfo *) mi)->user_ext[1])
+ extension = g_string_new ((((MimeInfo *) mi)->ext_readable[1]));
+ else
+ extension = g_string_new ("");
+ g_string_free (extension, TRUE);
+}
+static void
+finalize_user_mime ()
+{
+ g_hash_table_foreach (user_mime_types, finalize_mime_type_foreach, NULL);
+ g_hash_table_foreach (initial_user_mime_types, finalize_mime_type_foreach, NULL);
+}
+void
+init_mime_type (void)
+{
+ char *mime_info_dir;
+
+ mime_types = g_hash_table_new (g_str_hash, g_str_equal);
+ initial_user_mime_types = g_hash_table_new (g_str_hash, g_str_equal);
+ user_mime_types = g_hash_table_new (g_str_hash, g_str_equal);
+
+ mime_info_dir = gnome_unconditional_datadir_file ("mime-info");
+ mime_load_from_dir (mime_info_dir, TRUE);
+ g_free (mime_info_dir);
+
+ mime_info_dir = g_concat_dir_and_file (gnome_util_user_home (), ".gnome/mime-info");
+ mime_load_from_dir (mime_info_dir, FALSE);
+ g_free (mime_info_dir);
+ finalize_user_mime ();
+ init_mime_info ();
+}
+void
+add_new_mime_type (gchar *mime_type, gchar *raw_ext, gchar *regexp1, gchar *regexp2)
+{
+ gchar *temp;
+ MimeInfo *mi = NULL;
+ gint row;
+ gchar *ext = NULL;
+ gchar *ptr, *ptr2;
+
+ /* first we make sure that the information is good */
+ if (mime_type == NULL || *mime_type == '\000') {
+ run_error (_("You must enter a mime-type"));
+ return;
+ } else if ((raw_ext == NULL || *raw_ext == '\000') &&
+ (regexp1 == NULL || *regexp1 == '\000') &&
+ (regexp2 == NULL || *regexp2 == '\000')){
+ run_error (_("You must add either a regular-expression or\na file-name extension"));
+ return;
+ }
+ if (strchr (mime_type, '/') == NULL) {
+ run_error (_("Please put your mime-type in the format:\nCATEGORY/TYPE\n\nFor Example:\nimage/png"));
+ return;
+ }
+ if (g_hash_table_lookup (user_mime_types, mime_type) ||
+ g_hash_table_lookup (mime_types, mime_type)) {
+ run_error (_("This mime-type already exists"));
+ return;
+ }
+ if (raw_ext || *raw_ext) {
+ ptr2 = ext = g_malloc (sizeof (raw_ext));
+ for (ptr = raw_ext;*ptr; ptr++) {
+ if (*ptr != '.' && *ptr != ',') {
+ *ptr2 = *ptr;
+ ptr2 += 1;
+ }
+ }
+ *ptr2 = '\000';
+ }
+ /* passed check, now we add it. */
+ if (ext) {
+ temp = g_strconcat ("ext: ", ext, NULL);
+ add_to_key (mime_type, temp, user_mime_types, TRUE);
+ mi = (MimeInfo *) g_hash_table_lookup (user_mime_types, mime_type);
+ g_free (temp);
+ }
+ if (regexp1) {
+ temp = g_strconcat ("regex: ", regexp1, NULL);
+ add_to_key (mime_type, temp, user_mime_types, TRUE);
+ g_free (temp);
+ }
+ if (regexp2) {
+ temp = g_strconcat ("regex,2: ", regexp2, NULL);
+ add_to_key (mime_type, temp, user_mime_types, TRUE);
+ g_free (temp);
+ }
+ /* Finally add it to the clist */
+ if (mi) {
+ row = add_mime_vals_to_clist (mime_type, mi, clist);
+ gtk_clist_select_row (GTK_CLIST (clist), row, 0);
+ gtk_clist_moveto (GTK_CLIST (clist), row, 0, 0.5, 0.0);
+ }
+ g_free (ext);
+}
+static void
+write_mime_foreach (gpointer mime_type, gpointer info, gpointer data)
+{
+/* gchar *buf; */
+ MimeInfo *mi = (MimeInfo *) info;
+ fwrite ((char *) mi->mime_type, 1, strlen ((char *) mi->mime_type), (FILE *) data);
+ fwrite ("\n", 1, 1, (FILE *) data);
+ if (mi->ext_readable[0]) {
+ fwrite ("\text: ", 1, strlen ("\text: "), (FILE *) data);
+ fwrite (mi->ext_readable[0], 1,
+ strlen (mi->ext_readable[0]),
+ (FILE *) data);
+ fwrite ("\n", 1, 1, (FILE *) data);
+ }
+ if (mi->regex_readable[0]) {
+ fwrite ("\tregex: ", 1, strlen ("\tregex: "), (FILE *) data);
+ fwrite (mi->regex_readable[0], 1,
+ strlen (mi->regex_readable[0]),
+ (FILE *) data);
+ fwrite ("\n", 1, 1, (FILE *) data);
+ }
+ if (mi->regex_readable[1]) {
+ fwrite ("\tregex,2: ", 1, strlen ("\tregex,2: "), (FILE *) data);
+ fwrite (mi->regex_readable[1], 1,
+ strlen (mi->regex_readable[1]),
+ (FILE *) data);
+ fwrite ("\n", 1, 1, (FILE *) data);
+ }
+ fwrite ("\n", 1, 1, (FILE *) data);
+}
+
+static void
+write_mime (GHashTable *hash)
+{
+ struct stat s;
+ gchar *dirname, *filename;
+ FILE *file;
+/* GtkWidget *error_box; */
+
+ dirname = g_concat_dir_and_file (gnome_util_user_home (), ".gnome/mime-info");
+ if ((stat (dirname, &s) < 0) || !(S_ISDIR (s.st_mode))){
+ if (errno == ENOENT) {
+ if (mkdir (dirname, S_IRWXU) < 0) {
+ run_error (_("We are unable to create the directory\n"
+ "~/.gnome/mime-info\n\n"
+ "We will not be able to save the state."));
+ return;
+ }
+ } else {
+ run_error (_("We are unable to access the directory\n"
+ "~/.gnome/mime-info\n\n"
+ "We will not be able to save the state."));
+ return;
+ }
+ }
+ filename = g_concat_dir_and_file (dirname, "user.mime");
+
+ remove (filename);
+ file = fopen (filename, "w");
+ if (file == NULL) {
+ run_error (_("Cannot create the file\n~/.gnome/mime-info/user.mime\n\n"
+ "We will not be able to save the state"));
+ return;
+ }
+ g_hash_table_foreach (hash, write_mime_foreach, file);
+ fclose (file);
+}
+
+void
+write_user_mime (void)
+{
+ write_mime (user_mime_types);
+}
+
+void
+write_initial_mime (void)
+{
+ write_mime (initial_user_mime_types);
+}
+
+void
+reread_list ()
+{
+ gtk_clist_freeze (GTK_CLIST (clist));
+ gtk_clist_clear (GTK_CLIST (clist));
+ g_hash_table_foreach (mime_types, (GHFunc) add_mime_vals_to_clist, clist);
+ gtk_clist_thaw (GTK_CLIST (clist));
+}
+static void
+clean_mime_type (gpointer mime_type, gpointer mime_info, gpointer data)
+{
+ /* we should write this )-: */
+}
+void
+discard_mime_info ()
+{
+ gchar *filename;
+ g_hash_table_foreach (user_mime_types, clean_mime_type, NULL);
+ g_hash_table_destroy (user_mime_types);
+ g_hash_table_foreach (initial_user_mime_types, clean_mime_type, NULL);
+ g_hash_table_destroy (initial_user_mime_types);
+ user_mime_types = g_hash_table_new (g_str_hash, g_str_equal);
+ initial_user_mime_types = g_hash_table_new (g_str_hash, g_str_equal);
+
+ filename = g_concat_dir_and_file (gnome_util_user_home (), "/.gnome/mime-info/user.keys");
+ mime_fill_from_file (filename, TRUE);
+ finalize_user_mime ();
+ reread_list ();
+ g_free (filename);
+}
+
+
+
+
+
+
+
diff --git a/capplets/file-types/mime-data.h b/capplets/file-types/mime-data.h
new file mode 100644
index 000000000..f5c8bedea
--- /dev/null
+++ b/capplets/file-types/mime-data.h
@@ -0,0 +1,34 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* Copyright (C) 1998 Redhat Software Inc.
+ * Authors: Jonathan Blandford <jrb@redhat.com>
+ */
+#ifndef _MIME_DATA_H_
+#define _MIME_DATA_H_
+#include "gnome.h"
+#include <regex.h>
+/* Typedefs */
+typedef struct {
+ char *mime_type;
+ regex_t *regex[2];
+ GList *ext[2];
+ GList *user_ext[2];
+ char *ext_readable[2];
+ char *regex_readable[2];
+ char *file_name;
+ GList *keys;
+} MimeInfo;
+
+extern GHashTable *user_mime_types;
+extern void add_to_key (char *mime_type, char *def, GHashTable *table, gboolean init_user);
+
+GtkWidget *get_mime_clist (void);
+void init_mime_type (void);
+void delete_clicked (GtkWidget *widget, gpointer data);
+void add_clicked (GtkWidget *widget, gpointer data);
+void edit_clicked (GtkWidget *widget, gpointer data);
+void add_new_mime_type (gchar *mime_type, gchar *ext, gchar *regexp1, gchar *regexp2);
+void write_user_mime (void);
+void write_initial_mime (void);
+void reread_list (void);
+void discard_mime_info (void);
+#endif
diff --git a/capplets/file-types/mime-info.c b/capplets/file-types/mime-info.c
new file mode 100644
index 000000000..fe23a90de
--- /dev/null
+++ b/capplets/file-types/mime-info.c
@@ -0,0 +1,492 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* Copyright (C) 1998 Redhat Software Inc.
+ * Authors: Jonathan Blandford <jrb@redhat.com>
+ */
+#include <config.h>
+#include "capplet-widget.h"
+#include "gnome.h"
+#include <string.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <regex.h>
+#include <ctype.h>
+#include "mime-info.h"
+#include "mime-data.h"
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#if !defined getc_unlocked && !defined HAVE_GETC_UNLOCKED
+# define getc_unlocked(fp) getc (fp)
+#endif
+
+typedef struct {
+ char *mime_type;
+ GHashTable *keys;
+} GnomeMimeContext;
+
+typedef enum {
+ STATE_NONE,
+ STATE_LANG,
+ STATE_LOOKING_FOR_KEY,
+ STATE_ON_MIME_TYPE,
+ STATE_ON_KEY,
+ STATE_ON_VALUE
+} ParserState;
+
+static char *current_lang = NULL;
+
+/*
+ * A hash table containing all of the Mime records for specific
+ * mime types (full description, like image/png)
+ */
+static GHashTable *specific_types;
+static GHashTable *initial_specific_types;
+
+/*
+ * A hash table containing all of the Mime records for non-specific
+ * mime types (like image/\*)
+ */
+static GHashTable *generic_types;
+static GHashTable *initial_generic_types;
+
+#define SWITCH_TO_MIME_TYPE() {
+static GnomeMimeContext *
+context_new (GString *str, gboolean is_default_context)
+{
+ GnomeMimeContext *context;
+ GHashTable *table;
+ char *mime_type, *p;
+
+ mime_type = g_strdup (str->str);
+
+ if (is_default_context) {
+ if ((p = strstr (mime_type, "/*")) == NULL){
+ table = initial_specific_types;
+ } else {
+ *(p+1) = 0;
+ table = initial_generic_types;
+ }
+ } else {
+ if ((p = strstr (mime_type, "/*")) == NULL){
+ table = specific_types;
+ } else {
+ *(p+1) = 0;
+ table = generic_types;
+ }
+ }
+ context = g_hash_table_lookup (table, mime_type);
+
+ if (context)
+ return context;
+
+ context = g_new (GnomeMimeContext, 1);
+ context->mime_type = mime_type;
+ context->keys = g_hash_table_new (g_str_hash, g_str_equal);
+
+ g_hash_table_insert (table, context->mime_type, context);
+ return context;
+}
+
+static gboolean
+release_key_and_value (gpointer key, gpointer value, gpointer user_data)
+{
+ g_free (key);
+ g_free (value);
+
+ return TRUE;
+}
+
+
+static gboolean
+remove_this_key (gpointer key, gpointer value, gpointer user_data)
+{
+ if (strcmp ((gchar *)key, (gchar *)user_data) == 0){
+ g_free (key);
+ g_free (value);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+static void
+context_add_key (GnomeMimeContext *context, char *key, char *value)
+{
+ char *v;
+
+ v = g_hash_table_lookup (context->keys, key);
+ if (v)
+ g_hash_table_foreach_remove (context->keys, remove_this_key, key);
+
+ g_hash_table_insert (context->keys, g_strdup (key), g_strdup (value));
+}
+static void
+context_destroy (GnomeMimeContext *context)
+{
+ /*
+ * Remove the context from our hash tables, we dont know
+ * where it is: so just remove it from both (it can
+ * only be in one).
+ */
+ if (context->mime_type) {
+ g_hash_table_remove (specific_types, context->mime_type);
+ g_hash_table_remove (generic_types, context->mime_type);
+ }
+ /*
+ * Destroy it
+ */
+ if (context->keys) {
+ g_hash_table_foreach_remove (context->keys, release_key_and_value, NULL);
+ g_hash_table_destroy (context->keys);
+ }
+ g_free (context->mime_type);
+ g_free (context);
+}
+
+static void
+load_mime_type_info_from (char *filename)
+{
+ FILE *mime_file;
+ gboolean in_comment, context_used;
+ GString *line;
+ int column, c;
+ ParserState state;
+ GnomeMimeContext *context, *default_context;
+ char *key;
+
+ mime_file = fopen (filename, "r");
+ if (mime_file == NULL)
+ return;
+
+ in_comment = FALSE;
+ context_used = FALSE;
+ column = 0;
+ context = NULL;
+ default_context = NULL;
+ key = NULL;
+ line = g_string_sized_new (120);
+ state = STATE_NONE;
+
+ while ((c = getc_unlocked (mime_file)) != EOF){
+ column++;
+ if (c == '\r')
+ continue;
+
+ if (c == '#' && column == 0){
+ in_comment = TRUE;
+ continue;
+ }
+
+ if (c == '\n'){
+ in_comment = FALSE;
+ column = 0;
+ if (state == STATE_ON_MIME_TYPE){
+ context = context_new (line, FALSE);
+ default_context = context_new (line, TRUE);
+ context_used = FALSE;
+ g_string_assign (line, "");
+ state = STATE_LOOKING_FOR_KEY;
+ continue;
+ }
+ if (state == STATE_ON_VALUE){
+ context_used = TRUE;
+ context_add_key (context, key, line->str);
+ context_add_key (default_context, key, line->str);
+ g_string_assign (line, "");
+ g_free (key);
+ key = NULL;
+ state = STATE_LOOKING_FOR_KEY;
+ continue;
+ }
+ continue;
+ }
+
+ if (in_comment)
+ continue;
+
+ switch (state){
+ case STATE_NONE:
+ if (c != ' ' && c != '\t')
+ state = STATE_ON_MIME_TYPE;
+ else
+ break;
+ /* fall down */
+
+ case STATE_ON_MIME_TYPE:
+ if (c == ':'){
+ in_comment = TRUE;
+ break;
+ }
+ g_string_append_c (line, c);
+ break;
+
+ case STATE_LOOKING_FOR_KEY:
+ if (c == '\t' || c == ' ')
+ break;
+
+ if (c == '['){
+ state = STATE_LANG;
+ break;
+ }
+
+ if (column == 1){
+ state = STATE_ON_MIME_TYPE;
+ g_string_append_c (line, c);
+ break;
+ }
+ state = STATE_ON_KEY;
+ /* falldown */
+
+ case STATE_ON_KEY:
+ if (c == '\\'){
+ c = getc (mime_file);
+ if (c == EOF)
+ break;
+ }
+ if (c == '='){
+ key = g_strdup (line->str);
+ g_string_assign (line, "");
+ state = STATE_ON_VALUE;
+ break;
+ }
+ g_string_append_c (line, c);
+ break;
+
+ case STATE_ON_VALUE:
+ g_string_append_c (line, c);
+ break;
+
+ case STATE_LANG:
+ if (c == ']'){
+ state = STATE_ON_KEY;
+ if (current_lang && line->str [0]){
+ if (strcmp (current_lang, line->str) != 0){
+ in_comment = TRUE;
+ state = STATE_LOOKING_FOR_KEY;
+ }
+ } else {
+ in_comment = TRUE;
+ state = STATE_LOOKING_FOR_KEY;
+ }
+ g_string_assign (line, "");
+ break;
+ }
+ g_string_append_c (line, c);
+ break;
+ }
+ }
+
+ if (context){
+ if (key && line->str [0]) {
+ context_add_key (context, key, line->str);
+ context_add_key (default_context, key, line->str);
+ } else
+ if (!context_used) {
+ context_destroy (context);
+ context_destroy (default_context);
+ }
+
+ }
+
+ g_string_free (line, TRUE);
+ if (key)
+ g_free (key);
+
+ fclose (mime_file);
+}
+void
+set_mime_key_value (gchar *mime_type, gchar *key, gchar *value)
+{
+ GnomeMimeContext *context;
+
+ /* Assume no generic context's for now. */
+ context = g_hash_table_lookup (specific_types, mime_type);
+ if (context == NULL) {
+ GString *str = g_string_new (mime_type);
+ context = context_new (str, FALSE);
+ g_string_free (str, TRUE);
+ }
+ context_add_key (context, key, value);
+}
+void
+init_mime_info (void)
+{
+ gchar *filename;
+
+ current_lang = getenv ("LANG");
+ specific_types = g_hash_table_new (g_str_hash, g_str_equal);
+ generic_types = g_hash_table_new (g_str_hash, g_str_equal);
+ initial_specific_types = g_hash_table_new (g_str_hash, g_str_equal);
+ initial_generic_types = g_hash_table_new (g_str_hash, g_str_equal);
+
+ filename = g_concat_dir_and_file (gnome_util_user_home (), "/.gnome/mime-info/user.keys");
+ load_mime_type_info_from (filename);
+ g_free (filename);
+}
+
+const char *
+local_mime_get_value (const char *mime_type, char *key)
+{
+ char *value, *generic_type, *p;
+ GnomeMimeContext *context;
+
+ g_return_val_if_fail (mime_type != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+ context = g_hash_table_lookup (specific_types, mime_type);
+ if (context){
+ value = g_hash_table_lookup (context->keys, key);
+
+ if (value)
+ return value;
+ }
+
+ generic_type = g_strdup (mime_type);
+ p = strchr (generic_type, '/');
+ if (p)
+ *(p+1) = 0;
+
+ context = g_hash_table_lookup (generic_types, generic_type);
+ g_free (generic_type);
+
+ if (context){
+ value = g_hash_table_lookup (context->keys, key);
+ if (value)
+ return value;
+ }
+ return NULL;
+}
+static void
+clean_mime_foreach (gpointer mime_type, gpointer gmc, gpointer data)
+{
+ context_destroy ((GnomeMimeContext *) gmc);
+}
+static void
+write_mime_keys_foreach (gpointer key_name, gpointer value, gpointer data)
+{
+ gchar *buf;
+ if (current_lang && strcmp (current_lang, "C"))
+ buf = g_strconcat ("\t[",
+ current_lang,
+ "]",
+ (gchar *) key_name,
+ "=",
+ (gchar *) value,
+ "\n", NULL);
+ else
+ buf = g_strconcat ("\t",
+ (gchar *) key_name,
+ "=",
+ (gchar *) value,
+ "\n", NULL);
+ fwrite (buf, 1, strlen (buf), (FILE *) data);
+ g_free (buf);
+}
+static void
+write_mime_foreach (gpointer mime_type, gpointer gmc, gpointer data)
+{
+ gchar *buf;
+ GnomeMimeContext *context = (GnomeMimeContext *) gmc;
+
+ buf = g_strconcat ((gchar *) mime_type, ":\n", NULL);
+ fwrite (buf, 1, strlen (buf), (FILE *) data);
+ g_free (buf);
+ g_hash_table_foreach (context->keys, write_mime_keys_foreach, data);
+ fwrite ("\n", 1, strlen ("\n"), (FILE *) data);
+}
+
+static void
+run_error (gchar *message)
+{
+ GtkWidget *error_box;
+
+ error_box = gnome_message_box_new (
+ message,
+ GNOME_MESSAGE_BOX_ERROR,
+ GNOME_STOCK_BUTTON_OK,
+ NULL);
+ gnome_dialog_run_and_close (GNOME_DIALOG (error_box));
+}
+static void
+write_keys (GHashTable *spec_hash, GHashTable *generic_hash)
+{
+ struct stat s;
+ gchar *dirname, *filename;
+ FILE *file;
+/* GtkWidget *error_box; */
+
+ dirname = g_concat_dir_and_file (gnome_util_user_home (), ".gnome/mime-info");
+ if ((stat (dirname, &s) < 0) || !(S_ISDIR (s.st_mode))){
+ if (errno == ENOENT) {
+ if (mkdir (dirname, S_IRWXU) < 0) {
+ run_error (_("We are unable to create the directory\n"
+ "~/.gnome/mime-info.\n\n"
+ "We will not be able to save the state."));
+ return;
+ }
+ } else {
+ run_error (_("We are unable to access the directory\n"
+ "~/.gnome/mime-info.\n\n"
+ "We will not be able to save the state."));
+ return;
+ }
+ }
+ filename = g_concat_dir_and_file (dirname, "user.keys");
+
+ remove (filename);
+ file = fopen (filename, "w");
+ if (file == NULL) {
+ run_error (_("Cannot create the file\n~/.gnome/mime-info/user.keys.\n\n"
+ "We will not be able to save the state"));
+ return;
+ }
+ g_hash_table_foreach (spec_hash, write_mime_foreach, file);
+ g_hash_table_foreach (generic_hash, write_mime_foreach, file);
+ fclose (file);
+}
+void
+write_initial_keys (void)
+{
+ write_keys (initial_generic_types, initial_specific_types);
+}
+void
+write_user_keys (void)
+{
+ write_keys (generic_types, specific_types);
+}
+
+#if 0
+static void
+print_mime_foreach (gpointer mime_info, gpointer mi, gpointer data)
+{
+ g_print ("mime_info:%s:\n", (char *)mime_info);
+ g_print ("\t:%s:\n", ((MimeInfo *)mi)->mime_type);
+}
+#endif
+
+void
+discard_key_info (void)
+{
+ gchar *filename;
+
+ current_lang = getenv ("LANG");
+ g_hash_table_foreach (generic_types, clean_mime_foreach, NULL);
+/* g_hash_table_foreach (specific_types, print_mime_foreach, NULL); */
+ g_hash_table_foreach (specific_types, clean_mime_foreach, NULL);
+ g_hash_table_destroy (generic_types);
+ g_hash_table_destroy (specific_types);
+ specific_types = g_hash_table_new (g_str_hash, g_str_equal);
+ generic_types = g_hash_table_new (g_str_hash, g_str_equal);
+
+ filename = g_concat_dir_and_file (gnome_util_user_home (), "/.gnome/mime-info/user.keys");
+ load_mime_type_info_from (filename);
+ reread_list ();
+ g_free (filename);
+}
+void
+remove_mime_info (gchar *mime_type)
+{
+ g_hash_table_remove (generic_types, mime_type);
+ g_hash_table_remove (specific_types, mime_type);
+}
diff --git a/capplets/file-types/mime-info.h b/capplets/file-types/mime-info.h
new file mode 100644
index 000000000..18db2326f
--- /dev/null
+++ b/capplets/file-types/mime-info.h
@@ -0,0 +1,17 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* Copyright (C) 1998 Redhat Software Inc.
+ * Authors: Jonathan Blandford <jrb@redhat.com>
+ */
+#ifndef _MIME_INFO_H_
+#define _MIME_INFO_H_
+#include "gnome.h"
+#include <regex.h>
+/* Typedefs */
+void init_mime_info (void);
+void discard_key_info (void);
+void set_mime_key_value (gchar *mime_type, gchar *key, gchar *value);
+const char * local_mime_get_value (const char *mime_type, char *key);
+void write_user_keys (void);
+void write_initial_keys (void);
+void remove_mime_info (gchar *mime_type);
+#endif
diff --git a/capplets/file-types/mime-type-capplet.c b/capplets/file-types/mime-type-capplet.c
new file mode 100644
index 000000000..2813ede66
--- /dev/null
+++ b/capplets/file-types/mime-type-capplet.c
@@ -0,0 +1,142 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* Copyright (C) 1998 Redhat Software Inc.
+ * Authors: Jonathan Blandford <jrb@redhat.com>
+ */
+#include <config.h>
+#include "capplet-widget.h"
+#include "gnome.h"
+#include <string.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <regex.h>
+#include <ctype.h>
+#include "mime-data.h"
+#include "mime-info.h"
+#include "edit-window.h"
+/* Prototypes */
+static void try_callback ();
+static void revert_callback ();
+static void ok_callback ();
+static void cancel_callback ();
+#if 0
+static void help_callback ();
+#endif
+GtkWidget *capplet = NULL;
+GtkWidget *delete_button = NULL;
+
+static GtkWidget *
+left_aligned_button (gchar *label)
+{
+ GtkWidget *button = gtk_button_new_with_label (label);
+ gtk_misc_set_alignment (GTK_MISC (GTK_BIN (button)->child),
+ 0.0, 0.5);
+ gtk_misc_set_padding (GTK_MISC (GTK_BIN (button)->child),
+ GNOME_PAD_SMALL, 0);
+
+ return button;
+}
+
+static void
+try_callback ()
+{
+ write_user_keys ();
+ write_user_mime ();
+}
+static void
+revert_callback ()
+{
+ write_initial_keys ();
+ write_initial_mime ();
+ discard_key_info ();
+ discard_mime_info ();
+ initialize_main_win_vals ();
+}
+static void
+ok_callback ()
+{
+ write_user_keys ();
+ write_user_mime ();
+}
+static void
+cancel_callback ()
+{
+ write_initial_keys ();
+ write_initial_mime ();
+}
+
+#if 0
+static void
+help_callback ()
+{
+ /* Sigh... empty as always */
+}
+#endif
+
+static void
+init_mime_capplet ()
+{
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *button;
+
+ capplet = capplet_widget_new ();
+ delete_button = left_aligned_button (_("Delete"));
+ gtk_signal_connect (GTK_OBJECT (delete_button), "clicked",
+ delete_clicked, NULL);
+
+ hbox = gtk_hbox_new (FALSE, GNOME_PAD);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), GNOME_PAD_SMALL);
+ gtk_container_add (GTK_CONTAINER (capplet), hbox);
+ gtk_box_pack_start (GTK_BOX (hbox), get_mime_clist (), TRUE, TRUE, 0);
+ vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
+ gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
+ button = left_aligned_button (_("Add..."));
+ gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ add_clicked, NULL);
+ button = left_aligned_button (_("Edit..."));
+ gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ edit_clicked, NULL);
+ gtk_box_pack_start (GTK_BOX (vbox), delete_button, FALSE, FALSE, 0);
+ gtk_widget_show_all (capplet);
+ gtk_signal_connect(GTK_OBJECT(capplet), "try",
+ GTK_SIGNAL_FUNC(try_callback), NULL);
+ gtk_signal_connect(GTK_OBJECT(capplet), "revert",
+ GTK_SIGNAL_FUNC(revert_callback), NULL);
+ gtk_signal_connect(GTK_OBJECT(capplet), "ok",
+ GTK_SIGNAL_FUNC(ok_callback), NULL);
+ gtk_signal_connect(GTK_OBJECT(capplet), "cancel",
+ GTK_SIGNAL_FUNC(cancel_callback), NULL);
+ gtk_signal_connect(GTK_OBJECT(capplet), "page_hidden",
+ GTK_SIGNAL_FUNC(hide_edit_window), NULL);
+ gtk_signal_connect(GTK_OBJECT(capplet), "page_shown",
+ GTK_SIGNAL_FUNC(show_edit_window), NULL);
+#if 0
+ gtk_signal_connect(GTK_OBJECT(capplet), "help",
+ GTK_SIGNAL_FUNC(help_callback), NULL);
+#endif
+}
+
+int
+main (int argc, char **argv)
+{
+ int init_results;
+
+ bindtextdomain (PACKAGE, GNOMELOCALEDIR);
+ textdomain (PACKAGE);
+
+ init_results = gnome_capplet_init("mime-type-capplet", VERSION,
+ argc, argv, NULL, 0, NULL);
+
+ if (init_results < 0) {
+ exit (0);
+ }
+
+ if (init_results == 0) {
+ init_mime_type ();
+ init_mime_capplet ();
+ capplet_gtk_main ();
+ }
+ return 0;
+}
diff --git a/capplets/file-types/mime-type.desktop b/capplets/file-types/mime-type.desktop
new file mode 100644
index 000000000..b58b4e745
--- /dev/null
+++ b/capplets/file-types/mime-type.desktop
@@ -0,0 +1,52 @@
+[Desktop Entry]
+Name=Mime Types
+Name[ca]=Tipus MIME
+Name[cs]=MIME typy
+Name[da]=Mimetyper
+Name[de]=Mime-Typen
+Name[es]=Tipos MIME
+Name[et]=MIME tüübid
+Name[fi]=MIME-tyypit
+Name[fr]=Types MIME
+Name[gl]=Tipos MIME
+Name[hu]=MIME típusok
+Name[it]=Tipi MIME
+Name[ja]=MIME·¿
+Name[ko]=MIME ŸÀÔ
+Name[lt]=Mime tipai
+Name[no]=Mime typer
+Name[pl]=Typy MIME
+Name[pt]=Tipos Mime
+Name[pt_BR]=Tipos Mime
+Name[sv]=Mimetyper
+Name[uk]=ôÉÐÉ MIME
+Name[wa]=Sôrtes MIME
+Name[zh_TW.Big5]=Mime Ãþ«¬
+Name[zh_CN.GB2312]=Mime ÀàÐÍ
+Comment=Configure how files are associated and started
+Comment[ca]=Configurar com s'associen i obrin els fitxers
+Comment[cs]=Konfigurace MIME typù
+Comment[da]=Vælg hvilke programmer dine filer skal åbnes med.
+Comment[de]=Einrichten, wie Dateien verknüpft und geöffnet werden
+Comment[es]=Configura los tipos de archivos y los programas asociados para manejarlos
+Comment[et]=MIME tüüpide assigneerimine failidele ja programmidele
+Comment[fi]=Aseta tiedostoassosiaatiot ja avaajat
+Comment[fr]=Configure les types de fichier et les programmes y associés
+Comment[gl]=Configura a maneira en que os ficheiros se asocian cos programas
+Comment[it]=Configura i tipi di files e le applicazioni usate per aprirli
+Comment[ja]=¥Õ¥¡¥¤¥ë¤Î°À­¤Ë´Ø¤¹¤ëÀßÄê
+Comment[ko]=¾î¶² ÇÁ·Î±×·¥°ú ÆÄÀÏÀ» ¿¬°áÇÏ°í ¾î¶»°Ô ÆÄÀÏÀ» ¿©´ÂÁö ¼³Á¤ÇÕ´Ï´Ù
+Comment[lt]=Nustatyti, su kuo bylos susietos ir kaip paleidþiamos
+Comment[no]=Konfigurer hvordan filer er assosiert og startet
+Comment[pl]=Konfiguracja skojarzeñ typów plików
+Comment[pt]=Configura os tipos de ficheiros e os programas a eles associados
+Comment[pt_BR]=Configura os tipos de arquivos e os programas a eles associados
+Comment[sv]=Konfigurera hur filer ska associeras och startas
+Comment[uk]=îÁÓÔÒÏÀ×ÁÎÎÑ ÔÉÐ¦× MIME
+Comment[wa]=Apontyî les sôrtes di fitchî èt les programes po les drovî
+Comment[zh_TW.Big5]=³]©wÀÉ®×ÃöÁpÄÝ©Ê¥H¤Î±Ò°Ê¤è¦¡
+Comment[zh_CN.GB2312]=É趨µµ°¸¹ØÁªÊôÐÔÒÔ¼°Æô¶¯·½Ê½
+Icon=gnome-ccmime.png
+Exec=mime-type-capplet
+Terminal=0
+Type=Application
diff --git a/capplets/file-types/new-mime-window.c b/capplets/file-types/new-mime-window.c
new file mode 100644
index 000000000..92e75454d
--- /dev/null
+++ b/capplets/file-types/new-mime-window.c
@@ -0,0 +1,116 @@
+#include "new-mime-window.h"
+#include "capplet-widget.h"
+#include <config.h>
+static GtkWidget *add_dialog = NULL;
+extern GtkWidget *capplet;
+
+/*Public functions */
+void
+launch_new_mime_window (void)
+{
+ GtkWidget *mime_entry;
+ GtkWidget *label;
+ GtkWidget *frame;
+ GtkWidget *ext_entry;
+ GtkWidget *regex1_entry;
+ GtkWidget *regex2_entry;
+ GtkWidget *hbox;
+ GtkWidget *vbox;
+ GtkWidget *table;
+
+ add_dialog = gnome_dialog_new (_("Add Mime Type"), GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL, NULL);
+ label = gtk_label_new (_("Add a new Mime Type\nFor example: image/tiff; text/x-scheme"));
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+ hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (add_dialog)->vbox), hbox, FALSE, FALSE, 0);
+ label = gtk_label_new (_("Mime Type:"));
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+ hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ mime_entry = gtk_entry_new ();
+ gtk_box_pack_start (GTK_BOX (hbox), mime_entry, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (add_dialog)->vbox), hbox, FALSE, FALSE, 0);
+
+ frame = gtk_frame_new (_("Extensions"));
+ gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (add_dialog)->vbox), frame, FALSE, FALSE, 0);
+ vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), GNOME_PAD_SMALL);
+ label = gtk_label_new (_("Type in the extensions for this mime-type.\nFor example: .html, .htm"));
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+ hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (frame), vbox);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+ hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
+ gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("Extension:")), FALSE, FALSE, 0);
+ ext_entry = gtk_entry_new ();
+ gtk_box_pack_start (GTK_BOX (hbox), ext_entry, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+
+ frame = gtk_frame_new (_("Regular Expressions"));
+ gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (add_dialog)->vbox), frame, FALSE, FALSE, 0);
+ vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), GNOME_PAD_SMALL);
+ label = gtk_label_new (_("You can set up two regular expressions here to identify the Mime Type\nby. These fields are optional."));
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+ hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (frame), vbox);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), gtk_hseparator_new (), FALSE, FALSE, 0);
+ table = gtk_table_new (2, 2, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), GNOME_PAD_SMALL);
+/* gtk_container_set_border_width (GTK_CONTAINER (table), GNOME_PAD_SMALL);*/
+ label = gtk_label_new (_("First Regular Expression: "));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+ gtk_table_attach (GTK_TABLE (table),
+ label,
+ 0, 1, 0, 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+ regex1_entry = gtk_entry_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ regex1_entry,
+ 1, 2, 0, 1);
+ label = gtk_label_new (_("Second Regular Expression: "));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+ gtk_table_attach (GTK_TABLE (table),
+ label,
+ 0, 1, 1, 2,
+ GTK_FILL, GTK_FILL, 0, 0);
+ regex2_entry = gtk_entry_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ regex2_entry,
+ 1, 2, 1, 2);
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+
+
+ gtk_widget_show_all (GNOME_DIALOG (add_dialog)->vbox);
+ switch (gnome_dialog_run (GNOME_DIALOG (add_dialog))) {
+ case 0:
+ capplet_widget_state_changed (CAPPLET_WIDGET (capplet),
+ TRUE);
+ add_new_mime_type (gtk_entry_get_text (GTK_ENTRY (mime_entry)),
+ gtk_entry_get_text (GTK_ENTRY (ext_entry)),
+ gtk_entry_get_text (GTK_ENTRY (regex1_entry)),
+ gtk_entry_get_text (GTK_ENTRY (regex2_entry)));
+ case 1:
+ gtk_widget_destroy (add_dialog);
+ default:;
+ }
+ add_dialog = NULL;
+}
+void
+hide_new_mime_window (void)
+{
+ if (add_dialog != NULL)
+ gtk_widget_hide (add_dialog);
+}
+void
+show_new_mime_window (void)
+{
+ if (add_dialog != NULL)
+ gtk_widget_show (add_dialog);
+}
diff --git a/capplets/file-types/new-mime-window.h b/capplets/file-types/new-mime-window.h
new file mode 100644
index 000000000..3071ab3fd
--- /dev/null
+++ b/capplets/file-types/new-mime-window.h
@@ -0,0 +1,14 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* Copyright (C) 1998 Redhat Software Inc.
+ * Authors: Jonathan Blandford <jrb@redhat.com>
+ */
+#include "mime-data.h"
+#ifndef _NEW_MIME_WINDOW_H_
+#define _NEW_MIME_WINDOW_H_
+
+void launch_new_mime_window (void);
+void hide_new_mime_window (void);
+void show_new_mime_window (void);
+
+#endif
+