Port to GTK+-3
[dhcpcd-ui] / src / dhcpcd-gtk / menu.c
1 /*
2  * dhcpcd-gtk
3  * Copyright 2009-2012 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 "config.h"
28 #include "dhcpcd-gtk.h"
29
30 static const char *copyright = "Copyright (c) 2009-2012 Roy Marples";
31 static const char *authors[] = { "Roy Marples <roy@marples.name>", NULL };
32
33 static void
34 on_pref(_unused GObject *o, gpointer data)
35 {
36         dhcpcd_prefs_show((DHCPCD_CONNECTION *)data);
37 }
38
39 static void
40 on_quit(void)
41 {
42         gtk_main_quit();
43 }
44
45 #if GTK_MAJOR_VERSION == 2
46 static void
47 url_show(GtkAboutDialog *dialog, const char *url)
48 {
49         GdkScreen *screen;
50
51         screen = gtk_widget_get_screen(GTK_WIDGET(dialog));
52         gtk_show_uri(screen, url, GDK_CURRENT_TIME, NULL);
53 }
54
55 static void
56 email_hook(GtkAboutDialog *dialog, const char *url, _unused gpointer data)
57 {
58         char *address;
59
60         address = g_strdup_printf("mailto:%s", url);
61         url_show(dialog, address);
62         g_free(address);
63 }
64
65
66 static void
67 url_hook(GtkAboutDialog *dialog, const char *url, _unused gpointer data)
68 {
69         url_show(dialog, url);
70 }
71 #endif
72
73 static void
74 ssid_hook(_unused GtkMenuItem *item, gpointer data)
75 {
76         DHCPCD_WI_SCAN *scan;
77         WI_SCAN *wi;
78
79         scan = (DHCPCD_WI_SCAN *)data;
80         wi = wi_scan_find(scan);
81         if (wi)
82                 wpa_configure(wi->connection, wi->interface, scan);
83 }
84
85 static void
86 on_about(_unused GtkMenuItem *item)
87 {
88         gtk_window_set_default_icon_name("network-transmit-receive");
89 #if GTK_MAJOR_VERSION == 2
90         gtk_about_dialog_set_email_hook(email_hook, NULL, NULL);
91         gtk_about_dialog_set_url_hook(url_hook, NULL, NULL);
92 #endif
93         gtk_show_about_dialog(NULL,
94             "version", VERSION,
95             "copyright", copyright,
96             "website-label", "dhcpcd Website",
97             "website", "http://roy.marples.name/projects/dhcpcd",
98             "authors", authors,
99             "logo-icon-name", "network-transmit-receive",
100             "comments", "Part of the dhcpcd project",
101             NULL);
102 }
103
104 static GtkWidget *
105 add_scans(WI_SCAN *scan)
106 {
107         DHCPCD_WI_SCAN *wis;
108         GtkWidget *menu, *item, *image, *box, *label, *bar;
109         double perc;
110         int strength;
111         const char *icon;
112         char *tip;
113
114         if (scan->scans == NULL)
115                 return NULL;
116         menu = gtk_menu_new();
117         for (wis = scan->scans; wis; wis = wis->next) {
118                 item = gtk_check_menu_item_new();
119                 gtk_check_menu_item_set_draw_as_radio(
120                         GTK_CHECK_MENU_ITEM(item), true); 
121                 box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
122                 gtk_container_add(GTK_CONTAINER(item), box); 
123                 label = gtk_label_new(wis->ssid);
124                 gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 0);
125
126                 if (g_strcmp0(wis->ssid, scan->interface->ssid) == 0)
127                         gtk_check_menu_item_set_active(
128                                 GTK_CHECK_MENU_ITEM(item), true);
129                 if (wis->flags == NULL)
130                         icon = "network-wireless";
131                 else
132                         icon = "network-wireless-encrypted";
133                 image = gtk_image_new_from_icon_name(icon,
134                     GTK_ICON_SIZE_MENU);
135                 gtk_box_pack_start(GTK_BOX(box), image, FALSE, FALSE, 0);
136
137                 bar = gtk_progress_bar_new();
138                 gtk_widget_set_size_request(bar, 100, -1);
139                 gtk_box_pack_end(GTK_BOX(box), bar, FALSE, TRUE, 0);
140                 if (wis->quality.value == 0)
141                         strength = wis->level.average;
142                 else
143                         strength = wis->quality.average;
144                 perc = CLAMP(strength, 0, 100) / 100.0;
145                 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(bar), perc);
146
147                 tip = g_strconcat(wis->bssid, " ", wis->flags, NULL);
148                 gtk_widget_set_tooltip_text(item, tip);
149                 g_free(tip);
150
151                 gtk_widget_show(label);
152                 gtk_widget_show(bar);
153                 gtk_widget_show(image);
154                 gtk_widget_show(box);
155                 g_signal_connect(G_OBJECT(item), "activate",
156                     G_CALLBACK(ssid_hook), wis);
157                 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
158         }
159         return menu;
160 }
161
162 static void
163 on_activate(GtkStatusIcon *icon)
164 {
165         WI_SCAN *w;
166         GtkWidget *menu, *item, *image;
167
168         notify_close();
169         if (wi_scans == NULL)
170                 return;
171         if (wi_scans->next) {
172                 menu = gtk_menu_new();
173                 for (w = wi_scans; w; w = w->next) {
174                         item = gtk_image_menu_item_new_with_label(
175                                 w->interface->ifname);
176                         image = gtk_image_new_from_icon_name(
177                                 "network-wireless", GTK_ICON_SIZE_MENU);
178                         gtk_image_menu_item_set_image(
179                                 GTK_IMAGE_MENU_ITEM(item), image);
180                         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
181                         gtk_menu_item_set_submenu(GTK_MENU_ITEM(item),
182                             add_scans(w));
183                 }
184         } else
185                 menu = add_scans(wi_scans);
186
187         if (menu) {
188                 gtk_widget_show_all(GTK_WIDGET(menu));
189                 gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
190                     gtk_status_icon_position_menu, icon,
191                     1, gtk_get_current_event_time());
192         }
193 }
194
195 static void
196 on_popup(GtkStatusIcon *icon, guint button, guint32 atime, gpointer data)
197 {
198         DHCPCD_CONNECTION *con;
199         GtkMenu *menu;
200         GtkWidget *item, *image;
201
202         notify_close();
203
204         con = (DHCPCD_CONNECTION *)data;
205         menu = (GtkMenu *)gtk_menu_new();
206
207         item = gtk_image_menu_item_new_with_mnemonic(_("_Preferences"));
208         image = gtk_image_new_from_icon_name(GTK_STOCK_PREFERENCES,
209             GTK_ICON_SIZE_MENU);
210         gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
211         if (g_strcmp0(dhcpcd_status(con), "down") == 0)
212                 gtk_widget_set_sensitive(item, false);
213         else
214                 g_signal_connect(G_OBJECT(item), "activate",
215                     G_CALLBACK(on_pref), data);
216         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
217
218         item = gtk_separator_menu_item_new();
219         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
220
221         item = gtk_image_menu_item_new_with_mnemonic(_("_About"));
222         image = gtk_image_new_from_icon_name(GTK_STOCK_ABOUT,
223             GTK_ICON_SIZE_MENU);
224         gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
225         g_signal_connect(G_OBJECT(item), "activate",
226             G_CALLBACK(on_about), icon);
227         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
228
229         item = gtk_image_menu_item_new_with_mnemonic(_("_Quit"));
230         image = gtk_image_new_from_icon_name(GTK_STOCK_QUIT,
231             GTK_ICON_SIZE_MENU);
232         gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
233         g_signal_connect(G_OBJECT(item), "activate",
234             G_CALLBACK(on_quit), icon);
235         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
236
237         gtk_widget_show_all(GTK_WIDGET(menu));
238         gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
239             gtk_status_icon_position_menu, icon, button, atime);
240         if (button == 0)
241                 gtk_menu_shell_select_first(GTK_MENU_SHELL(menu), FALSE);
242 }
243
244 void
245 menu_init(GtkStatusIcon *icon, DHCPCD_CONNECTION *con)
246 {
247         g_signal_connect(G_OBJECT(icon), "activate",
248             G_CALLBACK(on_activate), con);
249         g_signal_connect(G_OBJECT(icon), "popup_menu",
250             G_CALLBACK(on_popup), con);
251 }
252
253
254 #if GTK_MAJOR_VERSION == 2
255 GtkWidget *
256 gtk_box_new(GtkOrientation o, gint s)
257 {
258
259         if (o == GTK_ORIENTATION_HORIZONTAL)
260                 return gtk_hbox_new(false, s);
261         else
262                 return gtk_vbox_new(false, s);
263 }
264 #endif