aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquicktextedit.cpp
Commit message (Collapse)AuthorAgeFilesLines
* Allow text edit to process key events when shortcutoverride configuredSanthosh Kumar2025-10-271-4/+1
| | | | | | | | | | | | | | | | | | | | | | | | | The shortcut override has been made to be ignored by default as part of the patch 1aefea26e5a574dad25646d330a6b3bb943a596c. And the further changes in the same patch were made to check whether the shortcut override can be accepted by text edit before processing the events. If the shortcut override has not been accepted (either by default or explicitly ignored by the user), the keys would be processed further by the textedit. The validation added as part of the same patch for processing the event doesn't seem to be correct, as it allows the key to be processed by the text edit control only when the key handler is not configured. This approach seems to be incorrect, as the text edit control shall be allowed to process the key events regardless of key handler configuration. This patch removes that validation, thus allowing the text edit control to process the key events regardless of key handler configuration. Fixes: QTBUG-139679 Task-number: QTBUG-136959 Pick-to: 6.10 6.8 6.5 Change-Id: I7c066e5f3709a00d0b18f0c5e8b9d1f7944c4e4e Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* QQuickTextInput/Edit: ensure original context menu event is acceptedMitch Curtis2025-07-121-1/+3
| | | | | | | | | | | | | | | | We make a copy of the context menu event in order to map its position to cursorRectangle, but we forgot to set the accepted state back onto the original event. If we don't do this, showEditMenu (in src/plugins/platforms/ios/qiostextinputoverlay.mm) shows the built-in native text editing context menu (QIOSTextInputOverlay::s_editMenu) because it sees that the event wasn't accepted, resulting in both that and Controls' menu being shown. Amends 31ca3936d38ecbc3aa93411654099f5a45b16c4f. Fixes: QTBUG-138209 Change-Id: Iac001d9632af2f891337821720a372ec4833f173 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Propagate ignored shortcut key events in quick text edit to parentSanthosh Kumar2025-07-111-5/+8
| | | | | | | | | | | | | | | | | | | | | | | The delivery agent generally accepts key events before sending them to the quick item; the corresponding item can further accept or ignore those events. The reason that the user can't override the shortcut key event in the quick text edit is that these events are marked as accepted by default in the delivery agent, and the quick text edit also doesn't explicitly handle the read-only case, which causes the event state to remain as accepted. This patch ignores the shortcut override event by default in the delivery agent. Also, make the quick text edit to execute the configured key handler to either accept or ignore before processing the events. This gives the chance to execute the required shortcut actions. Fixes: QTBUG-136959 Pick-to: 6.10 6.9 6.8 6.5 Change-Id: Ib6400f083f4e21d1b23db87b002acb1cbd4ac82b Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QQuickItemPrivate: introduce effectiveDevicePixelRatio() helper methodVladimir Belyavsky2025-05-241-1/+1
| | | | | | | | Introduce QQuickItemPrivate::effectiveDevicePixelRatio() helper method and unify its usage in Qt Quick code. Change-Id: I1978683d76e23c5bfe523a96ee07688eb0aef96b Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* TextEdit and TextInput: map QContextMenuEvent to text cursor posShawn Rutledge2025-05-021-0/+12
| | | | | | | | | | | | | | | ...if the position is not already set. Events that come from a keyboard menu key or shortcut often have pos() == {0, 0}, but we want the context menu to be in the context of what the user is editing. First though, we need QQuickDeliveryAgentPrivate::contextMenuTargets() to search for items at the correct position. We don't override delivery order, but activeFocusItem should be in the list that is returned. Pick-to: 6.9 6.8 Fixes: QTBUG-136253 Change-Id: I7eea03e118a95a1a267f02bd3385cc1ae4cbb0a0 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* Respect target DPR when drawing text objects in QQuickTextNodeEngineTor Arne Vestbø2025-04-241-4/+8
| | | | | | | | | | | | | | Instead of passing the DPR through as function arguments to each addFoo function we set the DPR on the QSGInternalTextNode and QQuickTextNodeEngine. We could have solved this by pulling the DPR from the QSGRootNode's renderer, but there might be more than one of them, and we're missing a setDevicePixelRatio in QSGAbstractRenderer (it's only exposed one level above, in QSGRenderer). Pick-to: 6.9 Fixes: QTBUG-127913 Change-Id: I48081d441259f0713cdc5f784eede6777b5fb601 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* Mark text-related Qt Quick items as security-sensitiveShawn Rutledge2025-03-111-0/+1
| | | | | | | | | Task-number: QTBUG-132472 Task-number: QTBUG-134547 Pick-to: 6.8 6.9 Change-Id: I916d996e593a270b9e3b0c07d0a9e6338b8883fc Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* Doc: fix linking warningsVolker Hilsheimer2024-12-161-1/+1
| | | | | | | | | | | | We can't link to a signal that's not explicitly documented, we can only link to the property it belongs to. Member functions in a different scope use '::', not '.'; and properties don't have parenths. Pick-to: 6.9 Change-Id: I5c87ab5dbd97e4612a032d7adf7248d23af05c6f Reviewed-by: Andreas Eliasson <andreas.eliasson@qt.io>
* Add textEdited() signal to TextEditDheerendra Purohit2024-12-021-0/+11
| | | | | | | | | | textEdited() signal is emitted whenever the text is edited. [ChangeLog][TextEdit] Added textEdited() signal. Fixes: QTBUG-103718 Change-Id: Ib3fa5a38aeadd6167aafc0dea91f02bd9e6df7cc Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* Disconnect from old document in QQuickTextControlAndrew Forrest2024-10-201-2/+3
| | | | | | | | | | Now the text document can change in QQuickTextEdit, we cannot keep lingering connections to the old document. Pick-to: 6.8 Task-number: QTBUG-35688 Change-Id: I02ce1eaa561170a2f2bc5150368788df7b0f4769 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Fix updating TextEdit when mirroring changesKaj Grönholm2024-08-221-0/+1
| | | | | | | | | | | When Item LayoutMirroring changes and mirrorChange() gets called, update the document properly. Task-number: QTBUG-124922 Pick-to: 6.5 6.7 6.8 Change-Id: I2b8a0e05ae3f0479eed68c0a7f84b23ba8d56e76 Reviewed-by: Oliver Eftevaag <oliver.eftevaag@qt.io> Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* Doc: Replace \instantiates with \nativetypePaul Wicking2024-08-201-1/+1
| | | | | | | | | | | Since the implementation of the `\nativetype`-command in QDoc, the `\instantiates`-command is deprecated. Replace the use of the deprecated command in favor of its replacement. Pick-to: 6.8 Task-number: QTBUG-128216 Change-Id: I23d9f66d3f6db2e5f827d7868497a432bb9b0626 Reviewed-by: Venugopal Shivashankar <Venugopal.Shivashankar@qt.io>
* Update text components with color fonts when dpr changesEskil Abrahamsen Blomfeldt2024-08-151-5/+16
| | | | | | | | | | | | | | | | | | | | | | | | There was already a hook in text components to update when the renderType was set to Text.NativeRendering. This is necessary because the text is rendered into a glyph cache at a given size and scaling it further will give pixelation artifacts. However, there are cases where the NativeRendering backend is used implicitly. In particular this happens for color fonts, so when changing the dpr of a screen (or when moving the window to a screen with a different dpr) we would get pixelated emojis in some cases. The fix is to detect in the text node whether any glyphs use the NativeRendering backend and if they do, we update whenever the dpr changes. Fixes: QTBUG-121449 Pick-to: 6.5 6.7 6.8 Change-Id: I9ad62d792e495d4439715fe87acfd87dd1833c67 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* Add Expanding size policy to some controls and itemsJan Arve Sæther2024-07-171-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | Applies to the following Quick items: * TextEdit * TextInput * Flickable and Qt Quick Controls: * ProgressBar * Slider * RangeSlider It follows the same Expanding size policies as the corresponding widgets Also enable size policies the following examples (and thus remove several lines of Layout.fill.*): * quick/layouts * quickcontrols/ios/todolist Task-number: QTBUG-117597 Pick-to: 6.8 Change-Id: Id4f552aa4c8e85a65b00ff1cf06f34dd7ddeb9fa Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io>
* TextEdit: load inline images from resources the same as local filesShawn Rutledge2024-07-021-0/+17
| | | | | | | | | | | | QQuickTextEdit::loadResource() now loads resource images with QFile rather than creating a QQuickPixmap "job". connectFinished() was complaining, presumably because loading happens instantly, and we don't need async notification when it gets done. Fixes: QTBUG-125526 Pick-to: 6.7 6.8 Change-Id: Ibcea546104aefb35ee333dfd0ac13c07549e33c7 Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io>
* QtQuick: Straighten out some logging categoriesUlf Hermann2024-06-191-2/+1
| | | | | | | | | | | | Either make them static or declare them in a header. We want them to be static wherever possible, in order to reduce the number of visible symbols. If they can't be static, however, they should at least be declared in only one place. Task-number: QTBUG-67692 Change-Id: I485bb7e4379e86f72619f848399ad58c76586851 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Update TextEdit after setDocument; move logic from QQTextControl ctorShawn Rutledge2024-06-161-2/+6
| | | | | | | | | | | | | | | | | QQuickTextEdit::setDocument() needs to do the same sort of init and signal connections as initial construction. Some of that was in the QQuickTextControl constructor; now, QQuickTextControl::setDocument() gets called either way, to connect signals related to the new document and its layout. Also ensure that text layout occurs, TextEdit is re-rendered, and interactive editing continues to be possible. Amends 4598939ee2fad1238609ca43717199fd4e98c75f Fixes: QTBUG-126267 Task-number: QTBUG-35688 Pick-to: 6.7 6.8 Change-Id: I7714548fbc7d1fc2c9c28e2601a490e54302cc8b Reviewed-by: Oliver Eftevaag <oliver.eftevaag@qt.io>
* Introduce preferTypoLineMetrics property to Qt Quick fonts as wellEskil Abrahamsen Blomfeldt2024-06-041-1/+8
| | | | | | | | | | | This matches the newly added QFont::PreferTypoLineMetrics style strategy. As a drive-by, this also fixes the return type of the newly added contextFontMerging property in the docs. Pick-to: 6.8 Task-number: QTBUG-125585 Change-Id: I2ff0bc26c3744dad783870e8d45c07fa0b1a8e95 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Call polish after setting HAlign in Qml TextEditEd Cooke2024-05-221-0/+1
| | | | | | | | | | | | | | | | Qml TextEdit does not call polish() in the setter for horizontal alignment. The test that tests horizontal alignment for TextEdit is broken, creating a Text item instead of a TextEdit and therefore calling the wrong setter. This test also has a false positive as a result of an unnecessary subtraction. Fixes: QTBUG-56921 Pick-to: 5.15 6.2 6.5 6.7 Change-Id: I21df3c4f403980fb5512abfd5e7e32a064cd60d7 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* Match QFont::ContextFontMerging with Qt Quick APIEskil Abrahamsen Blomfeldt2024-05-081-0/+7
| | | | | | | | | | | | While we don't support all style strategy flags in Qt Quick, we do support selected ones as bools. QFont::ContextFontMerging is useful to be able to set per Text element, so it should be exposed through the QML APIs. Task-number: QTBUG-121131 Change-Id: If28a065aefc4e2043e830e31356b8bd98f6d4cd8 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* TextEdit: don't skip nested frames or their blocks in updatePaintNodeShawn Rutledge2024-04-081-5/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I don't fully understand the previous logic behind keeping the same firstDirtyPos while we iterate all the frames. In case a document contains a mix of tables and text for example, we may iterate to a block in the root frame that is just beyond the first table, and set firstDirtyPos accordingly (which I think is meant to say that everything up to that character position has been rendered, but it's not true at that moment in time); and then when we look at the frame corresponding to the first table, rule out rendering the whole frame or any of its blocks based on the fact that it comes _before_ firstDirtyPos. The fact that we got past its position in the root frame should not preclude rendering the nested frame. So now it looks safer to reset firstDirtyPos before iterating each nested frame. Anyway the logic from f513e88403b66c4a5efe4c62c160dfce151efb33 assumed that we wanted to populate the whole document into the scene graph, and should just avoid redoing work while keeping the nodes up-to-date; whereas since 9db23e0e04906cf9ea33e23fa41f34955e5e6fe0 we're trying to avoid populating nodes too far outside the viewport. That's probably the bigger optimization: if we are avoiding most of the blocks in large documents most of the time, redoing work to render the ones that are in the viewport is not such a big deal. And it seems dangerous to preemptively skip frames or blocks before we've checked whether they are in the viewport. So now we visit all frames regardless of firstDirtyPos, but still skip blocks within the frame that are beyond the bottom of the viewport. And whenever we do render the first block that is beyond the viewport, we also enlarge our local copy of the viewport rectangle to encompass that block's bounds, to ensure that when we visit nested frames, we will also render other blocks within the enlarged bounds. Effectively this means if we render the next block in the root frame immediately past a table, we will also render all cells in the lower part of that table (between the top of the viewport and the bottom of the table). That might result in more SG nodes than we strictly need (outside the viewport bounds); but at the end, the stored QQuickTextEditPrivate::renderedRegion must include that one block that was past the table, so we want all intervening blocks too. QQuickTextEditPrivate::transformChanged() will not call update() if renderedRegion tells it that the coverage is complete within the current viewport, and nothing more needs to be rendered. That was the root of this bug. The autotest just counts the number of blocks rendered at different scroll positions in a Flickable. Perhaps it will turn out to be sensitive to font sizes on various platforms; but the number of blocks rendered was way too small in case of the bug, so we can afford a tolerance in the comparison, if needed. Fixes: QTBUG-118636 Pick-to: 6.5 6.6 6.7 Change-Id: Id1f2b393f26e2dd5b198e9d5251e8c33459c3c07 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Doris Verria <doris.verria@qt.io>
* QQuickTextEdit: Check QQuickAccessibleAttached for nullptrUlf Hermann2024-04-041-4/+5
| | | | | | | | | | | | | | If the host object is in the process of being deleted, the attached object will be null. We cannot rule this out here, and crashes have been reported. Amends commmit 12517742fcbd40b2311b94abe840532eae3d8914 Pick-to: 6.7 Change-Id: I31fcab2999c8ab8c20f3a2cd58060cbbefa7de40 Reviewed-by: Vladimir Belyavsky <belyavskyv@gmail.com> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Kai Uwe Broulik <kde@privat.broulik.de>
* Keep markup when toggling TextEdit.format: AutoText / PlainTextShawn Rutledge2024-03-091-29/+111
| | | | | | | | | | | | | | | | | | | | | | | | | | | This is useful when writing an editor that allows you to do wysiwyg editing or raw HTML/markdown. Usually you want `format: AutoText` because you don't know what the user is going to load, and we expect QQuickTextDocumentPrivate::load() to find the type from the URL extension (since b46d6a75ac16089de1a29c773e7594a82ffea13e). Then if the user toggles format to PlainText, that's assumed to be for the purpose of raw viewing or editing, not for the purpose of removing the formatting. (Switching to plain text can be accomplished by `textEdit.text = textEdit.getText(0, textEdit.length)` .) We adjust tst_qquicktextdocument::overrideTextFormat() slightly: loading an html document as AutoText and then converting to HTML no longer emits the textChanged signal (it's not really a conversion). Likewise, converting markdown loaded as AutoText to explicit markdown should not need to emit the textChanged signal. Amends fdbacf2d5c0a04925bcb3aecd7bf47da5fb69227 Done-with: Oliver Eftevaag <oliver.eftevaag@qt.io> Fixes: QTBUG-122985 Task-number: QTBUG-120772 Pick-to: 6.7 Change-Id: I1d43b5e5662197dfeb1a93a2d1f638a193aa66b2 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* doc: Update TextEdit.textFormat, text and TextDocument.sourceShawn Rutledge2024-03-061-7/+30
| | | | | | | | | Update docs after b46d6a75ac16089de1a29c773e7594a82ffea13e, fdbacf2d5c0a04925bcb3aecd7bf47da5fb69227 etc. Pick-to: 6.7 Change-Id: Ieb49d6876f0a86031fb0ffe970f695e5acbe4c43 Reviewed-by: Oliver Eftevaag <oliver.eftevaag@qt.io>
* doc: Remove statements that horizontal rules are not renderedShawn Rutledge2024-03-051-1/+0
| | | | | | | | | They've been rendered since eca6bd485436f9ddf16036b98c993b7ffeb7e6c4 Pick-to: 6.5 6.6 6.7 Task-number: QTBUG-74342 Change-Id: Ifabe3d38ab7121145b76653faee324f4c656def1 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Stabilize tst_qquicktextedit::largeTextObservesViewportShawn Rutledge2024-02-271-1/+2
| | | | | | | | | | | | | | | Ensure that firstBlockInViewport is set in all cases in QQuickTextEdit::updatePaintNode() where there is a viewport and we found one or more blocks that are within the viewport. Since 5ce225d6d310005f032ff319da8df15f7e10851a it's being used in a conditional check, so it's no longer only for the autotest; and there was an else case where it wouldn't get set. Perhaps that was happening in CI. Amends f878019332cc496cc00acd9554640ca198aa10a6 Pick-to: 6.6 6.7 Fixes: QTBUG-109488 Change-Id: Ib7ccd4aee4e41ff84cf0ebaca00e295568bcb9f9 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* Respect TextEdit.textFormat in TextDocument load(); detect formatShawn Rutledge2024-02-211-13/+59
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Don't load rich text if TextEdit.textFormat is PlainText. Thus it should be possible to have two independent TextEdit instances with independent document instances, viewing the same source file: the raw syntax and the rich/WYSIWYG formatting visible at the same time. Also, after the QQuickTextDocument's QTextDocument has already loaded the declared source, don't let QQuickTextEdit::componentComplete() replace it with empty text from the (unbound) TextEdit.text property. That was happening only if textFormat was RichText or MarkdownText. In case the user transitions TextEdit.textFormat from AutoText to any other, the text property now holds the format that was loaded from TextDocument.source; QQuickTextDocumentPrivate remembers the format rather than the mime type (because QMimeType is an optional feature in Qt); and TextEdit functions such as getFormattedText(), insert() and append() behave as if the textFormat property had been appropriate for the loaded file type in the first place. We cannot algorithmically detect markdown text by looking at the text itself; but now, QQuickTextDocumentPrivate::load() can populate markdown or html text into the document by detecting the file's mime type, even if the textFormat is AutoText. After that, if the user changes the textFormat to PlainText, we assume that they want to see the raw markdown or HTML. Amends b46d6a75ac16089de1a29c773e7594a82ffea13e : it already seemed odd at the time that it was OK for QQuickTextDocumentPrivate::load() to load any text format, without first changing TextEdit.textFormat to match what's expected. The default is PlainText, so it didn't make sense to read e.g. a markdown file and have the result look like WYSIWYG rich text. Now you have to change textFormat to MarkdownText or AutoText beforehand if you want to see WYSIWYG; and tst_qquicktextdocument::sourceAndSave() needs to do that too. On the other hand, if you switch textFormat to PlainText, we convert the QTextDocument to plain text, using Qt-generated markup/markdown syntax. Maybe the user would prefer to have the original syntax as read from the file; but so far it has always been this way: we just parse it, we don't store it. We are quite incapable of incrementally modifying the original syntax anyway: we can only regenerate it wholesale. So it makes sense that the text property holds Qt-generated syntax after the parsing is done. Pick-to: 6.7 Fixes: QTBUG-120772 Change-Id: I7db533c714e14bb4eb36745996c732e5162fb9cf Reviewed-by: Oliver Eftevaag <oliver.eftevaag@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Replace QSGTextNode::smooth with QSGTextNode::filteringEskil Abrahamsen Blomfeldt2024-02-151-1/+1
| | | | | | | | | | | | | The "smooth" property was intended to match the one in QQuickItem, which uses a less technical name (but also less precise). Since QSGTextNode is scenegraph API, it makes sense to expose the actual property of the texture instead of trying to mimic the vague name in QQuickItem. Pick-to: 6.7 Change-Id: I6fb2ac637a654e1df677bf95f43c28b0bc0661a1 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Avoid dangling pointers in QQuickTextEdit::resourceRequestFinished()Shawn Rutledge2024-02-121-19/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | If we encounter an error while trying to download a network resource for a document (for example an inline image URL has an invalid protocol, or the web server returns 404), we call QTextDocument::resource() one more time, in case a placeholder image is to be returned. That will call back to QQuickTextEdit::loadResource(), which will delete the QQuickPixmap "job". Break out of the loop, don't keep iterating on the same pixmapsInProgress list that we're deleting it from. Likewise, break out if resourceRequestFinished() deletes the job itself. So now we expect resourceRequestFinished() to run its loop more often rather than continuing the first run until pixmapsInProgress is empty; but as before, don't invalidate() until all resource-loading jobs are done (pixmapsInProgress is empty). Also, as a hypothetical improvement to thread safety, erase() from the QList before deleting; and don't dereference the iterator again when we've already done that once at the top. Amends 7fb39a7accba014063e32ac41a58b77905bbd95b turtle.svg for the autotest is from https://openclipart.org/detail/235021/silhouette-turtle Fixes: QTBUG-122108 Pick-to: 6.7 Change-Id: Icfcaba7b42c68b572efda15b1ddc791010701bfa Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* Set default layout size policies for quick itemsSanthosh Kumar2024-02-091-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | The quick items are initiliazed with default layout size policy. This size policy can be either Preferred or Fixed and it can vary depending on controls and its orientation. [ChangeLog][QtQuick][Item Behavior Changes] The QtQuick items now set their default size policy and it would be effective when used within QtQuick Layouts. The following types now behave differently by default when used in layouts: Button, CheckBox, ComboBox, Dial, DialogButtonBox, Frame, Flickable, GridView, GroupBox, HorizontalHeaderView, ListView, Page, Pane, PathView, ProgressBar, RadioButton, RangeSlider, RoundButton, ScrollBar, ScrollIndicator, ScrollView, Slider, SpinBox, SplitView, StackView, SwipeView, Switch, TabBar, TabButton, TableView, TextArea, TextEdit, TextField, TextInput, ToolButton, TreeView, Tumbler, VerticalHeaderView. Task-number: QTBUG-117597 Pick-to: 6.7 Change-Id: I41fe73a2e466e396f26604a14d1f15b8b42df338 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* Fix baseline offset with RichText when multiple fonts are usedEskil Abrahamsen Blomfeldt2024-02-071-1/+7
| | | | | | | | | | | | | | | | | | | When combining multiple different fonts in one text, we would align the baseline based on the ascent of the main font when using Text.RichText. When using StyledText, we would use the QTextLine's actual ascent instead (the maximum of all fonts in the line). This caused a misalignment when there are fonts with larger ascents in the text (e.g. fallback fonts). If possible, we use the first block's first line for alignment, same as for StyledText. Otherwise, we fall back to using the QFontMetrics like before. Fixes: QTBUG-122027 Change-Id: I86d12bfcd58cee837caff4ea72e002d4d5723b3b Reviewed-by: Lars Knoll <lars@knoll.priv.no>
* TextArea/TextField: properly update placeholder text alignmentVladimir Belyavsky2024-01-091-24/+38
| | | | | | | | | | | | | | | | | | | | | | Placeholder text alignment depends on actual alignment of a parent control, e.g. TextArea or TextField. Thus, if the horizontal text alignment of the parent control is set explicitly, the placeholder text must have the same alignment. Otherwise, the placeholder text alignment should respect to the natural alignment of the text. In order to do this QQuickPlaceholderText is connected to effectiveHorizontalAlignmentChanged() signal of the parent control. The problem is that the signal may not be emitted when alignment is set explicitly after the component creation, so the placeholder text alignment will not be updated respectively. To solve this we need to make sure that the signal is forcibly emitted every time when the alignment is set explicitly. Fixes: QTBUG-120052 Pick-to: 6.7 6.6 6.5 Change-Id: Ib66a7a46d523777cc54ca6b6883d3fecc800dfb2 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* qquicktext{edit,input}: Re-render when device pixel ratio changesKai Uwe Broulik2023-12-221-0/+21
| | | | | | | | | | | | Native rendering needs to be perfectly aligned to the pixel grid. When device pixel ratio changes, this can lead to blurry rendering. This was addressed for qquicktext in d870ea28 but not textedit/textinput. Pick-to: 6.7 6.6 6.5 Change-Id: I75d3172a047e73ba3e8e6cbcf4f5a9651d42c6b0 Reviewed-by: David Edmundson <davidedmundson@kde.org>
* Fix polish issue in quick text editSanthosh Kumar2023-12-121-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | The text edit didn't polish even after there is change in position offset, leading to alignment issues. During geometry change, the QQuickTextEdit calculates implicit size and base position offset, and then further requests a polish immediately afterwards. This sequence of update happens only if we have valid width or height set for text edit control. But in case we set width or height to undefined, there is a chance that this update would be missed. This patch removes the checking of widthValid() in QQuickTextEdit::geometryChange(), to allow those updates. The validation of width or height is already handled internally within updateSize(), so it shouldn't create an issue; and we still try to avoid emitting cursorRectangleChanged() too often. Amends 1770fa632facf2f1e4bb05e7689efc939d46cfef Task-number: QTBUG-117667 Task-number: QTBUG-25489 Pick-to: 6.7 6.6 6.5 Change-Id: Ia20cd06e78842f5edb0c395d6322a660f86f6b5e Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Add TextSelection (Tech Preview)Shawn Rutledge2023-12-081-1/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In the Controls text editor example, DocumentHandler always sounded like a hack, just by its name. We don't expect to be able to handle multiple selections anytime soon; but if we realistically expect to have multi-seat support in Qt some day, then probably the multi-user experience should include support for multiple text cursors and selections. So we shouldn't paint ourselves into a corner. QQuickTextControl works with only one QTextCursor most of the time (but it's private, thus modifiable); and TextEdit has properties like selectionStart, selectionEnd, selectedText, etc. which seem to assume that there is only one selection. So probably if we needed to support multiple selections, we could add Q_PROPERTY(QQmlListProperty<QQuickTextSelection> selections ...), document that those legacy properties just work with the first selection, and/or deprecate them. So with that in mind, let's get started with a QQuickTextSelection object. We add TextEdit.cursorSelection which holds the single selection near the text cursor. It provides API needed for tracking and manipulating often-used properties of selected rich text (such as QTextCharFormat properties) so that DocumentHandler can be removed. The example now uses TextArea.cursorSelection to manipulate the selected text's format. It's not possible to be fully declarative with this API though; we need to call setFont (by assigning a font), but QFont is a value type, and is not as mergeable as QTextCharFormat is, for example. If we used a binding rather than Action.onTriggered, it would trigger reading the font for an entire span of selected text (which may have had multiple fonts), setting one attribute (like bold), then applying the font to the whole span. What we do now is almost like that; but instead of reading the font first, we start with a default-constructed QFont, set one attribute, and call QTextCursor::mergeCharFormat(), in the hope that it can merge only the features of QFont that have actually been set. Unfortunately this is not quite true either: if you toggle the bold button, it might change the font size too, and so on; so maybe we really need QTextCharFormat in QML (as a value type, presumably) to implement those feature-toggling toolbar buttons correctly. This API is in tech preview, because of such issues as described above; because we're just scratching the surface of what might be possible; because we should perhaps compare popular JavaScript text-editing APIs that might be found elsewhere, in the meantime get feedback from users during the tech preview phase, and keep iterating. [ChangeLog][QtQuick][TextEdit] TextEdit.cursorSelection is a TextSelection object, which provides properties to inspect and modify the formatting of the single selection that is currently supported. This API is in Tech Preview. [ChangeLog][Controls][TextArea] TextArea.cursorSelection is a TextSelection object, which provides properties to inspect and modify the formatting of the single selection that is currently supported. This API is in Tech Preview. Task-number: QTBUG-36521 Task-number: QTBUG-38830 Task-number: QTBUG-81022 Change-Id: Icea99f633694aa712d0b4730b77369077288540f Reviewed-by: Oliver Eftevaag <oliver.eftevaag@qt.io>
* Add load/save functionality to QQuickTextDocument (Tech Preview)Shawn Rutledge2023-12-081-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Since QTBUG-92155 is not done, we need an easy way to load and save text into and out of a QTextDocument in QML. This patch follows the pattern from Image and other types: add a `source` property, a URL from which the file is to be loaded. When it comes to saving, the pattern is not set: so far the only file writing that has been available from QML is ItemGrabResult.saveToFile(). Since we need to save in specific formats, it makes sense to continue that pattern: the text document knows how to do its own serialization, so this is not suitable for generic data file I/O, even if we did have a QML API for that. We add invokable functions save() and saveAs() for the usual use cases in word processors and such. The URL extension determines the file format. Setting QQuickTextDocument's source is not allowed if the document has unsaved changes. The user (app author) needs to call save() or override modified to false first. [ChangeLog][QtQuick][TextEdit] TextEdit.textDocument now has a source property for loading files; save() and saveAs() functions for writing; a modified property which tracks QTextDocument::modified; and an error signal in case any of these operations fail. Setting the source property is allowed only if the document is in unmodified state. This API is in Tech Preview. [ChangeLog][Controls][TextArea] TextArea.textDocument now has a source property for loading files; save() and saveAs() functions for writing; a modified property which tracks QTextDocument::modified; and an error signal in case any of these operations fail. Setting the source property is allowed only if the document is in unmodified state. This API is in Tech Preview. Change-Id: I687318523c7a520e02244e47224d067da55318b5 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* Add setter and notifier for QQuickTextDocument's documentShawn Rutledge2023-12-061-2/+21
| | | | | | | | | | | | | | | | | | | | | | | Users want to be able to provide their own "special" instances of QTextDocument, or custom subclasses. But so far we allow this only from C++, not from QML. QQuickTextDocument is created lazily in QQuickTextEdit::textDocument() so it's not possible to rely on it to hold the actual QTextDocument all the time. It's only a facade provided to the user. But QQuickTextEdit holds the QTextDocument, and is the only class that creates QQuickTextDocument, and sets the parent to itself; so QQuickTextDocument can rely on accessing the TextEdit's document rather than maintaining its own pointer. textEdit.dot is basically a collaboration diagram showing which objects creates which, the parents, and which objects get swapped out if the user calls setTextDocument(). Task-number: QTBUG-35688 Change-Id: Iac5000aa8027a75a000d4501190f3ee5f04e426e Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Implement variable axes API in QMLEskil Abrahamsen Blomfeldt2023-12-051-0/+7
| | | | | | | | | [ChangeLog][QtQuick][Text] Added font.variableAxes property. Fixes: QTBUG-117836 Change-Id: Id35d346b8136d67054da404044ae80df8da61445 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Get rid of QQuickTextDocumentWithImageResourcesShawn Rutledge2023-12-041-6/+98
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Users want to be able to provide their own QTextDocument instances to TextEdit; but we had been creating a subclass called QQuickTextDocumentWithImageResources, which was an obstacle for that. QTextDocumentPrivate has two QMaps to hold resources, but QQuickTextDocumentWithImageResources existed for the purpose of caching remote resources, which only QQuickPixmap knows how to fetch. (This design was apparently invented as a workaround to the lack of virtual-filesystem functionality in Qt Core. If QtCore already knew how to fetch web resources from URLs in the background, QTextDocument could use it to do its own fetching of remote resources.) What we want instead of subclassing QTextDocument is to keep doing the fetching in Qt Quick (because there's no other choice for now), but get the images into the same QTextDocumentPrivate::cachedResources map where local-file resources are cached. As it turns out, since qtbase ac300a166f801a6f6c0b15278e6893720a5726f8 QTextDocument::loadResource() can use QMetaMethod::invoke() to call a method with the signature QVariant loadResource(int,QUrl) if such a method is found in QTD's parent object; so since QQuickTextEdit creates its own document by default, and is the document's parent, we can keep remote resource fetching functionality working by 1) providing the QQuickTextEdit::loadResource() method to be invoked, and 2) moving the document to the QML thread so that it can be invoked directly. (QMetaMethod::invoke() doesn't work across a queued connection, because we need to return a value: the QVariant.) QTD will already cache the images as soon as the call to loadResource() returns a valid QVariant. We ask for the QQuickPixmap not to be cached by passing an empty QQuickPixmap::Option enum to its ctor, which gets passed through to the load() function. When we consider fetching resources from a web server, it's unfortunate that the signature of QTextDocument::resource() sets the expectation that resources can be loaded immediately. But as long as QQuickTextEdit::loadResource() is waiting for fetching to be done, it keeps returning a default-constructed QVariant, which won't be cached; and it will be called again later, repeatedly, until it eventually succeeds. To ensure that it is called again when fetching is done, we call QTextDocument::resource() again, to provoke it to call our QQuickTextEdit::loadResource() one last time. If the returned image wasn't cached before, it will be after that. Then it's ok to delete the QQuickPixmap, and invalidate the TextEdit so that layout will be updated to include the image, now that we have it. But most of the time it's relatively boring: QTextDocument knows how to load local files on its own, and caches them. So we no longer need QQuickTextDocumentWithImageResources. But we still needed to replace QTextImageHandler with a custom implementation, as explained in bab2eaf3da299c471dd898c89cf356984b077412: we need QQuickPixmap for its QML-specific URL resolution relative to the Text item's context. And it turns out that in case the document contains only a missing image, the minimum size is 16x16 pixels, to reserve space to display a "broken image" icon as browsers sometimes do... we have never actually done that in Qt Quick AFAICT, but autotests have been enforcing the 16x16 minimum size all along. This is done in QQuickTextImageHandler::intrinsicSize() now. The same approach is taken with Text (when textFormat is RichText or MarkdownText. In case of StyledText, there is no QTextDocument instance, and resource loading is taken care of entirely within QQuickText.) For the autotests, friendly use of QQuickPixmapCache::m_cache requires QT_BEGIN_NAMESPACE. Task-number: QTBUG-35688 Change-Id: I8ad8142b3b3790254dd56d6cfe5209d641465f08 Reviewed-by: Oliver Eftevaag <oliver.eftevaag@qt.io> Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Introduce a CurveRendering backend for textEskil Abrahamsen Blomfeldt2023-11-111-0/+8
| | | | | | | | | | | This moves the internals of the curve renderer out from Qt Quick Shapes and into a more centralized location in Qt Quick, so that we can use the same code to create a new text backend for rendering large scale text without artifacts. Change-Id: I3f7e6f7961c1bbe230fcb531c0ca028e038c1afd Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* QQuickTextArea: move accessibility handling into base QQuickTextEdit classVladimir Belyavsky2023-11-011-0/+35
| | | | | | | | | | | | Move accessibility handling from QQuickTextArea into base QQuickTextEdit class. This fixes an issue where the virtual keyboard does not appear automatically when TextEdit initially gets focus on a Windows touch device such as the MS Surface Pro X. Fixes: QTBUG-108449 Pick-to: 6.6 Change-Id: I37e0d197d4af04c832dfb5651bade9d39e079f2b Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* QQuickTextEditPrivate: use in-class initializationVladimir Belyavsky2023-10-271-7/+1
| | | | | | | | ...to clean up the code a bit. As a drive-by change, remove unused include to fix clangd warning. Change-Id: I5761b18f01b0abe2c1cf82d983a4aa31586b7b6d Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* Make text node scenegraph API publicEskil Abrahamsen Blomfeldt2023-09-011-11/+12
| | | | | | | | | | | | | | A lot of functionality is hidden underneath this, so exposing this API will make it possible to build custom text-based components for Qt Quick. [ChangeLog][Text] Added QSGTextNode and QQuickWindow::createTextNode() for creating scene graph nodes containing text. This can be useful when building custom Qt Quick items with text. Fixes: QTBUG-72773 Change-Id: I4810589cc28eb1cdfe91c9d8b66f4c6fe52a0c6a Reviewed-by: Andy Nichols <andy.nichols@qt.io>
* Doc: add information about preeditText in text propertyBartlomiej Moskal2023-07-131-1/+11
| | | | | | | | | | | | | The documentation for the TextEdit::text and TextInput::text properties was missing information about preeditText. This may result in the expectation that text property will always contain all displayed text. Pick-to: 6.6 6.5 6.2 Fixes: QTBUG-109306 Change-Id: Ifa0b214238633a42e9772f796547f776a0d4251c Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Mitch Curtis <mitch.curtis@qt.io> Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
* Doc: Fix documentation for font.features QML propertyTopi Reinio2023-07-051-59/+1
| | | | | | | | | | | | | | | | | | Add a link to font.features property to the 'font' QML value type reference. The property documentation is duplicated for multiple QML types; keep only a single instance in qquicktext.cpp, add snippet markers and \include the same documentation for the rest of the types. Fix code snippets to use \qml, \endqml commands. Fix \sa link to QFont::setFeature(). Pick-to: 6.6 Change-Id: Ieafd7691ab859a3ae509080e0ee24b3d00f276f9 Reviewed-by: Andreas Eliasson <andreas.eliasson@qt.io> Reviewed-by: Safiyyah Moosa <safiyyah.moosa@qt.io>
* QQuickTextEdit: Fix rendering issues when selecting in long textPiotr Wierciński2023-06-121-1/+6
| | | | | | | | | | | | | | | Text that is longer than QQuickTextEditPrivate::largeTextSizeThreshold is rendered without populating blocks outside of the viewport into SG. When user scrolls backwards, there is a mechanism for loading and rendering blocks that were previously outside of the viewport. Make sure this mechanism does not trigger unnecessarily, for example during text selection, to avoid double rendering of some nodes. Amends cd083920b3b4f3a1ed7f2297058cf0d110d7cf10 Fixes: QTBUG-113009 Pick-to: 6.6 6.5 Change-Id: I45bc97f2aea4c5cb99b7dee097aa25ab711be653 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* TextEdit: fix wrong RTL text alignment when used with a ColumnLayoutVladimir Belyavsky2023-06-021-12/+11
| | | | | | | | | | | | | | | | | Due to some old bug in QTextDocument, invalidating document's width (via setTextWidth(-1)) also breaks RTL text alignment. It was a reason of broken text alignment in case when TextEdit control is placed into a layout. To avoid this, we have to call setTextWidth("idealWidth") all the time when an explicit width is not set and text wrapping is not used. As a drive-by change, we slightly polished the surrounding code to make it a bit clear. Fixes: QTBUG-112858 Pick-to: 6.5 Change-Id: I59cb0618d939d05fedbbabc59a8aae0e2ecabaee Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* Add font.features API to match the one in QFontEskil Abrahamsen Blomfeldt2023-05-261-0/+65
| | | | | | | | | | | | For convenience, we make this a map from strings to integers and just ignore any entries which are not valid four-letter tags. [ChangeLog][QtQuick] Added font.features property for fine-grained customization of the shaping process. Change-Id: I4ceaed859c1641f7b5888b27fa5a5bd576b05547 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* QQuickScrollView and QQuickTextEdit: Fix binding loopsKaj Grönholm2023-05-261-1/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If the content item of a ScrollArea is a height <-> width dependent item, like a TextEdit, a change in the height of the content, may trigger the vertical scrollbar to become visible, (if the content height is bigger than the ScrollArea's height). This in turn causes the right padding of the ScrollArea to change, to make place for the scrollbar, causing in this way a content resize again, giving us a binding loop on the Scrollbar's visible property and the ScrollView's 'implicitHeight'. To get rid of the binding loop on the 'implicitHeight' property, check if the TextEdit's updateSize() has already been called, and if so, don't emit its contentSizeChanged() signal again. In order to get rid of the binding loop on the Scrollbars' 'visible' property, introduce two new properties: effectiveScrollBarWidth and effectiveScrollBarHeight which represent the actual width/height of the scrollbars. Set this property dependent on the scrollbar's policy, visibility, and the scrollview's content size and make sure to update whenever any of these changes. Also, follow the same pattern as above and don't emit the signal twice if on a recursive call. [ChangeLog][Controls][ScrollView] Added effectiveScrollBarWidth and effectiveScrollBarHeight which hold the effective sizes of scrollbars. Fixes: QTBUG-97974 Change-Id: I3d915eae53881d000769de1824c3908c7acd5c6b Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Doris Verria <doris.verria@qt.io> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* doc: Use \value rather than \li for enumeration values and constantsShawn Rutledge2023-03-281-95/+88
| | | | | | Pick-to: 6.2 6.5 Change-Id: Ica8354a53d0a5fb5dd1d8cd5f774dcdc56b6f99a Reviewed-by: Paul Wicking <paul.wicking@qt.io>