~centralelyon2010/inkscape/imagelinks2

« back to all changes in this revision

Viewing changes to src/sp-item-group.cpp

  • Committer: JazzyNico
  • Date: 2011-08-29 20:25:30 UTC
  • Revision ID: nicoduf@yahoo.fr-20110829202530-6deuoz11q90usldv
Code refactoring and merging with trunk (revision 10599).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#define __SP_GROUP_C__
2
 
 
3
1
/*
4
2
 * SVG <g> implementation
5
3
 *
7
5
 *   Lauris Kaplinski <lauris@kaplinski.com>
8
6
 *   bulia byak <buliabyak@users.sf.net>
9
7
 *   Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
 
8
 *   Jon A. Cruz <jon@joncruz.org>
 
9
 *   Abhishek Sharma
10
10
 *
11
11
 * Copyright (C) 1999-2006 authors
12
12
 * Copyright (C) 2000-2001 Ximian, Inc.
22
22
#include <cstring>
23
23
#include <string>
24
24
 
25
 
#include "display/nr-arena-group.h"
 
25
#include "display/drawing-group.h"
26
26
#include "display/curve.h"
27
 
#include "libnr/nr-matrix-ops.h"
28
 
#include "libnr/nr-matrix-fns.h"
29
27
#include "xml/repr.h"
30
28
#include "svg/svg.h"
31
29
#include "document.h"
49
47
#include "sp-title.h"
50
48
#include "sp-desc.h"
51
49
#include "sp-switch.h"
 
50
#include "sp-defs.h"
 
51
 
 
52
using Inkscape::DocumentUndo;
52
53
 
53
54
static void sp_group_class_init (SPGroupClass *klass);
54
55
static void sp_group_init (SPGroup *group);
64
65
static Inkscape::XML::Node *sp_group_write (SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
65
66
static void sp_group_set(SPObject *object, unsigned key, char const *value);
66
67
 
67
 
static void sp_group_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags);
 
68
static Geom::OptRect sp_group_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type);
68
69
static void sp_group_print (SPItem * item, SPPrintContext *ctx);
69
70
static gchar * sp_group_description (SPItem * item);
70
 
static NRArenaItem *sp_group_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
 
71
static Inkscape::DrawingItem *sp_group_show (SPItem *item, Inkscape::Drawing &drawing, unsigned int key, unsigned int flags);
71
72
static void sp_group_hide (SPItem * item, unsigned int key);
72
73
static void sp_group_snappoints (SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
73
74
 
145
146
 
146
147
static void sp_group_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
147
148
{
148
 
    sp_object_read_attr(object, "inkscape:groupmode");
 
149
    object->readAttr( "inkscape:groupmode" );
149
150
 
150
151
    if (((SPObjectClass *)parent_class)->build) {
151
152
        ((SPObjectClass *)parent_class)->build(object, document, repr);
154
155
 
155
156
static void sp_group_release(SPObject *object) {
156
157
    if ( SP_GROUP(object)->_layer_mode == SPGroup::LAYER ) {
157
 
        sp_document_remove_resource(SP_OBJECT_DOCUMENT(object), "layer", object);
 
158
        object->document->removeResource("layer", object);
158
159
    }
159
160
    if (((SPObjectClass *)parent_class)->release) {
160
161
        ((SPObjectClass *)parent_class)->release(object);
168
169
    delete SP_GROUP(object)->group;
169
170
}
170
171
 
171
 
static void
172
 
sp_group_child_added (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref)
 
172
static void sp_group_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref)
173
173
{
174
 
    SPItem *item;
175
 
 
176
 
    item = SP_ITEM (object);
177
 
 
178
 
    if (((SPObjectClass *) (parent_class))->child_added)
 
174
    SPGroup *group = SP_GROUP(object);
 
175
 
 
176
    if (((SPObjectClass *) (parent_class))->child_added) {
179
177
        (* ((SPObjectClass *) (parent_class))->child_added) (object, child, ref);
 
178
    }
180
179
 
181
 
    SP_GROUP(object)->group->onChildAdded(child);
 
180
    group->group->onChildAdded(child);
182
181
}
183
182
 
184
183
/* fixme: hide (Lauris) */
219
218
    SP_GROUP(object)->group->onModified(flags);
220
219
}
221
220
 
222
 
static Inkscape::XML::Node *
223
 
sp_group_write (SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
 
221
static Inkscape::XML::Node * sp_group_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
224
222
{
225
 
    SPGroup *group;
226
 
    SPObject *child;
227
 
    Inkscape::XML::Node *crepr;
228
 
 
229
 
    group = SP_GROUP (object);
 
223
    SPGroup *group = SP_GROUP(object);
230
224
 
231
225
    if (flags & SP_OBJECT_WRITE_BUILD) {
232
226
        GSList *l;
233
227
        if (!repr) {
234
 
            if (SP_IS_SWITCH(object))
 
228
            if (SP_IS_SWITCH(object)) {
235
229
                repr = xml_doc->createElement("svg:switch");
236
 
            else
 
230
            } else {
237
231
                repr = xml_doc->createElement("svg:g");
 
232
            }
238
233
        }
239
234
        l = NULL;
240
 
        for (child = sp_object_first_child(object); child != NULL; child = SP_OBJECT_NEXT(child) ) {
241
 
            if (SP_IS_TITLE(child) || SP_IS_DESC(child)) continue;
242
 
            crepr = child->updateRepr(xml_doc, NULL, flags);
243
 
            if (crepr) l = g_slist_prepend (l, crepr);
 
235
        for (SPObject *child = object->firstChild(); child; child = child->getNext() ) {
 
236
            if ( !SP_IS_TITLE(child) && !SP_IS_DESC(child) ) {
 
237
                Inkscape::XML::Node *crepr = child->updateRepr(xml_doc, NULL, flags);
 
238
                if (crepr) {
 
239
                    l = g_slist_prepend (l, crepr);
 
240
                }
 
241
            }
244
242
        }
245
243
        while (l) {
246
244
            repr->addChild((Inkscape::XML::Node *) l->data, NULL);
248
246
            l = g_slist_remove (l, l->data);
249
247
        }
250
248
    } else {
251
 
        for (child = sp_object_first_child(object) ; child != NULL; child = SP_OBJECT_NEXT(child) ) {
252
 
            if (SP_IS_TITLE(child) || SP_IS_DESC(child)) continue;
253
 
            child->updateRepr(flags);
 
249
        for (SPObject *child = object->firstChild() ; child ; child = child->getNext() ) {
 
250
            if ( !SP_IS_TITLE(child) && !SP_IS_DESC(child) ) {
 
251
                child->updateRepr(flags);
 
252
            }
254
253
        }
255
254
    }
256
255
 
268
267
        repr->setAttribute("inkscape:groupmode", value);
269
268
    }
270
269
 
271
 
    if (((SPObjectClass *) (parent_class))->write)
 
270
    if (((SPObjectClass *) (parent_class))->write) {
272
271
        ((SPObjectClass *) (parent_class))->write (object, xml_doc, repr, flags);
 
272
    }
273
273
 
274
274
    return repr;
275
275
}
276
276
 
277
 
static void
278
 
sp_group_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags)
 
277
static Geom::OptRect
 
278
sp_group_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type)
279
279
{
280
 
    SP_GROUP(item)->group->calculateBBox(bbox, transform, flags);
 
280
    return SP_GROUP(item)->group->bounds(type, transform);
281
281
}
282
282
 
283
283
static void
312
312
    }
313
313
}
314
314
 
315
 
static NRArenaItem *
316
 
sp_group_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags)
 
315
static Inkscape::DrawingItem *
 
316
sp_group_show (SPItem *item, Inkscape::Drawing &drawing, unsigned int key, unsigned int flags)
317
317
{
318
 
    return SP_GROUP(item)->group->show(arena, key, flags);
 
318
    return SP_GROUP(item)->group->show(drawing, key, flags);
319
319
}
320
320
 
321
321
static void
324
324
    SP_GROUP(item)->group->hide(key);
325
325
}
326
326
 
327
 
static void sp_group_snappoints (SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs)
 
