1/*
2 Copyright (c) 2007 Till Adam <adam@kde.org>
3
4 This library is free software; you can redistribute it and/or modify it
5 under the terms of the GNU Library General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or (at your
7 option) any later version.
8
9 This library is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12 License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to the
16 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301, USA.
18*/
19
20#include "akonadi_serializer_addressee.h"
21
22#include <akonadi/abstractdifferencesreporter.h>
23#include <akonadi/item.h>
24#include <akonadi/kabc/contactparts.h>
25
26#include <kabc/addressee.h>
27#include <klocale.h>
28
29#include <QtCore/qplugin.h>
30
31using namespace Akonadi;
32
33//// ItemSerializerPlugin interface
34
35bool SerializerPluginAddressee::deserialize( Item& item, const QByteArray& label, QIODevice& data, int version )
36{
37 Q_UNUSED( version );
38
39 KABC::Addressee addr;
40 if ( label == Item::FullPayload ) {
41 addr = m_converter.parseVCard( data.readAll() );
42 } else if ( label == Akonadi::ContactPart::Standard ) {
43 addr = m_converter.parseVCard( data.readAll() );
44
45 // remove pictures and sound
46 addr.setPhoto( KABC::Picture() );
47 addr.setLogo( KABC::Picture() );
48 addr.setSound( KABC::Sound() );
49 } else if ( label == Akonadi::ContactPart::Lookup ) {
50 const KABC::Addressee temp = m_converter.parseVCard( data.readAll() );
51
52 // copy only uid, name and email addresses
53 addr.setUid( temp.uid() );
54 addr.setPrefix( temp.prefix() );
55 addr.setGivenName( temp.givenName() );
56 addr.setAdditionalName( temp.additionalName() );
57 addr.setFamilyName( temp.familyName() );
58 addr.setSuffix( temp.suffix() );
59 addr.setEmails( temp.emails() );
60 } else {
61 return false;
62 }
63
64 if ( !addr.isEmpty() ) {
65 item.setPayload<KABC::Addressee>( addr );
66 } else {
67 kWarning( 5261 ) << "Empty addressee object!";
68 }
69
70 return true;
71}
72
73void SerializerPluginAddressee::serialize( const Item& item, const QByteArray& label, QIODevice& data, int &version )
74{
75 Q_UNUSED( version );
76
77 if ( label != Item::FullPayload && label != Akonadi::ContactPart::Standard && label != Akonadi::ContactPart::Lookup )
78 return;
79
80 if ( !item.hasPayload<KABC::Addressee>() )
81 return;
82
83 KABC::Addressee addr, temp;
84
85 temp = item.payload<KABC::Addressee>();
86
87 if ( label == Item::FullPayload ) {
88 addr = temp;
89 } else if ( label == Akonadi::ContactPart::Standard ) {
90 addr = temp;
91
92 // remove pictures and sound
93 addr.setPhoto( KABC::Picture() );
94 addr.setLogo( KABC::Picture() );
95 addr.setSound( KABC::Sound() );
96 } else if ( label == Akonadi::ContactPart::Lookup ) {
97 // copy only uid, name and email addresses
98 addr.setUid( temp.uid() );
99 addr.setPrefix( temp.prefix() );
100 addr.setGivenName( temp.givenName() );
101 addr.setAdditionalName( temp.additionalName() );
102 addr.setFamilyName( temp.familyName() );
103 addr.setSuffix( temp.suffix() );
104 addr.setEmails( temp.emails() );
105 }
106
107 data.write( m_converter.createVCard( addr ) );
108}
109
110//// DifferencesAlgorithmInterface interface
111
112static bool compareString( const QString &left, const QString &right )
113{
114 if ( left.isEmpty() && right.isEmpty() )
115 return true;
116 else
117 return left == right;
118}
119
120static QString toString( const KABC::PhoneNumber &phoneNumber )
121{
122 return phoneNumber.number();
123}
124
125static QString toString( const KABC::Address &address )
126{
127 return address.toString();
128}
129
130static QString toString( const QString &value )
131{
132 return value;
133}
134
135template <class T>
136static void compareList( Akonadi::AbstractDifferencesReporter *reporter, const QString &id, const QList<T> &left, const QList<T> &right )
137{
138 for ( int i = 0; i < left.count(); ++i ) {
139 if ( !right.contains( left[ i ] ) )
140 reporter->addProperty( AbstractDifferencesReporter::AdditionalLeftMode, id, toString( left[ i ] ), QString() );
141 }
142
143 for ( int i = 0; i < right.count(); ++i ) {
144 if ( !left.contains( right[ i ] ) )
145 reporter->addProperty( AbstractDifferencesReporter::AdditionalRightMode, id, QString(), toString( right[ i ] ) );
146 }
147}
148
149void SerializerPluginAddressee::compare( Akonadi::AbstractDifferencesReporter *reporter,
150 const Akonadi::Item &leftItem,
151 const Akonadi::Item &rightItem )
152{
153 Q_ASSERT( reporter );
154 Q_ASSERT( leftItem.hasPayload<KABC::Addressee>() );
155 Q_ASSERT( rightItem.hasPayload<KABC::Addressee>() );
156
157 reporter->setLeftPropertyValueTitle( i18n( "Changed Contact" ) );
158 reporter->setRightPropertyValueTitle( i18n( "Conflicting Contact" ) );
159
160 const KABC::Addressee leftContact = leftItem.payload<KABC::Addressee>();
161 const KABC::Addressee rightContact = rightItem.payload<KABC::Addressee>();
162
163 if ( !compareString( leftContact.uid(), rightContact.uid() ) )
164 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::uidLabel(),
165 leftContact.uid(), rightContact.uid() );
166
167 if ( !compareString( leftContact.name(), rightContact.name() ) )
168 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::nameLabel(),
169 leftContact.name(), rightContact.name() );
170
171 if ( !compareString( leftContact.formattedName(), rightContact.formattedName() ) )
172 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::formattedNameLabel(),
173 leftContact.formattedName(), rightContact.formattedName() );
174
175 if ( !compareString( leftContact.familyName(), rightContact.familyName() ) )
176 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::familyNameLabel(),
177 leftContact.familyName(), rightContact.familyName() );
178
179 if ( !compareString( leftContact.givenName(), rightContact.givenName() ) )
180 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::givenNameLabel(),
181 leftContact.givenName(), rightContact.givenName() );
182
183 if ( !compareString( leftContact.additionalName(), rightContact.additionalName() ) )
184 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::additionalNameLabel(),
185 leftContact.additionalName(), rightContact.additionalName() );
186
187 if ( !compareString( leftContact.prefix(), rightContact.prefix() ) )
188 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::prefixLabel(),
189 leftContact.prefix(), rightContact.prefix() );
190
191 if ( !compareString( leftContact.suffix(), rightContact.suffix() ) )
192 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::suffixLabel(),
193 leftContact.suffix(), rightContact.suffix() );
194
195 if ( !compareString( leftContact.nickName(), rightContact.nickName() ) )
196 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::nickNameLabel(),
197 leftContact.nickName(), rightContact.nickName() );
198
199 if ( leftContact.birthday() != rightContact.birthday() )
200 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::birthdayLabel(),
201 leftContact.birthday().toString(), rightContact.birthday().toString() );
202
203 if ( !compareString( leftContact.mailer(), rightContact.mailer() ) )
204 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::mailerLabel(),
205 leftContact.mailer(), rightContact.mailer() );
206
207 if ( leftContact.timeZone() != rightContact.timeZone() )
208 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::timeZoneLabel(),
209 leftContact.timeZone().toString(), rightContact.timeZone().toString() );
210
211 if ( leftContact.geo() != rightContact.geo() )
212 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::geoLabel(),
213 leftContact.geo().toString(), rightContact.geo().toString() );
214
215 if ( !compareString( leftContact.title(), rightContact.title() ) )
216 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::titleLabel(),
217 leftContact.title(), rightContact.title() );
218
219 if ( !compareString( leftContact.role(), rightContact.role() ) )
220 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::roleLabel(),
221 leftContact.role(), rightContact.role() );
222
223 if ( !compareString( leftContact.organization(), rightContact.organization() ) )
224 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::organizationLabel(),
225 leftContact.organization(), rightContact.organization() );
226
227 if ( !compareString( leftContact.note(), rightContact.note() ) )
228 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::noteLabel(),
229 leftContact.note(), rightContact.note() );
230
231 if ( !compareString( leftContact.productId(), rightContact.productId() ) )
232 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::productIdLabel(),
233 leftContact.productId(), rightContact.productId() );
234
235 if ( !compareString( leftContact.sortString(), rightContact.sortString() ) )
236 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::sortStringLabel(),
237 leftContact.sortString(), rightContact.sortString() );
238
239 if ( leftContact.secrecy() != rightContact.secrecy() ) {
240 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::secrecyLabel(),
241 leftContact.secrecy().toString(), rightContact.secrecy().toString() );
242 }
243
244 if ( leftContact.url() != rightContact.url() )
245 reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::urlLabel(),
246 leftContact.url().prettyUrl(), rightContact.url().prettyUrl() );
247
248 compareList( reporter, i18n( "Emails" ), leftContact.emails(), rightContact.emails() );
249 compareList( reporter, i18n( "Phone Numbers" ), leftContact.phoneNumbers(), rightContact.phoneNumbers() );
250 compareList( reporter, i18n( "Addresses" ), leftContact.addresses(), rightContact.addresses() );
251
252 //TODO: logo/photo/custom entries
253}
254
255//// GidExtractorInterface
256
257QString SerializerPluginAddressee::extractGid( const Item& item ) const
258{
259 if ( !item.hasPayload<KABC::Addressee>() ) {
260 return QString();
261 }
262 return item.payload<KABC::Addressee>().uid();
263}
264
265
266Q_EXPORT_PLUGIN2( akonadi_serializer_addressee, Akonadi::SerializerPluginAddressee )
267
268