diff --git a/src/conversation_textview.py b/src/conversation_textview.py index 68bb8633b..ff74f606b 100644 --- a/src/conversation_textview.py +++ b/src/conversation_textview.py @@ -954,6 +954,13 @@ class ConversationTextview(gobject.GObject): print_conversation_line()''' buffer_ = self.tv.get_buffer() + + insert_tags_func = buffer_.insert_with_tags_by_name + # detect_and_print_special_text() is also used by + # HtmlHandler.handle_specials() and there tags is gtk.TextTag objects, + # not strings + if len(other_tags) > 0 and isinstance(other_tags[0], gtk.TextTag): + insert_tags_func = buffer_.insert_with_tags index = 0 @@ -974,8 +981,7 @@ class ConversationTextview(gobject.GObject): text_before_special_text = otext[index:start] end_iter = buffer_.get_end_iter() # we insert normal text - buffer_.insert_with_tags_by_name(end_iter, - text_before_special_text, *other_tags) + insert_tags_func(end_iter, text_before_special_text, *other_tags) index = end # update index # now print it @@ -984,7 +990,11 @@ class ConversationTextview(gobject.GObject): if specials_limit <= 0: break - return index # the position after *last* special text + # 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() def print_special_text(self, special_text, other_tags): '''is called by detect_and_print_special_text and prints @@ -1280,22 +1290,17 @@ 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.encode('utf-8')) + self.tv.display_html(xhtml.encode('utf-8'), self) return except Exception, e: gajim.log.debug(str('Error processing xhtml') + str(e)) gajim.log.debug(str('with |' + xhtml + '|')) - buffer_ = self.tv.get_buffer() # /me is replaced by name if name is given if name and (text.startswith('/me ') or text.startswith('/me\n')): text = '* ' + name + text[3:] text_tags.append('italic') # detect urls formatting and if the user has it on emoticons - index = self.detect_and_print_special_text(text, text_tags) - - # add the rest of text located in the index and after - end_iter = buffer_.get_end_iter() - buffer_.insert_with_tags_by_name(end_iter, text[index:], *text_tags) + self.detect_and_print_special_text(text, text_tags) # vim: se ts=3: diff --git a/src/htmltextview.py b/src/htmltextview.py index 9045d22c5..45ab4817f 100644 --- a/src/htmltextview.py +++ b/src/htmltextview.py @@ -50,6 +50,8 @@ import operator if __name__ == '__main__': from common import i18n + import common.configpaths + common.configpaths.gajimpaths.init(None) from common import gajim import tooltips @@ -184,25 +186,6 @@ for name in BLOCK_HEAD: ('font-weight: bold', 'font-style: oblique')[weigth], ) - -def build_patterns(view, config, interface): - # extra, rst does not mark _underline_ or /it/ up - # actually , or are not in the JEP-0071, but are seen in the wild - basic_pattern = r'(? gtk.gdk.Color''' if color.startswith('rgb(') and color.endswith(')'): @@ -222,11 +205,12 @@ class HtmlHandler(xml.sax.handler.ContentHandler): It keeps a stack of "style spans" (start/end element pairs) and a stack of list counters, for nested lists. """ - def __init__(self, textview, startiter): + def __init__(self, conv_textview, startiter): xml.sax.handler.ContentHandler.__init__(self) - self.textbuf = textview.get_buffer() - self.textview = textview + self.textbuf = conv_textview.tv.get_buffer() + self.textview = conv_textview.tv self.iter = startiter + self.conv_textview = conv_textview self.text = '' self.starting=True self.preserve = False @@ -672,51 +656,7 @@ class HtmlHandler(xml.sax.handler.ContentHandler): return False def handle_specials(self, text): - index = 0 - se = self.textview.config.get('show_ascii_formatting_chars') - af = gajim.config.get('ascii_formatting') - if self.textview.config.get('emoticons_theme'): - if af: - iterator = self.textview.emot_and_basic_re.finditer(text) - else: - iterator = self.textview.emot_pattern_re.finditer(text) - elif af: - iterator = self.textview.basic_pattern_re.finditer(text) - else: - iterator = [] - for match in iterator: - start, end = match.span() - special_text = text[start:end] - if start != 0: - self._insert_text(text[index:start]) - index = end # update index - #emoticons - possible_emot_ascii_caps = special_text.upper() # emoticons keys are CAPS - if self.textview.config.get('emoticons_theme') and \ - possible_emot_ascii_caps in self.textview.interface.emoticons.keys(): - #it's an emoticon - emot_ascii = possible_emot_ascii_caps - anchor = self.textbuf.create_child_anchor(self.iter) - img = gtk.Image() - img.set_from_file(self.textview.interface.emoticons[emot_ascii]) - img.show() - # TODO: add alt/tooltip with the special_text (a11y) - self.textview.add_child_at_anchor(img, anchor) - elif af: - # now print it - if special_text.startswith('/'): # it's explicit italics - self.startElement('i', {}) - elif special_text.startswith('_'): # it's explicit underline - self.startElement('u', {}) - if se: self._insert_text(special_text[0]) - self.handle_specials(special_text[1:-1]) - if se: self._insert_text(special_text[0]) - if special_text.startswith('_'): # it's explicit underline - self.endElement('u') - if special_text.startswith('/'): # it's explicit italics - self.endElement('i') - if index < len(text): - self._insert_text(text[index:]) + self.iter = self.conv_textview.detect_and_print_special_text(text, self._get_style_tags()) def characters(self, content): if self.preserve: @@ -870,7 +810,6 @@ class HtmlTextView(gtk.TextView): self.config = gajim.config self.interface = gajim.interface # end big hack - build_patterns(self,gajim.config,gajim.interface) def __destroy_event(self, widget): if self.tooltip.timeout != 0: @@ -921,14 +860,14 @@ class HtmlTextView(gtk.TextView): self._changed_cursor = False return False - def display_html(self, html): + def display_html(self, html, conv_textview): buffer_ = self.get_buffer() 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) parser = xml.sax.make_parser() - parser.setContentHandler(HtmlHandler(self, eob)) + parser.setContentHandler(HtmlHandler(conv_textview, eob)) parser.parse(StringIO(html)) # too much space after :) @@ -942,6 +881,9 @@ change_cursor = None if __name__ == '__main__': import os + from conversation_textview import ConversationTextview + import gajim as gaj + class log(object): def debug(self, text): @@ -953,33 +895,32 @@ if __name__ == '__main__': gajim.log=log() - if gajim.config.get('emoticons_theme'): - print "emoticons" + gaj.Interface() - htmlview = HtmlTextView() + htmlview = ConversationTextview(None) path_to_file = os.path.join(gajim.DATA_DIR, 'pixmaps', 'muc_separator.png') # use this for hr - htmlview.focus_out_line_pixbuf = gtk.gdk.pixbuf_new_from_file(path_to_file) + htmlview.tv.focus_out_line_pixbuf = gtk.gdk.pixbuf_new_from_file(path_to_file) tooltip = tooltips.BaseTooltip() def on_textview_motion_notify_event(widget, event): '''change the cursor to a hand when we are over a mail or an url''' global change_cursor - pointer_x, pointer_y = htmlview.window.get_pointer()[0:2] - x, y = htmlview.window_to_buffer_coords(gtk.TEXT_WINDOW_TEXT, pointer_x, + pointer_x, pointer_y = htmlview.tv.window.get_pointer()[0:2] + x, y = htmlview.tv.window_to_buffer_coords(gtk.TEXT_WINDOW_TEXT, pointer_x, pointer_y) - tags = htmlview.get_iter_at_location(x, y).get_tags() + tags = htmlview.tv.get_iter_at_location(x, y).get_tags() if change_cursor: - htmlview.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor( + htmlview.tv.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor( gtk.gdk.Cursor(gtk.gdk.XTERM)) change_cursor = None - tag_table = htmlview.get_buffer().get_tag_table() + tag_table = htmlview.tv.get_buffer().get_tag_table() for tag in tags: try: if tag.is_anchor: - htmlview.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor( + htmlview.tv.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor( gtk.gdk.Cursor(gtk.gdk.HAND2)) change_cursor = tag elif tag == tag_table.lookup('focus-out-line'): @@ -994,32 +935,38 @@ if __name__ == '__main__': #if over_line and not line_tooltip.win: # line_tooltip.timeout = gobject.timeout_add(500, # show_line_tooltip) - # htmlview.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor( + # htmlview.tv.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor( # gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)) # change_cursor = tag - htmlview.connect('motion_notify_event', on_textview_motion_notify_event) + htmlview.tv.connect('motion_notify_event', on_textview_motion_notify_event) def handler(texttag, widget, event, iter_, kind, href): if event.type == gtk.gdk.BUTTON_PRESS: print href - htmlview.html_hyperlink_handler = handler + htmlview.tv.html_hyperlink_handler = handler - htmlview.display_html('
Hello
\n' + htmlview.print_real_text(None, xhtml='
Hello
\n' '
\n' ' World\n' '
\n') - htmlview.display_html('
') - htmlview.display_html(''' + htmlview.print_real_text(None, xhtml='
') + htmlview.print_real_text(None, xhtml='''

OMG, I'm green with envy!

''') - htmlview.display_html('
') - htmlview.display_html(''' + htmlview.print_real_text(None, xhtml='
') + htmlview.print_real_text(None, xhtml=''' + + http://test.com/ testing links autolinkifying + + ''') + htmlview.print_real_text(None, xhtml='
') + htmlview.print_real_text(None, xhtml='''

As Emerson said in his essay Self-Reliance:

@@ -1027,8 +974,8 @@ if __name__ == '__main__':

''') - htmlview.display_html('
') - htmlview.display_html(''' + htmlview.print_real_text(None, xhtml='
') + htmlview.print_real_text(None, xhtml='''

Hey, are you licensed to Jabber?

''') - htmlview.display_html('
') - htmlview.display_html(''' + htmlview.print_real_text(None, xhtml='
') + htmlview.print_real_text(None, xhtml='''
  • One
  • @@ -1052,8 +999,8 @@ if __name__ == '__main__': return faciter(n,1) ''') - htmlview.display_html('
    ') - htmlview.display_html(''' + htmlview.print_real_text(None, xhtml='
    ') + htmlview.print_real_text(None, xhtml='''
    1. One
    2. @@ -1066,12 +1013,12 @@ if __name__ == '__main__':
    3. Three
    ''') - htmlview.show() + htmlview.tv.show() sw = gtk.ScrolledWindow() sw.set_property('hscrollbar-policy', gtk.POLICY_AUTOMATIC) sw.set_property('vscrollbar-policy', gtk.POLICY_AUTOMATIC) sw.set_property('border-width', 0) - sw.add(htmlview) + sw.add(htmlview.tv) sw.show() frame = gtk.Frame() frame.set_shadow_type(gtk.SHADOW_IN)