327
static void sp_group_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs)
328
328
{
329
 
    for (SPObject const *o = sp_object_first_child(SP_OBJECT(item));
330
 
         o != NULL;
331
 
         o = SP_OBJECT_NEXT(o))
 
329
    for ( SPObject const *o = item->firstChild(); o; o = o->getNext() )
332
330
    {
333
331
        if (SP_IS_ITEM(o)) {
334
 
            sp_item_snappoints(SP_ITEM(o), p, snapprefs);
 
332
            SP_ITEM(o)->getSnappoints(p, snapprefs);
335
333
        }
336
334
    }
337
335
}
343
341
    g_return_if_fail (group != NULL);
344
342
    g_return_if_fail (SP_IS_GROUP (group));
345
343
 
346
 
    SPDocument *doc = SP_OBJECT_DOCUMENT (group);
347
 
    SPObject *root = SP_DOCUMENT_ROOT (doc);
348
 
    SPObject *defs = SP_OBJECT (SP_ROOT (root)->defs);
 
344
    SPDocument *doc = group->document;
 
345
    SPRoot *root = doc->getRoot();
 
346
    SPObject *defs = root->defs;
349
347
 
350
 
    SPItem *gitem = SP_ITEM (group);
351
 
    Inkscape::XML::Node *grepr = SP_OBJECT_REPR (gitem);
 
348
    SPItem *gitem = group;
 
349
    Inkscape::XML::Node *grepr = gitem->getRepr();
352
350
 
353
351
    g_return_if_fail (!strcmp (grepr->name(), "svg:g") || !strcmp (grepr->name(), "svg:a") || !strcmp (grepr->name(), "svg:switch"));
354
352
 
355
353
    // this converts the gradient/pattern fill/stroke on the group, if any, to userSpaceOnUse
356
 
    sp_item_adjust_paint_recursive (gitem, Geom::identity(), Geom::identity(), false);
 
354
    gitem->adjust_paint_recursive (Geom::identity(), Geom::identity(), false);
357
355
 
358
 
    SPItem *pitem = SP_ITEM (SP_OBJECT_PARENT (gitem));
359
 
    Inkscape::XML::Node *prepr = SP_OBJECT_REPR (pitem);
 
356
    SPItem *pitem = SP_ITEM(gitem->parent);
 
357
    Inkscape::XML::Node *prepr = pitem->getRepr();
360
358
 
361
359
        if (SP_IS_BOX3D(gitem)) {
362
360
                group = box3d_convert_to_group(SP_BOX3D(gitem));
363
 
                gitem = SP_ITEM(group);
 
361
                gitem = group;
364
362
        }
365
363
 
366
364
        sp_lpe_item_remove_all_path_effects(SP_LPE_ITEM(group), false);
368
366
    /* Step 1 - generate lists of children objects */
369
367
    GSList *items = NULL;
370
368
    GSList *objects = NULL;
371
 
    for (SPObject *child = sp_object_first_child(SP_OBJECT(group)) ; child != NULL; child = SP_OBJECT_NEXT(child) ) {
 
369
    for (SPObject *child = group->firstChild() ; child; child = child->getNext() ) {
372
370
 
373
371
        if (SP_IS_ITEM (child)) {
374
372
 
377
375
            /* Merging of style */
378
376
            // this converts the gradient/pattern fill/stroke, if any, to userSpaceOnUse; we need to do
379
377
            // it here _before_ the new transform is set, so as to use the pre-transform bbox
380
 
            sp_item_adjust_paint_recursive (citem, Geom::identity(), Geom::identity(), false);
 
378
            citem->adjust_paint_recursive (Geom::identity(), Geom::identity(), false);
381
379
 
382
 
            sp_style_merge_from_dying_parent(SP_OBJECT_STYLE(child), SP_OBJECT_STYLE(gitem));
 
380
            sp_style_merge_from_dying_parent(child->style, gitem->style);
383
381
            /*
384
382
             * fixme: We currently make no allowance for the case where child is cloned
385
383
             * and the group has any style settings.
404
402
 
405
403
            child->updateRepr();
406
404
 
407
 
            Inkscape::XML::Node *nrepr = SP_OBJECT_REPR (child)->duplicate(prepr->document());
 
405
            Inkscape::XML::Node *nrepr = child->getRepr()->duplicate(prepr->document());
408
406
 
409
407
            // Merging transform
410
 
            Geom::Matrix ctrans;
411
 
            Geom::Matrix const g(gitem->transform);
 
408
            Geom::Affine ctrans;
 
409
            Geom::Affine const g(gitem->transform);
412
410
            if (SP_IS_USE(citem) && sp_use_get_original (SP_USE(citem)) &&
413
 
                    SP_OBJECT_PARENT (sp_use_get_original (SP_USE(citem))) == SP_OBJECT(group)) {
 
411
                sp_use_get_original( SP_USE(citem) )->parent == SP_OBJECT(group)) {
414
412
                // make sure a clone's effective transform is the same as was under group
415
413
                ctrans = g.inverse() * citem->transform * g;
416
414
            } else {
417
 
                // We should not apply the group's transformation to both a linked offset AND to its source
418
 
                if (SP_IS_OFFSET(citem)) { // Do we have an offset at hand (whether it's dynamic or linked)?
419
 
                        SPItem *source = sp_offset_get_source(SP_OFFSET(citem));
420
 
                        // When dealing with a chain of linked offsets, the transformation of an offset will be
421
 
                        // tied to the transformation of the top-most source, not to any of the intermediate
422
 
                        // offsets. So let's find the top-most source
423
 
                        while (source != NULL && SP_IS_OFFSET(source)) {
424
 
                                source = sp_offset_get_source(SP_OFFSET(source));
425
 
                        }
426
 
                        if (source != NULL && // If true then we must be dealing with a linked offset ...
427
 
                                        SP_OBJECT(group)->isAncestorOf(SP_OBJECT(source)) == false) { // ... of which the source is not in the same group
428
 
                                ctrans = citem->transform * g; // then we should apply the transformation of the group to the offset
429
 
                        } else {
430
 
                                ctrans = citem->transform;
431
 
                        }
 
415
                // We should not apply the group's transformation to both a linked offset AND to its source
 
416
                if (SP_IS_OFFSET(citem)) { // Do we have an offset at hand (whether it's dynamic or linked)?
 
417
                    SPItem *source = sp_offset_get_source(SP_OFFSET(citem));
 
418
                    // When dealing with a chain of linked offsets, the transformation of an offset will be
 
419
                    // tied to the transformation of the top-most source, not to any of the intermediate
 
420
                    // offsets. So let's find the top-most source
 
421
                    while (source != NULL && SP_IS_OFFSET(source)) {
 
422
                        source = sp_offset_get_source(SP_OFFSET(source));
 
423
                    }
 
424
                    if (source != NULL && // If true then we must be dealing with a linked offset ...
 
425
                        group->isAncestorOf(source) == false) { // ... of which the source is not in the same group
 
426
                        ctrans = citem->transform * g; // then we should apply the transformation of the group to the offset
 
427
                    } else {
 
428
                        ctrans = citem->transform;
 
429
                    }
432
430
                } else {
433
 
                        ctrans = citem->transform * g;
 
431
                    ctrans = citem->transform * g;
434
432
                }
435
433
            }
436
434
 
451
449
            items = g_slist_prepend (items, nrepr);
452
450
 
453
451
        } else {
454
 
            Inkscape::XML::Node *nrepr = SP_OBJECT_REPR (child)->duplicate(prepr->document());
 
452
            Inkscape::XML::Node *nrepr = child->getRepr()->duplicate(prepr->document());
455
453
            objects = g_slist_prepend (objects, nrepr);
456
454
        }
457
455
    }
458
456
 
459
457
    /* Step 2 - clear group */
460
458
    // remember the position of the group
461
 
    gint pos = SP_OBJECT_REPR(group)->position();
 
459
    gint pos = group->getRepr()->position();
462
460
 
463
461
    // the group is leaving forever, no heir, clones should take note; its children however are going to reemerge
464
 
    SP_OBJECT (group)->deleteObject(true, false);
 
462
    group->deleteObject(true, false);
465
463
 
466
464
    /* Step 3 - add nonitems */
467
465
    if (objects) {
468
 
        Inkscape::XML::Node *last_def = SP_OBJECT_REPR(defs)->lastChild();
 
466
        Inkscape::XML::Node *last_def = defs->getRepr()->lastChild();
469
467
        while (objects) {
470
 
                        Inkscape::XML::Node *repr = (Inkscape::XML::Node *) objects->data;
471
 
                        if (!sp_repr_is_meta_element(repr))
472
 
                                SP_OBJECT_REPR(defs)->addChild(repr, last_def);
473
 
                        Inkscape::GC::release(repr);
474
 
                        objects = g_slist_remove (objects, objects->data);
 
468
            Inkscape::XML::Node *repr = (Inkscape::XML::Node *) objects->data;
 
469
            if (!sp_repr_is_meta_element(repr)) {
 
470
                defs->getRepr()->addChild(repr, last_def);
 
471
            }
 
472
            Inkscape::GC::release(repr);
 
473
            objects = g_slist_remove (objects, objects->data);
475
474
        }
476
475
    }
477
476
 
487
486
        // fill in the children list if non-null
488
487
        SPItem *item = (SPItem *) doc->getObjectByRepr(repr);
489
488
 
490
 
        sp_item_write_transform(item, repr, item->transform, NULL, false);
 
489
        item->doWriteTransform(repr, item->transform, NULL, false);
491
490
 
492
491
        Inkscape::GC::release(repr);
493
492
        if (children && SP_IS_ITEM (item))
496
495
        items = g_slist_remove (items, items->data);
497
496
    }
498
497
 
499
 
    if (do_done)
500
 
        sp_document_done (doc, SP_VERB_NONE, _("Ungroup"));
 
498
    if (do_done) {
 
499
        DocumentUndo::done(doc, SP_VERB_NONE, _("Ungroup"));
 
500
    }
501
501
}
502
502
 
503
503
/*
504
504
 * some API for list aspect of SPGroup
505
505
 */
506
506
 
507
 
GSList *
508
 
sp_item_group_item_list (SPGroup * group)
 
507
GSList *sp_item_group_item_list(SPGroup * group)
509
508
{
510
 
    g_return_val_if_fail (group != NULL, NULL);
511
 
    g_return_val_if_fail (SP_IS_GROUP (group), NULL);
 
509
    g_return_val_if_fail(group != NULL, NULL);
 
510
    g_return_val_if_fail(SP_IS_GROUP(group), NULL);
512
511
 
513
512
    GSList *s = NULL;
514
513
 
515
 
    for (SPObject *o = sp_object_first_child(SP_OBJECT(group)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) {
516
 
        if (SP_IS_ITEM (o)) {
517
 
            s = g_slist_prepend (s, o);
 
514
    for (SPObject *o = group->firstChild() ; o ; o = o->getNext() ) {
 
515
        if ( SP_IS_ITEM(o) ) {
 
516
            s = g_slist_prepend(s, o);
518
517
        }
519
518
    }
520
519
 
521
520
    return g_slist_reverse (s);
522
521
}
523
522
 
524
 
SPObject *
525
 
sp_item_group_get_child_by_name (SPGroup *group, SPObject *ref, const gchar *name)
 
523
SPObject *sp_item_group_get_child_by_name(SPGroup *group, SPObject *ref, const gchar *name)
526
524
{
527
 
    SPObject *child;
528
 
    child = (ref) ? SP_OBJECT_NEXT(ref) : sp_object_first_child(SP_OBJECT(group));
529
 
    while ( child && strcmp (SP_OBJECT_REPR(child)->name(), name) ) {
530
 
        child = SP_OBJECT_NEXT(child);
 
525
    SPObject *child = (ref) ? ref->getNext() : group->firstChild();
 
526
    while ( child && strcmp(child->getRepr()->name(), name) ) {
 
527
        child = child->getNext();
531
528
    }
532
529
    return child;
533
530
}
535
532
void SPGroup::setLayerMode(LayerMode mode) {
536
533
    if ( _layer_mode != mode ) {
537
534
        if ( mode == LAYER ) {
538
 
            sp_document_add_resource(SP_OBJECT_DOCUMENT(this), "layer", this);
 
535
            this->document->addResource("layer", this);
539
536
        } else if ( _layer_mode == LAYER ) {
540
 
            sp_document_remove_resource(SP_OBJECT_DOCUMENT(this), "layer", this);
 
537
            this->document->removeResource("layer", this);
541
538
        }
542
539
        _layer_mode = mode;
543
540
        _updateLayerMode();
565
562
    SPItemView *view;
566
563
    for ( view = this->display ; view ; view = view->next ) {
567
564
        if ( !display_key || view->key == display_key ) {
568
 
            NRArenaGroup *arena_group=NR_ARENA_GROUP(view->arenaitem);
569
 
            if (arena_group) {
570
 
                nr_arena_group_set_transparent(arena_group, effectiveLayerMode(view->key) == SPGroup::LAYER);
 
565
            Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(view->arenaitem);
 
566
            if (g) {
 
567
                g->setPickChildren(effectiveLayerMode(view->key) == SPGroup::LAYER);
571
568
            }
572
569
        }
573
570
    }
575
572
 
576
573
void SPGroup::translateChildItems(Geom::Translate const &tr)
577
574
{
578
 
    if (this->hasChildren())
579
 
    {
580
 
        SPObject *o = NULL;
581
 
        for (o = sp_object_first_child(SP_OBJECT(this)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) {
582
 
            if (SP_IS_ITEM (o)) {
583
 
                sp_item_move_rel(static_cast<SPItem *>(o), tr);
 
575
    if ( hasChildren() ) {
 
576
        for (SPObject *o = firstChild() ; o ; o = o->getNext() ) {
 
577
            if ( SP_IS_ITEM(o) ) {
 
578
                sp_item_move_rel(reinterpret_cast<SPItem *>(o), tr);
584
579
            }
585
580
        }
586
581
    }
595
590
 
596
591
void CGroup::onChildAdded(Inkscape::XML::Node *child) {
597
592
    SPObject *last_child = _group->lastChild();
598
 
    if (last_child && SP_OBJECT_REPR(last_child) == child) {
 
593
    if (last_child && last_child->getRepr() == child) {
599
594
        // optimization for the common special case where the child is being added at the end
600
595
        SPObject *ochild = last_child;
601
596
        if ( SP_IS_ITEM(ochild) ) {
602
597
            /* TODO: this should be moved into SPItem somehow */
603
598
            SPItemView *v;
604
 
            NRArenaItem *ac;
 
599
            Inkscape::DrawingItem *ac;
605
600
 
606
601
            for (v = _group->display; v != NULL; v = v->next) {
607
 
                ac = sp_item_invoke_show (SP_ITEM (ochild), NR_ARENA_ITEM_ARENA (v->arenaitem), v->key, v->flags);
 
602
                ac = SP_ITEM (ochild)->invoke_show (v->arenaitem->drawing(), v->key, v->flags);
608
603
 
609
604
                if (ac) {
610
 
                    nr_arena_item_append_child (v->arenaitem, ac);
 
605
                    v->arenaitem->appendChild(ac);
611
606
                }
612
607
            }
613
608
        }
614
609
    } else {    // general case
615
 
        SPObject *ochild = sp_object_get_child_by_repr(_group, child);
 
610
        SPObject *ochild = _group->get_child_by_repr(child);
616
611
        if ( ochild && SP_IS_ITEM(ochild) ) {
617
612
            /* TODO: this should be moved into SPItem somehow */
618
613
            SPItemView *v;
619
 
            NRArenaItem *ac;
 
614
            Inkscape::DrawingItem *ac;
620
615
 
621
 
            unsigned position = sp_item_pos_in_parent(SP_ITEM(ochild));
 
616
            unsigned position = SP_ITEM(ochild)->pos_in_parent();
622
617
 
623
618
            for (v = _group->display; v != NULL; v = v->next) {
624
 
                ac = sp_item_invoke_show (SP_ITEM (ochild), NR_ARENA_ITEM_ARENA (v->arenaitem), v->key, v->flags);
 
619
                ac = SP_ITEM (ochild)->invoke_show (v->arenaitem->drawing(), v->key, v->flags);
625
620
 
626
621
                if (ac) {
627
 
                    nr_arena_item_add_child (v->arenaitem, ac, NULL);
628
 
                    nr_arena_item_set_order (ac, position);
 
622
                    v->arenaitem->prependChild(ac);
 
623
                    ac->setZOrder(position);
629
624
                }
630
625
            }
631
626
        }
651
646
    flags &= SP_OBJECT_MODIFIED_CASCADE;
652
647
 
653
648
    if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) {
654
 
      SPObject *object = SP_OBJECT(_group);
655
 
      for (SPItemView *v = SP_ITEM(_group)->display; v != NULL; v = v->next) {
656
 
    nr_arena_group_set_style(NR_ARENA_GROUP(v->arenaitem), SP_OBJECT_STYLE(object));
657
 
      }
 
649
        SPObject *object = _group;
 
650
        for (SPItemView *v = _group->display; v != NULL; v = v->next) {
 
651
            Inkscape::DrawingGroup *group = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem);
 
652
            group->setStyle(object->style);
 
653
        }
658
654
    }
659
655
 
660
656
    GSList *l = g_slist_reverse(_group->childList(true, SPObject::ActionUpdate));
682
678
    flags &= SP_OBJECT_MODIFIED_CASCADE;
683
679
 
684
680
    if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) {
685
 
      SPObject *object = SP_OBJECT(_group);
686
 
      for (SPItemView *v = SP_ITEM(_group)->display; v != NULL; v = v->next) {
687
 
    nr_arena_group_set_style(NR_ARENA_GROUP(v->arenaitem), SP_OBJECT_STYLE(object));
688
 
      }
 
681
        SPObject *object = _group;
 
682
        for (SPItemView *v = _group->display; v != NULL; v = v->next) {
 
683
            Inkscape::DrawingGroup *group = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem);
 
684
            group->setStyle(object->style);
 
685
        }
689
686
    }
690
687
 
691
688
    GSList *l = g_slist_reverse(_group->childList(true));
699
696
    }
700
697
}
701
698
 
702
 
void CGroup::calculateBBox(NRRect *bbox, Geom::Matrix const &transform, unsigned const flags) {
703
 
 
704
 
    Geom::OptRect dummy_bbox;
 
699
Geom::OptRect CGroup::bounds(SPItem::BBoxType type, Geom::Affine const &transform)
 
700
{
 
701
    Geom::OptRect bbox;
705
702
 
706
703
    GSList *l = _group->childList(false, SPObject::ActionBBox);
707
704
    while (l) {
708
705
        SPObject *o = SP_OBJECT (l->data);
709
706
        if (SP_IS_ITEM(o) && !SP_ITEM(o)->isHidden()) {
710
707
            SPItem *child = SP_ITEM(o);
711
 
            Geom::Matrix const ct(to_2geom(child->transform) * transform);
712
 
            sp_item_invoke_bbox_full(child, dummy_bbox, ct, flags, FALSE);
 
708
            Geom::Affine const ct(child->transform * transform);
 
709
            bbox |= child->bounds(type, ct);
713
710
        }
714
711
        l = g_slist_remove (l, o);
715
712
    }
716
 
 
717
 
    *bbox = NRRect(dummy_bbox);
 
713
    return bbox;
718
714
}
719
715
 
720
716
void CGroup::onPrint(SPPrintContext *ctx) {
722
718
    while (l) {
723
719
        SPObject *o = SP_OBJECT (l->data);
724
720
        if (SP_IS_ITEM(o)) {
725
 
            sp_item_invoke_print (SP_ITEM (o), ctx);
 
721
            SP_ITEM(o)->invoke_print (ctx);
726
722
        }
727
723
        l = g_slist_remove (l, o);
728
724
    }
730
726
 
731
727
gint CGroup::getItemCount() {
732
728
    gint len = 0;
733
 
    for (SPObject *o = sp_object_first_child(SP_OBJECT(_group)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) {
 
729
    for (SPObject *o = _group->firstChild() ; o ; o = o->getNext() ) {
734
730
        if (SP_IS_ITEM(o)) {
735
731
            len++;
736
732
        }
747
743
                 len), len);
748
744
}
749
745
 
750
 
NRArenaItem *CGroup::show (NRArena *arena, unsigned int key, unsigned int flags) {
751
 
    NRArenaItem *ai;
752
 
    SPObject *object = SP_OBJECT(_group);
753
 
 
754
 
    ai = NRArenaGroup::create(arena);
755
 
 
756
 
    nr_arena_group_set_transparent(NR_ARENA_GROUP (ai),
757
 
                                   _group->effectiveLayerMode(key) ==
758
 
                         SPGroup::LAYER);
759
 
    nr_arena_group_set_style(NR_ARENA_GROUP(ai), SP_OBJECT_STYLE(object));
760
 
 
761
 
    _showChildren(arena, ai, key, flags);
 
746
Inkscape::DrawingItem *CGroup::show (Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) {
 
747
    Inkscape::DrawingGroup *ai;
 
748
    SPObject *object = _group;
 
749
 
 
750
    ai = new Inkscape::DrawingGroup(drawing);
 
751
    ai->setPickChildren(_group->effectiveLayerMode(key) == SPGroup::LAYER);
 
752
    ai->setStyle(object->style);
 
753
 
 
754
    _showChildren(drawing, ai, key, flags);
762
755
    return ai;
763
756
}
764
757
 
765
 
void CGroup::_showChildren (NRArena *arena, NRArenaItem *ai, unsigned int key, unsigned int flags) {
766
 
    NRArenaItem *ac = NULL;
767
 
    NRArenaItem *ar = NULL;
 
758
void CGroup::_showChildren (Inkscape::Drawing &drawing, Inkscape::DrawingItem *ai, unsigned int key, unsigned int flags) {
 
759
    Inkscape::DrawingItem *ac = NULL;
768
760
    SPItem * child = NULL;
769
761
    GSList *l = g_slist_reverse(_group->childList(false, SPObject::ActionShow));
770
762
    while (l) {
771
763
        SPObject *o = SP_OBJECT (l->data);
772
764
        if (SP_IS_ITEM (o)) {
773
765
            child = SP_ITEM (o);
774
 
            ac = sp_item_invoke_show (child, arena, key, flags);
775
 
            if (ac) {
776
 
                nr_arena_item_add_child (ai, ac, ar);
777
 
                ar = ac;
778
 
            }
 
766
            ac = child->invoke_show (drawing, key, flags);
 
767
            ai->appendChild(ac);
779
768
        }
780
769
        l = g_slist_remove (l, o);
781
770
    }
789
778
        SPObject *o = SP_OBJECT (l->data);
790
779
        if (SP_IS_ITEM (o)) {
791
780
            child = SP_ITEM (o);
792
 
            sp_item_invoke_hide (child, key);
 
781
            child->invoke_hide (key);
793
782
        }
794
783
        l = g_slist_remove (l, o);
795
784
    }
800
789
 
801
790
void CGroup::onOrderChanged (Inkscape::XML::Node *child, Inkscape::XML::Node *, Inkscape::XML::Node *)
802
791
{
803
 
    SPObject *ochild = sp_object_get_child_by_repr(_group, child);
 
792
    SPObject *ochild = _group->get_child_by_repr(child);
804
793
    if ( ochild && SP_IS_ITEM(ochild) ) {
805
794
        /* TODO: this should be moved into SPItem somehow */
806
795
        SPItemView *v;
807
 
        unsigned position = sp_item_pos_in_parent(SP_ITEM(ochild));
 
796
        unsigned position = SP_ITEM(ochild)->pos_in_parent();
808
797
        for ( v = SP_ITEM (ochild)->display ; v != NULL ; v = v->next ) {
809
 
            nr_arena_item_set_order (v->arenaitem, position);
 
798
            v->arenaitem->setZOrder(position);
810
799
        }
811
800
    }
812
801
 
858
847
            if (SP_IS_PATH(subitem)) {
859
848
                c = sp_path_get_original_curve(SP_PATH(subitem));
860
849
            } else {
861
 
                c = sp_shape_get_curve(SP_SHAPE(subitem));
 
850
                c = SP_SHAPE(subitem)->getCurve();
862
851
            }
863
852
            // only run LPEs when the shape has a curve defined
864
853
            if (c) {
865
854
                sp_lpe_item_perform_path_effect(SP_LPE_ITEM(topgroup), c);
866
 
                sp_shape_set_curve(SP_SHAPE(subitem), c, TRUE);
 
855
                SP_SHAPE(subitem)->setCurve(c, TRUE);
867
856
 
868
857
                if (write) {
869
 
                    Inkscape::XML::Node *repr = SP_OBJECT_REPR(subitem);
 
858
                    Inkscape::XML::Node *repr = subitem->getRepr();
870
859
                    gchar *str = sp_svg_write_path(c->get_pathvector());
871
860
                    repr->setAttribute("d", str);
872
861
#ifdef GROUP_VERBOSE