Win32: Added spellchecker code. Must be defined __GOLD_SPELL__ to enable.

This commit is contained in:
Ianos Gnatiuc
2005-11-28 20:06:38 +00:00
parent df30d36fe5
commit b1ea7b88dd
18 changed files with 1267 additions and 0 deletions

View File

@@ -764,6 +764,11 @@ CfgGed::CfgGed() {
replylinkfloat = true;
replylinklist = 0;
replylinkshowalways = true;
#if defined(__GOLD_SPELL__)
scheckerdeflang = 0xFFFF;
scheckerenabled = NO;
strcpy(scheckeruserdic, "user.dic");
#endif
screenblanker = 180;
screenblankertype = BLANK_SLIDEWIN;
screenmaxcol = 0;

View File

@@ -320,6 +320,11 @@ const word CRC_REPLYLINKFLOAT = 0xA3EC;
const word CRC_REPLYLINKLIST = 0x104F;
const word CRC_REPLYLINKSHOWALWAYS = 0x2BCD;
const word CRC_ROBOTNAME = 0x7393;
#if defined(__GOLD_SPELL__)
const word CRC_SCHECKERDEFLANG = 0xBBEB;
const word CRC_SCHECKERENABLED = 0x7394;
const word CRC_SCHECKERUSERDIC = 0x0753;
#endif
const word CRC_SCREENBLANKER = 0x5CF7;
const word CRC_SCREENMAXCOL = 0xFFFC;
const word CRC_SCREENMAXROW = 0xFDF7;

View File

@@ -519,6 +519,11 @@ SwitchR:
SwitchS:
switch(crc) {
#if defined(__GOLD_SPELL__)
case CRC_SCHECKERDEFLANG : CfgScheckerdeflang (); break;
case CRC_SCHECKERENABLED : CfgScheckerenabled (); break;
case CRC_SCHECKERUSERDIC : CfgScheckeruserdic (); break;
#endif
case CRC_SCREENBLANKER : CfgScreenblanker (); break;
case CRC_SCREENMAXCOL : CfgScreenmaxcol (); break;
case CRC_SCREENMAXROW : CfgScreenmaxrow (); break;

View File

@@ -222,6 +222,31 @@ void CfgRobotname() {
// ------------------------------------------------------------------
#if defined(__GOLD_SPELL__)
void CfgScheckerdeflang()
{
CFG->scheckerdeflang = atoi(val);
if (CFG->scheckerdeflang == 0)
CFG->scheckerdeflang = 0xFFFF;
}
// ------------------------------------------------------------------
void CfgScheckerenabled()
{
CFG->scheckerenabled = GetYesno(val);
}
// ------------------------------------------------------------------
void CfgScheckeruserdic()
{
strcpy(CFG->scheckeruserdic, val);
}
#endif
// ------------------------------------------------------------------
void CfgScreenblanker() {
GTok t;

View File

@@ -671,6 +671,9 @@ tglobalkey globalkeys[] = {
{ CRC_READSHOWDEL , KK_ReadShowDel , KT_R }, // 0x8615
{ CRC_K_ENTER , Key_Ent , 0 }, // 0x87BD
{ CRC_EDITGOTOPLINE , KK_EditGoTopLine , KT_E }, // 0x87C2
#if defined(__GOLD_SPELL__)
{ CRC_EDITSCHECKERMENU , KK_EditSCheckerMenu , KT_E }, // 0x881F
#endif
{ CRC_HEADERTOGGLEARCSENT , KK_HeaderToggleArcsent , KT_H }, // 0x88A7
{ CRC_EDITBLOCKPGDN , KK_EditBlockPgDn , KT_E }, // 0x895B
{ CRC_EDITASKEXIT , KK_EditAskExit , KT_E }, // 0x89AF

View File

@@ -112,6 +112,9 @@ const word CRC_EDITQUITNOW = 0x80BA;
const word CRC_EDITREFLOW = 0x13F9;
const word CRC_EDITSAVEFILE = 0x64A4;
const word CRC_EDITSAVEMSG = 0x660C;
#if defined(__GOLD_SPELL__)
const word CRC_EDITSCHECKERMENU = 0x881F;
#endif
const word CRC_EDITSCODENORMAL = 0xE4CE;
const word CRC_EDITSCODEBOLD = 0x657D;
const word CRC_EDITSCODEITALIC = 0x487F;

View File

@@ -222,6 +222,14 @@ const word CRC_STYLECODE = 0x8B6C;
const word CRC_STYLECODES = 0x4CB0;
// ------------------------------------------------------------------
#if defined(__GOLD_SPELL__)
const word CRC_SPELL = 0xB8AE;
const word CRC_SCERROR = 0xAB65;
#endif
// ------------------------------------------------------------------
// Get color value
@@ -414,6 +422,11 @@ void GetColors(char* value) {
case CRC_STYLECODES:
wptr = &GC_STYLE_;
break;
#if defined(__GOLD_SPELL__)
case CRC_SPELL:
wptr = &GC_SPELL_;
break;
#endif
default:
return;
}
@@ -577,6 +590,11 @@ void GetColors(char* value) {
wptr->_ReverseBoldItalicUnderscore = attr;
}
break;
#if defined(__GOLD_SPELL__)
case CRC_SCERROR:
wptr->_SpellError = attr;
break;
#endif
default:
return;
}

View File

@@ -306,6 +306,11 @@ void CfgReplylinklist ();
void CfgReplylinkshowalways();
void CfgReplyto ();
void CfgRobotname ();
#if defined(__GOLD_SPELL__)
void CfgScheckerdeflang ();
void CfgScheckerenabled ();
void CfgScheckeruserdic ();
#endif
void CfgScreenblanker ();
void CfgScreenmaxcol ();
void CfgScreenmaxrow ();

View File

@@ -638,6 +638,9 @@ struct SaveUtil {
#define GC_CFGB_ CFG->color[11]
#define GC_STYLE_ CFG->color[12]
#define GC_SHAD_ CFG->color[13]
#if defined(__GOLD_SPELL__)
#define GC_SPELL_ CFG->color[14]
#endif
// ------------------------------------------------------------------
@@ -690,6 +693,10 @@ struct SaveUtil {
#define _ReverseItalicUnderscore c[14]
#define _ReverseBoldItalicUnderscore c[15]
#if defined(__GOLD_SPELL__)
#define _SpellError c[0]
#endif
// ------------------------------------------------------------------
// Window part colors
@@ -806,6 +813,10 @@ struct SaveUtil {
#define C_STYLERUI_ GC_STYLE_._ReverseItalicUnderscore
#define C_STYLERUIB GC_STYLE_._ReverseBoldItalicUnderscore
#if defined(__GOLD_SPELL__)
#define C_SCERROR GC_SPELL_._SpellError
#endif
// ------------------------------------------------------------------
// Window handles

View File

@@ -309,6 +309,11 @@ public:
int replylinklist;
bool replylinkshowalways;
gstrarray robotname;
#if defined(__GOLD_SPELL__)
word scheckerdeflang;
int scheckerenabled;
Path scheckeruserdic;
#endif
int screenblanker; // blanktime;
int screenblankertype;
int screenmaxcol; // maxcols;

View File

@@ -93,6 +93,16 @@ void IEclass::debugtest(char* __test, int __a, int __b, char* __file, int __line
#endif
// ------------------------------------------------------------------
#if defined(__GOLD_SPELL__)
inline bool isscchar(int c)
{
return isxalnum(c) || (c == '-') || (c == '\'') || (c == '.') ;
}
#endif
// ------------------------------------------------------------------
// Make sure line type is correct
@@ -240,6 +250,207 @@ void IEclass::gotorowcol(uint __col, uint __row) {
}
// ------------------------------------------------------------------
#if defined(__GOLD_SPELL__)
void IEclass::dispstringsc(char *__buf, uint __beg, uint __end, uint __row, uint __col, char endchar)
{
char scbuf[EDIT_BUFLEN];
uint bbeg = __beg;
uint bend = __beg;
uint bpos = __beg;
if ((bbeg > 0) && isscchar(__buf[bbeg]) && isscchar(__buf[bbeg-1]))
{
for (; (bpos < __end) && isscchar(__buf[bpos]); bpos++);
bend = bpos;
}
while (bpos < __end)
{
for (; (bpos < __end) && !isscchar(__buf[bpos]); bpos++);
bend = bpos;
uint scpos = 0;
for (; (bpos < __end) && isscchar(__buf[bpos]); bpos++, scpos++)
scbuf[scpos] = __buf[bpos];
if ((scpos == 0) || ((bpos == __end) && isscchar(endchar)))
{
bend = bpos;
break;
}
scbuf[scpos] = NUL;
if (schecker.Check(scbuf))
bend = bpos;
else
{
char savechar = __buf[bend];
__buf[bend] = NUL;
StyleCodeHighlight(__buf+bbeg, __row, __col+bbeg-__beg, false, -1);
__buf[bend] = savechar;
bbeg = bend; bend += scpos;
bool oldusestylies = AA->adat->usestylies;
bool oldhighlighturls = CFG->highlighturls;
AA->adat->usestylies = false;
CFG->highlighturls = false;
savechar = __buf[bend];
__buf[bend] = NUL;
StyleCodeHighlight(__buf+bbeg, __row, __col+bbeg-__beg, false, C_SCERROR);
__buf[bend] = savechar;
AA->adat->usestylies = oldusestylies;
CFG->highlighturls = oldhighlighturls;
bbeg = bend;
}
}
if (bbeg < bend)
StyleCodeHighlight(__buf+bbeg, __row, __col+bbeg-__beg, false, -1);
}
// ------------------------------------------------------------------
void IEclass::dispstring(Line* line, uint __row)
{
GFTRK("Editdispstring");
// Get string length
uint _length = strlen(line->txt.c_str());
// String longer than window width?
_test_haltab(_length > (maxcol+1), _length, (maxcol+1));
_length = MinV(_length, (maxcol+1));
// Buffer for translation to visual representation
char _buf[EDIT_BUFLEN];
// Space-pad and nul-terminate the buffer
memset(_buf, ' ', maxcol+1);
_buf[maxcol+1] = NUL;
// Copy/translate string into buffer
for (uint _pos = 0; _pos < _length; _pos++)
{
char chr = line->txt[_pos];
switch (chr)
{
case ' ': _buf[_pos] = EDIT->CharSpace(); break;
case '\n': _buf[_pos] = EDIT->CharPara(); break;
default: _buf[_pos] = chr;
}
}
int selected = 0;
uint begblock = 0;
uint endblock = 0;
Line *fbline = NULL;
Line *lbline = NULL;
if (blockcol != -1)
{
for (Line *ln = findfirstline(); ln; ln = ln->next)
{
if (ln == currline)
{
if (selected) { lbline = ln; selected ^= 1; endblock = col; }
else { fbline = ln; selected ^= 1; begblock = col; }
}
if (ln->type & GLINE_BLOK)
{
if (selected) { lbline = ln; selected ^= 1; endblock = blockcol; }
else { fbline = ln; selected ^= 1; begblock = blockcol; }
}
if (ln == line) { if (ln == lbline) selected = 1; break; }
if (lbline) break;
}
if (selected)
{
if (fbline == lbline)
{
if (begblock > endblock)
{
int temp = begblock;
begblock = endblock;
endblock = temp;
}
else if (begblock == endblock)
begblock = endblock = 0;
}
else if (line == fbline)
endblock = maxcol+1;
else if (line == lbline)
begblock = 0;
else
{
begblock = 0;
endblock = maxcol+1;
}
}
else
begblock = endblock = 0;
}
if (0 < begblock)
{
char savechar = _buf[begblock];
_buf[begblock] = NUL;
if ((CFG->scheckerenabled == GAUTO) && schecker.IsLoaded() &&
!(line->type & (GLINE_TAGL|GLINE_QUOT|GLINE_KLUD|GLINE_TEAR|GLINE_ORIG|GLINE_HIDD)))
{
dispstringsc(_buf, 0, begblock, __row, mincol, savechar);
}
else
StyleCodeHighlight(_buf, __row, mincol, false, -1);
_buf[begblock] = savechar;
}
if (begblock < endblock)
{
bool oldusestylies = AA->adat->usestylies;
bool oldhighlighturls = CFG->highlighturls;
AA->adat->usestylies = false;
CFG->highlighturls = false;
char savechar = _buf[endblock];
_buf[endblock] = NUL;
StyleCodeHighlight(_buf+begblock, __row, mincol+begblock, false, C_READA);
_buf[endblock] = savechar;
AA->adat->usestylies = oldusestylies;
CFG->highlighturls = oldhighlighturls;
}
if (endblock < (maxcol+1))
{
if ((CFG->scheckerenabled == GAUTO) && schecker.IsLoaded() &&
!(line->type & (GLINE_TAGL|GLINE_QUOT|GLINE_KLUD|GLINE_TEAR|GLINE_ORIG|GLINE_HIDD)))
{
dispstringsc(_buf, endblock, maxcol+1, __row, mincol+endblock, 0);
}
else
StyleCodeHighlight(_buf+endblock, __row, mincol+endblock, false, -1);
}
GFTRK(NULL);
}
#else //#if defined(__GOLD_SPELL__)
// ------------------------------------------------------------------
void IEclass::dispstring(const char* __string, uint __row, int attr, Line* line) {
@@ -353,6 +564,7 @@ void IEclass::dispstring(const char* __string, uint __row, int attr, Line* line)
GFTRK(NULL);
}
#endif //#if defined(__GOLD_SPELL__)
// ------------------------------------------------------------------
@@ -392,7 +604,11 @@ void IEclass::displine(Line* __line, uint __row) {
// Display line
setcolor(__line);
#if defined(__GOLD_SPELL__)
dispstring(__line, __row);
#else
dispstring(__line->txt.c_str(), __row, -1, __line);
#endif
GFTRK(NULL);
}
@@ -436,6 +652,12 @@ void IEclass::refresh(Line* __currline, uint __row) {
}
// If we ran out of lines, blank the rest
#if defined(__GOLD_SPELL__)
if (__row <= maxrow)
editwin.fill(__row, mincol, __row, maxcol, _box_table(W_BREAD, 1), C_READB|ACSET);
if (++__row <= maxrow)
editwin.fill(__row, mincol, maxrow, maxcol, ' ', C_READW);
#else
if(__row <= maxrow) {
vchar vbuf[256];
for(int c = 0; c < maxcol+1; c++)
@@ -445,6 +667,7 @@ void IEclass::refresh(Line* __currline, uint __row) {
while(__row <= maxrow)
dispstring("", __row++);
}
#endif
GFTRK(NULL);
}
@@ -1859,6 +2082,58 @@ void IEclass::SaveMsg() {
}
// ------------------------------------------------------------------
#if defined(__GOLD_SPELL__)
void IEclass::SCheckerMenu()
{
if (!schecker.IsLoaded())
return;
const char *txt = currline->txt.c_str();
GMenuSChecker menu;
int finaltag;
if (!isscchar(txt[col]))
finaltag = menu.Run(schecker, "");
else
{
char buff[EDIT_BUFLEN];
size_t beg = col;
size_t end = col;
for (; (beg > 0) && isscchar(txt[beg-1]); beg--);
for (; isscchar(txt[end]); end++);
size_t len = end - beg;
memcpy(buff, &txt[beg], len);
buff[len] = 0;
finaltag = menu.Run(schecker, buff);
if (finaltag >= 0)
{
std::string &str = schecker.GetSuggest()[finaltag].second;
size_t len2 = str.length() - 3;
txt = &str.c_str()[2];
if ((buff[len-1] == '.') && (txt[len2-1] != '.')) len--;
if (col > (beg + len2 - 1)) col = beg + len2 - 1;
Undo->PushItem(EDIT_UNDO_DEL_TEXT, currline, beg, len);
currline->txt.erase(beg, len);
Undo->PushItem(EDIT_UNDO_INS_TEXT|BATCH_MODE, currline, beg, len2);
currline->txt.insert(beg, txt, len2);
wrapit(&currline, &col, &row);
}
}
if (finaltag == -2)
refresh(currline, row);
}
#endif
// ------------------------------------------------------------------
int IEclass::isempty(Line* __line) {
@@ -2476,6 +2751,9 @@ noselecting:
case KK_EditReflow: Reflow(); break;
case KK_EditSaveFile: SaveFile(); break;
case KK_EditSaveMsg: SaveMsg(); break;
#if defined(__GOLD_SPELL__)
case KK_EditSCheckerMenu: SCheckerMenu(); break;
#endif
case KK_EditSoundkill: Soundkill(); break;
case KK_EditSpellCheck: SpellCheck(); break;
case KK_EditTab: Tab(); break;
@@ -2527,6 +2805,14 @@ int IEclass::Start(int __mode, uint* __position, GMsg* __msg) {
msgmode = __mode;
currline = __msg->lin;
#if defined(__GOLD_SPELL__)
if (CFG->scheckerenabled)
{
schecker.Init();
schecker.Load(CFG->scheckerdeflang, CFG->scheckeruserdic);
}
#endif
if(AA->isinternet() and (CFG->soupexportmargin <= CFG->dispmargin))
margintext = CFG->soupexportmargin;
else

View File

@@ -279,6 +279,12 @@ protected:
int blockcol;
int selecting;
// ----------------------------------------------------------------
// Speller.
#if defined(__GOLD_SPELL__)
CSpellChecker schecker;
#endif
// ----------------------------------------------------------------
// Internal helper functions
@@ -290,7 +296,12 @@ protected:
int dispchar (vchar __ch, int attr=-1);
void dispins ();
void displine (Line* __line, uint __row);
#if defined(__GOLD_SPELL__)
void dispstringsc (char *__buf, uint __beg, uint __end, uint __row, uint __col, char endchar);
void dispstring (Line* line, uint __row);
#else
void dispstring (const char* __string, uint __row, int attr=-1, Line* line=NULL);
#endif
int downoneline (uint __row);
void editexport (Line* __exportline, int __endat);
Line* findanchor ();
@@ -395,6 +406,9 @@ public:
void ReTab ();
void SaveFile ();
void SaveMsg ();
#if defined(__GOLD_SPELL__)
void SCheckerMenu ();
#endif
void Soundkill ();
void SpellCheck ();
void Tab ();

View File

@@ -181,6 +181,9 @@ const gkey KK_EditSCodeBold = 0xFF09;
const gkey KK_EditSCodeItalic = 0xFF0A;
const gkey KK_EditSCodeUnderline = 0xFF0B;
const gkey KK_EditSCodeReverse = 0xFF0C;
#if defined(__GOLD_SPELL__)
const gkey KK_EditSCheckerMenu = 0xFF0D;
#endif
const gkey KK_FileAbort = 0xFF10;
const gkey KK_FileAskExit = 0xFF11;

View File

@@ -1070,3 +1070,137 @@ int GMenuConfirm::Run() {
// ------------------------------------------------------------------
#if defined(__GOLD_SPELL__)
int GMenuSChecker::Run(CSpellChecker &schecker, const char *word)
{
enum
{
TAG_ADDWORD = 100,
TAG_LANG = 0x10000,
TAG_MORE = 0x20000,
TAG_INDEX = 0x30000
};
schecker.Check(word);
CSpellSuggestV &suggest = schecker.Suggest();
std::string title;
if (!*word)
title = " SChecker ";
else
{
title = " ";
title += word;
title += " ";
}
Init();
SetColor(C_ASKW, C_ASKQ, C_ASKN, C_ASKS, CFG->switches.get(screenshadows) ? C_SHADOW : -1);
SetTitle(title.c_str(), C_ASKT, TLEFT);
SetPos(6, 0, title.length()+2, 0);
SetBorder(W_BASK, C_ASKB);
SetMask(M_CLALL);
SetHelp(0);
Begin();
SetTitle("");
size_t idx;
size_t levels = 0;
size_t numrows = 7;
CSpellLangV &langs = schecker.GetLangs();
LIDC lidc = schecker.GetLangCode();
std::vector<std::string> langstr;
size_t langcount = langs.size();
for (idx = 0; idx < langcount; idx++)
{
char buff[10];
LIDC code = langs[idx].GetLangCode();
buff[0] = ' ';
buff[1] = (code == lidc) ? '\x10' : ' ';
itoa(code, &buff[2], 10);
strcat(buff, " ");
langstr.push_back(std::string(buff));
}
if (langcount)
{
Item(TAG_LANG, "L Language... ", 0);
numrows++;
SetPos(numrows, 1, 0, 0);
Begin();
for (idx = 0; idx < langcount; idx++)
Item(TAG_LANG+idx+1, langstr[idx].c_str());
End();
}
if (*word)
{
Item(TAG_ADDWORD, "A Add Word... ");
numrows++;
}
if (suggest.size())
{
ItemSep();
numrows++;
}
for (idx = 0; idx < suggest.size(); idx++)
{
Item(TAG_INDEX + idx, suggest[idx].second.c_str());
if ((numrows == (gvid->numrows - 5)) && (idx < suggest.size()-3))
{
ItemSep();
Item(TAG_MORE + levels, "M More... ", 0);
levels++;
numrows = levels + 6;
SetPos(numrows, levels, title.length()+2, 0);
BeginPullDown();
}
numrows++;
}
for (size_t n = 0; n < levels; n++)
End();
if (suggest.size())
SetTag(TAG_INDEX);
End();
vcurhide();
Start();
vcurshow();
if (finaltag == TAG_ADDWORD)
{
schecker.AddWord();
return -2;
}
else if ((finaltag > TAG_LANG) && (finaltag < TAG_MORE))
{
schecker.Load(langs[finaltag-TAG_LANG-1].GetLangCode(), CFG->scheckeruserdic);
return -2;
}
return (finaltag < TAG_INDEX) ? -1 : (finaltag - TAG_INDEX);
}
#endif
// ------------------------------------------------------------------

View File

@@ -304,3 +304,14 @@ public:
// ------------------------------------------------------------------
#if defined(__GOLD_SPELL__)
class GMenuSChecker : public GMnu
{
public:
int Run(CSpellChecker &schecker, const char *word);
};
#endif
// ------------------------------------------------------------------

View File

@@ -78,6 +78,7 @@
#include <gwinhelp.h>
#include <gwinpick.h>
#include <gedacfg.h>
#include <gespell.h>
// ------------------------------------------------------------------