📄 khtmlview.cpp
字号:
"* { 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; }" ); QPaintDeviceMetrics metrics( printer ); // this is a simple approximation... we layout the document // according to the width of the page, then just cut // pages without caring about the content. We should do better // in the future, but for the moment this is better than no // printing support kdDebug(6000) << "printing: physical page width = " << metrics.width() << " height = " << metrics.height() << endl; root->setPrintingMode(true); root->setWidth(metrics.width()); m_part->xmlDocImpl()->styleSelector()->computeFontSizes(&metrics); m_part->xmlDocImpl()->updateStyleSelector(); root->setPrintImages( printer->option("kde-khtml-printimages") == "true"); root->setNeedsLayoutAndMinMaxRecalc(); root->layout(); // 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 pageHeight = metrics.height(); int pageWidth = metrics.width(); p->setClipRect(0,0, pageWidth, pageHeight); if(root->docWidth() > metrics.width()) { double scale = ((double) metrics.width())/((double) root->docWidth());#ifndef QT_NO_TRANSFORMATIONS p->scale(scale, scale);#endif pageHeight = (int) (pageHeight/scale); pageWidth = (int) (pageWidth/scale); } 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_CHANGESvoid 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_CHANGESQStringList 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);}#endifbool 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); int screenX = _mouse->globalX(); int screenY = _mouse->globalY(); 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); 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, 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 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(); 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(d->isDoubleClick ? EventImpl::KHTML_DBLCLICK_EVENT : 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() || me->defaultPrevented()) swallowEvent = true; me->deref(); } 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 (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_WHEELEVENTvoid 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_CHANGESvoid 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_CHANGESvoid KHTMLView::focusInEvent( QFocusEvent *e ){ m_part->setSelectionVisible(); QScrollView::focusInEvent( e );}void KHTMLView::focusOutEvent( QFocusEvent *e ){ m_part->stopAutoScroll(); m_part->setSelectionVisible(false); QScrollView::focusOutEvent( e );}void KHTMLView::slotScrollBarMoved(){ if (!d->scrollingSelf) d->scrollBarMoved = true;}void KHTMLView::repaintRectangle(const QRect& r, bool immediate){ updateContents(r, immediate);}void KHTMLView::timerEvent ( QTimerEvent *e ){ if (e->timerId()==d->layoutTimerId) layout();}void KHTMLView::scheduleRelayout(){ if (!d->layoutSchedulingEnabled) return; if (d->layoutTimerId || (m_part->xmlDocImpl() && !m_part->xmlDocImpl()->shouldScheduleLayout())) return; d->allDataReceivedWhenTimerSet = m_part->xmlDocImpl() && !m_part->xmlDocImpl()->allDataReceived();#ifdef INSTRUMENT_LAYOUT_SCHEDULING if (!m_part->xmlDocImpl()->ownerElement()) printf("Scheduling layout for %d\n", m_part->xmlDocImpl()->minimumLayoutDelay());#endif d->layoutTimerId = startTimer(m_part->xmlDocImpl() ? m_part->xmlDocImpl()->minimumLayoutDelay() : 0);}bool KHTMLView::haveDelayedLayoutScheduled(){ return d->layoutTimerId && d->allDataReceivedWhenTimerSet;}void KHTMLView::unscheduleRelayout(){ if (!d->layoutTimerId) return; killTimer(d->layoutTimerId); d->layoutTimerId = 0; d->allDataReceivedWhenTimerSet = false;}bool KHTMLView::isTransparent() const{ return d->isTransparent;}void KHTMLView::setTransparent(bool isTransparent){ d->isTransparent = isTransparent;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -