/list command, can join the room with J (cannot sort, search or filter yet,...

/list command, can join the room with J (cannot sort, search or filter yet, and lacks some information)
parent 2b58f653
This diff is collapsed.
......@@ -125,19 +125,19 @@ class Tab(object):
raise NotImplementedError
def on_input(self, key):
raise NotImplementedError
pass
def on_lose_focus(self):
"""
called when this tab loses the focus.
"""
raise NotImplementedError
pass
def on_gain_focus(self):
"""
called when this tab gains the focus.
"""
raise NotImplementedError
pass
def add_message(self):
"""
......@@ -146,25 +146,25 @@ class Tab(object):
FormTab, where text is not intented to be appened), it returns False.
If the tab can, it returns True
"""
raise NotImplementedError
return False
def on_scroll_down(self):
"""
Defines what happens when we scrol down
"""
raise NotImplementedError
pass
def on_scroll_up(self):
"""
Defines what happens when we scrol down
"""
raise NotImplementedError
pass
def on_info_win_size_changed(self):
"""
Called when the window with the informations is resized
"""
raise NotImplementedError
pass
def just_before_refresh(self):
"""
......@@ -172,13 +172,13 @@ class Tab(object):
Particularly useful to move the cursor at the
correct position.
"""
raise NotImplementedError
pass
def on_close(self):
"""
Called when the tab is to be closed
"""
raise NotImplementedError
pass
class InfoTab(Tab):
"""
......@@ -933,6 +933,102 @@ class ConversationTab(ChatTab):
def on_close(self):
return
class MucListTab(Tab):
"""
A tab listing rooms from a specific server, displaying various information,
scrollable, and letting the user join them, etc
"""
def __init__(self, core, server):
Tab.__init__(self, core)
self._color_state = theme.COLOR_TAB_NORMAL
self.name = server
self.upper_message = windows.Topic()
columns = ('node-part','name', 'users')
self.list_header = windows.ColumnHeaderWin(columns)
self.listview = windows.ListWin(columns)
self.tab_win = windows.GlobalInfoBar()
self.default_help_message = windows.HelpText("“j”: join room. “i”: information")
self.input = self.default_help_message
self.key_func["KEY_DOWN"] = self.listview.move_cursor_down
self.key_func["KEY_UP"] = self.listview.move_cursor_up
self.key_func["/"] = self.on_slash
self.key_func['j'] = self.join_selected
self.key_func['J'] = self.join_selected_no_focus
self.resize()
def refresh(self, tabs, informations, roster):
self.upper_message.refresh('Chatroom list on server %s' % self.name)
self.list_header.refresh()
self.listview.refresh()
self.tab_win.refresh(tabs, tabs[0])
self.input.refresh()
def resize(self):
Tab.resize(self)
self.upper_message.resize(1, self.width, 0, 0, self.core.stdscr)
column_size = {'node-part': (self.width-5)//4,
'name': (self.width-5)//4*3,
'users': 5}
self.list_header.resize_columns(column_size)
self.list_header.resize(1, self.width, 1, 0, self.core.stdscr)
self.listview.resize_columns(column_size)
self.listview.resize(self.height-4, self.width, 2, 0, self.core.stdscr)
self.tab_win.resize(1, self.width, self.height-2, 0, self.core.stdscr)
self.input.resize(1, self.width, self.height-1, 0, self.core.stdscr)
def on_slash(self):
"""
'/' is pressed, activate the input
"""
curses.curs_set(1)
self.input = windows.CommandInput("", self.reset_help_message, self.execute_slash_command)
self.input.resize(1, self.width, self.height-1, 0, self.core.stdscr)
self.input.do_command("/") # we add the slash
def join_selected_no_focus(self):
return
def join_selected(self):
jid = self.listview.get_selected_row()['jid']
self.core.command_join(jid)
def reset_help_message(self, _=None):
curses.curs_set(0)
self.input = self.default_help_message
return True
def execute_slash_command(self, txt):
if txt.startswith('/'):
self.core.execute(txt)
return self.reset_help_message()
def get_color_state(self):
return theme.COLOR_TAB_NORMAL
def set_color_state(self, color):
pass
def get_name(self):
return self.name
def on_input(self, key):
res = self.input.do_command(key)
if res:
return True
if key in self.key_func:
return self.key_func[key]()
def on_lose_focus(self):
self._color_state = theme.COLOR_TAB_NORMAL
def on_gain_focus(self):
self._color_state = theme.COLOR_TAB_CURRENT
curses.curs_set(0)
def get_color_state(self):
return self._color_state
def diffmatch(search, string):
"""
Use difflib and a loop to check if search_pattern can
......
......@@ -41,7 +41,7 @@ from contact import Contact, Resource
from roster import RosterGroup, roster
from message import Line
from tab import MIN_WIDTH, MIN_HEIGHT
from tabs import MIN_WIDTH, MIN_HEIGHT
from sleekxmpp.xmlstream.stanzabase import JID
......@@ -55,17 +55,7 @@ class Win(object):
def _resize(self, height, width, y, x, parent_win):
self.height, self.width, self.x, self.y = height, width, x, y
# try:
self._win = curses.newwin(height, width, y, x)
# except:
# # When resizing in a too little height (less than 3 lines)
# # We don't need to resize the window, since this size
# # just makes no sense
# # Just don't crash when this happens.
# # (°> also, a penguin
# # //\
# # V_/_
# return
def _refresh(self):
self._win.noutrefresh()
......@@ -404,10 +394,6 @@ class MucInfoWin(InfoWin):
self.addstr(txt, curses.color_pair(theme.COLOR_INFORMATION_BAR))
class TextWin(Win):
"""
Just keep ONE single window for the text area and rewrite EVERYTHING
on each change. (thanks weechat :o)
"""
def __init__(self):
Win.__init__(self)
......@@ -1278,3 +1264,122 @@ class ContactInfoWin(Win):
elif isinstance(selected_row, Resource):
self.draw_contact_info(selected_row)
self._refresh()
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):
self._columns = columns # a tuple with the name of the columns
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
def resize(self, height, width, y, x, stdscr):
self._resize(height, width, y, x, stdscr)
def resize_columns(self, dic):
"""
Resize the width of the columns
"""
self._columns_sizes = dic
def sort_by_column(self, col_name, asc=True):
"""
Sort the list by the given column, ascendant or descendant
"""
pass # TODO
def add_lines(self, lines):
"""
Append some lines at the end of the list
"""
if not lines:
return
self.lines += lines
self.refresh()
def get_selected_row(self):
"""
Return the tuple representing the selected row
"""
if self._selected_row:
return self.lines[self._selected_row]
return None
def refresh(self):
with g_lock:
self._win.erase()
lines = self.lines[self._starting_pos:self._starting_pos+self.height]
for y, line in enumerate(lines):
x = 0
for col in self._columns:
try:
txt = line[col] or ''
except (KeyError):
txt = ''
size = self._columns_sizes[col]
txt += ' ' * (size-len(txt))
if not txt:
continue
if line is self.lines[self._selected_row]:
self.addstr(y, x, txt[:size], curses.color_pair(theme.COLOR_INFORMATION_BAR))
else:
self.addstr(y, x, txt[:size])
x += size
self._refresh()
def move_cursor_down(self):
"""
Move the cursor Down
"""
if not self.lines:
return
if self._selected_row < len(self.lines) - 1:
self._selected_row += 1
while self._selected_row >= self._starting_pos + self.height:
self._starting_pos += self.height // 2
if self._starting_pos < 0:
self._starting_pos = 0
return True
def move_cursor_up(self):
"""
Move the cursor Up
"""
if not self.lines:
return
if self._selected_row > 0:
self._selected_row -= 1
while self._selected_row < self._starting_pos:
self._starting_pos -= self.height // 2
return True
class ColumnHeaderWin(Win):
"""
A class displaying the column's names
"""
def __init__(self, columns):
self._columns = columns
self._columns_sizes = {}
def resize_columns(self, dic):
self._columns_sizes = dic
def resize(self, height, width, y, x, stdscr):
self._resize(height, width, y, x, stdscr)
def refresh(self):
with g_lock:
self._win.erase()
x = 0
for col in self._columns:
txt = col
size = self._columns_sizes[col]
txt += ' ' * (size-len(txt))
self.addstr(0, x, txt, curses.color_pair(theme.COLOR_STATUS_UNAVAILABLE))
x += size
self._refresh()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment