From d55cc5872503567775f0d7a7731d6f489bf2299b Mon Sep 17 00:00:00 2001 From: mathieui Date: Sun, 12 Nov 2017 15:03:09 +0100 Subject: yapf -ir --- poezio/windows/__init__.py | 18 ++-- poezio/windows/base_wins.py | 17 ++-- poezio/windows/bookmark_forms.py | 125 +++++++++++++++++---------- poezio/windows/confirm.py | 3 +- poezio/windows/data_forms.py | 159 +++++++++++++++++++++-------------- poezio/windows/funcs.py | 14 +-- poezio/windows/image.py | 16 ++-- poezio/windows/info_bar.py | 35 +++++--- poezio/windows/info_wins.py | 78 ++++++++++++----- poezio/windows/input_placeholders.py | 5 +- poezio/windows/inputs.py | 111 ++++++++++++++---------- poezio/windows/list.py | 42 +++++---- poezio/windows/misc.py | 3 +- poezio/windows/muc.py | 35 ++++---- poezio/windows/roster_win.py | 152 +++++++++++++++++++++------------ poezio/windows/text_win.py | 122 +++++++++++++++++---------- 16 files changed, 587 insertions(+), 348 deletions(-) (limited to 'poezio/windows') diff --git a/poezio/windows/__init__.py b/poezio/windows/__init__.py index 56657433..68250906 100644 --- a/poezio/windows/__init__.py +++ b/poezio/windows/__init__.py @@ -20,11 +20,13 @@ from poezio.windows.roster_win import RosterWin, ContactInfoWin from poezio.windows.text_win import TextWin, XMLTextWin from poezio.windows.image import ImageWin -__all__ = ['Win', 'FormWin', 'BookmarksWin', 'Dialog', 'GlobalInfoBar', - 'VerticalGlobalInfoBar', 'InfoWin', 'PrivateInfoWin', 'XMLInfoWin', - 'MucListInfoWin', 'ConversationInfoWin', 'MucInfoWin', - 'DynamicConversationInfoWin', 'ConversationStatusMessageWin', - 'BookmarksInfoWin', 'ConfirmStatusWin', 'HelpText', 'Input', - 'HistoryInput', 'MessageInput', 'CommandInput', 'ListWin', - 'ColumnHeaderWin', 'VerticalSeparator', 'UserList', 'Topic', - 'RosterWin', 'ContactInfoWin', 'TextWin', 'XMLTextWin', 'ImageWin'] +__all__ = [ + 'Win', 'FormWin', 'BookmarksWin', 'Dialog', 'GlobalInfoBar', + 'VerticalGlobalInfoBar', 'InfoWin', 'PrivateInfoWin', 'XMLInfoWin', + 'MucListInfoWin', 'ConversationInfoWin', 'MucInfoWin', + 'DynamicConversationInfoWin', 'ConversationStatusMessageWin', + 'BookmarksInfoWin', 'ConfirmStatusWin', 'HelpText', 'Input', + 'HistoryInput', 'MessageInput', 'CommandInput', 'ListWin', + 'ColumnHeaderWin', 'VerticalSeparator', 'UserList', 'Topic', 'RosterWin', + 'ContactInfoWin', 'TextWin', 'XMLTextWin', 'ImageWin' +] diff --git a/poezio/windows/base_wins.py b/poezio/windows/base_wins.py index 8813d8f7..f3970ff5 100644 --- a/poezio/windows/base_wins.py +++ b/poezio/windows/base_wins.py @@ -22,6 +22,7 @@ FORMAT_CHAR = '\x19' # I guess. But maybe we can find better chars that are even less risky. format_chars = '\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18' + class DummyWin(object): def __getattribute__(self, name): if name != '__bool__': @@ -103,7 +104,7 @@ class Win(object): has_italic = hasattr(curses, 'A_ITALIC') while next_attr_char != -1 and text: if next_attr_char + 1 < len(text): - attr_char = text[next_attr_char+1].lower() + attr_char = text[next_attr_char + 1].lower() else: attr_char = str() if next_attr_char != 0: @@ -116,8 +117,10 @@ class Win(object): self._win.attron(curses.A_BOLD) elif attr_char == 'i' and has_italic: self._win.attron(curses.A_ITALIC) - if (attr_char in string.digits or attr_char == '-') and attr_char != '': - color_str = text[next_attr_char+1:text.find('}', next_attr_char)] + if (attr_char in string.digits + or attr_char == '-') and attr_char != '': + color_str = text[next_attr_char + 1:text.find( + '}', next_attr_char)] if ',' in color_str: tup, char = read_tuple(color_str) self._win.attron(to_curses_attr(tup)) @@ -136,9 +139,9 @@ class Win(object): self._win.attroff(curses.A_BOLD) elif color_str: self._win.attron(to_curses_attr((int(color_str), -1))) - text = text[next_attr_char+len(color_str)+2:] + text = text[next_attr_char + len(color_str) + 2:] else: - text = text[next_attr_char+2:] + text = text[next_attr_char + 2:] next_attr_char = text.find(FORMAT_CHAR) self.addstr(text) @@ -149,6 +152,6 @@ class Win(object): (y, x) = self._win.getyx() size = self.width - x if color: - self.addnstr(' '*size, size, to_curses_attr(color)) + self.addnstr(' ' * size, size, to_curses_attr(color)) else: - self.addnstr(' '*size, size) + self.addnstr(' ' * size, size) diff --git a/poezio/windows/bookmark_forms.py b/poezio/windows/bookmark_forms.py index 5fbc3858..5f5d581a 100644 --- a/poezio/windows/bookmark_forms.py +++ b/poezio/windows/bookmark_forms.py @@ -10,6 +10,7 @@ from poezio.windows.data_forms import FieldInput, FieldInputMixin from poezio.theming import to_curses_attr, get_theme from poezio.common import safeJID + class BookmarkJIDInput(FieldInput, Input): def __init__(self, field): FieldInput.__init__(self, field) @@ -29,6 +30,7 @@ class BookmarkJIDInput(FieldInput, Input): def get_help_message(self): return 'Edit the text' + class BookmarkMethodInput(FieldInputMixin): def __init__(self, field): FieldInput.__init__(self, field) @@ -42,7 +44,7 @@ class BookmarkMethodInput(FieldInputMixin): if self.val_pos > 0: self.val_pos -= 1 elif key == 'KEY_RIGHT': - if self.val_pos < len(self.options)-1: + if self.val_pos < len(self.options) - 1: self.val_pos += 1 else: return @@ -51,14 +53,14 @@ class BookmarkMethodInput(FieldInputMixin): def refresh(self): self._win.erase() self._win.attron(to_curses_attr(self.color)) - self.addnstr(0, 0, ' '*self.width, self.width) + self.addnstr(0, 0, ' ' * self.width, self.width) if self.val_pos > 0: self.addstr(0, 0, '←') - if self.val_pos < len(self.options)-1: - self.addstr(0, self.width-1, '→') + if self.val_pos < len(self.options) - 1: + self.addstr(0, self.width - 1, '→') if self.options: option = self.options[self.val_pos] - self.addstr(0, self.width//2-len(option)//2, option) + self.addstr(0, self.width // 2 - len(option) // 2, option) self._win.attroff(to_curses_attr(self.color)) self._refresh() @@ -68,6 +70,7 @@ class BookmarkMethodInput(FieldInputMixin): def get_help_message(self): return '←, →: Select a value amongst the others' + class BookmarkPasswordInput(FieldInput, Input): def __init__(self, field): FieldInput.__init__(self, field) @@ -80,11 +83,12 @@ class BookmarkPasswordInput(FieldInput, Input): self._win.erase() if self.color: self._win.attron(to_curses_attr(self.color)) - self.addstr('*'*len(self.text[self.view_pos:self.view_pos+self.width-1])) + self.addstr( + '*' * len(self.text[self.view_pos:self.view_pos + self.width - 1])) if self.color: (y, x) = self._win.getyx() - size = self.width-x - self.addnstr(' '*size, size, to_curses_attr(self.color)) + size = self.width - x + self.addnstr(' ' * size, size, to_curses_attr(self.color)) self.addstr(0, self.pos, '') if self.color: self._win.attroff(to_curses_attr(self.color)) @@ -96,6 +100,7 @@ class BookmarkPasswordInput(FieldInput, Input): def get_help_message(self): return 'Edit the secret text' + class BookmarkAutojoinWin(FieldInputMixin): def __init__(self, field): FieldInput.__init__(self, field) @@ -138,10 +143,9 @@ class BookmarksWin(Win): self._bookmarks = list(bookmarks) self.lines = [] for bookmark in sorted(self._bookmarks, key=lambda x: x.jid): - self.lines.append((BookmarkJIDInput(bookmark), - BookmarkPasswordInput(bookmark), - BookmarkAutojoinWin(bookmark), - BookmarkMethodInput(bookmark))) + self.lines.append( + (BookmarkJIDInput(bookmark), BookmarkPasswordInput(bookmark), + BookmarkAutojoinWin(bookmark), BookmarkMethodInput(bookmark))) @property def current_input(self): @@ -151,20 +155,23 @@ class BookmarksWin(Win): def current_input(self, value): if 0 <= self._current_input < len(self.lines): if 0 <= value < len(self.lines): - self.lines[self._current_input][self.current_horizontal_input].set_color(get_theme().COLOR_NORMAL_TEXT) + self.lines[self._current_input][ + self.current_horizontal_input].set_color( + get_theme().COLOR_NORMAL_TEXT) self._current_input = value else: self._current_input = 0 def add_bookmark(self, bookmark): - self.lines.append((BookmarkJIDInput(bookmark), - BookmarkPasswordInput(bookmark), - BookmarkAutojoinWin(bookmark), - BookmarkMethodInput(bookmark))) - self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_NORMAL_TEXT) + self.lines.append( + (BookmarkJIDInput(bookmark), BookmarkPasswordInput(bookmark), + BookmarkAutojoinWin(bookmark), BookmarkMethodInput(bookmark))) + self.lines[ + self.current_input][self.current_horizontal_input].set_color( + get_theme().COLOR_NORMAL_TEXT) self.current_horizontal_input = 0 self.current_input = len(self.lines) - 1 - if self.current_input - self.scroll_pos > self.height-1: + if self.current_input - self.scroll_pos > self.height - 1: self.scroll_pos = self.current_input - self.height + 1 self.refresh() @@ -185,7 +192,7 @@ class BookmarksWin(Win): self._win = base_wins.TAB_WIN.derwin(height, width, y, x) # Adjust the scroll position, if resizing made the window too small # for the cursor to be visible - while self.current_input - self.scroll_pos > self.height-1: + while self.current_input - self.scroll_pos > self.height - 1: self.scroll_pos += 1 def go_to_next_line_input(self): @@ -193,39 +200,51 @@ class BookmarksWin(Win): return if self.current_input == len(self.lines) - 1: return - self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_NORMAL_TEXT) + self.lines[ + self.current_input][self.current_horizontal_input].set_color( + get_theme().COLOR_NORMAL_TEXT) # Adjust the scroll position if the current_input would be outside # of the visible area - if self.current_input + 1 - self.scroll_pos > self.height-1: + if self.current_input + 1 - self.scroll_pos > self.height - 1: self.current_input += 1 self.scroll_pos += 1 self.refresh() else: self.current_input += 1 - self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_SELECTED_ROW) + self.lines[self.current_input][ + self.current_horizontal_input].set_color( + get_theme().COLOR_SELECTED_ROW) def go_to_previous_line_input(self): if not self.lines: return if self.current_input == 0: return - self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_NORMAL_TEXT) + self.lines[ + self.current_input][self.current_horizontal_input].set_color( + get_theme().COLOR_NORMAL_TEXT) self.current_input -= 1 # Adjust the scroll position if the current_input would be outside # of the visible area if self.current_input < self.scroll_pos: self.scroll_pos = self.current_input self.refresh() - self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_SELECTED_ROW) + self.lines[ + self.current_input][self.current_horizontal_input].set_color( + get_theme().COLOR_SELECTED_ROW) def go_to_next_horizontal_input(self): if not self.lines: return - self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_NORMAL_TEXT) + self.lines[ + self.current_input][self.current_horizontal_input].set_color( + get_theme().COLOR_NORMAL_TEXT) self.current_horizontal_input += 1 if self.current_horizontal_input > 3: self.current_horizontal_input = 0 - self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_SELECTED_ROW) + self.lines[ + self.current_input][self.current_horizontal_input].set_color( + get_theme().COLOR_SELECTED_ROW) def go_to_next_page(self): if not self.lines: @@ -234,7 +253,9 @@ class BookmarksWin(Win): if self.current_input == len(self.lines) - 1: return - self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_NORMAL_TEXT) + self.lines[ + self.current_input][self.current_horizontal_input].set_color( + get_theme().COLOR_NORMAL_TEXT) inc = min(self.height, len(self.lines) - self.current_input - 1) if self.current_input + inc - self.scroll_pos > self.height - 1: @@ -243,7 +264,9 @@ class BookmarksWin(Win): self.refresh() else: self.current_input += inc - self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_SELECTED_ROW) + self.lines[self.current_input][ + self.current_horizontal_input].set_color( + get_theme().COLOR_SELECTED_ROW) return True def go_to_previous_page(self): @@ -253,7 +276,9 @@ class BookmarksWin(Win): if self.current_input == 0: return - self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_NORMAL_TEXT) + self.lines[ + self.current_input][self.current_horizontal_input].set_color( + get_theme().COLOR_NORMAL_TEXT) dec = min(self.height, self.current_input) self.current_input -= dec @@ -262,7 +287,9 @@ class BookmarksWin(Win): if self.current_input < self.scroll_pos: self.scroll_pos = self.current_input self.refresh() - self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_SELECTED_ROW) + self.lines[ + self.current_input][self.current_horizontal_input].set_color( + get_theme().COLOR_SELECTED_ROW) return True def go_to_previous_horizontal_input(self): @@ -270,24 +297,31 @@ class BookmarksWin(Win): return if self.current_horizontal_input == 0: return - self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_NORMAL_TEXT) + self.lines[ + self.current_input][self.current_horizontal_input].set_color( + get_theme().COLOR_NORMAL_TEXT) self.current_horizontal_input -= 1 - self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_SELECTED_ROW) + self.lines[ + self.current_input][self.current_horizontal_input].set_color( + get_theme().COLOR_SELECTED_ROW) def on_input(self, key): if not self.lines: return - self.lines[self.current_input][self.current_horizontal_input].do_command(key) + self.lines[self.current_input][ + self.current_horizontal_input].do_command(key) def refresh(self): # store the cursor status self._win.erase() - y = - self.scroll_pos + y = -self.scroll_pos for i in range(len(self.lines)): - self.lines[i][0].resize(1, self.width//3, y + 1, 0) - self.lines[i][1].resize(1, self.width//3, y + 1, self.width//3) - self.lines[i][2].resize(1, self.width//6, y + 1, 2*self.width//3) - self.lines[i][3].resize(1, self.width//6, y + 1, 5*self.width//6) + self.lines[i][0].resize(1, self.width // 3, y + 1, 0) + self.lines[i][1].resize(1, self.width // 3, y + 1, self.width // 3) + self.lines[i][2].resize(1, self.width // 6, y + 1, + 2 * self.width // 3) + self.lines[i][3].resize(1, self.width // 6, y + 1, + 5 * self.width // 6) y += 1 self._refresh() for i, inp in enumerate(self.lines): @@ -298,9 +332,12 @@ class BookmarksWin(Win): for j in range(4): inp[j].refresh() - if self.lines and self.current_input < self.height-1: - self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_SELECTED_ROW) - self.lines[self.current_input][self.current_horizontal_input].refresh() + if self.lines and self.current_input < self.height - 1: + self.lines[self.current_input][ + self.current_horizontal_input].set_color( + get_theme().COLOR_SELECTED_ROW) + self.lines[self.current_input][ + self.current_horizontal_input].refresh() if not self.lines: curses.curs_set(0) else: @@ -308,10 +345,10 @@ class BookmarksWin(Win): def refresh_current_input(self): if self.lines: - self.lines[self.current_input][self.current_horizontal_input].refresh() + self.lines[self.current_input][ + self.current_horizontal_input].refresh() def save(self): for line in self.lines: for item in line: item.save() - diff --git a/poezio/windows/confirm.py b/poezio/windows/confirm.py index 591ff89a..f2794221 100644 --- a/poezio/windows/confirm.py +++ b/poezio/windows/confirm.py @@ -2,9 +2,11 @@ from poezio.windows.base_wins import Win from poezio.theming import get_theme, to_curses_attr + class Dialog(Win): str_accept = " Accept " str_refuse = " Reject " + def __init__(self, helper_text, critical=False): self.text = helper_text self.accept = False @@ -35,4 +37,3 @@ class Dialog(Win): def toggle_choice(self): self.accept = not self.accept - diff --git a/poezio/windows/data_forms.py b/poezio/windows/data_forms.py index a14418d7..c600273e 100644 --- a/poezio/windows/data_forms.py +++ b/poezio/windows/data_forms.py @@ -12,12 +12,14 @@ from poezio.windows.inputs import Input from poezio.theming import to_curses_attr, get_theme + class FieldInput(object): """ All input types in a data form should inherit this class, in addition with windows.Input or any relevant class from the 'windows' library. """ + def __init__(self, field): self._field = field self.color = get_theme().COLOR_NORMAL_TEXT @@ -25,7 +27,6 @@ class FieldInput(object): def update_field_value(self, value): raise NotImplementedError - def is_dummy(self): return False @@ -42,8 +43,10 @@ class FieldInput(object): """ return '' + class FieldInputMixin(FieldInput, Win): "Mix both FieldInput and Win" + def __init__(self, field): FieldInput.__init__(self, field) Win.__init__(self) @@ -81,6 +84,7 @@ class DummyInput(FieldInputMixin): """ Used for fields that do not require any input ('fixed') """ + def __init__(self, field): FieldInputMixin.__init__(self, field) @@ -93,6 +97,7 @@ class DummyInput(FieldInputMixin): def is_dummy(self): return True + class BooleanWin(FieldInputMixin): def __init__(self, field): FieldInputMixin.__init__(self, field) @@ -108,8 +113,8 @@ class BooleanWin(FieldInputMixin): def refresh(self): self._win.erase() self._win.attron(to_curses_attr(self.color)) - self.addnstr(0, 0, ' '*(8), self.width) - self.addstr(0, 2, "%s"%self.value) + self.addnstr(0, 0, ' ' * (8), self.width) + self.addstr(0, 2, "%s" % self.value) self.addstr(0, 8, '→') self.addstr(0, 0, '←') if self.last_key == 'KEY_RIGHT': @@ -126,6 +131,7 @@ class BooleanWin(FieldInputMixin): def get_help_message(self): return '← and →: change the value between True and False' + class TextMultiWin(FieldInputMixin): def __init__(self, field): FieldInputMixin.__init__(self, field) @@ -149,20 +155,22 @@ class TextMultiWin(FieldInputMixin): if self.val_pos > 0: self.val_pos -= 1 elif key == 'KEY_RIGHT': - if self.val_pos < len(self.options)-1: + if self.val_pos < len(self.options) - 1: self.val_pos += 1 elif key == '^M': self.edition_input = Input() self.edition_input.color = self.color - self.edition_input.resize(self.height, self.width, self.y, self.x) + self.edition_input.resize(self.height, self.width, self.y, + self.x) self.edition_input.text = self.options[self.val_pos] self.edition_input.key_end() else: if key == '^M': self.options[self.val_pos] = self.edition_input.get_text() - if not self.options[self.val_pos] and self.val_pos != len(self.options) -1: + if not self.options[self.val_pos] and self.val_pos != len( + self.options) - 1: del self.options[self.val_pos] - if self.val_pos == len(self.options) -1: + if self.val_pos == len(self.options) - 1: self.val_pos -= 1 self.edition_input = None if not self.options or self.options[-1] != '': @@ -175,13 +183,13 @@ class TextMultiWin(FieldInputMixin): if not self.edition_input: self._win.erase() self._win.attron(to_curses_attr(self.color)) - self.addnstr(0, 0, ' '*self.width, self.width) + self.addnstr(0, 0, ' ' * self.width, self.width) option = self.options[self.val_pos] - self.addstr(0, self.width//2-len(option)//2, option) + self.addstr(0, self.width // 2 - len(option) // 2, option) if self.val_pos > 0: self.addstr(0, 0, '←') - if self.val_pos < len(self.options)-1: - self.addstr(0, self.width-1, '→') + if self.val_pos < len(self.options) - 1: + self.addstr(0, self.width - 1, '→') self._win.attroff(to_curses_attr(self.color)) self._refresh() else: @@ -194,7 +202,7 @@ class TextMultiWin(FieldInputMixin): def get_help_message(self): if not self.edition_input: help_msg = '← and →: browse the available entries. ' - if self.val_pos == len(self.options)-1: + if self.val_pos == len(self.options) - 1: help_msg += 'Enter: add an entry' else: help_msg += 'Enter: edit this entry' @@ -202,6 +210,7 @@ class TextMultiWin(FieldInputMixin): help_msg = 'Enter: finish editing this entry.' return help_msg + class ListMultiWin(FieldInputMixin): def __init__(self, field): FieldInputMixin.__init__(self, field) @@ -215,7 +224,7 @@ class ListMultiWin(FieldInputMixin): if self.val_pos > 0: self.val_pos -= 1 elif key == 'KEY_RIGHT': - if self.val_pos < len(self.options)-1: + if self.val_pos < len(self.options) - 1: self.val_pos += 1 elif key == ' ': self.options[self.val_pos][1] = not self.options[self.val_pos][1] @@ -226,14 +235,15 @@ class ListMultiWin(FieldInputMixin): def refresh(self): self._win.erase() self._win.attron(to_curses_attr(self.color)) - self.addnstr(0, 0, ' '*self.width, self.width) + self.addnstr(0, 0, ' ' * self.width, self.width) if self.val_pos > 0: self.addstr(0, 0, '←') - if self.val_pos < len(self.options)-1: - self.addstr(0, self.width-1, '→') + if self.val_pos < len(self.options) - 1: + self.addstr(0, self.width - 1, '→') if self.options: option = self.options[self.val_pos] - self.addstr(0, self.width//2-len(option)//2, option[0]['label']) + self.addstr(0, self.width // 2 - len(option) // 2, + option[0]['label']) self.addstr(0, 2, '✔' if option[1] else '☐') self._win.attroff(to_curses_attr(self.color)) self._refresh() @@ -241,12 +251,15 @@ class ListMultiWin(FieldInputMixin): def reply(self): self._field['label'] = '' self._field.delOptions() - values = [option[0]['value'] for option in self.options if option[1] is True] + values = [ + option[0]['value'] for option in self.options if option[1] is True + ] self._field.set_answer(values) def get_help_message(self): return '←, →: Switch between the value. Space: select or unselect a value' + class ListSingleWin(FieldInputMixin): def __init__(self, field): FieldInputMixin.__init__(self, field) @@ -263,7 +276,7 @@ class ListSingleWin(FieldInputMixin): if self.val_pos > 0: self.val_pos -= 1 elif key == 'KEY_RIGHT': - if self.val_pos < len(self.options)-1: + if self.val_pos < len(self.options) - 1: self.val_pos += 1 else: return @@ -272,14 +285,14 @@ class ListSingleWin(FieldInputMixin): def refresh(self): self._win.erase() self._win.attron(to_curses_attr(self.color)) - self.addnstr(0, 0, ' '*self.width, self.width) + self.addnstr(0, 0, ' ' * self.width, self.width) if self.val_pos > 0: self.addstr(0, 0, '←') - if self.val_pos < len(self.options)-1: - self.addstr(0, self.width-1, '→') + if self.val_pos < len(self.options) - 1: + self.addstr(0, self.width - 1, '→') if self.options: option = self.options[self.val_pos]['label'] - self.addstr(0, self.width//2-len(option)//2, option) + self.addstr(0, self.width // 2 - len(option) // 2, option) self._win.attroff(to_curses_attr(self.color)) self._refresh() @@ -291,6 +304,7 @@ class ListSingleWin(FieldInputMixin): def get_help_message(self): return '←, →: Select a value amongst the others' + class TextSingleWin(FieldInputMixin, Input): def __init__(self, field): FieldInputMixin.__init__(self, field) @@ -307,6 +321,7 @@ class TextSingleWin(FieldInputMixin, Input): def get_help_message(self): return 'Edit the text' + class TextPrivateWin(TextSingleWin): def __init__(self, field): TextSingleWin.__init__(self, field) @@ -315,11 +330,12 @@ class TextPrivateWin(TextSingleWin): self._win.erase() if self.color: self._win.attron(to_curses_attr(self.color)) - self.addstr('*'*len(self.text[self.view_pos:self.view_pos+self.width-1])) + self.addstr( + '*' * len(self.text[self.view_pos:self.view_pos + self.width - 1])) if self.color: (y, x) = self._win.getyx() - size = self.width-x - self.addnstr(' '*size, size, to_curses_attr(self.color)) + size = self.width - x + self.addnstr(' ' * size, size, to_curses_attr(self.color)) self.addstr(0, self.pos, '') if self.color: self._win.attroff(to_curses_attr(self.color)) @@ -328,6 +344,7 @@ class TextPrivateWin(TextSingleWin): def get_help_message(self): return 'Edit the secret text' + class FormWin(object): """ A window, with some subwins (the various inputs). @@ -335,22 +352,24 @@ class FormWin(object): On resize, move and resize all the subwin and define how the text will be written On refresh, write all the text, and refresh all the subwins """ - input_classes = {'boolean': BooleanWin, - 'fixed': DummyInput, - 'jid-multi': TextMultiWin, - 'jid-single': TextSingleWin, - 'list-multi': ListMultiWin, - 'list-single': ListSingleWin, - 'text-multi': TextMultiWin, - 'text-private': TextPrivateWin, - 'text-single': TextSingleWin, - } + input_classes = { + 'boolean': BooleanWin, + 'fixed': DummyInput, + 'jid-multi': TextMultiWin, + 'jid-single': TextSingleWin, + 'list-multi': ListMultiWin, + 'list-single': ListSingleWin, + 'text-multi': TextMultiWin, + 'text-private': TextPrivateWin, + 'text-single': TextSingleWin, + } + def __init__(self, form, height, width, y, x): self._form = form self._win = base_wins.TAB_WIN.derwin(height, width, y, x) self.scroll_pos = 0 self.current_input = 0 - self.inputs = [] # dict list + self.inputs = [] # dict list for (name, field) in self._form.getFields().items(): if field['type'] == 'hidden': continue @@ -363,9 +382,11 @@ class FormWin(object): if field['type'] == 'fixed': label = field.get_value() inp = input_class(field) - self.inputs.append({'label':ColoredLabel(label), - 'description': desc, - 'input':inp}) + self.inputs.append({ + 'label': ColoredLabel(label), + 'description': desc, + 'input': inp + }) def resize(self, height, width, y, x): self.height = height @@ -373,7 +394,7 @@ class FormWin(object): self._win = base_wins.TAB_WIN.derwin(height, width, y, x) # Adjust the scroll position, if resizing made the window too small # for the cursor to be visible - while self.current_input - self.scroll_pos > self.height-1: + while self.current_input - self.scroll_pos > self.height - 1: self.scroll_pos += 1 def reply(self): @@ -394,13 +415,17 @@ class FormWin(object): return if self.current_input == len(self.inputs) - 1: return - self.inputs[self.current_input]['input'].set_color(get_theme().COLOR_NORMAL_TEXT) - self.inputs[self.current_input]['label'].set_color(get_theme().COLOR_NORMAL_TEXT) + self.inputs[self.current_input]['input'].set_color( + get_theme().COLOR_NORMAL_TEXT) + self.inputs[self.current_input]['label'].set_color( + get_theme().COLOR_NORMAL_TEXT) self.current_input += 1 jump = 0 - while self.current_input+jump != len(self.inputs) - 1 and self.inputs[self.current_input+jump]['input'].is_dummy(): + while self.current_input + jump != len( + self.inputs) - 1 and self.inputs[self.current_input + + jump]['input'].is_dummy(): jump += 1 - if self.inputs[self.current_input+jump]['input'].is_dummy(): + if self.inputs[self.current_input + jump]['input'].is_dummy(): return self.current_input += jump # If moving made the current input out of the visible screen, we @@ -408,24 +433,31 @@ class FormWin(object): # call refresh() if this is not the case, because # refresh_current_input() is always called anyway, so this is not # needed - if self.current_input - self.scroll_pos > self.height-1: + if self.current_input - self.scroll_pos > self.height - 1: self.scroll_pos += 1 self.refresh() - self.inputs[self.current_input]['input'].set_color(get_theme().COLOR_SELECTED_ROW) - self.inputs[self.current_input]['label'].set_color(get_theme().COLOR_SELECTED_ROW) + self.inputs[self.current_input]['input'].set_color( + get_theme().COLOR_SELECTED_ROW) + self.inputs[self.current_input]['label'].set_color( + get_theme().COLOR_SELECTED_ROW) def go_to_previous_input(self): if not self.inputs: return if self.current_input == 0: return - self.inputs[self.current_input]['input'].set_color(get_theme().COLOR_NORMAL_TEXT) - self.inputs[self.current_input]['label'].set_color(get_theme().COLOR_NORMAL_TEXT) + self.inputs[self.current_input]['input'].set_color( + get_theme().COLOR_NORMAL_TEXT) + self.inputs[self.current_input]['label'].set_color( + get_theme().COLOR_NORMAL_TEXT) self.current_input -= 1 jump = 0 - while self.current_input-jump > 0 and self.inputs[self.current_input+jump]['input'].is_dummy(): + while self.current_input - jump > 0 and self.inputs[self.current_input + + + jump]['input'].is_dummy( + ): jump += 1 - if self.inputs[self.current_input+jump]['input'].is_dummy(): + if self.inputs[self.current_input + jump]['input'].is_dummy(): return # Adjust the scroll position if the current_input would be outside # of the visible area @@ -433,8 +465,10 @@ class FormWin(object): self.scroll_pos = self.current_input self.refresh() self.current_input -= jump - self.inputs[self.current_input]['input'].set_color(get_theme().COLOR_SELECTED_ROW) - self.inputs[self.current_input]['label'].set_color(get_theme().COLOR_SELECTED_ROW) + self.inputs[self.current_input]['input'].set_color( + get_theme().COLOR_SELECTED_ROW) + self.inputs[self.current_input]['label'].set_color( + get_theme().COLOR_SELECTED_ROW) def on_input(self, key, raw=False): if not self.inputs: @@ -448,8 +482,9 @@ class FormWin(object): for name, field in self._form.getFields().items(): if field['type'] == 'hidden': continue - self.inputs[i]['label'].resize(1, self.width//2, y + 1, 0) - self.inputs[i]['input'].resize(1, self.width//2, y+1, self.width//2) + self.inputs[i]['label'].resize(1, self.width // 2, y + 1, 0) + self.inputs[i]['input'].resize(1, self.width // 2, y + 1, + self.width // 2) # TODO: display the field description y += 1 i += 1 @@ -462,17 +497,19 @@ class FormWin(object): inp['label'].refresh() inp['input'].refresh() inp['label'].refresh() - if self.inputs and self.current_input < self.height-1: - self.inputs[self.current_input]['input'].set_color(get_theme().COLOR_SELECTED_ROW) + if self.inputs and self.current_input < self.height - 1: + self.inputs[self.current_input]['input'].set_color( + get_theme().COLOR_SELECTED_ROW) self.inputs[self.current_input]['input'].refresh() - self.inputs[self.current_input]['label'].set_color(get_theme().COLOR_SELECTED_ROW) + self.inputs[self.current_input]['label'].set_color( + get_theme().COLOR_SELECTED_ROW) self.inputs[self.current_input]['label'].refresh() def refresh_current_input(self): self.inputs[self.current_input]['input'].refresh() def get_help_message(self): - if self.inputs and self.current_input < self.height-1 and self.inputs[self.current_input]['input']: + if self.inputs and self.current_input < self.height - 1 and self.inputs[self. + current_input]['input']: return self.inputs[self.current_input]['input'].get_help_message() return '' - diff --git a/poezio/windows/funcs.py b/poezio/windows/funcs.py index ea2941c8..3648bac3 100644 --- a/poezio/windows/funcs.py +++ b/poezio/windows/funcs.py @@ -7,6 +7,7 @@ DIGITS = string.digits + '-' from poezio.windows.base_wins import FORMAT_CHAR, format_chars + def find_first_format_char(text, chars=None): if chars is None: chars = format_chars @@ -19,13 +20,15 @@ def find_first_format_char(text, chars=None): pos = p return pos + def truncate_nick(nick, size=10): if size < 1: size = 1 if nick and len(nick) > size: - return nick[:size]+'…' + return nick[:size] + '…' return nick + def parse_attrs(text, previous=None): next_attr_char = text.find(FORMAT_CHAR) if previous: @@ -34,7 +37,7 @@ def parse_attrs(text, previous=None): attrs = [] while next_attr_char != -1 and text: if next_attr_char + 1 < len(text): - attr_char = text[next_attr_char+1].lower() + attr_char = text[next_attr_char + 1].lower() else: attr_char = '\0' if attr_char == 'o': @@ -46,12 +49,11 @@ def parse_attrs(text, previous=None): elif attr_char == 'i': attrs.append('i') if attr_char in DIGITS and attr_char: - color_str = text[next_attr_char+1:text.find('}', next_attr_char)] + color_str = text[next_attr_char + 1:text.find('}', next_attr_char)] if color_str: attrs.append(color_str + '}') - text = text[next_attr_char+len(color_str)+2:] + text = text[next_attr_char + len(color_str) + 2:] else: - text = text[next_attr_char+2:] + text = text[next_attr_char + 2:] next_attr_char = text.find(FORMAT_CHAR) return attrs - diff --git a/poezio/windows/image.py b/poezio/windows/image.py index 57bbec71..09a11d6f 100644 --- a/poezio/windows/image.py +++ b/poezio/windows/image.py @@ -15,10 +15,12 @@ from poezio.windows.base_wins import Win from poezio.theming import to_curses_attr from poezio.xhtml import _parse_css_color + class ImageWin(Win): """ A window which contains either an image or a border. """ + def __init__(self): self._image = None Win.__init__(self) @@ -41,10 +43,10 @@ class ImageWin(Win): self._refresh() def _display_border(self): - self._win.border(curses.ACS_VLINE, curses.ACS_VLINE, - curses.ACS_HLINE, curses.ACS_HLINE, - curses.ACS_ULCORNER, curses.ACS_URCORNER, - curses.ACS_LLCORNER, curses.ACS_LRCORNER) + self._win.border(curses.ACS_VLINE, curses.ACS_VLINE, curses.ACS_HLINE, + curses.ACS_HLINE, curses.ACS_ULCORNER, + curses.ACS_URCORNER, curses.ACS_LLCORNER, + curses.ACS_LRCORNER) @staticmethod def _compute_size(image_size, width: int, height: int): @@ -69,13 +71,13 @@ class ImageWin(Win): start_y = (original_height - height // 2) // 2 start_x = (original_width - width) // 2 for y in range(height // 2): - two_lines = data[(2 * y) * width * 3: (2 * y + 2) * width * 3] + two_lines = data[(2 * y) * width * 3:(2 * y + 2) * width * 3] line1 = two_lines[:width * 3] line2 = two_lines[width * 3:] self.move(start_y + y, start_x) for x in range(width): - r, g, b = line1[x * 3: (x + 1) * 3] + r, g, b = line1[x * 3:(x + 1) * 3] top_color = _parse_css_color('#%02x%02x%02x' % (r, g, b)) - r, g, b = line2[x * 3: (x + 1) * 3] + r, g, b = line2[x * 3:(x + 1) * 3] bot_color = _parse_css_color('#%02x%02x%02x' % (r, g, b)) self.addstr('▄', to_curses_attr((bot_color, top_color))) diff --git a/poezio/windows/info_bar.py b/poezio/windows/info_bar.py index cac56db9..950813f1 100644 --- a/poezio/windows/info_bar.py +++ b/poezio/windows/info_bar.py @@ -10,11 +10,11 @@ log = logging.getLogger(__name__) import curses - from poezio.config import config from poezio.windows.base_wins import Win from poezio.theming import get_theme, to_curses_attr + class GlobalInfoBar(Win): def __init__(self, core): Win.__init__(self) @@ -23,7 +23,8 @@ class GlobalInfoBar(Win): def refresh(self): log.debug('Refresh: %s', self.__class__.__name__) self._win.erase() - self.addstr(0, 0, "[", to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + self.addstr(0, 0, "[", + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) create_gaps = config.get('create_gaps') show_names = config.get('show_tab_names') @@ -48,20 +49,24 @@ class GlobalInfoBar(Win): self.addstr(' ', to_curses_attr(color)) if show_names: if use_nicks: - self.addstr("%s" % str(tab.get_nick()), to_curses_attr(color)) + self.addstr("%s" % str(tab.get_nick()), + to_curses_attr(color)) else: self.addstr("%s" % tab.name, to_curses_attr(color)) - self.addstr("|", to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) - except: # end of line + self.addstr("|", + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + except: # end of line break (y, x) = self._win.getyx() - self.addstr(y, x-1, '] ', to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + self.addstr(y, x - 1, '] ', + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) (y, x) = self._win.getyx() remaining_size = self.width - x - self.addnstr(' '*remaining_size, remaining_size, + self.addnstr(' ' * remaining_size, remaining_size, to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) self._refresh() + class VerticalGlobalInfoBar(Win): def __init__(self, core, scr): Win.__init__(self) @@ -79,30 +84,32 @@ class VerticalGlobalInfoBar(Win): use_nicks = config.get('use_tab_nicks') if nb_tabs >= height: for y, tab in enumerate(sorted_tabs): - if tab.vertical_color == get_theme().COLOR_VERTICAL_TAB_CURRENT: + if tab.vertical_color == get_theme( + ).COLOR_VERTICAL_TAB_CURRENT: pos = y break # center the current tab as much as possible - if pos < height//2: + if pos < height // 2: sorted_tabs = sorted_tabs[:height] - elif nb_tabs - pos <= height//2: + elif nb_tabs - pos <= height // 2: sorted_tabs = sorted_tabs[-height:] else: - sorted_tabs = sorted_tabs[pos-height//2 : pos+height//2] + sorted_tabs = sorted_tabs[pos - height // 2:pos + height // 2] asc_sort = (config.get('vertical_tab_list_sort') == 'asc') for y, tab in enumerate(sorted_tabs): color = tab.vertical_color if asc_sort: y = height - y - 1 self.addstr(y, 0, "%2d" % tab.nb, - to_curses_attr(get_theme().COLOR_VERTICAL_TAB_NUMBER)) + to_curses_attr(get_theme().COLOR_VERTICAL_TAB_NUMBER)) self.addstr('.') if use_nicks: - self.addnstr("%s" % tab.get_nick(), width - 4, to_curses_attr(color)) + self.addnstr("%s" % tab.get_nick(), width - 4, + to_curses_attr(color)) else: self.addnstr("%s" % tab.name, width - 4, to_curses_attr(color)) separator = to_curses_attr(get_theme().COLOR_VERTICAL_SEPARATOR) self._win.attron(separator) - self._win.vline(0, width-1, curses.ACS_VLINE, height) + self._win.vline(0, width - 1, curses.ACS_VLINE, height) self._win.attroff(separator) self._refresh() diff --git a/poezio/windows/info_wins.py b/poezio/windows/info_wins.py index 1afb34b0..2d4d1e01 100644 --- a/poezio/windows/info_wins.py +++ b/poezio/windows/info_wins.py @@ -13,11 +13,13 @@ from poezio.windows.base_wins import Win from poezio.windows.funcs import truncate_nick from poezio.theming import get_theme, to_curses_attr + class InfoWin(Win): """ Base class for all the *InfoWin, used in various tabs. For example MucInfoWin, etc. Provides some useful methods. """ + def __init__(self): Win.__init__(self) @@ -29,12 +31,15 @@ class InfoWin(Win): """ if window.pos > 0: plus = ' -MORE(%s)-' % window.pos - self.addstr(plus, to_curses_attr(get_theme().COLOR_SCROLLABLE_NUMBER)) + self.addstr(plus, + to_curses_attr(get_theme().COLOR_SCROLLABLE_NUMBER)) + class XMLInfoWin(InfoWin): """ Info about the latest xml filter used and the state of the buffer. """ + def __init__(self): InfoWin.__init__(self) @@ -51,11 +56,13 @@ class XMLInfoWin(InfoWin): self.finish_line(get_theme().COLOR_INFORMATION_BAR) self._refresh() + class PrivateInfoWin(InfoWin): """ The line above the information window, displaying information about the MUC user we are talking to """ + def __init__(self): InfoWin.__init__(self) @@ -75,7 +82,8 @@ class PrivateInfoWin(InfoWin): value returned by the callbacks. """ for key in information: - self.addstr(information[key](jid), to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + self.addstr(information[key](jid), + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) def write_room_name(self, name): jid = safeJID(name) @@ -86,13 +94,16 @@ class PrivateInfoWin(InfoWin): def write_chatstate(self, state): if state: - self.addstr(' %s' % (state,), to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + self.addstr(' %s' % (state, ), + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + class MucListInfoWin(InfoWin): """ The live above the information window, displaying informatios about the muc server being listed """ + def __init__(self, message=''): InfoWin.__init__(self) self.message = message @@ -101,14 +112,17 @@ class MucListInfoWin(InfoWin): log.debug('Refresh: %s', self.__class__.__name__) self._win.erase() if name: - self.addstr(name, to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + self.addstr(name, + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) else: - self.addstr(self.message, to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + self.addstr(self.message, + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) if window: self.print_scroll_position(window) self.finish_line(get_theme().COLOR_INFORMATION_BAR) self._refresh() + class ConversationInfoWin(InfoWin): """ The line above the information window, displaying information @@ -154,7 +168,7 @@ class ConversationInfoWin(InfoWin): """ for key in information: self.addstr(information[key](jid), - to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) def write_resource_information(self, resource): """ @@ -171,7 +185,8 @@ class ConversationInfoWin(InfoWin): self.addstr(presence, to_curses_attr(color)) if resource and resource.status: shortened = resource.status[:20] + (resource.status[:20] and '…') - self.addstr(' %s' % shortened, to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + self.addstr(' %s' % shortened, + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) self.addstr(']', to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) def write_contact_information(self, contact): @@ -179,23 +194,28 @@ class ConversationInfoWin(InfoWin): Write the information about the contact """ if not contact: - self.addstr("(contact not in roster)", to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + self.addstr("(contact not in roster)", + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) return display_name = contact.name if display_name: - self.addstr('%s '%(display_name), to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + self.addstr('%s ' % (display_name), + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) def write_contact_jid(self, jid): """ Just write the jid that we are talking to """ self.addstr('[', to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) - self.addstr(jid.full, to_curses_attr(get_theme().COLOR_CONVERSATION_NAME)) + self.addstr(jid.full, + to_curses_attr(get_theme().COLOR_CONVERSATION_NAME)) self.addstr('] ', to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) def write_chatstate(self, state): if state: - self.addstr(' %s' % (state,), to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + self.addstr(' %s' % (state, ), + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + class DynamicConversationInfoWin(ConversationInfoWin): def write_contact_jid(self, jid): @@ -203,18 +223,23 @@ class DynamicConversationInfoWin(ConversationInfoWin): Just displays the resource in an other color """ log.debug("write_contact_jid DynamicConversationInfoWin, jid: %s", - jid.resource) + jid.resource) self.addstr('[', to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) - self.addstr(jid.bare, to_curses_attr(get_theme().COLOR_CONVERSATION_NAME)) + self.addstr(jid.bare, + to_curses_attr(get_theme().COLOR_CONVERSATION_NAME)) if jid.resource: - self.addstr("/%s" % (jid.resource,), to_curses_attr(get_theme().COLOR_CONVERSATION_RESOURCE)) + self.addstr("/%s" % (jid.resource, ), + to_curses_attr( + get_theme().COLOR_CONVERSATION_RESOURCE)) self.addstr('] ', to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + class MucInfoWin(InfoWin): """ The line just above the information window, displaying information about the MUC we are viewing """ + def __init__(self): InfoWin.__init__(self) @@ -233,12 +258,15 @@ class MucInfoWin(InfoWin): def write_room_name(self, room): self.addstr('[', to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) - self.addstr(room.name, to_curses_attr(get_theme().COLOR_GROUPCHAT_NAME)) + self.addstr(room.name, + to_curses_attr(get_theme().COLOR_GROUPCHAT_NAME)) self.addstr(']', to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) def write_participants_number(self, room): self.addstr('{', to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) - self.addstr(str(len(room.users)), to_curses_attr(get_theme().COLOR_GROUPCHAT_NAME)) + self.addstr( + str(len(room.users)), + to_curses_attr(get_theme().COLOR_GROUPCHAT_NAME)) self.addstr('} ', to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) def write_disconnected(self, room): @@ -246,7 +274,8 @@ class MucInfoWin(InfoWin): Shows a message if the room is not joined """ if not room.joined: - self.addstr(' -!- Not connected ', to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + self.addstr(' -!- Not connected ', + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) def write_own_nick(self, room): """ @@ -255,7 +284,9 @@ class MucInfoWin(InfoWin): nick = room.own_nick if not nick: return - self.addstr(truncate_nick(nick, 13), to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + self.addstr( + truncate_nick(nick, 13), + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) def write_role(self, room, user): """ @@ -269,10 +300,12 @@ class MucInfoWin(InfoWin): txt += user.role + ')' self.addstr(txt, to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + class ConversationStatusMessageWin(InfoWin): """ The upper bar displaying the status message of the contact """ + def __init__(self): InfoWin.__init__(self) @@ -293,7 +326,9 @@ class ConversationStatusMessageWin(InfoWin): self._refresh() def write_status_message(self, resource): - self.addstr(resource.status, to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + self.addstr(resource.status, + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + class BookmarksInfoWin(InfoWin): def __init__(self): @@ -307,7 +342,9 @@ class BookmarksInfoWin(InfoWin): self._refresh() def write_remote_status(self, preferred): - self.addstr('Remote storage: %s' % preferred, to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + self.addstr('Remote storage: %s' % preferred, + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + class ConfirmStatusWin(Win): def __init__(self, text, critical=False): @@ -326,4 +363,3 @@ class ConfirmStatusWin(Win): self.addstr(self.text, c_color) self.finish_line(color) self._refresh() - diff --git a/poezio/windows/input_placeholders.py b/poezio/windows/input_placeholders.py index 3ac478fd..47cfac31 100644 --- a/poezio/windows/input_placeholders.py +++ b/poezio/windows/input_placeholders.py @@ -6,7 +6,6 @@ but which are not inputs. import logging log = logging.getLogger(__name__) - from poezio.windows.base_wins import Win from poezio.theming import get_theme, to_curses_attr @@ -17,6 +16,7 @@ class HelpText(Win): Usually used to replace an Input when the tab is in command mode. """ + def __init__(self, text=''): Win.__init__(self) self.txt = text @@ -26,7 +26,8 @@ class HelpText(Win): if txt: self.txt = txt self._win.erase() - self.addstr(0, 0, self.txt[:self.width-1], to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + self.addstr(0, 0, self.txt[:self.width - 1], + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) self.finish_line(get_theme().COLOR_INFORMATION_BAR) self._refresh() diff --git a/poezio/windows/inputs.py b/poezio/windows/inputs.py index faf0125d..0ccd179e 100644 --- a/poezio/windows/inputs.py +++ b/poezio/windows/inputs.py @@ -18,6 +18,7 @@ from poezio.theming import to_curses_attr DEFAULT_ON_INPUT = lambda x: None + class Input(Win): """ The simplest Input possible, provides just a way to edit a single line @@ -31,7 +32,8 @@ class Input(Win): in a very flexible way. """ text_attributes = 'bou1234567t' - clipboard = '' # A common clipboard for all the inputs, this makes + clipboard = '' # A common clipboard for all the inputs, this makes + # it easy cut and paste text between various input def __init__(self): self.key_func = { @@ -59,16 +61,16 @@ class Input(Win): '^?': self.key_backspace, "M-^?": self.delete_word, # '^J': self.add_line_break, - } + } Win.__init__(self) self.text = '' - self.pos = 0 # The position of the “cursor” in the text - # (not only in the view) + self.pos = 0 # The position of the “cursor” in the text + # (not only in the view) self.view_pos = 0 # The position (in the text) of the - # first character displayed on the - # screen - self.on_input = DEFAULT_ON_INPUT # callback called on any key pressed - self.color = None # use this color on addstr + # first character displayed on the + # screen + self.on_input = DEFAULT_ON_INPUT # callback called on any key pressed + self.color = None # use this color on addstr def on_delete(self): """ @@ -101,10 +103,10 @@ class Input(Win): """ if self.pos == 0: return True - separators = string.punctuation+' ' - while self.pos > 0 and self.text[self.pos-1] in separators: + separators = string.punctuation + ' ' + while self.pos > 0 and self.text[self.pos - 1] in separators: self.key_left() - while self.pos > 0 and self.text[self.pos-1] not in separators: + while self.pos > 0 and self.text[self.pos - 1] not in separators: self.key_left() return True @@ -114,10 +116,11 @@ class Input(Win): """ if self.is_cursor_at_end(): return True - separators = string.punctuation+' ' + separators = string.punctuation + ' ' while not self.is_cursor_at_end() and self.text[self.pos] in separators: self.key_right() - while not self.is_cursor_at_end() and self.text[self.pos] not in separators: + while not self.is_cursor_at_end() and self.text[self. + pos] not in separators: self.key_right() return True @@ -125,10 +128,10 @@ class Input(Win): """ Delete the word just before the cursor """ - separators = string.punctuation+' ' - while self.pos > 0 and self.text[self.pos-1] in separators: + separators = string.punctuation + ' ' + while self.pos > 0 and self.text[self.pos - 1] in separators: self.key_backspace() - while self.pos > 0 and self.text[self.pos-1] not in separators: + while self.pos > 0 and self.text[self.pos - 1] not in separators: self.key_backspace() return True @@ -136,10 +139,11 @@ class Input(Win): """ Delete the word just after the cursor """ - separators = string.punctuation+' ' + separators = string.punctuation + ' ' while not self.is_cursor_at_end() and self.text[self.pos] in separators: self.key_dc() - while not self.is_cursor_at_end() and self.text[self.pos] not in separators: + while not self.is_cursor_at_end() and self.text[self. + pos] not in separators: self.key_dc() return True @@ -182,8 +186,8 @@ class Input(Win): """ self.reset_completion() if self.is_cursor_at_end(): - return True # end of line, nothing to delete - self.text = self.text[:self.pos]+self.text[self.pos+1:] + return True # end of line, nothing to delete + self.text = self.text[:self.pos] + self.text[self.pos + 1:] self.rewrite_text() return True @@ -257,7 +261,12 @@ class Input(Win): self.normal_completion(word_list, add_after) return True - def new_completion(self, word_list, argument_position=-1, add_after='', quotify=True, override=False): + def new_completion(self, + word_list, + argument_position=-1, + add_after='', + quotify=True, + override=False): """ Complete the argument at position ``argument_postion`` in the input. If ``quotify`` is ``True``, then the completion will operate on block of words @@ -277,11 +286,17 @@ class Input(Win): if argument_position == 0: self._new_completion_first(word_list) else: - self._new_completion_args(word_list, argument_position, add_after, quotify, override) + self._new_completion_args(word_list, argument_position, add_after, + quotify, override) self.rewrite_text() return True - def _new_completion_args(self, word_list, argument_position=-1, add_after='', quoted=True, override=False): + def _new_completion_args(self, + word_list, + argument_position=-1, + add_after='', + quoted=True, + override=False): """ Case for completing arguments with position ≠ 0 """ @@ -319,12 +334,12 @@ class Input(Win): if argument_position >= len(words): if quoted and ' ' in self.hit_list[0]: - words.append('"'+self.hit_list[0]+'"') + words.append('"' + self.hit_list[0] + '"') else: words.append(self.hit_list[0]) else: if quoted and ' ' in self.hit_list[0]: - words[argument_position] = '"'+self.hit_list[0]+'"' + words[argument_position] = '"' + self.hit_list[0] + '"' else: words[argument_position] = self.hit_list[0] @@ -370,7 +385,7 @@ class Input(Win): command_stop = self.text.find(' ') if command_stop == -1 or self.pos <= command_stop: return 0 - text = self.text[command_stop+1:] + text = self.text[command_stop + 1:] pos = self.pos - len(self.text) + len(text) - 1 val = common.find_argument(pos, text, quoted=quoted) + 1 return val @@ -387,19 +402,22 @@ class Input(Win): Normal completion """ pos = self.pos - if pos < len(self.text) and after.endswith(' ') and self.text[pos] == ' ': - after = after[:-1] # remove the last space if we are already on a space + if pos < len( + self.text) and after.endswith(' ') and self.text[pos] == ' ': + after = after[: + -1] # remove the last space if we are already on a space if not self.last_completion: space_before_cursor = self.text.rfind(' ', 0, pos) if space_before_cursor != -1: - begin = self.text[space_before_cursor+1:pos] + begin = self.text[space_before_cursor + 1:pos] else: begin = self.text[:pos] - hit_list = [] # list of matching hits + hit_list = [] # list of matching hits for word in word_list: if word.lower().startswith(begin.lower()): hit_list.append(word) - elif word.startswith('"') and word.lower()[1:].startswith(begin.lower()): + elif word.startswith('"') and word.lower()[1:].startswith( + begin.lower()): hit_list.append(word) if len(hit_list) == 0: return @@ -408,11 +426,11 @@ class Input(Win): else: begin = self.last_completion end = len(begin) + len(after) - self.hit_list.append(self.hit_list.pop(0)) # rotate list + self.hit_list.append(self.hit_list.pop(0)) # rotate list - self.text = self.text[:pos-end] + self.text[pos:] + self.text = self.text[:pos - end] + self.text[pos:] pos -= end - hit = self.hit_list[0] # take the first hit + hit = self.hit_list[0] # take the first hit self.text = self.text[:pos] + hit + after + self.text[pos:] for _ in range(end): try: @@ -432,11 +450,11 @@ class Input(Win): self.on_input(self.get_text()) return res if not raw and (not key or len(key) > 1): - return False # ignore non-handled keyboard shortcuts + return False # ignore non-handled keyboard shortcuts if reset: self.reset_completion() # Insert the char at the cursor position - self.text = self.text[:self.pos]+key+self.text[self.pos:] + self.text = self.text[:self.pos] + key + self.text[self.pos:] self.pos += len(key) if reset: self.rewrite_text() @@ -472,11 +490,11 @@ class Input(Win): if text[format_char] == '\n': attr_char = '|' else: - attr_char = self.text_attributes[ - format_chars.index(text[format_char])] + attr_char = self.text_attributes[format_chars.index( + text[format_char])] self.addstr(text[:format_char]) self.addstr(attr_char, curses.A_REVERSE) - text = text[format_char+1:] + text = text[format_char + 1:] if attr_char == 'o': self._win.attrset(0) elif attr_char == 'u': @@ -503,7 +521,9 @@ class Input(Win): self._win.erase() if self.color: self._win.attron(to_curses_attr(self.color)) - displayed_text = text[self.view_pos:self.view_pos+self.width-1].replace('\t', '\x18') + displayed_text = text[self.view_pos: + self.view_pos + self.width - 1].replace( + '\t', '\x18') self._win.attrset(0) self._addstr_colored_lite(displayed_text) # Fill the rest of the line with the input color @@ -512,7 +532,8 @@ class Input(Win): size = self.width - x self.addnstr(' ' * size, size, to_curses_attr(self.color)) self.addstr(0, - poopt.wcswidth(displayed_text[:self.pos-self.view_pos]), '') + poopt.wcswidth(displayed_text[:self.pos - self.view_pos]), + '') if self.color: self._win.attroff(to_curses_attr(self.color)) curses.curs_set(1) @@ -557,6 +578,7 @@ class Input(Win): self.clear_text() return txt + class HistoryInput(Input): """ An input with colors and stuff, plus an history @@ -641,13 +663,14 @@ class HistoryInput(Input): self.key_end() return True + class MessageInput(HistoryInput): """ The input featuring history and that is being used in Conversation, Muc and Private tabs Also letting the user enter colors or other text markups """ - history = list() # The history is common to all MessageInput + history = list() # The history is common to all MessageInput def __init__(self): HistoryInput.__init__(self) @@ -662,11 +685,13 @@ class MessageInput(HistoryInput): """ Read one more char (c), add the corresponding char from formats_char to the text string """ + def cb(attr_char): if attr_char in self.text_attributes: char = format_chars[self.text_attributes.index(attr_char)] self.do_command(char, False) self.rewrite_text() + keyboard.continuation_keys_callback = cb def key_enter(self): @@ -682,6 +707,7 @@ class MessageInput(HistoryInput): self.clear_text() return txt + class CommandInput(HistoryInput): """ An input with an help message in the left, with three given callbacks: @@ -769,4 +795,3 @@ class CommandInput(HistoryInput): # add the message to history, but avoid duplicates self.history.insert(0, txt) self.histo_pos = -1 - diff --git a/poezio/windows/list.py b/poezio/windows/list.py index c0dc44cf..1f51e88f 100644 --- a/poezio/windows/list.py +++ b/poezio/windows/list.py @@ -16,12 +16,13 @@ class ListWin(Win): A list (with no depth, so not for the roster) that can be scrolled up and down, with one selected line at a time """ + def __init__(self, columns, with_headers=True): Win.__init__(self) - self._columns = columns # a dict {'column_name': tuple_index} - self._columns_sizes = {} # a dict {'column_name': size} - self.sorted_by = (None, None) # for example: ('name', '↑') - self.lines = [] # a list of dicts + self._columns = columns # a dict {'column_name': tuple_index} + self._columns_sizes = {} # a dict {'column_name': size} + self.sorted_by = (None, None) # for example: ('name', '↑') + self.lines = [] # a list of dicts self._selected_row = 0 self._starting_pos = 0 # The column number from which we start the refresh @@ -55,8 +56,8 @@ class ListWin(Win): elif asc: self.lines.sort(key=lambda x: x[self._columns[col_name]]) else: - self.lines.sort(key=lambda x: x[self._columns[col_name]], - reverse=True) + self.lines.sort( + key=lambda x: x[self._columns[col_name]], reverse=True) self.refresh() curses.doupdate() @@ -87,7 +88,7 @@ class ListWin(Win): def refresh(self): log.debug('Refresh: %s', self.__class__.__name__) self._win.erase() - lines = self.lines[self._starting_pos:self._starting_pos+self.height] + lines = self.lines[self._starting_pos:self._starting_pos + self.height] for y, line in enumerate(lines): x = 0 for col in self._columns.items(): @@ -96,12 +97,13 @@ class ListWin(Win): except KeyError: txt = '' size = self._columns_sizes[col[0]] - txt += ' ' * (size-len(txt)) + txt += ' ' * (size - len(txt)) if not txt: continue if line is self.lines[self._selected_row]: self.addstr(y, x, txt[:size], - to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + to_curses_attr( + get_theme().COLOR_INFORMATION_BAR)) else: self.addstr(y, x, txt[:size]) x += size @@ -138,7 +140,7 @@ class ListWin(Win): return self._selected_row += self.height if self._selected_row > len(self.lines) - 1: - self._selected_row = len(self.lines) -1 + self._selected_row = len(self.lines) - 1 while self._selected_row >= self._starting_pos + self.height: self._starting_pos += self.height // 2 if self._starting_pos < 0: @@ -155,10 +157,12 @@ class ListWin(Win): self._starting_pos -= self.height // 2 return True + class ColumnHeaderWin(Win): """ A class displaying the column's names """ + def __init__(self, columns): Win.__init__(self) self._columns = columns @@ -186,11 +190,14 @@ class ColumnHeaderWin(Win): txt += get_theme().CHAR_COLUMN_DESC #⇓⇑↑↓⇧⇩▲▼ size = self._columns_sizes[col] - txt += ' ' * (size-len(txt)) + txt += ' ' * (size - len(txt)) if col in self._column_sel: - self.addstr(0, x, txt, to_curses_attr(get_theme().COLOR_COLUMN_HEADER_SEL)) + self.addstr(0, x, txt, + to_curses_attr( + get_theme().COLOR_COLUMN_HEADER_SEL)) else: - self.addstr(0, x, txt, to_curses_attr(get_theme().COLOR_COLUMN_HEADER)) + self.addstr(0, x, txt, + to_curses_attr(get_theme().COLOR_COLUMN_HEADER)) x += size self._refresh() @@ -214,7 +221,7 @@ class ColumnHeaderWin(Win): if self._column_sel in self._columns: index = self._columns.index(self._column_sel) if index > 1: - index = index -1 + index = index - 1 else: index = 0 else: @@ -225,12 +232,11 @@ class ColumnHeaderWin(Win): def sel_column_right(self): if self._column_sel in self._columns: index = self._columns.index(self._column_sel) - if index < len(self._columns)-2: - index = index +1 + if index < len(self._columns) - 2: + index = index + 1 else: - index = len(self._columns) -1 + index = len(self._columns) - 1 else: index = len(self._columns) - 1 self._column_sel = self._columns[index] self.refresh() - diff --git a/poezio/windows/misc.py b/poezio/windows/misc.py index d3d6783e..71027b7c 100644 --- a/poezio/windows/misc.py +++ b/poezio/windows/misc.py @@ -10,11 +10,13 @@ import curses from poezio.windows.base_wins import Win from poezio.theming import get_theme, to_curses_attr + class VerticalSeparator(Win): """ Just a one-column window, with just a line in it, that is refreshed only on resize, but never on refresh, for efficiency """ + def rewrite_line(self): self._win.vline(0, 0, curses.ACS_VLINE, self.height, to_curses_attr(get_theme().COLOR_VERTICAL_SEPARATOR)) @@ -54,4 +56,3 @@ class SimpleTextWin(Win): for y, line in enumerate(self.built_lines): self.addstr_colored(line, y, 0) self._refresh() - diff --git a/poezio/windows/muc.py b/poezio/windows/muc.py index 553a2cfa..4251c279 100644 --- a/poezio/windows/muc.py +++ b/poezio/windows/muc.py @@ -13,12 +13,15 @@ from poezio import poopt from poezio.config import config from poezio.theming import to_curses_attr, get_theme + def userlist_to_cache(userlist): result = [] for user in userlist: - result.append((user.nick, user.status, user.chatstate, user.affiliation, user.role)) + result.append((user.nick, user.status, user.chatstate, + user.affiliation, user.role)) return result + class UserList(Win): def __init__(self): Win.__init__(self) @@ -26,23 +29,23 @@ class UserList(Win): self.cache = [] def scroll_up(self): - self.pos += self.height-1 + self.pos += self.height - 1 return True def scroll_down(self): pos = self.pos - self.pos -= self.height-1 + self.pos -= self.height - 1 if self.pos < 0: self.pos = 0 return self.pos != pos def draw_plus(self, y): - self.addstr(y, self.width-2, '++', to_curses_attr(get_theme().COLOR_MORE_INDICATOR)) - + self.addstr(y, self.width - 2, '++', + to_curses_attr(get_theme().COLOR_MORE_INDICATOR)) def refresh_if_changed(self, users): old = self.cache - new = userlist_to_cache(users[self.pos:self.pos+self.height]) + new = userlist_to_cache(users[self.pos:self.pos + self.height]) if len(old) != len(new): self.cache = new self.refresh(users) @@ -56,7 +59,7 @@ class UserList(Win): def refresh(self, users): log.debug('Refresh: %s', self.__class__.__name__) if config.get('hide_user_list'): - return # do not refresh if this win is hidden. + return # do not refresh if this win is hidden. if len(users) < self.height: self.pos = 0 elif self.pos >= len(users) - self.height and self.pos != 0: @@ -69,12 +72,12 @@ class UserList(Win): else: y = 0 - for user in users[self.pos:self.pos+self.height]: + for user in users[self.pos:self.pos + self.height]: self.draw_role_affiliation(y, user) self.draw_status_chatstate(y, user) self.addstr(y, 2, - poopt.cut_by_columns(user.nick, self.width - 2), - to_curses_attr(user.color)) + poopt.cut_by_columns(user.nick, self.width - 2), + to_curses_attr(user.color)) if asc_sort: y -= 1 else: @@ -84,14 +87,14 @@ class UserList(Win): # draw indicators of position in the list if self.pos > 0: if asc_sort: - self.draw_plus(self.height-1) + self.draw_plus(self.height - 1) else: self.draw_plus(0) if self.pos + self.height < len(users): if asc_sort: self.draw_plus(0) else: - self.draw_plus(self.height-1) + self.draw_plus(self.height - 1) self._refresh() def draw_role_affiliation(self, y, user): @@ -119,6 +122,7 @@ class UserList(Win): self._win.vline(0, 0, curses.ACS_VLINE, self.height) self._win.attroff(separator) + class Topic(Win): def __init__(self): Win.__init__(self) @@ -128,17 +132,16 @@ class Topic(Win): log.debug('Refresh: %s', self.__class__.__name__) self._win.erase() if topic: - msg = topic[:self.width-1] + msg = topic[:self.width - 1] else: - msg = self._message[:self.width-1] + msg = self._message[:self.width - 1] self.addstr(0, 0, msg, to_curses_attr(get_theme().COLOR_TOPIC_BAR)) _, x = self._win.getyx() remaining_size = self.width - x if remaining_size: - self.addnstr(' '*remaining_size, remaining_size, + self.addnstr(' ' * remaining_size, remaining_size, to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) self._refresh() def set_message(self, message): self._message = message - diff --git a/poezio/windows/roster_win.py b/poezio/windows/roster_win.py index 73191e84..7b1e5ba7 100644 --- a/poezio/windows/roster_win.py +++ b/poezio/windows/roster_win.py @@ -17,11 +17,10 @@ from poezio.theming import get_theme, to_curses_attr class RosterWin(Win): - def __init__(self): Win.__init__(self) - self.pos = 0 # cursor position in the contact list - self.start_pos = 1 # position of the start of the display + self.pos = 0 # cursor position in the contact list + self.start_pos = 1 # position of the start of the display self.selected_row = None self.roster_cache = [] @@ -34,15 +33,15 @@ class RosterWin(Win): Return True if we scrolled, False otherwise """ pos = self.pos - if self.pos < self.roster_len-number: + if self.pos < self.roster_len - number: self.pos += number else: self.pos = self.roster_len - 1 - if self.pos >= self.start_pos-1 + self.height-1: + if self.pos >= self.start_pos - 1 + self.height - 1: if number == 1: self.scroll_down(8) else: - self.scroll_down(self.pos-self.start_pos - self.height // 2) + self.scroll_down(self.pos - self.start_pos - self.height // 2) self.update_pos() return pos != self.pos @@ -51,7 +50,7 @@ class RosterWin(Win): Return True if we scrolled, False otherwise """ pos = self.pos - if self.pos-number >= 0: + if self.pos - number >= 0: self.pos -= number else: self.pos = 0 @@ -59,7 +58,7 @@ class RosterWin(Win): if number == 1: self.scroll_up(8) else: - self.scroll_up(self.start_pos-self.pos + self.height // 2) + self.scroll_up(self.start_pos - self.pos + self.height // 2) self.update_pos() return pos != self.pos @@ -71,10 +70,10 @@ class RosterWin(Win): def scroll_down(self, number=8): pos = self.start_pos - if self.start_pos + number <= self.roster_len-1: + if self.start_pos + number <= self.roster_len - 1: self.start_pos += number else: - self.start_pos = self.roster_len-1 + self.start_pos = self.roster_len - 1 return self.start_pos != pos def scroll_up(self, number=8): @@ -106,21 +105,23 @@ class RosterWin(Win): # build the cache for group in roster.get_groups(group_sort): contacts_filtered = group.get_contacts() - if (not show_offline and group.get_nb_connected_contacts() == 0) or not contacts_filtered: - continue # Ignore empty groups + if (not show_offline and group.get_nb_connected_contacts() == 0 + ) or not contacts_filtered: + continue # Ignore empty groups self.roster_cache.append(group) if group.folded: - continue # ignore folded groups + continue # ignore folded groups for contact in group.get_contacts(sort=sort): if not show_offline and len(contact) == 0: - continue # ignore offline contacts + continue # ignore offline contacts self.roster_cache.append(contact) if not contact.folded(group.name): for resource in contact.get_resources(): self.roster_cache.append(resource) roster.last_built = datetime.now() if self.selected_row in self.roster_cache: - if self.pos < self.roster_len and self.roster_cache[self.pos] != self.selected_row: + if self.pos < self.roster_len and self.roster_cache[self. + pos] != self.selected_row: self.pos = self.roster_cache.index(self.selected_row) def refresh(self, roster): @@ -131,7 +132,8 @@ class RosterWin(Win): log.debug('Refresh: %s', self.__class__.__name__) self.build_roster_cache(roster) # make sure we are within bounds - self.move_cursor_up((self.roster_len + self.pos) if self.pos >= self.roster_len else 0) + self.move_cursor_up((self.roster_len + self.pos) + if self.pos >= self.roster_len else 0) if not self.roster_cache: self.selected_row = None self._win.erase() @@ -140,10 +142,12 @@ class RosterWin(Win): y = 1 group = "none" # scroll down if needed - if self.start_pos+self.height <= self.pos+2: - self.scroll_down(self.pos - self.start_pos - self.height + (self.height//2)) + if self.start_pos + self.height <= self.pos + 2: + self.scroll_down(self.pos - self.start_pos - self.height + + (self.height // 2)) # draw the roster from the cache - roster_view = self.roster_cache[self.start_pos-1:self.start_pos+self.height] + roster_view = self.roster_cache[self.start_pos - 1: + self.start_pos + self.height] options = { 'show_roster_sub': config.get('show_roster_subscriptions'), @@ -153,7 +157,7 @@ class RosterWin(Win): for item in roster_view: draw_selected = False - if y -2 + self.start_pos == self.pos: + if y - 2 + self.start_pos == self.pos: draw_selected = True self.selected_row = item @@ -161,7 +165,8 @@ class RosterWin(Win): self.draw_group(y, item, draw_selected) group = item.name elif isinstance(item, Contact): - self.draw_contact_line(y, item, draw_selected, group, **options) + self.draw_contact_line(y, item, draw_selected, group, + **options) elif isinstance(item, Resource): self.draw_resource_line(y, item, draw_selected) @@ -169,26 +174,25 @@ class RosterWin(Win): if self.start_pos > 1: self.draw_plus(1) - if self.start_pos + self.height-2 < self.roster_len: - self.draw_plus(self.height-1) + if self.start_pos + self.height - 2 < self.roster_len: + self.draw_plus(self.height - 1) self._refresh() - def draw_plus(self, y): """ Draw the indicator that shows that the list is longer than what is displayed """ - self.addstr(y, self.width-5, '++++', to_curses_attr(get_theme().COLOR_MORE_INDICATOR)) + self.addstr(y, self.width - 5, '++++', + to_curses_attr(get_theme().COLOR_MORE_INDICATOR)) def draw_roster_information(self, roster): """ The header at the top """ - self.addstr('Roster: %s/%s contacts' % ( - roster.get_nb_connected_contacts(), - len(roster)), - to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + self.addstr('Roster: %s/%s contacts' % + (roster.get_nb_connected_contacts(), len(roster)), + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) self.finish_line(get_theme().COLOR_INFORMATION_BAR) def draw_group(self, y, group, colored): @@ -202,7 +206,8 @@ class RosterWin(Win): else: self.addstr(y, 0, '[-] ') contacts = " (%s/%s)" % (group.get_nb_connected_contacts(), len(group)) - self.addstr(y, 4, self.truncate_name(group.name, len(contacts)+4) + contacts) + self.addstr( + y, 4, self.truncate_name(group.name, len(contacts) + 4) + contacts) if colored: self._win.attroff(to_curses_attr(get_theme().COLOR_SELECTED_ROW)) self.finish_line() @@ -212,8 +217,14 @@ class RosterWin(Win): return name return name[:self.width - added - 1] + '…' - def draw_contact_line(self, y, contact, colored, group, show_roster_sub=False, - show_s2s_errors=True, show_roster_jids=False): + def draw_contact_line(self, + y, + contact, + colored, + group, + show_roster_sub=False, + show_s2s_errors=True, + show_roster_jids=False): """ Draw on a line all information about one contact. This is basically the highest priority resource's information @@ -255,37 +266,51 @@ class RosterWin(Win): added += len(get_theme().CHAR_ROSTER_ACTIVITY) if contact.gaming: added += len(get_theme().CHAR_ROSTER_GAMING) - if show_roster_sub in ('all', 'incomplete', 'to', 'from', 'both', 'none'): - added += len(theme.char_subscription(contact.subscription, keep=show_roster_sub)) + if show_roster_sub in ('all', 'incomplete', 'to', 'from', 'both', + 'none'): + added += len( + theme.char_subscription( + contact.subscription, keep=show_roster_sub)) if not show_roster_jids and contact.name: display_name = '%s' % contact.name elif contact.name and contact.name != contact.bare_jid: display_name = '%s (%s)' % (contact.name, contact.bare_jid) else: - display_name = '%s' % (contact.bare_jid,) + display_name = '%s' % (contact.bare_jid, ) display_name = self.truncate_name(display_name, added) + nb if colored: - self.addstr(display_name, to_curses_attr(get_theme().COLOR_SELECTED_ROW)) + self.addstr(display_name, + to_curses_attr(get_theme().COLOR_SELECTED_ROW)) else: self.addstr(display_name) - if show_roster_sub in ('all', 'incomplete', 'to', 'from', 'both', 'none'): - self.addstr(theme.char_subscription(contact.subscription, keep=show_roster_sub), to_curses_attr(theme.COLOR_ROSTER_SUBSCRIPTION)) + if show_roster_sub in ('all', 'incomplete', 'to', 'from', 'both', + 'none'): + self.addstr( + theme.char_subscription( + contact.subscription, keep=show_roster_sub), + to_curses_attr(theme.COLOR_ROSTER_SUBSCRIPTION)) if contact.ask: - self.addstr(get_theme().CHAR_ROSTER_ASKED, to_curses_attr(get_theme().COLOR_IMPORTANT_TEXT)) + self.addstr(get_theme().CHAR_ROSTER_ASKED, + to_curses_attr(get_theme().COLOR_IMPORTANT_TEXT)) if show_s2s_errors and contact.error: - self.addstr(get_theme().CHAR_ROSTER_ERROR, to_curses_attr(get_theme().COLOR_ROSTER_ERROR)) + self.addstr(get_theme().CHAR_ROSTER_ERROR, + to_curses_attr(get_theme().COLOR_ROSTER_ERROR)) if contact.tune: - self.addstr(get_theme().CHAR_ROSTER_TUNE, to_curses_attr(get_theme().COLOR_ROSTER_TUNE)) + self.addstr(get_theme().CHAR_ROSTER_TUNE, + to_curses_attr(get_theme().COLOR_ROSTER_TUNE)) if contact.activity: - self.addstr(get_theme().CHAR_ROSTER_ACTIVITY, to_curses_attr(get_theme().COLOR_ROSTER_ACTIVITY)) + self.addstr(get_theme().CHAR_ROSTER_ACTIVITY, + to_curses_attr(get_theme().COLOR_ROSTER_ACTIVITY)) if contact.mood: - self.addstr(get_theme().CHAR_ROSTER_MOOD, to_curses_attr(get_theme().COLOR_ROSTER_MOOD)) + self.addstr(get_theme().CHAR_ROSTER_MOOD, + to_curses_attr(get_theme().COLOR_ROSTER_MOOD)) if contact.gaming: - self.addstr(get_theme().CHAR_ROSTER_GAMING, to_curses_attr(get_theme().COLOR_ROSTER_GAMING)) + self.addstr(get_theme().CHAR_ROSTER_GAMING, + to_curses_attr(get_theme().COLOR_ROSTER_GAMING)) self.finish_line() def draw_resource_line(self, y, resource, colored): @@ -295,7 +320,9 @@ class RosterWin(Win): color = get_theme().color_show(resource.presence) self.addstr(y, 4, get_theme().CHAR_STATUS, to_curses_attr(color)) if colored: - self.addstr(y, 8, self.truncate_name(str(resource.jid), 6), to_curses_attr(get_theme().COLOR_SELECTED_ROW)) + self.addstr(y, 8, + self.truncate_name(str(resource.jid), 6), + to_curses_attr(get_theme().COLOR_SELECTED_ROW)) else: self.addstr(y, 8, self.truncate_name(str(resource.jid), 6)) self.finish_line() @@ -308,6 +335,7 @@ class RosterWin(Win): return self.roster_cache[self.pos] return None + class ContactInfoWin(Win): def draw_contact_info(self, contact): """ @@ -319,23 +347,27 @@ class ContactInfoWin(Win): elif resource: jid = resource.jid else: - jid = 'example@example.com' # should never happen + jid = 'example@example.com' # should never happen if resource: presence = resource.presence else: presence = 'unavailable' i = 0 - self.addstr(0, 0, '%s (%s)'%(jid, presence,), to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + self.addstr(0, 0, '%s (%s)' % ( + jid, + presence, + ), to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) self.finish_line(get_theme().COLOR_INFORMATION_BAR) i += 1 - self.addstr(i, 0, 'Subscription: %s' % (contact.subscription,)) + self.addstr(i, 0, 'Subscription: %s' % (contact.subscription, )) self.finish_line() i += 1 if contact.ask: if contact.ask == 'asked': - self.addstr(i, 0, 'Ask: %s' % (contact.ask,), to_curses_attr(get_theme().COLOR_IMPORTANT_TEXT)) + self.addstr(i, 0, 'Ask: %s' % (contact.ask, ), + to_curses_attr(get_theme().COLOR_IMPORTANT_TEXT)) else: - self.addstr(i, 0, 'Ask: %s' % (contact.ask,)) + self.addstr(i, 0, 'Ask: %s' % (contact.ask, )) self.finish_line() i += 1 if resource: @@ -344,27 +376,34 @@ class ContactInfoWin(Win): i += 1 if contact.error: - self.addstr(i, 0, 'Error: %s' % contact.error, to_curses_attr(get_theme().COLOR_ROSTER_ERROR)) + self.addstr(i, 0, 'Error: %s' % contact.error, + to_curses_attr(get_theme().COLOR_ROSTER_ERROR)) self.finish_line() i += 1 if contact.tune: - self.addstr(i, 0, 'Tune: %s' % common.format_tune_string(contact.tune), to_curses_attr(get_theme().COLOR_NORMAL_TEXT)) + self.addstr(i, 0, + 'Tune: %s' % common.format_tune_string(contact.tune), + to_curses_attr(get_theme().COLOR_NORMAL_TEXT)) self.finish_line() i += 1 if contact.mood: - self.addstr(i, 0, 'Mood: %s' % contact.mood, to_curses_attr(get_theme().COLOR_NORMAL_TEXT)) + self.addstr(i, 0, 'Mood: %s' % contact.mood, + to_curses_attr(get_theme().COLOR_NORMAL_TEXT)) self.finish_line() i += 1 if contact.activity: - self.addstr(i, 0, 'Activity: %s' % contact.activity, to_curses_attr(get_theme().COLOR_NORMAL_TEXT)) + self.addstr(i, 0, 'Activity: %s' % contact.activity, + to_curses_attr(get_theme().COLOR_NORMAL_TEXT)) self.finish_line() i += 1 if contact.gaming: - self.addstr(i, 0, 'Game: %s' % common.format_gaming_string(contact.gaming), to_curses_attr(get_theme().COLOR_NORMAL_TEXT)) + self.addstr( + i, 0, 'Game: %s' % common.format_gaming_string(contact.gaming), + to_curses_attr(get_theme().COLOR_NORMAL_TEXT)) self.finish_line() i += 1 @@ -372,7 +411,8 @@ class ContactInfoWin(Win): """ draw the group information """ - self.addstr(0, 0, group.name, to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + self.addstr(0, 0, group.name, + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) self.finish_line(get_theme().COLOR_INFORMATION_BAR) def refresh(self, selected_row): diff --git a/poezio/windows/text_win.py b/poezio/windows/text_win.py index 4b16043d..1521ee34 100644 --- a/poezio/windows/text_win.py +++ b/poezio/windows/text_win.py @@ -21,6 +21,7 @@ from poezio.theming import to_curses_attr, get_theme, dump_tuple # text_end are the position delimiting the text in this line. class Line: __slots__ = ('msg', 'start_pos', 'end_pos', 'prepend') + def __init__(self, msg, start_pos, end_pos, prepend): self.msg = msg self.start_pos = start_pos @@ -35,7 +36,7 @@ class BaseTextWin(Win): Win.__init__(self) self.lines_nb_limit = lines_nb_limit self.pos = 0 - self.built_lines = [] # Each new message is built and kept here. + self.built_lines = [] # Each new message is built and kept here. # on resize, we rebuild all the messages self.lock = False @@ -73,13 +74,20 @@ class BaseTextWin(Win): self.pos = 0 return self.pos != pos - def build_new_message(self, message, history=None, clean=True, highlight=False, timestamp=False, nick_size=10): + def build_new_message(self, + message, + history=None, + clean=True, + highlight=False, + timestamp=False, + nick_size=10): """ Take one message, build it and add it to the list Return the number of lines that are built for the given message. """ - lines = self.build_message(message, timestamp=timestamp, nick_size=nick_size) + lines = self.build_message( + message, timestamp=timestamp, nick_size=nick_size) if self.lock: self.lock_buffer.extend(lines) else: @@ -143,16 +151,22 @@ class BaseTextWin(Win): with_timestamps = config.get('show_timestamps') nick_size = config.get('max_nick_length') for message in room.messages: - self.build_new_message(message, clean=False, timestamp=with_timestamps, nick_size=nick_size) + self.build_new_message( + message, + clean=False, + timestamp=with_timestamps, + nick_size=nick_size) if self.separator_after is message: self.build_new_message(None) while len(self.built_lines) > self.lines_nb_limit: self.built_lines.pop(0) def __del__(self): - log.debug('** TextWin: deleting %s built lines', (len(self.built_lines))) + log.debug('** TextWin: deleting %s built lines', + (len(self.built_lines))) del self.built_lines + class TextWin(BaseTextWin): def __init__(self, lines_nb_limit=None): BaseTextWin.__init__(self, lines_nb_limit) @@ -179,8 +193,8 @@ class TextWin(BaseTextWin): highlights, scroll to the end of the buffer. """ log.debug('Going to the next highlight…') - if (not self.highlights or self.hl_pos != self.hl_pos or - self.hl_pos >= len(self.highlights) - 1): + if (not self.highlights or self.hl_pos != self.hl_pos + or self.hl_pos >= len(self.highlights) - 1): self.hl_pos = float('nan') self.pos = 0 return @@ -196,7 +210,7 @@ class TextWin(BaseTextWin): try: pos = self.built_lines.index(hl) except ValueError: - self.highlights = self.highlights[self.hl_pos+1:] + self.highlights = self.highlights[self.hl_pos + 1:] if not self.highlights: self.hl_pos = float('nan') self.pos = 0 @@ -230,7 +244,7 @@ class TextWin(BaseTextWin): try: pos = self.built_lines.index(hl) except ValueError: - self.highlights = self.highlights[self.hl_pos+1:] + self.highlights = self.highlights[self.hl_pos + 1:] if not self.highlights: self.hl_pos = float('nan') self.pos = 0 @@ -247,7 +261,8 @@ class TextWin(BaseTextWin): present, scroll at the top of the window """ if None in self.built_lines: - self.pos = len(self.built_lines) - self.built_lines.index(None) - self.height + 1 + self.pos = len(self.built_lines) - self.built_lines.index( + None) - self.height + 1 if self.pos < 0: self.pos = 0 else: @@ -257,7 +272,8 @@ class TextWin(BaseTextWin): # Make “next highlight” work afterwards. This makes it easy to # review all the highlights since the separator was placed, in # the correct order. - self.hl_pos = len(self.highlights) - self.nb_of_highlights_after_separator - 1 + self.hl_pos = len( + self.highlights) - self.nb_of_highlights_after_separator - 1 log.debug("self.hl_pos = %s", self.hl_pos) def remove_line_separator(self): @@ -282,13 +298,20 @@ class TextWin(BaseTextWin): if room and room.messages: self.separator_after = room.messages[-1] - def build_new_message(self, message, history=None, clean=True, highlight=False, timestamp=False, nick_size=10): + def build_new_message(self, + message, + history=None, + clean=True, + highlight=False, + timestamp=False, + nick_size=10): """ Take one message, build it and add it to the list Return the number of lines that are built for the given message. """ - lines = self.build_message(message, timestamp=timestamp, nick_size=nick_size) + lines = self.build_message( + message, timestamp=timestamp, nick_size=nick_size) if self.lock: self.lock_buffer.extend(lines) else: @@ -316,8 +339,8 @@ class TextWin(BaseTextWin): if not txt: return [] if len(message.str_time) > 8: - default_color = (FORMAT_CHAR + dump_tuple(get_theme().COLOR_LOG_MSG) - + '}') + default_color = ( + FORMAT_CHAR + dump_tuple(get_theme().COLOR_LOG_MSG) + '}') else: default_color = None ret = [] @@ -329,11 +352,11 @@ class TextWin(BaseTextWin): else: offset += poopt.wcswidth(get_theme().CHAR_NACK) + 1 if nick: - offset += poopt.wcswidth(nick) + 2 # + nick + '> ' length + offset += poopt.wcswidth(nick) + 2 # + nick + '> ' length if message.revisions > 0: offset += ceil(log10(message.revisions + 1)) if message.me: - offset += 1 # '* ' before and ' ' after + offset += 1 # '* ' before and ' ' after if timestamp: if message.str_time: offset += 1 + len(message.str_time) @@ -341,11 +364,15 @@ class TextWin(BaseTextWin): offset += 1 if get_theme().CHAR_TIME_RIGHT and message.str_time: offset += 1 - lines = poopt.cut_text(txt, self.width-offset-1) + lines = poopt.cut_text(txt, self.width - offset - 1) prepend = default_color if default_color else '' attrs = [] for line in lines: - saved = Line(msg=message, start_pos=line[0], end_pos=line[1], prepend=prepend) + saved = Line( + msg=message, + start_pos=line[0], + end_pos=line[1], + prepend=prepend) attrs = parse_attrs(message.txt[line[0]:line[1]], attrs) if attrs: prepend = FORMAT_CHAR + FORMAT_CHAR.join(attrs) @@ -364,7 +391,7 @@ class TextWin(BaseTextWin): if self.pos == 0: lines = self.built_lines[-self.height:] else: - lines = self.built_lines[-self.height-self.pos:-self.pos] + lines = self.built_lines[-self.height - self.pos:-self.pos] with_timestamps = config.get("show_timestamps") nick_size = config.get("max_nick_length") self._win.move(0, 0) @@ -374,14 +401,17 @@ class TextWin(BaseTextWin): if line: msg = line.msg if line.start_pos == 0: - offset = self.write_pre_msg(msg, with_timestamps, nick_size) + offset = self.write_pre_msg(msg, with_timestamps, + nick_size) elif y == 0: - offset = self.compute_offset(msg, with_timestamps, nick_size) - self.write_text(y, offset, line.prepend - + line.msg.txt[line.start_pos:line.end_pos]) + offset = self.compute_offset(msg, with_timestamps, + nick_size) + self.write_text( + y, offset, + line.prepend + line.msg.txt[line.start_pos:line.end_pos]) else: self.write_line_separator(y) - if y != self.height-1: + if y != self.height - 1: self.addstr('\n') self._win.attrset(0) self._refresh() @@ -391,7 +421,7 @@ class TextWin(BaseTextWin): if with_timestamps and msg.str_time: offset += poopt.wcswidth(msg.str_time) + 1 - if not msg.nickname: # not a message, nothing to do afterwards + if not msg.nickname: # not a message, nothing to do afterwards return offset nick = truncate_nick(msg.nickname, nick_size) @@ -410,13 +440,12 @@ class TextWin(BaseTextWin): offset += self.write_revisions(msg) return offset - def write_pre_msg(self, msg, with_timestamps, nick_size): offset = 0 if with_timestamps: offset += self.write_time(msg.str_time) - if not msg.nickname: # not a message, nothing to do afterwards + if not msg.nickname: # not a message, nothing to do afterwards return offset nick = truncate_nick(msg.nickname, nick_size) @@ -448,7 +477,8 @@ class TextWin(BaseTextWin): def write_revisions(self, msg): if msg.revisions: - self._win.attron(to_curses_attr(get_theme().COLOR_REVISIONS_MESSAGE)) + self._win.attron( + to_curses_attr(get_theme().COLOR_REVISIONS_MESSAGE)) self.addstr('%d' % msg.revisions) self._win.attrset(0) return ceil(log10(msg.revisions + 1)) @@ -457,8 +487,7 @@ class TextWin(BaseTextWin): def write_line_separator(self, y): char = get_theme().CHAR_NEW_TEXT_SEPARATOR self.addnstr(y, 0, - char * (self.width // len(char) - 1), - self.width, + char * (self.width // len(char) - 1), self.width, to_curses_attr(get_theme().COLOR_NEW_TEXT_SEPARATOR)) def write_ack(self): @@ -505,23 +534,26 @@ class TextWin(BaseTextWin): """ with_timestamps = config.get('show_timestamps') nick_size = config.get('max_nick_length') - for i in range(len(self.built_lines)-1, -1, -1): + for i in range(len(self.built_lines) - 1, -1, -1): if self.built_lines[i] and self.built_lines[i].msg.identifier == old_id: index = i while index >= 0 and self.built_lines[index] and self.built_lines[index].msg.identifier == old_id: self.built_lines.pop(index) index -= 1 index += 1 - lines = self.build_message(message, timestamp=with_timestamps, nick_size=nick_size) + lines = self.build_message( + message, timestamp=with_timestamps, nick_size=nick_size) for line in lines: self.built_lines.insert(index, line) index += 1 break def __del__(self): - log.debug('** TextWin: deleting %s built lines', (len(self.built_lines))) + log.debug('** TextWin: deleting %s built lines', + (len(self.built_lines))) del self.built_lines + class XMLTextWin(BaseTextWin): def __init__(self): BaseTextWin.__init__(self) @@ -534,7 +566,7 @@ class XMLTextWin(BaseTextWin): if self.pos == 0: lines = self.built_lines[-self.height:] else: - lines = self.built_lines[-self.height-self.pos:-self.pos] + lines = self.built_lines[-self.height - self.pos:-self.pos] self._win.move(0, 0) self._win.erase() for y, line in enumerate(lines): @@ -548,7 +580,7 @@ class XMLTextWin(BaseTextWin): self.write_time(msg.str_time) self.write_prefix(msg.nickname, color) self.addstr(' ') - if y != self.height-1: + if y != self.height - 1: self.addstr('\n') self._win.attrset(0) for y, line in enumerate(lines): @@ -563,9 +595,10 @@ class XMLTextWin(BaseTextWin): # space offset += 1 - self.write_text(y, offset, line.prepend - + line.msg.txt[line.start_pos:line.end_pos]) - if y != self.height-1: + self.write_text( + y, offset, + line.prepend + line.msg.txt[line.start_pos:line.end_pos]) + if y != self.height - 1: self.addstr('\n') self._win.attrset(0) self._refresh() @@ -577,18 +610,22 @@ class XMLTextWin(BaseTextWin): nick = truncate_nick(message.nickname, nick_size) offset = 0 if nick: - offset += poopt.wcswidth(nick) + 1 # + nick + ' ' length + offset += poopt.wcswidth(nick) + 1 # + nick + ' ' length if message.str_time: offset += 1 + len(message.str_time) if get_theme().CHAR_TIME_LEFT and message.str_time: offset += 1 if get_theme().CHAR_TIME_RIGHT and message.str_time: offset += 1 - lines = poopt.cut_text(txt, self.width-offset-1) + lines = poopt.cut_text(txt, self.width - offset - 1) prepend = default_color if default_color else '' attrs = [] for line in lines: - saved = Line(msg=message, start_pos=line[0], end_pos=line[1], prepend=prepend) + saved = Line( + msg=message, + start_pos=line[0], + end_pos=line[1], + prepend=prepend) attrs = parse_attrs(message.txt[line[0]:line[1]], attrs) if attrs: prepend = FORMAT_CHAR + FORMAT_CHAR.join(attrs) @@ -604,4 +641,3 @@ class XMLTextWin(BaseTextWin): self._win.attron(to_curses_attr(color)) self.addstr(truncate_nick(nickname)) self._win.attroff(to_curses_attr(color)) - -- cgit v1.2.3