XEP-0308 Last Message Correction support.
This commit is contained in:
parent
df9a14f2a6
commit
b44b8499d7
|
@ -343,13 +343,13 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
if resource is None:
|
||||
# We very likely got a contact with a random resource.
|
||||
# This is bad, we need the highest for caps etc.
|
||||
c = gajim.contacts.get_contact_with_highest_priority(
|
||||
acct, contact.jid)
|
||||
c = gajim.contacts.get_contact_with_highest_priority(acct,
|
||||
contact.jid)
|
||||
if c and not isinstance(c, GC_Contact):
|
||||
contact = c
|
||||
|
||||
MessageControl.__init__(self, type_id, parent_win, widget_name,
|
||||
contact, acct, resource=resource)
|
||||
contact, acct, resource=resource)
|
||||
|
||||
widget = self.xml.get_object('history_button')
|
||||
# set document-open-recent icon for history button
|
||||
|
@ -371,85 +371,90 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
# Create banner and connect signals
|
||||
widget = self.xml.get_object('banner_eventbox')
|
||||
id_ = widget.connect('button-press-event',
|
||||
self._on_banner_eventbox_button_press_event)
|
||||
self._on_banner_eventbox_button_press_event)
|
||||
self.handlers[id_] = widget
|
||||
|
||||
self.urlfinder = re.compile(
|
||||
r"(www\.(?!\.)|[a-z][a-z0-9+.-]*://)[^\s<>'\"]+[^!,\.\s<>\)'\"\]]")
|
||||
r"(www\.(?!\.)|[a-z][a-z0-9+.-]*://)[^\s<>'\"]+[^!,\.\s<>\)'\"\]]")
|
||||
|
||||
self.banner_status_label = self.xml.get_object('banner_label')
|
||||
id_ = self.banner_status_label.connect('populate_popup',
|
||||
self.on_banner_label_populate_popup)
|
||||
self.on_banner_label_populate_popup)
|
||||
self.handlers[id_] = self.banner_status_label
|
||||
|
||||
# Init DND
|
||||
self.TARGET_TYPE_URI_LIST = 80
|
||||
self.dnd_list = [('text/uri-list', 0, self.TARGET_TYPE_URI_LIST),
|
||||
('MY_TREE_MODEL_ROW', gtk.TARGET_SAME_APP, 0)]
|
||||
('MY_TREE_MODEL_ROW', gtk.TARGET_SAME_APP, 0)]
|
||||
id_ = self.widget.connect('drag_data_received',
|
||||
self._on_drag_data_received)
|
||||
self._on_drag_data_received)
|
||||
self.handlers[id_] = self.widget
|
||||
self.widget.drag_dest_set(gtk.DEST_DEFAULT_MOTION |
|
||||
gtk.DEST_DEFAULT_HIGHLIGHT |
|
||||
gtk.DEST_DEFAULT_DROP,
|
||||
self.dnd_list, gtk.gdk.ACTION_COPY)
|
||||
gtk.DEST_DEFAULT_HIGHLIGHT |
|
||||
gtk.DEST_DEFAULT_DROP,
|
||||
self.dnd_list, gtk.gdk.ACTION_COPY)
|
||||
|
||||
# Create textviews and connect signals
|
||||
self.conv_textview = ConversationTextview(self.account)
|
||||
id_ = self.conv_textview.connect('quote', self.on_quote)
|
||||
self.handlers[id_] = self.conv_textview.tv
|
||||
id_ = self.conv_textview.tv.connect('key_press_event',
|
||||
self._conv_textview_key_press_event)
|
||||
self._conv_textview_key_press_event)
|
||||
self.handlers[id_] = self.conv_textview.tv
|
||||
# FIXME: DND on non editable TextView, find a better way
|
||||
self.drag_entered = False
|
||||
id_ = self.conv_textview.tv.connect('drag_data_received',
|
||||
self._on_drag_data_received)
|
||||
self._on_drag_data_received)
|
||||
self.handlers[id_] = self.conv_textview.tv
|
||||
id_ = self.conv_textview.tv.connect('drag_motion', self._on_drag_motion)
|
||||
self.handlers[id_] = self.conv_textview.tv
|
||||
id_ = self.conv_textview.tv.connect('drag_leave', self._on_drag_leave)
|
||||
self.handlers[id_] = self.conv_textview.tv
|
||||
self.conv_textview.tv.drag_dest_set(gtk.DEST_DEFAULT_MOTION |
|
||||
gtk.DEST_DEFAULT_HIGHLIGHT |
|
||||
gtk.DEST_DEFAULT_DROP,
|
||||
self.dnd_list, gtk.gdk.ACTION_COPY)
|
||||
gtk.DEST_DEFAULT_HIGHLIGHT |
|
||||
gtk.DEST_DEFAULT_DROP,
|
||||
self.dnd_list, gtk.gdk.ACTION_COPY)
|
||||
|
||||
self.conv_scrolledwindow = self.xml.get_object(
|
||||
'conversation_scrolledwindow')
|
||||
'conversation_scrolledwindow')
|
||||
self.conv_scrolledwindow.add(self.conv_textview.tv)
|
||||
widget = self.conv_scrolledwindow.get_vadjustment()
|
||||
id_ = widget.connect('value-changed',
|
||||
self.on_conversation_vadjustment_value_changed)
|
||||
self.on_conversation_vadjustment_value_changed)
|
||||
self.handlers[id_] = widget
|
||||
id_ = widget.connect('changed',
|
||||
self.on_conversation_vadjustment_changed)
|
||||
self.on_conversation_vadjustment_changed)
|
||||
self.handlers[id_] = widget
|
||||
self.scroll_to_end_id = None
|
||||
self.was_at_the_end = True
|
||||
self.correcting = False
|
||||
self.last_sent_msg = None
|
||||
self.last_sent_txt = None
|
||||
self.last_received_txt = {} # one per name
|
||||
self.last_received_id = {} # one per name
|
||||
|
||||
# add MessageTextView to UI and connect signals
|
||||
self.msg_scrolledwindow = self.xml.get_object('message_scrolledwindow')
|
||||
self.msg_textview = MessageTextView()
|
||||
id_ = self.msg_textview.connect('mykeypress',
|
||||
self._on_message_textview_mykeypress_event)
|
||||
self._on_message_textview_mykeypress_event)
|
||||
self.handlers[id_] = self.msg_textview
|
||||
self.msg_scrolledwindow.add(self.msg_textview)
|
||||
id_ = self.msg_textview.connect('key_press_event',
|
||||
self._on_message_textview_key_press_event)
|
||||
self._on_message_textview_key_press_event)
|
||||
self.handlers[id_] = self.msg_textview
|
||||
id_ = self.msg_textview.connect('size-request', self.size_request)
|
||||
self.handlers[id_] = self.msg_textview
|
||||
id_ = self.msg_textview.connect('populate_popup',
|
||||
self.on_msg_textview_populate_popup)
|
||||
self.on_msg_textview_populate_popup)
|
||||
self.handlers[id_] = self.msg_textview
|
||||
# Setup DND
|
||||
id_ = self.msg_textview.connect('drag_data_received',
|
||||
self._on_drag_data_received)
|
||||
self._on_drag_data_received)
|
||||
self.handlers[id_] = self.msg_textview
|
||||
self.msg_textview.drag_dest_set(gtk.DEST_DEFAULT_MOTION |
|
||||
gtk.DEST_DEFAULT_HIGHLIGHT,
|
||||
self.dnd_list, gtk.gdk.ACTION_COPY)
|
||||
gtk.DEST_DEFAULT_HIGHLIGHT,
|
||||
self.dnd_list, gtk.gdk.ACTION_COPY)
|
||||
|
||||
self.update_font()
|
||||
|
||||
|
@ -474,7 +479,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
# (so toggle works ok)
|
||||
img = self.xml.get_object('emoticons_button_image')
|
||||
img.set_from_file(os.path.join(gajim.DATA_DIR, 'emoticons', 'static',
|
||||
'smile.png'))
|
||||
'smile.png'))
|
||||
self.toggle_emoticons()
|
||||
|
||||
# Attach speller
|
||||
|
@ -893,12 +898,23 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
|
||||
label = self.get_seclabel()
|
||||
|
||||
def _cb(msg, cb, *cb_args):
|
||||
self.last_sent_msg = msg
|
||||
self.last_sent_txt = cb_args[1]
|
||||
if cb:
|
||||
cb(msg, *cb_args)
|
||||
|
||||
if self.correcting and self.last_sent_msg:
|
||||
correction_msg = self.last_sent_msg
|
||||
else:
|
||||
correction_msg = None
|
||||
|
||||
gajim.nec.push_outgoing_event(MessageOutgoingEvent(None,
|
||||
account=self.account, jid=self.contact.jid, message=message,
|
||||
keyID=keyID, type_=type_, chatstate=chatstate, msg_id=msg_id,
|
||||
resource=resource, user_nick=self.user_nick, xhtml=xhtml,
|
||||
label=label, callback=callback, callback_args=callback_args,
|
||||
control=self, attention=attention))
|
||||
label=label, callback=_cb, callback_args=[callback] + callback_args,
|
||||
control=self, attention=attention, correction_msg=correction_msg))
|
||||
|
||||
# Record the history of sent messages
|
||||
self.save_message(message, 'sent')
|
||||
|
@ -939,9 +955,11 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
def print_conversation_line(self, text, kind, name, tim,
|
||||
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, displaymarking=None, msg_id=None):
|
||||
xep0184_id=None, graphics=True, displaymarking=None, msg_id=None,
|
||||
correct_id=None):
|
||||
"""
|
||||
Print 'chat' type messages
|
||||
correct_id = (message_id, correct_id)
|
||||
"""
|
||||
jid = self.contact.jid
|
||||
full_jid = self.get_full_jid()
|
||||
|
@ -949,16 +967,28 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
end = False
|
||||
if self.was_at_the_end or kind == 'outgoing':
|
||||
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,
|
||||
displaymarking=displaymarking)
|
||||
old_txt = ''
|
||||
if name in self.last_received_txt:
|
||||
old_txt = self.last_received_txt[name]
|
||||
if correct_id and correct_id[1] and \
|
||||
name in self.conv_textview.last_received_message_marks and \
|
||||
correct_id[1] == self.last_received_id[name]:
|
||||
self.conv_textview.correct_last_received_message(text, xhtml,
|
||||
name, old_txt)
|
||||
else:
|
||||
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,
|
||||
displaymarking=displaymarking)
|
||||
|
||||
if xep0184_id is not None:
|
||||
textview.show_xep0184_warning(xep0184_id)
|
||||
|
||||
if not count_as_new:
|
||||
return
|
||||
if kind in ('incoming', 'outgoing'):
|
||||
self.last_received_txt[name] = text
|
||||
self.last_received_id[name] = correct_id[0]
|
||||
if kind == 'incoming':
|
||||
if not self.type_id == message_control.TYPE_GC or \
|
||||
gajim.config.get('notify_on_all_muc_messages') or \
|
||||
|
@ -1370,7 +1400,21 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
start_iter = msg_buf.get_start_iter()
|
||||
end_iter = msg_buf.get_end_iter()
|
||||
self.orig_msg = msg_buf.get_text(start_iter, end_iter, 0).decode(
|
||||
'utf-8')
|
||||
'utf-8')
|
||||
if pos == size and size > 0 and direction == 'up' and \
|
||||
msg_type == 'sent' and not self.correcting:
|
||||
self.correcting = True
|
||||
self.old_message_tv_color = self.msg_textview.get_style().base[0]
|
||||
self.msg_textview.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(
|
||||
'PaleGoldenrod'))
|
||||
message = history[pos - 1]
|
||||
msg_buf.set_text(message)
|
||||
return
|
||||
if self.correcting:
|
||||
# We were previously correcting
|
||||
self.msg_textview.modify_base(gtk.STATE_NORMAL,
|
||||
self.old_message_tv_color)
|
||||
self.correcting = False
|
||||
pos += -1 if direction == 'up' else +1
|
||||
if pos == -1:
|
||||
return
|
||||
|
@ -1456,6 +1500,8 @@ class ChatControl(ChatControlBase):
|
|||
'chat_control', contact, acct, resource)
|
||||
|
||||
self.gpg_is_active = False
|
||||
self.last_recv_message_id = None
|
||||
self.last_recv_message_marks = None
|
||||
# for muc use:
|
||||
# widget = self.xml.get_object('muc_window_actions_button')
|
||||
self.actions_button = self.xml.get_object('message_window_actions_button')
|
||||
|
@ -2318,7 +2364,8 @@ class ChatControl(ChatControlBase):
|
|||
gobject.source_remove(self.possible_inactive_timeout_id)
|
||||
self._schedule_activity_timers()
|
||||
|
||||
def _on_sent(id_, contact, message, encrypted, xhtml, label):
|
||||
def _on_sent(msg, contact, message, encrypted, xhtml, label, old_txt):
|
||||
id_ = msg.getID()
|
||||
if contact.supports(NS_RECEIPTS) and gajim.config.get_per('accounts',
|
||||
self.account, 'request_receipt'):
|
||||
xep0184_id = id_
|
||||
|
@ -2328,13 +2375,22 @@ class ChatControl(ChatControlBase):
|
|||
displaymarking = label.getTag('displaymarking')
|
||||
else:
|
||||
displaymarking = None
|
||||
self.print_conversation(message, self.contact.jid, encrypted=encrypted,
|
||||
xep0184_id=xep0184_id, xhtml=xhtml, displaymarking=displaymarking)
|
||||
if self.correcting and \
|
||||
self.conv_textview.last_sent_message_marks[0]:
|
||||
self.conv_textview.correct_last_sent_message(message, xhtml,
|
||||
self.get_our_nick(), old_txt)
|
||||
self.correcting = False
|
||||
self.msg_textview.modify_base(gtk.STATE_NORMAL,
|
||||
self.old_message_tv_color)
|
||||
return
|
||||
self.print_conversation(message, self.contact.jid,
|
||||
encrypted=encrypted, xep0184_id=xep0184_id, xhtml=xhtml,
|
||||
displaymarking=displaymarking)
|
||||
|
||||
ChatControlBase.send_message(self, message, keyID, type_='chat',
|
||||
chatstate=chatstate_to_send, xhtml=xhtml, callback=_on_sent,
|
||||
callback_args=[contact, message, encrypted, xhtml,
|
||||
self.get_seclabel()], process_commands=process_commands,
|
||||
self.get_seclabel(), self.last_sent_txt], process_commands=process_commands,
|
||||
attention=attention)
|
||||
|
||||
def check_for_possible_paused_chatstate(self, arg):
|
||||
|
@ -2446,7 +2502,7 @@ class ChatControl(ChatControlBase):
|
|||
|
||||
def print_conversation(self, text, frm='', tim=None, encrypted=False,
|
||||
subject=None, xhtml=None, simple=False, xep0184_id=None,
|
||||
displaymarking=None, msg_id=None):
|
||||
displaymarking=None, msg_id=None, correct_id=None):
|
||||
"""
|
||||
Print a line in the conversation
|
||||
|
||||
|
@ -2511,7 +2567,7 @@ class ChatControl(ChatControlBase):
|
|||
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, displaymarking=displaymarking,
|
||||
msg_id=msg_id)
|
||||
msg_id=msg_id, correct_id=correct_id)
|
||||
if text.startswith('/me ') or text.startswith('/me\n'):
|
||||
self.old_msg_kind = None
|
||||
else:
|
||||
|
|
|
@ -254,9 +254,11 @@ class CommonConnection:
|
|||
def _prepare_message(self, jid, msg, keyID, type_='chat', subject='',
|
||||
chatstate=None, msg_id=None, resource=None, user_nick=None, xhtml=None,
|
||||
session=None, forward_from=None, form_node=None, label=None,
|
||||
original_message=None, delayed=None, attention=False, callback=None):
|
||||
original_message=None, delayed=None, attention=False, correction_msg=None,
|
||||
callback=None):
|
||||
if not self.connection or self.connected < 2:
|
||||
return 1
|
||||
|
||||
try:
|
||||
jid = self.check_jid(jid)
|
||||
except helpers.InvalidFormat:
|
||||
|
@ -306,7 +308,7 @@ class CommonConnection:
|
|||
jid, xhtml, subject, chatstate, msg_id,
|
||||
label, forward_from, delayed, session,
|
||||
form_node, user_nick, keyID, attention,
|
||||
callback)
|
||||
correction_msg, callback)
|
||||
gajim.nec.push_incoming_event(GPGTrustKeyEvent(None,
|
||||
conn=self, callback=_on_always_trust))
|
||||
else:
|
||||
|
@ -314,7 +316,7 @@ class CommonConnection:
|
|||
original_message, fjid, resource, jid, xhtml,
|
||||
subject, chatstate, msg_id, label, forward_from,
|
||||
delayed, session, form_node, user_nick, keyID,
|
||||
attention, callback)
|
||||
attention, correction_msg, callback)
|
||||
gajim.thread_interface(encrypt_thread, [msg, keyID, False],
|
||||
_on_encrypted, [])
|
||||
return
|
||||
|
@ -322,18 +324,19 @@ class CommonConnection:
|
|||
self._message_encrypted_cb(('', error), type_, msg, msgtxt,
|
||||
original_message, fjid, resource, jid, xhtml, subject,
|
||||
chatstate, msg_id, label, forward_from, delayed, session,
|
||||
form_node, user_nick, keyID, attention, callback)
|
||||
form_node, user_nick, keyID, attention, correction_msg,
|
||||
callback)
|
||||
return
|
||||
|
||||
self._on_continue_message(type_, msg, msgtxt, original_message, fjid,
|
||||
resource, jid, xhtml, subject, msgenc, keyID, chatstate, msg_id,
|
||||
label, forward_from, delayed, session, form_node, user_nick,
|
||||
attention, callback)
|
||||
attention, correction_msg, callback)
|
||||
|
||||
def _message_encrypted_cb(self, output, type_, msg, msgtxt,
|
||||
original_message, fjid, resource, jid, xhtml, subject, chatstate, msg_id,
|
||||
label, forward_from, delayed, session, form_node, user_nick, keyID,
|
||||
attention, callback):
|
||||
attention, correction_msg, callback):
|
||||
msgenc, error = output
|
||||
|
||||
if msgenc and not error:
|
||||
|
@ -346,7 +349,7 @@ class CommonConnection:
|
|||
self._on_continue_message(type_, msg, msgtxt, original_message,
|
||||
fjid, resource, jid, xhtml, subject, msgenc, keyID,
|
||||
chatstate, msg_id, label, forward_from, delayed, session,
|
||||
form_node, user_nick, attention, callback)
|
||||
form_node, user_nick, attention, correction_msg, callback)
|
||||
return
|
||||
# Encryption failed, do not send message
|
||||
tim = localtime()
|
||||
|
@ -356,7 +359,32 @@ class CommonConnection:
|
|||
def _on_continue_message(self, type_, msg, msgtxt, original_message, fjid,
|
||||
resource, jid, xhtml, subject, msgenc, keyID, chatstate, msg_id,
|
||||
label, forward_from, delayed, session, form_node, user_nick, attention,
|
||||
callback):
|
||||
correction_msg, callback):
|
||||
|
||||
if correction_msg:
|
||||
id_ = correction_msg.getID()
|
||||
if correction_msg.getTag('replace'):
|
||||
correction_msg.delChild('replace')
|
||||
correction_msg.setTag('replace', attrs={'id': id_},
|
||||
namespace=nbxmpp.NS_CORRECT)
|
||||
id2 = self.connection.getAnID()
|
||||
correction_msg.setID(id2)
|
||||
correction_msg.setBody(msgtxt)
|
||||
if xhtml:
|
||||
correction_msg.setXHTML(xhtml)
|
||||
|
||||
if session:
|
||||
session.last_send = time.time()
|
||||
|
||||
# XEP-0200
|
||||
if session.enable_encryption:
|
||||
correction_msg = session.encrypt_stanza(correction_msg)
|
||||
|
||||
if callback:
|
||||
callback(jid, msg, keyID, forward_from, session, original_message,
|
||||
subject, type_, correction_msg, xhtml)
|
||||
return
|
||||
|
||||
if type_ == 'chat':
|
||||
msg_iq = nbxmpp.Message(to=fjid, body=msgtxt, typ=type_,
|
||||
xhtml=xhtml)
|
||||
|
@ -1941,8 +1969,8 @@ class Connection(CommonConnection, ConnectionHandlers):
|
|||
def send_message(self, jid, msg, keyID=None, type_='chat', subject='',
|
||||
chatstate=None, msg_id=None, resource=None, user_nick=None, xhtml=None,
|
||||
label=None, session=None, forward_from=None, form_node=None,
|
||||
original_message=None, delayed=None, attention=False, callback=None,
|
||||
callback_args=[], now=False):
|
||||
original_message=None, delayed=None, attention=False, correction_msg=None,
|
||||
callback=None, callback_args=[], now=False):
|
||||
|
||||
def cb(jid, msg, keyID, forward_from, session, original_message,
|
||||
subject, type_, msg_iq, xhtml):
|
||||
|
@ -1961,7 +1989,7 @@ class Connection(CommonConnection, ConnectionHandlers):
|
|||
user_nick=user_nick, xhtml=xhtml, label=label, session=session,
|
||||
forward_from=forward_from, form_node=form_node,
|
||||
original_message=original_message, delayed=delayed,
|
||||
attention=attention, callback=cb)
|
||||
attention=attention, correction_msg=correction_msg, callback=cb)
|
||||
|
||||
def _nec_message_outgoing(self, obj):
|
||||
if obj.account != self.name:
|
||||
|
@ -1974,7 +2002,7 @@ class Connection(CommonConnection, ConnectionHandlers):
|
|||
gajim.nec.push_incoming_event(MessageSentEvent(None, conn=self,
|
||||
jid=jid, message=msg, keyID=keyID, chatstate=obj.chatstate))
|
||||
if obj.callback:
|
||||
obj.callback(msg_id, *obj.callback_args)
|
||||
obj.callback(msg_iq, *obj.callback_args)
|
||||
|
||||
if not obj.is_loggable:
|
||||
return
|
||||
|
@ -1986,7 +2014,8 @@ class Connection(CommonConnection, ConnectionHandlers):
|
|||
resource=obj.resource, user_nick=obj.user_nick, xhtml=obj.xhtml,
|
||||
label=obj.label, session=obj.session, forward_from=obj.forward_from,
|
||||
form_node=obj.form_node, original_message=obj.original_message,
|
||||
delayed=obj.delayed, attention=obj.attention, callback=cb)
|
||||
delayed=obj.delayed, attention=obj.attention,
|
||||
correction_msg=obj.correction_msg, callback=cb)
|
||||
|
||||
def send_contacts(self, contacts, fjid, type_='message'):
|
||||
"""
|
||||
|
@ -2524,18 +2553,38 @@ class Connection(CommonConnection, ConnectionHandlers):
|
|||
t.setTagData('password', password)
|
||||
self.connection.send(p)
|
||||
|
||||
def send_gc_message(self, jid, msg, xhtml=None, label=None):
|
||||
def send_gc_message(self, jid, msg, xhtml=None, label=None,
|
||||
correction_msg=None, callback=None):
|
||||
if not gajim.account_is_connected(self.name):
|
||||
return
|
||||
if correction_msg:
|
||||
id_ = correction_msg.getID()
|
||||
if correction_msg.getTag('replace'):
|
||||
correction_msg.delChild('replace')
|
||||
correction_msg.setTag('replace', attrs={'id': id_},
|
||||
namespace=nbxmpp.NS_CORRECT)
|
||||
id2 = self.connection.getAnID()
|
||||
correction_msg.setID(id2)
|
||||
correction_msg.setBody(msg)
|
||||
if xhtml:
|
||||
correction_msg.setXHTML(xhtml)
|
||||
self.connection.send(correction_msg)
|
||||
gajim.nec.push_incoming_event(MessageSentEvent(None, conn=self,
|
||||
jid=jid, message=msg, keyID=None, chatstate=None))
|
||||
if callback:
|
||||
callback(correction_msg, msg)
|
||||
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 = nbxmpp.Message(jid, msg, typ='groupchat', xhtml=xhtml)
|
||||
if label is not None:
|
||||
msg_iq.addChild(node = label)
|
||||
msg_iq.addChild(node=label)
|
||||
self.connection.send(msg_iq)
|
||||
gajim.nec.push_incoming_event(MessageSentEvent(None, conn=self,
|
||||
jid=jid, message=msg, keyID=None, chatstate=None))
|
||||
if callback:
|
||||
callback(msg_iq, msg)
|
||||
|
||||
def send_gc_subject(self, jid, subject):
|
||||
if not gajim.account_is_connected(self.name):
|
||||
|
|
|
@ -1250,6 +1250,7 @@ class DecryptedMessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
|
|||
self.popup = False
|
||||
self.msg_id = None # id in log database
|
||||
self.attention = False # XEP-0224
|
||||
self.correct_id = None # XEP-0308
|
||||
|
||||
self.receipt_request_tag = self.stanza.getTag('request',
|
||||
namespace=nbxmpp.NS_RECEIPTS)
|
||||
|
@ -1293,6 +1294,10 @@ class DecryptedMessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
|
|||
self.msgtxt += _('URL:')
|
||||
self.msgtxt += ' ' + self.oob_url
|
||||
|
||||
replace = self.stanza.getTag('replace', namespace=nbxmpp.NS_CORRECT)
|
||||
if replace:
|
||||
self.correct_id = replace.getAttr('id')
|
||||
|
||||
return True
|
||||
|
||||
class ChatstateReceivedEvent(nec.NetworkIncomingEvent):
|
||||
|
@ -1320,6 +1325,7 @@ class GcMessageReceivedEvent(nec.NetworkIncomingEvent):
|
|||
self.nickname = self.msg_obj.resource
|
||||
self.timestamp = self.msg_obj.timestamp
|
||||
self.xhtml_msgtxt = self.stanza.getXHTML()
|
||||
self.correct_id = None # XEP-0308
|
||||
|
||||
if gajim.config.get('ignore_incoming_xhtml'):
|
||||
self.xhtml_msgtxt = None
|
||||
|
@ -1392,6 +1398,10 @@ class GcMessageReceivedEvent(nec.NetworkIncomingEvent):
|
|||
[self.stanza, self.msg_obj], 0)
|
||||
return
|
||||
|
||||
replace = self.stanza.getTag('replace', namespace=nbxmpp.NS_CORRECT)
|
||||
if replace:
|
||||
self.correct_id = replace.getAttr('id')
|
||||
|
||||
return True
|
||||
|
||||
class GcSubjectReceivedEvent(nec.NetworkIncomingEvent):
|
||||
|
@ -2426,6 +2436,7 @@ class MessageOutgoingEvent(nec.NetworkOutgoingEvent):
|
|||
self.is_loggable = True
|
||||
self.control = None
|
||||
self.attention = False
|
||||
self.correction_msg = None
|
||||
|
||||
def generate(self):
|
||||
return True
|
||||
|
|
|
@ -212,7 +212,7 @@ gajim_common_features = [nbxmpp.NS_BYTESTREAM, nbxmpp.NS_SI, nbxmpp.NS_FILE,
|
|||
nbxmpp.NS_SSN, nbxmpp.NS_MOOD, nbxmpp.NS_ACTIVITY, nbxmpp.NS_NICK,
|
||||
nbxmpp.NS_ROSTERX, nbxmpp.NS_SECLABEL, nbxmpp.NS_HASHES,
|
||||
nbxmpp.NS_HASHES_MD5, nbxmpp.NS_HASHES_SHA1, nbxmpp.NS_HASHES_SHA256,
|
||||
nbxmpp.NS_HASHES_SHA512]
|
||||
nbxmpp.NS_HASHES_SHA512, nbxmpp.NS_CORRECT]
|
||||
|
||||
# Optional features gajim supports per account
|
||||
gajim_optional_features = {}
|
||||
|
|
|
@ -74,7 +74,7 @@ class TextViewImage(gtk.Image):
|
|||
self._disconnect_funcs = []
|
||||
self.connect('parent-set', self.on_parent_set)
|
||||
self.connect('expose-event', self.on_expose)
|
||||
self.set_tooltip_text(text)
|
||||
self.set_tooltip_markup(text)
|
||||
self.anchor.set_data('plaintext', text)
|
||||
|
||||
def _get_selected(self):
|
||||
|
@ -171,7 +171,9 @@ class ConversationTextview(gobject.GObject):
|
|||
|
||||
FOCUS_OUT_LINE_PIXBUF = gtkgui_helpers.get_icon_pixmap('gajim-muc_separator')
|
||||
XEP0184_WARNING_PIXBUF = gtkgui_helpers.get_icon_pixmap(
|
||||
'gajim-receipt_missing')
|
||||
'gajim-receipt_missing')
|
||||
MESSAGE_CORRECTED_PIXBUF = gtkgui_helpers.get_icon_pixmap(
|
||||
'gajim-message_corrected')
|
||||
|
||||
# smooth scroll constants
|
||||
MAX_SCROLL_TIME = 0.4 # seconds
|
||||
|
@ -205,6 +207,9 @@ class ConversationTextview(gobject.GObject):
|
|||
self.image_cache = {}
|
||||
self.xep0184_marks = {}
|
||||
self.xep0184_shown = {}
|
||||
self.last_sent_message_marks = [None, None]
|
||||
# A pair per occupant. Key is '' in normal chat
|
||||
self.last_received_message_marks = {}
|
||||
|
||||
# It's True when we scroll in the code, so we can detect scroll from user
|
||||
self.auto_scrolling = False
|
||||
|
@ -459,6 +464,51 @@ class ConversationTextview(gobject.GObject):
|
|||
self.smooth_id = None
|
||||
self.smooth_scroll_timer.cancel()
|
||||
|
||||
def show_corrected_message_warning(self, iter_, text=''):
|
||||
buffer_ = self.tv.get_buffer()
|
||||
buffer_.begin_user_action()
|
||||
buffer_.insert(iter_, ' ')
|
||||
anchor = buffer_.create_child_anchor(iter_)
|
||||
img = TextViewImage(anchor, text)
|
||||
img.set_from_pixbuf(ConversationTextview.MESSAGE_CORRECTED_PIXBUF)
|
||||
img.show()
|
||||
self.tv.add_child_at_anchor(img, anchor)
|
||||
buffer_.end_user_action()
|
||||
|
||||
def correct_last_sent_message(self, message, xhtml, name, old_txt):
|
||||
m1 = self.last_sent_message_marks[0]
|
||||
m2 = self.last_sent_message_marks[1]
|
||||
buffer_ = self.tv.get_buffer()
|
||||
i1 = buffer_.get_iter_at_mark(m1)
|
||||
i2 = buffer_.get_iter_at_mark(m2)
|
||||
txt = buffer_.get_text(i1, i2)
|
||||
buffer_.delete(i1, i2)
|
||||
i2 = self.print_real_text(message, text_tags=['outgoingtxt'], name=name,
|
||||
xhtml=xhtml, iter_=i1)
|
||||
tt_txt = _('<b>Message was corrected. Last message was:</b>\n %s') % \
|
||||
old_txt
|
||||
self.show_corrected_message_warning(i2, tt_txt)
|
||||
self.last_sent_message_marks[1] = buffer_.create_mark(None, i2,
|
||||
left_gravity=True)
|
||||
|
||||
def correct_last_received_message(self, message, xhtml, name, old_txt):
|
||||
if name not in self.last_received_message_marks:
|
||||
return
|
||||
m1 = self.last_received_message_marks[name][0]
|
||||
m2 = self.last_received_message_marks[name][1]
|
||||
buffer_ = self.tv.get_buffer()
|
||||
i1 = buffer_.get_iter_at_mark(m1)
|
||||
i2 = buffer_.get_iter_at_mark(m2)
|
||||
txt = buffer_.get_text(i1, i2)
|
||||
buffer_.delete(i1, i2)
|
||||
i2 = self.print_real_text(message, text_tags=['incomingtxt'], name=name,
|
||||
xhtml=xhtml, iter_=i1)
|
||||
tt_txt = _('<b>Message was corrected. Last message was:</b>\n %s') % \
|
||||
old_txt
|
||||
self.show_corrected_message_warning(i2, tt_txt)
|
||||
self.last_received_message_marks[name][1] = buffer_.create_mark(None, i2,
|
||||
left_gravity=True)
|
||||
|
||||
def show_xep0184_warning(self, id_):
|
||||
if id_ in self.xep0184_marks:
|
||||
return
|
||||
|
@ -985,7 +1035,8 @@ class ConversationTextview(gobject.GObject):
|
|||
else:
|
||||
helpers.launch_browser_mailer(kind, word)
|
||||
|
||||
def detect_and_print_special_text(self, otext, other_tags, graphics=True):
|
||||
def detect_and_print_special_text(self, otext, other_tags, graphics=True,
|
||||
iter_=None):
|
||||
"""
|
||||
Detect special text (emots & links & formatting), print normal text
|
||||
before any special text it founds, then print special text (that happens
|
||||
|
@ -1015,6 +1066,10 @@ class ConversationTextview(gobject.GObject):
|
|||
iterator = gajim.interface.emot_and_basic_re.finditer(otext)
|
||||
else: # search for just urls + mail + formatting
|
||||
iterator = gajim.interface.basic_pattern_re.finditer(otext)
|
||||
if iter_:
|
||||
end_iter = iter_
|
||||
else:
|
||||
end_iter = buffer_.get_end_iter()
|
||||
for match in iterator:
|
||||
start, end = match.span()
|
||||
special_text = otext[start:end]
|
||||
|
@ -1026,18 +1081,19 @@ class ConversationTextview(gobject.GObject):
|
|||
index = end # update index
|
||||
|
||||
# now print it
|
||||
self.print_special_text(special_text, other_tags, graphics=graphics)
|
||||
self.print_special_text(special_text, other_tags, graphics=graphics,
|
||||
iter_=end_iter)
|
||||
specials_limit -= 1
|
||||
if specials_limit <= 0:
|
||||
break
|
||||
|
||||
# add the rest of text located in the index and after
|
||||
end_iter = buffer_.get_end_iter()
|
||||
insert_tags_func(end_iter, otext[index:], *other_tags)
|
||||
|
||||
return buffer_.get_end_iter()
|
||||
return end_iter
|
||||
|
||||
def print_special_text(self, special_text, other_tags, graphics=True):
|
||||
def print_special_text(self, special_text, other_tags, graphics=True,
|
||||
iter_=None):
|
||||
"""
|
||||
Is called by detect_and_print_special_text and prints special text
|
||||
(emots, links, formatting)
|
||||
|
@ -1056,7 +1112,7 @@ class ConversationTextview(gobject.GObject):
|
|||
text_is_valid_uri = False
|
||||
is_xhtml_link = None
|
||||
show_ascii_formatting_chars = \
|
||||
gajim.config.get('show_ascii_formatting_chars')
|
||||
gajim.config.get('show_ascii_formatting_chars')
|
||||
buffer_ = self.tv.get_buffer()
|
||||
|
||||
# Detect XHTML-IM link
|
||||
|
@ -1074,17 +1130,20 @@ class ConversationTextview(gobject.GObject):
|
|||
text_is_valid_uri = True
|
||||
|
||||
possible_emot_ascii_caps = special_text.upper() # emoticons keys are CAPS
|
||||
if iter_:
|
||||
end_iter = iter_
|
||||
else:
|
||||
end_iter = buffer_.get_end_iter()
|
||||
if gajim.config.get('emoticons_theme') and \
|
||||
possible_emot_ascii_caps in gajim.interface.emoticons.keys() and graphics:
|
||||
# it's an emoticon
|
||||
emot_ascii = possible_emot_ascii_caps
|
||||
end_iter = buffer_.get_end_iter()
|
||||
anchor = buffer_.create_child_anchor(end_iter)
|
||||
img = TextViewImage(anchor, special_text)
|
||||
animations = gajim.interface.emoticons_animations
|
||||
if not emot_ascii in animations:
|
||||
animations[emot_ascii] = gtk.gdk.PixbufAnimation(
|
||||
gajim.interface.emoticons[emot_ascii])
|
||||
gajim.interface.emoticons[emot_ascii])
|
||||
img.set_from_animation(animations[emot_ascii])
|
||||
img.show()
|
||||
self.images.append(img)
|
||||
|
@ -1095,13 +1154,13 @@ class ConversationTextview(gobject.GObject):
|
|||
text_is_valid_uri and not is_xhtml_link:
|
||||
tags.append('url')
|
||||
elif special_text.startswith('mailto:') and not is_xhtml_link:
|
||||
tags.append('mail')
|
||||
tags.append('mail')
|
||||
elif special_text.startswith('xmpp:') and not is_xhtml_link:
|
||||
tags.append('xmpp')
|
||||
tags.append('xmpp')
|
||||
elif gajim.interface.sth_at_sth_dot_sth_re.match(special_text) and\
|
||||
not is_xhtml_link:
|
||||
# it's a JID or mail
|
||||
tags.append('sth_at_sth')
|
||||
# it's a JID or mail
|
||||
tags.append('sth_at_sth')
|
||||
elif special_text.startswith('*'): # it's a bold text
|
||||
tags.append('bold')
|
||||
if special_text[1] == '/' and special_text[-2] == '/' and\
|
||||
|
@ -1150,7 +1209,6 @@ class ConversationTextview(gobject.GObject):
|
|||
else:
|
||||
# It's nothing special
|
||||
if use_other_tags:
|
||||
end_iter = buffer_.get_end_iter()
|
||||
insert_tags_func = buffer_.insert_with_tags_by_name
|
||||
if other_tags and isinstance(other_tags[0], gtk.TextTag):
|
||||
insert_tags_func = buffer_.insert_with_tags
|
||||
|
@ -1158,7 +1216,6 @@ class ConversationTextview(gobject.GObject):
|
|||
insert_tags_func(end_iter, special_text, *other_tags)
|
||||
|
||||
if tags:
|
||||
end_iter = buffer_.get_end_iter()
|
||||
all_tags = tags[:]
|
||||
if use_other_tags:
|
||||
all_tags += other_tags
|
||||
|
@ -1168,7 +1225,6 @@ class ConversationTextview(gobject.GObject):
|
|||
if 'url' in tags:
|
||||
puny_text = puny_encode(special_text)
|
||||
if not puny_text.endswith('-'):
|
||||
end_iter = buffer_.get_end_iter()
|
||||
buffer_.insert(end_iter, " (%s)" % puny_text)
|
||||
|
||||
def print_empty_line(self):
|
||||
|
@ -1178,9 +1234,9 @@ class ConversationTextview(gobject.GObject):
|
|||
self.just_cleared = False
|
||||
|
||||
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, displaymarking=None):
|
||||
other_tags_for_name=[], other_tags_for_time=[], other_tags_for_text=[],
|
||||
subject=None, old_kind=None, xhtml=None, simple=False, graphics=True,
|
||||
displaymarking=None):
|
||||
"""
|
||||
Print 'chat' type messages
|
||||
"""
|
||||
|
@ -1258,6 +1314,7 @@ class ConversationTextview(gobject.GObject):
|
|||
kind = 'status'
|
||||
other_text_tag = self.detect_other_text_tag(text, kind)
|
||||
text_tags = other_tags_for_text[:] # create a new list
|
||||
mark1 = None
|
||||
if other_text_tag:
|
||||
# note that color of /me may be overwritten in gc_control
|
||||
text_tags.append(other_text_tag)
|
||||
|
@ -1274,11 +1331,21 @@ class ConversationTextview(gobject.GObject):
|
|||
direction_mark=direction_mark)
|
||||
if kind == 'incoming':
|
||||
text_tags.append('incomingtxt')
|
||||
mark1 = buffer_.create_mark(None, buffer_.get_end_iter(),
|
||||
left_gravity=True)
|
||||
elif kind == 'outgoing':
|
||||
text_tags.append('outgoingtxt')
|
||||
mark1 = buffer_.create_mark(None, buffer_.get_end_iter(),
|
||||
left_gravity=True)
|
||||
self.print_subject(subject)
|
||||
self.print_real_text(text, text_tags, name, xhtml, graphics=graphics)
|
||||
|
||||
if mark1:
|
||||
mark2 = buffer_.create_mark(None, buffer_.get_end_iter(),
|
||||
left_gravity=True)
|
||||
if kind == 'incoming':
|
||||
self.last_received_message_marks[name] = [mark1, mark2]
|
||||
elif kind == 'outgoing':
|
||||
self.last_sent_message_marks = [mark1, mark2]
|
||||
# scroll to the end of the textview
|
||||
if at_the_end or kind == 'outgoing':
|
||||
# we are at the end or we are sending something
|
||||
|
@ -1353,16 +1420,19 @@ class ConversationTextview(gobject.GObject):
|
|||
format_ = direction_mark + before_str + name + after_str + ' '
|
||||
buffer_.insert_with_tags_by_name(end_iter, format_, *name_tags)
|
||||
|
||||
def print_subject(self, subject):
|
||||
def print_subject(self, subject, iter_=None):
|
||||
if subject: # if we have subject, show it too!
|
||||
subject = _('Subject: %s\n') % subject
|
||||
buffer_ = self.tv.get_buffer()
|
||||
end_iter = buffer_.get_end_iter()
|
||||
if iter_:
|
||||
end_iter = iter_
|
||||
else:
|
||||
end_iter = buffer_.get_end_iter()
|
||||
buffer_.insert(end_iter, subject)
|
||||
self.print_empty_line()
|
||||
|
||||
def print_real_text(self, text, text_tags=[], name=None, xhtml=None,
|
||||
graphics=True):
|
||||
graphics=True, iter_=None):
|
||||
"""
|
||||
Add normal and special text. call this to add text
|
||||
"""
|
||||
|
@ -1381,4 +1451,5 @@ class ConversationTextview(gobject.GObject):
|
|||
text = '* ' + name + text[3:]
|
||||
text_tags.append('italic')
|
||||
# detect urls formatting and if the user has it on emoticons
|
||||
self.detect_and_print_special_text(text, text_tags, graphics=graphics)
|
||||
return self.detect_and_print_special_text(text, text_tags, graphics=graphics,
|
||||
iter_=iter_)
|
||||
|
|
|
@ -1002,9 +1002,26 @@ class GroupchatControl(ChatControlBase):
|
|||
tim=obj.timestamp, xhtml=None,
|
||||
displaymarking=obj.displaymarking)
|
||||
else:
|
||||
if obj.nick in self.last_received_txt and obj.correct_id and \
|
||||
obj.correct_id == self.last_received_id[obj.nick]:
|
||||
if obj.nick == self.nick:
|
||||
old_txt = self.last_sent_txt
|
||||
self.last_sent_txt = obj.msgtxt
|
||||
self.conv_textview.correct_last_sent_message(obj.msgtxt,
|
||||
obj.xhtml_msgtxt, obj.nick, old_txt)
|
||||
else:
|
||||
old_txt = self.last_received_txt[obj.nick]
|
||||
self.conv_textview.correct_last_received_message(obj.msgtxt,
|
||||
obj.xhtml_msgtxt, obj.nick, old_txt)
|
||||
self.last_received_txt[obj.nick] = obj.msgtxt
|
||||
self.last_received_id[obj.nick] = obj.stanza.getID()
|
||||
return
|
||||
if obj.nick == self.nick:
|
||||
self.last_sent_txt = obj.msgtxt
|
||||
self.print_conversation(obj.msgtxt, contact=obj.nick,
|
||||
tim=obj.timestamp, xhtml=obj.xhtml_msgtxt,
|
||||
displaymarking=obj.displaymarking)
|
||||
displaymarking=obj.displaymarking,
|
||||
correct_id=(obj.stanza.getID(), None))
|
||||
obj.needs_highlight = self.needs_visual_notification(obj.msgtxt)
|
||||
|
||||
def on_private_message(self, nick, msg, tim, xhtml, session, msg_id=None,
|
||||
|
@ -1076,7 +1093,7 @@ class GroupchatControl(ChatControlBase):
|
|||
displaymarking=displaymarking)
|
||||
|
||||
def print_conversation(self, text, contact='', tim=None, xhtml=None,
|
||||
graphics=True, displaymarking=None):
|
||||
graphics=True, displaymarking=None, correct_id=None):
|
||||
"""
|
||||
Print a line in the conversation
|
||||
|
||||
|
@ -1139,7 +1156,8 @@ class GroupchatControl(ChatControlBase):
|
|||
|
||||
ChatControlBase.print_conversation_line(self, text, kind, contact, tim,
|
||||
other_tags_for_name, [], other_tags_for_text, xhtml=xhtml,
|
||||
graphics=graphics, displaymarking=displaymarking)
|
||||
graphics=graphics, displaymarking=displaymarking,
|
||||
correct_id=correct_id)
|
||||
|
||||
def get_nb_unread(self):
|
||||
type_events = ['printed_marked_gc_msg']
|
||||
|
@ -1580,6 +1598,18 @@ class GroupchatControl(ChatControlBase):
|
|||
else:
|
||||
s = _('%(nick)s is now known as %(new_nick)s') % {
|
||||
'nick': obj.nick, 'new_nick': obj.new_nick}
|
||||
tv = self.conv_textview
|
||||
if obj.nick in tv.last_received_message_marks:
|
||||
tv.last_received_message_marks[obj.new_nick] = \
|
||||
tv.last_received_message_marks[obj.nick]
|
||||
del tv.last_received_message_marks[obj.nick]
|
||||
if obj.nick in self.last_received_txt:
|
||||
self.last_received_txt[obj.new_nick] = \
|
||||
self.last_received_txt[obj.nick]
|
||||
del self.last_received_txt[obj.nick]
|
||||
self.last_received_id[obj.new_nick] = \
|
||||
self.last_received_id[obj.nick]
|
||||
del self.last_received_id[obj.nick]
|
||||
# We add new nick to muc roster here, so we don't see
|
||||
# that "new_nick has joined the room" when he just changed
|
||||
# nick.
|
||||
|
@ -1879,9 +1909,23 @@ class GroupchatControl(ChatControlBase):
|
|||
if message != '' or message != '\n':
|
||||
self.save_message(message, 'sent')
|
||||
|
||||
def _cb(msg, msg_txt):
|
||||
# we'll save sent message text when we'll receive it in
|
||||
# _nec_gc_message_received
|
||||
self.last_sent_msg = msg
|
||||
if self.correcting:
|
||||
self.correcting = False
|
||||
self.msg_textview.modify_base(gtk.STATE_NORMAL,
|
||||
self.old_message_tv_color)
|
||||
|
||||
if self.correcting and self.last_sent_msg:
|
||||
correction_msg = self.last_sent_msg
|
||||
else:
|
||||
correction_msg = None
|
||||
# Send the message
|
||||
gajim.connections[self.account].send_gc_message(self.room_jid,
|
||||
message, xhtml=xhtml, label=label)
|
||||
message, xhtml=xhtml, label=label,
|
||||
correction_msg=correction_msg, callback=_cb)
|
||||
self.msg_textview.get_buffer().set_text('')
|
||||
self.msg_textview.grab_focus()
|
||||
|
||||
|
|
|
@ -2704,7 +2704,7 @@ class RosterWindow:
|
|||
obj.session.control.print_conversation(obj.msgtxt, typ,
|
||||
tim=obj.timestamp, encrypted=obj.encrypted, subject=obj.subject,
|
||||
xhtml=obj.xhtml, displaymarking=obj.displaymarking,
|
||||
msg_id=obj.msg_id)
|
||||
msg_id=obj.msg_id, correct_id=(obj.id_, obj.correct_id))
|
||||
if obj.msg_id:
|
||||
pw = obj.session.control.parent_win
|
||||
end = obj.session.control.was_at_the_end
|
||||
|
|
|
@ -99,7 +99,7 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
|
|||
sectext = _('The database file (%s) cannot be read. Try to '
|
||||
'repair it (see http://trac.gajim.org/wiki/DatabaseBackup) '
|
||||
'or remove it (all history will be lost).') % \
|
||||
common.logger.LOG_DB_PATH
|
||||
gajim.logger.LOG_DB_PATH
|
||||
gajim.nec.push_incoming_event(InformationEvent(None,
|
||||
conn=self.conn, level='error', pri_txt=pritext,
|
||||
sec_txt=sectext))
|
||||
|
|
Loading…
Reference in New Issue