summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/ui/crumbs/hig/simplesettingsdialog.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/ui/crumbs/hig/simplesettingsdialog.py')
-rw-r--r--bitbake/lib/bb/ui/crumbs/hig/simplesettingsdialog.py891
1 files changed, 891 insertions, 0 deletions
diff --git a/bitbake/lib/bb/ui/crumbs/hig/simplesettingsdialog.py b/bitbake/lib/bb/ui/crumbs/hig/simplesettingsdialog.py
new file mode 100644
index 0000000000..b5eb3d8738
--- /dev/null
+++ b/bitbake/lib/bb/ui/crumbs/hig/simplesettingsdialog.py
@@ -0,0 +1,891 @@
1#
2# BitBake Graphical GTK User Interface
3#
4# Copyright (C) 2011-2012 Intel Corporation
5#
6# Authored by Joshua Lock <josh@linux.intel.com>
7# Authored by Dongxiao Xu <dongxiao.xu@intel.com>
8# Authored by Shane Wang <shane.wang@intel.com>
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License version 2 as
12# published by the Free Software Foundation.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License along
20# with this program; if not, write to the Free Software Foundation, Inc.,
21# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
23import gtk
24import gobject
25import hashlib
26from bb.ui.crumbs.hobwidget import hic, HobInfoButton, HobButton, HobAltButton
27from bb.ui.crumbs.progressbar import HobProgressBar
28from bb.ui.crumbs.hig.settingsuihelper import SettingsUIHelper
29from bb.ui.crumbs.hig.crumbsdialog import CrumbsDialog
30from bb.ui.crumbs.hig.crumbsmessagedialog import CrumbsMessageDialog
31from bb.ui.crumbs.hig.proxydetailsdialog import ProxyDetailsDialog
32
33"""
34The following are convenience classes for implementing GNOME HIG compliant
35BitBake GUI's
36In summary: spacing = 12px, border-width = 6px
37"""
38
39class SimpleSettingsDialog (CrumbsDialog, SettingsUIHelper):
40
41 (BUILD_ENV_PAGE_ID,
42 SHARED_STATE_PAGE_ID,
43 PROXIES_PAGE_ID,
44 OTHERS_PAGE_ID) = range(4)
45
46 (TEST_NETWORK_NONE,
47 TEST_NETWORK_INITIAL,
48 TEST_NETWORK_RUNNING,
49 TEST_NETWORK_PASSED,
50 TEST_NETWORK_FAILED,
51 TEST_NETWORK_CANCELED) = range(6)
52
53 TARGETS = [
54 ("MY_TREE_MODEL_ROW", gtk.TARGET_SAME_WIDGET, 0),
55 ("text/plain", 0, 1),
56 ("TEXT", 0, 2),
57 ("STRING", 0, 3),
58 ]
59
60 def __init__(self, title, configuration, all_image_types,
61 all_package_formats, all_distros, all_sdk_machines,
62 max_threads, parent, flags, handler, buttons=None):
63 super(SimpleSettingsDialog, self).__init__(title, parent, flags, buttons)
64
65 # class members from other objects
66 # bitbake settings from Builder.Configuration
67 self.configuration = configuration
68 self.image_types = all_image_types
69 self.all_package_formats = all_package_formats
70 self.all_distros = all_distros
71 self.all_sdk_machines = all_sdk_machines
72 self.max_threads = max_threads
73
74 # class members for internal use
75 self.dldir_text = None
76 self.sstatedir_text = None
77 self.sstatemirrors_list = []
78 self.sstatemirrors_changed = 0
79 self.bb_spinner = None
80 self.pmake_spinner = None
81 self.rootfs_size_spinner = None
82 self.extra_size_spinner = None
83 self.gplv3_checkbox = None
84 self.toolchain_checkbox = None
85 self.setting_store = None
86 self.image_types_checkbuttons = {}
87
88 self.md5 = self.config_md5()
89 self.proxy_md5 = self.config_proxy_md5()
90 self.settings_changed = False
91 self.proxy_settings_changed = False
92 self.handler = handler
93 self.proxy_test_ran = False
94 self.selected_mirror_row = 0
95 self.new_mirror = False
96
97 # create visual elements on the dialog
98 self.create_visual_elements()
99 self.connect("response", self.response_cb)
100
101 def _get_sorted_value(self, var):
102 return " ".join(sorted(str(var).split())) + "\n"
103
104 def config_proxy_md5(self):
105 data = ("ENABLE_PROXY: " + self._get_sorted_value(self.configuration.enable_proxy))
106 if self.configuration.enable_proxy:
107 for protocol in self.configuration.proxies.keys():
108 data += (protocol + ": " + self._get_sorted_value(self.configuration.combine_proxy(protocol)))
109 return hashlib.md5(data).hexdigest()
110
111 def config_md5(self):
112 data = ""
113 for key in self.configuration.extra_setting.keys():
114 data += (key + ": " + self._get_sorted_value(self.configuration.extra_setting[key]))
115 return hashlib.md5(data).hexdigest()
116
117 def gen_proxy_entry_widget(self, protocol, parent, need_button=True, line=0):
118 label = gtk.Label(protocol.upper() + " proxy")
119 self.proxy_table.attach(label, 0, 1, line, line+1, xpadding=24)
120
121 proxy_entry = gtk.Entry()
122 proxy_entry.set_size_request(300, -1)
123 self.proxy_table.attach(proxy_entry, 1, 2, line, line+1, ypadding=4)
124
125 self.proxy_table.attach(gtk.Label(":"), 2, 3, line, line+1, xpadding=12, ypadding=4)
126
127 port_entry = gtk.Entry()
128 port_entry.set_size_request(60, -1)
129 self.proxy_table.attach(port_entry, 3, 4, line, line+1, ypadding=4)
130
131 details_button = HobAltButton("Details")
132 details_button.connect("clicked", self.details_cb, parent, protocol)
133 self.proxy_table.attach(details_button, 4, 5, line, line+1, xpadding=4, yoptions=gtk.EXPAND)
134
135 return proxy_entry, port_entry, details_button
136
137 def refresh_proxy_components(self):
138 self.same_checkbox.set_sensitive(self.configuration.enable_proxy)
139
140 self.http_proxy.set_text(self.configuration.combine_host_only("http"))
141 self.http_proxy.set_editable(self.configuration.enable_proxy)
142 self.http_proxy.set_sensitive(self.configuration.enable_proxy)
143 self.http_proxy_port.set_text(self.configuration.combine_port_only("http"))
144 self.http_proxy_port.set_editable(self.configuration.enable_proxy)
145 self.http_proxy_port.set_sensitive(self.configuration.enable_proxy)
146 self.http_proxy_details.set_sensitive(self.configuration.enable_proxy)
147
148 self.https_proxy.set_text(self.configuration.combine_host_only("https"))
149 self.https_proxy.set_editable(self.configuration.enable_proxy and (not self.configuration.same_proxy))
150 self.https_proxy.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
151 self.https_proxy_port.set_text(self.configuration.combine_port_only("https"))
152 self.https_proxy_port.set_editable(self.configuration.enable_proxy and (not self.configuration.same_proxy))
153 self.https_proxy_port.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
154 self.https_proxy_details.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
155
156 self.ftp_proxy.set_text(self.configuration.combine_host_only("ftp"))
157 self.ftp_proxy.set_editable(self.configuration.enable_proxy and (not self.configuration.same_proxy))
158 self.ftp_proxy.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
159 self.ftp_proxy_port.set_text(self.configuration.combine_port_only("ftp"))
160 self.ftp_proxy_port.set_editable(self.configuration.enable_proxy and (not self.configuration.same_proxy))
161 self.ftp_proxy_port.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
162 self.ftp_proxy_details.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
163
164 self.socks_proxy.set_text(self.configuration.combine_host_only("socks"))
165 self.socks_proxy.set_editable(self.configuration.enable_proxy and (not self.configuration.same_proxy))
166 self.socks_proxy.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
167 self.socks_proxy_port.set_text(self.configuration.combine_port_only("socks"))
168 self.socks_proxy_port.set_editable(self.configuration.enable_proxy and (not self.configuration.same_proxy))
169 self.socks_proxy_port.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
170 self.socks_proxy_details.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
171
172 self.cvs_proxy.set_text(self.configuration.combine_host_only("cvs"))
173 self.cvs_proxy.set_editable(self.configuration.enable_proxy and (not self.configuration.same_proxy))
174 self.cvs_proxy.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
175 self.cvs_proxy_port.set_text(self.configuration.combine_port_only("cvs"))
176 self.cvs_proxy_port.set_editable(self.configuration.enable_proxy and (not self.configuration.same_proxy))
177 self.cvs_proxy_port.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
178 self.cvs_proxy_details.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
179
180 if self.configuration.same_proxy:
181 if self.http_proxy.get_text():
182 [w.set_text(self.http_proxy.get_text()) for w in self.same_proxy_addresses]
183 if self.http_proxy_port.get_text():
184 [w.set_text(self.http_proxy_port.get_text()) for w in self.same_proxy_ports]
185
186 def proxy_checkbox_toggled_cb(self, button):
187 self.configuration.enable_proxy = self.proxy_checkbox.get_active()
188 if not self.configuration.enable_proxy:
189 self.configuration.same_proxy = False
190 self.same_checkbox.set_active(self.configuration.same_proxy)
191 self.save_proxy_data()
192 self.refresh_proxy_components()
193
194 def same_checkbox_toggled_cb(self, button):
195 self.configuration.same_proxy = self.same_checkbox.get_active()
196 self.save_proxy_data()
197 self.refresh_proxy_components()
198
199 def save_proxy_data(self):
200 self.configuration.split_proxy("http", self.http_proxy.get_text() + ":" + self.http_proxy_port.get_text())
201 if self.configuration.same_proxy:
202 self.configuration.split_proxy("https", self.http_proxy.get_text() + ":" + self.http_proxy_port.get_text())
203 self.configuration.split_proxy("ftp", self.http_proxy.get_text() + ":" + self.http_proxy_port.get_text())
204 self.configuration.split_proxy("socks", self.http_proxy.get_text() + ":" + self.http_proxy_port.get_text())
205 self.configuration.split_proxy("cvs", self.http_proxy.get_text() + ":" + self.http_proxy_port.get_text())
206 else:
207 self.configuration.split_proxy("https", self.https_proxy.get_text() + ":" + self.https_proxy_port.get_text())
208 self.configuration.split_proxy("ftp", self.ftp_proxy.get_text() + ":" + self.ftp_proxy_port.get_text())
209 self.configuration.split_proxy("socks", self.socks_proxy.get_text() + ":" + self.socks_proxy_port.get_text())
210 self.configuration.split_proxy("cvs", self.cvs_proxy.get_text() + ":" + self.cvs_proxy_port.get_text())
211
212 def response_cb(self, dialog, response_id):
213 if response_id == gtk.RESPONSE_YES:
214 if self.proxy_checkbox.get_active():
215 # Check that all proxy entries have a corresponding port
216 for proxy, port in zip(self.all_proxy_addresses, self.all_proxy_ports):
217 if proxy.get_text() and not port.get_text():
218 lbl = "<b>Enter all port numbers</b>"
219 msg = "Proxy servers require a port number. Please make sure you have entered a port number for each proxy server."
220 dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_WARNING, msg)
221 button = dialog.add_button("Close", gtk.RESPONSE_OK)
222 HobButton.style_button(button)
223 response = dialog.run()
224 dialog.destroy()
225 self.emit_stop_by_name("response")
226 return
227
228 self.configuration.dldir = self.dldir_text.get_text()
229 self.configuration.sstatedir = self.sstatedir_text.get_text()
230 self.configuration.sstatemirror = ""
231 for mirror in self.sstatemirrors_list:
232 if mirror[1] != "" and mirror[2].startswith("file://"):
233 smirror = mirror[2] + " " + mirror[1] + " \\n "
234 self.configuration.sstatemirror += smirror
235 self.configuration.bbthread = self.bb_spinner.get_value_as_int()
236 self.configuration.pmake = self.pmake_spinner.get_value_as_int()
237 self.save_proxy_data()
238 self.configuration.extra_setting = {}
239 it = self.setting_store.get_iter_first()
240 while it:
241 key = self.setting_store.get_value(it, 0)
242 value = self.setting_store.get_value(it, 1)
243 self.configuration.extra_setting[key] = value
244 it = self.setting_store.iter_next(it)
245
246 md5 = self.config_md5()
247 self.settings_changed = (self.md5 != md5)
248 self.proxy_settings_changed = (self.proxy_md5 != self.config_proxy_md5())
249
250 def create_build_environment_page(self):
251 advanced_vbox = gtk.VBox(False, 6)
252 advanced_vbox.set_border_width(6)
253
254 advanced_vbox.pack_start(self.gen_label_widget('<span weight="bold">Parallel threads</span>'), expand=False, fill=False)
255 sub_vbox = gtk.VBox(False, 6)
256 advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
257 label = self.gen_label_widget("BitBake parallel threads")
258 tooltip = "Sets the number of threads that BitBake tasks can simultaneously run. See the <a href=\""
259 tooltip += "http://www.yoctoproject.org/docs/current/poky-ref-manual/"
260 tooltip += "poky-ref-manual.html#var-BB_NUMBER_THREADS\">Poky reference manual</a> for information"
261 bbthread_widget, self.bb_spinner = self.gen_spinner_widget(self.configuration.bbthread, 1, self.max_threads,"<b>BitBake prallalel threads</b>" + "*" + tooltip)
262 sub_vbox.pack_start(label, expand=False, fill=False)
263 sub_vbox.pack_start(bbthread_widget, expand=False, fill=False)
264
265 sub_vbox = gtk.VBox(False, 6)
266 advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
267 label = self.gen_label_widget("Make parallel threads")
268 tooltip = "Sets the maximum number of threads the host can use during the build. See the <a href=\""
269 tooltip += "http://www.yoctoproject.org/docs/current/poky-ref-manual/"
270 tooltip += "poky-ref-manual.html#var-PARALLEL_MAKE\">Poky reference manual</a> for information"
271 pmake_widget, self.pmake_spinner = self.gen_spinner_widget(self.configuration.pmake, 1, self.max_threads,"<b>Make parallel threads</b>" + "*" + tooltip)
272 sub_vbox.pack_start(label, expand=False, fill=False)
273 sub_vbox.pack_start(pmake_widget, expand=False, fill=False)
274
275 advanced_vbox.pack_start(self.gen_label_widget('<span weight="bold">Downloaded source code</span>'), expand=False, fill=False)
276 sub_vbox = gtk.VBox(False, 6)
277 advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
278 label = self.gen_label_widget("Downloads directory")
279 tooltip = "Select a folder that caches the upstream project source code"
280 dldir_widget, self.dldir_text = self.gen_entry_widget(self.configuration.dldir, self,"<b>Downloaded source code</b>" + "*" + tooltip)
281 sub_vbox.pack_start(label, expand=False, fill=False)
282 sub_vbox.pack_start(dldir_widget, expand=False, fill=False)
283
284 return advanced_vbox
285
286 def create_shared_state_page(self):
287 advanced_vbox = gtk.VBox(False)
288 advanced_vbox.set_border_width(12)
289
290 sub_vbox = gtk.VBox(False)
291 advanced_vbox.pack_start(sub_vbox, expand=False, fill=False, padding=24)
292 content = "<span>Shared state directory</span>"
293 tooltip = "Select a folder that caches your prebuilt results"
294 label = self.gen_label_info_widget(content,"<b>Shared state directory</b>" + "*" + tooltip)
295 sstatedir_widget, self.sstatedir_text = self.gen_entry_widget(self.configuration.sstatedir, self)
296 sub_vbox.pack_start(label, expand=False, fill=False)
297 sub_vbox.pack_start(sstatedir_widget, expand=False, fill=False, padding=6)
298
299 content = "<span weight=\"bold\">Shared state mirrors</span>"
300 tooltip = "URLs pointing to pre-built mirrors that will speed your build. "
301 tooltip += "Select the \'Standard\' configuration if the structure of your "
302 tooltip += "mirror replicates the structure of your local shared state directory. "
303 tooltip += "For more information on shared state mirrors, check the <a href=\""
304 tooltip += "http://www.yoctoproject.org/docs/current/poky-ref-manual/"
305 tooltip += "poky-ref-manual.html#shared-state\">Yocto Project Reference Manual</a>."
306 table = self.gen_label_info_widget(content,"<b>Shared state mirrors</b>" + "*" + tooltip)
307 advanced_vbox.pack_start(table, expand=False, fill=False, padding=6)
308
309 sub_vbox = gtk.VBox(False)
310 advanced_vbox.pack_start(sub_vbox, gtk.TRUE, gtk.TRUE, 0)
311
312 if self.sstatemirrors_changed == 0:
313 self.sstatemirrors_changed = 1
314 sstatemirrors = self.configuration.sstatemirror
315 if sstatemirrors == "":
316 sm_list = ["Standard", "", "file://(.*)"]
317 self.sstatemirrors_list.append(sm_list)
318 else:
319 sstatemirrors = [x for x in sstatemirrors.split('\\n')]
320 for sstatemirror in sstatemirrors:
321 sstatemirror_fields = [x for x in sstatemirror.split(' ') if x.strip()]
322 if len(sstatemirror_fields) == 2:
323 if sstatemirror_fields[0] == "file://(.*)" or sstatemirror_fields[0] == "file://.*":
324 sm_list = ["Standard", sstatemirror_fields[1], sstatemirror_fields[0]]
325 else:
326 sm_list = ["Custom", sstatemirror_fields[1], sstatemirror_fields[0]]
327 self.sstatemirrors_list.append(sm_list)
328
329 sstatemirrors_widget, sstatemirrors_store = self.gen_shared_sstate_widget(self.sstatemirrors_list, self)
330 sub_vbox.pack_start(sstatemirrors_widget, expand=True, fill=True)
331
332 table = gtk.Table(1, 10, False)
333 table.set_col_spacings(6)
334 add_mirror_button = HobAltButton("Add mirror")
335 add_mirror_button.connect("clicked", self.add_mirror)
336 add_mirror_button.set_size_request(120,30)
337 table.attach(add_mirror_button, 1, 2, 0, 1, xoptions=gtk.SHRINK)
338
339 self.delete_button = HobAltButton("Delete mirror")
340 self.delete_button.connect("clicked", self.delete_cb)
341 self.delete_button.set_size_request(120, 30)
342 table.attach(self.delete_button, 3, 4, 0, 1, xoptions=gtk.SHRINK)
343
344 advanced_vbox.pack_start(table, expand=False, fill=False, padding=6)
345
346 return advanced_vbox
347
348 def gen_shared_sstate_widget(self, sstatemirrors_list, window):
349 hbox = gtk.HBox(False)
350
351 sstatemirrors_store = gtk.ListStore(str, str, str)
352 for sstatemirror in sstatemirrors_list:
353 sstatemirrors_store.append(sstatemirror)
354
355 self.sstatemirrors_tv = gtk.TreeView()
356 self.sstatemirrors_tv.set_rules_hint(True)
357 self.sstatemirrors_tv.set_headers_visible(True)
358 tree_selection = self.sstatemirrors_tv.get_selection()
359 tree_selection.set_mode(gtk.SELECTION_SINGLE)
360
361 # Allow enable drag and drop of rows including row move
362 self.sstatemirrors_tv.enable_model_drag_source( gtk.gdk.BUTTON1_MASK,
363 self.TARGETS,
364 gtk.gdk.ACTION_DEFAULT|
365 gtk.gdk.ACTION_MOVE)
366 self.sstatemirrors_tv.enable_model_drag_dest(self.TARGETS,
367 gtk.gdk.ACTION_DEFAULT)
368 self.sstatemirrors_tv.connect("drag_data_get", self.drag_data_get_cb)
369 self.sstatemirrors_tv.connect("drag_data_received", self.drag_data_received_cb)
370
371
372 self.scroll = gtk.ScrolledWindow()
373 self.scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
374 self.scroll.set_shadow_type(gtk.SHADOW_IN)
375 self.scroll.connect('size-allocate', self.scroll_changed)
376 self.scroll.add(self.sstatemirrors_tv)
377
378 #list store for cell renderer
379 m = gtk.ListStore(gobject.TYPE_STRING)
380 m.append(["Standard"])
381 m.append(["Custom"])
382
383 cell0 = gtk.CellRendererCombo()
384 cell0.set_property("model",m)
385 cell0.set_property("text-column", 0)
386 cell0.set_property("editable", True)
387 cell0.set_property("has-entry", False)
388 col0 = gtk.TreeViewColumn("Configuration")
389 col0.pack_start(cell0, False)
390 col0.add_attribute(cell0, "text", 0)
391 col0.set_cell_data_func(cell0, self.configuration_field)
392 self.sstatemirrors_tv.append_column(col0)
393
394 cell0.connect("edited", self.combo_changed, sstatemirrors_store)
395
396 self.cell1 = gtk.CellRendererText()
397 self.cell1.set_padding(5,2)
398 col1 = gtk.TreeViewColumn('Regex', self.cell1)
399 col1.set_cell_data_func(self.cell1, self.regex_field)
400 self.sstatemirrors_tv.append_column(col1)
401
402 self.cell1.connect("edited", self.regex_changed, sstatemirrors_store)
403
404 cell2 = gtk.CellRendererText()
405 cell2.set_padding(5,2)
406 cell2.set_property("editable", True)
407 col2 = gtk.TreeViewColumn('URL', cell2)
408 col2.set_cell_data_func(cell2, self.url_field)
409 self.sstatemirrors_tv.append_column(col2)
410
411 cell2.connect("edited", self.url_changed, sstatemirrors_store)
412
413 self.sstatemirrors_tv.set_model(sstatemirrors_store)
414 self.sstatemirrors_tv.set_cursor(self.selected_mirror_row)
415 hbox.pack_start(self.scroll, expand=True, fill=True)
416 hbox.show_all()
417
418 return hbox, sstatemirrors_store
419
420 def drag_data_get_cb(self, treeview, context, selection, target_id, etime):
421 treeselection = treeview.get_selection()
422 model, iter = treeselection.get_selected()
423 data = model.get_string_from_iter(iter)
424 selection.set(selection.target, 8, data)
425
426 def drag_data_received_cb(self, treeview, context, x, y, selection, info, etime):
427 model = treeview.get_model()
428 data = []
429 tree_iter = model.get_iter_from_string(selection.data)
430 data.append(model.get_value(tree_iter, 0))
431 data.append(model.get_value(tree_iter, 1))
432 data.append(model.get_value(tree_iter, 2))
433
434 drop_info = treeview.get_dest_row_at_pos(x, y)
435 if drop_info:
436 path, position = drop_info
437 iter = model.get_iter(path)
438 if (position == gtk.TREE_VIEW_DROP_BEFORE or position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE):
439 model.insert_before(iter, data)
440 else:
441 model.insert_after(iter, data)
442 else:
443 model.append(data)
444 if context.action == gtk.gdk.ACTION_MOVE:
445 context.finish(True, True, etime)
446 return
447
448 def delete_cb(self, button):
449 selection = self.sstatemirrors_tv.get_selection()
450 tree_model, tree_iter = selection.get_selected()
451 index = int(tree_model.get_string_from_iter(tree_iter))
452 if index == 0:
453 self.selected_mirror_row = index
454 else:
455 self.selected_mirror_row = index - 1
456 self.sstatemirrors_list.pop(index)
457 self.refresh_shared_state_page()
458 if not self.sstatemirrors_list:
459 self.delete_button.set_sensitive(False)
460
461 def add_mirror(self, button):
462 self.new_mirror = True
463 tooltip = "Select the pre-built mirror that will speed your build"
464 index = len(self.sstatemirrors_list)
465 self.selected_mirror_row = index
466 sm_list = ["Standard", "", "file://(.*)"]
467 self.sstatemirrors_list.append(sm_list)
468 self.refresh_shared_state_page()
469
470 def scroll_changed(self, widget, event, data=None):
471 if self.new_mirror == True:
472 adj = widget.get_vadjustment()
473 adj.set_value(adj.upper - adj.page_size)
474 self.new_mirror = False
475
476 def combo_changed(self, widget, path, text, model):
477 model[path][0] = text
478 selection = self.sstatemirrors_tv.get_selection()
479 tree_model, tree_iter = selection.get_selected()
480 index = int(tree_model.get_string_from_iter(tree_iter))
481 self.sstatemirrors_list[index][0] = text
482
483 def regex_changed(self, cell, path, new_text, user_data):
484 user_data[path][2] = new_text
485 selection = self.sstatemirrors_tv.get_selection()
486 tree_model, tree_iter = selection.get_selected()
487 index = int(tree_model.get_string_from_iter(tree_iter))
488 self.sstatemirrors_list[index][2] = new_text
489 return
490
491 def url_changed(self, cell, path, new_text, user_data):
492 if new_text!="Enter the mirror URL" and new_text!="Match regex and replace it with this URL":
493 user_data[path][1] = new_text
494 selection = self.sstatemirrors_tv.get_selection()
495 tree_model, tree_iter = selection.get_selected()
496 index = int(tree_model.get_string_from_iter(tree_iter))
497 self.sstatemirrors_list[index][1] = new_text
498 return
499
500 def configuration_field(self, column, cell, model, iter):
501 cell.set_property('text', model.get_value(iter, 0))
502 if model.get_value(iter, 0) == "Standard":
503 self.cell1.set_property("sensitive", False)
504 self.cell1.set_property("editable", False)
505 else:
506 self.cell1.set_property("sensitive", True)
507 self.cell1.set_property("editable", True)
508 return
509
510 def regex_field(self, column, cell, model, iter):
511 cell.set_property('text', model.get_value(iter, 2))
512 return
513
514 def url_field(self, column, cell, model, iter):
515 text = model.get_value(iter, 1)
516 if text == "":
517 if model.get_value(iter, 0) == "Standard":
518 text = "Enter the mirror URL"
519 else:
520 text = "Match regex and replace it with this URL"
521 cell.set_property('text', text)
522 return
523
524 def refresh_shared_state_page(self):
525 page_num = self.nb.get_current_page()
526 self.nb.remove_page(page_num);
527 self.nb.insert_page(self.create_shared_state_page(), gtk.Label("Shared state"),page_num)
528 self.show_all()
529 self.nb.set_current_page(page_num)
530
531 def test_proxy_ended(self, passed):
532 self.proxy_test_running = False
533 self.set_test_proxy_state(self.TEST_NETWORK_PASSED if passed else self.TEST_NETWORK_FAILED)
534 self.set_sensitive(True)
535 self.refresh_proxy_components()
536
537 def timer_func(self):
538 self.test_proxy_progress.pulse()
539 return self.proxy_test_running
540
541 def test_network_button_cb(self, b):
542 self.set_test_proxy_state(self.TEST_NETWORK_RUNNING)
543 self.set_sensitive(False)
544 self.save_proxy_data()
545 if self.configuration.enable_proxy == True:
546 self.handler.set_http_proxy(self.configuration.combine_proxy("http"))
547 self.handler.set_https_proxy(self.configuration.combine_proxy("https"))
548 self.handler.set_ftp_proxy(self.configuration.combine_proxy("ftp"))
549 self.handler.set_socks_proxy(self.configuration.combine_proxy("socks"))
550 self.handler.set_cvs_proxy(self.configuration.combine_host_only("cvs"), self.configuration.combine_port_only("cvs"))
551 elif self.configuration.enable_proxy == False:
552 self.handler.set_http_proxy("")
553 self.handler.set_https_proxy("")
554 self.handler.set_ftp_proxy("")
555 self.handler.set_socks_proxy("")
556 self.handler.set_cvs_proxy("", "")
557 self.proxy_test_ran = True
558 self.proxy_test_running = True
559 gobject.timeout_add(100, self.timer_func)
560 self.handler.trigger_network_test()
561
562 def test_proxy_focus_event(self, w, direction):
563 if self.test_proxy_state in [self.TEST_NETWORK_PASSED, self.TEST_NETWORK_FAILED]:
564 self.set_test_proxy_state(self.TEST_NETWORK_INITIAL)
565 return False
566
567 def http_proxy_changed(self, e):
568 if not self.configuration.same_proxy:
569 return
570 if e == self.http_proxy:
571 [w.set_text(self.http_proxy.get_text()) for w in self.same_proxy_addresses]
572 else:
573 [w.set_text(self.http_proxy_port.get_text()) for w in self.same_proxy_ports]
574
575 def proxy_address_focus_out_event(self, w, direction):
576 text = w.get_text()
577 if not text:
578 return False
579 if text.find("//") == -1:
580 w.set_text("http://" + text)
581 return False
582
583 def set_test_proxy_state(self, state):
584 if self.test_proxy_state == state:
585 return
586 [self.proxy_table.remove(w) for w in self.test_gui_elements]
587 if state == self.TEST_NETWORK_INITIAL:
588 self.proxy_table.attach(self.test_network_button, 1, 2, 5, 6)
589 self.test_network_button.show()
590 elif state == self.TEST_NETWORK_RUNNING:
591 self.test_proxy_progress.set_rcstyle("running")
592 self.test_proxy_progress.set_text("Testing network configuration")
593 self.proxy_table.attach(self.test_proxy_progress, 0, 5, 5, 6, xpadding=4)
594 self.test_proxy_progress.show()
595 else: # passed or failed
596 self.dummy_progress.update(1.0)
597 if state == self.TEST_NETWORK_PASSED:
598 self.dummy_progress.set_text("Your network is properly configured")
599 self.dummy_progress.set_rcstyle("running")
600 else:
601 self.dummy_progress.set_text("Network test failed")
602 self.dummy_progress.set_rcstyle("fail")
603 self.proxy_table.attach(self.dummy_progress, 0, 4, 5, 6)
604 self.proxy_table.attach(self.retest_network_button, 4, 5, 5, 6, xpadding=4)
605 self.dummy_progress.show()
606 self.retest_network_button.show()
607 self.test_proxy_state = state
608
609 def create_network_page(self):
610 advanced_vbox = gtk.VBox(False, 6)
611 advanced_vbox.set_border_width(6)
612 self.same_proxy_addresses = []
613 self.same_proxy_ports = []
614 self.all_proxy_ports = []
615 self.all_proxy_addresses = []
616
617 sub_vbox = gtk.VBox(False, 6)
618 advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
619 label = self.gen_label_widget("<span weight=\"bold\">Set the proxies used when fetching source code</span>")
620 tooltip = "Set the proxies used when fetching source code. A blank field uses a direct internet connection."
621 info = HobInfoButton("<span weight=\"bold\">Set the proxies used when fetching source code</span>" + "*" + tooltip, self)
622 hbox = gtk.HBox(False, 12)
623 hbox.pack_start(label, expand=True, fill=True)
624 hbox.pack_start(info, expand=False, fill=False)
625 sub_vbox.pack_start(hbox, expand=False, fill=False)
626
627 proxy_test_focus = []
628 self.direct_checkbox = gtk.RadioButton(None, "Direct network connection")
629 proxy_test_focus.append(self.direct_checkbox)
630 self.direct_checkbox.set_tooltip_text("Check this box to use a direct internet connection with no proxy")
631 self.direct_checkbox.set_active(not self.configuration.enable_proxy)
632 sub_vbox.pack_start(self.direct_checkbox, expand=False, fill=False)
633
634 self.proxy_checkbox = gtk.RadioButton(self.direct_checkbox, "Manual proxy configuration")
635 proxy_test_focus.append(self.proxy_checkbox)
636 self.proxy_checkbox.set_tooltip_text("Check this box to manually set up a specific proxy")
637 self.proxy_checkbox.set_active(self.configuration.enable_proxy)
638 sub_vbox.pack_start(self.proxy_checkbox, expand=False, fill=False)
639
640 self.same_checkbox = gtk.CheckButton("Use the HTTP proxy for all protocols")
641 proxy_test_focus.append(self.same_checkbox)
642 self.same_checkbox.set_tooltip_text("Check this box to use the HTTP proxy for all five proxies")
643 self.same_checkbox.set_active(self.configuration.same_proxy)
644 hbox = gtk.HBox(False, 12)
645 hbox.pack_start(self.same_checkbox, expand=False, fill=False, padding=24)
646 sub_vbox.pack_start(hbox, expand=False, fill=False)
647
648 self.proxy_table = gtk.Table(6, 5, False)
649 self.http_proxy, self.http_proxy_port, self.http_proxy_details = self.gen_proxy_entry_widget(
650 "http", self, True, 0)
651 proxy_test_focus +=[self.http_proxy, self.http_proxy_port]
652 self.http_proxy.connect("changed", self.http_proxy_changed)
653 self.http_proxy_port.connect("changed", self.http_proxy_changed)
654
655 self.https_proxy, self.https_proxy_port, self.https_proxy_details = self.gen_proxy_entry_widget(
656 "https", self, True, 1)
657 proxy_test_focus += [self.https_proxy, self.https_proxy_port]
658 self.same_proxy_addresses.append(self.https_proxy)
659 self.same_proxy_ports.append(self.https_proxy_port)
660
661 self.ftp_proxy, self.ftp_proxy_port, self.ftp_proxy_details = self.gen_proxy_entry_widget(
662 "ftp", self, True, 2)
663 proxy_test_focus += [self.ftp_proxy, self.ftp_proxy_port]
664 self.same_proxy_addresses.append(self.ftp_proxy)
665 self.same_proxy_ports.append(self.ftp_proxy_port)
666
667 self.socks_proxy, self.socks_proxy_port, self.socks_proxy_details = self.gen_proxy_entry_widget(
668 "socks", self, True, 3)
669 proxy_test_focus += [self.socks_proxy, self.socks_proxy_port]
670 self.same_proxy_addresses.append(self.socks_proxy)
671 self.same_proxy_ports.append(self.socks_proxy_port)
672
673 self.cvs_proxy, self.cvs_proxy_port, self.cvs_proxy_details = self.gen_proxy_entry_widget(
674 "cvs", self, True, 4)
675 proxy_test_focus += [self.cvs_proxy, self.cvs_proxy_port]
676 self.same_proxy_addresses.append(self.cvs_proxy)
677 self.same_proxy_ports.append(self.cvs_proxy_port)
678 self.all_proxy_ports = self.same_proxy_ports + [self.http_proxy_port]
679 self.all_proxy_addresses = self.same_proxy_addresses + [self.http_proxy]
680 sub_vbox.pack_start(self.proxy_table, expand=False, fill=False)
681 self.proxy_table.show_all()
682
683 # Create the graphical elements for the network test feature, but don't display them yet
684 self.test_network_button = HobAltButton("Test network configuration")
685 self.test_network_button.connect("clicked", self.test_network_button_cb)
686 self.test_proxy_progress = HobProgressBar()
687 self.dummy_progress = HobProgressBar()
688 self.retest_network_button = HobAltButton("Retest")
689 self.retest_network_button.connect("clicked", self.test_network_button_cb)
690 self.test_gui_elements = [self.test_network_button, self.test_proxy_progress, self.dummy_progress, self.retest_network_button]
691 # Initialize the network tester
692 self.test_proxy_state = self.TEST_NETWORK_NONE
693 self.set_test_proxy_state(self.TEST_NETWORK_INITIAL)
694 self.proxy_test_passed_id = self.handler.connect("network-passed", lambda h:self.test_proxy_ended(True))
695 self.proxy_test_failed_id = self.handler.connect("network-failed", lambda h:self.test_proxy_ended(False))
696 [w.connect("focus-in-event", self.test_proxy_focus_event) for w in proxy_test_focus]
697 [w.connect("focus-out-event", self.proxy_address_focus_out_event) for w in self.all_proxy_addresses]
698
699 self.direct_checkbox.connect("toggled", self.proxy_checkbox_toggled_cb)
700 self.proxy_checkbox.connect("toggled", self.proxy_checkbox_toggled_cb)
701 self.same_checkbox.connect("toggled", self.same_checkbox_toggled_cb)
702
703 self.refresh_proxy_components()
704 return advanced_vbox
705
706 def switch_to_page(self, page_id):
707 self.nb.set_current_page(page_id)
708
709 def details_cb(self, button, parent, protocol):
710 self.save_proxy_data()
711 dialog = ProxyDetailsDialog(title = protocol.upper() + " Proxy Details",
712 user = self.configuration.proxies[protocol][1],
713 passwd = self.configuration.proxies[protocol][2],
714 parent = parent,
715 flags = gtk.DIALOG_MODAL
716 | gtk.DIALOG_DESTROY_WITH_PARENT
717 | gtk.DIALOG_NO_SEPARATOR)
718 dialog.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_OK)
719 response = dialog.run()
720 if response == gtk.RESPONSE_OK:
721 self.configuration.proxies[protocol][1] = dialog.user
722 self.configuration.proxies[protocol][2] = dialog.passwd
723 self.refresh_proxy_components()
724 dialog.destroy()
725
726 def rootfs_combo_changed_cb(self, rootfs_combo, all_package_format, check_hbox):
727 combo_item = self.rootfs_combo.get_active_text()
728 for child in check_hbox.get_children():
729 if isinstance(child, gtk.CheckButton):
730 check_hbox.remove(child)
731 for format in all_package_format:
732 if format != combo_item:
733 check_button = gtk.CheckButton(format)
734 check_hbox.pack_start(check_button, expand=False, fill=False)
735 check_hbox.show_all()
736
737 def gen_pkgfmt_widget(self, curr_package_format, all_package_format, tooltip_combo="", tooltip_extra=""):
738 pkgfmt_hbox = gtk.HBox(False, 24)
739
740 rootfs_vbox = gtk.VBox(False, 6)
741 pkgfmt_hbox.pack_start(rootfs_vbox, expand=False, fill=False)
742
743 label = self.gen_label_widget("Root file system package format")
744 rootfs_vbox.pack_start(label, expand=False, fill=False)
745
746 rootfs_format = ""
747 if curr_package_format:
748 rootfs_format = curr_package_format.split()[0]
749
750 rootfs_format_widget, rootfs_combo = self.gen_combo_widget(rootfs_format, all_package_format, tooltip_combo)
751 rootfs_vbox.pack_start(rootfs_format_widget, expand=False, fill=False)
752
753 extra_vbox = gtk.VBox(False, 6)
754 pkgfmt_hbox.pack_start(extra_vbox, expand=False, fill=False)
755
756 label = self.gen_label_widget("Additional package formats")
757 extra_vbox.pack_start(label, expand=False, fill=False)
758
759 check_hbox = gtk.HBox(False, 12)
760 extra_vbox.pack_start(check_hbox, expand=False, fill=False)
761 for format in all_package_format:
762 if format != rootfs_format:
763 check_button = gtk.CheckButton(format)
764 is_active = (format in curr_package_format.split())
765 check_button.set_active(is_active)
766 check_hbox.pack_start(check_button, expand=False, fill=False)
767
768 info = HobInfoButton(tooltip_extra, self)
769 check_hbox.pack_end(info, expand=False, fill=False)
770
771 rootfs_combo.connect("changed", self.rootfs_combo_changed_cb, all_package_format, check_hbox)
772
773 pkgfmt_hbox.show_all()
774
775 return pkgfmt_hbox, rootfs_combo, check_hbox
776
777 def editable_settings_cell_edited(self, cell, path_string, new_text, model):
778 it = model.get_iter_from_string(path_string)
779 column = cell.get_data("column")
780 model.set(it, column, new_text)
781
782 def editable_settings_add_item_clicked(self, button, model):
783 new_item = ["##KEY##", "##VALUE##"]
784
785 iter = model.append()
786 model.set (iter,
787 0, new_item[0],
788 1, new_item[1],
789 )
790
791 def editable_settings_remove_item_clicked(self, button, treeview):
792 selection = treeview.get_selection()
793 model, iter = selection.get_selected()
794
795 if iter:
796 path = model.get_path(iter)[0]
797 model.remove(iter)
798
799 def gen_editable_settings(self, setting, tooltip=""):
800 setting_hbox = gtk.HBox(False, 12)
801
802 vbox = gtk.VBox(False, 12)
803 setting_hbox.pack_start(vbox, expand=True, fill=True)
804
805 setting_store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
806 for key in setting.keys():
807 setting_store.set(setting_store.append(), 0, key, 1, setting[key])
808
809 setting_tree = gtk.TreeView(setting_store)
810 setting_tree.set_headers_visible(True)
811 setting_tree.set_size_request(300, 100)
812
813 col = gtk.TreeViewColumn('Key')
814 col.set_min_width(100)
815 col.set_max_width(150)
816 col.set_resizable(True)
817 col1 = gtk.TreeViewColumn('Value')
818 col1.set_min_width(100)
819 col1.set_max_width(150)
820 col1.set_resizable(True)
821 setting_tree.append_column(col)
822 setting_tree.append_column(col1)
823 cell = gtk.CellRendererText()
824 cell.set_property('width-chars', 10)
825 cell.set_property('editable', True)
826 cell.set_data("column", 0)
827 cell.connect("edited", self.editable_settings_cell_edited, setting_store)
828 cell1 = gtk.CellRendererText()
829 cell1.set_property('width-chars', 10)
830 cell1.set_property('editable', True)
831 cell1.set_data("column", 1)
832 cell1.connect("edited", self.editable_settings_cell_edited, setting_store)
833 col.pack_start(cell, True)
834 col1.pack_end(cell1, True)
835 col.set_attributes(cell, text=0)
836 col1.set_attributes(cell1, text=1)
837
838 scroll = gtk.ScrolledWindow()
839 scroll.set_shadow_type(gtk.SHADOW_IN)
840 scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
841 scroll.add(setting_tree)
842 vbox.pack_start(scroll, expand=True, fill=True)
843
844 # some buttons
845 hbox = gtk.HBox(True, 6)
846 vbox.pack_start(hbox, False, False)
847
848 button = gtk.Button(stock=gtk.STOCK_ADD)
849 button.connect("clicked", self.editable_settings_add_item_clicked, setting_store)
850 hbox.pack_start(button)
851
852 button = gtk.Button(stock=gtk.STOCK_REMOVE)
853 button.connect("clicked", self.editable_settings_remove_item_clicked, setting_tree)
854 hbox.pack_start(button)
855
856 info = HobInfoButton(tooltip, self)
857 setting_hbox.pack_start(info, expand=False, fill=False)
858
859 return setting_hbox, setting_store
860
861 def create_others_page(self):
862 advanced_vbox = gtk.VBox(False, 6)
863 advanced_vbox.set_border_width(6)
864
865 sub_vbox = gtk.VBox(False, 6)
866 advanced_vbox.pack_start(sub_vbox, expand=True, fill=True)
867 label = self.gen_label_widget("<span weight=\"bold\">Add your own variables:</span>")
868 tooltip = "These are key/value pairs for your extra settings. Click \'Add\' and then directly edit the key and the value"
869 setting_widget, self.setting_store = self.gen_editable_settings(self.configuration.extra_setting,"<b>Add your own variables</b>" + "*" + tooltip)
870 sub_vbox.pack_start(label, expand=False, fill=False)
871 sub_vbox.pack_start(setting_widget, expand=True, fill=True)
872
873 return advanced_vbox
874
875 def create_visual_elements(self):
876 self.nb = gtk.Notebook()
877 self.nb.set_show_tabs(True)
878 self.nb.append_page(self.create_build_environment_page(), gtk.Label("Build environment"))
879 self.nb.append_page(self.create_shared_state_page(), gtk.Label("Shared state"))
880 self.nb.append_page(self.create_network_page(), gtk.Label("Network"))
881 self.nb.append_page(self.create_others_page(), gtk.Label("Others"))
882 self.nb.set_current_page(0)
883 self.vbox.pack_start(self.nb, expand=True, fill=True)
884 self.vbox.pack_end(gtk.HSeparator(), expand=True, fill=True)
885
886 self.show_all()
887
888 def destroy(self):
889 self.handler.disconnect(self.proxy_test_passed_id)
890 self.handler.disconnect(self.proxy_test_failed_id)
891 super(SimpleSettingsDialog, self).destroy()