/* 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 . * * Authors: Christian J. Kellner * */ #include #include "bolt-str.h" #include "cc-bolt-device-entry.h" #include "cc-thunderbolt-resources.h" #include #define RESOURCE_UI "/org/gnome/control-center/thunderbolt/cc-bolt-device-entry.ui" struct _CcBoltDeviceEntry { GtkListBoxRow parent; BoltDevice *device; /* main ui */ GtkLabel *name_label; GtkLabel *status_label; GtkLabel *status_warning; gboolean show_warnings; }; static const char * device_status_to_brief_for_ui (BoltDevice *dev); G_DEFINE_TYPE (CcBoltDeviceEntry, cc_bolt_device_entry, GTK_TYPE_LIST_BOX_ROW); enum { SIGNAL_STATUS_CHANGED, SIGNAL_LAST }; static guint signals[SIGNAL_LAST] = { 0, }; static void entry_set_name (CcBoltDeviceEntry *entry) { g_autofree char *name = NULL; BoltDevice *dev = entry->device; g_return_if_fail (dev != NULL); name = bolt_device_get_display_name (dev); gtk_label_set_label (entry->name_label, name); } static void entry_update_status (CcBoltDeviceEntry *entry) { const char *brief; BoltStatus status; gboolean warn; status = bolt_device_get_status (entry->device); brief = device_status_to_brief_for_ui (entry->device); gtk_label_set_label (entry->status_label, brief); g_signal_emit (entry, signals[SIGNAL_STATUS_CHANGED], 0, status); warn = entry->show_warnings && bolt_status_is_pending (status); gtk_widget_set_visible (GTK_WIDGET (entry->status_warning), warn); } static void on_device_notify_cb (GObject *gobject, GParamSpec *pspec, gpointer user_data) { CcBoltDeviceEntry *entry = CC_BOLT_DEVICE_ENTRY (user_data); const char *what; what = g_param_spec_get_name (pspec); if (bolt_streq (what, "status")) entry_update_status (entry); else if (bolt_streq (what, "label") || bolt_streq (what, "name") || bolt_streq (what, "vendor")) entry_set_name (entry); } /* device helpers */ static const char * device_status_to_brief_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: case BOLT_STATUS_AUTHORIZED_DPONLY: return C_("Thunderbolt Device Status", "Connected"); case BOLT_STATUS_AUTH_ERROR: return C_("Thunderbolt Device Status", "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: if (nopcie) return C_("Thunderbolt Device Status", "Connected"); else return C_("Thunderbolt Device Status", "Authorized"); case BOLT_STATUS_UNKNOWN: break; /* use function default */ } return C_("Thunderbolt Device Status", "Unknown"); } static void cc_bolt_device_entry_finalize (GObject *object) { CcBoltDeviceEntry *entry = CC_BOLT_DEVICE_ENTRY (object); g_clear_object (&entry->device); G_OBJECT_CLASS (cc_bolt_device_entry_parent_class)->finalize (object); } static void cc_bolt_device_entry_class_init (CcBoltDeviceEntryClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); object_class->finalize = cc_bolt_device_entry_finalize; gtk_widget_class_set_template_from_resource (widget_class, RESOURCE_UI); gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceEntry, name_label); gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceEntry, status_label); gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceEntry, status_warning); signals[SIGNAL_STATUS_CHANGED] = g_signal_new ("status-changed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, BOLT_TYPE_STATUS); } static void cc_bolt_device_entry_init (CcBoltDeviceEntry *entry) { g_resources_register (cc_thunderbolt_get_resource ()); gtk_widget_init_template (GTK_WIDGET (entry)); } /* public function */ CcBoltDeviceEntry * cc_bolt_device_entry_new (BoltDevice *device, gboolean show_warnings) { CcBoltDeviceEntry *entry; entry = g_object_new (CC_TYPE_BOLT_DEVICE_ENTRY, NULL); entry->device = g_object_ref (device); entry->show_warnings = show_warnings; entry_set_name (entry); entry_update_status (entry); g_signal_connect_object (entry->device, "notify", G_CALLBACK (on_device_notify_cb), entry, 0); return entry; } BoltDevice * cc_bolt_device_entry_get_device (CcBoltDeviceEntry *entry) { g_return_val_if_fail (entry != NULL, NULL); g_return_val_if_fail (CC_IS_BOLT_DEVICE_ENTRY (entry), NULL); return entry->device; }