00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "katespell.h"
00025 #include "katespell.moc"
00026
00027 #include "kateview.h"
00028
00029 #include <kaction.h>
00030 #include <kstdaction.h>
00031 #include <kspell.h>
00032 #include <kdebug.h>
00033 #include <kmessagebox.h>
00034
00035 KateSpell::KateSpell( KateView* view )
00036 : QObject( view )
00037 , m_view (view)
00038 , m_kspell (0)
00039 {
00040 }
00041
00042 KateSpell::~KateSpell()
00043 {
00044
00045 if( m_kspell )
00046 {
00047 m_kspell->setAutoDelete(true);
00048 m_kspell->cleanUp();
00049 delete m_kspell;
00050 }
00051 }
00052
00053 void KateSpell::createActions( KActionCollection* ac )
00054 {
00055 KStdAction::spelling( this, SLOT(spellcheck()), ac );
00056 KAction *a = new KAction( i18n("Spelling (from cursor)..."), "spellcheck", 0, this, SLOT(spellcheckFromCursor()), ac, "tools_spelling_from_cursor" );
00057 a->setWhatsThis(i18n("Check the document's spelling from the cursor and forward"));
00058
00059 m_spellcheckSelection = new KAction( i18n("Spellcheck Selection..."), "spellcheck", 0, this, SLOT(spellcheckSelection()), ac, "tools_spelling_selection" );
00060 m_spellcheckSelection->setWhatsThis(i18n("Check spelling of the selected text"));
00061 }
00062
00063 void KateSpell::updateActions ()
00064 {
00065 m_spellcheckSelection->setEnabled (m_view->hasSelection ());
00066 }
00067
00068 void KateSpell::spellcheckFromCursor()
00069 {
00070 spellcheck( KateTextCursor(m_view->cursorLine(), m_view->cursorColumnReal()) );
00071 }
00072
00073 void KateSpell::spellcheckSelection()
00074 {
00075 KateTextCursor from( m_view->selStartLine(), m_view->selStartCol() );
00076 KateTextCursor to( m_view->selEndLine(), m_view->selEndCol() );
00077 spellcheck( from, to );
00078 }
00079
00080 void KateSpell::spellcheck()
00081 {
00082 spellcheck( KateTextCursor( 0, 0 ) );
00083 }
00084
00085 void KateSpell::spellcheck( const KateTextCursor &from, const KateTextCursor &to )
00086 {
00087 m_spellStart = from;
00088 m_spellEnd = to;
00089
00090 if ( to.line() == 0 && to.col() == 0 )
00091 {
00092 int lln = m_view->doc()->lastLine();
00093 m_spellEnd.setLine( lln );
00094 m_spellEnd.setCol( m_view->doc()->lineLength( lln ) );
00095 }
00096
00097 m_spellPosCursor = from;
00098 m_spellLastPos = 0;
00099
00100 QString mt = m_view->doc()->mimeType();
00101
00102 KSpell::SpellerType type = KSpell::Text;
00103 if ( mt == "text/x-tex" || mt == "text/x-latex" )
00104 type = KSpell::TeX;
00105 else if ( mt == "text/html" || mt == "text/xml" )
00106 type = KSpell::HTML;
00107
00108 m_kspell = new KSpell( 0, i18n("Spellcheck"),
00109 this, SLOT(ready(KSpell *)), 0, true, false, type );
00110
00111 connect( m_kspell, SIGNAL(death()),
00112 this, SLOT(spellCleanDone()) );
00113
00114 connect( m_kspell, SIGNAL(misspelling(const QString&, const QStringList&, unsigned int)),
00115 this, SLOT(misspelling(const QString&, const QStringList&, unsigned int)) );
00116 connect( m_kspell, SIGNAL(corrected(const QString&, const QString&, unsigned int)),
00117 this, SLOT(corrected(const QString&, const QString&, unsigned int)) );
00118 connect( m_kspell, SIGNAL(done(const QString&)),
00119 this, SLOT(spellResult(const QString&)) );
00120 }
00121
00122 void KateSpell::ready(KSpell *)
00123 {
00124 m_kspell->setProgressResolution( 1 );
00125
00126 m_kspell->check( m_view->doc()->text( m_spellStart.line(), m_spellStart.col(), m_spellEnd.line(), m_spellEnd.col() ) );
00127
00128 kdDebug (13020) << "SPELLING READY STATUS: " << m_kspell->status () << endl;
00129 }
00130
00131 void KateSpell::locatePosition( uint pos, uint& line, uint& col )
00132 {
00133 uint remains;
00134
00135 while ( m_spellLastPos < pos )
00136 {
00137 remains = pos - m_spellLastPos;
00138 uint l = m_view->doc()->lineLength( m_spellPosCursor.line() ) - m_spellPosCursor.col();
00139 if ( l > remains )
00140 {
00141 m_spellPosCursor.setCol( m_spellPosCursor.col() + remains );
00142 m_spellLastPos = pos;
00143 }
00144 else
00145 {
00146 m_spellPosCursor.setLine( m_spellPosCursor.line() + 1 );
00147 m_spellPosCursor.setCol(0);
00148 m_spellLastPos += l + 1;
00149 }
00150 }
00151
00152 line = m_spellPosCursor.line();
00153 col = m_spellPosCursor.col();
00154 }
00155
00156 void KateSpell::misspelling( const QString& origword, const QStringList&, unsigned int pos )
00157 {
00158 uint line, col;
00159
00160 locatePosition( pos, line, col );
00161
00162 m_view->setCursorPositionInternal (line, col, 1);
00163 m_view->setSelection( line, col, line, col + origword.length() );
00164 }
00165
00166 void KateSpell::corrected( const QString& originalword, const QString& newword, unsigned int pos )
00167 {
00168 uint line, col;
00169
00170 locatePosition( pos, line, col );
00171
00172 m_view->doc()->removeText( line, col, line, col + originalword.length() );
00173 m_view->doc()->insertText( line, col, newword );
00174 }
00175
00176 void KateSpell::spellResult( const QString& )
00177 {
00178 m_view->clearSelection();
00179 m_kspell->cleanUp();
00180 }
00181
00182 void KateSpell::spellCleanDone()
00183 {
00184 KSpell::spellStatus status = m_kspell->status();
00185
00186 if( status == KSpell::Error ) {
00187 KMessageBox::sorry( 0,
00188 i18n("The spelling program could not be started. "
00189 "Please make sure you have set the correct spelling program "
00190 "and that it is properly configured and in your PATH."));
00191 } else if( status == KSpell::Crashed ) {
00192 KMessageBox::sorry( 0,
00193 i18n("The spelling program seems to have crashed."));
00194 }
00195
00196 delete m_kspell;
00197 m_kspell = 0;
00198
00199 kdDebug (13020) << "SPELLING END" << endl;
00200 }
00201
00202
00203
00204