File indexing completed on 2024-04-21 04:39:55

0001 /*
0002     SPDX-FileCopyrightText: 2018 Nicolas Fella <nicolas.fella@gmx.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "tagsfileitemaction.h"
0008 
0009 #include <QAction>
0010 #include <QFileInfo>
0011 #include <QIcon>
0012 #include <QInputDialog>
0013 #include <QList>
0014 #include <QMenu>
0015 #include <QUrl>
0016 #include <QVariantList>
0017 #include <QWidget>
0018 
0019 #include <KLocalizedString>
0020 #include <KPluginFactory>
0021 
0022 K_PLUGIN_FACTORY_WITH_JSON(TagsFileItemActionFactory, "tagsfileitemaction.json", registerPlugin<TagsFileItemAction>();)
0023 
0024 TagsFileItemAction::TagsFileItemAction(QObject *parent, const QVariantList &)
0025     : KAbstractFileItemActionPlugin(parent)
0026     , m_tagsLister()
0027 {
0028     m_menu = new QMenu(i18n("Assign Tags"));
0029     m_menu->setIcon(QIcon::fromTheme(QStringLiteral("tag")));
0030 
0031     connect(&m_tagsLister, &KCoreDirLister::itemsAdded, this, [this](const QUrl &, const KFileItemList &items) {
0032         const QStringList fileTags = m_metaData->tags();
0033 
0034         // The file may be located outside an indexed path, or is not indexed yet
0035         // Show the complete tag list, i.e. the union of file and index DB tags
0036         QStringList allTags;
0037         allTags.reserve(fileTags.size() + items.size());
0038         allTags.append(fileTags);
0039         for (const KFileItem &item : items) {
0040             allTags.append(item.name());
0041         }
0042         allTags.sort(Qt::CaseInsensitive);
0043         allTags.removeDuplicates();
0044 
0045         for (const QString &name : std::as_const(allTags)) {
0046             QAction *action = m_menu->addAction(QIcon::fromTheme(QStringLiteral("tag")), name);
0047             action->setCheckable(true);
0048             action->setChecked(fileTags.contains(name));
0049 
0050             connect(action, &QAction::triggered, this, [this, name](bool isChecked) {
0051                 QStringList newTags = m_metaData->tags();
0052                 if (isChecked) {
0053                     newTags.append(name);
0054                 } else {
0055                     newTags.removeAll(name);
0056                 }
0057                 m_metaData->setTags(newTags);
0058             });
0059         }
0060     });
0061 
0062     newAction = new QAction(i18n("Create New..."));
0063     newAction->setIcon(QIcon::fromTheme(QStringLiteral("tag-new")));
0064 
0065     connect(newAction, &QAction::triggered, this, [this] {
0066         QString newTag = QInputDialog::getText(m_menu, i18n("New tag"), i18n("New tag:"), QLineEdit::Normal);
0067         QStringList tags = m_metaData->tags();
0068         if (!tags.contains(newTag)) {
0069             tags.append(newTag);
0070             m_metaData->setTags(tags);
0071         }
0072     });
0073 }
0074 
0075 TagsFileItemAction::~TagsFileItemAction()
0076 {
0077     delete m_metaData;
0078 }
0079 
0080 QList<QAction *> TagsFileItemAction::actions(const KFileItemListProperties &fileItemInfos, QWidget *parentWidget)
0081 {
0082     if (fileItemInfos.urlList().size() > 1) {
0083         return {};
0084     }
0085 
0086     const QString filePath = fileItemInfos.urlList().constFirst().toLocalFile();
0087     if (!QFileInfo(filePath).isWritable()) {
0088         return {};
0089     }
0090 
0091     m_metaData = new KFileMetaData::UserMetaData(filePath);
0092     if (!m_metaData->isSupported()) {
0093         return {};
0094     }
0095 
0096     m_tagsLister.openUrl(QUrl(QStringLiteral("tags:/")), KCoreDirLister::OpenUrlFlag::Reload);
0097 
0098     m_menu->clear();
0099     m_menu->addAction(newAction);
0100     m_menu->addSeparator();
0101     m_menu->setParent(parentWidget, Qt::Popup);
0102 
0103     return {m_menu->menuAction()};
0104 }
0105 
0106 #include "tagsfileitemaction.moc"
0107 
0108 #include "moc_tagsfileitemaction.cpp"