1 /*
2  * %kadu copyright begin%
3  * Copyright 2010, 2011, 2012 Piotr Galiszewski (piotr.galiszewski@kadu.im)
4  * Copyright 2010 Piotr Dąbrowski (ultr@ultr.pl)
5  * Copyright 2009 Bartłomiej Zimoń (uzi18@o2.pl)
6  * Copyright 2010, 2011, 2013, 2014 Bartosz Brachaczek (b.brachaczek@gmail.com)
7  * Copyright 2009, 2010, 2011, 2012, 2013, 2014 Rafał Przemysław Malinowski (rafal.przemyslaw.malinowski@gmail.com)
8  * %kadu copyright end%
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of
13  * the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 #pragma once
25 
26 #include "buddies/buddy-gender.h"
27 #include "misc/change-notifier.h"
28 #include "storage/shared.h"
29 #include "exports.h"
30 
31 #include <QtCore/QList>
32 #include <QtCore/QMap>
33 #include <QtCore/QPointer>
34 #include <QtCore/QSet>
35 #include <QtCore/QSharedData>
36 #include <QtCore/QString>
37 #include <QtCore/QStringList>
38 #include <QtCore/QUuid>
39 #include <QtXml/QDomElement>
40 #include <injeqt/injeqt.h>
41 
42 #define BuddyShared_PropertyDirtyWrite(type, name, capitalized_name) \
43 	void set##capitalized_name(type name) { ensureLoaded(); if (capitalized_name != name) { capitalized_name = name; changeNotifier().notify(); markContactsDirty(); } }
44 
45 #define BuddyShared_PropertyDirty(type, name, capitalized_name) \
46 	KaduShared_PropertyRead(type, name, capitalized_name) \
47 	BuddyShared_PropertyDirtyWrite(type, name, capitalized_name)
48 
49 #define BuddyShared_PropertySubscriptionRead(capitalized_name) \
50 	bool is##capitalized_name() { ensureLoaded(); return capitalized_name; }
51 
52 #define BuddyShared_PropertySubscriptionWrite(capitalized_name) \
53 	void set##capitalized_name(bool name) { ensureLoaded(); if (capitalized_name != name) { capitalized_name = name;  buddySubscriptionChanged(); changeNotifier().notify(); } }
54 
55 #define BuddyShared_PropertySubscriptionDirtyWrite(capitalized_name) \
56 	void set##capitalized_name(bool name) { ensureLoaded(); if (capitalized_name != name) { capitalized_name = name;  buddySubscriptionChanged(); changeNotifier().notify(); markContactsDirty(); } }
57 
58 #define BuddyShared_PropertySubscription(capitalized_name) \
59 	BuddyShared_PropertySubscriptionRead(capitalized_name) \
60 	BuddyShared_PropertySubscriptionWrite(capitalized_name)
61 
62 #define BuddyShared_PropertySubscriptionDirty(capitalized_name) \
63 	BuddyShared_PropertySubscriptionRead(capitalized_name) \
64 	BuddyShared_PropertySubscriptionDirtyWrite(capitalized_name)
65 
66 class Account;
67 class AvatarManager;
68 class Avatar;
69 class BuddyManager;
70 class ConfigurationApi;
71 class Contact;
72 class GroupManager;
73 class Group;
74 class Myself;
75 
76 class KADUAPI BuddyShared : public Shared
77 {
78 	Q_OBJECT
79 
80 	QPointer<AvatarManager> m_avatarManager;
81 	QPointer<BuddyManager> m_buddyManager;
82 	QPointer<GroupManager> m_groupManager;
83 	QPointer<Myself> m_myself;
84 
85 	bool CollectingGarbage;
86 
87 	QMap<QString, QString> CustomData;
88 	QList<Contact> Contacts;
89 
90 	Avatar *BuddyAvatar;
91 	QString Display;
92 	QString FirstName;
93 	QString LastName;
94 	QString FamilyName;
95 	QString City;
96 	QString FamilyCity;
97 	QString NickName;
98 	QString HomePhone;
99 	QString Mobile;
100 	QString Email;
101 	QString Website;
102 	unsigned short BirthYear;
103 	BuddyGender Gender;
104 	QSet<Group> Groups;
105 	bool PreferHigherStatuses;
106 
107 	bool Anonymous;
108 	bool Temporary;
109 	bool Blocked;
110 	bool OfflineTo;
111 
112 	bool doAddToGroup(const Group &group);
113 	bool doRemoveFromGroup(const Group &group);
114 
115 	int priorityForNewContact();
116 
117 private slots:
118 	INJEQT_SET void setAvatarManager(AvatarManager *avatarManager);
119 	INJEQT_SET void setBuddyManager(BuddyManager *buddyManager);
120 	INJEQT_SET void setGroupManager(GroupManager *groupManager);
121 	INJEQT_SET void setMyself(Myself *myself);
122 	INJEQT_INIT void init();
123 
124 	void avatarUpdated();
125 	void groupAboutToBeRemoved();
126 	void markContactsDirty();
127 
128 protected:
129 	virtual std::shared_ptr<StoragePoint> createStoragePoint();
130 
131 	virtual void load();
132 	virtual void store();
133 	virtual bool shouldStore();
134 
135 public:
136 	explicit BuddyShared(const QUuid &uuid = QUuid());
137 	virtual ~BuddyShared();
138 
139 	void collectGarbage();
140 
141 	virtual StorableObject * storageParent();
142 	virtual QString storageNodeName();
143 
144 	void importConfiguration(const QDomElement &parent);
145 	void importConfiguration(); // imports configuration from custom data values
146 
147 	virtual void aboutToBeRemoved();
148 
149 	QString id(const Account &account);
150 
customData()151 	QMap<QString, QString> & customData() { return CustomData; }
152 
153 	void addContact(const Contact &contact);
154 	void removeContact(const Contact &contact);
155 	QVector<Contact> contacts(const Account &account);
156 	const QList<Contact> & contacts();
157 
158 	void sortContacts();
159 	void normalizePriorities();
160 
161 	bool isEmpty(bool checkOnlyForContacts);
162 
163 	KaduShared_PropertyRead(const QSet<Group> &, groups, Groups)
164 	void setGroups(const QSet<Group> &groups);
165 	bool showInAllGroup();
166 	bool isInGroup(const Group &group);
167 	void addToGroup(const Group &group);
168 	void removeFromGroup(const Group &group);
169 
170 	KaduShared_PropertyReadDecl(Avatar, buddyAvatar)
171 	void setBuddyAvatar(const Avatar &buddyAvatar);
172 
173 	KaduShared_PropertyRead(const QString &, display, Display)
174 	void setDisplay(const QString &display);
175 
176 	BuddyShared_PropertyDirty(const QString &, firstName, FirstName)
177 	BuddyShared_PropertyDirty(const QString &, lastName, LastName)
178 	BuddyShared_PropertyDirty(const QString &, familyName, FamilyName)
179 	BuddyShared_PropertyDirty(const QString &, city, City)
180 	BuddyShared_PropertyDirty(const QString &, familyCity, FamilyCity)
181 	BuddyShared_PropertyDirty(const QString &, nickName, NickName)
182 	BuddyShared_PropertyDirty(const QString &, homePhone, HomePhone)
183 	BuddyShared_PropertyDirty(const QString &, mobile, Mobile)
184 	BuddyShared_PropertyDirty(const QString &, email, Email)
185 	BuddyShared_PropertyDirty(const QString &, website, Website)
186 	KaduShared_Property(unsigned short, birthYear, BirthYear)
187 	KaduShared_Property(BuddyGender, gender, Gender)
188 	KaduShared_Property(bool, preferHigherStatuses, PreferHigherStatuses)
189 	BuddyShared_PropertySubscription(Anonymous)
190 	KaduShared_PropertyBool(Temporary)
191 	BuddyShared_PropertySubscriptionDirty(Blocked)
192 	BuddyShared_PropertySubscriptionDirty(OfflineTo)
193 
194 	quint16 unreadMessagesCount();
195 
196 signals:
197 	void contactAboutToBeAdded(const Contact &contact);
198 	void contactAdded(const Contact &contact);
199 	void contactAboutToBeRemoved(const Contact &contact);
200 
201 	/**
202 	 * @note When this signal is emited contact.ownerBuddy value is still set to this buddy
203 	 */
204 	void contactRemoved(const Contact &contact);
205 
206 	void updated();
207 	void displayUpdated();
208 	void buddySubscriptionChanged();
209 
210 };
211