aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Vrátil <dvratil@redhat.com>2012-07-25 17:29:22 +0800
committerDan Vrátil <dvratil@redhat.com>2012-07-25 17:29:22 +0800
commit8663b54cae296883452850f3baad6d4cbc92e220 (patch)
treef895a43b817e0115a57bc639b2b6a9e40caa1193
parentb456ff5423b9f4ffe5719e460e4b769bed28c934 (diff)
downloadgsoc2013-evolution-8663b54cae296883452850f3baad6d4cbc92e220.tar
gsoc2013-evolution-8663b54cae296883452850f3baad6d4cbc92e220.tar.gz
gsoc2013-evolution-8663b54cae296883452850f3baad6d4cbc92e220.tar.bz2
gsoc2013-evolution-8663b54cae296883452850f3baad6d4cbc92e220.tar.lz
gsoc2013-evolution-8663b54cae296883452850f3baad6d4cbc92e220.tar.xz
gsoc2013-evolution-8663b54cae296883452850f3baad6d4cbc92e220.tar.zst
gsoc2013-evolution-8663b54cae296883452850f3baad6d4cbc92e220.zip
Highlighting of text parts and source codes
This adds 'Format as' submenu to the preview pane context menu. The submenu is available only for text/plain parts or parts with a source code (we support about 40 various types). Using the 'highlight' utility, the formatter processes the part and highlights the source code it contains. (discussion in bug #680026)
-rw-r--r--em-format/e-mail-formatter.h2
-rw-r--r--em-format/e-mail-parser-text-plain.c3
-rw-r--r--mail/e-mail-display.c6
-rw-r--r--mail/e-mail-request.c24
-rw-r--r--modules/text-highlight/Makefile.am16
-rw-r--r--modules/text-highlight/e-mail-display-popup-text-highlight.c370
-rw-r--r--modules/text-highlight/e-mail-display-popup-text-highlight.h30
-rw-r--r--modules/text-highlight/e-mail-formatter-text-highlight.c (renamed from modules/text-highlight/text-highlight.c)127
-rw-r--r--modules/text-highlight/e-mail-formatter-text-highlight.h (renamed from modules/text-highlight/text-highlight.h)0
-rw-r--r--modules/text-highlight/e-mail-parser-text-highlight.c159
-rw-r--r--modules/text-highlight/e-mail-parser-text-highlight.h30
-rw-r--r--modules/text-highlight/evolution-module-text-highlight.c7
-rw-r--r--modules/text-highlight/languages.c529
-rw-r--r--modules/text-highlight/languages.h39
14 files changed, 1298 insertions, 44 deletions
diff --git a/em-format/e-mail-formatter.h b/em-format/e-mail-formatter.h
index c0c21c13b0..9b4e84d262 100644
--- a/em-format/e-mail-formatter.h
+++ b/em-format/e-mail-formatter.h
@@ -96,6 +96,8 @@ struct _EMailFormatterContext {
EMailFormatterMode mode;
guint32 flags;
+
+ gchar *uri;
};
struct _EMailFormatter {
diff --git a/em-format/e-mail-parser-text-plain.c b/em-format/e-mail-parser-text-plain.c
index 00a7b53b18..1795d019a9 100644
--- a/em-format/e-mail-parser-text-plain.c
+++ b/em-format/e-mail-parser-text-plain.c
@@ -98,8 +98,7 @@ process_part (EMailParser *parser,
}
type = camel_mime_part_get_content_type (part);
- if (camel_content_type_is (type, "text", "*") &&
- (!camel_content_type_is (type, "text", "calendar"))) {
+ if (!camel_content_type_is (type, "text", "calendar")) {
g_string_append_printf (part_id, ".plain_text.%d", part_number);
diff --git a/mail/e-mail-display.c b/mail/e-mail-display.c
index be99ea226c..6cbbaa6091 100644
--- a/mail/e-mail-display.c
+++ b/mail/e-mail-display.c
@@ -177,6 +177,12 @@ mail_display_button_press_event (GtkWidget *widget,
GList *extensions, *iter;
EWebView *web_view = E_WEB_VIEW (widget);
+ if (event->button != 3) {
+ return GTK_WIDGET_CLASS (
+ e_mail_display_parent_class)->button_press_event (
+ widget, event);
+ }
+
hit_test = webkit_web_view_get_hit_test_result (
WEBKIT_WEB_VIEW (web_view), event);
diff --git a/mail/e-mail-request.c b/mail/e-mail-request.c
index 0f185c2031..aee9c9cc91 100644
--- a/mail/e-mail-request.c
+++ b/mail/e-mail-request.c
@@ -54,6 +54,7 @@ struct _EMailRequestPrivate {
GHashTable *uri_query;
gchar *uri_base;
+ gchar *full_uri;
gchar *ret_mime_type;
};
@@ -105,6 +106,7 @@ handle_mail_request (GSimpleAsyncResult *res,
context.message_uid = part_list->message_uid;
context.folder = part_list->folder;
context.parts = part_list->list;
+ context.uri = request->priv->full_uri;
if (context.mode == E_MAIL_FORMATTER_MODE_PRINTING)
formatter = e_mail_formatter_print_new ();
@@ -285,25 +287,22 @@ mail_request_finalize (GObject *object)
g_clear_object (&request->priv->output_stream);
- if (request->priv->mime_type) {
- g_free (request->priv->mime_type);
- request->priv->mime_type = NULL;
- }
+ g_free (request->priv->mime_type);
+ request->priv->mime_type = NULL;
if (request->priv->uri_query) {
g_hash_table_destroy (request->priv->uri_query);
request->priv->uri_query = NULL;
}
- if (request->priv->ret_mime_type) {
- g_free (request->priv->ret_mime_type);
- request->priv->ret_mime_type = NULL;
- }
+ g_free (request->priv->ret_mime_type);
+ request->priv->ret_mime_type = NULL;
- if (request->priv->uri_base) {
- g_free (request->priv->uri_base);
- request->priv->uri_base = NULL;
- }
+ g_free (request->priv->uri_base);
+ request->priv->uri_base = NULL;
+
+ g_free (request->priv->full_uri);
+ request->priv->full_uri = NULL;
G_OBJECT_CLASS (e_mail_request_parent_class)->finalize (object);
}
@@ -337,6 +336,7 @@ mail_request_send_async (SoupRequest *request,
emr->priv->uri_query = NULL;
}
+ emr->priv->full_uri = soup_uri_to_string (uri, FALSE);
uri_str = g_strdup_printf (
"%s://%s%s", uri->scheme, uri->host, uri->path);
emr->priv->uri_base = uri_str;
diff --git a/modules/text-highlight/Makefile.am b/modules/text-highlight/Makefile.am
index 9b27298474..8c7e639622 100644
--- a/modules/text-highlight/Makefile.am
+++ b/modules/text-highlight/Makefile.am
@@ -9,10 +9,16 @@ module_text_highlight_la_CPPFLAGS = \
$(EVOLUTION_DATA_SERVER_CFLAGS) \
$(GNOME_PLATFORM_CFLAGS)
-module_text_highlight_la_SOURCES = \
- text-highlight.c \
- text-highlight.h \
- evolution-module-text-highlight.c
+module_text_highlight_la_SOURCES = \
+ e-mail-display-popup-text-highlight.c \
+ e-mail-display-popup-text-highlight.h \
+ e-mail-formatter-text-highlight.c \
+ e-mail-formatter-text-highlight.h \
+ e-mail-parser-text-highlight.c \
+ e-mail-parser-text-highlight.h \
+ evolution-module-text-highlight.c \
+ languages.c \
+ languages.h
module_text_highlight_la_LIBADD = \
$(top_builddir)/e-util/libeutil.la \
@@ -21,7 +27,7 @@ module_text_highlight_la_LIBADD = \
$(EVOLUTION_DATA_SERVER_LIBS) \
$(GNOME_PLATFORM_LIBS)
-module_text_highlight_la_LDFLAGS = \
+module_text_highlight_la_LDFLAGS = \
-avoid-version -module $(NO_UNDEFINED)
-include $(top_srcdir)/git.mk
diff --git a/modules/text-highlight/e-mail-display-popup-text-highlight.c b/modules/text-highlight/e-mail-display-popup-text-highlight.c
new file mode 100644
index 0000000000..0adea1dac7
--- /dev/null
+++ b/modules/text-highlight/e-mail-display-popup-text-highlight.c
@@ -0,0 +1,370 @@
+/*
+ * 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/>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "e-mail-display-popup-text-highlight.h"
+#include "mail/e-mail-display-popup-extension.h"
+#include "mail/e-mail-display.h"
+#include <shell/e-shell.h>
+#include <shell/e-shell-window.h>
+#include "mail/e-mail-browser.h"
+
+#include <libebackend/libebackend.h>
+
+#include <glib/gi18n-lib.h>
+
+#include "languages.h"
+
+#define d(x)
+
+typedef struct _EMailDisplayPopupTextHighlight {
+ EExtension parent;
+
+ GtkActionGroup *action_group;
+
+ WebKitDOMDocument *document;
+} EMailDisplayPopupTextHighlight;
+
+typedef struct _EMailDisplayPopupTextHighlightClass {
+ EExtensionClass parent_class;
+} EMailDisplayPopupTextHighlightClass;
+
+#define E_MAIL_DISPLAY_POPUP_TEXT_HIGHLIGHT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), e_mail_display_popup_text_highlight_get_type(), EMailDisplayPopupTextHighlight))
+
+GType e_mail_display_popup_text_highlight_get_type (void);
+static void e_mail_display_popup_extension_interface_init (EMailDisplayPopupExtensionInterface *iface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (
+ EMailDisplayPopupTextHighlight,
+ e_mail_display_popup_text_highlight,
+ E_TYPE_EXTENSION,
+ 0,
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_DISPLAY_POPUP_EXTENSION,
+ e_mail_display_popup_extension_interface_init));
+
+static const gchar *ui =
+"<ui>"
+" <popup name='context'>"
+" <placeholder name='custom-actions-2'>"
+" <separator />"
+" <menu action='format-as-menu'>"
+" <placeholder name='format-as-actions' />"
+" <menu action='format-as-other-menu'>"
+" </menu>"
+" </menu>"
+" </placeholder>"
+" </popup>"
+"</ui>";
+
+static const gchar *ui_reader =
+"<ui>"
+" <popup name='mail-preview-popup'>"
+" <placeholder name='mail-preview-popup-actions'>"
+" <separator />"
+" <menu action='format-as-menu'>"
+" <placeholder name='format-as-actions' />"
+" <menu action='format-as-other-menu'>"
+" </menu>"
+" </menu>"
+" </placeholder>"
+" </popup>"
+"</ui>";
+
+static GtkActionEntry entries[] = {
+
+ { "format-as-menu",
+ NULL,
+ N_("_Format as..."),
+ NULL,
+ NULL,
+ NULL
+ },
+
+ { "format-as-other-menu",
+ NULL,
+ N_("_Other languages"),
+ NULL,
+ NULL,
+ NULL
+ }
+};
+
+static void
+reformat (GtkAction *old,
+ GtkAction *action,
+ gpointer user_data)
+{
+ EMailDisplayPopupTextHighlight *th_extension;
+ WebKitDOMDocument *doc;
+ WebKitDOMDOMWindow *window;
+ WebKitDOMElement *frame_element;
+ SoupURI *soup_uri;
+ GHashTable *query;
+ gchar *uri;
+
+
+ th_extension = E_MAIL_DISPLAY_POPUP_TEXT_HIGHLIGHT (user_data);
+ doc = th_extension->document;
+ if (!doc)
+ return;
+
+ uri = webkit_dom_document_get_document_uri (doc);
+ soup_uri = soup_uri_new (uri);
+ g_free (uri);
+
+ if (!soup_uri)
+ return;
+
+ if (!soup_uri->query) {
+ soup_uri_free (soup_uri);
+ return;
+ }
+
+ query = soup_form_decode (soup_uri->query);
+ g_hash_table_replace (
+ query, g_strdup ("__formatas"), (gpointer) gtk_action_get_name (action));
+
+ soup_uri_set_query_from_form (soup_uri, query);
+ g_hash_table_destroy (query);
+
+ uri = soup_uri_to_string (soup_uri, FALSE);
+ soup_uri_free (soup_uri);
+
+ /* Get frame's window and from the window the actual <iframe> element */
+ window = webkit_dom_document_get_default_view (doc);
+ frame_element = webkit_dom_dom_window_get_frame_element (window);
+ webkit_dom_html_iframe_element_set_src (
+ WEBKIT_DOM_HTML_IFRAME_ELEMENT (frame_element), uri);
+
+ g_free (uri);
+
+ /* The frame has been reloaded, the document pointer is invalid now */
+ th_extension->document = NULL;
+}
+
+static GtkActionGroup*
+create_group (EMailDisplayPopupExtension *extension)
+{
+ EExtensible *extensible;
+ EWebView *web_view;
+ GtkUIManager *ui_manager, *shell_ui_manager;
+ GtkActionGroup *group;
+ EShell *shell;
+ GtkWindow *shell_window;
+ gint i;
+ gsize len;
+ guint merge_id, shell_merge_id;
+ Language *languages;
+ GSList *radio_group;
+ gint action_index;
+
+ extensible = e_extension_get_extensible (E_EXTENSION (extension));
+ web_view = E_WEB_VIEW (extensible);
+
+ ui_manager = e_web_view_get_ui_manager (web_view);
+ shell = e_shell_get_default ();
+ shell_window = e_shell_get_active_window (shell);
+ if (E_IS_SHELL_WINDOW (shell_window)) {
+ shell_ui_manager = e_shell_window_get_ui_manager (E_SHELL_WINDOW (shell_window));
+ } else if (E_IS_MAIL_BROWSER (shell_window)) {
+ shell_ui_manager = e_mail_browser_get_ui_manager (E_MAIL_BROWSER (shell_window));
+ } else {
+ return NULL;
+ }
+
+ group = gtk_action_group_new ("format-as");
+ gtk_action_group_add_actions (group, entries, G_N_ELEMENTS (entries), NULL);
+
+ gtk_ui_manager_insert_action_group (ui_manager, group, 0);
+ gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, NULL);
+
+ gtk_ui_manager_insert_action_group (shell_ui_manager, group, 0);
+ gtk_ui_manager_add_ui_from_string (shell_ui_manager, ui_reader, -1, NULL);
+
+ merge_id = gtk_ui_manager_new_merge_id (ui_manager);
+ shell_merge_id = gtk_ui_manager_new_merge_id (shell_ui_manager);
+
+ languages = get_default_langauges (&len);
+ radio_group = NULL;
+ action_index = 0;
+ for (i = 0; i < len; i++) {
+
+ GtkRadioAction *action;
+ action = gtk_radio_action_new (
+ languages[i].action_name,
+ languages[i].action_label,
+ NULL, NULL, action_index);
+ action_index++;
+ gtk_action_group_add_action (group, GTK_ACTION (action));
+ g_signal_connect (action, "changed",
+ G_CALLBACK (reformat), extension);
+ gtk_radio_action_set_group (action, radio_group);
+ radio_group = gtk_radio_action_get_group (action);
+
+ g_object_unref (action);
+
+ gtk_ui_manager_add_ui (
+ ui_manager, merge_id,
+ "/context/custom-actions-2/format-as-menu/format-as-actions",
+ languages[i].action_name, languages[i].action_name,
+ GTK_UI_MANAGER_AUTO, FALSE);
+
+ gtk_ui_manager_add_ui (
+ shell_ui_manager, shell_merge_id,
+ "/mail-preview-popup/mail-preview-popup-actions/format-as-menu/format-as-actions",
+ languages[i].action_name, languages[i].action_name,
+ GTK_UI_MANAGER_AUTO, FALSE);
+ }
+
+ languages = get_additinal_languages (&len);
+ for (i = 0; i < len; i++) {
+ GtkRadioAction *action;
+
+ action = gtk_radio_action_new (
+ languages[i].action_name,
+ languages[i].action_label,
+ NULL, NULL, action_index);
+ action_index++;
+ gtk_action_group_add_action (group, GTK_ACTION (action));
+ g_signal_connect (action, "changed",
+ G_CALLBACK (reformat), extension);
+
+ gtk_radio_action_set_group (action, radio_group);
+ radio_group = gtk_radio_action_get_group (action);
+
+ g_object_unref (action);
+
+ gtk_ui_manager_add_ui (
+ ui_manager, merge_id,
+ "/context/custom-actions-2/format-as-menu/format-as-other-menu",
+ languages[i].action_name, languages[i].action_name,
+ GTK_UI_MANAGER_AUTO, FALSE);
+
+ gtk_ui_manager_add_ui (
+ shell_ui_manager, shell_merge_id,
+ "/mail-preview-popup/mail-preview-popup-actions/format-as-menu/format-as-other-menu",
+ languages[i].action_name, languages[i].action_name,
+ GTK_UI_MANAGER_AUTO, FALSE);
+ }
+
+ return group;
+}
+
+static void
+update_actions (EMailDisplayPopupExtension *extension,
+ WebKitHitTestResult *context)
+{
+ EMailDisplayPopupTextHighlight *th_extension;
+ WebKitDOMNode *node;
+ WebKitDOMDocument *document;
+ gchar *uri;
+
+ th_extension = E_MAIL_DISPLAY_POPUP_TEXT_HIGHLIGHT (extension);
+
+ if (th_extension->action_group == NULL) {
+ th_extension->action_group = create_group(extension);
+ }
+
+ g_object_get (G_OBJECT (context), "inner-node", &node, NULL);
+ document = webkit_dom_node_get_owner_document (node);
+ uri = webkit_dom_document_get_document_uri (document);
+
+
+ /* If the part below context menu was made by text-highlight formatter,
+ * then try to check what formatter it's using at the moment and set
+ * it as active in the popup menu */
+ if (uri && strstr (uri, ".text-highlight") != NULL) {
+ SoupURI *soup_uri;
+ gtk_action_group_set_visible (
+ th_extension->action_group, TRUE);
+
+ soup_uri = soup_uri_new (uri);
+ if (soup_uri && soup_uri->query) {
+ GHashTable *query = soup_form_decode (soup_uri->query);
+ gchar *highlighter;
+
+ highlighter = g_hash_table_lookup (query, "__formatas");
+ if (highlighter && *highlighter) {
+ GtkAction *action = gtk_action_group_get_action (
+ th_extension->action_group, highlighter);
+ if (action) {
+ gint value;
+ g_object_get (
+ G_OBJECT (action), "value",
+ &value, NULL);
+ gtk_radio_action_set_current_value (
+ GTK_RADIO_ACTION (action), value);
+ }
+ }
+ g_hash_table_destroy (query);
+ }
+
+ if (soup_uri) {
+ soup_uri_free (soup_uri);
+ }
+
+ } else {
+ gtk_action_group_set_visible(
+ th_extension->action_group, FALSE);
+ }
+
+ /* Set the th_extension->document AFTER changing the active action to
+ * prevent the reformat() from doing some crazy reformatting
+ * (reformat() returns immediatelly when th_extension->document is NULL) */
+ th_extension->document = document;
+
+ g_free (uri);
+}
+
+void
+e_mail_display_popup_text_highlight_type_register (GTypeModule *type_module)
+{
+ e_mail_display_popup_text_highlight_register_type (type_module);
+}
+
+static void
+e_mail_display_popup_text_highlight_class_init (EMailDisplayPopupTextHighlightClass *klass)
+{
+ EExtensionClass *extension_class;
+
+ e_mail_display_popup_text_highlight_parent_class = g_type_class_peek_parent (klass);
+
+ extension_class = E_EXTENSION_CLASS (klass);
+ extension_class->extensible_type = E_TYPE_MAIL_DISPLAY;
+}
+
+static void
+e_mail_display_popup_extension_interface_init (EMailDisplayPopupExtensionInterface *iface)
+{
+ iface->update_actions = update_actions;
+}
+
+void
+e_mail_display_popup_text_highlight_class_finalize (EMailDisplayPopupTextHighlightClass *klass)
+{
+
+}
+
+static void
+e_mail_display_popup_text_highlight_init (EMailDisplayPopupTextHighlight *extension)
+{
+ extension->action_group = NULL;
+}
diff --git a/modules/text-highlight/e-mail-display-popup-text-highlight.h b/modules/text-highlight/e-mail-display-popup-text-highlight.h
new file mode 100644
index 0000000000..003f7d9bc2
--- /dev/null
+++ b/modules/text-highlight/e-mail-display-popup-text-highlight.h
@@ -0,0 +1,30 @@
+/*
+ * e-mail-display-popup-text-highlight.h
+ *
+ * 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/>
+ *
+ */
+
+#ifndef E_MAIL_DISPLAY_POPUP_TEXT_HIGHLIGHT_H
+#define E_MAIL_DISPLAY_POPUP_TEXT_HIGHLIGHT_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void e_mail_display_popup_text_highlight_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_DISPLAY_POPUP_TEXT_HIGHLIGHT_H */
diff --git a/modules/text-highlight/text-highlight.c b/modules/text-highlight/e-mail-formatter-text-highlight.c
index 26f7708f76..e216245500 100644
--- a/modules/text-highlight/text-highlight.c
+++ b/modules/text-highlight/e-mail-formatter-text-highlight.c
@@ -20,13 +20,17 @@
#include <config.h>
#endif
-#include "text-highlight.h"
+#include "e-mail-formatter-text-highlight.h"
+#include "languages.h"
#include <em-format/e-mail-formatter-extension.h>
#include <em-format/e-mail-formatter.h>
#include <em-format/e-mail-part-utils.h>
#include <e-util/e-util.h>
+#include <shell/e-shell-settings.h>
+#include <shell/e-shell.h>
+
#include <libebackend/libebackend.h>
#include <libedataserver/libedataserver.h>
@@ -61,11 +65,8 @@ G_DEFINE_DYNAMIC_TYPE_EXTENDED (
E_TYPE_MAIL_FORMATTER_EXTENSION,
e_mail_formatter_formatter_extension_interface_init));
-static const gchar *formatter_mime_types[] = { "text/x-diff",
- "text/x-patch",
- NULL };
-
-static gchar * get_default_font (void)
+static gchar *
+get_default_font (void)
{
gchar *font;
GSettings *settings;
@@ -74,9 +75,61 @@ static gchar * get_default_font (void)
font = g_settings_get_string (settings, "monospace-font-name");
+ g_object_unref (settings);
+
return font ? font : g_strdup ("monospace 10");
}
+static gchar *
+get_syntax (EMailPart *part,
+ const gchar *uri)
+{
+ gchar *syntax = NULL;
+
+ if (uri) {
+ SoupURI *soup_uri = soup_uri_new (uri);
+ GHashTable *query = soup_form_decode (soup_uri->query);
+
+ syntax = g_hash_table_lookup (query, "__formatas");
+ if (syntax) {
+ syntax = g_strdup (syntax);
+ }
+ g_hash_table_destroy (query);
+ soup_uri_free (soup_uri);
+ }
+
+ /* Try to detect syntax from attachment filename extension */
+ if (syntax == NULL) {
+ const gchar *filename = camel_mime_part_get_filename (part->part);
+ if (filename) {
+ gchar *ext = g_strrstr (filename, ".");
+ if (ext) {
+ syntax = (gchar *) get_syntax_for_ext (ext + 1);
+ syntax = g_strdup (syntax ? syntax : "txt");
+ }
+ }
+ }
+
+ /* Try it by mime type */
+ if (syntax == NULL) {
+ CamelContentType *ct = camel_mime_part_get_content_type (part->part);
+ if (ct) {
+ gchar *mime_type = camel_content_type_simple (ct);
+
+ syntax = (gchar *) get_syntax_for_mime_type (mime_type);
+ syntax = g_strdup (syntax ? syntax : "txt");
+ g_free (mime_type);
+ }
+ }
+
+ /* Out of ideas - use plain text */
+ if (syntax == NULL) {
+ syntax = g_strdup ("txt");
+ }
+
+ return syntax;
+}
+
static gboolean
emfe_text_highlight_format (EMailFormatterExtension *extension,
EMailFormatter *formatter,
@@ -85,6 +138,17 @@ emfe_text_highlight_format (EMailFormatterExtension *extension,
CamelStream *stream,
GCancellable *cancellable)
{
+ /* Don't format text/html unless it's an attachment */
+ CamelContentType *ct = camel_mime_part_get_content_type (part->part);
+ if (ct && camel_content_type_is (ct, "text", "html")) {
+ const CamelContentDisposition *disp;
+ disp = camel_mime_part_get_content_disposition (part->part);
+
+ if (!disp || g_strcmp0 (disp->disposition, "attachment") != 0)
+ return FALSE;
+ }
+
+
if (context->mode == E_MAIL_FORMATTER_MODE_PRINTING) {
CamelDataWrapper *dw;
@@ -102,8 +166,7 @@ emfe_text_highlight_format (EMailFormatterExtension *extension,
filter_stream = camel_stream_filter_new (stream);
mime_filter = camel_mime_filter_tohtml_new (
CAMEL_MIME_FILTER_TOHTML_PRE |
- CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES,
- 0x7a7a7a);
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES, 0);
camel_stream_filter_add (
CAMEL_STREAM_FILTER (filter_stream), mime_filter);
g_object_unref (mime_filter);
@@ -124,18 +187,19 @@ emfe_text_highlight_format (EMailFormatterExtension *extension,
GPid pid;
CamelStream *read, *write;
CamelDataWrapper *dw;
- gchar *font_family, *font_size;
+ gchar *font_family, *font_size, *syntax;
gboolean use_custom_font;
- GSettings *settings;
+ EShell *shell;
+ EShellSettings *settings;
PangoFontDescription *fd;
const gchar *argv[] = { "highlight",
- NULL, /* don't move these! */
- NULL,
+ NULL, /* --font= */
+ NULL, /* --font-size= */
+ NULL, /* --syntax= */
"--out-format=html",
"--include-style",
"--inline-css",
"--style=bclear",
- "--syntax=diff",
"--failsafe",
NULL };
@@ -144,9 +208,20 @@ emfe_text_highlight_format (EMailFormatterExtension *extension,
return FALSE;
}
+ syntax = get_syntax (part, context->uri);
+
+ /* Use the traditional text/plain formatter for plain-text */
+ if (g_strcmp0 (syntax, "txt") == 0) {
+ g_free (syntax);
+ return FALSE;
+ }
+
+ shell = e_shell_get_default ();
+ settings = e_shell_get_shell_settings (shell);
+
fd = NULL;
- settings = g_settings_new ("org.gnome.evolution.mail");
- use_custom_font = g_settings_get_boolean (settings, "use-custom-font");
+ use_custom_font = e_shell_settings_get_boolean (
+ settings, "mail-use-custom-fonts");
if (!use_custom_font) {
gchar *font;
@@ -154,17 +229,15 @@ emfe_text_highlight_format (EMailFormatterExtension *extension,
fd = pango_font_description_from_string (font);
g_free (font);
- g_object_unref (settings);
-
} else {
gchar *font;
- font = g_settings_get_string (settings, "monospace-font");
+ font = e_shell_settings_get_string (
+ settings, "mail-font-monospace");
if (!font)
font = get_default_font ();
fd = pango_font_description_from_string (font);
-
g_free (font);
}
@@ -175,6 +248,8 @@ emfe_text_highlight_format (EMailFormatterExtension *extension,
argv[1] = font_family;
argv[2] = font_size;
+ argv[3] = g_strdup_printf ("--syntax=%s", syntax);
+ g_free (syntax);
if (!g_spawn_async_with_pipes (
NULL, (gchar **) argv, NULL,
@@ -195,22 +270,28 @@ emfe_text_highlight_format (EMailFormatterExtension *extension,
g_seekable_seek (G_SEEKABLE (read), 0, G_SEEK_SET, cancellable, NULL);
camel_stream_write_to_stream (read, stream, cancellable, NULL);
- camel_stream_flush (read, cancellable, NULL);
g_object_unref (read);
g_free (font_family);
g_free (font_size);
+ g_free ((gchar *) argv[3]);
pango_font_description_free (fd);
} else {
gchar *uri, *str;
+ gchar *syntax;
+
+ syntax = get_syntax (part, NULL);
uri = e_mail_part_build_uri (
context->folder, context->message_uid,
"part_id", G_TYPE_STRING, part->id,
"mode", G_TYPE_INT, E_MAIL_FORMATTER_MODE_RAW,
+ "__formatas", G_TYPE_STRING, syntax,
NULL);
+ g_free (syntax);
+
str = g_strdup_printf (
"<div class=\"part-container\" style=\"border-color: #%06x; "
"background-color: #%06x;\">"
@@ -239,19 +320,19 @@ emfe_text_highlight_format (EMailFormatterExtension *extension,
static const gchar *
emfe_text_highlight_get_display_name (EMailFormatterExtension *extension)
{
- return _("Patch");
+ return _("Text Highlight");
}
static const gchar *
emfe_text_highlight_get_description (EMailFormatterExtension *extension)
{
- return _("Format part as a patch");
+ return _("Syntax highlighting of mail parts");
}
static const gchar **
emfe_text_highlight_mime_types (EMailExtension *extension)
{
- return formatter_mime_types;
+ return get_mime_types ();
}
static void
diff --git a/modules/text-highlight/text-highlight.h b/modules/text-highlight/e-mail-formatter-text-highlight.h
index af10da4c84..af10da4c84 100644
--- a/modules/text-highlight/text-highlight.h
+++ b/modules/text-highlight/e-mail-formatter-text-highlight.h
diff --git a/modules/text-highlight/e-mail-parser-text-highlight.c b/modules/text-highlight/e-mail-parser-text-highlight.c
new file mode 100644
index 0000000000..328e590f6d
--- /dev/null
+++ b/modules/text-highlight/e-mail-parser-text-highlight.c
@@ -0,0 +1,159 @@
+/*
+ * 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/>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <camel/camel.h>
+
+#include "e-mail-parser-text-highlight.h"
+#include "languages.h"
+
+#include <em-format/e-mail-extension-registry.h>
+#include <em-format/e-mail-parser-extension.h>
+#include <em-format/e-mail-part.h>
+#include <em-format/e-mail-part-utils.h>
+
+#include <libebackend/libebackend.h>
+
+#define d(x)
+
+typedef struct _EMailParserTextHighlight {
+ EExtension parent;
+} EMailParserTextHighlight;
+
+typedef struct _EMailParserTextHighlightClass {
+ EExtensionClass parent_class;
+} EMailParserTextHighlightClass;
+
+GType e_mail_parser_text_highlight_get_type (void);
+static void e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface);
+static void e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (
+ EMailParserTextHighlight,
+ e_mail_parser_text_highlight,
+ E_TYPE_EXTENSION,
+ 0,
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_EXTENSION,
+ e_mail_parser_mail_extension_interface_init)
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_PARSER_EXTENSION,
+ e_mail_parser_parser_extension_interface_init));
+
+static GSList *
+empe_text_highlight_parse (EMailParserExtension *extension,
+ EMailParser *parser,
+ CamelMimePart *part,
+ GString *part_id,
+ GCancellable *cancellable)
+{
+ GSList *parts;
+ gint len;
+ CamelContentType *ct;
+
+ /* Prevent recursion */
+ if (strstr (part_id->str, ".text-highlight") != NULL) {
+ return NULL;
+ }
+
+ /* Don't parse text/html if it's not an attachment */
+ ct = camel_mime_part_get_content_type (part);
+ if (camel_content_type_is (ct, "text", "html")) {
+ const CamelContentDisposition *disp;
+
+ disp = camel_mime_part_get_content_disposition (part);
+ if (!disp || (g_strcmp0 (disp->disposition, "attachment") != 0)) {
+ return NULL;
+ }
+ }
+
+ len = part_id->len;
+ g_string_append (part_id, ".text-highlight");
+
+ /* All source codes and scripts are in general plain texts,
+ * so let text/plain parser handle it. */
+ parts = e_mail_parser_parse_part_as (
+ parser, part, part_id, "text/plain", cancellable);
+
+ g_string_truncate (part_id, len);
+
+ return parts;
+}
+
+static const gchar **
+empe_mime_types (EMailExtension *extension)
+{
+ return get_mime_types ();
+}
+
+void
+e_mail_parser_text_highlight_type_register (GTypeModule *type_module)
+{
+ e_mail_parser_text_highlight_register_type (type_module);
+}
+
+static void
+e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface)
+{
+ iface->mime_types = empe_mime_types;
+}
+
+static void
+e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface)
+{
+ iface->parse = empe_text_highlight_parse;
+}
+
+static void
+e_mail_parser_text_highlight_constructed (GObject *object)
+{
+ EExtensible *extensible;
+ EMailExtensionRegistry *reg;
+
+ extensible = e_extension_get_extensible (E_EXTENSION (object));
+ reg = E_MAIL_EXTENSION_REGISTRY (extensible);
+
+ e_mail_extension_registry_add_extension (reg, E_MAIL_EXTENSION (object));
+}
+
+static void
+e_mail_parser_text_highlight_class_init (EMailParserTextHighlightClass *class)
+{
+ GObjectClass *object_class;
+ EExtensionClass *extension_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->constructed = e_mail_parser_text_highlight_constructed;
+
+ extension_class = E_EXTENSION_CLASS (class);
+ extension_class->extensible_type = E_TYPE_MAIL_PARSER_EXTENSION_REGISTRY;
+}
+
+void
+e_mail_parser_text_highlight_class_finalize (EMailParserTextHighlightClass *class)
+{
+}
+
+static void
+e_mail_parser_text_highlight_init (EMailParserTextHighlight *parser)
+{
+
+}
diff --git a/modules/text-highlight/e-mail-parser-text-highlight.h b/modules/text-highlight/e-mail-parser-text-highlight.h
new file mode 100644
index 0000000000..cc55a777ac
--- /dev/null
+++ b/modules/text-highlight/e-mail-parser-text-highlight.h
@@ -0,0 +1,30 @@
+/*
+ * e-mail-parser-text-highlight.h
+ *
+ * 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/>
+ *
+ */
+
+#ifndef E_MAIL_PARSER_TEXT_HIGHLIGHT_H
+#define E_MAIL_PARSER_TEXT_HIGHLIGHT_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void e_mail_parser_text_highlight_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_PARSER_TEXT_HIGHLIGHT_H */
diff --git a/modules/text-highlight/evolution-module-text-highlight.c b/modules/text-highlight/evolution-module-text-highlight.c
index de6e469bde..78c3c4dcf5 100644
--- a/modules/text-highlight/evolution-module-text-highlight.c
+++ b/modules/text-highlight/evolution-module-text-highlight.c
@@ -16,7 +16,9 @@
*
*/
-#include "text-highlight.h"
+#include "e-mail-parser-text-highlight.h"
+#include "e-mail-formatter-text-highlight.h"
+#include "e-mail-display-popup-text-highlight.h"
#include <gmodule.h>
@@ -28,8 +30,9 @@ G_MODULE_EXPORT void
e_module_load (GTypeModule *type_module)
{
/* Register dynamically loaded types. */
-
+ e_mail_parser_text_highlight_type_register (type_module);
e_mail_formatter_text_highlight_type_register (type_module);
+ e_mail_display_popup_text_highlight_type_register (type_module);
}
G_MODULE_EXPORT void
diff --git a/modules/text-highlight/languages.c b/modules/text-highlight/languages.c
new file mode 100644
index 0000000000..957b0aded9
--- /dev/null
+++ b/modules/text-highlight/languages.c
@@ -0,0 +1,529 @@
+/*
+ * languages.c
+ *
+ * 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/>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "languages.h"
+
+#include <glib/gi18n-lib.h>
+
+static const gchar **mime_types = NULL;
+G_LOCK_DEFINE_STATIC (mime_types);
+
+static Language languages[] = {
+
+ { "txt", N_("_Plain text"),
+ (const gchar* []) { (gchar[]) { "text" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/plain" },
+ (gchar[]) { "text/*" }, NULL }
+ },
+
+ { "assembler", N_("_Assembler"),
+ (const gchar* []) { (gchar[]) { "asm" } , NULL },
+ (const gchar* []) { (gchar[]) { "text/x-asm" }, NULL }
+ },
+
+ { "sh", N_("_Bash"),
+ (const gchar* []) { (gchar[]) { "bash" }, (gchar[]) { "sh" },
+ (gchar[]) { "ebuild" }, (gchar[]) {"eclass" },
+ NULL },
+ (const gchar* []) { (gchar[]) { "application/x-bsh" },
+ (gchar[]) { "application/x-sh" },
+ (gchar[]) { "application/x-shar" },
+ (gchar[]) { "application/x-shellscript" },
+ (gchar[]) { "text/x-script.sh" }, NULL }
+ },
+
+ { "c", N_("_C/C++"),
+ (const gchar* []) { (gchar[]) { "c" }, (gchar[]) { "c++" },
+ (gchar[]) { "cc" }, (gchar[]) { "cpp" },
+ (gchar[]) { "cu" }, (gchar[]) { "cxx" },
+ (gchar[]) { "h" }, (gchar[]) { "hh" },
+ (gchar[]) { "hpp" }, (gchar[]) { "hxx" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-c" }, NULL }
+ },
+
+ { "csharp", N_("_C#"),
+ (const gchar* []) { (gchar[]) { "cs" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-csharp" }, NULL }
+ },
+
+ { "css", N_("_Cascade Style Sheet"),
+ (const gchar* []) { (gchar[]) { "css" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/css" }, NULL }
+ },
+
+ { "html", N_("_HTML"),
+ (const gchar* []) { (gchar[]) { "html" }, (gchar[]) { "html" },
+ (gchar[]) { "xhtml" }, (gchar[]) { "dhtml" }, NULL },
+ (const gchar* []) { NULL } /* Don't register text-highlight as formatter
+ or parser of text/html as it would break
+ all text/html emails. */
+ },
+
+ { "java", N_("_Java"),
+ (const gchar* []) { (gchar[]) { "java" }, (gchar[]) { "groovy" },
+ (gchar[]) { "grv" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/java-source" }, NULL }
+ },
+
+ { "js", N_("_JavaScript"),
+ (const gchar* []) { (gchar[]) { "js" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/javascript" },
+ (gchar[]) { "application/x-javascript" }, NULL }
+ },
+
+ { "diff", N_("_Patch/diff"),
+ (const gchar* []) { (gchar[]) { "diff" }, (gchar[]) { "patch" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-diff" },
+ (gchar[]) { "text/x-patch" }, NULL }
+ },
+
+ { "perl", N_("_Perl"),
+ (const gchar* []) { (gchar[]) { "perl" }, (gchar[]) { "cgi"},
+ (gchar[]) { "perl" }, (gchar[]) { "pl" },
+ (gchar[]) { "plex" }, (gchar[]) { "plx" },
+ (gchar[]) { "pm" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-script.perl" },
+ (gchar[]) { "text/x-script.perl-module" },
+ (gchar[]) { "application/x-pixclscript" },
+ (gchar[]) { "application/x-xpixmap" }, NULL }
+ },
+
+ { "php", N_("_PHP"),
+ (const gchar* []) { (gchar[]) { "php" }, (gchar[]) { "php3" },
+ (gchar[]) { "php4" }, (gchar[]) { "php5" },
+ (gchar[]) { "php6" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/php" },
+ (gchar[]) { "text/x-php" },
+ (gchar[]) { "application/php" },
+ (gchar[]) { "application/x-php" },
+ (gchar[]) { "application/x-httpd-php" },
+ (gchar[]) { "application/x-httpd-php-source" },
+ NULL }
+ },
+
+ { "python", N_("_Python"),
+ (const gchar* []) { (gchar[]) { "py" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-script.python" }, NULL }
+ },
+
+ { "ruby", N_("_Ruby"),
+ (const gchar* []) { (gchar[]) { "ruby" }, (gchar[]) { "pp" },
+ (gchar[]) { "rb" }, (gchar[]) { "rjs" },
+ (gchar[]) { "ruby" }, NULL },
+ (const gchar* []) { (gchar[]) { "application/x-ruby" }, NULL }
+ },
+
+ { "tcl", N_("_Tcl/Tk"),
+ (const gchar* []) { (gchar[]) { "tcl" }, (gchar[]) { "ictl" },
+ (gchar[]) { "wish" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-tcl" }, NULL }
+ },
+
+ { "tex", N_("_TeX/LaTeX"),
+ (const gchar* []) { (gchar[]) { "tex" }, (gchar[]) { "csl" },
+ (gchar[]) { "sty" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-tex" }, NULL }
+ },
+
+ { "vala", N_("_Vala"),
+ (const gchar* []) { (gchar[]) { "vala" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-vala" }, NULL }
+ },
+
+ { "vb", N_("_Visual Basic"),
+ (const gchar* []) { (gchar[]) { "vb" }, (gchar[]) { "bas" },
+ (gchar[]) { "basic" }, (gchar[]) { "bi" },
+ (gchar[]) { "vbs" }, NULL },
+ (const gchar* []) { NULL }
+ },
+
+ { "xml", N_("_XML"),
+ (const gchar* []) { (gchar[]) { "xml" }, (gchar[]) { "dtd" },
+ (gchar[]) { "ecf" }, (gchar[]) { "ent" },
+ (gchar[]) { "hdr" }, (gchar[]) { "hub" },
+ (gchar[]) { "jnlp" }, (gchar[]) { "nrm" },
+ (gchar[]) { "resx" }, (gchar[]) { "sgm" },
+ (gchar[]) { "sgml" }, (gchar[]) { "svg" },
+ (gchar[]) { "tld" }, (gchar[]) { "vxml" },
+ (gchar[]) { "wml" }, (gchar[]) { "xsd" },
+ (gchar[]) { "xsl" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/xml" },
+ (gchar[]) { "application/xml" },
+ (gchar[]) { "application/x-xml" }, NULL }
+ }
+};
+
+static struct Language other_languages[] = {
+
+ { "actionscript", N_("_ActionScript"),
+ (const gchar* []) { (gchar[]) { "as" }, NULL },
+ (const gchar* []) { NULL }
+ },
+
+ { "ada", N_("_ADA95"),
+ (const gchar* []) { (gchar[]) { "a" }, (gchar[]) { "adb" },
+ (gchar[]) { "ads" }, (gchar[]) { "gnad" },
+ NULL },
+ (const gchar* []) { (gchar[]) { "text/x-adasrc" }, NULL }
+ },
+
+ { "algol", N_("_ALGOL 68"),
+ (const gchar* []) { (gchar[]) { "alg" }, NULL },
+ (const gchar* []) { NULL }
+ },
+
+ { "awk", N_("(_G)AWK"),
+ (const gchar* []) { (gchar[]) { "awk" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-awk" }, NULL }
+ },
+
+ { "cobol", N_("_COBOL"),
+ (const gchar* []) { (gchar[]) { "cbl" }, (gchar[]) { "cob" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-cobol" }, NULL }
+ },
+
+ { "bat", N_("_DOS Batch"),
+ (const gchar* []) { (gchar[]) { "bat" }, (gchar[]) { "cmd" }, NULL },
+ (const gchar* []) { NULL }
+ },
+
+ { "d", N_("_D"),
+ (const gchar* []) { (gchar[]) { "d" }, NULL },
+ (const gchar* []) { NULL }
+ },
+
+ { "erlang", N_("_Erlang"),
+ (const gchar* []) { (gchar[]) { "erl" }, (gchar[]) { "hrl" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-erlang" }, NULL }
+ },
+
+ { "fortran77", N_("_FORTRAN 77"),
+ (const gchar* []) { (gchar[]) { "f" }, (gchar[]) { "for" },
+ (gchar[]) { "ftn" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-fortran" }, NULL }
+ },
+
+ { "fortran90", N_("_FORTRAN 90"),
+ (const gchar* []) { (gchar[]) { "f90" }, (gchar[]) { "f95" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-fortran" }, NULL }
+ },
+
+ { "fsharp", N_("_F#"),
+ (const gchar* []) { (gchar[]) { "fs" }, (gchar[]) { "fsx" }, NULL },
+ (const gchar* []) { NULL }
+ },
+
+ { "go", N_("_Go"),
+ (const gchar* []) { (gchar[]) { "go" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-go" }, NULL }
+ },
+
+ { "haskell", N_("_Haskell"),
+ (const gchar* []) { (gchar[]) { "hs" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-haskell" }, NULL }
+ },
+
+ { "jsp", N_("_JSP"),
+ (const gchar* []) { (gchar[]) { "jsp" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-jsp" }, NULL }
+ },
+
+ { "lisp", N_("_Lisp"),
+ (const gchar* []) { (gchar[]) { "cl" }, (gchar[]) { "clisp" },
+ (gchar[]) { "el" }, (gchar[]) { "lsp" },
+ (gchar[]) { "sbcl"}, (gchar[]) { "scom" },
+ NULL },
+ (const gchar* []) { (gchar[]) { "text/x-emacs-lisp" }, NULL }
+ },
+
+ { "lotus", N_("_Lotus"),
+ (const gchar* []) { (gchar[]) { "ls" }, NULL },
+ (const gchar* []) { (gchar[]) { "application/vnd.lotus-1-2-3" }, NULL }
+ },
+
+ { "lua", N_("_Lua"),
+ (const gchar* []) { (gchar[]) { "lua" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-lua" }, NULL }
+ },
+
+ { "maple", N_("_Maple"),
+ (const gchar* []) { (gchar[]) { "mpl" }, NULL },
+ (const gchar* []) { NULL }
+ },
+
+ { "matlab", N_("_Matlab"),
+ (const gchar* []) { (gchar[]) { "m" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-matlab" }, NULL }
+ },
+
+ { "maya", N_("_Maya"),
+ (const gchar* []) { (gchar[]) { "mel" }, NULL },
+ (const gchar* []) { NULL }
+ },
+
+ { "oberon", N_("_Oberon"),
+ (const gchar* []) { (gchar[]) { "ooc" }, NULL },
+ (const gchar* []) { NULL }
+ },
+
+ { "objc", N_("_Objective C"),
+ (const gchar* []) { (gchar[]) { "objc" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-objchdr" },
+ (gchar[]) { "text/x-objcsrc" }, NULL }
+ },
+
+ { "ocaml", N_("_OCaml"),
+ (const gchar* []) { (gchar[]) { "ml" }, (gchar[]) { "mli" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-ocaml" }, NULL }
+ },
+
+ { "octave", N_("_Octave"),
+ (const gchar* []) { (gchar[]) { "octave" }, NULL },
+ (const gchar* []) { NULL }
+ },
+
+ { "os", N_("_Object Script"),
+ (const gchar* []) { (gchar[]) { "os" }, NULL },
+ (const gchar* []) { NULL }
+ },
+
+ { "pascal", N_("_Pascal"),
+ (const gchar* []) { (gchar[]) { "pas" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-pascal" }, NULL }
+ },
+
+ { "pov", N_("_POV-Ray"),
+ (const gchar* []) { (gchar[]) { "pov" }, NULL },
+ (const gchar* []) { NULL }
+ },
+
+ { "pro", N_("_Prolog"),
+ (const gchar* []) { (gchar[]) { "pro" }, NULL },
+ (const gchar* []) { NULL }
+ },
+
+ { "ps", N_("_PostScript"),
+ (const gchar* []) { (gchar[]) { "ps" } , NULL },
+ (const gchar* []) { (gchar[]) { "application/postscript" }, NULL }
+ },
+
+ { "r", N_("_R"),
+ (const gchar* []) { (gchar[]) { "r" }, NULL },
+ (const gchar* []) { NULL }
+ },
+
+ { "spec", N_("_RPM Spec"),
+ (const gchar* []) { (gchar[]) { "spec" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-rpm-spec" }, NULL }
+ },
+
+ { "scala", N_("_Scala"),
+ (const gchar* []) { (gchar[]) { "scala" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-scala" }, NULL }
+ },
+
+ { "smalltalk", N_("_Smalltalk"),
+ (const gchar* []) { (gchar[]) { "gst" }, (gchar[]) { "sq" },
+ (gchar[]) { "st" }, NULL },
+ (const gchar* []) { NULL }
+ },
+
+ { "tcsh", N_("_TCSH"),
+ (const gchar* []) { (gchar[]) { "tcsh" }, NULL },
+ (const gchar* []) { NULL }
+ },
+
+ { "vhd", N_("_VHDL"),
+ (const gchar* []) { (gchar[]) { "vhd" }, NULL },
+ (const gchar* []) { (gchar[]) { "text/x-vhdl" }, NULL }
+ }
+};
+
+Language *
+get_default_langauges (gsize *len)
+{
+ if (len) {
+ *len = G_N_ELEMENTS (languages);
+ }
+
+ return languages;
+}
+
+Language *
+get_additinal_languages (gsize *len)
+{
+ if (len) {
+ *len = G_N_ELEMENTS (other_languages);
+ }
+
+ return other_languages;
+}
+
+const gchar *
+get_syntax_for_ext(const gchar *extension)
+{
+ gint i;
+ gint j;
+
+ for (i = 0; i < G_N_ELEMENTS (languages); i++) {
+
+ Language *lang = &languages[i];
+ const gchar *ext;
+
+ j = 0;
+ ext = lang->extensions[j];
+ while (ext) {
+ if (g_ascii_strncasecmp (ext, extension, strlen (ext)) == 0) {
+ return lang->action_name;
+ }
+
+ j++;
+ ext = lang->extensions[j];
+ }
+ }
+
+ for (i = 0; i < G_N_ELEMENTS (other_languages); i++) {
+
+ Language *lang = &other_languages[i];
+ const gchar *ext;
+
+ j = 0;
+ ext = lang->extensions[j];
+ while (ext) {
+ if (g_ascii_strncasecmp (ext, extension, strlen (ext)) == 0) {
+ return lang->action_name;
+ }
+
+ j++;
+ ext = lang->extensions[j];
+ }
+ }
+
+ return NULL;
+}
+
+const gchar *
+get_syntax_for_mime_type(const gchar *mime_type)
+{
+ gint i;
+ gint j;
+
+ for (i = 0; i < G_N_ELEMENTS (languages); i++) {
+
+ Language *lang = &languages[i];
+ const gchar *mt;
+
+ j = 0;
+ mt = lang->mime_types[j];
+ while (mt) {
+ if (g_ascii_strncasecmp (mt, mime_type, strlen (mt)) == 0) {
+ return lang->action_name;
+ }
+
+ j++;
+ mt = lang->mime_types[j];
+ }
+ }
+
+ for (i = 0; i < G_N_ELEMENTS (other_languages); i++) {
+
+ Language *lang = &other_languages[i];
+ const gchar *mt;
+
+ j = 0;
+ mt = lang->mime_types[j];
+ while (mt) {
+ if (g_ascii_strncasecmp (mt, mime_type, strlen (mt)) == 0) {
+ return lang->action_name;
+ }
+
+ j++;
+ mt = lang->mime_types[j];
+ }
+ }
+
+ return NULL;
+}
+
+
+const gchar **
+get_mime_types (void)
+{
+ G_LOCK (mime_types);
+ if (mime_types == NULL) {
+ gchar **list;
+ gsize array_len;
+ gint i, pos;
+
+ array_len = G_N_ELEMENTS (languages);
+ pos = 0;
+
+ list = g_malloc (array_len * sizeof (gchar *));
+
+ for (i = 0; i < G_N_ELEMENTS (languages); i++) {
+ Language *lang = &languages[i];
+
+ gint j = 0;
+ while (lang->mime_types[j] != NULL) {
+ if (pos == array_len) {
+ array_len += 10;
+ list = g_realloc (list, array_len * sizeof (gchar *));
+ }
+
+ list[pos] = (gchar *) lang->mime_types[j];
+ pos++;
+ j++;
+ }
+ }
+
+ for (i = 0; i < G_N_ELEMENTS (other_languages); i++) {
+ Language *lang = &other_languages[i];
+
+ gint j = 0;
+ while (lang->mime_types[j] != NULL) {
+ if (pos == array_len) {
+ array_len += 10;
+ list = g_realloc (list, array_len * sizeof (gchar *));
+ }
+
+ list[pos] = (gchar *) lang->mime_types[j];
+ pos++;
+ j++;
+ }
+ }
+
+ if (pos == array_len) {
+ array_len += 1;
+ list = g_realloc (list, array_len * sizeof (gchar *));
+ }
+
+ /* Ensure the array is null-terminated */
+ for (i = pos; i < array_len; i++) {
+ list[i] = NULL;
+ }
+
+ mime_types = (const gchar **) list;
+ }
+ G_UNLOCK (mime_types);
+
+ return mime_types;
+}
diff --git a/modules/text-highlight/languages.h b/modules/text-highlight/languages.h
new file mode 100644
index 0000000000..03f1442531
--- /dev/null
+++ b/modules/text-highlight/languages.h
@@ -0,0 +1,39 @@
+/*
+ * languages.h
+ *
+ * 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/>
+ *
+ */
+
+#ifndef LANGUAGES_H
+#define LANGUAGES_H
+
+#include <glib.h>
+
+typedef struct Language {
+ const gchar *action_name;
+ const gchar *action_label;
+ const gchar **extensions;
+ const gchar **mime_types;
+} Language;
+
+const gchar * get_syntax_for_ext (const gchar *extension);
+const gchar * get_syntax_for_mime_type (const gchar *mime_type);
+
+Language * get_default_langauges (gsize *len);
+Language * get_additinal_languages (gsize *len);
+
+const gchar ** get_mime_types (void);
+
+#endif /* LANGUAGES_H */