summaryrefslogtreecommitdiffstats
path: root/khtml/khtmlview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'khtml/khtmlview.cpp')
-rw-r--r--khtml/khtmlview.cpp4623
1 files changed, 0 insertions, 4623 deletions
diff --git a/khtml/khtmlview.cpp b/khtml/khtmlview.cpp
deleted file mode 100644
index 4a5c7cf2d..000000000
--- a/khtml/khtmlview.cpp
+++ /dev/null
@@ -1,4623 +0,0 @@
-/* This file is part of the KDE project
- *
- * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
- * 1999 Lars Knoll <knoll@kde.org>
- * 1999 Antti Koivisto <koivisto@kde.org>
- * 2000-2004 Dirk Mueller <mueller@kde.org>
- * 2003 Leo Savernik <l.savernik@aon.at>
- * 2003-2004 Apple Computer, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-
-#include "khtmlview.moc"
-
-#include "khtmlview.h"
-
-#include "khtml_part.h"
-#include "khtml_events.h"
-
-#include "html/html_documentimpl.h"
-#include "html/html_inlineimpl.h"
-#include "html/html_formimpl.h"
-#include "rendering/render_arena.h"
-#include "rendering/render_canvas.h"
-#include "rendering/render_frames.h"
-#include "rendering/render_replaced.h"
-#include "rendering/render_layer.h"
-#include "rendering/render_line.h"
-#include "rendering/render_table.h"
-// removeme
-#define protected public
-#include "rendering/render_text.h"
-#undef protected
-#include "xml/dom2_eventsimpl.h"
-#include "css/cssstyleselector.h"
-#include "css/csshelper.h"
-#include "misc/htmlhashes.h"
-#include "misc/helper.h"
-#include "misc/loader.h"
-#include "khtml_settings.h"
-#include "khtml_printsettings.h"
-
-#include "khtmlpart_p.h"
-
-#ifndef KHTML_NO_CARET
-#include "khtml_caret_p.h"
-#include "xml/dom2_rangeimpl.h"
-#endif
-
-#include <kapplication.h>
-#include <kcursor.h>
-#include <kdebug.h>
-#include <kdialogbase.h>
-#include <kiconloader.h>
-#include <kimageio.h>
-#include <klocale.h>
-#include <knotifyclient.h>
-#include <kprinter.h>
-#include <ksimpleconfig.h>
-#include <kstandarddirs.h>
-#include <kstdaccel.h>
-#include <kstringhandler.h>
-#include <kurldrag.h>
-
-#include <tqbitmap.h>
-#include <tqlabel.h>
-#include <tqobjectlist.h>
-#include <tqpaintdevicemetrics.h>
-#include <tqpainter.h>
-#include <tqptrdict.h>
-#include <tqtooltip.h>
-#include <tqstring.h>
-#include <tqstylesheet.h>
-#include <tqtimer.h>
-#include <tqvaluevector.h>
-
-//#define DEBUG_NO_PAINT_BUFFER
-
-//#define DEBUG_FLICKER
-
-//#define DEBUG_PIXEL
-
-#ifdef Q_WS_X11
-#include <X11/Xlib.h>
-#include <fixx11h.h>
-#endif
-
-#define PAINT_BUFFER_HEIGHT 128
-
-#if 0
-namespace khtml {
- void dumpLineBoxes(RenderFlow *flow);
-}
-#endif
-
-using namespace DOM;
-using namespace khtml;
-class KHTMLToolTip;
-
-
-#ifndef QT_NO_TOOLTIP
-
-class KHTMLToolTip : public TQToolTip
-{
-public:
- KHTMLToolTip(KHTMLView *view, KHTMLViewPrivate* vp) : TQToolTip(view->viewport())
- {
- m_view = view;
- m_viewprivate = vp;
- };
-
-protected:
- virtual void maybeTip(const TQPoint &);
-
-private:
- KHTMLView *m_view;
- KHTMLViewPrivate* m_viewprivate;
-};
-
-#endif
-
-class KHTMLViewPrivate {
- friend class KHTMLToolTip;
-public:
-
- enum PseudoFocusNodes {
- PFNone,
- PFTop,
- PFBottom
- };
-
- enum CompletedState {
- CSNone = 0,
- CSFull,
- CSActionPending
- };
-
- KHTMLViewPrivate()
- : underMouse( 0 ), underMouseNonShared( 0 ), visibleWidgets( 107 )
-#ifndef NO_SMOOTH_SCROLL_HACK
- , dx(0), dy(0), ddx(0), ddy(0), rdx(0), rdy(0), scrolling(false)
-#endif
- {
-#ifndef KHTML_NO_CARET
- m_caretViewContext = 0;
- m_editorContext = 0;
-#endif // KHTML_NO_CARET
- postponed_autorepeat = NULL;
- reset();
- vmode = TQScrollView::Auto;
- hmode = TQScrollView::Auto;
- tp=0;
- paintBuffer=0;
- vertPaintBuffer=0;
- formCompletions=0;
- prevScrollbarVisible = true;
- tooltip = 0;
- possibleTripleClick = false;
- emitCompletedAfterRepaint = CSNone;
- cursor_icon_widget = NULL;
- m_mouseScrollTimer = 0;
- m_mouseScrollIndicator = 0;
- }
- ~KHTMLViewPrivate()
- {
- delete formCompletions;
- delete tp; tp = 0;
- delete paintBuffer; paintBuffer =0;
- delete vertPaintBuffer;
- delete postponed_autorepeat;
- if (underMouse)
- underMouse->deref();
- if (underMouseNonShared)
- underMouseNonShared->deref();
- delete tooltip;
-#ifndef KHTML_NO_CARET
- delete m_caretViewContext;
- delete m_editorContext;
-#endif // KHTML_NO_CARET
- delete cursor_icon_widget;
- delete m_mouseScrollTimer;
- delete m_mouseScrollIndicator;
- }
- void reset()
- {
- if (underMouse)
- underMouse->deref();
- underMouse = 0;
- if (underMouseNonShared)
- underMouseNonShared->deref();
- underMouseNonShared = 0;
- linkPressed = false;
- useSlowRepaints = false;
- tabMovePending = false;
- lastTabbingDirection = true;
- pseudoFocusNode = PFNone;
-#ifndef KHTML_NO_SCROLLBARS
- //We don't turn off the toolbars here
- //since if the user turns them
- //off, then chances are they want them turned
- //off always - even after a reset.
-#else
- vmode = TQScrollView::AlwaysOff;
- hmode = TQScrollView::AlwaysOff;
-#endif
-#ifdef DEBUG_PIXEL
- timer.start();
- pixelbooth = 0;
- repaintbooth = 0;
-#endif
- scrollBarMoved = false;
- contentsMoving = false;
- ignoreWheelEvents = false;
- borderX = 30;
- borderY = 30;
- paged = false;
- clickX = -1;
- clickY = -1;
- prevMouseX = -1;
- prevMouseY = -1;
- clickCount = 0;
- isDoubleClick = false;
- scrollingSelf = false;
- delete postponed_autorepeat;
- postponed_autorepeat = NULL;
- layoutTimerId = 0;
- repaintTimerId = 0;
- scrollTimerId = 0;
- scrollSuspended = false;
- scrollSuspendPreActivate = false;
- complete = false;
- firstRelayout = true;
- needsFullRepaint = true;
- dirtyLayout = false;
- layoutSchedulingEnabled = true;
- painting = false;
- updateRegion = TQRegion();
- m_dialogsAllowed = true;
-#ifndef KHTML_NO_CARET
- if (m_caretViewContext) {
- m_caretViewContext->caretMoved = false;
- m_caretViewContext->keyReleasePending = false;
- }/*end if*/
-#endif // KHTML_NO_CARET
-#ifndef KHTML_NO_TYPE_AHEAD_FIND
- typeAheadActivated = false;
-#endif // KHTML_NO_TYPE_AHEAD_FIND
- accessKeysActivated = false;
- accessKeysPreActivate = false;
-
- // We ref/deref to ensure defaultHTMLSettings is available
- KHTMLFactory::ref();
- accessKeysEnabled = KHTMLFactory::defaultHTMLSettings()->accessKeysEnabled();
- KHTMLFactory::deref();
-
- emitCompletedAfterRepaint = CSNone;
- }
- void newScrollTimer(TQWidget *view, int tid)
- {
- //kdDebug(6000) << "newScrollTimer timer " << tid << endl;
- view->killTimer(scrollTimerId);
- scrollTimerId = tid;
- scrollSuspended = false;
- }
- enum ScrollDirection { ScrollLeft, ScrollRight, ScrollUp, ScrollDown };
-
- void adjustScroller(TQWidget *view, ScrollDirection direction, ScrollDirection oppositedir)
- {
- static const struct { int msec, pixels; } timings [] = {
- {320,1}, {224,1}, {160,1}, {112,1}, {80,1}, {56,1}, {40,1},
- {28,1}, {20,1}, {20,2}, {20,3}, {20,4}, {20,6}, {20,8}, {0,0}
- };
- if (!scrollTimerId ||
- (static_cast<int>(scrollDirection) != direction &&
- (static_cast<int>(scrollDirection) != oppositedir || scrollSuspended))) {
- scrollTiming = 6;
- scrollBy = timings[scrollTiming].pixels;
- scrollDirection = direction;
- newScrollTimer(view, view->startTimer(timings[scrollTiming].msec));
- } else if (scrollDirection == direction &&
- timings[scrollTiming+1].msec && !scrollSuspended) {
- scrollBy = timings[++scrollTiming].pixels;
- newScrollTimer(view, view->startTimer(timings[scrollTiming].msec));
- } else if (scrollDirection == oppositedir) {
- if (scrollTiming) {
- scrollBy = timings[--scrollTiming].pixels;
- newScrollTimer(view, view->startTimer(timings[scrollTiming].msec));
- }
- }
- scrollSuspended = false;
- }
-
-#ifndef KHTML_NO_CARET
- /** this function returns an instance of the caret view context. If none
- * exists, it will be instantiated.
- */
- CaretViewContext *caretViewContext() {
- if (!m_caretViewContext) m_caretViewContext = new CaretViewContext();
- return m_caretViewContext;
- }
- /** this function returns an instance of the editor context. If none
- * exists, it will be instantiated.
- */
- EditorContext *editorContext() {
- if (!m_editorContext) m_editorContext = new EditorContext();
- return m_editorContext;
- }
-#endif // KHTML_NO_CARET
-
-#ifdef DEBUG_PIXEL
- TQTime timer;
- unsigned int pixelbooth;
- unsigned int repaintbooth;
-#endif
-
- TQPainter *tp;
- TQPixmap *paintBuffer;
- TQPixmap *vertPaintBuffer;
- NodeImpl *underMouse;
- NodeImpl *underMouseNonShared;
-
- bool tabMovePending:1;
- bool lastTabbingDirection:1;
- PseudoFocusNodes pseudoFocusNode:2;
- bool scrollBarMoved:1;
- bool contentsMoving:1;
-
- TQScrollView::ScrollBarMode vmode;
- TQScrollView::ScrollBarMode hmode;
- bool prevScrollbarVisible:1;
- bool linkPressed:1;
- bool useSlowRepaints:1;
- bool ignoreWheelEvents:1;
-
- int borderX, borderY;
- KSimpleConfig *formCompletions;
-
- bool paged;
-
- int clickX, clickY, clickCount;
- bool isDoubleClick;
-
- int prevMouseX, prevMouseY;
- bool scrollingSelf;
- int layoutTimerId;
- TQKeyEvent* postponed_autorepeat;
-
- int repaintTimerId;
- int scrollTimerId;
- int scrollTiming;
- int scrollBy;
- ScrollDirection scrollDirection :2;
- bool scrollSuspended :1;
- bool scrollSuspendPreActivate :1;
- bool complete :1;
- bool firstRelayout :1;
- bool layoutSchedulingEnabled :1;
- bool needsFullRepaint :1;
- bool painting :1;
- bool possibleTripleClick :1;
- bool dirtyLayout :1;
- bool m_dialogsAllowed :1;
- TQRegion updateRegion;
- KHTMLToolTip *tooltip;
- TQPtrDict<TQWidget> visibleWidgets;
-#ifndef KHTML_NO_CARET
- CaretViewContext *m_caretViewContext;
- EditorContext *m_editorContext;
-#endif // KHTML_NO_CARET
-#ifndef KHTML_NO_TYPE_AHEAD_FIND
- TQString findString;
- TQTimer timer;
- bool findLinksOnly;
- bool typeAheadActivated;
-#endif // KHTML_NO_TYPE_AHEAD_FIND
- bool accessKeysEnabled;
- bool accessKeysActivated;
- bool accessKeysPreActivate;
- CompletedState emitCompletedAfterRepaint;
-
- TQWidget* cursor_icon_widget;
-
- // scrolling activated by MMB
- short m_mouseScroll_byX;
- short m_mouseScroll_byY;
- TQTimer *m_mouseScrollTimer;
- TQWidget *m_mouseScrollIndicator;
-#ifndef NO_SMOOTH_SCROLL_HACK
- TQTimer timer2;
- int dx;
- int dy;
- // Step size * 16 and residual to avoid huge difference between 1px/step and 2px/step
- int ddx;
- int ddy;
- int rdx;
- int rdy;
- bool scrolling;
-#endif
-};
-
-#ifndef QT_NO_TOOLTIP
-
-/** calculates the client-side image map rectangle for the given image element
- * @param img image element
- * @param scrollOfs scroll offset of viewport in content coordinates
- * @param p position to be probed in viewport coordinates
- * @param r returns the bounding rectangle in content coordinates
- * @param s returns the title string
- * @return true if an appropriate area was found -- only in this case r and
- * s are valid, false otherwise
- */
-static bool findImageMapRect(HTMLImageElementImpl *img, const TQPoint &scrollOfs,
- const TQPoint &p, TQRect &r, TQString &s)
-{
- HTMLMapElementImpl* map;
- if (img && img->getDocument()->isHTMLDocument() &&
- (map = static_cast<HTMLDocumentImpl*>(img->getDocument())->getMap(img->imageMap()))) {
- RenderObject::NodeInfo info(true, false);
- RenderObject *rend = img->renderer();
- int ax, ay;
- if (!rend || !rend->absolutePosition(ax, ay))
- return false;
- // we're a client side image map
- bool inside = map->mapMouseEvent(p.x() - ax + scrollOfs.x(),
- p.y() - ay + scrollOfs.y(), rend->contentWidth(),
- rend->contentHeight(), info);
- if (inside && info.URLElement()) {
- HTMLAreaElementImpl *area = static_cast<HTMLAreaElementImpl *>(info.URLElement());
- Q_ASSERT(area->id() == ID_AREA);
- s = area->getAttribute(ATTR_TITLE).string();
- TQRegion reg = area->cachedRegion();
- if (!s.isEmpty() && !reg.isEmpty()) {
- r = reg.boundingRect();
- r.moveBy(ax, ay);
- return true;
- }
- }
- }
- return false;
-}
-
-void KHTMLToolTip::maybeTip(const TQPoint& p)
-{
- DOM::NodeImpl *node = m_viewprivate->underMouseNonShared;
- TQRect region;
- while ( node ) {
- if ( node->isElementNode() ) {
- DOM::ElementImpl *e = static_cast<DOM::ElementImpl*>( node );
- TQRect r;
- TQString s;
- bool found = false;
- // for images, check if it is part of a client-side image map,
- // and query the <area>s' title attributes, too
- if (e->id() == ID_IMG && !e->getAttribute( ATTR_USEMAP ).isEmpty()) {
- found = findImageMapRect(static_cast<HTMLImageElementImpl *>(e),
- m_view->viewportToContents(TQPoint(0, 0)), p, r, s);
- }
- if (!found) {
- s = e->getAttribute( ATTR_TITLE ).string();
- r = node->getRect();
- }
- region |= TQRect( m_view->contentsToViewport( r.topLeft() ), r.size() );
- if ( !s.isEmpty() ) {
- tip( region, TQStyleSheet::convertFromPlainText( s, TQStyleSheetItem::WhiteSpaceNormal ) );
- break;
- }
- }
- node = node->parentNode();
- }
-}
-#endif
-
-KHTMLView::KHTMLView( KHTMLPart *part, TQWidget *parent, const char *name)
- : TQScrollView( parent, name, (WFlags)(WResizeNoErase | WRepaintNoErase) )
-{
- m_medium = "screen";
-
- m_part = part;
- d = new KHTMLViewPrivate;
- TQScrollView::setVScrollBarMode(d->vmode);
- TQScrollView::setHScrollBarMode(d->hmode);
- connect(kapp, TQT_SIGNAL(kdisplayPaletteChanged()), this, TQT_SLOT(slotPaletteChanged()));
- connect(this, TQT_SIGNAL(contentsMoving(int, int)), this, TQT_SLOT(slotScrollBarMoved()));
-
- // initialize QScrollView
- enableClipper(true);
- // hack to get unclipped painting on the viewport.
- static_cast<KHTMLView *>(TQT_TQWIDGET(viewport()))->setWFlags(WPaintUnclipped);
-
- setResizePolicy(Manual);
- viewport()->setMouseTracking(true);
- viewport()->setBackgroundMode(NoBackground);
-
- KImageIO::registerFormats();
-
-#ifndef QT_NO_TOOLTIP
- d->tooltip = new KHTMLToolTip( this, d );
-#endif
-
-#ifndef KHTML_NO_TYPE_AHEAD_FIND
- connect(&d->timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(findTimeout()));
-#endif // KHTML_NO_TYPE_AHEAD_FIND
-
- init();
-
- viewport()->show();
-#ifndef NO_SMOOTH_SCROLL_HACK
-#define timer timer2
- connect(&d->timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(scrollTick()));
-#undef timer
-#endif
-}
-
-KHTMLView::~KHTMLView()
-{
- closeChildDialogs();
- if (m_part)
- {
- //WABA: Is this Ok? Do I need to deref it as well?
- //Does this need to be done somewhere else?
- DOM::DocumentImpl *doc = m_part->xmlDocImpl();
- if (doc)
- doc->detach();
- }
- delete d; d = 0;
-}
-
-void KHTMLView::init()
-{
- if(!d->paintBuffer) d->paintBuffer = new TQPixmap(PAINT_BUFFER_HEIGHT, PAINT_BUFFER_HEIGHT);
- if(!d->vertPaintBuffer)
- d->vertPaintBuffer = new TQPixmap(10, PAINT_BUFFER_HEIGHT);
- if(!d->tp) d->tp = new TQPainter();
-
- setFocusPolicy(TQ_StrongFocus);
- viewport()->setFocusProxy(this);
-
- _marginWidth = -1; // undefined
- _marginHeight = -1;
- _width = 0;
- _height = 0;
-
- installEventFilter(this);
-
- setAcceptDrops(true);
- TQSize s = viewportSize(4095, 4095);
- resizeContents(s.width(), s.height());
-}
-
-void KHTMLView::clear()
-{
- // work around QScrollview's unbelievable bugginess
- setStaticBackground(true);
-#ifndef KHTML_NO_CARET
- if (!m_part->isCaretMode() && !m_part->isEditable()) caretOff();
-#endif
-
-#ifndef KHTML_NO_TYPE_AHEAD_FIND
- if( d->typeAheadActivated )
- findTimeout();
-#endif
- if (d->accessKeysEnabled && d->accessKeysActivated)
- accessKeysTimeout();
- viewport()->unsetCursor();
- if ( d->cursor_icon_widget )
- d->cursor_icon_widget->hide();
- d->reset();
- TQT_TQOBJECT(this)->killTimers();
- emit cleared();
-
- TQScrollView::setHScrollBarMode(d->hmode);
- TQScrollView::setVScrollBarMode(d->vmode);
- verticalScrollBar()->setEnabled( false );
- horizontalScrollBar()->setEnabled( false );
-}
-
-void KHTMLView::hideEvent(TQHideEvent* e)
-{
- TQScrollView::hideEvent(e);
- if ( m_part && m_part->xmlDocImpl() )
- m_part->xmlDocImpl()->docLoader()->pauseAnimations();
-}
-
-void KHTMLView::showEvent(TQShowEvent* e)
-{
- TQScrollView::showEvent(e);
- if ( m_part && m_part->xmlDocImpl() )
- m_part->xmlDocImpl()->docLoader()->resumeAnimations();
-}
-
-void KHTMLView::resizeEvent (TQResizeEvent* e)
-{
- int dw = e->oldSize().width() - e->size().width();
- int dh = e->oldSize().height() - e->size().height();
-
- // if we are shrinking the view, don't allow the content to overflow
- // before the layout occurs - we don't know if we need scrollbars yet
- dw = dw>0 ? kMax(0, contentsWidth()-dw) : contentsWidth();
- dh = dh>0 ? kMax(0, contentsHeight()-dh) : contentsHeight();
-
- resizeContents(dw, dh);
-
- TQScrollView::resizeEvent(e);
-
- if ( m_part && m_part->xmlDocImpl() )
- m_part->xmlDocImpl()->dispatchWindowEvent( EventImpl::RESIZE_EVENT, false, false );
-}
-
-void KHTMLView::viewportResizeEvent (TQResizeEvent* e)
-{
- TQScrollView::viewportResizeEvent(e);
-
- //int w = visibleWidth();
- //int h = visibleHeight();
-
- if (d->layoutSchedulingEnabled)
- layout();
-#ifndef KHTML_NO_CARET
- else {
- hideCaret();
- recalcAndStoreCaretPos();
- showCaret();
- }/*end if*/
-#endif
-
- TDEApplication::sendPostedEvents(viewport(), TQEvent::Paint);
-}
-
-// this is to get rid of a compiler virtual overload mismatch warning. do not remove
-void KHTMLView::drawContents( TQPainter*)
-{
-}
-
-void KHTMLView::drawContents( TQPainter *p, int ex, int ey, int ew, int eh )
-{
-#ifdef DEBUG_PIXEL
-
- if ( d->timer.elapsed() > 5000 ) {
- tqDebug( "drawed %d pixels in %d repaints the last %d milliseconds",
- d->pixelbooth, d->repaintbooth, d->timer.elapsed() );
- d->timer.restart();
- d->pixelbooth = 0;
- d->repaintbooth = 0;
- }
- d->pixelbooth += ew*eh;
- d->repaintbooth++;
-#endif
-
- //kdDebug( 6000 ) << "drawContents this="<< this <<" x=" << ex << ",y=" << ey << ",w=" << ew << ",h=" << eh << endl;
- if(!m_part || !m_part->xmlDocImpl() || !m_part->xmlDocImpl()->renderer()) {
- p->fillRect(ex, ey, ew, eh, palette().active().brush(TQColorGroup::Base));
- return;
- } else if ( d->complete && static_cast<RenderCanvas*>(m_part->xmlDocImpl()->renderer())->needsLayout() ) {
- // an external update request happens while we have a layout scheduled
- unscheduleRelayout();
- layout();
- }
-
- if (d->painting) {
- kdDebug( 6000 ) << "WARNING: drawContents reentered! " << endl;
- return;
- }
- d->painting = true;
-
- TQPoint pt = contentsToViewport(TQPoint(ex, ey));
- TQRegion cr = TQRect(pt.x(), pt.y(), ew, eh);
-
- // kdDebug(6000) << "clip rect: " << TQRect(pt.x(), pt.y(), ew, eh) << endl;
- for (TQPtrDictIterator<TQWidget> it(d->visibleWidgets); it.current(); ++it) {
- TQWidget *w = it.current();
- RenderWidget* rw = static_cast<RenderWidget*>( it.currentKey() );
- if (w && rw && !rw->isKHTMLWidget()) {
- int x, y;
- rw->absolutePosition(x, y);
- contentsToViewport(x, y, x, y);
- int pbx = rw->borderLeft()+rw->paddingLeft();
- int pby = rw->borderTop()+rw->paddingTop();
- TQRect g = TQRect(x+pbx, y+pby,
- rw->width()-pbx-rw->borderRight()-rw->paddingRight(),
- rw->height()-pby-rw->borderBottom()-rw->paddingBottom());
- if ( !rw->isFrame() && ((g.top() > pt.y()+eh) || (g.bottom() <= pt.y()) ||
- (g.right() <= pt.x()) || (g.left() > pt.x()+ew) ))
- continue;
- RenderLayer* rl = rw->needsMask() ? rw->enclosingStackingContext() : 0;
- TQRegion mask = rl ? rl->getMask() : TQRegion();
- if (!mask.isNull()) {
- TQPoint o(0,0);
- o = contentsToViewport(o);
- mask.translate(o.x(),o.y());
- mask = mask.intersect( TQRect(g.x(),g.y(),g.width(),g.height()) );
- cr -= mask;
- } else {
- cr -= g;
- }
- }
- }
-
-#if 0
- // this is commonly the case with framesets. we still do
- // want to paint them, otherwise the widgets don't get placed.
- if (cr.isEmpty()) {
- d->painting = false;
- return;
- }
-#endif
-
-#ifndef DEBUG_NO_PAINT_BUFFER
- p->setClipRegion(cr);
-
- if (eh > PAINT_BUFFER_HEIGHT && ew <= 10) {
- if ( d->vertPaintBuffer->height() < visibleHeight() )
- d->vertPaintBuffer->resize(10, visibleHeight());
- d->tp->begin(d->vertPaintBuffer);
- d->tp->translate(-ex, -ey);
- d->tp->fillRect(ex, ey, ew, eh, palette().active().brush(TQColorGroup::Base));
- m_part->xmlDocImpl()->renderer()->layer()->paint(d->tp, TQRect(ex, ey, ew, eh));
- d->tp->end();
- p->drawPixmap(ex, ey, *d->vertPaintBuffer, 0, 0, ew, eh);
- }
- else {
- if ( d->paintBuffer->width() < visibleWidth() )
- d->paintBuffer->resize(visibleWidth(),PAINT_BUFFER_HEIGHT);
-
- int py=0;
- while (py < eh) {
- int ph = eh-py < PAINT_BUFFER_HEIGHT ? eh-py : PAINT_BUFFER_HEIGHT;
- d->tp->begin(d->paintBuffer);
- d->tp->translate(-ex, -ey-py);
- d->tp->fillRect(ex, ey+py, ew, ph, palette().active().brush(TQColorGroup::Base));
- m_part->xmlDocImpl()->renderer()->layer()->paint(d->tp, TQRect(ex, ey+py, ew, ph));
- d->tp->end();
-
- p->drawPixmap(ex, ey+py, *d->paintBuffer, 0, 0, ew, ph);
- py += PAINT_BUFFER_HEIGHT;
- }
- }
-#else // !DEBUG_NO_PAINT_BUFFER
-static int cnt=0;
- ex = contentsX(); ey = contentsY();
- ew = visibleWidth(); eh = visibleHeight();
- TQRect pr(ex,ey,ew,eh);
- kdDebug() << "[" << ++cnt << "]" << " clip region: " << pr << endl;
-// p->setClipRegion(TQRect(0,0,ew,eh));
-// p->translate(-ex, -ey);
- p->fillRect(ex, ey, ew, eh, palette().active().brush(TQColorGroup::Base));
- m_part->xmlDocImpl()->renderer()->layer()->paint(p, pr);
-#endif // DEBUG_NO_PAINT_BUFFER
-
-#ifndef KHTML_NO_CARET
- if (d->m_caretViewContext && d->m_caretViewContext->visible) {
- TQRect pos(d->m_caretViewContext->x, d->m_caretViewContext->y,
- d->m_caretViewContext->width, d->m_caretViewContext->height);
- if (pos.intersects(TQRect(ex, ey, ew, eh))) {
- p->setRasterOp(XorROP);
- p->setPen(white);
- if (pos.width() == 1)
- p->drawLine(pos.topLeft(), pos.bottomRight());
- else {
- p->fillRect(pos, white);
- }/*end if*/
- }/*end if*/
- }/*end if*/
-#endif // KHTML_NO_CARET
-
-// p->setPen(TQPen(magenta,0,DashDotDotLine));
-// p->drawRect(dbg_paint_rect);
-
- khtml::DrawContentsEvent event( p, ex, ey, ew, eh );
- TQApplication::sendEvent( m_part, &event );
-
- d->painting = false;
-}
-
-void KHTMLView::setMarginWidth(int w)
-{
- // make it update the rendering area when set
- _marginWidth = w;
-}
-
-void KHTMLView::setMarginHeight(int h)
-{
- // make it update the rendering area when set
- _marginHeight = h;
-}
-
-void KHTMLView::layout()
-{
- if( m_part && m_part->xmlDocImpl() ) {
- DOM::DocumentImpl *document = m_part->xmlDocImpl();
-
- khtml::RenderCanvas* canvas = static_cast<khtml::RenderCanvas *>(document->renderer());
- if ( !canvas ) return;
-
- d->layoutSchedulingEnabled=false;
-
- // the reference object for the overflow property on canvas
- RenderObject * ref = 0;
- RenderObject* root = document->documentElement() ? document->documentElement()->renderer() : 0;
-
- if (document->isHTMLDocument()) {
- NodeImpl *body = static_cast<HTMLDocumentImpl*>(document)->body();
- if(body && body->renderer() && body->id() == ID_FRAMESET) {
- TQScrollView::setVScrollBarMode(AlwaysOff);
- TQScrollView::setHScrollBarMode(AlwaysOff);
- body->renderer()->setNeedsLayout(true);
-// if (d->tooltip) {
-// delete d->tooltip;
-// d->tooltip = 0;
-// }
- }
- else {
- if (!d->tooltip)
- d->tooltip = new KHTMLToolTip( this, d );
- // only apply body's overflow to canvas if root as a visible overflow
- if (root)
- ref = (!body || root->style()->hidesOverflow()) ? root : body->renderer();
- }
- } else {
- ref = root;
- }
- if (ref) {
- if( ref->style()->overflowX() == OHIDDEN ) {
- if (d->hmode == Auto) TQScrollView::setHScrollBarMode(AlwaysOff);
- } else if (ref->style()->overflowX() == OSCROLL ) {
- if (d->hmode == Auto) TQScrollView::setHScrollBarMode(AlwaysOn);
- } else {
- if (TQScrollView::hScrollBarMode() == AlwaysOff) TQScrollView::setHScrollBarMode(d->hmode);
- } if ( ref->style()->overflowY() == OHIDDEN ) {
- if (d->vmode == Auto) TQScrollView::setVScrollBarMode(AlwaysOff);
- } else if (ref->style()->overflowY() == OSCROLL ) {
- if (d->vmode == Auto) TQScrollView::setVScrollBarMode(AlwaysOn);
- } else {
- if (TQScrollView::vScrollBarMode() == AlwaysOff) TQScrollView::setVScrollBarMode(d->vmode);
- }
- }
- d->needsFullRepaint = d->firstRelayout;
- if (_height != visibleHeight() || _width != visibleWidth()) {;
- d->needsFullRepaint = true;
- _height = visibleHeight();
- _width = visibleWidth();
- }
- //TQTime qt;
- //qt.start();
- canvas->layout();
-
- emit finishedLayout();
- if (d->firstRelayout) {
- // make sure firstRelayout is set to false now in case this layout
- // wasn't scheduled
- d->firstRelayout = false;
- verticalScrollBar()->setEnabled( true );
- horizontalScrollBar()->setEnabled( true );
- }
-#if 0
- ElementImpl *listitem = m_part->xmlDocImpl()->getElementById("__test_element__");
- if (listitem) kdDebug(6000) << "after layout, before repaint" << endl;
- if (listitem) dumpLineBoxes(static_cast<RenderFlow *>(listitem->renderer()));
-#endif
-#ifndef KHTML_NO_CARET
- hideCaret();
- if ((m_part->isCaretMode() || m_part->isEditable())
- && !d->complete && d->m_caretViewContext
- && !d->m_caretViewContext->caretMoved) {
- initCaret();
- } else {
- recalcAndStoreCaretPos();
- showCaret();
- }/*end if*/
-#endif
- if (d->accessKeysEnabled && d->accessKeysActivated) {
- emit hideAccessKeys();
- displayAccessKeys();
- }
- //kdDebug( 6000 ) << "TIME: layout() dt=" << qt.elapsed() << endl;
- }
- else
- _width = visibleWidth();
-
- killTimer(d->layoutTimerId);
- d->layoutTimerId = 0;
- d->layoutSchedulingEnabled=true;
-}
-
-void KHTMLView::closeChildDialogs()
-{
- TQObjectList *dlgs = queryList(TQDIALOG_OBJECT_NAME_STRING);
- for (TQObject *dlg = dlgs->first(); dlg; dlg = dlgs->next())
- {
- KDialogBase* dlgbase = dynamic_cast<KDialogBase *>( dlg );
- if ( dlgbase ) {
- if ( dlgbase->testWFlags( WShowModal ) ) {
- kdDebug(6000) << "closeChildDialogs: closing dialog " << dlgbase << endl;
- // close() ends up calling TQButton::animateClick, which isn't immediate
- // we need something the exits the event loop immediately (#49068)
- dlgbase->cancel();
- }
- }
- else
- {
- kdWarning() << "closeChildDialogs: not a KDialogBase! Don't use QDialogs in KDE! " << TQT_TQWIDGET(dlg) << endl;
- TQT_TQWIDGET(dlg)->hide();
- }
- }
- delete dlgs;
- d->m_dialogsAllowed = false;
-}
-
-bool KHTMLView::dialogsAllowed() {
- bool allowed = d->m_dialogsAllowed;
- KHTMLPart* p = m_part->parentPart();
- if (p && p->view())
- allowed &= p->view()->dialogsAllowed();
- return allowed;
-}
-
-void KHTMLView::closeEvent( TQCloseEvent* ev )
-{
- closeChildDialogs();
- TQScrollView::closeEvent( ev );
-}
-
-//
-// Event Handling
-//
-/////////////////
-
-void KHTMLView::viewportMousePressEvent( TQMouseEvent *_mouse )
-{
- if (!m_part->xmlDocImpl()) return;
- if (d->possibleTripleClick && ( _mouse->button() & Qt::MouseButtonMask ) == Qt::LeftButton)
- {
- viewportMouseDoubleClickEvent( _mouse ); // it handles triple clicks too
- return;
- }
-
- int xm, ym;
- viewportToContents(_mouse->x(), _mouse->y(), xm, ym);
- //kdDebug( 6000 ) << "mousePressEvent: viewport=("<<_mouse->x()<<"/"<<_mouse->y()<<"), contents=(" << xm << "/" << ym << ")\n";
-
- d->isDoubleClick = false;
-
- DOM::NodeImpl::MouseEvent mev( _mouse->stateAfter(), DOM::NodeImpl::MousePress );
- m_part->xmlDocImpl()->prepareMouseEvent( false, xm, ym, &mev );
-
- //kdDebug(6000) << "innerNode="<<mev.innerNode.nodeName().string()<<endl;
-
- if ( (_mouse->button() == Qt::MidButton) &&
- !m_part->d->m_bOpenMiddleClick && !d->m_mouseScrollTimer &&
- mev.url.isNull() && (mev.innerNode.elementId() != ID_INPUT) ) {
- TQPoint point = mapFromGlobal( _mouse->globalPos() );
-
- d->m_mouseScroll_byX = 0;
- d->m_mouseScroll_byY = 0;
-
- d->m_mouseScrollTimer = new TQTimer( this );
- connect( d->m_mouseScrollTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotMouseScrollTimer()) );
-
- if ( !d->m_mouseScrollIndicator ) {
- TQPixmap pixmap, icon;
- pixmap.resize( 48, 48 );
- pixmap.fill( TQColor( tqRgba( 127, 127, 127, 127 ) ) );
-
- TQPainter p( &pixmap );
- icon = TDEGlobal::iconLoader()->loadIcon( "1uparrow", KIcon::Small );
- p.drawPixmap( 16, 0, icon );
- icon = TDEGlobal::iconLoader()->loadIcon( "1leftarrow", KIcon::Small );
- p.drawPixmap( 0, 16, icon );
- icon = TDEGlobal::iconLoader()->loadIcon( "1downarrow", KIcon::Small );
- p.drawPixmap( 16, 32,icon );
- icon = TDEGlobal::iconLoader()->loadIcon( "1rightarrow", KIcon::Small );
- p.drawPixmap( 32, 16, icon );
- p.drawEllipse( 23, 23, 2, 2 );
-
- d->m_mouseScrollIndicator = new TQWidget( this, 0 );
- d->m_mouseScrollIndicator->setFixedSize( 48, 48 );
- d->m_mouseScrollIndicator->setPaletteBackgroundPixmap( pixmap );
- }
- d->m_mouseScrollIndicator->move( point.x()-24, point.y()-24 );
-
- bool hasHorBar = visibleWidth() < contentsWidth();
- bool hasVerBar = visibleHeight() < contentsHeight();
-
- TDEConfig *config = TDEGlobal::config();
- TDEConfigGroupSaver saver( config, "HTML Settings" );
- if ( config->readBoolEntry( "ShowMouseScrollIndicator", true ) ) {
- d->m_mouseScrollIndicator->show();
- d->m_mouseScrollIndicator->unsetCursor();
-
- TQBitmap mask = d->m_mouseScrollIndicator->paletteBackgroundPixmap()->createHeuristicMask( true );
-
- if ( hasHorBar && !hasVerBar ) {
- TQBitmap bm( 16, 16, true );
- bitBlt( &mask, 16, 0, &bm, 0, 0, -1, -1 );
- bitBlt( &mask, 16, 32, &bm, 0, 0, -1, -1 );
- d->m_mouseScrollIndicator->setCursor( KCursor::SizeHorCursor );
- }
- else if ( !hasHorBar && hasVerBar ) {
- TQBitmap bm( 16, 16, true );
- bitBlt( &mask, 0, 16, &bm, 0, 0, -1, -1 );
- bitBlt( &mask, 32, 16, &bm, 0, 0, -1, -1 );
- d->m_mouseScrollIndicator->setCursor( KCursor::SizeVerCursor );
- }
- else
- d->m_mouseScrollIndicator->setCursor( KCursor::SizeAllCursor );
-
- d->m_mouseScrollIndicator->setMask( mask );
- }
- else {
- if ( hasHorBar && !hasVerBar )
- viewport()->setCursor( KCursor::SizeHorCursor );
- else if ( !hasHorBar && hasVerBar )
- viewport()->setCursor( KCursor::SizeVerCursor );
- else
- viewport()->setCursor( KCursor::SizeAllCursor );
- }
-
- return;
- }
- else if ( d->m_mouseScrollTimer ) {
- delete d->m_mouseScrollTimer;
- d->m_mouseScrollTimer = 0;
-
- if ( d->m_mouseScrollIndicator )
- d->m_mouseScrollIndicator->hide();
- }
-
- d->clickCount = 1;
- d->clickX = xm;
- d->clickY = ym;
-
- bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEDOWN_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),true,
- d->clickCount,_mouse,true,DOM::NodeImpl::MousePress);
-
- khtml::RenderObject* r = mev.innerNode.handle() ? mev.innerNode.handle()->renderer() : 0;
- if (r && r->isWidget())
- _mouse->ignore();
-
- if (!swallowEvent) {
- emit m_part->nodeActivated(mev.innerNode);
-
- khtml::MousePressEvent event( _mouse, xm, ym, mev.url, mev.target, mev.innerNode );
- TQApplication::sendEvent( m_part, &event );
- // we might be deleted after this
- }
-}
-
-void KHTMLView::viewportMouseDoubleClickEvent( TQMouseEvent *_mouse )
-{
- if(!m_part->xmlDocImpl()) return;
-
- int xm, ym;
- viewportToContents(_mouse->x(), _mouse->y(), xm, ym);
-
- kdDebug( 6000 ) << "mouseDblClickEvent: x=" << xm << ", y=" << ym << endl;
-
- d->isDoubleClick = true;
-
- DOM::NodeImpl::MouseEvent mev( _mouse->stateAfter(), DOM::NodeImpl::MouseDblClick );
- m_part->xmlDocImpl()->prepareMouseEvent( false, xm, ym, &mev );
-
- // We do the same thing as viewportMousePressEvent() here, since the DOM does not treat
- // single and double-click events as separate (only the detail, i.e. number of clicks differs)
- if (d->clickCount > 0 &&
- TQPoint(d->clickX-xm,d->clickY-ym).manhattanLength() <= TQApplication::startDragDistance())
- d->clickCount++;
- else { // shouldn't happen, if Qt has the same criterias for double clicks.
- d->clickCount = 1;
- d->clickX = xm;
- d->clickY = ym;
- }
- bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEDOWN_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),true,
- d->clickCount,_mouse,true,DOM::NodeImpl::MouseDblClick);
-
- khtml::RenderObject* r = mev.innerNode.handle() ? mev.innerNode.handle()->renderer() : 0;
- if (r && r->isWidget())
- _mouse->ignore();
-
- if (!swallowEvent) {
- khtml::MouseDoubleClickEvent event( _mouse, xm, ym, mev.url, mev.target, mev.innerNode, d->clickCount );
- TQApplication::sendEvent( m_part, &event );
- }
-
- d->possibleTripleClick=true;
- TQTimer::singleShot(TQApplication::doubleClickInterval(),this,TQT_SLOT(tripleClickTimeout()));
-}
-
-void KHTMLView::tripleClickTimeout()
-{
- d->possibleTripleClick = false;
- d->clickCount = 0;
-}
-
-static inline void forwardPeripheralEvent(khtml::RenderWidget* r, TQMouseEvent* me, int x, int y)
-{
- int absx = 0;
- int absy = 0;
- r->absolutePosition(absx, absy);
- TQPoint p(x-absx, y-absy);
- TQMouseEvent fw(me->type(), p, me->button(), me->state());
- TQWidget* w = r->widget();
- TQScrollView* sc = ::tqqt_cast<TQScrollView*>(w);
- if (sc && !::tqqt_cast<TQListBox*>(w))
- static_cast<khtml::RenderWidget::ScrollViewEventPropagator*>(sc)->sendEvent(TQT_TQEVENT(&fw));
- else if(w)
- static_cast<khtml::RenderWidget::EventPropagator*>(w)->sendEvent(TQT_TQEVENT(&fw));
-}
-
-
-static bool targetOpensNewWindow(KHTMLPart *part, TQString target)
-{
- if (!target.isEmpty() && (target.lower() != "_top") &&
- (target.lower() != "_self") && (target.lower() != "_parent")) {
- if (target.lower() == "_blank")
- return true;
- else {
- while (part->parentPart())
- part = part->parentPart();
- if (!part->frameExists(target))
- return true;
- }
- }
- return false;
-}
-
-void KHTMLView::viewportMouseMoveEvent( TQMouseEvent * _mouse )
-{
- if ( d->m_mouseScrollTimer ) {
- TQPoint point = mapFromGlobal( _mouse->globalPos() );
-
- int deltaX = point.x() - d->m_mouseScrollIndicator->x() - 24;
- int deltaY = point.y() - d->m_mouseScrollIndicator->y() - 24;
-
- (deltaX > 0) ? d->m_mouseScroll_byX = 1 : d->m_mouseScroll_byX = -1;
- (deltaY > 0) ? d->m_mouseScroll_byY = 1 : d->m_mouseScroll_byY = -1;
-
- double adX = TQABS(deltaX)/30.0;
- double adY = TQABS(deltaY)/30.0;
-
- d->m_mouseScroll_byX = kMax(kMin(d->m_mouseScroll_byX * int(adX*adX), SHRT_MAX), SHRT_MIN);
- d->m_mouseScroll_byY = kMax(kMin(d->m_mouseScroll_byY * int(adY*adY), SHRT_MAX), SHRT_MIN);
-
- if (d->m_mouseScroll_byX == 0 && d->m_mouseScroll_byY == 0) {
- d->m_mouseScrollTimer->stop();
- }
- else if (!d->m_mouseScrollTimer->isActive()) {
- d->m_mouseScrollTimer->changeInterval( 20 );
- }
- }
-
- if(!m_part->xmlDocImpl()) return;
-
- int xm, ym;
- viewportToContents(_mouse->x(), _mouse->y(), xm, ym);
-
- DOM::NodeImpl::MouseEvent mev( _mouse->stateAfter(), DOM::NodeImpl::MouseMove );
- // Do not modify :hover/:active state while mouse is pressed.
- m_part->xmlDocImpl()->prepareMouseEvent( _mouse->state() & Qt::MouseButtonMask /*readonly ?*/, xm, ym, &mev );
-
-// kdDebug(6000) << "mouse move: " << _mouse->pos()
-// << " button " << _mouse->button()
-// << " state " << _mouse->state() << endl;
-
- bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEMOVE_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),false,
- 0,_mouse,true,DOM::NodeImpl::MouseMove);
-
- if (d->clickCount > 0 &&
- TQPoint(d->clickX-xm,d->clickY-ym).manhattanLength() > TQApplication::startDragDistance()) {
- d->clickCount = 0; // moving the mouse outside the threshold invalidates the click
- }
-
- // execute the scheduled script. This is to make sure the mouseover events come after the mouseout events
- m_part->executeScheduledScript();
-
- DOM::NodeImpl* fn = m_part->xmlDocImpl()->focusNode();
- if (fn && fn != mev.innerNode.handle() &&
- fn->renderer() && fn->renderer()->isWidget()) {
- forwardPeripheralEvent(static_cast<khtml::RenderWidget*>(fn->renderer()), _mouse, xm, ym);
- }
-
- khtml::RenderObject* r = mev.innerNode.handle() ? mev.innerNode.handle()->renderer() : 0;
- khtml::RenderStyle* style = (r && r->style()) ? r->style() : 0;
- TQCursor c;
- bool mailtoCursor = false;
- bool newWindowCursor = false;
- switch ( style ? style->cursor() : CURSOR_AUTO) {
- case CURSOR_AUTO:
- if ( r && r->isText() )
- c = KCursor::ibeamCursor();
- if ( mev.url.length() && m_part->settings()->changeCursor() ) {
- c = m_part->urlCursor();
- if (mev.url.string().startsWith("mailto:") && mev.url.string().find('@')>0)
- mailtoCursor = true;
- else
- newWindowCursor = targetOpensNewWindow( m_part, mev.target.string() );
- }
-
- if (r && r->isFrameSet() && !static_cast<RenderFrameSet*>(r)->noResize())
- c = TQCursor(static_cast<RenderFrameSet*>(r)->cursorShape());
-
- break;
- case CURSOR_CROSS:
- c = KCursor::crossCursor();
- break;
- case CURSOR_POINTER:
- c = m_part->urlCursor();
- if (mev.url.string().startsWith("mailto:") && mev.url.string().find('@')>0)
- mailtoCursor = true;
- else
- newWindowCursor = targetOpensNewWindow( m_part, mev.target.string() );
- break;
- case CURSOR_PROGRESS:
- c = KCursor::workingCursor();
- break;
- case CURSOR_MOVE:
- c = KCursor::sizeAllCursor();
- break;
- case CURSOR_E_RESIZE:
- case CURSOR_W_RESIZE:
- c = KCursor::sizeHorCursor();
- break;
- case CURSOR_N_RESIZE:
- case CURSOR_S_RESIZE:
- c = KCursor::sizeVerCursor();
- break;
- case CURSOR_NE_RESIZE:
- case CURSOR_SW_RESIZE:
- c = KCursor::sizeBDiagCursor();
- break;
- case CURSOR_NW_RESIZE:
- case CURSOR_SE_RESIZE:
- c = KCursor::sizeFDiagCursor();
- break;
- case CURSOR_TEXT:
- c = KCursor::ibeamCursor();
- break;
- case CURSOR_WAIT:
- c = KCursor::waitCursor();
- break;
- case CURSOR_HELP:
- c = KCursor::whatsThisCursor();
- break;
- case CURSOR_DEFAULT:
- break;
- }
-
- if ( viewport()->cursor().handle() != c.handle() ) {
- if( c.handle() == KCursor::arrowCursor().handle()) {
- for (KHTMLPart* p = m_part; p; p = p->parentPart())
- p->view()->viewport()->unsetCursor();
- }
- else {
- viewport()->setCursor( c );
- }
- }
-
- if ( ( mailtoCursor || newWindowCursor ) && isVisible() && hasFocus() ) {
-#ifdef Q_WS_X11
- TQPixmap icon_pixmap = TDEGlobal::iconLoader()->loadIcon( mailtoCursor ? "mail_generic" : "window_new", KIcon::Small, 0, KIcon::DefaultState, 0, true );
-
- if (d->cursor_icon_widget) {
- const TQPixmap *pm = d->cursor_icon_widget->backgroundPixmap();
- if (!pm || pm->serialNumber()!=icon_pixmap.serialNumber()) {
- delete d->cursor_icon_widget;
- d->cursor_icon_widget = 0;
- }
- }
-
- if( !d->cursor_icon_widget ) {
- d->cursor_icon_widget = new TQWidget( NULL, NULL, WX11BypassWM );
- XSetWindowAttributes attr;
- attr.save_under = True;
- XChangeWindowAttributes( tqt_xdisplay(), d->cursor_icon_widget->winId(), CWSaveUnder, &attr );
- d->cursor_icon_widget->resize( icon_pixmap.width(), icon_pixmap.height());
- if( icon_pixmap.mask() )
- d->cursor_icon_widget->setMask( *icon_pixmap.mask());
- else
- d->cursor_icon_widget->clearMask();
- d->cursor_icon_widget->setBackgroundPixmap( icon_pixmap );
- d->cursor_icon_widget->erase();
- }
- TQPoint c_pos = TQCursor::pos();
- d->cursor_icon_widget->move( c_pos.x() + 15, c_pos.y() + 15 );
- XRaiseWindow( tqt_xdisplay(), d->cursor_icon_widget->winId());
- TQApplication::flushX();
- d->cursor_icon_widget->show();
-#endif
- }
- else if ( d->cursor_icon_widget )
- d->cursor_icon_widget->hide();
-
- if (r && r->isWidget()) {
- _mouse->ignore();
- }
-
-
- d->prevMouseX = xm;
- d->prevMouseY = ym;
-
- if (!swallowEvent) {
- khtml::MouseMoveEvent event( _mouse, xm, ym, mev.url, mev.target, mev.innerNode );
- TQApplication::sendEvent( m_part, &event );
- }
-}
-
-void KHTMLView::viewportMouseReleaseEvent( TQMouseEvent * _mouse )
-{
- bool swallowEvent = false;
- int xm, ym;
- viewportToContents(_mouse->x(), _mouse->y(), xm, ym);
- DOM::NodeImpl::MouseEvent mev( _mouse->stateAfter(), DOM::NodeImpl::MouseRelease );
-
- if ( m_part->xmlDocImpl() )
- {
- m_part->xmlDocImpl()->prepareMouseEvent( false, xm, ym, &mev );
-
- swallowEvent = dispatchMouseEvent(EventImpl::MOUSEUP_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),true,
- d->clickCount,_mouse,false,DOM::NodeImpl::MouseRelease);
-
- if (d->clickCount > 0 &&
- TQPoint(d->clickX-xm,d->clickY-ym).manhattanLength() <= TQApplication::startDragDistance()) {
- TQMouseEvent me(d->isDoubleClick ? TQEvent::MouseButtonDblClick : TQEvent::MouseButtonRelease,
- _mouse->pos(), _mouse->button(), _mouse->state());
- dispatchMouseEvent(EventImpl::CLICK_EVENT, mev.innerNode.handle(),mev.innerNonSharedNode.handle(),true,
- d->clickCount, &me, true, DOM::NodeImpl::MouseRelease);
- }
-
- DOM::NodeImpl* fn = m_part->xmlDocImpl()->focusNode();
- if (fn && fn != mev.innerNode.handle() &&
- fn->renderer() && fn->renderer()->isWidget() &&
- _mouse->button() != Qt::MidButton) {
- forwardPeripheralEvent(static_cast<khtml::RenderWidget*>(fn->renderer()), _mouse, xm, ym);
- }
-
- khtml::RenderObject* r = mev.innerNode.handle() ? mev.innerNode.handle()->renderer() : 0;
- if (r && r->isWidget())
- _mouse->ignore();
- }
-
- if (!swallowEvent) {
- khtml::MouseReleaseEvent event( _mouse, xm, ym, mev.url, mev.target, mev.innerNode );
- TQApplication::sendEvent( m_part, &event );
- }
-}
-
-// returns true if event should be swallowed
-bool KHTMLView::dispatchKeyEvent( TQKeyEvent *_ke )
-{
- if (!m_part->xmlDocImpl())
- return false;
- // Pressing and releasing a key should generate keydown, keypress and keyup events
- // Holding it down should generated keydown, keypress (repeatedly) and keyup events
- // The problem here is that Qt generates two autorepeat events (keyrelease+keypress)
- // for autorepeating, while DOM wants only one autorepeat event (keypress), so one
- // of the Qt events shouldn't be passed to DOM, but it should be still filtered
- // out if DOM would filter the autorepeat event. Additional problem is that Qt keyrelease
- // events don't have text() set (Qt bug?), so DOM often would ignore the keypress event
- // if it was created using Qt keyrelease, but Qt autorepeat keyrelease comes
- // before Qt autorepeat keypress (i.e. problem whether to filter it out or not).
- // The solution is to filter out and postpone the Qt autorepeat keyrelease until
- // the following Qt keypress event comes. If DOM accepts the DOM keypress event,
- // the postponed event will be simply discarded. If not, it will be passed to keyPressEvent()
- // again, and here it will be ignored.
- //
- // Qt: Press | Release(autorepeat) Press(autorepeat) etc. | Release
- // DOM: Down + Press | (nothing) Press | Up
-
- // It's also possible to get only Releases. E.g. the release of alt-tab,
- // or when the keypresses get captured by an accel.
-
- if( _ke == d->postponed_autorepeat ) // replayed event
- {
- return false;
- }
-
- if( _ke->type() == TQEvent::KeyPress )
- {
- if( !_ke->isAutoRepeat())
- {
- bool ret = dispatchKeyEventHelper( _ke, false ); // keydown
- // don't send keypress even if keydown was blocked, like IE (and unlike Mozilla)
- if( !ret && dispatchKeyEventHelper( _ke, true )) // keypress
- ret = true;
- return ret;
- }
- else // autorepeat
- {
- bool ret = dispatchKeyEventHelper( _ke, true ); // keypress
- if( !ret && d->postponed_autorepeat )
- keyPressEvent( d->postponed_autorepeat );
- delete d->postponed_autorepeat;
- d->postponed_autorepeat = NULL;
- return ret;
- }
- }
- else // TQEvent::KeyRelease
- {
- // Discard postponed "autorepeat key-release" events that didn't see
- // a keypress after them (e.g. due to TQAccel)
- if ( d->postponed_autorepeat ) {
- delete d->postponed_autorepeat;
- d->postponed_autorepeat = 0;
- }
-
- if( !_ke->isAutoRepeat()) {
- return dispatchKeyEventHelper( _ke, false ); // keyup
- }
- else
- {
- d->postponed_autorepeat = new TQKeyEvent( _ke->type(), _ke->key(), _ke->ascii(), _ke->state(),
- _ke->text(), _ke->isAutoRepeat(), _ke->count());
- if( _ke->isAccepted())
- d->postponed_autorepeat->accept();
- else
- d->postponed_autorepeat->ignore();
- return true;
- }
- }
-}
-
-// returns true if event should be swallowed
-bool KHTMLView::dispatchKeyEventHelper( TQKeyEvent *_ke, bool keypress )
-{
- DOM::NodeImpl* keyNode = m_part->xmlDocImpl()->focusNode();
- if (keyNode) {
- return keyNode->dispatchKeyEvent(_ke, keypress);
- } else { // no focused node, send to document
- return m_part->xmlDocImpl()->dispatchKeyEvent(_ke, keypress);
- }
-}
-
-void KHTMLView::keyPressEvent( TQKeyEvent *_ke )
-{
-#ifndef KHTML_NO_TYPE_AHEAD_FIND
- if(d->typeAheadActivated)
- {
- // type-ahead find aka find-as-you-type
- if(_ke->key() == Key_BackSpace)
- {
- d->findString = d->findString.left(d->findString.length() - 1);
-
- if(!d->findString.isEmpty())
- {
- findAhead(false);
- }
- else
- {
- findTimeout();
- }
-
- d->timer.start(3000, true);
- _ke->accept();
- return;
- }
- else if(_ke->key() == Key_Escape)
- {
- findTimeout();
-
- _ke->accept();
- return;
- }
- else if(_ke->key() == Key_Space || !TQString(_ke->text()).stripWhiteSpace().isEmpty())
- {
- d->findString += _ke->text();
-
- findAhead(true);
-
- d->timer.start(3000, true);
- _ke->accept();
- return;
- }
- }
-#endif // KHTML_NO_TYPE_AHEAD_FIND
-
-#ifndef KHTML_NO_CARET
- if (m_part->isEditable() || m_part->isCaretMode()
- || (m_part->xmlDocImpl() && m_part->xmlDocImpl()->focusNode()
- && m_part->xmlDocImpl()->focusNode()->contentEditable())) {
- d->caretViewContext()->keyReleasePending = true;
- caretKeyPressEvent(_ke);
- return;
- }
-#endif // KHTML_NO_CARET
-
- // If CTRL was hit, be prepared for access keys
- if (d->accessKeysEnabled && _ke->key() == Key_Control && _ke->state()==0 && !d->accessKeysActivated)
- {
- d->accessKeysPreActivate=true;
- _ke->accept();
- return;
- }
-
- if (_ke->key() == Key_Shift && _ke->state()==0)
- d->scrollSuspendPreActivate=true;
-
- // accesskey handling needs to be done before dispatching, otherwise e.g. lineedits
- // may eat the event
-
- if (d->accessKeysEnabled && d->accessKeysActivated)
- {
- int state = ( _ke->state() & ( ShiftButton | ControlButton | AltButton | MetaButton ));
- if ( state==0 || state==ShiftButton) {
- if (_ke->key() != Key_Shift) accessKeysTimeout();
- handleAccessKey( _ke );
- _ke->accept();
- return;
- }
- accessKeysTimeout();
- }
-
- if ( dispatchKeyEvent( _ke )) {
- // If either keydown or keypress was accepted by a widget, or canceled by JS, stop here.
- _ke->accept();
- return;
- }
-
- int offs = (clipper()->height() < 30) ? clipper()->height() : 30;
- if (_ke->state() & TQt::ShiftButton)
- switch(_ke->key())
- {
- case Key_Space:
- scrollBy( 0, -clipper()->height() + offs );
- if(d->scrollSuspended)
- d->newScrollTimer(this, 0);
- break;
-
- case Key_Down:
- case Key_J:
- d->adjustScroller(this, KHTMLViewPrivate::ScrollDown, KHTMLViewPrivate::ScrollUp);
- break;
-
- case Key_Up:
- case Key_K:
- d->adjustScroller(this, KHTMLViewPrivate::ScrollUp, KHTMLViewPrivate::ScrollDown);
- break;
-
- case Key_Left:
- case Key_H:
- d->adjustScroller(this, KHTMLViewPrivate::ScrollLeft, KHTMLViewPrivate::ScrollRight);
- break;
-
- case Key_Right:
- case Key_L:
- d->adjustScroller(this, KHTMLViewPrivate::ScrollRight, KHTMLViewPrivate::ScrollLeft);
- break;
- }
- else
- switch ( _ke->key() )
- {
- case Key_Down:
- case Key_J:
- if (!d->scrollTimerId || d->scrollSuspended)
- scrollBy( 0, 10 * _ke->count() );
- if (d->scrollTimerId)
- d->newScrollTimer(this, 0);
- break;
-
- case Key_Space:
- case Key_Next:
- scrollBy( 0, clipper()->height() - offs );
- if(d->scrollSuspended)
- d->newScrollTimer(this, 0);
- break;
-
- case Key_Up:
- case Key_K:
- if (!d->scrollTimerId || d->scrollSuspended)
- scrollBy( 0, -10 * _ke->count());
- if (d->scrollTimerId)
- d->newScrollTimer(this, 0);
- break;
-
- case Key_Prior:
- scrollBy( 0, -clipper()->height() + offs );
- if(d->scrollSuspended)
- d->newScrollTimer(this, 0);
- break;
- case Key_Right:
- case Key_L:
- if (!d->scrollTimerId || d->scrollSuspended)
- scrollBy( 10 * _ke->count(), 0 );
- if (d->scrollTimerId)
- d->newScrollTimer(this, 0);
- break;
- case Key_Left:
- case Key_H:
- if (!d->scrollTimerId || d->scrollSuspended)
- scrollBy( -10 * _ke->count(), 0 );
- if (d->scrollTimerId)
- d->newScrollTimer(this, 0);
- break;
- case Key_Enter:
- case Key_Return:
- // ### FIXME:
- // or even better to HTMLAnchorElementImpl::event()
- if (m_part->xmlDocImpl()) {
- NodeImpl *n = m_part->xmlDocImpl()->focusNode();
- if (n)
- n->setActive();
- }
- break;
- case Key_Home:
- setContentsPos( 0, 0 );
- if(d->scrollSuspended)
- d->newScrollTimer(this, 0);
- break;
- case Key_End:
- setContentsPos( 0, contentsHeight() - visibleHeight() );
- if(d->scrollSuspended)
- d->newScrollTimer(this, 0);
- break;
- case Key_Shift:
- // what are you doing here?
- _ke->ignore();
- return;
- default:
- if (d->scrollTimerId)
- d->newScrollTimer(this, 0);
- _ke->ignore();
- return;
- }
-
- _ke->accept();
-}
-
-void KHTMLView::findTimeout()
-{
-#ifndef KHTML_NO_TYPE_AHEAD_FIND
- d->typeAheadActivated = false;
- d->findString = "";
- m_part->setStatusBarText(i18n("Find stopped."), KHTMLPart::BarDefaultText);
- m_part->enableFindAheadActions( true );
-#endif // KHTML_NO_TYPE_AHEAD_FIND
-}
-
-#ifndef KHTML_NO_TYPE_AHEAD_FIND
-void KHTMLView::startFindAhead( bool linksOnly )
-{
- if( linksOnly )
- {
- d->findLinksOnly = true;
- m_part->setStatusBarText(i18n("Starting -- find links as you type"),
- KHTMLPart::BarDefaultText);
- }
- else
- {
- d->findLinksOnly = false;
- m_part->setStatusBarText(i18n("Starting -- find text as you type"),
- KHTMLPart::BarDefaultText);
- }
-
- m_part->findTextBegin();
- d->typeAheadActivated = true;
- // disable, so that the shortcut ( / or ' by default ) doesn't interfere
- m_part->enableFindAheadActions( false );
- d->timer.start(3000, true);
-}
-
-void KHTMLView::findAhead(bool increase)
-{
- TQString status;
-
- if(d->findLinksOnly)
- {
- m_part->findText(d->findString, KHTMLPart::FindNoPopups |
- KHTMLPart::FindLinksOnly, this);
- if(m_part->findTextNext())
- {
- status = i18n("Link found: \"%1\".");
- }
- else
- {
- if(increase) KNotifyClient::beep();
- status = i18n("Link not found: \"%1\".");
- }
- }
- else
- {
- m_part->findText(d->findString, KHTMLPart::FindNoPopups, this);
- if(m_part->findTextNext())
- {
- status = i18n("Text found: \"%1\".");
- }
- else
- {
- if(increase) KNotifyClient::beep();
- status = i18n("Text not found: \"%1\".");
- }
- }
-
- m_part->setStatusBarText(status.arg(d->findString.lower()),
- KHTMLPart::BarDefaultText);
-}
-
-void KHTMLView::updateFindAheadTimeout()
-{
- if( d->typeAheadActivated )
- d->timer.start( 3000, true );
-}
-
-#endif // KHTML_NO_TYPE_AHEAD_FIND
-
-void KHTMLView::keyReleaseEvent(TQKeyEvent *_ke)
-{
-#ifndef KHTML_NO_TYPE_AHEAD_FIND
- if(d->typeAheadActivated) {
- _ke->accept();
- return;
- }
-#endif
- if (d->m_caretViewContext && d->m_caretViewContext->keyReleasePending) {
- //caretKeyReleaseEvent(_ke);
- d->m_caretViewContext->keyReleasePending = false;
- return;
- }
-
- if( d->scrollSuspendPreActivate && _ke->key() != Key_Shift )
- d->scrollSuspendPreActivate = false;
- if( _ke->key() == Key_Shift && d->scrollSuspendPreActivate && _ke->state() == TQt::ShiftButton
- && !(TDEApplication::keyboardMouseState() & TQt::ShiftButton))
- {
- if (d->scrollTimerId)
- {
- d->scrollSuspended = !d->scrollSuspended;
-#ifndef NO_SMOOTH_SCROLL_HACK
- if( d->scrollSuspended )
- stopScrolling();
-#endif
- }
- }
-
- if (d->accessKeysEnabled)
- {
- if (d->accessKeysPreActivate && _ke->key() != Key_Control)
- d->accessKeysPreActivate=false;
- if (d->accessKeysPreActivate && _ke->state() == TQt::ControlButton && !(TDEApplication::keyboardMouseState() & TQt::ControlButton))
- {
- displayAccessKeys();
- m_part->setStatusBarText(i18n("Access Keys activated"),KHTMLPart::BarOverrideText);
- d->accessKeysActivated = true;
- d->accessKeysPreActivate = false;
- _ke->accept();
- return;
- }
- else if (d->accessKeysActivated)
- {
- accessKeysTimeout();
- _ke->accept();
- return;
- }
- }
-
- // Send keyup event
- if ( dispatchKeyEvent( _ke ) )
- {
- _ke->accept();
- return;
- }
-
- TQScrollView::keyReleaseEvent(_ke);
-}
-
-void KHTMLView::contentsContextMenuEvent ( TQContextMenuEvent * /*ce*/ )
-{
-// ### what kind of c*** is that ?
-#if 0
- if (!m_part->xmlDocImpl()) return;
- int xm = _ce->x();
- int ym = _ce->y();
-
- DOM::NodeImpl::MouseEvent mev( _ce->state(), DOM::NodeImpl::MouseMove ); // ### not a mouse event!
- m_part->xmlDocImpl()->prepareMouseEvent( xm, ym, &mev );
-
- NodeImpl *targetNode = mev.innerNode.handle();
- if (targetNode && targetNode->renderer() && targetNode->renderer()->isWidget()) {
- int absx = 0;
- int absy = 0;
- targetNode->renderer()->absolutePosition(absx,absy);
- TQPoint pos(xm-absx,ym-absy);
-
- TQWidget *w = static_cast<RenderWidget*>(targetNode->renderer())->widget();
- TQContextMenuEvent cme(_ce->reason(),pos,_ce->globalPos(),_ce->state());
- setIgnoreEvents(true);
- TQApplication::sendEvent(w,&cme);
- setIgnoreEvents(false);
- }
-#endif
-}
-
-bool KHTMLView::focusNextPrevChild( bool next )
-{
- // Now try to find the next child
- if (m_part->xmlDocImpl() && focusNextPrevNode(next))
- {
- if (m_part->xmlDocImpl()->focusNode())
- kdDebug() << "focusNode.name: "
- << m_part->xmlDocImpl()->focusNode()->nodeName().string() << endl;
- return true; // focus node found
- }
-
- // If we get here, pass tabbing control up to the next/previous child in our parent
- d->pseudoFocusNode = KHTMLViewPrivate::PFNone;
- if (m_part->parentPart() && m_part->parentPart()->view())
- return m_part->parentPart()->view()->focusNextPrevChild(next);
-
- return TQWidget::focusNextPrevChild(next);
-}
-
-void KHTMLView::doAutoScroll()
-{
- TQPoint pos = TQCursor::pos();
- pos = viewport()->mapFromGlobal( pos );
-
- int xm, ym;
- viewportToContents(pos.x(), pos.y(), xm, ym);
-
- pos = TQPoint(pos.x() - viewport()->x(), pos.y() - viewport()->y());
- if ( (pos.y() < 0) || (pos.y() > visibleHeight()) ||
- (pos.x() < 0) || (pos.x() > visibleWidth()) )
- {
- ensureVisible( xm, ym, 0, 5 );
-
-#ifndef KHTML_NO_SELECTION
- // extend the selection while scrolling
- DOM::Node innerNode;
- if (m_part->isExtendingSelection()) {
- RenderObject::NodeInfo renderInfo(true/*readonly*/, false/*active*/);
- m_part->xmlDocImpl()->renderer()->layer()
- ->nodeAtPoint(renderInfo, xm, ym);
- innerNode = renderInfo.innerNode();
- }/*end if*/
-
- if (innerNode.handle() && innerNode.handle()->renderer()) {
- int absX, absY;
- innerNode.handle()->renderer()->absolutePosition(absX, absY);
-
- m_part->extendSelectionTo(xm, ym, absX, absY, innerNode);
- }/*end if*/
-#endif // KHTML_NO_SELECTION
- }
-}
-
-
-class HackWidget : public TQWidget
-{
- public:
- inline void setNoErase() { setWFlags(getWFlags()|WRepaintNoErase); }
-};
-
-bool KHTMLView::eventFilter(TQObject *o, TQEvent *e)
-{
- if ( e->type() == TQEvent::AccelOverride ) {
- TQKeyEvent* ke = (TQKeyEvent*) e;
-//kdDebug(6200) << "TQEvent::AccelOverride" << endl;
- if (m_part->isEditable() || m_part->isCaretMode()
- || (m_part->xmlDocImpl() && m_part->xmlDocImpl()->focusNode()
- && m_part->xmlDocImpl()->focusNode()->contentEditable())) {
-//kdDebug(6200) << "editable/navigable" << endl;
- if ( (ke->state() & ControlButton) || (ke->state() & ShiftButton) ) {
- switch ( ke->key() ) {
- case Key_Left:
- case Key_Right:
- case Key_Up:
- case Key_Down:
- case Key_Home:
- case Key_End:
- ke->accept();
-//kdDebug(6200) << "eaten" << endl;
- return true;
- default:
- break;
- }
- }
- }
- }
-
- if ( e->type() == TQEvent::Leave ) {
- if ( d->cursor_icon_widget )
- d->cursor_icon_widget->hide();
- m_part->resetHoverText();
- }
-
- TQWidget *view = viewport();
-
- if (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(view)) {
- // we need to install an event filter on all children of the viewport to
- // be able to get correct stacking of children within the document.
- if(e->type() == TQEvent::ChildInserted) {
- TQObject *c = TQT_TQOBJECT(TQT_TQCHILDEVENT(e)->child());
- if (c->isWidgetType()) {
- TQWidget *w = TQT_TQWIDGET(c);
- // don't install the event filter on toplevels
- if (w->parentWidget(true) == view) {
- if (!strcmp(w->name(), "__khtml")) {
- w->installEventFilter(this);
- w->unsetCursor();
- if (!::tqqt_cast<TQFrame*>(w))
- w->setBackgroundMode( TQWidget::NoBackground );
- static_cast<HackWidget *>(w)->setNoErase();
- if (!w->childrenListObject().isEmpty()) {
- TQObjectListIterator it(w->childrenListObject());
- for (; it.current(); ++it) {
- TQWidget *widget = ::tqqt_cast<TQWidget *>(it.current());
- if (widget && !widget->isTopLevel()) {
- if (!::tqqt_cast<TQFrame*>(w))
- widget->setBackgroundMode( TQWidget::NoBackground );
- static_cast<HackWidget *>(widget)->setNoErase();
- widget->installEventFilter(this);
- }
- }
- }
- }
- }
- }
- }
- } else if (o->isWidgetType()) {
- TQWidget *v = TQT_TQWIDGET(o);
- TQWidget *c = v;
- while (v && v != view) {
- c = v;
- v = v->parentWidget(true);
- }
-
- if (v && !strcmp(c->name(), "__khtml")) {
- bool block = false;
- TQWidget *w = TQT_TQWIDGET(o);
- switch(e->type()) {
- case TQEvent::Paint:
- if (!allowWidgetPaintEvents) {
- // eat the event. Like this we can control exactly when the widget
- // get's repainted.
- block = true;
- int x = 0, y = 0;
- TQWidget *v = w;
- while (v && v != view) {
- x += v->x();
- y += v->y();
- v = v->parentWidget();
- }
- viewportToContents( x, y, x, y );
- TQPaintEvent *pe = TQT_TQPAINTEVENT(e);
- bool asap = !d->contentsMoving && ::tqqt_cast<TQScrollView *>(c);
-
- // TQScrollView needs fast repaints
- if ( asap && !d->painting && m_part->xmlDocImpl() && m_part->xmlDocImpl()->renderer() &&
- !static_cast<khtml::RenderCanvas *>(m_part->xmlDocImpl()->renderer())->needsLayout() ) {
- repaintContents(x + pe->rect().x(), y + pe->rect().y(),
- pe->rect().width(), pe->rect().height(), true);
- } else {
- scheduleRepaint(x + pe->rect().x(), y + pe->rect().y(),
- pe->rect().width(), pe->rect().height(), asap);
- }
- }
- break;
- case TQEvent::MouseMove:
- case TQEvent::MouseButtonPress:
- case TQEvent::MouseButtonRelease:
- case TQEvent::MouseButtonDblClick: {
- if ( (w->parentWidget() == view || ::tqqt_cast<TQScrollView*>(c)) && !::tqqt_cast<TQScrollBar *>(w)) {
- TQMouseEvent *me = TQT_TQMOUSEEVENT(e);
- TQPoint pt = w->mapTo( view, me->pos());
- TQMouseEvent me2(me->type(), pt, me->button(), me->state());
-
- if (e->type() == TQEvent::MouseMove)
- viewportMouseMoveEvent(&me2);
- else if(e->type() == TQEvent::MouseButtonPress)
- viewportMousePressEvent(&me2);
- else if(e->type() == TQEvent::MouseButtonRelease)
- viewportMouseReleaseEvent(&me2);
- else
- viewportMouseDoubleClickEvent(&me2);
- block = true;
- }
- break;
- }
- case TQEvent::KeyPress:
- case TQEvent::KeyRelease:
- if (w->parentWidget() == view && !::tqqt_cast<TQScrollBar *>(w)) {
- TQKeyEvent *ke = TQT_TQKEYEVENT(e);
- if (e->type() == TQEvent::KeyPress)
- keyPressEvent(ke);
- else
- keyReleaseEvent(ke);
- block = true;
- }
- default:
- break;
- }
- if (block) {
- //tqDebug("eating event");
- return true;
- }
- }
- }
-
-// kdDebug(6000) <<"passing event on to sv event filter object=" << o->className() << " event=" << e->type() << endl;
- return TQScrollView::eventFilter(o, e);
-}
-
-
-DOM::NodeImpl *KHTMLView::nodeUnderMouse() const
-{
- return d->underMouse;
-}
-
-DOM::NodeImpl *KHTMLView::nonSharedNodeUnderMouse() const
-{
- return d->underMouseNonShared;
-}
-
-bool KHTMLView::scrollTo(const TQRect &bounds)
-{
- d->scrollingSelf = true; // so scroll events get ignored
-
- int x, y, xe, ye;
- x = bounds.left();
- y = bounds.top();
- xe = bounds.right();
- ye = bounds.bottom();
-
- //kdDebug(6000)<<"scrolling coords: x="<<x<<" y="<<y<<" width="<<xe-x<<" height="<<ye-y<<endl;
-
- int deltax;
- int deltay;
-
- int curHeight = visibleHeight();
- int curWidth = visibleWidth();
-
- if (ye-y>curHeight-d->borderY)
- ye = y + curHeight - d->borderY;
-
- if (xe-x>curWidth-d->borderX)
- xe = x + curWidth - d->borderX;
-
- // is xpos of target left of the view's border?
- if (x < contentsX() + d->borderX )
- deltax = x - contentsX() - d->borderX;
- // is xpos of target right of the view's right border?
- else if (xe + d->borderX > contentsX() + curWidth)
- deltax = xe + d->borderX - ( contentsX() + curWidth );
- else
- deltax = 0;
-
- // is ypos of target above upper border?
- if (y < contentsY() + d->borderY)
- deltay = y - contentsY() - d->borderY;
- // is ypos of target below lower border?
- else if (ye + d->borderY > contentsY() + curHeight)
- deltay = ye + d->borderY - ( contentsY() + curHeight );
- else
- deltay = 0;
-
- int maxx = curWidth-d->borderX;
- int maxy = curHeight-d->borderY;
-
- int scrollX,scrollY;
-
- scrollX = deltax > 0 ? (deltax > maxx ? maxx : deltax) : deltax == 0 ? 0 : (deltax>-maxx ? deltax : -maxx);
- scrollY = deltay > 0 ? (deltay > maxy ? maxy : deltay) : deltay == 0 ? 0 : (deltay>-maxy ? deltay : -maxy);
-
- if (contentsX() + scrollX < 0)
- scrollX = -contentsX();
- else if (contentsWidth() - visibleWidth() - contentsX() < scrollX)
- scrollX = contentsWidth() - visibleWidth() - contentsX();
-
- if (contentsY() + scrollY < 0)
- scrollY = -contentsY();
- else if (contentsHeight() - visibleHeight() - contentsY() < scrollY)
- scrollY = contentsHeight() - visibleHeight() - contentsY();
-
- scrollBy(scrollX, scrollY);
-
- d->scrollingSelf = false;
-
- if ( (abs(deltax)<=maxx) && (abs(deltay)<=maxy) )
- return true;
- else return false;
-
-}
-
-bool KHTMLView::focusNextPrevNode(bool next)
-{
- // Sets the focus node of the document to be the node after (or if
- // next is false, before) the current focus node. Only nodes that
- // are selectable (i.e. for which isFocusable() returns true) are
- // taken into account, and the order used is that specified in the
- // HTML spec (see DocumentImpl::nextFocusNode() and
- // DocumentImpl::previousFocusNode() for details).
-
- DocumentImpl *doc = m_part->xmlDocImpl();
- NodeImpl *oldFocusNode = doc->focusNode();
-
- // See whether we're in the middle of detach. If so, we want to
- // clear focus... The document code will be careful to not
- // emit events in that case..
- if (oldFocusNode && oldFocusNode->renderer() &&
- !oldFocusNode->renderer()->parent()) {
- doc->setFocusNode(0);
- return true;
- }
-
-#if 1
- // If the user has scrolled the document, then instead of picking
- // the next focusable node in the document, use the first one that
- // is within the visible area (if possible).
- if (d->scrollBarMoved)
- {
- NodeImpl *toFocus;
- if (next)
- toFocus = doc->nextFocusNode(oldFocusNode);
- else
- toFocus = doc->previousFocusNode(oldFocusNode);
-
- if (!toFocus && oldFocusNode)
- if (next)
- toFocus = doc->nextFocusNode(NULL);
- else
- toFocus = doc->previousFocusNode(NULL);
-
- while (toFocus && toFocus != oldFocusNode)
- {
-
- TQRect focusNodeRect = toFocus->getRect();
- if ((focusNodeRect.left() > contentsX()) && (focusNodeRect.right() < contentsX() + visibleWidth()) &&
- (focusNodeRect.top() > contentsY()) && (focusNodeRect.bottom() < contentsY() + visibleHeight())) {
- {
- TQRect r = toFocus->getRect();
- ensureVisible( r.right(), r.bottom());
- ensureVisible( r.left(), r.top());
- d->scrollBarMoved = false;
- d->tabMovePending = false;
- d->lastTabbingDirection = next;
- d->pseudoFocusNode = KHTMLViewPrivate::PFNone;
- m_part->xmlDocImpl()->setFocusNode(toFocus);
- Node guard(toFocus);
- if (!toFocus->hasOneRef() )
- {
- emit m_part->nodeActivated(Node(toFocus));
- }
- return true;
- }
- }
- if (next)
- toFocus = doc->nextFocusNode(toFocus);
- else
- toFocus = doc->previousFocusNode(toFocus);
-
- if (!toFocus && oldFocusNode)
- if (next)
- toFocus = doc->nextFocusNode(NULL);
- else
- toFocus = doc->previousFocusNode(NULL);
- }
-
- d->scrollBarMoved = false;
- }
-#endif
-
- if (!oldFocusNode && d->pseudoFocusNode == KHTMLViewPrivate::PFNone)
- {
- ensureVisible(contentsX(), next?0:contentsHeight());
- d->scrollBarMoved = false;
- d->pseudoFocusNode = next?KHTMLViewPrivate::PFTop:KHTMLViewPrivate::PFBottom;
- return true;
- }
-
- NodeImpl *newFocusNode = NULL;
-
- if (d->tabMovePending && next != d->lastTabbingDirection)
- {
- //kdDebug ( 6000 ) << " tab move pending and tabbing direction changed!\n";
- newFocusNode = oldFocusNode;
- }
- else if (next)
- {
- if (oldFocusNode || d->pseudoFocusNode == KHTMLViewPrivate::PFTop )
- newFocusNode = doc->nextFocusNode(oldFocusNode);
- }
- else
- {
- if (oldFocusNode || d->pseudoFocusNode == KHTMLViewPrivate::PFBottom )
- newFocusNode = doc->previousFocusNode(oldFocusNode);
- }
-
- bool targetVisible = false;
- if (!newFocusNode)
- {
- if ( next )
- {
- targetVisible = scrollTo(TQRect(contentsX()+visibleWidth()/2,contentsHeight()-d->borderY,0,0));
- }
- else
- {
- targetVisible = scrollTo(TQRect(contentsX()+visibleWidth()/2,d->borderY,0,0));
- }
- }
- else
- {
-#ifndef KHTML_NO_CARET
- // if it's an editable element, activate the caret
- if (!m_part->isCaretMode() && !m_part->isEditable()
- && newFocusNode->contentEditable()) {
- d->caretViewContext();
- moveCaretTo(newFocusNode, 0L, true);
- } else {
- caretOff();
- }
-#endif // KHTML_NO_CARET
-
- targetVisible = scrollTo(newFocusNode->getRect());
- }
-
- if (targetVisible)
- {
- //kdDebug ( 6000 ) << " target reached.\n";
- d->tabMovePending = false;
-
- m_part->xmlDocImpl()->setFocusNode(newFocusNode);
- if (newFocusNode)
- {
- Node guard(newFocusNode);
- if (!newFocusNode->hasOneRef() )
- {
- emit m_part->nodeActivated(Node(newFocusNode));
- }
- return true;
- }
- else
- {
- d->pseudoFocusNode = next?KHTMLViewPrivate::PFBottom:KHTMLViewPrivate::PFTop;
- return false;
- }
- }
- else
- {
- if (!d->tabMovePending)
- d->lastTabbingDirection = next;
- d->tabMovePending = true;
- return true;
- }
-}
-
-void KHTMLView::displayAccessKeys()
-{
- TQValueVector< TQChar > taken;
- displayAccessKeys( NULL, this, taken, false );
- displayAccessKeys( NULL, this, taken, true );
-}
-
-void KHTMLView::displayAccessKeys( KHTMLView* caller, KHTMLView* origview, TQValueVector< TQChar >& taken, bool use_fallbacks )
-{
- TQMap< ElementImpl*, TQChar > fallbacks;
- if( use_fallbacks )
- fallbacks = buildFallbackAccessKeys();
- for( NodeImpl* n = m_part->xmlDocImpl(); n != NULL; n = n->traverseNextNode()) {
- if( n->isElementNode()) {
- ElementImpl* en = static_cast< ElementImpl* >( n );
- DOMString s = en->getAttribute( ATTR_ACCESSKEY );
- TQString accesskey;
- if( s.length() == 1 ) {
- TQChar a = s.string()[ 0 ].upper();
- if( tqFind( taken.begin(), taken.end(), a ) == taken.end()) // !contains
- accesskey = a;
- }
- if( accesskey.isNull() && fallbacks.contains( en )) {
- TQChar a = fallbacks[ en ].upper();
- if( tqFind( taken.begin(), taken.end(), a ) == taken.end()) // !contains
- accesskey = TQString( "<qt><i>" ) + a + "</i></qt>";
- }
- if( !accesskey.isNull()) {
- TQRect rec=en->getRect();
- TQLabel *lab=new TQLabel(accesskey,viewport(),0,(WFlags)WDestructiveClose);
- connect( origview, TQT_SIGNAL(hideAccessKeys()), lab, TQT_SLOT(close()) );
- connect( this, TQT_SIGNAL(repaintAccessKeys()), lab, TQT_SLOT(repaint()));
- lab->setPalette(TQToolTip::palette());
- lab->setLineWidth(2);
- lab->setFrameStyle(TQFrame::Box | TQFrame::Plain);
- lab->setMargin(3);
- lab->adjustSize();
- addChild(lab,
- KMIN(rec.left()+rec.width()/2, contentsWidth() - lab->width()),
- KMIN(rec.top()+rec.height()/2, contentsHeight() - lab->height()));
- showChild(lab);
- taken.append( accesskey[ 0 ] );
- }
- }
- }
- if( use_fallbacks )
- return;
- TQPtrList<KParts::ReadOnlyPart> frames = m_part->frames();
- for( TQPtrListIterator<KParts::ReadOnlyPart> it( frames );
- it != NULL;
- ++it ) {
- if( !(*it)->inherits( "KHTMLPart" ))
- continue;
- KHTMLPart* part = static_cast< KHTMLPart* >( *it );
- if( part->view() && part->view() != caller )
- part->view()->displayAccessKeys( this, origview, taken, use_fallbacks );
- }
- // pass up to the parent
- if (m_part->parentPart() && m_part->parentPart()->view()
- && m_part->parentPart()->view() != caller)
- m_part->parentPart()->view()->displayAccessKeys( this, origview, taken, use_fallbacks );
-}
-
-
-
-void KHTMLView::accessKeysTimeout()
-{
-d->accessKeysActivated=false;
-d->accessKeysPreActivate = false;
-m_part->setStatusBarText(TQString::null, KHTMLPart::BarOverrideText);
-emit hideAccessKeys();
-}
-
-// Handling of the HTML accesskey attribute.
-bool KHTMLView::handleAccessKey( const TQKeyEvent* ev )
-{
-// Qt interprets the keyevent also with the modifiers, and ev->text() matches that,
-// but this code must act as if the modifiers weren't pressed
- TQChar c;
- if( ev->key() >= Key_A && ev->key() <= Key_Z )
- c = 'A' + ev->key() - Key_A;
- else if( ev->key() >= Key_0 && ev->key() <= Key_9 )
- c = '0' + ev->key() - Key_0;
- else {
- // TODO fake XKeyEvent and XLookupString ?
- // This below seems to work e.g. for eacute though.
- if( ev->text().length() == 1 )
- c = ev->text()[ 0 ];
- }
- if( c.isNull())
- return false;
- return focusNodeWithAccessKey( c );
-}
-
-bool KHTMLView::focusNodeWithAccessKey( TQChar c, KHTMLView* caller )
-{
- DocumentImpl *doc = m_part->xmlDocImpl();
- if( !doc )
- return false;
- ElementImpl* node = doc->findAccessKeyElement( c );
- if( !node ) {
- TQPtrList<KParts::ReadOnlyPart> frames = m_part->frames();
- for( TQPtrListIterator<KParts::ReadOnlyPart> it( frames );
- it != NULL;
- ++it ) {
- if( !(*it)->inherits( "KHTMLPart" ))
- continue;
- KHTMLPart* part = static_cast< KHTMLPart* >( *it );
- if( part->view() && part->view() != caller
- && part->view()->focusNodeWithAccessKey( c, this ))
- return true;
- }
- // pass up to the parent
- if (m_part->parentPart() && m_part->parentPart()->view()
- && m_part->parentPart()->view() != caller
- && m_part->parentPart()->view()->focusNodeWithAccessKey( c, this ))
- return true;
- if( caller == NULL ) { // the active frame (where the accesskey was pressed)
- TQMap< ElementImpl*, TQChar > fallbacks = buildFallbackAccessKeys();
- for( TQMap< ElementImpl*, TQChar >::ConstIterator it = fallbacks.begin();
- it != fallbacks.end();
- ++it )
- if( *it == c ) {
- node = it.key();
- break;
- }
- }
- if( node == NULL )
- return false;
- }
-
- // Scroll the view as necessary to ensure that the new focus node is visible
-#ifndef KHTML_NO_CARET
- // if it's an editable element, activate the caret
- if (!m_part->isCaretMode() && !m_part->isEditable()
- && node->contentEditable()) {
- d->caretViewContext();
- moveCaretTo(node, 0L, true);
- } else {
- caretOff();
- }
-#endif // KHTML_NO_CARET
-
- TQRect r = node->getRect();
- ensureVisible( r.right(), r.bottom());
- ensureVisible( r.left(), r.top());
-
- Node guard( node );
- if( node->isFocusable()) {
- if (node->id()==ID_LABEL) {
- // if Accesskey is a label, give focus to the label's referrer.
- node=static_cast<ElementImpl *>(static_cast< HTMLLabelElementImpl* >( node )->getFormElement());
- if (!node) return true;
- guard = node;
- }
- // Set focus node on the document
-#ifdef USE_QT4
- m_part->xmlDocImpl()->setFocusNode(node);
-#else // USE_QT4
- TQFocusEvent::setReason( TQFocusEvent::Shortcut );
- m_part->xmlDocImpl()->setFocusNode(node);
- TQFocusEvent::resetReason();
-#endif // USE_QT4
- if( node != NULL && node->hasOneRef()) // deleted, only held by guard
- return true;
- emit m_part->nodeActivated(Node(node));
- if( node != NULL && node->hasOneRef())
- return true;
- }
-
- switch( node->id()) {
- case ID_A:
- static_cast< HTMLAnchorElementImpl* >( node )->click();
- break;
- case ID_INPUT:
- static_cast< HTMLInputElementImpl* >( node )->click();
- break;
- case ID_BUTTON:
- static_cast< HTMLButtonElementImpl* >( node )->click();
- break;
- case ID_AREA:
- static_cast< HTMLAreaElementImpl* >( node )->click();
- break;
- case ID_TEXTAREA:
- break; // just focusing it is enough
- case ID_LEGEND:
- // TODO
- break;
- }
- return true;
-}
-
-static TQString getElementText( NodeImpl* start, bool after )
-{
- TQString ret; // nextSibling(), to go after e.g. </select>
- for( NodeImpl* n = after ? start->nextSibling() : start->traversePreviousNode();
- n != NULL;
- n = after ? n->traverseNextNode() : n->traversePreviousNode()) {
- if( n->isTextNode()) {
- if( after )
- ret += static_cast< TextImpl* >( n )->toString().string();
- else
- ret.prepend( static_cast< TextImpl* >( n )->toString().string());
- } else {
- switch( n->id()) {
- case ID_A:
- case ID_FONT:
- case ID_TT:
- case ID_U:
- case ID_B:
- case ID_I:
- case ID_S:
- case ID_STRIKE:
- case ID_BIG:
- case ID_SMALL:
- case ID_EM:
- case ID_STRONG:
- case ID_DFN:
- case ID_CODE:
- case ID_SAMP:
- case ID_KBD:
- case ID_VAR:
- case ID_CITE:
- case ID_ABBR:
- case ID_ACRONYM:
- case ID_SUB:
- case ID_SUP:
- case ID_SPAN:
- case ID_NOBR:
- case ID_WBR:
- break;
- case ID_TD:
- if( ret.stripWhiteSpace().isEmpty())
- break;
- // fall through
- default:
- return ret.simplifyWhiteSpace();
- }
- }
- }
- return ret.simplifyWhiteSpace();
-}
-
-static TQMap< NodeImpl*, TQString > buildLabels( NodeImpl* start )
-{
- TQMap< NodeImpl*, TQString > ret;
- for( NodeImpl* n = start;
- n != NULL;
- n = n->traverseNextNode()) {
- if( n->id() == ID_LABEL ) {
- HTMLLabelElementImpl* label = static_cast< HTMLLabelElementImpl* >( n );
- NodeImpl* labelfor = label->getFormElement();
- if( labelfor )
- ret[ labelfor ] = label->innerText().string().simplifyWhiteSpace();
- }
- }
- return ret;
-}
-
-namespace khtml {
-struct AccessKeyData {
- ElementImpl* element;
- TQString text;
- TQString url;
- int priority; // 10(highest) - 0(lowest)
-};
-}
-
-TQMap< ElementImpl*, TQChar > KHTMLView::buildFallbackAccessKeys() const
-{
- // build a list of all possible candidate elements that could use an accesskey
- TQValueList< AccessKeyData > data;
- TQMap< NodeImpl*, TQString > labels = buildLabels( m_part->xmlDocImpl());
- for( NodeImpl* n = m_part->xmlDocImpl();
- n != NULL;
- n = n->traverseNextNode()) {
- if( n->isElementNode()) {
- ElementImpl* element = static_cast< ElementImpl* >( n );
- if( element->getAttribute( ATTR_ACCESSKEY ).length() == 1 )
- continue; // has accesskey set, ignore
- if( element->renderer() == NULL )
- continue; // not visible
- TQString text;
- TQString url;
- int priority = 0;
- bool ignore = false;
- bool text_after = false;
- bool text_before = false;
- switch( element->id()) {
- case ID_A:
- url = khtml::parseURL(element->getAttribute(ATTR_HREF)).string();
- if( url.isEmpty()) // doesn't have href, it's only an anchor
- continue;
- text = static_cast< HTMLElementImpl* >( element )->innerText().string().simplifyWhiteSpace();
- priority = 2;
- break;
- case ID_INPUT: {
- HTMLInputElementImpl* in = static_cast< HTMLInputElementImpl* >( element );
- switch( in->inputType()) {
- case HTMLInputElementImpl::SUBMIT:
- text = in->value().string();
- if( text.isEmpty())
- text = i18n( "Submit" );
- priority = 7;
- break;
- case HTMLInputElementImpl::IMAGE:
- text = in->altText().string();
- priority = 7;
- break;
- case HTMLInputElementImpl::BUTTON:
- text = in->value().string();
- priority = 5;
- break;
- case HTMLInputElementImpl::RESET:
- text = in->value().string();
- if( text.isEmpty())
- text = i18n( "Reset" );
- priority = 5;
- break;
- case HTMLInputElementImpl::HIDDEN:
- ignore = true;
- break;
- case HTMLInputElementImpl::CHECKBOX:
- case HTMLInputElementImpl::RADIO:
- text_after = true;
- priority = 5;
- break;
- case HTMLInputElementImpl::TEXT:
- case HTMLInputElementImpl::PASSWORD:
- case HTMLInputElementImpl::FILE:
- text_before = true;
- priority = 5;
- break;
- default:
- priority = 5;
- break;
- }
- break;
- }
- case ID_BUTTON:
- text = static_cast< HTMLElementImpl* >( element )->innerText().string().simplifyWhiteSpace();
- switch( static_cast< HTMLButtonElementImpl* >( element )->buttonType()) {
- case HTMLButtonElementImpl::SUBMIT:
- if( text.isEmpty())
- text = i18n( "Submit" );
- priority = 7;
- break;
- case HTMLButtonElementImpl::RESET:
- if( text.isEmpty())
- text = i18n( "Reset" );
- priority = 5;
- break;
- default:
- priority = 5;
- break;
- break;
- }
- case ID_SELECT: // these don't have accesskey attribute, but quick access may be handy
- text_before = true;
- text_after = true;
- priority = 5;
- break;
- case ID_FRAME:
- ignore = true;
- break;
- default:
- ignore = !element->isFocusable();
- priority = 2;
- break;
- }
- if( ignore )
- continue;
- if( text.isNull() && labels.contains( element ))
- text = labels[ element ];
- if( text.isNull() && text_before )
- text = getElementText( element, false );
- if( text.isNull() && text_after )
- text = getElementText( element, true );
- text = text.stripWhiteSpace();
- // increase priority of items which have explicitly specified accesskeys in the config
- TQValueList< TQPair< TQString, TQChar > > priorities
- = m_part->settings()->fallbackAccessKeysAssignments();
- for( TQValueList< TQPair< TQString, TQChar > >::ConstIterator it = priorities.begin();
- it != priorities.end();
- ++it ) {
- if( text == (*it).first )
- priority = 10;
- }
- AccessKeyData tmp = { element, text, url, priority };
- data.append( tmp );
- }
- }
-
- TQValueList< TQChar > keys;
- for( char c = 'A'; c <= 'Z'; ++c )
- keys << c;
- for( char c = '0'; c <= '9'; ++c )
- keys << c;
- for( NodeImpl* n = m_part->xmlDocImpl();
- n != NULL;
- n = n->traverseNextNode()) {
- if( n->isElementNode()) {
- ElementImpl* en = static_cast< ElementImpl* >( n );
- DOMString s = en->getAttribute( ATTR_ACCESSKEY );
- if( s.length() == 1 ) {
- TQChar c = s.string()[ 0 ].upper();
- keys.remove( c ); // remove manually assigned accesskeys
- }
- }
- }
-
- TQMap< ElementImpl*, TQChar > ret;
- for( int priority = 10;
- priority >= 0;
- --priority ) {
- for( TQValueList< AccessKeyData >::Iterator it = data.begin();
- it != data.end();
- ) {
- if( (*it).priority != priority ) {
- ++it;
- continue;
- }
- if( keys.isEmpty())
- break;
- TQString text = (*it).text;
- TQChar key;
- if( key.isNull() && !text.isEmpty()) {
- TQValueList< TQPair< TQString, TQChar > > priorities
- = m_part->settings()->fallbackAccessKeysAssignments();
- for( TQValueList< TQPair< TQString, TQChar > >::ConstIterator it = priorities.begin();
- it != priorities.end();
- ++it )
- if( text == (*it).first && keys.contains( (*it).second )) {
- key = (*it).second;
- break;
- }
- }
- // try first to select the first character as the accesskey,
- // then first character of the following words,
- // and then simply the first free character
- if( key.isNull() && !text.isEmpty()) {
- TQStringList words = TQStringList::split( ' ', text );
- for( TQStringList::ConstIterator it = words.begin();
- it != words.end();
- ++it ) {
- if( keys.contains( (*it)[ 0 ].upper())) {
- key = (*it)[ 0 ].upper();
- break;
- }
- }
- }
- if( key.isNull() && !text.isEmpty()) {
- for( unsigned int i = 0;
- i < text.length();
- ++i ) {
- if( keys.contains( text[ i ].upper())) {
- key = text[ i ].upper();
- break;
- }
- }
- }
- if( key.isNull())
- key = keys.front();
- ret[ (*it).element ] = key;
- keys.remove( key );
- TQString url = (*it).url;
- it = data.remove( it );
- // assign the same accesskey also to other elements pointing to the same url
- if( !url.isEmpty() && !url.startsWith( "javascript:", false )) {
- for( TQValueList< AccessKeyData >::Iterator it2 = data.begin();
- it2 != data.end();
- ) {
- if( (*it2).url == url ) {
- ret[ (*it2).element ] = key;
- if( it == it2 )
- ++it;
- it2 = data.remove( it2 );
- } else
- ++it2;
- }
- }
- }
- }
- return ret;
-}
-
-void KHTMLView::setMediaType( const TQString &medium )
-{
- m_medium = medium;
-}
-
-TQString KHTMLView::mediaType() const
-{
- return m_medium;
-}
-
-bool KHTMLView::pagedMode() const
-{
- return d->paged;
-}
-
-void KHTMLView::setWidgetVisible(RenderWidget* w, bool vis)
-{
- if (vis) {
- d->visibleWidgets.replace(w, w->widget());
- }
- else
- d->visibleWidgets.remove(w);
-}
-
-bool KHTMLView::needsFullRepaint() const
-{
- return d->needsFullRepaint;
-}
-
-void KHTMLView::print()
-{
- print( false );
-}
-
-void KHTMLView::print(bool quick)
-{
- if(!m_part->xmlDocImpl()) return;
- khtml::RenderCanvas *root = static_cast<khtml::RenderCanvas *>(m_part->xmlDocImpl()->renderer());
- if(!root) return;
-
- KPrinter *printer = new KPrinter(true, TQPrinter::ScreenResolution);
- printer->addDialogPage(new KHTMLPrintSettings());
- TQString docname = m_part->xmlDocImpl()->URL().prettyURL();
- if ( !docname.isEmpty() )
- docname = KStringHandler::csqueeze(docname, 80);
- if(quick || printer->setup(this, i18n("Print %1").arg(docname))) {
- viewport()->setCursor( tqwaitCursor ); // only viewport(), no TQApplication::, otherwise we get the busy cursor in tdeprint's dialogs
- // set up KPrinter
- printer->setFullPage(false);
- printer->setCreator(TQString("KDE %1.%2.%3 HTML Library").arg(TDE_VERSION_MAJOR).arg(TDE_VERSION_MINOR).arg(TDE_VERSION_RELEASE));
- printer->setDocName(docname);
-
- TQPainter *p = new TQPainter;
- p->begin( printer );
- khtml::setPrintPainter( p );
-
- m_part->xmlDocImpl()->setPaintDevice( printer );
- TQString oldMediaType = mediaType();
- setMediaType( "print" );
- // We ignore margin settings for html and body when printing
- // and use the default margins from the print-system
- // (In Qt 3.0.x the default margins are hardcoded in Qt)
- m_part->xmlDocImpl()->setPrintStyleSheet( printer->option("app-khtml-printfriendly") == "true" ?
- "* { background-image: none !important;"
- " background-color: white !important;"
- " color: black !important; }"
- "body { margin: 0px !important; }"
- "html { margin: 0px !important; }" :
- "body { margin: 0px !important; }"
- "html { margin: 0px !important; }"
- );
-
- TQPaintDeviceMetrics metrics( printer );
-
- kdDebug(6000) << "printing: physical page width = " << metrics.width()
- << " height = " << metrics.height() << endl;
- root->setStaticMode(true);
- root->setPagedMode(true);
- root->setWidth(metrics.width());
-// root->setHeight(metrics.height());
- root->setPageTop(0);
- root->setPageBottom(0);
- d->paged = true;
-
- m_part->xmlDocImpl()->styleSelector()->computeFontSizes(&metrics, 100);
- m_part->xmlDocImpl()->updateStyleSelector();
- root->setPrintImages( printer->option("app-khtml-printimages") == "true");
- root->makePageBreakAvoidBlocks();
-
- root->setNeedsLayoutAndMinMaxRecalc();
- root->layout();
- khtml::RenderWidget::flushWidgetResizes(); // make sure widgets have their final size
-
- // check sizes ask for action.. (scale or clip)
-
- bool printHeader = (printer->option("app-khtml-printheader") == "true");
-
- int headerHeight = 0;
- TQFont headerFont("Sans Serif", 8);
-
- TQString headerLeft = TDEGlobal::locale()->formatDate(TQDate::currentDate(),true);
- TQString headerMid = docname;
- TQString headerRight;
-
- if (printHeader)
- {
- p->setFont(headerFont);
- headerHeight = (p->fontMetrics().lineSpacing() * 3) / 2;
- }
-
- // ok. now print the pages.
- kdDebug(6000) << "printing: html page width = " << root->docWidth()
- << " height = " << root->docHeight() << endl;
- kdDebug(6000) << "printing: margins left = " << printer->margins().width()
- << " top = " << printer->margins().height() << endl;
- kdDebug(6000) << "printing: paper width = " << metrics.width()
- << " height = " << metrics.height() << endl;
- // if the width is too large to fit on the paper we just scale
- // the whole thing.
- int pageWidth = metrics.width();
- int pageHeight = metrics.height();
- p->setClipRect(0,0, pageWidth, pageHeight);
-
- pageHeight -= headerHeight;
-
- bool scalePage = false;
- double scale = 0.0;
-#ifndef QT_NO_TRANSFORMATIONS
- if(root->docWidth() > metrics.width()) {
- scalePage = true;
- scale = ((double) metrics.width())/((double) root->docWidth());
- pageHeight = (int) (pageHeight/scale);
- pageWidth = (int) (pageWidth/scale);
- headerHeight = (int) (headerHeight/scale);
- }
-#endif
- kdDebug(6000) << "printing: scaled html width = " << pageWidth
- << " height = " << pageHeight << endl;
-
- root->setHeight(pageHeight);
- root->setPageBottom(pageHeight);
- root->setNeedsLayout(true);
- root->layoutIfNeeded();
-// m_part->slotDebugRenderTree();
-
- // Squeeze header to make it it on the page.
- if (printHeader)
- {
- int available_width = metrics.width() - 10 -
- 2 * kMax(p->boundingRect(0, 0, metrics.width(), p->fontMetrics().lineSpacing(), Qt::AlignLeft, headerLeft).width(),
- p->boundingRect(0, 0, metrics.width(), p->fontMetrics().lineSpacing(), Qt::AlignLeft, headerRight).width());
- if (available_width < 150)
- available_width = 150;
- int mid_width;
- int squeeze = 120;
- do {
- headerMid = KStringHandler::csqueeze(docname, squeeze);
- mid_width = p->boundingRect(0, 0, metrics.width(), p->fontMetrics().lineSpacing(), Qt::AlignLeft, headerMid).width();
- squeeze -= 10;
- } while (mid_width > available_width);
- }
-
- int top = 0;
- int bottom = 0;
- int page = 1;
- while(top < root->docHeight()) {
- if(top > 0) printer->newPage();
- p->setClipRect(0, 0, pageWidth, headerHeight, TQPainter::CoordDevice);
- if (printHeader)
- {
- int dy = p->fontMetrics().lineSpacing();
- p->setPen(Qt::black);
- p->setFont(headerFont);
-
- headerRight = TQString("#%1").arg(page);
-
- p->drawText(0, 0, metrics.width(), dy, Qt::AlignLeft, headerLeft);
- p->drawText(0, 0, metrics.width(), dy, Qt::AlignHCenter, headerMid);
- p->drawText(0, 0, metrics.width(), dy, Qt::AlignRight, headerRight);
- }
-
-
-#ifndef QT_NO_TRANSFORMATIONS
- if (scalePage)
- p->scale(scale, scale);
-#endif
-
- p->setClipRect(0, headerHeight, pageWidth, pageHeight, TQPainter::CoordDevice);
- p->translate(0, headerHeight-top);
-
- bottom = top+pageHeight;
-
- root->setPageTop(top);
- root->setPageBottom(bottom);
- root->setPageNumber(page);
-
- root->layer()->paint(p, TQRect(0, top, pageWidth, pageHeight));
-// m_part->xmlDocImpl()->renderer()->layer()->paint(p, TQRect(0, top, pageWidth, pageHeight));
-// root->repaint();
-// p->flush();
- kdDebug(6000) << "printed: page " << page <<" bottom At = " << bottom << endl;
-
- top = bottom;
- p->resetXForm();
- page++;
- }
-
- p->end();
- delete p;
-
- // and now reset the layout to the usual one...
- root->setPagedMode(false);
- root->setStaticMode(false);
- d->paged = false;
- khtml::setPrintPainter( 0 );
- setMediaType( oldMediaType );
- m_part->xmlDocImpl()->setPaintDevice( TQT_TQPAINTDEVICE(this) );
- m_part->xmlDocImpl()->styleSelector()->computeFontSizes(m_part->xmlDocImpl()->paintDeviceMetrics(), m_part->zoomFactor());
- m_part->xmlDocImpl()->updateStyleSelector();
- viewport()->unsetCursor();
- }
- delete printer;
-}
-
-void KHTMLView::slotPaletteChanged()
-{
- if(!m_part->xmlDocImpl()) return;
- DOM::DocumentImpl *document = m_part->xmlDocImpl();
- if (!document->isHTMLDocument()) return;
- khtml::RenderCanvas *root = static_cast<khtml::RenderCanvas *>(document->renderer());
- if(!root) return;
- root->style()->resetPalette();
- NodeImpl *body = static_cast<HTMLDocumentImpl*>(document)->body();
- if(!body) return;
- body->setChanged(true);
- body->recalcStyle( NodeImpl::Force );
-}
-
-void KHTMLView::paint(TQPainter *p, const TQRect &rc, int yOff, bool *more)
-{
- if(!m_part->xmlDocImpl()) return;
- khtml::RenderCanvas *root = static_cast<khtml::RenderCanvas *>(m_part->xmlDocImpl()->renderer());
- if(!root) return;
-
- m_part->xmlDocImpl()->setPaintDevice(p->device());
- root->setPagedMode(true);
- root->setStaticMode(true);
- root->setWidth(rc.width());
-
- p->save();
- p->setClipRect(rc);
- p->translate(rc.left(), rc.top());
- double scale = ((double) rc.width()/(double) root->docWidth());
- int height = (int) ((double) rc.height() / scale);
-#ifndef QT_NO_TRANSFORMATIONS
- p->scale(scale, scale);
-#endif
- root->setPageTop(yOff);
- root->setPageBottom(yOff+height);
-
- root->layer()->paint(p, TQRect(0, yOff, root->docWidth(), height));
- if (more)
- *more = yOff + height < root->docHeight();
- p->restore();
-
- root->setPagedMode(false);
- root->setStaticMode(false);
- m_part->xmlDocImpl()->setPaintDevice( TQT_TQPAINTDEVICE(this) );
-}
-
-
-void KHTMLView::useSlowRepaints()
-{
- d->useSlowRepaints = true;
- setStaticBackground(true);
-}
-
-
-void KHTMLView::setVScrollBarMode ( ScrollBarMode mode )
-{
-#ifndef KHTML_NO_SCROLLBARS
- d->vmode = mode;
- TQScrollView::setVScrollBarMode(mode);
-#else
- Q_UNUSED( mode );
-#endif
-}
-
-void KHTMLView::setHScrollBarMode ( ScrollBarMode mode )
-{
-#ifndef KHTML_NO_SCROLLBARS
- d->hmode = mode;
- TQScrollView::setHScrollBarMode(mode);
-#else
- Q_UNUSED( mode );
-#endif
-}
-
-void KHTMLView::restoreScrollBar()
-{
- int ow = visibleWidth();
- TQScrollView::setVScrollBarMode(d->vmode);
- if (visibleWidth() != ow)
- layout();
- d->prevScrollbarVisible = verticalScrollBar()->isVisible();
-}
-
-TQStringList KHTMLView::formCompletionItems(const TQString &name) const
-{
- if (!m_part->settings()->isFormCompletionEnabled())
- return TQStringList();
- if (!d->formCompletions)
- d->formCompletions = new KSimpleConfig(locateLocal("data", "khtml/formcompletions"));
- return d->formCompletions->readListEntry(name);
-}
-
-void KHTMLView::clearCompletionHistory(const TQString& name)
-{
- if (!d->formCompletions)
- {
- d->formCompletions = new KSimpleConfig(locateLocal("data", "khtml/formcompletions"));
- }
- d->formCompletions->writeEntry(name, "");
- d->formCompletions->sync();
-}
-
-void KHTMLView::addFormCompletionItem(const TQString &name, const TQString &value)
-{
- if (!m_part->settings()->isFormCompletionEnabled())
- return;
- // don't store values that are all numbers or just numbers with
- // dashes or spaces as those are likely credit card numbers or
- // something similar
- bool cc_number(true);
- for (unsigned int i = 0; i < value.length(); ++i)
- {
- TQChar c(value[i]);
- if (!c.isNumber() && c != '-' && !c.isSpace())
- {
- cc_number = false;
- break;
- }
- }
- if (cc_number)
- return;
- TQStringList items = formCompletionItems(name);
- if (!items.contains(value))
- items.prepend(value);
- while ((int)items.count() > m_part->settings()->maxFormCompletionItems())
- items.remove(items.fromLast());
- d->formCompletions->writeEntry(name, items);
-}
-
-void KHTMLView::removeFormCompletionItem(const TQString &name, const TQString &value)
-{
- if (!m_part->settings()->isFormCompletionEnabled())
- return;
-
- TQStringList items = formCompletionItems(name);
- if (items.remove(value))
- d->formCompletions->writeEntry(name, items);
-}
-
-void KHTMLView::addNonPasswordStorableSite(const TQString& host)
-{
- if (!d->formCompletions) {
- d->formCompletions = new KSimpleConfig(locateLocal("data", "khtml/formcompletions"));
- }
-
- d->formCompletions->setGroup("NonPasswordStorableSites");
- TQStringList sites = d->formCompletions->readListEntry("Sites");
- sites.append(host);
- d->formCompletions->writeEntry("Sites", sites);
- d->formCompletions->sync();
- d->formCompletions->setGroup(TQString::null);//reset
-}
-
-bool KHTMLView::nonPasswordStorableSite(const TQString& host) const
-{
- if (!d->formCompletions) {
- d->formCompletions = new KSimpleConfig(locateLocal("data", "khtml/formcompletions"));
- }
- d->formCompletions->setGroup("NonPasswordStorableSites");
- TQStringList sites = d->formCompletions->readListEntry("Sites");
- d->formCompletions->setGroup(TQString::null);//reset
-
- return (sites.find(host) != sites.end());
-}
-
-// returns true if event should be swallowed
-bool KHTMLView::dispatchMouseEvent(int eventId, DOM::NodeImpl *targetNode,
- DOM::NodeImpl *targetNodeNonShared, bool cancelable,
- int detail,TQMouseEvent *_mouse, bool setUnder,
- int mouseEventType)
-{
- // if the target node is a text node, dispatch on the parent node - rdar://4196646 (and #76948)
- if (targetNode && targetNode->isTextNode())
- targetNode = targetNode->parentNode();
-
- if (d->underMouse)
- d->underMouse->deref();
- d->underMouse = targetNode;
- if (d->underMouse)
- d->underMouse->ref();
-
- if (d->underMouseNonShared)
- d->underMouseNonShared->deref();
- d->underMouseNonShared = targetNodeNonShared;
- if (d->underMouseNonShared)
- d->underMouseNonShared->ref();
-
- int exceptioncode = 0;
- int pageX = 0;
- int pageY = 0;
- viewportToContents(_mouse->x(), _mouse->y(), pageX, pageY);
- int clientX = pageX - contentsX();
- int clientY = pageY - contentsY();
- int screenX = _mouse->globalX();
- int screenY = _mouse->globalY();
- int button = -1;
- switch (_mouse->button()) {
- case Qt::LeftButton:
- button = 0;
- break;
- case Qt::MidButton:
- button = 1;
- break;
- case Qt::RightButton:
- button = 2;
- break;
- default:
- break;
- }
- if (d->accessKeysEnabled && d->accessKeysPreActivate && button!=-1)
- d->accessKeysPreActivate=false;
-
- bool ctrlKey = (_mouse->state() & ControlButton);
- bool altKey = (_mouse->state() & AltButton);
- bool shiftKey = (_mouse->state() & ShiftButton);
- bool metaKey = (_mouse->state() & MetaButton);
-
- // mouseout/mouseover
- if (setUnder && (d->prevMouseX != pageX || d->prevMouseY != pageY)) {
-
- // ### this code sucks. we should save the oldUnder instead of calculating
- // it again. calculating is expensive! (Dirk)
- NodeImpl *oldUnder = 0;
- if (d->prevMouseX >= 0 && d->prevMouseY >= 0) {
- NodeImpl::MouseEvent mev( _mouse->stateAfter(), static_cast<NodeImpl::MouseEventType>(mouseEventType));
- m_part->xmlDocImpl()->prepareMouseEvent( true, d->prevMouseX, d->prevMouseY, &mev );
- oldUnder = mev.innerNode.handle();
-
- if (oldUnder && oldUnder->isTextNode())
- oldUnder = oldUnder->parentNode();
- }
-// tqDebug("oldunder=%p (%s), target=%p (%s) x/y=%d/%d", oldUnder, oldUnder ? oldUnder->renderer()->renderName() : 0, targetNode, targetNode ? targetNode->renderer()->renderName() : 0, _mouse->x(), _mouse->y());
- if (oldUnder != targetNode) {
- // send mouseout event to the old node
- if (oldUnder){
- oldUnder->ref();
- MouseEventImpl *me = new MouseEventImpl(EventImpl::MOUSEOUT_EVENT,
- true,true,m_part->xmlDocImpl()->defaultView(),
- 0,screenX,screenY,clientX,clientY,pageX, pageY,
- ctrlKey,altKey,shiftKey,metaKey,
- button,targetNode);
- me->ref();
- oldUnder->dispatchEvent(me,exceptioncode,true);
- me->deref();
- }
-
- // send mouseover event to the new node
- if (targetNode) {
- MouseEventImpl *me = new MouseEventImpl(EventImpl::MOUSEOVER_EVENT,
- true,true,m_part->xmlDocImpl()->defaultView(),
- 0,screenX,screenY,clientX,clientY,pageX, pageY,
- ctrlKey,altKey,shiftKey,metaKey,
- button,oldUnder);
-
- me->ref();
- targetNode->dispatchEvent(me,exceptioncode,true);
- me->deref();
- }
-
- if (oldUnder)
- oldUnder->deref();
- }
- }
-
- bool swallowEvent = false;
-
- if (targetNode) {
- // send the actual event
- bool dblclick = ( eventId == EventImpl::CLICK_EVENT &&
- _mouse->type() == TQEvent::MouseButtonDblClick );
- MouseEventImpl *me = new MouseEventImpl(static_cast<EventImpl::EventId>(eventId),
- true,cancelable,m_part->xmlDocImpl()->defaultView(),
- detail,screenX,screenY,clientX,clientY,pageX, pageY,
- ctrlKey,altKey,shiftKey,metaKey,
- button,0, _mouse, dblclick );
- me->ref();
- targetNode->dispatchEvent(me,exceptioncode,true);
- bool defaultHandled = me->defaultHandled();
- if (defaultHandled || me->defaultPrevented())
- swallowEvent = true;
- me->deref();
-
- if (eventId == EventImpl::MOUSEDOWN_EVENT) {
- // Focus should be shifted on mouse down, not on a click. -dwh
- // Blur current focus node when a link/button is clicked; this
- // is expected by some sites that rely on onChange handlers running
- // from form fields before the button click is processed.
- DOM::NodeImpl* nodeImpl = targetNode;
- for ( ; nodeImpl && !nodeImpl->isFocusable(); nodeImpl = nodeImpl->parentNode());
- if (nodeImpl && nodeImpl->isMouseFocusable())
- m_part->xmlDocImpl()->setFocusNode(nodeImpl);
- else if (!nodeImpl || !nodeImpl->focused())
- m_part->xmlDocImpl()->setFocusNode(0);
- }
- }
-
- return swallowEvent;
-}
-
-void KHTMLView::setIgnoreWheelEvents( bool e )
-{
- d->ignoreWheelEvents = e;
-}
-
-#ifndef QT_NO_WHEELEVENT
-
-void KHTMLView::viewportWheelEvent(TQWheelEvent* e)
-{
- if (d->accessKeysEnabled && d->accessKeysPreActivate) d->accessKeysPreActivate=false;
-
- if ( ( e->state() & ControlButton) == ControlButton )
- {
- emit zoomView( - e->delta() );
- e->accept();
- }
- else if (d->firstRelayout)
- {
- e->accept();
- }
- else if( ( (e->orientation() == Qt::Vertical &&
- ((d->ignoreWheelEvents && !verticalScrollBar()->isVisible())
- || e->delta() > 0 && contentsY() <= 0
- || e->delta() < 0 && contentsY() >= contentsHeight() - visibleHeight()))
- ||
- (e->orientation() == Qt::Horizontal &&
- ((d->ignoreWheelEvents && !horizontalScrollBar()->isVisible())
- || e->delta() > 0 && contentsX() <=0
- || e->delta() < 0 && contentsX() >= contentsWidth() - visibleWidth())))
- && m_part->parentPart())
- {
- if ( m_part->parentPart()->view() )
- m_part->parentPart()->view()->wheelEvent( e );
- e->ignore();
- }
- else
- {
- d->scrollBarMoved = true;
-#ifndef NO_SMOOTH_SCROLL_HACK
- scrollViewWheelEvent( e );
-#else
- TQScrollView::viewportWheelEvent( e );
-#endif
-
- TQMouseEvent *tempEvent = new TQMouseEvent( TQEvent::MouseMove, TQPoint(-1,-1), TQPoint(-1,-1), Qt::NoButton, e->state() );
- emit viewportMouseMoveEvent ( tempEvent );
- delete tempEvent;
- }
-
-}
-#endif
-
-void KHTMLView::dragEnterEvent( TQDragEnterEvent* ev )
-{
- // Handle drops onto frames (#16820)
- // Drops on the main html part is handled by Konqueror (and shouldn't do anything
- // in e.g. kmail, so not handled here).
- if ( m_part->parentPart() )
- {
- TQApplication::sendEvent(m_part->parentPart()->widget(), ev);
- return;
- }
- TQScrollView::dragEnterEvent( ev );
-}
-
-void KHTMLView::dropEvent( TQDropEvent *ev )
-{
- // Handle drops onto frames (#16820)
- // Drops on the main html part is handled by Konqueror (and shouldn't do anything
- // in e.g. kmail, so not handled here).
- if ( m_part->parentPart() )
- {
- TQApplication::sendEvent(m_part->parentPart()->widget(), ev);
- return;
- }
- TQScrollView::dropEvent( ev );
-}
-
-void KHTMLView::focusInEvent( TQFocusEvent *e )
-{
-#ifndef KHTML_NO_TYPE_AHEAD_FIND
- m_part->enableFindAheadActions( true );
-#endif
- DOM::NodeImpl* fn = m_part->xmlDocImpl() ? m_part->xmlDocImpl()->focusNode() : 0;
- if (fn && fn->renderer() && fn->renderer()->isWidget() &&
- (e->reason() != TQFocusEvent::Mouse) &&
- static_cast<khtml::RenderWidget*>(fn->renderer())->widget())
- static_cast<khtml::RenderWidget*>(fn->renderer())->widget()->setFocus();
-#ifndef KHTML_NO_CARET
- // Restart blink frequency timer if it has been killed, but only on
- // editable nodes
- if (d->m_caretViewContext &&
- d->m_caretViewContext->freqTimerId == -1 &&
- fn) {
- if (m_part->isCaretMode()
- || m_part->isEditable()
- || (fn && fn->renderer()
- && fn->renderer()->style()->userInput()
- == UI_ENABLED)) {
- d->m_caretViewContext->freqTimerId = startTimer(500);
- d->m_caretViewContext->visible = true;
- }/*end if*/
- }/*end if*/
- showCaret();
-#endif // KHTML_NO_CARET
- TQScrollView::focusInEvent( e );
-}
-
-void KHTMLView::focusOutEvent( TQFocusEvent *e )
-{
- if(m_part) m_part->stopAutoScroll();
-
-#ifndef KHTML_NO_TYPE_AHEAD_FIND
- if(d->typeAheadActivated)
- {
- findTimeout();
- }
- m_part->enableFindAheadActions( false );
-#endif // KHTML_NO_TYPE_AHEAD_FIND
-
-#ifndef KHTML_NO_CARET
- if (d->m_caretViewContext) {
- switch (d->m_caretViewContext->displayNonFocused) {
- case KHTMLPart::CaretInvisible:
- hideCaret();
- break;
- case KHTMLPart::CaretVisible: {
- killTimer(d->m_caretViewContext->freqTimerId);
- d->m_caretViewContext->freqTimerId = -1;
- NodeImpl *caretNode = m_part->xmlDocImpl()->focusNode();
- if (!d->m_caretViewContext->visible && (m_part->isCaretMode()
- || m_part->isEditable()
- || (caretNode && caretNode->renderer()
- && caretNode->renderer()->style()->userInput()
- == UI_ENABLED))) {
- d->m_caretViewContext->visible = true;
- showCaret(true);
- }/*end if*/
- break;
- }
- case KHTMLPart::CaretBlink:
- // simply leave as is
- break;
- }/*end switch*/
- }/*end if*/
-#endif // KHTML_NO_CARET
-
- if ( d->cursor_icon_widget )
- d->cursor_icon_widget->hide();
-
- TQScrollView::focusOutEvent( e );
-}
-
-void KHTMLView::slotScrollBarMoved()
-{
- if ( !d->firstRelayout && !d->complete && m_part->xmlDocImpl() &&
- d->layoutSchedulingEnabled) {
- // contents scroll while we are not complete: we need to check our layout *now*
- khtml::RenderCanvas* root = static_cast<khtml::RenderCanvas *>( m_part->xmlDocImpl()->renderer() );
- if (root && root->needsLayout()) {
- unscheduleRelayout();
- layout();
- }
- }
- if (!d->scrollingSelf) {
- d->scrollBarMoved = true;
- d->contentsMoving = true;
- // ensure quick reset of contentsMoving flag
- scheduleRepaint(0, 0, 0, 0);
- }
-
- if (m_part->xmlDocImpl() && m_part->xmlDocImpl()->documentElement())
- m_part->xmlDocImpl()->documentElement()->dispatchHTMLEvent(EventImpl::SCROLL_EVENT, true, false);
-}
-
-void KHTMLView::timerEvent ( TQTimerEvent *e )
-{
-// kdDebug() << "timer event " << e->timerId() << endl;
- if ( e->timerId() == d->scrollTimerId ) {
- if( d->scrollSuspended )
- return;
- switch (d->scrollDirection) {
- case KHTMLViewPrivate::ScrollDown:
- if (contentsY() + visibleHeight () >= contentsHeight())
- d->newScrollTimer(this, 0);
- else
- scrollBy( 0, d->scrollBy );
- break;
- case KHTMLViewPrivate::ScrollUp:
- if (contentsY() <= 0)
- d->newScrollTimer(this, 0);
- else
- scrollBy( 0, -d->scrollBy );
- break;
- case KHTMLViewPrivate::ScrollRight:
- if (contentsX() + visibleWidth () >= contentsWidth())
- d->newScrollTimer(this, 0);
- else
- scrollBy( d->scrollBy, 0 );
- break;
- case KHTMLViewPrivate::ScrollLeft:
- if (contentsX() <= 0)
- d->newScrollTimer(this, 0);
- else
- scrollBy( -d->scrollBy, 0 );
- break;
- }
- return;
- }
- else if ( e->timerId() == d->layoutTimerId ) {
- d->dirtyLayout = true;
- layout();
- if (d->firstRelayout) {
- d->firstRelayout = false;
- verticalScrollBar()->setEnabled( true );
- horizontalScrollBar()->setEnabled( true );
- }
- }
-#ifndef KHTML_NO_CARET
- else if (d->m_caretViewContext
- && e->timerId() == d->m_caretViewContext->freqTimerId) {
- d->m_caretViewContext->visible = !d->m_caretViewContext->visible;
- if (d->m_caretViewContext->displayed) {
- updateContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
- d->m_caretViewContext->width,
- d->m_caretViewContext->height);
- }/*end if*/
-// if (d->m_caretViewContext->visible) cout << "|" << flush;
-// else cout << "" << flush;
- return;
- }
-#endif
-
- d->contentsMoving = false;
- if( m_part->xmlDocImpl() ) {
- DOM::DocumentImpl *document = m_part->xmlDocImpl();
- khtml::RenderCanvas* root = static_cast<khtml::RenderCanvas *>(document->renderer());
-
- if ( root && root->needsLayout() ) {
- killTimer(d->repaintTimerId);
- d->repaintTimerId = 0;
- scheduleRelayout();
- return;
- }
- }
-
- setStaticBackground(d->useSlowRepaints);
-
-// kdDebug() << "scheduled repaint "<< d->repaintTimerId << endl;
- killTimer(d->repaintTimerId);
- d->repaintTimerId = 0;
-
- TQRect updateRegion;
- TQMemArray<TQRect> rects = d->updateRegion.rects();
-
- d->updateRegion = TQRegion();
-
- if ( rects.size() )
- updateRegion = rects[0];
-
- for ( unsigned i = 1; i < rects.size(); ++i ) {
- TQRect newRegion = updateRegion.unite(rects[i]);
- if (2*newRegion.height() > 3*updateRegion.height() )
- {
- repaintContents( updateRegion );
- updateRegion = rects[i];
- }
- else
- updateRegion = newRegion;
- }
-
- if ( !updateRegion.isNull() )
- repaintContents( updateRegion );
-
- // As widgets can only be accurately positioned during painting, every layout might
- // dissociate a widget from its RenderWidget. E.g: if a RenderWidget was visible before layout, but the layout
- // pushed it out of the viewport, it will not be repainted, and consequently it's assocoated widget won't be repositioned!
- // Thus we need to check each supposedly 'visible' widget at the end of each layout, and remove it in case it's no more in sight.
-
- if (d->dirtyLayout && !d->visibleWidgets.isEmpty()) {
- TQWidget* w;
- d->dirtyLayout = false;
-
- TQRect visibleRect(contentsX(), contentsY(), visibleWidth(), visibleHeight());
- TQPtrList<RenderWidget> toRemove;
- for (TQPtrDictIterator<TQWidget> it(d->visibleWidgets); it.current(); ++it) {
- int xp = 0, yp = 0;
- w = it.current();
- RenderWidget* rw = static_cast<RenderWidget*>( it.currentKey() );
- if (!rw->absolutePosition(xp, yp) ||
- !visibleRect.intersects(TQRect(xp, yp, w->width(), w->height())))
- toRemove.append(rw);
- }
- for (RenderWidget* r = toRemove.first(); r; r = toRemove.next())
- if ( (w = d->visibleWidgets.take(r) ) )
- addChild(w, 0, -500000);
- }
-
- emit repaintAccessKeys();
- if (d->emitCompletedAfterRepaint) {
- bool full = d->emitCompletedAfterRepaint == KHTMLViewPrivate::CSFull;
- d->emitCompletedAfterRepaint = KHTMLViewPrivate::CSNone;
- if ( full )
- emit m_part->completed();
- else
- emit m_part->completed(true);
- }
-}
-
-void KHTMLView::scheduleRelayout(khtml::RenderObject * /*clippedObj*/)
-{
- if (!d->layoutSchedulingEnabled || d->layoutTimerId)
- return;
-
- d->layoutTimerId = startTimer( m_part->xmlDocImpl() && m_part->xmlDocImpl()->parsing()
- ? 1000 : 0 );
-}
-
-void KHTMLView::unscheduleRelayout()
-{
- if (!d->layoutTimerId)
- return;
-
- killTimer(d->layoutTimerId);
- d->layoutTimerId = 0;
-}
-
-void KHTMLView::unscheduleRepaint()
-{
- if (!d->repaintTimerId)
- return;
-
- killTimer(d->repaintTimerId);
- d->repaintTimerId = 0;
-}
-
-void KHTMLView::scheduleRepaint(int x, int y, int w, int h, bool asap)
-{
- bool parsing = !m_part->xmlDocImpl() || m_part->xmlDocImpl()->parsing();
-
-// kdDebug() << "parsing " << parsing << endl;
-// kdDebug() << "complete " << d->complete << endl;
-
- int time = parsing ? 300 : (!asap ? ( !d->complete ? 100 : 20 ) : 0);
-
-#ifdef DEBUG_FLICKER
- TQPainter p;
- p.begin( viewport() );
-
- int vx, vy;
- contentsToViewport( x, y, vx, vy );
- p.fillRect( vx, vy, w, h, TQt::red );
- p.end();
-#endif
-
- d->updateRegion = d->updateRegion.unite(TQRect(x,y,w,h));
-
- if (asap && !parsing)
- unscheduleRepaint();
-
- if ( !d->repaintTimerId )
- d->repaintTimerId = startTimer( time );
-
-// kdDebug() << "starting timer " << time << endl;
-}
-
-void KHTMLView::complete( bool pendingAction )
-{
-// kdDebug() << "KHTMLView::complete()" << endl;
-
- d->complete = true;
-
- // is there a relayout pending?
- if (d->layoutTimerId)
- {
-// kdDebug() << "requesting relayout now" << endl;
- // do it now
- killTimer(d->layoutTimerId);
- d->layoutTimerId = startTimer( 0 );
- d->emitCompletedAfterRepaint = pendingAction ?
- KHTMLViewPrivate::CSActionPending : KHTMLViewPrivate::CSFull;
- }
-
- // is there a repaint pending?
- if (d->repaintTimerId)
- {
-// kdDebug() << "requesting repaint now" << endl;
- // do it now
- killTimer(d->repaintTimerId);
- d->repaintTimerId = startTimer( 20 );
- d->emitCompletedAfterRepaint = pendingAction ?
- KHTMLViewPrivate::CSActionPending : KHTMLViewPrivate::CSFull;
- }
-
- if (!d->emitCompletedAfterRepaint)
- {
- if (!pendingAction)
- emit m_part->completed();
- else
- emit m_part->completed(true);
- }
-
-}
-
-void KHTMLView::slotMouseScrollTimer()
-{
- scrollBy( d->m_mouseScroll_byX, d->m_mouseScroll_byY );
-}
-
-#ifndef KHTML_NO_CARET
-
-// ### the dependencies on static functions are a nightmare. just be
-// hacky and include the implementation here. Clean me up, please.
-
-#include "khtml_caret.cpp"
-
-void KHTMLView::initCaret(bool keepSelection)
-{
-#if DEBUG_CARETMODE > 0
- kdDebug(6200) << "begin initCaret" << endl;
-#endif
- // save caretMoved state as moveCaretTo changes it
- if (m_part->xmlDocImpl()) {
-#if 0
- ElementImpl *listitem = m_part->xmlDocImpl()->getElementById("__test_element__");
- if (listitem) dumpLineBoxes(static_cast<RenderFlow *>(listitem->renderer()));
-#endif
- d->caretViewContext();
- bool cmoved = d->m_caretViewContext->caretMoved;
- if (m_part->d->caretNode().isNull()) {
- // set to document, position will be sanitized anyway
- m_part->d->caretNode() = m_part->document();
- m_part->d->caretOffset() = 0L;
- // This sanity check is necessary for the not so unlikely case that
- // setEditable or setCaretMode is called before any render objects have
- // been created.
- if (!m_part->d->caretNode().handle()->renderer()) return;
- }/*end if*/
-// kdDebug(6200) << "d->m_selectionStart " << m_part->d->m_selectionStart.handle()
-// << " d->m_selectionEnd " << m_part->d->m_selectionEnd.handle() << endl;
- // ### does not repaint the selection on keepSelection!=false
- moveCaretTo(m_part->d->caretNode().handle(), m_part->d->caretOffset(), !keepSelection);
-// kdDebug(6200) << "d->m_selectionStart " << m_part->d->m_selectionStart.handle()
-// << " d->m_selectionEnd " << m_part->d->m_selectionEnd.handle() << endl;
- d->m_caretViewContext->caretMoved = cmoved;
- }/*end if*/
-#if DEBUG_CARETMODE > 0
- kdDebug(6200) << "end initCaret" << endl;
-#endif
-}
-
-bool KHTMLView::caretOverrides() const
-{
- bool cm = m_part->isCaretMode();
- bool dm = m_part->isEditable();
- return cm && !dm ? false
- : (dm || m_part->d->caretNode().handle()->contentEditable())
- && d->editorContext()->override;
-}
-
-void KHTMLView::ensureNodeHasFocus(NodeImpl *node)
-{
- if (m_part->isCaretMode() || m_part->isEditable()) return;
- if (node->focused()) return;
-
- // Find first ancestor whose "user-input" is "enabled"
- NodeImpl *firstAncestor = 0;
- while (node) {
- if (node->renderer()
- && node->renderer()->style()->userInput() != UI_ENABLED)
- break;
- firstAncestor = node;
- node = node->parentNode();
- }/*wend*/
-
- if (!node) firstAncestor = 0;
-
- DocumentImpl *doc = m_part->xmlDocImpl();
- // ensure that embedded widgets don't lose their focus
- if (!firstAncestor && doc->focusNode() && doc->focusNode()->renderer()
- && doc->focusNode()->renderer()->isWidget())
- return;
-
- // Set focus node on the document
-#if DEBUG_CARETMODE > 1
- kdDebug(6200) << k_funcinfo << "firstAncestor " << firstAncestor << ": "
- << (firstAncestor ? firstAncestor->nodeName().string() : TQString::null) << endl;
-#endif
- doc->setFocusNode(firstAncestor);
- emit m_part->nodeActivated(Node(firstAncestor));
-}
-
-void KHTMLView::recalcAndStoreCaretPos(CaretBox *hintBox)
-{
- if (!m_part || m_part->d->caretNode().isNull()) return;
- d->caretViewContext();
- NodeImpl *caretNode = m_part->d->caretNode().handle();
-#if DEBUG_CARETMODE > 0
- 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;
-#endif
- caretNode->getCaret(m_part->d->caretOffset(), caretOverrides(),
- d->m_caretViewContext->x, d->m_caretViewContext->y,
- d->m_caretViewContext->width,
- d->m_caretViewContext->height);
-
- if (hintBox && d->m_caretViewContext->x == -1) {
-#if DEBUG_CARETMODE > 1
- kdDebug(6200) << "using hint inline box coordinates" << endl;
-#endif
- RenderObject *r = caretNode->renderer();
- const TQFontMetrics &fm = r->style()->fontMetrics();
- int absx, absy;
- r->containingBlock()->absolutePosition(absx, absy,
- false); // ### what about fixed?
- d->m_caretViewContext->x = absx + hintBox->xPos();
- d->m_caretViewContext->y = absy + hintBox->yPos();
-// + hintBox->baseline() - fm.ascent();
- d->m_caretViewContext->width = 1;
- // ### firstline not regarded. But I think it can be safely neglected
- // as hint boxes are only used for empty lines.
- d->m_caretViewContext->height = fm.height();
- }/*end if*/
-
-#if DEBUG_CARETMODE > 4
-// kdDebug(6200) << "freqTimerId: "<<d->m_caretViewContext->freqTimerId<<endl;
-#endif
-#if DEBUG_CARETMODE > 0
- kdDebug(6200) << "caret: ofs="<<m_part->d->caretOffset()<<" "
- <<" x="<<d->m_caretViewContext->x<<" y="<<d->m_caretViewContext->y
- <<" h="<<d->m_caretViewContext->height<<endl;
-#endif
-}
-
-void KHTMLView::caretOn()
-{
- if (d->m_caretViewContext) {
- killTimer(d->m_caretViewContext->freqTimerId);
-
- if (hasFocus() || d->m_caretViewContext->displayNonFocused
- == KHTMLPart::CaretBlink) {
- d->m_caretViewContext->freqTimerId = startTimer(500);
- } else {
- d->m_caretViewContext->freqTimerId = -1;
- }/*end if*/
-
- d->m_caretViewContext->visible = true;
- if ((d->m_caretViewContext->displayed = (hasFocus()
- || d->m_caretViewContext->displayNonFocused
- != KHTMLPart::CaretInvisible))) {
- updateContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
- d->m_caretViewContext->width,
- d->m_caretViewContext->height);
- }/*end if*/
-// kdDebug(6200) << "caret on" << endl;
- }/*end if*/
-}
-
-void KHTMLView::caretOff()
-{
- if (d->m_caretViewContext) {
- killTimer(d->m_caretViewContext->freqTimerId);
- d->m_caretViewContext->freqTimerId = -1;
- d->m_caretViewContext->displayed = false;
- if (d->m_caretViewContext->visible) {
- d->m_caretViewContext->visible = false;
- updateContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
- d->m_caretViewContext->width,
- d->m_caretViewContext->height);
- }/*end if*/
-// kdDebug(6200) << "caret off" << endl;
- }/*end if*/
-}
-
-void KHTMLView::showCaret(bool forceRepaint)
-{
- if (d->m_caretViewContext) {
- d->m_caretViewContext->displayed = true;
- if (d->m_caretViewContext->visible) {
- if (!forceRepaint) {
- updateContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
- d->m_caretViewContext->width,
- d->m_caretViewContext->height);
- } else {
- repaintContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
- d->m_caretViewContext->width,
- d->m_caretViewContext->height);
- }/*end if*/
- }/*end if*/
-// kdDebug(6200) << "caret shown" << endl;
- }/*end if*/
-}
-
-bool KHTMLView::foldSelectionToCaret(NodeImpl *startNode, long startOffset,
- NodeImpl *endNode, long endOffset)
-{
- m_part->d->m_selectionStart = m_part->d->m_selectionEnd = m_part->d->caretNode();
- m_part->d->m_startOffset = m_part->d->m_endOffset = m_part->d->caretOffset();
- m_part->d->m_extendAtEnd = true;
-
- bool folded = startNode != endNode || startOffset != endOffset;
-
- // Only clear the selection if there has been one.
- if (folded) {
- m_part->xmlDocImpl()->clearSelection();
- }/*end if*/
-
- return folded;
-}
-
-void KHTMLView::hideCaret()
-{
- if (d->m_caretViewContext) {
- if (d->m_caretViewContext->visible) {
-// kdDebug(6200) << "redraw caret hidden" << endl;
- d->m_caretViewContext->visible = false;
- // force repaint, otherwise the event won't be handled
- // before the focus leaves the window
- repaintContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
- d->m_caretViewContext->width,
- d->m_caretViewContext->height);
- d->m_caretViewContext->visible = true;
- }/*end if*/
- d->m_caretViewContext->displayed = false;
-// kdDebug(6200) << "caret hidden" << endl;
- }/*end if*/
-}
-
-int KHTMLView::caretDisplayPolicyNonFocused() const
-{
- if (d->m_caretViewContext)
- return d->m_caretViewContext->displayNonFocused;
- else
- return KHTMLPart::CaretInvisible;
-}
-
-void KHTMLView::setCaretDisplayPolicyNonFocused(int policy)
-{
- d->caretViewContext();
-// int old = d->m_caretViewContext->displayNonFocused;
- d->m_caretViewContext->displayNonFocused = (KHTMLPart::CaretDisplayPolicy)policy;
-
- // make change immediately take effect if not focused
- if (!hasFocus()) {
- switch (d->m_caretViewContext->displayNonFocused) {
- case KHTMLPart::CaretInvisible:
- hideCaret();
- break;
- case KHTMLPart::CaretBlink:
- if (d->m_caretViewContext->freqTimerId != -1) break;
- d->m_caretViewContext->freqTimerId = startTimer(500);
- // fall through
- case KHTMLPart::CaretVisible:
- d->m_caretViewContext->displayed = true;
- showCaret();
- break;
- }/*end switch*/
- }/*end if*/
-}
-
-bool KHTMLView::placeCaret(CaretBox *hintBox)
-{
- CaretViewContext *cv = d->caretViewContext();
- caretOff();
- NodeImpl *caretNode = m_part->d->caretNode().handle();
- // ### why is it sometimes null?
- if (!caretNode || !caretNode->renderer()) return false;
- ensureNodeHasFocus(caretNode);
- if (m_part->isCaretMode() || m_part->isEditable()
- || caretNode->renderer()->style()->userInput() == UI_ENABLED) {
- recalcAndStoreCaretPos(hintBox);
-
- cv->origX = cv->x;
-
- caretOn();
- return true;
- }/*end if*/
- return false;
-}
-
-void KHTMLView::ensureCaretVisible()
-{
- CaretViewContext *cv = d->m_caretViewContext;
- if (!cv) return;
- ensureVisible(cv->x, cv->y, cv->width, cv->height);
- d->scrollBarMoved = false;
-}
-
-bool KHTMLView::extendSelection(NodeImpl *oldStartSel, long oldStartOfs,
- NodeImpl *oldEndSel, long oldEndOfs)
-{
- bool changed = false;
- if (m_part->d->m_selectionStart == m_part->d->m_selectionEnd
- && m_part->d->m_startOffset == m_part->d->m_endOffset) {
- changed = foldSelectionToCaret(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs);
- m_part->d->m_extendAtEnd = true;
- } else do {
- changed = m_part->d->m_selectionStart.handle() != oldStartSel
- || m_part->d->m_startOffset != oldStartOfs
- || m_part->d->m_selectionEnd.handle() != oldEndSel
- || m_part->d->m_endOffset != oldEndOfs;
- if (!changed) break;
-
- // determine start position -- caret position is always at end.
- NodeImpl *startNode;
- long startOffset;
- if (m_part->d->m_extendAtEnd) {
- startNode = m_part->d->m_selectionStart.handle();
- startOffset = m_part->d->m_startOffset;
- } else {
- startNode = m_part->d->m_selectionEnd.handle();
- startOffset = m_part->d->m_endOffset;
- m_part->d->m_selectionEnd = m_part->d->m_selectionStart;
- m_part->d->m_endOffset = m_part->d->m_startOffset;
- m_part->d->m_extendAtEnd = true;
- }/*end if*/
-
- bool swapNeeded = false;
- if (!m_part->d->m_selectionEnd.isNull() && startNode) {
- swapNeeded = RangeImpl::compareBoundaryPoints(startNode, startOffset,
- m_part->d->m_selectionEnd.handle(),
- m_part->d->m_endOffset) >= 0;
- }/*end if*/
-
- m_part->d->m_selectionStart = startNode;
- m_part->d->m_startOffset = startOffset;
-
- if (swapNeeded) {
- m_part->xmlDocImpl()->setSelection(m_part->d->m_selectionEnd.handle(),
- m_part->d->m_endOffset, m_part->d->m_selectionStart.handle(),
- m_part->d->m_startOffset);
- } else {
- m_part->xmlDocImpl()->setSelection(m_part->d->m_selectionStart.handle(),
- m_part->d->m_startOffset, m_part->d->m_selectionEnd.handle(),
- m_part->d->m_endOffset);
- }/*end if*/
- } while(false);/*end if*/
- return changed;
-}
-
-void KHTMLView::updateSelection(NodeImpl *oldStartSel, long oldStartOfs,
- NodeImpl *oldEndSel, long oldEndOfs)
-{
- if (m_part->d->m_selectionStart == m_part->d->m_selectionEnd
- && m_part->d->m_startOffset == m_part->d->m_endOffset) {
- if (foldSelectionToCaret(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs)) {
- m_part->emitSelectionChanged();
- }/*end if*/
- m_part->d->m_extendAtEnd = true;
- } else {
- // check if the extending end has passed the immobile end
- if (!m_part->d->m_selectionEnd.isNull() && !m_part->d->m_selectionEnd.isNull()) {
- bool swapNeeded = RangeImpl::compareBoundaryPoints(
- m_part->d->m_selectionStart.handle(), m_part->d->m_startOffset,
- m_part->d->m_selectionEnd.handle(), m_part->d->m_endOffset) >= 0;
- if (swapNeeded) {
- DOM::Node tmpNode = m_part->d->m_selectionStart;
- long tmpOffset = m_part->d->m_startOffset;
- m_part->d->m_selectionStart = m_part->d->m_selectionEnd;
- m_part->d->m_startOffset = m_part->d->m_endOffset;
- m_part->d->m_selectionEnd = tmpNode;
- m_part->d->m_endOffset = tmpOffset;
- m_part->d->m_startBeforeEnd = true;
- m_part->d->m_extendAtEnd = !m_part->d->m_extendAtEnd;
- }/*end if*/
- }/*end if*/
-
- m_part->xmlDocImpl()->setSelection(m_part->d->m_selectionStart.handle(),
- m_part->d->m_startOffset, m_part->d->m_selectionEnd.handle(),
- m_part->d->m_endOffset);
- m_part->emitSelectionChanged();
- }/*end if*/
-}
-
-void KHTMLView::caretKeyPressEvent(TQKeyEvent *_ke)
-{
- NodeImpl *oldStartSel = m_part->d->m_selectionStart.handle();
- long oldStartOfs = m_part->d->m_startOffset;
- NodeImpl *oldEndSel = m_part->d->m_selectionEnd.handle();
- long oldEndOfs = m_part->d->m_endOffset;
-
- NodeImpl *oldCaretNode = m_part->d->caretNode().handle();
- long oldOffset = m_part->d->caretOffset();
-
- bool ctrl = _ke->state() & ControlButton;
-
-// FIXME: this is that widely indented because I will write ifs around it.
- switch(_ke->key()) {
- case Key_Space:
- break;
-
- case Key_Down:
- moveCaretNextLine(1);
- break;
-
- case Key_Up:
- moveCaretPrevLine(1);
- break;
-
- case Key_Left:
- moveCaretBy(false, ctrl ? CaretByWord : CaretByCharacter, 1);
- break;
-
- case Key_Right:
- moveCaretBy(true, ctrl ? CaretByWord : CaretByCharacter, 1);
- break;
-
- case Key_Next:
- moveCaretNextPage();
- break;
-
- case Key_Prior:
- moveCaretPrevPage();
- break;
-
- case Key_Home:
- if (ctrl)
- moveCaretToDocumentBoundary(false);
- else
- moveCaretToLineBegin();
- break;
-
- case Key_End:
- if (ctrl)
- moveCaretToDocumentBoundary(true);
- else
- moveCaretToLineEnd();
- break;
-
- }/*end switch*/
-
- if ((m_part->d->caretNode().handle() != oldCaretNode
- || m_part->d->caretOffset() != oldOffset)
- // node should never be null, but faulty conditions may cause it to be
- && !m_part->d->caretNode().isNull()) {
-
- d->m_caretViewContext->caretMoved = true;
-
- if (_ke->state() & ShiftButton) { // extend selection
- updateSelection(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs);
- } else { // clear any selection
- if (foldSelectionToCaret(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs))
- m_part->emitSelectionChanged();
- }/*end if*/
-
- m_part->emitCaretPositionChanged(m_part->d->caretNode(), m_part->d->caretOffset());
- }/*end if*/
-
- _ke->accept();
-}
-
-bool KHTMLView::moveCaretTo(NodeImpl *node, long offset, bool clearSel)
-{
- if (!node) return false;
- ElementImpl *baseElem = determineBaseElement(node);
- RenderFlow *base = static_cast<RenderFlow *>(baseElem ? baseElem->renderer() : 0);
- if (!node) return false;
-
- // need to find out the node's inline box. If there is none, this function
- // will snap to the next node that has one. This is necessary to make the
- // caret visible in any case.
- CaretBoxLineDeleter cblDeleter;
-// RenderBlock *cb;
- long r_ofs;
- CaretBoxIterator cbit;
- CaretBoxLine *cbl = findCaretBoxLine(node, offset, &cblDeleter, base, r_ofs, cbit);
- if(!cbl) {
- kdWarning() << "KHTMLView::moveCaretTo - findCaretBoxLine() returns NULL" << endl;
- return false;
- }
-
-#if DEBUG_CARETMODE > 3
- if (cbl) kdDebug(6200) << cbl->information() << endl;
-#endif
- CaretBox *box = *cbit;
- if (cbit != cbl->end() && box->object() != node->renderer()) {
- if (box->object()->element()) {
- mapRenderPosToDOMPos(box->object(), r_ofs, box->isOutside(),
- box->isOutsideEnd(), node, offset);
- //if (!outside) offset = node->minOffset();
-#if DEBUG_CARETMODE > 1
- kdDebug(6200) << "set new node " << node->nodeName().string() << "@" << node << endl;
-#endif
- } else { // box has no associated element -> do not use
- // this case should actually never happen.
- box = 0;
- kdError(6200) << "Box contains no node! Crash imminent" << endl;
- }/*end if*/
- }
-
- NodeImpl *oldStartSel = m_part->d->m_selectionStart.handle();
- long oldStartOfs = m_part->d->m_startOffset;
- NodeImpl *oldEndSel = m_part->d->m_selectionEnd.handle();
- long oldEndOfs = m_part->d->m_endOffset;
-
- // test for position change
- bool posChanged = m_part->d->caretNode().handle() != node
- || m_part->d->caretOffset() != offset;
- bool selChanged = false;
-
- m_part->d->caretNode() = node;
- m_part->d->caretOffset() = offset;
- if (clearSel || !oldStartSel || !oldEndSel) {
- selChanged = foldSelectionToCaret(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs);
- } else {
- //kdDebug(6200) << "moveToCaret: extendSelection: m_extendAtEnd " << m_part->d->m_extendAtEnd << endl;
- //kdDebug(6200) << "selection: start(" << m_part->d->m_selectionStart.handle() << "," << m_part->d->m_startOffset << "), end(" << m_part->d->m_selectionEnd.handle() << "," << m_part->d->m_endOffset << "), caret(" << m_part->d->caretNode().handle() << "," << m_part->d->caretOffset() << ")" << endl;
- selChanged = extendSelection(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs);
- //kdDebug(6200) << "after extendSelection: m_extendAtEnd " << m_part->d->m_extendAtEnd << endl;
- //kdDebug(6200) << "selection: start(" << m_part->d->m_selectionStart.handle() << "," << m_part->d->m_startOffset << "), end(" << m_part->d->m_selectionEnd.handle() << "," << m_part->d->m_endOffset << "), caret(" << m_part->d->caretNode().handle() << "," << m_part->d->caretOffset() << ")" << endl;
- }/*end if*/
-
- d->caretViewContext()->caretMoved = true;
-
- bool visible_caret = placeCaret(box);
-
- // FIXME: if the old position was !visible_caret, and the new position is
- // also, then two caretPositionChanged signals with a null Node are
- // emitted in series.
- if (posChanged) {
- m_part->emitCaretPositionChanged(visible_caret ? node : 0, offset);
- }/*end if*/
-
- return selChanged;
-}
-
-void KHTMLView::moveCaretByLine(bool next, int count)
-{
- Node &caretNodeRef = m_part->d->caretNode();
- if (caretNodeRef.isNull()) return;
-
- NodeImpl *caretNode = caretNodeRef.handle();
-// kdDebug(6200) << ": caretNode=" << caretNode << endl;
- long offset = m_part->d->caretOffset();
-
- CaretViewContext *cv = d->caretViewContext();
-
- ElementImpl *baseElem = determineBaseElement(caretNode);
- LinearDocument ld(m_part, caretNode, offset, LeafsOnly, baseElem);
-
- ErgonomicEditableLineIterator it(ld.current(), cv->origX);
-
- // move count lines vertically
- while (count > 0 && it != ld.end() && it != ld.preBegin()) {
- count--;
- if (next) ++it; else --it;
- }/*wend*/
-
- // Nothing? Then leave everything as is.
- if (it == ld.end() || it == ld.preBegin()) return;
-
- int x, absx, absy;
- CaretBox *caretBox = nearestCaretBox(it, d->m_caretViewContext, x, absx, absy);
-
- placeCaretOnLine(caretBox, x, absx, absy);
-}
-
-void KHTMLView::placeCaretOnLine(CaretBox *caretBox, int x, int absx, int absy)
-{
- // paranoia sanity check
- if (!caretBox) return;
-
- RenderObject *caretRender = caretBox->object();
-
-#if DEBUG_CARETMODE > 0
- kdDebug(6200) << "got valid caretBox " << caretBox << endl;
- kdDebug(6200) << "xPos: " << caretBox->xPos() << " yPos: " << caretBox->yPos()
- << " width: " << caretBox->width() << " height: " << caretBox->height() << endl;
- InlineTextBox *tb = static_cast<InlineTextBox *>(caretBox->inlineBox());
- if (caretBox->isInlineTextBox()) { kdDebug(6200) << "contains \"" << TQString(static_cast<RenderText *>(tb->object())->str->s + tb->m_start, tb->m_len) << "\"" << endl;}
-#endif
- // inquire height of caret
- int caretHeight = caretBox->height();
- bool isText = caretBox->isInlineTextBox();
- int yOfs = 0; // y-offset for text nodes
- if (isText) {
- // text boxes need extrawurst
- RenderText *t = static_cast<RenderText *>(caretRender);
- const TQFontMetrics &fm = t->metrics(caretBox->inlineBox()->m_firstLine);
- caretHeight = fm.height();
- yOfs = caretBox->inlineBox()->baseline() - fm.ascent();
- }/*end if*/
-
- caretOff();
-
- // set new caret node
- NodeImpl *caretNode;
- long &offset = m_part->d->caretOffset();
- mapRenderPosToDOMPos(caretRender, offset, caretBox->isOutside(),
- caretBox->isOutsideEnd(), caretNode, offset);
-
- // set all variables not needing special treatment
- d->m_caretViewContext->y = caretBox->yPos() + yOfs;
- d->m_caretViewContext->height = caretHeight;
- d->m_caretViewContext->width = 1; // FIXME: regard override
-
- int xPos = caretBox->xPos();
- int caretBoxWidth = caretBox->width();
- d->m_caretViewContext->x = xPos;
-
- if (!caretBox->isOutside()) {
- // before or at beginning of inline box -> place at beginning
- long r_ofs = 0;
- if (x <= xPos) {
- r_ofs = caretBox->minOffset();
- // somewhere within this block
- } else if (x > xPos && x <= xPos + caretBoxWidth) {
- if (isText) { // find out where exactly
- r_ofs = static_cast<InlineTextBox *>(caretBox->inlineBox())
- ->offsetForPoint(x, d->m_caretViewContext->x);
-#if DEBUG_CARETMODE > 2
- kdDebug(6200) << "deviation from origX " << d->m_caretViewContext->x - x << endl;
-#endif
-#if 0
- } else { // snap to nearest end
- if (xPos + caretBoxWidth - x < x - xPos) {
- d->m_caretViewContext->x = xPos + caretBoxWidth;
- r_ofs = caretNode ? caretNode->maxOffset() : 1;
- } else {
- d->m_caretViewContext->x = xPos;
- r_ofs = caretNode ? caretNode->minOffset() : 0;
- }/*end if*/
-#endif
- }/*end if*/
- } else { // after the inline box -> place at end
- d->m_caretViewContext->x = xPos + caretBoxWidth;
- r_ofs = caretBox->maxOffset();
- }/*end if*/
- offset = r_ofs;
- }/*end if*/
-#if DEBUG_CARETMODE > 0
- kdDebug(6200) << "new offset: " << offset << endl;
-#endif
-
- m_part->d->caretNode() = caretNode;
- m_part->d->caretOffset() = offset;
-
- d->m_caretViewContext->x += absx;
- d->m_caretViewContext->y += absy;
-
-#if DEBUG_CARETMODE > 1
- 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;
-#endif
-
- ensureVisible(d->m_caretViewContext->x, d->m_caretViewContext->y,
- d->m_caretViewContext->width, d->m_caretViewContext->height);
- d->scrollBarMoved = false;
-
- ensureNodeHasFocus(caretNode);
- caretOn();
-}
-
-void KHTMLView::moveCaretToLineBoundary(bool end)
-{
- Node &caretNodeRef = m_part->d->caretNode();
- if (caretNodeRef.isNull()) return;
-
- NodeImpl *caretNode = caretNodeRef.handle();
-// kdDebug(6200) << ": caretNode=" << caretNode << endl;
- long offset = m_part->d->caretOffset();
-
- ElementImpl *baseElem = determineBaseElement(caretNode);
- LinearDocument ld(m_part, caretNode, offset, LeafsOnly, baseElem);
-
- EditableLineIterator it = ld.current();
- if (it == ld.end()) return; // should not happen, but who knows
-
- EditableCaretBoxIterator fbit(it, end);
- Q_ASSERT(fbit != (*it)->end() && fbit != (*it)->preBegin());
- CaretBox *b = *fbit;
-
- RenderObject *cb = b->containingBlock();
- int absx, absy;
-
- if (cb) cb->absolutePosition(absx,absy);
- else absx = absy = 0;
-
- int x = b->xPos() + (end && !b->isOutside() ? b->width() : 0);
- d->m_caretViewContext->origX = absx + x;
- placeCaretOnLine(b, x, absx, absy);
-}
-
-void KHTMLView::moveCaretToDocumentBoundary(bool end)
-{
- Node &caretNodeRef = m_part->d->caretNode();
- if (caretNodeRef.isNull()) return;
-
- NodeImpl *caretNode = caretNodeRef.handle();
-// kdDebug(6200) << ": caretNode=" << caretNode << endl;
- long offset = m_part->d->caretOffset();
-
- ElementImpl *baseElem = determineBaseElement(caretNode);
- LinearDocument ld(m_part, caretNode, offset, IndicatedFlows, baseElem);
-
- EditableLineIterator it(end ? ld.preEnd() : ld.begin(), end);
- if (it == ld.end() || it == ld.preBegin()) return; // should not happen, but who knows
-
- EditableCaretBoxIterator fbit = it;
- Q_ASSERT(fbit != (*it)->end() && fbit != (*it)->preBegin());
- CaretBox *b = *fbit;
-
- RenderObject *cb = (*it)->containingBlock();
- int absx, absy;
-
- if (cb) cb->absolutePosition(absx, absy);
- else absx = absy = 0;
-
- int x = b->xPos()/* + (end ? b->width() : 0) reactivate for rtl*/;
- d->m_caretViewContext->origX = absx + x;
- placeCaretOnLine(b, x, absx, absy);
-}
-
-void KHTMLView::moveCaretBy(bool next, CaretMovement cmv, int count)
-{
- if (!m_part) return;
- Node &caretNodeRef = m_part->d->caretNode();
- if (caretNodeRef.isNull()) return;
-
- NodeImpl *caretNode = caretNodeRef.handle();
-// kdDebug(6200) << ": caretNode=" << caretNode << endl;
- long &offset = m_part->d->caretOffset();
-
- ElementImpl *baseElem = determineBaseElement(caretNode);
- CaretAdvancePolicy advpol = cmv != CaretByWord ? IndicatedFlows : LeafsOnly;
- LinearDocument ld(m_part, caretNode, offset, advpol, baseElem);
-
- EditableCharacterIterator it(&ld);
- while (!it.isEnd() && count > 0) {
- count--;
- if (cmv == CaretByCharacter) {
- if (next) ++it;
- else --it;
- } else if (cmv == CaretByWord) {
- if (next) moveItToNextWord(it);
- else moveItToPrevWord(it);
- }/*end if*/
-//kdDebug(6200) << "movecaret" << endl;
- }/*wend*/
- CaretBox *hintBox = 0; // make gcc uninit warning disappear
- if (!it.isEnd()) {
- NodeImpl *node = caretNodeRef.handle();
- hintBox = it.caretBox();
-//kdDebug(6200) << "hintBox = " << hintBox << endl;
-//kdDebug(6200) << " outside " << hintBox->isOutside() << " outsideEnd " << hintBox->isOutsideEnd() << " r " << it.renderer() << " ofs " << it.offset() << " cb " << hintBox->containingBlock() << endl;
- mapRenderPosToDOMPos(it.renderer(), it.offset(), hintBox->isOutside(),
- hintBox->isOutsideEnd(), node, offset);
-//kdDebug(6200) << "mapRTD" << endl;
- caretNodeRef = node;
-#if DEBUG_CARETMODE > 2
- kdDebug(6200) << "set by valid node " << node << " " << (node?node->nodeName().string():TQString::null) << " offset: " << offset << endl;
-#endif
- } else {
- offset = next ? caretNode->maxOffset() : caretNode->minOffset();
-#if DEBUG_CARETMODE > 0
- kdDebug(6200) << "set by INvalid node. offset: " << offset << endl;
-#endif
- }/*end if*/
- placeCaretOnChar(hintBox);
-}
-
-void KHTMLView::placeCaretOnChar(CaretBox *hintBox)
-{
- caretOff();
- recalcAndStoreCaretPos(hintBox);
- ensureVisible(d->m_caretViewContext->x, d->m_caretViewContext->y,
- d->m_caretViewContext->width, d->m_caretViewContext->height);
- d->m_caretViewContext->origX = d->m_caretViewContext->x;
- d->scrollBarMoved = false;
-#if DEBUG_CARETMODE > 3
- //if (caretNode->isTextNode()) kdDebug(6200) << "text[0] = " << (int)*((TextImpl *)caretNode)->data().unicode() << " text :\"" << ((TextImpl *)caretNode)->data().string() << "\"" << endl;
-#endif
- ensureNodeHasFocus(m_part->d->caretNode().handle());
- caretOn();
-}
-
-void KHTMLView::moveCaretByPage(bool next)
-{
- Node &caretNodeRef = m_part->d->caretNode();
- if (caretNodeRef.isNull()) return;
-
- NodeImpl *caretNode = caretNodeRef.handle();
-// kdDebug(6200) << ": caretNode=" << caretNode << endl;
- long offset = m_part->d->caretOffset();
-
- int offs = (clipper()->height() < 30) ? clipper()->height() : 30;
- // Minimum distance the caret must be moved
- int mindist = clipper()->height() - offs;
-
- CaretViewContext *cv = d->caretViewContext();
-// int y = cv->y; // we always measure the top border
-
- ElementImpl *baseElem = determineBaseElement(caretNode);
- LinearDocument ld(m_part, caretNode, offset, LeafsOnly, baseElem);
-
- ErgonomicEditableLineIterator it(ld.current(), cv->origX);
-
- moveIteratorByPage(ld, it, mindist, next);
-
- int x, absx, absy;
- CaretBox *caretBox = nearestCaretBox(it, d->m_caretViewContext, x, absx, absy);
-
- placeCaretOnLine(caretBox, x, absx, absy);
-}
-
-void KHTMLView::moveCaretPrevWord()
-{
- moveCaretBy(false, CaretByWord, 1);
-}
-
-void KHTMLView::moveCaretNextWord()
-{
- moveCaretBy(true, CaretByWord, 1);
-}
-
-void KHTMLView::moveCaretPrevLine(int n)
-{
- moveCaretByLine(false, n);
-}
-
-void KHTMLView::moveCaretNextLine(int n)
-{
- moveCaretByLine(true, n);
-}
-
-void KHTMLView::moveCaretPrevPage()
-{
- moveCaretByPage(false);
-}
-
-void KHTMLView::moveCaretNextPage()
-{
- moveCaretByPage(true);
-}
-
-void KHTMLView::moveCaretToLineBegin()
-{
- moveCaretToLineBoundary(false);
-}
-
-void KHTMLView::moveCaretToLineEnd()
-{
- moveCaretToLineBoundary(true);
-}
-
-#endif // KHTML_NO_CARET
-
-#ifndef NO_SMOOTH_SCROLL_HACK
-#define timer timer2
-
-// All scrolls must be completed within 240ms of last keypress
-static const int SCROLL_TIME = 240;
-// Each step is 20 ms == 50 frames/second
-static const int SCROLL_TICK = 20;
-
-void KHTMLView::scrollBy(int dx, int dy)
-{
- TDEConfigGroup cfg( TDEGlobal::config(), "KDE" );
- if( !cfg.readBoolEntry( "SmoothScrolling", false )) {
- TQScrollView::scrollBy( dx, dy );
- return;
- }
- // scrolling destination
- int full_dx = d->dx + dx;
- int full_dy = d->dy + dy;
-
- // scrolling speed
- int ddx = 0;
- int ddy = 0;
-
- int steps = SCROLL_TIME/SCROLL_TICK;
-
- ddx = (full_dx*16)/steps;
- ddy = (full_dy*16)/steps;
-
- // don't go under 1px/step
- if (ddx > 0 && ddx < 16) ddx = 16;
- if (ddy > 0 && ddy < 16) ddy = 16;
- if (ddx < 0 && ddx > -16) ddx = -16;
- if (ddy < 0 && ddy > -16) ddy = -16;
-
- d->dx = full_dx;
- d->dy = full_dy;
- d->ddx = ddx;
- d->ddy = ddy;
-
- if (!d->scrolling) {
- scrollTick();
- startScrolling();
- }
-}
-
-void KHTMLView::scrollTick() {
- if (d->dx == 0 && d->dy == 0) {
- stopScrolling();
- return;
- }
-
- int tddx = d->ddx + d->rdx;
- int tddy = d->ddy + d->rdy;
-
- int ddx = tddx / 16;
- int ddy = tddy / 16;
- d->rdx = tddx % 16;
- d->rdy = tddy % 16;
-
- if (d->dx > 0 && ddx > d->dx) ddx = d->dx;
- else
- if (d->dx < 0 && ddx < d->dx) ddx = d->dx;
-
- if (d->dy > 0 && ddy > d->dy) ddy = d->dy;
- else
- if (d->dy < 0 && ddy < d->dy) ddy = d->dy;
-
- d->dx -= ddx;
- d->dy -= ddy;
-
-// TQScrollView::setContentsPos( contentsX() + ddx, contentsY() + ddy);
- kapp->syncX();
- TQScrollView::scrollBy(ddx, ddy);
-// Unaccelerated X can get seriously overloaded by scrolling and for some reason
-// will send KeyPress events only infrequently. This should help to reduce
-// the load.
- kapp->syncX();
-}
-
-void KHTMLView::startScrolling()
-{
- d->scrolling = true;
- d->timer.start(SCROLL_TICK, false);
-}
-
-void KHTMLView::stopScrolling()
-{
- d->timer.stop();
- d->dx = d->dy = 0;
- d->scrolling = false;
-}
-
-// Overloaded from TQScrollView and TQScrollBar
-void KHTMLView::scrollViewWheelEvent( TQWheelEvent *e )
-{
- int pageStep = verticalScrollBar()->pageStep();
- int lineStep = verticalScrollBar()->lineStep();
- int step = TQMIN( TQApplication::wheelScrollLines()*lineStep, pageStep );
- if ( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) )
- step = pageStep;
-
- if(e->orientation() == Qt::Horizontal)
- scrollBy(-((e->delta()*step)/120), 0);
- else if(e->orientation() == Qt::Vertical)
- scrollBy(0,-((e->delta()*step)/120));
-
- e->accept();
-}
-
-#undef timer
-
-#endif // NO_SMOOTH_SCROLL_HACK
-
-#undef DEBUG_CARETMODE