GCC Code Coverage Report


Directory: ./
File: panels/network/cc-qr-code-dialog.c
Date: 2024-05-04 07:58:27
Exec Total Coverage
Lines: 0 81 0.0%
Functions: 0 10 0.0%
Branches: 0 45 0.0%

Line Branch Exec Source
1 /*
2 * Copyright © 2018 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 as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * 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, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <glib/gi18n.h>
19 #include <config.h>
20 #include "cc-qr-code-dialog.h"
21 #include "cc-qr-code.h"
22
23 #define QR_IMAGE_SIZE 200
24
25 struct _CcQrCodeDialog
26 {
27 AdwDialog parent_instance;
28 NMConnection *connection;
29 GtkWidget *qr_image;
30 GtkWidget *qr_subtitle_ssid;
31 GtkWidget *qr_subtitle_password;
32 };
33
34 enum
35 {
36 PROP_0,
37 PROP_CONNECTION,
38 PROP_LAST
39 };
40
41 G_DEFINE_TYPE (CcQrCodeDialog, cc_qr_code_dialog, ADW_TYPE_DIALOG)
42
43 static GParamSpec *props[PROP_LAST];
44
45 static void
46 cc_qr_code_dialog_get_property (GObject *object,
47 guint prop_id,
48 GValue *value,
49 GParamSpec *pspec)
50 {
51 CcQrCodeDialog *self = CC_QR_CODE_DIALOG (object);
52
53 switch (prop_id)
54 {
55 case PROP_CONNECTION:
56 g_value_set_object (value, self->connection);
57 break;
58
59 default:
60 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
61 }
62 }
63
64 static void
65 cc_qr_code_dialog_set_property (GObject *object,
66 guint prop_id,
67 const GValue *value,
68 GParamSpec *pspec)
69 {
70 CcQrCodeDialog *self = CC_QR_CODE_DIALOG (object);
71
72 switch (prop_id)
73 {
74 case PROP_CONNECTION:
75 g_assert (self->connection == NULL);
76 self->connection = g_value_dup_object (value);
77 g_assert (self->connection != NULL);
78 break;
79
80 default:
81 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
82 }
83 }
84
85 static void
86 cc_qr_code_dialog_constructed (GObject *object)
87 {
88 g_autoptr (CcQrCode) qr_code = NULL;
89 g_autoptr (GVariant) variant = NULL;
90 g_autoptr (GError) error = NULL;
91 g_autofree gchar *qr_connection_string = NULL;
92 g_autofree gchar *subtitle_text = NULL;
93 g_autofree gchar *ssid_text = NULL;
94 g_autofree gchar *password_text = NULL;
95 g_autofree gchar *ssid_subtitle_text = NULL;
96 g_autofree gchar *password_subtitle_text = NULL;
97
98
99 NMSettingWireless *setting;
100 CcQrCodeDialog *self;
101 GBytes *ssid;
102
103 self = CC_QR_CODE_DIALOG (object);
104
105 G_OBJECT_CLASS (cc_qr_code_dialog_parent_class)->constructed (object);
106
107 variant = nm_remote_connection_get_secrets (NM_REMOTE_CONNECTION (self->connection),
108 NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
109 NULL,
110 &error);
111 if (variant)
112 {
113 if (!nm_connection_update_secrets (self->connection,
114 NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
115 variant,
116 &error))
117 {
118 g_warning ("Couldn't update secrets: %s", error->message);
119 return;
120 }
121 }
122 else
123 {
124 if (!g_error_matches (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND))
125 {
126 g_warning ("Couldn't get secrets: %s", error->message);
127 return;
128 }
129 }
130
131 setting = nm_connection_get_setting_wireless (self->connection);
132 ssid = nm_setting_wireless_get_ssid (setting);
133 ssid_text = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid));
134 password_text = get_wifi_password (self->connection);
135
136 /*
137 * translators: Subtitle underneath the Wi-Fi QR code is constructed with two labels.
138 * The first label holds Network Name, the second Wi-Fi password.
139 */
140 ssid_subtitle_text = g_markup_printf_escaped (_("<b>Network Name</b>: %s"), ssid_text);
141 gtk_label_set_markup (GTK_LABEL (self->qr_subtitle_ssid), ssid_subtitle_text);
142
143 if (password_text)
144 {
145 password_subtitle_text = g_markup_printf_escaped (_("<b>Password</b>: %s"), password_text);
146 gtk_label_set_markup (GTK_LABEL (self->qr_subtitle_password), password_subtitle_text);
147 }
148 else
149 gtk_widget_set_visible (self->qr_subtitle_password, FALSE);
150
151 qr_code = cc_qr_code_new ();
152 qr_connection_string = get_qr_string_for_connection (self->connection);
153 if (cc_qr_code_set_text (qr_code, qr_connection_string))
154 {
155 gint scale = gtk_widget_get_scale_factor (self->qr_image);
156 GdkPaintable *paintable = cc_qr_code_get_paintable (qr_code, QR_IMAGE_SIZE * scale);
157 gtk_picture_set_paintable (GTK_PICTURE (self->qr_image), paintable);
158 }
159 else
160 {
161 // TODO what should happen in this case?
162 }
163 }
164
165 static void
166 cc_qr_code_dialog_finalize (GObject *object)
167 {
168 CcQrCodeDialog *self = CC_QR_CODE_DIALOG (object);
169
170 g_clear_object (&self->connection);
171
172 G_OBJECT_CLASS (cc_qr_code_dialog_parent_class)->finalize (object);
173 }
174
175 void
176 cc_qr_code_dialog_class_init (CcQrCodeDialogClass *klass)
177 {
178 GObjectClass *object_class = G_OBJECT_CLASS (klass);
179 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
180
181 object_class->constructed = cc_qr_code_dialog_constructed;
182 object_class->get_property = cc_qr_code_dialog_get_property;
183 object_class->set_property = cc_qr_code_dialog_set_property;
184 object_class->finalize = cc_qr_code_dialog_finalize;
185
186 props[PROP_CONNECTION] = g_param_spec_object ("connection", "Connection",
187 "The NMConnection for which to show a QR code",
188 NM_TYPE_CONNECTION,
189 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
190
191 g_object_class_install_properties (object_class, PROP_LAST, props);
192
193 gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/network/cc-qr-code-dialog.ui");
194 gtk_widget_class_bind_template_child (widget_class, CcQrCodeDialog, qr_image);
195 gtk_widget_class_bind_template_child (widget_class, CcQrCodeDialog, qr_subtitle_ssid);
196 gtk_widget_class_bind_template_child (widget_class, CcQrCodeDialog, qr_subtitle_password);
197 }
198
199 void
200 cc_qr_code_dialog_init (CcQrCodeDialog *self)
201 {
202 gtk_widget_init_template (GTK_WIDGET (self));
203 }
204
205 GtkWidget *
206 cc_qr_code_dialog_new (NMConnection *connection)
207 {
208 return g_object_new (CC_TYPE_QR_CODE_DIALOG,
209 "connection", connection,
210 NULL);
211 }
212