diff --git a/gajim/chat_control.py b/gajim/chat_control.py index a2d8e13e9de419d997e903a03280b0d75a22d162..7c6a8140baecbfc4e8e1901f97f80cfbce14d0cd 100644 --- a/gajim/chat_control.py +++ b/gajim/chat_control.py @@ -99,13 +99,11 @@ class ChatControl(ChatControlBase): # processed with this command host. COMMAND_HOST = ChatCommands # type: ClassVar[Type[CommandHost]] - def __init__(self, parent_win, jid, acct, session, resource=None): + def __init__(self, account, jid): ChatControlBase.__init__(self, - parent_win, 'chat_control', - jid, - acct, - resource) + account, + jid) self.last_recv_message_id = None self.last_recv_message_marks = None @@ -245,7 +243,7 @@ def add_actions(self): action_name, func = action act = Gio.SimpleAction.new(action_name + self.control_id, None) act.connect('activate', func) - self.parent_win.window.add_action(act) + app.window.add_action(act) chatstate = self.contact.settings.get('send_chatstate') @@ -254,7 +252,7 @@ def add_actions(self): GLib.VariantType.new("s"), GLib.Variant("s", chatstate)) act.connect('change-state', self._on_send_chatstate) - self.parent_win.window.add_action(act) + app.window.add_action(act) marker = self.contact.settings.get('send_marker') @@ -263,10 +261,10 @@ def add_actions(self): None, GLib.Variant.new_boolean(marker)) act.connect('change-state', self._on_send_marker) - self.parent_win.window.add_action(act) + app.window.add_action(act) def update_actions(self): - win = self.parent_win.window + win = app.window online = app.account_is_connected(self.account) # Add to roster @@ -366,7 +364,7 @@ def remove_actions(self): 'send-marker-', ] for action in actions: - self.parent_win.window.remove_action(f'{action}{self.control_id}') + app.window.remove_action(f'{action}{self.control_id}') def focus(self): self.msg_textview.grab_focus() @@ -377,7 +375,7 @@ def delegate_action(self, action): return res if action == 'show-contact-info': - self.parent_win.window.lookup_action( + app.window.lookup_action( 'information-%s' % self.control_id).activate() return Gdk.EVENT_STOP @@ -387,7 +385,7 @@ def delegate_action(self, action): app.interface.roster.tree.grab_focus() return Gdk.EVENT_PROPAGATE - self.parent_win.window.lookup_action( + app.window.lookup_action( 'send-file-%s' % self.control_id).activate() return Gdk.EVENT_STOP @@ -499,8 +497,6 @@ def _on_location_received(self, _event): def _on_nickname_received(self, _event): self.update_ui() - self.parent_win.redraw_tab(self) - self.parent_win.show_title() def _on_update_client_info(self, event): contact = app.contacts.get_contact( @@ -527,7 +523,7 @@ def _on_caps_update(self, event): def _on_mam_message_received(self, event): if event.properties.is_muc_pm: - if not event.properties.jid == self.contact.get_full_jid(): + if not event.properties.jid == self.contact.jid: return else: if not event.properties.jid.bare_match(self.contact.jid): @@ -608,19 +604,6 @@ def _nec_ping(self, event): elif event.name == 'ping-error': self.add_info_message(event.error) - def change_resource(self, resource): - old_full_jid = self.get_full_jid() - self.resource = resource - new_full_jid = self.get_full_jid() - # update app.last_message_time - if old_full_jid in app.last_message_time[self.account]: - app.last_message_time[self.account][new_full_jid] = \ - app.last_message_time[self.account][old_full_jid] - # update events - app.events.change_jid(self.account, old_full_jid, new_full_jid) - # update MessageWindow._controls - self.parent_win.change_jid(self.account, old_full_jid, new_full_jid) - # Jingle AV def _on_start_call(self, *args): audio_state = self.jingle['audio'].state @@ -771,7 +754,7 @@ def update_video(self): self.xml.outgoing_viewport.add(self._video_widget_self) session = self._client.get_module('Jingle').get_jingle_session( - self.contact.get_full_jid(), self.jingle['video'].sid) + self.contact.jid, self.jingle['video'].sid) content = session.get_content('video') content.do_setup(sink_self, sink_other) @@ -834,7 +817,7 @@ def close_jingle_content(self, jingle_type: str, return session = self._client.get_module('Jingle').get_jingle_session( - self.contact.get_full_jid(), jingle.sid) + self.contact.jid, jingle.sid) if session: content = session.get_content(jingle_type) if content: @@ -857,7 +840,7 @@ def _on_jingle_button_toggled(self, jingle_types): if all(item in jingle_types for item in ['audio', 'video']): # Both 'audio' and 'video' in jingle_types sid = self._client.get_module('Jingle').start_audio_video( - self.contact.get_full_jid()) + self.contact.jid) self.set_jingle_state('audio', JingleState.CONNECTING, sid) self.set_jingle_state('video', JingleState.CONNECTING, sid) return @@ -867,7 +850,7 @@ def _on_jingle_button_toggled(self, jingle_types): self.close_jingle_content('audio') else: sid = self._client.get_module('Jingle').start_audio( - self.contact.get_full_jid()) + self.contact.jid) self.set_jingle_state('audio', JingleState.CONNECTING, sid) if 'video' in jingle_types: @@ -875,12 +858,12 @@ def _on_jingle_button_toggled(self, jingle_types): self.close_jingle_content('video') else: sid = self._client.get_module('Jingle').start_video( - self.contact.get_full_jid()) + self.contact.jid) self.set_jingle_state('video', JingleState.CONNECTING, sid) def _get_audio_content(self): session = self._client.get_module('Jingle').get_jingle_session( - self.contact.get_full_jid(), self.jingle['audio'].sid) + self.contact.jid, self.jingle['audio'].sid) return session.get_content('audio') def on_num_button_pressed(self, _widget, num): @@ -912,11 +895,11 @@ def on_location_eventbox_leave_notify_event(self, _widget, _event): Just moved the mouse so show the cursor """ cursor = get_cursor('default') - self.parent_win.window.get_window().set_cursor(cursor) + app.window.get_window().set_cursor(cursor) def on_location_eventbox_enter_notify_event(self, _widget, _event): cursor = get_cursor('pointer') - self.parent_win.window.get_window().set_cursor(cursor) + app.window.get_window().set_cursor(cursor) def update_ui(self): # The name banner is drawn here @@ -932,14 +915,14 @@ def draw_banner_text(self): """ contact = self.contact name = contact.name - if self.resource: - name += '/' + self.resource - if self._type.is_privatechat: - name = i18n.direction_mark + _( - '%(nickname)s from group chat %(room_name)s') % \ - {'nickname': name, 'room_name': self.room_name} + # if self.resource: + # name += '/' + self.resource + # if self._type.is_privatechat: + # name = i18n.direction_mark + _( + # '%(nickname)s from group chat %(room_name)s') % \ + # {'nickname': name, 'room_name': self.room_name} - name = i18n.direction_mark + GLib.markup_escape_text(name) + # name = i18n.direction_mark + GLib.markup_escape_text(name) cs = self.contact.chatstate if cs is not None: @@ -1091,17 +1074,6 @@ def shutdown(self): self.close_jingle_content(jingle_type, shutdown=True) self.jingle.clear() - # disconnect self from session - if self.session: - self.session.control = None - - # Clean events - app.events.remove_events( - self.account, - self.get_full_jid(), - types=['printed_%s' % self._type, str(self._type)]) - # Remove contact instance if contact has been removed - super(ChatControl, self).shutdown() app.check_finalize(self) @@ -1112,7 +1084,7 @@ def safe_shutdown(self): return False def allow_shutdown(self, method, on_yes, on_no, _on_minimize): - time_ = app.last_message_time[self.account][self.get_full_jid()] + time_ = app.last_message_time[self.account][self.contact.jid] # 2 seconds if time.time() - time_ < 2: no_log_for = app.settings.get_account_setting( @@ -1136,7 +1108,7 @@ def allow_shutdown(self, method, on_yes, on_no, _on_minimize): DialogButton.make('Remove', text=_('_Close'), callback=lambda: on_yes(self))], - transient_for=self.parent_win.window).show() + transient_for=app.window).show() return on_yes(self) @@ -1144,7 +1116,7 @@ def _on_avatar_update(self, _contact, _signal_name): self._update_avatar() def _update_avatar(self): - scale = self.parent_win.window.get_scale_factor() + scale = app.window.get_scale_factor() surface = self.contact.get_avatar(AvatarSize.CHAT, scale) self.xml.avatar_image.set_from_surface(surface) @@ -1200,7 +1172,6 @@ def _on_presence_received(self, event): name = self.contact.name self.update_ui() - self.parent_win.redraw_tab(self) if not app.settings.get('print_status_in_chats'): return diff --git a/gajim/chat_control_base.py b/gajim/chat_control_base.py index 071e025d44c8234cebfc59c763300ca12256f205..b39bc9c9915ae890b9847bc5c316226557d5f809 100644 --- a/gajim/chat_control_base.py +++ b/gajim/chat_control_base.py @@ -98,20 +98,17 @@ class ChatControlBase(ChatCommandProcessor, CommandTools, EventHelper): _type = None # type: ControlType - def __init__(self, parent_win, widget_name, jid, acct, - resource=None): + def __init__(self, widget_name, account, jid): EventHelper.__init__(self) # Undo needs this variable to know if space has been pressed. # Initialize it to True so empty textview is saved in undo list self.space_pressed = True self.handlers = {} - self.parent_win = parent_win - self.account = acct - self.resource = resource + self.account = account - self._client = app.get_client(acct) + self._client = app.get_client(account) groupchat = self._type != ControlType.CHAT self.contact = self._client.get_module('Contacts').get_contact( @@ -123,7 +120,7 @@ def __init__(self, parent_win, widget_name, jid, acct, self.control_id = str(uuid.uuid4()) self.session = None - app.last_message_time[self.account][self.get_full_jid()] = 0 + app.last_message_time[self.account][self.contact.jid] = 0 self.xml = get_builder('%s.ui' % widget_name) self.xml.connect_signals(self) @@ -241,10 +238,10 @@ def __init__(self, parent_win, widget_name, jid, acct, self._client.get_module('Chatstate').set_active(self.contact) - if parent_win is not None: - id_ = parent_win.window.connect('motion-notify-event', - self._on_window_motion_notify) - self.handlers[id_] = parent_win.window + # TODO + # id_ = app.window.connect('motion-notify-event', + # self._on_window_motion_notify) + # self.handlers[id_] = app.window self.encryption = self.get_encryption_state() self.conversation_view.encryption_enabled = self.encryption is not None @@ -322,12 +319,6 @@ def is_privatechat(self): def is_groupchat(self): return self._type.is_groupchat - def get_full_jid(self): - fjid = self.contact.jid - if self.resource: - fjid += '/' + self.resource - return fjid - def minimizable(self): """ Called to check if control can be minimized @@ -360,15 +351,6 @@ def allow_shutdown(self, method, on_response_yes, on_response_no, def focus(self): raise NotImplementedError - def get_nb_unread(self): - jid = self.contact.jid - if self.resource: - jid += '/' + self.resource - return len(app.events.get_events( - self.account, - jid, - ['printed_%s' % self._type, str(self._type)])) - def draw_banner(self): """ Draw the fat line at the top of the window @@ -522,7 +504,7 @@ def add_actions(self): GLib.VariantType.new('s'), GLib.Variant('s', self.encryption or 'disabled')) action.connect('change-state', self.change_encryption) - self.parent_win.window.add_action(action) + app.window.add_action(action) actions = { 'send-message-%s': self._on_send_message, @@ -535,7 +517,7 @@ def add_actions(self): action = Gio.SimpleAction.new(name % self.control_id, None) action.connect('activate', func) action.set_enabled(False) - self.parent_win.window.add_action(action) + app.window.add_action(action) def remove_actions(self): actions = [ @@ -547,7 +529,7 @@ def remove_actions(self): ] for action in actions: - self.parent_win.window.remove_action(f'{action}{self.control_id}') + app.window.remove_action(f'{action}{self.control_id}') def change_encryption(self, action, param): encryption = param.get_string() @@ -783,9 +765,9 @@ def _paste_event_confirmed(self, is_checked, image): def _get_pref_ft_method(self): ft_pref = app.settings.get_account_setting(self.account, 'filetransfer_preference') - httpupload = self.parent_win.window.lookup_action( + httpupload = app.window.lookup_action( 'send-file-httpupload-%s' % self.control_id) - jingle = self.parent_win.window.lookup_action( + jingle = app.window.lookup_action( 'send-file-jingle-%s' % self.control_id) if self._type.is_groupchat: @@ -1037,9 +1019,6 @@ def _on_window_motion_notify(self, *args): """ It gets called no matter if it is the active window or not """ - if not self.parent_win: - # when a groupchat is minimized there is no parent window - return # TODO return if self.parent_win.get_active_jid() == self.contact.jid: @@ -1049,8 +1028,7 @@ def _on_window_motion_notify(self, *args): def _on_message_tv_buffer_changed(self, textbuffer): has_text = self.msg_textview.has_text() - if self.parent_win is not None: - self.parent_win.window.lookup_action( + app.window.lookup_action( 'send-message-' + self.control_id).set_enabled(has_text) if textbuffer.get_char_count() and self.encryption: @@ -1123,7 +1101,7 @@ def add_message(self, correct_id = (message_id, correct_id) """ jid = self.contact.jid - full_jid = self.get_full_jid() + full_jid = self.contact.jid end = False if self.conversation_view.autoscroll or kind == 'outgoing': end = True @@ -1252,9 +1230,6 @@ def set_emoticon_popover(self): if not app.settings.get('emoticons_theme'): return - if not self.parent_win: - return - if sys.platform in ('win32', 'darwin'): emoji_chooser.text_widget = self.msg_textview self.xml.emoticons_button.set_popover(emoji_chooser) @@ -1270,13 +1245,13 @@ def _on_emoticon_button_clicked(self, _widget): self.xml.emoticons_button.set_property('active', False) def on_color_menuitem_activate(self, _widget): - color_dialog = Gtk.ColorChooserDialog(None, self.parent_win.window) + color_dialog = Gtk.ColorChooserDialog(None, app.window) color_dialog.set_use_alpha(False) color_dialog.connect('response', self.msg_textview.color_set) color_dialog.show_all() def on_font_menuitem_activate(self, _widget): - font_dialog = Gtk.FontChooserDialog(None, self.parent_win.window) + font_dialog = Gtk.FontChooserDialog(None, app.window) start, finish = self.msg_textview.get_active_iters() font_dialog.connect('response', self.msg_textview.font_set, start, finish) font_dialog.show_all() @@ -1369,7 +1344,7 @@ def set_control_active(self, state): if self._type.is_groupchat: type_ = ['printed_gc_msg', 'printed_marked_gc_msg'] if not app.events.remove_events(self.account, - self.get_full_jid(), + self.contact.jid, types=type_): # There were events to remove self.redraw_after_event_removed(jid) @@ -1471,10 +1446,9 @@ def add_messages(self, messages): history=True) def has_focus(self): - if self.parent_win: - if self.parent_win.window.get_property('has-toplevel-focus'): - if self == self.parent_win.get_active_control(): - return True + if app.window.get_property('has-toplevel-focus'): + if self == app.window.get_active_control(): + return True return False def scroll_messages(self, direction, msg_buf, msg_type): diff --git a/gajim/common/modules/caps.py b/gajim/common/modules/caps.py index 148d62f2aa7b14437c381125ab71a5da26735935..cc01e6111fefc9a34b32824e1ceac3b1faf68ef9 100644 --- a/gajim/common/modules/caps.py +++ b/gajim/common/modules/caps.py @@ -212,9 +212,11 @@ def preconditions_met(self): return False if self._from_muc: - muc = client.get_module('MUC').get_muc_data(self.entity.jid.bare) + contact = client.get_module('Contacts').get_contact( + self.entity.jid.bare, + groupchat=True) - if muc is None or not muc.state.is_joined: + if not contact.is_joined: self.set_obsolete() return False diff --git a/gajim/common/modules/chat_markers.py b/gajim/common/modules/chat_markers.py index 67eb396a267df756a5062a74a0c81d0a0421bb56..40bb19fe7b8219bba681604acc118f71708e2172 100644 --- a/gajim/common/modules/chat_markers.py +++ b/gajim/common/modules/chat_markers.py @@ -45,9 +45,11 @@ def _process_chat_marker(self, _con, _stanza, properties): return if properties.type.is_groupchat: - muc_data = self._con.get_module('MUC').get_muc_data( - properties.muc_jid) - if muc_data is None: + contact = self._con.get_module('Contacts').get_contact( + properties.muc_jid, + groupchat=True) + if not contact.is_joined: + self._log.warning('Received chat marker while not joined') return if properties.muc_nickname != muc_data.nick: diff --git a/gajim/common/modules/contacts.py b/gajim/common/modules/contacts.py index dacee0275534905fbfe6eba6714640ad35f1bb81..f0fb3aec93f392bc4a43297acebe6c4faa9dceb3 100644 --- a/gajim/common/modules/contacts.py +++ b/gajim/common/modules/contacts.py @@ -346,11 +346,6 @@ def __init__(self, logger, jid, account): def is_groupchat(self): return True - @property - def state(self): - muc_data = self._module('MUC').get_muc_data(self._jid) - return muc_data.state - def add_resource(self, resource): jid = self._jid.new_with(resource=resource) contact = GroupchatParticipant(self._log, jid, self._account) @@ -392,6 +387,26 @@ def update_avatar(self, *args): app.interface.avatar_storage.invalidate_cache(self._jid) self.notify('avatar-update') + def get_self(self): + nick = self.nickname + if nick is None: + return None + return self.get_resource(nick) + + @property + def nickname(self): + muc_data = self._module('MUC').get_muc_data(self._jid) + if muc_data is None: + return None + return muc_data.nick + + @property + def occupant_jid(self): + muc_data = self._module('MUC').get_muc_data(self._jid) + if muc_data is None: + return None + return muc_data.occupant_jid + @property def is_joined(self): muc_data = self._module('MUC').get_muc_data(self._jid) @@ -399,6 +414,20 @@ def is_joined(self): return False return muc_data.state.is_joined + @property + def is_joining(self): + muc_data = self._module('MUC').get_muc_data(self._jid) + if muc_data is None: + return False + return muc_data.state.is_joining + + @property + def is_not_joined(self): + muc_data = self._module('MUC').get_muc_data(self._jid) + if muc_data is None: + return True + return muc_data.state.is_not_joined + def set_not_joined(self): for contact in self._resources.values(): contact.update_presence(UNKNOWN_MUC_PRESENCE, notify=False) diff --git a/gajim/common/modules/muc.py b/gajim/common/modules/muc.py index 2a9631868151bcac5924d3eeaec5a5cf0213d892..396902e11e770bf64837290bd38478fa23e832b4 100644 --- a/gajim/common/modules/muc.py +++ b/gajim/common/modules/muc.py @@ -116,7 +116,7 @@ def __init__(self, con): self._muc_service_jid = None self._joined_users = defaultdict(dict) self._mucs = {} - + self._muc_nicknames = {} def _on_resume_failed(self, _client, _signal_name): self._reset_presence() @@ -147,6 +147,10 @@ def pass_disco(self, info): def get_muc_data(self, room_jid): return self._mucs.get(room_jid) + def set_password(self, room_jid, password): + muc_data = self.get_muc_data(room_jid) + muc_data.password = password + def _get_mucs_with_state(self, states): return [muc for muc in self._mucs.values() if muc.state in states] diff --git a/gajim/groupchat_control.py b/gajim/groupchat_control.py index 1b03314e7b145254a43404741d63ddd1011f0ebe..20c12b8037276673c61deef1a7b18d3094ff737b 100644 --- a/gajim/groupchat_control.py +++ b/gajim/groupchat_control.py @@ -87,12 +87,11 @@ class GroupchatControl(ChatControlBase): # will be processed with this command host. COMMAND_HOST = GroupChatCommands - def __init__(self, parent_win, jid, muc_data, acct): + def __init__(self, account, jid): ChatControlBase.__init__(self, - parent_win, 'groupchat_control', - jid, - acct) + account, + jid) self._client.connect_signal('state-changed', self._on_client_state_changed) @@ -120,12 +119,9 @@ def __init__(self, parent_win, jid, muc_data, acct): self.xml.roster_revealer.add(self.roster) self.roster.connect('row-activated', self._on_roster_row_activated) - if parent_win is not None: - self.add_actions() - GLib.idle_add(self.update_actions) - self.scale_factor = parent_win.window.get_scale_factor() - else: - self.scale_factor = app.interface.roster.scale_factor + self.add_actions() + GLib.idle_add(self.update_actions) + self.scale_factor = app.window.get_scale_factor() if not app.settings.get('hide_groupchat_banner'): self.xml.banner_eventbox.set_no_show_all(False) @@ -256,45 +252,33 @@ def _connect_contact_signals(self): }) def _on_muc_state_changed(self, _contact, _signal_name): - state = self.contact.state - if state == MUCJoinedState.JOINING: + if self.contact.is_joining: self._groupchat_state.set_joining() - if state == MUCJoinedState.JOINED: + if self.contact.is_joined: self._set_control_active() self.show_roster() self._groupchat_state.set_joined() - elif state == MUCJoinedState.NOT_JOINED: + elif self.contact.is_not_joined: self._set_control_inactive() def _on_client_state_changed(self, _client, _signal_name, state): pass - @property - def _muc_data(self): - return self._client.get_module('MUC').get_muc_data(self.room_jid) - @property def _nick_completion(self): if self.__nick_completion is None: - self.__nick_completion = NickCompletionGenerator(self._muc_data.nick) + self.__nick_completion = NickCompletionGenerator( + self.contact.nickname) return self.__nick_completion - @property - def nick(self): - return self._muc_data.nick - @property def subject(self): if self._subject_data is None: return '' return self._subject_data.subject - @property - def room_name(self): - return self.contact.get_shown_name() - @property def disco_info(self): return app.storage.cache.get_last_disco_info(self.contact.jid) @@ -325,36 +309,35 @@ def add_actions(self): variant = GLib.VariantType.new(variant) act = Gio.SimpleAction.new(action_name + self.control_id, variant) act.connect("activate", func) - self.parent_win.window.add_action(act) + app.window.add_action(act) def update_actions(self, *args): - if self._muc_data is None: - return - - contact = self.contact.get_resource(self.nick) + joined = self.contact.is_joined + if joined: + contact = self.contact.get_self() self._get_action('request-voice-').set_enabled( - self.is_connected and contact.role.is_visitor) + joined and contact.role.is_visitor) # Change Nick - self._get_action('change-nickname-').set_enabled(self.is_connected) + self._get_action('change-nickname-').set_enabled(joined) # Execute command - self._get_action('execute-command-').set_enabled(self.is_connected) + self._get_action('execute-command-').set_enabled(joined) # Send message has_text = self.msg_textview.has_text() self._get_action('send-message-').set_enabled( - self.is_connected and has_text) + joined and has_text) # Send file (HTTP File Upload) httpupload = self._get_action( 'send-file-httpupload-') - httpupload.set_enabled(self.is_connected and + httpupload.set_enabled(joined and self._client.get_module('HTTPUpload').available) self._get_action('send-file-').set_enabled(httpupload.get_enabled()) - if self.is_connected and httpupload.get_enabled(): + if joined and httpupload.get_enabled(): tooltip_text = _('Send File…') max_file_size = self._client.get_module('HTTPUpload').max_file_size if max_file_size is not None: @@ -372,6 +355,7 @@ def update_actions(self, *args): vcard_support = False if self.disco_info is not None: vcard_support = self.disco_info.supports(Namespace.VCARD) + self.xml.muc_name_entry.set_text(self.disco_info.muc_name or '') self.xml.muc_description_entry.set_text( self.disco_info.muc_description or '') @@ -390,13 +374,13 @@ def update_actions(self, *args): self.xml.manage_destroy_button.set_sensitive( self.is_connected and contact.affiliation.is_owner) - self._get_action('contact-information-').set_enabled(self.is_connected) + self._get_action('contact-information-').set_enabled(joined) - self._get_action('execute-command-').set_enabled(self.is_connected) + self._get_action('execute-command-').set_enabled(joined) - self._get_action('ban-').set_enabled(self.is_connected) + self._get_action('ban-').set_enabled(joined) - self._get_action('kick-').set_enabled(self.is_connected) + self._get_action('kick-').set_enabled(joined) def remove_actions(self): super().remove_actions() @@ -418,10 +402,13 @@ def remove_actions(self): ] for action in actions: - self.parent_win.window.remove_action(f'{action}{self.control_id}') + app.window.remove_action(f'{action}{self.control_id}') def _is_subject_change_allowed(self): - contact = self.contact.get_resource(self.nick) + contact = self.contact.get_self() + if contact is None: + return False + if contact.affiliation in (Affiliation.OWNER, Affiliation.ADMIN): return True @@ -430,7 +417,7 @@ def _is_subject_change_allowed(self): return self.disco_info.muc_subjectmod or False def _get_action(self, name): - win = self.parent_win.window + win = app.window return win.lookup_action(name + self.control_id) def _show_page(self, name): @@ -560,7 +547,7 @@ def _on_configure_room(self, _button): win.present() return - contact = self.contact.get_resource(self.nick) + contact = self.contact.get_self() if contact.affiliation.is_owner: self._client.get_module('MUC').request_config( self.room_jid, callback=self._on_configure_form_received) @@ -610,7 +597,7 @@ def _on_accept(path): self._avatar_selector.get_prepared()) AvatarChooserDialog(_on_accept, - transient_for=self.parent_win.window, + transient_for=app.window, modal=True) def _on_upload_avatar_result(self, task): @@ -687,23 +674,6 @@ def show_roster(self): self.xml.roster_revealer.set_transition_type(transition) self.xml.roster_revealer.set_reveal_child(show) - def on_groupchat_maximize(self): - self.roster.enable_tooltips() - self.add_actions() - self.update_actions() - self.set_lock_image() - self.draw_banner_text() - type_ = ['printed_gc_msg', 'printed_marked_gc_msg'] - if not app.events.remove_events(self.account, - self.get_full_jid(), - types=type_): - # XEP-0333 Send <displayed> marker - self._client.get_module('ChatMarkers').send_displayed_marker( - self.contact, - self.last_msg_id, - self._type) - self.last_msg_id = None - def _on_roster_row_activated(self, _roster, nick): muc_prefer_direct_msg = app.settings.get('muc_prefer_direct_msg') if not self.is_anonymous and muc_prefer_direct_msg: @@ -746,7 +716,7 @@ def on_approve(): _('Voice Request'), _('Voice Request'), _('<b>%(nick)s</b> from <b>%(room_name)s</b> requests voice') % { - 'nick': voice_request.nick, 'room_name': self.room_name}, + 'nick': voice_request.nick, 'room_name': self.contact.name}, [DialogButton.make('Cancel'), DialogButton.make('Accept', text=_('_Approve'), @@ -773,7 +743,7 @@ def _on_gc_message_received(self, event): displaymarking=event.displaymarking, additional_data=event.additional_data) else: - if event.properties.muc_nickname == self.nick: + if event.properties.muc_nickname == self.contact.nickname: self.last_sent_txt = event.msgtxt stanza_id = None if event.properties.stanza_id: @@ -804,24 +774,17 @@ def add_message(self, text, contact='', tim=None, if not contact: # Message from the server kind = 'status' - elif contact == self.nick: # it's us + elif contact == self.contact.nickname: # it's us kind = 'outgoing' else: kind = 'incoming' # muc-specific chatstate - if self.parent_win: - self.parent_win.redraw_tab(self, 'newmsg') if kind == 'incoming': # it's a message NOT from us # highlighting and sounds highlight, _sound = self.highlighting_for_message(text, tim) other_tags_for_name.append('muc_nickname_color_%s' % contact) if highlight: - # muc-specific chatstate - if self.parent_win: - self.parent_win.redraw_tab(self, 'attention') - else: - self.attention_flag = True other_tags_for_name.append('bold') other_tags_for_text.append('marked') @@ -892,7 +855,7 @@ def needs_visual_notification(self, text): nick) appear """ special_words = app.settings.get('muc_highlight_words').split(';') - special_words.append(self.nick) + special_words.append(self.contact.nickname) special_words.append(self._client.get_own_jid().bare) # Strip empties: ''.split(';') == [''] and would highlight everything. # Also lowercase everything for case insensitive compare. @@ -929,7 +892,7 @@ def _on_room_subject(self, _contact, _signal_name, properties): text = '%s - %s' % (text, date) if (app.settings.get('show_subject_on_join') or - self._muc_data.state != MUCJoinedState.JOINING): + not self.contact.is_joining): self.add_info_message(text) def _on_room_config_changed(self, _contact, _signal_name, properties): @@ -990,14 +953,6 @@ def _nec_ping(self, event): elif event.name == 'ping-error': self.add_info_message(event.error) - @property - def is_connected(self) -> bool: - return app.gc_connected[self.account][self.room_jid] - - @is_connected.setter - def is_connected(self, value: bool) -> None: - app.gc_connected[self.account][self.room_jid] = value - def _set_control_active(self): self.xml.formattings_button.set_sensitive(True) self.msg_textview.set_sensitive(True) @@ -1005,8 +960,6 @@ def _set_control_active(self): self.roster.initial_draw() - self.is_connected = True - self.xml.formattings_button.set_sensitive(True) self.conversation_view.update_avatars() @@ -1021,8 +974,6 @@ def _set_control_inactive(self): self.roster.enable_sort(False) self.roster.clear() - self.is_connected = False - self._client.get_module('Chatstate').remove_delay_timeout(self.contact) self.update_actions() @@ -1039,13 +990,14 @@ def _on_user_joined(self, _contact, _signal_name, user_contact, properties): nick = user_contact.name if not properties.is_muc_self_presence: - if self.is_connected and self.contact.settings.get('print_join_left'): + if (self.contact.is_joined and + self.contact.settings.get('print_join_left')): self.add_info_message(_('%s has joined the group chat') % nick) return status_codes = properties.muc_status_codes or [] - if not self.is_connected: + if not self.contact.is_joined: # We just joined the room self.add_info_message(_('You (%s) joined the group chat') % nick) @@ -1411,21 +1363,20 @@ def shutdown(self, reason=None): # Remove unread events from systray app.events.remove_events(self.account, self.room_jid) - if self.parent_win is not None: - self.remove_actions() + self.remove_actions() super(GroupchatControl, self).shutdown() app.check_finalize(self) def safe_shutdown(self): # whether to ask for confirmation before closing muc - if app.settings.get('confirm_close_muc') and self.is_connected: + if app.settings.get('confirm_close_muc') and self.contact.is_joined: return False return True def allow_shutdown(self, method, on_yes, on_no): # whether to ask for confirmation before closing muc - if app.settings.get('confirm_close_muc') and self.is_connected: + if app.settings.get('confirm_close_muc') and self.contact.is_joined: def on_ok(is_checked): if is_checked: # User does not want to be asked again @@ -1442,33 +1393,24 @@ def on_cancel(is_checked): _('Leave Group Chat'), _('Are you sure you want to leave this group chat?'), _('If you close this window, you will leave ' - '\'%s\'.') % self.room_name, + '\'%s\'.') % self.contact.name, _('_Do not ask me again'), [DialogButton.make('Cancel', callback=on_cancel), DialogButton.make('Accept', text=_('_Leave'), callback=on_ok)], - transient_for=self.parent_win.window).show() + transient_for=app.window).show() return on_yes(self) def _close_control(self, reason=None): - # if self.parent_win is None: self.shutdown(reason) - # else: - # self.parent_win.remove_tab(self, None, reason=reason, force=True) def set_control_active(self, state): - # self.conv_textview.allow_focus_out_line = True self.attention_flag = False ChatControlBase.set_control_active(self, state) - # if not state: - # # add the focus-out line to the tab we are leaving - # self.check_focus_out_line() - # Sending active to undo unread state - self.parent_win.redraw_tab(self, 'active') def _on_drag_data_received(self, widget, context, x, y, selection, target_type, timestamp): @@ -1617,7 +1559,7 @@ def delegate_action(self, action): if action == 'change-nickname': control_action = '%s-%s' % (action, self.control_id) - self.parent_win.window.lookup_action(control_action).activate() + app.window.lookup_action(control_action).activate() return Gdk.EVENT_STOP if action == 'escape': @@ -1638,11 +1580,11 @@ def delegate_action(self, action): if action == 'change-subject': control_action = '%s-%s' % (action, self.control_id) - self.parent_win.window.lookup_action(control_action).activate() + app.window.lookup_action(control_action).activate() return Gdk.EVENT_STOP if action == 'show-contact-info': - self.parent_win.window.lookup_action( + app.window.lookup_action( 'information-%s' % self.control_id).activate() return Gdk.EVENT_STOP @@ -1716,14 +1658,14 @@ def _on_page_change(self, stack, _param): def _on_change_nick(self, _action, _param): if self._get_current_page() != 'groupchat': return - self.xml.nickname_entry.set_text(self.nick) + self.xml.nickname_entry.set_text(self.contact.nickname) self.xml.nickname_entry.grab_focus() self.xml.nickname_change_button.grab_default() self._show_page('nickname') def _on_nickname_text_changed(self, entry, _param): text = entry.get_text() - if not text or text == self.nick: + if not text or text == self.contact.nickname: self.xml.nickname_change_button.set_sensitive(False) else: try: @@ -1741,7 +1683,7 @@ def _on_nickname_change_clicked(self, _button): def _on_rename_groupchat(self, _action, _param): if self._get_current_page() != 'groupchat': return - self.xml.name_entry.set_text(self.room_name) + self.xml.name_entry.set_text(self.contact.name) self.xml.name_entry.grab_focus() self.xml.rename_button.grab_default() self._show_page('rename') @@ -1788,7 +1730,7 @@ def _on_subject_change_clicked(self, _button): def _on_password_set_clicked(self, _button): password = self.xml.password_entry.get_text() - self._muc_data.password = password + self._client.get_module('MUC').set_password(self.room_jid, password) self._client.get_module('MUC').join(self.room_jid) self._show_page('groupchat') @@ -1810,11 +1752,6 @@ def _on_room_captcha_challenge(self, _contact, _signal_name, properties): self._captcha_request.show_all() self.xml.captcha_box.add(self._captcha_request) - if self.parent_win: - self.parent_win.redraw_tab(self, 'attention') - else: - self.attention_flag = True - self._show_page('captcha') self._captcha_request.focus_first_entry() diff --git a/gajim/gtk/chat_stack.py b/gajim/gtk/chat_stack.py index 4f373bffa1e9e763600fd14df6597a5aeb31a002..5ea020612ac53d88e0a76c5c07ebd5e841d8c37b 100644 --- a/gajim/gtk/chat_stack.py +++ b/gajim/gtk/chat_stack.py @@ -47,8 +47,7 @@ def add_chat(self, account, jid): # Control is already in the Stack return - mw = self.get_toplevel() - chat_control = ChatControl(mw, jid, account, None, None) + chat_control = ChatControl(account, jid) self._controls[(account, jid)] = chat_control self.add_named(chat_control.widget, f'{account}:{jid}') chat_control.widget.show_all() @@ -57,21 +56,13 @@ def add_group_chat(self, account, jid): if self._controls.get((account, jid)) is not None: return - # muc_data = self._create_muc_data(account, - # room_jid, - # nick, - # password, - # None) - - mw = self.get_toplevel() - control = GroupchatControl(mw, jid, None, account) + control = GroupchatControl(account, jid) self._controls[(account, jid)] = control self.add_named(control.widget, f'{account}:{jid}') control.widget.show_all() def add_private_chat(self, account, jid): - mw = self.get_toplevel() - control = PrivateChatControl(mw, jid, account) + control = PrivateChatControl(account, jid) self._controls[(account, str(jid))] = control self.add_named(control.widget, f'{account}:{jid}') control.widget.show_all() diff --git a/gajim/privatechat_control.py b/gajim/privatechat_control.py index 3917a06f2955b457f421bdc5cad5daf7c25fb984..e48153c3e03383aeec6013385e68c289632d9b69 100644 --- a/gajim/privatechat_control.py +++ b/gajim/privatechat_control.py @@ -42,11 +42,11 @@ class PrivateChatControl(ChatControl): # will be processed with this command host. COMMAND_HOST = PrivateChatCommands - def __init__(self, parent_win, jid, account): + def __init__(self, account, jid): self._room_contact = self._client.get_module('Contacts').get_contact( jid.bare) - ChatControl.__init__(self, parent_win, jid, account, None) + ChatControl.__init__(self, account, jid) # self.register_events([ # ('update-gc-avatar', ged.GUI1, self._on_update_gc_avatar),