Commit 503d8a2f authored by Nick Schermer's avatar Nick Schermer

Add new mime settings dialog.

Application chooser is not working yet.
parent ee51e643
......@@ -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
......@@ -10,3 +10,8 @@ if HAVE_XRANDR
SUBDIRS += \
display-settings
endif
if HAVE_GIO_UNIX
SUBDIRS += \
mime-settings
endif
INCLUDES = \
-I${top_srcdir} \
-DDATADIR=\"$(datadir)\" \
-DSRCDIR=\"$(top_srcdir)\" \
-DLOCALEDIR=\"$(localedir)\" \
-DG_LOG_DOMAIN=\"xfce4-mime-settings\" \
$(PLATFORM_CPPFLAGS)
bin_PROGRAMS = \
xfce4-mime-settings
xfce4_mime_settings_SOURCES = \
main.c \
xfce-mime-window.c \
xfce-mime-window.h
xfce4_mime_settings_CFLAGS = \
$(GTK_CFLAGS) \
$(GIO_CFLAGS) \
$(GIO_UNIX_CFLAGS) \
$(LIBXFCE4UI_CFLAGS) \
$(PLATFORM_CFLAGS)
xfce4_mime_settings_LDFLAGS = \
-no-undefined \
$(PLATFORM_LDFLAGS)
xfce4_mime_settings_LDADD = \
$(GTK_LIBS) \
$(LIBXFCE4UI_LIBS) \
$(GIO_LIBS) \
$(GIO_UNIX_LIBS)
desktopdir = $(datadir)/applications
desktop_in_files = xfce4-mime-settings.desktop.in
desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
@INTLTOOL_DESKTOP_RULE@
EXTRA_DIST = \
$(desktop_in_files)
DISTCLEANFILES = \
$(desktop_DATA)
# vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
/*
* Copyright (C) 2012 Nick Schermer <nick@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;
}
/*
* Copyright (C) 2012 Nick Schermer <nick@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;