1 /****************************************************************************
2 * Familia Lignum - Genealogical program *
3 * Copyright (C) 2011-2012 Rafał Długołęcki <rafal@dlugolecki.net.pl> *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; version 2 of the License. *
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 along *
15 * with this program; if not, write to the Free Software Foundation, Inc., *
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
18 ****************************************************************************/
25 #include "positions.h"
28 * Structure holding individual and position pair
30 struct familia_storage_individual_position {
31 struct familia_individual *ind;
36 * Structure holding family and position pair
38 struct familia_storage_family_position {
39 struct familia_family *fam;
44 * Structure holding individual and family positions
46 struct familia_storage_positions {
47 struct familia_storage_individual_position **individuals;
49 unsigned int individuals_no;
51 struct familia_storage_family_position **families;
53 unsigned int families_no;
57 * Global variable for storing positions of graphic objects.
59 * Example graphic object is an individual or family...
61 struct familia_storage_positions * storage_positions;
64 * Initializes storage for individual and family positions.
66 void _familia_storage_positions_init()
68 if (!storage_positions) {
69 storage_positions = malloc(sizeof(struct familia_storage_positions));
71 if (!storage_positions) {
72 debug("["__FILE__ "] There was a problem with allocating memory for storage of positions.\n");
75 storage_positions->individuals_no = 0;
76 storage_positions->families_no = 0;
82 * Frees storage for the positions
84 void _familia_storage_positions_free()
86 if (storage_positions) {
87 if (storage_positions->individuals) {
88 free(storage_positions->individuals);
91 if (storage_positions->families) {
92 free(storage_positions->families);
95 free(storage_positions);
96 storage_positions = NULL;
101 * Adds new position for the given individual.
103 * This function should be invoked only internaly and thus is not declared in
104 * header. Usage without caution can create duplicates in global variable
105 * storage_positions. Variable storage_positions is not prepared for such duplicates
106 * and this can provide to errors.
108 void _familia_positions_add_individual_position(struct familia_individual *individual, struct position *pos)
110 struct familia_storage_individual_position ** tmp = NULL;
111 unsigned int alloc_size = sizeof(struct familia_storage_individual_position *);
113 int size = (storage_positions->individuals_no + 1);
115 tmp = realloc(storage_positions->individuals, size * alloc_size);
118 storage_positions->individuals = tmp;
119 storage_positions->individuals[storage_positions->individuals_no]->ind = individual;
120 storage_positions->individuals[storage_positions->individuals_no]->pos = pos;
121 storage_positions->individuals_no++;
124 debug("There were problems with allocating memory for storage of individual positions->\n");
129 * Adds new position for the given family.
131 * This function should be invoked only internaly and thus is not declared in
132 * header. Usage without caution can create duplicates in global variable
133 * storage_positions. Variable storage_positions is not prepared for such duplicates
134 * and this can provide to errors.
136 void _familia_positions_add_family_position(struct familia_family *family, struct position *pos)
138 struct familia_storage_family_position ** tmp = NULL;
139 unsigned int alloc_size = sizeof(struct familia_storage_family_position *);
141 int size = (storage_positions->families_no + 1);
143 tmp = realloc(storage_positions->families, size * alloc_size);
146 storage_positions->families = tmp;
147 storage_positions->families[storage_positions->families_no]->fam = family;
148 storage_positions->families[storage_positions->families_no]->pos = pos;
149 storage_positions->families_no++;
152 debug("There were problems with allocating memory for storage of family positions.\n");
156 void familia_positions_set_individual_position(struct familia_individual *individual, struct position *pos)
158 struct position * p = NULL;
160 p = familia_position_get_individual_position(individual);
162 /* If not found create a new one */
164 _familia_positions_add_individual_position(individual, pos);
168 void familia_positions_set_family_position(struct familia_family *family, struct position *pos)
170 struct position * p = NULL;
172 p = familia_position_get_family_position(family);
174 /* If not found create a new one */
176 _familia_positions_add_family_position(family, pos);
180 struct position * familia_position_get_individual_position(struct familia_individual *individual)
186 * Uninitialized global. Return error.
188 if (!storage_positions || !storage_positions->individuals) {
189 debug("Trying to request individual position, but positions storage is not initialized.\n");
195 for (i = 0; i < storage_positions->individuals_no; i++) {
196 if (storage_positions->individuals[i]->ind->id == id) {
197 return storage_positions->individuals[i]->pos;
202 * Entry not found for a given individual. Return error.
207 struct position * familia_position_get_family_position(struct familia_family *family)
213 * Uninitialized global. Return error.
215 if (!storage_positions || !storage_positions->families) {
216 debug("Trying to request family position, but positions storage is not initialized.\n");
222 for (i = 0; i < storage_positions->families_no; i++) {
223 if (storage_positions->families[i]->fam->id == id) {
224 return storage_positions->families[i]->pos;
229 * Entry not found for a given individual. Return error.