Mac-Cyrillic menu updates. patch by Anton Butanaev
[claws.git] / src / compose.c
index 8c7952bca5473431e62d62f502cb5ed4ad84a143..ab951c4f54176e2368b60db1e8adfa74d9c6add5 100644 (file)
@@ -84,7 +84,6 @@
 #include "procmime.h"
 #include "statusbar.h"
 #include "about.h"
-#include "base64.h"
 #include "quoted-printable.h"
 #include "codeconv.h"
 #include "utils.h"
@@ -563,6 +562,7 @@ static void compose_attach_update_label(Compose *compose);
 static void compose_set_folder_prefs(Compose *compose, FolderItem *folder,
                                     gboolean respect_default_to);
 static void compose_subject_entry_activated(GtkWidget *widget, gpointer data);
+static void from_name_activate_cb(GtkWidget *widget, gpointer data);
 
 static GtkActionEntry compose_popup_entries[] =
 {
@@ -737,6 +737,7 @@ static GtkRadioActionEntry compose_radio_enc_entries[] =
        ENC_ACTION(CS_ISO_8859_9, C_ISO_8859_9, N_("Turkish (ISO-8859-_9)")), /* RADIO compose_set_encoding_cb */
        ENC_ACTION("Cyrillic/"CS_ISO_8859_5, C_ISO_8859_5, "ISO-8859-_5"), /* RADIO compose_set_encoding_cb */
        ENC_ACTION("Cyrillic/"CS_KOI8_R, C_KOI8_R, "KOI8-_R"), /* RADIO compose_set_encoding_cb */
+       ENC_ACTION("Cyrillic/"CS_MACCYR, C_MACCYR, "_Mac-Cyrillic"), /* RADIO compose_set_encoding_cb */
        ENC_ACTION("Cyrillic/"CS_KOI8_U, C_KOI8_U, "KOI8-_U"), /* RADIO compose_set_encoding_cb */
        ENC_ACTION("Cyrillic/"CS_WINDOWS_1251, C_WINDOWS_1251, "Windows-1251"), /* RADIO compose_set_encoding_cb */
        ENC_ACTION("Japanese/"CS_ISO_2022_JP, C_ISO_2022_JP, "ISO-2022-_JP"), /* RADIO compose_set_encoding_cb */
@@ -3578,6 +3579,7 @@ static ComposeInsertResult compose_insert_file(Compose *compose, const gchar *fi
        struct stat file_stat;
        int ret;
        GString *file_contents = NULL;
+       ComposeInsertResult result = COMPOSE_INSERT_SUCCESS;
 
        cm_return_val_if_fail(file != NULL, COMPOSE_INSERT_NO_FILE);
 
@@ -3643,9 +3645,17 @@ static ComposeInsertResult compose_insert_file(Compose *compose, const gchar *fi
 
                if (g_utf8_validate(buf, -1, NULL) == TRUE)
                        str = g_strdup(buf);
-               else
+               else {
+                       codeconv_set_strict(TRUE);
                        str = conv_codeset_strdup
                                (buf, cur_encoding, CS_INTERNAL);
+                       codeconv_set_strict(FALSE);
+
+                       if (!str) {
+                               result = COMPOSE_INSERT_INVALID_CHARACTER;
+                               break;
+                       }
+               }
                if (!str) continue;
 
                /* strip <CR> if DOS/Windows file,
@@ -3661,20 +3671,22 @@ static ComposeInsertResult compose_insert_file(Compose *compose, const gchar *fi
                g_free(str);
        }
 
-       gtk_text_buffer_insert(buffer, &iter, file_contents->str, -1);
-       g_string_free(file_contents, TRUE);
+       if (result == COMPOSE_INSERT_SUCCESS) {
+               gtk_text_buffer_insert(buffer, &iter, file_contents->str, -1);
 
-       compose_changed_cb(NULL, compose);
-       g_signal_handlers_unblock_by_func(G_OBJECT(buffer),
-                                         G_CALLBACK(text_inserted),
-                                         compose);
-       compose->autowrap = prev_autowrap;
-       if (compose->autowrap)
-               compose_wrap_all(compose);
+               compose_changed_cb(NULL, compose);
+               g_signal_handlers_unblock_by_func(G_OBJECT(buffer),
+                                                 G_CALLBACK(text_inserted),
+                                                 compose);
+               compose->autowrap = prev_autowrap;
+               if (compose->autowrap)
+                       compose_wrap_all(compose);
+       }
 
+       g_string_free(file_contents, TRUE);
        fclose(fp);
 
-       return COMPOSE_INSERT_SUCCESS;
+       return result;
 }
 
 static gboolean compose_attach_append(Compose *compose, const gchar *file,
@@ -6862,7 +6874,11 @@ static void compose_create_header_entry(Compose *compose)
        g_signal_connect(G_OBJECT(gtk_bin_get_child(GTK_BIN(combo))), "grab_focus",
                         G_CALLBACK(compose_grab_focus_cb), compose);
        gtk_widget_show(combo);
-       
+
+       /* Putting only the combobox child into focus chain of its parent causes
+        * the parent to be skipped when changing focus via Tab or Shift+Tab.
+        * This eliminates need to pres Tab twice in order to really get from the
+        * combobox to next widget. */
        GList *l = NULL;
        l = g_list_prepend(l, gtk_bin_get_child(GTK_BIN(combo)));
        gtk_container_set_focus_chain(GTK_CONTAINER(combo), l);
@@ -7068,9 +7084,9 @@ static GtkWidget *compose_create_header(Compose *compose)
 
        header_table = gtk_table_new(2, 2, FALSE);
        gtk_widget_show(header_table);
-       gtk_container_set_border_width(GTK_CONTAINER(header_table), BORDER_WIDTH);
+       gtk_container_set_border_width(GTK_CONTAINER(header_table), 0);
        gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(header_scrolledwin), header_table);
-       gtk_viewport_set_shadow_type(GTK_VIEWPORT(gtk_bin_get_child(GTK_BIN((header_scrolledwin)))), GTK_SHADOW_NONE);
+       gtk_viewport_set_shadow_type(GTK_VIEWPORT(gtk_bin_get_child(GTK_BIN(header_scrolledwin))), GTK_SHADOW_NONE);
 
        gtk_table_attach(GTK_TABLE(header_table_main), header_scrolledwin,
                                  0, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 2);
@@ -7643,6 +7659,7 @@ static Compose *compose_create(PrefsAccount *account,
        MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Options/Encoding", "Cyrillic", "Options/Encoding/Cyrillic", GTK_UI_MANAGER_MENU)
        MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Options/Encoding/Cyrillic", CS_ISO_8859_5, "Options/Encoding/Cyrillic/"CS_ISO_8859_5, GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Options/Encoding/Cyrillic", CS_KOI8_R, "Options/Encoding/Cyrillic/"CS_KOI8_R, GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Options/Encoding/Cyrillic", CS_MACCYR, "Options/Encoding/Cyrillic/"CS_MACCYR, GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Options/Encoding/Cyrillic", CS_KOI8_U, "Options/Encoding/Cyrillic/"CS_KOI8_U, GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Options/Encoding/Cyrillic", CS_WINDOWS_1251, "Options/Encoding/Cyrillic/"CS_WINDOWS_1251, GTK_UI_MANAGER_MENUITEM)
 
@@ -7741,7 +7758,7 @@ static Compose *compose_create(PrefsAccount *account,
        gtk_container_set_border_width(GTK_CONTAINER(subject), 0);
        gtk_widget_show(subject);
 
-       label = gtk_label_new_with_mnemonic(_("Subject:"));
+       label = gtk_label_new_with_mnemonic(_("S_ubject:"));
        gtk_box_pack_start(GTK_BOX(subject), label, FALSE, FALSE, 0);
        gtk_widget_show(label);
 
@@ -8044,6 +8061,7 @@ static GtkWidget *compose_account_option_menu_create(Compose *compose)
        GtkWidget *hbox;
        GtkWidget *optmenu;
        GtkWidget *optmenubox;
+       GtkWidget *fromlabel;
        GtkListStore *menu;
        GtkTreeIter iter;
        GtkWidget *from_name = NULL;
@@ -8057,11 +8075,13 @@ static GtkWidget *compose_account_option_menu_create(Compose *compose)
        optmenu = gtkut_sc_combobox_create(optmenubox, FALSE);
        menu = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(optmenu)));
 
-       hbox = gtk_hbox_new(FALSE, 6);
+       hbox = gtk_hbox_new(FALSE, 4);
        from_name = gtk_entry_new();
        
        g_signal_connect_after(G_OBJECT(from_name), "grab_focus",
                         G_CALLBACK(compose_grab_focus_cb), compose);
+       g_signal_connect_after(G_OBJECT(from_name), "activate",
+                        G_CALLBACK(from_name_activate_cb), optmenu);
 
        for (; accounts != NULL; accounts = accounts->next, num++) {
                PrefsAccount *ac = (PrefsAccount *)accounts->data;
@@ -8069,7 +8089,7 @@ static GtkWidget *compose_account_option_menu_create(Compose *compose)
 
                if (ac == compose->account) def_menu = num;
 
-               name = g_markup_printf_escaped(_("From: <i>%s</i>"),
+               name = g_markup_printf_escaped(_("<i>%s</i>"),
                                       ac->account_name);
                
                if (ac == compose->account) {
@@ -8099,8 +8119,21 @@ static GtkWidget *compose_account_option_menu_create(Compose *compose)
                         G_CALLBACK(compose_entry_popup_extend),
                         NULL);
 
+       fromlabel = gtk_label_new_with_mnemonic(_("_From:"));
+       gtk_label_set_mnemonic_widget(GTK_LABEL(fromlabel), from_name);
+
+       gtk_box_pack_start(GTK_BOX(hbox), fromlabel, FALSE, FALSE, 4);
        gtk_box_pack_start(GTK_BOX(hbox), optmenubox, FALSE, FALSE, 0);
        gtk_box_pack_start(GTK_BOX(hbox), from_name, TRUE, TRUE, 0);
+
+       /* Putting only the GtkEntry into focus chain of parent hbox causes
+        * the account selector combobox next to it to be unreachable when
+        * navigating widgets in GtkTable with up/down arrow keys.
+        * Note: gtk_widget_set_can_focus() was not enough. */
+       GList *l = NULL;
+       l = g_list_prepend(l, from_name);
+       gtk_container_set_focus_chain(GTK_CONTAINER(hbox), l);
+       g_list_free(l);
        
        CLAWS_SET_TIP(optmenubox,
                _("Account to use for this email"));
@@ -8303,6 +8336,7 @@ static void compose_set_out_encoding(Compose *compose)
                case C_WINDOWS_1256: branch = "Menu/Options/Encoding/Arabic/" CS_WINDOWS_1256; break;
                case C_ISO_8859_5: branch = "Menu/Options/Encoding/Cyrillic/" CS_ISO_8859_5; break;
                case C_KOI8_R: branch = "Menu/Options/Encoding/Cyrillic/" CS_KOI8_R; break;
+               case C_MACCYR: branch = "Menu/Options/Encoding/Cyrillic/" CS_MACCYR; break;
                case C_KOI8_U: branch = "Menu/Options/Encoding/Cyrillic/" CS_KOI8_U; break;
                case C_WINDOWS_1251: branch = "Menu/Options/Encoding/Cyrillic/" CS_WINDOWS_1251; break;
                case C_ISO_2022_JP: branch = "Menu/Options/Encoding/Japanese/" CS_ISO_2022_JP; break;
@@ -8646,6 +8680,24 @@ static void compose_template_apply_fields(Compose *compose, Template *tmpl)
                }
        }
 
+       if (tmpl->replyto && *tmpl->replyto != '\0') {
+#ifdef USE_ENCHANT
+               quote_fmt_init(msginfo, NULL, NULL, FALSE, compose->account, FALSE,
+                               compose->gtkaspell);
+#else
+               quote_fmt_init(msginfo, NULL, NULL, FALSE, compose->account, FALSE);
+#endif
+               quote_fmt_scan_string(tmpl->replyto);
+               quote_fmt_parse();
+
+               buf = quote_fmt_get_buffer();
+               if (buf == NULL) {
+                       alertpanel_error(_("Template Reply-To format error."));
+               } else {
+                       compose_entry_append(compose, buf, COMPOSE_REPLYTO, PREF_TEMPLATE);
+               }
+       }
+
        /* process the subject */
        if (tmpl->subject && *tmpl->subject != '\0') {
 #ifdef USE_ENCHANT
@@ -9341,6 +9393,8 @@ static gboolean compose_input_cb(GIOChannel *source, GIOCondition condition,
        if (buf[0] == '0') {            /* success */
                GtkTextView *text = GTK_TEXT_VIEW(compose->text);
                GtkTextBuffer *buffer = gtk_text_view_get_buffer(text);
+               GtkTextIter start, end;
+               gchar *chars;
 
                gtk_text_buffer_set_text(buffer, "", -1);
                compose_insert_file(compose, compose->exteditor_file);
@@ -9349,6 +9403,14 @@ static gboolean compose_input_cb(GIOChannel *source, GIOCondition condition,
 
                if (claws_unlink(compose->exteditor_file) < 0)
                        FILE_OP_ERROR(compose->exteditor_file, "unlink");
+
+               buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(compose->text));
+               gtk_text_buffer_get_start_iter(buffer, &start);
+               gtk_text_buffer_get_end_iter(buffer, &end);
+               chars = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
+               if (chars && strlen(chars) > 0)
+                       compose->modified = TRUE;
+               g_free(chars);
        } else if (buf[0] == '1') {     /* failed */
                g_warning("Couldn't exec external editor\n");
                if (claws_unlink(compose->exteditor_file) < 0)
@@ -11830,6 +11892,12 @@ static void compose_subject_entry_activated(GtkWidget *widget, gpointer data)
        gtk_widget_grab_focus(compose->text);
 }
 
+static void from_name_activate_cb(GtkWidget *widget, gpointer data)
+{
+       gtk_combo_box_popup(GTK_COMBO_BOX(data));
+}
+
+
 /*
  * End of Source.
  */