/*!
 * \brief Parse _DiaObject from the given node
 * Fill a GList* with objects which is to be put in a
 * diagram or a group by the caller. 
 * Can be called recursively to allow groups in groups.
 * This is only using the render branch of the file, if the
 * object type is not registered with Dia. Otherwise the objects
 * are just created from their type and properties.
 * \ingroup DiaRenderScriptImport
 */
static GList*
read_items (xmlNodePtr startnode, DiaContext *ctx)
{
  xmlNodePtr node;
  GList *items = NULL;

  for (node = startnode; node != NULL; node = node->next) {
    if (xmlIsBlankNode(node)) 
      continue;
    if (node->type != XML_ELEMENT_NODE)
      continue;
    if (!xmlStrcmp(node->name, (const xmlChar *)"object")) {
      xmlChar *sType = xmlGetProp(node, (const xmlChar *)"type");
      const DiaObjectType *ot = object_get_type ((gchar *)sType);
      xmlNodePtr props = NULL, render = NULL;
      
      props = find_child_named (node, "properties");
      render = find_child_named (node, "render");

      if (ot && !ot->ops) {
	GList *moreitems;
        /* FIXME: 'render' is also the grouping element */
	moreitems = read_items (render->children, ctx);
	if (moreitems) {
	  DiaObject *group = group_create (moreitems);
	    /* apply group props, e.g. transform */
	  object_load_props (group, props, ctx);
	    /* group eats list */
	  items = g_list_append (items, group);
	}
      } else if (ot) {
        Point startpoint = {0.0,0.0};
        Handle *handle1,*handle2;
	DiaObject *o;

	o = ot->ops->create(&startpoint, 
                            ot->default_user_data, 
			    &handle1,&handle2);
	if (o) {
	  object_load_props (o, props, ctx);
	  items = g_list_append (items, o);
	}
      } else if (render) {
        DiaObject *o = _render_object (render, ctx);
	if (o)
	  items = g_list_append (items, o);
      } else {
	g_debug ("DRS-Import: %s?", node->name);
      }
    } else {
      g_debug ("DRS-Import: %s?", node->name);
    }
  }
  return items;
}
Beispiel #2
0
/* *NOT A CALLBACK* --> Must be called by inherited class (see aadldata.c) */
void aadlbox_load(ObjectNode obj_node, int version, DiaContext *ctx,
		   Aadlbox *aadlbox)
{
  AttributeNode attr;
  DataNode composite, data;
  Aadl_type type;
  gchar *declaration;
  Aadlport *port;
  ConnectionPoint *connection;
  int i, num;
  
  attr = object_find_attribute(obj_node, "aadlbox_ports");

  composite = attribute_first_data(attr);

  num = attribute_num_data(attr);
  
  for (i=0; i<num; i++) {
    
    Point p;
    attr = composite_find_attribute(composite, "point");
    data_point(attribute_first_data(attr), &p, ctx);
    
    attr = composite_find_attribute(composite, "port_type");
    type = data_enum(attribute_first_data(attr), ctx);
    
    attr = composite_find_attribute(composite, "port_declaration");
    declaration = data_string(attribute_first_data(attr), ctx);
  
    port = g_new0(Aadlport,1);
    port->handle = g_new0(Handle,1);
    port->type = type;
    port->declaration = declaration;
    

    aadlbox_add_port(aadlbox, &p, port);
    
    composite = data_next(composite);
  }
  
  attr = object_find_attribute(obj_node, "aadlbox_connections");
  num = attribute_num_data(attr);
  data = attribute_first_data(attr);
  
  for (i=0; i<num; i++) {
    Point p;
    data_point(data, &p, ctx);

    connection = g_new0(ConnectionPoint,1);
    aadlbox_add_connection(aadlbox, &p, connection);
    
    data = data_next(data);
  }
  
  object_load_props(&aadlbox->element.object,obj_node, ctx);
}
Beispiel #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,
	     DiaContext *ctx, 
	     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, ctx);
        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, ctx, 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 */
      GList *inner_objects = read_objects(obj_node, objects_hash, ctx, NULL, unknown_objects_hash);

      if (inner_objects) {
        obj = group_create(inner_objects);
	object_load_props(obj, obj_node, ctx);
	list = g_list_append(list, obj);
      }
    } else {
      /* silently ignore other nodes */
    }

    obj_node = obj_node->next;
  }
  return list;
}
Beispiel #4
0
/**
 * @param filename the file to load from or NULL for default
 * @param create_lazy if FALSE creates default objects for
 *             every known type. Otherwise default objects
 *             are created on demand
 *
 * Create all the default objects.
 */
