Example #1
0
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;
  }
}
Example #2
0
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);
}
Example #3
0
/**
 * 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;
}