Skip to content
This repository has been archived by the owner on Sep 4, 2021. It is now read-only.

Latest commit

 

History

History
166 lines (150 loc) · 7.02 KB

seasideimport.cpp

File metadata and controls

166 lines (150 loc) · 7.02 KB
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
* Copyright (C) 2013 Jolla Mobile <matthew.vogt@jollamobile.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* "Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Nemo Mobile nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
*/
#include "seasideimport.h"
#include <QContactIdFilter>
Feb 16, 2015
Feb 16, 2015
35
36
#include <QContact>
#include <QContactManager>
37
38
namespace {
Feb 16, 2015
Feb 16, 2015
39
40
41
42
43
44
45
QContactFetchHint basicFetchHint()
{
QContactFetchHint fetchHint;
fetchHint.setOptimizationHints(QContactFetchHint::NoRelationships |
QContactFetchHint::NoActionPreferences |
QContactFetchHint::NoBinaryBlobs);
return fetchHint;
Nov 5, 2013
Nov 5, 2013
46
}
Feb 16, 2015
Feb 16, 2015
49
QList<QContact> SeasideImport::buildImportContacts(const QList<QVersitDocument> &details, int *newCount, int *updatedCount, int *ignoredCount, SeasideContactBuilder *contactBuilder)
50
51
52
53
54
{
if (newCount)
*newCount = 0;
if (updatedCount)
*updatedCount = 0;
Feb 16, 2015
Feb 16, 2015
55
bool eraseMatch = false;
Feb 16, 2015
Feb 16, 2015
57
58
59
60
SeasideContactBuilder *builder = contactBuilder
? contactBuilder
: new SeasideContactBuilder;
QList<QContact> importedContacts = builder->importContacts(details);
Feb 16, 2015
Feb 16, 2015
62
// Preprocess the imported contacts and merge any duplicates in the import list
Nov 20, 2013
Nov 20, 2013
63
64
QList<QContact>::iterator it = importedContacts.begin();
while (it != importedContacts.end()) {
Feb 16, 2015
Feb 16, 2015
65
66
builder->preprocessContact(*it);
int previousIndex = builder->previousDuplicateIndex(importedContacts, it - importedContacts.begin());
Nov 20, 2013
Nov 20, 2013
67
if (previousIndex != -1) {
68
// Combine these duplicate contacts
Nov 20, 2013
Nov 20, 2013
69
QContact &previous(importedContacts[previousIndex]);
Feb 16, 2015
Feb 16, 2015
70
71
72
73
74
builder->mergeImportIntoImport(previous, *it, &eraseMatch);
if (eraseMatch) {
it = importedContacts.erase(it);
} else {
++it;
Feb 16, 2015
Feb 16, 2015
76
} else {
Nov 20, 2013
Nov 20, 2013
77
78
++it;
}
Nov 4, 2013
Nov 4, 2013
79
80
}
Feb 16, 2015
Feb 16, 2015
81
82
83
84
// Build up information about local device contacts, so we can detect matches
// in order to correctly set the appropriate ContactId in the imported contacts
// prior to save (thereby ensuring correct add vs update save semantics).
builder->buildLocalDeviceContactIndexes();
85
86
// Find any imported contacts that match contacts we already have
Nov 20, 2013
Nov 20, 2013
87
88
89
QMap<QContactId, int> existingIds;
it = importedContacts.begin();
while (it != importedContacts.end()) {
Feb 16, 2015
Feb 16, 2015
90
QContactId existingId = builder->matchingLocalContactId(*it);
Jan 9, 2014
Jan 9, 2014
91
if (!existingId.isNull()) {
Nov 20, 2013
Nov 20, 2013
92
QMap<QContactId, int>::iterator eit = existingIds.find(existingId);
93
if (eit == existingIds.end()) {
Feb 16, 2015
Feb 16, 2015
94
// this match hasn't been seen before.
Nov 20, 2013
Nov 20, 2013
95
96
existingIds.insert(existingId, (it - importedContacts.begin()));
++it;
Feb 16, 2015
Feb 16, 2015
98
99
// another import contact which matches that local contact has
// been seen already. Merge these both-matching import contacts.
Nov 20, 2013
Nov 20, 2013
100
QContact &previous(importedContacts[*eit]);
Feb 16, 2015
Feb 16, 2015
101
102
103
104
105
106
builder->mergeImportIntoImport(previous, *it, &eraseMatch);
if (eraseMatch) {
it = importedContacts.erase(it);
} else {
++it;
}
Nov 20, 2013
Nov 20, 2013
108
109
} else {
++it;
110
111
112
113
114
115
116
117
118
119
120
}
}
int existingCount(existingIds.count());
if (existingCount > 0) {
// Retrieve all the contacts that we have matches for
QContactIdFilter idFilter;
idFilter.setIds(existingIds.keys());
QSet<QContactId> modifiedContacts;
QSet<QContactId> unmodifiedContacts;
Feb 16, 2015
Feb 16, 2015
121
QHash<QContactId, bool> unmodifiedErase;
Feb 16, 2015
Feb 16, 2015
123
foreach (const QContact &contact, builder->manager()->contacts(idFilter & builder->mergeSubsetFilter(), QList<QContactSortOrder>(), basicFetchHint())) {
Nov 20, 2013
Nov 20, 2013
124
QMap<QContactId, int>::const_iterator it = existingIds.find(contact.id());
125
126
if (it != existingIds.end()) {
// Update the existing version of the contact with any new details
Nov 20, 2013
Nov 20, 2013
127
QContact &importContact(importedContacts[*it]);
Feb 16, 2015
Feb 16, 2015
128
bool modified = builder->mergeLocalIntoImport(importContact, contact, &eraseMatch);
129
130
131
132
if (modified) {
modifiedContacts.insert(importContact.id());
} else {
unmodifiedContacts.insert(importContact.id());
Feb 16, 2015
Feb 16, 2015
133
unmodifiedErase.insert(importContact.id(), eraseMatch);
134
135
136
137
138
139
140
141
142
143
144
145
}
} else {
qWarning() << "unable to update existing contact:" << contact.id();
}
}
if (!unmodifiedContacts.isEmpty()) {
QList<QContact>::iterator it = importedContacts.begin();
while (it != importedContacts.end()) {
const QContact &importContact(*it);
const QContactId contactId(importContact.id());
Feb 16, 2015
Feb 16, 2015
146
147
if (!modifiedContacts.contains(contactId) && unmodifiedContacts.contains(contactId) && unmodifiedErase.value(contactId, false) == true) {
// This contact was not modified by import and should be erased from the import list - don't update it
148
149
150
151
152
153
154
155
156
157
158
159
160
it = importedContacts.erase(it);
--existingCount;
} else {
++it;
}
}
}
}
if (updatedCount)
*updatedCount = existingCount;
if (newCount)
*newCount = importedContacts.count() - existingCount;
Feb 16, 2015
Feb 16, 2015
161
162
if (ignoredCount) // duplicates or insignificant updates
*ignoredCount = details.count() - importedContacts.count();
163
164
165
return importedContacts;
}