Selectable text
Closed, ResolvedPublic

Description

Kube will get a TextDisplay type as a read-only text type that supports text selection. This is to be used instead of labels in all places that should support
copying the text (display of addresses, names, ....).

Notable defects that this solution will have initially:

  • You cannot select text over TextDisplay boundaries. If an address is shown using multiple TextDisplay types you can only copy individual text fragments.
  • You have to accurately start the cursor trag on the textdisplay boundary if you want to select all the text. (If the previous point was solved this one would be solved with it I guess).

So in the long run we'd have to deal with mouse events that have the left mouse button pressed and then try to assemble the selection from all labels together.

The elide: Text.ElideRight option is not supported by TextInput.

Another behavioral change is, if you have text selected and click somewhere on an empty space you expect the selection to be cleared. However, that doesn't happen because the TextDisplay maintains focus, so the selection will only be cleared once you click on a focusable item.

A further challenge is how to deal with elided text in the first place. I suppose ideal behaviour would be to un-elide when the selection starts and scroll to the right while selecting (scroll with the cursor), but then show again the selected elided text once done. This is unfortunately non-trivial to implement.

What we perhaps could achieve is that we assign the text to a "fullText" property instead, and then we just assign text internally elided via textmetrics. This would then mean you can also only copy the elided text.

I wonder if we need to support partial text selection at all.

I don't worry so much about partial text-selection, it's more that it goes against everything we're used to in current systems if you cannot select the text by mouse (The alternative would be to have "Copy this to clipboard" buttons spread everywhere.

The upshot of the "copy this to clipboard" button would be that we could ensure that it's formatted sanely, it would work with more advanced delegates that aren't just text (clickable person delegates), and I suppose we could still make Ctrl+C work.

Perhaps discuss it with jens, I just want to avoid doing a half-assed solution just because our tools are so bad.

After investigating what it would take to implement this properly I came to the conclusion that it is not worth the effort.

For an example how it could be implemented see: https://gitorious.org/qt-components/qt-components.git (the label component, the inverse mouse area, all qtquick1 based and cannot be directly ported).

Challenges include:

  • Selectable text that sits on buttons etc that can be interacted with (so we don't break the interaction)
  • Detecting selection that starts outside the label (otherwise you have to hit the beginning of the label very precisely
  • Detecting a mouseclick outside of the label to clear the selection (focus is not enough, otherwise you have to go find a button).
  • Supporting selection that spans different labels (otherwise it will still feel broken in many places)
  • Dealing with elided text (should it be possible to copy elided text in full?)

The alternative is to make elements explicitly copyable with a button (+shortcut) that appears on hover.

Advantages are:

  • The copyable element can contain multiple labels, and we can format the text sanely (but have to do so explicitly)
  • The copy solution also works for touch devices.
  • Usability could actually improve if done well.
  • It's possibly to copy elided elements in full.

Disadvantages are:

  • It's impossible to only copy parts of the copyable element, it's all or nothing.
    • This should not be overly problematic for most cases, could be addressed with nested copyable elements where necessary, and since you normally paste into an editor you can just edit it there.
  • It's not necessarily the expected behaviour on desktop systems with mouse pointers.

on hover does not work with touch

I think the natural alternative for touch would be long press, which selects the element and pops up a little context menu with the copy option.

I have pushed an experimental SelectableLabel that I used in the LogView only. It simply sports an IconButton that copies the text of the label.
With a couple of labels that's perhaps not ideal (but might still be good enough for now).

Alternatives could be:

  • One button that copies all fields together
  • One button with a possibility to select/deselect individual labels.
cmollekopf moved this task from Backlog to In Progress on the Kube (0.4) board.Jul 29 2017, 10:51 PM

I have pushed an experimental SelectableLabel that I used in the LogView only. It simply sports an IconButton that copies the text of the label.
With a couple of labels that's perhaps not ideal (but might still be good enough for now).

Alternatives could be:

  • One button that copies all fields together

physical address is a case where this would make sense.

depending on how the logview turns out, we might want a single "copy this error message" button

depending on how the logview turns out, we might want a single "copy this error message" button

Agreed.

For the logview I think it would make sense to treat the whole thing as one and format the copied text just like it is visible. (including description labels etc).

Other usecases we have:

  • email address => copy button per address (but perhaps also per full line?)
  • address => single copy button for all (like logview)
  • Subject, contact name, ... => copy button per label

In all cases I would make the copy button only visible on hover, with perhaps a small frame highlighting what is included (And with touch essentially the same, just with long press and a popup menu).

mbohlender added a comment.EditedJul 30 2017, 9:35 PM

An idea for email addresses in the mailview:
click on address -> get "popup" with options:
copy to clipboard / add to addressbook / write email to

So we would make all copyable elements focusable/selectable and popup a menu that would contain "copy" + possibly other options?
That could work as well.

Essentially we would just turn the area in a big, transparent button that would popup the menu when clicked (and we could line out the area that is affected by a border).
We could of course also support shortcuts such as ctrl+c on hover (or if the area was selectable just on selected).

I'm not quite sure yet how to implement this technically, and it might depend a lot on how it is visualized. If we want to paint a border or overlay we will need a visual item in qml, otherwise we might not necessarily need that.

Something that could work is:

//A visual container that paints a border around it's children on hover
SelectableArea {
    SomeLayout {
        Label {
            text: "foobar"
            Selectable.text: text
        }
        Label {
            text: "foobar"
            Selectable.text: text
        }
    }
}

SelectableArea would be responsible for the border + the popup menu. The attached property would be used to gather the text to copy. Essentially we would go through all children and find all Selectable.text attached properties. Of course, an alternative more explicit variant would be a "text" property on the SelectableArea that we would have to assemble manually.

Further potentially useful attached properties could be:

  • Selectable.linebreak: insert a linebreak since we don't track layouting
  • Selectable.enabled: could be tied to visible by default to not copy invisible items automatically

I prototyped a solution consisting of:

  • SelectableItem: can be "attached" to a layout containing labels
  • SelectableLabel; a label that can be copied

Both use the same mechanism: An overlay is painted on hover (currently a blue border), to indicate what is affected. On rightclick, you get a context menu, that currently contains a single option "Copy", which copies the text. In case of SelectableLabel that's just the labels text, in case of SelectableItem the text is either taken from the text property, or otherwise automatically assembled by going through the assigned layout extracting it from the contained label items.

Input welcome on:

  • Better naming for the components
  • Approach; it's currently designed to be not too intrusive code-wise (as opposed to a container).
  • Usability; it clearly needs some tweaks, but if we want something wildly different then we might run into technical limitations.

Currently you can copy:

  • The subject
  • the logview area (clear out resolve.conf to generate host not found errors)
cmollekopf moved this task from In Progress to Done on the Kube (0.4) board.Aug 4 2017, 3:57 AM
mbohlender closed this task as Resolved.Aug 23 2017, 12:21 PM
mbohlender claimed this task.