summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCristiana Voicu <cristiana.voicu@intel.com>2013-01-28 15:33:39 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2013-01-31 12:46:20 +0000
commitb2ab771447d8d66c1ec43b7d509c1dcfa2e6cec2 (patch)
tree3196eb4b6f71d6ca07e280456e95f7ae93a72006
parent785e1ba01260165b81cbf69d898830fb2bc4d4a6 (diff)
downloadpoky-b2ab771447d8d66c1ec43b7d509c1dcfa2e6cec2.tar.gz
bitbake: hob: Use a GtkTreeView to present and configure the sstate mirrors
After some discussions about the design of the Shared State Settings tab in Hob, we have decided that using a GtkTreeView to present and configure the sstate mirrors is probably the best solution. [YOCTO #3569] (Bitbake rev: 2ff636910b9cf3099e8d961f4bbe71512c015ecc) Signed-off-by: Cristiana Voicu <cristiana.voicu@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--bitbake/lib/bb/ui/crumbs/hig/settingsuihelper.py94
-rw-r--r--bitbake/lib/bb/ui/crumbs/hig/simplesettingsdialog.py231
2 files changed, 204 insertions, 121 deletions
diff --git a/bitbake/lib/bb/ui/crumbs/hig/settingsuihelper.py b/bitbake/lib/bb/ui/crumbs/hig/settingsuihelper.py
index e10dd064ab..e0285c93ce 100644
--- a/bitbake/lib/bb/ui/crumbs/hig/settingsuihelper.py
+++ b/bitbake/lib/bb/ui/crumbs/hig/settingsuihelper.py
@@ -120,97 +120,3 @@ class SettingsUIHelper():
120 120
121 hbox.show_all() 121 hbox.show_all()
122 return hbox, entry 122 return hbox, entry
123
124 def gen_mirror_entry_widget(self, content, index, match_content=""):
125 hbox = gtk.HBox(False)
126 entry = gtk.Entry()
127 content = content[:-2]
128 entry.set_text(content)
129 entry.set_size_request(350,30)
130
131 entry_match = gtk.Entry()
132 entry_match.set_text(match_content)
133 entry_match.set_size_request(100,30)
134
135 table = gtk.Table(2, 5, False)
136 table.set_row_spacings(12)
137 table.set_col_spacings(6)
138 hbox.pack_start(table, expand=True, fill=True)
139
140 label_configuration = gtk.Label("Configuration")
141 label_configuration.set_alignment(0.0,0.5)
142 label_mirror_url = gtk.Label("Mirror URL")
143 label_mirror_url.set_alignment(0.0,0.5)
144 label_match = gtk.Label("Match")
145 label_match.set_alignment(0.0,0.5)
146 label_replace_with = gtk.Label("Replace with")
147 label_replace_with.set_alignment(0.0,0.5)
148
149 combo = gtk.combo_box_new_text()
150 combo.append_text("Standard")
151 combo.append_text("Custom")
152 if match_content == "":
153 combo.set_active(0)
154 else:
155 combo.set_active(1)
156 combo.connect("changed", self.on_combo_changed, index)
157 combo.set_size_request(100,30)
158
159 delete_button = HobAltButton("Delete")
160 delete_button.connect("clicked", self.delete_cb, index, entry)
161 if content == "" and index == 0 and len(self.sstatemirrors_list) == 1:
162 delete_button.set_sensitive(False)
163 delete_button.set_size_request(100, 30)
164
165 entry_match.connect("changed", self.insert_entry_match_cb, index)
166 entry.connect("changed", self.insert_entry_cb, index, delete_button)
167
168 if match_content == "":
169 table.attach(label_configuration, 1, 2, 0, 1, xoptions=gtk.SHRINK|gtk.FILL)
170 table.attach(label_mirror_url, 2, 3, 0, 1, xoptions=gtk.SHRINK|gtk.FILL)
171 table.attach(combo, 1, 2, 1, 2, xoptions=gtk.SHRINK)
172 table.attach(entry, 2, 3, 1, 2, xoptions=gtk.SHRINK)
173 table.attach(delete_button, 3, 4, 1, 2, xoptions=gtk.SHRINK)
174 else:
175 table.attach(label_configuration, 1, 2, 0, 1, xoptions=gtk.SHRINK|gtk.FILL)
176 table.attach(label_match, 2, 3, 0, 1, xoptions=gtk.SHRINK|gtk.FILL)
177 table.attach(label_replace_with, 3, 4, 0, 1, xoptions=gtk.SHRINK|gtk.FILL)
178 table.attach(combo, 1, 2, 1, 2, xoptions=gtk.SHRINK)
179 table.attach(entry_match, 2, 3, 1, 2, xoptions=gtk.SHRINK)
180 table.attach(entry, 3, 4, 1, 2, xoptions=gtk.SHRINK)
181 table.attach(delete_button, 4, 5, 1, 2, xoptions=gtk.SHRINK)
182
183 hbox.show_all()
184 return hbox
185
186 def insert_entry_match_cb(self, entry_match, index):
187 self.sstatemirrors_list[index][2] = entry_match.get_text()
188
189 def insert_entry_cb(self, entry, index, button):
190 self.sstatemirrors_list[index][1] = entry.get_text()
191 if entry.get_text() == "" and index == 0:
192 button.set_sensitive(False)
193 else:
194 button.set_sensitive(True)
195
196 def on_combo_changed(self, combo, index):
197 if combo.get_active_text() == "Standard":
198 self.sstatemirrors_list[index][0] = 0
199 self.sstatemirrors_list[index][2] = "file://(.*)"
200 else:
201 self.sstatemirrors_list[index][0] = 1
202 self.refresh_shared_state_page()
203
204 def delete_cb(self, button, index, entry):
205 if index == 0 and len(self.sstatemirrors_list)==1:
206 entry.set_text("")
207 else:
208 self.sstatemirrors_list.pop(index)
209 self.refresh_shared_state_page()
210
211 def add_mirror(self, button):
212 tooltip = "Select the pre-built mirror that will speed your build"
213 index = len(self.sstatemirrors_list)
214 sm_list = [0, "", "file://(.*)"]
215 self.sstatemirrors_list.append(sm_list)
216 self.refresh_shared_state_page()
diff --git a/bitbake/lib/bb/ui/crumbs/hig/simplesettingsdialog.py b/bitbake/lib/bb/ui/crumbs/hig/simplesettingsdialog.py
index 50c7510ff3..5f316ae336 100644
--- a/bitbake/lib/bb/ui/crumbs/hig/simplesettingsdialog.py
+++ b/bitbake/lib/bb/ui/crumbs/hig/simplesettingsdialog.py
@@ -50,6 +50,13 @@ class SimpleSettingsDialog (CrumbsDialog, SettingsUIHelper):
50 TEST_NETWORK_FAILED, 50 TEST_NETWORK_FAILED,
51 TEST_NETWORK_CANCELED) = range(6) 51 TEST_NETWORK_CANCELED) = range(6)
52 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
53 def __init__(self, title, configuration, all_image_types, 60 def __init__(self, title, configuration, all_image_types,
54 all_package_formats, all_distros, all_sdk_machines, 61 all_package_formats, all_distros, all_sdk_machines,
55 max_threads, parent, flags, handler, buttons=None): 62 max_threads, parent, flags, handler, buttons=None):
@@ -84,6 +91,8 @@ class SimpleSettingsDialog (CrumbsDialog, SettingsUIHelper):
84 self.proxy_settings_changed = False 91 self.proxy_settings_changed = False
85 self.handler = handler 92 self.handler = handler
86 self.proxy_test_ran = False 93 self.proxy_test_ran = False
94 self.selected_mirror_row = 0
95 self.new_mirror = False
87 96
88 # create visual elements on the dialog 97 # create visual elements on the dialog
89 self.create_visual_elements() 98 self.create_visual_elements()
@@ -219,7 +228,7 @@ class SimpleSettingsDialog (CrumbsDialog, SettingsUIHelper):
219 self.configuration.sstatedir = self.sstatedir_text.get_text() 228 self.configuration.sstatedir = self.sstatedir_text.get_text()
220 self.configuration.sstatemirror = "" 229 self.configuration.sstatemirror = ""
221 for mirror in self.sstatemirrors_list: 230 for mirror in self.sstatemirrors_list:
222 if mirror[1] != "": 231 if mirror[1] != "" and mirror[2].startswith("file://"):
223 if mirror[1].endswith("\\1"): 232 if mirror[1].endswith("\\1"):
224 smirror = mirror[2] + " " + mirror[1] + " \\n " 233 smirror = mirror[2] + " " + mirror[1] + " \\n "
225 else: 234 else:
@@ -287,7 +296,7 @@ class SimpleSettingsDialog (CrumbsDialog, SettingsUIHelper):
287 label = self.gen_label_info_widget(content, tooltip) 296 label = self.gen_label_info_widget(content, tooltip)
288 sstatedir_widget, self.sstatedir_text = self.gen_entry_widget(self.configuration.sstatedir, self) 297 sstatedir_widget, self.sstatedir_text = self.gen_entry_widget(self.configuration.sstatedir, self)
289 sub_vbox.pack_start(label, expand=False, fill=False) 298 sub_vbox.pack_start(label, expand=False, fill=False)
290 sub_vbox.pack_start(sstatedir_widget, expand=False, fill=False, padding=12) 299 sub_vbox.pack_start(sstatedir_widget, expand=False, fill=False, padding=6)
291 300
292 content = "<span weight=\"bold\">Shared state mirrors</span>" 301 content = "<span weight=\"bold\">Shared state mirrors</span>"
293 tooltip = "URLs pointing to pre-built mirrors that will speed your build. " 302 tooltip = "URLs pointing to pre-built mirrors that will speed your build. "
@@ -297,21 +306,17 @@ class SimpleSettingsDialog (CrumbsDialog, SettingsUIHelper):
297 tooltip += "http://www.yoctoproject.org/docs/current/poky-ref-manual/" 306 tooltip += "http://www.yoctoproject.org/docs/current/poky-ref-manual/"
298 tooltip += "poky-ref-manual.html#shared-state\">Yocto Project Reference Manual</a>." 307 tooltip += "poky-ref-manual.html#shared-state\">Yocto Project Reference Manual</a>."
299 table = self.gen_label_info_widget(content, tooltip) 308 table = self.gen_label_info_widget(content, tooltip)
300 advanced_vbox.pack_start(table, expand=False, fill=False) 309 advanced_vbox.pack_start(table, expand=False, fill=False, padding=6)
301 310
302 sub_vbox = gtk.VBox(False) 311 sub_vbox = gtk.VBox(False)
303 scroll = gtk.ScrolledWindow() 312 advanced_vbox.pack_start(sub_vbox, gtk.TRUE, gtk.TRUE, 0)
304 scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
305 scroll.add_with_viewport(sub_vbox)
306 scroll.connect('size-allocate', self.scroll_changed)
307 advanced_vbox.pack_start(scroll, gtk.TRUE, gtk.TRUE, 0)
308 searched_string = "file://" 313 searched_string = "file://"
309 314
310 if self.sstatemirrors_changed == 0: 315 if self.sstatemirrors_changed == 0:
311 self.sstatemirrors_changed = 1 316 self.sstatemirrors_changed = 1
312 sstatemirrors = self.configuration.sstatemirror 317 sstatemirrors = self.configuration.sstatemirror
313 if sstatemirrors == "": 318 if sstatemirrors == "":
314 sm_list = [ 0, "", "file://(.*)"] 319 sm_list = ["Standard", "", "file://(.*)"]
315 self.sstatemirrors_list.append(sm_list) 320 self.sstatemirrors_list.append(sm_list)
316 else: 321 else:
317 while sstatemirrors.find(searched_string) != -1: 322 while sstatemirrors.find(searched_string) != -1:
@@ -325,30 +330,206 @@ class SimpleSettingsDialog (CrumbsDialog, SettingsUIHelper):
325 sstatemirror_fields = [x for x in sstatemirror.split(' ') if x.strip()] 330 sstatemirror_fields = [x for x in sstatemirror.split(' ') if x.strip()]
326 if len(sstatemirror_fields): 331 if len(sstatemirror_fields):
327 if sstatemirror_fields[0] == "file://(.*)": 332 if sstatemirror_fields[0] == "file://(.*)":
328 sm_list = [ 0, sstatemirror_fields[1], "file://(.*)"] 333 sm_list = ["Standard", sstatemirror_fields[1], "file://(.*)"]
329 else: 334 else:
330 sm_list = [ 1, sstatemirror_fields[1], sstatemirror_fields[0]] 335 sm_list = ["Custom", sstatemirror_fields[1], sstatemirror_fields[0]]
331 self.sstatemirrors_list.append(sm_list) 336 self.sstatemirrors_list.append(sm_list)
332 337
333 index = 0 338 sstatemirrors_widget, sstatemirrors_store = self.gen_shared_sstate_widget(self.sstatemirrors_list, self)
334 for mirror in self.sstatemirrors_list: 339 sub_vbox.pack_start(sstatemirrors_widget, expand=True, fill=True)
335 if mirror[0] == 0:
336 sstatemirror_widget = self.gen_mirror_entry_widget(mirror[1], index)
337 else:
338 sstatemirror_widget = self.gen_mirror_entry_widget(mirror[1], index, mirror[2])
339 sub_vbox.pack_start(sstatemirror_widget, expand=False, fill=False, padding=9)
340 index += 1
341 340
342 table = gtk.Table(1, 1, False) 341 table = gtk.Table(1, 10, False)
343 table.set_col_spacings(6) 342 table.set_col_spacings(6)
344 add_mirror_button = HobAltButton("Add another mirror") 343 add_mirror_button = HobAltButton("Add mirror")
345 add_mirror_button.connect("clicked", self.add_mirror) 344 add_mirror_button.connect("clicked", self.add_mirror)
346 add_mirror_button.set_size_request(150,30) 345 add_mirror_button.set_size_request(120,30)
347 table.attach(add_mirror_button, 1, 2, 0, 1, xoptions=gtk.SHRINK) 346 table.attach(add_mirror_button, 1, 2, 0, 1, xoptions=gtk.SHRINK)
348 advanced_vbox.pack_start(table, expand=False, fill=False, padding=9) 347
348 self.delete_button = HobAltButton("Delete mirror")
349 self.delete_button.connect("clicked", self.delete_cb)
350 self.delete_button.set_size_request(120, 30)
351 table.attach(self.delete_button, 3, 4, 0, 1, xoptions=gtk.SHRINK)
352
353 advanced_vbox.pack_start(table, expand=False, fill=False, padding=6)
349 354
350 return advanced_vbox 355 return advanced_vbox
351 356
357 def gen_shared_sstate_widget(self, sstatemirrors_list, window):
358 hbox = gtk.HBox(False)
359
360 sstatemirrors_store = gtk.ListStore(str, str, str)
361 for sstatemirror in sstatemirrors_list:
362 sstatemirrors_store.append(sstatemirror)
363
364 self.sstatemirrors_tv = gtk.TreeView()
365 self.sstatemirrors_tv.set_rules_hint(True)
366 self.sstatemirrors_tv.set_headers_visible(True)
367 tree_selection = self.sstatemirrors_tv.get_selection()
368 tree_selection.set_mode(gtk.SELECTION_SINGLE)
369
370 # Allow enable drag and drop of rows including row move
371 self.sstatemirrors_tv.enable_model_drag_source( gtk.gdk.BUTTON1_MASK,
372 self.TARGETS,
373 gtk.gdk.ACTION_DEFAULT|
374 gtk.gdk.ACTION_MOVE)
375 self.sstatemirrors_tv.enable_model_drag_dest(self.TARGETS,
376 gtk.gdk.ACTION_DEFAULT)
377 self.sstatemirrors_tv.connect("drag_data_get", self.drag_data_get_cb)
378 self.sstatemirrors_tv.connect("drag_data_received", self.drag_data_received_cb)
379
380
381 self.scroll = gtk.ScrolledWindow()
382 self.scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
383 self.scroll.set_shadow_type(gtk.SHADOW_IN)
384 self.scroll.connect('size-allocate', self.scroll_changed)
385 self.scroll.add(self.sstatemirrors_tv)
386
387 #list store for cell renderer
388 m = gtk.ListStore(gobject.TYPE_STRING)
389 m.append(["Standard"])
390 m.append(["Custom"])
391
392 cell0 = gtk.CellRendererCombo()
393 cell0.set_property("model",m)
394 cell0.set_property("text-column", 0)
395 cell0.set_property("editable", True)
396 cell0.set_property("has-entry", False)
397 col0 = gtk.TreeViewColumn("Configuration")
398 col0.pack_start(cell0, False)
399 col0.add_attribute(cell0, "text", 0)
400 col0.set_cell_data_func(cell0, self.configuration_field)
401 self.sstatemirrors_tv.append_column(col0)
402
403 cell0.connect("edited", self.combo_changed, sstatemirrors_store)
404
405 self.cell1 = gtk.CellRendererText()
406 self.cell1.set_padding(5,2)
407 col1 = gtk.TreeViewColumn('Regex', self.cell1)
408 col1.set_cell_data_func(self.cell1, self.regex_field)
409 self.sstatemirrors_tv.append_column(col1)
410
411 self.cell1.connect("edited", self.regex_changed, sstatemirrors_store)
412
413 cell2 = gtk.CellRendererText()
414 cell2.set_padding(5,2)
415 cell2.set_property("editable", True)
416 col2 = gtk.TreeViewColumn('URL', cell2)
417 col2.set_cell_data_func(cell2, self.url_field)
418 self.sstatemirrors_tv.append_column(col2)
419
420 cell2.connect("edited", self.url_changed, sstatemirrors_store)
421
422 self.sstatemirrors_tv.set_model(sstatemirrors_store)
423 self.sstatemirrors_tv.set_cursor(self.selected_mirror_row)
424 hbox.pack_start(self.scroll, expand=True, fill=True)
425 hbox.show_all()
426
427 return hbox, sstatemirrors_store
428
429 def drag_data_get_cb(self, treeview, context, selection, target_id, etime):
430 treeselection = treeview.get_selection()
431 model, iter = treeselection.get_selected()
432 data = model.get_string_from_iter(iter)
433 selection.set(selection.target, 8, data)
434
435 def drag_data_received_cb(self, treeview, context, x, y, selection, info, etime):
436 model = treeview.get_model()
437 data = []
438 tree_iter = model.get_iter_from_string(selection.data)
439 data.append(model.get_value(tree_iter, 0))
440 data.append(model.get_value(tree_iter, 1))
441 data.append(model.get_value(tree_iter, 2))
442
443 drop_info = treeview.get_dest_row_at_pos(x, y)
444 if drop_info:
445 path, position = drop_info
446 iter = model.get_iter(path)
447 if (position == gtk.TREE_VIEW_DROP_BEFORE or position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE):
448 model.insert_before(iter, data)
449 else:
450 model.insert_after(iter, data)
451 else:
452 model.append(data)
453 if context.action == gtk.gdk.ACTION_MOVE:
454 context.finish(True, True, etime)
455 return
456
457 def delete_cb(self, button):
458 selection = self.sstatemirrors_tv.get_selection()
459 tree_model, tree_iter = selection.get_selected()
460 index = int(tree_model.get_string_from_iter(tree_iter))
461 if index == 0:
462 self.selected_mirror_row = index
463 else:
464 self.selected_mirror_row = index - 1
465 self.sstatemirrors_list.pop(index)
466 self.refresh_shared_state_page()
467 if not self.sstatemirrors_list:
468 self.delete_button.set_sensitive(False)
469
470 def add_mirror(self, button):
471 self.new_mirror = True
472 tooltip = "Select the pre-built mirror that will speed your build"
473 index = len(self.sstatemirrors_list)
474 self.selected_mirror_row = index
475 sm_list = ["Standard", "", "file://(.*)"]
476 self.sstatemirrors_list.append(sm_list)
477 self.refresh_shared_state_page()
478
479 def scroll_changed(self, widget, event, data=None):
480 if self.new_mirror == True:
481 adj = widget.get_vadjustment()
482 adj.set_value(adj.upper - adj.page_size)
483 self.new_mirror = False
484
485 def combo_changed(self, widget, path, text, model):
486 model[path][0] = text
487 selection = self.sstatemirrors_tv.get_selection()
488 tree_model, tree_iter = selection.get_selected()
489 index = int(tree_model.get_string_from_iter(tree_iter))
490 self.sstatemirrors_list[index][0] = text
491
492 def regex_changed(self, cell, path, new_text, user_data):
493 user_data[path][2] = 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][2] = new_text
498 return
499
500 def url_changed(self, cell, path, new_text, user_data):
501 if new_text!="Enter the mirror URL" and new_text!="Match regex and replace it with this URL":
502 user_data[path][1] = new_text
503 selection = self.sstatemirrors_tv.get_selection()
504 tree_model, tree_iter = selection.get_selected()
505 index = int(tree_model.get_string_from_iter(tree_iter))
506 self.sstatemirrors_list[index][1] = new_text
507 return
508
509 def configuration_field(self, column, cell, model, iter):
510 cell.set_property('text', model.get_value(iter, 0))
511 if model.get_value(iter, 0) == "Standard":
512 self.cell1.set_property("sensitive", False)
513 self.cell1.set_property("editable", False)
514 else:
515 self.cell1.set_property("sensitive", True)
516 self.cell1.set_property("editable", True)
517 return
518
519 def regex_field(self, column, cell, model, iter):
520 cell.set_property('text', model.get_value(iter, 2))
521 return
522
523 def url_field(self, column, cell, model, iter):
524 text = model.get_value(iter, 1)
525 if text == "":
526 if model.get_value(iter, 0) == "Standard":
527 text = "Enter the mirror URL"
528 else:
529 text = "Match regex and replace it with this URL"
530 cell.set_property('text', text)
531 return
532
352 def refresh_shared_state_page(self): 533 def refresh_shared_state_page(self):
353 page_num = self.nb.get_current_page() 534 page_num = self.nb.get_current_page()
354 self.nb.remove_page(page_num); 535 self.nb.remove_page(page_num);
@@ -717,7 +898,3 @@ class SimpleSettingsDialog (CrumbsDialog, SettingsUIHelper):
717 self.handler.disconnect(self.proxy_test_passed_id) 898 self.handler.disconnect(self.proxy_test_passed_id)
718 self.handler.disconnect(self.proxy_test_failed_id) 899 self.handler.disconnect(self.proxy_test_failed_id)
719 super(SimpleSettingsDialog, self).destroy() 900 super(SimpleSettingsDialog, self).destroy()
720
721 def scroll_changed(self, widget, event, data=None):
722 adj = widget.get_vadjustment()
723 adj.set_value(adj.upper - adj.page_size)