- substituted TextView widget with vte.Terminal which allows spritz to redirect portage.doebuild output to it

- further development on package queue execution
NOTE: you will need vte compiled with python USE flag from now on


git-svn-id: http://svn.sabayonlinux.org/projects/entropy/trunk@1036 cd1c1023-2f26-0410-ae45-c471fc1f0318
This commit is contained in:
(no author)
2008-01-12 15:38:27 +00:00
parent 6b82b00341
commit f34bdff9fa
6 changed files with 159 additions and 207 deletions
-17
View File
@@ -61,13 +61,11 @@ class QueueExecutor:
# XXX handle status
rc = Package.run()
if rc != 0:
self.close_stdout_stderr()
return -1,rc
Package.kill()
del Package
self.Entropy.cycleDone()
self.open_stdout_stderr()
# then removalQueue
totalremovalqueue = len(removalQueue)
currentremovalqueue = 0
@@ -89,7 +87,6 @@ class QueueExecutor:
# XXX handle status
rc = Package.run()
if rc != 0:
self.close_stdout_stderr()
return -1,rc
Package.kill()
@@ -116,29 +113,15 @@ class QueueExecutor:
# XXX handle status
rc = Package.run()
if rc != 0:
self.close_stdout_stderr()
return -1,rc
Package.kill()
del metaopts
del Package
self.close_stdout_stderr()
return 0,0
def open_stdout_stderr(self):
# redirecting stdout,stderr to the viewOutput
sys.stdout, self.Entropy.output.stdout = self.Entropy.output.stdout, sys.stdout
sys.stderr, self.Entropy.output.stderr = self.Entropy.output.stderr, sys.stderr
sys.stdin, self.Entropy.output.stdin = self.Entropy.output.stdin, sys.stdin
def close_stdout_stderr(self):
# do the contrary
sys.stdout, self.Entropy.output.stdout = self.Entropy.output.stdout, sys.stdout
sys.stderr, self.Entropy.output.stderr = self.Entropy.output.stderr, sys.stderr
sys.stdin, self.Entropy.output.stdin = self.Entropy.output.stdin, sys.stdin
class Equo(EquoInterface):
def connect_to_gui(self, progress, progressLog, viewOutput):
+17 -102
View File
@@ -24,85 +24,18 @@ import gobject
import types
import sys
from misc import const
import vte
class gtkoutfile:
"""
A fake output file object. It sends output to a GTK TextView widget,
and if asked for a file number, returns one set on instance creation
"""
# XXX hook font and colors ?
class SpritzConsole(vte.Terminal):
def __init__(self, console, fn, font):
self.fn = fn
self.console = console
self.font = font
def __init__(self, default_style = None):
vte.Terminal.__init__(self)
#if defaulty_style:
#self.console.set_font_from_string(self.cfg.get("consolefont", "GTK"))
def close(self):
pass
def flush(self):
self.close()
def fileno(self):
return self.fn
def isatty(self):
return False
def read(self, a):
return ''
def readline(self):
return ''
def readlines(self):
return []
def write(self, s):
self.console.write (s, self.font)
def writelines(self, l):
for s in l:
self.console.write (s, self.font)
def seek(self, a):
raise IOError, (29, 'Illegal seek')
def tell(self):
raise IOError, (29, 'Illegal seek')
def truncate(self):
self.tell()
# =============================================================================
class gtkinfile:
"""
A fake input file object. It receives input from a GTK TextView widget,
and if asked for a file number, returns one set on instance creation
"""
def __init__(self, console, fn):
self.fn = fn
self.console = console
def close(self): pass
flush = close
def fileno(self): return self.fn
def isatty(self): return False
def read(self, a): return self.readline()
def readline(self):
self.console.input_mode = True
while self.console.input_mode:
while gtk.events_pending():
gtk.main_iteration()
s = self.console.input
self.console.input = ''
return s+'\n'
def readlines(self): return []
def write(self, s): return None
def writelines(self, l): return None
def seek(self, a): raise IOError, (29, 'Illegal seek')
def tell(self): raise IOError, (29, 'Illegal seek')
truncate = tell
def reset (self):
vte.Terminal.reset(self, True, True)
class TextViewConsole:
@@ -111,11 +44,6 @@ class TextViewConsole:
self.textview = textview
self.buffer = self.textview.get_buffer()
# Setup hooks for standard output.
self.stdout = gtkoutfile (self, sys.stdout.fileno(), 'normal')
self.stderr = gtkoutfile (self, sys.stderr.fileno(), 'error')
self.stdin = gtkinfile (self, sys.stdin.fileno())
self.endMark = self.buffer.create_mark( "End", self.buffer.get_end_iter(), False )
self.startMark = self.buffer.create_mark( "Start", self.buffer.get_start_iter(), False )
#setup styles.
@@ -192,18 +120,6 @@ class TextViewConsole:
self.buffer.insert_with_tags( end, txt, style )
self.textview.scroll_to_iter( self.buffer.get_end_iter(), 0.0 )
def write(self, txt):
self.write_line(txt)
def isatty(self):
return False
def fileno(self):
return 1
def flush(self):
return
def _toUTF( self, txt ):
rc=""
if isinstance(txt,types.UnicodeType):
@@ -214,26 +130,25 @@ class TextViewConsole:
except UnicodeDecodeError, e:
rc = unicode( txt, 'iso-8859-1' )
return rc
def clear(self):
self.buffer.set_text('')
def goTop(self):
self.textview.scroll_to_iter( self.buffer.get_start_iter(), 0.0 )
#
#
# These classes come from the article
# http://www.linuxjournal.com/article/4702
#
# They have been modified a little to support domain
#
#
class UI(gtk.glade.XML):
"""Base class for UIs loaded from glade."""
def __init__(self, filename, rootname,domain=None):
"""Initialize a new instance.
`filename' is the name of the .glade file containing the UI hierarchy.
@@ -253,7 +168,7 @@ class UI(gtk.glade.XML):
if result is None:
raise AttributeError("Can't find widget %s in %s.\n" %
(`name`, `self.filename`))
# Cache the widget to speed up future lookups. If multiple
# widgets in a hierarchy have the same name, the lookup
# behavior is non-deterministic just as for libglade.
+13 -8
View File
@@ -20,7 +20,7 @@
from etpgui import *
from misc import YumexQueue,YumexConf,const,cleanMarkupSting
from views import *
from etpgui.widgets import TextViewConsole
from etpgui.widgets import TextViewConsole, SpritzConsole
from i18n import _
@@ -196,7 +196,6 @@ class YumexProgress:
""" Progress Class """
def __init__( self, ui, set_page_func,parent ):
self.ui = ui
#self.output = TextViewConsole( self.ui.viewOutput )
self.set_page_func = set_page_func
self.parent = parent
self.ui.progressMainLabel.set_text( "" )
@@ -264,7 +263,6 @@ class SpritzGUI:
''' This class contains GUI related methods '''
def __init__(self, EquoConnection, etpbase):
self.settings = YumexConf()
self.output = TextViewConsole( self.ui.viewOutput )
# Package & Queue Views
self.Entropy = EquoConnection
self.etpbase = etpbase
@@ -288,7 +286,7 @@ class SpritzGUI:
# Package Radiobuttons
self.packageRB = {}
self.lastPkgPB = 'updates'
self.tooltip = gtk.Tooltips()
self.tooltip = gtk.Tooltips()
def setupGUI(self):
''' Setup the GUI'''
@@ -298,6 +296,17 @@ class SpritzGUI:
self.ui.main.present()
self.setupPageButtons() # Setup left side toolbar
self.setPage(self.activePage)
# put self.console in place
self.console = SpritzConsole()
self.console.set_scrollback_lines(1024)
self.console.set_scroll_on_output(True)
#self.console.connect("button-press-event", self.cb_right_click)
termScroll = gtk.VScrollbar(self.console.get_adjustment())
self.ui.vteBox.pack_start(self.console, True, True)
self.ui.termScrollBox.pack_start(termScroll, False)
self.ui.termHBox.show_all()
# hide All Packages radio button, useless
self.ui.rbAll.hide()
self.setupPkgFilter()
@@ -332,10 +341,6 @@ class SpritzGUI:
self.createButton( _( "Output View" ), "button-output.png", 'output' )
style = self.ui.leftEvent.get_style()
# Set the background of the horisontal buttonbar to the same as the views.
# To make it look good on other than default gtk themes.
style = self.ui.viewOutput.get_style()
self.ui.leftEvent.modify_bg( gtk.STATE_NORMAL, style.base[0])
# Setup Page Icons
self.ui.pageImage0.set_from_file ( const.PIXMAPS_PATH + '/button-repo.png' )
self.ui.pageImage3.set_from_file ( const.PIXMAPS_PATH + '/button-group.png' )
+54 -5
View File
@@ -40,7 +40,7 @@ import packages
class const:
''' This Class contains all the Constants in Yumex'''
__spritz_version__ = "0.1"
__spritz_version__ = "0.2"
# Paths
MAIN_PATH = os.path.abspath( os.path.dirname( sys.argv[0] ) );
GLADE_FILE = MAIN_PATH+'/spritz.glade'
@@ -665,8 +665,57 @@ class YumexOptions:
def cleanMarkupSting(msg):
msg = str(msg) # make sure it is a string
msg = gobject.markup_escape_text(msg)
#msg = msg.replace('@',' AT ')
#msg = msg.replace('<','[')
#msg = msg.replace('>',']')
#msg = msg.replace('@',' AT ')
#msg = msg.replace('<','[')
#msg = msg.replace('>',']')
return msg
class fakeoutfile:
"""
A fake output file object. It sends output to a GTK TextView widget,
and if asked for a file number, returns one set on instance creation
"""
def __init__(self, fn):
self.fn = fn
def close(self):
pass
def flush(self):
self.close()
def fileno(self):
return self.fn
def isatty(self):
return False
def read(self, a):
return ''
def readline(self):
return ''
def readlines(self):
return []
def write(self, s):
os.write(self.fn,s)
#sys.stdout.write(s+"\n")
def write_line(self, s):
self.write(s)
def writelines(self, l):
for s in l:
self.write(s)
def seek(self, a):
raise IOError, (29, 'Illegal seek')
def tell(self):
raise IOError, (29, 'Illegal seek')
def truncate(self):
self.tell()
+63 -71
View File
@@ -4,13 +4,14 @@
<glade-interface>
<widget class="GtkWindow" id="main">
<property name="height_request">570</property>
<property name="visible">True</property>
<property name="title" translatable="yes">Spritz Package Manager</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_CENTER</property>
<property name="modal">False</property>
<property name="default_width">800</property>
<property name="default_height">600</property>
<property name="default_height">550</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="icon_name">spritz-icon</property>
@@ -1744,7 +1745,7 @@
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
</widget>
<packing>
<property name="padding">18</property>
<property name="padding">9</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
@@ -1775,79 +1776,12 @@
<property name="visible">True</property>
</widget>
<packing>
<property name="padding">5</property>
<property name="padding">2</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="outputSW">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkViewport" id="viewport1">
<property name="visible">True</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<child>
<widget class="GtkVBox" id="vbox18">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkScrolledWindow" id="swOutput">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTextView" id="viewOutput">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
<property name="overwrite">False</property>
<property name="accepts_tab">True</property>
<property name="justification">GTK_JUSTIFY_LEFT</property>
<property name="wrap_mode">GTK_WRAP_WORD</property>
<property name="cursor_visible">True</property>
<property name="pixels_above_lines">0</property>
<property name="pixels_below_lines">0</property>
<property name="pixels_inside_wrap">0</property>
<property name="left_margin">0</property>
<property name="right_margin">0</property>
<property name="indent">0</property>
<property name="text" translatable="yes"></property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="padding">18</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="bannerBox">
<property name="visible">True</property>
@@ -1857,9 +1791,67 @@
<child>
<placeholder/>
</child>
<child>
<widget class="GtkEventBox" id="consoleEvent">
<property name="visible">True</property>
<property name="visible_window">True</property>
<property name="above_child">False</property>
<child>
<widget class="GtkHBox" id="termHBox">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkVBox" id="vteBox">
<property name="height_request">250</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<placeholder/>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="termScrollBox">
<property name="width_request">20</property>
<property name="height_request">250</property>
<property name="visible">True</property>
<property name="homogeneous">True</property>
<property name="spacing">0</property>
<child>
<placeholder/>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="padding">6</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
+12 -4
View File
@@ -18,7 +18,7 @@
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# Base Python Imports
import sys,os
import sys, os, pty
import logging
import traceback
@@ -46,7 +46,7 @@ from etpgui import *
import filters
from gui import SpritzGUI
from dialogs import *
from misc import const, YumexOptions, YumexProfile
from misc import const, YumexOptions, YumexProfile, fakeoutfile
from i18n import _
import time
@@ -62,6 +62,11 @@ class SpritzController(Controller):
# init the Controller Class to connect signals.
Controller.__init__( self, ui )
self.pty = pty.openpty()
self.output = fakeoutfile(self.pty[1])
sys.stdout = self.output
sys.stderr = self.output
def quit(self, widget=None, event=None ):
EquoConnection.save_cache()
@@ -388,9 +393,8 @@ class SpritzApplication(SpritzController,SpritzGUI):
# Setup GUI
self.setupGUI()
self.logger.info(_('GUI Setup Completed'))
# XXX
#self.profile = YumexProfile()
# setup Repositories
self.setupRepoView()
self.firstTime = True
@@ -398,6 +402,10 @@ class SpritzApplication(SpritzController,SpritzGUI):
self.Equo.connect_to_gui(self.progress, self.progressLogWrite, self.output)
self.setupSpritz()
self.console.set_pty(self.pty[0])
# setup pty
def startWorking(self):
self.isWorking = True
busyCursor(self.ui.main)