diff --git a/gajim/gtk/chat_action_processor.py b/gajim/gtk/chat_action_processor.py index b6615afefb1e55dce2cf4453736c47d05e2ea8fc..b03c17006cbbaa11f3579531c80715b4223f5686 100644 --- a/gajim/gtk/chat_action_processor.py +++ b/gajim/gtk/chat_action_processor.py @@ -24,9 +24,13 @@ from gi.repository import Gtk from gajim.common import app +from gajim.common import types from gajim.common.const import Direction +from gajim.common.modules.contacts import GroupchatContact from .emoji_data_gtk import get_emoji_data +from .groupchat_nick_completion import GroupChatNickCompletion + if TYPE_CHECKING: from .message_input import MessageInputTextView @@ -34,7 +38,11 @@ class ChatActionProcessor(Gtk.Popover): - def __init__(self, message_input: MessageInputTextView) -> None: + def __init__(self, + account: str, + contact: types.ChatContactT, + message_input: MessageInputTextView + ) -> None: Gtk.Popover.__init__(self) self._menu = Gio.Menu() self.bind_model(self._menu) @@ -51,6 +59,12 @@ def __init__(self, message_input: MessageInputTextView) -> None: self._buf = message_input.get_buffer() self._buf.connect('changed', self._on_changed) + self._nick_completion: Optional[GroupChatNickCompletion] = None + if contact.is_groupchat: + assert isinstance(contact, GroupchatContact) + self._nick_completion = GroupChatNickCompletion( + account, contact, message_input) + self._start_mark: Optional[Gtk.TextMark] = None self._current_iter: Optional[Gtk.TextIter] = None @@ -60,9 +74,14 @@ def _on_destroy(self, _popover: Gtk.Popover) -> None: app.check_finalize(self) def _on_key_press(self, - _textview: Gtk.TextView, + textview: MessageInputTextView, event: Gdk.EventKey ) -> bool: + if self._nick_completion is not None: + res = self._nick_completion.process_key_press(textview, event) + if res: + return True + if not self._active: return False @@ -305,3 +324,7 @@ def _move_selection(self, direction: Direction) -> None: def _item_has_focus(item: Gtk.ModelButton) -> bool: flags = item.get_state_flags() return 'GTK_STATE_FLAG_FOCUSED' in str(flags) + + def process_outgoing_message(self, contact: str, highlight: bool) -> None: + if self._nick_completion is not None: + self._nick_completion.record_message(contact, highlight) diff --git a/gajim/gtk/controls/groupchat.py b/gajim/gtk/controls/groupchat.py index e10b7b21a9c854f2f85f7ab62ee46f280c89517a..33096eb5ff43d3cd0856fe5a912c1e90f3287bc3 100644 --- a/gajim/gtk/controls/groupchat.py +++ b/gajim/gtk/controls/groupchat.py @@ -72,7 +72,6 @@ from gajim.gui.groupchat_inviter import GroupChatInviter from gajim.gui.groupchat_roster import GroupchatRoster from gajim.gui.groupchat_state import GroupchatState -from gajim.gui.groupchat_nick_completion import GroupChatNickCompletion from gajim.gui.util import open_window from ..menus import get_encryption_menu @@ -152,9 +151,6 @@ def __init__(self, account: str, jid: JID) -> None: # if True, the room has mentioned us self.attention_flag: bool = False - self._nick_completion = GroupChatNickCompletion( - self.account, self.contact, self.msg_textview) - # Send file self.xml.sendfile_button.set_action_name( f'win.send-file-{self.control_id}') @@ -657,7 +653,7 @@ def add_message(self, highlight = helpers.message_needs_highlight( text, self.contact.nickname, self._client.get_own_jid().bare) - self._nick_completion.record_message(contact, highlight) + self.msg_textview.process_outgoing_message(contact, highlight) BaseControl.add_message(self, text, diff --git a/gajim/gtk/groupchat_nick_completion.py b/gajim/gtk/groupchat_nick_completion.py index 6a6e2162290abc3357367bac36d88a99c86dfc78..4369faed855f7bc2213c50d1495e2d2750925bfc 100644 --- a/gajim/gtk/groupchat_nick_completion.py +++ b/gajim/gtk/groupchat_nick_completion.py @@ -44,8 +44,6 @@ def __init__(self, self._contact.connect( 'user-nickname-changed', self._on_user_nickname_changed) - message_input.connect('key-press-event', self._on_key_press) - self._sender_list: list[str] = [] self._attention_list: list[str] = [] self._nick_hits: list[str] = [] @@ -140,10 +138,10 @@ def _nick_matching(nick: str) -> bool: return matches + other_nicks - def _on_key_press(self, - textview: MessageInputTextView, - event: Gdk.EventKey - ) -> bool: + def process_key_press(self, + textview: MessageInputTextView, + event: Gdk.EventKey + ) -> bool: if event.keyval not in (Gdk.KEY_ISO_Left_Tab, Gdk.KEY_Tab): self._last_key_tab = False return False @@ -156,7 +154,6 @@ def _on_key_press(self, text_split = text.split() - # nick completion # check if tab is pressed with empty message if text_split: # if there are any words begin = text_split[-1] # last word we typed @@ -194,22 +191,21 @@ def _on_key_press(self, return False if self._nick_hits: + shell_like_completion = app.settings.get('shell_like_completion') + if len(text_split) < 2 or with_refer_to_nick_char: # This is the 1st word of the line or no word or we are - # cycling at the beginning, possibly with a space in - # one nick + # cycling at the beginning, possibly with a space in one nick add = gc_refer_to_nick_char + ' ' else: add = ' ' start_iter = end_iter.copy() if (self._last_key_tab and with_refer_to_nick_char or (text and text[-1] == ' ')): - # have to accommodate for the added space from last - # completion + # have to accommodate for the added space from last completion # gc_refer_to_nick_char may be more than one char! start_iter.backward_chars(len(begin) + len(add)) - elif (self._last_key_tab and - not app.settings.get('shell_like_completion')): + elif self._last_key_tab and not shell_like_completion: # have to accommodate for the added space from last # completion start_iter.backward_chars( @@ -225,11 +221,10 @@ def _on_key_press(self, # get a shell-like completion # if there's more than one nick for this completion, complete # only the part that all these nicks have in common - if (app.settings.get('shell_like_completion') and - len(self._nick_hits) > 1): + if shell_like_completion and len(self._nick_hits) > 1: end = False completion = '' - add = "" # if nick is not complete, don't add anything + add = '' # if nick is not complete, don't add anything while not end and len(completion) < len(self._nick_hits[0]): completion = self._nick_hits[0][:len(completion) + 1] for nick in self._nick_hits: diff --git a/gajim/gtk/message_input.py b/gajim/gtk/message_input.py index 69fbff935d26686d9620a058a73bde0bf0f7c044..7974706116dd4765dade296e0e6bb3db123b1047 100644 --- a/gajim/gtk/message_input.py +++ b/gajim/gtk/message_input.py @@ -73,7 +73,8 @@ def __init__(self, account: str, contact: ChatContactT) -> None: self._undo_list: list[str] = [] self.undo_pressed: bool = False - self._chat_action_processor = ChatActionProcessor(self) + self._chat_action_processor = ChatActionProcessor( + account, contact, self) self.get_buffer().create_tag('strong', weight=Pango.Weight.BOLD) self.get_buffer().create_tag('emphasis', style=Pango.Style.ITALIC) @@ -313,3 +314,10 @@ def undo(self, *args: Any) -> None: if self._undo_list: buf.set_text(self._undo_list.pop()) self.undo_pressed = True + + def process_outgoing_message(self, + contact_name: str, + highlight: bool + ) -> None: + self._chat_action_processor.process_outgoing_message( + contact_name, highlight)