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 "misc/loader.h"
78 #include <QtGui/QBitmap>
79 #include <QtGui/QLabel>
80 #include <QtCore/QObject>
81 #include <QtGui/QPainter>
82 #include <QtCore/QHash>
83 #include <QtGui/QToolTip>
84 #include <QtCore/QString>
85 #include <QtGui/QTextDocument>
86 #include <QtCore/QTimer>
87 #include <QtCore/QAbstractEventDispatcher>
88 #include <QtCore/QVector>
89 #include <QtGui/QAbstractScrollArea>
90 #include <QtGui/QPrinter>
91 #include <QtGui/QPrintDialog>
99 #elif defined(Q_WS_WIN)
105 void dumpLineBoxes(RenderFlow *flow);
110 using namespace khtml;
131 class KHTMLViewPrivate {
135 enum PseudoFocusNodes {
141 enum StaticBackgroundState {
147 enum CompletedState {
154 : underMouse( 0 ), underMouseNonShared( 0 ), oldUnderMouse( 0 )
156 postponed_autorepeat = NULL;
157 scrollingFromWheelTimerId = 0;
161 vpolicy = Qt::ScrollBarAsNeeded;
162 hpolicy = Qt::ScrollBarAsNeeded;
164 prevScrollbarVisible =
true;
166 possibleTripleClick =
false;
167 emitCompletedAfterRepaint = CSNone;
168 cursorIconWidget = 0;
169 cursorIconType = KHTMLView::LINK_NORMAL;
170 m_mouseScrollTimer = 0;
171 m_mouseScrollIndicator = 0;
178 delete formCompletions;
179 delete postponed_autorepeat;
182 if (underMouseNonShared)
183 underMouseNonShared->deref();
185 oldUnderMouse->deref();
187 delete cursorIconWidget;
188 delete m_mouseScrollTimer;
189 delete m_mouseScrollIndicator;
196 if (underMouseNonShared)
197 underMouseNonShared->deref();
198 underMouseNonShared = 0;
200 oldUnderMouse->deref();
203 staticWidget = SBNone;
204 fixedObjectsCount = 0;
205 staticObjectsCount = 0;
206 tabMovePending =
false;
207 lastTabbingDirection =
true;
208 pseudoFocusNode = PFNone;
210 #ifndef KHTML_NO_SCROLLBARS
216 vpolicy = ScrollBarAlwaysOff;
217 hpolicy = ScrollBarAlwaysOff;
219 scrollBarMoved =
false;
220 contentsMoving =
false;
221 ignoreWheelEvents =
false;
222 scrollingFromWheel =
QPoint(-1,-1);
231 isDoubleClick =
false;
232 scrollingSelf =
false;
233 delete postponed_autorepeat;
234 postponed_autorepeat = NULL;
238 scrollSuspended =
false;
239 scrollSuspendPreActivate =
false;
240 smoothScrolling =
false;
241 smoothScrollModeIsDefault =
true;
242 shouldSmoothScroll =
false;
243 smoothScrollMissedDeadlines = 0;
246 firstLayoutPending =
true;
248 firstRepaintPending =
true;
250 needsFullRepaint =
true;
252 layoutSchedulingEnabled =
true;
255 layoutAttemptCounter = 0;
256 scheduledLayoutCounter = 0;
257 updateRegion = QRegion();
258 m_dialogsAllowed =
true;
259 accessKeysActivated =
false;
260 accessKeysPreActivate =
false;
267 KHTMLGlobal::deref();
269 emitCompletedAfterRepaint = CSNone;
270 m_mouseEventsTarget = 0;
273 void newScrollTimer(
QWidget *view,
int tid)
276 view->killTimer(scrollTimerId);
278 scrollSuspended =
false;
280 enum ScrollDirection { ScrollLeft, ScrollRight, ScrollUp, ScrollDown };
282 void adjustScroller(
QWidget *view, ScrollDirection direction, ScrollDirection oppositedir)
284 static const struct {
int msec, pixels; } timings [] = {
285 {320,1}, {224,1}, {160,1}, {112,1}, {80,1}, {56,1}, {40,1},
286 {28,1}, {20,1}, {20,2}, {20,3}, {20,4}, {20,6}, {20,8}, {0,0}
288 if (!scrollTimerId ||
289 (static_cast<int>(scrollDirection) != direction &&
290 (static_cast<int>(scrollDirection) != oppositedir || scrollSuspended))) {
292 scrollBy = timings[scrollTiming].pixels;
293 scrollDirection = direction;
294 newScrollTimer(view, view->startTimer(timings[scrollTiming].msec));
295 }
else if (scrollDirection == direction &&
296 timings[scrollTiming+1].msec && !scrollSuspended) {
297 scrollBy = timings[++scrollTiming].pixels;
298 newScrollTimer(view, view->startTimer(timings[scrollTiming].msec));
299 }
else if (scrollDirection == oppositedir) {
301 scrollBy = timings[--scrollTiming].pixels;
302 newScrollTimer(view, view->startTimer(timings[scrollTiming].msec));
305 scrollSuspended =
false;
308 bool haveZoom()
const {
return zoomLevel != 100; }
310 void startScrolling()
312 smoothScrolling =
true;
314 shouldSmoothScroll =
false;
319 smoothScrollTimer.stop();
323 smoothScrolling =
false;
324 shouldSmoothScroll =
false;
327 void updateContentsXY()
329 contentsX = QApplication::isRightToLeft() ?
330 view->horizontalScrollBar()->maximum()-view->horizontalScrollBar()->value() : view->horizontalScrollBar()->value();
331 contentsY = view->verticalScrollBar()->value();
333 void scrollAccessKeys(
int dx,
int dy)
335 QList<QLabel*> wl = qFindChildren<QLabel*>(view->widget(),
"KHTMLAccessKey");
337 w->move( w->pos() +
QPoint(dx, dy) );
340 void scrollExternalWidgets(
int dx,
int dy)
342 if (visibleWidgets.isEmpty())
345 QHashIterator<void*, QWidget*> it(visibleWidgets);
346 while (it.hasNext()) {
348 it.value()->move( it.value()->pos() +
QPoint(dx, dy) );
352 NodeImpl *underMouse;
353 NodeImpl *underMouseNonShared;
354 NodeImpl *oldUnderMouse;
358 bool tabMovePending:1;
359 bool lastTabbingDirection:1;
360 PseudoFocusNodes pseudoFocusNode:3;
361 bool scrollBarMoved:1;
362 bool contentsMoving:1;
364 Qt::ScrollBarPolicy vpolicy;
365 Qt::ScrollBarPolicy hpolicy;
366 bool prevScrollbarVisible:1;
368 bool ignoreWheelEvents:1;
369 StaticBackgroundState staticWidget: 3;
370 int staticObjectsCount;
371 int fixedObjectsCount;
374 int borderX, borderY;
379 int clickX, clickY, clickCount;
385 int contentsX, contentsY;
387 QKeyEvent* postponed_autorepeat;
393 ScrollDirection scrollDirection :3;
394 bool scrollSuspended :1;
395 bool scrollSuspendPreActivate :1;
397 bool smoothScrolling :1;
398 bool smoothScrollModeIsDefault :1;
399 bool shouldSmoothScroll :1;
402 bool firstLayoutPending :1;
404 bool firstRepaintPending :1;
406 bool layoutSchedulingEnabled :1;
407 bool needsFullRepaint :1;
409 bool possibleTripleClick :1;
411 bool m_dialogsAllowed :1;
412 short smoothScrollMissedDeadlines;
414 int layoutAttemptCounter;
415 int scheduledLayoutCounter;
416 QRegion updateRegion;
417 QTimer smoothScrollTimer;
418 QTime smoothScrollStopwatch;
420 bool accessKeysEnabled;
421 bool accessKeysActivated;
422 bool accessKeysPreActivate;
423 CompletedState emitCompletedAfterRepaint;
426 KHTMLView::LinkCursor cursorIconType;
429 short m_mouseScroll_byX;
430 short m_mouseScroll_byY;
431 QPoint scrollingFromWheel;
432 int scrollingFromWheelTimerId;
433 QTimer *m_mouseScrollTimer;
434 QWidget *m_mouseScrollIndicator;
435 QPointer<QWidget> m_mouseEventsTarget;
440 #ifndef QT_NO_TOOLTIP
454 HTMLMapElementImpl* map;
455 if (img && img->document()->isHTMLDocument() &&
456 (map =
static_cast<HTMLDocumentImpl*
>(img->document())->getMap(img->imageMap()))) {
457 RenderObject::NodeInfo info(
true,
false);
458 RenderObject *rend = img->renderer();
460 if (!rend || !rend->absolutePosition(ax, ay))
463 bool inside = map->mapMouseEvent(p.x() - ax + scrollOfs.x(),
464 p.y() - ay + scrollOfs.y(), rend->contentWidth(),
465 rend->contentHeight(), info);
466 if (inside && info.URLElement()) {
467 HTMLAreaElementImpl *area =
static_cast<HTMLAreaElementImpl *
>(info.URLElement());
468 Q_ASSERT(area->id() == ID_AREA);
469 s = area->getAttribute(ATTR_TITLE).string();
470 QRegion reg = area->cachedRegion();
471 if (!s.isEmpty() && !reg.isEmpty()) {
472 r = reg.boundingRect();
483 switch ( e->type() ) {
484 case QEvent::ToolTip: {
485 QHelpEvent *he =
static_cast<QHelpEvent*
>(e);
488 DOM::NodeImpl *node =
d->underMouseNonShared;
491 if ( node->isElementNode() ) {
492 DOM::ElementImpl *e =
static_cast<DOM::ElementImpl*
>( node );
498 if (e->id() == ID_IMG && !e->getAttribute( ATTR_USEMAP ).isEmpty()) {
500 viewportToContents(
QPoint(0, 0)), p, r, s);
503 s = e->getAttribute(ATTR_TITLE).string().trimmed();
506 region |=
QRect( contentsToViewport( r.topLeft() ), r.size() );
507 if ( !s.isEmpty() ) {
508 QToolTip::showText( he->globalPos(),
509 Qt::convertFromPlainText( s, Qt::WhiteSpaceNormal ),
514 node = node->parentNode();
522 case QEvent::DragEnter:
523 case QEvent::DragMove:
524 case QEvent::DragLeave:
534 return QWidget::event(e);
535 case QEvent::StyleChange:
536 case QEvent::LayoutRequest: {
538 return QAbstractScrollArea::event(e);
540 case QEvent::PaletteChange:
541 slotPaletteChanged();
542 return QScrollArea::event(e);
544 return QScrollArea::event(e);
550 :
QScrollArea( parent ),
d( new KHTMLViewPrivate( this ) )
556 QScrollArea::setVerticalScrollBarPolicy(d->vpolicy);
557 QScrollArea::setHorizontalScrollBarPolicy(d->hpolicy);
560 widget()->setMouseTracking(
true);
568 DOM::DocumentImpl *doc = m_part->xmlDocImpl();
581 void KHTMLView::init()
585 setFrameStyle(QFrame::NoFrame);
586 setFocusPolicy(Qt::StrongFocus);
587 viewport()->setFocusProxy(
this);
596 setAcceptDrops(
true);
598 setWidget(
new QWidget(
this) );
599 widget()->setAttribute( Qt::WA_NoSystemBackground );
605 widget()->setAttribute( Qt::WA_OpaquePaintEvent );
607 verticalScrollBar()->setCursor( Qt::ArrowCursor );
608 horizontalScrollBar()->setCursor( Qt::ArrowCursor );
610 connect(&d->smoothScrollTimer, SIGNAL(
timeout()),
this, SLOT(scrollTick()));
613 void KHTMLView::resizeContentsToViewport()
615 QSize s = viewport()->size();
623 if (d->accessKeysEnabled && d->accessKeysActivated)
625 viewport()->unsetCursor();
626 if ( d->cursorIconWidget )
627 d->cursorIconWidget->hide();
628 if (d->smoothScrolling)
631 QAbstractEventDispatcher::instance()->unregisterTimers(
this);
634 QScrollArea::setHorizontalScrollBarPolicy(d->hpolicy);
635 QScrollArea::setVerticalScrollBarPolicy(d->vpolicy);
636 verticalScrollBar()->setEnabled(
false );
637 horizontalScrollBar()->setEnabled(
false );
643 QScrollArea::hideEvent(e);
648 QScrollArea::showEvent(e);
651 void KHTMLView::setMouseEventsTarget(
QWidget* w )
653 d->m_mouseEventsTarget = w;
656 QWidget* KHTMLView::mouseEventsTarget()
const
658 return d->m_mouseEventsTarget;
663 d->m_clipHolder = ch;
668 return d->m_clipHolder;
673 return widget() ? widget()->width() : 0;
678 return widget() ? widget()->height() : 0;
685 widget()->resize(w, h);
686 if (!widget()->isVisible())
702 if (
m_kwp->isRedirected()) {
704 if (RenderWidget* rw =
m_kwp->renderWidget()) {
705 int ret = rw->width()-rw->paddingLeft()-rw->paddingRight()-rw->borderLeft()-rw->borderRight();
706 if (verticalScrollBar()->isVisible()) {
707 ret -= verticalScrollBar()->sizeHint().width();
713 return viewport()->width();
718 if (
m_kwp->isRedirected()) {
720 if (RenderWidget* rw =
m_kwp->renderWidget()) {
721 int ret = rw->height()-rw->paddingBottom()-rw->paddingTop()-rw->borderTop()-rw->borderBottom();
722 if (horizontalScrollBar()->isVisible()) {
723 ret -= horizontalScrollBar()->sizeHint().height();
729 return viewport()->height();
734 horizontalScrollBar()->setValue( QApplication::isRightToLeft() ?
735 horizontalScrollBar()->maximum()-x : x );
736 verticalScrollBar()->setValue( y );
741 if (d->scrollTimerId)
742 d->newScrollTimer(
this, 0);
743 horizontalScrollBar()->setValue( horizontalScrollBar()->value()+x );
744 verticalScrollBar()->setValue( verticalScrollBar()->value()+y );
775 applyTransforms(x, y, w, h);
776 if (
m_kwp->isRedirected()) {
781 widget()->update(x, y, w, h);
791 applyTransforms(x, y, w, h);
792 if (
m_kwp->isRedirected()) {
797 widget()->repaint(x, y, w, h);
805 void KHTMLView::applyTransforms(
int& x,
int& y,
int& w,
int& h)
const
808 const int z = d->zoomLevel;
818 void KHTMLView::revertTransforms(
int& x,
int& y,
int& w,
int& h)
const
823 const int z = d->zoomLevel;
831 void KHTMLView::revertTransforms(
int& x,
int& y )
const
834 revertTransforms(x, y, dummy, dummy);
842 if (!m_part->xmlDocImpl())
843 resizeContentsToViewport();
846 if (m_part->xmlDocImpl() && m_part->xmlDocImpl()->styleSelector()->affectedByViewportChange()) {
847 m_part->xmlDocImpl()->updateStyleSelector();
850 if (d->layoutSchedulingEnabled)
853 QApplication::sendPostedEvents(viewport(), QEvent::Paint);
855 if ( m_part && m_part->xmlDocImpl() ) {
863 HTMLPartContainerElementImpl::sendPostedResizeEvents();
864 m_part->xmlDocImpl()->dispatchWindowEvent( EventImpl::RESIZE_EVENT,
false,
false );
876 if (!r.isValid() || r.isEmpty())
return;
878 QPainter p(widget());
882 p.scale( d->zoomLevel/100., d->zoomLevel/100.);
884 r.setX(r.x()*100/d->zoomLevel);
885 r.setY(r.y()*100/d->zoomLevel);
886 r.setWidth(r.width()*100/d->zoomLevel);
887 r.setHeight(r.height()*100/d->zoomLevel);
897 if(!m_part || !m_part->xmlDocImpl() || !m_part->xmlDocImpl()->renderer()) {
898 p.fillRect(ex, ey, ew, eh, palette().brush(QPalette::Active, QPalette::Base));
900 }
else if ( d->complete && static_cast<RenderCanvas*>(m_part->xmlDocImpl()->renderer())->needsLayout() ) {
902 unscheduleRelayout();
904 }
else if (m_part->xmlDocImpl()->tokenizer()) {
905 m_part->xmlDocImpl()->tokenizer()->setNormalYieldDelay();
909 kDebug( 6000 ) <<
"WARNING: paintEvent reentered! ";
910 kDebug( 6000 ) << kBacktrace();
915 m_part->xmlDocImpl()->renderer()->layer()->paint(&p, r);
917 if (d->hasFrameset) {
918 NodeImpl *body =
static_cast<HTMLDocumentImpl*
>(m_part->xmlDocImpl())->body();
919 if(body && body->renderer() && body->id() == ID_FRAMESET)
920 static_cast<RenderFrameSet*>(body->renderer())->paintFrameSetRules(&p, r);
922 d->hasFrameset =
false;
926 QApplication::sendEvent( m_part, &event );
928 if (d->contentsMoving && !d->smoothScrolling && widget()->underMouse()) {
929 QMouseEvent *tempEvent =
new QMouseEvent( QEvent::MouseMove, widget()->mapFromGlobal( QCursor::pos() ),
930 Qt::NoButton, Qt::NoButton, Qt::NoModifier );
931 QApplication::postEvent(widget(), tempEvent);
934 if (d->firstRepaintPending && !m_part->
parentPart()) {
937 d->firstRepaintPending =
false;
956 if( m_part && m_part->xmlDocImpl() ) {
957 DOM::DocumentImpl *document = m_part->xmlDocImpl();
959 khtml::RenderCanvas* canvas =
static_cast<khtml::RenderCanvas *
>(document->renderer());
960 if ( !canvas )
return;
962 d->layoutSchedulingEnabled=
false;
963 d->dirtyLayout =
true;
966 RenderObject *
ref = 0;
967 RenderObject* root = document->documentElement() ? document->documentElement()->renderer() : 0;
969 if (document->isHTMLDocument()) {
970 NodeImpl *body =
static_cast<HTMLDocumentImpl*
>(document)->body();
971 if(body && body->renderer() && body->id() == ID_FRAMESET) {
972 QScrollArea::setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
973 QScrollArea::setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
974 body->renderer()->setNeedsLayout(
true);
975 d->hasFrameset =
true;
978 ref = (!body || root->style()->hidesOverflow()) ? root : body->renderer();
983 if( ref->style()->overflowX() == OHIDDEN ) {
984 if (d->hpolicy == Qt::ScrollBarAsNeeded) QScrollArea::setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
985 }
else if (ref->style()->overflowX() == OSCROLL ) {
986 if (d->hpolicy == Qt::ScrollBarAsNeeded) QScrollArea::setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
987 }
else if (horizontalScrollBarPolicy() != d->hpolicy) {
988 QScrollArea::setHorizontalScrollBarPolicy(d->hpolicy);
990 if ( ref->style()->overflowY() == OHIDDEN ) {
991 if (d->vpolicy == Qt::ScrollBarAsNeeded) QScrollArea::setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
992 }
else if (ref->style()->overflowY() == OSCROLL ) {
993 if (d->vpolicy == Qt::ScrollBarAsNeeded) QScrollArea::setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
994 }
else if (verticalScrollBarPolicy() != d->vpolicy) {
995 QScrollArea::setVerticalScrollBarPolicy(d->vpolicy);
998 d->needsFullRepaint = d->firstLayoutPending;
1000 d->needsFullRepaint =
true;
1008 if (d->firstLayoutPending) {
1011 d->firstLayoutPending =
false;
1012 verticalScrollBar()->setEnabled(
true );
1013 horizontalScrollBar()->setEnabled(
true );
1017 if (d->accessKeysEnabled && d->accessKeysActivated) {
1025 if (d->layoutTimerId)
1026 killTimer(d->layoutTimerId);
1027 d->layoutTimerId = 0;
1028 d->layoutSchedulingEnabled=
true;
1031 void KHTMLView::closeChildDialogs()
1038 if ( dlgbase->testAttribute( Qt::WA_ShowModal ) ) {
1039 kDebug(6000) <<
"closeChildDialogs: closing dialog " << dlgbase;
1047 kWarning() <<
"closeChildDialogs: not a KDialog! Don't use QDialogs in KDE! " <<
static_cast<QWidget*
>(dlg);
1048 static_cast<QWidget*
>(dlg)->hide();
1051 d->m_dialogsAllowed =
false;
1054 bool KHTMLView::dialogsAllowed() {
1055 bool allowed = d->m_dialogsAllowed;
1058 allowed &= p->
view()->dialogsAllowed();
1064 closeChildDialogs();
1065 QScrollArea::closeEvent( ev );
1070 percent = percent < 20 ? 20 : (percent > 800 ? 800 : percent);
1071 int oldpercent = d->zoomLevel;
1072 d->zoomLevel = percent;
1073 if (percent != oldpercent) {
1074 if (d->layoutSchedulingEnabled)
1082 return d->zoomLevel;
1087 d->smoothScrollMode = m;
1088 d->smoothScrollModeIsDefault =
false;
1089 if (d->smoothScrolling && !m)
1096 if (!d->smoothScrollModeIsDefault)
1098 d->smoothScrollMode = m;
1099 if (d->smoothScrolling && !m)
1105 return d->smoothScrollMode;
1115 if (!m_part->xmlDocImpl())
return;
1116 if (d->possibleTripleClick && ( _mouse->button() & Qt::MouseButtonMask ) == Qt::LeftButton)
1122 int xm = _mouse->x();
1123 int ym = _mouse->y();
1124 revertTransforms(xm, ym);
1128 d->isDoubleClick =
false;
1130 DOM::NodeImpl::MouseEvent mev( _mouse->buttons(), DOM::NodeImpl::MousePress );
1131 m_part->xmlDocImpl()->prepareMouseEvent(
false, xm, ym, &mev );
1135 if ( (_mouse->button() == Qt::MidButton) &&
1137 mev.url.isNull() && (mev.innerNode.elementId() != ID_INPUT) ) {
1138 QPoint point = mapFromGlobal( _mouse->globalPos() );
1140 d->m_mouseScroll_byX = 0;
1141 d->m_mouseScroll_byY = 0;
1143 d->m_mouseScrollTimer =
new QTimer(
this );
1144 connect( d->m_mouseScrollTimer, SIGNAL(
timeout()),
this, SLOT(slotMouseScrollTimer()) );
1146 if ( !d->m_mouseScrollIndicator ) {
1147 QPixmap pixmap( 48, 48 ), icon;
1148 pixmap.fill(
QColor( qRgba( 127, 127, 127, 127 ) ) );
1150 QPainter p( &pixmap );
1151 QStyleOption option;
1153 option.rect.setRect( 16, 0, 16, 16 );
1154 QApplication::style()->drawPrimitive( QStyle::PE_IndicatorArrowUp, &option, &p );
1155 option.rect.setRect( 0, 16, 16, 16 );
1156 QApplication::style()->drawPrimitive( QStyle::PE_IndicatorArrowLeft, &option, &p );
1157 option.rect.setRect( 16, 32, 16, 16 );
1158 QApplication::style()->drawPrimitive( QStyle::PE_IndicatorArrowDown, &option, &p );
1159 option.rect.setRect( 32, 16, 16, 16 );
1160 QApplication::style()->drawPrimitive( QStyle::PE_IndicatorArrowRight, &option, &p );
1161 p.drawEllipse( 23, 23, 2, 2 );
1163 d->m_mouseScrollIndicator =
new QWidget(
this );
1164 d->m_mouseScrollIndicator->setFixedSize( 48, 48 );
1166 palette.setBrush( d->m_mouseScrollIndicator->backgroundRole(), QBrush( pixmap ) );
1167 d->m_mouseScrollIndicator->setPalette( palette );
1169 d->m_mouseScrollIndicator->move( point.x()-24, point.y()-24 );
1175 if ( cg.
readEntry(
"ShowMouseScrollIndicator",
true ) ) {
1176 d->m_mouseScrollIndicator->show();
1177 d->m_mouseScrollIndicator->unsetCursor();
1179 QBitmap
mask = d->m_mouseScrollIndicator->palette().brush(d->m_mouseScrollIndicator->backgroundRole()).texture().createHeuristicMask(
true );
1181 if ( hasHorBar && !hasVerBar ) {
1182 QBitmap bm( 16, 16 );
1184 QPainter painter( &mask );
1185 painter.drawPixmap( QRectF( 16, 0, bm.width(), bm.height() ), bm, bm.rect() );
1186 painter.drawPixmap( QRectF( 16, 32, bm.width(), bm.height() ), bm, bm.rect() );
1187 d->m_mouseScrollIndicator->setCursor( Qt::SizeHorCursor );
1189 else if ( !hasHorBar && hasVerBar ) {
1190 QBitmap bm( 16, 16 );
1192 QPainter painter( &mask );
1193 painter.drawPixmap( QRectF( 0, 16, bm.width(), bm.height() ), bm, bm.rect() );
1194 painter.drawPixmap( QRectF( 32, 16, bm.width(), bm.height() ), bm, bm.rect() );
1195 d->m_mouseScrollIndicator->setCursor( Qt::SizeVerCursor );
1198 d->m_mouseScrollIndicator->setCursor( Qt::SizeAllCursor );
1200 d->m_mouseScrollIndicator->setMask( mask );
1203 if ( hasHorBar && !hasVerBar )
1204 viewport()->setCursor( Qt::SizeHorCursor );
1205 else if ( !hasHorBar && hasVerBar )
1206 viewport()->setCursor( Qt::SizeVerCursor );
1208 viewport()->setCursor( Qt::SizeAllCursor );
1213 else if ( d->m_mouseScrollTimer ) {
1214 delete d->m_mouseScrollTimer;
1215 d->m_mouseScrollTimer = 0;
1217 if ( d->m_mouseScrollIndicator )
1218 d->m_mouseScrollIndicator->hide();
1221 if (d->clickCount > 0 &&
1222 QPoint(d->clickX-xm,d->clickY-ym).manhattanLength() <= QApplication::startDragDistance())
1230 bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEDOWN_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),
true,
1231 d->clickCount,_mouse,
true,DOM::NodeImpl::MousePress);
1233 if (!swallowEvent) {
1234 emit m_part->nodeActivated(mev.innerNode);
1237 QApplication::sendEvent( m_part, &event );
1244 if(!m_part->xmlDocImpl())
return;
1246 int xm = _mouse->x();
1247 int ym = _mouse->y();
1248 revertTransforms(xm, ym);
1252 d->isDoubleClick =
true;
1254 DOM::NodeImpl::MouseEvent mev( _mouse->buttons(), DOM::NodeImpl::MouseDblClick );
1255 m_part->xmlDocImpl()->prepareMouseEvent(
false, xm, ym, &mev );
1259 if (d->clickCount > 0 &&
1260 QPoint(d->clickX-xm,d->clickY-ym).manhattanLength() <= QApplication::startDragDistance())
1267 bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEDOWN_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),
true,
1268 d->clickCount,_mouse,
true,DOM::NodeImpl::MouseDblClick);
1270 if (!swallowEvent) {
1272 QApplication::sendEvent( m_part, &event );
1275 d->possibleTripleClick=
true;
1276 QTimer::singleShot(QApplication::doubleClickInterval(),
this,SLOT(tripleClickTimeout()));
1279 void KHTMLView::tripleClickTimeout()
1281 d->possibleTripleClick =
false;
1287 if (!target.isEmpty() && (target.toLower() !=
"_top") &&
1288 (target.toLower() !=
"_self") && (target.toLower() !=
"_parent")) {
1289 if (target.toLower() ==
"_blank")
1303 if ( d->m_mouseScrollTimer ) {
1304 QPoint point = mapFromGlobal( _mouse->globalPos() );
1306 int deltaX = point.x() - d->m_mouseScrollIndicator->x() - 24;
1307 int deltaY = point.y() - d->m_mouseScrollIndicator->y() - 24;
1309 (deltaX > 0) ? d->m_mouseScroll_byX = 1 : d->m_mouseScroll_byX = -1;
1310 (deltaY > 0) ? d->m_mouseScroll_byY = 1 : d->m_mouseScroll_byY = -1;
1312 double adX = qAbs(deltaX)/30.0;
1313 double adY = qAbs(deltaY)/30.0;
1315 d->m_mouseScroll_byX = qMax(qMin(d->m_mouseScroll_byX *
int(adX*adX), SHRT_MAX), SHRT_MIN);
1316 d->m_mouseScroll_byY = qMax(qMin(d->m_mouseScroll_byY *
int(adY*adY), SHRT_MAX), SHRT_MIN);
1318 if (d->m_mouseScroll_byX == 0 && d->m_mouseScroll_byY == 0) {
1319 d->m_mouseScrollTimer->stop();
1321 else if (!d->m_mouseScrollTimer->isActive()) {
1322 d->m_mouseScrollTimer->start( 20 );
1326 if(!m_part->xmlDocImpl())
return;
1328 int xm = _mouse->x();
1329 int ym = _mouse->y();
1330 revertTransforms(xm, ym);
1332 DOM::NodeImpl::MouseEvent mev( _mouse->buttons(), DOM::NodeImpl::MouseMove );
1334 m_part->xmlDocImpl()->prepareMouseEvent( _mouse->buttons() , xm, ym, &mev );
1340 DOM::NodeImpl* target = mev.innerNode.handle();
1341 DOM::NodeImpl* fn = m_part->xmlDocImpl()->focusNode();
1344 if (d->m_mouseEventsTarget && fn && fn->renderer() && fn->renderer()->isWidget())
1347 bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEMOVE_EVENT,target,mev.innerNonSharedNode.handle(),
false,
1348 0,_mouse,
true,DOM::NodeImpl::MouseMove);
1350 if (d->clickCount > 0 &&
1351 QPoint(d->clickX-xm,d->clickY-ym).manhattanLength() > QApplication::startDragDistance()) {
1355 khtml::RenderObject* r = target ? target->renderer() : 0;
1356 bool setCursor =
true;
1357 bool forceDefault =
false;
1358 if (r && r->isWidget()) {
1359 RenderWidget* rw =
static_cast<RenderWidget*
>(r);
1360 KHTMLWidget* kw = qobject_cast<
KHTMLView*>(rw->widget())? dynamic_cast<KHTMLWidget*>(rw->widget()) : 0;
1361 if (kw && kw->
m_kwp->isRedirected())
1363 else if (
QLineEdit* le = qobject_cast<QLineEdit*>(rw->widget())) {
1364 QList<QWidget*> wl = qFindChildren<QWidget *>( le,
"KLineEditButton" );
1367 if (w->underMouse()) {
1368 forceDefault =
true;
1373 else if (
QTextEdit* te = qobject_cast<QTextEdit*>(rw->widget())) {
1374 if (te->verticalScrollBar()->underMouse() || te->horizontalScrollBar()->underMouse())
1375 forceDefault =
true;
1378 khtml::RenderStyle* style = (r && r->style()) ? r->style() : 0;
1380 LinkCursor linkCursor = LINK_NORMAL;
1381 switch (!forceDefault ? (style ? style->cursor() : CURSOR_AUTO) : CURSOR_DEFAULT) {
1384 !r->isPointInsideSelection(xm, ym, m_part->caret())) )
1388 if (mev.url.string().startsWith(
"mailto:") && mev.url.string().indexOf(
'@')>0)
1389 linkCursor = LINK_MAILTO;
1392 linkCursor = LINK_NEWWINDOW;
1395 if (r && r->isFrameSet() && !
static_cast<RenderFrameSet*
>(r)->noResize())
1396 c =
QCursor(static_cast<RenderFrameSet*>(r)->cursorShape());
1402 case CURSOR_POINTER:
1404 if (mev.url.string().startsWith(
"mailto:") && mev.url.string().indexOf(
'@')>0)
1405 linkCursor = LINK_MAILTO;
1408 linkCursor = LINK_NEWWINDOW;
1410 case CURSOR_PROGRESS:
1414 case CURSOR_ALL_SCROLL:
1415 c =
QCursor(Qt::SizeAllCursor);
1417 case CURSOR_E_RESIZE:
1418 case CURSOR_W_RESIZE:
1419 case CURSOR_EW_RESIZE:
1420 c =
QCursor(Qt::SizeHorCursor);
1422 case CURSOR_N_RESIZE:
1423 case CURSOR_S_RESIZE:
1424 case CURSOR_NS_RESIZE:
1425 c =
QCursor(Qt::SizeVerCursor);
1427 case CURSOR_NE_RESIZE:
1428 case CURSOR_SW_RESIZE:
1429 case CURSOR_NESW_RESIZE:
1430 c =
QCursor(Qt::SizeBDiagCursor);
1432 case CURSOR_NW_RESIZE:
1433 case CURSOR_SE_RESIZE:
1434 case CURSOR_NWSE_RESIZE:
1435 c =
QCursor(Qt::SizeFDiagCursor);
1444 c =
QCursor(Qt::WhatsThisCursor);
1446 case CURSOR_DEFAULT:
1449 case CURSOR_NOT_ALLOWED:
1450 c =
QCursor(Qt::ForbiddenCursor);
1452 case CURSOR_ROW_RESIZE:
1453 c =
QCursor(Qt::SplitVCursor);
1455 case CURSOR_COL_RESIZE:
1456 c =
QCursor(Qt::SplitHCursor);
1458 case CURSOR_VERTICAL_TEXT:
1459 case CURSOR_CONTEXT_MENU:
1460 case CURSOR_NO_DROP:
1468 if (!setCursor && style && style->cursor() != CURSOR_AUTO)
1474 vp = p->
view()->viewport();
1475 if ( setCursor && vp->cursor().handle() != c.handle() ) {
1476 if( c.shape() == Qt::ArrowCursor) {
1478 p->
view()->viewport()->unsetCursor();
1485 if ( linkCursor!=LINK_NORMAL && isVisible() && hasFocus() ) {
1488 if( !d->cursorIconWidget ) {
1490 d->cursorIconWidget =
new QLabel( 0, Qt::X11BypassWindowManagerHint );
1491 XSetWindowAttributes attr;
1492 attr.save_under = True;
1493 XChangeWindowAttributes( QX11Info::display(), d->cursorIconWidget->winId(), CWSaveUnder, &attr );
1495 d->cursorIconWidget =
new QLabel( NULL, NULL );
1501 if (linkCursor != d->cursorIconType) {
1502 d->cursorIconType = linkCursor;
1506 case LINK_MAILTO: cursorIcon =
"mail-message-new";
break;
1507 case LINK_NEWWINDOW: cursorIcon =
"window-new";
break;
1508 default: cursorIcon =
"dialog-error";
break;
1513 d->cursorIconWidget->resize( icon_pixmap.width(), icon_pixmap.height());
1514 d->cursorIconWidget->setMask( icon_pixmap.createMaskFromColor(Qt::transparent));
1515 d->cursorIconWidget->setPixmap( icon_pixmap);
1516 d->cursorIconWidget->update();
1519 QPoint c_pos = QCursor::pos();
1520 d->cursorIconWidget->move( c_pos.x() + 15, c_pos.y() + 15 );
1522 XRaiseWindow( QX11Info::display(), d->cursorIconWidget->winId());
1523 QApplication::flush();
1524 #elif defined(Q_WS_WIN)
1525 SetWindowPos( d->cursorIconWidget->winId(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE );
1529 d->cursorIconWidget->show();
1532 else if ( d->cursorIconWidget )
1533 d->cursorIconWidget->hide();
1535 if (r && r->isWidget()) {
1539 if (!swallowEvent) {
1541 QApplication::sendEvent( m_part, &event );
1547 bool swallowEvent =
false;
1549 int xm = _mouse->x();
1550 int ym = _mouse->y();
1551 revertTransforms(xm, ym);
1553 DOM::NodeImpl::MouseEvent mev( _mouse->buttons(), DOM::NodeImpl::MouseRelease );
1555 if ( m_part->xmlDocImpl() )
1557 m_part->xmlDocImpl()->prepareMouseEvent(
false, xm, ym, &mev );
1559 DOM::NodeImpl* target = mev.innerNode.handle();
1560 DOM::NodeImpl* fn = m_part->xmlDocImpl()->focusNode();
1563 if (d->m_mouseEventsTarget && fn && fn->renderer() && fn->renderer()->isWidget())
1566 swallowEvent = dispatchMouseEvent(EventImpl::MOUSEUP_EVENT,target,mev.innerNonSharedNode.handle(),
true,
1567 d->clickCount,_mouse,
false,DOM::NodeImpl::MouseRelease);
1570 if (d->m_mouseEventsTarget)
1571 d->m_mouseEventsTarget = 0;
1573 if (d->clickCount > 0 &&
1574 QPoint(d->clickX-xm,d->clickY-ym).manhattanLength() <= QApplication::startDragDistance()) {
1575 QMouseEvent me(d->isDoubleClick ? QEvent::MouseButtonDblClick : QEvent::MouseButtonRelease,
1576 _mouse->pos(), _mouse->button(), _mouse->buttons(), _mouse->modifiers());
1577 dispatchMouseEvent(EventImpl::CLICK_EVENT, mev.innerNode.handle(),mev.innerNonSharedNode.handle(),
true,
1578 d->clickCount, &me,
true, DOM::NodeImpl::MouseRelease);
1581 khtml::RenderObject* r = target ? target->renderer() : 0;
1582 if (r && r->isWidget())
1586 if (!swallowEvent) {
1588 QApplication::sendEvent( m_part, &event );
1593 bool KHTMLView::dispatchKeyEvent( QKeyEvent *_ke )
1595 if (!m_part->xmlDocImpl())
1617 if( _ke == d->postponed_autorepeat )
1622 if( _ke->type() == QEvent::KeyPress )
1624 if( !_ke->isAutoRepeat())
1626 bool ret = dispatchKeyEventHelper( _ke,
false );
1628 if( !ret && dispatchKeyEventHelper( _ke,
true ))
1634 bool ret = dispatchKeyEventHelper( _ke,
true );
1635 if( !ret && d->postponed_autorepeat )
1637 delete d->postponed_autorepeat;
1638 d->postponed_autorepeat = NULL;
1646 delete d->postponed_autorepeat;
1647 d->postponed_autorepeat = 0;
1649 if( !_ke->isAutoRepeat()) {
1650 return dispatchKeyEventHelper( _ke,
false );
1654 d->postponed_autorepeat =
new QKeyEvent( _ke->type(), _ke->key(), _ke->modifiers(),
1655 _ke->text(), _ke->isAutoRepeat(), _ke->count());
1656 if( _ke->isAccepted())
1657 d->postponed_autorepeat->accept();
1659 d->postponed_autorepeat->ignore();
1666 bool KHTMLView::dispatchKeyEventHelper( QKeyEvent *_ke,
bool keypress )
1668 DOM::NodeImpl* keyNode = m_part->xmlDocImpl()->focusNode();
1670 return keyNode->dispatchKeyEvent(_ke, keypress);
1672 return m_part->xmlDocImpl()->dispatchKeyEvent(_ke, keypress);
1679 if (d->accessKeysEnabled && _ke->key() == Qt::Key_Control && !(_ke->modifiers() & ~Qt::ControlModifier) && !d->accessKeysActivated)
1681 d->accessKeysPreActivate=
true;
1686 if (_ke->key() == Qt::Key_Shift && !(_ke->modifiers() & ~Qt::ShiftModifier))
1687 d->scrollSuspendPreActivate=
true;
1692 if (d->accessKeysEnabled && d->accessKeysActivated)
1694 int state = ( _ke->modifiers() & ( Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier ));
1695 if ( state==0 || state==Qt::ShiftModifier ) {
1696 if (_ke->key() != Qt::Key_Shift)
1697 accessKeysTimeout();
1698 handleAccessKey( _ke );
1702 accessKeysTimeout();
1707 if ( dispatchKeyEvent( _ke )) {
1713 int offs = (viewport()->height() < 30) ? viewport()->height() : 30;
1714 if (_ke->modifiers() & Qt::ShiftModifier)
1718 verticalScrollBar()->setValue( verticalScrollBar()->value() -viewport()->height() + offs );
1719 if(d->scrollSuspended)
1720 d->newScrollTimer(
this, 0);
1725 d->adjustScroller(
this, KHTMLViewPrivate::ScrollDown, KHTMLViewPrivate::ScrollUp);
1730 d->adjustScroller(
this, KHTMLViewPrivate::ScrollUp, KHTMLViewPrivate::ScrollDown);
1735 d->adjustScroller(
this, KHTMLViewPrivate::ScrollLeft, KHTMLViewPrivate::ScrollRight);
1740 d->adjustScroller(
this, KHTMLViewPrivate::ScrollRight, KHTMLViewPrivate::ScrollLeft);
1744 switch ( _ke->key() )
1748 if (!d->scrollTimerId || d->scrollSuspended)
1749 verticalScrollBar()->setValue( verticalScrollBar()->value()+10 );
1750 if (d->scrollTimerId)
1751 d->newScrollTimer(
this, 0);
1755 case Qt::Key_PageDown:
1756 d->shouldSmoothScroll =
true;
1757 verticalScrollBar()->setValue( verticalScrollBar()->value() +viewport()->height() - offs );
1758 if(d->scrollSuspended)
1759 d->newScrollTimer(
this, 0);
1764 if (!d->scrollTimerId || d->scrollSuspended)
1765 verticalScrollBar()->setValue( verticalScrollBar()->value()-10 );
1766 if (d->scrollTimerId)
1767 d->newScrollTimer(
this, 0);
1770 case Qt::Key_PageUp:
1771 d->shouldSmoothScroll =
true;
1772 verticalScrollBar()->setValue( verticalScrollBar()->value() -viewport()->height() + offs );
1773 if(d->scrollSuspended)
1774 d->newScrollTimer(
this, 0);
1778 if (!d->scrollTimerId || d->scrollSuspended)
1779 horizontalScrollBar()->setValue( horizontalScrollBar()->value()+10 );
1780 if (d->scrollTimerId)
1781 d->newScrollTimer(
this, 0);
1786 if (!d->scrollTimerId || d->scrollSuspended)
1787 horizontalScrollBar()->setValue( horizontalScrollBar()->value()-10 );
1788 if (d->scrollTimerId)
1789 d->newScrollTimer(
this, 0);
1792 case Qt::Key_Return:
1795 if (m_part->xmlDocImpl()) {
1796 NodeImpl *n = m_part->xmlDocImpl()->focusNode();
1802 verticalScrollBar()->setValue( 0 );
1803 horizontalScrollBar()->setValue( 0 );
1804 if(d->scrollSuspended)
1805 d->newScrollTimer(
this, 0);
1809 if(d->scrollSuspended)
1810 d->newScrollTimer(
this, 0);
1817 if (d->scrollTimerId)
1818 d->newScrollTimer(
this, 0);
1828 if( d->scrollSuspendPreActivate && _ke->key() != Qt::Key_Shift )
1829 d->scrollSuspendPreActivate =
false;
1830 if( _ke->key() == Qt::Key_Shift && d->scrollSuspendPreActivate && !(_ke->modifiers() & Qt::ShiftModifier))
1831 if (d->scrollTimerId) {
1832 d->scrollSuspended = !d->scrollSuspended;
1833 if (d->scrollSuspended)
1837 if (d->accessKeysEnabled)
1839 if (d->accessKeysPreActivate && _ke->key() != Qt::Key_Control)
1840 d->accessKeysPreActivate=
false;
1841 if (d->accessKeysPreActivate && !(_ke->modifiers() & Qt::ControlModifier))
1844 m_part->setStatusBarText(
i18n(
"Access Keys activated"),KHTMLPart::BarOverrideText);
1845 d->accessKeysActivated =
true;
1846 d->accessKeysPreActivate =
false;
1850 else if (d->accessKeysActivated)
1852 accessKeysTimeout();
1859 if ( dispatchKeyEvent( _ke ) )
1865 QScrollArea::keyReleaseEvent(_ke);
1871 if (m_part->xmlDocImpl() && focusNextPrevNode(next))
1873 if (m_part->xmlDocImpl()->focusNode())
1874 kDebug() <<
"focusNode.name: "
1875 << m_part->xmlDocImpl()->focusNode()->nodeName().string() << endl;
1880 d->pseudoFocusNode = KHTMLViewPrivate::PFNone;
1884 return QWidget::focusNextPrevChild(next);
1889 QPoint pos = QCursor::pos();
1892 pos = v->viewport()->mapFromGlobal( pos );
1897 pos =
QPoint(pos.x() - viewport()->x(), pos.y() - viewport()->y());
1901 ensureVisible( xm, ym, 0, 5 );
1903 #ifndef KHTML_NO_SELECTION
1906 if (m_part->isExtendingSelection()) {
1907 RenderObject::NodeInfo renderInfo(
true,
false);
1908 m_part->xmlDocImpl()->renderer()->layer()
1909 ->nodeAtPoint(renderInfo, xm, ym);
1910 innerNode = renderInfo.innerNode();
1913 if (innerNode.
handle() && innerNode.
handle()->renderer()
1914 && innerNode.
handle()->renderer()->shouldSelect()) {
1915 m_part->extendSelectionTo(xm, ym, innerNode);
1917 #endif // KHTML_NO_SELECTION
1943 if (!qobject_cast<QFrame*>(w))
1944 w->setAttribute( Qt::WA_NoSystemBackground );
1946 w->setAttribute(Qt::WA_WState_InPaintEvent);
1948 if (!(w->objectName() ==
"KLineEditButton"))
1949 w->setAttribute(Qt::WA_OpaquePaintEvent);
1951 w->installEventFilter(view);
1955 if (qobject_cast<KHTMLView*>(w)) {
1956 handleWidget(static_cast<KHTMLView*>(w)->widget(), view,
false);
1957 handleWidget(static_cast<KHTMLView*>(w)->horizontalScrollBar(), view,
false);
1958 handleWidget(static_cast<KHTMLView*>(w)->verticalScrollBar(), view,
false);
1962 QObjectList children = w->children();
1963 foreach (
QObject*
object, children) {
1970 class KHTMLBackingStoreHackWidget :
public QWidget
1973 void publicEvent(
QEvent *e)
1981 switch (e->type()) {
1984 case QEvent::MouseButtonPress:
1985 case QEvent::MouseButtonRelease:
1986 case QEvent::MouseButtonDblClick:
1987 case QEvent::MouseMove:
1988 #ifndef QT_NO_WHEELEVENT
1991 case QEvent::ContextMenu:
1992 case QEvent::DragEnter:
1993 case QEvent::DragMove:
1994 case QEvent::DragLeave:
2000 return QScrollArea::viewportEvent(e);
2005 w->setAttribute(Qt::WA_WState_InPaintEvent, b);
2009 if (qobject_cast<KHTMLView*>(w)) {
2016 foreach(
QObject* cw, w->children()) {
2017 if (cw->isWidgetType() && !
static_cast<QWidget*
>(cw)->isWindow()
2018 && !(
static_cast<QWidget*
>(cw)->windowModality() & Qt::ApplicationModal)) {
2026 if ( e->type() == QEvent::ShortcutOverride ) {
2027 QKeyEvent* ke = (QKeyEvent*) e;
2029 || (m_part->xmlDocImpl() && m_part->xmlDocImpl()->focusNode()
2030 && m_part->xmlDocImpl()->focusNode()->isContentEditable())) {
2031 if ( (ke->modifiers() & Qt::ControlModifier) || (ke->modifiers() & Qt::ShiftModifier) ) {
2032 switch ( ke->key() ) {
2048 if ( e->type() == QEvent::Leave ) {
2049 if ( d->cursorIconWidget )
2050 d->cursorIconWidget->hide();
2051 m_part->resetHoverText();
2058 else if (e->type() == QEvent::Resize) {
2062 }
else if (o->isWidgetType()) {
2065 while (v && v != view) {
2067 v = v->parentWidget();
2070 if (v && k && k->
m_kwp->isRedirected()) {
2072 bool isUpdate =
false;
2075 case QEvent::UpdateRequest: {
2077 static_cast<KHTMLBackingStoreHackWidget *
>(w)->publicEvent(e);
2081 case QEvent::UpdateLater:
2085 if (!allowWidgetPaintEvents) {
2091 while (v && v->parentWidget() != view) {
2094 v = v->parentWidget();
2101 QRect pr = isUpdate ?
static_cast<QUpdateLaterEvent*
>(e)->region().boundingRect() :
static_cast<QPaintEvent*
>(e)->rect();
2102 bool asap = !d->contentsMoving && qobject_cast<QAbstractScrollArea*>(c);
2107 w->repaint(static_cast<QUpdateLaterEvent*>(e)->region());
2109 w->update(static_cast<QUpdateLaterEvent*>(e)->region());
2114 if ( asap && !isUpdate && !d->painting && m_part->xmlDocImpl() && m_part->xmlDocImpl()->renderer() &&
2115 !
static_cast<khtml::RenderCanvas *
>(m_part->xmlDocImpl()->renderer())->needsLayout() ) {
2117 pr.width(), pr.height()+1);
2119 }
else if (!d->painting) {
2120 scheduleRepaint(x + pr.x(), y + pr.y(),
2121 pr.width(), pr.height()+1, asap);
2125 case QEvent::MouseMove:
2126 case QEvent::MouseButtonPress:
2127 case QEvent::MouseButtonRelease:
2128 case QEvent::MouseButtonDblClick: {
2130 if (0 && w->parentWidget() == view && !qobject_cast<QScrollBar*>(w) && !::qobject_cast<QScrollBar *>(w)) {
2131 QMouseEvent *me =
static_cast<QMouseEvent *
>(e);
2132 QPoint pt = w->mapTo( view, me->pos());
2133 QMouseEvent me2(me->type(), pt, me->button(), me->buttons(), me->modifiers());
2135 if (e->type() == QEvent::MouseMove)
2137 else if(e->type() == QEvent::MouseButtonPress)
2139 else if(e->type() == QEvent::MouseButtonRelease)
2147 case QEvent::KeyPress:
2148 case QEvent::KeyRelease:
2149 if (w->parentWidget() == view && !qobject_cast<QScrollBar*>(w)) {
2150 QKeyEvent *ke =
static_cast<QKeyEvent *
>(e);
2151 if (e->type() == QEvent::KeyPress) {
2161 if (qobject_cast<KUrlRequester*>(w->parentWidget()) &&
2162 e->type() == QEvent::KeyPress) {
2172 case QEvent::FocusIn:
2173 case QEvent::FocusOut: {
2178 block =
static_cast<QFocusEvent*
>(e)->reason() != Qt::MouseFocusReason || root->underMouse();
2192 return QScrollArea::eventFilter(o, e);
2197 switch (e->type()) {
2198 case QEvent::MouseButtonPress:
2199 case QEvent::MouseButtonRelease:
2200 case QEvent::MouseButtonDblClick:
2201 case QEvent::MouseMove:
2203 #ifndef QT_NO_WHEELEVENT
2206 case QEvent::ContextMenu:
2207 case QEvent::DragEnter:
2208 case QEvent::DragMove:
2209 case QEvent::DragLeave:
2211 return QFrame::event(e);
2212 case QEvent::ChildPolished: {
2215 QObject *c =
static_cast<QChildEvent *
>(e)->child();
2216 if (c->isWidgetType()) {
2219 if (!(w->windowFlags() & Qt::Window) && !(w->windowModality() & Qt::ApplicationModal)) {
2221 if (k && k->
m_kwp->isRedirected()) {
2229 case QEvent::Move: {
2230 if (static_cast<QMoveEvent*>(e)->pos() !=
QPoint(0,0)) {
2231 widget()->move(0,0);
2243 bool KHTMLView::hasLayoutPending()
2245 return d->layoutTimerId && !d->firstLayoutPending;
2248 DOM::NodeImpl *KHTMLView::nodeUnderMouse()
const
2250 return d->underMouse;
2253 DOM::NodeImpl *KHTMLView::nonSharedNodeUnderMouse()
const
2255 return d->underMouseNonShared;
2258 bool KHTMLView::scrollTo(
const QRect &bounds)
2260 d->scrollingSelf =
true;
2265 xe = bounds.right();
2266 ye = bounds.bottom();
2276 if (ye-y>curHeight-d->borderY)
2277 ye = y + curHeight - d->borderY;
2279 if (xe-x>curWidth-d->borderX)
2280 xe = x + curWidth - d->borderX;
2286 else if (xe + d->borderX >
contentsX() + curWidth)
2287 deltax = xe + d->borderX - (
contentsX() + curWidth );
2295 else if (ye + d->borderY >
contentsY() + curHeight)
2296 deltay = ye + d->borderY - (
contentsY() + curHeight );
2300 int maxx = curWidth-d->borderX;
2301 int maxy = curHeight-d->borderY;
2303 int scrollX, scrollY;
2305 scrollX = deltax > 0 ? (deltax > maxx ? maxx : deltax) : deltax == 0 ? 0 : (deltax>-maxx ? deltax : -maxx);
2306 scrollY = deltay > 0 ? (deltay > maxy ? maxy : deltay) : deltay == 0 ? 0 : (deltay>-maxy ? deltay : -maxy);
2318 horizontalScrollBar()->setValue( horizontalScrollBar()->value()+scrollX );
2319 verticalScrollBar()->setValue( verticalScrollBar()->value()+scrollY );
2321 d->scrollingSelf =
false;
2323 if ( (abs(deltax)<=maxx) && (abs(deltay)<=maxy) )
2329 bool KHTMLView::focusNextPrevNode(
bool next)
2338 DocumentImpl *doc = m_part->xmlDocImpl();
2339 NodeImpl *oldFocusNode = doc->focusNode();
2346 if ((oldFocusNode->renderer() && !oldFocusNode->renderer()->parent())
2347 || !oldFocusNode->isTabFocusable()) {
2348 doc->quietResetFocus();
2357 if (d->scrollBarMoved)
2361 toFocus = doc->nextFocusNode(oldFocusNode);
2363 toFocus = doc->previousFocusNode(oldFocusNode);
2365 if (!toFocus && oldFocusNode) {
2367 toFocus = doc->nextFocusNode(NULL);
2369 toFocus = doc->previousFocusNode(NULL);
2372 while (toFocus && toFocus != oldFocusNode)
2375 QRect focusNodeRect = toFocus->getRect();
2379 QRect r = toFocus->getRect();
2380 ensureVisible( r.right(), r.bottom());
2381 ensureVisible( r.left(), r.top());
2382 d->scrollBarMoved =
false;
2383 d->tabMovePending =
false;
2384 d->lastTabbingDirection = next;
2385 d->pseudoFocusNode = KHTMLViewPrivate::PFNone;
2386 m_part->xmlDocImpl()->setFocusNode(toFocus);
2387 Node guard(toFocus);
2388 if (!toFocus->hasOneRef() )
2396 toFocus = doc->nextFocusNode(toFocus);
2398 toFocus = doc->previousFocusNode(toFocus);
2400 if (!toFocus && oldFocusNode)
2404 toFocus = doc->nextFocusNode(NULL);
2408 toFocus = doc->previousFocusNode(NULL);
2413 d->scrollBarMoved =
false;
2417 if (!oldFocusNode && d->pseudoFocusNode == KHTMLViewPrivate::PFNone)
2420 d->scrollBarMoved =
false;
2421 d->pseudoFocusNode = next?KHTMLViewPrivate::PFTop:KHTMLViewPrivate::PFBottom;
2425 NodeImpl *newFocusNode = NULL;
2427 if (d->tabMovePending && next != d->lastTabbingDirection)
2430 newFocusNode = oldFocusNode;
2434 if (oldFocusNode || d->pseudoFocusNode == KHTMLViewPrivate::PFTop )
2435 newFocusNode = doc->nextFocusNode(oldFocusNode);
2439 if (oldFocusNode || d->pseudoFocusNode == KHTMLViewPrivate::PFBottom )
2440 newFocusNode = doc->previousFocusNode(oldFocusNode);
2443 bool targetVisible =
false;
2458 if (!m_part->
isCaretMode() && newFocusNode->isContentEditable()) {
2459 kDebug(6200) <<
"show caret! fn: " << newFocusNode->nodeName().string() << endl;
2460 m_part->clearCaretRectIfNeeded();
2465 kDebug(6200) <<
"hide caret! fn: " << newFocusNode->nodeName().string() << endl;
2467 m_part->notifySelectionChanged();
2469 targetVisible = scrollTo(newFocusNode->getRect());
2475 d->tabMovePending =
false;
2477 m_part->xmlDocImpl()->setFocusNode(newFocusNode);
2480 Node guard(newFocusNode);
2481 if (!newFocusNode->hasOneRef() )
2489 d->pseudoFocusNode = next?KHTMLViewPrivate::PFBottom:KHTMLViewPrivate::PFTop;
2495 if (!d->tabMovePending)
2496 d->lastTabbingDirection = next;
2497 d->tabMovePending =
true;
2513 fallbacks = buildFallbackAccessKeys();
2514 for( NodeImpl* n = m_part->xmlDocImpl(); n != NULL; n = n->traverseNextNode()) {
2515 if( n->isElementNode()) {
2516 ElementImpl* en =
static_cast< ElementImpl*
>( n );
2517 DOMString s = en->getAttribute( ATTR_ACCESSKEY );
2520 QChar a = s.
string()[ 0 ].toUpper();
2521 if( qFind( taken.begin(), taken.end(), a ) == taken.end())
2524 if( accesskey.isNull() && fallbacks.contains( en )) {
2525 QChar a = fallbacks[ en ].toUpper();
2526 if( qFind( taken.begin(), taken.end(), a ) == taken.end())
2527 accesskey =
QString(
"<qt><i>" ) + a +
"</i></qt>";
2529 if( !accesskey.isNull()) {
2530 QRect rec=en->getRect();
2532 lab->setAttribute(Qt::WA_DeleteOnClose);
2533 lab->setObjectName(
"KHTMLAccessKey");
2536 lab->setPalette(QToolTip::palette());
2537 lab->setLineWidth(2);
2538 lab->setFrameStyle(QFrame::Box | QFrame::Plain);
2541 lab->setParent( widget() );
2542 lab->setAutoFillBackground(
true);
2547 taken.append( accesskey[ 0 ] );
2556 if( !qobject_cast<KHTMLPart*>(cur) )
2559 if( part->
view() && part->
view() != caller )
2569 bool KHTMLView::isScrollingFromMouseWheel()
const
2571 return d->scrollingFromWheel !=
QPoint(-1,-1);
2574 void KHTMLView::accessKeysTimeout()
2576 d->accessKeysActivated=
false;
2577 d->accessKeysPreActivate =
false;
2578 m_part->setStatusBarText(
QString(), KHTMLPart::BarOverrideText);
2583 bool KHTMLView::handleAccessKey(
const QKeyEvent* ev )
2588 if( ev->key() >= Qt::Key_A && ev->key() <= Qt::Key_Z )
2589 c =
'A' + ev->key() - Qt::Key_A;
2590 else if( ev->key() >= Qt::Key_0 && ev->key() <= Qt::Key_9 )
2591 c =
'0' + ev->key() - Qt::Key_0;
2595 if( ev->text().length() == 1 )
2596 c = ev->text()[ 0 ];
2600 return focusNodeWithAccessKey( c );
2603 bool KHTMLView::focusNodeWithAccessKey( QChar c,
KHTMLView* caller )
2605 DocumentImpl *doc = m_part->xmlDocImpl();
2608 ElementImpl* node = doc->findAccessKeyElement( c );
2612 if( !qobject_cast<KHTMLPart*>(cur) )
2615 if( part->
view() && part->
view() != caller
2616 && part->
view()->focusNodeWithAccessKey( c,
this ))
2622 && m_part->
parentPart()->
view()->focusNodeWithAccessKey( c,
this ))
2624 if( caller == NULL ) {
2627 it != fallbacks.end();
2640 QRect r = node->getRect();
2641 ensureVisible( r.right(), r.bottom());
2642 ensureVisible( r.left(), r.top());
2645 if( node->isFocusable()) {
2646 if (node->id()==ID_LABEL) {
2648 node=
static_cast<ElementImpl *
>(
static_cast< HTMLLabelElementImpl*
>( node )->getFormElement());
2649 if (!node)
return true;
2653 m_part->xmlDocImpl()->setFocusNode(node);
2655 if( node != NULL && node->hasOneRef())
2658 if( node != NULL && node->hasOneRef())
2662 switch( node->id()) {
2664 static_cast< HTMLAnchorElementImpl*
>( node )->click();
2667 static_cast< HTMLInputElementImpl*
>( node )->click();
2670 static_cast< HTMLButtonElementImpl*
>( node )->click();
2673 static_cast< HTMLAreaElementImpl*
>( node )->click();
2687 for( NodeImpl* n = after ? start->nextSibling() : start->traversePreviousNode();
2689 n = after ? n->traverseNextNode() : n->traversePreviousNode()) {
2690 if( n->isTextNode()) {
2692 ret +=
static_cast< TextImpl*
>( n )->toString().string();
2694 ret.prepend( static_cast< TextImpl* >( n )->toString().
string());
2724 if( ret.trimmed().isEmpty())
2728 return ret.simplified();
2732 return ret.simplified();
2738 for( NodeImpl* n = start;
2740 n = n->traverseNextNode()) {
2741 if( n->id() == ID_LABEL ) {
2742 HTMLLabelElementImpl*
label =
static_cast< HTMLLabelElementImpl*
>( n );
2743 NodeImpl* labelfor = label->getFormElement();
2745 ret[ labelfor ] = label->innerText().string().simplified();
2752 struct AccessKeyData {
2753 ElementImpl* element;
2763 QLinkedList< AccessKeyData > data;
2768 for( NodeImpl* n = m_part->xmlDocImpl();
2770 n = n->traverseNextNode()) {
2771 if( n->isElementNode()) {
2772 ElementImpl* element =
static_cast< ElementImpl*
>( n );
2773 if( element->renderer() == NULL )
2778 bool ignore =
false;
2779 bool text_after =
false;
2780 bool text_before =
false;
2781 switch( element->id()) {
2783 url = element->getAttribute(ATTR_HREF).parsedUrl().string();
2786 text =
static_cast< HTMLElementImpl*
>( element )->innerText().string().simplified();
2790 HTMLInputElementImpl* in =
static_cast< HTMLInputElementImpl*
>( element );
2791 switch( in->inputType()) {
2792 case HTMLInputElementImpl::SUBMIT:
2793 text = in->value().string();
2795 text =
i18n(
"Submit" );
2798 case HTMLInputElementImpl::IMAGE:
2799 text = in->altText().string();
2802 case HTMLInputElementImpl::BUTTON:
2803 text = in->value().string();
2806 case HTMLInputElementImpl::RESET:
2807 text = in->value().string();
2809 text =
i18n(
"Reset" );
2812 case HTMLInputElementImpl::HIDDEN:
2815 case HTMLInputElementImpl::CHECKBOX:
2816 case HTMLInputElementImpl::RADIO:
2820 case HTMLInputElementImpl::TEXT:
2821 case HTMLInputElementImpl::PASSWORD:
2822 case HTMLInputElementImpl::FILE:
2833 text =
static_cast< HTMLElementImpl*
>( element )->innerText().string().simplified();
2834 switch( static_cast< HTMLButtonElementImpl* >( element )->buttonType()) {
2835 case HTMLButtonElementImpl::SUBMIT:
2837 text =
i18n(
"Submit" );
2840 case HTMLButtonElementImpl::RESET:
2842 text =
i18n(
"Reset" );
2859 ignore = !element->isFocusable();
2867 DOMString akey = element->getAttribute( ATTR_ACCESSKEY );
2868 if( akey.
length() == 1 ) {
2869 hrefs[url] = akey.
string()[ 0 ].toUpper();
2872 if( text.isNull() && labels.contains( element ))
2873 text = labels[ element ];
2874 if( text.isNull() && text_before )
2876 if( text.isNull() && text_after )
2878 text = text.trimmed();
2883 it != priorities.end();
2885 if( text == (*it).first )
2888 AccessKeyData tmp = { element, text, url, priority };
2894 for(
char c =
'A'; c <=
'Z'; ++c )
2896 for(
char c =
'0'; c <=
'9'; ++c )
2898 for( NodeImpl* n = m_part->xmlDocImpl();
2900 n = n->traverseNextNode()) {
2901 if( n->isElementNode()) {
2902 ElementImpl* en =
static_cast< ElementImpl*
>( n );
2903 DOMString s = en->getAttribute( ATTR_ACCESSKEY );
2905 QChar c = s.
string()[ 0 ].toUpper();
2906 keys.removeAll( c );
2912 for(
int priority = 10; priority >= 0; --priority ) {
2913 for( QLinkedList< AccessKeyData >::Iterator it = data.begin();
2916 if( (*it).priority != priority ) {
2924 const QString url = (*it).url;
2926 if( hrefs.contains( url ) ) {
2927 it = data.erase( it );
2930 if( !text.isEmpty()) {
2934 it != priorities.end();
2936 if( text == (*it).first && keys.contains( (*it).second )) {
2944 if( key.isNull() && !text.isEmpty()) {
2946 for( QStringList::ConstIterator it = words.begin();
2949 if( keys.contains( (*it)[ 0 ].toUpper())) {
2950 key = (*it)[ 0 ].toUpper();
2955 if( key.isNull() && !text.isEmpty()) {
2956 for(
int i = 0; i < text.length(); ++i ) {
2957 if( keys.contains( text[ i ].toUpper())) {
2958 key = text[ i ].toUpper();
2965 ret[ (*it).element ] = key;
2966 keys.removeAll( key );
2967 it = data.erase( it );
2969 if( !url.isEmpty() && !url.startsWith(
"javascript:", Qt::CaseInsensitive )) {
2970 for( QLinkedList< AccessKeyData >::Iterator it2 = data.begin();
2973 if( (*it2).url == url ) {
2974 ret[ (*it2).element ] = key;
2977 it2 = data.erase( it2 );
2987 void KHTMLView::setMediaType(
const QString &medium )
2992 QString KHTMLView::mediaType()
const
2997 bool KHTMLView::pagedMode()
const
3002 void KHTMLView::setWidgetVisible(RenderWidget* w,
bool vis)
3005 d->visibleWidgets.insert(w, w->widget());
3008 d->visibleWidgets.remove(w);
3011 bool KHTMLView::needsFullRepaint()
const
3013 return d->needsFullRepaint;
3017 class QPointerDeleter
3020 explicit QPointerDeleter(
QObject* o) : obj(o) {}
3021 ~QPointerDeleter() {
delete obj; }
3023 const QPointer<QObject> obj;
3029 if(!m_part->xmlDocImpl())
return;
3030 khtml::RenderCanvas *root =
static_cast<khtml::RenderCanvas *
>(m_part->xmlDocImpl()->renderer());
3038 printSettings->setprintFriendly(group.
readEntry(
"PrintFriendly",
true));
3039 printSettings->setprintImages(group.
readEntry(
"PrintImages",
true));
3040 printSettings->setprintHeader(group.
readEntry(
"PrintHeader",
true));
3042 const QPointerDeleter settingsDeleter(printSettings);
3046 const QPointerDeleter dialogDeleter(dialog);
3048 QString docname = m_part->xmlDocImpl()->URL().prettyUrl();
3049 if ( !docname.isEmpty() )
3052 if(quick || (dialog->exec() && dialog)) {
3056 group.
writeEntry(
"PrintFriendly", printSettings->printFriendly());
3057 group.
writeEntry(
"PrintImages", printSettings->printImages());
3058 group.
writeEntry(
"PrintHeader", printSettings->printHeader());
3060 viewport()->setCursor( Qt::WaitCursor );
3062 printer.setFullPage(
false);
3064 printer.setDocName(docname);
3066 QPainter *p =
new QPainter;
3067 p->
begin( &printer );
3068 khtml::setPrintPainter( p );
3070 m_part->xmlDocImpl()->setPaintDevice( &printer );
3071 QString oldMediaType = mediaType();
3072 setMediaType(
"print" );
3076 m_part->xmlDocImpl()->setPrintStyleSheet( printSettings->printFriendly() ?
3077 "* { background-image: none !important;"
3078 " background-color: white !important;"
3079 " color: black !important; }"
3080 "body { margin: 0px !important; }"
3081 "html { margin: 0px !important; }" :
3082 "body { margin: 0px !important; }"
3083 "html { margin: 0px !important; }"
3086 kDebug(6000) <<
"printing: physical page width = " << printer.width()
3087 <<
" height = " << printer.height() << endl;
3088 root->setStaticMode(
true);
3089 root->setPagedMode(
true);
3090 root->setWidth(printer.width());
3092 root->setPageTop(0);
3093 root->setPageBottom(0);
3096 m_part->xmlDocImpl()->styleSelector()->computeFontSizes(printer.logicalDpiY(), 100);
3097 m_part->xmlDocImpl()->updateStyleSelector();
3098 root->setPrintImages(printSettings->printImages());
3099 root->makePageBreakAvoidBlocks();
3101 root->setNeedsLayoutAndMinMaxRecalc();
3106 bool printHeader = printSettings->printHeader();
3108 int headerHeight = 0;
3109 QFont headerFont(
"Sans Serif", 8);
3117 p->setFont(headerFont);
3118 headerHeight = (p->fontMetrics().lineSpacing() * 3) / 2;
3122 kDebug(6000) <<
"printing: html page width = " << root->docWidth()
3123 <<
" height = " << root->docHeight() << endl;
3124 kDebug(6000) <<
"printing: margins left = " << printer.pageRect().left() - printer.paperRect().left()
3125 <<
" top = " << printer.pageRect().top() - printer.paperRect().top() << endl;
3126 kDebug(6000) <<
"printing: paper width = " << printer.width()
3127 <<
" height = " << printer.height() << endl;
3130 int pageWidth = printer.width();
3131 int pageHeight = printer.height();
3132 p->setClipRect(0,0, pageWidth, pageHeight);
3134 pageHeight -= headerHeight;
3136 #ifndef QT_NO_TRANSFORMATIONS
3137 bool scalePage =
false;
3139 if(root->docWidth() > printer.width()) {
3141 scale = ((
double) printer.width())/((
double) root->docWidth());
3142 pageHeight = (
int) (pageHeight/scale);
3143 pageWidth = (
int) (pageWidth/scale);
3144 headerHeight = (
int) (headerHeight/scale);
3147 kDebug(6000) <<
"printing: scaled html width = " << pageWidth
3148 <<
" height = " << pageHeight << endl;
3150 root->setHeight(pageHeight);
3151 root->setPageBottom(pageHeight);
3152 root->setNeedsLayout(
true);
3153 root->layoutIfNeeded();
3159 int available_width = printer.width() - 10 -
3160 2 * qMax(p->boundingRect(0, 0, printer.width(), p->fontMetrics().lineSpacing(), Qt::AlignLeft, headerLeft).width(),
3161 p->boundingRect(0, 0, printer.width(), p->fontMetrics().lineSpacing(), Qt::AlignLeft, headerRight).width());
3162 if (available_width < 150)
3163 available_width = 150;
3168 mid_width = p->boundingRect(0, 0, printer.width(), p->fontMetrics().lineSpacing(), Qt::AlignLeft, headerMid).width();
3170 }
while (mid_width > available_width);
3176 while(top < root->docHeight()) {
3177 if(top > 0) printer.newPage();
3178 #ifndef QT_NO_TRANSFORMATIONS
3180 p->scale(scale, scale);
3183 p->setClipRect(0, 0, pageWidth, headerHeight);
3186 int dy = p->fontMetrics().lineSpacing();
3187 p->setPen(Qt::black);
3188 p->setFont(headerFont);
3190 headerRight =
QString(
"#%1").arg(page);
3192 p->drawText(0, 0, printer.width(), dy, Qt::AlignLeft, headerLeft);
3193 p->drawText(0, 0, printer.width(), dy, Qt::AlignHCenter, headerMid);
3194 p->drawText(0, 0, printer.width(), dy, Qt::AlignRight, headerRight);
3198 p->translate(0, headerHeight-top);
3200 bottom = top+pageHeight;
3202 root->setPageTop(top);
3203 root->setPageBottom(bottom);
3204 root->setPageNumber(page);
3206 root->layer()->paint(p,
QRect(0, top, pageWidth, pageHeight));
3207 kDebug(6000) <<
"printed: page " << page <<
" bottom At = " << bottom;
3210 p->resetTransform();
3218 root->setPagedMode(
false);
3219 root->setStaticMode(
false);
3221 khtml::setPrintPainter( 0 );
3222 setMediaType( oldMediaType );
3223 m_part->xmlDocImpl()->setPaintDevice(
this );
3224 m_part->xmlDocImpl()->styleSelector()->computeFontSizes(m_part->xmlDocImpl()->logicalDpiY(), m_part->
fontScaleFactor());
3225 m_part->xmlDocImpl()->updateStyleSelector();
3226 viewport()->unsetCursor();
3232 if(!m_part->xmlDocImpl())
return;
3233 DOM::DocumentImpl *document = m_part->xmlDocImpl();
3234 if (!document->isHTMLDocument())
return;
3235 khtml::RenderCanvas *root =
static_cast<khtml::RenderCanvas *
>(document->renderer());
3237 root->style()->resetPalette();
3238 NodeImpl *body =
static_cast<HTMLDocumentImpl*
>(document)->body();
3240 body->setChanged(
true);
3241 body->recalcStyle( NodeImpl::Force );
3244 void KHTMLView::paint(QPainter *p,
const QRect &rc,
int yOff,
bool *more)
3246 if(!m_part->xmlDocImpl())
return;
3247 khtml::RenderCanvas *root =
static_cast<khtml::RenderCanvas *
>(m_part->xmlDocImpl()->renderer());
3250 d->firstRepaintPending =
false;
3253 QPaintDevice* opd = m_part->xmlDocImpl()->paintDevice();
3254 m_part->xmlDocImpl()->setPaintDevice(p->device());
3255 root->setPagedMode(
true);
3256 root->setStaticMode(
true);
3257 root->setWidth(rc.width());
3260 QRegion creg = p->clipRegion();
3261 QTransform t = p->worldTransform();
3262 QRect w = p->window();
3263 QRect v = p->viewport();
3264 bool vte = p->viewTransformEnabled();
3265 bool wme = p->worldMatrixEnabled();
3268 p->translate(rc.left(), rc.top());
3269 double scale = ((
double) rc.width()/(
double) root->docWidth());
3270 int height = (
int) ((
double) rc.height() / scale);
3271 #ifndef QT_NO_TRANSFORMATIONS
3272 p->scale(scale, scale);
3274 root->setPageTop(yOff);
3275 root->setPageBottom(yOff+height);
3277 root->layer()->paint(p,
QRect(0, yOff, root->docWidth(), height));
3279 *more = yOff + height < root->docHeight();
3282 p->setWorldTransform(t);
3285 p->setViewTransformEnabled( vte );
3286 p->setWorldMatrixEnabled( wme );
3287 if (!creg.isEmpty())
3288 p->setClipRegion( creg );
3290 p->setClipRegion(QRegion(), Qt::NoClip);
3292 root->setPagedMode(
false);
3293 root->setStaticMode(
false);
3294 m_part->xmlDocImpl()->setPaintDevice( opd );
3297 void KHTMLView::render(QPainter* p,
const QRect& r,
const QPoint& off)
3300 d->firstRepaintPending =
false;
3302 QRect clip(off.x()+r.x(), off.y()+r.y(),r.width(),r.height());
3303 if(!m_part || !m_part->xmlDocImpl() || !m_part->xmlDocImpl()->renderer()) {
3304 p->fillRect(clip, palette().brush(QPalette::Active, QPalette::Base));
3307 QPaintDevice* opd = m_part->xmlDocImpl()->paintDevice();
3308 m_part->xmlDocImpl()->setPaintDevice(p->device());
3311 QRegion creg = p->clipRegion();
3312 QTransform t = p->worldTransform();
3313 QRect w = p->window();
3314 QRect v = p->viewport();
3315 bool vte = p->viewTransformEnabled();
3316 bool wme = p->worldMatrixEnabled();
3318 p->setClipRect(clip);
3322 m_part->xmlDocImpl()->renderer()->layer()->paint(p, rect);
3325 p->setWorldTransform(t);
3328 p->setViewTransformEnabled( vte );
3329 p->setWorldMatrixEnabled( wme );
3330 if (!creg.isEmpty())
3331 p->setClipRegion( creg );
3333 p->setClipRegion(QRegion(), Qt::NoClip);
3335 m_part->xmlDocImpl()->setPaintDevice( opd );
3338 void KHTMLView::setHasStaticBackground(
bool partial)
3341 if (d->staticWidget == KHTMLViewPrivate::SBFull &&
m_kwp->isRedirected())
3344 d->staticWidget = partial ?
3345 KHTMLViewPrivate::SBPartial : KHTMLViewPrivate::SBFull;
3348 void KHTMLView::setHasNormalBackground()
3351 if (d->staticWidget == KHTMLViewPrivate::SBFull &&
m_kwp->isRedirected())
3354 d->staticWidget = KHTMLViewPrivate::SBNone;
3357 void KHTMLView::addStaticObject(
bool fixed)
3360 d->fixedObjectsCount++;
3362 d->staticObjectsCount++;
3364 setHasStaticBackground(
true );
3367 void KHTMLView::removeStaticObject(
bool fixed)
3370 d->fixedObjectsCount--;
3372 d->staticObjectsCount--;
3374 assert( d->fixedObjectsCount >= 0 && d->staticObjectsCount >= 0 );
3376 if (!d->staticObjectsCount && !d->fixedObjectsCount)
3377 setHasNormalBackground();
3379 setHasStaticBackground(
true );
3384 #ifndef KHTML_NO_SCROLLBARS
3385 d->vpolicy = policy;
3386 QScrollArea::setVerticalScrollBarPolicy(policy);
3394 #ifndef KHTML_NO_SCROLLBARS
3395 d->hpolicy = policy;
3396 QScrollArea::setHorizontalScrollBarPolicy(policy);
3402 void KHTMLView::restoreScrollBar()
3405 QScrollArea::setVerticalScrollBarPolicy(d->vpolicy);
3408 d->prevScrollbarVisible = verticalScrollBar()->isVisible();
3415 if (!d->formCompletions)
3417 return d->formCompletions->group(
"").readEntry(name,
QStringList());
3420 void KHTMLView::clearCompletionHistory(
const QString& name)
3422 if (!d->formCompletions)
3426 d->formCompletions->group(
"").writeEntry(name,
"");
3427 d->formCompletions->sync();
3430 void KHTMLView::addFormCompletionItem(
const QString &name,
const QString &value)
3437 bool cc_number(
true);
3438 for (
int i = 0; i < value.length(); ++i)
3441 if (!c.isNumber() && c !=
'-' && !c.isSpace())
3450 if (!items.contains(value))
3451 items.prepend(value);
3453 items.erase(items.isEmpty() ? items.end() : --items.end());
3454 d->formCompletions->group(
"").writeEntry(name, items);
3457 void KHTMLView::addNonPasswordStorableSite(
const QString& host)
3459 if (!d->formCompletions) {
3463 KConfigGroup cg( d->formCompletions,
"NonPasswordStorableSites");
3466 cg.writeEntry(
"Sites", sites);
3471 void KHTMLView::delNonPasswordStorableSite(
const QString& host)
3473 if (!d->formCompletions) {
3477 KConfigGroup cg( d->formCompletions,
"NonPasswordStorableSites");
3479 sites.removeOne(host);
3480 cg.writeEntry(
"Sites", sites);
3484 bool KHTMLView::nonPasswordStorableSite(
const QString& host)
const
3486 if (!d->formCompletions) {
3489 QStringList sites = d->formCompletions->group(
"NonPasswordStorableSites" ).readEntry(
"Sites",
QStringList());
3490 return (sites.indexOf(host) != -1);
3494 bool KHTMLView::dispatchMouseEvent(
int eventId, DOM::NodeImpl *targetNode,
3495 DOM::NodeImpl *targetNodeNonShared,
bool cancelable,
3496 int detail,QMouseEvent *_mouse,
bool setUnder,
3497 int mouseEventType,
int orient)
3500 if (targetNode && targetNode->isTextNode())
3501 targetNode = targetNode->parentNode();
3504 d->underMouse->deref();
3505 d->underMouse = targetNode;
3507 d->underMouse->ref();
3509 if (d->underMouseNonShared)
3510 d->underMouseNonShared->deref();
3511 d->underMouseNonShared = targetNodeNonShared;
3512 if (d->underMouseNonShared)
3513 d->underMouseNonShared->ref();
3515 bool isWheelEvent = (mouseEventType == DOM::NodeImpl::MouseWheel);
3517 int exceptioncode = 0;
3518 int pageX = _mouse->x();
3519 int pageY = _mouse->y();
3520 revertTransforms(pageX, pageY);
3523 int screenX = _mouse->globalX();
3524 int screenY = _mouse->globalY();
3526 switch (_mouse->button()) {
3527 case Qt::LeftButton:
3533 case Qt::RightButton:
3539 if (d->accessKeysEnabled && d->accessKeysPreActivate && button!=-1)
3540 d->accessKeysPreActivate=
false;
3542 bool ctrlKey = (_mouse->modifiers() & Qt::ControlModifier);
3543 bool altKey = (_mouse->modifiers() & Qt::AltModifier);
3544 bool shiftKey = (_mouse->modifiers() & Qt::ShiftModifier);
3545 bool metaKey = (_mouse->modifiers() & Qt::MetaModifier);
3548 if (setUnder && d->oldUnderMouse != targetNode) {
3549 if (d->oldUnderMouse && d->oldUnderMouse->document() != m_part->xmlDocImpl()) {
3550 d->oldUnderMouse->deref();
3551 d->oldUnderMouse = 0;
3554 if (d->oldUnderMouse) {
3556 MouseEventImpl *me =
new MouseEventImpl(EventImpl::MOUSEOUT_EVENT,
3557 true,
true,m_part->xmlDocImpl()->defaultView(),
3558 0,screenX,screenY,clientX,clientY,pageX, pageY,
3559 ctrlKey,altKey,shiftKey,metaKey,
3562 d->oldUnderMouse->dispatchEvent(me,exceptioncode,
true);
3567 MouseEventImpl *me =
new MouseEventImpl(EventImpl::MOUSEOVER_EVENT,
3568 true,
true,m_part->xmlDocImpl()->defaultView(),
3569 0,screenX,screenY,clientX,clientY,pageX, pageY,
3570 ctrlKey,altKey,shiftKey,metaKey,
3571 button,d->oldUnderMouse);
3574 targetNode->dispatchEvent(me,exceptioncode,
true);
3577 if (d->oldUnderMouse)
3578 d->oldUnderMouse->deref();
3579 d->oldUnderMouse = targetNode;
3580 if (d->oldUnderMouse)
3581 d->oldUnderMouse->ref();
3584 bool swallowEvent =
false;
3588 if (targetNode->isGenericFormElement()
3589 &&
static_cast<HTMLGenericFormElementImpl*
>(targetNode)->disabled())
3593 bool dblclick = ( eventId == EventImpl::CLICK_EVENT &&
3594 _mouse->type() == QEvent::MouseButtonDblClick );
3595 MouseEventImpl *me =
new MouseEventImpl(static_cast<EventImpl::EventId>(eventId),
3596 true,cancelable,m_part->xmlDocImpl()->defaultView(),
3597 detail,screenX,screenY,clientX,clientY,pageX, pageY,
3598 ctrlKey,altKey,shiftKey,metaKey,
3599 button,0, isWheelEvent ? 0 : _mouse, dblclick,
3600 isWheelEvent ?
static_cast<MouseEventImpl::Orientation
>(orient) : MouseEventImpl::ONone );
3602 if ( !d->m_mouseEventsTarget && RenderLayer::gScrollBar && eventId == EventImpl::MOUSEDOWN_EVENT )
3604 d->m_mouseEventsTarget = RenderLayer::gScrollBar;
3605 if ( d->m_mouseEventsTarget && qobject_cast<QScrollBar*>(d->m_mouseEventsTarget) &&
3606 dynamic_cast<KHTMLWidget*>(static_cast<QWidget*>(d->m_mouseEventsTarget)) ) {
3611 QMouseEvent fw(_mouse->type(),
QPoint(pageX, pageY)-p, _mouse->button(), _mouse->buttons(), _mouse->modifiers());
3612 static_cast<RenderWidget::EventPropagator *
>(
static_cast<QWidget*
>(d->m_mouseEventsTarget))->sendEvent(&fw);
3613 if (_mouse->type() == QMouseEvent::MouseButtonPress && _mouse->button() == Qt::RightButton) {
3614 QContextMenuEvent cme(QContextMenuEvent::Mouse, p);
3615 static_cast<RenderWidget::EventPropagator *
>(
static_cast<QWidget*
>(d->m_mouseEventsTarget))->sendEvent(&cme);
3616 d->m_mouseEventsTarget = 0;
3618 swallowEvent =
true;
3620 targetNode->dispatchEvent(me,exceptioncode,
true);
3621 bool defaultHandled = me->defaultHandled();
3622 if (defaultHandled || me->defaultPrevented())
3623 swallowEvent =
true;
3625 if (eventId == EventImpl::MOUSEDOWN_EVENT && !me->defaultPrevented()) {
3630 DOM::NodeImpl* nodeImpl = targetNode;
3631 for ( ; nodeImpl && !nodeImpl->isFocusable(); nodeImpl = nodeImpl->parentNode())
3633 if (nodeImpl && nodeImpl->isMouseFocusable())
3634 m_part->xmlDocImpl()->setFocusNode(nodeImpl);
3635 else if (!nodeImpl || !nodeImpl->focused())
3636 m_part->xmlDocImpl()->setFocusNode(0);
3641 return swallowEvent;
3644 void KHTMLView::setIgnoreWheelEvents(
bool e )
3646 d->ignoreWheelEvents = e;
3649 #ifndef QT_NO_WHEELEVENT
3655 if (d->scrollingFromWheel !=
QPoint(-1,-1) && d->scrollingFromWheel != QCursor::pos())
3656 d->scrollingFromWheel = d->scrollingFromWheelTimerId ? QCursor::pos() :
QPoint(-1,-1);
3658 if (d->accessKeysEnabled && d->accessKeysPreActivate) d->accessKeysPreActivate=
false;
3660 if ( ( e->modifiers() & Qt::ControlModifier) == Qt::ControlModifier )
3665 else if (d->firstLayoutPending)
3669 else if( !
m_kwp->isRedirected() &&
3670 ( (e->orientation() == Qt::Vertical &&
3671 ((d->ignoreWheelEvents && !verticalScrollBar()->isVisible())
3675 (e->orientation() == Qt::Horizontal &&
3676 ((d->ignoreWheelEvents && !horizontalScrollBar()->isVisible())
3689 revertTransforms(xm, ym);
3691 DOM::NodeImpl::MouseEvent mev( e->buttons(), DOM::NodeImpl::MouseWheel );
3692 m_part->xmlDocImpl()->prepareMouseEvent(
false, xm, ym, &mev );
3694 MouseEventImpl::Orientation o = MouseEventImpl::OVertical;
3695 if (e->orientation() == Qt::Horizontal)
3696 o = MouseEventImpl::OHorizontal;
3698 QMouseEvent _mouse(QEvent::MouseMove, e->pos(), Qt::NoButton, e->buttons(), e->modifiers());
3699 bool swallow = dispatchMouseEvent(EventImpl::KHTML_MOUSEWHEEL_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),
3700 true,-e->delta()/40,&_mouse,
true,DOM::NodeImpl::MouseWheel,o);
3705 d->scrollBarMoved =
true;
3706 d->scrollingFromWheel = QCursor::pos();
3708 d->shouldSmoothScroll =
true;
3709 if (d->scrollingFromWheelTimerId)
3710 killTimer(d->scrollingFromWheelTimerId);
3711 d->scrollingFromWheelTimerId = startTimer(400);
3715 bool h = (
static_cast<QWheelEvent*
>(e)->orientation() == Qt::Horizontal);
3716 bool d = (
static_cast<QWheelEvent*
>(e)->delta() < 0);
3717 QScrollBar* hsb = horizontalScrollBar();
3718 QScrollBar* vsb = verticalScrollBar();
3719 if ( (h && ((d && hsb->value() == hsb->maximum()) || (!d && hsb->value() == hsb->minimum()))) ||
3720 (!h && ((d && vsb->value() == vsb->maximum()) || (!d && vsb->value() == vsb->minimum()))) ) {
3725 QScrollArea::wheelEvent( e );
3734 QScrollArea::dragEnterEvent( ev );
3740 QScrollArea::dropEvent( ev );
3745 DOM::NodeImpl* fn = m_part->xmlDocImpl() ? m_part->xmlDocImpl()->focusNode() : 0;
3746 if (fn && fn->renderer() && fn->renderer()->isWidget() &&
3747 (e->reason() != Qt::MouseFocusReason) &&
3748 static_cast<khtml::RenderWidget*>(fn->renderer())->widget())
3749 static_cast<khtml::RenderWidget*>(fn->renderer())->widget()->setFocus();
3750 m_part->setSelectionVisible();
3751 QScrollArea::focusInEvent( e );
3757 m_part->stopAutoScroll();
3758 m_part->setSelectionVisible(
false);
3761 if ( d->cursorIconWidget )
3762 d->cursorIconWidget->hide();
3764 QScrollArea::focusOutEvent( e );
3769 if (!dx && !dy)
return;
3771 if ( !d->firstLayoutPending && !d->complete && m_part->xmlDocImpl() &&
3772 d->layoutSchedulingEnabled) {
3774 khtml::RenderCanvas* root =
static_cast<khtml::RenderCanvas *
>( m_part->xmlDocImpl()->renderer() );
3775 if (root && root->needsLayout()) {
3776 unscheduleRelayout();
3781 if ( d->shouldSmoothScroll && d->smoothScrollMode !=
SSMDisabled && m_part->xmlDocImpl() &&
3784 bool doSmoothScroll = (!d->staticWidget || d->smoothScrollMode ==
SSMEnabled);
3786 int numStaticPixels = 0;
3787 QRegion r =
static_cast<RenderCanvas*
>(m_part->xmlDocImpl()->renderer())->staticRegion();
3790 if (!doSmoothScroll && d->staticWidget == KHTMLViewPrivate::SBPartial && r.rects().size() <= 10) {
3791 foreach(
const QRect &rr, r.rects())
3792 numStaticPixels += rr.width()*rr.height();
3794 doSmoothScroll =
true;
3796 if (doSmoothScroll) {
3797 setupSmoothScrolling(dx, dy);
3802 if ( underMouse() && QToolTip::isVisible() )
3803 QToolTip::hideText();
3805 if (!d->scrollingSelf) {
3806 d->scrollBarMoved =
true;
3807 d->contentsMoving =
true;
3809 scheduleRepaint(0, 0, 0, 0);
3812 if (m_part->xmlDocImpl() && m_part->xmlDocImpl()->documentElement()) {
3813 m_part->xmlDocImpl()->documentElement()->dispatchHTMLEvent(EventImpl::SCROLL_EVENT,
true,
false);
3816 if (QApplication::isRightToLeft())
3819 if (!d->smoothScrolling) {
3820 d->updateContentsXY();
3825 if (widget()->pos() !=
QPoint(0,0)) {
3826 kDebug(6000) <<
"Static widget wasn't positioned at (0,0). This should NOT happen. Please report this event to developers.";
3827 kDebug(6000) << kBacktrace();
3828 widget()->move(0,0);
3833 if (
m_kwp->isRedirected()) {
3838 off = viewport()->mapTo(
this, off);
3841 if ( d->staticWidget ) {
3845 if (!d->visibleWidgets.isEmpty())
3846 checkExternalWidgetsPosition();
3848 if ( d->staticWidget == KHTMLViewPrivate::SBPartial
3849 && m_part->xmlDocImpl() && m_part->xmlDocImpl()->renderer() ) {
3851 QRegion r =
static_cast<RenderCanvas*
>(m_part->xmlDocImpl()->renderer())->staticRegion();
3855 for (
int i = 0; i < ar.size() ; ++i) {
3856 widget()->update( ar[i] );
3860 for (
int i = 0; i < ar.size() ; ++i) {
3861 w->scroll( dx, dy, ar[i].translated(off) );
3863 d->scrollExternalWidgets(dx, dy);
3868 if (d->accessKeysActivated)
3869 d->scrollAccessKeys(dx, dy);
3874 if (
m_kwp->isRedirected()) {
3876 w->scroll(dx, dy, rect);
3877 if (d->zoomLevel != 100) {
3881 widget()->scroll(dx, dy, widget()->rect() & viewport()->rect());
3884 d->scrollExternalWidgets(dx, dy);
3885 if (d->accessKeysActivated)
3886 d->scrollAccessKeys(dx, dy);
3889 void KHTMLView::setupSmoothScrolling(
int dx,
int dy)
3892 int ddx = qMax(d->steps ? abs(d->dx)/d->steps : 0,3);
3893 int ddy = qMax(d->steps ? abs(d->dy)/d->steps : 0,3);
3899 if (d->dx == 0 && d->dy == 0) {
3906 if (qMax(abs(d->dx), abs(d->dy)) / d->steps < qMax(ddx,ddy)) {
3909 d->steps = qMax((abs(d->dx)+ddx-1)/ddx, (abs(d->dy)+ddy-1)/ddy);
3910 if (d->steps < 1) d->steps = 1;
3913 d->smoothScrollStopwatch.start();
3914 if (!d->smoothScrolling) {
3915 d->startScrolling();
3920 void KHTMLView::scrollTick() {
3921 if (d->dx == 0 && d->dy == 0) {
3926 if (d->steps < 1) d->steps = 1;
3930 if (takesteps < 1) takesteps = 1;
3931 if (takesteps > d->steps) takesteps = d->steps;
3932 for(
int i = 0; i < takesteps; i++) {
3933 int ddx = (d->dx / (d->steps+1)) * 2;
3934 int ddy = (d->dy / (d->steps+1)) * 2;
3937 if (abs(ddx) > abs(d->dx)) ddx = d->dx;
3938 if (abs(ddy) > abs(d->dy)) ddy = d->dy;
3948 d->shouldSmoothScroll =
false;
3951 if (takesteps < 2) {
3952 d->smoothScrollMissedDeadlines = 0;
3954 if (d->smoothScrollMissedDeadlines !=
sWayTooMany &&
3955 (!m_part->xmlDocImpl() || !m_part->xmlDocImpl()->parsing())) {
3956 d->smoothScrollMissedDeadlines++;
3972 if (child->parent() != widget())
3973 child->setParent( widget() );
3983 if ( e->timerId() == d->scrollTimerId ) {
3984 if( d->scrollSuspended )
3986 switch (d->scrollDirection) {
3987 case KHTMLViewPrivate::ScrollDown:
3989 d->newScrollTimer(
this, 0);
3991 verticalScrollBar()->setValue( verticalScrollBar()->value() +d->scrollBy );
3993 case KHTMLViewPrivate::ScrollUp:
3995 d->newScrollTimer(
this, 0);
3997 verticalScrollBar()->setValue( verticalScrollBar()->value() -d->scrollBy );
3999 case KHTMLViewPrivate::ScrollRight:
4001 d->newScrollTimer(
this, 0);
4003 horizontalScrollBar()->setValue( horizontalScrollBar()->value() +d->scrollBy );
4005 case KHTMLViewPrivate::ScrollLeft:
4007 d->newScrollTimer(
this, 0);
4009 horizontalScrollBar()->setValue( horizontalScrollBar()->value() -d->scrollBy );
4014 else if ( e->timerId() == d->scrollingFromWheelTimerId ) {
4015 killTimer( d->scrollingFromWheelTimerId );
4016 d->scrollingFromWheelTimerId = 0;
4017 }
else if ( e->timerId() == d->layoutTimerId ) {
4018 if (d->firstLayoutPending && d->layoutAttemptCounter < 4
4019 && (!m_part->xmlDocImpl() || !m_part->xmlDocImpl()->readyForLayout())) {
4020 d->layoutAttemptCounter++;
4021 killTimer(d->layoutTimerId);
4022 d->layoutTimerId = 0;
4027 d->scheduledLayoutCounter++;
4028 if (d->firstLayoutPending) {
4029 d->firstLayoutPending =
false;
4030 verticalScrollBar()->setEnabled(
true );
4031 horizontalScrollBar()->setEnabled(
true );
4035 d->contentsMoving =
false;
4036 if( m_part->xmlDocImpl() ) {
4037 DOM::DocumentImpl *document = m_part->xmlDocImpl();
4038 khtml::RenderCanvas* root =
static_cast<khtml::RenderCanvas *
>(document->renderer());
4040 if ( root && root->needsLayout() ) {
4041 if (d->repaintTimerId)
4042 killTimer(d->repaintTimerId);
4043 d->repaintTimerId = 0;
4049 if (d->repaintTimerId)
4050 killTimer(d->repaintTimerId);
4051 d->repaintTimerId = 0;
4056 d->updateRegion = QRegion();
4059 updateRegion = rects[0];
4061 for (
int i = 1; i < rects.size(); ++i ) {
4062 QRect newRegion = updateRegion.unite(rects[i]);
4063 if (2*newRegion.height() > 3*updateRegion.height() )
4066 updateRegion = rects[i];
4069 updateRegion = newRegion;
4072 if ( !updateRegion.isNull() )
4080 if (d->dirtyLayout && !d->visibleWidgets.isEmpty())
4081 checkExternalWidgetsPosition();
4083 d->dirtyLayout =
false;
4086 if (d->emitCompletedAfterRepaint) {
4087 bool full = d->emitCompletedAfterRepaint == KHTMLViewPrivate::CSFull;
4088 d->emitCompletedAfterRepaint = KHTMLViewPrivate::CSNone;
4096 void KHTMLView::checkExternalWidgetsPosition()
4101 QHashIterator<void*, QWidget*> it(d->visibleWidgets);
4102 while (it.hasNext()) {
4105 RenderWidget* rw =
static_cast<RenderWidget*
>( it.key() );
4106 if (!rw->absolutePosition(xp, yp) ||
4107 !visibleRect.intersects(
QRect(xp, yp, it.value()->width(), it.value()->height())))
4108 toRemove.append(rw);
4110 foreach (RenderWidget* r, toRemove)
4111 if ( (w = d->visibleWidgets.take(r) ) )
4112 w->move( 0, -500000);
4115 void KHTMLView::scheduleRelayout(khtml::RenderObject * )
4117 if (!d->layoutSchedulingEnabled || d->layoutTimerId)
4121 if (d->firstLayoutPending) {
4125 time = d->layoutAttemptCounter ?
4127 }
else if (m_part->xmlDocImpl() && m_part->xmlDocImpl()->parsing()) {
4132 d->layoutTimerId = startTimer( time );
4135 void KHTMLView::unscheduleRelayout()
4137 if (!d->layoutTimerId)
4140 killTimer(d->layoutTimerId);
4141 d->layoutTimerId = 0;
4144 void KHTMLView::unscheduleRepaint()
4146 if (!d->repaintTimerId)
4149 killTimer(d->repaintTimerId);
4150 d->repaintTimerId = 0;
4153 void KHTMLView::scheduleRepaint(
int x,
int y,
int w,
int h,
bool asap)
4155 bool parsing = !m_part->xmlDocImpl() || m_part->xmlDocImpl()->parsing();
4160 int time = parsing && !d->firstLayoutPending ? 150 : (!asap ? ( !d->complete ? 80 : 20 ) : 0);
4162 #ifdef DEBUG_FLICKER
4164 p.begin( viewport() );
4168 p.fillRect( vx, vy, w, h, Qt::red );
4172 d->updateRegion = d->updateRegion.unite(
QRect(x,y,w,h));
4174 if (asap && !parsing)
4175 unscheduleRepaint();
4177 if ( !d->repaintTimerId )
4178 d->repaintTimerId = startTimer( time );
4183 void KHTMLView::complete(
bool pendingAction )
4190 if (d->layoutTimerId)
4194 killTimer(d->layoutTimerId);
4195 d->layoutTimerId = startTimer( 0 );
4196 d->emitCompletedAfterRepaint = pendingAction ?
4197 KHTMLViewPrivate::CSActionPending : KHTMLViewPrivate::CSFull;
4201 if (d->repaintTimerId)
4205 killTimer(d->repaintTimerId);
4206 d->repaintTimerId = startTimer( 0 );
4207 d->emitCompletedAfterRepaint = pendingAction ?
4208 KHTMLViewPrivate::CSActionPending : KHTMLViewPrivate::CSFull;
4211 if (!d->emitCompletedAfterRepaint)
4221 void KHTMLView::updateScrollBars()
4223 const QWidget *view = widget();
4227 QSize p = viewport()->size();
4228 QSize m = maximumViewportSize();
4230 if (m.expandedTo(view->size()) == m)
4233 QSize v = view->size();
4234 horizontalScrollBar()->setRange(0, v.width() - p.width());
4235 horizontalScrollBar()->setPageStep(p.width());
4236 verticalScrollBar()->setRange(0, v.height() - p.height());
4237 verticalScrollBar()->setPageStep(p.height());
4238 if (!d->smoothScrolling) {
4239 d->updateContentsXY();
4243 void KHTMLView::slotMouseScrollTimer()
4245 horizontalScrollBar()->setValue( horizontalScrollBar()->value() +d->m_mouseScroll_byX );
4246 verticalScrollBar()->setValue( verticalScrollBar()->value() +d->m_mouseScroll_byY);
4252 Selection sel = pos;
4253 sel.expandUsingGranularity(Selection::LINE);
4254 return toEnd ? sel.end() : sel.start();
4267 bool KHTMLView::caretKeyPressEvent(QKeyEvent *_ke)
4271 Position old_pos = caret.caretPos();
4272 Position pos = old_pos;
4273 bool recalcXPos =
true;
4274 bool handled =
true;
4276 bool ctrl = _ke->modifiers() & Qt::ControlModifier;
4277 bool shift = _ke->modifiers() & Qt::ShiftModifier;
4279 switch(_ke->key()) {
4283 pos = old_pos.nextLinePosition(caret.xPosForVerticalArrowNavigation(Selection::EXTENT));
4288 pos = old_pos.previousLinePosition(caret.xPosForVerticalArrowNavigation(Selection::EXTENT));
4293 pos = ctrl ? old_pos.previousWordPosition() : old_pos.previousCharacterPosition();
4297 pos = ctrl ? old_pos.nextWordPosition() : old_pos.nextCharacterPosition();
4300 case Qt::Key_PageDown:
4304 case Qt::Key_PageUp:
4327 if (pos != old_pos) {
4328 m_part->clearCaretRectIfNeeded();
4330 caret.moveTo(shift ? caret.nonCaretPos() : pos, pos);
4331 int old_x = caret.xPosForVerticalArrowNavigation(Selection::CARETPOS);
4333 m_part->selectionLayoutChanged();
4339 m_part->emitCaretPositionChanged(pos);
4341 m_part->notifySelectionChanged();
4345 if (handled) _ke->accept();
4349 #undef DEBUG_CARETMODE
QString i18n(const char *text)
SmoothScrollingMode smoothScrollingMode() const
Retrieve the current smooth scrolling mode.
Contextual information about the caret and the built-in editor.
bool changeCursor() const
void updateContents(const QRect &r)
Requests an update of the content area.
SmoothScrollingMode
Smooth Scrolling Mode enumeration.
void setSmoothScrollingModeDefault(SmoothScrollingMode m)
QList< QPair< QString, QChar > > fallbackAccessKeysAssignments() const
static const int sSmoothScrollMinStaticPixels
virtual void mouseDoubleClickEvent(QMouseEvent *)
QCursor urlCursor() const
Returns the cursor which is used when the cursor is on a link.
DOM::Selection m_selection
static QMap< NodeImpl *, QString > buildLabels(NodeImpl *start)
bool isFormCompletionEnabled() const
The Node interface is the primary datatype for the entire Document Object Model.
void setSmoothScrollingMode(SmoothScrollingMode m)
Set the smooth scrolling mode.
static QString getElementText(NodeImpl *start, bool after)
int maxFormCompletionItems() const
khtml::EditorContext editor_context
static const int sLayoutAttemptDelay
static DOM::Position positionOfLineEnd(const DOM::Position &pos)
QString label(StandardShortcut id)
int contentsY() const
Returns the y coordinate of the contents area point that is currently located at the top left in the ...
virtual void focusOutEvent(QFocusEvent *)
QPoint contentsToViewport(const QPoint &p) const
Returns a point translated to viewport coordinates.
void addChild(QWidget *child, int dx, int dy)
bool frameExists(const QString &frameName)
Returns whether a frame with the specified name is exists or not.
This class is khtml's main class.
static bool findImageMapRect(HTMLImageElementImpl *img, const QPoint &scrollOfs, const QPoint &p, QRect &r, QString &s)
calculates the client-side image map rectangle for the given image element
Renders and displays HTML in a QScrollArea.
void writeEntry(const QString &key, const QVariant &value, WriteConfigFlags pFlags=Normal)
virtual bool eventFilter(QObject *, QEvent *)
static KHTMLSettings * defaultHTMLSettings()
static const int sSmoothScrollTick
QPrintDialog * createPrintDialog(QPrinter *printer, PageSelectPolicy pageSelectPolicy, const QList< QWidget * > &customTabs, QWidget *parent=0)
void setContentsPos(int x, int y)
Place the contents area point x/y at the top left of the viewport.
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
bool m_beganSelectingText
static DOM::Position positionOfLineBegin(const DOM::Position &pos)
virtual bool focusNextPrevChild(bool next)
KSharedConfigPtr config()
virtual void closeEvent(QCloseEvent *)
KHTMLView * view() const
Returns a pointer to the HTML document's view.
virtual void mousePressEvent(QMouseEvent *)
KHTMLPart * part() const
Returns a pointer to the KHTMLPart that is rendering the page.
virtual void scrollContentsBy(int dx, int dy)
int visibleWidth() const
Returns the width of the viewport.
QList< KParts::ReadOnlyPart * > frames() const
int visibleHeight() const
Returns the height of the viewport.
void layout()
ensure the display is up to date
QPixmap loadIcon(const QString &name, KIconLoader::Group group, int size=0, int state=KIconLoader::DefaultState, const QStringList &overlays=QStringList(), QString *path_store=0L, bool canReturnNull=false) const
virtual void focusInEvent(QFocusEvent *)
void setCaretVisible(bool show)
Sets the visibility of the caret.
static const int sParsingLayoutsInterval
virtual void setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy)
Sets vertical scrollbar mode.
int contentsHeight() const
Returns the contents area's height.
int m_xPosForVerticalArrowNavigation
virtual void dragEnterEvent(QDragEnterEvent *)
virtual void hideEvent(QHideEvent *)
This class implements the basic string we use in the DOM.
virtual void begin(const KUrl &url=KUrl(), int xOffset=0, int yOffset=0)
Clears the widget and prepares it for new content.
void keyPressEvent(QKeyEvent *_ke)
QString csqueeze(const QString &str, int maxlen=40)
static void handleWidget(QWidget *w, KHTMLView *view, bool recurse=true)
static const int sFirstLayoutDelay
if(yyss+yystacksize-1<=yyssp)
static const int sLayoutAttemptIncrement
virtual void paintEvent(QPaintEvent *)
static KIconLoader * iconLoader()
void setMarginWidth(int x)
Sets a margin in x direction.
static const int sMaxMissedDeadlines
void scrollBy(int x, int y)
Scrolls the content area by a given amount.
friend class KHTMLViewPrivate
static const int sParsingLayoutsIncrement
bool accessKeysEnabled() const
virtual void mouseMoveEvent(QMouseEvent *)
void timerEvent(QTimerEvent *)
QPoint viewportToContents(const QPoint &p) const
Returns a point translated to contents area coordinates.
virtual void resizeEvent(QResizeEvent *event)
void setZoomLevel(int percent)
Apply a zoom level to the content area.
virtual void setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy policy)
Sets horizontal scrollbar mode.
static const int sSmoothScrollTime
virtual bool event(QEvent *event)
static const int sWayTooMany
virtual bool widgetEvent(QEvent *)
static QString locateLocal(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
bool isEditable() const
Returns true if the document is editable, false otherwise.
void finishedLayout()
This signal is used for internal layouting.
virtual bool viewportEvent(QEvent *e)
int contentsX() const
Returns the x coordinate of the contents area point that is currently located at the top left in the ...
bool isCaretMode() const
Returns whether caret mode is on/off.
void installEventFilter(QWidget *filter)
void setMarginHeight(int y)
QWeakPointer< DOM::HTMLPartContainerElementImpl > m_partContainerElement
#define KDE_VERSION_MAJOR
int fontScaleFactor() const
Returns the current font scale factor.
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
void print(bool quick=false)
Prints the HTML document.
QString formatDate(const QDate &date, DateFormat format=LongDate) const
virtual void wheelEvent(QWheelEvent *)
int contentsWidth() const
Returns the contents area's width.
#define KDE_VERSION_MINOR
void nodeActivated(const DOM::Node &)
This signal is emitted when an element retrieves the keyboard focus.
void repaintContents(const QRect &r)
Requests an immediate repaint of the content area.
virtual void dropEvent(QDropEvent *)
NodeImpl * handle() const
T readEntry(const QString &key, const T &aDefault) const
void keyReleaseEvent(QKeyEvent *_ke)
const KHTMLSettings * settings() const
virtual void showEvent(QShowEvent *)
static DOM::Position positionOfLineBoundary(const DOM::Position &pos, bool toEnd)
KHTMLView(KHTMLPart *part, QWidget *parent)
Constructs a KHTMLView.
static bool targetOpensNewWindow(KHTMLPart *part, QString target)
int zoomLevel() const
Retrieve the current zoom level.
KAction * close(const QObject *recvr, const char *slot, QObject *parent)
virtual void resizeContents(int w, int h)
Resize the contents area.
virtual void mouseReleaseEvent(QMouseEvent *)
void displayAccessKeys()
Display all accesskeys in small tooltips.
KHTMLPart * parentPart()
Returns a pointer to the parent KHTMLPart if the part is a frame in an HTML frameset.
#define KDE_VERSION_RELEASE
static void setInPaintEventFlag(QWidget *w, bool b=true, bool recurse=true)
void slotPaletteChanged()