[roidelapluie, elghinn, msieurhappy, xbright and me] chat to muc convertion. see #2095 and #1408. TODO: DND

This commit is contained in:
Yann Leboulanger 2007-08-21 23:13:03 +00:00
parent 86177e8536
commit 78f2c8c021
10 changed files with 594 additions and 114 deletions

View file

@ -1,90 +1,76 @@
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--*- mode: xml -*-->
<glade-interface>
<widget class="GtkMenu" id="chat_control_popup_menu">
<child>
<widget class="GtkImageMenuItem" id="history_menuitem">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Click to see past conversations with this contact</property>
<property name="label" translatable="yes">_History</property>
<property name="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="image1370">
<property name="visible">True</property>
<property name="stock">gtk-justify-fill</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="information_menuitem">
<property name="visible">True</property>
<property name="label">gtk-info</property>
<property name="use_stock">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="send_file_menuitem">
<property name="visible">True</property>
<property name="label" translatable="yes">Send _File</property>
<property name="use_underline">True</property>
<signal name="activate" handler="_on_send_file_menuitem_activate" last_modification_time="Tue, 03 Jan 2006 04:26:55 GMT"/>
<child internal-child="image">
<widget class="GtkImage" id="image1371">
<property name="visible">True</property>
<property name="stock">gtk-file</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkCheckMenuItem" id="toggle_gpg_menuitem">
<property name="visible">True</property>
<property name="label" translatable="yes">Toggle Open_PGP Encryption</property>
<property name="use_underline">True</property>
<property name="active">False</property>
<signal name="activate" handler="_on_toggle_gpg_menuitem_activate" last_modification_time="Tue, 03 Jan 2006 04:26:46 GMT"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="add_to_roster_menuitem">
<property name="visible">True</property>
<property name="label" translatable="yes">_Add to Roster</property>
<property name="use_underline">True</property>
<signal name="activate" handler="_on_add_to_roster_menuitem_activate" last_modification_time="Tue, 03 Jan 2006 04:26:37 GMT"/>
<child internal-child="image">
<widget class="GtkImage" id="image1372">
<property name="visible">True</property>
<property name="stock">gtk-add</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
</widget>
<widget class="GtkMenu" id="chat_control_popup_menu">
<child>
<widget class="GtkImageMenuItem" id="history_menuitem">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Click to see past conversations with this contact</property>
<property name="label" translatable="yes">_History</property>
<property name="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="image1370">
<property name="visible">True</property>
<property name="stock">gtk-justify-fill</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="information_menuitem">
<property name="visible">True</property>
<property name="label">gtk-info</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="send_file_menuitem">
<property name="visible">True</property>
<property name="label" translatable="yes">Send _File</property>
<property name="use_underline">True</property>
<signal name="activate" handler="_on_send_file_menuitem_activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image1371">
<property name="visible">True</property>
<property name="stock">gtk-missing-image</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkCheckMenuItem" id="toggle_gpg_menuitem">
<property name="visible">True</property>
<property name="label" translatable="yes">Toggle Open_PGP Encryption</property>
<property name="use_underline">True</property>
<signal name="activate" handler="_on_toggle_gpg_menuitem_activate"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="add_to_roster_menuitem">
<property name="visible">True</property>
<property name="label" translatable="yes">_Add to Roster</property>
<property name="use_underline">True</property>
<signal name="activate" handler="_on_add_to_roster_menuitem_activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image1372">
<property name="visible">True</property>
<property name="stock">gtk-add</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="convert_to_groupchat">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Invite _Friends</property>
<property name="use_underline">True</property>
</widget>
</child>
</widget>
</glade-interface>

View file

@ -0,0 +1,275 @@
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<widget class="GtkWindow" id="chat_to_muc_window">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="title" translatable="yes">Invite Friends !</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_NORMAL</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
<child>
<widget class="GtkVBox" id="general_vbox">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkLabel" id="server_select_label">
<property name="visible">True</property>
<property name="label" translatable="yes">You are going to begin a Multi-User Chat.
First please select a MUC server.</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_CENTER</property>
<property name="wrap">True</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">4</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkComboBoxEntry" id="server_list_comboboxentry">
<property name="visible">True</property>
<property name="add_tearoffs">False</property>
<property name="has_frame">True</property>
<property name="focus_on_click">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHSeparator" id="server_and_guests_hseparator">
<property name="visible">True</property>
</widget>
<packing>
<property name="padding">4</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="info_label">
<property name="visible">True</property>
<property name="label" translatable="yes">Select the friends you want to invite.</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_CENTER</property>
<property name="wrap">True</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">4</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="guests_scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTreeView" id="guests_treeview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_visible">False</property>
<property name="rules_hint">False</property>
<property name="reorderable">False</property>
<property name="enable_search">True</property>
<property name="fixed_height_mode">False</property>
<property name="hover_selection">False</property>
<property name="hover_expand">False</property>
<signal name="drag_data_received" handler="on_guests_treeview_drag_data_received" last_modification_time="Mon, 16 Jul 2007 13:49:16 GMT"/>
<signal name="drag_end" handler="on_guests_treeview_drag_end" last_modification_time="Mon, 16 Jul 2007 14:02:56 GMT"/>
<signal name="drag_data_get" handler="on_guests_treeview_drag_data_get" last_modification_time="Mon, 16 Jul 2007 14:04:27 GMT"/>
</widget>
</child>
</widget>
<packing>
<property name="padding">4</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="invite_cancel_hbox">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkLabel" id="empty_label">
<property name="visible">True</property>
<property name="label" translatable="yes"></property>
<property name="use_underline">False</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">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="cancel_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_cancel_button_clicked" last_modification_time="Sun, 15 Jul 2007 08:42:47 GMT"/>
</widget>
<packing>
<property name="padding">3</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="invite_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_invite_button_clicked" last_modification_time="Sun, 15 Jul 2007 08:42:41 GMT"/>
<child>
<widget class="GtkAlignment" id="alignment1">
<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="hbox2">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">2</property>
<child>
<widget class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="stock">gtk-jump-to</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="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">In_vite</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>
<packing>
<property name="padding">3</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">4</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View file

@ -1536,6 +1536,7 @@ class ChatControl(ChatControlBase):
add_to_roster_menuitem = xml.get_widget('add_to_roster_menuitem')
send_file_menuitem = xml.get_widget('send_file_menuitem')
information_menuitem = xml.get_widget('information_menuitem')
convert_to_gc_menuitem = xml.get_widget('convert_to_groupchat')
contact = self.parent_win.get_active_contact()
jid = contact.jid
@ -1550,7 +1551,7 @@ class ChatControl(ChatControlBase):
is_sensitive = gpg_btn.get_property('sensitive')
toggle_gpg_menuitem.set_active(isactive)
toggle_gpg_menuitem.set_property('sensitive', is_sensitive)
# If we don't have resource, we can't do file transfer
# in transports, contact holds our info we need to disable it too
if self.TYPE_ID == message_control.TYPE_PM and self.gc_contact.jid and \
@ -1560,7 +1561,14 @@ class ChatControl(ChatControlBase):
send_file_menuitem.set_sensitive(True)
else:
send_file_menuitem.set_sensitive(False)
# compact_view_menuitem
compact_view_menuitem.set_active(self.hide_chat_buttons_current)
# check if it's possible to convert to groupchat
if gajim.get_transport_name_from_jid(jid):
convert_to_gc_menuitem.set_sensitive(False)
# add_to_roster_menuitem
if _('Not in Roster') in contact.groups:
add_to_roster_menuitem.show()
@ -1568,8 +1576,7 @@ class ChatControl(ChatControlBase):
else:
add_to_roster_menuitem.hide()
add_to_roster_menuitem.set_no_show_all(True)
# connect signals
id = history_menuitem.connect('activate',
self._on_history_menuitem_activate)
@ -1586,6 +1593,9 @@ class ChatControl(ChatControlBase):
id = information_menuitem.connect('activate',
self._on_contact_information_menuitem_activate)
self.handlers[id] = information_menuitem
id = convert_to_gc_menuitem.connect('activate',
self._on_convert_to_gc_menuitem_activate)
self.handlers[id] = convert_to_gc_menuitem
menu.connect('selection-done', lambda w:w.destroy())
return menu
@ -1999,6 +2009,11 @@ class ChatControl(ChatControlBase):
# this is reverse logic, as we are on 'activate' (before change happens)
tb = self.xml.get_widget('gpg_togglebutton')
tb.set_active(not tb.get_active())
def _on_convert_to_gc_menuitem_activate(self, widget):
'''user want to invite some friends to chat'''
dialogs.TransformChatToMUC(self.account, [self.contact.jid])
def got_connected(self):
ChatControlBase.got_connected(self)

