1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 #include "dummy_dep.h"
32 object_init(Object
*obj
,
36 obj
->num_handles
= num_handles
;
38 obj
->handles
= g_new0(Handle
*,num_handles
);
42 obj
->num_connections
= num_connections
;
43 if (num_connections
>0)
44 obj
->connections
= g_new0(ConnectionPoint
*,num_connections
);
46 obj
->connections
= NULL
;
50 object_destroy(Object
*obj
)
52 object_unconnect_all(obj
);
58 g_free(obj
->connections
);
63 /* After this copying you have to fix up:
68 object_copy(Object
*from
, Object
*to
)
70 to
->type
= from
->type
;
71 to
->position
= from
->position
;
72 to
->bounding_box
= from
->bounding_box
;
74 to
->num_handles
= from
->num_handles
;
75 if (to
->handles
!= NULL
) g_free(to
->handles
);
76 if (to
->num_handles
>0)
77 to
->handles
= g_malloc(sizeof(Handle
*)*to
->num_handles
);
81 to
->num_connections
= from
->num_connections
;
82 if (to
->connections
!= NULL
) g_free(to
->connections
);
83 if (to
->num_connections
>0)
84 to
->connections
= g_malloc(sizeof(ConnectionPoint
*) * to
->num_connections
);
86 to
->connections
= NULL
;
93 destroy_object_list(GList
*list_to_be_destroyed
)
98 list
= list_to_be_destroyed
;
99 while (list
!= NULL
) {
100 obj
= (Object
*)list
->data
;
102 obj
->ops
->destroy(obj
);
105 list
= g_list_next(list
);
108 g_list_free(list_to_be_destroyed
);
112 object_add_handle(Object
*obj
, Handle
*handle
)
117 g_realloc(obj
->handles
, obj
->num_handles
*sizeof(Handle
*));
119 obj
->handles
[obj
->num_handles
-1] = handle
;
123 object_add_handle_at(Object
*obj
, Handle
*handle
, int pos
)
130 g_realloc(obj
->handles
, obj
->num_handles
*sizeof(Handle
*));
132 for (i
=obj
->num_handles
-1; i
> pos
; i
--) {
133 obj
->handles
[i
] = obj
->handles
[i
-1];
135 obj
->handles
[pos
] = handle
;
139 object_remove_handle(Object
*obj
, Handle
*handle
)
144 for (i
=0;i
<obj
->num_handles
;i
++) {
145 if (obj
->handles
[i
] == handle
)
150 message_error("Internal error, object_remove_handle: Handle doesn't exist");
154 for (i
=handle_nr
;i
<(obj
->num_handles
-1);i
++) {
155 obj
->handles
[i
] = obj
->handles
[i
+1];
157 obj
->handles
[obj
->num_handles
-1] = NULL
;
162 g_realloc(obj
->handles
, obj
->num_handles
*sizeof(Handle
*));
166 object_add_connectionpoint(Object
*obj
, ConnectionPoint
*conpoint
)
168 obj
->num_connections
++;
171 g_realloc(obj
->connections
,
172 obj
->num_connections
*sizeof(ConnectionPoint
*));
174 obj
->connections
[obj
->num_connections
-1] = conpoint
;
178 object_add_connectionpoint_at(Object
*obj
,
179 ConnectionPoint
*conpoint
, int pos
)
183 obj
->num_connections
++;
186 g_realloc(obj
->connections
,
187 obj
->num_connections
*sizeof(ConnectionPoint
*));
189 for (i
=obj
->num_connections
-1; i
> pos
; i
--) {
190 obj
->connections
[i
] = obj
->connections
[i
-1];
192 obj
->connections
[pos
] = conpoint
;
196 object_remove_connectionpoint(Object
*obj
, ConnectionPoint
*conpoint
)
200 object_remove_connections_to(conpoint
);
203 for (i
=0;i
<obj
->num_connections
;i
++) {
204 if (obj
->connections
[i
] == conpoint
)
209 message_error("Internal error, object_remove_connectionpoint: "
210 "ConnectionPoint doesn't exist");
214 for (i
=nr
;i
<(obj
->num_connections
-1);i
++) {
215 obj
->connections
[i
] = obj
->connections
[i
+1];
217 obj
->connections
[obj
->num_connections
-1] = NULL
;
219 obj
->num_connections
--;
222 g_realloc(obj
->connections
, obj
->num_connections
*sizeof(ConnectionPoint
*));
227 object_connect(Object
*obj
, Handle
*handle
,
228 ConnectionPoint
*connectionpoint
)
230 if (handle
->connect_type
==HANDLE_NONCONNECTABLE
) {
231 message_error("Error? trying to connect a non connectable handle.\n"
232 "Check this out...\n");
235 handle
->connected_to
= connectionpoint
;
236 connectionpoint
->connected
=
237 g_list_prepend(connectionpoint
->connected
, obj
);
241 object_unconnect(Object
*connected_obj
, Handle
*handle
)
243 ConnectionPoint
*connectionpoint
;
245 connectionpoint
= handle
->connected_to
;
247 if (connectionpoint
!=NULL
) {
248 connectionpoint
->connected
=
249 g_list_remove(connectionpoint
->connected
, connected_obj
);
250 handle
->connected_to
= NULL
;
255 object_remove_connections_to(ConnectionPoint
*conpoint
)
258 Object
*connected_obj
;
261 list
= conpoint
->connected
;
262 while (list
!= NULL
) {
263 connected_obj
= (Object
*)list
->data
;
265 for (i
=0;i
<connected_obj
->num_handles
;i
++) {
266 if (connected_obj
->handles
[i
]->connected_to
== conpoint
) {
267 connected_obj
->handles
[i
]->connected_to
= NULL
;
270 list
= g_list_next(list
);
272 g_list_free(conpoint
->connected
);
273 conpoint
->connected
= NULL
;
277 object_unconnect_all(Object
*obj
)
281 for (i
=0;i
<obj
->num_handles
;i
++) {
282 object_unconnect(obj
, obj
->handles
[i
]);
284 for (i
=0;i
<obj
->num_connections
;i
++) {
285 object_remove_connections_to(obj
->connections
[i
]);
289 void object_save(Object
*obj
, ObjectNode obj_node
)
291 data_add_point(new_attribute(obj_node
, "obj_pos"),
293 data_add_rectangle(new_attribute(obj_node
, "obj_bb"),
297 void object_load(Object
*obj
, ObjectNode obj_node
)
301 obj
->position
.x
= 0.0;
302 obj
->position
.y
= 0.0;
303 attr
= object_find_attribute(obj_node
, "obj_pos");
305 data_point( attribute_first_data(attr
), &obj
->position
);
307 obj
->bounding_box
.left
= obj
->bounding_box
.right
= 0.0;
308 obj
->bounding_box
.top
= obj
->bounding_box
.bottom
= 0.0;
309 attr
= object_find_attribute(obj_node
, "obj_bb");
311 data_rectangle( attribute_first_data(attr
), &obj
->bounding_box
);
314 /****** Object register: **********/
316 static guint
hash(gpointer key
)
318 char *string
= (char *)key
;
330 static gint
compare(gpointer a
, gpointer b
)
332 return strcmp((char *)a
, (char *)b
)==0;
335 static GHashTable
*object_type_table
= NULL
;
338 object_registry_init(void)
340 object_type_table
= g_hash_table_new( (GHashFunc
) hash
, (GCompareFunc
) compare
);
344 object_register_type(ObjectType
*type
)
346 if (g_hash_table_lookup(object_type_table
, type
->name
) != NULL
) {
347 message_warning("Several object-types were named %s.\n"
348 "Only first one will be used.\n"
349 "Some things might not work as expected.\n",
353 g_hash_table_insert(object_type_table
, type
->name
, type
);
356 static GSList
*object_types_nosheet_list
= NULL
;
359 object_type_detect_nosheet_callback(gpointer key
, gpointer value
,
363 gboolean found
= FALSE
;
366 static gchar
*ignore
[] = /* Ignore ObjectType's with these */
367 { /* 'name's. Mostly used for object */
368 "Group", /* types that are obsolete and thus */
369 /* are not found on any sheet. */
379 for (i
= 0; ignore
[i
]; i
++)
380 if (!strcmp(((ObjectType
*)(value
))->name
, ignore
[i
]))
383 /* We also ignore ObjectType's that begin with 'Standard -' */
385 sheet_name
= object_type_get_sheet_name((ObjectType
*)value
);
386 if (!strcmp(sheet_name
, "Standard"))
393 for (sheets_list
= get_sheets_list(); sheets_list
&& found
== FALSE
;
394 sheets_list
= g_slist_next(sheets_list
))
396 GSList
*objects_list
= ((Sheet
*)(sheets_list
)->data
)->objects
;
398 for ( ; objects_list
; objects_list
= g_slist_next(objects_list
))
400 if (!strcmp(key
, ((SheetObject
*)(objects_list
)->data
)->object_type
))
409 object_types_nosheet_list
= g_slist_append(object_types_nosheet_list
,
411 sizeof(ObjectType
)));
415 object_types_detect_nosheet(void)
417 g_slist_foreach(object_types_nosheet_list
, (GFunc
)g_free
, NULL
);
418 g_slist_free(object_types_nosheet_list
);
419 g_hash_table_foreach(object_type_table
,
420 (GHFunc
)object_type_detect_nosheet_callback
, NULL
);
421 return object_types_nosheet_list
;
425 object_type_get_sheet_name(ObjectType
*type
)
430 sheet_name
= g_strdup(type
->name
);
431 pos
= strchr(sheet_name
, '-');
433 return g_strchomp(g_strdelimit(sheet_name
, "-", '\0'));
439 object_type_strip_sheet_from_name(ObjectType
*type
)
443 pos
= strchr(type
->name
, '-');
451 object_get_type(char *name
)
453 return (ObjectType
*) g_hash_table_lookup(object_type_table
, name
);
458 object_return_false(Object
*obj
)
464 object_return_null(Object
*obj
)
470 object_return_void(Object
*obj
)
476 object_load_using_properties(const ObjectType
*type
,
477 ObjectNode obj_node
, int version
,
478 const char *filename
)
481 Point startpoint
= {0.0,0.0};
482 Handle
*handle1
,*handle2
;
484 obj
= type
->ops
->create(&startpoint
,NULL
, &handle1
,&handle2
);
485 object_load_props(obj
,obj_node
);
490 object_save_using_properties(Object
*obj
, ObjectNode obj_node
,
491 int version
, const char *filename
)
493 object_save_props(obj
,obj_node
);
496 Object
*object_copy_using_properties(Object
*obj
)
498 Point startpoint
= {0.0,0.0};
499 Handle
*handle1
,*handle2
;
500 Object
*newobj
= obj
->type
->ops
->create(&startpoint
,NULL
,
502 object_copy_props(newobj
,obj
);