Skip to content

Commit

Permalink
WIP multiline text handling based on https://www.kdab.com/handling-a-…
Browse files Browse the repository at this point in the history
…lot-of-text-in-qml/

There's also an improved branch by our favorite nuttyartist here
https://github.com/shaan7/qtdevcon2022-textarea/tree/improvements/v1 .
Check that out when continuing with this.
  • Loading branch information
MartinBriza committed Sep 28, 2023
1 parent a353689 commit de6b3c1
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 4 deletions.
8 changes: 4 additions & 4 deletions modules/Lith/Core/formattedstring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,19 +192,19 @@ QString FormattedString::toPlain() const {
}

QString FormattedString::toHtml(const ColorTheme& theme) const {
QString ret {"<html><body><span style='white-space: pre-wrap;'>"};
QString ret; // {"<html><body><span style='white-space: pre-wrap;'>"};
for (const auto& i : m_parts) {
ret.append(i.toHtml(theme));
}
ret.append("</span></body></html>");
// ret.append("</span></body></html>");
return ret;
}

QString FormattedString::toTrimmedHtml(int n, const ColorTheme& theme) const {
if (n < 0) {
return toHtml(theme);
}
QString ret = "<html><body><span style='white-space: pre-wrap;'>";
QString ret; // = "<html><body><span style='white-space: pre-wrap;'>";
for (const auto& i : m_parts) {
QString word = i.text.left(n);
Part tempPart = i;
Expand All @@ -219,7 +219,7 @@ QString FormattedString::toTrimmedHtml(int n, const ColorTheme& theme) const {
ret.append("\u00A0");
n--;
}
ret += "</span></body></html>";
// ret += "</span></body></html>";
return ret;
}

Expand Down
171 changes: 171 additions & 0 deletions modules/Lith/UI/ChannelMessageList.qml
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,189 @@ ListView {
verticalLayoutDirection: ListView.BottomToTop
spacing: Lith.settings.messageSpacing
model: Lith.selectedBuffer ? Lith.selectedBuffer.lines_filtered : null
/*
delegate: ChannelMessage {
messageModel: modelData
readonly property string sectionName: ListView.section
readonly property string nextSectionName: ListView.nextSection
header: Lith.settings.showDateHeaders && sectionName !== nextSectionName ? sectionName : ""
width: listView.delegateWidth
}
*/
delegate: TextArea {
id: delegateRoot
padding: 0
width: ListView.view.width
textFormat: TextEdit.RichText
renderType: TextEdit.NativeRendering
wrapMode: Text.Wrap
color: LithPalette.regular.text
activeFocusOnPress: false
activeFocusOnTab: false

required property var modelData
readonly property var messageModel: modelData
required property int index
text: "%1 %2 %3"
.arg(messageModel.date.toLocaleString(Qt.locale(), Lith.settings.timestampFormat))
.arg(messageModel.prefix.toTrimmedHtml(Lith.settings.nickCutoffThreshold))
.arg(messageModel.message)


/*
MouseArea {
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.NoButton
}
*/

onLinkActivated: (link) => {
linkHandler.show(link, delegateRoot)
}
onHoveredLinkChanged: {
if (hoveredLink) {
selectionArea.itemWithHoveredUrl = this
}
else {
if (selectionArea.itemWithHoveredUrl == this) {
selectionArea.itemWithHoveredUrl = null
}
}
}

Connections {
target: selectionArea
function onSelectionChanged() {
updateSelection();
}
}

Component.onCompleted: updateSelection()

function updateSelection() {
if (index < selectionArea.selTopIndex || index > selectionArea.selBottomIndex)
delegateRoot.select(0, 0);
else if (index > selectionArea.selTopIndex && index < selectionArea.selBottomIndex)
delegateRoot.selectAll();
else if (index === selectionArea.selTopIndex && index === selectionArea.selBottomIndex)
delegateRoot.select(selectionArea.selTopPos, selectionArea.selBottomPos);
else if (index === selectionArea.selTopIndex)
//delegateRoot.select(selectionArea.selStartPos, delegateRoot.length);
delegateRoot.select(0, selectionArea.selTopPos);
else if (index === selectionArea.selBottomIndex)
//delegateRoot.select(0, selectionArea.selEndPos);
delegateRoot.select(selectionArea.selBottomPos, delegateRoot.length);
}
}

function indexAtRelative(x, y) {
return indexAt(x + contentX, y + contentY)
}

MouseArea {
id: selectionArea
z: 1000000
readonly property int selTopIndex: selStartIndex < selEndIndex ? selStartIndex : selEndIndex
readonly property int selBottomIndex: selStartIndex < selEndIndex ? selEndIndex : selStartIndex
readonly property int selTopPos: selStartIndex < selEndIndex ? selStartPos : selEndPos
readonly property int selBottomPos: selStartIndex < selEndIndex ? selEndPos : selStartPos
property int selStartIndex
property int selEndIndex
property int selStartPos
property int selEndPos

signal selectionChanged

property var itemWithHoveredUrl: null

anchors.fill: parent
enabled: !scrollBar.hovered
cursorShape: enabled ? itemWithHoveredUrl ? Qt.PointingHandCursor : Qt.IBeamCursor : Qt.ArrowCursor
propagateComposedEvents: false

function indexAndPos(x, y) {
const index = listView.indexAtRelative(x, y)
if (index === -1)
return
const item = listView.itemAtIndex(index)
const relItemY = item.y - listView.contentY
const itemLocalCoords = Qt.point(x, y - relItemY)
const pos = item.positionAt(itemLocalCoords.x, itemLocalCoords.y)

return [index, pos, item, itemLocalCoords]
}

onPressed: (mouse) => {
const result = indexAndPos(mouse.x, mouse.y)
selStartIndex = result[0]
selStartPos = result[1]
selEndIndex = result[0]
selEndPos = result[1]
selectionChanged()
}

onReleased: (mouse) => {
const result = indexAndPos(mouse.x, mouse.y)
selEndIndex = result[0]
selEndPos = result[1]
const item = result[2]
const localCoords = result[3]

selectionChanged()
if (selStartIndex == selEndIndex && selStartPos == selEndPos) {
mouse.accepted = false
const link = item.linkAt(localCoords.x, localCoords.y)
if (link.length > 0)
linkHandler.show(link, item)

}
else {
mouse.accepted = true
}
}

onClicked: (mouse) => {
mouse.accepted = false
}

onPositionChanged: (mouse) => {
if (pressed) {
const result = indexAndPos(mouse.x, mouse.y)
selEndIndex = result[0]
selEndPos = result[1]
selectionChanged()
}
}
}

function getSelectedText() {
var result = ""
for (let i = selectionArea.selBottomIndex; i >= selectionArea.selTopIndex; i--) {
const item = listView.itemAtIndex(i)
console.warn(item.selectedText)
result += item.selectedText
}
return result
}

Keys.onShortcutOverride: (event) => {
console.warn("A")
}

Shortcut {
sequence: "Ctrl+M"
onActivated: {
console.warn("CCCCC")
listView.getSelectedText()
}
}

section.criteria: ViewSection.FullString
section.labelPositioning: ViewSection.InlineLabels
section.property: "modelData.dateString"

interactive: false
Connections {
target: Lith.search
function onHighlightedMatchIndexChanged() {
Expand Down

0 comments on commit de6b3c1

Please sign in to comment.