From c0a255eb90769638d57ae4122932f75c46e4e531 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 11 Sep 2008 15:34:29 +0000 Subject: Merge revisions 36016:36303 from trunk. svn path=/branches/kill-bonobo/; revision=36307 --- plugins/external-editor/external-editor.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'plugins/external-editor/external-editor.c') diff --git a/plugins/external-editor/external-editor.c b/plugins/external-editor/external-editor.c index 698b39ffb9..ecccbf8740 100644 --- a/plugins/external-editor/external-editor.c +++ b/plugins/external-editor/external-editor.c @@ -1,4 +1,25 @@ -/* Sankar P - - GPL V3 or Later */ +/* + * + * 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 + * + * + * Authors: + * Sankar P + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ #ifdef HAVE_CONFIG_H #include -- cgit v1.2.3 From 5a1c48696363e3f3c7ffe11bdffdcad6557f811a Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 20 Jan 2009 04:33:23 +0000 Subject: Untangle some circular dependencies with the composer. Addressbook and calendar no longer depend on the mailer. svn path=/branches/kill-bonobo/; revision=37107 --- plugins/external-editor/external-editor.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'plugins/external-editor/external-editor.c') diff --git a/plugins/external-editor/external-editor.c b/plugins/external-editor/external-editor.c index ecccbf8740..6f5b520465 100644 --- a/plugins/external-editor/external-editor.c +++ b/plugins/external-editor/external-editor.c @@ -198,9 +198,7 @@ async_external_editor (GArray *array) */ 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); -- cgit v1.2.3 From fee5916b60c605ff5086d8fdc2a85c5ea21351f6 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 31 Jan 2009 19:03:12 +0000 Subject: Merge revisions 37108:37199 from trunk. svn path=/branches/kill-bonobo/; revision=37200 --- plugins/external-editor/external-editor.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'plugins/external-editor/external-editor.c') diff --git a/plugins/external-editor/external-editor.c b/plugins/external-editor/external-editor.c index 6f5b520465..5ba4ca7830 100644 --- a/plugins/external-editor/external-editor.c +++ b/plugins/external-editor/external-editor.c @@ -38,7 +38,9 @@ #include #include -#include +#ifdef HAVE_SYS_WAIT_H +# include +#endif #include #include @@ -151,7 +153,11 @@ async_external_editor (GArray *array) return ; } +#ifdef HAVE_SYS_WAIT_H if (WEXITSTATUS (status) != 0) { +#else + if (status) { +#endif d(printf ("\n\nsome problem here with external editor\n\n")); return ; } else { -- cgit v1.2.3 From 3e2ea94186a231bfdd2f3cb33085b8442a7b6b1e Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 27 Apr 2009 11:34:11 +0200 Subject: Define .error files correctly and external-editor crash fix ** Fix for bug #561188 --- plugins/external-editor/external-editor.c | 141 ++++++++++++++++-------------- 1 file changed, 75 insertions(+), 66 deletions(-) (limited to 'plugins/external-editor/external-editor.c') diff --git a/plugins/external-editor/external-editor.c b/plugins/external-editor/external-editor.c index 5ba4ca7830..c541124e53 100644 --- a/plugins/external-editor/external-editor.c +++ b/plugins/external-editor/external-editor.c @@ -54,8 +54,6 @@ void org_gnome_external_editor (EPlugin *ep, EMMenuTargetSelect *select); void ee_editor_command_changed (GtkWidget *textbox); GtkWidget * e_plugin_lib_get_configure_widget (EPlugin *epl); -void async_external_editor (GArray *array); -static gboolean show_composer_dialog (EMsgComposer *composer); /* Utility function to convert an email address to CamelInternetAddress. May be this should belong to CamelInternetAddress.h file itself. */ @@ -132,7 +130,76 @@ e_plugin_lib_get_configure_widget (EPlugin *epl) return vbox; } -void +static gboolean +show_error (const char *id) +{ + if (id) + e_error_run (NULL, id, NULL); + return FALSE; +} + +static gboolean +read_file (char *filename) +{ + gchar *buf; + CamelMimeMessage *message; + EMsgComposer *composer; + + message = camel_mime_message_new (); + + if (filename && g_file_get_contents (filename, &buf, NULL, NULL)) { + gchar **tokens; + int i, j; + + tokens = g_strsplit (buf, "###|||", 6); + + for (i = 1; tokens[i]; ++i) { + + for (j = 0; tokens[i][j] && tokens[i][j] != '\n'; ++j) { + tokens [i][j] = ' '; + } + + if (tokens[i][j] == '\n') + tokens[i][j] = ' '; + + d(printf ("\nstripped off token[%d] is : %s \n", i, tokens[i])); + } + + 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"); + + /* FIXME: We need to make mail-remote working properly. + So that we neednot invoke composer widget at all. + + May be we can do it now itself by invoking local CamelTransport. + But all that is not needed for the first release. + + 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. + */ + + 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); + + gtk_widget_show (GTK_WIDGET (composer)); + + g_strfreev (tokens); + + /* We no longer need that temporary file */ + g_remove (filename); + } + + g_free (filename); + + return FALSE; +} + +static void async_external_editor (GArray *array) { char *filename = NULL; @@ -148,9 +215,9 @@ async_external_editor (GArray *array) 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]); - e_error_run (NULL, "org.gnome.evolution.plugins.external-editor:editor-not-launchable", NULL); + g_idle_add ((GSourceFunc)show_error, "org.gnome.evolution.plugins.external-editor:editor-not-launchable"); g_free (filename); - return ; + return; } #ifdef HAVE_SYS_WAIT_H @@ -159,71 +226,13 @@ async_external_editor (GArray *array) if (status) { #endif d(printf ("\n\nsome problem here with external editor\n\n")); - return ; + g_free (filename); + 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; - - tokens = g_strsplit (buf, "###|||", 6); - - for (i = 1; tokens[i]; ++i) { - - for (j = 0; tokens[i][j] && tokens[i][j] != '\n'; ++j) { - tokens [i][j] = ' '; - } - - if (tokens[i][j] == '\n') - tokens[i][j] = ' '; - - d(printf ("\nstripped off token[%d] is : %s \n", i, tokens[i])); - } - - 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"); - - - /* FIXME: We need to make mail-remote working properly. - So that we neednot invoke composer widget at all. - - May be we can do it now itself by invoking local CamelTransport. - But all that is not needed for the first release. - - 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. - */ - - composer = e_msg_composer_new_with_message (message); - - /* Composer cannot be shown in any random thread. Should happen in main thread */ - g_idle_add ((GSourceFunc) show_composer_dialog, composer); - - g_strfreev (tokens); - - /* We no longer need that temporary file */ - g_remove (filename); - g_free (filename); - } + g_idle_add ((GSourceFunc)read_file, filename); } } -static gboolean -show_composer_dialog (EMsgComposer *composer) -{ - gtk_widget_show (GTK_WIDGET(composer)); - return FALSE; -} - void org_gnome_external_editor (EPlugin *ep, EMMenuTargetSelect *select) { /* The template to be used in the external editor */ -- cgit v1.2.3 From 6f2f7292a7934a93e18d36594a8b9ef8dc4454e7 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 28 Apr 2009 10:57:05 -0400 Subject: Resolve some differences between this branch and master. --- plugins/external-editor/external-editor.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'plugins/external-editor/external-editor.c') diff --git a/plugins/external-editor/external-editor.c b/plugins/external-editor/external-editor.c index c541124e53..a2c86af392 100644 --- a/plugins/external-editor/external-editor.c +++ b/plugins/external-editor/external-editor.c @@ -183,8 +183,6 @@ read_file (char *filename) */ 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); gtk_widget_show (GTK_WIDGET (composer)); -- cgit v1.2.3 From d7e7b7ddd4e86a34ffbf240fdc887b10d363dd12 Mon Sep 17 00:00:00 2001 From: Holger Macht Date: Tue, 28 Apr 2009 20:40:26 +0530 Subject: External Editor rewrite by Holger Macht. Fixes #567145 --- plugins/external-editor/external-editor.c | 389 +++++++++++++++++++----------- 1 file changed, 251 insertions(+), 138 deletions(-) (limited to 'plugins/external-editor/external-editor.c') diff --git a/plugins/external-editor/external-editor.c b/plugins/external-editor/external-editor.c index a2c86af392..a07bb6e80e 100644 --- a/plugins/external-editor/external-editor.c +++ b/plugins/external-editor/external-editor.c @@ -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 + * License along with the program; if not, see * * * Authors: - * Sankar P + * Holger Macht + * based on work by Sankar P * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * @@ -31,11 +32,13 @@ #include #include #include +#include #include #include #include #include +#include #include #ifdef HAVE_SYS_WAIT_H @@ -47,56 +50,48 @@ #include -#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); +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; - - 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; -} +/* used to track when the external editor is active */ +static GThread *editor_thread; -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); } @@ -104,179 +99,297 @@ 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 (); label = gtk_label_new (_("Command to be executed to launch the editor: ")); - help = gtk_label_new (_("For Emacs use \"xemacs\"\nFor VI use \"gvim\"")); + help = gtk_label_new (_("For Emacs use \"xemacs\"\nFor VI use \"gvim -f\"")); 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 gboolean -show_error (const char *id) -{ - if (id) - e_error_run (NULL, id, NULL); - return FALSE; -} - -static gboolean -read_file (char *filename) +static void +enable_disable_composer (EMsgComposer *composer, gboolean enable) { - gchar *buf; - CamelMimeMessage *message; - EMsgComposer *composer; - - message = camel_mime_message_new (); + GtkhtmlEditor *editor; + GtkAction *action; + GtkActionGroup *action_group; - if (filename && g_file_get_contents (filename, &buf, NULL, NULL)) { - gchar **tokens; - int i, j; + g_return_if_fail (E_IS_MSG_COMPOSER (composer)); - tokens = g_strsplit (buf, "###|||", 6); + editor = GTKHTML_EDITOR (composer); - for (i = 1; tokens[i]; ++i) { + if (enable) + gtkhtml_editor_run_command (editor, "editable-on"); + else + gtkhtml_editor_run_command (editor, "editable-off"); - for (j = 0; tokens[i][j] && tokens[i][j] != '\n'; ++j) { - tokens [i][j] = ' '; - } + action = GTKHTML_EDITOR_ACTION_EDIT_MENU (composer); + gtk_action_set_sensitive (action, enable); - if (tokens[i][j] == '\n') - tokens[i][j] = ' '; + action = GTKHTML_EDITOR_ACTION_FORMAT_MENU (composer); + gtk_action_set_sensitive (action, enable); - d(printf ("\nstripped off token[%d] is : %s \n", i, tokens[i])); - } + action = GTKHTML_EDITOR_ACTION_INSERT_MENU (composer); + gtk_action_set_sensitive (action, enable); - 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"); + action_group = gtkhtml_editor_get_action_group (editor, "composer"); + gtk_action_group_set_sensitive (action_group, enable); +} - /* FIXME: We need to make mail-remote working properly. - So that we neednot invoke composer widget at all. +static void +enable_composer (EMsgComposer *composer) +{ + enable_disable_composer (composer, TRUE); +} - May be we can do it now itself by invoking local CamelTransport. - But all that is not needed for the first release. +static void +disable_composer (EMsgComposer *composer) +{ + enable_disable_composer (composer, FALSE); +} - 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. - */ +/* needed because the new thread needs to call g_idle_add () */ +static gboolean +update_composer_text (GArray *array) +{ + EMsgComposer *composer; + gchar *text; - composer = e_msg_composer_new_with_message (message); + composer = g_array_index (array, gpointer, 0); + text = g_array_index (array, gpointer, 1); - gtk_widget_show (GTK_WIDGET (composer)); + e_msg_composer_set_body_text (composer, text, -1); - g_strfreev (tokens); + enable_composer (composer); - /* We no longer need that temporary file */ - g_remove (filename); - } + g_free (text); - g_free (filename); + return FALSE; +} +/* needed because the new thread needs to call g_idle_add () */ +static gboolean +run_error_dialog (gchar *text) +{ + e_error_run (NULL, text, NULL); return FALSE; } -static void -async_external_editor (GArray *array) + +void +async_external_editor (EMsgComposer *composer) { char *filename = NULL; - gchar *argv[5]; int status = 0; + GConfClient *gconf; + gchar *editor_cmd_line = NULL; + gint fd; - argv[0] = g_array_index (array, gpointer, 0); - argv[1] = g_array_index (array, gpointer, 1); - argv[2] = NULL; + 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"); + g_idle_add ((GSourceFunc) run_error_dialog, + "org.gnome.evolution.plugins.external-editor:no-temp-file"); + g_idle_add ((GSourceFunc) enable_composer, composer); + return ; + } + + gconf = gconf_client_get_default (); + editor_cmd_line = gconf_client_get_string (gconf, EDITOR_GCONF_KEY_COMMAND, NULL); + if (!editor_cmd_line) { + if (! (editor_cmd_line = 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_line = g_strdup("gedit"); + } + g_object_unref (gconf); - filename = g_strdup (argv[1]); + editor_cmd_line = g_strconcat(editor_cmd_line, " ", filename, NULL); - if (!g_spawn_sync (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, &status, NULL)) + if (!g_spawn_command_line_sync(editor_cmd_line, NULL, NULL, &status, NULL)) { - g_warning ("Unable to launch %s: ", argv[0]); - g_idle_add ((GSourceFunc)show_error, "org.gnome.evolution.plugins.external-editor:editor-not-launchable"); + g_warning ("Unable to launch %s: ", editor_cmd_line); + g_idle_add ((GSourceFunc) run_error_dialog, + "org.gnome.evolution.plugins.external-editor:editor-not-launchable"); + g_idle_add ((GSourceFunc) enable_composer, composer); + g_free (filename); - return; + g_free (editor_cmd_line); + return ; } - + g_free (editor_cmd_line); + #ifdef HAVE_SYS_WAIT_H if (WEXITSTATUS (status) != 0) { #else if (status) { #endif d(printf ("\n\nsome problem here with external editor\n\n")); - g_free (filename); - return; + g_idle_add ((GSourceFunc) enable_composer, composer); + return ; } else { - g_idle_add ((GSourceFunc)read_file, filename); + gchar *buf; + + if (g_file_get_contents (filename, &buf, NULL, NULL)) { + gchar *htmltext; + GArray *array; + + htmltext = camel_text_to_html(buf, CAMEL_MIME_FILTER_TOHTML_PRE, 0); + + 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); + + g_idle_add ((GSourceFunc) update_composer_text, array); + + /* We no longer need that temporary file */ + g_remove (filename); + g_free (filename); + } } } -void org_gnome_external_editor (EPlugin *ep, EMMenuTargetSelect *select) +static void launch_editor (GtkAction *action, EMsgComposer *composer) { - /* The template to be used in the external editor */ + d(printf ("\n\nexternal_editor plugin is launched \n\n")); - /* README: I have not marked this for translation. - As I might change this string to make it more meaningful and friendlier based on feedback. */ + if (editor_running()) { + d(printf("not opening editor, because it's still running\n")); + return ; + } - 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"; + disable_composer (composer); - gint fd; - char *filename = NULL; - char *editor = NULL; - GConfClient *gconf; - GArray *array; + editor_thread = g_thread_create ((GThreadFunc)async_external_editor, composer, FALSE, NULL); +} - d(printf ("\n\nexternal_editor plugin is launched \n\n")); +static GtkActionEntry entries[] = { + { "ExternalEditor", + GTK_STOCK_EDIT, + N_("Compose in External Editor"), + "e", + N_("Compose in External Editor"), + G_CALLBACK (launch_editor) } +}; - 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 ; +static gboolean +key_press_cb(GtkWidget * widget, GdkEventKey * event, EMsgComposer *composer) +{ + GConfClient *gconf; + gboolean immediately; + + /* we don't want to start the editor on any modifier keys */ + switch (event->keyval) { + case GDK_Alt_L: + case GDK_Alt_R: + case GDK_Super_L: + case GDK_Super_R: + case GDK_Control_L: + case GDK_Control_R: + return FALSE; + default: + break; } gconf = gconf_client_get_default (); - editor = gconf_client_get_string (gconf, EDITOR_GCONF_KEY, NULL); - if (!editor) { + immediately = gconf_client_get_bool (gconf, EDITOR_GCONF_KEY_IMMEDIATE, NULL); + g_object_unref (gconf); + if (!immediately) + return FALSE; - 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"); + launch_editor (NULL, composer); + + return TRUE; +} + +static void +editor_running_thread_func (GThread *thread, gpointer running) +{ + if (thread == editor_thread) + *(gboolean*)running = TRUE; +} + +/* Racy? */ +static gboolean +editor_running (void) +{ + gboolean running = FALSE; + + g_thread_foreach ((GFunc)editor_running_thread_func, &running); + + return running; +} + +static gboolean +delete_cb (GtkWidget *widget, EMsgComposer *composer) +{ + if (editor_running()) { + e_error_run (NULL, "org.gnome.evolution.plugins.external-editor:editor-still-running", NULL); + return TRUE; } - g_object_unref (gconf); - 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); + return FALSE; +} + +gboolean +e_plugin_ui_init (GtkUIManager *manager, EMsgComposer *composer) +{ + GtkhtmlEditor *editor; + GtkHTML *html; + + editor = GTKHTML_EDITOR (composer); + + /* 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); + + html = gtkhtml_editor_get_html (editor); + + g_signal_connect (G_OBJECT(html), "key_press_event", + G_CALLBACK(key_press_cb), composer); - g_thread_create ( (GThreadFunc) async_external_editor, array, FALSE, NULL); + g_signal_connect (G_OBJECT(composer), "delete-event", + G_CALLBACK(delete_cb), composer); - return ; + return TRUE; } -- cgit v1.2.3 From 948235c3d1076dbe6ed2e57a24c16a083bbd9f01 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 27 May 2009 10:29:19 -0400 Subject: Prefer GLib basic types over C types. --- plugins/external-editor/external-editor.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'plugins/external-editor/external-editor.c') diff --git a/plugins/external-editor/external-editor.c b/plugins/external-editor/external-editor.c index a07bb6e80e..10cfdb4fd6 100644 --- a/plugins/external-editor/external-editor.c +++ b/plugins/external-editor/external-editor.c @@ -69,7 +69,7 @@ static GThread *editor_thread; void ee_editor_command_changed (GtkWidget *textbox) { - const char *editor; + const gchar *editor; GConfClient *gconf; editor = gtk_entry_get_text (GTK_ENTRY(textbox)); @@ -101,7 +101,7 @@ e_plugin_lib_get_configure_widget (EPlugin *epl) GtkWidget *vbox, *textbox, *label, *help; GtkWidget *checkbox; GConfClient *gconf; - char *editor; + gchar *editor; gboolean checked; vbox = gtk_vbox_new (FALSE, 10); @@ -209,8 +209,8 @@ run_error_dialog (gchar *text) void async_external_editor (EMsgComposer *composer) { - char *filename = NULL; - int status = 0; + gchar *filename = NULL; + gint status = 0; GConfClient *gconf; gchar *editor_cmd_line = NULL; gint fd; -- cgit v1.2.3 From 433eac7844481b8ceda0bae8bf08f6bb623185b0 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 1 Jun 2009 19:09:19 -0400 Subject: More code cleanup. --- plugins/external-editor/external-editor.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'plugins/external-editor/external-editor.c') diff --git a/plugins/external-editor/external-editor.c b/plugins/external-editor/external-editor.c index 10cfdb4fd6..5d8ae3bfcd 100644 --- a/plugins/external-editor/external-editor.c +++ b/plugins/external-editor/external-editor.c @@ -228,7 +228,7 @@ async_external_editor (EMsgComposer *composer) g_idle_add ((GSourceFunc) run_error_dialog, "org.gnome.evolution.plugins.external-editor:no-temp-file"); g_idle_add ((GSourceFunc) enable_composer, composer); - return ; + return; } gconf = gconf_client_get_default (); @@ -253,7 +253,7 @@ async_external_editor (EMsgComposer *composer) g_free (filename); g_free (editor_cmd_line); - return ; + return; } g_free (editor_cmd_line); @@ -264,7 +264,7 @@ async_external_editor (EMsgComposer *composer) #endif d(printf ("\n\nsome problem here with external editor\n\n")); g_idle_add ((GSourceFunc) enable_composer, composer); - return ; + return; } else { gchar *buf; @@ -294,7 +294,7 @@ static void launch_editor (GtkAction *action, EMsgComposer *composer) if (editor_running()) { d(printf("not opening editor, because it's still running\n")); - return ; + return; } disable_composer (composer); -- cgit v1.2.3 From b0e26e9c5f13c710c7677959cc457158206befe1 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 5 Jun 2009 14:48:29 +0200 Subject: Fix even more compiler warnings and disable one for format strings --- plugins/external-editor/external-editor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins/external-editor/external-editor.c') diff --git a/plugins/external-editor/external-editor.c b/plugins/external-editor/external-editor.c index 5d8ae3bfcd..a7f06b62bf 100644 --- a/plugins/external-editor/external-editor.c +++ b/plugins/external-editor/external-editor.c @@ -226,7 +226,7 @@ async_external_editor (EMsgComposer *composer) } else { g_warning ("Temporary file fd is null"); g_idle_add ((GSourceFunc) run_error_dialog, - "org.gnome.evolution.plugins.external-editor:no-temp-file"); + (gpointer)"org.gnome.evolution.plugins.external-editor:no-temp-file"); g_idle_add ((GSourceFunc) enable_composer, composer); return; } @@ -248,7 +248,7 @@ async_external_editor (EMsgComposer *composer) { g_warning ("Unable to launch %s: ", editor_cmd_line); g_idle_add ((GSourceFunc) run_error_dialog, - "org.gnome.evolution.plugins.external-editor:editor-not-launchable"); + (gpointer)"org.gnome.evolution.plugins.external-editor:editor-not-launchable"); g_idle_add ((GSourceFunc) enable_composer, composer); g_free (filename); -- cgit v1.2.3 From 374bd42f69aca2e132fd854c9619f3d7491f1f96 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sun, 12 Jul 2009 23:33:07 -0400 Subject: Fix excessive whitespace. --- plugins/external-editor/external-editor.c | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins/external-editor/external-editor.c') diff --git a/plugins/external-editor/external-editor.c b/plugins/external-editor/external-editor.c index a7f06b62bf..dcd81650f5 100644 --- a/plugins/external-editor/external-editor.c +++ b/plugins/external-editor/external-editor.c @@ -205,7 +205,6 @@ run_error_dialog (gchar *text) return FALSE; } - void async_external_editor (EMsgComposer *composer) { -- cgit v1.2.3 From 45d475c31b2dbda8033021984ba9a429b9eddf51 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sun, 9 Aug 2009 20:03:24 -0400 Subject: Kill EMMenu and EMPopup. Also finish adapting Templates plugin to EPluginUI. It was still leaning pretty hard on EMPopup. --- plugins/external-editor/external-editor.c | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins/external-editor/external-editor.c') diff --git a/plugins/external-editor/external-editor.c b/plugins/external-editor/external-editor.c index dcd81650f5..2342651fa3 100644 --- a/plugins/external-editor/external-editor.c +++ b/plugins/external-editor/external-editor.c @@ -26,7 +26,6 @@ #include #endif -#include #include #include #include -- cgit v1.2.3 From e1655141406910938698f7d390900b93a40ce602 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 7 Aug 2009 18:44:07 +0200 Subject: Bug #586076 - [external-editor] Pass cursor pos to vim --- plugins/external-editor/external-editor.c | 75 +++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 14 deletions(-) (limited to 'plugins/external-editor/external-editor.c') diff --git a/plugins/external-editor/external-editor.c b/plugins/external-editor/external-editor.c index 2342651fa3..88858c0211 100644 --- a/plugins/external-editor/external-editor.c +++ b/plugins/external-editor/external-editor.c @@ -204,23 +204,47 @@ run_error_dialog (gchar *text) return FALSE; } +static gint +numlines (const gchar *text, gint pos) +{ + gint ctr = 0; + gint lineno = 0; + + while (text && *text && ctr <= pos) { + if (*text == '\n') + lineno++; + + text++; + ctr++; + } + + if (lineno > 0) { + lineno++; + } + + return lineno; +} + void async_external_editor (EMsgComposer *composer) { gchar *filename = NULL; gint status = 0; GConfClient *gconf; - gchar *editor_cmd_line = NULL; - gint fd; + gchar *editor_cmd_line = NULL, *editor_cmd = NULL, *content; + gint fd, position = -1, offset = -1; - fd = g_file_open_tmp (NULL, &filename, NULL); + /* prefix temp files with evo so .*vimrc can be setup to recognize them */ + fd = g_file_open_tmp ("evoXXXXXX", &filename, NULL); if (fd > 0) { + gsize length = 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)); + + /* Push the text (if there is one) from the composer to the file */ + content = gtkhtml_editor_get_text_plain (GTKHTML_EDITOR (composer), &length); + g_file_set_contents (filename, content, length, NULL); } else { g_warning ("Temporary file fd is null"); g_idle_add ((GSourceFunc) run_error_dialog, @@ -230,20 +254,41 @@ async_external_editor (EMsgComposer *composer) } gconf = gconf_client_get_default (); - editor_cmd_line = gconf_client_get_string (gconf, EDITOR_GCONF_KEY_COMMAND, NULL); - if (!editor_cmd_line) { - if (! (editor_cmd_line = g_strdup(g_getenv ("EDITOR"))) ) + 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_line = g_strdup("gedit"); + editor_cmd = g_strdup ("gedit"); } g_object_unref (gconf); - editor_cmd_line = g_strconcat(editor_cmd_line, " ", filename, NULL); + if (g_strrstr (editor_cmd, "vim") != NULL + && gtk_html_get_cursor_pos (gtkhtml_editor_get_html (GTKHTML_EDITOR (composer)), &position, &offset) + && position >= 0 && offset >= 0) { + gchar *tmp = editor_cmd; + gint lineno; + gboolean set_nofork; + + set_nofork = g_strrstr (editor_cmd, "gvim") != NULL; + /* increment 1 so that entering vim insert mode places you in the same + * entry position you were at in the html */ + offset++; + + /* calculate the line number that the cursor is in */ + lineno = numlines (content, position); + + editor_cmd = g_strdup_printf ("%s \"+call cursor(%d,%d)\"%s%s", tmp, lineno, offset, set_nofork ? " " : "", set_nofork ? "--nofork" : ""); + + g_free (tmp); + } + + g_free (content); + + editor_cmd_line = g_strconcat (editor_cmd, " ", filename, NULL); - if (!g_spawn_command_line_sync(editor_cmd_line, NULL, NULL, &status, NULL)) - { + if (!g_spawn_command_line_sync (editor_cmd_line, NULL, NULL, &status, NULL)) { g_warning ("Unable to launch %s: ", editor_cmd_line); g_idle_add ((GSourceFunc) run_error_dialog, (gpointer)"org.gnome.evolution.plugins.external-editor:editor-not-launchable"); @@ -251,9 +296,11 @@ async_external_editor (EMsgComposer *composer) g_free (filename); g_free (editor_cmd_line); + g_free (editor_cmd); return; } g_free (editor_cmd_line); + g_free (editor_cmd); #ifdef HAVE_SYS_WAIT_H if (WEXITSTATUS (status) != 0) { -- cgit v1.2.3