[evolution-patches] Extend external editor plugin
- From: Holger Macht <hmacht suse de>
- To: evolution-patches gnome org
- Subject: [evolution-patches] Extend external editor plugin
- Date: Tue, 06 Jan 2009 12:46:31 +0100
Extend/rewrite the external editor plugin. Now you are able to launch
the external editor directly from the mail composer, either from the
menu or by a shortcut.
Furthermore, add a gconf configuration option to automatically launch
the editor when the user starts typing in the composer (kmail way of
doing it).
Signed-off-by: Holger Macht <hmacht suse de>
Index: plugins/external-editor/apps-evolution-external-editor.schemas.in
===================================================================
--- plugins/external-editor/apps-evolution-external-editor.schemas.in (Revision 36999)
+++ plugins/external-editor/apps-evolution-external-editor.schemas.in (Arbeitskopie)
@@ -10,6 +10,16 @@
<short>Default External Editor</short>
<long>The default command that must be used as the editor.</long>
</locale>
+
+ <key>/schemas/apps/evolution/eplugin/external-editor/launch-on-key-press</key>
+ <applyto>/apps/evolution/eplugin/external-editor/launch-on-key-press</applyto>
+ <owner>evolution-mail</owner>
+ <type>bool</type>
+ <default>false</default>
+ <locale name="C">
+ <short>Automatically launch when a new mail is edited</short>
+ <long>Automatically launch editor when key is pressed in the mail composer</long>
+ </locale>
</schema>
</schemalist>
</gconfschemafile>
Index: plugins/external-editor/ChangeLog
===================================================================
--- plugins/external-editor/ChangeLog (Revision 36999)
+++ plugins/external-editor/ChangeLog (Arbeitskopie)
@@ -1,3 +1,17 @@
+2009-01-06 Holger Macht <hmacht suse de>
+
+ * org-gnome-external-editor.eplug.xml:
+ Add hook for the editor to be launched from the menu.
+
+ * org-gnome-external-editor-errors.xml:
+ Add error messages.
+
+ * external-editor.c:
+ Extend the external editor plugin to be launched from composer.
+
+ * apps-evolution-external-editor.schemas.in:
+ Add gconf key for external editor "auto launch feature"
+
2008-08-27 Sankar P <psankar novell com>
License Changes
Index: plugins/external-editor/external-editor.c
===================================================================
--- plugins/external-editor/external-editor.c (Revision 36999)
+++ plugins/external-editor/external-editor.c (Arbeitskopie)
@@ -11,11 +11,12 @@
* 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/>
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
* Authors:
- * Sankar P <psankar novell com>
+ * Holger Macht <hmacht suse de>
+ * based on work by Sankar P <psankar novell com>
*
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
@@ -31,6 +32,7 @@
#include <mail/mail-config.h>
#include <e-util/e-error.h>
#include <e-msg-composer.h>
+#include <camel/camel-mime-filter-tohtml.h>
#include <glib/gi18n-lib.h>
#include <glib-object.h>
@@ -45,67 +47,59 @@
#include <gconf/gconf-client.h>
-#define d(x)
+#define d(x)
-#define EDITOR_GCONF_KEY "/apps/evolution/eplugin/external-editor/editor-command"
+#define EDITOR_GCONF_KEY_COMMAND "/apps/evolution/eplugin/external-editor/editor-command"
+#define EDITOR_GCONF_KEY_IMMEDIATE "/apps/evolution/eplugin/external-editor/launch-on-key-press"
-void org_gnome_external_editor (EPlugin *ep, EMMenuTargetSelect *select);
-void ee_editor_command_changed (GtkWidget *textbox);
+gboolean e_plugin_ui_init (GtkUIManager *manager, EMsgComposer *composer);
GtkWidget * e_plugin_lib_get_configure_widget (EPlugin *epl);
-void async_external_editor (GArray *array);
-static gboolean show_composer_dialog (EMsgComposer *composer);
+static void ee_editor_command_changed (GtkWidget *textbox);
+static void ee_editor_immediate_launch_changed (GtkWidget *checkbox);
+static void async_external_editor (EMsgComposer *composer);
+static gboolean editor_running (void);
+static gboolean key_press_cb(GtkWidget * widget, GdkEventKey * event, EMsgComposer *composer);
-/* Utility function to convert an email address to CamelInternetAddress.
-May be this should belong to CamelInternetAddress.h file itself. */
-static CamelInternetAddress * convert_to_camel_internet_address (char * emails)
-{
- CamelInternetAddress *cia = camel_internet_address_new();
- gchar **address_tokens = NULL;
- int i;
+/* used to track when the external editor is active */
+static GThread *editor_thread;
- d(printf ("\n\aconvert called with : [%s] \n\a", emails));
-
- emails = g_strstrip (emails);
-
- if (emails && strlen (emails) > 1) {
- address_tokens = g_strsplit (emails, ",", 0);
-
- if (address_tokens) {
- for (i = 0; address_tokens[i]; ++i) {
- camel_internet_address_add (cia, " ", address_tokens [i]);
- d(printf ("\nAdding camel_internet_address[%s] \n", address_tokens [i]));
- }
- g_strfreev (address_tokens);
-
- g_free (emails);
- return cia;
- }
- }
- camel_object_unref (cia);
- g_free (emails);
- return NULL;
-}
-
-void ee_editor_command_changed (GtkWidget *textbox)
+void
+ee_editor_command_changed (GtkWidget *textbox)
{
const char *editor;
GConfClient *gconf;
editor = gtk_entry_get_text (GTK_ENTRY(textbox));
d(printf ("\n\aeditor is : [%s] \n\a", editor));
-
+
/* gconf access for every key-press. Sucky ? */
gconf = gconf_client_get_default ();
- gconf_client_set_string (gconf, EDITOR_GCONF_KEY, editor, NULL);
+ gconf_client_set_string (gconf, EDITOR_GCONF_KEY_COMMAND, editor, NULL);
g_object_unref (gconf);
}
+void
+ee_editor_immediate_launch_changed (GtkWidget *checkbox)
+{
+ gboolean immediately;
+ GConfClient *gconf;
+
+ immediately = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox));
+ d(printf ("\n\aimmediate launch is : [%d] \n\a", immediately));
+
+ gconf = gconf_client_get_default ();
+ gconf_client_set_bool (gconf, EDITOR_GCONF_KEY_IMMEDIATE, immediately, NULL);
+ g_object_unref (gconf);
+}
+
GtkWidget *
e_plugin_lib_get_configure_widget (EPlugin *epl)
{
GtkWidget *vbox, *textbox, *label, *help;
+ GtkWidget *checkbox;
GConfClient *gconf;
char *editor;
+ gboolean checked;
vbox = gtk_vbox_new (FALSE, 10);
textbox = gtk_entry_new ();
@@ -113,32 +107,128 @@
help = gtk_label_new (_("For Emacs use \"xemacs\"\nFor VI use \"gvim\""));
gconf = gconf_client_get_default ();
- editor = gconf_client_get_string (gconf, EDITOR_GCONF_KEY, NULL);
+ editor = gconf_client_get_string (gconf, EDITOR_GCONF_KEY_COMMAND, NULL);
if (editor) {
gtk_entry_set_text (GTK_ENTRY(textbox), editor);
g_free (editor);
}
+
+ checkbox = gtk_check_button_new_with_label (
+ _("Automatically launch when a new mail is edited"));
+ checked = gconf_client_get_bool (gconf, EDITOR_GCONF_KEY_IMMEDIATE, NULL);
+ if (checked)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbox), TRUE);
g_object_unref (gconf);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), textbox, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), help, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), checkbox, FALSE, FALSE, 0);
g_signal_connect (textbox, "changed", G_CALLBACK(ee_editor_command_changed), textbox);
-
+
+ g_signal_connect (checkbox, "toggled",
+ G_CALLBACK(ee_editor_immediate_launch_changed), checkbox);
+
gtk_widget_show_all (vbox);
return vbox;
}
+static void
+enable_disable_composer (EMsgComposer *composer, gboolean enable)
+{
+ GtkhtmlEditor *editor;
+ GtkAction *action;
+ GtkActionGroup *action_group;
+
+ g_return_if_fail (E_IS_MSG_COMPOSER (composer));
+
+ editor = GTKHTML_EDITOR (composer);
+
+ if (enable)
+ gtkhtml_editor_run_command (editor, "editable-on");
+ else
+ gtkhtml_editor_run_command (editor, "editable-off");
+
+ action = GTKHTML_EDITOR_ACTION_EDIT_MENU (composer);
+ gtk_action_set_sensitive (action, enable);
+
+ action = GTKHTML_EDITOR_ACTION_FORMAT_MENU (composer);
+ gtk_action_set_sensitive (action, enable);
+
+ action = GTKHTML_EDITOR_ACTION_INSERT_MENU (composer);
+ gtk_action_set_sensitive (action, enable);
+
+ action_group = gtkhtml_editor_get_action_group (editor, "composer");
+ gtk_action_group_set_sensitive (action_group, enable);
+}
+
+static void enable_composer (EMsgComposer *composer)
+{
+ enable_disable_composer (composer, TRUE);
+}
+
+static void disable_composer (EMsgComposer *composer)
+{
+ enable_disable_composer (composer, FALSE);
+}
+
+static gboolean
+update_composer_text (GArray *array)
+{
+ EMsgComposer *composer;
+ gchar *text;
+
+ composer = g_array_index (array, gpointer, 0);
+ text = g_array_index (array, gpointer, 1);
+
+ e_msg_composer_set_body_text (composer, text, -1);
+
+ enable_composer (composer);
+
+ g_free (text);
+
+ return FALSE;
+}
+
void
-async_external_editor (GArray *array)
+async_external_editor (EMsgComposer *composer)
{
char *filename = NULL;
gchar *argv[5];
int status = 0;
+ GConfClient *gconf;
+ char *editor_cmd = NULL;
+ gint fd;
- argv[0] = g_array_index (array, gpointer, 0);
- argv[1] = g_array_index (array, gpointer, 1);
+ fd = g_file_open_tmp (NULL, &filename, NULL);
+ if (fd > 0) {
+ close (fd);
+ /* Push the text (if there is one) from the composer to the file */
+ g_file_set_contents (filename, gtkhtml_editor_get_text_plain(
+ GTKHTML_EDITOR(composer), NULL),
+ -1, NULL);
+ d(printf ("\n\aTemporary-file Name is : [%s] \n\a", filename));
+ } else {
+ g_warning ("Temporary file fd is null");
+ e_error_run (NULL, "org.gnome.evolution.plugins.external-editor:no-temp-file", NULL);
+ g_idle_add ((GSourceFunc) enable_composer, composer);
+ return ;
+ }
+
+ gconf = gconf_client_get_default ();
+ editor_cmd = gconf_client_get_string (gconf, EDITOR_GCONF_KEY_COMMAND, NULL);
+ if (!editor_cmd) {
+ if (! (editor_cmd = g_strdup(g_getenv ("EDITOR"))) )
+ /* Make gedit the default external editor,
+ if the default schemas are not installed
+ and no $EDITOR is set. */
+ editor_cmd = g_strdup("gedit");
+ }
+ g_object_unref (gconf);
+
+ argv[0] = editor_cmd;
+ argv[1] = filename;
argv[2] = NULL;
filename = g_strdup (argv[1]);
@@ -146,126 +236,139 @@
if (!g_spawn_sync (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, &status, NULL))
{
g_warning ("Unable to launch %s: ", argv[0]);
+ printf("doing error\n");
e_error_run (NULL, "org.gnome.evolution.plugins.external-editor:editor-not-launchable", NULL);
+ printf("error done\n");
g_free (filename);
+ printf("unable to launch\n");
+ enable_composer (composer);
return ;
}
-
+
if (WEXITSTATUS (status) != 0) {
d(printf ("\n\nsome problem here with external editor\n\n"));
+ g_idle_add ((GSourceFunc) enable_composer, composer);
return ;
} else {
gchar *buf;
- CamelMimeMessage *message;
- EMsgComposer *composer;
- message = camel_mime_message_new ();
-
if (g_file_get_contents (filename, &buf, NULL, NULL)) {
- gchar **tokens;
- int i, j;
+ gchar *htmltext;
+ GArray *array;
- tokens = g_strsplit (buf, "###|||", 6);
+ htmltext = camel_text_to_html(buf, CAMEL_MIME_FILTER_TOHTML_PRE, 0);
- for (i = 1; tokens[i]; ++i) {
+ array = g_array_sized_new (TRUE, TRUE,
+ sizeof (gpointer), 2 * sizeof(gpointer));
+ array = g_array_append_val (array, composer);
+ array = g_array_append_val (array, htmltext);
- for (j = 0; tokens[i][j] && tokens[i][j] != '\n'; ++j) {
- tokens [i][j] = ' ';
- }
+ g_idle_add ((GSourceFunc) update_composer_text, array);
- if (tokens[i][j] == '\n')
- tokens[i][j] = ' ';
+ /* We no longer need that temporary file */
+ g_remove (filename);
+ g_free (filename);
+ }
+ }
- d(printf ("\nstripped off token[%d] is : %s \n", i, tokens[i]));
- }
+ return ;
+}
- camel_mime_message_set_recipients (message, "To", convert_to_camel_internet_address(g_strchug(g_strdup(tokens[1]))));
- camel_mime_message_set_recipients (message, "Cc", convert_to_camel_internet_address(g_strchug(g_strdup(tokens[2]))));
- camel_mime_message_set_recipients (message, "Bcc", convert_to_camel_internet_address(g_strchug(g_strdup(tokens[3]))));
- camel_mime_message_set_subject (message, tokens[4]);
- camel_mime_part_set_content ((CamelMimePart *)message, tokens [5], strlen (tokens [5]), "text/plain");
+static void launch_editor (GtkAction *action, EMsgComposer *composer)
+{
+ d(printf ("\n\nexternal_editor plugin is launched \n\n"));
+ if (editor_running()) {
+ printf("not opening editor, because it's still running\n");
+ return ;
+ }
- /* FIXME: We need to make mail-remote working properly.
- So that we neednot invoke composer widget at all.
+ disable_composer (composer);
- May be we can do it now itself by invoking local CamelTransport.
- But all that is not needed for the first release.
+ editor_thread = g_thread_create ((GThreadFunc)async_external_editor, composer, FALSE, NULL);
+}
- People might want to format mails using their editor (80 cols width etc.)
- But might want to use evolution addressbook for auto-completion etc.
- So starting the composer window anyway.
- */
+static GtkActionEntry entries[] = {
- composer = e_msg_composer_new_with_message (message);
- g_signal_connect (GTK_OBJECT (composer), "send", G_CALLBACK (em_utils_composer_send_cb), NULL);
- g_signal_connect (GTK_OBJECT (composer), "save-draft", G_CALLBACK (em_utils_composer_save_draft_cb), NULL);
-
- /* Composer cannot be shown in any random thread. Should happen in main thread */
- g_idle_add ((GSourceFunc) show_composer_dialog, composer);
+ { "ExternalEditor",
+ GTK_STOCK_EDIT,
+ N_("Compose in External Editor"),
+ "<Shift><Control>e",
+ N_("Compose in External Editor"),
+ G_CALLBACK (launch_editor) }
+};
- g_strfreev (tokens);
+static gboolean
+key_press_cb(GtkWidget * widget, GdkEventKey * event, EMsgComposer *composer)
+{
+ GConfClient *gconf;
+ gboolean immediately;
- /* We no longer need that temporary file */
- g_remove (filename);
- g_free (filename);
- }
+ gconf = gconf_client_get_default ();
+ immediately = gconf_client_get_bool (gconf, EDITOR_GCONF_KEY_IMMEDIATE, NULL);
+ g_object_unref (gconf);
+ if (!immediately)
+ return FALSE;
+
+ launch_editor (NULL, composer);
+
+ return TRUE;
+}
+
+static void
+editor_running_thread_func (GThread *thread, gpointer running)
+{
+ printf("checking thread\n");
+ if (thread == editor_thread) {
+ printf("editor still running!!!!!!\n");
+ *(gboolean*)running = TRUE;
}
}
+/* Racy? */
static gboolean
-show_composer_dialog (EMsgComposer *composer)
+editor_running (void)
{
- gtk_widget_show (GTK_WIDGET(composer));
- return FALSE;
+ gboolean running = FALSE;
+
+ g_thread_foreach ((GFunc)editor_running_thread_func, &running);
+ printf("returning %d\n", running);
+
+ return running;
}
-void org_gnome_external_editor (EPlugin *ep, EMMenuTargetSelect *select)
+static gboolean
+delete_cb (GtkWidget *widget, EMsgComposer *composer)
{
- /* The template to be used in the external editor */
+ if (editor_running()) {
+ printf("composer: %p , widget: %p\n", composer, widget);
+ e_error_run (NULL, "org.gnome.evolution.plugins.external-editor:editor-still-running", NULL);
+ return TRUE;
+ }
- /* README: I have not marked this for translation.
- As I might change this string to make it more meaningful and friendlier based on feedback. */
+ return FALSE;
+}
- char template[] = "###|||Insert , seperated TO addresses below this line. Do not edit or delete this line. Optional field\n\n###||| Insert , seperated CC addresses below this line. Do not edit or delete this line. Optional field\n\n###|||Insert , seperated BCC addresses below this line. Do not edit or delete this line. Optional field\n\n###|||Insert SUBJECT below this line. Do not edit or delete this line. Optional field\n\n###|||Insert BODY of mail below this line. Do not edit or delete this line.\n\n";
+gboolean
+e_plugin_ui_init (GtkUIManager *manager, EMsgComposer *composer)
+{
+ GtkhtmlEditor *editor;
+ GtkHTML *html;
- gint fd;
- char *filename = NULL;
- char *editor = NULL;
- GConfClient *gconf;
- GArray *array;
+ editor = GTKHTML_EDITOR (composer);
- d(printf ("\n\nexternal_editor plugin is launched \n\n"));
+ /* Add actions to the "composer" action group. */
+ gtk_action_group_add_actions (
+ gtkhtml_editor_get_action_group (editor, "composer"),
+ entries, G_N_ELEMENTS (entries), composer);
- fd = g_file_open_tmp (NULL, &filename, NULL);
- if (fd > 0) {
- close (fd);
- /* Push the template contents to the intermediate file */
- g_file_set_contents (filename, template, strlen (template), NULL);
- d(printf ("\n\aTemporary-file Name is : [%s] \n\a", filename));
- } else {
- g_warning ("Temporary file fd is null");
- e_error_run (NULL, "org.gnome.evolution.plugins.external-editor:no-temp-file", NULL);
- return ;
- }
+ html = gtkhtml_editor_get_html (editor);
- gconf = gconf_client_get_default ();
- editor = gconf_client_get_string (gconf, EDITOR_GCONF_KEY, NULL);
- if (!editor) {
+ g_signal_connect (G_OBJECT(html), "key_press_event",
+ G_CALLBACK(key_press_cb), composer);
- if (! (editor = g_strdup(g_getenv ("EDITOR"))) )
- /* Make gedit the default external editor,
- if the default schemas are not installed
- and no $EDITOR is set. */
- editor = g_strdup("gedit");
- }
- g_object_unref (gconf);
+ g_signal_connect (G_OBJECT(composer), "delete-event",
+ G_CALLBACK(delete_cb), composer);
- array = g_array_sized_new (TRUE, TRUE, sizeof (gpointer), 2 * sizeof(gpointer));
- array = g_array_append_val (array, editor);
- array = g_array_append_val (array, filename);
-
- g_thread_create ( (GThreadFunc) async_external_editor, array, FALSE, NULL);
-
- return ;
+ return TRUE;
}
Index: plugins/external-editor/org-gnome-external-editor-errors.xml
===================================================================
--- plugins/external-editor/org-gnome-external-editor-errors.xml (Revision 36999)
+++ plugins/external-editor/org-gnome-external-editor-errors.xml (Arbeitskopie)
@@ -1,14 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<error-list domain="org.gnome.evolution.plugins.external-editor">
-
+
<error id="editor-not-launchable" type="error">
- <_primary>Editor not launchable</_primary>
- <_secondary>The external editor set in your plugin preferences cannot be launched. Try setting a different editor.</_secondary>
+ <primary>Editor not launchable</primary>
+ <secondary>The external editor set in your plugin preferences cannot be launched. Try setting a different editor.</secondary>
</error>
<error id="no-temp-file" type="error">
- <_primary>Cannot create Temporary File</_primary>
- <_secondary>Evolution is unable to create a temporary file to save your mail. Retry later.</_secondary>
+ <primary>Cannot create Temporary File</primary>
+ <secondary>Evolution is unable to create a temporary file to save your mail. Retry later.</secondary>
</error>
+ <error id="editor-still-running" type="error">
+ <primary>External editor still running</primary>
+ <secondary>The external editor is still running. The mail composer window cannot be closed as long as the editor is active.</secondary>
+ </error>
+
</error-list>
Index: plugins/external-editor/org-gnome-external-editor.eplug.xml
===================================================================
--- plugins/external-editor/org-gnome-external-editor.eplug.xml (Revision 36999)
+++ plugins/external-editor/org-gnome-external-editor.eplug.xml (Arbeitskopie)
@@ -1,27 +1,25 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<e-plugin-list>
- <!-- the path to the shared library -->
- <e-plugin
- id="org.gnome.plugin.external.editor"
- type="shlib"
- location="@PLUGINDIR@/liborg-gnome-external-editor SOEXT@"
- _name="External Editor">
+ <e-plugin type="shlib"
+ location="@PLUGINDIR@/liborg-gnome-external-editor SOEXT@"
+ id="org.gnome.plugin.external.editor" name="External Editor">
+ <author name="Holger Macht" email="hmacht suse de"/>
<author name="Sankar P" email="sankar2u gmail com"/>
- <_description>A plugin for using an external editor as the composer. You can send only plain-text messages.</_description>
+ <description>A plugin for using an external editor as the composer. You can send only plain-text messages.</description>
- <hook class="org.gnome.evolution.shell.bonobomenu:1.0">
+ <hook class="org.gnome.evolution.ui:1.0">
+ <ui-manager id="org.gnome.evolution.composer">
+ <menubar name='main-menu'>
+ <placeholder name='pre-edit-menu'>
+ <menu action='file-menu'>
+ <placeholder name="external-editor-holder">
+ <menuitem action="ExternalEditor"/>
+ </placeholder>
+ </menu>
+ </placeholder>
+ </menubar>
+ </ui-manager>
+ </hook>
- <menu id="org.gnome.evolution.shell" target="shell">
- <!-- the path to the bonobo menu description -->
- <ui file="@PLUGINDIR@/org-gnome-external-editor.xml"/>
- <item
- type="item"
- verb="EPExtEditor"
- path="/commands/EPExtEditor"
- activate="org_gnome_external_editor"/>
- </menu>
-
- </hook>
-
</e-plugin>
</e-plugin-list>
Index: plugins/external-editor/Makefile.am
===================================================================
--- plugins/external-editor/Makefile.am (Revision 36999)
+++ plugins/external-editor/Makefile.am (Arbeitskopie)
@@ -17,8 +17,7 @@
errordir = $(privdatadir)/errors
plugin_DATA = \
- org-gnome-external-editor.eplug \
- org-gnome-external-editor.xml
+ org-gnome-external-editor.eplug
plugin_LTLIBRARIES = liborg-gnome-external-editor.la
@@ -43,7 +42,6 @@
EXTRA_DIST = \
org-gnome-external-editor.eplug.xml \
org-gnome-external-editor-errors.xml \
- org-gnome-external-editor.xml \
$(schema_in_files)
BUILT_SOURCES = org-gnome-external-editor.eplug \
Index: composer/evolution-composer.ui
===================================================================
--- composer/evolution-composer.ui (Revision 36999)
+++ composer/evolution-composer.ui (Arbeitskopie)
@@ -11,6 +11,9 @@
<menuitem action='save-draft'/>
<placeholder name='template-holder'/>
<separator/>
+ <placeholder name='external-editor-holder'/>
+ <separator/>
+ <separator/>
<menuitem action='print-preview'/>
<menuitem action='print'/>
<separator/>
Index: composer/ChangeLog
===================================================================
--- composer/ChangeLog (Revision 36999)
+++ composer/ChangeLog (Arbeitskopie)
@@ -1,3 +1,8 @@
+2009-01-06 Holger Macht <hmacht suse de>
+
+ * evolution-composer.ui:
+ Add menu placeholder for the external editor plugin.
+
2008-12-18 Matthew Barnes <mbarnes redhat com>
* e-composer-actions.c:
[Date Prev][
Date Next] [Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]