📄 qtextbrowser.cpp
字号:
if ( !d->curhref.isEmpty() ) richText().setSelectedAnchor( QString::null, QtTriple(), QtTriple() ); setModalEditing( FALSE ); } else { e->ignore(); } return; default: if( qt_modalEditingEnabled ) { if ( !isModalEditing() ) { e->ignore(); return; } } }#endif if ( e->state() & AltButton ) { switch (e->key()) { case Key_Right: forward(); e->accept(); return; case Key_Left: backward(); e->accept(); return; case Key_Up: home(); e->accept(); return; } }#ifdef QT_KEYPAD_MODE switch( e->key() ) { case Key_Right: case Key_Down: if ( !selectNextPrevHref( TRUE ) ){ // scroll the screen down by one page QScrollBar *sb = verticalScrollBar(); sb->setValue( sb->value() + (sb->pageStep() >> 1) ); selectNextPrevHref( TRUE ); } e->accept(); return; case Key_Left: case Key_Up: if ( !selectNextPrevHref( FALSE ) ){ // scroll the screen up by one page QScrollBar *sb = verticalScrollBar(); sb->setValue( sb->value() - (sb->pageStep() >> 1) ); selectNextPrevHref( FALSE ); } e->accept(); return; }#endif QTextView::keyPressEvent(e);}/*! \e override to press anchors.*/void QTextBrowser::viewportMousePressEvent( QMouseEvent* e ){ if ( e->button() == LeftButton ) { d->buttonDown = anchorAt( e->pos() ); d->lastClick = e->globalPos(); } QTextView::viewportMousePressEvent( e );}/*! \e override to activate anchors.*/void QTextBrowser::viewportMouseReleaseEvent( QMouseEvent* e ){ if ( e->button() == LeftButton ) { if ( !d->buttonDown.isEmpty() && anchorAt( e->pos() ) == d->buttonDown ) { setSource( d->buttonDown ); } } d->buttonDown = QString::null; QTextView::viewportMouseReleaseEvent( e );}/*! Activate to emit highlighted().*/void QTextBrowser::viewportMouseMoveEvent( QMouseEvent* e){#ifndef QT_NO_DRAGANDDROP if ( (e->state() & LeftButton) == LeftButton && !d->buttonDown.isEmpty() ) { if ( ( e->globalPos() - d->lastClick ).manhattanLength() > QApplication::startDragDistance() ) { QUrl url ( context(), d->buttonDown, TRUE ); QUriDrag* drag = new QUriDrag( this ); drag->setUnicodeUris( url.toString() ); drag->drag(); } return; }#endif if ( e->state() == 0 ) { QString act = anchorAt( e->pos() ); if (d->highlight != act) { if ( !act.isEmpty() ){ emit highlighted( act ); d->highlight = act; } else if ( !d->highlight.isEmpty() ) { emit highlighted( QString::null ); d->highlight = QString::null; }#ifndef QT_NO_CURSOR viewport()->setCursor( d->highlight.isEmpty()?arrowCursor:pointingHandCursor );#endif } } QTextView::viewportMouseMoveEvent( e );}QString QTextBrowser::anchorAt(const QPoint& pos){ return richText().anchorAt( QPoint(contentsX(), contentsY() ) + pos );}class QTextDetailPopup : public QWidget{public: QTextDetailPopup() : QWidget ( 0, "automatic QText detail widget", WType_Popup | WDestructiveClose ) { }protected: void mousePressEvent( QMouseEvent*) { close(); }};void QTextBrowser::popupDetail( const QString& contents, const QPoint& pos ){ const int shadowWidth = 6; // also used as '5' and '6' and even '8' below const int vMargin = 8; const int hMargin = 12; QWidget* popup = new QTextDetailPopup; popup->setBackgroundMode( QWidget::NoBackground ); QSimpleRichText* doc = new QSimpleRichText( contents, popup->font() ); doc->adjustSize(); QRect r( 0, 0, doc->width(), doc->height() ); int w = r.width() + 2*hMargin; int h = r.height() + 2*vMargin; popup->resize( w + shadowWidth, h + shadowWidth ); // okay, now to find a suitable location //###### we need a global fancy popup positioning somewhere popup->move(pos - popup->rect().center()); if (popup->geometry().right() > QApplication::desktop()->width()) popup->move( QApplication::desktop()->width() - popup->width(), popup->y() ); if (popup->geometry().bottom() > QApplication::desktop()->height()) popup->move( popup->x(), QApplication::desktop()->height() - popup->height() ); if ( popup->x() < 0 ) popup->move( 0, popup->y() ); if ( popup->y() < 0 ) popup->move( popup->x(), 0 ); popup->show(); // now for super-clever shadow stuff. super-clever mostly in // how many window system problems it skirts around. QPainter p( popup ); p.setPen( QApplication::palette().normal().foreground() ); p.drawRect( 0, 0, w, h ); p.setPen( QApplication::palette().normal().mid() ); p.setBrush( QColor( 255, 255, 240 ) ); p.drawRect( 1, 1, w-2, h-2 ); p.setPen( black ); doc->draw( &p, hMargin, vMargin, r, popup->colorGroup(), 0 ); delete doc; p.drawPoint( w + 5, 6 ); p.drawLine( w + 3, 6, w + 5, 8 ); p.drawLine( w + 1, 6, w + 5, 10 ); int i; for( i=7; i < h; i += 2 ) p.drawLine( w, i, w + 5, i + 5 ); for( i = w - i + h; i > 6; i -= 2 ) p.drawLine( i, h, i + 5, h + 5 ); for( ; i > 0 ; i -= 2 ) p.drawLine( 6, h + 6 - i, i + 5, h + 5 );}/*! Scrolls the browser so that the part of the document named \a name is at the top of the view (or as close to the top as the size of the document allows).*/void QTextBrowser::scrollToAnchor(const QString& name){ if ( name.isEmpty() ) return; d->curmark = name; QRichTextIterator it( richText() ); do { if ( it.format()->anchorName() == name ) { QTextParagraph* b = it.outmostParagraph(); if ( b->dirty ) { // QTextView layouts delayed in the background, so this may happen QRichTextFormatter tc( richText() ); tc.gotoParagraph( 0, &richText() ); tc.updateLayout(); resizeContents( QMAX( richText().flow()->widthUsed-1, visibleWidth() ), richText().flow()->height ); } QRect r = it.lineGeometry(); setContentsPos( contentsX(), r.top() ); return; } } while ( it.right( FALSE ) );}#ifdef QT_KEYPAD_MODE/*! \Internal*/bool QTextBrowser::selectNextPrevHref(bool next){ QRichTextIterator it( richText() ); bool foundCurrent = d->curhref.isEmpty(); QString found; QtTriple startPos, endPos; QtTriple prevprev; QString anchor; //, atAnchor; QtTriple anchorPos; bool anchorBroken = FALSE; do { anchor = it.format()->anchorHref(); anchorPos = it.position(); if ( !anchor.isEmpty() ) { // it's an anchor if ( !next ) { //select a previous link if (it.position() == d->prevhrefstartpos) { //at the link before the current // break if previous anchor isn't within the current viewport if ( it.lineGeometry().top() < viewport()->rect().top() + contentsY() ) break; found = anchor; startPos = anchorPos; endPos = startPos; it.right( FALSE ); while( it.format()->anchorHref().length() ) { endPos = it.position(); it.right( FALSE ); } d->prevhrefstartpos = prevprev; break; } else //if ( anchor != atAnchor ) { //keep track of current link until we get to new current. // prevprev becomes prev href if( prevprev.isNull() || anchorBroken ) { //haven't set yet or this is a new link prevprev = anchorPos; anchorBroken = FALSE; } } } else { if ( d->curhref.isEmpty() || (foundCurrent && d->curhrefendpos < anchorPos) ) { //there's no current or we've found the current and this is //the anchor after it // break if next anchor isn't within the current viewport if ( it.lineGeometry().bottom() >= viewport()->rect().bottom() + contentsY() ) break; d->prevhrefstartpos = d->curhrefstartpos; found = anchor; startPos = anchorPos; endPos = startPos; it.right( FALSE ); while( it.format()->anchorHref().length() ) { endPos = it.position(); it.right( FALSE ); } break; } else if ( !foundCurrent && d->curhrefstartpos == anchorPos ) { foundCurrent = TRUE; //don't set prevpos until we know there's a link after it } } } else { //rich text other than an anchor anchorBroken = TRUE; } } while ( it.right( FALSE ) ); if ( found.length() ) { d->curhref = found; d->curhrefstartpos = startPos; d->curhrefendpos = endPos; richText().setSelectedAnchor( d->curhref, d->curhrefstartpos, d->curhrefendpos ); QTextParagraph* b = it.outmostParagraph(); if ( b->dirty ) { // QTextView layouts delayed in the background, so this may happen QRichTextFormatter tc( richText() ); tc.gotoParagraph( 0, &richText() ); tc.updateLayout(); resizeContents( QMAX( richText().flow()->widthUsed-1, visibleWidth() ), richText().flow()->height ); } //QRect r = it.lineGeometry(); //updateContents( r ); updateContents(0, 0, contentsWidth(), contentsHeight()); // erase previous highlighted link if ( next ) { updateContents(0, 0, contentsWidth(), contentsHeight()); } else { QString tmp = d->curhref; do { if ( it.format()->anchorHref().length() && tmp != it.format()->anchorHref() ) break; } while ( it.right( FALSE ) ); //updateContents( it.lineGeometry() ); updateContents(0, 0, contentsWidth(), contentsHeight()); } emit highlighted( d->curhref ); return TRUE; } return FALSE;}/* \Internal*/bool QTextBrowser::containsAnchor() const{ QRichTextIterator it( richText() ); do { if ( !it.format()->anchorHref().isEmpty() ) return TRUE; } while ( it.right( FALSE ) ); return FALSE;}#endif/*!\reimp */void QTextBrowser::showEvent( QShowEvent* e ){ QTextView::showEvent( e ); scrollToAnchor( d->curmark );}#endif // QT_NO_TEXTBROWSER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -