• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDEUI

ktextedit.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                  2005 Michael Brade <brade@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018    Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "ktextedit.h"
00022 
00023 #include <QApplication>
00024 #include <QClipboard>
00025 #include <QKeyEvent>
00026 #include <QScrollBar>
00027 #include <QTextCursor>
00028 #include <dialog.h>
00029 #include "backgroundchecker.h"
00030 #include <kaction.h>
00031 #include <kcursor.h>
00032 #include <kglobalsettings.h>
00033 #include <kstandardaction.h>
00034 #include <kstandardshortcut.h>
00035 #include <kicon.h>
00036 #include <kiconloader.h>
00037 #include <klocale.h>
00038 #include <kdialog.h>
00039 #include <kreplacedialog.h>
00040 #include <kfinddialog.h>
00041 #include <kfind.h>
00042 #include <kreplace.h>
00043 #include <QMenu>
00044 #include <kmessagebox.h>
00045 #include <kwindowsystem.h>
00046 
00047 class KTextEdit::Private
00048 {
00049   public:
00050     Private( KTextEdit *_parent )
00051       : parent( _parent ),
00052         customPalette( false ),
00053         checkSpellingEnabled( false ),
00054         findReplaceEnabled(true),
00055         highlighter( 0 ), findDlg(0),find(0),repDlg(0),replace(0), findIndex(0), repIndex(0)
00056     {
00057     }
00058 
00059     ~Private()
00060     {
00061       delete highlighter;
00062       delete findDlg;
00063       delete find;
00064       delete replace;
00065       delete repDlg;
00066     }
00067 
00073     bool overrideShortcut(const QKeyEvent* e);
00077     bool handleShortcut(const QKeyEvent* e);
00078 
00079     void slotSpellCheckDone( const QString &s );
00080 
00081     void spellCheckerMisspelling( const QString &text, int pos );
00082     void spellCheckerCorrected( const QString &, int,const QString &);
00083     void spellCheckerAutoCorrect(const QString&,const QString&);
00084     void spellCheckerCanceled();
00085     void spellCheckerFinished();
00086     void toggleAutoSpellCheck();
00087 
00088     void slotFindHighlight(const QString& text, int matchingIndex, int matchingLength);
00089     void slotReplaceText(const QString &text, int replacementIndex, int /*replacedLength*/, int matchedLength);
00090 
00095     void undoableClear();
00096 
00097     void slotAllowTab();
00098     void menuActivated( QAction* action );
00099 
00100     KTextEdit *parent;
00101     QAction *autoSpellCheckAction;
00102     QAction *allowTab;
00103     QAction *spellCheckAction;
00104     bool customPalette : 1;
00105 
00106     bool checkSpellingEnabled : 1;
00107     bool findReplaceEnabled: 1;
00108     QString originalBuffer;
00109     QString spellChechingConfigFileName;
00110     QString spellCheckingLanguage;
00111     Sonnet::Highlighter *highlighter;
00112     KFindDialog *findDlg;
00113     KFind *find;
00114     KReplaceDialog *repDlg;
00115     KReplace *replace;
00116     int findIndex, repIndex;
00117 };
00118 
00119 void KTextEdit::Private::spellCheckerCanceled()
00120 {
00121     parent->selectAll();
00122     parent->setPlainText(originalBuffer);
00123     spellCheckerFinished();
00124 }
00125 
00126 void KTextEdit::Private::spellCheckerAutoCorrect(const QString&,const QString&)
00127 {
00128     //TODO
00129 }
00130 
00131 void KTextEdit::Private::slotSpellCheckDone( const QString &s )
00132 {
00133 //Necessary ?
00134 //    if ( s != text() ) // TODO: toPlainText()?? (MiB)
00135 //        setText( s ); // setPlainText() ?! we'd loose rich text info
00136 }
00137 
00138 void KTextEdit::Private::spellCheckerMisspelling( const QString &text, int pos )
00139 {
00140     //kDebug()<<"TextEdit::Private::spellCheckerMisspelling :"<<text<<" pos :"<<pos;
00141     parent->highlightWord( text.length(), pos );
00142 }
00143 
00144 void KTextEdit::Private::spellCheckerCorrected( const QString& oldWord, int pos,const QString& newWord)
00145 {
00146   //kDebug()<<" oldWord :"<<oldWord<<" newWord :"<<newWord<<" pos : "<<pos;
00147   if (oldWord != newWord ) {
00148     QTextCursor cursor(parent->document());
00149     cursor.setPosition(pos);
00150     cursor.setPosition(pos+oldWord.length(),QTextCursor::KeepAnchor);
00151     cursor.insertText(newWord);
00152   }
00153 }
00154 
00155 void KTextEdit::Private::spellCheckerFinished()
00156 {
00157    QTextCursor cursor(parent->document());
00158    cursor.clearSelection();
00159    parent->setTextCursor(cursor);
00160    if (parent->highlighter())
00161        parent->highlighter()->rehighlight();
00162 }
00163 
00164 void KTextEdit::Private::toggleAutoSpellCheck()
00165 {
00166   parent->setCheckSpellingEnabled( !checkSpellingEnabled );
00167 }
00168 
00169 void KTextEdit::Private::undoableClear()
00170 {
00171     QTextCursor cursor = parent->textCursor();
00172     cursor.beginEditBlock();
00173     cursor.movePosition(QTextCursor::Start);
00174     cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
00175     cursor.removeSelectedText();
00176     cursor.endEditBlock();
00177 }
00178 
00179 void KTextEdit::Private::slotAllowTab()
00180 {
00181   parent->setTabChangesFocus( !parent->tabChangesFocus() );
00182 }
00183 
00184 void KTextEdit::Private::menuActivated( QAction* action )
00185 {
00186   if ( action == spellCheckAction )
00187     parent->checkSpelling();
00188   else if ( action == autoSpellCheckAction )
00189     toggleAutoSpellCheck();
00190   else if ( action == allowTab )
00191     slotAllowTab();
00192 }
00193 
00194 
00195 void KTextEdit::Private::slotFindHighlight(const QString& text, int matchingIndex, int matchingLength)
00196 {
00197     Q_UNUSED(text)
00198     //kDebug() << "Highlight: [" << text << "] mi:" << matchingIndex << " ml:" << matchingLength;
00199     QTextCursor tc = parent->textCursor();
00200     tc.setPosition(matchingIndex);
00201     tc.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, matchingLength);
00202     parent->setTextCursor(tc);
00203     parent->ensureCursorVisible();
00204 }
00205 
00206 
00207 void KTextEdit::Private::slotReplaceText(const QString &text, int replacementIndex, int /*replacedLength*/, int matchedLength) {
00208     Q_UNUSED(text)
00209     //kDebug() << "Replace: [" << text << "] ri:" << replacementIndex << " rl:" << replacedLength << " ml:" << matchedLength;
00210     QTextCursor tc = parent->textCursor();
00211     tc.setPosition(replacementIndex);
00212     tc.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, matchedLength);
00213     tc.removeSelectedText();
00214     tc.insertText(repDlg->replacement());
00215     parent->setTextCursor(tc);
00216     if (replace->options() & KReplaceDialog::PromptOnReplace) {
00217         parent->ensureCursorVisible();
00218     }
00219 }
00220 
00221 KTextEdit::KTextEdit( const QString& text, QWidget *parent )
00222   : QTextEdit( text, parent ), d( new Private( this ) )
00223 {
00224   KCursor::setAutoHideCursor( this, true, false );
00225 }
00226 
00227 KTextEdit::KTextEdit( QWidget *parent )
00228   : QTextEdit( parent ), d( new Private( this ) )
00229 {
00230   KCursor::setAutoHideCursor( this, true, false );
00231 }
00232 
00233 KTextEdit::~KTextEdit()
00234 {
00235   delete d;
00236 }
00237 
00238 void KTextEdit::setSpellCheckingConfigFileName(const QString &_fileName)
00239 {
00240     d->spellChechingConfigFileName = _fileName;
00241 }
00242 
00243 void KTextEdit::setSpellCheckingLanguage(const QString &_language)
00244 {
00245     d->spellCheckingLanguage = _language;
00246 }
00247 
00248 bool KTextEdit::event(QEvent* ev)
00249 {
00250     if (ev->type() == QEvent::ShortcutOverride) {
00251         QKeyEvent *e = static_cast<QKeyEvent *>( ev );
00252         if (d->overrideShortcut(e)) {
00253             e->accept();
00254             return true;
00255         }
00256     }
00257     return QTextEdit::event(ev);
00258 }
00259 
00260 bool KTextEdit::Private::handleShortcut(const QKeyEvent* event)
00261 {
00262   const int key = event->key() | event->modifiers();
00263 
00264   if ( KStandardShortcut::copy().contains( key ) ) {
00265     parent->copy();
00266     return true;
00267   } else if ( KStandardShortcut::paste().contains( key ) ) {
00268     parent->paste();
00269     return true;
00270   } else if ( KStandardShortcut::cut().contains( key ) ) {
00271     parent->cut();
00272     return true;
00273   } else if ( KStandardShortcut::undo().contains( key ) ) {
00274     parent->document()->undo();
00275     return true;
00276   } else if ( KStandardShortcut::redo().contains( key ) ) {
00277     parent->document()->redo();
00278     return true;
00279   } else if ( KStandardShortcut::deleteWordBack().contains( key ) ) {
00280     parent->deleteWordBack();
00281     return true;
00282   } else if ( KStandardShortcut::deleteWordForward().contains( key ) ) {
00283     parent->deleteWordForward();
00284     return true;
00285   } else if ( KStandardShortcut::backwardWord().contains( key ) ) {
00286     QTextCursor cursor = parent->textCursor();
00287     cursor.movePosition( QTextCursor::PreviousWord );
00288     parent->setTextCursor( cursor );
00289     return true;
00290   } else if ( KStandardShortcut::forwardWord().contains( key ) ) {
00291     QTextCursor cursor = parent->textCursor();
00292     cursor.movePosition( QTextCursor::NextWord );
00293     parent->setTextCursor( cursor );
00294     return true;
00295   } else if ( KStandardShortcut::next().contains( key ) ) {
00296     QTextCursor cursor = parent->textCursor();
00297     int targetY = parent->verticalScrollBar()->value() + parent->viewport()->height();
00298     bool moved = false;
00299     do {
00300       moved = cursor.movePosition( QTextCursor::Down );
00301       parent->setTextCursor( cursor );
00302     } while ( moved && parent->verticalScrollBar()->value() < targetY );
00303     return true;
00304   } else if ( KStandardShortcut::prior().contains( key ) ) {
00305     QTextCursor cursor = parent->textCursor();
00306     int targetY = parent->verticalScrollBar()->value() - parent->viewport()->height();
00307     bool moved = false;
00308     do {
00309       moved = cursor.movePosition( QTextCursor::Up );
00310       parent->setTextCursor( cursor );
00311     } while ( moved && parent->verticalScrollBar()->value() > targetY );
00312     return true;
00313   } else if ( KStandardShortcut::begin().contains( key ) ) {
00314     QTextCursor cursor = parent->textCursor();
00315     cursor.movePosition( QTextCursor::Start );
00316     parent->setTextCursor( cursor );
00317     return true;
00318   } else if ( KStandardShortcut::end().contains( key ) ) {
00319     QTextCursor cursor = parent->textCursor();
00320     cursor.movePosition( QTextCursor::End );
00321     parent->setTextCursor( cursor );
00322     return true;
00323   } else if ( KStandardShortcut::beginningOfLine().contains( key ) ) {
00324     QTextCursor cursor = parent->textCursor();
00325     cursor.movePosition( QTextCursor::StartOfLine );
00326     parent->setTextCursor( cursor );
00327     return true;
00328   } else if ( KStandardShortcut::endOfLine().contains( key ) ) {
00329     QTextCursor cursor = parent->textCursor();
00330     cursor.movePosition( QTextCursor::EndOfLine );
00331     parent->setTextCursor( cursor );
00332     return true;
00333   } else if ( KStandardShortcut::pasteSelection().contains( key ) ) {
00334     QString text = QApplication::clipboard()->text( QClipboard::Selection );
00335     if ( !text.isEmpty() )
00336       parent->insertPlainText( text );  // TODO: check if this is html? (MiB)
00337     return true;
00338   }
00339   return false;
00340 }
00341 
00342 void KTextEdit::deleteWordBack()
00343 {
00344   QTextCursor cursor = textCursor();
00345   cursor.clearSelection();
00346   cursor.movePosition( QTextCursor::PreviousWord, QTextCursor::KeepAnchor );
00347   cursor.removeSelectedText();
00348 }
00349 
00350 void KTextEdit::deleteWordForward()
00351 {
00352   QTextCursor cursor = textCursor();
00353   cursor.clearSelection();
00354   cursor.movePosition( QTextCursor::EndOfWord, QTextCursor::KeepAnchor );
00355   cursor.removeSelectedText();
00356 }
00357 
00358 QMenu *KTextEdit::mousePopupMenu()
00359 {
00360   QMenu *popup = createStandardContextMenu();
00361   connect( popup, SIGNAL( triggered ( QAction* ) ),
00362              this, SLOT( menuActivated( QAction* ) ) );
00363 
00364   bool emptyDocument = document()->isEmpty();
00365   if( !isReadOnly() )
00366   {
00367       QList<QAction *> actionList = popup->actions();
00368       enum { UndoAct, RedoAct, CutAct, CopyAct, PasteAct, ClearAct, SelectAllAct, NCountActs };
00369       QAction *separatorAction = 0L;
00370       int idx = actionList.indexOf( actionList[SelectAllAct] ) + 1;
00371       if ( idx < actionList.count() )
00372           separatorAction = actionList.at( idx );
00373       if ( separatorAction )
00374       {
00375           KAction *clearAllAction = KStandardAction::clear(this, SLOT(undoableClear()), this);
00376           if ( emptyDocument )
00377               clearAllAction->setEnabled( false );
00378           popup->insertAction( separatorAction, clearAllAction );
00379       }
00380   }
00381   KIconTheme::assignIconsToContextMenu( isReadOnly() ? KIconTheme::ReadOnlyText
00382                                           : KIconTheme::TextEditor,
00383                                           popup->actions() );
00384 
00385   if( !isReadOnly() )
00386   {
00387       popup->addSeparator();
00388       d->spellCheckAction = popup->addAction( KIcon( "tools-check-spelling" ),
00389                                               i18n( "Check Spelling..." ) );
00390       if ( emptyDocument )
00391         d->spellCheckAction->setEnabled( false );
00392       d->autoSpellCheckAction = popup->addAction( i18n( "Auto Spell Check" ) );
00393       d->autoSpellCheckAction->setCheckable( true );
00394       d->autoSpellCheckAction->setChecked( d->checkSpellingEnabled );
00395       popup->addSeparator();
00396       d->allowTab = popup->addAction( i18n("Allow Tabulations") );
00397       d->allowTab->setCheckable( true );
00398       d->allowTab->setChecked( !tabChangesFocus() );
00399 
00400       if (d->findReplaceEnabled)
00401       {
00402           KAction *findAction = KStandardAction::find( this, SLOT( slotFind() ), this );
00403           KAction *findNextAction = KStandardAction::findNext( this, SLOT( slotFindNext() ), this );
00404           KAction *replaceAction = KStandardAction::replace( this, SLOT( slotReplace() ), this );
00405           if (emptyDocument)
00406           {
00407               findAction->setEnabled(false);
00408               findNextAction->setEnabled(d->find != 0 );
00409               replaceAction->setEnabled(false);
00410           }
00411           popup->addSeparator();
00412           popup->addAction(findAction);
00413           popup->addAction(findNextAction);
00414           popup->addAction(replaceAction);
00415       }
00416   }
00417   return popup;
00418 }
00419 
00420 void KTextEdit::contextMenuEvent( QContextMenuEvent *event )
00421 {
00422   QMenu *popup = mousePopupMenu();
00423   popup->exec( event->globalPos() );
00424 
00425   delete popup;
00426 }
00427 
00428 void KTextEdit::wheelEvent( QWheelEvent *event )
00429 {
00430   if ( KGlobalSettings::wheelMouseZooms() )
00431     QTextEdit::wheelEvent( event );
00432   else // thanks, we don't want to zoom, so skip QTextEdit's impl.
00433     QAbstractScrollArea::wheelEvent( event );
00434 }
00435 
00436 void KTextEdit::createHighlighter()
00437 {
00438     setHighlighter(new Sonnet::Highlighter(this, d->spellChechingConfigFileName));
00439 }
00440 
00441 Sonnet::Highlighter* KTextEdit::highlighter() const
00442 {
00443     return d->highlighter;
00444 }
00445 
00446 void KTextEdit::setHighlighter(Sonnet::Highlighter *_highLighter)
00447 {
00448     delete d->highlighter;
00449     d->highlighter = _highLighter;
00450 }
00451 
00452 void KTextEdit::setCheckSpellingEnabled( bool check )
00453 {
00454   emit checkSpellingChanged( check );
00455   if ( check == d->checkSpellingEnabled )
00456     return;
00457 
00458   // From the above statment we know know that if we're turning checking
00459   // on that we need to create a new highlighter and if we're turning it
00460   // off we should remove the old one.
00461 
00462   d->checkSpellingEnabled = check;
00463     if ( check )
00464     {
00465         if ( hasFocus() ) {
00466             createHighlighter();
00467         }
00468     }
00469     else
00470     {
00471         delete d->highlighter;
00472         d->highlighter = 0;
00473     }
00474 }
00475 
00476 void KTextEdit::focusInEvent( QFocusEvent *event )
00477 {
00478   if ( d->checkSpellingEnabled && !isReadOnly() && !d->highlighter )
00479     createHighlighter();
00480 
00481   QTextEdit::focusInEvent( event );
00482 }
00483 
00484 bool KTextEdit::checkSpellingEnabled() const
00485 {
00486   return d->checkSpellingEnabled;
00487 }
00488 
00489 void KTextEdit::setReadOnly( bool readOnly )
00490 {
00491   if ( !readOnly && hasFocus() && d->checkSpellingEnabled && !d->highlighter )
00492     createHighlighter();
00493 
00494   if ( readOnly == isReadOnly() )
00495     return;
00496 
00497   if ( readOnly ) {
00498     delete d->highlighter;
00499     d->highlighter = 0;
00500 
00501     d->customPalette = testAttribute( Qt::WA_SetPalette );
00502     QPalette p = palette();
00503     QColor color = p.color( QPalette::Disabled, QPalette::Background );
00504     p.setColor( QPalette::Base, color );
00505     p.setColor( QPalette::Background, color );
00506     setPalette( p );
00507   } else {
00508     if ( d->customPalette && testAttribute( Qt::WA_SetPalette ) ) {
00509         QPalette p = palette();
00510         QColor color = p.color( QPalette::Normal, QPalette::Base );
00511         p.setColor( QPalette::Base, color );
00512         p.setColor( QPalette::Background, color );
00513         setPalette( p );
00514     } else
00515         setPalette( QPalette() );
00516   }
00517 
00518   QTextEdit::setReadOnly( readOnly );
00519 }
00520 
00521 void KTextEdit::checkSpelling()
00522 {
00523   if(document()->isEmpty())
00524   {
00525       KMessageBox::information(this, i18n("Nothing to spell check."));
00526       return;
00527   }
00528   Sonnet::BackgroundChecker *backgroundSpellCheck = new Sonnet::BackgroundChecker(this);
00529   if(!d->spellCheckingLanguage.isEmpty())
00530      backgroundSpellCheck->changeLanguage(d->spellCheckingLanguage);
00531   Sonnet::Dialog *spellDialog = new Sonnet::Dialog(
00532       backgroundSpellCheck, 0);
00533   connect(spellDialog, SIGNAL(replace( const QString&, int,const QString&)),
00534           this, SLOT(spellCheckerCorrected( const QString&, int,const QString&)));
00535   connect(spellDialog, SIGNAL(misspelling( const QString&, int)),
00536           this, SLOT(spellCheckerMisspelling(const QString &,int)));
00537   connect(spellDialog, SIGNAL(autoCorrect(const QString&, const QString&)),
00538           this, SLOT(spellCheckerAutoCorrect(const QString&, const QString&)));
00539   connect(spellDialog, SIGNAL(done(const QString&)),
00540           this, SLOT(spellCheckerFinished()));
00541   connect(spellDialog, SIGNAL(cancel()),
00542           this, SLOT(spellCheckerCanceled()));
00543   connect(spellDialog, SIGNAL(stop()),
00544           this, SLOT(spellCheckerFinished()));
00545   connect(spellDialog, SIGNAL(spellCheckStatus(const QString &)),
00546           this,SIGNAL(spellCheckStatus(const QString &)));
00547   connect(spellDialog, SIGNAL(languageChanged(const QString &)),
00548           this, SIGNAL(languageChanged(const QString &)));
00549   d->originalBuffer = toPlainText();
00550   spellDialog->setBuffer(d->originalBuffer);
00551   spellDialog->show();
00552 }
00553 
00554 void KTextEdit::highlightWord( int length, int pos )
00555 {
00556   QTextCursor cursor(document());
00557   cursor.setPosition(pos);
00558   cursor.setPosition(pos+length,QTextCursor::KeepAnchor);
00559   setTextCursor (cursor);
00560   ensureCursorVisible();
00561 }
00562 
00563 void KTextEdit::replace()
00564 {
00565      if( document()->isEmpty() )  // saves having to track the text changes
00566         return;
00567 
00568     if ( d->repDlg ) {
00569       KWindowSystem::activateWindow( d->repDlg->winId() );
00570     } else {
00571       d->repDlg = new KReplaceDialog(this, 0,
00572                                     QStringList(), QStringList(), false);
00573       connect( d->repDlg, SIGNAL(okClicked()), this, SLOT(slotDoReplace()) );
00574     }
00575     d->repDlg->show();
00576 }
00577 
00578 void KTextEdit::slotDoReplace()
00579 {
00580     if (!d->repDlg) {
00581         // Should really assert()
00582         return;
00583     }
00584 
00585     delete d->replace;
00586     d->replace = new KReplace(d->repDlg->pattern(), d->repDlg->replacement(), d->repDlg->options(), this);
00587     d->repIndex = 0;
00588     if (d->replace->options() & KFind::FromCursor || d->replace->options() & KFind::FindBackwards) {
00589         d->repIndex = textCursor().anchor();
00590     }
00591 
00592     // Connect highlight signal to code which handles highlighting
00593     // of found text.
00594     connect(d->replace, SIGNAL(highlight(const QString &, int, int)),
00595             this, SLOT(slotFindHighlight(const QString &, int, int)));
00596     connect(d->replace, SIGNAL(findNext()), this, SLOT(slotReplaceNext()));
00597     connect(d->replace, SIGNAL(replace(const QString &, int, int, int)),
00598             this, SLOT(slotReplaceText(const QString &, int, int, int)));
00599 
00600     d->repDlg->close();
00601     slotReplaceNext();
00602 }
00603 
00604 
00605 void KTextEdit::slotReplaceNext()
00606 {
00607     if (!d->replace)
00608         return;
00609 
00610     if (!(d->replace->options() & KReplaceDialog::PromptOnReplace))
00611         viewport()->setUpdatesEnabled(false);
00612 
00613     KFind::Result res = KFind::NoMatch;
00614 
00615     if (d->replace->needData())
00616         d->replace->setData(toPlainText(), d->repIndex);
00617     res = d->replace->replace();
00618     if (!(d->replace->options() & KReplaceDialog::PromptOnReplace)) {
00619         viewport()->setUpdatesEnabled(true);
00620         viewport()->update();
00621     }
00622 
00623     if (res == KFind::NoMatch) {
00624         d->replace->displayFinalDialog();
00625         d->replace->disconnect(this);
00626         d->replace->deleteLater(); // we are in a slot connected to m_replace, don't delete it right away
00627         d->replace = 0;
00628         ensureCursorVisible();
00629         //or           if ( m_replace->shouldRestart() ) { reinit (w/o FromCursor) and call slotReplaceNext(); }
00630     } else {
00631         //m_replace->closeReplaceNextDialog();
00632     }
00633 }
00634 
00635 
00636 void KTextEdit::slotDoFind()
00637 {
00638     if (!d->findDlg) {
00639         // Should really assert()
00640         return;
00641     }
00642 
00643     delete d->find;
00644     d->find = new KFind(d->findDlg->pattern(), d->findDlg->options(), this);
00645     d->findIndex = 0;
00646     if (d->find->options() & KFind::FromCursor || d->find->options() & KFind::FindBackwards) {
00647         d->findIndex = textCursor().anchor();
00648     }
00649 
00650     // Connect highlight signal to code which handles highlighting
00651     // of found text.
00652     connect(d->find, SIGNAL(highlight(const QString &, int, int)),
00653             this, SLOT(slotFindHighlight(const QString &, int, int)));
00654     connect(d->find, SIGNAL(findNext()), this, SLOT(slotFindNext()));
00655 
00656     d->findDlg->close();
00657     d->find->closeFindNextDialog();
00658     slotFindNext();
00659 }
00660 
00661 
00662 void KTextEdit::slotFindNext()
00663 {
00664     if (!d->find)
00665         return;
00666 
00667     KFind::Result res = KFind::NoMatch;
00668     if (d->find->needData())
00669         d->find->setData(toPlainText(), d->findIndex);
00670     res = d->find->find();
00671 
00672     if (res == KFind::NoMatch) {
00673         d->find->displayFinalDialog();
00674         d->find->disconnect(this);
00675         d->find->deleteLater(); // we are in a slot connected to m_find, don't delete right away
00676         d->find = 0;
00677         //or           if ( m_find->shouldRestart() ) { reinit (w/o FromCursor) and call slotFindNext(); }
00678     } else {
00679         //m_find->closeFindNextDialog();
00680     }
00681 }
00682 
00683 
00684 void KTextEdit::slotFind()
00685 {
00686     if( document()->isEmpty() )  // saves having to track the text changes
00687         return;
00688 
00689     if ( d->findDlg ) {
00690       KWindowSystem::activateWindow( d->findDlg->winId() );
00691     } else {
00692       d->findDlg = new KFindDialog(this);
00693       connect( d->findDlg, SIGNAL(okClicked()), this, SLOT(slotDoFind()) );
00694     }
00695     d->findDlg->show();
00696 }
00697 
00698 
00699 void KTextEdit::slotReplace()
00700 {
00701     if( document()->isEmpty() )  // saves having to track the text changes
00702         return;
00703 
00704     if ( d->repDlg ) {
00705       KWindowSystem::activateWindow( d->repDlg->winId() );
00706     } else {
00707       d->repDlg = new KReplaceDialog(this, 0,
00708                                     QStringList(), QStringList(), false);
00709       connect( d->repDlg, SIGNAL(okClicked()), this, SLOT(slotDoReplace()) );
00710     }
00711     d->repDlg->show();
00712 }
00713 
00714 void KTextEdit::enableFindReplace( bool enabled )
00715 {
00716     d->findReplaceEnabled = enabled;
00717 }
00718 
00719 bool KTextEdit::Private::overrideShortcut(const QKeyEvent* event)
00720 {
00721   const int key = event->key() | event->modifiers();
00722 
00723   if ( KStandardShortcut::copy().contains( key ) ) {
00724     return true;
00725   } else if ( KStandardShortcut::paste().contains( key ) ) {
00726     return true;
00727   } else if ( KStandardShortcut::cut().contains( key ) ) {
00728     return true;
00729   } else if ( KStandardShortcut::undo().contains( key ) ) {
00730     return true;
00731   } else if ( KStandardShortcut::redo().contains( key ) ) {
00732     return true;
00733   } else if ( KStandardShortcut::deleteWordBack().contains( key ) ) {
00734     return true;
00735   } else if ( KStandardShortcut::deleteWordForward().contains( key ) ) {
00736     return true;
00737   } else if ( KStandardShortcut::backwardWord().contains( key ) ) {
00738     return true;
00739   } else if ( KStandardShortcut::forwardWord().contains( key ) ) {
00740     return true;
00741   } else if ( KStandardShortcut::next().contains( key ) ) {
00742     return true;
00743   } else if ( KStandardShortcut::prior().contains( key ) ) {
00744     return true;
00745   } else if ( KStandardShortcut::begin().contains( key ) ) {
00746     return true;
00747   } else if ( KStandardShortcut::end().contains( key ) ) {
00748     return true;
00749   } else if ( KStandardShortcut::beginningOfLine().contains( key ) ) {
00750     return true;
00751   } else if ( KStandardShortcut::endOfLine().contains( key ) ) {
00752     return true;
00753   } else if ( KStandardShortcut::pasteSelection().contains( key ) ) {
00754     return true;
00755   } else if (event->modifiers() == Qt::ControlModifier &&
00756             (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) &&
00757               qobject_cast<KDialog*>(parent->window()) ) {
00758     // ignore Ctrl-Return so that KDialogs can close the dialog
00759     return true;
00760   }
00761   return false;
00762 }
00763 
00764 void KTextEdit::keyPressEvent( QKeyEvent *event )
00765 {
00766     if (d->handleShortcut(event)) {
00767         event->accept();
00768     }else if (event->modifiers() == Qt::ControlModifier &&
00769             (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) &&
00770               qobject_cast<KDialog*>(window()) ) {
00771         event->ignore();
00772     } else {
00773         QTextEdit::keyPressEvent(event);
00774     }
00775 }
00776 
00777 #include "ktextedit.moc"

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • KIO
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.6
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal