|
View:
New views
2 Messages
—
Rating Filter:
Alert me
|
|
|
Extend external editor pluginExtend/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@...> [evolution-extend-external-editor-plugin.patch] 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@...> + + * 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@...> 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@...> + * Holger Macht <hmacht@...> + * based on work by Sankar P <psankar@...> * * 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@..."/> <author name="Sankar P" email="sankar2u@..."/> - <_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@...> + + * evolution-composer.ui: + Add menu placeholder for the external editor plugin. + 2008-12-18 Matthew Barnes <mbarnes@...> * e-composer-actions.c: _______________________________________________ Evolution-patches mailing list Evolution-patches@... http://mail.gnome.org/mailman/listinfo/evolution-patches |
|
|
Re: Extend external editor pluginOn Tue, 2009-01-06 at 12:46 +0100, Holger Macht wrote:
> 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). > Patch added to http://bugzilla.gnome.org/show_bug.cgi?id=567145 More comments and review will continue there. Holger, Thanks a lot for the patch :-) > Signed-off-by: Holger Macht <hmacht@...> > _______________________________________________ > Evolution-patches mailing list > Evolution-patches@... > http://mail.gnome.org/mailman/listinfo/evolution-patches -- Sankar _______________________________________________ Evolution-patches mailing list Evolution-patches@... http://mail.gnome.org/mailman/listinfo/evolution-patches |
| Free embeddable forum powered by Nabble | Forum Help |