1 /*
2 * Copyright (c) 2009, 2010 Intel, Inc.
3 * Copyright (c) 2010 Red Hat, Inc.
4 *
5 * The Control Center is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * The Control Center is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with the Control Center; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 * Author: Thomas Wood <thos@gnome.org>
20 */
21
22 #include "cc-shell-model.h"
23 #include <string.h>
24
25 #define GNOME_SETTINGS_PANEL_ID_KEY "X-Cinnamon-Settings-Panel"
26 #define GNOME_SETTINGS_PANEL_CATEGORY GNOME_SETTINGS_PANEL_ID_KEY
27 #define GNOME_SETTINGS_PANEL_ID_KEYWORDS "Keywords"
28
29
G_DEFINE_TYPE(CcShellModel,cc_shell_model,GTK_TYPE_LIST_STORE)30 G_DEFINE_TYPE (CcShellModel, cc_shell_model, GTK_TYPE_LIST_STORE)
31
32 static GdkPixbuf *
33 load_pixbuf_for_gicon (GIcon *icon)
34 {
35 GtkIconTheme *theme;
36 GtkIconInfo *icon_info;
37 GdkPixbuf *pixbuf = NULL;
38 GError *err = NULL;
39
40 if (icon == NULL)
41 return NULL;
42
43 theme = gtk_icon_theme_get_default ();
44
45 icon_info = gtk_icon_theme_lookup_by_gicon (theme, icon,
46 48, GTK_ICON_LOOKUP_FORCE_SIZE);
47 if (icon_info)
48 {
49 pixbuf = gtk_icon_info_load_icon (icon_info, &err);
50 if (err)
51 {
52 g_warning ("Could not load icon '%s': %s",
53 gtk_icon_info_get_filename (icon_info), err->message);
54 g_error_free (err);
55 }
56
57 gtk_icon_info_free (icon_info);
58 }
59 else
60 {
61 g_warning ("Could not find icon");
62 }
63
64 return pixbuf;
65 }
66
67 static void
icon_theme_changed(GtkIconTheme * theme,CcShellModel * self)68 icon_theme_changed (GtkIconTheme *theme,
69 CcShellModel *self)
70 {
71 GtkTreeIter iter;
72 GtkTreeModel *model;
73 gboolean cont;
74
75 model = GTK_TREE_MODEL (self);
76 cont = gtk_tree_model_get_iter_first (model, &iter);
77 while (cont)
78 {
79 GdkPixbuf *pixbuf;
80 GIcon *icon;
81
82 gtk_tree_model_get (model, &iter,
83 COL_GICON, &icon,
84 -1);
85 pixbuf = load_pixbuf_for_gicon (icon);
86 g_object_unref (icon);
87 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
88 COL_PIXBUF, pixbuf,
89 -1);
90
91 cont = gtk_tree_model_iter_next (model, &iter);
92 }
93 }
94
95 static void
cc_shell_model_class_init(CcShellModelClass * klass)96 cc_shell_model_class_init (CcShellModelClass *klass)
97 {
98 }
99
100 static void
cc_shell_model_init(CcShellModel * self)101 cc_shell_model_init (CcShellModel *self)
102 {
103 GType types[] = {G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
104 GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_ICON, G_TYPE_STRV};
105
106 gtk_list_store_set_column_types (GTK_LIST_STORE (self),
107 N_COLS, types);
108
109 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (self), COL_NAME,
110 GTK_SORT_ASCENDING);
111
112 g_signal_connect (G_OBJECT (gtk_icon_theme_get_default ()), "changed",
113 G_CALLBACK (icon_theme_changed), self);
114 }
115
116 CcShellModel *
cc_shell_model_new(void)117 cc_shell_model_new (void)
118 {
119 return g_object_new (CC_TYPE_SHELL_MODEL, NULL);
120 }
121
122 static gboolean
desktop_entry_has_panel_category(GKeyFile * key_file)123 desktop_entry_has_panel_category (GKeyFile *key_file)
124 {
125 char **strv;
126 gsize len;
127 int i;
128
129 strv = g_key_file_get_string_list (key_file,
130 "Desktop Entry",
131 "Categories",
132 &len,
133 NULL);
134 if (!strv)
135 return FALSE;
136
137 for (i = 0; strv[i]; i++)
138 {
139 if (g_str_equal (strv[i], GNOME_SETTINGS_PANEL_CATEGORY))
140 {
141 g_strfreev (strv);
142 return TRUE;
143 }
144 }
145
146 g_strfreev (strv);
147
148 return FALSE;
149
150 }
151
152 void
cc_shell_model_add_item(CcShellModel * model,const gchar * category_name,GMenuTreeEntry * item)153 cc_shell_model_add_item (CcShellModel *model,
154 const gchar *category_name,
155 GMenuTreeEntry *item)
156 {
157 GAppInfo *appinfo = G_APP_INFO (gmenu_tree_entry_get_app_info (item));
158 GIcon *icon = g_app_info_get_icon (appinfo);
159 const gchar *name = g_app_info_get_name (appinfo);
160 const gchar *desktop = gmenu_tree_entry_get_desktop_file_path (item);
161 const gchar *comment = g_app_info_get_description (appinfo);
162 gchar *id;
163 GdkPixbuf *pixbuf = NULL;
164 GKeyFile *key_file;
165 gchar **keywords;
166
167 /* load the .desktop file since gnome-menus doesn't have a way to read
168 * custom properties from desktop files */
169
170 key_file = g_key_file_new ();
171 g_key_file_load_from_file (key_file, desktop, 0, NULL);
172
173 id = g_key_file_get_string (key_file, "Desktop Entry",
174 GNOME_SETTINGS_PANEL_ID_KEY, NULL);
175
176 if (!id)
177 {
178 /* Refuse to load desktop files without a panel ID, but
179 * with the X-GNOME-Settings-Panel category */
180 if (desktop_entry_has_panel_category (key_file))
181 {
182 g_warning ("Not loading desktop file '%s' because it uses the "
183 GNOME_SETTINGS_PANEL_CATEGORY
184 " category but isn't a panel.",
185 desktop);
186 g_key_file_free (key_file);
187 return;
188 }
189 id = g_strdup (gmenu_tree_entry_get_desktop_file_id (item));
190 }
191
192 keywords = g_key_file_get_locale_string_list (key_file, "Desktop Entry",
193 GNOME_SETTINGS_PANEL_ID_KEYWORDS,
194 NULL, NULL, NULL);
195
196 g_key_file_free (key_file);
197 key_file = NULL;
198
199 pixbuf = load_pixbuf_for_gicon (icon);
200
201 gtk_list_store_insert_with_values (GTK_LIST_STORE (model), NULL, 0,
202 COL_NAME, name,
203 COL_DESKTOP_FILE, desktop,
204 COL_ID, id,
205 COL_PIXBUF, pixbuf,
206 COL_CATEGORY, category_name,
207 COL_DESCRIPTION, comment,
208 COL_GICON, icon,
209 COL_KEYWORDS, keywords,
210 -1);
211
212 g_free (id);
213 g_strfreev (keywords);
214 }
215