Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_node_query_path.cc
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2009 Cyrille Berger <cberger@cberger.net>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#include <QStringList>
10#include <kis_node.h>
11#include <kis_image.h>
12#include <kis_paint_device.h>
13
20 PathElement(Type _type) : type(_type) {
21 Q_ASSERT(type == Wildcard || type == Parent);
22 }
23 PathElement(int _i) : type(Index), index(_i) {}
25 unsigned int index {0};
26};
27
28struct Q_DECL_HIDDEN KisNodeQueryPath::Private {
32 void simplifyPath() {
33 // No elements then return
34 if (elements.isEmpty()) return;
35 QList<PathElement> newelements;
36 int i = 0;
37 for (; i < elements.count() && elements[i].type == PathElement::Parent; ++i) {
38 newelements.push_back(PathElement::Parent);
39 }
40 // Loop over the element of the list
41 for (; i < elements.count(); ++i) {
42 PathElement pe = elements[i];
43 // If it's the last element, or the next element isn't a parent
44 if (pe.type != PathElement::Parent) {
45 newelements.push_back(pe);
46 } else {
47 if (newelements.isEmpty() || newelements.last().type == PathElement::Parent) {
48 newelements.push_back(PathElement::Parent);
49 } else {
50 newelements.removeLast();
51 }
52 }
53 }
54 // Set the new list
55 elements = newelements;
56 }
57 void queryLevel(int _level, KisNodeSP _node, QList<KisNodeSP>& _result) {
58 if (_level >= elements.size()) {
59 _result.push_back(_node);
60 } else {
61 PathElement pe = elements[_level];
62
63 switch (pe.type) {
65 for (KisNodeSP child = _node->firstChild();
66 child != 0; child = child->nextSibling()) {
67 queryLevel(_level + 1, child, _result);
68 }
69 }
70 break;
72 if (_node->parent()) {
73 queryLevel(_level + 1, _node->parent(), _result);
74 } else {
75 dbgKrita << "No parent";
76 }
77 break;
78 }
79 case PathElement::Index: {
80 if (pe.index < _node->childCount()) {
81 queryLevel(_level + 1, _node->at(pe.index), _result);
82 } else {
83 dbgKrita << "No parent";
84 }
85 break;
86 }
87 }
88 }
89 }
90};
91
95
100
102{
103}
104
106{
107 *d = *nqp.d;
108 return *this;
109}
110
112{
113 return d->relative;
114}
115
116
118{
119 KisNodeSP _node;
120 if (d->relative) {
121 _node = currentNode;
122 } else {
123 _node = image->root();
124 }
125
126 QList<KisNodeSP> result;
127
128 d->queryLevel(0, _node, result);
129
130 return result;
131}
132
134{
135 QList<KisNodeSP> result = queryNodes(image, currentNode);
136 KIS_ASSERT_RECOVER_NOOP(result.size() <= 1);
137
138 return !result.isEmpty() ? result.first() : 0;
139}
140
142{
143 QString str;
144 if (!d->relative) {
145 str = '/';
146 } else if (d->elements.count() == 0) {
147 return QString('.');
148 }
149 for (int i = 0; i < d->elements.count(); ++i) {
150 PathElement pe = d->elements[i];
151 switch (pe.type) {
153 str += '*';
154 break;
156 str += "..";
157 break;
159 str += QString::number(pe.index);
160 break;
161 }
162 if (i != d->elements.count() - 1) {
163 str += '/';
164 }
165 }
166 return str;
167}
168
170{
171 KisNodeQueryPath path;
172 if (_path.size() == 0 || _path == ".") {
173 path.d->relative = true;
174 return path;
175 }
176 if (_path == "/") {
177 path.d->relative = false;
178 return path;
179 }
180 path.d->relative = !(_path.at(0) == '/');
181 QStringList indexes = _path.split('/');
182 if (!path.d->relative) {
183 indexes.pop_front(); // In case of an absolute path "/1/2", the list is "", "1", "2" which is not good
184 }
185 Q_FOREACH (const QString& index, indexes) {
186 if (index == "*") {
187 path.d->elements.push_back(PathElement::Wildcard);
188 } else if (index == "..") {
189 path.d->elements.push_back(PathElement::Parent);
190 } else {
191 path.d->elements.push_back(index.toInt());
192 }
193 }
194 path.d->simplifyPath();
195 return path;
196}
197
199{
200 KisNodeQueryPath path;
201 path.d->relative = false;
202 KisNodeSP parent = 0;
203 while ((parent = node->parent())) {
204 int index = parent->index(node);
205 if (index >= 0) {
206 path.d->elements.push_front(index);
207 }
208 node = parent;
209 }
210 return path;
211}
212
213
#define KIS_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:97
#define dbgKrita
Definition kis_debug.h:45
static KisNodeQueryPath fromString(const QString &path)
KisNodeQueryPath & operator=(const KisNodeQueryPath &)
QString toString() const
QList< KisNodeSP > queryNodes(KisImageWSP image, KisNodeSP currentNode) const
QList< PathElement > elements
KisNodeSP queryUniqueNode(KisImageWSP image, KisNodeSP currentNode=0) const
static KisNodeQueryPath absolutePath(KisNodeSP node)
void simplifyPath()
This function will remove unneeded call to parent, for instance, "1/../3/../5" => "5".
void queryLevel(int _level, KisNodeSP _node, QList< KisNodeSP > &_result)
KisNodeSP firstChild() const
Definition kis_node.cpp:361
quint32 childCount() const
Definition kis_node.cpp:414
KisNodeWSP parent
Definition kis_node.cpp:86
KisNodeSP at(quint32 index) const
Definition kis_node.cpp:421
PathElement(Type _type)
unsigned int index