Krita Source Code Documentation
Loading...
Searching...
No Matches
KisResourceItemChooserContextMenu.cpp
Go to the documentation of this file.
1
2/* This file is part of the KDE project
3 * SPDX-FileCopyrightText: 2013 Sascha Suelzer <s.suelzer@gmail.com>
4 * SPDX-FileCopyrightText: 2020 Agata Cacko <cacko.azh@gmail.com>
5 *
6 * SPDX-License-Identifier: LGPL-2.0-or-later
7 * */
8
10
11#include <QDebug>
12#include <QGridLayout>
13
14#include <KoIcon.h>
15#include <klocalizedstring.h>
16#include <KoResource.h>
17#include <KisResourceModel.h>
18#include <KisTagResourceModel.h>
19#include <KisTag.h>
20
21
22#include "kis_debug.h"
23
25 return !tag.isNull() && tag->id() < 0;
26}
27
28
30 const KisTagSP currentlySelectedTag,
31 KisTagChooserWidget *tagChooser)
32 : m_tagChooserWidget(tagChooser)
33{
34 QImage image = resource->image();
35 QIcon icon(QPixmap::fromImage(image));
36 QAction *label = new QAction(resource->name(), this);
37 label->setIcon(icon);
38
39 addAction(label);
40
41 QMenu *removableTagsMenu;
42 QMenu *assignableTagsMenu;
43
44 m_tagModel = new KisTagModel(resource->resourceType().first);
46 KisResourceModel resourceModel(resource->resourceType().first);
47 KisTagResourceModel tagResourceModel(resource->resourceType().first);
48
49 tagResourceModel.setResourcesFilter(QVector<KoResourceSP>() << resource);
50 tagResourceModel.sort(KisAllTagResourceModel::TagName);
51
52 QList<KisTagSP> removableTags;
53 for (int i = 0; i < tagResourceModel.rowCount(); ++i) {
54 KisTagSP tag = tagResourceModel.data(tagResourceModel.index(i, 0), Qt::UserRole + KisAllTagResourceModel::Tag).value<KisTagSP>();
55 if (!tag.isNull() && tag->valid() && !isSpecialTag(tag)) {
56 removableTags << tag;
57 }
58 }
59
60 QList<KisTagSP> assignableTags;
61 for (int i = 0; i < m_tagModel->rowCount(); i++) {
62 QModelIndex index = m_tagModel->index(i, 0);
63 KisTagSP tag = m_tagModel->tagForIndex(index);
64 if (!tag.isNull() && tag->valid() && !isSpecialTag(tag)) {
65 assignableTags << tag;
66 }
67 }
68
69 CompareWithOtherTagFunctor comparer(currentlySelectedTag);
70
71 bool currentTagInRemovables = !currentlySelectedTag.isNull();
72 currentTagInRemovables = currentTagInRemovables
73 && (std::find_if(removableTags.begin(), removableTags.end(), comparer) != removableTags.end());
74
75 assignableTagsMenu = addMenu(koIcon("list-add"),i18n("Assign to tag"));
76
77 if (!removableTags.isEmpty()) {
78 addSeparator();
79 KisTagSP currentTag = currentlySelectedTag;
80
81 if (!currentTag.isNull() && currentTagInRemovables) {
82 // remove the current tag from both "Remove from tag: " and "Assign to tag: " lists
83 removableTags.erase(std::remove_if(removableTags.begin(),
84 removableTags.end(),
85 comparer),
86 removableTags.end());
87 assignableTags.erase(std::remove_if(assignableTags.begin(),
88 assignableTags.end(),
89 comparer),
90 assignableTags.end());
91
92 SimpleExistingTagAction *removeTagAction = new SimpleExistingTagAction(resource, currentTag, this);
93 removeTagAction->setText(i18n("Remove from this tag"));
94 removeTagAction->setIcon(koIcon("list-remove"));
95
96 connect(removeTagAction, SIGNAL(triggered(const KisTagSP, KoResourceSP)),
98 addAction(removeTagAction);
99 }
100
101 if (!removableTags.isEmpty()) {
102 removableTagsMenu = addMenu(koIcon("list-remove"),i18n("Remove from other tag"));
103
104 KisTagSP empty;
105 CompareWithOtherTagFunctor compareWithRemovable(empty);
106 foreach (const KisTagSP tag, removableTags) {
107
108 if (tag.isNull()) {
109 continue;
110 }
111
112 compareWithRemovable.setReferenceTag(tag);
113 assignableTags.erase(std::remove_if(assignableTags.begin(),
114 assignableTags.end(),
115 compareWithRemovable),
116 assignableTags.end());
117
118 SimpleExistingTagAction *removeTagAction = new SimpleExistingTagAction(resource, tag, this);
119
120 connect(removeTagAction, SIGNAL(triggered(const KisTagSP, KoResourceSP)),
122 removableTagsMenu->addAction(removeTagAction);
123 }
124 }
125
126 }
127
128 foreach (const KisTagSP &tag, assignableTags) {
129 if (tag.isNull()) {
130 continue;
131 }
132
133 SimpleExistingTagAction * addTagAction = new SimpleExistingTagAction(resource, tag, this);
134
135 connect(addTagAction, SIGNAL(triggered(const KisTagSP, KoResourceSP)),
136 this, SLOT(addResourceExistingTag(const KisTagSP, KoResourceSP)));
137
138 assignableTagsMenu->addAction(addTagAction);
139 }
140
141 assignableTagsMenu->addSeparator();
142
143 NewTagResourceAction *addNewTagAction = new NewTagResourceAction(resource, this);
144 connect(addNewTagAction, SIGNAL(triggered(QString, KoResourceSP)), m_tagChooserWidget, SLOT(addTag(QString, KoResourceSP)));
145
146 assignableTagsMenu->addAction(addNewTagAction);
147
148}
149
154
156{
157 KisTagResourceModel tagResourceModel(resource->resourceType().first);
158 tagResourceModel.untagResources(tag, QVector<int>() << resource->resourceId());
159}
160
162{
163 KisTagResourceModel tagResourceModel(resource->resourceType().first);
164 tagResourceModel.tagResources(tag, QVector<int>() << resource->resourceId());
165}
bool isSpecialTag(KisTagSP tag)
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
The CompareWithOtherTagFunctor class defines a comparer for tags.
Definition TagActions.h:186
void setReferenceTag(KisTagSP referenceTag)
setReferenceTag sets a reference tag in the comparer
void removeResourceExistingTag(const KisTagSP tag, KoResourceSP resource)
removeResourceExistingTag slot for a signal from the action to remove the tag from the resource
KisResourceItemChooserContextMenu(KoResourceSP resource, const KisTagSP currentlySelectedTag, KisTagChooserWidget *tagChooser)
KisResourceItemChooserContextMenu the constructor for the KisResourceItemChooserContextMenu class.
KisTagModel * m_tagModel
m_tagModel data model for tags (for tagging and untagging resources and create lists of tags)
void addResourceExistingTag(const KisTagSP tag, KoResourceSP resource)
addResourceExistingTag slot for a signal from the action to add the tag to the resource
The KisResourceModel class provides the main access to resources. It is possible to filter the resour...
The KisTagChooserWidget class is responsible for all the logic that the tags combobox has in various ...
KisTagSP tagForIndex(QModelIndex index=QModelIndex()) const override
The KisTagResourceModel class makes it possible to retrieve the resources for certain tags or the tag...
bool untagResources(const KisTagSP tag, const QVector< int > &resourceIds) override
bool tagResources(const KisTagSP tag, const QVector< int > &resourceIds) override
void setResourcesFilter(const QVector< int > resourceIds)
The NewTagResourceAction class defines an action that sends a signal with QString and a saved resourc...
Definition TagActions.h:156
The SimpleExistingTagAction class defines an action that holds a resource and a tag.
Definition TagActions.h:31
#define koIcon(name)
Use these macros for icons without any issues.
Definition kis_icon.h:25