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 QPopupMenu *menu = QTextEdit::createPopupMenu( pos );
00155
00156 if ( checkSpellingEnabled() && !isReadOnly() ) {
00157
00158 menu->insertSeparator();
00159 int id = menu->insertItem( SmallIcon( "spellcheck" ), i18n( "Check Spelling..." ),
00160 this, SLOT( checkSpelling() ) );
00161
00162 if( text().isEmpty() )
00163 menu->setItemEnabled( id, false );
00164 }
00165
00166 return menu;
00167 }
00168
00169 QPopupMenu *KTextEdit::createPopupMenu()
00170 {
00171 return QTextEdit::createPopupMenu();
00172 }
00173
00174 void KTextEdit::contentsWheelEvent( QWheelEvent *e )
00175 {
00176 if ( KGlobalSettings::wheelMouseZooms() )
00177 QTextEdit::contentsWheelEvent( e );
00178 else
00179 QScrollView::contentsWheelEvent( e );
00180 }
00181
00182 void KTextEdit::setPalette( const QPalette& palette )
00183 {
00184 QTextEdit::setPalette( palette );
00185
00186
00187 d->customPalette = ownPalette();
00188 }
00189
00190 void KTextEdit::setCheckSpellingEnabled( bool check )
00191 {
00192 if ( check == d->checkSpellingEnabled )
00193 return;
00194
00195
00196
00197
00198
00199 d->checkSpellingEnabled = check;
00200 if ( hasFocus() )
00201 d->highlighter = new KDictSpellingHighlighter( this );
00202 else {
00203 delete d->highlighter;
00204 d->highlighter = 0;
00205 }
00206 }
00207
00208 void KTextEdit::focusInEvent( QFocusEvent *e )
00209 {
00210 if ( d->checkSpellingEnabled && !d->highlighter )
00211 d->highlighter = new KDictSpellingHighlighter( this );
00212
00213 QTextEdit::focusInEvent( e );
00214 }
00215
00216 bool KTextEdit::checkSpellingEnabled() const
00217 {
00218 return d->checkSpellingEnabled;
00219 }
00220
00221 void KTextEdit::setReadOnly(bool readOnly)
00222 {
00223 if ( readOnly == isReadOnly() )
00224 return;
00225
00226 if (readOnly)
00227 {
00228 bool custom = ownPalette();
00229 QPalette p = palette();
00230 QColor color = p.color(QPalette::Disabled, QColorGroup::Background);
00231 p.setColor(QColorGroup::Base, color);
00232 p.setColor(QColorGroup::Background, color);
00233 setPalette(p);
00234 d->customPalette = custom;
00235 }
00236 else
00237 {
00238 if ( d->customPalette )
00239 {
00240 QPalette p = palette();
00241 QColor color = p.color(QPalette::Normal, QColorGroup::Base);
00242 p.setColor(QColorGroup::Base, color);
00243 p.setColor(QColorGroup::Background, color);
00244 setPalette( p );
00245 }
00246 else
00247 unsetPalette();
00248 }
00249
00250 QTextEdit::setReadOnly (readOnly);
00251 }
00252
00253 void KTextEdit::virtual_hook( int, void* )
00254 { }
00255
00256 void KTextEdit::checkSpelling()
00257 {
00258 delete d->spell;
00259 d->spell = new KSpell( this, i18n( "Spell Checking" ),
00260 this, SLOT( slotSpellCheckReady( KSpell *) ), 0, true, true);
00261
00262 connect( d->spell, SIGNAL( death() ),
00263 this, SLOT( spellCheckerFinished() ) );
00264
00265 connect( d->spell, SIGNAL( misspelling( const QString &, const QStringList &, unsigned int ) ),
00266 this, SLOT( spellCheckerMisspelling( const QString &, const QStringList &, unsigned int ) ) );
00267
00268 connect( d->spell, SIGNAL( corrected( const QString &, const QString &, unsigned int ) ),
00269 this, SLOT( spellCheckerCorrected( const QString &, const QString &, unsigned int ) ) );
00270 }
00271
00272 void KTextEdit::spellCheckerMisspelling( const QString &text, const QStringList &, unsigned int pos )
00273 {
00274 highLightWord( text.length(), pos );
00275 }
00276
00277 void KTextEdit::spellCheckerCorrected( const QString &oldWord, const QString &newWord, unsigned int pos )
00278 {
00279 unsigned int l = 0;
00280 unsigned int cnt = 0;
00281 if ( oldWord != newWord ) {
00282 posToRowCol( pos, l, cnt );
00283 setSelection( l, cnt, l, cnt + oldWord.length() );
00284 removeSelectedText();
00285 insert( newWord );
00286 }
00287 }
00288
00289 void KTextEdit::posToRowCol(unsigned int pos, unsigned int &line, unsigned int &col)
00290 {
00291 for ( line = 0; line < static_cast<uint>( lines() ) && col <= pos; line++ )
00292 col += paragraphLength( line ) + 1;
00293
00294 line--;
00295 col = pos - col + paragraphLength( line ) + 1;
00296 }
00297
00298 void KTextEdit::spellCheckerFinished()
00299 {
00300 delete d->spell;
00301 d->spell = 0L;
00302 }
00303
00304 void KTextEdit::slotSpellCheckReady( KSpell *s )
00305 {
00306 s->check( text() );
00307 connect( s, SIGNAL( done( const QString & ) ), this, SLOT( slotSpellCheckDone( const QString & ) ) );
00308 }
00309
00310 void KTextEdit::slotSpellCheckDone( const QString &s )
00311 {
00312 if ( s != text() )
00313 setText( s );
00314 }
00315
00316
00317 void KTextEdit::highLightWord( unsigned int length, unsigned int pos )
00318 {
00319 unsigned int l = 0;
00320 unsigned int cnt = 0;
00321 posToRowCol( pos, l, cnt );
00322 setSelection( l, cnt, l, cnt + length );
00323 }
00324
00325 #include "ktextedit.moc"