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.
28 #include "dummy_dep.h"
31 object_init(Object
*obj
,
35 obj
->num_handles
= num_handles
;
37 obj
->handles
= g_new0(Handle
*,num_handles
);
41 obj
->num_connections
= num_connections
;
42 if (num_connections
>0)
43 obj
->connections
= g_new0(ConnectionPoint
*,num_connections
);
45 obj
->connections
= NULL
;
49 object_destroy(Object
*obj
)
51 object_unconnect_all(obj
);
57 g_free(obj
->connections
);
62 /* After this copying you have to fix up:
67 object_copy(Object
*from
, Object
*to
)
69 to
->type
= from
->type
;
70 to
->position
= from
->position
;
71 to
->bounding_box
= from
->bounding_box
;
73 to
->num_handles
= from
->num_handles
;
74 if (to
->handles
!= NULL
) g_free(to
->handles
);
75 if (to
->num_handles
>0)
76 to
->handles
= g_malloc(sizeof(Handle
*)*to
->num_handles
);
80 to
->num_connections
= from
->num_connections
;
81 if (to
->connections
!= NULL
) g_free(to
->connections
);
82 if (to
->num_connections
>0)
83 to
->connections
= g_malloc(sizeof(ConnectionPoint
*) * to
->num_connections
);
85 to
->connections
= NULL
;
91 pointer_hash(gpointer some_pointer
)
93 return (guint
) some_pointer
;
97 object_copy_list(GList
*list_orig
)
103 GHashTable
*hash_table
;
106 hash_table
= g_hash_table_new((GHashFunc
) pointer_hash
, NULL
);
110 while (list
!= NULL
) {
111 obj
= (Object
*)list
->data
;
112 obj_copy
= obj
->ops
->copy(obj
);
114 g_hash_table_insert(hash_table
, obj
, obj_copy
);
116 list_copy
= g_list_append(list_copy
, obj_copy
);
118 list
= g_list_next(list
);
121 /* Rebuild the connections between the objects in the list: */
123 while (list
!= NULL
) {
124 obj
= (Object
*)list
->data
;
125 obj_copy
= g_hash_table_lookup(hash_table
, obj
);
127 for (i
=0;i
<obj
->num_handles
;i
++) {
128 ConnectionPoint
*con_point
;
129 con_point
= obj
->handles
[i
]->connected_to
;
131 if ( con_point
!= NULL
) {
133 Object
*other_obj_copy
;
136 other_obj
= con_point
->object
;
137 other_obj_copy
= g_hash_table_lookup(hash_table
, other_obj
);
139 if (other_obj_copy
== NULL
)
140 break; /* other object was not on list. */
143 while (other_obj
->connections
[con_point_nr
] != con_point
) {
147 object_connect(obj_copy
, obj_copy
->handles
[i
],
148 other_obj_copy
->connections
[con_point_nr
]);
152 list
= g_list_next(list
);
155 g_hash_table_destroy(hash_table
);
161 object_list_move_delta(GList
*objects
, Point
*delta
)
168 while (list
!= NULL
) {
169 obj
= (Object
*) list
->data
;
172 point_add(&pos
, delta
);
174 obj
->ops
->move(obj
, &pos
);
176 list
= g_list_next(list
);
181 destroy_object_list(GList
*list_to_be_destroyed
)
186 list
= list_to_be_destroyed
;
187 while (list
!= NULL
) {
188 obj
= (Object
*)list
->data
;
190 obj
->ops
->destroy(obj
);
193 list
= g_list_next(list
);
196 g_list_free(list_to_be_destroyed
);
200 object_add_handle(Object
*obj
, Handle
*handle
)
205 g_realloc(obj
->handles
, obj
->num_handles
*sizeof(Handle
*));
207 obj
->handles
[obj
->num_handles
-1] = handle
;
211 object_add_handle_at(Object
*obj
, Handle
*handle
, int pos
)
218 g_realloc(obj
->handles
, obj
->num_handles
*sizeof(Handle
*));
220 for (i
=obj
->num_handles
-1; i
> pos
; i
--) {
221 obj
->handles
[i
] = obj
->handles
[i
-1];
223 obj
->handles
[pos
] = handle
;
227 object_remove_handle(Object
*obj
, Handle
*handle
)
232 for (i
=0;i
<obj
->num_handles
;i
++) {
233 if (obj
->handles
[i
] == handle
)
238 message_error("Internal error, object_remove_handle: Handle doesn't exist");
242 for (i
=handle_nr
;i
<(obj
->num_handles
-1);i
++) {
243 obj
->handles
[i
] = obj
->handles
[i
+1];
245 obj
->handles
[obj
->num_handles
-1] = NULL
;
250 g_realloc(obj
->handles
, obj
->num_handles
*sizeof(Handle
*));
254 object_add_connectionpoint(Object
*obj
, ConnectionPoint
*conpoint
)
256 obj
->num_connections
++;
259 g_realloc(obj
->connections
,
260 obj
->num_connections
*sizeof(ConnectionPoint
*));
262 obj
->connections
[obj
->num_connections
-1] = conpoint
;
266 object_add_connectionpoint_at(Object
*obj
,
267 ConnectionPoint
*conpoint
, int pos
)
271 obj
->num_connections
++;
274 g_realloc(obj
->connections
,
275 obj
->num_connections
*sizeof(ConnectionPoint
*));
277 for (i
=obj
->num_connections
-1; i
> pos
; i
--) {
278 obj
->connections
[i
] = obj
->connections
[i
-1];
280 obj
->connections
[pos
] = conpoint
;
284 object_remove_connectionpoint(Object
*obj
, ConnectionPoint
*conpoint
)
288 object_remove_connections_to(conpoint
);
291 for (i
=0;i
<obj
->num_connections
;i
++) {
292 if (obj
->connections
[i
] == conpoint
)
297 message_error("Internal error, object_remove_connectionpoint: "
298 "ConnectionPoint doesn't exist");
302 for (i
=nr
;i
<(obj
->num_connections
-1);i
++) {
303 obj
->connections
[i
] = obj
->connections
[i
+1];
305 obj
->connections
[obj
->num_connections
-1] = NULL
;
307 obj
->num_connections
--;
310 g_realloc(obj
->connections
, obj
->num_connections
*sizeof(ConnectionPoint
*));
315 object_connect(Object
*obj
, Handle
*handle
,
316 ConnectionPoint
*connectionpoint
)
318 if (handle
->connect_type
==HANDLE_NONCONNECTABLE
) {
319 message_error("Error? trying to connect a non connectable handle.\n"
320 "Check this out...\n");
323 handle
->connected_to
= connectionpoint
;
324 connectionpoint
->connected
=
325 g_list_prepend(connectionpoint
->connected
, obj
);
329 object_unconnect(Object
*connected_obj
, Handle
*handle
)
331 ConnectionPoint
*connectionpoint
;
333 connectionpoint
= handle
->connected_to
;
335 if (connectionpoint
!=NULL
) {
336 connectionpoint
->connected
=
337 g_list_remove(connectionpoint
->connected
, connected_obj
);
338 handle
->connected_to
= NULL
;
343 object_remove_connections_to(ConnectionPoint
*conpoint
)
346 Object
*connected_obj
;
349 list
= conpoint
->connected
;
350 while (list
!= NULL
) {
351 connected_obj
= (Object
*)list
->data
;
353 for (i
=0;i
<connected_obj
->num_handles
;i
++) {
354 if (connected_obj
->handles
[i
]->connected_to
== conpoint
) {
355 connected_obj
->handles
[i
]->connected_to
= NULL
;
358 list
= g_list_next(list
);
360 g_list_free(conpoint
->connected
);
361 conpoint
->connected
= NULL
;
365 object_unconnect_all(Object
*obj
)
369 for (i
=0;i
<obj
->num_handles
;i
++) {
370 object_unconnect(obj
, obj
->handles
[i
]);
372 for (i
=0;i
<obj
->num_connections
;i
++) {
373 object_remove_connections_to(obj
->connections
[i
]);
377 void object_save(Object
*obj
, ObjectNode obj_node
)
379 data_add_point(new_attribute(obj_node
, "obj_pos"),
381 data_add_rectangle(new_attribute(obj_node
, "obj_bb"),
385 void object_load(Object
*obj
, ObjectNode obj_node
)
389 obj
->position
.x
= 0.0;
390 obj
->position
.y
= 0.0;
391 attr
= object_find_attribute(obj_node
, "obj_pos");
393 data_point( attribute_first_data(attr
), &obj
->position
);
395 obj
->bounding_box
.left
= obj
->bounding_box
.right
= 0.0;
396 obj
->bounding_box
.top
= obj
->bounding_box
.bottom
= 0.0;
397 attr
= object_find_attribute(obj_node
, "obj_bb");
399 data_rectangle( attribute_first_data(attr
), &obj
->bounding_box
);
402 Layer
*dia_object_get_parent_layer(Object
*obj
) {
403 return obj
->parent_layer
;
406 /****** Object register: **********/
408 static guint
hash(gpointer key
)
410 char *string
= (char *)key
;
422 static gint
compare(gpointer a
, gpointer b
)
424 return strcmp((char *)a
, (char *)b
)==0;
427 static GHashTable
*object_type_table
= NULL
;
430 object_registry_init(void)
432 object_type_table
= g_hash_table_new( (GHashFunc
) hash
, (GCompareFunc
) compare
);
436 object_register_type(ObjectType
*type
)
438 if (g_hash_table_lookup(object_type_table
, type
->name
) != NULL
) {
439 message_warning("Several object-types were named %s.\n"
440 "Only first one will be used.\n"
441 "Some things might not work as expected.\n",
445 g_hash_table_insert(object_type_table
, type
->name
, type
);
449 object_registry_foreach (GHFunc func
, gpointer user_data
)
451 g_hash_table_foreach (object_type_table
, func
, user_data
);
455 object_get_type(char *name
)
457 return (ObjectType
*) g_hash_table_lookup(object_type_table
, name
);
462 object_return_false(Object
*obj
)
468 object_return_null(Object
*obj
)
474 object_return_void(Object
*obj
)
480 object_load_using_properties(const ObjectType
*type
,
481 ObjectNode obj_node
, int version
,
482 const char *filename
)
485 Point startpoint
= {0.0,0.0};
486 Handle
*handle1
,*handle2
;
488 obj
= type
->ops
->create(&startpoint
,NULL
, &handle1
,&handle2
);
489 object_load_props(obj
,obj_node
);
494 object_save_using_properties(Object
*obj
, ObjectNode obj_node
,
495 int version
, const char *filename
)
497 object_save_props(obj
,obj_node
);
500 Object
*object_copy_using_properties(Object
*obj
)
502 Point startpoint
= {0.0,0.0};
503 Handle
*handle1
,*handle2
;
504 Object
*newobj
= obj
->type
->ops
->create(&startpoint
,NULL
,
506 object_copy_props(newobj
,obj
,FALSE
);