main.py :  » IDE » PIDA » pida-0.6beta3 » pida » utils » pycons » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » IDE » PIDA 
PIDA » pida 0.6beta3 » pida » utils » pycons » main.py
#! /usr/bin/env python
#
# Copyright (c) 2008, Nicolas Rougier
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the University of California, Berkeley nor the
#       names of its contributors may be used to endorse or promote products
#       derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

""" Interactive Python/IPython/Pylab console

This console implements a python (or ipython) shell within a GTK window and
handles python stdin/stderr/stdout redirection and system wide stdout/stderr
redirection (using a pipe), provides history based on the GNU readline package
and automatic completion. It is also able to display matplotlib figures
inline. Each call to the show functions actually produces a FigureCanvasGTKAgg
that is inserted within the console.

Usage: ./pycons [--ipython] [--pylab] [--toolbar] file

You can refresh all active figures by calling the refresh() method and replot
the last figures using the replot() method. You can also zoom(), pan(), home(),
back(), forward() and save() active figure.
"""

import os, os.path
import sys
import gc
import gobject
import gtk
import pango

def pylab_available():
    if globals().has_key('_pylab_available'):
        return globals()['_pylab_available']
    global _pylab_available
    try:
        import matplotlib
        matplotlib.use('GtkAgg')
        from matplotlib.backends.backend_gtkagg import 
            import FigureCanvasGTKAgg as Canvas
        from matplotlib.backends.backend_gtkagg import 
            import NavigationToolbar2GTKAgg as NavigationToolbar
        import matplotlib.backends.backend_gtkagg as backend_gtkagg
        def draw_if_interactive():
            """ Is called after every pylab drawing command """
            show(console)
        backend_gtkagg.draw_if_interactive = draw_if_interactive
        import pylab
        import matplotlib.pylab
        from matplotlib._pylab_helpers import Gcf
        _pylab_available = True
    except:
        _pylab_available = False

def ipython_available():
    if globals().has_key('_ipython_available'):
        return globals()['_ipython_available']
    global _ipython_available
    _ipython_available = True
    try:
        import IPython
    except:
        _ipython_available = False
    return _ipython_available

try:
    from functools import partial
except ImportError:
    def partial(func, *args, **keywords):
        def newfunc(*fargs, **fkeywords):
            newkeywords = keywords.copy()
            newkeywords.update(fkeywords)
            return func(*(args + fargs), **newkeywords)
        newfunc.func = func
        newfunc.args = args
        newfunc.keywords = keywords
        return newfunc

import console as cons


# ---------------------------------------------------------------------- replace
def replace (console, canvas, anchor):
    """ Replaces a given canvas with a static image replica """

    figures = console.figures
    view = console.view
    canvas.draw()
    w, h = canvas.get_size_request()
    pixbuf = gtk.gdk.pixbuf_new_from_data (
        canvas.buffer_rgba(0,0), gtk.gdk.COLORSPACE_RGB, True,8,w,h,w*4)
    image = gtk.Image()
    image.set_from_pixbuf (pixbuf)
    widget = anchor.get_widgets()
    for widget in anchor.get_widgets():
        for child in widget.get_children():
            widget.remove (child)
    view.add_child_at_anchor(image, anchor)
    image.show()
    #gc.collect()
    return widget

# ----------------------------------------------------------------------- refresh
def refresh(console):
    """ Refreshs all active canvas  """

    figures = console.figures
    for fig in figures:
        figure, canvas, anchor = fig
        canvas.draw()
    while gtk.events_pending():
        gtk.main_iteration()

# ----------------------------------------------------------------------- refresh
def figure_enter(widget, event, console):
    """ Change cursor to an arrow """

    watch = gtk.gdk.Cursor(gtk.gdk.TOP_LEFT_ARROW)
    widget.window.set_cursor (watch)
    widget.grab_focus()
    console.active_canvas = widget.get_child()

# ----------------------------------------------------------------------- refresh
def figure_leave(widget, event, console):
    """ Change cursor to text cursor """

    cursor = gtk.gdk.Cursor(gtk.gdk.XTERM)
    widget.window.set_cursor (cursor)
    console.grab_focus()
    console.active_canvas = None

