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 Binary files /dev/null and b/icons/hicolor/32x32/categories/gajim-agent-twitter.png differ diff --git a/src/conversation_textview.py b/src/conversation_textview.py index d3918c19d9e1e44ce22982f17ddeff624d158fb4..6229426e1e6555e0b2d2794350a31560ac3dd66e 100644 --- a/src/conversation_textview.py +++ b/src/conversation_textview.py @@ -477,8 +477,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 = _('<b>Message was corrected. Last message was:</b>\n %s') % \ old_txt @@ -496,7 +496,7 @@ class ConversationTextview(gobject.GObject): 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, + i2 = self.print_conversation_line(message, '', 'incoming', name, None, xhtml=xhtml, iter_=i1) tt_txt = _('<b>Message was corrected. Last message was:</b>\n %s') % \ old_txt @@ -1243,12 +1243,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() @@ -1257,7 +1259,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 @@ -1265,21 +1271,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': @@ -1318,7 +1325,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' @@ -1328,36 +1335,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': @@ -1370,6 +1384,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=''): """ @@ -1407,23 +1422,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') @@ -1453,7 +1475,8 @@ class ConversationTextview(gobject.GObject): try: if name and (text.startswith('/me ') or text.startswith('/me\n')): xhtml = xhtml.replace('/me', '<i>* %s</i>' % (name,), 1) - self.tv.display_html(xhtml.encode('utf-8'), self.tv, self) + self.tv.display_html(xhtml.encode('utf-8'), self.tv, self, + iter_=iter_) return except Exception, e: gajim.log.debug('Error processing xhtml' + str(e)) diff --git a/src/htmltextview.py b/src/htmltextview.py index 5fb028f690d2aa161053b112e772dbefc63d33b6..25ecf1261db4eca6eea24879ae705b56d31d21f5 100644 --- a/src/htmltextview.py +++ b/src/htmltextview.py @@ -656,7 +656,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) @@ -815,8 +815,8 @@ class HtmlTextView(gtk.TextView): self.id_ = self.connect('button-release-event', self.on_left_mouse_button_release) buffer_ = self.get_buffer() - buffer_.create_tag('eol', scale = pango.SCALE_XX_SMALL) - + buffer_.create_tag('eol') + self.tooltip = tooltips.BaseTooltip() self.config = gajim.config self.interface = gajim.interface @@ -1018,9 +1018,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)