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
This commit is contained in:
Stephan Erb 2008-07-19 17:36:21 +00:00
parent f5d92c296b
commit d83f9da555
5 changed files with 90 additions and 321 deletions

View File

@ -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>

View File

@ -2214,8 +2214,8 @@ class SingleMessageWindow:
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,50 +2920,34 @@ class InvitationReceivedDialog:
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)
label_text = '<big><b>%s</b></big>' % pritext
contact_text = contact and contact.name or contact_jid
sectext = sectext.replace('$Contact', contact_text)
if comment: # only if not None and not ''
comment = gobject.markup_escape_text(comment)
sectext = _('Comment: %s') % comment
label_text += '\n\n%s' % sectext
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
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
class ProgressDialog:
def __init__(self, title_text, during_text, messages_queue):

View File

@ -2128,11 +2128,7 @@ class Interface:
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 @@ class Interface:
################################################################################
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 \
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
self.roster.add_groupchat(room_jid, account)
return
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):
self.new_room(room_jid, nick, account, is_continued=is_continued)
if not minimized_control_exists:
not self.msg_win_mgr.has_window(room_jid, account):
# 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)
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)
# 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 @@ class Interface:
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):

View File

@ -1624,14 +1624,11 @@ class GroupchatControl(ChatControlBase):
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()

View File

@ -705,7 +705,6 @@ class RosterWindow:
else:
self._remove_entity(contact, account)
if backend:
# Remove contact before redrawing, otherwise the old
# numbers will still be show
@ -730,20 +729,28 @@ class RosterWindow:
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 @@ class RosterWindow:
'''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 @@ class RosterWindow:
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 @@ class RosterWindow:
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 @@ class RosterWindow:
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 @@ class RosterWindow:
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 @@ class RosterWindow:
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 @@ class RosterWindow:
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: