Commit 822c6b39 authored by Volker Krause's avatar Volker Krause
Browse files

Remove insertIntoTextEdit() from Signature's public interface

It's not used externally, so we can easily do that.

The motivation behind this is to separate core class (like Signature) and
widget code that pulls in the full rich text editing stack. This will e.g.
help background processes such as the reminder daemon, which use identity
data, but that don't have any editing UI for it themselves.

There is a second piece missing for this still, findImageNames() in
signature.cpp.
parent 04ec5bb6
Pipeline #136001 passed with stages
in 1 minute and 20 seconds
......@@ -11,6 +11,7 @@
#include "signaturetest.h"
#include "qtest.h"
#include "../src/signaturerichtexteditor.cpp"
#include "signature.h"
#include <KActionCollection>
......@@ -118,7 +119,7 @@ void SignatureTester::testTextEditInsertion()
// lines are inserted before the signature
edit.setPlainText(QStringLiteral("Bla Bla"));
sig.insertIntoTextEdit(Signature::Start, Signature::AddSeparator | Signature::AddNewLines, &edit);
SignatureRichTextEditor::insertIntoTextEdit(sig, Signature::Start, Signature::AddSeparator | Signature::AddNewLines, &edit);
QVERIFY(edit.textMode() == KPIMTextEdit::RichTextComposer::Plain);
QCOMPARE(edit.toPlainText(), QStringLiteral("\n\n-- \nHello World\nBla Bla"));
......@@ -126,7 +127,7 @@ void SignatureTester::testTextEditInsertion()
edit.clear();
edit.setPlainText(QStringLiteral("Bla Bla"));
setCursorPos(edit, 4);
sig.insertIntoTextEdit(Signature::End, Signature::AddSeparator | Signature::AddNewLines, &edit);
SignatureRichTextEditor::insertIntoTextEdit(sig, Signature::End, Signature::AddSeparator | Signature::AddNewLines, &edit);
QCOMPARE(edit.toPlainText(), QStringLiteral("Bla Bla\n-- \nHello World"));
QCOMPARE(edit.textCursor().position(), 4);
......@@ -136,7 +137,7 @@ void SignatureTester::testTextEditInsertion()
edit.setPlainText(QStringLiteral("Bla Bla"));
setCursorPos(edit, 4);
edit.document()->setModified(false);
sig.insertIntoTextEdit(Signature::AtCursor, Signature::AddSeparator | Signature::AddNewLines, &edit);
SignatureRichTextEditor::insertIntoTextEdit(sig, Signature::AtCursor, Signature::AddSeparator | Signature::AddNewLines, &edit);
QCOMPARE(edit.toPlainText(), QStringLiteral("-- \nHello World\nBla Bla"));
QCOMPARE(edit.textCursor().position(), 20);
QVERIFY(!edit.document()->isModified());
......@@ -151,7 +152,7 @@ void SignatureTester::testTextEditInsertion()
edit.setPlainText(QStringLiteral("Bla Bla"));
setCursorPos(edit, 4);
edit.document()->setModified(true);
sig.insertIntoTextEdit(Signature::End, Signature::AddNewLines, &edit);
SignatureRichTextEditor::insertIntoTextEdit(sig, Signature::End, Signature::AddNewLines, &edit);
QCOMPARE(edit.toPlainText(), QStringLiteral("Bla Bla\nHello World"));
QCOMPARE(edit.textCursor().position(), 4);
QVERIFY(edit.document()->isModified());
......@@ -162,7 +163,7 @@ void SignatureTester::testTextEditInsertion()
// test that html signatures turn html on and have correct line endings (<br> vs \n)
edit.clear();
edit.setPlainText(QStringLiteral("Bla Bla"));
sig.insertIntoTextEdit(Signature::End, Signature::AddSeparator | Signature::AddNewLines, &edit);
SignatureRichTextEditor::insertIntoTextEdit(sig, Signature::End, Signature::AddSeparator | Signature::AddNewLines, &edit);
QVERIFY(edit.textMode() == KPIMTextEdit::RichTextComposer::Rich);
QCOMPARE(edit.toPlainText(), QStringLiteral("Bla Bla\n-- \nHello\nWorld"));
}
......@@ -177,12 +178,12 @@ void SignatureTester::testBug167961()
// Test that the cursor is still at the start when appending a sig into
// an empty text edit
sig.insertIntoTextEdit(Signature::End, Signature::AddSeparator | Signature::AddNewLines, &edit);
SignatureRichTextEditor::insertIntoTextEdit(sig, Signature::End, Signature::AddSeparator | Signature::AddNewLines, &edit);
QCOMPARE(edit.textCursor().position(), 0);
// When prepending a sig, the cursor should also be at the start, see bug 211634
edit.clear();
sig.insertIntoTextEdit(Signature::Start, Signature::AddSeparator | Signature::AddNewLines, &edit);
SignatureRichTextEditor::insertIntoTextEdit(sig, Signature::Start, Signature::AddSeparator | Signature::AddNewLines, &edit);
QCOMPARE(edit.textCursor().position(), 0);
}
......@@ -250,7 +251,7 @@ void SignatureTester::testImages()
// read the images, and it does not mess up
MySignature sig2;
sig2.readConfig(group1);
sig2.insertIntoTextEdit(KIdentityManagement::Signature::End, Signature::AddSeparator | Signature::AddNewLines, &edit);
SignatureRichTextEditor::insertIntoTextEdit(sig2, Signature::End, Signature::AddSeparator | Signature::AddNewLines, &edit);
QCOMPARE(edit.composerControler()->composerImages()->embeddedImages().count(), 2);
QCOMPARE(sig2.text(), QStringLiteral("Bla<img src=\"folder-new.png\">Bla<img src=\"arrow-up.png\">Bla"));
sig2.writeConfig(group1);
......@@ -263,7 +264,7 @@ void SignatureTester::testImages()
sig2.setText(QStringLiteral("<img src=\"folder-new.png\">"));
sig2.writeConfig(group1);
edit.clear();
sig2.insertIntoTextEdit(Signature::End, Signature::AddSeparator | Signature::AddNewLines, &edit);
SignatureRichTextEditor::insertIntoTextEdit(sig2, Signature::End, Signature::AddSeparator | Signature::AddNewLines, &edit);
QCOMPARE(edit.composerControler()->composerImages()->embeddedImages().size(), 1);
entryList = dir.entryList(QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks);
QCOMPARE(entryList.count(), 1);
......@@ -279,12 +280,12 @@ void SignatureTester::testLinebreaks()
KPIMTextEdit::RichTextComposer edit;
edit.createActions(new KActionCollection(this));
sig.insertIntoTextEdit(Signature::Start, Signature::AddNothing, &edit);
SignatureRichTextEditor::insertIntoTextEdit(sig, Signature::Start, Signature::AddNothing, &edit);
QCOMPARE(edit.toPlainText(), QStringLiteral("Hans Mustermann\nMusterstr. 42"));
edit.clear();
sig.setText(QStringLiteral("<p>Hans Mustermann</p><br>Musterstr. 42"));
sig.insertIntoTextEdit(Signature::Start, Signature::AddSeparator, &edit);
SignatureRichTextEditor::insertIntoTextEdit(sig, Signature::Start, Signature::AddSeparator, &edit);
QEXPECT_FAIL("", "This test is probably bogus, since Qt doesn't seem to produce HTML like this anymore.", Continue);
QCOMPARE(edit.toPlainText(), QStringLiteral("-- \nHans Mustermann\nMusterstr. 42"));
}
......@@ -12,6 +12,8 @@ target_sources(KF5IdentityManagement PRIVATE
identitymanager.cpp
signature.cpp
signatureconfigurator.cpp
signaturerichtexteditor.cpp
signaturerichtexteditor_p.h
utils.cpp
utils.h
identitycombo.h
......
......@@ -37,7 +37,6 @@ public:
void saveImages() const;
Q_REQUIRED_RESULT QString textFromFile(bool *ok) const;
Q_REQUIRED_RESULT QString textFromCommand(bool *ok) const;
void insertSignatureText(Signature::Placement placement, Signature::AddedText addedText, KPIMTextEdit::RichTextComposer *textEdit, bool forceDisplay) const;
/// List of images that belong to this signature. Either added by addImage() or
/// by readConfig().
......@@ -53,97 +52,6 @@ public:
Signature *const q;
};
static bool isCursorAtEndOfLine(const QTextCursor &cursor)
{
QTextCursor testCursor = cursor;
testCursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
return !testCursor.hasSelection();
}
static void
insertSignatureHelper(const QString &signature, KPIMTextEdit::RichTextComposer *textEdit, Signature::Placement placement, bool isHtml, bool addNewlines)
{
if (!signature.isEmpty()) {
// Save the modified state of the document, as inserting a signature
// shouldn't change this. Restore it at the end of this function.
bool isModified = textEdit->document()->isModified();
// Move to the desired position, where the signature should be inserted
QTextCursor cursor = textEdit->textCursor();
QTextCursor oldCursor = cursor;
cursor.beginEditBlock();
if (placement == Signature::End) {
cursor.movePosition(QTextCursor::End);
} else if (placement == Signature::Start) {
cursor.movePosition(QTextCursor::Start);
} else if (placement == Signature::AtCursor) {
cursor.movePosition(QTextCursor::StartOfLine);
}
textEdit->setTextCursor(cursor);
QString lineSep;
if (addNewlines) {
if (isHtml) {
lineSep = QStringLiteral("<br>");
} else {
lineSep = QLatin1Char('\n');
}
}
// Insert the signature and newlines depending on where it was inserted.
int newCursorPos = -1;
QString headSep;
QString tailSep;
if (placement == Signature::End) {
// There is one special case when re-setting the old cursor: The cursor
// was at the end. In this case, QTextEdit has no way to know
// if the signature was added before or after the cursor, and just
// decides that it was added before (and the cursor moves to the end,
// but it should not when appending a signature). See bug 167961
if (oldCursor.position() == textEdit->toPlainText().length()) {
newCursorPos = oldCursor.position();
}
headSep = lineSep;
} else if (placement == Signature::Start) {
// When prepending signatures, add a couple of new lines before
// the signature, and move the cursor to the beginning of the QTextEdit.
// People tends to insert new text there.
newCursorPos = 0;
headSep = lineSep + lineSep;
if (!isCursorAtEndOfLine(cursor)) {
tailSep = lineSep;
}
} else if (placement == Signature::AtCursor) {
if (!isCursorAtEndOfLine(cursor)) {
tailSep = lineSep;
}
}
const QString full_signature = headSep + signature + tailSep;
if (isHtml) {
textEdit->insertHtml(full_signature);
} else {
textEdit->insertPlainText(full_signature);
}
cursor.endEditBlock();
if (newCursorPos != -1) {
oldCursor.setPosition(newCursorPos);
}
textEdit->setTextCursor(oldCursor);
textEdit->ensureCursorVisible();
textEdit->document()->setModified(isModified);
if (isHtml) {
textEdit->activateRichText();
}
}
}
// Returns the names of all images in the HTML code
static QStringList findImageNames(const QString &htmlCode)
{
......@@ -276,36 +184,6 @@ QString SignaturePrivate::textFromCommand(bool *ok) const
return QString::fromLocal8Bit(output.data(), output.size());
}
void SignaturePrivate::insertSignatureText(Signature::Placement placement,
Signature::AddedText addedText,
KPIMTextEdit::RichTextComposer *textEdit,
bool forceDisplay) const
{
if (!forceDisplay) {
if (!enabled) {
return;
}
}
QString signature;
if (addedText & Signature::AddSeparator) {
signature = q->withSeparator();
} else {
signature = q->rawText();
}
insertSignatureHelper(signature,
textEdit,
placement,
(inlinedHtml && type == KIdentityManagement::Signature::Inlined),
(addedText & Signature::AddNewLines));
// We added the text of the signature above, now it is time to add the images as well.
if (inlinedHtml) {
for (const Signature::EmbeddedImagePtr &image : std::as_const(embeddedImages)) {
textEdit->composerControler()->composerImages()->loadImage(image->image, image->name, image->name);
}
}
}
QDataStream &operator<<(QDataStream &stream, const KIdentityManagement::Signature::EmbeddedImagePtr &img)
{
return stream << img->image << img->name;
......@@ -497,11 +375,6 @@ void Signature::writeConfig(KConfigGroup &config) const
d->saveImages();
}
void Signature::insertIntoTextEdit(Placement placement, AddedText addedText, KPIMTextEdit::RichTextComposer *textEdit, bool forceDisplay) const
{
d->insertSignatureText(placement, addedText, textEdit, forceDisplay);
}
QVector<Signature::EmbeddedImagePtr> Signature::embeddedImages() const
{
return d->embeddedImages;
......
......@@ -24,11 +24,6 @@ class Identity;
}
class KConfigGroup;
namespace KPIMTextEdit
{
class RichTextComposer;
}
namespace KIdentityManagement
{
class SignaturePrivate;
......@@ -205,28 +200,6 @@ public:
/// Describes which additional parts should be added to the signature
using AddedText = QFlags<AddedTextFlag>;
/** Inserts this signature into the given text edit.
* If the signature is inserted at the beginning, a couple of new
* lines will be inserted before it, and the cursor is moved to
* the beginning. Otherwise, the cursor position is preserved.
* For undo/redo, this is treated as one operation.
*
* Rich text mode of the text edit will be enabled if the signature is in
* inlined HTML format.
*
* If this signature uses images, they will be added automatically.
*
* @param placement defines where in the text edit the signature should be
* inserted.
* @param addedText defines which other texts should be added to the signature
* @param textEdit the signature will be inserted into this text edit.
*
* @since 4.9
*/
// TODO: KDE5: BIC: Reorder parameters, the order here is a workaround for ambiguous parameters
// with the deprecated method
void insertIntoTextEdit(Placement placement, AddedText addedText, KPIMTextEdit::RichTextComposer *textEdit, bool forceDisplay = false) const;
Q_REQUIRED_RESULT QVector<Signature::EmbeddedImagePtr> embeddedImages() const;
void setEmbeddedImages(const QVector<EmbeddedImagePtr> &embedded);
......
......@@ -8,6 +8,7 @@
#include "signatureconfigurator.h"
#include "identity.h"
#include "signaturerichtexteditor_p.h"
#include "kidentitymanagement_debug.h"
#include <KActionCollection>
......@@ -395,7 +396,7 @@ void SignatureConfigurator::setSignature(const Signature &sig)
// Let insertIntoTextEdit() handle setting the text, as that function also adds the images.
d->mTextEdit->clear();
sig.insertIntoTextEdit(KIdentityManagement::Signature::Start, KIdentityManagement::Signature::AddNothing, d->mTextEdit, true);
SignatureRichTextEditor::insertIntoTextEdit(sig, Signature::Start, Signature::AddNothing, d->mTextEdit, true);
if (sig.type() == Signature::FromFile) {
setFileURL(sig.path());
} else {
......
/*
SPDX-FileCopyrightText: 2002-2004 Marc Mutz <mutz@kde.org>
SPDX-FileCopyrightText: 2007 Tom Albers <tomalbers@kde.nl>
SPDX-FileCopyrightText: 2009 Thomas McGuire <mcguire@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "signaturerichtexteditor_p.h"
#include <KPIMTextEdit/RichTextComposer>
#include <KPIMTextEdit/RichTextComposerControler>
#include <KPIMTextEdit/RichTextComposerImages>
using namespace KIdentityManagement;
static bool isCursorAtEndOfLine(const QTextCursor &cursor)
{
QTextCursor testCursor = cursor;
testCursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
return !testCursor.hasSelection();
}
static void
insertSignatureHelper(const QString &signature, KPIMTextEdit::RichTextComposer *textEdit, Signature::Placement placement, bool isHtml, bool addNewlines)
{
if (!signature.isEmpty()) {
// Save the modified state of the document, as inserting a signature
// shouldn't change this. Restore it at the end of this function.
bool isModified = textEdit->document()->isModified();
// Move to the desired position, where the signature should be inserted
QTextCursor cursor = textEdit->textCursor();
QTextCursor oldCursor = cursor;
cursor.beginEditBlock();
if (placement == Signature::End) {
cursor.movePosition(QTextCursor::End);
} else if (placement == Signature::Start) {
cursor.movePosition(QTextCursor::Start);
} else if (placement == Signature::AtCursor) {
cursor.movePosition(QTextCursor::StartOfLine);
}
textEdit->setTextCursor(cursor);
QString lineSep;
if (addNewlines) {
if (isHtml) {
lineSep = QStringLiteral("<br>");
} else {
lineSep = QLatin1Char('\n');
}
}
// Insert the signature and newlines depending on where it was inserted.
int newCursorPos = -1;
QString headSep;
QString tailSep;
if (placement == Signature::End) {
// There is one special case when re-setting the old cursor: The cursor
// was at the end. In this case, QTextEdit has no way to know
// if the signature was added before or after the cursor, and just
// decides that it was added before (and the cursor moves to the end,
// but it should not when appending a signature). See bug 167961
if (oldCursor.position() == textEdit->toPlainText().length()) {
newCursorPos = oldCursor.position();
}
headSep = lineSep;
} else if (placement == Signature::Start) {
// When prepending signatures, add a couple of new lines before
// the signature, and move the cursor to the beginning of the QTextEdit.
// People tends to insert new text there.
newCursorPos = 0;
headSep = lineSep + lineSep;
if (!isCursorAtEndOfLine(cursor)) {
tailSep = lineSep;
}
} else if (placement == Signature::AtCursor) {
if (!isCursorAtEndOfLine(cursor)) {
tailSep = lineSep;
}
}
const QString full_signature = headSep + signature + tailSep;
if (isHtml) {
textEdit->insertHtml(full_signature);
} else {
textEdit->insertPlainText(full_signature);
}
cursor.endEditBlock();
if (newCursorPos != -1) {
oldCursor.setPosition(newCursorPos);
}
textEdit->setTextCursor(oldCursor);
textEdit->ensureCursorVisible();
textEdit->document()->setModified(isModified);
if (isHtml) {
textEdit->activateRichText();
}
}
}
void SignatureRichTextEditor::insertIntoTextEdit(const Signature &sig,
Signature::Placement placement,
Signature::AddedText addedText,
KPIMTextEdit::RichTextComposer *textEdit,
bool forceDisplay)
{
if (!forceDisplay) {
if (!sig.isEnabledSignature()) {
return;
}
}
QString signature;
if (addedText & Signature::AddSeparator) {
signature = sig.withSeparator();
} else {
signature = sig.rawText();
}
insertSignatureHelper(signature,
textEdit,
placement,
(sig.isInlinedHtml() && sig.type() == KIdentityManagement::Signature::Inlined),
(addedText & Signature::AddNewLines));
// We added the text of the signature above, now it is time to add the images as well.
if (sig.isInlinedHtml()) {
const auto embeddedImgs = sig.embeddedImages();
for (const Signature::EmbeddedImagePtr &image : embeddedImgs) {
textEdit->composerControler()->composerImages()->loadImage(image->image, image->name, image->name);
}
}
}
/*
SPDX-FileCopyrightText: 2002-2004 Marc Mutz <mutz@kde.org>
SPDX-FileCopyrightText: 2007 Tom Albers <tomalbers@kde.nl>
SPDX-FileCopyrightText: 2009 Thomas McGuire <mcguire@kde.org>
Author: Stefan Taferner <taferner@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#pragma once
#include <KIdentityManagement/Signature>
namespace KPIMTextEdit
{
class RichTextComposer;
}
namespace KIdentityManagement
{
/** Helper methods for rich text signature editing .*/
namespace SignatureRichTextEditor
{
/** Inserts this signature into the given text edit.
* If the signature is inserted at the beginning, a couple of new
* lines will be inserted before it, and the cursor is moved to
* the beginning. Otherwise, the cursor position is preserved.
* For undo/redo, this is treated as one operation.
*
* Rich text mode of the text edit will be enabled if the signature is in
* inlined HTML format.
*
* If this signature uses images, they will be added automatically.
*
* @param placement defines where in the text edit the signature should be
* inserted.
* @param addedText defines which other texts should be added to the signature
* @param textEdit the signature will be inserted into this text edit.
*
* @since 4.9
*/
void insertIntoTextEdit(const Signature &sig,
Signature::Placement placement,
Signature::AddedText addedText,
KPIMTextEdit::RichTextComposer *textEdit,
bool forceDisplay = false);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment