From: Rafał Długołęcki Date: Thu, 6 Feb 2014 13:43:04 +0000 (+0100) Subject: Added reading date from the GEDCOM file and storing it in individual. X-Git-Url: https://git.dlugolecki.net.pl/?a=commitdiff_plain;h=d82f06ff5e5b5cef51709d4618779772931e5e90;p=familia.git Added reading date from the GEDCOM file and storing it in individual. Fixed documentation. --- diff --git a/Makefile.am b/Makefile.am index 62441d7..d503be4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -42,6 +42,7 @@ bin_familia_SOURCES = \ src/storage/positions.c \ src/math/positions.c \ src/math/camera.c \ + src/math/yearline.c \ src/graphics/individual.c \ src/graphics/family.c \ src/gedcom/familia_gedcom.c \ @@ -63,7 +64,7 @@ bin_familia_LDADD = \ $(GLU_LIBS) \ @GEDCOM_LIBS@ \ -L/usr/lib \ - -lzip + -lzip -lm bin_familia_LDFLAGS = $(LTLIBINTL) diff --git a/doc/model.dia b/doc/model.dia index f02a738..a278c15 100644 Binary files a/doc/model.dia and b/doc/model.dia differ diff --git a/src/gedcom/familia_gedcom.c b/src/gedcom/familia_gedcom.c index b547857..e92de3a 100644 --- a/src/gedcom/familia_gedcom.c +++ b/src/gedcom/familia_gedcom.c @@ -6,6 +6,8 @@ #include "../storage/individual.h" #include "../memory_stack.h" +#include "../debug.h" + Gedcom_ctxt familia_gedcom_header_start (Gedcom_rec rec, int level, Gedcom_val xref, @@ -14,11 +16,13 @@ Gedcom_ctxt familia_gedcom_header_start (Gedcom_rec rec, int parsed_tag, Gedcom_val parsed_value) { + assert(rec == REC_HEAD); + fprintf(stderr, "The header starts (l: %d, tag: %s, raw:%s) \n", level, tag, raw_value); return (Gedcom_ctxt)1; } -void familia_gedcom_header_end (Gedcom_rec rec, Gedcom_ctxt self) +void familia_gedcom_header_end (Gedcom_rec rec, Gedcom_ctxt self, Gedcom_val parsed_value) { /* context will print as "1" */ fprintf(stderr, "The header ends, context is %d\n", (int)self); @@ -79,16 +83,19 @@ Gedcom_ctxt familia_gedcom_family_start (Gedcom_rec rec, struct familia_family * family = NULL; struct xref_value *xr = GEDCOM_XREF_PTR(xref); + assert(rec == REC_FAM); + assert(parsed_tag == TAG_FAM); + family = familia_memory_stack_find(xr->string, FS_FAMILY); return (Gedcom_ctxt)family; } -/* -void familia_gedcom_family_end (Gedcom_rec rec, Gedcom_ctxt self) + +void familia_gedcom_family_end (Gedcom_rec rec, Gedcom_ctxt self, Gedcom_val parsed_value) { - familia_storage_add_family(familia_storage_get_current(), self); +/* familia_storage_add_family(familia_storage_get_current(), self);*/ } -*/ + Gedcom_ctxt familia_gedcom_individual_start (Gedcom_rec rec, int level, Gedcom_val xref, @@ -100,16 +107,19 @@ Gedcom_ctxt familia_gedcom_individual_start (Gedcom_rec rec, struct familia_individual * individual = NULL; struct xref_value *xr = GEDCOM_XREF_PTR(xref); + assert(rec == REC_INDI); + assert(parsed_tag == TAG_INDI); + individual = familia_memory_stack_find(xr->string, FS_INDIVIDUAL); return (Gedcom_ctxt)individual; } -/* -void familia_gedcom_individual_end (Gedcom_rec rec, Gedcom_ctxt self) + +void familia_gedcom_individual_end (Gedcom_rec rec, Gedcom_ctxt self, Gedcom_val parsed_value) { - familia_storage_add_individual(familia_storage_get_current(), self); +/* familia_storage_add_individual(familia_storage_get_current(), self);*/ } -*/ + Gedcom_ctxt familia_gedcom_individual_set_first_name(Gedcom_elt elt, Gedcom_ctxt ctxt, int level, @@ -118,6 +128,9 @@ Gedcom_ctxt familia_gedcom_individual_set_first_name(Gedcom_elt elt, int parsed_tag, Gedcom_val parsed_value) { + assert(elt == ELT_SUB_PERS_NAME); + assert(parsed_tag == TAG_NAME); + familia_individual_set_first_name(ctxt, GEDCOM_STRING(parsed_value)); return ctxt; } @@ -137,6 +150,8 @@ Gedcom_ctxt familia_gedcom_individual_last_name_start(Gedcom_elt elt, int parsed_tag, Gedcom_val parsed_value) { + assert(elt == ELT_SUB_PERS_NAME_SURN); + if (GEDCOM_IS_STRING(parsed_value)) { familia_individual_set_last_name(ctxt, GEDCOM_STRING(parsed_value)); } @@ -160,7 +175,12 @@ Gedcom_ctxt familia_gedcom_individual_add_family(Gedcom_elt elt, Gedcom_val parsed_value) { void * family = NULL; - struct xref_value *xr = GEDCOM_XREF_PTR(parsed_value); + struct xref_value *xr = NULL; + + assert(elt == ELT_SUB_FAMS); + assert(parsed_tag == TAG_FAMS); + + xr = GEDCOM_XREF_PTR(parsed_value); family = familia_memory_stack_find(xr->string, FS_FAMILY); familia_individual_add_family(ctxt, family); @@ -181,7 +201,12 @@ Gedcom_ctxt familia_gedcom_individual_set_parents(Gedcom_elt elt, { void * child = NULL; /* XREF_PTR(FAM) */ - struct xref_value *xr = GEDCOM_XREF_PTR(parsed_value); + struct xref_value *xr = NULL; + + assert(elt == ELT_FAM_CHIL); + assert(parsed_tag == TAG_CHIL); + + xr = GEDCOM_XREF_PTR(parsed_value); child = familia_memory_stack_find(xr->string, FS_INDIVIDUAL); familia_individual_set_parents(child, ctxt); @@ -202,7 +227,12 @@ Gedcom_ctxt familia_gedcom_family_add_child(Gedcom_elt elt, { void * family = NULL; /* XREF_PTR(FAM) */ - struct xref_value *xr = GEDCOM_XREF_PTR(parsed_value); + struct xref_value *xr = NULL; + + assert(elt == ELT_SUB_FAMC); + assert(parsed_tag == TAG_FAMC); + + xr = GEDCOM_XREF_PTR(parsed_value); family = familia_memory_stack_find(xr->string, FS_FAMILY); familia_family_add_child(family, ctxt); @@ -224,7 +254,12 @@ Gedcom_ctxt familia_gedcom_family_set_parent1(Gedcom_elt elt, { void * parent = NULL; /* XREF_PTR(INDI) */ - struct xref_value *xr = GEDCOM_XREF_PTR(parsed_value); + struct xref_value *xr = NULL; + + assert(elt == ELT_FAM_HUSB); + assert(parsed_tag == TAG_HUSB); + + xr = GEDCOM_XREF_PTR(parsed_value); parent = familia_memory_stack_find(xr->string, FS_FAMILY); /* ctxt: REC_FAM */ @@ -247,7 +282,12 @@ Gedcom_ctxt familia_gedcom_family_set_parent2(Gedcom_elt elt, { void * parent = NULL; /* XREF_PTR(INDI) */ - struct xref_value *xr = GEDCOM_XREF_PTR(parsed_value); + struct xref_value *xr = NULL; + + assert(elt == ELT_FAM_WIFE); + assert(parsed_tag == TAG_WIFE); + + xr = GEDCOM_XREF_PTR(parsed_value); parent = familia_memory_stack_find(xr->string, FS_FAMILY); /* ctxt: REC_FAM */ @@ -256,13 +296,70 @@ Gedcom_ctxt familia_gedcom_family_set_parent2(Gedcom_elt elt, return ctxt; } -/* -void familia_gedcom_individual_family_end(Gedcom_elt elt, +/** + * Sets date for the current event. Currently supports only individual birth. + * TODO: Implement all events. + */ +Gedcom_ctxt familia_gedcom_event_set_date(Gedcom_elt elt, + Gedcom_ctxt ctxt, + int level, + char* tag, + char* raw_value, + int parsed_tag, + Gedcom_val parsed_value) +{ + struct fged_timestampable_ctxt * tctxt = ctxt; + + switch(tctxt->type) { + case BIRTH: { + struct date_value dv; + struct familia_individual * ind = NULL; + + assert(GEDCOM_IS_DATE(parsed_value)); + + ind = ((struct fged_ctxt *)ctxt)->object; + dv = GEDCOM_DATE(parsed_value); + + familia_individual_set_birth_date(ind, dv); + break; + } + }; + + return ctxt; +} +Gedcom_ctxt familia_gedcom_timestampable_ctxt_wrap(Gedcom_elt elt, + Gedcom_ctxt ctxt, + int level, + char* tag, + char* raw_value, + int parsed_tag, + Gedcom_val parsed_value) +{ + struct fged_timestampable_ctxt * tctxt = NULL; + tctxt = (struct fged_timestampable_ctxt *)malloc(sizeof(struct fged_timestampable_ctxt)); + tctxt->ctxt = ctxt; + tctxt->type = UNSET; + + switch(elt) { + case ELT_SUB_INDIV_BIRT: + tctxt->type = BIRTH; + break; + } + return tctxt; +} + +void familia_gedcom_timestampable_ctxt_unwrap(Gedcom_elt elt, Gedcom_ctxt ctxt, Gedcom_ctxt self, Gedcom_val parsed_value) { -}*/ + struct fged_timestampable_ctxt * tctxt = NULL; + + tctxt = self; + + self = tctxt->ctxt; + free(tctxt); +} void familia_gedcom_error (Gedcom_msg_type type, char *msg) { @@ -277,9 +374,9 @@ void familia_gedcom_init() gedcom_subscribe_to_record(REC_HEAD, familia_gedcom_header_start, familia_gedcom_header_end); /* Create and set family as current (set to ctxt) */ - gedcom_subscribe_to_record(REC_FAM, familia_gedcom_family_start, NULL); + gedcom_subscribe_to_record(REC_FAM, familia_gedcom_family_start, familia_gedcom_family_end); /* Create and set individual as current (set to ctxt) */ - gedcom_subscribe_to_record(REC_INDI, familia_gedcom_individual_start, NULL); + gedcom_subscribe_to_record(REC_INDI, familia_gedcom_individual_start, familia_gedcom_individual_end); gedcom_subscribe_to_element(ELT_HEAD_SOUR, familia_gedcom_header_source_start, NULL); gedcom_subscribe_to_element(ELT_HEAD_SOUR_VERS, familia_gedcom_header_version_start, NULL); /* Set in current individual first name */ @@ -296,6 +393,9 @@ void familia_gedcom_init() gedcom_subscribe_to_element(ELT_FAM_HUSB, familia_gedcom_family_set_parent1, NULL); /* Set in current family second parent (e.g. wife) */ gedcom_subscribe_to_element(ELT_FAM_WIFE, familia_gedcom_family_set_parent2, NULL); + + gedcom_subscribe_to_element(ELT_SUB_EVT_DATE, familia_gedcom_event_set_date, NULL); + gedcom_subscribe_to_element(ELT_SUB_INDIV_BIRT, familia_gedcom_timestampable_ctxt_wrap, familia_gedcom_timestampable_ctxt_unwrap); familia_memory_stack_init(); } diff --git a/src/gedcom/familia_gedcom.h b/src/gedcom/familia_gedcom.h index 0cd88a9..d060171 100644 --- a/src/gedcom/familia_gedcom.h +++ b/src/gedcom/familia_gedcom.h @@ -22,11 +22,43 @@ #include +#include "../storage/storage.h" + /** * @file familia_gedcom.h * @brief GEDCOM Parser integration code. */ +/** + * Familia - Gedcom context. + * Used for passing current object/value between different states. + */ +struct fged_ctxt { + /** Currently parsed object, stored in storage */ + void * object; + + /** Type of current object */ + enum familia_storage_type type; +}; + +enum fged_timestamp_type { + UNSET, + + BIRTH, + +}; + +/** + * Familia - Gedcom timestampable context. + */ +struct fged_timestampable_ctxt { + /** Parent context */ + struct familia_gedcom_parser_ctxt * ctxt; + + /** Type of the timestamp */ + enum fged_timestamp_type type; +}; + /** * Initializes integration with gedcom-parse library */ diff --git a/src/math/camera.c b/src/math/camera.c index 3ab2cfc..7007524 100644 --- a/src/math/camera.c +++ b/src/math/camera.c @@ -1,6 +1,15 @@ - #include +#include "../storage/storage.h" + GLdouble camera_pos_x = 0; GLdouble camera_pos_y = 0; -GLdouble camera_pos_z = 0; \ No newline at end of file +GLdouble camera_pos_z = 0; + +/** + * + */ +struct position * camera_position_reset() +{ + /**/ +} \ No newline at end of file diff --git a/src/math/positions.c b/src/math/positions.c index 03d5b44..bf6b606 100644 --- a/src/math/positions.c +++ b/src/math/positions.c @@ -1,13 +1,72 @@ #include +#include #include "positions.h" +#include "yearline.h" #include "storage/individual.h" #include "storage/family.h" +#include "../debug.h" + +#define FAMILY_AVAIL_RANGE 180 + struct position * calculate_individual_position(struct familia_individual * individual) { -/* TODO: Implement this function*/ - return NULL; + struct position * pos = NULL; + struct familia_family * parents = NULL; + unsigned int children_no = 1; + int nth = 0; + + parents = familia_individual_get_parents(individual); + if (parents == NULL) { + debug("TODO: Calculate position for root individual."); + return NULL; + } + + nth = familia_individual_nth_child_of_family(individual, parents); + if (nth < 0) { + debug("Cannot calculate child number."); + return NULL; + } + + children_no = parents->children_no; + + if (children_no == 0) { + debug("Children number mismatch: I have child of family, " \ + "but parents does not have any children!"); + return NULL; + } + + pos = (struct position *)malloc(sizeof(struct position)); + pos->x = 0; + pos->y = 0; + pos->z = 0; + + /* If there is only one child in family, place it vertically + * over the family (do not change x and z). For all other + * calculate these positions. + */ + if (children_no != 1) { + /* Angle by which every child is rotated. */ + float theta = 0; + /* Angle by which this child will be rotated */ + float alpha = 0; + theta = FAMILY_AVAIL_RANGE / children_no; + + /* We subtract from FAMILY_AVAIL_RANGE (e.g. 180), + * to count angle from left instead of from right. + * This makes oldest children display in this order. + */ + alpha = FAMILY_AVAIL_RANGE - theta * nth; + + pos->x = cos(alpha); + pos->z = sin(alpha); + } + + /* pos.y is a local coordinate now. */ + pos->y = convert_date_to_height(NULL); + + return pos; } struct position * calculate_family_position(struct familia_family * family) diff --git a/src/storage/individual.c b/src/storage/individual.c index 33a0a08..f5a94df 100644 --- a/src/storage/individual.c +++ b/src/storage/individual.c @@ -21,6 +21,7 @@ struct familia_individual * familia_individual_new() individual->families = NULL; individual->families_no = 0; individual->parents = NULL; + individual->birth = NULL; return individual; } @@ -53,6 +54,11 @@ void familia_individual_free(struct familia_individual * individual) individual->parents = NULL; } + if (individual->birth) { + free(individual->birth); + individual->birth = NULL; + } + free(individual); } @@ -190,3 +196,33 @@ void familia_individual_remove_parents(struct familia_individual * individual) { individual->parents = NULL; } + +int familia_individual_nth_child_of_family(struct familia_individual * individual, struct familia_family * family) +{ + unsigned int i; + unsigned int children_no = family->children_no; + + for (i = 0; i < children_no; i++) { + if (family->children[i]->id == individual->id) { + return i; + } + } + + return -1; +} + +void familia_individual_set_birth_date(struct familia_individual * individual, struct date_value dv) +{ + /* TODO: Add multiple birth dates (in case there are many different sources) */ + if (!individual->birth) { + struct date_value * date = NULL; + date = gedcom_new_date_value(NULL); + + /* Just copy parsed date_value to newly allocated variable... */ + memcpy(date, &dv, sizeof(struct date_value)); + individual->birth = date; + } + else { + fprintf(stderr, "> Date has been already set, ignoring new one: %s\n", gedcom_date_to_string(&dv)); + } +} \ No newline at end of file diff --git a/src/storage/individual.h b/src/storage/individual.h index 87045c1..745698b 100644 --- a/src/storage/individual.h +++ b/src/storage/individual.h @@ -20,18 +20,26 @@ #ifndef _FAMILIA_INDIVIDUAL_H #define _FAMILIA_INDIVIDUAL_H +#include + #include "family.h" +/** + * @file storage/individual.h + * @brief Code for managing individuals from the family. + * + */ + /** * Structure holding individual data. */ struct familia_individual { /** Individual identifier */ unsigned int id; - + /** Individual first name */ char * first_name; - + /** Individual last name */ char * last_name; @@ -43,6 +51,13 @@ struct familia_individual { /** Parent family. Family this individual comes from. */ struct familia_family * parents; + + /** + * Birth date of individual. + * Could be exact date, range or unrecognized. You can find more info in + * gedcom-parse documentation. + */ + struct date_value * birth; }; /** @@ -54,51 +69,51 @@ struct familia_individual * familia_individual_new(); /** * Frees allocated memory of the given individual - * DISCLAIMER! This function does not free memory of linked families. You have to - * remove them manually from storage. - * @parameter individual to free + * @attention This function does not free memory of linked families. You have to + * remove them manually from @ref familia_storage, by using @ref familia_storage_free. + * @param individual individual to free */ void familia_individual_free(struct familia_individual * individual); /** * Sets first name of the given individual - * @parameter individual to set first name - * @parameter first name to set + * @param individual individual to set first name + * @param first_name first name to set */ void familia_individual_set_first_name(struct familia_individual * individual, char * first_name); /** * Gets first name of the given individual - * @parameter individual from whom get the first name + * @param individual individual from whom get the first name * @return individuals first name */ char * familia_individual_get_first_name(struct familia_individual * individual); /** * Sets last name of the given individual - * @parameter individual to set last name - * @parameter last name to set + * @param individual individual to set last name + * @param last_name last name to set */ void familia_individual_set_last_name(struct familia_individual * individual, char * last_name); /** * Gets last name of the given individual - * @parameter individual from whom get the last name + * @param individual individual from whom get the last name * @return individuals last name */ char * familia_individual_get_last_name(struct familia_individual * individual); /** * Adds family to the given individual - * @parameter individual to set last name - * @parameter last name to set + * @param individual individual to set last name + * @param family last name to set */ void familia_individual_add_family(struct familia_individual * individual, struct familia_family * family); /** * Gets family with the given id of the given individual - * @parameter individual from whom get the family - * @parameter family id of the individual + * @param individual individual from whom get the family + * @param id family id of the individual * @return selected family or NULL if such does not exists or index is out of * array bounds */ @@ -108,22 +123,21 @@ struct familia_family * familia_individual_get_family_by_id(struct familia_indiv * Removes family with the given id from the given individual * DISCLAIMER! This function does not free memory of linked families. You have to * remove them manually from storage. - * @parameter individual from whom family will be removed - * @parameter family id of the individual + * @param individual individual from whom family will be removed + * @param id family id of the individual */ void familia_individual_remove_family_by_id(struct familia_individual * individual, unsigned int id); /** * Sets parents family of the given individual - * @parameter individual to set parents - * @parameter parents to set + * @param individual individual to set parents + * @param family parents to set */ void familia_individual_set_parents(struct familia_individual * individual, struct familia_family * family); /** * Gets family with the given id of the given individual - * @parameter individual from whom get the family - * @parameter family id of the individual + * @param individual individual from whom get the parents * @return individuals last name */ struct familia_family * familia_individual_get_parents(struct familia_individual * individual); @@ -132,8 +146,24 @@ struct familia_family * familia_individual_get_parents(struct familia_individual * Removes parents from the given individual * DISCLAIMER! This function does not free memory of linked family. You have to * remove them manually from storage. - * @parameter individual from whom parents will be removed + * @param individual individual from whom parents will be removed */ void familia_individual_remove_parents(struct familia_individual * individual); +/** + * Calculates family number in order + * @return child number of individual in the given family, -1 on error or if child does not belong to family. + */ +int familia_individual_nth_child_of_family(struct familia_individual * individual, struct familia_family * family); + +/** + * Sets individual birth date. + * Date value is copied individual. Value is released on individual free(). + * @see familia_individual_free + * @param individual individual to set birth date + * @param dv date of the birth (exact, or bounds) + * @return child number of individual in the given family, -1 on error or if child does not belong to family. + */ +void familia_individual_set_birth_date(struct familia_individual * individual, struct date_value dv); + #endif /*_FAMILIA_INDIVIDUAL_H */ diff --git a/src/storage/positions.c b/src/storage/positions.c index e628997..8cb8ebe 100644 --- a/src/storage/positions.c +++ b/src/storage/positions.c @@ -19,6 +19,7 @@ #include #include +#include #include "../debug.h" @@ -229,5 +230,4 @@ struct position * familia_position_get_family_position(struct familia_family *fa * Entry not found for a given individual. Return error. */ return NULL; -} - +} \ No newline at end of file diff --git a/src/storage/storage.h b/src/storage/storage.h index 8800399..b72121b 100644 --- a/src/storage/storage.h +++ b/src/storage/storage.h @@ -68,7 +68,7 @@ struct familia_storage * familia_storage_get_current(); /** * Sets storage structure as a currently loaded one. - * @parameter storage to set as a current one + * @param storage storage to set as a current one */ void familia_storage_set_current(struct familia_storage * storage); @@ -81,51 +81,51 @@ struct familia_storage * familia_storage_new(); /** * Frees storage and all the content in it - * @parameter storage to free + * @param storage storage to free */ void familia_storage_free(struct familia_storage * storage); /** * Adds individual to the storage - * @parameter storage to which add individual - * @parameter individual to add to the storage + * @param storage storage to which add individual + * @param individual individual to add to the storage */ void familia_storage_add_individual(struct familia_storage * storage, struct familia_individual * individual); /** * Gets individual with the given id from the storage - * @parameter storage from which search for individual - * @parameter individual identifier + * @param storage storage from which search for individual + * @param id individual identifier * @return loaded individual if found. NULL otherwise. */ struct familia_individual * familia_storage_get_individual_by_id(struct familia_storage * storage, unsigned int id); /** * Removes individual with the given id from the storage - * @parameter storage from which remove individual - * @parameter individual id + * @param storage storage from which remove individual + * @param id individual id */ void familia_storage_remove_individual_by_id(struct familia_storage * storage, unsigned int id); /** * Adds family to the storage - * @parameter storage to which add family - * @parameter family to add to the storage + * @param storage storage to which add family + * @param family family to add to the storage */ void familia_storage_add_family(struct familia_storage * storage, struct familia_family * family); /** * Gets family with the given id from the storage - * @parameter storage from which search for family - * @parameter family identifier + * @param storage storage from which search for family + * @param id family identifier * @return loaded family if found. NULL otherwise */ struct familia_family * familia_storage_get_family_by_id(struct familia_storage * storage, unsigned int id); /** * Removes family with the given id from the storage - * @parameter storage from which remove family - * @parameter family id + * @param storage storage from which remove family + * @param id family id */ void familia_storage_remove_family_by_id(struct familia_storage * storage, unsigned int id);