From 95d7e157da0fb7ed9d86f2774a8f30ac22656b56 Mon Sep 17 00:00:00 2001 From: Yann Leboulanger Date: Fri, 13 Feb 2009 19:35:30 +0000 Subject: [PATCH] handle (un)subscription events as messages (don't force to popup a window) Fixes #2243 --- data/pixmaps/events/subscription_request.png | Bin 0 -> 4156 bytes data/pixmaps/events/unsubscribed.png | Bin 0 -> 3657 bytes src/common/events.py | 13 ++-- src/dialogs.py | 3 + src/gajim.py | 68 ++++++++++++++++--- src/notify.py | 4 ++ src/roster_window.py | 8 +++ 7 files changed, 81 insertions(+), 15 deletions(-) create mode 100644 data/pixmaps/events/subscription_request.png create mode 100644 data/pixmaps/events/unsubscribed.png diff --git a/data/pixmaps/events/subscription_request.png b/data/pixmaps/events/subscription_request.png new file mode 100644 index 0000000000000000000000000000000000000000..f3eeb37da85ee181b07f746a84d85ddb3adb7d9f GIT binary patch literal 4156 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 b0|5RXegt0h$?}fI00000NkvXXu0mjf0c!vZ literal 0 HcmV?d00001 diff --git a/src/common/events.py b/src/common/events.py index cb819d594..82017112a 100644 --- a/src/common/events.py +++ b/src/common/events.py @@ -28,11 +28,12 @@ import time class Event: '''Information concerning each event''' - def __init__(self, type_, time_, parameters, show_in_roster = False, - show_in_systray = True): + def __init__(self, type_, time_, parameters, show_in_roster=False, + show_in_systray=True): ''' type_ in chat, normal, file-request, file-error, file-completed, file-request-error, file-send-error, file-stopped, gc_msg, pm, - printed_chat, printed_gc_msg, printed_marked_gc_msg, printed_pm + printed_chat, printed_gc_msg, printed_marked_gc_msg, printed_pm, + gc-invitation, subscription_request, unsubscribed parameters is (per type_): chat, normal, pm: [message, subject, kind, time, encrypted, resource, msg_id] @@ -41,7 +42,11 @@ class Event: gc_msg: None printed_chat: control printed_*: None - messages that are already printed in chat, but not read''' + messages that are already printed in chat, but not read + gc-invitation: [room_jid, reason, password, is_continued] + subscription_request: [text, nick] + unsubscribed: contact + ''' self.type_ = type_ self.time_ = time_ self.parameters = parameters diff --git a/src/dialogs.py b/src/dialogs.py index fb531973d..de8e7f5b6 100644 --- a/src/dialogs.py +++ b/src/dialogs.py @@ -1644,6 +1644,9 @@ class SubscriptionRequestWindow: def on_deny_button_clicked(self, widget): '''refuse the request''' gajim.connections[self.account].refuse_authorization(self.jid) + contact = gajim.contacts.get_contact(self.account, self.jid) + if contact and _('Not in Roster') in contact.get_shown_groups(): + gajim.interface.roster.remove_contact(self.jid, self.account) self.window.destroy() def on_actions_button_clicked(self, widget): diff --git a/src/gajim.py b/src/gajim.py index 081d84a58..d0ee392b1 100644 --- a/src/gajim.py +++ b/src/gajim.py @@ -959,10 +959,26 @@ class Interface: def handle_event_subscribe(self, account, array): #('SUBSCRIBE', account, (jid, text, user_nick)) user_nick is JEP-0172 - dialogs.SubscriptionRequestWindow(array[0], array[1], account, array[2]) if self.remote_ctrl: self.remote_ctrl.raise_signal('Subscribe', (account, array)) + jid = array[0] + text = array[1] + nick = array[2] + if helpers.allow_popup_window(account) or not self.systray_enabled: + dialogs.SubscriptionRequestWindow(jid, text, account, nick) + return + + self.add_event(account, jid, 'subscription_request', (text, nick)) + + if helpers.allow_showing_notification(account): + path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events', + 'subscription_request.png') + path = gtkgui_helpers.get_path_to_generic_or_avatar(path) + event_type = _('Subscription request') + notify.popup(event_type, jid, account, 'subscription_request', path, + event_type, jid) + def handle_event_subscribed(self, account, array): #('SUBSCRIBED', account, (jid, resource)) jid = array[0] @@ -992,7 +1008,20 @@ class Interface: if self.remote_ctrl: self.remote_ctrl.raise_signal('Subscribed', (account, array)) + def show_unsubscribed_dialog(self, account, contact): + def on_yes(is_checked, list_): + self.roster.on_req_usub(None, list_) + list_ = [(contact, account)] + dialogs.YesNoDialog( + _('Contact "%s" removed subscription from you') % contact.jid, + _('You will always see him or her as offline.\nDo you want to ' + 'remove him or her from your contact list?'), + on_response_yes=(on_yes, list_)) + # FIXME: Per RFC 3921, we can "deny" ack as well, but the GUI does + # not show deny + def handle_event_unsubscribed(self, account, jid): + #('UNSUBSCRIBED', account, jid) gajim.connections[account].ack_unsubscribed(jid) if self.remote_ctrl: self.remote_ctrl.raise_signal('Unsubscribed', (account, jid)) @@ -1000,14 +1029,19 @@ class Interface: contact = gajim.contacts.get_first_contact_from_jid(account, jid) if not contact: return - def on_yes(is_checked, list_): - self.roster.on_req_usub(None, list_) - list_ = [(contact, account)] - dialogs.YesNoDialog( - _('Contact "%s" removed subscription from you') % jid, - _('You will always see him or her as offline.\nDo you want to remove him or her from your contact list?'), - on_response_yes=(on_yes, list_)) - # FIXME: Per RFC 3921, we can "deny" ack as well, but the GUI does not show deny + + if helpers.allow_popup_window(account) or not self.systray_enabled: + self.show_unsubscribed_dialog(account, contact) + + self.add_event(account, jid, 'unsubscribed', contact) + + if helpers.allow_showing_notification(account): + path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events', + 'unsubscribed.png') + path = gtkgui_helpers.get_path_to_generic_or_avatar(path) + event_type = _('Unsubscribed') + notify.popup(event_type, jid, account, 'unsubscribed', path, + event_type, jid) def handle_event_agent_info_error(self, account, agent): #('AGENT_ERROR_INFO', account, (agent)) @@ -2256,8 +2290,8 @@ class Interface: show_in_roster = notify.get_show_in_roster(event_type, account, jid) show_in_systray = notify.get_show_in_systray(event_type, account, jid) event = gajim.events.create_event(type_, event_args, - show_in_roster = show_in_roster, - show_in_systray = show_in_systray) + show_in_roster=show_in_roster, + show_in_systray=show_in_systray) gajim.events.add_event(account, jid, event) self.roster.show_title() @@ -2389,6 +2423,18 @@ class Interface: data[1], data[3]) gajim.events.remove_events(account, jid, event) self.roster.draw_contact(jid, account) + elif type_ == 'subscription_request': + event = gajim.events.get_first_event(account, jid, type_) + data = event.parameters + dialogs.SubscriptionRequestWindow(jid, data[0], account, data[1]) + gajim.events.remove_events(account, jid, event) + self.roster.draw_contact(jid, account) + elif type_ == 'unsubscribed': + event = gajim.events.get_first_event(account, jid, type_) + contact = event.parameters + self.show_unsubscribed_dialog(account, contact) + gajim.events.remove_events(account, jid, event) + self.roster.draw_contact(jid, account) if w: w.set_active_tab(ctrl) w.window.window.focus() diff --git a/src/notify.py b/src/notify.py index 6b2b7da14..97deface2 100644 --- a/src/notify.py +++ b/src/notify.py @@ -492,6 +492,10 @@ class DesktopNotification: ntype = 'presence.status' elif event_type == _('Connection Failed'): ntype = 'connection.failed' + elif event_type == _('Subscription request'): + ntype = 'subscription.request' + elif event_type == _('Unsubscribed'): + ntype = 'unsubscribed' else: # default failsafe values self.path_to_image = os.path.abspath( diff --git a/src/roster_window.py b/src/roster_window.py index f7be989fb..0e819e3ba 100644 --- a/src/roster_window.py +++ b/src/roster_window.py @@ -1832,6 +1832,14 @@ class RosterWindow: data[1]) gajim.events.remove_events(account, jid, event) return True + elif event.type_ == 'subscription_request': + dialogs.SubscriptionRequestWindow(jid, data[0], account, data[1]) + gajim.events.remove_events(account, jid, event) + return True + elif event.type_ == 'unsubscribed': + gajim.interface.show_unsubscribed_dialog(account, data) + gajim.events.remove_events(account, jid, event) + return True return False ################################################################################