1 /*
2  * %kadu copyright begin%
3  * Copyright 2010, 2011 Piotr Galiszewski (piotr.galiszewski@kadu.im)
4  * Copyright 2009 Michał Podsiadlik (michal@kadu.net)
5  * Copyright 2009 Bartłomiej Zimoń (uzi18@o2.pl)
6  * Copyright 2010, 2011, 2012, 2013, 2014 Bartosz Brachaczek (b.brachaczek@gmail.com)
7  * Copyright 2009, 2010, 2011, 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 #include <QtCore/QSet>
25 #include <QtCore/QStringList>
26 #include <QtXml/QDomElement>
27 
28 #include "buddies/buddy-manager.h"
29 #include "buddies/group-storage.h"
30 #include "configuration/configuration-api.h"
31 #include "configuration/configuration-manager.h"
32 #include "configuration/configuration.h"
33 #include "gui/windows/message-dialog.h"
34 #include "icons/icons-manager.h"
35 #include "storage/storage-point.h"
36 #include "debug.h"
37 
38 #include "group-manager.h"
39 
GroupManager(QObject * parent)40 GroupManager::GroupManager(QObject *parent) :
41 		SimpleManager<Group>{parent}
42 {
43 }
44 
~GroupManager()45 GroupManager::~GroupManager()
46 {
47 }
48 
setConfigurationManager(ConfigurationManager * configurationManager)49 void GroupManager::setConfigurationManager(ConfigurationManager *configurationManager)
50 {
51 	m_configurationManager = configurationManager;
52 }
53 
setConfiguration(Configuration * configuration)54 void GroupManager::setConfiguration(Configuration *configuration)
55 {
56 	m_configuration = configuration;
57 }
58 
setIconsManager(IconsManager * iconsManager)59 void GroupManager::setIconsManager(IconsManager *iconsManager)
60 {
61 	m_iconsManager = iconsManager;
62 }
63 
setGroupStorage(GroupStorage * groupStorage)64 void GroupManager::setGroupStorage(GroupStorage *groupStorage)
65 {
66 	m_groupStorage = groupStorage;
67 }
68 
init()69 void GroupManager::init()
70 {
71 	m_configurationManager->registerStorableObject(this);
72 }
73 
done()74 void GroupManager::done()
75 {
76 	m_configurationManager->unregisterStorableObject(this);
77 }
78 
importConfiguration()79 void GroupManager::importConfiguration()
80 {
81 	QMutexLocker locker(&mutex());
82 
83 	auto sp = storage();
84 	if (!sp || !sp->storage())
85 		return;
86 
87 	QSet<QString> groups;
88 	ConfigurationApi *configurationStorage = sp->storage();
89 
90 	QDomElement contactsNode = configurationStorage->getNode("Contacts", ConfigurationApi::ModeFind);
91 	if (contactsNode.isNull())
92 		return;
93 
94 	QVector<QDomElement> contactsElements = configurationStorage->getNodes(contactsNode, "Contact");
95 	foreach (const QDomElement &contactElement, contactsElements)
96 		foreach (const QString &newGroup, contactElement.attribute("groups").split(',', QString::SkipEmptyParts))
97 			groups << newGroup;
98 
99 	foreach (const QString &groupName, groups)
100 		byName(groupName); // it can do import, too
101 }
102 
load()103 void GroupManager::load()
104 {
105 	QMutexLocker locker(&mutex());
106 
107 	QDomElement groupsNode = m_configuration->api()->getNode("Groups", ConfigurationApi::ModeFind);
108 	if (groupsNode.isNull())
109 	{
110 		importConfiguration();
111 		setState(StateLoaded);
112 		return;
113 	}
114 
115 	SimpleManager<Group>::load();
116 }
117 
store()118 void GroupManager::store()
119 {
120 	QMutexLocker locker(&mutex());
121 
122 	emit saveGroupData();
123 
124 	SimpleManager<Group>::store();
125 }
126 
loadStubFromStorage(const std::shared_ptr<StoragePoint> & storagePoint)127 Group GroupManager::loadStubFromStorage(const std::shared_ptr<StoragePoint> &storagePoint)
128 {
129 	return m_groupStorage->loadStubFromStorage(storagePoint);
130 }
131 
byName(const QString & name,bool create)132 Group GroupManager::byName(const QString &name, bool create)
133 {
134 	QMutexLocker locker(&mutex());
135 
136 	if (name.isEmpty())
137 		return Group::null;
138 
139 	ensureLoaded();
140 
141 	foreach (Group group, items())
142 		if (name == group.name())
143 			return group;
144 
145 	if (!create)
146 		return Group::null;
147 
148 	auto group = m_groupStorage->create();
149 	group.data()->importConfiguration(name);
150 	addItem(group);
151 
152 	return group;
153 }
154 
validateGroupName(Group group,const QString & newName)155 QString GroupManager::validateGroupName(Group group, const QString &newName)
156 {
157 	if (newName.isEmpty())
158 		return tr("Group name must not be empty");
159 
160 	if (newName.contains(","))
161 		return tr("Group name must not contain '%1'").arg(',');
162 
163 	if (newName.contains(";"))
164 		return tr("Group name must not contain '%1'").arg(';');
165 
166 	bool number;
167 	newName.toLong(&number);
168 	if (number)
169 		return tr("Group name must not be a number");
170 
171 	// TODO All translations
172  	if (newName == tr("All"))
173 		return tr("Group name must not be '%1'").arg(newName);
174 
175 	auto existing = byName(newName, false);
176 	if (existing && existing != group)
177 		return tr("Group '%1' already exists").arg(newName);
178 
179 	return QString{};
180 }
181 
182 // TODO: move some of this to %like-encoding, so we don't block normal names
acceptableGroupName(const QString & groupName,bool acceptExistingGroupName)183 bool GroupManager::acceptableGroupName(const QString &groupName, bool acceptExistingGroupName)
184 {
185 	kdebugf();
186 	if (groupName.isEmpty())
187 	{
188 		kdebugf2();
189 		return false;
190 	}
191 
192 	if (groupName.contains(","))
193 	{
194 		MessageDialog::show(m_iconsManager->iconByPath(KaduIcon("dialog-warning")), tr("Kadu"), tr("'%1' is prohibited").arg(','));
195 		kdebugf2();
196 		return false;
197 	}
198 
199 	if (groupName.contains(";"))
200 	{
201 		MessageDialog::show(m_iconsManager->iconByPath(KaduIcon("dialog-warning")), tr("Kadu"), tr("'%1' is prohibited").arg(';'));
202 		kdebugf2();
203 		return false;
204 	}
205 
206 	bool number;
207 	groupName.toLong(&number);
208 	if (number)
209 	{
210 		// because of gadu-gadu contact list format...
211 		MessageDialog::show(m_iconsManager->iconByPath(KaduIcon("dialog-warning")), tr("Kadu"), tr("Numbers are prohibited"));
212 		kdebugf2();
213 		return false;
214 	}
215 
216 	// TODO All translations
217  	if (groupName == tr("All"))
218 	{
219 		MessageDialog::show(m_iconsManager->iconByPath(KaduIcon("dialog-warning")), tr("Kadu"), tr("Group name %1 is prohibited").arg(groupName));
220  		kdebugf2();
221  		return false;
222 	}
223 
224 	if (!acceptExistingGroupName && byName(groupName, false))
225  	{
226 		MessageDialog::show(m_iconsManager->iconByPath(KaduIcon("dialog-warning")), tr("Kadu"), tr("Group of that name already exists!"));
227  		kdebugf2();
228  		return false;
229  	}
230 
231 	kdebugf2();
232 	return true;
233 }
234 
groupDataUpdated()235 void GroupManager::groupDataUpdated()
236 {
237 	Group group(sender());
238 	if (!group.isNull())
239 		emit groupUpdated(group);
240 }
241 
itemAboutToBeAdded(Group item)242 void GroupManager::itemAboutToBeAdded(Group item)
243 {
244 	connect(item, SIGNAL(updated()), this, SLOT(groupDataUpdated()));
245 	emit groupAboutToBeAdded(item);
246 }
247 
itemAdded(Group item)248 void GroupManager::itemAdded(Group item)
249 {
250 	emit groupAdded(item);
251 }
252 
itemAboutToBeRemoved(Group item)253 void GroupManager::itemAboutToBeRemoved(Group item)
254 {
255 	emit groupAboutToBeRemoved(item);
256 }
257 
itemRemoved(Group item)258 void GroupManager::itemRemoved(Group item)
259 {
260 	disconnect(item, 0, this, 0);
261 	emit groupRemoved(item);
262 }
263 
264 #include "moc_group-manager.cpp"
265