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>
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
));
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
);
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
;
54 insert_categories_for_app (MMGtkApplicationStore
*self
,
58 GList
*categories
, *l
;
62 /* at the third level of the tree we insert all the categories */
63 categories
= mm_application_get_categories (app
, &error
);
65 g_critical ("MM-GTK: failed to build the ApplicationStore: %s",
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
,
77 insert_applications_for_type (MMGtkApplicationStore
*self
,
80 MMApplicationType type
)
82 GList
*applications
, *l
;
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
,
91 insert_categories_for_app (self
, child
, l
->data
);
96 populate_store (MMGtkApplicationStore
*self
)
100 MMApplicationType app_types
[3] = {
101 MM_APPLICATION_MUSIC
,
102 MM_APPLICATION_PHOTO
,
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
],
114 insert_applications_for_type (self
, iter
, manager
, app_types
[idx
]);
119 mm_gtk_application_store_init (MMGtkApplicationStore
*self
)
121 GType types
[] = { MM_TYPE_MAPPLICATION_TYPE
,
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. */
133 mm_gtk_application_store_get_object (MMGtkApplicationStore
*self
, GtkTreeIter
*iter
,
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
);
149 impl_get_column_type (GtkTreeModel
*self
, gint column
)
152 MM_TYPE_MAPPLICATION_TYPE
,
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
];
166 value_set_gicon_from_cat (GValue
*val
,
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
);
183 g_value_take_object (val
, icon
);
188 get_value_for_category (GtkTreeModel
*self
, GtkTreeIter
*iter
,
189 gint column
, GValue
*value
)
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
));
201 case MM_GTK_APP_STORE_CAT_COLUMN
:
202 /* return the object itself */
203 g_value_set_object (value
, cat
);
205 case MM_GTK_APP_STORE_APP_COLUMN
:
206 g_value_take_object (value
, mm_category_get_application (cat
));
208 case MM_GTK_APP_STORE_GICON_COLUMN
:
209 value_set_gicon_from_cat (value
, cat
);
211 case MM_GTK_APP_STORE_NAME_COLUMN
:
212 g_value_set_string (value
, mm_category_get_name (cat
));
214 case MM_GTK_APP_STORE_TYPE_COLUMN
:
215 g_critical ("MM-GTK: impossible to get this kind of value, something in the"
219 g_assert_not_reached ();
223 g_object_unref (cat
);
227 value_set_gicon_from_app (GValue
*val
, MMApplication
*app
)
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
);
245 value_set_name_from_app (GValue
*value
, MMApplication
*app
)
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
);
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
);
266 get_value_for_application (GtkTreeModel
*self
, GtkTreeIter
*iter
,
267 gint column
, GValue
*value
)
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
));
278 case MM_GTK_APP_STORE_APP_COLUMN
:
279 /* return the object itself */
280 g_value_set_object (value
, app
);
282 case MM_GTK_APP_STORE_GICON_COLUMN
:
283 value_set_gicon_from_app (value
, app
);
285 case MM_GTK_APP_STORE_NAME_COLUMN
:
286 value_set_name_from_app (value
, app
);
288 case MM_GTK_APP_STORE_TYPE_COLUMN
:
289 value_set_supp_type_from_app (value
, app
);
291 case MM_GTK_APP_STORE_CAT_COLUMN
:
292 g_critical ("MM-GTK: impossible to get this kind of value, something in the"
295 g_assert_not_reached ();
299 g_object_unref (app
);
303 value_set_name_from_mm_type (GValue
*val
,
304 MMApplicationType type
)
306 static const char *messages
[] = {
312 g_value_set_string (val
, messages
[type
-1]);
316 value_set_gicon_from_mm_type (GValue
*val
,
317 MMApplicationType type
)
322 case MM_APPLICATION_MUSIC
:
323 icon
= g_themed_icon_new ("audio-x-generic");
325 case MM_APPLICATION_VIDEO
:
326 icon
= g_themed_icon_new ("video-x-generic");
328 case MM_APPLICATION_PHOTO
:
329 icon
= g_themed_icon_new ("image-x-generic");
332 g_assert_not_reached ();
336 g_value_take_object (val
, icon
);
340 get_value_for_mm_type (GtkTreeModel
*self
, GtkTreeIter
*iter
,
341 gint column
, GValue
*value
)
343 MMApplicationType type
;
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
);
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
);
357 case MM_GTK_APP_STORE_NAME_COLUMN
:
358 value_set_name_from_mm_type (value
, type
);
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"
366 g_assert_not_reached ();
374 impl_get_value (GtkTreeModel
*self
, GtkTreeIter
*iter
,
375 gint column
, GValue
*value
)
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
);
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
);
393 g_assert_not_reached ();
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:
409 return MM_GTK_APP_STORE_N_COLUMNS
;
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
;
425 MMGtkApplicationStore
*
426 mm_gtk_application_store_new (void)
428 return g_object_new (MM_GTK_TYPE_APPLICATION_STORE
, NULL
);