File indexing completed on 2025-01-19 03:59:39
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2008-01-20 0007 * Description : User interface for searches 0008 * 0009 * SPDX-FileCopyrightText: 2008-2012 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0010 * SPDX-FileCopyrightText: 2011-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #include "searchgroup_p.h" 0017 0018 namespace Digikam 0019 { 0020 0021 SearchGroup::SearchGroup(SearchView* const parent) 0022 : AbstractSearchGroupContainer(parent), 0023 m_view (parent), 0024 m_layout (nullptr), 0025 m_label (nullptr), 0026 m_subgroupLayout (nullptr), 0027 m_groupType (FirstGroup) 0028 { 0029 } 0030 0031 void SearchGroup::setup(Type type) 0032 { 0033 m_groupType = type; 0034 0035 m_layout = new QVBoxLayout; 0036 m_layout->setContentsMargins(QMargins()); 0037 m_layout->setSpacing(0); 0038 0039 m_label = new SearchGroupLabel(m_view, m_groupType, this); 0040 m_layout->addWidget(m_label); 0041 0042 connect(m_label, SIGNAL(removeClicked()), 0043 this, SIGNAL(removeRequested())); 0044 0045 SearchFieldGroup* group = nullptr; 0046 SearchFieldGroupLabel* label = nullptr; 0047 0048 // To prevent Cppcheck warnings. 0049 (void)group; 0050 (void)label; 0051 0052 // ----- // 0053 0054 group = new SearchFieldGroup(this); 0055 group->addField(SearchField::createField(QLatin1String("keyword"), group)); 0056 m_fieldGroups << group; 0057 m_layout->addWidget(group); 0058 0059 // this group has no label. Need to show, else it is hidden forever 0060 0061 group->setFieldsVisible(true); 0062 0063 // ----- // 0064 0065 label = new SearchFieldGroupLabel(this); 0066 label->setTitle(i18n("File, Album, Tags")); 0067 group = new SearchFieldGroup(this); 0068 group->setLabel(label); 0069 0070 group->addField(SearchField::createField(QLatin1String("albumid"), group)); 0071 group->addField(SearchField::createField(QLatin1String("albumname"), group)); 0072 group->addField(SearchField::createField(QLatin1String("albumcollection"), group)); 0073 group->addField(SearchField::createField(QLatin1String("tagid"), group)); 0074 group->addField(SearchField::createField(QLatin1String("tagname"), group)); 0075 group->addField(SearchField::createField(QLatin1String("nottagged"), group)); 0076 group->addField(SearchField::createField(QLatin1String("filename"), group)); 0077 0078 m_fieldLabels << label; 0079 m_fieldGroups << group; 0080 m_layout->addWidget(label); 0081 m_layout->addWidget(group); 0082 0083 // ----- // 0084 0085 label = new SearchFieldGroupLabel(this); 0086 label->setTitle(i18n("Picture Properties")); 0087 group = new SearchFieldGroup(this); 0088 group->setLabel(label); 0089 0090 group->addField(SearchField::createField(QLatin1String("creationdate"), group)); 0091 group->addField(SearchField::createField(QLatin1String("creationtime"), group)); 0092 group->addField(SearchField::createField(QLatin1String("rating"), group)); 0093 group->addField(SearchField::createField(QLatin1String("labels"), group)); 0094 group->addField(SearchField::createField(QLatin1String("dimension"), group)); 0095 group->addField(SearchField::createField(QLatin1String("pageorientation"), group)); 0096 group->addField(SearchField::createField(QLatin1String("width"), group)); 0097 group->addField(SearchField::createField(QLatin1String("height"), group)); 0098 group->addField(SearchField::createField(QLatin1String("aspectratioimg"), group)); 0099 group->addField(SearchField::createField(QLatin1String("pixelsize"), group)); 0100 group->addField(SearchField::createField(QLatin1String("format"), group)); 0101 group->addField(SearchField::createField(QLatin1String("colordepth"), group)); 0102 group->addField(SearchField::createField(QLatin1String("colormodel"), group)); 0103 group->addField(SearchField::createField(QLatin1String("modificationdate"), group)); 0104 group->addField(SearchField::createField(QLatin1String("digitizationdate"), group)); 0105 group->addField(SearchField::createField(QLatin1String("filesize"), group)); 0106 group->addField(SearchField::createField(QLatin1String("bytesize"), group)); 0107 group->addField(SearchField::createField(QLatin1String("monthday"), group)); 0108 0109 m_fieldLabels << label; 0110 m_fieldGroups << group; 0111 m_layout->addWidget(label); 0112 m_layout->addWidget(group); 0113 0114 // ----- // 0115 0116 label = new SearchFieldGroupLabel(this); 0117 label->setTitle(i18n("Audio/Video Properties")); 0118 group = new SearchFieldGroup(this); 0119 group->setLabel(label); 0120 0121 group->addField(SearchField::createField(QLatin1String("videoaspectratio"), group)); 0122 group->addField(SearchField::createField(QLatin1String("videoduration"), group)); 0123 group->addField(SearchField::createField(QLatin1String("videoframerate"), group)); 0124 group->addField(SearchField::createField(QLatin1String("videocodec"), group)); 0125 group->addField(SearchField::createField(QLatin1String("videoaudiobitrate"), group)); 0126 group->addField(SearchField::createField(QLatin1String("videoaudiochanneltype"), group)); 0127 group->addField(SearchField::createField(QLatin1String("videoaudioCodec"), group)); 0128 0129 m_fieldLabels << label; 0130 m_fieldGroups << group; 0131 m_layout->addWidget(label); 0132 m_layout->addWidget(group); 0133 0134 // ----- // 0135 0136 label = new SearchFieldGroupLabel(this); 0137 label->setTitle(i18n("Caption, Comment, Title")); 0138 group = new SearchFieldGroup(this); 0139 group->setLabel(label); 0140 0141 group->addField(SearchField::createField(QLatin1String("creator"), group)); 0142 group->addField(SearchField::createField(QLatin1String("comment"), group)); 0143 group->addField(SearchField::createField(QLatin1String("commentauthor"), group)); 0144 group->addField(SearchField::createField(QLatin1String("headline"), group)); 0145 group->addField(SearchField::createField(QLatin1String("title"), group)); 0146 group->addField(SearchField::createField(QLatin1String("emptytext"), group)); 0147 0148 m_fieldLabels << label; 0149 m_fieldGroups << group; 0150 m_layout->addWidget(label); 0151 m_layout->addWidget(group); 0152 0153 // ----- // 0154 0155 label = new SearchFieldGroupLabel(this); 0156 label->setTitle(i18n("Photograph Information")); 0157 group = new SearchFieldGroup(this); 0158 group->setLabel(label); 0159 0160 group->addField(SearchField::createField(QLatin1String("make"), group)); 0161 group->addField(SearchField::createField(QLatin1String("model"), group)); 0162 group->addField(SearchField::createField(QLatin1String("lenses"), group)); 0163 group->addField(SearchField::createField(QLatin1String("aperture"), group)); 0164 group->addField(SearchField::createField(QLatin1String("focallength"), group)); 0165 group->addField(SearchField::createField(QLatin1String("focallength35"), group)); 0166 group->addField(SearchField::createField(QLatin1String("exposuretime"), group)); 0167 group->addField(SearchField::createField(QLatin1String("exposureprogram"), group)); 0168 group->addField(SearchField::createField(QLatin1String("exposuremode"), group)); 0169 group->addField(SearchField::createField(QLatin1String("sensitivity"), group)); 0170 group->addField(SearchField::createField(QLatin1String("orientation"), group)); 0171 group->addField(SearchField::createField(QLatin1String("flashmode"), group)); 0172 group->addField(SearchField::createField(QLatin1String("whitebalance"), group)); 0173 group->addField(SearchField::createField(QLatin1String("whitebalancecolortemperature"), group)); 0174 group->addField(SearchField::createField(QLatin1String("meteringmode"), group)); 0175 group->addField(SearchField::createField(QLatin1String("subjectdistance"), group)); 0176 group->addField(SearchField::createField(QLatin1String("subjectdistancecategory"), group)); 0177 0178 m_fieldLabels << label; 0179 m_fieldGroups << group; 0180 m_layout->addWidget(label); 0181 m_layout->addWidget(group); 0182 0183 // ----- // 0184 0185 label = new SearchFieldGroupLabel(this); 0186 label->setTitle(i18n("Geographic position")); 0187 group = new SearchFieldGroup(this); 0188 group->setLabel(label); 0189 0190 /* 0191 group->addField(SearchField::createField("latitude", group)); 0192 group->addField(SearchField::createField("longitude", group)); 0193 */ 0194 group->addField(SearchField::createField(QLatin1String("altitude"), group)); 0195 group->addField(SearchField::createField(QLatin1String("nogps"), group)); 0196 group->addField(SearchField::createField(QLatin1String("country"), group)); 0197 group->addField(SearchField::createField(QLatin1String("provinceState"), group)); 0198 group->addField(SearchField::createField(QLatin1String("city"), group)); 0199 group->addField(SearchField::createField(QLatin1String("location"), group)); 0200 0201 m_fieldLabels << label; 0202 m_fieldGroups << group; 0203 m_layout->addWidget(label); 0204 m_layout->addWidget(group); 0205 0206 // ----- // 0207 0208 label = new SearchFieldGroupLabel(this); 0209 label->setTitle(i18n("Face regions")); 0210 group = new SearchFieldGroup(this); 0211 group->setLabel(label); 0212 0213 group->addField(SearchField::createField(QLatin1String("faceregionscount"), group)); 0214 group->addField(SearchField::createField(QLatin1String("nofaceregions"), group)); 0215 0216 m_fieldLabels << label; 0217 m_fieldGroups << group; 0218 m_layout->addWidget(label); 0219 m_layout->addWidget(group); 0220 0221 // ----- // 0222 0223 // prepare subgroup layout 0224 0225 QHBoxLayout* const indentLayout = new QHBoxLayout; 0226 indentLayout->setContentsMargins(QMargins()); 0227 indentLayout->setSpacing(0); 0228 0229 QStyleOption option; 0230 option.initFrom(this); 0231 int indent = 5 * style()->pixelMetric(QStyle::PM_LayoutLeftMargin, &option, this); 0232 indent = qMax(indent, 20); 0233 indentLayout->addSpacing(indent); 0234 0235 m_subgroupLayout = new QVBoxLayout; 0236 m_subgroupLayout->setContentsMargins(QMargins()); 0237 m_subgroupLayout->setSpacing(0); 0238 0239 indentLayout->addLayout(m_subgroupLayout); 0240 0241 m_layout->addLayout(indentLayout); 0242 0243 // ----- // 0244 0245 m_layout->addStretch(1); 0246 setLayout(m_layout); 0247 0248 // ----- // 0249 0250 // initialization as empty group 0251 0252 reset(); 0253 } 0254 0255 void SearchGroup::read(SearchXmlCachingReader& reader) 0256 { 0257 reset(); 0258 0259 m_label->setGroupOperator(reader.groupOperator()); 0260 m_label->setDefaultFieldOperator(reader.defaultFieldOperator()); 0261 0262 startReadingGroups(reader); 0263 0264 while (!reader.atEnd()) 0265 { 0266 reader.readNext(); 0267 0268 if (reader.isEndElement()) 0269 { 0270 break; 0271 } 0272 0273 // subgroup 0274 0275 if (reader.isGroupElement()) 0276 { 0277 readGroup(reader); 0278 } 0279 0280 if (reader.isFieldElement()) 0281 { 0282 QString name = reader.fieldName(); 0283 0284 SearchField* field = nullptr; 0285 SearchFieldGroup* fieldGroup = nullptr; 0286 0287 Q_FOREACH (fieldGroup, m_fieldGroups) 0288 { 0289 if (fieldGroup) 0290 { 0291 if ((field = fieldGroup->fieldForName(name))) 0292 { 0293 // cppcheck-suppress useStlAlgorithm 0294 break; 0295 } 0296 } 0297 } 0298 0299 if (field) 0300 { 0301 field->read(reader); 0302 fieldGroup->markField(field); 0303 fieldGroup->setFieldsVisible(true); 0304 } 0305 else 0306 { 0307 qCWarning(DIGIKAM_GENERAL_LOG) << "Unhandled search field in XML with field name" << name; 0308 reader.readToEndOfElement(); 0309 } 0310 } 0311 } 0312 0313 finishReadingGroups(); 0314 } 0315 0316 SearchGroup* SearchGroup::createSearchGroup() 0317 { 0318 // create a sub group - view is the same 0319 0320 SearchGroup* const group = new SearchGroup(m_view); 0321 group->setup(SearchGroup::ChainGroup); 0322 0323 return group; 0324 } 0325 0326 void SearchGroup::addGroupToLayout(SearchGroup* group) 0327 { 0328 // insert in front of the stretch 0329 0330 m_subgroupLayout->addWidget(group); 0331 } 0332 0333 void SearchGroup::write(SearchXmlWriter& writer) 0334 { 0335 writer.writeGroup(); 0336 writer.setGroupOperator(m_label->groupOperator()); 0337 writer.setDefaultFieldOperator(m_label->defaultFieldOperator()); 0338 0339 Q_FOREACH (SearchFieldGroup* const fieldGroup, m_fieldGroups) 0340 { 0341 fieldGroup->write(writer); 0342 } 0343 0344 // take care for subgroups 0345 0346 writeGroups(writer); 0347 0348 writer.finishGroup(); 0349 } 0350 0351 void SearchGroup::reset() 0352 { 0353 Q_FOREACH (SearchFieldGroup* const fieldGroup, m_fieldGroups) 0354 { 0355 fieldGroup->reset(); 0356 } 0357 0358 m_label->setGroupOperator(SearchXml::standardGroupOperator()); 0359 m_label->setDefaultFieldOperator(SearchXml::standardFieldOperator()); 0360 } 0361 0362 SearchGroup::Type SearchGroup::groupType() const 0363 { 0364 return m_groupType; 0365 } 0366 0367 QList<QRect> SearchGroup::startupAnimationArea() const 0368 { 0369 QList<QRect> rects; 0370 0371 // from subgroups; 0372 0373 rects += startupAnimationAreaOfGroups(); 0374 0375 // field groups 0376 0377 Q_FOREACH (SearchFieldGroup* fieldGroup, m_fieldGroups) 0378 { 0379 // cppcheck-suppress useStlAlgorithm 0380 rects += fieldGroup->areaOfMarkedFields(); 0381 } 0382 0383 // adjust position relative to parent 0384 0385 for (QList<QRect>::iterator it = rects.begin() ; it != rects.end() ; ++it) 0386 { 0387 (*it).translate(pos()); 0388 } 0389 0390 return rects; 0391 } 0392 0393 } // namespace Digikam 0394 0395 #include "moc_searchgroup.cpp"