00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
#ifdef HAVE_CONFIG_H
00020
#include <config.h>
00021
#endif
00022
00023
#include <stdio.h>
00024
#include <sys/time.h>
00025
#include <sys/types.h>
00026
#include <unistd.h>
00027
#include <ctype.h>
00028
#include <stdlib.h>
00029
00030
#ifdef HAVE_STRINGS_H
00031
#include <strings.h>
00032
#endif
00033
00034
#include <qtextcodec.h>
00035
#include <qtimer.h>
00036
#include <kapplication.h>
00037
#include <kdebug.h>
00038
#include <klocale.h>
00039
00040
#include "koSpell.h"
00041
#include "koSpelldlg.h"
00042
#include "koispell.moc"
00043
#include "koispell.h"
00044
#include "koSconfig.h"
00045
00046
#include <kwin.h>
00047
#include <kprocio.h>
00048
00049
#define MAXLINELENGTH 10000
00050
00051
enum {
00052 GOOD= 0,
00053 IGNORE= 1,
00054 REPLACE= 2,
00055 MISTAKE= 3
00056 };
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
#define OUTPUT(x) (connect (proc, SIGNAL (readReady(KProcIO *)), this, SLOT (x(KProcIO *))))
00074
00075
00076
#define NOOUTPUT(x) (disconnect (proc, SIGNAL (readReady(KProcIO *)), this, SLOT (x(KProcIO *))))
00077
00078
00079
00080
00081
00082 KOISpell::KOISpell(
QWidget *_parent,
const QString &_caption,
00083
QObject *obj,
const char *slot,
KOSpellConfig *_ksc,
00084
bool _progressbar,
bool _modal, KOSpellerType _type )
00085 :KOSpell(_parent,_caption,_ksc,_modal,false, _type)
00086 {
00087 initialize( _parent, _caption, obj, slot, _ksc,
00088 _progressbar, _modal );
00089 }
00090
00091
void KOISpell::startIspell()
00092
00093 {
00094
00095 kdDebug(30006) <<
"Try #" << trystart << endl;
00096
if (trystart>0)
00097 proc->resetAll();
00098
00099
switch (ksconfig->client())
00100 {
00101
case KOS_CLIENT_ISPELL:
00102 *proc <<
"ispell";
00103 kdDebug(30006) <<
"Using ispell" << endl;
00104
break;
00105
case KOS_CLIENT_ASPELL:
00106
00107 *proc <<
"aspell";
00108 kdDebug(30006) <<
"Using aspell" << endl;
00109
break;
00110
case KOS_CLIENT_HSPELL:
00111 *proc <<
"hspell";
00112 kdDebug(30006) <<
"Using hspell" << endl;
00113
break;
00114
default:
00115 kdError(30006) <<
"Spelling configuration error, client=" << ksconfig->client() <<endl;
00116 }
00117
00118
if (ksconfig->client() == KOS_CLIENT_ISPELL || ksconfig->client() == KOS_CLIENT_ASPELL)
00119 {
00120
00121
00122 *proc <<
"-a" <<
"-S";
00123
switch ( type )
00124 {
00125
case HTML:
00126
00127
00128
00129
00130 *proc <<
"-H";
00131
break;
00132
case TeX:
00133
00134 *proc <<
"-t";
00135
break;
00136
case Nroff:
00137
00138
if ( ksconfig->client() == KOS_CLIENT_ISPELL )
00139 *proc <<
"-n";
00140
break;
00141
case Text:
00142
default:
00143
00144
break;
00145 }
00146
00147
if (ksconfig->noRootAffix())
00148 {
00149 *proc<<
"-m";
00150 }
00151
if (ksconfig->runTogether())
00152 {
00153 *proc <<
"-B";
00154 }
00155
else
00156 {
00157 *proc <<
"-C";
00158 }
00159
00160
if (trystart<2)
00161 {
00162
if (! ksconfig->dictionary().isEmpty())
00163 {
00164 kdDebug(30006) <<
"using dictionary [" << ksconfig->dictionary() <<
"]" << endl;
00165 *proc <<
"-d";
00166 *proc << ksconfig->dictionary();
00167 }
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
if (trystart<1)
00185
switch (ksconfig->encoding())
00186 {
00187
case KOS_E_LATIN1:
00188 *proc <<
"-Tlatin1";
00189
break;
00190
case KOS_E_LATIN2:
00191 *proc <<
"-Tlatin2";
00192
break;
00193
case KOS_E_LATIN3:
00194 *proc <<
"-Tlatin3";
00195
break;
00196
case KOS_E_LATIN15:
00197
00198
00199
00200
00201
00202 *proc <<
"-Tlatin1";
00203
break;
00204
00205
00206
case KOS_E_LATIN4:
00207
case KOS_E_LATIN5:
00208
case KOS_E_LATIN7:
00209
case KOS_E_LATIN8:
00210
case KOS_E_LATIN9:
00211
case KOS_E_LATIN13:
00212
00213
00214 kdError(30006) <<
"charsets iso-8859-4 .. iso-8859-13 not supported yet" << endl;
00215
break;
00216
00217
case KOS_E_UTF8:
00218 *proc <<
"-Tutf8";
00219
break;
00220
00221
case KOS_E_KOI8U:
00222 *proc <<
"-w'";
00223
break;
00224
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 }
00236
else
00237 *proc <<
"-a";
00238
00239
if (trystart==0)
00240 {
00241 connect (proc, SIGNAL ( receivedStderr (KProcess *,
char *,
int)),
00242
this, SLOT (ispellErrors (KProcess *,
char *,
int)));
00243
00244
00245 connect(proc, SIGNAL(processExited(KProcess *)),
00246
this, SLOT (ispellExit (KProcess *)));
00247
00248 OUTPUT(KSpell2);
00249 }
00250
00251
if ( proc->start() ==
false )
00252 {
00253 m_status = Error;
00254 QTimer::singleShot( 0,
this, SLOT(emitDeath()));
00255 }
00256 }
00257
00258
QStringList KOISpell::resultCheckWord(
const QString &_word )
00259 {
00260 disconnect();
00261 checkWord (_word,
false,
true);
00262
QStringList sug = suggestions();
00263
return sug;
00264 }
00265
00266
00267
void KOISpell::ispellErrors (KProcess *,
char *buffer,
int buflen)
00268 {
00269 buffer [buflen-1] =
'\0';
00270
00271 }
00272
00273
void KOISpell::KSpell2 (KProcIO *)
00274
00275 {
00276 kdDebug(30006) <<
"KSpell::KSpell2" << endl;
00277 trystart=maxtrystart;
00278
00279
QString line;
00280
00281
if (proc->fgets (line,
true)==-1)
00282 {
00283 QTimer::singleShot( 0,
this, SLOT(emitDeath()));
00284
return;
00285 }
00286
00287
00288
if (line[0]!=
'@')
00289 {
00290 QTimer::singleShot( 0,
this, SLOT(emitDeath()));
00291
return;
00292 }
00293
00294
00295
if (ignore (
"kde")==
false)
00296 {
00297 kdDebug(30006) <<
"@KDE was false" << endl;
00298 QTimer::singleShot( 0,
this, SLOT(emitDeath()));
00299
return;
00300 }
00301
00302
00303
if (ignore (
"linux")==
false)
00304 {
00305 kdDebug(30006) <<
"@Linux was false" << endl;
00306 QTimer::singleShot( 0,
this, SLOT(emitDeath()));
00307
return;
00308 }
00309
00310 NOOUTPUT (KSpell2);
00311
00312 m_status = Running;
00313 m_ready =
true;
00314 emit ready(
this);
00315 }
00316
00317
void
00318 KOISpell::setUpDialog (
bool reallyuseprogressbar)
00319 {
00320
if (dialogsetup)
00321
return;
00322
00323
00324 ksdlg=
new KOSpellDlg (parent, ksconfig,
"dialog",
00325 progressbar && reallyuseprogressbar, modaldlg );
00326 ksdlg->setCaption (caption);
00327 connect (ksdlg, SIGNAL (command (
int)),
this,
00328 SLOT (slotStopCancel (
int)) );
00331
#ifdef Q_WS_X11 // FIXME(E): Implement for Qt/Embedded
00332
KWin::setIcons (ksdlg->winId(), kapp->icon(), kapp->miniIcon());
00333
#endif
00334
if ( modaldlg )
00335 ksdlg->setFocus();
00336 dialogsetup =
true;
00337 }
00338
00339
bool KOISpell::addPersonal (
const QString & word)
00340 {
00341
QString qs = word.simplifyWhiteSpace();
00342
00343
00344
if (qs.find (
' ')!=-1 || qs.isEmpty())
00345
return false;
00346
00347 qs.prepend (
"*");
00348 personaldict=
true;
00349
00350
return proc->fputs(qs);
00351 }
00352
00353
bool KOISpell::writePersonalDictionary ()
00354 {
00355
return proc->fputs (
"#");
00356 }
00357
00358
bool KOISpell::ignore (
const QString & word)
00359 {
00360
QString qs = word.simplifyWhiteSpace();
00361
00362
00363
if (qs.find (
' ')!=-1 || qs.isEmpty())
00364
return false;
00365
00366 qs.prepend (
"@");
00367
00368
return proc->fputs(qs);
00369 }
00370
00371
bool
00372 KOISpell::cleanFputsWord (
const QString & s,
bool appendCR)
00373 {
00374
QString qs(s);
00375
00376
bool empty =
true;
00377
00378
for (
unsigned int i=0; i<qs.length(); i++)
00379 {
00380
00381
if (qs[i] !=
'\'' && qs[i] !=
'\"' && qs[i] !=
'-'
00382 && qs[i].isPunct() || qs[i].isSpace())
00383 {
00384 qs.remove(i,1);
00385 i--;
00386 }
else {
00387
if (qs[i].isLetter()) empty=
false;
00388 }
00389 }
00390
00391
00392
if (empty)
return false;
00393
00394
return proc->fputs(
"^"+qs, appendCR);
00395 }
00396
00397
bool
00398 KOISpell::cleanFputs (
const QString & s,
bool appendCR)
00399 {
00400
QString qs(s);
00401
unsigned l = qs.length();
00402
00403
00404
for(
unsigned int i = 0; i < l; ++i)
00405 {
00406
if(qs[i] ==
'$')
00407 qs[i] =
' ';
00408 }
00409
00410
if (l<MAXLINELENGTH)
00411 {
00412
if (qs.isEmpty())
00413 qs=
"";
00414
00415
return proc->fputs (
"^"+qs, appendCR);
00416 }
00417
else
00418
return proc->fputs (
"^\n",appendCR);
00419 }
00420
00421
bool KOISpell::checkWord (
const QString & buffer,
bool _usedialog)
00422 {
00423
QString qs = buffer.simplifyWhiteSpace();
00424
if (qs.find (
' ')!=-1 || qs.isEmpty())
00425
return false;
00426
00428 dialog3slot = SLOT(checkWord3());
00429
00430 usedialog=_usedialog;
00431 setUpDialog(
false);
00432
if (_usedialog)
00433 {
00434 emitProgress();
00435 ksdlg->show();
00436 }
00437
else
00438 ksdlg->hide();
00439
00440 OUTPUT (checkWord2);
00441
00442
00443 proc->fputs (
"%");
00444 cleanFputsWord( qs );
00445
00446
return true;
00447 }
00448
00449
00450
bool KOISpell::checkWord (
const QString & buffer,
bool _usedialog,
bool synchronous )
00451 {
00452
QString qs = buffer.simplifyWhiteSpace();
00453
if (qs.find (
' ')!=-1 || qs.isEmpty())
00454
return false;
00455
00457 dialog3slot = SLOT(checkWord3());
00458
00459 usedialog=_usedialog;
00460 setUpDialog(
false);
00461
00462 ksdlg->hide();
00463
if ( synchronous ) {
00464
00465
if ( !m_ready ) {
00466 connect(
this, SIGNAL(ready(KOSpell*)),
00467
this, SLOT(slotSynchronousReady()) );
00468 connect(
this, SIGNAL(death()),
00469
this, SLOT(slotSynchronousReady()) );
00470
00471 enter_loop();
00472 disconnect(
this, SIGNAL(ready(KOSpell*)),
00473
this, SLOT(slotSynchronousReady()) );
00474 disconnect(
this, SIGNAL(death()),
00475
this, SLOT(slotSynchronousReady()) );
00476 }
00477
if ( m_status == Error )
00478
return false;
00479 OUTPUT (checkWord2Synchronous);
00480 }
00481
else
00482 OUTPUT (checkWord2);
00483
00484 proc->fputs (
"%");
00485
00486
if (cleanFputsWord( qs ))
00487 enter_loop();
00488
00489
return true;
00490 }
00491
00492
void KOISpell::checkWord2 (KProcIO *)
00493 {
00494
QString word;
00495
00496
QString line;
00497 proc->fgets (line,
true);
00498
00499
00500
00501
00502
QString blank_line;
00503 proc->fgets(blank_line,
true);
00504
00505 NOOUTPUT(checkWord2);
00506
00507
bool mistake = (parseOneResponse(line, word, sugg) == MISTAKE);
00508
if ( mistake && usedialog )
00509 {
00510 cwword=word;
00511 dialog (word, sugg, SLOT (checkWord3()));
00512
return;
00513 }
00514
else if( mistake )
00515 {
00516 misspellingWord (word, sugg, lastpos);
00517 }
00518
00519
00520
00521 emit corrected (word, word, 0L);
00522 }
00523
00524
00525
00526
00527
void KOISpell::checkWord2Synchronous (KProcIO *)
00528 {
00529
QString word;
00530
00531
QString line;
00532 proc->fgets (line,
true);
00533
00534
00535
00536
00537
QString blank_line;
00538 proc->fgets(blank_line,
true);
00539
00540 NOOUTPUT(checkWord2);
00541
00542
bool mistake = (parseOneResponse(line, word, sugg) == MISTAKE);
00543
if( mistake )
00544 {
00545 misspellingWord (word, sugg, lastpos);
00546 }
00547
00548
00549 emit corrected (word, word, 0L);
00550 qApp->exit_loop();
00551 }
00552
00553
void KOISpell::checkWord3 ()
00554 {
00555 disconnect (
this, SIGNAL (dialog3()),
this, SLOT (checkWord3()));
00556
00557 emit corrected (cwword, replacement(), 0L);
00558 }
00559
00560
QString KOISpell::funnyWord (
const QString & word)
00561
00562
00563 {
00564
QString qs;
00565
unsigned int i=0;
00566
00567
for (i=0; word [i]!=
'\0';i++)
00568 {
00569
if (word [i]==
'+')
00570
continue;
00571
if (word [i]==
'-')
00572 {
00573
QString shorty;
00574
unsigned int j;
00575
int k;
00576
00577
for (j=i+1;word [j]!=
'\0' && word [j]!=
'+' &&
00578 word [j]!=
'-';j++)
00579 shorty+=word [j];
00580 i=j-1;
00581
00582
if ((k=qs.findRev (shorty))==0 || k!=-1)
00583 qs.remove (k,shorty.length());
00584
else
00585 {
00586 qs+=
'-';
00587 qs+=shorty;
00588 }
00589 }
00590
else
00591 qs+=word [i];
00592 }
00593
return qs;
00594 }
00595
00596
00597
int KOISpell::parseOneResponse (
const QString &buffer,
QString &word,
QStringList & sugg)
00598
00599
00600
00601
00602
00603
00604 {
00605 word =
"";
00606 posinline=0;
00607
00608 sugg.clear();
00609
00610
if (buffer [0]==
'*' || buffer[0] ==
'+' || buffer[0] ==
'-')
00611 {
00612
return GOOD;
00613 }
00614
00615
if (buffer [0]==
'&' || buffer [0]==
'?' || buffer [0]==
'#')
00616 {
00617
int i,j;
00618
00619
00620 word = buffer.mid (2,buffer.find (
' ',3)-2);
00621
00622 orig=word;
00623
00624
if(m_bIgnoreTitleCase && word==word.upper())
00625
return IGNORE;
00626
00627
if(m_bIgnoreUpperWords && word[0]==word[0].upper())
00628 {
00629
QString text=word[0]+word.right(word.length()-1).lower();
00630
if(text==word)
00631
return IGNORE;
00632 }
00633
00635
00636
00637
00638
if (ignorelist.findIndex(word.lower())!=-1)
00639
return IGNORE;
00640
00642
QString qs2;
00643
00644
if (buffer.find(
':')!=-1)
00645 qs2=buffer.left (buffer.find (
':'));
00646
else
00647 qs2=buffer;
00648
00649 posinline = qs2.right( qs2.length()-qs2.findRev(
' ') ).toInt()-1;
00650
00652 QStringList::Iterator it = replacelist.begin();
00653
for(;it != replacelist.end(); ++it, ++it)
00654 {
00655
if (word == *it)
00656 {
00657 ++it;
00658 word = *it;
00659
return REPLACE;
00660 }
00661 }
00662
00664
if (buffer [0] !=
'#')
00665 {
00666
QString qs = buffer.mid(buffer.find(
':')+2, buffer.length());
00667 qs+=
',';
00668 sugg.clear();
00669 i=j=0;
00670
while ((
unsigned int)i<qs.length())
00671 {
00672
QString temp = qs.mid (i,(j=qs.find (
',',i))-i);
00673 sugg.append (funnyWord (temp));
00674
00675 i=j+2;
00676 }
00677 }
00678
00679
if ((sugg.count()==1) && (sugg.first() == word))
00680
return GOOD;
00681
00682
return MISTAKE;
00683 }
00684
00685
00686 kdError(750) <<
"HERE?: [" << buffer <<
"]" << endl;
00687 kdError(750) <<
"Please report this to dsweet@kde.org" << endl;
00688 kdError(750) <<
"Thank you!" << endl;
00689 emit done(
false);
00690 emit done (KOISpell::origbuffer);
00691
return MISTAKE;
00692 }
00693
00694
bool KOISpell::checkList (
QStringList *_wordlist,
bool _usedialog)
00695
00696 {
00697 wordlist=_wordlist;
00698
if ((totalpos=wordlist->count())==0)
00699
return false;
00700 wlIt = wordlist->begin();
00701 usedialog=_usedialog;
00702
00703
00704 setUpDialog();
00705
00706
00707 dialog3slot = SLOT (checkList4 ());
00708
00709 proc->fputs (
"%");
00710
00711
00712 lastpos = -1;
00713 checkList2();
00714
00715
00716 OUTPUT(checkList3a);
00717
00718
return true;
00719 }
00720
00721
void KOISpell::checkList2 ()
00722
00723
00724 {
00725
00726
if (wlIt != wordlist->end())
00727 {
00728 kdDebug(30006) <<
"KS::cklist2 " << lastpos <<
": " << *wlIt << endl;
00729
00730 endOfResponse =
false;
00731
bool put;
00732 lastpos++; offset=0;
00733 put = cleanFputsWord (*wlIt);
00734 ++wlIt;
00735
00736
00737
00738
00739
if (!put) {
00740 checkList2();
00741 }
00742 }
00743
else
00744
00745 {
00746 NOOUTPUT(checkList3a);
00747 ksdlg->hide();
00748 emit done(
true);
00749 }
00750 }
00751
00752
void KOISpell::checkList3a (KProcIO *)
00753
00754 {
00755
00756
00757
00758
00759
if (dlgon) {
00760
00761
return;
00762 }
00763
00764
int e, tempe;
00765
00766
QString word;
00767
QString line;
00768
00769
do
00770 {
00771 tempe=proc->fgets (line,
true);
00772
00773
00774
00775
00776
if (tempe == 0) {
00777 endOfResponse =
true;
00778
00779 }
else if (tempe>0) {
00780
if ((e=parseOneResponse (line, word, sugg))==MISTAKE ||
00781 e==REPLACE)
00782 {
00783 dlgresult=-1;
00784
00785
if (e==REPLACE)
00786 {
00787
QString old = *(--wlIt); ++wlIt;
00788 dlgreplacement=word;
00789 checkListReplaceCurrent();
00790
00791 emit corrected (old, *(--wlIt), lastpos); ++wlIt;
00792 }
00793
else if( usedialog )
00794 {
00795 cwword=word;
00796 dlgon=
true;
00797
00798 dialog (word, sugg, SLOT (checkList4()));
00799
return;
00800 }
00801
else
00802 {
00803 misspellingWord (word, sugg, lastpos);
00804 }
00805 }
00806
00807 }
00808 emitProgress ();
00809
00810
00811 }
while (tempe > 0);
00812
00813
00814
00815
00816
00817
if (endOfResponse && !dlgon) {
00818
00819 checkList2();
00820 }
00821 }
00822
00823
void KOISpell::checkListReplaceCurrent () {
00824
00825
00826 wlIt--;
00827
00828
QString s = *wlIt;
00829 s.replace(posinline+offset,orig.length(),replacement());
00830 offset += replacement().length()-orig.length();
00831 wordlist->insert (wlIt, s);
00832 wlIt = wordlist->remove (wlIt);
00833
00834
00835 }
00836
00837
void KOISpell::checkList4 ()
00838
00839 {
00840 dlgon=
false;
00841
QString old;
00842
00843 disconnect (
this, SIGNAL (dialog3()),
this, SLOT (checkList4()));
00844
00845
00846
switch (dlgresult)
00847 {
00848
case KOS_REPLACE:
00849
case KOS_REPLACEALL:
00850 kdDebug(30006) <<
"KS: cklist4: lastpos: " << lastpos << endl;
00851 old = *(--wlIt); ++wlIt;
00852
00853 checkListReplaceCurrent();
00854 emit corrected (old, *(--wlIt), lastpos); ++wlIt;
00855
break;
00856
case KOS_CANCEL:
00857 ksdlg->hide();
00858 emit done (
false);
00859
return;
00860
case KOS_STOP:
00861 ksdlg->hide();
00862 emit done (
true);
00863
break;
00864 };
00865
00866
00867
if (!endOfResponse) {
00868
00869 checkList3a(NULL);
00870 }
00871 }
00872
00873
bool KOISpell::check(
const QString &_buffer,
bool _usedialog )
00874 {
00875
QString qs;
00876
00877 usedialog=_usedialog;
00878 setUpDialog ();
00879
00880 dialog3slot = SLOT (check3 ());
00881
00882 kdDebug(30006) <<
"KS: check" << endl;
00883 origbuffer = _buffer;
00884
if ( ( totalpos = origbuffer.length() ) == 0 )
00885 {
00886 emit done(origbuffer);
00887
return false;
00888 }
00889
00890
00891
00892
00893
if ( origbuffer.right(2) !=
"\n\n" )
00894 {
00895
if (origbuffer.at(origbuffer.length()-1)!=
'\n')
00896 {
00897 origbuffer+=
'\n';
00898 origbuffer+=
'\n';
00899 }
00900
else
00901 origbuffer+=
'\n';
00902 }
00903
00904 newbuffer=origbuffer;
00905
00906
00907 OUTPUT(check2);
00908 proc->fputs (
"!");
00909
00910
00911 offset=lastlastline=lastpos=lastline=0;
00912
00913 emitProgress ();
00914
00915
00916
int i = origbuffer.find(
'\n', 0)+1;
00917 qs=origbuffer.mid (0,i);
00918 cleanFputs (qs,
false);
00919
00920 lastline=i;
00921
00922
if (usedialog)
00923 {
00924 emitProgress();
00925 ksdlg->show();
00926 }
00927
else
00928 ksdlg->hide();
00929
00930
return true;
00931 }
00932
00933
void KOISpell::check2 (KProcIO *)
00934
00935 {
00936
int e, tempe;
00937
QString word;
00938
QString line;
00939
static bool recursive =
false;
00940
if (recursive &&
00941 (!ksdlg || ksdlg->isHidden()))
00942 {
00943
return;
00944 }
00945 recursive =
true;
00946
00947
do
00948 {
00949 tempe=proc->fgets (line);
00950 kdDebug(30006) <<
"KSpell::check2 (" << tempe <<
"b)" << endl;
00951
00952
if (tempe>0)
00953 {
00954
if ((e=parseOneResponse (line, word, sugg))==MISTAKE ||
00955 e==REPLACE)
00956 {
00957 dlgresult=-1;
00958
00959
00960
if (ksconfig->encoding() == KOS_E_UTF8) {
00961
00962
00963
00964
00965
00966
00967 posinline = (QString::fromUtf8(
00968 origbuffer.mid(lastlastline,lastline-lastlastline).utf8(),
00969 posinline)).length();
00970
00971 }
00972
00973 lastpos=posinline+lastlastline+offset;
00974
00975
00976
00977
if (e==REPLACE)
00978 {
00979 dlgreplacement=word;
00980 emit corrected (orig, replacement(), lastpos);
00981 offset+=replacement().length()-orig.length();
00982 newbuffer.replace (lastpos, orig.length(), word);
00983 }
00984
else
00985 {
00986 cwword=word;
00987
00988
if ( usedialog ) {
00989
00990 dialog (word, sugg, SLOT (check3()));
00991 }
else {
00992
00993 misspellingWord (word, sugg, lastpos);
00994 dlgresult = KOS_IGNORE;
00995 check3();
00996 }
00997 recursive =
false;
00998
return;
00999 }
01000 }
01001
01002 }
01003
01004 emitProgress ();
01005
01006 }
while (tempe>0);
01007
01008 proc->ackRead();
01009
01010
if (tempe==-1) {
01011 recursive =
false;
01012
return;
01013 }
01014
01015 proc->ackRead();
01016
01017
if ((
unsigned int)lastline<origbuffer.length())
01018 {
01019
int i;
01020
QString qs;
01021
01022
01023
01024 lastpos=(lastlastline=lastline)+offset;
01025 i=origbuffer.find(
'\n', lastline)+1;
01026 qs=origbuffer.mid (lastline, i-lastline);
01027 cleanFputs (qs,
false);
01028 lastline=i;
01029 recursive =
false;
01030
return;
01031 }
01032
else
01033
01034 {
01035 ksdlg->hide();
01036
01037 newbuffer.truncate (newbuffer.length()-2);
01038 emitProgress();
01039 NOOUTPUT( check2 );
01040 emit done (newbuffer);
01041 }
01042 recursive =
false;
01043 }
01044
01045
void KOISpell::check3 ()
01046
01047 {
01048 disconnect (
this, SIGNAL (dialog3()),
this, SLOT (check3()));
01049
01050 kdDebug(30006) <<
"check3 [" << cwword <<
"] [" << replacement() <<
"] " << dlgresult << endl;
01051
01052
01053
switch (dlgresult)
01054 {
01055
case KOS_REPLACE:
01056
case KOS_REPLACEALL:
01057 offset+=replacement().length()-cwword.length();
01058 newbuffer.replace (lastpos, cwword.length(),
01059 replacement());
01060 emit corrected (dlgorigword, replacement(), lastpos);
01061
break;
01062
case KOS_CANCEL:
01063
01064 ksdlg->hide();
01065 emit done (origbuffer);
01066
return;
01067
case KOS_STOP:
01068 ksdlg->hide();
01069
01070 emitProgress();
01071 emit done (newbuffer);
01072
return;
01073 };
01074
01075 proc->ackRead();
01076 }
01077
01078
void
01079 KOISpell::slotStopCancel (
int result)
01080 {
01081
if (dialogwillprocess)
01082
return;
01083
01084 kdDebug(30006) <<
"KSpell::slotStopCancel [" << result <<
"]" << endl;
01085
01086
if (result==KOS_STOP || result==KOS_CANCEL)
01087
if (!dialog3slot.isEmpty())
01088 {
01089 dlgresult=result;
01090 connect (
this, SIGNAL (dialog3()),
this, dialog3slot.ascii());
01091 emit dialog3();
01092 }
01093 }
01094
01095
01096
void KOISpell::dialog(
const QString & word,
QStringList & sugg,
const char *_slot)
01097 {
01098 dlgorigword=word;
01099
01100 dialog3slot=_slot;
01101 dialogwillprocess=
true;
01102 connect (ksdlg, SIGNAL (command (
int)),
this, SLOT (dialog2(
int)));
01103 ksdlg->init (word, &sugg);
01104 misspellingWord (word, sugg, lastpos);
01105
01106 emitProgress();
01107 ksdlg->show();
01108 }
01109
01110
void KOISpell::dialog2 (
int result)
01111 {
01112
QString qs;
01113
01114 disconnect (ksdlg, SIGNAL (command (
int)),
this, SLOT (dialog2(
int)));
01115 dialogwillprocess=
false;
01116 dlgresult=result;
01117 ksdlg->standby();
01118
01119 dlgreplacement=ksdlg->replacement();
01120
01121
01122
switch (dlgresult)
01123 {
01124
01125
case KOS_IGNORE:
01126 emit ignoreword(dlgorigword);
01127
break;
01128
case KOS_IGNOREALL:
01129
01130 ignorelist.prepend(dlgorigword.lower());
01131 emit ignoreall (dlgorigword);
01132
break;
01133
case KOS_ADD:
01134 addPersonal (dlgorigword);
01135 personaldict=
true;
01136 emit addword (dlgorigword);
01137
01138 ignorelist.prepend(dlgorigword.lower());
01139
break;
01140
case KOS_REPLACEALL:
01141 {
01142 replacelist.append (dlgorigword);
01143
QString _replacement = replacement();
01144 replacelist.append (_replacement);
01145 emit replaceall( dlgorigword , _replacement );
01146 }
01147
break;
01148
case KOS_ADDAUTOCORRECT:
01149 {
01150
01151
QString _replacement = replacement();
01152 emit addAutoCorrect (dlgorigword , _replacement);
01153
break;
01154 }
01155 }
01156
01157 connect (
this, SIGNAL (dialog3()),
this, dialog3slot.ascii());
01158 emit dialog3();
01159 }
01160
01161
01162 KOISpell:: ~KOISpell ()
01163 {
01164
delete proc;
01165 }
01166
01167
01168
void KOISpell::cleanUp ()
01169 {
01170
if (m_status == Cleaning)
return;
01171
if (m_status == Running)
01172 {
01173
if (personaldict)
01174 writePersonalDictionary();
01175 m_status = Cleaning;
01176 }
01177 proc->closeStdin();
01178 }
01179
01180
void KOISpell::ispellExit (KProcess *)
01181 {
01182 kdDebug(30006) <<
"KSpell::ispellExit() " << m_status << endl;
01183
01184
if ((m_status == Starting) && (trystart<maxtrystart))
01185 {
01186 trystart++;
01187 startIspell();
01188
return;
01189 }
01190
01191
if (m_status == Starting)
01192 m_status = Error;
01193
else if (m_status == Cleaning)
01194 m_status = m_bNoMisspellingsEncountered ? FinishedNoMisspellingsEncountered : Finished;
01195
else if (m_status == Running)
01196 m_status = Crashed;
01197
else
01198
return;
01199
01200 kdDebug(30006) <<
"Death" << endl;
01201 QTimer::singleShot( 0,
this, SLOT(emitDeath()));
01202 }
01203
01204
01205
01206
01207
void KOISpell::emitDeath()
01208 {
01209
bool deleteMe = autoDelete;
01210 emit death();
01211
if (deleteMe)
01212 deleteLater();
01213 }
01214
01215
void KOISpell::setProgressResolution (
unsigned int res)
01216 {
01217 progres=res;
01218 }
01219
01220
void KOISpell::emitProgress ()
01221 {
01222 uint nextprog = (uint) (100.*lastpos/(
double)totalpos);
01223
01224
if (nextprog>=curprog)
01225 {
01226 curprog=nextprog;
01227 emit progress (curprog);
01228 }
01229 }
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
int
01240 KOISpell::modalCheck(
QString& text,
KOSpellConfig* _kcs )
01241 {
01242 modalreturn = 0;
01243 modaltext = text;
01244
01245
01246
01247 KOISpell* spell =
new KOISpell( 0L, i18n(
"Spell Checker"), 0 ,
01248 0, _kcs,
true,
true );
01249
01250
01251
while ((spell->status()==Starting) || (spell->status()==Running) || (spell->status()==Cleaning))
01252 kapp->processEvents();
01253
01254 text = modaltext;
01255
01256
delete spell;
01257
return modalreturn;
01258 }
01259
01260
void KOISpell::slotSpellCheckerCorrected(
const QString & oldText,
const QString & newText,
unsigned int pos )
01261 {
01262 modaltext=modaltext.replace(pos,oldText.length(),newText);
01263 }
01264
01265
01266
void KOISpell::slotModalReady()
01267 {
01268
01269
01270
01271 Q_ASSERT( m_status == Running );
01272 connect(
this, SIGNAL( done(
const QString & ) ),
01273
this, SLOT( slotModalDone(
const QString & ) ) );
01274 QObject::connect(
this, SIGNAL( corrected(
const QString&,
const QString&,
unsigned int ) ),
01275
this, SLOT( slotSpellCheckerCorrected(
const QString&,
const QString &,
unsigned int ) ) );
01276 QObject::connect(
this, SIGNAL( death() ),
01277
this, SLOT( slotModalSpellCheckerFinished( ) ) );
01278 check( modaltext );
01279 }
01280
01281
void KOISpell::slotModalDone(
const QString & )
01282 {
01283
01284
01285 cleanUp();
01286
01287
01288
01289
01290 slotModalSpellCheckerFinished();
01291 }
01292
01293
void KOISpell::slotModalSpellCheckerFinished( )
01294 {
01295 modalreturn=(
int)this->status();
01296 }
01297
01298
01299
void KOISpell::initialize(
QWidget *_parent,
const QString &_caption,
01300
QObject *obj,
const char *slot,
KOSpellConfig *_ksc,
01301
bool _progressbar,
bool _modal )
01302 {
01303 m_ready =
false;
01304 m_bIgnoreUpperWords=
false;
01305 m_bIgnoreTitleCase=
false;
01306
01307 autoDelete =
false;
01308 modaldlg = _modal;
01309 progressbar = _progressbar;
01310
01311 proc=0;
01312 ksdlg=0;
01313
01314 texmode=dlgon=
false;
01315
01316 dialogsetup =
false;
01317 progres=10;
01318 curprog=0;
01319
01320 dialogwillprocess=
false;
01321 dialog3slot=
"";
01322
01323 personaldict=
false;
01324 dlgresult=-1;
01325
01326 caption=_caption;
01327
01328 parent=_parent;
01329
01330 trystart=0;
01331 maxtrystart=2;
01332
01333
if ( obj && slot )
01334
01335 connect (
this, SIGNAL (ready(KOSpell *)), obj, slot);
01336
else
01337
01338 connect (
this, SIGNAL (ready(KOSpell *)),
this, SLOT( slotModalReady() ) );
01339 proc=
new KProcIO(codec);
01340
01341 startIspell();
01342 }
01343
01344
01345
01346
void qt_enter_modal(
QWidget *widget );
01347
void qt_leave_modal(
QWidget *widget );
01348
void KOISpell::enter_loop()
01349 {
01350
QWidget dummy(0,0,WType_Dialog | WShowModal);
01351 dummy.setFocusPolicy( QWidget::NoFocus );
01352 qt_enter_modal(&dummy);
01353 qApp->enter_loop();
01354 qt_leave_modal(&dummy);
01355 }
01356
01357
void KOISpell::slotSynchronousReady()
01358 {
01359 qApp->exit_loop();
01360 }