File indexing completed on 2024-06-23 05:18:37

0001 /*
0002     SPDX-FileCopyrightText: 2010 Volker Krause <vkrause@kde.org>
0003     This file was part of KMail.
0004     SPDX-FileCopyrightText: 2005 Cornelius Schumacher <schumacher@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "recipientspicker.h"
0010 #include "settings/messagecomposersettings.h"
0011 
0012 #include <Akonadi/EmailAddressSelectionWidget>
0013 #include <Akonadi/RecipientsPickerWidget>
0014 #include <KContacts/ContactGroup>
0015 #include <PimCommonAkonadi/LdapSearchDialog>
0016 
0017 #include "messagecomposer_debug.h"
0018 #include <KConfigGroup>
0019 #include <KLocalizedString>
0020 #include <KMessageBox>
0021 #include <KWindowConfig>
0022 #include <QLineEdit>
0023 #include <QPushButton>
0024 #include <QWindow>
0025 
0026 #include <KSharedConfig>
0027 #include <QDialogButtonBox>
0028 #include <QKeyEvent>
0029 #include <QLabel>
0030 #include <QTreeView>
0031 #include <QVBoxLayout>
0032 
0033 using namespace MessageComposer;
0034 namespace
0035 {
0036 static const char myRecipientsPickerConfigGroupName[] = "RecipientsPicker";
0037 }
0038 RecipientsPicker::RecipientsPicker(QWidget *parent)
0039     : QDialog(parent)
0040     , mView(new Akonadi::RecipientsPickerWidget(true, nullptr, this))
0041     , mSelectedLabel(new QLabel(this))
0042 {
0043     setObjectName(QLatin1StringView("RecipientsPicker"));
0044     setWindowTitle(i18nc("@title:window", "Select Recipient"));
0045 
0046     auto mainLayout = new QVBoxLayout(this);
0047 
0048     mainLayout->addWidget(mView);
0049     mainLayout->setStretchFactor(mView, 1);
0050 
0051     connect(mView->view()->selectionModel(), &QItemSelectionModel::selectionChanged, this, &RecipientsPicker::slotSelectionChanged);
0052     connect(mView->view(), &QAbstractItemView::doubleClicked, this, &RecipientsPicker::slotPicked);
0053 
0054     mainLayout->addWidget(mSelectedLabel);
0055 
0056     auto searchLDAPButton = new QPushButton(i18n("Search &Directory Service"), this);
0057     connect(searchLDAPButton, &QPushButton::clicked, this, &RecipientsPicker::slotSearchLDAP);
0058     mainLayout->addWidget(searchLDAPButton);
0059 
0060     KConfig config(QStringLiteral("kabldaprc"));
0061     KConfigGroup group = config.group(QStringLiteral("LDAP"));
0062     int numHosts = group.readEntry("NumSelectedHosts", 0);
0063     if (!numHosts) {
0064         searchLDAPButton->setVisible(false);
0065     }
0066 
0067     auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, this);
0068     mUser1Button = new QPushButton(this);
0069     buttonBox->addButton(mUser1Button, QDialogButtonBox::ActionRole);
0070     mUser2Button = new QPushButton(this);
0071     buttonBox->addButton(mUser2Button, QDialogButtonBox::ActionRole);
0072     mUser3Button = new QPushButton(this);
0073     buttonBox->addButton(mUser3Button, QDialogButtonBox::ActionRole);
0074     mUser4Button = new QPushButton(this);
0075     buttonBox->addButton(mUser4Button, QDialogButtonBox::ActionRole);
0076 
0077     connect(buttonBox, &QDialogButtonBox::rejected, this, &RecipientsPicker::reject);
0078     mainLayout->addWidget(buttonBox);
0079     mUser4Button->setText(i18n("Add as &Reply-To"));
0080     mUser3Button->setText(i18n("Add as &To"));
0081     mUser2Button->setText(i18n("Add as CC"));
0082     mUser1Button->setText(i18n("Add as &BCC"));
0083     connect(mUser1Button, &QPushButton::clicked, this, &RecipientsPicker::slotBccClicked);
0084     connect(mUser2Button, &QPushButton::clicked, this, &RecipientsPicker::slotCcClicked);
0085     connect(mUser3Button, &QPushButton::clicked, this, &RecipientsPicker::slotToClicked);
0086     connect(mUser4Button, &QPushButton::clicked, this, &RecipientsPicker::slotReplyToClicked);
0087 
0088     mView->emailAddressSelectionWidget()->searchLineEdit()->setFocus();
0089 
0090     readConfig();
0091 
0092     slotSelectionChanged();
0093 }
0094 
0095 RecipientsPicker::~RecipientsPicker()
0096 {
0097     writeConfig();
0098 }
0099 
0100 void RecipientsPicker::updateLabel(int nbSelected)
0101 {
0102     if (nbSelected == 0) {
0103         mSelectedLabel->setText({});
0104     } else {
0105         mSelectedLabel->setText(i18np("%1 selected email", "%1 selected emails", nbSelected));
0106     }
0107 }
0108 
0109 void RecipientsPicker::slotSelectionChanged()
0110 {
0111     const auto selectedItems{mView->emailAddressSelectionWidget()->selectedAddresses().count()};
0112     const bool hasSelection = (selectedItems != 0);
0113     mUser1Button->setEnabled(hasSelection);
0114     mUser2Button->setEnabled(hasSelection);
0115     mUser3Button->setEnabled(hasSelection);
0116     mUser4Button->setEnabled(hasSelection);
0117     updateLabel(selectedItems);
0118 }
0119 
0120 void RecipientsPicker::setRecipients(const Recipient::List &)
0121 {
0122     mView->view()->selectionModel()->clear();
0123 }
0124 
0125 void RecipientsPicker::setDefaultType(Recipient::Type type)
0126 {
0127     mDefaultType = type;
0128     mUser1Button->setDefault(type == Recipient::Bcc);
0129     mUser2Button->setDefault(type == Recipient::Cc);
0130     mUser3Button->setDefault(type == Recipient::To);
0131     mUser4Button->setDefault(type == Recipient::ReplyTo);
0132 }
0133 
0134 void RecipientsPicker::slotToClicked()
0135 {
0136     pick(Recipient::To);
0137 }
0138 
0139 void RecipientsPicker::slotReplyToClicked()
0140 {
0141     pick(Recipient::ReplyTo);
0142 }
0143 
0144 void RecipientsPicker::slotCcClicked()
0145 {
0146     pick(Recipient::Cc);
0147 }
0148 
0149 void RecipientsPicker::slotBccClicked()
0150 {
0151     pick(Recipient::Bcc);
0152 }
0153 
0154 void RecipientsPicker::slotPicked()
0155 {
0156     pick(mDefaultType);
0157 }
0158 
0159 void RecipientsPicker::pick(Recipient::Type type)
0160 {
0161     qCDebug(MESSAGECOMPOSER_LOG) << int(type);
0162 
0163     const Akonadi::EmailAddressSelection::List selections = mView->emailAddressSelectionWidget()->selectedAddresses();
0164 
0165     const int count = selections.count();
0166     if (count == 0) {
0167         return;
0168     }
0169 
0170     if (count > MessageComposerSettings::self()->maximumRecipients()) {
0171         KMessageBox::error(this,
0172                            i18np("You selected 1 recipient. The maximum supported number of "
0173                                  "recipients is %2.\nPlease adapt the selection.",
0174                                  "You selected %1 recipients. The maximum supported number of "
0175                                  "recipients is %2.\nPlease adapt the selection.",
0176                                  count,
0177                                  MessageComposerSettings::self()->maximumRecipients()));
0178         return;
0179     }
0180 
0181     bool tooManyAddress = false;
0182     for (const Akonadi::EmailAddressSelection &selection : selections) {
0183         Recipient recipient;
0184         recipient.setType(type);
0185         recipient.setEmail(selection.quotedEmail());
0186 
0187         Q_EMIT pickedRecipient(recipient, tooManyAddress);
0188         if (tooManyAddress) {
0189             KMessageBox::error(this, i18n("You can not add more recipients."));
0190             break;
0191         }
0192     }
0193 }
0194 
0195 void RecipientsPicker::keyPressEvent(QKeyEvent *event)
0196 {
0197     if (event->key() == Qt::Key_Escape) {
0198         close();
0199     }
0200 
0201     QDialog::keyPressEvent(event);
0202 }
0203 
0204 void RecipientsPicker::readConfig()
0205 {
0206     create(); // ensure a window is created
0207     windowHandle()->resize(QSize(300, 200));
0208     KConfigGroup group(KSharedConfig::openStateConfig(), QLatin1StringView(myRecipientsPickerConfigGroupName));
0209     KWindowConfig::restoreWindowSize(windowHandle(), group);
0210     resize(windowHandle()->size()); // workaround for QTBUG-40584
0211 }
0212 
0213 void RecipientsPicker::writeConfig()
0214 {
0215     KConfigGroup group(KSharedConfig::openStateConfig(), QLatin1StringView(myRecipientsPickerConfigGroupName));
0216     KWindowConfig::saveWindowSize(windowHandle(), group);
0217 }
0218 
0219 void RecipientsPicker::slotSearchLDAP()
0220 {
0221     if (!mLdapSearchDialog) {
0222         mLdapSearchDialog = new PimCommon::LdapSearchDialog(this);
0223         connect(mLdapSearchDialog, &PimCommon::LdapSearchDialog::contactsAdded, this, &RecipientsPicker::ldapSearchResult);
0224     }
0225 
0226     mLdapSearchDialog->setSearchText(mView->emailAddressSelectionWidget()->searchLineEdit()->text());
0227     mLdapSearchDialog->show();
0228 }
0229 
0230 void RecipientsPicker::ldapSearchResult()
0231 {
0232     const KContacts::Addressee::List contacts = mLdapSearchDialog->selectedContacts();
0233     for (const KContacts::Addressee &contact : contacts) {
0234         bool tooManyAddress = false;
0235         Q_EMIT pickedRecipient(Recipient(contact.fullEmail(), Recipient::Undefined), tooManyAddress);
0236         if (tooManyAddress) {
0237             break;
0238         }
0239     }
0240 }
0241 
0242 #include "moc_recipientspicker.cpp"