kdeui Library API Documentation

ktextedit.cpp

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., 59 Temple Place - Suite 330,
00017    Boston, MA 02111-1307, USA.
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     // ignore Ctrl-Return so that KDialogs can close the dialog
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 // thanks, we don't want to zoom, so skip QTextEdit's impl.
00250         QScrollView::contentsWheelEvent( e );
00251 }
00252 
00253 void KTextEdit::setPalette( const QPalette& palette )
00254 {
00255     QTextEdit::setPalette( palette );
00256     // unsetPalette() is not virtual and calls setPalette() as well
00257     // so we can use ownPalette() to find out about unsetting
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     // From the above statment we know know that if we're turning checking
00272     // on that we need to create a new highlighter and if we're turning it
00273     // off we should remove the old one.
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 { /*BASE::virtual_hook( id, data );*/ }
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"
KDE Logo
This file is part of the documentation for kdeui Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Nov 27 13:43:15 2004 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003