Skip to content

Commit

Permalink
Chatedit: make default paste mode configurable
Browse files Browse the repository at this point in the history
Many people like pasting plain text as there is less trouble with
it and does the job. Even Element pastes plain text by default
despite being a rich client. This is why this patch switches to
plain text pasting by default while makes it configurable.

Other version can be pasted by `Ctrl+Shift+V`.

Cc quotient-im#849
  • Loading branch information
rpallai committed Feb 20, 2023
1 parent 0315b39 commit be3909d
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 12 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ Settings not exposed in UI:
is `false` since the current support of Markdown by Qt is buggy, and the whole
functionality in Quaternion is, again, experimental. If you have it enabled
(or use `/md` command) feel free to submit bug reports at the usual place.
- `paste_plaintext_by_default` - set this to false (or 0) if you want to paste
formatted text by default.

Since version 0.0.95, all Quaternion binaries at GitHub Releases are compiled
with Qt Keychain support. It means that Quaternion will try to store your access
Expand Down
64 changes: 52 additions & 12 deletions client/chatedit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,19 @@
#include <util.h>

static const QKeySequence ResetFormatShortcut("Ctrl+M");
static const QKeySequence AlternatePasteShortcut("Ctrl+Shift+V");

ChatEdit::ChatEdit(ChatRoomWidget* c)
: KChatEdit(c), chatRoomWidget(c), matchesListPosition(0)
, m_pastePlaintext(pastePlaintextByDefault())
{
auto* sh = new QShortcut(this);
sh->setKey(ResetFormatShortcut);
connect(sh, &QShortcut::activated, this, &KChatEdit::resetCurrentFormat);

sh = new QShortcut(this);
sh->setKey(AlternatePasteShortcut);
connect(sh, &QShortcut::activated, this, &ChatEdit::alternatePaste);
}

void ChatEdit::keyPressEvent(QKeyEvent* event)
Expand All @@ -70,6 +76,22 @@ void ChatEdit::contextMenuEvent(QContextMenuEvent *event)
connect(action, &QAction::triggered, this, &KChatEdit::resetCurrentFormat);
menu->addAction(action);

action = new QAction(QIcon::fromTheme("edit-paste"),
tr(pastePlaintextByDefault() ? "Paste as rich text"
: "Paste as plain text"),
this);
action->setShortcut(AlternatePasteShortcut);
connect(action, &QAction::triggered, this, &ChatEdit::alternatePaste);
bool insert = false;
for (QAction* a: menu->actions()) {
if (insert) {
menu->insertAction(a, action);
break;
}
if (a->objectName() == QStringLiteral("edit-paste"))
insert = true;
}

menu->setAttribute(Qt::WA_DeleteOnClose);
menu->popup(event->globalPos());
}
Expand All @@ -85,6 +107,13 @@ bool ChatEdit::canInsertFromMimeData(const QMimeData *source) const
return source->hasImage() || KChatEdit::canInsertFromMimeData(source);
}

void ChatEdit::alternatePaste()
{
m_pastePlaintext = !pastePlaintextByDefault();
paste();
m_pastePlaintext = pastePlaintextByDefault();
}

void ChatEdit::insertFromMimeData(const QMimeData *source)
{
if (!source) {
Expand All @@ -93,19 +122,25 @@ void ChatEdit::insertFromMimeData(const QMimeData *source)
}

if (source->hasHtml()) {
// Before insertion, remove formatting unsupported in Matrix
const auto [cleanHtml, errorPos, errorString] =
HtmlFilter::fromLocalHtml(source->html());
if (errorPos != -1) {
qWarning() << "HTML insertion failed at pos" << errorPos
<< "with error" << errorString;
// FIXME: Come on... It should be app->showStatusMessage() or smth
emit chatRoomWidget->timelineWidget()->showStatusMessage(
tr("Could not insert HTML - it's either invalid or unsupported"),
5000);
return;
if (m_pastePlaintext) {
QTextDocument document;
document.setHtml(source->html());
insertPlainText(document.toPlainText());
} else {
// Before insertion, remove formatting unsupported in Matrix
const auto [cleanHtml, errorPos, errorString] =
HtmlFilter::fromLocalHtml(source->html());
if (errorPos != -1) {
qWarning() << "HTML insertion failed at pos" << errorPos
<< "with error" << errorString;
// FIXME: Come on... It should be app->showStatusMessage() or smth
emit chatRoomWidget->timelineWidget()->showStatusMessage(
tr("Could not insert HTML - it's either invalid or unsupported"),
5000);
return;
}
insertHtml(cleanHtml);
}
insertHtml(cleanHtml);
ensureCursorVisible();
} else if (source->hasImage())
emit insertImageRequested(source->imageData().value<QImage>());
Expand Down Expand Up @@ -272,3 +307,8 @@ void ChatEdit::insertMention(QString author, QUrl url)
pickingMentions = true;
cancelCompletion();
}

bool ChatEdit::pastePlaintextByDefault()
{
return Quotient::Settings().get("UI/paste_plaintext_by_default", true);
}
3 changes: 3 additions & 0 deletions client/chatedit.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class ChatEdit : public KChatEdit

public slots:
void switchContext(QObject* contextKey) override;
void alternatePaste();

signals:
void proposedCompletion(const QStringList& allCompletions, int curIndex);
Expand All @@ -61,6 +62,7 @@ class ChatEdit : public KChatEdit
int matchesListPosition;

bool pickingMentions = false;
bool m_pastePlaintext;

/// \brief Initialise a new completion
///
Expand All @@ -71,6 +73,7 @@ class ChatEdit : public KChatEdit
QUrl mentionUrl, bool select);
void keyPressEvent(QKeyEvent* event) override;
void contextMenuEvent(QContextMenuEvent* event) override;
bool pastePlaintextByDefault();
};


0 comments on commit be3909d

Please sign in to comment.