📄 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> * * 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 "khtml_part.h"#include "khtml_events.h"#include "html/html_documentimpl.h"#include "html/html_inlineimpl.h"#include "rendering/render_object.h"#include "rendering/render_root.h"#include "rendering/render_style.h"#include "xml/dom2_eventsimpl.h"#include "misc/htmlhashes.h"#include "misc/helper.h"#include "khtml_settings.h"#include <kcursor.h>#include <ksimpleconfig.h>#include <kstddirs.h>#include <kprinter.h>#include <qpixmap.h>#include <qtooltip.h>#include <qstring.h>#include <qpainter.h>#include <qpalette.h>#include <qevent.h>#include <qdatetime.h>#include <qpaintdevicemetrics.h>#include <qtimer.h>#include <kapp.h>#include <kimageio.h>#include <kdebug.h>#define PAINT_BUFFER_HEIGHT 128template class QList<KHTMLView>;QList<KHTMLView> *KHTMLView::lstViews = 0L;using namespace DOM;using namespace khtml;class KHTMLToolTip;class KHTMLViewPrivate { friend class KHTMLToolTip;public: KHTMLViewPrivate() { underMouse = 0; reset(); tp=0; paintBuffer=0; formCompletions=0; prevScrollbarVisible = true; } ~KHTMLViewPrivate() { delete formCompletions; delete tp; tp = 0; delete paintBuffer; paintBuffer =0; if (underMouse) underMouse->deref(); } void reset() { if (underMouse) underMouse->deref(); underMouse = 0; linkPressed = false; useSlowRepaints = false; originalNode = 0; borderTouched = false;#ifndef KHTML_NO_SCROLLBARS vmode = QScrollView::Auto; hmode = QScrollView::Auto;#else vmode = QScrollView::AlwaysOff; hmode = QScrollView::AlwaysOff;#endif borderX = 30; borderY = 30; clickX = -1; clickY = -1; prevMouseX = -1; prevMouseY = -1; clickCount = 0; isDoubleClick = false; } QPainter *tp; QPixmap *paintBuffer; NodeImpl *underMouse; // the node that was selected when enter was pressed ElementImpl *originalNode; bool borderTouched; bool borderStart; QScrollView::ScrollBarMode vmode; QScrollView::ScrollBarMode hmode; bool prevScrollbarVisible; bool linkPressed; bool useSlowRepaints; int borderX, borderY; KSimpleConfig *formCompletions; int clickX, clickY, clickCount; bool isDoubleClick; int prevMouseX, prevMouseY;};#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;};void KHTMLToolTip::maybeTip(const QPoint& /*p*/){ DOM::NodeImpl *node = m_viewprivate->underMouse; while ( node ) { if ( node->isElementNode() ) { QString s = static_cast<DOM::ElementImpl*>( node )->getAttribute( ATTR_TITLE ).string(); if ( !s.isEmpty() ) { QRect r( m_view->contentsToViewport( node->getRect().topLeft() ), node->getRect().size() ); tip( r, s ); } break; } node = node->parentNode(); }}#endifKHTMLView::KHTMLView( KHTMLPart *part, QWidget *parent, const char *name) : QScrollView( parent, name, WResizeNoErase | WRepaintNoErase ){ m_part = part; d = new KHTMLViewPrivate; QScrollView::setVScrollBarMode(d->vmode); QScrollView::setHScrollBarMode(d->hmode); connect(kapp, SIGNAL(kdisplayPaletteChanged()), this, SLOT(slotPaletteChanged())); // initialize QScrollview enableClipper(true); viewport()->setMouseTracking(true); viewport()->setBackgroundMode(NoBackground); KImageIO::registerFormats(); viewport()->setCursor(arrowCursor);#ifndef QT_NO_TOOLTIP ( void ) new KHTMLToolTip( this, d );#endif init(); viewport()->show();}KHTMLView::~KHTMLView(){ 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(); } lstViews->removeRef( this ); if(lstViews->isEmpty()) { delete lstViews; lstViews = 0; } delete d; d = 0;}void KHTMLView::init(){ if ( lstViews == 0L ) lstViews = new QList<KHTMLView>; lstViews->setAutoDelete( FALSE ); lstViews->append( this ); if(!d->paintBuffer) d->paintBuffer = new QPixmap(PAINT_BUFFER_HEIGHT, PAINT_BUFFER_HEIGHT); if(!d->tp) d->tp = new QPainter(); setFocusPolicy(QWidget::StrongFocus); viewport()->setFocusPolicy( QWidget::WheelFocus ); viewport()->setFocusProxy(this); _marginWidth = -1; // undefined _marginHeight = -1; _width = 0; _height = 0; setAcceptDrops(true); resizeContents(visibleWidth(), visibleHeight());}void KHTMLView::clear(){ viewport()->erase(); if(d->useSlowRepaints) setStaticBackground(false); d->reset(); emit cleared(); QScrollView::setHScrollBarMode(d->hmode); if (d->vmode==Auto) QScrollView::setVScrollBarMode(d->prevScrollbarVisible?AlwaysOn:Auto); else QScrollView::setVScrollBarMode(d->vmode); resizeContents(visibleWidth(), visibleHeight());}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); 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(); KApplication::sendPostedEvents(viewport(), QEvent::Paint);}void KHTMLView::drawContents( QPainter *p, int ex, int ey, int ew, int eh ){ if(!m_part->xmlDocImpl() || !m_part->xmlDocImpl()->renderer()) { p->fillRect(ex, ey, ew, eh, palette().normal().brush(QColorGroup::Base)); return; } //kdDebug( 6000 ) << "drawContents x=" << ex << ",y=" << ey << ",w=" << ew << ",h=" << eh << endl; 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; } khtml::DrawContentsEvent event( p, ex, ey, ew, eh ); QApplication::sendEvent( m_part, &event );}void KHTMLView::layout(bool){ //### take care of frmaes (hide scrollbars,...) if( m_part->xmlDocImpl() ) { DOM::DocumentImpl *document = m_part->xmlDocImpl(); khtml::RenderRoot* root = static_cast<khtml::RenderRoot *>(document->renderer()); if (document->isHTMLDocument()) { NodeImpl *body = static_cast<HTMLDocumentImpl*>(document)->body(); if(body && body->renderer() && body->id() == ID_FRAMESET) { QScrollView::setVScrollBarMode(AlwaysOff); QScrollView::setHScrollBarMode(AlwaysOff); _width = visibleWidth(); body->renderer()->setLayouted(false); body->renderer()->layout(); root->layout(); return; } } _height = visibleHeight(); _width = visibleWidth(); //QTime qt; //qt.start(); root->layout(); //kdDebug( 6000 ) << "TIME: layout() dt=" << qt.elapsed() << endl; } else { _width = visibleWidth(); }}//// Event Handling///////////////////void KHTMLView::viewportMousePressEvent( QMouseEvent *_mouse ){ if(!m_part->xmlDocImpl()) return; int xm, ym; viewportToContents(_mouse->x(), _mouse->y(), xm, ym); //kdDebug( 6000 ) << "\nmousePressEvent: x=" << xm << ", y=" << ym << endl; // Make this frame the active one // ### need some visual indication for the active frame. /* ### use PartManager (Simon) if ( _isFrame && !_isSelected ) { kdDebug( 6000 ) << "activating frame!" << endl; topView()->setFrameSelected(this); }*/ d->isDoubleClick = false; DOM::NodeImpl::MouseEvent mev( _mouse->stateAfter(), DOM::NodeImpl::MousePress ); m_part->xmlDocImpl()->prepareMouseEvent( xm, ym, 0, 0, &mev ); if (d->clickCount > 0 && d->clickX == xm && d->clickY == ym) // ### support mouse threshold d->clickCount++; else { d->clickCount = 1; d->clickX = xm; d->clickY = ym; } dispatchMouseEvent(EventImpl::MOUSEDOWN_EVENT,mev.innerNode.handle(),true, d->clickCount,_mouse,true,DOM::NodeImpl::MousePress); if (mev.innerNode.handle()) mev.innerNode.handle()->setPressed(); khtml::MousePressEvent event( _mouse, xm, ym, mev.url, mev.innerNode ); event.setNodePos( mev.nodeAbsX, mev.nodeAbsY ); QApplication::sendEvent( m_part, &event ); emit m_part->nodeActivated(mev.innerNode);}void KHTMLView::viewportMouseDoubleClickEvent( QMouseEvent *_mouse ){ if(!m_part->xmlDocImpl()) return; int xm, ym;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -