sp-item-group.cpp revision 6b15695578f07a3f72c4c9475c1a261a3021472a
#define __SP_GROUP_C__
/*
* SVG <g> implementation
*
* Authors:
* Lauris Kaplinski <lauris@kaplinski.com>
* bulia byak <buliabyak@users.sf.net>
*
* Copyright (C) 1999-2005 authors
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#endif
#include "display/nr-arena-group.h"
#include "libnr/nr-matrix-ops.h"
#include "libnr/nr-matrix-fns.h"
#include "document.h"
#include "style.h"
#include "attributes.h"
#include "sp-root.h"
#include "sp-use.h"
#include "prefs-utils.h"
static void sp_group_child_added (SPObject * object, Inkscape::XML::Node * child, Inkscape::XML::Node * ref);
static void sp_group_order_changed (SPObject * object, Inkscape::XML::Node * child, Inkscape::XML::Node * old_ref, Inkscape::XML::Node * new_ref);
static Inkscape::XML::Node *sp_group_write (SPObject *object, Inkscape::XML::Node *repr, guint flags);
static void sp_group_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags);
static NRArenaItem *sp_group_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
static SPItemClass * parent_class;
sp_group_get_type (void)
{
static GType group_type = 0;
if (!group_type) {
GTypeInfo group_info = {
sizeof (SPGroupClass),
NULL, /* base_init */
NULL, /* base_finalize */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (SPGroup),
16, /* n_preallocs */
NULL, /* value_table */
};
}
return group_type;
}
static void
{
}
static void
{
}
{
}
}
}
}
}
static void
{
}
static void
{
// optimization for the common special case where the child is being added at the end
if ( SP_IS_ITEM(ochild) ) {
/* TODO: this should be moved into SPItem somehow */
SPItemView *v;
if (ac) {
}
}
}
} else { // general case
/* TODO: this should be moved into SPItem somehow */
SPItemView *v;
if (ac) {
}
}
}
}
}
/* fixme: hide (Lauris) */
static void
{
}
static void
sp_group_order_changed (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *old_ref, Inkscape::XML::Node *new_ref)
{
/* TODO: this should be moved into SPItem somehow */
SPItemView *v;
}
}
}
static void
{
GSList *l;
l = NULL;
l = g_slist_prepend (l, child);
}
l = g_slist_reverse (l);
while (l) {
l = g_slist_remove (l, child);
if (SP_IS_ITEM (child)) {
} else {
}
}
}
}
static void
{
GSList *l;
l = NULL;
l = g_slist_prepend (l, child);
}
l = g_slist_reverse (l);
while (l) {
l = g_slist_remove (l, child);
}
}
}
{
if (flags & SP_OBJECT_WRITE_BUILD) {
GSList *l;
l = NULL;
}
while (l) {
l = g_slist_remove (l, l->data);
}
} else {
}
}
if ( flags & SP_OBJECT_WRITE_EXT ) {
const char *value;
value = "layer";
} else if ( flags & SP_OBJECT_WRITE_ALL ) {
value = "group";
} else {
}
}
return repr;
}
static void
{
if (SP_IS_ITEM(o)) {
}
}
}
static void
{
SPObject * o;
if (SP_IS_ITEM (o)) {
}
}
}
{
SPObject * o;
len = 0;
if (SP_IS_ITEM(o)) {
len += 1;
}
}
return g_strdup_printf(
ngettext("<b>Group</b> of <b>%d</b> object",
"<b>Group</b> of <b>%d</b> objects",
}
switch (key) {
case SP_ATTR_INKSCAPE_GROUPMODE: {
} else {
}
} break;
default: {
}
}
}
}
static NRArenaItem *
{
SPObject * o;
if (SP_IS_ITEM (o)) {
if (ac) {
}
}
}
return ai;
}
static void
{
SPObject * o;
if (SP_IS_ITEM (o)) {
}
}
}
{
o != NULL;
o = SP_OBJECT_NEXT(o))
{
if (SP_IS_ITEM(o)) {
sp_item_snappoints(SP_ITEM(o), p);
}
}
}
void
{
g_return_if_fail (!strcmp (grepr->name(), "svg:g") || !strcmp (grepr->name(), "svg:a") || !strcmp (grepr->name(), "svg:switch"));
/* Step 1 - generate lists of children objects */
for (SPObject *child = sp_object_first_child(SP_OBJECT(group)) ; child != NULL; child = SP_OBJECT_NEXT(child) ) {
if (SP_IS_ITEM (child)) {
/* Merging of style */
// it here _before_ the new transform is set, so as to use the pre-transform bbox
/*
* fixme: We currently make no allowance for the case where child is cloned
* and the group has any style settings.
*
* (This should never occur with documents created solely with the current
* version of inkscape without using the XML editor: we usually apply group
* style changes to children rather than to the group itself.)
*
* If the group has no style settings, then
* sp_style_merge_from_dying_parent should be a no-op. Otherwise (i.e. if
* we change the child's style to compensate for its parent going away)
* then those changes will typically be reflected in any clones of child,
* whereas we'd prefer for Ungroup not to affect the visual appearance.
*
* The only way of preserving styling appearance in general is for child to
* be put into a new group -- a somewhat surprising response to an Ungroup
* command. We could add a new groupmode:transparent that would mostly
* hide the existence of such groups from the user (i.e. editing behaves as
* if the transparent group's children weren't in a group), though that's
* extra complication & maintenance burden and this case is rare.
*/
child->updateRepr();
// Merging transform
// make sure a clone's effective transform is the same as was under group
} else {
}
// FIXME: constructing a transform that would fully preserve the appearance of a
// textpath if it is ungrouped with its path seems to be impossible in general
// case. E.g. if the group was squeezed, to keep the ungrouped textpath squeezed
// as well, we'll need to relink it to some "virtual" path which is inversely
// stretched relative to the actual path, and then squeeze the textpath back so it
// would both fit the actual path _and_ be squeezed as before. It's a bummer.
// This is just a way to temporarily remember the transform in repr. When repr is
// reattached outside of the group, the transform will be written more properly
// (i.e. optimized into the object if the corresponding preference is set)
} else {
}
} else {
}
}
/* Step 2 - clear group */
// remember the position of the group
// the group is leaving forever, no heir, clones should take note; its children however are going to reemerge
/* Step 3 - add nonitems */
if (objects) {
while (objects) {
}
}
/* Step 4 - add items */
while (items) {
// add item
// restore position; since the items list was prepended (i.e. reverse), we now add
// all children at the same pos, which inverts the order once again
// fill in the children list if non-null
/* Optimize the transform matrix if requested. */
// No compensations are required because this is supposed to be a non-transformation visually.
if (!preserve) {
NR::Matrix (*set_transform)(SPItem *, NR::Matrix const &) = ((SPItemClass *) G_OBJECT_GET_CLASS(nitem))->set_transform;
if (set_transform) {
nitem->updateRepr();
}
}
}
}
/*
* some API for list aspect of SPGroup
*/
GSList *
{
GSList *s;
SPObject *o;
s = NULL;
if (SP_IS_ITEM (o)) {
s = g_slist_prepend (s, o);
}
}
return g_slist_reverse (s);
}
SPObject *
{
}
return child;
}
if ( _layer_mode != mode ) {
} else {
}
_layer_mode = mode;
}
}
} else {
return GROUP;
}
}
}
}
if (arena_group) {
}
}
}
}