Add ChatBarMessageContentModel and hook up
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
// SPDX-FileCopyrightText: 2025 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
import QtCore
|
||||
import QtQuick
|
||||
import QtQuick.Controls as QQC2
|
||||
import QtQuick.Layouts
|
||||
@@ -8,6 +9,7 @@ import QtQuick.Layouts
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
import org.kde.neochat.libneochat as LibNeoChat
|
||||
import org.kde.neochat.messagecontent as MessageContent
|
||||
|
||||
QQC2.ToolBar {
|
||||
id: root
|
||||
@@ -19,13 +21,23 @@ QQC2.ToolBar {
|
||||
|
||||
property LibNeoChat.ChatBarCache chatBarCache
|
||||
|
||||
required property LibNeoChat.ChatDocumentHandler documentHandler
|
||||
required property MessageContent.ChatBarMessageContentModel contentModel
|
||||
readonly property LibNeoChat.ChatDocumentHandler focusedDocumentHandler: contentModel.focusedDocumentHandler
|
||||
|
||||
Connections {
|
||||
target: contentModel
|
||||
|
||||
function onFocusRowChanged() {
|
||||
console.warn("focus changed", contentModel.focusRow, contentModel.focusType)
|
||||
}
|
||||
}
|
||||
|
||||
required property real maxAvailableWidth
|
||||
|
||||
readonly property real uncompressedImplicitWidth: textFormatRow.implicitWidth +
|
||||
listRow.implicitWidth +
|
||||
styleButton.implicitWidth +
|
||||
codeButton.implicitWidth +
|
||||
emojiButton.implicitWidth +
|
||||
linkButton.implicitWidth +
|
||||
sendRow.implicitWidth +
|
||||
@@ -36,6 +48,7 @@ QQC2.ToolBar {
|
||||
readonly property real listCompressedImplicitWidth: textFormatRow.implicitWidth +
|
||||
compressedListButton.implicitWidth +
|
||||
styleButton.implicitWidth +
|
||||
codeButton.implicitWidth +
|
||||
emojiButton.implicitWidth +
|
||||
linkButton.implicitWidth +
|
||||
sendRow.implicitWidth +
|
||||
@@ -46,6 +59,7 @@ QQC2.ToolBar {
|
||||
readonly property real textFormatCompressedImplicitWidth: compressedTextFormatButton.implicitWidth +
|
||||
compressedListButton.implicitWidth +
|
||||
styleButton.implicitWidth +
|
||||
codeButton.implicitWidth +
|
||||
emojiButton.implicitWidth +
|
||||
linkButton.implicitWidth +
|
||||
sendRow.implicitWidth +
|
||||
@@ -53,7 +67,7 @@ QQC2.ToolBar {
|
||||
buttonRow.spacing * 9 +
|
||||
3
|
||||
|
||||
signal requestPostMessage
|
||||
signal clicked
|
||||
|
||||
RowLayout {
|
||||
id: buttonRow
|
||||
@@ -67,11 +81,15 @@ QQC2.ToolBar {
|
||||
onActivated: boldButton.clicked()
|
||||
}
|
||||
icon.name: "format-text-bold"
|
||||
enabled: root.contentModel.focusType !== LibNeoChat.MessageComponentType.Code
|
||||
text: i18nc("@action:button", "Bold")
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
checkable: true
|
||||
checked: root.documentHandler.bold
|
||||
onClicked: root.documentHandler.bold = checked;
|
||||
checked: root.focusedDocumentHandler.bold
|
||||
onClicked: {
|
||||
root.focusedDocumentHandler.bold = checked;
|
||||
root.clicked()
|
||||
}
|
||||
|
||||
QQC2.ToolTip.text: text
|
||||
QQC2.ToolTip.visible: hovered
|
||||
@@ -84,11 +102,15 @@ QQC2.ToolBar {
|
||||
onActivated: italicButton.clicked()
|
||||
}
|
||||
icon.name: "format-text-italic"
|
||||
enabled: root.contentModel.focusType !== LibNeoChat.MessageComponentType.Code
|
||||
text: i18nc("@action:button", "Italic")
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
checkable: true
|
||||
checked: root.documentHandler.italic
|
||||
onClicked: root.documentHandler.italic = checked;
|
||||
checked: root.focusedDocumentHandler.italic
|
||||
onClicked: {
|
||||
root.focusedDocumentHandler.italic = checked;
|
||||
root.clicked()
|
||||
}
|
||||
|
||||
QQC2.ToolTip.text: text
|
||||
QQC2.ToolTip.visible: hovered
|
||||
@@ -101,11 +123,15 @@ QQC2.ToolBar {
|
||||
onActivated: underlineButton.clicked()
|
||||
}
|
||||
icon.name: "format-text-underline"
|
||||
enabled: root.contentModel.focusType !== LibNeoChat.MessageComponentType.Code
|
||||
text: i18nc("@action:button", "Underline")
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
checkable: true
|
||||
checked: root.documentHandler.underline
|
||||
onClicked: root.documentHandler.underline = checked;
|
||||
checked: root.focusedDocumentHandler.underline
|
||||
onClicked: {
|
||||
root.focusedDocumentHandler.underline = checked;
|
||||
root.clicked();
|
||||
}
|
||||
|
||||
QQC2.ToolTip.text: text
|
||||
QQC2.ToolTip.visible: hovered
|
||||
@@ -113,11 +139,15 @@ QQC2.ToolBar {
|
||||
}
|
||||
QQC2.ToolButton {
|
||||
icon.name: "format-text-strikethrough"
|
||||
enabled: root.contentModel.focusType !== LibNeoChat.MessageComponentType.Code
|
||||
text: i18nc("@action:button", "Strikethrough")
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
checkable: true
|
||||
checked: root.documentHandler.strikethrough
|
||||
onClicked: root.documentHandler.strikethrough = checked;
|
||||
checked: root.focusedDocumentHandler.strikethrough
|
||||
onClicked: {
|
||||
root.focusedDocumentHandler.strikethrough = checked;
|
||||
root.clicked()
|
||||
}
|
||||
|
||||
QQC2.ToolTip.text: text
|
||||
QQC2.ToolTip.visible: hovered
|
||||
@@ -128,6 +158,7 @@ QQC2.ToolBar {
|
||||
id: compressedTextFormatButton
|
||||
visible: root.maxAvailableWidth < root.listCompressedImplicitWidth
|
||||
icon.name: "dialog-text-and-font"
|
||||
enabled: root.contentModel.focusType !== LibNeoChat.MessageComponentType.Code
|
||||
text: i18nc("@action:button", "Format Text")
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
checkable: true
|
||||
@@ -144,29 +175,41 @@ QQC2.ToolBar {
|
||||
icon.name: "format-text-bold"
|
||||
text: i18nc("@action:button", "Bold")
|
||||
checkable: true
|
||||
checked: root.documentHandler.bold
|
||||
onTriggered: root.documentHandler.bold = checked;
|
||||
checked: root.focusedDocumentHandler.bold
|
||||
onTriggered: {
|
||||
root.focusedDocumentHandler.bold = checked;
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
QQC2.MenuItem {
|
||||
icon.name: "format-text-italic"
|
||||
text: i18nc("@action:button", "Italic")
|
||||
checkable: true
|
||||
checked: root.documentHandler.italic
|
||||
onTriggered: root.documentHandler.italic = checked;
|
||||
checked: root.focusedDocumentHandler.italic
|
||||
onTriggered: {
|
||||
root.focusedDocumentHandler.italic = checked;
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
QQC2.MenuItem {
|
||||
icon.name: "format-text-underline"
|
||||
text: i18nc("@action:button", "Underline")
|
||||
checkable: true
|
||||
checked: root.documentHandler.underline
|
||||
onTriggered: root.documentHandler.underline = checked;
|
||||
checked: root.focusedDocumentHandler.underline
|
||||
onTriggered: {
|
||||
root.focusedDocumentHandler.underline = checked;
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
QQC2.MenuItem {
|
||||
icon.name: "format-text-strikethrough"
|
||||
text: i18nc("@action:button", "Strikethrough")
|
||||
checkable: true
|
||||
checked: root.documentHandler.strikethrough
|
||||
onTriggered: root.documentHandler.strikethrough = checked;
|
||||
checked: root.focusedDocumentHandler.strikethrough
|
||||
onTriggered: {
|
||||
root.focusedDocumentHandler.strikethrough = checked;
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,12 +226,14 @@ QQC2.ToolBar {
|
||||
visible: root.maxAvailableWidth > root.uncompressedImplicitWidth
|
||||
QQC2.ToolButton {
|
||||
icon.name: "format-list-unordered"
|
||||
enabled: root.contentModel.focusType !== LibNeoChat.MessageComponentType.Code
|
||||
text: i18nc("@action:button", "Unordered List")
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
checkable: true
|
||||
checked: root.documentHandler.currentListStyle === 1
|
||||
checked: root.focusedDocumentHandler.currentListStyle === 1
|
||||
onClicked: {
|
||||
root.documentHandler.setListStyle(root.documentHandler.currentListStyle === 1 ? 0 : 1)
|
||||
root.focusedDocumentHandler.setListStyle(root.focusedDocumentHandler.currentListStyle === 1 ? 0 : 1);
|
||||
root.clicked();
|
||||
}
|
||||
|
||||
QQC2.ToolTip.text: text
|
||||
@@ -197,11 +242,15 @@ QQC2.ToolBar {
|
||||
}
|
||||
QQC2.ToolButton {
|
||||
icon.name: "format-list-ordered"
|
||||
enabled: root.contentModel.focusType !== LibNeoChat.MessageComponentType.Code
|
||||
text: i18nc("@action:button", "Ordered List")
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
checkable: true
|
||||
checked: root.documentHandler.currentListStyle === 4
|
||||
onClicked: root.documentHandler.setListStyle(root.documentHandler.currentListStyle === 4 ? 0 : 4)
|
||||
checked: root.focusedDocumentHandler.currentListStyle === 4
|
||||
onClicked: {
|
||||
root.focusedDocumentHandler.setListStyle(root.focusedDocumentHandler.currentListStyle === 4 ? 0 : 4);
|
||||
root.clicked();
|
||||
}
|
||||
|
||||
QQC2.ToolTip.text: text
|
||||
QQC2.ToolTip.visible: hovered
|
||||
@@ -213,7 +262,8 @@ QQC2.ToolBar {
|
||||
text: i18nc("@action:button", "Increase List Level")
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
onClicked: {
|
||||
root.documentHandler.indentListMore();
|
||||
root.focusedDocumentHandler.indentListMore();
|
||||
root.clicked();
|
||||
}
|
||||
|
||||
QQC2.ToolTip.text: text
|
||||
@@ -226,7 +276,8 @@ QQC2.ToolBar {
|
||||
text: i18nc("@action:button", "Decrease List Level")
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
onClicked: {
|
||||
root.documentHandler.indentListLess();
|
||||
root.focusedDocumentHandler.indentListLess();
|
||||
root.clicked();
|
||||
}
|
||||
|
||||
QQC2.ToolTip.text: text
|
||||
@@ -236,6 +287,7 @@ QQC2.ToolBar {
|
||||
}
|
||||
QQC2.ToolButton {
|
||||
id: compressedListButton
|
||||
enabled: root.contentModel.focusType !== LibNeoChat.MessageComponentType.Code
|
||||
visible: root.maxAvailableWidth < root.uncompressedImplicitWidth
|
||||
icon.name: "format-list-unordered"
|
||||
text: i18nc("@action:button", "List Style")
|
||||
@@ -253,22 +305,34 @@ QQC2.ToolBar {
|
||||
QQC2.MenuItem {
|
||||
icon.name: "format-list-unordered"
|
||||
text: i18nc("@action:button", "Unordered List")
|
||||
onTriggered: root.documentHandler.setListStyle(root.documentHandler.currentListStyle === 1 ? 0 : 1);
|
||||
onTriggered: {
|
||||
root.focusedDocumentHandler.setListStyle(root.focusedDocumentHandler.currentListStyle === 1 ? 0 : 1);
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
QQC2.MenuItem {
|
||||
icon.name: "format-list-ordered"
|
||||
text: i18nc("@action:button", "Ordered List")
|
||||
onTriggered: root.documentHandler.setListStyle(root.documentHandler.currentListStyle === 4 ? 0 : 4);
|
||||
onTriggered: {
|
||||
root.focusedDocumentHandler.setListStyle(root.focusedDocumentHandler.currentListStyle === 4 ? 0 : 4);
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
QQC2.MenuItem {
|
||||
icon.name: "format-indent-more"
|
||||
text: i18nc("@action:button", "Increase List Level")
|
||||
onTriggered: root.documentHandler.indentListMore();
|
||||
onTriggered: {
|
||||
root.focusedDocumentHandler.indentListMore();
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
QQC2.MenuItem {
|
||||
icon.name: "format-indent-less"
|
||||
text: i18nc("@action:button", "Decrease List Level")
|
||||
onTriggered: root.documentHandler.indentListLess();
|
||||
onTriggered: {
|
||||
root.focusedDocumentHandler.indentListLess();
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,31 +357,56 @@ QQC2.ToolBar {
|
||||
|
||||
QQC2.MenuItem {
|
||||
text: i18nc("@item:inmenu no heading", "Paragraph")
|
||||
onTriggered: root.documentHandler.setHeadingLevel(0);
|
||||
onTriggered: root.contentModel.insertComponentAtCursor(LibNeoChat.MessageComponentType.Text);
|
||||
}
|
||||
QQC2.MenuItem {
|
||||
text: i18nc("@item:inmenu heading level 1 (largest)", "Heading 1")
|
||||
onTriggered: root.documentHandler.setHeadingLevel(1);
|
||||
onTriggered: {
|
||||
root.focusedDocumentHandler.style = LibNeoChat.ChatDocumentHandler.Heading1;
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
QQC2.MenuItem {
|
||||
text: i18nc("@item:inmenu heading level 2", "Heading 2")
|
||||
onTriggered: root.documentHandler.setHeadingLevel(2);
|
||||
onTriggered: {
|
||||
root.focusedDocumentHandler.style = LibNeoChat.ChatDocumentHandler.Heading2;
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
QQC2.MenuItem {
|
||||
text: i18nc("@item:inmenu heading level 3", "Heading 3")
|
||||
onTriggered: root.documentHandler.setHeadingLevel(3);
|
||||
onTriggered: {
|
||||
root.focusedDocumentHandler.style = LibNeoChat.ChatDocumentHandler.Heading3;
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
QQC2.MenuItem {
|
||||
text: i18nc("@item:inmenu heading level 4", "Heading 4")
|
||||
onTriggered: root.documentHandler.setHeadingLevel(4);
|
||||
onTriggered: {
|
||||
root.focusedDocumentHandler.style = LibNeoChat.ChatDocumentHandler.Heading4;
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
QQC2.MenuItem {
|
||||
text: i18nc("@item:inmenu heading level 5", "Heading 5")
|
||||
onTriggered: root.documentHandler.setHeadingLevel(5);
|
||||
onTriggered: {
|
||||
root.focusedDocumentHandler.style = LibNeoChat.ChatDocumentHandler.Heading5;
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
QQC2.MenuItem {
|
||||
text: i18nc("@item:inmenu heading level 6 (smallest)", "Heading 6")
|
||||
onTriggered: root.documentHandler.setHeadingLevel(6);
|
||||
onTriggered: {
|
||||
root.focusedDocumentHandler.style = LibNeoChat.ChatDocumentHandler.Heading6;
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
QQC2.MenuItem {
|
||||
text: i18nc("@item:inmenu", "Quote")
|
||||
onTriggered: {
|
||||
root.contentModel.insertComponentAtCursor(LibNeoChat.MessageComponentType.Quote);
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,6 +414,20 @@ QQC2.ToolBar {
|
||||
QQC2.ToolTip.visible: hovered
|
||||
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
}
|
||||
QQC2.ToolButton {
|
||||
id: codeButton
|
||||
icon.name: "format-text-code"
|
||||
text: i18n("Code")
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
|
||||
onClicked: {
|
||||
root.contentModel.insertComponentAtCursor(LibNeoChat.MessageComponentType.Code);
|
||||
root.clicked();
|
||||
}
|
||||
QQC2.ToolTip.visible: hovered
|
||||
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
QQC2.ToolTip.text: text
|
||||
}
|
||||
Kirigami.Separator {
|
||||
Layout.fillHeight: true
|
||||
Layout.margins: 0
|
||||
@@ -354,10 +457,13 @@ QQC2.ToolBar {
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
onClicked: {
|
||||
let dialog = linkDialog.createObject(QQC2.Overlay.overlay, {
|
||||
linkText: root.documentHandler.currentLinkText(),
|
||||
linkUrl: root.documentHandler.currentLinkUrl()
|
||||
linkText: root.focusedDocumentHandler.currentLinkText(),
|
||||
linkUrl: root.focusedDocumentHandler.currentLinkUrl()
|
||||
})
|
||||
dialog.onAccepted.connect(() => { documentHandler.updateLink(dialog.linkUrl, dialog.linkText) });
|
||||
dialog.onAccepted.connect(() => {
|
||||
root.focusedDocumentHandler.updateLink(dialog.linkUrl, dialog.linkText)
|
||||
root.clicked();
|
||||
});
|
||||
dialog.open();
|
||||
}
|
||||
|
||||
@@ -384,7 +490,7 @@ QQC2.ToolBar {
|
||||
|
||||
onClicked: {
|
||||
let dialog = (LibNeoChat.Clipboard.hasImage ? attachDialog : openFileDialog).createObject(QQC2.Overlay.overlay);
|
||||
dialog.chosen.connect(path => root.chatBarCache.attachmentPath = path);
|
||||
dialog.chosen.connect(path => root.contentModel.addAttachment(path));
|
||||
dialog.open();
|
||||
}
|
||||
QQC2.ToolTip.visible: hovered
|
||||
@@ -482,9 +588,8 @@ QQC2.ToolBar {
|
||||
icon.name: "document-send"
|
||||
text: i18n("Send message")
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
checkable: true
|
||||
|
||||
onClicked: root.requestPostMessage()
|
||||
onClicked: root.contentModel.postMessage();
|
||||
QQC2.ToolTip.visible: hovered
|
||||
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
QQC2.ToolTip.text: text
|
||||
@@ -543,7 +648,7 @@ QQC2.ToolBar {
|
||||
currentRoom: root.room
|
||||
|
||||
onChosen: emoji => {
|
||||
root.documentHandler.insertText(emoji);
|
||||
root.focusedDocumentHandler.insertText(emoji);
|
||||
close();
|
||||
}
|
||||
onClosed: if (emojiButton.checked) {
|
||||
|
||||
Reference in New Issue
Block a user