Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
object-hierarchy.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Object hierarchy implementation.
4 *
5 * Authors:
6 * MenTaLguY <mental@rydia.net>
7 *
8 * Copyright (C) 2004 MenTaLguY
9 *
10 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
11 */
12
13#include <cstdio>
14
15#include "object-hierarchy.h"
16
17#include "object/sp-object.h"
18
19namespace Inkscape {
20
26
30
32 _clear();
33 _changed_signal.emit(nullptr, nullptr);
34}
35
37 if (object == nullptr) { printf("Assertion object != NULL failed\n"); return; }
38
39 if ( top() == object ) {
40 return;
41 }
42
43 if (!top()) {
44 _addTop(object);
45 } else if (object->isAncestorOf(top())) {
46 _addTop(object, top());
47 } else if ( object == bottom() || object->isAncestorOf(bottom()) ) {
48 _trimAbove(object);
49 } else {
50 _clear();
51 _addTop(object);
52 }
53
54 _changed_signal.emit(top(), bottom());
55}
56
58 assert(junior != NULL);
59 assert(senior != NULL);
60
61 SPObject *object = junior->parent;
62 do {
63 _addTop(object);
64 object = object->parent;
65 } while ( object != senior );
66}
67
69 assert(object != NULL);
70 _hierarchy.push_back(_attach(object));
71 _added_signal.emit(object);
72}
73
75 while ( !_hierarchy.empty() && _hierarchy.back().object != limit ) {
76 SPObject *object=_hierarchy.back().object;
77
78 sp_object_ref(object, nullptr);
79 _detach(_hierarchy.back());
80 _hierarchy.pop_back();
81 _removed_signal.emit(object);
82 sp_object_unref(object, nullptr);
83 }
84}
85
87 if (object == nullptr) { printf("assertion object != NULL failed\n"); return; }
88
89 if ( bottom() == object ) {
90 return;
91 }
92
93 if (!top()) {
94 _addBottom(object);
95 } else if (bottom()->isAncestorOf(object)) {
96 _addBottom(bottom(), object);
97 } else if ( top() == object ) {
98 _trimBelow(top());
99 } else if (top()->isAncestorOf(object)) {
100 if (object->isAncestorOf(bottom())) {
101 _trimBelow(object);
102 } else { // object is a sibling or cousin of bottom()
103 SPObject *saved_top=top();
104 sp_object_ref(saved_top, nullptr);
105 _clear();
106 _addBottom(saved_top);
107 _addBottom(saved_top, object);
108 sp_object_unref(saved_top, nullptr);
109 }
110 } else {
111 _clear();
112 _addBottom(object);
113 }
114
115 _changed_signal.emit(top(), bottom());
116}
117
119 while ( !_hierarchy.empty() && _hierarchy.front().object != limit ) {
120 SPObject *object=_hierarchy.front().object;
121 sp_object_ref(object, nullptr);
122 _detach(_hierarchy.front());
123 _hierarchy.pop_front();
124 _removed_signal.emit(object);
125 sp_object_unref(object, nullptr);
126 }
127}
128
130 assert(junior != NULL);
131 assert(senior != NULL);
132
133 if ( junior != senior ) {
134 _addBottom(senior, junior->parent);
135 _addBottom(junior);
136 }
137}
138
140 assert(object != NULL);
141 _hierarchy.push_front(_attach(object));
142 _added_signal.emit(object);
143}
144
146 this->_trimBelow(object);
147 assert(!this->_hierarchy.empty());
148 assert(this->_hierarchy.front().object == object);
149
150 sp_object_ref(object, nullptr);
151 this->_detach(this->_hierarchy.front());
152 this->_hierarchy.pop_front();
153 this->_removed_signal.emit(object);
154 sp_object_unref(object, nullptr);
155
156 this->_changed_signal.emit(this->top(), this->bottom());
157}
158
160 sp_object_ref(object, nullptr);
161 sigc::connection connection
162 = object->connectRelease(
163 sigc::mem_fun(*this, &ObjectHierarchy::_trim_for_release)
164 );
165 return Record(object, connection);
166}
167
169 rec.connection.disconnect();
170 sp_object_unref(rec.object, nullptr);
171}
172
173}
174
175/*
176 Local Variables:
177 mode:c++
178 c-file-style:"stroustrup"
179 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
180 indent-tabs-mode:nil
181 fill-column:99
182 End:
183*/
184// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
ObjectHierarchy(SPObject *top=nullptr)
Create new object hierarchy.
void _trim_for_release(SPObject *released)
void clear()
Remove all entries.
void _detach(Record &record)
void _trimAbove(SPObject *limit)
Remove all objects above limit from hierarchy.
void setBottom(SPObject *object)
Trim or expand hierarchy at bottom such that object becomes bottom entry.
void _addTop(SPObject *senior, SPObject *junior)
Add hierarchy from junior's parent to senior to this hierarchy's top.
void setTop(SPObject *object)
Trim or expand hierarchy on top such that object becomes top entry.
std::list< Record > _hierarchy
sigc::signal< void(SPObject *)> _added_signal
Record _attach(SPObject *object)
sigc::signal< void(SPObject *)> _removed_signal
sigc::signal< void(SPObject *, SPObject *)> _changed_signal
void _trimBelow(SPObject *limit)
Remove all objects under given object.
void _addBottom(SPObject *senior, SPObject *junior)
Add hierarchy from senior to junior, in range (senior, junior], to this hierarchy's bottom.
SPObject is an abstract base class of all of the document nodes at the SVG document level.
Definition sp-object.h:160
SPObject * parent
Definition sp-object.h:189
bool isAncestorOf(SPObject const *object) const
True if object is non-NULL and this is some in/direct parent of object.
Helper class to stream background task notifications as a series of messages.
SPObject * sp_object_unref(SPObject *object, SPObject *owner)
Decrease reference count of object, with possible debugging and finalization.
SPObject * sp_object_ref(SPObject *object, SPObject *owner)
Increase reference count of object, with possible debugging.