diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.Genealogy.UserInterface/Editors/FamilyTree/FamilyTreeEditor.cs b/Plugins.UserInterface/UniversalEditor.Plugins.Genealogy.UserInterface/Editors/FamilyTree/FamilyTreeEditor.cs
index 3a03405a..1997d7e7 100644
--- a/Plugins.UserInterface/UniversalEditor.Plugins.Genealogy.UserInterface/Editors/FamilyTree/FamilyTreeEditor.cs
+++ b/Plugins.UserInterface/UniversalEditor.Plugins.Genealogy.UserInterface/Editors/FamilyTree/FamilyTreeEditor.cs
@@ -54,6 +54,62 @@ namespace UniversalEditor.Editors.FamilyTree
base.OnObjectModelChanged (e);
FamilyTreeObjectModel ftom = (ObjectModel as FamilyTreeObjectModel);
+
+ EditorDocumentExplorerNode nodeDashboard = new EditorDocumentExplorerNode("Dashboard");
+ DocumentExplorer.Nodes.Add(nodeDashboard);
+
+ EditorDocumentExplorerNode nodePeople = new EditorDocumentExplorerNode("People");
+
+ foreach (Person item in ftom.Persons)
+ {
+ EditorDocumentExplorerNode node = new EditorDocumentExplorerNode(item.ToString());
+ nodePeople.Nodes.Add(node);
+ }
+
+ DocumentExplorer.Nodes.Add(nodePeople);
+
+ EditorDocumentExplorerNode nodeRelationships = new EditorDocumentExplorerNode("Relationships");
+ DocumentExplorer.Nodes.Add(nodeRelationships);
+
+ EditorDocumentExplorerNode nodeFamilies = new EditorDocumentExplorerNode("Families");
+ DocumentExplorer.Nodes.Add(nodeFamilies);
+
+ EditorDocumentExplorerNode nodeCharts = new EditorDocumentExplorerNode("Charts");
+ DocumentExplorer.Nodes.Add(nodeCharts);
+
+ EditorDocumentExplorerNode nodeEvents = new EditorDocumentExplorerNode("Events");
+ foreach (Event item in ftom.Events)
+ {
+ EditorDocumentExplorerNode node = new EditorDocumentExplorerNode(item.ToString());
+ nodeEvents.Nodes.Add(node);
+ }
+ DocumentExplorer.Nodes.Add(nodeEvents);
+
+ EditorDocumentExplorerNode nodePlaces = new EditorDocumentExplorerNode("Places");
+ foreach (Place item in ftom.Places)
+ {
+ EditorDocumentExplorerNode node = new EditorDocumentExplorerNode(item.ToString());
+ nodePlaces.Nodes.Add(node);
+ }
+ DocumentExplorer.Nodes.Add(nodePlaces);
+
+ EditorDocumentExplorerNode nodeGeography = new EditorDocumentExplorerNode("Geography");
+ DocumentExplorer.Nodes.Add(nodeGeography);
+
+ EditorDocumentExplorerNode nodeSources = new EditorDocumentExplorerNode("Sources");
+ DocumentExplorer.Nodes.Add(nodeSources);
+
+ EditorDocumentExplorerNode nodeCitations = new EditorDocumentExplorerNode("Citations");
+ DocumentExplorer.Nodes.Add(nodeCitations);
+
+ EditorDocumentExplorerNode nodeRepositories = new EditorDocumentExplorerNode("Repositories");
+ DocumentExplorer.Nodes.Add(nodeRepositories);
+
+ EditorDocumentExplorerNode nodeMedia = new EditorDocumentExplorerNode("Media");
+ DocumentExplorer.Nodes.Add(nodeMedia);
+
+ EditorDocumentExplorerNode nodeNotes = new EditorDocumentExplorerNode("Notes");
+ DocumentExplorer.Nodes.Add(nodeNotes);
}
}
}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/Associations/Gramps/Gramps.uexml b/Plugins/UniversalEditor.Plugins.Genealogy/Associations/Gramps/Gramps.uexml
new file mode 100644
index 00000000..de24c9b5
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/Associations/Gramps/Gramps.uexml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+ *.gramps
+
+
+
+ 1F8B
+
+
+
+
+
+ *.gramps
+
+
+
+ <?xml
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/DataFormats/Gramps/XML/GrampsXMLDataFormat.cs b/Plugins/UniversalEditor.Plugins.Genealogy/DataFormats/Gramps/XML/GrampsXMLDataFormat.cs
new file mode 100644
index 00000000..de60e499
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/DataFormats/Gramps/XML/GrampsXMLDataFormat.cs
@@ -0,0 +1,400 @@
+//
+// GrampsXMLDataFormat.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+using System.Collections.Generic;
+using UniversalEditor.Accessors;
+using UniversalEditor.DataFormats.Markup.XML;
+using UniversalEditor.ObjectModels.Markup;
+using UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree;
+
+namespace UniversalEditor.Plugins.Genealogy.DataFormats.Gramps.XML
+{
+ public class GrampsXMLDataFormat : XMLDataFormat
+ {
+ private static DataFormatReference _dfr = null;
+ protected override DataFormatReference MakeReferenceInternal()
+ {
+ if (_dfr == null)
+ {
+ _dfr = new DataFormatReference(GetType());
+ _dfr.Capabilities.Add(typeof(FamilyTreeObjectModel), DataFormatCapabilities.All);
+ }
+ return _dfr;
+ }
+
+ protected override void BeforeLoadInternal(Stack objectModels)
+ {
+ base.BeforeLoadInternal(objectModels);
+
+ byte[] hints = Accessor.Reader.ReadBytes(2);
+ if (hints[0] == 0x1F && hints[1] == 0x8B)
+ {
+ Accessor.Seek(-2, IO.SeekOrigin.Current);
+ byte[] data = Accessor.Reader.ReadToEnd();
+
+ System.IO.MemoryStream ms = new System.IO.MemoryStream(data);
+ System.IO.MemoryStream msout = new System.IO.MemoryStream();
+ Compression.CompressionModule.FromKnownCompressionMethod(Compression.CompressionMethod.Gzip).Decompress(ms, msout);
+
+ MemoryAccessor ma = new MemoryAccessor(msout.ToArray());
+
+ Accessor = ma;
+ }
+
+ objectModels.Push(new MarkupObjectModel());
+ }
+
+ protected override void AfterLoadInternal(Stack objectModels)
+ {
+ base.AfterLoadInternal(objectModels);
+
+ MarkupObjectModel mom = (objectModels.Pop() as MarkupObjectModel);
+ FamilyTreeObjectModel ftom = (objectModels.Pop() as FamilyTreeObjectModel);
+
+ MarkupTagElement tagDatabase = mom.Elements["database"] as MarkupTagElement;
+ if (tagDatabase == null) throw new InvalidDataFormatException();
+
+ Dictionary _eventsByHandle = new Dictionary();
+ Dictionary _placesByHandle = new Dictionary();
+ Dictionary _citationsByHandle = new Dictionary();
+ Dictionary _personsByHandle = new Dictionary();
+
+ Dictionary _eventPlaceHandles = new Dictionary();
+ Dictionary> _citationHandles = new Dictionary>();
+
+ MarkupTagElement tagEvents = tagDatabase.Elements["events"] as MarkupTagElement;
+ if (tagEvents != null)
+ {
+ foreach (MarkupElement elEvent in tagEvents.Elements)
+ {
+ MarkupTagElement tagEvent = (elEvent as MarkupTagElement);
+ if (tagEvent == null) continue;
+ if (tagEvent.Name != "event") continue;
+
+ MarkupAttribute attEventID = tagEvent.Attributes["id"];
+ MarkupAttribute attEventHandle = tagEvent.Attributes["handle"];
+ MarkupAttribute attEventChangeTimestamp = tagEvent.Attributes["change"];
+
+ Event evt = new Event();
+ evt.ID = attEventID.Value;
+ _eventsByHandle[attEventHandle.Value] = evt;
+
+ foreach (MarkupElement el in tagEvent.Elements)
+ {
+ MarkupTagElement tag = (el as MarkupTagElement);
+ if (tag == null) continue;
+
+ switch (tag.Name)
+ {
+ case "type":
+ {
+ evt.Type = tag.Value;
+ break;
+ }
+ case "dateval":
+ {
+ evt.Date = ParseDateReference(tag);
+ break;
+ }
+ case "place":
+ {
+ _eventPlaceHandles[evt] = tag.Attributes["hlink"].Value;
+ break;
+ }
+ case "description":
+ {
+ evt.Description = tag.Value;
+ break;
+ }
+ case "attribute":
+ {
+ DatabaseAttribute att = new DatabaseAttribute();
+ MarkupAttribute attType = tag.Attributes["type"];
+ MarkupAttribute attValue = tag.Attributes["value"];
+ if (attType == null || attValue == null)
+ continue;
+
+ att.Name = attType.Value;
+ att.Value = attValue.Value;
+
+ LoadCitations(_citationHandles, tag, att);
+
+ evt.Attributes.Add(att);
+ break;
+ }
+ case "noteref":
+ {
+ break;
+ }
+ }
+ }
+
+ LoadCitations(_citationHandles, tagEvent, evt);
+ }
+ }
+
+ MarkupTagElement tagPeople = tagDatabase.Elements["people"] as MarkupTagElement;
+ if (tagPeople != null)
+ {
+ foreach (MarkupElement elPerson in tagPeople.Elements)
+ {
+ MarkupTagElement tagPerson = (elPerson as MarkupTagElement);
+ if (tagPerson == null) continue;
+ if (tagPerson.Name != "person") continue;
+
+ MarkupAttribute attHandle = tagPerson.Attributes["handle"];
+ MarkupAttribute attChange = tagPerson.Attributes["change"];
+ MarkupAttribute attID = tagPerson.Attributes["id"];
+
+ Person person = new Person();
+ person.ID = attID.Value;
+ _personsByHandle[attHandle.Value] = person;
+
+ foreach (MarkupElement el in tagPerson.Elements)
+ {
+ MarkupTagElement tag = el as MarkupTagElement;
+ if (tag == null) continue;
+
+ switch (tag.Name)
+ {
+ case "gender":
+ {
+ switch (tag.Value.ToLower())
+ {
+ case "m":
+ {
+ person.Gender = Gender.Male;
+ break;
+ }
+ }
+ break;
+ }
+ case "name":
+ {
+ PersonName name = ParseName(tag);
+ if (name != null)
+ {
+ person.Names.Add(name);
+ }
+ if (person.Names.Count > 0)
+ {
+ person.DefaultName = person.Names[0];
+ }
+ break;
+ }
+ }
+ }
+
+ ftom.Persons.Add(person);
+ }
+ }
+
+ MarkupTagElement tagPlaces = tagDatabase.Elements["places"] as MarkupTagElement;
+ if (tagPlaces != null)
+ {
+ foreach (MarkupElement elPlaceObj in tagPlaces.Elements)
+ {
+ MarkupTagElement tagPlaceObj = (elPlaceObj as MarkupTagElement);
+ if (tagPlaceObj == null) continue;
+ if (tagPlaceObj.Name != "placeobj") continue;
+
+ MarkupAttribute attHandle = tagPlaceObj.Attributes["handle"];
+ MarkupAttribute attChange = tagPlaceObj.Attributes["change"];
+ MarkupAttribute attID = tagPlaceObj.Attributes["id"];
+ MarkupAttribute attType = tagPlaceObj.Attributes["type"];
+
+ Place place = new Place();
+ _placesByHandle[attHandle.Value] = place;
+ // place.Type = PlaceType.Parse(attType.Value);
+ foreach (MarkupElement el in tagPlaceObj.Elements)
+ {
+ MarkupTagElement tag = (el as MarkupTagElement);
+ if (tag == null) continue;
+
+ switch (tag.Name)
+ {
+ case "ptitle":
+ {
+ place.Title = tag.Value;
+ break;
+ }
+ case "code":
+ {
+ place.Code = tag.Value;
+ break;
+ }
+ case "pname":
+ {
+ place.Names.Add(ParsePlaceName(tag));
+ break;
+ }
+ }
+ }
+ ftom.Places.Add(place);
+ }
+ }
+
+ MarkupTagElement tagCitations = tagDatabase.Elements["citations"] as MarkupTagElement;
+ if (tagCitations != null)
+ {
+ foreach (MarkupElement elCitation in tagCitations.Elements)
+ {
+ MarkupTagElement tagCitation = (elCitation as MarkupTagElement);
+ if (tagCitation == null) continue;
+ if (tagCitation.Name != "citation") continue;
+
+ MarkupAttribute attHandle = tagCitation.Attributes["handle"];
+ MarkupAttribute attChange = tagCitation.Attributes["change"];
+ MarkupAttribute attID = tagCitation.Attributes["id"];
+
+ Citation citation = new Citation();
+ _citationsByHandle[attHandle.Value] = citation;
+
+ ftom.Citations.Add(citation);
+ }
+ }
+
+ // go through and apply all reference handles
+ foreach (KeyValuePair eventPlaceHandle in _eventPlaceHandles)
+ {
+ eventPlaceHandle.Key.Place = _placesByHandle[eventPlaceHandle.Value];
+ }
+ foreach (KeyValuePair> citationHandle in _citationHandles)
+ {
+ foreach (string handle in citationHandle.Value)
+ {
+ citationHandle.Key.Citations.Add(_citationsByHandle[handle]);
+ }
+ }
+
+
+ objectModels.Push(ftom);
+ }
+
+ private PlaceName ParsePlaceName(MarkupTagElement tag)
+ {
+ PlaceName name = new PlaceName();
+ name.Value = tag.Value;
+ if (tag.Attributes["lang"] != null)
+ {
+ name.Language = tag.Attributes["lang"].Value;
+ }
+
+ MarkupTagElement tagDateSpan = tag.Elements["datespan"] as MarkupTagElement;
+ if (tagDateSpan != null)
+ {
+ name.DateSpan = new DateReference(Date.Parse(tagDateSpan.Attributes["start"]?.Value), Date.Parse(tagDateSpan.Attributes["stop"]?.Value), DateType.Range);
+ }
+
+ return name;
+ }
+
+ private PersonName ParseName(MarkupTagElement tag)
+ {
+ PersonName name = new PersonName();
+ name.Type = PersonNameType.Parse(tag.Attributes["type"]?.Value);
+ foreach (MarkupElement el in tag.Elements)
+ {
+ MarkupTagElement tag2 = (el as MarkupTagElement);
+ if (tag2 == null) continue;
+ switch (tag2.Name)
+ {
+ case "first":
+ {
+ name.CompleteGivenName = tag2.Value;
+ break;
+ }
+ case "surname":
+ {
+ name.Surnames.Add(ParseSurname(tag2));
+ break;
+ }
+ }
+ }
+ return name;
+ }
+
+ private Surname ParseSurname(MarkupTagElement tag)
+ {
+ Surname name = new Surname();
+ name.Origin = SurnameOrigin.Parse(tag.Attributes["derivation"]?.Value);
+ name.Name = tag.Value;
+ return name;
+ }
+
+ private void LoadCitations(Dictionary> citationHandles, MarkupTagElement tag, CitableDatabaseObject obj)
+ {
+ foreach (MarkupElement el in tag.Elements)
+ {
+ MarkupTagElement tag2 = (el as MarkupTagElement);
+ if (tag2 == null) continue;
+
+ switch (tag2.Name)
+ {
+ case "citationref":
+ {
+ if (!citationHandles.ContainsKey(obj))
+ {
+ citationHandles[obj] = new List();
+ }
+ citationHandles[obj].Add(tag2.Attributes["hlink"].Value);
+ break;
+ }
+ }
+ }
+ }
+
+ private DateReference ParseDateReference(MarkupTagElement tag)
+ {
+ MarkupAttribute attVal = tag.Attributes["val"];
+
+ if (attVal == null) throw new FormatException("'val' attribute not found on dateval tag");
+ DateReference date = DateReference.Parse(attVal.Value);
+
+ MarkupAttribute attType = tag.Attributes["type"];
+ if (attType != null)
+ {
+ switch (attType.Value.ToLower())
+ {
+ case "about":
+ {
+ date.Type = DateType.Approximate;
+ break;
+ }
+ }
+ }
+
+ return date;
+ }
+
+ protected override void BeforeSaveInternal(Stack objectModels)
+ {
+ base.BeforeSaveInternal(objectModels);
+
+ FamilyTreeObjectModel ftom = (objectModels.Pop() as FamilyTreeObjectModel);
+ MarkupObjectModel mom = new MarkupObjectModel();
+
+ objectModels.Push(mom);
+ }
+
+
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/CitableDatabaseObject.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/CitableDatabaseObject.cs
new file mode 100644
index 00000000..5042c474
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/CitableDatabaseObject.cs
@@ -0,0 +1,30 @@
+//
+// CitableDatabaseObject.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree
+{
+ public abstract class CitableDatabaseObject : DatabaseObject
+ {
+ public CitableDatabaseObject()
+ {
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Citation.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Citation.cs
new file mode 100644
index 00000000..2b1cfd54
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Citation.cs
@@ -0,0 +1,36 @@
+//
+// Citation.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree
+{
+ public class Citation
+ {
+ public class CitationCollection
+ : System.Collections.ObjectModel.Collection
+ {
+
+ }
+
+ public Citation()
+ {
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/DatabaseAttribute.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/DatabaseAttribute.cs
new file mode 100644
index 00000000..6bb72adb
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/DatabaseAttribute.cs
@@ -0,0 +1,48 @@
+//
+// DatabaseAttribute.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree
+{
+ public class DatabaseAttribute : CitableDatabaseObject
+ {
+ public class DatabaseAttributeCollection
+ : System.Collections.ObjectModel.Collection
+ {
+
+ }
+
+ public DatabaseAttribute()
+ {
+ }
+
+ public string Name { get; set; } = null;
+ public string Value { get; set; } = null;
+
+ protected override DatabaseObject CloneInternal()
+ {
+ DatabaseAttribute clone = new DatabaseAttribute();
+ CloneTo(clone);
+ clone.Name = (Name?.Clone() as string);
+ clone.Value = (Value?.Clone() as string);
+ return clone;
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/DatabaseObject.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/DatabaseObject.cs
new file mode 100644
index 00000000..cc982f26
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/DatabaseObject.cs
@@ -0,0 +1,48 @@
+//
+// ICloneable.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+using System.Collections.Generic;
+
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree
+{
+ public abstract class DatabaseObject : ICloneable
+ {
+ public DatabaseObject()
+ {
+ }
+
+ public string ID { get; set; } = null;
+ public string Title { get; set; }
+ public Citation.CitationCollection Citations { get; } = new Citation.CitationCollection();
+ public DatabaseAttribute.DatabaseAttributeCollection Attributes { get; } = new DatabaseAttribute.DatabaseAttributeCollection();
+
+ protected void CloneTo(DatabaseObject obj)
+ {
+ obj.ID = ID;
+ }
+
+ protected abstract DatabaseObject CloneInternal();
+ public object Clone()
+ {
+ return CloneInternal();
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Date.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Date.cs
new file mode 100644
index 00000000..e53267f4
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Date.cs
@@ -0,0 +1,74 @@
+//
+// Date.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree
+{
+ public class Date
+ {
+ public int? Year { get; set; } = null;
+ public int? Month { get; set; } = null;
+ public int? Day { get; set; } = null;
+
+ public static Date Parse(string value)
+ {
+ Date date = new Date();
+ if (value.Length == 10 && value.Contains("-"))
+ {
+ // yyyy-mm-dd format
+ string[] parts = value.Split(new char[] { '-' });
+ if ((parts.Length == 3 && (parts[0].Length == 4 && parts[1].Length > 0 && parts[1].Length <= 2 && parts[2].Length > 0 && parts[2].Length <= 2)))
+ {
+ if (int.TryParse(parts[1], out int month) && int.TryParse(parts[2], out int day))
+ {
+ if (month != 0)
+ date.Month = month;
+ if (day != 0)
+ date.Day = day;
+ }
+ if (parts[0] == "????")
+ {
+ date.Year = null;
+ }
+ else if (int.TryParse(parts[0], out int year))
+ {
+ date.Year = year;
+ }
+ }
+ else
+ {
+ throw new FormatException("must be in yyyy-mm-dd format");
+ }
+ }
+ else if (value.Length == 4)
+ {
+ if (int.TryParse(value, out int year))
+ {
+ date.Year = year;
+ }
+ else
+ {
+ throw new FormatException("single four-digit component date must be an integer");
+ }
+ }
+ return date;
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/DateReference.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/DateReference.cs
new file mode 100644
index 00000000..3e0f3376
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/DateReference.cs
@@ -0,0 +1,77 @@
+//
+// DateReference.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree
+{
+ public class DateReference
+ {
+ private DateTime _val = DateTime.Now;
+ private string _valstr = null;
+
+ private DateReference()
+ {
+ }
+
+ public DateReference(Date date)
+ {
+ StartDate = date;
+ EndDate = null;
+ Type = DateType.Exact;
+ }
+ public DateReference(Date startDate, Date endDate, DateType type)
+ {
+ StartDate = startDate;
+ EndDate = endDate;
+ Type = type;
+ }
+
+ public DateType Type { get; set; } = DateType.Exact;
+
+ public Date StartDate { get; set; } = null;
+ public Date EndDate { get; set; } = null;
+
+ public static DateReference Parse(string value)
+ {
+ // hack: this is for english locales only
+ DateReference date = new DateReference();
+ if (value.Contains("from ") && value.Contains(" to "))
+ {
+ date.Type = DateType.Range;
+ }
+ else if (value.StartsWith("about "))
+ {
+ date.Type = DateType.Approximate;
+ date.StartDate = Date.Parse(value.Substring("about ".Length));
+ }
+ else if (value.Contains("between ") && value.Contains(" and "))
+ {
+ date.Type = DateType.Range2;
+ }
+ else
+ {
+ date.Type = DateType.Exact;
+ date.StartDate = Date.Parse(value);
+ date.EndDate = null;
+ }
+ return date;
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/DateType.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/DateType.cs
new file mode 100644
index 00000000..74fdbbd0
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/DateType.cs
@@ -0,0 +1,37 @@
+//
+// DateConfidence.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree
+{
+ public enum DateType
+ {
+ Exact,
+ Approximate,
+ ///
+ /// from x to y
+ ///
+ Range,
+ ///
+ /// between x and y
+ ///
+ Range2
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Event.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Event.cs
new file mode 100644
index 00000000..23939759
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Event.cs
@@ -0,0 +1,51 @@
+//
+// Event.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree
+{
+ public class Event : CitableDatabaseObject
+ {
+ public string Type { get; set; } = null;
+ public DateReference Date { get; set; } = null;
+ public Place Place { get; set; } = null;
+ public string Description { get; set; } = null;
+
+ public class EventCollection
+ : System.Collections.ObjectModel.Collection
+ {
+
+ }
+
+ public Event()
+ {
+ }
+
+ protected override DatabaseObject CloneInternal()
+ {
+ Event clone = new Event();
+ CloneTo(clone);
+ clone.Type = Type?.Clone() as string;
+ clone.Date = Date;
+ clone.Place = Place;
+ return clone;
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/FamilyTreeObjectModel.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/FamilyTreeObjectModel.cs
index 4caef03c..9e9549c6 100644
--- a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/FamilyTreeObjectModel.cs
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/FamilyTreeObjectModel.cs
@@ -4,12 +4,34 @@
{
public override void Clear ()
{
+ Events.Clear();
+ Persons.Clear();
}
public override void CopyTo (ObjectModel where)
{
+ FamilyTreeObjectModel clone = (where as FamilyTreeObjectModel);
+ if (clone == null) throw new ObjectModelNotSupportedException();
+
+ for (int i = 0; i < Events.Count; i++)
+ {
+ clone.Events.Add(Events[i].Clone() as Event);
+ }
+ for (int i = 0; i < Persons.Count; i++)
+ {
+ clone.Persons.Add(Persons[i].Clone() as Person);
+ }
+ for (int i = 0; i < Places.Count; i++)
+ {
+ clone.Places.Add(Places[i].Clone() as Place);
+ }
}
+ public Event.EventCollection Events { get; } = new Event.EventCollection();
+ public Person.PersonCollection Persons { get; } = new Person.PersonCollection();
+ public Place.PlaceCollection Places { get; } = new Place.PlaceCollection();
+ public Citation.CitationCollection Citations { get; } = new Citation.CitationCollection();
+
private static ObjectModelReference _omr = null;
protected override ObjectModelReference MakeReferenceInternal ()
{
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Gender.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Gender.cs
new file mode 100644
index 00000000..0f2952cf
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Gender.cs
@@ -0,0 +1,37 @@
+//
+// Gender.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree
+{
+ public class Gender
+ {
+ public static Gender Male { get; } = new Gender("Male");
+ public static Gender Female { get; } = new Gender("Female");
+ public static Gender Unknown { get; } = new Gender("Unknown");
+
+ public string Title { get; set; } = null;
+
+ public Gender(string title)
+ {
+ Title = title;
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Person.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Person.cs
new file mode 100644
index 00000000..60f28fa5
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Person.cs
@@ -0,0 +1,83 @@
+//
+// Person.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+using System.Text;
+
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree
+{
+ public class Person : DatabaseObject
+ {
+ public class PersonCollection
+ : System.Collections.ObjectModel.Collection
+ {
+
+ }
+
+ public Person()
+ {
+ }
+ public Person(PersonName name)
+ {
+ Names.Add(name);
+ DefaultName = name;
+ }
+ public Person(PersonName[] names, int defaultIndex = 0)
+ {
+ for (int i = 0; i < names.Length; i++)
+ {
+ Names.Add(names[i]);
+ }
+ if (Names.Count > 0)
+ {
+ DefaultName = Names[defaultIndex];
+ }
+ }
+
+ public PersonName.PersonNameCollection Names { get; } = new PersonName.PersonNameCollection();
+ public PersonName DefaultName { get; set; } = null;
+ public Gender Gender { get; set; } = null;
+
+ public override string ToString()
+ {
+ if (DefaultName != null)
+ {
+ return DefaultName.ToString();
+ }
+ return String.Empty;
+ }
+
+ protected override DatabaseObject CloneInternal()
+ {
+ Person clone = new Person();
+ CloneTo(clone);
+
+ for (int i = 0; i < Names.Count; i++)
+ {
+ clone.Names.Add(Names[i].Clone() as PersonName);
+ if (Names[i] == DefaultName)
+ {
+ clone.DefaultName = clone.Names[clone.Names.Count - 1];
+ }
+ }
+ return clone;
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/PersonName.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/PersonName.cs
new file mode 100644
index 00000000..2a38f06f
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/PersonName.cs
@@ -0,0 +1,147 @@
+//
+// PersonName.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+using System.Text;
+
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree
+{
+ public class PersonName : ICloneable
+ {
+ public class PersonNameCollection
+ : System.Collections.ObjectModel.Collection
+ {
+
+ }
+
+ public PersonNameType Type { get; set; } = null;
+
+ public Surname.SurnameCollection Surnames { get; } = new Surname.SurnameCollection();
+ public string CompleteSurname
+ {
+ get
+ {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < Surnames.Count; i++)
+ {
+ sb.Append(Surnames[i].ToString());
+ if (i < Surnames.Count - 1)
+ {
+ sb.Append(' ');
+ }
+ }
+ return sb.ToString();
+ }
+ set
+ {
+ string[] values = value.Split(new char[] { ' ' });
+ for (int i = 0; i < values.Length; i++)
+ {
+ Surnames.Add(new Surname(values[i]));
+ }
+ }
+ }
+
+ public System.Collections.Specialized.StringCollection GivenNames { get; } = new System.Collections.Specialized.StringCollection();
+ public string CompleteGivenName
+ {
+ get
+ {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < GivenNames.Count; i++)
+ {
+ sb.Append(GivenNames[i]);
+ if (i < GivenNames.Count - 1)
+ {
+ sb.Append(' ');
+ }
+ }
+ return sb.ToString();
+ }
+ set
+ {
+ GivenNames.Clear();
+
+ if (value != null)
+ {
+ string[] names = value.Split(new char[] { ' ' });
+ for (int i = 0; i < names.Length; i++)
+ {
+ GivenNames.Add(names[i]);
+ }
+ }
+ }
+ }
+
+ public string CallName { get; set; } = null;
+ public string Title { get; set; } = null;
+ public string Suffix { get; set; } = null;
+ public string Nickname { get; set; } = null;
+
+ public object Clone()
+ {
+ PersonName clone = new PersonName();
+ for (int i = 0; i < Surnames.Count; i++)
+ {
+ clone.Surnames.Add(Surnames[i].Clone() as Surname);
+ }
+ for (int i = 0; i < GivenNames.Count; i++)
+ {
+ clone.GivenNames.Add(GivenNames[i].Clone() as string);
+ }
+ return clone;
+ }
+
+ public string GroupSurname { get; set; } = null;
+ public PersonNameFormatter SortFormat { get; set; } = null;
+ public PersonNameFormatter DisplayFormat { get; set; } = null;
+
+ public PersonName()
+ {
+
+ }
+ public PersonName(string completeSurname, string completeGivenName)
+ {
+ CompleteSurname = completeSurname;
+ CompleteGivenName = completeGivenName;
+ }
+ public PersonName(Surname[] surnames, string[] givenNames)
+ {
+ for (int i = 0; i < surnames.Length; i++)
+ {
+ Surnames.Add(surnames[i]);
+ }
+ for (int i = 0; i < givenNames.Length; i++)
+ {
+ GivenNames.Add(givenNames[i]);
+ }
+ }
+
+ public override string ToString()
+ {
+ if (DisplayFormat != null)
+ {
+ return base.ToString();
+ }
+ return PersonNameFormatter.Default.Format(this);
+ }
+
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/PersonNameFormatter.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/PersonNameFormatter.cs
new file mode 100644
index 00000000..560a3944
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/PersonNameFormatter.cs
@@ -0,0 +1,37 @@
+//
+// PersonNameFormat.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+using System.Text;
+
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree
+{
+ public class PersonNameFormatter : StringFormatting.StringFormatter
+ {
+ public static PersonNameFormatter Default { get; } = new PersonNameFormatter();
+
+ static PersonNameFormatter()
+ {
+ Default.Parts.Add(new StringFormatting.FormattingParts.PropertyStringFormattingPart("CompleteSurname"));
+ Default.Parts.Add(new StringFormatting.FormattingParts.LiteralStringFormattingPart(", "));
+ Default.Parts.Add(new StringFormatting.FormattingParts.PropertyStringFormattingPart("CompleteGivenName"));
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/PersonNameType.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/PersonNameType.cs
new file mode 100644
index 00000000..55a4a5a8
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/PersonNameType.cs
@@ -0,0 +1,43 @@
+//
+// PersonNameType.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree
+{
+ public class PersonNameType
+ {
+ public static PersonNameType BirthName { get; } = new PersonNameType("Birth Name");
+
+ public string Title { get; set; } = null;
+ public PersonNameType(string title)
+ {
+ Title = title;
+ }
+
+ public static PersonNameType Parse(string value)
+ {
+ switch (value)
+ {
+ case "Birth Name": return PersonNameType.BirthName;
+ default: return new PersonNameType(value);
+ }
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Place.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Place.cs
new file mode 100644
index 00000000..e2b9949d
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Place.cs
@@ -0,0 +1,46 @@
+//
+// Place.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree
+{
+ public class Place : DatabaseObject
+ {
+ public class PlaceCollection
+ : System.Collections.ObjectModel.Collection
+ {
+
+ }
+
+ public PlaceName.PlaceNameCollection Names { get; } = new PlaceName.PlaceNameCollection();
+ public string Code { get; set; } = null;
+
+ protected override DatabaseObject CloneInternal()
+ {
+ Place clone = new Place();
+ CloneTo(clone);
+ foreach (PlaceName name in Names)
+ {
+ clone.Names.Add(name.Clone() as PlaceName);
+ }
+ return clone;
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/PlaceName.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/PlaceName.cs
new file mode 100644
index 00000000..33da9421
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/PlaceName.cs
@@ -0,0 +1,49 @@
+//
+// PlaceName.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree
+{
+ public class PlaceName : ICloneable
+ {
+ public class PlaceNameCollection
+ : System.Collections.ObjectModel.Collection
+ {
+
+ }
+
+ public string Value { get; set; } = null;
+ public DateReference DateSpan { get; set; } = null;
+ public string Language { get; set; } = null;
+
+ public PlaceName()
+ {
+ }
+
+ public object Clone()
+ {
+ PlaceName clone = new PlaceName();
+ clone.Value = (Value?.Clone() as string);
+ clone.DateSpan = DateSpan;
+ clone.Language = (Language?.Clone() as string);
+ return clone;
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/StringFormatting/FormattingParts/LiteralStringFormattingPart.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/StringFormatting/FormattingParts/LiteralStringFormattingPart.cs
new file mode 100644
index 00000000..a8063940
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/StringFormatting/FormattingParts/LiteralStringFormattingPart.cs
@@ -0,0 +1,37 @@
+//
+// StringFormatVariablePart.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree.StringFormatting.FormattingParts
+{
+ public class LiteralStringFormattingPart : StringFormattingPart
+ {
+ public string Value { get; set; } = null;
+ public LiteralStringFormattingPart(string value)
+ {
+ Value = value;
+ }
+
+ protected override string ToStringInternal(object obj)
+ {
+ return Value;
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/StringFormatting/FormattingParts/PropertyStringFormattingPart.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/StringFormatting/FormattingParts/PropertyStringFormattingPart.cs
new file mode 100644
index 00000000..ffc44b6b
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/StringFormatting/FormattingParts/PropertyStringFormattingPart.cs
@@ -0,0 +1,46 @@
+//
+// PropertyStringFormattingPart.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree.StringFormatting.FormattingParts
+{
+ public class PropertyStringFormattingPart : StringFormattingPart
+ {
+ public string PropertyName { get; set; } = null;
+
+ public PropertyStringFormattingPart(string propertyName)
+ {
+ PropertyName = propertyName;
+ }
+
+ protected override string ToStringInternal(object obj)
+ {
+ if (obj != null)
+ {
+ Type t = obj.GetType();
+ System.Reflection.PropertyInfo pi = t.GetProperty(PropertyName, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
+ object objV = pi.GetValue(obj, null);
+ if (objV != null)
+ return objV.ToString();
+ }
+ return null;
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/StringFormatting/StringFormatter.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/StringFormatting/StringFormatter.cs
new file mode 100644
index 00000000..646aca2e
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/StringFormatting/StringFormatter.cs
@@ -0,0 +1,44 @@
+//
+// StringFormatter.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+using System.Text;
+
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree.StringFormatting
+{
+ public class StringFormatter
+ {
+ public StringFormatter()
+ {
+ }
+
+ public StringFormatting.StringFormattingPart.StringFormattingPartCollection Parts { get; } = new StringFormatting.StringFormattingPart.StringFormattingPartCollection();
+
+ public string Format(object obj)
+ {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < Parts.Count; i++)
+ {
+ sb.Append(Parts[i].ToString(obj));
+ }
+ return sb.ToString();
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/StringFormatting/StringFormattingPart.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/StringFormatting/StringFormattingPart.cs
new file mode 100644
index 00000000..9b560db2
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/StringFormatting/StringFormattingPart.cs
@@ -0,0 +1,42 @@
+//
+// StringFormattingPart.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree.StringFormatting
+{
+ public abstract class StringFormattingPart
+ {
+ public class StringFormattingPartCollection
+ : System.Collections.ObjectModel.Collection
+ {
+
+ }
+
+ public StringFormattingPart()
+ {
+ }
+
+ protected abstract string ToStringInternal(object obj);
+ public string ToString(object obj)
+ {
+ return ToStringInternal(obj);
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Surname.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Surname.cs
new file mode 100644
index 00000000..b401de4f
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/Surname.cs
@@ -0,0 +1,100 @@
+//
+// Surname.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+using System.Text;
+
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree
+{
+ public class Surname : ICloneable
+ {
+ public class SurnameCollection
+ : System.Collections.ObjectModel.Collection
+ {
+
+ }
+
+ public string Prefix { get; set; } = null;
+ public string Name { get; set; } = null;
+ public string Connector { get; set; } = null;
+ public SurnameOrigin Origin { get; set; } = SurnameOrigin.Unknown;
+ public bool Primary { get; set; } = true;
+
+ public Surname()
+ {
+ }
+ public Surname(string name)
+ : this(null, name)
+ {
+ }
+ public Surname(string prefix, string name)
+ : this(prefix, name, null)
+ {
+ }
+ public Surname(string prefix, string name, string connector)
+ : this(prefix, name, connector, SurnameOrigin.Unknown)
+ {
+ }
+ public Surname(string prefix, string name, string connector, SurnameOrigin origin)
+ : this(prefix, name, connector, origin, true)
+ {
+ }
+ public Surname(string prefix, string name, string connector, SurnameOrigin origin, bool primary)
+ {
+ Prefix = prefix;
+ Name = name;
+ Connector = connector;
+ Origin = origin;
+ Primary = primary;
+ }
+
+ public object Clone()
+ {
+ Surname clone = new Surname();
+ clone.Prefix = (Prefix?.Clone() as string);
+ clone.Name = (Name?.Clone() as string);
+ clone.Connector = (Connector?.Clone() as string);
+ clone.Origin = (Origin?.Clone() as SurnameOrigin);
+ clone.Primary = Primary;
+ return clone;
+ }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ if (Prefix != null)
+ {
+ sb.Append(Prefix);
+ sb.Append(' ');
+ }
+ if (Name != null)
+ {
+ sb.Append(Name);
+ sb.Append(' ');
+ }
+ if (Connector != null)
+ {
+ sb.Append(Connector);
+ sb.Append(' ');
+ }
+ return sb.ToString().Trim();
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/SurnameOrigin.cs b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/SurnameOrigin.cs
new file mode 100644
index 00000000..029d43ee
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/ObjectModels/FamilyTree/SurnameOrigin.cs
@@ -0,0 +1,56 @@
+//
+// SurnameOrigin.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+namespace UniversalEditor.Plugins.Genealogy.ObjectModels.FamilyTree
+{
+ public class SurnameOrigin : ICloneable
+ {
+ public static SurnameOrigin Patrilineal { get; } = new SurnameOrigin(new Guid("{e54fefde-6dee-42fa-bb17-acc78c4bf7e1}"), "Patrilineal");
+ public static SurnameOrigin Matrilineal { get; } = new SurnameOrigin(new Guid("{25bce564-5785-4621-9990-5dc4e7ee9d1e}"), "Matrilineal");
+ public static SurnameOrigin Unknown { get; } = new SurnameOrigin(Guid.Empty, "Unknown");
+
+ private Guid id = Guid.Empty;
+ public string Title { get; set; } = null;
+ public SurnameOrigin(Guid id, string title)
+ {
+ this.id = id;
+ Title = title;
+ }
+
+ public object Clone()
+ {
+ SurnameOrigin clone = new SurnameOrigin(id, Title);
+ return clone;
+ }
+
+ public static SurnameOrigin Parse(string value)
+ {
+ if (value == null) return null;
+ switch (value.ToLower())
+ {
+ case "matrilineal": return SurnameOrigin.Matrilineal;
+ case "patrilineal": return SurnameOrigin.Patrilineal;
+ }
+
+ return new SurnameOrigin(Guid.Empty, value);
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.Genealogy/UniversalEditor.Plugins.Genealogy.csproj b/Plugins/UniversalEditor.Plugins.Genealogy/UniversalEditor.Plugins.Genealogy.csproj
index 281e4048..a1299948 100644
--- a/Plugins/UniversalEditor.Plugins.Genealogy/UniversalEditor.Plugins.Genealogy.csproj
+++ b/Plugins/UniversalEditor.Plugins.Genealogy/UniversalEditor.Plugins.Genealogy.csproj
@@ -5,7 +5,7 @@
AnyCPU
{74A835FD-93B8-4268-B120-1ACAA128AC7B}
Library
- UniversalEditor.Plugins.FamilyTreeMaker
+ UniversalEditor.Plugins.Genealogy
UniversalEditor.Plugins.FamilyTreeMaker
4.0.2019.12
@@ -39,6 +39,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -49,6 +71,11 @@
+
+
+
+
+
@@ -78,6 +105,7 @@
+