2019-08-31 01:17:13 +10:00
|
|
|
import QtQuick 2.12
|
|
|
|
import QtQuick.Controls 2.12
|
2019-09-01 14:22:18 +10:00
|
|
|
import "../utils.js" as Utils
|
2019-08-31 01:17:13 +10:00
|
|
|
|
|
|
|
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
|
2019-09-01 19:57:28 +10:00
|
|
|
activeFocusOnPress: false
|
|
|
|
focus: false
|
2019-08-31 01:17:13 +10:00
|
|
|
|
|
|
|
onLinkActivated: Qt.openUrlExternally(link)
|
|
|
|
|
2019-09-12 05:42:48 +10:00
|
|
|
Component.onCompleted: updateSelection()
|
|
|
|
|
2019-08-31 01:17:13 +10:00
|
|
|
|
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
|
2019-08-31 01:17:13 +10:00
|
|
|
property HSelectableLabelContainer container
|
2019-09-02 05:44:06 +10:00
|
|
|
property bool selectable: true
|
2019-08-31 01:17:13 +10:00
|
|
|
|
|
|
|
|
|
|
|
function updateSelection() {
|
2019-09-02 05:44:06 +10:00
|
|
|
if (! selectable && label.selectedText) {
|
|
|
|
label.deselect()
|
|
|
|
updateContainerSelectedTexts()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! selectable) return
|
|
|
|
|
2019-08-31 01:17:13 +10:00
|
|
|
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) {
|
2019-08-31 01:17:13 +10:00
|
|
|
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) {
|
2019-08-31 01:17:13 +10:00
|
|
|
label.select(positionAt(firstPos.x, firstPos.y), length)
|
|
|
|
|
2019-12-10 02:35:50 +11:00
|
|
|
} else if (last === index) {
|
2019-08-31 01:17:13 +10:00
|
|
|
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() :
|
2019-08-31 01:17:13 +10:00
|
|
|
container.clearSelection()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-12 05:25:57 +10:00
|
|
|
PointHandler {
|
|
|
|
onActiveChanged:
|
|
|
|
active ? container.dragStarted() : container.dragStopped()
|
|
|
|
onPointChanged: container.dragPointChanged(point)
|
|
|
|
}
|
|
|
|
|
2019-08-31 01:17:13 +10:00
|
|
|
MouseArea {
|
|
|
|
anchors.fill: label
|
|
|
|
acceptedButtons: Qt.NoButton
|
|
|
|
cursorShape: label.hoveredLink ? Qt.PointingHandCursor : Qt.IBeamCursor
|
|
|
|
}
|
|
|
|
}
|