Warning, file /pim/kidentitymanagement/src/widgets/signaturerichtexteditor.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     SPDX-FileCopyrightText: 2002-2004 Marc Mutz <mutz@kde.org>
0003     SPDX-FileCopyrightText: 2007 Tom Albers <tomalbers@kde.nl>
0004     SPDX-FileCopyrightText: 2009 Thomas McGuire <mcguire@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "signaturerichtexteditor_p.h"
0010 
0011 #include <KPIMTextEdit/RichTextComposer>
0012 #include <KPIMTextEdit/RichTextComposerControler>
0013 #include <KPIMTextEdit/RichTextComposerImages>
0014 
0015 using namespace KIdentityManagementWidgets;
0016 
0017 static bool isCursorAtEndOfLine(const QTextCursor &cursor)
0018 {
0019     QTextCursor testCursor = cursor;
0020     testCursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
0021     return !testCursor.hasSelection();
0022 }
0023 
0024 static void insertSignatureHelper(const QString &signature,
0025                                   KPIMTextEdit::RichTextComposer *textEdit,
0026                                   KIdentityManagementCore::Signature::Placement placement,
0027                                   bool isHtml,
0028                                   bool addNewlines)
0029 {
0030     if (!signature.isEmpty()) {
0031         // Save the modified state of the document, as inserting a signature
0032         // shouldn't change this. Restore it at the end of this function.
0033         bool isModified = textEdit->document()->isModified();
0034 
0035         // Move to the desired position, where the signature should be inserted
0036         QTextCursor cursor = textEdit->textCursor();
0037         QTextCursor oldCursor = cursor;
0038         cursor.beginEditBlock();
0039 
0040         if (placement == KIdentityManagementCore::Signature::End) {
0041             cursor.movePosition(QTextCursor::End);
0042         } else if (placement == KIdentityManagementCore::Signature::Start) {
0043             cursor.movePosition(QTextCursor::Start);
0044         } else if (placement == KIdentityManagementCore::Signature::AtCursor) {
0045             cursor.movePosition(QTextCursor::StartOfLine);
0046         }
0047         textEdit->setTextCursor(cursor);
0048 
0049         QString lineSep;
0050         if (addNewlines) {
0051             if (isHtml) {
0052                 lineSep = QStringLiteral("<br>");
0053             } else {
0054                 lineSep = QLatin1Char('\n');
0055             }
0056         }
0057 
0058         // Insert the signature and newlines depending on where it was inserted.
0059         int newCursorPos = -1;
0060         QString headSep;
0061         QString tailSep;
0062 
0063         if (placement == KIdentityManagementCore::Signature::End) {
0064             // There is one special case when re-setting the old cursor: The cursor
0065             // was at the end. In this case, QTextEdit has no way to know
0066             // if the signature was added before or after the cursor, and just
0067             // decides that it was added before (and the cursor moves to the end,
0068             // but it should not when appending a signature). See bug 167961
0069             if (oldCursor.position() == textEdit->toPlainText().length()) {
0070                 newCursorPos = oldCursor.position();
0071             }
0072             headSep = lineSep;
0073         } else if (placement == KIdentityManagementCore::Signature::Start) {
0074             // When prepending signatures, add a couple of new lines before
0075             // the signature, and move the cursor to the beginning of the QTextEdit.
0076             // People tends to insert new text there.
0077             newCursorPos = 0;
0078             headSep = lineSep + lineSep;
0079             if (!isCursorAtEndOfLine(cursor)) {
0080                 tailSep = lineSep;
0081             }
0082         } else if (placement == KIdentityManagementCore::Signature::AtCursor) {
0083             if (!isCursorAtEndOfLine(cursor)) {
0084                 tailSep = lineSep;
0085             }
0086         }
0087 
0088         const QString full_signature = headSep + signature + tailSep;
0089         if (isHtml) {
0090             textEdit->insertHtml(full_signature);
0091         } else {
0092             textEdit->insertPlainText(full_signature);
0093         }
0094 
0095         cursor.endEditBlock();
0096         if (newCursorPos != -1) {
0097             oldCursor.setPosition(newCursorPos);
0098         }
0099 
0100         textEdit->setTextCursor(oldCursor);
0101         textEdit->ensureCursorVisible();
0102 
0103         textEdit->document()->setModified(isModified);
0104 
0105         if (isHtml) {
0106             textEdit->activateRichText();
0107         }
0108     }
0109 }
0110 
0111 void SignatureRichTextEditor::insertIntoTextEdit(const KIdentityManagementCore::Signature &sig,
0112                                                  KIdentityManagementCore::Signature::Placement placement,
0113                                                  KIdentityManagementCore::Signature::AddedText addedText,
0114                                                  KPIMTextEdit::RichTextComposer *textEdit,
0115                                                  bool forceDisplay)
0116 {
0117     if (!forceDisplay) {
0118         if (!sig.isEnabledSignature()) {
0119             return;
0120         }
0121     }
0122     QString signature;
0123     if (addedText & KIdentityManagementCore::Signature::AddSeparator) {
0124         signature = sig.withSeparator();
0125     } else {
0126         signature = sig.rawText();
0127     }
0128     insertSignatureHelper(signature,
0129                           textEdit,
0130                           placement,
0131                           (sig.isInlinedHtml() && sig.type() == KIdentityManagementCore::Signature::Inlined),
0132                           (addedText & KIdentityManagementCore::Signature::AddNewLines));
0133 
0134     // We added the text of the signature above, now it is time to add the images as well.
0135     if (sig.isInlinedHtml()) {
0136         const auto embeddedImgs = sig.embeddedImages();
0137         for (const KIdentityManagementCore::Signature::EmbeddedImagePtr &image : embeddedImgs) {
0138             textEdit->composerControler()->composerImages()->loadImage(image->image, image->name, image->name);
0139         }
0140     }
0141 }