public Vertex AddIndividual(GDMIndividualRecord iRec) { return((iRec == null) ? null : fGraph.AddVertex(iRec.XRef, iRec)); }
// This is the main tree drawing method. // irSubject is the individual for whom the tree is based. // nTargeWidth is the width below which the layout is free to use up space to produce a nice tree. public List <MiniTreeMap> CreateMiniTree(Paintbox paintbox, GDMIndividualRecord ir, string fileName, int targetWidth, ImageFormat imageFormat) { // First calculate size required for tree, by iterating through individuals and building a data structure MiniTreeGroup mtgParent = CreateDataStructure(ir); // For each individual calculate size of box required for display using helper function // There must be a better way to get a graphics: Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format24bppRgb); Graphics g = Graphics.FromImage(bmp); Font f = paintbox.Font; // Record what font windows actually used, in case it chose a different one CConfig.Instance.TreeFontName = f.Name; CConfig.Instance.TreeFontSize = f.Size; // Recursively calculate sizes of other groups mtgParent.CalculateSize(g, f); g.Dispose(); bmp.Dispose(); // Now calculate sizes of each row // Total width includes irSubject, their spouses and their siblings. // Total height is always three generations // Now calculate how best to position each generation // Calculate the width of each generation // There are three cases : frParents widest, siblings widest, children widest // Plus two aims : minimise total width, get offspring centred under frParents. // If nTargetWidth is exceeded simply because of number of individuals in one row, that // row's width becomes the new target width. // If nTargetWidth is exceeded otherwise, minimising total width becomes the priority mtgParent.CalculateLayout(0f, 0f); mtgParent.Compress(); RectangleF rect = mtgParent.GetExtent(); fSizeTotal = new SizeF(rect.Width, rect.Height); mtgParent.Translate(-rect.Left, -rect.Top); // Calculate offset for each row // Can't do this so create a new bitmap: bmp.Width = totalSize.Width; // Can't do this so create a new bitmap: bmp.Height = totalSize.Height; int nTotalWidth = (int)(fSizeTotal.Width + 1.0f); int nTotalHeight = (int)(fSizeTotal.Height + 1.0f); bmp = new Bitmap(nTotalWidth, nTotalHeight, PixelFormat.Format32bppArgb); g = Graphics.FromImage(bmp); // Do background fill if (CConfig.Instance.FakeMiniTreeTransparency && paintbox.BrushFakeTransparency != null) { g.FillRectangle(paintbox.BrushFakeTransparency, 0, 0, nTotalWidth, nTotalHeight); } else if (imageFormat == ImageFormat.Gif && paintbox.BrushBgGif != null) { g.FillRectangle(paintbox.BrushBgGif, 0, 0, nTotalWidth, nTotalHeight); } List <MiniTreeMap> alMap = new List <MiniTreeMap>(); mtgParent.DrawBitmap(paintbox, g, alMap); // Save the bitmap fLogger.WriteInfo("Saving mini tree as " + fileName); if (File.Exists(fileName)) { // Delete any current file File.SetAttributes(fileName, FileAttributes.Normal); File.Delete(fileName); } // Save using FileStream to try to avoid crash (only seen by customers) FileStream fs = new FileStream(fileName, FileMode.Create); bmp.Save(fs, imageFormat); fs.Close(); g.Dispose(); bmp.Dispose(); // For gifs we need to reload and set transparency colour if (imageFormat == ImageFormat.Gif && !CConfig.Instance.FakeMiniTreeTransparency) { Image imageGif; ColorPalette colorpalette; imageGif = Image.FromFile(fileName); colorpalette = imageGif.Palette; // Creates a new GIF image with a modified colour palette if (colorpalette != null) { // Create a new 8 bit per pixel image Bitmap bm = new Bitmap(imageGif.Width, imageGif.Height, PixelFormat.Format8bppIndexed); // Get it's palette ColorPalette colorpaletteNew = bm.Palette; // Copy all the entries from the old palette removing any transparency int n = 0; foreach (Color c in colorpalette.Entries) { colorpaletteNew.Entries[n++] = Color.FromArgb(255, c); } // Now to copy the actual bitmap data // Lock the source and destination bits BitmapData src = ((Bitmap)imageGif).LockBits(new Rectangle(0, 0, imageGif.Width, imageGif.Height), ImageLockMode.ReadOnly, imageGif.PixelFormat); BitmapData dst = bm.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.WriteOnly, bm.PixelFormat); // Uses pointers so we need unsafe code. // The project is also compiled with /unsafe byte backColor = 0; unsafe { backColor = ((byte *)src.Scan0.ToPointer())[0]; // Assume transparent colour appears as first pixel. byte *src_ptr = ((byte *)src.Scan0.ToPointer()); byte *dst_ptr = ((byte *)dst.Scan0.ToPointer()); // May be useful: System.Runtime.InteropServices.Marshal.Copy(IntPtr source, byte[], destination, int start, int length) // May be useful: System.IO.MemoryStream ms = new System.IO.MemoryStream(src_ptr); int width = imageGif.Width; int src_stride = src.Stride - width; int dst_stride = dst.Stride - width; for (int y = 0; y < imageGif.Height; y++) { // Can't convert IntPtr to byte[]: Buffer.BlockCopy( src_ptr, 0, dst_ptr, 0, width ); int x = width; while (x-- > 0) { *dst_ptr++ = *src_ptr++; } src_ptr += src_stride; dst_ptr += dst_stride; } } // Set the newly selected transparency colorpaletteNew.Entries[(int)backColor] = Color.FromArgb(0, Color.Magenta); // Re-insert the palette bm.Palette = colorpaletteNew; // All done, unlock the bitmaps ((Bitmap)imageGif).UnlockBits(src); bm.UnlockBits(dst); imageGif.Dispose(); // Set the new image in place imageGif = bm; colorpalette = imageGif.Palette; fLogger.WriteInfo("Re-saving mini gif as " + fileName); imageGif.Save(fileName, imageFormat); } } return(alMap); }
// Returns true if the supplied record is valid for inclusion in the tree private static bool Exists(GDMIndividualRecord ir) { return(ir != null && GMHelper.GetVisibility(ir)); }
public static void FillContext(IBaseContext context) { // a null result if the record is not defined GDMCustomEvent evt = context.CreateEventEx(null, GEDCOMTagName.BIRT, "xxxxx", "xxxxx"); Assert.IsNull(evt); // first individual (I1) GDMIndividualRecord iRec = context.CreatePersonEx("Ivan", "Ivanovich", "Ivanov", GDMSex.svMale, true); Assert.IsNotNull(iRec); evt = iRec.FindEvent(GEDCOMTagType.BIRT); Assert.IsNotNull(evt); evt.Date.ParseString("28 DEC 1990"); evt.Place.StringValue = "Ivanovo"; GDMCustomEvent evtd = context.CreateEventEx(iRec, GEDCOMTagName.DEAT, "28 DEC 2010", "Ivanovo"); Assert.IsNotNull(evtd); // second individual, wife (I2) GDMIndividualRecord iRec2 = context.CreatePersonEx("Maria", "Petrovna", "Ivanova", GDMSex.svFemale, true); evt = iRec2.FindEvent(GEDCOMTagType.BIRT); Assert.IsNotNull(evt); evt.Date.ParseString("17 MAR 1991"); evt.Place.StringValue = "Ivanovo"; iRec.AddAssociation("spouse", iRec2); // third individual, child (I3) GDMIndividualRecord iRec3 = context.CreatePersonEx("Anna", "Ivanovna", "Ivanova", GDMSex.svFemale, true); evt = iRec3.FindEvent(GEDCOMTagType.BIRT); Assert.IsNotNull(evt); evt.Date.ParseString("11 FEB 2010"); evt.Place.StringValue = "Ivanovo"; // their family GDMFamilyRecord famRec = context.Tree.CreateFamily(); Assert.IsNotNull(famRec); famRec.AddSpouse(iRec); famRec.AddSpouse(iRec2); famRec.AddChild(iRec3); context.CreateEventEx(famRec, GEDCOMTagName.MARR, "01 JAN 2000", "unknown"); // individual outside the family (I4) GDMIndividualRecord iRec4 = context.CreatePersonEx("Alex", "", "Petrov", GDMSex.svMale, true); evt = iRec4.FindEvent(GEDCOMTagType.BIRT); Assert.IsNotNull(evt); evt.Date.ParseString("15 JUN 1989"); evt.Place.StringValue = "Far Forest"; evt = context.CreateEventEx(iRec4, GEDCOMTagName.RESI, "12 FEB", "Far Forest"); Assert.IsNotNull(evt); // fifth (I5) GDMIndividualRecord iRec5 = context.CreatePersonEx("Anna", "", "Jones", GDMSex.svFemale, false); Assert.IsNotNull(iRec5); // sixth (I6) GDMIndividualRecord iRec6 = context.CreatePersonEx("Mary", "", "Jones", GDMSex.svFemale, false); Assert.IsNotNull(iRec6); evt = context.CreateEventEx(iRec6, GEDCOMTagName.BIRT, "12 FEB 1650", "Far Forest"); GDMFamilyRecord famRec2 = context.Tree.CreateFamily(); Assert.IsNotNull(famRec2); famRec2.AddSpouse(iRec3); //famRec2.AddSpouse(iRec4); famRec2.AddChild(iRec5); famRec2.AddChild(iRec6); // group for tests GDMGroupRecord groupRec = context.Tree.CreateGroup(); groupRec.GroupName = "GroupTest"; Assert.IsNotNull(groupRec, "group1 != null"); groupRec.AddMember(iRec); // location for tests GDMLocationRecord locRec = context.Tree.CreateLocation(); locRec.LocationName = "Test Location"; locRec.Map.Lati = 5.11111; locRec.Map.Long = 7.99999; Assert.IsNotNull(locRec, "locRec != null"); // repository for tests GDMRepositoryRecord repoRec = context.Tree.CreateRepository(); repoRec.RepositoryName = "Test repository"; Assert.IsNotNull(repoRec, "repoRec != null"); // research for tests GDMResearchRecord resRec = context.Tree.CreateResearch(); resRec.ResearchName = "Test research"; Assert.IsNotNull(resRec, "resRec != null"); // source for tests GDMSourceRecord srcRec = context.Tree.CreateSource(); srcRec.ShortTitle = "Test source"; Assert.IsNotNull(srcRec, "srcRec != null"); iRec.AddSource(srcRec, "p1", 0); // note for tests GDMNoteRecord noteRec = context.Tree.CreateNote(); noteRec.SetNoteText("Test note"); Assert.IsNotNull(noteRec, "noteRec != null"); iRec.AddNote(noteRec); // task for tests GDMTaskRecord tskRec = context.Tree.CreateTask(); tskRec.Goal = "Test task"; Assert.IsNotNull(tskRec, "tskRec != null"); // media for tests GDMMultimediaRecord mediaRec = context.Tree.CreateMultimedia(); mediaRec.FileReferences.Add(new GDMFileReferenceWithTitle()); GDMFileReferenceWithTitle fileRef = mediaRec.FileReferences[0]; fileRef.Title = "Test multimedia"; fileRef.LinkFile("sample.png"); Assert.IsNotNull(mediaRec, "mediaRec != null"); iRec.AddMultimedia(mediaRec); // communication for tests GDMCommunicationRecord commRec = context.Tree.CreateCommunication(); commRec.CommName = "Test communication"; Assert.IsNotNull(commRec, "commRec != null"); }
public static void RestrictDescendants(GDMTree tree, GDMIndividualRecord iRec, bool visible) { TreeTools.WalkTree(tree, iRec, TreeTools.TreeWalkMode.twmDescendants, RestrictProc, visible); }
private AncPersonSegment TraverseAncestors(GDMIndividualRecord iRec, float v, int gen, float rad, float ro, int prevSteps, int groupIndex) { try { fIndividualsCount++; if (fGroupsMode && groupIndex == -1) { AncPersonSegment otherSegment = (AncPersonSegment)FindSegmentByRec(iRec); if (otherSegment != null) { fGroupCount++; groupIndex = fGroupCount; TraverseGroups(otherSegment, groupIndex); } } int genSize = 1 << gen; float ang = (360.0f / genSize); int idx = prevSteps + (int)(v / ang); AncPersonSegment segment = SetSegmentParams(idx, iRec, rad, groupIndex); if (segment != null && gen < fVisibleGenerations) { float inRad = rad; float extRad = rad + fGenWidth; segment.IntRad = inRad - 50; segment.ExtRad = extRad - 50; GDMIndividualRecord father = null, mother = null; GDMFamilyRecord fam = iRec.GetParentsFamily(); if (fam != null && fBase.Context.IsRecordAccess(fam.Restriction)) { father = fam.Husband.Individual; mother = fam.Wife.Individual; } int ps = prevSteps + genSize; if (father != null) { v -= (Math.Abs(ang - ro) / 2.0f); segment.FatherSegment = TraverseAncestors(father, v, gen + 1, rad + fGenWidth, ro / 2.0f, ps, groupIndex); } if (mother != null) { v += (ang / 2.0f); segment.MotherSegment = TraverseAncestors(mother, v, gen + 1, rad + fGenWidth, ro / 2.0f, ps, groupIndex); } } return(segment); } catch { return(null); } }
public void BuildBy(GDMIndividualRecord iRec) { try { fRec = iRec; if (iRec != null) { if (fModel.PreparedIndividuals.IndexOf(iRec.XRef) < 0) { fModel.PreparedIndividuals.Add(iRec.XRef); } var parts = GKUtils.GetNameParts(iRec); fSurname = parts.Surname; fName = parts.Name; fPatronymic = parts.Patronymic; fNick = GKUtils.GetNickString(iRec); fSex = iRec.Sex; TreeChartOptions options = fModel.Options; var lifeDates = iRec.GetLifeDates(); DateFormat dateFormat = (options.OnlyYears) ? DateFormat.dfYYYY : DateFormat.dfDD_MM_YYYY; IsDead = (lifeDates.DeathEvent != null); fBirthDate = GKUtils.GEDCOMEventToDateStr(lifeDates.BirthEvent, dateFormat, false); fDeathDate = GKUtils.GEDCOMEventToDateStr(lifeDates.DeathEvent, dateFormat, false); if (!options.OnlyYears) { if (options.ShowPlaces) { string birthPlace = GKUtils.GetPlaceStr(lifeDates.BirthEvent, false); if (!string.IsNullOrEmpty(birthPlace)) { if (!string.IsNullOrEmpty(fBirthDate)) { fBirthDate += ", "; } fBirthDate += birthPlace; } string deathPlace = GKUtils.GetPlaceStr(lifeDates.DeathEvent, false); if (!string.IsNullOrEmpty(deathPlace)) { if (!string.IsNullOrEmpty(fDeathDate)) { fDeathDate += ", "; } fDeathDate += deathPlace; } } if (!string.IsNullOrEmpty(fBirthDate)) { fBirthDate = ImportUtils.STD_BIRTH_SIGN + " " + fBirthDate; } if (!string.IsNullOrEmpty(fDeathDate)) { fDeathDate = ImportUtils.STD_DEATH_SIGN + " " + fDeathDate; } } if (options.SignsVisible) { EnumSet <SpecialUserRef> signs = EnumSet <SpecialUserRef> .Create(); int num = fRec.UserReferences.Count; for (int i = 0; i < num; i++) { string rs = fRec.UserReferences[i].StringValue; for (var cps = SpecialUserRef.urRI_StGeorgeCross; cps <= SpecialUserRef.urLast; cps++) { string sur = LangMan.LS(GKData.SpecialUserRefs[(int)cps].Title); if (rs == sur) { signs.Include(cps); } } } fSigns = signs; } else { fSigns = EnumSet <SpecialUserRef> .Create(); } if (options.PortraitsVisible) { try { fPortrait = PortraitsCache.Instance.GetImage(fModel.Base.Context, iRec); if (fPortrait == null && options.DefaultPortraits) { string resName = (fSex == GDMSex.svFemale) ? "pi_female_140.png" : "pi_male_140.png"; fPortrait = AppHost.GfxProvider.LoadResourceImage(resName, false); } } catch (MediaFileNotFoundException) { if (!fModel.HasMediaFail) { AppHost.StdDialogs.ShowError(LangMan.LS(LSID.LSID_MediaFileNotLoaded)); fModel.HasMediaFail = true; } } } CertaintyAssessment = iRec.GetCertaintyAssessment(); } else { fSurname = ""; fName = "< ? >"; fPatronymic = ""; fNick = ""; fBirthDate = ""; fDeathDate = ""; IsDead = false; fSex = GDMSex.svUnknown; fSigns = EnumSet <SpecialUserRef> .Create(); CertaintyAssessment = 0.0f; } } catch (Exception ex) { Logger.WriteError("TreeChartPerson.BuildBy()", ex); throw; } }
private void WriteExcessFmt(PedigreePerson person) { fWriter.AddParagraph(LangMan.LS(LSID.LSID_Sex) + ": " + GKUtils.SexStr(person.IRec.Sex), fTextFont); string st = GKUtils.GetLifeExpectancyStr(person.IRec); if (st != "?" && st != "") { fWriter.AddParagraph(LangMan.LS(LSID.LSID_LifeExpectancy) + ": " + st, fTextFont); } GDMIndividualRecord father, mother; fTree.GetParents(person.IRec, out father, out mother); if (father != null) { fWriter.AddParagraphLink(LangMan.LS(LSID.LSID_Father) + ": " + GKUtils.GetNameString(father, true, false) + " ", fTextFont, idLink(father), fLinkFont); } if (mother != null) { fWriter.AddParagraphLink(LangMan.LS(LSID.LSID_Mother) + ": " + GKUtils.GetNameString(mother, true, false) + " ", fTextFont, idLink(mother), fLinkFont); } var evList = new ExtList <PedigreeEvent>(true); try { int i; if (person.IRec.Events.Count > 0) { fWriter.AddParagraph(LangMan.LS(LSID.LSID_Events) + ":", fTextFont); int num = person.IRec.Events.Count; for (i = 0; i < num; i++) { GDMCustomEvent evt = person.IRec.Events[i]; if (!(evt is GDMIndividualAttribute) || fOptions.PedigreeOptions.IncludeAttributes) { evList.Add(new PedigreeEvent(person.IRec, evt)); } } WriteEventList(person, evList); } int num2 = person.IRec.SpouseToFamilyLinks.Count; for (i = 0; i < num2; i++) { GDMFamilyRecord family = fTree.GetPtrValue(person.IRec.SpouseToFamilyLinks[i]); if (!fBase.Context.IsRecordAccess(family.Restriction)) { continue; } GDMIndividualRecord spRec; string unk; if (person.IRec.Sex == GDMSex.svMale) { spRec = fTree.GetPtrValue(family.Wife); st = LangMan.LS(LSID.LSID_Wife) + ": "; unk = LangMan.LS(LSID.LSID_UnkFemale); } else { spRec = fTree.GetPtrValue(family.Husband); st = LangMan.LS(LSID.LSID_Husband) + ": "; unk = LangMan.LS(LSID.LSID_UnkMale); } string sps; if (spRec != null) { sps = st + GKUtils.GetNameString(spRec, true, false) + GKUtils.GetPedigreeLifeStr(spRec, fOptions.PedigreeOptions.Format) /* + this.idLink(this.FindPerson(irec))*/; } else { sps = st + unk; } fWriter.AddParagraph(sps, fTextFont); evList.Clear(); int childrenCount = family.Children.Count; for (int j = 0; j < childrenCount; j++) { GDMIndividualRecord child = fTree.GetPtrValue(family.Children[j]); evList.Add(new PedigreeEvent(child, child.FindEvent(GEDCOMTagType.BIRT))); } WriteEventList(person, evList); } } finally { evList.Dispose(); } if (fOptions.PedigreeOptions.IncludeNotes && person.IRec.Notes.Count != 0) { fWriter.AddParagraph(LangMan.LS(LSID.LSID_RPNotes) + ":", fTextFont); fWriter.BeginList(); int notesCount = person.IRec.Notes.Count; for (int i = 0; i < notesCount; i++) { GDMLines noteLines = fTree.GetNoteLines(person.IRec.Notes[i]); fWriter.AddListItem(" " + GKUtils.MergeStrings(noteLines), fTextFont); } fWriter.EndList(); } }
private void GenStep(PedigreePerson parent, GDMIndividualRecord iRec, int level, int familyOrder) { if (iRec == null) { return; } PedigreePerson res = new PedigreePerson(); res.Parent = parent; res.IRec = iRec; res.Level = level; res.ChildIdx = 0; res.FamilyOrder = familyOrder; fPersonList.Add(res); if (fOptions.PedigreeOptions.IncludeSources) { int num = iRec.SourceCitations.Count; for (int i = 0; i < num; i++) { var sourceRec = fTree.GetPtrValue <GDMSourceRecord>(iRec.SourceCitations[i]); if (sourceRec == null) { continue; } int srcIndex = fSourceList.IndexOfObject(sourceRec); if (srcIndex < 0) { string srcName = sourceRec.ShortTitle; string srcTitle = GKUtils.MergeStrings(sourceRec.Title.Lines); if (!string.IsNullOrEmpty(srcName) && !string.IsNullOrEmpty(srcTitle)) { srcName += "\n"; } srcName += srcTitle; srcIndex = fSourceList.AddObject(srcName, sourceRec); } res.Sources.Add((srcIndex + 1).ToString()); } } if (fKind == PedigreeKind.Ascend) { if (iRec.ChildToFamilyLinks.Count > 0) { GDMFamilyRecord family = fTree.GetPtrValue(iRec.ChildToFamilyLinks[0]); if (fBase.Context.IsRecordAccess(family.Restriction)) { GDMIndividualRecord prnt; prnt = fTree.GetPtrValue(family.Wife); GenStep(res, prnt, level + 1, 1); prnt = fTree.GetPtrValue(family.Husband); GenStep(res, prnt, level + 1, 1); } } } else { int num2 = iRec.SpouseToFamilyLinks.Count; for (int j = 0; j < num2; j++) { GDMFamilyRecord family = fTree.GetPtrValue(iRec.SpouseToFamilyLinks[j]); if (!fBase.Context.IsRecordAccess(family.Restriction)) { continue; } fBase.Context.ProcessFamily(family); int num3 = family.Children.Count; for (int i = 0; i < num3; i++) { GDMIndividualRecord child = fTree.GetPtrValue(family.Children[i]); GenStep(res, child, level + 1, i + 1); } } } }
public PedigreeExporter(IBaseWindow baseWin, GDMIndividualRecord root) : base(baseWin, false) { fRoot = root; fTitle = LangMan.LS(LSID.LSID_ExpPedigree) + ": " + GKUtils.GetNameString(fRoot, true, false); fShieldState = baseWin.Context.ShieldState; }
private string idLink(GDMIndividualRecord iRec) { PedigreePerson person = FindPerson(iRec); return((person == null) ? "" : person.Id); }
// The main method that causes the front page to be created. public void Create() { string keywords = "family tree history " + GMConfig.Instance.OwnersName; string title = GMConfig.Instance.SiteTitle; HTMLFile f = null; try { f = new HTMLFile(GMConfig.Instance.FrontPageURL, title, PageDescription, keywords); // Creates a new file, and puts standard header html into it. f.WriteLine(" <div id=\"page\"> <!-- page -->"); f.WriteLine(" <div id=\"cover\"> <!-- cover -->"); f.WriteLine("<h1>{0}</h1>", EscapeHTML(title, false)); if (!string.IsNullOrEmpty(GMConfig.Instance.FrontPageImageFilename)) { Rectangle newArea = new Rectangle(0, 0, 0, 0); string pictureFile = CopyMultimedia(GMConfig.Instance.FrontPageImageFilename, "", 0, 0, ref newArea, null); if (!string.IsNullOrEmpty(pictureFile)) { f.WriteLine("<p><img src=\"{0}\" alt=\"Front page image\" /></p>", pictureFile); } } if (!string.IsNullOrEmpty(GMConfig.Instance.CommentaryText)) { if (GMConfig.Instance.CommentaryIsHtml) { f.WriteLine("<p>{0}</p>", GMConfig.Instance.CommentaryText); } else { f.WriteLine("<p>{0}</p>", EscapeHTML(GMConfig.Instance.CommentaryText, false)); } } if (GMConfig.Instance.ShowFrontPageStats) { string individuals = fStats.Individuals == 0 ? "no" : fStats.Individuals.ToString(); individuals += " individual"; if (fStats.Individuals != 1) { individuals += "s"; } string sources = fStats.Sources == 0 ? "" : string.Concat(", cross-referenced to ", fStats.Sources.ToString(), " source"); if (fStats.Sources > 1) { sources += "s"; } string fileType = fStats.NonPicturesIncluded ? "multimedia file" : "image"; string multimedia = fStats.MultimediaFiles == 0 ? "" : string.Concat(". There are links to ", fStats.MultimediaFiles.ToString(), " ", fileType); if (fStats.MultimediaFiles > 1) { multimedia += "s"; } f.WriteLine(string.Concat(" <p>This website contains records on ", individuals, sources, multimedia, ".</p>")); } f.WriteLine(" <div id=\"links\"> <!-- links -->"); f.WriteLine(string.Concat(" <p><a href=\"individuals1.", GMConfig.Instance.HtmlExtension, "\">", GMConfig.Instance.IndexTitle, "</a></p>")); f.WriteLine(" </div> <!-- links -->"); if (GMConfig.Instance.KeyIndividuals != null && GMConfig.Instance.KeyIndividuals.Count > 0) { // Although in theory you might want a restricted individual as a key individual, (they still form part of the tree), in practice this isn't allowed: var censoredKeyIndividuals = new List <string>(GMConfig.Instance.KeyIndividuals.Count); foreach (string keyXref in GMConfig.Instance.KeyIndividuals) { GDMIndividualRecord air = fTree.XRefIndex_Find(keyXref) as GDMIndividualRecord; if (air != null) { censoredKeyIndividuals.Add(MakeLink(air)); } } if (censoredKeyIndividuals.Count > 0) { string plural = ""; if (censoredKeyIndividuals.Count > 1) { plural = "s"; } f.WriteLine("<div id=\"keyindividuals\">"); f.WriteLine("<p>Key Individual{0}:</p>", plural); f.WriteLine("<ul>"); foreach (string air_link in censoredKeyIndividuals) { f.WriteLine("<li>{0}</li>", air_link); } f.WriteLine("</ul>"); f.WriteLine("</div> <!-- keyindividuals -->"); } } string byEmail = ""; // Email contact address if (!string.IsNullOrEmpty(GMConfig.Instance.UserEmailAddress)) { byEmail = string.Concat(" by <a href=\"mailto:", GMConfig.Instance.UserEmailAddress, "\">", EscapeHTML(GMConfig.Instance.UserEmailAddress, false), "</a>"); } // Add brand and contact label f.WriteLine("<p>Website created{0} using GEDmill.</p>", byEmail); // Add last update string if (GMConfig.Instance.AddHomePageCreateTime) { f.WriteLine("<p>Created on {0}.</p>", GMHelper.GetNowDateStr()); } // Add link to users main website if (!string.IsNullOrEmpty(GMConfig.Instance.MainWebsiteLink)) { f.WriteLine("<p><a href=\"{0}\">Return to main site</a></p>", GMConfig.Instance.MainWebsiteLink); } f.WriteLine(" </div> <!-- cover -->"); f.WriteLine(" </div> <!-- page -->"); } catch (IOException e) { fLogger.WriteError("Caught IO Exception(7) : ", e); } catch (ArgumentException e) { fLogger.WriteError("Caught Argument Exception(7) : ", e); } finally { if (f != null) { // Add standard footer to the file f.Close(); } } }
public void SetPerson() { fTempInd = fBase.Context.SelectPerson(null, TargetMode.tmNone, GDMSex.svUnknown); fView.Corresponder.Text = ((fTempInd == null) ? "" : GKUtils.GetNameString(fTempInd, true, false)); }
private void DuplicateFoundFunc(GDMIndividualRecord indivA, GDMIndividualRecord indivB) { fView.CompareOutput.AppendText(" * [" + GKUtils.GetNameString(indivA, true, false) + "]\r\n"); fView.CompareOutput.AppendText(" [" + GKUtils.GetNameString(indivB, true, false) + "]\r\n\r\n"); }
protected CircleSegment(int generation) { Gen = generation; IRec = null; Path = AppHost.GfxProvider.CreatePath(); }
public PedigreeEvent(GDMIndividualRecord iRec, GDMCustomEvent evt) { IRec = iRec; Event = evt; Date = (evt == null) ? UDN.CreateEmpty() : evt.Date.GetUDN(); }
public void BuildAncTree() { fSegments.Clear(); const float startRad = CircleChartModel.CENTER_RAD - 50; float inRad = startRad; AncPersonSegment segment = new AncPersonSegment(0); DefineSegment(segment, 0, 0, inRad, 0 - 90.0f, 360.0f); fSegments.Add(segment); int maxSteps = 1; for (int gen = 1; gen <= fVisibleGenerations; gen++) { inRad = startRad + ((gen - 1) * fGenWidth); float extRad = inRad + fGenWidth; maxSteps *= 2; float wedgeAngle = (360.0f / maxSteps); for (int step = 0; step < maxSteps; step++) { float startAngle = (step * wedgeAngle) - 90.0f; segment = new AncPersonSegment(gen); DefineSegment(segment, 0, inRad, extRad, startAngle, wedgeAngle); fSegments.Add(segment); } } // traverse tree fGroupCount = -1; fIndividualsCount = 0; if (fRootPerson == null) { return; } fIndividualsCount++; AncPersonSegment rootSegment = SetSegmentParams(0, fRootPerson, 0, -1); if (rootSegment == null) { return; } rootSegment.WedgeAngle = 360.0f; GDMIndividualRecord father = null, mother = null; GDMFamilyRecord fam = fRootPerson.GetParentsFamily(); if (fam != null && fBase.Context.IsRecordAccess(fam.Restriction)) { father = fam.Husband.Individual; mother = fam.Wife.Individual; } if (mother != null) { rootSegment.MotherSegment = TraverseAncestors(mother, 90f, 1, CircleChartModel.CENTER_RAD, 90.0f, 1, -1); } if (father != null) { rootSegment.FatherSegment = TraverseAncestors(father, 270.0f, 1, CircleChartModel.CENTER_RAD, 90.0f, 1, -1); } }
public void Test_GetDescGenerations() { GDMIndividualRecord iRec = fContext.Tree.XRefIndex_Find("I1") as GDMIndividualRecord; Assert.AreEqual(2, GKUtils.GetDescGenerations(iRec)); }
private void CircleChartWin_RootChanged(object sender, GDMIndividualRecord person) { GenChart(); }
public void Test_GetMarriagesCount() { GDMIndividualRecord iRec = fContext.Tree.XRefIndex_Find("I1") as GDMIndividualRecord; Assert.AreEqual(1, GKUtils.GetMarriagesCount(iRec)); }
public void Test_SourceInput_RS() { SelectTab("PageControl1", fDialog, 1); ClickRadioButton("rbSK_Rev", fDialog); // RS var dataGridView1 = new DataGridViewTester("dataGridView1", fDialog); dataGridView1.Properties.Rows.Add(5); dataGridView1.EnterCell(0, 0, fLangMan.LS(FLS.LSID_PLPerson)); dataGridView1.EnterCell(0, 1, "Иван"); dataGridView1.EnterCell(0, 2, "Иванович"); dataGridView1.EnterCell(0, 3, "Иванов"); dataGridView1.EnterCell(0, 4, "20"); dataGridView1.EnterCell(0, 5, "test comment"); dataGridView1.EnterCell(1, 0, fLangMan.LS(FLS.LSID_Spouse)); dataGridView1.EnterCell(1, 1, "Анна"); dataGridView1.EnterCell(1, 2, "Васильевна"); dataGridView1.EnterCell(1, 3, "Иванова"); dataGridView1.EnterCell(1, 4, "19"); dataGridView1.EnterCell(1, 5, "test comment2"); dataGridView1.EnterCell(2, 0, fLangMan.LS(FLS.LSID_Father)); dataGridView1.EnterCell(2, 1, "Иван"); dataGridView1.EnterCell(2, 2, "Петрович"); dataGridView1.EnterCell(2, 3, "Иванов"); dataGridView1.EnterCell(2, 4, "40"); dataGridView1.EnterCell(2, 5, ""); dataGridView1.EnterCell(3, 0, fLangMan.LS(FLS.LSID_Child)); dataGridView1.EnterCell(3, 1, "Василий"); dataGridView1.EnterCell(3, 2, "Иванович"); dataGridView1.EnterCell(3, 3, "Иванов"); dataGridView1.EnterCell(3, 4, "1"); dataGridView1.EnterCell(3, 5, ""); dataGridView1.EnterCell(4, 0, fLangMan.LS(FLS.LSID_PLGodparent)); dataGridView1.EnterCell(4, 1, "Иван"); dataGridView1.EnterCell(4, 2, "Григорьевич"); dataGridView1.EnterCell(4, 3, "Иванов"); dataGridView1.EnterCell(4, 4, "60"); dataGridView1.EnterCell(4, 5, ""); EnterCombo("cbSource", fDialog, "test source"); EnterText("edSourceYear", fDialog, "1890"); EnterText("edPage", fDialog, "12"); EnterText("edPlace", fDialog, "Сосновка"); ModalFormHandler = SexCheckDlgTests.SexCheckDlgTests_AcceptM_Handler; // NamesTable not available ClickButton("btnParse", fDialog); Assert.AreEqual(10, fBase.Context.Tree.RecordsCount); GDMIndividualRecord iRec1 = fBase.Context.Tree.XRefIndex_Find("I1") as GDMIndividualRecord; Assert.IsNotNull(iRec1); Assert.AreEqual("Иван Иванович Иванов", iRec1.GetPrimaryFullName()); GDMIndividualRecord iRec2 = fBase.Context.Tree.XRefIndex_Find("I2") as GDMIndividualRecord; Assert.IsNotNull(iRec2); Assert.AreEqual("Анна Васильевна Иванова", iRec2.GetPrimaryFullName()); GDMIndividualRecord iRec3 = fBase.Context.Tree.XRefIndex_Find("I3") as GDMIndividualRecord; Assert.IsNotNull(iRec3); Assert.AreEqual("Иван Петрович Иванов", iRec3.GetPrimaryFullName()); GDMIndividualRecord iRec4 = fBase.Context.Tree.XRefIndex_Find("I4") as GDMIndividualRecord; Assert.IsNotNull(iRec4); Assert.AreEqual("Василий Иванович Иванов", iRec4.GetPrimaryFullName()); }
public void Test_ShowXInfo() { StringList summary = new StringList(); summary.Clear(); GKUtils.ShowFamilyInfo(fContext, null, null); GDMFamilyRecord famRec = fContext.Tree.XRefIndex_Find("F1") as GDMFamilyRecord; GKUtils.ShowFamilyInfo(fContext, famRec, summary); summary.Clear(); GKUtils.ShowGroupInfo(null, null); GDMGroupRecord grpRec = fContext.Tree.XRefIndex_Find("G1") as GDMGroupRecord; GKUtils.ShowGroupInfo(grpRec, summary); summary.Clear(); GKUtils.ShowMultimediaInfo(null, null); GDMMultimediaRecord mmRec = fContext.Tree.XRefIndex_Find("O1") as GDMMultimediaRecord; GKUtils.ShowMultimediaInfo(mmRec, summary); summary.Clear(); GKUtils.ShowNoteInfo(null, null); GDMNoteRecord noteRec = fContext.Tree.XRefIndex_Find("N1") as GDMNoteRecord; GKUtils.ShowNoteInfo(noteRec, summary); summary.Clear(); GKUtils.ShowPersonInfo(fContext, null, null); GDMIndividualRecord indRec = fContext.Tree.XRefIndex_Find("I1") as GDMIndividualRecord; GKUtils.ShowPersonInfo(fContext, indRec, summary); summary.Clear(); GKUtils.ShowSourceInfo(null, null); GDMSourceRecord srcRec = fContext.Tree.XRefIndex_Find("S1") as GDMSourceRecord; GKUtils.ShowSourceInfo(srcRec, summary); summary.Clear(); GKUtils.ShowRepositoryInfo(null, null); GDMRepositoryRecord repRec = fContext.Tree.XRefIndex_Find("R1") as GDMRepositoryRecord; GKUtils.ShowRepositoryInfo(repRec, summary); summary.Clear(); GKUtils.ShowResearchInfo(null, null); GDMResearchRecord resRec = fContext.Tree.XRefIndex_Find("RS1") as GDMResearchRecord; GKUtils.ShowResearchInfo(resRec, summary); summary.Clear(); GKUtils.ShowTaskInfo(null, null); GDMTaskRecord taskRec = fContext.Tree.XRefIndex_Find("TK1") as GDMTaskRecord; GKUtils.ShowTaskInfo(taskRec, summary); summary.Clear(); GKUtils.ShowCommunicationInfo(null, null); GDMCommunicationRecord commRec = fContext.Tree.XRefIndex_Find("CM1") as GDMCommunicationRecord; GKUtils.ShowCommunicationInfo(commRec, summary); summary.Clear(); GKUtils.ShowLocationInfo(null, null); GDMLocationRecord locRec = fContext.Tree.XRefIndex_Find("L1") as GDMLocationRecord; GKUtils.ShowLocationInfo(locRec, summary); }
private bool IsProcessed(GDMIndividualRecord indiRec) { return(fProcessedRecords.Contains(indiRec)); }
/// <summary> /// Attention: returns only the first marriage! /// </summary> /// <returns></returns> public static GDMFamilyRecord GetMarriageFamily(this GDMTree tree, GDMIndividualRecord indiRec) { GDMFamilyRecord result = (indiRec.SpouseToFamilyLinks.Count < 1) ? null : tree.GetPtrValue(indiRec.SpouseToFamilyLinks[0]); return(result); }
public static void MarkConnected(GDMTree tree, GDMIndividualRecord iRec, List <GDMRecord> marks) { TreeTools.WalkTree(tree, iRec, TreeTools.TreeWalkMode.twmAll, MarkProc, marks); }
/// <summary> /// Attention: returns only the first parents family! /// </summary> /// <returns></returns> public static GDMFamilyRecord GetParentsFamily(this GDMTree tree, GDMIndividualRecord indiRec) { GDMFamilyRecord result = (indiRec.ChildToFamilyLinks.Count < 1) ? null : tree.GetPtrValue(indiRec.ChildToFamilyLinks[0]); return(result); }
// Calculate size required for tree by iterating through individuals and building a data structure. protected MiniTreeGroup CreateDataStructure(GDMIndividualRecord irSubject) { // Add subject's frParents GDMFamilyRecord frParents = fTree.GetParentsFamily(irSubject); MiniTreeGroup mtgParents = new MiniTreeGroup(); MiniTreeIndividual mtiFather = null; if (frParents != null) { mtiFather = AddToGroup(fTree.GetPtrValue(frParents.Husband), mtgParents); } // Create a group for the subejct and their siblings. MiniTreeGroup mtgSiblings = new MiniTreeGroup(); // Keeps count of subject's siblings (including subject) int nSiblings = 0; // Keeps track of last added sibling, to hook up to next added sibling. MiniTreeIndividual mtiRightmostSibling = null; // Keeps track of last added child, to hook up to next added child. MiniTreeIndividual mtiRightmostChild = null; // For each sibling (including the subject) while (true) { GDMIndividualRecord irSibling = GetChild(frParents, nSiblings, irSubject); if (irSibling == null) { break; } if (irSibling == irSubject) { // Add spouses and children of subject, (and subject too, if we need to put wife after them.) MiniTreeGroup mtgOffspring = null; bool bAddedSubject = false; int nSpouses = 0; MiniTreeGroup.ECrossbar ecbCrossbar = MiniTreeGroup.ECrossbar.Solid; var indiFamilies = GMHelper.GetFamilyList(fTree, irSubject); foreach (GDMFamilyRecord famRec in indiFamilies) { GDMIndividualRecord irSpouse = fTree.GetSpouseBy(famRec, irSubject); if (famRec.Husband.XRef != irSubject.XRef) { mtiRightmostSibling = AddToGroup(irSpouse, mtgSiblings); // Subject is female so all but last husband have dotted bars ecbCrossbar = MiniTreeGroup.ECrossbar.DottedLeft; } else if (Exists(irSubject) && !bAddedSubject) { // Subject is male, so need to put them in now, before their children. // (Otherwise they get added as a regular sibling later) CBoxText boxtext = new CBoxText(irSubject); mtiRightmostSibling = mtgSiblings.AddIndividual(irSubject, boxtext.FirstName, boxtext.Surname, boxtext.Date, false, frParents != null, true, boxtext.Concealed, false); // To stop subject being added as regular sibling. bAddedSubject = true; } int nGrandchildren = 0; GDMIndividualRecord irGrandchild = null; // If we have already added an offspring box (from previous marriage) need connect this box to it as its right box. if (mtgOffspring != null) { mtgOffspring.RightBox = mtiRightmostSibling; } // Create a box for the offspring of this marriage mtgOffspring = new MiniTreeGroup(); // Set crossbar that joins subject to spouse according to whether this is subject's first spouse. mtgOffspring.fCrossbar = ecbCrossbar; // Add children by this spouse MiniTreeIndividual mtiChild = null; while ((irGrandchild = GetChild(famRec, nGrandchildren, null)) != null) { if (Exists(irGrandchild)) { CBoxText boxtext = new CBoxText(irGrandchild); mtiChild = mtgOffspring.AddIndividual(irGrandchild, boxtext.FirstName, boxtext.Surname, boxtext.Date, true, true, false, boxtext.Concealed, false); // Hook this up to any children by previous spouses. if (nGrandchildren == 0 && mtiRightmostChild != null) { mtiRightmostChild.RightObjectAlien = mtiChild; mtiChild.LeftObjectAlien = mtiRightmostChild; } } nGrandchildren++; } // If we added anything, record it as the right-most child ready to hook to children by next spouse. if (mtiChild != null) { mtiRightmostChild = mtiChild; } // Add the subjects children to the siblings group mtgSiblings.AddGroup(mtgOffspring); // Hook the offspring group to the previous sibling if (mtgOffspring != null) { mtgOffspring.LeftBox = mtiRightmostSibling; } // If subject is husband then we need to add their wife now. if (famRec.Husband.XRef == irSubject.XRef) { ecbCrossbar = MiniTreeGroup.ECrossbar.DottedRight; // Hook up to previous rightmost sibling and set this as new rightmost sibling. mtiRightmostSibling = AddToGroup(irSpouse, mtgSiblings); // Hook the wife up as box on right of offspring box. if (mtgOffspring != null) { mtgOffspring.RightBox = mtiRightmostSibling; } } nSpouses++; } if (!bAddedSubject) { CBoxText boxtext = new CBoxText(irSubject); MiniTreeIndividual mtiWife = mtgSiblings.AddIndividual(irSubject, boxtext.FirstName, boxtext.Surname, boxtext.Date, false, frParents != null, true, boxtext.Concealed, false); if (mtgOffspring != null) { mtgOffspring.fCrossbar = MiniTreeGroup.ECrossbar.Solid; mtgOffspring.RightBox = mtiWife; } } } else if (Exists(irSibling)) { // A sibling (not the subject). CBoxText boxtext = new CBoxText(irSibling); mtgSiblings.AddIndividual(irSibling, boxtext.FirstName, boxtext.Surname, boxtext.Date, true, frParents != null, true, boxtext.Concealed, false); } nSiblings++; } // Add siblings group after subject's father mtgParents.AddGroup(mtgSiblings); // Hook up to subject's father mtgSiblings.LeftBox = mtiFather; // Add subject's mother if (frParents != null) { MiniTreeIndividual mtiMother = AddToGroup(fTree.GetPtrValue(frParents.Wife), mtgParents); mtgSiblings.RightBox = mtiMother; } // Return the parents group (which contains the other family groups). return(mtgParents); }
/// <summary> /// Renders a specified <paramref name="segment"/>'s person name within /// the segment. /// </summary> /// <param name="gfx">GDI+ context to render on. This member may change /// this context's transformation. If it does, it also reverts the /// transformation back. Thus, from the point of view of the client code /// this member doesn't change the context's transformation.</param> /// <param name="segment">Source segment to be drawn on `gfx`.</param> private void DrawPersonName(CircleSegment segment) { int gen = segment.Gen; GDMIndividualRecord iRec = segment.IRec; string surn, givn; if (iRec == null) { if (gen == 0) { givn = "Choose"; surn = "subject"; } else { return; } } else { var parts = GKUtils.GetNameParts(iRec); surn = parts.Surname; givn = parts.Name; } var brush = fCircleBrushes[8]; ExtSizeF size; float rad = segment.Rad - 20; float angle = segment.StartAngle + 90.0f + segment.WedgeAngle / 2; float wedgeAngle = segment.WedgeAngle; bool isNarrow = IsNarrowSegment(givn, rad, wedgeAngle, Font); fRenderer.SaveTransform(); if (gen == 0) { // central circle size = fRenderer.GetTextSize(surn, Font); fRenderer.DrawString(surn, Font, brush, -size.Width / 2f, -size.Height / 2f - size.Height / 2f); size = fRenderer.GetTextSize(givn, Font); fRenderer.DrawString(givn, Font, brush, -size.Width / 2f, 0f); } else { if (isNarrow) { //var debugBrush = fRenderer.CreateSolidBrush(ChartRenderer.Red); // narrow segments of 6-8 generations, radial text float dx = (float)Math.Sin(Math.PI * angle / 180.0f) * rad; float dy = (float)Math.Cos(Math.PI * angle / 180.0f) * rad; fRenderer.TranslateTransform(dx, -dy); if (fOptions.LTRCorrection && (angle >= 180 && angle < 360)) { angle -= 180.0f; } fRenderer.RotateTransform(angle - 90.0f); size = fRenderer.GetTextSize(givn, Font); fRenderer.DrawString(givn, Font, brush, -size.Width / 2f, -size.Height / 2f); } else { if (wedgeAngle < 20) { float dx = (float)Math.Sin(Math.PI * angle / 180.0f) * rad; float dy = (float)Math.Cos(Math.PI * angle / 180.0f) * rad; fRenderer.TranslateTransform(dx, -dy); fRenderer.RotateTransform(angle); size = fRenderer.GetTextSize(givn, Font); fRenderer.DrawString(givn, Font, brush, -size.Width / 2f, -size.Height / 2f); } else if (wedgeAngle < 180) { if (fOptions.ArcText) { if (gen == 2) { size = fRenderer.GetTextSize(surn, Font); fRenderer.DrawArcText(surn, 0.0f, 0.0f, rad + size.Height / 2f, segment.StartAngle, segment.WedgeAngle, true, true, Font, brush); size = fRenderer.GetTextSize(givn, Font); fRenderer.DrawArcText(givn, 0.0f, 0.0f, rad - size.Height / 2f, segment.StartAngle, segment.WedgeAngle, true, true, Font, brush); } else { fRenderer.DrawArcText(givn, 0.0f, 0.0f, rad, segment.StartAngle, segment.WedgeAngle, true, true, Font, brush); } } else { float dx = (float)Math.Sin(Math.PI * angle / 180.0f) * rad; float dy = (float)Math.Cos(Math.PI * angle / 180.0f) * rad; fRenderer.TranslateTransform(dx, -dy); fRenderer.RotateTransform(angle); size = fRenderer.GetTextSize(surn, Font); fRenderer.DrawString(surn, Font, brush, -size.Width / 2f, -size.Height / 2f); size = fRenderer.GetTextSize(givn, Font); dx = (float)Math.Sin(Math.PI * angle / 180.0f) * (rad - size.Height); dy = (float)Math.Cos(Math.PI * angle / 180.0f) * (rad - size.Height); fRenderer.RestoreTransform(); fRenderer.SaveTransform(); fRenderer.TranslateTransform(dx, -dy); fRenderer.RotateTransform(angle); fRenderer.DrawString(givn, Font, brush, -size.Width / 2f, -size.Height / 2f); } } else if (wedgeAngle < 361) { if (fOptions.ArcText) { size = fRenderer.GetTextSize(surn, Font); fRenderer.DrawArcText(surn, 0.0f, 0.0f, rad + size.Height / 2f, segment.StartAngle, segment.WedgeAngle, true, true, Font, brush); size = fRenderer.GetTextSize(givn, Font); fRenderer.DrawArcText(givn, 0.0f, 0.0f, rad - size.Height / 2f, segment.StartAngle, segment.WedgeAngle, true, true, Font, brush); } else { float dx = (float)Math.Sin(Math.PI * angle / 180.0f) * rad; float dy = (float)Math.Cos(Math.PI * angle / 180.0f) * rad; fRenderer.TranslateTransform(dx, -dy); fRenderer.RotateTransform(angle); size = fRenderer.GetTextSize(surn, Font); fRenderer.DrawString(surn, Font, brush, -size.Width / 2f, -size.Height / 2f); size = fRenderer.GetTextSize(givn, Font); fRenderer.DrawString(givn, Font, brush, -size.Width / 2f, -size.Height / 2f + size.Height); } } } } fRenderer.RestoreTransform(); }
public static void PruneAncestors(this GDMTree tree, GDMIndividualRecord iRec, bool visible) { TreeTools.WalkTree(iRec, TreeTools.TreeWalkMode.twmAncestors, PruneProc, ((object)visible)); }
public string GetRelationship(GDMIndividualRecord targetRec, bool fullFormat = false) { if (targetRec == null) { return("???"); } Vertex target = fGraph.FindVertex(targetRec.XRef); if (target == null) { return("???"); } try { IEnumerable <Edge> edgesPath = fGraph.GetPath(target); string tmp = ""; RelationKind prevRel = RelationKind.rkNone; RelationKind finRel = RelationKind.rkNone; int great = 0; GDMIndividualRecord src = null, tgt = null, prev_tgt = null; string part, fullRel = ""; foreach (Edge edge in edgesPath) { GDMIndividualRecord xFrom = (GDMIndividualRecord)edge.Source.Value; GDMIndividualRecord xTo = (GDMIndividualRecord)edge.Target.Value; RelationKind curRel = FixLink(xFrom, xTo, (RelationKind)((int)edge.Value)); if (src == null) { src = xFrom; } prev_tgt = tgt; tgt = xTo; if (tmp != "") { tmp += ", "; } tmp += xFrom.XRef + ">" + GKData.RelationSigns[(int)curRel] + ">" + xTo.XRef; if (prevRel != RelationKind.rkUndefined) { int g, lev; finRel = KinshipsMan.FindKinship(prevRel, curRel, out g, out lev); great += g; // it's gap if (finRel == RelationKind.rkUndefined && fullFormat) { part = GetRelationPart(src, prev_tgt, prevRel, great); src = prev_tgt; great = 0; prevRel = RelationKind.rkNone; if (fullRel.Length > 0) { fullRel += ", "; } fullRel += part; finRel = KinshipsMan.FindKinship(prevRel, curRel, out g, out lev); great += g; } prevRel = finRel; } } IndividualsPath = targetRec.XRef + " [" + tmp + "]"; if (!fullFormat) { string relRes = FixRelation(targetRec, finRel, great); return(relRes); } else { part = GetRelationPart(src, tgt, finRel, great); if (fullRel.Length > 0) { fullRel += ", "; } fullRel += part; return(fullRel); } } catch (Exception ex) { Logger.WriteError("KinshipsGraph.GetRelationship()", ex); return(""); } }