Exemple #1
0
DiaObject *
create_standard_bezierline(int num_points, 
			   BezPoint *points,
			   Arrow *end_arrow,
			   Arrow *start_arrow) {
    DiaObjectType *otype = object_get_type("Standard - BezierLine");
    DiaObject *new_obj;
    Handle *h1, *h2;
    BezierCreateData bcd;
    GPtrArray *props;

    if (otype == NULL){
	message_error(_("Can't find standard object"));
	return NULL;
    }

    bcd.num_points = num_points;
    bcd.points = points;

    new_obj = otype->ops->create(NULL, &bcd, &h1, &h2);

    props = prop_list_from_descs(create_line_prop_descs,pdtpp_true);
    g_assert(props->len == 2);
    
    if (start_arrow != NULL)
	((ArrowProperty *)g_ptr_array_index(props, 0))->arrow_data = *start_arrow;
    if (end_arrow != NULL)
	((ArrowProperty *)g_ptr_array_index(props, 1))->arrow_data = *end_arrow;

    new_obj->ops->set_props(new_obj, props);
    prop_list_free(props);
    
    return new_obj;
}
Exemple #2
0
static void
display_data_received_callback (GtkWidget *widget, 
				GdkDragContext *context,
				gint x, 
				gint y, 
				GtkSelectionData *data,
				guint info, 
				guint time, 
				DDisplay *ddisp)
{
  if (gtk_selection_data_get_format(data) == 8 &&
      gtk_selection_data_get_length(data) == sizeof(ToolButtonData *) &&
      gtk_drag_get_source_widget(context) != NULL) {
    ToolButtonData *tooldata = *(ToolButtonData **)gtk_selection_data_get_data(data);
    /* g_message("Tool drop %s at (%d, %d)", (gchar *)tooldata->extra_data, x, y);*/
    ddisplay_drop_object(ddisp, x, y,
			 object_get_type((gchar *)tooldata->extra_data),
			 tooldata->user_data);

    gtk_drag_finish (context, TRUE, FALSE, time);
  } else {
    dia_dnd_file_drag_data_received (widget, context, x, y, data, info, time, ddisp);
  }
  /* ensure the right window has the focus for text editing */
  gtk_window_present(GTK_WINDOW(ddisp->shell));
}
Exemple #3
0
DiaObject *
create_standard_ellipse(real xpos, real ypos, real width, real height) {
    DiaObjectType *otype = object_get_type("Standard - Ellipse");
    DiaObject *new_obj;
    Handle *h1, *h2;
    
    GPtrArray *props;
    Point point;

    if (otype == NULL){
	message_error(_("Can't find standard object"));
	return NULL;
    }

    point.x = xpos;
    point.y = ypos;

    new_obj = otype->ops->create(&point, otype->default_user_data,
				 &h1, &h2);
  
    props = make_element_props(xpos,ypos,width,height);
    new_obj->ops->set_props(new_obj, props);
    prop_list_free(props);

    return new_obj;
}
Exemple #4
0
/*!
 * \brief factory function for ObjectType (Object factories)
 *
 * Before this function can return anything useful the ObjectType registry needs to be filled,
 * e.g. by dia::register_plugins()
 */
