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-runcommand-editor"
5 : :
6 : : #include "config.h"
7 : :
8 : : #include <adwaita.h>
9 : : #include <glib/gi18n.h>
10 : : #include <gtk/gtk.h>
11 : : #include <gio/gio.h>
12 : : #include <json-glib/json-glib.h>
13 : : #include <valent.h>
14 : :
15 : : #include "valent-device-preferences-commands-editor.h"
16 : :
17 : :
18 : : struct _ValentRuncommandEditor
19 : : {
20 : : GtkWindow parent_instance;
21 : :
22 : : char *uuid;
23 : : GVariant *command;
24 : :
25 : : /* template */
26 : : GtkWidget *save_button;
27 : : AdwEntryRow *argv_entry;
28 : : AdwEntryRow *name_entry;
29 : : GtkWidget *remove_group;
30 : : };
31 : :
32 [ + + + - ]: 28 : G_DEFINE_TYPE (ValentRuncommandEditor, valent_runcommand_editor, GTK_TYPE_WINDOW)
33 : :
34 : : typedef enum {
35 : : PROP_COMMAND = 1,
36 : : PROP_UUID,
37 : : } ValentRuncommandEditorProperty;
38 : :
39 : : static GParamSpec *properties[PROP_UUID + 1] = { NULL, };
40 : :
41 : :
42 : : static void
43 : 10 : on_entry_changed (AdwEntryRow *entry,
44 : : ValentRuncommandEditor *self)
45 : : {
46 : 10 : const char *argv_text;
47 : 10 : const char *name_text;
48 : :
49 [ + + + - ]: 10 : g_assert (entry == NULL || ADW_IS_ENTRY_ROW (entry));
50 [ - + ]: 10 : g_assert (VALENT_IS_RUNCOMMAND_EDITOR (self));
51 : :
52 : 10 : argv_text = gtk_editable_get_text (GTK_EDITABLE (self->argv_entry));
53 : 10 : name_text = gtk_editable_get_text (GTK_EDITABLE (self->name_entry));
54 : :
55 [ + - + + : 10 : if (argv_text != NULL && *argv_text != '\0' &&
+ - ]
56 [ + + ]: 7 : name_text != NULL && *name_text != '\0')
57 : 5 : gtk_widget_action_set_enabled (GTK_WIDGET (self), "editor.save", TRUE);
58 : : else
59 : 5 : gtk_widget_action_set_enabled (GTK_WIDGET (self), "editor.save", FALSE);
60 : 10 : }
61 : :
62 : : static void
63 : 2 : valent_runcommand_editor_sync (ValentRuncommandEditor *self)
64 : : {
65 : 2 : const char *name_text = "";
66 : 2 : const char *argv_text = "";
67 : :
68 [ + - ]: 2 : g_assert (VALENT_IS_RUNCOMMAND_EDITOR (self));
69 : :
70 : : /* Parse command */
71 [ + - ]: 2 : if (self->command != NULL)
72 : : {
73 : 2 : g_variant_lookup (self->command, "name", "&s", &name_text);
74 : 2 : g_variant_lookup (self->command, "command", "&s", &argv_text);
75 : : }
76 : :
77 : : /* Update editor content */
78 : 2 : gtk_editable_set_text (GTK_EDITABLE (self->name_entry), name_text);
79 : 2 : gtk_editable_set_text (GTK_EDITABLE (self->argv_entry), argv_text);
80 : 2 : gtk_widget_set_visible (self->remove_group, self->command != NULL);
81 : 2 : on_entry_changed (NULL, self);
82 : 2 : }
83 : :
84 : : /*
85 : : * GAction
86 : : */
87 : : static void
88 : 1 : editor_cancel_action (GtkWidget *widget,
89 : : const char *action_name,
90 : : GVariant *parameter)
91 : : {
92 : 1 : ValentRuncommandEditor *self = VALENT_RUNCOMMAND_EDITOR (widget);
93 : :
94 : 1 : valent_runcommand_editor_sync (self);
95 : 1 : g_object_notify_by_pspec (G_OBJECT (widget), properties [PROP_COMMAND]);
96 : 1 : }
97 : :
98 : : static void
99 : 1 : editor_remove_action (GtkWidget *widget,
100 : : const char *action_name,
101 : : GVariant *parameter)
102 : : {
103 : 1 : ValentRuncommandEditor *self = VALENT_RUNCOMMAND_EDITOR (widget);
104 : :
105 : 1 : gtk_editable_set_text (GTK_EDITABLE (self->name_entry), "");
106 : 1 : gtk_editable_set_text (GTK_EDITABLE (self->argv_entry), "");
107 : :
108 [ + - ]: 1 : g_clear_pointer (&self->command, g_variant_unref);
109 : 1 : g_object_notify_by_pspec (G_OBJECT (widget), properties [PROP_COMMAND]);
110 : 1 : }
111 : :
112 : : static void
113 : 1 : editor_save_action (GtkWidget *widget,
114 : : const char *action_name,
115 : : GVariant *parameter)
116 : : {
117 : 1 : ValentRuncommandEditor *self = VALENT_RUNCOMMAND_EDITOR (widget);
118 : 1 : GVariant *command = NULL;
119 : 1 : const char *name_text = NULL;
120 : 1 : const char *argv_text = NULL;
121 : :
122 [ + - ]: 1 : g_assert (VALENT_IS_RUNCOMMAND_EDITOR (self));
123 : :
124 : 1 : name_text = gtk_editable_get_text (GTK_EDITABLE (self->name_entry));
125 : 1 : argv_text = gtk_editable_get_text (GTK_EDITABLE (self->argv_entry));
126 : :
127 [ + - + - : 1 : g_return_if_fail (argv_text != NULL && *argv_text != '\0' &&
+ - - + ]
128 : : name_text != NULL && *name_text != '\0');
129 : :
130 : 1 : command = g_variant_new_parsed ("{"
131 : : "'name': <%s>, "
132 : : "'command': <%s>"
133 : : "}",
134 : : name_text,
135 : : argv_text);
136 : :
137 [ + - ]: 1 : g_clear_pointer (&self->command, g_variant_unref);
138 : 1 : self->command = g_variant_ref_sink (command);
139 : 1 : g_object_notify_by_pspec (G_OBJECT (widget), properties [PROP_COMMAND]);
140 : : }
141 : :
142 : : /*
143 : : * GObject
144 : : */
145 : : static void
146 : 1 : valent_runcommand_editor_dispose (GObject *object)
147 : : {
148 : 1 : GtkWidget *widget = GTK_WIDGET (object);
149 : :
150 : 1 : gtk_widget_dispose_template (widget, VALENT_TYPE_RUNCOMMAND_EDITOR);
151 : :
152 : 1 : G_OBJECT_CLASS (valent_runcommand_editor_parent_class)->dispose (object);
153 : 1 : }
154 : :
155 : : static void
156 : 1 : valent_runcommand_editor_finalize (GObject *object)
157 : : {
158 : 1 : ValentRuncommandEditor *self = VALENT_RUNCOMMAND_EDITOR (object);
159 : :
160 [ - + ]: 1 : g_clear_pointer (&self->command, g_variant_unref);
161 [ + - ]: 1 : g_clear_pointer (&self->uuid, g_free);
162 : :
163 : 1 : G_OBJECT_CLASS (valent_runcommand_editor_parent_class)->finalize (object);
164 : 1 : }
165 : :
166 : : static void
167 : 2 : valent_runcommand_editor_get_property (GObject *object,
168 : : guint prop_id,
169 : : GValue *value,
170 : : GParamSpec *pspec)
171 : : {
172 : 2 : ValentRuncommandEditor *self = VALENT_RUNCOMMAND_EDITOR (object);
173 : :
174 [ + + - ]: 2 : switch ((ValentRuncommandEditorProperty)prop_id)
175 : : {
176 : 1 : case PROP_COMMAND:
177 : 1 : g_value_set_variant (value, self->command);
178 : 1 : break;
179 : :
180 : 1 : case PROP_UUID:
181 : 1 : g_value_set_string (value, self->uuid);
182 : 1 : break;
183 : :
184 : 0 : default:
185 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
186 : : }
187 : 2 : }
188 : :
189 : : static void
190 : 2 : valent_runcommand_editor_set_property (GObject *object,
191 : : guint prop_id,
192 : : const GValue *value,
193 : : GParamSpec *pspec)
194 : : {
195 : 2 : ValentRuncommandEditor *self = VALENT_RUNCOMMAND_EDITOR (object);
196 : :
197 [ + + - ]: 2 : switch ((ValentRuncommandEditorProperty)prop_id)
198 : : {
199 : 1 : case PROP_COMMAND:
200 : 1 : valent_runcommand_editor_set_command (self, g_value_get_variant (value));
201 : 1 : break;
202 : :
203 : 1 : case PROP_UUID:
204 : 1 : valent_runcommand_editor_set_uuid (self, g_value_get_string (value));
205 : 1 : break;
206 : :
207 : 0 : default:
208 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
209 : : }
210 : 2 : }
211 : :
212 : : static void
213 : 1 : valent_runcommand_editor_class_init (ValentRuncommandEditorClass *klass)
214 : : {
215 : 1 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
216 : 1 : GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
217 : :
218 : 1 : object_class->dispose = valent_runcommand_editor_dispose;
219 : 1 : object_class->finalize = valent_runcommand_editor_finalize;
220 : 1 : object_class->get_property = valent_runcommand_editor_get_property;
221 : 1 : object_class->set_property = valent_runcommand_editor_set_property;
222 : :
223 : : /**
224 : : * ValentRuncommandEditor:command: (getter get_command) (setter set_command)
225 : : *
226 : : * The command the editor is operating on.
227 : : *
228 : : * Since: 1.0
229 : : */
230 : 2 : properties [PROP_COMMAND] =
231 : 1 : g_param_spec_variant ("command", NULL, NULL,
232 : : G_VARIANT_TYPE_VARDICT,
233 : : NULL,
234 : : (G_PARAM_READWRITE |
235 : : G_PARAM_CONSTRUCT |
236 : : G_PARAM_EXPLICIT_NOTIFY |
237 : : G_PARAM_STATIC_STRINGS));
238 : :
239 : : /**
240 : : * ValentRuncommandEditor:uuid: (getter get_uuid) (setter set_uuid)
241 : : *
242 : : * The uuid the editor is operating on.
243 : : *
244 : : * Since: 1.0
245 : : */
246 : 2 : properties [PROP_UUID] =
247 : 1 : g_param_spec_string ("uuid", NULL, NULL,
248 : : "",
249 : : (G_PARAM_READWRITE |
250 : : G_PARAM_CONSTRUCT |
251 : : G_PARAM_EXPLICIT_NOTIFY |
252 : : G_PARAM_STATIC_STRINGS));
253 : :
254 : 1 : g_object_class_install_properties (object_class, G_N_ELEMENTS (properties), properties);
255 : :
256 : 1 : gtk_widget_class_set_template_from_resource (widget_class, "/plugins/gnome/valent-device-preferences-commands-editor.ui");
257 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentRuncommandEditor, save_button);
258 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentRuncommandEditor, argv_entry);
259 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentRuncommandEditor, name_entry);
260 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentRuncommandEditor, remove_group);
261 : 1 : gtk_widget_class_bind_template_callback (widget_class, on_entry_changed);
262 : :
263 : 1 : gtk_widget_class_install_action (widget_class, "editor.cancel", NULL, editor_cancel_action);
264 : 1 : gtk_widget_class_install_action (widget_class, "editor.remove", NULL, editor_remove_action);
265 : 1 : gtk_widget_class_install_action (widget_class, "editor.save", NULL, editor_save_action);
266 : 1 : }
267 : :
268 : : static void
269 : 1 : valent_runcommand_editor_init (ValentRuncommandEditor *self)
270 : : {
271 : 1 : gtk_widget_init_template (GTK_WIDGET (self));
272 : 1 : }
273 : :
274 : : /**
275 : : * valent_runcommand_editor_get_command:
276 : : * @editor: a `ValentRuncommandEditor`
277 : : *
278 : : * Get the command the editor is operating on.
279 : : *
280 : : * Returns: (transfer none) (nullable): the command
281 : : */
282 : : GVariant *
283 : 6 : valent_runcommand_editor_get_command (ValentRuncommandEditor *editor)
284 : : {
285 [ + - ]: 6 : g_return_val_if_fail (VALENT_IS_RUNCOMMAND_EDITOR (editor), NULL);
286 : :
287 : 6 : return editor->command;
288 : : }
289 : :
290 : : /**
291 : : * valent_runcommand_editor_set_command:
292 : : * @editor: a `ValentRuncommandEditor`
293 : : * @command: a command entry
294 : : *
295 : : * Set the command for the editor to operate on.
296 : : */
297 : : void
298 : 1 : valent_runcommand_editor_set_command (ValentRuncommandEditor *editor,
299 : : GVariant *command)
300 : : {
301 [ + - ]: 1 : g_return_if_fail (VALENT_IS_RUNCOMMAND_EDITOR (editor));
302 [ + - - + ]: 1 : g_return_if_fail (command == NULL || g_variant_is_of_type (command, G_VARIANT_TYPE_VARDICT));
303 : :
304 : : /* Update the property */
305 [ - + ]: 1 : g_clear_pointer (&editor->command, g_variant_unref);
306 [ + - ]: 1 : editor->command = command ? g_variant_ref_sink (command) : NULL;
307 : 1 : g_object_notify_by_pspec (G_OBJECT (editor), properties [PROP_COMMAND]);
308 : :
309 : 1 : valent_runcommand_editor_sync (editor);
310 : : }
311 : :
312 : : /**
313 : : * valent_runcommand_editor_get_uuid:
314 : : * @editor: a `ValentRuncommandEditor`
315 : : *
316 : : * Get the UUID of the command for @editor
317 : : *
318 : : * Returns: (not nullable) (transfer none): the command UUID
319 : : */
320 : : const char *
321 : 3 : valent_runcommand_editor_get_uuid (ValentRuncommandEditor *editor)
322 : : {
323 [ + - ]: 3 : g_return_val_if_fail (VALENT_IS_RUNCOMMAND_EDITOR (editor), NULL);
324 : :
325 : 3 : return editor->uuid;
326 : : }
327 : :
328 : : /**
329 : : * valent_runcommand_editor_set_uuid:
330 : : * @editor: a `ValentRuncommandEditor`
331 : : * @uuid: a command UUID
332 : : *
333 : : * Set the UUID of the command for @editor to @uuid.
334 : : */
335 : : void
336 : 1 : valent_runcommand_editor_set_uuid (ValentRuncommandEditor *editor,
337 : : const char *uuid)
338 : : {
339 [ + - ]: 1 : g_return_if_fail (VALENT_IS_RUNCOMMAND_EDITOR (editor));
340 [ - + ]: 1 : g_return_if_fail (uuid != NULL);
341 : :
342 [ + - ]: 1 : if (g_set_str (&editor->uuid, uuid))
343 : 1 : g_object_notify_by_pspec (G_OBJECT (editor), properties [PROP_UUID]);
344 : : }
345 : :
|