diff --git a/core/app/views/tableview/tableview_column_audiovideo.cpp b/core/app/views/tableview/tableview_column_audiovideo.cpp index d7735df8a8..80645bb5b9 100644 --- a/core/app/views/tableview/tableview_column_audiovideo.cpp +++ b/core/app/views/tableview/tableview_column_audiovideo.cpp @@ -1,304 +1,318 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2013-05-13 * Description : Table view column helpers: Audio/video properties * * Copyright (C) 2017-2020 by Gilles Caulier * Copyright (C) 2013 by Michael G. Hansen * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "tableview_column_audiovideo.h" // Qt includes #include // KDE includes #include // Local includes #include "digikam_debug.h" #include "coredbinfocontainers.h" #include "dmetadata.h" #include "iteminfo.h" namespace Digikam { namespace TableViewColumns { ColumnAudioVideoProperties::ColumnAudioVideoProperties(TableViewShared* const tableViewShared, const TableViewColumnConfiguration& pConfiguration, const SubColumn pSubColumn, QObject* const parent) : TableViewColumn(tableViewShared, pConfiguration, parent), subColumn(pSubColumn) { } ColumnAudioVideoProperties::~ColumnAudioVideoProperties() { } QStringList ColumnAudioVideoProperties::getSubColumns() { QStringList columns; columns << QLatin1String("audiobitrate") << QLatin1String("audiochanneltype") << QLatin1String("audioCodec") << QLatin1String("duration") << QLatin1String("framerate") << QLatin1String("videocodec"); return columns; } TableViewColumnDescription ColumnAudioVideoProperties::getDescription() { TableViewColumnDescription description(QLatin1String("audiovideo-properties"), i18n("Audio/video properties")); description.setIcon(QLatin1String("video-x-generic")); description.addSubColumn(TableViewColumnDescription(QLatin1String("audiobitrate"), i18n("Audio bitrate"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("audiochanneltype"), i18n("Audio channel type"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("audioCodec"), i18n("Audio Codec"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("duration"), i18n("Duration"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("framerate"), i18n("Frame rate"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("videocodec"), i18n("Video codec"))); return description; } QString ColumnAudioVideoProperties::getTitle() const { switch (subColumn) { case SubColumnAudioBitRate: + { return i18n("Audio bitrate"); + } case SubColumnAudioChannelType: + { return i18n("Audio channel type"); + } case SubColumnAudioCodec: + { return i18n("Audio Codec"); + } case SubColumnDuration: + { return i18n("Duration"); + } case SubColumnFrameRate: + { return i18n("Frame rate"); + } case SubColumnVideoCodec: + { return i18n("Video codec"); + } } return QString(); } TableViewColumn::ColumnFlags ColumnAudioVideoProperties::getColumnFlags() const { ColumnFlags flags(ColumnNoFlags); /// @todo AudioChannelType contains "Mono" or "2", have to check for custom sorting + if ( (subColumn == SubColumnAudioBitRate) || (subColumn == SubColumnDuration) || (subColumn == SubColumnFrameRate) ) { flags |= ColumnCustomSorting; } return flags; } QVariant ColumnAudioVideoProperties::data(TableViewModel::Item* const item, const int role) const { if (role != Qt::DisplayRole) { return QVariant(); } switch (subColumn) { case SubColumnAudioBitRate: { bool ok; const int audioBitRate = s->tableViewModel->itemDatabaseFieldRaw(item, DatabaseFields::Set(DatabaseFields::AudioBitRate)).toInt(&ok); if (!ok) { return QString(); } const QString audioBitRateString = QLocale().toString(audioBitRate); return audioBitRateString; } case SubColumnAudioChannelType: { const QString audioChannelType = s->tableViewModel->itemDatabaseFieldRaw(item, DatabaseFields::Set(DatabaseFields::AudioChannelType)).toString(); return audioChannelType; } case SubColumnAudioCodec: { const QString audioCodec = s->tableViewModel->itemDatabaseFieldRaw(item, DatabaseFields::Set(DatabaseFields::AudioCodec)).toString(); return audioCodec; } case SubColumnDuration: { bool ok; // duration is in milliseconds const double duration = s->tableViewModel->itemDatabaseFieldRaw(item, DatabaseFields::Set(DatabaseFields::Duration)).toDouble(&ok); if (!ok) { return QString(); } const QTime durationTime = QTime().addMSecs(duration); const QString durationString = QLocale().toString(durationTime); return durationString; } case SubColumnFrameRate: { bool ok; const double frameRate = s->tableViewModel->itemDatabaseFieldRaw(item, DatabaseFields::Set(DatabaseFields::FrameRate)).toDouble(&ok); if (!ok) { return QString(); } const QString frameRateString = QLocale().toString(frameRate); return frameRateString; } case SubColumnVideoCodec: { const QString videoCodec = s->tableViewModel->itemDatabaseFieldRaw(item, DatabaseFields::Set(DatabaseFields::VideoCodec)).toString(); return videoCodec; } } return QVariant(); } TableViewColumn::ColumnCompareResult ColumnAudioVideoProperties::compare(TableViewModel::Item* const itemA, TableViewModel::Item* const itemB) const { /// @todo All the values used here are actually returned as strings in the QVariants, but should be stored as int/double switch (subColumn) { case SubColumnAudioBitRate: { const QVariant variantA = s->tableViewModel->itemDatabaseFieldRaw(itemA, DatabaseFields::Set(DatabaseFields::AudioBitRate)); const QVariant variantB = s->tableViewModel->itemDatabaseFieldRaw(itemB, DatabaseFields::Set(DatabaseFields::AudioBitRate)); bool okA; const int audioBitRateA = variantA.toInt(&okA); bool okB; const int audioBitRateB = variantB.toDouble(&okB); ColumnCompareResult result; if (!compareHelperBoolFailCheck(okA, okB, &result)) { return result; } return compareHelper(audioBitRateA, audioBitRateB); } case SubColumnDuration: { const QVariant variantA = s->tableViewModel->itemDatabaseFieldRaw(itemA, DatabaseFields::Set(DatabaseFields::Duration)); const QVariant variantB = s->tableViewModel->itemDatabaseFieldRaw(itemB, DatabaseFields::Set(DatabaseFields::Duration)); bool okA; const double durationA = variantA.toDouble(&okA); bool okB; const double durationB = variantB.toDouble(&okB); ColumnCompareResult result; if (!compareHelperBoolFailCheck(okA, okB, &result)) { return result; } return compareHelper(durationA, durationB); } case SubColumnFrameRate: { const QVariant variantA = s->tableViewModel->itemDatabaseFieldRaw(itemA, DatabaseFields::Set(DatabaseFields::FrameRate)); const QVariant variantB = s->tableViewModel->itemDatabaseFieldRaw(itemB, DatabaseFields::Set(DatabaseFields::FrameRate)); bool okA; const double frameRateA = variantA.toDouble(&okA); bool okB; const double frameRateB = variantB.toDouble(&okB); ColumnCompareResult result; if (!compareHelperBoolFailCheck(okA, okB, &result)) { return result; } return compareHelper(frameRateA, frameRateB); } default: { qCWarning(DIGIKAM_GENERAL_LOG) << "item: unimplemented comparison, subColumn=" << subColumn; + return CmpEqual; } } } void ColumnAudioVideoProperties::setConfiguration(const TableViewColumnConfiguration& newConfiguration) { configuration = newConfiguration; emit signalAllDataChanged(); } } // namespace TableViewColumns } // namespace Digikam diff --git a/core/app/views/tableview/tableview_column_file.cpp b/core/app/views/tableview/tableview_column_file.cpp index c406790e18..bb28065319 100644 --- a/core/app/views/tableview/tableview_column_file.cpp +++ b/core/app/views/tableview/tableview_column_file.cpp @@ -1,275 +1,289 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2013-02-25 * Description : Table view column helpers: File properties * * Copyright (C) 2017-2020 by Gilles Caulier * Copyright (C) 2013 by Michael G. Hansen * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "tableview_column_file.h" // Qt includes #include #include #include #include // KDE includes #include // Local includes #include "digikam_debug.h" #include "itempropertiestab.h" #include "iteminfo.h" namespace Digikam { namespace TableViewColumns { ColumnFileProperties::ColumnFileProperties(TableViewShared* const tableViewShared, const TableViewColumnConfiguration& pConfiguration, const SubColumn pSubColumn, QObject* const parent) : TableViewColumn(tableViewShared, pConfiguration, parent), subColumn(pSubColumn) { } TableViewColumnDescription ColumnFileProperties::getDescription() { TableViewColumnDescription description(QLatin1String("file-properties"), i18n("File properties")); description.setIcon(QLatin1String("dialog-information")); description.addSubColumn(TableViewColumnDescription(QLatin1String("filename"), i18n("Filename"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("filepath"), i18n("Path"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("filesize"), i18n("Size"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("filelastmodified"), i18n("Last modified"))); return description; } QStringList ColumnFileProperties::getSubColumns() { QStringList columns; columns << QLatin1String("filename") << QLatin1String("filepath") << QLatin1String("filesize") << QLatin1String("filelastmodified"); return columns; } QString ColumnFileProperties::getTitle() const { switch (subColumn) { case SubColumnName: + { return i18n("Filename"); + } case SubColumnFilePath: + { return i18n("Path"); + } case SubColumnSize: + { return i18n("Size"); + } case SubColumnLastModified: + { return i18n("Last modified"); + } } return QString(); } TableViewColumn::ColumnFlags ColumnFileProperties::getColumnFlags() const { if ( (subColumn == SubColumnSize) || (subColumn == SubColumnLastModified) ) { return (ColumnCustomSorting | ColumnHasConfigurationWidget); } return ColumnNoFlags; } QVariant ColumnFileProperties::data(TableViewModel::Item* const item, const int role) const { if ( (role != Qt::DisplayRole) && (role != Qt::TextAlignmentRole) ) { return QVariant(); } if (role == Qt::TextAlignmentRole) { switch (subColumn) { case SubColumnSize: + { return QVariant(Qt::Alignment(Qt::AlignRight | Qt::AlignVCenter)); + } default: + { return QVariant(); + } } } const ItemInfo info = s->tableViewModel->infoFromItem(item); switch (subColumn) { case SubColumnName: + { return info.fileUrl().fileName(); - break; + } case SubColumnFilePath: + { return QDir::toNativeSeparators(info.fileUrl().toLocalFile()); - break; + } case SubColumnSize: { /// @todo Add configuration options for SI-prefixes /// @todo Use an enum instead to avoid lots of string comparisons const QString formatKey = configuration.getSetting(QLatin1String("format"), QLatin1String("human")); if (formatKey == QLatin1String("human")) { return ItemPropertiesTab::humanReadableBytesCount(info.fileSize()); } else { // formatKey == "plain" return QLocale().toString(info.fileSize()); } break; } case SubColumnLastModified: { const QDateTime lastModifiedTime = info.modDateTime(); return QLocale().toString(lastModifiedTime, QLocale::ShortFormat); } } return QVariant(); } TableViewColumn::ColumnCompareResult ColumnFileProperties::compare(TableViewModel::Item* const itemA, TableViewModel::Item* const itemB) const { const ItemInfo infoA = s->tableViewModel->infoFromItem(itemA); const ItemInfo infoB = s->tableViewModel->infoFromItem(itemB); switch (subColumn) { case SubColumnSize: { const int sizeA = infoA.fileSize(); const int sizeB = infoB.fileSize(); return compareHelper(sizeA, sizeB); } case SubColumnLastModified: { const QDateTime dtA = infoA.modDateTime(); const QDateTime dtB = infoB.modDateTime(); return compareHelper(dtA, dtB); } default: { qCWarning(DIGIKAM_GENERAL_LOG) << "file: unimplemented comparison, subColumn=" << subColumn; return CmpEqual; } } } // --------------------------------------------------------------------------------------- ColumnFileConfigurationWidget::ColumnFileConfigurationWidget(TableViewShared* const sharedObject, const TableViewColumnConfiguration& columnConfiguration, QWidget* const parentWidget) : TableViewColumnConfigurationWidget(sharedObject, columnConfiguration, parentWidget), subColumn(ColumnFileProperties::SubColumnName), selectorSizeType(nullptr) { ColumnFileProperties::getSubColumnIndex(configuration.columnId, &subColumn); switch (subColumn) { case ColumnFileProperties::SubColumnSize: { QFormLayout* const box1 = new QFormLayout(); selectorSizeType = new QComboBox(this); selectorSizeType->addItem(i18n("Human readable"), QLatin1String("human")); selectorSizeType->addItem(i18n("Plain"), QLatin1String("plain")); box1->addRow(i18n("Display format"), selectorSizeType); setLayout(box1); const int index = selectorSizeType->findData(configuration.getSetting(QLatin1String("format"), QLatin1String("human"))); selectorSizeType->setCurrentIndex((index >= 0) ? index : 0); break; } default: { break; } } } ColumnFileConfigurationWidget::~ColumnFileConfigurationWidget() { } TableViewColumnConfiguration ColumnFileConfigurationWidget::getNewConfiguration() { const QString formatKey = selectorSizeType->itemData(selectorSizeType->currentIndex()).toString(); configuration.columnSettings.insert(QLatin1String("format"), formatKey); return configuration; } void ColumnFileProperties::setConfiguration(const TableViewColumnConfiguration& newConfiguration) { configuration = newConfiguration; emit signalAllDataChanged(); } TableViewColumnConfigurationWidget* ColumnFileProperties::getConfigurationWidget(QWidget* const parentWidget) const { return new ColumnFileConfigurationWidget(s, configuration, parentWidget); } } // namespace TableViewColumns } // namespace Digikam diff --git a/core/app/views/tableview/tableview_column_geo.cpp b/core/app/views/tableview/tableview_column_geo.cpp index 234e7c30f6..ea935aa55d 100644 --- a/core/app/views/tableview/tableview_column_geo.cpp +++ b/core/app/views/tableview/tableview_column_geo.cpp @@ -1,295 +1,306 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2013-02-25 * Description : Table view column helpers: Geographic columns * * Copyright (C) 2017-2020 by Gilles Caulier * Copyright (C) 2013 by Michael G. Hansen * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "tableview_column_geo.h" // Qt includes #include #include #include // KDE includes #include // Local includes #include "digikam_debug.h" #include "iteminfo.h" namespace { QString FormatAltitude(const qreal altitudeInMeters, const QLocale::MeasurementSystem& measureSystem) { if (measureSystem == QLocale::MetricSystem) { const QString altitudeInMetersString = QLocale().toString(altitudeInMeters); return QString::fromUtf8("%1 m").arg(altitudeInMetersString); } else { const qreal altitudeInFeet = altitudeInMeters /* m */ / ( 0.3048 /* m/foot */ ); const QString altitudeInFeetString = QLocale().toString(altitudeInFeet, 'g', 2); return QString::fromUtf8("%1 ft").arg(altitudeInFeetString); } } } // namespace namespace Digikam { namespace TableViewColumns { ColumnGeoProperties::ColumnGeoProperties(TableViewShared* const tableViewShared, const TableViewColumnConfiguration& pConfiguration, const SubColumn pSubColumn, QObject* const parent) : TableViewColumn(tableViewShared, pConfiguration, parent), subColumn(pSubColumn) { } ColumnGeoProperties::~ColumnGeoProperties() { } QStringList ColumnGeoProperties::getSubColumns() { QStringList columns; columns << QLatin1String("geohascoordinates") << QLatin1String("geocoordinates") << QLatin1String("geoaltitude"); return columns; } TableViewColumnDescription ColumnGeoProperties::getDescription() { TableViewColumnDescription description(QLatin1String("geo-properties"), i18n("Geo properties")); description.setIcon(QLatin1String("globe")); description.addSubColumn(TableViewColumnDescription(QLatin1String("geohascoordinates"), i18n("Geotagged"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("geocoordinates"), i18n("Coordinates"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("geoaltitude"), i18n("Altitude"))); return description; } QString ColumnGeoProperties::getTitle() const { switch (subColumn) { case SubColumnHasCoordinates: + { return i18n("Geotagged"); + } case SubColumnCoordinates: + { return i18n("Coordinates"); + } case SubColumnAltitude: + { return i18n("Altitude"); + } } return QString(); } TableViewColumn::ColumnFlags ColumnGeoProperties::getColumnFlags() const { ColumnFlags flags(ColumnNoFlags); if (subColumn == SubColumnAltitude) { flags |= (ColumnCustomSorting | ColumnHasConfigurationWidget); } return flags; } + QVariant ColumnGeoProperties::data(TableViewModel::Item* const item, const int role) const { if ( (role != Qt::DisplayRole) && (role != Qt::TextAlignmentRole) ) { return QVariant(); } if (role == Qt::TextAlignmentRole) { switch (subColumn) { case SubColumnAltitude: + { return QVariant(Qt::Alignment(Qt::AlignRight | Qt::AlignVCenter)); + } default: + { return QVariant(); + } } } const ItemInfo info = s->tableViewModel->infoFromItem(item); switch (subColumn) { case SubColumnHasCoordinates: { return info.hasCoordinates() ? i18n("Yes") : i18n("No"); } case SubColumnCoordinates: { if (!info.hasCoordinates()) { return QString(); } return QString::fromUtf8("%1,%2").arg(QLocale().toString(info.latitudeNumber(), 'g', 7)) .arg(QLocale().toString(info.longitudeNumber(), 'g', 7)); } case SubColumnAltitude: { /// @todo Needs custom sorting if ((!info.hasCoordinates()) || (!info.hasAltitude())) { return QString(); } /// @todo Use an enum instead to avoid lots of string comparisons const QString formatKey = configuration.getSetting(QLatin1String("format"), QLatin1String("metric")); QLocale::MeasurementSystem measureSystem = QLocale().measurementSystem(); if (formatKey == QLatin1String("metric")) { measureSystem = QLocale::MetricSystem; } else if (formatKey == QLatin1String("imperial")) { measureSystem = QLocale::ImperialSystem; } const QString formattedAltitude = FormatAltitude(info.altitudeNumber(), measureSystem); return formattedAltitude; } } return QVariant(); } TableViewColumn::ColumnCompareResult ColumnGeoProperties::compare(TableViewModel::Item* const itemA, TableViewModel::Item* const itemB) const { const ItemInfo infoA = s->tableViewModel->infoFromItem(itemA); const ItemInfo infoB = s->tableViewModel->infoFromItem(itemB); if (subColumn == SubColumnAltitude) { const bool hasAltitudeA = infoA.hasAltitude(); const bool hasAltitudeB = infoB.hasAltitude(); if (hasAltitudeA && hasAltitudeB) { const double altitudeA = infoA.altitudeNumber(); const double altitudeB = infoB.altitudeNumber(); return (compareHelper(altitudeA, altitudeB)); } return (compareHelper(int(hasAltitudeA), int(hasAltitudeB))); } qCWarning(DIGIKAM_GENERAL_LOG) << "geo: unimplemented comparison, subColumn=" << subColumn; return CmpEqual; } TableViewColumnConfigurationWidget* ColumnGeoProperties::getConfigurationWidget(QWidget* const parentWidget) const { TableViewColumnConfiguration myConfiguration = getConfiguration(); return (new ColumnGeoConfigurationWidget(s, myConfiguration, parentWidget)); } // ---------------------------------------------------------------------------------------------------------------- ColumnGeoConfigurationWidget::ColumnGeoConfigurationWidget(TableViewShared* const sharedObject, const TableViewColumnConfiguration& columnConfiguration, QWidget* const parentWidget) : TableViewColumnConfigurationWidget(sharedObject, columnConfiguration, parentWidget), subColumn(ColumnGeoProperties::SubColumnHasCoordinates), selectorAltitudeUnit(nullptr) { ColumnGeoProperties::getSubColumnIndex(configuration.columnId, &subColumn); switch (subColumn) { case ColumnGeoProperties::SubColumnAltitude: { QFormLayout* const box1 = new QFormLayout(); selectorAltitudeUnit = new QComboBox(this); selectorAltitudeUnit->addItem(i18n("Metric units"), QLatin1String("metric")); selectorAltitudeUnit->addItem(i18n("Imperial units"), QLatin1String("imperial")); box1->addRow(i18n("Display format"), selectorAltitudeUnit); setLayout(box1); const int index = selectorAltitudeUnit->findData(configuration.getSetting(QLatin1String("format"), QLatin1String("metric"))); selectorAltitudeUnit->setCurrentIndex((index >= 0) ? index : 0); break; } default: { break; } } } ColumnGeoConfigurationWidget::~ColumnGeoConfigurationWidget() { } TableViewColumnConfiguration ColumnGeoConfigurationWidget::getNewConfiguration() { const QString formatKey = selectorAltitudeUnit->itemData(selectorAltitudeUnit->currentIndex()).toString(); configuration.columnSettings.insert(QLatin1String("format"), formatKey); return configuration; } void ColumnGeoProperties::setConfiguration(const TableViewColumnConfiguration& newConfiguration) { configuration = newConfiguration; emit signalAllDataChanged(); } } // namespace TableViewColumns } // namespace Digikam diff --git a/core/app/views/tableview/tableview_column_item.cpp b/core/app/views/tableview/tableview_column_item.cpp index 76d95c12b6..cc9b80b8b9 100644 --- a/core/app/views/tableview/tableview_column_item.cpp +++ b/core/app/views/tableview/tableview_column_item.cpp @@ -1,430 +1,457 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2013-02-25 * Description : Table view column helpers: Item properties * * Copyright (C) 2017-2020 by Gilles Caulier * Copyright (C) 2013 by Michael G. Hansen * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "tableview_column_item.h" // Qt includes #include // KDE includes #include // Local includes #include "digikam_debug.h" #include "iteminfo.h" #include "coredbinfocontainers.h" #include "itempropertiestab.h" namespace Digikam { namespace TableViewColumns { ColumnItemProperties::ColumnItemProperties(TableViewShared* const tableViewShared, const TableViewColumnConfiguration& pConfiguration, const SubColumn pSubColumn, QObject* const parent) : TableViewColumn(tableViewShared, pConfiguration, parent), subColumn(pSubColumn) { } ColumnItemProperties::~ColumnItemProperties() { } QStringList ColumnItemProperties::getSubColumns() { QStringList columns; columns << QLatin1String("width") << QLatin1String("height") << QLatin1String("dimensions") << QLatin1String("pixelcount") << QLatin1String("bitdepth") << QLatin1String("colormode") << QLatin1String("itemtype") << QLatin1String("itemcreationdatetime") << QLatin1String("itemdigitizationtime") << QLatin1String("itemaspectratio") << QLatin1String("similarity"); return columns; } TableViewColumnDescription ColumnItemProperties::getDescription() { TableViewColumnDescription description(QLatin1String("item-properties"), i18n("Item properties")); description.setIcon(QLatin1String("view-preview")); description.addSubColumn(TableViewColumnDescription(QLatin1String("width"), i18n("Width"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("height"), i18n("Height"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("dimensions"), i18n("Dimensions"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("pixelcount"), i18n("Pixel count"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("bitdepth"), i18n("Bit depth"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("colormode"), i18n("Color mode"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("itemtype"), i18n("Type"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("itemcreationdatetime"), i18n("Creation date/time"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("itemdigitizationtime"), i18n("Digitization date/time"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("itemaspectratio"), i18n("Aspect ratio"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("similarity"), i18n("Similarity"))); return description; } QString ColumnItemProperties::getTitle() const { switch (subColumn) { case SubColumnWidth: + { return i18n("Width"); + } case SubColumnHeight: + { return i18n("Height"); + } case SubColumnDimensions: + { return i18n("Dimensions"); + } case SubColumnPixelCount: + { return i18n("Pixel count"); + } case SubColumnBitDepth: + { return i18n("Bit depth"); + } case SubColumnColorMode: + { return i18n("Color mode"); + } case SubColumnType: + { return i18n("Type"); + } case SubColumnCreationDateTime: + { return i18n("Creation date/time"); + } case SubColumnDigitizationDateTime: + { return i18n("Digitization date/time"); + } case SubColumnAspectRatio: + { return i18n("Aspect ratio"); + } case SubColumnSimilarity: + { return i18n("Similarity"); + } } return QString(); } TableViewColumn::ColumnFlags ColumnItemProperties::getColumnFlags() const { ColumnFlags flags(ColumnNoFlags); if ( (subColumn == SubColumnHeight) || (subColumn == SubColumnWidth) || (subColumn == SubColumnDimensions) || (subColumn == SubColumnBitDepth) || (subColumn == SubColumnPixelCount) || (subColumn == SubColumnCreationDateTime) || (subColumn == SubColumnDigitizationDateTime) || (subColumn == SubColumnAspectRatio) || (subColumn == SubColumnSimilarity) ) { flags |= ColumnCustomSorting; } return flags; } QVariant ColumnItemProperties::data(TableViewModel::Item* const item, const int role) const { if ( (role != Qt::DisplayRole) && (role != Qt::TextAlignmentRole) ) { return QVariant(); } if (role == Qt::TextAlignmentRole) { switch (subColumn) { case SubColumnHeight: case SubColumnWidth: case SubColumnPixelCount: + { return QVariant(Qt::Alignment(Qt::AlignRight | Qt::AlignVCenter)); + } default: + { return QVariant(); + } } } const ItemInfo info = s->tableViewModel->infoFromItem(item); switch (subColumn) { case SubColumnWidth: { return QLocale().toString(info.dimensions().width()); } case SubColumnHeight: { return QLocale().toString(info.dimensions().height()); } case SubColumnDimensions: { const QSize imgSize = info.dimensions(); if (imgSize.isNull()) { return QString(); } const QString widthString = QLocale().toString(imgSize.width()); const QString heightString = QLocale().toString(imgSize.height()); return QString::fromUtf8("%1x%2").arg(widthString).arg(heightString); } case SubColumnPixelCount: { const QSize imgSize = info.dimensions(); const int pixelCount = imgSize.height() * imgSize.width(); if (pixelCount == 0) { return QString(); } /// @todo make this configurable with si-prefixes return QLocale().toString(pixelCount); } case SubColumnAspectRatio: { const QSize imgSize = info.dimensions(); QString aspectRatioString; if (!ItemPropertiesTab::aspectRatioToString(imgSize.width(), imgSize.height(), aspectRatioString)) { return QString(); } return aspectRatioString; } case SubColumnBitDepth: { const ImageCommonContainer commonInfo = info.imageCommonContainer(); const int bitDepth = commonInfo.colorDepth; return QString::fromUtf8("%1 bpp").arg(bitDepth); } case SubColumnColorMode: { const ImageCommonContainer commonInfo = info.imageCommonContainer(); return commonInfo.colorModel; } case SubColumnType: { const ImageCommonContainer commonInfo = info.imageCommonContainer(); return commonInfo.format; } case SubColumnCreationDateTime: { const QDateTime creationDateTime = info.dateTime(); return QLocale().toString(creationDateTime, QLocale::ShortFormat); } case SubColumnDigitizationDateTime: { const ImageCommonContainer commonInfo = info.imageCommonContainer(); const QDateTime digitizationDateTime = commonInfo.digitizationDate; return QLocale().toString(digitizationDateTime, QLocale::ShortFormat); } case SubColumnSimilarity: { qlonglong referenceImageId = info.currentReferenceImage(); double similarity = info.currentSimilarity() * 100; if (referenceImageId == info.id()) { similarity = 100.00; } return QLocale().toString(similarity,'f',2); } } return QVariant(); } TableViewColumn::ColumnCompareResult ColumnItemProperties::compare(TableViewModel::Item* const itemA, TableViewModel::Item* const itemB) const { const ItemInfo infoA = s->tableViewModel->infoFromItem(itemA); const ItemInfo infoB = s->tableViewModel->infoFromItem(itemB); switch (subColumn) { case SubColumnHeight: { const int heightA = infoA.dimensions().height(); const int heightB = infoB.dimensions().height(); return compareHelper(heightA, heightB); } case SubColumnWidth: { const int widthA = infoA.dimensions().width(); const int widthB = infoB.dimensions().width(); return compareHelper(widthA, widthB); } case SubColumnDimensions: { const int widthA = infoA.dimensions().width(); const int widthB = infoB.dimensions().width(); const ColumnCompareResult widthResult = compareHelper(widthA, widthB); if (widthResult != CmpEqual) { return widthResult; } const int heightA = infoA.dimensions().height(); const int heightB = infoB.dimensions().height(); return compareHelper(heightA, heightB); } case SubColumnPixelCount: { const int widthA = infoA.dimensions().width(); const int widthB = infoB.dimensions().width(); const int heightA = infoA.dimensions().height(); const int heightB = infoB.dimensions().height(); const int pixelCountA = widthA*heightA; const int pixelCountB = widthB*heightB; return compareHelper(pixelCountA, pixelCountB); } case SubColumnAspectRatio: { const int widthA = infoA.dimensions().width(); const int widthB = infoB.dimensions().width(); const int heightA = infoA.dimensions().height(); const int heightB = infoB.dimensions().height(); if ((heightA == 0) || (heightB == 0)) { // at least one of the two does not have valid data, // sort based on which one has data at all return compareHelper(heightA, heightB); } const qreal aspectRatioA = qreal(widthA) / qreal(heightA); const qreal aspectRatioB = qreal(widthB) / qreal(heightB); /// @todo use fuzzy compare? return compareHelper(aspectRatioA, aspectRatioB); } case SubColumnBitDepth: { const ImageCommonContainer commonInfoA = infoA.imageCommonContainer(); const int bitDepthA = commonInfoA.colorDepth; const ImageCommonContainer commonInfoB = infoB.imageCommonContainer(); const int bitDepthB = commonInfoB.colorDepth; return compareHelper(bitDepthA, bitDepthB); } case SubColumnCreationDateTime: { const QDateTime dtA = infoA.dateTime(); const QDateTime dtB = infoB.dateTime(); return compareHelper(dtA, dtB); } case SubColumnDigitizationDateTime: { const ImageCommonContainer commonInfoA = infoA.imageCommonContainer(); const ImageCommonContainer commonInfoB = infoB.imageCommonContainer(); const QDateTime dtA = commonInfoA.digitizationDate; const QDateTime dtB = commonInfoB.digitizationDate; return compareHelper(dtA, dtB); } case SubColumnSimilarity: { qlonglong referenceImageIdA = infoA.currentReferenceImage(); qlonglong referenceImageIdB = infoB.currentReferenceImage(); if (referenceImageIdA == referenceImageIdB) { // make sure that the original image has always the highest similarity. double infoASimilarity = infoA.id() == referenceImageIdA ? 1.0 : infoA.currentSimilarity(); double infoBSimilarity = infoB.id() == referenceImageIdB ? 1.0 : infoB.currentSimilarity(); return compareHelper(infoASimilarity, infoBSimilarity); } else { qCWarning(DIGIKAM_GENERAL_LOG) << "item: items have different fuzzy search reference images. Sorting is not possible."; return CmpEqual; } } default: { qCWarning(DIGIKAM_GENERAL_LOG) << "item: unimplemented comparison, subColumn=" << subColumn; + return CmpEqual; } } } } // namespace TableViewColumns } // namespace Digikam diff --git a/core/app/views/tableview/tableview_column_photo.cpp b/core/app/views/tableview/tableview_column_photo.cpp index f3886f7cfb..a27dfa6b27 100644 --- a/core/app/views/tableview/tableview_column_photo.cpp +++ b/core/app/views/tableview/tableview_column_photo.cpp @@ -1,498 +1,518 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2013-03-14 * Description : Table view column helpers: Photo properties * * Copyright (C) 2017-2020 by Gilles Caulier * Copyright (C) 2013 by Michael G. Hansen * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "tableview_column_photo.h" // Qt includes #include #include #include // KDE includes #include // Local includes #include "digikam_debug.h" #include "coredbinfocontainers.h" #include "itempropertiestab.h" #include "dmetadata.h" #include "iteminfo.h" namespace Digikam { namespace TableViewColumns { ColumnPhotoProperties::ColumnPhotoProperties(TableViewShared* const tableViewShared, const TableViewColumnConfiguration& pConfiguration, const SubColumn pSubColumn, QObject* const parent) : TableViewColumn(tableViewShared, pConfiguration, parent), subColumn(pSubColumn) { } ColumnPhotoProperties::~ColumnPhotoProperties() { } QStringList ColumnPhotoProperties::getSubColumns() { QStringList columns; columns << QLatin1String("cameramaker") << QLatin1String("cameramodel") << QLatin1String("lens") << QLatin1String("aperture") << QLatin1String("focal") << QLatin1String("exposure") << QLatin1String("sensitivity") << QLatin1String("modeprogram") << QLatin1String("flash") << QLatin1String("whitebalance"); return columns; } TableViewColumnDescription ColumnPhotoProperties::getDescription() { TableViewColumnDescription description(QLatin1String("photo-properties"), i18n("Photo properties")); description.setIcon(QLatin1String("camera-photo")); description.addSubColumn(TableViewColumnDescription(QLatin1String("cameramaker"), i18n("Camera maker"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("cameramodel"), i18n("Camera model"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("lens"), i18n("Lens"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("aperture"), i18n("Aperture"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("focal"), i18n("Focal length"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("exposure"), i18n("Exposure"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("sensitivity"), i18n("Sensitivity"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("modeprogram"), i18n("Mode/program"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("flash"), i18n("Flash"))); description.addSubColumn(TableViewColumnDescription(QLatin1String("whitebalance"), i18n("White balance"))); return description; } QString ColumnPhotoProperties::getTitle() const { switch (subColumn) { case SubColumnCameraMaker: + { return i18n("Camera maker"); + } case SubColumnCameraModel: + { return i18n("Camera model"); + } case SubColumnLens: + { return i18n("Lens"); + } case SubColumnAperture: + { return i18n("Aperture"); + } case SubColumnFocal: + { return i18n("Focal length"); + } case SubColumnExposure: + { return i18n("Exposure"); + } case SubColumnSensitivity: + { return i18n("Sensitivity"); + } case SubColumnModeProgram: + { return i18n("Mode/program"); + } case SubColumnFlash: + { return i18n("Flash"); + } case SubColumnWhiteBalance: + { return i18n("White balance"); + } } return QString(); } TableViewColumn::ColumnFlags ColumnPhotoProperties::getColumnFlags() const { ColumnFlags flags(ColumnNoFlags); if ( (subColumn == SubColumnAperture) || (subColumn == SubColumnFocal) || (subColumn == SubColumnExposure) || (subColumn == SubColumnSensitivity) ) { flags |= ColumnCustomSorting; } if (subColumn == SubColumnExposure) { flags |= ColumnHasConfigurationWidget; } return flags; } QVariant ColumnPhotoProperties::data(TableViewModel::Item* const item, const int role) const { if (role != Qt::DisplayRole) { return QVariant(); } switch (subColumn) { case SubColumnCameraMaker: { QString cameraMaker = s->tableViewModel->itemDatabaseFieldRaw(item, DatabaseFields::Set(DatabaseFields::Make)).toString(); ItemPropertiesTab::shortenedMakeInfo(cameraMaker); return cameraMaker; } case SubColumnCameraModel: { QString cameraModel = s->tableViewModel->itemDatabaseFieldRaw(item, DatabaseFields::Set(DatabaseFields::Model)).toString(); ItemPropertiesTab::shortenedModelInfo(cameraModel); return cameraModel; } case SubColumnLens: { const QString cameraLens = s->tableViewModel->itemDatabaseFieldRaw(item, DatabaseFields::Set(DatabaseFields::Lens)).toString(); return cameraLens; } case SubColumnAperture: { const QVariant apertureVariant = s->tableViewModel->itemDatabaseFieldRaw(item, DatabaseFields::Set(DatabaseFields::Aperture)); const QString apertureString = DMetadata::valueToString(apertureVariant, MetadataInfo::Aperture); return apertureString; } case SubColumnFocal: { /// @todo Make this configurable const DatabaseFields::Set requiredSet = DatabaseFields::Set(DatabaseFields::FocalLength | DatabaseFields::FocalLength35); const TableViewModel::DatabaseFieldsHashRaw rawFields = s->tableViewModel->itemDatabaseFieldsRaw(item, requiredSet); const QVariant focalLengthVariant = rawFields.value(DatabaseFields::FocalLength); const QString focalLengthString = DMetadata::valueToString(focalLengthVariant, MetadataInfo::FocalLength); const QVariant focalLength35Variant = rawFields.value(DatabaseFields::FocalLength35); const QString focalLength35String = DMetadata::valueToString(focalLength35Variant, MetadataInfo::FocalLengthIn35mm); if (focalLength35String.isEmpty()) { return focalLengthString; } if (focalLengthString.isEmpty()) { return QString(); } /// @todo What if only 35 mm is set? return i18n("%1 (%2)", focalLengthString, focalLength35String); } case SubColumnExposure: { /// @todo Add a configuration option for fraction vs number, units s vs ms vs mus const QVariant exposureVariant = s->tableViewModel->itemDatabaseFieldRaw(item, DatabaseFields::Set(DatabaseFields::ExposureTime)); if (configuration.getSetting(QLatin1String("format"), QLatin1String("fraction")) == QLatin1String("fraction")) { const QString exposureString = DMetadata::valueToString(exposureVariant, MetadataInfo::ExposureTime); return exposureString; } if (!exposureVariant.isValid()) { return QString(); } const QString unitKey = configuration.getSetting(QLatin1String("unit"), QLatin1String("seconds")); double multiplier = 1.0; KLocalizedString exposureTimeLocalizedString = ki18n("%1 s"); if (unitKey == QLatin1String("milliseconds")) { multiplier = 1000.0; exposureTimeLocalizedString = ki18n("%1 ms"); } else if (unitKey == QLatin1String("microseconds")) { multiplier = 1000000.0; exposureTimeLocalizedString = ki18n("%1 µs"); } const double exposureTime = exposureVariant.toDouble() * multiplier; /// @todo Seems like we have to check for 0 here, too, as an invalid value if (exposureTime == 0) { return QString(); } /// @todo Remove trailing zeros? /// @todo Align right? --> better align at decimal point const QString exposureTimeString = exposureTimeLocalizedString.subs(QLocale().toString(exposureTime, 'g', 3)).toString(); return exposureTimeString; } case SubColumnSensitivity: { const QVariant sensitivityVariant = s->tableViewModel->itemDatabaseFieldRaw(item, DatabaseFields::Set(DatabaseFields::Sensitivity)); const QString sensitivityString = DMetadata::valueToString(sensitivityVariant, MetadataInfo::Sensitivity); if (sensitivityString.isEmpty()) { return QString(); } return i18n("%1 ISO", sensitivityString); } case SubColumnModeProgram: { const DatabaseFields::Set requiredSet = DatabaseFields::Set(DatabaseFields::ExposureMode | DatabaseFields::ExposureProgram); const TableViewModel::DatabaseFieldsHashRaw rawFields = s->tableViewModel->itemDatabaseFieldsRaw(item, requiredSet); const QVariant exposureModeVariant = rawFields.value(DatabaseFields::ExposureMode); const QString exposureModeString = DMetadata::valueToString(exposureModeVariant, MetadataInfo::ExposureMode); const QVariant exposureProgramVariant = rawFields.value(DatabaseFields::ExposureProgram); const QString exposureProgramString = DMetadata::valueToString(exposureProgramVariant, MetadataInfo::ExposureProgram); if (exposureModeString.isEmpty() && exposureProgramString.isEmpty()) { return QString(); } else if (!exposureModeString.isEmpty() && exposureProgramString.isEmpty()) { return exposureModeString; } else if (exposureModeString.isEmpty() && !exposureProgramString.isEmpty()) { return exposureProgramString; } return QString::fromUtf8("%1 / %2").arg(exposureModeString).arg(exposureProgramString); } case SubColumnFlash: { const QVariant flashModeVariant = s->tableViewModel->itemDatabaseFieldRaw(item, DatabaseFields::Set(DatabaseFields::FlashMode)); const QString flashModeString = DMetadata::valueToString(flashModeVariant, MetadataInfo::FlashMode); return flashModeString; } case SubColumnWhiteBalance: { const QVariant whiteBalanceVariant = s->tableViewModel->itemDatabaseFieldRaw(item, DatabaseFields::Set(DatabaseFields::WhiteBalance)); const QString whiteBalanceString = DMetadata::valueToString(whiteBalanceVariant, MetadataInfo::WhiteBalance); return whiteBalanceString; } } return QVariant(); } TableViewColumn::ColumnCompareResult ColumnPhotoProperties::compare(TableViewModel::Item* const itemA, TableViewModel::Item* const itemB) const { const ItemInfo infoA = s->tableViewModel->infoFromItem(itemA); const ItemInfo infoB = s->tableViewModel->infoFromItem(itemB); switch (subColumn) { case SubColumnAperture: { const QVariant variantA = s->tableViewModel->itemDatabaseFieldRaw(itemA, DatabaseFields::Set(DatabaseFields::Aperture)); const QVariant variantB = s->tableViewModel->itemDatabaseFieldRaw(itemB, DatabaseFields::Set(DatabaseFields::Aperture)); const double apertureA = variantA.toDouble(); const double apertureB = variantB.toDouble(); return compareHelper(apertureA, apertureB); } case SubColumnFocal: { /// @todo This just works if both have focal length set, not if focal length 35 has to be used const QVariant variantA = s->tableViewModel->itemDatabaseFieldRaw(itemA, DatabaseFields::Set(DatabaseFields::FocalLength)); const QVariant variantB = s->tableViewModel->itemDatabaseFieldRaw(itemB, DatabaseFields::Set(DatabaseFields::FocalLength)); const double focalLengthA = variantA.toDouble(); const double focalLengthB = variantB.toDouble(); return compareHelper(focalLengthA, focalLengthB); } case SubColumnExposure: { const QVariant variantA = s->tableViewModel->itemDatabaseFieldRaw(itemA, DatabaseFields::Set(DatabaseFields::ExposureTime)); const QVariant variantB = s->tableViewModel->itemDatabaseFieldRaw(itemB, DatabaseFields::Set(DatabaseFields::ExposureTime)); const double exposureTimeA = variantA.toDouble(); const double exposureTimeB = variantB.toDouble(); return compareHelper(exposureTimeA, exposureTimeB); } case SubColumnSensitivity: { const QVariant variantA = s->tableViewModel->itemDatabaseFieldRaw(itemA, DatabaseFields::Set(DatabaseFields::Sensitivity)); const QVariant variantB = s->tableViewModel->itemDatabaseFieldRaw(itemB, DatabaseFields::Set(DatabaseFields::Sensitivity)); const double sensitivityA = variantA.toDouble(); const double sensitivityB = variantB.toDouble(); return compareHelper(sensitivityA, sensitivityB); } default: { qCWarning(DIGIKAM_GENERAL_LOG) << "item: unimplemented comparison, subColumn=" << subColumn; return CmpEqual; } } } TableViewColumnConfigurationWidget* ColumnPhotoProperties::getConfigurationWidget(QWidget* const parentWidget) const { TableViewColumnConfiguration myConfiguration = getConfiguration(); return (new ColumnPhotoConfigurationWidget(s, myConfiguration, parentWidget)); } // --------------------------------------------------------------------------------------------------------------------- ColumnPhotoConfigurationWidget::ColumnPhotoConfigurationWidget(TableViewShared* const sharedObject, const TableViewColumnConfiguration& columnConfiguration, QWidget* const parentWidget) : TableViewColumnConfigurationWidget(sharedObject, columnConfiguration, parentWidget), subColumn(ColumnPhotoProperties::SubColumnExposure), selectorExposureTimeFormat(nullptr), selectorExposureTimeUnit(nullptr) { ColumnPhotoProperties::getSubColumnIndex(configuration.columnId, &subColumn); switch (subColumn) { case ColumnPhotoProperties::SubColumnExposure: { QFormLayout* const box1 = new QFormLayout(); selectorExposureTimeFormat = new QComboBox(this); selectorExposureTimeFormat->addItem(i18n("Fraction"), QLatin1String("fraction")); selectorExposureTimeFormat->addItem(i18n("Rational"), QLatin1String("rational")); box1->addRow(i18n("Format"), selectorExposureTimeFormat); selectorExposureTimeUnit = new QComboBox(this); selectorExposureTimeUnit->addItem(i18n("Seconds"), QLatin1String("seconds")); selectorExposureTimeUnit->addItem(i18n("Milliseconds"), QLatin1String("milliseconds")); selectorExposureTimeUnit->addItem(i18n("Microseconds"), QLatin1String("microseconds")); box1->addRow(i18n("Unit"), selectorExposureTimeUnit); setLayout(box1); const int indexF = selectorExposureTimeFormat->findData(configuration.getSetting(QLatin1String("format"), QLatin1String("fraction"))); selectorExposureTimeFormat->setCurrentIndex((indexF >= 0) ? indexF : 0); const int indexU = selectorExposureTimeUnit->findData(configuration.getSetting(QLatin1String("unit"), QLatin1String("seconds"))); selectorExposureTimeUnit->setCurrentIndex((indexU >= 0) ? indexU : 0); slotUpdateUI(); connect(selectorExposureTimeFormat, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateUI())); break; } default: { break; } } } ColumnPhotoConfigurationWidget::~ColumnPhotoConfigurationWidget() { } TableViewColumnConfiguration ColumnPhotoConfigurationWidget::getNewConfiguration() { const QString formatKey = selectorExposureTimeFormat->itemData(selectorExposureTimeFormat->currentIndex()).toString(); configuration.columnSettings.insert(QLatin1String("format"), formatKey); const QString unitKey = selectorExposureTimeUnit->itemData(selectorExposureTimeUnit->currentIndex()).toString(); configuration.columnSettings.insert(QLatin1String("unit"), unitKey); return configuration; } void ColumnPhotoProperties::setConfiguration(const TableViewColumnConfiguration& newConfiguration) { configuration = newConfiguration; emit signalAllDataChanged(); } void ColumnPhotoConfigurationWidget::slotUpdateUI() { if (selectorExposureTimeFormat) { const QString currentKey = selectorExposureTimeFormat->itemData(selectorExposureTimeFormat->currentIndex()).toString(); const bool needsUnits = (currentKey == QLatin1String("rational")); selectorExposureTimeUnit->setEnabled(needsUnits); } } } // namespace TableViewColumns } // namespace Digikam