Changeset 561 for trunk/src/gui/widgets/qplaintextedit.cpp
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/vendor/nokia/qt/4.6.1 merged eligible /branches/vendor/nokia/qt/current merged eligible /branches/vendor/trolltech/qt/current 3-149
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/gui/widgets/qplaintextedit.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtGui module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 66 66 #include <qtexttable.h> 67 67 #include <qvariant.h> 68 69 68 #include <qinputcontext.h> 70 69 … … 72 71 73 72 QT_BEGIN_NAMESPACE 73 74 static inline bool shouldEnableInputMethod(QPlainTextEdit *plaintextedit) 75 { 76 return !plaintextedit->isReadOnly(); 77 } 74 78 75 79 class QPlainTextDocumentLayoutPrivate : public QAbstractTextDocumentLayoutPrivate … … 110 114 \brief The QPlainTextDocumentLayout class implements a plain text layout for QTextDocument 111 115 112 \ingroup text 113 116 \ingroup richtext-processing 114 117 115 118 A QPlainTextDocumentLayout is required for text documents that can … … 251 254 void QPlainTextDocumentLayout::requestUpdate() 252 255 { 253 emit update(QRectF(0., - 4., 1000000000., 1000000000.));256 emit update(QRectF(0., -document()->documentMargin(), 1000000000., 1000000000.)); 254 257 } 255 258 … … 346 349 347 350 if (!d->blockUpdate) 348 emit update(); // optimization potential 349 351 emit update(QRectF(0., -doc->documentMargin(), 1000000000., 1000000000.)); // optimization potential 350 352 } 351 353 … … 356 358 QTextDocument *doc = document(); 357 359 qreal margin = doc->documentMargin(); 358 QFontMetrics fm(doc->defaultFont());359 360 qreal blockMaximumWidth = 0; 360 361 361 int leading = qMax(0, fm.leading());362 362 qreal height = 0; 363 363 QTextLayout *tl = block.layout(); … … 371 371 } 372 372 tl->beginLayout(); 373 qreal availableWidth = d->width; 374 if (availableWidth <= 0) { 375 availableWidth = qreal(INT_MAX); // similar to text edit with pageSize.width == 0 376 } 377 availableWidth -= 2*margin + extraMargin; 373 378 while (1) { 374 379 QTextLine line = tl->createLine(); 375 380 if (!line.isValid()) 376 381 break; 377 line.setLineWidth(d->width - 2*margin - extraMargin); 378 379 height += leading; 382 line.setLeadingIncluded(true); 383 line.setLineWidth(availableWidth); 380 384 line.setPosition(QPointF(margin, height)); 381 385 height += line.height(); … … 440 444 { 441 445 pageUpDownLastCursorYIsValid = false; 442 } ;446 } 443 447 444 448 void QPlainTextEditPrivate::_q_verticalScrollbarActionTriggered(int action) { … … 508 512 int currentBlockNumber = topBlock; 509 513 QTextBlock currentBlock = document()->findBlockByNumber(currentBlockNumber); 514 if (!currentBlock.isValid()) 515 return -1; 516 510 517 QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(document()->documentLayout()); 511 518 Q_ASSERT(documentLayout); … … 556 563 return QRectF(); 557 564 Q_ASSERT(currentBlock.blockNumber() == currentBlockNumber); 558 QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(document()->documentLayout()); 565 QTextDocument *doc = document(); 566 QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(doc->documentLayout()); 559 567 Q_ASSERT(documentLayout); 560 568 … … 563 571 return QRectF(); 564 572 QRectF r = documentLayout->blockBoundingRect(currentBlock); 565 while (currentBlockNumber < blockNumber && offset.y() <= 2* textEdit->viewport()->height()) { 573 int maxVerticalOffset = r.height(); 574 while (currentBlockNumber < blockNumber && offset.y() - maxVerticalOffset <= 2* textEdit->viewport()->height()) { 566 575 offset.ry() += r.height(); 567 576 currentBlock = currentBlock.next(); 568 577 ++currentBlockNumber; 578 if (!currentBlock.isVisible()) { 579 currentBlock = doc->findBlockByLineNumber(currentBlock.firstLineNumber()); 580 currentBlockNumber = currentBlock.blockNumber(); 581 } 569 582 r = documentLayout->blockBoundingRect(currentBlock); 570 583 } 571 while (currentBlockNumber > blockNumber && offset.y() >= -textEdit->viewport()->height()) {584 while (currentBlockNumber > blockNumber && offset.y() + maxVerticalOffset >= -textEdit->viewport()->height()) { 572 585 currentBlock = currentBlock.previous(); 586 --currentBlockNumber; 587 while (!currentBlock.isVisible()) { 588 currentBlock = currentBlock.previous(); 589 --currentBlockNumber; 590 } 573 591 if (!currentBlock.isValid()) 574 592 break; 575 --currentBlockNumber; 593 576 594 r = documentLayout->blockBoundingRect(currentBlock); 577 595 offset.ry() -= r.height(); … … 625 643 if (viewport->updatesEnabled() && viewport->isVisible()) { 626 644 int dy = 0; 627 if (doc->findBlockBy LineNumber(control->topBlock).isValid()) {645 if (doc->findBlockByNumber(control->topBlock).isValid()) { 628 646 dy = (int)(-q->blockBoundingGeometry(block).y()) 629 647 + verticalOffset() - verticalOffset(blockNumber, lineNumber); … … 667 685 qreal h = center ? line.naturalTextRect().center().y() : line.naturalTextRect().bottom(); 668 686 687 QTextBlock previousVisibleBlock = block; 669 688 while (h < height && block.previous().isValid()) { 670 block = block.previous(); 689 previousVisibleBlock = block; 690 do { 691 block = block.previous(); 692 } while (!block.isVisible() && block.previous().isValid()); 671 693 h += q->blockBoundingRect(block).height(); 672 694 } … … 682 704 } 683 705 684 if ( block.next().isValid() &&l >= lineCount) {685 block = block.next();706 if (l >= lineCount) { 707 block = previousVisibleBlock; 686 708 l = 0; 687 709 } … … 706 728 lineWrap(QPlainTextEdit::WidgetWidth), 707 729 wordWrap(QTextOption::WrapAtWordBoundaryOrAnywhere), 708 topLine(0), pageUpDownLastCursorYIsValid(false) 730 clickCausedFocus(0),topLine(0), 731 pageUpDownLastCursorYIsValid(false) 709 732 { 710 733 showCursorOnInitialShow = true; … … 743 766 QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged())); 744 767 768 QObject::connect(control, SIGNAL(textChanged()), q, SLOT(updateMicroFocus())); 745 769 746 770 // set a null page size initially to avoid any relayouting until the textedit 747 771 // is shown. relayoutDocument() will take care of setting the page size to the 748 772 // viewport dimensions later. 749 doc->setTextWidth( 0);773 doc->setTextWidth(-1); 750 774 doc->documentLayout()->setPaintDevice(viewport); 751 775 doc->setDefaultFont(q->font()); … … 766 790 #ifndef QT_NO_CURSOR 767 791 viewport->setCursor(Qt::IBeamCursor); 792 #endif 793 originalOffsetY = 0; 794 #ifdef Q_WS_WIN 795 setSingleFingerPanEnabled(true); 768 796 #endif 769 797 } … … 986 1014 plain text. 987 1015 988 \ingroup text989 \mainclass 1016 \ingroup richtext-processing 1017 990 1018 991 1019 \tableofcontents … … 1000 1028 QTextEdit, but is optimized for plain text handling. 1001 1029 1002 QPlainTextEdit works on paragraphs and characters. A paragraph is a1003 formatted string which is word-wrapped to fit into the width of1030 QPlainTextEdit works on paragraphs and characters. A paragraph is 1031 a formatted string which is word-wrapped to fit into the width of 1004 1032 the widget. By default when reading plain text, one newline 1005 1033 signifies a paragraph. A document consists of zero or more 1006 paragraphs. The words in the paragraph are aligned in accordance 1007 with the paragraph's alignment. Paragraphs are separated by hard 1008 line breaks. Each character within a paragraph has its own 1009 attributes, for example, font and color. 1034 paragraphs. Paragraphs are separated by hard line breaks. Each 1035 character within a paragraph has its own attributes, for example, 1036 font and color. 1010 1037 1011 1038 The shape of the mouse cursor on a QPlainTextEdit is … … 1015 1042 \section1 Using QPlainTextEdit as a Display Widget 1016 1043 1017 The text is set or replaced using setPlainText() which deletes any 1018 existing text and replaces it with the text passed in the 1019 setPlainText() call. 1020 1021 Text itself can be inserted using the QTextCursor class or using 1022 the convenience functins insertPlainText(), appendPlainText() or 1044 The text is set or replaced using setPlainText() which deletes the 1045 existing text and replaces it with the text passed to setPlainText(). 1046 1047 Text can be inserted using the QTextCursor class or using the 1048 convenience functions insertPlainText(), appendPlainText() or 1023 1049 paste(). 1024 1050 1025 By default the text edit wraps words at whitespace to fit within1051 By default, the text edit wraps words at whitespace to fit within 1026 1052 the text edit widget. The setLineWrapMode() function is used to 1027 1053 specify the kind of line wrap you want, \l WidgetWidth or \l … … 1149 1175 1150 1176 \sa QTextDocument, QTextCursor, {Application Example}, 1151 {Syntax Highlighter Example}, {Rich Text Processing} 1177 {Code Editor Example}, {Syntax Highlighter Example}, 1178 {Rich Text Processing} 1152 1179 1153 1180 */ … … 1429 1456 } 1430 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 } 1431 1481 return QAbstractScrollArea::event(e); 1432 1482 } … … 1552 1602 #endif 1553 1603 1554 if (!(d->control->textInteractionFlags() & Qt::TextEditable)) { 1604 #ifndef QT_NO_SHORTCUT 1605 1606 Qt::TextInteractionFlags tif = d->control->textInteractionFlags(); 1607 1608 if (tif & Qt::TextSelectableByKeyboard){ 1609 if (e == QKeySequence::SelectPreviousPage) { 1610 e->accept(); 1611 d->pageUpDown(QTextCursor::Up, QTextCursor::KeepAnchor); 1612 return; 1613 } else if (e ==QKeySequence::SelectNextPage) { 1614 e->accept(); 1615 d->pageUpDown(QTextCursor::Down, QTextCursor::KeepAnchor); 1616 return; 1617 } 1618 } 1619 if (tif & (Qt::TextSelectableByKeyboard | Qt::TextEditable)) { 1620 if (e == QKeySequence::MoveToPreviousPage) { 1621 e->accept(); 1622 d->pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor); 1623 return; 1624 } else if (e == QKeySequence::MoveToNextPage) { 1625 e->accept(); 1626 d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor); 1627 return; 1628 } 1629 } 1630 1631 if (!(tif & Qt::TextEditable)) { 1555 1632 switch (e->key()) { 1556 1633 case Qt::Key_Space: … … 1578 1655 return; 1579 1656 } 1580 1581 #ifndef QT_NO_SHORTCUT1582 if (e == QKeySequence::MoveToPreviousPage) {1583 e->accept();1584 d->pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor);1585 return;1586 } else if (e == QKeySequence::MoveToNextPage) {1587 e->accept();1588 d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor);1589 return;1590 } else if (e == QKeySequence::SelectPreviousPage) {1591 e->accept();1592 d->pageUpDown(QTextCursor::Up, QTextCursor::KeepAnchor);1593 return;1594 } else if (e ==QKeySequence::SelectNextPage) {1595 e->accept();1596 d->pageUpDown(QTextCursor::Down, QTextCursor::KeepAnchor);1597 return;1598 }1599 1657 #endif // QT_NO_SHORTCUT 1600 1601 1658 1602 1659 d->sendControlEvent(e); … … 1609 1666 // Cursor position didn't change, so we want to leave 1610 1667 // these keys to change focus. 1668 e->ignore(); 1669 return; 1670 } 1671 break; 1672 case Qt::Key_Left: 1673 case Qt::Key_Right: 1674 if (QApplication::keypadNavigationEnabled() 1675 && QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) { 1676 // Same as for Key_Up and Key_Down. 1611 1677 e->ignore(); 1612 1678 return; … … 1711 1777 if (brush.style() >= Qt::LinearGradientPattern && brush.style() <= Qt::ConicalGradientPattern) { 1712 1778 if (!gradientRect.isNull()) { 1713 QTransform m; 1714 m.translate(gradientRect.left(), gradientRect.top()); 1779 QTransform m = QTransform::fromTranslate(gradientRect.left(), gradientRect.top()); 1715 1780 m.scale(gradientRect.width(), gradientRect.height()); 1716 1781 brush.setTransform(m); … … 1742 1807 QTextBlock block = firstVisibleBlock(); 1743 1808 qreal maximumWidth = document()->documentLayout()->documentSize().width(); 1744 1809 1810 // Set a brush origin so that the WaveUnderline knows where the wave started 1811 painter.setBrushOrigin(offset); 1812 1745 1813 // keep right margin clean from full-width selection 1746 1814 int maxX = offset.x() + qMax((qreal)viewportRect.width(), maximumWidth) … … 1906 1974 d->ensureCursorVisible(); 1907 1975 } 1976 1977 if (!isReadOnly() && rect().contains(e->pos())) 1978 d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus); 1979 d->clickCausedFocus = 0; 1908 1980 } 1909 1981 … … 2006 2078 #endif 2007 2079 d->sendControlEvent(e); 2080 ensureCursorVisible(); 2008 2081 } 2009 2082 … … 2039 2112 { 2040 2113 Q_D(QPlainTextEdit); 2114 if (e->reason() == Qt::MouseFocusReason) { 2115 d->clickCausedFocus = 1; 2116 } 2041 2117 QAbstractScrollArea::focusInEvent(e); 2042 2118 d->sendControlEvent(e); … … 2305 2381 flags = Qt::TextEditorInteraction; 2306 2382 } 2307 setAttribute(Qt::WA_InputMethodEnabled, !ro);2383 setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this)); 2308 2384 d->control->setTextInteractionFlags(flags); 2309 2385 }
Note:
See TracChangeset
for help on using the changeset viewer.