def __init__(self, project=None):
	" 'project' may be a Project object or a filename. "

        
        self.eConfig = config.read_configfile(self, const.CONFIG_FILE)
        Signals.connect(self, "write-config",
                        (lambda sender: self.write_recentfiles()))
        
        self.plugins = dict()

        self.recent_files = list()
        self.read_recentfiles()

        # init() is a good place for initialization of derived class
        self.init()
        
        # Set up the Project...
        self._project = None
	if isinstance(project, basestring):
	    try:
		self.load_project(project)
	    except IOError:
                logger.error("Failed to load project '%s'\nSetting up an empty project instead." % project)                
		self.set_project(Project())
        else:
            self.set_project(project)

        self.init_plugins()
Exemplo n.º 2
0
    def _construct_toolwindow(self):

        window = tools.ToolWindow(self.app, None)
        window.set_transient_for(self)
        window.set_destroy_with_parent(True)
        window.hide()

        def cb_toggle_window(action, window):
            if action.get_active() is True: window.show()
            else: window.hide()        
        t = gtk.ToggleAction('ToggleToolWindow', 'Show tools window', None, None)
        t.connect("toggled", cb_toggle_window, window)
        uihelper.get_action_group(self.uimanager, 'Application').add_action(t)

        def cb_window_hideshow(window):
            action = self.uimanager.get_action('/MainMenu/ViewMenu/ToggleToolWindow')
            action.set_active(window.get_property('visible'))
        window.connect('hide', cb_window_hideshow)
        window.connect('show', cb_window_hideshow)

        def on_notify_project(sender, project, toolwin):
            print "==> project = ", project
            print "==> toolwin = ", toolwin
            toolwin.set_project(project)
        Signals.connect(self.app, 'notify::project', on_notify_project, window)
        
        return window
Exemplo n.º 3
0
    def set_dataset(self, dataset):
        
        if dataset is None:
            self.set_title("(no dataset)")
        else:
            self.set_title("DS: %s" % dataset.key)

        # FIXME
        # this is inconsistent: we expect 'table' to be fixed,
        # even though we argued before that the dataset.data field
        # is not necessarily fixed, only the Dataset.
        table = dataset.get_data()
        if not isinstance(table, Table):
            raise TypeError("TableWindow can only use Datasets with a Table as data.")
        self.tableview.set_table(table)

        for signal in self._signals:
            Signals.disconnect(signal)

        self._signals += [
            Signals.connect(table, 'update-columns',
                            (lambda sender: self.tableview.setup_columns())),
            Signals.connect(dataset,'notify',
                            (lambda sender: self.tableview.queue_draw()))
            ]

        # TODO: set metadata widget       
            
        self._dataset = dataset
Exemplo n.º 4
0
    def _cb_select_line(self, action):
            
        def finish_select_line(sender):
            print "FINISHED SELECT LINE", sender.line

        s = mpl_selector.SelectLine(self.backend.figure,mode=mpl_selector.SELECTLINE_VERTICAL)
        Signals.connect(s, "finished", finish_select_line)
        
        self.select(s)
Exemplo n.º 5
0
    def add_plotwidget(self, widget):
        n = self.plotbook.append_page(widget)
        self.plotbook.set_tab_label_text(widget, "Plot")
        # TODO: this signal should be a gobject signal
        Signals.connect(widget, "closed", self.detach_plotwidget)

        for ag in widget.get_actiongroups():
            self.uimanager.insert_action_group(ag, 0)
        self.add_accel_group(self.uimanager.get_accel_group())
        self.uimanager.add_ui_from_string(widget.get_uistring())
    def __init__(self, app, project, plot):
        gtk.Window.__init__(self)
        self.set_size_request(width=360,height=400)
        
        self.app = app
        self.project = project
        self.plot = None # will be set after everything else is set up
        self.backend = None
        self._signals = list()
        
        # some icons are not right at all....
        groups = {
            'Common':
            [('Replot', gtk.STOCK_REFRESH, 'Replot',
              '<control>R', 'Replot everything', '_cb_replot'),
             ('Edit', gtk.STOCK_PROPERTIES, 'Edit Plot',
              None, 'Edit Plot', '_cb_edit_plot'),
             ('ZoomSelection', gtk.STOCK_ZOOM_FIT, 'use current range',
              None, 'Use Current Range', '_cb_zoom_selection'),
             ('ZoomAutoscale', gtk.STOCK_ZOOM_100, 'do not limit range',
              None, 'Do not limit Range', '_cb_zoom_autoscale'),
             ('ExportPostscript', gtk.STOCK_SAVE, 'export as postscript',
              None, 'Export as Postscript file', '_cb_export_postscript')
             ]
            }
        
        ui = \
        """
        <ui>
          <toolbar name='Toolbar'>
            <toolitem action='Replot'/>            
            <separator/>
            <toolitem action='Edit'/>
            <toolitem action='ZoomSelection'/>
            <toolitem action='ZoomAutoscale'/>
            <separator/>
            <toolitem action='ExportPostscript'/>
          </toolbar>
        </ui>
        """
        
        self.uimanager = self._construct_uimanager(groups,ui)
        self.toolbar = self._construct_toolbar()

        # vbox 
        self.vbox = gtk.VBox(False)
        self.vbox.pack_start(self.toolbar, expand=False, fill=True)
        self.vbox.pack_start(self._construct_history(), expand=True, fill=True)
        self.vbox.show()
        self.add(self.vbox)

        self.connect("destroy", (lambda sender: self.destroy()))

        Signals.connect(self.project, "close", (lambda sender: self.destroy()))        
        self.set_plot(plot)
Exemplo n.º 7
0
    def _cb_zoom_axes(self, action):

        def finish_moving(sender):
            ul = UndoList().describe("Zoom")
            layer = self.backend.axes_to_layer[sender.axes]
            self.zoom_to_region(layer, sender.region, undolist=ul)
            self.project.journal.add_undo(ul)           
           
        s = mpl_selector.ZoomAxes(self.backend.figure)
        Signals.connect(s, "finished", finish_moving)

        self.select(s)
Exemplo n.º 8
0
    def on_action_SelectLine(self, action):
            
        def finish_select_line(sender):
            print "FINISHED SELECT LINE", sender.line

        layer = self.backend.layer
        axes = self.backend.layer_to_axes[layer]
        s = mpl_selector.SelectLine(self.backend.figure, axes,
                                    mode=mpl_selector.SELECTLINE_VERTICAL)
        Signals.connect(s, "finished", finish_select_line)
        
        self.select(s)
    def set_plot(self, plot):

        Signals.disconnect_list(self._signals)
        self.backend is not None and self.backend.disconnect()

        if plot is None:
            return

        
        self.plot = plot
        self.set_title( "Plot: %s" % plot.key )
        
        self.backend = project.new_backend('gnuplot/x11', plot=plot)

        # connect signals for treeview
        # these are disconnect by the backend if it closes
        Signals.connect(self.backend, 'gnuplot-send-cmd', self.on_send_cmd)
        Signals.connect(self.backend, 'gnuplot-finish-cmd', self.on_finish_cmd)
        Signals.connect(self.backend, 'gnuplot-start-plotting', self.on_start_plotting)

        # connect signal for plot
        # these should be disconnected before the plot needs to do it.
        self._signals += [
            Signals.connect(plot, "plot-changed", (lambda sender: self.backend.draw())),
            Signals.connect(plot, "closed", (lambda sender: self.destroy()))
            ]

        self.backend.draw()
Exemplo n.º 10
0
    def on_action_MoveAxes(self, action):

        def finish_moving(sender):
            ul = UndoList().describe("Move Graph")
            layer = self.backend.axes_to_layer[sender.axes]
            self.zoom_to_region(layer, sender.region, undolist=ul)
            self.project.journal.add_undo(ul)           

        layer = self.backend.layer
        axes = self.backend.layer_to_axes[layer]
        s = mpl_selector.MoveAxes(self.backend.figure, axes)
        Signals.connect(s, "finished", finish_moving)

        self.select(s)
