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()); |
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); |
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 */ |
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 |