⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 khtmlview.cpp

📁 手机浏览器源码程序,功能强大
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    }
}

void KHTMLView::viewportMouseDoubleClickEvent( QMouseEvent *_mouse )
{
    if(!m_part->xmlDocImpl()) return;

    SharedPtr<KHTMLView> protector(this);

    int xm, ym;
    viewportToContents(_mouse->x(), _mouse->y(), xm, ym);

    //kdDebug( 6000 ) << "mouseDblClickEvent: x=" << xm << ", y=" << ym << endl;

    d->isDoubleClick = true;
#if APPLE_CHANGES
    // We get this instead of a second mouse-up
    d->mousePressed = false;
#endif

    DOM::NodeImpl::MouseEvent mev( _mouse->stateAfter(), DOM::NodeImpl::MouseDblClick );
    m_part->xmlDocImpl()->prepareMouseEvent( false, xm, ym, &mev );

#if APPLE_CHANGES
    if (KWQ(m_part)->passSubframeEventToSubframe(mev))
        return;

    d->clickCount = _mouse->clickCount();
    bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEUP_EVENT,mev.innerNode.handle(),true,
                                           d->clickCount,_mouse,false,DOM::NodeImpl::MouseRelease);

    if (mev.innerNode.handle() == d->clickNode)
        dispatchMouseEvent(EventImpl::CLICK_EVENT,mev.innerNode.handle(),true,
               d->clickCount,_mouse,true,DOM::NodeImpl::MouseRelease);

    // Qt delivers a release event AND a double click event.
    if (!swallowEvent) {
    khtml::MouseReleaseEvent event1( _mouse, xm, ym, mev.url, mev.target, mev.innerNode );
    QApplication::sendEvent( m_part, &event1 );

    khtml::MouseDoubleClickEvent event2( _mouse, xm, ym, mev.url, mev.target, mev.innerNode );
    QApplication::sendEvent( m_part, &event2 );
    }
#else
    // We do the same thing as viewportMousePressEvent() here, since the DOM does not treat
    // single and double-click events as separate (only the detail, i.e. number of clicks differs)
    // In other words an even detail value for a mouse click event means a double click, and an
    // odd detail value means a single click
    bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEDOWN_EVENT,mev.innerNode.handle(),true,
                                           d->clickCount,_mouse,true,DOM::NodeImpl::MouseDblClick);

    if (!swallowEvent) {
    khtml::MouseDoubleClickEvent event( _mouse, xm, ym, mev.url, mev.target, mev.innerNode );
    QApplication::sendEvent( m_part, &event );

    // ###
    //if ( url.length() )
    //emit doubleClick( url.string(), _mouse->button() );
    }
#endif

    invalidateClick();
}

static bool isSubmitImage(DOM::NodeImpl *node)
{
    return node
        && node->isHTMLElement()
        && node->id() == ID_INPUT
        && static_cast<HTMLInputElementImpl*>(node)->inputType() == HTMLInputElementImpl::IMAGE;
}

void KHTMLView::viewportMouseMoveEvent( QMouseEvent * _mouse )
{
    // in Radar 3703768 we saw frequent crashes apparently due to the
    // part being null here, which seems impossible, so check for nil
    // but also assert so that we can try to figure this out in debug
    // builds, if it happens.
    assert(m_part);
    if(!m_part || !m_part->xmlDocImpl()) return;

    int xm, ym;
    viewportToContents(_mouse->x(), _mouse->y(), xm, ym);

    // Treat mouse move events while the mouse is pressed as "read-only" in prepareMouseEvent.
    // This means that :hover and :active freeze in the state they were in when the mouse
    // was pressed, rather than updating for nodes the mouse moves over as you hold the mouse down.
    DOM::NodeImpl::MouseEvent mev( _mouse->stateAfter(), DOM::NodeImpl::MouseMove );
    m_part->xmlDocImpl()->prepareMouseEvent( d->mousePressed, xm, ym, &mev );
#if APPLE_CHANGES
    if (KWQ(m_part)->passSubframeEventToSubframe(mev))
        return;
#endif

    bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEMOVE_EVENT,mev.innerNode.handle(),false,
                                           0,_mouse,true,DOM::NodeImpl::MouseMove);

#if !APPLE_CHANGES
    if (d->clickCount > 0 &&
        QPoint(d->clickX-xm,d->clickY-ym).manhattanLength() > QApplication::startDragDistance()) {
    d->clickCount = 0;  // moving the mouse outside the threshold invalidates the click
    }
