]> gitweb.michael.orlitzky.com - xfce4-hdaps.git/blob - panel-plugin/xfce4-hdaps-dialogs.c
panel-plugin: switch from xfce-panel-plugin.h to libxfce4panel.h.
[xfce4-hdaps.git] / panel-plugin / xfce4-hdaps-dialogs.c
1 /*
2 * xfce4-hdaps, an XFCE4 panel plugin for the HDAPS system.
3 *
4 * Copyright (C) 2019 Michael Orlitzky
5 *
6 * http://michael.orlitzky.com/
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as
10 * published by the Free Software Foundation, either version 3 of the
11 * License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Affero General Public License for more details:
17 *
18 * https://www.gnu.org/licenses/agpl-3.0.html
19 *
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <string.h>
27 #include <gtk/gtk.h>
28 #include <libxfce4ui/libxfce4ui.h>
29 #include <libxfce4panel/libxfce4panel.h>
30 #include "xfce4-hdaps-dialogs.h"
31 #include "hdaps.h"
32
33 /* Wild guess. Actually borrowed from some code
34 I copy-and-pasted. Doesn't seem too ugly. */
35 #define DEFAULT_BORDER_WIDTH 8
36
37 /* If people can't read the README, well maybe
38 * they can do it /online/.
39 */
40 #define PLUGIN_WEBSITE "http://michael.orlitzky.com/code/xfce4-hdaps.xhtml"
41
42 /* Launch a URI using either gtk_show_uri_on_window (gvfs), exo-open
43 * or xdg-open. This is used both when you click the author's email
44 * address, and when you visit the plugin's homepage.
45 */
46 static gboolean launch_uri(GtkWindow *parent, const gchar *uri) {
47 GError *error = NULL;
48 gboolean result = gtk_show_uri_on_window(parent,
49 uri,
50 GDK_CURRENT_TIME,
51 &error);
52 /* First, let's try what the GTK docs say the default is. */
53 if (result == TRUE) {
54 return result;
55 }
56 else {
57 g_warning(_("Error launching URI %s: %s"), uri, error->message);
58 g_error_free(error);
59 }
60
61 /* Ok, GTK failed, on to the fallbacks. Let's try exo-open first,
62 since it's part of XFCE. */
63 gchar *cmd = g_strdup_printf("%s %s","exo-open", uri);
64 result = g_spawn_command_line_async(cmd, NULL);
65
66 if (G_UNLIKELY(result == FALSE)) {
67 g_warning(_("Unable to open URI with exo-open, trying xdg-open: %s"), uri);
68 g_free(cmd);
69 cmd = g_strdup_printf("%s %s","xdg-open", uri);
70 result = g_spawn_command_line_async(cmd, NULL);
71 if (G_UNLIKELY(result == FALSE)) {
72 g_warning(_("Unable to open URI with xdg-open, giving up: %s"), uri);
73 }
74 }
75
76 g_free(cmd);
77
78 return result;
79 }
80
81
82 static void hdaps_configure_response(GtkDialog *dialog,
83 gint response,
84 HdapsPlugin *hdaps) {
85 if (response == GTK_RESPONSE_HELP) {
86 launch_uri(GTK_WINDOW(dialog), PLUGIN_WEBSITE);
87 return;
88 }
89
90
91 if (response == GTK_RESPONSE_OK) {
92 /* This corresponds to the "Save" button, so we
93 want to save any settings that may have changed. */
94 g_object_set_data(G_OBJECT(hdaps->plugin), "dialog", NULL);
95 hdaps->poll_frequency = gtk_spin_button_get_value_as_int((GtkSpinButton*)hdaps->sb_poll_frequency);
96 hdaps->device_name = gtk_combo_box_text_get_active_text((GtkComboBoxText*)hdaps->cb_device_name);
97 snprintf(hdaps->sysfs_file,
98 FILENAME_MAX,
99 UNLOAD_HEADS_FMT,
100 hdaps->device_name);
101 hdaps_save(hdaps->plugin, hdaps);
102 hdaps_reset_timeout(hdaps);
103 }
104
105
106 /* Since there is already a "save" button, we should ignore
107 any changes that were made if the user presses "cancel"
108 instead. */
109 g_object_set_data(G_OBJECT(hdaps->plugin), "dialog", NULL);
110 xfce_panel_plugin_unblock_menu(hdaps->plugin);
111 gtk_widget_destroy(GTK_WIDGET(dialog));
112
113 return;
114 }
115
116
117
118 void hdaps_configure(XfcePanelPlugin *plugin,
119 HdapsPlugin *hdaps) {
120
121 /* Here comes a bunch of GTK garbage to create the
122 settings dialog. */
123
124 GtkWidget *dialog;
125 GtkWidget *label;
126 GtkWidget *vbox;
127 GtkWidget *hbox;
128 GtkSizeGroup *sg;
129
130 /* Block the plugin menu while the configuration
131 dialogue is open. Don't forget to unblock it before
132 we close. */
133 xfce_panel_plugin_block_menu(plugin);
134
135 /* Create the dialog */
136 dialog = xfce_titled_dialog_new_with_buttons(
137 _("Hdaps Plugin"),
138 GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(plugin))),
139 GTK_DIALOG_DESTROY_WITH_PARENT,
140 "gtk-help", GTK_RESPONSE_HELP,
141 "gtk-save", GTK_RESPONSE_OK,
142 "gtk-cancel", GTK_RESPONSE_CANCEL,
143 NULL);
144
145 /* Center the dialog on screen. */
146 gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
147
148 /* Set dialog icon to a generic settings icon. */
149 gtk_window_set_icon_name(GTK_WINDOW(dialog), "xfce4-settings");
150
151 /* Link the dialog to the plugin, so we can destroy it in case
152 * the plugin is closed while the dialog is still open. */
153 g_object_set_data(G_OBJECT(plugin), "dialog", dialog);
154
155 /* Connect the reponse signal to the dialog. */
156 g_signal_connect(G_OBJECT (dialog), "response",
157 G_CALLBACK(hdaps_configure_response), hdaps);
158
159
160 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, DEFAULT_BORDER_WIDTH);
161 gtk_container_set_border_width(GTK_CONTAINER(vbox), DEFAULT_BORDER_WIDTH - 2);
162 gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
163 vbox, TRUE, TRUE, 0);
164
165 /* Create size group to keep widgets aligned */
166 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
167
168 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DEFAULT_BORDER_WIDTH);
169 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
170
171 label = gtk_label_new(_("Poll Frequency:"));
172 gtk_size_group_add_widget(sg, label);
173 gtk_widget_set_halign(label, 0.0);
174 gtk_widget_set_valign(label, 0.5);
175 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
176
177 hdaps->sb_poll_frequency = gtk_spin_button_new_with_range(100, 5000, 100);
178 gtk_spin_button_set_value((GtkSpinButton*)hdaps->sb_poll_frequency,
179 hdaps->poll_frequency);
180
181 gtk_box_pack_start(GTK_BOX(hbox),
182 hdaps->sb_poll_frequency,
183 FALSE,
184 FALSE,
185 0);
186
187 /* Create the device name dropdown. */
188 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DEFAULT_BORDER_WIDTH);
189 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
190
191 label = gtk_label_new(_("Device Name:"));
192 gtk_size_group_add_widget(sg, label);
193 gtk_widget_set_halign(label, 0.0);
194 gtk_widget_set_valign(label, 0.5);
195 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
196
197 hdaps->cb_device_name = gtk_combo_box_text_new();
198
199 /* Add the current device name, it should always be available.
200 Oh, and it should be the default, too. */
201 gtk_combo_box_text_append_text((GtkComboBoxText*)hdaps->cb_device_name,
202 hdaps->device_name);
203
204 /* This function takes an index, and 0 should be the first
205 (only) index at this point. */
206 gtk_combo_box_set_active((GtkComboBox*)hdaps->cb_device_name, 0);
207
208 /* Now loop through the list of available devices, adding each
209 to the list as we go. */
210 char hdaps_devices[MAX_HDAPS_DEVICES][FILENAME_MAX];
211 int found_devices = get_hdaps_device_list(hdaps_devices);
212 int list_idx = 0;
213
214 for (list_idx = 0; list_idx < found_devices; list_idx++) {
215 /* We don't want to add duplicate entries to the combo box.
216 However, at this point, the current device name should be
217 the only entry. Therefore, to avoid duplicates, we only
218 have to avoid adding the current device name a second time. */
219 if (strcmp(hdaps_devices[list_idx], hdaps->device_name) != 0) {
220 gtk_combo_box_text_append_text((GtkComboBoxText*)hdaps->cb_device_name,
221 hdaps_devices[list_idx]);
222 }
223 }
224
225 gtk_box_pack_start(GTK_BOX(hbox), hdaps->cb_device_name, FALSE, FALSE, 0);
226
227 /* Show the dialog and all of its widgets. */
228 gtk_widget_show_all(dialog);
229 }
230
231
232
233
234 /* URI (http(s):// and mailto://) handler used on the About dialog. */
235 static void hdaps_uri_handler(GtkAboutDialog *about,
236 const gchar *uri,
237 gpointer data) {
238
239 launch_uri(GTK_WINDOW(about), uri);
240 }
241
242 /* "Close" button handler for the About dialog. */
243 static void hdaps_close_handler (GtkAboutDialog *about,
244 gint response_id,
245 gpointer user_data) {
246 /* This will cause the dialog to be destroyed */
247 gtk_widget_destroy(GTK_WIDGET(about));
248 }
249
250 void hdaps_about(XfcePanelPlugin *plugin) {
251 const gchar *authors[] = { "Michael Orlitzky <michael@orlitzky.com>", NULL };
252 const gchar *copyright = "Copyright \302\251 2019 Michael Orlitzky";
253
254 GtkAboutDialog *about = GTK_ABOUT_DIALOG(gtk_about_dialog_new());
255
256 gtk_about_dialog_set_authors(about, authors);
257 gtk_about_dialog_set_copyright(about, copyright);
258 gtk_about_dialog_set_program_name(about, PACKAGE_NAME);
259 gtk_about_dialog_set_logo_icon_name(about, PACKAGE_NAME);
260 gtk_about_dialog_set_license(about, LICENSE_AGPL3);
261 gtk_about_dialog_set_version(about, PACKAGE_VERSION);
262 gtk_about_dialog_set_website(about, PLUGIN_WEBSITE);
263 gtk_about_dialog_set_website_label(about, "xfce4-hdaps homepage");
264
265 /* Use a custom URI handler for http(s):// and mailto:// URIs. The
266 default behavior apparently needs gio/gvfs to work, so we want
267 to add some fallbacks. */
268 g_signal_connect(about,
269 "activate-link",
270 G_CALLBACK(hdaps_uri_handler),
271 NULL);
272
273 /* To close the dialog when "close" is clicked, we have to connect
274 * the response signal to a handler that actually does it.
275 */
276 g_signal_connect(about,
277 "response",
278 G_CALLBACK(hdaps_close_handler),
279 NULL);
280 gtk_widget_show(GTK_WIDGET(about));
281 return;
282 }