home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / totem / plugins / pythonconsole / console.py next >
Encoding:
Python Source  |  2009-04-14  |  9.9 KB  |  312 lines

  1. # -*- coding: utf-8 -*-
  2.  
  3. # console.py -- Console widget
  4. #
  5. # Copyright (C) 2006 - Steve Fr√©cinaux
  6. #
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 2, or (at your option)
  10. # any later version.
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program; if not, write to the Free Software
  18. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19.  
  20. # Parts from "Interactive Python-GTK Console" (stolen from epiphany's console.py)
  21. #     Copyright (C), 1998 James Henstridge <james@daa.com.au>
  22. #     Copyright (C), 2005 Adam Hooper <adamh@densi.com>
  23. # Bits from gedit Python Console Plugin
  24. #     Copyrignt (C), 2005 Rapha√´l Slinckx
  25. #
  26. # The Totem project hereby grant permission for non-gpl compatible GStreamer
  27. # plugins to be used and distributed together with GStreamer and Totem. This
  28. # permission are above and beyond the permissions granted by the GPL license
  29. # Totem is covered by.
  30. #
  31. # Monday 7th February 2005: Christian Schaller: Add exception clause.
  32. # See license_change file for details.
  33.  
  34. import string
  35. import sys
  36. import re
  37. import traceback
  38. import gobject
  39. import pango
  40. import gtk
  41.  
  42. class PythonConsole(gtk.ScrolledWindow):
  43.     def __init__(self, namespace = {}, destroy_cb = None):
  44.         gtk.ScrolledWindow.__init__(self)
  45.  
  46.         self.destroy_cb = destroy_cb
  47.         self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC);
  48.         self.set_shadow_type(gtk.SHADOW_IN)
  49.         self.view = gtk.TextView()
  50.         self.view.modify_font(pango.FontDescription('Monospace'))
  51.         self.view.set_editable(True)
  52.         self.view.set_wrap_mode(gtk.WRAP_WORD_CHAR)
  53.         self.add(self.view)
  54.         self.view.show()
  55.  
  56.         buffer = self.view.get_buffer()
  57.         self.normal = buffer.create_tag("normal")
  58.         self.error  = buffer.create_tag("error")
  59.         self.error.set_property("foreground", "red")
  60.         self.command = buffer.create_tag("command")
  61.         self.command.set_property("foreground", "blue")
  62.  
  63.         self.__spaces_pattern = re.compile(r'^\s+')        
  64.         self.namespace = namespace
  65.  
  66.         self.block_command = False
  67.  
  68.         # Init first line
  69.         buffer.create_mark("input-line", buffer.get_end_iter(), True)
  70.         buffer.insert(buffer.get_end_iter(), ">>> ")
  71.         buffer.create_mark("input", buffer.get_end_iter(), True)
  72.  
  73.         # Init history
  74.         self.history = ['']
  75.         self.history_pos = 0
  76.         self.current_command = ''
  77.         self.namespace['__history__'] = self.history
  78.  
  79.         # Set up hooks for standard output.
  80.         self.stdout = OutFile(self, sys.stdout.fileno(), self.normal)
  81.         self.stderr = OutFile(self, sys.stderr.fileno(), self.error)
  82.         
  83.         # Signals
  84.         self.view.connect("key-press-event", self.__key_press_event_cb)
  85.         buffer.connect("mark-set", self.__mark_set_cb)
  86.         
  87.          
  88.     def __key_press_event_cb(self, view, event):
  89.         if event.keyval == gtk.keysyms.d and event.state == gtk.gdk.CONTROL_MASK:
  90.             self.destroy()
  91.         
  92.         elif event.keyval == gtk.keysyms.Return and event.state == gtk.gdk.CONTROL_MASK:
  93.             # Get the command
  94.             buffer = view.get_buffer()
  95.             inp_mark = buffer.get_mark("input")
  96.             inp = buffer.get_iter_at_mark(inp_mark)
  97.             cur = buffer.get_end_iter()
  98.             line = buffer.get_text(inp, cur)
  99.             self.current_command = self.current_command + line + "\n"
  100.             self.history_add(line)
  101.  
  102.             # Prepare the new line
  103.             cur = buffer.get_end_iter()
  104.             buffer.insert(cur, "\n... ")
  105.             cur = buffer.get_end_iter()
  106.             buffer.move_mark(inp_mark, cur)
  107.             
  108.             # Keep indentation of precendent line
  109.             spaces = re.match(self.__spaces_pattern, line)
  110.             if spaces is not None:
  111.                 buffer.insert(cur, line[spaces.start() : spaces.end()])
  112.                 cur = buffer.get_end_iter()
  113.                 
  114.             buffer.place_cursor(cur)
  115.             gobject.idle_add(self.scroll_to_end)
  116.             return True
  117.         
  118.         elif event.keyval == gtk.keysyms.Return:
  119.             # Get the marks
  120.             buffer = view.get_buffer()
  121.             lin_mark = buffer.get_mark("input-line")
  122.             inp_mark = buffer.get_mark("input")
  123.  
  124.             # Get the command line
  125.             inp = buffer.get_iter_at_mark(inp_mark)
  126.             cur = buffer.get_end_iter()
  127.             line = buffer.get_text(inp, cur)
  128.             self.current_command = self.current_command + line + "\n"
  129.             self.history_add(line)
  130.  
  131.             # Make the line blue
  132.             lin = buffer.get_iter_at_mark(lin_mark)
  133.             buffer.apply_tag(self.command, lin, cur)
  134.             buffer.insert(cur, "\n")
  135.             
  136.             cur_strip = self.current_command.rstrip()
  137.  
  138.             if cur_strip.endswith(":") \
  139.             or (self.current_command[-2:] != "\n\n" and self.block_command):
  140.                 # Unfinished block command
  141.                 self.block_command = True
  142.                 com_mark = "... "
  143.             elif cur_strip.endswith("\\"):
  144.                 com_mark = "... "
  145.             else:
  146.                 # Eval the command
  147.                 self.__run(self.current_command)
  148.                 self.current_command = ''
  149.                 self.block_command = False
  150.                 com_mark = ">>> "
  151.  
  152.             # Prepare the new line
  153.             cur = buffer.get_end_iter()
  154.             buffer.move_mark(lin_mark, cur)
  155.             buffer.insert(cur, com_mark)
  156.             cur = buffer.get_end_iter()
  157.             buffer.move_mark(inp_mark, cur)
  158.             buffer.place_cursor(cur)
  159.             gobject.idle_add(self.scroll_to_end)
  160.             return True
  161.  
  162.         elif event.keyval == gtk.keysyms.KP_Down or event.keyval == gtk.keysyms.Down:
  163.             # Next entry from history
  164.             view.emit_stop_by_name("key_press_event")
  165.             self.history_down()
  166.             gobject.idle_add(self.scroll_to_end)
  167.             return True
  168.  
  169.         elif event.keyval == gtk.keysyms.KP_Up or event.keyval == gtk.keysyms.Up:
  170.             # Previous entry from history
  171.             view.emit_stop_by_name("key_press_event")
  172.             self.history_up()
  173.             gobject.idle_add(self.scroll_to_end)
  174.             return True
  175.  
  176.         elif event.keyval == gtk.keysyms.KP_Left or event.keyval == gtk.keysyms.Left or \
  177.              event.keyval == gtk.keysyms.BackSpace:
  178.             buffer = view.get_buffer()
  179.             inp = buffer.get_iter_at_mark(buffer.get_mark("input"))
  180.             cur = buffer.get_iter_at_mark(buffer.get_insert())
  181.             return inp.compare(cur) == 0
  182.  
  183.         elif event.keyval == gtk.keysyms.Home:
  184.             # Go to the begin of the command instead of the begin of the line
  185.             buffer = view.get_buffer()
  186.             inp = buffer.get_iter_at_mark(buffer.get_mark("input"))
  187.             if event.state == gtk.gdk.SHIFT_MASK:
  188.                 buffer.move_mark_by_name("insert", inp)
  189.             else:
  190.                 buffer.place_cursor(inp)
  191.             return True
  192.         
  193.     def __mark_set_cb(self, buffer, iter, name):
  194.         input = buffer.get_iter_at_mark(buffer.get_mark("input"))
  195.         pos   = buffer.get_iter_at_mark(buffer.get_insert())
  196.         self.view.set_editable(pos.compare(input) != -1)
  197.  
  198.     def get_command_line(self):
  199.         buffer = self.view.get_buffer()
  200.         inp = buffer.get_iter_at_mark(buffer.get_mark("input"))
  201.         cur = buffer.get_end_iter()
  202.         return buffer.get_text(inp, cur)
  203.     
  204.     def set_command_line(self, command):
  205.         buffer = self.view.get_buffer()
  206.         mark = buffer.get_mark("input")
  207.         inp = buffer.get_iter_at_mark(mark)
  208.         cur = buffer.get_end_iter()
  209.         buffer.delete(inp, cur)
  210.         buffer.insert(inp, command)
  211.         buffer.select_range(buffer.get_iter_at_mark(mark), buffer.get_end_iter())
  212.         self.view.grab_focus()
  213.     
  214.     def history_add(self, line):
  215.         if line.strip() != '':
  216.             self.history_pos = len(self.history)
  217.             self.history[self.history_pos - 1] = line
  218.             self.history.append('')
  219.     
  220.     def history_up(self):
  221.         if self.history_pos > 0:
  222.             self.history[self.history_pos] = self.get_command_line()
  223.             self.history_pos = self.history_pos - 1
  224.             self.set_command_line(self.history[self.history_pos])
  225.             
  226.     def history_down(self):
  227.         if self.history_pos < len(self.history) - 1:
  228.             self.history[self.history_pos] = self.get_command_line()
  229.             self.history_pos = self.history_pos + 1
  230.             self.set_command_line(self.history[self.history_pos])
  231.     
  232.     def scroll_to_end(self):
  233.         iter = self.view.get_buffer().get_end_iter()
  234.         self.view.scroll_to_iter(iter, 0.0)
  235.         return False
  236.  
  237.     def write(self, text, tag = None):
  238.         buffer = self.view.get_buffer()
  239.         if tag is None:
  240.             buffer.insert(buffer.get_end_iter(), text)
  241.         else:
  242.             buffer.insert_with_tags(buffer.get_end_iter(), text, tag)
  243.         gobject.idle_add(self.scroll_to_end)
  244.      
  245.      def eval(self, command, display_command = False):
  246.         buffer = self.view.get_buffer()
  247.         lin = buffer.get_mark("input-line")
  248.         buffer.delete(buffer.get_iter_at_mark(lin),
  249.                       buffer.get_end_iter())
  250.  
  251.         if isinstance(command, list) or isinstance(command, tuple):
  252.              for c in command:
  253.                  if display_command:
  254.                      self.write(">>> " + c + "\n", self.command)
  255.                  self.__run(c)
  256.         else:
  257.              if display_command:
  258.                  self.write(">>> " + c + "\n", self.command)
  259.             self.__run(command) 
  260.  
  261.         cur = buffer.get_end_iter()
  262.         buffer.move_mark_by_name("input-line", cur)
  263.         buffer.insert(cur, ">>> ")
  264.         cur = buffer.get_end_iter()
  265.         buffer.move_mark_by_name("input", cur)
  266.         self.view.scroll_to_iter(buffer.get_end_iter(), 0.0)
  267.     
  268.      def __run(self, command):
  269.         sys.stdout, self.stdout = self.stdout, sys.stdout
  270.         sys.stderr, self.stderr = self.stderr, sys.stderr
  271.         
  272.         try:
  273.             try:
  274.                 r = eval(command, self.namespace, self.namespace)
  275.                 if r is not None:
  276.                     print `r`
  277.             except SyntaxError:
  278.                 exec command in self.namespace
  279.         except:
  280.             if hasattr(sys, 'last_type') and sys.last_type == SystemExit:
  281.                 self.destroy()
  282.             else:
  283.                 traceback.print_exc()
  284.  
  285.         sys.stdout, self.stdout = self.stdout, sys.stdout
  286.         sys.stderr, self.stderr = self.stderr, sys.stderr
  287.  
  288.     def destroy(self):
  289.         pass
  290.         #gtk.ScrolledWindow.destroy(self)
  291.         
  292. class OutFile:
  293.     """A fake output file object. It sends output to a TK test widget,
  294.     and if asked for a file number, returns one set on instance creation"""
  295.     def __init__(self, console, fn, tag):
  296.         self.fn = fn
  297.         self.console = console
  298.         self.tag = tag
  299.     def close(self):         pass
  300.     def flush(self):         pass
  301.     def fileno(self):        return self.fn
  302.     def isatty(self):        return 0
  303.     def read(self, a):       return ''
  304.     def readline(self):      return ''
  305.     def readlines(self):     return []
  306.     def write(self, s):      self.console.write(s, self.tag)
  307.     def writelines(self, l): self.console.write(l, self.tag)
  308.     def seek(self, a):       raise IOError, (29, 'Illegal seek')
  309.     def tell(self):          raise IOError, (29, 'Illegal seek')
  310.     truncate = tell
  311.