Source Code (Use browser search to find items of interest.)
Class Index
kdelibs'KHTMLView (./kdelibs/khtml/khtmlview.h:51)
class KHTMLView : public QScrollView
{
Q_OBJECT
friend DOM::HTMLDocumentImpl;
friend DOM::HTMLElementImpl;
friend DOM::HTMLTitleElementImpl;
friend class KHTMLPart;
friend khtml::RenderRoot;
public:
/**
* Constructs a KHTMLView
*/
KHTMLView( KHTMLPart *part, QWidget *parent, const char *name=0 );
virtual ~KHTMLView();
KHTMLPart *part() const { return m_part; }
protected:
void init();
void clear();
signals:
void selectionChanged();
public:
int frameWidth() const { return _width; }
/*
* @return the width of the parsed HTML code. Remember that
* the documents width depends on the width of the widget.
*/
// int docWidth() const;
/*
* @return the height of the parsed HTML code. Remember that
* the documents height depends on the width of the widget.
*/
// int docHeight() const;
/*
* Causes the widget contents to scroll automatically. Call
* @ref #stopAutoScrollY to stop. Stops automatically when the
* top or bottom of the document is reached.
*
* @param _delay Time in milliseconds to wait before scrolling the
* document again.
* @param _dy The amount to scroll the document when _delay elapses.
*
* (not implemented)
*/
// void autoScrollY( int _delay, int _dy );
/*
* Stops the document from @ref #autoScrollY ing.
*/
//void stopAutoScrollY();
/*
* Returns if the widget is currently auto scrolling.
*/
// bool isAutoScrollingY()
// { return autoScrollYTimer.isActive(); }
/**
* Sets the cursor to use when the cursor is on a link.
*/
void setURLCursor( const QCursor &c )
{ linkCursor = c; }
/**
* Returns the cursor which is used when the cursor is on a link.
*/
const QCursor& urlCursor() const { return linkCursor; }
/*
* set a margin in x direction
*/
// void setMarginWidth(int x) { _marginWidth = x; }
/**
* @return the margin With
*/
int marginWidth() const { return _marginWidth; }
/*
* set a margin in y direction
*/
// void setMarginHeight(int y) { _marginHeight = y; }
/*
* @return the margin height
*/
// int marginHeight() { return _marginHeight; }
QString selectedText() const;
bool hasSelection() const;
protected:
void paintElement( khtml::RenderObject *o, int x, int y );
virtual void resizeEvent ( QResizeEvent * event );
virtual void viewportPaintEvent ( QPaintEvent* pe );
virtual bool focusNextPrevChild( bool next );
virtual void drawContents ( QPainter * p, int clipx, int clipy, int clipw, int cliph );
public:
void layout(bool force = false);
protected:
virtual void viewportMousePressEvent( QMouseEvent * );
/**
* This function emits the 'doubleClick' signal when the user
* double clicks a <a href=...> tag.
*/
virtual void viewportMouseDoubleClickEvent( QMouseEvent * );
/**
* This function is called when the user moves the mouse.
*/
virtual void viewportMouseMoveEvent(QMouseEvent *);
/**
* this function is called when the user releases a mouse button.
*/
virtual void viewportMouseReleaseEvent(QMouseEvent *);
void keyPressEvent( QKeyEvent *_ke );
void keyReleaseEvent( QKeyEvent *_ke );
protected:
// ------------------------------------- member variables ------------------------------------
/**
* List of all open browsers.
*/
static QList<KHTMLView> *lstViews;
/**
* This is just a temporary variable. It stores the URL the user clicked
* on, until he releases the mouse again.
*
* @ref #mouseMoveHook
* @ref #mousePressedHook
*/
QString m_strSelectedURL;
private:
DOM::NodeImpl *nodeUnderMouse() const;
QCursor linkCursor;
bool pressed;
QString overURL;
int _width;
int _marginWidth;
int _marginHeight;
KHTMLPart *m_part;
static QPixmap* paintBuffer;
KHTMLViewPrivate *d;
};
kdelibs'KHTMLView::KHTMLView() (./kdelibs/khtml/khtmlview.cpp:86)
KHTMLView::KHTMLView( KHTMLPart *part, QWidget *parent, const char *name)
: QScrollView( parent, name)
{
m_part = part;
// initialize QScrollview
enableClipper(true);
viewport()->setMouseTracking(true);
viewport()->setBackgroundMode(NoBackground);
kimgioRegister();
setCursor(arrowCursor);
linkCursor = QCursor(PointingHandCursor);
init();
viewport()->show();
d = new KHTMLViewPrivate;
}
kdelibs'KHTMLView::~KHTMLView() (./kdelibs/khtml/khtmlview.cpp:109)
KHTMLView::~KHTMLView()
{
lstViews->removeRef( this );
if(lstViews->isEmpty())
{
delete lstViews;
lstViews = 0;
if(paintBuffer) delete paintBuffer;
paintBuffer = 0;
}
delete d;
}
kdelibs'KHTMLView::init() (./kdelibs/khtml/khtmlview.cpp:123)
void KHTMLView::init()
{
if ( lstViews == 0L )
lstViews = new QList<KHTMLView>;
lstViews->setAutoDelete( FALSE );
lstViews->append( this );
if(!paintBuffer) paintBuffer = new QPixmap();
viewport()->setFocusPolicy( QWidget::WheelFocus );
_marginWidth = 5;
_marginHeight = 5;
_width = width()- SCROLLBARWIDTH - 2*marginWidth();
resizeContents(clipper()->width(), clipper()->height());
}
kdelibs'KHTMLView::clear() (./kdelibs/khtml/khtmlview.cpp:141)
void KHTMLView::clear()
{
resizeContents(clipper()->width(), clipper()->height());
pressed = false;
setVScrollBarMode(Auto);
setHScrollBarMode(Auto);
d->selectionStart = 0;
d->selectionEnd = 0;
d->startOffset = 0;
d->endOffset = 0;
d->underMouse = 0;
}
/*
void KHTMLView::setFollowsLinks( bool follow )
{
_followLinks = follow;
}
bool KHTMLView::followsLinks()
{
return _followLinks;
}
*/
kdelibs'KHTMLView::resizeEvent() (./kdelibs/khtml/khtmlview.cpp:170)
void KHTMLView::resizeEvent ( QResizeEvent * event )
{
// kdDebug( 6000 ) << "resizeEvent" << endl;
layout();
DOM::HTMLDocumentImpl *doc = m_part->docImpl();
if ( doc && doc->body() )
resizeContents( doc->renderer()->width(), doc->renderer()->height() );
QScrollView::resizeEvent(event);
}
kdelibs'KHTMLView::viewportPaintEvent() (./kdelibs/khtml/khtmlview.cpp:185)
void KHTMLView::viewportPaintEvent ( QPaintEvent* pe )
{
QRect r = pe->rect();
// kdDebug( 6000 ) << "viewportPaintEvent r x=" << // r.x() << ",y=" << r.y() << ",w=" << r.width() << ",h=" << r.height() << endl;
NodeImpl *body = 0;
if( m_part->docImpl() )
body = m_part->docImpl()->body();
QRect rr(
-viewport()->x(), -viewport()->y(),
clipper()->width(), clipper()->height()
);
r &= rr;
int ex = r.x() + viewport()->x() + contentsX();
int ey = r.y() + viewport()->y() + contentsY();
int ew = r.width();
int eh = r.height();
if (ew<0) // events generated with repaint() are bit weird...
ew = pe->rect().width();
if (eh<0)
eh = pe->rect().height();
if(!body)
{
QPainter p(viewport());
p.fillRect(r.x(), r.y(), ew, eh, kapp->palette().normal().brush(QColorGroup::Background));
return;
}
// kdDebug( 6000 ) << "viewportPaintEvent x=" << ex << ",y=" << ey << ",w=" << ew << ",h=" << eh << endl;
if ( paintBuffer->width() < width() )
{
paintBuffer->resize(width(),PAINT_BUFFER_HEIGHT);
QPainter p(paintBuffer);
p.fillRect(r.x(), r.y(), ew, eh, kapp->palette().normal().brush(QColorGroup::Background));
}
QTime qt;
qt.start();
int py=0;
while (py < eh)
{
QPainter* tp = new QPainter;
tp->begin( paintBuffer );
tp->translate(-ex,-ey-py);
int ph = eh-py<PAINT_BUFFER_HEIGHT ? eh-py : PAINT_BUFFER_HEIGHT;
// ### fix this for frames...
tp->fillRect(ex, ey+py, ew, ph, kapp->palette().normal().brush(QColorGroup::Background));
m_part->docImpl()->renderer()->print(tp, ex, ey+py, ew, ph, 0, 0);
drawContents(tp,ex,ey+py,ew,ph); // in case someone want to extend the widget
tp->end();
delete tp;
//kdDebug( 6000 ) << "bitBlt x=" << ex << ",y=" << ey+py << ",sw=" << ew << ",sh=" << ph << endl;
bitBlt(viewport(),r.x(),r.y()+py,paintBuffer,0,0,ew,ph,Qt::CopyROP);
py += PAINT_BUFFER_HEIGHT;
}
//kdDebug( 6000 ) << "TIME: print() dt=" << qt.elapsed() << endl;
}
kdelibs'KHTMLView::layout() (./kdelibs/khtml/khtmlview.cpp:260)
void KHTMLView::layout(bool force)
{
//### take care of frmaes (hide scrollbars,...)
if( m_part->docImpl() )
{
DOM::HTMLDocumentImpl *document = m_part->docImpl();
NodeImpl *body = document->body();
if(body && body->id() == ID_FRAMESET)
{
setVScrollBarMode(AlwaysOff);
setHScrollBarMode(AlwaysOff);
_width = width();
document->renderer()->setMinWidth(_width);
document->renderer()->layout(true);
return;
}
int w = width() - SCROLLBARWIDTH - 2*marginWidth();
// if(w < _width-5 || w > _width + 5)
if (w != _width || force)
{
//kdDebug( 6000 ) << "layouting document" << endl;
_width = w;
QTime qt;
qt.start();
document->renderer()->setMinWidth(_width);
document->renderer()->layout(true);
resizeContents(document->renderer()->width(), document->renderer()->height());
kdDebug( 6000 ) << "TIME: layout() dt=" << qt.elapsed() << endl;
viewport()->repaint(false);
}
else
{
document->renderer()->layout(false);
viewport()->repaint(false);
}
}
else
{
_width = width() - SCROLLBARWIDTH - 2*marginWidth();
}
}
kdelibs'KHTMLView::paintElement() (./kdelibs/khtml/khtmlview.cpp:311)
void KHTMLView::paintElement( khtml::RenderObject *o, int xPos, int yPos )
{
int yOff = contentsY();
if(yOff > yPos + o->height() ||
yOff + visibleHeight() < yPos)
return;
QWidget *vp = viewport();
QPainter p(vp);
int xOff = contentsX()+vp->x();
yOff += vp->y();
p.translate( -xOff, -yOff );
o->printObject( &p , xOff, yOff, vp->width(), vp->height(),
xPos , yPos );
}
//
// Event Handling
//
/////////////////
kdelibs'KHTMLView::viewportMousePressEvent() (./kdelibs/khtml/khtmlview.cpp:333)
void KHTMLView::viewportMousePressEvent( QMouseEvent *_mouse )
{
if(!m_part->docImpl()) return;
int xm, ym;
viewportToContents(_mouse->x(), _mouse->y(), xm, ym);
//kdDebug( 6000 ) << "\nmousePressEvent: x=" << xm << ", y=" << ym << endl;
// Make this frame the active one
// ### need some visual indication for the active frame.
/* ### use PartManager (Simon)
if ( _isFrame && !_isSelected )
{
kdDebug( 6000 ) << "activating frame!" << endl;
topView()->setFrameSelected(this);
}*/
DOMString url;
NodeImpl *innerNode=0;
long offset=0;
m_part->docImpl()->mouseEvent( xm, ym, _mouse->stateAfter(), DOM::NodeImpl::MousePress, 0, 0, url, innerNode, offset );
kdDebug( 6000 ) << "Her har vi long'n: " << offset << " " << endl;
if(m_part->mousePressHook(_mouse, xm, ym, url, Node(innerNode), offset)) return;
if(url != 0)
{
//kdDebug( 6000 ) << "mouseEvent: overURL " << url.string() << endl;
m_strSelectedURL = url.string();
}
else
m_strSelectedURL = QString::null;
if ( _mouse->button() == LeftButton || _mouse->button() == MidButton )
{
pressed = TRUE;
if(_mouse->button() == LeftButton) {
if(innerNode) {
d->selectionStart = innerNode;
d->startOffset = offset;
d->selectionEnd = innerNode;
d->endOffset = offset;
m_part->docImpl()->clearSelection();
kdDebug( 6000 ) << "setting start of selection to " << innerNode << "/" << offset << endl;
} else {
d->selectionStart = 0;
d->selectionEnd = 0;
}
// ### emit some signal
emit selectionChanged();
}
}
if( _mouse->button() == RightButton )
{
m_part->popupMenu( m_strSelectedURL );
}
else if ( _mouse->button() == MidButton )
{
KURL u( m_part->url(), m_strSelectedURL );
if ( !u.isMalformed() )
emit m_part->browserExtension()->createNewWindow( u );
}
}
kdelibs'KHTMLView::viewportMouseDoubleClickEvent() (./kdelibs/khtml/khtmlview.cpp:401)
void KHTMLView::viewportMouseDoubleClickEvent( QMouseEvent *_mouse )
{
if(!m_part->docImpl()) return;
int xm, ym;
viewportToContents(_mouse->x(), _mouse->y(), xm, ym);
kdDebug( 6000 ) << "\nmouseDblClickEvent: x=" << xm << ", y=" << ym << endl;
DOMString url;
NodeImpl *innerNode=0;
long offset=0;
m_part->docImpl()->mouseEvent( xm, ym, _mouse->stateAfter(), DOM::NodeImpl::MouseDblClick, 0, 0, url, innerNode, offset );
if(m_part->mouseDoubleClickHook(_mouse, xm, ym, url, Node(innerNode), offset)) return;
// ###
//if ( url.length() )
//emit doubleClick( url.string(), _mouse->button() );
}
kdelibs'KHTMLView::viewportMouseMoveEvent() (./kdelibs/khtml/khtmlview.cpp:422)
void KHTMLView::viewportMouseMoveEvent( QMouseEvent * _mouse )
{
if(!m_part->docImpl()) return;
int xm, ym;
viewportToContents(_mouse->x(), _mouse->y(), xm, ym);
DOMString url;
NodeImpl *innerNode=0;
long offset=0;
m_part->docImpl()->mouseEvent( xm, ym, _mouse->stateAfter(), DOM::NodeImpl::MouseMove, 0, 0, url, innerNode, offset );
d->underMouse = innerNode;
if(m_part->mouseMoveHook(_mouse, xm, ym, url, Node(innerNode), offset)) return;
// drag of URL
if(pressed && !m_strSelectedURL.isEmpty())
{
QStrList uris;
KURL u( m_part->completeURL( m_strSelectedURL) );
uris.append(u.url().ascii());
QDragObject *d = new QUriDrag(uris, this);
QPixmap p = KMimeType::pixmapForURL(u, 0, KIconLoader::Medium);
if(p.isNull()) kdDebug( 6000 ) << "null pixmap" << endl;
d->setPixmap(p);
d->drag();
// when we finish our drag, we need to undo our mouse press
pressed = false;
m_strSelectedURL = "";
return;
}
if ( !pressed && url.length() )
{
QString surl = url.string();
if ( overURL.isEmpty() )
{
setCursor( linkCursor );
overURL = surl;
m_part->overURL( overURL );
}
else if ( overURL != surl )
{
m_part->overURL( overURL );
overURL = surl;
}
return;
}
else if( overURL.length() && !url.length() )
{
setCursor( arrowCursor );
m_part->overURL( QString::null );
overURL = "";
}
// selection stuff
if( pressed && innerNode && innerNode->isTextNode()) {
d->selectionEnd = innerNode;
d->endOffset = offset;
kdDebug( 6000 ) << "setting end of selection to " << innerNode << "/" << offset << endl;
// we have to get to know if end is before start or not...
NodeImpl *n = d->selectionStart;
d->startBeforeEnd = false;
while(n) {
if(n == d->selectionEnd) {
d->startBeforeEnd = true;
break;
}
NodeImpl *next = n->firstChild();
if(!next) next = n->nextSibling();
while( !next && (n = n->parentNode()) ) {
next = n->nextSibling();
}
n = next;
//viewport()->repaint(false);
}
if (d->selectionEnd == d->selectionStart && d->endOffset < d->startOffset)
m_part->docImpl()
->setSelection(d->selectionStart,d->endOffset,d->selectionEnd,d->startOffset);
else if (d->startBeforeEnd)
m_part->docImpl()
->setSelection(d->selectionStart,d->startOffset,d->selectionEnd,d->endOffset);
else
m_part->docImpl()
->setSelection(d->selectionEnd,d->endOffset,d->selectionStart,d->startOffset);
}
}
kdelibs'KHTMLView::viewportMouseReleaseEvent() (./kdelibs/khtml/khtmlview.cpp:518)
void KHTMLView::viewportMouseReleaseEvent( QMouseEvent * _mouse )
{
if ( !m_part->docImpl() ) return;
int xm, ym;
viewportToContents(_mouse->x(), _mouse->y(), xm, ym);
//kdDebug( 6000 ) << "\nmouseReleaseEvent: x=" << xm << ", y=" << ym << endl;
DOMString url=0;
NodeImpl *innerNode=0;
long offset;
m_part->docImpl()->mouseEvent( xm, ym, _mouse->stateAfter(), DOM::NodeImpl::MouseRelease, 0, 0, url, innerNode, offset );
if(m_part->mouseReleaseHook(_mouse, xm, ym, url, Node(innerNode), offset)) return;
if ( pressed )
{
// in case we started an autoscroll in MouseMove event
// ###
//stopAutoScrollY();
//disconnect( this, SLOT( slotUpdateSelectText(int) ) );
}
// Used to prevent mouseMoveEvent from initiating a drag before
// the mouse is pressed again.
pressed = false;
if ( !m_strSelectedURL.isEmpty() && _mouse->button() != RightButton )
{
KURL u(m_strSelectedURL);
QString pressedTarget;
if(u.protocol() == "target")
{
m_strSelectedURL = u.ref();
pressedTarget = u.host();
}
kdDebug( 6000 ) << "m_strSelectedURL='" << m_strSelectedURL << "' target=" << pressedTarget << endl;
m_part->urlSelected( m_strSelectedURL, _mouse->button(), _mouse->state(), pressedTarget );
}
if(innerNode && innerNode->isTextNode()) {
kdDebug( 6000 ) << "final range of selection to " << d->selectionStart << "/" << d->startOffset << " --> " << innerNode << "/" << offset << endl;
d->selectionEnd = innerNode;
d->endOffset = offset;
}
// delete selection in case start and end position are at the same point
if(d->selectionStart == d->selectionEnd && d->startOffset == d->endOffset) {
d->selectionStart = 0;
d->selectionEnd = 0;
d->startOffset = 0;
d->endOffset = 0;
emit selectionChanged();
} else {
// we have to get to know if end is before start or not...
NodeImpl *n = d->selectionStart;
d->startBeforeEnd = false;
while(n) {
if(n == d->selectionEnd) {
d->startBeforeEnd = true;
break;
}
NodeImpl *next = n->firstChild();
if(!next) next = n->nextSibling();
while( !next && (n = n->parentNode()) ) {
next = n->nextSibling();
}
n = next;
}
if(!d->startBeforeEnd)
{
NodeImpl *tmpNode = d->selectionStart;
int tmpOffset = d->startOffset;
d->selectionStart = d->selectionEnd;
d->startOffset = d->endOffset;
d->selectionEnd = tmpNode;
d->endOffset = tmpOffset;
d->startBeforeEnd = true;
}
// get selected text and paste to the clipboard
QString text = selectedText();
QClipboard *cb = QApplication::clipboard();
cb->setText(text);
//kdDebug( 6000 ) << "selectedText = " << text << endl;
emit selectionChanged();
}
}
kdelibs'KHTMLView::selectedText() (./kdelibs/khtml/khtmlview.cpp:610)
QString KHTMLView::selectedText() const
{
QString text;
NodeImpl *n = d->selectionStart;
while(n) {
if(n->isTextNode()) {
QString str = static_cast<TextImpl *>(n)->data().string();
if(n == d->selectionStart && n == d->selectionEnd)
text = str.mid(d->startOffset, d->endOffset - d->startOffset);
else if(n == d->selectionStart)
text = str.mid(d->startOffset);
else if(n == d->selectionEnd)
text += str.left(d->endOffset);
else
text += str;
}
else if(n->id() == ID_BR)
text += "\n";
else if(n->id() == ID_P || n->id() == ID_TD)
text += "\n\n";
if(n == d->selectionEnd) break;
NodeImpl *next = n->firstChild();
if(!next) next = n->nextSibling();
while( !next && (n = n->parentNode()) ) {
next = n->nextSibling();
}
n = next;
}
return text;
}
kdelibs'KHTMLView::hasSelection() (./kdelibs/khtml/khtmlview.cpp:642)
bool KHTMLView::hasSelection() const
{
return ( d->selectionStart != 0 && d->selectionEnd != 0 );
}
kdelibs'KHTMLView::keyPressEvent() (./kdelibs/khtml/khtmlview.cpp:647)
void KHTMLView::keyPressEvent( QKeyEvent *_ke )
{
if(m_part->keyPressHook(_ke)) return;
int offs = (clipper()->height() < 30) ? clipper()->height() : 30;
switch ( _ke->key() )
{
case Key_Down:
case Key_J:
scrollBy( 0, 10 );
break;
case Key_Next:
case Key_Space:
scrollBy( 0, clipper()->height() - offs );
break;
case Key_Up:
case Key_K:
scrollBy( 0, -10 );
break;
case Key_Prior:
case Key_Backspace:
scrollBy( 0, -clipper()->height() + offs );
break;
case Key_Right:
case Key_L:
scrollBy( 10, 0 );
break;
case Key_Left:
case Key_H:
scrollBy( -10, 0 );
break;
default:
QScrollView::keyPressEvent( _ke );
}
}
kdelibs'KHTMLView::keyReleaseEvent() (./kdelibs/khtml/khtmlview.cpp:690)
void KHTMLView::keyReleaseEvent( QKeyEvent *_ke )
{
if(m_part->keyReleaseHook(_ke)) return;
QScrollView::keyReleaseEvent( _ke);
}
kdelibs'KHTMLView::focusNextPrevChild() (./kdelibs/khtml/khtmlview.cpp:696)
bool KHTMLView::focusNextPrevChild( bool next )
{
kdDebug( 6000 ) << "focusNextPrev " << next << endl;
// return true; // ### temporary fix for qscrollview focus bug
// as a side effect, disables tabbing between form elements
// -antti
// return QScrollView::focusNextPrevChild( next );
return QScrollView::focusNextPrevChild( next );
}
kdelibs'KHTMLView::drawContents() (./kdelibs/khtml/khtmlview.cpp:707)
void KHTMLView::drawContents ( QPainter * p, int clipx, int clipy, int clipw, int cliph )
{
m_part->drawContentsHook(p);
}
DOM::NodeImpl *KHTMLView::nodeUnderMouse() const
{
return d->underMouse;
}