[Dave Cridland] add XEP-0258 support. Great thanks for that! Fixes #5772

This commit is contained in:
Yann Leboulanger 2010-06-07 19:11:44 +02:00
parent 28e3c36944
commit d58841cb2b
12 changed files with 191 additions and 63 deletions

View File

@ -5,7 +5,6 @@
<object class="GtkVBox" id="chat_control_vbox">
<property name="can_focus">True</property>
<property name="border_width">3</property>
<property name="orientation">vertical</property>
<property name="spacing">1</property>
<child>
<object class="GtkHBox" id="hbox3">
@ -13,7 +12,6 @@
<child>
<object class="GtkVBox" id="vbox2">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkAlignment" id="alignment">
<property name="visible">True</property>
@ -43,7 +41,6 @@
<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="border_width">5</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="banner_name_label">
<property name="visible">True</property>
@ -195,7 +192,6 @@
<child>
<object class="GtkVBox" id="vbox106">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkScrolledWindow" id="conversation_scrolledwindow">
<property name="height_request">60</property>
@ -314,7 +310,6 @@
<object class="GtkVSeparator" id="vseparator1">
<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="orientation">vertical</property>
</object>
<packing>
<property name="expand">False</property>
@ -470,7 +465,6 @@
<object class="GtkVSeparator" id="vseparator3">
<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="orientation">vertical</property>
</object>
<packing>
<property name="expand">False</property>
@ -499,6 +493,14 @@
<property name="position">11</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="label_selector">
<property name="visible">True</property>
</object>
<packing>
<property name="position">12</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
@ -508,7 +510,7 @@
</child>
</object>
<packing>
<property name="position">12</property>
<property name="position">13</property>
</packing>
</child>
<child>
@ -555,7 +557,7 @@
</object>
<packing>
<property name="expand">False</property>
<property name="position">13</property>
<property name="position">14</property>
</packing>
</child>
</object>
@ -572,7 +574,6 @@
<child>
<object class="GtkVBox" id="audio_vbox">
<property name="no_show_all">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label3">

View File

@ -5,7 +5,6 @@
<object class="GtkVBox" id="groupchat_control_vbox">
<property name="can_focus">True</property>
<property name="border_width">3</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkAlignment" id="alignment">
<property name="visible">True</property>
@ -35,7 +34,6 @@
<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="border_width">5</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="banner_name_label">
<property name="visible">True</property>
@ -133,7 +131,6 @@
<object class="GtkVSeparator" id="vseparator2">
<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="orientation">vertical</property>
</object>
<packing>
<property name="expand">False</property>
@ -233,7 +230,6 @@
<object class="GtkVSeparator" id="vseparator4">
<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="orientation">vertical</property>
</object>
<packing>
<property name="expand">False</property>
@ -269,6 +265,14 @@
<property name="position">8</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="label_selector">
<property name="visible">True</property>
</object>
<packing>
<property name="position">9</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment2">
<property name="visible">True</property>
@ -278,7 +282,7 @@
</child>
</object>
<packing>
<property name="position">9</property>
<property name="position">10</property>
</packing>
</child>
<child>
@ -326,7 +330,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">10</property>
<property name="position">11</property>
</packing>
</child>
</object>
@ -346,12 +350,10 @@
<object class="GtkVBox" id="vbox108">
<property name="width_request">0</property>
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkVBox" id="vbox109">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkScrolledWindow" id="conversation_scrolledwindow">

View File

