diff --git a/fluents/navigator.py b/fluents/navigator.py index 10c1a7a..4ec3024 100644 --- a/fluents/navigator.py +++ b/fluents/navigator.py @@ -8,6 +8,12 @@ import dataset, logger, plots, project, workflow, main import scipy class NavigatorView (gtk.TreeView): + """The NavigatorView is a tree view of the project. + + There is always one NavigatorView, that shows the functions, plots and + datasets in the current project. + """ + def __init__(self): if main.project: self.data_tree = main.project.data_tree @@ -16,15 +22,14 @@ class NavigatorView (gtk.TreeView): gtk.TreeView.__init__(self) - # various properties - + # Various properties self.set_enable_tree_lines(True) self.set_headers_visible(False) self.get_hadjustment().set_value(0) # Selection Mode self.get_selection().set_mode(gtk.SELECTION_MULTIPLE) - self.get_selection().connect('changed',self.selection_changed_handler) + self.get_selection().connect('changed',self.on_selection_changed) self._previous_selection = [] # Setting up TextRenderers etc @@ -41,7 +46,8 @@ class NavigatorView (gtk.TreeView): self.object_col = gtk.TreeViewColumn('Object') self.object_col.pack_start(pixbufrenderer,expand=False) self.object_col.pack_start(textrenderer,expand=False) - self.object_col.set_attributes(textrenderer, cell_background=3, foreground=4, text=0) + self.object_col.set_attributes(textrenderer, cell_background=3, + foreground=4, text=0) self.object_col.set_attributes(pixbufrenderer, pixbuf=5) self.append_column(self.object_col) @@ -54,20 +60,22 @@ class NavigatorView (gtk.TreeView): logger.log('debug', 'Initializing navigator window.') - # sets data for drag event. def slot_drag_data(self, treeview, context, selection, target_id, etime): + """Sets the data for a drag event.""" treeselection = treeview.get_selection() model, paths = treeselection.get_selected_rows() if paths: self.data_tree.drag_data_get(paths[0], selection) def add_project(self, project): + """Dependency injection.""" self.data_tree = project.data_tree self.set_model(project.data_tree) self.data_tree.connect('row-changed',self.on_row_changed) - # selection changed, setting current_data ojbects - def selection_changed_handler(self, selection): + def on_selection_changed(self, selection): + """Update the list of currently selected datasets.""" + # update prev selection right away in case of multiple events model, paths = selection.get_selected_rows() if not paths: # a plot is marked: do nothing @@ -75,17 +83,17 @@ class NavigatorView (gtk.TreeView): tmp = self._previous_selection self._previous_selection = paths + tree = self.data_tree # set timestamp on newly selected objects - [self.data_tree.set_value(self.data_tree.get_iter(path), 6, time.time()) + [tree.set_value(tree.get_iter(path), 6, time.time()) for path in paths if path not in tmp] - objs = [self.data_tree.get_iter(path) for path in paths] - objs = [(self.data_tree.get_value(iter,6), self.data_tree.get_value(iter,2)) - for iter in objs] + objs = [tree.get_iter(path) for path in paths] + objs = [(tree[iter][6], tree[iter][2]) for iter in objs] + objs.sort() objs = [obj for timestamp, obj in objs] - # order dataset if objs and isinstance(objs[0], dataset.Dataset): logger.log('debug', 'Selecting dataset') @@ -94,17 +102,16 @@ class NavigatorView (gtk.TreeView): logger.log('debug', 'Deselecting dataset') main.project.set_current_data([]) - - # TreeView changed. Set correct focus and colours def on_row_changed(self, treestore, pos, iter): - obj = treestore.get_value(iter,2) - type_= treestore.get_value(iter,1) + """Set correct focus and colours when rows have changed.""" + obj = treestore[iter][2] + obj_type = treestore[iter][1] - if not (treestore.get_value(iter,2) or treestore.get_value(iter,1)): + if not (obj or obj_type): return self.expand_to_path(pos) - if isinstance(obj,dataset.Dataset): + if isinstance(obj, dataset.Dataset): self.set_cursor(pos) self.grab_focus() @@ -135,12 +142,12 @@ class NavigatorView (gtk.TreeView): def on_mouse_event(self, widget, event): path = widget.get_path_at_pos(int(event.x), int(event.y)) - iter = None if path: iter = self.data_tree.get_iter(path[0]) obj = self.data_tree.get_value(iter, 2) else: + iter = None obj = None if isinstance(obj, dataset.Dataset): @@ -152,9 +159,15 @@ class NavigatorView (gtk.TreeView): self.menu.popup(None, None, None, event.button, event.time) def on_cursor_changed(self, widget): + """Update statusbar to contain dataset information. + + Lists the dimensions of a dataset in the statusbar of the program + if a dataset is focused in the navigator. + """ path = widget.get_cursor()[0] tree_iter = self.data_tree.get_iter(path) obj = self.data_tree.get_value(tree_iter, 2) + if isinstance(obj, dataset.Dataset): dims = zip(obj.get_dim_name(), obj.shape) dim_text = ", ".join(["%s (%d)" % dim for dim in dims]) @@ -250,30 +263,35 @@ class NavigatorMenu(gtk.Menu): self.plot_item.set_property('sensitive', True) self.trans_item.set_property('sensitive', True) + def load_dataset(self, filename): + """Load the dataset from the given file and add it to the project.""" + ds = dataset.read_ftsv(filename) + + if isinstance(ds, dataset.GraphDataset): + icon = fluents.icon_factory.get("graph_dataset") + elif isinstance(ds, dataset.CategoryDataset): + icon = fluents.icon_factory.get("category_dataset") + else: + icon = fluents.icon_factory.get("dataset") + + main.project.add_dataset(ds) + main.project.data_tree_insert(None, ds.get_name(), ds, None, "black", icon) + def on_load_dataset(self, item, navigator): + # Set up file chooser. dialog = gtk.FileChooserDialog('Load dataset') dialog.set_action(gtk.FILE_CHOOSER_ACTION_OPEN) - dialog.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK) + dialog.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, + gtk.STOCK_OPEN, gtk.RESPONSE_OK) dialog.set_select_multiple(True) dialog.set_current_folder(main.options.datadir) + retval = dialog.run() if retval in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]: pass elif retval == gtk.RESPONSE_OK: for filename in dialog.get_filenames(): - fd = open(filename) - ds = dataset.read_ftsv(fd) - fd.close() - - if isinstance(ds, dataset.GraphDataset): - icon = fluents.icon_factory.get("graph_dataset") - elif isinstance(ds, dataset.CategoryDataset): - icon = fluents.icon_factory.get("category_dataset") - else: - icon = fluents.icon_factory.get("dataset") - - main.project.add_dataset(ds) - main.project.data_tree_insert(None, ds.get_name(), ds, None, "black", icon) + self.load_dataset(filename) else: print "unknown; ", retval dialog.destroy() diff --git a/fluents/project.py b/fluents/project.py index 6e2e71a..e794570 100644 --- a/fluents/project.py +++ b/fluents/project.py @@ -7,14 +7,21 @@ import logger import dataset, plots, main class Project: + """A Project contains datasets, selections etc. + The project, of which the application has only one at any given time, + is the container for all datasets, plots and selections in use. The data + in the project is organized in a gtk.TreeStrore that is displayed in the + navigator. + """ + def __init__(self,name="Testing"): - self.data_tree = gtk.TreeStore(gobject.TYPE_STRING, - gobject.TYPE_STRING, - gobject.TYPE_PYOBJECT, - gobject.TYPE_STRING, - gobject.TYPE_STRING, - gobject.TYPE_OBJECT, - gobject.TYPE_DOUBLE) + self.data_tree = gtk.TreeStore(str, + str, + object, + str, + str, + gobject.TYPE_OBJECT, + float) self.name = name self.dim_names = [] @@ -104,16 +111,17 @@ class Project: elif isinstance(d, dataset.Selection): self.add_selection(d) - def data_tree_insert(self, parent, text, data, bgcolour, fontcolour, icon, selected = 0): + def data_tree_insert(self, parent, text, data, bg, fg, icon, selected = 0): + """Inserts data into the tree view. + @param text: The title of the object. + @param data: A dataset, plot or function object. + @param bg: Background color. + @param fg: Foreground (font) color. + @param icon: Pixmap icon. + """ tree = self.data_tree it = tree.append(parent) - tree.set_value(it, 0, text) - tree.set_value(it, 1, type(data)) - tree.set_value(it, 2, data) - tree.set_value(it, 3, bgcolour) - tree.set_value(it, 4, fontcolour) - tree.set_value(it, 5, icon) - tree.set_value(it, 6, selected) + tree[it] = [text, type(data), data, bg, fg, icon, selected] self._dataset_iter_map[data] = it return it @@ -144,4 +152,3 @@ class Project: def set_current_data(self, obj): self.current_data = obj -