/** * This file is part of the HTML widget for KDE. * * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) * Copyright (C) 2000-2003 Dirk Mueller (mueller@kde.org) * Copyright (C) 2003 Apple Computer, Inc. * Copyright (C) 2004 Germain Garand (germain@ebooksfrance.org) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "render_replaced.h" #include "render_layer.h" #include "render_canvas.h" #include "render_line.h" #include "render_arena.h" #include #include #include #include #include #include #include #include #include #include "tdehtml_ext.h" #include "tdehtmlview.h" #include "xml/dom2_eventsimpl.h" #include "tdehtml_part.h" #include "xml/dom_docimpl.h" #include bool tdehtml::allowWidgetPaintEvents = false; using namespace tdehtml; using namespace DOM; RenderReplaced::RenderReplaced(DOM::NodeImpl* node) : RenderBox(node) { // init RenderObject attributes setReplaced(true); m_intrinsicWidth = 300; m_intrinsicHeight = 150; } void RenderReplaced::calcMinMaxWidth() { TDEHTMLAssert( !minMaxKnown()); #ifdef DEBUG_LAYOUT kdDebug( 6040 ) << "RenderReplaced::calcMinMaxWidth() known=" << minMaxKnown() << endl; #endif m_width = calcReplacedWidth(); m_width = calcBoxWidth( m_width ); if ( style()->width().isPercent() || style()->height().isPercent() || style()->maxWidth().isPercent() || style()->maxHeight().isPercent() || style()->minWidth().isPercent() || style()->minHeight().isPercent() ) { m_minWidth = 0; m_maxWidth = m_width; } else m_minWidth = m_maxWidth = m_width; setMinMaxKnown(); } void RenderReplaced::position(InlineBox* box, int /*from*/, int /*len*/, bool /*reverse*/) { setPos( box->xPos(), box->yPos() ); } // ----------------------------------------------------------------------------- RenderWidget::RenderWidget(DOM::NodeImpl* node) : RenderReplaced(node) { m_widget = 0; // a widget doesn't support being anonymous assert(!isAnonymous()); m_view = node->getDocument()->view(); m_arena.reset(renderArena()); m_resizePending = false; m_discardResizes = false; m_isTDEHTMLWidget = false; m_needsMask = false; // this is no real reference counting, its just there // to make sure that we're not deleted while we're recursed // in an eventFilter of the widget ref(); } void RenderWidget::detach() { remove(); deleteInlineBoxes(); if ( m_widget ) { if ( m_view ) { m_view->setWidgetVisible(this, false); m_view->removeChild( m_widget ); } m_widget->removeEventFilter( this ); m_widget->setMouseTracking( false ); } deref(); } RenderWidget::~RenderWidget() { TDEHTMLAssert( refCount() <= 0 ); if(m_widget) { m_widget->hide(); m_widget->deleteLater(); } } class TQWidgetResizeEvent : public TQEvent { public: enum { Type = TQEvent::User + 0xbee }; TQWidgetResizeEvent( int _w, int _h ) : TQEvent( ( TQEvent::Type ) Type ), w( _w ), h( _h ) {} int w; int h; }; void RenderWidget::resizeWidget( int w, int h ) { // ugly hack to limit the maximum size of the widget ( as X11 has problems if // its bigger ) h = kMin( h, 3072 ); w = kMin( w, 2000 ); if (m_widget->width() != w || m_widget->height() != h) { m_resizePending = isTDEHTMLWidget(); ref(); element()->ref(); TQApplication::postEvent( this, new TQWidgetResizeEvent( w, h ) ); element()->deref(); deref(); } } void RenderWidget::cancelPendingResize() { if (!m_widget) return; m_discardResizes = true; TQApplication::sendPostedEvents(this, TQWidgetResizeEvent::Type); m_discardResizes = false; } bool RenderWidget::event( TQEvent *e ) { if ( m_widget && (e->type() == (TQEvent::Type)TQWidgetResizeEvent::Type) ) { m_resizePending = false; if (m_discardResizes) return true; TQWidgetResizeEvent *re = static_cast(e); m_widget->resize( re->w, re->h ); repaint(); } // eat all events - except if this is a frame (in which case TDEHTMLView handles it all) if ( ::tqt_cast( m_widget ) ) return TQObject::event( e ); return true; } void RenderWidget::flushWidgetResizes() //static { TQApplication::sendPostedEvents( 0, TQWidgetResizeEvent::Type ); } void RenderWidget::setQWidget(TQWidget *widget) { if (widget != m_widget) { if (m_widget) { m_widget->removeEventFilter(this); disconnect( m_widget, TQ_SIGNAL( destroyed()), this, TQ_SLOT( slotWidgetDestructed())); m_widget->hide(); m_widget->deleteLater(); //Might happen due to event on the widget, so be careful m_widget = 0; } m_widget = widget; if (m_widget) { connect( m_widget, TQ_SIGNAL( destroyed()), this, TQ_SLOT( slotWidgetDestructed())); m_widget->installEventFilter(this); if ( (m_isTDEHTMLWidget = !strcmp(m_widget->name(), "__tdehtml")) && !::tqt_cast(m_widget)) m_widget->setBackgroundMode( TQWidget::NoBackground ); if (m_widget->focusPolicy() > TQWidget::StrongFocus) m_widget->setFocusPolicy(TQWidget::StrongFocus); // if we've already received a layout, apply the calculated space to the // widget immediately, but we have to have really been full constructed (with a non-null // style pointer). if (!needsLayout() && style()) { resizeWidget( m_width-borderLeft()-borderRight()-paddingLeft()-paddingRight(), m_height-borderTop()-borderBottom()-paddingTop()-paddingBottom() ); } else setPos(xPos(), -500000); } m_view->setWidgetVisible(this, false); m_view->addChild( m_widget, 0, -500000); if ( m_widget ) m_widget->hide(); m_resizePending = false; } } void RenderWidget::layout( ) { TDEHTMLAssert( needsLayout() ); TDEHTMLAssert( minMaxKnown() ); if ( m_widget ) { resizeWidget( m_width-borderLeft()-borderRight()-paddingLeft()-paddingRight(), m_height-borderTop()-borderBottom()-paddingTop()-paddingBottom() ); if (!isTDEHTMLWidget() && !isFrame() && !m_needsMask) { m_needsMask = true; RenderLayer* rl = enclosingStackingContext(); RenderLayer* el = enclosingLayer(); while (rl && el && el != rl) { if (el->renderer()->style()->position() != STATIC) { m_needsMask = false; break; } el = el->parent(); } if (m_needsMask) { if (rl) rl->setHasOverlaidWidgets(); canvas()->setNeedsWidgetMasks(); } } } setNeedsLayout(false); } void RenderWidget::updateFromElement() { if (m_widget) { // Color: TQColor color = style()->color(); TQColor backgroundColor = style()->backgroundColor(); if ( color.isValid() || backgroundColor.isValid() ) { TQPalette pal(TQApplication::palette(m_widget)); int contrast_ = TDEGlobalSettings::contrast(); int highlightVal = 100 + (2*contrast_+4)*16/10; int lowlightVal = 100 + (2*contrast_+4)*10; if (backgroundColor.isValid()) { if (!isTDEHTMLWidget()) widget()->setEraseColor(backgroundColor ); for ( int i = 0; i < TQPalette::NColorGroups; ++i ) { pal.setColor( (TQPalette::ColorGroup)i, TQColorGroup::Background, backgroundColor ); pal.setColor( (TQPalette::ColorGroup)i, TQColorGroup::Light, backgroundColor.light(highlightVal) ); pal.setColor( (TQPalette::ColorGroup)i, TQColorGroup::Dark, backgroundColor.dark(lowlightVal) ); pal.setColor( (TQPalette::ColorGroup)i, TQColorGroup::Mid, backgroundColor.dark(120) ); pal.setColor( (TQPalette::ColorGroup)i, TQColorGroup::Midlight, backgroundColor.light(110) ); pal.setColor( (TQPalette::ColorGroup)i, TQColorGroup::Button, backgroundColor ); pal.setColor( (TQPalette::ColorGroup)i, TQColorGroup::Base, backgroundColor ); } } if ( color.isValid() ) { struct ColorSet { TQPalette::ColorGroup cg; TQColorGroup::ColorRole cr; }; const struct ColorSet toSet [] = { { TQPalette::Active, TQColorGroup::Foreground }, { TQPalette::Active, TQColorGroup::ButtonText }, { TQPalette::Active, TQColorGroup::Text }, { TQPalette::Inactive, TQColorGroup::Foreground }, { TQPalette::Inactive, TQColorGroup::ButtonText }, { TQPalette::Inactive, TQColorGroup::Text }, { TQPalette::Disabled,TQColorGroup::ButtonText }, { TQPalette::NColorGroups, TQColorGroup::NColorRoles }, }; const ColorSet *set = toSet; while( set->cg != TQPalette::NColorGroups ) { pal.setColor( set->cg, set->cr, color ); ++set; } TQColor disfg = color; int h, s, v; disfg.hsv( &h, &s, &v ); if (v > 128) // dark bg, light fg - need a darker disabled fg disfg = disfg.dark(lowlightVal); else if (disfg != TQt::black) // light bg, dark fg - need a lighter disabled fg - but only if !black disfg = disfg.light(highlightVal); else // black fg - use darkgray disabled fg disfg = TQt::darkGray; pal.setColor(TQPalette::Disabled,TQColorGroup::Foreground,disfg); } m_widget->setPalette(pal); } else m_widget->unsetPalette(); // Border: TQFrame* frame = ::tqt_cast(m_widget); if (frame) { if (shouldPaintBackgroundOrBorder()) { frame->setFrameShape(TQFrame::NoFrame); } } } RenderReplaced::updateFromElement(); } void RenderWidget::slotWidgetDestructed() { if (m_view) m_view->setWidgetVisible(this, false); m_widget = 0; } void RenderWidget::setStyle(RenderStyle *_style) { RenderReplaced::setStyle(_style); if(m_widget) { m_widget->setFont(style()->font()); if (style()->visibility() != VISIBLE) { if (m_view) m_view->setWidgetVisible(this, false); m_widget->hide(); } } // Don't paint borders if the border-style is native // or borders are not supported on this widget if (!canHaveBorder() || (style()->borderLeftStyle() == BNATIVE && style()->borderRightStyle() == BNATIVE && style()->borderTopStyle() == BNATIVE && style()->borderBottomStyle() == BNATIVE)) { setShouldPaintBackgroundOrBorder(false); } } void RenderWidget::paint(PaintInfo& paintInfo, int _tx, int _ty) { _tx += m_x; _ty += m_y; if (shouldPaintBackgroundOrBorder() && (paintInfo.phase == PaintActionChildBackground || paintInfo.phase == PaintActionChildBackgrounds)) paintBoxDecorations(paintInfo, _tx, _ty); if (!m_widget || !m_view || paintInfo.phase != PaintActionForeground) return; // not visible or not even once layouted if (style()->visibility() != VISIBLE || m_y <= -500000 || m_resizePending ) return; if ( (_ty > paintInfo.r.bottom()) || (_ty + m_height <= paintInfo.r.top()) || (_tx + m_width <= paintInfo.r.left()) || (_tx > paintInfo.r.right()) ) return; int xPos = _tx+borderLeft()+paddingLeft(); int yPos = _ty+borderTop()+paddingTop(); bool tdehtmlw = isTDEHTMLWidget(); int childw = m_widget->width(); int childh = m_widget->height(); if ( (childw == 2000 || childh == 3072) && m_widget->inherits( "TDEHTMLView" ) ) { TDEHTMLView *vw = static_cast(m_widget); int cy = m_view->contentsY(); int ch = m_view->visibleHeight(); int childx = m_view->childX( m_widget ); int childy = m_view->childY( m_widget ); int xNew = xPos; int yNew = childy; // tqDebug("cy=%d, ch=%d, childy=%d, childh=%d", cy, ch, childy, childh ); if ( childh == 3072 ) { if ( cy + ch > childy + childh ) { yNew = cy + ( ch - childh )/2; } else if ( cy < childy ) { yNew = cy + ( ch - childh )/2; } // tqDebug("calculated yNew=%d", yNew); } yNew = kMin( yNew, yPos + m_height - childh ); yNew = kMax( yNew, yPos ); if ( yNew != childy || xNew != childx ) { if ( vw->contentsHeight() < yNew - yPos + childh ) vw->resizeContents( vw->contentsWidth(), yNew - yPos + childh ); vw->setContentsPos( xNew - xPos, yNew - yPos ); } xPos = xNew; yPos = yNew; } m_view->setWidgetVisible(this, true); m_view->addChild(m_widget, xPos, yPos ); m_widget->show(); if (tdehtmlw) paintWidget(paintInfo, m_widget, xPos, yPos); } #include // The PaintBuffer class provides a shared buffer for widget painting. // // It will grow to encompass the biggest widget encountered, in order to avoid // constantly resizing. // When it grows over maxPixelBuffering, it periodically checks if such a size // is still needed. If not, it shrinks down to the biggest size < maxPixelBuffering // that was requested during the overflow lapse. class PaintBuffer: public TQObject { public: static const int maxPixelBuffering = 320*200; static const int leaseTime = 20*1000; static TQPixmap *grab( TQSize s = TQSize() ) { if (!m_inst) m_inst = new PaintBuffer; return m_inst->getBuf( s ); } static void release() { m_inst->m_grabbed = false; } protected: PaintBuffer(): m_overflow(false), m_grabbed(false), m_timer(0), m_resetWidth(0), m_resetHeight(0) {}; void timerEvent(TQTimerEvent* e) { assert( m_timer == e->timerId() ); if (m_grabbed) return; m_buf.resize(m_resetWidth, m_resetHeight); m_resetWidth = m_resetHeight = 0; killTimer( m_timer ); m_timer = 0; } TQPixmap *getBuf( TQSize s ) { assert( !m_grabbed ); if (s.isEmpty()) return 0; m_grabbed = true; bool cur_overflow = false; int nw = kMax(m_buf.width(), s.width()); int nh = kMax(m_buf.height(), s.height()); if (!m_overflow && (nw*nh > maxPixelBuffering)) cur_overflow = true; if (nw != m_buf.width() || nh != m_buf.height()) m_buf.resize(nw, nh); if (cur_overflow) { m_overflow = true; m_timer = startTimer( leaseTime ); } else if (m_overflow) { if( s.width()*s.height() > maxPixelBuffering ) { killTimer( m_timer ); m_timer = startTimer( leaseTime ); } else { if (s.width() > m_resetWidth) m_resetWidth = s.width(); if (s.height() > m_resetHeight) m_resetHeight = s.height(); } } return &m_buf; } private: static PaintBuffer* m_inst; TQPixmap m_buf; bool m_overflow; bool m_grabbed; int m_timer; int m_resetWidth; int m_resetHeight; }; PaintBuffer *PaintBuffer::m_inst = 0; static void copyWidget(const TQRect& r, TQPainter *p, TQWidget *widget, int tx, int ty) { if (r.isNull() || r.isEmpty() ) return; TQRegion blit(r); TQValueVector cw; TQValueVector cr; if (!widget->childrenListObject().isEmpty()) { // build region TQObjectList childWidgets = widget->childrenListObject(); TQObjectListIterator it(childWidgets); for (; it.current(); ++it) { TQWidget* const w = ::tqt_cast(it.current()); if ( w && !w->isTopLevel() && !w->isHidden()) { TQRect r2 = w->geometry(); blit -= r2; r2 = r2.intersect( r ); r2.moveBy(-w->x(), -w->y()); cr.append(r2); cw.append(w); } } } TQMemArray br = blit.rects(); const int cnt = br.size(); const bool external = p->device()->isExtDev(); TQPixmap* const pm = PaintBuffer::grab( widget->size() ); if (!pm) { kdWarning(6040) << "Rendering widget [ " << widget->className() << " ] failed due to invalid size." << endl; return; } // fill background if ( external ) { // even hackier! TQPainter pt( pm ); const TQColor c = widget->colorGroup().base(); for (int i = 0; i < cnt; ++i) pt.fillRect( br[i], c ); } else { TQRect dr; for (int i = 0; i < cnt; ++i ) { dr = br[i]; dr.moveBy( tx, ty ); dr = p->xForm( dr ); bitBlt(pm, br[i].topLeft(), p->device(), dr); } } // send paint event TQPainter::redirect(widget, pm); TQPaintEvent e( r, false ); TQApplication::sendEvent( widget, &e ); TQPainter::redirect(widget, 0); // transfer result if ( external ) for ( int i = 0; i < cnt; ++i ) p->drawPixmap(TQPoint(tx+br[i].x(), ty+br[i].y()), *pm, br[i]); else for ( int i = 0; i < cnt; ++i ) bitBlt(p->device(), p->xForm( TQPoint(tx, ty) + br[i].topLeft() ), pm, br[i]); // cleanup and recurse PaintBuffer::release(); TQValueVector::iterator cwit = cw.begin(); TQValueVector::iterator cwitEnd = cw.end(); TQValueVector::const_iterator crit = cr.begin(); for (; cwit != cwitEnd; ++cwit, ++crit) copyWidget(*crit, p, *cwit, tx+(*cwit)->x(), ty+(*cwit)->y()); } void RenderWidget::paintWidget(PaintInfo& pI, TQWidget *widget, int tx, int ty) { TQPainter* const p = pI.p; allowWidgetPaintEvents = true; const bool dsbld = TQSharedDoubleBuffer::isDisabled(); TQSharedDoubleBuffer::setDisabled(true); TQRect rr = pI.r; rr.moveBy(-tx, -ty); const TQRect r = widget->rect().intersect( rr ); copyWidget(r, p, widget, tx, ty); TQSharedDoubleBuffer::setDisabled(dsbld); allowWidgetPaintEvents = false; } bool RenderWidget::eventFilter(TQObject* /*o*/, TQEvent* e) { // no special event processing if this is a frame (in which case TDEHTMLView handles it all) if ( ::tqt_cast( m_widget ) ) return false; if ( !element() ) return true; static bool directToWidget = false; if (directToWidget) { //We're trying to get the event to the widget //promptly. So get out of here.. return false; } ref(); element()->ref(); bool filtered = false; //kdDebug() << "RenderWidget::eventFilter type=" << e->type() << endl; switch(e->type()) { case TQEvent::FocusOut: // First, forward it to the widget, so that Qt gets a precise // state of the focus before pesky JS can try changing it.. directToWidget = true; TQApplication::sendEvent(m_widget, e); directToWidget = false; filtered = true; //We already delivered it! // Don't count popup as a valid reason for losing the focus // (example: opening the options of a select combobox shouldn't emit onblur) if ( static_cast(e)->reason() != TQFocusEvent::Popup ) handleFocusOut(); break; case TQEvent::FocusIn: //As above, forward to the widget first... directToWidget = true; TQApplication::sendEvent(m_widget, e); directToWidget = false; filtered = true; //We already delivered it! //kdDebug(6000) << "RenderWidget::eventFilter captures FocusIn" << endl; element()->getDocument()->setFocusNode(element()); // if ( isEditable() ) { // TDEHTMLPartBrowserExtension *ext = static_cast( element()->view->part()->browserExtension() ); // if ( ext ) ext->editableWidgetFocused( m_widget ); // } break; case TQEvent::KeyPress: case TQEvent::KeyRelease: // TODO this seems wrong - Qt events are not correctly translated to DOM ones, // like in TDEHTMLView::dispatchKeyEvent() if (element()->dispatchKeyEvent(static_cast(e),false)) filtered = true; break; case TQEvent::Wheel: if (widget()->parentWidget() == view()->viewport()) { // don't allow the widget to react to wheel event unless its // currently focused. this avoids accidentally changing a select box // or something while wheeling a webpage. if (tqApp->focusWidget() != widget() && widget()->focusPolicy() <= TQWidget::StrongFocus) { static_cast(e)->ignore(); TQApplication::sendEvent(view(), e); filtered = true; } } break; default: break; }; element()->deref(); // stop processing if the widget gets deleted, but continue in all other cases if (hasOneRef()) filtered = true; deref(); return filtered; } void RenderWidget::EventPropagator::sendEvent(TQEvent *e) { switch(e->type()) { case TQEvent::MouseButtonPress: mousePressEvent(static_cast(e)); break; case TQEvent::MouseButtonRelease: mouseReleaseEvent(static_cast(e)); break; case TQEvent::MouseButtonDblClick: mouseDoubleClickEvent(static_cast(e)); break; case TQEvent::MouseMove: mouseMoveEvent(static_cast(e)); break; case TQEvent::KeyPress: keyPressEvent(static_cast(e)); break; case TQEvent::KeyRelease: keyReleaseEvent(static_cast(e)); break; default: break; } } void RenderWidget::ScrollViewEventPropagator::sendEvent(TQEvent *e) { switch(e->type()) { case TQEvent::MouseButtonPress: viewportMousePressEvent(static_cast(e)); break; case TQEvent::MouseButtonRelease: viewportMouseReleaseEvent(static_cast(e)); break; case TQEvent::MouseButtonDblClick: viewportMouseDoubleClickEvent(static_cast(e)); break; case TQEvent::MouseMove: viewportMouseMoveEvent(static_cast(e)); break; case TQEvent::KeyPress: keyPressEvent(static_cast(e)); break; case TQEvent::KeyRelease: keyReleaseEvent(static_cast(e)); break; default: break; } } bool RenderWidget::handleEvent(const DOM::EventImpl& ev) { bool ret = false; switch(ev.id()) { case EventImpl::MOUSEDOWN_EVENT: case EventImpl::MOUSEUP_EVENT: case EventImpl::MOUSEMOVE_EVENT: { if (!ev.isMouseEvent()) break; const MouseEventImpl &me = static_cast(ev); TQMouseEvent* const qme = me.qEvent(); int absx = 0; int absy = 0; absolutePosition(absx, absy); TQPoint p(me.clientX() - absx + m_view->contentsX(), me.clientY() - absy + m_view->contentsY()); TQMouseEvent::Type type; int button = 0; int state = 0; if (qme) { button = qme->button(); state = qme->state(); type = qme->type(); } else { switch(me.id()) { case EventImpl::MOUSEDOWN_EVENT: type = TQMouseEvent::MouseButtonPress; break; case EventImpl::MOUSEUP_EVENT: type = TQMouseEvent::MouseButtonRelease; break; case EventImpl::MOUSEMOVE_EVENT: default: type = TQMouseEvent::MouseMove; break; } switch (me.button()) { case 0: button = TQt::LeftButton; break; case 1: button = TQt::MidButton; break; case 2: button = TQt::RightButton; break; default: break; } if (me.ctrlKey()) state |= ControlButton; if (me.altKey()) state |= AltButton; if (me.shiftKey()) state |= ShiftButton; if (me.metaKey()) state |= MetaButton; } // kdDebug(6000) << "sending event to widget " // << " pos=" << p << " type=" << type // << " button=" << button << " state=" << state << endl; TQMouseEvent e(type, p, button, state); TQScrollView * sc = ::tqt_cast(m_widget); if (sc && !::tqt_cast(m_widget)) static_cast(sc)->sendEvent(static_cast(&e)); else static_cast(m_widget)->sendEvent(static_cast(&e)); ret = e.isAccepted(); break; } case EventImpl::KEYDOWN_EVENT: // do nothing; see the mapping table below break; case EventImpl::KEYUP_EVENT: { if (!ev.isKeyRelatedEvent()) break; const KeyEventBaseImpl& domKeyEv = static_cast(ev); if (domKeyEv.isSynthetic() && !acceptsSyntheticEvents()) break; TQKeyEvent* const ke = domKeyEv.qKeyEvent(); static_cast(m_widget)->sendEvent(static_cast(ke)); ret = ke->isAccepted(); break; } case EventImpl::KEYPRESS_EVENT: { if (!ev.isKeyRelatedEvent()) break; const KeyEventBaseImpl& domKeyEv = static_cast(ev); if (domKeyEv.isSynthetic() && !acceptsSyntheticEvents()) break; // See TDEHTMLView::dispatchKeyEvent: autorepeat is just keypress in the DOM // but it's keyrelease+keypress in Qt. So here we do the inverse mapping as // the one done in TDEHTMLView: generate two events for one DOM auto-repeat keypress. // Similarly, DOM keypress events with non-autorepeat Qt event do nothing here, // because the matching Qt keypress event was already sent from DOM keydown event. // Reverse drawing as the one in TDEHTMLView: // DOM: Down Press | Press | Up // Qt: (nothing) Press | Release(autorepeat) + Press(autorepeat) | Release // // TQt::KeyPress is sent for DOM keypress and not DOM keydown to allow // sites to block a key with onkeypress, #99749 TQKeyEvent* const ke = domKeyEv.qKeyEvent(); if (ke->isAutoRepeat()) { TQKeyEvent releaseEv( TQEvent::KeyRelease, ke->key(), ke->ascii(), ke->state(), ke->text(), ke->isAutoRepeat(), ke->count() ); static_cast(m_widget)->sendEvent(static_cast(&releaseEv)); } static_cast(m_widget)->sendEvent(static_cast(ke)); ret = ke->isAccepted(); break; } case EventImpl::MOUSEOUT_EVENT: { TQEvent moe( TQEvent::Leave ); TQApplication::sendEvent(m_widget, &moe); break; } case EventImpl::MOUSEOVER_EVENT: { TQEvent moe( TQEvent::Enter ); TQApplication::sendEvent(m_widget, &moe); view()->part()->resetHoverText(); break; } default: break; } return ret; } void RenderWidget::deref() { if (_ref) _ref--; // tqDebug( "deref(%p): width get count is %d", this, _ref); if (!_ref) { tdehtml::SharedPtr guard(m_arena); //Since delete on us gets called -first-, //before the arena free arenaDelete(m_arena.get()); } } FindSelectionResult RenderReplaced::checkSelectionPoint(int _x, int _y, int _tx, int _ty, DOM::NodeImpl*& node, int &offset, SelPointState &) { #if 0 kdDebug(6040) << "RenderReplaced::checkSelectionPoint(_x="<<_x<<",_y="<<_y<<",_tx="<<_tx<<",_ty="<<_ty<<")" << endl << "xPos: " << xPos() << " yPos: " << yPos() << " width: " << width() << " height: " << height() << endl << "_ty + yPos: " << (_ty + yPos()) << " + height: " << (_ty + yPos() + height()) << "; _tx + xPos: " << (_tx + xPos()) << " + width: " << (_tx + xPos() + width()) << endl; #endif node = element(); offset = 0; if ( _y < _ty + yPos() ) return SelectionPointBefore; // above -> before if ( _y > _ty + yPos() + height() ) { // below -> after // Set the offset to the max offset = 1; return SelectionPointAfter; } if ( _x > _tx + xPos() + width() ) { // to the right // ### how to regard bidi in replaced elements? (LS) offset = 1; return SelectionPointAfterInLine; } // The Y matches, check if we're on the left if ( _x < _tx + xPos() ) { // ### how to regard bidi in replaced elements? (LS) return SelectionPointBeforeInLine; } offset = _x > _tx + xPos() + width()/2; return SelectionPointInside; } #ifdef ENABLE_DUMP void RenderWidget::dump(TQTextStream &stream, const TQString &ind) const { RenderReplaced::dump(stream,ind); if ( widget() ) stream << " color=" << widget()->foregroundColor().name() << " bg=" << widget()->backgroundColor().name(); else stream << " null widget"; } #endif #include "render_replaced.moc"