File indexing completed on 2024-05-12 15:59:57
0001 0002 /* This file is part of the KDE project 0003 * SPDX-FileCopyrightText: 2013 Sascha Suelzer <s.suelzer@gmail.com> 0004 * SPDX-FileCopyrightText: 2020 Agata Cacko <cacko.azh@gmail.com> 0005 * 0006 * SPDX-License-Identifier: LGPL-2.0-or-later 0007 * */ 0008 0009 #include "KisResourceItemChooserContextMenu.h" 0010 0011 #include <QDebug> 0012 #include <QLabel> 0013 #include <QGridLayout> 0014 0015 #include <KoIcon.h> 0016 #include <klocalizedstring.h> 0017 #include <KoResource.h> 0018 #include <KisResourceModel.h> 0019 #include <KisTagResourceModel.h> 0020 #include <KisTag.h> 0021 0022 0023 #include "kis_debug.h" 0024 0025 bool isSpecialTag(KisTagSP tag) { 0026 return !tag.isNull() && tag->id() < 0; 0027 } 0028 0029 0030 KisResourceItemChooserContextMenu::KisResourceItemChooserContextMenu(KoResourceSP resource, 0031 const KisTagSP currentlySelectedTag, 0032 KisTagChooserWidget *tagChooser) 0033 : m_tagChooserWidget(tagChooser) 0034 { 0035 QImage image = resource->image(); 0036 QIcon icon(QPixmap::fromImage(image)); 0037 QAction *label = new QAction(resource->name(), this); 0038 label->setIcon(icon); 0039 0040 addAction(label); 0041 0042 QMenu *removableTagsMenu; 0043 QMenu *assignableTagsMenu; 0044 0045 m_tagModel = new KisTagModel(resource->resourceType().first); 0046 m_tagModel->sort(KisAllTagsModel::Name); 0047 KisResourceModel resourceModel(resource->resourceType().first); 0048 KisTagResourceModel tagResourceModel(resource->resourceType().first); 0049 0050 tagResourceModel.setResourcesFilter(QVector<KoResourceSP>() << resource); 0051 tagResourceModel.sort(KisAllTagResourceModel::TagName); 0052 0053 QList<KisTagSP> removableTags; 0054 for (int i = 0; i < tagResourceModel.rowCount(); ++i) { 0055 KisTagSP tag = tagResourceModel.data(tagResourceModel.index(i, 0), Qt::UserRole + KisAllTagResourceModel::Tag).value<KisTagSP>(); 0056 if (!tag.isNull() && tag->valid() && !isSpecialTag(tag)) { 0057 removableTags << tag; 0058 } 0059 } 0060 0061 QList<KisTagSP> assignableTags; 0062 for (int i = 0; i < m_tagModel->rowCount(); i++) { 0063 QModelIndex index = m_tagModel->index(i, 0); 0064 KisTagSP tag = m_tagModel->tagForIndex(index); 0065 if (!tag.isNull() && tag->valid() && !isSpecialTag(tag)) { 0066 assignableTags << tag; 0067 } 0068 } 0069 0070 CompareWithOtherTagFunctor comparer(currentlySelectedTag); 0071 0072 bool currentTagInRemovables = !currentlySelectedTag.isNull(); 0073 currentTagInRemovables = currentTagInRemovables 0074 && (std::find_if(removableTags.begin(), removableTags.end(), comparer) != removableTags.end()); 0075 0076 assignableTagsMenu = addMenu(koIcon("list-add"),i18n("Assign to tag")); 0077 0078 if (!removableTags.isEmpty()) { 0079 addSeparator(); 0080 KisTagSP currentTag = currentlySelectedTag; 0081 0082 if (!currentTag.isNull() && currentTagInRemovables) { 0083 // remove the current tag from both "Remove from tag: " and "Assign to tag: " lists 0084 removableTags.erase(std::remove_if(removableTags.begin(), 0085 removableTags.end(), 0086 comparer), 0087 removableTags.end()); 0088 assignableTags.erase(std::remove_if(assignableTags.begin(), 0089 assignableTags.end(), 0090 comparer), 0091 assignableTags.end()); 0092 0093 SimpleExistingTagAction *removeTagAction = new SimpleExistingTagAction(resource, currentTag, this); 0094 removeTagAction->setText(i18n("Remove from this tag")); 0095 removeTagAction->setIcon(koIcon("list-remove")); 0096 0097 connect(removeTagAction, SIGNAL(triggered(const KisTagSP, KoResourceSP)), 0098 this, SLOT(removeResourceExistingTag(const KisTagSP, KoResourceSP))); 0099 addAction(removeTagAction); 0100 } 0101 0102 if (!removableTags.isEmpty()) { 0103 removableTagsMenu = addMenu(koIcon("list-remove"),i18n("Remove from other tag")); 0104 0105 KisTagSP empty; 0106 CompareWithOtherTagFunctor compareWithRemovable(empty); 0107 foreach (const KisTagSP tag, removableTags) { 0108 0109 if (tag.isNull()) { 0110 continue; 0111 } 0112 0113 compareWithRemovable.setReferenceTag(tag); 0114 assignableTags.erase(std::remove_if(assignableTags.begin(), 0115 assignableTags.end(), 0116 compareWithRemovable), 0117 assignableTags.end()); 0118 0119 SimpleExistingTagAction *removeTagAction = new SimpleExistingTagAction(resource, tag, this); 0120 0121 connect(removeTagAction, SIGNAL(triggered(const KisTagSP, KoResourceSP)), 0122 this, SLOT(removeResourceExistingTag(const KisTagSP, KoResourceSP))); 0123 removableTagsMenu->addAction(removeTagAction); 0124 } 0125 } 0126 0127 } 0128 0129 foreach (const KisTagSP &tag, assignableTags) { 0130 if (tag.isNull()) { 0131 continue; 0132 } 0133 0134 SimpleExistingTagAction * addTagAction = new SimpleExistingTagAction(resource, tag, this); 0135 0136 connect(addTagAction, SIGNAL(triggered(const KisTagSP, KoResourceSP)), 0137 this, SLOT(addResourceExistingTag(const KisTagSP, KoResourceSP))); 0138 0139 assignableTagsMenu->addAction(addTagAction); 0140 } 0141 0142 assignableTagsMenu->addSeparator(); 0143 0144 NewTagResourceAction *addNewTagAction = new NewTagResourceAction(resource, this); 0145 connect(addNewTagAction, SIGNAL(triggered(QString, KoResourceSP)), m_tagChooserWidget, SLOT(addTag(QString, KoResourceSP))); 0146 0147 assignableTagsMenu->addAction(addNewTagAction); 0148 0149 } 0150 0151 KisResourceItemChooserContextMenu::~KisResourceItemChooserContextMenu() 0152 { 0153 delete m_tagModel; 0154 } 0155 0156 void KisResourceItemChooserContextMenu::removeResourceExistingTag(const KisTagSP tag, KoResourceSP resource) 0157 { 0158 KisTagResourceModel tagResourceModel(resource->resourceType().first); 0159 tagResourceModel.untagResources(tag, QVector<int>() << resource->resourceId()); 0160 } 0161 0162 void KisResourceItemChooserContextMenu::addResourceExistingTag(const KisTagSP tag, KoResourceSP resource) 0163 { 0164 KisTagResourceModel tagResourceModel(resource->resourceType().first); 0165 tagResourceModel.tagResources(tag, QVector<int>() << resource->resourceId()); 0166 }