KPeople

matchessolver.cpp
1 /*
2  SPDX-FileCopyrightText: 2012 Aleix Pol Gonzalez <[email protected]>
3  SPDX-FileCopyrightText: 2013 David Edmundson <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.1-or-later
6 */
7 
8 #include "kpeople_debug.h"
9 #include "match_p.h"
10 #include "matchessolver_p.h"
11 #include "personmanager_p.h"
12 #include "personsmodel.h"
13 
14 #include <QString>
15 
16 using namespace KPeople;
17 
18 MatchesSolver::MatchesSolver(const QList<Match> &matches, PersonsModel *model, QObject *parent)
19  : KJob(parent)
20  , m_matches(matches)
21  , m_model(model)
22 {
23 }
24 
26 {
27  QMetaObject::invokeMethod(this, "startMatching", Qt::QueuedConnection);
28 }
29 
30 void MatchesSolver::startMatching()
31 {
32  // Will contain all the sets to be merged
34  // has a relation of each person, to know where it is
35  QHash<QString, QString> destinationResolver;
36  for (const Match &m : std::as_const(m_matches)) {
37  QString urlA = m.indexA.data(PersonsModel::PersonUriRole).toString();
38  QString urlB = m.indexB.data(PersonsModel::PersonUriRole).toString();
39  Q_ASSERT(urlA != urlB);
40 
41  const bool inA = destinationResolver.contains(urlA);
42  const bool inB = destinationResolver.contains(urlB);
43  if (inA && inB) {
44  // Both are in already, so we have to merge both sets
45  destinationResolver[urlB] = urlA;
46  jobsData[urlA] = jobsData.take(urlB);
47 
48  // we've put all items pointed to by urlA, to the B set
49  // now we re-assign anything pointing to B as pointing to A
50  // because they are the same
51  const auto keys = destinationResolver.keys(urlB);
52  auto it = keys.constBegin();
53  const auto end = keys.constEnd();
54  for (; it != end; ++it) {
55  destinationResolver[*it] = urlA;
56  }
57  } else {
58  // if A is in but not B, we want B wherever A is
59  if (inA) {
60  qSwap(urlB, urlA);
61  }
62  // in case B is anywhere, add A to that set, otherwise just insert B
63  const QString mergeUrl = destinationResolver.value(urlB, urlB);
64 
65  QSet<QString> &jobs = jobsData[mergeUrl];
66  jobs.insert(urlB);
67  jobs.insert(urlA);
68 
69  // remember where urlA and urlB are
70  Q_ASSERT(urlA != mergeUrl);
71  destinationResolver.insert(urlA, mergeUrl);
72  if (urlB != mergeUrl) {
73  destinationResolver.insert(urlB, mergeUrl);
74  }
75  }
76  }
77 
78  for (const QSet<QString> &uris : std::as_const(jobsData)) {
79  if (PersonManager::instance()->mergeContacts(uris.values()).isEmpty()) {
80  qCWarning(KPEOPLE_LOG) << "error: failing to merge contacts: " << uris;
81  }
82  }
83  emitResult();
84 }
const T value(const Key &key) const const
This class creates a model of all known contacts from all sources Contacts are represented as a tree ...
Definition: personsmodel.h:33
QList< Key > keys() const const
Q_SCRIPTABLE Q_NOREPLY void start()
QHash::iterator insert(const Key &key, const T &value)
T take(const Key &key)
bool isEmpty() const const
QueuedConnection
bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, QGenericReturnArgument ret, QGenericArgument val0, QGenericArgument val1, QGenericArgument val2, QGenericArgument val3, QGenericArgument val4, QGenericArgument val5, QGenericArgument val6, QGenericArgument val7, QGenericArgument val8, QGenericArgument val9)
QSet::iterator insert(const T &value)
QChar * data()
bool contains(const Key &key) const const
const QList< QKeySequence > & end()
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.