# HG changeset patch # User Björn Ricks # Date 1365183899 -7200 # Node ID a1b00ffea2691d11bb82ac522d3c61d0f6384724 # Parent 921e98f9aa878955e63c7d84bae3cd77030de82d Use handle_input instead of keypress to act on user input in States diff -r 921e98f9aa87 -r a1b00ffea269 getan/states.py --- a/getan/states.py Fri Apr 05 19:34:23 2013 +0200 +++ b/getan/states.py Fri Apr 05 19:44:59 2013 +0200 @@ -66,80 +66,76 @@ class ProjectState(State): - def keypress(self, key): + + def handle_input(self, input): keys = self.config.get_keybinding() - logger.debug("ProjectState: handle key '%r'" % key) - if keys.get_switch_time_mode() in key: + logger.debug("ProjectState: handle input '%r'" % input) + if keys.get_switch_time_mode() in input: self.view.switch_time_mode() - return self + return True - if keys.get_switch_project_order() in key: + if keys.get_switch_project_order() in input: self.view.switch_project_order() - return self + return True - if keys.get_switch_lists() in key: + if keys.get_switch_lists() in input: if not self.controller.entries_view.rows: - return self - self.controller.entries_view.focused = 0 - self.controller.entries_view.update_focus(0) - return DefaultEntryListState(self, self.controller, - self.controller.entries_view) - - if keys.get_entry_up() in key: - return self.up() - - if keys.get_entry_down() in key: - return self.down() - - def up(self): - self.view.up() - self.controller.update_entries(self.view.item_in_focus()) - return self - - def down(self): - self.view.down() - self.controller.update_entries(self.view.item_in_focus()) - return self + return True + new_state = DefaultEntryListState(self, self.controller, + self.controller.entries_view) + self.set_next_state(new_state) + self.controller.view.set_focus(1) + self.controller.entries_view.set_focus(0) + return True class PausedProjectsState(ProjectState): + messages = { 'choose_proj': _('Choose a project: '), } - def keypress(self, key): + def handle_input(self, key): logger.debug("PausedProjectsState: handle key '%r'" % key) keys = self.config.get_keybinding() - ret = super(PausedProjectsState, self).keypress(key) + ret = super(PausedProjectsState, self).handle_input(key) if ret: - return ret + return True if keys.get_enter() in key: return self.select() if keys.get_insert() in key: - return AddProjectKeyState(self.controller, self.view) + state = AddProjectKeyState(self.controller, self.view) + self.set_next_state(state) + return True if keys.get_escape() in key: - return ExitState(self.controller, self.view) + state = ExitState(self.controller, self.view) + self.set_next_state(state) + return True if keys.get_project_edit() in key: proj = self.view.item_in_focus() if not proj: - return self - return ProjectEditKeyState(self.controller, self.view, proj) + return True + state = ProjectEditKeyState(self.controller, self.view, proj) + self.set_next_state(state) + return True else: if len(key) > 0 and len(key[0]) == 1: - select_proj = SelectProjectState(self.controller, self.view) - return select_proj.keypress(key) - return self - + state = SelectProjectState(self.controller, self.view) + self.set_next_state(state) + return state.handle_input(key) + return False def select(self): proj = self.view.item_in_focus() self.controller.start_project(proj) - return RunningProjectsState(self.controller, self.view, proj) + state = RunningProjectsState(self.controller, self.view, proj) + self.set_next_state(state) + return True class SelectProjectState(State): @@ -166,20 +162,22 @@ self.controller.start_project(self.view.item_in_focus()) self.controller.update_entries( self.view.item_in_focus()) - return RunningProjectsState(self.controller, self.view, proj) - return self + self.set_next_state(RunningProjectsState(self.controller, self.view, + proj)) + return True - def keypress(self, key): + def handle_input(self, key): keys = self.config.get_keybinding() if keys.get_escape() in key: self.reset() - return PausedProjectsState(self.controller, self.view) + self.set_next_state(PausedProjectsState(self.controller, self.view)) + return True if 'backspace' in key: if len(self.proj_keys) > 0: self.proj_keys = self.proj_keys[:-1] self.set_footer_text() - return self + return True if keys.get_enter() in key: return self.select_project() @@ -194,10 +192,11 @@ if num == 1: # run project directly return self.select_project() - return self + return False class ExitState(ProjectState): + messages = { 'quit' : _(" Really quit? (y/n)"), 'choose': _(" Choose a project:") @@ -207,23 +206,26 @@ super(ExitState, self).__init__(controller, view) self.controller.view.set_footer_text(self.msg('quit'), 'question') - def keypress(self, key): + def handle_input(self, key): logger.debug("ExitState: handle key '%r'" % key) - ret = super(ExitState, self).keypress(key) + ret = super(ExitState, self).handle_input(key) if ret: return ret if 'y' in key or 'Y' in key: self.controller.exit() + return True if 'n' in key or 'N' in key: self.controller.view.set_footer_text(self.msg('choose'), 'question') - return PausedProjectsState(self.controller, self.view) + self.set_next_state(PausedProjectsState(self.controller, self.view)) + return True - return self + return False class RunningProjectsState(ProjectState): + messages = { 'description': _("Enter a description: "), 'add_time' : _("Enter time to add [min]: "), @@ -245,8 +247,10 @@ def handle_signal(self, signum, frame): proj = self.project keys = self.config.get_keybinding() + if not proj: return + if not self.break_start: self.controller.view.set_footer_text(self.msg('running') % (human_time(self.sec), @@ -265,10 +269,10 @@ signal.signal(signal.SIGALRM, self.handle_signal) signal.alarm(1) - def keypress(self, key): + def handle_input(self, key): logger.debug("RunningProjectsState: handle key '%r'" % key) keys = self.config.get_keybinding() - ret = super(RunningProjectsState, self).keypress(key) + ret = super(RunningProjectsState, self).handle_input(key) if ret: return ret @@ -278,17 +282,20 @@ self.view.set_footer_text(self.msg('add_time'), 'question', 1) self.view.frame.set_focus('footer') - return AddTimeState(self.controller, self.view, self) + self.set_next_state(AddTimeState(self.controller, self.view, self)) + return True + if keys.get_subtract_time() in key: self.view.set_footer_text(self.msg('min_time'), 'question', 1) self.view.frame.set_focus('footer') - return SubtractTimeState(self.controller, self.view, self) + self.set_next_state(SubtractTimeState(self.controller, self.view, + self)) + return True if keys.get_project_pause() in key: if not self.break_start: self.break_start = datetime.now() - return self else: self.view._total_time() proj = self.project @@ -297,7 +304,8 @@ self.break_start = None signal.signal(signal.SIGALRM, self.handle_signal) signal.alarm(1) - return self + return True + return False def stop(self): signal.alarm(0) @@ -307,9 +315,9 @@ if proj: proj.start += datetime.now() - self.break_start self.controller.view.set_footer_text(self.msg('description'),'question',1) self.controller.view.get_frame().set_focus('footer') - return DescriptionProjectsState( - self.controller, self.view, self, - self.controller.view.get_frame().get_footer()) + self.set_next_state(DescriptionProjectsState(self.controller, self.view, + self, self.controller.view.get_frame().get_footer())) + return True class HandleUserInputState(State): @@ -318,7 +326,7 @@ self.state = state self.footer = footer - def keypress(self, key): + def handle_input(self, key): logger.debug("HandleUserInputState: handle key '%r'" % key) pos = self.footer.edit_pos keys = self.config.get_keybinding() @@ -329,27 +337,32 @@ return self.enter() elif 'left' in key: self.footer.set_edit_pos(pos-1) + return True elif 'right' in key: self.footer.set_edit_pos(pos+1) + return True elif 'backspace' in key: text = self.footer.edit_text self.footer.set_edit_text( '%s%s' % (text[0:pos-1], text[pos:len(text)])) self.footer.set_edit_pos(pos-1) + return True elif 'delete' in key: text = self.footer.edit_text self.footer.set_edit_text( '%s%s' % (text[0:pos], text[pos+1:len(text)])) self.footer.set_edit_pos(pos) + return True elif len(key) >= 1 and len(key[0]) == 1: return self.insert(key) - return self + return False def enter(self): raise Exception("Not implemented") def exit(self): - return self.state + self.set_next_state(self.state) + return True def insert(self, key): logger.debug("Enter key: %r" % key) @@ -360,7 +373,7 @@ if not isinstance(text, unicode): text = unicode(text, locale.getpreferredencoding()) self.footer.insert_text(text) - return self + return True class BaseTimeState(HandleUserInputState): @@ -371,7 +384,7 @@ def exit(self): self.view._total_time() - return self.state + return super(BaseTimeState, self).exit() def insert(self, key): if key[0] in ['0','1','2','3','4','5','6','7','8','9']: @@ -379,7 +392,7 @@ else: logger.debug("BaseTimeState: invalid character for "\ "adding/subtracting time: '%r'" % key) - return self + return True class AddTimeState(BaseTimeState): @@ -391,7 +404,8 @@ logger.info("AddTimeState: add %d minutes to project '%s'" % (minutes, project.desc)) self.view._total_time() - return self.state + self.set_next_state(self.state) + return True class SubtractTimeState(BaseTimeState): @@ -407,7 +421,8 @@ logger.info("SubtractTimeState: subtract %d minutes from project '%s'" % (minutes, project.desc)) self.view._total_time() - return self.state + self.set_next_state(self.state) + return True class DescriptionProjectsState(HandleUserInputState): @@ -421,7 +436,8 @@ return self self.controller.stop_project(text) self.controller.view.set_footer_text(self.msg('choose_proj'), 'question') - return PausedProjectsState(self.controller, self.view) + self.set_next_state(PausedProjectsState(self.controller, self.view)) + return True def exit(self): project = self.view.item_in_focus() @@ -430,7 +446,7 @@ self.state.sec = time signal.signal(signal.SIGALRM, self.state.handle_signal) signal.alarm(1) - return self.state + return super(DescriptionProjectsState, self).exit() class EntryListState(State): @@ -438,31 +454,22 @@ super(EntryListState, self).__init__(controller, view) self.projectlist_state = state - def keypress(self, key): + def handle_input(self, key): logger.debug("EntryListState: pressed key '%r'" % key) keys = self.config.get_keybinding() if keys.get_switch_lists() in key: self.view.clear() - return self.projectlist_state - if keys.get_entry_up() in key: - return self.up() - if keys.get_entry_down() in key: - return self.down() + self.set_next_state(self.projectlist_state) + self.controller.view.set_focus(0) + return True + if keys.get_enter() in key: return self.select() - return None - - def up(self): - self.view.up() - return self - - def down(self): - self.view.down() - return self + return False def select(self): self.view.select() - return self + return True def renew_focus(self): e_len = self.view.row_count() @@ -474,34 +481,43 @@ class DefaultEntryListState(EntryListState): - def keypress(self, key): - ret = super(DefaultEntryListState, self).keypress(key) + + def handle_input(self, key): + logger.info("Handling DefaultEntryListState input") + ret = super(DefaultEntryListState, self).handle_input(key) if ret: return ret keys = self.config.get_keybinding() if keys.get_escape() in key: self.view.clear() - return self.projectlist_state + self.set_next_state(self.projectlist_state) + return True if keys.get_entry_delete() in key: if self.view.selection: - return DeleteEntryState(self.projectlist_state, - self.controller, self.view) + self.set_next_state(DeleteEntryState(self.projectlist_state, + self.controller, self.view)) else: entry = self.view.item_in_focus() - return DeleteEntryState(self.projectlist_state, - self.controller, self.view, [entry]) + self.set_next_state(DeleteEntryState(self.projectlist_state, + self.controller, self.view, [entry])) + return True + if keys.get_entry_move() in key: if self.view.selection: - return MoveEntryState(self.projectlist_state, - self.controller, self.view) + self.set_next_state(MoveEntryState(self.projectlist_state, + self.controller, self.view)) + return True + if keys.get_entry_edit() in key: entry = self.view.item_in_focus() if entry: - return EditEntryState(self.projectlist_state, - self.controller, self.view, entry) - return self + self.set_next_state(EditEntryState(self.projectlist_state, + self.controller, self.view, entry)) + return True + + return False class DeleteEntryState(EntryListState): @@ -516,21 +532,23 @@ if not self.entries: self.entries = [x.item for x in self.view.selection] - def keypress(self, key): + def handle_input(self, key): if 'y' in key: if self.entries: self.controller.delete_entries(self.entries) self.renew_focus() self.view.set_footer_text("", 'entry_footer') - return DefaultEntryListState(self.projectlist_state, - self.controller, self.view) + self.set_next_state(DefaultEntryListState(self.projectlist_state, + self.controller, self.view)) + return True if 'n' in key: self.view.set_footer_text("", 'entry_footer') - return DefaultEntryListState(self.projectlist_state, - self.controller, self.view) + self.set_next_state(DefaultEntryListState(self.projectlist_state, + self.controller, self.view)) + return True - return self + return False class MoveEntryState(EntryListState): @@ -567,7 +585,7 @@ self.view.set_footer_text(self.msg('really'), 'question') - def keypress(self, key): + def handle_input(self, key): keys = self.config.get_keybinding() if 'y' in key and self.proj: logger.debug("MoveEntryState: move selected entries.") @@ -575,28 +593,32 @@ self.renew_focus() self.view.set_footer_text('', 'entry_footer') self.proj = None - return DefaultEntryListState(self.projectlist_state, - self.controller, self.view) + self.set_next_state(DefaultEntryListState(self.projectlist_state, + self.controller, self.view)) + return True if 'n' in key and self.proj: self.view.set_footer_text('', 'entry_footer') self.reset_project_footer() - return DefaultEntryListState(self.projectlist_state, - self.controller, self.view) + self.set_next_state(DefaultEntryListState(self.projectlist_state, + self.controller, self.view)) + return True if keys.get_escape() in key: self.view.set_footer_text('', 'entry_footer') self.reset_project_footer() - return DefaultEntryListState(self.projectlist_state, - self.controller, self.view) + self.set_next_state(DefaultEntryListState(self.projectlist_state, + self.controller, self.view)) + return True if 'backspace' in key: if len(self.proj_keys) > 0: self.proj_keys = self.proj_keys[:-1] self.set_project_footer() - return self + return True if keys.get_enter() in key and self.proj is None: self.select_project() + return True if len(key) > 0 and len(key[0]) == 1 and self.proj is None: proj_key = self.proj_keys + key[0] @@ -606,8 +628,9 @@ self.set_project_footer() if num == 1: self.select_project() + return True - return self + return False class AlterProjectState(HandleUserInputState): @@ -622,7 +645,8 @@ def exit(self): self.controller.view.set_footer_text(self.msg('choose_proj'), 'question') - return PausedProjectsState(self.controller, self.view) + self.set_next_state(PausedProjectsState(self.controller, self.view)) + return True class AddProjectKeyState(AlterProjectState): @@ -641,8 +665,10 @@ def enter(self): key = self.footer.get_edit_text() if key == '': - return self - return AddProjectDescriptionState(self.controller, self.view, key) + return True + self.set_next_state(AddProjectDescriptionState(self.controller, + self.view, key)) + return True class AddProjectDescriptionState(AlterProjectState): @@ -664,7 +690,8 @@ return self self.controller.add_project(self.key, description) self.controller.view.set_footer_text(self.msg('choose_proj'), 'question') - return PausedProjectsState(self.controller, self.view) + self.set_next_state(PausedProjectsState(self.controller, self.view)) + return True class EditEntryState(HandleUserInputState): @@ -696,7 +723,9 @@ def exit(self): self.view.set_footer_text("", 'entry_footer', False) - return DefaultEntryListState(self.state, self.controller, self.view) + self.set_next_state(DefaultEntryListState(self.state, self.controller, + self.view)) + return True class ProjectEditKeyState(AlterProjectState): @@ -719,10 +748,11 @@ def enter(self): key = self.footer.get_edit_text() if key == '': - return self + return True self.project.key = key - return ProjectEditDescriptionState(self.controller, self.view, - self.project) + self.set_next_state(ProjectEditDescriptionState(self.controller, + self.view, self.project)) + return True class ProjectEditDescriptionState(AlterProjectState): @@ -748,4 +778,5 @@ self.project.desc = description self.controller.update_project(self.project) self.controller.view.set_footer_text(self.msg('choose_proj'), 'question') - return PausedProjectsState(self.controller, self.view) + self.set_next_state(PausedProjectsState(self.controller, self.view)) + return True