[evolution/webkit: 51/196] Introduce a new write_func for headers in printout
- From: Dan VrÃtil <dvratil src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/webkit: 51/196] Introduce a new write_func for headers in printout
- Date: Tue, 27 Mar 2012 16:05:01 +0000 (UTC)
commit 8351e4a8fe2a3f2ff0af3d05b2ae107bab5d80dd
Author: Dan VrÃtil <dvratil redhat com>
Date: Tue Nov 22 12:13:09 2011 +0100
Introduce a new write_func for headers in printout
- big subject on the first line
- special header "Security" with informations about GPG/SMIME encrpytion/signature
- special header "Attachments" displaying count of attachments
- renders all headers user selected in the Printing dialog
TODO: We need to reload the page before actually printing it to regenerate the headers
according to what user has changed in the Printing dialog
data/webview.css | 17 +++
mail/e-mail-printer.c | 20 ++-
mail/em-format-html-print.c | 283 ++++++++++++++++++++++++++++---------------
mail/em-format-html.c | 45 ++++---
mail/em-format-html.h | 8 ++
5 files changed, 252 insertions(+), 121 deletions(-)
---
diff --git a/data/webview.css b/data/webview.css
index 25a6c53..33ab4ac 100644
--- a/data/webview.css
+++ b/data/webview.css
@@ -54,3 +54,20 @@ img.navigable {
width: 100%;
height: 100%;
}
+
+.printing-header {
+ margin-bottom: 20px;
+}
+
+.printing-header th {
+ text-align: right;
+ font-weight: bold;
+}
+
+.printing-header td {
+ text-align: left;
+}
+
+.printing-header h1 {
+ font-size: 20px;
+}
diff --git a/mail/e-mail-printer.c b/mail/e-mail-printer.c
index 59cee0d..4613b70 100644
--- a/mail/e-mail-printer.c
+++ b/mail/e-mail-printer.c
@@ -136,7 +136,7 @@ emp_run_print_operation (EMailPrinter *emp,
EMFormat *emf;
SoupSession *session;
GHashTable *formatters;
- WebKitWebFrame *frame;
+ WebKitWebFrame *frame;
gchar *mail_uri, *tmp;
emf = EM_FORMAT (emp->priv->efhp);
@@ -159,9 +159,15 @@ emp_run_print_operation (EMailPrinter *emp,
webkit_web_view_load_uri (emp->priv->webview, tmp);
frame = webkit_web_view_get_main_frame (emp->priv->webview);
- webkit_web_frame_print_full (frame, operation, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, NULL);
-
- g_free (tmp);
+
+ if (em_format_html_print_get_action (emp->priv->efhp) == GTK_PRINT_OPERATION_ACTION_EXPORT) {
+ gtk_print_operation_set_export_filename (operation, emp->priv->efhp->export_filename);
+ webkit_web_frame_print_full (frame, operation, GTK_PRINT_OPERATION_ACTION_EXPORT, NULL);
+ } else {
+ webkit_web_frame_print_full (frame, operation, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, NULL);
+ }
+
+ g_free (tmp);
g_free (mail_uri);
}
@@ -359,7 +365,7 @@ emp_finalize (GObject *object)
if (priv->headers) {
GtkTreeIter iter;
-
+
gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->headers), &iter);
while (gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->headers), &iter)) {
EMFormatHeader *header = NULL;
@@ -424,7 +430,7 @@ e_mail_printer_init (EMailPrinter *emp)
emp->priv->webview = NULL;
}
-EMailPrinter*
+EMailPrinter*
e_mail_printer_new (EMFormatHTML* source,
GtkPrintOperationAction action)
{
@@ -445,7 +451,7 @@ void
e_mail_printer_print (EMailPrinter *emp,
GCancellable *cancellable)
{
- GtkPrintOperation *operation;
+ GtkPrintOperation *operation;
g_return_if_fail (E_IS_MAIL_PRINTER (emp));
diff --git a/mail/em-format-html-print.c b/mail/em-format-html-print.c
index f8e3f4e..ccc3c63 100644
--- a/mail/em-format-html-print.c
+++ b/mail/em-format-html-print.c
@@ -49,11 +49,6 @@ struct _EMFormatHTMLPrintPrivate {
};
-G_DEFINE_TYPE (
- EMFormatHTMLPrint,
- em_format_html_print,
- EM_TYPE_FORMAT_HTML);
-
enum {
PROP_0,
PROP_ORIGINAL_FORMATTER,
@@ -61,57 +56,133 @@ enum {
};
static void efhp_write_print_layout (EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
+static void efhp_write_headers (EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
static void
-attachment_bar_html (EMFormatPURI *puri,
- GString *buffer,
- GCancellable *cancellable)
+efhp_write_headers (EMFormat *emf,
+ EMFormatPURI *puri,
+ CamelStream *stream,
+ EMFormatWriterInfo *info,
+ GCancellable *cancellable)
{
- EAttachmentStore *store;
- EMailAttachmentBar *bar;
- GList *attachments, *iter;
- GtkIconTheme *icon_theme;
-
- bar = E_MAIL_ATTACHMENT_BAR (
- puri->widget_func (puri->emf, puri, cancellable));
- store = e_mail_attachment_bar_get_store (bar);
-
- g_string_append_printf (buffer,
- "<fieldset class=\"attachments\"><legend>%s</legend>",
- _("Attachments"));
-
- icon_theme = gtk_icon_theme_get_default ();
- attachments = e_attachment_store_get_attachments (store);
- for (iter = attachments; iter != NULL; iter = iter->next) {
- EAttachment *attachment = iter->data;
- GFileInfo *finfo = e_attachment_get_file_info (attachment);
- GIcon *icon;
- GtkIconInfo *icon_info;
-
- icon = g_file_info_get_icon (finfo);
- if (icon) {
- icon_info = gtk_icon_theme_lookup_by_gicon (icon_theme,
- icon, 48, 0);
- }
-
- if (!icon || !icon_info) {
- icon_info = gtk_icon_theme_lookup_icon (icon_theme,
- "gtk-file", 48, 0);
+ struct _camel_header_raw raw_header;
+ GString *str, *tmp;
+ gchar *subject;
+ const gchar *buf;
+ EMFormatPURI *p;
+ GList *iter;
+ gint attachments_count;
+
+ buf = camel_medium_get_header (CAMEL_MEDIUM (puri->part), "subject");
+ subject = camel_header_decode_string (buf, "UTF-8");
+ str = g_string_new ("<table border=\"0\" width=\"100%\" " \
+ "cellspacing=\"5\" cellpadding=\"0\" class=\"printing-header\">\n");
+ g_string_append_printf (str, "<tr><td colspan=\"2\"><h1>%s</h1></td></tr>\n",
+ subject);
+ g_free (subject);
+
+ for (iter = g_queue_peek_head_link (&emf->header_list);
+ iter->next != NULL; iter = iter->next) {
+
+ EMFormatHeader *header = iter->data;
+ raw_header.name = header->name;
+
+ /* Skip 'Subject' header, it's already displayed. */
+ if (g_ascii_strncasecmp (header->name, "Subject", 7) == 0)
+ continue;
+
+ if (header->value && *header->value) {
+ raw_header.value = header->value;
+ em_format_html_format_header (emf, str,
+ CAMEL_MEDIUM (puri->part), &raw_header,
+ header->flags | EM_FORMAT_HTML_HEADER_NOLINKS,
+ "UTF-8");
+ } else {
+ raw_header.value = g_strdup (camel_medium_get_header (
+ CAMEL_MEDIUM (emf->message), header->name));
+
+ if (raw_header.value && *raw_header.value) {
+ em_format_html_format_header (emf, str,
+ CAMEL_MEDIUM (puri->part), &raw_header,
+ header->flags | EM_FORMAT_HTML_HEADER_NOLINKS,
+ "UTF-8");
+ }
+
+ if (raw_header.value)
+ g_free (raw_header.value);
}
+ }
+
+ /* Add encryption/signature header */
+ raw_header.name = _("Security");
+ tmp = g_string_new ("");
+ /* Find first secured part. */
+ for (iter = g_list_find (emf->mail_part_list, puri)->next; iter->next != NULL; iter = iter->next) {
+
+ p = iter->data;
+
+ /* Let that particular headers handle the encryption */
+ if (g_str_has_suffix (p->uri, ".headers"))
+ break;
- g_string_append_printf (buffer,
- "<div class=\"attachment\" >" \
- "<img src=\"evo-file://%s\" width=\"64\" height=\"64\" />"
- "<br>%s</div>",
- gtk_icon_info_get_filename (icon_info),
- g_file_info_get_display_name (finfo));
+ if (p->validity_type == 0)
+ continue;
+
+
+ if ((p->validity_type & EM_FORMAT_VALIDITY_FOUND_PGP) &&
+ (p->validity_type & EM_FORMAT_VALIDITY_FOUND_SIGNED)) {
+ g_string_append (tmp, _("GPG signed"));
+ }
+ if ((p->validity_type & EM_FORMAT_VALIDITY_FOUND_PGP) &&
+ (p->validity_type & EM_FORMAT_VALIDITY_FOUND_ENCRYPTED)) {
+ if (tmp->len > 0) g_string_append (tmp, ", ");
+ g_string_append (tmp, _("GPG encrpyted"));
+ }
+ if ((p->validity_type & EM_FORMAT_VALIDITY_FOUND_SMIME) &&
+ (p->validity_type & EM_FORMAT_VALIDITY_FOUND_SIGNED)) {
+
+ if (tmp->len > 0) g_string_append (tmp, ", ");
+ g_string_append (tmp, _("S/MIME signed"));
+ }
+ if ((p->validity_type & EM_FORMAT_VALIDITY_FOUND_SMIME) &&
+ (p->validity_type & EM_FORMAT_VALIDITY_FOUND_ENCRYPTED)) {
+
+ if (tmp->len > 0) g_string_append (tmp, ", ");
+ g_string_append (tmp, _("S/MIME encrpyted"));
+ }
+
+ break;
}
- g_string_append (buffer, "<div style=\"clear: both; width: 100%\"></div></fieldset>");
+ if (tmp->len > 0) {
+ raw_header.value = tmp->str;
+ em_format_html_format_header (emf, str, CAMEL_MEDIUM (p->part),
+ &raw_header, EM_FORMAT_HEADER_BOLD | EM_FORMAT_HTML_HEADER_NOLINKS, "UTF-8");
+ }
+ g_string_free (tmp, TRUE);
- g_list_free (attachments);
-}
+ /* Count attachments and display the number as a header */
+ attachments_count = 0;
+ for (iter = emf->mail_part_list; iter->next != NULL; iter = iter->next) {
+ p = iter->data;
+
+ if (p->is_attachment || g_str_has_suffix(p->uri, ".attachment"))
+ attachments_count++;
+ }
+ if (attachments_count > 0) {
+ raw_header.name = _("Attachments");
+ raw_header.value = g_strdup_printf ("%d", attachments_count);
+ em_format_html_format_header (emf, str, CAMEL_MEDIUM (puri->part),
+ &raw_header, EM_FORMAT_HEADER_BOLD | EM_FORMAT_HTML_HEADER_NOLINKS, "UTF-8");
+ g_free (raw_header.value);
+ }
+
+ g_string_append (str, "</table>");
+
+ camel_stream_write_string (stream, str->str, cancellable, NULL);
+ g_string_free (str, TRUE);
+}
static void
efhp_write_print_layout (EMFormat *emf,
@@ -137,19 +208,18 @@ efhp_write_print_layout (EMFormat *emf,
EMFormatPURI *puri = iter->data;
- /* Convert attachment bar to fancy HTML */
- /* FIXME WEBKIT
- if (g_str_has_suffix (puri->uri, ".attachment-bar")) {
- attachment_bar_html (puri, str, cancellable);
- continue;
- }
- */
-
/* Skip widget-parts. We either don't want them displayed
* or we will handle them manually */
if (puri->write_func == NULL ||
- g_str_has_prefix (puri->uri, "print_layout"))
+ g_str_has_suffix (puri->uri, "print_layout"))
+ continue;
+
+ /* To late to change .headers writer_func, do it manually. */
+ if (g_str_has_suffix (puri->uri, ".headers")) {
+ efhp_write_headers (emf, puri, stream, info, cancellable);
continue;
+ }
+
if (puri->is_attachment || g_str_has_suffix (puri->uri, ".attachment")) {
const EMFormatHandler *handler;
@@ -249,8 +319,25 @@ efhp_set_orig_formatter (EMFormatHTMLPrint *efhp,
sizeof (EMFormatPURI), NULL, "print_layout");
puri->write_func = efhp_write_print_layout;
puri->mime_type = g_strdup ("text/html");
- em_format_add_puri (EM_FORMAT (efhp), puri);
- efhp->priv->top_level_puri = puri;
+ em_format_add_puri (EM_FORMAT (efhp), puri);
+ efhp->priv->top_level_puri = puri;
+}
+
+static EMFormatHandler type_builtin_table[] = {
+ //{ (gchar *) "x-evolution/message/headers", 0, efhp_write_headers, },
+};
+
+static void
+efhp_builtin_init (EMFormatHTMLPrintClass *efhc)
+{
+ EMFormatClass *emfc;
+ gint ii;
+
+ emfc = (EMFormatClass *) efhc;
+
+ for (ii = 0; ii < G_N_ELEMENTS (type_builtin_table); ii++)
+ em_format_class_add_handler (
+ emfc, &type_builtin_table[ii]);
}
static void
@@ -308,20 +395,26 @@ efhp_get_property (GObject *object,
}
static void
-em_format_html_print_class_init (EMFormatHTMLPrintClass *class)
+em_format_html_print_base_init (EMFormatHTMLPrintClass *klass)
+{
+ efhp_builtin_init (klass);
+}
+
+static void
+em_format_html_print_class_init (EMFormatHTMLPrintClass *klass)
{
GObjectClass *object_class;
EMFormatClass *format_class;
- parent_class = g_type_class_peek_parent (class);
- g_type_class_add_private (class, sizeof (EMFormatHTMLPrintPrivate));
+ parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (EMFormatHTMLPrintPrivate));
- object_class = G_OBJECT_CLASS (class);
+ object_class = G_OBJECT_CLASS (klass);
object_class->finalize = efhp_finalize;
object_class->set_property = efhp_set_property;
object_class->get_property = efhp_get_property;
- format_class = EM_FORMAT_CLASS (class);
+ format_class = EM_FORMAT_CLASS (klass);
format_class->is_inline = efhp_is_inline;
g_object_class_install_property (
@@ -359,13 +452,40 @@ em_format_html_print_init (EMFormatHTMLPrint *efhp)
efhp->async = TRUE;
}
+GType
+em_format_html_print_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMFormatHTMLPrintClass),
+ (GBaseInitFunc) em_format_html_print_base_init,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) em_format_html_print_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMFormatHTMLPrint),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) em_format_html_print_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ em_format_html_get_type(), "EMFormatHTMLPrint",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
EMFormatHTMLPrint *
em_format_html_print_new (EMFormatHTML *source,
GtkPrintOperationAction action)
{
EMFormatHTMLPrint *efhp;
- efhp = g_object_new (EM_TYPE_FORMAT_HTML_PRINT,
+ efhp = g_object_new (EM_TYPE_FORMAT_HTML_PRINT,
"original-formatter", source,
"print-action", action,
NULL);
@@ -373,32 +493,6 @@ em_format_html_print_new (EMFormatHTML *source,
return efhp;
}
-static void
-emfhp_complete (EMFormatHTMLPrint *efhp)
-{
-/* FIXME WEBKIT
- GtkPrintOperation *operation;
- EWebView *web_view;
- GError *error = NULL;
-
- operation = e_print_operation_new ();
-// FIXME WEBKIT: Port to webkit's API, probably from outside
- if (efhp->action == GTK_PRINT_OPERATION_ACTION_EXPORT)
- gtk_print_operation_set_export_filename (operation, efhp->export_filename);
-
- gtk_html_print_operation_run (
- GTK_HTML (web_view),
- operation, efhp->action, NULL,
- (GtkHTMLPrintCalcHeight) NULL,
- (GtkHTMLPrintCalcHeight) efhp_calc_footer_height,
- (GtkHTMLPrintDrawFunc) NULL,
- (GtkHTMLPrintDrawFunc) efhp_draw_footer,
- NULL, &error);
-
- g_object_unref (operation);
-*/
-}
-
void
em_format_html_print_message (EMFormatHTMLPrint *efhp,
CamelMimeMessage *message,
@@ -414,9 +508,6 @@ em_format_html_print_message (EMFormatHTMLPrint *efhp,
EM_FORMAT_HTML_HEADER_CC |
EM_FORMAT_HTML_HEADER_BCC;
- g_signal_connect (
- efhp, "complete", G_CALLBACK (emfhp_complete), efhp);
-
/* FIXME Not passing a GCancellable here. */
em_format_parse ((EMFormat *) efhp, message, folder, NULL);
}
@@ -424,8 +515,8 @@ em_format_html_print_message (EMFormatHTMLPrint *efhp,
GtkPrintOperationAction
em_format_html_print_get_action (EMFormatHTMLPrint *efhp)
{
- g_return_val_if_fail (EM_IS_FORMAT_HTML_PRINT (efhp),
+ g_return_val_if_fail (EM_IS_FORMAT_HTML_PRINT (efhp),
GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
-
+
return efhp->priv->print_action;
-}
\ No newline at end of file
+}
diff --git a/mail/em-format-html.c b/mail/em-format-html.c
index e79e60a..1da3ee5 100644
--- a/mail/em-format-html.c
+++ b/mail/em-format-html.c
@@ -1849,7 +1849,8 @@ static gchar *
efh_format_address (EMFormatHTML *efh,
GString *out,
struct _camel_header_address *a,
- gchar *field)
+ gchar *field,
+ gboolean no_links)
{
guint32 flags = CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES;
gchar *name, *mailto, *addr;
@@ -1888,7 +1889,10 @@ efh_format_address (EMFormatHTML *efh,
mailto = camel_url_encode (a->v.addr, "?=&()");
}
addr = camel_text_to_html (a->v.addr, flags, 0);
- g_string_append_printf (out, "<a href=\"mailto:%s\">%s</a>", mailto, addr);
+ if (no_links)
+ g_string_append_printf (out, "%s", addr);
+ else
+ g_string_append_printf (out, "<a href=\"mailto:%s\">%s</a>", mailto, addr);
g_free (mailto);
g_free (addr);
@@ -1897,7 +1901,7 @@ efh_format_address (EMFormatHTML *efh,
break;
case CAMEL_HEADER_ADDRESS_GROUP:
g_string_append_printf (out, "%s: ", name);
- efh_format_address (efh, out, a->v.members, field);
+ efh_format_address (efh, out, a->v.members, field, no_links);
g_string_append_printf (out, ";");
break;
default:
@@ -1977,13 +1981,13 @@ canon_header_name (gchar *name)
}
}
-static void
-efh_format_header (EMFormat *emf,
- GString *buffer,
- CamelMedium *part,
- struct _camel_header_raw *header,
- guint32 flags,
- const gchar *charset)
+void
+em_format_html_format_header (EMFormat *emf,
+ GString *buffer,
+ CamelMedium *part,
+ struct _camel_header_raw *header,
+ guint32 flags,
+ const gchar *charset)
{
EMFormatHTML *efh = EM_FORMAT_HTML (emf);
gchar *name, *buf, *value = NULL;
@@ -2021,7 +2025,8 @@ efh_format_header (EMFormat *emf,
g_free (buf);
html = g_string_new("");
- img = efh_format_address (efh, html, addrs, (gchar *) label);
+ img = efh_format_address (efh, html, addrs, (gchar *) label,
+ (flags & EM_FORMAT_HTML_HEADER_NOLINKS));
if (img) {
str_field = g_strdup_printf ("%s%s:", img, label);
@@ -2107,7 +2112,11 @@ efh_format_header (EMFormat *emf,
html = g_string_new("");
scan = ng;
while (scan) {
- g_string_append_printf(html, "<a href=\"news:%s\">%s</a>", scan->newsgroup, scan->newsgroup);
+ if (flags & EM_FORMAT_HTML_HEADER_NOLINKS)
+ g_string_append_printf (html, "%s", scan->newsgroup);
+ else
+ g_string_append_printf(html, "<a href=\"news:%s\">%s</a>",
+ scan->newsgroup, scan->newsgroup);
scan = scan->next;
if (scan)
g_string_append_printf(html, ", ");
@@ -2175,7 +2184,7 @@ efh_format_short_headers (EMFormatHTML *efh,
continue;
}
tmp = g_string_new ("");
- efh_format_address (efh, tmp, addrs, header->name);
+ efh_format_address (efh, tmp, addrs, header->name, FALSE);
if (tmp->len)
g_string_printf (from, _("From: %s"), tmp->str);
@@ -2254,7 +2263,7 @@ efh_format_full_headers (EMFormatHTML *efh,
break;
html = g_string_new("");
- name = efh_format_address (efh, html, addrs, header->name);
+ name = efh_format_address (efh, html, addrs, header->name, FALSE);
header_sender = html->str;
camel_header_address_list_clear (&addrs);
@@ -2269,7 +2278,7 @@ efh_format_full_headers (EMFormatHTML *efh,
break;
html = g_string_new("");
- name = efh_format_address (efh, html, addrs, header->name);
+ name = efh_format_address (efh, html, addrs, header->name, FALSE);
header_from = html->str;
camel_header_address_list_clear (&addrs);
@@ -2321,7 +2330,7 @@ efh_format_full_headers (EMFormatHTML *efh,
if (all_headers) {
header = ((CamelMimePart *) part)->headers;
while (header) {
- efh_format_header (
+ em_format_html_format_header (
emf, buffer, part, header,
EM_FORMAT_HTML_HEADER_NOCOLUMNS, charset);
header = header->next;
@@ -2370,7 +2379,7 @@ efh_format_full_headers (EMFormatHTML *efh,
xmailer.value = use_header->value;
mailer_shown = TRUE;
- efh_format_header (
+ em_format_html_format_header (
emf, buffer, part,
&xmailer, h->flags, charset);
if (strstr(use_header->value, "Evolution"))
@@ -2391,7 +2400,7 @@ efh_format_full_headers (EMFormatHTML *efh,
face_decoded = TRUE;
/* Showing an encoded "Face" header makes little sense */
} else if (!g_ascii_strcasecmp (header->name, h->name) && !face) {
- efh_format_header (
+ em_format_html_format_header (
emf, buffer, part,
header, h->flags, charset);
}
diff --git a/mail/em-format-html.h b/mail/em-format-html.h
index 1024382..56b67ec 100644
--- a/mail/em-format-html.h
+++ b/mail/em-format-html.h
@@ -79,6 +79,7 @@ typedef enum {
/* header already in html format */
#define EM_FORMAT_HTML_HEADER_HTML (EM_FORMAT_HEADER_LAST<<1)
#define EM_FORMAT_HTML_HEADER_NODEC (EM_FORMAT_HEADER_LAST<<2)
+#define EM_FORMAT_HTML_HEADER_NOLINKS (EM_FORMAT_HEADER_LAST<<3)
#define EM_FORMAT_HTML_HEADER_LAST (EM_FORMAT_HEADER_LAST<<8)
@@ -202,6 +203,13 @@ void em_format_html_format_headers (EMFormatHTML *efh,
CamelMedium *part,
gboolean all_headers,
GCancellable *cancellable);
+void em_format_html_format_header (EMFormat *emf,
+ GString *buffer,
+ CamelMedium *part,
+ struct _camel_header_raw *header,
+ guint32 flags,
+ const gchar *charset);
+
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]