File indexing completed on 2025-01-19 03:50:48
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2013-02-25 0007 * Description : Table view column helpers: Item properties 0008 * 0009 * SPDX-FileCopyrightText: 2017-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * SPDX-FileCopyrightText: 2013 by Michael G. Hansen <mike at mghansen dot de> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #include "tableview_column_item.h" 0017 0018 // Qt includes 0019 0020 #include <QLocale> 0021 0022 // KDE includes 0023 0024 #include <klocalizedstring.h> 0025 0026 // Local includes 0027 0028 #include "digikam_debug.h" 0029 #include "iteminfo.h" 0030 #include "coredbinfocontainers.h" 0031 #include "itempropertiestab.h" 0032 0033 namespace Digikam 0034 { 0035 0036 namespace TableViewColumns 0037 { 0038 0039 ColumnItemProperties::ColumnItemProperties(TableViewShared* const tableViewShared, 0040 const TableViewColumnConfiguration& pConfiguration, 0041 const SubColumn pSubColumn, 0042 QObject* const parent) 0043 : TableViewColumn(tableViewShared, pConfiguration, parent), 0044 subColumn (pSubColumn) 0045 { 0046 } 0047 0048 ColumnItemProperties::~ColumnItemProperties() 0049 { 0050 } 0051 0052 QStringList ColumnItemProperties::getSubColumns() 0053 { 0054 QStringList columns; 0055 columns << QLatin1String("width") 0056 << QLatin1String("height") 0057 << QLatin1String("dimensions") 0058 << QLatin1String("pixelcount") 0059 << QLatin1String("bitdepth") 0060 << QLatin1String("colormode") 0061 << QLatin1String("itemtype") 0062 << QLatin1String("itemcreationdatetime") 0063 << QLatin1String("itemdigitizationtime") 0064 << QLatin1String("itemaspectratio") 0065 << QLatin1String("similarity"); 0066 0067 return columns; 0068 } 0069 0070 TableViewColumnDescription ColumnItemProperties::getDescription() 0071 { 0072 TableViewColumnDescription description(QLatin1String("item-properties"), i18n("Item properties")); 0073 description.setIcon(QLatin1String("view-preview")); 0074 0075 description.addSubColumn(TableViewColumnDescription(QLatin1String("width"), i18n("Width"))); 0076 description.addSubColumn(TableViewColumnDescription(QLatin1String("height"), i18n("Height"))); 0077 description.addSubColumn(TableViewColumnDescription(QLatin1String("dimensions"), i18n("Dimensions"))); 0078 description.addSubColumn(TableViewColumnDescription(QLatin1String("pixelcount"), i18n("Pixel count"))); 0079 description.addSubColumn(TableViewColumnDescription(QLatin1String("bitdepth"), i18n("Bit depth"))); 0080 description.addSubColumn(TableViewColumnDescription(QLatin1String("colormode"), i18n("Color mode"))); 0081 description.addSubColumn(TableViewColumnDescription(QLatin1String("itemtype"), i18n("Type"))); 0082 description.addSubColumn(TableViewColumnDescription(QLatin1String("itemcreationdatetime"), i18n("Creation date/time"))); 0083 description.addSubColumn(TableViewColumnDescription(QLatin1String("itemdigitizationtime"), i18n("Digitization date/time"))); 0084 description.addSubColumn(TableViewColumnDescription(QLatin1String("itemaspectratio"), i18n("Aspect ratio"))); 0085 description.addSubColumn(TableViewColumnDescription(QLatin1String("similarity"), i18n("Similarity"))); 0086 0087 return description; 0088 } 0089 0090 QString ColumnItemProperties::getTitle() const 0091 { 0092 switch (subColumn) 0093 { 0094 case SubColumnWidth: 0095 { 0096 return i18n("Width"); 0097 } 0098 0099 case SubColumnHeight: 0100 { 0101 return i18n("Height"); 0102 } 0103 0104 case SubColumnDimensions: 0105 { 0106 return i18n("Dimensions"); 0107 } 0108 0109 case SubColumnPixelCount: 0110 { 0111 return i18n("Pixel count"); 0112 } 0113 0114 case SubColumnBitDepth: 0115 { 0116 return i18n("Bit depth"); 0117 } 0118 0119 case SubColumnColorMode: 0120 { 0121 return i18n("Color mode"); 0122 } 0123 0124 case SubColumnType: 0125 { 0126 return i18n("Type"); 0127 } 0128 0129 case SubColumnCreationDateTime: 0130 { 0131 return i18n("Creation date/time"); 0132 } 0133 0134 case SubColumnDigitizationDateTime: 0135 { 0136 return i18n("Digitization date/time"); 0137 } 0138 0139 case SubColumnAspectRatio: 0140 { 0141 return i18n("Aspect ratio"); 0142 } 0143 0144 case SubColumnSimilarity: 0145 { 0146 return i18n("Similarity"); 0147 } 0148 } 0149 0150 return QString(); 0151 } 0152 0153 TableViewColumn::ColumnFlags ColumnItemProperties::getColumnFlags() const 0154 { 0155 ColumnFlags flags(ColumnNoFlags); 0156 0157 if ( 0158 (subColumn == SubColumnHeight) || 0159 (subColumn == SubColumnWidth) || 0160 (subColumn == SubColumnDimensions) || 0161 (subColumn == SubColumnBitDepth) || 0162 (subColumn == SubColumnPixelCount) || 0163 (subColumn == SubColumnCreationDateTime) || 0164 (subColumn == SubColumnDigitizationDateTime) || 0165 (subColumn == SubColumnAspectRatio) || 0166 (subColumn == SubColumnSimilarity) 0167 ) 0168 { 0169 flags |= ColumnCustomSorting; 0170 } 0171 0172 return flags; 0173 } 0174 0175 QVariant ColumnItemProperties::data(TableViewModel::Item* const item, const int role) const 0176 { 0177 if ( 0178 (role != Qt::DisplayRole) && 0179 (role != Qt::TextAlignmentRole) 0180 ) 0181 { 0182 return QVariant(); 0183 } 0184 0185 if (role == Qt::TextAlignmentRole) 0186 { 0187 switch (subColumn) 0188 { 0189 case SubColumnHeight: 0190 case SubColumnWidth: 0191 case SubColumnPixelCount: 0192 { 0193 return QVariant(Qt::Alignment(Qt::AlignRight | Qt::AlignVCenter)); 0194 } 0195 0196 default: 0197 { 0198 return QVariant(); 0199 } 0200 } 0201 } 0202 0203 const ItemInfo info = s->tableViewModel->infoFromItem(item); 0204 0205 switch (subColumn) 0206 { 0207 case SubColumnWidth: 0208 { 0209 return QLocale().toString(info.dimensions().width()); 0210 } 0211 0212 case SubColumnHeight: 0213 { 0214 return QLocale().toString(info.dimensions().height()); 0215 } 0216 0217 case SubColumnDimensions: 0218 { 0219 const QSize imgSize = info.dimensions(); 0220 0221 if (imgSize.isNull()) 0222 { 0223 return QString(); 0224 } 0225 0226 const QString widthString = QLocale().toString(imgSize.width()); 0227 const QString heightString = QLocale().toString(imgSize.height()); 0228 0229 return QString::fromUtf8("%1x%2").arg(widthString).arg(heightString); 0230 } 0231 0232 case SubColumnPixelCount: 0233 { 0234 const QSize imgSize = info.dimensions(); 0235 const int pixelCount = imgSize.height() * imgSize.width(); 0236 0237 if (pixelCount == 0) 0238 { 0239 return QString(); 0240 } 0241 0242 /// @todo make this configurable with si-prefixes 0243 0244 return QLocale().toString(pixelCount); 0245 } 0246 0247 case SubColumnAspectRatio: 0248 { 0249 const QSize imgSize = info.dimensions(); 0250 QString aspectRatioString; 0251 0252 if (!ItemPropertiesTab::aspectRatioToString(imgSize.width(), imgSize.height(), aspectRatioString)) 0253 { 0254 return QString(); 0255 } 0256 0257 return aspectRatioString; 0258 } 0259 0260 case SubColumnBitDepth: 0261 { 0262 const ImageCommonContainer commonInfo = info.imageCommonContainer(); 0263 const int bitDepth = commonInfo.colorDepth; 0264 0265 return QString::fromUtf8("%1 bpp").arg(bitDepth); 0266 } 0267 0268 case SubColumnColorMode: 0269 { 0270 const ImageCommonContainer commonInfo = info.imageCommonContainer(); 0271 0272 return commonInfo.colorModel; 0273 } 0274 0275 case SubColumnType: 0276 { 0277 const ImageCommonContainer commonInfo = info.imageCommonContainer(); 0278 0279 return commonInfo.format; 0280 } 0281 0282 case SubColumnCreationDateTime: 0283 { 0284 const QDateTime creationDateTime = info.dateTime(); 0285 0286 return QLocale().toString(creationDateTime, QLocale::ShortFormat); 0287 } 0288 0289 case SubColumnDigitizationDateTime: 0290 { 0291 const ImageCommonContainer commonInfo = info.imageCommonContainer(); 0292 const QDateTime digitizationDateTime = commonInfo.digitizationDate; 0293 0294 return QLocale().toString(digitizationDateTime, QLocale::ShortFormat); 0295 } 0296 case SubColumnSimilarity: 0297 { 0298 qlonglong referenceImageId = info.currentReferenceImage(); 0299 double similarity = info.currentSimilarity() * 100; 0300 0301 if (referenceImageId == info.id()) 0302 { 0303 similarity = 100.00; 0304 } 0305 0306 return QLocale().toString(similarity,'f',2); 0307 } 0308 } 0309 0310 return QVariant(); 0311 } 0312 0313 TableViewColumn::ColumnCompareResult ColumnItemProperties::compare(TableViewModel::Item* const itemA, 0314 TableViewModel::Item* const itemB) const 0315 { 0316 const ItemInfo infoA = s->tableViewModel->infoFromItem(itemA); 0317 const ItemInfo infoB = s->tableViewModel->infoFromItem(itemB); 0318 0319 switch (subColumn) 0320 { 0321 case SubColumnHeight: 0322 { 0323 const int heightA = infoA.dimensions().height(); 0324 const int heightB = infoB.dimensions().height(); 0325 0326 return compareHelper<int>(heightA, heightB); 0327 } 0328 0329 case SubColumnWidth: 0330 { 0331 const int widthA = infoA.dimensions().width(); 0332 const int widthB = infoB.dimensions().width(); 0333 0334 return compareHelper<int>(widthA, widthB); 0335 } 0336 0337 case SubColumnDimensions: 0338 { 0339 const int widthA = infoA.dimensions().width(); 0340 const int widthB = infoB.dimensions().width(); 0341 const ColumnCompareResult widthResult = compareHelper<int>(widthA, widthB); 0342 0343 if (widthResult != CmpEqual) 0344 { 0345 return widthResult; 0346 } 0347 0348 const int heightA = infoA.dimensions().height(); 0349 const int heightB = infoB.dimensions().height(); 0350 0351 return compareHelper<int>(heightA, heightB); 0352 } 0353 0354 case SubColumnPixelCount: 0355 { 0356 const int widthA = infoA.dimensions().width(); 0357 const int widthB = infoB.dimensions().width(); 0358 const int heightA = infoA.dimensions().height(); 0359 const int heightB = infoB.dimensions().height(); 0360 const int pixelCountA = widthA*heightA; 0361 const int pixelCountB = widthB*heightB; 0362 0363 return compareHelper<int>(pixelCountA, pixelCountB); 0364 } 0365 0366 case SubColumnAspectRatio: 0367 { 0368 const int widthA = infoA.dimensions().width(); 0369 const int widthB = infoB.dimensions().width(); 0370 const int heightA = infoA.dimensions().height(); 0371 const int heightB = infoB.dimensions().height(); 0372 0373 if ((heightA == 0) || (heightB == 0)) 0374 { 0375 // at least one of the two does not have valid data, 0376 // sort based on which one has data at all 0377 0378 return compareHelper<int>(heightA, heightB); 0379 } 0380 0381 const qreal aspectRatioA = qreal(widthA) / qreal(heightA); 0382 const qreal aspectRatioB = qreal(widthB) / qreal(heightB); 0383 0384 /// @todo use fuzzy compare? 0385 0386 return compareHelper<qreal>(aspectRatioA, aspectRatioB); 0387 } 0388 0389 case SubColumnBitDepth: 0390 { 0391 const ImageCommonContainer commonInfoA = infoA.imageCommonContainer(); 0392 const int bitDepthA = commonInfoA.colorDepth; 0393 const ImageCommonContainer commonInfoB = infoB.imageCommonContainer(); 0394 const int bitDepthB = commonInfoB.colorDepth; 0395 0396 return compareHelper<int>(bitDepthA, bitDepthB); 0397 } 0398 0399 case SubColumnCreationDateTime: 0400 { 0401 const QDateTime dtA = infoA.dateTime(); 0402 const QDateTime dtB = infoB.dateTime(); 0403 0404 return compareHelper<QDateTime>(dtA, dtB); 0405 } 0406 0407 case SubColumnDigitizationDateTime: 0408 { 0409 const ImageCommonContainer commonInfoA = infoA.imageCommonContainer(); 0410 const ImageCommonContainer commonInfoB = infoB.imageCommonContainer(); 0411 const QDateTime dtA = commonInfoA.digitizationDate; 0412 const QDateTime dtB = commonInfoB.digitizationDate; 0413 0414 return compareHelper<QDateTime>(dtA, dtB); 0415 } 0416 case SubColumnSimilarity: 0417 { 0418 qlonglong referenceImageIdA = infoA.currentReferenceImage(); 0419 qlonglong referenceImageIdB = infoB.currentReferenceImage(); 0420 0421 if (referenceImageIdA == referenceImageIdB) 0422 { 0423 // make sure that the original image has always the highest similarity. 0424 0425 double infoASimilarity = infoA.id() == referenceImageIdA ? 1.0 : infoA.currentSimilarity(); 0426 double infoBSimilarity = infoB.id() == referenceImageIdB ? 1.0 : infoB.currentSimilarity(); 0427 0428 return compareHelper<double>(infoASimilarity, infoBSimilarity); 0429 } 0430 else 0431 { 0432 qCWarning(DIGIKAM_GENERAL_LOG) << "item: items have different fuzzy search reference images. Sorting is not possible."; 0433 0434 return CmpEqual; 0435 } 0436 } 0437 0438 default: 0439 { 0440 qCWarning(DIGIKAM_GENERAL_LOG) << "item: unimplemented comparison, subColumn=" << subColumn; 0441 0442 return CmpEqual; 0443 } 0444 } 0445 } 0446 0447 } // namespace TableViewColumns 0448 0449 } // namespace Digikam 0450 0451 #include "moc_tableview_column_item.cpp"