Complete signals in the application view.
[mmediamanager.git] / libmmanager-gtk / mm-gtk-application-store.c
blob77dd6d4d520421bb9db22777eaad428a897b73ab
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-application-store.h"
23 #include <libmmanager/mm.h>
24 #include <libmmanager/mm-type-builtins.h>
25 #include <gtk/gtk.h>
26 #include <glib/gi18n.h>
28 /* our parent's model iface */
29 static GtkTreeModelIface parent_iface = { 0, };
30 static void mm_gtk_application_store_tree_model_iface_init (GtkTreeModelIface *iface);
31 static void value_set_gicon_from_mm_type (GValue *val, MMApplicationType type);
33 G_DEFINE_TYPE_EXTENDED (MMGtkApplicationStore, mm_gtk_application_store,
34 GTK_TYPE_TREE_STORE, 0,
35 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
36 mm_gtk_application_store_tree_model_iface_init));
38 static void
39 mm_gtk_application_store_finalize (GObject *object)
41 if (G_OBJECT_CLASS (mm_gtk_application_store_parent_class)->finalize)
42 G_OBJECT_CLASS (mm_gtk_application_store_parent_class)->finalize (object);
45 static void
46 mm_gtk_application_store_class_init (MMGtkApplicationStoreClass *klass)
48 GObjectClass *object_class = G_OBJECT_CLASS (klass);
50 object_class->finalize = mm_gtk_application_store_finalize;
53 static void
54 insert_categories_for_app (MMGtkApplicationStore *self,
55 GtkTreeIter iter,
56 MMApplication *app)
58 GList *categories, *l;
59 GError *error = NULL;
60 GtkTreeIter child;
62 /* at the third level of the tree we insert all the categories */
63 categories = mm_application_get_categories (app, &error);
64 if (error) {
65 g_critical ("MM-GTK: failed to build the ApplicationStore: %s",
66 error->message);
67 return;
69 for (l = categories; l; l = l->next) {
70 gtk_tree_store_append (GTK_TREE_STORE (self), &child, &iter);
71 gtk_tree_store_set (GTK_TREE_STORE (self), &child, MM_GTK_APP_STORE_CAT_COLUMN,
72 l->data, -1);
76 static void
77 insert_applications_for_type (MMGtkApplicationStore *self,
78 GtkTreeIter iter,
79 MMManager *manager,
80 MMApplicationType type)
82 GList *applications, *l;
83 GtkTreeIter child;
85 /* at the second level of the tree we insert all the applications */
86 applications = mm_manager_get_application_list_for_type (manager, type);
87 for (l = applications; l; l = l->next) {
88 gtk_tree_store_append (GTK_TREE_STORE (self), &child, &iter);
89 gtk_tree_store_set (GTK_TREE_STORE (self), &child, MM_GTK_APP_STORE_APP_COLUMN,
90 l->data, -1);
91 insert_categories_for_app (self, child, l->data);
95 static void
96 populate_store (MMGtkApplicationStore *self)
98 MMManager *manager;
99 GtkTreeIter iter;
100 MMApplicationType app_types[3] = {
101 MM_APPLICATION_MUSIC,
102 MM_APPLICATION_PHOTO,
103 MM_APPLICATION_VIDEO
105 int idx;
107 manager = mm_manager_get ();
108 /* at the first level, we insert all the types */
109 for (idx = 0; idx < 3; idx++) {
110 gtk_tree_store_append (GTK_TREE_STORE (self), &iter, NULL);
111 gtk_tree_store_set (GTK_TREE_STORE (self), &iter,
112 MM_GTK_APP_STORE_TYPE_COLUMN, app_types[idx],
113 -1);
114 insert_applications_for_type (self, iter, manager, app_types[idx]);
118 static void
119 mm_gtk_application_store_init (MMGtkApplicationStore *self)
121 GType types [] = { MM_TYPE_MAPPLICATION_TYPE,
122 MM_TYPE_APPLICATION,
123 MM_TYPE_CATEGORY
126 gtk_tree_store_set_column_types (GTK_TREE_STORE (self), 3, types);
127 populate_store (self);
130 /* retreive an object from our parent's data storage,
131 * unset the value when done. */
132 static GValue *
133 mm_gtk_application_store_get_object (MMGtkApplicationStore *self, GtkTreeIter *iter,
134 gint column)
136 GValue *value = g_new0 (GValue, 1);
138 /* validate our parameters */
139 g_return_val_if_fail (MM_GTK_IS_APPLICATION_STORE (self), NULL);
140 g_return_val_if_fail (iter != NULL, NULL);
142 /* retreive the object using our parent's interface */
143 parent_iface.get_value (GTK_TREE_MODEL (self), iter, column, value);
145 return value;
148 static GType
149 impl_get_column_type (GtkTreeModel *self, gint column)
151 GType types [] = {
152 MM_TYPE_MAPPLICATION_TYPE,
153 MM_TYPE_APPLICATION,
154 MM_TYPE_CATEGORY,
155 G_TYPE_ICON,
156 G_TYPE_STRING
159 g_return_val_if_fail (MM_GTK_IS_APPLICATION_STORE (self), G_TYPE_INVALID);
160 g_return_val_if_fail (column >= 0 && column < MM_GTK_APP_STORE_N_COLUMNS, G_TYPE_INVALID);
162 return types[column];
165 static void
166 value_set_gicon_from_cat (GValue *val,
167 MMCategory *cat)
169 GIcon *icon;
171 icon = mm_category_get_icon (cat);
172 if (!icon || !G_IS_ICON (icon)) {
173 /* fallback to a generic mimetype icon */
175 MMApplicationType type;
176 MMApplication *application;
178 application = mm_category_get_application (cat);
179 g_object_get (application, "supported-type", &type, NULL);
180 value_set_gicon_from_mm_type (val, type);
181 g_object_unref (application);
182 } else {
183 g_value_take_object (val, icon);
187 static void
188 get_value_for_category (GtkTreeModel *self, GtkTreeIter *iter,
189 gint column, GValue *value)
191 MMCategory *cat;
192 GValue *obj;
193 GIcon *icon;
195 obj = mm_gtk_application_store_get_object (MM_GTK_APPLICATION_STORE (self),
196 iter, MM_GTK_APP_STORE_CAT_COLUMN);
197 cat = MM_CATEGORY (g_value_dup_object (obj));
198 g_value_unset (obj);
200 switch (column) {
201 case MM_GTK_APP_STORE_CAT_COLUMN:
202 /* return the object itself */
203 g_value_set_object (value, cat);
204 break;
205 case MM_GTK_APP_STORE_APP_COLUMN:
206 g_value_take_object (value, mm_category_get_application (cat));
207 break;
208 case MM_GTK_APP_STORE_GICON_COLUMN:
209 value_set_gicon_from_cat (value, cat);
210 break;
211 case MM_GTK_APP_STORE_NAME_COLUMN:
212 g_value_set_string (value, mm_category_get_name (cat));
213 break;
214 case MM_GTK_APP_STORE_TYPE_COLUMN:
215 g_critical ("MM-GTK: impossible to get this kind of value, something in the"
216 "view is wrong!");
217 break;
218 default:
219 g_assert_not_reached ();
220 break;
223 g_object_unref (cat);
226 static void
227 value_set_gicon_from_app (GValue *val, MMApplication *app)
229 GAppInfo *app_info;
230 GIcon *icon;
232 app_info = mm_application_get_app_info (app);
233 icon = g_app_info_get_icon (app_info);
234 if (!icon || !G_IS_ICON (icon)) {
235 /* fallback to a default app icon */
236 icon = g_themed_icon_new ("application-default-icon");
239 g_value_take_object (val, icon);
241 g_object_unref (app_info);
244 static void
245 value_set_name_from_app (GValue *value, MMApplication *app)
247 GAppInfo *app_info;
249 app_info = mm_application_get_app_info (app);
250 g_value_set_string (value, g_app_info_get_name (app_info));
252 g_object_unref (app_info);
255 static void
256 value_set_supp_type_from_app (GValue *val, MMApplication *app)
258 MMApplicationType supp_type;
260 g_object_get (app, "supported-type", &supp_type, NULL);
262 g_value_set_enum (val, supp_type);
265 static void
266 get_value_for_application (GtkTreeModel *self, GtkTreeIter *iter,
267 gint column, GValue *value)
269 MMApplication *app;
270 GValue *obj;
272 obj = mm_gtk_application_store_get_object (MM_GTK_APPLICATION_STORE (self),
273 iter, MM_GTK_APP_STORE_APP_COLUMN);
274 app = MM_APPLICATION (g_value_dup_object (obj));
275 g_value_unset (obj);
277 switch (column) {
278 case MM_GTK_APP_STORE_APP_COLUMN:
279 /* return the object itself */
280 g_value_set_object (value, app);
281 break;
282 case MM_GTK_APP_STORE_GICON_COLUMN:
283 value_set_gicon_from_app (value, app);
284 break;
285 case MM_GTK_APP_STORE_NAME_COLUMN:
286 value_set_name_from_app (value, app);
287 break;
288 case MM_GTK_APP_STORE_TYPE_COLUMN:
289 value_set_supp_type_from_app (value, app);
290 break;
291 case MM_GTK_APP_STORE_CAT_COLUMN:
292 g_critical ("MM-GTK: impossible to get this kind of value, something in the"
293 "view is wrong!");
294 default:
295 g_assert_not_reached ();
296 break;
299 g_object_unref (app);
302 static void
303 value_set_name_from_mm_type (GValue *val,
304 MMApplicationType type)
306 static const char *messages[] = {
307 N_("Photos"),
308 N_("Music"),
309 N_("Videos")
312 g_value_set_string (val, messages[type-1]);
315 static void
316 value_set_gicon_from_mm_type (GValue *val,
317 MMApplicationType type)
319 GIcon *icon;
321 switch (type) {
322 case MM_APPLICATION_MUSIC:
323 icon = g_themed_icon_new ("audio-x-generic");
324 break;
325 case MM_APPLICATION_VIDEO:
326 icon = g_themed_icon_new ("video-x-generic");
327 break;
328 case MM_APPLICATION_PHOTO:
329 icon = g_themed_icon_new ("image-x-generic");
330 break;
331 default:
332 g_assert_not_reached ();
333 break;
336 g_value_take_object (val, icon);
339 static void
340 get_value_for_mm_type (GtkTreeModel *self, GtkTreeIter *iter,
341 gint column, GValue *value)
343 MMApplicationType type;
344 GValue *obj;
346 obj = mm_gtk_application_store_get_object (MM_GTK_APPLICATION_STORE (self),
347 iter, MM_GTK_APP_STORE_TYPE_COLUMN);
348 type = g_value_get_enum (obj);
350 switch (column) {
351 case MM_GTK_APP_STORE_TYPE_COLUMN:
352 /* return the value itself */
353 g_value_copy (obj, value);
354 case MM_GTK_APP_STORE_GICON_COLUMN:
355 value_set_gicon_from_mm_type (value, type);
356 break;
357 case MM_GTK_APP_STORE_NAME_COLUMN:
358 value_set_name_from_mm_type (value, type);
359 break;
360 case MM_GTK_APP_STORE_CAT_COLUMN:
361 case MM_GTK_APP_STORE_APP_COLUMN:
362 g_critical ("MM-GTK: impossible to get this kind of value, something in the"
363 "view is wrong!");
364 break;
365 default:
366 g_assert_not_reached ();
367 break;
370 g_value_unset (obj);
373 static void
374 impl_get_value (GtkTreeModel *self, GtkTreeIter *iter,
375 gint column, GValue *value)
377 int depth;
379 g_return_if_fail (MM_GTK_IS_APPLICATION_STORE (self));
380 g_return_if_fail (iter != NULL);
381 g_return_if_fail (column >= 0 && column < MM_GTK_APP_STORE_N_COLUMNS);
382 g_return_if_fail (value != NULL);
384 value = g_value_init (value, impl_get_column_type (self, column));
385 depth = gtk_tree_store_iter_depth (GTK_TREE_STORE (self), iter);
386 if (depth == 0) {
387 get_value_for_mm_type (self, iter, column, value);
388 } else if (depth == 1) {
389 get_value_for_application (self, iter, column, value);
390 } else if (depth == 2) {
391 get_value_for_category (self, iter, column, value);
392 } else {
393 g_assert_not_reached ();
397 static int
398 impl_get_n_columns (GtkTreeModel *self)
400 g_return_val_if_fail (MM_GTK_IS_APPLICATION_STORE (self), 0);
402 /* we have four columns:
403 * - media type
404 * - application
405 * - category
406 * - gicon
407 * - name
409 return MM_GTK_APP_STORE_N_COLUMNS;
412 static void
413 mm_gtk_application_store_tree_model_iface_init (GtkTreeModelIface *iface)
415 /* save a copy of our parent's iface */
416 parent_iface = *iface;
418 /* override the iface methods */
419 iface->get_n_columns = impl_get_n_columns;
420 iface->get_column_type = impl_get_column_type;
421 iface->get_value = impl_get_value;
424 /* public methods */
425 MMGtkApplicationStore*
426 mm_gtk_application_store_new (void)
428 return g_object_new (MM_GTK_TYPE_APPLICATION_STORE, NULL);