Fix a warning about reffing NULL and add fallback code for file icons in
[mmediamanager.git] / libmmanager-gtk / mm-gtk-hit-store.c
blob07e542e395cdc5de281a6c64ecbcf013459e4fff
1 /* MManager - a Desktop wide manager for multimedia applications.
3 * Copyright (C) 2008 Cosimo Cecchi <cosimoc@gnome.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
21 #include "mm-gtk-hit-store.h"
23 #include "libmmanager/mm-attribute-manager.h"
24 #include "libmmanager/mm-attribute-base-manager.h"
25 #include "libmmanager/mm-attribute.h"
26 #include "libmmanager/mm-hit.h"
27 #include "libmmanager/mm-hit-collection.h"
29 #include <gtk/gtk.h>
30 #include <glib.h>
31 #include <glib-object.h>
33 /* our parent's model iface */
34 static GtkTreeModelIface parent_iface = { 0, };
35 static void mm_gtk_hit_store_tree_model_iface_init (GtkTreeModelIface *iface);
37 G_DEFINE_TYPE_EXTENDED (MMGtkHitStore, mm_gtk_hit_store,
38 GTK_TYPE_LIST_STORE, 0,
39 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
40 mm_gtk_hit_store_tree_model_iface_init));
42 static void
43 mm_gtk_hit_store_class_init (MMGtkHitStoreClass *klass)
45 /* do nothing */
48 static void
49 mm_gtk_hit_store_init (MMGtkHitStore *self)
51 GType types [] = { MM_TYPE_HIT };
53 gtk_list_store_set_column_types (GTK_LIST_STORE (self), 1, types);
56 static void
57 populate_from_hit_collection (MMGtkHitStore *self,
58 MMHitCollection *collection)
60 MMHit *hit = NULL;
61 GtkTreeIter iter;
63 /* just append the hit collection to the model */
64 while ((hit = mm_hit_collection_get_next_hit (collection)) != NULL) {
65 gtk_list_store_append (GTK_LIST_STORE (self), &iter);
66 gtk_list_store_set (GTK_LIST_STORE (self), &iter,
67 MM_GTK_HIT_STORE_HIT_COL, hit, -1);
68 /* the store keeps a reference of the object */
69 g_object_unref (hit);
73 /* interface implementation */
75 static GType
76 impl_get_column_type (GtkTreeModel *self, gint column)
78 GType types [] = {
79 MM_TYPE_HIT,
80 G_TYPE_FILE,
81 G_TYPE_STRING,
82 G_TYPE_ICON
85 g_return_val_if_fail (MM_GTK_IS_HIT_STORE (self), G_TYPE_INVALID);
86 g_return_val_if_fail (column >= 0 && column < MM_GTK_HIT_STORE_N_COL, G_TYPE_INVALID);
88 return types[column];
91 static int
92 impl_get_n_columns (GtkTreeModel *self)
94 g_return_val_if_fail (MM_GTK_IS_HIT_STORE (self), 0);
96 /* we have four columns:
97 * - hit
98 * - gfile
99 * - name
100 * - gicon
102 return MM_GTK_HIT_STORE_N_COL;
105 static MMHit *
106 get_hit (GtkTreeModel *self, GtkTreeIter *iter)
108 GValue val = { 0, };
109 MMHit *hit;
111 /* validate our parameters */
112 g_return_val_if_fail (MM_GTK_IS_HIT_STORE (self), NULL);
113 g_return_val_if_fail (iter != NULL, NULL);
115 /* retreive the object using our parent's interface */
116 parent_iface.get_value (self, iter, MM_GTK_HIT_STORE_HIT_COL, &val);
118 hit = MM_HIT (g_value_dup_object (&val));
119 g_value_unset (&val);
121 return hit;
124 static GFile *
125 get_gfile_from_hit (MMHit *hit)
127 GFile *file;
128 GHashTable *pairs;
129 GValue *uri_val;
130 MMAttribute *uri_attr;
131 const char *uri;
133 pairs = mm_hit_get_values (hit,
134 MM_ATTRIBUTE_BASE_URI);
135 uri_attr = mm_attribute_manager_lookup_attribute (mm_attribute_base_manager_get (),
136 MM_ATTRIBUTE_BASE_URI);
137 uri_val = g_hash_table_lookup (pairs, uri_attr);
138 uri = g_value_get_string (uri_val);
139 file = g_file_new_for_uri (uri);
141 g_hash_table_destroy (pairs);
143 return file;
146 static void
147 value_set_gicon_from_hit (GValue *val, MMHit *hit)
149 /* TODO: maybe we should support custom icons in some way... */
150 GFile *file;
151 GFileInfo *info;
152 GIcon *icon;
154 file = get_gfile_from_hit (hit);
155 info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_ICON,
156 0, NULL, NULL);
157 if (info) {
158 icon = g_file_info_get_icon (info);
159 g_object_unref (info);
160 } else {
161 /* fallback */
162 icon = g_themed_icon_new ("document");
165 g_value_take_object (val, icon);
166 g_object_unref (file);
169 static void
170 value_set_name_from_hit (GValue *val, MMHit *hit)
172 GHashTable *pairs;
173 MMAttribute *name_attr;
174 GValue *name_val;
176 pairs = mm_hit_get_values (hit,
177 MM_ATTRIBUTE_BASE_NAME);
178 name_attr = mm_attribute_manager_lookup_attribute (mm_attribute_base_manager_get (),
179 MM_ATTRIBUTE_BASE_NAME);
180 name_val = g_hash_table_lookup (pairs, name_attr);
182 if (name_val) {
183 g_value_copy (name_val, val);
184 } else {
185 /* fallback */
186 GFile *file;
187 GFileInfo *info;
189 file = get_gfile_from_hit (hit);
190 info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
191 0, NULL, NULL);
192 if (info) {
193 g_value_set_string (val, g_file_info_get_display_name (info));
194 g_object_unref (info);
196 g_object_unref (file);
199 g_hash_table_destroy (pairs);
202 static void
203 value_set_gfile_from_hit (GValue *val, MMHit *hit)
205 GFile *file;
207 file = get_gfile_from_hit (hit);
208 g_value_take_object (val, file);
211 static void
212 impl_get_value (GtkTreeModel *self, GtkTreeIter *iter,
213 gint column, GValue *value)
215 MMHit *hit;
217 g_return_if_fail (MM_GTK_IS_HIT_STORE (self));
218 g_return_if_fail (iter != NULL);
219 g_return_if_fail (column >= 0 && column < MM_GTK_HIT_STORE_N_COL);
220 g_return_if_fail (value != NULL);
222 hit = get_hit (self, iter);
223 value = g_value_init (value, impl_get_column_type (self, column));
225 switch (column) {
226 case MM_GTK_HIT_STORE_HIT_COL:
227 g_value_set_object (value, hit);
228 break;
229 case MM_GTK_HIT_STORE_FILE_COL:
230 value_set_gfile_from_hit (value, hit);
231 break;
232 case MM_GTK_HIT_STORE_NAME_COL:
233 value_set_name_from_hit (value, hit);
234 break;
235 case MM_GTK_HIT_STORE_ICON_COL:
236 value_set_gicon_from_hit (value, hit);
237 break;
238 default:
239 g_assert_not_reached ();
240 break;
243 g_object_unref (hit);
246 static void
247 mm_gtk_hit_store_tree_model_iface_init (GtkTreeModelIface *iface)
249 /* save a copy of our parent's iface */
250 parent_iface = *iface;
252 /* override the iface methods */
253 iface->get_n_columns = impl_get_n_columns;
254 iface->get_column_type = impl_get_column_type;
255 iface->get_value = impl_get_value;
258 /* public methods */
260 MMGtkHitStore*
261 mm_gtk_hit_store_new (void)
263 MMGtkHitStore * self;
265 self = MM_GTK_HIT_STORE (g_object_new (MM_GTK_TYPE_HIT_STORE, NULL));
267 return self;
270 void
271 mm_gtk_hit_store_set_collection (MMGtkHitStore *self, MMHitCollection *collection)
273 g_return_if_fail (MM_GTK_IS_HIT_STORE (self));
274 g_return_if_fail (MM_IS_HIT_COLLECTION (collection));
276 gtk_list_store_clear (GTK_LIST_STORE (self));
277 populate_from_hit_collection (self, collection);