~ubuntu-branches/ubuntu/raring/kadu/raring

« back to all changes in this revision

Viewing changes to .pc/05-hotfix_upstream.patch/kadu-core/contacts/contact-shared.cpp

  • Committer: Package Import Robot
  • Author(s): Patryk Cisek
  • Date: 2012-09-15 13:02:48 UTC
  • mfrom: (0.95.1) (0.94.1) (0.91.2) (2.3.37 sid)
  • Revision ID: package-import@ubuntu.com-20120915130248-hu211iq9ow3s3oas
Tags: 0.12.3-1
* New upstream release
* Removed debian/patches/05-hotfix_upstream.patch and
  debian/patches/06-mpris_player-harden-fix.patch -- patches applied
  upstream
* Icon theme glass is installed again, since all icon sizes have been
  corrected
* Changed build dependency from aspell to enchant (Upstream's suggestion)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * %kadu copyright begin%
3
 
 * Copyright 2009, 2010, 2011 Piotr Galiszewski (piotr.galiszewski@kadu.im)
4
 
 * Copyright 2009 Bartłomiej Zimoń (uzi18@o2.pl)
5
 
 * Copyright 2009, 2009, 2010, 2011 Rafał Malinowski (rafal.przemyslaw.malinowski@gmail.com)
6
 
 * Copyright 2010, 2011 Bartosz Brachaczek (b.brachaczek@gmail.com)
7
 
 * %kadu copyright end%
8
 
 *
9
 
 * This program is free software; you can redistribute it and/or
10
 
 * modify it under the terms of the GNU General Public License as
11
 
 * published by the Free Software Foundation; either version 2 of
12
 
 * the License, or (at your option) any later version.
13
 
 *
14
 
 * This program is distributed in the hope that it will be useful,
15
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
 
 * GNU General Public License for more details.
18
 
 *
19
 
 * You should have received a copy of the GNU General Public License
20
 
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21
 
 */
22
 
 
23
 
#include "accounts/account-manager.h"
24
 
#include "accounts/account.h"
25
 
#include "avatars/avatar-manager.h"
26
 
#include "avatars/avatar.h"
27
 
#include "buddies/buddy-manager.h"
28
 
#include "configuration/configuration-file.h"
29
 
#include "contacts/contact-details.h"
30
 
#include "contacts/contact-manager.h"
31
 
#include "core/core.h"
32
 
#include "misc/change-notifier.h"
33
 
#include "protocols/protocol.h"
34
 
#include "protocols/protocol-factory.h"
35
 
#include "protocols/protocols-manager.h"
36
 
#include "protocols/services/roster/roster-entry.h"
37
 
 
38
 
#include "contact-shared.h"
39
 
 
40
 
ContactShared * ContactShared::loadStubFromStorage(const QSharedPointer<StoragePoint> &storagePoint)
41
 
{
42
 
        ContactShared *result = loadFromStorage(storagePoint);
43
 
        result->loadStub();
44
 
 
45
 
        return result;
46
 
}
47
 
 
48
 
ContactShared * ContactShared::loadFromStorage(const QSharedPointer<StoragePoint> &storagePoint)
49
 
{
50
 
        ContactShared *result = new ContactShared();
51
 
        result->setStorage(storagePoint);
52
 
 
53
 
        return result;
54
 
}
55
 
 
56
 
ContactShared::ContactShared(const QUuid &uuid) :
57
 
                Shared(uuid), Details(0),
58
 
                Priority(-1), MaximumImageSize(0), UnreadMessagesCount(0),
59
 
                Blocking(false), IgnoreNextStatusChange(false), Port(0)
60
 
{
61
 
        Entry = new RosterEntry(this);
62
 
        connect(Entry->changeNotifier(), SIGNAL(changed()), this, SIGNAL(dirtinessChanged()));
63
 
 
64
 
        ContactAccount = new Account();
65
 
        ContactAvatar = new Avatar();
66
 
        OwnerBuddy = new Buddy();
67
 
 
68
 
        connect(ProtocolsManager::instance(), SIGNAL(protocolFactoryRegistered(ProtocolFactory*)),
69
 
                this, SLOT(protocolFactoryRegistered(ProtocolFactory*)));
70
 
        connect(ProtocolsManager::instance(), SIGNAL(protocolFactoryUnregistered(ProtocolFactory*)),
71
 
                this, SLOT(protocolFactoryUnregistered(ProtocolFactory*)));
72
 
 
73
 
        connect(changeNotifier(), SIGNAL(changed()), this, SIGNAL(updated()));
74
 
}
75
 
 
76
 
ContactShared::~ContactShared()
77
 
{
78
 
        ref.ref();
79
 
 
80
 
        disconnect(ProtocolsManager::instance(), 0, this, 0);
81
 
 
82
 
        protocolFactoryUnregistered(ProtocolsManager::instance()->byName(ContactAccount->protocolName()));
83
 
 
84
 
        delete OwnerBuddy;
85
 
        delete ContactAvatar;
86
 
        delete ContactAccount;
87
 
}
88
 
 
89
 
StorableObject * ContactShared::storageParent()
90
 
{
91
 
        return ContactManager::instance();
92
 
}
93
 
 
94
 
QString ContactShared::storageNodeName()
95
 
{
96
 
        return QLatin1String("Contact");
97
 
}
98
 
 
99
 
void ContactShared::load()
100
 
{
101
 
        if (!isValidStorage())
102
 
                return;
103
 
 
104
 
        Shared::load();
105
 
 
106
 
        Id = loadValue<QString>("Id");
107
 
        Priority = loadValue<int>("Priority", -1);
108
 
 
109
 
        if (loadValue<bool>("Dirty", true))
110
 
                Entry->setState(RosterEntryDesynchronized);
111
 
        else
112
 
                Entry->setState(RosterEntrySynchronized);
113
 
        Entry->setDetached(loadValue<bool>("Detached", false));
114
 
 
115
 
        *ContactAccount = AccountManager::instance()->byUuid(loadValue<QString>("Account"));
116
 
        doSetOwnerBuddy(BuddyManager::instance()->byUuid(loadValue<QString>("Buddy")));
117
 
        doSetContactAvatar(AvatarManager::instance()->byUuid(loadValue<QString>("Avatar")));
118
 
 
119
 
        protocolFactoryRegistered(ProtocolsManager::instance()->byName(ContactAccount->protocolName()));
120
 
}
121
 
 
122
 
void ContactShared::aboutToBeRemoved()
123
 
{
124
 
        // clean up references
125
 
        *ContactAccount = Account::null;
126
 
        removeFromBuddy();
127
 
        doSetOwnerBuddy(Buddy::null);
128
 
 
129
 
        AvatarManager::instance()->removeItem(*ContactAvatar);
130
 
        doSetContactAvatar(Avatar::null);
131
 
 
132
 
        deleteDetails();
133
 
 
134
 
        changeNotifier()->notify();
135
 
}
136
 
 
137
 
void ContactShared::store()
138
 
{
139
 
        if (!isValidStorage())
140
 
                return;
141
 
 
142
 
        ensureLoaded();
143
 
 
144
 
        Shared::store();
145
 
 
146
 
        storeValue("Id", Id);
147
 
        storeValue("Priority", Priority);
148
 
 
149
 
        storeValue("Dirty", RosterEntrySynchronized != Entry->state());
150
 
        storeValue("Detached", Entry->detached());
151
 
 
152
 
        storeValue("Account", ContactAccount->uuid().toString());
153
 
        storeValue("Buddy", !isAnonymous()
154
 
                        ? OwnerBuddy->uuid().toString()
155
 
                        : QString());
156
 
 
157
 
        if (*ContactAvatar)
158
 
                storeValue("Avatar", ContactAvatar->uuid().toString());
159
 
 
160
 
        removeValue("Contact");
161
 
}
162
 
 
163
 
bool ContactShared::shouldStore()
164
 
{
165
 
        ensureLoaded();
166
 
 
167
 
        if (!UuidStorableObject::shouldStore())
168
 
                return false;
169
 
 
170
 
        if (Id.isEmpty() || ContactAccount->uuid().isNull())
171
 
                return false;
172
 
 
173
 
        // we dont need data for non-roster contacts only from 4 version of sql schema
174
 
        if (config_file.readNumEntry("History", "Schema", 0) < 4)
175
 
                return true;
176
 
 
177
 
        return !isAnonymous() || rosterEntry()->requiresSynchronization() || customProperties()->shouldStore();
178
 
}
179
 
 
180
 
void ContactShared::addToBuddy()
181
 
{
182
 
        // dont add to buddy if details are not available
183
 
        if (Details && *OwnerBuddy)
184
 
                OwnerBuddy->addContact(this);
185
 
}
186
 
 
187
 
void ContactShared::removeFromBuddy()
188
 
{
189
 
        if (*OwnerBuddy)
190
 
                OwnerBuddy->removeContact(this);
191
 
}
192
 
 
193
 
void ContactShared::setOwnerBuddy(const Buddy &buddy)
194
 
{
195
 
        ensureLoaded();
196
 
 
197
 
        if (*OwnerBuddy == buddy)
198
 
                return;
199
 
 
200
 
        /* NOTE: This guard is needed to avoid deleting this object when removing
201
 
         * Contact from Buddy which may hold last reference to it and thus wants to
202
 
         * delete it. But we don't want this to happen.
203
 
         */
204
 
        Contact guard(this);
205
 
 
206
 
        removeFromBuddy();
207
 
        doSetOwnerBuddy(buddy);
208
 
        addToBuddy();
209
 
 
210
 
        Entry->setState(RosterEntryDesynchronized);
211
 
        changeNotifier()->notify();
212
 
        emit buddyUpdated();
213
 
}
214
 
 
215
 
void ContactShared::setContactAccount(const Account &account)
216
 
{
217
 
        ensureLoaded();
218
 
 
219
 
        if (*ContactAccount == account)
220
 
                return;
221
 
 
222
 
        if (*ContactAccount && ContactAccount->protocolHandler() && ContactAccount->protocolHandler()->protocolFactory())
223
 
                protocolFactoryUnregistered(ContactAccount->protocolHandler()->protocolFactory());
224
 
 
225
 
        *ContactAccount = account;
226
 
 
227
 
        if (*ContactAccount && ContactAccount->protocolHandler() && ContactAccount->protocolHandler()->protocolFactory())
228
 
                protocolFactoryRegistered(ContactAccount->protocolHandler()->protocolFactory());
229
 
 
230
 
        changeNotifier()->notify();
231
 
}
232
 
 
233
 
void ContactShared::protocolFactoryRegistered(ProtocolFactory *protocolFactory)
234
 
{
235
 
        ensureLoaded();
236
 
 
237
 
        if (!protocolFactory || !*ContactAccount || ContactAccount->protocolName() != protocolFactory->name())
238
 
                return;
239
 
 
240
 
        if (Details)
241
 
                return;
242
 
 
243
 
        Details = protocolFactory->createContactDetails(this);
244
 
        Q_ASSERT(Details);
245
 
 
246
 
        Details->ensureLoaded();
247
 
 
248
 
        changeNotifier()->notify();
249
 
 
250
 
        ContactManager::instance()->registerItem(this);
251
 
        addToBuddy();
252
 
}
253
 
 
254
 
void ContactShared::protocolFactoryUnregistered(ProtocolFactory *protocolFactory)
255
 
{
256
 
        ensureLoaded();
257
 
 
258
 
        if (!protocolFactory || ContactAccount->protocolName() != protocolFactory->name())
259
 
                return;
260
 
 
261
 
        /* NOTE: This guard is needed to avoid deleting this object when detaching
262
 
         * Contact from Buddy which may hold last reference to it and thus wants to
263
 
         * delete it. But we don't want this to happen.
264
 
         */
265
 
        Contact guard(this);
266
 
 
267
 
        deleteDetails();
268
 
 
269
 
        changeNotifier()->notify();
270
 
}
271
 
 
272
 
void ContactShared::deleteDetails()
273
 
{
274
 
        if (Details)
275
 
        {
276
 
                // do not store contacts that are not in contact manager
277
 
                if (ContactManager::instance()->allItems().contains(uuid()))
278
 
                        Details->ensureStored();
279
 
 
280
 
                removeFromBuddy();
281
 
 
282
 
                delete Details;
283
 
                Details = 0;
284
 
        }
285
 
 
286
 
        ContactManager::instance()->unregisterItem(this);
287
 
}
288
 
 
289
 
void ContactShared::setId(const QString &id)
290
 
{
291
 
        ensureLoaded();
292
 
 
293
 
        if (Id == id)
294
 
                return;
295
 
 
296
 
        QString oldId = Id;
297
 
        Id = id;
298
 
 
299
 
        Entry->setState(RosterEntryDesynchronized);
300
 
        changeNotifier()->notify();
301
 
}
302
 
 
303
 
RosterEntry * ContactShared::rosterEntry()
304
 
{
305
 
        ensureLoaded();
306
 
 
307
 
        return Entry;
308
 
}
309
 
 
310
 
/*
311
 
 * @todo: move this comment somewhere
312
 
 *
313
 
 * Sets state if this contact to \p dirty. All contacts are dirty by default.
314
 
 *
315
 
 * Dirty contacts with anonymous owner buddies are considered dirty removed and will
316
 
 * never be added to roster as long as this state lasts and will in effect be removed
317
 
 * from remote roster. Dirty contacts with not anonymous owner buddies are considered
318
 
 * dirty added and will always be added to roster, even if remote roster marked
319
 
 * them as removed.
320
 
 *
321
 
 * When adding contacts with anononymous owner buddies to the manager, always make sure
322
 
 * to mark them not dirty, otherwise they will be considered dirty removed and will
323
 
 * not be added to roster if remote roster says so, which is probably not what one expects.
324
 
 */
325
 
 
326
 
void ContactShared::avatarUpdated()
327
 
{
328
 
        changeNotifier()->notify();
329
 
}
330
 
 
331
 
void ContactShared::doSetOwnerBuddy(const Buddy &buddy)
332
 
{
333
 
        if (*OwnerBuddy)
334
 
                disconnect(*OwnerBuddy, 0, this, 0);
335
 
 
336
 
        *OwnerBuddy = buddy;
337
 
 
338
 
        if (*OwnerBuddy)
339
 
                connect(*OwnerBuddy, SIGNAL(updated()), this, SIGNAL(buddyUpdated()));
340
 
}
341
 
 
342
 
void ContactShared::doSetContactAvatar(const Avatar &contactAvatar)
343
 
{
344
 
        if (*ContactAvatar)
345
 
                disconnect(*ContactAvatar, 0, this, 0);
346
 
 
347
 
        *ContactAvatar = contactAvatar;
348
 
 
349
 
        if (*ContactAvatar)
350
 
                connect(*ContactAvatar, SIGNAL(updated()), this, SLOT(avatarUpdated()));
351
 
}
352
 
 
353
 
void ContactShared::setContactAvatar(const Avatar &contactAvatar)
354
 
{
355
 
        ensureLoaded();
356
 
 
357
 
        if (*ContactAvatar == contactAvatar)
358
 
                return;
359
 
 
360
 
        doSetContactAvatar(contactAvatar);
361
 
        changeNotifier()->notify();
362
 
}
363
 
 
364
 
bool ContactShared::isAnonymous()
365
 
{
366
 
        ensureLoaded();
367
 
 
368
 
        if (!OwnerBuddy)
369
 
                return true;
370
 
 
371
 
        if (!(*OwnerBuddy))
372
 
                return true;
373
 
 
374
 
        return OwnerBuddy->isAnonymous();
375
 
}
376
 
 
377
 
QString ContactShared::display(bool useBuddyData)
378
 
{
379
 
        ensureLoaded();
380
 
 
381
 
        if (!useBuddyData || !OwnerBuddy || !(*OwnerBuddy) || OwnerBuddy->display().isEmpty())
382
 
                return Id;
383
 
 
384
 
        return OwnerBuddy->display();
385
 
}
386
 
 
387
 
Avatar ContactShared::avatar(bool useBuddyData)
388
 
{
389
 
        ensureLoaded();
390
 
 
391
 
        if (!useBuddyData || !OwnerBuddy || !(*OwnerBuddy) || OwnerBuddy->buddyAvatar().isEmpty())
392
 
                return ContactAvatar ? *ContactAvatar : Avatar::null;
393
 
 
394
 
        return OwnerBuddy->buddyAvatar();
395
 
}
396
 
 
397
 
KaduShared_PropertyPtrReadDef(ContactShared, Account, contactAccount, ContactAccount)
398
 
KaduShared_PropertyPtrReadDef(ContactShared, Avatar, contactAvatar, ContactAvatar)
399
 
KaduShared_PropertyPtrReadDef(ContactShared, Buddy, ownerBuddy, OwnerBuddy)