GCC Code Coverage Report


Directory: ./
File: shell/cc-panel-loader.c
Date: 2024-05-04 07:58:27
Exec Total Coverage
Lines: 0 74 0.0%
Functions: 0 6 0.0%
Branches: 0 52 0.0%

Line Branch Exec Source
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /*
3 * Copyright (c) 2012 Giovanni Campagna <scampa.giovanni@gmail.com>
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 <config.h>
23
24 #include <string.h>
25 #include <gio/gdesktopappinfo.h>
26 #include <glib/gi18n.h>
27
28 #include "cc-panel.h"
29 #include "cc-panel-loader.h"
30
31 #ifndef CC_PANEL_LOADER_NO_GTYPES
32
33 /* Extension points */
34 extern GType cc_applications_panel_get_type (void);
35 extern GType cc_background_panel_get_type (void);
36 #ifdef BUILD_BLUETOOTH
37 extern GType cc_bluetooth_panel_get_type (void);
38 #endif /* BUILD_BLUETOOTH */
39 extern GType cc_color_panel_get_type (void);
40 extern GType cc_date_time_panel_get_type (void);
41 extern GType cc_display_panel_get_type (void);
42 extern GType cc_keyboard_panel_get_type (void);
43 extern GType cc_mouse_panel_get_type (void);
44 extern GType cc_multitasking_panel_get_type (void);
45 #ifdef BUILD_NETWORK
46 extern GType cc_network_panel_get_type (void);
47 extern GType cc_wifi_panel_get_type (void);
48 #endif /* BUILD_NETWORK */
49 extern GType cc_notifications_panel_get_type (void);
50 extern GType cc_online_accounts_panel_get_type (void);
51 extern GType cc_power_panel_get_type (void);
52 extern GType cc_printers_panel_get_type (void);
53 extern GType cc_privacy_panel_get_type (void);
54 extern GType cc_search_panel_get_type (void);
55 extern GType cc_sharing_panel_get_type (void);
56 extern GType cc_sound_panel_get_type (void);
57 extern GType cc_system_panel_get_type (void);
58 extern GType cc_ua_panel_get_type (void);
59 #ifdef BUILD_WACOM
60 extern GType cc_wacom_panel_get_type (void);
61 #endif /* BUILD_WACOM */
62 #ifdef BUILD_WWAN
63 extern GType cc_wwan_panel_get_type (void);
64 #endif /* BUILD_WWAN */
65
66 /* Static init functions */
67 #ifdef BUILD_NETWORK
68 extern void cc_wifi_panel_static_init_func (void);
69 #endif /* BUILD_NETWORK */
70 extern void cc_sharing_panel_static_init_func (void);
71 #ifdef BUILD_WACOM
72 extern void cc_wacom_panel_static_init_func (void);
73 #endif /* BUILD_WACOM */
74 #ifdef BUILD_WWAN
75 extern void cc_wwan_panel_static_init_func (void);
76 #endif /* BUILD_WWAN */
77
78 #define PANEL_TYPE(name, get_type, init_func) { name, get_type, init_func }
79
80 #else /* CC_PANEL_LOADER_NO_GTYPES */
81
82 #define PANEL_TYPE(name, get_type, init_func) { name }
83
84 #endif
85
86 static CcPanelLoaderVtable default_panels[] =
87 {
88 PANEL_TYPE("applications", cc_applications_panel_get_type, NULL),
89 PANEL_TYPE("background", cc_background_panel_get_type, NULL),
90 #ifdef BUILD_BLUETOOTH
91 PANEL_TYPE("bluetooth", cc_bluetooth_panel_get_type, NULL),
92 #endif
93 PANEL_TYPE("color", cc_color_panel_get_type, NULL),
94 PANEL_TYPE("display", cc_display_panel_get_type, NULL),
95 PANEL_TYPE("keyboard", cc_keyboard_panel_get_type, NULL),
96 PANEL_TYPE("mouse", cc_mouse_panel_get_type, NULL),
97 PANEL_TYPE("multitasking", cc_multitasking_panel_get_type, NULL),
98 #ifdef BUILD_NETWORK
99 PANEL_TYPE("network", cc_network_panel_get_type, NULL),
100 PANEL_TYPE("wifi", cc_wifi_panel_get_type, cc_wifi_panel_static_init_func),
101 #endif
102 PANEL_TYPE("notifications", cc_notifications_panel_get_type, NULL),
103 PANEL_TYPE("online-accounts", cc_online_accounts_panel_get_type, NULL),
104 PANEL_TYPE("power", cc_power_panel_get_type, NULL),
105 PANEL_TYPE("printers", cc_printers_panel_get_type, NULL),
106 PANEL_TYPE("privacy", cc_privacy_panel_get_type, NULL),
107 PANEL_TYPE("search", cc_search_panel_get_type, NULL),
108 PANEL_TYPE("sharing", cc_sharing_panel_get_type, cc_sharing_panel_static_init_func),
109 PANEL_TYPE("sound", cc_sound_panel_get_type, NULL),
110 PANEL_TYPE("system", cc_system_panel_get_type, NULL),
111 PANEL_TYPE("universal-access", cc_ua_panel_get_type, NULL),
112 #ifdef BUILD_WACOM
113 PANEL_TYPE("wacom", cc_wacom_panel_get_type, cc_wacom_panel_static_init_func),
114 #endif
115 #ifdef BUILD_WWAN
116 PANEL_TYPE("wwan", cc_wwan_panel_get_type, cc_wwan_panel_static_init_func),
117 #endif
118 };
119
120 /* Override for the panel vtable. When NULL, the default_panels will
121 * be used.
122 */
123 static CcPanelLoaderVtable *panels_vtable = default_panels;
124 static gsize panels_vtable_len = G_N_ELEMENTS (default_panels);
125
126 typedef struct
127 {
128 CcPanelCategory category;
129 const gchar *name;
130 } CcSubpageLoaderVtable;
131
132 static CcSubpageLoaderVtable default_subpages[] =
133 {
134 {CC_CATEGORY_SYSTEM, "about"},
135 {CC_CATEGORY_SYSTEM, "datetime"},
136 {CC_CATEGORY_SYSTEM, "region"},
137 {CC_CATEGORY_SYSTEM, "users"},
138 };
139 static CcSubpageLoaderVtable *subpages_vtable = default_subpages;
140 static gsize supages_vtable_len = G_N_ELEMENTS (default_subpages);
141
142 static int
143 parse_categories (GDesktopAppInfo *app)
144 {
145 g_auto(GStrv) split = NULL;
146 const gchar *categories;
147 gint retval;
148
149 categories = g_desktop_app_info_get_categories (app);
150 split = g_strsplit (categories, ";", -1);
151
152 retval = -1;
153
154 #define const_strv(s) ((const gchar* const*) s)
155
156 if (g_strv_contains (const_strv (split), "X-GNOME-ConnectivitySettings"))
157 retval = CC_CATEGORY_CONNECTIVITY;
158 else if (g_strv_contains (const_strv (split), "X-GNOME-PersonalizationSettings"))
159 retval = CC_CATEGORY_PERSONALIZATION;
160 else if (g_strv_contains (const_strv (split), "X-GNOME-AccountSettings"))
161 retval = CC_CATEGORY_ACCOUNT;
162 else if (g_strv_contains (const_strv (split), "X-GNOME-DevicesSettings"))
163 retval = CC_CATEGORY_DEVICES;
164 else if (g_strv_contains (const_strv (split), "X-GNOME-DetailsSettings"))
165 retval = CC_CATEGORY_DETAILS;
166 else if (g_strv_contains (const_strv (split), "X-GNOME-SystemSettings"))
167 retval = CC_CATEGORY_SYSTEM;
168 else if (g_strv_contains (const_strv (split), "X-GNOME-PrivacySettings"))
169 retval = CC_CATEGORY_PRIVACY;
170 else if (g_strv_contains (const_strv (split), "HardwareSettings"))
171 retval = CC_CATEGORY_HARDWARE;
172
173 #undef const_strv
174
175 if (retval < 0)
176 {
177 g_warning ("Invalid categories %s for panel %s",
178 categories, g_app_info_get_id (G_APP_INFO (app)));
179 }
180
181 return retval;
182 }
183
184 #ifndef CC_PANEL_LOADER_NO_GTYPES
185
186 static GHashTable *panel_types;
187
188 static void
189 ensure_panel_types (void)
190 {
191 int i;
192
193 if (G_LIKELY (panel_types != NULL))
194 return;
195
196 panel_types = g_hash_table_new (g_str_hash, g_str_equal);
197 for (i = 0; i < panels_vtable_len; i++)
198 g_hash_table_insert (panel_types, (char*)panels_vtable[i].name, panels_vtable[i].get_type);
199 }
200
201 /**
202 * cc_panel_loader_load_by_name:
203 * @shell: a #CcShell implementation
204 * @name: name of the panel
205 * @parameters: parameters passed to the new panel
206 *
207 * Creates a new instance of a #CcPanel from @name, and sets the
208 * @shell and @parameters properties at construction time.
209 */
210 CcPanel *
211 cc_panel_loader_load_by_name (CcShell *shell,
212 const gchar *name,
213 const gchar *title,
214 GVariant *parameters)
215 {
216 GType (*get_type) (void);
217
218 ensure_panel_types ();
219
220 get_type = g_hash_table_lookup (panel_types, name);
221 g_assert (get_type != NULL);
222
223 return g_object_new (get_type (),
224 "shell", shell,
225 "parameters", parameters,
226 "title", title,
227 NULL);
228 }
229
230 #endif /* CC_PANEL_LOADER_NO_GTYPES */
231
232 /**
233 * cc_panel_loader_fill_model:
234 * @model: a #CcShellModel
235 *
236 * Fills @model with information from the available panels. It
237 * iterates over the panel vtable, gathering the panel names,
238 * build the desktop filename from it, and retrieves additional
239 * information from it.
240 */
241 void
242 cc_panel_loader_fill_model (CcShellModel *model)
243 {
244 guint i;
245
246 for (i = 0; i < panels_vtable_len; i++)
247 {
248 g_autoptr(GDesktopAppInfo) app = NULL;
249 g_autofree gchar *desktop_name = NULL;
250 gint category;
251
252 desktop_name = g_strconcat ("gnome-", panels_vtable[i].name, "-panel.desktop", NULL);
253 app = g_desktop_app_info_new (desktop_name);
254
255 if (!app)
256 {
257 g_warning ("Ignoring broken panel %s (missing desktop file)", panels_vtable[i].name);
258 continue;
259 }
260
261 category = parse_categories (app);
262 if (G_UNLIKELY (category < 0))
263 continue;
264
265 cc_shell_model_add_item (model, category, G_APP_INFO (app), panels_vtable[i].name);
266 }
267
268 for (i = 0; i < supages_vtable_len; i++)
269 {
270 g_autoptr(GDesktopAppInfo) app = NULL;
271 g_autofree gchar *desktop_name = NULL;
272
273 desktop_name = g_strconcat ("gnome-", subpages_vtable[i].name, "-panel.desktop", NULL);
274 app = g_desktop_app_info_new (desktop_name);
275
276 if (!app)
277 {
278 g_warning ("Ignoring broken panel %s (missing desktop file)", subpages_vtable[i].name);
279 continue;
280 }
281
282 cc_shell_model_add_item (model, subpages_vtable[i].category, G_APP_INFO (app), subpages_vtable[i].name);
283 cc_shell_model_set_panel_visibility (model, subpages_vtable[i].name, CC_PANEL_VISIBLE_IN_SEARCH);
284 }
285
286 /* If there's an static init function, execute it after adding all panels to
287 * the model. This will allow the panels to show or hide themselves without
288 * having an instance running.
289 */
290 #ifndef CC_PANEL_LOADER_NO_GTYPES
291 for (i = 0; i < panels_vtable_len; i++)
292 {
293 if (panels_vtable[i].static_init_func)
294 panels_vtable[i].static_init_func ();
295 }
296 #endif
297 }
298
299 /**
300 * cc_panel_loader_list_panels:
301 *
302 * Prints the list of panels from the current panel vtable,
303 * usually as response to running GNOME Settings with the
304 * '--list' command line argument.
305 */
306 void
307 cc_panel_loader_list_panels (void)
308 {
309 guint i;
310
311 g_print ("%s\n", _("Available panels:"));
312
313 for (i = 0; i < panels_vtable_len; i++)
314 g_print ("\t%s\n", panels_vtable[i].name);
315
316 }
317
318 /**
319 * cc_panel_loader_override_vtable:
320 * @override_vtable: the new panel vtable
321 * @n_elements: number of items of @override_vtable
322 *
323 * Override the default panel vtable so that GNOME Settings loads
324 * a custom set of panels. Intended to be used by tests to inject
325 * panels that exercise specific interactions with CcWindow (e.g.
326 * header widgets, permissions, etc).
327 */
328 void
329 cc_panel_loader_override_vtable (CcPanelLoaderVtable *override_vtable,
330 gsize n_elements)
331 {
332 g_assert (override_vtable != NULL);
333 g_assert (n_elements > 0);
334
335 g_debug ("Overriding default panel vtable");
336
337 panels_vtable = override_vtable;
338 panels_vtable_len = n_elements;
339 }
340