From 253c7e6cfc75bed65f92f24c50eb05a45517f642 Mon Sep 17 00:00:00 2001 From: Julien Pivotto Date: Thu, 3 May 2007 21:02:50 +0000 Subject: [PATCH] (Fix #3034) Add ability to minimize groupchats in roster, and to minimize autojoigned bookmarked rooms at launch. --- data/glade/gc_control_popup_menu.glade | 32 +++++++-- po/fr.po | 18 +++++ src/chat_control.py | 18 +++++ src/common/config.py | 1 + src/common/connection.py | 1 + src/common/contacts.py | 5 ++ src/common/events.py | 10 ++- src/common/helpers.py | 2 +- src/gajim.py | 96 ++++++++++++++++++++++---- src/groupchat_control.py | 63 +++++++++++++++-- src/message_window.py | 7 +- src/notify.py | 32 ++++++++- src/roster_window.py | 96 +++++++++++++++++++++++++- src/tooltips.py | 16 ++++- 14 files changed, 359 insertions(+), 38 deletions(-) diff --git a/data/glade/gc_control_popup_menu.glade b/data/glade/gc_control_popup_menu.glade index af8dba982..b8894a7cb 100644 --- a/data/glade/gc_control_popup_menu.glade +++ b/data/glade/gc_control_popup_menu.glade @@ -12,7 +12,7 @@ True - + True gtk-justify-fill 1 @@ -31,7 +31,7 @@ True - + True gtk-preferences 1 @@ -51,7 +51,7 @@ True - + True gtk-delete 1 @@ -70,7 +70,7 @@ True - + True gtk-edit 1 @@ -89,7 +89,7 @@ True - + True gtk-redo 1 @@ -108,7 +108,7 @@ True - + True gtk-add 1 @@ -128,6 +128,26 @@ False + + + + True + _Minimize + True + + + + True + gtk-goto-bottom + 1 + 0.5 + 0.5 + 0 + 0 + + + + diff --git a/po/fr.po b/po/fr.po index c649e2c9e..b9f6d8178 100644 --- a/po/fr.po +++ b/po/fr.po @@ -6519,6 +6519,24 @@ msgstr "_Bloquer" msgid "_Unblock" msgstr "_Débloquer" +msgid " [blocked]" +msgstr " [bloqué]" + +msgid "_Maximize" +msgstr "_Maximiser" + +msgid "_Minimize" +msgstr "_Minimiser" + +msgid " [minimized]" +msgstr " [minimisé]" + +msgid "Connected" +msgstr "Connecté" + +msgid "Disconnected" +msgstr "Déconnecté" + #~ msgid "2003-12-13T18:30:02Z" #~ msgstr "2003-12-13T18:30:02Z" #~ msgid "Romeo and Juliet" diff --git a/src/chat_control.py b/src/chat_control.py index 616f22910..6f5ce6687 100644 --- a/src/chat_control.py +++ b/src/chat_control.py @@ -659,6 +659,24 @@ class ChatControlBase(MessageControl): isactive = widget.get_active() self.chat_buttons_set_visible(isactive) + def _on_minimize_menuitem_activate(self, widget): + '''When a grouchat is minimized, unparent the tab, put it in roster etc''' + win = gajim.interface.msg_win_mgr.get_window(self.contact.jid, self.account) + ctrl = win.get_control(self.contact.jid, self.account) + + ctrl_page = win.notebook.page_num(ctrl.widget) + control = win.notebook.get_nth_page(ctrl_page) + + win.notebook.remove_page(ctrl_page) + control.unparent() + + gajim.connections[self.account].hidden_groupchats[self.contact.jid] = ctrl + del win._controls[self.account][self.contact.jid] + + win.check_tabs() + gajim.interface.roster.add_groupchat_to_roster(self.account, + self.contact.jid, status = self.subject) + def set_control_active(self, state): if state: jid = self.contact.jid diff --git a/src/common/config.py b/src/common/config.py index 71f05b176..2dd1fed72 100644 --- a/src/common/config.py +++ b/src/common/config.py @@ -187,6 +187,7 @@ class Config: 'notification_avatar_width': [opt_int, 48], 'notification_avatar_height': [opt_int, 48], 'muc_highlight_words': [opt_str, '', _('A semicolon-separated list of words that will be highlighted in group chats.')], + 'minimize_autojoined_rooms': [opt_bool, False, _('If True, autojoined bookmarked rooms will be minimized on startup.')], 'quit_on_roster_x_button': [opt_bool, False, _('If True, quits Gajim when X button of Window Manager is clicked. This setting is taken into account only if trayicon is used.')], 'check_if_gajim_is_default': [opt_bool, True, _('If True, Gajim will check if it\'s the default jabber client on each startup.')], 'show_unread_tab_icon': [opt_bool, False, _('If True, Gajim will display an icon on each tab containing unread messages. Depending on the theme, this icon may be animated.')], diff --git a/src/common/connection.py b/src/common/connection.py index e14cb6fab..801772d1a 100644 --- a/src/common/connection.py +++ b/src/common/connection.py @@ -70,6 +70,7 @@ class Connection(ConnectionHandlers): self.last_time_to_reconnect = None self.new_account_info = None self.bookmarks = [] + self.hidden_groupchats = {} self.annotations = {} self.on_purpose = False self.last_io = gajim.idlequeue.current_time() diff --git a/src/common/contacts.py b/src/common/contacts.py index 95d3bb17e..9cc92ad74 100644 --- a/src/common/contacts.py +++ b/src/common/contacts.py @@ -82,6 +82,11 @@ class Contact: is_observer = True return is_observer + def is_groupchat(self): + if _('Groupchats') in self.groups: + return True + return False + def is_transport(self): # if not '@' or '@' starts the jid then contact is transport if self.jid.find('@') <= 0: diff --git a/src/common/events.py b/src/common/events.py index b7dd852a1..d8f0c86a1 100644 --- a/src/common/events.py +++ b/src/common/events.py @@ -155,8 +155,9 @@ class Events: self._events[account][new_jid] = self._events[account][old_jid] del self._events[account][old_jid] - def get_nb_events(self, types = [], account = None): - return self._get_nb_events(types = types, account = account) + def get_nb_events(self, types = [], account = None, ignore_types = []): + return self._get_nb_events(types = types, account = account, + ignore_types = ignore_types) def get_events(self, account, jid = None, types = []): '''if event is not specified, get all events from this jid, @@ -185,7 +186,8 @@ class Events: first_event = event return first_event - def _get_nb_events(self, account = None, jid = None, attribute = None, types = []): + def _get_nb_events(self, account = None, jid = None, attribute = None, + types = [], ignore_types = []): '''return the number of pending events''' nb = 0 if account: @@ -205,6 +207,8 @@ class Events: for event in self._events[acct][j]: if types and event.type_ not in types: continue + if ignore_types and event.type_ in ignore_types: + continue if not attribute or \ attribute == 'systray' and event.show_in_systray or \ attribute == 'roster' and event.show_in_roster: diff --git a/src/common/helpers.py b/src/common/helpers.py index e6732bba9..a9910be0d 100644 --- a/src/common/helpers.py +++ b/src/common/helpers.py @@ -40,7 +40,7 @@ try: except: pass -special_groups = (_('Transports'), _('Not in Roster'), _('Observers')) +special_groups = (_('Transports'), _('Not in Roster'), _('Observers'), _('Groupchats')) class InvalidFormat(Exception): pass diff --git a/src/gajim.py b/src/gajim.py index 3faf6102b..a14113021 100755 --- a/src/gajim.py +++ b/src/gajim.py @@ -1052,15 +1052,6 @@ class Interface: show = array[1] status = array[2] - # Get the window and control for the updated status, this may be a - # PrivateChatControl - control = self.msg_win_mgr.get_control(room_jid, account) - if control and control.type_id != message_control.TYPE_GC: - return - if control: - control.chg_contact_status(nick, show, status, array[4], array[5], - array[6], array[7], array[8], array[9], array[10]) - # print status in chat window and update status/GPG image if self.msg_win_mgr.has_window(fjid, account): ctrl = self.msg_win_mgr.get_control(fjid, account) @@ -1079,13 +1070,39 @@ class Interface: if self.remote_ctrl: self.remote_ctrl.raise_signal('GCPresence', (account, array)) + if room_jid in gajim.connections[account].hidden_groupchats: + my_nick = gajim.connections[account].hidden_groupchats[room_jid].nick + first = False + if not gajim.events.get_events(account, room_jid, ['change_status']): + first = True + array = array + (time.localtime(),) + event = gajim.events.create_event('change_status', array, + show_in_roster = False, show_in_systray = False) + gajim.events.add_event(account, room_jid, event) + + # Change status icon if kicked or deconnected from gc + if array[3] == my_nick and array[1] in ('offline', 'error') and \ + array[9] != '303': + gajim.gc_connected[account][room_jid] = False + gajim.interface.roster.draw_contact(room_jid, account) + elif array[3] == my_nick: + gajim.gc_connected[account][room_jid] = True + gajim.interface.roster.draw_contact(room_jid, account) + return + + # Get the window and control for the updated status, this may be a + # PrivateChatControl + control = self.msg_win_mgr.get_control(room_jid, account) + if control and control.type_id != message_control.TYPE_GC: + return + if control: + control.chg_contact_status(nick, show, status, array[4], array[5], + array[6], array[7], array[8], array[9], array[10]) + def handle_event_gc_msg(self, account, array): # ('GC_MSG', account, (jid, msg, time, has_timestamp, htmlmsg)) jids = array[0].split('/', 1) room_jid = jids[0] - gc_control = self.msg_win_mgr.get_control(room_jid, account) - if not gc_control: - return xhtml = array[4] if gajim.config.get('ignore_incoming_xhtml'): xhtml = None @@ -1095,6 +1112,47 @@ class Interface: else: # message from someone nick = jids[1] + + if room_jid in gajim.connections[account].hidden_groupchats: + message = array[1] + tim = array[2] + first = False + + if not gajim.events.get_events(account, room_jid, ['gc_msg', + 'gc_chat']): + first = True + contact = gajim.contacts.get_contact_with_highest_priority( + account, room_jid) + advanced_notif_num = notify.get_advanced_notification\ + ('message_received', account, contact) + ctrl = gajim.connections[account].hidden_groupchats[room_jid] + + type_event = 'gc_msg' + do_popup = False + is_history = False + show_in_systray = False + show_in_roster = True + if not array[3] and ctrl.needs_visual_notification(message): + do_popup = True + show_in_systray = True + if array[3] or nick == '': + is_history = True + type_event = 'gc_history' + show_in_roster = False + if not array[3]: + notify.notify('new_gc_message', room_jid, account, [do_popup, + first, nick, message, is_history], advanced_notif_num) + event = gajim.events.create_event(type_event, (nick, array[1], + array[2], array[3], xhtml), show_in_roster = show_in_roster, + show_in_systray = show_in_systray) + gajim.events.add_event(account, room_jid, event) + gajim.interface.roster.draw_contact(room_jid, account) + gajim.interface.roster.show_title() + return + + gc_control = self.msg_win_mgr.get_control(room_jid, account) + if not gc_control: + return gc_control.on_message(nick, array[1], array[2], array[3], xhtml) if self.remote_ctrl: self.remote_ctrl.raise_signal('GCMessage', (account, array)) @@ -1103,6 +1161,17 @@ class Interface: #('GC_SUBJECT', account, (jid, subject, body, has_timestamp)) jids = array[0].split('/', 1) jid = jids[0] + if jid in gajim.connections[account].hidden_groupchats: + array = (array[0], array[1], array[2]) + (time.localtime(),) + event = gajim.events.create_event('change_subject', + array, show_in_roster = False, show_in_systray = False) + gajim.events.add_event(account, jid, event) + contact = gajim.contacts.\ + get_contact_with_highest_priority(account, jid) + contact.status = array[1] + gajim.interface.roster.draw_contact(jid, account) + return + gc_control = self.msg_win_mgr.get_control(jid, account) if not gc_control: return @@ -1246,7 +1315,8 @@ class Interface: for bm in bms: if bm['autojoin'] in ('1', 'true'): self.roster.join_gc_room(account, bm['jid'], bm['nick'], - bm['password']) + bm['password'], + minimize = gajim.config.get('minimize_autojoined_rooms')) def handle_event_file_send_error(self, account, array): jid = array[0] diff --git a/src/groupchat_control.py b/src/groupchat_control.py index 0a6c363af..3165a3644 100644 --- a/src/groupchat_control.py +++ b/src/groupchat_control.py @@ -240,6 +240,10 @@ class GroupchatControl(ChatControlBase): id = widget.connect('activate', self._on_history_menuitem_activate) self.handlers[id] = widget + widget = xm.get_widget('minimize_menuitem') + id = widget.connect('activate', self._on_minimize_menuitem_activate) + self.handlers[id] = widget + self.gc_popup_menu = xm.get_widget('gc_control_popup_menu') self.name_label = self.xml.get_widget('banner_name_label') @@ -590,7 +594,7 @@ class GroupchatControl(ChatControlBase): small_attr = [] ChatControlBase.print_conversation_line(self, text, kind, contact, tim, small_attr, small_attr + ['restored_message'], - small_attr + ['restored_message'], xhtml = xhtml) + small_attr + ['restored_message'], count_as_new = False, xhtml = xhtml) def print_conversation(self, text, contact = '', tim = None, xhtml = None): '''Print a line in the conversation: @@ -833,7 +837,7 @@ class GroupchatControl(ChatControlBase): model[iter][C_AVATAR] = scaled_pixbuf def chg_contact_status(self, nick, show, status, role, affiliation, jid, - reason, actor, statusCode, new_nick): + reason, actor, statusCode, new_nick, tim = None): '''When an occupant changes his or her status''' if show == 'invisible': return @@ -855,7 +859,7 @@ class GroupchatControl(ChatControlBase): 'nick': nick, 'who': actor, 'reason': reason } - self.print_conversation(s, 'info') + self.print_conversation(s, 'info', tim = tim) elif statusCode == '301': if actor is None: # do not print 'banned by None' s = _('%(nick)s has been banned: %(reason)s') % { @@ -866,7 +870,7 @@ class GroupchatControl(ChatControlBase): 'nick': nick, 'who': actor, 'reason': reason } - self.print_conversation(s, 'info') + self.print_conversation(s, 'info', tim = tim) elif statusCode == '303': # Someone changed his or her nick if nick == self.nick: # We changed our nick self.nick = new_nick @@ -901,9 +905,9 @@ class GroupchatControl(ChatControlBase): # Windows require this os.remove(files[old_file]) os.rename(old_file, files[old_file]) - self.print_conversation(s, 'info') + self.print_conversation(s, 'info', tim) elif statusCode == 'destroyed': # Room has been destroyed - self.print_conversation(reason, 'info') + self.print_conversation(reason, 'info', tim) if len(gajim.events.get_events(self.account, self.room_jid + '/' + nick)) == 0: @@ -969,7 +973,7 @@ class GroupchatControl(ChatControlBase): if st: if status: st += ' (' + status + ')' - self.print_conversation(st) + self.print_conversation(st, tim = tim) def add_contact_to_roster(self, nick, show, role, affiliation, status, jid = ''): @@ -2012,3 +2016,48 @@ class GroupchatControl(ChatControlBase): self.grant_owner(widget, jid) else: self.revoke_owner(widget, jid) + + def read_queue(self, jid, account): + '''read queue and print messages containted in it''' + events = gajim.events.get_events(account, jid) + + for event in events: + if event.type_ == 'change_subject': + array = event.parameters + jids = array[0].split('/', 1) + jid = jids[0] + self.set_subject(array[1]) + text = None + if len(jids) > 1: + text = _('%s has set the subject to %s') % (jids[1], array[1]) + elif array[2]: + text = array[2] + if text is not None: + self.print_conversation(text, tim = array[3]) + + if event.type_ == 'change_status': + array = event.parameters + nick = array[3] + if not nick: + return + room_jid = array[0] + fjid = room_jid + '/' + nick + show = array[1] + status = array[2] + self.chg_contact_status(nick, show, status, array[4], array[5], + array[6], array[7], array[8], array[9], array[10], array[11]) + + self.parent_win.redraw_tab(self) + + if event.type_ in ['gc_msg', 'gc_history']: + array = event.parameters + kind = array[0] + if kind == 'error' or kind == 'status': + kind = 'info' + self.on_message(kind, array[1], array[2], array[3], array[4]) + + gajim.events.remove_events(account, jid, + types = ['change_status', 'gc_msg', 'gc_history', + 'change_subject']) + gajim.interface.roster.draw_contact(jid, account) + gajim.interface.roster.show_title() diff --git a/src/message_window.py b/src/message_window.py index ed1ec93ab..4d3d51a2b 100644 --- a/src/message_window.py +++ b/src/message_window.py @@ -318,6 +318,10 @@ class MessageWindow: if len(self._controls[ctrl.account]) == 0: del self._controls[ctrl.account] + self.check_tabs() + self.show_title() + + def check_tabs(self): if self.get_num_controls() == 0: # These are not called when the window is destroyed like this, fake it gajim.interface.msg_win_mgr._on_window_delete(self.window, None) @@ -332,9 +336,8 @@ class MessageWindow: self.notebook.set_show_tabs(show_tabs_if_one_tab) if not show_tabs_if_one_tab: self.alignment.set_property('top-padding', 0) - self.show_title() - + def redraw_tab(self, ctrl, chatstate = None): hbox = self.notebook.get_tab_label(ctrl.widget).get_children()[0] status_img = hbox.get_children()[0] diff --git a/src/notify.py b/src/notify.py index 104dc7733..b24ee16d4 100644 --- a/src/notify.py +++ b/src/notify.py @@ -153,10 +153,25 @@ def notify(event, jid, account, parameters, advanced_notif_num = None): is_first_message = parameters[1] nickname = parameters[2] message = parameters[3] + if is_first_message and helpers.allow_sound_notification( + 'first_message_received', advanced_notif_num): + do_sound = True + elif not is_first_message and helpers.allow_sound_notification( + 'next_message_received', advanced_notif_num): + do_sound = True if helpers.allow_showing_notification(account, 'notify_on_new_message', advanced_notif_num, is_first_message): do_popup = True - if is_first_message and helpers.allow_sound_notification( + elif event == 'new_gc_message': + message_type = 'gc_msg' + do_popup = parameters[0] + is_first_message = parameters[1] + nickname = parameters[2] + message = parameters[3] + is_history = parameters[4] + if is_history: + pass + elif is_first_message and helpers.allow_sound_notification( 'first_message_received', advanced_notif_num): do_sound = True elif not is_first_message and helpers.allow_sound_notification( @@ -245,6 +260,19 @@ def notify(event, jid, account, parameters, advanced_notif_num = None): path = gtkgui_helpers.get_path_to_generic_or_avatar(img) popup(event_type, jid, account, message_type, path_to_image = path, title = title, text = text) + elif event == 'new_gc_message': + event_type = _('New Groupchat Message') + room_jid = jid + name = gajim.connections[account].hidden_groupchats[room_jid].name + img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events', + 'gc_invitation.png') + title = _('New Message on %s') % name + text = _('%(nickname)s: %(message)s') % {'nickname': nickname, + 'message': message} + path = gtkgui_helpers.get_path_to_generic_or_avatar(img) + popup(event_type, jid, account, message_type, + path_to_image = path, title = title, text = text) + if do_sound: snd_file = None @@ -434,6 +462,8 @@ class DesktopNotification: ntype = 'presence.status' elif event_type == _('Connection Failed'): ntype = 'connection.failed' + elif event_type == _('New Groupchat Message'): + ntype = 'im' else: # default failsafe values self.path_to_image = os.path.abspath( diff --git a/src/roster_window.py b/src/roster_window.py index b99502c22..c451913f3 100644 --- a/src/roster_window.py +++ b/src/roster_window.py @@ -280,6 +280,7 @@ class RosterWindow: if hide and contact.sub != 'from': return observer = contact.is_observer() + groupchat = contact.is_groupchat() if observer: # if he has a tag, remove it @@ -369,6 +370,8 @@ class RosterWindow: typestr = 'contact' if group == _('Transports'): typestr = 'agent' + if group == _('Groupchats'): + typestr = 'groupchat' name = contact.get_shown_name() # we add some values here. see draw_contact for more @@ -417,6 +420,20 @@ class RosterWindow: self.add_contact_to_roster(contact.jid, account) return contact + def add_groupchat_to_roster(self, account, jid, nick = '', resource = '', + status = ''): + ''' add groupchat to roster ''' + contact = gajim.contacts.get_contact_with_highest_priority(account, jid) + if contact == None: + contact = gajim.contacts.create_contact(jid = jid, name = jid, + groups = [_('Groupchats')], show = 'muc_active', + status = status, sub = 'none', + resource = resource) + gajim.contacts.add_contact(account, contact) + self.add_contact_to_roster(jid, account) + self.draw_group(_('Groupchats'), account) + return contact + def get_self_contact_iter(self, account): model = self.tree.get_model() iterAcct = self.get_account_iter(account) @@ -661,6 +678,13 @@ class RosterWindow: state_images = self.get_appropriate_state_images(jid, icon_name = icon_name) + if icon_name != 'message' and gajim.gc_connected[account].\ + has_key(jid): + if gajim.gc_connected[account][jid]: + icon_name = 'muc_active' + else: + icon_name = 'muc_inactive' + img = state_images[icon_name] for iter in iters: @@ -695,7 +719,7 @@ class RosterWindow: for iter in iters: model[iter][C_SECPIXBUF] = scaled_pixbuf - def join_gc_room(self, account, room_jid, nick, password): + def join_gc_room(self, account, room_jid, nick, password, minimize = False): '''joins the room immediatelly''' if gajim.interface.msg_win_mgr.has_window(room_jid, account) and \ gajim.gc_connected[account][room_jid]: @@ -704,11 +728,23 @@ class RosterWindow: win.set_active_tab(room_jid, account) dialogs.ErrorDialog(_('You are already in group chat %s') % room_jid) return + if gajim.connections[account].hidden_groupchats.has_key(room_jid): + self.on_groupchat_maximized(None, room_jid, account) + return invisible_show = gajim.SHOW_LIST.index('invisible') if gajim.connections[account].connected == invisible_show: dialogs.ErrorDialog( _('You cannot join a group chat while you are invisible')) return + if minimize: + contact = gajim.contacts.create_contact(jid = room_jid, name = nick) + gc_control = GroupchatControl(None, contact, account) + gajim.connections[account].hidden_groupchats[room_jid] = gc_control + self.add_groupchat_to_roster(account, room_jid) + gajim.connections[account].join_gc(nick, room_jid, password) + if password: + gajim.gc_passwords[room_jid] = password + return if not gajim.interface.msg_win_mgr.has_window(room_jid, account): self.new_room(room_jid, nick, account) gc_win = gajim.interface.msg_win_mgr.get_window(room_jid, account) @@ -1335,6 +1371,15 @@ class RosterWindow: self.tooltip.account = account self.tooltip.timeout = gobject.timeout_add(500, self.show_tooltip, connected_contacts) + elif model[iter][C_TYPE] == 'groupchat': + account = model[iter][C_ACCOUNT].decode('utf-8') + jid = model[iter][C_JID].decode('utf-8') + if self.tooltip.timeout == 0 or self.tooltip.id != props[0]: + self.tooltip.id = row + contact = gajim.contacts.get_contact(account, jid) + self.tooltip.account = account + self.tooltip.timeout = gobject.timeout_add(500, + self.show_tooltip, contact) elif model[iter][C_TYPE] == 'account': # we're on an account entry in the roster account = model[iter][C_ACCOUNT].decode('utf-8') @@ -2330,6 +2375,48 @@ class RosterWindow: menu.show_all() menu.popup(None, None, None, event_button, event.time) + def make_groupchat_menu(self, event, iter): + model = self.tree.get_model() + + path = model.get_path(iter) + jid = model[iter][C_JID].decode('utf-8') + account = model[iter][C_ACCOUNT].decode('utf-8') + + menu = gtk.Menu() + + maximize_menuitem = gtk.ImageMenuItem(_('_Maximize')) + icon = gtk.image_new_from_stock(gtk.STOCK_GOTO_TOP, gtk.ICON_SIZE_MENU) + maximize_menuitem.set_image(icon) + maximize_menuitem.connect('activate', self.on_groupchat_maximized, \ + jid, account) + + menu.append(maximize_menuitem) + + event_button = gtkgui_helpers.get_possible_button_event(event) + + menu.attach_to_widget(self.tree, None) + menu.connect('selection-done', gtkgui_helpers.destroy_widget) + menu.show_all() + menu.popup(None, None, None, event_button, event.time) + + def on_groupchat_maximized(self, widget, jid, account): + '''When a groupshat is maximised''' + ctrl = gajim.connections[account].hidden_groupchats[jid] + mw = gajim.interface.msg_win_mgr.get_window(ctrl.contact.jid, ctrl.account) + if not mw: + mw = gajim.interface.msg_win_mgr.create_window(ctrl.contact, \ + ctrl.account, ctrl.type_id) + ctrl.parent_win = mw + mw.new_tab(ctrl) + mw.set_active_tab(jid, account) + mw.window.present() + ctrl.read_queue(jid, account) + contact = gajim.contacts.get_contact_with_highest_priority(account, jid) + self.remove_contact(contact, account) + gajim.contacts.remove_contact(account, contact) + self.draw_group(_('Groupchats'), account) + del gajim.connections[account].hidden_groupchats[jid] + def make_group_menu(self, event, iter): '''Make group's popup menu''' model = self.tree.get_model() @@ -2811,6 +2898,8 @@ class RosterWindow: return if type_ == 'group' and len(iters) == 1: self.make_group_menu(event, iters[0]) + if type_ == 'groupchat' and len(iters) == 1: + self.make_groupchat_menu(event, iters[0]) elif type_ == 'agent' and len(iters) == 1: self.make_transport_menu(event, iters[0]) elif type_ in ('contact', 'self_contact') and len(iters) == 1: @@ -3697,7 +3786,8 @@ class RosterWindow: # check if we have unread or recent mesages unread = False recent = False - if gajim.events.get_nb_events() > 0: + if gajim.events.get_nb_events(ignore_types = ['gc_history', + 'change_status', 'change_subject']) > 0: unread = True for win in gajim.interface.msg_win_mgr.windows(): unrd = 0 @@ -3818,6 +3908,8 @@ class RosterWindow: self.tree.collapse_row(path) else: self.tree.expand_row(path, False) + elif gajim.connections[account].hidden_groupchats.has_key(jid): + self.on_groupchat_maximized(None, jid, account) else: first_ev = gajim.events.get_first_event(account, jid) if not first_ev: diff --git a/src/tooltips.py b/src/tooltips.py index 78862a9c4..3b4b5e3e8 100644 --- a/src/tooltips.py +++ b/src/tooltips.py @@ -411,9 +411,12 @@ class RosterTooltip(NotificationAreaTooltip): + '' if self.account and prim_contact.jid in gajim.connections[ self.account].blocked_contacts: - name_markup += u' [blocked]' + name_markup += _(' [blocked]') + if self.account and gajim.connections[self.account].\ + hidden_groupchats.has_key(prim_contact.jid): + name_markup += _(' [minimized]') properties.append((name_markup, None)) - + num_resources = 0 # put contacts in dict, where key is priority contacts_dict = {} @@ -474,6 +477,12 @@ class RosterTooltip(NotificationAreaTooltip): locale.getpreferredencoding()) text = text % local_time show += text + if self.account and \ + gajim.gc_connected[self.account].has_key(prim_contact.jid): + if gajim.gc_connected[self.account][prim_contact.jid]: + show = _('Connected') + else: + show = _('Disconnected') show = '' + show + '' # we append show below @@ -497,7 +506,8 @@ class RosterTooltip(NotificationAreaTooltip): gobject.markup_escape_text(contact.resource) +\ ' (' + unicode(contact.priority) + ')')) - if prim_contact.sub and prim_contact.sub != 'both': + if self.account and prim_contact.sub and prim_contact.sub != 'both' and\ + not gajim.gc_connected[self.account].has_key(prim_contact.jid): # ('both' is the normal sub so we don't show it) properties.append(( _('Subscription: '), gobject.markup_escape_text(helpers.get_uf_sub(prim_contact.sub))))