From 7732b04759f37e8be3ddd6bfa4e8ee8268b7773a Mon Sep 17 00:00:00 2001 From: Yann Leboulanger Date: Sun, 8 Sep 2013 18:18:23 +0200 Subject: [PATCH] render the whole line when we use XEP-309 Last Message Correction. Fixes #7400, #7453 --- .../32x32/categories/gajim-agent-twitter.png | Bin 0 -> 1351 bytes src/conversation_textview.py | 98 +++++++++++------- src/htmltextview.py | 12 ++- 3 files changed, 67 insertions(+), 43 deletions(-) create mode 100644 icons/hicolor/32x32/categories/gajim-agent-twitter.png diff --git a/icons/hicolor/32x32/categories/gajim-agent-twitter.png b/icons/hicolor/32x32/categories/gajim-agent-twitter.png new file mode 100644 index 0000000000000000000000000000000000000000..f7f862c40a56d6fd7f41f877976e61cabb2e3218 GIT binary patch literal 1351 zcmV-N1-SZ&P)1K~z|U#g|=dR7DiW|7Ygz-n;E?TWSHTQqUA5mhb>XOpQwL zBjM4nXh2C!j1L-OFeXC$s11=+9>gfoga;!Kf-l4b9*JpqAb>WenxX+EN`*jC*+S{= z{g|2K!@aw`-Og4UmpI8kle_ocJ-gT?V*Bb>uwhYkD&kIeQ{pr;;%R4r%=yq?*=P*_Zuy^=uu>0icKYg0);WuBt z)(8M$`>+|_uD2gvwcz#M6|U>$a3N$kSr>2gu5jO3yK;Ur@*g!KcwGPh>z`P*By%w| zC@KTrFpA3HLTK>RvL#s%9>1vozS5oTITt0(P>iZ3HDg}RMWA(OqX4W;C;(yrk)=Nv z05RyM0#pJi%L+9B@>vJoz=3N36Eg?|0yD*r6FEYZ9YJHhQhTD%`;_~h3Fi!8>Hu7c z48D8iX)w@206<96LDjUBl+OJ=QEuOJYGmNZ+4GA5Y?(6vGoUObIPYtSYS1`S)j7Fv z1);6bjCa?qb`PI9|Ke-_^;SVO18GHx0t5Jof<&PKLXI_|85aYCd0rOU=mPck*Nrnv z53scfYe#K25`e5Av^j)pp@JatRbQW(GeEr_=yD|%xdMXXGR3e{Gc(|8jZ2e0b`772 z93c)0?_hbgVzNhP#9_h!?7Et6&gmH=Nd>; zXas=WiUoqe7^@qG474`63~o#YtN;WG0&Tz$b^y<1NYl{>0J}jD{6HH348_xRH8OZ| zd3W9w&H!!S+e0(0U{0fs5779yA0p#6&9LJiOA6~2-a>CZa^KyDemHw-WXHa&1JWQS zFcBl3rJ$0O^0HFVK}Gn4w{7~%8p(Dflke}}zV*>H+g5dV$?qp;xB&{1ur%jjVMZWF zweQE9(uC6Z^?C`%ejfGr51lRsOg+4HL-Ai_z_9-M*tyZy9=m5r!RCfV#rS3-0ua}b zEJbJ*g!yg`&#%7M>nt>Nd@%U!#{gcaea_wktrI7PMlZYhg)@)PyxmGDK<|{}kZV-_qnqDwl1_*$o-+Sq+;on9F2L^|Nhw=gs zwr0@N{)8C7PCDh9`jToW#fqlSTmYE_E-jIylo9XLx<(2>0AMmv2|&oq)f18pfRZnkNze@9+Es#5YEEas zq(CY#20)aOj*~ML)c)sms#7b!urec=3HCjJQ>t92!N4^E{|3sJ$#ERcIP3rb002ov JPDHLkV1oGQSBC%q literal 0 HcmV?d00001 diff --git a/src/conversation_textview.py b/src/conversation_textview.py index 9d4bdee1f..7088d748d 100644 --- a/src/conversation_textview.py +++ b/src/conversation_textview.py @@ -482,8 +482,8 @@ class ConversationTextview(GObject.GObject): buffer_.delete(i1, i2) tag = 'outgoingtxt' if message.startswith('/me'): - tag = 'outgoing' - i2 = self.print_real_text(message, text_tags=[tag], name=name, + tag = 'outgoing' + i2 = self.print_conversation_line(message, '', 'outgoing', name, None, xhtml=xhtml, iter_=i1) tt_txt = _('Message was corrected. Last message was:\n %s') % \ old_txt @@ -501,7 +501,7 @@ class ConversationTextview(GObject.GObject): i2 = buffer_.get_iter_at_mark(m2) txt = buffer_.get_text(i1, i2, True) buffer_.delete(i1, i2) - i2 = self.print_real_text(message, text_tags=['incomingtxt'], name=name, + i2 = self.print_conversation_line(message, '', 'incoming', name, None, xhtml=xhtml, iter_=i1) tt_txt = _('Message was corrected. Last message was:\n %s') % \ old_txt @@ -1260,12 +1260,14 @@ 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, - displaymarking=None): + displaymarking=None, iter_=None): """ Print 'chat' type messages """ buffer_ = self.tv.get_buffer() buffer_.begin_user_action() + if iter_: + temp_mark = buffer_.create_mark(None, iter_, left_gravity=True) if self.marks_queue.full(): # remove oldest line m1 = self.marks_queue.get() @@ -1274,7 +1276,11 @@ class ConversationTextview(GObject.GObject): i2 = buffer_.get_iter_at_mark(m2) buffer_.delete(i1, i2) buffer_.delete_mark(m1) - end_iter = buffer_.get_end_iter() + if iter_: + end_iter = buffer_.get_iter_at_mark(temp_mark) + buffer_.delete_mark(temp_mark) + else: + end_iter = buffer_.get_end_iter() end_offset = end_iter.get_offset() at_the_end = self.at_the_end() move_selection = False @@ -1282,21 +1288,22 @@ class ConversationTextview(GObject.GObject): get_offset() == end_offset: move_selection = True - # Create one mark and add it to queue once if it's the first line - # else twice (one for end bound, one for start bound) - mark = None - if buffer_.get_char_count() > 0: - if not simple: - buffer_.insert_with_tags_by_name(end_iter, '\n', 'eol') - if move_selection: - sel_start, sel_end = buffer_.get_selection_bounds() - sel_end.backward_char() - buffer_.select_range(sel_start, sel_end) - mark = buffer_.create_mark(None, end_iter, left_gravity=True) + if not iter_: + # Create one mark and add it to queue once if it's the first line + # else twice (one for end bound, one for start bound) + mark = None + if buffer_.get_char_count() > 0: + if not simple and not iter_: + buffer_.insert_with_tags_by_name(end_iter, '\n', 'eol') + if move_selection: + sel_start, sel_end = buffer_.get_selection_bounds() + sel_end.backward_char() + buffer_.select_range(sel_start, sel_end) + mark = buffer_.create_mark(None, end_iter, left_gravity=True) + self.marks_queue.put(mark) + if not mark: + mark = buffer_.create_mark(None, end_iter, left_gravity=True) self.marks_queue.put(mark) - if not mark: - mark = buffer_.create_mark(None, end_iter, left_gravity=True) - self.marks_queue.put(mark) if kind == 'incoming_queue': kind = 'incoming' if old_kind == 'incoming_queue': @@ -1338,7 +1345,7 @@ class ConversationTextview(GObject.GObject): 'time_sometimes') # If there's a displaymarking, print it here. if displaymarking: - self.print_displaymarking(displaymarking) + self.print_displaymarking(displaymarking, iter_=end_iter) # kind = info, we print things as if it was a status: same color, ... if kind in ('error', 'info'): kind = 'status' @@ -1348,36 +1355,43 @@ class ConversationTextview(GObject.GObject): if other_text_tag: # note that color of /me may be overwritten in gc_control text_tags.append(other_text_tag) - if text.startswith('/me'): - mark1 = buffer_.create_mark(None, buffer_.get_end_iter(), - left_gravity=True) + if text.startswith('/me') and not iter_: + mark1 = mark else: # not status nor /me if gajim.config.get('chat_merge_consecutive_nickname'): if kind != old_kind or self.just_cleared: self.print_name(name, kind, other_tags_for_name, - direction_mark=direction_mark) + direction_mark=direction_mark, iter_=end_iter) else: self.print_real_text(gajim.config.get( - 'chat_merge_consecutive_nickname_indent')) + 'chat_merge_consecutive_nickname_indent'), + iter_=end_iter) else: self.print_name(name, kind, other_tags_for_name, - direction_mark=direction_mark) + direction_mark=direction_mark, iter_=end_iter) if kind == 'incoming': text_tags.append('incomingtxt') - mark1 = buffer_.create_mark(None, buffer_.get_end_iter(), - left_gravity=True) + if not iter_: + mark1 = mark 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: + if not iter_: + mark1 = mark + self.print_subject(subject, iter_=end_iter) + self.print_real_text(text, text_tags, name, xhtml, graphics=graphics, + iter_=end_iter) + if not iter_ and mark1: mark2 = buffer_.create_mark(None, buffer_.get_end_iter(), left_gravity=True) if kind == 'incoming': + if name in self.last_received_message_marks: + m = self.last_received_message_marks[name][1] + buffer_.delete_mark(m) self.last_received_message_marks[name] = [mark1, mark2] elif kind == 'outgoing': + m = self.last_sent_message_marks[1] + if m: + buffer_.delete_mark(m) self.last_sent_message_marks = [mark1, mark2] # scroll to the end of the textview if at_the_end or kind == 'outgoing': @@ -1390,6 +1404,7 @@ class ConversationTextview(GObject.GObject): self.just_cleared = False buffer_.end_user_action() + return end_iter def get_time_to_show(self, tim, direction_mark=''): """ @@ -1423,23 +1438,30 @@ class ConversationTextview(GObject.GObject): elif text.startswith('/me ') or text.startswith('/me\n'): return kind - def print_displaymarking(self, displaymarking): + def print_displaymarking(self, displaymarking, iter_=None): 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() + if iter_: + end_iter = iter_ + else: + 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, direction_mark=''): + def print_name(self, name, kind, other_tags_for_name, direction_mark='', + iter_=None): if name: buffer_ = self.tv.get_buffer() - end_iter = buffer_.get_end_iter() + if iter_: + end_iter = iter_ + else: + end_iter = buffer_.get_end_iter() name_tags = other_tags_for_name[:] # create a new list name_tags.append(kind) before_str = gajim.config.get('before_nickname') @@ -1469,7 +1491,7 @@ class ConversationTextview(GObject.GObject): try: if name and (text.startswith('/me ') or text.startswith('/me\n')): xhtml = xhtml.replace('/me', '* %s' % (name,), 1) - self.tv.display_html(xhtml, self.tv, self) + self.tv.display_html(xhtml, self.tv, self, iter_=iter_) return except Exception as e: gajim.log.debug('Error processing xhtml: ' + str(e)) diff --git a/src/htmltextview.py b/src/htmltextview.py index dc236aa10..3318d2442 100644 --- a/src/htmltextview.py +++ b/src/htmltextview.py @@ -690,7 +690,7 @@ class HtmlHandler(xml.sax.handler.ContentHandler): def handle_specials(self, text): if self.conv_textview: self.iter = self.conv_textview.detect_and_print_special_text(text, - self._get_style_tags()) + self._get_style_tags(), iter_=self.iter) else: self._insert_text(text) @@ -853,8 +853,7 @@ class HtmlTextView(Gtk.TextView): self.connect('copy-clipboard', self.on_html_text_view_copy_clipboard) self.id_ = self.connect('button-release-event', self.on_left_mouse_button_release) - #Pango.SCALE_XX_SMALL) - self.get_buffer().create_tag('eol', scale=0.5787037037037) + self.get_buffer().create_tag('eol') self.tooltip = tooltips.BaseTooltip() self.config = gajim.config self.interface = gajim.interface @@ -1059,9 +1058,12 @@ class HtmlTextView(Gtk.TextView): # self.hyperlink_handler can be overwritten, so call it when needed self.hyperlink_handler(texttag, widget, event, iter_, kind) - def display_html(self, html, textview, conv_textview): + def display_html(self, html, textview, conv_textview, iter_=None): buffer_ = self.get_buffer() - eob = buffer_.get_end_iter() + if iter_: + eob = iter_ + else: + eob = buffer_.get_end_iter() ## this works too if libxml2 is not available # parser = xml.sax.make_parser(['drv_libxml2']) # parser.setFeature(xml.sax.handler.feature_validation, True)