📄 khtmlview.cpp
字号:
/* 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 Dirk Mueller <mueller@kde.org> * Copyright (C) 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., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, 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_object.h"#include "rendering/render_canvas.h"#include "rendering/render_style.h"#include "rendering/render_replaced.h"#include "rendering/render_line.h"#include "rendering/render_text.h"#include "xml/dom_nodeimpl.h"#include "xml/dom_selection.h"#include "xml/dom2_eventsimpl.h"#include "css/cssstyleselector.h"#include "misc/htmlhashes.h"#include "misc/helper.h"#include "khtml_settings.h"#include "khtml_printsettings.h"#include "khtmlpart_p.h"#include <kcursor.h>#include <ksimpleconfig.h>#include <kstandarddirs.h>#include <kprinter.h>#include <qtooltip.h>#include <qpainter.h>#include <qpaintdevicemetrics.h>#include <kapplication.h>#include <kimageio.h>#include <assert.h>#include <kdebug.h>#include <kurldrag.h>#include <qobjectlist.h>#if APPLE_CHANGES#include "KWQAccObjectCache.h"#endif#define PAINT_BUFFER_HEIGHT 128#define INSTRUMENT_LAYOUT_SCHEDULING 0using namespace DOM;using namespace khtml;class KHTMLToolTip;#ifndef QT_NO_TOOLTIPclass KHTMLToolTip : public QToolTip{public: KHTMLToolTip(KHTMLView *view, KHTMLViewPrivate* vp) : QToolTip(view->viewport()) { m_view = view; m_viewprivate = vp; };protected: virtual void maybeTip(const QPoint &);private: KHTMLView *m_view; KHTMLViewPrivate* m_viewprivate;};#endifclass KHTMLViewPrivate { friend class KHTMLToolTip;public: KHTMLViewPrivate() { repaintRects = 0; underMouse = 0; reset();#if !APPLE_CHANGES tp=0; paintBuffer=0; formCompletions=0;#endif layoutTimerId = 0; allDataReceivedWhenTimerSet = false; mousePressed = false;#ifndef QT_NO_TOOLTIP tooltip = 0;#endif doFullRepaint = true; isTransparent = false;#if APPLE_CHANGES vmode = hmode = QScrollView::Auto; firstLayout = true; needToInitScrollBars = true;#else prevScrollbarVisible = true;#endif } ~KHTMLViewPrivate() {#if !APPLE_CHANGES delete formCompletions; delete tp; tp = 0; delete paintBuffer; paintBuffer =0;#endif if (underMouse) underMouse->deref();#ifndef QT_NO_TOOLTIP delete tooltip;#endif delete repaintRects; } void reset() { if (underMouse) underMouse->deref(); underMouse = 0; linkPressed = false; useSlowRepaints = false; originalNode = 0; dragTarget = 0; borderTouched = false;#if !APPLE_CHANGES#ifndef KHTML_NO_SCROLLBARS vmode = QScrollView::Auto; hmode = QScrollView::Auto;#else vmode = QScrollView::AlwaysOff; hmode = QScrollView::AlwaysOff;#endif#endif scrollBarMoved = false; ignoreWheelEvents = false; borderX = 30; borderY = 30; clickX = -1; clickY = -1; prevMouseX = -1; prevMouseY = -1; clickCount = 0; isDoubleClick = false; scrollingSelf = false; layoutTimerId = 0; allDataReceivedWhenTimerSet = false; mousePressed = false; doFullRepaint = true; layoutSchedulingEnabled = true; layoutSuppressed = false; layoutCount = 0;#if APPLE_CHANGES firstLayout = true;#endif if (repaintRects) repaintRects->clear(); }#if !APPLE_CHANGES QPainter *tp; QPixmap *paintBuffer;#endif NodeImpl *underMouse; // the node that was selected when enter was pressed NodeImpl *originalNode; bool borderTouched:1; bool borderStart:1; bool scrollBarMoved:1; bool doFullRepaint:1; QScrollView::ScrollBarMode vmode; QScrollView::ScrollBarMode hmode;#if !APPLE_CHANGES bool prevScrollbarVisible;#endif bool linkPressed; bool useSlowRepaints; bool ignoreWheelEvents; int borderX, borderY;#if !APPLE_CHANGES KSimpleConfig *formCompletions;#endif int clickX, clickY, clickCount; bool isDoubleClick; int prevMouseX, prevMouseY; bool scrollingSelf; int layoutTimerId; bool allDataReceivedWhenTimerSet; bool layoutSchedulingEnabled; bool layoutSuppressed; int layoutCount;#if APPLE_CHANGES bool firstLayout; bool needToInitScrollBars;#endif bool mousePressed; bool isTransparent;#ifndef QT_NO_TOOLTIP KHTMLToolTip *tooltip;#endif // Used by objects during layout to communicate repaints that need to take place only // after all layout has been completed. QPtrList<RenderObject::RepaintInfo>* repaintRects; Node dragTarget;};#ifndef QT_NO_TOOLTIPvoid KHTMLToolTip::maybeTip(const QPoint& /*p*/){ DOM::NodeImpl *node = m_viewprivate->underMouse; while ( node ) { if ( node->isElementNode() ) { AtomicString s = static_cast<DOM::ElementImpl*>( node )->getAttribute(ATTR_TITLE); if (!s.isEmpty()) { QRect r( m_view->contentsToViewport( node->getRect().topLeft() ), node->getRect().size() ); tip( r, s.string() ); } break; } node = node->parentNode(); }}#endifKHTMLView::KHTMLView( KHTMLPart *part, QWidget *parent, const char *name) : QScrollView( parent, name, WResizeNoErase | WRepaintNoErase | WPaintUnclipped ), _refCount(1){#if KWIQ QOBJECT_TYPE(KHTMLView);#endif m_medium = "screen"; m_part = part;#if APPLE_CHANGES m_part->ref();#endif d = new KHTMLViewPrivate;#if !APPLE_CHANGES QScrollView::setVScrollBarMode(d->vmode); QScrollView::setHScrollBarMode(d->hmode);#endif connect(kapp, SIGNAL(kdisplayPaletteChanged()), this, SLOT(slotPaletteChanged())); connect(this, SIGNAL(contentsMoving(int, int)), this, SLOT(slotScrollBarMoved())); // initialize QScrollview enableClipper(true); viewport()->setMouseTracking(true); viewport()->setBackgroundMode(NoBackground); KImageIO::registerFormats();#ifndef QT_NO_TOOLTIP d->tooltip = new KHTMLToolTip( this, d );#endif init(); viewport()->show();}KHTMLView::~KHTMLView(){#if APPLE_CHANGES resetScrollBars();#endif assert(_refCount == 0); 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();#if APPLE_CHANGES m_part->deref();#endif } delete d; d = 0;}void KHTMLView::clearPart(){ if (m_part){ m_part->deref(); m_part = 0; }}#if APPLE_CHANGESvoid KHTMLView::resetScrollBars(){ // Reset the document's scrollbars back to our defaults before we yield the floor. d->firstLayout = true; suppressScrollBars(true); QScrollView::setVScrollBarMode(d->vmode); QScrollView::setHScrollBarMode(d->hmode); suppressScrollBars(false);}#endifvoid KHTMLView::init(){#if !APPLE_CHANGES if(!d->paintBuffer) d->paintBuffer = new QPixmap(PAINT_BUFFER_HEIGHT, PAINT_BUFFER_HEIGHT); if(!d->tp) d->tp = new QPainter();#endif setFocusPolicy(QWidget::StrongFocus); viewport()->setFocusPolicy( QWidget::WheelFocus ); viewport()->setFocusProxy(this); _marginWidth = -1; // undefined _marginHeight = -1; _width = 0; _height = 0; setAcceptDrops(true); #if !APPLE_CHANGES resizeContents(visibleWidth(), visibleHeight());#endif}void KHTMLView::clear(){// viewport()->erase(); setStaticBackground(false); m_part->clearSelection(); d->reset(); killTimers(); emit cleared();#if APPLE_CHANGES suppressScrollBars(true);#else QScrollView::setHScrollBarMode(d->hmode); if (d->vmode==Auto) QScrollView::setVScrollBarMode(d->prevScrollbarVisible?AlwaysOn:Auto); else QScrollView::setVScrollBarMode(d->vmode); resizeContents(visibleWidth(), visibleHeight());#endif}void KHTMLView::hideEvent(QHideEvent* e){// viewport()->setBackgroundMode(PaletteBase); QScrollView::hideEvent(e);}void KHTMLView::showEvent(QShowEvent* e){// viewport()->setBackgroundMode(NoBackground); QScrollView::showEvent(e);}void KHTMLView::resizeEvent (QResizeEvent* e){ QScrollView::resizeEvent(e);#if !APPLE_CHANGES int w = visibleWidth(); int h = visibleHeight(); layout(); // this is to make sure we get the right width even if the scrolbar has dissappeared // due to the size change. if(visibleHeight() != h || visibleWidth() != w) layout();#endif if ( m_part && m_part->xmlDocImpl() ) m_part->xmlDocImpl()->dispatchWindowEvent( EventImpl::RESIZE_EVENT, false, false ); KApplication::sendPostedEvents(viewport(), QEvent::Paint);}#if APPLE_CHANGESvoid KHTMLView::initScrollBars(){ if (!d->needToInitScrollBars) return; d->needToInitScrollBars = false; setScrollBarsMode(hScrollBarMode());}#endif#if !APPLE_CHANGES// this is to get rid of a compiler virtual overload mismatch warning. do not removevoid KHTMLView::drawContents( QPainter*){}void KHTMLView::drawContents( QPainter *p, int ex, int ey, int ew, int eh ){ //kdDebug( 6000 ) << "drawContents x=" << ex << ",y=" << ey << ",w=" << ew << ",h=" << eh << endl; if(!m_part->xmlDocImpl() || !m_part->xmlDocImpl()->renderer()) { p->fillRect(ex, ey, ew, eh, palette().normal().brush(QColorGroup::Base)); return; } 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().normal().brush(QColorGroup::Base)); m_part->xmlDocImpl()->renderer()->print(d->tp, ex, ey+py, ew, ph, 0, 0);#ifdef BOX_DEBUG if (m_part->xmlDocImpl()->focusNode()) { d->tp->setBrush(Qt::NoBrush); d->tp->drawRect(m_part->xmlDocImpl()->focusNode()->getRect()); }#endif d->tp->end(); p->drawPixmap(ex, ey+py, *d->paintBuffer, 0, 0, ew, ph); py += PAINT_BUFFER_HEIGHT; } // EDIT FIXME: KDE needs to draw the caret here. khtml::DrawContentsEvent event( p, ex, ey, ew, eh ); QApplication::sendEvent( m_part, &event );}#endif // !APPLE_CHANGESvoid 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::adjustViewSize(){ if( m_part->xmlDocImpl() ) { DOM::DocumentImpl *document = m_part->xmlDocImpl();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -