We should use gettext.
[dhcpcd-ui] / menu.c
1 /*
2  * dhcpcd-gtk
3  * Copyright 2009 Roy Marples <roy@marples.name>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 #include "dhcpcd-gtk.h"
28 #include "menu.h"
29
30 static const char *copyright = "Copyright (c) 2009 Roy Marples";
31
32 static const char *authors[] = {
33         "Roy Marples <roy@marples.name>",
34         NULL
35 };
36 static const char *license[] = {
37         "Licensed under the 2 clause BSD license.\n",
38         "Redistribution and use in source and binary forms, with or without\n"
39         "modification, are permitted provided that the following conditions\n"
40         "are met:\n",
41         "1. Redistributions of source code must retain the above copyright\n"
42         "   notice, this list of conditions and the following disclaimer.\n",
43         "2. Redistributions in binary form must reproduce the above copyright\n"
44         "   notice, this list of conditions and the following disclaimer in the\n"
45         "   documentation and/or other materials provided with the distribution.\n",
46         "THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n"
47         "ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n"
48         "IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n"
49         "ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n"
50         "FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n"
51         "DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n"
52         "OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n"
53         "HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n"
54         "LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n"
55         "OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n"
56         "SUCH DAMAGE.",
57         NULL
58 };
59
60 static void
61 on_quit(_unused GtkMenuItem *item, _unused gpointer data)
62 {
63         gtk_main_quit();
64 }
65
66 static void
67 on_help(_unused GtkMenuItem *item, _unused gpointer data)
68 {
69 }
70
71 static void
72 url_show(GtkAboutDialog *dialog, const char *url)
73 {
74         GdkScreen *screen;
75
76         screen = gtk_widget_get_screen(GTK_WIDGET(dialog));
77         gtk_show_uri(screen, url, GDK_CURRENT_TIME, NULL);
78 }
79
80 static void
81 email_hook(GtkAboutDialog *dialog, const char *url, _unused gpointer p)
82 {
83         char *address;
84
85         address = g_strdup_printf("mailto:%s", url);
86         url_show(dialog, address);
87         g_free(address);
88 }
89
90 static void
91 url_hook(GtkAboutDialog *dialog, const char *url, _unused gpointer p)
92 {
93         url_show(dialog, url);
94 }
95
96 static void
97 on_about(_unused GtkMenuItem *item, _unused gpointer data)
98 {
99         char *l;
100
101         l = g_strconcat(_(license[0]), "\n",
102                         _(license[1]), "\n",
103                         _(license[2]), "\n",
104                         _(license[3]), "\n",
105                         _(license[4]), "\n",
106                         NULL);
107         gtk_window_set_default_icon_name(GTK_STOCK_NETWORK);
108         gtk_about_dialog_set_email_hook(email_hook, NULL, NULL);
109         gtk_about_dialog_set_url_hook(url_hook, NULL, NULL);
110         gtk_show_about_dialog(NULL,
111                               "version", VERSION,
112                               "copyright", copyright,
113                               "license", l,
114                               "website-label", "dhcpcd Website",
115                               "website", "http://roy.marples.name/projects/dhcpcd",
116                               "authors", authors,
117                               "logo-icon-name", GTK_STOCK_NETWORK,
118                               NULL);
119         g_free(l);
120 }
121
122 static void
123 add_scan_results(GtkMenu *menu, const struct if_msg *ifm)
124 {
125         GList *gl;
126         const struct if_ap *ifa;
127         GtkWidget *item, *image;
128
129         for (gl = ifm->scan_results; gl; gl = gl->next) {
130                 ifa = (const struct if_ap *)gl->data;
131                 item = gtk_image_menu_item_new_with_label(ifa->ssid);
132                 image = gtk_image_new_from_icon_name("network-wireless",
133                                                      GTK_ICON_SIZE_MENU);
134                 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
135                 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
136         }
137 }
138
139 static void
140 on_activate(GtkStatusIcon *icon, _unused guint button, _unused guint32 atime, _unused gpointer data)
141 {
142         GtkMenu *menu;
143         const struct if_msg *ifm;
144         GList *gl;
145         size_t n;
146
147         notify_close();
148
149         n = 0;
150         for (gl = interfaces; gl; gl = gl->next) {
151                 ifm = (const struct if_msg *)gl->data;
152                 if (ifm->wireless)
153                         if (++n > 1)
154                                 break;
155         }
156         if (n == 0)
157                 return;
158
159         menu = (GtkMenu *)gtk_menu_new();
160
161         for (gl = interfaces; gl; gl = gl->next) {
162                 ifm = (const struct if_msg *)gl->data;
163                 if (!ifm->wireless)
164                         continue;
165                 if (n == 1) {
166                         add_scan_results(menu, ifm);
167                         break;
168                 }
169 #if 0
170                 item = gtk_image_menu_item_new_with_label(ifm->name);
171                 image = gtk_image_new_from_icon_name("network-wireless",
172                                                      GTK_ICON_SIZE_MENU);
173                 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
174
175                 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
176 #endif
177         }
178         gtk_widget_show_all(GTK_WIDGET(menu));
179         gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
180                        gtk_status_icon_position_menu, icon,
181                        1, gtk_get_current_event_time());
182 }
183
184 static void
185 on_popup(GtkStatusIcon *icon, guint button, guint32 atime, gpointer data)
186 {
187         GtkMenu *menu;
188         GtkWidget *item, *image;
189
190         notify_close();
191
192         menu = (GtkMenu *)gtk_menu_new();
193
194         item = gtk_image_menu_item_new_with_mnemonic(_("_Quit"));
195         image = gtk_image_new_from_icon_name(GTK_STOCK_QUIT,
196                                              GTK_ICON_SIZE_MENU);
197         gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
198         g_signal_connect(G_OBJECT(item), "activate",
199                          G_CALLBACK(on_quit), icon);
200         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
201
202         item = gtk_separator_menu_item_new();
203         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
204
205         item = gtk_image_menu_item_new_with_mnemonic(_("_Help"));
206         image = gtk_image_new_from_icon_name(GTK_STOCK_HELP,
207                                              GTK_ICON_SIZE_MENU);
208         gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
209         g_signal_connect(G_OBJECT(item), "activate",
210                          G_CALLBACK(on_help), icon);
211         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
212
213         item = gtk_image_menu_item_new_with_mnemonic(_("_About"));
214         image = gtk_image_new_from_icon_name(GTK_STOCK_ABOUT,
215                                              GTK_ICON_SIZE_MENU);
216         gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
217         g_signal_connect(G_OBJECT(item), "activate",
218                          G_CALLBACK(on_about), icon);
219         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
220
221         gtk_widget_show_all(GTK_WIDGET(menu));
222         gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
223                        gtk_status_icon_position_menu, data, button, atime);
224         if (button == 0)
225                 gtk_menu_shell_select_first(GTK_MENU_SHELL(menu), FALSE);
226 }
227
228 void
229 menu_init(GtkStatusIcon *icon)
230 {
231         g_signal_connect_object(G_OBJECT(icon), "activate",
232                                 G_CALLBACK(on_activate), icon, 0);
233         g_signal_connect_object(G_OBJECT(icon), "popup_menu",
234                                 G_CALLBACK(on_popup), icon, 0);
235 }