File indexing completed on 2025-01-05 04:58:21
0001 /* 0002 SPDX-FileCopyrightText: 2015-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 0006 */ 0007 0008 #include "recentaddresswidget.h" 0009 #include "recentaddresses.h" 0010 0011 #include <KConfig> 0012 #include <KLocalizedString> 0013 #include <KMessageBox> 0014 #include <QLineEdit> 0015 #include <QPushButton> 0016 0017 #include <QKeyEvent> 0018 #include <QListWidget> 0019 #include <QMenu> 0020 #include <QShortcut> 0021 #include <QToolButton> 0022 #include <QVBoxLayout> 0023 0024 #include <KEmailValidator> 0025 #include <KLineEditEventHandler> 0026 0027 using namespace PimCommon; 0028 RecentAddressWidget::RecentAddressWidget(QWidget *parent) 0029 : QWidget(parent) 0030 , mLineEdit(new QLineEdit(this)) 0031 , mNewButton(new QToolButton(this)) 0032 , mRemoveButton(new QToolButton(this)) 0033 , mListView(new QListWidget(this)) 0034 { 0035 auto layout = new QVBoxLayout(this); 0036 0037 auto lineLayout = new QHBoxLayout; 0038 layout->addLayout(lineLayout); 0039 0040 mLineEdit->setObjectName(QLatin1StringView("line_edit")); 0041 KLineEditEventHandler::catchReturnKey(mLineEdit); 0042 mLineEdit->installEventFilter(this); 0043 mLineEdit->setClearButtonEnabled(true); 0044 mLineEdit->setValidator(new KEmailValidator(this)); 0045 mLineEdit->setPlaceholderText(i18n("New email...")); 0046 connect(mLineEdit, &QLineEdit::returnPressed, this, &RecentAddressWidget::slotAddItem); 0047 0048 lineLayout->addWidget(mLineEdit); 0049 0050 mNewButton->setToolTip(i18n("Add Email")); 0051 mNewButton->setObjectName(QLatin1StringView("new_button")); 0052 mNewButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); 0053 mNewButton->setEnabled(false); 0054 connect(mNewButton, &QPushButton::clicked, this, &RecentAddressWidget::slotAddItem); 0055 connect(mLineEdit, &QLineEdit::textChanged, this, &RecentAddressWidget::slotUpdateAddButton); 0056 lineLayout->addWidget(mNewButton); 0057 0058 mRemoveButton->setIcon(QIcon::fromTheme(QStringLiteral("list-remove"))); 0059 mRemoveButton->setToolTip(i18n("Remove")); 0060 mRemoveButton->setObjectName(QLatin1StringView("remove_button")); 0061 mRemoveButton->setEnabled(false); 0062 lineLayout->addWidget(mRemoveButton); 0063 connect(mRemoveButton, &QPushButton::clicked, this, &RecentAddressWidget::slotRemoveItem); 0064 0065 auto shortcut = new QShortcut(this); 0066 shortcut->setKey(QKeySequence(Qt::Key_Delete)); 0067 connect(shortcut, &QShortcut::activated, this, &RecentAddressWidget::slotRemoveItem); 0068 0069 mListView->setObjectName(QLatin1StringView("list_view")); 0070 mListView->setSelectionMode(QAbstractItemView::ExtendedSelection); 0071 mListView->setSortingEnabled(true); 0072 mListView->setContextMenuPolicy(Qt::CustomContextMenu); 0073 connect(mListView, &QListWidget::itemSelectionChanged, this, &RecentAddressWidget::updateButtonState); 0074 connect(mListView, &QListWidget::customContextMenuRequested, this, &RecentAddressWidget::slotCustomContextMenuRequested); 0075 layout->addWidget(mListView); 0076 mDirty = false; 0077 } 0078 0079 RecentAddressWidget::~RecentAddressWidget() = default; 0080 0081 void RecentAddressWidget::slotUpdateAddButton(const QString &str) 0082 { 0083 mNewButton->setEnabled(!str.trimmed().isEmpty()); 0084 } 0085 0086 void RecentAddressWidget::slotCustomContextMenuRequested(const QPoint &pos) 0087 { 0088 const QList<QListWidgetItem *> selectedItems = mListView->selectedItems(); 0089 if (selectedItems.isEmpty()) { 0090 return; 0091 } 0092 QListWidgetItem *item = mListView->itemAt(pos); 0093 if (item) { 0094 QMenu menu(this); 0095 menu.addAction(QIcon::fromTheme(QStringLiteral("edit-delete")), 0096 i18np("Remove Email", "Remove Emails", selectedItems.count()), 0097 this, 0098 &RecentAddressWidget::slotRemoveItem); 0099 menu.exec(QCursor::pos()); 0100 } 0101 } 0102 0103 void RecentAddressWidget::slotAddItem() 0104 { 0105 const QString newEmail = mLineEdit->text(); 0106 if (newEmail.isEmpty()) { 0107 return; 0108 } 0109 const int numberOfItem(mListView->count()); 0110 for (int i = 0; i < numberOfItem; ++i) { 0111 if (mListView->item(i)->text() == newEmail) { 0112 return; 0113 } 0114 } 0115 0116 mListView->insertItem(0, mLineEdit->text()); 0117 mListView->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); 0118 mLineEdit->clear(); 0119 mLineEdit->setFocus(); 0120 mDirty = true; 0121 updateButtonState(); 0122 } 0123 0124 void RecentAddressWidget::slotRemoveItem() 0125 { 0126 const QList<QListWidgetItem *> selectedItems = mListView->selectedItems(); 0127 if (selectedItems.isEmpty()) { 0128 return; 0129 } 0130 const int answer = 0131 KMessageBox::questionTwoActions(this, 0132 i18np("Do you want to remove this email address?", "Do you want to remove %1 email addresses?", selectedItems.count()), 0133 i18nc("@title:window", "Remove"), 0134 KStandardGuiItem::remove(), 0135 KStandardGuiItem::cancel()); 0136 if (answer == KMessageBox::ButtonCode::PrimaryAction) { 0137 for (QListWidgetItem *item : selectedItems) { 0138 delete mListView->takeItem(mListView->row(item)); 0139 } 0140 mDirty = true; 0141 updateButtonState(); 0142 } 0143 } 0144 0145 void RecentAddressWidget::updateButtonState() 0146 { 0147 QList<QListWidgetItem *> selectedItems = mListView->selectedItems(); 0148 const int numberOfElementSelected(selectedItems.count()); 0149 mRemoveButton->setEnabled(numberOfElementSelected); 0150 bool enableElement = (numberOfElementSelected <= 1); 0151 mNewButton->setEnabled(enableElement); 0152 mLineEdit->setEnabled(enableElement); 0153 } 0154 0155 void RecentAddressWidget::setAddresses(const QStringList &addrs) 0156 { 0157 mListView->clear(); 0158 mListView->addItems(addrs); 0159 } 0160 0161 bool RecentAddressWidget::eventFilter(QObject *o, QEvent *e) 0162 { 0163 if (o == mLineEdit && e->type() == QEvent::KeyPress) { 0164 auto keyEvent = static_cast<QKeyEvent *>(e); 0165 if (keyEvent->key() == Qt::Key_Down || keyEvent->key() == Qt::Key_Up) { 0166 return (static_cast<QObject *>(mListView))->event(e); 0167 } 0168 } 0169 0170 return false; 0171 } 0172 0173 void RecentAddressWidget::storeAddresses(KConfig *config) 0174 { 0175 const int numberOfItem(mListView->count()); 0176 for (int i = 0; i < numberOfItem; ++i) { 0177 PimCommon::RecentAddresses::self(config)->add(mListView->item(i)->text()); 0178 } 0179 } 0180 0181 bool RecentAddressWidget::wasChanged() const 0182 { 0183 return mDirty; 0184 } 0185 0186 #include "moc_recentaddresswidget.cpp"