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
else if (
KStdAccel::backwardWord().
contains( key ) )
00116 {
00117 moveCursor(MoveWordBackward,
false );
00118 e->accept();
00119
return;
00120 }
00121
else if (
KStdAccel::forwardWord().
contains( key ) )
00122 {
00123 moveCursor( MoveWordForward,
false );
00124 e->accept();
00125
return;
00126 }
00127
else if (
KStdAccel::next().
contains( key ) )
00128 {
00129 moveCursor( MovePgDown,
false );
00130 e->accept();
00131
return;
00132 }
00133
else if (
KStdAccel::prior().
contains( key ) )
00134 {
00135 moveCursor( MovePgUp,
false );
00136 e->accept();
00137
return;
00138 }
00139
else if (
KStdAccel::home().
contains( key ) )
00140 {
00141 moveCursor( MoveHome,
false );
00142 e->accept();
00143
return;
00144 }
00145
else if (
KStdAccel::end().
contains( key ) )
00146 {
00147 moveCursor( MoveEnd,
false );
00148 e->accept();
00149
return;
00150 }
00151
else if (
KStdAccel::beginningOfLine().
contains( key ) )
00152 {
00153 moveCursor( MoveLineStart,
false );
00154 e->accept();
00155
return;
00156 }
00157
else if (
KStdAccel::endOfLine().
contains( key ) )
00158 {
00159 moveCursor(MoveLineEnd,
false);
00160 e->accept();
00161
return;
00162 }
00163
00164
else if ( e->key() == Key_Insert &&
00165 (e->state() == (ShiftButton | ControlButton)) )
00166 {
00167
QString text = QApplication::clipboard()->text( QClipboard::Selection);
00168
if ( !text.isEmpty() )
00169 insert( text );
00170 e->accept();
00171
return;
00172 }
00173
00174
00175
else if ( e->state() == ControlButton &&
00176 (e->key() == Key_Return || e->key() == Key_Enter) &&
00177 topLevelWidget()->inherits(
"KDialog" ) )
00178 {
00179 e->ignore();
00180
return;
00181 }
00182
00183 QTextEdit::keyPressEvent( e );
00184 }
00185
00186 void KTextEdit::deleteWordBack()
00187 {
00188 removeSelection();
00189 moveCursor( MoveWordBackward,
true );
00190 removeSelectedText();
00191 }
00192
00193 void KTextEdit::deleteWordForward()
00194 {
00195 removeSelection();
00196 moveCursor( MoveWordForward,
true );
00197 removeSelectedText();
00198 }
00199
00200
void KTextEdit::slotAllowTab()
00201 {
00202 setTabChangesFocus(!tabChangesFocus());
00203 }
00204
00205 QPopupMenu *
KTextEdit::createPopupMenu(
const QPoint &pos )
00206 {
00207
enum { IdUndo, IdRedo, IdSep1, IdCut, IdCopy, IdPaste, IdClear, IdSep2, IdSelectAll };
00208
00209
QPopupMenu *menu = QTextEdit::createPopupMenu( pos );
00210
00211
if ( isReadOnly() )
00212 menu->changeItem( menu->idAt(0), SmallIconSet(
"editcopy"), menu->text( menu->idAt(0) ) );
00213
else {
00214
int id = menu->idAt(0);
00215 menu->changeItem(
id - IdUndo, SmallIconSet(
"undo"), menu->text(
id - IdUndo) );
00216 menu->changeItem(
id - IdRedo, SmallIconSet(
"redo"), menu->text(
id - IdRedo) );
00217 menu->changeItem(
id - IdCut, SmallIconSet(
"editcut"), menu->text(
id - IdCut) );
00218 menu->changeItem(
id - IdCopy, SmallIconSet(
"editcopy"), menu->text(
id - IdCopy) );
00219 menu->changeItem(
id - IdPaste, SmallIconSet(
"editpaste"), menu->text(
id - IdPaste) );
00220 menu->changeItem(
id - IdClear, SmallIconSet(
"editclear"), menu->text(
id - IdClear) );
00221
00222 menu->insertSeparator();
00223
id = menu->insertItem( SmallIconSet(
"spellcheck" ), i18n(
"Check Spelling..." ),
00224
this, SLOT(
checkSpelling() ) );
00225
00226
if( text().isEmpty() )
00227 menu->setItemEnabled(
id,
false );
00228
00229
id = menu->insertItem( i18n(
"Auto Spell Check" ),
00230
this, SLOT( toggleAutoSpellCheck() ) );
00231 menu->setItemChecked(
id, d->checkSpellingEnabled);
00232 menu->insertSeparator();
00233
id=menu->insertItem(i18n(
"Allow Tabulations"),
this,SLOT(slotAllowTab()));
00234 menu->setItemChecked(
id, !tabChangesFocus());
00235 }
00236
00237
return menu;
00238 }
00239
00240 QPopupMenu *
KTextEdit::createPopupMenu()
00241 {
00242
return QTextEdit::createPopupMenu();
00243 }
00244
00245 void KTextEdit::contentsWheelEvent(
QWheelEvent *e )
00246 {
00247
if (
KGlobalSettings::wheelMouseZooms() )
00248 QTextEdit::contentsWheelEvent( e );
00249
else
00250 QScrollView::contentsWheelEvent( e );
00251 }
00252
00253 void KTextEdit::setPalette(
const QPalette& palette )
00254 {
00255 QTextEdit::setPalette( palette );
00256
00257
00258 d->customPalette = ownPalette();
00259 }
00260
00261
void KTextEdit::toggleAutoSpellCheck()
00262 {
00263
setCheckSpellingEnabled( !d->checkSpellingEnabled );
00264 }
00265
00266 void KTextEdit::setCheckSpellingEnabled(
bool check )
00267 {
00268
if ( check == d->checkSpellingEnabled )
00269
return;
00270
00271
00272
00273
00274
00275 d->checkSpellingEnabled = check;
00276
if ( check )
00277 {
00278
if (hasFocus())
00279 d->highlighter =
new KDictSpellingHighlighter(
this );
00280 }
00281
else
00282 {
00283
delete d->highlighter;
00284 d->highlighter = 0;
00285 }
00286 }
00287
00288 void KTextEdit::focusInEvent(
QFocusEvent *e )
00289 {
00290
if ( d->checkSpellingEnabled && !d->highlighter )
00291 d->highlighter =
new KDictSpellingHighlighter(
this );
00292
00293 QTextEdit::focusInEvent( e );
00294 }
00295
00296 bool KTextEdit::checkSpellingEnabled()
const
00297
{
00298
return d->checkSpellingEnabled;
00299 }
00300
00301 void KTextEdit::setReadOnly(
bool readOnly)
00302 {
00303
if ( readOnly == isReadOnly() )
00304
return;
00305
00306
if (readOnly)
00307 {
00308
bool custom = ownPalette();
00309
QPalette p = palette();
00310
QColor color = p.color(QPalette::Disabled, QColorGroup::Background);
00311 p.setColor(QColorGroup::Base, color);
00312 p.setColor(QColorGroup::Background, color);
00313
setPalette(p);
00314 d->customPalette = custom;
00315 }
00316
else
00317 {
00318
if ( d->customPalette )
00319 {
00320
QPalette p = palette();
00321
QColor color = p.color(QPalette::Normal, QColorGroup::Base);
00322 p.setColor(QColorGroup::Base, color);
00323 p.setColor(QColorGroup::Background, color);
00324
setPalette( p );
00325 }
00326
else
00327 unsetPalette();
00328 }
00329
00330 QTextEdit::setReadOnly (readOnly);
00331 }
00332
00333
void KTextEdit::virtual_hook(
int,
void* )
00334 { }
00335
00336 void KTextEdit::checkSpelling()
00337 {
00338
delete d->spell;
00339 d->spell =
new KSpell(
this, i18n(
"Spell Checking" ),
00340
this, SLOT( slotSpellCheckReady(
KSpell *) ), 0,
true,
true);
00341
00342 connect( d->spell, SIGNAL( death() ),
00343
this, SLOT( spellCheckerFinished() ) );
00344
00345 connect( d->spell, SIGNAL( misspelling(
const QString &,
const QStringList &,
unsigned int ) ),
00346
this, SLOT( spellCheckerMisspelling(
const QString &,
const QStringList &,
unsigned int ) ) );
00347
00348 connect( d->spell, SIGNAL( corrected(
const QString &,
const QString &,
unsigned int ) ),
00349
this, SLOT( spellCheckerCorrected(
const QString &,
const QString &,
unsigned int ) ) );
00350 }
00351
00352
void KTextEdit::spellCheckerMisspelling(
const QString &text,
const QStringList &,
unsigned int pos )
00353 {
00354 highLightWord( text.length(), pos );
00355 }
00356
00357
void KTextEdit::spellCheckerCorrected(
const QString &oldWord,
const QString &newWord,
unsigned int pos )
00358 {
00359
unsigned int l = 0;
00360
unsigned int cnt = 0;
00361
if ( oldWord != newWord ) {
00362 posToRowCol( pos, l, cnt );
00363 setSelection( l, cnt, l, cnt + oldWord.length() );
00364 removeSelectedText();
00365
insert( newWord );
00366 }
00367 }
00368
00369
void KTextEdit::posToRowCol(
unsigned int pos,
unsigned int &line,
unsigned int &col)
00370 {
00371
for ( line = 0; line < static_cast<uint>( lines() ) && col <= pos; line++ )
00372 col += paragraphLength( line ) + 1;
00373
00374 line--;
00375 col = pos - col + paragraphLength( line ) + 1;
00376 }
00377
00378
void KTextEdit::spellCheckerFinished()
00379 {
00380
delete d->spell;
00381 d->spell = 0L;
00382 }
00383
00384
void KTextEdit::slotSpellCheckReady(
KSpell *s )
00385 {
00386 s->
check( text() );
00387 connect( s, SIGNAL( done(
const QString & ) ),
this, SLOT( slotSpellCheckDone(
const QString & ) ) );
00388 }
00389
00390
void KTextEdit::slotSpellCheckDone(
const QString &s )
00391 {
00392
if ( s != text() )
00393 setText( s );
00394 }
00395
00396
00397
void KTextEdit::highLightWord(
unsigned int length,
unsigned int pos )
00398 {
00399
unsigned int l = 0;
00400
unsigned int cnt = 0;
00401 posToRowCol( pos, l, cnt );
00402 setSelection( l, cnt, l, cnt + length );
00403 }
00404
00405
#include "ktextedit.moc"