[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Can we fix KSpell in KDE_2_0_BRANCH ?
From:       Matthias Kiefer <matthias.kiefer () gmx ! net>
Date:       2000-10-30 8:02:19
[Download RAW message or body]

Hi,

Wolfram Diestel and I  has fixed numerous bugs in kspell
(to be honest: almost everything has been fixed by Wolfram).
KSpell was _very_ buggy. Some functions like checkList() haven't 
worked at all. 

So I would like to ask, if we are allowed to fix kspell in
KDE_2_0_BRANCH. I think, since these were really grave bugs, 
a fixed version should be available as soon as possible.

Here is a list of what has been fixed:

- spellcheck with dictionaries using charsets Latin1, Latin2, Latin3,
   UTF8
- checking lines longer than 150 chars (now up to 10.000 chars possible)
- checkList _finally_ works (necessary for checking marked-up documents)
- accept the ispell responses + (root) and - (compound) too
- more robustness against strange words like "%1"
- some corrections in the config dialog 

I have attached a patch for review, but you can also have a look at the 
kspell sources in HEAD, where the fixed version is already in.

So please let me know, if it is ok to commit.

kind regards,
   Matthias
-- 
Matthias Kiefer
Email:	matthias.kiefer@gmx.de

["kspell.diff" (text/plain)]

Index: kprocio.cpp
===================================================================
RCS file: /home/kde/kdelibs/kspell/kprocio.cpp,v
retrieving revision 1.19
retrieving revision 1.21
diff -u -r1.19 -r1.21
--- kprocio.cpp	2000/03/27 20:35:56	1.19
+++ kprocio.cpp	2000/10/24 12:09:41	1.21
@@ -16,7 +16,7 @@
    Boston, MA 02111-1307, USA.
 */
 
-// $Id: kprocio.cpp,v 1.19 2000/03/27 20:35:56 granroth Exp $
+// $Id: kprocio.cpp,v 1.21 2000/10/24 12:09:41 wolfram Exp $
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -34,7 +34,7 @@
 {
   rbi=0;
   readsignalon=writeready=TRUE;
-  
+
   if (!codec)
   {
      codec = QTextCodec::codecForName("ISO 8859-1");
@@ -80,7 +80,9 @@
 
 bool KProcIO::writeStdin (const QString &line, bool appendnewline)
 {
-  QCString qs( codec->fromUnicode(line));
+
+  QCString qs(codec->fromUnicode(line));
+
   if (appendnewline)
     qs+='\n';
 
@@ -91,6 +93,7 @@
   if (writeready)
     {
       kdDebug(750) << "really writing" << endl;
+
       writeready=FALSE;
       return KProcess::writeStdin (qlist.current(),
 				   strlen (qlist.current()));
@@ -101,13 +104,14 @@
 
 void KProcIO::sent (KProcess *)
 {
-  if (qlist.first())     kdDebug(750) << "KP::sent [" << qlist.first() << "]" << \
endl; +  if (qlist.first()) kdDebug(750) << "KP::sent [" << qlist.first() << "]" << \
endl;  
   qlist.removeFirst();
 
   if (qlist.count()==0)
     {
-            kdDebug(750) << "Empty" << endl;
+      kdDebug(750) << "Empty" << endl;
+
       writeready=TRUE;
     }
   else
@@ -176,25 +180,24 @@
   //in case there's no '\n' at the end of the buffer
   if (len<0 && (unsigned int)rbi<recvbuffer.length())
     {
-      QString qs=recvbuffer.mid (rbi,recvbuffer.length()-rbi);
-      recvbuffer=qs;
+      recvbuffer=recvbuffer.mid (rbi,recvbuffer.length()-rbi);
       rbi=0;
       return -1;
     }
 
   if (len>=0)
     {
-      line = codec->toUnicode(recvbuffer.mid(rbi,len).ascii(), len);   
+      line = codec->toUnicode(recvbuffer.mid(rbi,len), len);
       rbi += len+1;
       return len;
     }
-  
+
   recvbuffer="";
   rbi=0;
 
   //-1 on return signals "no more data" not error
   return -1;
-    
+
 }
 #include "kprocio.moc"
 
Index: kprocio.h
===================================================================
RCS file: /home/kde/kdelibs/kspell/kprocio.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- kprocio.h	2000/03/27 20:35:56	1.6
+++ kprocio.h	2000/10/20 17:39:38	1.7
@@ -22,7 +22,7 @@
 #include <kprocess.h>
 
 /**
- * @version $Id: kprocio.h,v 1.6 2000/03/27 20:35:56 granroth Exp $
+ * @version $Id: kprocio.h,v 1.7 2000/10/20 17:39:38 wolfram Exp $
  * @author David Sweet
  * @short A slightly simpler interface to KProcess
  *
@@ -120,7 +120,7 @@
 
 protected:
   QStrList qlist;
-  QString recvbuffer;
+  QCString recvbuffer;
   QTextCodec *codec;
   int rbi;
   bool needreadsignal, readsignalon, writeready;
Index: ksconfig.cpp
===================================================================
RCS file: /home/kde/kdelibs/kspell/ksconfig.cpp,v
retrieving revision 1.43
retrieving revision 1.45
diff -u -r1.43 -r1.45
--- ksconfig.cpp	2000/09/06 18:28:25	1.43
+++ ksconfig.cpp	2000/10/26 12:45:47	1.45
@@ -16,7 +16,7 @@
    Boston, MA 02111-1307, USA.
 */
 
-// $Id: ksconfig.cpp,v 1.43 2000/09/06 18:28:25 morais Exp $
+// $Id: ksconfig.cpp,v 1.45 2000/10/26 12:45:47 kiefer Exp $
 
 #include <qcheckbox.h>
 #include <qcombobox.h>
@@ -37,6 +37,13 @@
 
 KSpellConfig::KSpellConfig (const KSpellConfig &_ksc)
   : QWidget(0, 0), nodialog(true)
+  , kc(0)
+  , cb1(0)
+  , cb2(0)
+  , dictlist(0)
+  , dictcombo(0)
+  , encodingcombo(0)
+  , clientcombo(0)
 {  
   setNoRootAffix (_ksc.noRootAffix());
   setRunTogether (_ksc.runTogether());
@@ -52,6 +59,13 @@
 KSpellConfig::KSpellConfig( QWidget *parent, const char *name,
 			    KSpellConfig *_ksc, bool addHelpButton ) 
   : QWidget (parent, name), nodialog(false)
+  , kc(0)
+  , cb1(0)
+  , cb2(0)
+  , dictlist(0)
+  , dictcombo(0)
+  , encodingcombo(0)
+  , clientcombo(0)
 {
   kc = KGlobal::config();
   if( _ksc == 0 )
@@ -91,9 +105,17 @@
   glay->addWidget( dictlist, 2 ,0 );
 
   encodingcombo = new QComboBox( this );
-  encodingcombo->insertItem (i18n("7-Bit/ASCII"));
-  encodingcombo->insertItem (i18n("Latin1"));
-  encodingcombo->insertItem (i18n("Latin2"));
+  encodingcombo->insertItem ("US-ASCII");
+  encodingcombo->insertItem ("ISO 8859-1");
+  encodingcombo->insertItem ("ISO 8859-2");
+  encodingcombo->insertItem ("ISO 8859-3");
+  encodingcombo->insertItem ("ISO 8859-4");
+  encodingcombo->insertItem ("ISO 8859-5");
+  encodingcombo->insertItem ("ISO 8859-7");
+  encodingcombo->insertItem ("ISO 8859-8");
+  encodingcombo->insertItem ("ISO 8859-9");
+  encodingcombo->insertItem ("ISO 8859-15");
+  encodingcombo->insertItem ("UTF-8");
   connect (encodingcombo, SIGNAL (activated(int)), this,
 	   SLOT (sChangeEncoding(int)));
   glay->addMultiCellWidget (encodingcombo, 3, 3, 1, 2);
@@ -265,7 +287,7 @@
 bool
 KSpellConfig::readGlobalSettings ()
 {
-  kc->setGroup ("KSpell");
+  KConfigGroupSaver cs(kc,"KSpell");
 
   setNoRootAffix   (kc->readNumEntry ("KSpell_NoRootAffix", 0));
   setRunTogether   (kc->readNumEntry ("KSpell_RunTogether", 0));
@@ -281,7 +303,7 @@
 bool
 KSpellConfig::writeGlobalSettings ()
 {
-  kc->setGroup ("KSpell");
+  KConfigGroupSaver cs(kc,"KSpell");
   kc->writeEntry ("KSpell_NoRootAffix",(int) noRootAffix (), TRUE, TRUE);
   kc->writeEntry ("KSpell_RunTogether", (int) runTogether (), TRUE, TRUE);
   kc->writeEntry ("KSpell_Dictionary", dictionary (), TRUE, TRUE);
@@ -354,6 +376,12 @@
       lname="pt";
       hname=i18n("Portuguese");
     }
+
+  else if (fname=="esperanto")
+    {
+      lname="eo";
+      hname=i18n("Esperanto");
+    }
   
   else
     {
@@ -420,7 +448,8 @@
 	      langfnames.remove ( langfnames.begin() );
 	      langfnames.prepend ( fname );
 
-	      hname="Default - "+hname+"("+fname+")";
+	      hname=i18n("default spelling dictionary"
+						  ,"Default - %1 (%2)").arg(hname).arg(fname);
 	      
 	      dictcombo->changeItem (hname,0);
 	    }
@@ -473,18 +502,28 @@
 KSpellConfig::setClient (int c)
 {
   iclient = c;
+  
+  if(clientcombo)
+	  clientcombo->setCurrentItem(c);
 }
 
 void
 KSpellConfig::setNoRootAffix (bool b)
 {
   bnorootaffix=b;
+
+
+  if(cb1)
+	  cb1->setChecked(b);
 }
 
 void
 KSpellConfig::setRunTogether(bool b)
 {
   bruntogether=b;
+
+  if(cb2)
+	  cb2->setChecked(b);
 }
 
 void
@@ -495,8 +534,27 @@
   if (qsdict.length()>4)
     if ((signed)qsdict.find(".aff")==(signed)qsdict.length()-4)
       qsdict.remove (qsdict.length()-4,4);
+
+
+  if(dictcombo)
+  {
+    int whichelement=-1;
+    if (dictFromList())
+    {
+      for (unsigned int i=0;i<langfnames.count();i++)
+      {
+         if (langfnames[i] == s)
+           whichelement=i;
+      }
+
+      if(whichelement >= 0)
+      {
+        dictcombo->setCurrentItem(whichelement);
+      }
+    }
+  }
 
-  //  kdebug (KDEBUG_INFO, 750, "setdictionary: [%s]",qsdict.data());
+
 }
 
 void
@@ -517,6 +575,9 @@
 KSpellConfig::setEncoding (int enctype)
 {
   enc=enctype;
+
+  if(encodingcombo)
+    encodingcombo->setCurrentItem(enctype);
 }
 
 /*
Index: ksconfig.h
===================================================================
RCS file: /home/kde/kdelibs/kspell/ksconfig.h,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- ksconfig.h	2000/06/29 00:42:36	1.26
+++ ksconfig.h	2000/10/20 17:39:38	1.27
@@ -26,10 +26,21 @@
 
 class KConfig;
 
+// Should be replaced by the charset strings
+// because the config file would be more stable
+// when inserting entries in the list
 enum Encoding {
   KS_E_ASCII=0,
   KS_E_LATIN1=1,
-  KS_E_LATIN2=2
+  KS_E_LATIN2=2,
+  KS_E_LATIN3=3,
+  KS_E_LATIN4=4,
+  KS_E_LATIN5=5,
+  KS_E_LATIN7=6,
+  KS_E_LATIN8=7,
+  KS_E_LATIN9=8,
+  KS_E_LATIN15=9,
+  KS_E_UTF8=10
 };
 
 enum KSpellClients {
@@ -40,7 +51,7 @@
 /**
  * A configuration class/dialog for @ref KSpell.
  *
- * It contains all of the options settings.The options are set to default 
+ * It contains all of the options settings.The options are set to default
  * values by the constructor and can be reset either by using the 
  * public interface or by using @ref KSpellConfig as a widget in a dialog 
  * (or, preferably a tabbed dialog using @ref KDialogBase) and letting 
@@ -54,7 +65,7 @@
  * writing papers in their word processor.
  *
  * @author David Sweet <dsweet@kde.org>
- * @version $Id: ksconfig.h,v 1.26 2000/06/29 00:42:36 dsweet Exp $
+ * @version $Id: ksconfig.h,v 1.27 2000/10/20 17:39:38 wolfram Exp $
  * @see KSpell
  */
 
Index: kspell.cpp
===================================================================
RCS file: /home/kde/kdelibs/kspell/kspell.cpp,v
retrieving revision 1.51
retrieving revision 1.62
diff -u -r1.51 -r1.62
--- kspell.cpp	2000/10/12 18:12:35	1.51
+++ kspell.cpp	2000/10/29 19:22:53	1.62
@@ -16,7 +16,7 @@
    Boston, MA 02111-1307, USA.
 */
 
-// $Id: kspell.cpp,v 1.51 2000/10/12 18:12:35 waba Exp $
+// $Id: kspell.cpp,v 1.62 2000/10/29 19:22:53 wolfram Exp $
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -40,7 +40,7 @@
 #include "kspell.h"
 #include <kwin.h>
 
-#define MAXLINELENGTH 150
+#define MAXLINELENGTH 10000
 
 enum {
 	GOOD=     0,
@@ -99,6 +99,30 @@
   case KS_E_LATIN2:
      codec = QTextCodec::codecForName("ISO 8859-2");
      break;
+  case KS_E_LATIN3:
+      codec = QTextCodec::codecForName("ISO 8859-3");
+      break;
+  case KS_E_LATIN4:
+      codec = QTextCodec::codecForName("ISO 8859-4");
+      break;
+  case KS_E_LATIN5:
+      codec = QTextCodec::codecForName("ISO 8859-5");
+      break;
+  case KS_E_LATIN7:
+      codec = QTextCodec::codecForName("ISO 8859-7");
+      break;
+  case KS_E_LATIN8:
+      codec = QTextCodec::codecForName("ISO 8859-8");
+      break;
+  case KS_E_LATIN9:
+      codec = QTextCodec::codecForName("ISO 8859-9");
+      break;
+  case KS_E_LATIN15:
+      codec = QTextCodec::codecForName("ISO 8859-15");
+      break;
+  case KS_E_UTF8:
+      codec = QTextCodec::codecForName("UTF-8");
+      break;
   default:
      break;
   }
@@ -192,6 +216,25 @@
       case KS_E_LATIN2:
 	*proc << "-Tlatin2";
 	break;
+      case KS_E_LATIN3:
+        *proc << "-Tlatin3";
+        break;
+
+      // add the other charsets here    
+      case KS_E_LATIN4:
+      case KS_E_LATIN5:
+      case KS_E_LATIN7:
+      case KS_E_LATIN8:
+      case KS_E_LATIN9:
+      case KS_E_LATIN15:
+      
+	// will work, if this is the default charset in the dictionary
+	kdError(750) << "charsets iso-8859-4 .. iso-8859-15 not supported yet" << endl;
+	break;
+
+      case KS_E_UTF8:
+        *proc << "-Tutf8";
+        break;
       }
 
 
@@ -332,17 +375,26 @@
 KSpell::cleanFputsWord (QString s, bool appendCR)
 {
   QString qs(s);
+  bool firstchar = TRUE;
+  bool empty = TRUE;
 
-  for (unsigned int i=0;i<qs.length();i++)
+  for (unsigned int i=0; i<qs.length(); i++)
   {
-    //we need some puctuation for ornaments
-    if (qs.at(i)!='\'' && qs.at(i)!='\"')
-      if (
-	  ispunct ((char)(QChar)qs.at(i)) // #### Should use qs[i].isPunct()
-	    || qs[i].isSpace())
-	  qs.remove(i,1);
+    //we need some punctuation for ornaments
+    if (qs[i] != '\'' && qs[i] != '\"' && !qs[i].isLetter() &&
+    // permit hyphen when it's not at the beginning of the word 
+	(firstchar || qs[i] != '-')) {
+      qs.remove(i,1);
+      i--;
+    } else {
+      firstchar = FALSE; 
+      if (qs[i].isLetter()) empty=FALSE;
+    }
   }
 
+  // don't check empty words, otherwise synchronisation fails
+  if (empty) return FALSE;
+
   return proc->fputs(qs, appendCR);
 }
 
@@ -350,23 +402,31 @@
 KSpell::cleanFputs (QString s, bool appendCR)
 {
   QString qs(s);
-  unsigned int j=0,l=qs.length();
+  unsigned l = qs.length();
+  bool firstchar = TRUE;
+
+  //  kdDebug(750) << "KS::cleanFputs (before)" << qs.length() << " [" << qs <<"]" \
<< endl;  
+  // Why we need this stuff?
   if (l<MAXLINELENGTH)
     {
-      for (unsigned int i=0;i<l;i++,j++)
+      for (unsigned int i=0; i<l; i++)
 	{
-	  if (//qs.at(i-1)=='\n' &&
-	      ispunct ((char)(QChar)qs.at(i)) // #### Should use qs[i].isPunct()
-	    && qs.at(i)!='\'' && qs.at(i)!='\"')
-	    qs.replace (i,1," ");
-	
+	  if ( !qs[i].isLetter() && qs[i] != '\'' && qs[i] != '\"' 
+	       && !qs[i].isSpace() &&
+	    // let hyphens pass, but in the beginning, where ispell would
+	    // interpret it as a control char
+	    (firstchar || qs[i] != '-')) {
+	      qs.replace (i,1," ");
+	    } else firstchar = FALSE; 
 	}
 
       if (qs.isEmpty())
 	qs="";
 
-      return proc->fputs (qs.ascii(), appendCR);
+      // kdDebug(750) << "KS::cleanFputs (after) " << qs.length() << " [" << qs << \
"]" << endl; +
+      return proc->fputs (qs, appendCR);
     }
   else
     return proc->fputs ("\n",appendCR);
@@ -398,7 +458,7 @@
   //  connect (this, SIGNAL (dialog3()), this, SLOT (checkWord3()));
 
   proc->fputs ("%"); // turn off terse mode
-  proc->fputs (buffer.ascii()); // send the word to ispell
+  proc->fputs (buffer); // send the word to ispell
 
   return TRUE;
 }
@@ -484,7 +544,7 @@
 
   sugg->clear();
 
-  if (buffer [0]=='*')
+  if (buffer [0]=='*' || buffer[0] == '+' || buffer[0] == '-')
     {
       return GOOD;
     }
@@ -561,60 +621,70 @@
   return MISTAKE;
 }
 
-
 bool KSpell::checkList (QStringList *_wordlist)
+  // prepare check or string list
 {
   wordlist=_wordlist;
   if ((totalpos=wordlist->count())==0)
     return FALSE;
   wlIt = wordlist->begin();
 
+  // prepare the dialog
   setUpDialog();
 
-  //  ksdlg->show(); //only show if we need it
-
   //set the dialog signal handler
   dialog3slot = SLOT (checkList4 ());
 
   proc->fputs ("%"); // turn off terse mode & check one word at a time
   lastpos=0; //now counts which *word number* we are at in checkList3()
-  connect (this, SIGNAL (eza()), this, SLOT (checkList2()));
-  emit eza();
+
+  //  connect (this, SIGNAL (eza()), this, SLOT (checkList2()));
+  //emit eza();
+
+  lastpos = -1;
+  checkList2();
+
+  // when checked, KProcIO calls checkList3a
   OUTPUT(checkList3a);
 
   return TRUE;
 }
 
 void KSpell::checkList2 ()
-  //output some words from the list
+  // send one word from the list to KProcIO
+  // invoked first time by checkList, later by checkList3 and checkList4
 {
-  //  disconnect (this, SIGNAL (eza()), this, SLOT (checkList2()));
-  if (wlIt == wordlist->end())
-  {
-     NOOUTPUT(checkList3a);
-     ksdlg->hide();
-     emit done(TRUE);
-  }
+  // send next word
+  if (wlIt != wordlist->end())
+    {
+      kdDebug(750) << "KS::cklist2 " << lastpos << ": " << *wlIt << endl;
+
+      bool put;
+      lastpos++; offset=0;
+      put = cleanFputsWord (*wlIt);
+      wlIt++;
+
+      // when cleanFPutsWord failed (e.g. on empty word)
+      // try next word; may be this is not good for other
+      // problems, because this will make read the list up to the end
+      if (!put) {
+	checkList2();
+      }
+    }
   else
-  {
-     cleanFputsWord (*wlIt);
-     wlIt++;
-  }
+    // end of word list
+    {
+      NOOUTPUT(checkList3a);
+      ksdlg->hide();
+      emit done(TRUE);
+    }
 }
 
 void KSpell::checkList3a (KProcIO *)
+  // invoked by KProcIO, when data from ispell are read
 {
-  connect (this, SIGNAL (ez()), this, SLOT (checkList3()));
-  emit ez();
-}
-
-void KSpell::checkList3 ()
-{
   int e, tempe;
 
-  disconnect (this, SIGNAL (ez()), this, SLOT (checkList3()));
-
-
   QString word;
   QString line;
 
@@ -623,25 +693,25 @@
 	tempe=proc->fgets (line, TRUE); //get ispell's response
 	if (tempe>0)
 	  {
-	    lastpos++;
 	    //kdDebug(750) << "lastpos advance on [" << temp << "]" << endl;
 	    if ((e=parseOneResponse (line, word, &sugg))==MISTAKE ||
 		e==REPLACE)
 	      {
 		dlgresult=-1;
 
-		//orig is set by parseOneResponse()
-		//		lastpos=newbuffer.find (orig,lastpos,TRUE);
-
 		if (e==REPLACE)
 		  {
-		    emit corrected (orig, replacement(), lastpos);
-		    //  newbuffer.replace (lastpos,orig.length(),word);
+		    QString old = *(--wlIt); wlIt++;
+		    dlgreplacement=word;   
+		    checkList3();
+		    // inform application  
+		    emit corrected (old, *(--wlIt), lastpos); wlIt++;
 		  }
 		else
 		  {
 		    cwword=word;
 		    dlgon=TRUE;
+		    // show the dialog
 		    dialog (word, &sugg, SLOT (checkList4()));
 		    return;
 		  }
@@ -652,12 +722,30 @@
       } while (tempe>=0);
 
     if (!dlgon) //is this condition needed?
-      emit eza();
+      // send next word
+      checkList2();
+}
+
+// rename to "checkListReplaceCurrent", when binary compatibility isn't needed
+void KSpell::checkList3 () {
+
+  // go back to misspelled word
+  wlIt--;
+
+  QString s = *wlIt;
+  s.replace(posinline+offset,orig.length(),replacement());
+  offset += replacement().length()-orig.length();
+  wordlist->insert (wlIt, s);
+  wlIt = wordlist->remove (wlIt);
+  // wlIt now points to the word after the repalced one
+  
 }
 
 void KSpell::checkList4 ()
+  // evaluate dialog return, when a button was pressed there
 {
   dlgon=FALSE;
+  QString old;
 
   disconnect (this, SIGNAL (dialog3()), this, SLOT (checkList4()));
 
@@ -666,10 +754,11 @@
     {
     case KS_REPLACE:
     case KS_REPLACEALL:
-      kdDebug(750) << "cklist4: lastpos==(" << lastpos << ")" << endl;
-      wordlist->remove (wlIt);
-      wordlist->insert (wlIt, replacement());
-      wlIt++;
+      kdDebug(750) << "KS: cklist4: lastpos: " << lastpos << endl;
+      old = *(--wlIt); wlIt++;
+      // replace word
+      checkList3();
+      emit corrected (old, *(--wlIt), lastpos); wlIt++;
       break;
     case KS_CANCEL:
       ksdlg->hide();
@@ -681,7 +770,8 @@
       break;
     };
 
-  emit eza();
+  // read more if there is more
+  checkList3a(NULL);
 }
 
 bool KSpell::check( const QString &_buffer )
@@ -716,6 +806,9 @@
 
   newbuffer=origbuffer;
 
+  kdDebug(750) << "{" << newbuffer << "}" << endl;
+
+  // KProcIO calls check2 when read from ispell
   OUTPUT(check2);
   proc->fputs ("!");
 
@@ -724,8 +817,9 @@
 
   emitProgress ();
 
-  int i = origbuffer.find('\n', lastline)+1;
-  qs=origbuffer.mid (lastline, i-lastline);
+  // send first buffer line
+  int i = origbuffer.find('\n', 0)+1;
+  qs=origbuffer.mid (0,i);
   cleanFputs (qs,FALSE);
 
   lastline=i; //the character position, not a line number
@@ -737,6 +831,7 @@
 }
 
 void KSpell::check2 (KProcIO *)
+  // invoked by KProcIO when read from ispell
 {
   int e, tempe;
   QString word;
@@ -745,16 +840,29 @@
   do
     {
       tempe=proc->fgets (line); //get ispell's response
-      kdDebug(750) << "2:(" << tempe << ")" << endl;
+      kdDebug(750) << "KSpell::check2 (" << tempe << "b)" << endl;
 
       if (tempe>0)
 	{
-	  //kdDebug(750) << "2:[" << temp << "]" << endl;
-	
 	  if ((e=parseOneResponse (line, word, &sugg))==MISTAKE ||
 	      e==REPLACE)
 	    {
 	      dlgresult=-1;
+
+	      // for multibyte encoding posinline needs correction
+	      if (ksconfig->encoding() == KS_E_UTF8) {
+		// kdDebug(750) << "line: " << origbuffer.mid(lastlastline,
+		// lastline-lastlastline) << endl;
+		// kdDebug(750) << "posinline uncorr: " << posinline << endl;
+
+		// convert line to UTF-8, cut at pos, convert back to UCS-2
+		// and get string length
+		posinline = (QString::fromUtf8(
+		   origbuffer.mid(lastlastline,lastline-lastlastline).utf8(),
+		   posinline)).length();
+		// kdDebug(750) << "posinline corr: " << posinline << endl;
+	      }
+	      
 	      lastpos=posinline+lastlastline+offset;
 	
 	      //orig is set by parseOneResponse()
@@ -771,6 +879,7 @@
 		  cwword=word;
 		  //kdDebug(750) << "(Before dialog) word=[" << word << "] cwword =[" << cwword << \
"]\n" << endl;  
+		  // show the word in the dialog
 		  dialog (word, &sugg, SLOT (check3()));
 		  return;
 		}
@@ -799,13 +908,12 @@
       lastpos=(lastlastline=lastline)+offset; //do we really want this?
       i=origbuffer.find('\n', lastline)+1;
       qs=origbuffer.mid (lastline, i-lastline);
-      cleanFputs (qs.ascii(),FALSE);
+      cleanFputs (qs,FALSE);
       lastline=i;
       return;
     }
   else
   //This is the end of it all
-    //  if (lastline==-1)
     {
       ksdlg->hide();
       //      kdDebug(750) << "check2() done" << endl;
@@ -813,10 +921,10 @@
       emitProgress();
       emit done (newbuffer);
     }
-
 }
 
 void KSpell::check3 ()
+  // evaluates the return value of the dialog
 {
   disconnect (this, SIGNAL (dialog3()), this, SLOT (check3()));
 
@@ -829,7 +937,8 @@
     case KS_REPLACEALL:
       offset+=replacement().length()-cwword.length();
       newbuffer.replace (lastpos, cwword.length(),
-			 replacement().ascii());
+			 replacement());
+      emit corrected (dlgorigword, replacement(), lastpos);
       break;
     case KS_CANCEL:
     //      kdDebug(750) << "cancelled\n" << endl;
@@ -865,7 +974,7 @@
 }
 
 
-void KSpell::dialog (QString word, QStringList *sugg, const char *_slot)
+void KSpell::dialog(QString word, QStringList *sugg, const char *_slot)
 {
   dlgorigword=word;
 
@@ -893,6 +1002,7 @@
   //process result here
   switch (dlgresult)
     {
+
     case KS_IGNOREALL:
       ignorelist.prepend(dlgorigword.lower());
       break;
@@ -904,10 +1014,15 @@
     case KS_REPLACEALL:
       replacelist.append (dlgorigword);
       replacelist.append (replacement());
+      /*
+    case KS_REPLACE:
+    emit corrected (dlgorigword, replacement(), lastpos);
+*/
       break;
     }
 
-  emit corrected (dlgorigword, replacement(), lastpos);
+  
+  // emit corrected (dlgorigword, replacement(), lastpos);
   connect (this, SIGNAL (dialog3()), this, dialog3slot.ascii());
   emit dialog3();
 }
@@ -1043,7 +1158,7 @@
 void KSpell::slotModalReady()
 {
   //kdDebug() << qApp->loopLevel() << endl;
-  // kdDebug() << "MODAL READY" << endl;
+  //kdDebug(750) << "MODAL READY" << endl;
   
   ASSERT( m_status == Running );
   connect( this, SIGNAL( done( const QString & ) ), 
@@ -1054,7 +1169,7 @@
 
 void KSpell::slotModalDone( const QString &_buffer )
 {
-    // kdDebug() << "MODAL DONE " << _buffer << endl;
+  //kdDebug(750) << "MODAL DONE " << _buffer << endl;
     modaltext = _buffer;
     cleanUp();
 
@@ -1070,3 +1185,4 @@
 
 
 #include "kspell.moc"
+
Index: kspell.h
===================================================================
RCS file: /home/kde/kdelibs/kspell/kspell.h,v
retrieving revision 1.24
retrieving revision 1.26
diff -u -r1.24 -r1.26
--- kspell.h	2000/06/25 16:53:37	1.24
+++ kspell.h	2000/10/29 07:51:52	1.26
@@ -33,7 +33,7 @@
  *  access to the spellchecker.
  *
  * @author David Sweet <dsweet@kde.org>
- * @version $Id: kspell.h,v 1.24 2000/06/25 16:53:37 dsweet Exp $
+ * @version $Id: kspell.h,v 1.26 2000/10/29 07:51:52 wolfram Exp $
  * @see KSpellConfig
  */
 
@@ -280,6 +280,8 @@
    *  If it is emitted by @ref checkList(), @p pos is the index to
    *  the misspelled
    *   word in the @ref QStringList passed to @ref checkList().
+   *  Note, that @p originalword can be only a word part, if it's
+   *  word with hyphens.
    *
    *  These are called _before_ the dialog is opened, so that the
    *   calling program's GUI may be updated. (e.g. the misspelled word may
@@ -289,12 +291,17 @@
 		    unsigned pos);
 
   /**
-   * Emitted after the dialog is closed, or if the word was 
+   * Emitted after the "Replace" or "Replace All" buttons of the dialog
+   * was pressed, or if the word was 
    * corrected without calling the dialog (i.e., the user previously chose
    * "Replace All" for this word). 
    *
    * Results from the dialog may be checked with @ref dlgResult()
    *  and @ref replacement().
+   *
+   * Note, that when using @ref checkList() this signal cann occure
+   * more then once with same list position, when checking a word with
+   * hyphens. In this case @p orignalword is the last replacement.
    *
    * @see check()
    */
Index: kspelldlg.cpp
===================================================================
RCS file: /home/kde/kdelibs/kspell/kspelldlg.cpp,v
retrieving revision 1.26
retrieving revision 1.28
diff -u -r1.26 -r1.28
--- kspelldlg.cpp	2000/09/23 20:02:11	1.26
+++ kspelldlg.cpp	2000/10/26 12:29:47	1.28
@@ -28,6 +28,7 @@
 #include <klineedit.h>
 #include <kprogress.h>
 #include <kbuttonbox.h>
+#include <kdebug.h>
 
 #include "kspelldlg.h"
 
@@ -38,7 +39,7 @@
   bool _modal
 )
   : KDialogBase(
-      parent, name, _modal, i18n("Check spelling"), Help|Close, Close, true
+      parent, name, _modal, i18n("Check spelling"), Help|Cancel, Cancel, true
     ),
     progressbar(_progressbar)
 {
@@ -142,6 +143,8 @@
 
   listbox->clear();
   listbox->insertStringList(*sugg);
+
+  kdDebug(750) << "KSpellDlg::init [" << word << "]" << endl; 
 
   emit(ready(true));
 
Index: kspelltest.cpp
===================================================================
RCS file: /home/kde/kdelibs/kspell/kspelltest.cpp,v
retrieving revision 1.4
retrieving revision 1.6
diff -u -r1.4 -r1.6
--- kspelltest.cpp	2000/07/04 19:38:59	1.4
+++ kspelltest.cpp	2000/10/24 12:09:41	1.6
@@ -22,20 +22,39 @@
 
 #include <qstring.h>
 #include <qlabel.h>
+#include <qtextcodec.h>
 
 int main(int argc, char **argv)
 {
     KApplication *app = new KApplication(argc, argv, "KSpellTest");
 
-    QString text( "I have noo idee of how to wride englisch or englisch" );
+    // test ASCII
+    //QString text( "I have noo idee of how to wride englisch or englisch" );
+
+    // test Latin-3 (need dictionary "esperanto" and "Latin3" in config)
+    //QCString ctext( "sed jen: eĥoŝanĝ' ĉiuĵaŭde; eĥuŝunĝo ĝiun fendredon - kaj \
dimanĝon..."); +    //QTextCodec *codec = QTextCodec::codecForName("ISO 8859-3");
+
+    // test UTF-8 (need dictionary "esperanto" and "UTF-8" in config)  
+   QCString ctext( "sed jen: e\304\245oĊanĝo ĉiuĵaĊ­de e\304\245uĊunĝo ĝiun \
fendredon kaj dimanĝon"); +   QTextCodec *codec = QTextCodec::codecForName("UTF-8");
     
+    QString text = codec->toUnicode(ctext.data());
+
     KSpell::modalCheck( text );
-    
+
     kdDebug() << "Returned " << text << endl;
-    
+
     QLabel* l = new QLabel( text, (QWidget*)0 );
     l->show();
-    
+
     return(app->exec());
+
 }
+
+
+
+
+
+
 



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic