class GTKProject(SlaveDelegate): """A facade of kmcos.types.Project so that pygtk can display in a TreeView. """ def __init__(self, parent, menubar): self.project_data = ObjectTree([ Column('name', use_markup=True, data_type=str, sorted=True), Column('info') ]) self.project_data.connect('row-activated', self.on_row_activated) self.model_tree = Project() self._set_treeview_hooks() self.menubar = menubar self.set_parent(parent) self.filename = '' self.undo_stack = UndoStack(self.model_tree.__repr__, self.import_file, self.project_data.select, menubar, self.meta, 'Initialization') SlaveDelegate.__init__(self, toplevel=self.project_data) def _set_treeview_hooks(self): """Fudge function to import to access function to kmcos.types.Project to kmcos.gui.GTKProject. """ self.project_data.clear() # Meta self.meta = self.project_data.append(None, self.model_tree.meta) self.model_tree.meta = self.meta # Layer List self.model_tree.add_layer = self.add_layer self.layer_list = self.project_data.append(None, self.model_tree.layer_list) self.get_layers = lambda: \ sorted(self.project_data.get_descendants(self.layer_list), key=lambda x: x.name) self.model_tree.get_layers = self.get_layers self.lattice = self.layer_list # Parameter List self.parameter_list = self.project_data.append( None, self.model_tree.parameter_list) self.add_parameter = lambda parameter: \ self.project_data.append(self.parameter_list, parameter) self.model_tree.add_parameter = self.add_parameter self.get_parameters = lambda: \ sorted(self.project_data.get_descendants(self.parameter_list), key=lambda x: x.name) self.model_tree.get_parameters = self.get_parameters # Species List self.species_list = self.project_data.append( None, self.model_tree.species_list) self.add_species = lambda species: \ self.project_data.append(self.species_list, species) self.model_tree.add_species = self.add_species self.get_speciess = lambda: \ sorted(self.project_data.get_descendants(self.species_list), key=lambda x: x.name) self.model_tree.get_speciess = self.get_speciess # Process List self.process_list = self.project_data.append( None, self.model_tree.process_list) self.add_process = lambda process:\ self.project_data.append(self.process_list, process) self.model_tree.add_process = self.add_process self.get_processes = lambda: \ sorted(self.project_data.get_descendants(self.process_list), key=lambda x: x.name) self.model_tree.get_processes = self.get_processes # Output List self.output_list = self.project_data.append( None, self.model_tree.output_list) self.add_output = lambda output:\ self.project_data.append(self.output_list, output) self.model_tree.add_output = self.add_output self.get_outputs = lambda: \ sorted(self.project_data.get_descendants(self.output_list), key=lambda x: x.name) self.model_tree.get_outputs = self.get_outputs def add_layer(self, layer): self.project_data.append(self.layer_list, layer) if len(self.get_layers()) == 1: self.set_default_layer(layer.name) self.set_substrate_layer(layer.name) return layer def set_default_species(self, species): self.model_tree.species_list.default_species = species def set_substrate_layer(self, layer): self.model_tree.layer_list.substrate_layer = layer def set_default_layer(self, layer): self.model_tree.layer_list.default_layer = layer def update(self, model): """Update the object tree.""" self.project_data.update(model) def on_row_activated(self, _tree, data): if isinstance(data, Layer): data.active = not data.active def get_name(self): """Return project name.""" if self.filename: return os.path.basename(self.filename) else: return 'Untitled' def __repr__(self): return str(self.model_tree) def import_file(self, filename): """Import XML project file into editor GUI, unfolding the object tree. """ self.filename = filename self.model_tree.import_file(filename) self.expand_all() def expand_all(self): """Expand all list of the project tree """ self.project_data.expand(self.species_list) self.project_data.expand(self.layer_list) self.project_data.expand(self.parameter_list) self.project_data.expand(self.process_list) self.project_data.expand(self.output_list) def on_key_press(self, _, event): """When the user hits the keyboard focusing the treeview this event is triggered. Right now the only supported function is to deleted the selected item """ selection = self.project_data.get_selected() if gtk.gdk.keyval_name(event.keyval) == 'Delete': if (isinstance(selection, Species) or isinstance(selection, Process) or isinstance(selection, Parameter) or isinstance(selection, Layer)): if kiwi.ui.dialogs.yesno( "Do you really want to delete '%s'?" \ % selection.name) == gtk.RESPONSE_YES: self.project_data.remove(selection) def on_project_data__selection_changed(self, _, elem): """When a new item is selected in the treeview this function loads the main area of the window with the corresponding form and data. """ slave = self.get_parent().get_slave('workarea') if slave: self.get_parent().detach_slave('workarea') if isinstance(elem, Layer): if self.meta.model_dimension in [1, 3]: self.get_parent().toast('Only 2d supported') return self.undo_stack.start_new_action('Edit Layer %s' % elem.name, elem) form = LayerEditor(elem, self) self.get_parent().attach_slave('workarea', form) form.focus_topmost() elif isinstance(elem, Meta): self.undo_stack.start_new_action('Edit Meta', elem) meta_form = MetaForm(self.meta, self) self.get_parent().attach_slave('workarea', meta_form) meta_form.focus_toplevel() meta_form.focus_topmost() elif isinstance(elem, OutputList): self.undo_stack.start_new_action('Edit Output', elem) form = OutputForm(self.output_list, self) self.get_parent().attach_slave('workarea', form) form.focus_topmost() elif isinstance(elem, Parameter): self.undo_stack.start_new_action('Edit Parameter %s' % elem.name, elem) form = ParameterForm(elem, self) self.get_parent().attach_slave('workarea', form) form.focus_topmost() elif isinstance(elem, Process): if self.meta.model_dimension in [1, 3]: self.get_parent().toast('Only 2d supported') return self.undo_stack.start_new_action('Edit Process %s' % elem.name, elem) form = ProcessForm(elem, self) self.get_parent().attach_slave('workarea', form) form.focus_topmost() elif isinstance(elem, ProcessList): if self.meta.model_dimension in [1, 3]: self.get_parent().toast('Only 2d supported') return self.undo_stack.start_new_action('Batch process editing', elem) form = BatchProcessForm(self) self.get_parent().attach_slave('workarea', form) form.focus_topmost() elif isinstance(elem, Species): self.undo_stack.start_new_action('Edit species', elem) form = SpeciesForm(elem, self.project_data) self.get_parent().attach_slave('workarea', form) form.focus_topmost() elif isinstance(elem, SpeciesList): self.undo_stack.start_new_action('Edit default species', elem) form = SpeciesListForm(elem, self) self.get_parent().attach_slave('workarea', form) form.focus_topmost() elif isinstance(elem, LayerList): self.undo_stack.start_new_action('Edit lattice', elem) dimension = self.meta.model_dimension form = LatticeForm(elem, dimension, self) self.get_parent().attach_slave('workarea', form) form.focus_topmost() else: self.get_parent().toast('Not implemented, yet(%s).' % type(elem))
class GTKProject(SlaveDelegate): """A facade of kmos.types.Project so that pygtk can display in a TreeView. """ def __init__(self, parent, menubar): self.project_data = ObjectTree([Column('name', use_markup=True, data_type=str, sorted=True), Column('info')]) self.project_data.connect('row-activated', self.on_row_activated) self.model_tree = Project() self._set_treeview_hooks() self.menubar = menubar self.set_parent(parent) self.filename = '' self.undo_stack = UndoStack( self.model_tree.__repr__, self.import_xml_file, self.project_data.select, menubar, self.meta, 'Initialization') SlaveDelegate.__init__(self, toplevel=self.project_data) def _set_treeview_hooks(self): """Fudge function to import to access function to kmos.types.Project to kmos.gui.GTKProject. """ self.project_data.clear() # Meta self.meta = self.project_data.append(None, self.model_tree.meta) self.model_tree.meta = self.meta # Layer List self.model_tree.add_layer = self.add_layer self.layer_list = self.project_data.append(None, self.model_tree.layer_list) self.get_layers = lambda :\ sorted(self.project_data.get_descendants(self.layer_list), key=lambda x: x.name) self.model_tree.get_layers = self.get_layers self.lattice = self.layer_list # Parameter List self.parameter_list = self.project_data.append(None, self.model_tree.parameter_list) self.add_parameter = lambda parameter :\ self.project_data.append(self.parameter_list, parameter) self.model_tree.add_parameter = self.add_parameter self.get_parameters = lambda :\ sorted(self.project_data.get_descendants(self.parameter_list), key=lambda x: x.name) self.model_tree.get_parameters = self.get_parameters # Species List self.species_list = self.project_data.append(None, self.model_tree.species_list) self.add_species = lambda species :\ self.project_data.append(self.species_list, species) self.model_tree.add_species = self.add_species self.get_speciess = lambda :\ sorted(self.project_data.get_descendants(self.species_list), key=lambda x: x.name) self.model_tree.get_speciess = self.get_speciess # Process List self.process_list = self.project_data.append(None, self.model_tree.process_list) self.add_process = lambda process:\ self.project_data.append(self.process_list, process) self.model_tree.add_process = self.add_process self.get_processes = lambda :\ sorted(self.project_data.get_descendants(self.process_list), key=lambda x: x.name) self.model_tree.get_processes = self.get_processes # Output List self.output_list = self.project_data.append(None, self.model_tree.output_list) self.add_output = lambda output:\ self.project_data.append(self.output_list, output) self.model_tree.add_output = self.add_output self.get_outputs = lambda : \ sorted(self.project_data.get_descendants(self.output_list), key=lambda x: x.name) self.model_tree.get_outputs = self.get_outputs def add_layer(self, layer): self.project_data.append(self.layer_list, layer) if len(self.get_layers()) == 1 : self.set_default_layer(layer.name) self.set_substrate_layer(layer.name) def set_default_species(self, species): self.model_tree.species_list.default_species = species def set_substrate_layer(self, layer): self.model_tree.layer_list.substrate_layer = layer def set_default_layer(self, layer): self.model_tree.layer_list.default_layer = layer def update(self, model): self.project_data.update(model) def on_row_activated(self, tree, data): if isinstance(data, Layer): data.active = not data.active def get_name(self): if self.filename: return os.path.basename(self.filename) else: return 'Untitled' def __repr__(self): return str(self.model_tree) def import_xml_file(self, filename): self.model_tree.import_xml_file(filename) self.expand_all() def expand_all(self): """Expand all list of the project tree """ self.project_data.expand(self.species_list) self.project_data.expand(self.layer_list) self.project_data.expand(self.parameter_list) self.project_data.expand(self.process_list) self.project_data.expand(self.output_list) def on_key_press(self, _, event): """When the user hits the keyboard focusing the treeview this event is triggered. Right now the only supported function is to deleted the selected item """ selection = self.project_data.get_selected() if gtk.gdk.keyval_name(event.keyval) == 'Delete': if(isinstance(selection, Species) or isinstance(selection, Process) or isinstance(selection, Parameter) or isinstance(selection, Layer)): if kiwi.ui.dialogs.yesno( "Do you really want to delete '%s'?" \ % selection.name) == gtk.RESPONSE_YES: self.project_data.remove(selection) def on_project_data__selection_changed(self, _, elem): """When a new item is selected in the treeview this function loads the main area of the window with the corresponding form and data. """ slave = self.get_parent().get_slave('workarea') if slave: self.get_parent().detach_slave('workarea') if isinstance(elem, Layer): if self.meta.model_dimension in [1, 3]: self.get_parent().toast('Only 2d supported') return self.undo_stack.start_new_action('Edit Layer %s' % elem.name, elem) form = LayerEditor(elem, self) self.get_parent().attach_slave('workarea', form) form.focus_topmost() elif isinstance(elem, Meta): self.undo_stack.start_new_action('Edit Meta', elem) meta_form = MetaForm(self.meta, self) self.get_parent().attach_slave('workarea', meta_form) meta_form.focus_toplevel() meta_form.focus_topmost() elif isinstance(elem, OutputList): self.undo_stack.start_new_action('Edit Output', elem) form = OutputForm(self.output_list, self) self.get_parent().attach_slave('workarea', form) form.focus_topmost() elif isinstance(elem, Parameter): self.undo_stack.start_new_action('Edit Parameter %s' % elem.name, elem) form = ParameterForm(elem, self) self.get_parent().attach_slave('workarea', form) form.focus_topmost() elif isinstance(elem, Process): if self.meta.model_dimension in [1, 3]: self.get_parent().toast('Only 2d supported') return self.undo_stack.start_new_action('Edit Process %s' % elem.name, elem) form = ProcessForm(elem, self) self.get_parent().attach_slave('workarea', form) form.focus_topmost() elif isinstance(elem, ProcessList): if self.meta.model_dimension in [1, 3]: self.get_parent().toast('Only 2d supported') return self.undo_stack.start_new_action('Batch process editing', elem) form = BatchProcessForm(self) self.get_parent().attach_slave('workarea', form) form.focus_topmost() elif isinstance(elem, Species): self.undo_stack.start_new_action('Edit species', elem) form = SpeciesForm(elem, self.project_data) self.get_parent().attach_slave('workarea', form) form.focus_topmost() elif isinstance(elem, SpeciesList): self.undo_stack.start_new_action('Edit default species', elem) form = SpeciesListForm(elem, self) self.get_parent().attach_slave('workarea', form) form.focus_topmost() elif isinstance(elem, LayerList): self.undo_stack.start_new_action('Edit lattice', elem) dimension = self.meta.model_dimension form = LatticeForm(elem, dimension, self) self.get_parent().attach_slave('workarea', form) form.focus_topmost() else: self.get_parent().toast('Not implemented, yet(%s).' % type(elem))
class NoteUI(GladeSlaveDelegate): def __init__(self, parent, mo): self.parent = parent self.mo = mo self.factory = Factory() # Set up the user interface GladeSlaveDelegate.__init__(self, gladefile="mo_tab_notes", toplevel_name="window_main") noteColumns = [ Column("summary", title='Title', data_type=str), ] #self.treeview_note = ObjectList(noteColumns) self.treeview_note = ObjectTree(noteColumns) self.vbox_notelist.add(self.treeview_note) # Connect signals self.treeview_note.connect('row-activated', self.treeview_note__row_activated) self.treeview_note.connect('selection-changed', self.treeview_note__selection_changed) self.treeview_note.connect('key-press-event', self.treeview_note__key_press_event) self.refresh() def refresh(self): self.treeview_note.clear() for journal in self.mo.cal_model.get_journals(): parent = self.mo.cal_model.get_model_by_uid(journal.get_related_to()) self.treeview_note.append(parent, journal) def on_toolbutton_add__clicked(self, *args): journal = self.factory.journal() journal = miniorganizer.ui.NoteEditUI(self.mo, journal).run() if journal: self.mo.cal_model.add(journal) self.treeview_note.append(None, journal) self.parent.menuitem_save.set_sensitive(True) def on_toolbutton_addsub__clicked(self, *args): parent_journal = self.treeview_note.get_selected() journal = self.factory.journal(parent_journal) if miniorganizer.ui.NoteEditUI(self.mo, journal).run(): self.mo.cal_model.add(journal) self.treeview_note.append(parent_journal, journal) self.treeview_note.expand(parent_journal) self.parent.menuitem_save.set_sensitive(True) def on_toolbutton_edit__clicked(self, *args): sel_note = self.treeview_note.get_selected() self.treeview_note__row_activated(self.treeview_note, sel_note) def on_toolbutton_remove__clicked(self, *args): sel_note = self.treeview_note.get_selected() if sel_note: children = self.mo.cal_model.get_models_related_by_uid(sel_note.get_uid()) if children: response = dialogs.warning('This note contains sub-notes. Removing it will also remove the sub-notes. Is this what you want?', buttons=gtk.BUTTONS_YES_NO) if response != gtk.RESPONSE_YES: return self.mo.cal_model.delete(sel_note, True) self.treeview_note.remove(sel_note, True) self.parent.menuitem_save.set_sensitive(True) def treeview_note__selection_changed(self, list, selection): has_selection = selection is not None self.toolbutton_addsub.set_sensitive(has_selection) self.toolbutton_remove.set_sensitive(has_selection) self.toolbutton_edit.set_sensitive(has_selection) def treeview_note__row_activated(self, list, object): sel_note = self.treeview_note.get_selected() note = miniorganizer.ui.NoteEditUI(self.mo, sel_note).run() def treeview_note__key_press_event(self, treeview, event): if event.keyval == gtk.keysyms.Delete: self.on_toolbutton_remove__clicked()
class TodoUI(GladeSlaveDelegate): def __init__(self, parent, mo): self.parent = parent self.mo = mo self.factory = Factory() GladeSlaveDelegate.__init__(self, gladefile="mo_tab_todo", toplevel_name="window_main") # Set up the user interface todoColumns = [ Column("done", title='Done', data_type=bool, editable=True), Column("summaryformat", title='Summary', use_markup=True), Column('priority', title='Priority', sorted=True, order=gtk.SORT_DESCENDING), ColoredColumn('due', title='Due', data_type=datetime.datetime, color='red', data_func=self.color_due), Column('created', title='Created', data_type=datetime.datetime) ] self.treeview_todo = ObjectTree(todoColumns) self.vbox_todolist.add(self.treeview_todo) # Connect signals self.treeview_todo.connect('row-activated', self.treeview_todo__row_activated) self.treeview_todo.connect('selection-changed', self.treeview_todo__selection_changed) self.treeview_todo.connect('key-press-event', self.treeview_todo__key_press_event) self.refresh() def refresh(self): """ Refresh the entire todo tab. This clears everything and rebuilds it. Call this when todos are removed outside of this class. """ self.treeview_todo.clear() # Fill the user interface with information for todo in self.mo.cal_model.get_todos(): parent = self.mo.cal_model.get_model_by_uid(todo.get_related_to()) self.treeview_todo.append(parent, todo) def color_due(self, value): if not value: return(False) return(value < datetime.datetime.now()) def on_toolbutton_add__clicked(self, *args): todo = self.factory.todo() todo = miniorganizer.ui.TodoEditUI(self.mo, todo).run() if todo: self.mo.cal_model.add(todo) self.treeview_todo.append(None, todo) self.parent.menuitem_save.set_sensitive(True) def on_toolbutton_edit__clicked(self, *args): sel_todo = self.treeview_todo.get_selected() self.treeview_todo__row_activated(self.treeview_todo, sel_todo) def on_toolbutton_remove__clicked(self, *args): sel_todo = self.treeview_todo.get_selected() if sel_todo: children = self.mo.cal_model.get_models_related_by_uid(sel_todo.get_uid()) if children: response = dialogs.warning('This Todo contains sub-todos. Removing it will also remove the sub-todos. Is this what you want?', buttons=gtk.BUTTONS_YES_NO) if response != gtk.RESPONSE_YES: return self.treeview_todo.remove(sel_todo, True) self.mo.cal_model.delete(sel_todo, True) self.parent.menuitem_save.set_sensitive(True) def on_toolbutton_addsub__clicked(self, *args): parent_todo = self.treeview_todo.get_selected() todo = self.factory.todo(parent_todo) if miniorganizer.ui.TodoEditUI(self.mo, todo).run(): self.mo.cal_model.add(todo) self.treeview_todo.append(parent_todo, todo) self.treeview_todo.expand(parent_todo) self.parent.menuitem_save.set_sensitive(True) def treeview_todo__selection_changed(self, list, selection): has_selection = selection is not None self.toolbutton_addsub.set_sensitive(has_selection) self.toolbutton_remove.set_sensitive(has_selection) self.toolbutton_edit.set_sensitive(has_selection) def treeview_todo__row_activated(self, list, object): todo = miniorganizer.ui.TodoEditUI(self.mo, object).run() self.parent.menuitem_save.set_sensitive(True) def treeview_todo__key_press_event(self, treeview, event): if event.keyval == gtk.keysyms.Delete: self.on_toolbutton_remove__clicked()