/*! * \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; }
/* *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); }
/** * 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; }
/** * @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; }