1 /*
2 * Copyright (C) 2012 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 "EntryAttributes.h"
19
20 const QString EntryAttributes::TitleKey = "Title";
21 const QString EntryAttributes::UserNameKey = "UserName";
22 const QString EntryAttributes::PasswordKey = "Password";
23 const QString EntryAttributes::URLKey = "URL";
24 const QString EntryAttributes::NotesKey = "Notes";
25 const QStringList EntryAttributes::DefaultAttributes(QStringList() << TitleKey << UserNameKey
26 << PasswordKey << URLKey << NotesKey);
27
EntryAttributes(QObject * parent)28 EntryAttributes::EntryAttributes(QObject* parent)
29 : QObject(parent)
30 {
31 clear();
32 }
33
keys() const34 QList<QString> EntryAttributes::keys() const
35 {
36 return m_attributes.keys();
37 }
38
hasKey(const QString & key) const39 bool EntryAttributes::hasKey(const QString& key) const
40 {
41 return m_attributes.keys().contains(key);
42 }
43
customKeys()44 QList<QString> EntryAttributes::customKeys()
45 {
46 QList<QString> customKeys;
47 const QList<QString> keyList = keys();
48 for (const QString& key : keyList) {
49 if (!isDefaultAttribute(key)) {
50 customKeys.append(key);
51 }
52 }
53 return customKeys;
54 }
55
value(const QString & key) const56 QString EntryAttributes::value(const QString& key) const
57 {
58 return m_attributes.value(key);
59 }
60
isProtected(const QString & key) const61 bool EntryAttributes::isProtected(const QString& key) const
62 {
63 return m_protectedAttributes.contains(key);
64 }
65
set(const QString & key,const QString & value,bool protect)66 void EntryAttributes::set(const QString& key, const QString& value, bool protect)
67 {
68 bool emitModified = false;
69
70 bool addAttribute = !m_attributes.contains(key);
71 bool changeValue = !addAttribute && (m_attributes.value(key) != value);
72 bool defaultAttribute = isDefaultAttribute(key);
73
74 if (addAttribute && !defaultAttribute) {
75 Q_EMIT aboutToBeAdded(key);
76 }
77
78 if (addAttribute || changeValue) {
79 m_attributes.insert(key, value);
80 emitModified = true;
81 }
82
83 if (protect) {
84 if (!m_protectedAttributes.contains(key)) {
85 emitModified = true;
86 }
87 m_protectedAttributes.insert(key);
88 }
89 else if (m_protectedAttributes.remove(key)) {
90 emitModified = true;
91 }
92
93 if (emitModified) {
94 Q_EMIT modified();
95 }
96
97 if (defaultAttribute && changeValue) {
98 Q_EMIT defaultKeyModified();
99 }
100 else if (addAttribute) {
101 Q_EMIT added(key);
102 }
103 else if (emitModified) {
104 Q_EMIT customKeyModified(key);
105 }
106 }
107
remove(const QString & key)108 void EntryAttributes::remove(const QString& key)
109 {
110 Q_ASSERT(!isDefaultAttribute(key));
111
112 if (!m_attributes.contains(key)) {
113 Q_ASSERT(false);
114 return;
115 }
116
117 Q_EMIT aboutToBeRemoved(key);
118
119 m_attributes.remove(key);
120 m_protectedAttributes.remove(key);
121
122 Q_EMIT removed(key);
123 Q_EMIT modified();
124 }
125
rename(const QString & oldKey,const QString & newKey)126 void EntryAttributes::rename(const QString& oldKey, const QString& newKey)
127 {
128 Q_ASSERT(!isDefaultAttribute(oldKey));
129 Q_ASSERT(!isDefaultAttribute(newKey));
130
131 if (!m_attributes.contains(oldKey)) {
132 Q_ASSERT(false);
133 return;
134 }
135
136 if (m_attributes.contains(newKey)) {
137 Q_ASSERT(false);
138 return;
139 }
140
141 QString data = value(oldKey);
142 bool protect = isProtected(oldKey);
143
144 Q_EMIT aboutToRename(oldKey, newKey);
145
146 m_attributes.remove(oldKey);
147 m_attributes.insert(newKey, data);
148 if (protect) {
149 m_protectedAttributes.remove(oldKey);
150 m_protectedAttributes.insert(newKey);
151 }
152
153 Q_EMIT modified();
154 Q_EMIT renamed(oldKey, newKey);
155 }
156
copyCustomKeysFrom(const EntryAttributes * other)157 void EntryAttributes::copyCustomKeysFrom(const EntryAttributes* other)
158 {
159 if (!areCustomKeysDifferent(other)) {
160 return;
161 }
162
163 Q_EMIT aboutToBeReset();
164
165 // remove all non-default keys
166 const QList<QString> keyList = keys();
167 for (const QString& key : keyList) {
168 if (!isDefaultAttribute(key)) {
169 m_attributes.remove(key);
170 m_protectedAttributes.remove(key);
171 }
172 }
173
174 const QList<QString> otherKeyList = other->keys();
175 for (const QString& key : otherKeyList) {
176 if (!isDefaultAttribute(key)) {
177 m_attributes.insert(key, other->value(key));
178 if (other->isProtected(key)) {
179 m_protectedAttributes.insert(key);
180 }
181 }
182 }
183
184 Q_EMIT reset();
185 Q_EMIT modified();
186 }
187
areCustomKeysDifferent(const EntryAttributes * other)188 bool EntryAttributes::areCustomKeysDifferent(const EntryAttributes* other)
189 {
190 // check if they are equal ignoring the order of the keys
191 if (keys().toSet() != other->keys().toSet()) {
192 return true;
193 }
194
195 const QList<QString> keyList = keys();
196 for (const QString& key : keyList) {
197 if (isDefaultAttribute(key)) {
198 continue;
199 }
200
201 if (isProtected(key) != other->isProtected(key) || value(key) != other->value(key)) {
202 return true;
203 }
204 }
205
206 return false;
207 }
208
copyDataFrom(const EntryAttributes * other)209 void EntryAttributes::copyDataFrom(const EntryAttributes* other)
210 {
211 if (*this != *other) {
212 Q_EMIT aboutToBeReset();
213
214 m_attributes = other->m_attributes;
215 m_protectedAttributes = other->m_protectedAttributes;
216
217 Q_EMIT reset();
218 Q_EMIT modified();
219 }
220 }
221
operator ==(const EntryAttributes & other) const222 bool EntryAttributes::operator==(const EntryAttributes& other) const
223 {
224 return (m_attributes == other.m_attributes
225 && m_protectedAttributes == other.m_protectedAttributes);
226 }
227
operator !=(const EntryAttributes & other) const228 bool EntryAttributes::operator!=(const EntryAttributes& other) const
229 {
230 return (m_attributes != other.m_attributes
231 || m_protectedAttributes != other.m_protectedAttributes);
232 }
233
clear()234 void EntryAttributes::clear()
235 {
236 Q_EMIT aboutToBeReset();
237
238 m_attributes.clear();
239 m_protectedAttributes.clear();
240
241 for (const QString& key : DefaultAttributes) {
242 m_attributes.insert(key, "");
243 }
244
245 Q_EMIT reset();
246 Q_EMIT modified();
247 }
248
attributesSize()249 int EntryAttributes::attributesSize()
250 {
251 int size = 0;
252
253 QMapIterator<QString, QString> i(m_attributes);
254 while (i.hasNext()) {
255 i.next();
256 size += i.value().toUtf8().size();
257 }
258 return size;
259 }
260
isDefaultAttribute(const QString & key)261 bool EntryAttributes::isDefaultAttribute(const QString& key)
262 {
263 return DefaultAttributes.contains(key);
264 }
265