Very basic integration of xHtml GUI

This commit is contained in:
Julien Pivotto 2008-11-14 11:13:15 +00:00
parent 0641beb5d4
commit 5a31ba2ef0
6 changed files with 367 additions and 33 deletions

View file

@ -230,6 +230,27 @@
<property name="expand">False</property> <property name="expand">False</property>
</packing> </packing>
</child> </child>
<child>
<widget class="GtkButton" id="formattings_button">
<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="tooltip" translatable="yes">Show a list of formattings</property>
<property name="relief">GTK_RELIEF_NONE</property>
<property name="focus_on_click">False</property>
<property name="response_id">0</property>
<child>
<widget class="GtkImage" id="image10">
<property name="visible">True</property>
<property name="stock">gtk-bold</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child> <child>
<widget class="GtkVSeparator" id="vseparator1"> <widget class="GtkVSeparator" id="vseparator1">
<property name="visible">True</property> <property name="visible">True</property>
@ -237,7 +258,7 @@
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="position">1</property> <property name="position">2</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -261,7 +282,7 @@
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">False</property> <property name="fill">False</property>
<property name="position">2</property> <property name="position">3</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -282,7 +303,7 @@
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="position">3</property> <property name="position">4</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -304,7 +325,7 @@
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="position">4</property> <property name="position">5</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -326,7 +347,7 @@
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="position">5</property> <property name="position">6</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -348,7 +369,7 @@
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="position">6</property> <property name="position">7</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -358,7 +379,7 @@
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="position">7</property> <property name="position">8</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -380,7 +401,7 @@
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="position">8</property> <property name="position">9</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -392,7 +413,7 @@
</child> </child>
</widget> </widget>
<packing> <packing>
<property name="position">9</property> <property name="position">10</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -438,7 +459,7 @@
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="position">10</property> <property name="position">11</property>
</packing> </packing>
</child> </child>
</widget> </widget>
@ -678,6 +699,27 @@
<property name="expand">False</property> <property name="expand">False</property>
</packing> </packing>
</child> </child>
<child>
<widget class="GtkButton" id="formattings_button">
<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="tooltip" translatable="yes">Show a list of formattings</property>
<property name="relief">GTK_RELIEF_NONE</property>
<property name="focus_on_click">False</property>
<property name="response_id">0</property>
<child>
<widget class="GtkImage" id="image11">
<property name="visible">True</property>
<property name="stock">gtk-bold</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child> <child>
<widget class="GtkVSeparator" id="vseparator2"> <widget class="GtkVSeparator" id="vseparator2">
<property name="visible">True</property> <property name="visible">True</property>
@ -685,7 +727,7 @@
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="position">1</property> <property name="position">2</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -707,7 +749,7 @@
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">False</property> <property name="fill">False</property>
<property name="position">2</property> <property name="position">3</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -729,7 +771,7 @@
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">False</property> <property name="fill">False</property>
<property name="position">3</property> <property name="position">4</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -752,7 +794,7 @@
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">False</property> <property name="fill">False</property>
<property name="position">4</property> <property name="position">5</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -774,7 +816,7 @@
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">False</property> <property name="fill">False</property>
<property name="position">5</property> <property name="position">6</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -784,7 +826,7 @@
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="position">6</property> <property name="position">7</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -813,7 +855,7 @@
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">False</property> <property name="fill">False</property>
<property name="position">7</property> <property name="position">8</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -825,7 +867,7 @@
</child> </child>
</widget> </widget>
<packing> <packing>
<property name="position">8</property> <property name="position">9</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -872,7 +914,7 @@
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">False</property> <property name="fill">False</property>
<property name="position">9</property> <property name="position">10</property>
</packing> </packing>
</child> </child>
</widget> </widget>

View file

@ -258,6 +258,10 @@ class ChatControlBase(MessageControl):
id = widget.connect('clicked', self._on_send_button_clicked) id = widget.connect('clicked', self._on_send_button_clicked)
self.handlers[id] = widget self.handlers[id] = widget
widget = self.xml.get_widget('formattings_button')
id = widget.connect('clicked', self.on_formattings_button_clicked)
self.handlers[id] = widget
# the following vars are used to keep history of user's messages # the following vars are used to keep history of user's messages
self.sent_history = [] self.sent_history = []
self.sent_history_pos = 0 self.sent_history_pos = 0
@ -359,9 +363,10 @@ class ChatControlBase(MessageControl):
start_iter = message_buffer.get_start_iter() start_iter = message_buffer.get_start_iter()
end_iter = message_buffer.get_end_iter() end_iter = message_buffer.get_end_iter()
message = message_buffer.get_text(start_iter, end_iter, 0).decode('utf-8') message = message_buffer.get_text(start_iter, end_iter, 0).decode('utf-8')
xhtml = self.msg_textview.get_xhtml()
# send the message # send the message
self.send_message(message) self.send_message(message, xhtml=xhtml)
def _paint_banner(self): def _paint_banner(self):
'''Repaint banner with theme color''' '''Repaint banner with theme color'''
@ -508,6 +513,7 @@ class ChatControlBase(MessageControl):
start_iter, end_iter = message_buffer.get_bounds() start_iter, end_iter = message_buffer.get_bounds()
message = message_buffer.get_text(start_iter, end_iter, False).decode( message = message_buffer.get_text(start_iter, end_iter, False).decode(
'utf-8') 'utf-8')
xhtml = self.msg_textview.get_xhtml()
# construct event instance from binding # construct event instance from binding
event = gtk.gdk.Event(gtk.gdk.KEY_PRESS) # it's always a key-press here event = gtk.gdk.Event(gtk.gdk.KEY_PRESS) # it's always a key-press here
@ -551,7 +557,7 @@ class ChatControlBase(MessageControl):
send_message = False send_message = False
if send_message: if send_message:
self.send_message(message) # send the message self.send_message(message, xhtml=xhtml) # send the message
else: else:
# Give the control itself a chance to process # Give the control itself a chance to process
self.handle_message_textview_mykey_press(widget, event_keyval, self.handle_message_textview_mykey_press(widget, event_keyval,
@ -595,7 +601,7 @@ class ChatControlBase(MessageControl):
def send_message(self, message, keyID = '', type_ = 'chat', chatstate = None, def send_message(self, message, keyID = '', type_ = 'chat', chatstate = None,
msg_id = None, composing_xep = None, resource = None, msg_id = None, composing_xep = None, resource = None,
process_command = True): process_command = True, xhtml = None):
'''Send the given message to the active tab. Doesn't return None if error '''Send the given message to the active tab. Doesn't return None if error
''' '''
if not message or message == '\n': if not message or message == '\n':
@ -607,7 +613,7 @@ class ChatControlBase(MessageControl):
ret = MessageControl.send_message(self, message, keyID, type_ = type_, ret = MessageControl.send_message(self, message, keyID, type_ = type_,
chatstate = chatstate, msg_id = msg_id, chatstate = chatstate, msg_id = msg_id,
composing_xep = composing_xep, resource = resource, composing_xep = composing_xep, resource = resource,
user_nick = self.user_nick) user_nick = self.user_nick, xhtml = xhtml)
# Record message history # Record message history
self.save_sent_message(message) self.save_sent_message(message)
@ -739,6 +745,68 @@ class ChatControlBase(MessageControl):
gajim.interface.emoticon_menuitem_clicked = self.append_emoticon gajim.interface.emoticon_menuitem_clicked = self.append_emoticon
gajim.interface.popup_emoticons_under_button(widget, self.parent_win) gajim.interface.popup_emoticons_under_button(widget, self.parent_win)
def on_formattings_button_clicked(self, widget):
'''popup formattings menu'''
menu = gtk.Menu()
menuitems = ((_('Bold'), 'bold'),
(_('Italic'), 'italic'),
(_('Underline'), 'underline'),
(_('Strike'), 'strike'))
active_tags = self.msg_textview.get_active_tags()
for menuitem in menuitems:
item = gtk.CheckMenuItem(menuitem[0])
if menuitem[1] in active_tags:
item.set_active(True)
else:
item.set_active(False)
item.connect('activate', self.msg_textview.set_tag,
menuitem[1])
menu.append(item)
item = gtk.SeparatorMenuItem() # separator
menu.append(item)
item = gtk.ImageMenuItem(_('Color'))
icon = gtk.image_new_from_stock(gtk.STOCK_SELECT_COLOR, gtk.ICON_SIZE_MENU)
item.set_image(icon)
item.connect('activate', self.on_color_menuitem_activale)
menu.append(item)
item = gtk.ImageMenuItem(_('Font'))
icon = gtk.image_new_from_stock(gtk.STOCK_SELECT_FONT, gtk.ICON_SIZE_MENU)
item.set_image(icon)
item.connect('activate', self.on_font_menuitem_activale)
menu.append(item)
item = gtk.SeparatorMenuItem() # separator
menu.append(item)
item = gtk.ImageMenuItem(_('Clear formating'))
icon = gtk.image_new_from_stock(gtk.STOCK_CLEAR, gtk.ICON_SIZE_MENU)
item.set_image(icon)
item.connect('activate', self.msg_textview.clear_tags)
menu.append(item)
menu.show_all()
gtkgui_helpers.popup_emoticons_under_button(menu, widget,
self.parent_win)
def on_color_menuitem_activale(self, widget):
color_dialog = gtk.ColorSelectionDialog('Select a color')
color_dialog.connect('response', self.msg_textview.color_set,
color_dialog.colorsel)
color_dialog.show_all()
def on_font_menuitem_activale(self, widget):
font_dialog = gtk.FontSelectionDialog('Select a font')
font_dialog.connect('response', self.msg_textview.font_set,
font_dialog.fontsel)
font_dialog.show_all()
def on_actions_button_clicked(self, widget): def on_actions_button_clicked(self, widget):
'''popup action menu''' '''popup action menu'''
menu = self.prepare_context_menu(True) menu = self.prepare_context_menu(True)
@ -1668,7 +1736,8 @@ class ChatControl(ChatControlBase):
else: else:
self.print_conversation(_('No help info for /%s') % command, 'info') self.print_conversation(_('No help info for /%s') % command, 'info')
def send_message(self, message, keyID = '', chatstate = None): def send_message(self, message, keyID = '', chatstate = None,
xhtml = None):
'''Send a message to contact''' '''Send a message to contact'''
if message in ('', None, '\n') or self._process_command(message): if message in ('', None, '\n') or self._process_command(message):
return None return None
@ -1725,7 +1794,7 @@ class ChatControl(ChatControlBase):
id = ChatControlBase.send_message(self, message, keyID, id = ChatControlBase.send_message(self, message, keyID,
type_ = 'chat', chatstate = chatstate_to_send, type_ = 'chat', chatstate = chatstate_to_send,
composing_xep = composing_xep, composing_xep = composing_xep,
process_command = process_command) process_command = process_command, xhtml = xhtml)
if id: if id:
# XXX: Once we have fallback to disco, remove # XXX: Once we have fallback to disco, remove
# notexistant check # notexistant check
@ -1738,7 +1807,8 @@ class ChatControl(ChatControlBase):
xep0184_id = None xep0184_id = None
self.print_conversation(message, self.contact.jid, self.print_conversation(message, self.contact.jid,
encrypted = encrypted, xep0184_id = xep0184_id) encrypted = encrypted, xep0184_id = xep0184_id,
xhtml = xhtml)
def check_for_possible_paused_chatstate(self, arg): def check_for_possible_paused_chatstate(self, arg):
''' did we move mouse of that window or write something in message ''' did we move mouse of that window or write something in message

View file

@ -2453,6 +2453,9 @@ class Interface:
latex = r'|\$\$[^$\\]*?([\]\[0-9A-Za-z()|+*/-]|[\\][\]\[0-9A-Za-z()|{}$])(.*?[^\\])?\$\$' latex = r'|\$\$[^$\\]*?([\]\[0-9A-Za-z()|+*/-]|[\\][\]\[0-9A-Za-z()|{}$])(.*?[^\\])?\$\$'
basic_pattern = links + '|' + mail + '|' + legacy_prefixes basic_pattern = links + '|' + mail + '|' + legacy_prefixes
link_pattern = basic_pattern
self.link_pattern_re = re.compile(link_pattern, re.IGNORECASE)
if gajim.config.get('use_latex'): if gajim.config.get('use_latex'):
basic_pattern += latex basic_pattern += latex

View file

@ -127,7 +127,7 @@ class PrivateChatControl(ChatControl):
ChatControl.__init__(self, parent_win, contact, account, session) ChatControl.__init__(self, parent_win, contact, account, session)
self.TYPE_ID = 'pm' self.TYPE_ID = 'pm'
def send_message(self, message): def send_message(self, message, xhtml=None):
'''call this function to send our message''' '''call this function to send our message'''
if not message: if not message:
return return
@ -153,7 +153,7 @@ class PrivateChatControl(ChatControl):
'left.') % {'room': room, 'nick': nick}) 'left.') % {'room': room, 'nick': nick})
return return
ChatControl.send_message(self, message) ChatControl.send_message(self, message, xhtml=xhtml)
def update_ui(self): def update_ui(self):
if self.contact.show == 'offline': if self.contact.show == 'offline':
@ -1628,7 +1628,7 @@ class GroupchatControl(ChatControlBase):
return False return False
def send_message(self, message): def send_message(self, message, xhtml=None):
'''call this function to send our message''' '''call this function to send our message'''
if not message: if not message:
return return
@ -1644,7 +1644,7 @@ class GroupchatControl(ChatControlBase):
if not self._process_command(message): if not self._process_command(message):
# Send the message # Send the message
gajim.connections[self.account].send_gc_message(self.room_jid, gajim.connections[self.account].send_gc_message(self.room_jid,
message) message, xhtml=xhtml)
self.msg_textview.get_buffer().set_text('') self.msg_textview.get_buffer().set_text('')
self.msg_textview.grab_focus() self.msg_textview.grab_focus()

View file

@ -162,7 +162,7 @@ class MessageControl:
def send_message(self, message, keyID = '', type_ = 'chat', def send_message(self, message, keyID = '', type_ = 'chat',
chatstate = None, msg_id = None, composing_xep = None, resource = None, chatstate = None, msg_id = None, composing_xep = None, resource = None,
user_nick = None): user_nick = None, xhtml = None):
# Send the given message to the active tab. # Send the given message to the active tab.
# Doesn't return None if error # Doesn't return None if error
jid = self.contact.jid jid = self.contact.jid
@ -189,6 +189,6 @@ class MessageControl:
composing_xep = composing_xep, composing_xep = composing_xep,
resource = self.resource, user_nick = user_nick, resource = self.resource, user_nick = user_nick,
session = self.session, session = self.session,
original_message = original_message) original_message = original_message, xhtml = xhtml)
# vim: se ts=3: # vim: se ts=3:

View file

@ -22,6 +22,9 @@
import gtk import gtk
import gobject import gobject
import pango
import gtkgui_helpers
from common import gajim
class MessageTextView(gtk.TextView): class MessageTextView(gtk.TextView):
'''Class for the message textview (where user writes new messages) '''Class for the message textview (where user writes new messages)
@ -35,7 +38,7 @@ class MessageTextView(gtk.TextView):
def __init__(self): def __init__(self):
gtk.TextView.__init__(self) gtk.TextView.__init__(self)
# set properties # set properties
self.set_border_width(1) self.set_border_width(1)
self.set_accepts_tab(True) self.set_accepts_tab(True)
@ -48,6 +51,222 @@ class MessageTextView(gtk.TextView):
self.set_pixels_below_lines(2) self.set_pixels_below_lines(2)
self.lang = None # Lang used for spell checking self.lang = None # Lang used for spell checking
buffer = self.get_buffer()
self.begin_tags = {}
self.end_tags = {}
self.color_tags = []
self.fonts_tags = []
self.other_tags = {}
self.other_tags['bold'] = buffer.create_tag('bold')
self.other_tags['bold'].set_property('weight', pango.WEIGHT_BOLD)
self.begin_tags['bold'] = '<strong>'
self.end_tags['bold'] = '</strong>'
self.other_tags['italic'] = buffer.create_tag('italic')
self.other_tags['italic'].set_property('style', pango.STYLE_ITALIC)
self.begin_tags['italic'] = '<em>'
self.end_tags['italic'] = '</em>'
self.other_tags['underline'] = buffer.create_tag('underline')
self.other_tags['underline'].set_property('underline', pango.UNDERLINE_SINGLE)
self.begin_tags['underline'] = '<span style="text-decoration: underline;">'
self.end_tags['underline'] = '</span>'
self.other_tags['strike'] = buffer.create_tag('strike')
self.other_tags['strike'].set_property('strikethrough', True)
self.begin_tags['strike'] = '<span style="text-decoration: line-through;">'
self.end_tags['strike'] = '</span>'
def make_clickable_urls(self, text):
buffer = self.get_buffer()
start = 0
end = 0
index = 0
new_text = ''
iterator = gajim.interface.link_pattern_re.finditer(text)
for match in iterator:
start, end = match.span()
url = text[start:end]
if start != 0:
text_before_special_text = text[index:start]
else:
text_before_special_text = ''
end_iter = buffer.get_end_iter()
# we insert normal text
new_text += text_before_special_text + \
'<a href="'+ url +'">' + url + '</a>'
index = end # update index
if end < len(text):
new_text += text[end:]
return new_text # the position after *last* special text
def get_active_tags(self):
buffer = self.get_buffer()
return_val = buffer.get_selection_bounds()
if return_val: # if sth was selected
start, finish = return_val[0], return_val[1]
else:
start, finish = buffer.get_bounds()
active_tags = []
for tag in start.get_tags():
active_tags.append(tag.get_property('name'))
return active_tags
def set_tag(self, widget, tag):
buffer = self.get_buffer()
return_val = buffer.get_selection_bounds()
if return_val: # if sth was selected
start, finish = return_val[0], return_val[1]
else:
start, finish = buffer.get_bounds()
if start.has_tag(self.other_tags[tag]):
buffer.remove_tag_by_name(tag, start, finish)
else:
if tag == 'underline':
buffer.remove_tag_by_name('strike', start, finish)
elif tag == 'strike':
buffer.remove_tag_by_name('underline', start, finish)
buffer.apply_tag_by_name(tag, start, finish)
def clear_tags(self, widget):
buffer = self.get_buffer()
return_val = buffer.get_selection_bounds()
if return_val: # if sth was selected
start, finish = return_val[0], return_val[1]
else:
start, finish = buffer.get_bounds()
buffer.remove_all_tags(start, finish)
def color_set(self, widget, response, color):
if response == -6:
widget.destroy()
return
buffer = self.get_buffer()
color = color.get_current_color()
widget.destroy()
color_string = gtkgui_helpers.make_color_string(color)
tag_name = 'color' + color_string
if not tag_name in self.color_tags:
tagColor = buffer.create_tag(tag_name)
tagColor.set_property('foreground', color_string)
self.begin_tags[tag_name] = '<span style="color: ' + color_string + ';">'
self.end_tags[tag_name] = '</span>'
self.color_tags.append(tag_name)
return_val = buffer.get_selection_bounds()
if return_val: # if sth was selected
start, finish = return_val[0], return_val[1]
else:
start, finish = buffer.get_bounds()
for tag in self.color_tags:
buffer.remove_tag_by_name(tag, start, finish)
buffer.apply_tag_by_name(tag_name, start, finish)
def font_set(self, widget, response, font):
if response == -6:
widget.destroy()
return
buffer = self.get_buffer()
font = font.get_font_name()
font_desc = pango.FontDescription(font)
family = font_desc.get_family()
size = font_desc.get_size()
size = size / pango.SCALE
weight = font_desc.get_weight()
style = font_desc.get_style()
widget.destroy()
tag_name = 'font' + font
if not tag_name in self.fonts_tags:
tagFont = buffer.create_tag(tag_name)
tagFont.set_property('font', family + ' ' + str(size))
self.begin_tags[tag_name] = \
'<span style="font-family: ' + family + '; ' + \
'font-size: ' + str(size) + 'px">'
self.end_tags[tag_name] = '</span>'
self.fonts_tags.append(tag_name)
return_val = buffer.get_selection_bounds()
if return_val: # if sth was selected
start, finish = return_val[0], return_val[1]
else:
start, finish = buffer.get_bounds()
for tag in self.fonts_tags:
buffer.remove_tag_by_name(tag, start, finish)
buffer.apply_tag_by_name(tag_name, start, finish)
if weight == pango.WEIGHT_BOLD:
buffer.apply_tag_by_name('bold', start, finish)
else:
buffer.remove_tag_by_name('bold', start, finish)
if style == pango.STYLE_ITALIC:
buffer.apply_tag_by_name('italic', start, finish)
else:
buffer.remove_tag_by_name('italic', start, finish)
def get_xhtml(self):
buffer = self.get_buffer()
old = buffer.get_start_iter()
tags = {}
tags['bold'] = False
iter = buffer.get_start_iter()
old = buffer.get_start_iter()
texte = ''
modified = False
def xhtml_special(text):
text = text.replace('<', '&lt;')
text = text.replace('>', '&gt;')
text = text.replace('\n', '<br />')
return text
for tag in iter.get_toggled_tags(True):
texte += self.begin_tags[tag.get_property('name')]
modified = True
while (iter.forward_to_tag_toggle(None) and not iter.is_end()):
modified = True
texte += xhtml_special(buffer.get_text(old, iter))
old.forward_to_tag_toggle(None)
new_tags = []
old_tags = []
end_tags = []
for tag in iter.get_toggled_tags(True):
new_tags.append(tag.get_property('name'))
for tag in iter.get_tags():
if tag.get_property('name') not in new_tags:
old_tags.append(tag.get_property('name'))
for tag in iter.get_toggled_tags(False):
end_tags.append(tag.get_property('name'))
for tag in old_tags:
texte += self.end_tags[tag]
for tag in end_tags:
texte += self.end_tags[tag]
for tag in new_tags:
texte += self.begin_tags[tag]
for tag in old_tags:
texte += self.begin_tags[tag]
texte += xhtml_special(buffer.get_text(old, buffer.get_end_iter()))
for tag in iter.get_toggled_tags(False):
texte += self.end_tags[tag.get_property('name')]
if modified:
return '<p>' + self.make_clickable_urls(texte) + '</p>'
else:
return None
def destroy(self): def destroy(self):
import gc import gc