1 /* This file is part of status-area-applet-tor.
3 * Copyright (C) 2010-2011 Philipp Zabel
5 * status-area-applet-tor is free software: you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as published
7 * by the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * status-area-applet-tor is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with status-area-applet-tor. If not, see <http://www.gnu.org/licenses/>.
19 class BridgeDialog : Gtk.Dialog {
20 private const string GCONF_DIR_TOR = "/apps/maemo/tor";
21 private const string GCONF_KEY_BRIDGES = GCONF_DIR_TOR + "/bridges";
24 Gtk.ListStore list_store;
27 * Show the bridge relay configuration dialog
29 private const int RESPONSE_NEW = 1;
30 public BridgeDialog () {
31 var content = (Gtk.VBox) get_content_area ();
32 content.set_size_request (-1, 5*70);
34 set_title (_("Bridge relays"));
36 gconf = GConf.Client.get_default ();
37 var bridges = new SList<string> ();
39 bridges = gconf.get_list (GCONF_KEY_BRIDGES, GConf.ValueType.STRING);
41 Hildon.Banner.show_information (null, null, "Error loading bridges: %s".printf (e.message));
44 list_store = new Gtk.ListStore (1, typeof (string));
46 foreach (string bridge in bridges) {
47 list_store.append (out iter);
48 list_store.@set (iter, 0, bridge);
51 var pannable_area = new Hildon.PannableArea ();
52 var tree_view = new Gtk.TreeView.with_model (list_store);
53 var renderer = new Gtk.CellRendererText ();
54 var column = new Gtk.TreeViewColumn.with_attributes ("IP", renderer, "text", 0);
55 tree_view.append_column (column);
56 pannable_area.add (tree_view);
57 content.pack_start (pannable_area, true, true, 0);
59 tree_view.row_activated.connect ((path, column) => {
60 bridge_edit_dialog (list_store, path);
63 add_button (_("New"), RESPONSE_NEW);
64 response.connect ((response_id) => {
65 if (response_id == RESPONSE_NEW) {
66 bridge_edit_dialog (list_store, null);
74 * Show the bridge relay edit dialog
76 private const int RESPONSE_DELETE = 1;
77 private void bridge_edit_dialog (Gtk.ListStore store, Gtk.TreePath? path) {
78 var dialog = new Gtk.Dialog ();
79 var content = (Gtk.VBox) dialog.get_content_area ();
82 dialog.set_title (_("New bridge relay"));
84 dialog.set_title (_("Edit bridge relay"));
86 var size_group = new Gtk.SizeGroup (Gtk.SizeGroupMode.HORIZONTAL);
88 var hbox = new Gtk.HBox (false, Hildon.MARGIN_DOUBLE);
89 var label = new Gtk.Label (_("IP address"));
90 label.set_alignment (0, 0.5f);
91 size_group.add_widget (label);
92 hbox.pack_start (label, false, false, 0);
93 var ip_entry = new Hildon.Entry (Hildon.SizeType.FINGER_HEIGHT);
94 ip_entry.set ("hildon-input-mode", Hildon.GtkInputMode.NUMERIC |
95 Hildon.GtkInputMode.SPECIAL);
96 hbox.pack_start (ip_entry, true, true, 0);
97 content.pack_start (hbox, false, false, 0);
99 hbox = new Gtk.HBox (false, Hildon.MARGIN_DOUBLE);
100 label = new Gtk.Label (_("Port"));
101 label.set_alignment (0, 0.5f);
102 size_group.add_widget (label);
103 hbox.pack_start (label, false, false, 0);
104 var port_entry = new Hildon.Entry (Hildon.SizeType.FINGER_HEIGHT);
105 port_entry.set ("hildon-input-mode", Hildon.GtkInputMode.NUMERIC);
106 hbox.pack_start (port_entry, true, true, 0);
107 content.pack_start (hbox, true, true, 0);
109 hbox = new Gtk.HBox (false, Hildon.MARGIN_DOUBLE);
110 label = new Gtk.Label (_("Fingerprint"));
111 label.set_alignment (0, 0.5f);
112 size_group.add_widget (label);
113 hbox.pack_start (label, false, false, 0);
114 var fingerprint_entry = new Hildon.Entry (Hildon.SizeType.FINGER_HEIGHT);
115 fingerprint_entry.set ("hildon-input-mode", Hildon.GtkInputMode.HEXA);
116 hbox.pack_start (fingerprint_entry, true, true, 0);
117 content.pack_start (hbox, true, true, 0);
119 var iter = Gtk.TreeIter ();
121 port_entry.set_text ("443");
122 } else if (store.get_iter (out iter, path)) {
124 store.@get (iter, 0, out tmp);
125 string[] ip_port = tmp.split (":");
126 if (ip_port.length == 2) {
127 ip_entry.set_text (ip_port[0]);
128 port_entry.set_text (ip_port[1]);
131 dialog.add_button (_("Delete"), RESPONSE_DELETE);
133 dialog.add_button (_("Save"), Gtk.ResponseType.OK);
134 dialog.response.connect ((response_id) => {
135 var bridges = new SList<string> ();
137 if (response_id == RESPONSE_DELETE) {
140 store.get_iter (out iter2, path);
141 store.remove (iter2);
143 if (store.get_iter_first (out iter2)) do {
144 store.@get (iter2, 0, out bridge);
145 bridges.append (bridge);
146 } while (store.iter_next (ref iter2));
148 gconf.set_list (GCONF_KEY_BRIDGES,
149 GConf.ValueType.STRING,
152 Hildon.Banner.show_information (dialog, null,
153 "Failed to save bridge relay list: %s".printf (e.message));
158 if (response_id == Gtk.ResponseType.OK) {
159 if (!is_valid_ip_address (ip_entry.get_text ())) {
160 Hildon.Banner.show_information (dialog, null,
161 _("Invalid IP address"));
164 int port = port_entry.get_text ().to_int ();
165 if (port < 0 || port > 65565) {
166 Hildon.Banner.show_information (dialog, null,
167 _("Invalid port number"));
172 store.append (out iter2);
174 store.get_iter (out iter2, path);
176 store.@set (iter2, 0, "%s:%d".printf (ip_entry.get_text (), port));
178 bridges = gconf.get_list (GCONF_KEY_BRIDGES,
179 GConf.ValueType.STRING);
181 Hildon.Banner.show_information (null, null,
182 "Error loading bridges: %s".printf (e.message));
185 bridges.append ("%s:%d".printf (ip_entry.get_text (), port));
189 if (store.get_iter_first (out iter2)) do {
190 store.@get (iter2, 0, out bridge);
191 bridges.append (bridge);
192 } while (store.iter_next (ref iter2));
195 gconf.set_list (GCONF_KEY_BRIDGES,
196 GConf.ValueType.STRING,
199 Hildon.Banner.show_information (dialog, null,
200 "Failed to save bridge relay list: %s".printf (e.message));
211 * Check whether the IP address consists of four numbers in the 0..255 range
213 bool is_valid_ip_address (string address) {
214 string[] ip = address.split (".");
219 for (int i = 0; i < ip.length; i++) {
220 int n = ip[i].to_int ();
221 if (n < 0 || n > 255)