From 9657f1cd40002fe034730cfc278256da8df088a6 Mon Sep 17 00:00:00 2001 From: "Sergey V. Zhdanovskih" Date: Tue, 3 Dec 2024 22:55:30 +0300 Subject: [PATCH] Minor improvements (#603) --- projects/GKCore/GDModel/GDMList.cs | 17 +- projects/GKCore/GDModel/GDMTree.cs | 20 +-- .../Providers/FamilyShow/FamilyXProvider.cs | 9 +- projects/GKCore/GKCore/BaseContext.cs | 64 ++------ .../GKCore/Controllers/SlideshowController.cs | 9 +- .../GKCore/Export/FamilyBookExporter.cs | 8 +- projects/GKCore/GKCore/GKUtils.cs | 153 +++++++++--------- .../GKCore/Lists/IndividualListModel.cs | 2 +- projects/GKTests/GKCore/GKUtilsTests.cs | 22 ++- projects/GKTests/TestUtils.cs | 7 + .../GKStdReports/ContemporariesReport.cs | 9 +- 11 files changed, 149 insertions(+), 171 deletions(-) diff --git a/projects/GKCore/GDModel/GDMList.cs b/projects/GKCore/GDModel/GDMList.cs index 4fea4c65a..474ef3f93 100644 --- a/projects/GKCore/GDModel/GDMList.cs +++ b/projects/GKCore/GDModel/GDMList.cs @@ -32,18 +32,15 @@ public sealed class GDMList : IGDMList private struct GEDCOMListEnumerator : IGDMListEnumerator { - private readonly GDMList fOwnList; + private readonly IList fDataList; private int fIndex; private int fSize; public GEDCOMListEnumerator(GDMList list) { - fOwnList = list; - + fDataList = list.fDataList; fIndex = -1; - - List dataList = list.fDataList; - fSize = ((dataList == null) ? 0 : dataList.Count); + fSize = (fDataList == null) ? 0 : fDataList.Count; } void IDisposable.Dispose() @@ -54,9 +51,7 @@ void IDisposable.Dispose() void IEnumerator.Reset() { fIndex = -1; - - List dataList = fOwnList.fDataList; - fSize = ((dataList == null) ? 0 : dataList.Count); + fSize = (fDataList == null) ? 0 : fDataList.Count; } bool IEnumerator.MoveNext() @@ -67,12 +62,12 @@ bool IEnumerator.MoveNext() object IEnumerator.Current { - get { return fOwnList.fDataList[fIndex]; } + get { return fDataList[fIndex]; } } T IEnumerator.Current { - get { return fOwnList.fDataList[fIndex]; } + get { return fDataList[fIndex]; } } } diff --git a/projects/GKCore/GDModel/GDMTree.cs b/projects/GKCore/GDModel/GDMTree.cs index c58b82c7d..cae3c3f71 100644 --- a/projects/GKCore/GDModel/GDMTree.cs +++ b/projects/GKCore/GDModel/GDMTree.cs @@ -43,16 +43,16 @@ public sealed class GDMTree : GDMObject private struct TreeEnumerator : IGDMTreeEnumerator { - private readonly GDMTree fTree; + private readonly IList fTreeRecords; private readonly GDMRecordType fRecType; private readonly int fEndIndex; private int fIndex; public TreeEnumerator(GDMTree tree, GDMRecordType recType) { - fTree = tree; + fTreeRecords = tree.fRecords.GetList(); fIndex = -1; - fEndIndex = tree.RecordsCount - 1; + fEndIndex = ((fTreeRecords == null) ? 0 : fTreeRecords.Count) - 1; fRecType = recType; } @@ -61,13 +61,13 @@ public bool MoveNext(out GDMRecord current) if (fRecType == GDMRecordType.rtNone) { if (fIndex < fEndIndex) { fIndex++; - current = fTree[fIndex]; + current = fTreeRecords[fIndex]; return true; } } else { while (fIndex < fEndIndex) { fIndex++; - GDMRecord rec = fTree[fIndex]; + GDMRecord rec = fTreeRecords[fIndex]; if (rec.RecordType == fRecType) { current = rec; return true; @@ -88,22 +88,22 @@ public void Reset() private struct TreeEnumerator : IGDMTreeEnumerator where T : GDMRecord { - private readonly GDMTree fTree; + private readonly IList fTreeRecords; private readonly int fEndIndex; private int fIndex; public TreeEnumerator(GDMTree tree) { - fTree = tree; + fTreeRecords = tree.fRecords.GetList(); fIndex = -1; - fEndIndex = tree.RecordsCount - 1; + fEndIndex = ((fTreeRecords == null) ? 0 : fTreeRecords.Count) - 1; } public bool MoveNext(out T current) { while (fIndex < fEndIndex) { fIndex++; - T rec = fTree[fIndex] as T; + T rec = fTreeRecords[fIndex] as T; if (rec != null) { current = rec; return true; @@ -119,7 +119,7 @@ public bool MoveNext(out GDMRecord current) { while (fIndex < fEndIndex) { fIndex++; - var rec = fTree[fIndex]; + var rec = fTreeRecords[fIndex]; if (rec != null) { current = rec; return true; diff --git a/projects/GKCore/GDModel/Providers/FamilyShow/FamilyXProvider.cs b/projects/GKCore/GDModel/Providers/FamilyShow/FamilyXProvider.cs index d81311d4a..c8f4f89d0 100644 --- a/projects/GKCore/GDModel/Providers/FamilyShow/FamilyXProvider.cs +++ b/projects/GKCore/GDModel/Providers/FamilyShow/FamilyXProvider.cs @@ -1,6 +1,6 @@ /* * "GEDKeeper", the personal genealogical database editor. - * Copyright (C) 2009-2023 by Sergey V. Zhdanovskih. + * Copyright (C) 2009-2024 by Sergey V. Zhdanovskih. * * This file is part of "GEDKeeper". * @@ -303,10 +303,9 @@ private GDMFamilyRecord GetParentsFamily(GDMIndividualRecord father, GDMIndividu string fatherXRef = (father == null) ? string.Empty : father.XRef; string motherXRef = (mother == null) ? string.Empty : mother.XRef; - var famEnum = fTree.GetEnumerator(GDMRecordType.rtFamily); - GDMRecord record; - while (famEnum.MoveNext(out record)) { - var famRec = record as GDMFamilyRecord; + var famEnum = fTree.GetEnumerator(); + GDMFamilyRecord famRec; + while (famEnum.MoveNext(out famRec)) { if (famRec.Husband.XRef == fatherXRef && famRec.Wife.XRef == motherXRef) { result = famRec; break; diff --git a/projects/GKCore/GKCore/BaseContext.cs b/projects/GKCore/GKCore/BaseContext.cs index 2e7110f31..18950e7fb 100644 --- a/projects/GKCore/GKCore/BaseContext.cs +++ b/projects/GKCore/GKCore/BaseContext.cs @@ -592,61 +592,21 @@ public void CollectTips(StringList tipsList) try { bool firstTip = true; - int num = fTree.RecordsCount; - for (int i = 0; i < num; i++) { - GDMRecord rec = fTree[i]; - if (rec.RecordType != GDMRecordType.rtIndividual) continue; - - GDMIndividualRecord iRec = (GDMIndividualRecord)rec; - - int days = GKUtils.GetDaysForBirth(iRec); - if (days >= 0 && days < 3) { - if (firstTip) { - tipsList.Add("#" + LangMan.LS(LSID.BirthDays)); - firstTip = false; - } - - string nm = Culture.GetPossessiveName(iRec); - - string tip; - switch (days) { - case 0: - tip = string.Format(LangMan.LS(LSID.BirthdayToday), nm); - break; - case 1: - tip = string.Format(LangMan.LS(LSID.BirthdayTomorrow), nm); - break; - default: - tip = string.Format(LangMan.LS(LSID.DaysRemained), nm, days); - break; - } - tipsList.Add(tip); - } - + var indiEnum = fTree.GetEnumerator(); + GDMIndividualRecord iRec; + while (indiEnum.MoveNext(out iRec)) { int years; - days = GKUtils.GetDaysForBirthAnniversary(iRec, out years); - if (days >= 0 && days < 3) { - if (firstTip) { - tipsList.Add("#" + LangMan.LS(LSID.BirthDays)); - firstTip = false; - } + bool anniversary; + int days = GKUtils.GetDaysForBirth(iRec, true, out years, out anniversary); + if (days < 0 || days >= 3) continue; - string nm = Culture.GetPossessiveName(iRec); - - string tip; - switch (days) { - case 0: - tip = string.Format(LangMan.LS(LSID.AnniversaryToday), nm); - break; - case 1: - tip = string.Format(LangMan.LS(LSID.AnniversaryTomorrow), nm); - break; - default: - tip = string.Format(LangMan.LS(LSID.AnniversaryDaysRemained), nm, days); - break; - } - tipsList.Add(tip); + if (firstTip) { + tipsList.Add("#" + LangMan.LS(LSID.BirthDays)); + firstTip = false; } + + string tip = GKUtils.GetBirthTipMessage(Culture, iRec, days, years, anniversary); + tipsList.Add(tip); } } catch (Exception ex) { Logger.WriteError("BaseContext.CollectTips()", ex); diff --git a/projects/GKCore/GKCore/Controllers/SlideshowController.cs b/projects/GKCore/GKCore/Controllers/SlideshowController.cs index 272079b33..c374761b7 100644 --- a/projects/GKCore/GKCore/Controllers/SlideshowController.cs +++ b/projects/GKCore/GKCore/Controllers/SlideshowController.cs @@ -1,6 +1,6 @@ /* * "GEDKeeper", the personal genealogical database editor. - * Copyright (C) 2009-2023 by Sergey V. Zhdanovskih. + * Copyright (C) 2009-2024 by Sergey V. Zhdanovskih. * * This file is part of "GEDKeeper". * @@ -87,10 +87,9 @@ private void Timer1Tick(object sender, EventArgs e) public void LoadList() { - GDMRecord record; - var enumerator = fBase.Context.Tree.GetEnumerator(GDMRecordType.rtMultimedia); - while (enumerator.MoveNext(out record)) { - GDMMultimediaRecord mediaRec = (GDMMultimediaRecord)record; + GDMMultimediaRecord mediaRec; + var enumerator = fBase.Context.Tree.GetEnumerator(); + while (enumerator.MoveNext(out mediaRec)) { GDMFileReferenceWithTitle fileRef = mediaRec.FileReferences[0]; MultimediaKind mmKind = GKUtils.GetMultimediaKind(fileRef.GetMultimediaFormat()); diff --git a/projects/GKCore/GKCore/Export/FamilyBookExporter.cs b/projects/GKCore/GKCore/Export/FamilyBookExporter.cs index 646c09b8a..6f1deea22 100644 --- a/projects/GKCore/GKCore/Export/FamilyBookExporter.cs +++ b/projects/GKCore/GKCore/Export/FamilyBookExporter.cs @@ -238,11 +238,9 @@ private void PrepareData() reliIndex = new StringList(); sourcesIndex = new StringList(); - GDMRecord rec; - - var iEnum = fTree.GetEnumerator(GDMRecordType.rtIndividual); - while (iEnum.MoveNext(out rec)) { - GDMIndividualRecord iRec = (GDMIndividualRecord)rec; + var iEnum = fTree.GetEnumerator(); + GDMIndividualRecord iRec; + while (iEnum.MoveNext(out iRec)) { string text = GKUtils.GetNameString(iRec, true, false); string st; diff --git a/projects/GKCore/GKCore/GKUtils.cs b/projects/GKCore/GKCore/GKUtils.cs index 8f63532c4..385777b98 100644 --- a/projects/GKCore/GKCore/GKUtils.cs +++ b/projects/GKCore/GKCore/GKUtils.cs @@ -1294,6 +1294,7 @@ public static string GetMarriageDateStr(GDMFamilyRecord fRec, DateFormat dateFor GDMCustomDate date = GetMarriageDate(fRec); return (date == null) ? string.Empty : date.GetDisplayStringExt(dateFormat, sign, false); } + public static string GetMarriageDateStr(GDMFamilyRecord fRec, DateFormat dateFormat) { GDMCustomDate date = GetMarriageDate(fRec); @@ -1308,104 +1309,104 @@ public static string GetMarriageDateStr(GDMFamilyRecord fRec, DateFormat dateFor /// Number of days remained until the birthday of /// the . The caller must ignore this value if /// the method returns -1. - public static int GetDaysForBirth(GDMIndividualRecord iRec) + public static int GetDaysForBirth(GDMIndividualRecord iRec, bool onlyAlive, out int years, out bool anniversary) { int distance = -1; + years = 0; + anniversary = false; - if (iRec != null) { - int bdD, bdM, bdY; + if (iRec == null) return distance; - try { - GDMCustomEvent evt = iRec.FindEvent(GEDCOMTagType.DEAT); - if (evt == null) { - evt = iRec.FindEvent(GEDCOMTagType.BIRT); - if (evt != null) { - var dt = evt.Date.Value as GDMDate; - if (dt != null) { - bdM = dt.Month; - bdD = dt.Day; - - if (bdM != 0 && bdD != 0) { - DateTime dtNow = DateTime.Now.Date; - int curY = dtNow.Year; - int curM = dtNow.Month; - int curD = dtNow.Day; - double bdN = curY + bdM / 12.0 + bdD / 12.0 / 31.0; - double curN = curY + curM / 12.0 + curD / 12.0 / 31.0; - bdY = (bdN < curN) ? (curY + 1) : curY; - - // There are valid birthdays on February 29th in leap years. - // For other years, we need a correction for an acceptable day. - if (bdD == 29 && bdM == 2 && !DateTime.IsLeapYear(bdY)) { - bdD -= 1; - } + GDMCustomEvent evt; - distance = DateHelper.DaysBetween(dtNow, new DateTime(bdY, bdM, bdD)); - } - } - } - } - } catch (Exception ex) { - Logger.WriteError("GKUtils.GetDaysForBirth()", ex); - } + if (onlyAlive) { + evt = iRec.FindEvent(GEDCOMTagType.DEAT); + if (evt != null) return distance; } + evt = iRec.FindEvent(GEDCOMTagType.BIRT); + if (evt == null) return distance; + + var dt = evt.Date.Value as GDMDate; + if (dt == null || !dt.IsValidDate()) return distance; + + distance = GetDaysFor(dt, DateTime.Now, out years, out anniversary); return distance; } - public static int GetDaysForBirthAnniversary(GDMIndividualRecord iRec, out int years) + public static int GetDaysFor(GDMDate dt, DateTime dtNow, out int years, out bool anniversary) { int distance = -1; years = 0; + anniversary = false; - if (iRec != null) { - int bdD, bdM, bdY; - - try { - GDMCustomEvent evt = iRec.FindEvent(GEDCOMTagType.DEAT); - if (evt == null) { - evt = iRec.FindEvent(GEDCOMTagType.BIRT); - if (evt != null) { - var dt = evt.Date.Value as GDMDate; - if (dt != null && dt.IsValidDate()) { - bdY = dt.Year; - bdM = dt.Month; - bdD = dt.Day; - - DateTime dtNow = DateTime.Now.Date; - int curY = dtNow.Year; - int curM = dtNow.Month; - int curD = dtNow.Day; - - double bdN = curY + bdM / 12.0 + bdD / 12.0 / 31.0; - double curN = curY + curM / 12.0 + curD / 12.0 / 31.0; - - if (bdN > curN) { - years = curY - bdY; - bool anniversary = (years % 10 == 0) || (years % 25 == 0); - if (anniversary) { - bdY = (bdN < curN) ? (curY + 1) : curY; - - // There are valid birthdays on February 29th in leap years. - // For other years, we need a correction for an acceptable day. - if (bdD == 29 && bdM == 2 && !DateTime.IsLeapYear(bdY)) { - bdD -= 1; - } - - distance = DateHelper.DaysBetween(dtNow, new DateTime(bdY, bdM, bdD)); - } - } - } + try { + if (dt != null && dt.IsValidDate()) { + int bdY = dt.Year; + int bdM = dt.Month; + int bdD = dt.Day; + + int curY = dtNow.Year; + int curM = dtNow.Month; + int curD = dtNow.Day; + + double bdN = bdM * 100 + bdD; + double curN = curM * 100 + curD; + + if (bdN >= curN) { + years = curY - bdY; + anniversary = (years % 10 == 0) || (years % 25 == 0); + + bdY = (bdN < curN) ? (curY + 1) : curY; + // There are valid birthdays on February 29th in leap years. + // For other years, we need a correction for an acceptable day. + if (bdD == 29 && bdM == 2 && !DateTime.IsLeapYear(bdY)) { + bdD -= 1; } + + distance = DateHelper.DaysBetween(dtNow, new DateTime(bdY, bdM, bdD)); } - } catch (Exception ex) { - Logger.WriteError("GKUtils.GetDaysForBirthAnniversary()", ex); } + } catch (Exception ex) { + Logger.WriteError("GKUtils.GetDaysFor()", ex); } return distance; } + public static string GetBirthTipMessage(ICulture culture, GDMIndividualRecord iRec, int days, int years, bool anniversary) + { + string nm = culture.GetPossessiveName(iRec); + + string tip; + if (!anniversary) { + switch (days) { + case 0: + tip = string.Format(LangMan.LS(LSID.BirthdayToday), nm); + break; + case 1: + tip = string.Format(LangMan.LS(LSID.BirthdayTomorrow), nm); + break; + default: + tip = string.Format(LangMan.LS(LSID.DaysRemained), nm, days); + break; + } + } else { + switch (days) { + case 0: + tip = string.Format(LangMan.LS(LSID.AnniversaryToday), nm); + break; + case 1: + tip = string.Format(LangMan.LS(LSID.AnniversaryTomorrow), nm); + break; + default: + tip = string.Format(LangMan.LS(LSID.AnniversaryDaysRemained), nm, days); + break; + } + } + return tip; + } + public static string GetCalendarSign(GDMCalendar calendar) { var globOptions = GlobalOptions.Instance; diff --git a/projects/GKCore/GKCore/Lists/IndividualListModel.cs b/projects/GKCore/GKCore/Lists/IndividualListModel.cs index dcb522257..99e99cc65 100644 --- a/projects/GKCore/GKCore/Lists/IndividualListModel.cs +++ b/projects/GKCore/GKCore/Lists/IndividualListModel.cs @@ -521,7 +521,7 @@ protected override object GetColumnValueEx(int colType, int colSubtype, bool isV break; case ColumnType.ctDaysForBirth: - int days = GKUtils.GetDaysForBirth(fFetchedRec); + int days = GKUtils.GetDaysForBirth(fFetchedRec, true, out _, out _); result = (days >= 0) ? (object)days : null; break; diff --git a/projects/GKTests/GKCore/GKUtilsTests.cs b/projects/GKTests/GKCore/GKUtilsTests.cs index 331f5c2a9..921eb7f50 100644 --- a/projects/GKTests/GKCore/GKUtilsTests.cs +++ b/projects/GKTests/GKCore/GKUtilsTests.cs @@ -291,7 +291,27 @@ public void Test_GetXGoalStr() [Test] public void Test_GetDaysForBirth() { - Assert.AreEqual(-1, GKUtils.GetDaysForBirth(null)); + GDMDate gdmDate = new GDMDate(); + gdmDate.ParseString("20 DEC 1980"); + + int years; + bool anniversary; + + Assert.AreEqual(-1, GKUtils.GetDaysForBirth(null, true, out years, out anniversary)); + + Assert.AreEqual(-1, GKUtils.GetDaysFor(gdmDate, DateTime.Parse("1982-12-25T00:00:00"), out years, out anniversary)); // curdate ahead + + Assert.AreEqual(0, GKUtils.GetDaysFor(gdmDate, DateTime.Parse("1981-12-20T00:00:00"), out years, out anniversary)); // dates are equal, and 1 year + Assert.AreEqual(1, years); + Assert.AreEqual(false, anniversary); + + Assert.AreEqual(2, GKUtils.GetDaysFor(gdmDate, DateTime.Parse("1981-12-18T00:00:00"), out years, out anniversary)); // 2 days left, and year *will be* 1 + Assert.AreEqual(1, years); + Assert.AreEqual(false, anniversary); + + Assert.AreEqual(1, GKUtils.GetDaysFor(gdmDate, DateTime.Parse("1990-12-19T00:00:00"), out years, out anniversary)); // 1 days left, and year *will be* 10 + Assert.AreEqual(10, years); + Assert.AreEqual(true, anniversary); } [Test] diff --git a/projects/GKTests/TestUtils.cs b/projects/GKTests/TestUtils.cs index 2af6dea4a..d14e95418 100644 --- a/projects/GKTests/TestUtils.cs +++ b/projects/GKTests/TestUtils.cs @@ -201,6 +201,13 @@ public static void FillContext(IBaseContext context) Assert.IsNotNull(commRec, "commRec != null"); } + public static GDMDate ParseGDT(string dtx) + { + GDMDate result = new GDMDate(); + result.ParseString(dtx); + return result; + } + public static DateTime ParseDT(string dtx) { return DateTime.ParseExact(dtx, "dd.MM.yyyy", CultureInfo.InvariantCulture); diff --git a/projects/plugins/GKStdReports/ContemporariesReport.cs b/projects/plugins/GKStdReports/ContemporariesReport.cs index b2c07a038..724d39a4c 100644 --- a/projects/plugins/GKStdReports/ContemporariesReport.cs +++ b/projects/plugins/GKStdReports/ContemporariesReport.cs @@ -1,6 +1,6 @@ /* * "GEDKeeper", the personal genealogical database editor. - * Copyright (C) 2018-2023 by Sergey V. Zhdanovskih. + * Copyright (C) 2018-2024 by Sergey V. Zhdanovskih. * * This file is part of "GEDKeeper". * @@ -89,10 +89,9 @@ protected override void InternalGenerate() fWriter.BeginList(); - var enumer = fBase.Context.Tree.GetEnumerator(GDMRecordType.rtIndividual); - GDMRecord record; - while (enumer.MoveNext(out record)) { - var iRec = record as GDMIndividualRecord; + var enumer = fBase.Context.Tree.GetEnumerator(); + GDMIndividualRecord iRec; + while (enumer.MoveNext(out iRec)) { var indRange = GetIndividualDates(iRec); try { if (personRange.IsOverlapped(indRange)) {