• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • 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 "xml/dom_selection.h"
00033 
00034 #include "khtmlview.h"
00035 
00036 #include <config.h>
00037 
00038 #include <QtGui/QClipboard>
00039 
00040 #include "rendering/render_form.h"
00041 
00042 #define d this
00043 
00044 using khtml::RenderPosition;
00045 
00046 using namespace DOM;
00047 
00048 KHTMLFind::KHTMLFind( KHTMLPart *part, KHTMLFind *parent ) :
00049   m_part( part ),
00050   m_find( 0 ),
00051   m_parent( parent ),
00052   m_findDialog( 0 )
00053 {
00054   connect( part, SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged()) );
00055 }
00056 
00057 
00058 KHTMLFind::~KHTMLFind()
00059 {
00060   d->m_find = 0; // deleted by its parent, the view.
00061 }
00062 
00063 void KHTMLFind::findTextBegin()
00064 {
00065   d->m_findPos = -1;
00066   d->m_findNode = 0;
00067   d->m_findPosEnd = -1;
00068   d->m_findNodeEnd= 0;
00069   d->m_findPosStart = -1;
00070   d->m_findNodeStart = 0;
00071   d->m_findNodePrevious = 0;
00072   delete d->m_find;
00073   d->m_find = 0L;
00074 }
00075 
00076 bool KHTMLFind::initFindNode( bool selection, bool reverse, bool fromCursor )
00077 {
00078     if ( m_part->document().isNull() )
00079         return false;
00080 
00081     DOM::NodeImpl* firstNode = 0L;
00082     if (m_part->document().isHTMLDocument())
00083       firstNode = m_part->htmlDocument().body().handle();
00084     else
00085       firstNode = m_part->document().handle();
00086 
00087     if ( !firstNode )
00088     {
00089       //kDebug(6050) << "no first node (body or doc) -> return false";
00090       return false;
00091     }
00092     if ( selection && m_part->hasSelection() )
00093     {
00094       //kDebug(6050) << "using selection";
00095       const Selection &sel = m_part->caret();
00096       if ( !fromCursor )
00097       {
00098         d->m_findNode = reverse ? sel.end().node() : sel.start().node();
00099         d->m_findPos = reverse ? sel.end().offset() : sel.start().offset();
00100       }
00101       d->m_findNodeEnd = reverse ? sel.start().node() : sel.end().node();
00102       d->m_findPosEnd = reverse ? sel.start().offset() : sel.end().offset();
00103       d->m_findNodeStart = !reverse ? sel.start().node() : sel.end().node();
00104       d->m_findPosStart = !reverse ? sel.start().offset() : sel.end().offset();
00105       d->m_findNodePrevious = d->m_findNodeStart;
00106     }
00107     else // whole document
00108     {
00109       //kDebug(6050) << "whole doc";
00110       if ( !fromCursor )
00111       {
00112         d->m_findNode = firstNode;
00113         d->m_findPos = reverse ? -1 : 0;
00114       }
00115       d->m_findNodeEnd = reverse ? firstNode : 0;
00116       d->m_findPosEnd = reverse ? 0 : -1;
00117       d->m_findNodeStart = !reverse ? firstNode : 0;
00118       d->m_findPosStart = !reverse ? 0 : -1;
00119       d->m_findNodePrevious = d->m_findNodeStart;
00120       if ( reverse )
00121       {
00122         // Need to find out the really last object, to start from it
00123         khtml::RenderObject* obj = d->m_findNode ? d->m_findNode->renderer() : 0;
00124         if ( obj )
00125         {
00126           // find the last object in the render tree
00127           while ( obj->lastChild() )
00128           {
00129               obj = obj->lastChild();
00130           }
00131           // now get the last object with a NodeImpl associated
00132           while ( !obj->element() && obj->objectAbove() )
00133           {
00134              obj = obj->objectAbove();
00135           }
00136           d->m_findNode = obj->element();
00137         }
00138       }
00139     }
00140     return true;
00141 }
00142 
00143 void KHTMLFind::deactivate()
00144 {
00145   kDebug(6050);
00146   d->m_lastFindState.options = d->m_findDialog->options();
00147   d->m_lastFindState.history = d->m_findDialog->findHistory();
00148   if (!m_parent) {
00149       d->m_findDialog->hide();
00150       d->m_findDialog->disconnect();
00151       d->m_findDialog->deleteLater();
00152   }
00153   d->m_findDialog = 0L;
00154 
00155   // if the selection is limited to a single link, that link gets focus
00156   const DOM::Selection sel = m_part->caret();
00157   if(sel.start().node() == sel.end().node())
00158   {
00159     bool isLink = false;
00160 
00161     // checks whether the node has a <A> parent
00162     DOM::NodeImpl *parent = sel.start().node();
00163     while ( parent )
00164     {
00165       if ( parent->nodeType() == Node::ELEMENT_NODE && parent->id() == ID_A )
00166       {
00167         isLink = true;
00168         break;
00169       }
00170       parent = parent->parentNode();
00171     }
00172 
00173     if(isLink == true)
00174     {
00175       static_cast<DOM::DocumentImpl *>( m_part->document().handle() )->setFocusNode( parent );
00176     }
00177   }
00178 }
00179 
00180 void KHTMLFind::slotFindDestroyed()
00181 {
00182   d->m_find = 0;
00183 }
00184 
00185 void KHTMLFind::activate()
00186 {
00187   // First do some init to make sure we can search in this frame
00188   if ( m_part->document().isNull() )
00189     return;
00190 
00191   // Raise if already opened
00192   if ( d->m_findDialog && !m_parent )
00193   {
00194     m_part->pBottomViewBar()->showBarWidget( d->m_findDialog );
00195     return;
00196   }
00197 
00198   // The lineedit of the dialog would make khtml lose its selection, otherwise
00199 #ifndef QT_NO_CLIPBOARD
00200   disconnect( qApp->clipboard(), SIGNAL(selectionChanged()), m_part, SLOT(slotClearSelection()) );
00201 #endif
00202 
00203   if (m_parent)
00204     d->m_findDialog  = m_parent->findBar();
00205   else
00206   {
00207     // Now show the dialog in which the user can choose options.
00208     d->m_findDialog = new KHTMLFindBar( m_part->widget() );
00209     d->m_findDialog->setHasSelection( m_part->hasSelection() );
00210     d->m_findDialog->setHasCursor( d->m_findNode != 0 );
00211 #if 0
00212     if ( d->m_findNode ) // has a cursor -> default to 'FromCursor'
00213       d->m_lastFindState.options |= KFind::FromCursor;
00214 #endif
00215 
00216     // TODO? optionsDialog.setPattern( d->m_lastFindState.text );
00217     d->m_findDialog->setFindHistory( d->m_lastFindState.history );
00218     d->m_findDialog->setOptions( d->m_lastFindState.options );
00219     d->m_findDialog->setFocus();
00220 
00221     d->m_lastFindState.options = -1; // force update in findTextNext
00222     d->m_lastFindState.last_dir = -1;
00223 
00224     m_part->pBottomViewBar()->addBarWidget( d->m_findDialog );
00225     m_part->pBottomViewBar()->showBarWidget( d->m_findDialog );
00226     connect( d->m_findDialog, SIGNAL(searchChanged()), this, SLOT(slotSearchChanged()) );
00227     connect( d->m_findDialog, SIGNAL(findNextClicked()), this, SLOT(slotFindNext()) );
00228     connect( d->m_findDialog, SIGNAL(findPreviousClicked()), this, SLOT(slotFindPrevious()) );
00229     connect( d->m_findDialog, SIGNAL(hideMe()), this, SLOT(deactivate()) );
00230   }
00231 #ifndef QT_NO_CLIPBOARD
00232     connect( qApp->clipboard(), SIGNAL(selectionChanged()), m_part, SLOT(slotClearSelection()) );
00233 #endif
00234   if (m_findDialog) {
00235     createNewKFind( m_findDialog->pattern() , 0 /*options*/, m_findDialog, 0 );
00236   } else if (m_parent && m_parent->find()) {
00237     createNewKFind( m_parent->find()->pattern(), m_parent->find()->options(), static_cast<QWidget*>(m_parent->find()->parent()), 0 );
00238   }
00239 }
00240 
00241 // ### this crawling through the render tree sucks. There should be another way to
00242 //     do that.
00243 static inline KHTMLPart* innerPart( khtml::RenderObject *ro ) {
00244     if (!ro || !ro->isWidget() || ro->isFormElement())
00245         return 0;
00246     KHTMLView* v = qobject_cast<KHTMLView*>( static_cast<khtml::RenderWidget*>(ro)->widget() );
00247     return v ? v->part() : 0;
00248 }
00249 static inline KHTMLPart* innerPartFromNode( DOM::NodeImpl *node ) {
00250     return (node && node->renderer() ? innerPart( node->renderer() ) : 0);
00251 }
00252 
00253 void KHTMLFind::createNewKFind( const QString &str, long options, QWidget *parent, KFindDialog *findDialog )
00254 {
00255   // First do some init to make sure we can search in this frame
00256   if ( m_part->document().isNull() )
00257     return;
00258 
00259   if (m_findNode) {
00260     if (KHTMLPart* p = innerPartFromNode(m_findNode)) {
00261       p->clearSelection();
00262       p->findTextBegin();
00263     }
00264   }
00265 
00266   // Create the KFind object
00267   delete d->m_find;
00268   d->m_find = new KFind( str, options, parent, findDialog );
00269   d->m_find->closeFindNextDialog(); // we use KFindDialog non-modal, so we don't want other dlg popping up
00270   connect( d->m_find, SIGNAL( highlight( const QString &, int, int ) ),
00271            this, SLOT( slotHighlight( const QString &, int, int ) ) );
00272   connect( d->m_find, SIGNAL( destroyed() ),
00273            this, SLOT( slotFindDestroyed() ) );
00274   //connect(d->m_find, SIGNAL( findNext() ),
00275   //        this, SLOT( slotFindNext() ) );
00276 
00277   if ( !findDialog )
00278   {
00279     d->m_lastFindState.options = options;
00280     initFindNode( options & KFind::SelectedText,
00281                   options & KFind::FindBackwards,
00282                   options & KFind::FromCursor );
00283   }
00284 }
00285 
00286 bool KHTMLFind::findTextNext( bool reverse )
00287 {
00288   if (!d->m_find)
00289   {
00290     // We didn't show the find dialog yet, let's do it then (#49442)
00291     activate();
00292 
00293     // FIXME Ugly hack: activate() may not create KFind object, so check whether it was created
00294     if (!d->m_find)
00295       return false;
00296 
00297     // It also means the user is trying to match a previous pattern, so try and
00298     // restore the last saved pattern.
00299     if (!m_parent && (!d->m_findDialog || !d->m_findDialog->restoreLastPatternFromHistory()))
00300          return false;
00301   }
00302 
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(RenderPosition(node, index - (*prev).index).position());
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( RenderPosition::fromDOMPosition(sel.start()).renderedOffset(), 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(), RenderPosition((*prev).node, index + length - (*prev).index).position());
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( RenderPosition::fromDOMPosition(sel.end()).renderedOffset(), 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
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
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