Exemplo n.º 11
0
    def set_plot(self, plot):
        if plot == self.plot:
            return        
        self.plot = plot

        if plot is not None:
            self.layer = plot.current_layer
            Signals.connect(plot, "notify::current_layer", self.on_notify_layer)
        else:
            self.layer = None

        self.set_sensitive(plot is not None)

        # TODO: connect properly on change of plot
        self.update_plot()
Exemplo n.º 12
0
    def set_backend(self, backend):
        """ Set the backend to the new value (implies setting a new layer). """
        if self.backend != backend:
            Signals.disconnect_list(self.backend_signals)

            self.backend = backend

            if self.backend is not None:
                # If no active layer is set, even though there are layers,
                # then we should set the first layer as being active.
                if self.backend.layer is None and len(self.backend.plot.layers) > 0:
                    self.backend.layer = self.backend.plot.layers[0]
                self.layer = self.backend.layer

                # make sure we keep track of changes to the active layer
                self.backend_signals.append(
                    Signals.connect(backend, "notify::layer",
                                    (lambda sender, layer: self.set_layer(layer)))
                    )
            else:
                self.layer = None

            # propagate the new backend to all tools
            self.dock.foreach((lambda tool: tool.set_backend(self.backend)))
            
            # Adjust the active index of the combobox so that the new
            # backend is displayed.
            if self.backend is None:
                index = -1
            else:
                model = self.combobox.get_model()
                index = self.project.backends.index(backend)
            self.combobox.set_active(index)
Exemplo n.º 13
0
    def set_project(self, project):
        if project == self.project:
            return

        if project is not None:
            # update combobox again if plots change
            Signals.connect(project.plots, 'notify',
                            (lambda sender: self.update_combobox()))
            Signals.connect(project.app, 'notify::current_plot',
                            (lambda sender, plot: self.set_plot(plot)))

        self.dock.foreach((lambda tool: tool.set_data('project', project)))
        
        self.project = project
        self.update_combobox()
        self.update_plot()
Exemplo n.º 14
0
    def set_project(self, project, confirm=True):

        # if project changes, then close the Project properly!
        if self._project is not None and id(project) != id(self._project):
            self._project.close()
            
        self._project = project
        if project is not None:
            project.app = self
            def detach_project(project):
                if id(self._project) == id(project):
                    self._project.app = None
                    self._project = None
                    
            # TODO: connect_once would be nice.
            Signals.connect(project, 'close', detach_project)
Exemplo n.º 15
0
    def set_plot(self, plot):
        # TODO: remove old plot
        # TODO: connect to plot's title    

        if plot is not None:
            backend = self.project.request_backend('matplotlib', plot=plot)

            #backend.canvas.set_size_request(800, 600)
            sw = uihelper.add_scrollbars(backend.canvas, viewport=True)
            sw.show()
            self.vbox.pack_start(sw)
        else:
            backend = None
           
        # disconnect old stuff
        if self.backend is not None and self.backend != backend:
            self.backend.disconnect()

        for signal in self._signals:
            Signals.disconnect(signal)
        self._signals = []
        
        if self.cursor is not None:
            self.cursor.finish()

        # connect new backend
        self.plot = plot
        self.backend = backend


        if backend is not None:
            self._signals.extend(
                [Signals.connect(plot, "plot-changed", (lambda sender: backend.draw())),
                 Signals.connect(plot, "closed", (lambda sender: Signals.emit(self, 'closed')))]
                )
            try:
                backend.draw()
            except:
                #gtkutils.info_msg("Nothing to plot.")
                raise            

            # Cursor
            self.cursor = mpl_selector.Cursor(self.backend.figure)
            Signals.connect(self.cursor, "move",
                            (lambda sender,x,y: self.set_coords(x,y)))
            self.cursor.init()
