File indexing completed on 2025-04-27 03:58:33
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2021-04-29 0007 * Description : ExifTool configuration panel. 0008 * 0009 * SPDX-FileCopyrightText: 2021-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #include "exiftoolconfpanel.h" 0016 0017 // Qt includes 0018 0019 #include <QGridLayout> 0020 #include <QVBoxLayout> 0021 #include <QTreeWidget> 0022 #include <QTreeWidgetItem> 0023 #include <QLabel> 0024 #include <QStringList> 0025 #include <QGroupBox> 0026 #include <QApplication> 0027 #include <QStyle> 0028 #include <QHeaderView> 0029 0030 // KDE includes 0031 0032 #include <klocalizedstring.h> 0033 0034 // Local includes 0035 0036 #include "exiftoolbinary.h" 0037 #include "exiftoolparser.h" 0038 #include "dbinarysearch.h" 0039 #include "metaenginesettings.h" 0040 0041 namespace Digikam 0042 { 0043 0044 class Q_DECL_HIDDEN ExifToolConfPanel::Private 0045 { 0046 public: 0047 0048 explicit Private() 0049 : exifToolBinWidget(nullptr), 0050 searchBar (nullptr), 0051 exifToolFormats (nullptr) 0052 { 0053 } 0054 0055 public: 0056 0057 DBinarySearch* exifToolBinWidget; 0058 ExifToolBinary exifToolBin; 0059 SearchTextBar* searchBar; 0060 0061 QTreeWidget* exifToolFormats; 0062 }; 0063 0064 // -------------------------------------------------------- 0065 0066 ExifToolConfPanel::ExifToolConfPanel(QWidget* const parent) 0067 : QWidget(parent), 0068 d (new Private) 0069 { 0070 QGridLayout* const grid = new QGridLayout; 0071 QLabel* const exifToolBinLabel = new QLabel(i18nc("@info", 0072 "%1 is an open-source software program for reading, writing, " 0073 "and manipulating multimedia files. It is platform independent " 0074 "available as a command-line application. ExifTool is commonly " 0075 "incorporated into different types of digital workflows and supports " 0076 "many types of metadata including Exif, IPTC, XMP, JFIF, GeoTIFF, ICC Profile, " 0077 "Photoshop IRB, as well as the manufacturer-specific metadata formats of " 0078 "many digital cameras.\n\n" 0079 "Here you can configure location where ExifTool binary is located. " 0080 "Application will try to find this binary automatically if they are " 0081 "already installed on your computer.", 0082 QString::fromUtf8("<a href='https://www.exiftool.org'>ExifTool</a>")), 0083 this); 0084 exifToolBinLabel->setWordWrap(true); 0085 exifToolBinLabel->setOpenExternalLinks(true); 0086 0087 d->exifToolBinWidget = new DBinarySearch(this); 0088 d->exifToolBinWidget->addBinary(d->exifToolBin); 0089 0090 QGroupBox* const exifToolBox = new QGroupBox(i18nc("@title: group", "Supported File Formats"), this); 0091 d->exifToolFormats = new QTreeWidget(exifToolBox); 0092 d->exifToolFormats->setRootIsDecorated(false); 0093 d->exifToolFormats->setSortingEnabled(true); 0094 d->exifToolFormats->sortByColumn(0, Qt::AscendingOrder); 0095 d->exifToolFormats->setSelectionMode(QAbstractItemView::SingleSelection); 0096 d->exifToolFormats->setAllColumnsShowFocus(true); 0097 d->exifToolFormats->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 0098 d->exifToolFormats->setColumnCount(4); 0099 d->exifToolFormats->setHeaderHidden(false); 0100 d->exifToolFormats->setHeaderLabels(QStringList() << i18nc("@title: column", "Extension") 0101 << i18nc("@title: column", "Read") 0102 << i18nc("@title: column", "Write") 0103 << i18nc("@title: column", "Description")); 0104 0105 d->searchBar = new SearchTextBar(this, QLatin1String("ExifToolFormatsSearchBar")); 0106 0107 QVBoxLayout* const vlay = new QVBoxLayout(exifToolBox); 0108 vlay->addWidget(d->exifToolFormats); 0109 vlay->addWidget(d->searchBar); 0110 0111 grid->addWidget(exifToolBinLabel, 0, 0, 1, 2); 0112 grid->addWidget(d->exifToolBinWidget, 1, 0, 1, 2); 0113 grid->addWidget(exifToolBox, 2, 0, 1, 2); 0114 grid->setRowStretch(2, 10); 0115 setLayout(grid); 0116 0117 // --- 0118 0119 connect(d->searchBar, SIGNAL(signalSearchTextSettings(SearchTextSettings)), 0120 this, SLOT(slotSearchTextChanged(SearchTextSettings))); 0121 0122 connect(d->exifToolBinWidget, SIGNAL(signalBinariesFound(bool)), 0123 this, SLOT(slotExifToolBinaryFound(bool))); 0124 0125 Q_FOREACH (const QString& path, MetaEngineSettings::instance()->settings().defaultExifToolSearchPaths()) 0126 { 0127 d->exifToolBinWidget->addDirectory(path); 0128 } 0129 } 0130 0131 ExifToolConfPanel::~ExifToolConfPanel() 0132 { 0133 delete d; 0134 } 0135 0136 void ExifToolConfPanel::slotStartFoundExifTool() 0137 { 0138 d->exifToolBinWidget->allBinariesFound(); 0139 } 0140 0141 QString ExifToolConfPanel::exifToolDirectory() const 0142 { 0143 return d->exifToolBin.directory(); 0144 } 0145 0146 void ExifToolConfPanel::setExifToolDirectory(const QString& dir) 0147 { 0148 d->exifToolBin.setup(dir); 0149 } 0150 0151 void ExifToolConfPanel::slotExifToolBinaryFound(bool found) 0152 { 0153 d->exifToolFormats->clear(); 0154 bool exifToolAvailable = false; 0155 0156 if (found) 0157 { 0158 QScopedPointer<ExifToolParser> const parser(new ExifToolParser(this)); 0159 parser->setExifToolProgram(exifToolDirectory()); 0160 exifToolAvailable = parser->exifToolAvailable(); 0161 0162 if (exifToolAvailable) 0163 { 0164 ExifToolParser::ExifToolData parsed; 0165 QStringList read; 0166 QStringList write; 0167 0168 if (parser->readableFormats() && !parser->currentData().isEmpty()) 0169 { 0170 parsed = parser->currentData(); 0171 read = parsed.find(QLatin1String("READ_FORMATS")).value()[0].toStringList(); 0172 } 0173 0174 if (parser->writableFormats() && !parser->currentData().isEmpty()) 0175 { 0176 parsed = parser->currentData(); 0177 write = parsed.find(QLatin1String("WRITE_FORMATS")).value()[0].toStringList(); 0178 } 0179 0180 QString ext; 0181 QString desc; 0182 0183 for (int i = 0 ; i < read.size() ; i += 2) 0184 { 0185 ext = read[i]; 0186 desc = read[i + 1]; 0187 new QTreeWidgetItem(d->exifToolFormats, QStringList() << ext 0188 << i18nc("@info: status", "yes") 0189 << (write.contains(ext) ? i18nc("@info: status", "yes") 0190 : i18nc("@info: status", "no")) 0191 << desc); 0192 } 0193 } 0194 } 0195 0196 Q_EMIT signalExifToolSettingsChanged(exifToolAvailable); 0197 } 0198 0199 void ExifToolConfPanel::slotSearchTextChanged(const SearchTextSettings& settings) 0200 { 0201 bool query = false; 0202 int results = 0; 0203 QString search = settings.text.toLower(); 0204 0205 QTreeWidgetItemIterator it(d->exifToolFormats); 0206 0207 while (*it) 0208 { 0209 QTreeWidgetItem* const item = *it; 0210 0211 if (item->text(0).toLower().contains(search, settings.caseSensitive) || 0212 item->text(3).toLower().contains(search, settings.caseSensitive)) 0213 { 0214 ++results; 0215 query = true; 0216 item->setHidden(false); 0217 } 0218 else 0219 { 0220 item->setHidden(true); 0221 } 0222 0223 ++it; 0224 } 0225 0226 d->searchBar->slotSearchResult(query); 0227 } 0228 0229 } // namespace Digikam 0230 0231 #include "moc_exiftoolconfpanel.cpp"