src/gui/widgets/qplaintextedit.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
   355 void QPlainTextDocumentLayout::layoutBlock(const QTextBlock &block)
   355 void QPlainTextDocumentLayout::layoutBlock(const QTextBlock &block)
   356 {
   356 {
   357     Q_D(QPlainTextDocumentLayout);
   357     Q_D(QPlainTextDocumentLayout);
   358     QTextDocument *doc = document();
   358     QTextDocument *doc = document();
   359     qreal margin = doc->documentMargin();
   359     qreal margin = doc->documentMargin();
   360     QFontMetrics fm(doc->defaultFont());
       
   361     qreal blockMaximumWidth = 0;
   360     qreal blockMaximumWidth = 0;
   362 
   361 
   363     int leading = qMax(0, fm.leading());
       
   364     qreal height = 0;
   362     qreal height = 0;
   365     QTextLayout *tl = block.layout();
   363     QTextLayout *tl = block.layout();
   366     QTextOption option = doc->defaultTextOption();
   364     QTextOption option = doc->defaultTextOption();
   367     tl->setTextOption(option);
   365     tl->setTextOption(option);
   368 
   366 
   379     availableWidth -= 2*margin + extraMargin;
   377     availableWidth -= 2*margin + extraMargin;
   380     while (1) {
   378     while (1) {
   381         QTextLine line = tl->createLine();
   379         QTextLine line = tl->createLine();
   382         if (!line.isValid())
   380         if (!line.isValid())
   383             break;
   381             break;
       
   382         line.setLeadingIncluded(true);
   384         line.setLineWidth(availableWidth);
   383         line.setLineWidth(availableWidth);
   385 
       
   386         height += leading;
       
   387         line.setPosition(QPointF(margin, height));
   384         line.setPosition(QPointF(margin, height));
   388         height += line.height();
   385         height += line.height();
   389         blockMaximumWidth = qMax(blockMaximumWidth, line.naturalTextWidth() + 2*margin);
   386         blockMaximumWidth = qMax(blockMaximumWidth, line.naturalTextWidth() + 2*margin);
   390     }
   387     }
   391     tl->endLayout();
   388     tl->endLayout();
   685         if (center)
   682         if (center)
   686             height /= 2;
   683             height /= 2;
   687 
   684 
   688         qreal h = center ? line.naturalTextRect().center().y() : line.naturalTextRect().bottom();
   685         qreal h = center ? line.naturalTextRect().center().y() : line.naturalTextRect().bottom();
   689 
   686 
       
   687         QTextBlock previousVisibleBlock = block;
   690         while (h < height && block.previous().isValid()) {
   688         while (h < height && block.previous().isValid()) {
   691             block = block.previous();
   689             previousVisibleBlock = block;
       
   690             do {
       
   691                 block = block.previous();
       
   692             } while (!block.isVisible() && block.previous().isValid());
   692             h += q->blockBoundingRect(block).height();
   693             h += q->blockBoundingRect(block).height();
   693         }
   694         }
   694 
   695 
   695         int l = 0;
   696         int l = 0;
   696         int lineCount = block.layout()->lineCount();
   697         int lineCount = block.layout()->lineCount();
   700             if (h - voffset - lineRect.top() <= height)
   701             if (h - voffset - lineRect.top() <= height)
   701                 break;
   702                 break;
   702             ++l;
   703             ++l;
   703         }
   704         }
   704 
   705 
   705         if (block.next().isValid() && l >= lineCount) {
   706         if (l >= lineCount) {
   706             block = block.next();
   707             block = previousVisibleBlock;
   707             l = 0;
   708             l = 0;
   708         }
   709         }
   709         setTopBlock(block.blockNumber(), l);
   710         setTopBlock(block.blockNumber(), l);
   710     } else if (lr.top() < visible.top()) {
   711     } else if (lr.top() < visible.top()) {
   711         setTopBlock(block.blockNumber(), line.lineNumber());
   712         setTopBlock(block.blockNumber(), line.lineNumber());
   731 {
   732 {
   732     showCursorOnInitialShow = true;
   733     showCursorOnInitialShow = true;
   733     backgroundVisible = false;
   734     backgroundVisible = false;
   734     centerOnScroll = false;
   735     centerOnScroll = false;
   735     inDrag = false;
   736     inDrag = false;
   736 #ifdef Q_WS_WIN
       
   737     singleFingerPanEnabled = true;
       
   738 #endif
       
   739 }
   737 }
   740 
   738 
   741 
   739 
   742 void QPlainTextEditPrivate::init(const QString &txt)
   740 void QPlainTextEditPrivate::init(const QString &txt)
   743 {
   741 {
   765     QObject::connect(control, SIGNAL(copyAvailable(bool)), q, SIGNAL(copyAvailable(bool)));
   763     QObject::connect(control, SIGNAL(copyAvailable(bool)), q, SIGNAL(copyAvailable(bool)));
   766     QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged()));
   764     QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged()));
   767     QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SLOT(_q_cursorPositionChanged()));
   765     QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SLOT(_q_cursorPositionChanged()));
   768     QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
   766     QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
   769 
   767 
       
   768     QObject::connect(control, SIGNAL(textChanged()), q, SLOT(updateMicroFocus()));
   770 
   769 
   771     // set a null page size initially to avoid any relayouting until the textedit
   770     // set a null page size initially to avoid any relayouting until the textedit
   772     // is shown. relayoutDocument() will take care of setting the page size to the
   771     // is shown. relayoutDocument() will take care of setting the page size to the
   773     // viewport dimensions later.
   772     // viewport dimensions later.
   774     doc->setTextWidth(-1);
   773     doc->setTextWidth(-1);
   790 
   789 
   791 #ifndef QT_NO_CURSOR
   790 #ifndef QT_NO_CURSOR
   792     viewport->setCursor(Qt::IBeamCursor);
   791     viewport->setCursor(Qt::IBeamCursor);
   793 #endif
   792 #endif
   794     originalOffsetY = 0;
   793     originalOffsetY = 0;
       
   794 #ifdef Q_WS_WIN
       
   795     setSingleFingerPanEnabled(true);
       
   796 #endif
   795 }
   797 }
   796 
   798 
   797 void QPlainTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
   799 void QPlainTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
   798 {
   800 {
   799     Q_Q(QPlainTextEdit);
   801     Q_Q(QPlainTextEdit);
  1451     else if (e->type() == QEvent::EnterEditFocus || e->type() == QEvent::LeaveEditFocus) {
  1453     else if (e->type() == QEvent::EnterEditFocus || e->type() == QEvent::LeaveEditFocus) {
  1452         if (QApplication::keypadNavigationEnabled())
  1454         if (QApplication::keypadNavigationEnabled())
  1453             d->sendControlEvent(e);
  1455             d->sendControlEvent(e);
  1454     }
  1456     }
  1455 #endif
  1457 #endif
       
  1458     else if (e->type() == QEvent::Gesture) {
       
  1459         QGestureEvent *ge = static_cast<QGestureEvent *>(e);
       
  1460         QPanGesture *g = static_cast<QPanGesture *>(ge->gesture(Qt::PanGesture));
       
  1461         if (g) {
       
  1462             QScrollBar *hBar = horizontalScrollBar();
       
  1463             QScrollBar *vBar = verticalScrollBar();
       
  1464             if (g->state() == Qt::GestureStarted)
       
  1465                 d->originalOffsetY = vBar->value();
       
  1466             QPointF offset = g->offset();
       
  1467             if (!offset.isNull()) {
       
  1468                 if (QApplication::isRightToLeft())
       
  1469                     offset.rx() *= -1;
       
  1470                 // QPlainTextEdit scrolls by lines only in vertical direction
       
  1471                 QFontMetrics fm(document()->defaultFont());
       
  1472                 int lineHeight = fm.height();
       
  1473                 int newX = hBar->value() - g->delta().x();
       
  1474                 int newY = d->originalOffsetY - offset.y()/lineHeight;
       
  1475                 hBar->setValue(newX);
       
  1476                 vBar->setValue(newY);
       
  1477             }
       
  1478         }
       
  1479         return true;
       
  1480     }
  1456     return QAbstractScrollArea::event(e);
  1481     return QAbstractScrollArea::event(e);
  1457 }
  1482 }
  1458 
  1483 
  1459 /*! \internal
  1484 /*! \internal
  1460 */
  1485 */
  1600             e->accept();
  1625             e->accept();
  1601             d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor);
  1626             d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor);
  1602             return;
  1627             return;
  1603         }
  1628         }
  1604     }
  1629     }
  1605 #endif // QT_NO_SHORTCUT
       
  1606 
  1630 
  1607     if (!(tif & Qt::TextEditable)) {
  1631     if (!(tif & Qt::TextEditable)) {
  1608         switch (e->key()) {
  1632         switch (e->key()) {
  1609             case Qt::Key_Space:
  1633             case Qt::Key_Space:
  1610                 e->accept();
  1634                 e->accept();
  1628                     QAbstractScrollArea::keyPressEvent(e);
  1652                     QAbstractScrollArea::keyPressEvent(e);
  1629                 }
  1653                 }
  1630         }
  1654         }
  1631         return;
  1655         return;
  1632     }
  1656     }
       
  1657 #endif // QT_NO_SHORTCUT
  1633 
  1658 
  1634     d->sendControlEvent(e);
  1659     d->sendControlEvent(e);
  1635 #ifdef QT_KEYPAD_NAVIGATION
  1660 #ifdef QT_KEYPAD_NAVIGATION
  1636     if (!e->isAccepted()) {
  1661     if (!e->isAccepted()) {
  1637         switch (e->key()) {
  1662         switch (e->key()) {
  1780     bool editable = !isReadOnly();
  1805     bool editable = !isReadOnly();
  1781 
  1806 
  1782     QTextBlock block = firstVisibleBlock();
  1807     QTextBlock block = firstVisibleBlock();
  1783     qreal maximumWidth = document()->documentLayout()->documentSize().width();
  1808     qreal maximumWidth = document()->documentLayout()->documentSize().width();
  1784 
  1809 
       
  1810     // Set a brush origin so that the WaveUnderline knows where the wave started
       
  1811     painter.setBrushOrigin(offset);
       
  1812 
  1785     // keep right margin clean from full-width selection
  1813     // keep right margin clean from full-width selection
  1786     int maxX = offset.x() + qMax((qreal)viewportRect.width(), maximumWidth)
  1814     int maxX = offset.x() + qMax((qreal)viewportRect.width(), maximumWidth)
  1787                - document()->documentMargin();
  1815                - document()->documentMargin();
  1788     er.setRight(qMin(er.right(), maxX));
  1816     er.setRight(qMin(er.right(), maxX));
  1789     painter.setClipRect(er);
  1817     painter.setClipRect(er);
  1944     if (d->autoScrollTimer.isActive()) {
  1972     if (d->autoScrollTimer.isActive()) {
  1945         d->autoScrollTimer.stop();
  1973         d->autoScrollTimer.stop();
  1946         d->ensureCursorVisible();
  1974         d->ensureCursorVisible();
  1947     }
  1975     }
  1948 
  1976 
  1949     d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
  1977     if (!isReadOnly() && rect().contains(e->pos()))
       
  1978         d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
  1950     d->clickCausedFocus = 0;
  1979     d->clickCausedFocus = 0;
  1951 }
  1980 }
  1952 
  1981 
  1953 /*! \reimp
  1982 /*! \reimp
  1954 */
  1983 */
  2930 
  2959 
  2931     This signal is emitted whenever redo operations become available
  2960     This signal is emitted whenever redo operations become available
  2932     (\a available is true) or unavailable (\a available is false).
  2961     (\a available is true) or unavailable (\a available is false).
  2933 */
  2962 */
  2934 
  2963 
  2935 //void QPlainTextEditPrivate::_q_gestureTriggered()
       
  2936 //{
       
  2937 //    Q_Q(QPlainTextEdit);
       
  2938 //    QPanGesture *g = qobject_cast<QPanGesture*>(q->sender());
       
  2939 //    if (!g)
       
  2940 //        return;
       
  2941 //    QScrollBar *hBar = q->horizontalScrollBar();
       
  2942 //    QScrollBar *vBar = q->verticalScrollBar();
       
  2943 //    if (g->state() == Qt::GestureStarted)
       
  2944 //        originalOffsetY = vBar->value();
       
  2945 //    QSizeF totalOffset = g->totalOffset();
       
  2946 //    if (!totalOffset.isNull()) {
       
  2947 //        if (QApplication::isRightToLeft())
       
  2948 //            totalOffset.rwidth() *= -1;
       
  2949 //        // QPlainTextEdit scrolls by lines only in vertical direction
       
  2950 //        QFontMetrics fm(q->document()->defaultFont());
       
  2951 //        int lineHeight = fm.height();
       
  2952 //        int newX = hBar->value() - g->lastOffset().width();
       
  2953 //        int newY = originalOffsetY - totalOffset.height()/lineHeight;
       
  2954 //        hbar->setValue(newX);
       
  2955 //        vbar->setValue(newY);
       
  2956 //    }
       
  2957 //}
       
  2958 
       
  2959 QT_END_NAMESPACE
  2964 QT_END_NAMESPACE
  2960 
  2965 
  2961 #include "moc_qplaintextedit.cpp"
  2966 #include "moc_qplaintextedit.cpp"
  2962 #include "moc_qplaintextedit_p.cpp"
  2967 #include "moc_qplaintextedit_p.cpp"
  2963 
  2968