KDE3Support
k3textedit.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2002 Carsten Pfeiffer <pfeiffer@kde.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "k3textedit.h" 00021 00022 #include <QtGui/QApplication> 00023 #include <QtGui/QClipboard> 00024 #include <Qt3Support/Q3PopupMenu> 00025 00026 #include <k3syntaxhighlighter.h> 00027 #include <k3spell.h> 00028 #include <kcursor.h> 00029 #include <kglobalsettings.h> 00030 #include <kstandardshortcut.h> 00031 #include <kicon.h> 00032 #include <klocale.h> 00033 #include <QKeyEvent> 00034 00035 class K3TextEdit::K3TextEditPrivate 00036 { 00037 public: 00038 K3TextEditPrivate() 00039 : customPalette( false ), 00040 checkSpellingEnabled( false ), 00041 highlighter( 0 ), 00042 spell( 0 ) 00043 {} 00044 ~K3TextEditPrivate() { 00045 delete highlighter; 00046 delete spell; 00047 } 00048 00049 bool customPalette; 00050 bool checkSpellingEnabled; 00051 K3DictSpellingHighlighter *highlighter; 00052 K3Spell *spell; 00053 }; 00054 00055 K3TextEdit::K3TextEdit( const QString& text, const QString& context, 00056 QWidget *parent, const char *name ) 00057 : Q3TextEdit ( text, context, parent, name ) 00058 { 00059 d = new K3TextEditPrivate(); 00060 KCursor::setAutoHideCursor( this, true, false ); 00061 } 00062 00063 K3TextEdit::K3TextEdit( QWidget *parent, const char *name ) 00064 : Q3TextEdit ( parent, name ) 00065 { 00066 d = new K3TextEditPrivate(); 00067 KCursor::setAutoHideCursor( this, true, false ); 00068 } 00069 00070 K3TextEdit::~K3TextEdit() 00071 { 00072 delete d; 00073 } 00074 00075 void K3TextEdit::keyPressEvent( QKeyEvent *e ) 00076 { 00077 int key = e->key(); 00078 00079 if ( KStandardShortcut::copy().contains( key ) ) { 00080 copy(); 00081 e->accept(); 00082 return; 00083 } 00084 else if ( KStandardShortcut::paste().contains( key ) ) { 00085 paste(); 00086 e->accept(); 00087 return; 00088 } 00089 else if ( KStandardShortcut::cut().contains( key ) ) { 00090 cut(); 00091 e->accept(); 00092 return; 00093 } 00094 else if ( KStandardShortcut::undo().contains( key ) ) { 00095 undo(); 00096 e->accept(); 00097 return; 00098 } 00099 else if ( KStandardShortcut::redo().contains( key ) ) { 00100 redo(); 00101 e->accept(); 00102 return; 00103 } 00104 else if ( KStandardShortcut::deleteWordBack().contains( key ) ) 00105 { 00106 deleteWordBack(); 00107 e->accept(); 00108 return; 00109 } 00110 else if ( KStandardShortcut::deleteWordForward().contains( key ) ) 00111 { 00112 deleteWordForward(); 00113 e->accept(); 00114 return; 00115 } 00116 else if ( KStandardShortcut::backwardWord().contains( key ) ) 00117 { 00118 CursorAction action = MoveWordBackward; 00119 int para, index; 00120 getCursorPosition( ¶, & index ); 00121 if (text(para).isRightToLeft()) 00122 action = MoveWordForward; 00123 moveCursor(action, false ); 00124 e->accept(); 00125 return; 00126 } 00127 else if ( KStandardShortcut::forwardWord().contains( key ) ) 00128 { 00129 CursorAction action = MoveWordForward; 00130 int para, index; 00131 getCursorPosition( ¶, & index ); 00132 if (text(para).isRightToLeft()) 00133 action = MoveWordBackward; 00134 moveCursor( action, false ); 00135 e->accept(); 00136 return; 00137 } 00138 else if ( KStandardShortcut::next().contains( key ) ) 00139 { 00140 moveCursor( MovePgDown, false ); 00141 e->accept(); 00142 return; 00143 } 00144 else if ( KStandardShortcut::prior().contains( key ) ) 00145 { 00146 moveCursor( MovePgUp, false ); 00147 e->accept(); 00148 return; 00149 } 00150 else if ( KStandardShortcut::begin().contains( key ) ) 00151 { 00152 moveCursor( MoveHome, false ); 00153 e->accept(); 00154 return; 00155 } 00156 else if ( KStandardShortcut::end().contains( key ) ) 00157 { 00158 moveCursor( MoveEnd, false ); 00159 e->accept(); 00160 return; 00161 } 00162 else if ( KStandardShortcut::beginningOfLine().contains( key ) ) 00163 { 00164 moveCursor( MoveLineStart, false ); 00165 e->accept(); 00166 return; 00167 } 00168 else if ( KStandardShortcut::endOfLine().contains( key ) ) 00169 { 00170 moveCursor(MoveLineEnd, false); 00171 e->accept(); 00172 return; 00173 } 00174 else if ( KStandardShortcut::pasteSelection().contains( key ) ) 00175 { 00176 QString text = QApplication::clipboard()->text( QClipboard::Selection); 00177 if ( !text.isEmpty() ) 00178 insert( text ); 00179 e->accept(); 00180 return; 00181 } 00182 00183 // ignore Ctrl-Return so that KDialogs can close the dialog 00184 else if ( e->state() == Qt::ControlModifier && 00185 (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) && 00186 topLevelWidget()->inherits( "KDialog" ) ) 00187 { 00188 e->ignore(); 00189 return; 00190 } 00191 00192 Q3TextEdit::keyPressEvent( e ); 00193 } 00194 00195 void K3TextEdit::deleteWordBack() 00196 { 00197 removeSelection(); 00198 moveCursor( MoveWordBackward, true ); 00199 removeSelectedText(); 00200 } 00201 00202 void K3TextEdit::deleteWordForward() 00203 { 00204 removeSelection(); 00205 moveCursor( MoveWordForward, true ); 00206 removeSelectedText(); 00207 } 00208 00209 void K3TextEdit::slotAllowTab() 00210 { 00211 setTabChangesFocus(!tabChangesFocus()); 00212 } 00213 00214 Q3PopupMenu *K3TextEdit::createPopupMenu( const QPoint &pos ) 00215 { 00216 enum { IdUndo, IdRedo, IdSep1, IdCut, IdCopy, IdPaste, IdClear, IdSep2, IdSelectAll }; 00217 00218 Q3PopupMenu *menu = Q3TextEdit::createPopupMenu( pos ); 00219 00220 if ( isReadOnly() ) 00221 menu->changeItem( menu->idAt(0), KIcon("edit-copy"), menu->text( menu->idAt(0) ) ); 00222 else { 00223 int id = menu->idAt(0); 00224 menu->changeItem( id - IdUndo, KIcon("edit-undo"), menu->text( id - IdUndo) ); 00225 menu->changeItem( id - IdRedo, KIcon("edit-redo"), menu->text( id - IdRedo) ); 00226 menu->changeItem( id - IdCut, KIcon("edit-cut"), menu->text( id - IdCut) ); 00227 menu->changeItem( id - IdCopy, KIcon("edit-copy"), menu->text( id - IdCopy) ); 00228 menu->changeItem( id - IdPaste, KIcon("edit-paste"), menu->text( id - IdPaste) ); 00229 menu->changeItem( id - IdClear, KIcon("edit-clear"), menu->text( id - IdClear) ); 00230 00231 menu->insertSeparator(); 00232 id = menu->insertItem( KIcon( "tools-check-spelling" ), i18n( "Check Spelling..." ), 00233 this, SLOT( checkSpelling() ) ); 00234 00235 if( text().isEmpty() ) 00236 menu->setItemEnabled( id, false ); 00237 00238 id = menu->insertItem( i18n( "Auto Spell Check" ), 00239 this, SLOT( toggleAutoSpellCheck() ) ); 00240 menu->setItemChecked(id, d->checkSpellingEnabled); 00241 menu->insertSeparator(); 00242 id=menu->insertItem(i18n("Allow Tabulations"),this,SLOT(slotAllowTab())); 00243 menu->setItemChecked(id, !tabChangesFocus()); 00244 } 00245 00246 return menu; 00247 } 00248 00249 Q3PopupMenu *K3TextEdit::createPopupMenu() 00250 { 00251 return Q3TextEdit::createPopupMenu(); 00252 } 00253 00254 void K3TextEdit::contentsWheelEvent( QWheelEvent *e ) 00255 { 00256 if ( KGlobalSettings::wheelMouseZooms() ) 00257 Q3TextEdit::contentsWheelEvent( e ); 00258 else // thanks, we don't want to zoom, so skip QTextEdit's impl. 00259 Q3ScrollView::contentsWheelEvent( e ); 00260 } 00261 00262 void K3TextEdit::setPalette( const QPalette& palette ) 00263 { 00264 Q3TextEdit::setPalette( palette ); 00265 // unsetPalette() is not virtual and calls setPalette() as well 00266 // so we can use ownPalette() to find out about unsetting 00267 d->customPalette = ownPalette(); 00268 } 00269 00270 void K3TextEdit::toggleAutoSpellCheck() 00271 { 00272 setCheckSpellingEnabled( !d->checkSpellingEnabled ); 00273 } 00274 00275 void K3TextEdit::setCheckSpellingEnabled( bool check ) 00276 { 00277 if ( check == d->checkSpellingEnabled ) 00278 return; 00279 00280 // From the above statment we know know that if we're turning checking 00281 // on that we need to create a new highlighter and if we're turning it 00282 // off we should remove the old one. 00283 00284 d->checkSpellingEnabled = check; 00285 if ( check ) 00286 { 00287 if (hasFocus()) 00288 d->highlighter = new K3DictSpellingHighlighter( this ); 00289 } 00290 else 00291 { 00292 delete d->highlighter; 00293 d->highlighter = 0; 00294 } 00295 } 00296 00297 void K3TextEdit::focusInEvent( QFocusEvent *e ) 00298 { 00299 if ( d->checkSpellingEnabled && !d->highlighter ) 00300 d->highlighter = new K3DictSpellingHighlighter( this ); 00301 00302 Q3TextEdit::focusInEvent( e ); 00303 } 00304 00305 bool K3TextEdit::checkSpellingEnabled() const 00306 { 00307 return d->checkSpellingEnabled; 00308 } 00309 00310 void K3TextEdit::setReadOnly(bool readOnly) 00311 { 00312 if ( readOnly == isReadOnly() ) 00313 return; 00314 00315 if (readOnly) 00316 { 00317 bool custom = ownPalette(); 00318 QPalette p = palette(); 00319 QColor color = p.color(QPalette::Disabled, QPalette::Background); 00320 p.setColor(QPalette::Base, color); 00321 p.setColor(QPalette::Background, color); 00322 setPalette(p); 00323 d->customPalette = custom; 00324 } 00325 else 00326 { 00327 if ( d->customPalette ) 00328 { 00329 QPalette p = palette(); 00330 QColor color = p.color(QPalette::Normal, QPalette::Base); 00331 p.setColor(QPalette::Base, color); 00332 p.setColor(QPalette::Background, color); 00333 setPalette( p ); 00334 } 00335 else 00336 unsetPalette(); 00337 } 00338 00339 Q3TextEdit::setReadOnly (readOnly); 00340 } 00341 00342 void K3TextEdit::virtual_hook( int, void* ) 00343 { /*BASE::virtual_hook( id, data );*/ } 00344 00345 void K3TextEdit::checkSpelling() 00346 { 00347 delete d->spell; 00348 d->spell = new K3Spell( this, i18n( "Spell Checking" ), 00349 this, SLOT( slotSpellCheckReady( K3Spell *) ), 0, true, true); 00350 00351 connect( d->spell, SIGNAL( death() ), 00352 this, SLOT( spellCheckerFinished() ) ); 00353 00354 connect( d->spell, SIGNAL( misspelling( const QString &, const QStringList &, unsigned int ) ), 00355 this, SLOT( spellCheckerMisspelling( const QString &, const QStringList &, unsigned int ) ) ); 00356 00357 connect( d->spell, SIGNAL( corrected( const QString &, const QString &, unsigned int ) ), 00358 this, SLOT( spellCheckerCorrected( const QString &, const QString &, unsigned int ) ) ); 00359 } 00360 00361 void K3TextEdit::spellCheckerMisspelling( const QString &text, const QStringList &, unsigned int pos ) 00362 { 00363 highLightWord( text.length(), pos ); 00364 } 00365 00366 void K3TextEdit::spellCheckerCorrected( const QString &oldWord, const QString &newWord, unsigned int pos ) 00367 { 00368 unsigned int l = 0; 00369 unsigned int cnt = 0; 00370 if ( oldWord != newWord ) { 00371 posToRowCol( pos, l, cnt ); 00372 setSelection( l, cnt, l, cnt + oldWord.length() ); 00373 removeSelectedText(); 00374 insert( newWord ); 00375 } 00376 } 00377 00378 void K3TextEdit::posToRowCol(unsigned int pos, unsigned int &line, unsigned int &col) 00379 { 00380 for ( line = 0; line < static_cast<uint>( lines() ) && col <= pos; line++ ) 00381 col += paragraphLength( line ) + 1; 00382 00383 line--; 00384 col = pos - col + paragraphLength( line ) + 1; 00385 } 00386 00387 void K3TextEdit::spellCheckerFinished() 00388 { 00389 delete d->spell; 00390 d->spell = 0L; 00391 } 00392 00393 void K3TextEdit::slotSpellCheckReady( K3Spell *s ) 00394 { 00395 s->check( text() ); 00396 connect( s, SIGNAL( done( const QString & ) ), this, SLOT( slotSpellCheckDone( const QString & ) ) ); 00397 } 00398 00399 void K3TextEdit::slotSpellCheckDone( const QString &s ) 00400 { 00401 if ( s != text() ) 00402 setText( s ); 00403 } 00404 00405 00406 void K3TextEdit::highLightWord( unsigned int length, unsigned int pos ) 00407 { 00408 unsigned int l = 0; 00409 unsigned int cnt = 0; 00410 posToRowCol( pos, l, cnt ); 00411 setSelection( l, cnt, l, cnt + length ); 00412 } 00413 00414 #include "k3textedit.moc"
KDE 4.6 API Reference