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