const PropDescription * object_list_get_prop_descriptions(GList *objects, PropMergeOption option) { GList *descs = NULL, *tmp; const PropDescription *pdesc; for (tmp = objects; tmp != NULL; tmp = tmp->next) { DiaObject *obj = tmp->data; const PropDescription *desc = object_get_prop_descriptions(obj); if (desc) descs = g_list_append(descs, (gpointer)desc); } /* use intersection for single object's list because it is more * complete than union. The latter does not include PROP_FLAG_DONT_MERGE */ if (option == PROP_UNION && g_list_length(objects)!=1) pdesc = prop_desc_lists_union(descs); else pdesc = prop_desc_lists_intersection(descs); /* Important: Do not destroy the actual descriptions returned by the objects. We don't own them. */ g_list_free(descs); return pdesc; }
Property * object_prop_by_name_type(DiaObject *obj, const char *name, const char *type) { const PropDescription *pdesc; GQuark name_quark = g_quark_from_string(name); if (!object_complies_with_stdprop(obj)) return NULL; for (pdesc = object_get_prop_descriptions(obj); pdesc->name != NULL; pdesc++) { if (name_quark == 0 || (pdesc->quark == name_quark)) { Property *prop; static GPtrArray *plist = NULL; if (type && (0 != strcmp(pdesc->type,type))) continue; if (!plist) { plist = g_ptr_array_new(); g_ptr_array_set_size(plist,1); } prop = pdesc->ops->new_prop(pdesc,pdtpp_from_object); g_ptr_array_index(plist,0) = prop; obj->ops->get_props(obj,plist); return prop; } } return NULL; }
/*! Match and possibly modify all the given object's properties. */ static GPtrArray * _match_all_props (DiaObject *obj, const SearchData *sd, const gchar *replacement) { GPtrArray *all_plist = NULL; GPtrArray *matched_plist = NULL; const PropDescription *desc; guint pnum; if (!obj) return NULL; desc = object_get_prop_descriptions (obj); if (!desc) return NULL; all_plist = prop_list_from_descs (desc, pdtpp_true); if (!all_plist) return NULL; /* Step though all object properties. * Along the way, construct a list of matching properties (or * replaced properties). */ for (pnum = 0; pnum < all_plist->len; ++pnum) { Property *prop = g_ptr_array_index (all_plist, pnum); gboolean is_match = FALSE; const gchar *prop_name; if (!prop || !prop->name) continue; /* This extra step seems to be necessary to populate the property data. */ prop_name = prop->name; prop->ops->free (prop); prop = object_prop_by_name (obj, prop_name); is_match = _match_prop (obj, sd, replacement, prop); if (!is_match) { prop->ops->free (prop); continue; } /* We have a match. */ if (!matched_plist) { /* First time. */ matched_plist = prop_list_from_single (prop); } else { /* FIXME: do we realy want a replace all here? */ /* Subsequent finds. */ GPtrArray *append_plist; append_plist = prop_list_from_single (prop); prop_list_add_list (matched_plist, append_plist); prop_list_free (append_plist); } } /* Continue stepping through all object properties. */ return matched_plist; }
void object_save_props(DiaObject *obj, ObjectNode obj_node, DiaContext *ctx) { GPtrArray *props; g_return_if_fail(obj != NULL); g_return_if_fail(obj_node != NULL); g_return_if_fail(object_complies_with_stdprop(obj)); props = prop_list_from_descs(object_get_prop_descriptions(obj), pdtpp_do_save); obj->ops->get_props(obj, props); prop_list_save(props,obj_node,ctx); prop_list_free(props); }
void object_load_props(DiaObject *obj, ObjectNode obj_node, DiaContext *ctx) { GPtrArray *props; g_return_if_fail(obj != NULL); g_return_if_fail(obj_node != NULL); g_return_if_fail(object_complies_with_stdprop(obj)); props = prop_list_from_descs(object_get_prop_descriptions(obj), pdtpp_do_load); if (!prop_list_load(props,obj_node, ctx)) { /* context already has the message */ } obj->ops->set_props(obj, props); prop_list_free(props); }
gboolean object_complies_with_stdprop(const DiaObject *obj) { if (obj->ops->set_props == NULL) { g_warning("No set_props !"); return FALSE; } if (obj->ops->get_props == NULL) { g_warning("No get_props !"); return FALSE; } if (obj->ops->describe_props == NULL) { g_warning("No describe_props !"); return FALSE; } if (object_get_prop_descriptions(obj) == NULL) { g_warning("No properties !"); return FALSE; } return TRUE; }
/** * dia_object_default_create: * @param type The objects type * @param startpoint The left upper corner * @param user_data * @param handle1 * @param handle2 * @return A newly created object. * * Create an object respecting defaults if available */ DiaObject * dia_object_default_create (const DiaObjectType *type, Point *startpoint, void *user_data, Handle **handle1, Handle **handle2) { const DiaObject *def_obj; DiaObject *obj; g_return_val_if_fail (type != NULL, NULL); /* don't use dia_object_default_get() as it would insert the object into the hashtable (store defaults without being asked for it) */ def_obj = g_hash_table_lookup (defaults_hash, type->name); if (def_obj && def_obj->ops->describe_props) { /* copy properties to new object, but keep position */ // factory_debug_to_log(g_strdup_printf(factory_utf8("拖入对像def_obj,名字:%s.\n"),type->name)); obj = type->ops->create (startpoint, user_data, handle1, handle2); if (obj) { GPtrArray *props = prop_list_from_descs ( object_get_prop_descriptions(def_obj), pdtpp_standard_or_defaults); // factory_debug_to_log(factory_utf8("拖入对像def_obj->ops->get_props(def_obj, props)\n")); def_obj->ops->get_props(def_obj, props); // factory_debug_to_log(factory_utf8("拖入对像obj->ops->set_props(obj, props)\n")); obj->ops->set_props(obj, props); obj->ops->move (obj, startpoint); prop_list_free(props); } } else { // factory_debug_to_log(g_strdup_printf(factory_utf8("拖入对像def_obj==NULL,名字:%s.\n"),type->name)); obj = type->ops->create (startpoint, user_data, handle1, handle2); } return obj; }
void object_copy_props(DiaObject *dest, const DiaObject *src, gboolean is_default) { GPtrArray *props; g_return_if_fail(src != NULL); g_return_if_fail(dest != NULL); g_return_if_fail(strcmp(src->type->name,dest->type->name)==0); g_return_if_fail(src->ops == dest->ops); g_return_if_fail(object_complies_with_stdprop(src)); g_return_if_fail(object_complies_with_stdprop(dest)); props = prop_list_from_descs(object_get_prop_descriptions(src), (is_default?pdtpp_do_save_no_standard_default: pdtpp_do_save)); src->ops->get_props((DiaObject *)src, props); /* FIXME: really should make get_props' first argument a (const DiaObject *) */ dest->ops->set_props(dest, props); prop_list_free(props); }