0
+ − 1 #!/usr/bin/python
+ − 2 # -*- coding: utf-8 -*-
+ − 3
+ − 4 """
+ − 5 sortilege: a SAT frontend
57
+ − 6 Copyright (C) 2009, 2010 Jérôme Poisson (goffi@goffi.org)
0
+ − 7
+ − 8 This program is free software: you can redistribute it and/or modify
+ − 9 it under the terms of the GNU General Public License as published by
+ − 10 the Free Software Foundation, either version 3 of the License, or
+ − 11 (at your option) any later version.
+ − 12
+ − 13 This program is distributed in the hope that it will be useful,
+ − 14 but WITHOUT ANY WARRANTY; without even the implied warranty of
+ − 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ − 16 GNU General Public License for more details.
+ − 17
+ − 18 You should have received a copy of the GNU General Public License
+ − 19 along with this program. If not, see <http://www.gnu.org/licenses/>.
+ − 20 """
+ − 21
+ − 22
+ − 23 import curses
+ − 24 from curses import ascii
+ − 25 from window import Window
+ − 26
+ − 27 def C ( k ):
+ − 28 """return the value of Ctrl+key"""
+ − 29 return ord ( ascii . ctrl ( k ))
+ − 30
+ − 31 def A ( k ):
+ − 32 """return the value of Alt+key"""
+ − 33 return ord ( ascii . alt ( k ))
+ − 34
+ − 35 class EditBox ( Window ):
+ − 36 """This class manage the edition of text"""
+ − 37
+ − 38 def __init__ ( self , parent , header , code = "utf-8" ):
+ − 39 self . __header = header
+ − 40 self . __text = unicode ()
+ − 41 self . __curs_pos = 0
+ − 42 self . __buffer = str ()
+ − 43 self . __replace_mode = False
+ − 44 self . __parent = parent
+ − 45 self . __code = code
+ − 46
+ − 47 Window . __init__ ( self , self . __parent , 1 , self . __parent . getmaxyx ()[ 1 ], self . __parent . getmaxyx ()[ 0 ] - 1 , 0 , code = code )
+ − 48 self . update ()
+ − 49
+ − 50 def registerEnterCB ( self , CB ):
+ − 51 self . __enterCB = CB
+ − 52
+ − 53 def resizeAdapt ( self ):
+ − 54 """Adapt window size to self.__parent size.
+ − 55 Must be called when self.__parent is resized."""
+ − 56 self . resize ( 1 , self . __parent . getmaxyx ()[ 1 ], self . __parent . getmaxyx ()[ 0 ] - 1 , 0 )
+ − 57 self . update ()
+ − 58
+ − 59 def __getTextToPrint ( self ):
+ − 60 """return the text printed on the edit line"""
+ − 61 width = self . rWidth - len ( self . __header ) - 1
+ − 62 if self . __curs_pos < width :
+ − 63 begin = 0
+ − 64 end = width
+ − 65 else :
+ − 66 begin = self . __curs_pos - width
+ − 67 end = self . __curs_pos
+ − 68 return self . __header + self . __text [ begin : end ]
+ − 69
+ − 70 def update ( self ):
+ − 71 Window . update ( self )
+ − 72 text = self . __getTextToPrint ()
+ − 73 self . addYXStr ( 0 , 0 , text , limit = self . rWidth )
+ − 74
+ − 75 self . noutrefresh ()
+ − 76
+ − 77 def __dec_cur ( self ):
+ − 78 """move cursor on the left"""
+ − 79 if self . __curs_pos > 0 :
+ − 80 self . __curs_pos = self . __curs_pos - 1
+ − 81
+ − 82 def __inc_cur ( self ):
+ − 83 """move cursor on the right"""
+ − 84 if self . __curs_pos < len ( self . __text ):
+ − 85 self . __curs_pos = self . __curs_pos + 1
+ − 86
+ − 87 def move_cur ( self , x ):
+ − 88 pos = x + len ( self . __header )
+ − 89 if pos >= self . rWidth :
+ − 90 pos = self . rWidth - 1
+ − 91 self . move ( 0 , pos )
+ − 92
+ − 93 def clear_text ( self ):
+ − 94 """Clear the text of the edit box"""
+ − 95 self . __text = ""
+ − 96 self . __curs_pos = 0
+ − 97
+ − 98 def replace_cur ( self ):
+ − 99 """must be called earch time the cursor is moved"""
+ − 100 self . move_cur ( self . __curs_pos )
+ − 101 self . noutrefresh ()
+ − 102
+ − 103 def activate ( self , state = True ):
+ − 104 cursor_mode = 1 if state else 0
+ − 105 curses . curs_set ( cursor_mode )
+ − 106 Window . activate ( self , state )
+ − 107
+ − 108 def handleKey ( self , k ):
+ − 109 if ascii . isgraph ( k ) or ascii . isblank ( k ):
+ − 110 pacman = 0 if not self . __replace_mode else 1
+ − 111 self . __text = self . __text [: self . __curs_pos ] + chr ( k ) + self . __text [ self . __curs_pos + pacman :]
+ − 112 self . __curs_pos = self . __curs_pos + 1
+ − 113
+ − 114 elif k == ascii . NL :
+ − 115 try :
+ − 116 self . __enterCB ( self . __text )
+ − 117 except NameError :
+ − 118 pass # TODO: thrown an error here
+ − 119 self . clear_text ()
+ − 120
+ − 121 elif k == curses . KEY_BACKSPACE :
+ − 122 self . __text = self . __text [: self . __curs_pos - 1 ] + self . __text [ self . __curs_pos :]
+ − 123 self . __dec_cur ()
+ − 124
+ − 125 elif k == curses . KEY_DC :
+ − 126 self . __text = self . __text [: self . __curs_pos ] + self . __text [ self . __curs_pos + 1 :]
+ − 127
+ − 128 elif k == curses . KEY_IC :
+ − 129 self . __replace_mode = not self . __replace_mode
+ − 130
+ − 131 elif k == curses . KEY_LEFT :
+ − 132 self . __dec_cur ()
+ − 133
+ − 134 elif k == curses . KEY_RIGHT :
+ − 135 self . __inc_cur ()
+ − 136
+ − 137 elif k == curses . KEY_HOME or k == C ( 'a' ):
+ − 138 self . __curs_pos = 0
+ − 139
+ − 140 elif k == curses . KEY_END or k == C ( 'e' ):
+ − 141 self . __curs_pos = len ( self . __text )
+ − 142
+ − 143 elif k == C ( 'k' ):
+ − 144 self . __text = self . __text [: self . __curs_pos ]
+ − 145
+ − 146 elif k == C ( 'w' ):
+ − 147 before = self . __text [: self . __curs_pos ]
+ − 148 pos = before . rstrip () . rfind ( " " ) + 1
+ − 149 self . __text = before [: pos ] + self . __text [ self . __curs_pos :]
+ − 150 self . __curs_pos = pos
+ − 151
+ − 152 elif k > 255 :
+ − 153 self . __buffer = ""
+ − 154
+ − 155 else : ## FIXME: dangerous code, must be checked ! (specialy buffer overflow) ##
+ − 156 #We now manage unicode
+ − 157 self . __buffer = self . __buffer + chr ( k )
+ − 158 decoded = unicode ()
+ − 159 if len ( self . __buffer ) > 4 :
+ − 160 self . __buffer = ""
+ − 161 return
+ − 162 try :
+ − 163 decoded = self . __buffer . decode ( self . __code )
+ − 164 except UnicodeDecodeError , e :
+ − 165 if e . reason != "unexpected end of data" :
+ − 166 self . __buffer = ""
+ − 167 return
+ − 168 if len ( self . __buffer ) == 1 : ## FIXME: awful ! only for test !
+ − 169 self . __buffer = ""
+ − 170 return
+ − 171 self . __text = self . __text + decoded
+ − 172 self . __curs_pos = self . __curs_pos + 1
+ − 173 self . __buffer = ""
+ − 174
+ − 175 self . update ()
+ − 176