Common subdirectories: dia.orig/objects/ER/CVS and dia/objects/ER/CVS
diff -uN dia.orig/objects/ER/er.c dia/objects/ER/er.c
--- dia.orig/objects/ER/er.c	2001-02-23 15:52:16.000000000 +0100
+++ dia/objects/ER/er.c	2004-04-12 21:33:24.000000000 +0200
@@ -34,14 +34,16 @@
 extern ObjectType relationship_type;
 extern ObjectType attribute_type;
 extern ObjectType participation_type;
+extern ObjectType specialisation_type;
+extern ObjectType subclass_type;
 
 DIA_PLUGIN_CHECK_INIT
 
 PluginInitResult
 dia_plugin_init(PluginInfo *info)
 {
-  if (!dia_plugin_info_init(info, "ER",
-			    _("Entity/Relationship diagram objects"),
+  if (!dia_plugin_info_init(info, "ER/EER",
+			    _("(Extended) Entity/Relationship diagram objects"),
 			    NULL, NULL))
     return DIA_PLUGIN_INIT_ERROR;
 
@@ -49,6 +51,8 @@
   object_register_type(&relationship_type);
   object_register_type(&attribute_type);
   object_register_type(&participation_type);
+  object_register_type(&specialisation_type);
+  object_register_type(&subclass_type);
 
   return DIA_PLUGIN_INIT_OK;
 }
diff -uN dia.orig/objects/ER/Makefile.am dia/objects/ER/Makefile.am
--- dia.orig/objects/ER/Makefile.am	2002-09-09 14:35:18.000000000 +0200
+++ dia/objects/ER/Makefile.am	2004-04-12 21:33:56.000000000 +0200
@@ -6,7 +6,9 @@
 			relationship.c \
 			attribute.c \
 			participation.c \
-			er.c
+			er.c \
+			specialisation.c \
+			subclass.c
 
 liber_objects_la_LDFLAGS = -export-dynamic -module -avoid-version
 
Common subdirectories: dia.orig/objects/ER/pixmaps and dia/objects/ER/pixmaps
diff -uN dia.orig/objects/ER/specialisation.c dia/objects/ER/specialisation.c
--- dia.orig/objects/ER/specialisation.c	1970-01-01 01:00:00.000000000 +0100
+++ dia/objects/ER/specialisation.c	2004-04-14 22:32:16.000000000 +0200
@@ -0,0 +1,516 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 2004 Pierre Ossman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <math.h>
+#include <string.h>
+
+#include "intl.h"
+#include "object.h"
+#include "element.h"
+#include "connectionpoint.h"
+#include "diarenderer.h"
+#include "attributes.h"
+#include "widgets.h"
+#include "properties.h"
+
+#include "pixmaps/specialisation.xpm"
+
+#define DEFAULT_WIDTH 0.5
+#define DEFAULT_HEIGHT 0.5
+#define FONT_HEIGHT 0.8
+#define TEXT_BORDER_WIDTH_X 0.2
+#define TEXT_BORDER_WIDTH_Y 0.1
+
+typedef struct _Specialisation Specialisation;
+
+struct _Specialisation {
+  Element element;
+
+  DiaFont *font;
+  real font_height;
+
+  ConnectionPoint connections[8];
+
+  gboolean disjoint;
+
+  real border_width;
+  Color border_color;
+  Color inner_color;
+};
+
+static real specialisation_distance_from(Specialisation *specialisation, Point *point);
+static void specialisation_select(Specialisation *specialisation, Point *clicked_point,
+			   DiaRenderer *interactive_renderer);
+static ObjectChange* specialisation_move_handle(Specialisation *specialisation, Handle *handle,
+					   Point *to, ConnectionPoint *cp,
+					   HandleMoveReason reason, 
+					   ModifierKeys modifiers);
+static ObjectChange* specialisation_move(Specialisation *specialisation, Point *to);
+static void specialisation_draw(Specialisation *specialisation, DiaRenderer *renderer);
+static void specialisation_update_data(Specialisation *specialisation);
+static Object *specialisation_create(Point *startpoint,
+			      void *user_data,
+			      Handle **handle1,
+			      Handle **handle2);
+static void specialisation_destroy(Specialisation *specialisation);
+static Object *specialisation_copy(Specialisation *specialisation);
+static PropDescription *
+specialisation_describe_props(Specialisation *specialisation);
+static void
+specialisation_get_props(Specialisation *specialisation, GPtrArray *props);
+static void
+specialisation_set_props(Specialisation *specialisation, GPtrArray *props);
+
+static void specialisation_save(Specialisation *specialisation, ObjectNode obj_node,
+			   const char *filename);
+static Object *specialisation_load(ObjectNode obj_node, int version,
+			      const char *filename);
+
+static ObjectTypeOps specialisation_type_ops =
+{
+  (CreateFunc) specialisation_create,
+  (LoadFunc)   specialisation_load,
+  (SaveFunc)   specialisation_save
+};
+
+ObjectType specialisation_type =
+{
+  "EER - Specialisation",   /* name */
+  0,                      /* version */
+  (char **) specialisation_xpm,  /* pixmap */
+  
+  &specialisation_type_ops       /* ops */
+};
+
+ObjectType *_specialisation_type = (ObjectType *) &specialisation_type;
+
+static ObjectOps specialisation_ops = {
+  (DestroyFunc)         specialisation_destroy,
+  (DrawFunc)            specialisation_draw,
+  (DistanceFunc)        specialisation_distance_from,
+  (SelectFunc)          specialisation_select,
+  (CopyFunc)            specialisation_copy,
+  (MoveFunc)            specialisation_move,
+  (MoveHandleFunc)      specialisation_move_handle,
+  (GetPropertiesFunc)   object_create_props_dialog,
+  (ApplyPropertiesFunc) object_apply_props_from_dialog,
+  (ObjectMenuFunc)      NULL,
+  (DescribePropsFunc)   specialisation_describe_props,
+  (GetPropsFunc)        specialisation_get_props,
+  (SetPropsFunc)        specialisation_set_props,
+};
+
+static PropDescription specialisation_props[] = {
+  ELEMENT_COMMON_PROPERTIES,
+  { "disjoint", PROP_TYPE_BOOL, PROP_FLAG_VISIBLE,
+    N_("Disjoint:"), NULL, NULL },
+  PROP_STD_LINE_WIDTH,
+  PROP_STD_LINE_COLOUR,
+  PROP_STD_FILL_COLOUR,
+  PROP_STD_TEXT_FONT,
+  PROP_STD_TEXT_HEIGHT,
+  PROP_DESC_END
+};
+
+static PropDescription *
+specialisation_describe_props(Specialisation *specialisation)
+{
+  if (specialisation_props[0].quark == 0)
+    prop_desc_list_calculate_quarks(specialisation_props);
+  return specialisation_props;
+}
+
+static PropOffset specialisation_offsets[] = {
+  ELEMENT_COMMON_PROPERTIES_OFFSETS,
+  { "disjoint", PROP_TYPE_BOOL, offsetof(Specialisation, disjoint) },
+  { "line_width", PROP_TYPE_REAL, offsetof(Specialisation, border_width) },
+  { "line_colour", PROP_TYPE_COLOUR, offsetof(Specialisation, border_color) },
+  { "fill_colour", PROP_TYPE_COLOUR, offsetof(Specialisation, inner_color) },
+  { "text_font", PROP_TYPE_FONT, offsetof(Specialisation, font) },
+  { "text_height", PROP_TYPE_REAL, offsetof(Specialisation, font_height) },
+  { NULL, 0, 0}
+};
+
+
+static void
+specialisation_get_props(Specialisation *specialisation, GPtrArray *props)
+{
+  object_get_props_from_offsets(&specialisation->element.object, 
+                                specialisation_offsets, props);
+}
+
+static void
+specialisation_set_props(Specialisation *specialisation, GPtrArray *props)
+{
+  object_set_props_from_offsets(&specialisation->element.object, 
+                                specialisation_offsets, props);
+  specialisation_update_data(specialisation);
+}
+
+static real
+specialisation_distance_from(Specialisation *specialisation, Point *point)
+{
+  Object *obj = &specialisation->element.object;
+  return distance_rectangle_point(&obj->bounding_box, point);
+}
+
+static void
+specialisation_select(Specialisation *specialisation, Point *clicked_point,
+	       DiaRenderer *interactive_renderer)
+{
+  element_update_handles(&specialisation->element);
+}
+
+static ObjectChange*
+specialisation_move_handle(Specialisation *specialisation, Handle *handle,
+		      Point *to, ConnectionPoint *cp,
+		      HandleMoveReason reason, ModifierKeys modifiers)
+{
+  assert(specialisation!=NULL);
+  assert(handle!=NULL);
+  assert(to!=NULL);
+
+  assert(handle->id < 8);
+  element_move_handle(&specialisation->element, handle->id, to, cp, 
+		      reason, modifiers);
+  specialisation_update_data(specialisation);
+
+  return NULL;
+}
+
+static ObjectChange*
+specialisation_move(Specialisation *specialisation, Point *to)
+{
+  specialisation->element.corner = *to;
+  specialisation_update_data(specialisation);
+
+  return NULL;
+}
+
+static void
+specialisation_draw(Specialisation *specialisation, DiaRenderer *renderer)
+{
+  DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
+  Point center;
+  Point p;
+  Element *elem;
+  gchar text[2];
+  
+  assert(specialisation != NULL);
+  assert(renderer != NULL);
+
+  elem = &specialisation->element;
+
+  center.x = elem->corner.x + elem->width/2;
+  center.y = elem->corner.y + elem->height/2;
+  
+  renderer_ops->set_fillstyle(renderer, FILLSTYLE_SOLID);
+  renderer_ops->fill_ellipse(renderer, &center,
+			      elem->width, elem->height,
+			      &specialisation->inner_color);
+
+  renderer_ops->set_linewidth(renderer, specialisation->border_width);
+  renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID);
+
+  renderer_ops->draw_ellipse(renderer, &center,
+			      elem->width, elem->height,
+			      &specialisation->border_color);
+			      
+  if (specialisation->disjoint)
+  	text[0] = 'd';
+  else
+  	text[0] = 'o';
+  text[1] = '\0';
+
+  p.x = elem->corner.x + elem->width / 2.0;
+  p.y = elem->corner.y + (elem->height - specialisation->font_height)/2.0 +
+         dia_font_ascent(text, specialisation->font, specialisation->font_height);
+
+  renderer_ops->set_font(renderer,  specialisation->font, specialisation->font_height);
+  renderer_ops->draw_string(renderer, text, 
+			     &p, ALIGN_CENTER, 
+			     &color_black);
+}
+
+static void
+specialisation_update_data(Specialisation *specialisation)
+{
+  Element *elem = &specialisation->element;
+  Object *obj = &elem->object;
+  Point center;
+  ElementBBExtras *extra = &elem->extra_spacing;
+  real half_x, half_y;
+  gchar text[2];
+  real text_width;
+
+  if (specialisation->disjoint)
+  	text[0] = 'd';
+  else
+  	text[0] = 'o';
+  text[1] = '\0';
+
+  text_width =
+    dia_font_string_width(text,
+                          specialisation->font, specialisation->font_height);
+
+  elem->width = text_width + 2*TEXT_BORDER_WIDTH_X;
+  elem->height = specialisation->font_height + 2*TEXT_BORDER_WIDTH_Y;
+  
+  if (elem->width > elem->height)
+  	elem->height = elem->width;
+  else
+  	elem->width = elem->height;
+
+  center.x = elem->corner.x + elem->width / 2.0;
+  center.y = elem->corner.y + elem->height / 2.0;
+  
+  half_x = elem->width * M_SQRT1_2 / 2.0;
+  half_y = elem->height * M_SQRT1_2 / 2.0;
+    
+  /* Update connections: */
+  connpoint_update(&specialisation->connections[0],
+		    center.x - half_x,
+		    center.y - half_y,
+		    DIR_NORTHWEST);
+  connpoint_update(&specialisation->connections[1],
+		    center.x,
+		    elem->corner.y,
+		    DIR_NORTH);
+  connpoint_update(&specialisation->connections[2],
+		    center.x + half_x,
+		    center.y - half_y,
+		    DIR_NORTHEAST);
+  connpoint_update(&specialisation->connections[3],
+		    elem->corner.x,
+		    center.y,
+		    DIR_WEST);
+  connpoint_update(&specialisation->connections[4],
+		    elem->corner.x + elem->width,
+		    elem->corner.y + elem->height / 2.0,
+		    DIR_EAST);
+  connpoint_update(&specialisation->connections[5],
+		    center.x - half_x,
+		    center.y + half_y,
+		    DIR_SOUTHWEST);
+  connpoint_update(&specialisation->connections[6],
+		    elem->corner.x + elem->width / 2.0,
+		    elem->corner.y + elem->height,
+		    DIR_SOUTH);
+  connpoint_update(&specialisation->connections[7],
+		    center.x + half_x,
+		    center.y + half_y,
+		    DIR_SOUTHEAST);
+
+  extra->border_trans = specialisation->border_width/2.0;
+  element_update_boundingbox(elem);
+
+  obj->position = elem->corner;
+
+  element_update_handles(elem);
+  
+}
+
+static Object *
+specialisation_create(Point *startpoint,
+	       void *user_data,
+  	       Handle **handle1,
+	       Handle **handle2)
+{
+  Specialisation *specialisation;
+  Element *elem;
+  Object *obj;
+  int i;
+
+  specialisation = g_malloc0(sizeof(Specialisation));
+  elem = &specialisation->element;
+  obj = &elem->object;
+  
+  obj->type = &specialisation_type;
+  obj->ops = &specialisation_ops;
+
+  elem->corner = *startpoint;
+  elem->width = DEFAULT_WIDTH;
+  elem->height = DEFAULT_HEIGHT;
+
+  specialisation->border_width =  attributes_get_default_linewidth();
+  specialisation->border_color = attributes_get_foreground();
+  specialisation->inner_color = attributes_get_background();
+
+  element_init(elem, 8, 8);
+
+  for (i=0;i<8;i++) {
+    obj->connections[i] = &specialisation->connections[i];
+    specialisation->connections[i].object = obj;
+    specialisation->connections[i].connected = NULL;
+  }
+
+  specialisation->disjoint = FALSE;
+  specialisation->font = dia_font_new_from_style(DIA_FONT_MONOSPACE,FONT_HEIGHT);
+  specialisation->font_height = FONT_HEIGHT;
+
+  specialisation_update_data(specialisation);
+
+  for (i=0;i<8;i++) {
+    obj->handles[i]->type = HANDLE_NON_MOVABLE;
+  }
+
+  *handle1 = NULL;
+  *handle2 = obj->handles[0];
+  return &specialisation->element.object;
+}
+
+static void
+specialisation_destroy(Specialisation *specialisation)
+{
+  element_destroy(&specialisation->element);
+}
+
+static Object *
+specialisation_copy(Specialisation *specialisation)
+{
+  int i;
+  Specialisation *newspecialisation;
+  Element *elem, *newelem;
+  Object *newobj;
+  
+  elem = &specialisation->element;
+  
+  newspecialisation = g_malloc0(sizeof(Specialisation));
+  newelem = &newspecialisation->element;
+  newobj = &newelem->object;
+
+  element_copy(elem, newelem);
+
+  newspecialisation->border_width = specialisation->border_width;
+  newspecialisation->border_color = specialisation->border_color;
+  newspecialisation->inner_color = specialisation->inner_color;
+
+  for (i=0;i<8;i++) {
+    newobj->connections[i] = &newspecialisation->connections[i];
+    newspecialisation->connections[i].object = newobj;
+    newspecialisation->connections[i].connected = NULL;
+    newspecialisation->connections[i].pos = specialisation->connections[i].pos;
+    newspecialisation->connections[i].last_pos = specialisation->connections[i].last_pos;
+  }
+  
+  newspecialisation->font = dia_font_ref(specialisation->font);
+  newspecialisation->font_height = specialisation->font_height;
+
+  newspecialisation->disjoint = specialisation->disjoint;
+
+  return &newspecialisation->element.object;
+}
+
+
+static void
+specialisation_save(Specialisation *specialisation, ObjectNode obj_node,
+	       const char *filename)
+{
+  element_save(&specialisation->element, obj_node);
+
+  data_add_real(new_attribute(obj_node, "border_width"),
+		specialisation->border_width);
+  data_add_color(new_attribute(obj_node, "border_color"),
+		 &specialisation->border_color);
+  data_add_color(new_attribute(obj_node, "inner_color"),
+		 &specialisation->inner_color);
+  data_add_boolean(new_attribute(obj_node, "disjoint"),
+		   specialisation->disjoint);
+  data_add_font (new_attribute(obj_node, "font"),
+		 specialisation->font);
+  data_add_real(new_attribute(obj_node, "font_height"),
+		specialisation->font_height);
+}
+
+static Object *specialisation_load(ObjectNode obj_node, int version,
+			      const char *filename)
+{
+  Specialisation *specialisation;
+  Element *elem;
+  Object *obj;
+  int i;
+  AttributeNode attr;
+
+  specialisation = g_malloc0(sizeof(Specialisation));
+  elem = &specialisation->element;
+  obj = &elem->object;
+  
+  obj->type = &specialisation_type;
+  obj->ops = &specialisation_ops;
+
+  element_load(elem, obj_node);
+
+  specialisation->border_width = 0.1;
+  attr = object_find_attribute(obj_node, "border_width");
+  if (attr != NULL)
+    specialisation->border_width =  data_real( attribute_first_data(attr) );
+
+  specialisation->border_color = color_black;
+  attr = object_find_attribute(obj_node, "border_color");
+  if (attr != NULL)
+    data_color(attribute_first_data(attr), &specialisation->border_color);
+  
+  specialisation->inner_color = color_white;
+  attr = object_find_attribute(obj_node, "inner_color");
+  if (attr != NULL)
+    data_color(attribute_first_data(attr), &specialisation->inner_color);
+  
+  attr = object_find_attribute(obj_node, "disjoint");
+  if (attr != NULL)
+    specialisation->disjoint = data_boolean(attribute_first_data(attr));
+
+  if (specialisation->font != NULL) {
+    /* This shouldn't happen, but doesn't hurt */
+    dia_font_unref(specialisation->font);
+    specialisation->font = NULL;
+  }
+  attr = object_find_attribute (obj_node, "font");
+  if (attr != NULL)
+	  specialisation->font = data_font (attribute_first_data (attr));
+
+  specialisation->font_height = FONT_HEIGHT;
+  attr = object_find_attribute (obj_node, "font_height");
+  if (attr != NULL)
+    specialisation->font_height = data_real( attribute_first_data(attr) );
+
+  element_init(elem, 8, 8);
+
+  for (i=0;i<8;i++) {
+    obj->connections[i] = &specialisation->connections[i];
+    specialisation->connections[i].object = obj;
+    specialisation->connections[i].connected = NULL;
+  }
+
+  if (specialisation->font == NULL) {
+	  specialisation->font = dia_font_new_from_style(DIA_FONT_MONOSPACE,
+                                              specialisation->font_height);
+  }
+
+  specialisation_update_data(specialisation);
+
+  for (i=0;i<8;i++) {
+    obj->handles[i]->type = HANDLE_NON_MOVABLE;
+  }
+
+  return &specialisation->element.object;
+}
diff -uN dia.orig/objects/ER/subclass.c dia/objects/ER/subclass.c
--- dia.orig/objects/ER/subclass.c	1970-01-01 01:00:00.000000000 +0100
+++ dia/objects/ER/subclass.c	2004-04-14 22:32:01.000000000 +0200
@@ -0,0 +1,406 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 2004 Pierre Ossman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <math.h>
+#include <string.h>
+
+#include "intl.h"
+#include "object.h"
+#include "element.h"
+#include "connection.h"
+#include "connectionpoint.h"
+#include "connpoint_line.h"
+#include "diarenderer.h"
+#include "attributes.h"
+#include "widgets.h"
+#include "properties.h"
+
+#include "pixmaps/subclass.xpm"
+
+#define ARC_WIDTH	1.0
+
+typedef struct _Subclass Subclass;
+
+struct _Subclass {
+  Connection connection;
+
+  ConnPointLine *cpl;
+
+  Color line_color;
+  real line_width;
+};
+
+static real subclass_distance_from(Subclass *subclass, Point *point);
+static void subclass_select(Subclass *subclass, Point *clicked_point,
+			   DiaRenderer *interactive_renderer);
+static ObjectChange* subclass_move_handle(Subclass *subclass, Handle *handle,
+					   Point *to, ConnectionPoint *cp,
+					   HandleMoveReason reason, 
+					   ModifierKeys modifiers);
+static ObjectChange* subclass_move(Subclass *subclass, Point *to);
+static void subclass_draw(Subclass *subclass, DiaRenderer *renderer);
+static void subclass_update_data(Subclass *subclass);
+static Object *subclass_create(Point *startpoint,
+			      void *user_data,
+			      Handle **handle1,
+			      Handle **handle2);
+static void subclass_destroy(Subclass *subclass);
+static Object *subclass_copy(Subclass *subclass);
+static PropDescription *
+subclass_describe_props(Subclass *subclass);
+static void
+subclass_get_props(Subclass *subclass, GPtrArray *props);
+static void
+subclass_set_props(Subclass *subclass, GPtrArray *props);
+
+static void subclass_save(Subclass *subclass, ObjectNode obj_node,
+			   const char *filename);
+static Object *subclass_load(ObjectNode obj_node, int version,
+			      const char *filename);
+
+static ObjectTypeOps subclass_type_ops =
+{
+  (CreateFunc) subclass_create,
+  (LoadFunc)   subclass_load,
+  (SaveFunc)   subclass_save
+};
+
+ObjectType subclass_type =
+{
+  "EER - Subclass",   /* name */
+  0,                      /* version */
+  (char **) subclass_xpm,  /* pixmap */
+  
+  &subclass_type_ops       /* ops */
+};
+
+ObjectType *_subclass_type = (ObjectType *) &subclass_type;
+
+static ObjectOps subclass_ops = {
+  (DestroyFunc)         subclass_destroy,
+  (DrawFunc)            subclass_draw,
+  (DistanceFunc)        subclass_distance_from,
+  (SelectFunc)          subclass_select,
+  (CopyFunc)            subclass_copy,
+  (MoveFunc)            subclass_move,
+  (MoveHandleFunc)      subclass_move_handle,
+  (GetPropertiesFunc)   object_create_props_dialog,
+  (ApplyPropertiesFunc) object_apply_props_from_dialog,
+  (ObjectMenuFunc)      NULL,
+  (DescribePropsFunc)   subclass_describe_props,
+  (GetPropsFunc)        subclass_get_props,
+  (SetPropsFunc)        subclass_set_props,
+};
+
+static PropDescription subclass_props[] = {
+  OBJECT_COMMON_PROPERTIES,
+  PROP_STD_LINE_WIDTH,
+  PROP_STD_LINE_COLOUR,
+  PROP_DESC_END
+};
+
+static PropDescription *
+subclass_describe_props(Subclass *subclass)
+{
+  if (subclass_props[0].quark == 0)
+    prop_desc_list_calculate_quarks(subclass_props);
+  return subclass_props;
+}
+
+static PropOffset subclass_offsets[] = {
+  OBJECT_COMMON_PROPERTIES_OFFSETS,
+  { "line_width", PROP_TYPE_REAL, offsetof(Subclass, line_width) },
+  { "line_colour", PROP_TYPE_COLOUR, offsetof(Subclass, line_color) },
+  { NULL, 0, 0}
+};
+
+
+static void
+subclass_get_props(Subclass *subclass, GPtrArray *props)
+{
+  object_get_props_from_offsets(&subclass->connection.object, 
+                                subclass_offsets, props);
+}
+
+static void
+subclass_set_props(Subclass *subclass, GPtrArray *props)
+{
+  object_set_props_from_offsets(&subclass->connection.object, 
+                                subclass_offsets, props);
+  subclass_update_data(subclass);
+}
+
+static real
+subclass_distance_from(Subclass *subclass, Point *point)
+{
+  Point *endpoints;
+
+  endpoints = &subclass->connection.endpoints[0]; 
+
+  return distance_line_point( &endpoints[0], &endpoints[1],
+                             subclass->line_width, point);
+}
+
+static void
+subclass_select(Subclass *subclass, Point *clicked_point,
+	       DiaRenderer *interactive_renderer)
+{
+  connection_update_handles(&subclass->connection);
+}
+
+static ObjectChange*
+subclass_move_handle(Subclass *subclass, Handle *handle,
+		      Point *to, ConnectionPoint *cp,
+		      HandleMoveReason reason, ModifierKeys modifiers)
+{
+  assert(subclass!=NULL);
+  assert(handle!=NULL);
+  assert(to!=NULL);
+
+  connection_move_handle(&subclass->connection, handle->id, to, cp, reason, modifiers);
+
+  subclass_update_data(subclass);
+
+  return NULL;
+}
+
+static ObjectChange*
+subclass_move(Subclass *subclass, Point *to)
+{
+  Point start_to_end;
+  Point *endpoints = &subclass->connection.endpoints[0]; 
+
+  start_to_end = endpoints[1];
+  point_sub(&start_to_end, &endpoints[0]);
+
+  endpoints[1] = endpoints[0] = *to;
+  point_add(&endpoints[1], &start_to_end);
+
+  subclass_update_data(subclass);
+
+  return NULL;
+}
+
+static void
+subclass_draw(Subclass *subclass, DiaRenderer *renderer)
+{
+  Point center, line[2];
+  Point *endpoints = &subclass->connection.endpoints[0];
+  double angle;
+
+  DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
+  
+  assert(subclass != NULL);
+  assert(renderer != NULL);
+
+  renderer_ops->set_linewidth(renderer, subclass->line_width);
+  renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID);
+  renderer_ops->set_linecaps(renderer, LINECAPS_BUTT);
+
+  renderer_ops->draw_line(renderer,
+			    &endpoints[0], 
+			    &endpoints[1],
+			    &subclass->line_color);
+
+  center.x = (endpoints[0].x + endpoints[1].x)/2;
+  center.y = (endpoints[0].y + endpoints[1].y)/2;
+  
+  angle = atan2(endpoints[1].x - endpoints[0].x,
+			  	endpoints[1].y - endpoints[0].y);
+  
+  renderer_ops->draw_arc(renderer,
+  				&center,
+  				ARC_WIDTH, ARC_WIDTH,
+  				angle * 180/M_PI + 180,
+  				angle * 180/M_PI,
+  				&subclass->line_color);
+  				
+  line[0].x = center.x + ARC_WIDTH/2 * sin(angle + M_PI_2);
+  line[0].y = center.y + ARC_WIDTH/2 * cos(angle + M_PI_2);
+  line[1].x = center.x + ARC_WIDTH/2 * M_SQRT2 * sin(angle + M_PI_2 + M_PI_4);
+  line[1].y = center.y + ARC_WIDTH/2 * M_SQRT2 * cos(angle + M_PI_2 + M_PI_4);
+
+  renderer_ops->draw_line(renderer,
+			    &line[0], 
+			    &line[1],
+			    &subclass->line_color);
+  				
+  line[0].x = center.x + ARC_WIDTH/2 * sin(angle - M_PI_2);
+  line[0].y = center.y + ARC_WIDTH/2 * cos(angle - M_PI_2);
+  line[1].x = center.x + ARC_WIDTH/2 * M_SQRT2 * sin(angle - M_PI_2 - M_PI_4);
+  line[1].y = center.y + ARC_WIDTH/2 * M_SQRT2 * cos(angle - M_PI_2 - M_PI_4);
+
+  renderer_ops->draw_line(renderer,
+			    &line[0], 
+			    &line[1],
+			    &subclass->line_color);
+}
+
+static void
+subclass_update_data(Subclass *subclass)
+{
+  Connection *conn = &subclass->connection;
+  Object *obj = &conn->object;
+  LineBBExtras *extra = &conn->extra_spacing;
+  Point start, end;
+
+  extra->start_trans = ARC_WIDTH/2 + (subclass->line_width / 2.0);
+  extra->end_trans   = ARC_WIDTH/2 + (subclass->line_width / 2.0);
+  extra->start_long  = (subclass->line_width / 2.0);
+  extra->end_long    = (subclass->line_width / 2.0);
+
+  connection_update_boundingbox(conn);
+  start = conn->endpoints[0];
+  end = conn->endpoints[1];
+
+  obj->position = conn->endpoints[0];
+ 
+  connpointline_update(subclass->cpl);
+  connpointline_putonaline(subclass->cpl,&start, &end);
+
+  connection_update_handles(conn);
+}
+
+static Object *
+subclass_create(Point *startpoint,
+	       void *user_data,
+  	       Handle **handle1,
+	       Handle **handle2)
+{
+  Subclass *subclass;
+  Connection *conn;
+  Object *obj;
+  Point defaultlen = { 1.0, 1.0 };
+
+  subclass = g_malloc0(sizeof(Subclass));
+
+  subclass->line_width = attributes_get_default_linewidth();
+  subclass->line_color = attributes_get_foreground();
+    
+  conn = &subclass->connection;
+  conn->endpoints[0] = *startpoint;
+  conn->endpoints[1] = *startpoint;
+  point_add(&conn->endpoints[1], &defaultlen);
+ 
+  obj = &conn->object;
+  
+  obj->type = &subclass_type;
+  obj->ops = &subclass_ops;
+
+  connection_init(conn, 2, 0);
+  
+  subclass->cpl = connpointline_create(obj,3);
+  
+  subclass_update_data(subclass);
+
+  *handle1 = obj->handles[0];
+  *handle2 = obj->handles[1];
+  return &subclass->connection.object;
+}
+
+static void
+subclass_destroy(Subclass *subclass)
+{
+  connection_destroy(&subclass->connection);
+}
+
+static Object *
+subclass_copy(Subclass *subclass)
+{
+  Subclass *newsubclass;
+  Connection *conn, *newconn;
+  Object *newobj;
+  int rcc = 0;
+
+  conn = &subclass->connection;
+  
+  newsubclass = g_malloc0(sizeof(Subclass));
+  newconn = &newsubclass->connection;
+  newobj = &newconn->object;
+  
+  connection_copy(conn, newconn);
+ 
+  newsubclass->cpl = connpointline_copy(newobj,subclass->cpl,&rcc);
+
+  newsubclass->line_color = subclass->line_color;
+  newsubclass->line_width = subclass->line_width;
+
+  subclass_update_data(subclass);
+
+  return &newsubclass->connection.object;
+}
+
+
+static void
+subclass_save(Subclass *subclass, ObjectNode obj_node,
+	       const char *filename)
+{
+  connection_save(&subclass->connection, obj_node);
+
+  connpointline_save(subclass->cpl,obj_node,"numcp");
+  
+  if (!color_equals(&subclass->line_color, &color_black))
+    data_add_color(new_attribute(obj_node, "line_color"),
+		   &subclass->line_color);
+  
+  if (subclass->line_width != 0.1)
+    data_add_real(new_attribute(obj_node, "line_width"),
+		  subclass->line_width);
+}
+
+static Object *subclass_load(ObjectNode obj_node, int version,
+			      const char *filename)
+{
+  Subclass *subclass;
+  Connection *conn;
+  Object *obj;
+  AttributeNode attr;
+
+  subclass = g_malloc0(sizeof(Subclass));
+
+  conn = &subclass->connection;
+  obj = &conn->object;
+
+  obj->type = &subclass_type;
+  obj->ops = &subclass_ops;
+
+  connection_load(conn, obj_node);
+
+  subclass->line_color = color_black;
+  attr = object_find_attribute(obj_node, "line_color");
+  if (attr != NULL)
+    data_color(attribute_first_data(attr), &subclass->line_color);
+
+  subclass->line_width = 0.1;
+  attr = object_find_attribute(obj_node, "line_width");
+  if (attr != NULL)
+    subclass->line_width = data_real(attribute_first_data(attr));
+
+  connection_init(conn, 2, 0);
+
+  subclass->cpl = connpointline_load(obj,obj_node,"numcp",1,NULL);
+
+  subclass_update_data(subclass);
+
+  return &subclass->connection.object;
+}
diff -uN dia.orig/sheets/ER.sheet.in dia/sheets/ER.sheet.in
--- dia.orig/sheets/ER.sheet.in	2003-04-30 23:03:38.000000000 +0200
+++ dia/sheets/ER.sheet.in	2004-04-12 21:33:06.000000000 +0200
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?> <!-- -*- xml -*- -->
 <sheet xmlns="http://www.lysator.liu.se/~alla/dia/dia-sheet-ns">
-  <_name>ER</_name>
-  <_description>Editor for Entity Relations Diagrams</_description>
+  <_name>ER/EER</_name>
+  <_description>Editor for (Extended) Entity Relations Diagrams</_description>
   <contents>
     <object name="ER - Entity" intdata="0">
       <_description>Entity</_description>
@@ -19,5 +19,11 @@
     <object name="ER - Participation">
       <_description>Participation</_description>
     </object>
+    <object name="EER - Specialisation">
+      <_description>Specialisation</_description>
+    </object>
+    <object name="EER - Subclass">
+      <_description>Subclass</_description>
+    </object>
   </contents>
 </sheet>
