Line |
Branch |
Exec |
Source |
1 |
|
|
/* |
2 |
|
|
* Copyright © 2013 Red Hat, Inc. |
3 |
|
|
* |
4 |
|
|
* This program is free software; you can redistribute it and/or |
5 |
|
|
* modify it under the terms of the GNU General Public License |
6 |
|
|
* as published by the Free Software Foundation; either version 2 |
7 |
|
|
* of the License, or (at your option) any later version. |
8 |
|
|
* |
9 |
|
|
* This program is distributed in the hope that it will be useful, |
10 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 |
|
|
* GNU General Public License for more details. |
13 |
|
|
* |
14 |
|
|
* You should have received a copy of the GNU General Public License |
15 |
|
|
* along with this program; if not, write to the Free Software |
16 |
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
17 |
|
|
* 02110-1301, USA. |
18 |
|
|
*/ |
19 |
|
|
|
20 |
|
|
#include "config.h" |
21 |
|
|
|
22 |
|
|
#include <stdlib.h> |
23 |
|
|
|
24 |
|
|
#include <glib.h> |
25 |
|
|
#include <glib/gi18n.h> |
26 |
|
|
#include <gio/gio.h> |
27 |
|
|
#include <adwaita.h> |
28 |
|
|
|
29 |
|
|
#include "cc-application.h" |
30 |
|
|
#include "cc-log.h" |
31 |
|
|
#include "cc-object-storage.h" |
32 |
|
|
#include "cc-panel-loader.h" |
33 |
|
|
#include "cc-window.h" |
34 |
|
|
|
35 |
|
|
struct _CcApplication |
36 |
|
|
{ |
37 |
|
|
AdwApplication parent; |
38 |
|
|
|
39 |
|
|
CcShellModel *model; |
40 |
|
|
|
41 |
|
|
CcWindow *window; |
42 |
|
|
}; |
43 |
|
|
|
44 |
|
|
static void cc_application_quit (GSimpleAction *simple, |
45 |
|
|
GVariant *parameter, |
46 |
|
|
gpointer user_data); |
47 |
|
|
|
48 |
|
|
static void launch_panel_activated (GSimpleAction *action, |
49 |
|
|
GVariant *parameter, |
50 |
|
|
gpointer user_data); |
51 |
|
|
|
52 |
|
|
static void help_activated (GSimpleAction *action, |
53 |
|
|
GVariant *parameter, |
54 |
|
|
gpointer user_data); |
55 |
|
|
|
56 |
|
|
static void about_activated (GSimpleAction *action, |
57 |
|
|
GVariant *parameter, |
58 |
|
|
gpointer user_data); |
59 |
|
|
|
60 |
|
|
static gboolean cmd_verbose_cb (const char *option_name, |
61 |
|
|
const char *value, |
62 |
|
|
gpointer data, |
63 |
|
|
GError **error); |
64 |
|
|
|
65 |
|
✗ |
G_DEFINE_TYPE (CcApplication, cc_application, ADW_TYPE_APPLICATION) |
66 |
|
|
|
67 |
|
|
const GOptionEntry all_options[] = { |
68 |
|
|
{ "version", 0, 0, G_OPTION_ARG_NONE, NULL, N_("Display version number"), NULL }, |
69 |
|
|
{ "verbose", 'v', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, cmd_verbose_cb, N_("Enable verbose mode"), NULL }, |
70 |
|
|
{ "search", 's', 0, G_OPTION_ARG_STRING, NULL, N_("Search for the string"), "SEARCH" }, |
71 |
|
|
{ "list", 'l', 0, G_OPTION_ARG_NONE, NULL, N_("List possible panel names and exit"), NULL }, |
72 |
|
|
{ G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, NULL, N_("Panel to display"), N_("[PANEL] [ARGUMENT…]") }, |
73 |
|
|
{ NULL, 0, 0, 0, NULL, NULL, NULL } /* end the list */ |
74 |
|
|
}; |
75 |
|
|
|
76 |
|
|
static const GActionEntry cc_app_actions[] = { |
77 |
|
|
{ "launch-panel", launch_panel_activated, "(sav)", NULL, NULL, { 0 } }, |
78 |
|
|
{ "help", help_activated, NULL, NULL, NULL, { 0 } }, |
79 |
|
|
{ "quit", cc_application_quit, NULL, NULL, NULL, { 0 } }, |
80 |
|
|
{ "about", about_activated, NULL, NULL, NULL, { 0 } } |
81 |
|
|
}; |
82 |
|
|
|
83 |
|
|
static void |
84 |
|
✗ |
help_activated (GSimpleAction *action, |
85 |
|
|
GVariant *parameter, |
86 |
|
|
gpointer user_data) |
87 |
|
|
{ |
88 |
|
✗ |
CcApplication *self = CC_APPLICATION (user_data); |
89 |
|
|
CcPanel *panel; |
90 |
|
|
GtkWidget *window; |
91 |
|
✗ |
const char *uri = NULL; |
92 |
|
|
|
93 |
|
✗ |
panel = cc_shell_get_active_panel (CC_SHELL (self->window)); |
94 |
|
✗ |
if (panel) |
95 |
|
✗ |
uri = cc_panel_get_help_uri (panel); |
96 |
|
|
|
97 |
|
✗ |
window = cc_shell_get_toplevel (CC_SHELL (self->window)); |
98 |
|
✗ |
gtk_show_uri (GTK_WINDOW (window), |
99 |
|
|
uri ? uri : "help:gnome-help/prefs", |
100 |
|
|
GDK_CURRENT_TIME); |
101 |
|
✗ |
} |
102 |
|
|
|
103 |
|
|
static void |
104 |
|
✗ |
about_activated (GSimpleAction *action, |
105 |
|
|
GVariant *parameter, |
106 |
|
|
gpointer user_data) |
107 |
|
|
|
108 |
|
|
{ |
109 |
|
✗ |
CcApplication *self = CC_APPLICATION (user_data); |
110 |
|
|
AdwDialog *about_dialog; |
111 |
|
|
const char *developer_name; |
112 |
|
|
|
113 |
|
✗ |
about_dialog = adw_about_dialog_new_from_appdata ("/org/gnome/Settings/appdata", NULL); |
114 |
|
✗ |
adw_about_dialog_set_version (ADW_ABOUT_DIALOG (about_dialog), VERSION); |
115 |
|
✗ |
developer_name = adw_about_dialog_get_developer_name (ADW_ABOUT_DIALOG (about_dialog)); |
116 |
|
|
/* Translators should localize the following string which will be displayed in the About dialog giving credit to the translator(s). */ |
117 |
|
✗ |
adw_about_dialog_set_translator_credits (ADW_ABOUT_DIALOG (about_dialog), _("translator-credits")); |
118 |
|
✗ |
adw_about_dialog_set_copyright (ADW_ABOUT_DIALOG (about_dialog), g_strdup_printf (_("© 1998 %s"), developer_name)); |
119 |
|
|
|
120 |
|
✗ |
adw_dialog_present (about_dialog, GTK_WIDGET (self->window)); |
121 |
|
✗ |
} |
122 |
|
|
|
123 |
|
|
static gboolean |
124 |
|
✗ |
cmd_verbose_cb (const char *option_name, |
125 |
|
|
const char *value, |
126 |
|
|
gpointer data, |
127 |
|
|
GError **error) |
128 |
|
|
{ |
129 |
|
✗ |
cc_log_increase_verbosity (); |
130 |
|
|
|
131 |
|
✗ |
return TRUE; |
132 |
|
|
} |
133 |
|
|
|
134 |
|
|
static void |
135 |
|
✗ |
launch_panel_activated (GSimpleAction *action, |
136 |
|
|
GVariant *parameter, |
137 |
|
|
gpointer user_data) |
138 |
|
|
{ |
139 |
|
✗ |
CcApplication *self = CC_APPLICATION (user_data); |
140 |
|
✗ |
g_autoptr(GVariant) parameters = NULL; |
141 |
|
✗ |
g_autoptr(GError) error = NULL; |
142 |
|
|
gchar *panel_id; |
143 |
|
|
|
144 |
|
✗ |
g_variant_get (parameter, "(&s@av)", &panel_id, ¶meters); |
145 |
|
|
|
146 |
|
✗ |
g_debug ("gnome-control-center: 'launch-panel' activated for panel '%s' with %"G_GSIZE_FORMAT" arguments", |
147 |
|
|
panel_id, |
148 |
|
|
g_variant_n_children (parameters)); |
149 |
|
|
|
150 |
|
✗ |
if (!cc_shell_set_active_panel_from_id (CC_SHELL (self->window), panel_id, parameters, &error)) |
151 |
|
✗ |
g_warning ("Failed to activate the '%s' panel: %s", panel_id, error->message); |
152 |
|
|
|
153 |
|
|
/* Now present the window */ |
154 |
|
✗ |
g_application_activate (G_APPLICATION (self)); |
155 |
|
✗ |
} |
156 |
|
|
|
157 |
|
|
static char ** |
158 |
|
✗ |
get_current_desktops (void) |
159 |
|
|
{ |
160 |
|
|
const char *envvar; |
161 |
|
|
|
162 |
|
✗ |
envvar = g_getenv ("XDG_CURRENT_DESKTOP"); |
163 |
|
|
|
164 |
|
✗ |
if (!envvar) |
165 |
|
✗ |
return g_new0 (char *, 0 + 1); |
166 |
|
|
|
167 |
|
✗ |
return g_strsplit (envvar, G_SEARCHPATH_SEPARATOR_S, 0); |
168 |
|
|
} |
169 |
|
|
|
170 |
|
|
static gboolean |
171 |
|
✗ |
is_supported_desktop (void) |
172 |
|
|
{ |
173 |
|
✗ |
g_auto(GStrv) desktops = NULL; |
174 |
|
|
guint i; |
175 |
|
|
|
176 |
|
✗ |
desktops = get_current_desktops (); |
177 |
|
✗ |
for (i = 0; desktops[i] != NULL; i++) |
178 |
|
|
{ |
179 |
|
|
/* This matches OnlyShowIn in gnome-control-center.desktop.in.in */ |
180 |
|
✗ |
if (g_ascii_strcasecmp (desktops[i], "GNOME") == 0) |
181 |
|
✗ |
return TRUE; |
182 |
|
|
} |
183 |
|
|
|
184 |
|
✗ |
return FALSE; |
185 |
|
|
} |
186 |
|
|
|
187 |
|
|
static gint |
188 |
|
✗ |
cc_application_handle_local_options (GApplication *application, |
189 |
|
|
GVariantDict *options) |
190 |
|
|
{ |
191 |
|
✗ |
if (g_variant_dict_contains (options, "version")) |
192 |
|
|
{ |
193 |
|
✗ |
g_print ("Local options %s %s\n", PACKAGE, VERSION); |
194 |
|
✗ |
return 0; |
195 |
|
|
} |
196 |
|
|
|
197 |
|
✗ |
if (!is_supported_desktop ()) |
198 |
|
|
{ |
199 |
|
✗ |
g_printerr ("Running gnome-control-center is only supported under GNOME and Unity, exiting\n"); |
200 |
|
✗ |
return 1; |
201 |
|
|
} |
202 |
|
|
|
203 |
|
✗ |
if (g_variant_dict_contains (options, "list")) |
204 |
|
|
{ |
205 |
|
✗ |
cc_panel_loader_list_panels (); |
206 |
|
✗ |
return 0; |
207 |
|
|
} |
208 |
|
|
|
209 |
|
✗ |
return -1; |
210 |
|
|
} |
211 |
|
|
|
212 |
|
|
static int |
213 |
|
✗ |
cc_application_command_line (GApplication *application, |
214 |
|
|
GApplicationCommandLine *command_line) |
215 |
|
|
{ |
216 |
|
|
CcApplication *self; |
217 |
|
✗ |
g_autofree GStrv start_panels = NULL; |
218 |
|
|
GVariantDict *options; |
219 |
|
✗ |
int retval = 0; |
220 |
|
|
char *search_str; |
221 |
|
|
gboolean debug; |
222 |
|
|
|
223 |
|
✗ |
self = CC_APPLICATION (application); |
224 |
|
✗ |
options = g_application_command_line_get_options_dict (command_line); |
225 |
|
|
|
226 |
|
✗ |
debug = g_variant_dict_contains (options, "verbose"); |
227 |
|
|
|
228 |
|
✗ |
if (debug) |
229 |
|
✗ |
cc_log_init (); |
230 |
|
|
|
231 |
|
✗ |
gtk_window_present (GTK_WINDOW (self->window)); |
232 |
|
|
|
233 |
|
✗ |
if (g_variant_dict_lookup (options, "search", "&s", &search_str)) |
234 |
|
|
{ |
235 |
|
✗ |
cc_window_set_search_item (self->window, search_str); |
236 |
|
|
} |
237 |
|
✗ |
else if (g_variant_dict_lookup (options, G_OPTION_REMAINING, "^a&ay", &start_panels)) |
238 |
|
|
{ |
239 |
|
|
const char *start_id; |
240 |
|
✗ |
GError *err = NULL; |
241 |
|
|
GVariant *parameters; |
242 |
|
|
GVariantBuilder builder; |
243 |
|
|
int i; |
244 |
|
|
|
245 |
|
✗ |
g_return_val_if_fail (start_panels[0] != NULL, 1); |
246 |
|
✗ |
start_id = start_panels[0]; |
247 |
|
|
|
248 |
|
✗ |
if (start_panels[1]) |
249 |
|
✗ |
g_debug ("Extra argument: %s", start_panels[1]); |
250 |
|
|
else |
251 |
|
✗ |
g_debug ("No extra argument"); |
252 |
|
|
|
253 |
|
✗ |
g_variant_builder_init (&builder, G_VARIANT_TYPE ("av")); |
254 |
|
|
|
255 |
|
✗ |
for (i = 1; start_panels[i] != NULL; i++) |
256 |
|
✗ |
g_variant_builder_add (&builder, "v", g_variant_new_string (start_panels[i])); |
257 |
|
✗ |
parameters = g_variant_builder_end (&builder); |
258 |
|
✗ |
if (!cc_shell_set_active_panel_from_id (CC_SHELL (self->window), start_id, parameters, &err)) |
259 |
|
|
{ |
260 |
|
✗ |
g_warning ("Could not load setting panel \"%s\": %s", start_id, |
261 |
|
|
(err) ? err->message : "Unknown error"); |
262 |
|
✗ |
retval = 1; |
263 |
|
|
|
264 |
|
✗ |
if (err) |
265 |
|
✗ |
g_clear_error (&err); |
266 |
|
|
} |
267 |
|
|
} |
268 |
|
|
|
269 |
|
✗ |
return retval; |
270 |
|
|
} |
271 |
|
|
|
272 |
|
|
static void |
273 |
|
✗ |
cc_application_quit (GSimpleAction *simple, |
274 |
|
|
GVariant *parameter, |
275 |
|
|
gpointer user_data) |
276 |
|
|
{ |
277 |
|
✗ |
CcApplication *self = CC_APPLICATION (user_data); |
278 |
|
|
|
279 |
|
✗ |
gtk_window_destroy (GTK_WINDOW (self->window)); |
280 |
|
✗ |
} |
281 |
|
|
|
282 |
|
|
|
283 |
|
|
static void |
284 |
|
✗ |
cc_application_activate (GApplication *application) |
285 |
|
|
{ |
286 |
|
✗ |
CcApplication *self = CC_APPLICATION (application); |
287 |
|
|
|
288 |
|
✗ |
gtk_window_present (GTK_WINDOW (self->window)); |
289 |
|
✗ |
} |
290 |
|
|
|
291 |
|
|
static void |
292 |
|
✗ |
cc_application_startup (GApplication *application) |
293 |
|
|
{ |
294 |
|
✗ |
CcApplication *self = CC_APPLICATION (application); |
295 |
|
✗ |
const gchar *help_accels[] = { "F1", NULL }; |
296 |
|
✗ |
g_autoptr(GtkCssProvider) provider = NULL; |
297 |
|
|
|
298 |
|
✗ |
g_action_map_add_action_entries (G_ACTION_MAP (self), |
299 |
|
|
cc_app_actions, |
300 |
|
|
G_N_ELEMENTS (cc_app_actions), |
301 |
|
|
self); |
302 |
|
|
|
303 |
|
✗ |
G_APPLICATION_CLASS (cc_application_parent_class)->startup (application); |
304 |
|
|
|
305 |
|
✗ |
gtk_application_set_accels_for_action (GTK_APPLICATION (application), |
306 |
|
|
"app.help", help_accels); |
307 |
|
|
|
308 |
|
✗ |
self->model = cc_shell_model_new (); |
309 |
|
✗ |
self->window = cc_window_new (GTK_APPLICATION (application), self->model); |
310 |
|
|
|
311 |
|
✗ |
provider = gtk_css_provider_new (); |
312 |
|
✗ |
gtk_css_provider_load_from_resource (provider, "/org/gnome/Settings/gtk/style.css"); |
313 |
|
✗ |
gtk_style_context_add_provider_for_display (gdk_display_get_default (), |
314 |
|
✗ |
GTK_STYLE_PROVIDER (provider), |
315 |
|
|
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); |
316 |
|
✗ |
} |
317 |
|
|
|
318 |
|
|
static void |
319 |
|
✗ |
cc_application_finalize (GObject *object) |
320 |
|
|
{ |
321 |
|
|
/* Destroy the object storage cache when finalizing */ |
322 |
|
✗ |
cc_object_storage_destroy (); |
323 |
|
|
|
324 |
|
✗ |
G_OBJECT_CLASS (cc_application_parent_class)->finalize (object); |
325 |
|
✗ |
} |
326 |
|
|
|
327 |
|
|
static GObject * |
328 |
|
✗ |
cc_application_constructor (GType type, |
329 |
|
|
guint n_construct_params, |
330 |
|
|
GObjectConstructParam *construct_params) |
331 |
|
|
{ |
332 |
|
|
static GObject *self = NULL; |
333 |
|
|
|
334 |
|
✗ |
if (self == NULL) |
335 |
|
|
{ |
336 |
|
✗ |
self = G_OBJECT_CLASS (cc_application_parent_class)->constructor (type, |
337 |
|
|
n_construct_params, |
338 |
|
|
construct_params); |
339 |
|
✗ |
g_object_add_weak_pointer (self, (gpointer) &self); |
340 |
|
✗ |
return self; |
341 |
|
|
} |
342 |
|
|
|
343 |
|
✗ |
return g_object_ref (self); |
344 |
|
|
} |
345 |
|
|
|
346 |
|
|
static void |
347 |
|
✗ |
cc_application_class_init (CcApplicationClass *klass) |
348 |
|
|
{ |
349 |
|
✗ |
GObjectClass *object_class = G_OBJECT_CLASS (klass); |
350 |
|
✗ |
GApplicationClass *application_class = G_APPLICATION_CLASS (klass); |
351 |
|
|
|
352 |
|
✗ |
object_class->finalize = cc_application_finalize; |
353 |
|
✗ |
object_class->constructor = cc_application_constructor; |
354 |
|
✗ |
application_class->activate = cc_application_activate; |
355 |
|
✗ |
application_class->startup = cc_application_startup; |
356 |
|
✗ |
application_class->command_line = cc_application_command_line; |
357 |
|
✗ |
application_class->handle_local_options = cc_application_handle_local_options; |
358 |
|
✗ |
} |
359 |
|
|
|
360 |
|
|
static void |
361 |
|
✗ |
cc_application_init (CcApplication *self) |
362 |
|
|
{ |
363 |
|
✗ |
cc_object_storage_initialize (); |
364 |
|
|
|
365 |
|
✗ |
g_application_add_main_option_entries (G_APPLICATION (self), all_options); |
366 |
|
✗ |
} |
367 |
|
|
|
368 |
|
|
GtkApplication * |
369 |
|
✗ |
cc_application_new (void) |
370 |
|
|
{ |
371 |
|
✗ |
return g_object_new (CC_TYPE_APPLICATION, |
372 |
|
|
"application-id", "org.gnome.Settings", |
373 |
|
|
"flags", G_APPLICATION_HANDLES_COMMAND_LINE, |
374 |
|
|
NULL); |
375 |
|
|
} |
376 |
|
|
|
377 |
|
|
CcShellModel * |
378 |
|
✗ |
cc_application_get_model (CcApplication *self) |
379 |
|
|
{ |
380 |
|
✗ |
g_return_val_if_fail (CC_IS_APPLICATION (self), NULL); |
381 |
|
|
|
382 |
|
✗ |
return self->model; |
383 |
|
|
} |
384 |
|
|
|