27 #include "khtmlview.moc"
29 #include "khtmlview.h"
31 #include "khtml_part.h"
32 #include "khtml_events.h"
34 #include "html/html_documentimpl.h"
35 #include "html/html_inlineimpl.h"
36 #include "html/html_formimpl.h"
37 #include "rendering/render_arena.h"
38 #include "rendering/render_canvas.h"
39 #include "rendering/render_frames.h"
40 #include "rendering/render_replaced.h"
41 #include "rendering/render_layer.h"
42 #include "rendering/render_line.h"
43 #include "rendering/render_table.h"
45 #define protected public
46 #include "rendering/render_text.h"
48 #include "xml/dom2_eventsimpl.h"
49 #include "css/cssstyleselector.h"
50 #include "css/csshelper.h"
51 #include "misc/htmlhashes.h"
52 #include "misc/helper.h"
53 #include "misc/loader.h"
54 #include "khtml_settings.h"
55 #include "khtml_printsettings.h"
57 #include "khtmlpart_p.h"
59 #ifndef KHTML_NO_CARET
60 #include "khtml_caret_p.h"
61 #include "xml/dom2_rangeimpl.h"
64 #include <kapplication.h>
67 #include <kdialogbase.h>
68 #include <kiconloader.h>
71 #include <knotifyclient.h>
73 #include <ksimpleconfig.h>
74 #include <kstandarddirs.h>
75 #include <kstdaccel.h>
76 #include <kstringhandler.h>
81 #include <tqobjectlist.h>
82 #include <tqpaintdevicemetrics.h>
83 #include <tqpainter.h>
84 #include <tqptrdict.h>
85 #include <tqtooltip.h>
87 #include <tqstylesheet.h>
89 #include <tqvaluevector.h>
102 #define PAINT_BUFFER_HEIGHT 128
106 void dumpLineBoxes(RenderFlow *flow);
111 using namespace khtml;
115 #ifndef QT_NO_TOOLTIP
117 class KHTMLToolTip :
public TQToolTip
120 KHTMLToolTip(
KHTMLView *view, KHTMLViewPrivate* vp) : TQToolTip(view->viewport())
127 virtual void maybeTip(
const TQPoint &);
131 KHTMLViewPrivate* m_viewprivate;
136 class KHTMLViewPrivate {
137 friend class KHTMLToolTip;
140 enum PseudoFocusNodes {
146 enum CompletedState {
153 : underMouse( 0 ), underMouseNonShared( 0 ), visibleWidgets( 107 )
154 #ifndef NO_SMOOTH_SCROLL_HACK
155 , dx(0), dy(0), ddx(0), ddy(0), rdx(0), rdy(0), scrolling(false)
158 #ifndef KHTML_NO_CARET
159 m_caretViewContext = 0;
161 #endif // KHTML_NO_CARET
162 postponed_autorepeat = NULL;
164 vmode = TQScrollView::Auto;
165 hmode = TQScrollView::Auto;
170 prevScrollbarVisible =
true;
172 possibleTripleClick =
false;
173 emitCompletedAfterRepaint = CSNone;
174 cursor_icon_widget = NULL;
175 m_mouseScrollTimer = 0;
176 m_mouseScrollIndicator = 0;
180 delete formCompletions;
182 delete paintBuffer; paintBuffer =0;
183 delete vertPaintBuffer;
184 delete postponed_autorepeat;
187 if (underMouseNonShared)
188 underMouseNonShared->deref();
190 #ifndef KHTML_NO_CARET
191 delete m_caretViewContext;
192 delete m_editorContext;
193 #endif // KHTML_NO_CARET
194 delete cursor_icon_widget;
195 delete m_mouseScrollTimer;
196 delete m_mouseScrollIndicator;
203 if (underMouseNonShared)
204 underMouseNonShared->deref();
205 underMouseNonShared = 0;
207 useSlowRepaints =
false;
208 tabMovePending =
false;
209 lastTabbingDirection =
true;
210 pseudoFocusNode = PFNone;
211 #ifndef KHTML_NO_SCROLLBARS
217 vmode = TQScrollView::AlwaysOff;
218 hmode = TQScrollView::AlwaysOff;
225 scrollBarMoved =
false;
226 contentsMoving =
false;
227 ignoreWheelEvents =
false;
236 isDoubleClick =
false;
237 scrollingSelf =
false;
238 delete postponed_autorepeat;
239 postponed_autorepeat = NULL;
243 scrollSuspended =
false;
244 scrollSuspendPreActivate =
false;
246 firstRelayout =
true;
247 needsFullRepaint =
true;
249 layoutSchedulingEnabled =
true;
251 updateRegion = TQRegion();
252 m_dialogsAllowed =
true;
253 #ifndef KHTML_NO_CARET
254 if (m_caretViewContext) {
255 m_caretViewContext->caretMoved =
false;
256 m_caretViewContext->keyReleasePending =
false;
258 #endif // KHTML_NO_CARET
259 #ifndef KHTML_NO_TYPE_AHEAD_FIND
260 typeAheadActivated =
false;
261 #endif // KHTML_NO_TYPE_AHEAD_FIND
262 accessKeysActivated =
false;
263 accessKeysPreActivate =
false;
267 accessKeysEnabled = KHTMLFactory::defaultHTMLSettings()->accessKeysEnabled();
268 KHTMLFactory::deref();
270 emitCompletedAfterRepaint = CSNone;
272 void newScrollTimer(TQWidget *view,
int tid)
275 view->killTimer(scrollTimerId);
277 scrollSuspended =
false;
279 enum ScrollDirection { ScrollLeft, ScrollRight, ScrollUp, ScrollDown };
281 void adjustScroller(TQWidget *view, ScrollDirection direction, ScrollDirection oppositedir)
283 static const struct {
int msec, pixels; } timings [] = {
284 {320,1}, {224,1}, {160,1}, {112,1}, {80,1}, {56,1}, {40,1},
285 {28,1}, {20,1}, {20,2}, {20,3}, {20,4}, {20,6}, {20,8}, {0,0}
287 if (!scrollTimerId ||
288 (static_cast<int>(scrollDirection) != direction &&
289 (static_cast<int>(scrollDirection) != oppositedir || scrollSuspended))) {
291 scrollBy = timings[scrollTiming].pixels;
292 scrollDirection = direction;
293 newScrollTimer(view, view->startTimer(timings[scrollTiming].msec));
294 }
else if (scrollDirection == direction &&
295 timings[scrollTiming+1].msec && !scrollSuspended) {
296 scrollBy = timings[++scrollTiming].pixels;
297 newScrollTimer(view, view->startTimer(timings[scrollTiming].msec));
298 }
else if (scrollDirection == oppositedir) {
300 scrollBy = timings[--scrollTiming].pixels;
301 newScrollTimer(view, view->startTimer(timings[scrollTiming].msec));
304 scrollSuspended =
false;
307 #ifndef KHTML_NO_CARET
311 CaretViewContext *caretViewContext() {
312 if (!m_caretViewContext) m_caretViewContext =
new CaretViewContext();
313 return m_caretViewContext;
318 EditorContext *editorContext() {
319 if (!m_editorContext) m_editorContext =
new EditorContext();
320 return m_editorContext;
322 #endif // KHTML_NO_CARET
326 unsigned int pixelbooth;
327 unsigned int repaintbooth;
331 TQPixmap *paintBuffer;
332 TQPixmap *vertPaintBuffer;
333 NodeImpl *underMouse;
334 NodeImpl *underMouseNonShared;
336 bool tabMovePending:1;
337 bool lastTabbingDirection:1;
338 PseudoFocusNodes pseudoFocusNode:2;
339 bool scrollBarMoved:1;
340 bool contentsMoving:1;
342 TQScrollView::ScrollBarMode vmode;
343 TQScrollView::ScrollBarMode hmode;
344 bool prevScrollbarVisible:1;
346 bool useSlowRepaints:1;
347 bool ignoreWheelEvents:1;
349 int borderX, borderY;
354 int clickX, clickY, clickCount;
357 int prevMouseX, prevMouseY;
360 TQKeyEvent* postponed_autorepeat;
366 ScrollDirection scrollDirection :2;
367 bool scrollSuspended :1;
368 bool scrollSuspendPreActivate :1;
370 bool firstRelayout :1;
371 bool layoutSchedulingEnabled :1;
372 bool needsFullRepaint :1;
374 bool possibleTripleClick :1;
376 bool m_dialogsAllowed :1;
377 TQRegion updateRegion;
378 KHTMLToolTip *tooltip;
379 TQPtrDict<TQWidget> visibleWidgets;
380 #ifndef KHTML_NO_CARET
381 CaretViewContext *m_caretViewContext;
382 EditorContext *m_editorContext;
383 #endif // KHTML_NO_CARET
384 #ifndef KHTML_NO_TYPE_AHEAD_FIND
388 bool typeAheadActivated;
389 #endif // KHTML_NO_TYPE_AHEAD_FIND
390 bool accessKeysEnabled;
391 bool accessKeysActivated;
392 bool accessKeysPreActivate;
393 CompletedState emitCompletedAfterRepaint;
395 TQWidget* cursor_icon_widget;
398 short m_mouseScroll_byX;
399 short m_mouseScroll_byY;
400 TQTimer *m_mouseScrollTimer;
401 TQWidget *m_mouseScrollIndicator;
402 #ifndef NO_SMOOTH_SCROLL_HACK
415 #ifndef QT_NO_TOOLTIP
426 static bool findImageMapRect(HTMLImageElementImpl *img,
const TQPoint &scrollOfs,
427 const TQPoint &p, TQRect &r, TQString &s)
429 HTMLMapElementImpl* map;
430 if (img && img->getDocument()->isHTMLDocument() &&
431 (map =
static_cast<HTMLDocumentImpl*
>(img->getDocument())->getMap(img->imageMap()))) {
432 RenderObject::NodeInfo info(
true,
false);
433 RenderObject *rend = img->renderer();
435 if (!rend || !rend->absolutePosition(ax, ay))
438 bool inside = map->mapMouseEvent(p.x() - ax + scrollOfs.x(),
439 p.y() - ay + scrollOfs.y(), rend->contentWidth(),
440 rend->contentHeight(), info);
441 if (inside && info.URLElement()) {
442 HTMLAreaElementImpl *area =
static_cast<HTMLAreaElementImpl *
>(info.URLElement());
443 Q_ASSERT(area->id() == ID_AREA);
444 s = area->getAttribute(ATTR_TITLE).string();
445 TQRegion reg = area->cachedRegion();
446 if (!s.isEmpty() && !reg.isEmpty()) {
447 r = reg.boundingRect();
456 void KHTMLToolTip::maybeTip(
const TQPoint& p)
458 DOM::NodeImpl *node = m_viewprivate->underMouseNonShared;
461 if ( node->isElementNode() ) {
462 DOM::ElementImpl *e =
static_cast<DOM::ElementImpl*
>( node );
468 if (e->id() == ID_IMG && !e->getAttribute( ATTR_USEMAP ).isEmpty()) {
469 found = findImageMapRect(static_cast<HTMLImageElementImpl *>(e),
470 m_view->viewportToContents(TQPoint(0, 0)), p, r, s);
473 s = e->getAttribute( ATTR_TITLE ).string();
476 region |= TQRect( m_view->contentsToViewport( r.topLeft() ), r.size() );
477 if ( !s.isEmpty() ) {
478 tip( region, TQStyleSheet::convertFromPlainText( s, TQStyleSheetItem::WhiteSpaceNormal ) );
482 node = node->parentNode();
488 : TQScrollView( parent, name, (WFlags)(WResizeNoErase | WRepaintNoErase) )
493 d =
new KHTMLViewPrivate;
496 connect(kapp, TQT_SIGNAL(kdisplayPaletteChanged()),
this, TQT_SLOT(slotPaletteChanged()));
497 connect(
this, TQT_SIGNAL(contentsMoving(
int,
int)),
this, TQT_SLOT(slotScrollBarMoved()));
502 static_cast<KHTMLView *
>(TQT_TQWIDGET(viewport()))->setWFlags(WPaintUnclipped);
504 setResizePolicy(Manual);
505 viewport()->setMouseTracking(
true);
506 viewport()->setBackgroundMode(NoBackground);
508 KImageIO::registerFormats();
510 #ifndef QT_NO_TOOLTIP
511 d->tooltip =
new KHTMLToolTip(
this, d );
514 #ifndef KHTML_NO_TYPE_AHEAD_FIND
515 connect(&d->timer, TQT_SIGNAL(timeout()),
this, TQT_SLOT(findTimeout()));
516 #endif // KHTML_NO_TYPE_AHEAD_FIND
521 #ifndef NO_SMOOTH_SCROLL_HACK
523 connect(&d->timer, TQT_SIGNAL(timeout()),
this, TQT_SLOT(scrollTick()));
528 KHTMLView::~KHTMLView()
535 DOM::DocumentImpl *doc = m_part->xmlDocImpl();
542 void KHTMLView::init()
544 if(!d->paintBuffer) d->paintBuffer =
new TQPixmap(PAINT_BUFFER_HEIGHT, PAINT_BUFFER_HEIGHT);
545 if(!d->vertPaintBuffer)
546 d->vertPaintBuffer =
new TQPixmap(10, PAINT_BUFFER_HEIGHT);
547 if(!d->tp) d->tp =
new TQPainter();
549 setFocusPolicy(TQ_StrongFocus);
550 viewport()->setFocusProxy(
this);
557 installEventFilter(
this);
559 setAcceptDrops(
true);
560 TQSize s = viewportSize(4095, 4095);
561 resizeContents(s.width(), s.height());
564 void KHTMLView::clear()
567 setStaticBackground(
true);
568 #ifndef KHTML_NO_CARET
572 #ifndef KHTML_NO_TYPE_AHEAD_FIND
573 if( d->typeAheadActivated )
576 if (d->accessKeysEnabled && d->accessKeysActivated)
578 viewport()->unsetCursor();
579 if ( d->cursor_icon_widget )
580 d->cursor_icon_widget->hide();
582 TQT_TQOBJECT(
this)->killTimers();
587 verticalScrollBar()->setEnabled(
false );
588 horizontalScrollBar()->setEnabled(
false );
591 void KHTMLView::hideEvent(TQHideEvent* e)
593 TQScrollView::hideEvent(e);
594 if ( m_part && m_part->xmlDocImpl() )
595 m_part->xmlDocImpl()->docLoader()->pauseAnimations();
598 void KHTMLView::showEvent(TQShowEvent* e)
600 TQScrollView::showEvent(e);
601 if ( m_part && m_part->xmlDocImpl() )
602 m_part->xmlDocImpl()->docLoader()->resumeAnimations();
605 void KHTMLView::resizeEvent (TQResizeEvent* e)
607 int dw = e->oldSize().width() - e->size().width();
608 int dh = e->oldSize().height() - e->size().height();
612 dw = dw>0 ? kMax(0, contentsWidth()-dw) : contentsWidth();
613 dh = dh>0 ? kMax(0, contentsHeight()-dh) : contentsHeight();
615 resizeContents(dw, dh);
617 TQScrollView::resizeEvent(e);
619 if ( m_part && m_part->xmlDocImpl() )
620 m_part->xmlDocImpl()->dispatchWindowEvent( EventImpl::RESIZE_EVENT,
false,
false );
623 void KHTMLView::viewportResizeEvent (TQResizeEvent* e)
625 TQScrollView::viewportResizeEvent(e);
630 if (d->layoutSchedulingEnabled)
632 #ifndef KHTML_NO_CARET
635 recalcAndStoreCaretPos();
640 KApplication::sendPostedEvents(viewport(), TQEvent::Paint);
644 void KHTMLView::drawContents( TQPainter*)
648 void KHTMLView::drawContents( TQPainter *p,
int ex,
int ey,
int ew,
int eh )
652 if ( d->timer.elapsed() > 5000 ) {
653 qDebug(
"drawed %d pixels in %d repaints the last %d milliseconds",
654 d->pixelbooth, d->repaintbooth, d->timer.elapsed() );
659 d->pixelbooth += ew*eh;
664 if(!m_part || !m_part->xmlDocImpl() || !m_part->xmlDocImpl()->renderer()) {
665 p->fillRect(ex, ey, ew, eh, palette().active().brush(TQColorGroup::Base));
667 }
else if ( d->complete && static_cast<RenderCanvas*>(m_part->xmlDocImpl()->renderer())->needsLayout() ) {
669 unscheduleRelayout();
674 kdDebug( 6000 ) <<
"WARNING: drawContents reentered! " <<
endl;
679 TQPoint pt = contentsToViewport(TQPoint(ex, ey));
680 TQRegion cr = TQRect(pt.x(), pt.y(), ew, eh);
683 for (TQPtrDictIterator<TQWidget> it(d->visibleWidgets); it.current(); ++it) {
684 TQWidget *w = it.current();
685 RenderWidget* rw =
static_cast<RenderWidget*
>( it.currentKey() );
686 if (w && rw && !rw->isKHTMLWidget()) {
688 rw->absolutePosition(x, y);
689 contentsToViewport(x, y, x, y);
690 int pbx = rw->borderLeft()+rw->paddingLeft();
691 int pby = rw->borderTop()+rw->paddingTop();
692 TQRect g = TQRect(x+pbx, y+pby,
693 rw->width()-pbx-rw->borderRight()-rw->paddingRight(),
694 rw->height()-pby-rw->borderBottom()-rw->paddingBottom());
695 if ( !rw->isFrame() && ((g.top() > pt.y()+eh) || (g.bottom() <= pt.y()) ||
696 (g.right() <= pt.x()) || (g.left() > pt.x()+ew) ))
698 RenderLayer* rl = rw->needsMask() ? rw->enclosingStackingContext() : 0;
699 TQRegion mask = rl ? rl->getMask() : TQRegion();
700 if (!mask.isNull()) {
702 o = contentsToViewport(o);
703 mask.translate(o.x(),o.y());
704 mask = mask.intersect( TQRect(g.x(),g.y(),g.width(),g.height()) );
721 #ifndef DEBUG_NO_PAINT_BUFFER
722 p->setClipRegion(cr);
724 if (eh > PAINT_BUFFER_HEIGHT && ew <= 10) {
725 if ( d->vertPaintBuffer->height() < visibleHeight() )
726 d->vertPaintBuffer->resize(10, visibleHeight());
727 d->tp->begin(d->vertPaintBuffer);
728 d->tp->translate(-ex, -ey);
729 d->tp->fillRect(ex, ey, ew, eh, palette().active().brush(TQColorGroup::Base));
730 m_part->xmlDocImpl()->renderer()->layer()->paint(d->tp, TQRect(ex, ey, ew, eh));
732 p->drawPixmap(ex, ey, *d->vertPaintBuffer, 0, 0, ew, eh);
735 if ( d->paintBuffer->width() < visibleWidth() )
736 d->paintBuffer->resize(visibleWidth(),PAINT_BUFFER_HEIGHT);
740 int ph = eh-py < PAINT_BUFFER_HEIGHT ? eh-py : PAINT_BUFFER_HEIGHT;
741 d->tp->begin(d->paintBuffer);
742 d->tp->translate(-ex, -ey-py);
743 d->tp->fillRect(ex, ey+py, ew, ph, palette().active().brush(TQColorGroup::Base));
744 m_part->xmlDocImpl()->renderer()->layer()->paint(d->tp, TQRect(ex, ey+py, ew, ph));
747 p->drawPixmap(ex, ey+py, *d->paintBuffer, 0, 0, ew, ph);
748 py += PAINT_BUFFER_HEIGHT;
751 #else // !DEBUG_NO_PAINT_BUFFER
753 ex = contentsX(); ey = contentsY();
754 ew = visibleWidth(); eh = visibleHeight();
755 TQRect pr(ex,ey,ew,eh);
756 kdDebug() <<
"[" << ++cnt <<
"]" <<
" clip region: " << pr <<
endl;
759 p->fillRect(ex, ey, ew, eh, palette().active().brush(TQColorGroup::Base));
760 m_part->xmlDocImpl()->renderer()->layer()->paint(p, pr);
761 #endif // DEBUG_NO_PAINT_BUFFER
763 #ifndef KHTML_NO_CARET
764 if (d->m_caretViewContext && d->m_caretViewContext->visible) {
765 TQRect pos(d->m_caretViewContext->x, d->m_caretViewContext->y,
766 d->m_caretViewContext->width, d->m_caretViewContext->height);
767 if (pos.intersects(TQRect(ex, ey, ew, eh))) {
768 p->setRasterOp(XorROP);
770 if (pos.width() == 1)
771 p->drawLine(pos.topLeft(), pos.bottomRight());
773 p->fillRect(pos, white);
777 #endif // KHTML_NO_CARET
782 khtml::DrawContentsEvent
event( p, ex, ey, ew, eh );
783 TQApplication::sendEvent( m_part, &event );
794 void KHTMLView::setMarginHeight(
int h)
802 if( m_part && m_part->xmlDocImpl() ) {
803 DOM::DocumentImpl *document = m_part->xmlDocImpl();
805 khtml::RenderCanvas* canvas =
static_cast<khtml::RenderCanvas *
>(document->renderer());
806 if ( !canvas )
return;
808 d->layoutSchedulingEnabled=
false;
811 RenderObject * ref = 0;
812 RenderObject* root = document->documentElement() ? document->documentElement()->renderer() : 0;
814 if (document->isHTMLDocument()) {
815 NodeImpl *body =
static_cast<HTMLDocumentImpl*
>(document)->body();
816 if(body && body->renderer() && body->id() == ID_FRAMESET) {
819 body->renderer()->setNeedsLayout(
true);
827 d->tooltip =
new KHTMLToolTip(
this, d );
830 ref = (!body || root->style()->hidesOverflow()) ? root : body->renderer();
836 if( ref->style()->overflowX() == OHIDDEN ) {
838 }
else if (ref->style()->overflowX() == OSCROLL ) {
842 }
if ( ref->style()->overflowY() == OHIDDEN ) {
844 }
else if (ref->style()->overflowY() == OSCROLL ) {
850 d->needsFullRepaint = d->firstRelayout;
851 if (_height != visibleHeight() || _width != visibleWidth()) {;
852 d->needsFullRepaint =
true;
853 _height = visibleHeight();
854 _width = visibleWidth();
861 if (d->firstRelayout) {
864 d->firstRelayout =
false;
865 verticalScrollBar()->setEnabled(
true );
866 horizontalScrollBar()->setEnabled(
true );
869 ElementImpl *listitem = m_part->xmlDocImpl()->getElementById(
"__test_element__");
870 if (listitem)
kdDebug(6000) <<
"after layout, before repaint" <<
endl;
871 if (listitem) dumpLineBoxes(static_cast<RenderFlow *>(listitem->renderer()));
873 #ifndef KHTML_NO_CARET
876 && !d->complete && d->m_caretViewContext
877 && !d->m_caretViewContext->caretMoved) {
880 recalcAndStoreCaretPos();
884 if (d->accessKeysEnabled && d->accessKeysActivated) {
885 emit hideAccessKeys();
891 _width = visibleWidth();
893 killTimer(d->layoutTimerId);
894 d->layoutTimerId = 0;
895 d->layoutSchedulingEnabled=
true;
898 void KHTMLView::closeChildDialogs()
900 TQObjectList *dlgs = queryList(TQDIALOG_OBJECT_NAME_STRING);
901 for (TQObject *dlg = dlgs->first(); dlg; dlg = dlgs->next())
905 if ( dlgbase->testWFlags( WShowModal ) ) {
906 kdDebug(6000) <<
"closeChildDialogs: closing dialog " << dlgbase <<
endl;
914 kdWarning() <<
"closeChildDialogs: not a KDialogBase! Don't use QDialogs in KDE! " << TQT_TQWIDGET(dlg) <<
endl;
915 TQT_TQWIDGET(dlg)->hide();
919 d->m_dialogsAllowed =
false;
922 bool KHTMLView::dialogsAllowed() {
923 bool allowed = d->m_dialogsAllowed;
926 allowed &= p->
view()->dialogsAllowed();
930 void KHTMLView::closeEvent( TQCloseEvent* ev )
933 TQScrollView::closeEvent( ev );
941 void KHTMLView::viewportMousePressEvent( TQMouseEvent *_mouse )
943 if (!m_part->xmlDocImpl())
return;
944 if (d->possibleTripleClick && ( _mouse->button() & Qt::MouseButtonMask ) == Qt::LeftButton)
946 viewportMouseDoubleClickEvent( _mouse );
951 viewportToContents(_mouse->x(), _mouse->y(), xm, ym);
954 d->isDoubleClick =
false;
956 DOM::NodeImpl::MouseEvent mev( _mouse->stateAfter(), DOM::NodeImpl::MousePress );
957 m_part->xmlDocImpl()->prepareMouseEvent(
false, xm, ym, &mev );
961 if ( (_mouse->button() == Qt::MidButton) &&
962 !m_part->d->m_bOpenMiddleClick && !d->m_mouseScrollTimer &&
963 mev.url.isNull() && (mev.innerNode.elementId() != ID_INPUT) ) {
964 TQPoint point = mapFromGlobal( _mouse->globalPos() );
966 d->m_mouseScroll_byX = 0;
967 d->m_mouseScroll_byY = 0;
969 d->m_mouseScrollTimer =
new TQTimer(
this );
970 connect( d->m_mouseScrollTimer, TQT_SIGNAL(timeout()),
this, TQT_SLOT(slotMouseScrollTimer()) );
972 if ( !d->m_mouseScrollIndicator ) {
973 TQPixmap pixmap, icon;
974 pixmap.resize( 48, 48 );
975 pixmap.fill( TQColor( tqRgba( 127, 127, 127, 127 ) ) );
977 TQPainter p( &pixmap );
979 p.drawPixmap( 16, 0, icon );
981 p.drawPixmap( 0, 16, icon );
983 p.drawPixmap( 16, 32,icon );
985 p.drawPixmap( 32, 16, icon );
986 p.drawEllipse( 23, 23, 2, 2 );
988 d->m_mouseScrollIndicator =
new TQWidget(
this, 0 );
989 d->m_mouseScrollIndicator->setFixedSize( 48, 48 );
990 d->m_mouseScrollIndicator->setPaletteBackgroundPixmap( pixmap );
992 d->m_mouseScrollIndicator->move( point.x()-24, point.y()-24 );
994 bool hasHorBar = visibleWidth() < contentsWidth();
995 bool hasVerBar = visibleHeight() < contentsHeight();
999 if ( config->
readBoolEntry(
"ShowMouseScrollIndicator",
true ) ) {
1000 d->m_mouseScrollIndicator->show();
1001 d->m_mouseScrollIndicator->unsetCursor();
1003 TQBitmap mask = d->m_mouseScrollIndicator->paletteBackgroundPixmap()->createHeuristicMask(
true );
1005 if ( hasHorBar && !hasVerBar ) {
1006 TQBitmap bm( 16, 16,
true );
1007 bitBlt( &mask, 16, 0, &bm, 0, 0, -1, -1 );
1008 bitBlt( &mask, 16, 32, &bm, 0, 0, -1, -1 );
1009 d->m_mouseScrollIndicator->setCursor( KCursor::SizeHorCursor );
1011 else if ( !hasHorBar && hasVerBar ) {
1012 TQBitmap bm( 16, 16,
true );
1013 bitBlt( &mask, 0, 16, &bm, 0, 0, -1, -1 );
1014 bitBlt( &mask, 32, 16, &bm, 0, 0, -1, -1 );
1015 d->m_mouseScrollIndicator->setCursor( KCursor::SizeVerCursor );
1018 d->m_mouseScrollIndicator->setCursor( KCursor::SizeAllCursor );
1020 d->m_mouseScrollIndicator->setMask( mask );
1023 if ( hasHorBar && !hasVerBar )
1024 viewport()->setCursor( KCursor::SizeHorCursor );
1025 else if ( !hasHorBar && hasVerBar )
1026 viewport()->setCursor( KCursor::SizeVerCursor );
1028 viewport()->setCursor( KCursor::SizeAllCursor );
1033 else if ( d->m_mouseScrollTimer ) {
1034 delete d->m_mouseScrollTimer;
1035 d->m_mouseScrollTimer = 0;
1037 if ( d->m_mouseScrollIndicator )
1038 d->m_mouseScrollIndicator->hide();
1045 bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEDOWN_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),
true,
1046 d->clickCount,_mouse,
true,DOM::NodeImpl::MousePress);
1048 khtml::RenderObject* r = mev.innerNode.handle() ? mev.innerNode.handle()->renderer() : 0;
1049 if (r && r->isWidget())
1052 if (!swallowEvent) {
1055 khtml::MousePressEvent
event( _mouse, xm, ym, mev.url, mev.target, mev.innerNode );
1056 TQApplication::sendEvent( m_part, &event );
1061 void KHTMLView::viewportMouseDoubleClickEvent( TQMouseEvent *_mouse )
1063 if(!m_part->xmlDocImpl())
return;
1066 viewportToContents(_mouse->x(), _mouse->y(), xm, ym);
1068 kdDebug( 6000 ) <<
"mouseDblClickEvent: x=" << xm <<
", y=" << ym <<
endl;
1070 d->isDoubleClick =
true;
1072 DOM::NodeImpl::MouseEvent mev( _mouse->stateAfter(), DOM::NodeImpl::MouseDblClick );
1073 m_part->xmlDocImpl()->prepareMouseEvent(
false, xm, ym, &mev );
1077 if (d->clickCount > 0 &&
1078 TQPoint(d->clickX-xm,d->clickY-ym).manhattanLength() <= TQApplication::startDragDistance())
1085 bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEDOWN_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),
true,
1086 d->clickCount,_mouse,
true,DOM::NodeImpl::MouseDblClick);
1088 khtml::RenderObject* r = mev.innerNode.handle() ? mev.innerNode.handle()->renderer() : 0;
1089 if (r && r->isWidget())
1092 if (!swallowEvent) {
1093 khtml::MouseDoubleClickEvent
event( _mouse, xm, ym, mev.url, mev.target, mev.innerNode, d->clickCount );
1094 TQApplication::sendEvent( m_part, &event );
1097 d->possibleTripleClick=
true;
1098 TQTimer::singleShot(TQApplication::doubleClickInterval(),
this,TQT_SLOT(tripleClickTimeout()));
1101 void KHTMLView::tripleClickTimeout()
1103 d->possibleTripleClick =
false;
1107 static inline void forwardPeripheralEvent(khtml::RenderWidget* r, TQMouseEvent* me,
int x,
int y)
1111 r->absolutePosition(absx, absy);
1112 TQPoint p(x-absx, y-absy);
1113 TQMouseEvent fw(me->type(), p, me->button(), me->state());
1114 TQWidget* w = r->widget();
1115 TQScrollView* sc = ::tqqt_cast<TQScrollView*>(w);
1116 if (sc && !::tqqt_cast<TQListBox*>(w))
1117 static_cast<khtml::RenderWidget::ScrollViewEventPropagator*>(sc)->sendEvent(TQT_TQEVENT(&fw));
1119 static_cast<khtml::RenderWidget::EventPropagator*
>(w)->sendEvent(TQT_TQEVENT(&fw));
1123 static bool targetOpensNewWindow(
KHTMLPart *part, TQString target)
1125 if (!target.isEmpty() && (target.lower() !=
"_top") &&
1126 (target.lower() !=
"_self") && (target.lower() !=
"_parent")) {
1127 if (target.lower() ==
"_blank")
1139 void KHTMLView::viewportMouseMoveEvent( TQMouseEvent * _mouse )
1141 if ( d->m_mouseScrollTimer ) {
1142 TQPoint point = mapFromGlobal( _mouse->globalPos() );
1144 int deltaX = point.x() - d->m_mouseScrollIndicator->x() - 24;
1145 int deltaY = point.y() - d->m_mouseScrollIndicator->y() - 24;
1147 (deltaX > 0) ? d->m_mouseScroll_byX = 1 : d->m_mouseScroll_byX = -1;
1148 (deltaY > 0) ? d->m_mouseScroll_byY = 1 : d->m_mouseScroll_byY = -1;
1150 double adX = TQABS(deltaX)/30.0;
1151 double adY = TQABS(deltaY)/30.0;
1153 d->m_mouseScroll_byX = kMax(kMin(d->m_mouseScroll_byX *
int(adX*adX), SHRT_MAX), SHRT_MIN);
1154 d->m_mouseScroll_byY = kMax(kMin(d->m_mouseScroll_byY *
int(adY*adY), SHRT_MAX), SHRT_MIN);
1156 if (d->m_mouseScroll_byX == 0 && d->m_mouseScroll_byY == 0) {
1157 d->m_mouseScrollTimer->stop();
1159 else if (!d->m_mouseScrollTimer->isActive()) {
1160 d->m_mouseScrollTimer->changeInterval( 20 );
1164 if(!m_part->xmlDocImpl())
return;
1167 viewportToContents(_mouse->x(), _mouse->y(), xm, ym);
1169 DOM::NodeImpl::MouseEvent mev( _mouse->stateAfter(), DOM::NodeImpl::MouseMove );
1171 m_part->xmlDocImpl()->prepareMouseEvent( _mouse->state() & Qt::MouseButtonMask , xm, ym, &mev );
1177 bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEMOVE_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),
false,
1178 0,_mouse,
true,DOM::NodeImpl::MouseMove);
1180 if (d->clickCount > 0 &&
1181 TQPoint(d->clickX-xm,d->clickY-ym).manhattanLength() > TQApplication::startDragDistance()) {
1186 m_part->executeScheduledScript();
1188 DOM::NodeImpl* fn = m_part->xmlDocImpl()->focusNode();
1189 if (fn && fn != mev.innerNode.handle() &&
1190 fn->renderer() && fn->renderer()->isWidget()) {
1191 forwardPeripheralEvent(static_cast<khtml::RenderWidget*>(fn->renderer()), _mouse, xm, ym);
1194 khtml::RenderObject* r = mev.innerNode.handle() ? mev.innerNode.handle()->renderer() : 0;
1195 khtml::RenderStyle* style = (r && r->style()) ? r->style() : 0;
1197 bool mailtoCursor =
false;
1198 bool newWindowCursor =
false;
1199 switch ( style ? style->cursor() : CURSOR_AUTO) {
1201 if ( r && r->isText() )
1203 if ( mev.url.length() && m_part->settings()->changeCursor() ) {
1205 if (mev.url.string().startsWith(
"mailto:") && mev.url.string().find(
'@')>0)
1206 mailtoCursor =
true;
1208 newWindowCursor = targetOpensNewWindow( m_part, mev.target.string() );
1211 if (r && r->isFrameSet() && !
static_cast<RenderFrameSet*
>(r)->noResize())
1212 c = TQCursor(static_cast<RenderFrameSet*>(r)->cursorShape());
1218 case CURSOR_POINTER:
1220 if (mev.url.string().startsWith(
"mailto:") && mev.url.string().find(
'@')>0)
1221 mailtoCursor =
true;
1223 newWindowCursor = targetOpensNewWindow( m_part, mev.target.string() );
1225 case CURSOR_PROGRESS:
1231 case CURSOR_E_RESIZE:
1232 case CURSOR_W_RESIZE:
1235 case CURSOR_N_RESIZE:
1236 case CURSOR_S_RESIZE:
1239 case CURSOR_NE_RESIZE:
1240 case CURSOR_SW_RESIZE:
1243 case CURSOR_NW_RESIZE:
1244 case CURSOR_SE_RESIZE:
1256 case CURSOR_DEFAULT:
1260 if ( viewport()->cursor().handle() != c.handle() ) {
1263 p->
view()->viewport()->unsetCursor();
1266 viewport()->setCursor( c );
1270 if ( ( mailtoCursor || newWindowCursor ) && isVisible() && hasFocus() ) {
1274 if (d->cursor_icon_widget) {
1275 const TQPixmap *pm = d->cursor_icon_widget->backgroundPixmap();
1276 if (!pm || pm->serialNumber()!=icon_pixmap.serialNumber()) {
1277 delete d->cursor_icon_widget;
1278 d->cursor_icon_widget = 0;
1282 if( !d->cursor_icon_widget ) {
1283 d->cursor_icon_widget =
new TQWidget( NULL, NULL, WX11BypassWM );
1284 XSetWindowAttributes attr;
1285 attr.save_under = True;
1286 XChangeWindowAttributes( qt_xdisplay(), d->cursor_icon_widget->winId(), CWSaveUnder, &attr );
1287 d->cursor_icon_widget->resize( icon_pixmap.width(), icon_pixmap.height());
1288 if( icon_pixmap.mask() )
1289 d->cursor_icon_widget->setMask( *icon_pixmap.mask());
1291 d->cursor_icon_widget->clearMask();
1292 d->cursor_icon_widget->setBackgroundPixmap( icon_pixmap );
1293 d->cursor_icon_widget->erase();
1295 TQPoint c_pos = TQCursor::pos();
1296 d->cursor_icon_widget->move( c_pos.x() + 15, c_pos.y() + 15 );
1297 XRaiseWindow( qt_xdisplay(), d->cursor_icon_widget->winId());
1298 TQApplication::flushX();
1299 d->cursor_icon_widget->show();
1302 else if ( d->cursor_icon_widget )
1303 d->cursor_icon_widget->hide();
1305 if (r && r->isWidget()) {
1313 if (!swallowEvent) {
1314 khtml::MouseMoveEvent
event( _mouse, xm, ym, mev.url, mev.target, mev.innerNode );
1315 TQApplication::sendEvent( m_part, &event );
1319 void KHTMLView::viewportMouseReleaseEvent( TQMouseEvent * _mouse )
1321 bool swallowEvent =
false;
1323 viewportToContents(_mouse->x(), _mouse->y(), xm, ym);
1324 DOM::NodeImpl::MouseEvent mev( _mouse->stateAfter(), DOM::NodeImpl::MouseRelease );
1326 if ( m_part->xmlDocImpl() )
1328 m_part->xmlDocImpl()->prepareMouseEvent(
false, xm, ym, &mev );
1330 swallowEvent = dispatchMouseEvent(EventImpl::MOUSEUP_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),
true,
1331 d->clickCount,_mouse,
false,DOM::NodeImpl::MouseRelease);
1333 if (d->clickCount > 0 &&
1334 TQPoint(d->clickX-xm,d->clickY-ym).manhattanLength() <= TQApplication::startDragDistance()) {
1335 TQMouseEvent me(d->isDoubleClick ? TQEvent::MouseButtonDblClick : TQEvent::MouseButtonRelease,
1336 _mouse->pos(), _mouse->button(), _mouse->state());
1337 dispatchMouseEvent(EventImpl::CLICK_EVENT, mev.innerNode.handle(),mev.innerNonSharedNode.handle(),
true,
1338 d->clickCount, &me,
true, DOM::NodeImpl::MouseRelease);
1341 DOM::NodeImpl* fn = m_part->xmlDocImpl()->focusNode();
1342 if (fn && fn != mev.innerNode.handle() &&
1343 fn->renderer() && fn->renderer()->isWidget() &&
1344 _mouse->button() != Qt::MidButton) {
1345 forwardPeripheralEvent(static_cast<khtml::RenderWidget*>(fn->renderer()), _mouse, xm, ym);
1348 khtml::RenderObject* r = mev.innerNode.handle() ? mev.innerNode.handle()->renderer() : 0;
1349 if (r && r->isWidget())
1353 if (!swallowEvent) {
1354 khtml::MouseReleaseEvent
event( _mouse, xm, ym, mev.url, mev.target, mev.innerNode );
1355 TQApplication::sendEvent( m_part, &event );
1360 bool KHTMLView::dispatchKeyEvent( TQKeyEvent *_ke )
1362 if (!m_part->xmlDocImpl())
1384 if( _ke == d->postponed_autorepeat )
1389 if( _ke->type() == TQEvent::KeyPress )
1391 if( !_ke->isAutoRepeat())
1393 bool ret = dispatchKeyEventHelper( _ke,
false );
1395 if( !ret && dispatchKeyEventHelper( _ke,
true ))
1401 bool ret = dispatchKeyEventHelper( _ke,
true );
1402 if( !ret && d->postponed_autorepeat )
1403 keyPressEvent( d->postponed_autorepeat );
1404 delete d->postponed_autorepeat;
1405 d->postponed_autorepeat = NULL;
1413 if ( d->postponed_autorepeat ) {
1414 delete d->postponed_autorepeat;
1415 d->postponed_autorepeat = 0;
1418 if( !_ke->isAutoRepeat()) {
1419 return dispatchKeyEventHelper( _ke,
false );
1423 d->postponed_autorepeat =
new TQKeyEvent( _ke->type(), _ke->key(), _ke->ascii(), _ke->state(),
1424 _ke->text(), _ke->isAutoRepeat(), _ke->count());
1425 if( _ke->isAccepted())
1426 d->postponed_autorepeat->accept();
1428 d->postponed_autorepeat->ignore();
1435 bool KHTMLView::dispatchKeyEventHelper( TQKeyEvent *_ke,
bool keypress )
1437 DOM::NodeImpl* keyNode = m_part->xmlDocImpl()->focusNode();
1439 return keyNode->dispatchKeyEvent(_ke, keypress);
1441 return m_part->xmlDocImpl()->dispatchKeyEvent(_ke, keypress);
1445 void KHTMLView::keyPressEvent( TQKeyEvent *_ke )
1447 #ifndef KHTML_NO_TYPE_AHEAD_FIND
1448 if(d->typeAheadActivated)
1451 if(_ke->key() == Key_BackSpace)
1453 d->findString = d->findString.left(d->findString.length() - 1);
1455 if(!d->findString.isEmpty())
1464 d->timer.start(3000,
true);
1468 else if(_ke->key() == Key_Escape)
1475 else if(_ke->key() == Key_Space || !TQString(_ke->text()).stripWhiteSpace().isEmpty())
1477 d->findString += _ke->text();
1481 d->timer.start(3000,
true);
1486 #endif // KHTML_NO_TYPE_AHEAD_FIND
1488 #ifndef KHTML_NO_CARET
1490 || (m_part->xmlDocImpl() && m_part->xmlDocImpl()->focusNode()
1491 && m_part->xmlDocImpl()->focusNode()->contentEditable())) {
1492 d->caretViewContext()->keyReleasePending =
true;
1493 caretKeyPressEvent(_ke);
1496 #endif // KHTML_NO_CARET
1499 if (d->accessKeysEnabled && _ke->key() == Key_Control && _ke->state()==0 && !d->accessKeysActivated)
1501 d->accessKeysPreActivate=
true;
1506 if (_ke->key() == Key_Shift && _ke->state()==0)
1507 d->scrollSuspendPreActivate=
true;
1512 if (d->accessKeysEnabled && d->accessKeysActivated)
1514 int state = ( _ke->state() & ( ShiftButton | ControlButton | AltButton | MetaButton ));
1515 if ( state==0 || state==ShiftButton) {
1516 if (_ke->key() != Key_Shift) accessKeysTimeout();
1517 handleAccessKey( _ke );
1521 accessKeysTimeout();
1524 if ( dispatchKeyEvent( _ke )) {
1530 int offs = (clipper()->height() < 30) ? clipper()->height() : 30;
1531 if (_ke->state() & TQt::ShiftButton)
1535 scrollBy( 0, -clipper()->height() + offs );
1536 if(d->scrollSuspended)
1537 d->newScrollTimer(
this, 0);
1542 d->adjustScroller(
this, KHTMLViewPrivate::ScrollDown, KHTMLViewPrivate::ScrollUp);
1547 d->adjustScroller(
this, KHTMLViewPrivate::ScrollUp, KHTMLViewPrivate::ScrollDown);
1552 d->adjustScroller(
this, KHTMLViewPrivate::ScrollLeft, KHTMLViewPrivate::ScrollRight);
1557 d->adjustScroller(
this, KHTMLViewPrivate::ScrollRight, KHTMLViewPrivate::ScrollLeft);
1561 switch ( _ke->key() )
1565 if (!d->scrollTimerId || d->scrollSuspended)
1566 scrollBy( 0, 10 * _ke->count() );
1567 if (d->scrollTimerId)
1568 d->newScrollTimer(
this, 0);
1573 scrollBy( 0, clipper()->height() - offs );
1574 if(d->scrollSuspended)
1575 d->newScrollTimer(
this, 0);
1580 if (!d->scrollTimerId || d->scrollSuspended)
1581 scrollBy( 0, -10 * _ke->count());
1582 if (d->scrollTimerId)
1583 d->newScrollTimer(
this, 0);
1587 scrollBy( 0, -clipper()->height() + offs );
1588 if(d->scrollSuspended)
1589 d->newScrollTimer(
this, 0);
1593 if (!d->scrollTimerId || d->scrollSuspended)
1594 scrollBy( 10 * _ke->count(), 0 );
1595 if (d->scrollTimerId)
1596 d->newScrollTimer(
this, 0);
1600 if (!d->scrollTimerId || d->scrollSuspended)
1601 scrollBy( -10 * _ke->count(), 0 );
1602 if (d->scrollTimerId)
1603 d->newScrollTimer(
this, 0);
1609 if (m_part->xmlDocImpl()) {
1610 NodeImpl *n = m_part->xmlDocImpl()->focusNode();
1616 setContentsPos( 0, 0 );
1617 if(d->scrollSuspended)
1618 d->newScrollTimer(
this, 0);
1621 setContentsPos( 0, contentsHeight() - visibleHeight() );
1622 if(d->scrollSuspended)
1623 d->newScrollTimer(
this, 0);
1630 if (d->scrollTimerId)
1631 d->newScrollTimer(
this, 0);
1639 void KHTMLView::findTimeout()
1641 #ifndef KHTML_NO_TYPE_AHEAD_FIND
1642 d->typeAheadActivated =
false;
1644 m_part->setStatusBarText(i18n(
"Find stopped."), KHTMLPart::BarDefaultText);
1645 m_part->enableFindAheadActions(
true );
1646 #endif // KHTML_NO_TYPE_AHEAD_FIND
1649 #ifndef KHTML_NO_TYPE_AHEAD_FIND
1650 void KHTMLView::startFindAhead(
bool linksOnly )
1654 d->findLinksOnly =
true;
1655 m_part->setStatusBarText(i18n(
"Starting -- find links as you type"),
1656 KHTMLPart::BarDefaultText);
1660 d->findLinksOnly =
false;
1661 m_part->setStatusBarText(i18n(
"Starting -- find text as you type"),
1662 KHTMLPart::BarDefaultText);
1666 d->typeAheadActivated =
true;
1668 m_part->enableFindAheadActions(
false );
1669 d->timer.start(3000,
true);
1672 void KHTMLView::findAhead(
bool increase)
1676 if(d->findLinksOnly)
1678 m_part->
findText(d->findString, KHTMLPart::FindNoPopups |
1679 KHTMLPart::FindLinksOnly,
this);
1682 status = i18n(
"Link found: \"%1\".");
1687 status = i18n(
"Link not found: \"%1\".");
1692 m_part->
findText(d->findString, KHTMLPart::FindNoPopups,
this);
1695 status = i18n(
"Text found: \"%1\".");
1700 status = i18n(
"Text not found: \"%1\".");
1704 m_part->setStatusBarText(status.arg(d->findString.lower()),
1705 KHTMLPart::BarDefaultText);
1708 void KHTMLView::updateFindAheadTimeout()
1710 if( d->typeAheadActivated )
1711 d->timer.start( 3000,
true );
1714 #endif // KHTML_NO_TYPE_AHEAD_FIND
1716 void KHTMLView::keyReleaseEvent(TQKeyEvent *_ke)
1718 #ifndef KHTML_NO_TYPE_AHEAD_FIND
1719 if(d->typeAheadActivated) {
1724 if (d->m_caretViewContext && d->m_caretViewContext->keyReleasePending) {
1726 d->m_caretViewContext->keyReleasePending =
false;
1730 if( d->scrollSuspendPreActivate && _ke->key() != Key_Shift )
1731 d->scrollSuspendPreActivate =
false;
1732 if( _ke->key() == Key_Shift && d->scrollSuspendPreActivate && _ke->state() == TQt::ShiftButton
1735 if (d->scrollTimerId)
1737 d->scrollSuspended = !d->scrollSuspended;
1738 #ifndef NO_SMOOTH_SCROLL_HACK
1739 if( d->scrollSuspended )
1745 if (d->accessKeysEnabled)
1747 if (d->accessKeysPreActivate && _ke->key() != Key_Control)
1748 d->accessKeysPreActivate=
false;
1752 m_part->setStatusBarText(i18n(
"Access Keys activated"),KHTMLPart::BarOverrideText);
1753 d->accessKeysActivated =
true;
1754 d->accessKeysPreActivate =
false;
1758 else if (d->accessKeysActivated)
1760 accessKeysTimeout();
1767 if ( dispatchKeyEvent( _ke ) )
1773 TQScrollView::keyReleaseEvent(_ke);
1776 void KHTMLView::contentsContextMenuEvent ( TQContextMenuEvent * )
1780 if (!m_part->xmlDocImpl())
return;
1784 DOM::NodeImpl::MouseEvent mev( _ce->state(), DOM::NodeImpl::MouseMove );
1785 m_part->xmlDocImpl()->prepareMouseEvent( xm, ym, &mev );
1787 NodeImpl *targetNode = mev.innerNode.handle();
1788 if (targetNode && targetNode->renderer() && targetNode->renderer()->isWidget()) {
1791 targetNode->renderer()->absolutePosition(absx,absy);
1792 TQPoint pos(xm-absx,ym-absy);
1794 TQWidget *w =
static_cast<RenderWidget*
>(targetNode->renderer())->widget();
1795 TQContextMenuEvent cme(_ce->reason(),pos,_ce->globalPos(),_ce->state());
1796 setIgnoreEvents(
true);
1797 TQApplication::sendEvent(w,&cme);
1798 setIgnoreEvents(
false);
1803 bool KHTMLView::focusNextPrevChild(
bool next )
1806 if (m_part->xmlDocImpl() && focusNextPrevNode(next))
1808 if (m_part->xmlDocImpl()->focusNode())
1809 kdDebug() <<
"focusNode.name: "
1810 << m_part->xmlDocImpl()->focusNode()->nodeName().string() <<
endl;
1815 d->pseudoFocusNode = KHTMLViewPrivate::PFNone;
1819 return TQWidget::focusNextPrevChild(next);
1822 void KHTMLView::doAutoScroll()
1824 TQPoint pos = TQCursor::pos();
1825 pos = viewport()->mapFromGlobal( pos );
1828 viewportToContents(pos.x(), pos.y(), xm, ym);
1830 pos = TQPoint(pos.x() - viewport()->x(), pos.y() - viewport()->y());
1831 if ( (pos.y() < 0) || (pos.y() > visibleHeight()) ||
1832 (pos.x() < 0) || (pos.x() > visibleWidth()) )
1834 ensureVisible( xm, ym, 0, 5 );
1836 #ifndef KHTML_NO_SELECTION
1839 if (m_part->isExtendingSelection()) {
1840 RenderObject::NodeInfo renderInfo(
true,
false);
1841 m_part->xmlDocImpl()->renderer()->layer()
1842 ->nodeAtPoint(renderInfo, xm, ym);
1843 innerNode = renderInfo.innerNode();
1846 if (innerNode.handle() && innerNode.handle()->renderer()) {
1848 innerNode.handle()->renderer()->absolutePosition(absX, absY);
1850 m_part->extendSelectionTo(xm, ym, absX, absY, innerNode);
1852 #endif // KHTML_NO_SELECTION
1857 class HackWidget :
public TQWidget
1860 inline void setNoErase() { setWFlags(getWFlags()|WRepaintNoErase); }
1863 bool KHTMLView::eventFilter(TQObject *o, TQEvent *e)
1865 if ( e->type() == TQEvent::AccelOverride ) {
1866 TQKeyEvent* ke = (TQKeyEvent*) e;
1869 || (m_part->xmlDocImpl() && m_part->xmlDocImpl()->focusNode()
1870 && m_part->xmlDocImpl()->focusNode()->contentEditable())) {
1872 if ( (ke->state() & ControlButton) || (ke->state() & ShiftButton) ) {
1873 switch ( ke->key() ) {
1890 if ( e->type() == TQEvent::Leave ) {
1891 if ( d->cursor_icon_widget )
1892 d->cursor_icon_widget->hide();
1893 m_part->resetHoverText();
1896 TQWidget *view = viewport();
1898 if (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(view)) {
1901 if(e->type() == TQEvent::ChildInserted) {
1902 TQObject *c = TQT_TQOBJECT(TQT_TQCHILDEVENT(e)->child());
1903 if (c->isWidgetType()) {
1904 TQWidget *w = TQT_TQWIDGET(c);
1906 if (w->parentWidget(
true) == view) {
1907 if (!strcmp(w->name(),
"__khtml")) {
1908 w->installEventFilter(
this);
1910 if (!::tqqt_cast<TQFrame*>(w))
1911 w->setBackgroundMode( TQWidget::NoBackground );
1912 static_cast<HackWidget *
>(w)->setNoErase();
1913 if (!w->childrenListObject().isEmpty()) {
1914 TQObjectListIterator it(w->childrenListObject());
1915 for (; it.current(); ++it) {
1916 TQWidget *widget = ::tqqt_cast<TQWidget *>(it.current());
1917 if (widget && !widget->isTopLevel()) {
1918 if (!::tqqt_cast<TQFrame*>(w))
1919 widget->setBackgroundMode( TQWidget::NoBackground );
1920 static_cast<HackWidget *
>(widget)->setNoErase();
1921 widget->installEventFilter(
this);
1929 }
else if (o->isWidgetType()) {
1930 TQWidget *v = TQT_TQWIDGET(o);
1932 while (v && v != view) {
1934 v = v->parentWidget(
true);
1937 if (v && !strcmp(c->name(),
"__khtml")) {
1939 TQWidget *w = TQT_TQWIDGET(o);
1941 case TQEvent::Paint:
1942 if (!allowWidgetPaintEvents) {
1948 while (v && v != view) {
1951 v = v->parentWidget();
1953 viewportToContents( x, y, x, y );
1954 TQPaintEvent *pe = TQT_TQPAINTEVENT(e);
1955 bool asap = !d->contentsMoving && ::tqqt_cast<TQScrollView *>(c);
1958 if ( asap && !d->painting && m_part->xmlDocImpl() && m_part->xmlDocImpl()->renderer() &&
1959 !
static_cast<khtml::RenderCanvas *
>(m_part->xmlDocImpl()->renderer())->needsLayout() ) {
1960 repaintContents(x + pe->rect().x(), y + pe->rect().y(),
1961 pe->rect().width(), pe->rect().height(),
true);
1963 scheduleRepaint(x + pe->rect().x(), y + pe->rect().y(),
1964 pe->rect().width(), pe->rect().height(), asap);
1968 case TQEvent::MouseMove:
1969 case TQEvent::MouseButtonPress:
1970 case TQEvent::MouseButtonRelease:
1971 case TQEvent::MouseButtonDblClick: {
1972 if ( (w->parentWidget() == view || ::tqqt_cast<TQScrollView*>(c)) && !::tqqt_cast<TQScrollBar *>(w)) {
1973 TQMouseEvent *me = TQT_TQMOUSEEVENT(e);
1974 TQPoint pt = w->mapTo( view, me->pos());
1975 TQMouseEvent me2(me->type(), pt, me->button(), me->state());
1977 if (e->type() == TQEvent::MouseMove)
1978 viewportMouseMoveEvent(&me2);
1979 else if(e->type() == TQEvent::MouseButtonPress)
1980 viewportMousePressEvent(&me2);
1981 else if(e->type() == TQEvent::MouseButtonRelease)
1982 viewportMouseReleaseEvent(&me2);
1984 viewportMouseDoubleClickEvent(&me2);
1989 case TQEvent::KeyPress:
1990 case TQEvent::KeyRelease:
1991 if (w->parentWidget() == view && !::tqqt_cast<TQScrollBar *>(w)) {
1992 TQKeyEvent *ke = TQT_TQKEYEVENT(e);
1993 if (e->type() == TQEvent::KeyPress)
1996 keyReleaseEvent(ke);
2010 return TQScrollView::eventFilter(o, e);
2014 DOM::NodeImpl *KHTMLView::nodeUnderMouse()
const
2016 return d->underMouse;
2019 DOM::NodeImpl *KHTMLView::nonSharedNodeUnderMouse()
const
2021 return d->underMouseNonShared;
2024 bool KHTMLView::scrollTo(
const TQRect &bounds)
2026 d->scrollingSelf =
true;
2031 xe = bounds.right();
2032 ye = bounds.bottom();
2039 int curHeight = visibleHeight();
2040 int curWidth = visibleWidth();
2042 if (ye-y>curHeight-d->borderY)
2043 ye = y + curHeight - d->borderY;
2045 if (xe-x>curWidth-d->borderX)
2046 xe = x + curWidth - d->borderX;
2049 if (x < contentsX() + d->borderX )
2050 deltax = x - contentsX() - d->borderX;
2052 else if (xe + d->borderX > contentsX() + curWidth)
2053 deltax = xe + d->borderX - ( contentsX() + curWidth );
2058 if (y < contentsY() + d->borderY)
2059 deltay = y - contentsY() - d->borderY;
2061 else if (ye + d->borderY > contentsY() + curHeight)
2062 deltay = ye + d->borderY - ( contentsY() + curHeight );
2066 int maxx = curWidth-d->borderX;
2067 int maxy = curHeight-d->borderY;
2069 int scrollX,scrollY;
2071 scrollX = deltax > 0 ? (deltax > maxx ? maxx : deltax) : deltax == 0 ? 0 : (deltax>-maxx ? deltax : -maxx);
2072 scrollY = deltay > 0 ? (deltay > maxy ? maxy : deltay) : deltay == 0 ? 0 : (deltay>-maxy ? deltay : -maxy);
2074 if (contentsX() + scrollX < 0)
2075 scrollX = -contentsX();
2076 else if (contentsWidth() - visibleWidth() - contentsX() < scrollX)
2077 scrollX = contentsWidth() - visibleWidth() - contentsX();
2079 if (contentsY() + scrollY < 0)
2080 scrollY = -contentsY();
2081 else if (contentsHeight() - visibleHeight() - contentsY() < scrollY)
2082 scrollY = contentsHeight() - visibleHeight() - contentsY();
2084 scrollBy(scrollX, scrollY);
2086 d->scrollingSelf =
false;
2088 if ( (abs(deltax)<=maxx) && (abs(deltay)<=maxy) )
2094 bool KHTMLView::focusNextPrevNode(
bool next)
2103 DocumentImpl *doc = m_part->xmlDocImpl();
2104 NodeImpl *oldFocusNode = doc->focusNode();
2109 if (oldFocusNode && oldFocusNode->renderer() &&
2110 !oldFocusNode->renderer()->parent()) {
2111 doc->setFocusNode(0);
2119 if (d->scrollBarMoved)
2123 toFocus = doc->nextFocusNode(oldFocusNode);
2125 toFocus = doc->previousFocusNode(oldFocusNode);
2127 if (!toFocus && oldFocusNode)
2129 toFocus = doc->nextFocusNode(NULL);
2131 toFocus = doc->previousFocusNode(NULL);
2133 while (toFocus && toFocus != oldFocusNode)
2136 TQRect focusNodeRect = toFocus->getRect();
2137 if ((focusNodeRect.left() > contentsX()) && (focusNodeRect.right() < contentsX() + visibleWidth()) &&
2138 (focusNodeRect.top() > contentsY()) && (focusNodeRect.bottom() < contentsY() + visibleHeight())) {
2140 TQRect r = toFocus->getRect();
2141 ensureVisible( r.right(), r.bottom());
2142 ensureVisible( r.left(), r.top());
2143 d->scrollBarMoved =
false;
2144 d->tabMovePending =
false;
2145 d->lastTabbingDirection = next;
2146 d->pseudoFocusNode = KHTMLViewPrivate::PFNone;
2147 m_part->xmlDocImpl()->setFocusNode(toFocus);
2148 Node guard(toFocus);
2149 if (!toFocus->hasOneRef() )
2157 toFocus = doc->nextFocusNode(toFocus);
2159 toFocus = doc->previousFocusNode(toFocus);
2161 if (!toFocus && oldFocusNode)
2163 toFocus = doc->nextFocusNode(NULL);
2165 toFocus = doc->previousFocusNode(NULL);
2168 d->scrollBarMoved =
false;
2172 if (!oldFocusNode && d->pseudoFocusNode == KHTMLViewPrivate::PFNone)
2174 ensureVisible(contentsX(), next?0:contentsHeight());
2175 d->scrollBarMoved =
false;
2176 d->pseudoFocusNode = next?KHTMLViewPrivate::PFTop:KHTMLViewPrivate::PFBottom;
2180 NodeImpl *newFocusNode = NULL;
2182 if (d->tabMovePending && next != d->lastTabbingDirection)
2185 newFocusNode = oldFocusNode;
2189 if (oldFocusNode || d->pseudoFocusNode == KHTMLViewPrivate::PFTop )
2190 newFocusNode = doc->nextFocusNode(oldFocusNode);
2194 if (oldFocusNode || d->pseudoFocusNode == KHTMLViewPrivate::PFBottom )
2195 newFocusNode = doc->previousFocusNode(oldFocusNode);
2198 bool targetVisible =
false;
2203 targetVisible = scrollTo(TQRect(contentsX()+visibleWidth()/2,contentsHeight()-d->borderY,0,0));
2207 targetVisible = scrollTo(TQRect(contentsX()+visibleWidth()/2,d->borderY,0,0));
2212 #ifndef KHTML_NO_CARET
2215 && newFocusNode->contentEditable()) {
2216 d->caretViewContext();
2217 moveCaretTo(newFocusNode, 0L,
true);
2221 #endif // KHTML_NO_CARET
2223 targetVisible = scrollTo(newFocusNode->getRect());
2229 d->tabMovePending =
false;
2231 m_part->xmlDocImpl()->setFocusNode(newFocusNode);
2234 Node guard(newFocusNode);
2235 if (!newFocusNode->hasOneRef() )
2243 d->pseudoFocusNode = next?KHTMLViewPrivate::PFBottom:KHTMLViewPrivate::PFTop;
2249 if (!d->tabMovePending)
2250 d->lastTabbingDirection = next;
2251 d->tabMovePending =
true;
2258 TQValueVector< TQChar > taken;
2265 TQMap< ElementImpl*, TQChar > fallbacks;
2267 fallbacks = buildFallbackAccessKeys();
2268 for( NodeImpl* n = m_part->xmlDocImpl(); n != NULL; n = n->traverseNextNode()) {
2269 if( n->isElementNode()) {
2270 ElementImpl* en =
static_cast< ElementImpl*
>( n );
2271 DOMString s = en->getAttribute( ATTR_ACCESSKEY );
2273 if( s.length() == 1 ) {
2274 TQChar a = s.string()[ 0 ].upper();
2275 if( tqFind( taken.begin(), taken.end(), a ) == taken.end())
2278 if( accesskey.isNull() && fallbacks.contains( en )) {
2279 TQChar a = fallbacks[ en ].upper();
2280 if( tqFind( taken.begin(), taken.end(), a ) == taken.end())
2281 accesskey = TQString(
"<qt><i>" ) + a +
"</i></qt>";
2283 if( !accesskey.isNull()) {
2284 TQRect rec=en->getRect();
2285 TQLabel *lab=
new TQLabel(accesskey,viewport(),0,(WFlags)WDestructiveClose);
2286 connect( origview, TQT_SIGNAL(hideAccessKeys()), lab, TQT_SLOT(
close()) );
2287 connect(
this, TQT_SIGNAL(repaintAccessKeys()), lab, TQT_SLOT(repaint()));
2288 lab->setPalette(TQToolTip::palette());
2289 lab->setLineWidth(2);
2290 lab->setFrameStyle(TQFrame::Box | TQFrame::Plain);
2294 KMIN(rec.left()+rec.width()/2, contentsWidth() - lab->width()),
2295 KMIN(rec.top()+rec.height()/2, contentsHeight() - lab->height()));
2297 taken.append( accesskey[ 0 ] );
2303 TQPtrList<KParts::ReadOnlyPart> frames = m_part->frames();
2304 for( TQPtrListIterator<KParts::ReadOnlyPart> it( frames );
2307 if( !(*it)->inherits(
"KHTMLPart" ))
2310 if( part->
view() && part->
view() != caller )
2321 void KHTMLView::accessKeysTimeout()
2323 d->accessKeysActivated=
false;
2324 d->accessKeysPreActivate =
false;
2325 m_part->setStatusBarText(TQString::null, KHTMLPart::BarOverrideText);
2326 emit hideAccessKeys();
2330 bool KHTMLView::handleAccessKey(
const TQKeyEvent* ev )
2335 if( ev->key() >= Key_A && ev->key() <= Key_Z )
2336 c =
'A' + ev->key() - Key_A;
2337 else if( ev->key() >= Key_0 && ev->key() <= Key_9 )
2338 c =
'0' + ev->key() - Key_0;
2342 if( ev->text().length() == 1 )
2343 c = ev->text()[ 0 ];
2347 return focusNodeWithAccessKey( c );
2350 bool KHTMLView::focusNodeWithAccessKey( TQChar c,
KHTMLView* caller )
2352 DocumentImpl *doc = m_part->xmlDocImpl();
2355 ElementImpl* node = doc->findAccessKeyElement( c );
2357 TQPtrList<KParts::ReadOnlyPart> frames = m_part->frames();
2358 for( TQPtrListIterator<KParts::ReadOnlyPart> it( frames );
2361 if( !(*it)->inherits(
"KHTMLPart" ))
2364 if( part->
view() && part->
view() != caller
2365 && part->
view()->focusNodeWithAccessKey( c,
this ))
2371 && m_part->
parentPart()->
view()->focusNodeWithAccessKey( c,
this ))
2373 if( caller == NULL ) {
2374 TQMap< ElementImpl*, TQChar > fallbacks = buildFallbackAccessKeys();
2375 for( TQMap< ElementImpl*, TQChar >::ConstIterator it = fallbacks.begin();
2376 it != fallbacks.end();
2388 #ifndef KHTML_NO_CARET
2391 && node->contentEditable()) {
2392 d->caretViewContext();
2393 moveCaretTo(node, 0L,
true);
2397 #endif // KHTML_NO_CARET
2399 TQRect r = node->getRect();
2400 ensureVisible( r.right(), r.bottom());
2401 ensureVisible( r.left(), r.top());
2404 if( node->isFocusable()) {
2405 if (node->id()==ID_LABEL) {
2407 node=
static_cast<ElementImpl *
>(
static_cast< HTMLLabelElementImpl*
>( node )->getFormElement());
2408 if (!node)
return true;
2413 m_part->xmlDocImpl()->setFocusNode(node);
2415 TQFocusEvent::setReason( TQFocusEvent::Shortcut );
2416 m_part->xmlDocImpl()->setFocusNode(node);
2417 TQFocusEvent::resetReason();
2419 if( node != NULL && node->hasOneRef())
2422 if( node != NULL && node->hasOneRef())
2426 switch( node->id()) {
2428 static_cast< HTMLAnchorElementImpl*
>( node )->click();
2431 static_cast< HTMLInputElementImpl*
>( node )->click();
2434 static_cast< HTMLButtonElementImpl*
>( node )->click();
2437 static_cast< HTMLAreaElementImpl*
>( node )->click();
2448 static TQString getElementText( NodeImpl* start,
bool after )
2451 for( NodeImpl* n = after ? start->nextSibling() : start->traversePreviousNode();
2453 n = after ? n->traverseNextNode() : n->traversePreviousNode()) {
2454 if( n->isTextNode()) {
2456 ret +=
static_cast< TextImpl*
>( n )->toString().string();
2458 ret.prepend( static_cast< TextImpl* >( n )->toString().
string());
2488 if( ret.stripWhiteSpace().isEmpty())
2492 return ret.simplifyWhiteSpace();
2496 return ret.simplifyWhiteSpace();
2499 static TQMap< NodeImpl*, TQString > buildLabels( NodeImpl* start )
2501 TQMap< NodeImpl*, TQString > ret;
2502 for( NodeImpl* n = start;
2504 n = n->traverseNextNode()) {
2505 if( n->id() == ID_LABEL ) {
2506 HTMLLabelElementImpl*
label =
static_cast< HTMLLabelElementImpl*
>( n );
2507 NodeImpl* labelfor = label->getFormElement();
2509 ret[ labelfor ] = label->innerText().string().simplifyWhiteSpace();
2516 struct AccessKeyData {
2517 ElementImpl* element;
2524 TQMap< ElementImpl*, TQChar > KHTMLView::buildFallbackAccessKeys()
const
2527 TQValueList< AccessKeyData > data;
2528 TQMap< NodeImpl*, TQString > labels = buildLabels( m_part->xmlDocImpl());
2529 for( NodeImpl* n = m_part->xmlDocImpl();
2531 n = n->traverseNextNode()) {
2532 if( n->isElementNode()) {
2533 ElementImpl* element =
static_cast< ElementImpl*
>( n );
2534 if( element->getAttribute( ATTR_ACCESSKEY ).length() == 1 )
2536 if( element->renderer() == NULL )
2541 bool ignore =
false;
2542 bool text_after =
false;
2543 bool text_before =
false;
2544 switch( element->id()) {
2546 url = khtml::parseURL(element->getAttribute(ATTR_HREF)).
string();
2549 text =
static_cast< HTMLElementImpl*
>( element )->innerText().string().simplifyWhiteSpace();
2553 HTMLInputElementImpl* in =
static_cast< HTMLInputElementImpl*
>( element );
2554 switch( in->inputType()) {
2555 case HTMLInputElementImpl::SUBMIT:
2556 text = in->value().string();
2558 text = i18n(
"Submit" );
2561 case HTMLInputElementImpl::IMAGE:
2562 text = in->altText().string();
2565 case HTMLInputElementImpl::BUTTON:
2566 text = in->value().string();
2569 case HTMLInputElementImpl::RESET:
2570 text = in->value().string();
2572 text = i18n(
"Reset" );
2575 case HTMLInputElementImpl::HIDDEN:
2578 case HTMLInputElementImpl::CHECKBOX:
2579 case HTMLInputElementImpl::RADIO:
2583 case HTMLInputElementImpl::TEXT:
2584 case HTMLInputElementImpl::PASSWORD:
2585 case HTMLInputElementImpl::FILE:
2596 text =
static_cast< HTMLElementImpl*
>( element )->innerText().string().simplifyWhiteSpace();
2597 switch( static_cast< HTMLButtonElementImpl* >( element )->buttonType()) {
2598 case HTMLButtonElementImpl::SUBMIT:
2600 text = i18n(
"Submit" );
2603 case HTMLButtonElementImpl::RESET:
2605 text = i18n(
"Reset" );
2622 ignore = !element->isFocusable();
2628 if( text.isNull() && labels.contains( element ))
2629 text = labels[ element ];
2630 if( text.isNull() && text_before )
2631 text = getElementText( element,
false );
2632 if( text.isNull() && text_after )
2633 text = getElementText( element,
true );
2634 text = text.stripWhiteSpace();
2636 TQValueList< TQPair< TQString, TQChar > > priorities
2637 = m_part->settings()->fallbackAccessKeysAssignments();
2638 for( TQValueList< TQPair< TQString, TQChar > >::ConstIterator it = priorities.begin();
2639 it != priorities.end();
2641 if( text == (*it).first )
2644 AccessKeyData tmp = { element, text, url, priority };
2649 TQValueList< TQChar > keys;
2650 for(
char c =
'A'; c <=
'Z'; ++c )
2652 for(
char c =
'0'; c <=
'9'; ++c )
2654 for( NodeImpl* n = m_part->xmlDocImpl();
2656 n = n->traverseNextNode()) {
2657 if( n->isElementNode()) {
2658 ElementImpl* en =
static_cast< ElementImpl*
>( n );
2659 DOMString s = en->getAttribute( ATTR_ACCESSKEY );
2660 if( s.length() == 1 ) {
2661 TQChar c = s.string()[ 0 ].upper();
2667 TQMap< ElementImpl*, TQChar > ret;
2668 for(
int priority = 10;
2671 for( TQValueList< AccessKeyData >::Iterator it = data.begin();
2674 if( (*it).priority != priority ) {
2680 TQString text = (*it).text;
2682 if( key.isNull() && !text.isEmpty()) {
2683 TQValueList< TQPair< TQString, TQChar > > priorities
2684 = m_part->settings()->fallbackAccessKeysAssignments();
2685 for( TQValueList< TQPair< TQString, TQChar > >::ConstIterator it = priorities.begin();
2686 it != priorities.end();
2688 if( text == (*it).first && keys.contains( (*it).second )) {
2696 if( key.isNull() && !text.isEmpty()) {
2697 TQStringList words = TQStringList::split(
' ', text );
2698 for( TQStringList::ConstIterator it = words.begin();
2701 if( keys.contains( (*it)[ 0 ].upper())) {
2702 key = (*it)[ 0 ].upper();
2707 if( key.isNull() && !text.isEmpty()) {
2708 for(
unsigned int i = 0;
2711 if( keys.contains( text[ i ].upper())) {
2712 key = text[ i ].upper();
2719 ret[ (*it).element ] = key;
2721 TQString url = (*it).url;
2722 it = data.remove( it );
2724 if( !url.isEmpty() && !url.startsWith(
"javascript:",
false )) {
2725 for( TQValueList< AccessKeyData >::Iterator it2 = data.begin();
2728 if( (*it2).url == url ) {
2729 ret[ (*it2).element ] = key;
2732 it2 = data.remove( it2 );
2742 void KHTMLView::setMediaType(
const TQString &medium )
2747 TQString KHTMLView::mediaType()
const
2752 bool KHTMLView::pagedMode()
const
2757 void KHTMLView::setWidgetVisible(RenderWidget* w,
bool vis)
2760 d->visibleWidgets.replace(w, w->widget());
2763 d->visibleWidgets.remove(w);
2766 bool KHTMLView::needsFullRepaint()
const
2768 return d->needsFullRepaint;
2778 if(!m_part->xmlDocImpl())
return;
2779 khtml::RenderCanvas *root =
static_cast<khtml::RenderCanvas *
>(m_part->xmlDocImpl()->renderer());
2782 KPrinter *printer =
new KPrinter(
true, TQPrinter::ScreenResolution);
2783 printer->addDialogPage(
new KHTMLPrintSettings());
2784 TQString docname = m_part->xmlDocImpl()->URL().prettyURL();
2785 if ( !docname.isEmpty() )
2787 if(quick || printer->setup(
this, i18n(
"Print %1").arg(docname))) {
2788 viewport()->setCursor( tqwaitCursor );
2790 printer->setFullPage(
false);
2791 printer->setCreator(TQString(
"KDE %1.%2.%3 HTML Library").arg(KDE_VERSION_MAJOR).arg(KDE_VERSION_MINOR).arg(KDE_VERSION_RELEASE));
2792 printer->setDocName(docname);
2794 TQPainter *p =
new TQPainter;
2795 p->
begin( printer );
2796 khtml::setPrintPainter( p );
2798 m_part->xmlDocImpl()->setPaintDevice( printer );
2799 TQString oldMediaType = mediaType();
2800 setMediaType(
"print" );
2804 m_part->xmlDocImpl()->setPrintStyleSheet( printer->option(
"app-khtml-printfriendly") ==
"true" ?
2805 "* { background-image: none !important;"
2806 " background-color: white !important;"
2807 " color: black !important; }"
2808 "body { margin: 0px !important; }"
2809 "html { margin: 0px !important; }" :
2810 "body { margin: 0px !important; }"
2811 "html { margin: 0px !important; }"
2814 TQPaintDeviceMetrics metrics( printer );
2816 kdDebug(6000) <<
"printing: physical page width = " << metrics.width()
2817 <<
" height = " << metrics.height() <<
endl;
2818 root->setStaticMode(
true);
2819 root->setPagedMode(
true);
2820 root->setWidth(metrics.width());
2822 root->setPageTop(0);
2823 root->setPageBottom(0);
2826 m_part->xmlDocImpl()->styleSelector()->computeFontSizes(&metrics, 100);
2827 m_part->xmlDocImpl()->updateStyleSelector();
2828 root->setPrintImages( printer->option(
"app-khtml-printimages") ==
"true");
2829 root->makePageBreakAvoidBlocks();
2831 root->setNeedsLayoutAndMinMaxRecalc();
2833 khtml::RenderWidget::flushWidgetResizes();
2837 bool printHeader = (printer->option(
"app-khtml-printheader") ==
"true");
2839 int headerHeight = 0;
2840 TQFont headerFont(
"Sans Serif", 8);
2843 TQString headerMid = docname;
2844 TQString headerRight;
2848 p->setFont(headerFont);
2849 headerHeight = (p->fontMetrics().lineSpacing() * 3) / 2;
2853 kdDebug(6000) <<
"printing: html page width = " << root->docWidth()
2854 <<
" height = " << root->docHeight() <<
endl;
2855 kdDebug(6000) <<
"printing: margins left = " << printer->margins().width()
2856 <<
" top = " << printer->margins().height() <<
endl;
2857 kdDebug(6000) <<
"printing: paper width = " << metrics.width()
2858 <<
" height = " << metrics.height() <<
endl;
2861 int pageWidth = metrics.width();
2862 int pageHeight = metrics.height();
2863 p->setClipRect(0,0, pageWidth, pageHeight);
2865 pageHeight -= headerHeight;
2867 bool scalePage =
false;
2869 #ifndef QT_NO_TRANSFORMATIONS
2870 if(root->docWidth() > metrics.width()) {
2872 scale = ((double) metrics.width())/((
double) root->docWidth());
2873 pageHeight = (int) (pageHeight/scale);
2874 pageWidth = (int) (pageWidth/scale);
2875 headerHeight = (int) (headerHeight/scale);
2878 kdDebug(6000) <<
"printing: scaled html width = " << pageWidth
2879 <<
" height = " << pageHeight <<
endl;
2881 root->setHeight(pageHeight);
2882 root->setPageBottom(pageHeight);
2883 root->setNeedsLayout(
true);
2884 root->layoutIfNeeded();
2890 int available_width = metrics.width() - 10 -
2891 2 * kMax(p->boundingRect(0, 0, metrics.width(), p->fontMetrics().lineSpacing(), Qt::AlignLeft, headerLeft).width(),
2892 p->boundingRect(0, 0, metrics.width(), p->fontMetrics().lineSpacing(), Qt::AlignLeft, headerRight).width());
2893 if (available_width < 150)
2894 available_width = 150;
2899 mid_width = p->boundingRect(0, 0, metrics.width(), p->fontMetrics().lineSpacing(), Qt::AlignLeft, headerMid).width();
2901 }
while (mid_width > available_width);
2907 while(top < root->docHeight()) {
2908 if(top > 0) printer->newPage();
2909 p->setClipRect(0, 0, pageWidth, headerHeight, TQPainter::CoordDevice);
2912 int dy = p->fontMetrics().lineSpacing();
2913 p->setPen(Qt::black);
2914 p->setFont(headerFont);
2916 headerRight = TQString(
"#%1").arg(page);
2918 p->drawText(0, 0, metrics.width(), dy, Qt::AlignLeft, headerLeft);
2919 p->drawText(0, 0, metrics.width(), dy, Qt::AlignHCenter, headerMid);
2920 p->drawText(0, 0, metrics.width(), dy, Qt::AlignRight, headerRight);
2924 #ifndef QT_NO_TRANSFORMATIONS
2926 p->scale(scale, scale);
2929 p->setClipRect(0, headerHeight, pageWidth, pageHeight, TQPainter::CoordDevice);
2930 p->translate(0, headerHeight-top);
2932 bottom = top+pageHeight;
2934 root->setPageTop(top);
2935 root->setPageBottom(bottom);
2936 root->setPageNumber(page);
2938 root->layer()->paint(p, TQRect(0, top, pageWidth, pageHeight));
2942 kdDebug(6000) <<
"printed: page " << page <<
" bottom At = " << bottom <<
endl;
2953 root->setPagedMode(
false);
2954 root->setStaticMode(
false);
2956 khtml::setPrintPainter( 0 );
2957 setMediaType( oldMediaType );
2958 m_part->xmlDocImpl()->setPaintDevice( TQT_TQPAINTDEVICE(
this) );
2959 m_part->xmlDocImpl()->styleSelector()->computeFontSizes(m_part->xmlDocImpl()->paintDeviceMetrics(), m_part->
zoomFactor());
2960 m_part->xmlDocImpl()->updateStyleSelector();
2961 viewport()->unsetCursor();
2966 void KHTMLView::slotPaletteChanged()
2968 if(!m_part->xmlDocImpl())
return;
2969 DOM::DocumentImpl *document = m_part->xmlDocImpl();
2970 if (!document->isHTMLDocument())
return;
2971 khtml::RenderCanvas *root =
static_cast<khtml::RenderCanvas *
>(document->renderer());
2973 root->style()->resetPalette();
2974 NodeImpl *body =
static_cast<HTMLDocumentImpl*
>(document)->body();
2976 body->setChanged(
true);
2977 body->recalcStyle( NodeImpl::Force );
2980 void KHTMLView::paint(TQPainter *p,
const TQRect &rc,
int yOff,
bool *more)
2982 if(!m_part->xmlDocImpl())
return;
2983 khtml::RenderCanvas *root =
static_cast<khtml::RenderCanvas *
>(m_part->xmlDocImpl()->renderer());
2986 m_part->xmlDocImpl()->setPaintDevice(p->device());
2987 root->setPagedMode(
true);
2988 root->setStaticMode(
true);
2989 root->setWidth(rc.width());
2993 p->translate(rc.left(), rc.top());
2994 double scale = ((double) rc.width()/(double) root->docWidth());
2995 int height = (int) ((
double) rc.height() / scale);
2996 #ifndef QT_NO_TRANSFORMATIONS
2997 p->scale(scale, scale);
2999 root->setPageTop(yOff);
3000 root->setPageBottom(yOff+height);
3002 root->layer()->paint(p, TQRect(0, yOff, root->docWidth(), height));
3004 *more = yOff + height < root->docHeight();
3007 root->setPagedMode(
false);
3008 root->setStaticMode(
false);
3009 m_part->xmlDocImpl()->setPaintDevice( TQT_TQPAINTDEVICE(
this) );
3013 void KHTMLView::useSlowRepaints()
3015 d->useSlowRepaints =
true;
3016 setStaticBackground(
true);
3022 #ifndef KHTML_NO_SCROLLBARS
3032 #ifndef KHTML_NO_SCROLLBARS
3040 void KHTMLView::restoreScrollBar()
3042 int ow = visibleWidth();
3044 if (visibleWidth() != ow)
3046 d->prevScrollbarVisible = verticalScrollBar()->isVisible();
3049 TQStringList KHTMLView::formCompletionItems(
const TQString &name)
const
3051 if (!m_part->settings()->isFormCompletionEnabled())
3052 return TQStringList();
3053 if (!d->formCompletions)
3055 return d->formCompletions->readListEntry(name);
3058 void KHTMLView::clearCompletionHistory(
const TQString& name)
3060 if (!d->formCompletions)
3064 d->formCompletions->writeEntry(name,
"");
3065 d->formCompletions->sync();
3068 void KHTMLView::addFormCompletionItem(
const TQString &name,
const TQString &value)
3070 if (!m_part->settings()->isFormCompletionEnabled())
3075 bool cc_number(
true);
3076 for (
unsigned int i = 0; i < value.length(); ++i)
3079 if (!c.isNumber() && c !=
'-' && !c.isSpace())
3087 TQStringList items = formCompletionItems(name);
3088 if (!items.contains(value))
3089 items.prepend(value);
3090 while ((
int)items.count() > m_part->settings()->maxFormCompletionItems())
3091 items.remove(items.fromLast());
3092 d->formCompletions->writeEntry(name, items);
3095 void KHTMLView::removeFormCompletionItem(
const TQString &name,
const TQString &value)
3097 if (!m_part->settings()->isFormCompletionEnabled())
3100 TQStringList items = formCompletionItems(name);
3101 if (items.remove(value))
3102 d->formCompletions->writeEntry(name, items);
3105 void KHTMLView::addNonPasswordStorableSite(
const TQString& host)
3107 if (!d->formCompletions) {
3111 d->formCompletions->setGroup(
"NonPasswordStorableSites");
3112 TQStringList sites = d->formCompletions->readListEntry(
"Sites");
3114 d->formCompletions->writeEntry(
"Sites", sites);
3115 d->formCompletions->sync();
3116 d->formCompletions->setGroup(TQString::null);
3119 bool KHTMLView::nonPasswordStorableSite(
const TQString& host)
const
3121 if (!d->formCompletions) {
3124 d->formCompletions->setGroup(
"NonPasswordStorableSites");
3125 TQStringList sites = d->formCompletions->readListEntry(
"Sites");
3126 d->formCompletions->setGroup(TQString::null);
3128 return (sites.find(host) != sites.end());
3132 bool KHTMLView::dispatchMouseEvent(
int eventId, DOM::NodeImpl *targetNode,
3133 DOM::NodeImpl *targetNodeNonShared,
bool cancelable,
3134 int detail,TQMouseEvent *_mouse,
bool setUnder,
3138 if (targetNode && targetNode->isTextNode())
3139 targetNode = targetNode->parentNode();
3142 d->underMouse->deref();
3143 d->underMouse = targetNode;
3145 d->underMouse->ref();
3147 if (d->underMouseNonShared)
3148 d->underMouseNonShared->deref();
3149 d->underMouseNonShared = targetNodeNonShared;
3150 if (d->underMouseNonShared)
3151 d->underMouseNonShared->ref();
3153 int exceptioncode = 0;
3156 viewportToContents(_mouse->x(), _mouse->y(), pageX, pageY);
3157 int clientX = pageX - contentsX();
3158 int clientY = pageY - contentsY();
3159 int screenX = _mouse->globalX();
3160 int screenY = _mouse->globalY();
3162 switch (_mouse->button()) {
3163 case Qt::LeftButton:
3169 case Qt::RightButton:
3175 if (d->accessKeysEnabled && d->accessKeysPreActivate && button!=-1)
3176 d->accessKeysPreActivate=
false;
3178 bool ctrlKey = (_mouse->state() & ControlButton);
3179 bool altKey = (_mouse->state() & AltButton);
3180 bool shiftKey = (_mouse->state() & ShiftButton);
3181 bool metaKey = (_mouse->state() & MetaButton);
3184 if (setUnder && (d->prevMouseX != pageX || d->prevMouseY != pageY)) {
3188 NodeImpl *oldUnder = 0;
3189 if (d->prevMouseX >= 0 && d->prevMouseY >= 0) {
3190 NodeImpl::MouseEvent mev( _mouse->stateAfter(),
static_cast<NodeImpl::MouseEventType
>(mouseEventType));
3191 m_part->xmlDocImpl()->prepareMouseEvent(
true, d->prevMouseX, d->prevMouseY, &mev );
3192 oldUnder = mev.innerNode.handle();
3194 if (oldUnder && oldUnder->isTextNode())
3195 oldUnder = oldUnder->parentNode();
3198 if (oldUnder != targetNode) {
3202 MouseEventImpl *me =
new MouseEventImpl(EventImpl::MOUSEOUT_EVENT,
3203 true,
true,m_part->xmlDocImpl()->defaultView(),
3204 0,screenX,screenY,clientX,clientY,pageX, pageY,
3205 ctrlKey,altKey,shiftKey,metaKey,
3208 oldUnder->dispatchEvent(me,exceptioncode,
true);
3214 MouseEventImpl *me =
new MouseEventImpl(EventImpl::MOUSEOVER_EVENT,
3215 true,
true,m_part->xmlDocImpl()->defaultView(),
3216 0,screenX,screenY,clientX,clientY,pageX, pageY,
3217 ctrlKey,altKey,shiftKey,metaKey,
3221 targetNode->dispatchEvent(me,exceptioncode,
true);
3230 bool swallowEvent =
false;
3234 bool dblclick = ( eventId == EventImpl::CLICK_EVENT &&
3235 _mouse->type() == TQEvent::MouseButtonDblClick );
3236 MouseEventImpl *me =
new MouseEventImpl(static_cast<EventImpl::EventId>(eventId),
3237 true,cancelable,m_part->xmlDocImpl()->defaultView(),
3238 detail,screenX,screenY,clientX,clientY,pageX, pageY,
3239 ctrlKey,altKey,shiftKey,metaKey,
3240 button,0, _mouse, dblclick );
3242 targetNode->dispatchEvent(me,exceptioncode,
true);
3243 bool defaultHandled = me->defaultHandled();
3244 if (defaultHandled || me->defaultPrevented())
3245 swallowEvent =
true;
3248 if (eventId == EventImpl::MOUSEDOWN_EVENT) {
3253 DOM::NodeImpl* nodeImpl = targetNode;
3254 for ( ; nodeImpl && !nodeImpl->isFocusable(); nodeImpl = nodeImpl->parentNode());
3255 if (nodeImpl && nodeImpl->isMouseFocusable())
3256 m_part->xmlDocImpl()->setFocusNode(nodeImpl);
3257 else if (!nodeImpl || !nodeImpl->focused())
3258 m_part->xmlDocImpl()->setFocusNode(0);
3262 return swallowEvent;
3265 void KHTMLView::setIgnoreWheelEvents(
bool e )
3267 d->ignoreWheelEvents = e;
3270 #ifndef QT_NO_WHEELEVENT
3272 void KHTMLView::viewportWheelEvent(TQWheelEvent* e)
3274 if (d->accessKeysEnabled && d->accessKeysPreActivate) d->accessKeysPreActivate=
false;
3276 if ( ( e->state() & ControlButton) == ControlButton )
3278 emit zoomView( - e->delta() );
3281 else if (d->firstRelayout)
3285 else if( ( (e->orientation() == Qt::Vertical &&
3286 ((d->ignoreWheelEvents && !verticalScrollBar()->isVisible())
3287 || e->delta() > 0 && contentsY() <= 0
3288 || e->delta() < 0 && contentsY() >= contentsHeight() - visibleHeight()))
3290 (e->orientation() == Qt::Horizontal &&
3291 ((d->ignoreWheelEvents && !horizontalScrollBar()->isVisible())
3292 || e->delta() > 0 && contentsX() <=0
3293 || e->delta() < 0 && contentsX() >= contentsWidth() - visibleWidth())))
3302 d->scrollBarMoved =
true;
3303 #ifndef NO_SMOOTH_SCROLL_HACK
3304 scrollViewWheelEvent( e );
3306 TQScrollView::viewportWheelEvent( e );
3309 TQMouseEvent *tempEvent =
new TQMouseEvent( TQEvent::MouseMove, TQPoint(-1,-1), TQPoint(-1,-1), Qt::NoButton, e->state() );
3310 emit viewportMouseMoveEvent ( tempEvent );
3317 void KHTMLView::dragEnterEvent( TQDragEnterEvent* ev )
3327 TQScrollView::dragEnterEvent( ev );
3330 void KHTMLView::dropEvent( TQDropEvent *ev )
3340 TQScrollView::dropEvent( ev );
3343 void KHTMLView::focusInEvent( TQFocusEvent *e )
3345 #ifndef KHTML_NO_TYPE_AHEAD_FIND
3346 m_part->enableFindAheadActions(
true );
3348 DOM::NodeImpl* fn = m_part->xmlDocImpl() ? m_part->xmlDocImpl()->focusNode() : 0;
3349 if (fn && fn->renderer() && fn->renderer()->isWidget() &&
3350 (e->reason() != TQFocusEvent::Mouse) &&
3351 static_cast<khtml::RenderWidget*>(fn->renderer())->widget())
3352 static_cast<khtml::RenderWidget*>(fn->renderer())->widget()->setFocus();
3353 #ifndef KHTML_NO_CARET
3356 if (d->m_caretViewContext &&
3357 d->m_caretViewContext->freqTimerId == -1 &&
3361 || (fn && fn->renderer()
3362 && fn->renderer()->style()->userInput()
3364 d->m_caretViewContext->freqTimerId = startTimer(500);
3365 d->m_caretViewContext->visible =
true;
3369 #endif // KHTML_NO_CARET
3370 TQScrollView::focusInEvent( e );
3373 void KHTMLView::focusOutEvent( TQFocusEvent *e )
3375 if(m_part) m_part->stopAutoScroll();
3377 #ifndef KHTML_NO_TYPE_AHEAD_FIND
3378 if(d->typeAheadActivated)
3382 m_part->enableFindAheadActions(
false );
3383 #endif // KHTML_NO_TYPE_AHEAD_FIND
3385 #ifndef KHTML_NO_CARET
3386 if (d->m_caretViewContext) {
3387 switch (d->m_caretViewContext->displayNonFocused) {
3388 case KHTMLPart::CaretInvisible:
3391 case KHTMLPart::CaretVisible: {
3392 killTimer(d->m_caretViewContext->freqTimerId);
3393 d->m_caretViewContext->freqTimerId = -1;
3394 NodeImpl *caretNode = m_part->xmlDocImpl()->focusNode();
3395 if (!d->m_caretViewContext->visible && (m_part->
isCaretMode()
3397 || (caretNode && caretNode->renderer()
3398 && caretNode->renderer()->style()->userInput()
3400 d->m_caretViewContext->visible =
true;
3405 case KHTMLPart::CaretBlink:
3410 #endif // KHTML_NO_CARET
3412 if ( d->cursor_icon_widget )
3413 d->cursor_icon_widget->hide();
3415 TQScrollView::focusOutEvent( e );
3418 void KHTMLView::slotScrollBarMoved()
3420 if ( !d->firstRelayout && !d->complete && m_part->xmlDocImpl() &&
3421 d->layoutSchedulingEnabled) {
3423 khtml::RenderCanvas* root =
static_cast<khtml::RenderCanvas *
>( m_part->xmlDocImpl()->renderer() );
3424 if (root && root->needsLayout()) {
3425 unscheduleRelayout();
3429 if (!d->scrollingSelf) {
3430 d->scrollBarMoved =
true;
3431 d->contentsMoving =
true;
3433 scheduleRepaint(0, 0, 0, 0);
3436 if (m_part->xmlDocImpl() && m_part->xmlDocImpl()->documentElement())
3437 m_part->xmlDocImpl()->documentElement()->dispatchHTMLEvent(EventImpl::SCROLL_EVENT,
true,
false);
3440 void KHTMLView::timerEvent ( TQTimerEvent *e )
3443 if ( e->timerId() == d->scrollTimerId ) {
3444 if( d->scrollSuspended )
3446 switch (d->scrollDirection) {
3447 case KHTMLViewPrivate::ScrollDown:
3448 if (contentsY() + visibleHeight () >= contentsHeight())
3449 d->newScrollTimer(
this, 0);
3451 scrollBy( 0, d->scrollBy );
3453 case KHTMLViewPrivate::ScrollUp:
3454 if (contentsY() <= 0)
3455 d->newScrollTimer(
this, 0);
3457 scrollBy( 0, -d->scrollBy );
3459 case KHTMLViewPrivate::ScrollRight:
3460 if (contentsX() + visibleWidth () >= contentsWidth())
3461 d->newScrollTimer(
this, 0);
3463 scrollBy( d->scrollBy, 0 );
3465 case KHTMLViewPrivate::ScrollLeft:
3466 if (contentsX() <= 0)
3467 d->newScrollTimer(
this, 0);
3469 scrollBy( -d->scrollBy, 0 );
3474 else if ( e->timerId() == d->layoutTimerId ) {
3475 d->dirtyLayout =
true;
3477 if (d->firstRelayout) {
3478 d->firstRelayout =
false;
3479 verticalScrollBar()->setEnabled(
true );
3480 horizontalScrollBar()->setEnabled(
true );
3483 #ifndef KHTML_NO_CARET
3484 else if (d->m_caretViewContext
3485 && e->timerId() == d->m_caretViewContext->freqTimerId) {
3486 d->m_caretViewContext->visible = !d->m_caretViewContext->visible;
3487 if (d->m_caretViewContext->displayed) {
3488 updateContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
3489 d->m_caretViewContext->width,
3490 d->m_caretViewContext->height);
3498 d->contentsMoving =
false;
3499 if( m_part->xmlDocImpl() ) {
3500 DOM::DocumentImpl *document = m_part->xmlDocImpl();
3501 khtml::RenderCanvas* root =
static_cast<khtml::RenderCanvas *
>(document->renderer());
3503 if ( root && root->needsLayout() ) {
3504 killTimer(d->repaintTimerId);
3505 d->repaintTimerId = 0;
3511 setStaticBackground(d->useSlowRepaints);
3514 killTimer(d->repaintTimerId);
3515 d->repaintTimerId = 0;
3517 TQRect updateRegion;
3518 TQMemArray<TQRect> rects = d->updateRegion.rects();
3520 d->updateRegion = TQRegion();
3523 updateRegion = rects[0];
3525 for (
unsigned i = 1; i < rects.size(); ++i ) {
3526 TQRect newRegion = updateRegion.unite(rects[i]);
3527 if (2*newRegion.height() > 3*updateRegion.height() )
3529 repaintContents( updateRegion );
3530 updateRegion = rects[i];
3533 updateRegion = newRegion;
3536 if ( !updateRegion.isNull() )
3537 repaintContents( updateRegion );
3544 if (d->dirtyLayout && !d->visibleWidgets.isEmpty()) {
3546 d->dirtyLayout =
false;
3548 TQRect visibleRect(contentsX(), contentsY(), visibleWidth(), visibleHeight());
3549 TQPtrList<RenderWidget> toRemove;
3550 for (TQPtrDictIterator<TQWidget> it(d->visibleWidgets); it.current(); ++it) {
3553 RenderWidget* rw =
static_cast<RenderWidget*
>( it.currentKey() );
3554 if (!rw->absolutePosition(xp, yp) ||
3555 !visibleRect.intersects(TQRect(xp, yp, w->width(), w->height())))
3556 toRemove.append(rw);
3558 for (RenderWidget* r = toRemove.first(); r; r = toRemove.next())
3559 if ( (w = d->visibleWidgets.take(r) ) )
3560 addChild(w, 0, -500000);
3563 emit repaintAccessKeys();
3564 if (d->emitCompletedAfterRepaint) {
3565 bool full = d->emitCompletedAfterRepaint == KHTMLViewPrivate::CSFull;
3566 d->emitCompletedAfterRepaint = KHTMLViewPrivate::CSNone;
3574 void KHTMLView::scheduleRelayout(khtml::RenderObject * )
3576 if (!d->layoutSchedulingEnabled || d->layoutTimerId)
3579 d->layoutTimerId = startTimer( m_part->xmlDocImpl() && m_part->xmlDocImpl()->parsing()
3583 void KHTMLView::unscheduleRelayout()
3585 if (!d->layoutTimerId)
3588 killTimer(d->layoutTimerId);
3589 d->layoutTimerId = 0;
3592 void KHTMLView::unscheduleRepaint()
3594 if (!d->repaintTimerId)
3597 killTimer(d->repaintTimerId);
3598 d->repaintTimerId = 0;
3601 void KHTMLView::scheduleRepaint(
int x,
int y,
int w,
int h,
bool asap)
3603 bool parsing = !m_part->xmlDocImpl() || m_part->xmlDocImpl()->parsing();
3608 int time = parsing ? 300 : (!asap ? ( !d->complete ? 100 : 20 ) : 0);
3610 #ifdef DEBUG_FLICKER
3612 p.begin( viewport() );
3615 contentsToViewport( x, y, vx, vy );
3616 p.fillRect( vx, vy, w, h, TQt::red );
3620 d->updateRegion = d->updateRegion.unite(TQRect(x,y,w,h));
3622 if (asap && !parsing)
3623 unscheduleRepaint();
3625 if ( !d->repaintTimerId )
3626 d->repaintTimerId = startTimer( time );
3631 void KHTMLView::complete(
bool pendingAction )
3638 if (d->layoutTimerId)
3642 killTimer(d->layoutTimerId);
3643 d->layoutTimerId = startTimer( 0 );
3644 d->emitCompletedAfterRepaint = pendingAction ?
3645 KHTMLViewPrivate::CSActionPending : KHTMLViewPrivate::CSFull;
3649 if (d->repaintTimerId)
3653 killTimer(d->repaintTimerId);
3654 d->repaintTimerId = startTimer( 20 );
3655 d->emitCompletedAfterRepaint = pendingAction ?
3656 KHTMLViewPrivate::CSActionPending : KHTMLViewPrivate::CSFull;
3659 if (!d->emitCompletedAfterRepaint)
3669 void KHTMLView::slotMouseScrollTimer()
3671 scrollBy( d->m_mouseScroll_byX, d->m_mouseScroll_byY );
3674 #ifndef KHTML_NO_CARET
3679 #include "khtml_caret.cpp"
3681 void KHTMLView::initCaret(
bool keepSelection)
3683 #if DEBUG_CARETMODE > 0
3687 if (m_part->xmlDocImpl()) {
3689 ElementImpl *listitem = m_part->xmlDocImpl()->getElementById(
"__test_element__");
3690 if (listitem) dumpLineBoxes(static_cast<RenderFlow *>(listitem->renderer()));
3692 d->caretViewContext();
3693 bool cmoved = d->m_caretViewContext->caretMoved;
3694 if (m_part->d->caretNode().isNull()) {
3696 m_part->d->caretNode() = m_part->
document();
3697 m_part->d->caretOffset() = 0L;
3701 if (!m_part->d->caretNode().handle()->renderer())
return;
3706 moveCaretTo(m_part->d->caretNode().handle(), m_part->d->caretOffset(), !keepSelection);
3709 d->m_caretViewContext->caretMoved = cmoved;
3711 #if DEBUG_CARETMODE > 0
3716 bool KHTMLView::caretOverrides()
const
3720 return cm && !dm ?
false
3721 : (dm || m_part->d->caretNode().handle()->contentEditable())
3722 && d->editorContext()->override;
3725 void KHTMLView::ensureNodeHasFocus(NodeImpl *node)
3728 if (node->focused())
return;
3731 NodeImpl *firstAncestor = 0;
3733 if (node->renderer()
3734 && node->renderer()->style()->userInput() != UI_ENABLED)
3736 firstAncestor = node;
3737 node = node->parentNode();
3740 if (!node) firstAncestor = 0;
3742 DocumentImpl *doc = m_part->xmlDocImpl();
3744 if (!firstAncestor && doc->focusNode() && doc->focusNode()->renderer()
3745 && doc->focusNode()->renderer()->isWidget())
3749 #if DEBUG_CARETMODE > 1
3751 << (firstAncestor ? firstAncestor->nodeName().string() : TQString::null) << endl;
3753 doc->setFocusNode(firstAncestor);
3757 void KHTMLView::recalcAndStoreCaretPos(CaretBox *hintBox)
3759 if (!m_part || m_part->d->caretNode().isNull())
return;
3760 d->caretViewContext();
3761 NodeImpl *caretNode = m_part->d->caretNode().handle();
3762 #if DEBUG_CARETMODE > 0
3763 kdDebug(6200) <<
"recalcAndStoreCaretPos: caretNode=" << caretNode << (caretNode ?
" "+caretNode->nodeName().string() : TQString::null) <<
" r@" << caretNode->renderer() << (caretNode->renderer() && caretNode->renderer()->isText() ?
" \"" + TQConstString(static_cast<RenderText *>(caretNode->renderer())->str->s, kMin(static_cast<RenderText *>(caretNode->renderer())->str->l, 15u)).
string() +
"\"" : TQString::null) << endl;
3765 caretNode->getCaret(m_part->d->caretOffset(), caretOverrides(),
3766 d->m_caretViewContext->x, d->m_caretViewContext->y,
3767 d->m_caretViewContext->width,
3768 d->m_caretViewContext->height);
3770 if (hintBox && d->m_caretViewContext->x == -1) {
3771 #if DEBUG_CARETMODE > 1
3772 kdDebug(6200) <<
"using hint inline box coordinates" <<
endl;
3774 RenderObject *r = caretNode->renderer();
3775 const TQFontMetrics &fm = r->style()->fontMetrics();
3777 r->containingBlock()->absolutePosition(absx, absy,
3779 d->m_caretViewContext->x = absx + hintBox->xPos();
3780 d->m_caretViewContext->y = absy + hintBox->yPos();
3782 d->m_caretViewContext->width = 1;
3785 d->m_caretViewContext->height = fm.height();
3788 #if DEBUG_CARETMODE > 4
3791 #if DEBUG_CARETMODE > 0
3792 kdDebug(6200) <<
"caret: ofs="<<m_part->d->caretOffset()<<
" "
3793 <<
" x="<<d->m_caretViewContext->x<<
" y="<<d->m_caretViewContext->y
3794 <<
" h="<<d->m_caretViewContext->height<<
endl;
3798 void KHTMLView::caretOn()
3800 if (d->m_caretViewContext) {
3801 killTimer(d->m_caretViewContext->freqTimerId);
3803 if (hasFocus() || d->m_caretViewContext->displayNonFocused
3804 == KHTMLPart::CaretBlink) {
3805 d->m_caretViewContext->freqTimerId = startTimer(500);
3807 d->m_caretViewContext->freqTimerId = -1;
3810 d->m_caretViewContext->visible =
true;
3811 if ((d->m_caretViewContext->displayed = (hasFocus()
3812 || d->m_caretViewContext->displayNonFocused
3813 != KHTMLPart::CaretInvisible))) {
3814 updateContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
3815 d->m_caretViewContext->width,
3816 d->m_caretViewContext->height);
3822 void KHTMLView::caretOff()
3824 if (d->m_caretViewContext) {
3825 killTimer(d->m_caretViewContext->freqTimerId);
3826 d->m_caretViewContext->freqTimerId = -1;
3827 d->m_caretViewContext->displayed =
false;
3828 if (d->m_caretViewContext->visible) {
3829 d->m_caretViewContext->visible =
false;
3830 updateContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
3831 d->m_caretViewContext->width,
3832 d->m_caretViewContext->height);
3838 void KHTMLView::showCaret(
bool forceRepaint)
3840 if (d->m_caretViewContext) {
3841 d->m_caretViewContext->displayed =
true;
3842 if (d->m_caretViewContext->visible) {
3843 if (!forceRepaint) {
3844 updateContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
3845 d->m_caretViewContext->width,
3846 d->m_caretViewContext->height);
3848 repaintContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
3849 d->m_caretViewContext->width,
3850 d->m_caretViewContext->height);
3857 bool KHTMLView::foldSelectionToCaret(NodeImpl *startNode,
long startOffset,
3858 NodeImpl *endNode,
long endOffset)
3860 m_part->d->m_selectionStart = m_part->d->m_selectionEnd = m_part->d->caretNode();
3861 m_part->d->m_startOffset = m_part->d->m_endOffset = m_part->d->caretOffset();
3862 m_part->d->m_extendAtEnd =
true;
3864 bool folded = startNode != endNode || startOffset != endOffset;
3868 m_part->xmlDocImpl()->clearSelection();
3874 void KHTMLView::hideCaret()
3876 if (d->m_caretViewContext) {
3877 if (d->m_caretViewContext->visible) {
3879 d->m_caretViewContext->visible =
false;
3882 repaintContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
3883 d->m_caretViewContext->width,
3884 d->m_caretViewContext->height);
3885 d->m_caretViewContext->visible =
true;
3887 d->m_caretViewContext->displayed =
false;
3892 int KHTMLView::caretDisplayPolicyNonFocused()
const
3894 if (d->m_caretViewContext)
3895 return d->m_caretViewContext->displayNonFocused;
3897 return KHTMLPart::CaretInvisible;
3900 void KHTMLView::setCaretDisplayPolicyNonFocused(
int policy)
3902 d->caretViewContext();
3908 switch (d->m_caretViewContext->displayNonFocused) {
3909 case KHTMLPart::CaretInvisible:
3912 case KHTMLPart::CaretBlink:
3913 if (d->m_caretViewContext->freqTimerId != -1)
break;
3914 d->m_caretViewContext->freqTimerId = startTimer(500);
3916 case KHTMLPart::CaretVisible:
3917 d->m_caretViewContext->displayed =
true;
3924 bool KHTMLView::placeCaret(CaretBox *hintBox)
3926 CaretViewContext *cv = d->caretViewContext();
3928 NodeImpl *caretNode = m_part->d->caretNode().handle();
3930 if (!caretNode || !caretNode->renderer())
return false;
3931 ensureNodeHasFocus(caretNode);
3933 || caretNode->renderer()->style()->userInput() == UI_ENABLED) {
3934 recalcAndStoreCaretPos(hintBox);
3944 void KHTMLView::ensureCaretVisible()
3946 CaretViewContext *cv = d->m_caretViewContext;
3948 ensureVisible(cv->x, cv->y, cv->width, cv->height);
3949 d->scrollBarMoved =
false;
3952 bool KHTMLView::extendSelection(NodeImpl *oldStartSel,
long oldStartOfs,
3953 NodeImpl *oldEndSel,
long oldEndOfs)
3955 bool changed =
false;
3956 if (m_part->d->m_selectionStart == m_part->d->m_selectionEnd
3957 && m_part->d->m_startOffset == m_part->d->m_endOffset) {
3958 changed = foldSelectionToCaret(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs);
3959 m_part->d->m_extendAtEnd =
true;
3961 changed = m_part->d->m_selectionStart.handle() != oldStartSel
3962 || m_part->d->m_startOffset != oldStartOfs
3963 || m_part->d->m_selectionEnd.handle() != oldEndSel
3964 || m_part->d->m_endOffset != oldEndOfs;
3965 if (!changed)
break;
3968 NodeImpl *startNode;
3970 if (m_part->d->m_extendAtEnd) {
3971 startNode = m_part->d->m_selectionStart.handle();
3972 startOffset = m_part->d->m_startOffset;
3974 startNode = m_part->d->m_selectionEnd.handle();
3975 startOffset = m_part->d->m_endOffset;
3976 m_part->d->m_selectionEnd = m_part->d->m_selectionStart;
3977 m_part->d->m_endOffset = m_part->d->m_startOffset;
3978 m_part->d->m_extendAtEnd =
true;
3981 bool swapNeeded =
false;
3982 if (!m_part->d->m_selectionEnd.isNull() && startNode) {
3983 swapNeeded = RangeImpl::compareBoundaryPoints(startNode, startOffset,
3984 m_part->d->m_selectionEnd.handle(),
3985 m_part->d->m_endOffset) >= 0;
3988 m_part->d->m_selectionStart = startNode;
3989 m_part->d->m_startOffset = startOffset;
3992 m_part->xmlDocImpl()->setSelection(m_part->d->m_selectionEnd.handle(),
3993 m_part->d->m_endOffset, m_part->d->m_selectionStart.handle(),
3994 m_part->d->m_startOffset);
3996 m_part->xmlDocImpl()->setSelection(m_part->d->m_selectionStart.handle(),
3997 m_part->d->m_startOffset, m_part->d->m_selectionEnd.handle(),
3998 m_part->d->m_endOffset);
4004 void KHTMLView::updateSelection(NodeImpl *oldStartSel,
long oldStartOfs,
4005 NodeImpl *oldEndSel,
long oldEndOfs)
4007 if (m_part->d->m_selectionStart == m_part->d->m_selectionEnd
4008 && m_part->d->m_startOffset == m_part->d->m_endOffset) {
4009 if (foldSelectionToCaret(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs)) {
4010 m_part->emitSelectionChanged();
4012 m_part->d->m_extendAtEnd =
true;
4015 if (!m_part->d->m_selectionEnd.isNull() && !m_part->d->m_selectionEnd.isNull()) {
4016 bool swapNeeded = RangeImpl::compareBoundaryPoints(
4017 m_part->d->m_selectionStart.handle(), m_part->d->m_startOffset,
4018 m_part->d->m_selectionEnd.handle(), m_part->d->m_endOffset) >= 0;
4020 DOM::Node tmpNode = m_part->d->m_selectionStart;
4021 long tmpOffset = m_part->d->m_startOffset;
4022 m_part->d->m_selectionStart = m_part->d->m_selectionEnd;
4023 m_part->d->m_startOffset = m_part->d->m_endOffset;
4024 m_part->d->m_selectionEnd = tmpNode;
4025 m_part->d->m_endOffset = tmpOffset;
4026 m_part->d->m_startBeforeEnd =
true;
4027 m_part->d->m_extendAtEnd = !m_part->d->m_extendAtEnd;
4031 m_part->xmlDocImpl()->setSelection(m_part->d->m_selectionStart.handle(),
4032 m_part->d->m_startOffset, m_part->d->m_selectionEnd.handle(),
4033 m_part->d->m_endOffset);
4034 m_part->emitSelectionChanged();
4038 void KHTMLView::caretKeyPressEvent(TQKeyEvent *_ke)
4040 NodeImpl *oldStartSel = m_part->d->m_selectionStart.handle();
4041 long oldStartOfs = m_part->d->m_startOffset;
4042 NodeImpl *oldEndSel = m_part->d->m_selectionEnd.handle();
4043 long oldEndOfs = m_part->d->m_endOffset;
4045 NodeImpl *oldCaretNode = m_part->d->caretNode().handle();
4046 long oldOffset = m_part->d->caretOffset();
4048 bool ctrl = _ke->state() & ControlButton;
4051 switch(_ke->key()) {
4056 moveCaretNextLine(1);
4060 moveCaretPrevLine(1);
4064 moveCaretBy(
false, ctrl ? CaretByWord : CaretByCharacter, 1);
4068 moveCaretBy(
true, ctrl ? CaretByWord : CaretByCharacter, 1);
4072 moveCaretNextPage();
4076 moveCaretPrevPage();
4081 moveCaretToDocumentBoundary(
false);
4083 moveCaretToLineBegin();
4088 moveCaretToDocumentBoundary(
true);
4090 moveCaretToLineEnd();
4095 if ((m_part->d->caretNode().handle() != oldCaretNode
4096 || m_part->d->caretOffset() != oldOffset)
4098 && !m_part->d->caretNode().isNull()) {
4100 d->m_caretViewContext->caretMoved =
true;
4102 if (_ke->state() & ShiftButton) {
4103 updateSelection(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs);
4105 if (foldSelectionToCaret(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs))
4106 m_part->emitSelectionChanged();
4109 m_part->emitCaretPositionChanged(m_part->d->caretNode(), m_part->d->caretOffset());
4115 bool KHTMLView::moveCaretTo(NodeImpl *node,
long offset,
bool clearSel)
4117 if (!node)
return false;
4118 ElementImpl *baseElem = determineBaseElement(node);
4119 RenderFlow *base =
static_cast<RenderFlow *
>(baseElem ? baseElem->renderer() : 0);
4120 if (!node)
return false;
4125 CaretBoxLineDeleter cblDeleter;
4128 CaretBoxIterator cbit;
4129 CaretBoxLine *cbl = findCaretBoxLine(node, offset, &cblDeleter, base, r_ofs, cbit);
4131 kdWarning() <<
"KHTMLView::moveCaretTo - findCaretBoxLine() returns NULL" <<
endl;
4135 #if DEBUG_CARETMODE > 3
4136 if (cbl)
kdDebug(6200) << cbl->information() <<
endl;
4138 CaretBox *box = *cbit;
4139 if (cbit != cbl->end() && box->object() != node->renderer()) {
4140 if (box->object()->element()) {
4141 mapRenderPosToDOMPos(box->object(), r_ofs, box->isOutside(),
4142 box->isOutsideEnd(), node, offset);
4144 #if DEBUG_CARETMODE > 1
4145 kdDebug(6200) <<
"set new node " << node->nodeName().string() <<
"@" << node <<
endl;
4150 kdError(6200) <<
"Box contains no node! Crash imminent" <<
endl;
4154 NodeImpl *oldStartSel = m_part->d->m_selectionStart.handle();
4155 long oldStartOfs = m_part->d->m_startOffset;
4156 NodeImpl *oldEndSel = m_part->d->m_selectionEnd.handle();
4157 long oldEndOfs = m_part->d->m_endOffset;
4160 bool posChanged = m_part->d->caretNode().handle() != node
4161 || m_part->d->caretOffset() != offset;
4162 bool selChanged =
false;
4164 m_part->d->caretNode() = node;
4165 m_part->d->caretOffset() = offset;
4166 if (clearSel || !oldStartSel || !oldEndSel) {
4167 selChanged = foldSelectionToCaret(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs);
4171 selChanged = extendSelection(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs);
4176 d->caretViewContext()->caretMoved =
true;
4178 bool visible_caret = placeCaret(box);
4184 m_part->emitCaretPositionChanged(visible_caret ? node : 0, offset);
4190 void KHTMLView::moveCaretByLine(
bool next,
int count)
4192 Node &caretNodeRef = m_part->d->caretNode();
4193 if (caretNodeRef.
isNull())
return;
4195 NodeImpl *caretNode = caretNodeRef.handle();
4197 long offset = m_part->d->caretOffset();
4199 CaretViewContext *cv = d->caretViewContext();
4201 ElementImpl *baseElem = determineBaseElement(caretNode);
4202 LinearDocument ld(m_part, caretNode, offset, LeafsOnly, baseElem);
4204 ErgonomicEditableLineIterator it(ld.current(), cv->origX);
4207 while (count > 0 && it != ld.end() && it != ld.preBegin()) {
4209 if (next) ++it;
else --it;
4213 if (it == ld.end() || it == ld.preBegin())
return;
4216 CaretBox *caretBox = nearestCaretBox(it, d->m_caretViewContext, x, absx, absy);
4218 placeCaretOnLine(caretBox, x, absx, absy);
4221 void KHTMLView::placeCaretOnLine(CaretBox *caretBox,
int x,
int absx,
int absy)
4224 if (!caretBox)
return;
4226 RenderObject *caretRender = caretBox->object();
4228 #if DEBUG_CARETMODE > 0
4229 kdDebug(6200) <<
"got valid caretBox " << caretBox <<
endl;
4230 kdDebug(6200) <<
"xPos: " << caretBox->xPos() <<
" yPos: " << caretBox->yPos()
4231 <<
" width: " << caretBox->width() <<
" height: " << caretBox->height() <<
endl;
4232 InlineTextBox *tb =
static_cast<InlineTextBox *
>(caretBox->inlineBox());
4233 if (caretBox->isInlineTextBox()) {
kdDebug(6200) <<
"contains \"" << TQString(static_cast<RenderText *>(tb->object())->str->s + tb->m_start, tb->m_len) <<
"\"" <<
endl;}
4236 int caretHeight = caretBox->height();
4237 bool isText = caretBox->isInlineTextBox();
4241 RenderText *t =
static_cast<RenderText *
>(caretRender);
4242 const TQFontMetrics &fm = t->metrics(caretBox->inlineBox()->m_firstLine);
4243 caretHeight = fm.height();
4244 yOfs = caretBox->inlineBox()->baseline() - fm.ascent();
4250 NodeImpl *caretNode;
4251 long &offset = m_part->d->caretOffset();
4252 mapRenderPosToDOMPos(caretRender, offset, caretBox->isOutside(),
4253 caretBox->isOutsideEnd(), caretNode, offset);
4256 d->m_caretViewContext->y = caretBox->yPos() + yOfs;
4257 d->m_caretViewContext->height = caretHeight;
4258 d->m_caretViewContext->width = 1;
4260 int xPos = caretBox->xPos();
4261 int caretBoxWidth = caretBox->width();
4262 d->m_caretViewContext->x = xPos;
4264 if (!caretBox->isOutside()) {
4268 r_ofs = caretBox->minOffset();
4270 }
else if (x > xPos && x <= xPos + caretBoxWidth) {
4272 r_ofs =
static_cast<InlineTextBox *
>(caretBox->inlineBox())
4273 ->offsetForPoint(x, d->m_caretViewContext->x);
4274 #if DEBUG_CARETMODE > 2
4275 kdDebug(6200) <<
"deviation from origX " << d->m_caretViewContext->x - x <<
endl;
4279 if (xPos + caretBoxWidth - x < x - xPos) {
4280 d->m_caretViewContext->x = xPos + caretBoxWidth;
4281 r_ofs = caretNode ? caretNode->maxOffset() : 1;
4283 d->m_caretViewContext->x = xPos;
4284 r_ofs = caretNode ? caretNode->minOffset() : 0;
4289 d->m_caretViewContext->x = xPos + caretBoxWidth;
4290 r_ofs = caretBox->maxOffset();
4294 #if DEBUG_CARETMODE > 0
4295 kdDebug(6200) <<
"new offset: " << offset <<
endl;
4298 m_part->d->caretNode() = caretNode;
4299 m_part->d->caretOffset() = offset;
4301 d->m_caretViewContext->x += absx;
4302 d->m_caretViewContext->y += absy;
4304 #if DEBUG_CARETMODE > 1
4305 kdDebug(6200) <<
"new caret position: x " << d->m_caretViewContext->x <<
" y " << d->m_caretViewContext->y <<
" w " << d->m_caretViewContext->width <<
" h " << d->m_caretViewContext->height <<
" absx " << absx <<
" absy " << absy <<
endl;
4308 ensureVisible(d->m_caretViewContext->x, d->m_caretViewContext->y,
4309 d->m_caretViewContext->width, d->m_caretViewContext->height);
4310 d->scrollBarMoved =
false;
4312 ensureNodeHasFocus(caretNode);
4316 void KHTMLView::moveCaretToLineBoundary(
bool end)
4318 Node &caretNodeRef = m_part->d->caretNode();
4319 if (caretNodeRef.
isNull())
return;
4321 NodeImpl *caretNode = caretNodeRef.handle();
4323 long offset = m_part->d->caretOffset();
4325 ElementImpl *baseElem = determineBaseElement(caretNode);
4326 LinearDocument ld(m_part, caretNode, offset, LeafsOnly, baseElem);
4328 EditableLineIterator it = ld.current();
4329 if (it == ld.end())
return;
4331 EditableCaretBoxIterator fbit(it, end);
4332 Q_ASSERT(fbit != (*it)->end() && fbit != (*it)->preBegin());
4333 CaretBox *b = *fbit;
4335 RenderObject *cb = b->containingBlock();
4338 if (cb) cb->absolutePosition(absx,absy);
4339 else absx = absy = 0;
4341 int x = b->xPos() + (end && !b->isOutside() ? b->width() : 0);
4342 d->m_caretViewContext->origX = absx + x;
4343 placeCaretOnLine(b, x, absx, absy);
4346 void KHTMLView::moveCaretToDocumentBoundary(
bool end)
4348 Node &caretNodeRef = m_part->d->caretNode();
4349 if (caretNodeRef.
isNull())
return;
4351 NodeImpl *caretNode = caretNodeRef.handle();
4353 long offset = m_part->d->caretOffset();
4355 ElementImpl *baseElem = determineBaseElement(caretNode);
4356 LinearDocument ld(m_part, caretNode, offset, IndicatedFlows, baseElem);
4358 EditableLineIterator it(end ? ld.preEnd() : ld.begin(), end);
4359 if (it == ld.end() || it == ld.preBegin())
return;
4361 EditableCaretBoxIterator fbit = it;
4362 Q_ASSERT(fbit != (*it)->end() && fbit != (*it)->preBegin());
4363 CaretBox *b = *fbit;
4365 RenderObject *cb = (*it)->containingBlock();
4368 if (cb) cb->absolutePosition(absx, absy);
4369 else absx = absy = 0;
4372 d->m_caretViewContext->origX = absx + x;
4373 placeCaretOnLine(b, x, absx, absy);
4376 void KHTMLView::moveCaretBy(
bool next, CaretMovement cmv,
int count)
4378 if (!m_part)
return;
4379 Node &caretNodeRef = m_part->d->caretNode();
4380 if (caretNodeRef.
isNull())
return;
4382 NodeImpl *caretNode = caretNodeRef.handle();
4384 long &offset = m_part->d->caretOffset();
4386 ElementImpl *baseElem = determineBaseElement(caretNode);
4387 CaretAdvancePolicy advpol = cmv != CaretByWord ? IndicatedFlows : LeafsOnly;
4388 LinearDocument ld(m_part, caretNode, offset, advpol, baseElem);
4390 EditableCharacterIterator it(&ld);
4391 while (!it.isEnd() && count > 0) {
4393 if (cmv == CaretByCharacter) {
4396 }
else if (cmv == CaretByWord) {
4397 if (next) moveItToNextWord(it);
4398 else moveItToPrevWord(it);
4402 CaretBox *hintBox = 0;
4404 NodeImpl *node = caretNodeRef.handle();
4405 hintBox = it.caretBox();
4408 mapRenderPosToDOMPos(it.renderer(), it.offset(), hintBox->isOutside(),
4409 hintBox->isOutsideEnd(), node, offset);
4411 caretNodeRef = node;
4412 #if DEBUG_CARETMODE > 2
4413 kdDebug(6200) <<
"set by valid node " << node <<
" " << (node?node->nodeName().string():TQString::null) <<
" offset: " << offset << endl;
4416 offset = next ? caretNode->maxOffset() : caretNode->minOffset();
4417 #if DEBUG_CARETMODE > 0
4418 kdDebug(6200) <<
"set by INvalid node. offset: " << offset <<
endl;
4421 placeCaretOnChar(hintBox);
4424 void KHTMLView::placeCaretOnChar(CaretBox *hintBox)
4427 recalcAndStoreCaretPos(hintBox);
4428 ensureVisible(d->m_caretViewContext->x, d->m_caretViewContext->y,
4429 d->m_caretViewContext->width, d->m_caretViewContext->height);
4430 d->m_caretViewContext->origX = d->m_caretViewContext->x;
4431 d->scrollBarMoved =
false;
4432 #if DEBUG_CARETMODE > 3
4435 ensureNodeHasFocus(m_part->d->caretNode().handle());
4439 void KHTMLView::moveCaretByPage(
bool next)
4441 Node &caretNodeRef = m_part->d->caretNode();
4442 if (caretNodeRef.
isNull())
return;
4444 NodeImpl *caretNode = caretNodeRef.handle();
4446 long offset = m_part->d->caretOffset();
4448 int offs = (clipper()->height() < 30) ? clipper()->height() : 30;
4450 int mindist = clipper()->height() - offs;
4452 CaretViewContext *cv = d->caretViewContext();
4455 ElementImpl *baseElem = determineBaseElement(caretNode);
4456 LinearDocument ld(m_part, caretNode, offset, LeafsOnly, baseElem);
4458 ErgonomicEditableLineIterator it(ld.current(), cv->origX);
4460 moveIteratorByPage(ld, it, mindist, next);
4463 CaretBox *caretBox = nearestCaretBox(it, d->m_caretViewContext, x, absx, absy);
4465 placeCaretOnLine(caretBox, x, absx, absy);
4468 void KHTMLView::moveCaretPrevWord()
4470 moveCaretBy(
false, CaretByWord, 1);
4473 void KHTMLView::moveCaretNextWord()
4475 moveCaretBy(
true, CaretByWord, 1);
4478 void KHTMLView::moveCaretPrevLine(
int n)
4480 moveCaretByLine(
false, n);
4483 void KHTMLView::moveCaretNextLine(
int n)
4485 moveCaretByLine(
true, n);
4488 void KHTMLView::moveCaretPrevPage()
4490 moveCaretByPage(
false);
4493 void KHTMLView::moveCaretNextPage()
4495 moveCaretByPage(
true);
4498 void KHTMLView::moveCaretToLineBegin()
4500 moveCaretToLineBoundary(
false);
4503 void KHTMLView::moveCaretToLineEnd()
4505 moveCaretToLineBoundary(
true);
4508 #endif // KHTML_NO_CARET
4510 #ifndef NO_SMOOTH_SCROLL_HACK
4511 #define timer timer2
4514 static const int SCROLL_TIME = 240;
4516 static const int SCROLL_TICK = 20;
4518 void KHTMLView::scrollBy(
int dx,
int dy)
4521 if( !cfg.readBoolEntry(
"SmoothScrolling",
false )) {
4522 TQScrollView::scrollBy( dx, dy );
4526 int full_dx = d->dx + dx;
4527 int full_dy = d->dy + dy;
4533 int steps = SCROLL_TIME/SCROLL_TICK;
4535 ddx = (full_dx*16)/steps;
4536 ddy = (full_dy*16)/steps;
4539 if (ddx > 0 && ddx < 16) ddx = 16;
4540 if (ddy > 0 && ddy < 16) ddy = 16;
4541 if (ddx < 0 && ddx > -16) ddx = -16;
4542 if (ddy < 0 && ddy > -16) ddy = -16;
4549 if (!d->scrolling) {
4555 void KHTMLView::scrollTick() {
4556 if (d->dx == 0 && d->dy == 0) {
4561 int tddx = d->ddx + d->rdx;
4562 int tddy = d->ddy + d->rdy;
4564 int ddx = tddx / 16;
4565 int ddy = tddy / 16;
4569 if (d->dx > 0 && ddx > d->dx) ddx = d->dx;
4571 if (d->dx < 0 && ddx < d->dx) ddx = d->dx;
4573 if (d->dy > 0 && ddy > d->dy) ddy = d->dy;
4575 if (d->dy < 0 && ddy < d->dy) ddy = d->dy;
4582 TQScrollView::scrollBy(ddx, ddy);
4589 void KHTMLView::startScrolling()
4591 d->scrolling =
true;
4592 d->timer.start(SCROLL_TICK,
false);
4595 void KHTMLView::stopScrolling()
4599 d->scrolling =
false;
4603 void KHTMLView::scrollViewWheelEvent( TQWheelEvent *e )
4605 int pageStep = verticalScrollBar()->pageStep();
4606 int lineStep = verticalScrollBar()->lineStep();
4607 int step = TQMIN( TQApplication::wheelScrollLines()*lineStep, pageStep );
4608 if ( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) )
4611 if(e->orientation() == Qt::Horizontal)
4612 scrollBy(-((e->delta()*step)/120), 0);
4613 else if(e->orientation() == Qt::Vertical)
4614 scrollBy(0,-((e->delta()*step)/120));
4621 #endif // NO_SMOOTH_SCROLL_HACK
4623 #undef DEBUG_CARETMODE