KPeople

metacontact.cpp
1 /*
2  SPDX-FileCopyrightText: 2013 David Edmundson <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.1-or-later
5 */
6 
7 #include "global.h"
8 #include "kpeople_debug.h"
9 #include "metacontact_p.h"
10 
11 #include <QSharedData>
12 
13 namespace KPeople
14 {
15 class MetaContactData : public QSharedData
16 {
17 public:
18  QString personUri;
19  QStringList contactUris;
20  AbstractContact::List contacts;
21  AbstractContact::Ptr personAddressee;
22 };
23 }
24 
25 // TODO: It feels like MetaContact and MetaContactProxy should be merged,
26 // still, not today.
27 
28 class MetaContactProxy : public KPeople::AbstractContact
29 {
30 public:
31  MetaContactProxy(const AbstractContact::List &contacts)
32  : m_contacts(contacts)
33  {
34  }
35 
36  QVariant customProperty(const QString &key) const override
37  {
38  if (key.startsWith(QLatin1String("all-"))) {
39  QVariantList ret;
40  for (const AbstractContact::Ptr &contact : std::as_const(m_contacts)) {
41  QVariant val = contact->customProperty(key);
42  Q_ASSERT(val.canConvert<QVariantList>() || val.isNull());
43 
44  if (!val.isNull()) {
45  ret.append(val.toList());
46  }
47  }
48  return ret;
49  } else {
50  for (const AbstractContact::Ptr &contact : std::as_const(m_contacts)) {
51  QVariant val = contact->customProperty(key);
52  if (val.isValid()) {
53  return val;
54  }
55  }
56  return QVariant();
57  }
58  }
59 
60  const AbstractContact::List m_contacts;
61 };
62 
63 using namespace KPeople;
64 
65 MetaContact::MetaContact()
66  : d(new MetaContactData)
67 {
68  reload();
69 }
70 
71 MetaContact::MetaContact(const QString &personUri, const QMap<QString, AbstractContact::Ptr> &contacts)
72  : d(new MetaContactData)
73 {
74  d->personUri = personUri;
75 
77  while (it != contacts.constEnd()) {
78  insertContactInternal(it.key(), it.value());
79  it++;
80  }
81  reload();
82 }
83 
84 MetaContact::MetaContact(const QString &contactUri, const AbstractContact::Ptr &contact)
85  : d(new MetaContactData)
86 {
87  d->personUri = contactUri;
88  insertContactInternal(contactUri, contact);
89  reload();
90 }
91 
92 MetaContact::MetaContact(const MetaContact &other)
93  : d(other.d)
94 {
95 }
96 
97 MetaContact &MetaContact::operator=(const MetaContact &other)
98 {
99  if (this != &other) {
100  d = other.d;
101  }
102 
103  return *this;
104 }
105 
106 MetaContact::~MetaContact()
107 {
108 }
109 
110 QString MetaContact::id() const
111 {
112  return d->personUri;
113 }
114 
115 bool MetaContact::isValid() const
116 {
117  return !d->contacts.isEmpty();
118 }
119 
120 QStringList MetaContact::contactUris() const
121 {
122  return d->contactUris;
123 }
124 
125 AbstractContact::Ptr MetaContact::contact(const QString &contactUri)
126 {
127  int index = d->contactUris.indexOf(contactUri);
128  if (index >= 0) {
129  return d->contacts[index];
130  } else {
131  return AbstractContact::Ptr();
132  }
133 }
134 
135 AbstractContact::List MetaContact::contacts() const
136 {
137  return d->contacts;
138 }
139 
140 const AbstractContact::Ptr &MetaContact::personAddressee() const
141 {
142  Q_ASSERT(d->personAddressee);
143  return d->personAddressee;
144 }
145 
146 int MetaContact::insertContact(const QString &contactUri, const AbstractContact::Ptr &contact)
147 {
148  int index = insertContactInternal(contactUri, contact);
149  if (index >= 0) {
150  reload();
151  } else {
152  qCWarning(KPEOPLE_LOG) << "Inserting an already-present contact" << contactUri;
153  }
154  return index;
155 }
156 
157 int MetaContact::insertContactInternal(const QString &contactUri, const AbstractContact::Ptr &contact)
158 {
159  if (d->contactUris.contains(contactUri)) {
160  // if item is already listed, do nothing.
161  return -1;
162  } else {
163  // TODO if from the local address book - prepend to give higher priority.
164  int index = d->contacts.size();
165  d->contacts.append(contact);
166  d->contactUris.append(contactUri);
167  return index;
168  }
169 }
170 
171 int MetaContact::updateContact(const QString &contactUri, const AbstractContact::Ptr &contact)
172 {
173  const int index = d->contactUris.indexOf(contactUri);
174  Q_ASSERT(index < 0 || d->contacts[index] == contact);
175  if (index < 0) {
176  qCWarning(KPEOPLE_LOG) << "contact not part of the metacontact";
177  }
178  return index;
179 }
180 
181 int MetaContact::removeContact(const QString &contactUri)
182 {
183  const int index = d->contactUris.indexOf(contactUri);
184  if (index >= 0) {
185  d->contacts.removeAt(index);
186  d->contactUris.removeAt(index);
187  reload();
188  }
189  return index;
190 }
191 
192 void MetaContact::reload()
193 {
194  // always favour the first item
195 
196  // Optimization, if only one contact re-use that one
197  d->personAddressee = (d->contacts.size() == 1) ? d->contacts.first() : AbstractContact::Ptr(new MetaContactProxy(d->contacts));
198  Q_ASSERT(d->personAddressee);
199 }
bool isNull() const const
QMap::const_iterator constBegin() const const
bool isValid() const const
int size() const const
virtual QVariant customProperty(const QString &key) const =0
Generic method to access a random contact property.
const QList< QKeySequence > & reload()
QMap::const_iterator constEnd() const const
bool isEmpty() const const
bool canConvert(int targetTypeId) const const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
KPeople::AbstractContact is the class to provide the data from a given contact by the backends.
QList< QVariant > toList() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sun Aug 14 2022 04:09:08 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.