KPeople

matchessolver.cpp
1/*
2 SPDX-FileCopyrightText: 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
3 SPDX-FileCopyrightText: 2013 David Edmundson <david@davidedmundson.co.uk>
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
16using namespace KPeople;
17
18MatchesSolver::MatchesSolver(const QList<Match> &matches, PersonsModel *model, QObject *parent)
19 : KJob(parent)
20 , m_matches(matches)
21 , m_model(model)
22{
23}
24
25void MatchesSolver::start()
26{
27 QMetaObject::invokeMethod(this, "startMatching", Qt::QueuedConnection);
28}
29
30void 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}
85
86#include "moc_matchessolver_p.cpp"
This class creates a model of all known contacts from all sources Contacts are represented as a tree ...
const QList< QKeySequence > & end()
bool contains(const Key &key) const const
iterator insert(const Key &key, const T &value)
QList< Key > keys() const const
T take(const Key &key)
T value(const Key &key) const const
bool invokeMethod(QObject *context, Functor &&function, FunctorReturnType *ret)
iterator insert(const T &value)
QChar * data()
bool isEmpty() const const
QueuedConnection
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:15:03 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.