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