2018-03-26 16:18:30 +02:00
|
|
|
/* Copyright (C) 2018 Red Hat, Inc
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* Authors: Christian J. Kellner <ckellner@redhat.com>
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2019-02-01 17:55:57 +01:00
|
|
|
#include <list-box-helper.h>
|
|
|
|
|
2018-03-26 16:18:30 +02:00
|
|
|
#include <glib/gi18n.h>
|
|
|
|
|
|
|
|
#include "bolt-device.h"
|
|
|
|
#include "bolt-error.h"
|
|
|
|
#include "bolt-time.h"
|
|
|
|
|
|
|
|
#include "cc-thunderbolt-resources.h"
|
|
|
|
|
|
|
|
#include "cc-bolt-device-dialog.h"
|
2019-02-01 17:55:57 +01:00
|
|
|
#include "cc-bolt-device-entry.h"
|
2018-03-26 16:18:30 +02:00
|
|
|
|
|
|
|
struct _CcBoltDeviceDialog
|
|
|
|
{
|
|
|
|
GtkDialog parent;
|
|
|
|
|
|
|
|
BoltClient *client;
|
|
|
|
BoltDevice *device;
|
|
|
|
GCancellable *cancel;
|
|
|
|
|
|
|
|
/* main ui */
|
|
|
|
GtkHeaderBar *header_bar;
|
|
|
|
|
|
|
|
/* notifications */
|
|
|
|
GtkLabel *notify_label;
|
|
|
|
GtkRevealer *notify_revealer;
|
|
|
|
|
|
|
|
/* device details */
|
|
|
|
GtkLabel *name_label;
|
|
|
|
GtkLabel *status_label;
|
|
|
|
GtkLabel *uuid_label;
|
|
|
|
|
|
|
|
GtkLabel *time_title;
|
|
|
|
GtkLabel *time_label;
|
|
|
|
|
2019-02-01 17:55:57 +01:00
|
|
|
/* parents */
|
|
|
|
GtkExpander *parents_expander;
|
|
|
|
GtkLabel *parents_label;
|
|
|
|
GtkListBox *parents_devices;
|
|
|
|
|
2018-03-26 16:18:30 +02:00
|
|
|
/* actions */
|
|
|
|
GtkWidget *button_box;
|
|
|
|
GtkSpinner *spinner;
|
|
|
|
GtkButton *connect_button;
|
|
|
|
GtkButton *forget_button;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void on_notify_button_clicked_cb (GtkButton *button,
|
|
|
|
CcBoltDeviceDialog *panel);
|
|
|
|
|
|
|
|
static void on_forget_button_clicked_cb (CcBoltDeviceDialog *dialog);
|
|
|
|
static void on_connect_button_clicked_cb (CcBoltDeviceDialog *dialog);
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (CcBoltDeviceDialog, cc_bolt_device_dialog, GTK_TYPE_DIALOG);
|
|
|
|
|
|
|
|
#define RESOURCE_UI "/org/gnome/control-center/thunderbolt/cc-bolt-device-dialog.ui"
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
status_to_string_for_ui (BoltDevice *dev)
|
|
|
|
{
|
|
|
|
BoltStatus status;
|
|
|
|
BoltAuthFlags aflags;
|
|
|
|
gboolean nopcie;
|
|
|
|
|
|
|
|
status = bolt_device_get_status (dev);
|
|
|
|
aflags = bolt_device_get_authflags(dev);
|
|
|
|
nopcie = bolt_flag_isset (aflags, BOLT_AUTH_NOPCIE);
|
|
|
|
|
|
|
|
switch (status)
|
|
|
|
{
|
|
|
|
case BOLT_STATUS_DISCONNECTED:
|
|
|
|
return C_("Thunderbolt Device Status", "Disconnected");
|
|
|
|
|
|
|
|
case BOLT_STATUS_CONNECTING:
|
|
|
|
return C_("Thunderbolt Device Status", "Connecting");
|
|
|
|
|
|
|
|
case BOLT_STATUS_CONNECTED:
|
|
|
|
return C_("Thunderbolt Device Status", "Connected");
|
|
|
|
|
|
|
|
case BOLT_STATUS_AUTH_ERROR:
|
|
|
|
return C_("Thunderbolt Device Status", "Authorization Error");
|
|
|
|
|
|
|
|
case BOLT_STATUS_AUTHORIZING:
|
|
|
|
return C_("Thunderbolt Device Status", "Authorizing");
|
|
|
|
|
|
|
|
case BOLT_STATUS_AUTHORIZED:
|
|
|
|
case BOLT_STATUS_AUTHORIZED_NEWKEY:
|
|
|
|
case BOLT_STATUS_AUTHORIZED_SECURE:
|
|
|
|
case BOLT_STATUS_AUTHORIZED_DPONLY:
|
|
|
|
if (nopcie)
|
|
|
|
return C_("Thunderbolt Device Status", "Reduced Functionality");
|
|
|
|
else
|
|
|
|
return C_("Thunderbolt Device Status", "Connected & Authorized");
|
|
|
|
|
|
|
|
case BOLT_STATUS_UNKNOWN:
|
|
|
|
break; /* use default return value, i.e. Unknown */
|
|
|
|
}
|
|
|
|
|
|
|
|
return C_("Thunderbolt Device Status", "Unknown");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dialog_update_from_device (CcBoltDeviceDialog *dialog)
|
|
|
|
{
|
|
|
|
g_autofree char *generated = NULL;
|
|
|
|
g_autofree char *timestr = NULL;
|
|
|
|
const char *label;
|
|
|
|
const char *uuid;
|
|
|
|
const char *status_brief;
|
|
|
|
BoltStatus status;
|
|
|
|
gboolean stored;
|
|
|
|
BoltDevice *dev;
|
|
|
|
guint timestamp;
|
|
|
|
|
|
|
|
if (gtk_widget_in_destruction (GTK_WIDGET (dialog)))
|
|
|
|
return;
|
|
|
|
|
|
|
|
dev = dialog->device;
|
|
|
|
|
|
|
|
uuid = bolt_device_get_uid (dev);
|
|
|
|
label = bolt_device_get_label (dev);
|
|
|
|
|
|
|
|
stored = bolt_device_is_stored (dev);
|
|
|
|
status = bolt_device_get_status (dev);
|
|
|
|
|
|
|
|
if (label == NULL)
|
|
|
|
{
|
|
|
|
const char *name = bolt_device_get_name (dev);
|
|
|
|
const char *vendor = bolt_device_get_vendor (dev);
|
|
|
|
|
|
|
|
generated = g_strdup_printf ("%s %s", name, vendor);
|
|
|
|
label = generated;
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_label_set_label (dialog->name_label, label);
|
|
|
|
gtk_header_bar_set_title (dialog->header_bar, label);
|
|
|
|
|
|
|
|
status_brief = status_to_string_for_ui (dev);
|
|
|
|
gtk_label_set_label (dialog->status_label, status_brief);
|
|
|
|
gtk_widget_set_visible (GTK_WIDGET (dialog->forget_button), stored);
|
|
|
|
|
|
|
|
/* while we are having an ongoing operation we are setting the buttons
|
|
|
|
* to be in-sensitive. In that case, if the button was visible
|
|
|
|
* before it will be hidden when the operation is finished by the
|
|
|
|
* dialog_operation_done() function */
|
|
|
|
if (gtk_widget_is_sensitive (GTK_WIDGET (dialog->connect_button)))
|
|
|
|
gtk_widget_set_visible (GTK_WIDGET (dialog->connect_button),
|
|
|
|
status == BOLT_STATUS_CONNECTED);
|
|
|
|
|
|
|
|
gtk_label_set_label (dialog->uuid_label, uuid);
|
|
|
|
|
|
|
|
if (bolt_status_is_authorized (status))
|
|
|
|
{
|
|
|
|
/* Translators: The time point the device was authorized. */
|
|
|
|
gtk_label_set_label (dialog->time_title, _("Authorized at:"));
|
|
|
|
timestamp = bolt_device_get_authtime (dev);
|
|
|
|
}
|
|
|
|
else if (bolt_status_is_connected (status))
|
|
|
|
{
|
|
|
|
/* Translators: The time point the device was connected. */
|
|
|
|
gtk_label_set_label (dialog->time_title, _("Connected at:"));
|
|
|
|
timestamp = bolt_device_get_conntime (dev);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Translators: The time point the device was enrolled,
|
|
|
|
* i.e. authorized and stored in the device database. */
|
|
|
|
gtk_label_set_label (dialog->time_title, _("Enrolled at:"));
|
|
|
|
timestamp = bolt_device_get_storetime (dev);
|
|
|
|
}
|
|
|
|
|
|
|
|
timestr = bolt_epoch_format (timestamp, "%c");
|
|
|
|
gtk_label_set_label (dialog->time_label, timestr);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_device_notify_cb (GObject *gobject,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
CcBoltDeviceDialog *dialog = CC_BOLT_DEVICE_DIALOG (user_data);
|
|
|
|
|
|
|
|
dialog_update_from_device (dialog);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dialog_operation_start (CcBoltDeviceDialog *dialog)
|
|
|
|
{
|
|
|
|
gtk_widget_set_sensitive (GTK_WIDGET (dialog->connect_button), FALSE);
|
|
|
|
gtk_widget_set_sensitive (GTK_WIDGET (dialog->forget_button), FALSE);
|
|
|
|
gtk_spinner_start (dialog->spinner);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dialog_operation_done (CcBoltDeviceDialog *dialog,
|
|
|
|
GtkWidget *sender,
|
|
|
|
GError *error)
|
|
|
|
{
|
|
|
|
GtkWidget *cb = GTK_WIDGET (dialog->connect_button);
|
|
|
|
GtkWidget *fb = GTK_WIDGET (dialog->forget_button);
|
|
|
|
|
|
|
|
/* don' do anything if we are being destroyed */
|
|
|
|
if (gtk_widget_in_destruction (GTK_WIDGET (dialog)))
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* also don't do anything if the op was canceled */
|
|
|
|
if (error != NULL && bolt_err_cancelled (error))
|
|
|
|
return;
|
|
|
|
|
|
|
|
gtk_spinner_stop (dialog->spinner);
|
|
|
|
|
|
|
|
if (error != NULL)
|
|
|
|
{
|
|
|
|
gtk_label_set_label (dialog->notify_label, error->message);
|
|
|
|
gtk_revealer_set_reveal_child (dialog->notify_revealer, TRUE);
|
|
|
|
|
|
|
|
/* set the *other* button to sensitive */
|
|
|
|
gtk_widget_set_sensitive (cb, cb != sender);
|
|
|
|
gtk_widget_set_sensitive (fb, fb != sender);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gtk_widget_set_visible (sender, FALSE);
|
|
|
|
gtk_widget_set_sensitive (cb, TRUE);
|
|
|
|
gtk_widget_set_sensitive (fb, TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-02-01 17:55:57 +01:00
|
|
|
on_connect_all_done (GObject *source_object,
|
|
|
|
GAsyncResult *res,
|
|
|
|
gpointer user_data)
|
2018-03-26 16:18:30 +02:00
|
|
|
{
|
|
|
|
g_autoptr(GError) err = NULL;
|
|
|
|
CcBoltDeviceDialog *dialog = CC_BOLT_DEVICE_DIALOG (user_data);
|
|
|
|
gboolean ok;
|
|
|
|
|
2019-02-01 17:55:57 +01:00
|
|
|
ok = bolt_client_connect_all_finish (dialog->client, res, &err);
|
2018-03-26 16:18:30 +02:00
|
|
|
|
2019-02-01 17:55:57 +01:00
|
|
|
if (!ok)
|
|
|
|
g_prefix_error (&err, _("Failed to authorize device: "));
|
2018-03-26 16:18:30 +02:00
|
|
|
|
2019-02-01 17:55:57 +01:00
|
|
|
dialog_operation_done (dialog, GTK_WIDGET (dialog->connect_button), err);
|
2018-03-26 16:18:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_connect_button_clicked_cb (CcBoltDeviceDialog *dialog)
|
|
|
|
{
|
2019-02-01 17:55:57 +01:00
|
|
|
g_autoptr(GPtrArray) devices = NULL;
|
|
|
|
g_autoptr(GList) entries = NULL;
|
2018-03-26 16:18:30 +02:00
|
|
|
BoltDevice *device = dialog->device;
|
2019-02-01 17:55:57 +01:00
|
|
|
GList *iter;
|
2018-03-26 16:18:30 +02:00
|
|
|
|
|
|
|
g_return_if_fail (device != NULL);
|
|
|
|
|
|
|
|
dialog_operation_start (dialog);
|
|
|
|
|
2019-02-01 17:55:57 +01:00
|
|
|
entries = gtk_container_get_children (GTK_CONTAINER (dialog->parents_devices));
|
|
|
|
devices = g_ptr_array_new ();
|
|
|
|
|
|
|
|
/* reverse the order, so to start with the devices closest to the host */
|
|
|
|
entries = g_list_reverse (entries);
|
|
|
|
|
|
|
|
for (iter = entries; iter; iter = iter->next)
|
2018-03-26 16:18:30 +02:00
|
|
|
{
|
2019-02-01 17:55:57 +01:00
|
|
|
CcBoltDeviceEntry *entry;
|
|
|
|
BoltDevice *dev;
|
|
|
|
BoltStatus status;
|
|
|
|
|
|
|
|
entry = (CcBoltDeviceEntry *) iter->data;
|
|
|
|
dev = cc_bolt_device_entry_get_device (entry);
|
|
|
|
status = bolt_device_get_status (dev);
|
|
|
|
|
|
|
|
/* skip any devices down in the chain that are already authorized
|
|
|
|
* NB: it is not possible to have gaps of non-authorized devices
|
|
|
|
* in the chain, i.e. once we encounter a non-authorized device,
|
|
|
|
* all following device (down the chain, towards the target) will
|
|
|
|
* also be not authorized. */
|
|
|
|
if (!bolt_status_is_pending (status))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* device is now either !stored || pending */
|
|
|
|
g_ptr_array_add (devices, dev);
|
2018-03-26 16:18:30 +02:00
|
|
|
}
|
|
|
|
|
2019-02-01 17:55:57 +01:00
|
|
|
/* finally the actual device of the dialog */
|
|
|
|
g_ptr_array_add (devices, device);
|
|
|
|
|
|
|
|
bolt_client_connect_all_async (dialog->client,
|
|
|
|
devices,
|
|
|
|
BOLT_POLICY_DEFAULT,
|
|
|
|
BOLT_AUTHCTRL_NONE,
|
|
|
|
dialog->cancel,
|
|
|
|
on_connect_all_done,
|
|
|
|
dialog);
|
2018-03-26 16:18:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_forget_device_done (GObject *source_object,
|
|
|
|
GAsyncResult *res,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
g_autoptr(GError) err = NULL;
|
|
|
|
CcBoltDeviceDialog *dialog = CC_BOLT_DEVICE_DIALOG (user_data);
|
|
|
|
gboolean ok;
|
|
|
|
|
|
|
|
ok = bolt_client_forget_device_finish (dialog->client, res, &err);
|
|
|
|
|
|
|
|
if (!ok)
|
|
|
|
g_prefix_error (&err, _("Failed to forget device: "));
|
|
|
|
|
|
|
|
dialog_operation_done (dialog, GTK_WIDGET (dialog->forget_button), err);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_forget_button_clicked_cb (CcBoltDeviceDialog *dialog)
|
|
|
|
{
|
|
|
|
const char *uid = NULL;
|
|
|
|
|
|
|
|
g_return_if_fail (dialog->device != NULL);
|
|
|
|
|
|
|
|
uid = bolt_device_get_uid (dialog->device);
|
|
|
|
dialog_operation_start (dialog);
|
|
|
|
|
|
|
|
bolt_client_forget_device_async (dialog->client,
|
|
|
|
uid,
|
|
|
|
dialog->cancel,
|
|
|
|
on_forget_device_done,
|
|
|
|
dialog);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_notify_button_clicked_cb (GtkButton *button,
|
|
|
|
CcBoltDeviceDialog *dialog)
|
|
|
|
{
|
|
|
|
gtk_revealer_set_reveal_child (dialog->notify_revealer, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
cc_bolt_device_dialog_finalize (GObject *object)
|
|
|
|
{
|
|
|
|
CcBoltDeviceDialog *dialog = CC_BOLT_DEVICE_DIALOG (object);
|
|
|
|
|
|
|
|
g_clear_object (&dialog->device);
|
|
|
|
g_cancellable_cancel (dialog->cancel);
|
|
|
|
g_clear_object (&dialog->cancel);
|
|
|
|
g_clear_object (&dialog->client);
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (cc_bolt_device_dialog_parent_class)->finalize (object);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
cc_bolt_device_dialog_class_init (CcBoltDeviceDialogClass *klass)
|
|
|
|
{
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
|
|
|
|
|
|
|
object_class->finalize = cc_bolt_device_dialog_finalize;
|
|
|
|
|
|
|
|
gtk_widget_class_set_template_from_resource (widget_class, RESOURCE_UI);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, header_bar);
|
|
|
|
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, notify_label);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, notify_revealer);
|
|
|
|
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, name_label);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, status_label);
|
|
|
|
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, uuid_label);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, time_title);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, time_label);
|
|
|
|
|
2019-02-01 17:55:57 +01:00
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, parents_expander);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, parents_label);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, parents_devices);
|
|
|
|
|
2018-03-26 16:18:30 +02:00
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, button_box);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, spinner);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, connect_button);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, forget_button);
|
|
|
|
|
|
|
|
gtk_widget_class_bind_template_callback (widget_class, on_notify_button_clicked_cb);
|
|
|
|
gtk_widget_class_bind_template_callback (widget_class, on_connect_button_clicked_cb);
|
|
|
|
gtk_widget_class_bind_template_callback (widget_class, on_forget_button_clicked_cb);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
cc_bolt_device_dialog_init (CcBoltDeviceDialog *dialog)
|
|
|
|
{
|
|
|
|
g_resources_register (cc_thunderbolt_get_resource ());
|
|
|
|
gtk_widget_init_template (GTK_WIDGET (dialog));
|
2019-02-01 17:55:57 +01:00
|
|
|
|
|
|
|
gtk_list_box_set_header_func (dialog->parents_devices,
|
|
|
|
cc_list_box_update_header_func,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
2018-03-26 16:18:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* public functions */
|
|
|
|
CcBoltDeviceDialog *
|
|
|
|
cc_bolt_device_dialog_new (void)
|
|
|
|
{
|
|
|
|
CcBoltDeviceDialog *dialog;
|
|
|
|
|
|
|
|
dialog = g_object_new (CC_TYPE_BOLT_DEVICE_DIALOG,
|
|
|
|
"use-header-bar", TRUE,
|
|
|
|
NULL);
|
|
|
|
return dialog;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cc_bolt_device_dialog_set_client (CcBoltDeviceDialog *dialog,
|
|
|
|
BoltClient *client)
|
|
|
|
{
|
|
|
|
g_clear_object (&dialog->client);
|
|
|
|
dialog->client = g_object_ref (client);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cc_bolt_device_dialog_set_device (CcBoltDeviceDialog *dialog,
|
2019-02-01 17:55:57 +01:00
|
|
|
BoltDevice *device,
|
|
|
|
GPtrArray *parents)
|
2018-03-26 16:18:30 +02:00
|
|
|
{
|
2019-02-01 17:55:57 +01:00
|
|
|
g_autofree char *msg = NULL;
|
|
|
|
guint i;
|
|
|
|
|
2018-03-26 16:18:30 +02:00
|
|
|
if (device == dialog->device)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (dialog->device)
|
|
|
|
{
|
|
|
|
g_cancellable_cancel (dialog->cancel);
|
|
|
|
g_clear_object (&dialog->cancel);
|
|
|
|
dialog->cancel = g_cancellable_new ();
|
|
|
|
|
|
|
|
g_signal_handlers_disconnect_by_func (dialog->device,
|
|
|
|
G_CALLBACK (on_device_notify_cb),
|
|
|
|
dialog);
|
|
|
|
g_clear_object (&dialog->device);
|
2019-02-01 17:55:57 +01:00
|
|
|
|
|
|
|
gtk_container_foreach (GTK_CONTAINER (dialog->parents_devices),
|
|
|
|
(GtkCallback) gtk_widget_destroy, NULL);
|
|
|
|
gtk_widget_hide (GTK_WIDGET (dialog->parents_expander));
|
2018-03-26 16:18:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (device == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
dialog->device = g_object_ref (device);
|
|
|
|
g_signal_connect_object (dialog->device,
|
|
|
|
"notify",
|
|
|
|
G_CALLBACK (on_device_notify_cb),
|
|
|
|
dialog,
|
|
|
|
0);
|
|
|
|
|
|
|
|
/* reset the sensitivity of the buttons, because
|
|
|
|
* dialog_update_from_device, because it can't know */
|
|
|
|
gtk_widget_set_sensitive (GTK_WIDGET (dialog->connect_button), TRUE);
|
|
|
|
gtk_widget_set_sensitive (GTK_WIDGET (dialog->forget_button), TRUE);
|
|
|
|
|
|
|
|
dialog_update_from_device (dialog);
|
2019-02-01 17:55:57 +01:00
|
|
|
|
|
|
|
/* no parents, we are done here */
|
|
|
|
if (!parents || parents->len == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
msg = g_strdup_printf (ngettext ("Depends on %u other device",
|
|
|
|
"Depends on %u other devices",
|
|
|
|
parents->len), parents->len);
|
|
|
|
|
|
|
|
gtk_label_set_label (dialog->parents_label, msg);
|
|
|
|
gtk_widget_show (GTK_WIDGET (dialog->parents_expander));
|
|
|
|
|
|
|
|
for (i = 0; i < parents->len; i++)
|
|
|
|
{
|
|
|
|
CcBoltDeviceEntry *entry;
|
|
|
|
BoltDevice *parent;
|
|
|
|
|
|
|
|
parent = g_ptr_array_index (parents, i);
|
|
|
|
|
|
|
|
entry = cc_bolt_device_entry_new (parent, TRUE);
|
|
|
|
gtk_widget_show (GTK_WIDGET (entry));
|
|
|
|
gtk_container_add (GTK_CONTAINER (dialog->parents_devices), GTK_WIDGET (entry));
|
|
|
|
}
|
2018-03-26 16:18:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
BoltDevice *
|
|
|
|
cc_bolt_device_dialog_peek_device (CcBoltDeviceDialog *dialog)
|
|
|
|
{
|
|
|
|
return dialog->device;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
cc_bolt_device_dialog_device_equal (CcBoltDeviceDialog *dialog,
|
|
|
|
BoltDevice *device)
|
|
|
|
{
|
|
|
|
return dialog->device != NULL && device == dialog->device;
|
|
|
|
}
|