2011-11-28 06:32:40 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
#
|
|
|
|
# BitBake Graphical GTK User Interface
|
|
|
|
#
|
|
|
|
# Copyright (C) 2012 Intel Corporation
|
|
|
|
#
|
|
|
|
# Authored by Dongxiao Xu <dongxiao.xu@intel.com>
|
|
|
|
# Authored by Shane Wang <shane.wang@intel.com>
|
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License version 2 as
|
|
|
|
# published by the Free Software Foundation.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License along
|
|
|
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
|
|
|
|
import gtk
|
|
|
|
import glib
|
|
|
|
from bb.ui.crumbs.hobcolor import HobColors
|
2012-03-22 23:06:42 +00:00
|
|
|
from bb.ui.crumbs.hobwidget import HobViewTable, HobNotebook, HobAltButton, HobButton
|
2011-11-28 06:32:40 +00:00
|
|
|
from bb.ui.crumbs.hoblistmodel import RecipeListModel
|
|
|
|
from bb.ui.crumbs.hobpages import HobPage
|
|
|
|
|
|
|
|
#
|
|
|
|
# RecipeSelectionPage
|
|
|
|
#
|
|
|
|
class RecipeSelectionPage (HobPage):
|
|
|
|
pages = [
|
|
|
|
{
|
2012-03-21 02:09:16 +00:00
|
|
|
'name' : 'Included',
|
|
|
|
'filter' : { RecipeListModel.COL_INC : [True],
|
|
|
|
RecipeListModel.COL_TYPE : ['recipe', 'task'] },
|
2011-11-28 06:32:40 +00:00
|
|
|
'columns' : [{
|
2012-03-28 16:29:13 +00:00
|
|
|
'col_name' : 'Recipe name',
|
2011-11-28 06:32:40 +00:00
|
|
|
'col_id' : RecipeListModel.COL_NAME,
|
|
|
|
'col_style': 'text',
|
|
|
|
'col_min' : 100,
|
2012-04-06 23:02:22 +00:00
|
|
|
'col_max' : 400,
|
|
|
|
'expand' : 'True'
|
2011-11-28 06:32:40 +00:00
|
|
|
}, {
|
2012-03-21 02:09:16 +00:00
|
|
|
'col_name' : 'Brought in by',
|
|
|
|
'col_id' : RecipeListModel.COL_BINB,
|
2012-04-05 21:39:50 +00:00
|
|
|
'col_style': 'binb',
|
2011-11-28 06:32:40 +00:00
|
|
|
'col_min' : 100,
|
2012-04-06 23:02:22 +00:00
|
|
|
'col_max' : 500,
|
|
|
|
'expand' : 'True'
|
2012-04-05 23:37:23 +00:00
|
|
|
}, {
|
|
|
|
'col_name' : 'Group',
|
|
|
|
'col_id' : RecipeListModel.COL_GROUP,
|
|
|
|
'col_style': 'text',
|
|
|
|
'col_min' : 100,
|
2012-04-06 23:02:22 +00:00
|
|
|
'col_max' : 300,
|
|
|
|
'expand' : 'True'
|
2011-11-28 06:32:40 +00:00
|
|
|
}, {
|
|
|
|
'col_name' : 'Included',
|
|
|
|
'col_id' : RecipeListModel.COL_INC,
|
2012-02-29 14:14:58 +00:00
|
|
|
'col_style': 'check toggle',
|
2012-04-06 23:02:22 +00:00
|
|
|
'col_min' : 100,
|
|
|
|
'col_max' : 100
|
2011-11-28 06:32:40 +00:00
|
|
|
}]
|
|
|
|
}, {
|
2012-03-21 02:09:16 +00:00
|
|
|
'name' : 'All recipes',
|
|
|
|
'filter' : { RecipeListModel.COL_TYPE : ['recipe'] },
|
2011-11-28 06:32:40 +00:00
|
|
|
'columns' : [{
|
2012-03-28 16:29:13 +00:00
|
|
|
'col_name' : 'Recipe name',
|
2011-11-28 06:32:40 +00:00
|
|
|
'col_id' : RecipeListModel.COL_NAME,
|
|
|
|
'col_style': 'text',
|
|
|
|
'col_min' : 100,
|
2012-04-06 23:02:22 +00:00
|
|
|
'col_max' : 400,
|
|
|
|
'expand' : 'True'
|
2011-11-28 06:32:40 +00:00
|
|
|
}, {
|
2012-03-21 02:09:16 +00:00
|
|
|
'col_name' : 'License',
|
|
|
|
'col_id' : RecipeListModel.COL_LIC,
|
|
|
|
'col_style': 'text',
|
|
|
|
'col_min' : 100,
|
2012-04-06 23:02:22 +00:00
|
|
|
'col_max' : 400,
|
|
|
|
'expand' : 'True'
|
2012-03-21 02:09:16 +00:00
|
|
|
}, {
|
|
|
|
'col_name' : 'Group',
|
|
|
|
'col_id' : RecipeListModel.COL_GROUP,
|
2011-11-28 06:32:40 +00:00
|
|
|
'col_style': 'text',
|
|
|
|
'col_min' : 100,
|
2012-04-06 23:02:22 +00:00
|
|
|
'col_max' : 400,
|
|
|
|
'expand' : 'True'
|
2011-11-28 06:32:40 +00:00
|
|
|
}, {
|
|
|
|
'col_name' : 'Included',
|
|
|
|
'col_id' : RecipeListModel.COL_INC,
|
2012-02-29 14:14:58 +00:00
|
|
|
'col_style': 'check toggle',
|
2012-04-06 23:02:22 +00:00
|
|
|
'col_min' : 100,
|
|
|
|
'col_max' : 100
|
2011-11-28 06:32:40 +00:00
|
|
|
}]
|
|
|
|
}, {
|
2012-03-21 02:09:16 +00:00
|
|
|
'name' : 'Tasks',
|
|
|
|
'filter' : { RecipeListModel.COL_TYPE : ['task'] },
|
2011-11-28 06:32:40 +00:00
|
|
|
'columns' : [{
|
2012-03-28 16:29:13 +00:00
|
|
|
'col_name' : 'Task name',
|
2011-11-28 06:32:40 +00:00
|
|
|
'col_id' : RecipeListModel.COL_NAME,
|
|
|
|
'col_style': 'text',
|
|
|
|
'col_min' : 100,
|
2012-04-06 23:02:22 +00:00
|
|
|
'col_max' : 400,
|
|
|
|
'expand' : 'True'
|
2011-11-28 06:32:40 +00:00
|
|
|
}, {
|
2012-03-21 02:09:16 +00:00
|
|
|
'col_name' : 'Description',
|
|
|
|
'col_id' : RecipeListModel.COL_DESC,
|
2011-11-28 06:32:40 +00:00
|
|
|
'col_style': 'text',
|
|
|
|
'col_min' : 100,
|
2012-04-06 23:02:22 +00:00
|
|
|
'col_max' : 400,
|
|
|
|
'expand' : 'True'
|
2011-11-28 06:32:40 +00:00
|
|
|
}, {
|
|
|
|
'col_name' : 'Included',
|
|
|
|
'col_id' : RecipeListModel.COL_INC,
|
2012-02-29 14:14:58 +00:00
|
|
|
'col_style': 'check toggle',
|
2012-04-06 23:02:22 +00:00
|
|
|
'col_min' : 100,
|
|
|
|
'col_max' : 100
|
2011-11-28 06:32:40 +00:00
|
|
|
}]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
|
|
|
|
def __init__(self, builder = None):
|
2012-03-21 03:34:26 +00:00
|
|
|
super(RecipeSelectionPage, self).__init__(builder, "Recipes")
|
2011-11-28 06:32:40 +00:00
|
|
|
|
|
|
|
# set invisiable members
|
|
|
|
self.recipe_model = self.builder.recipe_model
|
|
|
|
|
|
|
|
# create visual elements
|
|
|
|
self.create_visual_elements()
|
|
|
|
|
|
|
|
def create_visual_elements(self):
|
2012-03-23 07:37:09 +00:00
|
|
|
self.label = gtk.Label()
|
2011-11-28 06:32:40 +00:00
|
|
|
self.eventbox = self.add_onto_top_bar(self.label, 73)
|
|
|
|
self.pack_start(self.eventbox, expand=False, fill=False)
|
|
|
|
self.pack_start(self.group_align, expand=True, fill=True)
|
|
|
|
|
|
|
|
# set visiable members
|
Hob: implement a self-defined notebook visual component for Hob
In recipe selection page, package selection page, and build details page, etc, there is a notebook component which is not gtk.Notebook in the design video.
We implement the visual component with a drawing area, and use it to replace the old notebook in recipe selection page and package selection page. The reasons why we do it are:
1) General speaking, gtk.Notebook doesn't look like the designer worked out. (see https://wiki.yoctoproject.org/wiki/File:Hob1.2-screencast2.mov)
2) And the designer version looks better, for example, there is an indicator to show how many recipes or packages are included, and how many issues happened when building? Very straightforward.
But technically, gtk.Notebook can't implement that, as far as we know.
3) Moreover, there is an entry for "search recipes", and "search packages". How to make it horizontal to the tabs is a problem to us.
Regarding those, we give up gtk.Notebook and use our own.
(From Poky rev: e4ebac226cc5e4589bcecd8bada9fde462e925cc)
(Bitbake rev: b0c2ca3f600694c6d37924006de3f9474b2a9a8e)
Signed-off-by: Liming An <limingx.l.an@intel.com>
Signed-off-by: Shane Wang <shane.wang@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2012-02-27 05:28:26 +00:00
|
|
|
self.ins = HobNotebook()
|
2011-11-28 06:32:40 +00:00
|
|
|
self.tables = [] # we need modify table when the dialog is shown
|
|
|
|
# append the tabs in order
|
2012-03-16 05:40:41 +00:00
|
|
|
for page in self.pages:
|
|
|
|
columns = page['columns']
|
2012-02-29 14:14:58 +00:00
|
|
|
tab = HobViewTable(columns)
|
2012-03-16 05:40:41 +00:00
|
|
|
filter = page['filter']
|
2012-02-29 14:14:58 +00:00
|
|
|
tab.set_model(self.recipe_model.tree_model(filter))
|
2012-04-09 14:13:32 +00:00
|
|
|
tab.connect("toggled", self.table_toggled_cb, page['name'])
|
2012-03-16 05:40:41 +00:00
|
|
|
if page['name'] == "Included":
|
2012-04-05 22:32:28 +00:00
|
|
|
tab.connect("button-release-event", self.button_click_cb)
|
2012-04-09 14:13:32 +00:00
|
|
|
tab.connect("cell-fadeinout-stopped", self.after_fadeout_checkin_include)
|
2012-03-16 05:40:41 +00:00
|
|
|
label = gtk.Label(page['name'])
|
2011-11-28 06:32:40 +00:00
|
|
|
self.ins.append_page(tab, label)
|
|
|
|
self.tables.append(tab)
|
|
|
|
|
Hob: implement a self-defined notebook visual component for Hob
In recipe selection page, package selection page, and build details page, etc, there is a notebook component which is not gtk.Notebook in the design video.
We implement the visual component with a drawing area, and use it to replace the old notebook in recipe selection page and package selection page. The reasons why we do it are:
1) General speaking, gtk.Notebook doesn't look like the designer worked out. (see https://wiki.yoctoproject.org/wiki/File:Hob1.2-screencast2.mov)
2) And the designer version looks better, for example, there is an indicator to show how many recipes or packages are included, and how many issues happened when building? Very straightforward.
But technically, gtk.Notebook can't implement that, as far as we know.
3) Moreover, there is an entry for "search recipes", and "search packages". How to make it horizontal to the tabs is a problem to us.
Regarding those, we give up gtk.Notebook and use our own.
(From Poky rev: e4ebac226cc5e4589bcecd8bada9fde462e925cc)
(Bitbake rev: b0c2ca3f600694c6d37924006de3f9474b2a9a8e)
Signed-off-by: Liming An <limingx.l.an@intel.com>
Signed-off-by: Shane Wang <shane.wang@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2012-02-27 05:28:26 +00:00
|
|
|
self.ins.set_entry("Search recipes:")
|
2011-11-28 06:32:40 +00:00
|
|
|
# set the search entry for each table
|
|
|
|
for tab in self.tables:
|
Hob: implement a self-defined notebook visual component for Hob
In recipe selection page, package selection page, and build details page, etc, there is a notebook component which is not gtk.Notebook in the design video.
We implement the visual component with a drawing area, and use it to replace the old notebook in recipe selection page and package selection page. The reasons why we do it are:
1) General speaking, gtk.Notebook doesn't look like the designer worked out. (see https://wiki.yoctoproject.org/wiki/File:Hob1.2-screencast2.mov)
2) And the designer version looks better, for example, there is an indicator to show how many recipes or packages are included, and how many issues happened when building? Very straightforward.
But technically, gtk.Notebook can't implement that, as far as we know.
3) Moreover, there is an entry for "search recipes", and "search packages". How to make it horizontal to the tabs is a problem to us.
Regarding those, we give up gtk.Notebook and use our own.
(From Poky rev: e4ebac226cc5e4589bcecd8bada9fde462e925cc)
(Bitbake rev: b0c2ca3f600694c6d37924006de3f9474b2a9a8e)
Signed-off-by: Liming An <limingx.l.an@intel.com>
Signed-off-by: Shane Wang <shane.wang@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2012-02-27 05:28:26 +00:00
|
|
|
tab.set_search_entry(0, self.ins.search)
|
2011-11-28 06:32:40 +00:00
|
|
|
|
|
|
|
# add all into the window
|
Hob: implement a self-defined notebook visual component for Hob
In recipe selection page, package selection page, and build details page, etc, there is a notebook component which is not gtk.Notebook in the design video.
We implement the visual component with a drawing area, and use it to replace the old notebook in recipe selection page and package selection page. The reasons why we do it are:
1) General speaking, gtk.Notebook doesn't look like the designer worked out. (see https://wiki.yoctoproject.org/wiki/File:Hob1.2-screencast2.mov)
2) And the designer version looks better, for example, there is an indicator to show how many recipes or packages are included, and how many issues happened when building? Very straightforward.
But technically, gtk.Notebook can't implement that, as far as we know.
3) Moreover, there is an entry for "search recipes", and "search packages". How to make it horizontal to the tabs is a problem to us.
Regarding those, we give up gtk.Notebook and use our own.
(From Poky rev: e4ebac226cc5e4589bcecd8bada9fde462e925cc)
(Bitbake rev: b0c2ca3f600694c6d37924006de3f9474b2a9a8e)
Signed-off-by: Liming An <limingx.l.an@intel.com>
Signed-off-by: Shane Wang <shane.wang@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2012-02-27 05:28:26 +00:00
|
|
|
self.box_group_area.pack_start(self.ins, expand=True, fill=True)
|
2011-11-28 06:32:40 +00:00
|
|
|
|
2012-03-15 06:56:45 +00:00
|
|
|
button_box = gtk.HBox(False, 6)
|
2011-11-28 06:32:40 +00:00
|
|
|
self.box_group_area.pack_end(button_box, expand=False, fill=False)
|
|
|
|
|
2012-03-22 23:06:42 +00:00
|
|
|
self.build_packages_button = HobButton('Build packages')
|
2011-11-28 06:32:40 +00:00
|
|
|
self.build_packages_button.set_size_request(205, 49)
|
2012-04-09 08:42:01 +00:00
|
|
|
self.build_packages_button.set_tooltip_text("Build selected recipes into packages")
|
2011-11-28 06:32:40 +00:00
|
|
|
self.build_packages_button.set_flags(gtk.CAN_DEFAULT)
|
|
|
|
self.build_packages_button.grab_default()
|
|
|
|
self.build_packages_button.connect("clicked", self.build_packages_clicked_cb)
|
|
|
|
button_box.pack_end(self.build_packages_button, expand=False, fill=False)
|
|
|
|
|
2012-03-22 23:02:56 +00:00
|
|
|
self.back_button = HobAltButton("<< Back to image configuration")
|
2011-11-28 06:32:40 +00:00
|
|
|
self.back_button.connect("clicked", self.back_button_clicked_cb)
|
|
|
|
button_box.pack_start(self.back_button, expand=False, fill=False)
|
|
|
|
|
2012-04-05 22:32:28 +00:00
|
|
|
def button_click_cb(self, widget, event):
|
|
|
|
path, col = widget.table_tree.get_cursor()
|
|
|
|
tree_model = widget.table_tree.get_model()
|
|
|
|
if path: # else activation is likely a removal
|
|
|
|
binb = tree_model.get_value(tree_model.get_iter(path), RecipeListModel.COL_BINB)
|
|
|
|
if binb:
|
|
|
|
self.builder.show_binb_dialog(binb)
|
2011-11-28 06:32:40 +00:00
|
|
|
|
|
|
|
def build_packages_clicked_cb(self, button):
|
|
|
|
self.builder.build_packages()
|
|
|
|
|
|
|
|
def back_button_clicked_cb(self, button):
|
|
|
|
self.builder.show_configuration()
|
|
|
|
|
|
|
|
def refresh_selection(self):
|
|
|
|
self.builder.configuration.selected_image = self.recipe_model.get_selected_image()
|
|
|
|
_, self.builder.configuration.selected_recipes = self.recipe_model.get_selected_recipes()
|
|
|
|
self.label.set_text("Recipes included: %s" % len(self.builder.configuration.selected_recipes))
|
2012-02-29 14:15:09 +00:00
|
|
|
self.ins.show_indicator_icon("Included", len(self.builder.configuration.selected_recipes))
|
2011-11-28 06:32:40 +00:00
|
|
|
|
2012-04-09 14:13:32 +00:00
|
|
|
def toggle_item_idle_cb(self, path, view_tree, cell, pagename):
|
2011-11-28 06:32:40 +00:00
|
|
|
if not self.recipe_model.path_included(path):
|
|
|
|
self.recipe_model.include_item(item_path=path, binb="User Selected", image_contents=False)
|
|
|
|
else:
|
2012-04-09 14:13:32 +00:00
|
|
|
if pagename == "Included":
|
|
|
|
self.pre_fadeout_checkout_include(view_tree)
|
|
|
|
self.recipe_model.exclude_item(item_path=path)
|
|
|
|
self.render_fadeout(view_tree, cell)
|
|
|
|
else:
|
|
|
|
self.recipe_model.exclude_item(item_path=path)
|
2011-11-28 06:32:40 +00:00
|
|
|
|
2012-03-14 02:53:42 +00:00
|
|
|
self.refresh_selection()
|
2012-04-09 08:41:57 +00:00
|
|
|
if not self.builder.customized:
|
|
|
|
self.builder.customized = True
|
|
|
|
self.builder.configuration.selected_image = self.recipe_model.__dummy_image__
|
|
|
|
self.builder.rcppkglist_populated()
|
|
|
|
|
2011-11-28 06:32:40 +00:00
|
|
|
self.builder.window_sensitive(True)
|
|
|
|
|
2012-04-09 14:13:32 +00:00
|
|
|
def table_toggled_cb(self, table, cell, view_path, toggled_columnid, view_tree, pagename):
|
2011-11-28 06:32:40 +00:00
|
|
|
# Click to include a recipe
|
|
|
|
self.builder.window_sensitive(False)
|
|
|
|
view_model = view_tree.get_model()
|
|
|
|
path = self.recipe_model.convert_vpath_to_path(view_model, view_path)
|
2012-04-09 14:13:32 +00:00
|
|
|
glib.idle_add(self.toggle_item_idle_cb, path, view_tree, cell, pagename)
|
|
|
|
|
|
|
|
def pre_fadeout_checkout_include(self, tree):
|
|
|
|
#resync the included items to a backup fade include column
|
|
|
|
it = self.recipe_model.get_iter_first()
|
|
|
|
while it:
|
|
|
|
active = self.recipe_model.get_value(it, self.recipe_model.COL_INC)
|
|
|
|
self.recipe_model.set(it, self.recipe_model.COL_FADE_INC, active)
|
|
|
|
it = self.recipe_model.iter_next(it)
|
|
|
|
# Check out a model which base on the column COL_FADE_INC,
|
|
|
|
# it's save the prev state of column COL_INC before do exclude_item
|
|
|
|
filter = { RecipeListModel.COL_FADE_INC : [True],
|
|
|
|
RecipeListModel.COL_TYPE : ['recipe', 'task'] }
|
|
|
|
new_model = self.recipe_model.tree_model(filter, excluded_items_head=True)
|
|
|
|
tree.set_model(new_model)
|
|
|
|
|
|
|
|
def render_fadeout(self, tree, cell):
|
|
|
|
if (not cell) or (not tree):
|
|
|
|
return
|
|
|
|
to_render_cells = []
|
|
|
|
model = tree.get_model()
|
|
|
|
it = model.get_iter_first()
|
|
|
|
while it:
|
|
|
|
path = model.get_path(it)
|
|
|
|
prev_cell_is_active = model.get_value(it, RecipeListModel.COL_FADE_INC)
|
|
|
|
curr_cell_is_active = model.get_value(it, RecipeListModel.COL_INC)
|
|
|
|
if (prev_cell_is_active == True) and (curr_cell_is_active == False):
|
|
|
|
to_render_cells.append(path)
|
|
|
|
it = model.iter_next(it)
|
|
|
|
|
|
|
|
cell.fadeout(tree, 1000, to_render_cells)
|
|
|
|
|
|
|
|
def after_fadeout_checkin_include(self, table, ctrl, cell, tree):
|
|
|
|
tree.set_model(self.recipe_model.tree_model(self.pages[0]['filter']))
|