1 class BridgeDialog : Gtk.Dialog {
2 private const string GCONF_DIR_TOR = "/apps/maemo/tor";
3 private const string GCONF_KEY_BRIDGES = GCONF_DIR_TOR + "/bridges";
6 Gtk.ListStore list_store;
9 * Show the bridge relay configuration dialog
11 private const int RESPONSE_NEW = 1;
12 public BridgeDialog () {
13 var content = (Gtk.VBox) get_content_area ();
14 content.set_size_request (-1, 5*70);
16 set_title (_("Bridge relays"));
18 gconf = GConf.Client.get_default ();
19 var bridges = new SList<string> ();
21 bridges = gconf.get_list (GCONF_KEY_BRIDGES, GConf.ValueType.STRING);
23 Hildon.Banner.show_information (null, null, "Error loading bridges: %s".printf (e.message));
26 list_store = new Gtk.ListStore (1, typeof (string));
28 foreach (string bridge in bridges) {
29 list_store.append (out iter);
30 list_store.@set (iter, 0, bridge);
33 var pannable_area = new Hildon.PannableArea ();
34 var tree_view = new Gtk.TreeView.with_model (list_store);
35 var renderer = new Gtk.CellRendererText ();
36 var column = new Gtk.TreeViewColumn.with_attributes ("IP", renderer, "text", 0);
37 tree_view.append_column (column);
38 pannable_area.add (tree_view);
39 content.pack_start (pannable_area, true, true, 0);
41 tree_view.row_activated.connect ((path, column) => {
42 bridge_edit_dialog (list_store, path);
45 add_button (_("New"), RESPONSE_NEW);
46 response.connect ((response_id) => {
47 if (response_id == RESPONSE_NEW) {
48 bridge_edit_dialog (list_store, null);
56 * Show the bridge relay edit dialog
58 private const int RESPONSE_DELETE = 1;
59 private void bridge_edit_dialog (Gtk.ListStore store, Gtk.TreePath? path) {
60 var dialog = new Gtk.Dialog ();
61 var content = (Gtk.VBox) dialog.get_content_area ();
64 dialog.set_title (_("New bridge relay"));
66 dialog.set_title (_("Edit bridge relay"));
68 var size_group = new Gtk.SizeGroup (Gtk.SizeGroupMode.HORIZONTAL);
70 var hbox = new Gtk.HBox (false, Hildon.MARGIN_DOUBLE);
71 var label = new Gtk.Label (_("IP address"));
72 label.set_alignment (0, 0.5f);
73 size_group.add_widget (label);
74 hbox.pack_start (label, false, false, 0);
75 var ip_entry = new Hildon.Entry (Hildon.SizeType.FINGER_HEIGHT);
76 ip_entry.set ("hildon-input-mode", Hildon.GtkInputMode.NUMERIC |
77 Hildon.GtkInputMode.SPECIAL);
78 hbox.pack_start (ip_entry, true, true, 0);
79 content.pack_start (hbox, false, false, 0);
81 hbox = new Gtk.HBox (false, Hildon.MARGIN_DOUBLE);
82 label = new Gtk.Label (_("Port"));
83 label.set_alignment (0, 0.5f);
84 size_group.add_widget (label);
85 hbox.pack_start (label, false, false, 0);
86 var port_entry = new Hildon.Entry (Hildon.SizeType.FINGER_HEIGHT);
87 port_entry.set ("hildon-input-mode", Hildon.GtkInputMode.NUMERIC);
88 hbox.pack_start (port_entry, true, true, 0);
89 content.pack_start (hbox, true, true, 0);
91 hbox = new Gtk.HBox (false, Hildon.MARGIN_DOUBLE);
92 label = new Gtk.Label (_("Fingerprint"));
93 label.set_alignment (0, 0.5f);
94 size_group.add_widget (label);
95 hbox.pack_start (label, false, false, 0);
96 var fingerprint_entry = new Hildon.Entry (Hildon.SizeType.FINGER_HEIGHT);
97 fingerprint_entry.set ("hildon-input-mode", Hildon.GtkInputMode.HEXA);
98 hbox.pack_start (fingerprint_entry, true, true, 0);
99 content.pack_start (hbox, true, true, 0);
101 var iter = Gtk.TreeIter ();
103 port_entry.set_text ("443");
104 } else if (store.get_iter (out iter, path)) {
106 store.@get (iter, 0, out tmp);
107 string[] ip_port = tmp.split (":");
108 if (ip_port.length == 2) {
109 ip_entry.set_text (ip_port[0]);
110 port_entry.set_text (ip_port[1]);
113 dialog.add_button (_("Delete"), RESPONSE_DELETE);
115 dialog.add_button (_("Save"), Gtk.ResponseType.OK);
116 dialog.response.connect ((response_id) => {
117 var bridges = new SList<string> ();
119 if (response_id == RESPONSE_DELETE) {
122 store.get_iter (out iter2, path);
123 store.remove (iter2);
125 if (store.get_iter_first (out iter2)) do {
126 store.@get (iter2, 0, out bridge);
127 bridges.append (bridge);
128 } while (store.iter_next (ref iter2));
130 gconf.set_list (GCONF_KEY_BRIDGES,
131 GConf.ValueType.STRING,
134 Hildon.Banner.show_information (dialog, null,
135 "Failed to save bridge relay list: %s".printf (e.message));
140 if (response_id == Gtk.ResponseType.OK) {
141 if (!is_valid_ip_address (ip_entry.get_text ())) {
142 Hildon.Banner.show_information (dialog, null,
143 _("Invalid IP address"));
146 int port = port_entry.get_text ().to_int ();
147 if (port < 0 || port > 65565) {
148 Hildon.Banner.show_information (dialog, null,
149 _("Invalid port number"));
154 store.append (out iter2);
156 store.get_iter (out iter2, path);
158 store.@set (iter2, 0, "%s:%d".printf (ip_entry.get_text (), port));
160 bridges = gconf.get_list (GCONF_KEY_BRIDGES,
161 GConf.ValueType.STRING);
163 Hildon.Banner.show_information (null, null,
164 "Error loading bridges: %s".printf (e.message));
167 bridges.append ("%s:%d".printf (ip_entry.get_text (), port));
171 if (store.get_iter_first (out iter2)) do {
172 store.@get (iter2, 0, out bridge);
173 bridges.append (bridge);
174 } while (store.iter_next (ref iter2));
177 gconf.set_list (GCONF_KEY_BRIDGES,
178 GConf.ValueType.STRING,
181 Hildon.Banner.show_information (dialog, null,
182 "Failed to save bridge relay list: %s".printf (e.message));
193 * Check whether the IP address consists of four numbers in the 0..255 range
195 bool is_valid_ip_address (string address) {
196 string[] ip = address.split (".");
201 for (int i = 0; i < ip.length; i++) {
202 int n = ip[i].to_int ();
203 if (n < 0 || n > 255)