veusz_listen.py 4.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
#!/usr/bin/env python

#    Copyright (C) 2005 Jeremy S. Sanders
#    Email: Jeremy Sanders <jeremy@jeremysanders.net>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with this program; if not, write to the Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
##############################################################################

"""
Veusz interface which listens to stdin, and receives commands.
Results are written to stdout

All commands in CommandInterface are supported, plus further commands:
Quit: exit the listening program
Zoom x: Change the zoom factor of the plot to x
"""

30
from __future__ import division
31 32
import sys

33
from . import qtall as qt4
34
from .compat import cstr
35

36 37
from .windows.simplewindow import SimpleWindow
from . import document
38 39 40 41 42 43 44 45

class ReadingThread(qt4.QThread):
    """Stdin reading thread. Emits newline signals with new data.

    We could use a QSocketNotifier on Unix, but this doesn't work on
    Windows as its stdin is a weird object
    """

46 47
    newline = qt4.pyqtSignal(cstr)

48 49 50 51 52 53
    def run(self):
        """Emit lines read from stdin."""
        while True:
            line = sys.stdin.readline()
            if line == '':
                break
54
            self.newline.emit(line)
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81

class InputListener(qt4.QObject):
    """Class reads text from stdin, in order to send commands to a document."""

    def __init__(self, window):
        """Initialse the listening object to send commands to the
        document given by window."""
        
        qt4.QObject.__init__(self)

        self.window = window
        self.document = window.document
        self.plot = window.plot
        self.pickle = False

        self.ci = document.CommandInterpreter(self.document)
        self.ci.addCommand('Quit', self.quitProgram)
        self.ci.addCommand('Zoom', self.plotZoom)
        self.ci.addCommand('EnableToolbar', self.enableToolbar)
        self.ci.addCommand('Pickle', self.enablePickle)

        self.ci.addCommand('ResizeWindow', self.resizeWindow)
        self.ci.addCommand('SetUpdateInterval', self.setUpdateInterval)
        self.ci.addCommand('MoveToPage', self.moveToPage)

        # reading is done in a separate thread so as not to block
        self.readthread = ReadingThread(self)
82
        self.readthread.newline.connect(self.processLine)
83
        self.readthread.start()
84

85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
    def resizeWindow(self, width, height):
        """ResizeWindow(width, height)

        Resize the window to be width x height pixels."""
        self.window.resize(width, height)

    def setUpdateInterval(self, interval):
        """SetUpdateInterval(interval)

        Set graph update interval.
        interval is in milliseconds (ms)
        set to zero to disable updates
        """
        self.plot.setTimeout(interval)

    def moveToPage(self, pagenum):
        """MoveToPage(pagenum)

        Tell window to show specified pagenumber (starting from 1).
        """
        self.plot.setPageNumber(pagenum-1)

    def quitProgram(self):
        """Exit the program."""
        self.window.close()

    def plotZoom(self, zoomfactor):
        """Set the plot zoom factor."""
        self.window.setZoom(zoomfactor)

    def enableToolbar(self, enable=True):
        """Enable plot toolbar."""
        self.window.enableToolbar(enable)
        
    def enablePickle(self, on=True):
        """Enable/disable pickling of commands to/data from veusz"""
        self.pickle = on

    def processLine(self, line):
        """Process inputted line."""
        if self.pickle:
            # line is repr form of pickled string get get rid of \n
            retn = self.ci.runPickle( eval(line.strip()) )
            sys.stdout.write('%s\n' % repr(retn))
            sys.stdout.flush()
            
        else:
            self.ci.run(line)

def openWindow(args, quiet=False):
    '''Opening listening window.
    args is a list of arguments to the program
    '''
    global _win
    global _listen

    if len(args) > 1:
        name = args[1]
    else:
        name = 'Veusz output'

    _win = SimpleWindow(name)
    if not quiet:
        _win.show()
    _listen = InputListener(_win)

def run():
    '''Actually run the program.'''
    app = qt4.QApplication(sys.argv)
    openWindow(sys.argv)
    app.exec_()

# if ran as a program
if __name__ == '__main__':
    run()