moment/src/gui/Base/HSelectableLabel.qml

143 lines
4.0 KiB
QML
Raw Normal View History

2019-12-19 22:46:16 +11:00
// SPDX-License-Identifier: LGPL-3.0-or-later
import QtQuick 2.12
import QtQuick.Controls 2.12
TextEdit {
id: label
font.family: theme.fontFamily.sans
font.pixelSize: theme.fontSize.normal
color: theme.colors.text
textFormat: Label.PlainText
tabStopDistance: 4 * 4 // 4 spaces
readOnly: true
persistentSelection: true
activeFocusOnPress: false
focus: false
onLinkActivated: Qt.openUrlExternally(link)
Component.onCompleted: updateSelection()
2019-09-01 17:40:48 +10:00
// If index is a whole number, the label will get two \n before itself
// in container.joinedSelection. If it's a decimal number, if gets one \n.
property real index
property HSelectableLabelContainer container
2019-09-02 05:44:06 +10:00
property bool selectable: true
function updateSelection() {
2019-09-02 05:44:06 +10:00
if (! selectable && label.selectedText) {
label.deselect()
updateContainerSelectedTexts()
return
}
if (! selectable) return
if (! container.reversed &&
container.selectionStart <= container.selectionEnd ||
container.reversed &&
container.selectionStart > container.selectionEnd)
{
var first = container.selectionStart
var firstPos = container.selectionStartPosition
var last = container.selectionEnd
var lastPos = container.selectionEndPosition
} else {
var first = container.selectionEnd
var firstPos = container.selectionEndPosition
var last = container.selectionStart
var lastPos = container.selectionStartPosition
}
2019-12-10 02:35:50 +11:00
if (first === index && last === index) {
select(
label.positionAt(firstPos.x, firstPos.y),
label.positionAt(lastPos.x, lastPos.y),
)
} else if ((! container.reversed && first < index && index < last) ||
(container.reversed && first > index && index > last))
{
label.selectAll()
2019-12-10 02:35:50 +11:00
} else if (first === index) {
label.select(positionAt(firstPos.x, firstPos.y), length)
2019-12-10 02:35:50 +11:00
} else if (last === index) {
label.select(0, positionAt(lastPos.x, lastPos.y))
} else {
label.deselect()
}
updateContainerSelectedTexts()
}
function updateContainerSelectedTexts() {
container.selectedTexts[index] = selectedText
container.selectedTextsChanged()
}
function selectWordAt(position) {
container.clearSelection()
label.cursorPosition = positionAt(position.x, position.y)
label.selectWord()
updateContainerSelectedTexts()
}
function selectAllText() {
container.clearSelection()
label.selectAll()
updateContainerSelectedTexts()
}
Connections {
target: container
onSelectionInfoChanged: updateSelection()
onDeselectAll: deselect()
}
DropArea {
anchors.fill: parent
onPositionChanged: {
if (! container.selecting) {
container.clearSelection()
container.selectionStart = index
container.selectionStartPosition = Qt.point(drag.x, drag.y)
container.selecting = true
} else {
container.selectionEnd = index
container.selectionEndPosition = Qt.point(drag.x, drag.y)
}
}
}
TapHandler {
acceptedButtons: Qt.LeftButton
onTapped: {
2019-12-10 02:35:50 +11:00
tapCount === 2 ? selectWordAt(eventPoint.position) :
tapCount === 3 ? selectAllText() :
container.clearSelection()
}
}
2019-09-12 05:25:57 +10:00
PointHandler {
onActiveChanged:
active ? container.dragStarted() : container.dragStopped()
onPointChanged: container.dragPointChanged(point)
}
MouseArea {
anchors.fill: label
acceptedButtons: Qt.NoButton
cursorShape: label.hoveredLink ? Qt.PointingHandCursor : Qt.IBeamCursor
}
}