def reset_specimen_controller(self): """ Recreates only the specimen controllers """ if self.model.specimen_selected: specimen_view = self.view.reset_child_view("specimen") self.specimen = SpecimenController(model=self.model.current_specimen, view=specimen_view, parent=self) self.show_markers_for(self.model.current_specimen) else: self.specimen = None self.markers = None self.view.update_specimen_sensitivities( self.model.single_specimen_selected, self.model.multiple_specimens_selected ) self.idle_redraw_plot()
class AppController (BaseController): """ Controller handling the main application interface. In essence this delegates actions to its child controllers for Project, Mixture, Specimen, Phase, Marker and Atoms actions. """ file_filters = Project.Meta.file_filters + [ ("All Files", "*.*"), ] import_filters = Project.Meta.import_filters + [ ("All Files", "*.*"), ] # ------------------------------------------------------------ # Initialization and other internals # ------------------------------------------------------------ def __init__(self, model, view, gtk_exception_hook=None, spurious=False, auto_adapt=False, parent=None): """ Initializes an AppController with the given arguments. """ super(AppController, self).__init__(model=model, view=view, spurious=spurious, auto_adapt=auto_adapt, parent=parent) self.gtk_exception_hook = gtk_exception_hook self.gtk_exception_hook.parent_view = view.get_toplevel() # Plot controller: self.plot_controller = MainPlotController(self) view.setup_plot(self.plot_controller) # Child controllers: self.project = None self.specimen = None self.markers = None self.phases = None self.atom_types = None self.mixtures = None self.idle_redraw_plot() if self.model.project_loaded: self.reset_project_controller() self.push_status_msg("Done.") def register_view(self, view): """ Registers the view with this controller """ if self.model.project_loaded: self.update_sensitivities() view.set_layout_mode(self.model.current_project.layout_mode) else: view.set_layout_mode(settings.DEFAULT_LAYOUT) def set_model(self, model): """ Sets the model in this controller """ super(self, AppController).set_model(model) self.reset_project_controller() def reset_project_controller(self): """ Recreates all child controllers """ self.view.reset_all_views() self.project = ProjectController(model=self.model.current_project, view=self.view.project, parent=self) self.phases = PhasesController(model=self.model.current_project, view=self.view.phases, parent=self) self.atom_types = AtomTypesController(model=self.model.current_project, view=self.view.atom_types, parent=self) self.mixtures = MixturesController(model=self.model.current_project, view=self.view.mixtures, parent=self) self.reset_specimen_controller() self.view.update_project_sensitivities(self.model.project_loaded) self.set_layout_mode(self.model.current_project.layout_mode) self.update_title() def reset_specimen_controller(self): """ Recreates only the specimen controllers """ if self.model.specimen_selected: specimen_view = self.view.reset_child_view("specimen") self.specimen = SpecimenController(model=self.model.current_specimen, view=specimen_view, parent=self) markers_view = self.view.reset_child_view("markers") self.markers = MarkersController(model=self.model.current_specimen, view=markers_view, parent=self) else: self.specimen = None self.markers = None self.view.update_specimen_sensitivities( self.model.single_specimen_selected, self.model.multiple_specimens_selected ) self.idle_redraw_plot() # ------------------------------------------------------------ # Notifications of observable properties # ------------------------------------------------------------ @BaseController.observe("needs_plot_update", signal=True) def notif_needs_plot_update(self, model, prop_name, info): """ This handles needs_plot_update signals emitted by the Application model, in effect it is either a forwarded 'data_changed' or 'visuals_changed' signal coming from the :class:`pyxrd.project.models.Project` model. """ self.idle_redraw_plot() @BaseController.observe("current_project", assign=True, after=True) def notif_project_update(self, model, prop_name, info): self.reset_project_controller() @BaseController.observe("current_specimen", assign=True, after=True) @BaseController.observe("current_specimens", assign=True, after=True) def notif_specimen_changed(self, model, prop_name, info): self.reset_specimen_controller() # ------------------------------------------------------------ # View updating # ------------------------------------------------------------ _idle_redraw_id = None _needs_redraw = False def idle_redraw_plot(self): """Adds a redraw plot function as 'idle' action to the main GTK loop.""" if self._idle_redraw_id is None: self._idle_redraw_id = gobject.idle_add(self.redraw_plot) self._needs_redraw = True @BaseController.status_message("Updating display...") def redraw_plot(self): """Updates the plot""" if self._needs_redraw == True: self._needs_redraw = False self.plot_controller.update( clear=True, project=self.model.current_project, specimens=self.model.current_specimens[::-1] ) if self._needs_redraw: return True else: self._idle_redraw_id = None return False def update_title(self): """Convenience method for setting the application view's title""" self.view.set_title(self.model.current_project.name) def update_sensitivities(self): """Convenience method for updating the application view's sensitivities""" self.view.update_project_sensitivities(self.model.project_loaded) self.view.update_specimen_sensitivities( self.model.single_specimen_selected, self.model.multiple_specimens_selected ) def set_layout_mode(self, mode): """Convenience method for updating the application view's layout mode""" self.view.set_layout_mode(mode) # ------------------------------------------------------------ # Loading and saving of projects # ------------------------------------------------------------ def save_project(self, filename=None): # Set the filename to the current location if None or "" was given: filename = filename or self.model.current_filename # Try to save the project: with self.ui_error_handler("An error has occurred while saving!"): self.model.current_project.save_object(filename) # Set the current filename property and update the title self.model.current_filename = filename self.update_title() def save_project_as(self, title="Save project as"): def on_accept(dialog): self.save_project(filename=self.extract_filename(dialog)) suggest_name, suggest_folder = None, None if self.model.current_filename is not None: # Set the name and directory of the file dialog to the current # project location: suggest_name = basename(self.model.current_filename) suggest_folder = dirname(self.model.current_filename) self.run_save_dialog(title=title, suggest_name=suggest_name, suggest_folder=suggest_folder, on_accept_callback=on_accept, parent=self.view.get_top_widget()) def open_project(self, filename): # Try to load the project: with self.ui_error_handler("An error has occurred.\n Your project was not loaded!"): self.model.current_project = Project.load_object(filename, parent=self.model) # Set the current filename property and update the title self.model.current_filename = filename self.update_title() def load_project(self, title, confirm_msg, action=None, filters=None): """Convenience function for loading projects from different sources following similar user interaction paths""" action = not_none(action, self.open_project) filter = not_none(filters, self.file_filters) def on_open_project(confirm_dialog): def on_accept(dialog): gobject.idle_add(action, self.extract_filename(dialog)) return True self.run_load_dialog( title=title, on_accept_callback=on_accept, filters=filters, parent=self.view.get_top_widget()) if self.model.current_project and self.model.current_project.needs_saving: self.run_confirmation_dialog( confirm_msg, on_open_project, parent=self.view.get_top_widget()) else: on_open_project(None) def new_project(self): # Create a new project self.model.current_project = Project(parent=self.model) # Set the current filename property and update the title self.model.current_filename = None self.update_title() # Show the edit project dialog self.view.project.present() def import_project_from_xml(self, filename): with self.ui_error_handler("An error has occurred.\n Your project was not imported!"): self.model.current_project = Project.create_from_sybilla_xml(filename, parent=self.model) self.model.current_filename = None self.update_title() self.view.project.present() # ------------------------------------------------------------ # GTK Signal handlers - general # ------------------------------------------------------------ def on_manual_activate(self, widget, data=None): try: import webbrowser webbrowser.open(settings.MANUAL_URL) except: pass # ignore errors return True def on_about_activate(self, widget, data=None): self.view["about_window"].show() return True def on_main_window_delete_event(self, widget, event): def on_accept(dialog): gtk.main_quit() return False def on_reject(dialog): return True if self.model.current_project and self.model.current_project.needs_saving: self.run_confirmation_dialog( "The current project has unsaved changes,\n" "are you sure you want to quit?", on_accept, on_reject, parent=self.view.get_top_widget()) return True else: return on_accept(None) def on_menu_item_quit_activate (self, widget, data=None): self.view.get_toplevel().destroy() return True def on_refresh_graph(self, event): if self.model.current_project: with self.model.current_project.data_changed.hold(): self.model.current_project.update_all_mixtures() self.redraw_plot() def on_save_graph(self, event): filename = None if self.model.single_specimen_selected: filename = os.path.splitext(self.model.current_specimen.name)[0] else: filename = self.model.current_project.name self.plot_controller.save( parent=self.view.get_toplevel(), suggest_name=filename, num_specimens=len(self.model.current_specimens), offset=self.model.current_project.display_plot_offset) def on_sample_point(self, event): """ Sample a point on the plot and display the (calculated and) experimental data values in an information dialog. """ self.edc = None def parse_x_pos(x_pos, event): self.edc.enabled = False self.edc.disconnect() exp_y = self.model.current_specimen.experimental_pattern.get_y_at_x(x_pos) calc_y = self.model.current_specimen.calculated_pattern.get_y_at_x(x_pos) message = "Sampled point:\n" message += "\tExperimental data:\t( %.4f , %.4f )\n" if self.model.current_project.layout_mode == "FULL": message += "\tCalculated data:\t\t( %.4f , %.4f )" message = message % (x_pos, exp_y, x_pos, calc_y) self.run_information_dialog(message, parent=self.view.get_toplevel()) del self.edc self.edc = EyeDropper(self.plot_controller, parse_x_pos) # ------------------------------------------------------------ # GTK Signal handlers - Project related # ------------------------------------------------------------ @BaseController.status_message("Creating new project...", "new_project") def on_new_project_activate(self, widget, data=None): def on_accept(dialog): self.new_project() if self.model.current_project and self.model.current_project.needs_saving: self.run_confirmation_dialog( "The current project has unsaved changes,\n" "are you sure you want to create a new project?", on_accept, parent=self.view.get_top_widget()) else: on_accept(None) @BaseController.status_message("Displaying project data...", "edit_project") def on_edit_project_activate(self, widget, data=None): self.view.project.present() @BaseController.status_message("Open project...", "open_project") def on_open_project_activate(self, widget, data=None): """Open an existing project. Asks the user if (s)he's sure when an unsaved project is loaded.""" self.load_project( title="Open project", confirm_msg="The current project has unsaved changes,\n" "are you sure you want to load another project?", action=self.open_project, ) @BaseController.status_message("Import Sybilla XML...", "import_project_xml") def on_import_project_sybilla_activate(self, widget, data=None, title="Import Sybilla XML"): """Import an existing Sybilla project from an XML file. Asks the user if (s)he's sure when an unsaved project is loaded.""" self.load_project( title="Import project", confirm_msg="The current project has unsaved changes,\n" "are you sure you want to create a new project?", action=self.import_project_from_xml, filters=self.import_filters ) @BaseController.status_message("Save project...", "save_project") def on_save_project_activate(self, widget, *args): if not self.model.current_filename: self.save_project_as(title="Save project") else: self.save_project() @BaseController.status_message("Save project...", "save_project") def on_save_project_as_activate(self, widget, *args): self.save_project_as() # ------------------------------------------------------------ # GTK Signal handlers - Mixtures related # ----------------------------------------------------------- def on_edit_mixtures(self, widget, data=None): if self.model.project_loaded: self.view.mixtures.present() pass # ------------------------------------------------------------ # GTK Signal handlers - Specimen related # ------------------------------------------------------------ def on_edit_specimen_activate(self, event): self.project.edit_specimen() return True def on_add_specimen_activate(self, event): self.project.add_specimen() return True def on_add_multiple_specimens(self, event): self.project.import_multiple_specimen() return True def on_del_specimen_activate(self, event): self.project.delete_selected_specimens() return True def on_replace_specimen_data_activate(self, event): if self.model.single_specimen_selected: self.specimen.on_replace_experimental_data() return True def on_export_specimen_data_activate(self, event): if self.model.single_specimen_selected: self.specimen.on_export_experimental_data() return True def on_convert_to_fixed_activate(self, event): for specimen in self.model.current_specimens: specimen.convert_to_fixed() def on_convert_to_ads_activate(self, event): for specimen in self.model.current_specimens: specimen.convert_to_ads() def on_remove_background(self, event): if self.model.single_specimen_selected: self.specimen.remove_background() else: self.project.remove_backgrounds(self.model.current_specimens) return True def on_smooth_data(self, event): if self.model.single_specimen_selected: self.specimen.smooth_data() return True def on_add_noise(self, event): if self.model.single_specimen_selected: self.specimen.add_noise() return True def on_shift_data(self, event): if self.model.single_specimen_selected: self.specimen.shift_data() return True def on_strip_peak(self, event): if self.model.single_specimen_selected: self.specimen.strip_peak() return True def on_peak_area(self, event): if self.model.single_specimen_selected: self.specimen.peak_area() return True # ------------------------------------------------------------ # GTK Signal handlers - Phases related # ------------------------------------------------------------ def on_edit_phases_activate(self, event): if self.model.project_loaded: self.view.phases.present() return True # ------------------------------------------------------------ # GTK Signal handlers - Atom Types related # ------------------------------------------------------------ def on_edit_atom_types_activate(self, event): if self.model.project_loaded: self.view.atom_types.present() return True # ------------------------------------------------------------ # GTK Signal handlers - Markers related # ------------------------------------------------------------ def on_edit_markers_activate(self, event): if self.model.current_specimen is not None: self.view.markers.present() return True pass # end of class
class AppController (BaseController): """ Controller handling the main application interface. In essence this delegates actions to its child controllers for Project, Mixture, Specimen, Phase, Marker and Atoms actions. """ # ------------------------------------------------------------ # Dialog properties # ------------------------------------------------------------ _save_project_dialog = None @property def save_project_dialog(self): """ Creates & returns the 'save project' dialog """ if self._save_project_dialog is None: # Check to see if we have a project loaded, if so, # set the paths to match current_name, current_folder = None, None if self.model.current_filename is not None: current_name = basename(self.model.current_filename) current_folder = dirname(self.model.current_filename) # Create the dialog once, and re-use its context self._save_project_dialog = DialogFactory.get_save_dialog( title="Save project", current_name=current_name, current_folder=current_folder, filters=project_parsers.get_export_file_filters(), persist=True, parent=self.view.get_top_widget() ) return self._save_project_dialog _load_project_dialog = None @property def load_project_dialog(self): """ Creates & returns the 'load project' dialog """ if self._load_project_dialog is None: # Check to see if we have a project loaded, if so, # set the paths to match current_folder = None if self.model.current_filename is not None: current_folder = dirname(self.model.current_filename) # Create the dialog once, and re-use self._load_project_dialog = DialogFactory.get_load_dialog( title="Load project", current_folder=current_folder, filters=project_parsers.get_import_file_filters(), persist=True, multiple=False, parent=self.view.get_top_widget() ) return self._load_project_dialog # ------------------------------------------------------------ # Initialization and other internals # ------------------------------------------------------------ def __init__(self, model, view, gtk_exception_hook=None, spurious=False, auto_adapt=False, parent=None): """ Initializes an AppController with the given arguments. """ super(AppController, self).__init__(model=model, view=view, spurious=spurious, auto_adapt=auto_adapt, parent=parent) self.gtk_exception_hook = gtk_exception_hook self.gtk_exception_hook.parent_view = view.get_toplevel() # Plot controller: self.plot_controller = MainPlotController( self.update_plot_status, self.show_marker ) # Child controllers: self.project = None self.specimen = None self.markers = None self.phases = None self.atom_types = None self.mixtures = None self.idle_redraw_plot() if self.model.project_loaded: self.reset_project_controller() self.push_status_msg("Done.") def register_view(self, view): """ Registers the view with this controller """ view.setup_plot(self.plot_controller) if self.model.project_loaded: self.update_sensitivities() view.set_layout_mode(self.model.current_project.layout_mode) else: view.set_layout_mode(settings.DEFAULT_LAYOUT) def set_model(self, model): """ Sets the model in this controller """ super(self, AppController).set_model(model) self.reset_project_controller() def reset_project_controller(self): """ Recreates all child controllers """ self.view.reset_all_views() self.project = ProjectController(model=self.model.current_project, view=self.view.project, parent=self) self.phases = PhasesController(model=self.model.current_project, view=self.view.phases, parent=self) #self.behaviours = InSituBehavioursController(model=self.model.current_project, view=self.view.behaviours, parent=self) self.atom_types = AtomTypesController(model=self.model.current_project, view=self.view.atom_types, parent=self) self.mixtures = MixturesController(model=self.model.current_project, view=self.view.mixtures, parent=self) self.reset_specimen_controller() self.view.update_project_sensitivities(self.model.project_loaded) self.set_layout_mode(self.model.current_project.layout_mode) self.update_title() def reset_specimen_controller(self): """ Recreates only the specimen controllers """ if self.model.specimen_selected: specimen_view = self.view.reset_child_view("specimen") self.specimen = SpecimenController(model=self.model.current_specimen, view=specimen_view, parent=self) self.show_markers_for(self.model.current_specimen) else: self.specimen = None self.markers = None self.view.update_specimen_sensitivities( self.model.single_specimen_selected, self.model.multiple_specimens_selected ) self.idle_redraw_plot() def show_markers_for(self, specimen): markers_view = self.view.reset_child_view("markers") self.markers = MarkersController(model=specimen, view=markers_view, parent=self) def show_marker(self, marker): markers_view = self.view.reset_child_view("markers") self.markers = MarkersController(model=marker.specimen, view=markers_view, parent=self) self.view.markers.present() add_idle_call(self.markers.select_object, marker) # ------------------------------------------------------------ # Notifications of observable properties # ------------------------------------------------------------ @BaseController.observe("needs_plot_update", signal=True) def notif_needs_plot_update(self, model, prop_name, info): """ This handles needs_plot_update signals emitted by the Application model, in effect it is either a forwarded 'data_changed' or 'visuals_changed' signal coming from the :class:`pyxrd.project.models.Project` model. """ self.idle_redraw_plot() @BaseController.observe("current_project", assign=True, after=True) def notif_project_update(self, model, prop_name, info): self.reset_project_controller() @BaseController.observe("current_specimen", assign=True, after=True) @BaseController.observe("current_specimens", assign=True, after=True) def notif_specimen_changed(self, model, prop_name, info): self.reset_specimen_controller() # ------------------------------------------------------------ # View updating # ------------------------------------------------------------ _idle_redraw_id = None _needs_redraw = False def idle_redraw_plot(self): """Adds a redraw plot function as 'idle' action to the main GTK loop.""" if self._idle_redraw_id is None: self._idle_redraw_id = add_idle_call(self.redraw_plot) self._needs_redraw = True @BaseController.status_message("Updating display...") def redraw_plot(self): """Updates the plot""" if self._needs_redraw == True: self._needs_redraw = False self.plot_controller.update( clear=True, project=self.model.current_project, specimens=self.model.current_specimens[::-1] ) if self._needs_redraw: return True else: self._idle_redraw_id = None return False def update_title(self): """Convenience method for setting the application view's title""" self.view.set_title(self.model.current_project.name) def update_sensitivities(self): """Convenience method for updating the application view's sensitivities""" self.view.update_project_sensitivities(self.model.project_loaded) self.view.update_specimen_sensitivities( self.model.single_specimen_selected, self.model.multiple_specimens_selected ) def update_plot_status(self, x_pos, event): if x_pos > 0 and self.model.current_specimen is not None: # Get experimental data at the sampled point exp_y = self.model.current_specimen.experimental_pattern.get_y_at_x(x_pos) dspacing = self.model.current_specimen.goniometer.get_nm_from_2t(x_pos) # Get calculated data if applicable if self.model.current_project.layout_mode == "FULL": calc_y = self.model.current_specimen.calculated_pattern.get_y_at_x(x_pos) self.view.update_plot_status(x_pos, dspacing, exp_y, calc_y) else: self.view.update_plot_status(x_pos, dspacing, exp_y, None) else: self.view.update_plot_status(None, None, None, None) def set_layout_mode(self, mode): """Convenience method for updating the application view's layout mode""" self.view.set_layout_mode(mode) # ------------------------------------------------------------ # Loading and saving of projects # ------------------------------------------------------------ def _save_project(self, filename=None): # Set the filename to the current location if None or "" was given: filename = filename or self.model.current_filename # Try to save the project: with DialogFactory.error_dialog_handler( "An error has occurred while saving!\n<i>{0}</i>", parent=self.view.get_toplevel(), reraise=False): JSONProjectParser.write(self.model.current_project, filename, zipped=True) self.model.current_project.filename = filename self.model.update_project_last_save_hash() # Update the title self.update_title() def confirm_discard_unsaved_changes(self, confirm_msg="The current project has unsaved changes,\n" "are you sure you want to continue?", on_reject=None): """ Function decorator which will check if a project is opened with unsaved changes and ask the user to confirm the action without first saving the changes. """ def accept_decorator(on_accept): @wraps(on_accept) def accept_wrapper(self, *args, **kwargs): if self.model.check_for_changes(): return DialogFactory.get_confirmation_dialog( confirm_msg, parent=self.view.get_top_widget() ).run(lambda d: on_accept(self, *args, **kwargs), on_reject) else: return on_accept(self, *args, **kwargs) return accept_wrapper return accept_decorator @confirm_discard_unsaved_changes( "The current project has unsaved changes,\n" "are you sure you want to quit?") def quit(self, *args, **kwargs): stop_event_loop() return False @confirm_discard_unsaved_changes( "The current project has unsaved changes,\n" "are you sure you want to load another project?") def load_project(self): """Convenience function for loading projects from different sources following similar user interaction paths""" def on_accept(dialog): # Try to load the project: with DialogFactory.error_dialog_handler( "An error has occurred:\n<i>{0}</i>\n Your project was not loaded!", parent=self.view.get_toplevel(), title="Parsing error", reraise=False): self.model.current_project = dialog.parser.parse(dialog.filename) self.model.current_project.parent = self.model self.model.update_project_last_save_hash() # Update the title self.update_title() # Run the open/import project dialog: self.load_project_dialog.run(on_accept) @confirm_discard_unsaved_changes( "The current project has unsaved changes,\n" "are you sure you want to create a new project?") def new_project(self, *args, **kwargs): # Create a new project self.model.current_project = Project(parent=self.model) # Set the current filename property and update the title self.update_title() # Show the edit project dialog self.view.project.present() # ------------------------------------------------------------ # GTK Signal handlers - general # ------------------------------------------------------------ def on_manual_activate(self, widget, data=None): try: import webbrowser webbrowser.open(settings.MANUAL_URL) except: pass # ignore errors return True def on_about_activate(self, widget, data=None): self.view["about_window"].show() return True def on_main_window_destroy_event(self, widget, event): self.quit() return True def on_main_window_delete_event(self, widget, event): self.quit() return True def on_menu_item_quit_activate (self, widget, data=None): self.quit() return True def on_refresh_graph(self, event): if self.model.current_project: with self.model.current_project.data_changed.hold(): self.model.current_project.update_all_mixtures() self.redraw_plot() def on_save_graph(self, event): filename = None if self.model.single_specimen_selected: filename = os.path.splitext(self.model.current_specimen.name)[0] else: filename = self.model.current_project.name self.plot_controller.save( parent=self.view.get_toplevel(), current_name=filename, num_specimens=len(self.model.current_specimens), offset=self.model.current_project.display_plot_offset) def on_toggled_plot_toolbar(self, action): if action.get_active(): self.view.show_plot_toolbar() else: self.view.hide_plot_toolbar() @BaseController.status_message("Sampling...", "sampling") def on_sample_point(self, event): """ Sample a point on the plot and display the (calculated and) experimental data values in an information dialog. """ self.edc = None def parse_x_pos(x_pos, event): # Clear the eye dropper controller self.edc.enabled = False self.edc.disconnect() del self.edc # Get experimental data at the sampled point exp_y = self.model.current_specimen.experimental_pattern.get_y_at_x(x_pos) message = "Sampled point:\n" message += "\tExperimental data:\t( %.4f , %.4f )\n" % (x_pos, exp_y) # Get calculated data if applicable if self.model.current_project.layout_mode == "FULL": calc_y = self.model.current_specimen.calculated_pattern.get_y_at_x(x_pos) message += "\tCalculated data:\t\t( %.4f , %.4f )" % (x_pos, calc_y) # Display message dialog DialogFactory.get_information_dialog( message, parent=self.view.get_toplevel() ).run() self.edc = EyeDropper(self.plot_controller, parse_x_pos) # ------------------------------------------------------------ # GTK Signal handlers - Project related # ------------------------------------------------------------ @BaseController.status_message("Creating new project...", "new_project") def on_new_project_activate(self, widget, data=None): self.new_project() @BaseController.status_message("Displaying project data...", "edit_project") def on_edit_project_activate(self, widget, data=None): self.view.project.present() @BaseController.status_message("Open project...", "open_project") def on_open_project_activate(self, widget, data=None): """Open an existing project. Asks the user if (s)he's sure when an unsaved project is loaded.""" self.load_project() @BaseController.status_message("Save project...", "save_project") def on_save_project_activate(self, widget, *args): # No filename yet: show a dialog if not self.model.current_filename: self.save_project_dialog.update(title="Save project").run( lambda dialog: self._save_project(filename=dialog.filename) ) else: # we already have a filename, overwrite: self._save_project() @BaseController.status_message("Save project as...", "save_project_as") def on_save_project_as_activate(self, widget, *args): self.save_project_dialog.update(title="Save project as").run( lambda dialog: self._save_project(filename=dialog.filename) ) # ------------------------------------------------------------ # GTK Signal handlers - Mixtures related # ----------------------------------------------------------- def on_edit_mixtures(self, widget, data=None): if self.model.project_loaded: self.view.mixtures.present() pass # ------------------------------------------------------------ # GTK Signal handlers - Behaviour related # ------------------------------------------------------------ def on_edit_behaviours(self, widget, data=None): #if self.model.project_loaded: # self.view.behaviours.present() return True # ------------------------------------------------------------ # GTK Signal handlers - Specimen related # ------------------------------------------------------------ def on_edit_specimen_activate(self, event): self.project.edit_specimen() return True def on_add_specimen_activate(self, event): self.project.add_specimen() return True def on_add_multiple_specimens(self, event): self.project.import_multiple_specimen() return True def on_del_specimen_activate(self, event): self.project.delete_selected_specimens() return True def on_replace_specimen_data_activate(self, event): if self.model.single_specimen_selected: self.specimen.on_replace_experimental_data() return True def on_export_specimen_data_activate(self, event): if self.model.single_specimen_selected: self.specimen.on_export_experimental_data() return True def on_convert_to_fixed_activate(self, event): for specimen in self.model.current_specimens: specimen.convert_to_fixed() def on_convert_to_ads_activate(self, event): for specimen in self.model.current_specimens: specimen.convert_to_ads() def on_remove_background(self, event): if self.model.single_specimen_selected: self.specimen.remove_background() else: self.project.remove_backgrounds(self.model.current_specimens) return True def on_smooth_data(self, event): if self.model.single_specimen_selected: self.specimen.smooth_data() return True def on_add_noise(self, event): if self.model.single_specimen_selected: self.specimen.add_noise() return True def on_shift_data(self, event): if self.model.single_specimen_selected: self.specimen.shift_data() return True def on_strip_peak(self, event): if self.model.single_specimen_selected: self.specimen.strip_peak() return True def on_peak_properties(self, event): if self.model.single_specimen_selected: self.specimen.peak_properties() return True # ------------------------------------------------------------ # GTK Signal handlers - Phases related # ------------------------------------------------------------ def on_edit_phases_activate(self, event): if self.model.project_loaded: self.view.phases.present() return True # ------------------------------------------------------------ # GTK Signal handlers - Atom Types related # ------------------------------------------------------------ def on_edit_atom_types_activate(self, event): if self.model.project_loaded: self.view.atom_types.present() return True # ------------------------------------------------------------ # GTK Signal handlers - Markers related # ------------------------------------------------------------ def on_edit_markers_activate(self, event): if self.model.current_specimen is not None: self.view.markers.present() return True def edit_marker(self, marker): self.show_markers_for(marker.specimen) pass # end of class