From f34bdff9fa77ac20a83640af95e008d7467c49d2 Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@cd1c1023-2f26-0410-ae45-c471fc1f0318> Date: Sat, 12 Jan 2008 15:38:27 +0000 Subject: [PATCH] - 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 --- spritz/src/entropyapi.py | 17 ----- spritz/src/etpgui/widgets.py | 119 +++++-------------------------- spritz/src/gui.py | 21 +++--- spritz/src/misc.py | 59 +++++++++++++-- spritz/src/spritz.glade | 134 ++++++++++++++++------------------- spritz/src/spritz.py | 16 +++-- 6 files changed, 159 insertions(+), 207 deletions(-) diff --git a/spritz/src/entropyapi.py b/spritz/src/entropyapi.py index 80320507a..5878e6cd8 100644 --- a/spritz/src/entropyapi.py +++ b/spritz/src/entropyapi.py @@ -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): diff --git a/spritz/src/etpgui/widgets.py b/spritz/src/etpgui/widgets.py index a5cddfd81..c11b4cf3f 100644 --- a/spritz/src/etpgui/widgets.py +++ b/spritz/src/etpgui/widgets.py @@ -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. diff --git a/spritz/src/gui.py b/spritz/src/gui.py index be3a2f621..47f7d3f20 100644 --- a/spritz/src/gui.py +++ b/spritz/src/gui.py @@ -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' ) diff --git a/spritz/src/misc.py b/spritz/src/misc.py index 266b13caa..425884097 100644 --- a/spritz/src/misc.py +++ b/spritz/src/misc.py @@ -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() \ No newline at end of file diff --git a/spritz/src/spritz.glade b/spritz/src/spritz.glade index ebc65657f..dd5b4b3ca 100644 --- a/spritz/src/spritz.glade +++ b/spritz/src/spritz.glade @@ -4,13 +4,14 @@ + 570 True Spritz Package Manager GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER False 800 - 600 + 550 True False spritz-icon @@ -1744,7 +1745,7 @@ PANGO_ELLIPSIZE_NONE - 18 + 9 False False @@ -1775,79 +1776,12 @@ True - 5 + 2 False True - - - True - True - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - GTK_SHADOW_NONE - GTK_CORNER_TOP_LEFT - - - - True - GTK_SHADOW_IN - - - - True - False - 0 - - - - True - True - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - GTK_SHADOW_IN - GTK_CORNER_TOP_LEFT - - - - True - True - False - False - True - GTK_JUSTIFY_LEFT - GTK_WRAP_WORD - True - 0 - 0 - 0 - 0 - 0 - 0 - - - - - - 0 - True - True - - - - - - - - - 18 - True - True - - - True @@ -1857,9 +1791,67 @@ + + + + True + True + False + + + + True + False + 0 + + + + 250 + True + False + 0 + + + + + + + 0 + True + True + + + + + + 20 + 250 + True + True + 0 + + + + + + + 0 + False + True + + + + + + + 0 + True + True + + - 0 + 6 False True diff --git a/spritz/src/spritz.py b/spritz/src/spritz.py index de0759c1f..2df050022 100644 --- a/spritz/src/spritz.py +++ b/spritz/src/spritz.py @@ -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)