def set_color(self): cept_data = bytearray() if self.fgcolor is not None: cept_data.extend(Cept.set_fg_color(self.fgcolor)) if self.bgcolor is not None: cept_data.extend(Cept.set_bg_color(self.bgcolor)) return cept_data
def edit(self, skip_entry=False): start = True dct = False prefix = bytearray() inject_char = None while True: if start and not skip_entry: start = False self.print_hint() cept_data = bytearray() self.__y = 0 if self.height > 1 or self.cursor_home: cept_data.extend(Cept.set_cursor(self.line, self.column)) self.__x = 0 else: cept_data.extend( Cept.set_cursor(self.line, self.column + len(self.string))) self.__x = len(self.string) if self.fgcolor: cept_data.extend(Cept.set_fg_color(self.fgcolor)) if self.bgcolor: cept_data.extend(Cept.set_bg_color(self.bgcolor)) cept_data.extend(Cept.show_cursor()) sys.stdout.buffer.write(cept_data) sys.stdout.flush() if skip_entry: sys.stderr.write("skipping\n") break if inject_char: c = inject_char inject_char = None else: c = Util.readchar() sys.stderr.write("In: " + hex(ord(c)) + "\n") if self.command_mode and ord( c) == Cept.ini() and self.string[-1:] == chr(Cept.ini()): # exit command mode, tell parent to clear return (None, False) c2 = Cept.code_to_str(prefix + bytes([ord(c)])) if c2 is None: # sequence not complete prefix.append(ord(c)) continue prefix = bytearray() if c2 == "": # we couldn't decode it continue c = c2 # if c < 0x20 # c is a CEPT control code # if c >= 0x20 # c is Unicode if ord(c) < 0x20: #and ord(c) != Cept.ini(): prefix = bytearray() if ord(c) == Cept.ini(): if not self.command_mode: is_editor_code = False sys.stderr.write("entering command mode\n") editor = Editor() editor.line = 24 editor.column = 1 editor.height = 1 editor.width = 20 editor.string = chr(Cept.ini()) editor.command_mode = True editor.clear_line = True editor.echo_ter = True editor.draw() (val, dct) = editor.edit() sys.stderr.write("exited command mode\n") if val is None: # "**" in command mode self.string = "" self.draw() else: Editor.debug_print(val) if val.startswith(chr(Cept.ini()) + "02") and len(val) == 4: # editor codes *021# etc. is_editor_code = True code = int(val[3:]) map = { 1: "\r", # CR 2: "\x0b", # UP 4: "\x08", # LEFT 6: "\x09", # RIGHT 8: "\n", # DOWN 9: "\x1a" # DCT } c = map.get(code) if c is not None: inject_char = c else: sys.stderr.write( "ignoring invalid editor code\n") else: # global code if not self.no_navigation or val == chr( Cept.ini()) + "00" or val == chr( Cept.ini()) + "09": return (val, False) sys.stderr.write("ignoring navigation\n") start = True continue elif ord(c) == Cept.ter(): if self.echo_ter: sys.stdout.write("#") sys.stdout.flush() break elif ord(c) == Cept.dct(): dct = True break self.insert_control_character(c) else: # ord(c) >= 0x20 character_legal = True string_legal = False # CEPT doesn't have a concept of backspace, so the backspace key # sends the sequence CSR_LEFT, SPACE, CSR_LEFT. It is very tricky # to detect this properly, so we will just allow spaces in # "number" and "alpha" input fields. if self.type == "number" and not c.isdigit() and not c == " ": character_legal = False elif self.type == "alpha" and not c.isalpha() and not c == " ": character_legal = False elif self.legal_values: s = self.try_insert_character(c).rstrip() character_legal = False for legal_input in self.legal_values: if s == legal_input: character_legal = True string_legal = True # sys.stderr.write("string_legal!\n") break elif legal_input.startswith(s): character_legal = True # sys.stderr.write("character_legal!\n") break if character_legal or self.end_on_illegal_character: if self.insert_character(c): if self.type == "password": sys.stdout.write("*") else: sys.stdout.buffer.write(Cept.from_str(c)) sys.stdout.flush() if not character_legal and self.end_on_illegal_character: break if string_legal and self.end_on_legal_string: break # sys.stderr.write("self.__data:\n" + pprint.pformat(self.__data) + "\n") # sys.stderr.write("self.string:\n" + pprint.pformat(self.string) + "\n") return (self.string, dct)