def print_header(self) -> None: """Public function to print self.header in self.commandText. [requires]: self.header is not None self.commandText is not None [ensures]: [self.header displays as the last part in self.commandText] self.protected_text = self.header [convention #3.1] self.commandText.last_row = len(self.commandText._lines) - 1 [convention #0.1] [calls]: self.commandText.on_cursor """ if not asserts( self.header is not None, "self.header must be initialized before calling print_header." ): return if not asserts( self.commandText is not None, "self.commandText must be initialized before callingprint_header." ): return obj = self.commandText obj.insert_text("\n" + self.header) self.protected_text = self.header obj._reset_last_line() obj.on_cursor(obj, obj.cursor)
def build(self) -> Widget: """Builder of the application interface, called after build_config(). [requires]: isinstance(self.config, kivy.config.Config) [see [ensures] of build_config] [ensures]: self.header = self.config.get("Text", "username") + self.config.get("Text", "cmd_identifier) isinstance(self.commandText, Widget) self.commandText.text = self.header self.protected_text = self.header [calls]: _reset_header [reset self.commandText.protected_len] """ if not asserts(isinstance(self.config, ConfigParser), "self.config is not initialized."): return self.settings_cls = SettingsWithSidebar self.username = self.config.get("Text", "username") self.options_per_line = max( int(self.config.get("Option", "options_per_line")), 1) self.space_completion = self.config.get("Option", "space_completion") == "1" self.tab_completion = self.config.get("Option", "tab_completion") == "1" self._reset_header(self.username, self.config.get("Text", "cmd_identifier")) self.protected_text = self.header self.commandText = Builder.load_file("res/sira.kv") self._on_url(self.config.get("Jira", "url")) self._on_timeout(self.config.get("Jira", "timeout")) self._on_protocol(self.config.get("Jira", "protocol")) return self.commandText
def on_info(self, instance: App, info: list) -> None: """Property driven function, fired when info is changed. This function automatically prints all elements in info on seperate lines in this.commandText. [requires]: [convention #2.1] [ensures]: self.info = [] self.commandText.text = $self.commandText.text + '\n' + \n'.join(info) self.commandText.protected_text = info[-1] [convention #3.1] self.commandText.last_row = len(self.commandText._lines) - 1 [convention #0.1] [calls]: on_info (recursively once) self.commandText.on_cursor """ if self.info == []: return obj = self.commandText for s in info: if not asserts(isinstance(s, str), "(for line in self.info: isinstance(line, str))."): return obj.do_cursor_movement("cursor_end", control=True) self.protected_text = info[-1] for s in info: obj.insert_text("\n" + str(s)) obj._reset_last_line() obj.on_cursor(obj, obj.cursor) self.info = []
def _select_next_option(self, direction: str) -> None: """Private function to replace auto-completion text and selection next avaliable option. According to direction, there are three scenarios: [Scenario 1]: When direction == "tab", the function will erase any text from self.completion_start to the end of self.commandText.last_row, and replace it with next option avaliable. If the current option is the last displayed options, the first option will be print and selected. [Scenario 2]: When direction == "left", the function will act like Scenario 1 except printing and selecting the previous avaliable option. If there does not exist any previous options, this function will do nothing. [Scenario 3]: When direction == "right". the function will act exactly like Scenario 1, except do nothing when there does not exist any options avaliable. [requires]: self.commandText.completion_mode [ensures]: [function_doc] self.tab_index in range(self.options_per_line) """ instance = self.commandText if not asserts(instance.completion_mode, "Not in completion mode"): return tab_index = self.tab_index # update tab_index according to direction if direction == "tab": tab_index = tab_index + 1\ if tab_index < len(self.start_indices) - 1\ else 0 elif direction == "left": tab_index = max(tab_index - 1, 0) elif direction == "right": tab_index = min(tab_index + 1, len(self.start_indices) - 1) # do nothing if tab_index does not changed if tab_index != self.tab_index: # delete and insert next option instance.cancel_selection() start = self.completion_start end = instance.find_last_return(0, len(instance.text)) if end < start: import pdb pdb.set_trace() instance.select_text(start, end) instance.delete_selection() instance.do_cursor_movement("cursor_end", control=True) instance.insert_text(self.option[self.page_index + tab_index]) instance._reset_last_line() instance.on_cursor(instance, instance.cursor) # select next option last_char_return = instance.text.rindex("\n") start = last_char_return + self.start_indices[tab_index] + 1 end = start + len(self.option[self.page_index + tab_index]) if end < start: import pdb pdb.set_trace() instance.select_text(start, end) # update self.tab_index self.tab_index = tab_index
def _on_timeout(self, value: str) -> None: """Private function fired when timeout is changed through self.config. [requires]: value.isdigit() [ensures]: glob_dic.dic["timeout"] = int(value) """ if not asserts(value.isdigit(), "Timeout has to be an integer"): return glob_dic.set_value("timeout", int(value))
def _on_font_size(self, value: str) -> None: """Privated function fired when font_size is changed through self.config. [requires]: value.isdigit() [ensures]: self.commandText.font_size = int(value) """ if not asserts(value.isdigit(), "Font_size has to be an integer"): return self.commandText.font_size = int(value)
def build_settings(self, settings: Settings) -> None: """Builds and adds custom setting pannels to original settings, called when the user open settings for the first time. [requires]: isinstance(self.config, kivy.config.Config) [see [ensures] of build_config] """ if not asserts(isinstance(self.config, ConfigParser), "self.config is not initialized."): return settings.add_json_panel("Sira", self.config, filename="res/sira.json") settings.add_json_panel("Jira", self.config, filename="res/jira.json")
def _on_switch_option(self, instance: AdvancedTextInput, direction: str) -> bool: """Private function to select next option. This function is fired when self.commandText.on_left_option or self.commandText.on_right_option is called. [requires]: instance.completion_mode [calls]: self._select_next_option """ if not asserts(instance.completion_mode, "Not in completion mode"): return True self._select_next_option(direction)
def on_config_change(self, config: ConfigParser, section: str, key: str, value: str) -> None: """Fires when configs change. [requires]: config = self.config (for all config where config = self.config, ((section, key) in self.config_func_dict.keys())) [calls]: [corresponding functions in self.config_func_dict] """ if config == self.config: if not asserts((section, key) in self.config_func_dict.keys( ), "({}, {}) is not a key pair in self.config_func_dict".format( section, key)): return self.config_func_dict[(section, key)](value)
def _clear_options(self, instance: AdvancedTextInput) -> None: """Private function to clear all displayed options in self.commandText. [requires]: instance.completion_mode [ensures]: len(self.commandText._lines) - 1 = self.commandText.last_row [erase all text below self.commandText.last_row] """ if not asserts(instance.completion_mode, "Not in completion mode"): return instance.cancel_selection() start = instance.text.rindex('\n') end = len(instance.text) if end < start: import pdb pdb.set_trace() instance.select_text(start, end) instance.delete_selection()
def on_username(self, instance: App, value: str) -> None: """Property driven function, fired when username is changed. This function writes the new value in self.config and its corresponding config files. [requires]: self.config is not None [convention #1.1] (unchecked) [ensure]: self.config.get("Text", "username") = value [convention #0.2] [calls]: _reset_header """ if not asserts( self.config is not None, "self.config must be initialized before calling on_username."): return self.config.set("Text", "username", value) self.config.write() self._reset_header(value, self.config.get("Text", "cmd_identifier"))
def _stop_completion(self, instance: AdvancedTextInput) -> None: """Private function to stop completion mode. [requires]: instance.completion_mode [ensures]: not instance.completion_mode self.tab_index = -1 self.option = [] self.start_indices = [] [calls]: self._clear_options """ if not asserts(instance.completion_mode, "Not in completion mode"): return self._clear_options(instance) instance.completion_mode = False instance._reset_last_line() instance.on_cursor(instance, instance.cursor) self.tab_index = -1 self.option = [] self.start_indices = []
def _on_reduce_option(self, instance: AdvancedTextInput) -> bool: """Private function to reduce options based on user input. This function is fired when self.commandText.on_reduce_option is called. [requires]: instance.completion_mode [ensures]: self.option = [opt for all opt in $self.option if opt.lower().startswith( instance.text[self.completion_start:end].lower() )] [calls]: self._stop_completion """ if not asserts(instance.completion_mode, "Not in completion mode"): return True copy = list() instance.do_cursor_movement("cursor_end", control=False) end = instance.cursor_index(instance.cursor) word_truc = instance.text[self.completion_start:end] copy = [ opt for opt in self.option if opt.lower().startswith(word_truc.lower()) ] self._stop_completion(instance) self.option = copy