gboolean
dia_object_defaults_load (const gchar *filename, gboolean create_lazy)
{
    xmlDocPtr doc;
    xmlNsPtr name_space;
    ObjectNode obj_node, layer_node;

    object_default_create_lazy = create_lazy;

    if (!defaults_hash)
    {
        defaults_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
                                              NULL, _obj_destroy);

        if (!create_lazy)
            object_registry_foreach (_obj_create, defaults_hash);
    }


    /* overload properties from file */
    if (!filename)
    {
        gchar *default_filename = dia_config_filename("defaults.dia");

        if (g_file_test(default_filename, G_FILE_TEST_EXISTS))
            doc = xmlDiaParseFile(default_filename);
        else
            doc = NULL;
        g_free (default_filename);
    }
    else
        doc = xmlDiaParseFile(filename);

    if (!doc)
        return FALSE;

    name_space = xmlSearchNs(doc, doc->xmlRootNode, (const xmlChar *)"dia");
    if (xmlStrcmp (doc->xmlRootNode->name, (const xmlChar *)"diagram")
            || (name_space == NULL))
    {
        message_error(_("Error loading defaults '%s'.\n"
                        "Not a Dia diagram file."),
                      dia_message_filename(filename));
        xmlFreeDoc (doc);
        return FALSE;
    }

    layer_node = doc->xmlRootNode->xmlChildrenNode;
    while (layer_node)
    {
        if (   !xmlIsBlankNode(layer_node)
                && 0 == xmlStrcmp(layer_node->name, (const xmlChar *)"layer"))
        {
            obj_node = layer_node->xmlChildrenNode;
            while (obj_node)
            {
                if (!xmlIsBlankNode(obj_node)
                        && 0 == xmlStrcmp(obj_node->name, (const xmlChar *)"object"))
                {
                    char *typestr = (char *) xmlGetProp(obj_node, (const xmlChar *)"type");
                    char *version = (char *) xmlGetProp(obj_node, (const xmlChar *)"version");
                    if (typestr)
                    {
                        DiaObject *obj = g_hash_table_lookup (defaults_hash, typestr);
                        if (!obj)
                        {
                            if (!create_lazy)
                                g_warning ("Unknown object '%s' while reading '%s'",
                                           typestr, filename);
                            else
                            {
                                DiaObjectType *type = object_get_type (typestr);
                                if (type)
                                    obj = type->ops->load (
                                              obj_node,
                                              0,
                                              filename);
                                if (obj)
                                    g_hash_table_insert (defaults_hash,
                                                         obj->type->name, obj);
                            }
                        }
                        else
                        {
#if 0 /* lots of complaining about missing attributes */
                            object_load_props(obj, obj_node); /* leaks ?? */
#else
                            DiaObject *def_obj;
                            def_obj = obj->type->ops->load (
                                          obj_node,
                                          /*version ? atoi(version) : 0,*/0,
                                          filename);
                            if (def_obj->ops->set_props)
                            {
                                object_copy_props (obj, def_obj, TRUE);
                                def_obj->ops->destroy (def_obj);
                            }
                            else
                            {
                                /* can't copy props */
                                g_hash_table_replace (defaults_hash,
                                                      def_obj->type->name, def_obj);
                            }
#endif
                        }
                        if (version)
                            xmlFree (version);
                        xmlFree (typestr);
                    }
                }
                obj_node = obj_node->next;
            }
        }
        layer_node = layer_node->next;
    }

    xmlFreeDoc(doc);
    return TRUE;
}