Line |
Branch |
Exec |
Source |
1 |
|
|
/* Copyright (C) 2018 Red Hat, Inc |
2 |
|
|
* |
3 |
|
|
* This program is free software; you can redistribute it and/or modify |
4 |
|
|
* it under the terms of the GNU General Public License as published by |
5 |
|
|
* the Free Software Foundation; either version 2 of the License, or |
6 |
|
|
* (at your option) any later version. |
7 |
|
|
* |
8 |
|
|
* This program is distributed in the hope that it will be useful, |
9 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 |
|
|
* GNU General Public License for more details. |
12 |
|
|
* |
13 |
|
|
* You should have received a copy of the GNU General Public License |
14 |
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>. |
15 |
|
|
* |
16 |
|
|
* Authors: Christian J. Kellner <ckellner@redhat.com> |
17 |
|
|
* |
18 |
|
|
*/ |
19 |
|
|
|
20 |
|
|
#include <config.h> |
21 |
|
|
|
22 |
|
|
#include <glib/gi18n.h> |
23 |
|
|
#include "cc-list-row.h" |
24 |
|
|
|
25 |
|
|
#include "bolt-device.h" |
26 |
|
|
#include "bolt-error.h" |
27 |
|
|
#include "bolt-time.h" |
28 |
|
|
|
29 |
|
|
#include "cc-bolt-device-dialog.h" |
30 |
|
|
#include "cc-bolt-device-entry.h" |
31 |
|
|
|
32 |
|
|
struct _CcBoltDeviceDialog |
33 |
|
|
{ |
34 |
|
|
AdwWindow parent; |
35 |
|
|
|
36 |
|
|
BoltClient *client; |
37 |
|
|
BoltDevice *device; |
38 |
|
|
GCancellable *cancel; |
39 |
|
|
|
40 |
|
|
AdwToastOverlay *toast_overlay; |
41 |
|
|
|
42 |
|
|
/* device details */ |
43 |
|
|
CcListRow *status_row; |
44 |
|
|
CcListRow *uuid_row; |
45 |
|
|
CcListRow *time_row; |
46 |
|
|
|
47 |
|
|
/* parents */ |
48 |
|
|
AdwPreferencesGroup *parents_group; |
49 |
|
|
GtkListBox *parents_devices; |
50 |
|
|
|
51 |
|
|
/* actions */ |
52 |
|
|
GtkWidget *button_box; |
53 |
|
|
GtkSpinner *spinner; |
54 |
|
|
GtkButton *connect_button; |
55 |
|
|
GtkButton *forget_button; |
56 |
|
|
}; |
57 |
|
|
|
58 |
|
|
static void on_forget_button_clicked_cb (CcBoltDeviceDialog *dialog); |
59 |
|
|
static void on_connect_button_clicked_cb (CcBoltDeviceDialog *dialog); |
60 |
|
|
|
61 |
|
✗ |
G_DEFINE_TYPE (CcBoltDeviceDialog, cc_bolt_device_dialog, ADW_TYPE_WINDOW); |
62 |
|
|
|
63 |
|
|
#define RESOURCE_UI "/org/gnome/control-center/privacy/bolt/cc-bolt-device-dialog.ui" |
64 |
|
|
|
65 |
|
|
static const char * |
66 |
|
✗ |
status_to_string_for_ui (BoltDevice *dev) |
67 |
|
|
{ |
68 |
|
|
BoltStatus status; |
69 |
|
|
BoltAuthFlags aflags; |
70 |
|
|
gboolean nopcie; |
71 |
|
|
|
72 |
|
✗ |
status = bolt_device_get_status (dev); |
73 |
|
✗ |
aflags = bolt_device_get_authflags(dev); |
74 |
|
✗ |
nopcie = bolt_flag_isset (aflags, BOLT_AUTH_NOPCIE); |
75 |
|
|
|
76 |
|
✗ |
switch (status) |
77 |
|
|
{ |
78 |
|
✗ |
case BOLT_STATUS_DISCONNECTED: |
79 |
|
✗ |
return C_("Thunderbolt Device Status", "Disconnected"); |
80 |
|
|
|
81 |
|
✗ |
case BOLT_STATUS_CONNECTING: |
82 |
|
✗ |
return C_("Thunderbolt Device Status", "Connecting"); |
83 |
|
|
|
84 |
|
✗ |
case BOLT_STATUS_CONNECTED: |
85 |
|
✗ |
return C_("Thunderbolt Device Status", "Connected"); |
86 |
|
|
|
87 |
|
✗ |
case BOLT_STATUS_AUTH_ERROR: |
88 |
|
✗ |
return C_("Thunderbolt Device Status", "Authorization Error"); |
89 |
|
|
|
90 |
|
✗ |
case BOLT_STATUS_AUTHORIZING: |
91 |
|
✗ |
return C_("Thunderbolt Device Status", "Authorizing"); |
92 |
|
|
|
93 |
|
✗ |
case BOLT_STATUS_AUTHORIZED: |
94 |
|
|
case BOLT_STATUS_AUTHORIZED_NEWKEY: |
95 |
|
|
case BOLT_STATUS_AUTHORIZED_SECURE: |
96 |
|
|
case BOLT_STATUS_AUTHORIZED_DPONLY: |
97 |
|
✗ |
if (nopcie) |
98 |
|
✗ |
return C_("Thunderbolt Device Status", "Reduced Functionality"); |
99 |
|
|
else |
100 |
|
✗ |
return C_("Thunderbolt Device Status", "Connected & Authorized"); |
101 |
|
|
|
102 |
|
✗ |
case BOLT_STATUS_UNKNOWN: |
103 |
|
✗ |
break; /* use default return value, i.e. Unknown */ |
104 |
|
|
} |
105 |
|
|
|
106 |
|
✗ |
return C_("Thunderbolt Device Status", "Unknown"); |
107 |
|
|
} |
108 |
|
|
|
109 |
|
|
static void |
110 |
|
✗ |
dialog_update_from_device (CcBoltDeviceDialog *dialog) |
111 |
|
|
{ |
112 |
|
✗ |
g_autofree char *generated = NULL; |
113 |
|
✗ |
g_autofree char *timestr = NULL; |
114 |
|
|
const char *label; |
115 |
|
|
const char *uuid; |
116 |
|
|
const char *status_brief; |
117 |
|
|
BoltStatus status; |
118 |
|
|
gboolean stored; |
119 |
|
|
BoltDevice *dev; |
120 |
|
|
guint timestamp; |
121 |
|
|
|
122 |
|
✗ |
if (gtk_widget_in_destruction (GTK_WIDGET (dialog))) |
123 |
|
✗ |
return; |
124 |
|
|
|
125 |
|
✗ |
dev = dialog->device; |
126 |
|
|
|
127 |
|
✗ |
uuid = bolt_device_get_uid (dev); |
128 |
|
✗ |
label = bolt_device_get_label (dev); |
129 |
|
|
|
130 |
|
✗ |
stored = bolt_device_is_stored (dev); |
131 |
|
✗ |
status = bolt_device_get_status (dev); |
132 |
|
|
|
133 |
|
✗ |
if (label == NULL) |
134 |
|
|
{ |
135 |
|
✗ |
const char *name = bolt_device_get_name (dev); |
136 |
|
✗ |
const char *vendor = bolt_device_get_vendor (dev); |
137 |
|
|
|
138 |
|
✗ |
generated = g_strdup_printf ("%s %s", name, vendor); |
139 |
|
✗ |
label = generated; |
140 |
|
|
} |
141 |
|
|
|
142 |
|
✗ |
gtk_window_set_title (GTK_WINDOW (dialog), label); |
143 |
|
|
|
144 |
|
✗ |
status_brief = status_to_string_for_ui (dev); |
145 |
|
✗ |
cc_list_row_set_secondary_label (dialog->status_row, status_brief); |
146 |
|
✗ |
gtk_widget_set_visible (GTK_WIDGET (dialog->forget_button), stored); |
147 |
|
|
|
148 |
|
|
/* while we are having an ongoing operation we are setting the buttons |
149 |
|
|
* to be in-sensitive. In that case, if the button was visible |
150 |
|
|
* before it will be hidden when the operation is finished by the |
151 |
|
|
* dialog_operation_done() function */ |
152 |
|
✗ |
if (gtk_widget_is_sensitive (GTK_WIDGET (dialog->connect_button))) |
153 |
|
✗ |
gtk_widget_set_visible (GTK_WIDGET (dialog->connect_button), |
154 |
|
|
status == BOLT_STATUS_CONNECTED); |
155 |
|
|
|
156 |
|
✗ |
cc_list_row_set_secondary_label (dialog->uuid_row, uuid); |
157 |
|
|
|
158 |
|
✗ |
if (bolt_status_is_authorized (status)) |
159 |
|
|
{ |
160 |
|
|
/* Translators: The time point the device was authorized. */ |
161 |
|
✗ |
adw_preferences_row_set_title (ADW_PREFERENCES_ROW (dialog->time_row), _("Authorized at")); |
162 |
|
✗ |
timestamp = bolt_device_get_authtime (dev); |
163 |
|
|
} |
164 |
|
✗ |
else if (bolt_status_is_connected (status)) |
165 |
|
|
{ |
166 |
|
|
/* Translators: The time point the device was connected. */ |
167 |
|
✗ |
adw_preferences_row_set_title (ADW_PREFERENCES_ROW (dialog->time_row), _("Connected at")); |
168 |
|
✗ |
timestamp = bolt_device_get_conntime (dev); |
169 |
|
|
} |
170 |
|
|
else |
171 |
|
|
{ |
172 |
|
|
/* Translators: The time point the device was enrolled, |
173 |
|
|
* i.e. authorized and stored in the device database. */ |
174 |
|
✗ |
adw_preferences_row_set_title (ADW_PREFERENCES_ROW (dialog->time_row), _("Enrolled at")); |
175 |
|
✗ |
timestamp = bolt_device_get_storetime (dev); |
176 |
|
|
} |
177 |
|
|
|
178 |
|
✗ |
timestr = bolt_epoch_format (timestamp, "%c"); |
179 |
|
✗ |
cc_list_row_set_secondary_label (dialog->time_row, timestr); |
180 |
|
|
|
181 |
|
|
} |
182 |
|
|
|
183 |
|
|
static void |
184 |
|
✗ |
on_device_notify_cb (GObject *gobject, |
185 |
|
|
GParamSpec *pspec, |
186 |
|
|
gpointer user_data) |
187 |
|
|
{ |
188 |
|
✗ |
CcBoltDeviceDialog *dialog = CC_BOLT_DEVICE_DIALOG (user_data); |
189 |
|
|
|
190 |
|
✗ |
dialog_update_from_device (dialog); |
191 |
|
✗ |
} |
192 |
|
|
|
193 |
|
|
static void |
194 |
|
✗ |
dialog_operation_start (CcBoltDeviceDialog *dialog) |
195 |
|
|
{ |
196 |
|
✗ |
gtk_widget_set_sensitive (GTK_WIDGET (dialog->connect_button), FALSE); |
197 |
|
✗ |
gtk_widget_set_sensitive (GTK_WIDGET (dialog->forget_button), FALSE); |
198 |
|
✗ |
gtk_spinner_start (dialog->spinner); |
199 |
|
✗ |
} |
200 |
|
|
|
201 |
|
|
static void |
202 |
|
✗ |
dialog_operation_done (CcBoltDeviceDialog *dialog, |
203 |
|
|
GtkWidget *sender, |
204 |
|
|
GError *error) |
205 |
|
|
{ |
206 |
|
✗ |
GtkWidget *cb = GTK_WIDGET (dialog->connect_button); |
207 |
|
✗ |
GtkWidget *fb = GTK_WIDGET (dialog->forget_button); |
208 |
|
|
|
209 |
|
|
/* don' do anything if we are being destroyed */ |
210 |
|
✗ |
if (gtk_widget_in_destruction (GTK_WIDGET (dialog))) |
211 |
|
✗ |
return; |
212 |
|
|
|
213 |
|
|
/* also don't do anything if the op was canceled */ |
214 |
|
✗ |
if (error != NULL && bolt_err_cancelled (error)) |
215 |
|
✗ |
return; |
216 |
|
|
|
217 |
|
✗ |
gtk_spinner_stop (dialog->spinner); |
218 |
|
|
|
219 |
|
✗ |
if (error != NULL) |
220 |
|
|
{ |
221 |
|
✗ |
AdwToast *toast = adw_toast_new (error->message); |
222 |
|
✗ |
adw_toast_overlay_add_toast (dialog->toast_overlay, toast); |
223 |
|
|
|
224 |
|
|
/* set the *other* button to sensitive */ |
225 |
|
✗ |
gtk_widget_set_sensitive (cb, cb != sender); |
226 |
|
✗ |
gtk_widget_set_sensitive (fb, fb != sender); |
227 |
|
|
} |
228 |
|
|
else |
229 |
|
|
{ |
230 |
|
✗ |
gtk_widget_set_visible (sender, FALSE); |
231 |
|
✗ |
gtk_widget_set_sensitive (cb, TRUE); |
232 |
|
✗ |
gtk_widget_set_sensitive (fb, TRUE); |
233 |
|
|
} |
234 |
|
|
} |
235 |
|
|
|
236 |
|
|
static void |
237 |
|
✗ |
on_connect_all_done (GObject *source_object, |
238 |
|
|
GAsyncResult *res, |
239 |
|
|
gpointer user_data) |
240 |
|
|
{ |
241 |
|
✗ |
g_autoptr(GError) err = NULL; |
242 |
|
✗ |
CcBoltDeviceDialog *dialog = CC_BOLT_DEVICE_DIALOG (user_data); |
243 |
|
|
gboolean ok; |
244 |
|
|
|
245 |
|
✗ |
ok = bolt_client_connect_all_finish (dialog->client, res, &err); |
246 |
|
|
|
247 |
|
✗ |
if (!ok) |
248 |
|
✗ |
g_prefix_error (&err, _("Failed to authorize device: ")); |
249 |
|
|
|
250 |
|
✗ |
dialog_operation_done (dialog, GTK_WIDGET (dialog->connect_button), err); |
251 |
|
✗ |
} |
252 |
|
|
|
253 |
|
|
static void |
254 |
|
✗ |
on_connect_button_clicked_cb (CcBoltDeviceDialog *dialog) |
255 |
|
|
{ |
256 |
|
✗ |
g_autoptr(GPtrArray) devices = NULL; |
257 |
|
✗ |
BoltDevice *device = dialog->device; |
258 |
|
|
GtkWidget *child; |
259 |
|
|
|
260 |
|
✗ |
g_return_if_fail (device != NULL); |
261 |
|
|
|
262 |
|
✗ |
dialog_operation_start (dialog); |
263 |
|
|
|
264 |
|
✗ |
devices = g_ptr_array_new (); |
265 |
|
|
|
266 |
|
|
/* Iter from the last child to the first one */ |
267 |
|
✗ |
for (child = gtk_widget_get_last_child (GTK_WIDGET (dialog->parents_devices)); |
268 |
|
✗ |
child; |
269 |
|
✗ |
child = gtk_widget_get_prev_sibling (child)) |
270 |
|
|
{ |
271 |
|
|
CcBoltDeviceEntry *entry; |
272 |
|
|
BoltDevice *dev; |
273 |
|
|
BoltStatus status; |
274 |
|
|
|
275 |
|
✗ |
entry = CC_BOLT_DEVICE_ENTRY (child); |
276 |
|
✗ |
dev = cc_bolt_device_entry_get_device (entry); |
277 |
|
✗ |
status = bolt_device_get_status (dev); |
278 |
|
|
|
279 |
|
|
/* skip any devices down in the chain that are already authorized |
280 |
|
|
* NB: it is not possible to have gaps of non-authorized devices |
281 |
|
|
* in the chain, i.e. once we encounter a non-authorized device, |
282 |
|
|
* all following device (down the chain, towards the target) will |
283 |
|
|
* also be not authorized. */ |
284 |
|
✗ |
if (!bolt_status_is_pending (status)) |
285 |
|
✗ |
continue; |
286 |
|
|
|
287 |
|
|
/* device is now either !stored || pending */ |
288 |
|
✗ |
g_ptr_array_add (devices, dev); |
289 |
|
|
} |
290 |
|
|
|
291 |
|
|
/* finally the actual device of the dialog */ |
292 |
|
✗ |
g_ptr_array_add (devices, device); |
293 |
|
|
|
294 |
|
✗ |
bolt_client_connect_all_async (dialog->client, |
295 |
|
|
devices, |
296 |
|
|
BOLT_POLICY_DEFAULT, |
297 |
|
|
BOLT_AUTHCTRL_NONE, |
298 |
|
|
dialog->cancel, |
299 |
|
|
on_connect_all_done, |
300 |
|
|
dialog); |
301 |
|
|
} |
302 |
|
|
|
303 |
|
|
static void |
304 |
|
✗ |
on_forget_device_done (GObject *source_object, |
305 |
|
|
GAsyncResult *res, |
306 |
|
|
gpointer user_data) |
307 |
|
|
{ |
308 |
|
✗ |
g_autoptr(GError) err = NULL; |
309 |
|
✗ |
CcBoltDeviceDialog *dialog = CC_BOLT_DEVICE_DIALOG (user_data); |
310 |
|
|
gboolean ok; |
311 |
|
|
|
312 |
|
✗ |
ok = bolt_client_forget_device_finish (dialog->client, res, &err); |
313 |
|
|
|
314 |
|
✗ |
if (!ok) |
315 |
|
✗ |
g_prefix_error (&err, _("Failed to forget device: ")); |
316 |
|
|
|
317 |
|
✗ |
dialog_operation_done (dialog, GTK_WIDGET (dialog->forget_button), err); |
318 |
|
✗ |
} |
319 |
|
|
|
320 |
|
|
static void |
321 |
|
✗ |
on_forget_button_clicked_cb (CcBoltDeviceDialog *dialog) |
322 |
|
|
{ |
323 |
|
✗ |
const char *uid = NULL; |
324 |
|
|
|
325 |
|
✗ |
g_return_if_fail (dialog->device != NULL); |
326 |
|
|
|
327 |
|
✗ |
uid = bolt_device_get_uid (dialog->device); |
328 |
|
✗ |
dialog_operation_start (dialog); |
329 |
|
|
|
330 |
|
✗ |
bolt_client_forget_device_async (dialog->client, |
331 |
|
|
uid, |
332 |
|
|
dialog->cancel, |
333 |
|
|
on_forget_device_done, |
334 |
|
|
dialog); |
335 |
|
|
} |
336 |
|
|
|
337 |
|
|
static void |
338 |
|
✗ |
cc_bolt_device_dialog_finalize (GObject *object) |
339 |
|
|
{ |
340 |
|
✗ |
CcBoltDeviceDialog *dialog = CC_BOLT_DEVICE_DIALOG (object); |
341 |
|
|
|
342 |
|
✗ |
g_clear_object (&dialog->device); |
343 |
|
✗ |
g_cancellable_cancel (dialog->cancel); |
344 |
|
✗ |
g_clear_object (&dialog->cancel); |
345 |
|
✗ |
g_clear_object (&dialog->client); |
346 |
|
|
|
347 |
|
✗ |
G_OBJECT_CLASS (cc_bolt_device_dialog_parent_class)->finalize (object); |
348 |
|
✗ |
} |
349 |
|
|
|
350 |
|
|
static void |
351 |
|
✗ |
cc_bolt_device_dialog_class_init (CcBoltDeviceDialogClass *klass) |
352 |
|
|
{ |
353 |
|
✗ |
GObjectClass *object_class = G_OBJECT_CLASS (klass); |
354 |
|
✗ |
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); |
355 |
|
|
|
356 |
|
✗ |
object_class->finalize = cc_bolt_device_dialog_finalize; |
357 |
|
|
|
358 |
|
✗ |
gtk_widget_class_set_template_from_resource (widget_class, RESOURCE_UI); |
359 |
|
|
|
360 |
|
✗ |
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, toast_overlay); |
361 |
|
|
|
362 |
|
✗ |
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, status_row); |
363 |
|
|
|
364 |
|
✗ |
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, uuid_row); |
365 |
|
✗ |
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, time_row); |
366 |
|
|
|
367 |
|
✗ |
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, parents_devices); |
368 |
|
✗ |
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, parents_group); |
369 |
|
|
|
370 |
|
✗ |
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, button_box); |
371 |
|
✗ |
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, spinner); |
372 |
|
✗ |
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, connect_button); |
373 |
|
✗ |
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, forget_button); |
374 |
|
|
|
375 |
|
✗ |
gtk_widget_class_bind_template_callback (widget_class, on_connect_button_clicked_cb); |
376 |
|
✗ |
gtk_widget_class_bind_template_callback (widget_class, on_forget_button_clicked_cb); |
377 |
|
✗ |
} |
378 |
|
|
|
379 |
|
|
static void |
380 |
|
✗ |
cc_bolt_device_dialog_init (CcBoltDeviceDialog *dialog) |
381 |
|
|
{ |
382 |
|
✗ |
gtk_widget_init_template (GTK_WIDGET (dialog)); |
383 |
|
✗ |
} |
384 |
|
|
|
385 |
|
|
/* public functions */ |
386 |
|
|
CcBoltDeviceDialog * |
387 |
|
✗ |
cc_bolt_device_dialog_new (void) |
388 |
|
|
{ |
389 |
|
|
CcBoltDeviceDialog *dialog; |
390 |
|
|
|
391 |
|
✗ |
dialog = g_object_new (CC_TYPE_BOLT_DEVICE_DIALOG, |
392 |
|
|
NULL); |
393 |
|
✗ |
return dialog; |
394 |
|
|
} |
395 |
|
|
|
396 |
|
|
void |
397 |
|
✗ |
cc_bolt_device_dialog_set_client (CcBoltDeviceDialog *dialog, |
398 |
|
|
BoltClient *client) |
399 |
|
|
{ |
400 |
|
✗ |
g_clear_object (&dialog->client); |
401 |
|
✗ |
dialog->client = g_object_ref (client); |
402 |
|
✗ |
} |
403 |
|
|
|
404 |
|
|
void |
405 |
|
✗ |
cc_bolt_device_dialog_set_device (CcBoltDeviceDialog *dialog, |
406 |
|
|
BoltDevice *device, |
407 |
|
|
GPtrArray *parents) |
408 |
|
|
{ |
409 |
|
✗ |
g_autofree char *msg = NULL; |
410 |
|
|
guint i; |
411 |
|
|
|
412 |
|
✗ |
if (device == dialog->device) |
413 |
|
✗ |
return; |
414 |
|
|
|
415 |
|
✗ |
if (dialog->device) |
416 |
|
|
{ |
417 |
|
|
GtkWidget *child; |
418 |
|
|
|
419 |
|
✗ |
g_cancellable_cancel (dialog->cancel); |
420 |
|
✗ |
g_clear_object (&dialog->cancel); |
421 |
|
✗ |
dialog->cancel = g_cancellable_new (); |
422 |
|
|
|
423 |
|
✗ |
g_signal_handlers_disconnect_by_func (dialog->device, |
424 |
|
|
G_CALLBACK (on_device_notify_cb), |
425 |
|
|
dialog); |
426 |
|
✗ |
g_clear_object (&dialog->device); |
427 |
|
|
|
428 |
|
✗ |
while ((child = gtk_widget_get_first_child (GTK_WIDGET (dialog->parents_devices))) != NULL) |
429 |
|
✗ |
gtk_list_box_remove (dialog->parents_devices, child); |
430 |
|
|
|
431 |
|
✗ |
gtk_widget_set_visible (GTK_WIDGET (dialog->parents_group), FALSE); |
432 |
|
|
} |
433 |
|
|
|
434 |
|
✗ |
if (device == NULL) |
435 |
|
✗ |
return; |
436 |
|
|
|
437 |
|
✗ |
dialog->device = g_object_ref (device); |
438 |
|
✗ |
g_signal_connect_object (dialog->device, |
439 |
|
|
"notify", |
440 |
|
|
G_CALLBACK (on_device_notify_cb), |
441 |
|
|
dialog, |
442 |
|
|
0); |
443 |
|
|
|
444 |
|
|
/* reset the sensitivity of the buttons, because |
445 |
|
|
* dialog_update_from_device, because it can't know */ |
446 |
|
✗ |
gtk_widget_set_sensitive (GTK_WIDGET (dialog->connect_button), TRUE); |
447 |
|
✗ |
gtk_widget_set_sensitive (GTK_WIDGET (dialog->forget_button), TRUE); |
448 |
|
|
|
449 |
|
✗ |
dialog_update_from_device (dialog); |
450 |
|
|
|
451 |
|
|
/* no parents, we are done here */ |
452 |
|
✗ |
if (!parents || parents->len == 0) |
453 |
|
✗ |
return; |
454 |
|
|
|
455 |
|
✗ |
msg = g_strdup_printf (ngettext ("Depends on %u other device", |
456 |
|
|
"Depends on %u other devices", |
457 |
|
✗ |
parents->len), parents->len); |
458 |
|
|
|
459 |
|
✗ |
adw_preferences_group_set_title (dialog->parents_group, msg); |
460 |
|
✗ |
gtk_widget_set_visible (GTK_WIDGET (dialog->parents_group), TRUE); |
461 |
|
|
|
462 |
|
✗ |
for (i = 0; i < parents->len; i++) |
463 |
|
|
{ |
464 |
|
|
CcBoltDeviceEntry *entry; |
465 |
|
|
BoltDevice *parent; |
466 |
|
|
|
467 |
|
✗ |
parent = g_ptr_array_index (parents, i); |
468 |
|
|
|
469 |
|
✗ |
entry = cc_bolt_device_entry_new (parent, TRUE); |
470 |
|
✗ |
gtk_list_box_append (dialog->parents_devices, GTK_WIDGET (entry)); |
471 |
|
|
} |
472 |
|
|
} |
473 |
|
|
|
474 |
|
|
BoltDevice * |
475 |
|
✗ |
cc_bolt_device_dialog_peek_device (CcBoltDeviceDialog *dialog) |
476 |
|
|
{ |
477 |
|
✗ |
return dialog->device; |
478 |
|
|
} |
479 |
|
|
|
480 |
|
|
gboolean |
481 |
|
✗ |
cc_bolt_device_dialog_device_equal (CcBoltDeviceDialog *dialog, |
482 |
|
|
BoltDevice *device) |
483 |
|
|
{ |
484 |
|
✗ |
return dialog->device != NULL && device == dialog->device; |
485 |
|
|
} |
486 |
|
|
|