def __init__(self): self.filename = '' self.attributes = {} self.refimage = '' self.exp_list = [] self.exp_list.append(Experiment()) self.current_experiment = self.exp_list[-1] self.bug_max_speed = 3 self.bug_size = 39 self.attributes[_("Project Name")] = _("Project")
def edited_cb(self, entry, obj, depth): entry.set_sensitive(True) if depth == 0: #project object obj.attributes[_("Project Name")] = entry.get_text() elif depth == 1: #exp object obj.attributes[_("Experiment Name")] = entry.get_text() elif depth == 2: #area object obj.name = entry.get_text() elif depth == 3: #track object entry.set_sensitive(False)
def __init__(self): self.point_list = [] self.areas_list = [] self.start_time = '' self.end_time = '' self.attributes = {} self.measurement_unit = 'cm' self.x_scale_ratio = 1 self.y_scale_ratio = 1 self.scale_shape = None self.threshold = 0x30 self.release_area = [0, 0, 480, 640] self.attributes[_("Experiment Name")] = _("Experiment") self.finished = False
def load_project(self, widget): ''' Shows the load dialog. Asks the user the filename of the project, and load it. ''' main = self.xml.get_widget("mainwindow") filename = None fsdial = gtk.FileChooserDialog(_("Load Project"), main, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) fsdial.set_current_folder(self.home) response = fsdial.run() if response != gtk.RESPONSE_OK: fsdial.destroy() else: filename = fsdial.get_filename() self.update_state() fsdial.destroy() if filename: prj = self.project.load(filename) if prj: self.project = prj self.update_state() else: # TODO: print error print "error loading project"
def populate(self, view, event, model): model.clear() project = model.append( None, [ self.project.attributes[_("Project Name")], self.project ] ) for exp in self.project.exp_list: parent = model.append( project, [ exp.attributes[_("Experiment Name")], exp ] ) for area in exp.areas_list: area_parent = model.append( parent, [area.name, area] ) for track in area.track_list: model.append( area_parent, [ str(track.start_time.time()), track ] ) view.set_model(model) view.expand_all()
def fill_experiment_combo(self): combo = self.xml.get_widget("comboboxExperiment") model = combo.get_model() if model == None: model = gtk.ListStore(gobject.TYPE_STRING) model.clear() for exp in self.project.exp_list: model.append([exp.attributes[_("Experiment Name")]]) combo.set_model(model) combo.set_active(0) self.fill_area_combo(self.project.exp_list[0])
def set_as_release_area(self, wid): ''' Set the current selected shape as the release area. ''' if self.selected_shape != None: self.release_area = self.selected_shape else: diag = gtk.MessageDialog( self.window, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("An area must be selected")) diag.run() diag.destroy()
def report(self, widget): ''' Shows the report dialog. ''' fsdialog = gtk.FileChooserDialog( _("Save Report"), self.window, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) if self.project.filename: fsdialog.set_current_folder(self.project.filename) else: fsdialog.set_current_folder(self.home) response = fsdialog.run() if response == gtk.RESPONSE_OK: filename = fsdialog.get_filename() + '.csv' self.project.export(filename) fsdialog.destroy() msg = gtk.MessageDialog(self.window, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("Report generated.")) msg.run() msg.destroy()
def new_project(self, widget): ''' Creates a new project. Asks the user if he wants to save the current project, and deals with the answer. ''' if self.project: diag = gtk.MessageDialog( self.window, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _("Do you want to save the current project?")) response = diag.run() if response == gtk.RESPONSE_YES: diag.destroy() self.save_project(None) self.project = Project() else: diag.destroy() self.project = Project() response = self.propdiag.run(None, self.project) if response == False: return self.device_manager.pipeline_start() response = self.refimgdiag.run(None, self.project, self.device_manager, self) if response == False: self.update_state() return response = self.areasdiag.run(None, self.project, self) if response == False: self.update_state() return response = self.scalediag.run(None, self.project, self) if response == False: self.update_state() return response = self.insectsizediag.run(None, self.project, self) if response == False: self.update_state() return self.update_state()
def save_project(self, widget): ''' Shows the save dialog. Asks the user where to save the project, and save it. ''' if self.invalid["path"]: fsdialog = gtk.FileChooserDialog( _("Save Project"), self.window, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) fsdialog.set_current_folder(self.home) self.invalid["path"] = True while self.invalid["path"]: response = fsdialog.run() if response == gtk.RESPONSE_OK: current = fsdialog.get_current_folder() filepath = fsdialog.get_filename() filename = filepath[len(current) + 1:] try: os.makedirs(filepath) except OSError, why: errordiag = gtk.MessageDialog( fsdialog, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, why.args[1]) errordiag.run() errordiag.destroy() else: self.invalid["path"] = False fsdialog.destroy() else: self.invalid["path"] = True fsdialog.destroy() return self.project.filename = filepath + '/' + filename + '.exp' self.project.save()
def __init__(self, xml, project): self.xml = xml self.project = project self.edited_hndl = None view = self.xml.get_widget("treeviewPrjManager") model = gtk.TreeStore( gobject.TYPE_STRING, gobject.TYPE_PYOBJECT ) self.populate(view, None, model) # renderer of the first column renderer = gtk.CellRendererText() column = gtk.TreeViewColumn(_("Name"), renderer, text=0) view.append_column(column) view.set_expander_column(column) # treat single selection only selection = view.get_selection() selection.set_mode(gtk.SELECTION_SINGLE) # TODO: this signal will determine the right side of the manager # (wheter to show properties from track, area, exp or project). view.connect("cursor_changed", self.changed_cursor_cb) view.connect("visibility-notify-event", self.populate, model)
def __init__(self, project): gladefile = environ.find_resource('glade', 'areas.glade') self.xml = gtk.glade.XML(gladefile, domain=APP_NAME) self.project = project self.output_handler = None # widgets to be used output = self.xml.get_widget("drawingareaAreas") area_name = self.xml.get_widget("entryAreaName") area_desc = self.xml.get_widget("entryAreaDesc") self.window = None # setting up the areas treeview view = self.xml.get_widget("treeviewAreas") # model columns: area name, area shape, area description model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT, gobject.TYPE_STRING) view.set_model(model) # renderer of the first column renderer = gtk.CellRendererText() renderer.props.editable = True renderer.connect("edited", self.edited_cb, area_name, view.get_model(), 0) column = gtk.TreeViewColumn(_("Name"), renderer, text=0) view.append_column(column) # renderer of the second column renderer = gtk.CellRendererText() renderer.props.editable = True renderer.connect("edited", self.edited_cb, area_desc, view.get_model(), 2) column = gtk.TreeViewColumn(_("Description"), renderer, text=2) view.append_column(column) # To treat single selection only selection = view.get_selection() selection.set_mode(gtk.SELECTION_SINGLE) view.connect("cursor_changed", self.select_area, output, area_name, area_desc) #connecting the callbacks of the areasDiag widget = self.xml.get_widget("buttonAddArea") widget.connect("clicked", self.shape_action, "add") widget = self.xml.get_widget("buttonRemoveArea") widget.connect("clicked", self.remove_area) widget = self.xml.get_widget("buttonResizeArea") widget.connect("clicked", self.shape_action, "resize") widget = self.xml.get_widget("buttonMoveArea") widget.connect("clicked", self.shape_action, "move") #buttons to define the shape that will be drawn widget = self.xml.get_widget("buttonRectangle") widget.connect("clicked", self.set_shape, "rectangle") widget = self.xml.get_widget("buttonEllipse") widget.connect("clicked", self.set_shape, "ellipse") widget = self.xml.get_widget("buttonSetReleaseArea") widget.connect("clicked", self.set_as_release_area) self.release_area = None #default shape to be drawn self.shape_type = "rectangle" #default action is to add an area self.action = "add" self.composing_shape = False self.moving_shape_started = False self.resizing_shape_started = False self.graphic_context = None self.red_gc = None self.start_point = None self.end_point = None self.first_point = None self.last_point = None self.initial_point = None self.final_point = None self.selected_shape = None self.resizing_shape = None self.temp_shape = None self.moving_shape = None output.add_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.BUTTON_MOTION_MASK | gtk.gdk.KEY_PRESS_MASK | gtk.gdk.KEY_RELEASE_MASK) #these three are necessary to draw something in the draw area output.connect("button-press-event", self.compose_shape) output.connect("motion-notify-event", self.compose_shape) output.connect("button-release-event", self.finish_shape, model, area_name, area_desc, view)
def export(self): ''' Export the experiment to CSV format.''' rows = [] for key in self.attributes: rows.append((key, self.attributes[key])) # for each area in the experiment, export name and shape for item in self.areas_list: rows.append(("")) rows.append((_("Area Name: "), item.name)) rows.append((_("Area Description: "), item.description)) if isinstance(item.shape, Rectangle): rows.append((_("Area Shape: "), _("Rectangle"))) elif isinstance(item.shape, Ellipse): rows.append((_("Area Shape: "), _("Ellipse"))) #for each track in area, export the data needed if item.track_list == []: string = _("Insect didn't enter in this area, no data " "available") rows.append((string, "")) else: rows.append((_("Track List: "), "")) rows.append( ("", _("Start Time "), _("End Time "), _("Residence "), _("Tortuosity "), _("Lenght (") + self.measurement_unit + ") ", _("Average Speed (") \ + self.measurement_unit + "/s) ", _("Standard Deviation"), _("Angular Average Speed"), _("Angular Standard Deviation")) ) for trk in item.track_list: rows.append( ("", trk.start_time, trk.end_time, trk.total_time, trk.tortuosity, trk.lenght, trk.mean_lin_speed, trk.lin_speed_deviation, trk.meanAngleSpeed, trk.angle_speed_deviation)) rows.append(('')) rows.append((_("Resume: "), "")) rows.append((_("Residence: "), item.residence)) rows.append( (_("Residence (%): "), item.residence_percentage * 100)) rows.append( (_("Average Lenght (") \ + self.measurement_unit + "): ", item.total_lenght / item.number_of_tracks) ) rows.append( (_("Total Lenght (") \ + self.measurement_unit + "): ", item.total_lenght) ) #TODO: this value is different from the calculated in the track div = (float(item.residence.seconds) + float(item.residence.microseconds / 1000000)) if div: value = item.total_lenght / div else: value = 0 rows.append( (_("Average Speed (") + self.measurement_unit\ + "/s): ", value) ) rows.append(('')) rows.append(('')) return rows
def run(self, wid, project): ''' Run the specific dialog and save the changes in the project. ''' propdiag = self.gui.get_widget("dialogProjProp") propdiag.show_all() experiment = project.current_experiment entry_bio = self.gui.get_widget("entryNameProject") entry_exp = self.gui.get_widget("entryNameExperiment") entry_name = self.gui.get_widget("entryNameInsect") entry_comp = self.gui.get_widget("entryComp") entry_temp = self.gui.get_widget("entryTemp") hscale_threshold = self.gui.get_widget("hscaleThreshold") try: temp = project.attributes[_("Project Name")] except KeyError: entry_bio.props.text = "" else: entry_bio.props.text = temp try: temp = experiment.attributes[_("Experiment Name")] except KeyError: entry_exp.props.text = "" else: entry_exp.props.text = temp try: temp = project.attributes[_("Insect Name")] except KeyError: entry_name.props.text = "" else: entry_name.props.text = temp try: temp = project.attributes[_("Compounds used")] except KeyError: entry_comp.props.text = "" else: entry_comp.props.text = temp try: temp = project.attributes[_("Temperature")] except KeyError: entry_temp.props.text = "" else: entry_temp.props.text = temp hscale_threshold.set_value(project.current_experiment.threshold) response = propdiag.run() if response == gtk.RESPONSE_OK: project.attributes[_("Project Name")] = entry_bio.props.text project.attributes[_("Insect Name")] = entry_name.props.text project.attributes[_("Compounds used")] = entry_comp.props.text project.attributes[_("Temperature")] = entry_temp.props.text experiment.attributes[_("Experiment Name")] = entry_exp.props.text experiment.threshold = hscale_threshold.get_value() propdiag.hide_all() return True else: propdiag.hide_all() return False
def update_state(self): ''' Verify if the project values are consistent and update the user interface. ''' if len(self.project.current_experiment.areas_list) == 0: self.invalid["areas"] = True else: self.invalid["areas"] = False if self.project.refimage: self.invalid["refimg"] = False else: self.invalid["refimg"] = True if self.project.filename: if os.path.exists(self.project.filename): self.invalid["path"] = False else: self.invalid["path"] = True if self.project.bug_size: self.invalid["size"] = False else: self.invalid["size"] = True if self.project.bug_max_speed: self.invalid["speed"] = False else: self.invalid["speed"] = True if (self.project.current_experiment.x_scale_ratio and self.project.current_experiment.y_scale_ratio): self.invalid["scale"] = False else: self.invalid["scale"] = True if not self.invalid["scale"]: scale = self.project.current_experiment.x_scale_ratio if not self.invalid["size"]: widget = self.xml.get_widget("scaleSize") widget.set_range(0, self.device_manager.frame["width"] / scale) widget.set_value(self.project.bug_size / scale) widget = self.xml.get_widget("scaleTolerance") widget.set_range(0, self.device_manager.frame["width"] / scale) widget.set_value(self.project.bug_size / scale / 2) if not self.invalid["speed"]: widget = self.xml.get_widget("scaleSpeed") widget.set_range(0, self.device_manager.frame["width"] / scale) widget.set_value(self.project.bug_max_speed / scale) widget = self.xml.get_widget("labelSize") widget.set_text( _("Size (") + self.project.current_experiment.measurement_unit + (") :")) widget = self.xml.get_widget("labelSpeed") widget = self.xml.get_widget("labelTolerance") self.connect_project_signals() prj = self.project.attributes[_("Project Name")] exp = self.project.current_experiment.attributes[_("Experiment Name")] self.window.set_title(("SACAM - %s - %s") % (prj, exp)) self.ready_state()