#endif

    // execute the scheduled script. This is to make sure the mouseover events come after the mouseout events
    m_part->executeScheduledScript();

    NodeImpl *node = mev.innerNode.handle();
    RenderObject *renderer = node ? node->renderer() : 0;
    RenderStyle *style = renderer ? renderer->style() : 0;

    QCursor c;
    if (style && style->cursor() == CURSOR_AUTO && style->cursorImage()
        && !(style->cursorImage()->pixmap().isNull())) {
        /* First of all it works: Check out http://www.iam.unibe.ch/~schlpbch/cursor.html
         *
         * But, I don't know what exactly we have to do here: rescale to 32*32, change to monochrome..
         */
        //kdDebug( 6000 ) << "using custom cursor" << endl;
        const QPixmap p = style->cursorImage()->pixmap();
        // ### fix
        c = QCursor(p);
    }

    switch ( style ? style->cursor() : CURSOR_AUTO ) {
    case CURSOR_AUTO:
        if ( d->mousePressed && m_part->hasSelection() )
        // during selection, use an IBeam no matter what we're over
        c = KCursor::ibeamCursor();
        else if ( (!mev.url.isNull() || isSubmitImage(node)) && m_part->settings()->changeCursor() )
            c = m_part->urlCursor();
        else if ( (node && node->isContentEditable()) || (renderer && renderer->isText() && renderer->canSelect()) )
            c = KCursor::ibeamCursor();
        break;
    case CURSOR_CROSS:
        c = KCursor::crossCursor();
        break;
    case CURSOR_POINTER:
        c = m_part->urlCursor();
        break;
    case CURSOR_MOVE:
        c = KCursor::sizeAllCursor();
        break;
    case CURSOR_E_RESIZE:
#if APPLE_CHANGES
        c = KCursor::eastResizeCursor();
        break;
#endif
    case CURSOR_W_RESIZE:
#if APPLE_CHANGES
        c = KCursor::westResizeCursor();
#else
        c = KCursor::sizeHorCursor();
#endif
        break;
    case CURSOR_N_RESIZE:
#if APPLE_CHANGES
        c = KCursor::northResizeCursor();
        break;
#endif
    case CURSOR_S_RESIZE:
#if APPLE_CHANGES
        c = KCursor::southResizeCursor();
#else
        c = KCursor::sizeVerCursor();
#endif
        break;
    case CURSOR_NE_RESIZE:
#if APPLE_CHANGES
        c = KCursor::northEastResizeCursor();
        break;
#endif
    case CURSOR_SW_RESIZE:
#if APPLE_CHANGES
        c = KCursor::southWestResizeCursor();
#else
        c = KCursor::sizeBDiagCursor();
#endif
        break;
    case CURSOR_NW_RESIZE:
#if APPLE_CHANGES
        c = KCursor::northWestResizeCursor();
        break;
#endif
    case CURSOR_SE_RESIZE:
#if APPLE_CHANGES
        c = KCursor::southEastResizeCursor();
#else
        c = KCursor::sizeFDiagCursor();
#endif
        break;
    case CURSOR_TEXT:
        c = KCursor::ibeamCursor();
        break;
    case CURSOR_WAIT:
        c = KCursor::waitCursor();
        break;
    case CURSOR_HELP:
        c = KCursor::whatsThisCursor();
        break;
    case CURSOR_DEFAULT:
        break;
    }

    QWidget *vp = viewport();
    if ( vp->cursor().handle() != c.handle() ) {
        if( c.handle() == KCursor::arrowCursor().handle())
            vp->unsetCursor();
        else
            vp->setCursor( c );
    }
    d->prevMouseX = xm;
    d->prevMouseY = ym;

    if (!swallowEvent) {
        khtml::MouseMoveEvent event( _mouse, xm, ym, mev.url, mev.target, mev.innerNode );
        QApplication::sendEvent( m_part, &event );
    }
}

void KHTMLView::resetCursor()
{
    viewport()->unsetCursor();
}

void KHTMLView::invalidateClick()
{
    d->clickCount = 0;
    if (d->clickNode) {
        d->clickNode->deref();
        d->clickNode = 0;
    }
}

void KHTMLView::viewportMouseReleaseEvent( QMouseEvent * _mouse )
{
    if ( !m_part->xmlDocImpl() ) return;

    SharedPtr<KHTMLView> protector(this);

    int xm, ym;
    viewportToContents(_mouse->x(), _mouse->y(), xm, ym);

    d->mousePressed = false;

    //kdDebug( 6000 ) << "\nmouseReleaseEvent: x=" << xm << ", y=" << ym << endl;

    DOM::NodeImpl::MouseEvent mev( _mouse->stateAfter(), DOM::NodeImpl::MouseRelease );
    m_part->xmlDocImpl()->prepareMouseEvent( false, xm, ym, &mev );

#if APPLE_CHANGES
    if (KWQ(m_part)->passSubframeEventToSubframe(mev))
        return;
#endif

    bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEUP_EVENT,mev.innerNode.handle(),true,
                                           d->clickCount,_mouse,false,DOM::NodeImpl::MouseRelease);

    if (d->clickCount > 0 && mev.innerNode.handle() == d->clickNode
#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 );
    }

    invalidateClick();
}

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();
        }
            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);
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -