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