gnome-control-center/capplets/file-types/mime-types-model.c
Jonathan Blandford bd160edddf Patch from Kjartan Maraas to fix a bunch of leaks.
Thu Feb 13 18:51:37 2003  Jonathan Blandford  <jrb@redhat.com>

        * capplets/common/gconf-property-editor.c: (gconf_peditor_new):
        * capplets/common/gnome-theme-info.c: (read_meta_theme),
        (update_theme_index), (update_common_theme_dir_index),
        (top_theme_dir_changed), (top_icon_theme_dir_changed),
        (add_common_theme_dir_monitor), (real_add_top_theme_dir_monitor):
        * capplets/default-applications/gnome-default-applications-properti
        es.c: (initialize_default_applications), (read_editor),
        (read_terminal):
        * capplets/file-types/mime-edit-dialog.c: (fill_dialog):
        * capplets/file-types/mime-type-info.c: (load_all_mime_types):
        * capplets/file-types/mime-types-model.c:
        (mime_types_model_get_value):
        * capplets/font/main.c: (font_render_get_gconf), (enum_group_load):
        * capplets/mouse/gnome-mouse-properties.c: (read_cursor_font),
        (cursor_changed):
        * capplets/theme-switcher/gnome-theme-details.c:
        (window_theme_selection_changed):
        * capplets/theme-switcher/gnome-theme-manager.c:
        (meta_theme_selection_changed):
        * capplets/theme-switcher/theme-thumbnail.c:
        (generate_theme_thumbnail):
        * libsounds/sound-properties.c: (sound_properties_add_directory),
        (sound_properties_add_file):
        * libsounds/sound-view.c: (compare_func):
        * libwindow-settings/gnome-window-manager.c:
        (gnome_window_manager_new): Patch from Kjartan Maraas to fix a
        bunch of leaks.
2003-02-14 00:02:50 +00:00

624 lines
16 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* -*- mode: c; style: linux -*- */
/* mime-types-model.c
* Copyright (C) 2000 Red Hat, Inc.,
* (C) 2002 Ximian, Inc.
*
* Written by Bradford Hovinen <hovinen@ximian.com>
* Based on code by Jonathan Blandford <jrb@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* The model-related bootstrapping is lifted from gtk+/gtk/gtktreestore.c
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "mime-types-model.h"
#include "mime-type-info.h"
#include "service-info.h"
#define IS_CATEGORY(entry) ((entry) != NULL && (entry)->type == MODEL_ENTRY_CATEGORY)
enum {
PROP_0,
PROP_CATEGORY_ONLY
};
struct _MimeTypesModelPrivate
{
gint stamp;
gboolean category_only;
};
static GObjectClass *parent_class;
static void mime_types_model_init (MimeTypesModel *mime_types_model,
MimeTypesModelClass *class);
static void mime_types_model_class_init (MimeTypesModelClass *class);
static void mime_types_model_base_init (MimeTypesModelClass *class);
static void mime_types_model_tree_model_init (GtkTreeModelIface *iface);
static void mime_types_model_set_prop (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void mime_types_model_get_prop (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void mime_types_model_finalize (GObject *object);
static guint mime_types_model_get_flags (GtkTreeModel *tree_model);
static gint mime_types_model_get_n_columns (GtkTreeModel *tree_model);
static GType mime_types_model_get_column_type (GtkTreeModel *tree_model,
gint index);
static gboolean mime_types_model_get_iter (GtkTreeModel *tree_model,
GtkTreeIter *iter,
GtkTreePath *path);
static GtkTreePath *mime_types_model_get_path (GtkTreeModel *tree_model,
GtkTreeIter *iter);
static void mime_types_model_get_value (GtkTreeModel *tree_model,
GtkTreeIter *iter,
gint column,
GValue *value);
static gboolean mime_types_model_iter_next (GtkTreeModel *tree_model,
GtkTreeIter *iter);
static gboolean mime_types_model_iter_children (GtkTreeModel *tree_model,
GtkTreeIter *iter,
GtkTreeIter *parent);
static gboolean mime_types_model_iter_has_child (GtkTreeModel *tree_model,
GtkTreeIter *iter);
static gint mime_types_model_iter_n_children (GtkTreeModel *tree_model,
GtkTreeIter *iter);
static gboolean mime_types_model_iter_nth_child (GtkTreeModel *tree_model,
GtkTreeIter *iter,
GtkTreeIter *parent,
gint n);
static gboolean mime_types_model_iter_parent (GtkTreeModel *tree_model,
GtkTreeIter *result,
GtkTreeIter *child);
GType
mime_types_model_get_type (void)
{
static GType mime_types_model_type = 0;
if (!mime_types_model_type) {
static const GTypeInfo mime_types_model_info = {
sizeof (MimeTypesModelClass),
(GBaseInitFunc) mime_types_model_base_init,
NULL, /* GBaseFinalizeFunc */
(GClassInitFunc) mime_types_model_class_init,
NULL, /* GClassFinalizeFunc */
NULL, /* user-supplied data */
sizeof (MimeTypesModel),
0, /* n_preallocs */
(GInstanceInitFunc) mime_types_model_init,
NULL
};
static const GInterfaceInfo tree_model_info = {
(GInterfaceInitFunc) mime_types_model_tree_model_init,
NULL,
NULL
};
mime_types_model_type =
g_type_register_static (G_TYPE_OBJECT,
"MimeTypesModel",
&mime_types_model_info, 0);
g_type_add_interface_static (mime_types_model_type,
GTK_TYPE_TREE_MODEL,
&tree_model_info);
}
return mime_types_model_type;
}
static void
mime_types_model_init (MimeTypesModel *mime_types_model, MimeTypesModelClass *class)
{
mime_types_model->p = g_new0 (MimeTypesModelPrivate, 1);
mime_types_model->p->stamp = g_random_int ();
}
static void
mime_types_model_base_init (MimeTypesModelClass *class)
{
}
static void
mime_types_model_class_init (MimeTypesModelClass *class)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (class);
object_class->finalize = mime_types_model_finalize;
object_class->set_property = mime_types_model_set_prop;
object_class->get_property = mime_types_model_get_prop;
g_object_class_install_property
(object_class, PROP_CATEGORY_ONLY,
g_param_spec_boolean ("category-only",
_("Model for categories only"),
_("Model for categories only"),
FALSE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
parent_class = G_OBJECT_CLASS
(g_type_class_ref (G_TYPE_OBJECT));
}
static void
mime_types_model_tree_model_init (GtkTreeModelIface *iface)
{
iface->get_flags = mime_types_model_get_flags;
iface->get_n_columns = mime_types_model_get_n_columns;
iface->get_column_type = mime_types_model_get_column_type;
iface->get_iter = mime_types_model_get_iter;
iface->get_path = mime_types_model_get_path;
iface->get_value = mime_types_model_get_value;
iface->iter_next = mime_types_model_iter_next;
iface->iter_children = mime_types_model_iter_children;
iface->iter_has_child = mime_types_model_iter_has_child;
iface->iter_n_children = mime_types_model_iter_n_children;
iface->iter_nth_child = mime_types_model_iter_nth_child;
iface->iter_parent = mime_types_model_iter_parent;
}
static void
mime_types_model_set_prop (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
MimeTypesModel *mime_types_model;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_MIME_TYPES_MODEL (object));
mime_types_model = MIME_TYPES_MODEL (object);
switch (prop_id) {
case PROP_CATEGORY_ONLY:
mime_types_model->p->category_only = g_value_get_boolean (value);
break;
default:
g_warning ("Bad property set");
break;
}
}
static void
mime_types_model_get_prop (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
MimeTypesModel *mime_types_model;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_MIME_TYPES_MODEL (object));
mime_types_model = MIME_TYPES_MODEL (object);
switch (prop_id) {
case PROP_CATEGORY_ONLY:
g_value_set_boolean (value, mime_types_model->p->category_only);
break;
default:
g_warning ("Bad property get");
break;
}
}
static void
mime_types_model_finalize (GObject *object)
{
MimeTypesModel *mime_types_model;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_MIME_TYPES_MODEL (object));
mime_types_model = MIME_TYPES_MODEL (object);
g_free (mime_types_model->p);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
GObject *
mime_types_model_new (gboolean category_only)
{
return g_object_new (mime_types_model_get_type (),
"category-only", category_only,
NULL);
}
void
mime_types_model_construct_iter (MimeTypesModel *model, ModelEntry *entry, GtkTreeIter *iter)
{
g_return_if_fail (model != NULL);
g_return_if_fail (IS_MIME_TYPES_MODEL (model));
g_return_if_fail (iter != NULL);
iter->stamp = model->p->stamp;
iter->user_data = entry;
}
static guint
mime_types_model_get_flags (GtkTreeModel *tree_model)
{
g_return_val_if_fail (tree_model != NULL, 0);
g_return_val_if_fail (IS_MIME_TYPES_MODEL (tree_model), 0);
return GTK_TREE_MODEL_ITERS_PERSIST;
}
static gint
mime_types_model_get_n_columns (GtkTreeModel *tree_model)
{
g_return_val_if_fail (tree_model != NULL, 0);
g_return_val_if_fail (IS_MIME_TYPES_MODEL (tree_model), 0);
return MODEL_LAST_COLUMN;
}
static GType
mime_types_model_get_column_type (GtkTreeModel *tree_model, gint index)
{
g_return_val_if_fail (tree_model != NULL, G_TYPE_INVALID);
g_return_val_if_fail (IS_MIME_TYPES_MODEL (tree_model), G_TYPE_INVALID);
switch (index) {
case MODEL_COLUMN_MIME_TYPE:
case MODEL_COLUMN_DESCRIPTION:
case MODEL_COLUMN_FILE_EXT:
return G_TYPE_STRING;
break;
case MODEL_COLUMN_ICON:
return GDK_TYPE_PIXBUF;
break;
default:
return G_TYPE_INVALID;
break;
}
}
/* Adapted from gtk+/gtk/gtktreestore.c, gtk_tree_store_get_iter */
static gboolean
mime_types_model_get_iter (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path)
{
MimeTypesModel *model;
gint *indices, depth, i;
GtkTreeIter parent;
g_return_val_if_fail (tree_model != NULL, FALSE);
g_return_val_if_fail (IS_MIME_TYPES_MODEL (tree_model), FALSE);
model = MIME_TYPES_MODEL (tree_model);
indices = gtk_tree_path_get_indices (path);
depth = gtk_tree_path_get_depth (path);
g_return_val_if_fail (depth > 0, FALSE);
parent.stamp = model->p->stamp;
parent.user_data = get_model_entries (tree_model);
if (!gtk_tree_model_iter_nth_child (tree_model, iter, &parent, indices[0]))
return FALSE;
for (i = 1; i < depth; i++) {
parent = *iter;
if (!gtk_tree_model_iter_nth_child (tree_model, iter, &parent, indices[i]))
return FALSE;
}
return TRUE;
}
static GtkTreePath *
mime_types_model_get_path (GtkTreeModel *tree_model, GtkTreeIter *iter)
{
MimeTypesModel *model;
ModelEntry *entry;
GtkTreePath *path;
g_return_val_if_fail (tree_model != NULL, NULL);
g_return_val_if_fail (IS_MIME_TYPES_MODEL (tree_model), NULL);
model = MIME_TYPES_MODEL (tree_model);
path = gtk_tree_path_new ();
entry = iter->user_data;
while (entry->parent != NULL) {
gtk_tree_path_prepend_index (path, model_entry_get_index (entry->parent, entry));
entry = entry->parent;
}
return path;
}
static void
mime_types_model_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value)
{
MimeTypesModel *model;
ModelEntry *entry;
GdkPixbuf *icon;
gchar *pretty_string;
g_return_if_fail (tree_model != NULL);
g_return_if_fail (IS_MIME_TYPES_MODEL (tree_model));
model = MIME_TYPES_MODEL (tree_model);
entry = iter->user_data;
switch (column) {
case MODEL_COLUMN_MIME_TYPE:
g_value_init (value, G_TYPE_STRING);
switch (entry->type) {
case MODEL_ENTRY_MIME_TYPE:
g_value_set_static_string (value, MIME_TYPE_INFO (entry)->mime_type);
break;
case MODEL_ENTRY_SERVICE:
g_value_set_static_string (value, SERVICE_INFO (entry)->protocol);
break;
default:
g_value_set_string (value, "");
break;
}
break;
case MODEL_COLUMN_DESCRIPTION:
g_value_init (value, G_TYPE_STRING);
switch (entry->type) {
case MODEL_ENTRY_MIME_TYPE:
g_value_set_static_string (value, mime_type_info_get_description (MIME_TYPE_INFO (entry)));
break;
case MODEL_ENTRY_CATEGORY:
g_value_set_static_string (value, MIME_CATEGORY_INFO (entry)->description);
break;
case MODEL_ENTRY_SERVICE:
g_value_set_static_string (value, service_info_get_description (SERVICE_INFO (entry)));
break;
case MODEL_ENTRY_SERVICES_CATEGORY:
g_value_set_static_string (value, _("Internet Services"));
break;
default:
g_value_set_string (value, "");
break;
}
break;
case MODEL_COLUMN_ICON:
g_value_init (value, GDK_TYPE_PIXBUF);
switch (entry->type) {
case MODEL_ENTRY_MIME_TYPE:
icon = mime_type_info_get_icon (MIME_TYPE_INFO (entry));
if (icon != NULL)
g_value_set_object (value, G_OBJECT (icon));
else
g_value_set_object (value, NULL);
break;
default:
g_value_set_object (value, NULL);
break;
}
break;
case MODEL_COLUMN_FILE_EXT:
g_value_init (value, G_TYPE_STRING);
switch (entry->type) {
case MODEL_ENTRY_MIME_TYPE:
pretty_string = mime_type_info_get_file_extensions_pretty_string (MIME_TYPE_INFO (entry));
g_value_set_string (value, pretty_string);
g_free (pretty_string);
break;
case MODEL_ENTRY_SERVICE:
g_value_set_static_string (value, SERVICE_INFO (entry)->protocol);
break;
default:
g_value_set_string (value, "");
break;
}
break;
}
}
static gboolean
mime_types_model_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter)
{
MimeTypesModel *model;
ModelEntry *entry;
g_return_val_if_fail (tree_model != NULL, FALSE);
g_return_val_if_fail (IS_MIME_TYPES_MODEL (tree_model), FALSE);
model = MIME_TYPES_MODEL (tree_model);
entry = iter->user_data;
if (entry != NULL)
iter->user_data = entry->next;
if (model->p->category_only)
while (iter->user_data != NULL && !IS_CATEGORY (MODEL_ENTRY (iter->user_data)))
iter->user_data = MODEL_ENTRY (iter->user_data)->next;
return iter->user_data != NULL;
}
static gboolean
mime_types_model_iter_children (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent)
{
MimeTypesModel *model;
ModelEntry *entry;
g_return_val_if_fail (tree_model != NULL, FALSE);
g_return_val_if_fail (IS_MIME_TYPES_MODEL (tree_model), FALSE);
model = MIME_TYPES_MODEL (tree_model);
if (parent != NULL)
entry = parent->user_data;
else
entry = get_model_entries (tree_model);
iter->user_data = entry->first_child;
if (model->p->category_only)
while (iter->user_data != NULL && !IS_CATEGORY (MODEL_ENTRY (iter->user_data)))
iter->user_data = MODEL_ENTRY (iter->user_data)->next;
return iter->user_data != NULL;
}
static gboolean
mime_types_model_iter_has_child (GtkTreeModel *tree_model, GtkTreeIter *iter)
{
MimeTypesModel *model;
ModelEntry *entry;
g_return_val_if_fail (tree_model != NULL, FALSE);
g_return_val_if_fail (IS_MIME_TYPES_MODEL (tree_model), FALSE);
model = MIME_TYPES_MODEL (tree_model);
entry = iter->user_data;
if (entry == NULL)
return get_model_entries (tree_model)->first_child != NULL;
else if (!model->p->category_only || IS_CATEGORY (entry->first_child))
return entry->first_child != NULL;
else {
for (entry = entry->first_child; entry != NULL; entry = entry->next)
if (IS_CATEGORY (entry))
return TRUE;
return FALSE;
}
}
static gint
mime_types_model_iter_n_children (GtkTreeModel *tree_model, GtkTreeIter *iter)
{
MimeTypesModel *model;
ModelEntry *entry, *tmp;
gint count = 0;
g_return_val_if_fail (tree_model != NULL, 0);
g_return_val_if_fail (IS_MIME_TYPES_MODEL (tree_model), 0);
model = MIME_TYPES_MODEL (tree_model);
if (iter != NULL)
entry = iter->user_data;
else
entry = NULL;
if (entry == NULL)
entry = get_model_entries (tree_model);
if (model->p->category_only) {
for (tmp = entry->first_child; tmp != NULL; tmp = tmp->next) {
if (tmp->type == MODEL_ENTRY_CATEGORY)
count++;
}
} else {
for (tmp = entry->first_child; tmp != NULL; tmp = tmp->next)
count++;
}
return count;
}
static gboolean
mime_types_model_iter_nth_child (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n)
{
MimeTypesModel *model;
ModelEntry *entry;
g_return_val_if_fail (tree_model != NULL, FALSE);
g_return_val_if_fail (IS_MIME_TYPES_MODEL (tree_model), FALSE);
model = MIME_TYPES_MODEL (tree_model);
if (parent != NULL)
entry = parent->user_data;
else
entry = NULL;
if (entry == NULL)
iter->user_data = model_entry_get_nth_child (get_model_entries (tree_model), n, model->p->category_only);
else
iter->user_data = model_entry_get_nth_child (entry, n, model->p->category_only);
return iter->user_data != NULL;
}
static gboolean
mime_types_model_iter_parent (GtkTreeModel *tree_model, GtkTreeIter *result, GtkTreeIter *child)
{
MimeTypesModel *model;
ModelEntry *entry;
g_return_val_if_fail (tree_model != NULL, FALSE);
g_return_val_if_fail (IS_MIME_TYPES_MODEL (tree_model), FALSE);
model = MIME_TYPES_MODEL (tree_model);
entry = child->user_data;
if (entry != NULL && entry->parent->type != MODEL_ENTRY_NONE)
result->user_data = entry->parent;
else
result->user_data = NULL;
return result->user_data != NULL;
}