View file

@ -1201,6 +1201,21 @@ class Connection(ConnectionHandlers):
p = self.add_sha(p, ptype != 'unavailable')
self.connection.send(p)
def check_unique_room_id_support(self, server, instance):
if not self.connection:
return
iq = common.xmpp.Iq(typ = 'get', to = server)
iq.setAttr('id', 'unique1')
iq.addChild('unique', namespace=common.xmpp.NS_MUC_UNIQUE)
def _on_response(resp):
if not common.xmpp.isResultNode(resp):
self.dispatch('UNIQUE_ROOM_ID_UNSUPPORTED', (server, instance))
return
print resp.getTag('unique').getData()
self.dispatch('UNIQUE_ROOM_ID_SUPPORTED', (server, instance,
resp.getTag('unique').getData()))
self.connection.SendAndCallForResponse(iq, _on_response)
def join_gc(self, nick, room_jid, password):
# FIXME: This room JID needs to be normalized; see #1364
if not self.connection:
@ -1387,11 +1402,13 @@ class Connection(ConnectionHandlers):
else:
_on_unregister_account_connect(self.connection)
def send_invite(self, room, to, reason=''):
def send_invite(self, room, to, reason='', continue_tag=False):
'''sends invitation'''
message=common.xmpp.Message(to = room)
c = message.addChild(name = 'x', namespace = common.xmpp.NS_MUC_USER)
c = c.addChild(name = 'invite', attrs={'to' : to})
if continue_tag:
c.addChild(name = 'continue')
if reason != '':
c.setTagData('reason', reason)
self.connection.send(message)

View file

@ -1483,7 +1483,11 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
for xtag in xtags:
if xtag.getNamespace() == common.xmpp.NS_CONFERENCE and not invite:
room_jid = xtag.getAttr('jid')
self.dispatch('GC_INVITATION', (room_jid, frm, '', None))
is_continued = False
if xtag.getTag('continue'):
is_continued = True
self.dispatch('GC_INVITATION', (room_jid, frm, '', None,
is_continued))
return
# chatstates - look for chatstate tags in a message if not delayed
if not delayed:
@ -1574,7 +1578,11 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
reason = item.getTagData('reason')
item = invite.getTag('password')
password = invite.getTagData('password')
self.dispatch('GC_INVITATION',(frm, jid_from, reason, password))
is_continued = False
if invite.getTag('invite').getTag('continue'):
is_continued = True
self.dispatch('GC_INVITATION',(frm, jid_from, reason, password,
is_continued))
return
if self.name not in no_log_for and jid not in no_log_for and msgtxt:
try:

View file

@ -62,6 +62,7 @@ NS_MUC ='http://jabber.org/protocol/muc'
NS_MUC_USER =NS_MUC+'#user'
NS_MUC_ADMIN =NS_MUC+'#admin'
NS_MUC_OWNER =NS_MUC+'#owner'
NS_MUC_UNIQUE =NS_MUC+'#unique'
NS_NICK ='http://jabber.org/protocol/nick' # XEP-0172
NS_OFFLINE ='http://www.jabber.org/jeps/jep-0030.html' # XEP-0013
NS_PHYSLOC ='http://jabber.org/protocol/physloc' # XEP-0112

View file

@ -29,6 +29,8 @@ import vcard
import conversation_textview
import message_control
from random import randrange
try:
import gtkspell
HAS_GTK_SPELL = True
@ -401,7 +403,7 @@ class ChangeStatusMessageDialog:
def on_change_status_message_dialog_key_press_event(self, widget, event):
self.countdown_enabled = False
if event.keyval == gtk.keysyms.Return or \
event.keyval == gtk.keysyms.KP_Enter: # catch CTRL+ENTER
event.keyval == gtk.keysyms.KP_Enter: # catch CTRL+ENTER
if (event.state & gtk.gdk.CONTROL_MASK):
self.window.response(gtk.RESPONSE_OK)
# Stop the event
@ -1532,7 +1534,7 @@ class NewChatDialog(InputDialog):
keys.sort()
for jid in keys:
contact = self.completion_dict[jid]
img = gajim.interface.roster.jabber_state_images['16'][contact.show]
img = gajim.interface.roster.jabber_state_images['16'][contact.show]
liststore.append((img.get_pixbuf(), jid))
self.ok_handler = self.new_chat_response
@ -2577,17 +2579,21 @@ class PrivacyListsWindow:
class InvitationReceivedDialog:
def __init__(self, account, room_jid, contact_jid, password = None,
comment = None):
comment = None, is_continued = False):
self.room_jid = room_jid
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')
#Don't translate $Contact
pritext = _('$Contact has invited you to group chat %(room_jid)s')\
% {'room_jid': room_jid}
if is_continued:
pritext = _('$Contact has invited you to join a discussion')
else:
pritext = _('$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)
@ -2615,8 +2621,11 @@ class InvitationReceivedDialog:
def on_accept_button_clicked(self, widget):
self.dialog.destroy()
try:
JoinGroupchatWindow(self.account, self.room_jid,
password=self.password)
if self.is_continued:
gajim.interface.roster.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
@ -3283,3 +3292,135 @@ class AdvancedNotificationsWindow:
def on_close_window(self, widget):
self.window.destroy()
class TransformChatToMUC:
def __init__(self, account, jids):
'''This window is used to trasform a one-to-one chat to a MUC.
We do 2 things: first select the server and then make a guests list.'''
self.account = account
self.auto_jids = jids
self.xml = gtkgui_helpers.get_glade('chat_to_muc_window.glade')
self.window = self.xml.get_widget('chat_to_muc_window')
self.window.connect('key_press_event', self._on_keypress_event)
for widget_to_add in ('invite_button', 'cancel_button',
'server_list_comboboxentry', 'guests_treeview',
'server_and_guests_hseparator', 'server_select_label'):
self.__dict__[widget_to_add] = self.xml.get_widget(widget_to_add)
self.window.connect('key_press_event', self._on_keypress_event)
# set a list of servers which support it
self.servers_support = {}
# set comboboxentry
renderer_servers = gtk.CellRendererText()
server_list = []
self.servers = gtk.ListStore(str)
self.server_list_comboboxentry.set_model(self.servers)
self.server_list_comboboxentry.set_text_column(0)
# get the muc server of our server
if 'jabber' in gajim.connections[account].muc_jid:
server_list.append(gajim.connections[account].muc_jid['jabber'])
# add servers or recently joined groupchats
recently_groupchat = gajim.config.get('recently_groupchat').split()
for g in recently_groupchat:
server = gajim.get_server_from_jid(g)
if server not in server_list:
server_list.append(gajim.get_server_from_jid(g))
# add a default server
if not server_list:
server_list.append('conference.jabber.org')
for s in server_list:
self.servers.append([s])
self.server_list_comboboxentry.set_active(0)
# set treeview
# name, jid
self.store = gtk.ListStore(str, str)
self.guests_treeview.set_model(self.store)
renderer1 = gtk.CellRendererText()
column = gtk.TreeViewColumn('Name', renderer1, text=0)
self.guests_treeview.append_column(column)
self.guests_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
# set jabber id and pseudos
for jid in gajim.contacts.get_jid_list(self.account):
contact = \
gajim.contacts.get_contact_with_highest_priority(self.account, jid)
if contact.jid not in self.auto_jids:
if contact.show not in ('offline', 'error'):
name = contact.name
if name == '':
name = jid.split('@')[0]
self.store.append([name, jid])
# show all but...
self.window.show_all()
# ...hide this
self.server_selection_visible = True
self.toggle_server_selection_visible()
self.xml.signal_autoconnect(self)
def toggle_server_selection_visible(self):
if self.server_selection_visible:
self.server_selection_visible = False
self.server_and_guests_hseparator.hide()
self.server_list_comboboxentry.hide()
self.server_select_label.hide()
else:
self.server_selection_visible = True
self.server_and_guests_hseparator.show()
self.server_list_comboboxentry.show()
self.server_select_label.show()
def _on_keypress_event(self, widget, event):
if (event.state & gtk.gdk.MOD1_MASK) and (event.keyval == gtk.keysyms.c \
or event.keyval == gtk.keysyms.C):
self.toggle_server_selection_visible()
return True
def on_invite_button_clicked(self, widget):
server = self.server_list_comboboxentry.get_active_text()
if server == '':
return
room_id = gajim.nicks[self.account] + str(randrange(9999999))
# if self.servers_support.has_key(server):
# self.unique_room_id_supported(server, self.servers_support[server])
# return
# gajim.connections[self.account].check_unique_room_id_support(server, self)
# def unique_room_id_supported(self, server, room_id):
# if not self.servers_support.has_key(server):
# self.servers_support[server] = room_id
guest_list = []
guests = self.guests_treeview.get_selection().get_selected_rows()
for guest in guests[1]:
iter = self.store.get_iter(guest)
guest_list.append(self.store[iter][1].decode('utf-8'))
for guest in self.auto_jids:
guest_list.append(guest)
room_jid = room_id + '@' + server
gajim.automatic_rooms[self.account][room_jid] = {}
gajim.automatic_rooms[self.account][room_jid]['invities'] = guest_list
gajim.automatic_rooms[self.account][room_jid]['continue_tag'] = True
gajim.interface.roster.join_gc_room(self.account, room_jid,
gajim.nicks[self.account], None, is_continued=True)
self.window.destroy()
def on_cancel_button_clicked(self, widget):
self.window.destroy()
def unique_room_id_error(self, server):
self.unique_room_id_supported(server,
gajim.nicks[self.account] + str(randrange(9999999)))

View file

@ -1210,9 +1210,14 @@ class Interface:
# use default configuration
gajim.connections[account].send_gc_config(room_jid, array[1])
# invite contacts
# check if it is necessary to add <continue />
continue_tag = False
if gajim.automatic_rooms[account][room_jid].has_key('continue_tag'):
continue_tag = True
if gajim.automatic_rooms[account][room_jid].has_key('invities'):
for jid in gajim.automatic_rooms[account][room_jid]['invities']:
gajim.connections[account].send_invite(room_jid, jid)
gajim.connections[account].send_invite(room_jid, jid,
continue_tag=continue_tag)
del gajim.automatic_rooms[account][room_jid]
elif not self.instances[account]['gc_config'].has_key(room_jid):
self.instances[account]['gc_config'][room_jid] = \
@ -1289,16 +1294,16 @@ class Interface:
dlg.input_entry.set_visibility(False)
def handle_event_gc_invitation(self, account, array):
#('GC_INVITATION', (room_jid, jid_from, reason, password))
#('GC_INVITATION', (room_jid, jid_from, reason, password, is_continued))
jid = gajim.get_jid_without_resource(array[1])
room_jid = array[0]
if helpers.allow_popup_window(account) or not self.systray_enabled:
dialogs.InvitationReceivedDialog(account, room_jid, jid, array[3],
array[2])
array[2], is_continued=array[4])
return
self.add_event(account, jid, 'gc-invitation', (room_jid, array[2],
array[3]))
array[3], array[4]))
if helpers.allow_showing_notification(account):
path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
@ -1867,6 +1872,17 @@ class Interface:
_('You are already connected to this account with the same resource. Please type a new one'), input_str = gajim.connections[account].server_resource,
is_modal = False, ok_handler = on_ok)
def handle_event_unique_room_id_supported(self, account, data):
'''Receive confirmation that unique_room_id are supported'''
# ('UNIQUE_ROOM_ID_SUPPORTED', server, instance, room_id)
instance = data[1]
instance.unique_room_id_supported(data[0], data[2])
def handle_event_unique_room_id_unsupported(self, account, data):
# ('UNIQUE_ROOM_ID_UNSUPPORTED', server, instance)
instance = data[1]
instance.unique_room_id_error(data[0])
def read_sleepy(self):
'''Check idle status and change that status if needed'''
if not self.sleeper.poll():
@ -2195,6 +2211,9 @@ class Interface:
'SEARCH_FORM': self.handle_event_search_form,
'SEARCH_RESULT': self.handle_event_search_result,
'RESOURCE_CONFLICT': self.handle_event_resource_conflict,
'UNIQUE_ROOM_ID_UNSUPPORTED': \
self.handle_event_unique_room_id_unsupported,
'UNIQUE_ROOM_ID_SUPPORTED': self.handle_event_unique_room_id_supported,
}
gajim.handlers = self.handlers
@ -2287,7 +2306,7 @@ class Interface:
event = gajim.events.get_first_event(account, jid, type_)
data = event.parameters
dialogs.InvitationReceivedDialog(account, data[0], jid, data[2],
data[1])
data[1], data[3])
gajim.events.remove_events(account, jid, event)
self.roster.draw_contact(jid, account)
if w:

