Implement serialization/deserialization

This commit is contained in:
Marco Pesenti Gritti 2006-04-22 22:36:39 -04:00
parent 490c146da9
commit 401dca032c

View File

@ -4,6 +4,7 @@ import pygtk
pygtk.require('2.0') pygtk.require('2.0')
import gtk import gtk
import pango import pango
import xml.sax
class RichTextBuffer(gtk.TextBuffer): class RichTextBuffer(gtk.TextBuffer):
def __init__(self): def __init__(self):
@ -33,12 +34,6 @@ class RichTextBuffer(gtk.TextBuffer):
pos_end.backward_chars(length) pos_end.backward_chars(length)
self.apply_tag_by_name(tag, pos, pos_end) self.apply_tag_by_name(tag, pos, pos_end)
def to_xml():
next_iter = buffer.get_start_iter()
while not next_iter.is_end():
class RichTextToolbar(gtk.Toolbar): class RichTextToolbar(gtk.Toolbar):
def __init__(self, buf): def __init__(self, buf):
gtk.Toolbar.__init__(self) gtk.Toolbar.__init__(self)
@ -61,8 +56,99 @@ class RichTextToolbar(gtk.Toolbar):
else: else:
self.buf.unapply_tag(tag_name) self.buf.unapply_tag(tag_name)
class RichTextHandler(xml.sax.handler.ContentHandler):
def __init__(self, buf):
self.buf = buf
self.tags = []
def _deserialize_element(self, el_name):
if el_name == "bold":
return "bold"
elif el_name == "italic":
return "italic"
else:
return None
def startElement(self, name, attributes):
tag = self._deserialize_element(name)
if tag:
self.tags.append(tag)
def characters(self, data):
start_it = it = self.buf.get_end_iter()
mark = self.buf.create_mark(None, start_it, True)
self.buf.insert(it, data)
start_it = self.buf.get_iter_at_mark(mark)
for tag in self.tags:
self.buf.apply_tag_by_name(tag, start_it, it)
def endElement(self, name):
tag = self._deserialize_element(name)
if tag:
self.tags.remove(tag)
class RichTextSerializer:
def __init__(self):
self._open_xml_tags = []
def _get_xml_tag(self, tag):
if tag.get_property("name") == "bold":
return "bold"
elif tag.get_property("name") == "italic":
return "italic"
else:
return "unknown_tag"
def serialize(self, buf):
xml = "<richtext>"
next_it = buf.get_start_iter()
while not next_it.is_end():
it = next_it.copy()
if not next_it.forward_to_tag_toggle(None):
next_it = buf.get_end_iter()
reopen_xml_tags = []
for tag in it.get_toggled_tags(False):
xml_tag = self._get_xml_tag(tag)
while 1:
open_xml_tag = self._open_xml_tags.pop()
if open_xml_tag != xml_tag:
xml += "</" + open_xml_tag + ">"
reopen_xml_tags.append(open_xml_tag)
else:
xml += "</" + xml_tag + ">"
break
for xml_tag in reopen_xml_tags:
self._open_xml_tags.append(xml_tag)
xml += "<" + xml_tag + ">"
for tag in it.get_toggled_tags(True):
xml_tag = self._get_xml_tag(tag)
self._open_xml_tags.append(xml_tag)
xml += "<" + xml_tag + ">"
xml += buf.get_text(it, next_it)
if next_it.is_end():
for xml_tag in self._open_xml_tags:
xml += "</" + xml_tag + ">"
xml += "</richtext>"
return xml
def deserialize(self, xml_string, buf):
parser = xml.sax.make_parser()
handler = RichTextHandler(buf)
parser.setContentHandler(handler)
parser.feed(xml_string)
parser.close()
def test_quit(window, rich_buf): def test_quit(window, rich_buf):
print rich_buf.to_xml() print RichTextSerializer().serialize(rich_buf)
gtk.main_quit() gtk.main_quit()
if __name__ == "__main__": if __name__ == "__main__":
@ -73,6 +159,9 @@ if __name__ == "__main__":
rich_buf = RichTextBuffer() rich_buf = RichTextBuffer()
xml_string = "<richtext><bold><italic>Hello</italic>World</bold></richtext>"
RichTextSerializer().deserialize(xml_string, rich_buf)
view = gtk.TextView(rich_buf) view = gtk.TextView(rich_buf)
vbox.pack_start(view) vbox.pack_start(view)
view.show() view.show()