1 /* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2010-09-27
7 * Description : Interface for info stored about a face tag in the database
8 *
9 * Copyright (C) 2010 by Aditya Bhatt <adityabhatt1991 at gmail dot com>
10 * Copyright (C) 2010-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
11 *
12 * This program is free software; you can redistribute it
13 * and/or modify it under the terms of the GNU General
14 * Public License as published by the Free Software Foundation;
15 * either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * ============================================================ */
24
25 #include "facetagsiface.h"
26
27 // Qt includes
28
29 #include <QStringList>
30
31 // Local includes
32
33 #include "digikam_debug.h"
34 #include "coredbconstants.h"
35 #include "tagscache.h"
36 #include "facetags.h"
37
38 namespace Digikam
39 {
40
FaceTagsIface()41 FaceTagsIface::FaceTagsIface()
42 : m_type(InvalidFace),
43 m_imageId(0),
44 m_tagId(0)
45 {
46 }
47
FaceTagsIface(Type type,qlonglong imageId,int tagId,const TagRegion & region)48 FaceTagsIface::FaceTagsIface(Type type, qlonglong imageId, int tagId, const TagRegion& region)
49 : m_type(type),
50 m_imageId(imageId),
51 m_tagId(tagId),
52 m_region(region)
53 {
54 }
55
FaceTagsIface(const QString & attribute,qlonglong imageId,int tagId,const TagRegion & region)56 FaceTagsIface::FaceTagsIface(const QString& attribute, qlonglong imageId, int tagId, const TagRegion& region)
57 : m_imageId(imageId),
58 m_tagId(tagId),
59 m_region(region)
60 {
61 m_type = typeForAttribute(attribute, tagId);
62 }
63
isNull() const64 bool FaceTagsIface::isNull() const
65 {
66 return (m_type == InvalidFace);
67 }
68
type() const69 FaceTagsIface::Type FaceTagsIface::type() const
70 {
71 return m_type;
72 }
73
imageId() const74 qlonglong FaceTagsIface::imageId() const
75 {
76 return m_imageId;
77 }
78
tagId() const79 int FaceTagsIface::tagId() const
80 {
81 return m_tagId;
82 }
83
region() const84 TagRegion FaceTagsIface::region() const
85 {
86 return m_region;
87 }
88
setType(Type type)89 void FaceTagsIface::setType(Type type)
90 {
91 m_type = type;
92 }
93
setTagId(int tagId)94 void FaceTagsIface::setTagId(int tagId)
95 {
96 m_tagId = tagId;
97 }
98
setRegion(const TagRegion & region)99 void FaceTagsIface::setRegion(const TagRegion& region)
100 {
101 m_region = region;
102 }
103
operator ==(const FaceTagsIface & other) const104 bool FaceTagsIface::operator==(const FaceTagsIface& other) const
105 {
106 return (
107 (m_tagId == other.m_tagId) &&
108 (m_imageId == other.m_imageId) &&
109 (m_type == other.m_type) &&
110 (m_region == other.m_region)
111 );
112 }
113
attributesForFlags(TypeFlags flags)114 QStringList FaceTagsIface::attributesForFlags(TypeFlags flags)
115 {
116 QStringList attributes;
117
118 for (int i = FaceTagsIface::TypeFirst ; i <= FaceTagsIface::TypeLast ; i <<= 1)
119 {
120 if (flags & FaceTagsIface::Type(i))
121 {
122 QString attribute = attributeForType(FaceTagsIface::Type(i));
123
124 if (!attributes.contains(attribute))
125 {
126 attributes << attribute;
127 }
128 }
129 }
130
131 return attributes;
132 }
133
attributeForType(Type type)134 QString FaceTagsIface::attributeForType(Type type)
135 {
136 if ((type == FaceTagsIface::UnknownName) || (type == FaceTagsIface::UnconfirmedName))
137 {
138 return ImageTagPropertyName::autodetectedFace();
139 }
140
141 if (type == FaceTagsIface::ConfirmedName)
142 {
143 return ImageTagPropertyName::tagRegion();
144 }
145
146 if (type == FaceTagsIface::IgnoredName)
147 {
148 return ImageTagPropertyName::ignoredFace();
149 }
150
151 if (type == FaceTagsIface::FaceForTraining)
152 {
153 return ImageTagPropertyName::faceToTrain();
154 }
155
156 return QString();
157 }
158
typeForId(int tagId)159 FaceTagsIface::Type FaceTagsIface::typeForId(int tagId)
160 {
161 if (!FaceTags::isPerson(tagId))
162 {
163 return InvalidFace;
164 }
165
166 if (FaceTags::isTheUnknownPerson(tagId))
167 {
168 return UnknownName;
169 }
170 else if (FaceTags::isTheUnconfirmedPerson(tagId))
171 {
172 return UnconfirmedName;
173 }
174 else if (FaceTags::isTheIgnoredPerson(tagId))
175 {
176 return IgnoredName;
177 }
178
179 return ConfirmedName;
180 }
181
typeForAttribute(const QString & attribute,int tagId)182 FaceTagsIface::Type FaceTagsIface::typeForAttribute(const QString& attribute, int tagId)
183 {
184 if (attribute == ImageTagPropertyName::autodetectedFace())
185 {
186 if (tagId && TagsCache::instance()->hasProperty(tagId, TagPropertyName::unknownPerson()))
187 {
188 return FaceTagsIface::UnknownName;
189 }
190 else
191 {
192 return FaceTagsIface::UnconfirmedName;
193 }
194 }
195 else if (attribute == ImageTagPropertyName::ignoredFace())
196 {
197 return FaceTagsIface::IgnoredName;
198 }
199 else if (attribute == ImageTagPropertyName::tagRegion())
200 {
201 return FaceTagsIface::ConfirmedName;
202 }
203 else if (attribute == ImageTagPropertyName::faceToTrain())
204 {
205 return FaceTagsIface::FaceForTraining;
206 }
207
208 return FaceTagsIface::InvalidFace;
209 }
210
fromVariant(const QVariant & var)211 FaceTagsIface FaceTagsIface::fromVariant(const QVariant& var)
212 {
213 if (var.type() == QVariant::List)
214 {
215 QList<QVariant> list(var.toList());
216
217 if ((list.size() == 4) || (list.size() == 5))
218 {
219 return FaceTagsIface((Type)list.at(0).toInt(),
220 list.at(1).toLongLong(),
221 list.at(2).toInt(),
222 TagRegion::fromVariant(list.at(3)));
223 }
224 }
225
226 return FaceTagsIface();
227 }
228
toVariant() const229 QVariant FaceTagsIface::toVariant() const
230 {
231 // this is still not perfect, with QList<QVariant> being inefficient
232 // we must keep to native types, to make operator== work.
233
234 QList<QVariant> list;
235 list << (int)m_type;
236 list << m_imageId;
237 list << m_tagId;
238 list << m_region.toVariant();
239
240 return list;
241 }
242
fromListing(qlonglong imageId,const QList<QVariant> & extraValues)243 FaceTagsIface FaceTagsIface::fromListing(qlonglong imageId, const QList<QVariant>& extraValues)
244 {
245 if (extraValues.size() < 3)
246 {
247 return FaceTagsIface();
248 }
249
250 // See imagelister.cpp: value - property - tagId
251
252 int tagId = extraValues.at(2).toInt();
253 QString attribute = extraValues.at(1).toString();
254 QString value = extraValues.at(0).toString();
255 /*
256 qCDebug(DIGIKAM_DATABASE_LOG) << tagId << attribute << value;
257 */
258 return FaceTagsIface(attribute,
259 imageId, tagId,
260 TagRegion(value));
261 }
262
getAutodetectedPersonString() const263 QString FaceTagsIface::getAutodetectedPersonString() const
264 {
265 if (isUnconfirmedType())
266 {
267 return (QString::number(tagId()) +
268 QLatin1Char(',') +
269 ImageTagPropertyName::autodetectedFace() +
270 QLatin1Char(',') +
271 (TagRegion(region().toRect())).toXml());
272 }
273 else
274 {
275 return QString();
276 }
277 }
278
operator <<(QDebug dbg,const FaceTagsIface & f)279 QDebug operator<<(QDebug dbg, const FaceTagsIface& f)
280 {
281 dbg.nospace() << "FaceTagsIface(" << f.type()
282 << ", image " << f.imageId()
283 << ", tag " << f.tagId()
284 << ", region" << f.region();
285 return dbg;
286 }
287
288 } // namespace Digikam
289