Branch data Line data Source code
1 : : /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 : : *
3 : : * Copyright 2025 GNOME Foundation, Inc.
4 : : *
5 : : * SPDX-License-Identifier: GPL-2.0-or-later
6 : : *
7 : : * This program is free software; you can redistribute it and/or modify
8 : : * it under the terms of the GNU General Public License as published by
9 : : * the Free Software Foundation; either version 2 of the License, or
10 : : * (at your option) any later version.
11 : : *
12 : : * This program is distributed in the hope that it will be useful,
13 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : : * GNU General Public License for more details.
16 : : *
17 : : * You should have received a copy of the GNU General Public License
18 : : * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 : : *
20 : : * Authors:
21 : : * - Ignacy Kuchciński <ignacykuchcinski@gnome.org>
22 : : */
23 : :
24 : : #include "config.h"
25 : :
26 : : #include <glib/gi18n-lib.h>
27 : : #include <libmalcontent-ui/malcontent-ui.h>
28 : :
29 : : #include "access-page.h"
30 : :
31 : : /**
32 : : * MctAccessPage:
33 : : *
34 : : * A widget which shows parental controls access and restrictions
35 : : * for the selected user.
36 : : *
37 : : * [property@Malcontent.AccessPage:user] may be `NULL`, in which case the
38 : : * contents of the widget are undefined and it should not be shown.
39 : : *
40 : : * Since: 0.14.0
41 : : */
42 : : struct _MctAccessPage
43 : : {
44 : : AdwNavigationPage parent;
45 : :
46 : : AdwWindowTitle *access_window_title;
47 : : MctUserControls *user_controls;
48 : :
49 : : MctUser *user; /* (owned) (nullable) */
50 : : unsigned long user_notify_id;
51 : : };
52 : :
53 [ # # # # : 0 : G_DEFINE_TYPE (MctAccessPage, mct_access_page, ADW_TYPE_NAVIGATION_PAGE)
# # ]
54 : :
55 : : typedef enum
56 : : {
57 : : PROP_USER = 1,
58 : : } MctAccessPageProperty;
59 : :
60 : : static GParamSpec *properties[PROP_USER + 1];
61 : :
62 : : static void
63 : 0 : mct_access_page_get_property (GObject *object,
64 : : guint prop_id,
65 : : GValue *value,
66 : : GParamSpec *pspec)
67 : : {
68 : 0 : MctAccessPage *self = MCT_ACCESS_PAGE (object);
69 : :
70 [ # # ]: 0 : switch ((MctAccessPageProperty) prop_id)
71 : : {
72 : 0 : case PROP_USER:
73 : 0 : g_value_set_object (value, self->user);
74 : 0 : break;
75 : :
76 : 0 : default:
77 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
78 : : }
79 : 0 : }
80 : :
81 : : static void
82 : 0 : mct_access_page_set_property (GObject *object,
83 : : guint prop_id,
84 : : const GValue *value,
85 : : GParamSpec *pspec)
86 : : {
87 : 0 : MctAccessPage *self = MCT_ACCESS_PAGE (object);
88 : :
89 [ # # ]: 0 : switch ((MctAccessPageProperty) prop_id)
90 : : {
91 : 0 : case PROP_USER:
92 : 0 : mct_access_page_set_user (self, g_value_dup_object (value), NULL);
93 : 0 : break;
94 : :
95 : 0 : default:
96 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
97 : : }
98 : 0 : }
99 : :
100 : : static void
101 : 0 : mct_access_page_dispose (GObject *object)
102 : : {
103 : 0 : MctAccessPage *self = MCT_ACCESS_PAGE (object);
104 : :
105 [ # # ]: 0 : g_clear_signal_handler (&self->user_notify_id, self->user);
106 [ # # ]: 0 : g_clear_object (&self->user);
107 : :
108 : 0 : G_OBJECT_CLASS (mct_access_page_parent_class)->dispose (object);
109 : 0 : }
110 : :
111 : : static void
112 : 0 : mct_access_page_class_init (MctAccessPageClass *klass)
113 : : {
114 : 0 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
115 : 0 : GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
116 : :
117 : 0 : object_class->get_property = mct_access_page_get_property;
118 : 0 : object_class->set_property = mct_access_page_set_property;
119 : 0 : object_class->dispose = mct_access_page_dispose;
120 : :
121 : : /**
122 : : * MctAccessPage:user: (nullable)
123 : : *
124 : : * The currently selected user account.
125 : : *
126 : : * Since 0.14.0
127 : : */
128 : 0 : properties[PROP_USER] =
129 : 0 : g_param_spec_object ("user", NULL, NULL,
130 : : MCT_TYPE_USER,
131 : : G_PARAM_READWRITE |
132 : : G_PARAM_STATIC_STRINGS |
133 : : G_PARAM_EXPLICIT_NOTIFY);
134 : :
135 : 0 : g_object_class_install_properties (object_class, G_N_ELEMENTS (properties), properties);
136 : :
137 : 0 : gtk_widget_class_set_template_from_resource (widget_class, "/org/freedesktop/MalcontentControl/ui/access-page.ui");
138 : :
139 : 0 : gtk_widget_class_bind_template_child (widget_class, MctAccessPage, access_window_title);
140 : 0 : gtk_widget_class_bind_template_child (widget_class, MctAccessPage, user_controls);
141 : 0 : }
142 : :
143 : : static void
144 : 0 : mct_access_page_init (MctAccessPage *self)
145 : : {
146 : 0 : gtk_widget_init_template (GTK_WIDGET (self));
147 : 0 : }
148 : :
149 : : /**
150 : : * mct_access_page_new:
151 : : *
152 : : * Create a new [class@Malcontent.AccessPage] widget.
153 : : *
154 : : * Returns: (transfer full): a new access page
155 : : * Since: 0.14.0
156 : : */
157 : : MctAccessPage *
158 : 0 : mct_access_page_new (void)
159 : : {
160 : 0 : return g_object_new (MCT_TYPE_ACCESS_PAGE,
161 : : NULL);
162 : : }
163 : :
164 : : /**
165 : : * mct_access_page_get_user:
166 : : * @self: an access page
167 : : *
168 : : * Get the currently selected user.
169 : : *
170 : : * Returns: (transfer none) (nullable): the currently selected user
171 : : * Since: 0.14.0
172 : : */
173 : : MctUser *
174 : 0 : mct_access_page_get_user (MctAccessPage *self)
175 : : {
176 : 0 : g_return_val_if_fail (MCT_IS_ACCESS_PAGE (self), NULL);
177 : :
178 : 0 : return self->user;
179 : : }
180 : :
181 : : static void
182 : 0 : user_notify_cb (GObject *object,
183 : : GParamSpec *pspec,
184 : : void *user_data)
185 : : {
186 : 0 : MctUser *user = MCT_USER (object);
187 : 0 : MctAccessPage *self = MCT_ACCESS_PAGE (user_data);
188 : 0 : g_autofree gchar *help_label = NULL;
189 : :
190 : 0 : adw_window_title_set_subtitle (self->access_window_title,
191 : : mct_user_get_display_name (user));
192 : :
193 : : /* Translators: Replace the link to commonsensemedia.org with some
194 : : * localised guidance for parents/carers on how to set restrictions on
195 : : * their child/caree in a responsible way which is in keeping with the
196 : : * best practice and culture of the region. If no suitable localised
197 : : * guidance exists, and if the default commonsensemedia.org link is not
198 : : * suitable, please file an issue against malcontent so we can discuss
199 : : * further!
200 : : * https://gitlab.freedesktop.org/pwithnall/malcontent/-/issues/new
201 : : */
202 : 0 : help_label = g_strdup_printf (_("It’s recommended that restrictions are "
203 : : "set as part of an ongoing conversation "
204 : : "with %s. <a href='https://www.commonsensemedia.org/privacy-and-internet-safety'>"
205 : : "Read guidance</a> on what to consider."),
206 : : mct_user_get_display_name (user));
207 : :
208 : 0 : mct_user_controls_set_description (self->user_controls, help_label);
209 : 0 : }
210 : :
211 : : /**
212 : : * mct_access_page_set_user:
213 : : * @self: an access page
214 : : * @user: (nullable): a user
215 : : * @permission: (nullable) (transfer none): the [class@Gio.Permission]
216 : : * indicating whether the current user has permission to view or change
217 : : * parental controls, or `NULL` if permission is not allowed or is unknown
218 : : *
219 : : * Set the currently selected user.
220 : : *
221 : : * Since: 0.14.0
222 : : */
223 : : void
224 : 0 : mct_access_page_set_user (MctAccessPage *self,
225 : : MctUser *user,
226 : : GPermission *permission)
227 : : {
228 : 0 : g_return_if_fail (MCT_IS_ACCESS_PAGE (self));
229 : 0 : g_return_if_fail (user == NULL || MCT_IS_USER (user));
230 : 0 : g_return_if_fail (permission == NULL || G_IS_PERMISSION (permission));
231 : :
232 : 0 : g_autoptr(MctUser) old_user = NULL;
233 : :
234 [ # # ]: 0 : old_user = (self->user != NULL) ? g_object_ref (self->user) : NULL;
235 : :
236 [ # # ]: 0 : if (g_set_object (&self->user, user))
237 : : {
238 [ # # ]: 0 : if (old_user != NULL)
239 [ # # ]: 0 : g_clear_signal_handler (&self->user_notify_id, old_user);
240 : :
241 [ # # ]: 0 : if (user != NULL)
242 : : {
243 : 0 : self->user_notify_id = g_signal_connect (user,
244 : : "notify",
245 : : G_CALLBACK (user_notify_cb),
246 : : self);
247 : 0 : user_notify_cb (G_OBJECT (user), NULL, self);
248 : : }
249 : :
250 : 0 : mct_user_controls_set_permission (self->user_controls, permission);
251 : 0 : mct_user_controls_set_user (self->user_controls, user);
252 : :
253 : 0 : g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_USER]);
254 : : }
255 : : }
|