aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquicktextedit_p_p.h
Commit message (Collapse)AuthorAgeFilesLines
* TextEdit: don't skip nested frames or their blocks in updatePaintNodeShawn Rutledge2024-04-081-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* Stabilize tst_qquicktextedit::largeTextObservesViewportShawn Rutledge2024-02-271-1/+1
| | | | | | | | | | | | | | | 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-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* Remove the use of Q_QUICK_PRIVATE_EXPORTAlexey Edelev2024-01-091-3/+3
| | | | | | Task-number: QTBUG-117983 Change-Id: Ia904c9390efb13b92de2e16fa0690e48394f9bab Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* Reorder members of QQuickTextEditPrivate::NodeMårten Nordheim2023-12-201-2/+2
| | | | | | | Saves 4 bytes on padding. Change-Id: I5e4e59d0fda6dc4e5e0a2aa8210bff9ab38db9a7 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Add TextSelection (Tech Preview)Shawn Rutledge2023-12-081-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 setter and notifier for QQuickTextDocument's documentShawn Rutledge2023-12-061-1/+2
| | | | | | | | | | | | | | | | | | | | | | | 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>
* Get rid of QQuickTextDocumentWithImageResourcesShawn Rutledge2023-12-041-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* QQuickTextArea: move accessibility handling into base QQuickTextEdit classVladimir Belyavsky2023-11-011-0/+22
| | | | | | | | | | | | 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-44/+31
| | | | | | | | ...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-6/+6
| | | | | | | | | | | | | | 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>
* QQuickScrollView and QQuickTextEdit: Fix binding loopsKaj Grönholm2023-05-261-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* Fix bad rendering after text selectionShawn Rutledge2022-08-251-0/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In 9db23e0e04906cf9ea33e23fa41f34955e5e6fe0 we added a new call to createTextNode(), but it turns out that it could be called again for the same block, a few lines below (in code that was originally added in dfdc4ce825e814b30449cfa1c85d3d2f47f8a845), if we have not reached the "last node that needed replacing or last block of the frame". This resulted in a memory leak: TransformNodes were created without parents, which b616028dae933e7ff6142d41bdafee8ad445a8ec tried to fix by calling addCurrentTextNodeToRoot(). That change made the code in "Update the position of the subsequent text blocks" re-add offsets that had already been added, which had the effect of moving down the blocks below the selected ones by the height of one line; but the new call to addCurrentTextNodeToRoot() was anyway just adding empty TransformNode instances to the scene graph. Afterwards we can see that any TransformNode that does not have a GeometryNode as a child is not actually rendering any text, it's just wasting memory. Having a debug operator for QQuickTextEditPrivate::Node, and using a QQuickTextEdit subclass in the autotest that checks the nodes corresponding to blocks rendered at the end of updatePaintNode(), makes this easier to see and verify. So now, if createTextNode() has already been called, we avoid calling it again a few lines below; but we keep the checks in place to make sure that every node which does not have a parent will get added to the scene graph (regardless of which line of code it was created on), so that there's no leak. It remains to be seen if this could be cleaned up further. Amends 9db23e0e04906cf9ea33e23fa41f34955e5e6fe0 and b616028dae933e7ff6142d41bdafee8ad445a8ec Pick-to: 6.3.2 6.3 6.4 Task-number: QTBUG-103819 Fixes: QTBUG-105208 Fixes: QTBUG-105555 Fixes: QTBUG-105728 Change-Id: I321980c705887bfdb37825f7e6ed8da3d200654e Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* TextEdit: selectByMouse default=true, but not on touchscreensShawn Rutledge2022-07-231-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When you drag a finger across a TextEdit, it should not select text. - your finger probably covers several characters, so you can't see where you're selecting until afterwards - if the item is in a Flickable, flicking by touch should be prioritized - if flicking happens, the text cursor should not move; but to avoid losing too much functionality, we allow it to move on release, if the TextEdit gets the release (i.e. if it still has the exclusive grab) So now we distinguish mouse events that are synthesized from non-mouse devices and avoid mouse-like behaviors as described above, but there is no behavior change if the event comes from an actual mouse or touchpad. Since most users want selecting text by mouse to "just work", and an actual mouse is precise enough to do so, and dragging a Flickable with the mouse is unintuitive (since most UIs don't allow it and most mice have wheels), selectByMouse now defaults to true, and has the stricter meaning that its name implies. To select text on a touchscreen, the end-user needs to rely on text-selection handles, which are provided on touch-centric mobile platforms, and could also be implemented from scratch if someone builds a custom text field using TextInput. In QQuickPressHandler::mousePressEvent() we give the original event's device to the delayed press event, now that we check the device to distinguish "real" mouse events from those that are synthesized from touch. [ChangeLog][QtQuick][TextEdit] The selectByMouse property is now enabled by default, but no longer enables selecting by dragging your finger across text on a touchscreen. Platforms that are optimized for touchscreens normally use special text-selection handles, which interact with Qt via QInputMethod. You can opt out of the behavior change by using an import version < 6.4. Pick-to: 6.4 Task-number: QTBUG-10684 Task-number: QTBUG-38934 Task-number: QTBUG-90494 Task-number: QTBUG-101205 Change-Id: Ia96f53cd7c6db5f995aab5505f61c13f9a4c4c0a Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Mitch Curtis <mitch.curtis@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Fix TextEdit/TextArea mouse cursor shape handling logicVladimir Belyavsky2022-06-161-1/+4
| | | | | | | | | | | | | | | | | | Previously IBeamCursor was wrongly shown in case when TextEdit was readonly and not selectable by mouse. Now ArrowCursor will be shown in such case. Additionally removed own mouse cursor shape handling logic in TextArea, so it will be unified now with derived logic from TextEdit. This is a change from 23f78b6b76fb9350a472485e34857e1a4842e5d3: we no longer attempt to restore a cursor that was set via setCursor(). [ChangeLog][QtQuick][TextEdit] TextEdit and TextArea now set their own mouse cursors more consistently, but without regard for any external call to setCursor(). Fixes: QTBUG-104089 Pick-to: 6.3 6.4 Change-Id: Iba4e0cb55d555b0f360d7856346ff9e8393b9e1e Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Use SPDX license identifiersLucie Gérard2022-06-111-38/+2
| | | | | | | | | | | | Replace the current license disclaimer in files by a SPDX-License-Identifier. Files that have to be modified by hand are modified. License files are organized under LICENSES directory. Pick-to: 6.4 Task-number: QTBUG-67283 Change-Id: I63563bbeb6f60f89d2c99660400dca7fab78a294 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Invalidate text when application fonts are added or removedEskil Abrahamsen Blomfeldt2022-04-081-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We had multiple related issues due to application fonts being added or removed during the application lifetime. 1. If a text had font family "foo" set, and this font did not exist at the time, then loading "foo" at a later stage would not update the text to use the correct font, since the result of the previous request had been cached. 2. A variation of #1 was if the font "foo" was loaded by a FontLoader in the scene and referred to by name in the text component. In this case, there was a race condition, where the font lookup would sometimes yield different results on the main thread and on the render thread, and text would be garbled. 3. When a font was removed from the font database, then references to it would remain in the caches (glyph cache + font cache) in the render thread. With certain backends (DirectWrite, CoreText) this caused errors or even crashes, as the cached font engines would be referring to data that had been removed. The work-around for #1 and #2 was merely to avoid hardcoding names for fonts, but instead getting them from the FontLoader. This way, you can avoid requesting the font family before it is available (and thus avoid caching the wrong result). However, for #3 there is no known work-around. This patch fixes all three (together with a smaller patch for qtbase) by invalidating all text and related caches in Qt Quick when fonts are either added or removed from the font database. This does add some overhead if font loading happens during runtime, but the alternative is broken behavior and dangling pointers. This is done during the synchronization step. Before synchronization, the font cache is flushed and all text components are marked for update, so that fonts are re-requested against the new font database. After synchronization, we delete all distance field glyph caches which are not currently in use, to avoid having references to stale application font data in the list. [ChangeLog][Text] Fix multiple issues with usage of application fonts when they are added or removed during the lifetime of the application. Task-number: QTBUG-100697 Task-number: QDS-1142 Change-Id: Ib309e54e0ee97b6be6d2a7211964043fd51c9ec5 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* TextEdit: deal with scrolling backwards in rich textShawn Rutledge2022-01-061-2/+2
| | | | | | | | | | | | | | | | | | | | | | A bug was introduced in 9db23e0e04906cf9ea33e23fa41f34955e5e6fe0 : when scrolling backwards in some kinds of rich text, updatePaintNode() failed to re-populate the nodes that had been scrolled out above the viewport. That was because those nodes had been removed from textNodeMap, and then firstDirtyPos was set from the first node in textNodeMap. For some reason this didn't happen with the markdown document that I was testing (maybe because it had a table and an image near the beginning), but showed up when viewing an html document similar to the one we ship with the rich text example. So now we iterate backwards from textNodeMap.begin() when this happens, to find all nodes in the current frame that intersect the viewport as rendered. In the autotest we now use font.pixelSize in an attempt to make the rendered text ranges more consistent across platforms in CI; and we need to wait for the rendering to be redone after scrolling. Pick-to: 6.3 Change-Id: I70ef54c8d8facc439b9a6f8b5cb8e3a4a1c37e16 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* TextEdit large text: don't populate blocks outside the viewport into SGShawn Rutledge2021-12-031-0/+6
| | | | | | | | | | | | | | | | | | | | | | | When the text is larger than 10000 characters, we now avoid creating nodes for blocks that go outside the viewport. Each time the text moves relative to the viewport, we check whether the rectangular area that we know is "covered" with the text rendered so far is still enough to fill the viewport; if not, update the whole document: mark all existing SG nodes dirty, then delete and re-create them. [ChangeLog][QtQuick][Text] When given large text documents (QString::size() > 10000), Text and TextEdit now try to avoid populating scene graph nodes for ranges of text that fall outside the viewport, which could be a parent item having the ItemIsViewport flag set (such as a Flickable), or the window's content item. If the viewport is smaller than the window, you might see lines of text disappearing when they are scrolled out of the viewport; if that's undesired, either design your UI so that other items obscure the area beyond the viewport, or set the clip property to make clipping exact. Task-number: QTBUG-90734 Change-Id: I9c88885b1ad3c3f24df0f7f322ed82d76b8e07c9 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* Add Markdown support to TextEditShawn Rutledge2019-05-291-1/+2
| | | | | | | | | | | | - textFormat can be set to MarkdownText, and markdown can be loaded into the text property - markdown text can be pulled out of the text property - if there are lists with checkboxes, you can click them to change the checkbox state Change-Id: I450115c732d737446ae71806e4abb18e8cc639f3 Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io>
* TextEdit: use I-beam cursor by default, pointing cursor for linksShawn Rutledge2019-05-151-0/+1
| | | | | | | | | | But do not interfere with any custom cursor that user code sets: remember and restore it when the mouse is no longer hovering a link. Task-number: QTBUG-14769 Fixes: QTBUG-50482 Change-Id: Ia4633c22d0ad42d07203d4dc3e330b90a5f94a7c Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* use nullptr consistently (clang-tidy)Shawn Rutledge2018-02-261-2/+2
| | | | | | | | | | | | | From now on we prefer nullptr instead of 0 to clarify cases where we are assigning or testing a pointer rather than a numeric zero. Also, replaced cases where 0 was passed as Qt::KeyboardModifiers with Qt::NoModifier (clang-tidy replaced them with nullptr, which waas wrong, so it was just as well to make the tests more readable rather than to revert those lines). Change-Id: I4735d35e4d9f42db5216862ce091429eadc6e65d Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* QQuickTextEdit: Simplify node handlingUlf Hermann2018-02-021-8/+6
| | | | | | | | | We don't need to manually manage pointers to nodes as QList can do that for us. Change-Id: I0185db2d5909178b3e36c8d1b7921bdbb1858ca6 Reviewed-by: Anton Kudryavtsev <antkudr@mail.ru> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Replace Q_DECL_OVERRIDE with overrideKevin Funk2017-09-251-2/+2
| | | | | Change-Id: I176f91a8c51e81a2df3fe91733118261491223ee Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Add a way to set the default render type of text-like elementsGiuseppe D'Angelo2017-08-231-5/+2
| | | | | | | | | | | | | | | | | | | | | | | | | f3446071da8357620d0c8593a04e3b4fbba88f21 introduced a build-time way to select the default render type of text-like elements. This patch adds also a way to select it at runtime, via a setter on QQuickWindow. (QQuickWindow has been chosen as convenience, rather than adding another namespace/class to just have this setter.) Given that QT_QUICK_DEFAULT_TEXT_RENDER_TYPE was never documented, I've taken the liberty of changing the accepted values for it (to match the new enumerator names in QQuickWindow, rather than the ones in QQuickText/QQuickTextEdit/etc.). [ChangeLog][QtQuick][QQuickWindow] It is now possible to set the default render type of text-like elements globally via the QQuickWindow::setTextRenderType() function. If you were using the (undocumented) QT_QUICK_DEFAULT_TEXT_RENDER_TYPE macro when building Qt Quick for the same purpose, note that the macro value needs now to be set to the "NativeTextRendering" value, instead of "NativeRendering". Change-Id: Id4b2dc3ec823971486e445ca4173b8be848fb4e3 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* Get rid of most QT_NO_FOO usagesLars Knoll2016-11-291-3/+3
| | | | | | | | Instead use QT_CONFIG(foo). This change actually detected a few mis-spelled macros and invalid usages. Change-Id: I06ac327098dd1a458e6bc379d637b8e2dac52f85 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Updated license headersJani Heikkinen2016-01-191-14/+20
| | | | | | | | | | | From Qt 5.7 -> LGPL v2.1 isn't an option anymore, see http://blog.qt.io/blog/2016/01/13/new-agreement-with-the-kde-free-qt-foundation/ Updated license headers to use new LGPL header instead of LGPL21 one (in those files which will be under LGPL v3) Change-Id: Ic36f1a0a1436fe6ac6eeca8c2375a79857e9cb12 Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
* QQuickTextEdit: added clear() methodLiang Qi2016-01-191-0/+1
| | | | | | Task-number: QTBUG-50428 Change-Id: Id618616f8d8d50c2a2eba79a2bf6969662e727b8 Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>
* Merge remote-tracking branch 'origin/5.6' into devLiang Qi2015-10-141-1/+4
|\ | | | | | | Change-Id: I11ea57222ba5aa683b7bfd7735fbc1d2cf86e875
| * QQuickTextEdit/Input: revise implicit resizing - take twoJ-P Nurmi2015-10-041-6/+2
| | | | | | | | | | | | | | | | Referencing unexported symbols (ExtraData) from an inlined method does not work with MinGW. Change-Id: I19935c84c4e2014f73bcd1801d182d193166bd44 Reviewed-by: Liang Qi <liang.qi@theqtcompany.com>
| * QQuickTextEdit/Input: revise implicit resizingJ-P Nurmi2015-10-031-1/+8
| | | | | | | | | | | | | | | | | | | | Rename explicitImplicitSize to better descriptive implicitResize, and add a method to disable the default behavior. QQuickTextField was unable to access the flag directly, because ExtraData is not exported (and we prefer to keep it that way). Change-Id: Ia8b8281267adfc376e03a14882708e9cf80f0451 Reviewed-by: Liang Qi <liang.qi@theqtcompany.com>
* | Add a way to set default font rendering at build time.Stephen Kelly2015-10-131-0/+4
|/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QML text rendering elements have a renderType property controlling whether to use 'Qt' rendering or 'Native' rendering. There is no reason to mix different types of rendering in one static ui. The element-local properties may be used to change the rendering type during animation for example, but otherwise there should be an application-wide rendering mode for text. That means that all Text-based elements in QML should default to the same rendering mode. Additionally, applications wishing to use NativeRendering, wish to use it for all text-based elements, so they require changing the defaults of the elements themselves, still allowing the possibility of changing the rendering mode during animation. Creating third party wrappers for each of the QML text rendering types is not a solution because an application requires the same font rendering for all text. That is, whether written directly with QML Text* elements, or using QtQuick controls, or another 3rd party component set, it is necessary to set the same font rendering mode for all text, except in temporary execptional cases. The known options to achieve this are 1) Create an environment variable to set the default rendering. 2) Add C++ API to set the default 3) Add a build-time option to set the default. The first option is unsatisfying because it is fragile and is easy to get wrong. The second option is incomplete because it does not affect qmlscene etc, so it would require adding a command line argument to qmlscene to change the default. That is unsatisfying because it is also fragile. It is necessary for the sanity of developers and designers (and also end users) that qmlscene use the correct default by default. It must be easy to create qml files for designers to run with qmlscene and which look correct. The third option is the one chosen for this patch. It is most suitable for environments where the Qt build and settings are contained because a particular Qt build is shipped with the application using it (This is the most common way Qt is used). It affects all uses of the text rendering elements, whether used through qmlscene or through another entry point, and it allows changing the property in QML code away from the build-time-determined default. When building Qt, -DQT_QUICK_DEFAULT_TEXT_RENDER_TYPE=NativeRendering may be passed to configure to affect the default rendering for the Qt build. It also leaves the question why the default text rendering is 'Qt' instead of being 'Native', given that many of the Qt controls need to switch to Native anyway (though this depends on the platform and the style). Change-Id: Ib0eed61caf4895b29e5c05e0418fad9962779f85 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
* TextInput & TextEdit: allow controls to override the implicit sizeJ-P Nurmi2015-09-061-0/+1
| | | | | | Change-Id: I4b5eae46a9fef574249eee9061858bdf874c54be Reviewed-by: Liang Qi <liang.qi@theqtcompany.com> Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@theqtcompany.com>
* qquicktextedit_p_p.h: cleanup unneeded includeJ-P Nurmi2015-06-241-1/+0
| | | | | | | | | A forward declaration of QQuickTextControl is enough. This solves a linking error on Windows, when QQuickTextAreaPrivate inherits QQuickTextEditPrivate. Change-Id: I05a2fa5745e27eea51f7c0a5a0360c3fbb563544 Reviewed-by: Liang Qi <liang.qi@theqtcompany.com>
* Export QQuickTextInputPrivate and QQuickTextEditPrivateJ-P Nurmi2015-06-231-1/+1
| | | | | | | ...so that QtQuick.Controls 2 TextField and TextArea can inherit them. Change-Id: I9383927c51a70848753a9f41f374d4161000fbb1 Reviewed-by: Frederik Gladhorn <frederik.gladhorn@theqtcompany.com>
* QQuickTextEdit: move paddings into extraDataLiang Qi2015-06-151-11/+18
| | | | | | Task-number: QTBUG-46529 Change-Id: I67b8125d160213121b30fbb44fa834609d668099 Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>
* QQuickText: Don't store node engine per node.Robin Burchell2015-06-061-1/+2
| | | | | | | | | | | | | | | Since these are only used during one particular phase of dealing with text, it is extremely wasteful to heap allocate them and keep them around for the entire lifetime of the node (~3kb of total allocation _each_ according to OS X). Removing these cuts around 100mb of transient allocations off the qmlbench text creation benchmark (and takes the total allocations during a test run from ~496 MB to ~389 MB). It also improves the approximate throughput for creation of text items by ~5%. Change-Id: I45c8a50879ed545da1fb13ab3c2c5d857b112cf7 Reviewed-by: Gunnar Sletta <gunnar@sletta.org> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
* TextEdit: add support for paddingJ-P Nurmi2015-03-051-1/+17
| | | | | | | | | | | | | This makes it possible for TextArea to inherit TextEdit, reserve space for the decoration, and set the desired property defaults without having to create dozens of property aliases. [ChangeLog][QtQuick][TextEdit] Added padding, leftPadding, topPadding, rightPadding and bottomPadding properties. Task-number: QTBUG-41559 Change-Id: I4fa22f86e6151524a63b2b862f17bc9d6a713142 Reviewed-by: Alan Alpert <aalpert@blackberry.com>
* Update copyright headersJani Heikkinen2015-02-121-7/+7
| | | | | | | | | Qt copyrights are now in The Qt Company, so we could update the source code headers accordingly. In the same go we should also fix the links to point to qt.io. Change-Id: I61120571787870c0ed17066afb31779b1e6e30e9 Reviewed-by: Iikka Eklund <iikka.eklund@theqtcompany.com>
* Merge remote-tracking branch 'origin/5.4' into devSimon Hausmann2014-10-311-1/+1
|\ | | | | | | Change-Id: I30f9c925631991ceb22339d1333936faecffbaf4
| * text input: always let cursor rect have a width == 1Richard Moe Gustavsen2014-10-301-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Instead of using a cursor width of null when a cursor delegate is set, we should to use a value of 1. Otherwise the rect we e.g return from cursorRect() will be invalid. An alternative would be to use the width of the delegate, but that was found to be controversial. On iOS we saw a bug with this when telling iOS to position text spelling popups underneath the cursor. Since the cursor rect we got was invalid (zero-width), no popup would show. Change-Id: Ice51b9a1bd33f331183e3acec61b7d9c0f5163cd Reviewed-by: Andrew den Exter <andrew.den.exter@qinetic.com.au>
* | Merge remote-tracking branch 'origin/5.4' into devOswald Buddenhagen2014-09-111-20/+12
|\| | | | | | | | | | | | | | | | | Conflicts: src/quick/items/qquickpainteditem.h src/quick/items/qquickshadereffectsource.cpp src/quick/items/qquickshadereffectsource_p.h Change-Id: If98096443afe85fc4370cef971eace050006a61b
| * Update license headers and add new licensesJani Heikkinen2014-08-251-19/+11
| | | | | | | | | | | | | | | | | | - Renamed LICENSE.LGPL to LICENSE.LGPLv21 - Added LICENSE.LGPLv3 & LICENSE.GPLv2 - Removed LICENSE.GPL Change-Id: I84a565e2e0caa3b76bf291a7d188a57a4b00e1b0 Reviewed-by: Jani Heikkinen <jani.heikkinen@digia.com>
| * Create rectangle nodes in the text editing through the contextLars Knoll2014-08-131-1/+1
| | | | | | | | | | | | | | | | | | | | Unfortunately we can't re-use the QSGSimpleRectNode, as it doesn't provide us with virtual methods to move it's creation into the context. But's since it's only 20 lines of code anyway, this is still a nice cleanup. And it also allows the re-use of any optimizations in the renderer for QSGRectangleNode. Change-Id: I957777fbbeb0a994a9c257baf3bfe87fce8cc9e8 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
* | Add Q_DECL_OVERRIDEAlbert Astals Cid2014-08-141-2/+2
|/ | | | | Change-Id: I2e64950aef710f943c3bc50bc9bf8a1f7fb58d28 Reviewed-by: Frederik Gladhorn <frederik.gladhorn@digia.com>
* Fix Node object leak in QQuickTextEditPrivateLiang Jian2014-07-231-0/+5
| | | | | | | Delete Node objects stored in textNodeMap at two places to prevent leak. Change-Id: I8eb0d1af900c94e1fab2f55b689de393e674f0aa Reviewed-by: Andrew den Exter <andrew.den.exter@qinetic.com.au>
* Fix license headers of QtQuick sources.Gunnar Sletta2013-09-301-1/+1
| | | | | Change-Id: I3750c47640bf21c3567c5fa1c4667e3e2552942e Reviewed-by: Lars Knoll <lars.knoll@digia.com>
* Merge remote-tracking branch 'origin/stable' into devFrederik Gladhorn2013-07-041-4/+1
|\ | | | | | | Change-Id: I15cb7460171b38d11d66367aeb0831ec6e3ca933
| * QQuickTextEdit: move QSG* members from dptr to root node.Pierre Rossi2013-07-031-4/+1
| | | | | | | | | | | | | | | | | | Subclass QSGTransform node for our use case and add the frame decorations and cursor nodes in there. Task-number: QTBUG-31580 Change-Id: Id2b468b53092f21134ae45e5694bc54c43660f8b Reviewed-by: Gunnar Sletta <gunnar.sletta@digia.com>
* | Add QQuickTextEdit::hoveredLinkJ-P Nurmi2013-06-071-0/+1
|/ | | | | | Change-Id: I9d75a97c86e047742514f942cdb91c70f1d7a9a2 Reviewed-by: Mitch Curtis <mitch.curtis@digia.com> Reviewed-by: Alan Alpert <aalpert@blackberry.com>