diff --git a/autotests/identitytest.cpp b/autotests/identitytest.cpp index f3c7c5f7..53eb2432 100644 --- a/autotests/identitytest.cpp +++ b/autotests/identitytest.cpp @@ -1,242 +1,242 @@ /* Copyright (c) 2008 Thomas McGuire This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "qtest.h" #include "identitytest.h" #include "identitymanager.h" #include "identity.h" #include #include #include #include #include using namespace KIdentityManagement; QTEST_GUILESS_MAIN(IdentityTester) void IdentityTester::initTestCase() { QStandardPaths::setTestModeEnabled(true); } bool IdentityTester::compareIdentities(const Identity &actual, const Identity &expected) { bool ok = false; [&]() { QCOMPARE(actual.uoid(), expected.uoid()); // Don't compare isDefault - only one copy can be default, so this property // is not copied! It does not affect result of operator==() either. //QCOMPARE(actual.isDefault(), expected.isDefault()); QCOMPARE(actual.identityName(), expected.identityName()); QCOMPARE(actual.fullName(), expected.fullName()); QCOMPARE(actual.organization(), expected.organization()); QCOMPARE(actual.pgpEncryptionKey(), expected.pgpEncryptionKey()); QCOMPARE(actual.pgpSigningKey(), expected.pgpSigningKey()); QCOMPARE(actual.smimeEncryptionKey(), expected.smimeEncryptionKey()); QCOMPARE(actual.smimeSigningKey(), expected.smimeSigningKey()); QCOMPARE(actual.preferredCryptoMessageFormat(), expected.preferredCryptoMessageFormat()); QCOMPARE(actual.emailAliases(), expected.emailAliases()); QCOMPARE(actual.primaryEmailAddress(), expected.primaryEmailAddress()); QCOMPARE(actual.vCardFile(), expected.vCardFile()); QCOMPARE(actual.replyToAddr(), expected.replyToAddr()); QCOMPARE(actual.bcc(), expected.bcc()); QCOMPARE(actual.cc(), expected.cc()); QCOMPARE(actual.attachVcard(), expected.attachVcard()); QCOMPARE(actual.autocorrectionLanguage(), expected.autocorrectionLanguage()); QCOMPARE(actual.disabledFcc(), expected.disabledFcc()); QCOMPARE(actual.pgpAutoSign(), expected.pgpAutoSign()); QCOMPARE(actual.pgpAutoEncrypt(), expected.pgpAutoEncrypt()); QCOMPARE(actual.defaultDomainName(), expected.defaultDomainName()); QCOMPARE(actual.signatureText(), expected.signatureText()); QCOMPARE(const_cast(actual).signature(), const_cast(expected).signature()); QCOMPARE(actual.transport(), expected.transport()); QCOMPARE(actual.fcc(), expected.fcc()); QCOMPARE(actual.drafts(), expected.drafts()); QCOMPARE(actual.templates(), expected.templates()); QCOMPARE(actual.dictionary(), expected.dictionary()); QCOMPARE(actual.isXFaceEnabled(), expected.isXFaceEnabled()); QCOMPARE(actual.xface(), expected.xface()); ok = true; } (); return ok; } void IdentityTester::test_Identity() { Identity identity; identity.setUoid(42); QCOMPARE(identity.uoid(), 42u); identity.setIsDefault(true); QCOMPARE(identity.isDefault(), true); identity.setIdentityName(QStringLiteral("01234")); QCOMPARE(identity.identityName(), QStringLiteral("01234")); identity.setFullName(QStringLiteral("Daniel Vrátil")); QCOMPARE(identity.fullName(), QStringLiteral("Daniel Vrátil")); identity.setOrganization(QStringLiteral("KDE")); QCOMPARE(identity.organization(), QStringLiteral("KDE")); identity.setPGPEncryptionKey("0x0123456789ABCDEF"); QCOMPARE(identity.pgpEncryptionKey(), QByteArray("0x0123456789ABCDEF")); identity.setPGPSigningKey("0xFEDCBA9876543210"); QCOMPARE(identity.pgpSigningKey(), QByteArray("0xFEDCBA9876543210")); identity.setSMIMEEncryptionKey("0xABCDEF0123456789"); QCOMPARE(identity.smimeEncryptionKey(), QByteArray("0xABCDEF0123456789")); identity.setSMIMESigningKey("0xFEDCBA9876543210"); QCOMPARE(identity.smimeSigningKey(), QByteArray("0xFEDCBA9876543210")); identity.setPreferredCryptoMessageFormat(QStringLiteral("PGP")); QCOMPARE(identity.preferredCryptoMessageFormat(), QStringLiteral("PGP")); identity.setPrimaryEmailAddress(QStringLiteral("dvratil@kde.org")); const QStringList aliases = { QStringLiteral("dvratil1@kde.org"), QStringLiteral("example@example.org") }; identity.setEmailAliases(aliases); QCOMPARE(identity.emailAliases(), aliases); QVERIFY(identity.matchesEmailAddress(QStringLiteral("dvratil@kde.org"))); QVERIFY(identity.matchesEmailAddress(aliases[0])); QVERIFY(identity.matchesEmailAddress(aliases[1])); QCOMPARE(identity.primaryEmailAddress(), QStringLiteral("dvratil@kde.org")); const auto vcardFile = QStringLiteral("BEGIN:VCARD\n" "VERSION:2.1\n" "N:Vrátil;Daniel;;\n" "END:VCARD"); identity.setVCardFile(vcardFile); QCOMPARE(identity.vCardFile(), vcardFile); identity.setReplyToAddr(QStringLiteral("dvratil+reply@kde.org")); QCOMPARE(identity.replyToAddr(), QStringLiteral("dvratil+reply@kde.org")); identity.setBcc(QStringLiteral("dvratil+bcc@kde.org")); QCOMPARE(identity.bcc(), QStringLiteral("dvratil+bcc@kde.org")); identity.setCc(QStringLiteral("dvratil+cc@kde.org")); QCOMPARE(identity.cc(), QStringLiteral("dvratil+cc@kde.org")); identity.setAttachVcard(true); QCOMPARE(identity.attachVcard(), true); identity.setAutocorrectionLanguage(QStringLiteral("cs_CZ")); QCOMPARE(identity.autocorrectionLanguage(), QStringLiteral("cs_CZ")); identity.setDisabledFcc(true); QCOMPARE(identity.disabledFcc(), true); identity.setPgpAutoSign(true); QCOMPARE(identity.pgpAutoSign(), true); identity.setPgpAutoEncrypt(true); QCOMPARE(identity.pgpAutoEncrypt(), true); identity.setDefaultDomainName(QStringLiteral("kde.org")); QCOMPARE(identity.defaultDomainName(), QStringLiteral("kde.org")); Signature sig; sig.setEnabledSignature(true); sig.setText(QStringLiteral("Regards,\nDaniel")); identity.setSignature(sig); QCOMPARE(identity.signature(), sig); identity.setTransport(QStringLiteral("smtp")); QCOMPARE(identity.transport(), QStringLiteral("smtp")); identity.setFcc(QStringLiteral("123")); // must be an Akonadi::Collection::Id QCOMPARE(identity.fcc(), QStringLiteral("123")); identity.setDrafts(QStringLiteral("124")); QCOMPARE(identity.drafts(), QStringLiteral("124")); identity.setTemplates(QStringLiteral("125")); QCOMPARE(identity.templates(), QStringLiteral("125")); identity.setDictionary(QStringLiteral("Čeština")); QCOMPARE(identity.dictionary(), QStringLiteral("Čeština")); identity.setXFaceEnabled(true); QCOMPARE(identity.isXFaceEnabled(), true); identity.setXFace(QStringLiteral(":-P")); QCOMPARE(identity.xface(), QStringLiteral(":-P")); // Test copy { const Identity copy = identity; QCOMPARE(copy, identity); // Test that the operator==() actually works QVERIFY(compareIdentities(copy, identity)); identity.setXFace(QStringLiteral(":-(")); QVERIFY(!(copy == identity)); } // Test serialization { QByteArray ba; QDataStream inStream(&ba, QIODevice::WriteOnly); inStream << identity; Identity copy; QDataStream outStream(&ba, QIODevice::ReadOnly); outStream >> copy; // We already verified that operator==() works, so this should be enough QVERIFY(compareIdentities(copy, identity)); } } void IdentityTester::test_NullIdentity() { IdentityManager manager; QVERIFY(manager.identityForAddress(QStringLiteral("thisaddressforsuredoesnotexist@kde.org")).isNull()); } void IdentityTester::test_Aliases() { IdentityManager manager; - // It is picking up identities from older tests somethimes, so cleanup + // It is picking up identities from older tests sometimes, so cleanup while (manager.identities().size() > 1) { QVERIFY(manager.removeIdentity(manager.identities().at(0))); manager.commit(); } Identity &i1 = manager.newFromScratch(QStringLiteral("Test1")); i1.setPrimaryEmailAddress(QStringLiteral("firstname.lastname@example.com")); i1.setEmailAliases(QStringList() << QStringLiteral("firstname@example.com") << QStringLiteral("lastname@example.com")); QVERIFY(i1.matchesEmailAddress(QStringLiteral("\"Lastname, Firstname\" "))); QVERIFY(i1.matchesEmailAddress(QStringLiteral("\"Lastname, Firstname\" "))); QCOMPARE(i1.emailAliases().size(), 2); KConfig testConfig(QStringLiteral("test")); KConfigGroup testGroup(&testConfig, "testGroup"); i1.writeConfig(testGroup); i1.readConfig(testGroup); QCOMPARE(i1.emailAliases().size(), 2); manager.commit(); Identity &i2 = manager.newFromScratch(QStringLiteral("Test2")); i2.setPrimaryEmailAddress(QStringLiteral("test@test.de")); QVERIFY(i2.emailAliases().isEmpty()); manager.commit(); // Remove the first identity, which we couldn't remove above QVERIFY(manager.removeIdentity(manager.identities().at(0))); manager.commit(); QCOMPARE(manager.allEmails().size(), 4); QCOMPARE(manager.identityForAddress(QStringLiteral("firstname@example.com")).identityName().toLatin1().data(), "Test1"); } void IdentityTester::test_toMimeData() { Identity identity(QStringLiteral("Test1")); identity.setFullName(QStringLiteral("name")); QMimeData mimeData; identity.populateMimeData(&mimeData); Identity identity2 = Identity::fromMimeData(&mimeData); QVERIFY(compareIdentities(identity, identity2)); QCOMPARE(identity, identity2); QCOMPARE(identity.fullName(), identity2.fullName()); } diff --git a/autotests/signaturetest.cpp b/autotests/signaturetest.cpp index d9c8444c..be13c3e8 100644 --- a/autotests/signaturetest.cpp +++ b/autotests/signaturetest.cpp @@ -1,305 +1,305 @@ /* Copyright (C) 2016-2018 Laurent Montel Copyright (c) 2008 Thomas McGuire This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #undef QT_USE_FAST_CONCATENATION #undef QT_USE_FAST_OPERATOR_PLUS #include "qtest.h" #include "signaturetest.h" #include "signature.h" #include #include #include #include #include #include #include #include #include using namespace KIdentityManagement; using namespace KPIMTextEdit; QTEST_MAIN(SignatureTester) void SignatureTester::testEqualSignatures() { Signature sig1; sig1.setText(QStringLiteral("Hello World")); sig1.setEnabledSignature(true); Signature sig2(sig1); QVERIFY(sig1 == sig2); QCOMPARE(sig2.text(), QStringLiteral("Hello World")); QCOMPARE(sig2.type(), Signature::Inlined); QCOMPARE(sig2.rawText(), QStringLiteral("Hello World")); QVERIFY(!sig2.isInlinedHtml()); QCOMPARE(sig2.withSeparator(), QStringLiteral("-- \nHello World")); QVERIFY(sig2.isEnabledSignature()); Signature sig3 = sig1; QVERIFY(sig1 == sig3); QCOMPARE(sig3.text(), QStringLiteral("Hello World")); QCOMPARE(sig3.type(), Signature::Inlined); QCOMPARE(sig3.rawText(), QStringLiteral("Hello World")); QVERIFY(!sig3.isInlinedHtml()); QCOMPARE(sig3.withSeparator(), QStringLiteral("-- \nHello World")); QVERIFY(sig3.isEnabledSignature()); } void SignatureTester::testSignatures() { Signature sig1; sig1.setText(QStringLiteral("Hello World")); QCOMPARE(sig1.text(), QStringLiteral("Hello World")); QCOMPARE(sig1.type(), Signature::Inlined); QCOMPARE(sig1.rawText(), QStringLiteral("Hello World")); QVERIFY(!sig1.isInlinedHtml()); QCOMPARE(sig1.withSeparator(), QStringLiteral("-- \nHello World")); QVERIFY(!sig1.isEnabledSignature()); Signature sig2; sig2.setText(QStringLiteral("Hello World")); sig2.setInlinedHtml(true); QVERIFY(sig2.isInlinedHtml()); QCOMPARE(sig2.type(), Signature::Inlined); QCOMPARE(sig2.rawText(), QStringLiteral("Hello World")); QCOMPARE(sig2.withSeparator(), QStringLiteral("--
Hello World")); QVERIFY(!sig2.isEnabledSignature()); // Read this very file in, we use it for the tests QFile thisFile(QStringLiteral(__FILE__)); thisFile.open(QIODevice::ReadOnly); QString fileContent = QString::fromUtf8(thisFile.readAll()); Signature sig3; sig3.setPath(QStringLiteral("cat ") + KShell::quoteArg(QStringLiteral(__FILE__)), true); QCOMPARE(sig3.rawText(), fileContent); QVERIFY(!sig3.isInlinedHtml()); QVERIFY(sig3.text().isEmpty()); QCOMPARE(sig3.type(), Signature::FromCommand); QCOMPARE(sig3.withSeparator(), QString(QStringLiteral("-- \n") + fileContent)); QVERIFY(!sig3.isEnabledSignature()); Signature sig4; sig4.setPath(QStringLiteral(__FILE__), false); QCOMPARE(sig4.rawText(), fileContent); QVERIFY(!sig4.isInlinedHtml()); QVERIFY(sig4.text().isEmpty()); QCOMPARE(sig4.type(), Signature::FromFile); QCOMPARE(sig4.withSeparator(), QString(QStringLiteral("-- \n") + fileContent)); QVERIFY(!sig4.isEnabledSignature()); } static void setCursorPos(QTextEdit &edit, int pos) { QTextCursor cursor(edit.document()); cursor.setPosition(pos); edit.setTextCursor(cursor); } void SignatureTester::testTextEditInsertion() { KPIMTextEdit::RichTextComposer edit; edit.createActions(new KActionCollection(this)); Signature sig; sig.setEnabledSignature(true); sig.setText(QStringLiteral("Hello World")); - // Test inserting signature at start, with seperators. Make sure two new + // Test inserting signature at start, with separators. Make sure two new // lines are inserted before the signature edit.setPlainText(QStringLiteral("Bla Bla")); sig.insertIntoTextEdit(Signature::Start, Signature::AddSeparator | Signature::AddNewLines, &edit); QVERIFY(edit.textMode() == KPIMTextEdit::RichTextComposer::Plain); QCOMPARE(edit.toPlainText(), QStringLiteral("\n\n-- \nHello World\nBla Bla")); // Test inserting signature at end. make sure cursor position is preserved edit.clear(); edit.setPlainText(QStringLiteral("Bla Bla")); setCursorPos(edit, 4); sig.insertIntoTextEdit(Signature::End, Signature::AddSeparator | Signature::AddNewLines, &edit); QCOMPARE(edit.toPlainText(), QStringLiteral("Bla Bla\n-- \nHello World")); QCOMPARE(edit.textCursor().position(), 4); // test inserting a signature at cursor position. make sure the signature is inserted // to the beginning of the line and make sure modified state is preserved edit.clear(); edit.setPlainText(QStringLiteral("Bla Bla")); setCursorPos(edit, 4); edit.document()->setModified(false); sig.insertIntoTextEdit(Signature::AtCursor, Signature::AddSeparator | Signature::AddNewLines, &edit); QCOMPARE(edit.toPlainText(), QStringLiteral("-- \nHello World\nBla Bla")); QCOMPARE(edit.textCursor().position(), 20); QVERIFY(!edit.document()->isModified()); // make sure undo undoes everything in one go edit.undo(); QCOMPARE(edit.toPlainText(), QStringLiteral("Bla Bla")); - // test inserting signature without seperator. + // test inserting signature without separator. // make sure cursor position and modified state is preserved. edit.clear(); edit.setPlainText(QStringLiteral("Bla Bla")); setCursorPos(edit, 4); edit.document()->setModified(true); sig.insertIntoTextEdit(Signature::End, Signature::AddNewLines, &edit); QCOMPARE(edit.toPlainText(), QStringLiteral("Bla Bla\nHello World")); QCOMPARE(edit.textCursor().position(), 4); QVERIFY(edit.document()->isModified()); sig.setText(QStringLiteral("Hello
World")); sig.setInlinedHtml(true); // test that html signatures turn html on and have correct line endings (
vs \n) edit.clear(); edit.setPlainText(QStringLiteral("Bla Bla")); sig.insertIntoTextEdit(Signature::End, Signature::AddSeparator | Signature::AddNewLines, &edit); QVERIFY(edit.textMode() == KPIMTextEdit::RichTextComposer::Rich); QCOMPARE(edit.toPlainText(), QStringLiteral("Bla Bla\n-- \nHello\nWorld")); } void SignatureTester::testBug167961() { KPIMTextEdit::RichTextComposer edit; edit.createActions(new KActionCollection(this)); Signature sig; sig.setEnabledSignature(true); sig.setText(QStringLiteral("BLA")); // 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); 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); QCOMPARE(edit.textCursor().position(), 0); } // Make writeConfig() public, we need it class MySignature : public Signature { public: using Signature::writeConfig; using Signature::readConfig; }; void SignatureTester::testImages() { KPIMTextEdit::RichTextComposer edit; edit.createActions(new KActionCollection(this)); QImage img(16, 16, QImage::Format_ARGB32_Premultiplied); img.fill(Qt::green); QString image1Path = QCoreApplication::applicationDirPath() + QLatin1String("/image.png"); img.save(image1Path); QImage image1, image2; QVERIFY(image1.load(image1Path)); QVERIFY(image2.load(image1Path)); QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/emailidentities/unittest/"); QDir().mkpath(path); QString configPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QStringLiteral("/signaturetest"); QDir().mkpath(configPath); KConfig config(configPath); KConfigGroup group1 = config.group("Signature1"); MySignature sig; sig.setEnabledSignature(true); sig.setImageLocation(path); sig.setInlinedHtml(true); sig.setText(QStringLiteral("BlaBla")); sig.addImage(image1, QStringLiteral("folder-new.png")); sig.writeConfig(group1); // OK, signature saved, the image should be saved as well QDir dir(path); QStringList entryList = dir.entryList(QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks); QCOMPARE(entryList.count(), 1); QCOMPARE(entryList.first(), QStringLiteral("folder-new.png")); // Now, set the text of the signature to something without images, then save it. // The signature class should have removed the images. sig.setText(QStringLiteral("ascii ribbon campaign - against html mail")); sig.writeConfig(group1); entryList = dir.entryList(QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks); QCOMPARE(entryList.count(), 0); // Enable images again, this time with two of the buggers sig.setText(QStringLiteral("BlaBlaBla")); sig.addImage(image1, QStringLiteral("folder-new.png")); sig.addImage(image2, QStringLiteral("arrow-up.png")); sig.writeConfig(group1); entryList = dir.entryList(QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks); QCOMPARE(entryList.count(), 2); QCOMPARE(entryList.first(), QStringLiteral("arrow-up.png")); QCOMPARE(entryList.last(), QStringLiteral("folder-new.png")); // Now, create a second signature instance from the same config, and make sure it can still // read the images, and it does not mess up MySignature sig2; sig2.readConfig(group1); sig2.insertIntoTextEdit(KIdentityManagement::Signature::End, Signature::AddSeparator | Signature::AddNewLines, &edit); QCOMPARE(edit.composerControler()->composerImages()->embeddedImages().count(), 2); QCOMPARE(sig2.text(), QStringLiteral("BlaBlaBla")); sig2.writeConfig(group1); entryList = dir.entryList(QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks); QCOMPARE(entryList.count(), 2); QCOMPARE(entryList.first(), QStringLiteral("arrow-up.png")); QCOMPARE(entryList.last(), QStringLiteral("folder-new.png")); // Remove one image from the signature, and make sure only 1 file is left one file system. sig2.setText(QStringLiteral("")); sig2.writeConfig(group1); edit.clear(); sig2.insertIntoTextEdit(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); } void SignatureTester::testLinebreaks() { Signature sig; sig.setEnabledSignature(true); sig.setType(Signature::Inlined); sig.setInlinedHtml(true); sig.setText(QStringLiteral("Hans Mustermann
Musterstr. 42")); KPIMTextEdit::RichTextComposer edit; edit.createActions(new KActionCollection(this)); sig.insertIntoTextEdit(Signature::Start, Signature::AddNothing, &edit); QCOMPARE(edit.toPlainText(), QStringLiteral("Hans Mustermann\nMusterstr. 42")); edit.clear(); sig.setText(QStringLiteral("

Hans Mustermann


Musterstr. 42")); sig.insertIntoTextEdit(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")); } diff --git a/src/identity.h b/src/identity.h index e35ba528..8b8a5736 100644 --- a/src/identity.h +++ b/src/identity.h @@ -1,364 +1,364 @@ /* Copyright (c) 2002-2004 Marc Mutz Copyright (c) 2007 Tom Albers Author: Stefan Taferner This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef KPIMIDENTITES_IDENTITY_H -#define KPIMIDENTITES_IDENTITY_H +#ifndef KPIMIDENTITIES_IDENTITY_H +#define KPIMIDENTITIES_IDENTITY_H #include "kidentitymanagement_export.h" #include "signature.h" #include #include #include #include #include namespace KIdentityManagement { class Identity; class Signature; } class KConfigGroup; class QDataStream; class QMimeData; namespace KIdentityManagement { static const char s_uoid[] = "uoid"; static const char s_identity[] = "Identity"; static const char s_name[] = "Name"; static const char s_organization[] = "Organization"; static const char s_pgps[] = "PGP Signing Key"; static const char s_pgpe[] = "PGP Encryption Key"; static const char s_smimes[] = "SMIME Signing Key"; static const char s_smimee[] = "SMIME Encryption Key"; static const char s_prefcrypt[] = "Preferred Crypto Message Format"; static const char s_primaryEmail[] = "Email Address"; static const char s_replyto[] = "Reply-To Address"; static const char s_bcc[] = "Bcc"; static const char s_cc[] = "Cc"; static const char s_vcard[] = "VCardFile"; static const char s_transport[] = "Transport"; static const char s_fcc[] = "Fcc"; static const char s_drafts[] = "Drafts"; static const char s_templates[] = "Templates"; static const char s_dict[] = "Dictionary"; static const char s_xface[] = "X-Face"; static const char s_xfaceenabled[] = "X-FaceEnabled"; static const char s_signature[] = "Signature"; static const char s_emailAliases[] = "Email Aliases"; static const char s_attachVcard[] = "Attach Vcard"; static const char s_autocorrectionLanguage[] = "Autocorrection Language"; static const char s_disabledFcc[] = "Disable Fcc"; static const char s_pgpautosign[] = "Pgp Auto Sign"; static const char s_pgpautoencrypt[] = "Pgp Auto Encrypt"; static const char s_defaultDomainName[] = "Default Domain"; KIDENTITYMANAGEMENT_EXPORT QDataStream &operator<<(QDataStream &stream, const KIdentityManagement::Identity &ident); KIDENTITYMANAGEMENT_EXPORT QDataStream &operator>>(QDataStream &stream, KIdentityManagement::Identity &ident); /** User identity information */ class KIDENTITYMANAGEMENT_EXPORT Identity { // only the identity manager should be able to construct and // destruct us, but then we get into problems with using // QValueList and especially qHeapSort(). friend class IdentityManager; friend KIDENTITYMANAGEMENT_EXPORT QDataStream &operator<<(QDataStream &stream, const KIdentityManagement::Identity &ident); friend KIDENTITYMANAGEMENT_EXPORT QDataStream &operator>>(QDataStream &stream, KIdentityManagement::Identity &ident); public: typedef QVector List; /** Constructor */ explicit Identity(const QString &id = QString(), const QString &realName = QString(), const QString &emailAddr = QString(), const QString &organization = QString(), const QString &replyToAddress = QString()); /** used for comparison */ bool operator==(const Identity &other) const; /** used for comparison */ bool operator!=(const Identity &other) const; /** used for sorting */ bool operator<(const Identity &other) const; /** used for sorting */ bool operator>(const Identity &other) const; /** used for sorting */ bool operator<=(const Identity &other) const; /** used for sorting */ bool operator>=(const Identity &other) const; /** Tests if there are enough values set to allow mailing */ Q_REQUIRED_RESULT bool mailingAllowed() const; /** Identity/nickname for this collection */ Q_REQUIRED_RESULT QString identityName() const; /** Identity/nickname for this collection */ void setIdentityName(const QString &name); /** @return whether this identity is the default identity */ Q_REQUIRED_RESULT bool isDefault() const; /** Unique Object Identifier for this identity */ Q_REQUIRED_RESULT uint uoid() const; /** Full name of the user */ Q_REQUIRED_RESULT QString fullName() const; void setFullName(const QString &); /** The user's organization (optional) */ Q_REQUIRED_RESULT QString organization() const; void setOrganization(const QString &); /** The user's OpenPGP encryption key */ Q_REQUIRED_RESULT QByteArray pgpEncryptionKey() const; void setPGPEncryptionKey(const QByteArray &key); /** The user's OpenPGP signing key */ Q_REQUIRED_RESULT QByteArray pgpSigningKey() const; void setPGPSigningKey(const QByteArray &key); /** The user's S/MIME encryption key */ Q_REQUIRED_RESULT QByteArray smimeEncryptionKey() const; void setSMIMEEncryptionKey(const QByteArray &key); /** The user's S/MIME signing key */ Q_REQUIRED_RESULT QByteArray smimeSigningKey() const; void setSMIMESigningKey(const QByteArray &key); Q_REQUIRED_RESULT QString preferredCryptoMessageFormat() const; void setPreferredCryptoMessageFormat(const QString &); /** * primary email address (without the user name - only name\@host). * The primary email address is used for all outgoing mail. * * @since 4.6 */ Q_REQUIRED_RESULT QString primaryEmailAddress() const; void setPrimaryEmailAddress(const QString &email); /** * email address aliases * * @since 4.6 */ Q_REQUIRED_RESULT const QStringList emailAliases() const; void setEmailAliases(const QStringList &aliases); /** * @param addr the email address to check * @return true if this identity contains the email address @p addr, either as primary address * or as alias * * @since 4.6 */ Q_REQUIRED_RESULT bool matchesEmailAddress(const QString &addr) const; /** vCard to attach to outgoing emails */ Q_REQUIRED_RESULT QString vCardFile() const; void setVCardFile(const QString &); /** email address in the format "username " suitable for the "From:" field of email messages. */ Q_REQUIRED_RESULT QString fullEmailAddr() const; /** email address for the ReplyTo: field */ Q_REQUIRED_RESULT QString replyToAddr() const; void setReplyToAddr(const QString &); /** email addresses for the BCC: field */ Q_REQUIRED_RESULT QString bcc() const; void setBcc(const QString &); /** email addresses for the CC: field * @since 4.9 */ Q_REQUIRED_RESULT QString cc() const; void setCc(const QString &); /** * * @since 4.10 */ Q_REQUIRED_RESULT bool attachVcard() const; void setAttachVcard(bool attach); /** * @since 4.10 */ QString autocorrectionLanguage() const; void setAutocorrectionLanguage(const QString &language); /** * @since 4.11 */ Q_REQUIRED_RESULT bool disabledFcc() const; void setDisabledFcc(bool); /** * @since 4.12 */ Q_REQUIRED_RESULT bool pgpAutoSign() const; void setPgpAutoSign(bool); /** * @since 5.4 */ Q_REQUIRED_RESULT bool pgpAutoEncrypt() const; void setPgpAutoEncrypt(bool); /** * @since 4.14 */ Q_REQUIRED_RESULT QString defaultDomainName() const; void setDefaultDomainName(const QString &domainName); void setSignature(const Signature &sig); Q_REQUIRED_RESULT Signature &signature(); /* _not_ const! */ /** @return the signature with '-- \n' prepended to it if it is not present already. No newline in front of or after the signature is added. @param ok if a valid bool pointer, it is set to @c true or @c false depending on whether the signature could successfully be obtained. */ Q_REQUIRED_RESULT QString signatureText(bool *ok = nullptr) const; /** * @since 4.1 * @return true if the inlined signature is html formatted */ Q_REQUIRED_RESULT bool signatureIsInlinedHtml() const; /** The transport that is set for this identity. Used to link a transport with an identity. */ Q_REQUIRED_RESULT QString transport() const; void setTransport(const QString &); /** The folder where sent messages from this identity will be stored by default. */ Q_REQUIRED_RESULT QString fcc() const; void setFcc(const QString &); /** The folder where draft messages from this identity will be stored by default. */ Q_REQUIRED_RESULT QString drafts() const; void setDrafts(const QString &); /** The folder where template messages from this identity will be stored by default. */ Q_REQUIRED_RESULT QString templates() const; void setTemplates(const QString &); /** * Dictionary which should be used for spell checking * * Note that this is the localized language name (e.g. "British English"), * _not_ the language code or dictionary name! */ Q_REQUIRED_RESULT QString dictionary() const; void setDictionary(const QString &); /** a X-Face header for this identity */ Q_REQUIRED_RESULT QString xface() const; void setXFace(const QString &); Q_REQUIRED_RESULT bool isXFaceEnabled() const; void setXFaceEnabled(const bool); /** Get random properties * @param key the key of the property to get */ Q_REQUIRED_RESULT QVariant property(const QString &key) const; /** Set random properties, when @p value is empty (for QStrings) or null, the property is deleted. */ void setProperty(const QString &key, const QVariant &value); static const Identity &null(); /** Returns true when the identity contains no values, all null values or only empty values */ Q_REQUIRED_RESULT bool isNull() const; Q_REQUIRED_RESULT static QString mimeDataType(); Q_REQUIRED_RESULT static bool canDecode(const QMimeData *); void populateMimeData(QMimeData *) const; static Identity fromMimeData(const QMimeData *); /** Read configuration from config. Group must be preset (or use KConfigGroup). Called from IdentityManager. */ void readConfig(const KConfigGroup &); /** Write configuration to config. Group must be preset (or use KConfigGroup). Called from IdentityManager. */ void writeConfig(KConfigGroup &) const; /** Set whether this identity is the default identity. Since this - affects all other identites, too (most notably, the old default + affects all other identities, too (most notably, the old default identity), only the IdentityManager can change this. You should use
         kmkernel->identityManager()->setAsDefault( name_of_default )
         
instead. */ void setIsDefault(bool flag); /** set the uiod * @param aUoid the uoid to set */ void setUoid(uint aUoid); protected: /** during migration when it failed it can be a string => not a qlonglong akonadi::id => fix it*/ Q_REQUIRED_RESULT QString verifyAkonadiId(const QString &str) const; /** @return true if the signature is read from the output of a command */ Q_REQUIRED_RESULT bool signatureIsCommand() const; /** @return true if the signature is read from a text file */ Q_REQUIRED_RESULT bool signatureIsPlainFile() const; /** @return true if the signature was specified directly */ Q_REQUIRED_RESULT bool signatureIsInline() const; /** name of the signature file (with path) */ Q_REQUIRED_RESULT QString signatureFile() const; void setSignatureFile(const QString &); /** inline signature */ Q_REQUIRED_RESULT QString signatureInlineText() const; void setSignatureInlineText(const QString &); /** Inline or signature from a file */ Q_REQUIRED_RESULT bool useSignatureFile() const; Signature mSignature; bool mIsDefault; QHash mPropertiesMap; }; } -#endif /*kpim_identity_h*/ +#endif /*identity_h*/ diff --git a/src/identitymanager.cpp b/src/identitymanager.cpp index 59ec07f5..0a192fc4 100644 --- a/src/identitymanager.cpp +++ b/src/identitymanager.cpp @@ -1,718 +1,718 @@ /* Copyright (c) 2002 Marc Mutz This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // config keys: static const char configKeyDefaultIdentity[] = "Default Identity"; #include "identitymanager.h" #include "identity.h" // for IdentityList::{export,import}Data #include // for static helper functions #include // for IdentityEntry::fromControlCenter() #include #include "kidentitymanagement_debug.h" #include #include #include #include #include #include #include #include #include #include #include #include "identitymanageradaptor.h" namespace KIdentityManagement { static QString newDBusObjectName() { static int s_count = 0; QString name(QStringLiteral("/KIDENTITYMANAGER_IdentityManager")); if (s_count++) { name += QLatin1Char('_'); name += QString::number(s_count); } return name; } /** * Private class that helps to provide binary compatibility between releases. * @internal */ //@cond PRIVATE class Q_DECL_HIDDEN KIdentityManagement::IdentityManager::Private { public: Private(KIdentityManagement::IdentityManager *); ~Private(); void writeConfig() const; void readConfig(KConfig *config); void createDefaultIdentity(); QStringList groupList(KConfig *config) const; void slotIdentitiesChanged(const QString &id); KConfig *mConfig = nullptr; QList mIdentities; QList shadowIdentities; // returns a new Unique Object Identifier int newUoid(); bool mReadOnly = true; KIdentityManagement::IdentityManager *q; }; IdentityManager::Private::Private(KIdentityManagement::IdentityManager *manager) : q(manager) { } void IdentityManager::Private::writeConfig() const { const QStringList identities = groupList(mConfig); QStringList::const_iterator groupEnd = identities.constEnd(); for (QStringList::const_iterator group = identities.constBegin(); group != groupEnd; ++group) { mConfig->deleteGroup(*group); } int i = 0; ConstIterator end = mIdentities.constEnd(); for (ConstIterator it = mIdentities.constBegin(); it != end; ++it, ++i) { KConfigGroup cg(mConfig, QStringLiteral("Identity #%1").arg(i)); (*it).writeConfig(cg); if ((*it).isDefault()) { // remember which one is default: KConfigGroup general(mConfig, "General"); general.writeEntry(configKeyDefaultIdentity, (*it).uoid()); // Also write the default identity to emailsettings KEMailSettings es; es.setSetting(KEMailSettings::RealName, (*it).fullName()); es.setSetting(KEMailSettings::EmailAddress, (*it).primaryEmailAddress()); es.setSetting(KEMailSettings::Organization, (*it).organization()); es.setSetting(KEMailSettings::ReplyToAddress, (*it).replyToAddr()); } } mConfig->sync(); } void IdentityManager::Private::readConfig(KConfig *config) { mIdentities.clear(); const QStringList identities = groupList(config); if (identities.isEmpty()) { return; // nothing to be done... } KConfigGroup general(config, "General"); uint defaultIdentity = general.readEntry(configKeyDefaultIdentity, 0); bool haveDefault = false; QStringList::const_iterator groupEnd = identities.constEnd(); for (QStringList::const_iterator group = identities.constBegin(); group != groupEnd; ++group) { KConfigGroup configGroup(config, *group); Identity identity; identity.readConfig(configGroup); //Don't load invalid identity if (!identity.isNull() && !identity.primaryEmailAddress().isEmpty()) { if (!haveDefault && identity.uoid() == defaultIdentity) { haveDefault = true; identity.setIsDefault(true); } } mIdentities << identity; } if (!haveDefault) { if (mIdentities.isEmpty()) { mIdentities << Identity(); } qCWarning(KIDENTITYMANAGEMENT_LOG) << "IdentityManager: There was no default identity." << "Marking first one as default."; mIdentities.first().setIsDefault(true); } std::sort(mIdentities.begin(), mIdentities.end()); shadowIdentities = mIdentities; } void IdentityManager::Private::createDefaultIdentity() { QString fullName, emailAddress; bool done = false; // Check if the application has any settings q->createDefaultIdentity(fullName, emailAddress); // If not, then use the kcontrol settings if (fullName.isEmpty() && emailAddress.isEmpty()) { KEMailSettings emailSettings; fullName = emailSettings.getSetting(KEMailSettings::RealName); emailAddress = emailSettings.getSetting(KEMailSettings::EmailAddress); if (!fullName.isEmpty() && !emailAddress.isEmpty()) { q->newFromControlCenter(i18nc("use default address from control center", "Default")); done = true; } else { // If KEmailSettings doesn't have name and address, generate something from KUser KUser user; if (fullName.isEmpty()) { fullName = user.property(KUser::FullName).toString(); } if (emailAddress.isEmpty()) { emailAddress = user.loginName(); if (!emailAddress.isEmpty()) { KConfigGroup general(mConfig, "General"); QString defaultdomain = general.readEntry("Default domain"); if (!defaultdomain.isEmpty()) { emailAddress += QLatin1Char('@') + defaultdomain; } else { emailAddress.clear(); } } } } } if (!done) { // Default identity name QString name(i18nc("Default name for new email accounts/identities.", "Unnamed")); if (!emailAddress.isEmpty()) { // If we have an email address, create a default identity name from it QString idName = emailAddress; int pos = idName.indexOf(QLatin1Char('@')); if (pos != -1) { name = idName.mid(pos + 1, -1); } // Make the name a bit more human friendly name.replace(QLatin1Char('.'), QLatin1Char(' ')); pos = name.indexOf(QLatin1Char(' ')); if (pos != 0) { name[pos + 1] = name[pos + 1].toUpper(); } name[0] = name[0].toUpper(); } else if (!fullName.isEmpty()) { // If we have a full name, create a default identity name from it name = fullName; } shadowIdentities << Identity(name, fullName, emailAddress); } shadowIdentities.last().setIsDefault(true); shadowIdentities.last().setUoid(newUoid()); if (mReadOnly) { // commit won't do it in readonly mode mIdentities = shadowIdentities; } } QStringList IdentityManager::Private::groupList(KConfig *config) const { return config->groupList().filter(QRegularExpression(QStringLiteral("^Identity #\\d+$"))); } int IdentityManager::Private::newUoid() { int uoid; // determine the UOIDs of all saved identities QList usedUOIDs; usedUOIDs.reserve(1 + mIdentities.count() + (q->hasPendingChanges() ? shadowIdentities.count() : 0)); QList::ConstIterator end(mIdentities.constEnd()); for (QList::ConstIterator it = mIdentities.constBegin(); it != end; ++it) { usedUOIDs << (*it).uoid(); } if (q->hasPendingChanges()) { // add UOIDs of all shadow identities. Yes, we will add a lot of duplicate // UOIDs, but avoiding duplicate UOIDs isn't worth the effort. QList::ConstIterator endShadow(shadowIdentities.constEnd()); for (QList::ConstIterator it = shadowIdentities.constBegin(); it != endShadow; ++it) { usedUOIDs << (*it).uoid(); } } usedUOIDs << 0; // no UOID must be 0 because this value always refers to the // default identity do { uoid = KRandom::random(); } while (usedUOIDs.indexOf(uoid) != -1); return uoid; } void IdentityManager::Private::slotIdentitiesChanged(const QString &id) { qCDebug(KIDENTITYMANAGEMENT_LOG) << " KIdentityManagement::IdentityManager::slotIdentitiesChanged :" << id; const QString ourIdentifier = QStringLiteral("%1/%2"). arg(QDBusConnection::sessionBus().baseService(), q->property("uniqueDBusPath").toString()); if (id != ourIdentifier) { mConfig->reparseConfiguration(); Q_ASSERT(!q->hasPendingChanges()); readConfig(mConfig); emit q->changed(); } } Q_GLOBAL_STATIC(IdentityManager, s_self) IdentityManager *IdentityManager::self() { return s_self; } IdentityManager::IdentityManager(bool readonly, QObject *parent, const char *name) : QObject(parent) , d(new Private(this)) { static bool triedMigration = false; if (!triedMigration) { triedMigration = true; Kdelibs4ConfigMigrator migrate(QStringLiteral("identitymanager")); migrate.setConfigFiles(QStringList() << QStringLiteral("emailidentities")); migrate.migrate(); } setObjectName(QLatin1String(name)); new IdentityManagerAdaptor(this); QDBusConnection dbus = QDBusConnection::sessionBus(); const QString dbusPath = newDBusObjectName(); setProperty("uniqueDBusPath", dbusPath); const QString dbusInterface = QStringLiteral("org.kde.pim.IdentityManager"); dbus.registerObject(dbusPath, this); dbus.connect(QString(), QString(), dbusInterface, QStringLiteral("identitiesChanged"), this, SLOT(slotIdentitiesChanged(QString))); d->mReadOnly = readonly; d->mConfig = new KConfig(QStringLiteral("emailidentities")); d->readConfig(d->mConfig); // we need at least a default identity: if (d->mIdentities.isEmpty()) { qCDebug(KIDENTITYMANAGEMENT_LOG) << "IdentityManager: No identity found. Creating default."; d->createDefaultIdentity(); commit(); } KSharedConfig::Ptr kmailConf(KSharedConfig::openConfig(QStringLiteral("kmail2rc"))); if (!d->mReadOnly) { bool needCommit = false; if (kmailConf->hasGroup(QStringLiteral("Composer"))) { KConfigGroup composerGroup = kmailConf->group(QStringLiteral("Composer")); if (composerGroup.hasKey(QStringLiteral("pgp-auto-sign"))) { const bool pgpAutoSign = composerGroup.readEntry(QStringLiteral("pgp-auto-sign"), false); QList::iterator end = d->mIdentities.end(); for (QList::iterator it = d->mIdentities.begin(); it != end; ++it) { it->setPgpAutoSign(pgpAutoSign); } composerGroup.deleteEntry(QStringLiteral("pgp-auto-sign")); composerGroup.sync(); needCommit = true; } } if (kmailConf->hasGroup(QStringLiteral("General"))) { KConfigGroup generalGroup = kmailConf->group(QStringLiteral("General")); if (generalGroup.hasKey(QStringLiteral("Default domain"))) { QString defaultDomain = generalGroup.readEntry(QStringLiteral("Default domain")); if (defaultDomain.isEmpty()) { defaultDomain = QHostInfo::localHostName(); } QList::iterator end = d->mIdentities.end(); for (QList::iterator it = d->mIdentities.begin(); it != end; ++it) { it->setDefaultDomainName(defaultDomain); } generalGroup.deleteEntry(QStringLiteral("Default domain")); generalGroup.sync(); needCommit = true; } } if (needCommit) { commit(); } } // Migration: people without settings in kemailsettings should get some if (KEMailSettings().getSetting(KEMailSettings::EmailAddress).isEmpty()) { d->writeConfig(); } } IdentityManager::~IdentityManager() { if (hasPendingChanges()) { qCWarning(KIDENTITYMANAGEMENT_LOG) << "IdentityManager: There were uncommitted changes!"; } delete d; } QString IdentityManager::makeUnique(const QString &name) const { int suffix = 1; QString result = name; while (identities().contains(result)) { result = i18nc("%1: name; %2: number appended to it to make it unique " "among a list of names", "%1 #%2", name, suffix); ++suffix; } return result; } bool IdentityManager::isUnique(const QString &name) const { return !identities().contains(name); } void IdentityManager::commit() { // early out: if (!hasPendingChanges() || d->mReadOnly) { return; } QList seenUOIDs; seenUOIDs.reserve(d->mIdentities.count()); QList::ConstIterator end = d->mIdentities.constEnd(); for (QList::ConstIterator it = d->mIdentities.constBegin(); it != end; ++it) { seenUOIDs << (*it).uoid(); } QList changedUOIDs; // find added and changed identities: for (QList::ConstIterator it = d->shadowIdentities.constBegin(); it != d->shadowIdentities.constEnd(); ++it) { int index = seenUOIDs.indexOf((*it).uoid()); if (index != -1) { uint uoid = seenUOIDs.at(index); const Identity &orig = identityForUoid(uoid); // look up in mIdentities if (*it != orig) { // changed identity qCDebug(KIDENTITYMANAGEMENT_LOG) << "emitting changed() for identity" << uoid; emit changed(*it); changedUOIDs << uoid; } seenUOIDs.removeAll(uoid); } else { // new identity qCDebug(KIDENTITYMANAGEMENT_LOG) << "emitting added() for identity" << (*it).uoid(); emit added(*it); } } // what's left are deleted identities: for (QList::ConstIterator it = seenUOIDs.constBegin(); it != seenUOIDs.constEnd(); ++it) { qCDebug(KIDENTITYMANAGEMENT_LOG) << "emitting deleted() for identity" << (*it); emit deleted(*it); } d->mIdentities = d->shadowIdentities; d->writeConfig(); // now that mIdentities has all the new info, we can emit the added/changed // signals that ship a uoid. This is because the slots might use // identityForUoid(uoid)... QList::ConstIterator changedEnd(changedUOIDs.constEnd()); for (QList::ConstIterator it = changedUOIDs.constBegin(); it != changedEnd; ++it) { emit changed(*it); } emit changed(); // normal signal // DBus signal for other IdentityManager instances const QString ourIdentifier = QStringLiteral("%1/%2"). arg(QDBusConnection::sessionBus().baseService(), property("uniqueDBusPath").toString()); emit identitiesChanged(ourIdentifier); } void IdentityManager::rollback() { d->shadowIdentities = d->mIdentities; } bool IdentityManager::hasPendingChanges() const { return d->mIdentities != d->shadowIdentities; } QStringList IdentityManager::identities() const { QStringList result; result.reserve(d->mIdentities.count()); ConstIterator end = d->mIdentities.constEnd(); for (ConstIterator it = d->mIdentities.constBegin(); it != end; ++it) { result << (*it).identityName(); } return result; } QStringList IdentityManager::shadowIdentities() const { QStringList result; result.reserve(d->shadowIdentities.count()); ConstIterator end = d->shadowIdentities.constEnd(); for (ConstIterator it = d->shadowIdentities.constBegin(); it != end; ++it) { result << (*it).identityName(); } return result; } void IdentityManager::sort() { std::sort(d->shadowIdentities.begin(), d->shadowIdentities.end()); } IdentityManager::ConstIterator IdentityManager::begin() const { return d->mIdentities.constBegin(); } IdentityManager::ConstIterator IdentityManager::end() const { return d->mIdentities.constEnd(); } IdentityManager::Iterator IdentityManager::modifyBegin() { return d->shadowIdentities.begin(); } IdentityManager::Iterator IdentityManager::modifyEnd() { return d->shadowIdentities.end(); } const Identity &IdentityManager::identityForUoid(uint uoid) const { for (ConstIterator it = begin(); it != end(); ++it) { if ((*it).uoid() == uoid) { return *it; } } return Identity::null(); } const Identity &IdentityManager::identityForUoidOrDefault(uint uoid) const { const Identity &ident = identityForUoid(uoid); if (ident.isNull()) { return defaultIdentity(); } else { return ident; } } const Identity &IdentityManager::identityForAddress( const QString &addresses) const { const QStringList addressList = KEmailAddress::splitAddressList(addresses); for (const QString &fullAddress : addressList) { const QString addrSpec = KEmailAddress::extractEmailAddress(fullAddress).toLower(); for (ConstIterator it = begin(); it != end(); ++it) { const Identity &identity = *it; if (identity.matchesEmailAddress(addrSpec)) { return identity; } } } return Identity::null(); } bool IdentityManager::thatIsMe(const QString &addressList) const { return !identityForAddress(addressList).isNull(); } Identity &IdentityManager::modifyIdentityForName(const QString &name) { for (Iterator it = modifyBegin(); it != modifyEnd(); ++it) { if ((*it).identityName() == name) { return *it; } } qCWarning(KIDENTITYMANAGEMENT_LOG) << "IdentityManager::modifyIdentityForName() used as" << "newFromScratch() replacement!" << endl << " name == \"" << name << "\""; return newFromScratch(name); } Identity &IdentityManager::modifyIdentityForUoid(uint uoid) { for (Iterator it = modifyBegin(); it != modifyEnd(); ++it) { if ((*it).uoid() == uoid) { return *it; } } qCWarning(KIDENTITYMANAGEMENT_LOG) << "IdentityManager::identityForUoid() used as" << "newFromScratch() replacement!" << endl << " uoid == \"" << uoid << "\""; return newFromScratch(i18n("Unnamed")); } const Identity &IdentityManager::defaultIdentity() const { for (ConstIterator it = begin(); it != end(); ++it) { if ((*it).isDefault()) { return *it; } } if (d->mIdentities.isEmpty()) { qCritical() << "IdentityManager: No default identity found!"; } else { qCWarning(KIDENTITYMANAGEMENT_LOG) << "IdentityManager: No default identity found!"; } return *begin(); } bool IdentityManager::setAsDefault(uint uoid) { // First, check if the identity actually exists: bool found = false; ConstIterator end(d->shadowIdentities.constEnd()); for (ConstIterator it = d->shadowIdentities.constBegin(); it != end; ++it) { if ((*it).uoid() == uoid) { found = true; break; } } if (!found) { return false; } // Then, change the default as requested: for (Iterator it = modifyBegin(); it != modifyEnd(); ++it) { (*it).setIsDefault((*it).uoid() == uoid); } // and re-sort: sort(); return true; } bool IdentityManager::removeIdentity(const QString &name) { if (d->shadowIdentities.size() <= 1) { return false; } for (Iterator it = modifyBegin(); it != modifyEnd(); ++it) { if ((*it).identityName() == name) { bool removedWasDefault = (*it).isDefault(); d->shadowIdentities.erase(it); if (removedWasDefault && !d->shadowIdentities.isEmpty()) { d->shadowIdentities.first().setIsDefault(true); } return true; } } return false; } bool IdentityManager::removeIdentityForced(const QString &name) { for (Iterator it = modifyBegin(); it != modifyEnd(); ++it) { if ((*it).identityName() == name) { bool removedWasDefault = (*it).isDefault(); d->shadowIdentities.erase(it); if (removedWasDefault && !d->shadowIdentities.isEmpty()) { d->shadowIdentities.first().setIsDefault(true); } return true; } } return false; } Identity &IdentityManager::newFromScratch(const QString &name) { return newFromExisting(Identity(name)); } Identity &IdentityManager::newFromControlCenter(const QString &name) { KEMailSettings es; es.setProfile(es.defaultProfileName()); return newFromExisting(Identity(name, es.getSetting(KEMailSettings::RealName), es.getSetting(KEMailSettings::EmailAddress), es.getSetting(KEMailSettings::Organization), es.getSetting(KEMailSettings::ReplyToAddress))); } Identity &IdentityManager::newFromExisting(const Identity &other, const QString &name) { d->shadowIdentities << other; Identity &result = d->shadowIdentities.last(); result.setIsDefault(false); // we don't want two default identities! - result.setUoid(d->newUoid()); // we don't want two identies w/ same UOID + result.setUoid(d->newUoid()); // we don't want two identities w/ same UOID if (!name.isNull()) { result.setIdentityName(name); } return result; } QStringList KIdentityManagement::IdentityManager::allEmails() const { QStringList lst; for (ConstIterator it = begin(); it != end(); ++it) { lst << (*it).primaryEmailAddress(); if (!(*it).emailAliases().isEmpty()) { lst << (*it).emailAliases(); } } return lst; } void IdentityManager::createDefaultIdentity(QString &, QString &) { } void KIdentityManagement::IdentityManager::slotRollback() { rollback(); } IdentityManager::Private::~Private() { delete mConfig; } } #include "moc_identitymanager.cpp" diff --git a/src/signatureconfigurator.cpp b/src/signatureconfigurator.cpp index 19e02554..1689a795 100644 --- a/src/signatureconfigurator.cpp +++ b/src/signatureconfigurator.cpp @@ -1,488 +1,488 @@ /* -*- c++ -*- Copyright 2008 Thomas McGuire Copyright 2008 Edwin Schepers Copyright 2004 Marc Mutz This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "signatureconfigurator.h" #include "identity.h" #include #include #include "kidentitymanagement_debug.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace KIdentityManagement; namespace KIdentityManagement { /** Private class that helps to provide binary compatibility between releases. @internal */ //@cond PRIVATE class Q_DECL_HIDDEN SignatureConfigurator::Private { public: Private(SignatureConfigurator *parent); void init(); // Returns the current text of the textedit as HTML code, but strips // unnecessary tags Qt inserts QString asCleanedHTML() const; QString imageLocation; SignatureConfigurator *q; QCheckBox *mEnableCheck = nullptr; QCheckBox *mHtmlCheck = nullptr; QComboBox *mSourceCombo = nullptr; KUrlRequester *mFileRequester = nullptr; QPushButton *mEditButton = nullptr; KLineEdit *mCommandEdit = nullptr; KToolBar *mEditToolBar = nullptr; KToolBar *mFormatToolBar = nullptr; KPIMTextEdit::RichTextComposer *mTextEdit = nullptr; bool inlinedHtml = false; }; //@endcond SignatureConfigurator::Private::Private(SignatureConfigurator *parent) : q(parent) , inlinedHtml(true) { } QString SignatureConfigurator::Private::asCleanedHTML() const { QString text = mTextEdit->toHtml(); // Beautiful little hack to find the html headers produced by Qt. QTextDocument textDocument; QString html = textDocument.toHtml(); // Now remove each line from the text, the result is clean html. const QStringList lst = html.split(QLatin1Char('\n')); for (const QString &line : lst) { text.remove(line + QLatin1Char('\n')); } return text; } void SignatureConfigurator::Private::init() { QVBoxLayout *vlay = new QVBoxLayout(q); vlay->setObjectName(QStringLiteral("main layout")); - // "enable signatue" checkbox: + // "enable signature" checkbox: mEnableCheck = new QCheckBox(i18n("&Enable signature"), q); mEnableCheck->setWhatsThis( i18n("Check this box if you want KMail to append a signature to mails " "written with this identity.")); vlay->addWidget(mEnableCheck); // "obtain signature text from" combo and label: QHBoxLayout *hlay = new QHBoxLayout(); // inherits spacing vlay->addLayout(hlay); mSourceCombo = new QComboBox(q); mSourceCombo->setEditable(false); mSourceCombo->setWhatsThis( i18n("Click on the widgets below to obtain help on the input methods.")); mSourceCombo->setEnabled(false); // since !mEnableCheck->isChecked() mSourceCombo->addItems(QStringList() << i18nc("continuation of \"obtain signature text from\"", "Input Field Below") << i18nc("continuation of \"obtain signature text from\"", "File") << i18nc("continuation of \"obtain signature text from\"", "Output of Command")); QLabel *label = new QLabel(i18n("Obtain signature &text from:"), q); label->setBuddy(mSourceCombo); label->setEnabled(false); // since !mEnableCheck->isChecked() hlay->addWidget(label); hlay->addWidget(mSourceCombo, 1); // widget stack that is controlled by the source combo: QStackedWidget *widgetStack = new QStackedWidget(q); widgetStack->setEnabled(false); // since !mEnableCheck->isChecked() vlay->addWidget(widgetStack, 1); q->connect(mSourceCombo, QOverload::of(&QComboBox::currentIndexChanged), widgetStack, &QStackedWidget::setCurrentIndex); q->connect(mSourceCombo, QOverload::of(&QComboBox::highlighted), widgetStack, &QStackedWidget::setCurrentIndex); // connects for the enabling of the widgets depending on // signatureEnabled: q->connect(mEnableCheck, &QCheckBox::toggled, mSourceCombo, &QComboBox::setEnabled); q->connect(mEnableCheck, &QCheckBox::toggled, widgetStack, &QStackedWidget::setEnabled); q->connect(mEnableCheck, &QCheckBox::toggled, label, &QLabel::setEnabled); // The focus might be still in the widget that is disabled q->connect(mEnableCheck, &QCheckBox::clicked, mEnableCheck, QOverload<>::of(&QCheckBox::setFocus)); int pageno = 0; // page 0: input field for direct entering: QWidget *page = new QWidget(widgetStack); widgetStack->insertWidget(pageno, page); QVBoxLayout *page_vlay = new QVBoxLayout(page); page_vlay->setMargin(0); #ifndef QT_NO_TOOLBAR mEditToolBar = new KToolBar(q); mEditToolBar->setToolButtonStyle(Qt::ToolButtonIconOnly); page_vlay->addWidget(mEditToolBar, 0); mFormatToolBar = new KToolBar(q); mFormatToolBar->setToolButtonStyle(Qt::ToolButtonIconOnly); page_vlay->addWidget(mFormatToolBar, 1); #endif mTextEdit = new KPIMTextEdit::RichTextComposer(q); KPIMTextEdit::RichTextEditorWidget *richTextEditorwidget = new KPIMTextEdit::RichTextEditorWidget(mTextEdit, q); page_vlay->addWidget(richTextEditorwidget, 2); mTextEdit->setWhatsThis(i18n("Use this field to enter an arbitrary static signature.")); // Fill the toolbars. KActionCollection *actionCollection = new KActionCollection(q); mTextEdit->createActions(actionCollection); #ifndef QT_NO_TOOLBAR mEditToolBar->addAction(actionCollection->action(QStringLiteral("format_text_bold"))); mEditToolBar->addAction(actionCollection->action(QStringLiteral("format_text_italic"))); mEditToolBar->addAction(actionCollection->action(QStringLiteral("format_text_underline"))); mEditToolBar->addAction(actionCollection->action(QStringLiteral("format_text_strikeout"))); mEditToolBar->addAction(actionCollection->action(QStringLiteral("format_text_foreground_color"))); mEditToolBar->addAction(actionCollection->action(QStringLiteral("format_text_background_color"))); mEditToolBar->addAction(actionCollection->action(QStringLiteral("format_font_family"))); mEditToolBar->addAction(actionCollection->action(QStringLiteral("format_font_size"))); mEditToolBar->addAction(actionCollection->action(QStringLiteral("format_reset"))); mFormatToolBar->addAction(actionCollection->action(QStringLiteral("format_list_style"))); mFormatToolBar->addAction(actionCollection->action(QStringLiteral("format_list_indent_more"))); mFormatToolBar->addAction(actionCollection->action(QStringLiteral("format_list_indent_less"))); mFormatToolBar->addAction(actionCollection->action(QStringLiteral("format_list_indent_less"))); mFormatToolBar->addSeparator(); mFormatToolBar->addAction(actionCollection->action(QStringLiteral("format_align_left"))); mFormatToolBar->addAction(actionCollection->action(QStringLiteral("format_align_center"))); mFormatToolBar->addAction(actionCollection->action(QStringLiteral("format_align_right"))); mFormatToolBar->addAction(actionCollection->action(QStringLiteral("format_align_justify"))); mFormatToolBar->addSeparator(); mFormatToolBar->addAction(actionCollection->action(QStringLiteral("insert_horizontal_rule"))); mFormatToolBar->addAction(actionCollection->action(QStringLiteral("manage_link"))); mFormatToolBar->addAction(actionCollection->action(QStringLiteral("format_painter"))); mFormatToolBar->addSeparator(); mFormatToolBar->addAction(actionCollection->action(QStringLiteral("add_image"))); mFormatToolBar->addSeparator(); mFormatToolBar->addAction(actionCollection->action(QStringLiteral("insert_html"))); mFormatToolBar->addAction(actionCollection->action(QStringLiteral("insert_table"))); #endif hlay = new QHBoxLayout(); // inherits spacing page_vlay->addLayout(hlay); mHtmlCheck = new QCheckBox(i18n("&Use HTML"), page); q->connect(mHtmlCheck, &QCheckBox::clicked, q, &SignatureConfigurator::slotSetHtml); hlay->addWidget(mHtmlCheck); inlinedHtml = true; widgetStack->setCurrentIndex(0); // since mSourceCombo->currentItem() == 0 // page 1: "signature file" requester, label, "edit file" button: ++pageno; page = new QWidget(widgetStack); widgetStack->insertWidget(pageno, page); // force sequential numbers (play safe) page_vlay = new QVBoxLayout(page); page_vlay->setMargin(0); hlay = new QHBoxLayout(); // inherits spacing page_vlay->addLayout(hlay); mFileRequester = new KUrlRequester(page); mFileRequester->setFilter(QStringLiteral("*.txt")); mFileRequester->setWhatsThis( i18n("Use this requester to specify a text file that contains your " "signature. It will be read every time you create a new mail or " "append a new signature.")); label = new QLabel(i18n("S&pecify file:"), page); label->setBuddy(mFileRequester); hlay->addWidget(label); hlay->addWidget(mFileRequester, 1); mFileRequester->button()->setAutoDefault(false); q->connect(mFileRequester, &KUrlRequester::textEdited, q, &SignatureConfigurator::slotUrlChanged); q->connect(mFileRequester, &KUrlRequester::urlSelected, q, &SignatureConfigurator::slotUrlChanged); mEditButton = new QPushButton(i18n("Edit &File"), page); mEditButton->setWhatsThis(i18n("Opens the specified file in a text editor.")); q->connect(mEditButton, &QPushButton::clicked, q, &SignatureConfigurator::slotEdit); mEditButton->setAutoDefault(false); mEditButton->setEnabled(false); // initially nothing to edit hlay->addWidget(mEditButton); page_vlay->addStretch(1); // spacer // page 2: "signature command" requester and label: ++pageno; page = new QWidget(widgetStack); widgetStack->insertWidget(pageno, page); page_vlay = new QVBoxLayout(page); page_vlay->setMargin(0); hlay = new QHBoxLayout(); // inherits spacing page_vlay->addLayout(hlay); mCommandEdit = new KLineEdit(page); mCommandEdit->setClearButtonEnabled(true); mCommandEdit->setCompletionObject(new KShellCompletion()); mCommandEdit->setAutoDeleteCompletionObject(true); mCommandEdit->setWhatsThis( i18n("You can add an arbitrary command here, either with or without path " "depending on whether or not the command is in your Path. For every " "new mail, KMail will execute the command and use what it outputs (to " "standard output) as a signature. Usual commands for use with this " "mechanism are \"fortune\" or \"ksig -random\".")); label = new QLabel(i18n("S&pecify command:"), page); label->setBuddy(mCommandEdit); hlay->addWidget(label); hlay->addWidget(mCommandEdit, 1); page_vlay->addStretch(1); // spacer } SignatureConfigurator::SignatureConfigurator(QWidget *parent) : QWidget(parent) , d(new Private(this)) { d->init(); } SignatureConfigurator::~SignatureConfigurator() { delete d; } bool SignatureConfigurator::isSignatureEnabled() const { return d->mEnableCheck->isChecked(); } void SignatureConfigurator::setSignatureEnabled(bool enable) { d->mEnableCheck->setChecked(enable); } Signature::Type SignatureConfigurator::signatureType() const { switch (d->mSourceCombo->currentIndex()) { case 0: return Signature::Inlined; case 1: return Signature::FromFile; case 2: return Signature::FromCommand; default: return Signature::Disabled; } } void SignatureConfigurator::setSignatureType(Signature::Type type) { int idx = 0; switch (type) { case Signature::Inlined: idx = 0; break; case Signature::FromFile: idx = 1; break; case Signature::FromCommand: idx = 2; break; default: idx = 0; break; } d->mSourceCombo->setCurrentIndex(idx); } void SignatureConfigurator::setInlineText(const QString &text) { d->mTextEdit->setTextOrHtml(text); } QString SignatureConfigurator::filePath() const { QString file = d->mFileRequester->url().path(); // Force the filename to be relative to ~ instead of $PWD depending // on the rest of the code (KRun::run in Edit and KFileItem on save) if (!file.isEmpty() && QFileInfo(file).isRelative()) { file = QDir::home().absolutePath() + QDir::separator() + file; } return file; } void SignatureConfigurator::setFileURL(const QString &url) { d->mFileRequester->setUrl(QUrl::fromLocalFile(url)); d->mEditButton->setDisabled(url.trimmed().isEmpty()); } QString SignatureConfigurator::commandPath() const { return d->mCommandEdit->text(); } void SignatureConfigurator::setCommandURL(const QString &url) { d->mCommandEdit->setText(url); } Signature SignatureConfigurator::signature() const { Signature sig; const Signature::Type sigType = signatureType(); switch (sigType) { case Signature::Inlined: sig.setInlinedHtml(d->inlinedHtml); sig.setText(d->inlinedHtml ? d->asCleanedHTML() : d->mTextEdit->textOrHtml()); if (d->inlinedHtml) { if (!d->imageLocation.isEmpty()) { sig.setImageLocation(d->imageLocation); } const KPIMTextEdit::ImageWithNameList images = d->mTextEdit->composerControler()->composerImages()->imagesWithName(); for (const KPIMTextEdit::ImageWithNamePtr &image : images) { sig.addImage(image->image, image->name); } } break; case Signature::FromCommand: sig.setPath(commandPath(), true); break; case Signature::FromFile: sig.setPath(filePath(), false); break; case Signature::Disabled: /* do nothing */ break; } sig.setEnabledSignature(isSignatureEnabled()); sig.setType(sigType); return sig; } void SignatureConfigurator::setSignature(const Signature &sig) { setSignatureType(sig.type()); setSignatureEnabled(sig.isEnabledSignature()); if (sig.isInlinedHtml()) { d->mHtmlCheck->setCheckState(Qt::Checked); } else { d->mHtmlCheck->setCheckState(Qt::Unchecked); } slotSetHtml(); // 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); if (sig.type() == Signature::FromFile) { setFileURL(sig.path()); } else { setFileURL(QString()); } if (sig.type() == Signature::FromCommand) { setCommandURL(sig.path()); } else { setCommandURL(QString()); } } void SignatureConfigurator::slotUrlChanged() { const QString file = filePath(); const QFileInfo infoFile = QFileInfo(file); if (infoFile.isFile() && (infoFile.size() > 1000)) { KMessageBox::information(this, i18n("This text file size exceeds 1kb."), i18n("Text File Size")); } d->mEditButton->setDisabled(file.isEmpty()); } void SignatureConfigurator::slotEdit() { QString url = filePath(); // slotEnableEditButton should prevent this assert from being hit: assert(!url.isEmpty()); KRun::RunFlags flags; flags |= KRun::DeleteTemporaryFiles; KRun::runUrl(QUrl::fromLocalFile(url), QStringLiteral("text/plain"), this, flags); } // "use HTML"-checkbox (un)checked void SignatureConfigurator::slotSetHtml() { if (d->mHtmlCheck->checkState() == Qt::Unchecked) { d->mHtmlCheck->setText(i18n("&Use HTML")); #ifndef QT_NO_TOOLBAR d->mEditToolBar->setVisible(false); d->mEditToolBar->setEnabled(false); d->mFormatToolBar->setVisible(false); d->mFormatToolBar->setEnabled(false); #endif d->mTextEdit->switchToPlainText(); d->inlinedHtml = false; } else { d->mHtmlCheck->setText(i18n("&Use HTML (disabling removes formatting)")); d->inlinedHtml = true; #ifndef QT_NO_TOOLBAR d->mEditToolBar->setVisible(true); d->mEditToolBar->setEnabled(true); d->mFormatToolBar->setVisible(true); d->mFormatToolBar->setEnabled(true); #endif d->mTextEdit->activateRichText(); } } void SignatureConfigurator::setImageLocation(const QString &path) { d->imageLocation = path; } void SignatureConfigurator::setImageLocation(const Identity &identity) { const QString dir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/emailidentities/%1/").arg( QString::number(identity.uoid())); QDir().mkpath(dir); setImageLocation(dir); } } diff --git a/src/signatureconfigurator.h b/src/signatureconfigurator.h index 94aa8200..9bf62880 100644 --- a/src/signatureconfigurator.h +++ b/src/signatureconfigurator.h @@ -1,157 +1,157 @@ /* -*- c++ -*- Copyright 2008 Thomas McGuire Copyright 2008 Edwin Schepers Copyright 2008 Tom Albers Copyright 2004 Marc Mutz This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef KIDENTITYMANAGER_SIGNATURECONFIGURATOR_H #define KIDENTITYMANAGER_SIGNATURECONFIGURATOR_H #include "kidentitymanagement_export.h" #include "signature.h" // for Signature::Type #include using KIdentityManagement::Signature; namespace KIdentityManagement { /** * This widget gives an interface so users can edit their signature. * You can set a signature via setSignature(), let the user edit the * signature and when done, read the signature back. */ class KIDENTITYMANAGEMENT_EXPORT SignatureConfigurator : public QWidget { Q_OBJECT public: /** * Constructor */ explicit SignatureConfigurator(QWidget *parent = nullptr); /** * destructor */ ~SignatureConfigurator() override; /** - * Enum for the different viemodes. + * Enum for the different viewmodes. */ enum ViewMode { ShowCode, ShowHtml }; /** * Indicated if the user wants a signature */ Q_REQUIRED_RESULT bool isSignatureEnabled() const; /** * Use this to activate the signature. */ void setSignatureEnabled(bool enable); /** * This returns the type of the signature, * so that can be Disabled, Inline, fromFile, etc. */ Q_REQUIRED_RESULT Signature::Type signatureType() const; /** * Set the signature type to @p type. */ void setSignatureType(Signature::Type type); /** * Returns the inline text, only useful * when this is the appropriate Signature::Type */ Q_REQUIRED_RESULT QString inlineText() const; /** * Make @p text the text for the signature. */ void setInlineText(const QString &text); /** * Returns the file url which the user wants * to use as a signature. */ Q_REQUIRED_RESULT QString filePath() const; /** * Set @p url for the file url part of the * widget. */ void setFileURL(const QString &url); /** * Returns the url of the command which the * users wants to use as signature. */ Q_REQUIRED_RESULT QString commandPath() const; /** * Sets @p url as the command to execute. */ void setCommandURL(const QString &url); /** - Conveniece method. + Convenience method. @return a Signature object representing the state of the widgets. **/ Q_REQUIRED_RESULT Signature signature() const; /** Convenience method. Sets the widgets according to @p sig @param sig the signature to configure **/ void setSignature(const Signature &sig); /** * Sets the directory where the images used in the HTML signature will be stored. * Needs to be called before calling setSignature(), as each signature should use * a different location. * The directory needs to exist, it will not be created. * @param path the image location to set * @since 4.4 * @sa Signature::setImageLocation */ void setImageLocation(const QString &path); /** * Sets the image location to the image location of a given identity, which is * emailidentities//. * * @param identity The identity whose unique ID will be used to determine the image * location. * @since 4.4 */ void setImageLocation(const Identity &identity); private: void slotUrlChanged(); void slotEdit(); void slotSetHtml(); //@cond PRIVATE class Private; Private *const d; //@endcond }; } #endif diff --git a/src/utils.h b/src/utils.h index 47b458db..de420a13 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,44 +1,44 @@ /* Copyright (c) 2014 Sandro Knauß This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or ( at your option ) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef KPIMIDENTITES_UTILS_H -#define KPIMIDENTITES_UTILS_H +#ifndef KPIMIDENTITIES_UTILS_H +#define KPIMIDENTITIES_UTILS_H #include "kidentitymanagement_export.h" #include #include namespace KIdentityManagement { /* * Very fast version of IdentityManager::thatIsMe, that is using an internal cache (allEmails) * - make sure that only an email address is used as parameter and NO name * - emails are tested with email.toLower(), so no need to lower them before. */ Q_REQUIRED_RESULT KIDENTITYMANAGEMENT_EXPORT bool thatIsMe(const QString &email); /* * Very fast version of IdentityManager::allEmails , that is using an internal cache. * The cache is updated with IdentityManager::changed signal. * All email addresses + alias of the identities. The email addresses are all lowered. */ Q_REQUIRED_RESULT KIDENTITYMANAGEMENT_EXPORT const QSet &allEmails(); } #endif