Akonadi Contacts

emailaddressselectionwidget.cpp
1/*
2 This file is part of Akonadi Contact.
3
4 SPDX-FileCopyrightText: 2010 KDAB
5 SPDX-FileContributor: Tobias Koenig <tokoe@kde.org>
6
7 SPDX-License-Identifier: LGPL-2.0-or-later
8*/
9
10#include "emailaddressselectionwidget.h"
11
12#include "emailaddressselection_p.h"
13#include "emailaddressselectionmodel.h"
14#include "emailaddressselectionproxymodel_p.h"
15
16#include "contactsfilterproxymodel.h"
17#include "contactstreemodel.h"
18#include <Akonadi/ChangeRecorder>
19#include <Akonadi/ControlGui>
20#include <Akonadi/EntityDisplayAttribute>
21#include <Akonadi/EntityTreeView>
22#include <Akonadi/ItemFetchScope>
23#include <Akonadi/Session>
24#include <KLocalizedString>
25
26#include <QHBoxLayout>
27#include <QHeaderView>
28#include <QKeyEvent>
29#include <QLabel>
30#include <QLineEdit>
31#include <QTimer>
32#include <QVBoxLayout>
33using namespace Akonadi;
34using namespace Akonadi;
35/**
36 * @internal
37 */
38class SearchLineEdit : public QLineEdit
39{
41public:
42 SearchLineEdit(QWidget *receiver, QWidget *parent = nullptr)
44 , mReceiver(receiver)
45 {
48 }
49
50protected:
51 void keyPressEvent(QKeyEvent *event) override
52 {
53 if (event->key() == Qt::Key_Down) {
54 QMetaObject::invokeMethod(mReceiver, "setFocus");
55 }
56
58 }
59 bool eventFilter(QObject *obj, QEvent *event) override
60 {
61 if (obj == this) {
62 if (event->type() == QEvent::KeyPress) {
63 auto e = static_cast<QKeyEvent *>(event);
64 if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
65 const bool stopEvent = (e->modifiers() == Qt::NoButton || e->modifiers() == Qt::KeypadModifier);
66 if (stopEvent) {
68 }
69 return true;
70 }
71 }
72 }
73 return QObject::eventFilter(obj, event);
74 }
75
76private:
77 QWidget *const mReceiver;
78};
79
80/**
81 * @internal
82 */
83class Akonadi::EmailAddressSelectionWidgetPrivate
84{
85public:
86 EmailAddressSelectionWidgetPrivate(bool showOnlyContactWithEmail, EmailAddressSelectionWidget *qq, QAbstractItemModel *model)
87 : q(qq)
88 , mModel(model)
89 , mShowOnlyContactWithEmail(showOnlyContactWithEmail)
90 {
91 init();
92 }
93
94 void init();
95
97 QAbstractItemModel *mModel = nullptr;
98 QLabel *mDescriptionLabel = nullptr;
99 SearchLineEdit *mSearchLine = nullptr;
100 Akonadi::EntityTreeView *mView = nullptr;
101 EmailAddressSelectionProxyModel *mSelectionModel = nullptr;
102 bool mShowOnlyContactWithEmail = false;
103};
104
105void EmailAddressSelectionWidgetPrivate::init()
106{
107 // setup internal model if needed
108 if (!mModel) {
109 auto model = new Akonadi::EmailAddressSelectionModel(q);
110 mModel = model->model();
111 }
112
113 // setup ui
114 auto layout = new QVBoxLayout(q);
115 layout->setContentsMargins({});
116
117 mDescriptionLabel = new QLabel;
118 mDescriptionLabel->hide();
119 layout->addWidget(mDescriptionLabel);
120
121 auto searchLayout = new QHBoxLayout;
122 searchLayout->setContentsMargins({});
123 layout->addLayout(searchLayout);
124
125 mView = new Akonadi::EntityTreeView;
127
128 auto label = new QLabel(i18nc("@label Search in a list of contacts", "Search:"));
129 mSearchLine = new SearchLineEdit(mView);
130 mSearchLine->setPlaceholderText(i18nc("@info:placeholder", "Search Contact..."));
131 label->setBuddy(mSearchLine);
132 searchLayout->addWidget(label);
133 searchLayout->addWidget(mSearchLine);
134
135#ifndef QT_NO_DRAGANDDROP
137#endif
138 layout->addWidget(mView);
139
141 if (mShowOnlyContactWithEmail) {
142 filter->setFilterFlags(ContactsFilterProxyModel::HasEmail);
143 }
144 filter->setMatchFilterContactFlag(ContactsFilterProxyModel::MatchFilterContactFlag::OnlyNameAndEmailsAddresses);
145 filter->setExcludeVirtualCollections(true);
146 filter->setSourceModel(mModel);
147
148 mSelectionModel = new EmailAddressSelectionProxyModel(q);
149 mSelectionModel->setSourceModel(filter);
150
151 mView->setModel(mSelectionModel);
152 mView->header()->hide();
153
155
156 q->connect(mView, qOverload<const Akonadi::Item &>(&Akonadi::EntityTreeView::doubleClicked), q, [this]() {
157 Q_EMIT q->doubleClicked();
158 });
160
161 mSearchLine->setFocus();
162
163 if (auto etm = qobject_cast<Akonadi::EntityTreeModel *>(mModel)) {
165 } else {
167 }
168}
169
171 : QWidget(parent)
172 , d(new EmailAddressSelectionWidgetPrivate(true, this, nullptr))
173{
174}
175
177 : QWidget(parent)
178 , d(new EmailAddressSelectionWidgetPrivate(true, this, model))
179{
180}
181
183 : QWidget(parent)
184 , d(new EmailAddressSelectionWidgetPrivate(showOnlyContactWithEmail, this, model))
185{
186}
187
189
191{
193
194 if (!d->mView->selectionModel()) {
195 return selections;
196 }
197
198 const QModelIndexList selectedRows = d->mView->selectionModel()->selectedRows(0);
199 for (const QModelIndex &index : selectedRows) {
200 EmailAddressSelection selection;
201 selection.setName(index.data(EmailAddressSelectionProxyModel::NameRole).toString());
202 selection.setEmail(index.data(EmailAddressSelectionProxyModel::EmailAddressRole).toString());
203 selection.setItem(index.data(ContactsTreeModel::ItemRole).value<Akonadi::Item>());
204
205 if (d->mShowOnlyContactWithEmail) {
206 if (!selection.email().isEmpty()) {
207 selections << selection;
208 }
209 } else {
210 selections << selection;
211 }
212 }
213
214 return selections;
215}
216
218{
219 return d->mSearchLine;
220}
221
223{
224 return d->mView;
225}
226
227#include "emailaddressselectionwidget.moc"
228
229#include "moc_emailaddressselectionwidget.cpp"
A proxy model for ContactsTreeModel models.
void setFilterString(const QString &filter)
Sets the filter that is used to filter for matching contacts and contact groups.
static void widgetNeedsAkonadi(QWidget *widget)
A widget to select email addresses from Akonadi.
~EmailAddressSelectionWidget() override
Destroys the email address selection widget.
QLineEdit * searchLineEdit() const
Returns the line edit that is used for the search line.
EmailAddressSelectionWidget(QWidget *parent=nullptr)
Creates a new email address selection widget.
Akonadi::EmailAddressSelection::List selectedAddresses() const
Returns the list of selected email addresses.
QTreeView * view() const
Returns the tree view that is used to list the items.
An selection of an email address and corresponding name.
QString email() const
Returns the address part of the selected email address.
void collectionTreeFetched(const Akonadi::Collection::List &collections)
void doubleClicked(const Akonadi::Collection &collection)
void setModel(QAbstractItemModel *model) override
QString i18nc(const char *context, const char *text, const TYPE &arg...)
A widget for editing the display name of a contact.
QString label(StandardShortcut id)
void setDragDropMode(DragDropMode behavior)
void setEditTriggers(EditTriggers triggers)
void setContentsMargins(const QMargins &margins)
void setClearButtonEnabled(bool enable)
virtual bool event(QEvent *e) override
virtual void keyPressEvent(QKeyEvent *event) override
void setPlaceholderText(const QString &)
void returnPressed()
void textChanged(const QString &text)
bool invokeMethod(QObject *context, Functor &&function, FunctorReturnType *ret)
Q_EMITQ_EMIT
Q_OBJECTQ_OBJECT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
virtual bool eventFilter(QObject *watched, QEvent *event)
void installEventFilter(QObject *filterObj)
QObject * parent() const const
bool isEmpty() const const
Key_Down
KeypadModifier
NoButton
QFuture< void > filter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&filterFunction)
void expandAll()
QHeaderView * header() const const
void hide()
void setFocus()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:08:08 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.