[evolution/449-support-markdown-in-composer] Composer: Read/write markdown format
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/449-support-markdown-in-composer] Composer: Read/write markdown format
- Date: Tue, 8 Feb 2022 16:33:24 +0000 (UTC)
commit 03c370dadbafb9a4dffe2a9d7557ba79dad0476c
Author: Milan Crha <mcrha redhat com>
Date: Tue Feb 8 17:32:53 2022 +0100
Composer: Read/write markdown format
src/composer/e-msg-composer.c | 255 ++++++++++++++++++++++++++++++-----------
src/e-util/e-html-editor.c | 20 +++-
src/e-util/e-markdown-editor.c | 55 ++++++++-
src/e-util/e-markdown-editor.h | 3 +
4 files changed, 253 insertions(+), 80 deletions(-)
---
diff --git a/src/composer/e-msg-composer.c b/src/composer/e-msg-composer.c
index 97cbdfd933..b8ba281d1e 100644
--- a/src/composer/e-msg-composer.c
+++ b/src/composer/e-msg-composer.c
@@ -86,8 +86,7 @@ typedef enum {
COMPOSER_FLAG_PGP_ENCRYPT = 1 << 5,
COMPOSER_FLAG_SMIME_SIGN = 1 << 6,
COMPOSER_FLAG_SMIME_ENCRYPT = 1 << 7,
- COMPOSER_FLAG_HTML_MODE = 1 << 8,
- COMPOSER_FLAG_SAVE_DRAFT = 1 << 9
+ COMPOSER_FLAG_SAVE_DRAFT = 1 << 8
} ComposerFlags;
enum {
@@ -217,7 +216,7 @@ e_msg_composer_dec_soft_busy (EMsgComposer *composer)
g_object_notify (G_OBJECT (composer), "soft-busy");
}
-/**
+/*
* emcu_part_to_html:
* @part:
*
@@ -227,7 +226,7 @@ e_msg_composer_dec_soft_busy (EMsgComposer *composer)
* will be performed.
*
* Return Value: The part in displayable html format.
- **/
+ */
static gchar *
emcu_part_to_html (EMsgComposer *composer,
CamelMimePart *part,
@@ -306,6 +305,45 @@ emcu_part_to_html (EMsgComposer *composer,
return text;
}
+static gchar *
+emcu_part_as_text (EMsgComposer *composer,
+ CamelMimePart *part,
+ gssize *out_len,
+ GCancellable *cancellable)
+{
+ CamelDataWrapper *dw;
+ gchar *text;
+ gssize length;
+
+ dw = camel_medium_get_content (CAMEL_MEDIUM (part));
+ if (dw) {
+ CamelStream *mem = camel_stream_mem_new ();
+ GByteArray *bytes;
+
+ camel_data_wrapper_decode_to_stream_sync (dw, mem, cancellable, NULL);
+ camel_stream_close (mem, cancellable, NULL);
+
+ bytes = camel_stream_mem_get_byte_array (CAMEL_STREAM_MEM (mem));
+ if (bytes && bytes->len) {
+ text = g_strndup ((const gchar *) bytes->data, bytes->len);
+ length = bytes->len;
+ } else {
+ text = g_strdup ("");
+ length = 0;
+ }
+
+ g_object_unref (mem);
+ } else {
+ text = g_strdup ("");
+ length = 0;
+ }
+
+ if (out_len)
+ *out_len = length;
+
+ return text;
+}
+
static EDestination **
destination_list_to_vector_sized (GList *list,
gint n)
@@ -1203,41 +1241,45 @@ composer_build_message_thread (GSimpleAsyncResult *simple,
#endif /* ENABLE_SMIME */
}
-static void
-composer_add_evolution_composer_mode_header (CamelMedium *medium,
- EMsgComposer *composer)
+static const gchar *
+composer_get_editor_mode_format_text (EContentEditorMode mode)
{
- EHTMLEditor *editor;
- const gchar *mode = "text/plain";
-
- editor = e_msg_composer_get_editor (composer);
- switch (e_html_editor_get_mode (editor)) {
+ switch (mode) {
case E_CONTENT_EDITOR_MODE_UNKNOWN:
g_warn_if_reached ();
break;
case E_CONTENT_EDITOR_MODE_PLAIN_TEXT:
- mode = "text/plain";
- break;
+ return "text/plain";
case E_CONTENT_EDITOR_MODE_HTML:
- mode = "text/html";
- break;
+ return "text/html";
case E_CONTENT_EDITOR_MODE_MARKDOWN:
- mode = "text/markdown";
- break;
+ return "text/markdown";
case E_CONTENT_EDITOR_MODE_MARKDOWN_PLAIN_TEXT:
- mode = "text/markdown-plain";
- break;
+ return "text/markdown-plain";
case E_CONTENT_EDITOR_MODE_MARKDOWN_HTML:
- mode = "text/markdown-html";
- break;
+ return "text/markdown-html";
}
+ return "text/plain";
+}
+
+static void
+composer_add_evolution_composer_mode_header (CamelMedium *medium,
+ EMsgComposer *composer)
+{
+ EHTMLEditor *editor;
+ const gchar *mode;
+
+ editor = e_msg_composer_get_editor (composer);
+ mode = composer_get_editor_mode_format_text (e_html_editor_get_mode (editor));
+
camel_medium_add_header (medium, "X-Evolution-Composer-Mode", mode);
}
static void
composer_add_evolution_format_header (CamelMedium *medium,
- ComposerFlags flags)
+ ComposerFlags flags,
+ EContentEditorMode mode)
{
GString *string;
@@ -1474,7 +1516,10 @@ composer_build_message (EMsgComposer *composer,
if (!g_str_has_suffix (text, "\r\n") && !g_str_has_suffix (text, "\n"))
g_byte_array_append (data, (const guint8 *) "\r\n", 2);
- type = camel_content_type_new ("text", "plain");
+ if (e_html_editor_get_mode (editor) == E_CONTENT_EDITOR_MODE_MARKDOWN)
+ type = camel_content_type_new ("text", "markdown");
+ else
+ type = camel_content_type_new ("text", "plain");
charset = best_charset (
data, priv->charset, &context->plain_encoding);
if (charset != NULL) {
@@ -1482,6 +1527,12 @@ composer_build_message (EMsgComposer *composer,
iconv_charset = camel_iconv_charset_name (charset);
g_free (charset);
}
+
+ if ((flags & COMPOSER_FLAG_SAVE_DRAFT) == 0 && (
+ e_html_editor_get_mode (editor) == E_CONTENT_EDITOR_MODE_MARKDOWN ||
+ e_html_editor_get_mode (editor) == E_CONTENT_EDITOR_MODE_MARKDOWN_PLAIN_TEXT ||
+ e_html_editor_get_mode (editor) == E_CONTENT_EDITOR_MODE_MARKDOWN_HTML))
+ composer_add_evolution_composer_mode_header (CAMEL_MEDIUM (context->message),
composer);
}
mem_stream = camel_stream_mem_new_with_byte_array (data);
@@ -1541,7 +1592,7 @@ composer_build_message (EMsgComposer *composer,
if ((flags & COMPOSER_FLAG_SAVE_DRAFT) != 0) {
/* X-Evolution-Format */
composer_add_evolution_format_header (
- CAMEL_MEDIUM (context->message), flags);
+ CAMEL_MEDIUM (context->message), flags, e_html_editor_get_mode
(composer->priv->editor));
/* X-Evolution-Composer-Mode */
composer_add_evolution_composer_mode_header (
@@ -2730,7 +2781,7 @@ msg_composer_map (GtkWidget *widget)
/* Jump to the editor as a last resort. */
cnt_editor = e_html_editor_get_content_editor (editor);
- gtk_widget_grab_focus (GTK_WIDGET (cnt_editor));
+ e_content_editor_grab_focus (cnt_editor);
}
static gboolean
@@ -3426,6 +3477,23 @@ e_msg_composer_check_inline_attachments (EMsgComposer *composer)
}
}
+static gboolean
+emcu_format_as_plain_text (EMsgComposer *composer,
+ CamelContentType *content_type)
+{
+ EContentEditorMode mode;
+
+ if (!camel_content_type_is (content_type, "text", "plain") &&
+ !camel_content_type_is (content_type, "text", "markdown"))
+ return FALSE;
+
+ mode = e_html_editor_get_mode (e_msg_composer_get_editor (composer));
+
+ return mode == E_CONTENT_EDITOR_MODE_MARKDOWN ||
+ mode == E_CONTENT_EDITOR_MODE_MARKDOWN_PLAIN_TEXT ||
+ mode == E_CONTENT_EDITOR_MODE_MARKDOWN_HTML;
+}
+
static void
handle_multipart_signed (EMsgComposer *composer,
CamelMultipart *multipart,
@@ -3502,7 +3570,14 @@ handle_multipart_signed (EMsgComposer *composer,
handle_multipart (
composer, multipart, parent_part, keep_signature, cancellable, depth);
}
+ } else if (camel_content_type_is (content_type, "text", "markdown") ||
+ emcu_format_as_plain_text (composer, content_type)) {
+ gchar *text;
+ gssize length;
+ text = emcu_part_as_text (composer, mime_part, &length, cancellable);
+ if (text)
+ e_msg_composer_set_pending_body (composer, text, length, FALSE);
} else if (camel_content_type_is (content_type, "text", "*")) {
gchar *html;
gssize length;
@@ -3605,6 +3680,14 @@ handle_multipart_encrypted (EMsgComposer *composer,
composer, content_multipart, multipart, keep_signature, cancellable, depth);
}
+ } else if (camel_content_type_is (content_type, "text", "markdown") ||
+ emcu_format_as_plain_text (composer, content_type)) {
+ gchar *text;
+ gssize length;
+
+ text = emcu_part_as_text (composer, mime_part, &length, cancellable);
+ if (text)
+ e_msg_composer_set_pending_body (composer, text, length, FALSE);
} else if (camel_content_type_is (content_type, "text", "*")) {
gchar *html;
gssize length;
@@ -3677,6 +3760,17 @@ handle_multipart_alternative (EMsgComposer *composer,
/* text/html is preferable, so once we find it we're done... */
text_part = mime_part;
break;
+ } else if (camel_content_type_is (content_type, "text", "markdown") ||
+ emcu_format_as_plain_text (composer, content_type)) {
+ gchar *text;
+ gssize length;
+
+ text = emcu_part_as_text (composer, mime_part, &length, cancellable);
+ if (text) {
+ e_msg_composer_set_pending_body (composer, text, length, FALSE);
+ text_part = NULL;
+ break;
+ }
} else if (camel_content_type_is (content_type, "text", "*")) {
/* anyt text part not text/html is second rate so the first
* text part we find isn't necessarily the one we'll use. */
@@ -3696,11 +3790,33 @@ handle_multipart_alternative (EMsgComposer *composer,
gchar *html;
gssize length;
- html = emcu_part_to_html (
- composer, text_part, &length, keep_signature, cancellable);
- if (!html && fallback_text_part)
- html = emcu_part_to_html (
- composer, fallback_text_part, &length, keep_signature, cancellable);
+ if (emcu_format_as_plain_text (composer, camel_mime_part_get_content_type (text_part))) {
+ gchar *text;
+ gssize length;
+
+ text = emcu_part_as_text (composer, text_part, &length, cancellable);
+ if (text) {
+ e_msg_composer_set_pending_body (composer, text, length, FALSE);
+ return;
+ }
+ }
+
+ html = emcu_part_to_html (composer, text_part, &length, keep_signature, cancellable);
+ if (!html && fallback_text_part) {
+ if (emcu_format_as_plain_text (composer, camel_mime_part_get_content_type
(fallback_text_part))) {
+ gchar *text;
+ gssize length;
+
+ text = emcu_part_as_text (composer, fallback_text_part, &length, cancellable);
+ if (text) {
+ e_msg_composer_set_pending_body (composer, text, length, FALSE);
+ return;
+ }
+ }
+
+ html = emcu_part_to_html (composer, fallback_text_part, &length, keep_signature,
cancellable);
+ }
+
if (html)
e_msg_composer_set_pending_body (composer, html, length, TRUE);
}
@@ -3762,15 +3878,26 @@ handle_multipart (EMsgComposer *composer,
}
} else if (depth == 0 && i == 0) {
- gchar *html = NULL;
- gssize length = 0;
-
/* Since the first part is not multipart/alternative,
* this must be the body. */
- html = emcu_part_to_html (
- composer, mime_part, &length, keep_signature, cancellable);
- e_msg_composer_set_pending_body (composer, html, length, TRUE);
+ if (camel_content_type_is (content_type, "text", "markdown") ||
+ emcu_format_as_plain_text (composer, content_type)) {
+ gchar *text;
+ gssize length;
+
+ text = emcu_part_as_text (composer, mime_part, &length, cancellable);
+ if (text)
+ e_msg_composer_set_pending_body (composer, text, length, FALSE);
+ } else {
+ gchar *html = NULL;
+ gssize length = 0;
+
+ html = emcu_part_to_html (
+ composer, mime_part, &length, keep_signature, cancellable);
+
+ e_msg_composer_set_pending_body (composer, html, length, TRUE);
+ }
} else if (camel_content_type_is (content_type, "image", "*") && (
camel_mime_part_get_content_id (mime_part) ||
@@ -4122,7 +4249,7 @@ e_msg_composer_setup_with_message (EMsgComposer *composer,
composer_mode = camel_medium_get_header (
CAMEL_MEDIUM (message), "X-Evolution-Composer-Mode");
- if (composer_mode && *composer_mode)
+ if (format && *format && composer_mode && *composer_mode)
is_message_from_draft = TRUE;
if (format != NULL) {
@@ -4168,6 +4295,21 @@ e_msg_composer_setup_with_message (EMsgComposer *composer,
}
}
g_strfreev (flags);
+ } else if (composer_mode != NULL) {
+ EContentEditorMode mode = E_CONTENT_EDITOR_MODE_HTML;
+
+ if (!g_ascii_strcasecmp (composer_mode, "text/plain"))
+ mode = E_CONTENT_EDITOR_MODE_PLAIN_TEXT;
+ else if (!g_ascii_strcasecmp (composer_mode, "text/html"))
+ mode = E_CONTENT_EDITOR_MODE_HTML;
+ else if (!g_ascii_strcasecmp (composer_mode, "text/markdown"))
+ mode = E_CONTENT_EDITOR_MODE_MARKDOWN;
+ else if (!g_ascii_strcasecmp (composer_mode, "text/markdown-plain"))
+ mode = E_CONTENT_EDITOR_MODE_MARKDOWN_PLAIN_TEXT;
+ else if (!g_ascii_strcasecmp (composer_mode, "text/markdown-html"))
+ mode = E_CONTENT_EDITOR_MODE_MARKDOWN_HTML;
+
+ e_html_editor_set_mode (editor, mode);
}
if (is_message_from_draft || (
@@ -4278,7 +4420,6 @@ e_msg_composer_setup_with_message (EMsgComposer *composer,
/* If we are opening message from Drafts */
if (is_message_from_draft) {
/* Extract the body */
- CamelDataWrapper *dw;
#ifdef ENABLE_SMIME
if (is_smime_encrypted) {
@@ -4307,28 +4448,11 @@ e_msg_composer_setup_with_message (EMsgComposer *composer,
}
#endif
- dw = camel_medium_get_content ((CamelMedium *) mime_part);
- if (dw) {
- CamelStream *mem = camel_stream_mem_new ();
- GByteArray *bytes;
-
- camel_data_wrapper_decode_to_stream_sync (dw, mem, cancellable, NULL);
- camel_stream_close (mem, cancellable, NULL);
-
- bytes = camel_stream_mem_get_byte_array (CAMEL_STREAM_MEM (mem));
- if (bytes && bytes->len) {
- html = g_strndup ((const gchar *) bytes->data, bytes->len);
- length = bytes->len;
- } else {
- html = g_strdup ("");
- length = 0;
- }
-
- g_object_unref (mem);
- } else {
- html = g_strdup ("");
- length = 0;
- }
+ html = emcu_part_as_text (composer, mime_part, &length, cancellable);
+ } else if (camel_content_type_is (content_type, "text", "markdown") ||
+ emcu_format_as_plain_text (composer, content_type)) {
+ is_html = FALSE;
+ html = emcu_part_as_text (composer, CAMEL_MIME_PART (message), &length, cancellable);
} else {
is_html = TRUE;
html = emcu_part_to_html (
@@ -5911,7 +6035,8 @@ e_msg_composer_get_message (EMsgComposer *composer,
g_simple_async_result_set_check_cancellable (simple, cancellable);
- if (e_html_editor_get_mode (editor) == E_CONTENT_EDITOR_MODE_HTML)
+ if (e_html_editor_get_mode (editor) == E_CONTENT_EDITOR_MODE_HTML ||
+ e_html_editor_get_mode (editor) == E_CONTENT_EDITOR_MODE_MARKDOWN_HTML)
flags |= COMPOSER_FLAG_HTML_CONTENT;
action = ACTION (PRIORITIZE_MESSAGE);
@@ -6022,7 +6147,6 @@ e_msg_composer_get_message_draft (EMsgComposer *composer,
GAsyncReadyCallback callback,
gpointer user_data)
{
- EHTMLEditor *editor;
GSimpleAsyncResult *simple;
ComposerFlags flags = COMPOSER_FLAG_SAVE_DRAFT;
GtkAction *action;
@@ -6035,11 +6159,6 @@ e_msg_composer_get_message_draft (EMsgComposer *composer,
g_simple_async_result_set_check_cancellable (simple, cancellable);
- editor = e_msg_composer_get_editor (composer);
-
- /* We need to remember composer mode */
- if (e_html_editor_get_mode (editor) == E_CONTENT_EDITOR_MODE_HTML)
- flags |= COMPOSER_FLAG_HTML_MODE;
/* We want to save HTML content everytime when we save as draft */
flags |= COMPOSER_FLAG_SAVE_DRAFT;
diff --git a/src/e-util/e-html-editor.c b/src/e-util/e-html-editor.c
index 7ce754f2df..fa10bc9eba 100644
--- a/src/e-util/e-html-editor.c
+++ b/src/e-util/e-html-editor.c
@@ -1718,18 +1718,26 @@ e_html_editor_set_mode (EHTMLEditor *editor,
if (editor->priv->use_content_editor) {
is_focused = e_content_editor_is_focus (editor->priv->use_content_editor);
- e_content_editor_get_content (editor->priv->use_content_editor,
- E_CONTENT_EDITOR_GET_TO_SEND_HTML |
E_CONTENT_EDITOR_GET_TO_SEND_PLAIN,
- "localhost", NULL,
- e_html_editor_update_content_on_mode_change_cb,
- e_weak_ref_new (editor));
+ if (gtk_widget_get_realized (GTK_WIDGET (editor->priv->use_content_editor))) {
+ /* Transfer also the content between editors */
+ e_content_editor_get_content (editor->priv->use_content_editor,
+ E_CONTENT_EDITOR_GET_TO_SEND_HTML |
E_CONTENT_EDITOR_GET_TO_SEND_PLAIN,
+ "localhost", NULL,
+ e_html_editor_update_content_on_mode_change_cb,
+ e_weak_ref_new (editor));
+ }
gtk_widget_hide (GTK_WIDGET (editor->priv->use_content_editor));
if (E_IS_MARKDOWN_EDITOR (editor->priv->use_content_editor)) {
+ EMarkdownEditor *markdown_editor;
GtkToolbar *toolbar;
- toolbar = e_markdown_editor_get_action_toolbar (E_MARKDOWN_EDITOR
(editor->priv->use_content_editor));
+ markdown_editor = E_MARKDOWN_EDITOR
(editor->priv->use_content_editor);
+
+ e_markdown_editor_set_preview_mode (markdown_editor, FALSE);
+
+ toolbar = e_markdown_editor_get_action_toolbar (markdown_editor);
gtk_container_remove (GTK_CONTAINER (toolbar), GTK_WIDGET
(editor->priv->mode_tool_item));
toolbar = GTK_TOOLBAR (editor->priv->edit_toolbar);
diff --git a/src/e-util/e-markdown-editor.c b/src/e-util/e-markdown-editor.c
index 4126000bb0..29a2b80718 100644
--- a/src/e-util/e-markdown-editor.c
+++ b/src/e-util/e-markdown-editor.c
@@ -21,6 +21,7 @@
#include "e-markdown-editor.h"
struct _EMarkdownEditorPrivate {
+ GtkNotebook *notebook;
GtkTextView *text_view;
EWebView *web_view;
GtkToolbar *action_toolbar;
@@ -1305,7 +1306,6 @@ e_markdown_editor_constructed (GObject *object)
{
EMarkdownEditor *self = E_MARKDOWN_EDITOR (object);
GtkWidget *widget;
- GtkNotebook *notebook;
GtkScrolledWindow *scrolled_window;
guint ii;
@@ -1324,7 +1324,7 @@ e_markdown_editor_constructed (GObject *object)
NULL);
gtk_box_pack_start (GTK_BOX (self), widget, TRUE, TRUE, 0);
- notebook = GTK_NOTEBOOK (widget);
+ self->priv->notebook = GTK_NOTEBOOK (widget);
widget = gtk_scrolled_window_new (NULL, NULL);
g_object_set (G_OBJECT (widget),
@@ -1337,7 +1337,7 @@ e_markdown_editor_constructed (GObject *object)
"vscrollbar-policy", GTK_POLICY_AUTOMATIC,
NULL);
- gtk_notebook_append_page (notebook, widget, gtk_label_new_with_mnemonic (_("_Write")));
+ gtk_notebook_append_page (self->priv->notebook, widget, gtk_label_new_with_mnemonic (_("_Write")));
scrolled_window = GTK_SCROLLED_WINDOW (widget);
@@ -1372,7 +1372,7 @@ e_markdown_editor_constructed (GObject *object)
"vscrollbar-policy", GTK_POLICY_AUTOMATIC,
NULL);
- gtk_notebook_append_page (notebook, widget, gtk_label_new_with_mnemonic (_("_Preview")));
+ gtk_notebook_append_page (self->priv->notebook, widget, gtk_label_new_with_mnemonic (_("_Preview")));
scrolled_window = GTK_SCROLLED_WINDOW (widget);
@@ -1394,7 +1394,7 @@ e_markdown_editor_constructed (GObject *object)
widget = gtk_toolbar_new ();
gtk_toolbar_set_icon_size (GTK_TOOLBAR (widget), GTK_ICON_SIZE_SMALL_TOOLBAR);
gtk_widget_show (widget);
- gtk_notebook_set_action_widget (notebook, widget, GTK_PACK_END);
+ gtk_notebook_set_action_widget (self->priv->notebook, widget, GTK_PACK_END);
self->priv->action_toolbar = GTK_TOOLBAR (widget);
self->priv->is_dark_theme = e_markdown_editor_is_dark_theme (self);
@@ -1422,7 +1422,7 @@ e_markdown_editor_constructed (GObject *object)
}
#ifdef HAVE_MARKDOWN
- g_signal_connect_object (notebook, "switch-page", G_CALLBACK (e_markdown_editor_switch_page_cb),
self, 0);
+ g_signal_connect_object (self->priv->notebook, "switch-page", G_CALLBACK
(e_markdown_editor_switch_page_cb), self, 0);
#endif
g_signal_connect (self, "style-updated", G_CALLBACK (e_markdown_editor_style_updated_cb), NULL);
@@ -1692,3 +1692,46 @@ e_markdown_editor_dup_html (EMarkdownEditor *self)
return NULL;
#endif
}
+
+/**
+ * e_markdown_editor_get_preview_mode:
+ * @self: an #EMarkdownEditor
+ *
+ * Returns: whether the @self is in the preview mode; %FALSE means
+ * it is in the editing mode
+ *
+ * Since: 3.44
+ **/
+gboolean
+e_markdown_editor_get_preview_mode (EMarkdownEditor *self)
+{
+ g_return_val_if_fail (E_IS_MARKDOWN_EDITOR (self), FALSE);
+
+ return gtk_notebook_get_current_page (self->priv->notebook) == 1;
+}
+
+/**
+ * e_markdown_editor_set_preview_mode:
+ * @self: an #EMarkdownEditor
+ * @preview_mode: %TRUE to set the preview mode, %FALSE otherwise
+ *
+ * Sets the @self into the preview mode, when @preview_mode is %TRUE, or
+ * into editing mode, when @preview_mode is %FALSE.
+ *
+ * Note: The request to move to the preview mode can be silently ignored
+ * when the Evolution was not built with the markdown support.
+ *
+ * Since: 3.44
+ **/
+void
+e_markdown_editor_set_preview_mode (EMarkdownEditor *self,
+ gboolean preview_mode)
+{
+ g_return_if_fail (E_IS_MARKDOWN_EDITOR (self));
+
+ #ifdef HAVE_MARKDOWN
+ gtk_notebook_set_current_page (self->priv->notebook, preview_mode ? 1 : 0);
+ #else
+ gtk_notebook_set_current_page (self->priv->notebook, 0);
+ #endif
+}
diff --git a/src/e-util/e-markdown-editor.h b/src/e-util/e-markdown-editor.h
index c42959a36d..c8cc59bc5b 100644
--- a/src/e-util/e-markdown-editor.h
+++ b/src/e-util/e-markdown-editor.h
@@ -59,6 +59,9 @@ void e_markdown_editor_set_text (EMarkdownEditor *self,
const gchar *text);
gchar * e_markdown_editor_dup_text (EMarkdownEditor *self);
gchar * e_markdown_editor_dup_html (EMarkdownEditor *self);
+gboolean e_markdown_editor_get_preview_mode (EMarkdownEditor *self);
+void e_markdown_editor_set_preview_mode (EMarkdownEditor *self,
+ gboolean preview_mode);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]