summaryrefslogtreecommitdiffstats
path: root/import-layers/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/layerselectiondialog.py
diff options
context:
space:
mode:
Diffstat (limited to 'import-layers/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/layerselectiondialog.py')
-rw-r--r--import-layers/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/layerselectiondialog.py298
1 files changed, 298 insertions, 0 deletions
diff --git a/import-layers/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/layerselectiondialog.py b/import-layers/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/layerselectiondialog.py
new file mode 100644
index 000000000..52d57b673
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/layerselectiondialog.py
@@ -0,0 +1,298 @@
+#
+# BitBake Graphical GTK User Interface
+#
+# Copyright (C) 2011-2012 Intel Corporation
+#
+# Authored by Joshua Lock <josh@linux.intel.com>
+# 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 gobject
+import os
+import tempfile
+from bb.ui.crumbs.hobwidget import hic, HobButton, HobAltButton
+from bb.ui.crumbs.hig.crumbsdialog import CrumbsDialog
+from bb.ui.crumbs.hig.crumbsmessagedialog import CrumbsMessageDialog
+
+"""
+The following are convenience classes for implementing GNOME HIG compliant
+BitBake GUI's
+In summary: spacing = 12px, border-width = 6px
+"""
+
+class CellRendererPixbufActivatable(gtk.CellRendererPixbuf):
+ """
+ A custom CellRenderer implementation which is activatable
+ so that we can handle user clicks
+ """
+ __gsignals__ = { 'clicked' : (gobject.SIGNAL_RUN_LAST,
+ gobject.TYPE_NONE,
+ (gobject.TYPE_STRING,)), }
+
+ def __init__(self):
+ gtk.CellRendererPixbuf.__init__(self)
+ self.set_property('mode', gtk.CELL_RENDERER_MODE_ACTIVATABLE)
+ self.set_property('follow-state', True)
+
+ """
+ Respond to a user click on a cell
+ """
+ def do_activate(self, even, widget, path, background_area, cell_area, flags):
+ self.emit('clicked', path)
+
+#
+# LayerSelectionDialog
+#
+class LayerSelectionDialog (CrumbsDialog):
+
+ TARGETS = [
+ ("MY_TREE_MODEL_ROW", gtk.TARGET_SAME_WIDGET, 0),
+ ("text/plain", 0, 1),
+ ("TEXT", 0, 2),
+ ("STRING", 0, 3),
+ ]
+
+ def gen_label_widget(self, content):
+ label = gtk.Label()
+ label.set_alignment(0, 0)
+ label.set_markup(content)
+ label.show()
+ return label
+
+ def layer_widget_toggled_cb(self, cell, path, layer_store):
+ name = layer_store[path][0]
+ toggle = not layer_store[path][1]
+ layer_store[path][1] = toggle
+
+ def layer_widget_add_clicked_cb(self, action, layer_store, parent):
+ dialog = gtk.FileChooserDialog("Add new layer", parent,
+ gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
+ button = dialog.add_button("Cancel", gtk.RESPONSE_NO)
+ HobAltButton.style_button(button)
+ button = dialog.add_button("Open", gtk.RESPONSE_YES)
+ HobButton.style_button(button)
+ label = gtk.Label("Select the layer you wish to add")
+ label.show()
+ dialog.set_extra_widget(label)
+ response = dialog.run()
+ path = dialog.get_filename()
+ dialog.destroy()
+
+ lbl = "<b>Error</b>"
+ msg = "Unable to load layer <i>%s</i> because " % path
+ if response == gtk.RESPONSE_YES:
+ import os
+ import os.path
+ layers = []
+ it = layer_store.get_iter_first()
+ while it:
+ layers.append(layer_store.get_value(it, 0))
+ it = layer_store.iter_next(it)
+
+ if not path:
+ msg += "it is an invalid path."
+ elif not os.path.exists(path+"/conf/layer.conf"):
+ msg += "there is no layer.conf inside the directory."
+ elif path in layers:
+ msg += "it is already in loaded layers."
+ else:
+ layer_store.append([path])
+ return
+ dialog = CrumbsMessageDialog(parent, lbl, gtk.MESSAGE_ERROR, msg)
+ dialog.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_OK)
+ response = dialog.run()
+ dialog.destroy()
+
+ def layer_widget_del_clicked_cb(self, action, tree_selection, layer_store):
+ model, iter = tree_selection.get_selected()
+ if iter:
+ layer_store.remove(iter)
+
+
+ def gen_layer_widget(self, layers, layers_avail, window, tooltip=""):
+ hbox = gtk.HBox(False, 6)
+
+ layer_tv = gtk.TreeView()
+ layer_tv.set_rules_hint(True)
+ layer_tv.set_headers_visible(False)
+ tree_selection = layer_tv.get_selection()
+ tree_selection.set_mode(gtk.SELECTION_SINGLE)
+
+ # Allow enable drag and drop of rows including row move
+ dnd_internal_target = ''
+ dnd_targets = [(dnd_internal_target, gtk.TARGET_SAME_WIDGET, 0)]
+ layer_tv.enable_model_drag_source( gtk.gdk.BUTTON1_MASK,
+ dnd_targets,
+ gtk.gdk.ACTION_MOVE)
+ layer_tv.enable_model_drag_dest(dnd_targets,
+ gtk.gdk.ACTION_MOVE)
+ layer_tv.connect("drag_data_get", self.drag_data_get_cb)
+ layer_tv.connect("drag_data_received", self.drag_data_received_cb)
+
+ col0= gtk.TreeViewColumn('Path')
+ cell0 = gtk.CellRendererText()
+ cell0.set_padding(5,2)
+ col0.pack_start(cell0, True)
+ col0.set_cell_data_func(cell0, self.draw_layer_path_cb)
+ layer_tv.append_column(col0)
+
+ scroll = gtk.ScrolledWindow()
+ scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+ scroll.set_shadow_type(gtk.SHADOW_IN)
+ scroll.add(layer_tv)
+
+ table_layer = gtk.Table(2, 10, False)
+ hbox.pack_start(table_layer, expand=True, fill=True)
+
+ table_layer.attach(scroll, 0, 10, 0, 1)
+
+ layer_store = gtk.ListStore(gobject.TYPE_STRING)
+ for layer in layers:
+ layer_store.append([layer])
+
+ col1 = gtk.TreeViewColumn('Enabled')
+ layer_tv.append_column(col1)
+
+ cell1 = CellRendererPixbufActivatable()
+ cell1.set_fixed_size(-1,35)
+ cell1.connect("clicked", self.del_cell_clicked_cb, layer_store)
+ col1.pack_start(cell1, True)
+ col1.set_cell_data_func(cell1, self.draw_delete_button_cb, layer_tv)
+
+ add_button = gtk.Button()
+ add_button.set_relief(gtk.RELIEF_NONE)
+ box = gtk.HBox(False, 6)
+ box.show()
+ add_button.add(box)
+ add_button.connect("enter-notify-event", self.add_hover_cb)
+ add_button.connect("leave-notify-event", self.add_leave_cb)
+ self.im = gtk.Image()
+ self.im.set_from_file(hic.ICON_INDI_ADD_FILE)
+ self.im.show()
+ box.pack_start(self.im, expand=False, fill=False, padding=6)
+ lbl = gtk.Label("Add layer")
+ lbl.set_alignment(0.0, 0.5)
+ lbl.show()
+ box.pack_start(lbl, expand=True, fill=True, padding=6)
+ add_button.connect("clicked", self.layer_widget_add_clicked_cb, layer_store, window)
+ table_layer.attach(add_button, 0, 10, 1, 2, gtk.EXPAND | gtk.FILL, 0, 0, 6)
+ layer_tv.set_model(layer_store)
+
+ hbox.show_all()
+
+ return hbox, layer_store
+
+ def drag_data_get_cb(self, treeview, context, selection, target_id, etime):
+ treeselection = treeview.get_selection()
+ model, iter = treeselection.get_selected()
+ data = model.get_value(iter, 0)
+ selection.set(selection.target, 8, data)
+
+ def drag_data_received_cb(self, treeview, context, x, y, selection, info, etime):
+ model = treeview.get_model()
+ data = selection.data
+ drop_info = treeview.get_dest_row_at_pos(x, y)
+ if drop_info:
+ path, position = drop_info
+ iter = model.get_iter(path)
+ if (position == gtk.TREE_VIEW_DROP_BEFORE or position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE):
+ model.insert_before(iter, [data])
+ else:
+ model.insert_after(iter, [data])
+ else:
+ model.append([data])
+ if context.action == gtk.gdk.ACTION_MOVE:
+ context.finish(True, True, etime)
+ return
+
+ def add_hover_cb(self, button, event):
+ self.im.set_from_file(hic.ICON_INDI_ADD_HOVER_FILE)
+
+ def add_leave_cb(self, button, event):
+ self.im.set_from_file(hic.ICON_INDI_ADD_FILE)
+
+ def __init__(self, title, layers, layers_non_removable, all_layers, parent, flags, buttons=None):
+ super(LayerSelectionDialog, self).__init__(title, parent, flags, buttons)
+
+ # class members from other objects
+ self.layers = layers
+ self.layers_non_removable = layers_non_removable
+ self.all_layers = all_layers
+ self.layers_changed = False
+
+ # icon for remove button in TreeView
+ im = gtk.Image()
+ im.set_from_file(hic.ICON_INDI_REMOVE_FILE)
+ self.rem_icon = im.get_pixbuf()
+
+ # class members for internal use
+ self.layer_store = None
+
+ # create visual elements on the dialog
+ self.create_visual_elements()
+ self.connect("response", self.response_cb)
+
+ def create_visual_elements(self):
+ layer_widget, self.layer_store = self.gen_layer_widget(self.layers, self.all_layers, self, None)
+ layer_widget.set_size_request(450, 250)
+ self.vbox.pack_start(layer_widget, expand=True, fill=True)
+ self.show_all()
+
+ def response_cb(self, dialog, response_id):
+ model = self.layer_store
+ it = model.get_iter_first()
+ layers = []
+ while it:
+ layers.append(model.get_value(it, 0))
+ it = model.iter_next(it)
+
+ self.layers_changed = (self.layers != layers)
+ self.layers = layers
+
+ """
+ A custom cell_data_func to draw a delete 'button' in the TreeView for layers
+ other than the meta layer. The deletion of which is prevented so that the
+ user can't shoot themselves in the foot too badly.
+ """
+ def draw_delete_button_cb(self, col, cell, model, it, tv):
+ path = model.get_value(it, 0)
+ if path in self.layers_non_removable:
+ cell.set_sensitive(False)
+ cell.set_property('pixbuf', None)
+ cell.set_property('mode', gtk.CELL_RENDERER_MODE_INERT)
+ else:
+ cell.set_property('pixbuf', self.rem_icon)
+ cell.set_sensitive(True)
+ cell.set_property('mode', gtk.CELL_RENDERER_MODE_ACTIVATABLE)
+
+ return True
+
+ """
+ A custom cell_data_func to write an extra message into the layer path cell
+ for the meta layer. We should inform the user that they can't remove it for
+ their own safety.
+ """
+ def draw_layer_path_cb(self, col, cell, model, it):
+ path = model.get_value(it, 0)
+ if path in self.layers_non_removable:
+ cell.set_property('markup', "<b>It cannot be removed</b>\n%s" % path)
+ else:
+ cell.set_property('text', path)
+
+ def del_cell_clicked_cb(self, cell, path, model):
+ it = model.get_iter_from_string(path)
+ model.remove(it)
OpenPOWER on IntegriCloud