as I already mentioned on the IRC meeting, embedding widgets into WebKit is broken and I was told that WebKit-Gtk developers intend to drop this functionality sooner or later. So I decided to go similar way Anjal does, splitting the email display into multiple webviews. To be able to do so, I also decided to change the way EMFormat works as well.

(Unless explicitly stated, by EMFormat I mean EMFormat and all EMFormat-derived classes).

I split the functionality of EMFormat into two parts: parsing and writing. Parsing is done only once when EMFormat object is created. Parsing means, that the email is traversed and each mime part is assigned a write function (EMFormatWriteFunc). The part is then stored as a EMFormatPURI object. The EMFormatPURI object contains ptr to the CamelMimePart part, pointer to a write function and to a widget function (read below), ID of the part and other meta data. The EMFormatPURIs are stored in GList (which represents the order the parts should be display in EMailDisplay, read below) and GHashTable (for fast lookup of parts by their ID). I dropped the code for creating a tree structure representing the mime parts as I think it's not needed. I also created EMailParserInfo struct which is passed between the parser functions and which holds various informations about states of the previous parts (like encrpytion/signature, etc). I think this way is cleaner then having these informations stored as public properties of the EMFormat class.

The parsing is done only for the first time when the email is downloaded from server/storage. The EMFormat object is then stored in SoupSession (explained below), identified by it's URL "mail://#STOREID#/#FOLDERID#/#MAILID#". For now, it's there forever, but the plan is to keep in there all emails that are displayed in at least one view (preview pane or EMailReader) + few (two or three) already closed emails, just in case user decides to re-open any of them.

When an email should be displayed, a new EMailDisplay is created. Originally EMailDisplay was subclass of EWebView. I've changed it to GtkScrolledWindow, so it became a container for all the webviews and other widgets. When EMailDisplay is told to load an email, it retrieves the right EMFormat from SoupSession and iterates through the list of all parts. For each part it creates a new EWebView and loads URI "mail://#STOREID#/#FOLDERID#/#MAILID#?partid=#PARTID#" in it.

I have created a EMailRequest class, which is a subclass of SoupRequest and registered it as a handler for the "mail://" protocol to SoupSession. This way, when WebKit requests the URI for a part, an EMailRequest object is created. The EMailRequests then retrieves proper EMFormat from SoupSession (SoupSession is a global object, the only object accessible in both, Evo and the EMailRequest instances, as the instance is executed by WebKit, out of Evo's reach), finds a part identified by the #PARTID# from URI and calls it's write_func, thus obtaining a HTML representation of the part and returns it to WebKit. This all is running asynchronously and it is the only way how to serve content of resources to WebKit completely asynchronously. Additionally, since each part has it's own EWebView, multiple parts can be requested and processed at the same time, making displaying of the email faster (for example mailing lists digests with many parts, there's no much gain in multipart/alternative).

Alternatively, when a part is represented by a GtkWidget (say ical or vcard), the write_func is NULL, but widget_func is set. Widget_func is similar to write_func, just instead of HTML code, it returns GtkWidget to be displayed. For this parts, EWebView is not created of course.

My plan is to re-implement the API of EWebView in EMailDisplay, so that from the outside EMailDisplay would look like a single EWebView and internally it would act as a proxy, relaying all commands, signals etc to all the webviews and widgets it manages.

At this moment, I am able to display almost all types of emails (though there are still bugs and it does not look nice sometimes), only signed and encrypted emails are not working, application/mbox crashes, multipart/digest displays only some parts and multi-level multiparts are not working very good as well. Also attachments are not displayed in the EAttachmentBar, neither are EAttachmentButtons. Some features are disabled for now and need to be ported to the new EMFormat API. The bright side is, that plugins work very well, so displaying iCal events or VCards as GtkWidgets works!

So as you can see, there's still a long way to go, but I think I'm on the right track to make all the things work. The recent code is already in the webkit branch in git, so you can check it.

I also provided some more explanation in commit messages in git so if something is unclear, try looking there.

I'm leaving now and I should be back on 5th or 6th September. I won't be able to check my email, so please be patient, I'll reply to all your comments as soon as I get back.

 - Dan

Dan Vratil
evolution-hackers mailing list
To change your list options or unsubscribe, visit ...

Reply via email to