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"
9using namespace Qt::Literals::StringLiterals;
10
11#include "recentaddresses.h"
12
13#include <KConfig>
14#include <KLocalizedString>
15#include <KMessageBox>
16#include <QLineEdit>
17#include <QPushButton>
18
19#include <QKeyEvent>
20#include <QListWidget>
21#include <QMenu>
22#include <QShortcut>
23#include <QToolButton>
24#include <QVBoxLayout>
25
26#include <KEmailValidator>
27#include <KLineEditEventHandler>
28
29using namespace PimCommon;
30RecentAddressWidget::RecentAddressWidget(QWidget *parent)
31 : QWidget(parent)
32 , mLineEdit(new QLineEdit(this))
33 , mNewButton(new QToolButton(this))
34 , mRemoveButton(new QToolButton(this))
35 , mListView(new QListWidget(this))
36{
37 auto layout = new QVBoxLayout(this);
38
39 auto lineLayout = new QHBoxLayout;
40 layout->addLayout(lineLayout);
41
42 mLineEdit->setObjectName("line_edit"_L1);
44 mLineEdit->installEventFilter(this);
45 mLineEdit->setClearButtonEnabled(true);
46 mLineEdit->setValidator(new KEmailValidator(this));
47 mLineEdit->setPlaceholderText(i18nc("@info:placeholder", "New email..."));
48 connect(mLineEdit, &QLineEdit::returnPressed, this, &RecentAddressWidget::slotAddItem);
49
50 lineLayout->addWidget(mLineEdit);
51
52 mNewButton->setToolTip(i18nc("@info:tooltip", "Add Email"));
53 mNewButton->setObjectName("new_button"_L1);
54 mNewButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
55 mNewButton->setEnabled(false);
56 connect(mNewButton, &QPushButton::clicked, this, &RecentAddressWidget::slotAddItem);
57 connect(mLineEdit, &QLineEdit::textChanged, this, &RecentAddressWidget::slotUpdateAddButton);
58 lineLayout->addWidget(mNewButton);
59
60 mRemoveButton->setIcon(QIcon::fromTheme(QStringLiteral("list-remove")));
61 mRemoveButton->setToolTip(i18nc("@info:tooltip", "Remove"));
62 mRemoveButton->setObjectName("remove_button"_L1);
63 mRemoveButton->setEnabled(false);
64 lineLayout->addWidget(mRemoveButton);
65 connect(mRemoveButton, &QPushButton::clicked, this, &RecentAddressWidget::slotRemoveItem);
66
67 auto shortcut = new QShortcut(this);
69 connect(shortcut, &QShortcut::activated, this, &RecentAddressWidget::slotRemoveItem);
70
71 mListView->setObjectName("list_view"_L1);
72 mListView->setSelectionMode(QAbstractItemView::ExtendedSelection);
73 mListView->setSortingEnabled(true);
74 mListView->setContextMenuPolicy(Qt::CustomContextMenu);
75 connect(mListView, &QListWidget::itemSelectionChanged, this, &RecentAddressWidget::updateButtonState);
76 connect(mListView, &QListWidget::customContextMenuRequested, this, &RecentAddressWidget::slotCustomContextMenuRequested);
77 layout->addWidget(mListView);
78 mDirty = false;
79}
80
81RecentAddressWidget::~RecentAddressWidget() = default;
82
83void RecentAddressWidget::slotUpdateAddButton(const QString &str)
84{
85 mNewButton->setEnabled(!str.trimmed().isEmpty());
86}
87
88void RecentAddressWidget::slotCustomContextMenuRequested(const QPoint &pos)
89{
90 const QList<QListWidgetItem *> selectedItems = mListView->selectedItems();
91 if (selectedItems.isEmpty()) {
92 return;
93 }
94 QListWidgetItem *item = mListView->itemAt(pos);
95 if (item) {
96 QMenu menu(this);
97 menu.addAction(QIcon::fromTheme(QStringLiteral("edit-delete")),
98 i18np("Remove Email", "Remove Emails", selectedItems.count()),
99 this,
100 &RecentAddressWidget::slotRemoveItem);
101 menu.exec(QCursor::pos());
102 }
103}
104
105void RecentAddressWidget::slotAddItem()
106{
107 const QString newEmail = mLineEdit->text();
108 if (newEmail.isEmpty()) {
109 return;
110 }
111 const int numberOfItem(mListView->count());
112 for (int i = 0; i < numberOfItem; ++i) {
113 if (mListView->item(i)->text() == newEmail) {
114 return;
115 }
116 }
117
118 mListView->insertItem(0, mLineEdit->text());
120 mLineEdit->clear();
121 mLineEdit->setFocus();
122 mDirty = true;
123 updateButtonState();
124}
125
126void RecentAddressWidget::slotRemoveItem()
127{
128 const QList<QListWidgetItem *> selectedItems = mListView->selectedItems();
129 if (selectedItems.isEmpty()) {
130 return;
131 }
132 const int answer =
134 i18np("Do you want to remove this email address?", "Do you want to remove %1 email addresses?", selectedItems.count()),
135 i18nc("@title:window", "Remove"),
138 if (answer == KMessageBox::ButtonCode::PrimaryAction) {
139 for (QListWidgetItem *item : selectedItems) {
140 delete mListView->takeItem(mListView->row(item));
141 }
142 mDirty = true;
143 updateButtonState();
144 }
145}
146
147void RecentAddressWidget::updateButtonState()
148{
149 QList<QListWidgetItem *> selectedItems = mListView->selectedItems();
150 const int numberOfElementSelected(selectedItems.count());
151 mRemoveButton->setEnabled(numberOfElementSelected);
152 bool enableElement = (numberOfElementSelected <= 1);
153 mNewButton->setEnabled(enableElement);
154 mLineEdit->setEnabled(enableElement);
155}
156
157void RecentAddressWidget::setAddresses(const QStringList &addrs)
158{
159 mListView->clear();
160 mListView->addItems(addrs);
161}
162
163bool RecentAddressWidget::eventFilter(QObject *o, QEvent *e)
164{
165 if (o == mLineEdit && e->type() == QEvent::KeyPress) {
166 auto keyEvent = static_cast<QKeyEvent *>(e);
167 if (keyEvent->key() == Qt::Key_Down || keyEvent->key() == Qt::Key_Up) {
168 return (static_cast<QObject *>(mListView))->event(e);
169 }
170 }
171
172 return false;
173}
174
175void RecentAddressWidget::storeAddresses(KConfig *config)
176{
177 const int numberOfItem(mListView->count());
178 for (int i = 0; i < numberOfItem; ++i) {
179 PimCommon::RecentAddresses::self(config)->add(mListView->item(i)->text());
180 }
181}
182
183bool RecentAddressWidget::wasChanged() const
184{
185 return mDirty;
186}
187
188#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...)
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)
void setFocus()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Oct 11 2024 12:08:32 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.