from system import logger, dataset import pygtk import gtk import gtk.gdk import gtk.glade import gnome import gnome.ui import gobject class SimpleMenu(gtk.Menu): def __init__(self): gtk.Menu.__init__(self) def add_simple_item(self, title, function): item = gtk.MenuItem(title) item.connect('activate', function) self.append(item) item.show() class SelectionTree(gtk.TreeView): def __init__(self): self.store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT) gtk.TreeView.__init__(self, self.store) renderer = gtk.CellRendererText() sel_column = gtk.TreeViewColumn('Selection', renderer, text=0) self.insert_column(sel_column, 0) self.connect('row-activated', self._on_row_activated) self._identifier_list = None self._dim_list = {} # A mapping of selection names to selection lines. self._selections = [] self.set_headers_visible(True) self._current_dim = None self._current_selection = None # Set up context menu self._menu = SimpleMenu() self._menu.add_simple_item('Select', self._on_set_selection) self.connect('popup_menu', self._on_popup_menu) self.connect('button_press_event', self._on_button_press_event) def set_identifier_list(self, identifier_list): """Dependency injection. Sets the widget that should be used to display the selected identifiers.""" self._identifier_list = identifier_list def set_project(self, project): """Dependency injection. Set the current project.""" self.project = project project.add_selection_observer(self) project.add_dataset_observer(self) self.update_dims(project.dim_names) self.add_selection(project.get_selection()) def selection_changed(self, selection): """Callback on selection update""" self.update_dims(selection.keys()) self.add_selection(selection) self._update_current_dim() def get_selection_iter(self, dimname, selection): i = self._dim_list[dimname] if not i: return None children = self.store.iter_children(i) if not children: return None while children: if self.store.get(children, 1)[0] == selection: return self.store.get(children, 1)[0] children = self.store.iter_next(children) return None def dataset_changed(self): """Callback when new datasets are created""" self.selection_changed(self.project.get_selection()) for sel in self.project.selections: if not sel in self._selections: self._selections.append(sel) self.add_selection(sel) def update_dims(self, dim_list): """Update the list of dimensions shown""" for dim in dim_list: if not self._dim_list.has_key(dim): d = self.store.insert_after(None, None, (dim, None)) self._dim_list[dim] = d def add_selection(self, selection): for dim in selection.dims(): if not self.get_selection_iter(dim, selection): d = self._dim_list[dim] i = self.store.insert_after(d, None, (selection.title, selection)) def _update_current_dim(self): if not self._current_dim or not self._current_selection: return id_list = self._current_selection[self._current_dim] self._identifier_list.set_identifiers(id_list) # Callbacks def _on_row_activated(self, treeview, path, column): i = self.store.get_iter(path) p = self.store.iter_parent(i) if p == None: pass else: self._current_dim = self.store.get_value(p, 0) self._current_selection = self.store.get_value(i, 1) self._update_current_dim() def _on_set_selection(self, *rest): if not self._current_selection: return self.project.set_selection(self._current_dim, self._current_selection[self._current_dim]) def _on_button_press_event(self, widget, event): if event.button == 3: self._menu.popup(None, None, None, event.button, event.time) def _on_popup_menu(self): pass class IdentifierList(gtk.TreeView): def __init__(self): self.store = gtk.ListStore(gobject.TYPE_STRING) gtk.TreeView.__init__(self, self.store) self.set_headers_visible(True) # Set up identifier column to show active identifiers renderer = gtk.CellRendererText() ids_column = gtk.TreeViewColumn('Identifiers', renderer, text=0) self.insert_column(ids_column, 0) def set_identifiers(self, identifiers): "Show the list of identifier strings." self.store.clear() for e in identifiers: self.store.append((e,))