[Xfce4-commits] <xfce4-settings:master> Add new mime settings dialog.

Nick Schermer noreply at xfce.org
Sat Jan 21 22:16:01 CET 2012


Updating branch refs/heads/master
         to 503d8a2f78703128e9fd957fd169f294bee684f2 (commit)
       from ee51e64355789b2e46554a74700ee2b0d7e4f5e1 (commit)

commit 503d8a2f78703128e9fd957fd169f294bee684f2
Author: Nick Schermer <nick at xfce.org>
Date:   Fri Jan 20 22:49:46 2012 +0100

    Add new mime settings dialog.
    
    Application chooser is not working yet.

 configure.ac.in                                    |   12 +
 dialogs/Makefile.am                                |    5 +
 .../mime-settings}/Makefile.am                     |   31 +-
 dialogs/mime-settings/main.c                       |   96 +++
 dialogs/mime-settings/xfce-mime-window.c           |  762 ++++++++++++++++++++
 dialogs/mime-settings/xfce-mime-window.h           |   40 +
 .../mime-settings/xfce4-mime-settings.desktop.in   |   11 +
 po/POTFILES.in                                     |    4 +
 8 files changed, 943 insertions(+), 18 deletions(-)

diff --git a/configure.ac.in b/configure.ac.in
index db9313b..2ec11c1 100644
--- a/configure.ac.in
+++ b/configure.ac.in
@@ -139,6 +139,12 @@ dnl **************************************
 XDT_CHECK_OPTIONAL_PACKAGE([LIBNOTIFY], [libnotify], [0.1.3],
                            [libnotify], [Notification support])
 
+dnl *********************
+dnl *** Mime settings ***
+dnl *********************
+XDT_CHECK_OPTIONAL_PACKAGE([GIO_UNIX], [gio-unix-2.0], [2.24],
+                           [gio-unix], [Mime settings])
+
 dnl ************************************
 dnl *** Optional support for Xcursor ***
 dnl ************************************
@@ -224,6 +230,7 @@ dialogs/appearance-settings/Makefile
 dialogs/accessibility-settings/Makefile
 dialogs/display-settings/Makefile
 dialogs/keyboard-settings/Makefile
+dialogs/mime-settings/Makefile
 dialogs/mouse-settings/Makefile
 xfsettingsd/Makefile
 xfce4-settings-manager/Makefile
@@ -268,6 +275,11 @@ echo "* Libxklavier support:       yes"
 else
 echo "* Libxklavier support:       no"
 fi
+if test x"$GIO_UNIX_FOUND" = x"yes"; then
+echo "* Mime settings (gio-unix):  yes"
+else
+echo "* Mime settings (gio-unix):  no"
+fi
 echo
 
 
diff --git a/dialogs/Makefile.am b/dialogs/Makefile.am
index e5ecd12..e39f64d 100644
--- a/dialogs/Makefile.am
+++ b/dialogs/Makefile.am
@@ -10,3 +10,8 @@ if HAVE_XRANDR
 SUBDIRS += \
 	display-settings
 endif
+
+if HAVE_GIO_UNIX
+SUBDIRS += \
+	mime-settings
+endif
diff --git a/xfce4-settings-manager/Makefile.am b/dialogs/mime-settings/Makefile.am
similarity index 53%
copy from xfce4-settings-manager/Makefile.am
copy to dialogs/mime-settings/Makefile.am
index 22d33c9..9b806a5 100644
--- a/xfce4-settings-manager/Makefile.am
+++ b/dialogs/mime-settings/Makefile.am
@@ -1,44 +1,39 @@
-# $Id$
 
 INCLUDES = \
 	-I${top_srcdir} \
 	-DDATADIR=\"$(datadir)\" \
 	-DSRCDIR=\"$(top_srcdir)\" \
 	-DLOCALEDIR=\"$(localedir)\" \
-	-DG_LOG_DOMAIN=\"xfce4-settings-manager\" \
+	-DG_LOG_DOMAIN=\"xfce4-mime-settings\" \
 	$(PLATFORM_CPPFLAGS)
 
 bin_PROGRAMS = \
-	xfce4-settings-manager
+	xfce4-mime-settings
 
-xfce4_settings_manager_SOURCES = \
+xfce4_mime_settings_SOURCES = \
 	main.c \
-	xfce-settings-manager-dialog.c \
-	xfce-settings-manager-dialog.h \
-	xfce-text-renderer.c \
-	xfce-text-renderer.h
+	xfce-mime-window.c \
+	xfce-mime-window.h
 
-xfce4_settings_manager_CFLAGS = \
+xfce4_mime_settings_CFLAGS = \
 	$(GTK_CFLAGS) \
