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

0001 /*
0002     SPDX-FileCopyrightText: 2010 Casey Link <unnamedrambler@gmail.com>
0003     SPDX-FileCopyrightText: 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "recipientline.h"
0009 
0010 #include <KEmailAddress>
0011 #include <KLocalizedString>
0012 
0013 #include <QHBoxLayout>
0014 #include <QKeyEvent>
0015 
0016 using namespace MessageComposer;
0017 using namespace KPIM;
0018 
0019 RecipientComboBox::RecipientComboBox(QWidget *parent)
0020     : QComboBox(parent)
0021 {
0022 }
0023 
0024 void RecipientComboBox::keyPressEvent(QKeyEvent *ev)
0025 {
0026     if (ev->key() == Qt::Key_Right) {
0027         Q_EMIT rightPressed();
0028     } else {
0029         QComboBox::keyPressEvent(ev);
0030     }
0031 }
0032 
0033 RecipientLineEdit::RecipientLineEdit(QWidget *parent)
0034     : ComposerLineEdit(parent)
0035 {
0036     setExpandIntern(false);
0037 }
0038 
0039 void RecipientLineEdit::keyPressEvent(QKeyEvent *ev)
0040 {
0041     // Laurent Bug:280153
0042     /*if ( ev->key() == Qt::Key_Backspace  &&  text().isEmpty() ) {
0043     ev->accept();
0044     Q_EMIT deleteMe();
0045     } else */
0046     if (ev->key() == Qt::Key_Left && cursorPosition() == 0 && !ev->modifiers().testFlag(Qt::ShiftModifier)) { // Shift would be pressed during selection
0047         Q_EMIT leftPressed();
0048     } else if (ev->key() == Qt::Key_Right && cursorPosition() == text().length()
0049                && !ev->modifiers().testFlag(Qt::ShiftModifier)) { // Shift would be pressed during selection
0050         Q_EMIT rightPressed();
0051     } else {
0052         MessageComposer::ComposerLineEdit::keyPressEvent(ev);
0053     }
0054 }
0055 
0056 RecipientLineNG::RecipientLineNG(QWidget *parent)
0057     : MultiplyingLine(parent)
0058     , mData(new Recipient)
0059 {
0060     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
0061 
0062     auto topLayout = new QHBoxLayout(this);
0063     topLayout->setContentsMargins({});
0064 
0065     const QStringList recipientTypes = Recipient::allTypeLabels();
0066 
0067     mCombo = new RecipientComboBox(this);
0068     mCombo->addItems(recipientTypes);
0069     topLayout->addWidget(mCombo);
0070     mCombo->setToolTip(i18nc("@label:listbox", "Select type of recipient"));
0071     mEdit = new RecipientLineEdit(this);
0072     mEdit->setToolTip(i18n("Set the list of email addresses to receive this message"));
0073     mEdit->setClearButtonEnabled(true);
0074     topLayout->addWidget(mEdit);
0075     mEdit->installEventFilter(this);
0076 
0077     connect(mEdit, &RecipientLineEdit::returnPressed, this, &RecipientLineNG::slotReturnPressed);
0078     connect(mEdit, &RecipientLineEdit::deleteMe, this, &RecipientLineNG::slotPropagateDeletion);
0079     connect(mEdit, &QLineEdit::textChanged, this, &RecipientLineNG::analyzeLine);
0080     connect(mEdit, &RecipientLineEdit::focusUp, this, &RecipientLineNG::slotFocusUp);
0081     connect(mEdit, &RecipientLineEdit::focusDown, this, &RecipientLineNG::slotFocusDown);
0082     connect(mEdit, &RecipientLineEdit::rightPressed, this, &RecipientLineNG::rightPressed);
0083     connect(mEdit, &RecipientLineEdit::iconClicked, this, &RecipientLineNG::iconClicked);
0084 
0085     connect(mEdit, &RecipientLineEdit::leftPressed, mCombo, qOverload<>(&QWidget::setFocus));
0086     connect(mEdit, &RecipientLineEdit::editingFinished, this, &RecipientLineNG::slotEditingFinished);
0087     connect(mEdit, &RecipientLineEdit::clearButtonClicked, this, &RecipientLineNG::slotPropagateDeletion);
0088     connect(mCombo, &RecipientComboBox::rightPressed, mEdit, qOverload<>(&QWidget::setFocus));
0089 
0090     connect(mCombo, &RecipientComboBox::activated, this, &RecipientLineNG::slotTypeModified);
0091 
0092     connect(mEdit, &RecipientLineEdit::addAddress, this, &RecipientLineNG::slotAddRecipient);
0093 }
0094 
0095 void RecipientLineNG::slotEditingFinished()
0096 {
0097     if (mEdit->text().isEmpty()) {
0098         Q_EMIT deleteLine(this);
0099     }
0100 }
0101 
0102 void RecipientLineNG::slotAddRecipient(const QString &email)
0103 {
0104     Q_EMIT addRecipient(this, email);
0105     slotReturnPressed();
0106 }
0107 
0108 void RecipientLineNG::slotTypeModified()
0109 {
0110     mModified = true;
0111 
0112     Q_EMIT typeModified(this);
0113 }
0114 
0115 void RecipientLineNG::analyzeLine(const QString &text)
0116 {
0117     const QStringList r = KEmailAddress::splitAddressList(text);
0118     mRecipientsCount = r.count();
0119     mModified = true;
0120     Q_EMIT countChanged();
0121 }
0122 
0123 int RecipientLineNG::recipientsCount() const
0124 {
0125     return mRecipientsCount;
0126 }
0127 
0128 void RecipientLineNG::setData(const MultiplyingLineData::Ptr &data)
0129 {
0130     Recipient::Ptr rec = qSharedPointerDynamicCast<Recipient>(data);
0131     if (rec.isNull()) {
0132         return;
0133     }
0134     mData = rec;
0135     fieldsFromData();
0136 }
0137 
0138 MultiplyingLineData::Ptr RecipientLineNG::data() const
0139 {
0140     if (isModified()) {
0141         const_cast<RecipientLineNG *>(this)->dataFromFields();
0142     }
0143     return mData;
0144 }
0145 
0146 void RecipientLineNG::dataFromFields()
0147 {
0148     if (!mData) {
0149         return;
0150     }
0151     const QString editStr(mEdit->text());
0152     QString displayName;
0153     QString addrSpec;
0154     QString comment;
0155     if (KEmailAddress::splitAddress(editStr, displayName, addrSpec, comment) == KEmailAddress::AddressOk) {
0156         mData->setName(displayName);
0157     }
0158     mData->setEmail(editStr);
0159     mData->setType(Recipient::idToType(mCombo->currentIndex()));
0160     mModified = false;
0161 }
0162 
0163 void RecipientLineNG::fieldsFromData()
0164 {
0165     if (!mData) {
0166         return;
0167     }
0168     mCombo->setCurrentIndex(Recipient::typeToId(mData->type()));
0169     mEdit->setText(mData->email());
0170 }
0171 
0172 void RecipientLineNG::activate()
0173 {
0174     mEdit->setFocus();
0175 }
0176 
0177 bool RecipientLineNG::isActive() const
0178 {
0179     return mEdit->hasFocus();
0180 }
0181 
0182 bool RecipientLineNG::isEmpty() const
0183 {
0184     return mEdit->text().isEmpty();
0185 }
0186 
0187 bool RecipientLineNG::isModified() const
0188 {
0189     return mModified || mEdit->isModified();
0190 }
0191 
0192 void RecipientLineNG::clearModified()
0193 {
0194     mModified = false;
0195     mEdit->setModified(false);
0196 }
0197 
0198 int RecipientLineNG::setColumnWidth(int w)
0199 {
0200     w = qMax(w, mCombo->sizeHint().width());
0201     mCombo->setFixedWidth(w);
0202     mCombo->updateGeometry();
0203     parentWidget()->updateGeometry();
0204     return w;
0205 }
0206 
0207 void RecipientLineNG::fixTabOrder(QWidget *previous)
0208 {
0209     setTabOrder(previous, mCombo);
0210     setTabOrder(mCombo, mEdit);
0211 }
0212 
0213 QWidget *RecipientLineNG::tabOut() const
0214 {
0215     return mEdit;
0216 }
0217 
0218 void RecipientLineNG::clear()
0219 {
0220     mRecipientsCount = 0;
0221     mEdit->clear();
0222 }
0223 
0224 bool RecipientLineNG::canDeleteLineEdit() const
0225 {
0226     return mEdit->canDeleteLineEdit();
0227 }
0228 
0229 void RecipientLineNG::setCompletionMode(KCompletion::CompletionMode mode)
0230 {
0231     mEdit->setCompletionMode(mode);
0232 }
0233 
0234 Recipient::Type RecipientLineNG::recipientType() const
0235 {
0236     return Recipient::idToType(mCombo->currentIndex());
0237 }
0238 
0239 void RecipientLineNG::setRecipientType(Recipient::Type type)
0240 {
0241     mCombo->setCurrentIndex(Recipient::typeToId(type));
0242     slotTypeModified();
0243 }
0244 
0245 void RecipientLineNG::setRecentAddressConfig(KConfig *config)
0246 {
0247     mEdit->setRecentAddressConfig(config);
0248 }
0249 
0250 Recipient::Ptr RecipientLineNG::recipient() const
0251 {
0252     return qSharedPointerDynamicCast<Recipient>(data());
0253 }
0254 
0255 void RecipientLineNG::setIcon(const QIcon &icon, const QString &tooltip)
0256 {
0257     mEdit->setIcon(icon, tooltip);
0258 }
0259 
0260 void RecipientLineNG::setEnableIndexSearch(bool enableIndexSearch)
0261 {
0262     mEdit->setEnableBalooSearch(enableIndexSearch);
0263 }
0264 
0265 bool RecipientLineNG::enableIndexSearch() const
0266 {
0267     return mEdit->enableBalooSearch();
0268 }
0269 
0270 void RecipientLineNG::setEnableAkonadiSearch(bool enableAkonadiSearch)
0271 {
0272     mEdit->setEnableAkonadiSearch(enableAkonadiSearch);
0273 }
0274 
0275 bool RecipientLineNG::enableAkonadiSearch() const
0276 {
0277     return mEdit->enableAkonadiSearch();
0278 }
0279 
0280 QString RecipientLineNG::rawData() const
0281 {
0282     return mEdit->text();
0283 }
0284 
0285 bool RecipientLineNG::eventFilter(QObject *watched, QEvent *event)
0286 {
0287     if (watched == mEdit) {
0288         if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut) {
0289             Q_EMIT activeChanged();
0290         }
0291     }
0292 
0293     return false;
0294 }
0295 
0296 #include "moc_recipientline.cpp"