1 /*
2 * Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 or (at your option)
7 * version 3 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "Metadata.h"
19
20 #include "core/Entry.h"
21 #include "core/Group.h"
22 #include "core/Tools.h"
23
24 const int Metadata::DefaultHistoryMaxItems = 10;
25 const int Metadata::DefaultHistoryMaxSize = 6 * 1024 * 1024;
26
Metadata(QObject * parent)27 Metadata::Metadata(QObject* parent)
28 : QObject(parent)
29 , m_updateDatetime(true)
30 {
31 m_data.generator = "KeePassX";
32 m_data.maintenanceHistoryDays = 365;
33 m_data.masterKeyChangeRec = -1;
34 m_data.masterKeyChangeForce = -1;
35 m_data.historyMaxItems = DefaultHistoryMaxItems;
36 m_data.historyMaxSize = DefaultHistoryMaxSize;
37 m_data.recycleBinEnabled = true;
38 m_data.protectTitle = false;
39 m_data.protectUsername = false;
40 m_data.protectPassword = true;
41 m_data.protectUrl = false;
42 m_data.protectNotes = false;
43 // m_data.autoEnableVisualHiding = false;
44
45 QDateTime now = QDateTime::currentDateTimeUtc();
46 m_data.nameChanged = now;
47 m_data.descriptionChanged = now;
48 m_data.defaultUserNameChanged = now;
49 m_recycleBinChanged = now;
50 m_entryTemplatesGroupChanged = now;
51 m_masterKeyChanged = now;
52 }
53
set(P & property,const V & value)54 template <class P, class V> bool Metadata::set(P& property, const V& value)
55 {
56 if (property != value) {
57 property = value;
58 Q_EMIT modified();
59 return true;
60 }
61 else {
62 return false;
63 }
64 }
65
set(P & property,const V & value,QDateTime & dateTime)66 template <class P, class V> bool Metadata::set(P& property, const V& value, QDateTime& dateTime) {
67 if (property != value) {
68 property = value;
69 if (m_updateDatetime) {
70 dateTime = QDateTime::currentDateTimeUtc();
71 }
72 Q_EMIT modified();
73 return true;
74 }
75 else {
76 return false;
77 }
78 }
79
setUpdateDatetime(bool value)80 void Metadata::setUpdateDatetime(bool value)
81 {
82 m_updateDatetime = value;
83 }
84
copyAttributesFrom(const Metadata * other)85 void Metadata::copyAttributesFrom(const Metadata* other)
86 {
87 m_data = other->m_data;
88 }
89
generator() const90 QString Metadata::generator() const
91 {
92 return m_data.generator;
93 }
94
name() const95 QString Metadata::name() const
96 {
97 return m_data.name;
98 }
99
nameChanged() const100 QDateTime Metadata::nameChanged() const
101 {
102 return m_data.nameChanged;
103 }
104
description() const105 QString Metadata::description() const
106 {
107 return m_data.description;
108 }
109
descriptionChanged() const110 QDateTime Metadata::descriptionChanged() const
111 {
112 return m_data.descriptionChanged;
113 }
114
defaultUserName() const115 QString Metadata::defaultUserName() const
116 {
117 return m_data.defaultUserName;
118 }
119
defaultUserNameChanged() const120 QDateTime Metadata::defaultUserNameChanged() const
121 {
122 return m_data.defaultUserNameChanged;
123 }
124
maintenanceHistoryDays() const125 int Metadata::maintenanceHistoryDays() const
126 {
127 return m_data.maintenanceHistoryDays;
128 }
129
color() const130 QColor Metadata::color() const
131 {
132 return m_data.color;
133 }
134
protectTitle() const135 bool Metadata::protectTitle() const
136 {
137 return m_data.protectTitle;
138 }
139
protectUsername() const140 bool Metadata::protectUsername() const
141 {
142 return m_data.protectUsername;
143 }
144
protectPassword() const145 bool Metadata::protectPassword() const
146 {
147 return m_data.protectPassword;
148 }
149
protectUrl() const150 bool Metadata::protectUrl() const
151 {
152 return m_data.protectUrl;
153 }
154
protectNotes() const155 bool Metadata::protectNotes() const
156 {
157 return m_data.protectNotes;
158 }
159
160 /*bool Metadata::autoEnableVisualHiding() const
161 {
162 return m_autoEnableVisualHiding;
163 }*/
164
customIcon(const Uuid & uuid) const165 QImage Metadata::customIcon(const Uuid& uuid) const
166 {
167 return m_customIcons.value(uuid);
168 }
169
customIconPixmap(const Uuid & uuid) const170 QPixmap Metadata::customIconPixmap(const Uuid& uuid) const
171 {
172 QPixmap pixmap;
173
174 if (!m_customIcons.contains(uuid)) {
175 return pixmap;
176 }
177
178 QPixmapCache::Key& cacheKey = m_customIconCacheKeys[uuid];
179
180 if (!QPixmapCache::find(cacheKey, &pixmap)) {
181 pixmap = QPixmap::fromImage(m_customIcons.value(uuid));
182 cacheKey = QPixmapCache::insert(pixmap);
183 }
184
185 return pixmap;
186 }
187
customIconScaledPixmap(const Uuid & uuid) const188 QPixmap Metadata::customIconScaledPixmap(const Uuid& uuid) const
189 {
190 QPixmap pixmap;
191
192 if (!m_customIcons.contains(uuid)) {
193 return pixmap;
194 }
195
196 QPixmapCache::Key& cacheKey = m_customIconScaledCacheKeys[uuid];
197
198 if (!QPixmapCache::find(cacheKey, &pixmap)) {
199 QImage image = m_customIcons.value(uuid).scaled(16, 16, Qt::KeepAspectRatio, Qt::SmoothTransformation);
200 pixmap = QPixmap::fromImage(image);
201 cacheKey = QPixmapCache::insert(pixmap);
202 }
203
204 return pixmap;
205 }
206
containsCustomIcon(const Uuid & uuid) const207 bool Metadata::containsCustomIcon(const Uuid& uuid) const
208 {
209 return m_customIcons.contains(uuid);
210 }
211
customIcons() const212 QHash<Uuid, QImage> Metadata::customIcons() const
213 {
214 return m_customIcons;
215 }
216
customIconsScaledPixmaps() const217 QHash<Uuid, QPixmap> Metadata::customIconsScaledPixmaps() const
218 {
219 QHash<Uuid, QPixmap> result;
220
221 for (const Uuid& uuid : m_customIconsOrder) {
222 result.insert(uuid, customIconScaledPixmap(uuid));
223 }
224
225 return result;
226 }
227
customIconsOrder() const228 QList<Uuid> Metadata::customIconsOrder() const
229 {
230 return m_customIconsOrder;
231 }
232
recycleBinEnabled() const233 bool Metadata::recycleBinEnabled() const
234 {
235 return m_data.recycleBinEnabled;
236 }
237
recycleBin()238 Group* Metadata::recycleBin()
239 {
240 return m_recycleBin;
241 }
242
recycleBin() const243 const Group* Metadata::recycleBin() const
244 {
245 return m_recycleBin;
246 }
247
recycleBinChanged() const248 QDateTime Metadata::recycleBinChanged() const
249 {
250 return m_recycleBinChanged;
251 }
252
entryTemplatesGroup() const253 const Group* Metadata::entryTemplatesGroup() const
254 {
255 return m_entryTemplatesGroup;
256 }
257
entryTemplatesGroupChanged() const258 QDateTime Metadata::entryTemplatesGroupChanged() const
259 {
260 return m_entryTemplatesGroupChanged;
261 }
262
lastSelectedGroup() const263 const Group* Metadata::lastSelectedGroup() const
264 {
265 return m_lastSelectedGroup;
266 }
267
lastTopVisibleGroup() const268 const Group* Metadata::lastTopVisibleGroup() const
269 {
270 return m_lastTopVisibleGroup;
271 }
272
masterKeyChanged() const273 QDateTime Metadata::masterKeyChanged() const
274 {
275 return m_masterKeyChanged;
276 }
277
masterKeyChangeRec() const278 int Metadata::masterKeyChangeRec() const
279 {
280 return m_data.masterKeyChangeRec;
281 }
282
masterKeyChangeForce() const283 int Metadata::masterKeyChangeForce() const
284 {
285 return m_data.masterKeyChangeForce;
286 }
287
historyMaxItems() const288 int Metadata::historyMaxItems() const
289 {
290 return m_data.historyMaxItems;
291 }
292
historyMaxSize() const293 int Metadata::historyMaxSize() const
294 {
295 return m_data.historyMaxSize;
296 }
297
customFields() const298 QHash<QString, QString> Metadata::customFields() const
299 {
300 return m_customFields;
301 }
302
setGenerator(const QString & value)303 void Metadata::setGenerator(const QString& value)
304 {
305 set(m_data.generator, value);
306 }
307
setName(const QString & value)308 void Metadata::setName(const QString& value)
309 {
310 if (set(m_data.name, value, m_data.nameChanged)) {
311 Q_EMIT nameTextChanged();
312 }
313 }
314
setNameChanged(const QDateTime & value)315 void Metadata::setNameChanged(const QDateTime& value)
316 {
317 Q_ASSERT(value.timeSpec() == Qt::UTC);
318 m_data.nameChanged = value;
319 }
320
setDescription(const QString & value)321 void Metadata::setDescription(const QString& value)
322 {
323 set(m_data.description, value, m_data.descriptionChanged);
324 }
325
setDescriptionChanged(const QDateTime & value)326 void Metadata::setDescriptionChanged(const QDateTime& value)
327 {
328 Q_ASSERT(value.timeSpec() == Qt::UTC);
329 m_data.descriptionChanged = value;
330 }
331
setDefaultUserName(const QString & value)332 void Metadata::setDefaultUserName(const QString& value)
333 {
334 set(m_data.defaultUserName, value, m_data.defaultUserNameChanged);
335 }
336
setDefaultUserNameChanged(const QDateTime & value)337 void Metadata::setDefaultUserNameChanged(const QDateTime& value)
338 {
339 Q_ASSERT(value.timeSpec() == Qt::UTC);
340 m_data.defaultUserNameChanged = value;
341 }
342
setMaintenanceHistoryDays(int value)343 void Metadata::setMaintenanceHistoryDays(int value)
344 {
345 set(m_data.maintenanceHistoryDays, value);
346 }
347
setColor(const QColor & value)348 void Metadata::setColor(const QColor& value)
349 {
350 set(m_data.color, value);
351 }
352
setProtectTitle(bool value)353 void Metadata::setProtectTitle(bool value)
354 {
355 set(m_data.protectTitle, value);
356 }
357
setProtectUsername(bool value)358 void Metadata::setProtectUsername(bool value)
359 {
360 set(m_data.protectUsername, value);
361 }
362
setProtectPassword(bool value)363 void Metadata::setProtectPassword(bool value)
364 {
365 set(m_data.protectPassword, value);
366 }
367
setProtectUrl(bool value)368 void Metadata::setProtectUrl(bool value)
369 {
370 set(m_data.protectUrl, value);
371 }
372
setProtectNotes(bool value)373 void Metadata::setProtectNotes(bool value)
374 {
375 set(m_data.protectNotes, value);
376 }
377
378 /*void Metadata::setAutoEnableVisualHiding(bool value)
379 {
380 set(m_autoEnableVisualHiding, value);
381 }*/
382
addCustomIcon(const Uuid & uuid,const QImage & icon)383 void Metadata::addCustomIcon(const Uuid& uuid, const QImage& icon)
384 {
385 Q_ASSERT(!uuid.isNull());
386 Q_ASSERT(!m_customIcons.contains(uuid));
387
388 m_customIcons.insert(uuid, icon);
389 // reset cache in case there is also an icon with that uuid
390 m_customIconCacheKeys[uuid] = QPixmapCache::Key();
391 m_customIconScaledCacheKeys[uuid] = QPixmapCache::Key();
392 m_customIconsOrder.append(uuid);
393 Q_ASSERT(m_customIcons.count() == m_customIconsOrder.count());
394 Q_EMIT modified();
395 }
396
addCustomIconScaled(const Uuid & uuid,const QImage & icon)397 void Metadata::addCustomIconScaled(const Uuid& uuid, const QImage& icon)
398 {
399 QImage iconScaled;
400
401 // scale down to 128x128 if icon is larger
402 if (icon.width() > 128 || icon.height() > 128) {
403 iconScaled = icon.scaled(QSize(128, 128), Qt::KeepAspectRatio,
404 Qt::SmoothTransformation);
405 }
406 else {
407 iconScaled = icon;
408 }
409
410 addCustomIcon(uuid, iconScaled);
411 }
412
removeCustomIcon(const Uuid & uuid)413 void Metadata::removeCustomIcon(const Uuid& uuid)
414 {
415 Q_ASSERT(!uuid.isNull());
416 Q_ASSERT(m_customIcons.contains(uuid));
417
418 m_customIcons.remove(uuid);
419 QPixmapCache::remove(m_customIconCacheKeys.value(uuid));
420 m_customIconCacheKeys.remove(uuid);
421 QPixmapCache::remove(m_customIconScaledCacheKeys.value(uuid));
422 m_customIconScaledCacheKeys.remove(uuid);
423 m_customIconsOrder.removeAll(uuid);
424 Q_ASSERT(m_customIcons.count() == m_customIconsOrder.count());
425 Q_EMIT modified();
426 }
427
copyCustomIcons(const QSet<Uuid> & iconList,const Metadata * otherMetadata)428 void Metadata::copyCustomIcons(const QSet<Uuid>& iconList, const Metadata* otherMetadata)
429 {
430 for (const Uuid& uuid : iconList) {
431 Q_ASSERT(otherMetadata->containsCustomIcon(uuid));
432
433 if (!containsCustomIcon(uuid) && otherMetadata->containsCustomIcon(uuid)) {
434 addCustomIcon(uuid, otherMetadata->customIcon(uuid));
435 }
436 }
437 }
438
setRecycleBinEnabled(bool value)439 void Metadata::setRecycleBinEnabled(bool value)
440 {
441 set(m_data.recycleBinEnabled, value);
442 }
443
setRecycleBin(Group * group)444 void Metadata::setRecycleBin(Group* group)
445 {
446 set(m_recycleBin, group, m_recycleBinChanged);
447 }
448
setRecycleBinChanged(const QDateTime & value)449 void Metadata::setRecycleBinChanged(const QDateTime& value)
450 {
451 Q_ASSERT(value.timeSpec() == Qt::UTC);
452 m_recycleBinChanged = value;
453 }
454
setEntryTemplatesGroup(Group * group)455 void Metadata::setEntryTemplatesGroup(Group* group)
456 {
457 set(m_entryTemplatesGroup, group, m_entryTemplatesGroupChanged);
458 }
459
setEntryTemplatesGroupChanged(const QDateTime & value)460 void Metadata::setEntryTemplatesGroupChanged(const QDateTime& value)
461 {
462 Q_ASSERT(value.timeSpec() == Qt::UTC);
463 m_entryTemplatesGroupChanged = value;
464 }
465
setLastSelectedGroup(Group * group)466 void Metadata::setLastSelectedGroup(Group* group)
467 {
468 set(m_lastSelectedGroup, group);
469 }
470
setLastTopVisibleGroup(Group * group)471 void Metadata::setLastTopVisibleGroup(Group* group)
472 {
473 set(m_lastTopVisibleGroup, group);
474 }
475
setMasterKeyChanged(const QDateTime & value)476 void Metadata::setMasterKeyChanged(const QDateTime& value)
477 {
478 Q_ASSERT(value.timeSpec() == Qt::UTC);
479 m_masterKeyChanged = value;
480 }
481
setMasterKeyChangeRec(int value)482 void Metadata::setMasterKeyChangeRec(int value)
483 {
484 set(m_data.masterKeyChangeRec, value);
485 }
486
setMasterKeyChangeForce(int value)487 void Metadata::setMasterKeyChangeForce(int value)
488 {
489 set(m_data.masterKeyChangeForce, value);
490 }
491
setHistoryMaxItems(int value)492 void Metadata::setHistoryMaxItems(int value)
493 {
494 set(m_data.historyMaxItems, value);
495 }
496
setHistoryMaxSize(int value)497 void Metadata::setHistoryMaxSize(int value)
498 {
499 set(m_data.historyMaxSize, value);
500 }
501
addCustomField(const QString & key,const QString & value)502 void Metadata::addCustomField(const QString& key, const QString& value)
503 {
504 Q_ASSERT(!m_customFields.contains(key));
505
506 m_customFields.insert(key, value);
507 Q_EMIT modified();
508 }
509
removeCustomField(const QString & key)510 void Metadata::removeCustomField(const QString& key)
511 {
512 Q_ASSERT(m_customFields.contains(key));
513
514 m_customFields.remove(key);
515 Q_EMIT modified();
516 }
517