/*! Match and possibly modify the given object's name/text property */ static GPtrArray * _match_name_prop (DiaObject *obj, const SearchData *sd, const gchar *replacement) { Property *prop; gchar **name; gboolean is_match = FALSE; GPtrArray *plist = NULL; if ((prop = object_prop_by_name(obj, "name")) != NULL) name = &((StringProperty *)prop)->string_data; else if ((prop = object_prop_by_name(obj, "text")) != NULL) name = &((TextProperty *)prop)->text_data; else return NULL; is_match = _match_text_prop (obj, sd, replacement, name); if (!is_match) { prop->ops->free (prop); return NULL; } plist = prop_list_from_single (prop); return plist; }
/* * Implement the dictionary interface for the Properties object */ static PyObject * PyDiaProperties_Get(PyDiaProperties *self, PyObject *args) { PyObject *key; PyObject *failobj = Py_None; PyObject *val = NULL; if (!PyArg_ParseTuple(args, "O|O:get", &key, &failobj)) return NULL; if (self->object->ops->get_props != NULL) { Property *p; char* name = PyString_AsString(key); p = object_prop_by_name (self->object, name); if (p) { val = PyDiaProperty_New(p); /* makes a copy */ p->ops->free(p); } } if (val == NULL) { val = failobj; Py_INCREF(val); } return val; }
static int PyDiaProperties_AssSub (PyDiaProperties* self, PyObject *key, PyObject *val) { int ret = -1; if (val == NULL) { PyErr_SetString(PyExc_TypeError, "can not delete properties."); } else { Property *p; char *name; name = PyString_AsString(key); p = object_prop_by_name (self->object, name); /* g_print ("AssSub(key: '%s', type <%s>)\n", name, (p ? p->type : "none")); */ if (p) { if (0 == PyDiaProperty_ApplyToObject(self->object, name, p, val)) { /* if applied the property is deleted */ ret = 0; } else { p->ops->free (p); PyErr_SetString(PyExc_TypeError, "prop type mis-match."); } } else { PyErr_SetObject(PyExc_KeyError, key); } } return ret; }
static PyObject * PyDiaProperties_Subscript (PyDiaProperties *self, register PyObject *key) { PyObject *v = NULL; if (!self->object->ops->describe_props) { PyErr_SetObject(PyExc_KeyError, key); return NULL; } else { Property *p; char *name; name = PyString_AsString(key); p = object_prop_by_name (self->object, name); if (p) { v = PyDiaProperty_New(p); /* makes a copy */ p->ops->free (p); } } if (v == NULL) PyErr_SetObject(PyExc_KeyError, key); return v; }
static PyObject * PyDiaProperties_HasKey(PyDiaProperties *self, PyObject *args) { PyObject *key; long ok = 0; if (!PyArg_ParseTuple(args, "O:has_key", &key)) return NULL; if (!PyString_Check(key)) ok = 0; /* is this too drastic? */ if (self->object->ops->get_props != NULL) { Property *p; char *name; name = PyString_AsString(key); p = object_prop_by_name (self->object, name); ok = (NULL != p); if (p) p->ops->free(p); } return PyInt_FromLong(ok); }
/*! 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; }
/*! * Translate from various Dia point representation to OGDF 'bends', * the latter not containing the first and last point I think. */ static int _obj_get_bends (DiaObject *obj, std::vector<double>& coords) { Property *prop = NULL; coords.resize(0); // no need to ask for Standard - Line: start_point, end_point // we always drop the very first and last point if ((prop = object_prop_by_name(obj, "orth_points")) != NULL || (prop = object_prop_by_name(obj, "poly_points")) != NULL) { PointarrayProperty *ptp = (PointarrayProperty *)prop; int num = ptp->pointarray_data->len; for (int i = 1; i < num-1; ++i) { Point *pt = &g_array_index(ptp->pointarray_data, Point, i); coords.push_back (pt->x); coords.push_back (pt->y); } } else if ((prop = object_prop_by_name(obj, "bez_points")) != NULL) { BezPointarrayProperty *ptp = (BezPointarrayProperty *)prop; int num = ptp->bezpointarray_data->len; for (int i = 1; i < num-1; ++i) { BezPoint *bp = &g_array_index(ptp->bezpointarray_data, BezPoint, i); // TODO: better conversion from polyline to bezierline if (bp->type == BezPoint::BEZ_CURVE_TO) { coords.push_back (bp->p3.x); coords.push_back (bp->p3.y); } else { coords.push_back (bp->p1.x); coords.push_back (bp->p1.y); } } } if (prop) prop->ops->free(prop); return coords.size(); }
static ObjectChange * _obj_set_bends (DiaObject *obj, std::vector<double>& coords) { Property *prop = NULL; if ((prop = object_prop_by_name(obj, "poly_points")) != NULL) { PointarrayProperty *ptp = (PointarrayProperty *)prop; int num = ptp->pointarray_data->len; Point last = g_array_index(ptp->pointarray_data, Point, num-1); // we keep the first and last point (the connected ones) and overwrite the rest num = coords.size()/2+2; g_array_set_size(ptp->pointarray_data, num); for (int i = 1; i < num-1; ++i) { Point *pt = &g_array_index(ptp->pointarray_data, Point, i); pt->x = coords[(i-1)*2]; pt->y = coords[(i-1)*2+1]; } g_array_index(ptp->pointarray_data, Point, num-1) = last; } else if ((prop = object_prop_by_name(obj, "orth_points")) != NULL) { PointarrayProperty *ptp = (PointarrayProperty *)prop; int num = ptp->pointarray_data->len; Point last = g_array_index(ptp->pointarray_data, Point, num-1); // we keep the first and last point (the connected ones) and overwrite the rest num = coords.size()/2+2; // there must be at least 3 points with an orthconn, so we may have to create one // TODO: also maintain the orthogonality? if (num == 2) { Point first = g_array_index(ptp->pointarray_data, Point, 0); Point pt = { (first.x + last.x) / 2, (first.y + last.y) / 2 }; ++num; g_array_set_size(ptp->pointarray_data, num); g_array_index(ptp->pointarray_data, Point, num-2) = pt; } else { g_array_set_size(ptp->pointarray_data, num); for (int i = 1; i < num-1; ++i) { Point *pt = &g_array_index(ptp->pointarray_data, Point, i); pt->x = coords[(i-1)*2]; pt->y = coords[(i-1)*2+1]; } } g_array_index(ptp->pointarray_data, Point, num-1) = last; } else if ((prop = object_prop_by_name(obj, "bez_points")) != NULL) { BezPointarrayProperty *ptp = (BezPointarrayProperty *)prop; int num = ptp->bezpointarray_data->len; BezPoint last = g_array_index(ptp->bezpointarray_data, BezPoint, num-1); // we keep the first and last point (the connected ones) and overwrite the rest num = coords.size()/2+1; if (num == 1) { // still want to have two points - a straight line g_array_set_size(ptp->bezpointarray_data, 2); last.p1 = last.p3; last.p2 = g_array_index(ptp->bezpointarray_data, BezPoint, 0).p1; g_array_index(ptp->bezpointarray_data, BezPoint, 1) = last; } else { // the bends are used for control points ... Point p1; p1.x = coords[0]; p1.y = coords[1]; g_array_set_size(ptp->bezpointarray_data, num); for (int i = 1; i < num-1; ++i) { BezPoint *bp = &g_array_index(ptp->bezpointarray_data, BezPoint, i); // TODO: better conversion from polyline to bezierline? bp->type = BezPoint::BEZ_CURVE_TO; bp->p1 = p1; bp->p2 = p1; // ... and an extra point on every segment center bp->p3.x = (p1.x + coords[i*2]) / 2; bp->p3.y = (p1.y + coords[i*2+1]) / 2; // next control point p1.x = coords[i*2]; p1.y = coords[i*2+1]; } last.type = BezPoint::BEZ_CURVE_TO; last.p1 = p1; last.p2 = p1; g_array_index(ptp->bezpointarray_data, BezPoint, num-1) = last; } } if (prop) { GPtrArray *props = prop_list_from_single (prop); return object_apply_props (obj, props); } return NULL; }