# ----------------------------------------------------------------------- insert
def insert (console, figure):
    """  Inserts a new canvas for the given figure """

    figures = console.figures
    last_figure = console.last_figure
    figure.set_facecolor ('w')
    view = console.view
    buffer = console.buffer

    # Compute size of the canvas according to current console visible area
    x,y,width,height = console.get_allocation()
    dpi = figure.get_dpi()
    figwidth = figure.get_figwidth() * dpi
    figheight = figure.get_figheight() * dpi
    w = int (width*.75)
    h = int ( (w/figwidth)*figheight)
    if h > height*.75:
        h = int (height*.75)
        w = int ( (h/figheight)*figwidth)
    figure.set_figwidth  (w/dpi)
    figure.set_figheight (h/dpi)
    canvas = Canvas(figure)
    for s,func in console.callbacks:
        canvas.mpl_connect(s,func)
    canvas.set_size_request (w,h)
    canvas.show_all()
    console.write ('\n')
    console.write (' ', 'center')
    iter = buffer.get_iter_at_mark(buffer.get_mark('insert'))
    anchor = buffer.create_child_anchor(iter)
    console.write (' ', 'center')

    if console.use_toolbar:
        boxout = gtk.EventBox()
        boxout.set_border_width(0)
        boxin =  gtk.EventBox()
        boxin.set_border_width(1)
        boxout.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#cccccc"))
        boxout.add (boxin)

    vbox = gtk.VBox()
    box = gtk.EventBox()
    box.add(canvas)
    box.connect ('enter-notify-event', figure_enter, console)
    box.connect ('leave-notify-event', figure_leave, console)
    vbox.add(box)
    toolbar = NavigationToolbar(canvas, None)
    vbox.add(toolbar)

    if console.use_toolbar:
        boxin.add(vbox)
        boxout.show_all()
        vbox.show()
        box.show()
        view.add_child_at_anchor(boxout, anchor)
    else:
        vbox.show_all()
        toolbar.hide()
        view.add_child_at_anchor(vbox, anchor)

    console.shell.namespace()['pan'] = toolbar.pan
    console.shell.namespace()['zoom'] = toolbar.zoom
    console.shell.namespace()['back'] = toolbar.back
    console.shell.namespace()['forward'] = toolbar.forward
    console.shell.namespace()['home'] = toolbar.forward
    console.shell.namespace()['save'] = partial(toolbar.save_figure,1)
    console.write ('\n')
    figures.append ( (figure, canvas, anchor) )
    console.last_figure = figure

# ----------------------------------------------------------------------- refresh
def refresh(console):
    """ Refreshs all active canvas  """
    figures = console.figures
    for fig in figures:
        figure, canvas, anchor = fig
        canvas.draw()

# ----------------------------------------------------------------------- replot
def replot (console):
    """
    Produces a replot of the last figure and insert it within console. Previous
    figure, if it exists, is transformed into a static image replica and
    inserted in place of the previous figure.
    """

    figures = console.figures
    last_figure = console.last_figure
    if not figures:
        if last_figure:
            insert (console, last_figure)
            return
        else:
            return
    figure, canvas, anchor = figures[-1]
    if not anchor.get_deleted():
        replace (console, canvas, anchor)
        figures.remove ( (figure, canvas, anchor) )
        #        insert (console, figure, canvas)
        insert (console, figure)
    else:
        console.figures = console.figures[0:-1]
        insert (console, figure)
    console.view.scroll_mark_onscreen(console.buffer.get_insert())
    while gtk.events_pending():
        gtk.main_iteration()


# ---------------------------------------------------------------------- connect
def connect (console, s, func):
    """ Append callback to the list of callbacks (to be connected later) """

    console.callbacks.append([s,func])


# ------------------------------------------------------------------------- show
def show (console):
    """ Insert pending figures within console """

    figures = console.figures
    last_figure = console.last_figure
    for manager in Gcf.get_all_fig_managers():
        found = False
        for fig in figures:
            figure, canvas, anchor = fig
            if figure == manager.canvas.figure:
                canvas.draw()
                found = True
                break
        if not found:
            insert (console, manager.canvas.figure)

