Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-3.0-or-later
2 : : // SPDX-FileCopyrightText: Andy Holmes <andrew.g.r.holmes@gmail.com>
3 : :
4 : : #define G_LOG_DOMAIN "valent-preferences-dialog"
5 : :
6 : : #include "config.h"
7 : :
8 : : #include <glib/gi18n-lib.h>
9 : : #include <adwaita.h>
10 : : #include <gtk/gtk.h>
11 : : #include <pango/pango.h>
12 : : #include <valent.h>
13 : :
14 : : #include "valent-preferences-dialog.h"
15 : :
16 : :
17 : : struct _ValentPreferencesDialog
18 : : {
19 : : AdwPreferencesDialog parent_instance;
20 : :
21 : : GSettings *settings;
22 : : GHashTable *pages;
23 : : GHashTable *rows;
24 : :
25 : : /* template */
26 : : AdwPreferencesPage *main_page;
27 : : AdwPreferencesGroup *general_group;
28 : : AdwEntryRow *name_entry;
29 : : GtkRevealer *name_error;
30 : : GtkLabel *name_error_label;
31 : : AdwPreferencesGroup *network_address_group;
32 : : GtkListBox *network_address_list;
33 : : AdwDialog *network_address_dialog;
34 : : GtkEditable *network_address_entry;
35 : : GtkButton *network_address_add;
36 : :
37 : : AdwPreferencesPage *plugin_page;
38 : : AdwPreferencesGroup *plugin_group;
39 : : GtkListBox *plugin_list;
40 : : };
41 : :
42 [ + + + - ]: 66 : G_DEFINE_FINAL_TYPE (ValentPreferencesDialog, valent_preferences_dialog, ADW_TYPE_PREFERENCES_DIALOG)
43 : :
44 : :
45 : : typedef struct
46 : : {
47 : : GType gtype;
48 : : char *title;
49 : : char *domain;
50 : : } ExtensionDescription;
51 : :
52 : : enum {
53 : : EXTEN_APPLICATION_PLUGIN,
54 : : EXTEN_CHANNEL_SERVICE,
55 : : EXTEN_CLIPBOARD_ADAPTER,
56 : : EXTEN_CONTACTS_ADAPTER,
57 : : EXTEN_INPUT_ADAPTER,
58 : : EXTEN_MEDIA_ADAPTER,
59 : : EXTEN_MIXER_ADAPTER,
60 : : EXTEN_NOTIFICATION_ADAPTER,
61 : : EXTEN_SESSION_ADAPTER,
62 : : N_EXTENSIONS,
63 : : };
64 : :
65 : : static ExtensionDescription extensions[N_EXTENSIONS] = { 0, };
66 : :
67 : :
68 : : static int
69 : 3 : plugin_list_sort (GtkListBoxRow *row1,
70 : : GtkListBoxRow *row2,
71 : : gpointer user_data)
72 : : {
73 [ + - + - ]: 3 : if G_UNLIKELY (!ADW_IS_PREFERENCES_ROW (row1) ||
74 : : !ADW_IS_PREFERENCES_ROW (row2))
75 : 0 : return 0;
76 : :
77 : 3 : return g_utf8_collate (adw_preferences_row_get_title ((AdwPreferencesRow *)row1),
78 : 3 : adw_preferences_row_get_title ((AdwPreferencesRow *)row2));
79 : : }
80 : :
81 : : /*
82 : : * Device Name Callbacks
83 : : */
84 : : static void
85 : 0 : on_name_apply (GtkEditable *editable,
86 : : ValentPreferencesDialog *self)
87 : : {
88 : 0 : const char *name = NULL;
89 : :
90 [ # # # # : 0 : g_assert (GTK_IS_EDITABLE (editable));
# # # # ]
91 [ # # ]: 0 : g_assert (VALENT_IS_PREFERENCES_DIALOG (self));
92 : :
93 : 0 : name = gtk_editable_get_text (editable);
94 [ # # ]: 0 : if (valent_device_validate_name (name))
95 : : {
96 : 0 : adw_entry_row_set_show_apply_button (self->name_entry, TRUE);
97 : 0 : gtk_widget_remove_css_class (GTK_WIDGET (self->name_entry), "warning");
98 : 0 : gtk_revealer_set_reveal_child (self->name_error, FALSE);
99 : 0 : gtk_accessible_reset_state (GTK_ACCESSIBLE (self->name_entry),
100 : : GTK_ACCESSIBLE_STATE_INVALID);
101 : 0 : g_settings_set_string (self->settings, "name", name);
102 : : }
103 : : else
104 : : {
105 : 0 : adw_entry_row_set_show_apply_button (self->name_entry, FALSE);
106 : 0 : gtk_widget_add_css_class (GTK_WIDGET (self->name_entry), "warning");
107 : 0 : gtk_revealer_set_reveal_child (self->name_error, TRUE);
108 : 0 : gtk_accessible_update_state (GTK_ACCESSIBLE (self->name_entry),
109 : : GTK_ACCESSIBLE_STATE_INVALID,
110 : : GTK_ACCESSIBLE_INVALID_TRUE,
111 : : -1);
112 : : // FIXME: compel AT-devices to speak the forbidden punctuation
113 : 0 : gtk_accessible_announce (GTK_ACCESSIBLE (self->name_entry),
114 : : gtk_label_get_text (self->name_error_label),
115 : : GTK_ACCESSIBLE_ANNOUNCEMENT_PRIORITY_MEDIUM);
116 : : }
117 : 0 : }
118 : :
119 : : static void
120 : 0 : on_name_changed (GtkEditable *editable,
121 : : ValentPreferencesDialog *self)
122 : : {
123 : 0 : const char *name = NULL;
124 : :
125 [ # # # # : 0 : g_assert (GTK_IS_EDITABLE (editable));
# # # # ]
126 [ # # ]: 0 : g_assert (VALENT_IS_PREFERENCES_DIALOG (self));
127 : :
128 : 0 : name = gtk_editable_get_text (editable);
129 [ # # ]: 0 : if (valent_device_validate_name (name))
130 : : {
131 : 0 : adw_entry_row_set_show_apply_button (self->name_entry, TRUE);
132 : 0 : gtk_widget_remove_css_class (GTK_WIDGET (self->name_entry), "warning");
133 : 0 : gtk_revealer_set_reveal_child (self->name_error, FALSE);
134 : 0 : gtk_accessible_reset_state (GTK_ACCESSIBLE (self->name_entry),
135 : : GTK_ACCESSIBLE_STATE_INVALID);
136 : : }
137 : 0 : }
138 : :
139 : : static void
140 : 0 : on_settings_changed (GSettings *settings,
141 : : const char *key,
142 : : ValentPreferencesDialog *self)
143 : : {
144 : 0 : const char *text = NULL;
145 : 0 : g_autofree char *name = NULL;
146 : :
147 [ # # # # : 0 : g_assert (G_IS_SETTINGS (settings));
# # # # ]
148 [ # # # # ]: 0 : g_assert (key != NULL && *key != '\0');
149 [ # # ]: 0 : g_assert (VALENT_IS_PREFERENCES_DIALOG (self));
150 : :
151 : 0 : name = g_settings_get_string (self->settings, "name");
152 : 0 : text = gtk_editable_get_text (GTK_EDITABLE (self->name_entry));
153 : :
154 [ # # ]: 0 : if (g_strcmp0 (text, name) != 0)
155 : 0 : gtk_editable_set_text (GTK_EDITABLE (self->name_entry), name);
156 : 0 : }
157 : :
158 : : /*
159 : : * PeasEngine Callbacks
160 : : */
161 : : static void
162 : 5 : plugin_row_add_extensions (AdwExpanderRow *plugin_row,
163 : : PeasPluginInfo *info)
164 : : {
165 : 5 : PeasEngine *engine = valent_get_plugin_engine ();
166 : 5 : GtkWidget *row;
167 : :
168 [ + + ]: 50 : for (size_t i = 0; i < N_EXTENSIONS; i++)
169 : : {
170 : 45 : ExtensionDescription extension = extensions[i];
171 : 45 : g_autoptr (ValentContext) domain = NULL;
172 [ + - ]: 29 : g_autoptr (ValentContext) context = NULL;
173 [ + - ]: 29 : g_autoptr (GSettings) settings = NULL;
174 : :
175 [ + + ]: 45 : if (!peas_engine_provides_extension (engine, info, extension.gtype))
176 : 14 : continue;
177 : :
178 : : /* Skip this plugin's application extension, so can not be disabled
179 : : * from its own user interface.
180 : : */
181 [ + + ]: 31 : if (extension.gtype == VALENT_TYPE_APPLICATION_PLUGIN &&
182 [ + + ]: 5 : g_str_equal (peas_plugin_info_get_module_name (info), "gnome"))
183 : : {
184 : 2 : continue;
185 : : }
186 : :
187 : 29 : row = g_object_new (ADW_TYPE_SWITCH_ROW,
188 : 29 : "title", _(extension.title),
189 : : "selectable", FALSE,
190 : : NULL);
191 : 29 : adw_expander_row_add_row (ADW_EXPANDER_ROW (plugin_row), row);
192 : :
193 : 29 : domain = valent_context_new (NULL, extension.domain, NULL);
194 : 29 : context = valent_context_get_plugin_context (domain, info);
195 : 29 : settings = valent_context_create_settings (context,
196 : : "ca.andyholmes.Valent.Plugin");
197 : 29 : g_settings_bind (settings, "enabled",
198 : : row, "active",
199 : : G_SETTINGS_BIND_DEFAULT);
200 : 29 : adw_switch_row_set_active (ADW_SWITCH_ROW (row),
201 : : g_settings_get_boolean (settings, "enabled"));
202 [ + - ]: 29 : g_object_set_data_full (G_OBJECT (row),
203 : : "plugin-settings",
204 : : g_steal_pointer (&settings),
205 : : g_object_unref);
206 : : }
207 : 5 : }
208 : :
209 : : static void
210 : 27 : on_load_plugin (PeasEngine *engine,
211 : : PeasPluginInfo *info,
212 : : ValentPreferencesDialog *self)
213 : : {
214 : 27 : const char *title;
215 : 27 : const char *subtitle;
216 : 27 : const char *icon_name;
217 : :
218 [ - + ]: 27 : g_assert (PEAS_IS_ENGINE (engine));
219 [ + - ]: 27 : g_assert (info != NULL);
220 [ + - ]: 27 : g_assert (VALENT_IS_PREFERENCES_DIALOG (self));
221 : :
222 [ + + ]: 27 : if (peas_plugin_info_is_hidden (info))
223 : : return;
224 : :
225 : 25 : title = peas_plugin_info_get_name (info);
226 : 25 : subtitle = peas_plugin_info_get_description (info);
227 : 25 : icon_name = peas_plugin_info_get_icon_name (info);
228 : :
229 [ + + + - ]: 45 : if (peas_engine_provides_extension (engine, info, VALENT_TYPE_APPLICATION_PLUGIN) ||
230 [ + - ]: 40 : peas_engine_provides_extension (engine, info, VALENT_TYPE_CLIPBOARD_ADAPTER) ||
231 [ + - ]: 40 : peas_engine_provides_extension (engine, info, VALENT_TYPE_CHANNEL_SERVICE) ||
232 [ + - ]: 40 : peas_engine_provides_extension (engine, info, VALENT_TYPE_CONTACTS_ADAPTER) ||
233 [ + - ]: 40 : peas_engine_provides_extension (engine, info, VALENT_TYPE_INPUT_ADAPTER) ||
234 [ + - ]: 40 : peas_engine_provides_extension (engine, info, VALENT_TYPE_MEDIA_ADAPTER) ||
235 [ + - ]: 40 : peas_engine_provides_extension (engine, info, VALENT_TYPE_MIXER_ADAPTER) ||
236 [ - + ]: 40 : peas_engine_provides_extension (engine, info, VALENT_TYPE_NOTIFICATIONS_ADAPTER) ||
237 : 20 : peas_engine_provides_extension (engine, info, VALENT_TYPE_SESSION_ADAPTER))
238 : : {
239 : 5 : GtkWidget *row;
240 : 5 : GtkWidget *icon;
241 : :
242 : 5 : row = g_object_new (ADW_TYPE_EXPANDER_ROW,
243 : : "title", title,
244 : : "subtitle", subtitle,
245 : : "selectable", FALSE,
246 : : NULL);
247 : 5 : icon = g_object_new (GTK_TYPE_IMAGE,
248 : : "accessible-role", GTK_ACCESSIBLE_ROLE_PRESENTATION,
249 : : "icon-name", icon_name,
250 : : NULL);
251 : 5 : adw_expander_row_add_prefix (ADW_EXPANDER_ROW (row), icon);
252 : :
253 : 5 : plugin_row_add_extensions (ADW_EXPANDER_ROW (row), info);
254 : :
255 : 5 : gtk_list_box_insert (self->plugin_list, row, -1);
256 : 5 : g_hash_table_insert (self->rows, info, g_object_ref (row));
257 : : }
258 : : }
259 : :
260 : : static void
261 : 1 : on_unload_plugin (PeasEngine *engine,
262 : : PeasPluginInfo *info,
263 : : ValentPreferencesDialog *self)
264 : : {
265 : 2 : g_autoptr (AdwPreferencesPage) page = NULL;
266 [ - + ]: 1 : g_autoptr (GtkWidget) row = NULL;
267 : :
268 [ - + ]: 1 : if (g_hash_table_steal_extended (self->pages, info, NULL, (void **)&page))
269 : 0 : adw_preferences_dialog_remove (ADW_PREFERENCES_DIALOG (self), page);
270 : :
271 [ + - ]: 1 : if (g_hash_table_steal_extended (self->rows, info, NULL, (void **)&row))
272 : 1 : gtk_list_box_remove (self->plugin_list, row);
273 : 1 : }
274 : :
275 : : /*
276 : : * Manual Connections
277 : : */
278 : : static gboolean
279 : 0 : validate_host_entry (const char *input)
280 : : {
281 : 0 : g_autoptr (GSocketConnectable) net = NULL;
282 : :
283 [ # # # # ]: 0 : if (input == NULL || *input == '\0')
284 : : return FALSE;
285 : :
286 : 0 : net = g_network_address_parse (input, 1716, NULL);
287 [ # # ]: 0 : if (net == NULL)
288 : : return FALSE;
289 : :
290 : : return TRUE;
291 : : }
292 : :
293 : : static void
294 : 0 : on_network_address_activated (GtkWidget *widget,
295 : : ValentPreferencesDialog *self)
296 : : {
297 : 0 : const char *hostname = NULL;
298 : :
299 [ # # # # : 0 : g_assert (GTK_IS_EDITABLE (widget) || GTK_IS_BUTTON (widget));
# # # # #
# # # # #
# # ]
300 [ # # ]: 0 : g_assert (VALENT_IS_PREFERENCES_DIALOG (self));
301 : :
302 : 0 : hostname = gtk_editable_get_text (GTK_EDITABLE (self->network_address_entry));
303 [ # # ]: 0 : if (validate_host_entry (hostname))
304 : : {
305 : 0 : gtk_widget_activate_action (GTK_WIDGET (self),
306 : : "network.add-address",
307 : : "s", hostname);
308 : 0 : gtk_editable_set_text (GTK_EDITABLE (self->network_address_entry), "");
309 : 0 : gtk_widget_grab_focus (GTK_WIDGET (self->network_address_entry));
310 : 0 : adw_dialog_close (self->network_address_dialog);
311 : : }
312 : 0 : }
313 : :
314 : : static void
315 : 0 : on_network_address_changed (GtkEditable *editable,
316 : : GtkButton *button)
317 : : {
318 : 0 : const char *hostname = NULL;
319 : :
320 [ # # # # : 0 : g_assert (GTK_IS_EDITABLE (editable));
# # # # ]
321 [ # # # # : 0 : g_assert (GTK_IS_BUTTON (button));
# # # # ]
322 : :
323 : 0 : hostname = gtk_editable_get_text (editable);
324 [ # # ]: 0 : if (validate_host_entry (hostname))
325 : : {
326 : 0 : gtk_widget_set_sensitive (GTK_WIDGET (button), TRUE);
327 : 0 : gtk_widget_remove_css_class (GTK_WIDGET (editable), "warning");
328 : 0 : gtk_accessible_reset_state (GTK_ACCESSIBLE (editable),
329 : : GTK_ACCESSIBLE_STATE_INVALID);
330 : : }
331 [ # # # # ]: 0 : else if (hostname == NULL || *hostname == '\0')
332 : : {
333 : 0 : gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE);
334 : 0 : gtk_widget_remove_css_class (GTK_WIDGET (editable), "warning");
335 : 0 : gtk_accessible_reset_state (GTK_ACCESSIBLE (editable),
336 : : GTK_ACCESSIBLE_STATE_INVALID);
337 : : }
338 : : else
339 : : {
340 : 0 : gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE);
341 : 0 : gtk_widget_add_css_class (GTK_WIDGET (editable), "warning");
342 : 0 : gtk_accessible_update_state (GTK_ACCESSIBLE (editable),
343 : : GTK_ACCESSIBLE_STATE_INVALID,
344 : : GTK_ACCESSIBLE_INVALID_TRUE,
345 : : -1);
346 : : }
347 : 0 : }
348 : :
349 : : static GtkWidget *
350 : 0 : network_address_create_row (gpointer item,
351 : : gpointer user_data)
352 : : {
353 : 0 : GtkStringObject *string = GTK_STRING_OBJECT (item);
354 : 0 : GtkWidget *row, *button;
355 : 0 : const char *address;
356 : :
357 : 0 : address = gtk_string_object_get_string (string);
358 : 0 : row = g_object_new (ADW_TYPE_ACTION_ROW,
359 : : "title", gtk_string_object_get_string (string),
360 : : "use-markup", FALSE,
361 : : NULL);
362 : 0 : button = g_object_new (GTK_TYPE_BUTTON,
363 : : "icon-name", "edit-delete-symbolic",
364 : : "action-target", g_variant_new_string (address),
365 : : "action-name", "network.remove-address",
366 : 0 : "tooltip-text", _("Remove"),
367 : : "valign", GTK_ALIGN_CENTER,
368 : : NULL);
369 : 0 : gtk_widget_add_css_class (button, "flat");
370 : 0 : adw_action_row_add_suffix (ADW_ACTION_ROW (row), button);
371 : :
372 : 0 : return row;
373 : : }
374 : :
375 : : static void
376 : 2 : on_device_addresses_changed (GSettings *settings,
377 : : const char *key,
378 : : ValentPreferencesDialog *self)
379 : : {
380 : 4 : g_auto (GStrv) addresses = NULL;
381 [ + - ]: 2 : g_autoptr (GtkStringList) model = NULL;
382 : :
383 [ + - + - : 2 : g_assert (G_IS_SETTINGS (settings));
- + - - ]
384 [ + - + - ]: 2 : g_assert (key != NULL && *key != '\0');
385 [ + - ]: 2 : g_assert (VALENT_IS_PREFERENCES_DIALOG (self));
386 : :
387 : 2 : addresses = g_settings_get_strv (self->settings, "device-addresses");
388 : 2 : model = gtk_string_list_new ((const char * const *)addresses);
389 [ + - ]: 2 : gtk_list_box_bind_model (self->network_address_list,
390 : : G_LIST_MODEL (model),
391 : : network_address_create_row,
392 : : NULL, NULL);
393 : 2 : }
394 : :
395 : : /*
396 : : * GActions
397 : : */
398 : : static void
399 : 0 : add_address_action (GtkWidget *widget,
400 : : const char *action_name,
401 : : GVariant *parameter)
402 : : {
403 : 0 : ValentPreferencesDialog *self = VALENT_PREFERENCES_DIALOG (widget);
404 : 0 : g_auto (GStrv) addresses = NULL;
405 : 0 : const char *address = NULL;
406 : :
407 [ # # ]: 0 : g_assert (VALENT_IS_PREFERENCES_DIALOG (self));
408 : :
409 : 0 : address = g_variant_get_string (parameter, NULL);
410 : 0 : addresses = g_settings_get_strv (self->settings, "device-addresses");
411 [ # # ]: 0 : if (!g_strv_contains ((const char * const *)addresses, address))
412 : : {
413 [ # # ]: 0 : g_autoptr (GStrvBuilder) builder = NULL;
414 : :
415 : 0 : builder = g_strv_builder_new ();
416 : 0 : g_strv_builder_add (builder, address);
417 : 0 : g_strv_builder_addv (builder, (const char **)addresses);
418 : :
419 [ # # ]: 0 : g_clear_pointer (&addresses, g_strfreev);
420 : 0 : addresses = g_strv_builder_end (builder);
421 [ # # ]: 0 : g_settings_set_strv (self->settings, "device-addresses",
422 : : (const char * const *)addresses);
423 : : }
424 : 0 : }
425 : :
426 : : static void
427 : 0 : remove_address_action (GtkWidget *widget,
428 : : const char *action_name,
429 : : GVariant *parameter)
430 : : {
431 : 0 : ValentPreferencesDialog *self = VALENT_PREFERENCES_DIALOG (widget);
432 : 0 : g_auto (GStrv) addresses = NULL;
433 : 0 : const char *address = NULL;
434 : :
435 [ # # ]: 0 : g_assert (VALENT_IS_PREFERENCES_DIALOG (self));
436 : :
437 : 0 : address = g_variant_get_string (parameter, NULL);
438 : 0 : addresses = g_settings_get_strv (self->settings, "device-addresses");
439 [ # # ]: 0 : if (g_strv_contains ((const char * const *)addresses, address))
440 : : {
441 [ # # ]: 0 : g_autoptr (GStrvBuilder) builder = NULL;
442 : :
443 : 0 : builder = g_strv_builder_new ();
444 [ # # ]: 0 : for (size_t i = 0; addresses[i] != NULL; i++)
445 : : {
446 [ # # ]: 0 : if (!g_str_equal (addresses[i], address))
447 : 0 : g_strv_builder_add (builder, addresses[i]);
448 : : }
449 : :
450 [ # # ]: 0 : g_clear_pointer (&addresses, g_strfreev);
451 : 0 : addresses = g_strv_builder_end (builder);
452 [ # # ]: 0 : g_settings_set_strv (self->settings, "device-addresses",
453 : : (const char * const *)addresses);
454 : : }
455 : 0 : }
456 : :
457 : : static void
458 : 0 : page_action (GtkWidget *widget,
459 : : const char *action_name,
460 : : GVariant *parameter)
461 : : {
462 : 0 : AdwPreferencesDialog *window = ADW_PREFERENCES_DIALOG (widget);
463 : 0 : const char *module;
464 : :
465 : 0 : module = g_variant_get_string (parameter, NULL);
466 : 0 : adw_preferences_dialog_set_visible_page_name (window, module);
467 : 0 : }
468 : :
469 : : /*
470 : : * GObject
471 : : */
472 : : static void
473 : 2 : valent_preferences_dialog_constructed (GObject *object)
474 : : {
475 : 2 : ValentPreferencesDialog *self = VALENT_PREFERENCES_DIALOG (object);
476 : 4 : g_autofree char *error_label = NULL;
477 : 2 : g_autofree char *name = NULL;
478 : 2 : PeasEngine *engine = NULL;
479 : 2 : unsigned int n_plugins = 0;
480 : :
481 : 2 : G_OBJECT_CLASS (valent_preferences_dialog_parent_class)->constructed (object);
482 : :
483 : : /* Device Name
484 : : */
485 : 2 : self->settings = g_settings_new ("ca.andyholmes.Valent");
486 : 2 : g_signal_connect_object (self->settings,
487 : : "changed::name",
488 : : G_CALLBACK (on_settings_changed),
489 : : self, 0);
490 : 2 : name = g_settings_get_string (self->settings, "name");
491 : 2 : gtk_editable_set_text (GTK_EDITABLE (self->name_entry), name);
492 : :
493 : : // TRANSLATORS: %s is a list of forbidden characters
494 : 2 : error_label = g_strdup_printf (_("The device name must not contain "
495 : : "punctuation or brackets, including %s"),
496 : : "<b><tt>\"',;:.!?()[]<></tt></b>");
497 : 2 : gtk_label_set_markup (self->name_error_label, error_label);
498 : :
499 : : /* Manual Device Setup
500 : : */
501 : 2 : g_signal_connect_object (self->settings,
502 : : "changed::device-addresses",
503 : : G_CALLBACK (on_device_addresses_changed),
504 : : self,
505 : : G_CONNECT_DEFAULT);
506 : 2 : on_device_addresses_changed (self->settings, "device-addresses", self);
507 : :
508 : : /* Plugins
509 : : */
510 : 2 : engine = valent_get_plugin_engine ();
511 : 2 : g_signal_connect_object (engine,
512 : : "load-plugin",
513 : : G_CALLBACK (on_load_plugin),
514 : : self,
515 : : G_CONNECT_AFTER);
516 : 2 : g_signal_connect_object (engine,
517 : : "unload-plugin",
518 : : G_CALLBACK (on_unload_plugin),
519 : : self,
520 : : G_CONNECT_DEFAULT);
521 : :
522 : 2 : n_plugins = g_list_model_get_n_items (G_LIST_MODEL (engine));
523 [ + + ]: 28 : for (unsigned int i = 0; i < n_plugins; i++)
524 : : {
525 : 26 : g_autoptr (PeasPluginInfo) info = NULL;
526 : :
527 : 26 : info = g_list_model_get_item (G_LIST_MODEL (engine), i);
528 [ + - ]: 26 : if (peas_plugin_info_is_loaded (info))
529 : 26 : on_load_plugin (engine, info, self);
530 : : }
531 : 2 : }
532 : :
533 : : static void
534 : 2 : valent_preferences_dialog_dispose (GObject *object)
535 : : {
536 : 2 : ValentPreferencesDialog *self = VALENT_PREFERENCES_DIALOG (object);
537 : :
538 : 2 : g_signal_handlers_disconnect_by_data (valent_get_plugin_engine (), self);
539 [ + - ]: 2 : g_clear_object (&self->settings);
540 : :
541 : 2 : gtk_widget_dispose_template (GTK_WIDGET (object),
542 : : VALENT_TYPE_PREFERENCES_DIALOG);
543 : :
544 : 2 : G_OBJECT_CLASS (valent_preferences_dialog_parent_class)->dispose (object);
545 : 2 : }
546 : :
547 : : static void
548 : 2 : valent_preferences_dialog_finalize (GObject *object)
549 : : {
550 : 2 : ValentPreferencesDialog *self = VALENT_PREFERENCES_DIALOG (object);
551 : :
552 [ + - ]: 2 : g_clear_pointer (&self->pages, g_hash_table_unref);
553 [ + - ]: 2 : g_clear_pointer (&self->rows, g_hash_table_unref);
554 : :
555 : 2 : G_OBJECT_CLASS (valent_preferences_dialog_parent_class)->finalize (object);
556 : 2 : }
557 : :
558 : : static void
559 : 1 : valent_preferences_dialog_class_init (ValentPreferencesDialogClass *klass)
560 : : {
561 : 1 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
562 : 1 : GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
563 : :
564 : 1 : object_class->constructed = valent_preferences_dialog_constructed;
565 : 1 : object_class->dispose = valent_preferences_dialog_dispose;
566 : 1 : object_class->finalize = valent_preferences_dialog_finalize;
567 : :
568 : 1 : gtk_widget_class_set_template_from_resource (widget_class, "/plugins/gnome/valent-preferences-dialog.ui");
569 : :
570 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, general_group);
571 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, main_page);
572 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, plugin_group);
573 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, plugin_list);
574 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, name_entry);
575 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, name_error);
576 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, name_error_label);
577 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, network_address_group);
578 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, network_address_list);
579 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, network_address_dialog);
580 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, network_address_add);
581 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, network_address_entry);
582 : 1 : gtk_widget_class_bind_template_callback (widget_class, on_name_apply);
583 : 1 : gtk_widget_class_bind_template_callback (widget_class, on_name_changed);
584 : 1 : gtk_widget_class_bind_template_callback (widget_class, on_network_address_activated);
585 : 1 : gtk_widget_class_bind_template_callback (widget_class, on_network_address_changed);
586 : :
587 : 1 : gtk_widget_class_install_action (widget_class, "network.add-address", "s", add_address_action);
588 : 1 : gtk_widget_class_install_action (widget_class, "network.remove-address", "s", remove_address_action);
589 : 1 : gtk_widget_class_install_action (widget_class, "win.page", "s", page_action);
590 : :
591 : : /* ... */
592 : 2 : extensions[EXTEN_APPLICATION_PLUGIN] =
593 : : (ExtensionDescription){
594 : 1 : VALENT_TYPE_APPLICATION_PLUGIN,
595 : : N_("Application"),
596 : : "application",
597 : : };
598 : :
599 : 2 : extensions[EXTEN_CHANNEL_SERVICE] =
600 : : (ExtensionDescription){
601 : 1 : VALENT_TYPE_CHANNEL_SERVICE,
602 : : N_("Device Connections"),
603 : : "network",
604 : : };
605 : :
606 : 2 : extensions[EXTEN_CLIPBOARD_ADAPTER] =
607 : : (ExtensionDescription){
608 : 1 : VALENT_TYPE_CLIPBOARD_ADAPTER,
609 : : N_("Clipboard"),
610 : : "clipboard",
611 : : };
612 : :
613 : 2 : extensions[EXTEN_CONTACTS_ADAPTER] =
614 : : (ExtensionDescription){
615 : 1 : VALENT_TYPE_CONTACTS_ADAPTER,
616 : : N_("Contacts"),
617 : : "contacts",
618 : : };
619 : :
620 : 2 : extensions[EXTEN_INPUT_ADAPTER] =
621 : : (ExtensionDescription){
622 : 1 : VALENT_TYPE_INPUT_ADAPTER,
623 : : N_("Mouse and Keyboard"),
624 : : "input",
625 : : };
626 : :
627 : 2 : extensions[EXTEN_MEDIA_ADAPTER] =
628 : : (ExtensionDescription){
629 : 1 : VALENT_TYPE_MEDIA_ADAPTER,
630 : : N_("Media Players"),
631 : : "media",
632 : : };
633 : :
634 : 2 : extensions[EXTEN_MIXER_ADAPTER] =
635 : : (ExtensionDescription){
636 : 1 : VALENT_TYPE_MIXER_ADAPTER,
637 : : N_("Volume Control"),
638 : : "mixer",
639 : : };
640 : :
641 : 2 : extensions[EXTEN_NOTIFICATION_ADAPTER] =
642 : : (ExtensionDescription){
643 : 1 : VALENT_TYPE_NOTIFICATIONS_ADAPTER,
644 : : N_("Notifications"),
645 : : "notifications",
646 : : };
647 : :
648 : 2 : extensions[EXTEN_SESSION_ADAPTER] =
649 : : (ExtensionDescription){
650 : 1 : VALENT_TYPE_SESSION_ADAPTER,
651 : : N_("Session Manager"),
652 : : "session",
653 : : };
654 : 1 : }
655 : :
656 : : static void
657 : 2 : valent_preferences_dialog_init (ValentPreferencesDialog *self)
658 : : {
659 : 2 : gtk_widget_init_template (GTK_WIDGET (self));
660 : :
661 : 2 : gtk_list_box_set_sort_func (self->plugin_list, plugin_list_sort, NULL, NULL);
662 : :
663 : 2 : self->pages = g_hash_table_new_full (NULL, NULL, NULL, g_object_unref);
664 : 2 : self->rows = g_hash_table_new_full (NULL, NULL, NULL, g_object_unref);
665 : 2 : }
666 : :
|