public GedcomFamilyRecord(GedcomDatabase database, GedcomIndividualRecord indi1, GedcomIndividualRecord indi2) : this() { Level = 0; Database = database; XRefID = database.GenerateXref("FAM"); if (indi1 != null) { GedcomFamilyLink link = new GedcomFamilyLink(); link.Database = database; link.Family = XRefID; link.Indi = indi1.XRefID; indi1.SpouseIn.Add(link); if (indi2 != null) { link = new GedcomFamilyLink(); link.Database = database; link.Family = XRefID; link.Indi = indi2.XRefID; indi2.SpouseIn.Add(link); } switch (indi1.Sex) { case GedcomSex.Female: Wife = indi1.XRefID; if (indi2 != null) { Husband = indi2.XRefID; } break; default: // got to put some where if not male or female, // go with same as male Husband = indi1.XRefID; if (indi2 != null) { Wife = indi2.XRefID; } break; } } database.Add(XRefID, this); }
private void AppendFamilyDetails(GedcomFamilyLink link, XmlNode root, int generation) { string famID = link.Family; if (!_processed.Contains(famID)) { _processed.Add(famID); GedcomFamilyRecord fam = _database[famID] as GedcomFamilyRecord; if (fam != null) { foreach (GedcomFamilyEvent famEvent in fam.Events) { famEvent.EventXRefID = _database.GenerateXref("EVENT"); AppendEvent(famEvent, root); AppendSources(famEvent, root); } AppendFamily(fam, root); if (!string.IsNullOrEmpty(fam.Husband)) { GedcomIndividualRecord husb = _database[fam.Husband] as GedcomIndividualRecord; if (husb != null) { AppendIndividualDetails(husb, root, generation); } else { throw new Exception("Husband points to non individual record"); } } if (!string.IsNullOrEmpty(fam.Wife)) { GedcomIndividualRecord wife = _database[fam.Wife] as GedcomIndividualRecord; if (wife != null) { AppendIndividualDetails(wife, root, generation); } else { throw new Exception("Husband points to non individual record"); } } foreach (string childID in fam.Children) { GedcomIndividualRecord child = _database[childID] as GedcomIndividualRecord; if (child != null) { int childGeneration = generation - 1; AppendIndividualDetails(child, root, childGeneration); } else { throw new Exception("Child points to non individual record"); } } } else { throw new Exception("Family link points to non family record"); } } }
public bool ChildInFamily(string family, out GedcomFamilyLink famLink) { bool ret = false; famLink = null; foreach (GedcomFamilyLink link in ChildIn) { if (link.Family == family) { ret = true; famLink = link; break; } } return ret; }
private void Rebuild(Gtk.Table table, uint[][][] positions, GedcomIndividualRecord activePerson, GedcomFamilyLink[] lst) { foreach (Gtk.Widget child in table.Children) { child.Destroy(); } table.Resize(1,1); uint xmax = 0; uint ymax = 0; for (int i = 0; i < positions.Length; i ++) { uint x = positions[i][0][0] + 1; uint y = positions[i][0][1] + 1; uint w = positions[i][0][2]; uint h = positions[i][0][3]; GedcomFamilyLink famLink = (GedcomFamilyLink)lst[i]; if (famLink == null) { PedigreeBox pw = new PedigreeBox(null, 0, null); if (i > 0 && lst[((i+1)/2)-1] != null) { GedcomFamilyLink missingFamLink = (GedcomFamilyLink)lst[((i+1)/2)-1]; // missing parent button pw.ForceMouseOver = true; } // FIXME: both conditions do the same thing, double checking // the gramps code it doesn't appear to be a mistake in porting if (positions[i][0][2] > 1) { table.Attach(pw,x, x+w, y, y+h, Gtk.AttachOptions.Fill, Gtk.AttachOptions.Fill, 0, 0); } else { table.Attach(pw,x, x+w, y, y+h, Gtk.AttachOptions.Fill, Gtk.AttachOptions.Fill, 0, 0); } xmax = (uint)Math.Max(xmax, x + w); ymax = (uint)Math.Max(ymax, y + h); } else { GedcomIndividualRecord indi = (GedcomIndividualRecord)_database[famLink.Indi]; if (_showImages && i < ((positions.Length - 1) / 2) && positions[i][0][3] > 1) { } PedigreeBox pw = new PedigreeBox(indi, positions[i][0][3], null); pw.SelectIndividual += PedigreeBox_SelectIndividual; if (positions[i][0][3] < 7) { pw.TooltipMarkup = pw.FormatPerson(11, true); } if (positions[i][0][2] > 1) { table.Attach(pw, x, x+w, y, y+h, Gtk.AttachOptions.Expand | Gtk.AttachOptions.Fill, Gtk.AttachOptions.Expand | Gtk.AttachOptions.Fill, 0, 0); } else { table.Attach(pw, x, x+w, y, y+h, Gtk.AttachOptions.Fill, Gtk.AttachOptions.Fill, 0, 0); } xmax = (uint)Math.Max(xmax, x + w); ymax = (uint)Math.Max(ymax, y + h); } // connection lines if (positions[i].Length > 1) { // separate boxes for father and mother x = positions[i][1][0] + 1; y = positions[i][1][1] + 1; w = 1; h = positions[i][1][2]; Gtk.DrawingArea line = new Gtk.DrawingArea(); line.ExposeEvent += Line_Expose; bool rela = false; if (famLink != null && (famLink.Pedigree == PedegreeLinkageType.Birth || famLink.Pedigree == PedegreeLinkageType.Unknown)) { line.AddEvents((int)Gdk.EventMask.ButtonPressMask); rela = true; } Utility.Pair<int, bool> lineData = new Pair<int,bool>(); lineData.First = i * 2 + 1; lineData.Second = rela; _lines[line] = lineData; table.Attach(line, x, x + w, y, y + h, Gtk.AttachOptions.Fill, Gtk.AttachOptions.Fill, 0, 0); xmax = (uint)Math.Max(xmax, x + w); ymax = (uint)Math.Max(ymax, y + h); x = positions[i][2][0] + 1; y = positions[i][2][1] + 1; w = 1; h = positions[i][2][2]; line = new Gtk.DrawingArea(); line.ExposeEvent += Line_Expose; rela = false; if (famLink != null && (famLink.Pedigree == PedegreeLinkageType.Birth || famLink.Pedigree == PedegreeLinkageType.Unknown)) { line.AddEvents((int)Gdk.EventMask.ButtonPressMask); rela = true; } lineData = new Pair<int,bool>(); lineData.First = i * 2 + 2; lineData.Second = rela; _lines[line] = lineData; table.Attach(line, x, x + w, y, y + h, Gtk.AttachOptions.Fill, Gtk.AttachOptions.Fill, 0, 0); xmax = (uint)Math.Max(xmax, x + w); ymax = (uint)Math.Max(ymax, y + h); } // marriage data if (_showMarriageData && positions[i].Length > 3) { string text = string.Empty; if (famLink != null && (famLink.Pedigree == PedegreeLinkageType.Birth || famLink.Pedigree == PedegreeLinkageType.Unknown)) { text = "foo"; } Gtk.Label label = new Gtk.Label(text); label.Justify = Gtk.Justification.Left; label.LineWrap = true; label.SetAlignment(0.1F, 0.5F); x = positions[i][3][0] + 1; y = positions[i][3][1] + 1; w = positions[i][3][2]; h = positions[i][3][3]; table.Attach(label, x, x + w, y, y + h, Gtk.AttachOptions.Fill, Gtk.AttachOptions.Fill, 0, 0); } } // nav arrows if (lst[0] != null) { Gtk.Button arrowButton = new Gtk.Button(); arrowButton.Add(new Gtk.Arrow(Gtk.ArrowType.Left, Gtk.ShadowType.In)); arrowButton.Sensitive = (_dummyFam.Children.Count > 0); arrowButton.Clicked += ArrowButton_Click; if (arrowButton.Sensitive) { arrowButton.TooltipText = "Jump to child..."; } uint ymid = (uint)Math.Floor(ymax / 2.0F); table.Attach(arrowButton, 0, 1, ymid, ymid + 1, 0, 0, 0, 0); // father arrowButton = new Gtk.Button(); arrowButton.Add(new Gtk.Arrow(Gtk.ArrowType.Right, Gtk.ShadowType.In)); arrowButton.Sensitive = (lst[1] != null); arrowButton.Clicked += FatherButton_Click; if (arrowButton.Sensitive) { arrowButton.TooltipText = "Jump to father"; } ymid = (uint)Math.Floor(ymax / 4.0F); table.Attach(arrowButton, xmax, xmax + 1, ymid - 1, ymid + 2, 0, 0, 0, 0); // mother arrowButton = new Gtk.Button(); arrowButton.Add(new Gtk.Arrow(Gtk.ArrowType.Right, Gtk.ShadowType.In)); arrowButton.Sensitive = (lst[2] != null); arrowButton.Clicked += MotherButton_Click; if (arrowButton.Sensitive) { arrowButton.TooltipText = "Jump to mother"; } ymid = (uint)Math.Floor(ymax / 4.0F * 3); table.Attach(arrowButton, xmax, xmax + 1, ymid - 1, ymid + 2, 0, 0, 0, 0); // dummy widgets to allow pedigree to be centred Gtk.Label l = new Gtk.Label(string.Empty); table.Attach(l, 0, 1, 0, 1, Gtk.AttachOptions.Expand | Gtk.AttachOptions.Fill, Gtk.AttachOptions.Expand | Gtk.AttachOptions.Fill, 0, 0); l = new Gtk.Label(string.Empty); table.Attach(l, xmax, xmax + 1, ymax, ymax + 1, Gtk.AttachOptions.Expand | Gtk.AttachOptions.Fill, Gtk.AttachOptions.Expand | Gtk.AttachOptions.Fill, 0, 0); table.ShowAll(); } }
private void FindTree(GedcomIndividualRecord indi, int i, int depth, GedcomFamilyLink[] lst) { if (depth <= 5 && indi != null) { List<GedcomFamilyLink> families = indi.ChildIn; if (families == null || families.Count == 0) { // indi doesn't exist as a child in any family, create // a dummy link record GedcomFamilyLink famLink = new GedcomFamilyLink(); famLink.Indi = indi.XRefID; famLink.Pedigree = PedegreeLinkageType.Unknown; famLink.Database = _database; lst[i] = famLink; } else { GedcomFamilyLink famLink = families[0]; lst[i] = famLink; GedcomFamilyRecord famRec = (GedcomFamilyRecord)_database[famLink.Family]; if (!string.IsNullOrEmpty(famRec.Husband)) { indi = (GedcomIndividualRecord)_database[famRec.Husband]; FindTree(indi, (2*i)+1, depth + 1, lst); } if (!string.IsNullOrEmpty(famRec.Wife)) { indi = (GedcomIndividualRecord)_database[famRec.Wife]; FindTree(indi, (2*i)+2, depth + 1, lst); } } } }
private void BuildTrees() { uint[][][] pos2 = new uint[][][] { new uint[][] { new uint[] { 0, 3, 3, 3 }, new uint[] { 1, 0, 3 }, new uint[] { 1, 6, 4 }, new uint[] { 3, 3, 2, 3 } }, new uint[][] { new uint[] { 2, 0, 3, 3 } }, new uint[][] { new uint[] { 2, 6, 3, 3 } } }; uint[][][] pos3 = new uint[][][] { new uint[][] { new uint[] { 0, 4, 3, 5 }, new uint[] { 1, 1, 3 }, new uint[] { 1, 9, 4 }, new uint[] { 3, 5, 2, 3 } }, new uint[][] { new uint[] { 2, 1, 3, 3 }, new uint[] { 3, 0, 1 }, new uint[] { 3, 4, 1 }, new uint[] { 5, 1, 2, 3 } }, new uint[][] { new uint[] { 2, 9, 3, 3 }, new uint[] { 3, 8, 1 }, new uint[] { 3, 12, 1 }, new uint[] { 5, 9, 2, 3 } }, new uint[][] { new uint[] { 4, 0, 3, 1 } }, new uint[][] { new uint[] { 4, 4, 3, 1 } }, new uint[][] { new uint[] { 4, 8, 3, 1 } }, new uint[][] { new uint[] { 4, 12, 3, 1 } } }; uint[][][] pos4 = new uint[][][] { new uint[][] { new uint[] { 0, 5, 3, 5 }, new uint[] { 1, 2, 3 }, new uint[] { 1, 10, 4 }, new uint[] { 3, 6, 2, 3 } }, new uint[][] { new uint[] { 2, 2, 3, 3 }, new uint[] { 3, 1, 1 }, new uint[] { 3, 5, 1 }, new uint[] { 5, 3, 2, 1 } }, new uint[][] { new uint[] { 2, 10, 3, 3 }, new uint[] { 3, 9, 1 }, new uint[] { 3, 13, 1 }, new uint[] { 5, 11, 2, 1 } }, new uint[][] { new uint[] { 4, 1, 3, 1 }, new uint[] { 5, 0, 1 }, new uint[] { 5, 2, 1 }, new uint[] { 7, 1, 2, 1 } }, new uint[][] { new uint[] { 4, 5, 3, 1 }, new uint[] { 5, 4, 1 }, new uint[] { 5, 6, 1 }, new uint[] { 7, 5, 2, 1 } }, new uint[][] { new uint[] { 4, 9, 3, 1 }, new uint[] { 5, 8, 1 }, new uint[] { 5, 10, 1 }, new uint[] { 7, 9, 2, 1 } }, new uint[][] { new uint[] { 4, 13, 3, 1 }, new uint[] { 5, 12, 1 }, new uint[] { 5, 14, 1 }, new uint[] { 7, 13, 2, 1 } }, new uint[][] { new uint[] { 6, 0, 3, 1 } }, new uint[][] { new uint[] { 6, 2, 3, 1 } }, new uint[][] { new uint[] { 6, 4, 3, 1 } }, new uint[][] { new uint[] { 6, 6, 3, 1 } }, new uint[][] { new uint[] { 6, 8, 3, 1 } }, new uint[][] { new uint[] { 6, 10, 3, 1 } }, new uint[][] { new uint[] { 6, 12, 3, 1 } }, new uint[][] { new uint[] { 6, 14, 3, 1 } } }; uint[][][] pos5 = new uint[][][] { new uint[][] { new uint[] {0, 10, 3, 11}, new uint[] {1, 5, 5}, new uint[] {1, 21, 5}, new uint[] {3, 13, 2, 5} }, new uint[][] { new uint[] {2, 5, 3, 5}, new uint[] {3, 2, 3}, new uint[] {3, 10, 3}, new uint[] {5, 6, 2, 3} }, new uint[][] { new uint[] {2, 21, 3, 5}, new uint[] {3, 18, 3}, new uint[] {3, 26, 3}, new uint[] {5, 22, 2, 3} }, new uint[][] { new uint[] {4, 2, 3, 3}, new uint[] {5, 1, 1}, new uint[] {5, 5, 1}, new uint[] {7, 3, 2, 1} }, new uint[][] { new uint[] {4, 10, 3, 3}, new uint[] {5, 9, 1}, new uint[] {5, 13, 1}, new uint[] {7, 11, 2, 1} }, new uint[][] { new uint[] {4, 18, 3, 3}, new uint[] {5, 17, 1}, new uint[] {5, 21, 1}, new uint[] {7, 19, 2, 1} }, new uint[][] { new uint[] {4, 26, 3, 3}, new uint[] {5, 25, 1}, new uint[] {5, 29, 1}, new uint[] {7, 27, 2, 1} }, new uint[][] { new uint[] {6, 1, 3, 1}, new uint[] {7, 0, 1}, new uint[] {7, 2, 1}, new uint[] {9, 1, 2, 1} }, new uint[][] { new uint[] {6, 5, 3, 1}, new uint[] {7, 4, 1}, new uint[] {7, 6, 1}, new uint[] {9, 5, 2, 1} }, new uint[][] { new uint[] {6, 9, 3, 1}, new uint[] {7, 8, 1}, new uint[] {7, 10, 1}, new uint[] {9, 9, 2, 1} }, new uint[][] { new uint[] {6, 13, 3, 1}, new uint[] {7, 12, 1}, new uint[] {7, 14, 1}, new uint[] {9, 13, 2, 1} }, new uint[][] { new uint[] {6, 17, 3, 1}, new uint[] {7, 16, 1}, new uint[] {7, 18, 1}, new uint[] {9, 17, 2, 1} }, new uint[][] { new uint[] {6, 21, 3, 1}, new uint[] {7, 20, 1}, new uint[] {7, 22, 1}, new uint[] {9, 21, 2, 1} }, new uint[][] { new uint[] {6, 25, 3, 1}, new uint[] {7, 24, 1}, new uint[] {7, 26, 1}, new uint[] {9, 25, 2, 1} }, new uint[][] { new uint[] {6, 29, 3, 1}, new uint[] {7, 28, 1}, new uint[] {7, 30, 1}, new uint[] {9, 29, 2, 1} }, new uint[][] { new uint[] {8, 0, 3, 1}}, new uint[][] { new uint[] {8, 2, 3, 1}}, new uint[][] { new uint[] {8, 4, 3, 1}}, new uint[][] { new uint[] {8, 6, 3, 1}}, new uint[][] { new uint[] {8, 8, 3, 1}}, new uint[][] { new uint[] {8, 10, 3, 1}}, new uint[][] { new uint[] {8, 12, 3, 1}}, new uint[][] { new uint[] {8, 14, 3, 1}}, new uint[][] { new uint[] {8, 16, 3, 1}}, new uint[][] { new uint[] {8, 18, 3, 1}}, new uint[][] { new uint[] {8, 20, 3, 1}}, new uint[][] { new uint[] {8, 22, 3, 1}}, new uint[][] { new uint[] {8, 24, 3, 1}}, new uint[][] { new uint[] {8, 26, 3, 1}}, new uint[][] { new uint[] {8, 28, 3, 1}}, new uint[][] { new uint[] {8, 30, 3, 1}} }; GedcomFamilyLink[] lst = new GedcomFamilyLink[32]; GedcomIndividualRecord indi = (GedcomIndividualRecord)_record; FindTree(indi, 0, 1, lst); _lines.Clear(); _fatherID = string.Empty; _motherID = string.Empty; if (!string.IsNullOrEmpty(lst[0].Family)) { GedcomFamilyRecord fam = (GedcomFamilyRecord)_database[lst[0].Family]; _fatherID = fam.Husband; _motherID = fam.Wife; } Rebuild(_table2, pos2, indi, lst); Rebuild(_table3, pos3, indi, lst); Rebuild(_table4, pos4, indi, lst); Rebuild(_table5, pos5, indi, lst); this.ShowAll(); }
public void ChangeWife(GedcomIndividualRecord indi) { GedcomIndividualRecord husband = null; GedcomIndividualRecord wife = null; if (!string.IsNullOrEmpty(_Husband)) { husband = _database[_Husband] as GedcomIndividualRecord; } if (!string.IsNullOrEmpty(_Wife)) { wife = _database[_Wife] as GedcomIndividualRecord; } if (string.IsNullOrEmpty(XRefID)) { XRefID = _database.GenerateXref("FAM"); _database.Add(XRefID,this); } if (wife != null) { GedcomFamilyLink link; if (wife.SpouseInFamily(XRefID,out link)) { wife.SpouseIn.Remove(link); } } wife = indi; _Wife = string.Empty; if (husband != null) { _Husband = husband.XRefID; if (!husband.SpouseInFamily(XRefID)) { GedcomFamilyLink link = new GedcomFamilyLink(); link.Database = _database; link.Family = XRefID; link.Indi = _Husband; husband.SpouseIn.Add(link); } } if (wife != null) { _Wife = wife.XRefID; if (!wife.SpouseInFamily(XRefID)) { GedcomFamilyLink link = new GedcomFamilyLink(); link.Database = _database; link.Family = XRefID; link.Indi = _Wife; wife.SpouseIn.Add(link); } } }
public bool AddChild(GedcomIndividualRecord indi) { bool added = false; if (indi != null && ! Children.Contains(indi.XRefID)) { if (string.IsNullOrEmpty(XRefID)) { XRefID = _database.GenerateXref("FAM"); _database.Add(XRefID,this); } if (!indi.ChildInFamily(XRefID)) { GedcomFamilyLink link = new GedcomFamilyLink(); link.Database = _database; link.Family = XRefID; link.Indi = indi.XRefID; link.Level = 1; indi.ChildIn.Add(link); } Children.Add(indi.XRefID); added = true; } return added; }
/// <summary> /// Starts reading the specified gedcom file /// </summary> /// <param name="gedcomFile">Filename to read</param> /// <returns>bool indicating if the file was successfully read</returns> public bool ReadGedcom(string gedcomFile) { bool success = false; _gedcomFile = gedcomFile; _percent = 0; FileInfo info = new FileInfo(gedcomFile); long fileSize = info.Length; long read = 0; _missingReferences = new List<string>(); _sourceCitations = new List<GedcomSourceCitation>(); _repoCitations = new List<GedcomRepositoryCitation>(); try { _stream = null; Encoding enc = Encoding.Default; using (FileStream fileStream = File.OpenRead(gedcomFile)) { ResetParse(); byte[] bom = new byte[4]; fileStream.Read(bom, 0, 4); // look for BOMs, if found we will ignore the CHAR tag // don't use .net look for bom as we also want to detect // unicode where there isn't a BOM, as far as the parser // is concerned the data is utf16le if we detect this way // as the conversion is already done if (bom[0] == 0xEF && bom[1] == 0xBB && bom[2] == 0xBF) { _Parser.Charset = GedcomCharset.UTF16LE; enc = Encoding.UTF8; } else if (bom[0] == 0xFE && bom[1] == 0xFF) { _Parser.Charset = GedcomCharset.UTF16LE; enc = Encoding.BigEndianUnicode; } else if (bom[0] == 0xFF && bom[1] == 0xFE && bom[2] == 0x00 && bom[3] == 0x00) { _Parser.Charset = GedcomCharset.UTF16LE; enc = Encoding.UTF32; } else if (bom[0] == 0xFF && bom[1] == 0xFE) { _Parser.Charset = GedcomCharset.UTF16LE; enc = Encoding.Unicode; } else if (bom[0] == 0x00 && bom[1] == 0x00 && bom[2] == 0xFE && bom[3] == 0xFF) { _Parser.Charset = GedcomCharset.UTF16LE; enc = Encoding.UTF32; } else if (bom[0] == 0x00 && bom[2] == 0x00) { _Parser.Charset = GedcomCharset.UTF16LE; enc = Encoding.BigEndianUnicode; } else if (bom[1] == 0x00 && bom[3] == 0x00) { _Parser.Charset = GedcomCharset.UTF16LE; enc = Encoding.Unicode; } } _stream = new StreamReader(gedcomFile, enc); while (!_stream.EndOfStream) { string line = _stream.ReadLine(); if (line != null) { // file may not have same newline as environment so this isn't 100% correct read += line.Length + Environment.NewLine.Length; try { _Parser.GedcomParse(line); } catch { } line = null; // to allow for inaccuracy above int percentDone = (int)Math.Min(100, (read * 100.0F)/fileSize); if (percentDone != _percent) { _percent = percentDone; if (PercentageDone != null) { PercentageDone(this, EventArgs.Empty); } } } } Flush(); } finally { if (_stream != null) { _stream.Dispose(); } } success = (_Parser.ErrorState == GedcomErrorState.NoError); if (success) { _percent = 100; // cleanup header record, don't want submitter record or content description in the main // database submitters / notes GedcomHeader header = Database.Header; if (header != null) { if (header.Notes.Count > 0) { string xref = header.Notes[0]; // belongs in content description, not top level record notes header.Notes.Remove(xref); header.ContentDescription = (GedcomNoteRecord)Database[xref]; // fix up level, note is inline in the header + remove from database // list of notes header.ContentDescription.Level = 1; header.ContentDescription.XRefID = string.Empty; //Database.Remove(xref, header.ContentDescription); } // brothers keeper doesn't output a source name, so set the name to // the same as the ID if it is empty if (string.IsNullOrEmpty(header.ApplicationName) && !string.IsNullOrEmpty(header.ApplicationSystemID)) { header.ApplicationName = header.ApplicationSystemID; } } // add any missing child in and spouse in linkage foreach (GedcomFamilyRecord family in Database.Families) { string husbandID = family.Husband; if (!string.IsNullOrEmpty(husbandID)) { GedcomIndividualRecord husband = Database[husbandID] as GedcomIndividualRecord; if (husband != null) { GedcomFamilyLink famLink = null; if (!husband.SpouseInFamily(family.XRefID, out famLink)) { famLink = new GedcomFamilyLink(); famLink.Database = Database; famLink.Family = family.XRefID; famLink.Indi = husbandID; famLink.Level = 1; famLink.PreferedSpouse = (husband.SpouseIn.Count == 0); husband.SpouseIn.Add(famLink); } } else { System.Diagnostics.Debug.WriteLine("Husband in family points to non individual record"); } } string wifeID = family.Wife; if (!string.IsNullOrEmpty(wifeID)) { GedcomIndividualRecord wife = Database[wifeID] as GedcomIndividualRecord; if (wife != null) { GedcomFamilyLink famLink = null; if (!wife.SpouseInFamily(family.XRefID, out famLink)) { famLink = new GedcomFamilyLink(); famLink.Database = Database; famLink.Family = family.XRefID; famLink.Indi = wifeID; famLink.Level = 1; wife.SpouseIn.Add(famLink); } } else { System.Diagnostics.Debug.WriteLine("Wife in family points to non individual record"); } } foreach (string childID in family.Children) { GedcomIndividualRecord child = Database[childID] as GedcomIndividualRecord; if (child != null) { GedcomFamilyLink famLink = null; // add a family link record if one doesn't already exist if (!child.ChildInFamily(family.XRefID, out famLink)) { famLink = new GedcomFamilyLink(); famLink.Database = Database; famLink.Family = family.XRefID; famLink.Indi = childID; famLink.Level = 1; famLink.Status = ChildLinkageStatus.Unknown; // pedigree now set below child.ChildIn.Add(famLink); } // set pedigree here to allow for ADOP/FOST in the FAM tag // FAM record overrides link status if they differ famLink.Pedigree = family.GetLinkageType(childID); famLink.FatherPedigree = family.GetHusbandLinkageType(childID); famLink.MotherPedigree = family.GetWifeLinkageType(childID); // check BIRT event for a FAMC record, check ADOP for FAMC / ADOP records foreach (GedcomIndividualEvent indiEv in child.Events) { if (indiEv.Famc == family.XRefID) { switch (indiEv.EventType) { case GedcomEvent.GedcomEventType.BIRT: // BIRT records do not state father/mother birth, // all we can say is both are natural famLink.Pedigree = PedegreeLinkageType.Birth; break; case GedcomEvent.GedcomEventType.ADOP: switch (indiEv.AdoptedBy) { case Gedcom.GedcomAdoptionType.Husband: famLink.FatherPedigree = PedegreeLinkageType.Adopted; break; case Gedcom.GedcomAdoptionType.Wife: famLink.MotherPedigree = PedegreeLinkageType.Adopted; break; case Gedcom.GedcomAdoptionType.HusbandAndWife: default: // default is both as well, has to be adopted by someone if // there is an event on the family. famLink.Pedigree = PedegreeLinkageType.Adopted; break; } break; } } } } else { System.Diagnostics.Debug.WriteLine("Child in family points to non individual record"); } } family.ClearLinkageTypes(); } // look for any broken references / update ref counts foreach (string xref in _missingReferences) { GedcomRecord record = Database[xref]; if (record != null) { switch (record.RecordType) { case GedcomRecordType.Individual: // FIXME: don't increase ref count on individuals, // a bit of a hack, only place where it may be // needed is on assocciations break; case GedcomRecordType.Family: // FIXME: don't increase ref count on families break; default: record.RefCount ++; break; } } else if (!_removedNotes.Contains(xref)) { System.Diagnostics.Debug.WriteLine("Missing reference: " + xref); } } //System.Console.WriteLine("Removed " + _removedNotes.Count + " notes"); _missingReferences = null; // link sources with citations which reference them foreach (GedcomSourceCitation citation in _sourceCitations) { GedcomSourceRecord source = Database[citation.Source] as GedcomSourceRecord; if (source != null) { source.Citations.Add(citation); } else { System.Diagnostics.Debug.WriteLine("Missing source reference: " + citation.Source); } } _sourceCitations = null; // link repos with citations which reference them foreach (GedcomRepositoryCitation citation in _repoCitations) { GedcomRepositoryRecord repo = Database[citation.Repository] as GedcomRepositoryRecord; if (repo != null) { repo.Citations.Add(citation); } else { System.Diagnostics.Debug.WriteLine("Missing repo reference: " + citation.Repository); } } _repoCitations = null; // find any sources without a title and give them one, happens with Database1.ged, // could be bad parsing, not sure, try and make up for it anyway int missingSourceTitleCount = 1; foreach (GedcomSourceRecord source in Database.Sources) { if (string.IsNullOrEmpty(source.Title)) { source.Title = string.Format("Source {0}", missingSourceTitleCount ++); } } Database.Name = gedcomFile; } if (PercentageDone != null) { PercentageDone(this, EventArgs.Empty); } Database.Loading = false; return success; }
private void ReadIndividualRecord() { GedcomIndividualRecord individualRecord; individualRecord = _ParseState.Records.Peek() as GedcomIndividualRecord; GedcomIndividualEvent individualEvent; // some custom tags we convert to generic facts/events // this means we have to set the line value to the type // they represent, so store the real line value and use // for the event classification. string customToGenericClassification = string.Empty; if (_tag.StartsWith("_")) { switch (_tag) { // we convert _MILT to EVEN Military Service case "_MILT": _tag = "EVEN"; _lineValue = "Military Service"; _lineValueType = GedcomLineValueType.DataType; break; // we convert _MDCL to FACT Medical case "_MDCL": _tag = "FACT"; customToGenericClassification = _lineValue; _lineValue = "Medical"; _lineValueType = GedcomLineValueType.DataType; break; // we convert _HEIG to FACT Height case "_HEIG": _tag = "FACT"; customToGenericClassification = _lineValue; _lineValue = "Height"; _lineValueType = GedcomLineValueType.DataType; break; // we convert _WEIG to FACT Weight case "_WEIG": _tag = "FACT"; customToGenericClassification = _lineValue; _lineValue = "Weight"; _lineValueType = GedcomLineValueType.DataType; break; default: GedcomCustomRecord custom = new GedcomCustomRecord(); custom.Level = _level; custom.XRefID = _xrefID; custom.Tag = _tag; if (_lineValueType == GedcomLineValueType.DataType) { custom.Classification = _lineValue; } // FIXME: may want to use customs at some point //individualRecord.Events.Add(custom); _ParseState.Records.Push(custom); break; } } if (_level == individualRecord.ParsingLevel + 1) { switch (_tag) { case "FAMC": if (_lineValueType == GedcomLineValueType.PointerType) { GedcomFamilyLink childIn = new GedcomFamilyLink(); childIn.Level = _level; childIn.Family = _lineValue; childIn.Indi = individualRecord.XRefID; _missingReferences.Add(_lineValue); individualRecord.ChildIn.Add(childIn); _ParseState.Records.Push(childIn); } break; case "FAMS": if (_lineValueType == GedcomLineValueType.PointerType) { GedcomFamilyLink spouseIn = new GedcomFamilyLink(); spouseIn.Level = _level; spouseIn.Family = _lineValue; spouseIn.Indi = individualRecord.XRefID; spouseIn.PreferedSpouse = (individualRecord.SpouseIn.Count == 0); _missingReferences.Add(_lineValue); individualRecord.SpouseIn.Add(spouseIn); _ParseState.Records.Push(spouseIn); } break; case "ASSO": if (_lineValueType == GedcomLineValueType.PointerType) { GedcomAssociation association = new GedcomAssociation(); association.Level = _level; association.Individual = _lineValue; _missingReferences.Add(_lineValue); individualRecord.Associations.Add(association); _ParseState.Records.Push(association); } break; case "RESN": if (_lineValueType == GedcomLineValueType.DataType) { try { individualRecord.RestrictionNotice = EnumHelper.Parse<GedcomRestrictionNotice>(_lineValue,true); } catch { Debug.WriteLine("Invalid restriction type: " + _lineValue); // default to confidential to protect privacy individualRecord.RestrictionNotice = GedcomRestrictionNotice.Confidential; } } break; case "NAME": if (_lineValueType == GedcomLineValueType.DataType) { GedcomName name = new GedcomName(); name.Database = _ParseState.Database; name.Level = _level; name.Name = _lineValue; name.PreferedName = (individualRecord.Names.Count == 0); individualRecord.Names.Add(name); _ParseState.Records.Push(name); } break; // Invalid, but seen from Family Origins, Family Tree Maker, Personal Ancestral File, and Legacy case "AKA": if (_lineValueType == GedcomLineValueType.DataType) { GedcomName name = new GedcomName(); name.Database = _ParseState.Database; name.Level = _level; name.Name = _lineValue; name.Type = "aka"; name.PreferedName = (individualRecord.Names.Count == 0); individualRecord.Names.Add(name); } break; case "SEX": if (_lineValueType == GedcomLineValueType.DataType) { switch (_lineValue) { case "M": individualRecord.Sex = GedcomSex.Male; break; case "F": individualRecord.Sex = GedcomSex.Female; break; // non standard case "B": individualRecord.Sex = GedcomSex.Both; break; // non standard case "N": individualRecord.Sex = GedcomSex.Neuter; break; // non standard case "U": individualRecord.Sex = GedcomSex.Undetermined; break; } } break; case "SUBM": if (_lineValueType == GedcomLineValueType.PointerType) { individualRecord.SubmitterRecords.Add(_lineValue); _missingReferences.Add(_lineValue); } else { GedcomSubmitterRecord submitter = new GedcomSubmitterRecord(); submitter.Level = 0; // new top level submitter, always 0 submitter.ParsingLevel = _level; submitter.XRefID = Database.GenerateXref("SUBM"); _ParseState.Records.Push(submitter); individualRecord.SubmitterRecords.Add(submitter.XRefID); } break; case "ALIA": if (_lineValueType == GedcomLineValueType.PointerType) { individualRecord.Alia.Add(_lineValue); _missingReferences.Add(_lineValue); } else if (_lineValueType == GedcomLineValueType.DataType) { // Family Tree Maker doing this? // ALIA is unsupported in gedcom 5.5 as a way of // adding multiple names, the spec // does say it should be a pointer to an individual // though, not another name. // spec allows multiple NAME though, so add one // with this name GedcomName name = new GedcomName(); name.Database = _ParseState.Database; name.Level = _level; name.Name = _lineValue; name.Type = "aka"; name.PreferedName = (individualRecord.Names.Count == 0); individualRecord.Names.Add(name); } break; case "ANCI": if (_lineValueType == GedcomLineValueType.PointerType) { individualRecord.Anci.Add(_lineValue); _missingReferences.Add(_lineValue); } break; case "DESI": if (_lineValueType == GedcomLineValueType.PointerType) { individualRecord.Desi.Add(_lineValue); _missingReferences.Add(_lineValue); } break; case "RFN": if (_lineValueType == GedcomLineValueType.DataType) { individualRecord.PermanentRecordFileNumber = _lineValue; } break; case "AFN": if (_lineValueType == GedcomLineValueType.DataType) { individualRecord.AncestralFileNumber = _lineValue; } break; case "REFN": if (_lineValueType == GedcomLineValueType.DataType) { individualRecord.UserReferenceNumber = _lineValue; } break; case "RIN": if (_lineValueType == GedcomLineValueType.DataType) { individualRecord.AutomatedRecordID = _lineValue; } break; case "CHAN": GedcomChangeDate date = new GedcomChangeDate(Database); date.Level = _level; _ParseState.Records.Push(date); break; case "NOTE": AddNoteRecord(individualRecord); break; case "SOUR": AddSourceCitation(individualRecord); break; case "OBJE": AddMultimediaRecord(individualRecord); break; case "BIRT": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.BIRT; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "CHR": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.CHR; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "DEAT": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.DEAT; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "BURI": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.BURI; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "CREM": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.CREM; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "ADOP": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.ADOP; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "BAPM": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.BAPM; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "BARM": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.BARM; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "BASM": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.BASM; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "BLES": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.BLES; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "CHRA": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.CHRA; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "CONF": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.CONF; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "FCOM": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.FCOM; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "ORDN": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.ORDN; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "NATU": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.NATU; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "EMIG": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.EMIG; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "IMMI": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.IMMI; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "CENS": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.CENS; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "PROB": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.PROB; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "WILL": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.WILL; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "GRAD": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.GRAD; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "RETI": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.RETI; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "EVEN": // event individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.GenericEvent; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; if (_lineValueType == GedcomLineValueType.DataType) { individualEvent.EventName = _lineValue; } individualRecord.Events.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "CAST": // fact individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.CASTFact; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; if (_lineValueType == GedcomLineValueType.DataType) { individualEvent.EventName = _lineValue; } individualRecord.Attributes.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "DSCR": // fact individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.DSCRFact; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; if (_lineValueType == GedcomLineValueType.DataType) { individualEvent.EventName = _lineValue; } individualRecord.Attributes.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "EDUC": // fact individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.EDUCFact; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; if (_lineValueType == GedcomLineValueType.DataType) { individualEvent.EventName = _lineValue; } individualRecord.Attributes.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "IDNO": // fact individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.IDNOFact; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; if (_lineValueType == GedcomLineValueType.DataType) { individualEvent.EventName = _lineValue; } individualRecord.Attributes.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "NATI": // fact individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.NATIFact; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; if (_lineValueType == GedcomLineValueType.DataType) { individualEvent.EventName = _lineValue; } individualRecord.Attributes.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "NCHI": // fact individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.NCHIFact; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; if (_lineValueType == GedcomLineValueType.DataType) { individualEvent.EventName = _lineValue; } individualRecord.Attributes.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "NMR": // fact individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.NMRFact; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; if (_lineValueType == GedcomLineValueType.DataType) { individualEvent.EventName = _lineValue; } individualRecord.Attributes.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "OCCU": // fact individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.OCCUFact; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; if (_lineValueType == GedcomLineValueType.DataType) { individualEvent.EventName = _lineValue; } individualRecord.Attributes.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "PROP": // fact individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.PROPFact; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; if (_lineValueType == GedcomLineValueType.DataType) { individualEvent.EventName = _lineValue; } individualRecord.Attributes.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "RELI": // fact individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.RELIFact; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; if (_lineValueType == GedcomLineValueType.DataType) { individualEvent.EventName = _lineValue; } individualRecord.Attributes.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "RESI": // fact individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.RESIFact; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; if (_lineValueType == GedcomLineValueType.DataType) { individualEvent.EventName = _lineValue; } individualRecord.Attributes.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "SSN": // fact individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.SSNFact; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; if (_lineValueType == GedcomLineValueType.DataType) { individualEvent.EventName = _lineValue; } individualRecord.Attributes.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "TITL": // fact individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.TITLFact; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; if (_lineValueType == GedcomLineValueType.DataType) { individualEvent.EventName = _lineValue; } individualRecord.Attributes.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; case "FACT": // fact individualEvent = new GedcomIndividualEvent(); individualEvent.EventType = GedcomEvent.GedcomEventType.GenericFact; individualEvent.Level = _level; individualEvent.IndiRecord = individualRecord; if (_lineValueType == GedcomLineValueType.DataType) { individualEvent.EventName = _lineValue; } if (!string.IsNullOrEmpty(customToGenericClassification)) { individualEvent.Classification = customToGenericClassification; } individualRecord.Attributes.Add(individualEvent); _ParseState.Records.Push(individualEvent); break; // Not according to the spec, but Family Tree Maker sticks // an address under an individual so we will support reading it case "ADDR": if (individualRecord.Address == null) { individualRecord.Address = new GedcomAddress(); individualRecord.Address.Database = Database; } if (_lineValueType == GedcomLineValueType.DataType) { individualRecord.Address.AddressLine = _lineValue; } break; case "PHON": if (individualRecord.Address == null) { individualRecord.Address = new GedcomAddress(); individualRecord.Address.Database = Database; } if (_lineValueType == GedcomLineValueType.DataType) { if (string.IsNullOrEmpty(individualRecord.Address.Phone1)) { individualRecord.Address.Phone1 = _lineValue; } else if (string.IsNullOrEmpty(individualRecord.Address.Phone2)) { individualRecord.Address.Phone2 = _lineValue; } else if (string.IsNullOrEmpty(individualRecord.Address.Phone3)) { individualRecord.Address.Phone3 = _lineValue; } else { // should never occur only 3 phone numbers are allowed } } break; case "EMAIL": if (individualRecord.Address == null) { individualRecord.Address = new GedcomAddress(); individualRecord.Address.Database = Database; } if (_lineValueType == GedcomLineValueType.DataType) { if (string.IsNullOrEmpty(individualRecord.Address.Email1)) { individualRecord.Address.Email1 = _lineValue; } else if (string.IsNullOrEmpty(individualRecord.Address.Email2)) { individualRecord.Address.Email2 = _lineValue; } else if (string.IsNullOrEmpty(individualRecord.Address.Email3)) { individualRecord.Address.Email3 = _lineValue; } else { // should never occur only 3 emails are allowed } } break; case "FAX": if (individualRecord.Address == null) { individualRecord.Address = new GedcomAddress(); individualRecord.Address.Database = Database; } if (_lineValueType == GedcomLineValueType.DataType) { if (string.IsNullOrEmpty(individualRecord.Address.Fax1)) { individualRecord.Address.Fax1 = _lineValue; } else if (string.IsNullOrEmpty(individualRecord.Address.Fax2)) { individualRecord.Address.Fax2 = _lineValue; } else if (string.IsNullOrEmpty(individualRecord.Address.Fax3)) { individualRecord.Address.Fax3 = _lineValue; } else { // should never occur only 3 fax numbers are allowed } } break; case "WWW": if (individualRecord.Address == null) { individualRecord.Address = new GedcomAddress(); individualRecord.Address.Database = Database; } if (_lineValueType == GedcomLineValueType.DataType) { if (string.IsNullOrEmpty(individualRecord.Address.Www1)) { individualRecord.Address.Www1 = _lineValue; } else if (string.IsNullOrEmpty(individualRecord.Address.Www2)) { individualRecord.Address.Www2 = _lineValue; } else if (string.IsNullOrEmpty(individualRecord.Address.Www3)) { individualRecord.Address.Www3 = _lineValue; } else { // should never occur only 3 urls are allowed } } break; } } else if ( (!string.IsNullOrEmpty(_ParseState.PreviousTag)) && _level == _ParseState.PreviousLevel + 1) { string pTag = _ParseState.PreviousTag; if (pTag == "REFN" && _tag == "TYPE") { if (_lineValueType == GedcomLineValueType.DataType) { individualRecord.UserReferenceType = _lineValue; } } else { AddressParse(individualRecord.Address, _tag, _lineValue, _lineValueType); } } else if ( (!string.IsNullOrEmpty(_ParseState.PreviousTag)) && _level == _ParseState.PreviousLevel) { AddressParse(individualRecord.Address, _tag, _lineValue, _lineValueType); } else { // shouldn't be here Debug.WriteLine("Unknown state / tag parsing individual (" + individualRecord.XRefID + ") node: " + _tag + "\t at level: " + _level); System.Console.WriteLine("Unknown state / tag parsing individual (" + individualRecord.XRefID + ") node: " + _tag + "\t at level: " + _level); System.Console.WriteLine("Previous tag: " + _ParseState.PreviousTag + "\tPrevious Level: " + _ParseState.PreviousLevel); } }