[roidelapluie, elghinn, msieurhappy, xbright and me] chat to muc convertion. see #2095 and #1408. TODO: DND
This commit is contained in:
parent
86177e8536
commit
78f2c8c021
10 changed files with 594 additions and 114 deletions
|
@ -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>
|
||||
|
|
275
data/glade/chat_to_muc_window.glade
Normal file
275
data/glade/chat_to_muc_window.glade
Normal 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>
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
155
src/dialogs.py
155
src/dialogs.py
|
@ -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)))
|
||||
|
|
29
src/gajim.py
29
src/gajim.py
|
@ -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:
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue