29 #include "html/html_documentimpl.h"
30 #include "rendering/render_text.h"
31 #include "rendering/render_replaced.h"
32 #include "xml/dom_selection.h"
38 #include <QtGui/QClipboard>
40 #include "rendering/render_form.h"
44 using khtml::RenderPosition;
54 connect( part, SIGNAL(selectionChanged()),
this, SLOT(slotSelectionChanged()) );
69 d->m_findPosStart = -1;
70 d->m_findNodeStart = 0;
71 d->m_findNodePrevious = 0;
81 DOM::NodeImpl* firstNode = 0L;
95 const Selection &sel = m_part->caret();
98 d->m_findNode = reverse ? sel.end().node() : sel.start().node();
99 d->m_findPos = reverse ? sel.end().offset() : sel.start().offset();
101 d->m_findNodeEnd = reverse ? sel.start().node() : sel.end().node();
102 d->m_findPosEnd = reverse ? sel.start().offset() : sel.end().offset();
103 d->m_findNodeStart = !reverse ? sel.start().node() : sel.end().node();
104 d->m_findPosStart = !reverse ? sel.start().offset() : sel.end().offset();
105 d->m_findNodePrevious =
d->m_findNodeStart;
112 d->m_findNode = firstNode;
113 d->m_findPos = reverse ? -1 : 0;
115 d->m_findNodeEnd = reverse ? firstNode : 0;
116 d->m_findPosEnd = reverse ? 0 : -1;
117 d->m_findNodeStart = !reverse ? firstNode : 0;
118 d->m_findPosStart = !reverse ? 0 : -1;
119 d->m_findNodePrevious =
d->m_findNodeStart;
123 khtml::RenderObject* obj =
d->m_findNode ?
d->m_findNode->renderer() : 0;
127 while ( obj->lastChild() )
129 obj = obj->lastChild();
132 while ( !obj->element() && obj->objectAbove() )
134 obj = obj->objectAbove();
136 d->m_findNode = obj->element();
146 d->m_lastFindState.options =
d->m_findDialog->options();
147 d->m_lastFindState.history =
d->m_findDialog->findHistory();
149 d->m_findDialog->hide();
150 d->m_findDialog->disconnect();
151 d->m_findDialog->deleteLater();
153 d->m_findDialog = 0L;
156 const DOM::Selection sel = m_part->caret();
157 if(sel.start().node() == sel.end().node())
162 DOM::NodeImpl *parent = sel.start().node();
165 if ( parent->nodeType() == Node::ELEMENT_NODE && parent->id() == ID_A )
170 parent = parent->parentNode();
175 static_cast<DOM::DocumentImpl *
>( m_part->
document().
handle() )->setFocusNode( parent );
180 void KHTMLFind::slotFindDestroyed()
192 if (
d->m_findDialog && !m_parent )
199 #ifndef QT_NO_CLIPBOARD
200 disconnect( qApp->clipboard(), SIGNAL(selectionChanged()), m_part, SLOT(slotClearSelection()) );
204 d->m_findDialog = m_parent->
findBar();
210 d->m_findDialog->setHasCursor(
d->m_findNode != 0 );
217 d->m_findDialog->setFindHistory(
d->m_lastFindState.history );
218 d->m_findDialog->setOptions(
d->m_lastFindState.options );
219 d->m_findDialog->setFocus();
221 d->m_lastFindState.options = -1;
222 d->m_lastFindState.last_dir = -1;
226 connect(
d->m_findDialog, SIGNAL(searchChanged()),
this, SLOT(slotSearchChanged()) );
227 connect(
d->m_findDialog, SIGNAL(findNextClicked()),
this, SLOT(slotFindNext()) );
228 connect(
d->m_findDialog, SIGNAL(findPreviousClicked()),
this, SLOT(slotFindPrevious()) );
229 connect(
d->m_findDialog, SIGNAL(hideMe()),
this, SLOT(
deactivate()) );
231 #ifndef QT_NO_CLIPBOARD
232 connect( qApp->clipboard(), SIGNAL(selectionChanged()), m_part, SLOT(slotClearSelection()) );
236 }
else if (m_parent && m_parent->
find()) {
244 if (!ro || !ro->isWidget() || ro->isFormElement())
246 KHTMLView* v = qobject_cast<
KHTMLView*>(
static_cast<khtml::RenderWidget*
>(ro)->widget() );
247 return v ? v->
part() : 0;
250 return (node && node->renderer() ?
innerPart( node->renderer() ) : 0);
268 d->m_find =
new KFind( str, options, parent, findDialog );
269 d->m_find->closeFindNextDialog();
270 connect(
d->m_find, SIGNAL(highlight(
QString,
int,
int)),
271 this, SLOT(slotHighlight(
QString,
int,
int)) );
272 connect(
d->m_find, SIGNAL(destroyed()),
273 this, SLOT(slotFindDestroyed()) );
279 d->m_lastFindState.options = options;
299 if (!m_parent && (!
d->m_findDialog || !
d->m_findDialog->restoreLastPatternFromHistory()))
304 if (
d->m_findDialog )
310 if ( (
d->m_find->pattern() !=
d->m_findDialog->pattern()) ) {
311 d->m_find->setPattern(
d->m_findDialog->pattern() );
312 d->m_find->resetCounts();
316 options =
d->m_findDialog->options();
317 if (
d->m_lastFindState.options != options )
319 d->m_find->setOptions( options );
324 long difference =
d->m_lastFindState.options ^ options;
332 d->m_lastFindState.options = options;
336 options =
d->m_lastFindState.options;
344 if(
d->m_find->options() != options )
345 d->m_find->setOptions( options );
350 if(
d->m_lastFindState.last_dir != -1
351 &&
bool(
d->m_lastFindState.last_dir ) !=
bool( options & KFind::FindBackwards ))
353 qSwap(
d->m_findNodeEnd,
d->m_findNodeStart );
354 qSwap(
d->m_findPosEnd,
d->m_findPosStart );
355 qSwap(
d->m_findNode,
d->m_findNodePrevious );
358 khtml::RenderObject* obj =
d->m_findNode ?
d->m_findNode->renderer() : 0;
359 khtml::RenderObject*
end =
d->m_findNodeEnd ?
d->m_findNodeEnd->renderer() : 0;
366 }
while ( obj && ( !obj->element() || obj->isInlineContinuation() ) );
369 d->m_findNode = obj->element();
373 options & KFind::FindBackwards,
381 khtml::RenderObject* obj =
d->m_findNode ?
d->m_findNode->renderer() : 0;
382 khtml::RenderObject*
end =
d->m_findNodeEnd ?
d->m_findNodeEnd->renderer() : 0;
386 if (
d->m_find->needData() )
397 d->m_stringPortions.clear();
398 bool newLine =
false;
400 DOM::NodeImpl* lastNode =
d->m_findNode;
401 while ( obj && !newLine )
405 if ( obj->renderName() == QLatin1String(
"RenderTextArea") )
407 s =
static_cast<khtml::RenderTextArea *
>(obj)->text();
408 s = s.replace(0xa0,
' ');
410 else if ( obj->renderName() == QLatin1String(
"RenderLineEdit") )
412 khtml::RenderLineEdit *parentLine=
static_cast<khtml::RenderLineEdit *
>(obj);
413 if (parentLine->widget()->echoMode() == QLineEdit::Normal)
414 s = parentLine->widget()->text();
415 s = s.replace(0xa0,
' ');
417 else if ( obj->isText() )
424 DOM::NodeImpl *parent = obj->element();
427 if ( parent->nodeType() == Node::ELEMENT_NODE && parent->id() == ID_A )
432 parent = parent->parentNode();
442 s =
static_cast<khtml::RenderText *
>(obj)->data().string();
443 s = s.replace(0xa0,
' ');
448 if (p->pFindTextNextInThisFrame(reverse))
452 lastNode = obj->element();
457 else if ( obj->isBR() )
459 else if ( !obj->isInline() && !str.isEmpty() )
462 if ( lastNode ==
d->m_findNodeEnd )
463 s.truncate(
d->m_findPosEnd );
466 newLine = s.indexOf(
'\n' ) != -1;
467 if( !( options & KFind::FindBackwards ))
470 d->m_stringPortions.append( StringPortion( str.length(), lastNode ) );
476 it !=
d->m_stringPortions.end();
478 (*it).index += s.length();
479 d->m_stringPortions.prepend( StringPortion( 0, lastNode ) );
495 }
while ( obj && ( !obj->element() || obj->isInlineContinuation() ) );
498 lastNode = obj->element();
503 if ( !str.isEmpty() )
505 d->m_find->setData( str,
d->m_findPos );
508 d->m_findNodePrevious =
d->m_findNode;
509 d->m_findNode = lastNode;
514 res =
d->m_find->find();
520 kDebug(6050) <<
"No more matches.";
523 kDebug(6050) <<
"Restarting";
524 initFindNode(
false, options & KFind::FindBackwards,
false );
525 d->m_find->resetCounts();
530 kDebug(6050) <<
"Finishing";
533 initFindNode(
false, options & KFind::FindBackwards,
false );
534 d->m_find->resetCounts();
535 d->m_part->clearSelection();
537 kDebug(6050) <<
"Dialog closed.";
540 if ( m_findDialog != 0 )
543 m_findDialog->setAtEnd( m_find->
numMatches() < numMatchesOld );
549 void KHTMLFind::slotHighlight(
const QString& ,
int index,
int length )
556 while ( it != itEnd && (*it).index <= index )
561 Q_ASSERT ( prev != itEnd );
562 DOM::NodeImpl* node = (*prev).node;
565 Selection sel(RenderPosition(node, index - (*prev).index).position());
567 khtml::RenderObject* obj = node->renderer();
568 khtml::RenderTextArea *renderTextArea = 0L;
569 khtml::RenderLineEdit *renderLineEdit = 0L;
576 if ( obj->renderName() == QLatin1String(
"RenderTextArea") )
577 renderTextArea = static_cast<khtml::RenderTextArea *>(obj);
578 if ( obj->renderName() == QLatin1String(
"RenderLineEdit") )
579 renderLineEdit = static_cast<khtml::RenderLineEdit *>(obj);
580 if ( !renderLineEdit && !renderTextArea )
585 static_cast<khtml::RenderText *
>(node->renderer())
586 ->caretPos( RenderPosition::fromDOMPosition(sel.start()).renderedOffset(),
false, x, y, dummy, dummy );
588 if ( x != -1 || y != -1 )
595 if (gox < 0) gox = 0;
602 while ( it != itEnd && (*it).index < index + length )
607 Q_ASSERT ( prev != itEnd );
609 sel.moveTo(sel.start(), RenderPosition((*prev).node, index + length - (*prev).index).position());
612 kDebug(6050) <<
"slotHighlight: " <<
d->m_selectionStart.handle() <<
"," <<
d->m_startOffset <<
" - " <<
613 d->m_selectionEnd.handle() <<
"," <<
d->m_endOffset << endl;
614 it =
d->m_stringPortions.begin();
615 for ( ; it !=
d->m_stringPortions.end() ; ++it )
616 kDebug(6050) <<
" StringPortion: from index=" << (*it).index <<
" -> node=" << (*it).node;
618 if ( renderTextArea )
619 renderTextArea->highLightWord( length, sel.end().offset()-length );
620 else if ( renderLineEdit )
621 renderLineEdit->highLightWord( length, sel.end().offset()-length );
624 m_part->setCaret( sel );
626 if (sel.end().node()->renderer() )
628 int x, y, height, dummy;
629 static_cast<khtml::RenderText *
>(sel.end().node()->renderer())
630 ->caretPos( RenderPosition::fromDOMPosition(sel.end()).renderedOffset(),
false, x, y, dummy, height );
634 m_part->emitSelectionChanged();
638 void KHTMLFind::slotSelectionChanged()
640 if (
d->m_findDialog )
644 void KHTMLFind::slotSearchChanged()
646 createNewKFind( m_findDialog->pattern(), m_findDialog->options(), m_findDialog, 0 );
650 void KHTMLFind::slotFindNext()
655 void KHTMLFind::slotFindPrevious()
void showBarWidget(KHTMLViewBarWidget *barWidget)
Shows barWidget that was previously added with addBarWidget.
bool initFindNode(bool selection, bool reverse, bool fromCursor)
static KHTMLPart * innerPartFromNode(DOM::NodeImpl *node)
bool findTextNext(bool reverse=false)
void addBarWidget(KHTMLViewBarWidget *newBarWidget)
Adds a widget to this viewbar.
This class is khtml's main class.
Renders and displays HTML in a QScrollArea.
virtual QWidget * widget()
void setContentsPos(int x, int y)
Place the contents area point x/y at the top left of the viewport.
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
void createNewKFind(const QString &str, long options, QWidget *parent, KFindDialog *findDialog)
This class implements the find activity for the KHTMLPart.
KHTMLView * view() const
Returns a pointer to the HTML document's view.
KHTMLPart * part() const
Returns a pointer to the KHTMLPart that is rendering the page.
int visibleWidth() const
Returns the width of the viewport.
void qSwap(KParts::SelectorInterface::Element &lhs, KParts::SelectorInterface::Element &rhs)
bool isNull() const
tests if this Node is 0.
KHTMLFindBar * findBar() const
static KHTMLPart * innerPart(khtml::RenderObject *ro)
int contentsX() const
Returns the x coordinate of the contents area point that is currently located at the top left in the ...
bool isHTMLDocument() const
KHTMLFind(KHTMLPart *part, KHTMLFind *parent=0)
DOM::HTMLDocument htmlDocument() const
Returns a reference to the DOM HTML document (for non-HTML documents, returns null) ...
DOM::Document document() const
Returns a reference to the DOM document.
NodeImpl * handle() const
bool hasSelection() const
Has the user selected anything?
HTMLElement body() const
The element that contains the content for the document.