-	$(LIBXFCE4UTIL_CFLAGS) \
+	$(GIO_CFLAGS) \
+	$(GIO_UNIX_CFLAGS) \
 	$(LIBXFCE4UI_CFLAGS) \
-	$(XFCONF_CFLAGS) \
-	$(EXO_CFLAGS) \
 	$(PLATFORM_CFLAGS)
 
-xfce4_settings_manager_LDFLAGS = \
+xfce4_mime_settings_LDFLAGS = \
 	-no-undefined \
 	$(PLATFORM_LDFLAGS)
 
-xfce4_settings_manager_LDADD = \
+xfce4_mime_settings_LDADD = \
 	$(GTK_LIBS) \
-	$(LIBXFCE4UTIL_LIBS) \
 	$(LIBXFCE4UI_LIBS) \
-	$(XFCONF_LIBS) \
-	$(EXO_LIBS)
+	$(GIO_LIBS) \
+	$(GIO_UNIX_LIBS)
 
 desktopdir = $(datadir)/applications
-desktop_in_files = xfce-settings-manager.desktop.in
+desktop_in_files = xfce4-mime-settings.desktop.in
 desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
 
 @INTLTOOL_DESKTOP_RULE@
diff --git a/dialogs/mime-settings/main.c b/dialogs/mime-settings/main.c
new file mode 100644
index 0000000..c6d1e05
--- /dev/null
+++ b/dialogs/mime-settings/main.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2012 Nick Schermer <nick at xfce.org>
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+#include "xfce-mime-window.h"
+
+
+
+static gboolean opt_version = FALSE;
+static GOptionEntry entries[] =
+{
+    { "version", 'v', 0, G_OPTION_ARG_NONE, &opt_version, N_("Version information"), NULL },
+    { NULL }
+};
+
+
+
+gint
+main (gint argc, gchar **argv)
+{
+    GError    *error = NULL;
+    GtkWidget *window;
+
+    /* setup translation domain */
+    xfce_textdomain (GETTEXT_PACKAGE, LOCALEDIR, "UTF-8");
+
+    /* initialize Gtk+ */
+    if(!gtk_init_with_args (&argc, &argv, "", entries, PACKAGE, &error))
+    {
+        if (G_LIKELY (error))
+        {
+            /* print error */
+            g_print ("%s: %s.\n", G_LOG_DOMAIN, error->message);
+            g_print (_("Type '%s --help' for usage."), G_LOG_DOMAIN);
+            g_print ("\n");
+
+            /* cleanup */
+            g_error_free (error);
+        }
+        else
+        {
+            g_error ("Unable to open display.");
+        }
+
+        return EXIT_FAILURE;
+    }
+
+    /* check if we should print version information */
+    if (G_UNLIKELY (opt_version))
+    {
+        g_print ("%s %s (Xfce %s)\n\n", G_LOG_DOMAIN, PACKAGE_VERSION, xfce_version_string ());
+        g_print ("%s\n", "Copyright (c) 2008-2011");
+        g_print ("\t%s\n\n", _("The Xfce development team. All rights reserved."));
+        g_print (_("Please report bugs to <%s>."), PACKAGE_BUGREPORT);
+        g_print ("\n");
+
+        return EXIT_SUCCESS;
+    }
+
+    window = g_object_new (XFCE_TYPE_MIME_WINDOW, NULL);
+    gtk_window_set_default_size (GTK_WINDOW (window), 400, 500);
+    g_signal_connect (G_OBJECT (window), "response",
+        G_CALLBACK (gtk_main_quit), NULL);
+    gtk_window_present (GTK_WINDOW (window));
+
+    gtk_main ();
+
+    return EXIT_SUCCESS;
+}
diff --git a/dialogs/mime-settings/xfce-mime-window.c b/dialogs/mime-settings/xfce-mime-window.c
new file mode 100644
index 0000000..048de46
--- /dev/null
+++ b/dialogs/mime-settings/xfce-mime-window.c
@@ -0,0 +1,762 @@
+/*
+ * Copyright (C) 2012 Nick Schermer <nick at xfce.org>
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+#include <libxfce4util/libxfce4util.h>
+#include <libxfce4ui/libxfce4ui.h>
+#include <gio/gdesktopappinfo.h>
+
+#include "xfce-mime-window.h"
+
+
+static void     xfce_mime_window_finalize          (GObject              *object);
+static gint     xfce_mime_window_mime_model        (XfceMimeWindow       *window);
+static void     xfce_mime_window_filter_changed    (GtkEntry             *entry,
+                                                    XfceMimeWindow       *window);
+static void     xfce_mime_window_filter_clear      (GtkEntry             *entry,
+                                                    GtkEntryIconPosition  icon_pos,
+                                                    GdkEvent             *event,
+                                                    gpointer              user_data);
+static void     xfce_mime_window_statusbar_count   (XfceMimeWindow       *window,
+                                                    gint                 n_mime_types);
+static gboolean xfce_mime_window_row_visible_func  (GtkTreeModel         *model,
+                                                    GtkTreeIter          *iter,
+                                                    gpointer              data);
+static void     xfce_mime_window_selection_changed (GtkTreeSelection     *selection,
+                                                    XfceMimeWindow       *window);
+static void     xfce_mime_window_column_clicked    (GtkTreeViewColumn    *column,
+                                                    XfceMimeWindow       *window);
+static void     xfce_mime_window_combo_populate    (GtkCellRenderer      *renderer,
+                                                    GtkCellEditable      *editable,
+                                                    const gchar          *path_string,
+                                                    XfceMimeWindow       *window);
+
+
+
+struct _XfceMimeWindowClass
+{
+    XfceTitledDialogClass __parent__;
+};
+
+struct _XfceMimeWindow
+{
+    XfceTitledDialog  __parent__;
+
+    GtkWidget     *treeview;
+
+    PangoAttrList *attrs_bold;
+    GtkTreeModel  *mime_model;
+
+    GtkTreeModel  *filter_model;
+    gchar         *filter_text;
+
+    /* status bar stuff */
+    GtkWidget     *statusbar;
+    guint          description_id;
+    guint          count_id;
+};
+
+
+
+enum
+{
+    COLUMN_MIME_TYPE,
+    COLUMN_MIME_STATUS,
+    COLUMN_MIME_DEFAULT,
+    COLUMN_MIME_ATTRS,
+    N_MIME_COLUMNS
+};
+
+enum
+{
+    COLUMN_APP_NAME,
+    COLUMN_APP_INFO,
+    COLUMN_APP_TYPE,
+    N_APP_COLUMNS
+};
+
+enum
+{
+    APP_TYPE_APP,
+    APP_TYPE_SEPARATOR,
+    APP_TYPE_CHOOSER,
+    APP_TYPE_RESET
+};
+
+
+
+G_DEFINE_TYPE (XfceMimeWindow, xfce_mime_window, XFCE_TYPE_TITLED_DIALOG)
+
+
+
+static void
+xfce_mime_window_class_init (XfceMimeWindowClass *klass)
+{
+    GObjectClass *gobject_class;
+
+    gobject_class = G_OBJECT_CLASS (klass);
+    gobject_class->finalize = xfce_mime_window_finalize;
+}
+
+
+
+static void
+xfce_mime_window_init (XfceMimeWindow *window)
+{
+    GtkWidget         *area;
+    GtkWidget         *vbox;
+    GtkWidget         *hbox;
+    GtkWidget         *label;
+    GtkWidget         *entry;
+    GtkWidget         *scroll;
+    GtkWidget         *statusbar;
+    GtkWidget         *treeview;
+    GtkTreeSelection  *selection;
+    gint               n_mime_types;
+    GtkTreeViewColumn *column;
+    GtkCellRenderer   *renderer;
+
+    window->attrs_bold = pango_attr_list_new ();
+    pango_attr_list_insert (window->attrs_bold, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
+
+    n_mime_types = xfce_mime_window_mime_model (window);
+
+    gtk_window_set_title (GTK_WINDOW (window), _("Mime Type Editor"));
+    gtk_window_set_icon_name (GTK_WINDOW (window), "application-default-icon");
+    xfce_titled_dialog_set_subtitle (XFCE_TITLED_DIALOG (window),
+        _("Configure the application accossiated with a mime type"));
+
+    /* don't act like a dialog, hide the button box */
+    area = gtk_dialog_get_action_area (GTK_DIALOG (window));
+    gtk_widget_hide (area);
+
+    vbox = gtk_vbox_new (FALSE, 2);
+    area = gtk_dialog_get_content_area (GTK_DIALOG (window));
+    gtk_box_pack_start (GTK_BOX (area), vbox, TRUE, TRUE, 0);
+    gtk_widget_show (vbox);
+
+    hbox = gtk_hbox_new (FALSE, 6);
+    gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+    gtk_widget_show (hbox);
+
+    label = gtk_label_new_with_mnemonic (_("_Filter:"));
+    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+    gtk_widget_show (label);
+
+    entry = gtk_entry_new ();
+    gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
+    gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
+    gtk_entry_set_icon_from_stock (GTK_ENTRY (entry), GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
+    gtk_entry_set_icon_tooltip_text (GTK_ENTRY (entry), GTK_ENTRY_ICON_SECONDARY, _("Clear filter"));
+    g_signal_connect (G_OBJECT (entry), "icon-release",
+        G_CALLBACK (xfce_mime_window_filter_clear), NULL);
+    g_signal_connect (G_OBJECT (entry), "changed",
+        G_CALLBACK (xfce_mime_window_filter_changed), window);
+    gtk_widget_show (entry);
+
+    scroll = gtk_scrolled_window_new (NULL, NULL);
+    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+                                    GTK_POLICY_AUTOMATIC,
+                                    GTK_POLICY_ALWAYS);
+    gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_ETCHED_IN);
+    gtk_box_pack_start (GTK_BOX (vbox), scroll, TRUE, TRUE, 0);
+    gtk_widget_show (scroll);
+
+    window->statusbar = statusbar = gtk_statusbar_new ();
+    gtk_box_pack_start (GTK_BOX (vbox), statusbar, FALSE, TRUE, 0);
+    gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (statusbar), TRUE);
+    window->description_id = gtk_statusbar_get_context_id (GTK_STATUSBAR (statusbar), "description");
+    window->count_id = gtk_statusbar_get_context_id (GTK_STATUSBAR (statusbar), "count");
+    xfce_mime_window_statusbar_count (window, n_mime_types);
+    gtk_widget_show (statusbar);
+
+    window->filter_model = gtk_tree_model_filter_new (window->mime_model, NULL);
+    gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (window->filter_model),
+                                            xfce_mime_window_row_visible_func,
+                                            window, NULL);
+
+    treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (window->filter_model));
+    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), TRUE);
+    gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW (treeview), TRUE);
+    gtk_tree_view_set_enable_search (GTK_TREE_VIEW (treeview), FALSE);
+    gtk_container_add (GTK_CONTAINER (scroll), treeview);
+    gtk_widget_show (treeview);
+    window->treeview = treeview;
+
+    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+    g_signal_connect (G_OBJECT (selection), "changed",
+        G_CALLBACK (xfce_mime_window_selection_changed), window);
+
+    column = gtk_tree_view_column_new ();
+    gtk_tree_view_column_set_title (column, _("Mime Type"));
+    gtk_tree_view_column_set_clickable (column, TRUE);
+    gtk_tree_view_column_set_sort_indicator (column, TRUE);
+    gtk_tree_view_column_set_resizable (column, TRUE);
+    gtk_tree_view_column_set_expand (column, TRUE);
+    g_signal_connect (G_OBJECT (column), "clicked",
+        G_CALLBACK (xfce_mime_window_column_clicked), window);
+    gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+
+    renderer = gtk_cell_renderer_text_new ();
+    gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer, TRUE);
+    g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+    gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer,
+                                    "attributes", COLUMN_MIME_ATTRS,
+                                    "text", COLUMN_MIME_TYPE, NULL);
+
+    column = gtk_tree_view_column_new ();
+    gtk_tree_view_column_set_title (column, _("Status"));
+    gtk_tree_view_column_set_clickable (column, TRUE);
+    gtk_tree_view_column_set_resizable (column, TRUE);
+    g_signal_connect (G_OBJECT (column), "clicked",
+        G_CALLBACK (xfce_mime_window_column_clicked), window);
+    gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+
+    renderer = gtk_cell_renderer_text_new ();
+    gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer, FALSE);
+    gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer,
+                                    "attributes", COLUMN_MIME_ATTRS,
+                                    "text", COLUMN_MIME_STATUS, NULL);
+
+    column = gtk_tree_view_column_new ();
+    gtk_tree_view_column_set_title (column, _("Default Application"));
+    gtk_tree_view_column_set_clickable (column, TRUE);
+    gtk_tree_view_column_set_resizable (column, TRUE);
+    g_signal_connect (G_OBJECT (column), "clicked",
+        G_CALLBACK (xfce_mime_window_column_clicked), window);
+    gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+
+    renderer = gtk_cell_renderer_combo_new ();
+    g_signal_connect (G_OBJECT (renderer), "editing-started",
+        G_CALLBACK (xfce_mime_window_combo_populate), window);
+    g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+    gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer, TRUE);
+    g_object_set (renderer, "text-column", COLUMN_APP_NAME,
+                  "has-entry", FALSE, "editable", TRUE, NULL);
+    gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer,
+                                    "attributes", COLUMN_MIME_ATTRS,
+                                    "text", COLUMN_MIME_DEFAULT, NULL);
+}
+
+
+
+static void
+xfce_mime_window_finalize (GObject *object)
+{
+    XfceMimeWindow *window = XFCE_MIME_WINDOW (object);
+
+    g_free (window->filter_text);
+
+    g_object_unref (G_OBJECT (window->filter_model));
+    g_object_unref (G_OBJECT (window->mime_model));
+
+    pango_attr_list_unref (window->attrs_bold);
+
+    (*G_OBJECT_CLASS (xfce_mime_window_parent_class)->finalize) (object);
+}
+
+
+
+static GHashTable *
+xfce_mime_window_mime_user (void)
+{
+    gchar       *filename;
+    GHashTable  *table;
+    XfceRc      *rc;
+    guint        i;
+    gchar      **mimes;
+
+    table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+    filename = xfce_resource_save_location (XFCE_RESOURCE_DATA, "applications/mimeapps.list", FALSE);
+    if (filename == NULL)
+        return table;
+
+    rc = xfce_rc_simple_open (filename, TRUE);
+    g_free (filename);
+
+    if (G_LIKELY (rc != NULL))
+    {
+        mimes = xfce_rc_get_entries (rc, "Default Applications");
+        if (G_LIKELY (mimes != NULL))
+        {
+            for (i = 0; mimes[i] != NULL; i++)
+                g_hash_table_insert (table, mimes[i], mimes[i]);
+            g_free (mimes);
+        }
+
+        xfce_rc_close (rc);
+    }
+
+    return table;
+}
+
+
+
+static gint
+xfce_mime_window_mime_model (XfceMimeWindow *window)
+{
+    GtkListStore *model;
+    GList        *mime_types, *li;
+    gchar        *mime_type;
+    const gchar  *app_name;
+    GAppInfo     *app_default;
+    GHashTable   *user_mime;
+    gboolean      is_user_set;
+    gint          n;
+    const gchar  *status;
+
+    model = gtk_list_store_new (N_MIME_COLUMNS,
+                                G_TYPE_STRING,
+                                G_TYPE_STRING,
+                                G_TYPE_STRING,
+                                PANGO_TYPE_ATTR_LIST);
+
+    /* get sorted list of known mime types */
+    mime_types = g_content_types_get_registered ();
+    mime_types = g_list_sort (mime_types, (GCompareFunc) g_strcmp0);
+
+    /* mime types the user has set */
+    user_mime = xfce_mime_window_mime_user ();
+
+    for (li = mime_types, n = 0; li != NULL; li = li->next)
+    {
+        mime_type = li->data;
+
+        app_default = g_app_info_get_default_for_type (mime_type, FALSE);
+
+        if (G_LIKELY (app_default != NULL))
+            app_name = g_app_info_get_name (app_default);
+        else
+            app_name = NULL;
+
+        /* check if the user locally override this mime handler */
+        is_user_set = g_hash_table_remove (user_mime, mime_type);
+        if (is_user_set)
+            status = _("User Set");
+        else
+            status = _("Default");
+
+        gtk_list_store_insert_with_values (model, NULL, n++,
+                                           COLUMN_MIME_TYPE, mime_type,
+                                           COLUMN_MIME_DEFAULT, app_name,
+                                           COLUMN_MIME_STATUS, status,
+                                           COLUMN_MIME_ATTRS,
+                                               is_user_set ? window->attrs_bold : NULL,
+                                           -1);
+
+        g_free (mime_type);
+        if (G_LIKELY (app_default != NULL))
+          g_object_unref (app_default);
+    }
+
+    g_list_free (mime_types);
+    g_hash_table_destroy (user_mime);
+
+    window->mime_model = GTK_TREE_MODEL (model);
+
+    return n;
+}
+
+
+
+static void
+xfce_mime_window_filter_changed (GtkEntry       *entry,
+                                   XfceMimeWindow *window)
+{
+    const gchar *text;
+    gint         count;
+
+    g_free (window->filter_text);
+
+    text = gtk_entry_get_text (GTK_ENTRY (entry));
+    if (text == NULL || *text == '\0')
+        window->filter_text = NULL;
+    else
+        window->filter_text = g_utf8_casefold (text, -1);
+
+    gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (window->filter_model));
+
+    count = gtk_tree_model_iter_n_children (window->filter_model, NULL);
+    xfce_mime_window_statusbar_count (window, count);
+}
+
+
+
+static void
+xfce_mime_window_filter_clear (GtkEntry            *entry,
+                                 GtkEntryIconPosition icon_pos,
+                                 GdkEvent            *event,
+                                 gpointer             user_data)
+{
+    if (icon_pos == GTK_ENTRY_ICON_SECONDARY)
+        gtk_entry_set_text (entry, "");
+}
+
+
+
+static void
+xfce_mime_window_statusbar_count (XfceMimeWindow *window,
+                                    gint            n_mime_types)
+{
+    gchar *msg;
+
+    gtk_statusbar_pop (GTK_STATUSBAR (window->statusbar), window->count_id);
+
+    msg = g_strdup_printf (ngettext ("%d mime type found",
+                                     "%d mime types found",
+                                     n_mime_types), n_mime_types);
+    gtk_statusbar_push (GTK_STATUSBAR (window->statusbar), window->count_id, msg);
+    g_free (msg);
+}
+
+
+
+static gboolean
+xfce_mime_window_row_visible_func (GtkTreeModel *model,
+                                     GtkTreeIter  *iter,
+                                     gpointer      data)
+{
+    XfceMimeWindow *window = XFCE_MIME_WINDOW (data);
+    gchar          *mime_type;
+    gboolean        visible = FALSE;
+
+    if (window->filter_text == NULL)
+        return TRUE;
+
+    gtk_tree_model_get (model, iter, COLUMN_MIME_TYPE, &mime_type, -1);
+    if (G_UNLIKELY (mime_type == NULL))
+        return FALSE;
+
+    visible = strstr (mime_type, window->filter_text) != NULL;
+    g_free (mime_type);
+
+    return visible;
+}
+
+
+
+static void
+xfce_mime_window_selection_changed (GtkTreeSelection *selection,
+                                      XfceMimeWindow   *window)
+{
+    gchar        *mime_type;
+    gchar        *description;
+    GtkTreeModel *model;
+    GtkTreeIter   iter;
+
+    gtk_statusbar_pop (GTK_STATUSBAR (window->statusbar),
+                       window->description_id);
+
+    if (gtk_tree_selection_get_selected (selection, &model, &iter))
+    {
+        gtk_tree_model_get (model, &iter, COLUMN_MIME_TYPE, &mime_type, -1);
+        description = g_content_type_get_description (mime_type);
+        g_free (mime_type);
+
+        if (G_LIKELY (description != NULL))
+        {
+            gtk_statusbar_push (GTK_STATUSBAR (window->statusbar),
+                                window->description_id, description);
+            g_free (description);
+        }
+    }
+}
+
+
+
+static void
+xfce_mime_window_column_clicked (GtkTreeViewColumn *column,
+                                   XfceMimeWindow    *window)
+{
+    GtkSortType  sort_type;
+    GList       *columns, *li;
+
+    columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (window->treeview));
+
+    if (gtk_tree_view_column_get_sort_indicator (column))
+    {
+        /* invert sort order */
+        sort_type = gtk_tree_view_column_get_sort_order (column);
+        if (sort_type == GTK_SORT_ASCENDING)
+            sort_type = GTK_SORT_DESCENDING;
+        else
+            sort_type = GTK_SORT_ASCENDING;
+    }
+    else
+    {
+        /* update indicator visibility */
+        for (li = columns; li != NULL; li = li->next)
+            gtk_tree_view_column_set_sort_indicator (li->data, li->data == column);
+
+        /* always start asc sort on first click */
+        sort_type = GTK_SORT_ASCENDING;
+    }
+
+    /* update arrow and sort column */
+    gtk_tree_view_column_set_sort_order (column, sort_type);
+    gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (window->mime_model),
+        g_list_index (columns, column), sort_type);
+    g_list_free (columns);
+}
+
+
+
+static gboolean
+xfce_mime_window_combo_row_separator_func (GtkTreeModel *model,
+                                             GtkTreeIter  *iter,
+                                             gpointer      data)
+{
+    guint type;
+
+    gtk_tree_model_get (model, iter, COLUMN_APP_TYPE, &type, -1);
+
+    return type == APP_TYPE_SEPARATOR;
+}
+
+
+
+typedef struct
+{
+    guint           ref_count;
+    XfceMimeWindow *window;
+    gchar          *mime_type;
+    GtkTreePath    *path;
+}
+MimeChangedData;
+
+
+
+static void
+xfce_mime_window_combo_unref_data (gpointer user_data)
+{
+    MimeChangedData *data = user_data;
+
+    if (--data->ref_count > 0)
+        return;
+
+    g_free (data->mime_type);
+    gtk_tree_path_free (data->path);
+    g_slice_free (MimeChangedData, data);
+}
+
+
+
+static void
+xfce_mime_window_reset_response (GtkWidget       *dialog,
+                                 gint             response_id,
+                                 MimeChangedData *data)
+{
+    GAppInfo       *app_default;
+    const gchar    *app_name;
+    GtkTreeIter     mime_iter;
+
+    gtk_widget_destroy (dialog);
+
+    if (response_id == GTK_RESPONSE_YES)
+    {
+        if (!gtk_tree_model_get_iter (data->window->mime_model, &mime_iter, data->path))
+            return;
+
+        /* reset the user's default */
+        g_app_info_reset_type_associations (data->mime_type);
+
+        /* restore the system default */
+        app_default = g_app_info_get_default_for_type (data->mime_type, FALSE);
+        if (app_default != NULL)
+          app_name = g_app_info_get_name (app_default);
+        else
+          app_name = NULL;
+
+        gtk_list_store_set (GTK_LIST_STORE (data->window->mime_model), &mime_iter,
+                            COLUMN_MIME_DEFAULT, app_name,
+                            COLUMN_MIME_STATUS, _("Default"),
+                            COLUMN_MIME_ATTRS, NULL,
+                            -1);
+
+        if (app_default != NULL)
+            g_object_unref (app_default);
+    }
+
+    xfce_mime_window_combo_unref_data (data);
+}
+
+
+
+static void
+xfce_mime_window_combo_changed (GtkWidget       *combo,
+                                MimeChangedData *data)
+{
+    XfceMimeWindow *window = XFCE_MIME_WINDOW (data->window);
+    GtkTreeModel   *model;
+    GtkTreeIter     iter;
+    guint           type;
+    GAppInfo       *app_info;
+    GError         *error = NULL;
+    GtkTreeIter     mime_iter;
+    GtkWidget *dialog;
+    gchar *primary;
+
+    model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
+    if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter))
+        return;
+
+    gtk_tree_model_get (model, &iter,
+                        COLUMN_APP_TYPE, &type,
+                        COLUMN_APP_INFO, &app_info, -1);
+
+    if (type == APP_TYPE_APP
+        && app_info != NULL)
+    {
+        if (g_app_info_set_as_default_for_type (app_info, data->mime_type, &error))
+        {
+            if (gtk_tree_model_get_iter (window->mime_model, &mime_iter, data->path))
+            {
+                gtk_list_store_set (GTK_LIST_STORE (window->mime_model), &mime_iter,
+                                    COLUMN_MIME_DEFAULT, g_app_info_get_name (app_info),
+                                    COLUMN_MIME_STATUS, _("User Set"),
+                                    COLUMN_MIME_ATTRS, window->attrs_bold,
+                                    -1);
+            }
+        }
+        else
+        {
+            xfce_dialog_show_error (GTK_WINDOW (window), error,
+                _("Failed to set application \"%s\" for mime type \"%s\"."),
+                g_app_info_get_name (app_info), data->mime_type);
+            g_error_free (error);
+        }
+
+        g_object_unref (app_info);
+    }
+    else if (type == APP_TYPE_CHOOSER)
+    {
+        g_message ("todo");
+    }
+    else if (type == APP_TYPE_RESET)
+    {
+        primary = g_strdup_printf (_("Are you sure you want to reset content "
+                                     "type \"%s\" to its default value?"), data->mime_type);
+
+        dialog = xfce_message_dialog_new (GTK_WINDOW (window),
+                                          _("Question"),
+                                          GTK_STOCK_DIALOG_QUESTION,
+                                          primary,
+                                          _("This will remove your custom mime-association "
+                                            "and restore the system-wide default."),
+                                          GTK_STOCK_CANCEL, GTK_RESPONSE_NO,
+                                          XFCE_BUTTON_TYPE_MIXED, GTK_STOCK_REVERT_TO_SAVED,
+                                          _("Reset to Default"), GTK_RESPONSE_YES, NULL);
+        g_free (primary);
+
+        /* ref data */
+        data->ref_count++;
+
+        g_signal_connect (G_OBJECT (dialog), "response",
+            G_CALLBACK (xfce_mime_window_reset_response), data);
+        gtk_window_present (GTK_WINDOW (dialog));
+    }
+}
+
+
+
+static void
+xfce_mime_window_combo_populate (GtkCellRenderer *renderer,
+                                 GtkCellEditable *editable,
+                                 const gchar     *path_string,
+                                 XfceMimeWindow  *window)
+{
+    GtkTreeIter      iter;
+    GtkTreeIter      filter_iter;
+    gchar           *mime_type;
+    GList           *app_infos, *li;
+    guint            n;
+    GtkListStore    *model;
+    GAppInfo        *app_info;
+    MimeChangedData *data;
+
+    if (!gtk_tree_model_get_iter_from_string (window->filter_model, &filter_iter, path_string))
+        return;
+    gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (window->filter_model),
+                                                      &iter, &filter_iter);
+
+    model = gtk_list_store_new (N_APP_COLUMNS,
+                                G_TYPE_STRING,
+                                G_TYPE_APP_INFO,
+                                G_TYPE_UINT);
+
+    gtk_tree_model_get (window->mime_model, &iter, COLUMN_MIME_TYPE, &mime_type, -1);
+    app_infos = g_app_info_get_all_for_type (mime_type);
+
+    for (li = app_infos, n = 0; li != NULL; li = li->next)
+    {
+        app_info = G_APP_INFO (li->data);
+        if (G_UNLIKELY (app_info == NULL))
+            continue;
+
+        gtk_list_store_insert_with_values (model, NULL, n++,
+                                           COLUMN_APP_NAME, g_app_info_get_name (app_info),
+                                           COLUMN_APP_INFO, app_info,
+                                           COLUMN_APP_TYPE, APP_TYPE_APP,
+                                           -1);
+        g_object_unref (app_info);
+    }
+
+    if (n != 0)
+    {
+        gtk_list_store_insert_with_values (model, NULL, n++,
+                                           COLUMN_APP_TYPE, APP_TYPE_SEPARATOR,
+                                           -1);
+    }
+
+    gtk_list_store_insert_with_values (model, NULL, n++,
+                                       COLUMN_APP_NAME, _("Choose Application..."),
+                                       COLUMN_APP_TYPE, APP_TYPE_CHOOSER,
+                                       -1);
+
+    gtk_list_store_insert_with_values (model, NULL, n,
+                                       COLUMN_APP_NAME, _("Reset to Default"),
+                                       COLUMN_APP_TYPE, APP_TYPE_RESET,
+                                       -1);
+
+    data = g_slice_new0 (MimeChangedData);
+    data->window = window;
+    data->ref_count = 1;
+    data->mime_type = mime_type;
+    data->path = gtk_tree_model_get_path (window->mime_model, &iter);
+
+    /* directly update the combo */
+    gtk_combo_box_set_model (GTK_COMBO_BOX (editable), GTK_TREE_MODEL (model));
+    g_signal_connect_data (G_OBJECT (editable), "changed",
+        G_CALLBACK (xfce_mime_window_combo_changed), data,
+        (GClosureNotify) xfce_mime_window_combo_unref_data, 0);
+    gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (editable),
+        xfce_mime_window_combo_row_separator_func, NULL, NULL);
+
+    g_list_free (app_infos);
+    g_object_unref (G_OBJECT (model));
+}
diff --git a/dialogs/mime-settings/xfce-mime-window.h b/dialogs/mime-settings/xfce-mime-window.h
new file mode 100644
index 0000000..0c48684
--- /dev/null
+++ b/dialogs/mime-settings/xfce-mime-window.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012 Nick Schermer <nick at xfce.org>
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __XFCE_MIME_WINDOW_H__
+#define __XFCE_MIME_WINDOW_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+typedef struct _XfceMimeWindowClass XfceMimeWindowClass;
+typedef struct _XfceMimeWindow      XfceMimeWindow;
+
+#define XFCE_TYPE_MIME_WINDOW            (xfce_mime_window_get_type ())
+#define XFCE_MIME_WINDOW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_TYPE_MIME_WINDOW, XfceMimeWindow))
+#define XFCE_MIME_WINDOW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_MIME_WINDOW, XfceMimeWindowClass))
+#define XFCE_IS_MIME_WINDOW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFCE_TYPE_MIME_WINDOW))
+#define XFCE_IS_MIME_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFCE_TYPE_MIME_WINDOW))
+#define XFCE_MIME_WINDOW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_TYPE_MIME_WINDOW, XfceMimeWindowClass))
+
+GType      xfce_mime_window_get_type     (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* !__XFCE_MIME_WINDOW_H__ */
diff --git a/dialogs/mime-settings/xfce4-mime-settings.desktop.in b/dialogs/mime-settings/xfce4-mime-settings.desktop.in
new file mode 100644
index 0000000..7bc6b93
--- /dev/null
+++ b/dialogs/mime-settings/xfce4-mime-settings.desktop.in
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Version=1.0
+_Name=Mime Settings
+_Comment=Configure the default application for mime types
+Exec=xfce4-mime-settings
+Icon=application-default-icon
+Terminal=false
+Type=Application
+Categories=X-XFCE;Settings;DesktopSettings;
+StartupNotify=true
+OnlyShowIn=XFCE;
diff --git a/po/POTFILES.in b/po/POTFILES.in
index ea42a56..6e0774d 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -20,6 +20,10 @@ dialogs/keyboard-settings/main.c
 dialogs/keyboard-settings/xfce-keyboard-settings.c
 dialogs/keyboard-settings/xfce-keyboard-settings.desktop.in
 
+dialogs/mime-settings/main.c
+dialogs/mime-settings/xfce-mime-window.c
+dialogs/mime-settings/xfce-mime-settings.desktop.in
+
 dialogs/mouse-settings/main.c
 dialogs/mouse-settings/mouse-dialog.glade
 dialogs/mouse-settings/xfce-mouse-settings.desktop.in


More information about the Xfce4-commits mailing list