Pimcommon

recentaddresswidget.cpp
1/*
2 SPDX-FileCopyrightText: 2015-2024 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5
6*/
7
8#include "recentaddresswidget.h"
9#include "recentaddresses.h"
10
11#include <KConfig>
12#include <KLocalizedString>
13#include <KMessageBox>
14#include <QLineEdit>
15#include <QPushButton>
16
17#include <QKeyEvent>
18#include <QListWidget>
19#include <QMenu>
20#include <QShortcut>
21#include <QToolButton>
22#include <QVBoxLayout>
23
24#include <KEmailValidator>
25#include <KLineEditEventHandler>
26
27using namespace PimCommon;
28RecentAddressWidget::RecentAddressWidget(QWidget *parent)
29 : QWidget(parent)
30 , mLineEdit(new QLineEdit(this))
31 , mNewButton(new QToolButton(this))
32 , mRemoveButton(new QToolButton(this))
33 , mListView(new QListWidget(this))
34{
35 auto layout = new QVBoxLayout(this);
36
37 auto lineLayout = new QHBoxLayout;
38 layout->addLayout(lineLayout);
39
40 mLineEdit->setObjectName(QLatin1StringView("line_edit"));
42 mLineEdit->installEventFilter(this);
43 mLineEdit->setClearButtonEnabled(true);
44 mLineEdit->setValidator(new KEmailValidator(this));
45 mLineEdit->setPlaceholderText(i18n("New email..."));
46 connect(mLineEdit, &QLineEdit::returnPressed, this, &RecentAddressWidget::slotAddItem);
47
48 lineLayout->addWidget(mLineEdit);
49
50 mNewButton->setToolTip(i18n("Add Email"));
51 mNewButton->setObjectName(QLatin1StringView("new_button"));
52 mNewButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
53 mNewButton->setEnabled(false);
54 connect(mNewButton, &QPushButton::clicked, this, &RecentAddressWidget::slotAddItem);
55 connect(mLineEdit, &QLineEdit::textChanged, this, &RecentAddressWidget::slotUpdateAddButton);
56 lineLayout->addWidget(mNewButton);
57
58 mRemoveButton->setIcon(QIcon::fromTheme(QStringLiteral("list-remove")));
59 mRemoveButton->setToolTip(i18n("Remove"));
60 mRemoveButton->setObjectName(QLatin1StringView("remove_button"));
61 mRemoveButton->setEnabled(false);
62 lineLayout->addWidget(mRemoveButton);
63 connect(mRemoveButton, &QPushButton::clicked, this, &RecentAddressWidget::slotRemoveItem);
64
65 auto shortcut = new QShortcut(this);
67 connect(shortcut, &QShortcut::activated, this, &RecentAddressWidget::slotRemoveItem);
68
69 mListView->setObjectName(QLatin1StringView("list_view"));
70 mListView->setSelectionMode(QAbstractItemView::ExtendedSelection);
71 mListView->setSortingEnabled(true);
72 mListView->setContextMenuPolicy(Qt::CustomContextMenu);
73 connect(mListView, &QListWidget::itemSelectionChanged, this, &RecentAddressWidget::updateButtonState);
74 connect(mListView, &QListWidget::customContextMenuRequested, this, &RecentAddressWidget::slotCustomContextMenuRequested);
75 layout->addWidget(mListView);
76 mDirty = false;
77}
78
79RecentAddressWidget::~RecentAddressWidget() = default;
80
81void RecentAddressWidget::slotUpdateAddButton(const QString &str)
82{
83 mNewButton->setEnabled(!str.trimmed().isEmpty());
84}
85
86void RecentAddressWidget::slotCustomContextMenuRequested(const QPoint &pos)
87{
88 const QList<QListWidgetItem *> selectedItems = mListView->selectedItems();
89 if (selectedItems.isEmpty()) {
90 return;
91 }
92 QListWidgetItem *item = mListView->itemAt(pos);
93 if (item) {
94 QMenu menu(this);
95 menu.addAction(QIcon::fromTheme(QStringLiteral("edit-delete")),
96 i18np("Remove Email", "Remove Emails", selectedItems.count()),
97 this,
98 &RecentAddressWidget::slotRemoveItem);
99 menu.exec(QCursor::pos());
100 }
101}
102
103void RecentAddressWidget::slotAddItem()
104{
105 const QString newEmail = mLineEdit->text();
106 if (newEmail.isEmpty()) {
107 return;
108 }
109 const int numberOfItem(mListView->count());
110 for (int i = 0; i < numberOfItem; ++i) {
111 if (mListView->item(i)->text() == newEmail) {
112 return;
113 }
114 }
115
116 mListView->insertItem(0, mLineEdit->text());
118 mLineEdit->clear();
119 mLineEdit->setFocus();
120 mDirty = true;
121 updateButtonState();
122}
123
124void RecentAddressWidget::slotRemoveItem()
125{
126 const QList<QListWidgetItem *> selectedItems = mListView->selectedItems();
127 if (selectedItems.isEmpty()) {
128 return;
129 }
130 const int answer =
132 i18np("Do you want to remove this email address?", "Do you want to remove %1 email addresses?", selectedItems.count()),
133 i18nc("@title:window", "Remove"),
136 if (answer == KMessageBox::ButtonCode::PrimaryAction) {
137 for (QListWidgetItem *item : selectedItems) {
138 delete mListView->takeItem(mListView->row(item));
139 }
140 mDirty = true;
141 updateButtonState();
142 }
143}
144
145void RecentAddressWidget::updateButtonState()
146{
147 QList<QListWidgetItem *> selectedItems = mListView->selectedItems();
148 const int numberOfElementSelected(selectedItems.count());
149 mRemoveButton->setEnabled(numberOfElementSelected);
150 bool enableElement = (numberOfElementSelected <= 1);
151 mNewButton->setEnabled(enableElement);
152 mLineEdit->setEnabled(enableElement);
153}
154
155void RecentAddressWidget::setAddresses(const QStringList &addrs)
156{
157 mListView->clear();
158 mListView->addItems(addrs);
159}
160
161bool RecentAddressWidget::eventFilter(QObject *o, QEvent *e)
162{
163 if (o == mLineEdit && e->type() == QEvent::KeyPress) {
164 auto keyEvent = static_cast<QKeyEvent *>(e);
165 if (keyEvent->key() == Qt::Key_Down || keyEvent->key() == Qt::Key_Up) {
166 return (static_cast<QObject *>(mListView))->event(e);
167 }
168 }
169
170 return false;
171}
172
173void RecentAddressWidget::storeAddresses(KConfig *config)
174{
175 const int numberOfItem(mListView->count());
176 for (int i = 0; i < numberOfItem; ++i) {
177 PimCommon::RecentAddresses::self(config)->add(mListView->item(i)->text());
178 }
179}
180
181bool RecentAddressWidget::wasChanged() const
182{
183 return mDirty;
184}
185
186#include "moc_recentaddresswidget.cpp"
void add(const QString &entry)
Adds an entry to the list.
static RecentAddresses * self(KConfig *config=nullptr)
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
void catchReturnKey(QObject *lineEdit)
ButtonCode questionTwoActions(QWidget *parent, const QString &text, const QString &title, const KGuiItem &primaryAction, const KGuiItem &secondaryAction, const QString &dontAskAgainName=QString(), Options options=Notify)
KGuiItem remove()
KGuiItem cancel()
const QList< QKeySequence > & shortcut(StandardShortcut id)
folderdialogacltab.h
void clicked(bool checked)
void addLayout(QLayout *layout, int stretch)
QPoint pos()
Type type() const const
QIcon fromTheme(const QString &name)
void clear()
void returnPressed()
void textChanged(const QString &text)
qsizetype count() const const
bool isEmpty() const const
void addItems(const QStringList &labels)
void clear()
void setCurrentRow(int row)
void insertItem(int row, QListWidgetItem *item)
QListWidgetItem * item(int row) const const
QListWidgetItem * itemAt(const QPoint &p) const const
void itemSelectionChanged()
int row(const QListWidgetItem *item) const const
QList< QListWidgetItem * > selectedItems() const const
QListWidgetItem * takeItem(int row)
QString text() const const
void activated()
bool isEmpty() const const
QString trimmed() const const
CustomContextMenu
Key_Delete
void keyEvent(KeyAction action, QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier, int delay)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void customContextMenuRequested(const QPoint &pos)
void setEnabled(bool)
virtual bool event(QEvent *event) override
void setFocus()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:17:23 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.