Hi all,
I am sorry if I should not be cross posting this, but I have been told
by Robin Dunn in the past with richtextctrl questions, that the expert
on this area is to be found on the wxwidgets list, but this is a
wxpython question.
I have a richtextctrl object, and I am inserting images into the
document. When it comes to exporting the xml I would like to set the
flags to control how the images are handled, but I am finding that the
flags are ignored, and that the image data is being encoded to base 16
ascii, and embedded into the xml. This leads to enormous files. I
really do not want the data embedded in any encoding, but would like
to grab the images directly, and send the binary data to the receiving
end of the message.
At the moment I am working on parsing the xml, grabbing the data tag
from all images, converting it back to a binary string, and sending it
as a separate entity, while adding an attribute to the image tag with
the name of the binary object. At the other end, I am taking the
binary data, and reinserting it into the xml, before it gets imported,
and importing the xml. The import process can be quite slow even if the
image being imported is relatively small (350k on the filesystem),
because it gets expanded to somewhere around 3.8 Megs! I have done
some testing and the size difference seems to average out to about 10
times the binary size of the image.
It occurs to me that I am missing something here, and that there must
be a better way of handling this process. Could someone enlighten me?
wxPython/Widgets: '2.8.9.1 (gtk2-unicode)'
python: 2.5.2
Platform: Linux version 2.6.24-19-generic (buildd@terranova)
(gcc version 4.2.3 (Ubuntu 4.2.3-2ubuntu7))
#1 SMP Wed Aug 20 22:56:21 UTC 2008
Thanks in advance for any help with this. I have a workaround as
described above, but it is not really a solution.
Rohan
And here is a code example with what I use to make the xml export:
#!/usr/bin/env python
# -*- indent-tabs-mode:nil -*-
import wx
import wx.richtext as rt
import os.path as p
import cStringIO
class RichFrame(wx.Frame):
def __init__(self,parent,id,title='',text=None,):
wx.Frame.__init__(self,parent,id,title,size=(800,600))
self.rtc = rt.RichTextCtrl(self, -1)
self.statusbar = self.CreateStatusBar()
self.toolbar = self.CreateToolBar()
# create a some text and embed an very small image
self.rtc.BeginFontSize(14)
self.rtc.WriteText("Welcome to wxRichTextCtrl, a wxWidgets control for editing and presenting styled text and images")
self.rtc.EndFontSize()
self.rtc.Newline()
self.rtc.BeginFontSize(10)
self.rtc.WriteText("The image that is on the next line will be embedded in the xml output")
self.rtc.Newline()
path = p.join(p.dirname(__file__), "bomb.png")
img = wx.Bitmap(path, wx.BITMAP_TYPE_PNG)
self.rtc.WriteBitmap(img)
self.rtc.Newline()
self.rtc.WriteText("When this is encoded, with either of rt.RICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY, or rt.RICHTEXT_HANDLER_SAVE_IMAGES_TO_FILES set, it has no effect, and you end up with the image data embedded in the xml as shown below")
self.rtc.Newline()
# xml export the image, it is b16 inline, encoded
xmloutput = self.ExportXML()
# dialog = wx.MessageDialog(self, xmloutput.getvalue(),
# style=wx.DIALOG_MODAL | wx.OK ^ wx.CANCEL,)
# dialog.ShowModal()
# dialog.Destroy()
# print out at the prompt in case this is handier
print xmloutput.getvalue()
# dump the output form the export into the rtc window
self.rtc.WriteText(xmloutput.getvalue())
def ExportXML(self):
""" Grabs the content of the richtext buffer, and returns a
StringIO object that contains the contents, in a recreatable
XML form for the editor"""
handler = rt.RichTextXMLHandler()
#### WHERE THE PROBLEM IS
# These flags are completely ignored,
# and the xml always embeds the images as b16 encoded ascii
# strings
# handler.SetFlags(rt.RICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY)
handler.SetFlags(rt.RICHTEXT_HANDLER_SAVE_IMAGES_TO_FILES)
···
####
stream = cStringIO.StringIO()
if not handler.SaveStream(self.rtc.GetBuffer(), stream):
return
# process any images, extract them into their own binary stringIO object
# insert the reference, munge the output so it will import properly
u = unicode(stream.getvalue(), 'ascii')
return cStringIO.StringIO(u.encode('utf8'))
class RichApp(wx.App):
def __init__(self, redirect=False, filename=None,
style=wx.DEFAULT_FRAME_STYLE, text=None):
self.text = text
wx.App.__init__(self, redirect, filename)
def OnInit(self):
self.frame = RichFrame(parent=None, id=-1, title="Rich Editor",
text=self.text)
self.frame.Show()
self.SetTopWindow(self.frame)
return True
if __name__ == '__main__':
text = "This is a test"
app = RichApp(text=text)
app.MainLoop()