summaryrefslogtreecommitdiff
path: root/poezio/core/core.py
diff options
context:
space:
mode:
Diffstat (limited to 'poezio/core/core.py')
-rw-r--r--poezio/core/core.py115
1 files changed, 60 insertions, 55 deletions
diff --git a/poezio/core/core.py b/poezio/core/core.py
index 52b45427..bf0b8a3d 100644
--- a/poezio/core/core.py
+++ b/poezio/core/core.py
@@ -39,7 +39,6 @@ from slixmpp.exceptions import IqError, IqTimeout, XMPPError
from poezio import connection
from poezio import decorators
from poezio import events
-from poezio import tabs
from poezio import theming
from poezio import timed_events
from poezio import windows
@@ -48,6 +47,11 @@ from poezio.bookmarks import (
BookmarkList,
Bookmark,
)
+from poezio.tabs import (
+ Tab, XMLTab, ChatTab, ConversationTab, PrivateTab, MucTab, OneToOneTab,
+ GapTab, RosterInfoTab, StaticConversationTab, DataFormsTab,
+ DynamicConversationTab, STATE_PRIORITY
+)
from poezio.common import get_error_message
from poezio.config import config
from poezio.contact import Contact, Resource
@@ -83,7 +87,7 @@ if TYPE_CHECKING:
log = logging.getLogger(__name__)
-T = TypeVar('T', bound=tabs.Tab)
+T = TypeVar('T', bound=Tab)
class Core:
@@ -105,7 +109,6 @@ class Core:
configuration_change_handlers: Dict[str, List[Callable[..., None]]]
own_nick: str
connection_time: float
- custom_version: str
xmpp: connection.Connection
avatar_cache: FileSystemPerJidCache
plugins_autoloaded: bool
@@ -119,7 +122,7 @@ class Core:
information_win_size: int
stdscr: Optional[_CursesWindow]
xml_buffer: TextBuffer
- xml_tab: Optional[tabs.XMLTab]
+ xml_tab: Optional[XMLTab]
last_stream_error: Optional[Tuple[float, XMPPError]]
remote_fifo: Optional[Fifo]
key_func: KeyDict
@@ -165,7 +168,7 @@ class Core:
self.events = events.EventHandler()
self.events.add_event_handler('tab_change', self.on_tab_change)
- self.tabs = Tabs(self.events, tabs.GapTab())
+ self.tabs = Tabs(self.events, GapTab())
self.previous_tab_nb = 0
self.own_nick: str = (
@@ -387,7 +390,7 @@ class Core:
self.left_tab_win = None
self.tab_win = windows.GlobalInfoBar(self)
- def on_tab_change(self, old_tab: tabs.Tab, new_tab: tabs.Tab):
+ def on_tab_change(self, old_tab: Tab, new_tab: Tab):
"""Whenever the current tab changes, change focus and refresh"""
old_tab.on_lose_focus()
new_tab.on_gain_focus()
@@ -576,7 +579,7 @@ class Core:
windows.base_wins.TAB_WIN = self.stdscr
self._create_windows()
self.call_for_resize()
- default_tab = tabs.RosterInfoTab(self)
+ default_tab = RosterInfoTab(self)
default_tab.on_gain_focus()
self.tabs.append(default_tab)
self.information('Welcome to poezio!', 'Info')
@@ -712,7 +715,7 @@ class Core:
Messages are namedtuples of the form
('txt nick_color time str_time nickname user')
"""
- if not isinstance(self.tabs.current_tab, tabs.ChatTab):
+ if not isinstance(self.tabs.current_tab, ChatTab):
return None
return self.tabs.current_tab.get_conversation_messages()
@@ -895,7 +898,7 @@ class Core:
if reconnect:
self.xmpp.reconnect(wait=0.0, reason=msg)
else:
- for tab in self.get_tabs(tabs.MucTab):
+ for tab in self.get_tabs(MucTab):
tab.leave_room(msg)
self.xmpp.disconnect(reason=msg)
@@ -905,7 +908,7 @@ class Core:
conversation.
Returns False if the current tab is not a conversation tab
"""
- if not isinstance(self.tabs.current_tab, tabs.ChatTab):
+ if not isinstance(self.tabs.current_tab, ChatTab):
return False
self.tabs.current_tab.command_say(msg)
return True
@@ -1039,7 +1042,7 @@ class Core:
def get_conversation_by_jid(self,
jid: JID,
create: bool = True,
- fallback_barejid: bool = True) -> Optional[tabs.ChatTab]:
+ fallback_barejid: bool = True) -> Optional[ChatTab]:
"""
From a JID, get the tab containing the conversation with it.
If none already exist, and create is "True", we create it
@@ -1051,17 +1054,17 @@ class Core:
jid = JID(jid)
# We first check if we have a static conversation opened
# with this precise resource
- conversation: Optional[tabs.ConversationTab]
+ conversation: Optional[ConversationTab]
conversation = self.tabs.by_name_and_class(jid.full,
- tabs.StaticConversationTab)
+ StaticConversationTab)
if jid.bare == jid.full and not conversation:
conversation = self.tabs.by_name_and_class(
- jid.full, tabs.DynamicConversationTab)
+ jid.full, DynamicConversationTab)
if not conversation and fallback_barejid:
# If not, we search for a conversation with the bare jid
conversation = self.tabs.by_name_and_class(
- jid.bare, tabs.DynamicConversationTab)
+ jid.bare, DynamicConversationTab)
if not conversation:
if create:
# We create a dynamic conversation with the bare Jid if
@@ -1073,7 +1076,7 @@ class Core:
conversation = None
return conversation
- def add_tab(self, new_tab: tabs.Tab, focus: bool = False) -> None:
+ def add_tab(self, new_tab: Tab, focus: bool = False) -> None:
"""
Appends the new_tab in the tab list and
focus it if focus==True
@@ -1169,11 +1172,11 @@ class Core:
def go_to_important_room(self) -> None:
"""
Go to the next room with activity, in the order defined in the
- dict tabs.STATE_PRIORITY
+ dict STATE_PRIORITY
"""
# shortcut
- priority = tabs.STATE_PRIORITY
- tab_refs: Dict[str, List[tabs.Tab]] = {}
+ priority = STATE_PRIORITY
+ tab_refs: Dict[str, List[Tab]] = {}
# put all the active tabs in a dict of lists by state
for tab in self.tabs.get_tabs():
if not tab:
@@ -1198,7 +1201,7 @@ class Core:
def focus_tab_named(self,
tab_name: str,
- type_: Type[tabs.Tab] = None) -> bool:
+ type_: Type[Tab] = None) -> bool:
"""Returns True if it found a tab to focus on"""
if type_ is None:
tab = self.tabs.by_name(tab_name)
@@ -1209,24 +1212,24 @@ class Core:
return True
return False
- def focus_tab(self, tab: tabs.Tab) -> bool:
+ def focus_tab(self, tab: Tab) -> bool:
"""Focus a tab"""
return self.tabs.set_current_tab(tab)
### Opening actions ###
def open_conversation_window(self, jid: JID,
- focus=True) -> tabs.ConversationTab:
+ focus=True) -> ConversationTab:
"""
Open a new conversation tab and focus it if needed. If a resource is
provided, we open a StaticConversationTab, else a
DynamicConversationTab
"""
- new_tab: tabs.ConversationTab
+ new_tab: ConversationTab
if jid.resource:
- new_tab = tabs.StaticConversationTab(self, jid)
+ new_tab = StaticConversationTab(self, jid)
else:
- new_tab = tabs.DynamicConversationTab(self, jid)
+ new_tab = DynamicConversationTab(self, jid)
if not focus:
new_tab.state = "private"
self.add_tab(new_tab, focus)
@@ -1234,21 +1237,21 @@ class Core:
return new_tab
def open_private_window(self, room_name: str, user_nick: str,
- focus=True) -> Optional[tabs.PrivateTab]:
+ focus=True) -> Optional[PrivateTab]:
"""
Open a Private conversation in a MUC and focus if needed.
"""
complete_jid = room_name + '/' + user_nick
# if the room exists, focus it and return
- for tab in self.get_tabs(tabs.PrivateTab):
+ for tab in self.get_tabs(PrivateTab):
if tab.name == complete_jid:
self.tabs.set_current_tab(tab)
return tab
# create the new tab
- muc_tab = self.tabs.by_name_and_class(room_name, tabs.MucTab)
+ muc_tab = self.tabs.by_name_and_class(room_name, MucTab)
if not muc_tab:
return None
- tab = tabs.PrivateTab(self, complete_jid, muc_tab.own_nick)
+ tab = PrivateTab(self, complete_jid, muc_tab.own_nick)
if hasattr(tab, 'directed_presence'):
tab.directed_presence = tab.directed_presence
if not focus:
@@ -1264,11 +1267,11 @@ class Core:
nick: str,
*,
password: Optional[str] = None,
- focus=True) -> tabs.MucTab:
+ focus=True) -> MucTab:
"""
Open a new tab.MucTab containing a muc Room, using the specified nick
"""
- new_tab = tabs.MucTab(self, room, nick, password=password)
+ new_tab = MucTab(self, room, nick, password=password)
self.add_tab(new_tab, focus)
self.refresh_window()
return new_tab
@@ -1280,7 +1283,7 @@ class Core:
The callback are called with the completed form as parameter in
addition with kwargs
"""
- form_tab = tabs.DataFormsTab(self, form, on_cancel, on_send, kwargs)
+ form_tab = DataFormsTab(self, form, on_cancel, on_send, kwargs)
self.add_tab(form_tab, True)
### Modifying actions ###
@@ -1292,7 +1295,7 @@ class Core:
with him/her
"""
tab = self.tabs.by_name_and_class('%s/%s' % (room_name, old_nick),
- tabs.PrivateTab)
+ PrivateTab)
if tab:
tab.rename_user(old_nick, user)
@@ -1303,7 +1306,7 @@ class Core:
private conversation
"""
tab = self.tabs.by_name_and_class('%s/%s' % (room_name, user.nick),
- tabs.PrivateTab)
+ PrivateTab)
if tab:
tab.user_left(status_message, user)
@@ -1313,7 +1316,7 @@ class Core:
private conversation
"""
tab = self.tabs.by_name_and_class('%s/%s' % (room_name, nick),
- tabs.PrivateTab)
+ PrivateTab)
if tab:
tab.user_rejoined(nick)
@@ -1325,7 +1328,7 @@ class Core:
"""
if reason is None:
reason = '\x195}You left the room\x193}'
- for tab in self.get_tabs(tabs.PrivateTab):
+ for tab in self.get_tabs(PrivateTab):
if tab.name.startswith(room_name):
tab.deactivate(reason=reason)
@@ -1336,23 +1339,23 @@ class Core:
"""
if reason is None:
reason = '\x195}You joined the room\x193}'
- for tab in self.get_tabs(tabs.PrivateTab):
+ for tab in self.get_tabs(PrivateTab):
if tab.name.startswith(room_name):
tab.activate(reason=reason)
def on_user_changed_status_in_private(self, jid: JID, status: Status) -> None:
- tab = self.tabs.by_name_and_class(jid, tabs.OneToOneTab)
+ tab = self.tabs.by_name_and_class(jid, OneToOneTab)
if tab is not None: # display the message in private
tab.update_status(status)
- def close_tab(self, to_close: tabs.Tab = None) -> None:
+ def close_tab(self, to_close: Tab = None) -> None:
"""
Close the given tab. If None, close the current one
"""
was_current = to_close is None
tab = to_close or self.tabs.current_tab
- if isinstance(tab, tabs.RosterInfoTab):
+ if isinstance(tab, RosterInfoTab):
return # The tab 0 should NEVER be closed
tab.on_close()
del tab.key_func # Remove self references
@@ -1373,7 +1376,7 @@ class Core:
Search for a ConversationTab with the given jid (full or bare),
if yes, add the given message to it
"""
- tab = self.tabs.by_name_and_class(jid, tabs.ConversationTab)
+ tab = self.tabs.by_name_and_class(jid, ConversationTab)
if tab is not None:
tab.add_message(PersistentInfoMessage(msg))
if self.tabs.current_tab is tab:
@@ -1409,7 +1412,7 @@ class Core:
)
)
popup_on = config.getlist('information_buffer_popup_on')
- if isinstance(self.tabs.current_tab, tabs.RosterInfoTab):
+ if isinstance(self.tabs.current_tab, RosterInfoTab):
self.refresh_window()
elif typ != '' and typ.lower() in popup_on:
popup_time = config.getint('popup_time') + (nb_lines - 1) * 2
@@ -1560,7 +1563,7 @@ class Core:
Scroll the information buffer up
"""
self.information_win.scroll_up(self.information_win.height)
- if not isinstance(self.tabs.current_tab, tabs.RosterInfoTab):
+ if not isinstance(self.tabs.current_tab, RosterInfoTab):
self.information_win.refresh()
else:
info = self.tabs.current_tab.information_win
@@ -1572,7 +1575,7 @@ class Core:
Scroll the information buffer down
"""
self.information_win.scroll_down(self.information_win.height)
- if not isinstance(self.tabs.current_tab, tabs.RosterInfoTab):
+ if not isinstance(self.tabs.current_tab, RosterInfoTab):
self.information_win.refresh()
else:
info = self.tabs.current_tab.information_win
@@ -1606,13 +1609,13 @@ class Core:
"""
Resize the global_information_win only once at each resize.
"""
- if self.information_win_size > tabs.Tab.height - 6:
- self.information_win_size = tabs.Tab.height - 6
- if tabs.Tab.height < 6:
+ if self.information_win_size > Tab.height - 6:
+ self.information_win_size = Tab.height - 6
+ if Tab.height < 6:
self.information_win_size = 0
- height = (tabs.Tab.height - 1 - self.information_win_size -
- tabs.Tab.tab_win_height())
- self.information_win.resize(self.information_win_size, tabs.Tab.width,
+ height = (Tab.height - 1 - self.information_win_size -
+ Tab.tab_win_height())
+ self.information_win.resize(self.information_win_size, Tab.width,
height, 0, self.information_buffer,
force=ui_config_changed)
@@ -1635,7 +1638,7 @@ class Core:
self.left_tab_win = windows.VerticalGlobalInfoBar(
self, truncated_win)
elif not self.size.core_degrade_y:
- self.tab_win.resize(1, tabs.Tab.width, tabs.Tab.height - 2, 0)
+ self.tab_win.resize(1, Tab.width, Tab.height - 2, 0)
self.left_tab_win = None
def full_screen_redraw(self):
@@ -1653,6 +1656,8 @@ class Core:
# window to each Tab class, so they draw themself in the portion of
# the screen that they can occupy, and we draw the tab list on the
# remaining space, on the left
+ if self.stdscr is None:
+ raise ValueError('No output available')
height, width = self.stdscr.getmaxyx()
if (config.getbool('enable_vertical_tab_list')
and not self.size.core_degrade_x):
@@ -1666,7 +1671,7 @@ class Core:
return
else:
scr = self.stdscr
- tabs.Tab.initial_resize(scr)
+ Tab.initial_resize(scr)
self.resize_global_info_bar()
self.resize_global_information_win(ui_config_changed)
for tab in self.tabs:
@@ -1741,7 +1746,7 @@ class Core:
for bm in bookmarks:
if not (bm.autojoin or config.getbool('open_all_bookmarks')):
continue
- tab = self.tabs.by_name_and_class(bm.jid, tabs.MucTab)
+ tab = self.tabs.by_name_and_class(bm.jid, MucTab)
nick = bm.nick if bm.nick else self.own_nick
if not tab:
tab = self.open_new_room(
@@ -1749,7 +1754,7 @@ class Core:
self.initial_joins.append(bm.jid)
# do not join rooms that do not have autojoin
# but display them anyway
- if bm.autojoin:
+ if bm.autojoin and tab:
tab.join()
async def check_bookmark_storage(self, features: List[str]):
@@ -1776,7 +1781,7 @@ class Core:
"""
Display the error in the tab
"""
- tab = self.tabs.by_name_and_class(room_name, tabs.MucTab)
+ tab = self.tabs.by_name_and_class(room_name, MucTab)
if not tab:
return
error_message = get_error_message(error)