@ -232,6 +232,29 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
def status_url_clicked(self, widget, url):
helpers.launch_browser_mailer('url', url)
def setup_seclabel(self, combo):
self.seclabel_combo = combo
self.seclabel_combo.hide()
self.seclabel_combo.set_no_show_all(True)
lb = gtk.ListStore(str)
self.seclabel_combo.set_model(lb)
cell = gtk.CellRendererText()
cell.set_property('xpad', 5) # padding for status text
self.seclabel_combo.pack_start(cell, True)
# text to show is in in first column of liststore
self.seclabel_combo.add_attribute(cell, 'text', 0)
if gajim.connections[self.account].seclabel_supported:
gajim.connections[self.account].seclabel_catalogue(self.contact.jid, self.on_seclabels_ready)
def on_seclabels_ready(self):
lb = self.seclabel_combo.get_model()
lb.clear()
for label in gajim.connections[self.account].seclabel_catalogues[self.contact.jid][2]:
lb.append([label])
self.seclabel_combo.set_active(0)
self.seclabel_combo.set_no_show_all(False)
self.seclabel_combo.show_all()
def __init__(self, type_id, parent_win, widget_name, contact, acct,
resource=None):
# Undo needs this variable to know if space has been pressed.
@ -721,6 +744,16 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
self.drag_entered_conv = True
self.conv_textview.tv.set_editable(True)
def get_seclabel(self):
label = None
if self.seclabel_combo is not None:
idx = self.seclabel_combo.get_active()
if idx != -1:
cat = gajim.connections[self.account].seclabel_catalogues[self.contact.jid]
lname = cat[2][idx]
label = cat[1][lname]
return label
def send_message(self, message, keyID='', type_='chat', chatstate=None,
msg_id=None, composing_xep=None, resource=None, xhtml=None,
callback=None, callback_args=[], process_commands=True):
@ -733,9 +766,11 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
if process_commands and self.process_as_command(message):
return
label = self.get_seclabel()
MessageControl.send_message(self, message, keyID, type_=type_,
chatstate=chatstate, msg_id=msg_id, composing_xep=composing_xep,
resource=resource, user_nick=self.user_nick, xhtml=xhtml,
label=label,
callback=callback, callback_args=callback_args)
# Record message history
@ -769,7 +804,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
other_tags_for_name=[], other_tags_for_time=[],
other_tags_for_text=[], count_as_new=True, subject=None,
old_kind=None, xhtml=None, simple=False, xep0184_id=None,
graphics=True):
graphics=True, displaymarking=None):
"""
Print 'chat' type messages
"""
@ -781,7 +816,8 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
end = True
textview.print_conversation_line(text, jid, kind, name, tim,
other_tags_for_name, other_tags_for_time, other_tags_for_text,
subject, old_kind, xhtml, simple=simple, graphics=graphics)
subject, old_kind, xhtml, simple=simple, graphics=graphics,
displaymarking=displaymarking)
if xep0184_id is not None:
textview.show_xep0184_warning(xep0184_id)
@ -1429,6 +1465,7 @@ class ChatControl(ChatControlBase):
session = gajim.connections[self.account].find_controlless_session(
self.contact.jid, resource)
self.setup_seclabel(self.xml.get_object('label_selector'))
if session:
session.control = self
self.session = session
@ -2048,20 +2085,23 @@ class ChatControl(ChatControlBase):
gobject.source_remove(self.possible_inactive_timeout_id)
self._schedule_activity_timers()
def _on_sent(id_, contact, message, encrypted, xhtml):
def _on_sent(id_, contact, message, encrypted, xhtml, label):
if contact.supports(NS_RECEIPTS) and gajim.config.get_per('accounts',
self.account, 'request_receipt'):
xep0184_id = id_
else:
xep0184_id = None
if label:
displaymarking = label.getTag('displaymarking')
else:
displaymarking = None
self.print_conversation(message, self.contact.jid, encrypted=encrypted,
xep0184_id=xep0184_id, xhtml=xhtml)
xep0184_id=xep0184_id, xhtml=xhtml, displaymarking=displaymarking)
ChatControlBase.send_message(self, message, keyID, type_='chat',
chatstate=chatstate_to_send, composing_xep=composing_xep,
xhtml=xhtml, callback=_on_sent,
callback_args=[contact, message, encrypted, xhtml],
callback_args=[contact, message, encrypted, xhtml, self.get_seclabel()],
process_commands=process_commands)
def check_for_possible_paused_chatstate(self, arg):
@ -2150,7 +2190,8 @@ class ChatControl(ChatControlBase):
self.session.is_loggable(), self.session and self.session.verified_identity)
def print_conversation(self, text, frm='', tim=None, encrypted=False,
subject=None, xhtml=None, simple=False, xep0184_id=None):
subject=None, xhtml=None, simple=False, xep0184_id=None,
displaymarking=None):
"""
Print a line in the conversation
@ -2213,7 +2254,7 @@ class ChatControl(ChatControlBase):
xhtml = '<body xmlns="%s">%s</body>' % (NS_XHTML, xhtml)
ChatControlBase.print_conversation_line(self, text, kind, name, tim,
subject=subject, old_kind=self.old_msg_kind, xhtml=xhtml,
simple=simple, xep0184_id=xep0184_id)
simple=simple, xep0184_id=xep0184_id, displaymarking=displaymarking)
if text.startswith('/me ') or text.startswith('/me\n'):
self.old_msg_kind = None
else:
@ -2660,8 +2701,12 @@ class ChatControl(ChatControlBase):
kind = 'info'
else:
kind = 'print_queue'
dm = None
if len(data) > 10:
dm = data[10]
self.print_conversation(data[0], kind, tim = data[3],
encrypted = data[4], subject = data[1], xhtml = data[7])
encrypted = data[4], subject = data[1], xhtml = data[7],
displaymarking=dm)
if len(data) > 6 and isinstance(data[6], int):
message_ids.append(data[6])

View File

@ -135,6 +135,9 @@ class CommonConnection:
self.blocked_groups = []
self.blocked_all = False
self.seclabel_supported = False
self.seclabel_catalogues = {}
self.pep_supported = False
self.pep = {}
# Do we continue connection when we get roster (send presence,get vcard..)
@ -239,7 +242,7 @@ class CommonConnection:
def _prepare_message(self, jid, msg, keyID, type_='chat', subject='',
chatstate=None, msg_id=None, composing_xep=None, resource=None,
user_nick=None, xhtml=None, session=None, forward_from=None, form_node=None,
original_message=None, delayed=None, callback=None):
label=None, original_message=None, delayed=None, callback=None):
if not self.connection or self.connected < 2:
return 1
try:
@ -287,14 +290,14 @@ class CommonConnection:
else:
self._message_encrypted_cb(output, type_, msg, msgtxt,
original_message, fjid, resource, jid, xhtml,
subject, chatstate, composing_xep, forward_from,
subject, chatstate, composing_xep, label, forward_from,
delayed, session, form_node, user_nick, keyID,
callback)
self.dispatch('GPG_ALWAYS_TRUST', _on_always_trust)
else:
self._message_encrypted_cb(output, type_, msg, msgtxt,
original_message, fjid, resource, jid, xhtml, subject,
chatstate, composing_xep, forward_from, delayed, session,
chatstate, composing_xep, label, forward_from, delayed, session,
form_node, user_nick, keyID, callback)
gajim.thread_interface(encrypt_thread, [msg, keyID, False],
_on_encrypted, [])
@ -302,15 +305,15 @@ class CommonConnection:
self._message_encrypted_cb(('', error), type_, msg, msgtxt,
original_message, fjid, resource, jid, xhtml, subject, chatstate,
composing_xep, forward_from, delayed, session, form_node, user_nick,
composing_xep, label, forward_from, delayed, session, form_node, user_nick,
keyID, callback)
self._on_continue_message(type_, msg, msgtxt, original_message, fjid,
resource, jid, xhtml, subject, msgenc, keyID, chatstate, composing_xep,
forward_from, delayed, session, form_node, user_nick, callback)
label, forward_from, delayed, session, form_node, user_nick, callback)
def _message_encrypted_cb(self, output, type_, msg, msgtxt, original_message,
fjid, resource, jid, xhtml, subject, chatstate, composing_xep, forward_from,
fjid, resource, jid, xhtml, subject, chatstate, composing_xep, label, forward_from,
delayed, session, form_node, user_nick, keyID, callback):
msgenc, error = output
@ -323,7 +326,7 @@ class CommonConnection:
' (' + msgtxt + ')'
self._on_continue_message(type_, msg, msgtxt, original_message, fjid,
resource, jid, xhtml, subject, msgenc, keyID, chatstate,
composing_xep, forward_from, delayed, session, form_node, user_nick,
composing_xep, label, forward_from, delayed, session, form_node, user_nick,
callback)
return
# Encryption failed, do not send message
@ -332,6 +335,7 @@ class CommonConnection:
def _on_continue_message(self, type_, msg, msgtxt, original_message, fjid,
resource, jid, xhtml, subject, msgenc, keyID, chatstate, composing_xep,
label,
forward_from, delayed, session, form_node, user_nick, callback):
if type_ == 'chat':
msg_iq = common.xmpp.Message(to=fjid, body=msgtxt, typ=type_,
@ -348,6 +352,8 @@ class CommonConnection:
if form_node:
msg_iq.addChild(node=form_node)
if label:
msg_iq.addChild(node=label)
# XEP-0172: user_nickname
if user_nick:
@ -1605,7 +1611,7 @@ class Connection(CommonConnection, ConnectionHandlers):
def send_message(self, jid, msg, keyID, type_='chat', subject='',
chatstate=None, msg_id=None, composing_xep=None, resource=None,
user_nick=None, xhtml=None, session=None, forward_from=None, form_node=None,
user_nick=None, xhtml=None, label=None, session=None, forward_from=None, form_node=None,
original_message=None, delayed=None, callback=None, callback_args=[],
now=False):
@ -1622,7 +1628,8 @@ class Connection(CommonConnection, ConnectionHandlers):
self._prepare_message(jid, msg, keyID, type_=type_, subject=subject,
chatstate=chatstate, msg_id=msg_id, composing_xep=composing_xep,
resource=resource, user_nick=user_nick, xhtml=xhtml, session=session,
resource=resource, user_nick=user_nick, xhtml=xhtml, label=label,
session=session,
forward_from=forward_from, form_node=form_node,
original_message=original_message, delayed=delayed, callback=cb)
@ -1830,6 +1837,15 @@ class Connection(CommonConnection, ConnectionHandlers):
iq2.addChild(name='gajim', namespace='gajim:prefs')
self.connection.send(iq)
def seclabel_catalogue(self, to, callback):
if not gajim.account_is_connected(self.name):
return
self.seclabel_catalogue_request(to, callback)
iq = common.xmpp.Iq(typ='get')
iq2 = iq.addChild(name='catalog', namespace=common.xmpp.NS_SECLABEL_CATALOG)
iq2.setAttr('to', to)
self.connection.send(iq)
def _request_bookmarks_xml(self):
if not gajim.account_is_connected(self.name):
return
@ -2041,13 +2057,15 @@ class Connection(CommonConnection, ConnectionHandlers):
t.setTagData('password', password)
self.connection.send(p)
def send_gc_message(self, jid, msg, xhtml = None):
def send_gc_message(self, jid, msg, xhtml = None, label = None):
if not gajim.account_is_connected(self.name):
return
if not xhtml and gajim.config.get('rst_formatting_outgoing_messages'):
from common.rst_xhtml_generator import create_xhtml
xhtml = create_xhtml(msg)
msg_iq = common.xmpp.Message(jid, msg, typ = 'groupchat', xhtml = xhtml)
if label is not None:
msg_iq.addChild(node = label)
self.connection.send(msg_iq)
self.dispatch('MSGSENT', (jid, msg))

View File

@ -341,6 +341,8 @@ class ConnectionDisco:
if features.__contains__(common.xmpp.NS_GMAILNOTIFY):
gajim.gmail_domains.append(jid)
self.request_gmail_notifications()
if features.__contains__(common.xmpp.NS_SECLABEL):
self.seclabel_supported = True
for identity in identities:
if identity['category'] == 'pubsub' and identity.get('type') == \
'pep':
@ -1071,6 +1073,33 @@ ConnectionCaps, ConnectionHandlersBase, ConnectionJingle):
annotation = note.getData()
self.annotations[jid] = annotation
def _SecLabelCB(self, con, iq_obj):
"""
Security Label callback, used for catalogues.
"""
log.debug('SecLabelCB')
query = iq_obj.getTag('catalog')
to = query.getAttr('to')
items = query.getTags('securitylabel')
labels = {}
ll = []
for item in items:
label = item.getTag('displaymarking').getData()
labels[label] = item
ll.append(label)
if to not in self.seclabel_catalogues:
self.seclabel_catalogues[to] = [[], None, None]
self.seclabel_catalogues[to][1] = labels
self.seclabel_catalogues[to][2] = ll
for callback in self.seclabel_catalogues[to][0]:
callback()
self.seclabel_catalogues[to][0] = []
def seclabel_catalogue_request(self, to, callback):
if to not in self.seclabel_catalogues:
self.seclabel_catalogues[to] = [[], None, None]
self.seclabel_catalogues[to][0].append(callback)
def _parse_bookmarks(self, storage, storage_type):
"""
storage_type can be 'pubsub' or 'xml' to tell from where we got bookmarks
@ -1618,12 +1647,15 @@ ConnectionCaps, ConnectionHandlersBase, ConnectionJingle):
self.dispatch('GC_CONFIG_CHANGE', (jid, statusCode))
return
# Ignore message from room in which we are not
displaymarking = None
seclabel = msg.getTag('securitylabel')
if seclabel and seclabel.getNamespace() == common.xmpp.NS_SECLABEL:
displaymarking = seclabel.getTag('displaymarking') # Ignore message from room in which we are not
if jid not in self.last_history_time:
return
self.dispatch('GC_MSG', (frm, msgtxt, tim, has_timestamp, msg.getXHTML(),
statusCode))
statusCode, displaymarking))
tim_int = int(float(mktime(tim)))
if gajim.config.should_log(self.name, jid) and not \
@ -2302,6 +2334,8 @@ ConnectionCaps, ConnectionHandlersBase, ConnectionJingle):
common.xmpp.NS_MUC_ADMIN)
con.RegisterHandler('iq', self._PrivateCB, 'result',
common.xmpp.NS_PRIVATE)
con.RegisterHandler('iq', self._SecLabelCB, 'result',
common.xmpp.NS_SECLABEL_CATALOG)
con.RegisterHandler('iq', self._HttpAuthCB, 'get',
common.xmpp.NS_HTTP_AUTH)
con.RegisterHandler('iq', self._CommandExecuteCB, 'set',

View File

@ -193,7 +193,7 @@ gajim_common_features = [xmpp.NS_BYTESTREAM, xmpp.NS_SI, xmpp.NS_FILE,
'jabber:iq:gateway', xmpp.NS_LAST, xmpp.NS_PRIVACY, xmpp.NS_PRIVATE,
xmpp.NS_REGISTER, xmpp.NS_VERSION, xmpp.NS_DATA, xmpp.NS_ENCRYPTED, 'msglog',
'sslc2s', 'stringprep', xmpp.NS_PING, xmpp.NS_TIME_REVISED, xmpp.NS_SSN,
xmpp.NS_MOOD, xmpp.NS_ACTIVITY, xmpp.NS_NICK, xmpp.NS_ROSTERX]
xmpp.NS_MOOD, xmpp.NS_ACTIVITY, xmpp.NS_NICK, xmpp.NS_ROSTERX, xmpp.NS_SECLABEL]
# Optional features gajim supports per account
gajim_optional_features = {}

View File

@ -100,6 +100,8 @@ NS_ROSTERX ='http://jabber.org/protocol/rosterx'
NS_ROSTER_VER ='urn:xmpp:features:rosterver' # XEP-0273
NS_RPC ='jabber:iq:rpc' # XEP-0009
NS_SASL ='urn:ietf:params:xml:ns:xmpp-sasl'
NS_SECLABEL ='urn:xmpp:sec-label:0'
NS_SECLABEL_CATALOG ='urn:xmpp:sec-label:catalog:0'
NS_SEARCH ='jabber:iq:search'
NS_SERVER ='jabber:server'
NS_SESSION ='urn:ietf:params:xml:ns:xmpp-session'

View File

@ -326,6 +326,7 @@ class ConversationTextview(gobject.GObject):
tag.set_property('underline', pango.UNDERLINE_SINGLE)
buffer_.create_tag('focus-out-line', justification = gtk.JUSTIFY_CENTER)
self.displaymarking_tags = {}
tag = buffer_.create_tag('xep0184-warning')
@ -1173,7 +1174,7 @@ class ConversationTextview(gobject.GObject):
def print_conversation_line(self, text, jid, kind, name, tim,
other_tags_for_name=[], other_tags_for_time=[],
other_tags_for_text=[], subject=None, old_kind=None, xhtml=None,
simple=False, graphics=True):
simple=False, graphics=True, displaymarking=None):
"""
Print 'chat' type messages
"""
@ -1238,6 +1239,9 @@ class ConversationTextview(gobject.GObject):
tim_format = self.get_time_to_show(tim)
buffer_.insert_with_tags_by_name(end_iter, tim_format + '\n',
'time_sometimes')
# If there's a displaymarking, print it here.
if displaymarking:
self.print_displaymarking(displaymarking)
# kind = info, we print things as if it was a status: same color, ...
if kind in ('error', 'info'):
kind = 'status'
@ -1309,6 +1313,19 @@ class ConversationTextview(gobject.GObject):
elif text.startswith('/me ') or text.startswith('/me\n'):
return kind
def print_displaymarking(self, displaymarking):
bgcolor = displaymarking.getAttr('bgcolor') or '#FFF'
fgcolor = displaymarking.getAttr('fgcolor') or '#000'
text = displaymarking.getData()
if text:
buffer_ = self.tv.get_buffer()
end_iter = buffer_.get_end_iter()
tag = self.displaymarking_tags.setdefault(bgcolor + '/' + fgcolor,
buffer_.create_tag(None, background=bgcolor, foreground=fgcolor))
buffer_.insert_with_tags(end_iter, '[' + text + ']', tag)
end_iter = buffer_.get_end_iter()
buffer_.insert_with_tags(end_iter, ' ')
def print_name(self, name, kind, other_tags_for_name):
if name:
buffer_ = self.tv.get_buffer()

View File

@ -385,6 +385,8 @@ class GroupchatControl(ChatControlBase):
column.set_visible(False)
self.list_treeview.set_expander_column(column)
self.setup_seclabel(self.xml.get_object('label_selector'))
gajim.gc_connected[self.account][self.room_jid] = False
# disable win, we are not connected yet
ChatControlBase.got_disconnected(self)
@ -785,30 +787,30 @@ class GroupchatControl(ChatControlBase):
menu.destroy()
def on_message(self, nick, msg, tim, has_timestamp=False, xhtml=None,
status_code=[]):
status_code=[], displaymarking=None):
if '100' in status_code:
# Room is not anonymous
self.is_anonymous = False
if not nick:
# message from server
self.print_conversation(msg, tim=tim, xhtml=xhtml)
self.print_conversation(msg, tim=tim, xhtml=xhtml, displaymarking=displaymarking)
else:
# message from someone
if has_timestamp:
# don't print xhtml if it's an old message.
# Like that xhtml messages are grayed too.
self.print_old_conversation(msg, nick, tim, None)
self.print_old_conversation(msg, nick, tim, None, displaymarking=displaymarking)
else:
self.print_conversation(msg, nick, tim, xhtml)
self.print_conversation(msg, nick, tim, xhtml, displaymarking=displaymarking)
def on_private_message(self, nick, msg, tim, xhtml, session, msg_id=None,
encrypted=False):
encrypted=False, displaymarking=None):
# Do we have a queue?
fjid = self.room_jid + '/' + nick
no_queue = len(gajim.events.get_events(self.account, fjid)) == 0
event = gajim.events.create_event('pm', (msg, '', 'incoming', tim,
encrypted, '', msg_id, xhtml, session))
encrypted, '', msg_id, xhtml, session, displaymarking))
gajim.events.add_event(self.account, fjid, event)
autopopup = gajim.config.get('autopopup')
@ -851,7 +853,8 @@ class GroupchatControl(ChatControlBase):
role_iter = model.iter_next(role_iter)
return None
def print_old_conversation(self, text, contact='', tim=None, xhtml = None):
def print_old_conversation(self, text, contact='', tim=None, xhtml = None,
displaymarking=None):
if isinstance(text, str):
text = unicode(text, 'utf-8')
if contact:
@ -867,10 +870,11 @@ class GroupchatControl(ChatControlBase):
small_attr = []
ChatControlBase.print_conversation_line(self, text, kind, contact, tim,
small_attr, small_attr + ['restored_message'],
small_attr + ['restored_message'], count_as_new=False, xhtml=xhtml)
small_attr + ['restored_message'], count_as_new=False, xhtml=xhtml,
displaymarking=displaymarking)
def print_conversation(self, text, contact='', tim=None, xhtml=None,
graphics=True):
graphics=True, displaymarking=None):
"""
Print a line in the conversation
@ -937,7 +941,7 @@ class GroupchatControl(ChatControlBase):
ChatControlBase.print_conversation_line(self, text, kind, contact, tim,
other_tags_for_name, [], other_tags_for_text, xhtml=xhtml,
graphics=graphics)
graphics=graphics, displaymarking=displaymarking)
def get_nb_unread(self):
type_events = ['printed_marked_gc_msg']
@ -1588,12 +1592,13 @@ class GroupchatControl(ChatControlBase):
if not message:
return
label = self.get_seclabel()
if message != '' or message != '\n':
self.save_sent_message(message)
# Send the message
gajim.connections[self.account].send_gc_message(self.room_jid,
message, xhtml=xhtml)
message, xhtml=xhtml, label=label)
self.msg_textview.get_buffer().set_text('')
self.msg_textview.grab_focus()

View File

@ -956,7 +956,7 @@ class Interface:
def handle_event_gc_msg(self, account, array):
# ('GC_MSG', account, (jid, msg, time, has_timestamp, htmlmsg,
# [status_codes]))
# [status_codes], displaymarking))
jids = array[0].split('/', 1)
room_jid = jids[0]
@ -980,7 +980,7 @@ class Interface:
# message from someone
nick = jids[1]
gc_control.on_message(nick, msg, array[2], array[3], xhtml, array[5])
gc_control.on_message(nick, msg, array[2], array[3], xhtml, array[5], displaymarking=array[6])
if self.remote_ctrl:
highlight = gc_control.needs_visual_notification(msg)

View File

@ -208,7 +208,7 @@ class MessageControl:
def send_message(self, message, keyID='', type_='chat', chatstate=None,
msg_id=None, composing_xep=None, resource=None, user_nick=None,
xhtml=None, callback=None, callback_args=[]):
xhtml=None, label=None, callback=None, callback_args=[]):
# Send the given message to the active tab.
# Doesn't return None if error
jid = self.contact.jid
@ -241,5 +241,5 @@ class MessageControl:
conn.send_message(jid, message, keyID, type_=type_, chatstate=chatstate,
msg_id=msg_id, composing_xep=composing_xep, resource=self.resource,
user_nick=user_nick, session=self.session,
original_message=original_message, xhtml=xhtml, callback=callback,
original_message=original_message, xhtml=xhtml, label=label, callback=callback,
callback_args=callback_args)

View File

@ -95,6 +95,8 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
self.resource = resource
if self.control and self.control.resource:
self.control.change_resource(self.resource)
seclabel = None
displaymarking = None
if not msg_type or msg_type not in ('chat', 'groupchat', 'error'):
msg_type = 'normal'
@ -113,7 +115,9 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
break
composing_xep, chatstate = self.get_chatstate(msg, msgtxt)
seclabel = msg.getTag('securitylabel')
if seclabel and seclabel.getNamespace() == common.xmpp.NS_SECLABEL:
displaymarking = seclabel.getTag('displaymarking')
xhtml = msg.getXHTML()
if msg_type == 'chat':
@ -236,15 +240,15 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
if self.control:
# print if a control is open
self.control.print_conversation(msgtxt, tim=tim, xhtml=xhtml,
encrypted=encrypted)
encrypted=encrypted, displaymarking=displaymarking)
else:
# otherwise pass it off to the control to be queued
groupchat_control.on_private_message(nickname, msgtxt, tim,
xhtml, self, msg_id=msg_id, encrypted=encrypted)
xhtml, self, msg_id=msg_id, encrypted=encrypted, displaymarking=displaymarking)
else:
self.roster_message(jid, msgtxt, tim, encrypted, msg_type,
subject, resource, msg_id, user_nick, advanced_notif_num,
xhtml=xhtml, form_node=form_node)
xhtml=xhtml, form_node=form_node, displaymarking=displaymarking)
nickname = gajim.get_name_from_jid(self.conn.name, jid)
@ -270,7 +274,7 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
def roster_message(self, jid, msg, tim, encrypted=False, msg_type='',
subject=None, resource='', msg_id=None, user_nick='',
advanced_notif_num=None, xhtml=None, form_node=None):
advanced_notif_num=None, xhtml=None, form_node=None, displaymarking=None):
"""
Display the message or show notification in the roster
"""
@ -334,7 +338,7 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
if msg_type == 'normal' and popup: # it's single message to be autopopuped
dialogs.SingleMessageWindow(self.conn.name, contact.jid,
action='receive', from_whom=jid, subject=subject, message=msg,
resource=resource, session=self, form_node=form_node)
resource=resource, session=self, form_node=form_node, displaymarking=displaymarking)
return
# We print if window is opened and it's not a single message
@ -345,7 +349,7 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
typ = 'error'
self.control.print_conversation(msg, typ, tim=tim, encrypted=encrypted,
subject=subject, xhtml=xhtml)
subject=subject, xhtml=xhtml, displaymarking=displaymarking)
if msg_id:
gajim.logger.set_read_messages([msg_id])
@ -366,7 +370,7 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
contact)
event = gajim.events.create_event(type_, (msg, subject, msg_type, tim,
encrypted, resource, msg_id, xhtml, self, form_node),
encrypted, resource, msg_id, xhtml, self, form_node, displaymarking),
show_in_roster=show_in_roster, show_in_systray=show_in_systray)
gajim.events.add_event(self.conn.name, fjid, event)