Author: steve-e Date: 2008-07-19 19:36:21 +0200 (Sat, 19 Jul 2008) New Revision: 9960
Removed: trunk/data/glade/invitation_received_dialog.glade Modified: trunk/src/dialogs.py trunk/src/gajim.py trunk/src/groupchat_control.py trunk/src/roster_window.py Log: Improved groupchat minimization:
* partly rewrote join_room because it was hard to read * Correctly handle invites from anonymous rooms. Fixes #4057 * Use HIG dialog for invitation requests * Fix bug where minimized groupchats where hidden after a reconnect * Removed some duplicated code
Deleted: trunk/data/glade/invitation_received_dialog.glade =================================================================== --- trunk/data/glade/invitation_received_dialog.glade 2008-07-19 14:45:04 UTC (rev 9959) +++ trunk/data/glade/invitation_received_dialog.glade 2008-07-19 17:36:21 UTC (rev 9960) @@ -1,221 +0,0 @@ -<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> -<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> - -<glade-interface> - -<widget class="GtkDialog" id="invitation_received_dialog"> - <property name="border_width">6</property> - <property name="title" translatable="yes">Invitation Received</property> - <property name="type">GTK_WINDOW_TOPLEVEL</property> - <property name="window_position">GTK_WIN_POS_NONE</property> - <property name="modal">False</property> - <property name="resizable">True</property> - <property name="destroy_with_parent">False</property> - <property name="decorated">True</property> - <property name="skip_taskbar_hint">False</property> - <property name="skip_pager_hint">False</property> - <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> - <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> - <property name="focus_on_map">True</property> - <property name="has_separator">True</property> - - <child internal-child="vbox"> - <widget class="GtkVBox" id="dialog-vbox11"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="dialog-action_area10"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - - <child> - <widget class="GtkButton" id="deny_button"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="can_focus">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="focus_on_click">True</property> - <property name="response_id">-9</property> - - <child> - <widget class="GtkAlignment" id="alignment95"> - <property name="visible">True</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - <property name="top_padding">0</property> - <property name="bottom_padding">0</property> - <property name="left_padding">0</property> - <property name="right_padding">0</property> - - <child> - <widget class="GtkHBox" id="hbox2995"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">2</property> - - <child> - <widget class="GtkImage" id="image1238"> - <property name="visible">True</property> - <property name="stock">gtk-cancel</property> - <property name="icon_size">4</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label362"> - <property name="visible">True</property> - <property name="label" translatable="yes">Deny</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - </child> - </widget> - </child> - </widget> - </child> - - <child> - <widget class="GtkButton" id="accept_button"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="can_focus">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="focus_on_click">True</property> - <property name="response_id">-8</property> - - <child> - <widget class="GtkAlignment" id="alignment94"> - <property name="visible">True</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - <property name="top_padding">0</property> - <property name="bottom_padding">0</property> - <property name="left_padding">0</property> - <property name="right_padding">0</property> - - <child> - <widget class="GtkHBox" id="hbox2994"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">2</property> - - <child> - <widget class="GtkImage" id="image1237"> - <property name="visible">True</property> - <property name="stock">gtk-apply</property> - <property name="icon_size">4</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label361"> - <property name="visible">True</property> - <property name="label" translatable="yes">Accept</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - </child> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes"></property> - <property name="use_underline">False</property> - <property name="use_markup">True</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">True</property> - <property name="selectable">True</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - </child> -</widget> - -</glade-interface>
Modified: trunk/src/dialogs.py =================================================================== --- trunk/src/dialogs.py 2008-07-19 14:45:04 UTC (rev 9959) +++ trunk/src/dialogs.py 2008-07-19 17:36:21 UTC (rev 9960) @@ -2214,8 +2214,8 @@ self.instances.remove(self)
def set_cursor_to_end(self): - end_iter = self.message_tv_buffer.get_end_iter() - self.message_tv_buffer.place_cursor(end_iter) + end_iter = self.message_tv_buffer.get_end_iter() + self.message_tv_buffer.place_cursor(end_iter)
def save_pos(self): # save the window size and position @@ -2920,51 +2920,35 @@ self.account = account self.password = password self.is_continued = is_continued - xml = gtkgui_helpers.get_glade('invitation_received_dialog.glade') - self.dialog = xml.get_widget('invitation_received_dialog')
+ pritext = _('''You are invited to a groupchat''') #Don't translate $Contact if is_continued: - pritext = _('$Contact has invited you to join a discussion') + sectext = _('$Contact has invited you to join a discussion') else: - pritext = _('$Contact has invited you to group chat %(room_jid)s')\ + sectext = _('$Contact has invited you to group chat %(room_jid)s')\ % {'room_jid': room_jid} contact = gajim.contacts.get_first_contact_from_jid(account, contact_jid) - if contact and contact.name: - contact_text = '%s (%s)' % (contact.name, contact_jid) - else: - contact_text = contact_jid - pritext = pritext.replace('$Contact', contact_text) + contact_text = contact and contact.name or contact_jid + sectext = sectext.replace('$Contact', contact_text)
- label_text = '<big><b>%s</b></big>' % pritext - if comment: # only if not None and not '' comment = gobject.markup_escape_text(comment) - sectext = _('Comment: %s') % comment - label_text += '\n\n%s' % sectext + comment = _('Comment: %s') % comment + sectext += '\n\n%s' % comment + sectext += '\n\n' + _('Do you want to accept the invitation?') + + dialog = YesNoDialog(pritext, sectext) + if dialog.get_response() == gtk.RESPONSE_YES: + try: + if self.is_continued: + gajim.interface.join_gc_room(self.account, self.room_jid, + gajim.nicks[self.account], None, is_continued=True) + else: + JoinGroupchatWindow(self.account, self.room_jid) + except GajimGeneralException: + pass
- xml.get_widget('label').set_markup(label_text) - - xml.get_widget('deny_button').connect('clicked', - self.on_deny_button_clicked) - xml.get_widget('accept_button').connect('clicked', - self.on_accept_button_clicked) - self.dialog.show_all() - - def on_deny_button_clicked(self, widget): - self.dialog.destroy() - - def on_accept_button_clicked(self, widget): - self.dialog.destroy() - try: - if self.is_continued: - gajim.interface.join_gc_room(self.account, self.room_jid, - gajim.nicks[self.account], None, is_continued=True) - else: - JoinGroupchatWindow(self.account, self.room_jid) - except GajimGeneralException: - pass - class ProgressDialog: def __init__(self, title_text, during_text, messages_queue): '''during text is what to show during the procedure,
Modified: trunk/src/gajim.py =================================================================== --- trunk/src/gajim.py 2008-07-19 14:45:04 UTC (rev 9959) +++ trunk/src/gajim.py 2008-07-19 17:36:21 UTC (rev 9960) @@ -2128,11 +2128,7 @@
if type_ in ('printed_gc_msg', 'printed_marked_gc_msg', 'gc_msg'): w = self.msg_win_mgr.get_window(jid, account) - if self.minimized_controls[account].has_key(jid): - if not w: - ctrl = self.minimized_controls[account][jid] - w = self.msg_win_mgr.create_window(ctrl.contact, \ - ctrl.account, ctrl.type_id) + if jid in self.minimized_controls[account]: self.roster.on_groupchat_maximized(None, jid, account)
if not ctrl: @@ -2473,48 +2469,51 @@ ################################################################################
def join_gc_room(self, account, room_jid, nick, password, minimize=False, - is_continued=False): + is_continued=False): '''joins the room immediately''' if not nick: nick = gajim.nicks[account] + if self.msg_win_mgr.has_window(room_jid, account) and \ - gajim.gc_connected[account][room_jid]: + gajim.gc_connected[account][room_jid]: gc_ctrl = self.msg_win_mgr.get_gc_control(room_jid, account) win = gc_ctrl.parent_win win.set_active_tab(gc_ctrl) dialogs.ErrorDialog(_('You are already in group chat %s') % room_jid) return - minimized_control_exists = False - if room_jid in gajim.interface.minimized_controls[account]: - minimized_control_exists = True + 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 and not minimized_control_exists and \ + + minimized_control_exists = False + if room_jid in gajim.interface.minimized_controls[account]: + minimized_control_exists = True + + if not minimized_control_exists and \ not self.msg_win_mgr.has_window(room_jid, account): - contact = gajim.contacts.create_contact(jid=room_jid, name=nick) - gc_control = GroupchatControl(None, contact, account) - self.minimized_controls[account][room_jid] = gc_control - gajim.connections[account].join_gc(nick, room_jid, password) - if password: - gajim.gc_passwords[room_jid] = password + # Join new groupchat + if minimize: + contact = gajim.contacts.create_contact(jid=room_jid, name=nick) + gc_control = GroupchatControl(None, contact, account) + gajim.interface.minimized_controls[account][room_jid] = gc_control + self.roster.add_groupchat(room_jid, account) + else: + self.new_room(room_jid, nick, account, is_continued=is_continued) + elif not minimized_control_exists: + # We are already in that groupchat + gc_control = self.msg_win_mgr.get_gc_control(room_jid, account) + gc_control.parent_win.set_active_tab(gc_control) + else: + # We are already in this groupchat and it is minimized self.roster.add_groupchat(room_jid, account) - return - if not minimized_control_exists and \ - not self.msg_win_mgr.has_window(room_jid, account): - self.new_room(room_jid, nick, account, is_continued=is_continued) - if not minimized_control_exists: - gc_control = self.msg_win_mgr.get_gc_control(room_jid, account) - gc_control.parent_win.set_active_tab(gc_control) + + # Connect gajim.connections[account].join_gc(nick, room_jid, password) if password: gajim.gc_passwords[room_jid] = password - contact = gajim.contacts.get_contact_with_highest_priority(account, \ - room_jid) - if contact or minimized_control_exists: - self.roster.add_groupchat(room_jid, account)
def new_room(self, room_jid, nick, account, is_continued=False): # Get target window, create a control, and associate it with the window @@ -2821,11 +2820,16 @@ jid = bm['jid'] # Only join non-opened groupchats. Opened one are already # auto-joined on re-connection - if not gajim.gc_connected[account].has_key(jid): + if not jid in gajim.gc_connected[account]: # we are not already connected minimize = bm['minimize'] in ('1', 'true') gajim.interface.join_gc_room(account, jid, bm['nick'], bm['password'], minimize = minimize) + elif jid in self.minimized_controls[account]: + # more or less a hack: + # On disconnect the minimized gc contact instances + # were set to offline. Reconnect them to show up in the roster. + self.roster.add_groupchat(jid, account)
def add_gc_bookmark(self, account, name, jid, autojoin, minimize, password, nick):
Modified: trunk/src/groupchat_control.py =================================================================== --- trunk/src/groupchat_control.py 2008-07-19 14:45:04 UTC (rev 9959) +++ trunk/src/groupchat_control.py 2008-07-19 17:36:21 UTC (rev 9960) @@ -1624,14 +1624,11 @@ control.unparent() ctrl.parent_win = None
- gajim.interface.minimized_controls[self.account][self.contact.jid] = \ - ctrl - - del win._controls[self.account][self.contact.jid] - gajim.interface.roster.add_groupchat(self.contact.jid, self.account, status = self.subject)
+ del win._controls[self.account][self.contact.jid] + def shutdown(self, status='offline'): # destroy banner tooltip - bug #pygtk for that! self.subject_tooltip.destroy()
Modified: trunk/src/roster_window.py =================================================================== --- trunk/src/roster_window.py 2008-07-19 14:45:04 UTC (rev 9959) +++ trunk/src/roster_window.py 2008-07-19 17:36:21 UTC (rev 9960) @@ -705,7 +705,6 @@ else: self._remove_entity(contact, account)
- if backend: # Remove contact before redrawing, otherwise the old # numbers will still be show @@ -730,20 +729,28 @@ Return the added contact instance. ''' contact = gajim.contacts.get_contact_with_highest_priority(account, jid) + # Do not show gc if we are disconnected and minimize it + if gajim.account_is_connected(account): + show = 'online' + else: + show = 'offline' + status = '' + if contact is None: - # Do not show gc if we are disconnected and minimize it - if gajim.account_is_connected(account): - show = 'online' - else: - show = 'offline' - status = '' + # New groupchat contact = gajim.contacts.create_contact(jid=jid, name=jid, groups=[_('Groupchats')], show=show, status=status, sub='none') gajim.contacts.add_contact(account, contact) + gc_control = gajim.interface.msg_win_mgr.get_gc_control(jid, account) + if gc_control: + # there is a window that we can minimize + gajim.interface.minimized_controls[account][jid] = gc_control self.add_contact(jid, account) else: - contact.show = 'online' + contact.show = show + contact.status = status self.draw_completely_and_show_if_needed(jid, account) + return contact
@@ -751,6 +758,8 @@ '''Remove groupchat from roster and redraw account and group.''' contact = gajim.contacts.get_contact_with_highest_priority(account, jid) if contact.is_groupchat(): + if jid in gajim.interface.minimized_controls[account]: + gajim.interface.minimized_controls[account][jid] self.remove_contact(jid, account, force=True, backend=True) return True else: @@ -961,7 +970,8 @@ name = gobject.markup_escape_text(contact.get_shown_name())
# gets number of unread gc marked messages - if jid in gajim.interface.minimized_controls[account]: + if jid in gajim.interface.minimized_controls[account] and \ + gajim.interface.minimized_controls[account][jid]: nb_unread = len(gajim.events.get_events(account, jid, ['printed_marked_gc_msg'])) nb_unread += \ @@ -1581,18 +1591,6 @@ return True return False
- def auto_join_bookmarks(self, account): - '''autojoin bookmarks that have 'auto join' on for this account''' - for bm in gajim.connections[account].bookmarks: - if bm['autojoin'] in ('1', 'true'): - jid = bm['jid'] - if not gajim.gc_connected[account].has_key(jid) or\ - not gajim.gc_connected[account][jid]: - # we are not already connected - minimize = bm['minimize'] in ('1', 'true') - gajim.interface.join_gc_room(account, jid, bm['nick'], - bm['password'], minimize = minimize) - def on_event_removed(self, event_list): '''Remove contacts on last events removed.
@@ -2651,9 +2649,9 @@
def on_disconnect(self, widget, jid, account): '''When disconnect menuitem is activated: disconect from room''' - ctrl = gajim.interface.minimized_controls[account][jid] - del gajim.interface.minimized_controls[account][jid] - ctrl.shutdown() + if jid in gajim.interface.minimized_controls[account]: + ctrl = gajim.interface.minimized_controls[account][jid] + ctrl.shutdown() self.remove_groupchat(jid, account)
def on_send_single_message_menuitem_activate(self, widget, account, @@ -2722,6 +2720,8 @@
def on_groupchat_maximized(self, widget, jid, account): '''When a groupchat is maximised''' + if not jid in gajim.interface.minimized_controls[account]: + return ctrl = gajim.interface.minimized_controls[account][jid] mw = gajim.interface.msg_win_mgr.get_window(ctrl.contact.jid, ctrl.account) @@ -2731,8 +2731,7 @@ ctrl.parent_win = mw mw.new_tab(ctrl) mw.set_active_tab(ctrl) - del gajim.interface.minimized_controls[account][jid] - + self.remove_groupchat(jid, account)
def on_edit_account(self, widget, account): @@ -3240,15 +3239,21 @@ type_ = model[path][C_TYPE] jid = model[path][C_JID].decode('utf-8') resource = None - contact = None + contact = gajim.contacts.get_first_contact_from_jid(account, jid) titer = model.get_iter(path) if type_ in ('group', 'account'): if self.tree.row_expanded(path): self.tree.collapse_row(path) else: self.tree.expand_row(path, False) - elif jid in gajim.interface.minimized_controls[account]: - self.on_groupchat_maximized(None, jid, account) + elif contact.is_groupchat(): + first_ev = gajim.events.get_first_event(account, jid) + if first_ev and self.open_event(account, jid, first_ev): + # We are invited to a GC + # open event cares about connecting to it + self.remove_groupchat(jid, account) + else: + self.on_groupchat_maximized(None, jid, account) else: first_ev = gajim.events.get_first_event(account, jid) if not first_ev: