📄 khtmlview.cpp
字号:
}
kdDebug(6000) << "printing: scaled html width = " << pageWidth
<< " height = " << pageHeight << endl;
int top = 0;
while(top < root->docHeight()) {
if(top > 0) printer->newPage();
root->setTruncatedAt(top+pageHeight);
root->print(p, 0, top, pageWidth, pageHeight, 0, 0);
if (top + pageHeight >= root->docHeight())
break; // Stop if we have printed everything
p->translate(0, top - root->truncatedAt());
top = root->truncatedAt();
}
p->end();
delete p;
// and now reset the layout to the usual one...
root->setPrintingMode(false);
khtml::setPrintPainter( 0 );
setMediaType( oldMediaType );
m_part->xmlDocImpl()->setPaintDevice( this );
m_part->xmlDocImpl()->styleSelector()->computeFontSizes(m_part->xmlDocImpl()->paintDeviceMetrics());
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(QPainter *p, const QRect &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->setPrintingMode(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->print(p, 0, yOff, root->docWidth(), height, 0, 0);
if (more)
*more = yOff + height < root->docHeight();
p->restore();
root->setPrintingMode(false);
m_part->xmlDocImpl()->setPaintDevice( this );
}
#endif // !APPLE_CHANGES
void KHTMLView::useSlowRepaints()
{
kdDebug(0) << "slow repaints requested" << endl;
d->useSlowRepaints = true;
setStaticBackground(true);
}
void KHTMLView::setScrollBarsMode ( ScrollBarMode mode )
{
#ifndef KHTML_NO_SCROLLBARS
d->vmode = mode;
d->hmode = mode;
#if APPLE_CHANGES
QScrollView::setScrollBarsMode(mode);
#else
QScrollView::setVScrollBarMode(mode);
QScrollView::setHScrollBarMode(mode);
#endif
#else
Q_UNUSED( mode );
#endif
}
void KHTMLView::setVScrollBarMode ( ScrollBarMode mode )
{
#ifndef KHTML_NO_SCROLLBARS
d->vmode = mode;
QScrollView::setVScrollBarMode(mode);
#else
Q_UNUSED( mode );
#endif
}
void KHTMLView::setHScrollBarMode ( ScrollBarMode mode )
{
#ifndef KHTML_NO_SCROLLBARS
d->hmode = mode;
QScrollView::setHScrollBarMode(mode);
#else
Q_UNUSED( mode );
#endif
}
void KHTMLView::restoreScrollBar ( )
{
#if APPLE_CHANGES
suppressScrollBars(false);
#else
int ow = visibleWidth();
QScrollView::setVScrollBarMode(d->vmode);
if (visibleWidth() != ow)
layout();
d->prevScrollbarVisible = verticalScrollBar()->isVisible();
#endif
}
#if !APPLE_CHANGES
QStringList KHTMLView::formCompletionItems(const QString &name) const
{
if (!m_part->settings()->isFormCompletionEnabled())
return QStringList();
if (!d->formCompletions)
d->formCompletions = new KSimpleConfig(locateLocal("data", "khtml/formcompletions"));
return d->formCompletions->readListEntry(name);
}
void KHTMLView::addFormCompletionItem(const QString &name, const QString &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)
{
QChar c(value[i]);
if (!c.isNumber() && c != '-' && !c.isSpace())
{
cc_number = false;
break;
}
}
if (cc_number)
return;
QStringList 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);
}
#endif
bool KHTMLView::dispatchMouseEvent(int eventId, DOM::NodeImpl *targetNode, bool cancelable,
int detail,QMouseEvent *_mouse, bool setUnder,
int mouseEventType)
{
if (d->underMouse)
d->underMouse->deref();
d->underMouse = targetNode;
if (d->underMouse)
d->underMouse->ref();
int exceptioncode = 0;
int clientX, clientY;
viewportToContents(_mouse->x(), _mouse->y(), clientX, clientY);
#if APPLE_CHANGES
QPoint screenLoc = viewportToGlobal(_mouse->pos());
int screenX = screenLoc.x();
int screenY = screenLoc.y();
#else
int screenX = _mouse->globalX();
int screenY = _mouse->globalY();
#endif
int button = -1;
switch (_mouse->button()) {
case LeftButton:
button = 0;
break;
case MidButton:
button = 1;
break;
case RightButton:
button = 2;
break;
default:
break;
}
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 != clientX || d->prevMouseY != clientY)) {
// ### 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 != 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,
ctrlKey,altKey,shiftKey,metaKey,
button,targetNode);
oldUnder->dispatchEvent(me,exceptioncode,true);
}
// 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,
ctrlKey,altKey,shiftKey,metaKey,
button,oldUnder);
targetNode->dispatchEvent(me,exceptioncode,true);
}
if (oldUnder)
oldUnder->deref();
}
}
bool swallowEvent = false;
if (targetNode) {
// FIXME: Should share code with RenderFormElement::slotClicked, and NodeImpl::dispatchMouseEvent,
// which do a lot of the same stuff.
// send the actual event
MouseEventImpl *me = new MouseEventImpl(static_cast<EventImpl::EventId>(eventId),
true,cancelable,m_part->xmlDocImpl()->defaultView(),
detail,screenX,screenY,clientX,clientY,
ctrlKey,altKey,shiftKey,metaKey,
button,0);
me->ref();
targetNode->dispatchEvent(me,exceptioncode,true);
bool defaultHandled = me->defaultHandled();
bool defaultPrevented = me->defaultPrevented();
if (me->defaultHandled() || me->defaultPrevented())
swallowEvent = true;
me->deref();
// Special case: If it's a click event, we also send the KHTML_CLICK or KHTML_DBLCLICK event. This is not part
// of the DOM specs, but is used for compatibility with the traditional onclick="" and ondblclick="" attributes,
// as there is no way to tell the difference between single & double clicks using DOM (only the click count is
// stored, which is not necessarily the same)
if (eventId == EventImpl::CLICK_EVENT) {
me = new MouseEventImpl(EventImpl::KHTML_CLICK_EVENT,
true,cancelable,m_part->xmlDocImpl()->defaultView(),
detail,screenX,screenY,clientX,clientY,
ctrlKey,altKey,shiftKey,metaKey,
button,0);
me->ref();
if (defaultHandled)
me->setDefaultHandled();
targetNode->dispatchEvent(me,exceptioncode,true);
if (me->defaultHandled())
defaultHandled = true;
if (me->defaultPrevented())
defaultPrevented = true;
if (me->defaultHandled() || me->defaultPrevented())
swallowEvent = true;
me->deref();
if (d->isDoubleClick) {
me = new MouseEventImpl(EventImpl::KHTML_DBLCLICK_EVENT,
true,cancelable,m_part->xmlDocImpl()->defaultView(),
detail,screenX,screenY,clientX,clientY,
ctrlKey,altKey,shiftKey,metaKey,
button,0);
me->ref();
if (defaultHandled)
me->setDefaultHandled();
targetNode->dispatchEvent(me,exceptioncode,true);
if (me->defaultHandled() || me->defaultPrevented())
swallowEvent = true;
me->deref();
}
// Also send a DOMActivate event, which causes things like form submissions to occur.
if (!defaultPrevented && !targetNode->disabled())
targetNode->dispatchUIEvent(EventImpl::DOMACTIVATE_EVENT, detail);
}
else 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 focus shift is blocked, we eat the event. Note we should never clear swallowEvent
// if the page already set it (e.g., by canceling default behavior).
if (nodeImpl && nodeImpl->isMouseFocusable())
swallowEvent |= !m_part->xmlDocImpl()->setFocusNode(nodeImpl);
else if (!nodeImpl || !nodeImpl->focused())
swallowEvent |= !m_part->xmlDocImpl()->setFocusNode(0);
}
}
return swallowEvent;
}
void KHTMLView::setIgnoreWheelEvents( bool e )
{
d->ignoreWheelEvents = e;
}
#ifndef QT_NO_WHEELEVENT
void KHTMLView::viewportWheelEvent(QWheelEvent* e)
{
#if !APPLE_CHANGES
if ( d->ignoreWheelEvents && !verticalScrollBar()->isVisible() && m_part->parentPart() ) {
if ( m_part->parentPart()->view() )
m_part->parentPart()->view()->wheelEvent( e );
e->ignore();
}
else if ( d->vmode == QScrollView::AlwaysOff ) {
e->accept();
}
else {
d->scrollBarMoved = true;
QScrollView::viewportWheelEvent( e );
}
#endif
}
#endif
#if !APPLE_CHANGES
void KHTMLView::dragEnterEvent( QDragEnterEvent* 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() )
{
// Duplicated from KonqView::eventFilter
if ( QUriDrag::canDecode( ev ) )
{
KURL::List lstDragURLs;
bool ok = KURLDrag::decode( ev, lstDragURLs );
QObjectList *children = this->queryList( "QWidget" );
if ( ok &&
!lstDragURLs.first().url().contains( "javascript:", false ) && // ### this looks like a hack to me
ev->source() != this &&
children &&
children->findRef( ev->source() ) == -1 )
ev->acceptAction();
delete children;
}
}
QScrollView::dragEnterEvent( ev );
}
void KHTMLView::dropEvent( QDropEvent *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() )
{
KURL::List lstDragURLs;
bool ok = KURLDrag::decode( ev, lstDragURLs );
KHTMLPart* part = m_part->parentPart();
while ( part && part->parentPart() )
part = part->parentPart();
KParts::BrowserExtension *ext = part->browserExtension();
if ( ok && ext && lstDragURLs.first().isValid() )
emit ext->openURLRequest( lstDragURLs.first() );
}
QScrollView::dropEvent( ev );
}
#endif // !APPLE_CHANGES
void KHTMLView::focusInEvent( QFocusEvent *e )
{
m_part->setCaretVisible();
QScrollView::focusInEvent( e );
}
void KHTMLView::focusOutEvent( QFocusE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -