1 /*
2 encodedimagepicker.cpp
3
4 KMail, the KDE mail client.
5 SPDX-FileCopyrightText: 2021 the KMail authors.
6 See file AUTHORS for details
7
8 SPDX-License-Identifier: GPL-2.0-only
9 */
10
11 #include "encodedimagepicker.h"
12 #include "ui_encodedimagepicker.h"
13
14 #include <Akonadi/Contact/ContactSearchJob>
15 #include <KIdentityManagement/Identity>
16 #include <KIdentityManagement/IdentityManager>
17 #include <KPIMTextEdit/PlainTextEditor>
18
19 #include <KIO/StoredTransferJob>
20 #include <KJobWidgets>
21 #include <KLocalizedString>
22 #include <KMessageBox>
23
24 #include <QFileDialog>
25 #include <QImageReader>
26
27 using namespace KMail;
28 using KContacts::Addressee;
29
EncodedImagePicker(QWidget * parent)30 EncodedImagePicker::EncodedImagePicker(QWidget *parent)
31 : QGroupBox(parent)
32 , mUi(new Ui::EncodedImagePicker)
33 {
34 mUi->setupUi(this);
35
36 mUi->source->editor()->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
37
38 // wrap anywhere, these contain encoded data
39 mUi->source->editor()->setWordWrapMode(QTextOption::WrapAnywhere);
40
41 connect(mUi->openImageButton, &QAbstractButton::clicked, this, &EncodedImagePicker::selectFile);
42 connect(mUi->selectContactsButton, &QPushButton::released, this, &EncodedImagePicker::selectFromAddressBook);
43 connect(mUi->source->editor(), &KPIMTextEdit::PlainTextEditor::textChanged, this, &EncodedImagePicker::sourceChanged);
44 }
45
46 EncodedImagePicker::~EncodedImagePicker() = default;
47
setInfo(const QString & info)48 void EncodedImagePicker::setInfo(const QString &info)
49 {
50 mUi->infoLabel->setText(info);
51 }
52
source() const53 QString EncodedImagePicker::source() const
54 {
55 return mUi->source->editor()->toPlainText();
56 }
57
setSource(const QString & source)58 void EncodedImagePicker::setSource(const QString &source)
59 {
60 mUi->source->editor()->setPlainText(source);
61 }
62
setImage(const QImage & image)63 void EncodedImagePicker::setImage(const QImage &image)
64 {
65 if (image.isNull()) {
66 mUi->image->clear();
67 } else {
68 const QPixmap p = QPixmap::fromImage(image);
69 mUi->image->setPixmap(p);
70 }
71 }
72
selectFile()73 void EncodedImagePicker::selectFile()
74 {
75 QString filter;
76 const QList<QByteArray> supportedImage = QImageReader::supportedImageFormats();
77 for (const QByteArray &ba : supportedImage) {
78 if (!filter.isEmpty()) {
79 filter += QLatin1Char(' ');
80 }
81 filter += QLatin1String("*.") + QString::fromLatin1(ba);
82 }
83
84 filter = QStringLiteral("%1 (%2)").arg(i18n("Image"), filter);
85 const QUrl url = QFileDialog::getOpenFileUrl(this, QString(), QUrl(), filter);
86
87 if (!url.isEmpty()) {
88 setFromFile(url);
89 }
90 }
91
setFromFile(const QUrl & url)92 void EncodedImagePicker::setFromFile(const QUrl &url)
93 {
94 auto job = KIO::storedGet(url);
95 KJobWidgets::setWindow(job, this);
96 connect(job, &KJob::result, this, &EncodedImagePicker::setFromFileDone);
97 job->start();
98 }
99
setFromFileDone(KJob * job)100 void EncodedImagePicker::setFromFileDone(KJob *job)
101 {
102 const KIO::StoredTransferJob *kioJob = qobject_cast<KIO::StoredTransferJob *>(job);
103
104 if (kioJob->error() == 0) {
105 const QImage image = QImage::fromData(kioJob->data());
106
107 Q_EMIT imageSelected(image);
108 } else {
109 KMessageBox::error(this, kioJob->errorString());
110 }
111 }
112
selectFromAddressBook()113 void EncodedImagePicker::selectFromAddressBook()
114 {
115 using namespace KIdentityManagement;
116
117 const IdentityManager manager(true);
118 const Identity defaultIdentity = manager.defaultIdentity();
119 const QString email = defaultIdentity.primaryEmailAddress().toLower();
120
121 auto job = new Akonadi::ContactSearchJob(this);
122 job->setLimit(1);
123 job->setQuery(Akonadi::ContactSearchJob::Email, email, Akonadi::ContactSearchJob::ExactMatch);
124 connect(job, &KJob::result, this, &EncodedImagePicker::selectFromAddressBookDone);
125 }
126
selectFromAddressBookDone(KJob * job)127 void EncodedImagePicker::selectFromAddressBookDone(KJob *job)
128 {
129 const Akonadi::ContactSearchJob *searchJob = qobject_cast<Akonadi::ContactSearchJob *>(job);
130
131 if (searchJob->contacts().isEmpty()) {
132 KMessageBox::information(this, i18n("You do not have your own contact defined in the address book."), i18n("No Picture"));
133 return;
134 }
135
136 const Addressee contact = searchJob->contacts().at(0);
137
138 if (contact.photo().isIntern()) {
139 const QImage photo = contact.photo().data();
140
141 if (photo.isNull()) {
142 KMessageBox::information(this, i18n("No picture set for your address book entry."), i18n("No Picture"));
143 } else {
144 Q_EMIT imageSelected(photo);
145 }
146 } else {
147 const QUrl url(contact.photo().url());
148
149 if (url.isEmpty()) {
150 KMessageBox::information(this, i18n("No picture set for your address book entry."), i18n("No Picture"));
151 } else {
152 setFromFile(url);
153 }
154 }
155 }
156