Exemplo n.º 16
0
    def set_project(self,project):
        """
        Assign a project to the TreeView and repopulate the tree.  If
        no project is given, the TreeView will be empty.
        """
        if project:
            self.set_property('sensitive',True)
        else:
            self.set_property('sensitive',False)
            
        self._project = project
        self.populate_treeview()

        # TODO: remove old signals
        if self.project is not None:
            Signals.connect(self.project.datasets, "changed", self.populate_treeview)
            Signals.connect(self.project.plots, "changed", self.populate_treeview)
Exemplo n.º 17
0
    def _cb_zoom_rect(self, action):

        def finish_zooming(sender):
            self.statusbar.pop(
                self.statusbar.get_context_id('action-zoom'))

            ul = UndoList().describe("Zoom Region")
            layer = self.backend.axes_to_layer[sender.axes]
            self.zoom_to_region(layer, sender.region, undolist=ul)
            self.project.journal.add_undo(ul)           
        
        s = mpl_selector.SelectRegion(self.backend.figure)
        Signals.connect(s, 'finished', finish_zooming)
        self.statusbar.push(
            self.statusbar.get_context_id('action-zoom'),
            "Use the left mouse button to zoom.")

        self.select(s)
Exemplo n.º 18
0
    def __init__(self, app, project, dataset=None):
        gtk.Window.__init__(self)
	self.set_size_request(280,320)
        self.set_transient_for(app.window)
        self.app = app
        
        self._signals = []

        self.uimanager = self._construct_uimanager()
        self.menubar = self._construct_menubar()
        self.toolbar = self._construct_toolbar()
        self.popup = self.uimanager.get_widget('/popup_column')
        self.popup_info = None # needed for popup
        self.statusbar = self._construct_statusbar()

        self.tableview = self._construct_tableview()
        sw = uihelper.add_scrollbars(self.tableview)
        sw.show()
        
        
        hpaned = gtk.HPaned()
        hpaned.pack1( sw )
#        hpaned.pack2( self._construct_metadata_widget() )
        hpaned.show()
        self.hpaned = hpaned
        
        vbox = gtk.VBox()

        vbox.pack_start( self.menubar, expand=False, fill=True )
        vbox.pack_start( self.toolbar, expand=False, fill=True )
        vbox.pack_start( self.hpaned, expand=True, fill=True )
        vbox.pack_start( self.statusbar, expand=False, fill=True )

        vbox.show()
        self.add(vbox)

        self.project = project  # immutable
        self._dataset = None
        self.dataset = dataset

        Signals.connect(self.project, "close", (lambda sender: self.destroy()))
        Signals.connect(self.dataset, "closed", (lambda sender: self.destroy()))

        self.tableview.emit('cursor_changed')                
Exemplo n.º 19
0
    def set_project(self, project, confirm=True):

        has_changed = (id(self._project) != id(project))        
        if self._project is not None and has_changed:
            self._project.close()

        self._project = project
        if project is not None:
            project.app = self
            def detach_project(project):
                if id(self._project) == id(project):
                    self._project.app = None
                    self._project = None
                    
            # TODO: connect_once would be nice.
            Signals.connect(project, 'close', detach_project)

        if has_changed is True:
            Signals.emit(self, 'notify::project', self._project)
Exemplo n.º 20
0
    def set_project(self, project):
        if project == self.project:
            return

        Signals.disconnect_list(self.project_signals)            
        if project is not None:
            # update combobox again if plots change
            self.project_signals.extend(
                [Signals.connect(project, 'notify::plots',
                                 (lambda sender: self.update_combobox())),
                 Signals.connect(project.app, 'notify::current_plot',
                                 (lambda sender, plot: self.set_plot(plot)))
                 ])

        self.dock.foreach((lambda tool: tool.set_data('project', project)))
        
        self.project = project
        self.update_combobox()
        self.update_plot()
Exemplo n.º 21
0
    def set(self, project,plot):
        logging.debug("Assigning project %s to Backend" % repr(project))

        # if necessary, detach messages from old project
        for signal in self.Signals:
            Signals.disconnect(signal)
        self.Signals.clear()
            
        # assign project and plot
        self.plot = plot
        self.project = project
        if self.project is not None:
            logging.debug("Connecting Signals.")
            self.Signals['close'] = Signals.connect(
                self.project, 'close', self.cb_project_closed)
            self.Signals['plot-changed'] = Signals.connect(
                self.plot, 'plot-changed', self.cb_plot_changed)
            self.Signals['plot-closed'] = Signals.connect(
                self.plot, 'closed', (lambda sender: self.disconnect()))
Exemplo n.º 22
0
    def select(self, selector):

        self.emit("edit-mode-started")

        self._current_selector = None
        
        def on_finish(sender):
            # Be careful not to call self.abort_selection() in this place.
            self._current_selector = None
            self.btn_cancel.set_sensitive(False)
            self.emit("edit-mode-ended")

        self.btn_cancel.set_sensitive(True)
        self.btn_cancel.connect("clicked", (lambda sender: self.abort_selection()))
        
        Signals.connect(selector, "finished", on_finish)
        Signals.connect(selector, "aborted", on_finish)
        self._current_selector = selector
        selector.init()
Exemplo n.º 23
0
    def __init__(self, app, project, plot):
        gtk.VBox.__init__(self)

        self._current_selector = None
        
        self.app = app

        self._construct_actiongroups()        
        self.statusbar = self._construct_statusbar()
        self.coords = self._construct_coords()

        self.btn_cancel = self._construct_cancel_button()

        self.context_id = self.statusbar.get_context_id("coordinates")
        #self.statusbar.push(self.context_id, "X: 10, Y: 20")
        #self.statusbar.pop(self.context_id)
        
        vbox = self.vbox = gtk.VBox()
        hbox = gtk.HBox()
        hbox.pack_start(self.btn_cancel, False, padding=4)
        hbox.pack_start(self.coords, False, padding=4)
        hbox.pack_start(self.statusbar, padding=4)
        hbox.show()
        vbox.pack_end(hbox, False, True)
        vbox.show()

        self.add(vbox)

        # set up project/plot
        self.project = project        
        self.plot = None
        self.backend = None
        self.cursor = None
        self._signals = []

        self.set_plot(plot)
        Signals.connect(self.project, "close", (lambda sender: self.destroy()))

        # set up file selector for export dialog
        # TODO: this could be put into a plugin, since it is desirable to have
        # TODO: such a method in the shell frontend as well.
        self.fileselect = FileChooserDialog(title='Save the figure', parent=None)
Exemplo n.º 24
0
 def set_layer(self, layer):
     if layer == self.layer:
         return
     
     Signals.disconnect_list(self.layer_signals)
     self.layer = layer
     
     if layer is not None:
         self.layer_signals.append(
             Signals.connect(self.layer, "notify::labels", self.on_notify_labels)
             )
     self.update_layer()
Exemplo n.º 25
0
    def on_action_DataCursor(self, action):

        layer = self.backend.layer
        axes = self.backend.layer_to_axes[layer]
        s = mpl_selector.DataCursor(self.backend.figure, axes)

        def abort_selector(sender, context_id):
            self.statusbar.pop(context_id)
            
        def finish_selector(sender, context_id):
            self.statusbar.pop(context_id)
            xvalue, yvalue = sender.point

        def update_position(sender, line, index, point, context_id):
            # Note that 'line' is a Line2d instance from matplotlib!
            x, y = point
            self.statusbar.pop(context_id)
            self.statusbar.push(context_id, "X: %f, Y: %f (value #%s)" %
                                (x, y, index))

        context_id = self.statusbar.get_context_id("data_cursor")
        Signals.connect(s, "update-position", update_position, context_id)
        Signals.connect(s, "finished", finish_selector, context_id)
        Signals.connect(s, "aborted", abort_selector, context_id)
        
        self.select(s)
