📄 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.
* Copyright (c) 2005 Nokia Corporation, 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/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 "html/html_imageimpl.h"
#include "rendering/render_frames.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>
#include <math.h>
#if APPLE_CHANGES
#include "KWQAccObjectCache.h"
#endif
#define PAINT_BUFFER_HEIGHT 128
// #define INSTRUMENT_LAYOUT_SCHEDULING 1
using namespace DOM;
using namespace khtml;
class KHTMLToolTip;
#ifndef QT_NO_TOOLTIP
class 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;
};
#endif
class KHTMLViewPrivate
OOM_MODIFIED
{
friend class KHTMLToolTip;
public:
KHTMLViewPrivate()
{
repaintRects = 0;
underMouse = 0;
clickNode = 0;
reset();
#if !APPLE_CHANGES
tp=0;
paintBuffer=0;
formCompletions=0;
#endif
layoutTimerId = 0;
delayedLayout = 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();
if (clickNode)
clickNode->deref();
#ifndef QT_NO_TOOLTIP
delete tooltip;
#endif
delete repaintRects;
}
void reset()
{
if (underMouse)
underMouse->deref();
underMouse = 0;
linkPressed = false;
useSlowRepaints = false;
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;
#if !APPLE_CHANGES
clickX = -1;
clickY = -1;
#endif
prevMouseX = -1;
prevMouseY = -1;
clickCount = 0;
if (clickNode)
clickNode->deref();
clickNode = 0;
isDoubleClick = false;
scrollingSelf = false;
layoutTimerId = 0;
delayedLayout = 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;
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;
int clickX, clickY;
#endif
int clickCount;
NodeImpl *clickNode;
bool isDoubleClick;
int prevMouseX, prevMouseY;
bool scrollingSelf;
int layoutTimerId;
bool delayedLayout;
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_TOOLTIP
void 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();
}
}
#endif
KHTMLView::KHTMLView( KHTMLPart *part, QWidget *parent, const char *name)
: QScrollView( parent, name, WResizeNoErase | WRepaintNoErase | WPaintUnclipped ),
_refCount(1)
{
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_CHANGES
void 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);
}
#endif
void 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();
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
if (d->layoutTimerId && m_part->xmlDocImpl() && !m_part->xmlDocImpl()->ownerElement())
printf("Killing the layout timer from a clear at %d\n", m_part->xmlDocImpl()->elapsedTime());
#endif
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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -