~centralelyon2010/inkscape/imagelinks2

1 by mental
moving trunk for module inkscape
1
/*
2
 * Inkscape::SelectionDescriber - shows messages describing selection
3
 *
4
 * Authors:
5
 *   MenTaLguY <mental@rydia.net>
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
6
 *   Jon A. Cruz <jon@joncruz.org>
1 by mental
moving trunk for module inkscape
7
 *
8
 * Copyright (C) 2004 MenTaLguY
9
 *
10
 * Released under GNU GPL, read the file 'COPYING' for more information
11
 */
12
13
#ifdef HAVE_CONFIG_H
14
# include "config.h"
15
#endif
16
17
#include "document.h"
18
#include "sp-item-group.h"
19
#include "xml/repr.h"
9012.1.182 by Krzysztof Kosiński
Move around files to remove some vanity directories.
20
#include "util/find-last-if.h"
251 by mental
merged patch #1447043 from Andrius "knutux" R. to create sub-layers
21
#include "layer-fns.h"
1 by mental
moving trunk for module inkscape
22
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
23
// TODO move the documentation comments into the .h file
24
1 by mental
moving trunk for module inkscape
25
namespace Inkscape {
26
27
namespace {
28
29
bool is_layer(SPObject &object) {
30
    return SP_IS_GROUP(&object) &&
31
           SP_GROUP(&object)->layerMode() == SPGroup::LAYER;
32
}
33
251 by mental
merged patch #1447043 from Andrius "knutux" R. to create sub-layers
34
/** Finds the next sibling layer for a \a layer
35
 *
36
 *  @returns NULL if there are no further layers under a parent
37
 */
1 by mental
moving trunk for module inkscape
38
SPObject *next_sibling_layer(SPObject *layer) {
39
    using std::find_if;
40
41
    return find_if<SPObject::SiblingIterator>(
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
42
        layer->getNext(), NULL, &is_layer
1 by mental
moving trunk for module inkscape
43
    );
44
}
45
251 by mental
merged patch #1447043 from Andrius "knutux" R. to create sub-layers
46
/** Finds the previous sibling layer for a \a layer
47
 *
48
 *  @returns NULL if there are no further layers under a parent
49
 */
1 by mental
moving trunk for module inkscape
50
SPObject *previous_sibling_layer(SPObject *layer) {
51
    using Inkscape::Algorithms::find_last_if;
52
53
    SPObject *sibling(find_last_if<SPObject::SiblingIterator>(
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
54
        layer->parent->firstChild(), layer, &is_layer
1 by mental
moving trunk for module inkscape
55
    ));
56
57
    return ( sibling != layer ) ? sibling : NULL;
58
}
59
251 by mental
merged patch #1447043 from Andrius "knutux" R. to create sub-layers
60
/** Finds the first child of a \a layer
61
 *
62
 *  @returns NULL if layer has no sublayers
63
 */
1 by mental
moving trunk for module inkscape
64
SPObject *first_descendant_layer(SPObject *layer) {
65
    using std::find_if;
66
67
    SPObject *first_descendant=NULL;
68
    while (layer) {
69
        layer = find_if<SPObject::SiblingIterator>(
70
            layer->firstChild(), NULL, &is_layer
71
        );
72
        if (layer) {
73
            first_descendant = layer;
74
        }
75
    }
76
77
    return first_descendant;
78
}
79
251 by mental
merged patch #1447043 from Andrius "knutux" R. to create sub-layers
80
/** Finds the last (topmost) child of a \a layer
81
 *
82
 *  @returns NULL if layer has no sublayers
83
 */
1 by mental
moving trunk for module inkscape
84
SPObject *last_child_layer(SPObject *layer) {
85
    using Inkscape::Algorithms::find_last_if;
86
87
    return find_last_if<SPObject::SiblingIterator>(
88
        layer->firstChild(), NULL, &is_layer
89
    );
90
}
91
92
SPObject *last_elder_layer(SPObject *root, SPObject *layer) {
93
    using Inkscape::Algorithms::find_last_if;
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
94
    SPObject *result = 0;
1 by mental
moving trunk for module inkscape
95
96
    while ( layer != root ) {
97
        SPObject *sibling(previous_sibling_layer(layer));
98
        if (sibling) {
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
99
            result = sibling;
100
            break;
1 by mental
moving trunk for module inkscape
101
        }
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
102
        layer = layer->parent;
1 by mental
moving trunk for module inkscape
103
    }
104
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
105
    return result;
1 by mental
moving trunk for module inkscape
106
}
107
108
}
109
110
/** Finds the next layer under \a root, relative to \a layer in
111
 *  depth-first order.
112
 *
113
 *  @returns NULL if there are no further layers under \a root
114
 */
115
SPObject *next_layer(SPObject *root, SPObject *layer) {
116
    using std::find_if;
117
118
    g_return_val_if_fail(layer != NULL, NULL);
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
119
    SPObject *result = 0;
1 by mental
moving trunk for module inkscape
120
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
121
    SPObject *sibling = next_sibling_layer(layer);
1 by mental
moving trunk for module inkscape
122
    if (sibling) {
123
        SPObject *descendant(first_descendant_layer(sibling));
124
        if (descendant) {
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
125
            result = descendant;
126
        } else {
127
            result = sibling;
128
        }
129
    } else if ( layer->parent != root ) {
130
        result = layer->parent;
1 by mental
moving trunk for module inkscape
131
    }
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
132
133
    return result;
1 by mental
moving trunk for module inkscape
134
}
135
136
137
/** Finds the previous layer under \a root, relative to \a layer in
138
 *  depth-first order.
139
 *
140
 *  @returns NULL if there are no prior layers under \a root.
141
 */
142
SPObject *previous_layer(SPObject *root, SPObject *layer) {
143
    using Inkscape::Algorithms::find_last_if;
144
145
    g_return_val_if_fail(layer != NULL, NULL);
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
146
    SPObject *result = 0;
1 by mental
moving trunk for module inkscape
147
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
148
    SPObject *child = last_child_layer(layer);
1 by mental
moving trunk for module inkscape
149
    if (child) {
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
150
        result = child;
1 by mental
moving trunk for module inkscape
151
    } else if ( layer != root ) {
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
152
        SPObject *sibling = previous_sibling_layer(layer);
1 by mental
moving trunk for module inkscape
153
        if (sibling) {
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
154
            result = sibling;
1 by mental
moving trunk for module inkscape
155
        } else {
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
156
            result = last_elder_layer(root, layer->parent);
1 by mental
moving trunk for module inkscape
157
        }
149 by rwst
bulk trailing spaces removal. consistency through MD5 of binary
158
    }
1 by mental
moving trunk for module inkscape
159
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
160
    return result;
1 by mental
moving trunk for module inkscape
161
}
162
251 by mental
merged patch #1447043 from Andrius "knutux" R. to create sub-layers
163
/**
164
*  Creates a new layer.  Advances to the next layer id indicated
165
 *  by the string "layerNN", then creates a new group object of
166
 *  that id with attribute inkscape:groupmode='layer', and finally
167
 *  appends the new group object to \a root after object \a layer.
168
 *
169
 *  \pre \a root should be either \a layer or an ancestor of it
170
 */
171
SPObject *create_layer(SPObject *root, SPObject *layer, LayerRelativePosition position) {
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
172
    SPDocument *document = root->document;
251 by mental
merged patch #1447043 from Andrius "knutux" R. to create sub-layers
173
    
174
    static int layer_suffix=1;
175
    gchar *id=NULL;
176
    do {
177
        g_free(id);
178
        id = g_strdup_printf("layer%d", layer_suffix++);
179
    } while (document->getObjectById(id));
180
    
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
181
    Inkscape::XML::Document *xml_doc = document->getReprDoc();
2254 by acspike
continue switching sp_repr_new* over to XML::Document::create*
182
    Inkscape::XML::Node *repr = xml_doc->createElement("svg:g");
251 by mental
merged patch #1447043 from Andrius "knutux" R. to create sub-layers
183
    repr->setAttribute("inkscape:groupmode", "layer");
184
    repr->setAttribute("id", id);
185
    g_free(id);
186
    
187
    if ( LPOS_CHILD == position ) {
188
        root = layer;
189
        SPObject *child_layer = Inkscape::last_child_layer(layer);
190
        if ( NULL != child_layer ) {
191
            layer = child_layer;
192
        }
193
    }
194
    
195
    if ( root == layer ) {
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
196
        root->getRepr()->appendChild(repr);
251 by mental
merged patch #1447043 from Andrius "knutux" R. to create sub-layers
197
    } else {
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
198
        Inkscape::XML::Node *layer_repr = layer->getRepr();
251 by mental
merged patch #1447043 from Andrius "knutux" R. to create sub-layers
199
        sp_repr_parent(layer_repr)->addChild(repr, layer_repr);
200
        
201
        if ( LPOS_BELOW == position ) {
202
            SP_ITEM(document->getObjectByRepr(repr))->lowerOne();
203
        }
204
    }
205
    
206
    return document->getObjectByRepr(repr);
207
}
208
1 by mental
moving trunk for module inkscape
209
}
210
211
/*
212
  Local Variables:
213
  mode:c++
214
  c-file-style:"stroustrup"
215
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
216
  indent-tabs-mode:nil
217
  fill-column:99
218
  End:
219
*/
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
220
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :