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

KHTML

khtmlfind.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002  *
00003  * Copyright (C) 2008 Bernhard Beschow <bbeschow cs tu berlin de>
00004  *           (C) 2009 Germain Garand <germain@ebooksfrance.org>
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Library General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Library General Public License
00017  * along with this library; see the file COPYING.LIB.  If not, write to
00018  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020  */
00021 
00022 #include "khtmlfind_p.h"
00023 
00024 #include "khtml_part.h"
00025 #include "khtmlviewbar.h"
00026 #include "khtmlfindbar.h"
00027 
00028 #include "dom/html_document.h"
00029 #include "html/html_documentimpl.h"
00030 #include "rendering/render_text.h"
00031 #include "rendering/render_replaced.h"
00032 #include "misc/htmlhashes.h"
00033 #include "xml/dom_selection.h"
00034 
00035 #include "khtmlview.h"
00036 
00037 #include <config.h>
00038 
00039 #include <QtGui/QClipboard>
00040 
00041 #include "rendering/render_form.h"
00042 
00043 #define d this
00044 
00045 using namespace DOM;
00046 
00047 KHTMLFind::KHTMLFind( KHTMLPart *part, KHTMLFind *parent ) :
00048   m_part( part ),
00049   m_find( 0 ),
00050   m_parent( parent ),
00051   m_findDialog( 0 )
00052 {
00053   connect( part, SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged()) );
00054 }
00055 
00056 
00057 KHTMLFind::~KHTMLFind()
00058 {
00059   d->m_find = 0; // deleted by its parent, the view.
00060 }
00061 
00062 void KHTMLFind::findTextBegin()
00063 {
00064   d->m_findPos = -1;
00065   d->m_findNode = 0;
00066   d->m_findPosEnd = -1;
00067   d->m_findNodeEnd= 0;
00068   d->m_findPosStart = -1;
00069   d->m_findNodeStart = 0;
00070   d->m_findNodePrevious = 0;
00071   delete d->m_find;
00072   d->m_find = 0L;
00073 }
00074 
00075 bool KHTMLFind::initFindNode( bool selection, bool reverse, bool fromCursor )
00076 {
00077     if ( m_part->document().isNull() )
00078         return false;
00079 
00080     DOM::NodeImpl* firstNode = 0L;
00081     if (m_part->document().isHTMLDocument())
00082       firstNode = m_part->htmlDocument().body().handle();
00083     else
00084       firstNode = m_part->document().handle();
00085 
00086     if ( !firstNode )
00087     {
00088       //kDebug(6050) << "no first node (body or doc) -> return false";
00089       return false;
00090     }
00091     if ( selection && m_part->hasSelection() )
00092     {
00093       //kDebug(6050) << "using selection";
00094       const Selection &sel = m_part->caret();
00095       if ( !fromCursor )
00096       {
00097         d->m_findNode = reverse ? sel.end().node() : sel.start().node();
00098         d->m_findPos = reverse ? sel.end().offset() : sel.start().offset();
00099       }
00100       d->m_findNodeEnd = reverse ? sel.start().node() : sel.end().node();
00101       d->m_findPosEnd = reverse ? sel.start().offset() : sel.end().offset();
00102       d->m_findNodeStart = !reverse ? sel.start().node() : sel.end().node();
00103       d->m_findPosStart = !reverse ? sel.start().offset() : sel.end().offset();
00104       d->m_findNodePrevious = d->m_findNodeStart;
00105     }
00106     else // whole document
00107     {
00108       //kDebug(6050) << "whole doc";
00109       if ( !fromCursor )
00110       {
00111         d->m_findNode = firstNode;
00112         d->m_findPos = reverse ? -1 : 0;
00113       }
00114       d->m_findNodeEnd = reverse ? firstNode : 0;
00115       d->m_findPosEnd = reverse ? 0 : -1;
00116       d->m_findNodeStart = !reverse ? firstNode : 0;
00117       d->m_findPosStart = !reverse ? 0 : -1;
00118       d->m_findNodePrevious = d->m_findNodeStart;
00119       if ( reverse )
00120       {
00121         // Need to find out the really last object, to start from it
00122         khtml::RenderObject* obj = d->m_findNode ? d->m_findNode->renderer() : 0;
00123         if ( obj )
00124         {
00125           // find the last object in the render tree
00126           while ( obj->lastChild() )
00127           {
00128               obj = obj->lastChild();
00129           }
00130           // now get the last object with a NodeImpl associated
00131           while ( !obj->element() && obj->objectAbove() )
00132           {
00133              obj = obj->objectAbove();
00134           }
00135           d->m_findNode = obj->element();
00136         }
00137       }
00138     }
00139     return true;
00140 }
00141 
00142 void KHTMLFind::deactivate()
00143 {
00144   kDebug(6050);
00145   d->m_lastFindState.options = d->m_findDialog->options();
00146   d->m_lastFindState.history = d->m_findDialog->findHistory();
00147   if (!m_parent) {
00148       d->m_findDialog->hide();
00149       d->m_findDialog->disconnect();
00150       d->m_findDialog->deleteLater();
00151   }
00152   d->m_findDialog = 0L;
00153 
00154   // if the selection is limited to a single link, that link gets focus
00155   const DOM::Selection sel = m_part->caret();
00156   if(sel.start().node() == sel.end().node())
00157   {
00158     bool isLink = false;
00159 
00160     // checks whether the node has a <A> parent
00161     DOM::NodeImpl *parent = sel.start().node();
00162     while ( parent )
00163     {
00164       if ( parent->nodeType() == Node::ELEMENT_NODE && parent->id() == ID_A )
00165       {
00166         isLink = true;
00167         break;
00168       }
00169       parent = parent->parentNode();
00170     }
00171 
00172     if(isLink == true)
00173     {
00174       static_cast<DOM::DocumentImpl *>( m_part->document().handle() )->setFocusNode( parent );
00175     }
00176   }
00177 }
00178 
00179 void KHTMLFind::slotFindDestroyed()
00180 {
00181   d->m_find = 0;
00182 }
00183 
00184 void KHTMLFind::activate()
00185 {
00186   // First do some init to make sure we can search in this frame
00187   if ( m_part->document().isNull() )
00188     return;
00189 
00190   // Raise if already opened
00191   if ( d->m_findDialog && !m_parent )
00192   {
00193     m_part->pBottomViewBar()->showBarWidget( d->m_findDialog );
00194     return;
00195   }
00196 
00197   // The lineedit of the dialog would make khtml lose its selection, otherwise
00198 #ifndef QT_NO_CLIPBOARD
00199   disconnect( qApp->clipboard(), SIGNAL(selectionChanged()), m_part, SLOT(slotClearSelection()) );
00200 #endif
00201 
00202   if (m_parent)
00203     d->m_findDialog  = m_parent->findBar();
00204   else 
00205   {
00206     // Now show the dialog in which the user can choose options.
00207     d->m_findDialog = new KHTMLFindBar( m_part->widget() );
00208     d->m_findDialog->setHasSelection( m_part->hasSelection() );
00209     d->m_findDialog->setHasCursor( d->m_findNode != 0 );
00210 #if 0
00211     if ( d->m_findNode ) // has a cursor -> default to 'FromCursor'
00212       d->m_lastFindState.options |= KFind::FromCursor;
00213 #endif
00214 
00215     // TODO? optionsDialog.setPattern( d->m_lastFindState.text );
00216     d->m_findDialog->setFindHistory( d->m_lastFindState.history );
00217     d->m_findDialog->setOptions( d->m_lastFindState.options );
00218     d->m_findDialog->setFocus();
00219 
00220     d->m_lastFindState.options = -1; // force update in findTextNext
00221     d->m_lastFindState.last_dir = -1;
00222 
00223     m_part->pBottomViewBar()->addBarWidget( d->m_findDialog );
00224     m_part->pBottomViewBar()->showBarWidget( d->m_findDialog );
00225     connect( d->m_findDialog, SIGNAL(searchChanged()), this, SLOT(slotSearchChanged()) );
00226     connect( d->m_findDialog, SIGNAL(findNextClicked()), this, SLOT(slotFindNext()) );
00227     connect( d->m_findDialog, SIGNAL(findPreviousClicked()), this, SLOT(slotFindPrevious()) );
00228     connect( d->m_findDialog, SIGNAL(hideMe()), this, SLOT(deactivate()) );
00229   }
00230 #ifndef QT_NO_CLIPBOARD
00231     connect( qApp->clipboard(), SIGNAL(selectionChanged()), m_part, SLOT(slotClearSelection()) );
00232 #endif
00233   if (m_findDialog) {
00234     createNewKFind( m_findDialog->pattern() , 0 /*options*/, m_findDialog, 0 );
00235   } else if (m_parent && m_parent->find()) {
00236     createNewKFind( m_parent->find()->pattern(), m_parent->find()->options(), static_cast<QWidget*>(m_parent->find()->parent()), 0 );
00237   }
00238 }
00239 
00240 // ### this crawling through the render tree sucks. There should be another way to
00241 //     do that.
00242 static inline KHTMLPart* innerPart( khtml::RenderObject *ro ) {
00243     if (!ro || !ro->isWidget() || ro->isFormElement())
00244         return 0;
00245     KHTMLView* v = qobject_cast<KHTMLView*>( static_cast<khtml::RenderWidget*>(ro)->widget() );
00246     return v ? v->part() : 0;
00247 }
00248 static inline KHTMLPart* innerPartFromNode( DOM::NodeImpl *node ) {
00249     return (node && node->renderer() ? innerPart( node->renderer() ) : 0);
00250 }
00251 
00252 void KHTMLFind::createNewKFind( const QString &str, long options, QWidget *parent, KFindDialog *findDialog )
00253 {
00254   // First do some init to make sure we can search in this frame
00255   if ( m_part->document().isNull() )
00256     return;
00257 
00258   if (m_findNode) {
00259     if (KHTMLPart* p = innerPartFromNode(m_findNode)) {
00260       p->clearSelection();
00261       p->findTextBegin();
00262     }
00263   }
00264 
00265   // Create the KFind object
00266   delete d->m_find;
00267   d->m_find = new KFind( str, options, parent, findDialog );
00268   d->m_find->closeFindNextDialog(); // we use KFindDialog non-modal, so we don't want other dlg popping up
00269   connect( d->m_find, SIGNAL( highlight( const QString &, int, int ) ),
00270            this, SLOT( slotHighlight( const QString &, int, int ) ) );
00271   connect( d->m_find, SIGNAL( destroyed() ),
00272            this, SLOT( slotFindDestroyed() ) );
00273   //connect(d->m_find, SIGNAL( findNext() ),
00274   //        this, SLOT( slotFindNext() ) );
00275 
00276   if ( !findDialog )
00277   {
00278     d->m_lastFindState.options = options;
00279     initFindNode( options & KFind::SelectedText,
00280                   options & KFind::FindBackwards,
00281                   options & KFind::FromCursor );
00282   }
00283 }
00284 
00285 bool KHTMLFind::findTextNext( bool reverse )
00286 {
00287   if (!d->m_find)
00288   {
00289     // We didn't show the find dialog yet, let's do it then (#49442)
00290     activate();
00291 
00292     // FIXME Ugly hack: activate() may not create KFind object, so check whether it was created
00293     if (!d->m_find)
00294       return false;
00295 
00296     // It also means the user is trying to match a previous pattern, so try and
00297     // restore the last saved pattern.    
00298     if (!m_parent && (!d->m_findDialog || !d->m_findDialog->restoreLastPatternFromHistory()))
00299          return false;
00300   }
00301 
00302   m_part->view()->updateFindAheadTimeout();
00303   long options = 0;
00304   if ( d->m_findDialog ) // 0 when we close the dialog
00305   {
00306     // there is a search dialog
00307     // make sure pattern from search dialog is used
00308     // (### in fact pattern changes should always trigger a reconstruction of the KFind object cf. slotSearchChanged
00309     //   - so make this an assert)
00310     if ( (d->m_find->pattern() != d->m_findDialog->pattern()) ) {
00311       d->m_find->setPattern( d->m_findDialog->pattern() );
00312       d->m_find->resetCounts();
00313     }
00314 
00315     // make sure options from search dialog are used
00316     options = d->m_findDialog->options();
00317     if ( d->m_lastFindState.options != options )
00318     {
00319       d->m_find->setOptions( options );
00320 
00321       if ( options & KFind::SelectedText ) //#### FIXME find in selection for frames!
00322         Q_ASSERT( m_part->hasSelection() );
00323 
00324       long difference = d->m_lastFindState.options ^ options;
00325       if ( difference & (KFind::SelectedText | KFind::FromCursor ) )
00326       {
00327           // Important options changed -> reset search range
00328         (void) initFindNode( options & KFind::SelectedText,
00329                              options & KFind::FindBackwards,
00330                              options & KFind::FromCursor );
00331       }
00332       d->m_lastFindState.options = options;
00333     }
00334   } else {
00335     // no dialog
00336     options = d->m_lastFindState.options;
00337   }
00338 
00339   // only adopt options for search direction manually
00340   if( reverse )
00341     options = options ^ KFind::FindBackwards;
00342 
00343   // make sure our options are used by KFind
00344   if( d->m_find->options() != options )
00345     d->m_find->setOptions( options );
00346 
00347   // Changing find direction. Start and end nodes must be switched.
00348   // Additionally since d->m_findNode points after the last node
00349   // that was searched, it needs to be "after" it in the opposite direction.
00350   if( d->m_lastFindState.last_dir != -1
00351       && bool( d->m_lastFindState.last_dir ) != bool( options & KFind::FindBackwards ))
00352   {
00353     qSwap( d->m_findNodeEnd, d->m_findNodeStart );
00354     qSwap( d->m_findPosEnd, d->m_findPosStart );
00355     qSwap( d->m_findNode, d->m_findNodePrevious );
00356   
00357     // d->m_findNode now point at the end of the last searched line - advance one node
00358     khtml::RenderObject* obj = d->m_findNode ? d->m_findNode->renderer() : 0;
00359     khtml::RenderObject* end = d->m_findNodeEnd ? d->m_findNodeEnd->renderer() : 0;
00360     if ( obj == end )
00361       obj = 0L;
00362     else if ( obj )
00363     {
00364       do {
00365         obj = (options & KFind::FindBackwards) ? obj->objectAbove() : obj->objectBelow();
00366       } while ( obj && ( !obj->element() || obj->isInlineContinuation() ) );
00367     }
00368     if ( obj )
00369       d->m_findNode = obj->element();
00370     else {
00371       // already at end, start again
00372       (void) initFindNode( options & KFind::SelectedText,
00373                            options & KFind::FindBackwards,
00374                            options & KFind::FromCursor );
00375     }
00376   }
00377   d->m_lastFindState.last_dir = ( options & KFind::FindBackwards ) ? 1 : 0;
00378 
00379   int numMatchesOld = m_find->numMatches();
00380   KFind::Result res = KFind::NoMatch;
00381   khtml::RenderObject* obj = d->m_findNode ? d->m_findNode->renderer() : 0;
00382   khtml::RenderObject* end = d->m_findNodeEnd ? d->m_findNodeEnd->renderer() : 0;
00383   //kDebug(6050) << "obj=" << obj << " end=" << end;
00384   while( res == KFind::NoMatch )
00385   {
00386     if ( d->m_find->needData() )
00387     {
00388       if ( !obj ) {
00389         //kDebug(6050) << "obj=0 -> done";
00390         break; // we're done
00391       }
00392       //kDebug(6050) << " gathering data";
00393       // First make up the QString for the current 'line' (i.e. up to \n)
00394       // We also want to remember the DOMNode for every portion of the string.
00395       // We store this in an index->node list.
00396 
00397       d->m_stringPortions.clear();
00398       bool newLine = false;
00399       QString str;
00400       DOM::NodeImpl* lastNode = d->m_findNode;
00401       while ( obj && !newLine )
00402       {
00403         // Grab text from render object
00404         QString s;
00405         if ( obj->renderName() == QLatin1String("RenderTextArea") )
00406         {
00407           s = static_cast<khtml::RenderTextArea *>(obj)->text();
00408           s = s.replace(0xa0, ' ');
00409         }
00410         else if ( obj->renderName() ==  QLatin1String("RenderLineEdit") )
00411         {
00412           khtml::RenderLineEdit *parentLine= static_cast<khtml::RenderLineEdit *>(obj);
00413           if (parentLine->widget()->echoMode() == QLineEdit::Normal)
00414             s = parentLine->widget()->text();
00415           s = s.replace(0xa0, ' ');
00416         }
00417         else if ( obj->isText() )
00418         {
00419           bool isLink = false;
00420 
00421           // checks whether the node has a <A> parent
00422           if ( options & KHTMLPart::FindLinksOnly )
00423           {
00424             DOM::NodeImpl *parent = obj->element();
00425             while ( parent )
00426             {
00427               if ( parent->nodeType() == Node::ELEMENT_NODE && parent->id() == ID_A )
00428               {
00429                 isLink = true;
00430                 break;
00431               }
00432               parent = parent->parentNode();
00433             }
00434           }
00435           else
00436           {
00437             isLink = true;
00438           }
00439 
00440           if ( isLink )
00441           {
00442             s = static_cast<khtml::RenderText *>(obj)->data().string();
00443             s = s.replace(0xa0, ' ');
00444           }
00445         }
00446         else if ( KHTMLPart *p = innerPart(obj) )
00447         {
00448           if (p->pFindTextNextInThisFrame(reverse))
00449           {
00450             numMatchesOld++;
00451             res = KFind::Match;
00452             lastNode = obj->element();
00453             break;
00454           }
00455           
00456         }          
00457         else if ( obj->isBR() )
00458           s = '\n';
00459         else if ( !obj->isInline() && !str.isEmpty() )
00460           s = '\n';
00461 
00462         if ( lastNode == d->m_findNodeEnd )
00463           s.truncate( d->m_findPosEnd );
00464         if ( !s.isEmpty() )
00465         {
00466           newLine = s.indexOf( '\n' ) != -1; // did we just get a newline?
00467           if( !( options & KFind::FindBackwards ))
00468           {
00469             //kDebug(6050) << "StringPortion: " << index << "-" << index+s.length()-1 << " -> " << lastNode;
00470             d->m_stringPortions.append( StringPortion( str.length(), lastNode ) );
00471             str += s;
00472           }
00473           else // KFind itself can search backwards, so str must not be built backwards
00474           {
00475             for( QList<StringPortion>::Iterator it = d->m_stringPortions.begin();
00476                  it != d->m_stringPortions.end();
00477                  ++it )
00478                 (*it).index += s.length();
00479             d->m_stringPortions.prepend( StringPortion( 0, lastNode ) );
00480             str.prepend( s );
00481           }
00482         }
00483         // Compare obj and end _after_ we processed the 'end' node itself
00484         if ( obj == end )
00485           obj = 0L;
00486         else
00487         {
00488           // Move on to next object (note: if we found a \n already, then obj (and lastNode)
00489           // will point to the _next_ object, i.e. they are in advance.
00490           do {
00491             // We advance until the next RenderObject that has a NodeImpl as its element().
00492             // Otherwise (if we keep the 'last node', and it has a '\n') we might be stuck
00493             // on that object forever...
00494             obj = (options & KFind::FindBackwards) ? obj->objectAbove() : obj->objectBelow();
00495           } while ( obj && ( !obj->element() || obj->isInlineContinuation() ) );
00496         }
00497         if ( obj )
00498           lastNode = obj->element();
00499         else
00500           lastNode = 0;
00501       } // end while
00502 
00503       if ( !str.isEmpty() )
00504       {
00505         d->m_find->setData( str, d->m_findPos );
00506       }
00507       d->m_findPos = -1; // not used during the findnext loops. Only during init.
00508       d->m_findNodePrevious = d->m_findNode;
00509       d->m_findNode = lastNode;
00510     }
00511     if ( !d->m_find->needData() && !(res == KFind::Match) ) // happens if str was empty
00512     {
00513       // Let KFind inspect the text fragment, and emit highlighted if a match is found
00514       res = d->m_find->find();
00515     }
00516   } // end while
00517 
00518   if ( res == KFind::NoMatch ) // i.e. we're done
00519   {
00520     kDebug(6050) << "No more matches.";
00521     if ( !(options & KHTMLPart::FindNoPopups) && d->m_find->shouldRestart() )
00522     {
00523       kDebug(6050) << "Restarting";
00524       initFindNode( false, options & KFind::FindBackwards, false );
00525       d->m_find->resetCounts();
00526       findTextNext( reverse );
00527     }
00528     else // really done
00529     {
00530       kDebug(6050) << "Finishing";
00531       //delete d->m_find;
00532       //d->m_find = 0L;
00533       initFindNode( false, options & KFind::FindBackwards, false );
00534       d->m_find->resetCounts();
00535       d->m_part->clearSelection();
00536     }
00537     kDebug(6050) << "Dialog closed.";
00538   }
00539 
00540   if ( m_findDialog != 0 )
00541   {
00542     m_findDialog->setFoundMatch( res == KFind::Match );
00543     m_findDialog->setAtEnd( m_find->numMatches() < numMatchesOld );
00544   }
00545 
00546   return res == KFind::Match;
00547 }
00548 
00549 void KHTMLFind::slotHighlight( const QString& /*text*/, int index, int length )
00550 {
00551   //kDebug(6050) << "slotHighlight index=" << index << " length=" << length;
00552   QList<StringPortion>::Iterator it = d->m_stringPortions.begin();
00553   const QList<StringPortion>::Iterator itEnd = d->m_stringPortions.end();
00554   QList<StringPortion>::Iterator prev = it;
00555   // We stop at the first portion whose index is 'greater than', and then use the previous one
00556   while ( it != itEnd && (*it).index <= index )
00557   {
00558     prev = it;
00559     ++it;
00560   }
00561   Q_ASSERT ( prev != itEnd );
00562   DOM::NodeImpl* node = (*prev).node;
00563   Q_ASSERT( node );
00564 
00565   Selection sel(Position(node, index - (*prev).index));
00566 
00567   khtml::RenderObject* obj = node->renderer();
00568   khtml::RenderTextArea *renderTextArea = 0L;
00569   khtml::RenderLineEdit *renderLineEdit = 0L;
00570 
00571   Q_ASSERT( obj );
00572   if ( obj )
00573   {
00574     int x = 0, y = 0;
00575 
00576     if ( obj->renderName() == QLatin1String("RenderTextArea") )
00577       renderTextArea = static_cast<khtml::RenderTextArea *>(obj);
00578     if ( obj->renderName() == QLatin1String("RenderLineEdit") )
00579       renderLineEdit = static_cast<khtml::RenderLineEdit *>(obj);
00580     if ( !renderLineEdit && !renderTextArea )
00581       //if (static_cast<khtml::RenderText *>(node->renderer())
00582       //    ->posOfChar(d->m_startOffset, x, y))
00583       {
00584         int dummy;
00585         static_cast<khtml::RenderText *>(node->renderer())
00586           ->caretPos( sel.start().offset(), false, x, y, dummy, dummy ); // more precise than posOfChar
00587         //kDebug(6050) << "topleft: " << x << "," << y;
00588         if ( x != -1 || y != -1 )
00589         {
00590           int gox = m_part->view()->contentsX();
00591           if (x+50 > m_part->view()->contentsX() + m_part->view()->visibleWidth())
00592               gox = x - m_part->view()->visibleWidth() + 50;
00593           if (x-10 < m_part->view()->contentsX())
00594               gox = x - m_part->view()->visibleWidth() - 10;
00595           if (gox < 0) gox = 0;
00596           m_part->view()->setContentsPos(gox, y-50);
00597         }
00598       }
00599   }
00600   // Now look for end node
00601   it = prev; // no need to start from beginning again
00602   while ( it != itEnd && (*it).index < index + length )
00603   {
00604     prev = it;
00605     ++it;
00606   }
00607   Q_ASSERT ( prev != itEnd );
00608 
00609   sel.moveTo(sel.start(), Position((*prev).node, index + length - (*prev).index));
00610 
00611 #if 0
00612   kDebug(6050) << "slotHighlight: " << d->m_selectionStart.handle() << "," << d->m_startOffset << " - " <<
00613     d->m_selectionEnd.handle() << "," << d->m_endOffset << endl;
00614   it = d->m_stringPortions.begin();
00615   for ( ; it != d->m_stringPortions.end() ; ++it )
00616     kDebug(6050) << "  StringPortion: from index=" << (*it).index << " -> node=" << (*it).node;
00617 #endif
00618   if ( renderTextArea )
00619     renderTextArea->highLightWord( length, sel.end().offset()-length );
00620   else if ( renderLineEdit )
00621     renderLineEdit->highLightWord( length, sel.end().offset()-length );
00622   else
00623   {
00624     m_part->setCaret( sel );
00625 //    d->m_doc->updateSelection();
00626     if (sel.end().node()->renderer() )
00627     {
00628       int x, y, height, dummy;
00629       static_cast<khtml::RenderText *>(sel.end().node()->renderer())
00630           ->caretPos( sel.end().offset(), false, x, y, dummy, height ); // more precise than posOfChar
00631       //kDebug(6050) << "bottomright: " << x << "," << y+height;
00632     }
00633   }
00634   m_part->emitSelectionChanged();
00635 
00636 }
00637 
00638 void KHTMLFind::slotSelectionChanged()
00639 {
00640   if ( d->m_findDialog )
00641        d->m_findDialog->setHasSelection( m_part->hasSelection() );
00642 }
00643 
00644 void KHTMLFind::slotSearchChanged()
00645 {
00646     createNewKFind( m_findDialog->pattern(), m_findDialog->options(), m_findDialog, 0 );
00647     findTextNext();
00648 }
00649 
00650 void KHTMLFind::slotFindNext()
00651 {
00652     findTextNext();
00653 }
00654 
00655 void KHTMLFind::slotFindPrevious()
00656 {
00657     findTextNext( true );  // find backwards
00658 }

KHTML

Skip menu "KHTML"
  • Main Page
  • 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
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
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