Exemplo n.º 26
0
    def __init__(self, app, project, plot):
        gtk.VBox.__init__(self)

        self._current_selector = None
        
        self.app = app

        self._construct_actiongroups()        
        self.statusbar = self._construct_statusbar()
        self.coords = self._construct_coords()

        self.btn_cancel = self._construct_cancel_button()

        self.context_id = self.statusbar.get_context_id("coordinates")
        self.statusbar.push(self.context_id, "X: 10, Y: 20")
        self.statusbar.pop(self.context_id)
        
        vbox = self.vbox = gtk.VBox()
        hbox = gtk.HBox()
        hbox.pack_start(self.btn_cancel, False, padding=4)
        hbox.pack_start(self.coords, False, padding=4)
        hbox.pack_start(self.statusbar, padding=4)
        hbox.show()
        vbox.pack_end(hbox, False, True)
        vbox.show()

        self.add(vbox)

        # set up project/plot
        self.project = project        
        self.plot = None
        self.backend = None
        self.cursor = None
        self._signals = []

        self.set_plot(plot)
        Signals.connect(self.project, "close", (lambda sender: self.destroy()))
Exemplo n.º 27
0
    def arrange(self, rows=1, cols=1):

        layers = self.plot.layers
        n = len(layers)

        if n > (rows*cols):
            rows = int((rows*cols) / n) + 1
            cols = rows * n
            #raise ValueError("Not enough rows and cols for all layers!")

        self.figure.clear()
        self.figure.axes = []
        
        self.layer_to_axes.clear()
        self.axes_to_layer.clear()
        self.layers_cache = []

        for signal_list in self.layer_signals.itervalues():
            for signal in signal_list:
                Signals.disconnect(signal)
        self.layer_signals = {}
        
        j = 1
        for layer in layers:
            print "Setting up layer", layer
            axes = self.figure.add_subplot("%d%d%d" % (rows,cols,j))
            self.layer_to_axes[layer] = axes
            self.axes_to_layer[axes] = layer
            self.layers_cache.append(layer)

            print "Connecting to notify of ", layer
            self.layer_signals[layer] = \
              [Signals.connect(layer, 'notify', self.on_update_layer),
               Signals.connect(layer, 'notify::labels', self.on_update_labels)]

            j += 1
Exemplo n.º 28
0
    def _construct_toolbox(self):

        window = tools.Toolbox(self.app, None)
        window.set_transient_for(self)
        window.set_destroy_with_parent(True)
        window.hide()

        def cb_toggle_window(action, window):
            if action.get_active() is True: window.show()
            else: window.hide()        
        t = gtk.ToggleAction('ToggleToolbox', 'Show tools window', None, None)
        t.connect("toggled", cb_toggle_window, window)
        uihelper.get_action_group(self.uimanager, 'Application').add_action(t)

        def on_window_visibility_toggled(window, action):
            action.set_active(window.get_property('visible'))
        window.connect('hide', on_window_visibility_toggled, t)
        window.connect('show', on_window_visibility_toggled, t)

        def on_notify_project(sender, project, toolwin):
            toolwin.set_project(project)
        Signals.connect(self.app, 'notify::project', on_notify_project, window)
        
        return window
Exemplo n.º 29
0
    def update_backend(self):
        if self.backend is None:
            self.treeview.set_sensitive(False)
            return        
        self.treeview.set_sensitive(True)

        # check_in
        model = self.treeview.get_model()
        model.clear()
        for layer in self.backend.plot.layers:
             model.append((layer,))

        # connect to change of current layer
        self.backend_signals.append(
            Signals.connect(self.backend, "notify::layer",
                            (lambda sender, layer: self.set_layer(layer)))
            )
Exemplo n.º 30
0
    def set_plot(self, plot):
        if plot == self.plot:
            return        

        Signals.disconnect_list(self.plot_signals)
        if plot is not None:
            self.layer = plot.current_layer
            self.plot_signals.append(
                Signals.connect(plot, "notify::current_layer", self.on_notify_layer)
                )
        else:
            self.layer = None

        self.set_sensitive(plot is not None)

        self.plot = plot        
        self.update_plot()