#!/usr/bin/env python/
import sys
import string
import time
import struct
import curses
import curses.ascii
import curses.wrapper
INPUT_TIMEOUT= 10
STORED_SCREENS= 2
class MyWin:
def __init__( self, rows, cols, y, x ):
self.y= y
self.x= x
self.rows= rows
self.cols= cols
self.w= curses.newwin( rows, cols, y, x )
#self.w.bkgdset( 0, curses.COLOR_YELLOW )
self.w.scrollok(1)
def resize( self, sizeY, sizeX, y, x ):
self.w= curses.newwin( sizeY, sizeX, y, x )
self.x= x
self.y= y
self.rows= sizeY
self.cols= sizeX
self.w.scrollok(1)
def addch( self, char ):
self.w.addch( char )
def addstr( self, text, attr= None ):
if attr:
self.w.addstr( text, attr )
else:
self.w.addstr( text )
def erase( self ):
self.w.erase()
def refresh( self ):
self.w.refresh()
class MyScrollWin(MyWin):
def __init__( self, rows, cols, y, x ):
MyWin.__init__( self, rows, cols, y, x )
self.pRows= rows * STORED_SCREENS
self.p= curses.newpad( self.pRows, cols )
self.p.scrollok(1)
self.scroll= 0
self.text= []
def addch( self, char ):
self.p.addch( char )
def addstr( self, text, attr= None ):
self.text.append( (text, attr) )
#print >>sys.stderr, 'paso'
try:
if attr:
self.p.addstr( text, attr )
else:
self.p.addstr( text )
except curses.error, e:
#print >>sys.stderr, 'UOP', e
pass
(padY, padX)= self.p.getyx()
(scrY, scrX)= self.p.getmaxyx()
#print >>sys.stderr, 'pady= ', padY
#print >>sys.stderr, 'scrY= ', scrY
if padY >= (scrY - 1):
self.pRows*= 2
self.p= curses.newpad( self.pRows, scrX )
self.redraw()
def dump( self, file ):
for elem in self.text:
file.write( elem[0] )
file.close()
def resize( self, sizeY, sizeX, y, x ):
#print >>sys.stderr, 'newpad: sizeY= %d, sizeX= %d' % ( sizeY * STORED_SCREENS, sizeX )
#print >>sys.stderr, 'resizePad: sizeY= %d, sizeX= %d' % ( sizeY, sizeX )
self.p= curses.newpad( self.pRows, sizeX )
self.x= x
self.y= y
self.rows= sizeY
self.cols= sizeX
#print >>sys.stderr, 'text=', self.text
self.redraw()
def refresh( self ):
(y, x)= self.p.getyx()
firstRow= y - (self.rows - 1)
if (firstRow + self.scroll) < 0:
firstRow= 0
#print >>sys.stderr, str(self), firstRow + self.scroll, self.x, self.y, self.x , self.y+self.rows-1, self.cols-1
#(scrY, scrX)= curses.getmaxyx()
#rows= self.rows
#cols= self.cols
#if scrY < rows:
#rows= scrY
#if scrX < cols:
#cols= scrX
#print >>sys.stderr, 'prefresh: pminrow= %d, pmincol= %d, sminrow= %d, smincol= %d, smaxrow= %d, smaxcol= %d' % \
#(firstRow + self.scroll, 0, self.y, 0 \
#, self.y+self.rows-1, self.cols-1)
#print >>sys.stderr, 'self.y= %d' % (self.y)
#print >>sys.stderr, 'self.rows= %d' % (self.rows)
sizeY= self.y+self.rows-1
(padY, padX)= self.p.getyx()
#print >>sys.stderr, 'sizeY= %d, padY= %d' % (sizeY, padY)
try:
self.p.refresh(firstRow + self.scroll, 0, self.y, 0
, self.y+self.rows-1, self.cols-1)
except curses.error:
pass
#self.p.refresh(firstRow + self.scroll, self.x, self.y, self.x
#, self.y+self.rows-1, self.cols-1)
def redraw( self ):
self.p.erase()
for elem in self.text:
#print >>sys.stderr, 'elem=', elem
if elem[1] == None:
self.p.addstr( elem[0] )
else:
self.p.addstr( elem[0], elem[1] )
def attrset( self, color ):
self.p.attrset( color )
def toTop( self ):
(y, x)= self.p.getyx()
self.scroll= -(y - self.rows +1)
def toBottom( self ):
self.scroll= 0
def line( self ):
(y, x)= self.p.getyx()
(maxY, maxX)= self.p.getmaxyx()
#print >>sys.stderr, '%d %d - ' % (x, y)
#print >>sys.stderr, '%d %d' % (maxX, maxY)
self.p.hline( y, x, curses.ACS_HLINE, maxX - x )
def scrollUp( self, lines= 1 ):
(y, x)= self.p.getyx()
firstRow= y - self.rows
if (firstRow + self.scroll - lines ) >= 0:
self.scroll-= lines
else:
self.scroll= -(y - self.rows +1)
self.refresh()
def getWin( self ):
return self.w
def erase( self ):
self.text= []
self.p.erase()
#self.refresh()
def scrollDown( self, lines= 1 ):
(y, x)= self.p.getyx()
if (self.scroll + lines) < 0:
self.scroll+= lines
else:
self.scroll= 0
self.refresh()
class MyInputWin(MyScrollWin):
def __init__( self, rows, cols, y, x ):
MyScrollWin.__init__( self, rows, cols, y, x )
self.p.timeout( INPUT_TIMEOUT )
self.p.keypad(1)
self.attr= None
#print >>sys.stderr, str(self), self.rows, self.cols, self.y, self.x
self.hidden= 0
def setAttr( self, attr ):
self.attr= attr
def resize( self, sizeY, sizeX, y, x ):
MyScrollWin.resize( self, sizeY, sizeX, y, x )
self.p.timeout( INPUT_TIMEOUT )
self.p.keypad(1)
def getLine( self, handleFunc= None, idleFunc= None, hidden= 0 ):
#curses.noecho()
self.p.immedok(0)
#l= open('/tmp/jeje', 'w')
self.buff= ''
self.pos= 0
self.hidden= hidden
while 1:
c= self.p.getch()
#l.write( str(c) )
#print >>sys.stderr, 'leido= %s\n' % str(c)
if c == curses.ascii.NL:
break
elif c != curses.ERR:
#print >>sys.stderr, 'en el elif'
if not handleFunc( c ):
#print >>sys.stderr, 'en if'
if self.pos < len(self.buff):
self.buff= self.buff[:self.pos] + chr(c) \
+ self.buff[self.pos:]
self.erase()
#print >>sys.stderr, 'lala= %s' % self.buff
if not self.hidden:
#print >>sys.stderr, 'en if2'
if self.attr:
self.p.addstr( self.buff, self.attr )
else:
self.p.addstr( self.buff )
self.cursPos(self.pos+1)
self.refresh()
else:
self.buff+= chr(c)
if not self.hidden:
#print >>sys.stderr, 'self.attr'
if self.attr:
self.p.addch( c, self.attr )
else:
self.p.addch( c )
#print >>sys.stderr, 'getLine=', self.p.getyx()
self.refresh()
self.pos += 1
else:
if idleFunc != None:
idleFunc()
else:
curses.napms( 1 )
self.hidden= 0
return self.buff
#def refresh( self ):
#(y, x)= self.p.getyx()
#firstRow= y - self.rows
#if (firstRow + self.scroll) < 0:
#firstRow= 0
#print >>sys.stderr, firstRow + self.scroll, 0, self.y, self.x, self.y+self.rows-1, self.cols-1
#self.p.refresh(firstRow + self.scroll, 0, self.y+1, self.x, self.rows-1
#, self.cols-1)
#self.p.refresh(0, 0, 23, 0, 24, 79)
def delChar( self ):
if self.pos >= 1:
self.pos-= 1
self.buff= self.buff[:self.pos] + self.buff[self.pos+1:]
if not self.hidden:
self.p.erase()
if self.attr:
self.p.addstr( self.buff, self.attr )
else:
self.p.addstr( self.buff )
self.cursPos( self.pos )
def suprChar( self ):
self.buff= self.buff[:self.pos] + self.buff[self.pos+1:]
if not self.hidden:
self.p.erase()
if self.attr:
self.p.addstr( self.buff, self.attr )
else:
self.p.addstr( self.buff )
self.cursPos( self.pos )
def cursPos( self, pos ):
y= pos/self.cols
x= pos%self.cols
#print >>sys.stderr, 'cursor=', self.p.getyx()
self.p.move( y, x )
if y >= self.rows:
y= self.rows - 1
#print >>sys.stderr, '/= %d, %%=%d' % (pos/self.cols, pos%self.cols)
#print >>sys.stderr, 'move=', y, x
self.w.move( y, x )
def cursBegin( self ):
self.pos= 0
self.cursPos( self.pos )
def cursEnd( self ):
self.pos= len( self.buff )
self.cursPos( self.pos )
def cursBack( self ):
if self.pos >= 1:
self.pos-= 1
self.cursPos( self.pos )
def cursForward( self ):
if self.pos < len(self.buff):
self.pos+= 1
self.cursPos( self.pos )
def addstr( self, text ):
self.buff= text
self.pos= len( text )
self.p.addstr( text )
class MyWinStack:
def __init__( self, rows, cols, y, x ):
self.y= y
self.x= x
self.rows= rows
self.cols= cols
#w= MyScrollWin( rows, cols, y, x )
self.wins= {}
def resize( self, sizeY, sizeX, y, x ):
self.y= y
self.x= x
self.rows= sizeY
self.cols= sizeX
for win in self.wins.values():
win.resize( sizeY, sizeX, y, x )
def dump( self, chat, file ):
self.wins[chat].dump( file )
def newWin( self, chat ):
w = MyScrollWin( self.rows, self.cols, self.y, self.x )
self.wins[chat]= w
# Looks for a window which has a chat with only the user 'user'
# returns the old chat
def reuseWindow( self, newChat ):
if len(newChat.users) != 1:
return None
user = newChat.listUsers()[0]
for chat in self.wins.keys():
if (user in chat.listUsers()) and len(chat.listUsers())==1:
self.replaceChat(chat, newChat)
return chat
return None
def replaceChat( self, oldChat, newChat ):
self.wins[newChat]= self.wins[oldChat]
self.delWin( oldChat )
#print >>sys.stderr, 'self.wins: ', self.wins
def hasWin( self, chat ):
return self.wins.has_key( chat )
def show( self, chat ):
w= self.wins[chat]
w.refresh()
def delWin( self, chat ):
if self.wins.has_key(chat):
del( self.wins[chat] )
def erase( self, chat ):
self.wins[chat].erase()
def addstr( self, chat, text, attr= None ):
if self.wins.has_key( chat ):
w= self.wins[chat]
try:
w.addstr( text, attr )
except curses.error:
self.addstr( None, _('Detected ERROR when displaying: ') + text )
def scrollUp( self, chat, lines= 1 ):
w= self.wins[chat]
w.scrollUp( lines )
def scrollDown( self, chat, lines= 1 ):
w= self.wins[chat]
w.scrollDown( lines )
def toTop( self, chat ):
self.wins[chat].toTop()
def toBottom( self, chat ):
self.wins[chat].toBottom()
def redraw( self ):
for w in self.wins.values():
w.redraw()
def refresh( self, chat ):
if self.wins.has_key(chat):
w= self.wins[chat]
w.refresh()
def dummy( c ):
return 1
def main(a):
#curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK)
#curses.meta(1)
v1= MyWin( 22, 80, 0, 0 )
v2= MyInputWin(2, 80, 22, 0)
#v1.hline(21, 0, curses.ACS_HLINE, 80)
#p1.refresh(0, 0, 0, 0, 22, 80)
#p2.refresh(0, 0, 22, 0, 24, 80)
v1.refresh()
v2.refresh()
while 1:
st= v2.getLine( dummy, hidden= 1 )
v1.addstr( st )
v1.refresh()
#p1.refresh(0, 0, 0, 0, 22, 80)
#p2.refresh(0, 0, 22, 0, 24, 80)
#raw_input()
if __name__ == '__main__':
curses.wrapper(main)
|