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 (unsigned int i = 0; i < N_EXTENSIONS; i++)
169 : : {
170 : 45 : ExtensionDescription extension = extensions[i];
171 : 45 : g_autoptr (ValentContext) domain = NULL;
172 [ + - ]: 45 : g_autoptr (ValentContext) context = NULL;
173 [ + - ]: 45 : g_autoptr (GSettings) settings = NULL;
174 : :
175 [ + + ]: 45 : if (!peas_engine_provides_extension (engine, info, extension.gtype))
176 : 14 : continue;
177 : :
178 : 31 : row = g_object_new (ADW_TYPE_SWITCH_ROW,
179 : 31 : "title", _(extension.title),
180 : : "selectable", FALSE,
181 : : NULL);
182 : 31 : adw_expander_row_add_row (ADW_EXPANDER_ROW (plugin_row), row);
183 : :
184 : 31 : domain = valent_context_new (NULL, extension.domain, NULL);
185 : 31 : context = valent_context_get_plugin_context (domain, info);
186 : 31 : settings = valent_context_create_settings (context,
187 : : "ca.andyholmes.Valent.Plugin");
188 : 31 : g_settings_bind (settings, "enabled",
189 : : row, "active",
190 : : G_SETTINGS_BIND_DEFAULT);
191 : 31 : adw_switch_row_set_active (ADW_SWITCH_ROW (row),
192 : : g_settings_get_boolean (settings, "enabled"));
193 [ + - ]: 31 : g_object_set_data_full (G_OBJECT (row),
194 : : "plugin-settings",
195 : : g_steal_pointer (&settings),
196 : : g_object_unref);
197 : : }
198 : 5 : }
199 : :
200 : : static void
201 : 27 : on_load_plugin (PeasEngine *engine,
202 : : PeasPluginInfo *info,
203 : : ValentPreferencesDialog *self)
204 : : {
205 : 27 : const char *title;
206 : 27 : const char *subtitle;
207 : 27 : const char *icon_name;
208 : :
209 [ + - ]: 27 : g_assert (PEAS_IS_ENGINE (engine));
210 [ - + ]: 27 : g_assert (info != NULL);
211 [ - + ]: 27 : g_assert (VALENT_IS_PREFERENCES_DIALOG (self));
212 : :
213 [ + + ]: 27 : if (peas_plugin_info_is_hidden (info))
214 : : return;
215 : :
216 : 25 : title = peas_plugin_info_get_name (info);
217 : 25 : subtitle = peas_plugin_info_get_description (info);
218 : 25 : icon_name = peas_plugin_info_get_icon_name (info);
219 : :
220 [ + + + - ]: 45 : if (peas_engine_provides_extension (engine, info, VALENT_TYPE_APPLICATION_PLUGIN) ||
221 [ + - ]: 40 : peas_engine_provides_extension (engine, info, VALENT_TYPE_CLIPBOARD_ADAPTER) ||
222 [ + - ]: 40 : peas_engine_provides_extension (engine, info, VALENT_TYPE_CHANNEL_SERVICE) ||
223 [ + - ]: 40 : peas_engine_provides_extension (engine, info, VALENT_TYPE_CONTACTS_ADAPTER) ||
224 [ + - ]: 40 : peas_engine_provides_extension (engine, info, VALENT_TYPE_INPUT_ADAPTER) ||
225 [ + - ]: 40 : peas_engine_provides_extension (engine, info, VALENT_TYPE_MEDIA_ADAPTER) ||
226 [ + - ]: 40 : peas_engine_provides_extension (engine, info, VALENT_TYPE_MIXER_ADAPTER) ||
227 [ - + ]: 40 : peas_engine_provides_extension (engine, info, VALENT_TYPE_NOTIFICATIONS_ADAPTER) ||
228 : 20 : peas_engine_provides_extension (engine, info, VALENT_TYPE_SESSION_ADAPTER))
229 : : {
230 : 5 : GtkWidget *row;
231 : 5 : GtkWidget *icon;
232 : :
233 : 5 : row = g_object_new (ADW_TYPE_EXPANDER_ROW,
234 : : "title", title,
235 : : "subtitle", subtitle,
236 : : "selectable", FALSE,
237 : : NULL);
238 : 5 : icon = g_object_new (GTK_TYPE_IMAGE,
239 : : "accessible-role", GTK_ACCESSIBLE_ROLE_PRESENTATION,
240 : : "icon-name", icon_name,
241 : : NULL);
242 : 5 : adw_expander_row_add_prefix (ADW_EXPANDER_ROW (row), icon);
243 : :
244 : 5 : plugin_row_add_extensions (ADW_EXPANDER_ROW (row), info);
245 : :
246 : 5 : gtk_list_box_insert (self->plugin_list, row, -1);
247 : 5 : g_hash_table_insert (self->rows, info, g_object_ref (row));
248 : : }
249 : : }
250 : :
251 : : static void
252 : 1 : on_unload_plugin (PeasEngine *engine,
253 : : PeasPluginInfo *info,
254 : : ValentPreferencesDialog *self)
255 : : {
256 : 2 : g_autoptr (AdwPreferencesPage) page = NULL;
257 [ - + ]: 1 : g_autoptr (GtkWidget) row = NULL;
258 : :
259 [ - + ]: 1 : if (g_hash_table_steal_extended (self->pages, info, NULL, (void **)&page))
260 : 0 : adw_preferences_dialog_remove (ADW_PREFERENCES_DIALOG (self), page);
261 : :
262 [ + - ]: 1 : if (g_hash_table_steal_extended (self->rows, info, NULL, (void **)&row))
263 : 1 : gtk_list_box_remove (self->plugin_list, row);
264 : 1 : }
265 : :
266 : : /*
267 : : * Manual Connections
268 : : */
269 : : static gboolean
270 : 0 : validate_host_entry (const char *input)
271 : : {
272 : 0 : g_autoptr (GSocketConnectable) net = NULL;
273 : :
274 [ # # # # ]: 0 : if (input == NULL || *input == '\0')
275 : : return FALSE;
276 : :
277 : 0 : net = g_network_address_parse (input, 1716, NULL);
278 [ # # ]: 0 : if (net == NULL)
279 : : return FALSE;
280 : :
281 : : return TRUE;
282 : : }
283 : :
284 : : static void
285 : 0 : on_network_address_activated (GtkWidget *widget,
286 : : ValentPreferencesDialog *self)
287 : : {
288 : 0 : const char *hostname = NULL;
289 : :
290 [ # # # # : 0 : g_assert (GTK_IS_EDITABLE (widget) || GTK_IS_BUTTON (widget));
# # # # #
# # # # #
# # ]
291 [ # # ]: 0 : g_assert (VALENT_IS_PREFERENCES_DIALOG (self));
292 : :
293 : 0 : hostname = gtk_editable_get_text (GTK_EDITABLE (self->network_address_entry));
294 [ # # ]: 0 : if (validate_host_entry (hostname))
295 : : {
296 : 0 : gtk_widget_activate_action (GTK_WIDGET (self),
297 : : "network.add-address",
298 : : "s", hostname);
299 : 0 : gtk_editable_set_text (GTK_EDITABLE (self->network_address_entry), "");
300 : 0 : gtk_widget_grab_focus (GTK_WIDGET (self->network_address_entry));
301 : 0 : adw_dialog_close (self->network_address_dialog);
302 : : }
303 : 0 : }
304 : :
305 : : static void
306 : 0 : on_network_address_changed (GtkEditable *editable,
307 : : GtkButton *button)
308 : : {
309 : 0 : const char *hostname = NULL;
310 : :
311 [ # # # # : 0 : g_assert (GTK_IS_EDITABLE (editable));
# # # # ]
312 [ # # # # : 0 : g_assert (GTK_IS_BUTTON (button));
# # # # ]
313 : :
314 : 0 : hostname = gtk_editable_get_text (editable);
315 [ # # ]: 0 : if (validate_host_entry (hostname))
316 : : {
317 : 0 : gtk_widget_set_sensitive (GTK_WIDGET (button), TRUE);
318 : 0 : gtk_widget_remove_css_class (GTK_WIDGET (editable), "warning");
319 : 0 : gtk_accessible_reset_state (GTK_ACCESSIBLE (editable),
320 : : GTK_ACCESSIBLE_STATE_INVALID);
321 : : }
322 [ # # # # ]: 0 : else if (hostname == NULL || *hostname == '\0')
323 : : {
324 : 0 : gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE);
325 : 0 : gtk_widget_remove_css_class (GTK_WIDGET (editable), "warning");
326 : 0 : gtk_accessible_reset_state (GTK_ACCESSIBLE (editable),
327 : : GTK_ACCESSIBLE_STATE_INVALID);
328 : : }
329 : : else
330 : : {
331 : 0 : gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE);
332 : 0 : gtk_widget_add_css_class (GTK_WIDGET (editable), "warning");
333 : 0 : gtk_accessible_update_state (GTK_ACCESSIBLE (editable),
334 : : GTK_ACCESSIBLE_STATE_INVALID,
335 : : GTK_ACCESSIBLE_INVALID_TRUE,
336 : : -1);
337 : : }
338 : 0 : }
339 : :
340 : : static GtkWidget *
341 : 0 : network_address_create_row (gpointer item,
342 : : gpointer user_data)
343 : : {
344 : 0 : GtkStringObject *string = GTK_STRING_OBJECT (item);
345 : 0 : GtkWidget *row, *button;
346 : 0 : const char *address;
347 : :
348 : 0 : address = gtk_string_object_get_string (string);
349 : 0 : row = g_object_new (ADW_TYPE_ACTION_ROW,
350 : : "title", gtk_string_object_get_string (string),
351 : : "use-markup", FALSE,
352 : : NULL);
353 : 0 : button = g_object_new (GTK_TYPE_BUTTON,
354 : : "icon-name", "edit-delete-symbolic",
355 : : "action-target", g_variant_new_string (address),
356 : : "action-name", "network.remove-address",
357 : 0 : "tooltip-text", _("Remove"),
358 : : "valign", GTK_ALIGN_CENTER,
359 : : NULL);
360 : 0 : gtk_widget_add_css_class (button, "flat");
361 : 0 : adw_action_row_add_suffix (ADW_ACTION_ROW (row), button);
362 : :
363 : 0 : return row;
364 : : }
365 : :
366 : : static void
367 : 2 : on_device_addresses_changed (GSettings *settings,
368 : : const char *key,
369 : : ValentPreferencesDialog *self)
370 : : {
371 : 4 : g_auto (GStrv) addresses = NULL;
372 [ + - ]: 2 : g_autoptr (GtkStringList) model = NULL;
373 : :
374 [ + - + - : 2 : g_assert (G_IS_SETTINGS (settings));
- + - - ]
375 [ + - - + ]: 2 : g_assert (key != NULL && *key != '\0');
376 [ - + ]: 2 : g_assert (VALENT_IS_PREFERENCES_DIALOG (self));
377 : :
378 : 2 : addresses = g_settings_get_strv (self->settings, "device-addresses");
379 : 2 : model = gtk_string_list_new ((const char * const *)addresses);
380 [ + - ]: 2 : gtk_list_box_bind_model (self->network_address_list,
381 : : G_LIST_MODEL (model),
382 : : network_address_create_row,
383 : : NULL, NULL);
384 : 2 : }
385 : :
386 : : /*
387 : : * GActions
388 : : */
389 : : static void
390 : 0 : add_address_action (GtkWidget *widget,
391 : : const char *action_name,
392 : : GVariant *parameter)
393 : : {
394 : 0 : ValentPreferencesDialog *self = VALENT_PREFERENCES_DIALOG (widget);
395 : 0 : g_auto (GStrv) addresses = NULL;
396 : 0 : const char *address = NULL;
397 : :
398 [ # # ]: 0 : g_assert (VALENT_IS_PREFERENCES_DIALOG (self));
399 : :
400 : 0 : address = g_variant_get_string (parameter, NULL);
401 : 0 : addresses = g_settings_get_strv (self->settings, "device-addresses");
402 [ # # ]: 0 : if (!g_strv_contains ((const char * const *)addresses, address))
403 : : {
404 [ # # ]: 0 : g_autoptr (GStrvBuilder) builder = NULL;
405 : :
406 : 0 : builder = g_strv_builder_new ();
407 : 0 : g_strv_builder_add (builder, address);
408 : 0 : g_strv_builder_addv (builder, (const char **)addresses);
409 : :
410 [ # # ]: 0 : g_clear_pointer (&addresses, g_strfreev);
411 : 0 : addresses = g_strv_builder_end (builder);
412 [ # # ]: 0 : g_settings_set_strv (self->settings, "device-addresses",
413 : : (const char * const *)addresses);
414 : : }
415 : 0 : }
416 : :
417 : : static void
418 : 0 : remove_address_action (GtkWidget *widget,
419 : : const char *action_name,
420 : : GVariant *parameter)
421 : : {
422 : 0 : ValentPreferencesDialog *self = VALENT_PREFERENCES_DIALOG (widget);
423 : 0 : g_auto (GStrv) addresses = NULL;
424 : 0 : const char *address = NULL;
425 : :
426 [ # # ]: 0 : g_assert (VALENT_IS_PREFERENCES_DIALOG (self));
427 : :
428 : 0 : address = g_variant_get_string (parameter, NULL);
429 : 0 : addresses = g_settings_get_strv (self->settings, "device-addresses");
430 [ # # ]: 0 : if (g_strv_contains ((const char * const *)addresses, address))
431 : : {
432 [ # # ]: 0 : g_autoptr (GStrvBuilder) builder = NULL;
433 : :
434 : 0 : builder = g_strv_builder_new ();
435 [ # # ]: 0 : for (size_t i = 0; addresses[i] != NULL; i++)
436 : : {
437 [ # # ]: 0 : if (!g_str_equal (addresses[i], address))
438 : 0 : g_strv_builder_add (builder, addresses[i]);
439 : : }
440 : :
441 [ # # ]: 0 : g_clear_pointer (&addresses, g_strfreev);
442 : 0 : addresses = g_strv_builder_end (builder);
443 [ # # ]: 0 : g_settings_set_strv (self->settings, "device-addresses",
444 : : (const char * const *)addresses);
445 : : }
446 : 0 : }
447 : :
448 : : static void
449 : 0 : page_action (GtkWidget *widget,
450 : : const char *action_name,
451 : : GVariant *parameter)
452 : : {
453 : 0 : AdwPreferencesDialog *window = ADW_PREFERENCES_DIALOG (widget);
454 : 0 : const char *module;
455 : :
456 : 0 : module = g_variant_get_string (parameter, NULL);
457 : 0 : adw_preferences_dialog_set_visible_page_name (window, module);
458 : 0 : }
459 : :
460 : : /*
461 : : * GObject
462 : : */
463 : : static void
464 : 2 : valent_preferences_dialog_constructed (GObject *object)
465 : : {
466 : 2 : ValentPreferencesDialog *self = VALENT_PREFERENCES_DIALOG (object);
467 : 4 : g_autofree char *error_label = NULL;
468 : 2 : g_autofree char *name = NULL;
469 : 2 : PeasEngine *engine = NULL;
470 : 2 : unsigned int n_plugins = 0;
471 : :
472 : 2 : G_OBJECT_CLASS (valent_preferences_dialog_parent_class)->constructed (object);
473 : :
474 : : /* Device Name
475 : : */
476 : 2 : self->settings = g_settings_new ("ca.andyholmes.Valent");
477 : 2 : g_signal_connect_object (self->settings,
478 : : "changed::name",
479 : : G_CALLBACK (on_settings_changed),
480 : : self, 0);
481 : 2 : name = g_settings_get_string (self->settings, "name");
482 : 2 : gtk_editable_set_text (GTK_EDITABLE (self->name_entry), name);
483 : :
484 : : // TRANSLATORS: %s is a list of forbidden characters
485 : 2 : error_label = g_strdup_printf (_("The device name must not contain "
486 : : "punctuation or brackets, including %s"),
487 : : "<b><tt>\"',;:.!?()[]<></tt></b>");
488 : 2 : gtk_label_set_markup (self->name_error_label, error_label);
489 : :
490 : : /* Manual Device Setup
491 : : */
492 : 2 : g_signal_connect_object (self->settings,
493 : : "changed::device-addresses",
494 : : G_CALLBACK (on_device_addresses_changed),
495 : : self,
496 : : G_CONNECT_DEFAULT);
497 : 2 : on_device_addresses_changed (self->settings, "device-addresses", self);
498 : :
499 : : /* Plugins
500 : : */
501 : 2 : engine = valent_get_plugin_engine ();
502 : 2 : g_signal_connect_object (engine,
503 : : "load-plugin",
504 : : G_CALLBACK (on_load_plugin),
505 : : self,
506 : : G_CONNECT_AFTER);
507 : 2 : g_signal_connect_object (engine,
508 : : "unload-plugin",
509 : : G_CALLBACK (on_unload_plugin),
510 : : self,
511 : : G_CONNECT_DEFAULT);
512 : :
513 : 2 : n_plugins = g_list_model_get_n_items (G_LIST_MODEL (engine));
514 [ + + ]: 28 : for (unsigned int i = 0; i < n_plugins; i++)
515 : : {
516 : 26 : g_autoptr (PeasPluginInfo) info = NULL;
517 : :
518 : 26 : info = g_list_model_get_item (G_LIST_MODEL (engine), i);
519 [ + - ]: 26 : if (peas_plugin_info_is_loaded (info))
520 : 26 : on_load_plugin (engine, info, self);
521 : : }
522 : 2 : }
523 : :
524 : : static void
525 : 2 : valent_preferences_dialog_dispose (GObject *object)
526 : : {
527 : 2 : ValentPreferencesDialog *self = VALENT_PREFERENCES_DIALOG (object);
528 : :
529 : 2 : g_signal_handlers_disconnect_by_data (valent_get_plugin_engine (), self);
530 [ + - ]: 2 : g_clear_object (&self->settings);
531 : :
532 : 2 : gtk_widget_dispose_template (GTK_WIDGET (object),
533 : : VALENT_TYPE_PREFERENCES_DIALOG);
534 : :
535 : 2 : G_OBJECT_CLASS (valent_preferences_dialog_parent_class)->dispose (object);
536 : 2 : }
537 : :
538 : : static void
539 : 2 : valent_preferences_dialog_finalize (GObject *object)
540 : : {
541 : 2 : ValentPreferencesDialog *self = VALENT_PREFERENCES_DIALOG (object);
542 : :
543 [ + - ]: 2 : g_clear_pointer (&self->pages, g_hash_table_unref);
544 [ + - ]: 2 : g_clear_pointer (&self->rows, g_hash_table_unref);
545 : :
546 : 2 : G_OBJECT_CLASS (valent_preferences_dialog_parent_class)->finalize (object);
547 : 2 : }
548 : :
549 : : static void
550 : 1 : valent_preferences_dialog_class_init (ValentPreferencesDialogClass *klass)
551 : : {
552 : 1 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
553 : 1 : GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
554 : :
555 : 1 : object_class->constructed = valent_preferences_dialog_constructed;
556 : 1 : object_class->dispose = valent_preferences_dialog_dispose;
557 : 1 : object_class->finalize = valent_preferences_dialog_finalize;
558 : :
559 : 1 : gtk_widget_class_set_template_from_resource (widget_class, "/plugins/gnome/valent-preferences-dialog.ui");
560 : :
561 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, general_group);
562 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, main_page);
563 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, plugin_group);
564 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, plugin_list);
565 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, name_entry);
566 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, name_error);
567 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, name_error_label);
568 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, network_address_group);
569 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, network_address_list);
570 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, network_address_dialog);
571 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, network_address_add);
572 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentPreferencesDialog, network_address_entry);
573 : 1 : gtk_widget_class_bind_template_callback (widget_class, on_name_apply);
574 : 1 : gtk_widget_class_bind_template_callback (widget_class, on_name_changed);
575 : 1 : gtk_widget_class_bind_template_callback (widget_class, on_network_address_activated);
576 : 1 : gtk_widget_class_bind_template_callback (widget_class, on_network_address_changed);
577 : :
578 : 1 : gtk_widget_class_install_action (widget_class, "network.add-address", "s", add_address_action);
579 : 1 : gtk_widget_class_install_action (widget_class, "network.remove-address", "s", remove_address_action);
580 : 1 : gtk_widget_class_install_action (widget_class, "win.page", "s", page_action);
581 : :
582 : : /* ... */
583 : 2 : extensions[EXTEN_APPLICATION_PLUGIN] =
584 : : (ExtensionDescription){
585 : 1 : VALENT_TYPE_APPLICATION_PLUGIN,
586 : : N_("Application"),
587 : : "application",
588 : : };
589 : :
590 : 2 : extensions[EXTEN_CHANNEL_SERVICE] =
591 : : (ExtensionDescription){
592 : 1 : VALENT_TYPE_CHANNEL_SERVICE,
593 : : N_("Device Connections"),
594 : : "network",
595 : : };
596 : :
597 : 2 : extensions[EXTEN_CLIPBOARD_ADAPTER] =
598 : : (ExtensionDescription){
599 : 1 : VALENT_TYPE_CLIPBOARD_ADAPTER,
600 : : N_("Clipboard"),
601 : : "clipboard",
602 : : };
603 : :
604 : 2 : extensions[EXTEN_CONTACTS_ADAPTER] =
605 : : (ExtensionDescription){
606 : 1 : VALENT_TYPE_CONTACTS_ADAPTER,
607 : : N_("Contacts"),
608 : : "contacts",
609 : : };
610 : :
611 : 2 : extensions[EXTEN_INPUT_ADAPTER] =
612 : : (ExtensionDescription){
613 : 1 : VALENT_TYPE_INPUT_ADAPTER,
614 : : N_("Mouse and Keyboard"),
615 : : "input",
616 : : };
617 : :
618 : 2 : extensions[EXTEN_MEDIA_ADAPTER] =
619 : : (ExtensionDescription){
620 : 1 : VALENT_TYPE_MEDIA_ADAPTER,
621 : : N_("Media Players"),
622 : : "media",
623 : : };
624 : :
625 : 2 : extensions[EXTEN_MIXER_ADAPTER] =
626 : : (ExtensionDescription){
627 : 1 : VALENT_TYPE_MIXER_ADAPTER,
628 : : N_("Volume Control"),
629 : : "mixer",
630 : : };
631 : :
632 : 2 : extensions[EXTEN_NOTIFICATION_ADAPTER] =
633 : : (ExtensionDescription){
634 : 1 : VALENT_TYPE_NOTIFICATIONS_ADAPTER,
635 : : N_("Notifications"),
636 : : "notifications",
637 : : };
638 : :
639 : 2 : extensions[EXTEN_SESSION_ADAPTER] =
640 : : (ExtensionDescription){
641 : 1 : VALENT_TYPE_SESSION_ADAPTER,
642 : : N_("Session Manager"),
643 : : "session",
644 : : };
645 : 1 : }
646 : :
647 : : static void
648 : 2 : valent_preferences_dialog_init (ValentPreferencesDialog *self)
649 : : {
650 : 2 : gtk_widget_init_template (GTK_WIDGET (self));
651 : :
652 : 2 : gtk_list_box_set_sort_func (self->plugin_list, plugin_list_sort, NULL, NULL);
653 : :
654 : 2 : self->pages = g_hash_table_new_full (NULL, NULL, NULL, g_object_unref);
655 : 2 : self->rows = g_hash_table_new_full (NULL, NULL, NULL, g_object_unref);
656 : 2 : }
657 : :
|