Revision 175 src/compose.c

compose.c (revision 175)
159 159
						 GtkWidget	*container);
160 160
static GtkWidget *compose_account_option_menu_create
161 161
						(Compose	*compose);
162
static void compose_set_out_encoding		(Compose	*compose);
162 163
static void compose_set_template_menu		(Compose	*compose);
163 164
static void compose_template_apply		(Compose	*compose,
164 165
						 Template	*tmpl,
......
231 232
static gint compose_queue			(Compose	*compose,
232 233
						 const gchar	*file);
233 234
static void compose_write_attach		(Compose	*compose,
234
						 FILE		*fp);
235
						 FILE		*fp,
236
						 const gchar	*charset);
235 237
static gint compose_write_headers		(Compose	*compose,
236 238
						 FILE		*fp,
237 239
						 const gchar	*charset,
......
240 242
static gint compose_redirect_write_headers	(Compose	*compose,
241 243
						 FILE		*fp);
242 244

  
243
static void compose_convert_header		(gchar		*dest,
245
static void compose_convert_header		(Compose	*compose,
246
						 gchar		*dest,
244 247
						 gint		 len,
245 248
						 gchar		*src,
246 249
						 gint		 header_len,
247
						 gboolean	 addr_field);
250
						 gboolean	 addr_field,
251
						 const gchar	*encoding);
248 252
static void compose_generate_msgid		(Compose	*compose,
249 253
						 gchar		*buf,
250 254
						 gint		 len);
......
348 352
					 guint		 action,
349 353
					 GtkWidget	*widget);
350 354

  
355
static void compose_set_encoding_cb	(gpointer	 data,
356
					 guint		 action,
357
					 GtkWidget	*widget);
358

  
351 359
static void compose_address_cb		(gpointer	 data,
352 360
					 guint		 action,
353 361
					 GtkWidget	*widget);
......
581 589
	{N_("/_View/R_uler"),		NULL, compose_toggle_ruler_cb, 0, "<ToggleItem>"},
582 590
	{N_("/_View/---"),		NULL, NULL, 0, "<Separator>"},
583 591
	{N_("/_View/_Attachment"),	NULL, compose_toggle_attach_cb, 0, "<ToggleItem>"},
592
	{N_("/_View/---"),		NULL, NULL, 0, "<Separator>"},
584 593

  
594
#define ENC_ACTION(action) \
595
	NULL, compose_set_encoding_cb, action, \
596
	"/View/Character encoding/Automatic"
597

  
598
	{N_("/_View/Character _encoding"), NULL, NULL, 0, "<Branch>"},
599
	{N_("/_View/Character _encoding/_Automatic"),
600
			NULL, compose_set_encoding_cb, C_AUTO, "<RadioItem>"},
601
	{N_("/_View/Character _encoding/---"), NULL, NULL, 0, "<Separator>"},
602

  
603
	{N_("/_View/Character _encoding/7bit ascii (US-ASC_II)"),
604
	 ENC_ACTION(C_US_ASCII)},
605
	{N_("/_View/Character _encoding/Unicode (_UTF-8)"),
606
	 ENC_ACTION(C_UTF_8)},
607
	{N_("/_View/Character _encoding/---"), NULL, NULL, 0, "<Separator>"},
608

  
609
	{N_("/_View/Character _encoding/Western European (ISO-8859-_1)"),
610
	 ENC_ACTION(C_ISO_8859_1)},
611
	{N_("/_View/Character _encoding/Western European (ISO-8859-15)"),
612
	 ENC_ACTION(C_ISO_8859_15)},
613
	{N_("/_View/Character _encoding/---"), NULL, NULL, 0, "<Separator>"},
614

  
615
	{N_("/_View/Character _encoding/Central European (ISO-8859-_2)"),
616
	 ENC_ACTION(C_ISO_8859_2)},
617
	{N_("/_View/Character _encoding/---"), NULL, NULL, 0, "<Separator>"},
618

  
619
	{N_("/_View/Character _encoding/_Baltic (ISO-8859-13)"),
620
	 ENC_ACTION(C_ISO_8859_13)},
621
	{N_("/_View/Character _encoding/Baltic (ISO-8859-_4)"),
622
	 ENC_ACTION(C_ISO_8859_4)},
623
	{N_("/_View/Character _encoding/---"), NULL, NULL, 0, "<Separator>"},
624

  
625
	{N_("/_View/Character _encoding/Greek (ISO-8859-_7)"),
626
	 ENC_ACTION(C_ISO_8859_7)},
627
	{N_("/_View/Character _encoding/---"), NULL, NULL, 0, "<Separator>"},
628

  
629
	{N_("/_View/Character _encoding/Turkish (ISO-8859-_9)"),
630
	 ENC_ACTION(C_ISO_8859_9)},
631
	{N_("/_View/Character _encoding/---"), NULL, NULL, 0, "<Separator>"},
632

  
633
	{N_("/_View/Character _encoding/Cyrillic (ISO-8859-_5)"),
634
	 ENC_ACTION(C_ISO_8859_5)},
635
	{N_("/_View/Character _encoding/Cyrillic (KOI8-_R)"),
636
	 ENC_ACTION(C_KOI8_R)},
637
	{N_("/_View/Character _encoding/Cyrillic (KOI8-U)"),
638
	 ENC_ACTION(C_KOI8_U)},
639
	{N_("/_View/Character _encoding/Cyrillic (Windows-1251)"),
640
	 ENC_ACTION(C_CP1251)},
641
	{N_("/_View/Character _encoding/---"), NULL, NULL, 0, "<Separator>"},
642

  
643
	{N_("/_View/Character _encoding/Japanese (ISO-2022-_JP)"),
644
	 ENC_ACTION(C_ISO_2022_JP)},
645
	{N_("/_View/Character _encoding/---"), NULL, NULL, 0, "<Separator>"},
646

  
647
	{N_("/_View/Character _encoding/Simplified Chinese (_GB2312)"),
648
	 ENC_ACTION(C_GB2312)},
649
	{N_("/_View/Character _encoding/Traditional Chinese (_Big5)"),
650
	 ENC_ACTION(C_BIG5)},
651
	{N_("/_View/Character _encoding/Traditional Chinese (EUC-_TW)"),
652
	 ENC_ACTION(C_EUC_TW)},
653
	{N_("/_View/Character _encoding/---"), NULL, NULL, 0, "<Separator>"},
654

  
655
	{N_("/_View/Character _encoding/Korean (EUC-_KR)"),
656
	 ENC_ACTION(C_EUC_KR)},
657
	{N_("/_View/Character _encoding/---"), NULL, NULL, 0, "<Separator>"},
658

  
659
	{N_("/_View/Character _encoding/Thai (TIS-620)"),
660
	 ENC_ACTION(C_TIS_620)},
661
	{N_("/_View/Character _encoding/Thai (Windows-874)"),
662
	 ENC_ACTION(C_WINDOWS_874)},
663

  
585 664
	{N_("/_Tools"),			NULL, NULL, 0, "<Branch>"},
586 665
	{N_("/_Tools/_Address book"),	"<shift><control>A", compose_address_cb , 0, NULL},
587 666
	{N_("/_Tools/_Template"),	NULL, NULL, 0, "<Branch>"},
......
2531 2610
	} else {
2532 2611
		gint error = 0;
2533 2612

  
2534
		out_codeset = conv_get_outgoing_charset_str();
2535
		if (!strcasecmp(out_codeset, CS_US_ASCII))
2613
		out_codeset = conv_get_charset_str(compose->out_encoding);
2614
		if (!out_codeset)
2615
			out_codeset = conv_get_outgoing_charset_str();
2616
		if (!g_strcasecmp(out_codeset, CS_US_ASCII))
2536 2617
			out_codeset = CS_ISO_8859_1;
2537 2618

  
2538 2619
		buf = conv_codeset_strdup_full(chars, src_codeset, out_codeset,
......
2675 2756

  
2676 2757
	if (compose->use_attach &&
2677 2758
	    GTK_CLIST(compose->attach_clist)->row_list)
2678
		compose_write_attach(compose, fp);
2759
		compose_write_attach(compose, fp, out_codeset);
2679 2760

  
2680 2761
	if (fclose(fp) == EOF) {
2681 2762
		FILE_OP_ERROR(file, "fclose");
......
2822 2903
		if (g_strncasecmp(buf, "From:", strlen("From:")) == 0) {
2823 2904
			fputs("\n (by way of ", fdest);
2824 2905
			if (compose->account->name) {
2825
				compose_convert_header(buf, sizeof(buf),
2906
				compose_convert_header(compose,
2907
						       buf, sizeof(buf),
2826 2908
						       compose->account->name,
2827 2909
						       strlen(" (by way of "),
2828
						       FALSE);
2910
						       FALSE, NULL);
2829 2911
				fprintf(fdest, "%s <%s>", buf,
2830 2912
					compose->account->address);
2831 2913
			} else
......
3006 3088
	return 0;
3007 3089
}
3008 3090

  
3009
static void compose_write_attach(Compose *compose, FILE *fp)
3091
static void compose_write_attach(Compose *compose, FILE *fp,
3092
				 const gchar *charset)
3010 3093
{
3011 3094
	AttachInfo *ainfo;
3012 3095
	GtkCList *clist = GTK_CLIST(compose->attach_clist);
......
3029 3112
			fprintf(fp, "Content-Type: %s\n", ainfo->content_type);
3030 3113
			fprintf(fp, "Content-Disposition: inline\n");
3031 3114
		} else {
3032
			compose_convert_header(filename, sizeof(filename),
3033
					       ainfo->name, 12, FALSE);
3115
			compose_convert_header(compose,
3116
					       filename, sizeof(filename),
3117
					       ainfo->name, 12, FALSE, charset);
3034 3118
			fprintf(fp, "Content-Type: %s;\n"
3035 3119
				    " name=\"%s\"\n",
3036 3120
				ainfo->content_type, filename);
......
3145 3229
			compose->to_list = address_list_append		     \
3146 3230
				(compose->to_list, dest);		     \
3147 3231
			compose_convert_header				     \
3148
				(buf, sizeof(buf), dest, strlen(header) + 2, \
3149
				 TRUE);					     \
3232
				(compose, buf, sizeof(buf), dest,	     \
3233
				 strlen(header) + 2, TRUE, charset);	     \
3150 3234
			fprintf(fp, "%s: %s\n", header, buf);		     \
3151 3235
		}							     \
3152 3236
	}								     \
......
3180 3264
	/* From */
3181 3265
	if (compose->account->name && *compose->account->name) {
3182 3266
		compose_convert_header
3183
			(buf, sizeof(buf), compose->account->name,
3184
			 strlen("From: "), TRUE);
3267
			(compose, buf, sizeof(buf), compose->account->name,
3268
			 strlen("From: "), TRUE, charset);
3185 3269
		QUOTE_IF_REQUIRED(name, buf);
3186 3270
		fprintf(fp, "From: %s <%s>\n",
3187 3271
			name, compose->account->address);
......
3214 3298
				compose->newsgroup_list =
3215 3299
					newsgroup_list_append
3216 3300
						(compose->newsgroup_list, str);
3217
				compose_convert_header(buf, sizeof(buf), str,
3301
				compose_convert_header(compose,
3302
						       buf, sizeof(buf), str,
3218 3303
						       strlen("Newsgroups: "),
3219
						       TRUE);
3304
						       TRUE, charset);
3220 3305
				fprintf(fp, "Newsgroups: %s\n", buf);
3221 3306
			}
3222 3307
		}
......
3243 3328
		Xstrdup_a(str, entry_str, return -1);
3244 3329
		g_strstrip(str);
3245 3330
		if (*str != '\0') {
3246
			compose_convert_header(buf, sizeof(buf), str,
3247
					       strlen("Subject: "), FALSE);
3331
			compose_convert_header(compose, buf, sizeof(buf), str,
3332
					       strlen("Subject: "), FALSE,
3333
					       charset);
3248 3334
			fprintf(fp, "Subject: %s\n", buf);
3249 3335
		}
3250 3336
	}
......
3273 3359
			g_strstrip(str);
3274 3360
			remove_space(str);
3275 3361
			if (*str != '\0') {
3276
				compose_convert_header(buf, sizeof(buf), str,
3362
				compose_convert_header(compose,
3363
						       buf, sizeof(buf), str,
3277 3364
						       strlen("Followup-To: "),
3278
						       TRUE);
3365
						       TRUE, charset);
3279 3366
				fprintf(fp, "Followup-To: %s\n", buf);
3280 3367
			}
3281 3368
		}
......
3288 3375
			Xstrdup_a(str, entry_str, return -1);
3289 3376
			g_strstrip(str);
3290 3377
			if (*str != '\0') {
3291
				compose_convert_header(buf, sizeof(buf), str,
3378
				compose_convert_header(compose,
3379
						       buf, sizeof(buf), str,
3292 3380
						       strlen("Reply-To: "),
3293
						       TRUE);
3381
						       TRUE, charset);
3294 3382
				fprintf(fp, "Reply-To: %s\n", buf);
3295 3383
			}
3296 3384
		}
......
3299 3387
	/* Organization */
3300 3388
	if (compose->account->organization &&
3301 3389
	    !IS_IN_CUSTOM_HEADER("Organization")) {
3302
		compose_convert_header(buf, sizeof(buf),
3390
		compose_convert_header(compose, buf, sizeof(buf),
3303 3391
				       compose->account->organization,
3304
				       strlen("Organization: "), FALSE);
3392
				       strlen("Organization: "), FALSE,
3393
				       charset);
3305 3394
		fprintf(fp, "Organization: %s\n", buf);
3306 3395
	}
3307 3396

  
......
3342 3431
			    strcasecmp(chdr->name, "Content-Transfer-Encoding")
3343 3432
			    != 0) {
3344 3433
				compose_convert_header
3345
					(buf, sizeof(buf),
3434
					(compose, buf, sizeof(buf),
3346 3435
					 chdr->value ? chdr->value : "",
3347
					 strlen(chdr->name) + 2, FALSE);
3436
					 strlen(chdr->name) + 2, FALSE,
3437
					 charset);
3348 3438
				fprintf(fp, "%s: %s\n", chdr->name, buf);
3349 3439
			}
3350 3440
		}
......
3384 3474
	gchar buf[BUFFSIZE];
3385 3475
	const gchar *entry_str;
3386 3476
	gchar *str;
3477
	const gchar *charset = NULL;
3387 3478

  
3388 3479
	g_return_val_if_fail(fp != NULL, -1);
3389 3480
	g_return_val_if_fail(compose->account != NULL, -1);
......
3396 3487
	/* Resent-From */
3397 3488
	if (compose->account->name) {
3398 3489
		compose_convert_header
3399
			(buf, sizeof(buf), compose->account->name,
3400
			 strlen("Resent-From: "), TRUE);
3490
			(compose, buf, sizeof(buf), compose->account->name,
3491
			 strlen("Resent-From: "), TRUE, NULL);
3401 3492
		fprintf(fp, "Resent-From: %s <%s>\n",
3402 3493
			buf, compose->account->address);
3403 3494
	} else
......
3437 3528
				compose->newsgroup_list =
3438 3529
					newsgroup_list_append
3439 3530
						(compose->newsgroup_list, str);
3440
				compose_convert_header(buf, sizeof(buf), str,
3531
				compose_convert_header(compose,
3532
						       buf, sizeof(buf), str,
3441 3533
						       strlen("Newsgroups: "),
3442
						       TRUE);
3534
						       TRUE, NULL);
3443 3535
				fprintf(fp, "Newsgroups: %s\n", buf);
3444 3536
			}
3445 3537
		}
......
3454 3546
		Xstrdup_a(str, entry_str, return -1);
3455 3547
		g_strstrip(str);
3456 3548
		if (*str != '\0') {
3457
			compose_convert_header(buf, sizeof(buf), str,
3458
					       strlen("Subject: "), FALSE);
3549
			compose_convert_header(compose, buf, sizeof(buf), str,
3550
					       strlen("Subject: "), FALSE,
3551
					       NULL);
3459 3552
			fprintf(fp, "Subject: %s\n", buf);
3460 3553
		}
3461 3554
	}
......
3476 3569
			g_strstrip(str);
3477 3570
			remove_space(str);
3478 3571
			if (*str != '\0') {
3479
				compose_convert_header(buf, sizeof(buf), str,
3572
				compose_convert_header(compose,
3573
						       buf, sizeof(buf), str,
3480 3574
						       strlen("Followup-To: "),
3481
						       TRUE);
3575
						       TRUE, NULL);
3482 3576
				fprintf(fp, "Followup-To: %s\n", buf);
3483 3577
			}
3484 3578
		}
......
3492 3586
			g_strstrip(str);
3493 3587
			if (*str != '\0') {
3494 3588
				compose_convert_header
3495
					(buf, sizeof(buf), str,
3496
					 strlen("Resent-Reply-To: "), TRUE);
3589
					(compose, buf, sizeof(buf), str,
3590
					 strlen("Resent-Reply-To: "), TRUE,
3591
					 NULL);
3497 3592
				fprintf(fp, "Resent-Reply-To: %s\n", buf);
3498 3593
			}
3499 3594
		}
......
3506 3601

  
3507 3602
#undef IS_IN_CUSTOM_HEADER
3508 3603

  
3509
static void compose_convert_header(gchar *dest, gint len, gchar *src,
3510
				   gint header_len, gboolean addr_field)
3604
static void compose_convert_header(Compose *compose, gchar *dest, gint len,
3605
				   gchar *src, gint header_len,
3606
				   gboolean addr_field, const gchar *encoding)
3511 3607
{
3512 3608
	g_return_if_fail(src != NULL);
3513 3609
	g_return_if_fail(dest != NULL);
......
3515 3611
	if (len < 1) return;
3516 3612

  
3517 3613
	g_strchomp(src);
3518
	conv_encode_header(dest, len, src, header_len, addr_field);
3614
	if (!encoding)
3615
		encoding = conv_get_charset_str(compose->out_encoding);
3616
	conv_encode_header(dest, len, src, header_len, addr_field, encoding);
3519 3617
}
3520 3618

  
3521 3619
static void compose_generate_msgid(Compose *compose, gchar *buf, gint len)
......
3995 4093
	compose->use_followupto = FALSE;
3996 4094
	compose->use_attach     = FALSE;
3997 4095

  
4096
	compose->out_encoding   = C_AUTO;
4097

  
3998 4098
#if USE_GPGME
3999 4099
	compose->use_signing    = FALSE;
4000 4100
	compose->use_encryption = FALSE;
......
4050 4150
				       FALSE);
4051 4151
	}
4052 4152

  
4153
	compose_set_out_encoding(compose);
4053 4154
	addressbook_set_target_compose(compose);
4054 4155
	action_update_compose_menu(ifactory, compose);
4055 4156
	compose_set_template_menu(compose);
......
4252 4353
	return hbox;
4253 4354
}
4254 4355

  
4356
static void compose_set_out_encoding(Compose *compose)
4357
{
4358
	GtkItemFactoryEntry *entry;
4359
	GtkItemFactory *ifactory;
4360
	CharSet out_encoding;
4361
	gchar *path, *p, *q;
4362
	GtkWidget *item;
4363

  
4364
	out_encoding = conv_get_charset_from_str(prefs_common.outgoing_charset);
4365
	ifactory = gtk_item_factory_from_widget(compose->menubar);
4366

  
4367
	for (entry = compose_entries; entry->callback != compose_address_cb;
4368
	     entry++) {
4369
		if (entry->callback == compose_set_encoding_cb &&
4370
		    (CharSet)entry->callback_action == out_encoding) {
4371
			p = q = path = g_strdup(entry->path);
4372
			while (*p) {
4373
				if (*p == '_') {
4374
					if (p[1] == '_') {
4375
						p++;
4376
						*q++ = '_';
4377
					}
4378
				} else
4379
					*q++ = *p;
4380
				p++;
4381
			}
4382
			*q = '\0';
4383
			item = gtk_item_factory_get_item(ifactory, path);
4384
			gtk_widget_activate(item);
4385
			g_free(path);
4386
			break;
4387
		}
4388
	}
4389
}
4390

  
4255 4391
static void compose_set_template_menu(Compose *compose)
4256 4392
{
4257 4393
	GSList *tmpl_list, *cur;
......
5359 5495
	gtk_widget_destroy(compose->window);
5360 5496
}
5361 5497

  
5498
static void compose_set_encoding_cb(gpointer data, guint action,
5499
				    GtkWidget *widget)
5500
{
5501
	Compose *compose = (Compose *)data;
5502

  
5503
	if (GTK_CHECK_MENU_ITEM(widget)->active)
5504
		compose->out_encoding = (CharSet)action;
5505
}
5506

  
5362 5507
static void compose_address_cb(gpointer data, guint action, GtkWidget *widget)
5363 5508
{
5364 5509
	Compose *compose = (Compose *)data;

Also available in: Unified diff