View file

@ -153,10 +153,12 @@ class GroupchatControl(ChatControlBase):
'help', 'invite', 'join', 'kick', 'leave', 'me', 'msg', 'nick',
'part', 'names', 'say', 'topic']
def __init__(self, parent_win, contact, acct):
def __init__(self, parent_win, contact, acct, is_continued=False):
ChatControlBase.__init__(self, self.TYPE_ID, parent_win,
'muc_child_vbox', contact, acct);
self.is_continued=is_continued
widget = self.xml.get_widget('muc_window_actions_button')
id = widget.connect('clicked', self.on_actions_button_clicked)
self.handlers[id] = widget
@ -478,7 +480,19 @@ class GroupchatControl(ChatControlBase):
'''
self.name_label.set_ellipsize(pango.ELLIPSIZE_END)
font_attrs, font_attrs_small = self.get_font_attrs()
text = '<span %s>%s</span>' % (font_attrs, self.room_jid)
if self.is_continued:
nicks = []
for nick in gajim.contacts.get_nick_list(self.account, self.room_jid):
if nick != self.nick:
nicks.append(nick)
if nicks != []:
title = ', '
title = 'Conversation with ' + title.join(nicks)
else:
title = 'Continued conversation'
text = '<span %s>%s</span>' % (font_attrs, title)
else:
text = '<span %s>%s</span>' % (font_attrs, self.room_jid)
if self.subject:
subject = helpers.reduce_chars_newlines(self.subject, max_lines = 2)
subject = gobject.markup_escape_text(subject)
@ -1135,6 +1149,8 @@ class GroupchatControl(ChatControlBase):
if nick == self.nick: # we became online
self.got_connected()
self.list_treeview.expand_row((model.get_path(role_iter)), False)
if self.is_continued:
self.draw_banner_text()
return iter
def get_role_iter(self, role):

View file

@ -751,7 +751,8 @@ class RosterWindow:
for iter in iters:
model[iter][C_SECPIXBUF] = scaled_pixbuf
def join_gc_room(self, account, room_jid, nick, password, minimize = False):
def join_gc_room(self, account, room_jid, nick, password, minimize=False,
is_continued=False):
'''joins the room immediatelly'''
if gajim.interface.msg_win_mgr.has_window(room_jid, account) and \
gajim.gc_connected[account][room_jid]:
@ -780,7 +781,7 @@ class RosterWindow:
return
if not minimized_control_exists and \
not gajim.interface.msg_win_mgr.has_window(room_jid, account):
self.new_room(room_jid, nick, account)
self.new_room(room_jid, nick, account, is_continued=is_continued)
if not minimized_control_exists:
gc_win = gajim.interface.msg_win_mgr.get_window(room_jid, account)
gc_win.set_active_tab(room_jid, account)
@ -3804,14 +3805,15 @@ class RosterWindow:
mc = mw.get_control(fjid, account)
mc.user_nick = gajim.nicks[account]
def new_room(self, room_jid, nick, account):
def new_room(self, room_jid, nick, account, is_continued=False):
# Get target window, create a control, and associate it with the window
contact = gajim.contacts.create_contact(jid = room_jid, name = nick)
mw = gajim.interface.msg_win_mgr.get_window(contact.jid, account)
if not mw:
mw = gajim.interface.msg_win_mgr.create_window(contact, account,
GroupchatControl.TYPE_ID)
gc_control = GroupchatControl(mw, contact, account)
GroupchatControl.TYPE_ID)
gc_control = GroupchatControl(mw, contact, account,
is_continued=is_continued)
mw.new_tab(gc_control)
def on_message(self, jid, msg, tim, account, encrypted = False,