00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include "ktextedit.h"
00021
00022
#include <qapplication.h>
00023
#include <qclipboard.h>
00024
#include <qpopupmenu.h>
00025
00026
#include <ksyntaxhighlighter.h>
00027
#include <kspell.h>
00028
#include <kcursor.h>
00029
#include <kglobalsettings.h>
00030
#include <kstdaccel.h>
00031
#include <kiconloader.h>
00032
#include <klocale.h>
00033
00034
class KTextEdit::KTextEditPrivate
00035 {
00036
public:
00037 KTextEditPrivate()
00038 : customPalette( false ),
00039 checkSpellingEnabled( false ),
00040 highlighter( 0 ),
00041 spell( 0 )
00042 {}
00043 ~KTextEditPrivate() {
00044
delete highlighter;
00045
delete spell;
00046 }
00047
00048
bool customPalette;
00049
bool checkSpellingEnabled;
00050 KDictSpellingHighlighter *highlighter;
00051
KSpell *spell;
00052 };
00053
00054 KTextEdit::KTextEdit(
const QString& text,
const QString& context,
00055
QWidget *parent,
const char *name )
00056 :
QTextEdit ( text, context, parent, name )
00057 {
00058 d =
new KTextEditPrivate();
00059
KCursor::setAutoHideCursor(
this,
true,
false );
00060 }
00061
00062 KTextEdit::KTextEdit(
QWidget *parent,
const char *name )
00063 :
QTextEdit ( parent, name )
00064 {
00065 d =
new KTextEditPrivate();
00066
KCursor::setAutoHideCursor(
this,
true,
false );
00067 }
00068
00069 KTextEdit::~KTextEdit()
00070 {
00071
delete d;
00072 }
00073
00074 void KTextEdit::keyPressEvent(
QKeyEvent *e )
00075 {
00076
KKey key( e );
00077
00078
if (
KStdAccel::copy().
contains( key ) ) {
00079 copy();
00080 e->accept();
00081
return;
00082 }
00083
else if (
KStdAccel::paste().
contains( key ) ) {
00084 paste();
00085 e->accept();
00086
return;
00087 }
00088
else if (
KStdAccel::cut().
contains( key ) ) {
00089 cut();
00090 e->accept();
00091
return;
00092 }
00093
else if (
KStdAccel::undo().
contains( key ) ) {
00094 undo();
00095 e->accept();
00096
return;
00097 }
00098
else if (
KStdAccel::redo().
contains( key ) ) {
00099 redo();
00100 e->accept();
00101
return;
00102 }
00103
else if (
KStdAccel::deleteWordBack().
contains( key ) )
00104 {
00105
deleteWordBack();
00106 e->accept();
00107
return;
00108 }
00109
else if (
KStdAccel::deleteWordForward().
contains( key ) )
00110 {
00111
deleteWordForward();
00112 e->accept();
00113
return;
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
else if (
KStdAccel::next().
contains( key ) )
00134 {
00135 moveCursor( MovePgDown,
false );
00136 e->accept();
00137
return;
00138 }
00139
else if (
KStdAccel::prior().
contains( key ) )
00140 {
00141 moveCursor( MovePgUp,
false );
00142 e->accept();
00143
return;
00144 }
00145
else if (
KStdAccel::home().
contains( key ) )
00146 {
00147 moveCursor( MoveHome,
false );
00148 e->accept();
00149
return;
00150 }
00151
else if (
KStdAccel::end().
contains( key ) )
00152 {
00153 moveCursor( MoveEnd,
false );
00154 e->accept();
00155
return;
00156 }
00157
else if (
KStdAccel::beginningOfLine().
contains( key ) )
00158 {
00159 moveCursor( MoveLineStart,
false );
00160 e->accept();
00161
return;
00162 }
00163
else if (
KStdAccel::endOfLine().
contains( key ) )
00164 {
00165 moveCursor(MoveLineEnd,
false);
00166 e->accept();
00167
return;
00168 }
00169
00170
else if ( e->key() == Key_Insert &&
00171 (e->state() == (ShiftButton | ControlButton)) )
00172 {
00173
QString text = QApplication::clipboard()->text( QClipboard::Selection);
00174
if ( !text.isEmpty() )
00175 insert( text );
00176 e->accept();
00177
return;
00178 }
00179
00180
00181
else if ( e->state() == ControlButton &&
00182 (e->key() == Key_Return || e->key() == Key_Enter) &&
00183 topLevelWidget()->inherits(
"KDialog" ) )
00184 {
00185 e->ignore();
00186
return;
00187 }
00188
00189 QTextEdit::keyPressEvent( e );
00190 }
00191
00192 void KTextEdit::deleteWordBack()
00193 {
00194 removeSelection();
00195 moveCursor( MoveWordBackward,
true );
00196 removeSelectedText();
00197 }
00198
00199 void KTextEdit::deleteWordForward()
00200 {
00201 removeSelection();
00202 moveCursor( MoveWordForward,
true );
00203 removeSelectedText();
00204 }
00205
00206
void KTextEdit::slotAllowTab()
00207 {
00208 setTabChangesFocus(!tabChangesFocus());
00209 }
00210
00211 QPopupMenu *
KTextEdit::createPopupMenu(
const QPoint &pos )
00212 {
00213
enum { IdUndo, IdRedo, IdSep1, IdCut, IdCopy, IdPaste, IdClear, IdSep2, IdSelectAll };
00214
00215
QPopupMenu *menu = QTextEdit::createPopupMenu( pos );
00216
00217
if ( isReadOnly() )
00218 menu->changeItem( menu->idAt(0), SmallIconSet(
"editcopy"), menu->text( menu->idAt(0) ) );
00219
else {
00220
int id = menu->idAt(0);
00221 menu->changeItem(
id - IdUndo, SmallIconSet(
"undo"), menu->text(
id - IdUndo) );
00222 menu->changeItem(
id - IdRedo, SmallIconSet(
"redo"), menu->text(
id - IdRedo) );
00223 menu->changeItem(
id - IdCut, SmallIconSet(
"editcut"), menu->text(
id - IdCut) );
00224 menu->changeItem(
id - IdCopy, SmallIconSet(
"editcopy"), menu->text(
id - IdCopy) );
00225 menu->changeItem(
id - IdPaste, SmallIconSet(
"editpaste"), menu->text(
id - IdPaste) );
00226 menu->changeItem(
id - IdClear, SmallIconSet(
"editclear"), menu->text(
id - IdClear) );
00227
00228 menu->insertSeparator();
00229
id = menu->insertItem( SmallIconSet(
"spellcheck" ), i18n(
"Check Spelling..." ),
00230
this, SLOT(
checkSpelling() ) );
00231
00232
if( text().isEmpty() )
00233 menu->setItemEnabled(
id,
false );
00234
00235
id = menu->insertItem( i18n(
"Auto Spell Check" ),
00236
this, SLOT( toggleAutoSpellCheck() ) );
00237 menu->setItemChecked(
id, d->checkSpellingEnabled);
00238 menu->insertSeparator();
00239
id=menu->insertItem(i18n(
"Allow Tabulations"),
this,SLOT(slotAllowTab()));
00240 menu->setItemChecked(
id, !tabChangesFocus());
00241 }
00242
00243
return menu;
00244 }
00245
00246 QPopupMenu *
KTextEdit::createPopupMenu()
00247 {
00248
return QTextEdit::createPopupMenu();
00249 }
00250
00251 void KTextEdit::contentsWheelEvent(
QWheelEvent *e )
00252 {
00253
if (
KGlobalSettings::wheelMouseZooms() )
00254 QTextEdit::contentsWheelEvent( e );
00255
else
00256 QScrollView::contentsWheelEvent( e );
00257 }
00258
00259 void KTextEdit::setPalette(
const QPalette& palette )
00260 {
00261 QTextEdit::setPalette( palette );
00262
00263
00264 d->customPalette = ownPalette();
00265 }
00266
00267
void KTextEdit::toggleAutoSpellCheck()
00268 {
00269
setCheckSpellingEnabled( !d->checkSpellingEnabled );
00270 }
00271
00272 void KTextEdit::setCheckSpellingEnabled(
bool check )
00273 {
00274
if ( check == d->checkSpellingEnabled )
00275
return;
00276
00277
00278
00279
00280
00281 d->checkSpellingEnabled = check;
00282
if ( check )
00283 {
00284
if (hasFocus())
00285 d->highlighter =
new KDictSpellingHighlighter(
this );
00286 }
00287
else
00288 {
00289
delete d->highlighter;
00290 d->highlighter = 0;
00291 }
00292 }
00293
00294 void KTextEdit::focusInEvent(
QFocusEvent *e )
00295 {
00296
if ( d->checkSpellingEnabled && !d->highlighter )
00297 d->highlighter =
new KDictSpellingHighlighter(
this );
00298
00299 QTextEdit::focusInEvent( e );
00300 }
00301
00302 bool KTextEdit::checkSpellingEnabled()
const
00303
{
00304
return d->checkSpellingEnabled;
00305 }
00306
00307 void KTextEdit::setReadOnly(
bool readOnly)
00308 {
00309
if ( readOnly == isReadOnly() )
00310
return;
00311
00312
if (readOnly)
00313 {
00314
bool custom = ownPalette();
00315
QPalette p = palette();
00316
QColor color = p.color(QPalette::Disabled, QColorGroup::Background);
00317 p.setColor(QColorGroup::Base, color);
00318 p.setColor(QColorGroup::Background, color);
00319
setPalette(p);
00320 d->customPalette = custom;
00321 }
00322
else
00323 {
00324
if ( d->customPalette )
00325 {
00326
QPalette p = palette();
00327
QColor color = p.color(QPalette::Normal, QColorGroup::Base);
00328 p.setColor(QColorGroup::Base, color);
00329 p.setColor(QColorGroup::Background, color);
00330
setPalette( p );
00331 }
00332
else
00333 unsetPalette();
00334 }
00335
00336 QTextEdit::setReadOnly (readOnly);
00337 }
00338
00339
void KTextEdit::virtual_hook(
int,
void* )
00340 { }
00341
00342 void KTextEdit::checkSpelling()
00343 {
00344
delete d->spell;
00345 d->spell =
new KSpell(
this, i18n(
"Spell Checking" ),
00346
this, SLOT( slotSpellCheckReady(
KSpell *) ), 0,
true,
true);
00347
00348 connect( d->spell, SIGNAL( death() ),
00349
this, SLOT( spellCheckerFinished() ) );
00350
00351 connect( d->spell, SIGNAL( misspelling(
const QString &,
const QStringList &,
unsigned int ) ),
00352
this, SLOT( spellCheckerMisspelling(
const QString &,
const QStringList &,
unsigned int ) ) );
00353
00354 connect( d->spell, SIGNAL( corrected(
const QString &,
const QString &,
unsigned int ) ),
00355
this, SLOT( spellCheckerCorrected(
const QString &,
const QString &,
unsigned int ) ) );
00356 }
00357
00358
void KTextEdit::spellCheckerMisspelling(
const QString &text,
const QStringList &,
unsigned int pos )
00359 {
00360 highLightWord( text.length(), pos );
00361 }
00362
00363
void KTextEdit::spellCheckerCorrected(
const QString &oldWord,
const QString &newWord,
unsigned int pos )
00364 {
00365
unsigned int l = 0;
00366
unsigned int cnt = 0;
00367
if ( oldWord != newWord ) {
00368 posToRowCol( pos, l, cnt );
00369 setSelection( l, cnt, l, cnt + oldWord.length() );
00370 removeSelectedText();
00371
insert( newWord );
00372 }
00373 }
00374
00375
void KTextEdit::posToRowCol(
unsigned int pos,
unsigned int &line,
unsigned int &col)
00376 {
00377
for ( line = 0; line < static_cast<uint>( lines() ) && col <= pos; line++ )
00378 col += paragraphLength( line ) + 1;
00379
00380 line--;
00381 col = pos - col + paragraphLength( line ) + 1;
00382 }
00383
00384
void KTextEdit::spellCheckerFinished()
00385 {
00386
delete d->spell;
00387 d->spell = 0L;
00388 }
00389
00390
void KTextEdit::slotSpellCheckReady(
KSpell *s )
00391 {
00392 s->
check( text() );
00393 connect( s, SIGNAL( done(
const QString & ) ),
this, SLOT( slotSpellCheckDone(
const QString & ) ) );
00394 }
00395
00396
void KTextEdit::slotSpellCheckDone(
const QString &s )
00397 {
00398
if ( s != text() )
00399 setText( s );
00400 }
00401
00402
00403
void KTextEdit::highLightWord(
unsigned int length,
unsigned int pos )
00404 {
00405
unsigned int l = 0;
00406
unsigned int cnt = 0;
00407 posToRowCol( pos, l, cnt );
00408 setSelection( l, cnt, l, cnt + length );
00409 }
00410
00411
#include "ktextedit.moc"