00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "tdehtmlview.moc"
00028
00029 #include "tdehtmlview.h"
00030
00031 #include "tdehtml_part.h"
00032 #include "tdehtml_events.h"
00033
00034 #include "html/html_documentimpl.h"
00035 #include "html/html_inlineimpl.h"
00036 #include "html/html_formimpl.h"
00037 #include "rendering/render_arena.h"
00038 #include "rendering/render_canvas.h"
00039 #include "rendering/render_frames.h"
00040 #include "rendering/render_replaced.h"
00041 #include "rendering/render_layer.h"
00042 #include "rendering/render_line.h"
00043 #include "rendering/render_table.h"
00044
00045 #define protected public
00046 #include "rendering/render_text.h"
00047 #undef protected
00048 #include "xml/dom2_eventsimpl.h"
00049 #include "css/cssstyleselector.h"
00050 #include "css/csshelper.h"
00051 #include "misc/htmlhashes.h"
00052 #include "misc/helper.h"
00053 #include "misc/loader.h"
00054 #include "tdehtml_settings.h"
00055 #include "tdehtml_printsettings.h"
00056
00057 #include "tdehtmlpart_p.h"
00058
00059 #ifndef TDEHTML_NO_CARET
00060 #include "tdehtml_caret_p.h"
00061 #include "xml/dom2_rangeimpl.h"
00062 #endif
00063
00064 #include <tdeapplication.h>
00065 #include <kcursor.h>
00066 #include <kdebug.h>
00067 #include <kdialogbase.h>
00068 #include <kiconloader.h>
00069 #include <kimageio.h>
00070 #include <tdelocale.h>
00071 #include <knotifyclient.h>
00072 #include <kprinter.h>
00073 #include <ksimpleconfig.h>
00074 #include <kstandarddirs.h>
00075 #include <tdestdaccel.h>
00076 #include <kstringhandler.h>
00077 #include <kurldrag.h>
00078
00079 #include <tqbitmap.h>
00080 #include <tqlabel.h>
00081 #include <tqobjectlist.h>
00082 #include <tqpaintdevicemetrics.h>
00083 #include <tqpainter.h>
00084 #include <tqptrdict.h>
00085 #include <tqtooltip.h>
00086 #include <tqstring.h>
00087 #include <tqstylesheet.h>
00088 #include <tqtimer.h>
00089 #include <tqvaluevector.h>
00090
00091
00092
00093
00094
00095
00096
00097 #ifdef Q_WS_X11
00098 #include <X11/Xlib.h>
00099 #include <fixx11h.h>
00100 #endif
00101
00102 #define PAINT_BUFFER_HEIGHT 128
00103
00104 #if 0
00105 namespace tdehtml {
00106 void dumpLineBoxes(RenderFlow *flow);
00107 }
00108 #endif
00109
00110 using namespace DOM;
00111 using namespace tdehtml;
00112 class TDEHTMLToolTip;
00113
00114
00115 #ifndef QT_NO_TOOLTIP
00116
00117 class TDEHTMLToolTip : public TQToolTip
00118 {
00119 public:
00120 TDEHTMLToolTip(TDEHTMLView *view, TDEHTMLViewPrivate* vp) : TQToolTip(view->viewport())
00121 {
00122 m_view = view;
00123 m_viewprivate = vp;
00124 };
00125
00126 protected:
00127 virtual void maybeTip(const TQPoint &);
00128
00129 private:
00130 TDEHTMLView *m_view;
00131 TDEHTMLViewPrivate* m_viewprivate;
00132 };
00133
00134 #endif
00135
00136 class TDEHTMLViewPrivate {
00137 friend class TDEHTMLToolTip;
00138 public:
00139
00140 enum PseudoFocusNodes {
00141 PFNone,
00142 PFTop,
00143 PFBottom
00144 };
00145
00146 enum CompletedState {
00147 CSNone = 0,
00148 CSFull,
00149 CSActionPending
00150 };
00151
00152 TDEHTMLViewPrivate()
00153 : underMouse( 0 ), underMouseNonShared( 0 ), visibleWidgets( 107 )
00154 #ifndef NO_SMOOTH_SCROLL_HACK
00155 , dx(0), dy(0), ddx(0), ddy(0), rdx(0), rdy(0), scrolling(false)
00156 #endif
00157 {
00158 #ifndef TDEHTML_NO_CARET
00159 m_caretViewContext = 0;
00160 m_editorContext = 0;
00161 #endif // TDEHTML_NO_CARET
00162 postponed_autorepeat = NULL;
00163 reset();
00164 vmode = TQScrollView::Auto;
00165 hmode = TQScrollView::Auto;
00166 tp=0;
00167 paintBuffer=0;
00168 vertPaintBuffer=0;
00169 formCompletions=0;
00170 prevScrollbarVisible = true;
00171 tooltip = 0;
00172 possibleTripleClick = false;
00173 emitCompletedAfterRepaint = CSNone;
00174 cursor_icon_widget = NULL;
00175 m_mouseScrollTimer = 0;
00176 m_mouseScrollIndicator = 0;
00177 }
00178 ~TDEHTMLViewPrivate()
00179 {
00180 delete formCompletions;
00181 delete tp; tp = 0;
00182 delete paintBuffer; paintBuffer =0;
00183 delete vertPaintBuffer;
00184 delete postponed_autorepeat;
00185 if (underMouse)
00186 underMouse->deref();
00187 if (underMouseNonShared)
00188 underMouseNonShared->deref();
00189 delete tooltip;
00190 #ifndef TDEHTML_NO_CARET
00191 delete m_caretViewContext;
00192 delete m_editorContext;
00193 #endif // TDEHTML_NO_CARET
00194 delete cursor_icon_widget;
00195 delete m_mouseScrollTimer;
00196 delete m_mouseScrollIndicator;
00197 }
00198 void reset()
00199 {
00200 if (underMouse)
00201 underMouse->deref();
00202 underMouse = 0;
00203 if (underMouseNonShared)
00204 underMouseNonShared->deref();
00205 underMouseNonShared = 0;
00206 linkPressed = false;
00207 useSlowRepaints = false;
00208 tabMovePending = false;
00209 lastTabbingDirection = true;
00210 pseudoFocusNode = PFNone;
00211 #ifndef TDEHTML_NO_SCROLLBARS
00212
00213
00214
00215
00216 #else
00217 vmode = TQScrollView::AlwaysOff;
00218 hmode = TQScrollView::AlwaysOff;
00219 #endif
00220 #ifdef DEBUG_PIXEL
00221 timer.start();
00222 pixelbooth = 0;
00223 repaintbooth = 0;
00224 #endif
00225 scrollBarMoved = false;
00226 contentsMoving = false;
00227 ignoreWheelEvents = false;
00228 borderX = 30;
00229 borderY = 30;
00230 paged = false;
00231 clickX = -1;
00232 clickY = -1;
00233 prevMouseX = -1;
00234 prevMouseY = -1;
00235 clickCount = 0;
00236 isDoubleClick = false;
00237 scrollingSelf = false;
00238 delete postponed_autorepeat;
00239 postponed_autorepeat = NULL;
00240 layoutTimerId = 0;
00241 repaintTimerId = 0;
00242 scrollTimerId = 0;
00243 scrollSuspended = false;
00244 scrollSuspendPreActivate = false;
00245 complete = false;
00246 firstRelayout = true;
00247 needsFullRepaint = true;
00248 dirtyLayout = false;
00249 layoutSchedulingEnabled = true;
00250 painting = false;
00251 updateRegion = TQRegion();
00252 m_dialogsAllowed = true;
00253 #ifndef TDEHTML_NO_CARET
00254 if (m_caretViewContext) {
00255 m_caretViewContext->caretMoved = false;
00256 m_caretViewContext->keyReleasePending = false;
00257 }
00258 #endif // TDEHTML_NO_CARET
00259 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
00260 typeAheadActivated = false;
00261 #endif // TDEHTML_NO_TYPE_AHEAD_FIND
00262 accessKeysActivated = false;
00263 accessKeysPreActivate = false;
00264
00265
00266 TDEHTMLFactory::ref();
00267 accessKeysEnabled = TDEHTMLFactory::defaultHTMLSettings()->accessKeysEnabled();
00268 TDEHTMLFactory::deref();
00269
00270 emitCompletedAfterRepaint = CSNone;
00271 }
00272 void newScrollTimer(TQWidget *view, int tid)
00273 {
00274
00275 view->killTimer(scrollTimerId);
00276 scrollTimerId = tid;
00277 scrollSuspended = false;
00278 }
00279 enum ScrollDirection { ScrollLeft, ScrollRight, ScrollUp, ScrollDown };
00280
00281 void adjustScroller(TQWidget *view, ScrollDirection direction, ScrollDirection oppositedir)
00282 {
00283 static const struct { int msec, pixels; } timings [] = {
00284 {320,1}, {224,1}, {160,1}, {112,1}, {80,1}, {56,1}, {40,1},
00285 {28,1}, {20,1}, {20,2}, {20,3}, {20,4}, {20,6}, {20,8}, {0,0}
00286 };
00287 if (!scrollTimerId ||
00288 (static_cast<int>(scrollDirection) != direction &&
00289 (static_cast<int>(scrollDirection) != oppositedir || scrollSuspended))) {
00290 scrollTiming = 6;
00291 scrollBy = timings[scrollTiming].pixels;
00292 scrollDirection = direction;
00293 newScrollTimer(view, view->startTimer(timings[scrollTiming].msec));
00294 } else if (scrollDirection == direction &&
00295 timings[scrollTiming+1].msec && !scrollSuspended) {
00296 scrollBy = timings[++scrollTiming].pixels;
00297 newScrollTimer(view, view->startTimer(timings[scrollTiming].msec));
00298 } else if (scrollDirection == oppositedir) {
00299 if (scrollTiming) {
00300 scrollBy = timings[--scrollTiming].pixels;
00301 newScrollTimer(view, view->startTimer(timings[scrollTiming].msec));
00302 }
00303 }
00304 scrollSuspended = false;
00305 }
00306
00307 #ifndef TDEHTML_NO_CARET
00308
00311 CaretViewContext *caretViewContext() {
00312 if (!m_caretViewContext) m_caretViewContext = new CaretViewContext();
00313 return m_caretViewContext;
00314 }
00318 EditorContext *editorContext() {
00319 if (!m_editorContext) m_editorContext = new EditorContext();
00320 return m_editorContext;
00321 }
00322 #endif // TDEHTML_NO_CARET
00323
00324 #ifdef DEBUG_PIXEL
00325 TQTime timer;
00326 unsigned int pixelbooth;
00327 unsigned int repaintbooth;
00328 #endif
00329
00330 TQPainter *tp;
00331 TQPixmap *paintBuffer;
00332 TQPixmap *vertPaintBuffer;
00333 NodeImpl *underMouse;
00334 NodeImpl *underMouseNonShared;
00335
00336 bool tabMovePending:1;
00337 bool lastTabbingDirection:1;
00338 PseudoFocusNodes pseudoFocusNode:2;
00339 bool scrollBarMoved:1;
00340 bool contentsMoving:1;
00341
00342 TQScrollView::ScrollBarMode vmode;
00343 TQScrollView::ScrollBarMode hmode;
00344 bool prevScrollbarVisible:1;
00345 bool linkPressed:1;
00346 bool useSlowRepaints:1;
00347 bool ignoreWheelEvents:1;
00348
00349 int borderX, borderY;
00350 KSimpleConfig *formCompletions;
00351
00352 bool paged;
00353
00354 int clickX, clickY, clickCount;
00355 bool isDoubleClick;
00356
00357 int prevMouseX, prevMouseY;
00358 bool scrollingSelf;
00359 int layoutTimerId;
00360 TQKeyEvent* postponed_autorepeat;
00361
00362 int repaintTimerId;
00363 int scrollTimerId;
00364 int scrollTiming;
00365 int scrollBy;
00366 ScrollDirection scrollDirection :2;
00367 bool scrollSuspended :1;
00368 bool scrollSuspendPreActivate :1;
00369 bool complete :1;
00370 bool firstRelayout :1;
00371 bool layoutSchedulingEnabled :1;
00372 bool needsFullRepaint :1;
00373 bool painting :1;
00374 bool possibleTripleClick :1;
00375 bool dirtyLayout :1;
00376 bool m_dialogsAllowed :1;
00377 TQRegion updateRegion;
00378 TDEHTMLToolTip *tooltip;
00379 TQPtrDict<TQWidget> visibleWidgets;
00380 #ifndef TDEHTML_NO_CARET
00381 CaretViewContext *m_caretViewContext;
00382 EditorContext *m_editorContext;
00383 #endif // TDEHTML_NO_CARET
00384 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
00385 TQString findString;
00386 TQTimer timer;
00387 bool findLinksOnly;
00388 bool typeAheadActivated;
00389 #endif // TDEHTML_NO_TYPE_AHEAD_FIND
00390 bool accessKeysEnabled;
00391 bool accessKeysActivated;
00392 bool accessKeysPreActivate;
00393 CompletedState emitCompletedAfterRepaint;
00394
00395 TQWidget* cursor_icon_widget;
00396
00397
00398 short m_mouseScroll_byX;
00399 short m_mouseScroll_byY;
00400 TQTimer *m_mouseScrollTimer;
00401 TQWidget *m_mouseScrollIndicator;
00402 #ifndef NO_SMOOTH_SCROLL_HACK
00403 TQTimer timer2;
00404 int dx;
00405 int dy;
00406
00407 int ddx;
00408 int ddy;
00409 int rdx;
00410 int rdy;
00411 bool scrolling;
00412 #endif
00413 };
00414
00415 #ifndef QT_NO_TOOLTIP
00416
00426 static bool findImageMapRect(HTMLImageElementImpl *img, const TQPoint &scrollOfs,
00427 const TQPoint &p, TQRect &r, TQString &s)
00428 {
00429 HTMLMapElementImpl* map;
00430 if (img && img->getDocument()->isHTMLDocument() &&
00431 (map = static_cast<HTMLDocumentImpl*>(img->getDocument())->getMap(img->imageMap()))) {
00432 RenderObject::NodeInfo info(true, false);
00433 RenderObject *rend = img->renderer();
00434 int ax, ay;
00435 if (!rend || !rend->absolutePosition(ax, ay))
00436 return false;
00437
00438 bool inside = map->mapMouseEvent(p.x() - ax + scrollOfs.x(),
00439 p.y() - ay + scrollOfs.y(), rend->contentWidth(),
00440 rend->contentHeight(), info);
00441 if (inside && info.URLElement()) {
00442 HTMLAreaElementImpl *area = static_cast<HTMLAreaElementImpl *>(info.URLElement());
00443 Q_ASSERT(area->id() == ID_AREA);
00444 s = area->getAttribute(ATTR_TITLE).string();
00445 TQRegion reg = area->cachedRegion();
00446 if (!s.isEmpty() && !reg.isEmpty()) {
00447 r = reg.boundingRect();
00448 r.moveBy(ax, ay);
00449 return true;
00450 }
00451 }
00452 }
00453 return false;
00454 }
00455
00456 void TDEHTMLToolTip::maybeTip(const TQPoint& p)
00457 {
00458 DOM::NodeImpl *node = m_viewprivate->underMouseNonShared;
00459 TQRect region;
00460 while ( node ) {
00461 if ( node->isElementNode() ) {
00462 DOM::ElementImpl *e = static_cast<DOM::ElementImpl*>( node );
00463 TQRect r;
00464 TQString s;
00465 bool found = false;
00466
00467
00468 if (e->id() == ID_IMG && !e->getAttribute( ATTR_USEMAP ).isEmpty()) {
00469 found = findImageMapRect(static_cast<HTMLImageElementImpl *>(e),
00470 m_view->viewportToContents(TQPoint(0, 0)), p, r, s);
00471 }
00472 if (!found) {
00473 s = e->getAttribute( ATTR_TITLE ).string();
00474 r = node->getRect();
00475 }
00476 region |= TQRect( m_view->contentsToViewport( r.topLeft() ), r.size() );
00477 if ( !s.isEmpty() ) {
00478 tip( region, TQStyleSheet::convertFromPlainText( s, TQStyleSheetItem::WhiteSpaceNormal ) );
00479 break;
00480 }
00481 }
00482 node = node->parentNode();
00483 }
00484 }
00485 #endif
00486
00487 TDEHTMLView::TDEHTMLView( TDEHTMLPart *part, TQWidget *parent, const char *name)
00488 : TQScrollView( parent, name, (WFlags)(WResizeNoErase | WRepaintNoErase) )
00489 {
00490 m_medium = "screen";
00491
00492 m_part = part;
00493 d = new TDEHTMLViewPrivate;
00494 TQScrollView::setVScrollBarMode(d->vmode);
00495 TQScrollView::setHScrollBarMode(d->hmode);
00496 connect(kapp, TQT_SIGNAL(tdedisplayPaletteChanged()), this, TQT_SLOT(slotPaletteChanged()));
00497 connect(this, TQT_SIGNAL(contentsMoving(int, int)), this, TQT_SLOT(slotScrollBarMoved()));
00498
00499
00500 enableClipper(true);
00501
00502 static_cast<TDEHTMLView *>(TQT_TQWIDGET(viewport()))->setWFlags(WPaintUnclipped);
00503
00504 setResizePolicy(Manual);
00505 viewport()->setMouseTracking(true);
00506 viewport()->setBackgroundMode(NoBackground);
00507
00508 KImageIO::registerFormats();
00509
00510 #ifndef QT_NO_TOOLTIP
00511 d->tooltip = new TDEHTMLToolTip( this, d );
00512 #endif
00513
00514 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
00515 connect(&d->timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(findTimeout()));
00516 #endif // TDEHTML_NO_TYPE_AHEAD_FIND
00517
00518 init();
00519
00520 viewport()->show();
00521 #ifndef NO_SMOOTH_SCROLL_HACK
00522 #define timer timer2
00523 connect(&d->timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(scrollTick()));
00524 #undef timer
00525 #endif
00526 }
00527
00528 TDEHTMLView::~TDEHTMLView()
00529 {
00530 closeChildDialogs();
00531 if (m_part)
00532 {
00533
00534
00535 DOM::DocumentImpl *doc = m_part->xmlDocImpl();
00536 if (doc)
00537 doc->detach();
00538 }
00539 delete d; d = 0;
00540 }
00541
00542 void TDEHTMLView::init()
00543 {
00544 if(!d->paintBuffer) d->paintBuffer = new TQPixmap(PAINT_BUFFER_HEIGHT, PAINT_BUFFER_HEIGHT);
00545 if(!d->vertPaintBuffer)
00546 d->vertPaintBuffer = new TQPixmap(10, PAINT_BUFFER_HEIGHT);
00547 if(!d->tp) d->tp = new TQPainter();
00548
00549 setFocusPolicy(TQ_StrongFocus);
00550 viewport()->setFocusProxy(this);
00551
00552 _marginWidth = -1;
00553 _marginHeight = -1;
00554 _width = 0;
00555 _height = 0;
00556
00557 installEventFilter(this);
00558
00559 setAcceptDrops(true);
00560 TQSize s = viewportSize(4095, 4095);
00561 resizeContents(s.width(), s.height());
00562 }
00563
00564 void TDEHTMLView::clear()
00565 {
00566
00567 setStaticBackground(true);
00568 #ifndef TDEHTML_NO_CARET
00569 if (!m_part->isCaretMode() && !m_part->isEditable()) caretOff();
00570 #endif
00571
00572 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
00573 if( d->typeAheadActivated )
00574 findTimeout();
00575 #endif
00576 if (d->accessKeysEnabled && d->accessKeysActivated)
00577 accessKeysTimeout();
00578 viewport()->unsetCursor();
00579 if ( d->cursor_icon_widget )
00580 d->cursor_icon_widget->hide();
00581 d->reset();
00582 TQT_TQOBJECT(this)->killTimers();
00583 emit cleared();
00584
00585 TQScrollView::setHScrollBarMode(d->hmode);
00586 TQScrollView::setVScrollBarMode(d->vmode);
00587 verticalScrollBar()->setEnabled( false );
00588 horizontalScrollBar()->setEnabled( false );
00589 }
00590
00591 void TDEHTMLView::hideEvent(TQHideEvent* e)
00592 {
00593 TQScrollView::hideEvent(e);
00594 if ( m_part && m_part->xmlDocImpl() )
00595 m_part->xmlDocImpl()->docLoader()->pauseAnimations();
00596 }
00597
00598 void TDEHTMLView::showEvent(TQShowEvent* e)
00599 {
00600 TQScrollView::showEvent(e);
00601 if ( m_part && m_part->xmlDocImpl() )
00602 m_part->xmlDocImpl()->docLoader()->resumeAnimations();
00603 }
00604
00605 void TDEHTMLView::resizeEvent (TQResizeEvent* e)
00606 {
00607 int dw = e->oldSize().width() - e->size().width();
00608 int dh = e->oldSize().height() - e->size().height();
00609
00610
00611
00612 dw = dw>0 ? kMax(0, contentsWidth()-dw) : contentsWidth();
00613 dh = dh>0 ? kMax(0, contentsHeight()-dh) : contentsHeight();
00614
00615 resizeContents(dw, dh);
00616
00617 TQScrollView::resizeEvent(e);
00618
00619 if ( m_part && m_part->xmlDocImpl() )
00620 m_part->xmlDocImpl()->dispatchWindowEvent( EventImpl::RESIZE_EVENT, false, false );
00621 }
00622
00623 void TDEHTMLView::viewportResizeEvent (TQResizeEvent* e)
00624 {
00625 TQScrollView::viewportResizeEvent(e);
00626
00627
00628
00629
00630 if (d->layoutSchedulingEnabled)
00631 layout();
00632 #ifndef TDEHTML_NO_CARET
00633 else {
00634 hideCaret();
00635 recalcAndStoreCaretPos();
00636 showCaret();
00637 }
00638 #endif
00639
00640 TDEApplication::sendPostedEvents(viewport(), TQEvent::Paint);
00641 }
00642
00643
00644 void TDEHTMLView::drawContents( TQPainter*)
00645 {
00646 }
00647
00648 void TDEHTMLView::drawContents( TQPainter *p, int ex, int ey, int ew, int eh )
00649 {
00650 #ifdef DEBUG_PIXEL
00651
00652 if ( d->timer.elapsed() > 5000 ) {
00653 tqDebug( "drawed %d pixels in %d repaints the last %d milliseconds",
00654 d->pixelbooth, d->repaintbooth, d->timer.elapsed() );
00655 d->timer.restart();
00656 d->pixelbooth = 0;
00657 d->repaintbooth = 0;
00658 }
00659 d->pixelbooth += ew*eh;
00660 d->repaintbooth++;
00661 #endif
00662
00663
00664 if(!m_part || !m_part->xmlDocImpl() || !m_part->xmlDocImpl()->renderer()) {
00665 p->fillRect(ex, ey, ew, eh, palette().active().brush(TQColorGroup::Base));
00666 return;
00667 } else if ( d->complete && static_cast<RenderCanvas*>(m_part->xmlDocImpl()->renderer())->needsLayout() ) {
00668
00669 unscheduleRelayout();
00670 layout();
00671 }
00672
00673 if (d->painting) {
00674 kdDebug( 6000 ) << "WARNING: drawContents reentered! " << endl;
00675 return;
00676 }
00677 d->painting = true;
00678
00679 TQPoint pt = contentsToViewport(TQPoint(ex, ey));
00680 TQRegion cr = TQRect(pt.x(), pt.y(), ew, eh);
00681
00682
00683 for (TQPtrDictIterator<TQWidget> it(d->visibleWidgets); it.current(); ++it) {
00684 TQWidget *w = it.current();
00685 RenderWidget* rw = static_cast<RenderWidget*>( it.currentKey() );
00686 if (w && rw && !rw->isTDEHTMLWidget()) {
00687 int x, y;
00688 rw->absolutePosition(x, y);
00689 contentsToViewport(x, y, x, y);
00690 int pbx = rw->borderLeft()+rw->paddingLeft();
00691 int pby = rw->borderTop()+rw->paddingTop();
00692 TQRect g = TQRect(x+pbx, y+pby,
00693 rw->width()-pbx-rw->borderRight()-rw->paddingRight(),
00694 rw->height()-pby-rw->borderBottom()-rw->paddingBottom());
00695 if ( !rw->isFrame() && ((g.top() > pt.y()+eh) || (g.bottom() <= pt.y()) ||
00696 (g.right() <= pt.x()) || (g.left() > pt.x()+ew) ))
00697 continue;
00698 RenderLayer* rl = rw->needsMask() ? rw->enclosingStackingContext() : 0;
00699 TQRegion mask = rl ? rl->getMask() : TQRegion();
00700 if (!mask.isNull()) {
00701 TQPoint o(0,0);
00702 o = contentsToViewport(o);
00703 mask.translate(o.x(),o.y());
00704 mask = mask.intersect( TQRect(g.x(),g.y(),g.width(),g.height()) );
00705 cr -= mask;
00706 } else {
00707 cr -= g;
00708 }
00709 }
00710 }
00711
00712 #if 0
00713
00714
00715 if (cr.isEmpty()) {
00716 d->painting = false;
00717 return;
00718 }
00719 #endif
00720
00721 #ifndef DEBUG_NO_PAINT_BUFFER
00722 p->setClipRegion(cr);
00723
00724 if (eh > PAINT_BUFFER_HEIGHT && ew <= 10) {
00725 if ( d->vertPaintBuffer->height() < visibleHeight() )
00726 d->vertPaintBuffer->resize(10, visibleHeight());
00727 d->tp->begin(d->vertPaintBuffer);
00728 d->tp->translate(-ex, -ey);
00729 d->tp->fillRect(ex, ey, ew, eh, palette().active().brush(TQColorGroup::Base));
00730 m_part->xmlDocImpl()->renderer()->layer()->paint(d->tp, TQRect(ex, ey, ew, eh));
00731 d->tp->end();
00732 p->drawPixmap(ex, ey, *d->vertPaintBuffer, 0, 0, ew, eh);
00733 }
00734 else {
00735 if ( d->paintBuffer->width() < visibleWidth() )
00736 d->paintBuffer->resize(visibleWidth(),PAINT_BUFFER_HEIGHT);
00737
00738 int py=0;
00739 while (py < eh) {
00740 int ph = eh-py < PAINT_BUFFER_HEIGHT ? eh-py : PAINT_BUFFER_HEIGHT;
00741 d->tp->begin(d->paintBuffer);
00742 d->tp->translate(-ex, -ey-py);
00743 d->tp->fillRect(ex, ey+py, ew, ph, palette().active().brush(TQColorGroup::Base));
00744 m_part->xmlDocImpl()->renderer()->layer()->paint(d->tp, TQRect(ex, ey+py, ew, ph));
00745 d->tp->end();
00746
00747 p->drawPixmap(ex, ey+py, *d->paintBuffer, 0, 0, ew, ph);
00748 py += PAINT_BUFFER_HEIGHT;
00749 }
00750 }
00751 #else // !DEBUG_NO_PAINT_BUFFER
00752 static int cnt=0;
00753 ex = contentsX(); ey = contentsY();
00754 ew = visibleWidth(); eh = visibleHeight();
00755 TQRect pr(ex,ey,ew,eh);
00756 kdDebug() << "[" << ++cnt << "]" << " clip region: " << pr << endl;
00757
00758
00759 p->fillRect(ex, ey, ew, eh, palette().active().brush(TQColorGroup::Base));
00760 m_part->xmlDocImpl()->renderer()->layer()->paint(p, pr);
00761 #endif // DEBUG_NO_PAINT_BUFFER
00762
00763 #ifndef TDEHTML_NO_CARET
00764 if (d->m_caretViewContext && d->m_caretViewContext->visible) {
00765 TQRect pos(d->m_caretViewContext->x, d->m_caretViewContext->y,
00766 d->m_caretViewContext->width, d->m_caretViewContext->height);
00767 if (pos.intersects(TQRect(ex, ey, ew, eh))) {
00768 p->setRasterOp(XorROP);
00769 p->setPen(white);
00770 if (pos.width() == 1)
00771 p->drawLine(pos.topLeft(), pos.bottomRight());
00772 else {
00773 p->fillRect(pos, white);
00774 }
00775 }
00776 }
00777 #endif // TDEHTML_NO_CARET
00778
00779
00780
00781
00782 tdehtml::DrawContentsEvent event( p, ex, ey, ew, eh );
00783 TQApplication::sendEvent( m_part, &event );
00784
00785 d->painting = false;
00786 }
00787
00788 void TDEHTMLView::setMarginWidth(int w)
00789 {
00790
00791 _marginWidth = w;
00792 }
00793
00794 void TDEHTMLView::setMarginHeight(int h)
00795 {
00796
00797 _marginHeight = h;
00798 }
00799
00800 void TDEHTMLView::layout()
00801 {
00802 if( m_part && m_part->xmlDocImpl() ) {
00803 DOM::DocumentImpl *document = m_part->xmlDocImpl();
00804
00805 tdehtml::RenderCanvas* canvas = static_cast<tdehtml::RenderCanvas *>(document->renderer());
00806 if ( !canvas ) return;
00807
00808 d->layoutSchedulingEnabled=false;
00809
00810
00811 RenderObject * ref = 0;
00812 RenderObject* root = document->documentElement() ? document->documentElement()->renderer() : 0;
00813
00814 if (document->isHTMLDocument()) {
00815 NodeImpl *body = static_cast<HTMLDocumentImpl*>(document)->body();
00816 if(body && body->renderer() && body->id() == ID_FRAMESET) {
00817 TQScrollView::setVScrollBarMode(AlwaysOff);
00818 TQScrollView::setHScrollBarMode(AlwaysOff);
00819 body->renderer()->setNeedsLayout(true);
00820
00821
00822
00823
00824 }
00825 else {
00826 if (!d->tooltip)
00827 d->tooltip = new TDEHTMLToolTip( this, d );
00828
00829 if (root)
00830 ref = (!body || root->style()->hidesOverflow()) ? root : body->renderer();
00831 }
00832 } else {
00833 ref = root;
00834 }
00835 if (ref) {
00836 if( ref->style()->overflowX() == OHIDDEN ) {
00837 if (d->hmode == Auto) TQScrollView::setHScrollBarMode(AlwaysOff);
00838 } else if (ref->style()->overflowX() == OSCROLL ) {
00839 if (d->hmode == Auto) TQScrollView::setHScrollBarMode(AlwaysOn);
00840 } else {
00841 if (TQScrollView::hScrollBarMode() == AlwaysOff) TQScrollView::setHScrollBarMode(d->hmode);
00842 } if ( ref->style()->overflowY() == OHIDDEN ) {
00843 if (d->vmode == Auto) TQScrollView::setVScrollBarMode(AlwaysOff);
00844 } else if (ref->style()->overflowY() == OSCROLL ) {
00845 if (d->vmode == Auto) TQScrollView::setVScrollBarMode(AlwaysOn);
00846 } else {
00847 if (TQScrollView::vScrollBarMode() == AlwaysOff) TQScrollView::setVScrollBarMode(d->vmode);
00848 }
00849 }
00850 d->needsFullRepaint = d->firstRelayout;
00851 if (_height != visibleHeight() || _width != visibleWidth()) {;
00852 d->needsFullRepaint = true;
00853 _height = visibleHeight();
00854 _width = visibleWidth();
00855 }
00856
00857
00858 canvas->layout();
00859
00860 emit finishedLayout();
00861 if (d->firstRelayout) {
00862
00863
00864 d->firstRelayout = false;
00865 verticalScrollBar()->setEnabled( true );
00866 horizontalScrollBar()->setEnabled( true );
00867 }
00868 #if 0
00869 ElementImpl *listitem = m_part->xmlDocImpl()->getElementById("__test_element__");
00870 if (listitem) kdDebug(6000) << "after layout, before repaint" << endl;
00871 if (listitem) dumpLineBoxes(static_cast<RenderFlow *>(listitem->renderer()));
00872 #endif
00873 #ifndef TDEHTML_NO_CARET
00874 hideCaret();
00875 if ((m_part->isCaretMode() || m_part->isEditable())
00876 && !d->complete && d->m_caretViewContext
00877 && !d->m_caretViewContext->caretMoved) {
00878 initCaret();
00879 } else {
00880 recalcAndStoreCaretPos();
00881 showCaret();
00882 }
00883 #endif
00884 if (d->accessKeysEnabled && d->accessKeysActivated) {
00885 emit hideAccessKeys();
00886 displayAccessKeys();
00887 }
00888
00889 }
00890 else
00891 _width = visibleWidth();
00892
00893 killTimer(d->layoutTimerId);
00894 d->layoutTimerId = 0;
00895 d->layoutSchedulingEnabled=true;
00896 }
00897
00898 void TDEHTMLView::closeChildDialogs()
00899 {
00900 TQObjectList *dlgs = queryList(TQDIALOG_OBJECT_NAME_STRING);
00901 for (TQObject *dlg = dlgs->first(); dlg; dlg = dlgs->next())
00902 {
00903 KDialogBase* dlgbase = dynamic_cast<KDialogBase *>( dlg );
00904 if ( dlgbase ) {
00905 if ( dlgbase->testWFlags( WShowModal ) ) {
00906 kdDebug(6000) << "closeChildDialogs: closing dialog " << dlgbase << endl;
00907
00908
00909 dlgbase->cancel();
00910 }
00911 }
00912 else
00913 {
00914 kdWarning() << "closeChildDialogs: not a KDialogBase! Don't use QDialogs in KDE! " << TQT_TQWIDGET(dlg) << endl;
00915 TQT_TQWIDGET(dlg)->hide();
00916 }
00917 }
00918 delete dlgs;
00919 d->m_dialogsAllowed = false;
00920 }
00921
00922 bool TDEHTMLView::dialogsAllowed() {
00923 bool allowed = d->m_dialogsAllowed;
00924 TDEHTMLPart* p = m_part->parentPart();
00925 if (p && p->view())
00926 allowed &= p->view()->dialogsAllowed();
00927 return allowed;
00928 }
00929
00930 void TDEHTMLView::closeEvent( TQCloseEvent* ev )
00931 {
00932 closeChildDialogs();
00933 TQScrollView::closeEvent( ev );
00934 }
00935
00936
00937
00938
00940
00941 void TDEHTMLView::viewportMousePressEvent( TQMouseEvent *_mouse )
00942 {
00943 if (!m_part->xmlDocImpl()) return;
00944 if (d->possibleTripleClick && ( _mouse->button() & Qt::MouseButtonMask ) == Qt::LeftButton)
00945 {
00946 viewportMouseDoubleClickEvent( _mouse );
00947 return;
00948 }
00949
00950 int xm, ym;
00951 viewportToContents(_mouse->x(), _mouse->y(), xm, ym);
00952
00953
00954 d->isDoubleClick = false;
00955
00956 DOM::NodeImpl::MouseEvent mev( _mouse->stateAfter(), DOM::NodeImpl::MousePress );
00957 m_part->xmlDocImpl()->prepareMouseEvent( false, xm, ym, &mev );
00958
00959
00960
00961 if ( (_mouse->button() == Qt::MidButton) &&
00962 !m_part->d->m_bOpenMiddleClick && !d->m_mouseScrollTimer &&
00963 mev.url.isNull() && (mev.innerNode.elementId() != ID_INPUT) ) {
00964 TQPoint point = mapFromGlobal( _mouse->globalPos() );
00965
00966 d->m_mouseScroll_byX = 0;
00967 d->m_mouseScroll_byY = 0;
00968
00969 d->m_mouseScrollTimer = new TQTimer( this );
00970 connect( d->m_mouseScrollTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotMouseScrollTimer()) );
00971
00972 if ( !d->m_mouseScrollIndicator ) {
00973 TQPixmap pixmap, icon;
00974 pixmap.resize( 48, 48 );
00975 pixmap.fill( TQColor( tqRgba( 127, 127, 127, 127 ) ) );
00976
00977 TQPainter p( &pixmap );
00978 icon = TDEGlobal::iconLoader()->loadIcon( "1uparrow", TDEIcon::Small );
00979 p.drawPixmap( 16, 0, icon );
00980 icon = TDEGlobal::iconLoader()->loadIcon( "1leftarrow", TDEIcon::Small );
00981 p.drawPixmap( 0, 16, icon );
00982 icon = TDEGlobal::iconLoader()->loadIcon( "1downarrow", TDEIcon::Small );
00983 p.drawPixmap( 16, 32,icon );
00984 icon = TDEGlobal::iconLoader()->loadIcon( "1rightarrow", TDEIcon::Small );
00985 p.drawPixmap( 32, 16, icon );
00986 p.drawEllipse( 23, 23, 2, 2 );
00987
00988 d->m_mouseScrollIndicator = new TQWidget( this, 0 );
00989 d->m_mouseScrollIndicator->setFixedSize( 48, 48 );
00990 d->m_mouseScrollIndicator->setPaletteBackgroundPixmap( pixmap );
00991 }
00992 d->m_mouseScrollIndicator->move( point.x()-24, point.y()-24 );
00993
00994 bool hasHorBar = visibleWidth() < contentsWidth();
00995 bool hasVerBar = visibleHeight() < contentsHeight();
00996
00997 TDEConfig *config = TDEGlobal::config();
00998 TDEConfigGroupSaver saver( config, "HTML Settings" );
00999 if ( config->readBoolEntry( "ShowMouseScrollIndicator", true ) ) {
01000 d->m_mouseScrollIndicator->show();
01001 d->m_mouseScrollIndicator->unsetCursor();
01002
01003 TQBitmap mask = d->m_mouseScrollIndicator->paletteBackgroundPixmap()->createHeuristicMask( true );
01004
01005 if ( hasHorBar && !hasVerBar ) {
01006 TQBitmap bm( 16, 16, true );
01007 bitBlt( &mask, 16, 0, &bm, 0, 0, -1, -1 );
01008 bitBlt( &mask, 16, 32, &bm, 0, 0, -1, -1 );
01009 d->m_mouseScrollIndicator->setCursor( KCursor::SizeHorCursor );
01010 }
01011 else if ( !hasHorBar && hasVerBar ) {
01012 TQBitmap bm( 16, 16, true );
01013 bitBlt( &mask, 0, 16, &bm, 0, 0, -1, -1 );
01014 bitBlt( &mask, 32, 16, &bm, 0, 0, -1, -1 );
01015 d->m_mouseScrollIndicator->setCursor( KCursor::SizeVerCursor );
01016 }
01017 else
01018 d->m_mouseScrollIndicator->setCursor( KCursor::SizeAllCursor );
01019
01020 d->m_mouseScrollIndicator->setMask( mask );
01021 }
01022 else {
01023 if ( hasHorBar && !hasVerBar )
01024 viewport()->setCursor( KCursor::SizeHorCursor );
01025 else if ( !hasHorBar && hasVerBar )
01026 viewport()->setCursor( KCursor::SizeVerCursor );
01027 else
01028 viewport()->setCursor( KCursor::SizeAllCursor );
01029 }
01030
01031 return;
01032 }
01033 else if ( d->m_mouseScrollTimer ) {
01034 delete d->m_mouseScrollTimer;
01035 d->m_mouseScrollTimer = 0;
01036
01037 if ( d->m_mouseScrollIndicator )
01038 d->m_mouseScrollIndicator->hide();
01039 }
01040
01041 d->clickCount = 1;
01042 d->clickX = xm;
01043 d->clickY = ym;
01044
01045 bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEDOWN_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),true,
01046 d->clickCount,_mouse,true,DOM::NodeImpl::MousePress);
01047
01048 tdehtml::RenderObject* r = mev.innerNode.handle() ? mev.innerNode.handle()->renderer() : 0;
01049 if (r && r->isWidget())
01050 _mouse->ignore();
01051
01052 if (!swallowEvent) {
01053 emit m_part->nodeActivated(mev.innerNode);
01054
01055 tdehtml::MousePressEvent event( _mouse, xm, ym, mev.url, mev.target, mev.innerNode );
01056 TQApplication::sendEvent( m_part, &event );
01057
01058 }
01059 }
01060
01061 void TDEHTMLView::viewportMouseDoubleClickEvent( TQMouseEvent *_mouse )
01062 {
01063 if(!m_part->xmlDocImpl()) return;
01064
01065 int xm, ym;
01066 viewportToContents(_mouse->x(), _mouse->y(), xm, ym);
01067
01068 kdDebug( 6000 ) << "mouseDblClickEvent: x=" << xm << ", y=" << ym << endl;
01069
01070 d->isDoubleClick = true;
01071
01072 DOM::NodeImpl::MouseEvent mev( _mouse->stateAfter(), DOM::NodeImpl::MouseDblClick );
01073 m_part->xmlDocImpl()->prepareMouseEvent( false, xm, ym, &mev );
01074
01075
01076
01077 if (d->clickCount > 0 &&
01078 TQPoint(d->clickX-xm,d->clickY-ym).manhattanLength() <= TQApplication::startDragDistance())
01079 d->clickCount++;
01080 else {
01081 d->clickCount = 1;
01082 d->clickX = xm;
01083 d->clickY = ym;
01084 }
01085 bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEDOWN_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),true,
01086 d->clickCount,_mouse,true,DOM::NodeImpl::MouseDblClick);
01087
01088 tdehtml::RenderObject* r = mev.innerNode.handle() ? mev.innerNode.handle()->renderer() : 0;
01089 if (r && r->isWidget())
01090 _mouse->ignore();
01091
01092 if (!swallowEvent) {
01093 tdehtml::MouseDoubleClickEvent event( _mouse, xm, ym, mev.url, mev.target, mev.innerNode, d->clickCount );
01094 TQApplication::sendEvent( m_part, &event );
01095 }
01096
01097 d->possibleTripleClick=true;
01098 TQTimer::singleShot(TQApplication::doubleClickInterval(),this,TQT_SLOT(tripleClickTimeout()));
01099 }
01100
01101 void TDEHTMLView::tripleClickTimeout()
01102 {
01103 d->possibleTripleClick = false;
01104 d->clickCount = 0;
01105 }
01106
01107 static inline void forwardPeripheralEvent(tdehtml::RenderWidget* r, TQMouseEvent* me, int x, int y)
01108 {
01109 int absx = 0;
01110 int absy = 0;
01111 r->absolutePosition(absx, absy);
01112 TQPoint p(x-absx, y-absy);
01113 TQMouseEvent fw(me->type(), p, me->button(), me->state());
01114 TQWidget* w = r->widget();
01115 TQScrollView* sc = ::tqqt_cast<TQScrollView*>(w);
01116 if (sc && !::tqqt_cast<TQListBox*>(w))
01117 static_cast<tdehtml::RenderWidget::ScrollViewEventPropagator*>(sc)->sendEvent(TQT_TQEVENT(&fw));
01118 else if(w)
01119 static_cast<tdehtml::RenderWidget::EventPropagator*>(w)->sendEvent(TQT_TQEVENT(&fw));
01120 }
01121
01122
01123 static bool targetOpensNewWindow(TDEHTMLPart *part, TQString target)
01124 {
01125 if (!target.isEmpty() && (target.lower() != "_top") &&
01126 (target.lower() != "_self") && (target.lower() != "_parent")) {
01127 if (target.lower() == "_blank")
01128 return true;
01129 else {
01130 while (part->parentPart())
01131 part = part->parentPart();
01132 if (!part->frameExists(target))
01133 return true;
01134 }
01135 }
01136 return false;
01137 }
01138
01139 void TDEHTMLView::viewportMouseMoveEvent( TQMouseEvent * _mouse )
01140 {
01141 if ( d->m_mouseScrollTimer ) {
01142 TQPoint point = mapFromGlobal( _mouse->globalPos() );
01143
01144 int deltaX = point.x() - d->m_mouseScrollIndicator->x() - 24;
01145 int deltaY = point.y() - d->m_mouseScrollIndicator->y() - 24;
01146
01147 (deltaX > 0) ? d->m_mouseScroll_byX = 1 : d->m_mouseScroll_byX = -1;
01148 (deltaY > 0) ? d->m_mouseScroll_byY = 1 : d->m_mouseScroll_byY = -1;
01149
01150 double adX = TQABS(deltaX)/30.0;
01151 double adY = TQABS(deltaY)/30.0;
01152
01153 d->m_mouseScroll_byX = kMax(kMin(d->m_mouseScroll_byX * int(adX*adX), SHRT_MAX), SHRT_MIN);
01154 d->m_mouseScroll_byY = kMax(kMin(d->m_mouseScroll_byY * int(adY*adY), SHRT_MAX), SHRT_MIN);
01155
01156 if (d->m_mouseScroll_byX == 0 && d->m_mouseScroll_byY == 0) {
01157 d->m_mouseScrollTimer->stop();
01158 }
01159 else if (!d->m_mouseScrollTimer->isActive()) {
01160 d->m_mouseScrollTimer->changeInterval( 20 );
01161 }
01162 }
01163
01164 if(!m_part->xmlDocImpl()) return;
01165
01166 int xm, ym;
01167 viewportToContents(_mouse->x(), _mouse->y(), xm, ym);
01168
01169 DOM::NodeImpl::MouseEvent mev( _mouse->stateAfter(), DOM::NodeImpl::MouseMove );
01170
01171 m_part->xmlDocImpl()->prepareMouseEvent( _mouse->state() & Qt::MouseButtonMask , xm, ym, &mev );
01172
01173
01174
01175
01176
01177 bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEMOVE_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),false,
01178 0,_mouse,true,DOM::NodeImpl::MouseMove);
01179
01180 if (d->clickCount > 0 &&
01181 TQPoint(d->clickX-xm,d->clickY-ym).manhattanLength() > TQApplication::startDragDistance()) {
01182 d->clickCount = 0;
01183 }
01184
01185
01186 m_part->executeScheduledScript();
01187
01188 DOM::NodeImpl* fn = m_part->xmlDocImpl()->focusNode();
01189 if (fn && fn != mev.innerNode.handle() &&
01190 fn->renderer() && fn->renderer()->isWidget()) {
01191 forwardPeripheralEvent(static_cast<tdehtml::RenderWidget*>(fn->renderer()), _mouse, xm, ym);
01192 }
01193
01194 tdehtml::RenderObject* r = mev.innerNode.handle() ? mev.innerNode.handle()->renderer() : 0;
01195 tdehtml::RenderStyle* style = (r && r->style()) ? r->style() : 0;
01196 TQCursor c;
01197 bool mailtoCursor = false;
01198 bool newWindowCursor = false;
01199 switch ( style ? style->cursor() : CURSOR_AUTO) {
01200 case CURSOR_AUTO:
01201 if ( r && r->isText() )
01202 c = KCursor::ibeamCursor();
01203 if ( mev.url.length() && m_part->settings()->changeCursor() ) {
01204 c = m_part->urlCursor();
01205 if (mev.url.string().startsWith("mailto:") && mev.url.string().find('@')>0)
01206 mailtoCursor = true;
01207 else
01208 newWindowCursor = targetOpensNewWindow( m_part, mev.target.string() );
01209 }
01210
01211 if (r && r->isFrameSet() && !static_cast<RenderFrameSet*>(r)->noResize())
01212 c = TQCursor(static_cast<RenderFrameSet*>(r)->cursorShape());
01213
01214 break;
01215 case CURSOR_CROSS:
01216 c = KCursor::crossCursor();
01217 break;
01218 case CURSOR_POINTER:
01219 c = m_part->urlCursor();
01220 if (mev.url.string().startsWith("mailto:") && mev.url.string().find('@')>0)
01221 mailtoCursor = true;
01222 else
01223 newWindowCursor = targetOpensNewWindow( m_part, mev.target.string() );
01224 break;
01225 case CURSOR_PROGRESS:
01226 c = KCursor::workingCursor();
01227 break;
01228 case CURSOR_MOVE:
01229 c = KCursor::sizeAllCursor();
01230 break;
01231 case CURSOR_E_RESIZE:
01232 case CURSOR_W_RESIZE:
01233 c = KCursor::sizeHorCursor();
01234 break;
01235 case CURSOR_N_RESIZE:
01236 case CURSOR_S_RESIZE:
01237 c = KCursor::sizeVerCursor();
01238 break;
01239 case CURSOR_NE_RESIZE:
01240 case CURSOR_SW_RESIZE:
01241 c = KCursor::sizeBDiagCursor();
01242 break;
01243 case CURSOR_NW_RESIZE:
01244 case CURSOR_SE_RESIZE:
01245 c = KCursor::sizeFDiagCursor();
01246 break;
01247 case CURSOR_TEXT:
01248 c = KCursor::ibeamCursor();
01249 break;
01250 case CURSOR_WAIT:
01251 c = KCursor::waitCursor();
01252 break;
01253 case CURSOR_HELP:
01254 c = KCursor::whatsThisCursor();
01255 break;
01256 case CURSOR_DEFAULT:
01257 break;
01258 }
01259
01260 if ( viewport()->cursor().handle() != c.handle() ) {
01261 if( c.handle() == KCursor::arrowCursor().handle()) {
01262 for (TDEHTMLPart* p = m_part; p; p = p->parentPart())
01263 p->view()->viewport()->unsetCursor();
01264 }
01265 else {
01266 viewport()->setCursor( c );
01267 }
01268 }
01269
01270 if ( ( mailtoCursor || newWindowCursor ) && isVisible() && hasFocus() ) {
01271 #ifdef Q_WS_X11
01272 TQPixmap icon_pixmap = TDEGlobal::iconLoader()->loadIcon( mailtoCursor ? "mail_generic" : "window-new", TDEIcon::Small, 0, TDEIcon::DefaultState, 0, true );
01273
01274 if (d->cursor_icon_widget) {
01275 const TQPixmap *pm = d->cursor_icon_widget->backgroundPixmap();
01276 if (!pm || pm->serialNumber()!=icon_pixmap.serialNumber()) {
01277 delete d->cursor_icon_widget;
01278 d->cursor_icon_widget = 0;
01279 }
01280 }
01281
01282 if( !d->cursor_icon_widget ) {
01283 d->cursor_icon_widget = new TQWidget( NULL, NULL, WX11BypassWM );
01284 XSetWindowAttributes attr;
01285 attr.save_under = True;
01286 XChangeWindowAttributes( tqt_xdisplay(), d->cursor_icon_widget->winId(), CWSaveUnder, &attr );
01287 d->cursor_icon_widget->resize( icon_pixmap.width(), icon_pixmap.height());
01288 if( icon_pixmap.mask() )
01289 d->cursor_icon_widget->setMask( *icon_pixmap.mask());
01290 else
01291 d->cursor_icon_widget->clearMask();
01292 d->cursor_icon_widget->setBackgroundPixmap( icon_pixmap );
01293 d->cursor_icon_widget->erase();
01294 }
01295 TQPoint c_pos = TQCursor::pos();
01296 d->cursor_icon_widget->move( c_pos.x() + 15, c_pos.y() + 15 );
01297 XRaiseWindow( tqt_xdisplay(), d->cursor_icon_widget->winId());
01298 TQApplication::flushX();
01299 d->cursor_icon_widget->show();
01300 #endif
01301 }
01302 else if ( d->cursor_icon_widget )
01303 d->cursor_icon_widget->hide();
01304
01305 if (r && r->isWidget()) {
01306 _mouse->ignore();
01307 }
01308
01309
01310 d->prevMouseX = xm;
01311 d->prevMouseY = ym;
01312
01313 if (!swallowEvent) {
01314 tdehtml::MouseMoveEvent event( _mouse, xm, ym, mev.url, mev.target, mev.innerNode );
01315 TQApplication::sendEvent( m_part, &event );
01316 }
01317 }
01318
01319 void TDEHTMLView::viewportMouseReleaseEvent( TQMouseEvent * _mouse )
01320 {
01321 bool swallowEvent = false;
01322 int xm, ym;
01323 viewportToContents(_mouse->x(), _mouse->y(), xm, ym);
01324 DOM::NodeImpl::MouseEvent mev( _mouse->stateAfter(), DOM::NodeImpl::MouseRelease );
01325
01326 if ( m_part->xmlDocImpl() )
01327 {
01328 m_part->xmlDocImpl()->prepareMouseEvent( false, xm, ym, &mev );
01329
01330 swallowEvent = dispatchMouseEvent(EventImpl::MOUSEUP_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),true,
01331 d->clickCount,_mouse,false,DOM::NodeImpl::MouseRelease);
01332
01333 if (d->clickCount > 0 &&
01334 TQPoint(d->clickX-xm,d->clickY-ym).manhattanLength() <= TQApplication::startDragDistance()) {
01335 TQMouseEvent me(d->isDoubleClick ? TQEvent::MouseButtonDblClick : TQEvent::MouseButtonRelease,
01336 _mouse->pos(), _mouse->button(), _mouse->state());
01337 dispatchMouseEvent(EventImpl::CLICK_EVENT, mev.innerNode.handle(),mev.innerNonSharedNode.handle(),true,
01338 d->clickCount, &me, true, DOM::NodeImpl::MouseRelease);
01339 }
01340
01341 DOM::NodeImpl* fn = m_part->xmlDocImpl()->focusNode();
01342 if (fn && fn != mev.innerNode.handle() &&
01343 fn->renderer() && fn->renderer()->isWidget() &&
01344 _mouse->button() != Qt::MidButton) {
01345 forwardPeripheralEvent(static_cast<tdehtml::RenderWidget*>(fn->renderer()), _mouse, xm, ym);
01346 }
01347
01348 tdehtml::RenderObject* r = mev.innerNode.handle() ? mev.innerNode.handle()->renderer() : 0;
01349 if (r && r->isWidget())
01350 _mouse->ignore();
01351 }
01352
01353 if (!swallowEvent) {
01354 tdehtml::MouseReleaseEvent event( _mouse, xm, ym, mev.url, mev.target, mev.innerNode );
01355 TQApplication::sendEvent( m_part, &event );
01356 }
01357 }
01358
01359
01360 bool TDEHTMLView::dispatchKeyEvent( TQKeyEvent *_ke )
01361 {
01362 if (!m_part->xmlDocImpl())
01363 return false;
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384 if( _ke == d->postponed_autorepeat )
01385 {
01386 return false;
01387 }
01388
01389 if( _ke->type() == TQEvent::KeyPress )
01390 {
01391 if( !_ke->isAutoRepeat())
01392 {
01393 bool ret = dispatchKeyEventHelper( _ke, false );
01394
01395 if( !ret && dispatchKeyEventHelper( _ke, true ))
01396 ret = true;
01397 return ret;
01398 }
01399 else
01400 {
01401 bool ret = dispatchKeyEventHelper( _ke, true );
01402 if( !ret && d->postponed_autorepeat )
01403 keyPressEvent( d->postponed_autorepeat );
01404 delete d->postponed_autorepeat;
01405 d->postponed_autorepeat = NULL;
01406 return ret;
01407 }
01408 }
01409 else
01410 {
01411
01412
01413 if ( d->postponed_autorepeat ) {
01414 delete d->postponed_autorepeat;
01415 d->postponed_autorepeat = 0;
01416 }
01417
01418 if( !_ke->isAutoRepeat()) {
01419 return dispatchKeyEventHelper( _ke, false );
01420 }
01421 else
01422 {
01423 d->postponed_autorepeat = new TQKeyEvent( _ke->type(), _ke->key(), _ke->ascii(), _ke->state(),
01424 _ke->text(), _ke->isAutoRepeat(), _ke->count());
01425 if( _ke->isAccepted())
01426 d->postponed_autorepeat->accept();
01427 else
01428 d->postponed_autorepeat->ignore();
01429 return true;
01430 }
01431 }
01432 }
01433
01434
01435 bool TDEHTMLView::dispatchKeyEventHelper( TQKeyEvent *_ke, bool keypress )
01436 {
01437 DOM::NodeImpl* keyNode = m_part->xmlDocImpl()->focusNode();
01438 if (keyNode) {
01439 return keyNode->dispatchKeyEvent(_ke, keypress);
01440 } else {
01441 return m_part->xmlDocImpl()->dispatchKeyEvent(_ke, keypress);
01442 }
01443 }
01444
01445 void TDEHTMLView::keyPressEvent( TQKeyEvent *_ke )
01446 {
01447 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
01448 if(d->typeAheadActivated)
01449 {
01450
01451 if(_ke->key() == Key_BackSpace)
01452 {
01453 d->findString = d->findString.left(d->findString.length() - 1);
01454
01455 if(!d->findString.isEmpty())
01456 {
01457 findAhead(false);
01458 }
01459 else
01460 {
01461 findTimeout();
01462 }
01463
01464 d->timer.start(3000, true);
01465 _ke->accept();
01466 return;
01467 }
01468 else if(_ke->key() == Key_Escape)
01469 {
01470 findTimeout();
01471
01472 _ke->accept();
01473 return;
01474 }
01475 else if(_ke->key() == Key_Space || !TQString(_ke->text()).stripWhiteSpace().isEmpty())
01476 {
01477 d->findString += _ke->text();
01478
01479 findAhead(true);
01480
01481 d->timer.start(3000, true);
01482 _ke->accept();
01483 return;
01484 }
01485 }
01486 #endif // TDEHTML_NO_TYPE_AHEAD_FIND
01487
01488 #ifndef TDEHTML_NO_CARET
01489 if (m_part->isEditable() || m_part->isCaretMode()
01490 || (m_part->xmlDocImpl() && m_part->xmlDocImpl()->focusNode()
01491 && m_part->xmlDocImpl()->focusNode()->contentEditable())) {
01492 d->caretViewContext()->keyReleasePending = true;
01493 caretKeyPressEvent(_ke);
01494 return;
01495 }
01496 #endif // TDEHTML_NO_CARET
01497
01498
01499 if (d->accessKeysEnabled && _ke->key() == Key_Control && _ke->state()==0 && !d->accessKeysActivated)
01500 {
01501 d->accessKeysPreActivate=true;
01502 _ke->accept();
01503 return;
01504 }
01505
01506 if (_ke->key() == Key_Shift && _ke->state()==0)
01507 d->scrollSuspendPreActivate=true;
01508
01509
01510
01511
01512 if (d->accessKeysEnabled && d->accessKeysActivated)
01513 {
01514 int state = ( _ke->state() & ( ShiftButton | ControlButton | AltButton | MetaButton ));
01515 if ( state==0 || state==ShiftButton) {
01516 if (_ke->key() != Key_Shift) accessKeysTimeout();
01517 handleAccessKey( _ke );
01518 _ke->accept();
01519 return;
01520 }
01521 accessKeysTimeout();
01522 }
01523
01524 if ( dispatchKeyEvent( _ke )) {
01525
01526 _ke->accept();
01527 return;
01528 }
01529
01530 int offs = (clipper()->height() < 30) ? clipper()->height() : 30;
01531 if (_ke->state() & TQt::ShiftButton)
01532 switch(_ke->key())
01533 {
01534 case Key_Space:
01535 scrollBy( 0, -clipper()->height() + offs );
01536 if(d->scrollSuspended)
01537 d->newScrollTimer(this, 0);
01538 break;
01539
01540 case Key_Down:
01541 case Key_J:
01542 d->adjustScroller(this, TDEHTMLViewPrivate::ScrollDown, TDEHTMLViewPrivate::ScrollUp);
01543 break;
01544
01545 case Key_Up:
01546 case Key_K:
01547 d->adjustScroller(this, TDEHTMLViewPrivate::ScrollUp, TDEHTMLViewPrivate::ScrollDown);
01548 break;
01549
01550 case Key_Left:
01551 case Key_H:
01552 d->adjustScroller(this, TDEHTMLViewPrivate::ScrollLeft, TDEHTMLViewPrivate::ScrollRight);
01553 break;
01554
01555 case Key_Right:
01556 case Key_L:
01557 d->adjustScroller(this, TDEHTMLViewPrivate::ScrollRight, TDEHTMLViewPrivate::ScrollLeft);
01558 break;
01559 }
01560 else
01561 switch ( _ke->key() )
01562 {
01563 case Key_Down:
01564 case Key_J:
01565 if (!d->scrollTimerId || d->scrollSuspended)
01566 scrollBy( 0, 10 * _ke->count() );
01567 if (d->scrollTimerId)
01568 d->newScrollTimer(this, 0);
01569 break;
01570
01571 case Key_Space:
01572 case Key_Next:
01573 scrollBy( 0, clipper()->height() - offs );
01574 if(d->scrollSuspended)
01575 d->newScrollTimer(this, 0);
01576 break;
01577
01578 case Key_Up:
01579 case Key_K:
01580 if (!d->scrollTimerId || d->scrollSuspended)
01581 scrollBy( 0, -10 * _ke->count());
01582 if (d->scrollTimerId)
01583 d->newScrollTimer(this, 0);
01584 break;
01585
01586 case Key_Prior:
01587 scrollBy( 0, -clipper()->height() + offs );
01588 if(d->scrollSuspended)
01589 d->newScrollTimer(this, 0);
01590 break;
01591 case Key_Right:
01592 case Key_L:
01593 if (!d->scrollTimerId || d->scrollSuspended)
01594 scrollBy( 10 * _ke->count(), 0 );
01595 if (d->scrollTimerId)
01596 d->newScrollTimer(this, 0);
01597 break;
01598 case Key_Left:
01599 case Key_H:
01600 if (!d->scrollTimerId || d->scrollSuspended)
01601 scrollBy( -10 * _ke->count(), 0 );
01602 if (d->scrollTimerId)
01603 d->newScrollTimer(this, 0);
01604 break;
01605 case Key_Enter:
01606 case Key_Return:
01607
01608
01609 if (m_part->xmlDocImpl()) {
01610 NodeImpl *n = m_part->xmlDocImpl()->focusNode();
01611 if (n)
01612 n->setActive();
01613 }
01614 break;
01615 case Key_Home:
01616 setContentsPos( 0, 0 );
01617 if(d->scrollSuspended)
01618 d->newScrollTimer(this, 0);
01619 break;
01620 case Key_End:
01621 setContentsPos( 0, contentsHeight() - visibleHeight() );
01622 if(d->scrollSuspended)
01623 d->newScrollTimer(this, 0);
01624 break;
01625 case Key_Shift:
01626
01627 _ke->ignore();
01628 return;
01629 default:
01630 if (d->scrollTimerId)
01631 d->newScrollTimer(this, 0);
01632 _ke->ignore();
01633 return;
01634 }
01635
01636 _ke->accept();
01637 }
01638
01639 void TDEHTMLView::findTimeout()
01640 {
01641 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
01642 d->typeAheadActivated = false;
01643 d->findString = "";
01644 m_part->setStatusBarText(i18n("Find stopped."), TDEHTMLPart::BarDefaultText);
01645 m_part->enableFindAheadActions( true );
01646 #endif // TDEHTML_NO_TYPE_AHEAD_FIND
01647 }
01648
01649 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
01650 void TDEHTMLView::startFindAhead( bool linksOnly )
01651 {
01652 if( linksOnly )
01653 {
01654 d->findLinksOnly = true;
01655 m_part->setStatusBarText(i18n("Starting -- find links as you type"),
01656 TDEHTMLPart::BarDefaultText);
01657 }
01658 else
01659 {
01660 d->findLinksOnly = false;
01661 m_part->setStatusBarText(i18n("Starting -- find text as you type"),
01662 TDEHTMLPart::BarDefaultText);
01663 }
01664
01665 m_part->findTextBegin();
01666 d->typeAheadActivated = true;
01667
01668 m_part->enableFindAheadActions( false );
01669 d->timer.start(3000, true);
01670 }
01671
01672 void TDEHTMLView::findAhead(bool increase)
01673 {
01674 TQString status;
01675
01676 if(d->findLinksOnly)
01677 {
01678 m_part->findText(d->findString, TDEHTMLPart::FindNoPopups |
01679 TDEHTMLPart::FindLinksOnly, this);
01680 if(m_part->findTextNext())
01681 {
01682 status = i18n("Link found: \"%1\".");
01683 }
01684 else
01685 {
01686 if(increase) KNotifyClient::beep();
01687 status = i18n("Link not found: \"%1\".");
01688 }
01689 }
01690 else
01691 {
01692 m_part->findText(d->findString, TDEHTMLPart::FindNoPopups, this);
01693 if(m_part->findTextNext())
01694 {
01695 status = i18n("Text found: \"%1\".");
01696 }
01697 else
01698 {
01699 if(increase) KNotifyClient::beep();
01700 status = i18n("Text not found: \"%1\".");
01701 }
01702 }
01703
01704 m_part->setStatusBarText(status.arg(d->findString.lower()),
01705 TDEHTMLPart::BarDefaultText);
01706 }
01707
01708 void TDEHTMLView::updateFindAheadTimeout()
01709 {
01710 if( d->typeAheadActivated )
01711 d->timer.start( 3000, true );
01712 }
01713
01714 #endif // TDEHTML_NO_TYPE_AHEAD_FIND
01715
01716 void TDEHTMLView::keyReleaseEvent(TQKeyEvent *_ke)
01717 {
01718 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
01719 if(d->typeAheadActivated) {
01720 _ke->accept();
01721 return;
01722 }
01723 #endif
01724 if (d->m_caretViewContext && d->m_caretViewContext->keyReleasePending) {
01725
01726 d->m_caretViewContext->keyReleasePending = false;
01727 return;
01728 }
01729
01730 if( d->scrollSuspendPreActivate && _ke->key() != Key_Shift )
01731 d->scrollSuspendPreActivate = false;
01732 if( _ke->key() == Key_Shift && d->scrollSuspendPreActivate && _ke->state() == TQt::ShiftButton
01733 && !(TDEApplication::keyboardMouseState() & TQt::ShiftButton))
01734 {
01735 if (d->scrollTimerId)
01736 {
01737 d->scrollSuspended = !d->scrollSuspended;
01738 #ifndef NO_SMOOTH_SCROLL_HACK
01739 if( d->scrollSuspended )
01740 stopScrolling();
01741 #endif
01742 }
01743 }
01744
01745 if (d->accessKeysEnabled)
01746 {
01747 if (d->accessKeysPreActivate && _ke->key() != Key_Control)
01748 d->accessKeysPreActivate=false;
01749 if (d->accessKeysPreActivate && _ke->state() == TQt::ControlButton && !(TDEApplication::keyboardMouseState() & TQt::ControlButton))
01750 {
01751 displayAccessKeys();
01752 m_part->setStatusBarText(i18n("Access Keys activated"),TDEHTMLPart::BarOverrideText);
01753 d->accessKeysActivated = true;
01754 d->accessKeysPreActivate = false;
01755 _ke->accept();
01756 return;
01757 }
01758 else if (d->accessKeysActivated)
01759 {
01760 accessKeysTimeout();
01761 _ke->accept();
01762 return;
01763 }
01764 }
01765
01766
01767 if ( dispatchKeyEvent( _ke ) )
01768 {
01769 _ke->accept();
01770 return;
01771 }
01772
01773 TQScrollView::keyReleaseEvent(_ke);
01774 }
01775
01776 void TDEHTMLView::contentsContextMenuEvent ( TQContextMenuEvent * )
01777 {
01778
01779 #if 0
01780 if (!m_part->xmlDocImpl()) return;
01781 int xm = _ce->x();
01782 int ym = _ce->y();
01783
01784 DOM::NodeImpl::MouseEvent mev( _ce->state(), DOM::NodeImpl::MouseMove );
01785 m_part->xmlDocImpl()->prepareMouseEvent( xm, ym, &mev );
01786
01787 NodeImpl *targetNode = mev.innerNode.handle();
01788 if (targetNode && targetNode->renderer() && targetNode->renderer()->isWidget()) {
01789 int absx = 0;
01790 int absy = 0;
01791 targetNode->renderer()->absolutePosition(absx,absy);
01792 TQPoint pos(xm-absx,ym-absy);
01793
01794 TQWidget *w = static_cast<RenderWidget*>(targetNode->renderer())->widget();
01795 TQContextMenuEvent cme(_ce->reason(),pos,_ce->globalPos(),_ce->state());
01796 setIgnoreEvents(true);
01797 TQApplication::sendEvent(w,&cme);
01798 setIgnoreEvents(false);
01799 }
01800 #endif
01801 }
01802
01803 bool TDEHTMLView::focusNextPrevChild( bool next )
01804 {
01805
01806 if (m_part->xmlDocImpl() && focusNextPrevNode(next))
01807 {
01808 if (m_part->xmlDocImpl()->focusNode())
01809 kdDebug() << "focusNode.name: "
01810 << m_part->xmlDocImpl()->focusNode()->nodeName().string() << endl;
01811 return true;
01812 }
01813
01814
01815 d->pseudoFocusNode = TDEHTMLViewPrivate::PFNone;
01816 if (m_part->parentPart() && m_part->parentPart()->view())
01817 return m_part->parentPart()->view()->focusNextPrevChild(next);
01818
01819 return TQWidget::focusNextPrevChild(next);
01820 }
01821
01822 void TDEHTMLView::doAutoScroll()
01823 {
01824 TQPoint pos = TQCursor::pos();
01825 pos = viewport()->mapFromGlobal( pos );
01826
01827 int xm, ym;
01828 viewportToContents(pos.x(), pos.y(), xm, ym);
01829
01830 pos = TQPoint(pos.x() - viewport()->x(), pos.y() - viewport()->y());
01831 if ( (pos.y() < 0) || (pos.y() > visibleHeight()) ||
01832 (pos.x() < 0) || (pos.x() > visibleWidth()) )
01833 {
01834 ensureVisible( xm, ym, 0, 5 );
01835
01836 #ifndef TDEHTML_NO_SELECTION
01837
01838 DOM::Node innerNode;
01839 if (m_part->isExtendingSelection()) {
01840 RenderObject::NodeInfo renderInfo(true, false);
01841 m_part->xmlDocImpl()->renderer()->layer()
01842 ->nodeAtPoint(renderInfo, xm, ym);
01843 innerNode = renderInfo.innerNode();
01844 }
01845
01846 if (innerNode.handle() && innerNode.handle()->renderer()) {
01847 int absX, absY;
01848 innerNode.handle()->renderer()->absolutePosition(absX, absY);
01849
01850 m_part->extendSelectionTo(xm, ym, absX, absY, innerNode);
01851 }
01852 #endif // TDEHTML_NO_SELECTION
01853 }
01854 }
01855
01856
01857 class HackWidget : public TQWidget
01858 {
01859 public:
01860 inline void setNoErase() { setWFlags(getWFlags()|WRepaintNoErase); }
01861 };
01862
01863 bool TDEHTMLView::eventFilter(TQObject *o, TQEvent *e)
01864 {
01865 if ( e->type() == TQEvent::AccelOverride ) {
01866 TQKeyEvent* ke = (TQKeyEvent*) e;
01867
01868 if (m_part->isEditable() || m_part->isCaretMode()
01869 || (m_part->xmlDocImpl() && m_part->xmlDocImpl()->focusNode()
01870 && m_part->xmlDocImpl()->focusNode()->contentEditable())) {
01871
01872 if ( (ke->state() & ControlButton) || (ke->state() & ShiftButton) ) {
01873 switch ( ke->key() ) {
01874 case Key_Left:
01875 case Key_Right:
01876 case Key_Up:
01877 case Key_Down:
01878 case Key_Home:
01879 case Key_End:
01880 ke->accept();
01881
01882 return true;
01883 default:
01884 break;
01885 }
01886 }
01887 }
01888 }
01889
01890 if ( e->type() == TQEvent::Leave ) {
01891 if ( d->cursor_icon_widget )
01892 d->cursor_icon_widget->hide();
01893 m_part->resetHoverText();
01894 }
01895
01896 TQWidget *view = viewport();
01897
01898 if (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(view)) {
01899
01900
01901 if(e->type() == TQEvent::ChildInserted) {
01902 TQObject *c = TQT_TQOBJECT(TQT_TQCHILDEVENT(e)->child());
01903 if (c->isWidgetType()) {
01904 TQWidget *w = TQT_TQWIDGET(c);
01905
01906 if (w->parentWidget(true) == view) {
01907 if (!strcmp(w->name(), "__tdehtml")) {
01908 w->installEventFilter(this);
01909 w->unsetCursor();
01910 if (!::tqqt_cast<TQFrame*>(w))
01911 w->setBackgroundMode( TQWidget::NoBackground );
01912 static_cast<HackWidget *>(w)->setNoErase();
01913 if (!w->childrenListObject().isEmpty()) {
01914 TQObjectListIterator it(w->childrenListObject());
01915 for (; it.current(); ++it) {
01916 TQWidget *widget = ::tqqt_cast<TQWidget *>(it.current());
01917 if (widget && !widget->isTopLevel()) {
01918 if (!::tqqt_cast<TQFrame*>(w))
01919 widget->setBackgroundMode( TQWidget::NoBackground );
01920 static_cast<HackWidget *>(widget)->setNoErase();
01921 widget->installEventFilter(this);
01922 }
01923 }
01924 }
01925 }
01926 }
01927 }
01928 }
01929 } else if (o->isWidgetType()) {
01930 TQWidget *v = TQT_TQWIDGET(o);
01931 TQWidget *c = v;
01932 while (v && v != view) {
01933 c = v;
01934 v = v->parentWidget(true);
01935 }
01936
01937 if (v && !strcmp(c->name(), "__tdehtml")) {
01938 bool block = false;
01939 TQWidget *w = TQT_TQWIDGET(o);
01940 switch(e->type()) {
01941 case TQEvent::Paint:
01942 if (!allowWidgetPaintEvents) {
01943
01944
01945 block = true;
01946 int x = 0, y = 0;
01947 TQWidget *v = w;
01948 while (v && v != view) {
01949 x += v->x();
01950 y += v->y();
01951 v = v->parentWidget();
01952 }
01953 viewportToContents( x, y, x, y );
01954 TQPaintEvent *pe = TQT_TQPAINTEVENT(e);
01955 bool asap = !d->contentsMoving && ::tqqt_cast<TQScrollView *>(c);
01956
01957
01958 if ( asap && !d->painting && m_part->xmlDocImpl() && m_part->xmlDocImpl()->renderer() &&
01959 !static_cast<tdehtml::RenderCanvas *>(m_part->xmlDocImpl()->renderer())->needsLayout() ) {
01960 repaintContents(x + pe->rect().x(), y + pe->rect().y(),
01961 pe->rect().width(), pe->rect().height(), true);
01962 } else {
01963 scheduleRepaint(x + pe->rect().x(), y + pe->rect().y(),
01964 pe->rect().width(), pe->rect().height(), asap);
01965 }
01966 }
01967 break;
01968 case TQEvent::MouseMove:
01969 case TQEvent::MouseButtonPress:
01970 case TQEvent::MouseButtonRelease:
01971 case TQEvent::MouseButtonDblClick: {
01972 if ( (w->parentWidget() == view || ::tqqt_cast<TQScrollView*>(c)) && !::tqqt_cast<TQScrollBar *>(w)) {
01973 TQMouseEvent *me = TQT_TQMOUSEEVENT(e);
01974 TQPoint pt = w->mapTo( view, me->pos());
01975 TQMouseEvent me2(me->type(), pt, me->button(), me->state());
01976
01977 if (e->type() == TQEvent::MouseMove)
01978 viewportMouseMoveEvent(&me2);
01979 else if(e->type() == TQEvent::MouseButtonPress)
01980 viewportMousePressEvent(&me2);
01981 else if(e->type() == TQEvent::MouseButtonRelease)
01982 viewportMouseReleaseEvent(&me2);
01983 else
01984 viewportMouseDoubleClickEvent(&me2);
01985 block = true;
01986 }
01987 break;
01988 }
01989 case TQEvent::KeyPress:
01990 case TQEvent::KeyRelease:
01991 if (w->parentWidget() == view && !::tqqt_cast<TQScrollBar *>(w)) {
01992 TQKeyEvent *ke = TQT_TQKEYEVENT(e);
01993 if (e->type() == TQEvent::KeyPress)
01994 keyPressEvent(ke);
01995 else
01996 keyReleaseEvent(ke);
01997 block = true;
01998 }
01999 default:
02000 break;
02001 }
02002 if (block) {
02003
02004 return true;
02005 }
02006 }
02007 }
02008
02009
02010 return TQScrollView::eventFilter(o, e);
02011 }
02012
02013
02014 DOM::NodeImpl *TDEHTMLView::nodeUnderMouse() const
02015 {
02016 return d->underMouse;
02017 }
02018
02019 DOM::NodeImpl *TDEHTMLView::nonSharedNodeUnderMouse() const
02020 {
02021 return d->underMouseNonShared;
02022 }
02023
02024 bool TDEHTMLView::scrollTo(const TQRect &bounds)
02025 {
02026 d->scrollingSelf = true;
02027
02028 int x, y, xe, ye;
02029 x = bounds.left();
02030 y = bounds.top();
02031 xe = bounds.right();
02032 ye = bounds.bottom();
02033
02034
02035
02036 int deltax;
02037 int deltay;
02038
02039 int curHeight = visibleHeight();
02040 int curWidth = visibleWidth();
02041
02042 if (ye-y>curHeight-d->borderY)
02043 ye = y + curHeight - d->borderY;
02044
02045 if (xe-x>curWidth-d->borderX)
02046 xe = x + curWidth - d->borderX;
02047
02048
02049 if (x < contentsX() + d->borderX )
02050 deltax = x - contentsX() - d->borderX;
02051
02052 else if (xe + d->borderX > contentsX() + curWidth)
02053 deltax = xe + d->borderX - ( contentsX() + curWidth );
02054 else
02055 deltax = 0;
02056
02057
02058 if (y < contentsY() + d->borderY)
02059 deltay = y - contentsY() - d->borderY;
02060
02061 else if (ye + d->borderY > contentsY() + curHeight)
02062 deltay = ye + d->borderY - ( contentsY() + curHeight );
02063 else
02064 deltay = 0;
02065
02066 int maxx = curWidth-d->borderX;
02067 int maxy = curHeight-d->borderY;
02068
02069 int scrollX,scrollY;
02070
02071 scrollX = deltax > 0 ? (deltax > maxx ? maxx : deltax) : deltax == 0 ? 0 : (deltax>-maxx ? deltax : -maxx);
02072 scrollY = deltay > 0 ? (deltay > maxy ? maxy : deltay) : deltay == 0 ? 0 : (deltay>-maxy ? deltay : -maxy);
02073
02074 if (contentsX() + scrollX < 0)
02075 scrollX = -contentsX();
02076 else if (contentsWidth() - visibleWidth() - contentsX() < scrollX)
02077 scrollX = contentsWidth() - visibleWidth() - contentsX();
02078
02079 if (contentsY() + scrollY < 0)
02080 scrollY = -contentsY();
02081 else if (contentsHeight() - visibleHeight() - contentsY() < scrollY)
02082 scrollY = contentsHeight() - visibleHeight() - contentsY();
02083
02084 scrollBy(scrollX, scrollY);
02085
02086 d->scrollingSelf = false;
02087
02088 if ( (abs(deltax)<=maxx) && (abs(deltay)<=maxy) )
02089 return true;
02090 else return false;
02091
02092 }
02093
02094 bool TDEHTMLView::focusNextPrevNode(bool next)
02095 {
02096
02097
02098
02099
02100
02101
02102
02103 DocumentImpl *doc = m_part->xmlDocImpl();
02104 NodeImpl *oldFocusNode = doc->focusNode();
02105
02106
02107
02108
02109 if (oldFocusNode && oldFocusNode->renderer() &&
02110 !oldFocusNode->renderer()->parent()) {
02111 doc->setFocusNode(0);
02112 return true;
02113 }
02114
02115 #if 1
02116
02117
02118
02119 if (d->scrollBarMoved)
02120 {
02121 NodeImpl *toFocus;
02122 if (next)
02123 toFocus = doc->nextFocusNode(oldFocusNode);
02124 else
02125 toFocus = doc->previousFocusNode(oldFocusNode);
02126
02127 if (!toFocus && oldFocusNode)
02128 if (next)
02129 toFocus = doc->nextFocusNode(NULL);
02130 else
02131 toFocus = doc->previousFocusNode(NULL);
02132
02133 while (toFocus && toFocus != oldFocusNode)
02134 {
02135
02136 TQRect focusNodeRect = toFocus->getRect();
02137 if ((focusNodeRect.left() > contentsX()) && (focusNodeRect.right() < contentsX() + visibleWidth()) &&
02138 (focusNodeRect.top() > contentsY()) && (focusNodeRect.bottom() < contentsY() + visibleHeight())) {
02139 {
02140 TQRect r = toFocus->getRect();
02141 ensureVisible( r.right(), r.bottom());
02142 ensureVisible( r.left(), r.top());
02143 d->scrollBarMoved = false;
02144 d->tabMovePending = false;
02145 d->lastTabbingDirection = next;
02146 d->pseudoFocusNode = TDEHTMLViewPrivate::PFNone;
02147 m_part->xmlDocImpl()->setFocusNode(toFocus);
02148 Node guard(toFocus);
02149 if (!toFocus->hasOneRef() )
02150 {
02151 emit m_part->nodeActivated(Node(toFocus));
02152 }
02153 return true;
02154 }
02155 }
02156 if (next)
02157 toFocus = doc->nextFocusNode(toFocus);
02158 else
02159 toFocus = doc->previousFocusNode(toFocus);
02160
02161 if (!toFocus && oldFocusNode)
02162 if (next)
02163 toFocus = doc->nextFocusNode(NULL);
02164 else
02165 toFocus = doc->previousFocusNode(NULL);
02166 }
02167
02168 d->scrollBarMoved = false;
02169 }
02170 #endif
02171
02172 if (!oldFocusNode && d->pseudoFocusNode == TDEHTMLViewPrivate::PFNone)
02173 {
02174 ensureVisible(contentsX(), next?0:contentsHeight());
02175 d->scrollBarMoved = false;
02176 d->pseudoFocusNode = next?TDEHTMLViewPrivate::PFTop:TDEHTMLViewPrivate::PFBottom;
02177 return true;
02178 }
02179
02180 NodeImpl *newFocusNode = NULL;
02181
02182 if (d->tabMovePending && next != d->lastTabbingDirection)
02183 {
02184
02185 newFocusNode = oldFocusNode;
02186 }
02187 else if (next)
02188 {
02189 if (oldFocusNode || d->pseudoFocusNode == TDEHTMLViewPrivate::PFTop )
02190 newFocusNode = doc->nextFocusNode(oldFocusNode);
02191 }
02192 else
02193 {
02194 if (oldFocusNode || d->pseudoFocusNode == TDEHTMLViewPrivate::PFBottom )
02195 newFocusNode = doc->previousFocusNode(oldFocusNode);
02196 }
02197
02198 bool targetVisible = false;
02199 if (!newFocusNode)
02200 {
02201 if ( next )
02202 {
02203 targetVisible = scrollTo(TQRect(contentsX()+visibleWidth()/2,contentsHeight()-d->borderY,0,0));
02204 }
02205 else
02206 {
02207 targetVisible = scrollTo(TQRect(contentsX()+visibleWidth()/2,d->borderY,0,0));
02208 }
02209 }
02210 else
02211 {
02212 #ifndef TDEHTML_NO_CARET
02213
02214 if (!m_part->isCaretMode() && !m_part->isEditable()
02215 && newFocusNode->contentEditable()) {
02216 d->caretViewContext();
02217 moveCaretTo(newFocusNode, 0L, true);
02218 } else {
02219 caretOff();
02220 }
02221 #endif // TDEHTML_NO_CARET
02222
02223 targetVisible = scrollTo(newFocusNode->getRect());
02224 }
02225
02226 if (targetVisible)
02227 {
02228
02229 d->tabMovePending = false;
02230
02231 m_part->xmlDocImpl()->setFocusNode(newFocusNode);
02232 if (newFocusNode)
02233 {
02234 Node guard(newFocusNode);
02235 if (!newFocusNode->hasOneRef() )
02236 {
02237 emit m_part->nodeActivated(Node(newFocusNode));
02238 }
02239 return true;
02240 }
02241 else
02242 {
02243 d->pseudoFocusNode = next?TDEHTMLViewPrivate::PFBottom:TDEHTMLViewPrivate::PFTop;
02244 return false;
02245 }
02246 }
02247 else
02248 {
02249 if (!d->tabMovePending)
02250 d->lastTabbingDirection = next;
02251 d->tabMovePending = true;
02252 return true;
02253 }
02254 }
02255
02256 void TDEHTMLView::displayAccessKeys()
02257 {
02258 TQValueVector< TQChar > taken;
02259 displayAccessKeys( NULL, this, taken, false );
02260 displayAccessKeys( NULL, this, taken, true );
02261 }
02262
02263 void TDEHTMLView::displayAccessKeys( TDEHTMLView* caller, TDEHTMLView* origview, TQValueVector< TQChar >& taken, bool use_fallbacks )
02264 {
02265 TQMap< ElementImpl*, TQChar > fallbacks;
02266 if( use_fallbacks )
02267 fallbacks = buildFallbackAccessKeys();
02268 for( NodeImpl* n = m_part->xmlDocImpl(); n != NULL; n = n->traverseNextNode()) {
02269 if( n->isElementNode()) {
02270 ElementImpl* en = static_cast< ElementImpl* >( n );
02271 DOMString s = en->getAttribute( ATTR_ACCESSKEY );
02272 TQString accesskey;
02273 if( s.length() == 1 ) {
02274 TQChar a = s.string()[ 0 ].upper();
02275 if( tqFind( taken.begin(), taken.end(), a ) == taken.end())
02276 accesskey = a;
02277 }
02278 if( accesskey.isNull() && fallbacks.contains( en )) {
02279 TQChar a = fallbacks[ en ].upper();
02280 if( tqFind( taken.begin(), taken.end(), a ) == taken.end())
02281 accesskey = TQString( "<qt><i>" ) + a + "</i></qt>";
02282 }
02283 if( !accesskey.isNull()) {
02284 TQRect rec=en->getRect();
02285 TQLabel *lab=new TQLabel(accesskey,viewport(),0,(WFlags)WDestructiveClose);
02286 connect( origview, TQT_SIGNAL(hideAccessKeys()), lab, TQT_SLOT(close()) );
02287 connect( this, TQT_SIGNAL(repaintAccessKeys()), lab, TQT_SLOT(repaint()));
02288 lab->setPalette(TQToolTip::palette());
02289 lab->setLineWidth(2);
02290 lab->setFrameStyle(TQFrame::Box | TQFrame::Plain);
02291 lab->setMargin(3);
02292 lab->adjustSize();
02293 addChild(lab,
02294 KMIN(rec.left()+rec.width()/2, contentsWidth() - lab->width()),
02295 KMIN(rec.top()+rec.height()/2, contentsHeight() - lab->height()));
02296 showChild(lab);
02297 taken.append( accesskey[ 0 ] );
02298 }
02299 }
02300 }
02301 if( use_fallbacks )
02302 return;
02303 TQPtrList<KParts::ReadOnlyPart> frames = m_part->frames();
02304 for( TQPtrListIterator<KParts::ReadOnlyPart> it( frames );
02305 it != NULL;
02306 ++it ) {
02307 if( !(*it)->inherits( "TDEHTMLPart" ))
02308 continue;
02309 TDEHTMLPart* part = static_cast< TDEHTMLPart* >( *it );
02310 if( part->view() && part->view() != caller )
02311 part->view()->displayAccessKeys( this, origview, taken, use_fallbacks );
02312 }
02313
02314 if (m_part->parentPart() && m_part->parentPart()->view()
02315 && m_part->parentPart()->view() != caller)
02316 m_part->parentPart()->view()->displayAccessKeys( this, origview, taken, use_fallbacks );
02317 }
02318
02319
02320
02321 void TDEHTMLView::accessKeysTimeout()
02322 {
02323 d->accessKeysActivated=false;
02324 d->accessKeysPreActivate = false;
02325 m_part->setStatusBarText(TQString::null, TDEHTMLPart::BarOverrideText);
02326 emit hideAccessKeys();
02327 }
02328
02329
02330 bool TDEHTMLView::handleAccessKey( const TQKeyEvent* ev )
02331 {
02332
02333
02334 TQChar c;
02335 if( ev->key() >= Key_A && ev->key() <= Key_Z )
02336 c = 'A' + ev->key() - Key_A;
02337 else if( ev->key() >= Key_0 && ev->key() <= Key_9 )
02338 c = '0' + ev->key() - Key_0;
02339 else {
02340
02341
02342 if( ev->text().length() == 1 )
02343 c = ev->text()[ 0 ];
02344 }
02345 if( c.isNull())
02346 return false;
02347 return focusNodeWithAccessKey( c );
02348 }
02349
02350 bool TDEHTMLView::focusNodeWithAccessKey( TQChar c, TDEHTMLView* caller )
02351 {
02352 DocumentImpl *doc = m_part->xmlDocImpl();
02353 if( !doc )
02354 return false;
02355 ElementImpl* node = doc->findAccessKeyElement( c );
02356 if( !node ) {
02357 TQPtrList<KParts::ReadOnlyPart> frames = m_part->frames();
02358 for( TQPtrListIterator<KParts::ReadOnlyPart> it( frames );
02359 it != NULL;
02360 ++it ) {
02361 if( !(*it)->inherits( "TDEHTMLPart" ))
02362 continue;
02363 TDEHTMLPart* part = static_cast< TDEHTMLPart* >( *it );
02364 if( part->view() && part->view() != caller
02365 && part->view()->focusNodeWithAccessKey( c, this ))
02366 return true;
02367 }
02368
02369 if (m_part->parentPart() && m_part->parentPart()->view()
02370 && m_part->parentPart()->view() != caller
02371 && m_part->parentPart()->view()->focusNodeWithAccessKey( c, this ))
02372 return true;
02373 if( caller == NULL ) {
02374 TQMap< ElementImpl*, TQChar > fallbacks = buildFallbackAccessKeys();
02375 for( TQMap< ElementImpl*, TQChar >::ConstIterator it = fallbacks.begin();
02376 it != fallbacks.end();
02377 ++it )
02378 if( *it == c ) {
02379 node = it.key();
02380 break;
02381 }
02382 }
02383 if( node == NULL )
02384 return false;
02385 }
02386
02387
02388 #ifndef TDEHTML_NO_CARET
02389
02390 if (!m_part->isCaretMode() && !m_part->isEditable()
02391 && node->contentEditable()) {
02392 d->caretViewContext();
02393 moveCaretTo(node, 0L, true);
02394 } else {
02395 caretOff();
02396 }
02397 #endif // TDEHTML_NO_CARET
02398
02399 TQRect r = node->getRect();
02400 ensureVisible( r.right(), r.bottom());
02401 ensureVisible( r.left(), r.top());
02402
02403 Node guard( node );
02404 if( node->isFocusable()) {
02405 if (node->id()==ID_LABEL) {
02406
02407 node=static_cast<ElementImpl *>(static_cast< HTMLLabelElementImpl* >( node )->getFormElement());
02408 if (!node) return true;
02409 guard = node;
02410 }
02411
02412 #ifdef USE_QT4
02413 m_part->xmlDocImpl()->setFocusNode(node);
02414 #else // USE_QT4
02415 TQFocusEvent::setReason( TQFocusEvent::Shortcut );
02416 m_part->xmlDocImpl()->setFocusNode(node);
02417 TQFocusEvent::resetReason();
02418 #endif // USE_QT4
02419 if( node != NULL && node->hasOneRef())
02420 return true;
02421 emit m_part->nodeActivated(Node(node));
02422 if( node != NULL && node->hasOneRef())
02423 return true;
02424 }
02425
02426 switch( node->id()) {
02427 case ID_A:
02428 static_cast< HTMLAnchorElementImpl* >( node )->click();
02429 break;
02430 case ID_INPUT:
02431 static_cast< HTMLInputElementImpl* >( node )->click();
02432 break;
02433 case ID_BUTTON:
02434 static_cast< HTMLButtonElementImpl* >( node )->click();
02435 break;
02436 case ID_AREA:
02437 static_cast< HTMLAreaElementImpl* >( node )->click();
02438 break;
02439 case ID_TEXTAREA:
02440 break;
02441 case ID_LEGEND:
02442
02443 break;
02444 }
02445 return true;
02446 }
02447
02448 static TQString getElementText( NodeImpl* start, bool after )
02449 {
02450 TQString ret;
02451 for( NodeImpl* n = after ? start->nextSibling() : start->traversePreviousNode();
02452 n != NULL;
02453 n = after ? n->traverseNextNode() : n->traversePreviousNode()) {
02454 if( n->isTextNode()) {
02455 if( after )
02456 ret += static_cast< TextImpl* >( n )->toString().string();
02457 else
02458 ret.prepend( static_cast< TextImpl* >( n )->toString().string());
02459 } else {
02460 switch( n->id()) {
02461 case ID_A:
02462 case ID_FONT:
02463 case ID_TT:
02464 case ID_U:
02465 case ID_B:
02466 case ID_I:
02467 case ID_S:
02468 case ID_STRIKE:
02469 case ID_BIG:
02470 case ID_SMALL:
02471 case ID_EM:
02472 case ID_STRONG:
02473 case ID_DFN:
02474 case ID_CODE:
02475 case ID_SAMP:
02476 case ID_KBD:
02477 case ID_VAR:
02478 case ID_CITE:
02479 case ID_ABBR:
02480 case ID_ACRONYM:
02481 case ID_SUB:
02482 case ID_SUP:
02483 case ID_SPAN:
02484 case ID_NOBR:
02485 case ID_WBR:
02486 break;
02487 case ID_TD:
02488 if( ret.stripWhiteSpace().isEmpty())
02489 break;
02490
02491 default:
02492 return ret.simplifyWhiteSpace();
02493 }
02494 }
02495 }
02496 return ret.simplifyWhiteSpace();
02497 }
02498
02499 static TQMap< NodeImpl*, TQString > buildLabels( NodeImpl* start )
02500 {
02501 TQMap< NodeImpl*, TQString > ret;
02502 for( NodeImpl* n = start;
02503 n != NULL;
02504 n = n->traverseNextNode()) {
02505 if( n->id() == ID_LABEL ) {
02506 HTMLLabelElementImpl* label = static_cast< HTMLLabelElementImpl* >( n );
02507 NodeImpl* labelfor = label->getFormElement();
02508 if( labelfor )
02509 ret[ labelfor ] = label->innerText().string().simplifyWhiteSpace();
02510 }
02511 }
02512 return ret;
02513 }
02514
02515 namespace tdehtml {
02516 struct AccessKeyData {
02517 ElementImpl* element;
02518 TQString text;
02519 TQString url;
02520 int priority;
02521 };
02522 }
02523
02524 TQMap< ElementImpl*, TQChar > TDEHTMLView::buildFallbackAccessKeys() const
02525 {
02526
02527 TQValueList< AccessKeyData > data;
02528 TQMap< NodeImpl*, TQString > labels = buildLabels( m_part->xmlDocImpl());
02529 for( NodeImpl* n = m_part->xmlDocImpl();
02530 n != NULL;
02531 n = n->traverseNextNode()) {
02532 if( n->isElementNode()) {
02533 ElementImpl* element = static_cast< ElementImpl* >( n );
02534 if( element->getAttribute( ATTR_ACCESSKEY ).length() == 1 )
02535 continue;
02536 if( element->renderer() == NULL )
02537 continue;
02538 TQString text;
02539 TQString url;
02540 int priority = 0;
02541 bool ignore = false;
02542 bool text_after = false;
02543 bool text_before = false;
02544 switch( element->id()) {
02545 case ID_A:
02546 url = tdehtml::parseURL(element->getAttribute(ATTR_HREF)).string();
02547 if( url.isEmpty())
02548 continue;
02549 text = static_cast< HTMLElementImpl* >( element )->innerText().string().simplifyWhiteSpace();
02550 priority = 2;
02551 break;
02552 case ID_INPUT: {
02553 HTMLInputElementImpl* in = static_cast< HTMLInputElementImpl* >( element );
02554 switch( in->inputType()) {
02555 case HTMLInputElementImpl::SUBMIT:
02556 text = in->value().string();
02557 if( text.isEmpty())
02558 text = i18n( "Submit" );
02559 priority = 7;
02560 break;
02561 case HTMLInputElementImpl::IMAGE:
02562 text = in->altText().string();
02563 priority = 7;
02564 break;
02565 case HTMLInputElementImpl::BUTTON:
02566 text = in->value().string();
02567 priority = 5;
02568 break;
02569 case HTMLInputElementImpl::RESET:
02570 text = in->value().string();
02571 if( text.isEmpty())
02572 text = i18n( "Reset" );
02573 priority = 5;
02574 break;
02575 case HTMLInputElementImpl::HIDDEN:
02576 ignore = true;
02577 break;
02578 case HTMLInputElementImpl::CHECKBOX:
02579 case HTMLInputElementImpl::RADIO:
02580 text_after = true;
02581 priority = 5;
02582 break;
02583 case HTMLInputElementImpl::TEXT:
02584 case HTMLInputElementImpl::PASSWORD:
02585 case HTMLInputElementImpl::FILE:
02586 text_before = true;
02587 priority = 5;
02588 break;
02589 default:
02590 priority = 5;
02591 break;
02592 }
02593 break;
02594 }
02595 case ID_BUTTON:
02596 text = static_cast< HTMLElementImpl* >( element )->innerText().string().simplifyWhiteSpace();
02597 switch( static_cast< HTMLButtonElementImpl* >( element )->buttonType()) {
02598 case HTMLButtonElementImpl::SUBMIT:
02599 if( text.isEmpty())
02600 text = i18n( "Submit" );
02601 priority = 7;
02602 break;
02603 case HTMLButtonElementImpl::RESET:
02604 if( text.isEmpty())
02605 text = i18n( "Reset" );
02606 priority = 5;
02607 break;
02608 default:
02609 priority = 5;
02610 break;
02611 break;
02612 }
02613 case ID_SELECT:
02614 text_before = true;
02615 text_after = true;
02616 priority = 5;
02617 break;
02618 case ID_FRAME:
02619 ignore = true;
02620 break;
02621 default:
02622 ignore = !element->isFocusable();
02623 priority = 2;
02624 break;
02625 }
02626 if( ignore )
02627 continue;
02628 if( text.isNull() && labels.contains( element ))
02629 text = labels[ element ];
02630 if( text.isNull() && text_before )
02631 text = getElementText( element, false );
02632 if( text.isNull() && text_after )
02633 text = getElementText( element, true );
02634 text = text.stripWhiteSpace();
02635
02636 TQValueList< TQPair< TQString, TQChar > > priorities
02637 = m_part->settings()->fallbackAccessKeysAssignments();
02638 for( TQValueList< TQPair< TQString, TQChar > >::ConstIterator it = priorities.begin();
02639 it != priorities.end();
02640 ++it ) {
02641 if( text == (*it).first )
02642 priority = 10;
02643 }
02644 AccessKeyData tmp = { element, text, url, priority };
02645 data.append( tmp );
02646 }
02647 }
02648
02649 TQValueList< TQChar > keys;
02650 for( char c = 'A'; c <= 'Z'; ++c )
02651 keys << c;
02652 for( char c = '0'; c <= '9'; ++c )
02653 keys << c;
02654 for( NodeImpl* n = m_part->xmlDocImpl();
02655 n != NULL;
02656 n = n->traverseNextNode()) {
02657 if( n->isElementNode()) {
02658 ElementImpl* en = static_cast< ElementImpl* >( n );
02659 DOMString s = en->getAttribute( ATTR_ACCESSKEY );
02660 if( s.length() == 1 ) {
02661 TQChar c = s.string()[ 0 ].upper();
02662 keys.remove( c );
02663 }
02664 }
02665 }
02666
02667 TQMap< ElementImpl*, TQChar > ret;
02668 for( int priority = 10;
02669 priority >= 0;
02670 --priority ) {
02671 for( TQValueList< AccessKeyData >::Iterator it = data.begin();
02672 it != data.end();
02673 ) {
02674 if( (*it).priority != priority ) {
02675 ++it;
02676 continue;
02677 }
02678 if( keys.isEmpty())
02679 break;
02680 TQString text = (*it).text;
02681 TQChar key;
02682 if( key.isNull() && !text.isEmpty()) {
02683 TQValueList< TQPair< TQString, TQChar > > priorities
02684 = m_part->settings()->fallbackAccessKeysAssignments();
02685 for( TQValueList< TQPair< TQString, TQChar > >::ConstIterator it = priorities.begin();
02686 it != priorities.end();
02687 ++it )
02688 if( text == (*it).first && keys.contains( (*it).second )) {
02689 key = (*it).second;
02690 break;
02691 }
02692 }
02693
02694
02695
02696 if( key.isNull() && !text.isEmpty()) {
02697 TQStringList words = TQStringList::split( ' ', text );
02698 for( TQStringList::ConstIterator it = words.begin();
02699 it != words.end();
02700 ++it ) {
02701 if( keys.contains( (*it)[ 0 ].upper())) {
02702 key = (*it)[ 0 ].upper();
02703 break;
02704 }
02705 }
02706 }
02707 if( key.isNull() && !text.isEmpty()) {
02708 for( unsigned int i = 0;
02709 i < text.length();
02710 ++i ) {
02711 if( keys.contains( text[ i ].upper())) {
02712 key = text[ i ].upper();
02713 break;
02714 }
02715 }
02716 }
02717 if( key.isNull())
02718 key = keys.front();
02719 ret[ (*it).element ] = key;
02720 keys.remove( key );
02721 TQString url = (*it).url;
02722 it = data.remove( it );
02723
02724 if( !url.isEmpty() && !url.startsWith( "javascript:", false )) {
02725 for( TQValueList< AccessKeyData >::Iterator it2 = data.begin();
02726 it2 != data.end();
02727 ) {
02728 if( (*it2).url == url ) {
02729 ret[ (*it2).element ] = key;
02730 if( it == it2 )
02731 ++it;
02732 it2 = data.remove( it2 );
02733 } else
02734 ++it2;
02735 }
02736 }
02737 }
02738 }
02739 return ret;
02740 }
02741
02742 void TDEHTMLView::setMediaType( const TQString &medium )
02743 {
02744 m_medium = medium;
02745 }
02746
02747 TQString TDEHTMLView::mediaType() const
02748 {
02749 return m_medium;
02750 }
02751
02752 bool TDEHTMLView::pagedMode() const
02753 {
02754 return d->paged;
02755 }
02756
02757 void TDEHTMLView::setWidgetVisible(RenderWidget* w, bool vis)
02758 {
02759 if (vis) {
02760 d->visibleWidgets.replace(w, w->widget());
02761 }
02762 else
02763 d->visibleWidgets.remove(w);
02764 }
02765
02766 bool TDEHTMLView::needsFullRepaint() const
02767 {
02768 return d->needsFullRepaint;
02769 }
02770
02771 void TDEHTMLView::print()
02772 {
02773 print( false );
02774 }
02775
02776 void TDEHTMLView::print(bool quick)
02777 {
02778 if(!m_part->xmlDocImpl()) return;
02779 tdehtml::RenderCanvas *root = static_cast<tdehtml::RenderCanvas *>(m_part->xmlDocImpl()->renderer());
02780 if(!root) return;
02781
02782 KPrinter *printer = new KPrinter(true, TQPrinter::ScreenResolution);
02783 printer->addDialogPage(new TDEHTMLPrintSettings());
02784 TQString docname = m_part->xmlDocImpl()->URL().prettyURL();
02785 if ( !docname.isEmpty() )
02786 docname = KStringHandler::csqueeze(docname, 80);
02787 if(quick || printer->setup(this, i18n("Print %1").arg(docname))) {
02788 viewport()->setCursor( tqwaitCursor );
02789
02790 printer->setFullPage(false);
02791 printer->setCreator(TQString("KDE %1.%2.%3 HTML Library").arg(TDE_VERSION_MAJOR).arg(TDE_VERSION_MINOR).arg(TDE_VERSION_RELEASE));
02792 printer->setDocName(docname);
02793
02794 TQPainter *p = new TQPainter;
02795 p->begin( printer );
02796 tdehtml::setPrintPainter( p );
02797
02798 m_part->xmlDocImpl()->setPaintDevice( printer );
02799 TQString oldMediaType = mediaType();
02800 setMediaType( "print" );
02801
02802
02803
02804 m_part->xmlDocImpl()->setPrintStyleSheet( printer->option("app-khtml-printfriendly") == "true" ?
02805 "* { background-image: none !important;"
02806 " background-color: white !important;"
02807 " color: black !important; }"
02808 "body { margin: 0px !important; }"
02809 "html { margin: 0px !important; }" :
02810 "body { margin: 0px !important; }"
02811 "html { margin: 0px !important; }"
02812 );
02813
02814 TQPaintDeviceMetrics metrics( printer );
02815
02816 kdDebug(6000) << "printing: physical page width = " << metrics.width()
02817 << " height = " << metrics.height() << endl;
02818 root->setStaticMode(true);
02819 root->setPagedMode(true);
02820 root->setWidth(metrics.width());
02821
02822 root->setPageTop(0);
02823 root->setPageBottom(0);
02824 d->paged = true;
02825
02826 m_part->xmlDocImpl()->styleSelector()->computeFontSizes(&metrics, 100);
02827 m_part->xmlDocImpl()->updateStyleSelector();
02828 root->setPrintImages( printer->option("app-khtml-printimages") == "true");
02829 root->makePageBreakAvoidBlocks();
02830
02831 root->setNeedsLayoutAndMinMaxRecalc();
02832 root->layout();
02833 tdehtml::RenderWidget::flushWidgetResizes();
02834
02835
02836
02837 bool printHeader = (printer->option("app-khtml-printheader") == "true");
02838
02839 int headerHeight = 0;
02840 TQFont headerFont("Sans Serif", 8);
02841
02842 TQString headerLeft = TDEGlobal::locale()->formatDate(TQDate::currentDate(),true);
02843 TQString headerMid = docname;
02844 TQString headerRight;
02845
02846 if (printHeader)
02847 {
02848 p->setFont(headerFont);
02849 headerHeight = (p->fontMetrics().lineSpacing() * 3) / 2;
02850 }
02851
02852
02853 kdDebug(6000) << "printing: html page width = " << root->docWidth()
02854 << " height = " << root->docHeight() << endl;
02855 kdDebug(6000) << "printing: margins left = " << printer->margins().width()
02856 << " top = " << printer->margins().height() << endl;
02857 kdDebug(6000) << "printing: paper width = " << metrics.width()
02858 << " height = " << metrics.height() << endl;
02859
02860
02861 int pageWidth = metrics.width();
02862 int pageHeight = metrics.height();
02863 p->setClipRect(0,0, pageWidth, pageHeight);
02864
02865 pageHeight -= headerHeight;
02866
02867 bool scalePage = false;
02868 double scale = 0.0;
02869 #ifndef QT_NO_TRANSFORMATIONS
02870 if(root->docWidth() > metrics.width()) {
02871 scalePage = true;
02872 scale = ((double) metrics.width())/((double) root->docWidth());
02873 pageHeight = (int) (pageHeight/scale);
02874 pageWidth = (int) (pageWidth/scale);
02875 headerHeight = (int) (headerHeight/scale);
02876 }
02877 #endif
02878 kdDebug(6000) << "printing: scaled html width = " << pageWidth
02879 << " height = " << pageHeight << endl;
02880
02881 root->setHeight(pageHeight);
02882 root->setPageBottom(pageHeight);
02883 root->setNeedsLayout(true);
02884 root->layoutIfNeeded();
02885
02886
02887
02888 if (printHeader)
02889 {
02890 int available_width = metrics.width() - 10 -
02891 2 * kMax(p->boundingRect(0, 0, metrics.width(), p->fontMetrics().lineSpacing(), Qt::AlignLeft, headerLeft).width(),
02892 p->boundingRect(0, 0, metrics.width(), p->fontMetrics().lineSpacing(), Qt::AlignLeft, headerRight).width());
02893 if (available_width < 150)
02894 available_width = 150;
02895 int mid_width;
02896 int squeeze = 120;
02897 do {
02898 headerMid = KStringHandler::csqueeze(docname, squeeze);
02899 mid_width = p->boundingRect(0, 0, metrics.width(), p->fontMetrics().lineSpacing(), Qt::AlignLeft, headerMid).width();
02900 squeeze -= 10;
02901 } while (mid_width > available_width);
02902 }
02903
02904 int top = 0;
02905 int bottom = 0;
02906 int page = 1;
02907 while(top < root->docHeight()) {
02908 if(top > 0) printer->newPage();
02909 p->setClipRect(0, 0, pageWidth, headerHeight, TQPainter::CoordDevice);
02910 if (printHeader)
02911 {
02912 int dy = p->fontMetrics().lineSpacing();
02913 p->setPen(Qt::black);
02914 p->setFont(headerFont);
02915
02916 headerRight = TQString("#%1").arg(page);
02917
02918 p->drawText(0, 0, metrics.width(), dy, Qt::AlignLeft, headerLeft);
02919 p->drawText(0, 0, metrics.width(), dy, Qt::AlignHCenter, headerMid);
02920 p->drawText(0, 0, metrics.width(), dy, Qt::AlignRight, headerRight);
02921 }
02922
02923
02924 #ifndef QT_NO_TRANSFORMATIONS
02925 if (scalePage)
02926 p->scale(scale, scale);
02927 #endif
02928
02929 p->setClipRect(0, headerHeight, pageWidth, pageHeight, TQPainter::CoordDevice);
02930 p->translate(0, headerHeight-top);
02931
02932 bottom = top+pageHeight;
02933
02934 root->setPageTop(top);
02935 root->setPageBottom(bottom);
02936 root->setPageNumber(page);
02937
02938 root->layer()->paint(p, TQRect(0, top, pageWidth, pageHeight));
02939
02940
02941
02942 kdDebug(6000) << "printed: page " << page <<" bottom At = " << bottom << endl;
02943
02944 top = bottom;
02945 p->resetXForm();
02946 page++;
02947 }
02948
02949 p->end();
02950 delete p;
02951
02952
02953 root->setPagedMode(false);
02954 root->setStaticMode(false);
02955 d->paged = false;
02956 tdehtml::setPrintPainter( 0 );
02957 setMediaType( oldMediaType );
02958 m_part->xmlDocImpl()->setPaintDevice( TQT_TQPAINTDEVICE(this) );
02959 m_part->xmlDocImpl()->styleSelector()->computeFontSizes(m_part->xmlDocImpl()->paintDeviceMetrics(), m_part->zoomFactor());
02960 m_part->xmlDocImpl()->updateStyleSelector();
02961 viewport()->unsetCursor();
02962 }
02963 delete printer;
02964 }
02965
02966 void TDEHTMLView::slotPaletteChanged()
02967 {
02968 if(!m_part->xmlDocImpl()) return;
02969 DOM::DocumentImpl *document = m_part->xmlDocImpl();
02970 if (!document->isHTMLDocument()) return;
02971 tdehtml::RenderCanvas *root = static_cast<tdehtml::RenderCanvas *>(document->renderer());
02972 if(!root) return;
02973 root->style()->resetPalette();
02974 NodeImpl *body = static_cast<HTMLDocumentImpl*>(document)->body();
02975 if(!body) return;
02976 body->setChanged(true);
02977 body->recalcStyle( NodeImpl::Force );
02978 }
02979
02980 void TDEHTMLView::paint(TQPainter *p, const TQRect &rc, int yOff, bool *more)
02981 {
02982 if(!m_part->xmlDocImpl()) return;
02983 tdehtml::RenderCanvas *root = static_cast<tdehtml::RenderCanvas *>(m_part->xmlDocImpl()->renderer());
02984 if(!root) return;
02985
02986 m_part->xmlDocImpl()->setPaintDevice(p->device());
02987 root->setPagedMode(true);
02988 root->setStaticMode(true);
02989 root->setWidth(rc.width());
02990
02991 p->save();
02992 p->setClipRect(rc);
02993 p->translate(rc.left(), rc.top());
02994 double scale = ((double) rc.width()/(double) root->docWidth());
02995 int height = (int) ((double) rc.height() / scale);
02996 #ifndef QT_NO_TRANSFORMATIONS
02997 p->scale(scale, scale);
02998 #endif
02999 root->setPageTop(yOff);
03000 root->setPageBottom(yOff+height);
03001
03002 root->layer()->paint(p, TQRect(0, yOff, root->docWidth(), height));
03003 if (more)
03004 *more = yOff + height < root->docHeight();
03005 p->restore();
03006
03007 root->setPagedMode(false);
03008 root->setStaticMode(false);
03009 m_part->xmlDocImpl()->setPaintDevice( TQT_TQPAINTDEVICE(this) );
03010 }
03011
03012
03013 void TDEHTMLView::useSlowRepaints()
03014 {
03015 d->useSlowRepaints = true;
03016 setStaticBackground(true);
03017 }
03018
03019
03020 void TDEHTMLView::setVScrollBarMode ( ScrollBarMode mode )
03021 {
03022 #ifndef TDEHTML_NO_SCROLLBARS
03023 d->vmode = mode;
03024 TQScrollView::setVScrollBarMode(mode);
03025 #else
03026 Q_UNUSED( mode );
03027 #endif
03028 }
03029
03030 void TDEHTMLView::setHScrollBarMode ( ScrollBarMode mode )
03031 {
03032 #ifndef TDEHTML_NO_SCROLLBARS
03033 d->hmode = mode;
03034 TQScrollView::setHScrollBarMode(mode);
03035 #else
03036 Q_UNUSED( mode );
03037 #endif
03038 }
03039
03040 void TDEHTMLView::restoreScrollBar()
03041 {
03042 int ow = visibleWidth();
03043 TQScrollView::setVScrollBarMode(d->vmode);
03044 if (visibleWidth() != ow)
03045 layout();
03046 d->prevScrollbarVisible = verticalScrollBar()->isVisible();
03047 }
03048
03049 TQStringList TDEHTMLView::formCompletionItems(const TQString &name) const
03050 {
03051 if (!m_part->settings()->isFormCompletionEnabled())
03052 return TQStringList();
03053 if (!d->formCompletions)
03054 d->formCompletions = new KSimpleConfig(locateLocal("data", "tdehtml/formcompletions"));
03055 return d->formCompletions->readListEntry(name);
03056 }
03057
03058 void TDEHTMLView::clearCompletionHistory(const TQString& name)
03059 {
03060 if (!d->formCompletions)
03061 {
03062 d->formCompletions = new KSimpleConfig(locateLocal("data", "tdehtml/formcompletions"));
03063 }
03064 d->formCompletions->writeEntry(name, "");
03065 d->formCompletions->sync();
03066 }
03067
03068 void TDEHTMLView::addFormCompletionItem(const TQString &name, const TQString &value)
03069 {
03070 if (!m_part->settings()->isFormCompletionEnabled())
03071 return;
03072
03073
03074
03075 bool cc_number(true);
03076 for (unsigned int i = 0; i < value.length(); ++i)
03077 {
03078 TQChar c(value[i]);
03079 if (!c.isNumber() && c != '-' && !c.isSpace())
03080 {
03081 cc_number = false;
03082 break;
03083 }
03084 }
03085 if (cc_number)
03086 return;
03087 TQStringList items = formCompletionItems(name);
03088 if (!items.contains(value))
03089 items.prepend(value);
03090 while ((int)items.count() > m_part->settings()->maxFormCompletionItems())
03091 items.remove(items.fromLast());
03092 d->formCompletions->writeEntry(name, items);
03093 }
03094
03095 void TDEHTMLView::removeFormCompletionItem(const TQString &name, const TQString &value)
03096 {
03097 if (!m_part->settings()->isFormCompletionEnabled())
03098 return;
03099
03100 TQStringList items = formCompletionItems(name);
03101 if (items.remove(value))
03102 d->formCompletions->writeEntry(name, items);
03103 }
03104
03105 void TDEHTMLView::addNonPasswordStorableSite(const TQString& host)
03106 {
03107 if (!d->formCompletions) {
03108 d->formCompletions = new KSimpleConfig(locateLocal("data", "tdehtml/formcompletions"));
03109 }
03110
03111 d->formCompletions->setGroup("NonPasswordStorableSites");
03112 TQStringList sites = d->formCompletions->readListEntry("Sites");
03113 sites.append(host);
03114 d->formCompletions->writeEntry("Sites", sites);
03115 d->formCompletions->sync();
03116 d->formCompletions->setGroup(TQString::null);
03117 }
03118
03119 bool TDEHTMLView::nonPasswordStorableSite(const TQString& host) const
03120 {
03121 if (!d->formCompletions) {
03122 d->formCompletions = new KSimpleConfig(locateLocal("data", "tdehtml/formcompletions"));
03123 }
03124 d->formCompletions->setGroup("NonPasswordStorableSites");
03125 TQStringList sites = d->formCompletions->readListEntry("Sites");
03126 d->formCompletions->setGroup(TQString::null);
03127
03128 return (sites.find(host) != sites.end());
03129 }
03130
03131
03132 bool TDEHTMLView::dispatchMouseEvent(int eventId, DOM::NodeImpl *targetNode,
03133 DOM::NodeImpl *targetNodeNonShared, bool cancelable,
03134 int detail,TQMouseEvent *_mouse, bool setUnder,
03135 int mouseEventType)
03136 {
03137
03138 if (targetNode && targetNode->isTextNode())
03139 targetNode = targetNode->parentNode();
03140
03141 if (d->underMouse)
03142 d->underMouse->deref();
03143 d->underMouse = targetNode;
03144 if (d->underMouse)
03145 d->underMouse->ref();
03146
03147 if (d->underMouseNonShared)
03148 d->underMouseNonShared->deref();
03149 d->underMouseNonShared = targetNodeNonShared;
03150 if (d->underMouseNonShared)
03151 d->underMouseNonShared->ref();
03152
03153 int exceptioncode = 0;
03154 int pageX = 0;
03155 int pageY = 0;
03156 viewportToContents(_mouse->x(), _mouse->y(), pageX, pageY);
03157 int clientX = pageX - contentsX();
03158 int clientY = pageY - contentsY();
03159 int screenX = _mouse->globalX();
03160 int screenY = _mouse->globalY();
03161 int button = -1;
03162 switch (_mouse->button()) {
03163 case Qt::LeftButton:
03164 button = 0;
03165 break;
03166 case Qt::MidButton:
03167 button = 1;
03168 break;
03169 case Qt::RightButton:
03170 button = 2;
03171 break;
03172 default:
03173 break;
03174 }
03175 if (d->accessKeysEnabled && d->accessKeysPreActivate && button!=-1)
03176 d->accessKeysPreActivate=false;
03177
03178 bool ctrlKey = (_mouse->state() & ControlButton);
03179 bool altKey = (_mouse->state() & AltButton);
03180 bool shiftKey = (_mouse->state() & ShiftButton);
03181 bool metaKey = (_mouse->state() & MetaButton);
03182
03183
03184 if (setUnder && (d->prevMouseX != pageX || d->prevMouseY != pageY)) {
03185
03186
03187
03188 NodeImpl *oldUnder = 0;
03189 if (d->prevMouseX >= 0 && d->prevMouseY >= 0) {
03190 NodeImpl::MouseEvent mev( _mouse->stateAfter(), static_cast<NodeImpl::MouseEventType>(mouseEventType));
03191 m_part->xmlDocImpl()->prepareMouseEvent( true, d->prevMouseX, d->prevMouseY, &mev );
03192 oldUnder = mev.innerNode.handle();
03193
03194 if (oldUnder && oldUnder->isTextNode())
03195 oldUnder = oldUnder->parentNode();
03196 }
03197
03198 if (oldUnder != targetNode) {
03199
03200 if (oldUnder){
03201 oldUnder->ref();
03202 MouseEventImpl *me = new MouseEventImpl(EventImpl::MOUSEOUT_EVENT,
03203 true,true,m_part->xmlDocImpl()->defaultView(),
03204 0,screenX,screenY,clientX,clientY,pageX, pageY,
03205 ctrlKey,altKey,shiftKey,metaKey,
03206 button,targetNode);
03207 me->ref();
03208 oldUnder->dispatchEvent(me,exceptioncode,true);
03209 me->deref();
03210 }
03211
03212
03213 if (targetNode) {
03214 MouseEventImpl *me = new MouseEventImpl(EventImpl::MOUSEOVER_EVENT,
03215 true,true,m_part->xmlDocImpl()->defaultView(),
03216 0,screenX,screenY,clientX,clientY,pageX, pageY,
03217 ctrlKey,altKey,shiftKey,metaKey,
03218 button,oldUnder);
03219
03220 me->ref();
03221 targetNode->dispatchEvent(me,exceptioncode,true);
03222 me->deref();
03223 }
03224
03225 if (oldUnder)
03226 oldUnder->deref();
03227 }
03228 }
03229
03230 bool swallowEvent = false;
03231
03232 if (targetNode) {
03233
03234 bool dblclick = ( eventId == EventImpl::CLICK_EVENT &&
03235 _mouse->type() == TQEvent::MouseButtonDblClick );
03236 MouseEventImpl *me = new MouseEventImpl(static_cast<EventImpl::EventId>(eventId),
03237 true,cancelable,m_part->xmlDocImpl()->defaultView(),
03238 detail,screenX,screenY,clientX,clientY,pageX, pageY,
03239 ctrlKey,altKey,shiftKey,metaKey,
03240 button,0, _mouse, dblclick );
03241 me->ref();
03242 targetNode->dispatchEvent(me,exceptioncode,true);
03243 bool defaultHandled = me->defaultHandled();
03244 if (defaultHandled || me->defaultPrevented())
03245 swallowEvent = true;
03246 me->deref();
03247
03248 if (eventId == EventImpl::MOUSEDOWN_EVENT) {
03249
03250
03251
03252
03253 DOM::NodeImpl* nodeImpl = targetNode;
03254 for ( ; nodeImpl && !nodeImpl->isFocusable(); nodeImpl = nodeImpl->parentNode());
03255 if (nodeImpl && nodeImpl->isMouseFocusable())
03256 m_part->xmlDocImpl()->setFocusNode(nodeImpl);
03257 else if (!nodeImpl || !nodeImpl->focused())
03258 m_part->xmlDocImpl()->setFocusNode(0);
03259 }
03260 }
03261
03262 return swallowEvent;
03263 }
03264
03265 void TDEHTMLView::setIgnoreWheelEvents( bool e )
03266 {
03267 d->ignoreWheelEvents = e;
03268 }
03269
03270 #ifndef QT_NO_WHEELEVENT
03271
03272 void TDEHTMLView::viewportWheelEvent(TQWheelEvent* e)
03273 {
03274 if (d->accessKeysEnabled && d->accessKeysPreActivate) d->accessKeysPreActivate=false;
03275
03276 if ( ( e->state() & ControlButton) == ControlButton )
03277 {
03278 emit zoomView( - e->delta() );
03279 e->accept();
03280 }
03281 else if (d->firstRelayout)
03282 {
03283 e->accept();
03284 }
03285 else if( ( (e->orientation() == Qt::Vertical &&
03286 ((d->ignoreWheelEvents && !verticalScrollBar()->isVisible())
03287 || e->delta() > 0 && contentsY() <= 0
03288 || e->delta() < 0 && contentsY() >= contentsHeight() - visibleHeight()))
03289 ||
03290 (e->orientation() == Qt::Horizontal &&
03291 ((d->ignoreWheelEvents && !horizontalScrollBar()->isVisible())
03292 || e->delta() > 0 && contentsX() <=0
03293 || e->delta() < 0 && contentsX() >= contentsWidth() - visibleWidth())))
03294 && m_part->parentPart())
03295 {
03296 if ( m_part->parentPart()->view() )
03297 m_part->parentPart()->view()->wheelEvent( e );
03298 e->ignore();
03299 }
03300 else
03301 {
03302 d->scrollBarMoved = true;
03303 #ifndef NO_SMOOTH_SCROLL_HACK
03304 scrollViewWheelEvent( e );
03305 #else
03306 TQScrollView::viewportWheelEvent( e );
03307 #endif
03308
03309 TQMouseEvent *tempEvent = new TQMouseEvent( TQEvent::MouseMove, TQPoint(-1,-1), TQPoint(-1,-1), Qt::NoButton, e->state() );
03310 emit viewportMouseMoveEvent ( tempEvent );
03311 delete tempEvent;
03312 }
03313
03314 }
03315 #endif
03316
03317 void TDEHTMLView::dragEnterEvent( TQDragEnterEvent* ev )
03318 {
03319
03320
03321
03322 if ( m_part->parentPart() )
03323 {
03324 TQApplication::sendEvent(m_part->parentPart()->widget(), ev);
03325 return;
03326 }
03327 TQScrollView::dragEnterEvent( ev );
03328 }
03329
03330 void TDEHTMLView::dropEvent( TQDropEvent *ev )
03331 {
03332
03333
03334
03335 if ( m_part->parentPart() )
03336 {
03337 TQApplication::sendEvent(m_part->parentPart()->widget(), ev);
03338 return;
03339 }
03340 TQScrollView::dropEvent( ev );
03341 }
03342
03343 void TDEHTMLView::focusInEvent( TQFocusEvent *e )
03344 {
03345 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
03346 m_part->enableFindAheadActions( true );
03347 #endif
03348 DOM::NodeImpl* fn = m_part->xmlDocImpl() ? m_part->xmlDocImpl()->focusNode() : 0;
03349 if (fn && fn->renderer() && fn->renderer()->isWidget() &&
03350 (e->reason() != TQFocusEvent::Mouse) &&
03351 static_cast<tdehtml::RenderWidget*>(fn->renderer())->widget())
03352 static_cast<tdehtml::RenderWidget*>(fn->renderer())->widget()->setFocus();
03353 #ifndef TDEHTML_NO_CARET
03354
03355
03356 if (d->m_caretViewContext &&
03357 d->m_caretViewContext->freqTimerId == -1 &&
03358 fn) {
03359 if (m_part->isCaretMode()
03360 || m_part->isEditable()
03361 || (fn && fn->renderer()
03362 && fn->renderer()->style()->userInput()
03363 == UI_ENABLED)) {
03364 d->m_caretViewContext->freqTimerId = startTimer(500);
03365 d->m_caretViewContext->visible = true;
03366 }
03367 }
03368 showCaret();
03369 #endif // TDEHTML_NO_CARET
03370 TQScrollView::focusInEvent( e );
03371 }
03372
03373 void TDEHTMLView::focusOutEvent( TQFocusEvent *e )
03374 {
03375 if(m_part) m_part->stopAutoScroll();
03376
03377 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
03378 if(d->typeAheadActivated)
03379 {
03380 findTimeout();
03381 }
03382 m_part->enableFindAheadActions( false );
03383 #endif // TDEHTML_NO_TYPE_AHEAD_FIND
03384
03385 #ifndef TDEHTML_NO_CARET
03386 if (d->m_caretViewContext) {
03387 switch (d->m_caretViewContext->displayNonFocused) {
03388 case TDEHTMLPart::CaretInvisible:
03389 hideCaret();
03390 break;
03391 case TDEHTMLPart::CaretVisible: {
03392 killTimer(d->m_caretViewContext->freqTimerId);
03393 d->m_caretViewContext->freqTimerId = -1;
03394 NodeImpl *caretNode = m_part->xmlDocImpl()->focusNode();
03395 if (!d->m_caretViewContext->visible && (m_part->isCaretMode()
03396 || m_part->isEditable()
03397 || (caretNode && caretNode->renderer()
03398 && caretNode->renderer()->style()->userInput()
03399 == UI_ENABLED))) {
03400 d->m_caretViewContext->visible = true;
03401 showCaret(true);
03402 }
03403 break;
03404 }
03405 case TDEHTMLPart::CaretBlink:
03406
03407 break;
03408 }
03409 }
03410 #endif // TDEHTML_NO_CARET
03411
03412 if ( d->cursor_icon_widget )
03413 d->cursor_icon_widget->hide();
03414
03415 TQScrollView::focusOutEvent( e );
03416 }
03417
03418 void TDEHTMLView::slotScrollBarMoved()
03419 {
03420 if ( !d->firstRelayout && !d->complete && m_part->xmlDocImpl() &&
03421 d->layoutSchedulingEnabled) {
03422
03423 tdehtml::RenderCanvas* root = static_cast<tdehtml::RenderCanvas *>( m_part->xmlDocImpl()->renderer() );
03424 if (root && root->needsLayout()) {
03425 unscheduleRelayout();
03426 layout();
03427 }
03428 }
03429 if (!d->scrollingSelf) {
03430 d->scrollBarMoved = true;
03431 d->contentsMoving = true;
03432
03433 scheduleRepaint(0, 0, 0, 0);
03434 }
03435
03436 if (m_part->xmlDocImpl() && m_part->xmlDocImpl()->documentElement())
03437 m_part->xmlDocImpl()->documentElement()->dispatchHTMLEvent(EventImpl::SCROLL_EVENT, true, false);
03438 }
03439
03440 void TDEHTMLView::timerEvent ( TQTimerEvent *e )
03441 {
03442
03443 if ( e->timerId() == d->scrollTimerId ) {
03444 if( d->scrollSuspended )
03445 return;
03446 switch (d->scrollDirection) {
03447 case TDEHTMLViewPrivate::ScrollDown:
03448 if (contentsY() + visibleHeight () >= contentsHeight())
03449 d->newScrollTimer(this, 0);
03450 else
03451 scrollBy( 0, d->scrollBy );
03452 break;
03453 case TDEHTMLViewPrivate::ScrollUp:
03454 if (contentsY() <= 0)
03455 d->newScrollTimer(this, 0);
03456 else
03457 scrollBy( 0, -d->scrollBy );
03458 break;
03459 case TDEHTMLViewPrivate::ScrollRight:
03460 if (contentsX() + visibleWidth () >= contentsWidth())
03461 d->newScrollTimer(this, 0);
03462 else
03463 scrollBy( d->scrollBy, 0 );
03464 break;
03465 case TDEHTMLViewPrivate::ScrollLeft:
03466 if (contentsX() <= 0)
03467 d->newScrollTimer(this, 0);
03468 else
03469 scrollBy( -d->scrollBy, 0 );
03470 break;
03471 }
03472 return;
03473 }
03474 else if ( e->timerId() == d->layoutTimerId ) {
03475 d->dirtyLayout = true;
03476 layout();
03477 if (d->firstRelayout) {
03478 d->firstRelayout = false;
03479 verticalScrollBar()->setEnabled( true );
03480 horizontalScrollBar()->setEnabled( true );
03481 }
03482 }
03483 #ifndef TDEHTML_NO_CARET
03484 else if (d->m_caretViewContext
03485 && e->timerId() == d->m_caretViewContext->freqTimerId) {
03486 d->m_caretViewContext->visible = !d->m_caretViewContext->visible;
03487 if (d->m_caretViewContext->displayed) {
03488 updateContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
03489 d->m_caretViewContext->width,
03490 d->m_caretViewContext->height);
03491 }
03492
03493
03494 return;
03495 }
03496 #endif
03497
03498 d->contentsMoving = false;
03499 if( m_part->xmlDocImpl() ) {
03500 DOM::DocumentImpl *document = m_part->xmlDocImpl();
03501 tdehtml::RenderCanvas* root = static_cast<tdehtml::RenderCanvas *>(document->renderer());
03502
03503 if ( root && root->needsLayout() ) {
03504 killTimer(d->repaintTimerId);
03505 d->repaintTimerId = 0;
03506 scheduleRelayout();
03507 return;
03508 }
03509 }
03510
03511 setStaticBackground(d->useSlowRepaints);
03512
03513
03514 killTimer(d->repaintTimerId);
03515 d->repaintTimerId = 0;
03516
03517 TQRect updateRegion;
03518 TQMemArray<TQRect> rects = d->updateRegion.rects();
03519
03520 d->updateRegion = TQRegion();
03521
03522 if ( rects.size() )
03523 updateRegion = rects[0];
03524
03525 for ( unsigned i = 1; i < rects.size(); ++i ) {
03526 TQRect newRegion = updateRegion.unite(rects[i]);
03527 if (2*newRegion.height() > 3*updateRegion.height() )
03528 {
03529 repaintContents( updateRegion );
03530 updateRegion = rects[i];
03531 }
03532 else
03533 updateRegion = newRegion;
03534 }
03535
03536 if ( !updateRegion.isNull() )
03537 repaintContents( updateRegion );
03538
03539
03540
03541
03542
03543
03544 if (d->dirtyLayout && !d->visibleWidgets.isEmpty()) {
03545 TQWidget* w;
03546 d->dirtyLayout = false;
03547
03548 TQRect visibleRect(contentsX(), contentsY(), visibleWidth(), visibleHeight());
03549 TQPtrList<RenderWidget> toRemove;
03550 for (TQPtrDictIterator<TQWidget> it(d->visibleWidgets); it.current(); ++it) {
03551 int xp = 0, yp = 0;
03552 w = it.current();
03553 RenderWidget* rw = static_cast<RenderWidget*>( it.currentKey() );
03554 if (!rw->absolutePosition(xp, yp) ||
03555 !visibleRect.intersects(TQRect(xp, yp, w->width(), w->height())))
03556 toRemove.append(rw);
03557 }
03558 for (RenderWidget* r = toRemove.first(); r; r = toRemove.next())
03559 if ( (w = d->visibleWidgets.take(r) ) )
03560 addChild(w, 0, -500000);
03561 }
03562
03563 emit repaintAccessKeys();
03564 if (d->emitCompletedAfterRepaint) {
03565 bool full = d->emitCompletedAfterRepaint == TDEHTMLViewPrivate::CSFull;
03566 d->emitCompletedAfterRepaint = TDEHTMLViewPrivate::CSNone;
03567 if ( full )
03568 emit m_part->completed();
03569 else
03570 emit m_part->completed(true);
03571 }
03572 }
03573
03574 void TDEHTMLView::scheduleRelayout(tdehtml::RenderObject * )
03575 {
03576 if (!d->layoutSchedulingEnabled || d->layoutTimerId)
03577 return;
03578
03579 d->layoutTimerId = startTimer( m_part->xmlDocImpl() && m_part->xmlDocImpl()->parsing()
03580 ? 1000 : 0 );
03581 }
03582
03583 void TDEHTMLView::unscheduleRelayout()
03584 {
03585 if (!d->layoutTimerId)
03586 return;
03587
03588 killTimer(d->layoutTimerId);
03589 d->layoutTimerId = 0;
03590 }
03591
03592 void TDEHTMLView::unscheduleRepaint()
03593 {
03594 if (!d->repaintTimerId)
03595 return;
03596
03597 killTimer(d->repaintTimerId);
03598 d->repaintTimerId = 0;
03599 }
03600
03601 void TDEHTMLView::scheduleRepaint(int x, int y, int w, int h, bool asap)
03602 {
03603 bool parsing = !m_part->xmlDocImpl() || m_part->xmlDocImpl()->parsing();
03604
03605
03606
03607
03608 int time = parsing ? 300 : (!asap ? ( !d->complete ? 100 : 20 ) : 0);
03609
03610 #ifdef DEBUG_FLICKER
03611 TQPainter p;
03612 p.begin( viewport() );
03613
03614 int vx, vy;
03615 contentsToViewport( x, y, vx, vy );
03616 p.fillRect( vx, vy, w, h, TQt::red );
03617 p.end();
03618 #endif
03619
03620 d->updateRegion = d->updateRegion.unite(TQRect(x,y,w,h));
03621
03622 if (asap && !parsing)
03623 unscheduleRepaint();
03624
03625 if ( !d->repaintTimerId )
03626 d->repaintTimerId = startTimer( time );
03627
03628
03629 }
03630
03631 void TDEHTMLView::complete( bool pendingAction )
03632 {
03633
03634
03635 d->complete = true;
03636
03637
03638 if (d->layoutTimerId)
03639 {
03640
03641
03642 killTimer(d->layoutTimerId);
03643 d->layoutTimerId = startTimer( 0 );
03644 d->emitCompletedAfterRepaint = pendingAction ?
03645 TDEHTMLViewPrivate::CSActionPending : TDEHTMLViewPrivate::CSFull;
03646 }
03647
03648
03649 if (d->repaintTimerId)
03650 {
03651
03652
03653 killTimer(d->repaintTimerId);
03654 d->repaintTimerId = startTimer( 20 );
03655 d->emitCompletedAfterRepaint = pendingAction ?
03656 TDEHTMLViewPrivate::CSActionPending : TDEHTMLViewPrivate::CSFull;
03657 }
03658
03659 if (!d->emitCompletedAfterRepaint)
03660 {
03661 if (!pendingAction)
03662 emit m_part->completed();
03663 else
03664 emit m_part->completed(true);
03665 }
03666
03667 }
03668
03669 void TDEHTMLView::slotMouseScrollTimer()
03670 {
03671 scrollBy( d->m_mouseScroll_byX, d->m_mouseScroll_byY );
03672 }
03673
03674 #ifndef TDEHTML_NO_CARET
03675
03676
03677
03678
03679 #include "tdehtml_caret.cpp"
03680
03681 void TDEHTMLView::initCaret(bool keepSelection)
03682 {
03683 #if DEBUG_CARETMODE > 0
03684 kdDebug(6200) << "begin initCaret" << endl;
03685 #endif
03686
03687 if (m_part->xmlDocImpl()) {
03688 #if 0
03689 ElementImpl *listitem = m_part->xmlDocImpl()->getElementById("__test_element__");
03690 if (listitem) dumpLineBoxes(static_cast<RenderFlow *>(listitem->renderer()));
03691 #endif
03692 d->caretViewContext();
03693 bool cmoved = d->m_caretViewContext->caretMoved;
03694 if (m_part->d->caretNode().isNull()) {
03695
03696 m_part->d->caretNode() = m_part->document();
03697 m_part->d->caretOffset() = 0L;
03698
03699
03700
03701 if (!m_part->d->caretNode().handle()->renderer()) return;
03702 }
03703
03704
03705
03706 moveCaretTo(m_part->d->caretNode().handle(), m_part->d->caretOffset(), !keepSelection);
03707
03708
03709 d->m_caretViewContext->caretMoved = cmoved;
03710 }
03711 #if DEBUG_CARETMODE > 0
03712 kdDebug(6200) << "end initCaret" << endl;
03713 #endif
03714 }
03715
03716 bool TDEHTMLView::caretOverrides() const
03717 {
03718 bool cm = m_part->isCaretMode();
03719 bool dm = m_part->isEditable();
03720 return cm && !dm ? false
03721 : (dm || m_part->d->caretNode().handle()->contentEditable())
03722 && d->editorContext()->override;
03723 }
03724
03725 void TDEHTMLView::ensureNodeHasFocus(NodeImpl *node)
03726 {
03727 if (m_part->isCaretMode() || m_part->isEditable()) return;
03728 if (node->focused()) return;
03729
03730
03731 NodeImpl *firstAncestor = 0;
03732 while (node) {
03733 if (node->renderer()
03734 && node->renderer()->style()->userInput() != UI_ENABLED)
03735 break;
03736 firstAncestor = node;
03737 node = node->parentNode();
03738 }
03739
03740 if (!node) firstAncestor = 0;
03741
03742 DocumentImpl *doc = m_part->xmlDocImpl();
03743
03744 if (!firstAncestor && doc->focusNode() && doc->focusNode()->renderer()
03745 && doc->focusNode()->renderer()->isWidget())
03746 return;
03747
03748
03749 #if DEBUG_CARETMODE > 1
03750 kdDebug(6200) << k_funcinfo << "firstAncestor " << firstAncestor << ": "
03751 << (firstAncestor ? firstAncestor->nodeName().string() : TQString::null) << endl;
03752 #endif
03753 doc->setFocusNode(firstAncestor);
03754 emit m_part->nodeActivated(Node(firstAncestor));
03755 }
03756
03757 void TDEHTMLView::recalcAndStoreCaretPos(CaretBox *hintBox)
03758 {
03759 if (!m_part || m_part->d->caretNode().isNull()) return;
03760 d->caretViewContext();
03761 NodeImpl *caretNode = m_part->d->caretNode().handle();
03762 #if DEBUG_CARETMODE > 0
03763 kdDebug(6200) << "recalcAndStoreCaretPos: caretNode=" << caretNode << (caretNode ? " "+caretNode->nodeName().string() : TQString::null) << " r@" << caretNode->renderer() << (caretNode->renderer() && caretNode->renderer()->isText() ? " \"" + TQConstString(static_cast<RenderText *>(caretNode->renderer())->str->s, kMin(static_cast<RenderText *>(caretNode->renderer())->str->l, 15u)).string() + "\"" : TQString::null) << endl;
03764 #endif
03765 caretNode->getCaret(m_part->d->caretOffset(), caretOverrides(),
03766 d->m_caretViewContext->x, d->m_caretViewContext->y,
03767 d->m_caretViewContext->width,
03768 d->m_caretViewContext->height);
03769
03770 if (hintBox && d->m_caretViewContext->x == -1) {
03771 #if DEBUG_CARETMODE > 1
03772 kdDebug(6200) << "using hint inline box coordinates" << endl;
03773 #endif
03774 RenderObject *r = caretNode->renderer();
03775 const TQFontMetrics &fm = r->style()->fontMetrics();
03776 int absx, absy;
03777 r->containingBlock()->absolutePosition(absx, absy,
03778 false);
03779 d->m_caretViewContext->x = absx + hintBox->xPos();
03780 d->m_caretViewContext->y = absy + hintBox->yPos();
03781
03782 d->m_caretViewContext->width = 1;
03783
03784
03785 d->m_caretViewContext->height = fm.height();
03786 }
03787
03788 #if DEBUG_CARETMODE > 4
03789
03790 #endif
03791 #if DEBUG_CARETMODE > 0
03792 kdDebug(6200) << "caret: ofs="<<m_part->d->caretOffset()<<" "
03793 <<" x="<<d->m_caretViewContext->x<<" y="<<d->m_caretViewContext->y
03794 <<" h="<<d->m_caretViewContext->height<<endl;
03795 #endif
03796 }
03797
03798 void TDEHTMLView::caretOn()
03799 {
03800 if (d->m_caretViewContext) {
03801 killTimer(d->m_caretViewContext->freqTimerId);
03802
03803 if (hasFocus() || d->m_caretViewContext->displayNonFocused
03804 == TDEHTMLPart::CaretBlink) {
03805 d->m_caretViewContext->freqTimerId = startTimer(500);
03806 } else {
03807 d->m_caretViewContext->freqTimerId = -1;
03808 }
03809
03810 d->m_caretViewContext->visible = true;
03811 if ((d->m_caretViewContext->displayed = (hasFocus()
03812 || d->m_caretViewContext->displayNonFocused
03813 != TDEHTMLPart::CaretInvisible))) {
03814 updateContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
03815 d->m_caretViewContext->width,
03816 d->m_caretViewContext->height);
03817 }
03818
03819 }
03820 }
03821
03822 void TDEHTMLView::caretOff()
03823 {
03824 if (d->m_caretViewContext) {
03825 killTimer(d->m_caretViewContext->freqTimerId);
03826 d->m_caretViewContext->freqTimerId = -1;
03827 d->m_caretViewContext->displayed = false;
03828 if (d->m_caretViewContext->visible) {
03829 d->m_caretViewContext->visible = false;
03830 updateContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
03831 d->m_caretViewContext->width,
03832 d->m_caretViewContext->height);
03833 }
03834
03835 }
03836 }
03837
03838 void TDEHTMLView::showCaret(bool forceRepaint)
03839 {
03840 if (d->m_caretViewContext) {
03841 d->m_caretViewContext->displayed = true;
03842 if (d->m_caretViewContext->visible) {
03843 if (!forceRepaint) {
03844 updateContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
03845 d->m_caretViewContext->width,
03846 d->m_caretViewContext->height);
03847 } else {
03848 repaintContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
03849 d->m_caretViewContext->width,
03850 d->m_caretViewContext->height);
03851 }
03852 }
03853
03854 }
03855 }
03856
03857 bool TDEHTMLView::foldSelectionToCaret(NodeImpl *startNode, long startOffset,
03858 NodeImpl *endNode, long endOffset)
03859 {
03860 m_part->d->m_selectionStart = m_part->d->m_selectionEnd = m_part->d->caretNode();
03861 m_part->d->m_startOffset = m_part->d->m_endOffset = m_part->d->caretOffset();
03862 m_part->d->m_extendAtEnd = true;
03863
03864 bool folded = startNode != endNode || startOffset != endOffset;
03865
03866
03867 if (folded) {
03868 m_part->xmlDocImpl()->clearSelection();
03869 }
03870
03871 return folded;
03872 }
03873
03874 void TDEHTMLView::hideCaret()
03875 {
03876 if (d->m_caretViewContext) {
03877 if (d->m_caretViewContext->visible) {
03878
03879 d->m_caretViewContext->visible = false;
03880
03881
03882 repaintContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
03883 d->m_caretViewContext->width,
03884 d->m_caretViewContext->height);
03885 d->m_caretViewContext->visible = true;
03886 }
03887 d->m_caretViewContext->displayed = false;
03888
03889 }
03890 }
03891
03892 int TDEHTMLView::caretDisplayPolicyNonFocused() const
03893 {
03894 if (d->m_caretViewContext)
03895 return d->m_caretViewContext->displayNonFocused;
03896 else
03897 return TDEHTMLPart::CaretInvisible;
03898 }
03899
03900 void TDEHTMLView::setCaretDisplayPolicyNonFocused(int policy)
03901 {
03902 d->caretViewContext();
03903
03904 d->m_caretViewContext->displayNonFocused = (TDEHTMLPart::CaretDisplayPolicy)policy;
03905
03906
03907 if (!hasFocus()) {
03908 switch (d->m_caretViewContext->displayNonFocused) {
03909 case TDEHTMLPart::CaretInvisible:
03910 hideCaret();
03911 break;
03912 case TDEHTMLPart::CaretBlink:
03913 if (d->m_caretViewContext->freqTimerId != -1) break;
03914 d->m_caretViewContext->freqTimerId = startTimer(500);
03915
03916 case TDEHTMLPart::CaretVisible:
03917 d->m_caretViewContext->displayed = true;
03918 showCaret();
03919 break;
03920 }
03921 }
03922 }
03923
03924 bool TDEHTMLView::placeCaret(CaretBox *hintBox)
03925 {
03926 CaretViewContext *cv = d->caretViewContext();
03927 caretOff();
03928 NodeImpl *caretNode = m_part->d->caretNode().handle();
03929
03930 if (!caretNode || !caretNode->renderer()) return false;
03931 ensureNodeHasFocus(caretNode);
03932 if (m_part->isCaretMode() || m_part->isEditable()
03933 || caretNode->renderer()->style()->userInput() == UI_ENABLED) {
03934 recalcAndStoreCaretPos(hintBox);
03935
03936 cv->origX = cv->x;
03937
03938 caretOn();
03939 return true;
03940 }
03941 return false;
03942 }
03943
03944 void TDEHTMLView::ensureCaretVisible()
03945 {
03946 CaretViewContext *cv = d->m_caretViewContext;
03947 if (!cv) return;
03948 ensureVisible(cv->x, cv->y, cv->width, cv->height);
03949 d->scrollBarMoved = false;
03950 }
03951
03952 bool TDEHTMLView::extendSelection(NodeImpl *oldStartSel, long oldStartOfs,
03953 NodeImpl *oldEndSel, long oldEndOfs)
03954 {
03955 bool changed = false;
03956 if (m_part->d->m_selectionStart == m_part->d->m_selectionEnd
03957 && m_part->d->m_startOffset == m_part->d->m_endOffset) {
03958 changed = foldSelectionToCaret(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs);
03959 m_part->d->m_extendAtEnd = true;
03960 } else do {
03961 changed = m_part->d->m_selectionStart.handle() != oldStartSel
03962 || m_part->d->m_startOffset != oldStartOfs
03963 || m_part->d->m_selectionEnd.handle() != oldEndSel
03964 || m_part->d->m_endOffset != oldEndOfs;
03965 if (!changed) break;
03966
03967
03968 NodeImpl *startNode;
03969 long startOffset;
03970 if (m_part->d->m_extendAtEnd) {
03971 startNode = m_part->d->m_selectionStart.handle();
03972 startOffset = m_part->d->m_startOffset;
03973 } else {
03974 startNode = m_part->d->m_selectionEnd.handle();
03975 startOffset = m_part->d->m_endOffset;
03976 m_part->d->m_selectionEnd = m_part->d->m_selectionStart;
03977 m_part->d->m_endOffset = m_part->d->m_startOffset;
03978 m_part->d->m_extendAtEnd = true;
03979 }
03980
03981 bool swapNeeded = false;
03982 if (!m_part->d->m_selectionEnd.isNull() && startNode) {
03983 swapNeeded = RangeImpl::compareBoundaryPoints(startNode, startOffset,
03984 m_part->d->m_selectionEnd.handle(),
03985 m_part->d->m_endOffset) >= 0;
03986 }
03987
03988 m_part->d->m_selectionStart = startNode;
03989 m_part->d->m_startOffset = startOffset;
03990
03991 if (swapNeeded) {
03992 m_part->xmlDocImpl()->setSelection(m_part->d->m_selectionEnd.handle(),
03993 m_part->d->m_endOffset, m_part->d->m_selectionStart.handle(),
03994 m_part->d->m_startOffset);
03995 } else {
03996 m_part->xmlDocImpl()->setSelection(m_part->d->m_selectionStart.handle(),
03997 m_part->d->m_startOffset, m_part->d->m_selectionEnd.handle(),
03998 m_part->d->m_endOffset);
03999 }
04000 } while(false);
04001 return changed;
04002 }
04003
04004 void TDEHTMLView::updateSelection(NodeImpl *oldStartSel, long oldStartOfs,
04005 NodeImpl *oldEndSel, long oldEndOfs)
04006 {
04007 if (m_part->d->m_selectionStart == m_part->d->m_selectionEnd
04008 && m_part->d->m_startOffset == m_part->d->m_endOffset) {
04009 if (foldSelectionToCaret(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs)) {
04010 m_part->emitSelectionChanged();
04011 }
04012 m_part->d->m_extendAtEnd = true;
04013 } else {
04014
04015 if (!m_part->d->m_selectionEnd.isNull() && !m_part->d->m_selectionEnd.isNull()) {
04016 bool swapNeeded = RangeImpl::compareBoundaryPoints(
04017 m_part->d->m_selectionStart.handle(), m_part->d->m_startOffset,
04018 m_part->d->m_selectionEnd.handle(), m_part->d->m_endOffset) >= 0;
04019 if (swapNeeded) {
04020 DOM::Node tmpNode = m_part->d->m_selectionStart;
04021 long tmpOffset = m_part->d->m_startOffset;
04022 m_part->d->m_selectionStart = m_part->d->m_selectionEnd;
04023 m_part->d->m_startOffset = m_part->d->m_endOffset;
04024 m_part->d->m_selectionEnd = tmpNode;
04025 m_part->d->m_endOffset = tmpOffset;
04026 m_part->d->m_startBeforeEnd = true;
04027 m_part->d->m_extendAtEnd = !m_part->d->m_extendAtEnd;
04028 }
04029 }
04030
04031 m_part->xmlDocImpl()->setSelection(m_part->d->m_selectionStart.handle(),
04032 m_part->d->m_startOffset, m_part->d->m_selectionEnd.handle(),
04033 m_part->d->m_endOffset);
04034 m_part->emitSelectionChanged();
04035 }
04036 }
04037
04038 void TDEHTMLView::caretKeyPressEvent(TQKeyEvent *_ke)
04039 {
04040 NodeImpl *oldStartSel = m_part->d->m_selectionStart.handle();
04041 long oldStartOfs = m_part->d->m_startOffset;
04042 NodeImpl *oldEndSel = m_part->d->m_selectionEnd.handle();
04043 long oldEndOfs = m_part->d->m_endOffset;
04044
04045 NodeImpl *oldCaretNode = m_part->d->caretNode().handle();
04046 long oldOffset = m_part->d->caretOffset();
04047
04048 bool ctrl = _ke->state() & ControlButton;
04049
04050
04051 switch(_ke->key()) {
04052 case Key_Space:
04053 break;
04054
04055 case Key_Down:
04056 moveCaretNextLine(1);
04057 break;
04058
04059 case Key_Up:
04060 moveCaretPrevLine(1);
04061 break;
04062
04063 case Key_Left:
04064 moveCaretBy(false, ctrl ? CaretByWord : CaretByCharacter, 1);
04065 break;
04066
04067 case Key_Right:
04068 moveCaretBy(true, ctrl ? CaretByWord : CaretByCharacter, 1);
04069 break;
04070
04071 case Key_Next:
04072 moveCaretNextPage();
04073 break;
04074
04075 case Key_Prior:
04076 moveCaretPrevPage();
04077 break;
04078
04079 case Key_Home:
04080 if (ctrl)
04081 moveCaretToDocumentBoundary(false);
04082 else
04083 moveCaretToLineBegin();
04084 break;
04085
04086 case Key_End:
04087 if (ctrl)
04088 moveCaretToDocumentBoundary(true);
04089 else
04090 moveCaretToLineEnd();
04091 break;
04092
04093 }
04094
04095 if ((m_part->d->caretNode().handle() != oldCaretNode
04096 || m_part->d->caretOffset() != oldOffset)
04097
04098 && !m_part->d->caretNode().isNull()) {
04099
04100 d->m_caretViewContext->caretMoved = true;
04101
04102 if (_ke->state() & ShiftButton) {
04103 updateSelection(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs);
04104 } else {
04105 if (foldSelectionToCaret(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs))
04106 m_part->emitSelectionChanged();
04107 }
04108
04109 m_part->emitCaretPositionChanged(m_part->d->caretNode(), m_part->d->caretOffset());
04110 }
04111
04112 _ke->accept();
04113 }
04114
04115 bool TDEHTMLView::moveCaretTo(NodeImpl *node, long offset, bool clearSel)
04116 {
04117 if (!node) return false;
04118 ElementImpl *baseElem = determineBaseElement(node);
04119 RenderFlow *base = static_cast<RenderFlow *>(baseElem ? baseElem->renderer() : 0);
04120 if (!node) return false;
04121
04122
04123
04124
04125 CaretBoxLineDeleter cblDeleter;
04126
04127 long r_ofs;
04128 CaretBoxIterator cbit;
04129 CaretBoxLine *cbl = findCaretBoxLine(node, offset, &cblDeleter, base, r_ofs, cbit);
04130 if(!cbl) {
04131 kdWarning() << "TDEHTMLView::moveCaretTo - findCaretBoxLine() returns NULL" << endl;
04132 return false;
04133 }
04134
04135 #if DEBUG_CARETMODE > 3
04136 if (cbl) kdDebug(6200) << cbl->information() << endl;
04137 #endif
04138 CaretBox *box = *cbit;
04139 if (cbit != cbl->end() && box->object() != node->renderer()) {
04140 if (box->object()->element()) {
04141 mapRenderPosToDOMPos(box->object(), r_ofs, box->isOutside(),
04142 box->isOutsideEnd(), node, offset);
04143
04144 #if DEBUG_CARETMODE > 1
04145 kdDebug(6200) << "set new node " << node->nodeName().string() << "@" << node << endl;
04146 #endif
04147 } else {
04148
04149 box = 0;
04150 kdError(6200) << "Box contains no node! Crash imminent" << endl;
04151 }
04152 }
04153
04154 NodeImpl *oldStartSel = m_part->d->m_selectionStart.handle();
04155 long oldStartOfs = m_part->d->m_startOffset;
04156 NodeImpl *oldEndSel = m_part->d->m_selectionEnd.handle();
04157 long oldEndOfs = m_part->d->m_endOffset;
04158
04159
04160 bool posChanged = m_part->d->caretNode().handle() != node
04161 || m_part->d->caretOffset() != offset;
04162 bool selChanged = false;
04163
04164 m_part->d->caretNode() = node;
04165 m_part->d->caretOffset() = offset;
04166 if (clearSel || !oldStartSel || !oldEndSel) {
04167 selChanged = foldSelectionToCaret(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs);
04168 } else {
04169
04170
04171 selChanged = extendSelection(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs);
04172
04173
04174 }
04175
04176 d->caretViewContext()->caretMoved = true;
04177
04178 bool visible_caret = placeCaret(box);
04179
04180
04181
04182
04183 if (posChanged) {
04184 m_part->emitCaretPositionChanged(visible_caret ? node : 0, offset);
04185 }
04186
04187 return selChanged;
04188 }
04189
04190 void TDEHTMLView::moveCaretByLine(bool next, int count)
04191 {
04192 Node &caretNodeRef = m_part->d->caretNode();
04193 if (caretNodeRef.isNull()) return;
04194
04195 NodeImpl *caretNode = caretNodeRef.handle();
04196
04197 long offset = m_part->d->caretOffset();
04198
04199 CaretViewContext *cv = d->caretViewContext();
04200
04201 ElementImpl *baseElem = determineBaseElement(caretNode);
04202 LinearDocument ld(m_part, caretNode, offset, LeafsOnly, baseElem);
04203
04204 ErgonomicEditableLineIterator it(ld.current(), cv->origX);
04205
04206
04207 while (count > 0 && it != ld.end() && it != ld.preBegin()) {
04208 count--;
04209 if (next) ++it; else --it;
04210 }
04211
04212
04213 if (it == ld.end() || it == ld.preBegin()) return;
04214
04215 int x, absx, absy;
04216 CaretBox *caretBox = nearestCaretBox(it, d->m_caretViewContext, x, absx, absy);
04217
04218 placeCaretOnLine(caretBox, x, absx, absy);
04219 }
04220
04221 void TDEHTMLView::placeCaretOnLine(CaretBox *caretBox, int x, int absx, int absy)
04222 {
04223
04224 if (!caretBox) return;
04225
04226 RenderObject *caretRender = caretBox->object();
04227
04228 #if DEBUG_CARETMODE > 0
04229 kdDebug(6200) << "got valid caretBox " << caretBox << endl;
04230 kdDebug(6200) << "xPos: " << caretBox->xPos() << " yPos: " << caretBox->yPos()
04231 << " width: " << caretBox->width() << " height: " << caretBox->height() << endl;
04232 InlineTextBox *tb = static_cast<InlineTextBox *>(caretBox->inlineBox());
04233 if (caretBox->isInlineTextBox()) { kdDebug(6200) << "contains \"" << TQString(static_cast<RenderText *>(tb->object())->str->s + tb->m_start, tb->m_len) << "\"" << endl;}
04234 #endif
04235
04236 int caretHeight = caretBox->height();
04237 bool isText = caretBox->isInlineTextBox();
04238 int yOfs = 0;
04239 if (isText) {
04240
04241 RenderText *t = static_cast<RenderText *>(caretRender);
04242 const TQFontMetrics &fm = t->metrics(caretBox->inlineBox()->m_firstLine);
04243 caretHeight = fm.height();
04244 yOfs = caretBox->inlineBox()->baseline() - fm.ascent();
04245 }
04246
04247 caretOff();
04248
04249
04250 NodeImpl *caretNode;
04251 long &offset = m_part->d->caretOffset();
04252 mapRenderPosToDOMPos(caretRender, offset, caretBox->isOutside(),
04253 caretBox->isOutsideEnd(), caretNode, offset);
04254
04255
04256 d->m_caretViewContext->y = caretBox->yPos() + yOfs;
04257 d->m_caretViewContext->height = caretHeight;
04258 d->m_caretViewContext->width = 1;
04259
04260 int xPos = caretBox->xPos();
04261 int caretBoxWidth = caretBox->width();
04262 d->m_caretViewContext->x = xPos;
04263
04264 if (!caretBox->isOutside()) {
04265
04266 long r_ofs = 0;
04267 if (x <= xPos) {
04268 r_ofs = caretBox->minOffset();
04269
04270 } else if (x > xPos && x <= xPos + caretBoxWidth) {
04271 if (isText) {
04272 r_ofs = static_cast<InlineTextBox *>(caretBox->inlineBox())
04273 ->offsetForPoint(x, d->m_caretViewContext->x);
04274 #if DEBUG_CARETMODE > 2
04275 kdDebug(6200) << "deviation from origX " << d->m_caretViewContext->x - x << endl;
04276 #endif
04277 #if 0
04278 } else {
04279 if (xPos + caretBoxWidth - x < x - xPos) {
04280 d->m_caretViewContext->x = xPos + caretBoxWidth;
04281 r_ofs = caretNode ? caretNode->maxOffset() : 1;
04282 } else {
04283 d->m_caretViewContext->x = xPos;
04284 r_ofs = caretNode ? caretNode->minOffset() : 0;
04285 }
04286 #endif
04287 }
04288 } else {
04289 d->m_caretViewContext->x = xPos + caretBoxWidth;
04290 r_ofs = caretBox->maxOffset();
04291 }
04292 offset = r_ofs;
04293 }
04294 #if DEBUG_CARETMODE > 0
04295 kdDebug(6200) << "new offset: " << offset << endl;
04296 #endif
04297
04298 m_part->d->caretNode() = caretNode;
04299 m_part->d->caretOffset() = offset;
04300
04301 d->m_caretViewContext->x += absx;
04302 d->m_caretViewContext->y += absy;
04303
04304 #if DEBUG_CARETMODE > 1
04305 kdDebug(6200) << "new caret position: x " << d->m_caretViewContext->x << " y " << d->m_caretViewContext->y << " w " << d->m_caretViewContext->width << " h " << d->m_caretViewContext->height << " absx " << absx << " absy " << absy << endl;
04306 #endif
04307
04308 ensureVisible(d->m_caretViewContext->x, d->m_caretViewContext->y,
04309 d->m_caretViewContext->width, d->m_caretViewContext->height);
04310 d->scrollBarMoved = false;
04311
04312 ensureNodeHasFocus(caretNode);
04313 caretOn();
04314 }
04315
04316 void TDEHTMLView::moveCaretToLineBoundary(bool end)
04317 {
04318 Node &caretNodeRef = m_part->d->caretNode();
04319 if (caretNodeRef.isNull()) return;
04320
04321 NodeImpl *caretNode = caretNodeRef.handle();
04322
04323 long offset = m_part->d->caretOffset();
04324
04325 ElementImpl *baseElem = determineBaseElement(caretNode);
04326 LinearDocument ld(m_part, caretNode, offset, LeafsOnly, baseElem);
04327
04328 EditableLineIterator it = ld.current();
04329 if (it == ld.end()) return;
04330
04331 EditableCaretBoxIterator fbit(it, end);
04332 Q_ASSERT(fbit != (*it)->end() && fbit != (*it)->preBegin());
04333 CaretBox *b = *fbit;
04334
04335 RenderObject *cb = b->containingBlock();
04336 int absx, absy;
04337
04338 if (cb) cb->absolutePosition(absx,absy);
04339 else absx = absy = 0;
04340
04341 int x = b->xPos() + (end && !b->isOutside() ? b->width() : 0);
04342 d->m_caretViewContext->origX = absx + x;
04343 placeCaretOnLine(b, x, absx, absy);
04344 }
04345
04346 void TDEHTMLView::moveCaretToDocumentBoundary(bool end)
04347 {
04348 Node &caretNodeRef = m_part->d->caretNode();
04349 if (caretNodeRef.isNull()) return;
04350
04351 NodeImpl *caretNode = caretNodeRef.handle();
04352
04353 long offset = m_part->d->caretOffset();
04354
04355 ElementImpl *baseElem = determineBaseElement(caretNode);
04356 LinearDocument ld(m_part, caretNode, offset, IndicatedFlows, baseElem);
04357
04358 EditableLineIterator it(end ? ld.preEnd() : ld.begin(), end);
04359 if (it == ld.end() || it == ld.preBegin()) return;
04360
04361 EditableCaretBoxIterator fbit = it;
04362 Q_ASSERT(fbit != (*it)->end() && fbit != (*it)->preBegin());
04363 CaretBox *b = *fbit;
04364
04365 RenderObject *cb = (*it)->containingBlock();
04366 int absx, absy;
04367
04368 if (cb) cb->absolutePosition(absx, absy);
04369 else absx = absy = 0;
04370
04371 int x = b->xPos();
04372 d->m_caretViewContext->origX = absx + x;
04373 placeCaretOnLine(b, x, absx, absy);
04374 }
04375
04376 void TDEHTMLView::moveCaretBy(bool next, CaretMovement cmv, int count)
04377 {
04378 if (!m_part) return;
04379 Node &caretNodeRef = m_part->d->caretNode();
04380 if (caretNodeRef.isNull()) return;
04381
04382 NodeImpl *caretNode = caretNodeRef.handle();
04383
04384 long &offset = m_part->d->caretOffset();
04385
04386 ElementImpl *baseElem = determineBaseElement(caretNode);
04387 CaretAdvancePolicy advpol = cmv != CaretByWord ? IndicatedFlows : LeafsOnly;
04388 LinearDocument ld(m_part, caretNode, offset, advpol, baseElem);
04389
04390 EditableCharacterIterator it(&ld);
04391 while (!it.isEnd() && count > 0) {
04392 count--;
04393 if (cmv == CaretByCharacter) {
04394 if (next) ++it;
04395 else --it;
04396 } else if (cmv == CaretByWord) {
04397 if (next) moveItToNextWord(it);
04398 else moveItToPrevWord(it);
04399 }
04400
04401 }
04402 CaretBox *hintBox = 0;
04403 if (!it.isEnd()) {
04404 NodeImpl *node = caretNodeRef.handle();
04405 hintBox = it.caretBox();
04406
04407
04408 mapRenderPosToDOMPos(it.renderer(), it.offset(), hintBox->isOutside(),
04409 hintBox->isOutsideEnd(), node, offset);
04410
04411 caretNodeRef = node;
04412 #if DEBUG_CARETMODE > 2
04413 kdDebug(6200) << "set by valid node " << node << " " << (node?node->nodeName().string():TQString::null) << " offset: " << offset << endl;
04414 #endif
04415 } else {
04416 offset = next ? caretNode->maxOffset() : caretNode->minOffset();
04417 #if DEBUG_CARETMODE > 0
04418 kdDebug(6200) << "set by INvalid node. offset: " << offset << endl;
04419 #endif
04420 }
04421 placeCaretOnChar(hintBox);
04422 }
04423
04424 void TDEHTMLView::placeCaretOnChar(CaretBox *hintBox)
04425 {
04426 caretOff();
04427 recalcAndStoreCaretPos(hintBox);
04428 ensureVisible(d->m_caretViewContext->x, d->m_caretViewContext->y,
04429 d->m_caretViewContext->width, d->m_caretViewContext->height);
04430 d->m_caretViewContext->origX = d->m_caretViewContext->x;
04431 d->scrollBarMoved = false;
04432 #if DEBUG_CARETMODE > 3
04433
04434 #endif
04435 ensureNodeHasFocus(m_part->d->caretNode().handle());
04436 caretOn();
04437 }
04438
04439 void TDEHTMLView::moveCaretByPage(bool next)
04440 {
04441 Node &caretNodeRef = m_part->d->caretNode();
04442 if (caretNodeRef.isNull()) return;
04443
04444 NodeImpl *caretNode = caretNodeRef.handle();
04445
04446 long offset = m_part->d->caretOffset();
04447
04448 int offs = (clipper()->height() < 30) ? clipper()->height() : 30;
04449
04450 int mindist = clipper()->height() - offs;
04451
04452 CaretViewContext *cv = d->caretViewContext();
04453
04454
04455 ElementImpl *baseElem = determineBaseElement(caretNode);
04456 LinearDocument ld(m_part, caretNode, offset, LeafsOnly, baseElem);
04457
04458 ErgonomicEditableLineIterator it(ld.current(), cv->origX);
04459
04460 moveIteratorByPage(ld, it, mindist, next);
04461
04462 int x, absx, absy;
04463 CaretBox *caretBox = nearestCaretBox(it, d->m_caretViewContext, x, absx, absy);
04464
04465 placeCaretOnLine(caretBox, x, absx, absy);
04466 }
04467
04468 void TDEHTMLView::moveCaretPrevWord()
04469 {
04470 moveCaretBy(false, CaretByWord, 1);
04471 }
04472
04473 void TDEHTMLView::moveCaretNextWord()
04474 {
04475 moveCaretBy(true, CaretByWord, 1);
04476 }
04477
04478 void TDEHTMLView::moveCaretPrevLine(int n)
04479 {
04480 moveCaretByLine(false, n);
04481 }
04482
04483 void TDEHTMLView::moveCaretNextLine(int n)
04484 {
04485 moveCaretByLine(true, n);
04486 }
04487
04488 void TDEHTMLView::moveCaretPrevPage()
04489 {
04490 moveCaretByPage(false);
04491 }
04492
04493 void TDEHTMLView::moveCaretNextPage()
04494 {
04495 moveCaretByPage(true);
04496 }
04497
04498 void TDEHTMLView::moveCaretToLineBegin()
04499 {
04500 moveCaretToLineBoundary(false);
04501 }
04502
04503 void TDEHTMLView::moveCaretToLineEnd()
04504 {
04505 moveCaretToLineBoundary(true);
04506 }
04507
04508 #endif // TDEHTML_NO_CARET
04509
04510 #ifndef NO_SMOOTH_SCROLL_HACK
04511 #define timer timer2
04512
04513
04514 static const int SCROLL_TIME = 240;
04515
04516 static const int SCROLL_TICK = 20;
04517
04518 void TDEHTMLView::scrollBy(int dx, int dy)
04519 {
04520 TDEConfigGroup cfg( TDEGlobal::config(), "KDE" );
04521 if( !cfg.readBoolEntry( "SmoothScrolling", false )) {
04522 TQScrollView::scrollBy( dx, dy );
04523 return;
04524 }
04525
04526 int full_dx = d->dx + dx;
04527 int full_dy = d->dy + dy;
04528
04529
04530 int ddx = 0;
04531 int ddy = 0;
04532
04533 int steps = SCROLL_TIME/SCROLL_TICK;
04534
04535 ddx = (full_dx*16)/steps;
04536 ddy = (full_dy*16)/steps;
04537
04538
04539 if (ddx > 0 && ddx < 16) ddx = 16;
04540 if (ddy > 0 && ddy < 16) ddy = 16;
04541 if (ddx < 0 && ddx > -16) ddx = -16;
04542 if (ddy < 0 && ddy > -16) ddy = -16;
04543
04544 d->dx = full_dx;
04545 d->dy = full_dy;
04546 d->ddx = ddx;
04547 d->ddy = ddy;
04548
04549 if (!d->scrolling) {
04550 scrollTick();
04551 startScrolling();
04552 }
04553 }
04554
04555 void TDEHTMLView::scrollTick() {
04556 if (d->dx == 0 && d->dy == 0) {
04557 stopScrolling();
04558 return;
04559 }
04560
04561 int tddx = d->ddx + d->rdx;
04562 int tddy = d->ddy + d->rdy;
04563
04564 int ddx = tddx / 16;
04565 int ddy = tddy / 16;
04566 d->rdx = tddx % 16;
04567 d->rdy = tddy % 16;
04568
04569 if (d->dx > 0 && ddx > d->dx) ddx = d->dx;
04570 else
04571 if (d->dx < 0 && ddx < d->dx) ddx = d->dx;
04572
04573 if (d->dy > 0 && ddy > d->dy) ddy = d->dy;
04574 else
04575 if (d->dy < 0 && ddy < d->dy) ddy = d->dy;
04576
04577 d->dx -= ddx;
04578 d->dy -= ddy;
04579
04580
04581 kapp->syncX();
04582 TQScrollView::scrollBy(ddx, ddy);
04583
04584
04585
04586 kapp->syncX();
04587 }
04588
04589 void TDEHTMLView::startScrolling()
04590 {
04591 d->scrolling = true;
04592 d->timer.start(SCROLL_TICK, false);
04593 }
04594
04595 void TDEHTMLView::stopScrolling()
04596 {
04597 d->timer.stop();
04598 d->dx = d->dy = 0;
04599 d->scrolling = false;
04600 }
04601
04602
04603 void TDEHTMLView::scrollViewWheelEvent( TQWheelEvent *e )
04604 {
04605 int pageStep = verticalScrollBar()->pageStep();
04606 int lineStep = verticalScrollBar()->lineStep();
04607 int step = TQMIN( TQApplication::wheelScrollLines()*lineStep, pageStep );
04608 if ( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) )
04609 step = pageStep;
04610
04611 if(e->orientation() == Qt::Horizontal)
04612 scrollBy(-((e->delta()*step)/120), 0);
04613 else if(e->orientation() == Qt::Vertical)
04614 scrollBy(0,-((e->delta()*step)/120));
04615
04616 e->accept();
04617 }
04618
04619 #undef timer
04620
04621 #endif // NO_SMOOTH_SCROLL_HACK
04622
04623 #undef DEBUG_CARETMODE