dia::ObjectType*
dia::get_object_type (const char* name)
{
    ::DiaObjectType* ot = object_get_type(const_cast<char*>(name));
    if (ot)
        return new dia::ObjectType (ot);
    return 0;
}
/*!
 * \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;
}
Exemple #6
0
void
sheet_append_sheet_obj(Sheet *sheet, SheetObject *obj)
{
    ObjectType *type;

    type = object_get_type(obj->object_type);
    if (type == NULL) {
        message_warning("Object '%s' needed in sheet '%s' was not found.\n"
                        "It will not be availible for use.",
                        obj->object_type, sheet->name);
    } else {
        sheet->objects = g_slist_append( sheet->objects, (gpointer) obj);
    }
}
static GList *
read_objects(xmlNodePtr objects, GHashTable *objects_hash, char *filename)
{
  GList *list;
  ObjectType *type;
  Object *obj;
  ObjectNode obj_node;
  char *typestr;
  char *versionstr;
  char *id;
  int version;

  list = NULL;

  obj_node = objects->childs;
  
  while ( obj_node != NULL) {

    if (strcmp(obj_node->name, "object")==0) {
      typestr = xmlGetProp(obj_node, "type");
      versionstr = xmlGetProp(obj_node, "version");
      id = xmlGetProp(obj_node, "id");
      
      version = 0;
      if (versionstr != NULL) {
	version = atoi(versionstr);
	free(versionstr);
      }
      
      type = object_get_type((char *)typestr);
      if (typestr) free(typestr);
      
      obj = type->ops->load(obj_node, version, filename);
      list = g_list_append(list, obj);
      
      g_hash_table_insert(objects_hash, (char *)id, obj);
   
    } else if (strcmp(obj_node->name, "group")==0) {
      obj = group_create(read_objects(obj_node, objects_hash, filename));
      list = g_list_append(list, obj);
    } else {
      message_error(_("Error reading diagram file\n"));
    }

    obj_node = obj_node->next;
  }
  return list;
}
Exemple #8
0
static gboolean
import_data (const gchar *filename, DiagramData *data, DiaContext *ctx, void* user_data)
{
  DiaObjectType *otype = object_get_type("Standard - Image");
  gint width, height;

  if (!otype) /* this would be really broken */
    return FALSE;

  if (!user_data) {
    dia_context_add_message(ctx, _("Calling error, missing user_data."));
    return FALSE;
  }

  if (gdk_pixbuf_get_file_info (filename, &width, &height))
    {
      DiaObject *obj;
      Handle *h1, *h2;
      Point point;
      point.x = point.y = 0.0;

      obj = otype->ops->create(&point, otype->default_user_data, &h1, &h2);
      if (obj)
        {
          GPtrArray *plist = g_ptr_array_new ();

          prop_list_add_filename (plist, "image_file", filename);
          prop_list_add_real (plist, "elem_width", width / 20.0);
          prop_list_add_real (plist, "elem_height", height / 20.0);

          obj->ops->set_props(obj, plist);
          prop_list_free (plist);

          layer_add_object(data->active_layer, obj);
          return TRUE;
        }
    }
  else
    {
      dia_context_add_message(ctx, _("Pixbuf[%s] can't load:\n%s"), 
			      (gchar*)user_data, dia_context_get_filename(ctx));
    }

  return FALSE;
}
Exemple #9
0
DiaObject *
create_standard_text(real xpos, real ypos) {
    DiaObjectType *otype = object_get_type("Standard - Text");
    DiaObject *new_obj;
    Handle *h1, *h2;
    Point point;

    if (otype == NULL){
	message_error(_("Can't find standard object"));
	return NULL;
    }

    point.x = xpos;
    point.y = ypos;

    new_obj = otype->ops->create(&point, otype->default_user_data,
				 &h1, &h2);
    
    return new_obj;
}
Exemple #10
0
DiaObject *
create_standard_path(int num_points, BezPoint *points)
{
    DiaObjectType *otype = object_get_type("Standard - Path");
    DiaObject *new_obj;
    Handle *h1, *h2;
    BezierCreateData bcd;

    if (otype == NULL){
	message_error(_("Can't find standard object"));
	return NULL;
    }

    bcd.num_points = num_points;
    bcd.points = points;

    new_obj = otype->ops->create(NULL, &bcd, &h1, &h2);
    
    return new_obj;
}
Exemple #11
0
DiaObject *
create_standard_polygon(int num_points, 
			Point *points) {
    DiaObjectType *otype = object_get_type("Standard - Polygon");
    DiaObject *new_obj;
    Handle *h1, *h2;
    MultipointCreateData pcd;

    if (otype == NULL){
	message_error(_("Can't find standard object"));
	return NULL;
    }

    pcd.num_points = num_points;
    pcd.points = points;

    new_obj = otype->ops->create(NULL, &pcd, &h1, &h2);
    
    return new_obj;
}
Exemple #12
0
DiaObject *
create_standard_arc(real x1, real y1, real x2, real y2,
		    real distance, 
		    Arrow *end_arrow,
		    Arrow *start_arrow) {
    DiaObjectType *otype = object_get_type("Standard - Arc");
    DiaObject *new_obj;
    Handle *h1, *h2;
    Point p1, p2;
    GPtrArray *props;

    if (otype == NULL){
	message_error(_("Can't find standard object"));
	return NULL;
    }

    p1.x = x1;
    p1.y = y1;
    p2.x = x2;
    p2.y = y2;


    new_obj = otype->ops->create(&p1, otype->default_user_data,
				 &h1, &h2);
    new_obj->ops->move_handle(new_obj, h2, &p2, NULL, HANDLE_MOVE_USER_FINAL,0);
    props = prop_list_from_descs(create_arc_prop_descs,pdtpp_true);
    g_assert(props->len == 3);
    
    ((RealProperty *)g_ptr_array_index(props,0))->real_data = distance;
    if (start_arrow != NULL)
	((ArrowProperty *)g_ptr_array_index(props, 1))->arrow_data = *start_arrow;
    if (end_arrow != NULL)
	((ArrowProperty *)g_ptr_array_index(props, 2))->arrow_data = *end_arrow;

    new_obj->ops->set_props(new_obj, props);
    prop_list_free(props);

    return new_obj;
}
Exemple #13
0
static PyObject *
PyDiaSheet_GetAttr(PyDiaSheet *self, gchar *attr)
{
    if (!strcmp(attr, "__members__"))
	return Py_BuildValue("[ssss]", "name", "description", "filename", "objects");
    else if (!strcmp(attr, "name"))
	return PyString_FromString(self->sheet->name);
    else if (!strcmp(attr, "description"))
	return PyString_FromString(self->sheet->description);
    else if (!strcmp(attr, "filename"))
	return PyString_FromString(self->sheet->filename);
    else if (!strcmp(attr, "user"))
	return PyInt_FromLong(self->sheet->scope == SHEET_SCOPE_USER ? 1 : 0);
    else if (!strcmp(attr, "objects")) {
	/* Just returning tuples with information for now. Wrapping SheetObject
	 * looks like overkill for the time being.
	 *  - DiaObjectType or None
	 *  - description of the SheetObject
	 *  - filename of the icon file
	 */
	PyObject *ret = PyList_New(0);
	GSList *list;

	for (list = self->sheet->objects; list != NULL; list = list->next) {
	    SheetObject *so = list->data;
	    DiaObjectType *ot = object_get_type (so->object_type);

	    if (!ot)
		Py_INCREF(Py_None);
	    PyList_Append(ret, Py_BuildValue ("(Oss)",
						ot ? PyDiaObjectType_New (ot) : Py_None,
						PyString_FromString (so->description ? so->description : ""),
						PyString_FromString (so->pixmap_file ? so->pixmap_file : "")));
	}
	return ret;
    }

    return Py_FindMethod(PyDiaSheet_Methods, (PyObject *)self, attr);
}
Exemple #14
0
DiaObject *
create_standard_image(real xpos, real ypos, real width, real height,
		      char *file) {
    DiaObjectType *otype = object_get_type("Standard - Image");
    DiaObject *new_obj;
    Handle *h1, *h2;
    Point point;
    GPtrArray *props;
    StringProperty *sprop;

    if (otype == NULL){
	message_error(_("Can't find standard object"));
	return NULL;
    }

    point.x = xpos;
    point.y = ypos;

    new_obj = otype->ops->create(&point, otype->default_user_data,
				 &h1, &h2);
    
    props = make_element_props(xpos,ypos,width,height);
    new_obj->ops->set_props(new_obj, props);
    prop_list_free(props);


    props = prop_list_from_descs(create_file_prop_descs,pdtpp_true);
    g_assert(props->len == 1);    
    sprop = g_ptr_array_index(props,0);
    g_free(sprop->string_data);
    sprop->string_data = g_strdup(file);
    new_obj->ops->set_props(new_obj, props);
    prop_list_free(props);

    return new_obj;
}
Exemple #15
0
SheetObjectMod *
sheets_append_sheet_object_mod(SheetObject *so, SheetMod *sm)
{
  SheetObjectMod *sheet_object_mod;
  DiaObjectType *ot;

  g_return_val_if_fail (so != NULL && sm != NULL, NULL);
  g_return_val_if_fail (custom_type_symbol != NULL, NULL);

  sheet_object_mod = g_new0(SheetObjectMod, 1);
  sheet_object_mod->sheet_object = *so;
  sheet_object_mod->mod = SHEET_OBJECT_MOD_NONE;

  ot = object_get_type(so->object_type);
  g_assert(ot);
  if (ot->ops == ((DiaObjectType *)(custom_type_symbol))->ops)
    sheet_object_mod->type = OBJECT_TYPE_SVG;
  else
    sheet_object_mod->type = OBJECT_TYPE_PROGRAMMED;

  sm->sheet.objects = g_slist_append(sm->sheet.objects, sheet_object_mod);

  return sheet_object_mod;
}
Exemple #16
0
/* reads a solid entity from the dxf file and creates a polygon object in dia*/
static DiaObject *
read_entity_solid_dxf(FILE *filedxf, DxfData *data, DiagramData *dia)
{
   /* polygon data */
   Point p[4];
   
   DiaObjectType *otype = object_get_type("Standard - Polygon");  
   Handle *h1, *h2;
   
   DiaObject *polygon_obj;
   MultipointCreateData *pcd;

   Color fill_colour;

   GPtrArray *props;
   
   real line_width = 0.001;
   LineStyle style = LINESTYLE_SOLID;
   Layer *layer = dia->active_layer;
   RGB_t color  = { 127, 127, 127 };
   
/*   printf( "Solid " ); */

   memset(p, 0, sizeof(p));

    do {
        if(read_dxf_codes(filedxf, data) == FALSE){
            return( NULL );
        }
        switch(data->code){
        case 6:	 
	   style = get_dia_linestyle_dxf(data->value);
	   break;		
        case  8: 
	   layer = layer_find_by_name(data->value, dia);
	   color = pal_get_rgb (_dxf_color_get_by_layer (layer));
	   /*printf( "layer: %s ", data->value );*/
	   break;
        case 10:
	   p[0].x = g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
	   /*printf( "P0.x: %f ", p[0].x );*/
	   break;
        case 11: 
            p[1].x = g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
	   /*printf( "P1.x: %f ", p[1].x );*/
            break;
        case 12: /* bot only swapped, but special for only 3 points given */
            p[2].x = p[3].x = g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
	   /*printf( "P2.x: %f ", p[2].x );*/
            break;
        case 13: /* SOLID order swapped compared to Dia's */
            p[2].x = g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
	   /*printf( "P3.x: %f ", p[3].x );*/
            break;
        case 20: 
            p[0].y = (-1)*g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
	   /*printf( "P0.y: %f ", p[0].y );*/
            break;
        case 21: 
            p[1].y = (-1)*g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
	   /*printf( "P1.y: %f ", p[1].y );*/
            break;
        case 22: 
            p[2].y = p[3].y = (-1)*g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
	   /*printf( "P2.y: %f ", p[2].y );*/
            break;
        case 23: 
            p[2].y = (-1)*g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
	   /*printf( "P3.y: %f\n", p[3].y );*/
            break;
        case 39: 
            line_width = g_ascii_strtod(data->value, NULL) * WIDTH_SCALE;
	   /*printf( "width %f\n", line_width );*/
            break;
        case 62: 
            color = pal_get_rgb (atoi(data->value));
            break;
        }	
    } while(data->code != 0);

   pcd = g_new( MultipointCreateData, 1);
   
   if( p[2].x != p[3].x || p[2].y != p[3].y )
     pcd->num_points = 4;
   else
     pcd->num_points = 3;
   
   pcd->points = g_new( Point, pcd->num_points );
   
   memcpy( pcd->points, p, sizeof( Point ) * pcd->num_points );

   polygon_obj = otype->ops->create( NULL, pcd, &h1, &h2 );

    _color_init_from_rgb (&fill_colour, color);

   props = g_ptr_array_new ();

   prop_list_add_line_colour (props, &fill_colour);
   prop_list_add_line_width (props, line_width);
   prop_list_add_line_style (props, style, 1.0);
   prop_list_add_fill_colour (props, &fill_colour);
   prop_list_add_show_background (props, TRUE);

   polygon_obj->ops->set_props( polygon_obj, props );

   prop_list_free(props);

   if (layer)
      layer_add_object( layer, polygon_obj );
   else
      return polygon_obj;

   return NULL;
}
Exemple #17
0
/* reads a line entity from the dxf file and creates a line object in dia*/
static DiaObject *
read_entity_line_dxf(FILE *filedxf, DxfData *data, DiagramData *dia)
{
    /* line data */
    Point start, end;
    
    DiaObjectType *otype = object_get_type("Standard - Line");  
    Handle *h1, *h2;
    
    DiaObject *line_obj;
    Color line_colour;
    RGB_t color = { 0, };
    GPtrArray *props;

    real line_width = DEFAULT_LINE_WIDTH;
    LineStyle style = LINESTYLE_SOLID;
    Layer *layer = dia->active_layer;
    
    end.x=0;
    end.y=0;

    props = g_ptr_array_new();

    do {
        if(read_dxf_codes(filedxf, data) == FALSE){
            return( NULL );
        }
        switch(data->code){
        case 6:	 style = get_dia_linestyle_dxf(data->value);
            break;		
        case  8: 
	    layer = layer_find_by_name(data->value, dia);
	    color = pal_get_rgb (_dxf_color_get_by_layer (layer));
            break;
        case 10:
            start.x = g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
            break;
        case 11: 
            end.x = g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
            break;
        case 20: 
            start.y = (-1)*g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
            break;
        case 21: 
            end.y = (-1)*g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
            break;
        case 39: 
            line_width = g_ascii_strtod(data->value, NULL) * WIDTH_SCALE;
	   /*printf( "line width %f\n", line_width ); */
            break;
	case 62 :
            color = pal_get_rgb (atoi(data->value));
            break;
        }	
    } while(data->code != 0);

    _color_init_from_rgb (&line_colour, color);
    line_obj = otype->ops->create(&start, otype->default_user_data,
                                  &h1, &h2);

    prop_list_add_point (props, "start_point", &start);
    prop_list_add_point (props, "end_point", &end);
    prop_list_add_line_colour (props, &line_colour);
    prop_list_add_line_width (props, line_width);
    prop_list_add_line_style (props, style, 1.0);

    line_obj->ops->set_props(line_obj, props);

    prop_list_free(props);

    if (layer)
      layer_add_object(layer, line_obj);
    else
      return line_obj;
    /* don't add it it twice */
    return NULL;
}
Exemple #18
0
/* reads a circle entity from the dxf file and creates a circle object in dia*/
static DiaObject *
read_entity_arc_dxf(FILE *filedxf, DxfData *data, DiagramData *dia)
{
    /* arc data */
    Point start, end;
    Point center = {0, 0};
    real radius = 1.0, start_angle = 0.0, end_angle=360.0;
    real curve_distance;

    DiaObjectType *otype = object_get_type("Standard - Arc");  
    Handle *h1, *h2;
  
    DiaObject *arc_obj;
    RGB_t color  = { 0, };
    Color line_colour;
    GPtrArray *props;

    real line_width = DEFAULT_LINE_WIDTH;
    Layer *layer = dia->active_layer;
		
    do {
        if(read_dxf_codes(filedxf, data) == FALSE){
            return( NULL );
        }
        switch(data->code){
        case  8: 
            layer = layer_find_by_name(data->value, dia);
	    color = pal_get_rgb (_dxf_color_get_by_layer (layer));
            break;
        case 10: 
            center.x = g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
            break;
        case 20: 
            center.y = (-1)*g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
            break;
        case 39: 
            line_width = g_ascii_strtod(data->value, NULL) * WIDTH_SCALE;
            break;
        case 40: 
            radius = g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
            break;
        case 50:
            start_angle = g_ascii_strtod(data->value, NULL)*M_PI/180.0;
            break;
        case 51:
            end_angle = g_ascii_strtod(data->value, NULL)*M_PI/180.0;
            break;
	case 62 :
            color = pal_get_rgb (atoi(data->value));
            break;
        }
    } while(data->code != 0);

    /* printf("c.x=%f c.y=%f s",center.x,center.y); */
    start.x = center.x + cos(start_angle) * radius; 
    start.y = center.y - sin(start_angle) * radius;
    end.x = center.x + cos(end_angle) * radius;
    end.y = center.y - sin(end_angle) * radius;
    /*printf("s.x=%f s.y=%f e.x=%f e.y=%f\n",start.x,start.y,end.x,end.y);*/


    if (end_angle < start_angle) end_angle += 2.0*M_PI;
    curve_distance = radius * (1 - cos ((end_angle - start_angle)/2));

    /*printf("start_angle: %f end_angle: %f radius:%f  curve_distance:%f\n",
      start_angle,end_angle,radius,curve_distance);*/
   
    arc_obj = otype->ops->create(&center, otype->default_user_data,
                                     &h1, &h2);
    
    _color_init_from_rgb (&line_colour, color);

    props = g_ptr_array_new ();
    prop_list_add_point (props, "start_point", &start);
    prop_list_add_point (props, "end_point", &end);
    prop_list_add_real (props, "curve_distance", curve_distance);
    prop_list_add_line_colour (props, &line_colour);
    prop_list_add_line_width (props, line_width);
    
    arc_obj->ops->set_props(arc_obj, props);
    prop_list_free(props);
   
    if (layer)
        layer_add_object(layer, arc_obj);
    else
        return arc_obj ;

    return NULL; /* don't add it twice */
}
Exemple #19
0
/* reads an ellipse entity from the dxf file and creates an ellipse object in dia*/
static DiaObject *
read_entity_ellipse_dxf(FILE *filedxf, DxfData *data, DiagramData *dia)
{
    /* ellipse data */
    Point center = {0, 0};
    real width = 1.0;
    real ratio_width_height = 1.0;
    
    DiaObjectType *otype = object_get_type("Standard - Ellipse");
    Handle *h1, *h2;
    
    DiaObject *ellipse_obj; 
    RGB_t color = { 0, };
    Color line_colour;
    GPtrArray *props;

    real line_width = DEFAULT_LINE_WIDTH;
    Layer *layer = dia->active_layer;
    
    do {
        if(read_dxf_codes(filedxf, data) == FALSE){
            return( NULL );
        }
        switch(data->code){
        case  8: 
            layer = layer_find_by_name(data->value, dia);
	    color = pal_get_rgb (_dxf_color_get_by_layer (layer));
            break;
        case 10: 
            center.x = g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
            break;
        case 11: 
            ratio_width_height = g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
            break;
        case 20: 
            center.y = (-1)*g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
            break;
        case 39: 
            line_width = g_ascii_strtod(data->value, NULL) * WIDTH_SCALE;
            break;
        case 40: 
            width = g_ascii_strtod(data->value, NULL) * WIDTH_SCALE; /* XXX what scale */
            break;
	case 62 :
            color = pal_get_rgb (atoi(data->value));
            break;
        }
    } while(data->code != 0);
 
    center.x -= width;
    center.y -= (width*ratio_width_height);
    ellipse_obj = otype->ops->create(&center, otype->default_user_data,
                                     &h1, &h2);

    _color_init_from_rgb (&line_colour, color);

    props = g_ptr_array_new ();

    prop_list_add_point (props, "elem_corner", &center);
    prop_list_add_real (props, "elem_width", width);
    prop_list_add_real (props, "elem_height", width * ratio_width_height);
    prop_list_add_line_colour (props, &line_colour);
    prop_list_add_line_width (props, line_width);
    prop_list_add_show_background (props, FALSE);
    
    ellipse_obj->ops->set_props(ellipse_obj, props);
    prop_list_free(props);

    if (layer)
        layer_add_object(layer, ellipse_obj);
    else
        return ellipse_obj;

    return NULL; /* don't add it twice */
}
Exemple #20
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;
}
Exemple #21
0
static void
load_register_sheet(const gchar *dirname, const gchar *filename)
{
    xmlDocPtr doc;
    xmlNsPtr ns;
    xmlNodePtr node, contents,subnode,root;
    char *tmp;
    gchar *name = NULL, *description = NULL;
    int name_score = -1;
    int descr_score = -1;
    Sheet *sheet = NULL;
    GSList *sheetp;

    /* the XML fun begins here. */

    doc = xmlParseFile(filename);
    if (!doc) return;
    root = doc->root;
    while (root && (root->type != XML_ELEMENT_NODE)) root=root->next;
    if (!root) return;

    if (!(ns = xmlSearchNsByHref(doc,root,
                                 "http://www.lysator.liu.se/~alla/dia/dia-sheet-ns"))) {
        g_warning("could not find sheet namespace");
        xmlFreeDoc(doc);
        return;
    }

    if ((root->ns != ns) || (strcmp(root->name,"sheet"))) {
        g_warning("root element was %s -- expecting sheet", doc->root->name);
        xmlFreeDoc(doc);
        return;
    }
    for (node = root->childs; node != NULL; node = node->next) {
        if (node->type != XML_ELEMENT_NODE)
            continue;

        if (node->ns == ns && !strcmp(node->name, "name")) {
            gint score;

            /* compare the xml:lang property on this element to see if we get a
             * better language match.  LibXML seems to throw away attribute
             * namespaces, so we use "lang" instead of "xml:lang" */
            tmp = xmlGetProp(node, "xml:lang");
            if (!tmp) tmp = xmlGetProp(node, "lang");
            score = intl_score_locale(tmp);
            if (tmp) free(tmp);

            if (name_score < 0 || score < name_score) {
                name_score = score;
                if (name) free(name);
                name = xmlNodeGetContent(node);
            }
        } else if (node->ns == ns && !strcmp(node->name, "description")) {
            gint score;

            /* compare the xml:lang property on this element to see if we get a
             * better language match.  LibXML seems to throw away attribute
             * namespaces, so we use "lang" instead of "xml:lang" */
            tmp = xmlGetProp(node, "xml:lang");
            if (!tmp) tmp = xmlGetProp(node, "lang");
            score = intl_score_locale(tmp);
            g_free(tmp);

            if (descr_score < 0 || score < descr_score) {
                descr_score = score;
                if (description) free(description);
                description = xmlNodeGetContent(node);
            }

        } else if (node->ns == ns && !strcmp(node->name, "contents")) {
            contents = node;
        }
    }

    if (!contents) {
        g_warning("no contents in sheet %s.", filename);
        xmlFreeDoc(doc);
        if (name) free(name);
        if (description) free(description);
        return;
    }

    sheetp = get_sheets_list();
    while (sheetp) {
        if (sheetp->data && !strcmp(((Sheet *)(sheetp->data))->name,name)) {
            sheet = sheetp->data;
            break;
        }
        sheetp = sheetp->next;
    }

    if (!sheet)
        sheet = new_sheet(name,description);

    for (node = contents->childs ; node != NULL; node = node->next) {
        ObjectType *obj_type;
        SheetObject *sheet_obj;
        gboolean isobject = FALSE,isshape = FALSE;
        gchar *iconname = NULL;

        int subdesc_score = -1;
        gchar *objdesc = NULL, *objicon = NULL;

        gint intdata = 0;
        gchar *chardata = NULL;

        if (node->type != XML_ELEMENT_NODE)
            continue;
        if (node->ns != ns) continue;
        if (!strcmp(node->name,"object")) {
            isobject = TRUE;
        } else if (!strcmp(node->name,"shape")) {
            isshape = TRUE;
        }

        if (isobject) {
            tmp = xmlGetProp(node,"intdata");
            if (tmp) {
                char *p;
                intdata = (gint)strtol(tmp,&p,0);
                if (*p != 0) intdata = 0;
                free(tmp);
            }
            chardata = xmlGetProp(node,"chardata");
            /* TODO.... */
            if (chardata) free(chardata);
        }

        if (isobject || isshape) {
            for (subnode = node->childs; subnode != NULL ; subnode = subnode->next) {
                if (subnode->ns == ns && !strcmp(subnode->name, "description")) {
                    gint score;

                    /* compare the xml:lang property on this element to see if we get a
                     * better language match.  LibXML seems to throw away attribute
                     * namespaces, so we use "lang" instead of "xml:lang" */

                    tmp = xmlGetProp(subnode, "xml:lang");
                    if (!tmp) tmp = xmlGetProp(subnode, "lang");
                    score = intl_score_locale(tmp);
                    if (tmp) free(tmp);

                    if (subdesc_score < 0 || score < subdesc_score) {
                        subdesc_score = score;
                        if (objdesc) free(objdesc);
                        objdesc = xmlNodeGetContent(subnode);
                    }

                } else if (subnode->ns == ns && !strcmp(subnode->name,"icon")) {
                    tmp = xmlNodeGetContent(subnode);
                    iconname = g_strconcat(dirname,G_DIR_SEPARATOR_S,tmp,NULL);
                    if (tmp) free(tmp);
                }
            }

            tmp = xmlGetProp(node,"name");

            sheet_obj = g_new(SheetObject,1);
            sheet_obj->object_type = g_strdup(tmp);
            sheet_obj->description = objdesc;
            sheet_obj->pixmap = NULL;
            sheet_obj->user_data = (void *)intdata; /* XXX modify user_data type ? */
            sheet_obj->pixmap_file = iconname;


            if (isshape) {
                ShapeInfo *info = shape_info_getbyname(tmp);
                if (info) {
                    if (!sheet_obj->description)
                        sheet_obj->description = g_strdup(info->description);
                    if (!sheet_obj->pixmap_file && !sheet_obj->pixmap)
                        sheet_obj->pixmap_file = info->icon;
                    sheet_obj->user_data = (void *)info;
                } else {
                    /* Somehow, this shape is unknown */
                    g_free(sheet_obj->description);
                    g_free(sheet_obj->pixmap_file);
                    g_free(sheet_obj->object_type);
                    g_free(sheet_obj);
                    if (tmp) free(tmp);
                    continue;
                }
            } else {
                if (shape_info_getbyname(tmp)) {
                    g_warning("Object_type(%s) is really a shape, not an object..",tmp);
                    /* maybe I should listen to what others say, after all, and dump
                       this shape/object distinction ? */
                }
                if (!object_get_type(tmp)) {
                    g_free(sheet_obj->description);
                    g_free(sheet_obj->pixmap_file);
                    g_free(sheet_obj->object_type);
                    g_free(sheet_obj);
                    if (tmp) free(tmp);
                    continue;
                }
            }
            if (tmp) free(tmp);

            /* we don't need to fix up the icon and descriptions for simple objects,
            since they don't have their own description, and their icon is
             already automatically handled. */
            sheet_append_sheet_obj(sheet,sheet_obj);
        }
    }

    if (sheet) register_sheet(sheet);
    xmlFreeDoc(doc);
}
static GtkWidget *
create_sheet_page(GtkWidget *parent, Sheet *sheet)
{
  GSList *list;
  SheetObject *sheet_obj;
  GtkWidget *table;
  GtkWidget *button;
  GtkWidget *pixmapwidget;
  GdkPixmap *pixmap;
  GdkBitmap *mask;
  ToolButtonData *data;
  GtkStyle *style;
  GtkWidget *scrolled_window;
  int i;
  int rows;


  scrolled_window = gtk_scrolled_window_new(NULL, NULL);
  gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(scrolled_window),
				  GTK_POLICY_AUTOMATIC,
				  GTK_POLICY_AUTOMATIC);

  rows = (g_slist_length(sheet->objects) - 1) / COLUMNS + 1;
  if (rows<1)
    rows = 1;
  
  table = gtk_table_new (rows, COLUMNS, TRUE);
  
  style = gtk_widget_get_style(parent);

  i = 0;
  list = sheet->objects;
  while (list != NULL) {
    sheet_obj = (SheetObject *) list->data;
    
    
    if (sheet_obj->pixmap != NULL) {
      pixmap = gdk_pixmap_create_from_xpm_d(parent->window, &mask, 
					    &style->bg[GTK_STATE_NORMAL], 
					    sheet_obj->pixmap);
    } else if (sheet_obj->pixmap_file != NULL) {
      pixmap = gdk_pixmap_create_from_xpm(parent->window, &mask,
					  &style->bg[GTK_STATE_NORMAL],
					  sheet_obj->pixmap_file);
    } else {
      ObjectType *type;
      type = object_get_type(sheet_obj->object_type);
      pixmap = gdk_pixmap_create_from_xpm_d(parent->window, &mask, 
					    &style->bg[GTK_STATE_NORMAL], 
					    type->pixmap);
    }

    pixmapwidget = gtk_pixmap_new(pixmap, mask);

    
    button = gtk_radio_button_new (tool_group);
    gtk_container_set_border_width (GTK_CONTAINER (button), 0);
    tool_group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
    
    gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);


    gtk_container_add (GTK_CONTAINER (button), pixmapwidget);
    gtk_table_attach (GTK_TABLE (table), button,
		      (i % COLUMNS), (i % COLUMNS) + 1,
		      (i / COLUMNS), (i / COLUMNS) + 1,
		      GTK_EXPAND | GTK_SHRINK | GTK_FILL,
		      GTK_FILL,
		      0, 0);


    /* This is a Memory leak, these can't be freed.
       Doesn't matter much anyway... */

    data = g_new(ToolButtonData, 1);
    data->type = CREATE_OBJECT_TOOL;
    data->extra_data = sheet_obj->object_type;
    data->user_data = sheet_obj->user_data;
    
    gtk_signal_connect (GTK_OBJECT (button), "toggled",
			GTK_SIGNAL_FUNC (tool_select_update),
			data);
    
    gtk_signal_connect (GTK_OBJECT (button), "button_press_event",
			GTK_SIGNAL_FUNC (tool_button_press),
			data);

    gtk_tooltips_set_tip (tool_tips, button,
			  gettext(sheet_obj->description), NULL);

    list = g_slist_next(list);
    i++;
  }

  gtk_widget_show(table);
  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), table);
  
  return scrolled_window;
}
static void
create_tools(GtkWidget *parent)
{
  GtkWidget *table;
  GtkWidget *button;
  GtkWidget *pixmapwidget;
  GdkPixmap *pixmap;
  GdkBitmap *mask;
  GtkStyle *style;
  char **pixmap_data;
  int i;
  
  table = gtk_table_new (ROWS, COLUMNS, FALSE);
  gtk_box_pack_start (GTK_BOX (parent), table, FALSE, TRUE, 0);
  gtk_widget_realize (table);

  for (i = 0; i < NUM_TOOLS; i++) {
    tool_widgets[i] = button = gtk_radio_button_new (tool_group);
    gtk_container_set_border_width (GTK_CONTAINER (button), 0);
    tool_group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
    gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);

    gtk_table_attach (GTK_TABLE (table), button,
		      (i % COLUMNS), (i % COLUMNS) + 1,
		      (i / COLUMNS), (i / COLUMNS) + 1,
		      GTK_EXPAND | GTK_SHRINK | GTK_FILL,
		      GTK_FILL,
		      0, 0);

    if (tool_data[i].callback_data.type == MODIFY_TOOL) {
      modify_tool_button = GTK_WIDGET(button);
    }
    
    if (tool_data[i].icon_data==NULL) {
      ObjectType *type;
      type =
	object_get_type((char *)tool_data[i].callback_data.extra_data);
      if (type == NULL)
	pixmap_data = tool_data[0].icon_data;
      else
	pixmap_data = type->pixmap;
    } else {
      pixmap_data = tool_data[i].icon_data;
    }
    
    style = gtk_widget_get_style(button);
    pixmap = gdk_pixmap_create_from_xpm_d(parent->window, &mask, 
					  &style->bg[GTK_STATE_NORMAL], 
					  pixmap_data);
    
    pixmapwidget = gtk_pixmap_new(pixmap, mask);
    
    gtk_misc_set_padding(GTK_MISC(pixmapwidget), 4, 4);
    
    gtk_container_add (GTK_CONTAINER (button), pixmapwidget);
    
    gtk_signal_connect (GTK_OBJECT (button), "toggled",
			GTK_SIGNAL_FUNC (tool_select_update),
			&tool_data[i].callback_data);
    
    gtk_signal_connect (GTK_OBJECT (button), "button_press_event",
			GTK_SIGNAL_FUNC (tool_button_press),
			&tool_data[i].callback_data);
    
    gtk_tooltips_set_tip (tool_tips, button,
			  gettext(tool_data[i].tool_desc), NULL);
    
    gtk_widget_show (pixmapwidget);
    gtk_widget_show (button);
  }
  gtk_widget_show(table);
}
Exemple #24
0
static DiaObject *
read_entity_text_dxf(FILE *filedxf, DxfData *data, DiagramData *dia)
{
    RGB_t color = { 0, };

    /* text data */
    Point location = {0, 0};
    real height = text_scale * coord_scale * measure_scale;
    real y_offset = 0;
    Alignment textalignment = ALIGN_LEFT;
    char *textvalue = NULL, *textp;
    
    DiaObjectType *otype = object_get_type("Standard - Text");
    Handle *h1, *h2;
    
    DiaObject *text_obj;
    Color text_colour;

    TextProperty *tprop;
    GPtrArray *props;

    Layer *layer = dia->active_layer;

    do {
        if (read_dxf_codes(filedxf, data) == FALSE) {
            return( NULL );
        }
        switch (data->code) {
        case  1: 
	   textvalue = g_strdup(data->value);
	   textp = textvalue;
	   /* FIXME - poor tab to space converter */
	   do 
	     {
		if( textp[0] == '^' && textp[1] == 'I' )
		  {
		     textp[0] = ' ';
		     textp[1] = ' ';
		     textp++;
		  }
		
	     }
	   while( *(++textp) != '\0' );
		
	   /*printf( "Found text: %s\n", textvalue );*/
            break;
        case  8: 
	    layer = layer_find_by_name(data->value, dia);
	    color = pal_get_rgb (_dxf_color_get_by_layer (layer));
            break;
        case 10: 
            location.x = g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
	   /*printf( "Found text location x: %f\n", location.x );*/
            break;
        case 11:
            location.x = g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
	   /*printf( "Found text location x: %f\n", location.x );*/
            break;
        case 20:
            location.y = (-1)*g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
	   /*printf( "Found text location y: %f\n", location.y );*/
            break;
        case 21:
            location.y = (-1)*g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
	   /*location.y = (-1)*g_ascii_strtod(data->value, NULL) / text_scale;*/
	   /*printf( "Found text location y: %f\n", location.y );*/
            break;
        case 40: 
            height = g_ascii_strtod(data->value, NULL) * text_scale * coord_scale * measure_scale;
	   /*printf( "text height %f\n", height );*/
            break;
	 case 62: 
	    color = pal_get_rgb (atoi(data->value));
            break;
        case 72: 
	   switch(atoi(data->value))
	     {
	      case 0:
		textalignment = ALIGN_LEFT;
                break;
	      case 1: 
		textalignment = ALIGN_CENTER;
                break;
	      case 2: 
		textalignment = ALIGN_RIGHT;
                break;	
	      case 3:
		/* FIXME - it's not clear what these are */
                break;
	      case 4: 
		/* FIXME - it's not clear what these are */
                break;	
	      case 5: 
		/* FIXME - it's not clear what these are */
                break;	
            }
	   break;
        case 73: 
	   switch(atoi(data->value))
	     {
	      case 0:
	      case 1:
		/* FIXME - not really the same vertical alignment */
		/* 0 = baseline */
		/* 1 = bottom */
		y_offset = 0;
                break;
	      case 2: 
		/* 2 = middle */
		y_offset = 0.5;
                break;	
	      case 3:
		/* 3 = top */
		y_offset = 1;
                break;	
            }
	   break;
        }
    } while(data->code != 0);
  
    location.y += y_offset * height;
    _color_init_from_rgb (&text_colour, color);
    text_obj = otype->ops->create(&location, otype->default_user_data,
                                  &h1, &h2);
    props = prop_list_from_descs(dxf_text_prop_descs,pdtpp_true);
    g_assert(props->len == 1);

    tprop = g_ptr_array_index(props,0);
    g_free(tprop->text_data);
    tprop->text_data = textvalue;
    tprop->attr.alignment = textalignment;
    tprop->attr.position.x = location.x;
    tprop->attr.position.y = location.y;

    attributes_get_default_font(&tprop->attr.font, &tprop->attr.height);
    tprop->attr.color = text_colour;
    tprop->attr.height = height;
        
    text_obj->ops->set_props(text_obj, props);
    prop_list_free(props);
   
    if (layer)
        layer_add_object(layer, text_obj);
    else
        return text_obj;

    return NULL; /* don't add it twice */
}
Exemple #25
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;
}
Exemple #26
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;
}
Exemple #27
0
void
app_init (int argc, char **argv)
{
  static gboolean nosplash = FALSE;
  static gboolean nonew = FALSE;
  static gboolean use_integrated_ui = TRUE;
  static gboolean credits = FALSE;
  static gboolean version = FALSE;
  static gboolean verbose = FALSE;
  static gboolean log_to_stderr = FALSE;
#ifdef HAVE_GNOME
  GnomeClient *client;
#endif
  static char *export_file_name = NULL;
  static char *export_file_format = NULL;
  static char *size = NULL;
  static char *show_layers = NULL;
  gboolean made_conversions = FALSE;
  GSList *files = NULL;
  static const gchar **filenames = NULL;
  int i = 0;

  gchar *export_format_string = 
     /* Translators:  The argument is a list of options, not to be translated */
    g_strdup_printf(_("Select the filter/format out of: %s"),
		    "cgm, dia, dxf, eps, eps-builtin, " EPS_PANGO
		    "fig, mp, plt, hpgl, png ("
#  if defined(HAVE_LIBPNG) && defined(HAVE_LIBART)
		    "png-libart, "
#  endif
#  ifdef HAVE_CAIRO
		    "cairo-png, cairo-alpha-png, "
#  endif
		    /* we always have pixbuf but don't know exactly all it's *few* save formats */
		    "pixbuf-png), jpg, "
		    "shape, svg, tex (pgf-tex, pstricks-tex), " WMF
		    "wpg");

  GOptionContext *context = NULL;
  static GOptionEntry options[] =
  {
    {"export", 'e', 0, G_OPTION_ARG_FILENAME, NULL /* &export_file_name */,
     N_("Export loaded file and exit"), N_("OUTPUT")},
    {"filter",'t', 0, G_OPTION_ARG_STRING, NULL /* &export_file_format */,
     NULL /* &export_format_string */, N_("TYPE") },
    {"size", 's', 0, G_OPTION_ARG_STRING, NULL,
     N_("Export graphics size"), N_("WxH")},
    {"show-layers", 'L', 0, G_OPTION_ARG_STRING, NULL,
     N_("Show only specified layers (e.g. when exporting). Can be either the layer name or a range of layer numbers (X-Y)"),
     N_("LAYER,LAYER,...")},
    {"nosplash", 'n', 0, G_OPTION_ARG_NONE, &nosplash,
     N_("Don't show the splash screen"), NULL },
    {"nonew", 'n', 0, G_OPTION_ARG_NONE, &nonew,
     N_("Don't create an empty diagram"), NULL },
    {"classic", '\0', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &use_integrated_ui,
     N_("Start classic user interface (no diagrams in tabs)"), NULL },
    {"log-to-stderr", 'l', 0, G_OPTION_ARG_NONE, &log_to_stderr,
     N_("Send error messages to stderr instead of showing dialogs."), NULL },
    {"input-directory", 'I', 0, G_OPTION_ARG_CALLBACK, _check_option_input_directory,
     N_("Directory containing input files"), N_("DIRECTORY")},
    {"output-directory", 'O', 0, G_OPTION_ARG_CALLBACK, _check_option_output_directory,
     N_("Directory containing output files"), N_("DIRECTORY")},
    {"credits", 'c', 0, G_OPTION_ARG_NONE, &credits,
     N_("Display credits list and exit"), NULL },
    {"verbose", 0, 0, G_OPTION_ARG_NONE, &verbose,
     N_("Generate verbose output"), NULL },
    {"version", 'v', 0, G_OPTION_ARG_NONE, &version,
     N_("Display version and exit"), NULL },
    { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, NULL /* &filenames */,
      NULL, NULL },
    { NULL }
  };
  
  /* for users of app_init() the default is interactive */
  dia_is_interactive = TRUE;

  options[0].arg_data = &export_file_name;
  options[1].arg_data = &export_file_format;
  options[1].description = export_format_string;
  options[2].arg_data = &size;
  options[3].arg_data = &show_layers;
  g_assert (strcmp (options[13].long_name, G_OPTION_REMAINING) == 0);
  options[13].arg_data = (void*)&filenames;

  argv0 = (argc > 0) ? argv[0] : "(none)";

#if GTK_CHECK_VERSION(2,24,0)
  /* ... use setlocale directly? */
#else
  gtk_set_locale();
#endif
  setlocale(LC_NUMERIC, "C");
  _setup_textdomains ();

  context = g_option_context_new(_("[FILE...]"));
  g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
#ifndef HAVE_GNOME
  /* avoid to add it a second time */
  g_option_context_add_group (context, gtk_get_option_group (FALSE));
#endif
  if (argv) {
    GError *error = NULL;

    if (!g_option_context_parse (context, &argc, &argv, &error)) {
      if (error) { /* IMO !error here is a bug upstream, triggered e.g. with --gdk-debug=updates */
	g_print ("%s", error->message);
	g_error_free (error);
      } else {
	g_print (_("Invalid option?"));
      }

      g_option_context_free(context);
      exit(1);
    }
    /* second level check of command line options, existance of input files etc. */
    if (filenames) {
      while (filenames[i] != NULL) {
	gchar *filename; 
	gchar *testpath;	  

	if (g_str_has_prefix (filenames[i], "file://")) {
	  filename = g_filename_from_uri (filenames[i], NULL, NULL);
	  if (!g_utf8_validate(filename, -1, NULL)) {
	    gchar *tfn = filename;
	    filename = g_filename_to_utf8(filename, -1, NULL, NULL, NULL);
	    g_free(tfn);
	  }
	} else
	  filename = g_filename_to_utf8 (filenames[i], -1, NULL, NULL, NULL);

	if (!filename) {
	  g_print (_("Filename conversion failed: %s\n"), filenames[i]);
	  continue;
	}

	if (g_path_is_absolute(filename))
	  testpath = filename;
	else
	  testpath = g_build_filename(input_directory ? input_directory : ".", filename, NULL);

	/* we still have a problem here, if GLib's file name encoding would not be utf-8 */
	if (g_file_test (testpath, G_FILE_TEST_IS_REGULAR))
	  files = g_slist_append(files, filename);
	else {
	  g_print (_("Missing input: %s\n"), filename);
	  g_free (filename);
	}
	if (filename != testpath)
	  g_free (testpath);
	++i;
      }
    }
    /* given some files to output, we are not starting up the UI */
    if (export_file_name || export_file_format || size)
      dia_is_interactive = FALSE;

  }

  if (argv && dia_is_interactive && !version) {
#ifdef HAVE_GNOME
    GnomeProgram *program =
      gnome_program_init (PACKAGE, VERSION, LIBGNOMEUI_MODULE,
			  argc, argv,
			  /* haven't found a quick way to pass GOption here */
			  GNOME_PARAM_GOPTION_CONTEXT, context,
			  GNOME_PROGRAM_STANDARD_PROPERTIES,
			  GNOME_PARAM_NONE);
    client = gnome_master_client();
    if(client == NULL) {
      g_warning(_("Can't connect to session manager!\n"));
    }
    else {
      g_signal_connect(G_OBJECT (client), "save_yourself",
		       G_CALLBACK (save_state), NULL);
      g_signal_connect(G_OBJECT (client), "die",
		       G_CALLBACK (session_die), NULL);
    }

    /* This smaller icon is 48x48, standard Gnome size */
    /* gnome_window_icon_set_default_from_file (GNOME_ICONDIR"/dia_gnome_icon.png");*/

#else
#  ifdef G_THREADS_ENABLED
    g_thread_init (NULL);
#  endif
    gtk_init(&argc, &argv);
#endif
  }
  else {
#ifdef G_THREADS_ENABLED
    g_thread_init (NULL);
#endif
    g_type_init();
    /*
     * On Windows there is no command line without display so that gtk_init is harmless. 
     * On X11 we need gtk_init_check() to avoid exit() just because there is no display 
     * running outside of X11.
     */
    if (!gtk_init_check(&argc, &argv))
      dia_log_message ("Running without display");
  }

  /* done with option parsing, don't leak */
  g_free(export_format_string);
  
  if (version) {
    gchar *ver_utf8;
    gchar *ver_locale;
#if (defined __TIME__) && (defined __DATE__)
    /* TRANSLATOR: 2nd and 3rd %s are time and date respectively. */
    ver_utf8 = g_strdup_printf(_("Dia version %s, compiled %s %s\n"), VERSION, __TIME__, __DATE__);
#else
    ver_utf8 = g_strdup_printf(_("Dia version %s\n"), VERSION);
#endif
    ver_locale = g_locale_from_utf8(ver_utf8, -1, NULL, NULL, NULL);
    printf("%s\n", ver_locale);
    g_free(ver_locale);
    g_free(ver_utf8);
    if (verbose)
      dump_dependencies();
    exit(0);
  }

  if (!dia_is_interactive)
    log_to_stderr = TRUE;

  libdia_init (   (dia_is_interactive ? DIA_INTERACTIVE : 0)
	       | (log_to_stderr ? DIA_MESSAGE_STDERR : 0)
	       | (verbose ? DIA_VERBOSE : 0) );

  print_credits(credits);

  if (dia_is_interactive) {
    create_user_dirs();

    if (!nosplash)
      app_splash_init("");

    /* Init cursors: */
    default_cursor = gdk_cursor_new(GDK_LEFT_PTR);
    ddisplay_set_all_cursor(default_cursor);
  }

  dia_register_plugins();
  dia_register_builtin_plugin(internal_plugin_init);

  load_all_sheets();     /* new mechanism */

  dia_log_message ("object defaults");
  {
    DiaContext *ctx = dia_context_new (_("Object Defaults"));
    dia_object_defaults_load (NULL, TRUE /* prefs.object_defaults_create_lazy */, ctx);
    dia_context_release (ctx);
  }
  debug_break();

  if (object_get_type("Standard - Box") == NULL) {
    message_error(_("Couldn't find standard objects when looking for "
		  "object-libs; exiting...\n"));
    g_critical( _("Couldn't find standard objects when looking for "
	    "object-libs in '%s'; exiting...\n"), dia_get_lib_directory("dia"));
    exit(1);
  }

  persistence_load();

  /** Must load prefs after persistence */
  prefs_init();

  if (dia_is_interactive) {

    /* further initialization *before* reading files */  
    active_tool = create_modify_tool();

    dia_log_message ("ui creation");
    if (use_integrated_ui) {
      create_integrated_ui();
    } else {
      create_toolbox();
      /* for the integrated ui case it is integrated */
      persistence_register_window_create("layer_window",
				         (NullaryFunc*)&layer_dialog_create);
    }
      
    /*fill recent file menu */
    recent_file_history_init();

    /* Set up autosave to check every 5 minutes */
    g_timeout_add_seconds(5*60, autosave_check_autosave, NULL);

#if 0 /* do we really open these automatically in the next session? */
    persistence_register_window_create("diagram_tree", 
                                       &diagram_tree_show);
#endif
    persistence_register_window_create("sheets_main_dialog",
				       (NullaryFunc*)&sheets_dialog_create);

    /* In current setup, we can't find the autosaved files. */
    /*autosave_restore_documents();*/

  }

  dia_log_message ("diagrams");
  made_conversions = handle_all_diagrams(files, export_file_name,
					 export_file_format, size, show_layers,
					 input_directory, output_directory);
					 
  if (dia_is_interactive && files == NULL && !nonew) {
    if (use_integrated_ui) {
      GList * list;
    
      file_new_callback(NULL);  
      list = dia_open_diagrams();
      if (list) {
        Diagram * diagram = list->data;
        diagram_update_extents(diagram);
        diagram->is_default = TRUE;
      }
    } else {
      gchar *filename = g_filename_from_utf8(_("Diagram1.dia"), -1, NULL, NULL, NULL);
      Diagram *diagram = new_diagram (filename);
      g_free(filename);
    
      if (diagram != NULL) {
        diagram_update_extents(diagram);
        diagram->is_default = TRUE;
        /* I think this is done in diagram_init() with a call to 
         * layer_dialog_update_diagram_list() */
        layer_dialog_set_diagram(diagram);
        new_display(diagram); 
      }
    }
  }
  g_slist_free(files);
  if (made_conversions) exit(0);

  dynobj_refresh_init();
  dia_log_message ("initialized");
}
Exemple #28
0
/* reads a polyline entity from the dxf file and creates a polyline object in dia*/
static DiaObject *
read_entity_polyline_dxf(FILE *filedxf, DxfData *data, DiagramData *dia)
{
    int i;
   
        /* polygon data */
    Point *p = NULL, start, end, center;
    
    DiaObjectType *otype = object_get_type("Standard - PolyLine");
    Handle *h1, *h2;
    
    DiaObject *polyline_obj;
    MultipointCreateData *pcd;

    Color line_colour;

    GPtrArray *props;

    real line_width = DEFAULT_LINE_WIDTH;
    real radius, start_angle = 0;
    LineStyle style = LINESTYLE_SOLID;
    Layer *layer = dia->active_layer;
    RGB_t color = { 0, };
    unsigned char closed = 0;
    int points = 0;
    real bulge = 0.0;
    int bulge_end = -1;
    gboolean bulge_x_avail = FALSE, bulge_y_avail = FALSE;

    do {
        if(read_dxf_codes(filedxf, data) == FALSE){
            return( NULL );
        }
        switch(data->code){
            case 0:
                if( !strcmp( data->value, "VERTEX" ))
                {
                    points++;
		
                    p = g_realloc( p, sizeof( Point ) * points );
		
                        /*printf( "Vertex %d\n", points );*/
		  
                }
		break;	   
            case 6:	 
                style = get_dia_linestyle_dxf(data->value);
                break;		
            case  8: 
                layer = layer_find_by_name(data->value, dia);
	        color = pal_get_rgb (_dxf_color_get_by_layer (layer));
                    /*printf( "layer: %s ", data->value );*/
                break;
            case 10:
                if( points != 0 )
                {
                    p[points-1].x = g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
                        /*printf( "P[%d].x: %f ", points-1, p[points-1].x );*/
		    bulge_x_avail = (bulge_end == points);
                }
                break;
            case 20: 
                if( points != 0 )
                {
                    p[points-1].y = (-1)*g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
                        /*printf( "P[%d].y: %f\n", points-1, p[points-1].y );*/
		    bulge_y_avail = (bulge_end == points);
                }
                break;
            case 39: 
                line_width = g_ascii_strtod(data->value, NULL) * WIDTH_SCALE;
                    /*printf( "width %f\n", line_width );*/
                break;
	    case 40: /* default starting width */
	    case 41: /* default ending width */
	        line_width = g_ascii_strtod(data->value, NULL) * WIDTH_SCALE;
		break;
            case 42:
                bulge = g_ascii_strtod(data->value, NULL);
		/* The bulge is meant to be _between_ two VERTEX, here: p[points-1] and p[points,]
		 * but we have not yet read the end point; so just remember the point to 'bulge to' */
		bulge_end = points+1;
		bulge_x_avail = bulge_y_avail = FALSE;
                break;
            case 62: 
                color = pal_get_rgb (atoi(data->value));
                break;
            case 70:
                closed = 1 & atoi( data->value );
                    /*printf( "closed %d %s", closed, data->value );*/
                break;
        }
	if (points == bulge_end && bulge_x_avail && bulge_y_avail) {
	    /* turn the last segment into a bulge */

                p = g_realloc( p, sizeof( Point ) * ( points + 10 ));

                if (points < 2)
                    continue;
                start = p[points-2];
                end = p[points-1];
	   
                radius = sqrt( pow( end.x - start.x, 2 ) + pow( end.y - start.y, 2 ))/2;

                center.x = start.x + ( end.x - start.x )/2;
                center.y = start.y + ( end.y - start.y )/2;
	   
                if( is_equal( start.x, end.x ))
                {
                    if( is_equal( start.y, end.y ))
                    {
                        continue; /* better than complaining? */
                        g_warning("Bad vertex bulge");
                    }
                    else if( start.y > center.y )
                    {
                            /*start_angle = 90.0;*/
                        start_angle = M_PI/2;
                    }
                    else
                    {
                            /*start_angle = 270.0;*/
                        start_angle = M_PI * 1.5;
                    }
                }
                else if( is_equal( start.y, end.y ))
                {
                    if( is_equal( start.x, end.x ))
                    {
                        continue;
                        g_warning("Bad vertex bulge");
                    }
                    else if( start.x > center.x )
                    {
                        start_angle = 0.0;
                    }
                    else
                    {
                        start_angle = M_PI;
                    }
                }
                else
                {
                    start_angle = atan( center.y - start.y /center.x - start.x );
                }
	   
                    /*printf( "start x %f end x %f center x %f\n", start.x, end.x, center.x );
                      printf( "start y %f end y %f center y %f\n", start.y, end.y, center.y );
                      printf( "bulge %s %f startx_angle %f\n", data->value, radius, start_angle );*/
	   
                for( i=(points-1); i<(points+9); i++ )
                {
                    p[i].x = center.x + cos( start_angle ) * radius;
                    p[i].y = center.y + sin( start_angle ) * radius;
                    start_angle += (-M_PI/10.0 * bulge);
                        /*printf( "i %d x %f y %f\n", i, p[i].x, p[i].y );*/
                }
                points += 10;
	   
                p[points-1] = end;
	  
	}
    } while( strcmp( data->value, "SEQEND" ));
   
    if( points == 0 )
    {
        printf( "No vertexes defined\n" );
        return( NULL );
    }
   
    pcd = g_new( MultipointCreateData, 1);
   
    if( closed )
    {
	otype = object_get_type("Standard - Polygon");
    }
   
    pcd->num_points = points;
    pcd->points = g_new( Point, pcd->num_points );
   
    memcpy( pcd->points, p, sizeof( Point ) * pcd->num_points );
   
    g_free( p );

    polyline_obj = otype->ops->create( NULL, pcd, &h1, &h2 );

    _color_init_from_rgb (&line_colour, color);

    props = g_ptr_array_new ();

    prop_list_add_line_colour (props, &line_colour);
    prop_list_add_line_width (props, line_width);
    prop_list_add_line_style (props, style, 1.0);

    polyline_obj->ops->set_props( polyline_obj, props );

    prop_list_free(props);

    if (layer)
       layer_add_object( layer, polyline_obj );
    else
       return polyline_obj;
       
    return NULL; /* don't add it twice */
}