Akonadi Contacts

contactgroupviewer.cpp
1 /*
2  This file is part of Akonadi Contact.
3 
4  SPDX-FileCopyrightText: 2009 Tobias Koenig <[email protected]>
5 
6  SPDX-License-Identifier: LGPL-2.0-or-later
7 */
8 
9 #include "contactgroupviewer.h"
10 
11 #include "job/contactgroupexpandjob.h"
12 #include "standardcontactgroupformatter.h"
13 #include "textbrowser_p.h"
14 
15 #include <KColorScheme>
16 #include <collectionfetchjob.h>
17 #include <entitydisplayattribute.h>
18 #include <item.h>
19 #include <itemfetchjob.h>
20 #include <itemfetchscope.h>
21 #include <kcontacts/addressee.h>
22 #include <kcontacts/contactgroup.h>
23 
24 #include <KLocalizedString>
25 
26 #include <QIcon>
27 #include <QVBoxLayout>
28 
29 using namespace Akonadi;
30 
31 class Q_DECL_HIDDEN ContactGroupViewer::Private
32 {
33 public:
34  Private(ContactGroupViewer *parent)
35  : mParent(parent)
36  {
37  mBrowser = new TextBrowser;
38 
39  static QPixmap groupPixmap = QIcon::fromTheme(QStringLiteral("x-mail-distribution-list")).pixmap(QSize(100, 100));
40  mBrowser->document()->addResource(QTextDocument::ImageResource, QUrl(QStringLiteral("group_photo")), groupPixmap);
41 
42  mStandardContactGroupFormatter = new StandardContactGroupFormatter;
43  mContactGroupFormatter = mStandardContactGroupFormatter;
44  }
45 
46  ~Private()
47  {
48  delete mStandardContactGroupFormatter;
49  }
50 
51  void updateView()
52  {
53  mParent->setWindowTitle(i18nc("@title:window", "Contact Group %1", mCurrentGroupName));
54 
56  group.setName(mCurrentGroupName);
57  for (const KContacts::Addressee &contact : qAsConst(mCurrentContacts)) {
58  group.append(KContacts::ContactGroup::Data(contact.realName(), contact.preferredEmail()));
59  }
60 
61  mContactGroupFormatter->setContactGroup(group);
62 
63  QVector<QVariantMap> additionalFields;
64 
65  if (!mCurrentAddressBookName.isEmpty()) {
66  QVariantMap addressBookName;
67  addressBookName.insert(QStringLiteral("title"), i18n("Address Book"));
68  addressBookName.insert(QStringLiteral("value"), mCurrentAddressBookName);
69 
70  additionalFields << addressBookName;
71  }
72 
73  mContactGroupFormatter->setAdditionalFields(additionalFields);
74 
75  mBrowser->setHtml(mContactGroupFormatter->toHtml());
76  }
77 
78  void slotMailClicked(const QUrl &email)
79  {
81 
82  // remove the 'mailto:' and split into name and email address
83  KContacts::Addressee::parseEmailAddress(email.path(), name, address);
84 
85  Q_EMIT mParent->emailClicked(name, address);
86  }
87 
88  void _k_expandResult(KJob *job)
89  {
90  mExpandJob = nullptr;
91 
92  if (!job->error()) {
93  auto expandJob = qobject_cast<ContactGroupExpandJob *>(job);
94  mCurrentContacts = expandJob->contacts();
95  }
96 
97  // stop any running fetch job
98  if (mParentCollectionFetchJob) {
99  mParent->disconnect(mCollectionFetchJobConnection);
100  delete mParentCollectionFetchJob;
101  mParentCollectionFetchJob = nullptr;
102  }
103 
104  mParentCollectionFetchJob = new CollectionFetchJob(mCurrentItem.parentCollection(), CollectionFetchJob::Base, mParent);
105  mCollectionFetchJobConnection = mParent->connect(mParentCollectionFetchJob, &CollectionFetchJob::result, mParent, [this](KJob *job) {
106  slotParentCollectionFetched(job);
107  });
108  }
109 
110  void slotParentCollectionFetched(KJob *job)
111  {
112  mParentCollectionFetchJob = nullptr;
113  mCurrentAddressBookName.clear();
114 
115  if (!job->error()) {
116  auto fetchJob = qobject_cast<CollectionFetchJob *>(job);
117  if (!fetchJob->collections().isEmpty()) {
118  const Collection collection = fetchJob->collections().at(0);
119  mCurrentAddressBookName = collection.displayName();
120  }
121  }
122 
123  updateView();
124  }
125 
126  QMetaObject::Connection mCollectionFetchJobConnection;
127  QMetaObject::Connection mJobConnection;
128  ContactGroupViewer *mParent = nullptr;
129  TextBrowser *mBrowser = nullptr;
130  QString mCurrentGroupName;
131  KContacts::Addressee::List mCurrentContacts;
132  QString mCurrentAddressBookName;
133  Item mCurrentItem;
134  ContactGroupExpandJob *mExpandJob = nullptr;
135  CollectionFetchJob *mParentCollectionFetchJob = nullptr;
136  AbstractContactGroupFormatter *mStandardContactGroupFormatter = nullptr;
137  AbstractContactGroupFormatter *mContactGroupFormatter = nullptr;
138 };
139 
141  : QWidget(parent)
142  , d(new Private(this))
143 {
144  auto layout = new QVBoxLayout(this);
145  layout->setContentsMargins(0, 0, 0, 0);
146 
147  connect(d->mBrowser, &TextBrowser::anchorClicked, this, [this](const QUrl &url) {
148  d->slotMailClicked(url);
149  });
150 
151  layout->addWidget(d->mBrowser);
152 
153  // always fetch full payload for contact groups
156 }
157 
159 {
160  delete d;
161 }
162 
164 {
165  return ItemMonitor::item();
166 }
167 
169 {
170  ItemMonitor::setItem(group);
171 }
172 
174 {
175  if (formatter == nullptr) {
176  d->mContactGroupFormatter = d->mStandardContactGroupFormatter;
177  } else {
178  d->mContactGroupFormatter = formatter;
179  }
180 }
181 
182 void ContactGroupViewer::itemChanged(const Item &item)
183 {
184  if (!item.hasPayload<KContacts::ContactGroup>()) {
185  return;
186  }
187 
188  const auto group = item.payload<KContacts::ContactGroup>();
189  d->mCurrentGroupName = group.name();
190  d->mCurrentItem = item;
191 
192  if (d->mExpandJob) {
193  disconnect(d->mJobConnection);
194  d->mExpandJob->kill();
195  }
196 
197  d->mExpandJob = new ContactGroupExpandJob(group);
198  d->mJobConnection = connect(d->mExpandJob, &ContactGroupExpandJob::result, this, [this](KJob *job) {
199  d->_k_expandResult(job);
200  });
201  d->mExpandJob->start();
202 }
203 
204 void ContactGroupViewer::itemRemoved()
205 {
206  d->mBrowser->clear();
207 }
208 
209 #include "moc_contactgroupviewer.cpp"
QLayout * layout() const const
void setContactGroupFormatter(AbstractContactGroupFormatter *formatter)
Sets the contact group formatter that should be used for formatting the contact group.
void setContentsMargins(int left, int top, int right, int bottom)
QString name(const QVariant &location)
QString displayName() const
static void parseEmailAddress(const QString &rawEmail, QString &fullName, QString &email)
ItemFetchScope & fetchScope()
A class that formats a contact group as HTML code.
void insert(int i, T &&value)
ContactGroupViewer(QWidget *parent=nullptr)
Creates a new contact group viewer.
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
void fetchFullPayload(bool fetch=true)
T payload() const
QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) const const
QString name() const
~ContactGroupViewer() override
Destroys the contact group viewer.
The interface for all contact group formatters.
PostalAddress address(const QVariant &location)
KContacts::Addressee::List contacts() const
Returns the list of contacts.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString path(QUrl::ComponentFormattingOptions options) const const
void setName(const QString &name)
Item item() const
void addWidget(QWidget *w)
void setAncestorRetrieval(AncestorRetrieval ancestorDepth)
QString i18n(const char *text, const TYPE &arg...)
Akonadi::Item contactGroup() const
Returns the contact group that is currently displayed.
void setItem(const Item &item)
AddresseeList List
Job that expands a ContactGroup to a list of contacts.
QIcon fromTheme(const QString &name)
void append(const ContactReference &reference)
void setContactGroup(const Akonadi::Item &group)
Sets the contact group that shall be displayed in the viewer.
void result(KJob *job)
bool hasPayload() const
A viewer component for contact groups in Akonadi.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
int error() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Wed Jun 23 2021 23:09:24 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.