Make sure that the style menu shows the right style name for code and quote.

Also when in quote mode the valid styles are now transformed to how they look in quote to show they are valid. Clicking quote style again in a quote block will return to paragrpah style from heading now
This commit is contained in:
James Graham
2026-02-07 17:18:26 +00:00
parent 7afce01a23
commit 13d7f9b322
11 changed files with 110 additions and 18 deletions

View File

@@ -57,6 +57,7 @@ RowLayout {
readonly property ChatButtonHelper chatButtonHelper: ChatButtonHelper {
textItem: root.contentModel.focusedTextItem
inQuote: root.contentModel.focusType == LibNeoChat.MessageComponentType.Quote
}
signal clicked
@@ -195,11 +196,12 @@ RowLayout {
}
StyleButton {
id: styleButton
Layout.minimumWidth: compressed ? -1 : Kirigami.Units.gridUnit * 8 + Kirigami.Units.largeSpacing * 2
Layout.minimumWidth: compressed ? -1 : Kirigami.Units.gridUnit * 10 + Kirigami.Units.largeSpacing * 2
icon.name: "typewriter"
text: i18nc("@action:button", "Text Style")
style: root.chatButtonHelper.currentStyle
inQuote: root.contentModel.focusType == LibNeoChat.MessageComponentType.Quote
compressed: root.maxAvailableWidth < root.extraTextCompressedImplicitWidth
enabled: root.chatButtonHelper.styleFormatEnabled
display: QQC2.AbstractButton.IconOnly
@@ -216,8 +218,10 @@ RowLayout {
StylePicker {
id: styleMenu
width: styleButton.compressed ? implicitWidth : styleButton.width
chatContentModel: root.contentModel
chatButtonHelper: root.chatButtonHelper
inQuote: root.contentModel.focusType == LibNeoChat.MessageComponentType.Quote
onClosed: {
root.clicked()

View File

@@ -16,6 +16,8 @@ QQC2.AbstractButton {
required property int style
required property bool inQuote
property bool open: false
property bool compressed: false
@@ -37,6 +39,7 @@ QQC2.AbstractButton {
visible: !root.compressed
style: root.style
inQuote: root.inQuote
sizeText: false
onPressed: root.clicked()

View File

@@ -16,6 +16,8 @@ QQC2.TextArea {
required property int style
required property bool inQuote
property bool highlight: false
property bool sizeText: true
@@ -52,11 +54,12 @@ QQC2.TextArea {
StyleDelegateHelper {
textItem: root
inQuote: root.inQuote
}
background: Rectangle {
color: Kirigami.Theme.backgroundColor
Kirigami.Theme.colorSet: root.style === LibNeoChat.RichFormat.Quote ? Kirigami.Theme.Window : Kirigami.Theme.View
Kirigami.Theme.colorSet: root.style === LibNeoChat.RichFormat.Quote || (root.inQuote && !(root.style == LibNeoChat.RichFormat.Paragraph || root.style == LibNeoChat.RichFormat.Code)) ? Kirigami.Theme.Window : Kirigami.Theme.View
Kirigami.Theme.inherit: false
radius: Kirigami.Units.cornerRadius
border {

View File

@@ -17,6 +17,7 @@ QQC2.Popup {
required property MessageContent.ChatBarMessageContentModel chatContentModel
required property ChatButtonHelper chatButtonHelper
required property bool inQuote
y: -implicitHeight
padding: Kirigami.Units.largeSpacing
@@ -35,7 +36,12 @@ QQC2.Popup {
Layout.minimumWidth: Kirigami.Units.gridUnit * 8
Layout.minimumHeight: Kirigami.Units.gridUnit * 2
enabled: chatButtonHelper.richFormatEnabled ||
index == LibNeoChat.RichFormat.Paragraph ||
index == LibNeoChat.RichFormat.Code ||
index == LibNeoChat.RichFormat.Quote
style: index
inQuote: root.inQuote
highlight: root.chatButtonHelper.currentStyle === index || hovered
onPressed: (event) => {

View File

@@ -41,6 +41,7 @@ void ChatButtonHelper::setTextItem(ChatTextItemHelper *textItem)
}
});
connect(m_textItem, &ChatTextItemHelper::textFormatChanged, this, &ChatButtonHelper::richFormatEnabledChanged);
connect(m_textItem, &ChatTextItemHelper::textFormatChanged, this, &ChatButtonHelper::styleChanged);
connect(m_textItem, &ChatTextItemHelper::charFormatChanged, this, &ChatButtonHelper::charFormatChanged);
connect(m_textItem, &ChatTextItemHelper::styleChanged, this, &ChatButtonHelper::styleChanged);
connect(m_textItem, &ChatTextItemHelper::listChanged, this, &ChatButtonHelper::listChanged);
@@ -48,6 +49,23 @@ void ChatButtonHelper::setTextItem(ChatTextItemHelper *textItem)
Q_EMIT textItemChanged();
Q_EMIT richFormatEnabledChanged();
Q_EMIT styleChanged();
}
bool ChatButtonHelper::inQuote() const
{
return m_inQuote;
}
void ChatButtonHelper::setInQuote(bool inQuote)
{
if (inQuote == m_inQuote) {
return;
}
m_inQuote = inQuote;
Q_EMIT inQuoteChanged();
Q_EMIT richFormatEnabledChanged();
Q_EMIT styleChanged();
}
bool ChatButtonHelper::richFormatEnabled() const
@@ -158,7 +176,14 @@ RichFormat::Format ChatButtonHelper::currentStyle() const
if (!m_textItem) {
return RichFormat::Paragraph;
}
return static_cast<RichFormat::Format>(m_textItem->textCursor().blockFormat().headingLevel());
if (!richFormatEnabled()) {
return RichFormat::Code;
}
const auto currentHeadingLevel = m_textItem->textCursor().blockFormat().headingLevel();
if (currentHeadingLevel == 0 && m_inQuote) {
return RichFormat::Quote;
}
return static_cast<RichFormat::Format>(currentHeadingLevel);
}
void ChatButtonHelper::setFormat(RichFormat::Format format)

View File

@@ -23,6 +23,11 @@ class ChatButtonHelper : public QObject
*/
Q_PROPERTY(ChatTextItemHelper *textItem READ textItem WRITE setTextItem NOTIFY textItemChanged)
/**
* @brief Whether the current block is a Quote block.
*/
Q_PROPERTY(bool inQuote READ inQuote WRITE setInQuote NOTIFY inQuoteChanged)
/**
* @brief Whether rich formating is enabled at the current cursor location.
*/
@@ -94,6 +99,9 @@ public:
ChatTextItemHelper *textItem() const;
void setTextItem(ChatTextItemHelper *textItem);
bool inQuote() const;
void setInQuote(bool inQuote);
bool richFormatEnabled() const;
bool styleFormatEnabled() const;
bool bold() const;
@@ -140,6 +148,7 @@ public:
Q_SIGNALS:
void textItemChanged();
void inQuoteChanged();
void richFormatEnabledChanged();
void charFormatChanged();
void styleChanged();
@@ -147,6 +156,7 @@ Q_SIGNALS:
private:
QPointer<ChatTextItemHelper> m_textItem;
bool m_inQuote = false;
void selectLinkText(QTextCursor &cursor) const;
};

View File

@@ -47,6 +47,21 @@ QTextDocument *StyleDelegateHelper::document() const
return quickDocument ? quickDocument->textDocument() : nullptr;
}
bool StyleDelegateHelper::inQuote() const
{
return m_inQuote;
}
void StyleDelegateHelper::setInQuote(bool inQuote)
{
if (inQuote == m_inQuote) {
return;
}
m_inQuote = inQuote;
formatDocument();
Q_EMIT inQuoteChanged();
}
void StyleDelegateHelper::formatDocument()
{
if (!document()) {
@@ -62,7 +77,7 @@ void StyleDelegateHelper::formatDocument()
cursor.select(QTextCursor::Document);
cursor.removeSelectedText();
const auto style = static_cast<RichFormat::Format>(m_textItem->property("style").toInt());
const auto string = RichFormat::styleString(style);
const auto string = RichFormat::styleString(style, m_inQuote);
const auto sizeText = static_cast<RichFormat::Format>(m_textItem->property("sizeText").toBool());
const int headingLevel = style <= 6 && sizeText ? style : 0;
@@ -83,7 +98,7 @@ void StyleDelegateHelper::formatDocument()
chrfmt.setFontItalic(true);
}
cursor.mergeBlockCharFormat(chrfmt);
cursor.setBlockCharFormat(chrfmt);
cursor.insertText(string);
cursor.endEditBlock();
}

View File

@@ -19,19 +19,30 @@ class StyleDelegateHelper : public QObject
*/
Q_PROPERTY(QQuickItem *textItem READ textItem WRITE setTextItem NOTIFY textItemChanged)
/**
* @brief Whether the current block is a Quote block.
*/
Q_PROPERTY(bool inQuote READ inQuote WRITE setInQuote NOTIFY inQuoteChanged)
public:
explicit StyleDelegateHelper(QObject *parent = nullptr);
QQuickItem *textItem() const;
void setTextItem(QQuickItem *textItem);
bool inQuote() const;
void setInQuote(bool inQuote);
Q_SIGNALS:
void textItemChanged();
void inQuoteChanged();
private:
QPointer<QQuickItem> m_textItem;
QTextDocument *document() const;
bool m_inQuote = false;
private Q_SLOTS:
void formatDocument();
};

View File

@@ -9,30 +9,45 @@
#include <KLocalizedString>
QString RichFormat::styleString(Format format)
QString RichFormat::styleString(Format format, bool inQuoteBlock)
{
QString formatString;
switch (format) {
case Paragraph:
return i18nc("As in the default paragraph text style in the chat bar", "Paragraph Style");
formatString = i18nc("As in the default paragraph text style in the chat bar", "Paragraph Style");
break;
case Heading1:
return i18nc("As in heading level 1 text style in the chat bar", "Heading 1");
formatString = i18nc("As in heading level 1 text style in the chat bar", "Heading 1");
break;
case Heading2:
return i18nc("As in heading level 2 text style in the chat bar", "Heading 2");
formatString = i18nc("As in heading level 2 text style in the chat bar", "Heading 2");
break;
case Heading3:
return i18nc("As in heading level 3 text style in the chat bar", "Heading 3");
formatString = i18nc("As in heading level 3 text style in the chat bar", "Heading 3");
break;
case Heading4:
return i18nc("As in heading level 4 text style in the chat bar", "Heading 4");
formatString = i18nc("As in heading level 4 text style in the chat bar", "Heading 4");
break;
case Heading5:
return i18nc("As in heading level 5 text style in the chat bar", "Heading 5");
formatString = i18nc("As in heading level 5 text style in the chat bar", "Heading 5");
break;
case Heading6:
return i18nc("As in heading level 6 text style in the chat bar", "Heading 6");
formatString = i18nc("As in heading level 6 text style in the chat bar", "Heading 6");
break;
case Code:
return i18nc("As in code text style in the chat bar", "Code");
formatString = i18nc("As in code text style in the chat bar", "Code");
break;
case Quote:
return i18nc("As in quote text style in the chat bar", "\"Quote\"");
if (inQuoteBlock) {
formatString = i18nc("As in the default paragraph text style inside a quote block in the chat bar", "Quote Paragraph Style");
break;
}
formatString = i18nc("As in quote text style in the chat bar", "Quote");
break;
default:
return {};
break;
}
return u"%1%2%1"_s.arg(inQuoteBlock && !(format == Paragraph || format == Code) ? u"\""_s : u""_s, formatString);
};
RichFormat::FormatType RichFormat::typeForFormat(Format format)

View File

@@ -67,7 +67,7 @@ public:
*
* @sa Format
*/
static QString styleString(Format format);
static QString styleString(Format format, bool inQuoteBlock = false);
/**
* @brief Return the FormatType for the Format.

View File

@@ -430,7 +430,7 @@ void ChatBarMessageContentModel::insertStyleAtCursor(RichFormat::Format style)
void ChatBarMessageContentModel::insertComponentAtCursor(MessageComponentType::Type type)
{
if (m_components[m_currentFocusComponent.row()].type == type) {
if (type == MessageComponentType::Text && focusedTextItem()) {
if ((type == MessageComponentType::Text || type == MessageComponentType::Quote) && focusedTextItem()) {
focusedTextItem()->mergeFormatOnCursor(RichFormat::Paragraph);
}
return;