31 #include "khtmlview.moc"
36 #include <qx11info_x11.h>
39 #include "html/html_documentimpl.h"
40 #include "html/html_inlineimpl.h"
41 #include "html/html_formimpl.h"
42 #include "html/htmltokenizer.h"
44 #include "rendering/render_arena.h"
45 #include "rendering/render_canvas.h"
46 #include "rendering/render_frames.h"
47 #include "rendering/render_replaced.h"
48 #include "rendering/render_form.h"
49 #include "rendering/render_layer.h"
50 #include "rendering/render_line.h"
51 #include "rendering/render_table.h"
53 #define protected public
54 #include "rendering/render_text.h"
56 #include "xml/dom2_eventsimpl.h"
57 #include "css/cssstyleselector.h"
58 #include "css/csshelper.h"
59 #include "misc/helper.h"
60 #include "misc/loader.h"
80 #include <QtGui/QBitmap>
81 #include <QtGui/QLabel>
82 #include <QtCore/QObject>
83 #include <QtGui/QPainter>
84 #include <QtCore/QHash>
85 #include <QtGui/QToolTip>
86 #include <QtCore/QString>
87 #include <QtGui/QTextDocument>
88 #include <QtCore/QTimer>
89 #include <QtCore/QAbstractEventDispatcher>
90 #include <QtCore/QVector>
91 #include <QtGui/QAbstractScrollArea>
92 #include <QtGui/QPrinter>
93 #include <QtGui/QPrintDialog>
101 #elif defined(Q_WS_WIN)
107 void dumpLineBoxes(RenderFlow *flow);
112 using namespace khtml;
133 class KHTMLViewPrivate {
137 enum PseudoFocusNodes {
143 enum StaticBackgroundState {
149 enum CompletedState {
156 : underMouse( 0 ), underMouseNonShared( 0 ), oldUnderMouse( 0 )
158 postponed_autorepeat = NULL;
159 scrollingFromWheelTimerId = 0;
163 vpolicy = Qt::ScrollBarAsNeeded;
164 hpolicy = Qt::ScrollBarAsNeeded;
166 prevScrollbarVisible =
true;
168 possibleTripleClick =
false;
169 emitCompletedAfterRepaint = CSNone;
170 cursorIconWidget = 0;
171 cursorIconType = KHTMLView::LINK_NORMAL;
172 m_mouseScrollTimer = 0;
173 m_mouseScrollIndicator = 0;
180 delete formCompletions;
181 delete postponed_autorepeat;
184 if (underMouseNonShared)
185 underMouseNonShared->deref();
187 oldUnderMouse->deref();
189 delete cursorIconWidget;
190 delete m_mouseScrollTimer;
191 delete m_mouseScrollIndicator;
198 if (underMouseNonShared)
199 underMouseNonShared->deref();
200 underMouseNonShared = 0;
202 oldUnderMouse->deref();
205 staticWidget = SBNone;
206 fixedObjectsCount = 0;
207 staticObjectsCount = 0;
208 tabMovePending =
false;
209 lastTabbingDirection =
true;
210 pseudoFocusNode = PFNone;
212 #ifndef KHTML_NO_SCROLLBARS
218 vpolicy = ScrollBarAlwaysOff;
219 hpolicy = ScrollBarAlwaysOff;
221 scrollBarMoved =
false;
222 contentsMoving =
false;
223 ignoreWheelEvents =
false;
224 scrollingFromWheel =
QPoint(-1,-1);
233 isDoubleClick =
false;
234 scrollingSelf =
false;
235 delete postponed_autorepeat;
236 postponed_autorepeat = NULL;
240 scrollSuspended =
false;
241 scrollSuspendPreActivate =
false;
242 smoothScrolling =
false;
243 smoothScrollModeIsDefault =
true;
244 shouldSmoothScroll =
false;
245 smoothScrollMissedDeadlines = 0;
248 firstLayoutPending =
true;
250 firstRepaintPending =
true;
252 needsFullRepaint =
true;
254 layoutSchedulingEnabled =
true;
257 layoutAttemptCounter = 0;
258 scheduledLayoutCounter = 0;
259 updateRegion = QRegion();
260 m_dialogsAllowed =
true;
261 accessKeysActivated =
false;
262 accessKeysPreActivate =
false;
269 KHTMLGlobal::deref();
271 emitCompletedAfterRepaint = CSNone;
272 m_mouseEventsTarget = 0;
275 void newScrollTimer(
QWidget *view,
int tid)
278 view->killTimer(scrollTimerId);
280 scrollSuspended =
false;
282 enum ScrollDirection { ScrollLeft, ScrollRight, ScrollUp, ScrollDown };
284 void adjustScroller(
QWidget *view, ScrollDirection direction, ScrollDirection oppositedir)
286 static const struct {
int msec, pixels; } timings [] = {
287 {320,1}, {224,1}, {160,1}, {112,1}, {80,1}, {56,1}, {40,1},
288 {28,1}, {20,1}, {20,2}, {20,3}, {20,4}, {20,6}, {20,8}, {0,0}
290 if (!scrollTimerId ||
291 (static_cast<int>(scrollDirection) != direction &&
292 (static_cast<int>(scrollDirection) != oppositedir || scrollSuspended))) {
294 scrollBy = timings[scrollTiming].pixels;
295 scrollDirection = direction;
296 newScrollTimer(view, view->startTimer(timings[scrollTiming].msec));
297 }
else if (scrollDirection == direction &&
298 timings[scrollTiming+1].msec && !scrollSuspended) {
299 scrollBy = timings[++scrollTiming].pixels;
300 newScrollTimer(view, view->startTimer(timings[scrollTiming].msec));
301 }
else if (scrollDirection == oppositedir) {
303 scrollBy = timings[--scrollTiming].pixels;
304 newScrollTimer(view, view->startTimer(timings[scrollTiming].msec));
307 scrollSuspended =
false;
310 bool haveZoom()
const {
return zoomLevel != 100; }
312 void startScrolling()
314 smoothScrolling =
true;
316 shouldSmoothScroll =
false;
321 smoothScrollTimer.stop();
325 smoothScrolling =
false;
326 shouldSmoothScroll =
false;
329 void updateContentsXY()
331 contentsX = QApplication::isRightToLeft() ?
332 view->horizontalScrollBar()->maximum()-view->horizontalScrollBar()->value() : view->horizontalScrollBar()->value();
333 contentsY = view->verticalScrollBar()->value();
335 void scrollAccessKeys(
int dx,
int dy)
337 QList<QLabel*> wl = qFindChildren<QLabel*>(view->widget(),
"KHTMLAccessKey");
339 w->move( w->pos() +
QPoint(dx, dy) );
342 void scrollExternalWidgets(
int dx,
int dy)
344 if (visibleWidgets.isEmpty())
347 QHashIterator<void*, QWidget*> it(visibleWidgets);
348 while (it.hasNext()) {
350 it.value()->move( it.value()->pos() +
QPoint(dx, dy) );
354 NodeImpl *underMouse;
355 NodeImpl *underMouseNonShared;
356 NodeImpl *oldUnderMouse;
360 bool tabMovePending:1;
361 bool lastTabbingDirection:1;
362 PseudoFocusNodes pseudoFocusNode:3;
363 bool scrollBarMoved:1;
364 bool contentsMoving:1;
366 Qt::ScrollBarPolicy vpolicy;
367 Qt::ScrollBarPolicy hpolicy;
368 bool prevScrollbarVisible:1;
370 bool ignoreWheelEvents:1;
371 StaticBackgroundState staticWidget: 3;
372 int staticObjectsCount;
373 int fixedObjectsCount;
376 int borderX, borderY;
381 int clickX, clickY, clickCount;
387 int contentsX, contentsY;
389 QKeyEvent* postponed_autorepeat;
395 ScrollDirection scrollDirection :3;
396 bool scrollSuspended :1;
397 bool scrollSuspendPreActivate :1;
399 bool smoothScrolling :1;
400 bool smoothScrollModeIsDefault :1;
401 bool shouldSmoothScroll :1;
404 bool firstLayoutPending :1;
406 bool firstRepaintPending :1;
408 bool layoutSchedulingEnabled :1;
409 bool needsFullRepaint :1;
411 bool possibleTripleClick :1;
413 bool m_dialogsAllowed :1;
414 short smoothScrollMissedDeadlines;
416 int layoutAttemptCounter;
417 int scheduledLayoutCounter;
418 QRegion updateRegion;
419 QTimer smoothScrollTimer;
420 QTime smoothScrollStopwatch;
421 QHash<void*, QWidget*> visibleWidgets;
422 bool accessKeysEnabled;
423 bool accessKeysActivated;
424 bool accessKeysPreActivate;
425 CompletedState emitCompletedAfterRepaint;
428 KHTMLView::LinkCursor cursorIconType;
431 short m_mouseScroll_byX;
432 short m_mouseScroll_byY;
433 QPoint scrollingFromWheel;
434 int scrollingFromWheelTimerId;
435 QTimer *m_mouseScrollTimer;
436 QWidget *m_mouseScrollIndicator;
437 QPointer<QWidget> m_mouseEventsTarget;
438 QStack<QRegion>* m_clipHolder;
442 #ifndef QT_NO_TOOLTIP
456 HTMLMapElementImpl* map;
457 if (img && img->document()->isHTMLDocument() &&
458 (map =
static_cast<HTMLDocumentImpl*
>(img->document())->getMap(img->imageMap()))) {
459 RenderObject::NodeInfo info(
true,
false);
460 RenderObject *rend = img->renderer();
462 if (!rend || !rend->absolutePosition(ax, ay))
465 bool inside = map->mapMouseEvent(p.x() - ax + scrollOfs.x(),
466 p.y() - ay + scrollOfs.y(), rend->contentWidth(),
467 rend->contentHeight(), info);
468 if (inside && info.URLElement()) {
469 HTMLAreaElementImpl *area =
static_cast<HTMLAreaElementImpl *
>(info.URLElement());
470 Q_ASSERT(area->id() == ID_AREA);
471 s = area->getAttribute(ATTR_TITLE).string();
472 QRegion reg = area->cachedRegion();
473 if (!s.isEmpty() && !reg.isEmpty()) {
474 r = reg.boundingRect();
485 switch ( e->type() ) {
486 case QEvent::ToolTip: {
487 QHelpEvent *he =
static_cast<QHelpEvent*
>(e);
490 DOM::NodeImpl *node =
d->underMouseNonShared;
493 if ( node->isElementNode() ) {
494 DOM::ElementImpl *e =
static_cast<DOM::ElementImpl*
>( node );
500 if (e->id() == ID_IMG && !e->getAttribute( ATTR_USEMAP ).isEmpty()) {
502 viewportToContents(
QPoint(0, 0)), p, r, s);
505 s = e->getAttribute( ATTR_TITLE ).string();
508 region |=
QRect( contentsToViewport( r.topLeft() ), r.size() );
509 if ( !s.isEmpty() ) {
510 QToolTip::showText( he->globalPos(),
511 Qt::convertFromPlainText( s, Qt::WhiteSpaceNormal ),
516 node = node->parentNode();
524 case QEvent::DragEnter:
525 case QEvent::DragMove:
526 case QEvent::DragLeave:
536 return QWidget::event(e);
537 case QEvent::StyleChange:
538 case QEvent::LayoutRequest: {
540 return QAbstractScrollArea::event(e);
542 case QEvent::PaletteChange:
543 slotPaletteChanged();
544 return QScrollArea::event(e);
546 return QScrollArea::event(e);
552 :
QScrollArea( parent ),
d( new KHTMLViewPrivate( this ) )
562 widget()->setMouseTracking(
true);
570 DOM::DocumentImpl *doc = m_part->xmlDocImpl();
583 void KHTMLView::init()
587 setFrameStyle(QFrame::NoFrame);
588 setFocusPolicy(Qt::StrongFocus);
589 viewport()->setFocusProxy(
this);
598 setAcceptDrops(
true);
600 setWidget(
new QWidget(
this) );
601 widget()->setAttribute( Qt::WA_NoSystemBackground );
607 widget()->setAttribute( Qt::WA_OpaquePaintEvent );
609 verticalScrollBar()->setCursor( Qt::ArrowCursor );
610 horizontalScrollBar()->setCursor( Qt::ArrowCursor );
612 connect(&d->smoothScrollTimer, SIGNAL(
timeout()),
this, SLOT(scrollTick()));
615 void KHTMLView::resizeContentsToViewport()
617 QSize s = viewport()->size();
625 if (d->accessKeysEnabled && d->accessKeysActivated)
627 viewport()->unsetCursor();
628 if ( d->cursorIconWidget )
629 d->cursorIconWidget->hide();
630 if (d->smoothScrolling)
633 QAbstractEventDispatcher::instance()->unregisterTimers(
this);
638 verticalScrollBar()->setEnabled(
false );
639 horizontalScrollBar()->setEnabled(
false );
653 void KHTMLView::setMouseEventsTarget(
QWidget* w )
655 d->m_mouseEventsTarget = w;
658 QWidget* KHTMLView::mouseEventsTarget()
const
660 return d->m_mouseEventsTarget;
663 void KHTMLView::setClipHolder( QStack<QRegion>* ch )
665 d->m_clipHolder = ch;
668 QStack<QRegion>* KHTMLView::clipHolder()
const
670 return d->m_clipHolder;
675 return widget() ? widget()->width() : 0;
680 return widget() ? widget()->height() : 0;
687 widget()->resize(w, h);
688 if (!widget()->isVisible())
704 if (
m_kwp->isRedirected()) {
706 if (RenderWidget* rw =
m_kwp->renderWidget()) {
707 int ret = rw->width()-rw->paddingLeft()-rw->paddingRight()-rw->borderLeft()-rw->borderRight();
708 if (verticalScrollBar()->isVisible()) {
709 ret -= verticalScrollBar()->sizeHint().width();
715 return viewport()->width();
720 if (
m_kwp->isRedirected()) {
722 if (RenderWidget* rw =
m_kwp->renderWidget()) {
723 int ret = rw->height()-rw->paddingBottom()-rw->paddingTop()-rw->borderTop()-rw->borderBottom();
724 if (horizontalScrollBar()->isVisible()) {
725 ret -= horizontalScrollBar()->sizeHint().height();
731 return viewport()->height();
736 horizontalScrollBar()->setValue( QApplication::isRightToLeft() ?
737 horizontalScrollBar()->maximum()-x : x );
738 verticalScrollBar()->setValue( y );
743 if (d->scrollTimerId)
744 d->newScrollTimer(
this, 0);
745 horizontalScrollBar()->setValue( horizontalScrollBar()->value()+x );
746 verticalScrollBar()->setValue( verticalScrollBar()->value()+y );
777 applyTransforms(x, y, w, h);
778 if (
m_kwp->isRedirected()) {
783 widget()->update(x, y, w, h);
793 applyTransforms(x, y, w, h);
794 if (
m_kwp->isRedirected()) {
799 widget()->repaint(x, y, w, h);
807 void KHTMLView::applyTransforms(
int& x,
int& y,
int& w,
int& h)
const
810 const int z = d->zoomLevel;
820 void KHTMLView::revertTransforms(
int& x,
int& y,
int& w,
int& h)
const
825 const int z = d->zoomLevel;
833 void KHTMLView::revertTransforms(
int& x,
int& y )
const
836 revertTransforms(x, y, dummy, dummy);
844 if (!m_part->xmlDocImpl())
845 resizeContentsToViewport();
848 if (m_part->xmlDocImpl() && m_part->xmlDocImpl()->styleSelector()->affectedByViewportChange()) {
849 m_part->xmlDocImpl()->updateStyleSelector();
852 if (d->layoutSchedulingEnabled)
855 QApplication::sendPostedEvents(viewport(), QEvent::Paint);
857 if ( m_part && m_part->xmlDocImpl() ) {
865 HTMLPartContainerElementImpl::sendPostedResizeEvents();
866 m_part->xmlDocImpl()->dispatchWindowEvent( EventImpl::RESIZE_EVENT,
false,
false );
878 if (!r.isValid() || r.isEmpty())
return;
880 QPainter p(widget());
884 p.scale( d->zoomLevel/100., d->zoomLevel/100.);
886 r.setX(r.x()*100/d->zoomLevel);
887 r.setY(r.y()*100/d->zoomLevel);
888 r.setWidth(r.width()*100/d->zoomLevel);
889 r.setHeight(r.height()*100/d->zoomLevel);
899 if(!m_part || !m_part->xmlDocImpl() || !m_part->xmlDocImpl()->renderer()) {
900 p.fillRect(ex, ey, ew, eh, palette().brush(QPalette::Active, QPalette::Base));
902 }
else if ( d->complete && static_cast<RenderCanvas*>(m_part->xmlDocImpl()->renderer())->needsLayout() ) {
904 unscheduleRelayout();
906 }
else if (m_part->xmlDocImpl()->tokenizer()) {
907 m_part->xmlDocImpl()->tokenizer()->setNormalYieldDelay();
911 kDebug( 6000 ) <<
"WARNING: paintEvent reentered! ";
912 kDebug( 6000 ) << kBacktrace();
917 m_part->xmlDocImpl()->renderer()->layer()->paint(&p, r);
919 if (d->hasFrameset) {
920 NodeImpl *body =
static_cast<HTMLDocumentImpl*
>(m_part->xmlDocImpl())->body();
921 if(body && body->renderer() && body->id() == ID_FRAMESET)
922 static_cast<RenderFrameSet*>(body->renderer())->paintFrameSetRules(&p, r);
924 d->hasFrameset =
false;
928 QApplication::sendEvent( m_part, &event );
930 if (d->contentsMoving && !d->smoothScrolling && widget()->underMouse()) {
931 QMouseEvent *tempEvent =
new QMouseEvent( QEvent::MouseMove, widget()->mapFromGlobal( QCursor::pos() ),
932 Qt::NoButton, Qt::NoButton, Qt::NoModifier );
933 QApplication::postEvent(widget(), tempEvent);
936 if (d->firstRepaintPending && !m_part->
parentPart()) {
939 d->firstRepaintPending =
false;
958 if( m_part && m_part->xmlDocImpl() ) {
959 DOM::DocumentImpl *document = m_part->xmlDocImpl();
961 khtml::RenderCanvas* canvas =
static_cast<khtml::RenderCanvas *
>(document->renderer());
962 if ( !canvas )
return;
964 d->layoutSchedulingEnabled=
false;
965 d->dirtyLayout =
true;
968 RenderObject *
ref = 0;
969 RenderObject* root = document->documentElement() ? document->documentElement()->renderer() : 0;
971 if (document->isHTMLDocument()) {
972 NodeImpl *body =
static_cast<HTMLDocumentImpl*
>(document)->body();
973 if(body && body->renderer() && body->id() == ID_FRAMESET) {
976 body->renderer()->setNeedsLayout(
true);
977 d->hasFrameset =
true;
980 ref = (!body || root->style()->hidesOverflow()) ? root : body->renderer();
985 if( ref->style()->overflowX() == OHIDDEN ) {
987 }
else if (ref->style()->overflowX() == OSCROLL ) {
989 }
else if (horizontalScrollBarPolicy() != d->hpolicy) {
992 if ( ref->style()->overflowY() == OHIDDEN ) {
994 }
else if (ref->style()->overflowY() == OSCROLL ) {
996 }
else if (verticalScrollBarPolicy() != d->vpolicy) {
1000 d->needsFullRepaint = d->firstLayoutPending;
1002 d->needsFullRepaint =
true;
1010 if (d->firstLayoutPending) {
1013 d->firstLayoutPending =
false;
1014 verticalScrollBar()->setEnabled(
true );
1015 horizontalScrollBar()->setEnabled(
true );
1019 if (d->accessKeysEnabled && d->accessKeysActivated) {
1027 if (d->layoutTimerId)
1028 killTimer(d->layoutTimerId);
1029 d->layoutTimerId = 0;
1030 d->layoutSchedulingEnabled=
true;
1033 void KHTMLView::closeChildDialogs()
1040 if ( dlgbase->testAttribute( Qt::WA_ShowModal ) ) {
1041 kDebug(6000) <<
"closeChildDialogs: closing dialog " << dlgbase;
1049 kWarning() <<
"closeChildDialogs: not a KDialog! Don't use QDialogs in KDE! " <<
static_cast<QWidget*
>(dlg);
1050 static_cast<QWidget*
>(dlg)->hide();
1053 d->m_dialogsAllowed =
false;
1056 bool KHTMLView::dialogsAllowed() {
1057 bool allowed = d->m_dialogsAllowed;
1060 allowed &= p->
view()->dialogsAllowed();
1066 closeChildDialogs();
1072 percent = percent < 20 ? 20 : (percent > 800 ? 800 : percent);
1073 int oldpercent = d->zoomLevel;
1074 d->zoomLevel = percent;
1075 if (percent != oldpercent) {
1076 if (d->layoutSchedulingEnabled)
1084 return d->zoomLevel;
1089 d->smoothScrollMode = m;
1090 d->smoothScrollModeIsDefault =
false;
1091 if (d->smoothScrolling && !m)
1098 if (!d->smoothScrollModeIsDefault)
1100 d->smoothScrollMode = m;
1101 if (d->smoothScrolling && !m)
1107 return d->smoothScrollMode;
1117 if (!m_part->xmlDocImpl())
return;
1118 if (d->possibleTripleClick && ( _mouse->button() & Qt::MouseButtonMask ) == Qt::LeftButton)
1124 int xm = _mouse->x();
1125 int ym = _mouse->y();
1126 revertTransforms(xm, ym);
1130 d->isDoubleClick =
false;
1132 DOM::NodeImpl::MouseEvent mev( _mouse->buttons(), DOM::NodeImpl::MousePress );
1133 m_part->xmlDocImpl()->prepareMouseEvent(
false, xm, ym, &mev );
1137 if ( (_mouse->button() == Qt::MidButton) &&
1139 mev.url.isNull() && (mev.innerNode.elementId() != ID_INPUT) ) {
1140 QPoint point = mapFromGlobal( _mouse->globalPos() );
1142 d->m_mouseScroll_byX = 0;
1143 d->m_mouseScroll_byY = 0;
1145 d->m_mouseScrollTimer =
new QTimer(
this );
1146 connect( d->m_mouseScrollTimer, SIGNAL(
timeout()),
this, SLOT(slotMouseScrollTimer()) );
1148 if ( !d->m_mouseScrollIndicator ) {
1149 QPixmap pixmap( 48, 48 ), icon;
1150 pixmap.fill(
QColor( qRgba( 127, 127, 127, 127 ) ) );
1152 QPainter p( &pixmap );
1153 QStyleOption option;
1155 option.rect.setRect( 16, 0, 16, 16 );
1156 QApplication::style()->drawPrimitive( QStyle::PE_IndicatorArrowUp, &option, &p );
1157 option.rect.setRect( 0, 16, 16, 16 );
1158 QApplication::style()->drawPrimitive( QStyle::PE_IndicatorArrowLeft, &option, &p );
1159 option.rect.setRect( 16, 32, 16, 16 );
1160 QApplication::style()->drawPrimitive( QStyle::PE_IndicatorArrowDown, &option, &p );
1161 option.rect.setRect( 32, 16, 16, 16 );
1162 QApplication::style()->drawPrimitive( QStyle::PE_IndicatorArrowRight, &option, &p );
1163 p.drawEllipse( 23, 23, 2, 2 );
1165 d->m_mouseScrollIndicator =
new QWidget(
this );
1166 d->m_mouseScrollIndicator->setFixedSize( 48, 48 );
1168 palette.setBrush( d->m_mouseScrollIndicator->backgroundRole(), QBrush( pixmap ) );
1169 d->m_mouseScrollIndicator->setPalette( palette );
1171 d->m_mouseScrollIndicator->move( point.x()-24, point.y()-24 );
1177 if ( cg.
readEntry(
"ShowMouseScrollIndicator",
true ) ) {
1178 d->m_mouseScrollIndicator->show();
1179 d->m_mouseScrollIndicator->unsetCursor();
1181 QBitmap
mask = d->m_mouseScrollIndicator->palette().brush(d->m_mouseScrollIndicator->backgroundRole()).texture().createHeuristicMask(
true );
1183 if ( hasHorBar && !hasVerBar ) {
1184 QBitmap bm( 16, 16 );
1186 QPainter painter( &mask );
1187 painter.drawPixmap( QRectF( 16, 0, bm.width(), bm.height() ), bm, bm.rect() );
1188 painter.drawPixmap( QRectF( 16, 32, bm.width(), bm.height() ), bm, bm.rect() );
1189 d->m_mouseScrollIndicator->setCursor( Qt::SizeHorCursor );
1191 else if ( !hasHorBar && hasVerBar ) {
1192 QBitmap bm( 16, 16 );
1194 QPainter painter( &mask );
1195 painter.drawPixmap( QRectF( 0, 16, bm.width(), bm.height() ), bm, bm.rect() );
1196 painter.drawPixmap( QRectF( 32, 16, bm.width(), bm.height() ), bm, bm.rect() );
1197 d->m_mouseScrollIndicator->setCursor( Qt::SizeVerCursor );
1200 d->m_mouseScrollIndicator->setCursor( Qt::SizeAllCursor );
1202 d->m_mouseScrollIndicator->setMask( mask );
1205 if ( hasHorBar && !hasVerBar )
1206 viewport()->setCursor( Qt::SizeHorCursor );
1207 else if ( !hasHorBar && hasVerBar )
1208 viewport()->setCursor( Qt::SizeVerCursor );
1210 viewport()->setCursor( Qt::SizeAllCursor );
1215 else if ( d->m_mouseScrollTimer ) {
1216 delete d->m_mouseScrollTimer;
1217 d->m_mouseScrollTimer = 0;
1219 if ( d->m_mouseScrollIndicator )
1220 d->m_mouseScrollIndicator->hide();
1223 if (d->clickCount > 0 &&
1224 QPoint(d->clickX-xm,d->clickY-ym).manhattanLength() <= QApplication::startDragDistance())
1232 bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEDOWN_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),
true,
1233 d->clickCount,_mouse,
true,DOM::NodeImpl::MousePress);
1235 if (!swallowEvent) {
1236 emit m_part->nodeActivated(mev.innerNode);
1239 QApplication::sendEvent( m_part, &event );
1246 if(!m_part->xmlDocImpl())
return;
1248 int xm = _mouse->x();
1249 int ym = _mouse->y();
1250 revertTransforms(xm, ym);
1254 d->isDoubleClick =
true;
1256 DOM::NodeImpl::MouseEvent mev( _mouse->buttons(), DOM::NodeImpl::MouseDblClick );
1257 m_part->xmlDocImpl()->prepareMouseEvent(
false, xm, ym, &mev );
1261 if (d->clickCount > 0 &&
1262 QPoint(d->clickX-xm,d->clickY-ym).manhattanLength() <= QApplication::startDragDistance())
1269 bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEDOWN_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),
true,
1270 d->clickCount,_mouse,
true,DOM::NodeImpl::MouseDblClick);
1272 if (!swallowEvent) {
1274 QApplication::sendEvent( m_part, &event );
1277 d->possibleTripleClick=
true;
1278 QTimer::singleShot(QApplication::doubleClickInterval(),
this,SLOT(tripleClickTimeout()));
1281 void KHTMLView::tripleClickTimeout()
1283 d->possibleTripleClick =
false;
1289 if (!target.isEmpty() && (target.toLower() !=
"_top") &&
1290 (target.toLower() !=
"_self") && (target.toLower() !=
"_parent")) {
1291 if (target.toLower() ==
"_blank")
1305 if ( d->m_mouseScrollTimer ) {
1306 QPoint point = mapFromGlobal( _mouse->globalPos() );
1308 int deltaX = point.x() - d->m_mouseScrollIndicator->x() - 24;
1309 int deltaY = point.y() - d->m_mouseScrollIndicator->y() - 24;
1311 (deltaX > 0) ? d->m_mouseScroll_byX = 1 : d->m_mouseScroll_byX = -1;
1312 (deltaY > 0) ? d->m_mouseScroll_byY = 1 : d->m_mouseScroll_byY = -1;
1314 double adX = qAbs(deltaX)/30.0;
1315 double adY = qAbs(deltaY)/30.0;
1317 d->m_mouseScroll_byX = qMax(qMin(d->m_mouseScroll_byX *
int(adX*adX), SHRT_MAX), SHRT_MIN);
1318 d->m_mouseScroll_byY = qMax(qMin(d->m_mouseScroll_byY *
int(adY*adY), SHRT_MAX), SHRT_MIN);
1320 if (d->m_mouseScroll_byX == 0 && d->m_mouseScroll_byY == 0) {
1321 d->m_mouseScrollTimer->stop();
1323 else if (!d->m_mouseScrollTimer->isActive()) {
1324 d->m_mouseScrollTimer->start( 20 );
1328 if(!m_part->xmlDocImpl())
return;
1330 int xm = _mouse->x();
1331 int ym = _mouse->y();
1332 revertTransforms(xm, ym);
1334 DOM::NodeImpl::MouseEvent mev( _mouse->buttons(), DOM::NodeImpl::MouseMove );
1336 m_part->xmlDocImpl()->prepareMouseEvent( _mouse->buttons() , xm, ym, &mev );
1342 DOM::NodeImpl* target = mev.innerNode.handle();
1343 DOM::NodeImpl* fn = m_part->xmlDocImpl()->focusNode();
1346 if (d->m_mouseEventsTarget && fn && fn->renderer() && fn->renderer()->isWidget())
1349 bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEMOVE_EVENT,target,mev.innerNonSharedNode.handle(),
false,
1350 0,_mouse,
true,DOM::NodeImpl::MouseMove);
1352 if (d->clickCount > 0 &&
1353 QPoint(d->clickX-xm,d->clickY-ym).manhattanLength() > QApplication::startDragDistance()) {
1357 khtml::RenderObject* r = target ? target->renderer() : 0;
1358 bool setCursor =
true;
1359 bool forceDefault =
false;
1360 if (r && r->isWidget()) {
1361 RenderWidget* rw =
static_cast<RenderWidget*
>(r);
1362 KHTMLWidget* kw = qobject_cast<
KHTMLView*>(rw->widget())? dynamic_cast<KHTMLWidget*>(rw->widget()) : 0;
1363 if (kw && kw->
m_kwp->isRedirected())
1365 else if (
QLineEdit* le = qobject_cast<QLineEdit*>(rw->widget())) {
1366 QList<QWidget*> wl = qFindChildren<QWidget *>( le,
"KLineEditButton" );
1369 if (w->underMouse()) {
1370 forceDefault =
true;
1376 khtml::RenderStyle* style = (r && r->style()) ? r->style() : 0;
1378 LinkCursor linkCursor = LINK_NORMAL;
1379 switch (!forceDefault ? (style ? style->cursor() : CURSOR_AUTO) : CURSOR_DEFAULT) {
1382 !r->isPointInsideSelection(xm, ym, m_part->caret())) )
1386 if (mev.url.string().startsWith(
"mailto:") && mev.url.string().indexOf(
'@')>0)
1387 linkCursor = LINK_MAILTO;
1390 linkCursor = LINK_NEWWINDOW;
1393 if (r && r->isFrameSet() && !
static_cast<RenderFrameSet*
>(r)->noResize())
1394 c =
QCursor(static_cast<RenderFrameSet*>(r)->cursorShape());
1400 case CURSOR_POINTER:
1402 if (mev.url.string().startsWith(
"mailto:") && mev.url.string().indexOf(
'@')>0)
1403 linkCursor = LINK_MAILTO;
1406 linkCursor = LINK_NEWWINDOW;
1408 case CURSOR_PROGRESS:
1412 case CURSOR_ALL_SCROLL:
1413 c =
QCursor(Qt::SizeAllCursor);
1415 case CURSOR_E_RESIZE:
1416 case CURSOR_W_RESIZE:
1417 case CURSOR_EW_RESIZE:
1418 c =
QCursor(Qt::SizeHorCursor);
1420 case CURSOR_N_RESIZE:
1421 case CURSOR_S_RESIZE:
1422 case CURSOR_NS_RESIZE:
1423 c =
QCursor(Qt::SizeVerCursor);
1425 case CURSOR_NE_RESIZE:
1426 case CURSOR_SW_RESIZE:
1427 case CURSOR_NESW_RESIZE:
1428 c =
QCursor(Qt::SizeBDiagCursor);
1430 case CURSOR_NW_RESIZE:
1431 case CURSOR_SE_RESIZE:
1432 case CURSOR_NWSE_RESIZE:
1433 c =
QCursor(Qt::SizeFDiagCursor);
1442 c =
QCursor(Qt::WhatsThisCursor);
1444 case CURSOR_DEFAULT:
1447 case CURSOR_NOT_ALLOWED:
1448 c =
QCursor(Qt::ForbiddenCursor);
1450 case CURSOR_ROW_RESIZE:
1451 c =
QCursor(Qt::SplitVCursor);
1453 case CURSOR_COL_RESIZE:
1454 c =
QCursor(Qt::SplitHCursor);
1456 case CURSOR_VERTICAL_TEXT:
1457 case CURSOR_CONTEXT_MENU:
1458 case CURSOR_NO_DROP:
1466 if (!setCursor && style && style->cursor() != CURSOR_AUTO)
1472 vp = p->
view()->viewport();
1473 if ( setCursor && vp->cursor().handle() != c.handle() ) {
1474 if( c.shape() == Qt::ArrowCursor) {
1476 p->
view()->viewport()->unsetCursor();
1483 if ( linkCursor!=LINK_NORMAL && isVisible() && hasFocus() ) {
1486 if( !d->cursorIconWidget ) {
1488 d->cursorIconWidget =
new QLabel( 0, Qt::X11BypassWindowManagerHint );
1489 XSetWindowAttributes attr;
1490 attr.save_under = True;
1491 XChangeWindowAttributes( QX11Info::display(), d->cursorIconWidget->winId(), CWSaveUnder, &attr );
1493 d->cursorIconWidget =
new QLabel( NULL, NULL );
1499 if (linkCursor != d->cursorIconType) {
1500 d->cursorIconType = linkCursor;
1504 case LINK_MAILTO: cursorIcon =
"mail-message-new";
break;
1505 case LINK_NEWWINDOW: cursorIcon =
"window-new";
break;
1506 default: cursorIcon =
"dialog-error";
break;
1511 d->cursorIconWidget->resize( icon_pixmap.width(), icon_pixmap.height());
1512 d->cursorIconWidget->setMask( icon_pixmap.createMaskFromColor(Qt::transparent));
1513 d->cursorIconWidget->setPixmap( icon_pixmap);
1514 d->cursorIconWidget->update();
1517 QPoint c_pos = QCursor::pos();
1518 d->cursorIconWidget->move( c_pos.x() + 15, c_pos.y() + 15 );
1520 XRaiseWindow( QX11Info::display(), d->cursorIconWidget->winId());
1521 QApplication::flush();
1522 #elif defined(Q_WS_WIN)
1523 SetWindowPos( d->cursorIconWidget->winId(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE );
1527 d->cursorIconWidget->show();
1530 else if ( d->cursorIconWidget )
1531 d->cursorIconWidget->hide();
1533 if (r && r->isWidget()) {
1537 if (!swallowEvent) {
1539 QApplication::sendEvent( m_part, &event );
1545 bool swallowEvent =
false;
1547 int xm = _mouse->x();
1548 int ym = _mouse->y();
1549 revertTransforms(xm, ym);
1551 DOM::NodeImpl::MouseEvent mev( _mouse->buttons(), DOM::NodeImpl::MouseRelease );
1553 if ( m_part->xmlDocImpl() )
1555 m_part->xmlDocImpl()->prepareMouseEvent(
false, xm, ym, &mev );
1557 DOM::NodeImpl* target = mev.innerNode.handle();
1558 DOM::NodeImpl* fn = m_part->xmlDocImpl()->focusNode();
1561 if (d->m_mouseEventsTarget && fn && fn->renderer() && fn->renderer()->isWidget())
1564 swallowEvent = dispatchMouseEvent(EventImpl::MOUSEUP_EVENT,target,mev.innerNonSharedNode.handle(),
true,
1565 d->clickCount,_mouse,
false,DOM::NodeImpl::MouseRelease);
1568 if (d->m_mouseEventsTarget)
1569 d->m_mouseEventsTarget = 0;
1571 if (d->clickCount > 0 &&
1572 QPoint(d->clickX-xm,d->clickY-ym).manhattanLength() <= QApplication::startDragDistance()) {
1573 QMouseEvent me(d->isDoubleClick ? QEvent::MouseButtonDblClick : QEvent::MouseButtonRelease,
1574 _mouse->pos(), _mouse->button(), _mouse->buttons(), _mouse->modifiers());
1575 dispatchMouseEvent(EventImpl::CLICK_EVENT, mev.innerNode.handle(),mev.innerNonSharedNode.handle(),
true,
1576 d->clickCount, &me,
true, DOM::NodeImpl::MouseRelease);
1579 khtml::RenderObject* r = target ? target->renderer() : 0;
1580 if (r && r->isWidget())
1584 if (!swallowEvent) {
1586 QApplication::sendEvent( m_part, &event );
1591 bool KHTMLView::dispatchKeyEvent( QKeyEvent *_ke )
1593 if (!m_part->xmlDocImpl())
1615 if( _ke == d->postponed_autorepeat )
1620 if( _ke->type() == QEvent::KeyPress )
1622 if( !_ke->isAutoRepeat())
1624 bool ret = dispatchKeyEventHelper( _ke,
false );
1626 if( !ret && dispatchKeyEventHelper( _ke,
true ))
1632 bool ret = dispatchKeyEventHelper( _ke,
true );
1633 if( !ret && d->postponed_autorepeat )
1635 delete d->postponed_autorepeat;
1636 d->postponed_autorepeat = NULL;
1644 delete d->postponed_autorepeat;
1645 d->postponed_autorepeat = 0;
1647 if( !_ke->isAutoRepeat()) {
1648 return dispatchKeyEventHelper( _ke,
false );
1652 d->postponed_autorepeat =
new QKeyEvent( _ke->type(), _ke->key(), _ke->modifiers(),
1653 _ke->text(), _ke->isAutoRepeat(), _ke->count());
1654 if( _ke->isAccepted())
1655 d->postponed_autorepeat->accept();
1657 d->postponed_autorepeat->ignore();
1664 bool KHTMLView::dispatchKeyEventHelper( QKeyEvent *_ke,
bool keypress )
1666 DOM::NodeImpl* keyNode = m_part->xmlDocImpl()->focusNode();
1668 return keyNode->dispatchKeyEvent(_ke, keypress);
1670 return m_part->xmlDocImpl()->dispatchKeyEvent(_ke, keypress);
1677 if (d->accessKeysEnabled && _ke->key() == Qt::Key_Control && !(_ke->modifiers() & ~Qt::ControlModifier) && !d->accessKeysActivated)
1679 d->accessKeysPreActivate=
true;
1684 if (_ke->key() == Qt::Key_Shift && !(_ke->modifiers() & ~Qt::ShiftModifier))
1685 d->scrollSuspendPreActivate=
true;
1690 if (d->accessKeysEnabled && d->accessKeysActivated)
1692 int state = ( _ke->modifiers() & ( Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier ));
1693 if ( state==0 || state==Qt::ShiftModifier ) {
1694 if (_ke->key() != Qt::Key_Shift)
1695 accessKeysTimeout();
1696 handleAccessKey( _ke );
1700 accessKeysTimeout();
1705 if ( dispatchKeyEvent( _ke )) {
1711 int offs = (viewport()->height() < 30) ? viewport()->height() : 30;
1712 if (_ke->modifiers() & Qt::ShiftModifier)
1716 verticalScrollBar()->setValue( verticalScrollBar()->value() -viewport()->height() + offs );
1717 if(d->scrollSuspended)
1718 d->newScrollTimer(
this, 0);
1723 d->adjustScroller(
this, KHTMLViewPrivate::ScrollDown, KHTMLViewPrivate::ScrollUp);
1728 d->adjustScroller(
this, KHTMLViewPrivate::ScrollUp, KHTMLViewPrivate::ScrollDown);
1733 d->adjustScroller(
this, KHTMLViewPrivate::ScrollLeft, KHTMLViewPrivate::ScrollRight);
1738 d->adjustScroller(
this, KHTMLViewPrivate::ScrollRight, KHTMLViewPrivate::ScrollLeft);
1742 switch ( _ke->key() )
1746 if (!d->scrollTimerId || d->scrollSuspended)
1747 verticalScrollBar()->setValue( verticalScrollBar()->value()+10 );
1748 if (d->scrollTimerId)
1749 d->newScrollTimer(
this, 0);
1753 case Qt::Key_PageDown:
1754 d->shouldSmoothScroll =
true;
1755 verticalScrollBar()->setValue( verticalScrollBar()->value() +viewport()->height() - offs );
1756 if(d->scrollSuspended)
1757 d->newScrollTimer(
this, 0);
1762 if (!d->scrollTimerId || d->scrollSuspended)
1763 verticalScrollBar()->setValue( verticalScrollBar()->value()-10 );
1764 if (d->scrollTimerId)
1765 d->newScrollTimer(
this, 0);
1768 case Qt::Key_PageUp:
1769 d->shouldSmoothScroll =
true;
1770 verticalScrollBar()->setValue( verticalScrollBar()->value() -viewport()->height() + offs );
1771 if(d->scrollSuspended)
1772 d->newScrollTimer(
this, 0);
1776 if (!d->scrollTimerId || d->scrollSuspended)
1777 horizontalScrollBar()->setValue( horizontalScrollBar()->value()+10 );
1778 if (d->scrollTimerId)
1779 d->newScrollTimer(
this, 0);
1784 if (!d->scrollTimerId || d->scrollSuspended)
1785 horizontalScrollBar()->setValue( horizontalScrollBar()->value()-10 );
1786 if (d->scrollTimerId)
1787 d->newScrollTimer(
this, 0);
1790 case Qt::Key_Return:
1793 if (m_part->xmlDocImpl()) {
1794 NodeImpl *n = m_part->xmlDocImpl()->focusNode();
1800 verticalScrollBar()->setValue( 0 );
1801 horizontalScrollBar()->setValue( 0 );
1802 if(d->scrollSuspended)
1803 d->newScrollTimer(
this, 0);
1807 if(d->scrollSuspended)
1808 d->newScrollTimer(
this, 0);
1815 if (d->scrollTimerId)
1816 d->newScrollTimer(
this, 0);
1826 if( d->scrollSuspendPreActivate && _ke->key() != Qt::Key_Shift )
1827 d->scrollSuspendPreActivate =
false;
1828 if( _ke->key() == Qt::Key_Shift && d->scrollSuspendPreActivate && !(_ke->modifiers() & Qt::ShiftModifier))
1829 if (d->scrollTimerId) {
1830 d->scrollSuspended = !d->scrollSuspended;
1831 if (d->scrollSuspended)
1835 if (d->accessKeysEnabled)
1837 if (d->accessKeysPreActivate && _ke->key() != Qt::Key_Control)
1838 d->accessKeysPreActivate=
false;
1839 if (d->accessKeysPreActivate && !(_ke->modifiers() & Qt::ControlModifier))
1842 m_part->setStatusBarText(
i18n(
"Access Keys activated"),KHTMLPart::BarOverrideText);
1843 d->accessKeysActivated =
true;
1844 d->accessKeysPreActivate =
false;
1848 else if (d->accessKeysActivated)
1850 accessKeysTimeout();
1857 if ( dispatchKeyEvent( _ke ) )
1869 if (m_part->xmlDocImpl() && focusNextPrevNode(next))
1871 if (m_part->xmlDocImpl()->focusNode())
1872 kDebug() <<
"focusNode.name: "
1873 << m_part->xmlDocImpl()->focusNode()->nodeName().string() << endl;
1878 d->pseudoFocusNode = KHTMLViewPrivate::PFNone;
1887 QPoint pos = QCursor::pos();
1890 pos = v->viewport()->mapFromGlobal( pos );
1895 pos =
QPoint(pos.x() - viewport()->x(), pos.y() - viewport()->y());
1899 ensureVisible( xm, ym, 0, 5 );
1901 #ifndef KHTML_NO_SELECTION
1904 if (m_part->isExtendingSelection()) {
1905 RenderObject::NodeInfo renderInfo(
true,
false);
1906 m_part->xmlDocImpl()->renderer()->layer()
1907 ->nodeAtPoint(renderInfo, xm, ym);
1908 innerNode = renderInfo.innerNode();
1911 if (innerNode.
handle() && innerNode.
handle()->renderer()
1912 && innerNode.
handle()->renderer()->shouldSelect()) {
1913 m_part->extendSelectionTo(xm, ym, innerNode);
1915 #endif // KHTML_NO_SELECTION
1941 if (!qobject_cast<QFrame*>(w))
1942 w->setAttribute( Qt::WA_NoSystemBackground );
1944 w->setAttribute(Qt::WA_WState_InPaintEvent);
1946 if (!(w->objectName() ==
"KLineEditButton"))
1947 w->setAttribute(Qt::WA_OpaquePaintEvent);
1949 w->installEventFilter(view);
1953 if (qobject_cast<KHTMLView*>(w)) {
1954 handleWidget(static_cast<KHTMLView*>(w)->widget(), view,
false);
1955 handleWidget(static_cast<KHTMLView*>(w)->horizontalScrollBar(), view,
false);
1956 handleWidget(static_cast<KHTMLView*>(w)->verticalScrollBar(), view,
false);
1960 QObjectList children = w->children();
1961 foreach (
QObject*
object, children) {
1968 class KHTMLBackingStoreHackWidget :
public QWidget
1971 void publicEvent(
QEvent *e)
1979 switch (e->type()) {
1982 case QEvent::MouseButtonPress:
1983 case QEvent::MouseButtonRelease:
1984 case QEvent::MouseButtonDblClick:
1985 case QEvent::MouseMove:
1986 #ifndef QT_NO_WHEELEVENT
1989 case QEvent::ContextMenu:
1990 case QEvent::DragEnter:
1991 case QEvent::DragMove:
1992 case QEvent::DragLeave:
2003 w->setAttribute(Qt::WA_WState_InPaintEvent, b);
2007 if (qobject_cast<KHTMLView*>(w)) {
2014 foreach(
QObject* cw, w->children()) {
2015 if (cw->isWidgetType() && !
static_cast<QWidget*
>(cw)->isWindow()
2016 && !(
static_cast<QWidget*
>(cw)->windowModality() & Qt::ApplicationModal)) {
2024 if ( e->type() == QEvent::ShortcutOverride ) {
2025 QKeyEvent* ke = (QKeyEvent*) e;
2027 || (m_part->xmlDocImpl() && m_part->xmlDocImpl()->focusNode()
2028 && m_part->xmlDocImpl()->focusNode()->isContentEditable())) {
2029 if ( (ke->modifiers() & Qt::ControlModifier) || (ke->modifiers() & Qt::ShiftModifier) ) {
2030 switch ( ke->key() ) {
2046 if ( e->type() == QEvent::Leave ) {
2047 if ( d->cursorIconWidget )
2048 d->cursorIconWidget->hide();
2049 m_part->resetHoverText();
2056 else if (e->type() == QEvent::Resize) {
2060 }
else if (o->isWidgetType()) {
2063 while (v && v != view) {
2065 v = v->parentWidget();
2068 if (v && k && k->
m_kwp->isRedirected()) {
2070 bool isUpdate =
false;
2073 case QEvent::UpdateRequest: {
2075 static_cast<KHTMLBackingStoreHackWidget *
>(w)->publicEvent(e);
2079 case QEvent::UpdateLater:
2083 if (!allowWidgetPaintEvents) {
2089 while (v && v->parentWidget() != view) {
2092 v = v->parentWidget();
2099 QRect pr = isUpdate ?
static_cast<QUpdateLaterEvent*
>(e)->region().boundingRect() :
static_cast<QPaintEvent*
>(e)->rect();
2100 bool asap = !d->contentsMoving && qobject_cast<QAbstractScrollArea*>(c);
2105 w->repaint(static_cast<QUpdateLaterEvent*>(e)->region());
2107 w->update(static_cast<QUpdateLaterEvent*>(e)->region());
2112 if ( asap && !isUpdate && !d->painting && m_part->xmlDocImpl() && m_part->xmlDocImpl()->renderer() &&
2113 !
static_cast<khtml::RenderCanvas *
>(m_part->xmlDocImpl()->renderer())->needsLayout() ) {
2115 pr.width(), pr.height()+1);
2117 }
else if (!d->painting) {
2118 scheduleRepaint(x + pr.x(), y + pr.y(),
2119 pr.width(), pr.height()+1, asap);
2123 case QEvent::MouseMove:
2124 case QEvent::MouseButtonPress:
2125 case QEvent::MouseButtonRelease:
2126 case QEvent::MouseButtonDblClick: {
2128 if (0 && w->parentWidget() == view && !qobject_cast<QScrollBar*>(w) && !::qobject_cast<QScrollBar *>(w)) {
2129 QMouseEvent *me =
static_cast<QMouseEvent *
>(e);
2130 QPoint pt = w->mapTo( view, me->pos());
2131 QMouseEvent me2(me->type(), pt, me->button(), me->buttons(), me->modifiers());
2133 if (e->type() == QEvent::MouseMove)
2135 else if(e->type() == QEvent::MouseButtonPress)
2137 else if(e->type() == QEvent::MouseButtonRelease)
2145 case QEvent::KeyPress:
2146 case QEvent::KeyRelease:
2147 if (w->parentWidget() == view && !qobject_cast<QScrollBar*>(w)) {
2148 QKeyEvent *ke =
static_cast<QKeyEvent *
>(e);
2149 if (e->type() == QEvent::KeyPress) {
2159 if (qobject_cast<KUrlRequester*>(w->parentWidget()) &&
2160 e->type() == QEvent::KeyPress) {
2170 case QEvent::FocusIn:
2171 case QEvent::FocusOut: {
2176 block =
static_cast<QFocusEvent*
>(e)->reason() != Qt::MouseFocusReason || root->underMouse();
2195 switch (e->type()) {
2196 case QEvent::MouseButtonPress:
2197 case QEvent::MouseButtonRelease:
2198 case QEvent::MouseButtonDblClick:
2199 case QEvent::MouseMove:
2201 #ifndef QT_NO_WHEELEVENT
2204 case QEvent::ContextMenu:
2205 case QEvent::DragEnter:
2206 case QEvent::DragMove:
2207 case QEvent::DragLeave:
2210 case QEvent::ChildPolished: {
2213 QObject *c =
static_cast<QChildEvent *
>(e)->child();
2214 if (c->isWidgetType()) {
2217 if (!(w->windowFlags() & Qt::Window) && !(w->windowModality() & Qt::ApplicationModal)) {
2219 if (k && k->
m_kwp->isRedirected()) {
2227 case QEvent::Move: {
2228 if (static_cast<QMoveEvent*>(e)->pos() !=
QPoint(0,0)) {
2229 widget()->move(0,0);
2241 bool KHTMLView::hasLayoutPending()
2243 return d->layoutTimerId && !d->firstLayoutPending;
2246 DOM::NodeImpl *KHTMLView::nodeUnderMouse()
const
2248 return d->underMouse;
2251 DOM::NodeImpl *KHTMLView::nonSharedNodeUnderMouse()
const
2253 return d->underMouseNonShared;
2256 bool KHTMLView::scrollTo(
const QRect &bounds)
2258 d->scrollingSelf =
true;
2263 xe = bounds.right();
2264 ye = bounds.bottom();
2274 if (ye-y>curHeight-d->borderY)
2275 ye = y + curHeight - d->borderY;
2277 if (xe-x>curWidth-d->borderX)
2278 xe = x + curWidth - d->borderX;
2284 else if (xe + d->borderX >
contentsX() + curWidth)
2285 deltax = xe + d->borderX - (
contentsX() + curWidth );
2293 else if (ye + d->borderY >
contentsY() + curHeight)
2294 deltay = ye + d->borderY - (
contentsY() + curHeight );
2298 int maxx = curWidth-d->borderX;
2299 int maxy = curHeight-d->borderY;
2301 int scrollX, scrollY;
2303 scrollX = deltax > 0 ? (deltax > maxx ? maxx : deltax) : deltax == 0 ? 0 : (deltax>-maxx ? deltax : -maxx);
2304 scrollY = deltay > 0 ? (deltay > maxy ? maxy : deltay) : deltay == 0 ? 0 : (deltay>-maxy ? deltay : -maxy);
2316 horizontalScrollBar()->setValue( horizontalScrollBar()->value()+scrollX );
2317 verticalScrollBar()->setValue( verticalScrollBar()->value()+scrollY );
2319 d->scrollingSelf =
false;
2321 if ( (abs(deltax)<=maxx) && (abs(deltay)<=maxy) )
2327 bool KHTMLView::focusNextPrevNode(
bool next)
2336 DocumentImpl *doc = m_part->xmlDocImpl();
2337 NodeImpl *oldFocusNode = doc->focusNode();
2344 if ((oldFocusNode->renderer() && !oldFocusNode->renderer()->parent())
2345 || !oldFocusNode->isTabFocusable()) {
2346 doc->quietResetFocus();
2355 if (d->scrollBarMoved)
2359 toFocus = doc->nextFocusNode(oldFocusNode);
2361 toFocus = doc->previousFocusNode(oldFocusNode);
2363 if (!toFocus && oldFocusNode) {
2365 toFocus = doc->nextFocusNode(NULL);
2367 toFocus = doc->previousFocusNode(NULL);
2370 while (toFocus && toFocus != oldFocusNode)
2373 QRect focusNodeRect = toFocus->getRect();
2377 QRect r = toFocus->getRect();
2378 ensureVisible( r.right(), r.bottom());
2379 ensureVisible( r.left(), r.top());
2380 d->scrollBarMoved =
false;
2381 d->tabMovePending =
false;
2382 d->lastTabbingDirection = next;
2383 d->pseudoFocusNode = KHTMLViewPrivate::PFNone;
2384 m_part->xmlDocImpl()->setFocusNode(toFocus);
2385 Node guard(toFocus);
2386 if (!toFocus->hasOneRef() )
2394 toFocus = doc->nextFocusNode(toFocus);
2396 toFocus = doc->previousFocusNode(toFocus);
2398 if (!toFocus && oldFocusNode)
2402 toFocus = doc->nextFocusNode(NULL);
2406 toFocus = doc->previousFocusNode(NULL);
2411 d->scrollBarMoved =
false;
2415 if (!oldFocusNode && d->pseudoFocusNode == KHTMLViewPrivate::PFNone)
2418 d->scrollBarMoved =
false;
2419 d->pseudoFocusNode = next?KHTMLViewPrivate::PFTop:KHTMLViewPrivate::PFBottom;
2423 NodeImpl *newFocusNode = NULL;
2425 if (d->tabMovePending && next != d->lastTabbingDirection)
2428 newFocusNode = oldFocusNode;
2432 if (oldFocusNode || d->pseudoFocusNode == KHTMLViewPrivate::PFTop )
2433 newFocusNode = doc->nextFocusNode(oldFocusNode);
2437 if (oldFocusNode || d->pseudoFocusNode == KHTMLViewPrivate::PFBottom )
2438 newFocusNode = doc->previousFocusNode(oldFocusNode);
2441 bool targetVisible =
false;
2456 if (!m_part->
isCaretMode() && newFocusNode->isContentEditable()) {
2457 kDebug(6200) <<
"show caret! fn: " << newFocusNode->nodeName().string() << endl;
2458 m_part->clearCaretRectIfNeeded();
2463 kDebug(6200) <<
"hide caret! fn: " << newFocusNode->nodeName().string() << endl;
2465 m_part->notifySelectionChanged();
2467 targetVisible = scrollTo(newFocusNode->getRect());
2473 d->tabMovePending =
false;
2475 m_part->xmlDocImpl()->setFocusNode(newFocusNode);
2478 Node guard(newFocusNode);
2479 if (!newFocusNode->hasOneRef() )
2487 d->pseudoFocusNode = next?KHTMLViewPrivate::PFBottom:KHTMLViewPrivate::PFTop;
2493 if (!d->tabMovePending)
2494 d->lastTabbingDirection = next;
2495 d->tabMovePending =
true;
2511 fallbacks = buildFallbackAccessKeys();
2512 for( NodeImpl* n = m_part->xmlDocImpl(); n != NULL; n = n->traverseNextNode()) {
2513 if( n->isElementNode()) {
2514 ElementImpl* en =
static_cast< ElementImpl*
>( n );
2515 DOMString s = en->getAttribute( ATTR_ACCESSKEY );
2518 QChar a = s.
string()[ 0 ].toUpper();
2519 if( qFind( taken.begin(), taken.end(), a ) == taken.end())
2522 if( accesskey.isNull() && fallbacks.contains( en )) {
2523 QChar a = fallbacks[ en ].toUpper();
2524 if( qFind( taken.begin(), taken.end(), a ) == taken.end())
2525 accesskey =
QString(
"<qt><i>" ) + a +
"</i></qt>";
2527 if( !accesskey.isNull()) {
2528 QRect rec=en->getRect();
2530 lab->setAttribute(Qt::WA_DeleteOnClose);
2531 lab->setObjectName(
"KHTMLAccessKey");
2534 lab->setPalette(QToolTip::palette());
2535 lab->setLineWidth(2);
2536 lab->setFrameStyle(QFrame::Box | QFrame::Plain);
2539 lab->setParent( widget() );
2540 lab->setAutoFillBackground(
true);
2545 taken.append( accesskey[ 0 ] );
2554 if( !qobject_cast<KHTMLPart*>(cur) )
2557 if( part->
view() && part->
view() != caller )
2567 bool KHTMLView::isScrollingFromMouseWheel()
const
2569 return d->scrollingFromWheel !=
QPoint(-1,-1);
2572 void KHTMLView::accessKeysTimeout()
2574 d->accessKeysActivated=
false;
2575 d->accessKeysPreActivate =
false;
2576 m_part->setStatusBarText(
QString(), KHTMLPart::BarOverrideText);
2581 bool KHTMLView::handleAccessKey(
const QKeyEvent* ev )
2586 if( ev->key() >= Qt::Key_A && ev->key() <= Qt::Key_Z )
2587 c =
'A' + ev->key() - Qt::Key_A;
2588 else if( ev->key() >= Qt::Key_0 && ev->key() <= Qt::Key_9 )
2589 c =
'0' + ev->key() - Qt::Key_0;
2593 if( ev->text().length() == 1 )
2594 c = ev->text()[ 0 ];
2598 return focusNodeWithAccessKey( c );
2601 bool KHTMLView::focusNodeWithAccessKey( QChar c,
KHTMLView* caller )
2603 DocumentImpl *doc = m_part->xmlDocImpl();
2606 ElementImpl* node = doc->findAccessKeyElement( c );
2610 if( !qobject_cast<KHTMLPart*>(cur) )
2613 if( part->
view() && part->
view() != caller
2614 && part->
view()->focusNodeWithAccessKey( c,
this ))
2620 && m_part->
parentPart()->
view()->focusNodeWithAccessKey( c,
this ))
2622 if( caller == NULL ) {
2625 it != fallbacks.end();
2638 QRect r = node->getRect();
2639 ensureVisible( r.right(), r.bottom());
2640 ensureVisible( r.left(), r.top());
2643 if( node->isFocusable()) {
2644 if (node->id()==ID_LABEL) {
2646 node=
static_cast<ElementImpl *
>(
static_cast< HTMLLabelElementImpl*
>( node )->getFormElement());
2647 if (!node)
return true;
2652 #warning "port QFocusEvent::setReason( QFocusEvent::Shortcut ); to qt4"
2655 m_part->xmlDocImpl()->setFocusNode(node);
2657 #warning "port QFocusEvent::resetReason(); to qt4"
2660 if( node != NULL && node->hasOneRef())
2663 if( node != NULL && node->hasOneRef())
2667 switch( node->id()) {
2669 static_cast< HTMLAnchorElementImpl*
>( node )->click();
2672 static_cast< HTMLInputElementImpl*
>( node )->click();
2675 static_cast< HTMLButtonElementImpl*
>( node )->click();
2678 static_cast< HTMLAreaElementImpl*
>( node )->click();
2692 for( NodeImpl* n = after ? start->nextSibling() : start->traversePreviousNode();
2694 n = after ? n->traverseNextNode() : n->traversePreviousNode()) {
2695 if( n->isTextNode()) {
2697 ret +=
static_cast< TextImpl*
>( n )->toString().string();
2699 ret.prepend( static_cast< TextImpl* >( n )->toString().
string());
2729 if( ret.trimmed().isEmpty())
2733 return ret.simplified();
2737 return ret.simplified();
2743 for( NodeImpl* n = start;
2745 n = n->traverseNextNode()) {
2746 if( n->id() == ID_LABEL ) {
2747 HTMLLabelElementImpl*
label =
static_cast< HTMLLabelElementImpl*
>( n );
2748 NodeImpl* labelfor = label->getFormElement();
2750 ret[ labelfor ] = label->innerText().string().simplified();
2757 struct AccessKeyData {
2758 ElementImpl* element;
2768 QLinkedList< AccessKeyData > data;
2773 for( NodeImpl* n = m_part->xmlDocImpl();
2775 n = n->traverseNextNode()) {
2776 if( n->isElementNode()) {
2777 ElementImpl* element =
static_cast< ElementImpl*
>( n );
2778 if( element->renderer() == NULL )
2783 bool ignore =
false;
2784 bool text_after =
false;
2785 bool text_before =
false;
2786 switch( element->id()) {
2788 url = khtml::parseURL(element->getAttribute(ATTR_HREF)).
string();
2791 text =
static_cast< HTMLElementImpl*
>( element )->innerText().string().simplified();
2795 HTMLInputElementImpl* in =
static_cast< HTMLInputElementImpl*
>( element );
2796 switch( in->inputType()) {
2797 case HTMLInputElementImpl::SUBMIT:
2798 text = in->value().string();
2800 text =
i18n(
"Submit" );
2803 case HTMLInputElementImpl::IMAGE:
2804 text = in->altText().string();
2807 case HTMLInputElementImpl::BUTTON:
2808 text = in->value().string();
2811 case HTMLInputElementImpl::RESET:
2812 text = in->value().string();
2814 text =
i18n(
"Reset" );
2817 case HTMLInputElementImpl::HIDDEN:
2820 case HTMLInputElementImpl::CHECKBOX:
2821 case HTMLInputElementImpl::RADIO:
2825 case HTMLInputElementImpl::TEXT:
2826 case HTMLInputElementImpl::PASSWORD:
2827 case HTMLInputElementImpl::FILE:
2838 text =
static_cast< HTMLElementImpl*
>( element )->innerText().string().simplified();
2839 switch( static_cast< HTMLButtonElementImpl* >( element )->buttonType()) {
2840 case HTMLButtonElementImpl::SUBMIT:
2842 text =
i18n(
"Submit" );
2845 case HTMLButtonElementImpl::RESET:
2847 text =
i18n(
"Reset" );
2864 ignore = !element->isFocusable();
2872 DOMString akey = element->getAttribute( ATTR_ACCESSKEY );
2873 if( akey.
length() == 1 ) {
2874 hrefs[url] = akey.
string()[ 0 ].toUpper();
2877 if( text.isNull() && labels.contains( element ))
2878 text = labels[ element ];
2879 if( text.isNull() && text_before )
2881 if( text.isNull() && text_after )
2883 text = text.trimmed();
2888 it != priorities.end();
2890 if( text == (*it).first )
2893 AccessKeyData tmp = { element, text, url, priority };
2899 for(
char c =
'A'; c <=
'Z'; ++c )
2901 for(
char c =
'0'; c <=
'9'; ++c )
2903 for( NodeImpl* n = m_part->xmlDocImpl();
2905 n = n->traverseNextNode()) {
2906 if( n->isElementNode()) {
2907 ElementImpl* en =
static_cast< ElementImpl*
>( n );
2908 DOMString s = en->getAttribute( ATTR_ACCESSKEY );
2910 QChar c = s.
string()[ 0 ].toUpper();
2911 keys.removeAll( c );
2917 for(
int priority = 10; priority >= 0; --priority ) {
2918 for( QLinkedList< AccessKeyData >::Iterator it = data.begin();
2921 if( (*it).priority != priority ) {
2929 const QString url = (*it).url;
2931 if( hrefs.contains( url ) ) {
2932 it = data.erase( it );
2935 if( !text.isEmpty()) {
2939 it != priorities.end();
2941 if( text == (*it).first && keys.contains( (*it).second )) {
2949 if( key.isNull() && !text.isEmpty()) {
2951 for( QStringList::ConstIterator it = words.begin();
2954 if( keys.contains( (*it)[ 0 ].toUpper())) {
2955 key = (*it)[ 0 ].toUpper();
2960 if( key.isNull() && !text.isEmpty()) {
2961 for(
int i = 0; i < text.length(); ++i ) {
2962 if( keys.contains( text[ i ].toUpper())) {
2963 key = text[ i ].toUpper();
2970 ret[ (*it).element ] = key;
2971 keys.removeAll( key );
2972 it = data.erase( it );
2974 if( !url.isEmpty() && !url.startsWith(
"javascript:", Qt::CaseInsensitive )) {
2975 for( QLinkedList< AccessKeyData >::Iterator it2 = data.begin();
2978 if( (*it2).url == url ) {
2979 ret[ (*it2).element ] = key;
2982 it2 = data.erase( it2 );
2992 void KHTMLView::setMediaType(
const QString &medium )
2997 QString KHTMLView::mediaType()
const
3002 bool KHTMLView::pagedMode()
const
3007 void KHTMLView::setWidgetVisible(RenderWidget* w,
bool vis)
3010 d->visibleWidgets.insert(w, w->widget());
3013 d->visibleWidgets.remove(w);
3016 bool KHTMLView::needsFullRepaint()
const
3018 return d->needsFullRepaint;
3022 class QPointerDeleter
3025 explicit QPointerDeleter(
QObject* o) : obj(o) {}
3026 ~QPointerDeleter() {
delete obj; }
3028 const QPointer<QObject> obj;
3034 if(!m_part->xmlDocImpl())
return;
3035 khtml::RenderCanvas *root =
static_cast<khtml::RenderCanvas *
>(m_part->xmlDocImpl()->renderer());
3039 const QPointerDeleter settingsDeleter(printSettings);
3043 const QPointerDeleter dialogDeleter(dialog);
3045 QString docname = m_part->xmlDocImpl()->URL().prettyUrl();
3046 if ( !docname.isEmpty() )
3049 if(quick || (dialog->exec() && dialog)) {
3050 viewport()->setCursor( Qt::WaitCursor );
3052 printer.setFullPage(
false);
3054 printer.setDocName(docname);
3056 QPainter *p =
new QPainter;
3057 p->
begin( &printer );
3058 khtml::setPrintPainter( p );
3060 m_part->xmlDocImpl()->setPaintDevice( &printer );
3061 QString oldMediaType = mediaType();
3062 setMediaType(
"print" );
3066 m_part->xmlDocImpl()->setPrintStyleSheet( printSettings->printFriendly() ?
3067 "* { background-image: none !important;"
3068 " background-color: white !important;"
3069 " color: black !important; }"
3070 "body { margin: 0px !important; }"
3071 "html { margin: 0px !important; }" :
3072 "body { margin: 0px !important; }"
3073 "html { margin: 0px !important; }"
3076 kDebug(6000) <<
"printing: physical page width = " << printer.width()
3077 <<
" height = " << printer.height() << endl;
3078 root->setStaticMode(
true);
3079 root->setPagedMode(
true);
3080 root->setWidth(printer.width());
3082 root->setPageTop(0);
3083 root->setPageBottom(0);
3086 m_part->xmlDocImpl()->styleSelector()->computeFontSizes(printer.logicalDpiY(), 100);
3087 m_part->xmlDocImpl()->updateStyleSelector();
3088 root->setPrintImages(printSettings->printImages());
3089 root->makePageBreakAvoidBlocks();
3091 root->setNeedsLayoutAndMinMaxRecalc();
3096 bool printHeader = printSettings->printHeader();
3098 int headerHeight = 0;
3099 QFont headerFont(
"Sans Serif", 8);
3107 p->setFont(headerFont);
3108 headerHeight = (p->fontMetrics().lineSpacing() * 3) / 2;
3112 kDebug(6000) <<
"printing: html page width = " << root->docWidth()
3113 <<
" height = " << root->docHeight() << endl;
3114 kDebug(6000) <<
"printing: margins left = " << printer.pageRect().left() - printer.paperRect().left()
3115 <<
" top = " << printer.pageRect().top() - printer.paperRect().top() << endl;
3116 kDebug(6000) <<
"printing: paper width = " << printer.width()
3117 <<
" height = " << printer.height() << endl;
3120 int pageWidth = printer.width();
3121 int pageHeight = printer.height();
3122 p->setClipRect(0,0, pageWidth, pageHeight);
3124 pageHeight -= headerHeight;
3126 #ifndef QT_NO_TRANSFORMATIONS
3127 bool scalePage =
false;
3129 if(root->docWidth() > printer.width()) {
3131 scale = ((
double) printer.width())/((
double) root->docWidth());
3132 pageHeight = (int) (pageHeight/scale);
3133 pageWidth = (int) (pageWidth/scale);
3134 headerHeight = (int) (headerHeight/scale);
3137 kDebug(6000) <<
"printing: scaled html width = " << pageWidth
3138 <<
" height = " << pageHeight << endl;
3140 root->setHeight(pageHeight);
3141 root->setPageBottom(pageHeight);
3142 root->setNeedsLayout(
true);
3143 root->layoutIfNeeded();
3149 int available_width = printer.width() - 10 -
3150 2 * qMax(p->boundingRect(0, 0, printer.width(), p->fontMetrics().lineSpacing(), Qt::AlignLeft, headerLeft).width(),
3151 p->boundingRect(0, 0, printer.width(), p->fontMetrics().lineSpacing(), Qt::AlignLeft, headerRight).width());
3152 if (available_width < 150)
3153 available_width = 150;
3158 mid_width = p->boundingRect(0, 0, printer.width(), p->fontMetrics().lineSpacing(), Qt::AlignLeft, headerMid).width();
3160 }
while (mid_width > available_width);
3166 while(top < root->docHeight()) {
3167 if(top > 0) printer.newPage();
3168 #ifndef QT_NO_TRANSFORMATIONS
3170 p->scale(scale, scale);
3173 p->setClipRect(0, 0, pageWidth, headerHeight);
3176 int dy = p->fontMetrics().lineSpacing();
3177 p->setPen(Qt::black);
3178 p->setFont(headerFont);
3180 headerRight =
QString(
"#%1").arg(page);
3182 p->drawText(0, 0, printer.width(), dy, Qt::AlignLeft, headerLeft);
3183 p->drawText(0, 0, printer.width(), dy, Qt::AlignHCenter, headerMid);
3184 p->drawText(0, 0, printer.width(), dy, Qt::AlignRight, headerRight);
3188 p->translate(0, headerHeight-top);
3190 bottom = top+pageHeight;
3192 root->setPageTop(top);
3193 root->setPageBottom(bottom);
3194 root->setPageNumber(page);
3196 root->layer()->paint(p,
QRect(0, top, pageWidth, pageHeight));
3197 kDebug(6000) <<
"printed: page " << page <<
" bottom At = " << bottom;
3200 p->resetTransform();
3208 root->setPagedMode(
false);
3209 root->setStaticMode(
false);
3211 khtml::setPrintPainter( 0 );
3212 setMediaType( oldMediaType );
3213 m_part->xmlDocImpl()->setPaintDevice(
this );
3214 m_part->xmlDocImpl()->styleSelector()->computeFontSizes(m_part->xmlDocImpl()->logicalDpiY(), m_part->
fontScaleFactor());
3215 m_part->xmlDocImpl()->updateStyleSelector();
3216 viewport()->unsetCursor();
3222 if(!m_part->xmlDocImpl())
return;
3223 DOM::DocumentImpl *document = m_part->xmlDocImpl();
3224 if (!document->isHTMLDocument())
return;
3225 khtml::RenderCanvas *root =
static_cast<khtml::RenderCanvas *
>(document->renderer());
3227 root->style()->resetPalette();
3228 NodeImpl *body =
static_cast<HTMLDocumentImpl*
>(document)->body();
3230 body->setChanged(
true);
3231 body->recalcStyle( NodeImpl::Force );
3234 void KHTMLView::paint(QPainter *p,
const QRect &rc,
int yOff,
bool *more)
3236 if(!m_part->xmlDocImpl())
return;
3237 khtml::RenderCanvas *root =
static_cast<khtml::RenderCanvas *
>(m_part->xmlDocImpl()->renderer());
3240 d->firstRepaintPending =
false;
3243 QPaintDevice* opd = m_part->xmlDocImpl()->paintDevice();
3244 m_part->xmlDocImpl()->setPaintDevice(p->device());
3245 root->setPagedMode(
true);
3246 root->setStaticMode(
true);
3247 root->setWidth(rc.width());
3250 QRegion creg = p->clipRegion();
3251 QTransform t = p->worldTransform();
3252 QRect w = p->window();
3253 QRect v = p->viewport();
3254 bool vte = p->viewTransformEnabled();
3255 bool wme = p->worldMatrixEnabled();
3258 p->translate(rc.left(), rc.top());
3259 double scale = ((
double) rc.width()/(
double) root->docWidth());
3260 int height = (int) ((
double) rc.height() / scale);
3261 #ifndef QT_NO_TRANSFORMATIONS
3262 p->scale(scale, scale);
3264 root->setPageTop(yOff);
3265 root->setPageBottom(yOff+height);
3267 root->layer()->paint(p,
QRect(0, yOff, root->docWidth(), height));
3269 *more = yOff + height < root->docHeight();
3272 p->setWorldTransform(t);
3275 p->setViewTransformEnabled( vte );
3276 p->setWorldMatrixEnabled( wme );
3277 if (!creg.isEmpty())
3278 p->setClipRegion( creg );
3280 p->setClipRegion(QRegion(), Qt::NoClip);
3282 root->setPagedMode(
false);
3283 root->setStaticMode(
false);
3284 m_part->xmlDocImpl()->setPaintDevice( opd );
3287 void KHTMLView::render(QPainter* p,
const QRect& r,
const QPoint& off)
3290 d->firstRepaintPending =
false;
3292 QRect clip(off.x()+r.x(), off.y()+r.y(),r.width(),r.height());
3293 if(!m_part || !m_part->xmlDocImpl() || !m_part->xmlDocImpl()->renderer()) {
3294 p->fillRect(clip, palette().brush(QPalette::Active, QPalette::Base));
3297 QPaintDevice* opd = m_part->xmlDocImpl()->paintDevice();
3298 m_part->xmlDocImpl()->setPaintDevice(p->device());
3301 QRegion creg = p->clipRegion();
3302 QTransform t = p->worldTransform();
3303 QRect w = p->window();
3304 QRect v = p->viewport();
3305 bool vte = p->viewTransformEnabled();
3306 bool wme = p->worldMatrixEnabled();
3308 p->setClipRect(clip);
3312 m_part->xmlDocImpl()->renderer()->layer()->paint(p, rect);
3315 p->setWorldTransform(t);
3318 p->setViewTransformEnabled( vte );
3319 p->setWorldMatrixEnabled( wme );
3320 if (!creg.isEmpty())
3321 p->setClipRegion( creg );
3323 p->setClipRegion(QRegion(), Qt::NoClip);
3325 m_part->xmlDocImpl()->setPaintDevice( opd );
3328 void KHTMLView::setHasStaticBackground(
bool partial)
3331 if (d->staticWidget == KHTMLViewPrivate::SBFull &&
m_kwp->isRedirected())
3334 d->staticWidget = partial ?
3335 KHTMLViewPrivate::SBPartial : KHTMLViewPrivate::SBFull;
3338 void KHTMLView::setHasNormalBackground()
3341 if (d->staticWidget == KHTMLViewPrivate::SBFull &&
m_kwp->isRedirected())
3344 d->staticWidget = KHTMLViewPrivate::SBNone;
3347 void KHTMLView::addStaticObject(
bool fixed)
3350 d->fixedObjectsCount++;
3352 d->staticObjectsCount++;
3354 setHasStaticBackground(
true );
3357 void KHTMLView::removeStaticObject(
bool fixed)
3360 d->fixedObjectsCount--;
3362 d->staticObjectsCount--;
3364 assert( d->fixedObjectsCount >= 0 && d->staticObjectsCount >= 0 );
3366 if (!d->staticObjectsCount && !d->fixedObjectsCount)
3367 setHasNormalBackground();
3369 setHasStaticBackground(
true );
3374 #ifndef KHTML_NO_SCROLLBARS
3375 d->vpolicy = policy;
3384 #ifndef KHTML_NO_SCROLLBARS
3385 d->hpolicy = policy;
3392 void KHTMLView::restoreScrollBar()
3398 d->prevScrollbarVisible = verticalScrollBar()->isVisible();
3405 if (!d->formCompletions)
3407 return d->formCompletions->group(
"").readEntry(name,
QStringList());
3410 void KHTMLView::clearCompletionHistory(
const QString& name)
3412 if (!d->formCompletions)
3416 d->formCompletions->group(
"").writeEntry(name,
"");
3417 d->formCompletions->sync();
3420 void KHTMLView::addFormCompletionItem(
const QString &name,
const QString &value)
3427 bool cc_number(
true);
3428 for (
int i = 0; i < value.length(); ++i)
3431 if (!c.isNumber() && c !=
'-' && !c.isSpace())
3440 if (!items.contains(value))
3441 items.prepend(value);
3443 items.erase(items.isEmpty() ? items.end() : --items.end());
3444 d->formCompletions->group(
"").writeEntry(name, items);
3447 void KHTMLView::addNonPasswordStorableSite(
const QString& host)
3449 if (!d->formCompletions) {
3453 KConfigGroup cg( d->formCompletions,
"NonPasswordStorableSites");
3456 cg.writeEntry(
"Sites", sites);
3461 void KHTMLView::delNonPasswordStorableSite(
const QString& host)
3463 if (!d->formCompletions) {
3467 KConfigGroup cg( d->formCompletions,
"NonPasswordStorableSites");
3469 sites.removeOne(host);
3470 cg.writeEntry(
"Sites", sites);
3474 bool KHTMLView::nonPasswordStorableSite(
const QString& host)
const
3476 if (!d->formCompletions) {
3479 QStringList sites = d->formCompletions->group(
"NonPasswordStorableSites" ).readEntry(
"Sites",
QStringList());
3480 return (sites.indexOf(host) != -1);
3484 bool KHTMLView::dispatchMouseEvent(
int eventId, DOM::NodeImpl *targetNode,
3485 DOM::NodeImpl *targetNodeNonShared,
bool cancelable,
3486 int detail,QMouseEvent *_mouse,
bool setUnder,
3487 int mouseEventType,
int orient)
3490 if (targetNode && targetNode->isTextNode())
3491 targetNode = targetNode->parentNode();
3494 d->underMouse->deref();
3495 d->underMouse = targetNode;
3497 d->underMouse->ref();
3499 if (d->underMouseNonShared)
3500 d->underMouseNonShared->deref();
3501 d->underMouseNonShared = targetNodeNonShared;
3502 if (d->underMouseNonShared)
3503 d->underMouseNonShared->ref();
3505 bool isWheelEvent = (mouseEventType == DOM::NodeImpl::MouseWheel);
3507 int exceptioncode = 0;
3508 int pageX = _mouse->x();
3509 int pageY = _mouse->y();
3510 revertTransforms(pageX, pageY);
3513 int screenX = _mouse->globalX();
3514 int screenY = _mouse->globalY();
3516 switch (_mouse->button()) {
3517 case Qt::LeftButton:
3523 case Qt::RightButton:
3529 if (d->accessKeysEnabled && d->accessKeysPreActivate && button!=-1)
3530 d->accessKeysPreActivate=
false;
3532 bool ctrlKey = (_mouse->modifiers() & Qt::ControlModifier);
3533 bool altKey = (_mouse->modifiers() & Qt::AltModifier);
3534 bool shiftKey = (_mouse->modifiers() & Qt::ShiftModifier);
3535 bool metaKey = (_mouse->modifiers() & Qt::MetaModifier);
3538 if (setUnder && d->oldUnderMouse != targetNode) {
3539 if (d->oldUnderMouse && d->oldUnderMouse->document() != m_part->xmlDocImpl()) {
3540 d->oldUnderMouse->deref();
3541 d->oldUnderMouse = 0;
3544 if (d->oldUnderMouse) {
3546 MouseEventImpl *me =
new MouseEventImpl(EventImpl::MOUSEOUT_EVENT,
3547 true,
true,m_part->xmlDocImpl()->defaultView(),
3548 0,screenX,screenY,clientX,clientY,pageX, pageY,
3549 ctrlKey,altKey,shiftKey,metaKey,
3552 d->oldUnderMouse->dispatchEvent(me,exceptioncode,
true);
3557 MouseEventImpl *me =
new MouseEventImpl(EventImpl::MOUSEOVER_EVENT,
3558 true,
true,m_part->xmlDocImpl()->defaultView(),
3559 0,screenX,screenY,clientX,clientY,pageX, pageY,
3560 ctrlKey,altKey,shiftKey,metaKey,
3561 button,d->oldUnderMouse);
3564 targetNode->dispatchEvent(me,exceptioncode,
true);
3567 if (d->oldUnderMouse)
3568 d->oldUnderMouse->deref();
3569 d->oldUnderMouse = targetNode;
3570 if (d->oldUnderMouse)
3571 d->oldUnderMouse->ref();
3574 bool swallowEvent =
false;
3578 if (targetNode->isGenericFormElement()
3579 &&
static_cast<HTMLGenericFormElementImpl*
>(targetNode)->disabled())
3583 bool dblclick = ( eventId == EventImpl::CLICK_EVENT &&
3584 _mouse->type() == QEvent::MouseButtonDblClick );
3585 MouseEventImpl *me =
new MouseEventImpl(static_cast<EventImpl::EventId>(eventId),
3586 true,cancelable,m_part->xmlDocImpl()->defaultView(),
3587 detail,screenX,screenY,clientX,clientY,pageX, pageY,
3588 ctrlKey,altKey,shiftKey,metaKey,
3589 button,0, isWheelEvent ? 0 : _mouse, dblclick,
3590 isWheelEvent ?
static_cast<MouseEventImpl::Orientation
>(orient) : MouseEventImpl::ONone );
3592 if ( !d->m_mouseEventsTarget && RenderLayer::gScrollBar && eventId == EventImpl::MOUSEDOWN_EVENT )
3594 d->m_mouseEventsTarget = RenderLayer::gScrollBar;
3595 if ( d->m_mouseEventsTarget && qobject_cast<QScrollBar*>(d->m_mouseEventsTarget) &&
3596 dynamic_cast<KHTMLWidget*>(static_cast<QWidget*>(d->m_mouseEventsTarget)) ) {
3601 QMouseEvent fw(_mouse->type(),
QPoint(pageX, pageY)-p, _mouse->button(), _mouse->buttons(), _mouse->modifiers());
3602 static_cast<RenderWidget::EventPropagator *
>(
static_cast<QWidget*
>(d->m_mouseEventsTarget))->sendEvent(&fw);
3603 if (_mouse->type() == QMouseEvent::MouseButtonPress && _mouse->button() == Qt::RightButton) {
3604 QContextMenuEvent cme(QContextMenuEvent::Mouse, p);
3605 static_cast<RenderWidget::EventPropagator *
>(
static_cast<QWidget*
>(d->m_mouseEventsTarget))->sendEvent(&cme);
3606 d->m_mouseEventsTarget = 0;
3608 swallowEvent =
true;
3610 targetNode->dispatchEvent(me,exceptioncode,
true);
3611 bool defaultHandled = me->defaultHandled();
3612 if (defaultHandled || me->defaultPrevented())
3613 swallowEvent =
true;
3615 if (eventId == EventImpl::MOUSEDOWN_EVENT && !me->defaultPrevented()) {
3620 DOM::NodeImpl* nodeImpl = targetNode;
3621 for ( ; nodeImpl && !nodeImpl->isFocusable(); nodeImpl = nodeImpl->parentNode())
3623 if (nodeImpl && nodeImpl->isMouseFocusable())
3624 m_part->xmlDocImpl()->setFocusNode(nodeImpl);
3625 else if (!nodeImpl || !nodeImpl->focused())
3626 m_part->xmlDocImpl()->setFocusNode(0);
3631 return swallowEvent;
3634 void KHTMLView::setIgnoreWheelEvents(
bool e )
3636 d->ignoreWheelEvents = e;
3639 #ifndef QT_NO_WHEELEVENT
3645 if (d->scrollingFromWheel !=
QPoint(-1,-1) && d->scrollingFromWheel != QCursor::pos())
3646 d->scrollingFromWheel = d->scrollingFromWheelTimerId ? QCursor::pos() :
QPoint(-1,-1);
3648 if (d->accessKeysEnabled && d->accessKeysPreActivate) d->accessKeysPreActivate=
false;
3650 if ( ( e->modifiers() & Qt::ControlModifier) == Qt::ControlModifier )
3655 else if (d->firstLayoutPending)
3659 else if( !
m_kwp->isRedirected() &&
3660 ( (e->orientation() == Qt::Vertical &&
3661 ((d->ignoreWheelEvents && !verticalScrollBar()->isVisible())
3665 (e->orientation() == Qt::Horizontal &&
3666 ((d->ignoreWheelEvents && !horizontalScrollBar()->isVisible())
3679 revertTransforms(xm, ym);
3681 DOM::NodeImpl::MouseEvent mev( e->buttons(), DOM::NodeImpl::MouseWheel );
3682 m_part->xmlDocImpl()->prepareMouseEvent(
false, xm, ym, &mev );
3684 MouseEventImpl::Orientation o = MouseEventImpl::OVertical;
3685 if (e->orientation() == Qt::Horizontal)
3686 o = MouseEventImpl::OHorizontal;
3688 QMouseEvent _mouse(QEvent::MouseMove, e->pos(), Qt::NoButton, e->buttons(), e->modifiers());
3689 bool swallow = dispatchMouseEvent(EventImpl::KHTML_MOUSEWHEEL_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),
3690 true,-e->delta()/40,&_mouse,
true,DOM::NodeImpl::MouseWheel,o);
3695 d->scrollBarMoved =
true;
3696 d->scrollingFromWheel = QCursor::pos();
3698 d->shouldSmoothScroll =
true;
3699 if (d->scrollingFromWheelTimerId)
3700 killTimer(d->scrollingFromWheelTimerId);
3701 d->scrollingFromWheelTimerId = startTimer(400);
3705 bool h = (
static_cast<QWheelEvent*
>(e)->orientation() == Qt::Horizontal);
3706 bool d = (
static_cast<QWheelEvent*
>(e)->delta() < 0);
3707 QScrollBar* hsb = horizontalScrollBar();
3708 QScrollBar* vsb = verticalScrollBar();
3709 if ( (h && ((d && hsb->value() == hsb->maximum()) || (!d && hsb->value() == hsb->minimum()))) ||
3710 (!h && ((d && vsb->value() == vsb->maximum()) || (!d && vsb->value() == vsb->minimum()))) ) {
3735 DOM::NodeImpl* fn = m_part->xmlDocImpl() ? m_part->xmlDocImpl()->focusNode() : 0;
3736 if (fn && fn->renderer() && fn->renderer()->isWidget() &&
3737 (e->reason() != Qt::MouseFocusReason) &&
3738 static_cast<khtml::RenderWidget*>(fn->renderer())->widget())
3739 static_cast<khtml::RenderWidget*>(fn->renderer())->widget()->setFocus();
3740 m_part->setSelectionVisible();
3747 m_part->stopAutoScroll();
3748 m_part->setSelectionVisible(
false);
3751 if ( d->cursorIconWidget )
3752 d->cursorIconWidget->hide();
3759 if (!dx && !dy)
return;
3761 if ( !d->firstLayoutPending && !d->complete && m_part->xmlDocImpl() &&
3762 d->layoutSchedulingEnabled) {
3764 khtml::RenderCanvas* root =
static_cast<khtml::RenderCanvas *
>( m_part->xmlDocImpl()->renderer() );
3765 if (root && root->needsLayout()) {
3766 unscheduleRelayout();
3771 if ( d->shouldSmoothScroll && d->smoothScrollMode !=
SSMDisabled && m_part->xmlDocImpl() &&
3774 bool doSmoothScroll = (!d->staticWidget || d->smoothScrollMode ==
SSMEnabled);
3776 int numStaticPixels = 0;
3777 QRegion r =
static_cast<RenderCanvas*
>(m_part->xmlDocImpl()->renderer())->staticRegion();
3780 if (!doSmoothScroll && d->staticWidget == KHTMLViewPrivate::SBPartial && r.rects().size() <= 10) {
3781 foreach(
const QRect &rr, r.rects())
3782 numStaticPixels += rr.width()*rr.height();
3784 doSmoothScroll =
true;
3786 if (doSmoothScroll) {
3787 setupSmoothScrolling(dx, dy);
3792 if ( underMouse() && QToolTip::isVisible() )
3793 QToolTip::hideText();
3795 if (!d->scrollingSelf) {
3796 d->scrollBarMoved =
true;
3797 d->contentsMoving =
true;
3799 scheduleRepaint(0, 0, 0, 0);
3802 if (m_part->xmlDocImpl() && m_part->xmlDocImpl()->documentElement()) {
3803 m_part->xmlDocImpl()->documentElement()->dispatchHTMLEvent(EventImpl::SCROLL_EVENT,
true,
false);
3806 if (QApplication::isRightToLeft())
3809 if (!d->smoothScrolling) {
3810 d->updateContentsXY();
3815 if (widget()->pos() !=
QPoint(0,0)) {
3816 kDebug(6000) <<
"Static widget wasn't positioned at (0,0). This should NOT happen. Please report this event to developers.";
3817 kDebug(6000) << kBacktrace();
3818 widget()->move(0,0);
3823 if (
m_kwp->isRedirected()) {
3828 off = viewport()->mapTo(
this, off);
3831 if ( d->staticWidget ) {
3835 if (!d->visibleWidgets.isEmpty())
3836 checkExternalWidgetsPosition();
3838 if ( d->staticWidget == KHTMLViewPrivate::SBPartial
3839 && m_part->xmlDocImpl() && m_part->xmlDocImpl()->renderer() ) {
3841 QRegion r =
static_cast<RenderCanvas*
>(m_part->xmlDocImpl()->renderer())->staticRegion();
3845 for (
int i = 0; i < ar.size() ; ++i) {
3846 widget()->update( ar[i] );
3850 for (
int i = 0; i < ar.size() ; ++i) {
3851 w->scroll( dx, dy, ar[i].translated(off) );
3853 d->scrollExternalWidgets(dx, dy);
3858 if (d->accessKeysActivated)
3859 d->scrollAccessKeys(dx, dy);
3864 if (
m_kwp->isRedirected()) {
3866 w->scroll(dx, dy, rect);
3867 if (d->zoomLevel != 100) {
3871 widget()->scroll(dx, dy, widget()->rect() & viewport()->rect());
3874 d->scrollExternalWidgets(dx, dy);
3875 if (d->accessKeysActivated)
3876 d->scrollAccessKeys(dx, dy);
3879 void KHTMLView::setupSmoothScrolling(
int dx,
int dy)
3882 int ddx = qMax(d->steps ? abs(d->dx)/d->steps : 0,3);
3883 int ddy = qMax(d->steps ? abs(d->dy)/d->steps : 0,3);
3889 if (d->dx == 0 && d->dy == 0) {
3896 if (qMax(abs(d->dx), abs(d->dy)) / d->steps < qMax(ddx,ddy)) {
3899 d->steps = qMax((abs(d->dx)+ddx-1)/ddx, (abs(d->dy)+ddy-1)/ddy);
3900 if (d->steps < 1) d->steps = 1;
3903 d->smoothScrollStopwatch.start();
3904 if (!d->smoothScrolling) {
3905 d->startScrolling();
3910 void KHTMLView::scrollTick() {
3911 if (d->dx == 0 && d->dy == 0) {
3916 if (d->steps < 1) d->steps = 1;
3920 if (takesteps < 1) takesteps = 1;
3921 if (takesteps > d->steps) takesteps = d->steps;
3922 for(
int i = 0; i < takesteps; i++) {
3923 int ddx = (d->dx / (d->steps+1)) * 2;
3924 int ddy = (d->dy / (d->steps+1)) * 2;
3927 if (abs(ddx) > abs(d->dx)) ddx = d->dx;
3928 if (abs(ddy) > abs(d->dy)) ddy = d->dy;
3938 d->shouldSmoothScroll =
false;
3941 if (takesteps < 2) {
3942 d->smoothScrollMissedDeadlines = 0;
3944 if (d->smoothScrollMissedDeadlines !=
sWayTooMany &&
3945 (!m_part->xmlDocImpl() || !m_part->xmlDocImpl()->parsing())) {
3946 d->smoothScrollMissedDeadlines++;
3962 if (child->parent() != widget())
3963 child->setParent( widget() );
3973 if ( e->timerId() == d->scrollTimerId ) {
3974 if( d->scrollSuspended )
3976 switch (d->scrollDirection) {
3977 case KHTMLViewPrivate::ScrollDown:
3979 d->newScrollTimer(
this, 0);
3981 verticalScrollBar()->setValue( verticalScrollBar()->value() +d->scrollBy );
3983 case KHTMLViewPrivate::ScrollUp:
3985 d->newScrollTimer(
this, 0);
3987 verticalScrollBar()->setValue( verticalScrollBar()->value() -d->scrollBy );
3989 case KHTMLViewPrivate::ScrollRight:
3991 d->newScrollTimer(
this, 0);
3993 horizontalScrollBar()->setValue( horizontalScrollBar()->value() +d->scrollBy );
3995 case KHTMLViewPrivate::ScrollLeft:
3997 d->newScrollTimer(
this, 0);
3999 horizontalScrollBar()->setValue( horizontalScrollBar()->value() -d->scrollBy );
4004 else if ( e->timerId() == d->scrollingFromWheelTimerId ) {
4005 killTimer( d->scrollingFromWheelTimerId );
4006 d->scrollingFromWheelTimerId = 0;
4007 }
else if ( e->timerId() == d->layoutTimerId ) {
4008 if (d->firstLayoutPending && d->layoutAttemptCounter < 4
4009 && (!m_part->xmlDocImpl() || !m_part->xmlDocImpl()->readyForLayout())) {
4010 d->layoutAttemptCounter++;
4011 killTimer(d->layoutTimerId);
4012 d->layoutTimerId = 0;
4017 d->scheduledLayoutCounter++;
4018 if (d->firstLayoutPending) {
4019 d->firstLayoutPending =
false;
4020 verticalScrollBar()->setEnabled(
true );
4021 horizontalScrollBar()->setEnabled(
true );
4025 d->contentsMoving =
false;
4026 if( m_part->xmlDocImpl() ) {
4027 DOM::DocumentImpl *document = m_part->xmlDocImpl();
4028 khtml::RenderCanvas* root =
static_cast<khtml::RenderCanvas *
>(document->renderer());
4030 if ( root && root->needsLayout() ) {
4031 if (d->repaintTimerId)
4032 killTimer(d->repaintTimerId);
4033 d->repaintTimerId = 0;
4039 if (d->repaintTimerId)
4040 killTimer(d->repaintTimerId);
4041 d->repaintTimerId = 0;
4046 d->updateRegion = QRegion();
4049 updateRegion = rects[0];
4051 for (
int i = 1; i < rects.size(); ++i ) {
4052 QRect newRegion = updateRegion.unite(rects[i]);
4053 if (2*newRegion.height() > 3*updateRegion.height() )
4056 updateRegion = rects[i];
4059 updateRegion = newRegion;
4062 if ( !updateRegion.isNull() )
4070 if (d->dirtyLayout && !d->visibleWidgets.isEmpty())
4071 checkExternalWidgetsPosition();
4073 d->dirtyLayout =
false;
4076 if (d->emitCompletedAfterRepaint) {
4077 bool full = d->emitCompletedAfterRepaint == KHTMLViewPrivate::CSFull;
4078 d->emitCompletedAfterRepaint = KHTMLViewPrivate::CSNone;
4086 void KHTMLView::checkExternalWidgetsPosition()
4091 QHashIterator<void*, QWidget*> it(d->visibleWidgets);
4092 while (it.hasNext()) {
4095 RenderWidget* rw =
static_cast<RenderWidget*
>( it.key() );
4096 if (!rw->absolutePosition(xp, yp) ||
4097 !visibleRect.intersects(
QRect(xp, yp, it.value()->width(), it.value()->height())))
4098 toRemove.append(rw);
4100 foreach (RenderWidget* r, toRemove)
4101 if ( (w = d->visibleWidgets.take(r) ) )
4102 w->move( 0, -500000);
4105 void KHTMLView::scheduleRelayout(khtml::RenderObject * )
4107 if (!d->layoutSchedulingEnabled || d->layoutTimerId)
4111 if (d->firstLayoutPending) {
4115 time = d->layoutAttemptCounter ?
4117 }
else if (m_part->xmlDocImpl() && m_part->xmlDocImpl()->parsing()) {
4122 d->layoutTimerId = startTimer( time );
4125 void KHTMLView::unscheduleRelayout()
4127 if (!d->layoutTimerId)
4130 killTimer(d->layoutTimerId);
4131 d->layoutTimerId = 0;
4134 void KHTMLView::unscheduleRepaint()
4136 if (!d->repaintTimerId)
4139 killTimer(d->repaintTimerId);
4140 d->repaintTimerId = 0;
4143 void KHTMLView::scheduleRepaint(
int x,
int y,
int w,
int h,
bool asap)
4145 bool parsing = !m_part->xmlDocImpl() || m_part->xmlDocImpl()->parsing();
4150 int time = parsing && !d->firstLayoutPending ? 150 : (!asap ? ( !d->complete ? 80 : 20 ) : 0);
4152 #ifdef DEBUG_FLICKER
4154 p.begin( viewport() );
4158 p.fillRect( vx, vy, w, h, Qt::red );
4162 d->updateRegion = d->updateRegion.unite(
QRect(x,y,w,h));
4164 if (asap && !parsing)
4165 unscheduleRepaint();
4167 if ( !d->repaintTimerId )
4168 d->repaintTimerId = startTimer( time );
4173 void KHTMLView::complete(
bool pendingAction )
4180 if (d->layoutTimerId)
4184 killTimer(d->layoutTimerId);
4185 d->layoutTimerId = startTimer( 0 );
4186 d->emitCompletedAfterRepaint = pendingAction ?
4187 KHTMLViewPrivate::CSActionPending : KHTMLViewPrivate::CSFull;
4191 if (d->repaintTimerId)
4195 killTimer(d->repaintTimerId);
4196 d->repaintTimerId = startTimer( 0 );
4197 d->emitCompletedAfterRepaint = pendingAction ?
4198 KHTMLViewPrivate::CSActionPending : KHTMLViewPrivate::CSFull;
4201 if (!d->emitCompletedAfterRepaint)
4211 void KHTMLView::updateScrollBars()
4213 const QWidget *view = widget();
4217 QSize p = viewport()->size();
4218 QSize m = maximumViewportSize();
4220 if (m.expandedTo(view->size()) == m)
4223 QSize v = view->size();
4224 horizontalScrollBar()->setRange(0, v.width() - p.width());
4225 horizontalScrollBar()->setPageStep(p.width());
4226 verticalScrollBar()->setRange(0, v.height() - p.height());
4227 verticalScrollBar()->setPageStep(p.height());
4228 if (!d->smoothScrolling) {
4229 d->updateContentsXY();
4233 void KHTMLView::slotMouseScrollTimer()
4235 horizontalScrollBar()->setValue( horizontalScrollBar()->value() +d->m_mouseScroll_byX );
4236 verticalScrollBar()->setValue( verticalScrollBar()->value() +d->m_mouseScroll_byY);
4242 Selection sel = pos;
4243 sel.expandUsingGranularity(Selection::LINE);
4244 return toEnd ? sel.end() : sel.start();
4257 bool KHTMLView::caretKeyPressEvent(QKeyEvent *_ke)
4261 Position old_pos = caret.caretPos();
4262 Position pos = old_pos;
4263 bool recalcXPos =
true;
4264 bool handled =
true;
4266 bool ctrl = _ke->modifiers() & Qt::ControlModifier;
4267 bool shift = _ke->modifiers() & Qt::ShiftModifier;
4269 switch(_ke->key()) {
4273 pos = old_pos.nextLinePosition(caret.xPosForVerticalArrowNavigation(Selection::EXTENT));
4278 pos = old_pos.previousLinePosition(caret.xPosForVerticalArrowNavigation(Selection::EXTENT));
4283 pos = ctrl ? old_pos.previousWordPosition() : old_pos.previousCharacterPosition();
4287 pos = ctrl ? old_pos.nextWordPosition() : old_pos.nextCharacterPosition();
4290 case Qt::Key_PageDown:
4294 case Qt::Key_PageUp:
4317 if (pos != old_pos) {
4318 m_part->clearCaretRectIfNeeded();
4320 caret.moveTo(shift ? caret.nonCaretPos() : pos, pos);
4321 int old_x = caret.xPosForVerticalArrowNavigation(Selection::CARETPOS);
4323 m_part->selectionLayoutChanged();
4329 m_part->emitCaretPositionChanged(pos);
4331 m_part->notifySelectionChanged();
4335 if (handled) _ke->accept();
4339 #undef DEBUG_CARETMODE