File indexing completed on 2025-03-09 03:57:07

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2009-08-08
0007  * Description : an option to provide metadata information to the parser
0008  *
0009  * SPDX-FileCopyrightText: 2009-2012 by Andi Clemens <andi dot clemens at gmail dot com>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #include "metadataoption.h"
0016 
0017 // Qt includes
0018 
0019 #include <QGridLayout>
0020 #include <QLabel>
0021 #include <QPointer>
0022 #include <QLineEdit>
0023 #include <QApplication>
0024 #include <QStyle>
0025 #include <QScopedPointer>
0026 #include <QRegularExpression>
0027 
0028 // KDE includes
0029 
0030 #include <klocalizedstring.h>
0031 
0032 // Local includes
0033 
0034 #include "dmetadata.h"
0035 #include "metadatapanel.h"
0036 #include "metadataselector.h"
0037 
0038 namespace Digikam
0039 {
0040 
0041 MetadataOptionDialog::MetadataOptionDialog(Rule* const parent)
0042     : RuleDialog(parent),
0043       metadataPanel(nullptr),
0044       separatorLineEdit(nullptr)
0045 {
0046     QWidget* const mainWidget = new QWidget(this);
0047     QTabWidget* const tab     = new QTabWidget(this);
0048     metadataPanel             = new MetadataPanel(tab);
0049     QLabel* const customLabel = new QLabel(i18n("Keyword separator:"));
0050     separatorLineEdit         = new QLineEdit(this);
0051     separatorLineEdit->setText(QLatin1String("_"));
0052 
0053     // --------------------------------------------------------
0054 
0055     // We only need the "SearchBar" control element.
0056     // We also need to reset the default selections.
0057 
0058     Q_FOREACH (MetadataSelectorView* const viewer, metadataPanel->viewers())
0059     {
0060         viewer->setControlElements(MetadataSelectorView::SearchBar);
0061         viewer->clearSelection();
0062     }
0063 
0064     // --------------------------------------------------------
0065 
0066     // remove "Viewer" string from tabs
0067     int tabs = tab->count();
0068 
0069     for (int i = 0 ; i < tabs ; ++i)
0070     {
0071         QString text = tab->tabText(i);
0072         text.remove(QLatin1String("viewer"), Qt::CaseInsensitive);
0073         tab->setTabText(i, text.simplified());
0074     }
0075 
0076     // --------------------------------------------------------
0077 
0078     QGridLayout* const mainLayout = new QGridLayout(this);
0079     mainLayout->addWidget(customLabel,       0, 0, 1, 1);
0080     mainLayout->addWidget(separatorLineEdit, 0, 1, 1, 1);
0081     mainLayout->addWidget(tab,               1, 0, 1, -1);
0082     mainWidget->setLayout(mainLayout);
0083 
0084     // --------------------------------------------------------
0085 
0086     setSettingsWidget(mainWidget);
0087     resize(450, 450);
0088 }
0089 
0090 MetadataOptionDialog::~MetadataOptionDialog()
0091 {
0092 }
0093 
0094 // --------------------------------------------------------
0095 
0096 MetadataOption::MetadataOption()
0097     : Option(i18n("Metadata..."),
0098              i18n("Add metadata information"))
0099 {
0100     QString iconName(QLatin1String("format-text-code"));
0101     QPixmap icon = QIcon::fromTheme(iconName).pixmap(QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize));
0102     setIcon(iconName);
0103 
0104     // --------------------------------------------------------
0105 
0106     addToken(QLatin1String("[meta:||key||]"), description());
0107 
0108     QRegularExpression reg(QLatin1String("\\[meta(:(.*))\\]"));
0109     reg.setPatternOptions(QRegularExpression::InvertedGreedinessOption);
0110     setRegExp(reg);
0111 }
0112 
0113 void MetadataOption::slotTokenTriggered(const QString& token)
0114 {
0115     Q_UNUSED(token)
0116 
0117     QStringList tags;
0118 
0119     QPointer<MetadataOptionDialog> dlg = new MetadataOptionDialog(this);
0120 
0121     if (dlg->exec() == QDialog::Accepted)
0122     {
0123         QStringList checkedTags = dlg->metadataPanel->getAllCheckedTags();
0124 
0125         Q_FOREACH (const QString& tag, checkedTags)
0126         {
0127             tags << QString::fromUtf8("[meta:%1]").arg(tag);
0128         }
0129     }
0130 
0131     if (!tags.isEmpty())
0132     {
0133         QString tokenStr = tags.join(dlg->separatorLineEdit->text());
0134         Q_EMIT signalTokenTriggered(tokenStr);
0135     }
0136 
0137     delete dlg;
0138 }
0139 
0140 QString MetadataOption::parseOperation(ParseSettings& settings, const QRegularExpressionMatch& match)
0141 {
0142     QString keyword = match.captured(2);
0143     QString result  = parseMetadata(keyword, settings);
0144     return result;
0145 }
0146 
0147 QString MetadataOption::parseMetadata(const QString& token, ParseSettings& settings)
0148 {
0149     QString result;
0150 
0151     if (settings.fileUrl.isEmpty())
0152     {
0153         return result;
0154     }
0155 
0156     QString keyword = token.toLower();
0157 
0158     if (keyword.isEmpty())
0159     {
0160         return result;
0161     }
0162 
0163     QScopedPointer<DMetadata> meta(new DMetadata(settings.fileUrl.toLocalFile()));
0164 
0165     if (!meta->isEmpty())
0166     {
0167         MetaEngine::MetaDataMap dataMap;
0168 
0169         if      (keyword.startsWith(QLatin1String("exif.")))
0170         {
0171             dataMap = meta->getExifTagsDataList(QStringList(), true);
0172         }
0173         else if (keyword.startsWith(QLatin1String("iptc.")))
0174         {
0175             dataMap = meta->getIptcTagsDataList(QStringList(), true);
0176         }
0177         else if (keyword.startsWith(QLatin1String("xmp.")))
0178         {
0179             dataMap = meta->getXmpTagsDataList(QStringList(), true);
0180         }
0181 
0182         Q_FOREACH (const QString& key, dataMap.keys())
0183         {
0184             if (key.toLower().contains(keyword))
0185             {   // cppcheck-suppress useStlAlgorithm
0186                 result = dataMap[key];
0187                 break;
0188             }
0189         }
0190     }
0191 
0192     result.replace(QLatin1Char('/'), QLatin1Char('_'));
0193 
0194     return result;
0195 }
0196 
0197 } // namespace Digikam
0198 
0199 #include "moc_metadataoption.cpp"