# ---------------------------------------------------------------- class Console
class Console (cons.Console):
    """ GTK python console """

    def setup(self, argv=[], shelltype='python', banner=[],
                 filename=None, size=100):
        cons.Console.setup(self, argv, shelltype, banner, filename, size)
        os.environ['TERM'] = "dumb"
        self.buffer.create_tag('center',
                               justification=gtk.JUSTIFY_CENTER,
                               font='Mono 4')
        self.figures = []
        self.callbacks = []
        self.last_figure = None
        self.active_canvas = None
        self.view.connect ('key-press-event', self.key_press_event)
        self.view.connect ('button-press-event', self.button_press_event)
        self.view.connect ('scroll-event', self.scroll_event)


    def key_press_event (self, widget, event):
        """ Handle key press event """
        
        if self.active_canvas:
            self.active_canvas.emit ('key-press-event', event)
            return True
        return cons.Console.key_press_event (self, widget, event)

    def scroll_event (self, widget, event):
        """ Scroll event """
        if self.active_canvas:
            return True
        return False
 
    def button_press_event (self, widget, event):
        """ Button press event """
        return self.refresh()

    def refresh (self):
        """ Refresh drawing """
        for fig in self.figures:
            figure, canvas, anchor = fig
            canvas.draw()
        return False

def main(args=()):
    from optparse import OptionParser
    try:
        import IPython
    except:
        pass

    usage = "Usage: %pycons [options] file"
    parser = OptionParser(usage=usage, version="%prog 1.0")
    parser.add_option("", "--embed", action="store_true", dest="embed",
                      help="Prepares for embedding window")
    parser.add_option("", "--socket", action="store", dest="socket", default=0,
                      help="Pass a Socket ID for embedding")
    parser.add_option("", "--ipython", action="store_true", dest="ipython",
                      help="Use IPython as shell (if available)")
    parser.add_option("", "--pylab",   action="store_true", dest="pylab",
                      help="Use Pylab integration (if available)")
    parser.add_option("", "--toolbar",  action="store_true", dest="toolbar",
                      help="Use Pylab toolbar")
    (options, args) = parser.parse_args(args=list(args))

    filename = os.path.expanduser("~/.pyhistory")

    gtk.rc_add_default_file(os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "..", 
        "resources", "data", "gtkrc-2.0"))
        )
    gtk.rc_add_default_file(os.path.join(os.path.expanduser("~/.pida2"), "gtkrc-2.0"))
    # we have to force reload the settings
    gtk.rc_reparse_all_for_settings(gtk.settings_get_default(), True)

    p = 'Python %s' % sys.version.split(' ')[0]
    #l = 'matplotlib %s' % matplotlib.__version__
    shelltype = 'python'
    if (options.ipython and ipython_available()) is True:
        p = 'IPython %s' % IPython.__version__
        shelltype = 'ipython'
    if options.pylab and pylab_available():
        banner = [
            ['GTK Pylab console\n', 'title'],
            [' Using %s and %s\n' % (p,l),'subtitle'],
            [' Extra commands: "replot", "refresh", "pan", "zoom", "back", "forward", "home"\n',
             'subtitle']
            ]
    else:
        banner = [
            ['GTK Python console\n', 'title'],
            [' Using %s\n' % p,'subtitle'],
            [' Type "help", "copyright", "credits" or "license" for more information.\n',
             'subtitle']
            ]


    console = Console()
    if options.toolbar:
        console.use_toolbar = True
    else:
        console.use_toolbar = False

    if options.embed:
        window = gtk.Plug(long(options.socket))
        print "WINDOWID: %s" %window.get_id()
    else:
        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
    window.set_position(gtk.WIN_POS_CENTER)
    window.set_name('PidaPyshell')
    window.set_default_size(800,600)
    window.set_border_width(0)
    window.add (console)
    console.show()
    window.show()
    console.setup(argv=args, shelltype=shelltype,
                      banner=banner, filename=filename, size=100)
    window.connect('destroy-event', console.quit)
    window.connect('delete-event', console.quit)
    window.show_all()
    console.grab_focus()
    # usefull when debugging UI
    #__builtins__['PYSHELL'] =  window

    if options.pylab and pylab_available():
        console.write ("from pylab import *")
        console.execute()
        pylab.show = partial (show, console)
        matplotlib.pylab.show = pylab.show
        matplotlib.pyplot.show = pylab.show
        pylab.connect = partial (connect, console)
        matplotlib.pylab.connect = pylab.connect
        console.shell.namespace()['replot'] = partial (replot, console)
        console.shell.namespace()['refresh'] = partial (refresh, console)

    def execfiles(console):
        console.write ('execfile("%s")' % args[0])
        #  execfile(console.argv[0], console.shell.namespace())
        console.execute()
        return False
    if len(args):
        gobject.timeout_add(50, execfiles, console)


    # Prevent external commands/scripts to quit
    while console.do_quit == False:
        gtk.main()


if __name__ == "__main__":
    # this is run by pida for embedding
    import sys
    args = sys.argv[:]
    args.remove(__file__)
    main(args)

www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.