28 #include "khtmlview.h"
30 #include "khtml_part.h"
31 #include "khtml_events.h"
32 #include <config-khtml.h>
34 #include <qx11info_x11.h>
37 #include "html/html_documentimpl.h"
38 #include "html/html_inlineimpl.h"
39 #include "html/html_formimpl.h"
40 #include "html/htmltokenizer.h"
41 #include "editing/editor.h"
42 #include "rendering/render_arena.h"
43 #include "rendering/render_canvas.h"
44 #include "rendering/render_frames.h"
45 #include "rendering/render_replaced.h"
46 #include "rendering/render_form.h"
47 #include "rendering/render_layer.h"
48 #include "rendering/render_line.h"
49 #include "rendering/render_table.h"
51 #define protected public
52 #include "rendering/render_text.h"
54 #include "xml/dom2_eventsimpl.h"
55 #include "css/cssstyleselector.h"
56 #include "misc/loader.h"
57 #include "khtml_settings.h"
58 #include "khtml_printsettings.h"
60 #include "khtmlpart_p.h"
63 #include "khtml_debug.h"
64 #include <kiconloader.h>
65 #include <knotification.h>
67 #include <../khtml_version.h>
69 #include <kstringhandler.h>
70 #include <kconfiggroup.h>
71 #include <ksharedconfig.h>
72 #include <KWindowSystem>
76 #include <QDialogButtonBox>
84 #include <QTextDocument>
86 #include <QAbstractEventDispatcher>
88 #include <QAbstractScrollArea>
90 #include <QPrintDialog>
91 #include <qstandardpaths.h>
99 #elif defined(Q_OS_WIN)
111 using namespace khtml;
114 static const int sFirstLayoutDelay = 520;
115 static const int sParsingLayoutsInterval = 380;
116 static const int sLayoutAttemptDelay = 300;
118 static const int sFirstLayoutDelay = 280;
119 static const int sParsingLayoutsInterval = 320;
120 static const int sLayoutAttemptDelay = 200;
122 static const int sLayoutAttemptIncrement = 20;
123 static const int sParsingLayoutsIncrement = 60;
125 static const int sSmoothScrollTime = 128;
126 static const int sSmoothScrollTick = 16;
127 static const int sSmoothScrollMinStaticPixels = 320 * 200;
129 static const int sMaxMissedDeadlines = 12;
130 static const int sWayTooMany = -1;
132 class KHTMLViewPrivate
137 enum PseudoFocusNodes {
143 enum StaticBackgroundState {
149 enum CompletedState {
156 :
underMouse(nullptr), underMouseNonShared(nullptr), oldUnderMouse(nullptr)
158 postponed_autorepeat =
nullptr;
159 scrollingFromWheelTimerId = 0;
160 smoothScrollMode = KHTMLView::SSMWhenEfficient;
165 formCompletions =
nullptr;
166 prevScrollbarVisible =
true;
168 possibleTripleClick =
false;
169 emitCompletedAfterRepaint = CSNone;
170 cursorIconWidget =
nullptr;
171 cursorIconType = KHTMLView::LINK_NORMAL;
172 m_mouseScrollTimer =
nullptr;
173 m_mouseScrollIndicator =
nullptr;
180 delete formCompletions;
181 delete postponed_autorepeat;
185 if (underMouseNonShared) {
186 underMouseNonShared->deref();
189 oldUnderMouse->deref();
192 delete cursorIconWidget;
193 delete m_mouseScrollTimer;
194 delete m_mouseScrollIndicator;
202 if (underMouseNonShared) {
203 underMouseNonShared->deref();
205 underMouseNonShared =
nullptr;
207 oldUnderMouse->deref();
209 oldUnderMouse =
nullptr;
211 staticWidget = SBNone;
212 fixedObjectsCount = 0;
213 staticObjectsCount = 0;
214 tabMovePending =
false;
215 lastTabbingDirection =
true;
216 pseudoFocusNode = PFNone;
218 #ifndef KHTML_NO_SCROLLBARS
227 scrollBarMoved =
false;
228 contentsMoving =
false;
229 ignoreWheelEvents =
false;
230 scrollingFromWheel =
QPoint(-1, -1);
239 isDoubleClick =
false;
240 scrollingSelf =
false;
241 delete postponed_autorepeat;
242 postponed_autorepeat =
nullptr;
246 scrollSuspended =
false;
247 scrollSuspendPreActivate =
false;
248 smoothScrolling =
false;
249 smoothScrollModeIsDefault =
true;
250 shouldSmoothScroll =
false;
251 smoothScrollMissedDeadlines = 0;
254 firstLayoutPending =
true;
256 firstRepaintPending =
true;
258 needsFullRepaint =
true;
260 layoutSchedulingEnabled =
true;
263 layoutAttemptCounter = 0;
264 scheduledLayoutCounter = 0;
266 m_dialogsAllowed =
true;
267 accessKeysActivated =
false;
268 accessKeysPreActivate =
false;
274 accessKeysEnabled = KHTMLGlobal::defaultHTMLSettings()->accessKeysEnabled();
275 KHTMLGlobal::deref();
277 emitCompletedAfterRepaint = CSNone;
278 m_mouseEventsTarget =
nullptr;
279 m_clipHolder =
nullptr;
281 void newScrollTimer(
QWidget *view,
int tid)
286 scrollSuspended =
false;
288 enum ScrollDirection { ScrollLeft, ScrollRight, ScrollUp, ScrollDown };
290 void adjustScroller(
QWidget *view, ScrollDirection direction, ScrollDirection oppositedir)
292 static const struct {
295 {320, 1}, {224, 1}, {160, 1}, {112, 1}, {80, 1}, {56, 1}, {40, 1},
296 {28, 1}, {20, 1}, {20, 2}, {20, 3}, {20, 4}, {20, 6}, {20, 8}, {0, 0}
298 if (!scrollTimerId ||
299 (
static_cast<int>(scrollDirection) != direction &&
300 (
static_cast<int>(scrollDirection) != oppositedir || scrollSuspended))) {
302 scrollBy = timings[scrollTiming].pixels;
303 scrollDirection = direction;
304 newScrollTimer(view, view->
startTimer(timings[scrollTiming].msec));
305 }
else if (scrollDirection == direction &&
306 timings[scrollTiming + 1].msec && !scrollSuspended) {
307 scrollBy = timings[++scrollTiming].pixels;
308 newScrollTimer(view, view->
startTimer(timings[scrollTiming].msec));
309 }
else if (scrollDirection == oppositedir) {
311 scrollBy = timings[--scrollTiming].pixels;
312 newScrollTimer(view, view->
startTimer(timings[scrollTiming].msec));
315 scrollSuspended =
false;
318 bool haveZoom()
const
320 return zoomLevel != 100;
323 void startScrolling()
325 smoothScrolling =
true;
326 smoothScrollTimer.start(sSmoothScrollTick);
327 shouldSmoothScroll =
false;
332 smoothScrollTimer.stop();
336 smoothScrolling =
false;
337 shouldSmoothScroll =
false;
340 void updateContentsXY()
343 view->horizontalScrollBar()->maximum() - view->horizontalScrollBar()->value() : view->horizontalScrollBar()->value();
344 contentsY = view->verticalScrollBar()->value();
346 void scrollAccessKeys(
int dx,
int dy)
353 void scrollExternalWidgets(
int dx,
int dy)
355 if (visibleWidgets.isEmpty()) {
360 while (it.hasNext()) {
362 it.value()->move(it.value()->pos() +
QPoint(dx, dy));
366 NodeImpl *underMouse;
367 NodeImpl *underMouseNonShared;
368 NodeImpl *oldUnderMouse;
372 bool tabMovePending: 1;
373 bool lastTabbingDirection: 1;
374 PseudoFocusNodes pseudoFocusNode: 3;
375 bool scrollBarMoved: 1;
376 bool contentsMoving: 1;
380 bool prevScrollbarVisible: 1;
382 bool ignoreWheelEvents: 1;
383 StaticBackgroundState staticWidget: 3;
384 int staticObjectsCount;
385 int fixedObjectsCount;
388 int borderX, borderY;
393 int clickX, clickY, clickCount;
399 int contentsX, contentsY;
407 ScrollDirection scrollDirection : 3;
408 bool scrollSuspended : 1;
409 bool scrollSuspendPreActivate : 1;
411 bool smoothScrolling : 1;
412 bool smoothScrollModeIsDefault : 1;
413 bool shouldSmoothScroll : 1;
414 bool hasFrameset : 1;
416 bool firstLayoutPending : 1;
418 bool firstRepaintPending : 1;
420 bool layoutSchedulingEnabled : 1;
421 bool needsFullRepaint : 1;
423 bool possibleTripleClick : 1;
424 bool dirtyLayout : 1;
425 bool m_dialogsAllowed : 1;
426 short smoothScrollMissedDeadlines;
428 int layoutAttemptCounter;
429 int scheduledLayoutCounter;
432 QTime smoothScrollStopwatch;
434 bool accessKeysEnabled;
435 bool accessKeysActivated;
436 bool accessKeysPreActivate;
437 CompletedState emitCompletedAfterRepaint;
440 KHTMLView::LinkCursor cursorIconType;
443 short m_mouseScroll_byX;
444 short m_mouseScroll_byY;
445 QPoint scrollingFromWheel;
446 int scrollingFromWheelTimerId;
447 QTimer *m_mouseScrollTimer;
448 QWidget *m_mouseScrollIndicator;
454 #ifndef QT_NO_TOOLTIP
465 static bool findImageMapRect(HTMLImageElementImpl *img,
const QPoint &scrollOfs,
468 HTMLMapElementImpl *
map;
469 if (img && img->document()->isHTMLDocument() &&
470 (map =
static_cast<HTMLDocumentImpl *
>(img->document())->getMap(img->imageMap()))) {
471 RenderObject::NodeInfo info(
true,
false);
474 if (!rend || !rend->absolutePosition(ax, ay)) {
478 bool inside =
map->mapMouseEvent(p.
x() - ax + scrollOfs.
x(),
479 p.
y() - ay + scrollOfs.
y(), rend->contentWidth(),
480 rend->contentHeight(), info);
481 if (inside && info.URLElement()) {
482 HTMLAreaElementImpl *area =
static_cast<HTMLAreaElementImpl *
>(info.URLElement());
483 Q_ASSERT(area->id() == ID_AREA);
484 s = area->getAttribute(ATTR_TITLE).string();
485 QRegion reg = area->cachedRegion();
496 bool KHTMLView::event(
QEvent *e)
503 DOM::NodeImpl *node = d->underMouseNonShared;
506 if (node->isElementNode()) {
507 DOM::ElementImpl *e =
static_cast<DOM::ElementImpl *
>(node);
513 if (e->id() == ID_IMG && !e->getAttribute(ATTR_USEMAP).isEmpty()) {
514 found = findImageMapRect(
static_cast<HTMLImageElementImpl *
>(e),
515 viewportToContents(
QPoint(0, 0)), p, r, s);
518 s = e->getAttribute(ATTR_TITLE).string().
trimmed();
529 node = node->parentNode();
556 slotPaletteChanged();
565 :
QScrollArea(parent), d(new KHTMLViewPrivate(this))
578 KHTMLView::~KHTMLView()
592 assert(
part && !m_part);
596 void KHTMLView::initWidget()
626 connect(&d->smoothScrollTimer, SIGNAL(timeout()),
this, SLOT(scrollTick()));
629 void KHTMLView::resizeContentsToViewport()
636 void KHTMLView::clear()
638 if (d->accessKeysEnabled && d->accessKeysActivated) {
642 if (d->cursorIconWidget) {
643 d->cursorIconWidget->hide();
645 if (d->smoothScrolling) {
669 void KHTMLView::setMouseEventsTarget(
QWidget *w)
671 d->m_mouseEventsTarget = w;
674 QWidget *KHTMLView::mouseEventsTarget()
const
676 return d->m_mouseEventsTarget;
681 d->m_clipHolder = ch;
686 return d->m_clipHolder;
722 if (m_kwp->isRedirected()) {
724 if (RenderWidget *rw = m_kwp->renderWidget()) {
725 int ret = rw->width() - rw->paddingLeft() - rw->paddingRight() - rw->borderLeft() - rw->borderRight();
738 if (m_kwp->isRedirected()) {
740 if (RenderWidget *rw = m_kwp->renderWidget()) {
741 int ret = rw->height() - rw->paddingBottom() - rw->paddingTop() - rw->borderTop() - rw->borderBottom();
761 if (d->scrollTimerId) {
762 d->newScrollTimer(
this, 0);
796 applyTransforms(
x,
y, w, h);
797 if (m_kwp->isRedirected()) {
798 QPoint off = m_kwp->absolutePos();
813 applyTransforms(
x,
y, w, h);
814 if (m_kwp->isRedirected()) {
815 QPoint off = m_kwp->absolutePos();
828 void KHTMLView::applyTransforms(
int &x,
int &y,
int &w,
int &h)
const
831 const int z = d->zoomLevel;
841 void KHTMLView::revertTransforms(
int &x,
int &y,
int &w,
int &h)
const
846 const int z = d->zoomLevel;
854 void KHTMLView::revertTransforms(
int &x,
int &y)
const
857 revertTransforms(
x,
y, dummy, dummy);
865 if (!m_part->xmlDocImpl()) {
866 resizeContentsToViewport();
870 if (m_part->xmlDocImpl() && m_part->xmlDocImpl()->styleSelector()->affectedByViewportChange()) {
874 if (d->layoutSchedulingEnabled) {
880 if (m_part && m_part->xmlDocImpl()) {
883 khtml::ChildFrame *cf = m_part->
parentPart()->frame(m_part);
884 if (cf && !cf->m_partContainerElement.isNull()) {
885 cf->m_partContainerElement.data()->postResizeEvent();
889 HTMLPartContainerElementImpl::sendPostedResizeEvents();
890 m_part->xmlDocImpl()->dispatchWindowEvent(EventImpl::RESIZE_EVENT,
false,
false);
910 p.scale(d->zoomLevel / 100., d->zoomLevel / 100.);
912 r.
setX(r.
x() * 100 / d->zoomLevel);
913 r.
setY(r.
y() * 100 / d->zoomLevel);
925 if (!m_part || !m_part->xmlDocImpl() || !m_part->xmlDocImpl()->renderer()) {
928 }
else if (d->complete &&
static_cast<RenderCanvas *
>(m_part->xmlDocImpl()->renderer())->needsLayout()) {
930 unscheduleRelayout();
932 }
else if (m_part->xmlDocImpl()->tokenizer()) {
933 m_part->xmlDocImpl()->tokenizer()->setNormalYieldDelay();
942 m_part->xmlDocImpl()->renderer()->layer()->paint(&p, r);
944 if (d->hasFrameset) {
945 NodeImpl *body =
static_cast<HTMLDocumentImpl *
>(m_part->xmlDocImpl())->body();
946 if (body && body->renderer() && body->id() == ID_FRAMESET) {
947 static_cast<RenderFrameSet *
>(body->renderer())->paintFrameSetRules(&p, r);
949 d->hasFrameset =
false;
953 khtml::DrawContentsEvent event(&p, ex, ey, ew, eh);
962 if (d->firstRepaintPending && !m_part->
parentPart()) {
963 qCDebug(KHTML_LOG) <<
"FIRST PAINT:" << m_part->d->m_parsetime.elapsed();
965 d->firstRepaintPending =
false;
976 void KHTMLView::setMarginHeight(
int h)
984 if (m_part && m_part->xmlDocImpl()) {
987 khtml::RenderCanvas *canvas =
static_cast<khtml::RenderCanvas *
>(document->renderer());
992 d->layoutSchedulingEnabled =
false;
993 d->dirtyLayout =
true;
997 RenderObject *root = document->documentElement() ? document->documentElement()->renderer() :
nullptr;
999 if (document->isHTMLDocument()) {
1000 NodeImpl *body =
static_cast<HTMLDocumentImpl *
>(document)->body();
1001 if (body && body->renderer() && body->id() == ID_FRAMESET) {
1004 body->renderer()->setNeedsLayout(
true);
1005 d->hasFrameset =
true;
1007 ref = (!body || root->style()->hidesOverflow()) ? root : body->renderer();
1013 if (ref->style()->overflowX() == OHIDDEN) {
1017 }
else if (ref->style()->overflowX() == OSCROLL) {
1024 if (ref->style()->overflowY() == OHIDDEN) {
1028 }
else if (ref->style()->overflowY() == OSCROLL) {
1036 d->needsFullRepaint = d->firstLayoutPending;
1039 d->needsFullRepaint =
true;
1047 if (d->firstLayoutPending) {
1050 d->firstLayoutPending =
false;
1056 if (d->accessKeysEnabled && d->accessKeysActivated) {
1057 emit hideAccessKeys();
1064 if (d->layoutTimerId) {
1067 d->layoutTimerId = 0;
1068 d->layoutSchedulingEnabled =
true;
1071 void KHTMLView::closeChildDialogs()
1074 foreach (
QDialog *dlg, dlgs) {
1082 d->m_dialogsAllowed =
false;
1085 bool KHTMLView::dialogsAllowed()
1087 bool allowed = d->m_dialogsAllowed;
1089 if (p && p->
view()) {
1090 allowed &= p->
view()->dialogsAllowed();
1097 closeChildDialogs();
1103 percent = percent < 20 ? 20 : (percent > 800 ? 800 : percent);
1104 int oldpercent = d->zoomLevel;
1105 d->zoomLevel = percent;
1106 if (percent != oldpercent) {
1107 if (d->layoutSchedulingEnabled) {
1116 return d->zoomLevel;
1121 d->smoothScrollMode = m;
1122 d->smoothScrollModeIsDefault =
false;
1123 if (d->smoothScrolling && !m) {
1128 void KHTMLView::setSmoothScrollingModeDefault(SmoothScrollingMode m)
1131 if (!d->smoothScrollModeIsDefault) {
1134 d->smoothScrollMode = m;
1135 if (d->smoothScrolling && !m) {
1142 return d->smoothScrollMode;
1150 void KHTMLView::mousePressEvent(
QMouseEvent *_mouse)
1152 if (!m_part->xmlDocImpl()) {
1156 mouseDoubleClickEvent(_mouse);
1160 int xm = _mouse->
x();
1161 int ym = _mouse->
y();
1162 revertTransforms(xm, ym);
1166 d->isDoubleClick =
false;
1168 DOM::NodeImpl::MouseEvent mev(_mouse->
buttons(), DOM::NodeImpl::MousePress);
1169 m_part->xmlDocImpl()->prepareMouseEvent(
false, xm, ym, &mev);
1174 !m_part->d->m_bOpenMiddleClick && !d->m_mouseScrollTimer &&
1175 mev.url.isNull() && (mev.innerNode.elementId() != ID_INPUT)) {
1178 d->m_mouseScroll_byX = 0;
1179 d->m_mouseScroll_byY = 0;
1181 d->m_mouseScrollTimer =
new QTimer(
this);
1182 connect(d->m_mouseScrollTimer, SIGNAL(timeout()),
this, SLOT(slotMouseScrollTimer()));
1184 if (!d->m_mouseScrollIndicator) {
1186 pixmap.
fill(
QColor(qRgba(127, 127, 127, 127)));
1191 option.rect.setRect(16, 0, 16, 16);
1193 option.rect.setRect(0, 16, 16, 16);
1195 option.rect.setRect(16, 32, 16, 16);
1197 option.rect.setRect(32, 16, 16, 16);
1199 p.drawEllipse(23, 23, 2, 2);
1201 d->m_mouseScrollIndicator =
new QWidget(
this);
1202 d->m_mouseScrollIndicator->setFixedSize(48, 48);
1204 palette.setBrush(d->m_mouseScrollIndicator->backgroundRole(),
QBrush(pixmap));
1205 d->m_mouseScrollIndicator->setPalette(
palette);
1207 d->m_mouseScrollIndicator->move(point.
x() - 24, point.
y() - 24);
1213 if (cg.readEntry(
"ShowMouseScrollIndicator",
true)) {
1214 d->m_mouseScrollIndicator->show();
1215 d->m_mouseScrollIndicator->unsetCursor();
1217 QBitmap mask = d->m_mouseScrollIndicator->palette().brush(d->m_mouseScrollIndicator->backgroundRole()).texture().createHeuristicMask(
true);
1219 if (hasHorBar && !hasVerBar) {
1223 painter.drawPixmap(
QRectF(16, 0, bm.width(), bm.height()), bm, bm.rect());
1224 painter.drawPixmap(
QRectF(16, 32, bm.width(), bm.height()), bm, bm.rect());
1226 }
else if (!hasHorBar && hasVerBar) {
1230 painter.drawPixmap(
QRectF(0, 16, bm.width(), bm.height()), bm, bm.rect());
1231 painter.drawPixmap(
QRectF(32, 16, bm.width(), bm.height()), bm, bm.rect());
1237 d->m_mouseScrollIndicator->setMask(
mask);
1239 if (hasHorBar && !hasVerBar) {
1241 }
else if (!hasHorBar && hasVerBar) {
1249 }
else if (d->m_mouseScrollTimer) {
1250 delete d->m_mouseScrollTimer;
1251 d->m_mouseScrollTimer =
nullptr;
1253 if (d->m_mouseScrollIndicator) {
1254 d->m_mouseScrollIndicator->hide();
1258 if (d->clickCount > 0 &&
1267 bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEDOWN_EVENT, mev.innerNode.handle(), mev.innerNonSharedNode.handle(),
true,
1268 d->clickCount, _mouse,
true, DOM::NodeImpl::MousePress);
1270 if (!swallowEvent) {
1273 khtml::MousePressEvent event(_mouse, xm, ym, mev.url, mev.target, mev.innerNode);
1279 void KHTMLView::mouseDoubleClickEvent(
QMouseEvent *_mouse)
1281 if (!m_part->xmlDocImpl()) {
1285 int xm = _mouse->
x();
1286 int ym = _mouse->
y();
1287 revertTransforms(xm, ym);
1291 d->isDoubleClick =
true;
1293 DOM::NodeImpl::MouseEvent mev(_mouse->
buttons(), DOM::NodeImpl::MouseDblClick);
1294 m_part->xmlDocImpl()->prepareMouseEvent(
false, xm, ym, &mev);
1298 if (d->clickCount > 0 &&
1306 bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEDOWN_EVENT, mev.innerNode.handle(), mev.innerNonSharedNode.handle(),
true,
1307 d->clickCount, _mouse,
true, DOM::NodeImpl::MouseDblClick);
1309 if (!swallowEvent) {
1310 khtml::MouseDoubleClickEvent event(_mouse, xm, ym, mev.url, mev.target, mev.innerNode, d->clickCount);
1314 d->possibleTripleClick =
true;
1318 void KHTMLView::tripleClickTimeout()
1320 d->possibleTripleClick =
false;
1327 (target.
toLower() !=
"_self") && (target.
toLower() !=
"_parent")) {
1328 if (target.
toLower() ==
"_blank") {
1342 void KHTMLView::mouseMoveEvent(
QMouseEvent *_mouse)
1344 if (d->m_mouseScrollTimer) {
1347 int deltaX = point.
x() - d->m_mouseScrollIndicator->x() - 24;
1348 int deltaY = point.
y() - d->m_mouseScrollIndicator->y() - 24;
1350 (deltaX > 0) ? d->m_mouseScroll_byX = 1 : d->m_mouseScroll_byX = -1;
1351 (deltaY > 0) ? d->m_mouseScroll_byY = 1 : d->m_mouseScroll_byY = -1;
1353 double adX = qAbs(deltaX) / 30.0;
1354 double adY = qAbs(deltaY) / 30.0;
1356 d->m_mouseScroll_byX = qMax(qMin(d->m_mouseScroll_byX *
int(adX * adX), SHRT_MAX), SHRT_MIN);
1357 d->m_mouseScroll_byY = qMax(qMin(d->m_mouseScroll_byY *
int(adY * adY), SHRT_MAX), SHRT_MIN);
1359 if (d->m_mouseScroll_byX == 0 && d->m_mouseScroll_byY == 0) {
1360 d->m_mouseScrollTimer->stop();
1361 }
else if (!d->m_mouseScrollTimer->isActive()) {
1362 d->m_mouseScrollTimer->start(20);
1366 if (!m_part->xmlDocImpl()) {
1370 int xm = _mouse->
x();
1371 int ym = _mouse->
y();
1372 revertTransforms(xm, ym);
1374 DOM::NodeImpl::MouseEvent mev(_mouse->
buttons(), DOM::NodeImpl::MouseMove);
1376 m_part->xmlDocImpl()->prepareMouseEvent(_mouse->
buttons() , xm, ym, &mev);
1382 DOM::NodeImpl *target = mev.innerNode.handle();
1383 DOM::NodeImpl *fn = m_part->xmlDocImpl()->focusNode();
1386 if (d->m_mouseEventsTarget && fn && fn->renderer() && fn->renderer()->isWidget()) {
1390 bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEMOVE_EVENT, target, mev.innerNonSharedNode.handle(),
false,
1391 0, _mouse,
true, DOM::NodeImpl::MouseMove);
1393 if (d->clickCount > 0 &&
1400 bool forceDefault =
false;
1401 if (r && r->isWidget()) {
1402 RenderWidget *rw =
static_cast<RenderWidget *
>(r);
1403 KHTMLWidget *kw = qobject_cast<KHTMLView *>(rw->widget()) ?
dynamic_cast<KHTMLWidget *
>(rw->widget()) :
nullptr;
1404 if (kw && kw->m_kwp->isRedirected()) {
1406 }
else if (
QLineEdit *le = qobject_cast<QLineEdit *>(rw->widget())) {
1411 forceDefault =
true;
1415 }
else if (
QTextEdit *te = qobject_cast<QTextEdit *>(rw->widget())) {
1416 if (te->verticalScrollBar()->underMouse() || te->horizontalScrollBar()->underMouse()) {
1417 forceDefault =
true;
1421 khtml::RenderStyle *
style = (r && r->style()) ? r->style() :
nullptr;
1423 LinkCursor linkCursor = LINK_NORMAL;
1424 switch (!forceDefault ? (
style ?
style->cursor() : CURSOR_AUTO) : CURSOR_DEFAULT) {
1426 if (r && r->isText() && ((m_part->d->m_bMousePressed && m_part->d->editor_context.m_beganSelectingText) ||
1427 !r->isPointInsideSelection(xm, ym, m_part->caret()))) {
1430 if (mev.url.length() && m_part->
settings()->changeCursor()) {
1432 if (mev.url.string().startsWith(
"mailto:") && mev.url.string().indexOf(
'@') > 0) {
1433 linkCursor = LINK_MAILTO;
1434 }
else if (targetOpensNewWindow(m_part, mev.target.string())) {
1435 linkCursor = LINK_NEWWINDOW;
1439 if (r && r->isFrameSet() && !
static_cast<RenderFrameSet *
>(r)->noResize()) {
1440 c =
QCursor(
static_cast<RenderFrameSet *
>(r)->cursorShape());
1447 case CURSOR_POINTER:
1449 if (mev.url.string().startsWith(
"mailto:") && mev.url.string().indexOf(
'@') > 0) {
1450 linkCursor = LINK_MAILTO;
1451 }
else if (targetOpensNewWindow(m_part, mev.target.string())) {
1452 linkCursor = LINK_NEWWINDOW;
1455 case CURSOR_PROGRESS:
1459 case CURSOR_ALL_SCROLL:
1462 case CURSOR_E_RESIZE:
1463 case CURSOR_W_RESIZE:
1464 case CURSOR_EW_RESIZE:
1467 case CURSOR_N_RESIZE:
1468 case CURSOR_S_RESIZE:
1469 case CURSOR_NS_RESIZE:
1472 case CURSOR_NE_RESIZE:
1473 case CURSOR_SW_RESIZE:
1474 case CURSOR_NESW_RESIZE:
1477 case CURSOR_NW_RESIZE:
1478 case CURSOR_SE_RESIZE:
1479 case CURSOR_NWSE_RESIZE:
1491 case CURSOR_DEFAULT:
1494 case CURSOR_NOT_ALLOWED:
1497 case CURSOR_ROW_RESIZE:
1500 case CURSOR_COL_RESIZE:
1503 case CURSOR_VERTICAL_TEXT:
1504 case CURSOR_CONTEXT_MENU:
1505 case CURSOR_NO_DROP:
1536 if (!d->cursorIconWidget) {
1539 XSetWindowAttributes attr;
1540 attr.save_under = True;
1541 XChangeWindowAttributes(QX11Info::display(), d->cursorIconWidget->winId(), CWSaveUnder, &attr);
1543 d->cursorIconWidget =
new QLabel(NULL, NULL);
1549 if (linkCursor != d->cursorIconType) {
1550 d->cursorIconType = linkCursor;
1552 switch (linkCursor) {
1553 case LINK_MAILTO: cursorIcon =
"mail-message-new";
break;
1554 case LINK_NEWWINDOW: cursorIcon =
"window-new";
break;
1555 default: cursorIcon =
"dialog-error";
break;
1560 d->cursorIconWidget->resize(icon_pixmap.
width(), icon_pixmap.
height());
1562 d->cursorIconWidget->setPixmap(icon_pixmap);
1563 d->cursorIconWidget->update();
1567 d->cursorIconWidget->move(c_pos.
x() + 15, c_pos.
y() + 15);
1569 XRaiseWindow(QX11Info::display(), d->cursorIconWidget->winId());
1571 #elif defined(Q_OS_WIN)
1572 SetWindowPos(d->cursorIconWidget->winId(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1576 d->cursorIconWidget->show();
1579 }
else if (d->cursorIconWidget) {
1580 d->cursorIconWidget->hide();
1583 if (r && r->isWidget()) {
1587 if (!swallowEvent) {
1588 khtml::MouseMoveEvent event(_mouse, xm, ym, mev.url, mev.target, mev.innerNode);
1593 void KHTMLView::mouseReleaseEvent(
QMouseEvent *_mouse)
1595 bool swallowEvent =
false;
1597 int xm = _mouse->
x();
1598 int ym = _mouse->
y();
1599 revertTransforms(xm, ym);
1601 DOM::NodeImpl::MouseEvent mev(_mouse->
buttons(), DOM::NodeImpl::MouseRelease);
1603 if (m_part->xmlDocImpl()) {
1604 m_part->xmlDocImpl()->prepareMouseEvent(
false, xm, ym, &mev);
1606 DOM::NodeImpl *target = mev.innerNode.handle();
1607 DOM::NodeImpl *fn = m_part->xmlDocImpl()->focusNode();
1610 if (d->m_mouseEventsTarget && fn && fn->renderer() && fn->renderer()->isWidget()) {
1614 swallowEvent = dispatchMouseEvent(EventImpl::MOUSEUP_EVENT, target, mev.innerNonSharedNode.handle(),
true,
1615 d->clickCount, _mouse,
false, DOM::NodeImpl::MouseRelease);
1618 if (d->m_mouseEventsTarget) {
1619 d->m_mouseEventsTarget =
nullptr;
1622 if (d->clickCount > 0 &&
1626 dispatchMouseEvent(EventImpl::CLICK_EVENT, mev.innerNode.handle(), mev.innerNonSharedNode.handle(),
true,
1627 d->clickCount, &me,
true, DOM::NodeImpl::MouseRelease);
1631 if (r && r->isWidget()) {
1636 if (!swallowEvent) {
1637 khtml::MouseReleaseEvent event(_mouse, xm, ym, mev.url, mev.target, mev.innerNode);
1643 bool KHTMLView::dispatchKeyEvent(
QKeyEvent *_ke)
1645 if (!m_part->xmlDocImpl()) {
1668 if (_ke == d->postponed_autorepeat) {
1674 bool ret = dispatchKeyEventHelper(_ke,
false);
1676 if (!ret && dispatchKeyEventHelper(_ke,
true)) {
1681 bool ret = dispatchKeyEventHelper(_ke,
true);
1682 if (!ret && d->postponed_autorepeat) {
1683 keyPressEvent(d->postponed_autorepeat);
1685 delete d->postponed_autorepeat;
1686 d->postponed_autorepeat =
nullptr;
1692 delete d->postponed_autorepeat;
1693 d->postponed_autorepeat =
nullptr;
1696 return dispatchKeyEventHelper(_ke,
false);
1701 d->postponed_autorepeat->accept();
1703 d->postponed_autorepeat->ignore();
1711 bool KHTMLView::dispatchKeyEventHelper(
QKeyEvent *_ke,
bool keypress)
1713 DOM::NodeImpl *keyNode = m_part->xmlDocImpl()->focusNode();
1715 return keyNode->dispatchKeyEvent(_ke, keypress);
1717 return m_part->xmlDocImpl()->dispatchKeyEvent(_ke, keypress);
1721 void KHTMLView::keyPressEvent(
QKeyEvent *_ke)
1725 d->accessKeysPreActivate =
true;
1731 d->scrollSuspendPreActivate =
true;
1737 if (d->accessKeysEnabled && d->accessKeysActivated) {
1741 accessKeysTimeout();
1743 handleAccessKey(_ke);
1747 accessKeysTimeout();
1752 if (dispatchKeyEvent(_ke)) {
1760 switch (_ke->
key()) {
1763 if (d->scrollSuspended) {
1764 d->newScrollTimer(
this, 0);
1770 d->adjustScroller(
this, KHTMLViewPrivate::ScrollDown, KHTMLViewPrivate::ScrollUp);
1775 d->adjustScroller(
this, KHTMLViewPrivate::ScrollUp, KHTMLViewPrivate::ScrollDown);
1780 d->adjustScroller(
this, KHTMLViewPrivate::ScrollLeft, KHTMLViewPrivate::ScrollRight);
1785 d->adjustScroller(
this, KHTMLViewPrivate::ScrollRight, KHTMLViewPrivate::ScrollLeft);
1789 switch (_ke->
key()) {
1792 if (!d->scrollTimerId || d->scrollSuspended) {
1795 if (d->scrollTimerId) {
1796 d->newScrollTimer(
this, 0);
1802 d->shouldSmoothScroll =
true;
1804 if (d->scrollSuspended) {
1805 d->newScrollTimer(
this, 0);
1811 if (!d->scrollTimerId || d->scrollSuspended) {
1814 if (d->scrollTimerId) {
1815 d->newScrollTimer(
this, 0);
1820 d->shouldSmoothScroll =
true;
1822 if (d->scrollSuspended) {
1823 d->newScrollTimer(
this, 0);
1828 if (!d->scrollTimerId || d->scrollSuspended) {
1831 if (d->scrollTimerId) {
1832 d->newScrollTimer(
this, 0);
1838 if (!d->scrollTimerId || d->scrollSuspended) {
1841 if (d->scrollTimerId) {
1842 d->newScrollTimer(
this, 0);
1849 if (m_part->xmlDocImpl()) {
1850 NodeImpl *n = m_part->xmlDocImpl()->focusNode();
1859 if (d->scrollSuspended) {
1860 d->newScrollTimer(
this, 0);
1865 if (d->scrollSuspended) {
1866 d->newScrollTimer(
this, 0);
1874 if (d->scrollTimerId) {
1875 d->newScrollTimer(
this, 0);
1884 void KHTMLView::keyReleaseEvent(
QKeyEvent *_ke)
1887 d->scrollSuspendPreActivate =
false;
1890 if (d->scrollTimerId) {
1891 d->scrollSuspended = !d->scrollSuspended;
1892 if (d->scrollSuspended) {
1897 if (d->accessKeysEnabled) {
1899 d->accessKeysPreActivate =
false;
1903 m_part->setStatusBarText(
i18n(
"Access Keys activated"), KHTMLPart::BarOverrideText);
1904 d->accessKeysActivated =
true;
1905 d->accessKeysPreActivate =
false;
1908 }
else if (d->accessKeysActivated) {
1909 accessKeysTimeout();
1916 if (dispatchKeyEvent(_ke)) {
1924 bool KHTMLView::focusNextPrevChild(
bool next)
1927 if (m_part->xmlDocImpl() && focusNextPrevNode(next)) {
1935 d->pseudoFocusNode = KHTMLViewPrivate::PFNone;
1943 void KHTMLView::doAutoScroll()
1947 KHTMLView *v = m_kwp->isRedirected() ? m_kwp->rootViewPos(off) :
this;
1958 #ifndef KHTML_NO_SELECTION
1961 if (m_part->isExtendingSelection()) {
1962 RenderObject::NodeInfo renderInfo(
true,
false);
1963 m_part->xmlDocImpl()->renderer()->layer()
1964 ->nodeAtPoint(renderInfo, xm, ym);
1965 innerNode = renderInfo.innerNode();
1968 if (innerNode.
handle() && innerNode.
handle()->renderer()
1969 && innerNode.
handle()->renderer()->shouldSelect()) {
1970 m_part->extendSelectionTo(xm, ym, innerNode);
1972 #endif // KHTML_NO_SELECTION
1999 if (!qobject_cast<QFrame *>(w)) {
2005 if (!(w->
objectName() ==
"KLineEditButton")) {
2014 if (qobject_cast<KHTMLView *>(w)) {
2015 handleWidget(
static_cast<KHTMLView *
>(w)->widget(), view,
false);
2016 handleWidget(
static_cast<KHTMLView *
>(w)->horizontalScrollBar(), view,
false);
2017 handleWidget(
static_cast<KHTMLView *
>(w)->verticalScrollBar(), view,
false);
2021 QObjectList children = w->
children();
2022 foreach (
QObject *
object, children) {
2023 QWidget *widget = qobject_cast<QWidget *>(
object);
2025 handleWidget(widget, view);
2030 class KHTMLBackingStoreHackWidget :
public QWidget
2033 void publicEvent(
QEvent *e)
2039 bool KHTMLView::viewportEvent(
QEvent *e)
2041 switch (e->
type()) {
2048 #ifndef QT_NO_WHEELEVENT
2063 static void setInPaintEventFlag(
QWidget *w,
bool b =
true,
bool recurse =
true)
2070 if (qobject_cast<KHTMLView *>(w)) {
2071 setInPaintEventFlag(
static_cast<KHTMLView *
>(w)->widget(), b,
false);
2072 setInPaintEventFlag(
static_cast<KHTMLView *
>(w)->horizontalScrollBar(), b,
false);
2073 setInPaintEventFlag(
static_cast<KHTMLView *
>(w)->verticalScrollBar(), b,
false);
2080 setInPaintEventFlag(
static_cast<QWidget *
>(cw), b);
2090 || (m_part->xmlDocImpl() && m_part->xmlDocImpl()->focusNode()
2091 && m_part->xmlDocImpl()->focusNode()->isContentEditable())) {
2093 switch (ke->
key()) {
2110 if (d->cursorIconWidget) {
2111 d->cursorIconWidget->hide();
2113 m_part->resetHoverText();
2118 if (widgetEvent(e)) {
2127 while (v && v != view) {
2131 KHTMLWidget *k =
dynamic_cast<KHTMLWidget *
>(c);
2132 if (v && k && k->m_kwp->isRedirected()) {
2135 switch (e->
type()) {
2138 static_cast<KHTMLBackingStoreHackWidget *
>(w)->publicEvent(e);
2145 if (!allowWidgetPaintEvents) {
2157 QPoint ap = k->m_kwp->absolutePos();
2167 if (0 && w->
parentWidget() == view && !qobject_cast<QScrollBar *>(w) && !::qobject_cast<QScrollBar *>(w)) {
2173 mouseMoveEvent(&me2);
2175 mousePressEvent(&me2);
2177 mouseReleaseEvent(&me2);
2179 mouseDoubleClickEvent(&me2);
2187 if (w->
parentWidget() == view && !qobject_cast<QScrollBar *>(w)) {
2193 keyReleaseEvent(ke);
2199 if (qobject_cast<KUrlRequester *>(w->
parentWidget()) &&
2213 KHTMLView *root = m_kwp->rootViewPos(dummy);
2234 bool KHTMLView::widgetEvent(
QEvent *e)
2236 switch (e->
type()) {
2242 #ifndef QT_NO_WHEELEVENT
2259 KHTMLWidget *k =
dynamic_cast<KHTMLWidget *
>(w);
2260 if (k && k->m_kwp->isRedirected()) {
2262 handleWidget(w,
this);
2282 bool KHTMLView::hasLayoutPending()
2284 return d->layoutTimerId && !d->firstLayoutPending;
2287 DOM::NodeImpl *KHTMLView::nodeUnderMouse()
const
2289 return d->underMouse;
2292 DOM::NodeImpl *KHTMLView::nonSharedNodeUnderMouse()
const
2294 return d->underMouseNonShared;
2297 bool KHTMLView::scrollTo(
const QRect &bounds)
2299 d->scrollingSelf =
true;
2304 xe = bounds.
right();
2315 if (ye -
y > curHeight - d->borderY) {
2316 ye =
y + curHeight - d->borderY;
2319 if (xe -
x > curWidth - d->borderX) {
2320 xe =
x + curWidth - d->borderX;
2328 else if (xe + d->borderX >
contentsX() + curWidth) {
2329 deltax = xe + d->borderX - (
contentsX() + curWidth);
2339 else if (ye + d->borderY >
contentsY() + curHeight) {
2340 deltay = ye + d->borderY - (
contentsY() + curHeight);
2345 int maxx = curWidth - d->borderX;
2346 int maxy = curHeight - d->borderY;
2348 int scrollX, scrollY;
2350 scrollX = deltax > 0 ? (deltax > maxx ? maxx : deltax) : deltax == 0 ? 0 : (deltax > -maxx ? deltax : -maxx);
2351 scrollY = deltay > 0 ? (deltay > maxy ? maxy : deltay) : deltay == 0 ? 0 : (deltay > -maxy ? deltay : -maxy);
2368 d->scrollingSelf =
false;
2370 if ((abs(deltax) <= maxx) && (abs(deltay) <= maxy)) {
2378 bool KHTMLView::focusNextPrevNode(
bool next)
2388 NodeImpl *oldFocusNode = doc->focusNode();
2395 if ((oldFocusNode->renderer() && !oldFocusNode->renderer()->parent())
2396 || !oldFocusNode->isTabFocusable()) {
2397 doc->quietResetFocus();
2406 if (d->scrollBarMoved) {
2414 if (!toFocus && oldFocusNode) {
2422 while (toFocus && toFocus != oldFocusNode) {
2428 QRect r = toFocus->getRect();
2431 d->scrollBarMoved =
false;
2432 d->tabMovePending =
false;
2433 d->lastTabbingDirection =
next;
2434 d->pseudoFocusNode = KHTMLViewPrivate::PFNone;
2435 m_part->xmlDocImpl()->setFocusNode(toFocus);
2436 Node guard(toFocus);
2437 if (!toFocus->hasOneRef()) {
2449 if (!toFocus && oldFocusNode) {
2458 d->scrollBarMoved =
false;
2462 if (!oldFocusNode && d->pseudoFocusNode == KHTMLViewPrivate::PFNone) {
2464 d->scrollBarMoved =
false;
2465 d->pseudoFocusNode =
next ? KHTMLViewPrivate::PFTop : KHTMLViewPrivate::PFBottom;
2469 NodeImpl *newFocusNode =
nullptr;
2471 if (d->tabMovePending && next != d->lastTabbingDirection) {
2473 newFocusNode = oldFocusNode;
2475 if (oldFocusNode || d->pseudoFocusNode == KHTMLViewPrivate::PFTop) {
2479 if (oldFocusNode || d->pseudoFocusNode == KHTMLViewPrivate::PFBottom) {
2484 bool targetVisible =
false;
2485 if (!newFocusNode) {
2493 if (!m_part->
isCaretMode() && newFocusNode->isContentEditable()) {
2495 m_part->clearCaretRectIfNeeded();
2496 m_part->d->editor_context.m_selection.moveTo(Position(newFocusNode, 0L));
2502 m_part->notifySelectionChanged();
2504 targetVisible = scrollTo(newFocusNode->getRect());
2507 if (targetVisible) {
2509 d->tabMovePending =
false;
2511 m_part->xmlDocImpl()->setFocusNode(newFocusNode);
2513 Node guard(newFocusNode);
2514 if (!newFocusNode->hasOneRef()) {
2519 d->pseudoFocusNode =
next ? KHTMLViewPrivate::PFBottom : KHTMLViewPrivate::PFTop;
2523 if (!d->tabMovePending) {
2524 d->lastTabbingDirection =
next;
2526 d->tabMovePending =
true;
2541 if (use_fallbacks) {
2542 fallbacks = buildFallbackAccessKeys();
2544 for (NodeImpl *n = m_part->xmlDocImpl(); n !=
nullptr; n = n->traverseNextNode()) {
2545 if (n->isElementNode()) {
2546 ElementImpl *en =
static_cast< ElementImpl *
>(n);
2547 DOMString s = en->getAttribute(ATTR_ACCESSKEY);
2549 if (s.length() == 1) {
2551 if (qFind(taken.
begin(), taken.
end(), a) == taken.
end()) {
2556 QChar a = fallbacks[ en ].toUpper();
2557 if (qFind(taken.
begin(), taken.
end(), a) == taken.
end()) {
2558 accesskey =
QString(
"<qt><i>") + a +
"</i></qt>";
2561 if (!accesskey.
isNull()) {
2566 connect(origview, SIGNAL(hideAccessKeys()), lab, SLOT(
close()));
2567 connect(
this, SIGNAL(repaintAccessKeys()), lab, SLOT(
repaint()));
2579 taken.
append(accesskey[ 0 ]);
2583 if (use_fallbacks) {
2589 if (!qobject_cast<KHTMLPart *>(cur)) {
2605 bool KHTMLView::isScrollingFromMouseWheel()
const
2607 return d->scrollingFromWheel !=
QPoint(-1, -1);
2610 void KHTMLView::accessKeysTimeout()
2612 d->accessKeysActivated =
false;
2613 d->accessKeysPreActivate =
false;
2614 m_part->setStatusBarText(
QString(), KHTMLPart::BarOverrideText);
2615 emit hideAccessKeys();
2619 bool KHTMLView::handleAccessKey(
const QKeyEvent *ev)
2632 c = ev->
text()[ 0 ];
2638 return focusNodeWithAccessKey(c);
2641 bool KHTMLView::focusNodeWithAccessKey(
QChar c,
KHTMLView *caller)
2647 ElementImpl *node = doc->findAccessKeyElement(c);
2651 if (!qobject_cast<KHTMLPart *>(cur)) {
2656 &&
part->
view()->focusNodeWithAccessKey(c,
this)) {
2663 && m_part->
parentPart()->
view()->focusNodeWithAccessKey(c,
this)) {
2666 if (caller ==
nullptr) {
2669 it != fallbacks.
end();
2676 if (node ==
nullptr) {
2688 if (node->isFocusable()) {
2689 if (node->id() == ID_LABEL) {
2691 node =
static_cast<ElementImpl *
>(
static_cast< HTMLLabelElementImpl *
>(node)->getFormElement());
2698 m_part->xmlDocImpl()->setFocusNode(node);
2700 if (node !=
nullptr && node->hasOneRef()) {
2704 if (node !=
nullptr && node->hasOneRef()) {
2709 switch (node->id()) {
2711 static_cast< HTMLAnchorElementImpl *
>(node)->click();
2714 static_cast< HTMLInputElementImpl *
>(node)->click();
2717 static_cast< HTMLButtonElementImpl *
>(node)->click();
2720 static_cast< HTMLAreaElementImpl *
>(node)->click();
2731 static QString getElementText(NodeImpl *
start,
bool after)
2734 for (NodeImpl *n = after ?
start->nextSibling() :
start->traversePreviousNode();
2736 n = after ? n->traverseNextNode() : n->traversePreviousNode()) {
2737 if (n->isTextNode()) {
2739 ret +=
static_cast< TextImpl *
>(n)->
toString().string();
2741 ret.
prepend(
static_cast< TextImpl *
>(n)->toString().string());
2787 for (NodeImpl *n =
start;
2789 n = n->traverseNextNode()) {
2790 if (n->id() == ID_LABEL) {
2791 HTMLLabelElementImpl *
label =
static_cast< HTMLLabelElementImpl *
>(n);
2792 NodeImpl *labelfor =
label->getFormElement();
2803 struct AccessKeyData {
2804 ElementImpl *element;
2819 for (NodeImpl *n = m_part->xmlDocImpl();
2821 n = n->traverseNextNode()) {
2822 if (n->isElementNode()) {
2823 ElementImpl *element =
static_cast< ElementImpl *
>(n);
2824 if (element->renderer() ==
nullptr) {
2830 bool ignore =
false;
2831 bool text_after =
false;
2832 bool text_before =
false;
2833 switch (element->id()) {
2835 url = element->getAttribute(ATTR_HREF).trimSpaces().string();
2839 text =
static_cast< HTMLElementImpl *
>(element)->innerText().string().
simplified();
2843 HTMLInputElementImpl *in =
static_cast< HTMLInputElementImpl *
>(element);
2844 switch (in->inputType()) {
2845 case HTMLInputElementImpl::SUBMIT:
2846 text = in->value().string();
2848 text =
i18n(
"Submit");
2852 case HTMLInputElementImpl::IMAGE:
2853 text = in->altText().string();
2856 case HTMLInputElementImpl::BUTTON:
2857 text = in->value().string();
2860 case HTMLInputElementImpl::RESET:
2861 text = in->value().string();
2863 text =
i18n(
"Reset");
2867 case HTMLInputElementImpl::HIDDEN:
2870 case HTMLInputElementImpl::CHECKBOX:
2871 case HTMLInputElementImpl::RADIO:
2875 case HTMLInputElementImpl::TEXT:
2876 case HTMLInputElementImpl::PASSWORD:
2877 case HTMLInputElementImpl::FILE:
2888 text =
static_cast< HTMLElementImpl *
>(element)->innerText().string().
simplified();
2889 switch (
static_cast< HTMLButtonElementImpl *
>(element)->buttonType()) {
2890 case HTMLButtonElementImpl::SUBMIT:
2892 text =
i18n(
"Submit");
2896 case HTMLButtonElementImpl::RESET:
2898 text =
i18n(
"Reset");
2916 ignore = !element->isFocusable();
2925 DOMString akey = element->getAttribute(ATTR_ACCESSKEY);
2926 if (akey.length() == 1) {
2927 hrefs[url] = akey.string()[ 0 ].
toUpper();
2931 text = labels[ element ];
2933 if (text.
isNull() && text_before) {
2934 text = getElementText(element,
false);
2936 if (text.
isNull() && text_after) {
2937 text = getElementText(element,
true);
2942 = m_part->
settings()->fallbackAccessKeysAssignments();
2944 it != priorities.
end();
2946 if (text == (*it).first) {
2950 AccessKeyData tmp = { element, text, url, priority };
2956 for (
char c =
'A'; c <=
'Z'; ++c) {
2959 for (
char c =
'0'; c <=
'9'; ++c) {
2962 for (NodeImpl *n = m_part->xmlDocImpl();
2964 n = n->traverseNextNode()) {
2965 if (n->isElementNode()) {
2966 ElementImpl *en =
static_cast< ElementImpl *
>(n);
2967 DOMString s = en->getAttribute(ATTR_ACCESSKEY);
2968 if (s.length() == 1) {
2976 for (
int priority = 10; priority >= 0; --priority) {
2980 if ((*it).priority != priority) {
2989 const QString url = (*it).url;
2992 it = data.
erase(it);
2997 = m_part->
settings()->fallbackAccessKeysAssignments();
2999 it != priorities.
end();
3001 if (text == (*it).first && keys.
contains((*it).second)) {
3014 if (keys.
contains((*it)[ 0 ].toUpper())) {
3021 for (
int i = 0; i < text.
length(); ++i) {
3022 if (keys.
contains(text[ i ].toUpper())) {
3031 ret[(*it).element ] = key;
3033 it = data.
erase(it);
3039 if ((*it2).url == url) {
3040 ret[(*it2).element ] = key;
3044 it2 = data.
erase(it2);
3055 void KHTMLView::setMediaType(
const QString &medium)
3060 QString KHTMLView::mediaType()
const
3065 bool KHTMLView::pagedMode()
const
3070 void KHTMLView::setWidgetVisible(RenderWidget *w,
bool vis)
3073 d->visibleWidgets.insert(w, w->widget());
3075 d->visibleWidgets.remove(w);
3079 bool KHTMLView::needsFullRepaint()
const
3081 return d->needsFullRepaint;
3086 class QPointerDeleter
3089 explicit QPointerDeleter(
QObject *o) : obj(o) {}
3102 print(&printer, quick);
3107 if (!m_part->xmlDocImpl()) {
3110 khtml::RenderCanvas *root =
static_cast<khtml::RenderCanvas *
>(m_part->xmlDocImpl()->renderer());
3120 const QPointerDeleter dialogDeleter(dialog);
3127 if (quick || (dialog->exec() && dialog)) {
3131 printer.
setCreator(
QString(
"KDE %1.%2.%3 HTML Library").arg(KHTML_VERSION_MAJOR).arg(KHTML_VERSION_MINOR).arg(KHTML_VERSION_PATCH));
3136 khtml::setPrintPainter(p);
3138 m_part->xmlDocImpl()->setPaintDevice(&printer);
3139 QString oldMediaType = mediaType();
3140 setMediaType(
"print");
3144 m_part->xmlDocImpl()->setPrintStyleSheet(printSettings->printFriendly() ?
3145 "* { background-image: none !important;"
3146 " background-color: white !important;"
3147 " color: black !important; }"
3148 "body { margin: 0px !important; }"
3149 "html { margin: 0px !important; }" :
3150 "body { margin: 0px !important; }"
3151 "html { margin: 0px !important; }"
3156 root->setStaticMode(
true);
3157 root->setPagedMode(
true);
3158 root->setWidth(printer.
width());
3160 root->setPageTop(0);
3161 root->setPageBottom(0);
3164 m_part->xmlDocImpl()->styleSelector()->computeFontSizes(printer.
logicalDpiY(), 100);
3166 root->setPrintImages(printSettings->printImages());
3167 root->makePageBreakAvoidBlocks();
3169 root->setNeedsLayoutAndMinMaxRecalc();
3174 bool printHeader = printSettings->printHeader();
3176 int headerHeight = 0;
3177 QFont headerFont(
"Sans Serif", 8);
3197 int pageWidth = printer.
width();
3198 int pageHeight = printer.
height();
3201 pageHeight -= headerHeight;
3203 #ifndef QT_NO_TRANSFORMATIONS
3204 bool scalePage =
false;
3206 if (root->docWidth() > printer.
width()) {
3208 scale = ((double) printer.
width()) / ((
double) root->docWidth());
3209 pageHeight = (int)(pageHeight / scale);
3210 pageWidth = (int)(pageWidth / scale);
3211 headerHeight = (int)(headerHeight / scale);
3217 root->setHeight(pageHeight);
3218 root->setPageBottom(pageHeight);
3219 root->setNeedsLayout(
true);
3220 root->layoutIfNeeded();
3225 int available_width = printer.
width() - 10 -
3228 if (available_width < 150) {
3229 available_width = 150;
3237 }
while (mid_width > available_width);
3243 while (top < root->docHeight()) {
3247 #ifndef QT_NO_TRANSFORMATIONS
3249 p->
scale(scale, scale);
3269 bottom = top + pageHeight;
3271 root->setPageTop(top);
3272 root->setPageBottom(bottom);
3273 root->setPageNumber(page);
3275 root->layer()->paint(p,
QRect(0, top, pageWidth, pageHeight));
3287 root->setPagedMode(
false);
3288 root->setStaticMode(
false);
3290 khtml::setPrintPainter(
nullptr);
3291 setMediaType(oldMediaType);
3292 m_part->xmlDocImpl()->setPaintDevice(
this);
3293 m_part->xmlDocImpl()->styleSelector()->computeFontSizes(m_part->xmlDocImpl()->logicalDpiY(), m_part->
fontScaleFactor());
3299 void KHTMLView::slotPaletteChanged()
3301 if (!m_part->xmlDocImpl()) {
3305 if (!document->isHTMLDocument()) {
3308 khtml::RenderCanvas *root =
static_cast<khtml::RenderCanvas *
>(document->renderer());
3312 root->
style()->resetPalette();
3313 NodeImpl *body =
static_cast<HTMLDocumentImpl *
>(document)->body();
3317 body->setChanged(
true);
3318 body->recalcStyle(NodeImpl::Force);
3321 void KHTMLView::paint(
QPainter *p,
const QRect &rc,
int yOff,
bool *more)
3323 if (!m_part->xmlDocImpl()) {
3326 khtml::RenderCanvas *root =
static_cast<khtml::RenderCanvas *
>(m_part->xmlDocImpl()->renderer());
3331 d->firstRepaintPending =
false;
3334 QPaintDevice *opd = m_part->xmlDocImpl()->paintDevice();
3335 m_part->xmlDocImpl()->setPaintDevice(p->
device());
3336 root->setPagedMode(
true);
3337 root->setStaticMode(
true);
3338 root->setWidth(rc.
width());
3350 double scale = ((double) rc.
width() / (double) root->docWidth());
3352 #ifndef QT_NO_TRANSFORMATIONS
3353 p->
scale(scale, scale);
3355 root->setPageTop(yOff);
3356 root->setPageBottom(yOff +
height);
3358 root->layer()->paint(p,
QRect(0, yOff, root->docWidth(),
height));
3360 *more = yOff +
height < root->docHeight();
3375 root->setPagedMode(
false);
3376 root->setStaticMode(
false);
3377 m_part->xmlDocImpl()->setPaintDevice(opd);
3383 d->firstRepaintPending =
false;
3386 if (!m_part || !m_part->xmlDocImpl() || !m_part->xmlDocImpl()->renderer()) {
3390 QPaintDevice *opd = m_part->xmlDocImpl()->paintDevice();
3391 m_part->xmlDocImpl()->setPaintDevice(p->
device());
3405 m_part->xmlDocImpl()->renderer()->layer()->paint(p,
rect);
3419 m_part->xmlDocImpl()->setPaintDevice(opd);
3422 void KHTMLView::setHasStaticBackground(
bool partial)
3425 if (d->staticWidget == KHTMLViewPrivate::SBFull && m_kwp->isRedirected()) {
3429 d->staticWidget = partial ?
3430 KHTMLViewPrivate::SBPartial : KHTMLViewPrivate::SBFull;
3433 void KHTMLView::setHasNormalBackground()
3436 if (d->staticWidget == KHTMLViewPrivate::SBFull && m_kwp->isRedirected()) {
3440 d->staticWidget = KHTMLViewPrivate::SBNone;
3443 void KHTMLView::addStaticObject(
bool fixed)
3446 d->fixedObjectsCount++;
3448 d->staticObjectsCount++;
3451 setHasStaticBackground(
true );
3454 void KHTMLView::removeStaticObject(
bool fixed)
3457 d->fixedObjectsCount--;
3459 d->staticObjectsCount--;
3462 assert(d->fixedObjectsCount >= 0 && d->staticObjectsCount >= 0);
3464 if (!d->staticObjectsCount && !d->fixedObjectsCount) {
3465 setHasNormalBackground();
3467 setHasStaticBackground(
true );
3473 #ifndef KHTML_NO_SCROLLBARS
3474 d->vpolicy = policy;
3483 #ifndef KHTML_NO_SCROLLBARS
3484 d->hpolicy = policy;
3491 void KHTMLView::restoreScrollBar()
3503 if (!m_part->
settings()->isFormCompletionEnabled()) {
3506 if (!d->formCompletions) {
3509 return d->formCompletions->group(
"").readEntry(name,
QStringList());
3512 void KHTMLView::clearCompletionHistory(
const QString &name)
3514 if (!d->formCompletions) {
3517 d->formCompletions->group(
"").writeEntry(name,
"");
3518 d->formCompletions->sync();
3521 void KHTMLView::addFormCompletionItem(
const QString &name,
const QString &value)
3523 if (!m_part->
settings()->isFormCompletionEnabled()) {
3529 bool cc_number(
true);
3530 for (
int i = 0; i < value.
length(); ++i) {
3544 while ((
int)items.
count() > m_part->
settings()->maxFormCompletionItems()) {
3547 d->formCompletions->group(
"").writeEntry(name, items);
3550 void KHTMLView::addNonPasswordStorableSite(
const QString &
host)
3552 if (!d->formCompletions) {
3556 KConfigGroup cg(d->formCompletions,
"NonPasswordStorableSites");
3559 cg.writeEntry(
"Sites", sites);
3563 void KHTMLView::delNonPasswordStorableSite(
const QString &
host)
3565 if (!d->formCompletions) {
3569 KConfigGroup cg(d->formCompletions,
"NonPasswordStorableSites");
3572 cg.writeEntry(
"Sites", sites);
3576 bool KHTMLView::nonPasswordStorableSite(
const QString &
host)
const
3578 if (!d->formCompletions) {
3581 QStringList sites = d->formCompletions->group(
"NonPasswordStorableSites").readEntry(
"Sites",
QStringList());
3586 bool KHTMLView::dispatchMouseEvent(
int eventId, DOM::NodeImpl *targetNode,
3587 DOM::NodeImpl *targetNodeNonShared,
bool cancelable,
3589 int mouseEventType,
int orient)
3592 if (targetNode && targetNode->isTextNode()) {
3593 targetNode = targetNode->parentNode();
3596 if (d->underMouse) {
3597 d->underMouse->deref();
3599 d->underMouse = targetNode;
3600 if (d->underMouse) {
3601 d->underMouse->ref();
3604 if (d->underMouseNonShared) {
3605 d->underMouseNonShared->deref();
3607 d->underMouseNonShared = targetNodeNonShared;
3608 if (d->underMouseNonShared) {
3609 d->underMouseNonShared->ref();
3612 bool isWheelEvent = (mouseEventType == DOM::NodeImpl::MouseWheel);
3614 int exceptioncode = 0;
3615 int pageX = _mouse->
x();
3616 int pageY = _mouse->
y();
3617 revertTransforms(pageX, pageY);
3620 int screenX = _mouse->
globalX();
3621 int screenY = _mouse->
globalY();
3623 switch (_mouse->
button()) {
3636 if (d->accessKeysEnabled && d->accessKeysPreActivate && button != -1) {
3637 d->accessKeysPreActivate =
false;
3646 if (setUnder && d->oldUnderMouse != targetNode) {
3647 if (d->oldUnderMouse && d->oldUnderMouse->document() != m_part->xmlDocImpl()) {
3648 d->oldUnderMouse->deref();
3649 d->oldUnderMouse =
nullptr;
3652 if (d->oldUnderMouse) {
3654 MouseEventImpl *me =
new MouseEventImpl(EventImpl::MOUSEOUT_EVENT,
3655 true,
true, m_part->xmlDocImpl()->defaultView(),
3656 0, screenX, screenY, clientX, clientY, pageX, pageY,
3657 ctrlKey, altKey, shiftKey, metaKey,
3658 button, targetNode);
3660 d->oldUnderMouse->dispatchEvent(me, exceptioncode,
true);
3665 MouseEventImpl *me =
new MouseEventImpl(EventImpl::MOUSEOVER_EVENT,
3666 true,
true, m_part->xmlDocImpl()->defaultView(),
3667 0, screenX, screenY, clientX, clientY, pageX, pageY,
3668 ctrlKey, altKey, shiftKey, metaKey,
3669 button, d->oldUnderMouse);
3672 targetNode->dispatchEvent(me, exceptioncode,
true);
3675 if (d->oldUnderMouse) {
3676 d->oldUnderMouse->deref();
3678 d->oldUnderMouse = targetNode;
3679 if (d->oldUnderMouse) {
3680 d->oldUnderMouse->ref();
3684 bool swallowEvent =
false;
3688 if (targetNode->isGenericFormElement()
3689 &&
static_cast<HTMLGenericFormElementImpl *
>(targetNode)->disabled()) {
3694 bool dblclick = (eventId == EventImpl::CLICK_EVENT &&
3696 MouseEventImpl *me =
new MouseEventImpl(
static_cast<EventImpl::EventId
>(eventId),
3697 true, cancelable, m_part->xmlDocImpl()->defaultView(),
3698 detail, screenX, screenY, clientX, clientY, pageX, pageY,
3699 ctrlKey, altKey, shiftKey, metaKey,
3700 button,
nullptr, isWheelEvent ?
nullptr : _mouse, dblclick,
3701 isWheelEvent ?
static_cast<MouseEventImpl::Orientation
>(orient) : MouseEventImpl::ONone);
3703 if (!d->m_mouseEventsTarget && RenderLayer::gScrollBar && eventId == EventImpl::MOUSEDOWN_EVENT)
3706 d->m_mouseEventsTarget = RenderLayer::gScrollBar;
3708 if (d->m_mouseEventsTarget && qobject_cast<QScrollBar *>(d->m_mouseEventsTarget) &&
3709 dynamic_cast<KHTMLWidget *
>(
static_cast<QWidget *
>(d->m_mouseEventsTarget))) {
3712 KHTMLWidget *w =
dynamic_cast<KHTMLWidget *
>(
static_cast<QWidget *
>(d->m_mouseEventsTarget));
3713 QPoint p = w->m_kwp->absolutePos();
3715 static_cast<RenderWidget::EventPropagator *
>(
static_cast<QWidget *
>(d->m_mouseEventsTarget))->sendEvent(&fw);
3718 static_cast<RenderWidget::EventPropagator *
>(
static_cast<QWidget *
>(d->m_mouseEventsTarget))->sendEvent(&cme);
3719 d->m_mouseEventsTarget =
nullptr;
3721 swallowEvent =
true;
3723 targetNode->dispatchEvent(me, exceptioncode,
true);
3724 bool defaultHandled = me->defaultHandled();
3725 if (defaultHandled || me->defaultPrevented()) {
3726 swallowEvent =
true;
3729 if (eventId == EventImpl::MOUSEDOWN_EVENT && !me->defaultPrevented()) {
3734 DOM::NodeImpl *nodeImpl = targetNode;
3735 for (; nodeImpl && !nodeImpl->isFocusable(); nodeImpl = nodeImpl->parentNode()) {
3737 if (nodeImpl && nodeImpl->isMouseFocusable()) {
3738 m_part->xmlDocImpl()->setFocusNode(nodeImpl);
3739 }
else if (!nodeImpl || !nodeImpl->focused()) {
3740 m_part->xmlDocImpl()->setFocusNode(
nullptr);
3746 return swallowEvent;
3749 void KHTMLView::setIgnoreWheelEvents(
bool e)
3751 d->ignoreWheelEvents = e;
3754 #ifndef QT_NO_WHEELEVENT
3760 if (d->scrollingFromWheel !=
QPoint(-1, -1) && d->scrollingFromWheel !=
QCursor::pos()) {
3761 d->scrollingFromWheel = d->scrollingFromWheelTimerId ?
QCursor::pos() :
QPoint(-1, -1);
3764 if (d->accessKeysEnabled && d->accessKeysPreActivate) {
3765 d->accessKeysPreActivate =
false;
3769 emit zoomView(- e->
delta());
3771 }
else if (d->firstLayoutPending) {
3773 }
else if (!m_kwp->isRedirected() &&
3791 revertTransforms(xm, ym);
3793 DOM::NodeImpl::MouseEvent mev(e->
buttons(), DOM::NodeImpl::MouseWheel);
3794 m_part->xmlDocImpl()->prepareMouseEvent(
false, xm, ym, &mev);
3796 MouseEventImpl::Orientation o = MouseEventImpl::OVertical;
3798 o = MouseEventImpl::OHorizontal;
3802 bool swallow = dispatchMouseEvent(EventImpl::KHTML_MOUSEWHEEL_EVENT, mev.innerNode.handle(), mev.innerNonSharedNode.handle(),
3803 true, -e->
delta() / 40, &_mouse,
true, DOM::NodeImpl::MouseWheel, o);
3809 d->scrollBarMoved =
true;
3811 if (d->smoothScrollMode != SSMDisabled) {
3812 d->shouldSmoothScroll =
true;
3814 if (d->scrollingFromWheelTimerId) {
3815 killTimer(d->scrollingFromWheelTimerId);
3817 d->scrollingFromWheelTimerId =
startTimer(400);
3822 bool d = (
static_cast<QWheelEvent *
>(e)->delta() < 0);
3851 DOM::NodeImpl *fn = m_part->xmlDocImpl() ? m_part->xmlDocImpl()->focusNode() :
nullptr;
3852 if (fn && fn->renderer() && fn->renderer()->isWidget() &&
3854 static_cast<khtml::RenderWidget *
>(fn->renderer())->widget()) {
3855 static_cast<khtml::RenderWidget *
>(fn->renderer())->
widget()->
setFocus();
3857 m_part->setSelectionVisible();
3864 m_part->stopAutoScroll();
3865 m_part->setSelectionVisible(
false);
3868 if (d->cursorIconWidget) {
3869 d->cursorIconWidget->hide();
3875 void KHTMLView::scrollContentsBy(
int dx,
int dy)
3881 if (!d->firstLayoutPending && !d->complete && m_part->xmlDocImpl() &&
3882 d->layoutSchedulingEnabled) {
3884 khtml::RenderCanvas *root =
static_cast<khtml::RenderCanvas *
>(m_part->xmlDocImpl()->renderer());
3885 if (root && root->needsLayout()) {
3886 unscheduleRelayout();
3891 if (d->shouldSmoothScroll && d->smoothScrollMode != SSMDisabled && m_part->xmlDocImpl() &&
3892 m_part->xmlDocImpl()->renderer() && (d->smoothScrollMode != SSMWhenEfficient || d->smoothScrollMissedDeadlines != sWayTooMany)) {
3894 bool doSmoothScroll = (!d->staticWidget || d->smoothScrollMode == SSMEnabled);
3896 int numStaticPixels = 0;
3897 QRegion r =
static_cast<RenderCanvas *
>(m_part->xmlDocImpl()->renderer())->staticRegion();
3900 if (!doSmoothScroll && d->staticWidget == KHTMLViewPrivate::SBPartial && r.
rects().size() <= 10) {
3905 doSmoothScroll =
true;
3908 if (doSmoothScroll) {
3909 setupSmoothScrolling(dx, dy);
3918 if (!d->scrollingSelf) {
3919 d->scrollBarMoved =
true;
3920 d->contentsMoving =
true;
3922 scheduleRepaint(0, 0, 0, 0);
3925 if (m_part->xmlDocImpl() && m_part->xmlDocImpl()->documentElement()) {
3926 m_part->xmlDocImpl()->documentElement()->dispatchHTMLEvent(EventImpl::SCROLL_EVENT,
true,
false);
3933 if (!d->smoothScrolling) {
3934 d->updateContentsXY();
3946 if (m_kwp->isRedirected()) {
3955 if (d->staticWidget) {
3959 if (!d->visibleWidgets.isEmpty()) {
3960 checkExternalWidgetsPosition();
3963 if (d->staticWidget == KHTMLViewPrivate::SBPartial
3964 && m_part->xmlDocImpl() && m_part->xmlDocImpl()->renderer()) {
3966 QRegion r =
static_cast<RenderCanvas *
>(m_part->xmlDocImpl()->renderer())->staticRegion();
3970 for (
int i = 0; i < ar.
size(); ++i) {
3975 for (
int i = 0; i < ar.
size(); ++i) {
3976 w->
scroll(dx, dy, ar[i].translated(off));
3978 d->scrollExternalWidgets(dx, dy);
3983 if (d->accessKeysActivated) {
3984 d->scrollAccessKeys(dx, dy);
3990 if (m_kwp->isRedirected()) {
3993 if (d->zoomLevel != 100) {
4000 d->scrollExternalWidgets(dx, dy);
4001 if (d->accessKeysActivated) {
4002 d->scrollAccessKeys(dx, dy);
4006 void KHTMLView::setupSmoothScrolling(
int dx,
int dy)
4009 int ddx = qMax(d->steps ? abs(d->dx) / d->steps : 0, 3);
4010 int ddy = qMax(d->steps ? abs(d->dy) / d->steps : 0, 3);
4016 if (d->dx == 0 && d->dy == 0) {
4021 d->steps = (sSmoothScrollTime - 1) / sSmoothScrollTick + 1;
4023 if (qMax(abs(d->dx), abs(d->dy)) / d->steps < qMax(ddx, ddy)) {
4026 d->steps = qMax((abs(d->dx) + ddx - 1) / ddx, (abs(d->dy) + ddy - 1) / ddy);
4032 d->smoothScrollStopwatch.start();
4033 if (!d->smoothScrolling) {
4034 d->startScrolling();
4039 void KHTMLView::scrollTick()
4041 if (d->dx == 0 && d->dy == 0) {
4049 int takesteps = d->smoothScrollStopwatch.restart() / sSmoothScrollTick;
4052 if (takesteps < 1) {
4055 if (takesteps > d->steps) {
4056 takesteps = d->steps;
4058 for (
int i = 0; i < takesteps; i++) {
4059 int ddx = (d->dx / (d->steps + 1)) * 2;
4060 int ddy = (d->dy / (d->steps + 1)) * 2;
4063 if (abs(ddx) > abs(d->dx)) {
4066 if (abs(ddy) > abs(d->dy)) {
4078 d->shouldSmoothScroll =
false;
4079 scrollContentsBy(scroll_x, scroll_y);
4081 if (takesteps < 2) {
4082 d->smoothScrollMissedDeadlines = 0;
4084 if (d->smoothScrollMissedDeadlines != sWayTooMany &&
4085 (!m_part->xmlDocImpl() || !m_part->xmlDocImpl()->parsing())) {
4086 d->smoothScrollMissedDeadlines++;
4087 if (d->smoothScrollMissedDeadlines >= sMaxMissedDeadlines) {
4090 d->smoothScrollMissedDeadlines = sWayTooMany;
4096 void KHTMLView::addChild(
QWidget *child,
int x,
int y)
4114 if (e->
timerId() == d->scrollTimerId) {
4115 if (d->scrollSuspended) {
4118 switch (d->scrollDirection) {
4119 case KHTMLViewPrivate::ScrollDown:
4121 d->newScrollTimer(
this, 0);
4126 case KHTMLViewPrivate::ScrollUp:
4128 d->newScrollTimer(
this, 0);
4133 case KHTMLViewPrivate::ScrollRight:
4135 d->newScrollTimer(
this, 0);
4140 case KHTMLViewPrivate::ScrollLeft:
4142 d->newScrollTimer(
this, 0);
4149 }
else if (e->
timerId() == d->scrollingFromWheelTimerId) {
4150 killTimer(d->scrollingFromWheelTimerId);
4151 d->scrollingFromWheelTimerId = 0;
4152 }
else if (e->
timerId() == d->layoutTimerId) {
4153 if (d->firstLayoutPending && d->layoutAttemptCounter < 4
4154 && (!m_part->xmlDocImpl() || !m_part->xmlDocImpl()->readyForLayout())) {
4155 d->layoutAttemptCounter++;
4157 d->layoutTimerId = 0;
4162 d->scheduledLayoutCounter++;
4163 if (d->firstLayoutPending) {
4164 d->firstLayoutPending =
false;
4170 d->contentsMoving =
false;
4171 if (m_part->xmlDocImpl()) {
4173 khtml::RenderCanvas *root =
static_cast<khtml::RenderCanvas *
>(document->renderer());
4175 if (root && root->needsLayout()) {
4176 if (d->repaintTimerId) {
4179 d->repaintTimerId = 0;
4185 if (d->repaintTimerId) {
4188 d->repaintTimerId = 0;
4196 updateRegion = rects[0];
4199 for (
int i = 1; i < rects.
size(); ++i) {
4201 if (2 * newRegion.
height() > 3 * updateRegion.
height()) {
4203 updateRegion = rects[i];
4205 updateRegion = newRegion;
4209 if (!updateRegion.
isNull()) {
4218 if (d->dirtyLayout && !d->visibleWidgets.isEmpty()) {
4219 checkExternalWidgetsPosition();
4222 d->dirtyLayout =
false;
4224 emit repaintAccessKeys();
4225 if (d->emitCompletedAfterRepaint) {
4226 bool full = d->emitCompletedAfterRepaint == KHTMLViewPrivate::CSFull;
4227 d->emitCompletedAfterRepaint = KHTMLViewPrivate::CSNone;
4236 void KHTMLView::checkExternalWidgetsPosition()
4242 while (it.hasNext()) {
4245 RenderWidget *rw =
static_cast<RenderWidget *
>(it.key());
4246 if (!rw->absolutePosition(xp, yp) ||
4247 !visibleRect.intersects(
QRect(xp, yp, it.value()->width(), it.value()->height()))) {
4251 foreach (RenderWidget *r, toRemove)
4252 if ((w = d->visibleWidgets.take(r))) {
4253 w->
move(0, -500000);
4259 if (!d->layoutSchedulingEnabled || d->layoutTimerId) {
4264 if (d->firstLayoutPending) {
4268 time = d->layoutAttemptCounter ?
4269 sLayoutAttemptDelay + sLayoutAttemptIncrement * d->layoutAttemptCounter : sFirstLayoutDelay;
4270 }
else if (m_part->xmlDocImpl() && m_part->xmlDocImpl()->parsing()) {
4273 time = qMin(2000, sParsingLayoutsInterval + d->scheduledLayoutCounter * sParsingLayoutsIncrement);
4278 void KHTMLView::unscheduleRelayout()
4280 if (!d->layoutTimerId) {
4285 d->layoutTimerId = 0;
4288 void KHTMLView::unscheduleRepaint()
4290 if (!d->repaintTimerId) {
4295 d->repaintTimerId = 0;
4298 void KHTMLView::scheduleRepaint(
int x,
int y,
int w,
int h,
bool asap)
4300 bool parsing = !m_part->xmlDocImpl() || m_part->xmlDocImpl()->parsing();
4305 int time = parsing && !d->firstLayoutPending ? 150 : (!asap ? (!d->complete ? 80 : 20) : 0);
4307 #ifdef DEBUG_FLICKER
4317 d->updateRegion = d->updateRegion.united(
QRect(
x,
y, w, h));
4319 if (asap && !parsing) {
4320 unscheduleRepaint();
4323 if (!d->repaintTimerId) {
4330 void KHTMLView::complete(
bool pendingAction)
4337 if (d->layoutTimerId) {
4342 d->emitCompletedAfterRepaint = pendingAction ?
4343 KHTMLViewPrivate::CSActionPending : KHTMLViewPrivate::CSFull;
4347 if (d->repaintTimerId) {
4352 d->emitCompletedAfterRepaint = pendingAction ?
4353 KHTMLViewPrivate::CSActionPending : KHTMLViewPrivate::CSFull;
4356 if (!d->emitCompletedAfterRepaint) {
4357 if (!pendingAction) {
4366 void KHTMLView::updateScrollBars()
4385 if (!d->smoothScrolling) {
4386 d->updateContentsXY();
4390 void KHTMLView::slotMouseScrollTimer()
4396 static DOM::Position positionOfLineBoundary(
const DOM::Position &pos,
bool toEnd)
4398 Selection sel = pos;
4399 sel.expandUsingGranularity(Selection::LINE);
4400 return toEnd ? sel.end() : sel.start();
4403 inline static DOM::Position positionOfLineBegin(
const DOM::Position &pos)
4405 return positionOfLineBoundary(pos,
false);
4408 inline static DOM::Position positionOfLineEnd(
const DOM::Position &pos)
4410 return positionOfLineBoundary(pos,
true);
4413 bool KHTMLView::caretKeyPressEvent(
QKeyEvent *_ke)
4415 EditorContext *ec = &m_part->d->editor_context;
4416 Selection &caret = ec->m_selection;
4417 Position old_pos = caret.caretPos();
4418 Position
pos = old_pos;
4419 bool recalcXPos =
true;
4420 bool handled =
true;
4425 switch (_ke->
key()) {
4429 pos = old_pos.nextLinePosition(caret.xPosForVerticalArrowNavigation(Selection::EXTENT));
4434 pos = old_pos.previousLinePosition(caret.xPosForVerticalArrowNavigation(Selection::EXTENT));
4439 pos = ctrl ? old_pos.previousWordPosition() : old_pos.previousCharacterPosition();
4443 pos = ctrl ? old_pos.nextWordPosition() : old_pos.nextCharacterPosition();
4458 pos = positionOfLineBegin(old_pos);
4466 pos = positionOfLineEnd(old_pos);
4475 if (
pos != old_pos) {
4476 m_part->clearCaretRectIfNeeded();
4478 caret.moveTo(shift ? caret.nonCaretPos() :
pos,
pos);
4479 int old_x = caret.xPosForVerticalArrowNavigation(Selection::CARETPOS);
4481 m_part->selectionLayoutChanged();
4485 m_part->d->editor_context.m_xPosForVerticalArrowNavigation = old_x;
4488 m_part->emitCaretPositionChanged(
pos);
4490 m_part->notifySelectionChanged();
4500 #undef DEBUG_CARETMODE