gettextise some forgotten strings
[claws.git] / src / compose.c
index 9ae2385188d1916920dbf3201ff74d1d0897ac9a..292f353f806f7dd5ca22299a67bca1b7cb6b5b04 100644 (file)
@@ -170,7 +170,8 @@ static GList *compose_list = NULL;
 Compose *compose_generic_new                   (PrefsAccount   *account,
                                                 const gchar    *to,
                                                 FolderItem     *item,
-                                                GPtrArray      *attach_files);
+                                                GPtrArray      *attach_files,
+                                                GList          *listAddress );
 
 static Compose *compose_create                 (PrefsAccount   *account,
                                                 ComposeMode     mode);
@@ -299,6 +300,9 @@ static void compose_create_header_entry     (Compose *compose);
 static void compose_add_header_entry   (Compose *compose, gchar *header, gchar *text);
 static void compose_update_priority_menu_item(Compose * compose);
 
+static void compose_add_field_list     ( Compose *compose,
+                                         GList *listAddress );
+
 /* callback functions */
 
 static gboolean compose_edit_size_alloc (GtkEditable   *widget,
@@ -481,6 +485,9 @@ void compose_headerentry_changed_cb    (GtkWidget          *entry,
 void compose_headerentry_key_press_event_cb(GtkWidget         *entry,
                                            GdkEventKey        *event,
                                            ComposeHeaderEntry *headerentry);
+static gboolean compose_headerentry_button_pressed (GtkWidget *entry, 
+                                                   GdkEventButton *event,
+                                                   gpointer data);
 
 static void compose_show_first_last_header (Compose *compose, gboolean show_first);
 
@@ -656,7 +663,8 @@ static GtkItemFactoryEntry compose_entries[] =
        {N_("/_Message/---"),           NULL, NULL, 0, "<Separator>"},
        {N_("/_Message/Si_gn"),         NULL, compose_toggle_sign_cb   , 0, "<ToggleItem>"},
        {N_("/_Message/_Encrypt"),      NULL, compose_toggle_encrypt_cb, 0, "<ToggleItem>"},
-       {N_("/_Message/Mode/MIME"),             NULL, compose_set_gnupg_mode_cb,   GNUPG_MODE_DETACH, "<RadioItem>"},   
+       {N_("/_Message/Mode"),          NULL, NULL,   0, "<Branch>"},
+       {N_("/_Message/Mode/MIME"),     NULL, compose_set_gnupg_mode_cb,   GNUPG_MODE_DETACH, "<RadioItem>"},   
        {N_("/_Message/Mode/Inline"),   NULL, compose_set_gnupg_mode_cb,   GNUPG_MODE_INLINE, "/Message/Mode/MIME"},    
 #endif /* USE_GPGME */
        {N_("/_Message/---"),           NULL,           NULL,   0, "<Separator>"},
@@ -686,21 +694,25 @@ static GtkTargetEntry compose_mime_types[] =
 Compose *compose_new(PrefsAccount *account, const gchar *mailto,
                     GPtrArray *attach_files)
 {
-       return compose_generic_new(account, mailto, NULL, attach_files);
+       return compose_generic_new(account, mailto, NULL, attach_files, NULL);
 }
 
 Compose *compose_new_with_folderitem(PrefsAccount *account, FolderItem *item)
 {
-       return compose_generic_new(account, NULL, item, NULL);
+       return compose_generic_new(account, NULL, item, NULL, NULL);
+}
+
+Compose *compose_new_with_list( PrefsAccount *account, GList *listAddress )
+{
+       return compose_generic_new( account, NULL, NULL, NULL, listAddress );
 }
 
 Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderItem *item,
-                            GPtrArray *attach_files)
+                            GPtrArray *attach_files, GList *listAddress )
 {
        Compose *compose;
        GtkSText *text;
        GtkItemFactory *ifactory;
-       gboolean grab_focus_on_last = TRUE;
 
        if (item && item->prefs && item->prefs->enable_default_account)
                account = account_find_from_id(item->prefs->default_account);
@@ -737,8 +749,7 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
 
                } else if (item && item->prefs->enable_default_to) {
                        compose_entry_append(compose, item->prefs->default_to, COMPOSE_TO);
-                       compose_entry_select(compose, item->prefs->default_to);
-                       grab_focus_on_last = FALSE;
+                       compose_entry_mark_default_to(compose, item->prefs->default_to);
                }
                if (item && item->ret_rcpt) {
                        menu_set_toggle(ifactory, "/Message/Request Return Receipt", TRUE);
@@ -753,6 +764,7 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
                 */
                menu_set_sensitive(ifactory, "/Message/Request Return Receipt", FALSE); 
        }
+       compose_add_field_list( compose, listAddress );
 
        if (attach_files) {
                gint i;
@@ -776,9 +788,7 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
                g_free(folderidentifier);
        }
        
-       /* Grab focus on last header only if no default_to was set */
-       if (grab_focus_on_last)
-               gtk_widget_grab_focus(compose->header_last->entry);
+       gtk_widget_grab_focus(compose->header_last->entry);
 
        if (prefs_common.auto_exteditor)
                compose_exec_ext_editor(compose);
@@ -999,13 +1009,20 @@ static void compose_generic_reply(MsgInfo *msginfo, gboolean quote,
        if (account->auto_sig)
                compose_insert_sig(compose, FALSE);
 
-       if (quote && prefs_common.linewrap_quote)
-               compose_wrap_line_all(compose);
+       /* Must thaw here, otherwise the GtkSTextEdit will become confused 
+        * when positioning cursor */
+       gtk_stext_thaw(text);
 
-       gtk_editable_set_position(GTK_EDITABLE(text), 0);
-       gtk_stext_set_point(text, 0);
+       gtk_editable_set_position
+               (GTK_EDITABLE(text), quote_fmt_get_cursor_pos());
+       gtk_stext_set_point(text, quote_fmt_get_cursor_pos());
+
+       if (quote && prefs_common.linewrap_quote) {
+               gtk_stext_freeze(text);
+               compose_wrap_line_all(compose);
+               gtk_stext_thaw(text);
+       }
 
-       gtk_stext_thaw(text);
        gtk_widget_grab_focus(compose->text);
 
        if (prefs_common.auto_exteditor)
@@ -1384,7 +1401,8 @@ Compose *compose_redirect(PrefsAccount *account, MsgInfo *msginfo)
        gtk_widget_set_sensitive(compose->toolbar->attach_btn, FALSE);
        gtk_widget_set_sensitive(compose->toolbar->sig_btn, FALSE);
        gtk_widget_set_sensitive(compose->toolbar->exteditor_btn, FALSE);
-       gtk_widget_set_sensitive(compose->toolbar->linewrap_btn, FALSE);
+       gtk_widget_set_sensitive(compose->toolbar->linewrap_current_btn, FALSE);
+       gtk_widget_set_sensitive(compose->toolbar->linewrap_all_btn, FALSE);
 
         return compose;
 }
@@ -1450,16 +1468,32 @@ void compose_entry_append(Compose *compose, const gchar *address,
        compose_add_header_entry(compose, header, (gchar *)address);
 }
 
-void compose_entry_select (Compose *compose, const gchar *mailto)
+void compose_entry_mark_default_to(Compose *compose, const gchar *mailto)
 {
-       GSList *header_list;
+       static GtkStyle *bold_style = NULL;
+       static GdkColor bold_color;
+       static GdkFont *bold_font = NULL;
+       GSList *h_list;
+       GtkEntry *entry;
                
-       for (header_list = compose->header_list; header_list != NULL; header_list = header_list->next) {
-               GtkEntry * entry = GTK_ENTRY(((ComposeHeaderEntry *)header_list->data)->entry);
-
-               if (gtk_entry_get_text(entry) && !g_strcasecmp(gtk_entry_get_text(entry), mailto)) {
-                       gtk_entry_select_region(entry, 0, -1);
-                       gtk_widget_grab_focus(GTK_WIDGET(entry));
+       for (h_list = compose->header_list; h_list != NULL; h_list = h_list->next) {
+               entry = GTK_ENTRY(((ComposeHeaderEntry *)h_list->data)->entry);
+               if (gtk_entry_get_text(entry) && 
+                   !g_strcasecmp(gtk_entry_get_text(entry), mailto)) {
+                       gtk_widget_ensure_style(GTK_WIDGET(entry));
+                       if (!bold_style) {
+                               gtkut_convert_int_to_gdk_color
+                                       (prefs_common.color_new, &bold_color);
+                               bold_style = gtk_style_copy(gtk_widget_get_style
+                                       (GTK_WIDGET(entry)));
+                               if (!bold_font)
+                                       bold_font = gtkut_font_load
+                                               (prefs_common.boldfont);
+                               if (bold_font)
+                                       bold_style->font = bold_font;
+                               bold_style->fg[GTK_STATE_NORMAL] = bold_color;
+                       }
+                       gtk_widget_set_style(GTK_WIDGET(entry), bold_style);
                }
        }
 }
@@ -1493,7 +1527,10 @@ void compose_toolbar_cb(gint action, gpointer data)
        case A_EXTEDITOR:
                compose_ext_editor_cb(compose, 0, NULL);
                break;
-       case A_LINEWRAP:
+       case A_LINEWRAP_CURRENT:
+               compose_wrap_line(compose);
+               break;
+       case A_LINEWRAP_ALL:
                compose_wrap_line_all(compose);
                break;
        case A_ADDRBOOK:
@@ -1840,7 +1877,8 @@ static void compose_reply_set_entry(Compose *compose, MsgInfo *msginfo,
        }
 
        if (msginfo->subject && *msginfo->subject) {
-               gchar *buf, *buf2, *p;
+               gchar *buf, *buf2;
+               guchar *p;
 
                buf = p = g_strdup(msginfo->subject);
                p += subject_get_prefix_length(p);
@@ -2273,7 +2311,7 @@ static void compose_attach_parts(Compose *compose, MsgInfo *msginfo)
                else {
                        gchar *content_type;
 
-                       content_type = g_strdup_printf("%s/%s", procmime_get_type_str(child->type), child->subtype);
+                       content_type = procmime_get_content_type_str(child->type, child->subtype);
                        partname = procmime_mimeinfo_get_parameter(child, "name");
                        if (partname == NULL)
                                partname = "";
@@ -2348,7 +2386,7 @@ static void compose_wrap_line(Compose *compose)
                        if (ch_len == 1 
                            && strchr(prefs_common.quote_chars, *cbuf))
                                quoted = 1;
-                       else if (ch_len != 1 || !isspace(*cbuf))
+                       else if (ch_len != 1 || !isspace(*(guchar *)cbuf))
                                quoted = 0;
 
                        line_end = 0;
@@ -2395,15 +2433,16 @@ static void compose_wrap_line(Compose *compose)
                        ch_len = 1;
                }
 
-               if (ch_len == 1 && isspace(*cbuf))
+               if (ch_len == 1 && isspace(*(guchar *)cbuf))
                        space = 1;
 
                if (ch_len == 1 && *cbuf == '\n') {
                        guint replace = 0;
-                       if (last_ch_len == 1 && !isspace(last_ch)) {
+                       if (last_ch_len == 1 && !isspace((guchar)last_ch)) {
                                if (cur_pos + 1 < p_end) {
                                        GET_CHAR(cur_pos + 1, cbuf, ch_len);
-                                       if (ch_len == 1 && !isspace(*cbuf))
+                                       if (ch_len == 1 &&
+                                           !isspace(*(guchar *)cbuf))
                                                replace = 1;
                                }
                        }
@@ -2434,7 +2473,7 @@ static void compose_wrap_line(Compose *compose)
                        gint tlen = ch_len;
 
                        GET_CHAR(line_pos - 1, cbuf, ch_len);
-                       if (ch_len == 1 && isspace(*cbuf)) {
+                       if (ch_len == 1 && isspace(*(guchar *)cbuf)) {
                                gtk_stext_set_point(text, line_pos);
                                gtk_stext_backward_delete(text, 1);
                                p_end--;
@@ -2530,7 +2569,7 @@ static guint get_indent_length(GtkSText *text, guint start_pos, guint text_len)
                        break;
                case WAIT_FOR_INDENT_CHAR_OR_SPACE:
                        if (is_indent == FALSE && is_space == FALSE &&
-                           !isupper(cbuf[0]))
+                           !isupper((guchar)cbuf[0]))
                                goto out;
                        if (is_space == TRUE) {
                                alnum_cnt = 0;
@@ -2544,7 +2583,7 @@ static guint get_indent_length(GtkSText *text, guint start_pos, guint text_len)
                        }
                        break;
                case WAIT_FOR_INDENT_CHAR:
-                       if (is_indent == FALSE && !isupper(cbuf[0]))
+                       if (is_indent == FALSE && !isupper((guchar)cbuf[0]))
                                goto out;
                        if (is_indent == TRUE) {
                                if (alnum_cnt > 0 
@@ -2721,7 +2760,7 @@ static void compose_wrap_line_all_full(Compose *compose, gboolean autowrap)
 
                                /* insert space if it's alphanumeric */
                                if ((cur_pos != line_pos) &&
-                                   ((clen > 1) || isalnum(cb[0]))) {
+                                   ((clen > 1) || isalnum((guchar)cb[0]))) {
                                        gtk_stext_insert(text, NULL, NULL,
                                                        NULL, " ", 1);
                                        tlen++;
@@ -2762,7 +2801,7 @@ static void compose_wrap_line_all_full(Compose *compose, gboolean autowrap)
                }
 
                /* possible line break */
-               if (ch_len == 1 && isspace(*cbuf)) {
+               if (ch_len == 1 && isspace(*(guchar *)cbuf)) {
                        line_pos = cur_pos + 1;
                        line_len = cur_len + ch_len;
                }
@@ -2788,7 +2827,7 @@ static void compose_wrap_line_all_full(Compose *compose, gboolean autowrap)
                        GET_CHAR(line_pos - 1, cbuf, clen);
 
                        /* if next character is space delete it */
-                       if (clen == 1 && isspace(*cbuf)) {
+                       if (clen == 1 && isspace(*(guchar *)cbuf)) {
                                if (p_pos + i_len != line_pos ||
                                    !gtk_stext_is_uri_string
                                        (text, line_pos, tlen)) {
@@ -3526,7 +3565,6 @@ static gint compose_write_to_file(Compose *compose, const gchar *file,
 
        /* get all composed text */
        chars = gtk_editable_get_chars(GTK_EDITABLE(compose->text), 0, -1);
-       len = strlen(chars);
        if (is_ascii_str(chars)) {
                buf = chars;
                chars = NULL;
@@ -4217,17 +4255,15 @@ static gint compose_write_headers(Compose *compose, FILE *fp,
        }
 
        /* From */
-       if (!IS_IN_CUSTOM_HEADER("From")) {
-               if (compose->account->name && *compose->account->name) {
-                       compose_convert_header
-                               (buf, sizeof(buf), compose->account->name,
-                                strlen("From: "), TRUE);
-                       QUOTE_IF_REQUIRED(name, buf);
-                       fprintf(fp, "From: %s <%s>\n",
-                               name, compose->account->address);
-               } else
-                       fprintf(fp, "From: %s\n", compose->account->address);
-       }
+       if (compose->account->name && *compose->account->name) {
+               compose_convert_header
+                       (buf, sizeof(buf), compose->account->name,
+                        strlen("From: "), TRUE);
+               QUOTE_IF_REQUIRED(name, buf);
+               fprintf(fp, "From: %s <%s>\n",
+                       name, compose->account->address);
+       } else
+               fprintf(fp, "From: %s\n", compose->account->address);
        
        /* To */
        compose_write_headers_from_headerlist(compose, fp, "To", ", ");
@@ -4375,17 +4411,7 @@ static gint compose_write_headers(Compose *compose, FILE *fp,
                     cur = cur->next) {
                        CustomHeader *chdr = (CustomHeader *)cur->data;
 
-                       if (strcasecmp(chdr->name, "Date")         != 0 &&
-                           strcasecmp(chdr->name, "From")         != 0 &&
-                           strcasecmp(chdr->name, "To")           != 0 &&
-                        /* strcasecmp(chdr->name, "Sender")       != 0 && */
-                           strcasecmp(chdr->name, "Message-Id")   != 0 &&
-                           strcasecmp(chdr->name, "In-Reply-To")  != 0 &&
-                           strcasecmp(chdr->name, "References")   != 0 &&
-                           strcasecmp(chdr->name, "Mime-Version") != 0 &&
-                           strcasecmp(chdr->name, "Content-Type") != 0 &&
-                           strcasecmp(chdr->name, "Content-Transfer-Encoding")
-                           != 0) {
+                       if (custom_header_is_allowed(chdr->name)) {
                                compose_convert_header
                                        (buf, sizeof(buf),
                                         chdr->value ? chdr->value : "",
@@ -4593,6 +4619,9 @@ static void compose_create_header_entry(Compose *compose)
         gtk_signal_connect(GTK_OBJECT(entry), "key-press-event", GTK_SIGNAL_FUNC(compose_headerentry_key_press_event_cb), headerentry);
        gtk_signal_connect(GTK_OBJECT(entry), "changed", GTK_SIGNAL_FUNC(compose_headerentry_changed_cb), headerentry);
        gtk_signal_connect(GTK_OBJECT(entry), "activate", GTK_SIGNAL_FUNC(text_activated), compose);
+       gtk_signal_connect(GTK_OBJECT(entry), "button-press-event", 
+                          GTK_SIGNAL_FUNC(compose_headerentry_button_pressed),
+                          NULL);
 
        address_completion_register_entry(GTK_ENTRY(entry));
 
@@ -5227,6 +5256,7 @@ static Compose *compose_create(PrefsAccount *account, ComposeMode mode)
        compose->exteditor_pid     = -1;
        compose->exteditor_readdes = -1;
        compose->exteditor_tag     = -1;
+       compose->draft_timeout_tag = -1;
 
 #if USE_ASPELL
        menu_set_sensitive(ifactory, "/Spelling", FALSE);
@@ -6164,7 +6194,8 @@ static void compose_set_ext_editor_sensitive(Compose *compose,
        gtk_widget_set_sensitive(compose->toolbar->insert_btn,    sensitive);
        gtk_widget_set_sensitive(compose->toolbar->sig_btn,       sensitive);
        gtk_widget_set_sensitive(compose->toolbar->exteditor_btn, sensitive);
-       gtk_widget_set_sensitive(compose->toolbar->linewrap_btn,  sensitive);
+       gtk_widget_set_sensitive(compose->toolbar->linewrap_current_btn,  sensitive);
+       gtk_widget_set_sensitive(compose->toolbar->linewrap_all_btn,  sensitive);
 }
 
 /**
@@ -6375,6 +6406,11 @@ static void compose_send_cb(gpointer data, guint action, GtkWidget *widget)
                               _("Yes"), _("No"), NULL) != G_ALERTDEFAULT)
                        return;
        
+       if (compose->draft_timeout_tag != -1) { /* CLAWS: disable draft timeout */
+               gtk_timeout_remove(compose->draft_timeout_tag);
+               compose->draft_timeout_tag = -1;
+       }
+
        compose_allow_user_actions (compose, FALSE);
        compose->sending = TRUE;
        val = compose_send(compose);
@@ -7128,6 +7164,15 @@ void compose_headerentry_changed_cb(GtkWidget *entry,
        }
 }
 
+static gboolean compose_headerentry_button_pressed
+       (GtkWidget *entry, GdkEventButton *event, gpointer data)
+{
+       /* if this is a lclick, grab the focus */
+       if (event->button == 1)
+               gtk_widget_grab_focus(entry);
+       return FALSE;
+}
+
 static void compose_show_first_last_header(Compose *compose, gboolean show_first)
 {
        GtkAdjustment *vadj;
@@ -7186,11 +7231,13 @@ static void text_inserted(GtkWidget *widget, const gchar *text,
 
        if (prefs_common.autosave && 
            gtk_stext_get_length(GTK_STEXT(widget)) % prefs_common.autosave_length == 0)
-               gtk_timeout_add(500, (GtkFunction) compose_defer_auto_save_draft, compose);
+               compose->draft_timeout_tag = gtk_timeout_add
+                       (500, (GtkFunction) compose_defer_auto_save_draft, compose);
 }
 
 static gint compose_defer_auto_save_draft(Compose *compose)
 {
+       compose->draft_timeout_tag = -1;
        compose_draft_cb((gpointer)compose, 2, NULL);
        return FALSE;
 }
@@ -7214,6 +7261,9 @@ static gboolean compose_send_control_enter(Compose *compose)
        if (!(kev->keyval == GDK_Return && (kev->state & GDK_CONTROL_MASK)))
                return FALSE;
 
+       if (compose->exteditor_tag != -1)
+               return FALSE;
+
        ifactory = gtk_item_factory_from_widget(compose->menubar);
        send_menu = gtk_item_factory_get_widget(ifactory, "/Message/Send");
        list = gtk_accel_group_entries_from_object(GTK_OBJECT(send_menu));
@@ -7269,3 +7319,23 @@ static void compose_check_forwards_go(Compose *compose)
 }
 #endif
 
+/**
+ * Add entry field for each address in list.
+ * \param compose     E-Mail composition object.
+ * \param listAddress List of (formatted) E-Mail addresses.
+ */
+static void compose_add_field_list( Compose *compose, GList *listAddress ) {
+       GList *node;
+       gchar *addr;
+       node = listAddress;
+       while( node ) {
+               addr = ( gchar * ) node->data;
+               compose_entry_append( compose, addr, COMPOSE_TO );
+               node = g_list_next( node );
+       }
+}
+
+/*
+ * End of Source.
+ */
+