static void ungroup_objects_free(struct UngroupObjectsChange *change) { DEBUG_PRINTF(("ungroup_objects_free()\n")); if (change->applied) { group_destroy_shallow(change->group); change->group = NULL; change->obj_list = NULL; } }
static void group_objects_free(struct GroupObjectsChange *change) { DEBUG_PRINTF(("group_objects_free()\n")); if (!change->applied) { group_destroy_shallow(change->group); change->group = NULL; change->obj_list = NULL; /** Leak here? */ } g_list_free(change->orig_list); }
/** * Recursive function to read objects from a specific level in the xml. * * Nowadays there are quite a few of them : * - Layers : a diagram may have different layers, but this function does *not* * add the created objects to them as it does not know on which nesting level it * is called. So the topmost caller must add the returned objects to the layer. * - Groups : groups in itself can have an arbitrary nesting level including other * groups or objects or both of them. A group not containing any objects is by * definition useless. So it is not created. This is to avoid trouble with some older * diagrams which happen to be saved with empty groups. * - Parents : if the parent relations would have been there from the beginning of * Dias file format they probably would have been added as nesting level * themselves. But to maintain forward compatibility (allow to let older versions * of Dia to see as much as possible) they were added all on the same level and * the parent child relation is reconstructed from additional attributes. */ static GList * read_objects(xmlNodePtr objects, GHashTable *objects_hash,const char *filename, DiaObject *parent, GHashTable *unknown_objects_hash) { GList *list; DiaObjectType *type; DiaObject *obj; ObjectNode obj_node; char *typestr; char *versionstr; char *id; int version; xmlNodePtr child_node; list = NULL; obj_node = objects->xmlChildrenNode; while ( obj_node != NULL) { if (xmlIsBlankNode(obj_node)) { obj_node = obj_node->next; continue; } if (!obj_node) break; if (xmlStrcmp(obj_node->name, (const xmlChar *)"object")==0) { typestr = (char *) xmlGetProp(obj_node, (const xmlChar *)"type"); versionstr = (char *) xmlGetProp(obj_node, (const xmlChar *)"version"); id = (char *) xmlGetProp(obj_node, (const xmlChar *)"id"); version = 0; if (versionstr != NULL) { version = atoi(versionstr); xmlFree(versionstr); } type = object_get_type((char *)typestr); if (!type) { if (g_utf8_validate (typestr, -1, NULL) && NULL == g_hash_table_lookup(unknown_objects_hash, typestr)) g_hash_table_insert(unknown_objects_hash, g_strdup(typestr), 0); } else { obj = type->ops->load(obj_node, version, filename); list = g_list_append(list, obj); if (parent) { obj->parent = parent; parent->children = g_list_append(parent->children, obj); } g_hash_table_insert(objects_hash, g_strdup((char *)id), obj); child_node = obj_node->children; while(child_node) { if (xmlStrcmp(child_node->name, (const xmlChar *)"children") == 0) { GList *children_read = read_objects(child_node, objects_hash, filename, obj, unknown_objects_hash); list = g_list_concat(list, children_read); break; } child_node = child_node->next; } } if (typestr) xmlFree(typestr); if (id) xmlFree (id); } else if (xmlStrcmp(obj_node->name, (const xmlChar *)"group")==0 && obj_node->children) { /* don't create empty groups */ obj = group_create(read_objects(obj_node, objects_hash, filename, NULL, unknown_objects_hash)); #ifdef USE_NEWGROUP /* Old group objects had objects recursively inside them. Since * objects are now done with parenting, we need to extract those objects, * make a newgroup object, set parent-child relationships, and add * all of them to the diagram. */ { DiaObject *newgroup; GList *objects; Point lower_right; type = object_get_type("Misc - NewGroup"); lower_right = obj->position; newgroup = type->ops->create(&lower_right, NULL, NULL, NULL); list = g_list_append(list, newgroup); for (objects = group_objects(obj); objects != NULL; objects = g_list_next(objects)) { DiaObject *subobj = (DiaObject *) objects->data; list = g_list_append(list, subobj); subobj->parent = newgroup; newgroup->children = g_list_append(newgroup->children, subobj); if (subobj->bounding_box.right > lower_right.x) { lower_right.x = subobj->bounding_box.right; } if (subobj->bounding_box.bottom > lower_right.y) { lower_right.y = subobj->bounding_box.bottom; } } newgroup->ops->move_handle(newgroup, newgroup->handles[7], &lower_right, NULL, HANDLE_MOVE_CREATE_FINAL, 0); /* We've used the info from the old group, destroy it */ group_destroy_shallow(obj); } #else list = g_list_append(list, obj); #endif } else { /* silently ignore other nodes */ } obj_node = obj_node->next; } return list; }