Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-3.0-or-later
2 : : // SPDX-FileCopyrightText: Andy Holmes <andrew.g.r.holmes@gmail.com>
3 : :
4 : : #define G_LOG_DOMAIN "valent-connectivity_report-gadget"
5 : :
6 : : #include "config.h"
7 : :
8 : : #include <glib/gi18n.h>
9 : : #include <gtk/gtk.h>
10 : : #include <valent.h>
11 : :
12 : : #include "valent-connectivity_report-gadget.h"
13 : :
14 : :
15 : : struct _ValentConnectivityReportGadget
16 : : {
17 : : ValentDeviceGadget parent_instance;
18 : :
19 : : GHashTable *connections;
20 : :
21 : : GtkWidget *button;
22 : : GtkWidget *box;
23 : : };
24 : :
25 [ + + + - ]: 18 : G_DEFINE_FINAL_TYPE (ValentConnectivityReportGadget, valent_connectivity_report_gadget, VALENT_TYPE_DEVICE_GADGET)
26 : :
27 : :
28 : : static void
29 : 9 : on_action_state_changed (GActionGroup *action_group,
30 : : const char *action_name,
31 : : GVariant *value,
32 : : ValentConnectivityReportGadget *self)
33 : : {
34 : 9 : GtkWidget *child;
35 : 9 : g_autoptr (GVariant) signal_strengths = NULL;
36 : 9 : GVariantIter iter;
37 : 9 : char *signal_id = NULL;
38 : 9 : GVariant *signal_state;
39 : 9 : const char *icon_name;
40 : 9 : const char *title;
41 : :
42 [ - + ]: 9 : g_assert (VALENT_IS_CONNECTIVITY_REPORT_GADGET (self));
43 : :
44 : : /* Clear the popup */
45 [ + + ]: 15 : while ((child = gtk_widget_get_first_child (self->box)) != NULL)
46 : 6 : gtk_box_remove (GTK_BOX (self->box), child);
47 : :
48 [ - + ]: 9 : if (!g_variant_lookup (value, "signal-strengths", "@a{sv}", &signal_strengths))
49 : : {
50 : 0 : gtk_widget_set_visible (self->button, FALSE);
51 [ # # ]: 0 : return;
52 : : }
53 : :
54 : : /* Add each signal */
55 : 9 : g_variant_iter_init (&iter, signal_strengths);
56 : :
57 [ + + ]: 16 : while (g_variant_iter_loop (&iter, "{sv}", &signal_id, &signal_state))
58 : : {
59 : 7 : GtkWidget *box;
60 : 7 : GtkWidget *level;
61 : 7 : GtkWidget *icon;
62 : 7 : const char *signal_icon;
63 : 7 : const char *network_type;
64 : 7 : int64_t signal_strength;
65 : :
66 : 7 : box = g_object_new (GTK_TYPE_BOX,
67 : : "spacing", 6,
68 : : NULL);
69 : :
70 : 7 : icon = g_object_new (GTK_TYPE_IMAGE,
71 : : "pixel-size", 16,
72 : : "valign", GTK_ALIGN_CENTER,
73 : : NULL);
74 : 7 : gtk_box_append (GTK_BOX (box), icon);
75 : :
76 : 7 : level = g_object_new (GTK_TYPE_LEVEL_BAR,
77 : : "mode", GTK_LEVEL_BAR_MODE_DISCRETE,
78 : : "min-value", 0.0,
79 : : "max-value", 5.0,
80 : : "value", 0.0,
81 : : "valign", GTK_ALIGN_CENTER,
82 : : "hexpand", TRUE,
83 : : "height-request", 3,
84 : : "width-request", 64,
85 : : NULL);
86 : 7 : gtk_box_append (GTK_BOX (box), level);
87 : :
88 [ + - ]: 7 : if (g_variant_lookup (signal_state, "icon-name", "&s", &signal_icon))
89 : 7 : gtk_image_set_from_icon_name (GTK_IMAGE (icon), signal_icon);
90 : :
91 [ + - ]: 7 : if (g_variant_lookup (signal_state, "network-type", "&s", &network_type))
92 : 7 : gtk_widget_set_tooltip_text (GTK_WIDGET (icon), network_type);
93 : :
94 [ + - ]: 7 : if (g_variant_lookup (signal_state, "signal-strength", "x", &signal_strength))
95 : 7 : gtk_level_bar_set_value (GTK_LEVEL_BAR (level), signal_strength);
96 : :
97 : 7 : gtk_box_append (GTK_BOX (self->box), box);
98 : : }
99 : :
100 : : /* Add status properties */
101 [ + - ]: 9 : if (g_variant_lookup (value, "icon-name", "&s", &icon_name))
102 : 9 : gtk_menu_button_set_icon_name (GTK_MENU_BUTTON (self->button), icon_name);
103 : :
104 [ + - ]: 9 : if (g_variant_lookup (value, "title", "&s", &title))
105 : 9 : gtk_accessible_update_property (GTK_ACCESSIBLE (self->button),
106 : : GTK_ACCESSIBLE_PROPERTY_LABEL, title,
107 : : -1);
108 : :
109 [ + + ]: 9 : if (g_action_group_get_action_enabled (action_group, action_name))
110 : 8 : gtk_widget_set_visible (self->button, TRUE);
111 : : }
112 : :
113 : : static void
114 : 2 : on_action_enabled_changed (GActionGroup *action_group,
115 : : const char *action_name,
116 : : gboolean enabled,
117 : : ValentConnectivityReportGadget *self)
118 : : {
119 : 4 : g_autoptr (GVariant) state = NULL;
120 : :
121 : 2 : gtk_widget_set_visible (self->button, enabled);
122 : :
123 [ + + ]: 2 : if (enabled)
124 : 1 : state = g_action_group_get_action_state (action_group, action_name);
125 : :
126 [ + - ]: 1 : if (state != NULL)
127 : 1 : on_action_state_changed (action_group, action_name, state, self);
128 : 2 : }
129 : :
130 : : /*
131 : : * GObject
132 : : */
133 : : static void
134 : 1 : valent_connectivity_report_gadget_constructed (GObject *object)
135 : : {
136 : 1 : ValentConnectivityReportGadget *self = VALENT_CONNECTIVITY_REPORT_GADGET (object);
137 : 1 : GActionGroup *action_group = NULL;
138 : 1 : gboolean enabled = FALSE;
139 : :
140 : 1 : g_object_get (object, "device", &action_group, NULL);
141 : 1 : g_signal_connect_object (action_group,
142 : : "action-state-changed::connectivity_report.state",
143 : : G_CALLBACK (on_action_state_changed),
144 : : self, 0);
145 : :
146 : 1 : g_signal_connect_object (action_group,
147 : : "action-enabled-changed::connectivity_report.state",
148 : : G_CALLBACK (on_action_enabled_changed),
149 : : self, 0);
150 : :
151 : 1 : enabled = g_action_group_get_action_enabled (action_group, "connectivity_report.state");
152 : 1 : on_action_enabled_changed (action_group, "connectivity_report.state", enabled, self);
153 [ + - ]: 1 : g_clear_object (&action_group);
154 : :
155 : 1 : G_OBJECT_CLASS (valent_connectivity_report_gadget_parent_class)->constructed (object);
156 : 1 : }
157 : :
158 : : static void
159 : 1 : valent_connectivity_report_gadget_dispose (GObject *object)
160 : : {
161 : 1 : ValentConnectivityReportGadget *self = VALENT_CONNECTIVITY_REPORT_GADGET (object);
162 : :
163 [ + - ]: 1 : g_clear_pointer (&self->button, gtk_widget_unparent);
164 : :
165 : 1 : G_OBJECT_CLASS (valent_connectivity_report_gadget_parent_class)->dispose (object);
166 : 1 : }
167 : :
168 : : static void
169 : 3 : valent_connectivity_report_gadget_class_init (ValentConnectivityReportGadgetClass *klass)
170 : : {
171 : 3 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
172 : :
173 : 3 : object_class->constructed = valent_connectivity_report_gadget_constructed;
174 : 3 : object_class->dispose = valent_connectivity_report_gadget_dispose;
175 : : }
176 : :
177 : : static void
178 : 1 : valent_connectivity_report_gadget_init (ValentConnectivityReportGadget *self)
179 : : {
180 : 1 : GtkWidget *popover;
181 : :
182 : : /* Popover */
183 : 1 : self->box = g_object_new (GTK_TYPE_BOX,
184 : : "margin-top", 6,
185 : : "margin-bottom", 6,
186 : : "margin-start", 6,
187 : : "margin-end", 6,
188 : : "orientation", GTK_ORIENTATION_VERTICAL,
189 : : "spacing", 6,
190 : : NULL);
191 : 1 : popover = g_object_new (GTK_TYPE_POPOVER,
192 : : "autohide", TRUE,
193 : : "child", self->box,
194 : : NULL);
195 : :
196 : : /* Button */
197 : 1 : self->button = g_object_new (GTK_TYPE_MENU_BUTTON,
198 : : "icon-name", "network-cellular-offline-symbolic",
199 : : "popover", popover,
200 : : "has-frame", FALSE,
201 : : NULL);
202 : 1 : gtk_accessible_update_property (GTK_ACCESSIBLE (self->button),
203 : : GTK_ACCESSIBLE_PROPERTY_LABEL, _("Mobile Network"),
204 : : -1);
205 : 1 : gtk_widget_set_parent (self->button, GTK_WIDGET (self));
206 : 1 : }
207 : :
|