13#include <QtCore/qmath.h>
14#include <QtGui/qguiapplication.h>
15#include <QtGui/qevent.h>
16#include <QtGui/qpainter.h>
17#include <QtGui/qtextobject.h>
18#include <QtGui/qtexttable.h>
19#include <QtQml/qqmlinfo.h>
20#include <QtQuick/qsgsimplerectnode.h>
22#include <private/qqmlglobal_p.h>
23#include <private/qqmlproperty_p.h>
24#include <private/qtextengine_p.h>
25#include <private/qsgadaptationlayer_p.h>
97#if !defined(QQUICKTEXT_LARGETEXT_THRESHOLD)
98 #define QQUICKTEXT_LARGETEXT_THRESHOLD 10000
107 RootNode() : cursorNode(
nullptr), frameDecorationsNode(
nullptr)
112 if (frameDecorationsNode) {
114 delete frameDecorationsNode;
116 frameDecorationsNode = newNode;
125 cursorNode = newNode;
157#if QT_CONFIG(texthtmlparser)
159 d->text =
d->control->toHtml();
162#if QT_CONFIG(textmarkdownwriter)
164 d->text =
d->control->toMarkdown();
167 d->text =
d->control->toPlainText();
168 d->textCached =
true;
386 d->document->clearResources();
391 }
else if (
d->richText) {
392#if QT_CONFIG(texthtmlparser)
393 d->control->setHtml(
text);
395 d->control->setPlainText(
text);
397 }
else if (
d->markdownText) {
398 d->control->setMarkdownText(
text);
400 d->control->setPlainText(
text);
410void QQuickTextEdit::q_invalidate()
414 if (
d->document !=
nullptr)
415 d->document->markContentsDirty(0,
d->document->characterCount());
416 invalidateFontCaches();
437 return d->control->preeditText();
493 const bool wasRich =
d->richText;
494 const bool wasMarkdown =
d->markdownText;
499#if QT_CONFIG(texthtmlparser)
500 if (wasRich && !
d->richText && !
d->markdownText) {
501 d->control->setPlainText(!
d->textCached ?
d->control->toHtml() :
d->text);
503 }
else if (!wasRich &&
d->richText) {
504 d->control->setHtml(!
d->textCached ?
d->control->toPlainText() :
d->text);
508#if QT_CONFIG(textmarkdownwriter) && QT_CONFIG(textmarkdownreader)
509 if (wasMarkdown && !
d->markdownText && !
d->richText) {
510 d->control->setPlainText(!
d->textCached ?
d->control->toMarkdown() :
d->text);
512 }
else if (!wasMarkdown &&
d->markdownText) {
513 d->control->setMarkdownText(!
d->textCached ?
d->control->toPlainText() :
d->text);
520 d->control->setAcceptRichText(
d->format !=
PlainText);
544 return d->renderType;
555 d->updateDefaultTextOption();
564 return d->sourceFont;
570 if (
d->sourceFont ==
font)
573 d->sourceFont =
font;
576 if (
d->font.pointSizeF() != -1) {
579 d->font.setPointSizeF(
size/2.0);
582 if (oldFont !=
d->font) {
583 d->document->setDefaultFont(
d->font);
586 moveCursorDelegate();
589 updateWholeDocument();
625 updateWholeDocument();
637 return d->selectionColor;
643 if (
d->selectionColor ==
color)
646 d->selectionColor =
color;
647 updateWholeDocument();
659 return d->selectedTextColor;
665 if (
d->selectedTextColor ==
color)
668 d->selectedTextColor =
color;
669 updateWholeDocument();
714 bool forceAlign =
d->hAlignImplicit &&
d->effectiveLayoutMirror;
715 d->hAlignImplicit =
false;
717 d->updateDefaultTextOption();
725 d->hAlignImplicit =
true;
727 d->updateDefaultTextOption();
736 if (!
d->hAlignImplicit &&
d->effectiveLayoutMirror) {
748 return effectiveAlignment;
758 if (oldEffectiveHAlign !=
q->effectiveHAlign())
759 emit q->effectiveHorizontalAlignmentChanged();
769 while (!character->
isNull()) {
807 if (
q->isComponentComplete()) {
811 emit q->effectiveHorizontalAlignmentChanged();
819 qCDebug(lcVP) <<
q <<
"sees that" << transformedItem <<
"moved in VP" <<
q->
clipRect();
828 qCDebug(lcVP) <<
"viewport" << vp <<
"now goes beyond rendered region" <<
renderedRegion <<
"; updating";
829 q->updateWholeDocument();
831 const bool textCursorVisible =
cursorVisible &&
q->cursorRectangle().intersects(vp);
842Qt::InputMethodHints QQuickTextEditPrivate::effectiveInputMethodHints()
const
851 qreal oldPadding =
q->topPadding();
858 q->updateWholeDocument();
859 emit q->topPaddingChanged();
866 qreal oldPadding =
q->leftPadding();
873 q->updateWholeDocument();
874 emit q->leftPaddingChanged();
881 qreal oldPadding =
q->rightPadding();
888 q->updateWholeDocument();
889 emit q->rightPaddingChanged();
896 qreal oldPadding =
q->bottomPadding();
903 q->updateWholeDocument();
904 emit q->bottomPaddingChanged();
910 return !
extra.isAllocated() ||
extra->implicitResize;
916 extra.value().implicitResize =
false;
917 else if (
extra.isAllocated())
918 extra->implicitResize =
true;
933 d->updateDefaultTextOption();
935 moveCursorDelegate();
968 if (
mode ==
d->wrapMode)
971 d->updateDefaultTextOption();
1003 return qMax(0,
d->document->characterCount() - 1);
1015 return d->contentSize.width();
1027 return d->contentSize.height();
1042 if (
d->baseUrl.isEmpty()) {
1055 d->document->setBaseUrl(
url);
1080 return d->control->cursorRect(
c).translated(
d->xoff,
d->yoff);
1106 const int preeditLength =
layout
1107 ?
layout->preeditAreaText().size()
1109 if (preeditLength > 0
1110 &&
d->document->documentLayout()->blockBoundingRect(
cursor.block()).contains(
x,
y)) {
1111 r =
r >
cursor.position() + preeditLength
1164 d->control->setTextCursor(
cursor);
1213 d->control->setTextCursor(
cursor);
1226 return d->cursorVisible;
1232 if (
d->cursorVisible == on)
1234 d->cursorVisible = on;
1237 if (!on && !
d->persistentSelection)
1238 d->control->setCursorIsFocusIndicator(
true);
1239 d->control->setCursorVisible(on);
1258 return d->control->textCursor().position();
1264 if (pos < 0 || pos >=
d->document->characterCount())
1270 d->control->setTextCursor(
cursor);
1271 d->control->updateCursorRectangle(
true);
1290 return d->cursorComponent;
1299void QQuickTextEdit::createCursor()
1302 d->cursorPending =
true;
1319 return d->control->textCursor().selectionStart();
1335 return d->control->textCursor().selectionEnd();
1355#if QT_CONFIG(texthtmlparser)
1356 return d->richText ||
d->markdownText
1357 ?
d->control->textCursor().selectedText()
1358 :
d->control->textCursor().selection().toPlainText();
1360 return d->control->textCursor().selection().toPlainText();
1373 return d->focusOnPress;
1379 if (
d->focusOnPress == on)
1381 d->focusOnPress = on;
1394 return d->persistentSelection;
1400 if (
d->persistentSelection == on)
1402 d->persistentSelection = on;
1414 return d->textMargin;
1420 if (
d->textMargin == margin)
1422 d->textMargin = margin;
1423 d->document->setDocumentMargin(
d->textMargin);
1470 return d->inputMethodHints;
1481 if (hints ==
d->inputMethodHints)
1484 d->inputMethodHints = hints;
1496 updateWholeDocument();
1497 moveCursorDelegate();
1515#if QT_CONFIG(texthtmlparser)
1517 d->control->setHtml(
d->text);
1520#if QT_CONFIG(textmarkdownreader)
1521 if (
d->markdownText)
1522 d->control->setMarkdownText(
d->text);
1525 if (!
d->text.isEmpty()) {
1526 if (
d->markdownText)
1527 d->control->setMarkdownText(
d->text);
1529 d->control->setPlainText(
d->text);
1533 d->determineHorizontalAlignment();
1534 d->updateDefaultTextOption();
1560 if (
d->selectByKeyboardSet)
1561 return d->selectByKeyboard;
1569 if (!
d->selectByKeyboardSet || was != on) {
1570 d->selectByKeyboardSet =
true;
1571 d->selectByKeyboard = on;
1576 emit selectByKeyboardChanged(on);
1606 return d->selectByMouse;
1612 if (
d->selectByMouse == on)
1615 d->selectByMouse = on;
1622#if QT_CONFIG(cursor)
1623 d->updateMouseCursorShape();
1641 return d->mouseSelectionMode;
1647 if (
d->mouseSelectionMode !=
mode) {
1648 d->mouseSelectionMode =
mode;
1669 setFlag(QQuickItem::ItemAcceptsInputMethod, !
r);
1672 if (
d->selectByMouse)
1674 if (
d->selectByKeyboardSet &&
d->selectByKeyboard)
1676 else if (!
d->selectByKeyboardSet && !
r)
1680 d->control->setTextInteractionFlags(
flags);
1686#if QT_CONFIG(cursor)
1687 d->updateMouseCursorShape();
1689 q_canPasteChanged();
1691 if (!
d->selectByKeyboardSet)
1692 emit selectByKeyboardChanged(!
r);
1719 return d->control->cursorRect().translated(
d->xoff,
d->yoff);
1727 if (
event->isAccepted())
1750 return d->control->overwriteMode();
1756 d->control->setOverwriteMode(overwrite);
1767 if (!
event->isAccepted())
1779 if (!
event->isAccepted())
1793 d->control->setTextCursor(
c);
1804 d->control->selectAll();
1817 d->control->setTextCursor(
c);
1836 if (
start < 0 || end < 0 || start >=
d->document->characterCount() ||
end >=
d->document->characterCount())
1843 d->control->setTextCursor(
cursor);
1848 updateInputMethod();
1861 qmlWarning(
this) <<
"isRightToLeft(start, end) called with the end property being smaller than the start.";
1868#if QT_CONFIG(clipboard)
1874void QQuickTextEdit::cut()
1885void QQuickTextEdit::copy()
1896void QQuickTextEdit::paste()
1899 d->control->paste();
1940 if (
d->focusOnPress){
1946 qGuiApp->inputMethod()->show();
1951 if (!
event->isAccepted())
1964 if (!
event->isAccepted())
1976 if (!
event->isAccepted())
1988 if (!
event->isAccepted())
2018 v = (bool)(
flags() & ItemAcceptsInputMethod);
2021 v = (int)
d->effectiveInputMethodHints();
2024 v = QQuickItem::inputMethodQuery(
property);
2034 v =
QVariant(
v.toRectF().translated(
d->xoff,
d->yoff));
2050void QQuickTextEdit::triggerPreprocess()
2070 transformMatrix.
translate(topLeft.
x(), topLeft.
y());
2080void QQuickTextEdit::invalidateFontCaches()
2083 if (
d->document ==
nullptr)
2087 for (block =
d->document->firstBlock(); block.
isValid(); block = block.
next()) {
2096 engine->setTextColor(textColor);
2097 engine->setSelectedTextColor(selectedTextColor);
2098 engine->setSelectionColor(selectionColor);
2108 && oldNode !=
nullptr) {
2120 d->textNodeMap.clear();
2125 RootNode *rootNode =
static_cast<RootNode *
>(oldNode);
2127 std::optional<int> firstPosAcrossAllNodes;
2128 if (nodeIterator !=
d->textNodeMap.end())
2129 firstPosAcrossAllNodes = nodeIterator->startPos();
2131 while (nodeIterator !=
d->textNodeMap.end() && !nodeIterator->dirty())
2137 if (!oldNode || nodeIterator < d->textNodeMap.end() ||
d->textNodeMap.isEmpty()) {
2140 rootNode =
new RootNode;
2142 int firstDirtyPos = 0;
2143 if (nodeIterator !=
d->textNodeMap.end()) {
2144 firstDirtyPos = nodeIterator->startPos();
2148 auto it =
d->textNodeMap.constEnd();
2149 while (
it != nodeIterator) {
2153 firstCleanNode =
it->textNode();
2156 rootNode->removeChildNode(nodeIterator->textNode());
2157 delete nodeIterator->textNode();
2158 nodeIterator =
d->textNodeMap.erase(nodeIterator);
2159 }
while (nodeIterator !=
d->textNodeMap.constEnd() && nodeIterator->textNode() != firstCleanNode);
2170 rootNode->resetFrameDecorations(
d->createTextNode());
2171 resetEngine(&frameDecorationsEngine,
d->color,
d->selectedTextColor,
d->selectionColor);
2175 int currentNodeSize = 0;
2176 int nodeStart = firstDirtyPos;
2179 basePositionMatrix.
translate(basePosition.
x(), basePosition.
y());
2180 rootNode->setMatrix(basePositionMatrix);
2183 const TextNode firstCleanNode = (nodeIterator !=
d->textNodeMap.end()) ? *nodeIterator
2187 frames.
append(
d->document->rootFrame());
2190 d->firstBlockInViewport = -1;
2191 d->firstBlockPastViewport = -1;
2204 node =
d->createTextNode();
2205 updateNodeTransform(node,
d->document->documentLayout()->frameBoundingRect(textFrame).topLeft());
2210 nodeOffset =
d->document->documentLayout()->blockBoundingRect(block).topLeft();
2215 qCDebug(lcVP) <<
"non-flow frame" << coveredRegion <<
"in viewport?" << inView;
2229 std::sort(frameBoundaries.
begin(), frameBoundaries.
end());
2232 while (!
it.atEnd()) {
2234 if (block.
position() < firstDirtyPos) {
2239 if (!
engine.hasContents())
2240 nodeOffset =
d->document->documentLayout()->blockBoundingRect(block).topLeft();
2249 const bool potentiallyScrollingBackwards = firstPosAcrossAllNodes && *firstPosAcrossAllNodes == firstDirtyPos;
2250 if (
d->firstBlockInViewport < 0 && inView && potentiallyScrollingBackwards) {
2253 qCDebug(lcVP) <<
"checking backwards from block" << block.
blockNumber() <<
"@" << nodeOffset.
y() << coveredRegion;
2254 while (
it != textFrame->
begin() &&
it.currentBlock().layout() &&
2255 it.currentBlock().layout()->boundingRect().top() + nodeOffset.
y() >
viewport.top()) {
2256 nodeOffset =
d->document->documentLayout()->blockBoundingRect(
it.currentBlock()).topLeft();
2259 if (!
it.currentBlock().layout())
2262 block =
it.currentBlock();
2264 firstDirtyPos =
it.currentBlock().position();
2266 qCWarning(lcVP) <<
"failed to find a text block with layout during back-scrolling";
2269 qCDebug(lcVP) <<
"first block in viewport" << block.
blockNumber() <<
"@" << nodeOffset.
y() << coveredRegion;
2272 d->renderedRegion = coveredRegion;
2274 if (nodeOffset.
y() >
viewport.bottom()) {
2276 if (
d->firstBlockInViewport >= 0 &&
d->firstBlockPastViewport < 0) {
2278 <<
"@" << nodeOffset.
y() <<
"total region rendered" <<
d->renderedRegion;
2284 d->renderedRegion =
d->renderedRegion.united(coveredRegion);
2288 bool createdNodeInView =
false;
2290 if (!
engine.hasContents()) {
2291 if (node && !node->
parent())
2292 d->addCurrentTextNodeToRoot(&
engine, rootNode, node, nodeIterator, nodeStart);
2293 node =
d->createTextNode();
2294 createdNodeInView =
true;
2299 currentNodeSize += block.
length();
2305 if (node && (currentNodeSize >
nodeBreakingSize || lowerBound == frameBoundaries.
constEnd() || *lowerBound > nodeStart)) {
2306 currentNodeSize = 0;
2308 d->addCurrentTextNodeToRoot(&
engine, rootNode, node, nodeIterator, nodeStart);
2309 if (!createdNodeInView)
2310 node =
d->createTextNode();
2318 d->addCurrentTextNodeToRoot(&
engine, rootNode, node, nodeIterator, nodeStart);
2322 rootNode->prependChildNode(rootNode->frameDecorationsNode);
2324 Q_ASSERT(nodeIterator ==
d->textNodeMap.end()
2325 || (nodeIterator->textNode() == firstCleanNode.
textNode()
2326 && nodeIterator->startPos() == firstCleanNode.
startPos()));
2328 if (firstCleanNode.
textNode() !=
nullptr) {
2330 QPointF currentOffset =
d->document->documentLayout()->blockBoundingRect(
2331 d->document->findBlock(firstCleanNode.
startPos())).topLeft();
2332 QPointF delta = currentOffset - oldOffset;
2333 while (nodeIterator !=
d->textNodeMap.end()) {
2334 QMatrix4x4 transformMatrix = nodeIterator->textNode()->matrix();
2336 nodeIterator->textNode()->setMatrix(transformMatrix);
2344 std::sort(
d->textNodeMap.begin(),
d->textNodeMap.end());
2347 if (
d->cursorComponent ==
nullptr) {
2349 if (!
isReadOnly() &&
d->cursorVisible &&
d->control->cursorOn() &&
d->control->cursorVisible())
2350 cursor =
d->sceneGraphContext()->createInternalRectangleNode(
d->control->cursorRect(),
d->color);
2351 rootNode->resetCursorNode(
cursor);
2354 invalidateFontCaches();
2361 invalidateFontCaches();
2373 if (!
d->canPasteValid) {
2390 return d->document->isUndoAvailable();
2403 return d->document->isRedoAvailable();
2424 return d->control->hasImState();
2434 , explicitTopPadding(
false)
2435 , explicitLeftPadding(
false)
2436 , explicitRightPadding(
false)
2437 , explicitBottomPadding(
false)
2438 , implicitResize(true)
2446#if QT_CONFIG(clipboard)
2454 q->setFlag(QQuickItem::ItemAcceptsInputMethod);
2458 q->setAcceptHoverEvents(
true);
2466 q->setKeepMouseGrab(
true);
2478#if QT_CONFIG(clipboard)
2495#if QT_CONFIG(cursor)
2496 updateMouseCursorShape();
2503 if (!
q->isReadOnly() &&
q->hasActiveFocus() &&
qGuiApp)
2507void QQuickTextEdit::q_textChanged()
2510 d->textCached =
false;
2512 d->contentDirection =
d->textDirection(
it.text());
2516 d->determineHorizontalAlignment();
2517 d->updateDefaultTextOption();
2520 markDirtyNodesForRange(0,
d->document->characterCount(), 0);
2521 if (isComponentComplete()) {
2530void QQuickTextEdit::markDirtyNodesForRange(
int start,
int end,
int charDelta)
2544 if (
it != textNodeMapBegin) {
2547 it = std::lower_bound(textNodeMapBegin, textNodeMapEnd, otherDummy);
2551 while (
it != textNodeMapEnd) {
2552 if (
it->startPos() <=
end)
2555 it->moveStartPos(charDelta);
2562void QQuickTextEdit::q_contentsChange(
int pos,
int charsRemoved,
int charsAdded)
2566 const int editRange =
pos +
qMax(charsAdded, charsRemoved);
2567 const int delta = charsAdded - charsRemoved;
2569 markDirtyNodesForRange(
pos, editRange, delta);
2571 if (isComponentComplete()) {
2578void QQuickTextEdit::moveCursorDelegate()
2582 updateInputMethod();
2584 emit cursorRectangleChanged();
2587 QRectF cursorRect = cursorRectangle();
2588 d->cursorItem->setX(cursorRect.
x());
2589 d->cursorItem->setY(cursorRect.
y());
2590 d->cursorItem->setHeight(cursorRect.
height());
2593void QQuickTextEdit::updateSelection()
2598 if (
d->control->textCursor().hasSelection() ||
d->hadSelection) {
2599 markDirtyNodesForRange(
qMin(
d->lastSelectionStart,
d->control->textCursor().selectionStart()),
qMax(
d->control->textCursor().selectionEnd(),
d->lastSelectionEnd), 0);
2600 if (isComponentComplete()) {
2607 d->hadSelection =
d->control->textCursor().hasSelection();
2609 if (
d->lastSelectionStart !=
d->control->textCursor().selectionStart()) {
2610 d->lastSelectionStart =
d->control->textCursor().selectionStart();
2611 emit selectionStartChanged();
2613 if (
d->lastSelectionEnd !=
d->control->textCursor().selectionEnd()) {
2614 d->lastSelectionEnd =
d->control->textCursor().selectionEnd();
2615 emit selectionEndChanged();
2625 d->contentSize.width(),
2626 d->contentSize.height());
2628 int cursorWidth = 1;
2631 else if (!
d->document->isEmpty())
2635 r.setRight(
r.right() + cursorWidth);
2644 int cursorWidth = 1;
2646 cursorWidth =
d->cursorItem->width();
2647 if (!
d->document->isEmpty())
2652 r.setRight(
r.right() + cursorWidth);
2670void QQuickTextEdit::updateSize()
2673 if (!isComponentComplete()) {
2681 if (!
d->requireImplicitWidth) {
2684 if (
d->requireImplicitWidth)
2687 if (
d->requireImplicitWidth) {
2688 d->document->setTextWidth(-1);
2689 const qreal naturalWidth =
d->document->idealWidth();
2690 const bool wasInLayout =
d->inLayout;
2692 if (
d->isImplicitResizeEnabled())
2693 setImplicitWidth(naturalWidth + leftPadding() + rightPadding());
2694 d->inLayout = wasInLayout;
2698 const qreal newTextWidth =
width() - leftPadding() - rightPadding();
2699 if (
d->document->textWidth() != newTextWidth)
2700 d->document->setTextWidth(newTextWidth);
2701 }
else if (
d->wrapMode == NoWrap) {
2705 const qreal newTextWidth =
d->document->idealWidth();
2706 if (
d->document->textWidth() != newTextWidth)
2707 d->document->setTextWidth(newTextWidth);
2709 d->document->setTextWidth(-1);
2714 const qreal newWidth =
d->document->idealWidth();
2716 if (
d->isImplicitResizeEnabled()) {
2719 setImplicitSize(newWidth + leftPadding() + rightPadding(), newHeight + topPadding() + bottomPadding());
2721 setImplicitHeight(newHeight + topPadding() + bottomPadding());
2726 setBaselineOffset(fm.ascent() +
d->yoff +
d->textMargin);
2729 if (
d->contentSize !=
size) {
2730 d->contentSize =
size;
2732 const bool wasInResize =
d->inResize;
2735 emit contentSizeChanged();
2736 d->inResize = wasInResize;
2741void QQuickTextEdit::updateWholeDocument()
2744 if (!
d->textNodeMap.isEmpty()) {
2749 if (isComponentComplete()) {
2756void QQuickTextEdit::invalidateBlock(
const QTextBlock &block)
2761 if (isComponentComplete()) {
2768void QQuickTextEdit::updateCursor()
2771 if (isComponentComplete() &&
isVisible()) {
2778void QQuickTextEdit::q_linkHovered(
const QString &link)
2781 emit linkHovered(link);
2782#if QT_CONFIG(cursor)
2784 d->updateMouseCursorShape();
2791void QQuickTextEdit::q_markerHovered(
bool hovered)
2794#if QT_CONFIG(cursor)
2796 d->updateMouseCursorShape();
2803void QQuickTextEdit::q_updateAlignment()
2806 if (
d->determineHorizontalAlignment()) {
2807 d->updateDefaultTextOption();
2809 moveCursorDelegate();
2813void QQuickTextEdit::updateTotalLines()
2823 subLines +=
layout->lineCount()-1;
2826 int newTotalLines =
d->document->lineCount() + subLines;
2827 if (
d->lineCount != newTotalLines) {
2828 d->lineCount = newTotalLines;
2829 emit lineCountChanged();
2837 const Qt::Alignment oldAlignment =
opt.alignment();
2848 opt.setAlignment((Qt::Alignment)(
int)(horizontalAlignment |
vAlign));
2850 opt.setAlignment(Qt::Alignment(
vAlign));
2854 opt.setTextDirection(
qGuiApp->inputMethod()->inputDirection());
2864 bool oldUseDesignMetrics =
opt.useDesignMetrics();
2867 if (oldWrapMode !=
opt.wrapMode() || oldAlignment !=
opt.alignment()
2868 || oldTextDirection !=
opt.textDirection()
2869 || oldUseDesignMetrics !=
opt.useDesignMetrics()) {
2877 d->handleFocusEvent(
event);
2884 d->handleFocusEvent(
event);
2892 if (!
q->isReadOnly())
2893 q->setCursorVisible(
focus);
2896 q->q_updateAlignment();
2899 qGuiApp->inputMethod()->show();
2901 q,
SLOT(q_updateAlignment()));
2906 q,
SLOT(q_updateAlignment()));
2914 emit q->editingFinished();
2934void QQuickTextEdit::q_canPasteChanged()
2937 bool old =
d->canPaste;
2938 d->canPaste =
d->control->canPaste();
2939 bool changed = old!=
d->canPaste || !
d->canPasteValid;
2940 d->canPasteValid =
true;
2942 emit canPasteChanged();
2961#if QT_CONFIG(texthtmlparser)
2962 return d->richText ||
d->markdownText
2964 :
cursor.selection().toPlainText();
2966 return cursor.selection().toPlainText();
2990#if QT_CONFIG(texthtmlparser)
2991 return cursor.selection().toHtml();
2993 return cursor.selection().toPlainText();
2995 }
else if (
d->markdownText) {
2996#if QT_CONFIG(textmarkdownwriter)
2997 return cursor.selection().toMarkdown();
2999 return cursor.selection().toPlainText();
3002 return cursor.selection().toPlainText();
3014 if (position < 0 || position >=
d->document->characterCount())
3020#if QT_CONFIG(texthtmlparser)
3025 }
else if (
d->markdownText) {
3026#if QT_CONFIG(textmarkdownreader)
3034 d->control->updateCursorRectangle(
false);
3051 cursor.removeSelectedText();
3052 d->control->updateCursorRectangle(
false);
3069 if (!
d->quickDocument)
3071 return d->quickDocument;
3080#if QT_CONFIG(cursor)
3081void QQuickTextEditPrivate::updateMouseCursorShape()
3121 return d->control->hoveredLink();
3123#if QT_CONFIG(cursor)
3126 return d->control->anchorAt(
pos);
3136 if (
d->isLinkHoveredConnected())
3144 if (
d->isLinkHoveredConnected())
3152 if (
d->isLinkHoveredConnected())
3173 if (!
d->document->isEmpty())
3177#if QT_CONFIG(texthtmlparser)
3182 }
else if (
d->format == MarkdownText) {
3183#if QT_CONFIG(textmarkdownreader)
3193 d->control->updateCursorRectangle(
false);
3208 return d->control->anchorAt(
QPointF(
x + topPadding(),
y + leftPadding()));
3225 return d->padding();
3234 d->extra.value().padding =
padding;
3236 if (isComponentComplete()) {
3240 emit paddingChanged();
3241 if (!
d->extra.isAllocated() || !
d->extra->explicitTopPadding)
3242 emit topPaddingChanged();
3243 if (!
d->extra.isAllocated() || !
d->extra->explicitLeftPadding)
3244 emit leftPaddingChanged();
3245 if (!
d->extra.isAllocated() || !
d->extra->explicitRightPadding)
3246 emit rightPaddingChanged();
3247 if (!
d->extra.isAllocated() || !
d->extra->explicitBottomPadding)
3248 emit bottomPaddingChanged();
3259 if (
d->extra.isAllocated() &&
d->extra->explicitTopPadding)
3260 return d->extra->topPadding;
3261 return d->padding();
3273 d->setTopPadding(0,
true);
3279 if (
d->extra.isAllocated() &&
d->extra->explicitLeftPadding)
3280 return d->extra->leftPadding;
3281 return d->padding();
3293 d->setLeftPadding(0,
true);
3299 if (
d->extra.isAllocated() &&
d->extra->explicitRightPadding)
3300 return d->extra->rightPadding;
3301 return d->padding();
3313 d->setRightPadding(0,
true);
3319 if (
d->extra.isAllocated() &&
d->extra->explicitBottomPadding)
3320 return d->extra->bottomPadding;
3321 return d->padding();
3333 d->setBottomPadding(0,
true);
3347 return d->document->defaultTextOption().tabStopDistance();
3353 QTextOption textOptions =
d->document->defaultTextOption();
3358 d->document->setDefaultTextOption(textOptions);
3373void QQuickTextEdit::clear()
3376 d->resetInputMethod();
3377 d->control->clear();
3380#ifndef QT_NO_DEBUG_STREAM
3385 debug <<
"Node(startPos:" <<
n.m_startPos <<
"dirty:" <<
n.m_dirty <<
n.m_node <<
')';
3390#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
3391void QQuickTextEdit::setOldSelectionDefault()
3394 d->selectByMouse =
false;
3395 setKeepMouseGrab(
false);
3397 d->control->setTouchDragSelectionEnabled(
true);
3398 qCDebug(lcTextEdit,
"pre-6.4 behavior chosen: selectByMouse defaults false; if enabled, touchscreen acts like a mouse");
3405 setOldSelectionDefault();
3411#include "moc_qquicktextedit_p.cpp"
void updateBlock(const QTextBlock &block)
Direction direction() const noexcept
Returns the character's direction.
constexpr bool isNull() const noexcept
Returns true if the character is the Unicode character 0x0000 ('\0'); otherwise returns false.
The QClipboard class provides access to the window system clipboard.
The QColor class provides colors based on RGB, HSV or CMYK values.
static QPoint pos()
Returns the position of the cursor (hot spot) of the primary screen in global screen coordinates.
The QFocusEvent class contains event parameters for widget focus events.
\reentrant \inmodule QtGui
\reentrant \inmodule QtGui
int height() const
Returns the height of the font.
static QClipboard * clipboard()
Returns the object for interacting with the clipboard.
static QInputMethod * inputMethod()
returns the input method.
The QKeyEvent class describes a key event.
qsizetype size() const noexcept
bool isEmpty() const noexcept
const_iterator constBegin() const noexcept
void reserve(qsizetype size)
void append(parameter_type t)
const_iterator constEnd() const noexcept
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
QPoint map(const QPoint &point) const
Maps point by multiplying this matrix by point.
void translate(const QVector3D &vector)
Multiplies this matrix by another that translates coordinates by the components of vector.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
virtual bool event(QEvent *event)
This virtual function receives events to an object and should return true if the event e was recogniz...
\inmodule QtCore\reentrant
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
The QQmlComponent class encapsulates a QML component definition.
The QQmlContext class defines a context within a QML engine.
virtual void componentComplete()=0
Invoked after the root component that caused this instantiation has completed construction.
static bool isEventFromMouseOrTouchpad(const QPointerEvent *ev)
virtual bool transformChanged(QQuickItem *transformedItem)
virtual void implicitWidthChanged()
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
virtual void focusOutEvent(QFocusEvent *)
This event handler can be reimplemented in a subclass to receive focus-out events for an item.
virtual void mouseReleaseEvent(QMouseEvent *event)
This event handler can be reimplemented in a subclass to receive mouse release events for an item.
Flags flags() const
Returns the item flags for this item.
virtual void mouseDoubleClickEvent(QMouseEvent *event)
This event handler can be reimplemented in a subclass to receive mouse double-click events for an ite...
void setFlag(Flag flag, bool enabled=true)
Enables the specified flag for this item if enabled is true; if enabled is false, the flag is disable...
virtual void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
virtual void keyPressEvent(QKeyEvent *event)
This event handler can be reimplemented in a subclass to receive key press events for an item.
bool hasActiveFocus() const
virtual void mousePressEvent(QMouseEvent *event)
This event handler can be reimplemented in a subclass to receive mouse press events for an item.
bool isComponentComplete() const
Returns true if construction of the QML component is complete; otherwise returns false.
bool heightValid() const
Returns whether the height property has been set explicitly.
void setKeepMouseGrab(bool)
Sets whether the mouse input should remain exclusively with this item.
Q_INVOKABLE void forceActiveFocus()
\qmlmethod point QtQuick::Item::mapToItem(Item item, real x, real y) \qmlmethod point QtQuick::Item::...
bool widthValid() const
Returns whether the width property has been set explicitly.
virtual void keyReleaseEvent(QKeyEvent *event)
This event handler can be reimplemented in a subclass to receive key release events for an item.
virtual QRectF clipRect() const
Returns the rectangular area within this item that is currently visible in \l viewportItem(),...
virtual void focusInEvent(QFocusEvent *)
This event handler can be reimplemented in a subclass to receive focus-in events for an item.
void update()
Schedules a call to updatePaintNode() for this item.
void polish()
Schedules a polish event for this item.
virtual void mouseMoveEvent(QMouseEvent *event)
This event handler can be reimplemented in a subclass to receive mouse move events for an item.
void setTextInteractionFlags(Qt::TextInteractionFlags flags)
void linkHovered(const QString &link)
virtual void processEvent(QEvent *e, const QTransform &transform)
void setAcceptRichText(bool accept)
void markerHovered(bool marker)
QTextCursor textCursor() const
void setCursorIsFocusIndicator(bool b)
void setCursorVisible(bool visible)
The QQuickTextDocument class provides access to the QTextDocument of QQuickTextEdit....
QList< Node >::iterator TextNodeIterator
QQuickTextEdit::HAlignment hAlign
void addCurrentTextNodeToRoot(QQuickTextNodeEngine *, QSGTransformNode *, QQuickTextNode *, TextNodeIterator &, int startPos)
QList< Node > textNodeMap
void setImplicitResizeEnabled(bool enabled)
bool isImplicitResizeEnabled() const
void setRightPadding(qreal value, bool reset=false)
QLazilyAllocated< ExtraData > extra
Qt::LayoutDirection textDirection(const QString &text) const
Qt::LayoutDirection contentDirection
bool setHAlign(QQuickTextEdit::HAlignment, bool forceAlign=false)
static const int largeTextSizeThreshold
QQuickTextControl * control
QQuickTextDocumentWithImageResources * document
qreal getImplicitWidth() const override
void setLeftPadding(qreal value, bool reset=false)
void updateDefaultTextOption()
QQuickTextEdit::WrapMode wrapMode
bool transformChanged(QQuickItem *transformedItem) override
QQuickTextEdit::VAlignment vAlign
void handleFocusEvent(QFocusEvent *event)
QQuickTextEdit::RenderType renderType
QQuickTextNode * createTextNode()
void setBottomPadding(qreal value, bool reset=false)
bool determineHorizontalAlignment()
void setTopPadding(qreal value, bool reset=false)
bool isLinkHoveredConnected()
bool requireImplicitWidth
void mirrorChange() override
void setFont(const QFont &font)
void setRenderType(RenderType renderType)
void selectWord()
\qmlmethod QtQuick::TextEdit::selectWord()
void resetBottomPadding()
void keyReleaseEvent(QKeyEvent *) override
This is an overloaded member function, provided for convenience. It differs from the above function o...
void setInputMethodHints(Qt::InputMethodHints hints)
void setWrapMode(WrapMode w)
bool isInputMethodComposing() const
\qmlproperty bool QtQuick::TextEdit::inputMethodComposing
void inputMethodComposingChanged()
void setCursorDelegate(QQmlComponent *)
void focusInEvent(QFocusEvent *event) override
This event handler can be reimplemented in a subclass to receive focus-in events for an item.
void hoverMoveEvent(QHoverEvent *event) override
This event handler can be reimplemented in a subclass to receive hover-move events for an item.
void setPersistentSelection(bool on)
void setSelectionColor(const QColor &c)
void setFocusOnPress(bool on)
SelectionMode mouseSelectionMode
void invalidate() override
void keyPressEvent(QKeyEvent *) override
This is an overloaded member function, provided for convenience. It differs from the above function o...
QQuickTextDocument * textDocument
\qmlproperty TextDocument QtQuick::TextEdit::textDocument
HAlignment hAlign() const
\qmlproperty enumeration QtQuick::TextEdit::horizontalAlignment \qmlproperty enumeration QtQuick::Tex...
void mouseMoveEvent(QMouseEvent *event) override
This is an overloaded member function, provided for convenience. It differs from the above function o...
void remove(int start, int end)
\qmlmethod string QtQuick::TextEdit::remove(int start, int end)
void setSelectByMouse(bool)
void setColor(const QColor &c)
void setMouseSelectionMode(SelectionMode mode)
void colorChanged(const QColor &color)
QRectF clipRect() const override
Returns the rectangular area within this item that is currently visible in \l viewportItem(),...
bool event(QEvent *) override
\reimp
void componentComplete() override
Ensures any delayed caching or data loading the class needs to performed is complete.
void setRightPadding(qreal padding)
Qt::InputMethodHints inputMethodHints
void hoverLeaveEvent(QHoverEvent *event) override
This event handler can be reimplemented in a subclass to receive hover-leave events for an item.
Q_INVOKABLE int positionAt(qreal x, qreal y) const
\qmlmethod int QtQuick::TextEdit::positionAt(int x, int y)
bool focusOnPress() const
\qmlproperty bool QtQuick::TextEdit::activeFocusOnPress
void select(int start, int end)
\qmlmethod QtQuick::TextEdit::select(int start, int end)
void setLeftPadding(qreal padding)
void selectAll()
\qmlmethod QtQuick::TextEdit::selectAll()
void activeFocusOnPressChanged(bool activeFocusOnPressed)
void setOverwriteMode(bool overwrite)
void setHAlign(HAlignment align)
void selectedTextColorChanged(const QColor &color)
void setTopPadding(qreal padding)
void setCursorPosition(int pos)
QSGNode * updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) override
Called on the render thread when it is time to sync the state of the item with the scene graph.
void mouseReleaseEvent(QMouseEvent *event) override
This is an overloaded member function, provided for convenience. It differs from the above function o...
void setPadding(qreal padding)
void insert(int position, const QString &text)
\qmlmethod QtQuick::TextEdit::insert(int position, string text)
void setTextFormat(TextFormat format)
void mouseDoubleClickEvent(QMouseEvent *event) override
This is an overloaded member function, provided for convenience. It differs from the above function o...
void textMarginChanged(qreal textMargin)
void inputMethodHintsChanged()
void updatePolish() override
This function should perform any layout as required for this item.
FINALqreal tabStopDistance
void readOnlyChanged(bool isReadOnly)
Q_INVOKABLE QString getFormattedText(int start, int end) const
\qmlmethod string QtQuick::TextEdit::getFormattedText(int start, int end)
QQmlComponent * cursorDelegate
void setTabStopDistance(qreal distance)
VAlignment vAlign() const
void verticalAlignmentChanged(QQuickTextEdit::VAlignment alignment)
void setSelectedTextColor(const QColor &c)
void cursorVisibleChanged(bool isCursorVisible)
void mousePressEvent(QMouseEvent *event) override
This is an overloaded member function, provided for convenience. It differs from the above function o...
void hoverEnterEvent(QHoverEvent *event) override
This event handler can be reimplemented in a subclass to receive hover-enter events for an item.
Q_INVOKABLE QString getText(int start, int end) const
\qmlmethod string QtQuick::TextEdit::getText(int start, int end)
void setBottomPadding(qreal padding)
bool isRightToLeft(int start, int end)
\qmlmethod QtQuick::TextEdit::isRightToLeft(int start, int end)
void selectByMouseChanged(bool selectByMouse)
void setReadOnly(bool)
\qmlproperty bool QtQuick::TextEdit::readOnly
void setSelectByKeyboard(bool)
void deselect()
\qmlmethod QtQuick::TextEdit::deselect()
void fontChanged(const QFont &font)
bool isCursorVisible() const
\qmlproperty bool QtQuick::TextEdit::cursorVisible If true the text edit shows a cursor.
void selectionColorChanged(const QColor &color)
void undo()
\qmlmethod QtQuick::TextEdit::undo()
QQuickTextEdit(QQuickItem *parent=nullptr)
void mouseSelectionModeChanged(QQuickTextEdit::SelectionMode mode)
void focusOutEvent(QFocusEvent *event) override
This event handler can be reimplemented in a subclass to receive focus-out events for an item.
void textFormatChanged(QQuickTextEdit::TextFormat textFormat)
void setVAlign(VAlignment align)
QRectF boundingRect() const override
Returns the extents of the item in its own coordinate system: a rectangle from {0,...
void setBaseUrl(const QUrl &url)
FINALQString preeditText
\qmlproperty string QtQuick::TextEdit::preeditText \readonly
void setTextMargin(qreal margin)
Q_INVOKABLE QRectF positionToRectangle(int) const
\qmlmethod rectangle QtQuick::TextEdit::positionToRectangle(position)
HAlignment effectiveHAlign() const
void redo()
\qmlmethod QtQuick::TextEdit::redo()
void setCursorVisible(bool on)
Q_INVOKABLE void moveCursorSelection(int pos)
\qmlmethod QtQuick::TextEdit::moveCursorSelection(int position, SelectionMode mode)
void persistentSelectionChanged(bool isPersistentSelection)
void setText(const QString &)
\qmlproperty string QtQuick::TextEdit::font.family
void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override
void addToSceneGraph(QQuickTextNode *parent, QQuickText::TextStyle style=QQuickText::Normal, const QColor &styleColor=QColor())
void addFrameDecorations(QTextDocument *document, QTextFrame *frame)
void setUseNativeRenderer(bool on)
static qreal alignedX(qreal textWidth, qreal itemWidth, int alignment)
static void createCursor(Private *d)
static qreal alignedY(qreal textHeight, qreal itemHeight, int alignment)
static void setCursorDelegate(Private *d, QQmlComponent *delegate)
\qmltype Window \instantiates QQuickWindow \inqmlmodule QtQuick
\inmodule QtCore\reentrant
constexpr qreal bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
constexpr qreal y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr qreal height() const noexcept
Returns the height of the rectangle.
constexpr qreal width() const noexcept
Returns the width of the rectangle.
constexpr qreal x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
constexpr QRectF adjusted(qreal x1, qreal y1, qreal x2, qreal y2) const noexcept
Returns a new rectangle with dx1, dy1, dx2 and dy2 added respectively to the existing coordinates of ...
constexpr qreal top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr bool isValid() const noexcept
Returns true if the rectangle is valid, otherwise returns false.
\group qtquick-scenegraph-nodes \title Qt Quick Scene Graph Node classes
void removeChildNode(QSGNode *node)
Removes node from this node's list of children.
void appendChildNode(QSGNode *node)
Appends node to this node's list of children.
QSGNode * parent() const
Returns the parent node of this node.
void setFlag(Flag, bool=true)
Sets the flag f on this node if enabled is true; otherwise clears the flag.
\macro QT_RESTRICTED_CAST_FROM_ASCII
const QChar * constData() const
Returns a pointer to the data stored in the QString.
qsizetype size() const
Returns the number of characters in this string.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
bool isRightToLeft() const
Returns true if the string is read right to left.
int length() const
Returns the length of the block in characters.
bool isValid() const
Returns true if this text block is valid; otherwise returns false.
QTextBlock next() const
Returns the text block in the document after this block, or an empty text block if this is the last o...
QTextLayout * layout() const
Returns the QTextLayout that is used to lay out and display the block's contents.
int position() const
Returns the index of the block's first character within the document.
QString text() const
Returns the block's contents as plain text.
\reentrant \inmodule QtGui
QTextBlock block() const
Returns the block that contains the cursor.
bool hasSelection() const
Returns true if the cursor contains a selection; otherwise returns false.
void contentsChange(int from, int charsRemoved, int charsAdded)
This signal is emitted whenever the document's content changes; for example, when text is inserted or...
void setDefaultTextOption(const QTextOption &option)
QAbstractTextDocumentLayout * documentLayout() const
Returns the document layout for this document.
QTextOption defaultTextOption() const
the default text option will be set on all \l{QTextLayout}s in the document.
void setDefaultFont(const QFont &font)
Sets the default font to use in the document layout.
void setUndoRedoEnabled(bool enable)
void setDocumentMargin(qreal margin)
void resetFontEngineCache()
Position position() const
Returns the positioning policy for frames with this frame format.
int lastPosition() const
Returns the last document position inside the frame.
QList< QTextFrame * > childFrames() const
Returns a (possibly empty) list of the frame's child frames.
QTextFrameFormat frameFormat() const
Returns the frame's format.
iterator begin() const
Returns an iterator pointing to the first document element inside the frame.
int firstPosition() const
Returns the first document position inside the frame.
QTextCursor firstCursorPosition() const
Returns the first cursor position inside the frame.
QTextLine lineForTextPosition(int pos) const
Returns the line that contains the cursor position specified by pos.
QTextEngine * engine() const
QString preeditAreaText() const
Returns the text that is inserted in the layout before editing occurs.
QRectF boundingRect() const
The smallest rectangle that contains all the lines in the layout.
qreal tabStopDistance() const
WrapMode
This enum describes how text is wrapped in a document.
void setTabStopDistance(qreal tabStopDistance)
void textChanged(const QString &newText)
QSet< QString >::iterator it
Combined button and popup list for selecting options.
@ ImInputItemClipRectangle
@ TextSelectableByKeyboard
Q_GUI_EXPORT bool mightBeRichText(const QString &)
Returns true if the string text is likely to be rich text; otherwise returns false.
@ ActiveWindowFocusReason
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
int qRound(qfloat16 d) noexcept
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qBound(const T &min, const T &val, const T &max)
constexpr const T & qMax(const T &a, const T &b)
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLint GLsizei GLsizei height
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLsizei GLsizei GLfloat distance
GLint GLsizei GLsizei GLenum format
GLdouble GLdouble GLdouble GLdouble q
QQmlContext * qmlContext(const QObject *obj)
#define qmlobject_connect(Sender, SenderType, Signal, Receiver, ReceiverType, Method)
Connect Signal of Sender to Method of Receiver.
#define IS_SIGNAL_CONNECTED(Sender, SenderType, Name, Arguments)
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
static void updateNodeTransform(QQuickTextNode *node, const QPointF &topLeft)
#define QQUICKTEXT_LARGETEXT_THRESHOLD
static bool operator<(const TextNode &n1, const TextNode &n2)
static QT_BEGIN_NAMESPACE const int nodeBreakingSize
\qmlsignal QtQuick::TextEdit::linkActivated(string link)
QQuickTextEditPrivate::Node TextNode
void resetEngine(QQuickTextNodeEngine *engine, const QColor &textColor, const QColor &selectedTextColor, const QColor &selectionColor)
QDebug Q_QUICK_PRIVATE_EXPORT operator<<(QDebug debug, const QQuickTextEditPrivate::Node &)
QUrl url("example.com")
[constructor-url-reference]
item setCursor(Qt::IBeamCursor)
[1]
view viewport() -> scroll(dx, dy, deviceRect)
QQuickTextNode * textNode() const
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent