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-type-builtins.h"
24 #include "libmmanager/mm-types.h"
25 #include "libmmanager/mm-application.h"
26 #include "libmmanager/mm-manager.h"
27 #include "libmmanager/mm-category.h"
29 #include <glib/gi18n.h>
31 /* our parent's model iface */
32 static GtkTreeModelIface parent_iface
= { 0, };
33 static void mm_gtk_application_store_tree_model_iface_init (GtkTreeModelIface
*iface
);
34 static void value_set_gicon_from_mm_type (GValue
*val
, MMApplicationType type
);
36 G_DEFINE_TYPE_EXTENDED (MMGtkApplicationStore
, mm_gtk_application_store
,
37 GTK_TYPE_TREE_STORE
, 0,
38 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL
,
39 mm_gtk_application_store_tree_model_iface_init
));
42 mm_gtk_application_store_finalize (GObject
*object
)
44 if (G_OBJECT_CLASS (mm_gtk_application_store_parent_class
)->finalize
)
45 G_OBJECT_CLASS (mm_gtk_application_store_parent_class
)->finalize (object
);
49 mm_gtk_application_store_class_init (MMGtkApplicationStoreClass
*klass
)
51 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
53 object_class
->finalize
= mm_gtk_application_store_finalize
;
57 insert_categories_for_app (MMGtkApplicationStore
*self
,
61 GList
*categories
, *l
;
65 /* at the third level of the tree we insert all the categories */
66 categories
= mm_application_get_categories (app
, &error
);
68 g_critical ("MM-GTK: failed to build the ApplicationStore: %s",
72 for (l
= categories
; l
; l
= l
->next
) {
73 gtk_tree_store_append (GTK_TREE_STORE (self
), &child
, &iter
);
74 gtk_tree_store_set (GTK_TREE_STORE (self
), &child
, MM_GTK_APP_STORE_CAT_COLUMN
,
80 insert_applications_for_type (MMGtkApplicationStore
*self
,
83 MMApplicationType type
)
85 GList
*applications
, *l
;
88 /* at the second level of the tree we insert all the applications */
89 applications
= mm_manager_get_application_list_for_type (manager
, type
);
90 for (l
= applications
; l
; l
= l
->next
) {
91 gtk_tree_store_append (GTK_TREE_STORE (self
), &child
, &iter
);
92 gtk_tree_store_set (GTK_TREE_STORE (self
), &child
, MM_GTK_APP_STORE_APP_COLUMN
,
94 insert_categories_for_app (self
, child
, l
->data
);
99 populate_store (MMGtkApplicationStore
*self
)
103 MMApplicationType app_types
[3] = {
104 MM_APPLICATION_MUSIC
,
105 MM_APPLICATION_PHOTO
,
110 manager
= mm_manager_get ();
111 /* at the first level, we insert all the types */
112 for (idx
= 0; idx
< 3; idx
++) {
113 gtk_tree_store_append (GTK_TREE_STORE (self
), &iter
, NULL
);
114 gtk_tree_store_set (GTK_TREE_STORE (self
), &iter
,
115 MM_GTK_APP_STORE_TYPE_COLUMN
, app_types
[idx
],
117 insert_applications_for_type (self
, iter
, manager
, app_types
[idx
]);
122 mm_gtk_application_store_init (MMGtkApplicationStore
*self
)
124 GType types
[] = { MM_TYPE_MAPPLICATION_TYPE
,
129 gtk_tree_store_set_column_types (GTK_TREE_STORE (self
), 3, types
);
130 populate_store (self
);
133 /* retreive an object from our parent's data storage,
134 * unset the value when done. */
136 mm_gtk_application_store_get_object (MMGtkApplicationStore
*self
, GtkTreeIter
*iter
,
139 GValue
*value
= g_new0 (GValue
, 1);
141 /* validate our parameters */
142 g_return_val_if_fail (MM_GTK_IS_APPLICATION_STORE (self
), NULL
);
143 g_return_val_if_fail (iter
!= NULL
, NULL
);
145 /* retreive the object using our parent's interface */
146 parent_iface
.get_value (GTK_TREE_MODEL (self
), iter
, column
, value
);
152 impl_get_column_type (GtkTreeModel
*self
, gint column
)
155 MM_TYPE_MAPPLICATION_TYPE
,
162 g_return_val_if_fail (MM_GTK_IS_APPLICATION_STORE (self
), G_TYPE_INVALID
);
163 g_return_val_if_fail (column
>= 0 && column
< MM_GTK_APP_STORE_N_COLUMNS
, G_TYPE_INVALID
);
165 return types
[column
];
169 value_set_gicon_from_cat (GValue
*val
,
174 icon
= mm_category_get_icon (cat
);
175 if (!icon
|| !G_IS_ICON (icon
)) {
176 /* fallback to a generic mimetype icon */
178 MMApplicationType type
;
179 MMApplication
*application
;
181 application
= mm_category_get_application (cat
);
182 g_object_get (application
, "supported-type", &type
, NULL
);
183 value_set_gicon_from_mm_type (val
, type
);
184 g_object_unref (application
);
186 g_value_take_object (val
, icon
);
191 get_value_for_category (GtkTreeModel
*self
, GtkTreeIter
*iter
,
192 gint column
, GValue
*value
)
198 obj
= mm_gtk_application_store_get_object (MM_GTK_APPLICATION_STORE (self
),
199 iter
, MM_GTK_APP_STORE_CAT_COLUMN
);
200 cat
= MM_CATEGORY (g_value_dup_object (obj
));
204 case MM_GTK_APP_STORE_CAT_COLUMN
:
205 /* return the object itself */
206 g_value_set_object (value
, cat
);
208 case MM_GTK_APP_STORE_APP_COLUMN
:
209 g_value_take_object (value
, mm_category_get_application (cat
));
211 case MM_GTK_APP_STORE_GICON_COLUMN
:
212 value_set_gicon_from_cat (value
, cat
);
214 case MM_GTK_APP_STORE_NAME_COLUMN
:
215 g_value_set_string (value
, mm_category_get_name (cat
));
217 case MM_GTK_APP_STORE_TYPE_COLUMN
:
218 g_critical ("MM-GTK: impossible to get this kind of value, something in the"
222 g_assert_not_reached ();
226 g_object_unref (cat
);
230 value_set_gicon_from_app (GValue
*val
, MMApplication
*app
)
235 app_info
= mm_application_get_app_info (app
);
236 icon
= g_app_info_get_icon (app_info
);
237 if (!icon
|| !G_IS_ICON (icon
)) {
238 /* fallback to a default app icon */
239 icon
= g_themed_icon_new ("application-default-icon");
242 g_value_take_object (val
, icon
);
244 g_object_unref (app_info
);
248 value_set_name_from_app (GValue
*value
, MMApplication
*app
)
252 app_info
= mm_application_get_app_info (app
);
253 g_value_set_string (value
, g_app_info_get_name (app_info
));
255 g_object_unref (app_info
);
259 value_set_supp_type_from_app (GValue
*val
, MMApplication
*app
)
261 MMApplicationType supp_type
;
263 g_object_get (app
, "supported-type", &supp_type
, NULL
);
265 g_value_set_enum (val
, supp_type
);
269 get_value_for_application (GtkTreeModel
*self
, GtkTreeIter
*iter
,
270 gint column
, GValue
*value
)
275 obj
= mm_gtk_application_store_get_object (MM_GTK_APPLICATION_STORE (self
),
276 iter
, MM_GTK_APP_STORE_APP_COLUMN
);
277 app
= MM_APPLICATION (g_value_dup_object (obj
));
281 case MM_GTK_APP_STORE_APP_COLUMN
:
282 /* return the object itself */
283 g_value_set_object (value
, app
);
285 case MM_GTK_APP_STORE_GICON_COLUMN
:
286 value_set_gicon_from_app (value
, app
);
288 case MM_GTK_APP_STORE_NAME_COLUMN
:
289 value_set_name_from_app (value
, app
);
291 case MM_GTK_APP_STORE_TYPE_COLUMN
:
292 value_set_supp_type_from_app (value
, app
);
294 case MM_GTK_APP_STORE_CAT_COLUMN
:
295 g_critical ("MM-GTK: impossible to get this kind of value, something in the"
298 g_assert_not_reached ();
302 g_object_unref (app
);
306 value_set_name_from_mm_type (GValue
*val
,
307 MMApplicationType type
)
309 static const char *messages
[] = {
315 g_value_set_string (val
, messages
[type
-1]);
319 value_set_gicon_from_mm_type (GValue
*val
,
320 MMApplicationType type
)
325 case MM_APPLICATION_MUSIC
:
326 icon
= g_themed_icon_new ("audio-x-generic");
328 case MM_APPLICATION_VIDEO
:
329 icon
= g_themed_icon_new ("video-x-generic");
331 case MM_APPLICATION_PHOTO
:
332 icon
= g_themed_icon_new ("image-x-generic");
335 g_assert_not_reached ();
339 g_value_take_object (val
, icon
);
343 get_value_for_mm_type (GtkTreeModel
*self
, GtkTreeIter
*iter
,
344 gint column
, GValue
*value
)
346 MMApplicationType type
;
349 obj
= mm_gtk_application_store_get_object (MM_GTK_APPLICATION_STORE (self
),
350 iter
, MM_GTK_APP_STORE_TYPE_COLUMN
);
351 type
= g_value_get_enum (obj
);
354 case MM_GTK_APP_STORE_TYPE_COLUMN
:
355 /* return the value itself */
356 g_value_copy (obj
, value
);
358 case MM_GTK_APP_STORE_GICON_COLUMN
:
359 value_set_gicon_from_mm_type (value
, type
);
361 case MM_GTK_APP_STORE_NAME_COLUMN
:
362 value_set_name_from_mm_type (value
, type
);
364 case MM_GTK_APP_STORE_CAT_COLUMN
:
365 case MM_GTK_APP_STORE_APP_COLUMN
:
366 g_critical ("MM-GTK: impossible to get this kind of value, something in the"
370 g_assert_not_reached ();
378 impl_get_value (GtkTreeModel
*self
, GtkTreeIter
*iter
,
379 gint column
, GValue
*value
)
383 g_return_if_fail (MM_GTK_IS_APPLICATION_STORE (self
));
384 g_return_if_fail (iter
!= NULL
);
385 g_return_if_fail (column
>= 0 && column
< MM_GTK_APP_STORE_N_COLUMNS
);
386 g_return_if_fail (value
!= NULL
);
388 value
= g_value_init (value
, impl_get_column_type (self
, column
));
389 depth
= gtk_tree_store_iter_depth (GTK_TREE_STORE (self
), iter
);
391 get_value_for_mm_type (self
, iter
, column
, value
);
392 } else if (depth
== 1) {
393 get_value_for_application (self
, iter
, column
, value
);
394 } else if (depth
== 2) {
395 get_value_for_category (self
, iter
, column
, value
);
397 g_assert_not_reached ();
402 impl_get_n_columns (GtkTreeModel
*self
)
404 g_return_val_if_fail (MM_GTK_IS_APPLICATION_STORE (self
), 0);
406 /* we have four columns:
413 return MM_GTK_APP_STORE_N_COLUMNS
;
417 mm_gtk_application_store_tree_model_iface_init (GtkTreeModelIface
*iface
)
419 /* save a copy of our parent's iface */
420 parent_iface
= *iface
;
422 /* override the iface methods */
423 iface
->get_n_columns
= impl_get_n_columns
;
424 iface
->get_column_type
= impl_get_column_type
;
425 iface
->get_value
= impl_get_value
;
431 * mm_gtk_application_store_new:
433 * Builds a #GtkTreeStore that hierarchically groups all the #MMApplicationType,
434 * #MMApplication and #MMCategory objects in a #GtkTreeModel fashion.
436 * Return value: an already populated #MMGtkApplicationStore.
439 MMGtkApplicationStore
*
440 mm_gtk_application_store_new (void)
442 return g_object_new (MM_GTK_TYPE_APPLICATION_STORE
, NULL
);