def __init__(self, context, file_path): self.__file_path = file_path self.__offset_in_file = 0 self.__file_size = os.stat(file_path).st_size file_buffer.init(128) file_buffer.open_file(file_path) self.__context = context self.__init_context(self.__context) self.__max_y, self.__max_x = self.__context.getmaxyx() self.__event_manager = EventManager('eventmanager', self) app_box = MailBox('application@eventmanager') listeners.application.attach_listeners(app_box, self) self.__event_manager.register_listeners(app_box.listeners) system_box = MailBox('system@eventmanager') listeners.system.attach_listeners(system_box, self) self.__event_manager.register_listeners(system_box.listeners) command_box = MailBox('command@eventmanager') listeners.commands.attach_listeners(command_box, self) self.__event_manager.register_listeners(command_box.listeners) self.__event_manager.boxes.extend([app_box, system_box, command_box]) self.__init_GUI() self.__event_manager.deactivate_all_listeners() self.__event_manager.activate_listeners_in_box(app_box.address) self.__event_manager.activate_listeners_in_box(system_box.address) self.go_to(0)
class Application: def __init__(self, context, file_path): self.__file_path = file_path self.__offset_in_file = 0 self.__file_size = os.stat(file_path).st_size file_buffer.init(128) file_buffer.open_file(file_path) self.__context = context self.__init_context(self.__context) self.__max_y, self.__max_x = self.__context.getmaxyx() self.__event_manager = EventManager('eventmanager', self) app_box = MailBox('application@eventmanager') listeners.application.attach_listeners(app_box, self) self.__event_manager.register_listeners(app_box.listeners) system_box = MailBox('system@eventmanager') listeners.system.attach_listeners(system_box, self) self.__event_manager.register_listeners(system_box.listeners) command_box = MailBox('command@eventmanager') listeners.commands.attach_listeners(command_box, self) self.__event_manager.register_listeners(command_box.listeners) self.__event_manager.boxes.extend([app_box, system_box, command_box]) self.__init_GUI() self.__event_manager.deactivate_all_listeners() self.__event_manager.activate_listeners_in_box(app_box.address) self.__event_manager.activate_listeners_in_box(system_box.address) self.go_to(0) def __init_GUI(self): curses.curs_set(0) self.address_block = AddressBlock(Rect(0, 1, 8, self.__max_y-2)) self.address_block.start_address = 0 self.address_block.color = 2 self.address_block.highlight = 3 self.address_block.highlight_inx = 0 busy_space = self.address_block.draw_zone.width ratio = (self.__max_x + 1 - busy_space) / 4 self.byte_grid = ByteGrid(Rect(busy_space + 1, 1, ratio*3, self.__max_y-2)) self.byte_grid.color = 2 self.byte_grid.highlight = 3 self.byte_grid.data = bytearray() self.byte_grid.cursor_position = (1, 1) self.byte_grid.autosize() busy_space += self.byte_grid.draw_zone.width + 1 self.address_block.step = self.byte_grid.col_count self.text_view = TextView(Rect(busy_space, 1, self.byte_grid.col_count, self.__max_y-2)) self.text_view.symbol_in_row = self.byte_grid.col_count self.text_view.color = 2 self.text_view.highlight_color = 3 self.status_line = StatusLine(Rect(0, 0, self.__max_x, 1)) self.status_line.file_name = os.path.basename(self.__file_path) self.status_line.offset = self.__offset_in_file self.status_line.file_size = self.__file_size self.status_line.color = 4 cmdline_box = MailBox('cmdline@eventmanager') self.command_line = CommandLine(Rect(0, self.__max_y-1, self.__max_x, 1), cmdline_box) self.command_line.attach_listeners(self) self.__event_manager.register_listeners(cmdline_box.listeners) self.__event_manager.boxes.append(cmdline_box) self.command_line.color = 5 def __init_context(self, context): if curses.has_colors(): curses.init_pair(1, curses.COLOR_YELLOW, curses.COLOR_BLUE) curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_BLUE) curses.init_pair(3, curses.COLOR_BLUE, curses.COLOR_WHITE) curses.init_pair(4, curses.COLOR_BLACK, curses.COLOR_CYAN) curses.init_pair(5, curses.COLOR_WHITE, curses.COLOR_BLACK) context.bkgdset(curses.color_pair(2)) def keyloop(self): self.__context.clear() self.resize() self.draw() self.__context.refresh() while True: key = self.__context.getch() em = self.__event_manager new_message = Message('null@{0}'.format(em.server_name), em.everyone_mail(), Event('key_press', {'key': key })) em.send(new_message) self.resize() self.draw() self.__context.refresh() def exit(self): file_buffer.close_file() curses.endwin() exit() @property def address_block(self): return self.__address_block @address_block.setter def address_block(self, widget): self.__address_block = widget @property def byte_grid(self): return self.__byte_grid @byte_grid.setter def byte_grid(self, widget): self.__byte_grid = widget @property def offset_in_file(self): return self.__offset_in_file @property def event_manager(self): return self.__event_manager def draw(self): self.status_line.draw(self.__context) self.address_block.draw(self.__context) self.byte_grid.draw(self.__context) self.text_view.draw(self.__context) self.command_line.draw(self.__context) def go_to(self, offset): "Позволяет перейти к произвольному байту в файле" if offset >= self.__file_size: return if offset < 0: offset = 0 self.__offset_in_file = offset data_size = self.byte_grid.data_size() if offset + data_size > self.__file_size: data_size = self.__file_size - offset data = [] for byte_offset in range(data_size): data.append(ord(file_buffer.get_byte(offset + byte_offset))) data = bytearray(data) self.byte_grid.data = data self.byte_grid.cursor_position = (0, 0) self.text_view.data = data self.text_view.highlight_index = 0 self.address_block.start_address = offset self.address_block.highlight_inx = 0 self.status_line.offset = offset def resize(self): self.__max_y, self.__max_x = self.__context.getmaxyx() (max_x, max_y) = self.size self.address_block.draw_zone = Rect(0, 1, 8, max_y-2) busy_space = self.address_block.draw_zone.width ratio = (max_x - busy_space) / 4 self.byte_grid.draw_zone = Rect(busy_space + 1, 1, ratio*3, max_y-2) self.byte_grid.autosize() busy_space += self.byte_grid.draw_zone.width + 1 self.address_block.step = self.byte_grid.col_count self.text_view.draw_zone = Rect(busy_space, 1, self.byte_grid.col_count, max_y-2) self.text_view.symbol_in_row = self.byte_grid.col_count self.status_line.draw_zone = Rect(0, 0, max_x, 1) self.command_line.draw_zone = Rect(0, max_y-1, max_x, 1) # При изменении размеров окна курсор активного байта # может оказаться в не валидной позиции cur_pos = self.byte_grid.cursor_position cur_offset = cur_pos[0] * self.byte_grid.col_count + cur_pos[1] if cur_offset > len(self.byte_grid.data): self.byte_grid.cursor_position = (0,0) self.address_block.highlight_inx = 0 self.text_view.highlight_index = 0 @property def size(self): return (self.__max_x, self.__max_y)
class Application: def __init__(self, context, file_path): self.__file_path = file_path self.__offset_in_file = 0 self.__file_size = os.stat(file_path).st_size file_buffer.init(128) file_buffer.open_file(file_path) self.__context = context self.__init_context(self.__context) self.__max_y, self.__max_x = self.__context.getmaxyx() self.__event_manager = EventManager('eventmanager', self) app_box = MailBox('application@eventmanager') listeners.application.attach_listeners(app_box, self) self.__event_manager.register_listeners(app_box.listeners) system_box = MailBox('system@eventmanager') listeners.system.attach_listeners(system_box, self) self.__event_manager.register_listeners(system_box.listeners) command_box = MailBox('command@eventmanager') listeners.commands.attach_listeners(command_box, self) self.__event_manager.register_listeners(command_box.listeners) self.__event_manager.boxes.extend([app_box, system_box, command_box]) self.__init_GUI() self.__event_manager.deactivate_all_listeners() self.__event_manager.activate_listeners_in_box(app_box.address) self.__event_manager.activate_listeners_in_box(system_box.address) self.go_to(0) def __init_GUI(self): curses.curs_set(0) self.address_block = AddressBlock(Rect(0, 1, 8, self.__max_y - 2)) self.address_block.start_address = 0 self.address_block.color = 2 self.address_block.highlight = 3 self.address_block.highlight_inx = 0 busy_space = self.address_block.draw_zone.width ratio = (self.__max_x + 1 - busy_space) / 4 self.byte_grid = ByteGrid( Rect(busy_space + 1, 1, ratio * 3, self.__max_y - 2)) self.byte_grid.color = 2 self.byte_grid.highlight = 3 self.byte_grid.data = bytearray() self.byte_grid.cursor_position = (1, 1) self.byte_grid.autosize() busy_space += self.byte_grid.draw_zone.width + 1 self.address_block.step = self.byte_grid.col_count self.text_view = TextView( Rect(busy_space, 1, self.byte_grid.col_count, self.__max_y - 2)) self.text_view.symbol_in_row = self.byte_grid.col_count self.text_view.color = 2 self.text_view.highlight_color = 3 self.status_line = StatusLine(Rect(0, 0, self.__max_x, 1)) self.status_line.file_name = os.path.basename(self.__file_path) self.status_line.offset = self.__offset_in_file self.status_line.file_size = self.__file_size self.status_line.color = 4 cmdline_box = MailBox('cmdline@eventmanager') self.command_line = CommandLine( Rect(0, self.__max_y - 1, self.__max_x, 1), cmdline_box) self.command_line.attach_listeners(self) self.__event_manager.register_listeners(cmdline_box.listeners) self.__event_manager.boxes.append(cmdline_box) self.command_line.color = 5 def __init_context(self, context): if curses.has_colors(): curses.init_pair(1, curses.COLOR_YELLOW, curses.COLOR_BLUE) curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_BLUE) curses.init_pair(3, curses.COLOR_BLUE, curses.COLOR_WHITE) curses.init_pair(4, curses.COLOR_BLACK, curses.COLOR_CYAN) curses.init_pair(5, curses.COLOR_WHITE, curses.COLOR_BLACK) context.bkgdset(curses.color_pair(2)) def keyloop(self): self.__context.clear() self.resize() self.draw() self.__context.refresh() while True: key = self.__context.getch() em = self.__event_manager new_message = Message('null@{0}'.format(em.server_name), em.everyone_mail(), Event('key_press', {'key': key})) em.send(new_message) self.resize() self.draw() self.__context.refresh() def exit(self): file_buffer.close_file() curses.endwin() exit() @property def address_block(self): return self.__address_block @address_block.setter def address_block(self, widget): self.__address_block = widget @property def byte_grid(self): return self.__byte_grid @byte_grid.setter def byte_grid(self, widget): self.__byte_grid = widget @property def offset_in_file(self): return self.__offset_in_file @property def event_manager(self): return self.__event_manager def draw(self): self.status_line.draw(self.__context) self.address_block.draw(self.__context) self.byte_grid.draw(self.__context) self.text_view.draw(self.__context) self.command_line.draw(self.__context) def go_to(self, offset): "Позволяет перейти к произвольному байту в файле" if offset >= self.__file_size: return if offset < 0: offset = 0 self.__offset_in_file = offset data_size = self.byte_grid.data_size() if offset + data_size > self.__file_size: data_size = self.__file_size - offset data = [] for byte_offset in range(data_size): data.append(ord(file_buffer.get_byte(offset + byte_offset))) data = bytearray(data) self.byte_grid.data = data self.byte_grid.cursor_position = (0, 0) self.text_view.data = data self.text_view.highlight_index = 0 self.address_block.start_address = offset self.address_block.highlight_inx = 0 self.status_line.offset = offset def resize(self): self.__max_y, self.__max_x = self.__context.getmaxyx() (max_x, max_y) = self.size self.address_block.draw_zone = Rect(0, 1, 8, max_y - 2) busy_space = self.address_block.draw_zone.width ratio = (max_x - busy_space) / 4 self.byte_grid.draw_zone = Rect(busy_space + 1, 1, ratio * 3, max_y - 2) self.byte_grid.autosize() busy_space += self.byte_grid.draw_zone.width + 1 self.address_block.step = self.byte_grid.col_count self.text_view.draw_zone = Rect(busy_space, 1, self.byte_grid.col_count, max_y - 2) self.text_view.symbol_in_row = self.byte_grid.col_count self.status_line.draw_zone = Rect(0, 0, max_x, 1) self.command_line.draw_zone = Rect(0, max_y - 1, max_x, 1) # При изменении размеров окна курсор активного байта # может оказаться в не валидной позиции cur_pos = self.byte_grid.cursor_position cur_offset = cur_pos[0] * self.byte_grid.col_count + cur_pos[1] if cur_offset > len(self.byte_grid.data): self.byte_grid.cursor_position = (0, 0) self.address_block.highlight_inx = 0 self.text_view.highlight_index = 0 @property def size(self): return (self.__max_x, self.__max_y)