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-share-text-dialog"
5 : :
6 : : #include "config.h"
7 : :
8 : : #include <adwaita.h>
9 : : #include <glib/gi18n.h>
10 : : #include <gtk/gtk.h>
11 : : #include <valent.h>
12 : :
13 : : #include "valent-share-text-dialog.h"
14 : :
15 : :
16 : : struct _ValentShareTextDialog
17 : : {
18 : : AdwMessageDialog parent_instance;
19 : :
20 : : char *text;
21 : : GtkLabel *text_label;
22 : : };
23 : :
24 [ + + + - ]: 19 : G_DEFINE_FINAL_TYPE (ValentShareTextDialog, valent_share_text_dialog, ADW_TYPE_MESSAGE_DIALOG)
25 : :
26 : : enum {
27 : : PROP_0,
28 : : PROP_TEXT,
29 : : N_PROPERTIES
30 : : };
31 : :
32 : : static GParamSpec *properties[N_PROPERTIES] = { NULL, };
33 : :
34 : :
35 : : static void
36 : 0 : g_file_replace_contents_cb (GFile *file,
37 : : GAsyncResult *result,
38 : : gpointer user_data)
39 : : {
40 : 0 : g_autoptr (GError) error = NULL;
41 : :
42 [ # # ]: 0 : if (!g_file_replace_contents_finish (file, result, NULL, &error))
43 : 0 : g_warning ("\"%s\": %s", g_file_peek_path (file), error->message);
44 : 0 : }
45 : :
46 : : static void
47 : 0 : gtk_file_dialog_save_cb (GtkFileDialog *dialog,
48 : : GAsyncResult *result,
49 : : ValentShareTextDialog *self)
50 : : {
51 : 0 : g_autoptr (GBytes) bytes = NULL;
52 [ # # ]: 0 : g_autoptr (GFile) file = NULL;
53 : 0 : g_autoptr (GError) error = NULL;
54 : :
55 [ # # ]: 0 : if ((file = gtk_file_dialog_save_finish (dialog, result, &error)) == NULL)
56 : : {
57 [ # # # # ]: 0 : if (!g_error_matches (error, GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_CANCELLED) &&
58 : 0 : !g_error_matches (error, GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_DISMISSED))
59 : 0 : g_warning ("%s(): %s", G_STRFUNC, error->message);
60 : :
61 [ # # ]: 0 : return;
62 : : }
63 : :
64 : 0 : bytes = g_bytes_new (self->text, strlen (self->text));
65 : 0 : g_file_replace_contents_bytes_async (file,
66 : : bytes,
67 : : NULL,
68 : : FALSE,
69 : : G_FILE_CREATE_REPLACE_DESTINATION,
70 : : NULL,
71 : : (GAsyncReadyCallback)g_file_replace_contents_cb,
72 : : NULL);
73 [ # # ]: 0 : gtk_window_destroy (GTK_WINDOW (self));
74 : : }
75 : :
76 : : /*
77 : : * AdwMessageDialog
78 : : */
79 : : static void
80 : 2 : valent_share_text_dialog_response (AdwMessageDialog *dialog,
81 : : const char *response)
82 : : {
83 : 2 : ValentShareTextDialog *self = VALENT_SHARE_TEXT_DIALOG (dialog);
84 : :
85 [ + - ]: 2 : g_assert (VALENT_IS_SHARE_TEXT_DIALOG (self));
86 : :
87 [ + + ]: 2 : if (g_strcmp0 (response, "copy") == 0)
88 : : {
89 : 1 : gdk_clipboard_set_text (gtk_widget_get_clipboard (GTK_WIDGET (dialog)),
90 : 1 : self->text);
91 : 1 : gtk_window_destroy (GTK_WINDOW (dialog));
92 : : }
93 [ + - ]: 1 : else if (g_strcmp0 (response, "save") == 0)
94 : : {
95 : 3 : g_autoptr (GtkFileDialog) chooser = NULL;
96 : :
97 : 1 : chooser = g_object_new (GTK_TYPE_FILE_DIALOG,
98 : : "accept-label", _("Save"),
99 : : "modal", TRUE,
100 : : NULL);
101 [ + - ]: 1 : gtk_file_dialog_save (chooser,
102 : : GTK_WINDOW (dialog),
103 : : NULL,
104 : : (GAsyncReadyCallback)gtk_file_dialog_save_cb,
105 : : self);
106 : : }
107 [ # # ]: 0 : else if (g_strcmp0 (response, "close") == 0)
108 : : {
109 : 0 : gtk_window_destroy (GTK_WINDOW (dialog));
110 : : }
111 : 2 : }
112 : :
113 : : /*
114 : : * GtkWindow
115 : : */
116 : : static gboolean
117 : 0 : valent_share_text_dialog_close_request (GtkWindow *window)
118 : : {
119 : : /* Chain-up to AdwMessageDialog to avoid re-entrancy with `response` */
120 : 0 : GTK_WINDOW_CLASS (valent_share_text_dialog_parent_class)->close_request (window);
121 : :
122 : : /* Unconditionally block `close-request` */
123 : 0 : return TRUE;
124 : : }
125 : :
126 : : /*
127 : : * GObject
128 : : */
129 : : static void
130 : 4 : valent_share_text_dialog_dispose (GObject *object)
131 : : {
132 : 4 : GtkWidget *widget = GTK_WIDGET (object);
133 : :
134 : 4 : gtk_widget_dispose_template (widget, VALENT_TYPE_SHARE_TEXT_DIALOG);
135 : :
136 : 4 : G_OBJECT_CLASS (valent_share_text_dialog_parent_class)->dispose (object);
137 : 4 : }
138 : :
139 : : static void
140 : 4 : valent_share_text_dialog_finalize (GObject *object)
141 : : {
142 : 4 : ValentShareTextDialog *self = VALENT_SHARE_TEXT_DIALOG (object);
143 : :
144 [ + - ]: 4 : g_clear_pointer (&self->text, g_free);
145 : :
146 : 4 : G_OBJECT_CLASS (valent_share_text_dialog_parent_class)->finalize (object);
147 : 4 : }
148 : :
149 : : static void
150 : 1 : valent_share_text_dialog_get_property (GObject *object,
151 : : guint prop_id,
152 : : GValue *value,
153 : : GParamSpec *pspec)
154 : : {
155 : 1 : ValentShareTextDialog *self = VALENT_SHARE_TEXT_DIALOG (object);
156 : :
157 [ + - ]: 1 : switch (prop_id)
158 : : {
159 : 1 : case PROP_TEXT:
160 : 1 : g_value_set_string (value, valent_share_text_dialog_get_text (self));
161 : 1 : break;
162 : :
163 : 0 : default:
164 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
165 : : }
166 : 1 : }
167 : :
168 : : static void
169 : 4 : valent_share_text_dialog_set_property (GObject *object,
170 : : guint prop_id,
171 : : const GValue *value,
172 : : GParamSpec *pspec)
173 : : {
174 : 4 : ValentShareTextDialog *self = VALENT_SHARE_TEXT_DIALOG (object);
175 : :
176 [ + - ]: 4 : switch (prop_id)
177 : : {
178 : 4 : case PROP_TEXT:
179 : 4 : valent_share_text_dialog_set_text (self, g_value_get_string (value));
180 : 4 : break;
181 : :
182 : 0 : default:
183 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
184 : : }
185 : 4 : }
186 : :
187 : : static void
188 : 2 : valent_share_text_dialog_class_init (ValentShareTextDialogClass *klass)
189 : : {
190 : 2 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
191 : 2 : GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
192 : 2 : GtkWindowClass *window_class = GTK_WINDOW_CLASS (klass);
193 : 2 : AdwMessageDialogClass *dialog_class = ADW_MESSAGE_DIALOG_CLASS (klass);
194 : :
195 : 2 : object_class->finalize = valent_share_text_dialog_finalize;
196 : 2 : object_class->dispose = valent_share_text_dialog_dispose;
197 : 2 : object_class->get_property = valent_share_text_dialog_get_property;
198 : 2 : object_class->set_property = valent_share_text_dialog_set_property;
199 : :
200 : 2 : window_class->close_request = valent_share_text_dialog_close_request;
201 : :
202 : 2 : dialog_class->response = valent_share_text_dialog_response;
203 : :
204 : 2 : gtk_widget_class_set_template_from_resource (widget_class, "/plugins/share/valent-share-text-dialog.ui");
205 : 2 : gtk_widget_class_bind_template_child (widget_class, ValentShareTextDialog, text_label);
206 : :
207 : : /**
208 : : * ValentShareTextDialog:text:
209 : : *
210 : : * The text content shared from the remote [class@Valent.Device].
211 : : */
212 : 4 : properties [PROP_TEXT] =
213 : 2 : g_param_spec_string ("text", NULL, NULL,
214 : : NULL,
215 : : (G_PARAM_READWRITE |
216 : : G_PARAM_EXPLICIT_NOTIFY |
217 : : G_PARAM_STATIC_STRINGS));
218 : :
219 : 2 : g_object_class_install_properties (object_class, N_PROPERTIES, properties);
220 : 2 : }
221 : :
222 : : static void
223 : 4 : valent_share_text_dialog_init (ValentShareTextDialog *self)
224 : : {
225 : 4 : gtk_widget_init_template (GTK_WIDGET (self));
226 : 4 : }
227 : :
228 : : /**
229 : : * valent_share_text_dialog_get_text:
230 : : * @dialog: a `ValentShareTextDialog`
231 : : *
232 : : * Get the text content shared by the remote [class@Valent.Device].
233 : : *
234 : : * Returns: (transfer none) (nullable): the text content
235 : : */
236 : : const char *
237 : 1 : valent_share_text_dialog_get_text (ValentShareTextDialog *dialog)
238 : : {
239 [ + - ]: 1 : g_assert (VALENT_IS_SHARE_TEXT_DIALOG (dialog));
240 : :
241 : 1 : return dialog->text;
242 : : }
243 : :
244 : : /**
245 : : * valent_share_text_dialog_set_text:
246 : : * @self: a `ValentShareTextDialog`
247 : : * @text: (nullable): text content
248 : : *
249 : : * Set the text content shared by the remote [class@Valent.Device].
250 : : */
251 : : void
252 : 4 : valent_share_text_dialog_set_text (ValentShareTextDialog *dialog,
253 : : const char *text)
254 : : {
255 [ + - ]: 4 : g_assert (VALENT_IS_SHARE_TEXT_DIALOG (dialog));
256 : :
257 [ + - ]: 4 : if (g_set_str (&dialog->text, text))
258 : : {
259 : 4 : g_autofree char *markup = NULL;
260 : :
261 : 4 : markup = valent_string_to_markup (dialog->text);
262 : 4 : gtk_label_set_markup (dialog->text_label, markup);
263 : 4 : g_object_notify_by_pspec (G_OBJECT (dialog), properties [PROP_TEXT]);
264 : : }
265 : 4 : }
266 : :
|