📄 khtmlview.cpp
字号:
#endif bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEUP_EVENT,mev.innerNode.handle(),true, d->clickCount,_mouse,false,DOM::NodeImpl::MouseRelease); if (d->clickCount > 0#if !APPLE_CHANGES && QPoint(d->clickX-xm,d->clickY-ym).manhattanLength() <= QApplication::startDragDistance()#endif ) dispatchMouseEvent(EventImpl::CLICK_EVENT,mev.innerNode.handle(),true, d->clickCount,_mouse,true,DOM::NodeImpl::MouseRelease); if (!swallowEvent) { khtml::MouseReleaseEvent event( _mouse, xm, ym, mev.url, mev.target, mev.innerNode ); QApplication::sendEvent( m_part, &event ); }}void KHTMLView::keyPressEvent( QKeyEvent *_ke ){ if (m_part->xmlDocImpl() && m_part->xmlDocImpl()->focusNode()) { if (m_part->xmlDocImpl()->focusNode()->dispatchKeyEvent(_ke)) { _ke->accept(); return; } }#if !APPLE_CHANGES int offs = (clipper()->height() < 30) ? clipper()->height() : 30; if (_ke->state()&ShiftButton) switch(_ke->key()) { case Key_Space: if ( d->vmode == QScrollView::AlwaysOff ) _ke->accept(); else scrollBy( 0, -clipper()->height() - offs ); break; } else switch ( _ke->key() ) { case Key_Down: case Key_J: if ( d->vmode == QScrollView::AlwaysOff ) _ke->accept(); else scrollBy( 0, 10 ); break; case Key_Space: case Key_Next: if ( d->vmode == QScrollView::AlwaysOff ) _ke->accept(); else scrollBy( 0, clipper()->height() - offs ); break; case Key_Up: case Key_K: if ( d->vmode == QScrollView::AlwaysOff ) _ke->accept(); else scrollBy( 0, -10 ); break; case Key_Prior: if ( d->vmode == QScrollView::AlwaysOff ) _ke->accept(); else scrollBy( 0, -clipper()->height() + offs ); break; case Key_Right: case Key_L: if ( d->hmode == QScrollView::AlwaysOff ) _ke->accept(); else scrollBy( 10, 0 ); break; case Key_Left: case Key_H: if ( d->hmode == QScrollView::AlwaysOff ) _ke->accept(); else scrollBy( -10, 0 ); break; case Key_Enter: case Key_Return: // ### FIXME: // or even better to HTMLAnchorElementImpl::event() if (m_part->xmlDocImpl()) { NodeImpl *n = m_part->xmlDocImpl()->focusNode(); if (n) n->setActive(); d->originalNode = n; } break; case Key_Home: if ( d->vmode == QScrollView::AlwaysOff ) _ke->accept(); else setContentsPos( 0, 0 ); break; case Key_End: if ( d->vmode == QScrollView::AlwaysOff ) _ke->accept(); else setContentsPos( 0, contentsHeight() - visibleHeight() ); break; default: _ke->ignore(); return; } _ke->accept();#endif}void KHTMLView::keyReleaseEvent(QKeyEvent *_ke){ if(m_part->xmlDocImpl() && m_part->xmlDocImpl()->focusNode()) { // Qt is damn buggy. we receive release events from our child // widgets. therefore, do not support keyrelease event on generic // nodes for now until we found a workaround for the Qt bugs. (Dirk)// if (m_part->xmlDocImpl()->focusNode()->dispatchKeyEvent(_ke)) {// _ke->accept();// return;// }// QScrollView::keyReleaseEvent(_ke); Q_UNUSED(_ke); }}void KHTMLView::contentsContextMenuEvent ( QContextMenuEvent *_ce ){// ### what kind of c*** is that ?#if 0 if (!m_part->xmlDocImpl()) return; int xm = _ce->x(); int ym = _ce->y(); DOM::NodeImpl::MouseEvent mev( _ce->state(), DOM::NodeImpl::MouseMove ); // ### not a mouse event! m_part->xmlDocImpl()->prepareMouseEvent( xm, ym, &mev ); NodeImpl *targetNode = mev.innerNode.handle(); if (targetNode && targetNode->renderer() && targetNode->renderer()->isWidget()) { int absx = 0; int absy = 0; targetNode->renderer()->absolutePosition(absx,absy); QPoint pos(xm-absx,ym-absy); QWidget *w = static_cast<RenderWidget*>(targetNode->renderer())->widget(); QContextMenuEvent cme(_ce->reason(),pos,_ce->globalPos(),_ce->state()); setIgnoreEvents(true); QApplication::sendEvent(w,&cme); setIgnoreEvents(false); }#endif}bool KHTMLView::dispatchDragEvent(int eventId, DOM::NodeImpl *dragTarget, const QPoint &loc, DOM::ClipboardImpl *clipboard){ int clientX, clientY; viewportToContents(loc.x(), loc.y(), clientX, clientY); // Typically we'd use the mouse event's globalX/Y, but we have no mouse event to query, and in practice // the globalX/Y fields are the window level coords anyway. int screenX = loc.x(); int screenY = loc.y(); bool ctrlKey = 0; // FIXME - set up modifiers, grab from AK or CG bool altKey = 0; bool shiftKey = 0; bool metaKey = 0; MouseEventImpl *me = new MouseEventImpl(static_cast<EventImpl::EventId>(eventId), true, true, m_part->xmlDocImpl()->defaultView(), 0, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, 0, 0, clipboard); me->ref(); int exceptioncode = 0; dragTarget->dispatchEvent(me, exceptioncode, true); bool accept = me->defaultPrevented(); me->deref(); return accept;}bool KHTMLView::updateDragAndDrop(const QPoint &loc, DOM::ClipboardImpl *clipboard){ bool accept = false; int xm, ym; viewportToContents(loc.x(), loc.y(), xm, ym); DOM::NodeImpl::MouseEvent mev(0, DOM::NodeImpl::MouseMove); m_part->xmlDocImpl()->prepareMouseEvent(true, xm, ym, &mev); DOM::Node newTarget = mev.innerNode; // Drag events should never go to text nodes (following IE, and proper mouseover/out dispatch) if (newTarget.nodeType() == Node::TEXT_NODE) { newTarget = newTarget.parentNode(); } if (d->dragTarget != newTarget) { // note this ordering is explicitly chosen to match WinIE if (!newTarget.isNull()) { accept = dispatchDragEvent(EventImpl::DRAGENTER_EVENT, newTarget.handle(), loc, clipboard); } if (!d->dragTarget.isNull()) { dispatchDragEvent(EventImpl::DRAGLEAVE_EVENT, d->dragTarget.handle(), loc, clipboard); } } else if (!newTarget.isNull()) { accept = dispatchDragEvent(EventImpl::DRAGOVER_EVENT, newTarget.handle(), loc, clipboard); } d->dragTarget = newTarget; return accept;}void KHTMLView::cancelDragAndDrop(const QPoint &loc, DOM::ClipboardImpl *clipboard){ if (!d->dragTarget.isNull()) { dispatchDragEvent(EventImpl::DRAGLEAVE_EVENT, d->dragTarget.handle(), loc, clipboard); } d->dragTarget = 0;}bool KHTMLView::performDragAndDrop(const QPoint &loc, DOM::ClipboardImpl *clipboard){ bool accept = false; if (!d->dragTarget.isNull()) { accept = dispatchDragEvent(EventImpl::DROP_EVENT, d->dragTarget.handle(), loc, clipboard); } d->dragTarget = 0; return accept;}#if !APPLE_CHANGESbool KHTMLView::focusNextPrevChild( bool next ){ // Now try to find the next child if (m_part->xmlDocImpl()) { focusNextPrevNode(next); if (m_part->xmlDocImpl()->focusNode() != 0) return true; // focus node found } // If we get here, there is no next/previous child to go to, so pass up to the next/previous child in our parent if (m_part->parentPart() && m_part->parentPart()->view()) { return m_part->parentPart()->view()->focusNextPrevChild(next); } return QWidget::focusNextPrevChild(next);}void KHTMLView::doAutoScroll(){ QPoint pos = QCursor::pos(); pos = viewport()->mapFromGlobal( pos ); int xm, ym; viewportToContents(pos.x(), pos.y(), xm, ym); pos = QPoint(pos.x() - viewport()->x(), pos.y() - viewport()->y()); if ( (pos.y() < 0) || (pos.y() > visibleHeight()) || (pos.x() < 0) || (pos.x() > visibleWidth()) ) { ensureVisible( xm, ym, 0, 5 ); }}#endifDOM::NodeImpl *KHTMLView::nodeUnderMouse() const{ return d->underMouse;}bool KHTMLView::scrollTo(const QRect &bounds){ d->scrollingSelf = true; // so scroll events get ignored int x, y, xe, ye; x = bounds.left(); y = bounds.top(); xe = bounds.right(); ye = bounds.bottom(); //kdDebug(6000)<<"scrolling coords: x="<<x<<" y="<<y<<" width="<<xe-x<<" height="<<ye-y<<endl; int deltax; int deltay; int curHeight = visibleHeight(); int curWidth = visibleWidth(); if (ye-y>curHeight-d->borderY) ye = y + curHeight - d->borderY; if (xe-x>curWidth-d->borderX) xe = x + curWidth - d->borderX; // is xpos of target left of the view's border? if (x < contentsX() + d->borderX ) deltax = x - contentsX() - d->borderX; // is xpos of target right of the view's right border? else if (xe + d->borderX > contentsX() + curWidth) deltax = xe + d->borderX - ( contentsX() + curWidth ); else deltax = 0; // is ypos of target above upper border? if (y < contentsY() + d->borderY) deltay = y - contentsY() - d->borderY; // is ypos of target below lower border? else if (ye + d->borderY > contentsY() + curHeight) deltay = ye + d->borderY - ( contentsY() + curHeight ); else deltay = 0; int maxx = curWidth-d->borderX; int maxy = curHeight-d->borderY; int scrollX,scrollY; scrollX = deltax > 0 ? (deltax > maxx ? maxx : deltax) : deltax == 0 ? 0 : (deltax>-maxx ? deltax : -maxx); scrollY = deltay > 0 ? (deltay > maxy ? maxy : deltay) : deltay == 0 ? 0 : (deltay>-maxy ? deltay : -maxy); if (contentsX() + scrollX < 0) scrollX = -contentsX(); else if (contentsWidth() - visibleWidth() - contentsX() < scrollX) scrollX = contentsWidth() - visibleWidth() - contentsX(); if (contentsY() + scrollY < 0) scrollY = -contentsY(); else if (contentsHeight() - visibleHeight() - contentsY() < scrollY) scrollY = contentsHeight() - visibleHeight() - contentsY(); scrollBy(scrollX, scrollY); // generate abs(scroll.) if (scrollX<0) scrollX=-scrollX; if (scrollY<0) scrollY=-scrollY; d->scrollingSelf = false; if ( (scrollX!=maxx) && (scrollY!=maxy) ) return true; else return false;}void KHTMLView::focusNextPrevNode(bool next){ // Sets the focus node of the document to be the node after (or if next is false, before) the current focus node. // Only nodes that are selectable (i.e. for which isSelectable() returns true) are taken into account, and the order // used is that specified in the HTML spec (see DocumentImpl::nextFocusNode() and DocumentImpl::previousFocusNode() // for details). DocumentImpl *doc = m_part->xmlDocImpl(); NodeImpl *oldFocusNode = doc->focusNode(); NodeImpl *newFocusNode; // Find the next/previous node from the current one if (next) newFocusNode = doc->nextFocusNode(oldFocusNode); else newFocusNode = doc->previousFocusNode(oldFocusNode); // If there was previously no focus node and the user has scrolled the document, then instead of picking the first // focusable node in the document, use the first one that lies within the visible area (if possible). if (!oldFocusNode && newFocusNode && d->scrollBarMoved) { kdDebug(6000) << " searching for visible link" << endl; bool visible = false; NodeImpl *toFocus = newFocusNode; while (!visible && toFocus) { QRect focusNodeRect = toFocus->getRect(); if ((focusNodeRect.left() > contentsX()) && (focusNodeRect.right() < contentsX() + visibleWidth()) && (focusNodeRect.top() > contentsY()) && (focusNodeRect.bottom() < contentsY() + visibleHeight())) { // toFocus is visible in the contents area visible = true; } else { // toFocus is _not_ visible in the contents area, pick the next node if (next) toFocus = doc->nextFocusNode(toFocus); else toFocus = doc->previousFocusNode(toFocus); } } if (toFocus) newFocusNode = toFocus; } d->scrollBarMoved = false; if (!newFocusNode) { // No new focus node, scroll to bottom or top depending on next if (next) scrollTo(QRect(contentsX()+visibleWidth()/2,contentsHeight(),0,0)); else scrollTo(QRect(contentsX()+visibleWidth()/2,0,0,0)); } else { // EDIT FIXME: if it's an editable element, activate the caret // otherwise, hide it if (newFocusNode->isContentEditable()) { // make caret visible } else { // hide caret } // Scroll the view as necessary to ensure that the new focus node is visible if (oldFocusNode) { if (!scrollTo(newFocusNode->getRect())) return; } else { ensureVisible(contentsX(), next ? 0: contentsHeight()); } } // Set focus node on the document m_part->xmlDocImpl()->setFocusNode(newFocusNode); emit m_part->nodeActivated(Node(newFocusNode));#if 0 if (newFocusNode) { // this does not belong here. it should run a query on the tree (Dirk) // I'll fix this very particular part of the code soon when I cleaned // up the positioning code // If the newly focussed node is a link, notify the part HTMLAnchorElementImpl *anchor = 0; if ((newFocusNode->id() == ID_A || newFocusNode->id() == ID_AREA)) anchor = static_cast<HTMLAnchorElementImpl *>(newFocusNode); if (anchor && !anchor->areaHref().isNull()) m_part->overURL(anchor->areaHref().string(), 0); else m_part->overURL(QString(), 0); }#endif}void KHTMLView::setMediaType( const QString &medium ){ m_medium = medium;}QString KHTMLView::mediaType() const{#if APPLE_CHANGES // See if we have an override type. QString overrideType = KWQ(m_part)->overrideMediaType(); if (!overrideType.isNull()) return overrideType;#endif return m_medium;}#if !APPLE_CHANGESvoid KHTMLView::print(){ if(!m_part->xmlDocImpl()) return; khtml::RenderCanvas *root = static_cast<khtml::RenderCanvas *>(m_part->xmlDocImpl()->renderer()); if(!root) return; // this only works on Unix - we assume 72dpi KPrinter *printer = new KPrinter(QPrinter::PrinterResolution); printer->addDialogPage(new KHTMLPrintSettings()); if(printer->setup(this)) { viewport()->setCursor( waitCursor ); // only viewport(), no QApplication::, otherwise we get the busy cursor in kdeprint's dialogs // set up KPrinter printer->setFullPage(false); printer->setCreator("KDE 3.0 HTML Library"); QString docname = m_part->xmlDocImpl()->URL(); if ( !docname.isEmpty() ) printer->setDocName(docname); QPainter *p = new QPainter; p->begin( printer ); khtml::setPrintPainter( p ); m_part->xmlDocImpl()->setPaintDevice( printer ); QString oldMediaType = mediaType(); setMediaType( "print" ); // We ignore margin settings for html and body when printing // and use the default margins from the print-system // (In Qt 3.0.x the default margins are hardcoded in Qt) m_part->xmlDocImpl()->setPrintStyleSheet( printer->option("kde-khtml-printfriendly") == "true" ?
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -