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.py894
1 files changed, 894 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 0000000..ab5b614
--- /dev/null
+++ b/bitbake/lib/bb/ui/crumbs/hig/simplesettingsdialog.py
@@ -0,0 +1,894 @@
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 if mirror[1].endswith("\\1"):
234 smirror = mirror[2] + " " + mirror[1] + " \\n "
235 else:
236 smirror = mirror[2] + " " + mirror[1] + "\\1 \\n "
237 self.configuration.sstatemirror += smirror
238 self.configuration.bbthread = self.bb_spinner.get_value_as_int()
239 self.configuration.pmake = self.pmake_spinner.get_value_as_int()
240 self.save_proxy_data()
241 self.configuration.extra_setting = {}
242 it = self.setting_store.get_iter_first()
243 while it:
244 key = self.setting_store.get_value(it, 0)
245 value = self.setting_store.get_value(it, 1)
246 self.configuration.extra_setting[key] = value
247 it = self.setting_store.iter_next(it)
248
249 md5 = self.config_md5()
250 self.settings_changed = (self.md5 != md5)
251 self.proxy_settings_changed = (self.proxy_md5 != self.config_proxy_md5())
252
253 def create_build_environment_page(self):
254 advanced_vbox = gtk.VBox(False, 6)
255 advanced_vbox.set_border_width(6)
256
257 advanced_vbox.pack_start(self.gen_label_widget('<span weight="bold">Parallel threads</span>'), expand=False, fill=False)
258 sub_vbox = gtk.VBox(False, 6)
259 advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
260 label = self.gen_label_widget("BitBake parallel threads")
261 tooltip = "Sets the number of threads that BitBake tasks can simultaneously run. See the <a href=\""
262 tooltip += "http://www.yoctoproject.org/docs/current/poky-ref-manual/"
263 tooltip += "poky-ref-manual.html#var-BB_NUMBER_THREADS\">Poky reference manual</a> for information"
264 bbthread_widget, self.bb_spinner = self.gen_spinner_widget(self.configuration.bbthread, 1, self.max_threads,"<b>BitBake prallalel threads</b>" + "*" + tooltip)
265 sub_vbox.pack_start(label, expand=False, fill=False)
266 sub_vbox.pack_start(bbthread_widget, expand=False, fill=False)
267
268 sub_vbox = gtk.VBox(False, 6)
269 advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
270 label = self.gen_label_widget("Make parallel threads")
271 tooltip = "Sets the maximum number of threads the host can use during the build. See the <a href=\""
272 tooltip += "http://www.yoctoproject.org/docs/current/poky-ref-manual/"
273 tooltip += "poky-ref-manual.html#var-PARALLEL_MAKE\">Poky reference manual</a> for information"
274 pmake_widget, self.pmake_spinner = self.gen_spinner_widget(self.configuration.pmake, 1, self.max_threads,"<b>Make parallel threads</b>" + "*" + tooltip)
275 sub_vbox.pack_start(label, expand=False, fill=False)
276 sub_vbox.pack_start(pmake_widget, expand=False, fill=False)
277
278 advanced_vbox.pack_start(self.gen_label_widget('<span weight="bold">Downloaded source code</span>'), expand=False, fill=False)
279 sub_vbox = gtk.VBox(False, 6)
280 advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
281 label = self.gen_label_widget("Downloads directory")
282 tooltip = "Select a folder that caches the upstream project source code"
283 dldir_widget, self.dldir_text = self.gen_entry_widget(self.configuration.dldir, self,"<b>Downloaded source code</b>" + "*" + tooltip)
284 sub_vbox.pack_start(label, expand=False, fill=False)
285 sub_vbox.pack_start(dldir_widget, expand=False, fill=False)
286
287 return advanced_vbox
288
289 def create_shared_state_page(self):
290 advanced_vbox = gtk.VBox(False)
291 advanced_vbox.set_border_width(12)
292
293 sub_vbox = gtk.VBox(False)
294 advanced_vbox.pack_start(sub_vbox, expand=False, fill=False, padding=24)
295 content = "<span>Shared state directory</span>"
296 tooltip = "Select a folder that caches your prebuilt results"
297 label = self.gen_label_info_widget(content,"<b>Shared state directory</b>" + "*" + tooltip)
298 sstatedir_widget, self.sstatedir_text = self.gen_entry_widget(self.configuration.sstatedir, self)
299 sub_vbox.pack_start(label, expand=False, fill=False)
300 sub_vbox.pack_start(sstatedir_widget, expand=False, fill=False, padding=6)
301
302 content = "<span weight=\"bold\">Shared state mirrors</span>"
303 tooltip = "URLs pointing to pre-built mirrors that will speed your build. "
304 tooltip += "Select the \'Standard\' configuration if the structure of your "
305 tooltip += "mirror replicates the structure of your local shared state directory. "
306 tooltip += "For more information on shared state mirrors, check the <a href=\""
307 tooltip += "http://www.yoctoproject.org/docs/current/poky-ref-manual/"
308 tooltip += "poky-ref-manual.html#shared-state\">Yocto Project Reference Manual</a>."
309 table = self.gen_label_info_widget(content,"<b>Shared state mirrors</b>" + "*" + tooltip)
310 advanced_vbox.pack_start(table, expand=False, fill=False, padding=6)
311
312 sub_vbox = gtk.VBox(False)
313 advanced_vbox.pack_start(sub_vbox, gtk.TRUE, gtk.TRUE, 0)
314
315 if self.sstatemirrors_changed == 0:
316 self.sstatemirrors_changed = 1
317 sstatemirrors = self.configuration.sstatemirror
318 if sstatemirrors == "":
319 sm_list = ["Standard", "", "file://(.*)"]
320 self.sstatemirrors_list.append(sm_list)
321 else:
322 sstatemirrors = [x for x in sstatemirrors.split('\\n')]
323 for sstatemirror in sstatemirrors:
324 sstatemirror_fields = [x for x in sstatemirror.split(' ') if x.strip()]
325 if len(sstatemirror_fields) == 2:
326 if sstatemirror_fields[0] == "file://(.*)" or sstatemirror_fields[0] == "file://.*":
327 sm_list = ["Standard", sstatemirror_fields[1], sstatemirror_fields[0]]
328 else:
329 sm_list = ["Custom", sstatemirror_fields[1], sstatemirror_fields[0]]
330 self.sstatemirrors_list.append(sm_list)
331
332 sstatemirrors_widget, sstatemirrors_store = self.gen_shared_sstate_widget(self.sstatemirrors_list, self)
333 sub_vbox.pack_start(sstatemirrors_widget, expand=True, fill=True)
334
335 table = gtk.Table(1, 10, False)
336 table.set_col_spacings(6)
337 add_mirror_button = HobAltButton("Add mirror")
338 add_mirror_button.connect("clicked", self.add_mirror)
339 add_mirror_button.set_size_request(120,30)
340 table.attach(add_mirror_button, 1, 2, 0, 1, xoptions=gtk.SHRINK)
341
342 self.delete_button = HobAltButton("Delete mirror")
343 self.delete_button.connect("clicked", self.delete_cb)
344 self.delete_button.set_size_request(120, 30)
345 table.attach(self.delete_button, 3, 4, 0, 1, xoptions=gtk.SHRINK)
346
347 advanced_vbox.pack_start(table, expand=False, fill=False, padding=6)
348
349 return advanced_vbox
350
351 def gen_shared_sstate_widget(self, sstatemirrors_list, window):
352 hbox = gtk.HBox(False)
353
354 sstatemirrors_store = gtk.ListStore(str, str, str)
355 for sstatemirror in sstatemirrors_list:
356 sstatemirrors_store.append(sstatemirror)
357
358 self.sstatemirrors_tv = gtk.TreeView()
359 self.sstatemirrors_tv.set_rules_hint(True)
360 self.sstatemirrors_tv.set_headers_visible(True)
361 tree_selection = self.sstatemirrors_tv.get_selection()
362 tree_selection.set_mode(gtk.SELECTION_SINGLE)
363
364 # Allow enable drag and drop of rows including row move
365 self.sstatemirrors_tv.enable_model_drag_source( gtk.gdk.BUTTON1_MASK,
366 self.TARGETS,
367 gtk.gdk.ACTION_DEFAULT|
368 gtk.gdk.ACTION_MOVE)
369 self.sstatemirrors_tv.enable_model_drag_dest(self.TARGETS,
370 gtk.gdk.ACTION_DEFAULT)
371 self.sstatemirrors_tv.connect("drag_data_get", self.drag_data_get_cb)
372 self.sstatemirrors_tv.connect("drag_data_received", self.drag_data_received_cb)
373
374
375 self.scroll = gtk.ScrolledWindow()
376 self.scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
377 self.scroll.set_shadow_type(gtk.SHADOW_IN)
378 self.scroll.connect('size-allocate', self.scroll_changed)
379 self.scroll.add(self.sstatemirrors_tv)
380
381 #list store for cell renderer
382 m = gtk.ListStore(gobject.TYPE_STRING)
383 m.append(["Standard"])
384 m.append(["Custom"])
385
386 cell0 = gtk.CellRendererCombo()
387 cell0.set_property("model",m)
388 cell0.set_property("text-column", 0)
389 cell0.set_property("editable", True)
390 cell0.set_property("has-entry", False)
391 col0 = gtk.TreeViewColumn("Configuration")
392 col0.pack_start(cell0, False)
393 col0.add_attribute(cell0, "text", 0)
394 col0.set_cell_data_func(cell0, self.configuration_field)
395 self.sstatemirrors_tv.append_column(col0)
396
397 cell0.connect("edited", self.combo_changed, sstatemirrors_store)
398
399 self.cell1 = gtk.CellRendererText()
400 self.cell1.set_padding(5,2)
401 col1 = gtk.TreeViewColumn('Regex', self.cell1)
402 col1.set_cell_data_func(self.cell1, self.regex_field)
403 self.sstatemirrors_tv.append_column(col1)
404
405 self.cell1.connect("edited", self.regex_changed, sstatemirrors_store)
406
407 cell2 = gtk.CellRendererText()
408 cell2.set_padding(5,2)
409 cell2.set_property("editable", True)
410 col2 = gtk.TreeViewColumn('URL', cell2)
411 col2.set_cell_data_func(cell2, self.url_field)
412 self.sstatemirrors_tv.append_column(col2)
413
414 cell2.connect("edited", self.url_changed, sstatemirrors_store)
415
416 self.sstatemirrors_tv.set_model(sstatemirrors_store)
417 self.sstatemirrors_tv.set_cursor(self.selected_mirror_row)
418 hbox.pack_start(self.scroll, expand=True, fill=True)
419 hbox.show_all()
420
421 return hbox, sstatemirrors_store
422
423 def drag_data_get_cb(self, treeview, context, selection, target_id, etime):
424 treeselection = treeview.get_selection()
425 model, iter = treeselection.get_selected()
426 data = model.get_string_from_iter(iter)
427 selection.set(selection.target, 8, data)
428
429 def drag_data_received_cb(self, treeview, context, x, y, selection, info, etime):
430 model = treeview.get_model()
431 data = []
432 tree_iter = model.get_iter_from_string(selection.data)
433 data.append(model.get_value(tree_iter, 0))
434 data.append(model.get_value(tree_iter, 1))
435 data.append(model.get_value(tree_iter, 2))
436
437 drop_info = treeview.get_dest_row_at_pos(x, y)
438 if drop_info:
439 path, position = drop_info
440 iter = model.get_iter(path)
441 if (position == gtk.TREE_VIEW_DROP_BEFORE or position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE):
442 model.insert_before(iter, data)
443 else:
444 model.insert_after(iter, data)
445 else:
446 model.append(data)
447 if context.action == gtk.gdk.ACTION_MOVE:
448 context.finish(True, True, etime)
449 return
450
451 def delete_cb(self, button):
452 selection = self.sstatemirrors_tv.get_selection()
453 tree_model, tree_iter = selection.get_selected()
454 index = int(tree_model.get_string_from_iter(tree_iter))
455 if index == 0:
456 self.selected_mirror_row = index
457 else:
458 self.selected_mirror_row = index - 1
459 self.sstatemirrors_list.pop(index)
460 self.refresh_shared_state_page()
461 if not self.sstatemirrors_list:
462 self.delete_button.set_sensitive(False)
463
464 def add_mirror(self, button):
465 self.new_mirror = True
466 tooltip = "Select the pre-built mirror that will speed your build"
467 index = len(self.sstatemirrors_list)
468 self.selected_mirror_row = index
469 sm_list = ["Standard", "", "file://(.*)"]
470 self.sstatemirrors_list.append(sm_list)
471 self.refresh_shared_state_page()
472
473 def scroll_changed(self, widget, event, data=None):
474 if self.new_mirror == True:
475 adj = widget.get_vadjustment()
476 adj.set_value(adj.upper - adj.page_size)
477 self.new_mirror = False
478
479 def combo_changed(self, widget, path, text, model):
480 model[path][0] = text
481 selection = self.sstatemirrors_tv.get_selection()
482 tree_model, tree_iter = selection.get_selected()
483 index = int(tree_model.get_string_from_iter(tree_iter))
484 self.sstatemirrors_list[index][0] = text
485
486 def regex_changed(self, cell, path, new_text, user_data):
487 user_data[path][2] = new_text
488 selection = self.sstatemirrors_tv.get_selection()
489 tree_model, tree_iter = selection.get_selected()
490 index = int(tree_model.get_string_from_iter(tree_iter))
491 self.sstatemirrors_list[index][2] = new_text
492 return
493
494 def url_changed(self, cell, path, new_text, user_data):
495 if new_text!="Enter the mirror URL" and new_text!="Match regex and replace it with this URL":
496 user_data[path][1] = new_text
497 selection = self.sstatemirrors_tv.get_selection()
498 tree_model, tree_iter = selection.get_selected()
499 index = int(tree_model.get_string_from_iter(tree_iter))
500 self.sstatemirrors_list[index][1] = new_text
501 return
502
503 def configuration_field(self, column, cell, model, iter):
504 cell.set_property('text', model.get_value(iter, 0))
505 if model.get_value(iter, 0) == "Standard":
506 self.cell1.set_property("sensitive", False)
507 self.cell1.set_property("editable", False)
508 else:
509 self.cell1.set_property("sensitive", True)
510 self.cell1.set_property("editable", True)
511 return
512
513 def regex_field(self, column, cell, model, iter):
514 cell.set_property('text', model.get_value(iter, 2))
515 return
516
517 def url_field(self, column, cell, model, iter):
518 text = model.get_value(iter, 1)
519 if text == "":
520 if model.get_value(iter, 0) == "Standard":
521 text = "Enter the mirror URL"
522 else:
523 text = "Match regex and replace it with this URL"
524 cell.set_property('text', text)
525 return
526
527 def refresh_shared_state_page(self):
528 page_num = self.nb.get_current_page()
529 self.nb.remove_page(page_num);
530 self.nb.insert_page(self.create_shared_state_page(), gtk.Label("Shared state"),page_num)
531 self.show_all()
532 self.nb.set_current_page(page_num)
533
534 def test_proxy_ended(self, passed):
535 self.proxy_test_running = False
536 self.set_test_proxy_state(self.TEST_NETWORK_PASSED if passed else self.TEST_NETWORK_FAILED)
537 self.set_sensitive(True)
538 self.refresh_proxy_components()
539
540 def timer_func(self):
541 self.test_proxy_progress.pulse()
542 return self.proxy_test_running
543
544 def test_network_button_cb(self, b):
545 self.set_test_proxy_state(self.TEST_NETWORK_RUNNING)
546 self.set_sensitive(False)
547 self.save_proxy_data()
548 if self.configuration.enable_proxy == True:
549 self.handler.set_http_proxy(self.configuration.combine_proxy("http"))
550 self.handler.set_https_proxy(self.configuration.combine_proxy("https"))
551 self.handler.set_ftp_proxy(self.configuration.combine_proxy("ftp"))
552 self.handler.set_socks_proxy(self.configuration.combine_proxy("socks"))
553 self.handler.set_cvs_proxy(self.configuration.combine_host_only("cvs"), self.configuration.combine_port_only("cvs"))
554 elif self.configuration.enable_proxy == False:
555 self.handler.set_http_proxy("")
556 self.handler.set_https_proxy("")
557 self.handler.set_ftp_proxy("")
558 self.handler.set_socks_proxy("")
559 self.handler.set_cvs_proxy("", "")
560 self.proxy_test_ran = True
561 self.proxy_test_running = True
562 gobject.timeout_add(100, self.timer_func)
563 self.handler.trigger_network_test()
564
565 def test_proxy_focus_event(self, w, direction):
566 if self.test_proxy_state in [self.TEST_NETWORK_PASSED, self.TEST_NETWORK_FAILED]:
567 self.set_test_proxy_state(self.TEST_NETWORK_INITIAL)
568 return False
569
570 def http_proxy_changed(self, e):
571 if not self.configuration.same_proxy:
572 return
573 if e == self.http_proxy:
574 [w.set_text(self.http_proxy.get_text()) for w in self.same_proxy_addresses]
575 else:
576 [w.set_text(self.http_proxy_port.get_text()) for w in self.same_proxy_ports]
577
578 def proxy_address_focus_out_event(self, w, direction):
579 text = w.get_text()
580 if not text:
581 return False
582 if text.find("//") == -1:
583 w.set_text("http://" + text)
584 return False
585
586 def set_test_proxy_state(self, state):
587 if self.test_proxy_state == state:
588 return
589 [self.proxy_table.remove(w) for w in self.test_gui_elements]
590 if state == self.TEST_NETWORK_INITIAL:
591 self.proxy_table.attach(self.test_network_button, 1, 2, 5, 6)
592 self.test_network_button.show()
593 elif state == self.TEST_NETWORK_RUNNING:
594 self.test_proxy_progress.set_rcstyle("running")
595 self.test_proxy_progress.set_text("Testing network configuration")
596 self.proxy_table.attach(self.test_proxy_progress, 0, 5, 5, 6, xpadding=4)
597 self.test_proxy_progress.show()
598 else: # passed or failed
599 self.dummy_progress.update(1.0)
600 if state == self.TEST_NETWORK_PASSED:
601 self.dummy_progress.set_text("Your network is properly configured")
602 self.dummy_progress.set_rcstyle("running")
603 else:
604 self.dummy_progress.set_text("Network test failed")
605 self.dummy_progress.set_rcstyle("fail")
606 self.proxy_table.attach(self.dummy_progress, 0, 4, 5, 6)
607 self.proxy_table.attach(self.retest_network_button, 4, 5, 5, 6, xpadding=4)
608 self.dummy_progress.show()
609 self.retest_network_button.show()
610 self.test_proxy_state = state
611
612 def create_network_page(self):
613 advanced_vbox = gtk.VBox(False, 6)
614 advanced_vbox.set_border_width(6)
615 self.same_proxy_addresses = []
616 self.same_proxy_ports = []
617 self.all_proxy_ports = []
618 self.all_proxy_addresses = []
619
620 sub_vbox = gtk.VBox(False, 6)
621 advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
622 label = self.gen_label_widget("<span weight=\"bold\">Set the proxies used when fetching source code</span>")
623 tooltip = "Set the proxies used when fetching source code. A blank field uses a direct internet connection."
624 info = HobInfoButton("<span weight=\"bold\">Set the proxies used when fetching source code</span>" + "*" + tooltip, self)
625 hbox = gtk.HBox(False, 12)
626 hbox.pack_start(label, expand=True, fill=True)
627 hbox.pack_start(info, expand=False, fill=False)
628 sub_vbox.pack_start(hbox, expand=False, fill=False)
629
630 proxy_test_focus = []
631 self.direct_checkbox = gtk.RadioButton(None, "Direct network connection")
632 proxy_test_focus.append(self.direct_checkbox)
633 self.direct_checkbox.set_tooltip_text("Check this box to use a direct internet connection with no proxy")
634 self.direct_checkbox.set_active(not self.configuration.enable_proxy)
635 sub_vbox.pack_start(self.direct_checkbox, expand=False, fill=False)
636
637 self.proxy_checkbox = gtk.RadioButton(self.direct_checkbox, "Manual proxy configuration")
638 proxy_test_focus.append(self.proxy_checkbox)
639 self.proxy_checkbox.set_tooltip_text("Check this box to manually set up a specific proxy")
640 self.proxy_checkbox.set_active(self.configuration.enable_proxy)
641 sub_vbox.pack_start(self.proxy_checkbox, expand=False, fill=False)
642
643 self.same_checkbox = gtk.CheckButton("Use the HTTP proxy for all protocols")
644 proxy_test_focus.append(self.same_checkbox)
645 self.same_checkbox.set_tooltip_text("Check this box to use the HTTP proxy for all five proxies")
646 self.same_checkbox.set_active(self.configuration.same_proxy)
647 hbox = gtk.HBox(False, 12)
648 hbox.pack_start(self.same_checkbox, expand=False, fill=False, padding=24)
649 sub_vbox.pack_start(hbox, expand=False, fill=False)
650
651 self.proxy_table = gtk.Table(6, 5, False)
652 self.http_proxy, self.http_proxy_port, self.http_proxy_details = self.gen_proxy_entry_widget(
653 "http", self, True, 0)
654 proxy_test_focus +=[self.http_proxy, self.http_proxy_port]
655 self.http_proxy.connect("changed", self.http_proxy_changed)
656 self.http_proxy_port.connect("changed", self.http_proxy_changed)
657
658 self.https_proxy, self.https_proxy_port, self.https_proxy_details = self.gen_proxy_entry_widget(
659 "https", self, True, 1)
660 proxy_test_focus += [self.https_proxy, self.https_proxy_port]
661 self.same_proxy_addresses.append(self.https_proxy)
662 self.same_proxy_ports.append(self.https_proxy_port)
663
664 self.ftp_proxy, self.ftp_proxy_port, self.ftp_proxy_details = self.gen_proxy_entry_widget(
665 "ftp", self, True, 2)
666 proxy_test_focus += [self.ftp_proxy, self.ftp_proxy_port]
667 self.same_proxy_addresses.append(self.ftp_proxy)
668 self.same_proxy_ports.append(self.ftp_proxy_port)
669
670 self.socks_proxy, self.socks_proxy_port, self.socks_proxy_details = self.gen_proxy_entry_widget(
671 "socks", self, True, 3)
672 proxy_test_focus += [self.socks_proxy, self.socks_proxy_port]
673 self.same_proxy_addresses.append(self.socks_proxy)
674 self.same_proxy_ports.append(self.socks_proxy_port)
675
676 self.cvs_proxy, self.cvs_proxy_port, self.cvs_proxy_details = self.gen_proxy_entry_widget(
677 "cvs", self, True, 4)
678 proxy_test_focus += [self.cvs_proxy, self.cvs_proxy_port]
679 self.same_proxy_addresses.append(self.cvs_proxy)
680 self.same_proxy_ports.append(self.cvs_proxy_port)
681 self.all_proxy_ports = self.same_proxy_ports + [self.http_proxy_port]
682 self.all_proxy_addresses = self.same_proxy_addresses + [self.http_proxy]
683 sub_vbox.pack_start(self.proxy_table, expand=False, fill=False)
684 self.proxy_table.show_all()
685
686 # Create the graphical elements for the network test feature, but don't display them yet
687 self.test_network_button = HobAltButton("Test network configuration")
688 self.test_network_button.connect("clicked", self.test_network_button_cb)
689 self.test_proxy_progress = HobProgressBar()
690 self.dummy_progress = HobProgressBar()
691 self.retest_network_button = HobAltButton("Retest")
692 self.retest_network_button.connect("clicked", self.test_network_button_cb)
693 self.test_gui_elements = [self.test_network_button, self.test_proxy_progress, self.dummy_progress, self.retest_network_button]
694 # Initialize the network tester
695 self.test_proxy_state = self.TEST_NETWORK_NONE
696 self.set_test_proxy_state(self.TEST_NETWORK_INITIAL)
697 self.proxy_test_passed_id = self.handler.connect("network-passed", lambda h:self.test_proxy_ended(True))
698 self.proxy_test_failed_id = self.handler.connect("network-failed", lambda h:self.test_proxy_ended(False))
699 [w.connect("focus-in-event", self.test_proxy_focus_event) for w in proxy_test_focus]
700 [w.connect("focus-out-event", self.proxy_address_focus_out_event) for w in self.all_proxy_addresses]
701
702 self.direct_checkbox.connect("toggled", self.proxy_checkbox_toggled_cb)
703 self.proxy_checkbox.connect("toggled", self.proxy_checkbox_toggled_cb)
704 self.same_checkbox.connect("toggled", self.same_checkbox_toggled_cb)
705
706 self.refresh_proxy_components()
707 return advanced_vbox
708
709 def switch_to_page(self, page_id):
710 self.nb.set_current_page(page_id)
711
712 def details_cb(self, button, parent, protocol):
713 self.save_proxy_data()
714 dialog = ProxyDetailsDialog(title = protocol.upper() + " Proxy Details",
715 user = self.configuration.proxies[protocol][1],
716 passwd = self.configuration.proxies[protocol][2],
717 parent = parent,
718 flags = gtk.DIALOG_MODAL
719 | gtk.DIALOG_DESTROY_WITH_PARENT
720 | gtk.DIALOG_NO_SEPARATOR)
721 dialog.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_OK)
722 response = dialog.run()
723 if response == gtk.RESPONSE_OK:
724 self.configuration.proxies[protocol][1] = dialog.user
725 self.configuration.proxies[protocol][2] = dialog.passwd
726 self.refresh_proxy_components()
727 dialog.destroy()
728
729 def rootfs_combo_changed_cb(self, rootfs_combo, all_package_format, check_hbox):
730 combo_item = self.rootfs_combo.get_active_text()
731 for child in check_hbox.get_children():
732 if isinstance(child, gtk.CheckButton):
733 check_hbox.remove(child)
734 for format in all_package_format:
735 if format != combo_item:
736 check_button = gtk.CheckButton(format)
737 check_hbox.pack_start(check_button, expand=False, fill=False)
738 check_hbox.show_all()
739
740 def gen_pkgfmt_widget(self, curr_package_format, all_package_format, tooltip_combo="", tooltip_extra=""):
741 pkgfmt_hbox = gtk.HBox(False, 24)
742
743 rootfs_vbox = gtk.VBox(False, 6)
744 pkgfmt_hbox.pack_start(rootfs_vbox, expand=False, fill=False)
745
746 label = self.gen_label_widget("Root file system package format")
747 rootfs_vbox.pack_start(label, expand=False, fill=False)
748
749 rootfs_format = ""
750 if curr_package_format:
751 rootfs_format = curr_package_format.split()[0]
752
753 rootfs_format_widget, rootfs_combo = self.gen_combo_widget(rootfs_format, all_package_format, tooltip_combo)
754 rootfs_vbox.pack_start(rootfs_format_widget, expand=False, fill=False)
755
756 extra_vbox = gtk.VBox(False, 6)
757 pkgfmt_hbox.pack_start(extra_vbox, expand=False, fill=False)
758
759 label = self.gen_label_widget("Additional package formats")
760 extra_vbox.pack_start(label, expand=False, fill=False)
761
762 check_hbox = gtk.HBox(False, 12)
763 extra_vbox.pack_start(check_hbox, expand=False, fill=False)
764 for format in all_package_format:
765 if format != rootfs_format:
766 check_button = gtk.CheckButton(format)
767 is_active = (format in curr_package_format.split())
768 check_button.set_active(is_active)
769 check_hbox.pack_start(check_button, expand=False, fill=False)
770
771 info = HobInfoButton(tooltip_extra, self)
772 check_hbox.pack_end(info, expand=False, fill=False)
773
774 rootfs_combo.connect("changed", self.rootfs_combo_changed_cb, all_package_format, check_hbox)
775
776 pkgfmt_hbox.show_all()
777
778 return pkgfmt_hbox, rootfs_combo, check_hbox
779
780 def editable_settings_cell_edited(self, cell, path_string, new_text, model):
781 it = model.get_iter_from_string(path_string)
782 column = cell.get_data("column")
783 model.set(it, column, new_text)
784
785 def editable_settings_add_item_clicked(self, button, model):
786 new_item = ["##KEY##", "##VALUE##"]
787
788 iter = model.append()
789 model.set (iter,
790 0, new_item[0],
791 1, new_item[1],
792 )
793
794 def editable_settings_remove_item_clicked(self, button, treeview):
795 selection = treeview.get_selection()
796 model, iter = selection.get_selected()
797
798 if iter:
799 path = model.get_path(iter)[0]
800 model.remove(iter)
801
802 def gen_editable_settings(self, setting, tooltip=""):
803 setting_hbox = gtk.HBox(False, 12)
804
805 vbox = gtk.VBox(False, 12)
806 setting_hbox.pack_start(vbox, expand=True, fill=True)
807
808 setting_store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
809 for key in setting.keys():
810 setting_store.set(setting_store.append(), 0, key, 1, setting[key])
811
812 setting_tree = gtk.TreeView(setting_store)
813 setting_tree.set_headers_visible(True)
814 setting_tree.set_size_request(300, 100)
815
816 col = gtk.TreeViewColumn('Key')
817 col.set_min_width(100)
818 col.set_max_width(150)
819 col.set_resizable(True)
820 col1 = gtk.TreeViewColumn('Value')
821 col1.set_min_width(100)
822 col1.set_max_width(150)
823 col1.set_resizable(True)
824 setting_tree.append_column(col)
825 setting_tree.append_column(col1)
826 cell = gtk.CellRendererText()
827 cell.set_property('width-chars', 10)
828 cell.set_property('editable', True)
829 cell.set_data("column", 0)
830 cell.connect("edited", self.editable_settings_cell_edited, setting_store)
831 cell1 = gtk.CellRendererText()
832 cell1.set_property('width-chars', 10)
833 cell1.set_property('editable', True)
834 cell1.set_data("column", 1)
835 cell1.connect("edited", self.editable_settings_cell_edited, setting_store)
836 col.pack_start(cell, True)
837 col1.pack_end(cell1, True)
838 col.set_attributes(cell, text=0)
839 col1.set_attributes(cell1, text=1)
840
841 scroll = gtk.ScrolledWindow()
842 scroll.set_shadow_type(gtk.SHADOW_IN)
843 scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
844 scroll.add(setting_tree)
845 vbox.pack_start(scroll, expand=True, fill=True)
846
847 # some buttons
848 hbox = gtk.HBox(True, 6)
849 vbox.pack_start(hbox, False, False)
850
851 button = gtk.Button(stock=gtk.STOCK_ADD)
852 button.connect("clicked", self.editable_settings_add_item_clicked, setting_store)
853 hbox.pack_start(button)
854
855 button = gtk.Button(stock=gtk.STOCK_REMOVE)
856 button.connect("clicked", self.editable_settings_remove_item_clicked, setting_tree)
857 hbox.pack_start(button)
858
859 info = HobInfoButton(tooltip, self)
860 setting_hbox.pack_start(info, expand=False, fill=False)
861
862 return setting_hbox, setting_store
863
864 def create_others_page(self):
865 advanced_vbox = gtk.VBox(False, 6)
866 advanced_vbox.set_border_width(6)
867
868 sub_vbox = gtk.VBox(False, 6)
869 advanced_vbox.pack_start(sub_vbox, expand=True, fill=True)
870 label = self.gen_label_widget("<span weight=\"bold\">Add your own variables:</span>")
871 tooltip = "These are key/value pairs for your extra settings. Click \'Add\' and then directly edit the key and the value"
872 setting_widget, self.setting_store = self.gen_editable_settings(self.configuration.extra_setting,"<b>Add your own variables</b>" + "*" + tooltip)
873 sub_vbox.pack_start(label, expand=False, fill=False)
874 sub_vbox.pack_start(setting_widget, expand=True, fill=True)
875
876 return advanced_vbox
877
878 def create_visual_elements(self):
879 self.nb = gtk.Notebook()
880 self.nb.set_show_tabs(True)
881 self.nb.append_page(self.create_build_environment_page(), gtk.Label("Build environment"))
882 self.nb.append_page(self.create_shared_state_page(), gtk.Label("Shared state"))
883 self.nb.append_page(self.create_network_page(), gtk.Label("Network"))
884 self.nb.append_page(self.create_others_page(), gtk.Label("Others"))
885 self.nb.set_current_page(0)
886 self.vbox.pack_start(self.nb, expand=True, fill=True)
887 self.vbox.pack_end(gtk.HSeparator(), expand=True, fill=True)
888
889 self.show_all()
890
891 def destroy(self):
892 self.handler.disconnect(self.proxy_test_passed_id)
893 self.handler.disconnect(self.proxy_test_failed_id)
894 super(SimpleSettingsDialog, self).destroy()