📄 khtmlview.cpp
字号:
}
}
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 + -