diff options
Diffstat (limited to 'em-format/em-format.h')
-rw-r--r-- | em-format/em-format.h | 402 |
1 files changed, 402 insertions, 0 deletions
diff --git a/em-format/em-format.h b/em-format/em-format.h new file mode 100644 index 0000000000..7e59ecf462 --- /dev/null +++ b/em-format/em-format.h @@ -0,0 +1,402 @@ +/* + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Michael Zucchi <notzed@ximian.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +/* + Abstract class for formatting mime messages +*/ + +#ifndef EM_FORMAT_H +#define EM_FORMAT_H + +#include <glib-object.h> +#include <camel/camel-url.h> +#include <camel/camel-folder.h> +#include <camel/camel-stream.h> +#include <camel/camel-session.h> +#include <camel/camel-mime-part.h> +#include <camel/camel-mime-message.h> +#include <camel/camel-cipher-context.h> +#include <libedataserver/e-msgport.h> + +/* Standard GObject macros */ +#define EM_TYPE_FORMAT \ + (em_format_get_type ()) +#define EM_FORMAT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), EM_TYPE_FORMAT, EMFormat)) +#define EM_FORMAT_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), EM_TYPE_FORMAT, EMFormatClass)) +#define EM_IS_FORMAT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), EM_TYPE_FORMAT)) +#define EM_IS_FORMAT_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), EM_TYPE_FORMAT)) +#define EM_FORMAT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), EM_TYPE_FORMAT, EMFormatClass)) + +G_BEGIN_DECLS + +typedef struct _EMFormat EMFormat; +typedef struct _EMFormatClass EMFormatClass; +typedef struct _EMFormatPrivate EMFormatPrivate; + +typedef struct _EMFormatHandler EMFormatHandler; +typedef struct _EMFormatHeader EMFormatHeader; + +typedef void (*EMFormatFunc) (EMFormat *md, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info); + +typedef enum _em_format_mode_t { + EM_FORMAT_NORMAL, + EM_FORMAT_ALLHEADERS, + EM_FORMAT_SOURCE +} em_format_mode_t; + +/** + * struct _EMFormatHandler - MIME type handler. + * + * @mime_type: Type this handler handles. + * @handler: The handler callback. + * @flags: Handling flags, see enum _em_format_handler_t. + * @old: The last handler set on this type. Allows overrides to + * fallback to previous implementation. + * + **/ +struct _EMFormatHandler { + gchar *mime_type; + EMFormatFunc handler; + guint32 flags; + + struct _EMFormatHandler *old; +}; + +/** + * enum _em_format_handler_t - Format handler flags. + * + * @EM_FORMAT_HANDLER_INLINE: This type should be shown expanded + * inline by default. + * @EM_FORMAT_HANDLER_INLINE_DISPOSITION: This type should always be + * shown inline, despite what the Content-Disposition suggests. + * + **/ +enum _em_format_handler_t { + EM_FORMAT_HANDLER_INLINE = 1<<0, + EM_FORMAT_HANDLER_INLINE_DISPOSITION = 1<<1 +}; + +typedef struct _EMFormatPURI EMFormatPURI; +typedef void (*EMFormatPURIFunc)(EMFormat *md, CamelStream *stream, EMFormatPURI *puri); + +/** + * struct _EMFormatPURI - Pending URI object. + * + * @next: Double-linked list header. + * @prev: Double-linked list header. + * @free: May be set by allocator and will be called when no longer needed. + * @format: + * @uri: Calculated URI of the part, if the part has one in its + * Content-Location field. + * @cid: The RFC2046 Content-Id of the part. If none is present, a unique value + * is calculated from @part_id. + * @part_id: A unique identifier for each part. + * @func: Callback for when the URI is requested. The callback writes + * its data to the supplied stream. + * @part: + * @use_count: + * + * This is used for multipart/related, and other formatters which may + * need to include a reference to out-of-band data in the content + * stream. + * + * This object may be subclassed as a struct. + **/ +struct _EMFormatPURI { + struct _EMFormatPURI *next; + struct _EMFormatPURI *prev; + + void (*free)(struct _EMFormatPURI *p); /* optional callback for freeing user-fields */ + struct _EMFormat *format; + + gchar *uri; /* will be the location of the part, may be empty */ + gchar *cid; /* will always be set, a fake one created if needed */ + gchar *part_id; /* will always be set, emf->part_id->str for this part */ + + EMFormatPURIFunc func; + CamelMimePart *part; + + guint use_count; /* used by multipart/related to see if it was accessed */ +}; + +/** + * struct _EMFormatPURITree - Pending URI visibility tree. + * + * @next: Double-linked list header. + * @prev: Double-linked list header. + * @parent: Parent in tree. + * @uri_list: List of EMFormatPURI objects at this level. + * @children: Child nodes of EMFormatPURITree. + * + * This structure is used internally to form a visibility tree of + * parts in the current formatting stream. This is to implement the + * part resolution rules for RFC2387 to implement multipart/related. + **/ +struct _EMFormatPURITree { + struct _EMFormatPURITree *next; + struct _EMFormatPURITree *prev; + struct _EMFormatPURITree *parent; + + EDList uri_list; + EDList children; +}; + +struct _EMFormatHeader { + struct _EMFormatHeader *next, *prev; + + guint32 flags; /* E_FORMAT_HEADER_* */ + gchar name[1]; +}; + +#define EM_FORMAT_HEADER_BOLD (1<<0) +#define EM_FORMAT_HEADER_LAST (1<<4) /* reserve 4 slots */ + +/** + * struct _EMFormat - Mail formatter object. + * + * @parent: + * @priv: + * @message: + * @folder: + * @uid: + * @part_id: + * @header_list: + * @session: + * @base url: + * @snoop_mime_type: + * @valid: + * @valid_parent: + * @inline_table: + * @pending_uri_table: + * @pending_uri_tree: + * @pending_uri_level: + * @mode: + * @charset: + * @default_charset: + * + * Most fields are private or read-only. + * + * This is the base MIME formatter class. It provides no formatting + * itself, but drives most of the basic types, including multipart / * types. + **/ +struct _EMFormat { + GObject parent; + + EMFormatPrivate *priv; + + CamelMimeMessage *message; /* the current message */ + + CamelFolder *folder; + gchar *uid; + + GString *part_id; /* current part id prefix, for identifying parts directly */ + + EDList header_list; /* if empty, then all */ + + CamelSession *session; /* session, used for authentication when required */ + CamelURL *base; /* content-base header or absolute content-location, for any part */ + + const gchar *snoop_mime_type; /* if we snooped an application/octet-stream type, what we snooped */ + + /* for validity enveloping */ + CamelCipherValidity *valid; + CamelCipherValidity *valid_parent; + + /* for forcing inlining */ + GHashTable *inline_table; + + /* global lookup table for message */ + GHashTable *pending_uri_table; + + /* visibility tree, also stores every puri permanently */ + struct _EMFormatPURITree *pending_uri_tree; + /* current level to search from */ + struct _EMFormatPURITree *pending_uri_level; + + em_format_mode_t mode; /* source/headers/etc */ + gchar *charset; /* charset override */ + gchar *default_charset; /* charset fallback */ + gboolean composer; /* Formatting from composer ?*/ + gboolean print; +}; + +struct _EMFormatClass { + GObjectClass parent_class; + + GHashTable *type_handlers; + + /* lookup handler, default falls back to hashtable above */ + const EMFormatHandler *(*find_handler)(EMFormat *, const gchar *mime_type); + + /* start formatting a message */ + void (*format_clone)(EMFormat *, CamelFolder *, const gchar *uid, CamelMimeMessage *, EMFormat *); + + /* some internel error/inconsistency */ + void (*format_error)(EMFormat *, CamelStream *, const gchar *msg); + + /* use for external structured parts */ + void (*format_attachment)(EMFormat *, CamelStream *, CamelMimePart *, const gchar *mime_type, const struct _EMFormatHandler *info); + + /* use for unparsable content */ + void (*format_source)(EMFormat *, CamelStream *, CamelMimePart *); + /* for outputing secure(d) content */ + void (*format_secure)(EMFormat *, CamelStream *, CamelMimePart *, CamelCipherValidity *); + + /* returns true if the formatter is still busy with pending stuff */ + gboolean (*busy)(EMFormat *); + + /* Shows optional way to open messages */ + void (*format_optional)(EMFormat *, CamelStream *, CamelMimePart *, CamelStream* ); + + /* signals */ + /* complete, alternative to polling busy, for asynchronous work */ + void (*complete)(EMFormat *); +}; + +void em_format_set_mode (EMFormat *emf, + em_format_mode_t type); +void em_format_set_charset (EMFormat *emf, + const gchar *charset); +void em_format_set_default_charset (EMFormat *emf, + const gchar *charset); + +/* also indicates to show all headers */ +void em_format_clear_headers (EMFormat *emf); + +void em_format_default_headers (EMFormat *emf); +void em_format_add_header (EMFormat *emf, + const gchar *name, + guint32 flags); + +/* FIXME: Need a 'clone' api to copy details about the current view (inlines etc) + Or maybe it should live with sub-classes? */ + +gint em_format_is_attachment (EMFormat *emf, + CamelMimePart *part); + +gint em_format_is_inline (EMFormat *emf, + const gchar *partid, + CamelMimePart *part, + const EMFormatHandler *handle); +void em_format_set_inline (EMFormat *emf, + const gchar *partid, + gint state); + +gchar * em_format_describe_part (CamelMimePart *part, + const gchar *mime_type); + +/* for implementers */ +GType em_format_get_type (void); + +void em_format_class_add_handler (EMFormatClass *emfc, + EMFormatHandler *info); +void em_format_class_remove_handler (EMFormatClass *emfc, + EMFormatHandler *info); +const EMFormatHandler * + em_format_find_handler (EMFormat *emf, + const gchar *mime_type); +const EMFormatHandler * + em_format_fallback_handler (EMFormat *emf, + const gchar *mime_type); + +/* puri is short for pending uri ... really */ +EMFormatPURI * em_format_add_puri (EMFormat *emf, + gsize size, + const gchar *uri, + CamelMimePart *part, + EMFormatPURIFunc func); +EMFormatPURI * em_format_find_visible_puri (EMFormat *emf, + const gchar *uri); +EMFormatPURI * em_format_find_puri (EMFormat *emf, + const gchar *uri); +void em_format_clear_puri_tree (EMFormat *emf); +void em_format_push_level (EMFormat *emf); +void em_format_pull_level (EMFormat *emf); + +/* clones inline state/view and format, or use to redraw */ +void em_format_format_clone (EMFormat *emf, + CamelFolder *folder, + const gchar *uid, + CamelMimeMessage *message, + EMFormat *source); + +/* formats a new message */ +void em_format_format (EMFormat *emf, + CamelFolder *folder, + const gchar *uid, + CamelMimeMessage *message); +void em_format_redraw (EMFormat *emf); +void em_format_format_attachment (EMFormat *emf, + CamelStream *stream, + CamelMimePart *mime_part, + const gchar *mime_type, + const struct _EMFormatHandler *info); +void em_format_format_error (EMFormat *emf, + CamelStream *stream, + const gchar *format, + ...) G_GNUC_PRINTF (3, 4); +void em_format_format_secure (EMFormat *emf, + CamelStream *stream, + CamelMimePart *mime_part, + CamelCipherValidity *valid); +void em_format_format_source (EMFormat *emf, + CamelStream *stream, + CamelMimePart *mime_part); + +gboolean em_format_busy (EMFormat *emf); + +/* raw content only */ +void em_format_format_content (EMFormat *emf, + CamelStream *stream, + CamelMimePart *part); + +/* raw content text parts - should this just be checked/done by above? */ +void em_format_format_text (EMFormat *emf, + CamelStream *stream, + CamelDataWrapper *part); + +void em_format_part_as (EMFormat *emf, + CamelStream *stream, + CamelMimePart *part, + const gchar *mime_type); +void em_format_part (EMFormat *emf, + CamelStream *stream, + CamelMimePart *part); +void em_format_merge_handler (EMFormat *new, + EMFormat *old); + +const gchar * em_format_snoop_type (CamelMimePart *part); + +G_END_DECLS + +#endif /* EM_FORMAT_H */ |