summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Chappa <chappa@washington.edu>2015-11-15 17:56:28 -0700
committerEduardo Chappa <chappa@washington.edu>2015-11-15 17:56:28 -0700
commitb3ad27e8991fdbd64fd4db58c0c89538b5f02959 (patch)
treedb96448acc54c9893d17970c4dfffbcc95279eec
parentabf5b4cfbff3150ad3340679b80dc1ff5adf6298 (diff)
downloadalpine-b3ad27e8991fdbd64fd4db58c0c89538b5f02959.tar.xz
* PC-Alpine: New configuration option "Aspell Dictionaries" allows a
user to choose the dictionary used to spell, in case the user communicates in more than one language. Examples of values for the variable are "en_US" or "de_DE", etc. Only the first 10 dictionaries are offered.
-rw-r--r--alpine/send.c8
-rw-r--r--build.bat2
-rw-r--r--imap/src/osdep/nt/env_nt.c7
-rw-r--r--pico/display.c195
-rw-r--r--pico/edef.h8
-rw-r--r--pico/efunc.h2
-rw-r--r--pico/osdep/mswin_spell.c35
-rw-r--r--pico/pico.c4
-rw-r--r--pico/pico.h4
-rw-r--r--pith/charconv/makefile.wnt2
-rw-r--r--pith/conf.c15
-rw-r--r--pith/conf.h4
-rw-r--r--pith/conftype.h3
-rw-r--r--pith/pine.hlp30
14 files changed, 298 insertions, 21 deletions
diff --git a/alpine/send.c b/alpine/send.c
index 5725b482..397d4c8c 100644
--- a/alpine/send.c
+++ b/alpine/send.c
@@ -1822,7 +1822,13 @@ pine_send(ENVELOPE *outgoing, struct mail_bodystruct **body,
ps_global->newthread = 0; /* reset this value */
if(F_OFF(F_CANCEL_CONFIRM, ps_global))
pbf->canceltest = cancel_for_pico;
-
+#ifdef _WINDOWS
+ pbf->dict = (ps_global->VAR_DICTIONARY
+ && ps_global->VAR_DICTIONARY[0]
+ && ps_global->VAR_DICTIONARY[0][0])
+ ? ps_global->VAR_DICTIONARY : NULL;
+ pbf->chosen_dict = -1; /* not chosen yet */
+#endif /* _WINDOWS */
pbf->alt_ed = (ps_global->VAR_EDITOR && ps_global->VAR_EDITOR[0] &&
ps_global->VAR_EDITOR[0][0])
? ps_global->VAR_EDITOR : NULL;
diff --git a/build.bat b/build.bat
index f73c0fbd..a88a1a40 100644
--- a/build.bat
+++ b/build.bat
@@ -28,7 +28,7 @@ echo clean -- to remove obj, lib, and exe files from source
goto fini
:wnt
-echo PC-Pine for Windows/Winsock (Win32) build sequence
+echo PC-Aline for Windows/Winsock (Win32) build sequence
set cclntmake=makefile.nt
set alpinemake=makefile.wnt
if not defined ALPINE_LDAP set ALPINE_LDAP=%cd%\ldap
diff --git a/imap/src/osdep/nt/env_nt.c b/imap/src/osdep/nt/env_nt.c
index 6f961a95..d28d30a3 100644
--- a/imap/src/osdep/nt/env_nt.c
+++ b/imap/src/osdep/nt/env_nt.c
@@ -9,7 +9,8 @@
* Author: Mark Crispin
*
* Date: 1 August 1988
- * Last Edited: 3 April 2010
+ * Last Edited: November 10, 2015.
+ * Eduardo Chappa <chappa@gmx.com>
*
* Previous versions of this file were:
*
@@ -164,8 +165,8 @@ static void do_date (char *date,char *prefix,char *fmt,int suffix)
t->tm_hour,t->tm_min,t->tm_sec,zone/60,abs (zone) % 60);
if (suffix) { /* append timezone suffix if desired */
char *tz;
- tzset (); /* get timezone from TZ environment stuff */
- tz = tzname[daylight ? (((struct tm *) t)->tm_isdst > 0) : 0];
+ _tzset (); /* get timezone from TZ environment stuff */
+ tz = _tzname[_daylight ? (((struct tm *) t)->tm_isdst > 0) : 0];
if (tz && tz[0]) {
char *s;
for (s = tz; *s; s++) if (*s & 0x80) return;
diff --git a/pico/display.c b/pico/display.c
index 96e3adb8..23b6f62d 100644
--- a/pico/display.c
+++ b/pico/display.c
@@ -1307,6 +1307,201 @@ mlerase(void)
mpresf = FALSE;
}
+/* returns the chosen dictionary. If one was already chosen
+ * return that one
+ */
+char *
+speller_choice(char **sp_list, int *choice)
+{
+ int ch_dict = -1;
+ int cnt;
+
+ if(sp_list == NULL || sp_list[0] == NULL || sp_list[0][0] == '\0')
+ return NULL;
+
+ if(choice && *choice >= 0)
+ return sp_list[*choice];
+
+ for(cnt = 0; sp_list[cnt] != NULL && sp_list[cnt][0] != '\0'; cnt++)
+ ;
+
+ if(cnt > 10) /* only the first 10 dictionaries */
+ cnt = 10;
+
+ if(cnt == 1) /* only one dictionary? choose it! */
+ ch_dict = 0;
+
+ if(ch_dict > cnt - 1) /* choose again in case something changed */
+ ch_dict = -1;
+
+ if(ch_dict < 0){ /* not a choice yet? do one now! */
+ UCS buf[128];
+ int i;
+ char *utf8_prompt;
+ UCS *ucs4_prompt;
+ EXTRAKEYS menu_dictionary[] = {
+ {"0", NULL, '0'},
+ {"1", NULL, '1'},
+ {"2", NULL, '2'},
+ {"3", NULL, '3'},
+ {"4", NULL, '4'},
+ {"5", NULL, '5'},
+ {"6", NULL, '6'},
+ {"7", NULL, '7'},
+ {"8", NULL, '8'},
+ {"9", NULL, '9'}
+ };
+
+ for(i = 0; i < cnt; i++)
+ menu_dictionary[i].label = sp_list[i];
+
+ if(cnt < 10)
+ menu_dictionary[cnt].name = NULL;
+
+ buf[0] = '\0';
+ /* write the prompt in utf8, and let internal functions translate it to ucs4 */
+ ucs4_prompt = utf8_to_ucs4_cpystr(_("Choose Dictionary: "));
+
+ i = mlchoose(ucs4_prompt, menu_dictionary);
+
+ if(i >= '0' && i <= '9')
+ ch_dict = i - '0';
+
+ if (i == -2) /* user cancelled */
+ ch_dict = -2;
+
+ if(ucs4_prompt)
+ fs_give((void **)&ucs4_prompt);
+ }
+ else ch_dict = -1;
+
+ if(choice)
+ *choice = ch_dict;
+
+ return ch_dict >= 0 ? sp_list[ch_dict] : NULL;
+}
+
+/* just like mlreplyd, but user cannot fill a prompt */
+int
+mlchoose(UCS *prompt, EXTRAKEYS *extras)
+{
+ UCS c;
+ UCS buf[NLINE];
+ int i;
+ int changed = FALSE;
+ int return_val = 0;
+ KEYMENU menu_choose[12];
+ COLOR_PAIR *lastc = NULL;
+
+ for(i = 0; i < 12; i++){
+ menu_choose[i].name = NULL;
+ KS_OSDATASET(&menu_choose[i], KS_NONE);
+ }
+
+ menu_choose[0].name = "^G";
+ menu_choose[0].label = N_("Get Help");
+ KS_OSDATASET(&menu_choose[0], KS_SCREENHELP);
+
+ menu_choose[6].name = "^C";
+ menu_choose[6].label = N_("Cancel");
+ KS_OSDATASET(&menu_choose[6], KS_NONE);
+
+ for(i = 0; i < 10; i++){
+ if((i % 2) == 0){
+ menu_choose[i / 2 + 1].name = extras[i].name;
+ menu_choose[i / 2 + 1].label = extras[i].label;
+ }
+ else{
+ menu_choose[(i + 13) / 2].name = extras[i].name;
+ menu_choose[(i + 13) / 2].label = extras[i].label;
+ }
+ }
+ wkeyhelp(menu_choose); /* paint generic menu */
+ sgarbk = TRUE; /* mark menu dirty */
+ if(Pmaster && curwp)
+ curwp->w_flag |= WFMODE;
+
+ ucs4_strncpy(buf, prompt, NLINE);
+ buf[NLINE-1] = '\0';
+ mlwrite(buf, NULL);
+ if(Pmaster && Pmaster->colors && Pmaster->colors->prcp
+ && pico_is_good_colorpair(Pmaster->colors->prcp)){
+ lastc = pico_get_cur_color();
+ (void) pico_set_colorp(Pmaster->colors->prcp, PSC_NONE);
+ }
+ else
+ (*term.t_rev)(1);
+
+ return_val = -1;
+ while(1){
+ c = GetKey();
+ for(i = 0; i < 10 && extras[i].name != NULL && extras[i].key != c; i++)
+ ;
+ if(i < 10 && extras[i].name)
+ return_val = c;
+ else switch(c){
+ case (CTRL|'C') : /* Bail out! */
+ case F2 :
+ pputs_utf8(_("Cancel"), 1);
+ return_val = -2;
+ break;
+
+ case (CTRL|'G') :
+ if(term.t_mrow == 0 && km_popped == 0){
+ movecursor(term.t_nrow-2, 0);
+ peeol();
+ term.t_mrow = 2;
+ if(lastc){
+ (void) pico_set_colorp(lastc, PSC_NONE);
+ free_color_pair(&lastc);
+ }
+ else
+ (*term.t_rev)(0);
+
+ wkeyhelp(menu_choose); /* paint generic menu */
+ mlwrite(buf, NULL);
+ if(Pmaster && Pmaster->colors && Pmaster->colors->prcp
+ && pico_is_good_colorpair(Pmaster->colors->prcp)){
+ lastc = pico_get_cur_color();
+ (void) pico_set_colorp(Pmaster->colors->prcp, PSC_NONE);
+ }
+ else
+ (*term.t_rev)(1);
+
+ sgarbk = TRUE; /* mark menu dirty */
+ km_popped++;
+ break;
+ }
+ /* else fall through */
+
+ default:
+ (*term.t_beep)();
+ case NODATA :
+ break;
+ }
+
+ (*term.t_flush)();
+ if (return_val != -1){ /* abort sets rv = -2, other return values are positive */
+ if(lastc){
+ (void) pico_set_colorp(lastc, PSC_NONE);
+ free_color_pair(&lastc);
+ }
+ else
+ (*term.t_rev)(0);
+
+ if(km_popped){
+ term.t_mrow = 0;
+ movecursor(term.t_nrow, 0);
+ peeol();
+ sgarbf = 1;
+ km_popped = 0;
+ }
+
+ return(return_val);
+ }
+ }
+}
+
int
mlyesno_utf8(char *utf8prompt, int dflt)
diff --git a/pico/edef.h b/pico/edef.h
index 3cc7fd3e..5d0c1155 100644
--- a/pico/edef.h
+++ b/pico/edef.h
@@ -56,6 +56,10 @@ char *display_character_set = NULL;
char *keyboard_character_set = NULL;
UCS *glo_wordseps = NULL; /* points to word separators if set */
char *glo_wordseps_orig = NULL;
+#ifdef _WINDOWS
+char **dictionary = NULL; /* speller dictionary */
+int chosen_dict = -1; /* the dictionary chosen */
+#endif /* _WINDOWS */
/* uninitialized global definitions */
int currow; /* Cursor row */
@@ -111,6 +115,10 @@ extern char *display_character_set;
extern char *keyboard_character_set;
extern UCS *glo_wordseps;
extern char *glo_wordseps_orig;
+#ifdef _WINDOWS
+extern char **dictionary;
+extern int chosen_dict;
+#endif /* _WINDOWS */
/* initialized global external declarations */
extern int currow; /* Cursor row */
extern int curcol; /* Cursor column */
diff --git a/pico/efunc.h b/pico/efunc.h
index e0d457aa..14a16d61 100644
--- a/pico/efunc.h
+++ b/pico/efunc.h
@@ -124,6 +124,8 @@ extern void modeline(struct WINDOW *);
extern void movecursor(int, int);
extern void clearcursor(void);
extern void mlerase(void);
+extern char *speller_choice(char **, int *);
+extern int mlchoose(UCS *, EXTRAKEYS *);
extern int mlyesno_utf8(char *, int);
extern int mlyesno(UCS *, int);
extern int mlreply_utf8(char *, char *, int, int, EXTRAKEYS *);
diff --git a/pico/osdep/mswin_spell.c b/pico/osdep/mswin_spell.c
index ac899421..f0392cf4 100644
--- a/pico/osdep/mswin_spell.c
+++ b/pico/osdep/mswin_spell.c
@@ -53,12 +53,21 @@ spell(int f, int n)
LINE *w_markp_bak;
WORD_INFO word_info;
ASPELLINFO *aspellinfo;
+ char *lang = NULL;
emlwrite(_("Checking spelling..."), NULL); /* greetings! */
memset(&word_info, 0, sizeof(WORD_INFO));
- aspellinfo = speller_init(NULL);
+ lang = speller_choice(dictionary, &chosen_dict);
+
+ if (chosen_dict == -2){ /* user cancelled */
+ chosen_dict = -1;
+ emlwrite(_("Speller Cancelled"), NULL);
+ return 1;
+ }
+
+ aspellinfo = speller_init(lang);
if(!aspellinfo ||
(word_info.utf8_err_message = speller_get_error_message(aspellinfo)))
{
@@ -67,6 +76,7 @@ spell(int f, int n)
else
emlwrite(_("Spelling: initializing Aspell failed"), NULL);
+ chosen_dict = -1; /* try a different one next time */
speller_close(aspellinfo);
return -1;
}
@@ -437,8 +447,8 @@ spell_dlg_proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
static int
get_next_word(WORD_INFO *word_info)
{
- UCS *ucst;
- int i, hibit;
+ UCS *tmp = NULL;
+ int i;
// Skip quoted lines
while(lgetc(curwp->w_dotp, 0).c == '>')
@@ -482,19 +492,14 @@ get_next_word(WORD_INFO *word_info)
break;
}
- ucst = (UCS *)&word_info->word_dotp->l_text[word_info->word_doto];
- for(i = 0, hibit = 0; i < word_info->word_size; i++)
- if(ucst[i] & 0xff000000)
- hibit++;
-
- if(hibit > 0){
- ucst = ucs4_cpystr(ucst);
- for(i = 0; i < word_info->word_size; i++)
- ucst[i] &= 0xffffff;
+ tmp = fs_get((word_info->word_size+1)*sizeof(UCS));
+ if(tmp != NULL){
+ for(i = 0; i < word_info->word_size; i++)
+ tmp[i] = word_info->word_dotp->l_text[word_info->word_doto+i].c;
+ tmp[i] = 0;
+ word_info->word_utf8 = ucs4_to_utf8_cpystr_n(tmp, word_info->word_size);
+ fs_give((void **)&tmp);
}
- word_info->word_utf8 = ucs4_to_utf8_cpystr_n(ucst, word_info->word_size);
- if(hibit > 0)
- fs_give((void **)&ucst);
return 1;
}
diff --git a/pico/pico.c b/pico/pico.c
index 93d555d4..0d087281 100644
--- a/pico/pico.c
+++ b/pico/pico.c
@@ -165,6 +165,10 @@ pico(PICO *pm)
gmode |= pm->pine_flags; /* high 4 bits rsv'd for pine */
alt_speller = pm->alt_spell;
+#ifdef _WINDOWS
+ dictionary = pm->dict;
+ chosen_dict = pm->chosen_dict;
+#endif /* _WINDOWS */
pico_all_done = 0;
km_popped = 0;
diff --git a/pico/pico.h b/pico/pico.h
index 0605f992..04ad126e 100644
--- a/pico/pico.h
+++ b/pico/pico.h
@@ -190,6 +190,10 @@ typedef struct pico_struct {
char *ctrlr_label; /* Label for ^R in keymenu */
char *alt_spell; /* Checker to use other than "spell" */
char **alt_ed; /* name of alternate editor or NULL */
+#ifdef _WINDOWS
+ char **dict; /* list of dictionaries to choose */
+ int chosen_dict; /* chosen default dictionary */
+#endif /* WINDOWS */
UCS *wordseps; /* word separator characters other than space */
int fillcolumn; /* where to wrap */
int menu_rows; /* number of rows in menu (0 or 2) */
diff --git a/pith/charconv/makefile.wnt b/pith/charconv/makefile.wnt
index 6700ec3b..a692150c 100644
--- a/pith/charconv/makefile.wnt
+++ b/pith/charconv/makefile.wnt
@@ -56,3 +56,5 @@ libpithcc.lib: $(OFILES)
clean:
$(RM) *.lib
$(RM) *.obj
+ $(RM) *.pdb
+
diff --git a/pith/conf.c b/pith/conf.c
index 66dc6dbe..d7c055eb 100644
--- a/pith/conf.c
+++ b/pith/conf.c
@@ -224,6 +224,10 @@ CONF_TXT_T cf_text_editor[] = "Specifies the program invoked by ^_ in the Compo
CONF_TXT_T cf_text_speller[] = "Specifies the program invoked by ^T in the Composer.";
+#ifdef _WINDOWS
+CONF_TXT_T cf_text_speller_dictionary[] = "Specifies the list of dictionaries used by Aspell.";
+#endif /* _WINDOWS */
+
CONF_TXT_T cf_text_deadlets[] = "Specifies the number of dead letter files to keep when canceling.";
CONF_TXT_T cf_text_fillcol[] = "Specifies the column of the screen where the composer should wrap.";
@@ -560,6 +564,10 @@ static struct variable variables[] = {
NULL, cf_text_editor},
{"speller", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
NULL, cf_text_speller},
+#ifdef _WINDOWS
+{"aspell-dictionary-list", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
+ "Aspell Dictionaries", cf_text_speller_dictionary},
+#endif /* _WINDOWS */
{"composer-wrap-column", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
NULL, cf_text_fillcol},
{"reply-indent-string", 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0,
@@ -2005,6 +2013,9 @@ init_vars(struct pine *ps, void (*cmds_f) (struct pine *, char **))
set_current_val(&vars[V_FORM_FOLDER], TRUE, TRUE);
set_current_val(&vars[V_EDITOR], TRUE, TRUE);
set_current_val(&vars[V_SPELLER], TRUE, TRUE);
+#ifdef _WINDOWS
+ set_current_val(&vars[V_DICTIONARY], TRUE, TRUE);
+#endif /* _WINDOWS */
set_current_val(&vars[V_IMAGE_VIEWER], TRUE, TRUE);
set_current_val(&vars[V_BROWSER], TRUE, TRUE);
set_current_val(&vars[V_SMTP_SERVER], TRUE, TRUE);
@@ -7689,6 +7700,10 @@ config_help(int var, int feature)
return(h_config_editor);
case V_SPELLER :
return(h_config_speller);
+#ifdef _WINDOWS
+ case V_DICTIONARY :
+ return(h_config_aspell_dictionary);
+#endif /* _WINDOWS */
case V_DISPLAY_FILTERS :
return(h_config_display_filters);
case V_SEND_FILTER :
diff --git a/pith/conf.h b/pith/conf.h
index 4584cd98..94a94310 100644
--- a/pith/conf.h
+++ b/pith/conf.h
@@ -161,6 +161,10 @@
#define GLO_EDITOR vars[V_EDITOR].global_val.l
#define VAR_SPELLER vars[V_SPELLER].current_val.p
#define GLO_SPELLER vars[V_SPELLER].global_val.p
+#ifdef _WINDOWS
+#define VAR_DICTIONARY vars[V_DICTIONARY].current_val.l
+#define GLO_DICTIONARY vars[V_DICTIONARY].global_val.l
+#endif /* _WINDOWS */
#define VAR_FILLCOL vars[V_FILLCOL].current_val.p
#define GLO_FILLCOL vars[V_FILLCOL].global_val.p
#define VAR_DEADLETS vars[V_DEADLETS].current_val.p
diff --git a/pith/conftype.h b/pith/conftype.h
index b7ec5eb0..6d077785 100644
--- a/pith/conftype.h
+++ b/pith/conftype.h
@@ -79,6 +79,9 @@ typedef enum { V_PERSONAL_NAME = 0
, V_UNK_CHAR_SET
, V_EDITOR
, V_SPELLER
+#ifdef _WINDOWS
+ , V_DICTIONARY
+#endif /* _WINDOWS */
, V_FILLCOL
, V_REPLY_STRING
, V_REPLY_INTRO
diff --git a/pith/pine.hlp b/pith/pine.hlp
index d1544960..454317e0 100644
--- a/pith/pine.hlp
+++ b/pith/pine.hlp
@@ -140,7 +140,7 @@ with help text for the config screen and the composer that didn't have any
reasonable place to be called from.
Dummy change to get revision in pine.hlp
============= h_revision =================
-Alpine Commit 109 2015-11-07 18:56:21
+Alpine Commit 110 2015-11-15 17:54:38
============= h_news =================
<HTML>
<HEAD>
@@ -179,6 +179,12 @@ addresses bugs found in previous releases and has a few additions as well.
<P>
Additions include:
<UL>
+ <LI> PC-Alpine: New configuration option "Aspell Dictionaries" allows a
+ user to choose the dictionary used to spell, in case the user
+ communicates in more than one language. Examples of values for the
+ variable are "en_US" or "de_DE", etc. Only the first 10
+ dictionaries are offered.
+
<LI> Ignore message from smtp server after a successful authentication
challenge.
@@ -4045,6 +4051,7 @@ There are also additional details on
<li><a href="h_config_smtp_server">OPTION: <!--#echo var="VAR_smtp-server"--></a>
<li><a href="h_config_sort_key">OPTION: <!--#echo var="VAR_sort-key"--></a>
<li><a href="h_config_speller">OPTION: <!--#echo var="VAR_speller"--></a>
+<li><a href="h_config_aspell_dictionary">OPTION: <!--#echo var="VAR_aspell-dictionary-list"--></a>
<li><a href="h_config_sshcmd">OPTION: <!--#echo var="VAR_ssh-command"--></a>
<li><a href="h_config_ssh_open_timeo">OPTION: <!--#echo var="VAR_ssh-open-timeout"--></a>
<li><a href="h_config_sshpath">OPTION: <!--#echo var="VAR_ssh-path"--></a>
@@ -23424,6 +23431,27 @@ That won't work because spell works in a different way.
&lt;End of help on this topic&gt;
</BODY>
</HTML>
+====== h_config_aspell_dictionary =====
+<HTML>
+<HEAD>
+<TITLE>OPTION: <!--#echo var="VAR_aspell-dictionary-list"--></TITLE>
+</HEAD>
+<BODY>
+<H1>OPTION: <!--#echo var="VAR_aspell-dictionary-list"--></H1>
+
+PC Alpine only.
+<P>
+This option specifies a list of dictionaries you will use with
+aspell. A sample entry is &quot;en_US&quot; for american english, or
+&quot;en_GB&quot; for brittish english.
+
+<P>
+<UL>
+<LI><A HREF="h_finding_help">Finding more information and requesting help</A>
+</UL><P>
+&lt;End of help on this topic&gt;
+</BODY>
+</HTML>
====== h_config_display_filters =====
<HTML>
<HEAD>